Version 2.13.0-211.1.beta

Merge '2.13.0-211.0.dev' into beta
diff --git a/.dart_tool/package_config.json b/.dart_tool/package_config.json
index f5b87d777..4064188 100644
--- a/.dart_tool/package_config.json
+++ b/.dart_tool/package_config.json
@@ -11,7 +11,7 @@
     "constraint, update this by running tools/generate_package_config.dart."
   ],
   "configVersion": 2,
-  "generated": "2021-03-04T14:15:31.446260",
+  "generated": "2021-04-06T14:39:06.316531",
   "generator": "tools/generate_package_config.dart",
   "packages": [
     {
@@ -70,13 +70,13 @@
       "name": "analysis_server",
       "rootUri": "../pkg/analysis_server",
       "packageUri": "lib/",
-      "languageVersion": "2.6"
+      "languageVersion": "2.12"
     },
     {
       "name": "analysis_server_client",
       "rootUri": "../pkg/analysis_server_client",
       "packageUri": "lib/",
-      "languageVersion": "2.8"
+      "languageVersion": "2.12"
     },
     {
       "name": "analyzer",
@@ -94,7 +94,7 @@
       "name": "analyzer_plugin",
       "rootUri": "../pkg/analyzer_plugin",
       "packageUri": "lib/",
-      "languageVersion": "2.9"
+      "languageVersion": "2.12"
     },
     {
       "name": "analyzer_utilities",
@@ -139,6 +139,12 @@
       "languageVersion": "2.10"
     },
     {
+      "name": "browser_launcher",
+      "rootUri": "../third_party/pkg/browser_launcher",
+      "packageUri": "lib/",
+      "languageVersion": "2.2"
+    },
+    {
       "name": "build_integration",
       "rootUri": "../pkg/build_integration",
       "packageUri": "lib/",
@@ -220,7 +226,7 @@
       "name": "dart_style",
       "rootUri": "../third_party/pkg_tested/dart_style",
       "packageUri": "lib/",
-      "languageVersion": "2.9"
+      "languageVersion": "2.12"
     },
     {
       "name": "dartdev",
@@ -238,7 +244,7 @@
       "name": "dds",
       "rootUri": "../pkg/dds",
       "packageUri": "lib/",
-      "languageVersion": "2.6"
+      "languageVersion": "2.12"
     },
     {
       "name": "dev_compiler",
@@ -339,7 +345,7 @@
       "name": "http_retry",
       "rootUri": "../third_party/pkg/http_retry",
       "packageUri": "lib/",
-      "languageVersion": "1.24"
+      "languageVersion": "2.12"
     },
     {
       "name": "http_throttle",
@@ -437,12 +443,6 @@
       "languageVersion": "2.2"
     },
     {
-      "name": "mustache",
-      "rootUri": "../third_party/pkg/mustache",
-      "packageUri": "lib/",
-      "languageVersion": "2.0"
-    },
-    {
       "name": "native_stack_traces",
       "rootUri": "../pkg/native_stack_traces",
       "packageUri": "lib/",
@@ -575,7 +575,7 @@
       "name": "shelf_proxy",
       "rootUri": "../third_party/pkg/shelf_proxy",
       "packageUri": "lib/",
-      "languageVersion": "2.0"
+      "languageVersion": "2.12"
     },
     {
       "name": "shelf_static",
@@ -632,12 +632,6 @@
       "languageVersion": "2.12"
     },
     {
-      "name": "stagehand",
-      "rootUri": "../third_party/pkg/stagehand",
-      "packageUri": "lib/",
-      "languageVersion": "2.10"
-    },
-    {
       "name": "status_file",
       "rootUri": "../pkg/status_file",
       "packageUri": "lib/",
@@ -695,13 +689,13 @@
       "name": "test_descriptor",
       "rootUri": "../third_party/pkg/test_descriptor",
       "packageUri": "lib/",
-      "languageVersion": "2.0"
+      "languageVersion": "2.12"
     },
     {
       "name": "test_process",
       "rootUri": "../third_party/pkg/test_process",
       "packageUri": "lib/",
-      "languageVersion": "2.0"
+      "languageVersion": "2.12"
     },
     {
       "name": "test_reflective_loader",
@@ -785,6 +779,12 @@
       "name": "webdriver",
       "rootUri": "../third_party/pkg/webdriver",
       "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
+      "name": "webkit_inspection_protocol",
+      "rootUri": "../third_party/pkg/webkit_inspection_protocol",
+      "packageUri": "lib/",
       "languageVersion": "2.0"
     },
     {
diff --git a/.gitignore b/.gitignore
index d7864e2..1f4ccc7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -23,11 +23,6 @@
 /*.vcxproj.user
 *.stamp
 
-# LLVM prebuilts
-/third_party/llvm/include
-/third_party/llvm/lib
-/third_party/llvm/.versions
-
 # Gyp generated files
 *.xcodeproj
 *.intermediate
diff --git a/.packages b/.packages
index 3587c4f..7646deb 100644
--- a/.packages
+++ b/.packages
@@ -20,6 +20,7 @@
 bazel_worker:third_party/pkg/bazel_worker/lib
 benchmark_harness:third_party/pkg/benchmark_harness/lib
 boolean_selector:third_party/pkg/boolean_selector/lib
+browser_launcher:third_party/pkg/browser_launcher/lib
 build_integration:pkg/build_integration/lib
 charcode:third_party/pkg/charcode/lib
 cli_util:third_party/pkg/cli_util/lib
@@ -94,7 +95,6 @@
 source_span:third_party/pkg/source_span/lib
 sse:third_party/pkg/sse/lib
 stack_trace:third_party/pkg/stack_trace/lib
-stagehand:third_party/pkg/stagehand/lib
 status_file:pkg/status_file/lib
 stream_channel:third_party/pkg/stream_channel/lib
 string_scanner:third_party/pkg/string_scanner/lib
@@ -118,6 +118,7 @@
 wasm:pkg/wasm/lib
 watcher:third_party/pkg/watcher/lib
 webdriver:third_party/pkg/webdriver/lib
+webkit_inspection_protocol:third_party/pkg/webkit_inspection_protocol/lib
 web_components:third_party/pkg/web_components/lib
 web_socket_channel:third_party/pkg/web_socket_channel/lib
 yaml:third_party/pkg/yaml/lib
diff --git a/BUILD.gn b/BUILD.gn
index 1140b668..c25c176 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -14,9 +14,6 @@
     testonly = true
   }
   deps = [ ":runtime" ]
-  if (defined(checkout_llvm) && checkout_llvm) {
-    deps += [ ":llvm_codegen" ]
-  }
 }
 
 group("most") {
@@ -26,6 +23,7 @@
     testonly = true
   }
   deps = [
+    ":analysis_server",
     ":create_sdk",
     ":dart2js",
     ":dartanalyzer",
@@ -33,9 +31,6 @@
     ":runtime",
     ":samples",
   ]
-  if (dart_target_arch != "arm") {
-    deps += [ ":analysis_server" ]
-  }
 }
 
 group("runtime") {
@@ -117,21 +112,6 @@
   deps = [ "utils/analysis_server" ]
 }
 
-group("check_llvm") {
-  if (defined(checkout_llvm) && checkout_llvm) {
-    deps = [ "runtime/llvm_codegen/test" ]
-  }
-}
-
-group("llvm_codegen") {
-  if (defined(checkout_llvm) && checkout_llvm) {
-    deps = [
-      "runtime/llvm_codegen/bit",
-      "runtime/llvm_codegen/codegen",
-    ]
-  }
-}
-
 # This is the target that is built on the dart2js build bots.
 # It must depend on anything that is required by the dart2js
 # test suites.
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6a2ee87..3fe24ae 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,25 +2,139 @@
 
 ### Language
 
+*   **Type aliases** [Non-function type aliases][]: Type aliases (names for
+    types introduced via the `typedef` keyword) were previously restricted
+    to only introduce names for function types.  In this release, we
+    remove this restriction and allow type aliases to name any kind of type.
+
+    ```dart
+    import 'dart:convert';
+
+    typedef JsonMap = Map<String, dynamic>;
+
+    JsonMap parseJsonMap(String input) => json.decode(input) as JsonMap;
+    ```
+
+    In addition to being usable as type annotations, type aliases that name
+    class types can now also be used anywhere that the underlying class could be
+    used, allowing type aliases to be used to safely rename existing classes.
+
+    ```dart
+    class NewClassName<T> {
+       NewClassName.create(T x);
+       static NewClassName<T> mkOne<T>(T x) => NewClassName<T>.create(x);
+     }
+    @Deprecated("Use NewClassName instead")
+    typedef OldClassName<T> = NewClassName<T>;
+
+    class LegacyClass extends OldClassName<int> {
+      LegacyClass() : super.create(3);
+    }
+    OldClassName<int> legacyCode() {
+      var one = OldClassName.create(1);
+      var two = OldClassName.mkOne(2);
+      return LegacyClass();
+    }
+    ```
+
+    The new type alias feature is only available as part of the 2.13 [language
+    version](https://dart.dev/guides/language/evolution).  To use this feature,
+    you must set the lower bound on the sdk constraint for your package to 2.13
+    or greater.
+
+    [Non-function type aliases]: https://github.com/dart-lang/language/blob/master/accepted/2.13/nonfunction-type-aliases/feature-specification.md
+
 ### Core libraries
 
+#### `dart:collection`
+
+- The `SplayTreeMap` was changed to allow `null` as key if the `compare`
+  function allows it. It now checks that a new key can be used as an
+  argument to the `compare` function when the member is added,
+  *even if the map is empty* (in which case it just compares the key
+  to itself).
+- The `SplayTreeSet` was changed to checks that a new element can be used as an
+  argument to the `compare` function when the member is added,
+  *even if the set is empty* (in which case it just compares the element
+  to itself).
+
 ### Dart VM
 
 ### Tools
 
-#### Dartanalyzer
+#### Analyzer
+
+- Static analyses with "error" severity can once again be ignored with
+  comments like `// ignore: code` and `// ignore_for_file: code`. To declare
+  that certain analysis codes, or codes with certain severities ("error",
+  "warning", and "info") cannot be ignored with such comments, list them in
+  `analysis_options.yaml`, under the `analyzer` heading, with a new YAML key,
+  `cannot-ignore`. For example, to declare that "error" codes and
+  `unused_import` cannot be ignored, write the following into
+  `analysis_options.yaml`:
+
+  ```yaml
+  analyzer:
+    cannot-ignore:
+      - error
+      - unused_import
+  ```
+
+#### dart format
+
+*   Flatten indentation on nested chains of conditional (`?:`) operators.
+
+*   Correct constructor initializer indentation after `required` named
+    parameters.
 
 #### Linter
 
-Updated the Linter to `1.0.0`, which includes:
+Updated the Linter to `1.2.1`, which includes:
 
+- improvements to `iterable_contains_unrelated_type` to better support `List`
+  content checks.
+- fixes to `camel_case_types` and `prefer_mixin` to support non-function
+  type aliases.
+- fixed `prefer_mixin` to properly make exceptions for `dart.collection`
+  legacy mixins.
+- new lint: `use_build_context_synchronously` (experimental).
+- new lint: `avoid_multiple_declarations_per_line`.
 - full library migration to null-safety.
 - new lint: `use_if_null_to_convert_nulls_to_bools`.
 - new lint: `deprecated_consistency`.
 - new lint: `use_named_constants`.
 - deprecation of `avoid_as`.
 
-## 2.12.0
+### Other libraries
+
+#### `package:js`
+
+*   **Breaking change:** It is no longer valid to use `String`s that match
+    an `@Native` annotation in an `@JS()` annotation for a non-anonymous JS
+    interop class. This led to erroneous behavior due to the way interceptors
+    work. If you need to work with a native class, prefer `dart:html`, an
+    `@anonymous` class, or `js_util`. See issue [#44211][] for more details.
+
+[#44211]: https://github.com/dart-lang/sdk/issues/44211
+
+## 2.12.2 - 2021-03-17
+
+This is a patch release that fixes crashes reported by Flutter 2 users (issue
+[flutter/flutter#78167][]).
+
+[flutter/flutter#78167]: https://github.com/flutter/flutter/issues/78167
+
+## 2.12.1 - 2021-03-10
+
+This is a patch release that fixes:
+
+* an unhandled exception in HTTPS connections (issue [#45047][]).
+* a typing issue in the typed_data `+` operator (issue [#45140][]).
+
+[#45047]: https://github.com/dart-lang/sdk/issues/45047
+[#45140]: https://github.com/dart-lang/sdk/issues/45140
+
+## 2.12.0 - 2021-03-03
 
 ### Language
 
@@ -131,7 +245,7 @@
 
 ### Tools
 
-#### Dartanalyzer
+#### Analyzer
 
 *   Remove the `--use-fasta-parser`, `--preview-dart-2`, and
     `--enable-assert-initializers` command line options. These options haven't
@@ -318,7 +432,7 @@
 [#44072]: https://github.com/dart-lang/sdk/issues/44072
 [dart tool]: https://dart.dev/tools/dart-tool
 
-## 2.10.5 - 2020-01-21
+## 2.10.5 - 2021-01-21
 
 This is a patch release that fixes a crash in the Dart VM. (issue [#44563][]).
 
@@ -565,6 +679,11 @@
 * Indent blocks in initializers of multiple-variable declarations.
 * Update the null-aware subscript syntax from `?.[]` to `?[]`.
 
+#### Analyzer
+
+* Static analyses with a severity of "error" can no longer be ignored with
+  comments (`// ignore: code` and `// ignore_for_file: code`).
+
 #### Linter
 
 Updated the Linter to `0.1.117`, which includes:
diff --git a/DEPS b/DEPS
index ea4b377..380ac87 100644
--- a/DEPS
+++ b/DEPS
@@ -39,16 +39,16 @@
 
   # Checked-in SDK version. The checked-in SDK is a Dart SDK distribution in a
   # cipd package used to run Dart scripts in the build and test infrastructure.
-  "sdk_tag": "version:2.12.0-259.8.beta",
+  "sdk_tag": "version:2.12.0",
 
   # 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": "88b4f0556b0889067efcac45f2b96bc630e5b96c",
-  "co19_2_rev": "cf6eed0535e45413672bb5bb6e65df9f59846372",
+  "co19_rev": "fddb1dce948cec277bf3dc23b45ee95e761b89fe",
+  "co19_2_rev": "3642f24e2e6273c6fb65a8f60cd0edc95153942e",
 
   # The internal benchmarks to use. See go/dart-benchmarks-internal
-  "benchmarks_internal_rev": "354c978979c57e4a76f62e22cf644ed0804f4421",
+  "benchmarks_internal_rev": "076df10d9b77af337f2d8029725787155eb1cd52",
   "checkout_benchmarks_internal": False,
 
   # Checkout Android dependencies only on Mac and Linux.
@@ -68,9 +68,9 @@
   "gperftools_revision": "180bfa10d7cb38e8b3784d60943d50e8fcef0dcb",
 
   # Revisions of /third_party/* dependencies.
-  "args_rev": "eb2deca5b4489709acd001a5c7fd2df4f1eed19d",
+  "args_rev": "d8fea36c10ef96797be02e3d132d572445cd86f4",
   "async_rev": "376d418b1b535030fbe3369938d2ffdbb0340a77",
-  "bazel_worker_rev": "060c55a933d39798681a4f533b161b81dc48d77e",
+  "bazel_worker_rev": "0885637b037979afbf5bcd05fd748b309fd669c0",
   "benchmark_harness_rev": "c546dbd9f639f75cd2f75de8df2eb9f8ea15e8e7",
   "boolean_selector_rev": "665e6921ab246569420376f827bff4585dff0b14",
   "boringssl_gen_rev": "7322fc15cc065d8d2957fccce6b62a509dc4d641",
@@ -98,10 +98,11 @@
   #     and land the review.
   #
   # For more details, see https://github.com/dart-lang/sdk/issues/30164
-  "dart_style_tag": "1.3.11",  # Please see the note above before updating.
+  "dart_style_rev": "0067cfcc5bfa64cf59888c3fed34c71d1272555a",
 
   "chromedriver_tag": "83.0.4103.39",
-  "dartdoc_rev" : "174021f3d76c2a8500b54977c80f32c5bbc099f1",
+  "browser_launcher_rev": "12ab9f351a44ac803de9bc17bb2180bb312a9dd7",
+  "dartdoc_rev" : "505f163f7cb48e917503e4a23fbff1227e08b263",
   "ffi_rev": "f3346299c55669cc0db48afae85b8110088bf8da",
   "fixnum_rev": "16d3890c6dc82ca629659da1934e412292508bba",
   "file_rev": "0e09370f581ab6388d46fda4cdab66638c0171a1",
@@ -110,26 +111,25 @@
   "http_io_rev": "2fa188caf7937e313026557713f7feffedd4978b",
   "http_multi_server_rev" : "6bf4b6e5d4d890e6d54559b858ff229d79711171",
   "http_parser_rev": "5dd4d16693242049dfb43b5efa429fedbf932e98",
-  "http_retry_tag": "0.1.1",
-  "http_rev": "d5c678cd63c3e9c1d779a09acfa95b7e3af84665",
+  "http_retry_rev": "845771af7bb5ab38ab740ce4a31f3b0c7680302b",
+  "http_rev": "615380db687d0649057ed8dba9d933d7d5f5051b",
   "http_throttle_tag" : "1.0.2",
-  "icu_rev" : "79326efe26e5440f530963704c3c0ff965b3a4ac",
+  "icu_rev" : "81d656878ec611cb0b42d52c82e9dae93920d9ba",
   "idl_parser_rev": "5fb1ebf49d235b5a70c9f49047e83b0654031eb7",
   "intl_tag": "0.17.0-nullsafety",
   "jinja2_rev": "2222b31554f03e62600cd7e383376a7c187967a1",
   "json_rpc_2_rev": "b8dfe403fd8528fd14399dee3a6527b55802dd4d",
-  "linter_tag": "1.0.0",
+  "linter_tag": "1.2.1",
   "logging_rev": "e2f633b543ef89c54688554b15ca3d7e425b86a2",
   "markupsafe_rev": "8f45f5cfa0009d2a70589bcda0349b8cb2b72783",
   "markdown_rev": "9c4beaac96d8f008078e00b027915f81b665d2de",
   "matcher_rev": "1f7b6f0cb15eb6659a1de0513571575a5c8a51d0",
   "mime_rev": "c931f4bed87221beaece356494b43731445ce7b8",
   "mockito_rev": "d39ac507483b9891165e422ec98d9fb480037c8b",
-  "mustache_rev": "664737ecad027e6b96d0d1e627257efa0e46fcb1",
   "oauth2_rev": "7cd3284049fe5badbec9f2bea2afc41d14c01057",
-  "package_config_rev": "249af482de9ebabfc781bf10d6152c938e5ce45e",
+  "package_config_rev": "a84c0d45401f215fbe9384df923a38f4022a3c45",
   "path_rev": "407ab76187fade41c31e39c745b39661b710106c",
-  "pedantic_rev": "df177f6ae531426aaf7bbf0121c90dc89d9c57bf",
+  "pedantic_rev": "66f2f6c27581c7936482e83be80b27be2719901c",
   "platform_rev": "c20e6fa315e9f8820e51c0ae721f63aff33b8e17",
   "ply_rev": "604b32590ffad5cbb82e4afef1d305512d06ae93",
   "pool_rev": "7abe634002a1ba8a0928eded086062f1307ccfae",
@@ -140,34 +140,34 @@
   "resource_rev": "6b79867d0becf5395e5819a75720963b8298e9a7",
   "root_certificates_rev": "7e5ec82c99677a2e5b95ce296c4d68b0d3378ed8",
   "rust_revision": "b7856f695d65a8ebc846754f97d15814bcb1c244",
-  "shelf_static_rev": "bafde9eaddb5d02040a614e41deddd971b4d67e6",
+  "shelf_static_rev": "fa30419055279a00c9e428439b1abe362d18f25d",
   "shelf_packages_handler_rev": "78302e67c035047e6348e692b0c1182131f0fe35",
-  "shelf_proxy_tag": "0.1.0+7",
-  "shelf_rev": "e9294125f0c1fc2049c958577cd586ca2395168f",
-  "shelf_web_socket_rev": "aa312d3cdeef96fb64bc3e602bc354a05a995624",
+  "shelf_proxy_tag": "v1.0.0",
+  "shelf_rev": "00e50adfb776602c25942a99d89f8704cc20db9c",
+  "shelf_web_socket_rev": "24fb8a04befa75a94ac63a27047b231d1a22aab4",
   "source_map_stack_trace_rev": "1c3026f69d9771acf2f8c176a1ab750463309cce",
   "source_maps-0.9.4_rev": "38524",
   "source_maps_rev": "53eb92ccfe6e64924054f83038a534b959b12b3e",
   "source_span_rev": "1be3c44045a06dff840d2ed3a13e6082d7a03a23",
   "sse_tag": "5da8fedcdc56f306933d202e2d204753eecefd36",
   "stack_trace_tag": "6788afc61875079b71b3d1c3e65aeaa6a25cbc2f",
-  "stagehand_rev": "e64ac90cac508981011299c4ceb819149e71f1bd",
   "stream_channel_tag": "d7251e61253ec389ee6e045ee1042311bced8f1d",
   "string_scanner_rev": "1b63e6e5db5933d7be0a45da6e1129fe00262734",
   "sync_http_rev": "b59c134f2e34d12acac110d4f17f83e5a7db4330",
-  "test_descriptor_tag": "1.1.1",
-  "test_process_tag": "1.0.3",
+  "test_descriptor_tag": "2.0.0",
+  "test_process_tag": "2.0.0",
   "term_glyph_rev": "6a0f9b6fb645ba75e7a00a4e20072678327a0347",
   "test_reflective_loader_rev": "54e930a11c372683792e22bddad79197728c91ce",
-  "test_rev": "bb98af3d17a821c28488ef8e2881e3ca173baf94",
+  "test_rev": "e673623f45d75ccec750d35271b0b4d1423e9fac",
   "typed_data_tag": "f94fc57b8e8c0e4fe4ff6cfd8290b94af52d3719",
-  "usage_rev": "6c64d9e7b6b3758d06d030efcb5afe20bfc04dde",
+  "usage_rev": "5b7317ba89166f3cf1af98cb280a4cc8e78f25f9",
   "vector_math_rev": "0c9f5d68c047813a6dcdeb88ba7a42daddf25025",
   "watcher_rev": "3924194385fb215cef483193ed2879a618a3d69c",
-  "webdriver_rev": "5a8d6805d9cf8a3cbb4fcd64849b538b7491e50e",
+  "webdriver_rev": "ff5ccb1522edf4bed578ead4d65e0cbc1f2c4f02",
   "web_components_rev": "8f57dac273412a7172c8ade6f361b407e2e4ed02",
-  "web_socket_channel_rev": "76931ea1b81ba71e8319330c35285d3e88566315",
+  "web_socket_channel_rev": "d3e100de8feb0283a04732366bb591ebd2282d7d",
   "WebCore_rev": "fb11e887f77919450e497344da570d780e078bc8",
+  "webkit_inspection_protocol_rev": "6b15729292d030f2e5c5861022da4c5a4c11961c",
   "yaml_rev": "b4c4411631bda556ce9a45af1ab0eecaf9f3ac53",
   "zlib_rev": "bf44340d1b6be1af8950bbdf664fec0cf5a831cc",
   "crashpad_rev": "bf327d8ceb6a669607b0dbab5a83a275d03f99ed",
@@ -180,18 +180,10 @@
   "chrome_tag": "84",
   "download_firefox": False,
   "firefox_tag": "67",
-
-  # An LLVM backend needs LLVM binaries and headers. To avoid build time
-  # increases we can use prebuilts. We don't want to download this on every
-  # CQ/CI bot nor do we want the average Dart developer to incur that cost.
-  # So by default we will not download prebuilts.
-  "checkout_llvm": False,
-  "llvm_revision": "fe8bd96ebd6c490ea0b5c1fb342db2d7c393a109"
 }
 
 gclient_gn_args_file = Var("dart_root") + '/build/config/gclient_args.gni'
 gclient_gn_args = [
-  'checkout_llvm'
 ]
 
 deps = {
@@ -321,6 +313,9 @@
   Var("dart_root") + "/third_party/pkg/boolean_selector":
       Var("dart_git") + "boolean_selector.git" +
       "@" + Var("boolean_selector_rev"),
+  Var("dart_root") + "/third_party/pkg/browser_launcher":
+      Var("dart_git") + "browser_launcher.git" +
+      "@" + Var("browser_launcher_rev"),
   Var("dart_root") + "/third_party/pkg/charcode":
       Var("dart_git") + "charcode.git" + "@" + Var("charcode_rev"),
   Var("dart_root") + "/third_party/pkg/cli_util":
@@ -336,7 +331,7 @@
   Var("dart_root") + "/third_party/pkg/csslib":
       Var("dart_git") + "csslib.git" + "@" + Var("csslib_rev"),
   Var("dart_root") + "/third_party/pkg_tested/dart_style":
-      Var("dart_git") + "dart_style.git" + "@" + Var("dart_style_tag"),
+      Var("dart_git") + "dart_style.git" + "@" + Var("dart_style_rev"),
   Var("dart_root") + "/third_party/pkg/dart2js_info":
       Var("dart_git") + "dart2js_info.git" + "@" + Var("dart2js_info_rev"),
   Var("dart_root") + "/third_party/pkg/dartdoc":
@@ -363,7 +358,7 @@
       Var("dart_git") + "http_parser.git" + "@" + Var("http_parser_rev"),
   Var("dart_root") + "/third_party/pkg/http_retry":
       Var("dart_git") + "http_retry.git" +
-      "@" + Var("http_retry_tag"),
+      "@" + Var("http_retry_rev"),
   Var("dart_root") + "/third_party/pkg/http_throttle":
       Var("dart_git") + "http_throttle.git" +
       "@" + Var("http_throttle_tag"),
@@ -383,10 +378,6 @@
       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":
-      Var("dart_git")
-      + "external/github.com/xxgreg/mustache"
-      + "@" + Var("mustache_rev"),
   Var("dart_root") + "/third_party/pkg/oauth2":
       Var("dart_git") + "oauth2.git" + "@" + Var("oauth2_rev"),
   Var("dart_root") + "/third_party/pkg_tested/package_config":
@@ -433,8 +424,6 @@
       Var("dart_git") + "sse.git" + "@" + Var("sse_tag"),
   Var("dart_root") + "/third_party/pkg/stack_trace":
       Var("dart_git") + "stack_trace.git" + "@" + Var("stack_trace_tag"),
-  Var("dart_root") + "/third_party/pkg/stagehand":
-      Var("dart_git") + "stagehand.git" + "@" + Var("stagehand_rev"),
   Var("dart_root") + "/third_party/pkg/stream_channel":
       Var("dart_git") + "stream_channel.git" +
       "@" + Var("stream_channel_tag"),
@@ -469,6 +458,9 @@
   Var("dart_root") + "/third_party/pkg/webdriver":
       Var("dart_git") + "external/github.com/google/webdriver.dart.git" +
       "@" + Var("webdriver_rev"),
+  Var("dart_root") + "/third_party/pkg/webkit_inspection_protocol":
+      Var("dart_git") + "external/github.com/google/webkit_inspection_protocol.dart.git" +
+      "@" + Var("webkit_inspection_protocol_rev"),
 
   Var("dart_root") + "/third_party/pkg/web_socket_channel":
       Var("dart_git") + "web_socket_channel.git" +
@@ -613,17 +605,7 @@
               "version": "ebF5aRXKDananlaN4Y8b0bbCNHT1MnkGbWqfpCpiND4C",
           },
       ],
-      "dep_type": "cipd",
-  },
-  Var("dart_root") + "/third_party/llvm": {
-      "packages": [
-          {
-              "package": "fuchsia/lib/llvm/${{platform}}",
-              "version": "git_revision:" + Var("llvm_revision"),
-          },
-      ],
-      "condition": "checkout_llvm",
-      "dep_type": "cipd",
+          "dep_type": "cipd",
   },
   Var("dart_root") + "/third_party/browsers/chrome": {
       "packages": [
@@ -664,8 +646,6 @@
   }
 }
 
-# TODO(iposva): Move the necessary tools so that hooks can be run
-# without the runtime being available.
 hooks = [
   {
     "name": "firefox_jsshell",
diff --git a/WATCHLISTS b/WATCHLISTS
index 195162c..e4b5b89 100644
--- a/WATCHLISTS
+++ b/WATCHLISTS
@@ -18,6 +18,9 @@
         '^tools/buildtools/'
       )
     },
+    'experimental_features': {
+      'filepath': 'tools/experimental_features\\.yaml',
+    },
     'front_end': {
       'filepath': '^pkg/front_end',
     },
@@ -73,9 +76,9 @@
   },
 
   'WATCHLISTS': {
-    'build': [ 'keertip@google.com' ],
     'dart2js': [ 'dart2js-team+reviews@google.com' ],
     'dartdevc': [ 'dart-dc-team+reviews@google.com' ],
+    'experimental_features': [ 'scheglov@google.com' ],
     'front_end': [ 'dart-fe-team+reviews@google.com' ],
     'kernel': [ 'jensj@google.com', 'alexmarkov@google.com' ],
     'messages_review': [ 'dart-uxr+reviews@google.com' ],
diff --git a/benchmarks/FfiMemory/dart/FfiMemory.dart b/benchmarks/FfiMemory/dart/FfiMemory.dart
index 1b822fb..26ff8e7 100644
--- a/benchmarks/FfiMemory/dart/FfiMemory.dart
+++ b/benchmarks/FfiMemory/dart/FfiMemory.dart
@@ -390,6 +390,30 @@
   }
 }
 
+class PointerUint32Unaligned extends BenchmarkBase {
+  Pointer<Uint32> pointer = nullptr;
+  Pointer<Uint32> unalignedPointer = nullptr;
+  PointerUint32Unaligned() : super('FfiMemory.PointerUint32Unaligned');
+
+  @override
+  void setup() {
+    pointer = calloc(N + 1);
+    unalignedPointer = Pointer.fromAddress(pointer.address + 1);
+  }
+
+  @override
+  void teardown() => calloc.free(pointer);
+
+  @override
+  void run() {
+    doStoreUint32(unalignedPointer, N);
+    final int x = doLoadUint32(unalignedPointer, N);
+    if (x != N) {
+      throw Exception('$name: Unexpected result: $x');
+    }
+  }
+}
+
 class PointerInt64 extends BenchmarkBase {
   Pointer<Int64> pointer = nullptr;
   PointerInt64() : super('FfiMemory.PointerInt64');
@@ -527,6 +551,7 @@
     () => PointerUint16(),
     () => PointerInt32(),
     () => PointerUint32(),
+    () => PointerUint32Unaligned(),
     () => PointerInt64(),
     () => PointerInt64Mint(),
     () => PointerUint64(),
diff --git a/benchmarks/FfiMemory/dart2/FfiMemory.dart b/benchmarks/FfiMemory/dart2/FfiMemory.dart
index f788959..8ed6302 100644
--- a/benchmarks/FfiMemory/dart2/FfiMemory.dart
+++ b/benchmarks/FfiMemory/dart2/FfiMemory.dart
@@ -390,6 +390,30 @@
   }
 }
 
+class PointerUint32Unaligned extends BenchmarkBase {
+  Pointer<Float> pointer;
+  Pointer<Uint32> unalignedPointer;
+  PointerUint32Unaligned() : super('FfiMemory.PointerUint32Unaligned');
+
+  @override
+  void setup() {
+    pointer = calloc(N + 1);
+    unalignedPointer = Pointer.fromAddress(pointer.address + 1);
+  }
+
+  @override
+  void teardown() => calloc.free(pointer);
+
+  @override
+  void run() {
+    doStoreUint32(unalignedPointer, N);
+    final int x = doLoadUint32(unalignedPointer, N);
+    if (x != N) {
+      throw Exception('$name: Unexpected result: $x');
+    }
+  }
+}
+
 class PointerInt64 extends BenchmarkBase {
   Pointer<Int64> pointer;
   PointerInt64() : super('FfiMemory.PointerInt64');
@@ -527,6 +551,7 @@
     () => PointerUint16(),
     () => PointerInt32(),
     () => PointerUint32(),
+    () => PointerUint32Unaligned(),
     () => PointerInt64(),
     () => PointerInt64Mint(),
     () => PointerUint64(),
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn
index e6e7c2d..f1ac8c2 100644
--- a/build/config/compiler/BUILD.gn
+++ b/build/config/compiler/BUILD.gn
@@ -271,15 +271,12 @@
     cflags += [ "-fcolor-diagnostics" ]
   }
 
-  # C++11 compiler flags setup.
+  # C++ standard compiler flags setup.
   # ---------------------------
   if (is_win) {
-    # Up-to-date toolchain MSVC doesn't support c++11 flag any longer.
-    cc_std = [ "/std:c++14" ]
-  } else if (is_fuchsia) {
-    cc_std = [ "-std=c++17" ]
+    cc_std = [ "/std:c++17" ]
   } else {
-    cc_std = [ "-std=c++11" ]
+    cc_std = [ "-std=c++17" ]
   }
   cflags_cc += cc_std
   cflags_objcc += cc_std
@@ -518,7 +515,6 @@
     default_warning_flags += [
       "-Wno-deprecated-declarations",  # crashpad
       "-Wno-ignored-pragma-optimize",  # icu, double-conversion
-      "-Wno-implicit-int-float-conversion",  # icu
       "-Wno-macro-redefined",
       "-Wno-microsoft-cast",
       "-Wno-microsoft-unqualified-friend",
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 766b57a..e4c7261 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
@@ -232,11 +232,6 @@
             '{${_info.keys.map((k) => '$k (${k.hashCode})').join(',')}}'));
   }
 
-  /// Indicates whether information is stored for the given [node].
-  bool _hasInfoForNode(Node node) {
-    return _info[node] != null;
-  }
-
   void _printOn(StringBuffer sb) {
     sb.write('_info=$_info,');
     sb.write('_stack=$_stack,');
@@ -305,58 +300,32 @@
 /// Non-promotion reason describing the situation where a variable was not
 /// promoted due to an explicit write to the variable appearing somewhere in the
 /// source code.
-class DemoteViaExplicitWrite<Variable extends Object, Expression extends Object>
+class DemoteViaExplicitWrite<Variable extends Object>
     extends NonPromotionReason {
   /// The local variable that was not promoted.
   final Variable variable;
 
-  /// The expression that wrote to the variable; this corresponds to an
-  /// expression that was passed to [FlowAnalysis.write].
-  final Expression writeExpression;
+  /// The node that wrote to the variable; this corresponds to a node that was
+  /// passed to [FlowAnalysis.write].
+  final Object node;
 
-  DemoteViaExplicitWrite(this.variable, this.writeExpression);
+  DemoteViaExplicitWrite(this.variable, this.node);
+
+  @override
+  String get documentationLink => 'http://dart.dev/go/non-promo-write';
 
   @override
   String get shortName => 'explicitWrite';
 
   @override
-  R accept<R, Node extends Object, Expression extends Object,
-              Variable extends Object, Type extends Object>(
-          NonPromotionReasonVisitor<R, Node, Expression, Variable, Type>
-              visitor) =>
+  R accept<R, Node extends Object, Variable extends Object,
+              Type extends Object>(
+          NonPromotionReasonVisitor<R, Node, Variable, Type> visitor) =>
       visitor.visitDemoteViaExplicitWrite(
-          this as DemoteViaExplicitWrite<Variable, Expression>);
+          this as DemoteViaExplicitWrite<Variable>);
 
   @override
-  String toString() => 'DemoteViaExplicitWrite($writeExpression)';
-}
-
-/// Non-promotion reason describing the situation where a variable was not
-/// promoted due to the variable appearing before the word `in` in a "for each"
-/// statement or a "for each" collection element.
-class DemoteViaForEachVariableWrite<Variable extends Object,
-    Node extends Object> extends NonPromotionReason {
-  /// The local variable that was not promoted.
-  final Variable variable;
-
-  /// The "for each" statement or collection element that wrote to the variable.
-  final Node node;
-
-  DemoteViaForEachVariableWrite(this.variable, this.node);
-
-  @override
-  String get shortName => 'explicitWrite';
-
-  @override
-  R accept<R, Node extends Object, Expression extends Object,
-              Variable extends Object, Type extends Object>(
-          NonPromotionReasonVisitor<R, Node, Expression, Variable, Type>
-              visitor) =>
-      visitor.visitDemoteViaForEachVariableWrite(
-          this as DemoteViaForEachVariableWrite<Variable, Node>);
-
-  @override
-  String toString() => 'DemoteViaForEachVariableWrite($node)';
+  String toString() => 'DemoteViaExplicitWrite($node)';
 }
 
 /// A collection of flow models representing the possible outcomes of evaluating
@@ -564,11 +533,8 @@
   /// - Call [forEach_end].
   ///
   /// [node] should be the same node that was passed to
-  /// [AssignedVariables.endNode] for the for statement.  [loopVariable] should
-  /// be the variable assigned to by the loop (if it is promotable, otherwise
-  /// null).  [writtenType] should be the type written to that variable (i.e.
-  /// if the loop iterates over `List<Foo>`, it should be `Foo`).
-  void forEach_bodyBegin(Node node, Variable? loopVariable, Type writtenType);
+  /// [AssignedVariables.endNode] for the for statement.
+  void forEach_bodyBegin(Node node);
 
   /// Call this method just before visiting the body of a "for-in" statement or
   /// collection element.  See [forEach_bodyBegin] for details.
@@ -894,11 +860,7 @@
 
   /// Call this method just after visiting a "try/finally" statement.
   /// See [tryFinallyStatement_bodyBegin] for details.
-  ///
-  /// [finallyBlock] should be the same node that was passed to
-  /// [AssignedVariables.endNode] for the "finally" part of the try/finally
-  /// statement.
-  void tryFinallyStatement_end(Node finallyBlock);
+  void tryFinallyStatement_end();
 
   /// Call this method just before visiting the finally block of a "try/finally"
   /// statement.  See [tryFinallyStatement_bodyBegin] for details.
@@ -934,33 +896,58 @@
   /// promotion, to retrieve information about why [target] was not promoted.
   /// This call must be made right after visiting [target].
   ///
-  /// The returned value is a map whose keys are types that the user might have
-  /// been expecting the target to be promoted to, and whose values are reasons
-  /// why the corresponding promotion did not occur.  The caller is expected to
-  /// select which non-promotion reason to report to the user by seeing which
-  /// promotion would have prevented the error.  (For example, if an error
-  /// occurs due to the target having a nullable type, the caller should report
-  /// a non-promotion reason associated with non-promotion to a non-nullable
-  /// type).
-  Map<Type, NonPromotionReason> whyNotPromoted(Expression target);
+  /// The returned value is a function yielding a map whose keys are types that
+  /// the user might have been expecting the target to be promoted to, and whose
+  /// values are reasons why the corresponding promotion did not occur.  The
+  /// caller is expected to select which non-promotion reason to report to the
+  /// user by seeing which promotion would have prevented the error.  (For
+  /// example, if an error occurs due to the target having a nullable type, the
+  /// caller should report a non-promotion reason associated with non-promotion
+  /// to a non-nullable type).
+  ///
+  /// This method is expected to execute fairly efficiently; the bulk of the
+  /// expensive computation is deferred to the function it returns.  The reason
+  /// for this is that in certain cases, it's not possible to know whether "why
+  /// not promoted" information will be needed until long after visiting a node.
+  /// (For example, in resolving a call like
+  /// `(x as Future<T>).then(y, onError: z)`, we don't know whether an error
+  /// should be reported at `y` until we've inferred the type argument to
+  /// `then`, which doesn't occur until after visiting `z`).  So the caller may
+  /// freely call this method after any expression for which an error *might*
+  /// need to be generated, and then defer invoking the returned function until
+  /// it is determined that an error actually occurred.
+  Map<Type, NonPromotionReason> Function() whyNotPromoted(Expression target);
 
   /// Call this method when an error occurs that may be due to a lack of type
   /// promotion, to retrieve information about why an implicit reference to
   /// `this` was not promoted.  [staticType] is the (unpromoted) type of `this`.
   ///
-  /// The returned value is a map whose keys are types that the user might have
-  /// been expecting the target to be promoted to, and whose values are reasons
-  /// why the corresponding promotion did not occur.  The caller is expected to
-  /// select which non-promotion reason to report to the user by seeing which
-  /// promotion would have prevented the error.  (For example, if an error
-  /// occurs due to the target having a nullable type, the caller should report
-  /// a non-promotion reason associated with non-promotion to a non-nullable
-  /// type).
-  Map<Type, NonPromotionReason> whyNotPromotedImplicitThis(Type staticType);
+  /// The returned value is a function yielding a map whose keys are types that
+  /// the user might have been expecting `this` to be promoted to, and whose
+  /// values are reasons why the corresponding promotion did not occur.  The
+  /// caller is expected to select which non-promotion reason to report to the
+  /// user by seeing which promotion would have prevented the error.  (For
+  /// example, if an error occurs due to the target having a nullable type, the
+  /// caller should report a non-promotion reason associated with non-promotion
+  /// to a non-nullable type).
+  ///
+  /// This method is expected to execute fairly efficiently; the bulk of the
+  /// expensive computation is deferred to the function it returns.  The reason
+  /// for this is that in certain cases, it's not possible to know whether "why
+  /// not promoted" information will be needed until long after visiting a node.
+  /// (For example, in resolving a call like
+  /// `(x as Future<T>).then(y, onError: z)`, we don't know whether an error
+  /// should be reported at `y` until we've inferred the type argument to
+  /// `then`, which doesn't occur until after visiting `z`).  So the caller may
+  /// freely call this method after any expression for which an error *might*
+  /// need to be generated, and then defer invoking the returned function until
+  /// it is determined that an error actually occurred.
+  Map<Type, NonPromotionReason> Function() whyNotPromotedImplicitThis(
+      Type staticType);
 
   /// Register write of the given [variable] in the current state.
   /// [writtenType] should be the type of the value that was written.
-  /// [expression] should be the whole expression performing the write.
+  /// [node] should be the syntactic construct performing the write.
   /// [writtenExpression] should be the expression that was written, or `null`
   /// if the expression that was written is not directly represented in the
   /// source code (this happens, for example, with compound assignments and with
@@ -969,7 +956,7 @@
   /// This should also be used for the implicit write to a non-final variable in
   /// its initializer, to ensure that the type is promoted to non-nullable if
   /// necessary; in this case, [viaInitializer] should be `true`.
-  void write(Expression expression, Variable variable, Type writtenType,
+  void write(Node node, Variable variable, Type writtenType,
       Expression? writtenExpression);
 
   /// Prints out a summary of the current state of flow analysis, intended for
@@ -1140,9 +1127,9 @@
   }
 
   @override
-  void forEach_bodyBegin(Node node, Variable? loopVariable, Type writtenType) {
-    return _wrap('forEach_bodyBegin($node, $loopVariable, $writtenType)',
-        () => _wrapped.forEach_bodyBegin(node, loopVariable, writtenType));
+  void forEach_bodyBegin(Node node) {
+    return _wrap(
+        'forEach_bodyBegin($node)', () => _wrapped.forEach_bodyBegin(node));
   }
 
   @override
@@ -1439,9 +1426,9 @@
   }
 
   @override
-  void tryFinallyStatement_end(Node finallyBlock) {
-    return _wrap('tryFinallyStatement_end($finallyBlock)',
-        () => _wrapped.tryFinallyStatement_end(finallyBlock));
+  void tryFinallyStatement_end() {
+    return _wrap(
+        'tryFinallyStatement_end()', () => _wrapped.tryFinallyStatement_end());
   }
 
   @override
@@ -1476,26 +1463,25 @@
   }
 
   @override
-  Map<Type, NonPromotionReason> whyNotPromoted(Expression target) {
+  Map<Type, NonPromotionReason> Function() whyNotPromoted(Expression target) {
     return _wrap(
         'whyNotPromoted($target)', () => _wrapped.whyNotPromoted(target),
         isQuery: true);
   }
 
   @override
-  Map<Type, NonPromotionReason> whyNotPromotedImplicitThis(Type staticType) {
+  Map<Type, NonPromotionReason> Function() whyNotPromotedImplicitThis(
+      Type staticType) {
     return _wrap('whyNotPromotedImplicitThis($staticType)',
         () => _wrapped.whyNotPromotedImplicitThis(staticType),
         isQuery: true);
   }
 
   @override
-  void write(Expression expression, Variable variable, Type writtenType,
+  void write(Node node, Variable variable, Type writtenType,
       Expression? writtenExpression) {
-    _wrap(
-        'write($expression, $variable, $writtenType, $writtenExpression)',
-        () => _wrapped.write(
-            expression, variable, writtenType, writtenExpression));
+    _wrap('write($node, $variable, $writtenType, $writtenExpression)',
+        () => _wrapped.write(node, variable, writtenType, writtenExpression));
   }
 
   @override
@@ -2315,26 +2301,27 @@
 
 /// Abstract class representing a reason why something was not promoted.
 abstract class NonPromotionReason {
+  /// Link to documentation describing this non-promotion reason; this should be
+  /// presented to the user as a source of additional information about the
+  /// error.
+  String get documentationLink;
+
   /// Short text description of this non-promotion reason; intended for ID
   /// testing.
   String get shortName;
 
   /// Implementation of the visitor pattern for non-promotion reasons.
-  R accept<R, Node extends Object, Expression extends Object,
-          Variable extends Object, Type extends Object>(
-      NonPromotionReasonVisitor<R, Node, Expression, Variable, Type> visitor);
+  R accept<R, Node extends Object, Variable extends Object,
+          Type extends Object>(
+      NonPromotionReasonVisitor<R, Node, Variable, Type> visitor);
 }
 
 /// Implementation of the visitor pattern for non-promotion reasons.
 abstract class NonPromotionReasonVisitor<R, Node extends Object,
-    Expression extends Object, Variable extends Object, Type extends Object> {
+    Variable extends Object, Type extends Object> {
   NonPromotionReasonVisitor._() : assert(false, 'Do not extend this class');
 
-  R visitDemoteViaExplicitWrite(
-      DemoteViaExplicitWrite<Variable, Expression> reason);
-
-  R visitDemoteViaForEachVariableWrite(
-      DemoteViaForEachVariableWrite<Variable, Node> reason);
+  R visitDemoteViaExplicitWrite(DemoteViaExplicitWrite<Variable> reason);
 
   R visitPropertyNotPromoted(PropertyNotPromoted<Type> reason);
 
@@ -2355,13 +2342,15 @@
   PropertyNotPromoted(this.propertyName, this.staticType);
 
   @override
+  String get documentationLink => 'http://dart.dev/go/non-promo-property';
+
+  @override
   String get shortName => 'propertyNotPromoted';
 
   @override
-  R accept<R, Node extends Object, Expression extends Object,
-              Variable extends Object, Type extends Object>(
-          NonPromotionReasonVisitor<R, Node, Expression, Variable, Type>
-              visitor) =>
+  R accept<R, Node extends Object, Variable extends Object,
+              Type extends Object>(
+          NonPromotionReasonVisitor<R, Node, Variable, Type> visitor) =>
       visitor.visitPropertyNotPromoted(this as PropertyNotPromoted<Type>);
 }
 
@@ -2521,7 +2510,7 @@
 
   /// Gets a map of non-promotion reasons associated with this reference.  This
   /// is the map that will be returned from [FlowAnalysis.whyNotPromoted].
-  Map<Type, NonPromotionReason> getNonPromotionReasons(
+  Map<Type, NonPromotionReason> Function() getNonPromotionReasons(
       Map<Variable?, VariableModel<Variable, Type>> variableInfo,
       Type staticType,
       TypeOperations<Variable, Type> typeOperations);
@@ -2590,13 +2579,15 @@
 /// promoted due to the fact that it's a reference to `this`.
 class ThisNotPromoted extends NonPromotionReason {
   @override
+  String get documentationLink => 'http://dart.dev/go/non-promo-this';
+
+  @override
   String get shortName => 'thisNotPromoted';
 
   @override
-  R accept<R, Node extends Object, Expression extends Object,
-              Variable extends Object, Type extends Object>(
-          NonPromotionReasonVisitor<R, Node, Expression, Variable, Type>
-              visitor) =>
+  R accept<R, Node extends Object, Variable extends Object,
+              Type extends Object>(
+          NonPromotionReasonVisitor<R, Node, Variable, Type> visitor) =>
       visitor.visitThisNotPromoted(this);
 }
 
@@ -3254,13 +3245,16 @@
   VariableReference(this.variable);
 
   @override
-  Map<Type, NonPromotionReason> getNonPromotionReasons(
+  Map<Type, NonPromotionReason> Function() getNonPromotionReasons(
       Map<Variable?, VariableModel<Variable, Type>> variableInfo,
       Type staticType,
       TypeOperations<Variable, Type> typeOperations) {
-    Map<Type, NonPromotionReason> result = <Type, NonPromotionReason>{};
     VariableModel<Variable, Type>? currentVariableInfo = variableInfo[variable];
-    if (currentVariableInfo != null) {
+    if (currentVariableInfo == null) {
+      return () => {};
+    }
+    return () {
+      Map<Type, NonPromotionReason> result = <Type, NonPromotionReason>{};
       Type currentType = currentVariableInfo.promotedTypes?.last ??
           typeOperations.variableType(variable);
       NonPromotionHistory? nonPromotionHistory =
@@ -3272,8 +3266,8 @@
         }
         nonPromotionHistory = nonPromotionHistory.previous;
       }
-    }
-    return result;
+      return result;
+    };
   }
 
   @override
@@ -3288,6 +3282,8 @@
       variableInfo[variable];
 }
 
+class WhyNotPromotedInfo {}
+
 /// [_FlowContext] representing an assert statement or assert initializer.
 class _AssertContext<Variable extends Object, Type extends Object>
     extends _SimpleContext<Variable, Type> {
@@ -3641,7 +3637,7 @@
   }
 
   @override
-  void forEach_bodyBegin(Node node, Variable? loopVariable, Type writtenType) {
+  void forEach_bodyBegin(Node node) {
     AssignedVariablesNodeInfo<Variable> info =
         _assignedVariables._getInfoForNode(node);
     _current = _current.conservativeJoin(info._written, info._captured).split();
@@ -3649,14 +3645,6 @@
         new _SimpleStatementContext<Variable, Type>(
             _current.reachable.parent!, _current);
     _stack.add(context);
-    if (loopVariable != null) {
-      _current = _current.write(
-          new DemoteViaForEachVariableWrite<Variable, Node>(loopVariable, node),
-          loopVariable,
-          writtenType,
-          new SsaNode<Variable, Type>(null),
-          typeOperations);
-    }
   }
 
   @override
@@ -4065,7 +4053,7 @@
       Variable? exceptionVariable, Variable? stackTraceVariable) {
     _TryContext<Variable, Type> context =
         _stack.last as _TryContext<Variable, Type>;
-    _current = context._beforeCatch;
+    _current = context._beforeCatch!;
     if (exceptionVariable != null) {
       _current = _current.declare(exceptionVariable, true);
     }
@@ -4086,7 +4074,7 @@
   void tryCatchStatement_end() {
     _TryContext<Variable, Type> context =
         _stack.removeLast() as _TryContext<Variable, Type>;
-    _current = context._afterBodyAndCatches.unsplit();
+    _current = context._afterBodyAndCatches!.unsplit();
   }
 
   @override
@@ -4095,13 +4083,10 @@
   }
 
   @override
-  void tryFinallyStatement_end(Node finallyBlock) {
-    // We used to need info for `finally` blocks but we don't anymore.
-    assert(!_assignedVariables._hasInfoForNode(finallyBlock),
-        'No assigned variables info should have been stored for $finallyBlock');
+  void tryFinallyStatement_end() {
     _TryFinallyContext<Variable, Type> context =
         _stack.removeLast() as _TryFinallyContext<Variable, Type>;
-    _current = context._afterBodyAndCatches
+    _current = context._afterBodyAndCatches!
         .attachFinally(typeOperations, context._beforeFinally, _current);
   }
 
@@ -4164,23 +4149,27 @@
   }
 
   @override
-  Map<Type, NonPromotionReason> whyNotPromoted(Expression target) {
-    ReferenceWithType<Variable, Type>? referenceWithType = _expressionReference;
-    if (referenceWithType != null) {
-      return referenceWithType.reference.getNonPromotionReasons(
-          _current.variableInfo, referenceWithType.type, typeOperations);
+  Map<Type, NonPromotionReason> Function() whyNotPromoted(Expression target) {
+    if (identical(target, _expressionWithReference)) {
+      ReferenceWithType<Variable, Type>? referenceWithType =
+          _expressionReference;
+      if (referenceWithType != null) {
+        return referenceWithType.reference.getNonPromotionReasons(
+            _current.variableInfo, referenceWithType.type, typeOperations);
+      }
     }
-    return {};
+    return () => {};
   }
 
   @override
-  Map<Type, NonPromotionReason> whyNotPromotedImplicitThis(Type staticType) {
+  Map<Type, NonPromotionReason> Function() whyNotPromotedImplicitThis(
+      Type staticType) {
     return new _ThisReference<Variable, Type>().getNonPromotionReasons(
         _current.variableInfo, staticType, typeOperations);
   }
 
   @override
-  void write(Expression expression, Variable variable, Type writtenType,
+  void write(Node node, Variable variable, Type writtenType,
       Expression? writtenExpression) {
     ExpressionInfo<Variable, Type>? expressionInfo = writtenExpression == null
         ? null
@@ -4188,7 +4177,7 @@
     SsaNode<Variable, Type> newSsaNode = new SsaNode<Variable, Type>(
         expressionInfo is _TrivialExpressionInfo ? null : expressionInfo);
     _current = _current.write(
-        new DemoteViaExplicitWrite<Variable, Expression>(variable, expression),
+        new DemoteViaExplicitWrite<Variable>(variable, node),
         variable,
         writtenType,
         newSsaNode,
@@ -4469,8 +4458,7 @@
   void for_updaterBegin() {}
 
   @override
-  void forEach_bodyBegin(
-      Node node, Variable? loopVariable, Type? writtenType) {}
+  void forEach_bodyBegin(Node node) {}
 
   @override
   void forEach_end() {}
@@ -4741,7 +4729,7 @@
   void tryFinallyStatement_bodyBegin() {}
 
   @override
-  void tryFinallyStatement_end(Node finallyBlock) {}
+  void tryFinallyStatement_end() {}
 
   @override
   void tryFinallyStatement_finallyBegin(Node body) {}
@@ -4764,17 +4752,18 @@
   void whileStatement_end() {}
 
   @override
-  Map<Type, NonPromotionReason> whyNotPromoted(Expression target) {
-    return {};
+  Map<Type, NonPromotionReason> Function() whyNotPromoted(Expression target) {
+    return () => {};
   }
 
   @override
-  Map<Type, NonPromotionReason> whyNotPromotedImplicitThis(Type staticType) {
-    return {};
+  Map<Type, NonPromotionReason> Function() whyNotPromotedImplicitThis(
+      Type staticType) {
+    return () => {};
   }
 
   @override
-  void write(Expression expression, Variable variable, Type writtenType,
+  void write(Node node, Variable variable, Type writtenType,
       Expression? writtenExpression) {
     assert(
         _assignedVariables._anywhere._written.contains(variable),
@@ -4922,18 +4911,21 @@
   _PropertyGetReference(this.target, this.propertyName);
 
   @override
-  Map<Type, NonPromotionReason> getNonPromotionReasons(
+  Map<Type, NonPromotionReason> Function() getNonPromotionReasons(
       Map<Variable?, VariableModel<Variable, Type>> variableInfo,
       Type staticType,
       TypeOperations<Variable, Type> typeOperations) {
-    Map<Type, NonPromotionReason> result = <Type, NonPromotionReason>{};
     List<Type>? promotedTypes = _getInfo(variableInfo)?.promotedTypes;
     if (promotedTypes != null) {
-      for (Type type in promotedTypes) {
-        result[type] = new PropertyNotPromoted(propertyName, staticType);
-      }
+      return () {
+        Map<Type, NonPromotionReason> result = <Type, NonPromotionReason>{};
+        for (Type type in promotedTypes) {
+          result[type] = new PropertyNotPromoted(propertyName, staticType);
+        }
+        return result;
+      };
     }
-    return result;
+    return () => {};
   }
 
   @override
@@ -4994,18 +4986,21 @@
 class _ThisReference<Variable extends Object, Type extends Object>
     extends Reference<Variable, Type> {
   @override
-  Map<Type, NonPromotionReason> getNonPromotionReasons(
+  Map<Type, NonPromotionReason> Function() getNonPromotionReasons(
       Map<Variable?, VariableModel<Variable, Type>> variableInfo,
       Type staticType,
       TypeOperations<Variable, Type> typeOperations) {
-    Map<Type, NonPromotionReason> result = <Type, NonPromotionReason>{};
     List<Type>? promotedTypes = _getInfo(variableInfo)?.promotedTypes;
     if (promotedTypes != null) {
-      for (Type type in promotedTypes) {
-        result[type] = new ThisNotPromoted();
-      }
+      return () {
+        Map<Type, NonPromotionReason> result = <Type, NonPromotionReason>{};
+        for (Type type in promotedTypes) {
+          result[type] = new ThisNotPromoted();
+        }
+        return result;
+      };
     }
-    return result;
+    return () => {};
   }
 
   @override
@@ -5051,14 +5046,14 @@
     extends _SimpleContext<Variable, Type> {
   /// If the statement is a "try/catch" statement, the flow model representing
   /// program state at the top of any `catch` block.
-  late final FlowModel<Variable, Type> _beforeCatch;
+  FlowModel<Variable, Type>? _beforeCatch;
 
   /// If the statement is a "try/catch" statement, the accumulated flow model
   /// representing program state after the `try` block or one of the `catch`
   /// blocks has finished executing.  If the statement is a "try/finally"
   /// statement, the flow model representing program state after the `try` block
   /// has finished executing.
-  late FlowModel<Variable, Type> _afterBodyAndCatches;
+  FlowModel<Variable, Type>? _afterBodyAndCatches;
 
   _TryContext(FlowModel<Variable, Type> previous) : super(previous);
 
diff --git a/pkg/_fe_analyzer_shared/lib/src/messages/codes.dart b/pkg/_fe_analyzer_shared/lib/src/messages/codes.dart
index bea98e1..ddb14d5 100644
--- a/pkg/_fe_analyzer_shared/lib/src/messages/codes.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/messages/codes.dart
@@ -166,7 +166,14 @@
   final String plain;
   final String colorized;
 
+  @override
+  String toString() {
+    assert(false, "Called PlainAndColorizedString.toString: $plain");
+    return 'PlainAndColorizedString:$plain';
+  }
+
   const PlainAndColorizedString(this.plain, this.colorized);
+
   const PlainAndColorizedString.plainOnly(this.plain) : this.colorized = plain;
 }
 
diff --git a/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart b/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
index d77d6dc..530baf1 100644
--- a/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
@@ -1514,7 +1514,7 @@
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const MessageCode messageConstEvalUnevaluated = const MessageCode(
     "ConstEvalUnevaluated",
-    message: r"""Could not evaluate constant expression.""");
+    message: r"""Couldn't evaluate constant expression.""");
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Template<
@@ -3884,7 +3884,7 @@
     Message Function(String name)> templateFfiNotStatic = const Template<
         Message Function(String name)>(
     messageTemplate:
-        r"""#name expects a static function as parameter. dart:ffi only supports calling static Dart functions from native code.""",
+        r"""#name expects a static function as parameter. dart:ffi only supports calling static Dart functions from native code. Closures and tear-offs are not supported because they can capture context.""",
     withArguments: _withArgumentsFfiNotStatic);
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
@@ -3899,11 +3899,73 @@
   name = demangleMixinApplicationName(name);
   return new Message(codeFfiNotStatic,
       message:
-          """${name} expects a static function as parameter. dart:ffi only supports calling static Dart functions from native code.""",
+          """${name} expects a static function as parameter. dart:ffi only supports calling static Dart functions from native code. Closures and tear-offs are not supported because they can capture context.""",
       arguments: {'name': name});
 }
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<Message Function(String name)> templateFfiPackedAnnotation =
+    const Template<Message Function(String name)>(
+        messageTemplate:
+            r"""Struct '#name' must have at most one 'Packed' annotation.""",
+        withArguments: _withArgumentsFfiPackedAnnotation);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String name)> codeFfiPackedAnnotation =
+    const Code<Message Function(String name)>(
+  "FfiPackedAnnotation",
+);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsFfiPackedAnnotation(String name) {
+  if (name.isEmpty) throw 'No name provided';
+  name = demangleMixinApplicationName(name);
+  return new Message(codeFfiPackedAnnotation,
+      message:
+          """Struct '${name}' must have at most one 'Packed' annotation.""",
+      arguments: {'name': name});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Null> codeFfiPackedAnnotationAlignment =
+    messageFfiPackedAnnotationAlignment;
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const MessageCode messageFfiPackedAnnotationAlignment = const MessageCode(
+    "FfiPackedAnnotationAlignment",
+    message: r"""Only packing to 1, 2, 4, 8, and 16 bytes is supported.""");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<
+    Message Function(
+        String name,
+        String
+            name2)> templateFfiPackedNestingNonPacked = const Template<
+        Message Function(String name, String name2)>(
+    messageTemplate:
+        r"""Nesting the non-packed or less tightly packed struct '#name' in a packed struct '#name2' is not supported.""",
+    withArguments: _withArgumentsFfiPackedNestingNonPacked);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String name, String name2)>
+    codeFfiPackedNestingNonPacked =
+    const Code<Message Function(String name, String name2)>(
+  "FfiPackedNestingNonPacked",
+);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsFfiPackedNestingNonPacked(String name, String name2) {
+  if (name.isEmpty) throw 'No name provided';
+  name = demangleMixinApplicationName(name);
+  if (name2.isEmpty) throw 'No name provided';
+  name2 = demangleMixinApplicationName(name2);
+  return new Message(codeFfiPackedNestingNonPacked,
+      message:
+          """Nesting the non-packed or less tightly packed struct '${name}' in a packed struct '${name2}' is not supported.""",
+      arguments: {'name': name, 'name2': name2});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Template<Message Function(String name)> templateFfiSizeAnnotation =
     const Template<Message Function(String name)>(
         messageTemplate:
@@ -3926,6 +3988,32 @@
 }
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<
+    Message Function(
+        String
+            name)> templateFfiSizeAnnotationDimensions = const Template<
+        Message Function(String name)>(
+    messageTemplate:
+        r"""Field '#name' must have an 'Array' annotation that matches the dimensions.""",
+    withArguments: _withArgumentsFfiSizeAnnotationDimensions);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String name)> codeFfiSizeAnnotationDimensions =
+    const Code<Message Function(String name)>(
+  "FfiSizeAnnotationDimensions",
+);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsFfiSizeAnnotationDimensions(String name) {
+  if (name.isEmpty) throw 'No name provided';
+  name = demangleMixinApplicationName(name);
+  return new Message(codeFfiSizeAnnotationDimensions,
+      message:
+          """Field '${name}' must have an 'Array' annotation that matches the dimensions.""",
+      arguments: {'name': name});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Template<Message Function(String name)> templateFfiStructGeneric =
     const Template<Message Function(String name)>(
         messageTemplate: r"""Struct '#name' should not be generic.""",
@@ -4022,26 +4110,29 @@
     tip: r"""Try removing 'this.'.""");
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const Template<Message Function(String name)> templateFieldNotPromoted =
-    const Template<Message Function(String name)>(
+const Template<Message Function(String name, String string)>
+    templateFieldNotPromoted =
+    const Template<Message Function(String name, String string)>(
         messageTemplate:
-            r"""'#name' refers to a property so it could not be promoted.""",
+            r"""'#name' refers to a property so it couldn't be promoted.""",
+        tipTemplate: r"""See #string""",
         withArguments: _withArgumentsFieldNotPromoted);
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const Code<Message Function(String name)> codeFieldNotPromoted =
-    const Code<Message Function(String name)>(
+const Code<Message Function(String name, String string)> codeFieldNotPromoted =
+    const Code<Message Function(String name, String string)>(
   "FieldNotPromoted",
 );
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-Message _withArgumentsFieldNotPromoted(String name) {
+Message _withArgumentsFieldNotPromoted(String name, String string) {
   if (name.isEmpty) throw 'No name provided';
   name = demangleMixinApplicationName(name);
+  if (string.isEmpty) throw 'No string provided';
   return new Message(codeFieldNotPromoted,
-      message:
-          """'${name}' refers to a property so it could not be promoted.""",
-      arguments: {'name': name});
+      message: """'${name}' refers to a property so it couldn't be promoted.""",
+      tip: """See ${string}""",
+      arguments: {'name': name, 'string': string});
 }
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
@@ -6221,6 +6312,65 @@
     message: r"""List literal requires exactly one type argument.""");
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<Message Function(String string, Token token)>
+    templateLiteralWithClass =
+    const Template<Message Function(String string, Token token)>(
+        messageTemplate:
+            r"""A #string literal can't be prefixed by '#lexeme'.""",
+        tipTemplate: r"""Try removing '#lexeme'""",
+        withArguments: _withArgumentsLiteralWithClass);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String string, Token token)> codeLiteralWithClass =
+    const Code<Message Function(String string, Token token)>("LiteralWithClass",
+        index: 116);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsLiteralWithClass(String string, Token token) {
+  if (string.isEmpty) throw 'No string provided';
+  String lexeme = token.lexeme;
+  return new Message(codeLiteralWithClass,
+      message: """A ${string} literal can't be prefixed by '${lexeme}'.""",
+      tip: """Try removing '${lexeme}'""",
+      arguments: {'string': string, 'lexeme': token});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<Message Function(String string, Token token)>
+    templateLiteralWithClassAndNew =
+    const Template<Message Function(String string, Token token)>(
+        messageTemplate:
+            r"""A #string literal can't be prefixed by 'new #lexeme'.""",
+        tipTemplate: r"""Try removing 'new' and '#lexeme'""",
+        withArguments: _withArgumentsLiteralWithClassAndNew);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String string, Token token)>
+    codeLiteralWithClassAndNew =
+    const Code<Message Function(String string, Token token)>(
+        "LiteralWithClassAndNew",
+        index: 115);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsLiteralWithClassAndNew(String string, Token token) {
+  if (string.isEmpty) throw 'No string provided';
+  String lexeme = token.lexeme;
+  return new Message(codeLiteralWithClassAndNew,
+      message: """A ${string} literal can't be prefixed by 'new ${lexeme}'.""",
+      tip: """Try removing 'new' and '${lexeme}'""",
+      arguments: {'string': string, 'lexeme': token});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Null> codeLiteralWithNew = messageLiteralWithNew;
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const MessageCode messageLiteralWithNew = const MessageCode("LiteralWithNew",
+    index: 117,
+    message: r"""A literal can't be prefixed by 'new'.""",
+    tip: r"""Try removing 'new'""");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Code<Null> codeLoadLibraryTakesNoArguments =
     messageLoadLibraryTakesNoArguments;
 
@@ -7684,11 +7834,10 @@
 }
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const Template<
-        Message Function(String name, Uri uri_)> templatePackageNotFound =
+const Template<Message Function(String name, Uri uri_)>
+    templatePackageNotFound =
     const Template<Message Function(String name, Uri uri_)>(
-        messageTemplate:
-            r"""Could not resolve the package '#name' in '#uri'.""",
+        messageTemplate: r"""Couldn't resolve the package '#name' in '#uri'.""",
         withArguments: _withArgumentsPackageNotFound);
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
@@ -7703,7 +7852,7 @@
   name = demangleMixinApplicationName(name);
   String? uri = relativizeUri(uri_);
   return new Message(codePackageNotFound,
-      message: """Could not resolve the package '${name}' in '${uri}'.""",
+      message: """Couldn't resolve the package '${name}' in '${uri}'.""",
       arguments: {'name': name, 'uri': uri_});
 }
 
@@ -8928,11 +9077,26 @@
     tip: r"""Try replacing '?.' with '.'""");
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const Code<Null> codeThisNotPromoted = messageThisNotPromoted;
+const Template<Message Function(String string)> templateThisNotPromoted =
+    const Template<Message Function(String string)>(
+        messageTemplate: r"""'this' can't be promoted.""",
+        tipTemplate: r"""See #string""",
+        withArguments: _withArgumentsThisNotPromoted);
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const MessageCode messageThisNotPromoted = const MessageCode("ThisNotPromoted",
-    message: r"""'this' can't be promoted.""");
+const Code<Message Function(String string)> codeThisNotPromoted =
+    const Code<Message Function(String string)>(
+  "ThisNotPromoted",
+);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsThisNotPromoted(String string) {
+  if (string.isEmpty) throw 'No string provided';
+  return new Message(codeThisNotPromoted,
+      message: """'this' can't be promoted.""",
+      tip: """See ${string}""",
+      arguments: {'string': string});
+}
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Template<Message Function(String string)>
@@ -9543,29 +9707,37 @@
         r"""Try removing the keyword 'var', or replacing it with the name of the return type.""");
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const Template<Message Function(String name)>
-    templateVariableCouldBeNullDueToWrite =
-    const Template<Message Function(String name)>(
-        messageTemplate:
-            r"""Variable '#name' could be null due to an intervening write.""",
-        tipTemplate: r"""Try null checking the variable after the write.""",
-        withArguments: _withArgumentsVariableCouldBeNullDueToWrite);
+const Template<
+    Message Function(
+        String name,
+        String
+            string)> templateVariableCouldBeNullDueToWrite = const Template<
+        Message Function(String name, String string)>(
+    messageTemplate:
+        r"""Variable '#name' could not be promoted due to an assignment.""",
+    tipTemplate:
+        r"""Try null checking the variable after the assignment.  See #string""",
+    withArguments: _withArgumentsVariableCouldBeNullDueToWrite);
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const Code<Message Function(String name)> codeVariableCouldBeNullDueToWrite =
-    const Code<Message Function(String name)>(
+const Code<Message Function(String name, String string)>
+    codeVariableCouldBeNullDueToWrite =
+    const Code<Message Function(String name, String string)>(
   "VariableCouldBeNullDueToWrite",
 );
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-Message _withArgumentsVariableCouldBeNullDueToWrite(String name) {
+Message _withArgumentsVariableCouldBeNullDueToWrite(
+    String name, String string) {
   if (name.isEmpty) throw 'No name provided';
   name = demangleMixinApplicationName(name);
+  if (string.isEmpty) throw 'No string provided';
   return new Message(codeVariableCouldBeNullDueToWrite,
       message:
-          """Variable '${name}' could be null due to an intervening write.""",
-      tip: """Try null checking the variable after the write.""",
-      arguments: {'name': name});
+          """Variable '${name}' could not be promoted due to an assignment.""",
+      tip:
+          """Try null checking the variable after the assignment.  See ${string}""",
+      arguments: {'name': name, 'string': string});
 }
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
diff --git a/pkg/_fe_analyzer_shared/lib/src/parser/forwarding_listener.dart b/pkg/_fe_analyzer_shared/lib/src/parser/forwarding_listener.dart
index 0274d64..1402102 100644
--- a/pkg/_fe_analyzer_shared/lib/src/parser/forwarding_listener.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/parser/forwarding_listener.dart
@@ -1174,6 +1174,11 @@
   }
 
   @override
+  void handleConstFactory(Token constKeyword) {
+    listener?.handleConstFactory(constKeyword);
+  }
+
+  @override
   void handleContinueStatement(
       bool hasTarget, Token continueKeyword, Token endToken) {
     listener?.handleContinueStatement(hasTarget, continueKeyword, endToken);
diff --git a/pkg/_fe_analyzer_shared/lib/src/parser/listener.dart b/pkg/_fe_analyzer_shared/lib/src/parser/listener.dart
index bb635b6..0e08a2e 100644
--- a/pkg/_fe_analyzer_shared/lib/src/parser/listener.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/parser/listener.dart
@@ -1360,6 +1360,10 @@
     logEvent("ConstExpression");
   }
 
+  void handleConstFactory(Token constKeyword) {
+    logEvent("ConstFactory");
+  }
+
   /// Called before parsing a "for" control flow list, set, or map entry.
   /// Ended by either [endForControlFlow] or [endForInControlFlow].
   void beginForControlFlow(Token? awaitToken, Token forToken) {}
diff --git a/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart b/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart
index c98702e..93d7a7b 100644
--- a/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart
@@ -1044,10 +1044,43 @@
   }
 
   /// ```
-  /// annotation:
-  ///   '@' qualified ('.' identifier)? arguments?
-  /// ;
+  /// <metadata> ::= (‘@’ <metadatum>)*
+  /// <metadatum> ::= <identifier>
+  ///   | <qualifiedName>
+  ///   | <constructorDesignation> <arguments>
+  /// <qualifiedName> ::= <typeIdentifier> ‘.’ <identifier>
+  ///   | <typeIdentifier> ‘.’ <typeIdentifier> ‘.’ <identifier>
+  /// <constructorDesignation> ::= <typeIdentifier>
+  ///   | <qualifiedName>
+  ///   | <typeName> <typeArguments> (‘.’ <identifier>)?
+  /// <typeName> ::= <typeIdentifier> (‘.’ <typeIdentifier>)?
   /// ```
+  /// (where typeIdentifier is an identifier that's not on the list of
+  /// built in identifiers)
+  /// So these are legal:
+  /// * identifier
+  /// qualifiedName:
+  /// * typeIdentifier.identifier
+  /// * typeIdentifier.typeIdentifier.identifier
+  /// via constructorDesignation part 1
+  /// * typeIdentifier(arguments)
+  /// via constructorDesignation part 2
+  /// * typeIdentifier.identifier(arguments)
+  /// * typeIdentifier.typeIdentifier.identifier(arguments)
+  /// via constructorDesignation part 3
+  /// * typeIdentifier<typeArguments>(arguments)
+  /// * typeIdentifier<typeArguments>.identifier(arguments)
+  /// * typeIdentifier.typeIdentifier<typeArguments>(arguments)
+  /// * typeIdentifier.typeIdentifier<typeArguments>.identifier(arguments)
+  ///
+  /// So in another way (ignoring the difference between typeIdentifier and
+  /// identifier):
+  /// * 1, 2 or 3 identifiers with or without arguments.
+  /// * 1 or 2 identifiers, then type arguments, then possibly followed by a
+  ///   single identifier, and then (required!) arguments.
+  ///
+  /// Note that if this is updated [skipMetadata] (in util.dart) should be
+  /// updated as well.
   Token parseMetadata(Token token) {
     Token atToken = token.next!;
     assert(optional('@', atToken));
@@ -2377,6 +2410,10 @@
     return identifier;
   }
 
+  /// Checks whether the next token is (directly) an identifier. If this returns
+  /// true a call to [ensureIdentifier] will return the next token.
+  bool isNextIdentifier(Token token) => token.next?.kind == IDENTIFIER_TOKEN;
+
   /// Parse a simple identifier at the given [token], and return the identifier
   /// that was parsed.
   ///
@@ -3790,7 +3827,13 @@
         varFinalOrConst, getOrSet, name);
 
     Token token = typeInfo.parseType(beforeType, this);
-    assert(token.next == (getOrSet ?? name));
+    assert(token.next == (getOrSet ?? name) ||
+        // [skipType] and [parseType] for something ending in `>>` is different
+        // because [`>>`] is split to [`>`, `>`] in both cases. For skip it's
+        // cached as the end but for parse a new pair is created (which is also
+        // woven into the token stream). At least for now we allow this and let
+        // the assert not fail because of it.
+        (token.next!.type == name.type && token.next!.offset == name.offset));
     token = getOrSet ?? token;
 
     bool hasQualifiedName = false;
@@ -4020,7 +4063,7 @@
     } else {
       if (varFinalOrConst != null && !optional('native', next)) {
         if (optional('const', varFinalOrConst)) {
-          reportRecoverableError(varFinalOrConst, codes.messageConstFactory);
+          listener.handleConstFactory(varFinalOrConst);
         }
       }
       token = parseFunctionBody(
@@ -5709,8 +5752,66 @@
   Token parseNewExpression(Token token) {
     Token newKeyword = token.next!;
     assert(optional('new', newKeyword));
+
+    TypeParamOrArgInfo? potentialTypeArg;
+
+    if (isNextIdentifier(newKeyword)) {
+      Token identifier = newKeyword.next!;
+      String value = identifier.lexeme;
+      if ((value == "Map" || value == "Set") &&
+          !optional('.', identifier.next!)) {
+        potentialTypeArg = computeTypeParamOrArg(identifier);
+        Token afterToken = potentialTypeArg.skip(identifier).next!;
+        if (optional('{', afterToken)) {
+          // Recover by ignoring both the `new` and the `Map`/`Set` and parse as
+          // a literal map/set.
+          reportRecoverableErrorWithEnd(
+              newKeyword,
+              identifier,
+              codes.templateLiteralWithClassAndNew
+                  .withArguments(value.toLowerCase(), identifier));
+          return parsePrimary(identifier, IdentifierContext.expression);
+        }
+      } else if (value == "List" && !optional('.', identifier.next!)) {
+        potentialTypeArg = computeTypeParamOrArg(identifier);
+        Token afterToken = potentialTypeArg.skip(identifier).next!;
+        if (optional('[', afterToken) || optional('[]', afterToken)) {
+          // Recover by ignoring both the `new` and the `List` and parse as
+          // a literal list.
+          reportRecoverableErrorWithEnd(
+              newKeyword,
+              identifier,
+              codes.templateLiteralWithClassAndNew
+                  .withArguments(value.toLowerCase(), identifier));
+          return parsePrimary(identifier, IdentifierContext.expression);
+        }
+      }
+    } else {
+      // This is probably an error. "Normal" recovery will happen in
+      // parseConstructorReference.
+      // Do special recovery for literal maps/set/list erroneously prepended
+      // with 'new'.
+      Token notIdentifier = newKeyword.next!;
+      String value = notIdentifier.lexeme;
+      if (value == "<") {
+        potentialTypeArg = computeTypeParamOrArg(newKeyword);
+        Token afterToken = potentialTypeArg.skip(newKeyword).next!;
+        if (optional('{', afterToken) ||
+            optional('[', afterToken) ||
+            optional('[]', afterToken)) {
+          // Recover by ignoring the `new` and parse as a literal map/set/list.
+          reportRecoverableError(newKeyword, codes.messageLiteralWithNew);
+          return parsePrimary(newKeyword, IdentifierContext.expression);
+        }
+      } else if (value == "{" || value == "[" || value == "[]") {
+        // Recover by ignoring the `new` and parse as a literal map/set/list.
+        reportRecoverableError(newKeyword, codes.messageLiteralWithNew);
+        return parsePrimary(newKeyword, IdentifierContext.expression);
+      }
+    }
+
     listener.beginNewExpression(newKeyword);
-    token = parseConstructorReference(newKeyword);
+    token = parseConstructorReference(newKeyword, potentialTypeArg);
     token = parseConstructorInvocationArguments(token);
     listener.endNewExpression(newKeyword);
     return token;
@@ -5768,8 +5869,75 @@
       listener.endConstLiteral(token.next!);
       return token;
     }
+    final String lexeme = next.lexeme;
+    Token nextNext = next.next!;
+    TypeParamOrArgInfo? potentialTypeArg;
+    if ((lexeme == "Map" || lexeme == "Set") && !optional('.', nextNext)) {
+      // Special-case-recovery for `const Map<..>?{}` and `const Set<..>?{}`.
+      potentialTypeArg = computeTypeParamOrArg(next);
+      Token afterToken = potentialTypeArg.skip(next).next!;
+      if (optional('{', afterToken)) {
+        final String? nextValue = nextNext.stringValue;
+        if (identical(nextValue, '{')) {
+          // Recover by ignoring the `Map`/`Set` and parse as a literal map/set.
+          reportRecoverableError(
+              next,
+              codes.templateLiteralWithClass
+                  .withArguments(lexeme.toLowerCase(), next));
+          listener.beginConstLiteral(nextNext);
+          listener.handleNoTypeArguments(nextNext);
+          token = parseLiteralSetOrMapSuffix(next, constKeyword);
+          listener.endConstLiteral(token.next!);
+          return token;
+        }
+        if (identical(nextValue, '<')) {
+          // Recover by ignoring the `Map`/`Set` and parse as a literal map/set.
+          reportRecoverableError(
+              next,
+              codes.templateLiteralWithClass
+                  .withArguments(lexeme.toLowerCase(), next));
+
+          listener.beginConstLiteral(nextNext);
+          token = parseLiteralListSetMapOrFunction(next, constKeyword);
+          listener.endConstLiteral(token.next!);
+          return token;
+        }
+        assert(false, "Expected either { or < but found neither.");
+      }
+    } else if (lexeme == "List" && !optional('.', nextNext)) {
+      // Special-case-recovery for `const List<..>?[` and `const List<..>?[]`.
+      potentialTypeArg = computeTypeParamOrArg(next);
+      Token afterToken = potentialTypeArg.skip(next).next!;
+      if (optional('[', afterToken) || optional('[]', afterToken)) {
+        final String? nextValue = nextNext.stringValue;
+        if (identical(nextValue, '[') || identical(nextValue, '[]')) {
+          // Recover by ignoring the `List` and parse as a literal list.
+          reportRecoverableError(
+              next,
+              codes.templateLiteralWithClass
+                  .withArguments(lexeme.toLowerCase(), next));
+          listener.beginConstLiteral(nextNext);
+          listener.handleNoTypeArguments(nextNext);
+          token = parseLiteralListSuffix(next, constKeyword);
+          listener.endConstLiteral(token.next!);
+          return token;
+        }
+        if (identical(nextValue, '<')) {
+          // Recover by ignoring the `List` and parse as a literal list.
+          reportRecoverableError(
+              next,
+              codes.templateLiteralWithClass
+                  .withArguments(lexeme.toLowerCase(), next));
+          listener.beginConstLiteral(nextNext);
+          token = parseLiteralListSetMapOrFunction(next, constKeyword);
+          listener.endConstLiteral(token.next!);
+          return token;
+        }
+        assert(false, "Expected either [, [] or < but found neither.");
+      }
+    }
     listener.beginConstExpression(constKeyword);
-    token = parseConstructorReference(token);
+    token = parseConstructorReference(token, potentialTypeArg);
     token = parseConstructorInvocationArguments(token);
     listener.endConstExpression(constKeyword);
     return token;
@@ -5925,6 +6093,45 @@
   }
 
   Token parseSend(Token token, IdentifierContext context) {
+    // Least-costly recovery of `Map<...>?{`, `Set<...>?{`, `List<...>[` and
+    // `List<...>?[]`.
+    // Note that we have to "peek" into the identifier because we don't want to
+    // send an `handleIdentifier` if we end up recovering.
+    TypeParamOrArgInfo? potentialTypeArg;
+    Token? afterToken;
+    if (isNextIdentifier(token)) {
+      Token identifier = token.next!;
+      String value = identifier.lexeme;
+      if (value == "Map" || value == "Set") {
+        potentialTypeArg = computeTypeParamOrArg(identifier);
+        afterToken = potentialTypeArg.skip(identifier).next!;
+        if (optional('{', afterToken)) {
+          // Recover by ignoring the `Map`/`Set` and parse as a literal map/set.
+          reportRecoverableError(
+              identifier,
+              codes.templateLiteralWithClass
+                  .withArguments(value.toLowerCase(), identifier));
+          return parsePrimary(identifier, context);
+        }
+      } else if (value == "List") {
+        potentialTypeArg = computeTypeParamOrArg(identifier);
+        afterToken = potentialTypeArg.skip(identifier).next!;
+        if ((potentialTypeArg != noTypeParamOrArg &&
+                optional('[', afterToken)) ||
+            optional('[]', afterToken)) {
+          // Recover by ignoring the `List` and parse as a literal List.
+          // Note that we here require the `<...>` for `[` as `List[` would be
+          // an indexed expression. `List[]` wouldn't though, so we don't
+          // require it there.
+          reportRecoverableError(
+              identifier,
+              codes.templateLiteralWithClass
+                  .withArguments(value.toLowerCase(), identifier));
+          return parsePrimary(identifier, context);
+        }
+      }
+    }
+
     Token beginToken = token = ensureIdentifier(token, context);
     // Notice that we don't parse the bang (!) here as we do in many other
     // instances where we call computeMethodTypeArguments.
@@ -5933,7 +6140,18 @@
     // the type arguments and the arguments.
     // By not handling bang here we don't parse any of it, and the parser will
     // parse it correctly in a different recursion step.
-    TypeParamOrArgInfo typeArg = computeMethodTypeArguments(token);
+
+    // Special-case [computeMethodTypeArguments] to re-use potentialTypeArg if
+    // already computed.
+    potentialTypeArg ??= computeTypeParamOrArg(token);
+    afterToken ??= potentialTypeArg.skip(token).next!;
+    TypeParamOrArgInfo typeArg;
+    if (optional('(', afterToken)) {
+      typeArg = potentialTypeArg;
+    } else {
+      typeArg = noTypeParamOrArg;
+    }
+
     if (typeArg != noTypeParamOrArg) {
       token = typeArg.parseArguments(token, this);
     } else {
diff --git a/pkg/_fe_analyzer_shared/lib/src/parser/util.dart b/pkg/_fe_analyzer_shared/lib/src/parser/util.dart
index f6f1939..6891278 100644
--- a/pkg/_fe_analyzer_shared/lib/src/parser/util.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/parser/util.dart
@@ -105,10 +105,12 @@
   token = token.next!;
   assert(optional('@', token));
   Token next = token.next!;
+  // Corresponds to 'ensureIdentifier' in [parseMetadata].
   if (next.isIdentifier) {
     token = next;
     next = token.next!;
-    while (optional('.', next)) {
+    // Corresponds to 'parseQualifiedRestOpt' in [parseMetadata].
+    if (optional('.', next)) {
       token = next;
       next = token.next!;
       if (next.isIdentifier) {
@@ -116,6 +118,23 @@
         next = token.next!;
       }
     }
+    // Corresponds to 'computeTypeParamOrArg' in [parseMetadata].
+    if (optional('<', next) && !next.endGroup!.isSynthetic) {
+      token = next.endGroup!;
+      next = token.next!;
+    }
+
+    // The extra .identifier after arguments in in [parseMetadata].
+    if (optional('.', next)) {
+      token = next;
+      next = token.next!;
+      if (next.isIdentifier) {
+        token = next;
+        next = token.next!;
+      }
+    }
+
+    // Corresponds to 'parseArgumentsOpt' in [parseMetadata].
     if (optional('(', next) && !next.endGroup!.isSynthetic) {
       token = next.endGroup!;
       next = token.next!;
diff --git a/pkg/_fe_analyzer_shared/lib/src/scanner/token.dart b/pkg/_fe_analyzer_shared/lib/src/scanner/token.dart
index 6f92ebe..4cc7473 100644
--- a/pkg/_fe_analyzer_shared/lib/src/scanner/token.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/scanner/token.dart
@@ -1077,24 +1077,23 @@
   Object value();
 
   /**
-   * Compare the given [tokens] to find the token that appears first in the
+   * Compare the given tokens to find the token that appears first in the
    * source being parsed. That is, return the left-most of all of the tokens.
-   * The list must be non-`null`, but the elements of the list are allowed to be
-   * `null`. Return the token with the smallest offset, or `null` if the list is
-   * empty or if all of the elements of the list are `null`.
+   * Return the token with the smallest offset, or `null` if all of the
+   * tokens are `null`.
    */
-  static Token? lexicallyFirst(List<Token?> tokens) {
-    Token? first = null;
-    int offset = -1;
-    int length = tokens.length;
-    for (int i = 0; i < length; i++) {
-      Token? token = tokens[i];
-      if (token != null && (offset < 0 || token.offset < offset)) {
-        first = token;
-        offset = token.offset;
-      }
+  static Token? lexicallyFirst([Token? t1, Token? t2, Token? t3, Token? t4]) {
+    Token? result = t1;
+    if (result == null || t2 != null && t2.offset < result.offset) {
+      result = t2;
     }
-    return first;
+    if (result == null || t3 != null && t3.offset < result.offset) {
+      result = t3;
+    }
+    if (result == null || t4 != null && t4.offset < result.offset) {
+      result = t4;
+    }
+    return result;
   }
 }
 
diff --git a/pkg/_fe_analyzer_shared/lib/src/testing/id_testing.dart b/pkg/_fe_analyzer_shared/lib/src/testing/id_testing.dart
index 6494ac3..4baea51 100644
--- a/pkg/_fe_analyzer_shared/lib/src/testing/id_testing.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/testing/id_testing.dart
@@ -619,7 +619,7 @@
         print('--annotations diff [${uri.pathSegments.last}]-------------');
         AnnotatedCode? annotatedCode = code[uri];
         print(new AnnotatedCode(annotatedCode?.annotatedCode ?? "",
-                annotatedCode?.sourceCode ?? "", annotations[uri]!)
+                annotatedCode?.sourceCode ?? "", annotations[uri] ?? const [])
             .toText());
         print('----------------------------------------------------------');
       }
diff --git a/pkg/_fe_analyzer_shared/pubspec.yaml b/pkg/_fe_analyzer_shared/pubspec.yaml
index 9d64fc8..e576474 100644
--- a/pkg/_fe_analyzer_shared/pubspec.yaml
+++ b/pkg/_fe_analyzer_shared/pubspec.yaml
@@ -1,5 +1,5 @@
 name: _fe_analyzer_shared
-version: 17.0.0
+version: 19.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
 
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
deleted file mode 100644
index 024a4c6..0000000
--- a/pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_mini_ast.dart
+++ /dev/null
@@ -1,1862 +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 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:test/test.dart';
-
-Expression get nullLiteral => new _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,
-        bool isFinal = false,
-        bool isLate = false}) =>
-    new _Declare(variable, initialized ? expr(variable.type.type) : null,
-        isFinal, isLate);
-
-Statement declareInitialized(Var variable, Expression initializer,
-        {bool isFinal = false, bool isLate = false}) =>
-    new _Declare(variable, initializer, isFinal, isLate);
-
-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) {
-  // ignore: unnecessary_null_comparison
-  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) {
-  // ignore: unnecessary_null_comparison
-  assert(variable != null);
-  return new _ForEach(variable, iterable, body, false);
-}
-
-/// Creates a [Statement] that, when analyzed, will cause [callback] to be
-/// passed an [SsaNodeHarness] allowing the test to examine the values of
-/// variables' SSA nodes.
-Statement getSsaNodes(void Function(SsaNodeHarness) callback) =>
-    new _GetSsaNodes(callback);
-
-Statement if_(Expression condition, List<Statement> ifTrue,
-        [List<Statement>? ifFalse]) =>
-    new _If(condition, ifTrue, ifFalse);
-
-Statement implicitThis_whyNotPromoted(String staticType,
-        void Function(Map<Type, NonPromotionReason>) callback) =>
-    new _WhyNotPromoted_ImplicitThis(Type(staticType), callback);
-
-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);
-
-Expression this_(String type) => new _This(Type(type));
-
-Expression thisOrSuperPropertyGet(String name, {String type = 'Object?'}) =>
-    new _ThisOrSuperPropertyGet(name, Type(type));
-
-Expression throw_(Expression operand) => new _Throw(operand);
-
-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 {
-  late Statement _target;
-
-  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 extends Node implements _Visitable<Type> {
-  Expression() : super._();
-
-  /// 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 not => new _Not(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);
-
-  /// Creates an [Expression] that, when analyzed, will behave the same as
-  /// `this`, but after visiting it, will cause [callback] to be passed the
-  /// [ExpressionInfo] associated with it.  If the expression has no flow
-  /// analysis information associated with it, `null` will be passed to
-  /// [callback].
-  Expression getExpressionInfo(
-          void Function(ExpressionInfo<Var, Type>?) callback) =>
-      new _GetExpressionInfo(this, callback);
-
-  /// 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 the expression `x.name`.
-  Expression propertyGet(String name, {String type = 'Object?'}) =>
-      new _PropertyGet(this, name, Type(type));
-
-  /// 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);
-
-  /// Creates an [Expression] that, when analyzed, will behave the same as
-  /// `this`, but after visiting it, will cause [callback] to be passed the
-  /// non-promotion info associated with it.  If the expression has no
-  /// non-promotion info, an empty map will be passed to [callback].
-  Expression whyNotPromoted(
-          void Function(Map<Type, NonPromotionReason>) callback) =>
-      new _WhyNotPromoted(this, callback);
-}
-
-/// 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 {
-    'bool <: int': false,
-    'bool <: Object': true,
-    '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,
-    'Never <: Object?': true,
-    'Null <: int': false,
-    'Null <: Object': false,
-    'Null <: Object?': true,
-    '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 <: Null': false,
-    'Object <: num': false,
-    'Object <: num?': false,
-    'Object <: Object?': true,
-    'Object <: String': false,
-    'Object? <: Object': false,
-    'Object? <: int': false,
-    'Object? <: int?': false,
-    'Object? <: Null': false,
-    'String <: int': false,
-    'String <: int?': false,
-    'String <: num?': false,
-    'String <: Object': true,
-    'String <: Object?': true,
-  };
-
-  static final Map<String, Type> _coreFactors = {
-    'Object? - int': Type('Object?'),
-    'Object? - int?': Type('Object'),
-    'Object? - Never': Type('Object?'),
-    'Object? - Null': Type('Object'),
-    'Object? - num?': Type('Object'),
-    'Object? - Object?': Type('Never?'),
-    'Object? - String': Type('Object?'),
-    'Object - bool': Type('Object'),
-    'Object - int': Type('Object'),
-    'Object - String': 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 bool legacy;
-
-  final Map<String, bool> _subtypes = Map.of(_coreSubtypes);
-
-  final Map<String, Type> _factorResults = Map.of(_coreFactors);
-
-  Node? _currentSwitch;
-
-  Map<String, Map<String, String>> _promotionExceptions = {};
-
-  Harness({this.legacy = false});
-
-  /// Updates the harness so that when a [factor] query is invoked on types
-  /// [from] and [what], [result] will be returned.
-  void addFactor(String from, String what, String result) {
-    var query = '$from - $what';
-    _factorResults[query] = Type(result);
-  }
-
-  void addPromotionException(String from, String to, String result) {
-    (_promotionExceptions[from] ??= {})[to] = result;
-  }
-
-  /// Updates the harness so that when an [isSubtypeOf] query is invoked on
-  /// types [leftType] and [rightType], [isSubtype] will be returned.
-  void addSubtype(String leftType, String 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 = legacy
-        ? FlowAnalysis<Node, Statement, Expression, Var, Type>.legacy(
-            this, assignedVariables)
-        : FlowAnalysis<Node, Statement, Expression, Var, Type>(
-            this, assignedVariables);
-    statements._visit(this, flow);
-    flow.finish();
-  }
-
-  @override
-  Type? tryPromoteToType(Type to, Type from) {
-    var exception = (_promotionExceptions[from.type] ?? {})[to.type];
-    if (exception != null) {
-      return Type(exception);
-    }
-    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 if (type1.type == 'Never') {
-      return type2;
-    } else if (type2.type == 'Never') {
-      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 {
-  static int _nextId = 0;
-
-  final int id;
-
-  Node._() : id = _nextId++;
-
-  String toString() => 'Node#$id';
-}
-
-/// Helper class allowing tests to examine the values of variables' SSA nodes.
-class SsaNodeHarness {
-  final FlowAnalysis<Node, Statement, Expression, Var, Type> _flow;
-
-  SsaNodeHarness(this._flow);
-
-  /// Gets the SSA node associated with [variable] at the current point in
-  /// control flow, or `null` if the variable has been write captured.
-  SsaNode<Var, Type>? operator [](Var variable) =>
-      _flow.ssaNodeForTesting(variable);
-}
-
-/// 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 {
-  static bool _allowComparisons = false;
-
-  final String type;
-
-  Type(this.type);
-
-  @override
-  int get hashCode {
-    if (!_allowComparisons) {
-      // The flow analysis engine should not hash types using hashCode.  It
-      // should compare them using TypeOperations.
-      fail('Unexpected use of operator== on types');
-    }
-    return type.hashCode;
-  }
-
-  @override
-  bool operator ==(Object other) {
-    if (!_allowComparisons) {
-      // The flow analysis engine should not compare types using operator==.  It
-      // should compare them using TypeOperations.
-      fail('Unexpected use of operator== on types');
-    }
-    return other is Type && this.type == other.type;
-  }
-
-  @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, null);
-
-  /// Creates an expression representing a read of this variable, which as a
-  /// side effect will call the given callback with the returned promoted type.
-  Expression readAndCheckPromotedType(void Function(Type?) callback) =>
-      new _VariableRead(this, callback);
-
-  @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) {
-    // ignore: unnecessary_null_comparison
-    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);
-    assignedVariables.beginNode();
-    ifTrue._preVisit(assignedVariables);
-    assignedVariables.endNode(this);
-    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), this);
-    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) {
-    // ignore: unnecessary_null_comparison
-    assert(branchTargetPlaceholder._target != null);
-    flow.handleContinue(branchTargetPlaceholder._target);
-  }
-}
-
-class _Declare extends Statement {
-  final Var variable;
-  final Expression? initializer;
-  final bool isFinal;
-  final bool isLate;
-
-  _Declare(this.variable, this.initializer, this.isFinal, this.isLate)
-      : super._();
-
-  @override
-  String toString() {
-    var latePart = isLate ? 'late ' : '';
-    var finalPart = isFinal ? 'final ' : '';
-    var initializerPart = initializer != null ? ' = $initializer' : '';
-    return '$latePart$finalPart$variable${initializerPart};';
-  }
-
-  @override
-  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
-    initializer?._preVisit(assignedVariables);
-  }
-
-  @override
-  void _visit(
-      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
-    var initializer = this.initializer;
-    if (initializer == null) {
-      flow.declare(variable, false);
-    } else {
-      var initializerType = initializer._visit(h, flow);
-      flow.declare(variable, true);
-      flow.initialize(variable, initializerType, initializer,
-          isFinal: isFinal, isLate: isLate);
-    }
-  }
-}
-
-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 _GetExpressionInfo extends Expression {
-  final Expression target;
-
-  final void Function(ExpressionInfo<Var, Type>?) callback;
-
-  _GetExpressionInfo(this.target, this.callback);
-
-  @override
-  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
-    target._preVisit(assignedVariables);
-  }
-
-  @override
-  Type _visit(
-      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
-    var type = target._visit(h, flow);
-    flow.forwardExpression(this, target);
-    callback(flow.expressionInfoForTesting(this));
-    return type;
-  }
-}
-
-class _GetSsaNodes extends Statement {
-  final void Function(SsaNodeHarness) callback;
-
-  _GetSsaNodes(this.callback) : super._();
-
-  @override
-  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {}
-
-  @override
-  void _visit(
-      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
-    callback(SsaNodeHarness(flow));
-  }
-}
-
-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);
-    assignedVariables.beginNode();
-    ifTrue._preVisit(assignedVariables);
-    assignedVariables.endNode(this);
-    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), this);
-    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);
-    assignedVariables.beginNode();
-    rhs._preVisit(assignedVariables);
-    assignedVariables.endNode(this);
-  }
-
-  @override
-  Type _visit(
-      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
-    flow.logicalBinaryOp_begin();
-    flow.logicalBinaryOp_rightBegin(lhs.._visit(h, flow), this, 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 _Not extends Expression {
-  final Expression operand;
-
-  _Not(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) {
-    flow.logicalNot_end(this, operand.._visit(h, flow));
-    return Type('bool');
-  }
-}
-
-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 {
-  _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 _PropertyGet extends Expression {
-  final Expression target;
-
-  final String propertyName;
-
-  final Type type;
-
-  _PropertyGet(this.target, this.propertyName, this.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.propertyGet(this, target, propertyName, type);
-    return 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 _This extends Expression {
-  final Type type;
-
-  _This(this.type);
-
-  @override
-  String toString() => 'this';
-
-  @override
-  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {}
-
-  @override
-  Type _visit(
-      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
-    flow.thisOrSuper(this, type);
-    return type;
-  }
-}
-
-class _ThisOrSuperPropertyGet extends Expression {
-  final String propertyName;
-
-  final Type type;
-
-  _ThisOrSuperPropertyGet(this.propertyName, this.type);
-
-  @override
-  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {}
-
-  @override
-  Type _visit(
-      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
-    flow.thisOrSuperPropertyGet(this, propertyName, type);
-    return type;
-  }
-}
-
-class _Throw extends Expression {
-  final Expression operand;
-
-  _Throw(this.operand);
-
-  @override
-  String toString() => 'throw ...';
-
-  @override
-  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
-    operand._preVisit(assignedVariables);
-  }
-
-  @override
-  Type _visit(
-      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
-    operand._visit(h, flow);
-    flow.handleExit();
-    return Type('Never');
-  }
-}
-
-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);
-    finally_._preVisit(assignedVariables);
-  }
-
-  @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;
-
-  final void Function(Type?)? callback;
-
-  _VariableRead(this.variable, this.callback);
-
-  @override
-  String toString() => variable.name;
-
-  @override
-  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
-    assignedVariables.read(variable);
-  }
-
-  @override
-  Type _visit(
-      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
-    var readResult = flow.variableRead(this, variable);
-    callback?.call(readResult);
-    return readResult ?? 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 _WhyNotPromoted extends Expression {
-  final Expression target;
-
-  final void Function(Map<Type, NonPromotionReason>) callback;
-
-  _WhyNotPromoted(this.target, this.callback);
-
-  @override
-  String toString() => '$target (whyNotPromoted)';
-
-  @override
-  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
-    target._preVisit(assignedVariables);
-  }
-
-  @override
-  Type _visit(
-      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
-    var type = target._visit(h, flow);
-    flow.forwardExpression(this, target);
-    assert(!Type._allowComparisons);
-    Type._allowComparisons = true;
-    try {
-      callback(flow.whyNotPromoted(this));
-    } finally {
-      Type._allowComparisons = false;
-    }
-    return type;
-  }
-}
-
-class _WhyNotPromoted_ImplicitThis extends Statement {
-  final Type staticType;
-
-  final void Function(Map<Type, NonPromotionReason>) callback;
-
-  _WhyNotPromoted_ImplicitThis(this.staticType, this.callback) : super._();
-
-  @override
-  String toString() => 'implicit this (whyNotPromoted)';
-
-  @override
-  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {}
-
-  @override
-  void _visit(
-      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
-    assert(!Type._allowComparisons);
-    Type._allowComparisons = true;
-    try {
-      callback(flow.whyNotPromotedImplicitThis(staticType));
-    } finally {
-      Type._allowComparisons = false;
-    }
-  }
-}
-
-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 rhs = this.rhs;
-    var type = rhs == null ? variable.type : rhs._visit(h, flow);
-    flow.write(this, variable, type, rhs);
-    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 67012be..76c3ebc 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
@@ -5,7 +5,8 @@
 import 'package:_fe_analyzer_shared/src/flow_analysis/flow_analysis.dart';
 import 'package:test/test.dart';
 
-import 'flow_analysis_mini_ast.dart';
+import '../mini_ast.dart';
+import '../mini_types.dart';
 
 main() {
   group('API', () {
@@ -16,7 +17,7 @@
       h.run([
         declare(x, initialized: true),
         getSsaNodes((nodes) => ssaBeforePromotion = nodes[x]!),
-        x.read.as_('int').stmt,
+        x.expr.as_('int').stmt,
         checkPromoted(x, 'int'),
         getSsaNodes((nodes) => expect(nodes[x], same(ssaBeforePromotion))),
       ]);
@@ -33,7 +34,7 @@
       var h = Harness();
       var x = Var('x', 'int?');
       h.run([
-        assert_(x.read.eq(nullLiteral),
+        assert_(x.expr.eq(nullLiteral),
             checkPromoted(x, 'int').thenExpr(expr('String'))),
       ]);
     });
@@ -41,15 +42,15 @@
     test('assert_end joins previous and ifTrue states', () {
       var h = Harness();
       var x = Var('x', 'int?');
-      var y = Var('x', 'int?');
-      var z = Var('x', 'int?');
+      var y = Var('y', 'int?');
+      var z = Var('z', 'int?');
       h.run([
-        x.read.as_('int').stmt,
-        z.read.as_('int').stmt,
+        x.expr.as_('int').stmt,
+        z.expr.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)))),
+        ]).thenExpr(x.expr.notEq(nullLiteral).and(y.expr.notEq(nullLiteral)))),
         // x should be promoted because it was promoted before the assert, and
         // it is re-promoted within the assert (if it passes)
         checkPromoted(x, 'int'),
@@ -67,7 +68,7 @@
       var x = Var('x', 'int?');
       h.run([
         declare(x, initialized: true),
-        x.read
+        x.expr
             .notEq(nullLiteral)
             .conditional(checkPromoted(x, 'int').thenExpr(expr('int')),
                 checkNotPromoted(x).thenExpr(expr('int')))
@@ -81,7 +82,7 @@
       var x = Var('x', 'int?');
       h.run([
         declare(x, initialized: true),
-        x.read
+        x.expr
             .eq(nullLiteral)
             .conditional(checkNotPromoted(x).thenExpr(expr('Null')),
                 checkPromoted(x, 'int').thenExpr(expr('Null')))
@@ -103,12 +104,12 @@
         expr('bool')
             .conditional(
                 block([
-                  x.read.as_('int').stmt,
-                  y.read.as_('int').stmt,
+                  x.expr.as_('int').stmt,
+                  y.expr.as_('int').stmt,
                 ]).thenExpr(expr('Null')),
                 block([
-                  x.read.as_('int').stmt,
-                  z.read.as_('int').stmt,
+                  x.expr.as_('int').stmt,
+                  z.expr.as_('int').stmt,
                 ]).thenExpr(expr('Null')))
             .stmt,
         checkPromoted(x, 'int'),
@@ -131,8 +132,8 @@
         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))),
+                x.expr.notEq(nullLiteral).and(y.expr.notEq(nullLiteral)),
+                x.expr.notEq(nullLiteral).and(z.expr.notEq(nullLiteral))),
             [
               checkPromoted(x, 'int'),
               checkNotPromoted(y),
@@ -156,8 +157,8 @@
         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))),
+                x.expr.eq(nullLiteral).or(y.expr.eq(nullLiteral)),
+                x.expr.eq(nullLiteral).or(z.expr.eq(nullLiteral))),
             [],
             [
               checkPromoted(x, 'int'),
@@ -185,7 +186,7 @@
       h.run([
         declare(x, initialized: true),
         getSsaNodes((nodes) => ssaBeforePromotion = nodes[x]!),
-        if_(x.read.notEq(nullLiteral), [
+        if_(x.expr.notEq(nullLiteral), [
           checkReachable(true),
           checkPromoted(x, 'int'),
           getSsaNodes((nodes) => expect(nodes[x], same(ssaBeforePromotion))),
@@ -202,7 +203,7 @@
       var x = Var('x', 'int');
       h.run([
         declare(x, initialized: true),
-        if_(x.read.notEq(nullLiteral), [
+        if_(x.expr.notEq(nullLiteral), [
           checkReachable(true),
           checkNotPromoted(x),
         ], [
@@ -239,7 +240,7 @@
       var x = Var('x', 'int?');
       h.run([
         declare(x, initialized: true),
-        if_(x.read.notEq(expr('Null')), [
+        if_(x.expr.notEq(expr('Null')), [
           checkNotPromoted(x),
         ], [
           checkNotPromoted(x),
@@ -254,7 +255,7 @@
       h.run([
         declare(x, initialized: true),
         getSsaNodes((nodes) => ssaBeforePromotion = nodes[x]!),
-        if_(x.read.eq(nullLiteral), [
+        if_(x.expr.eq(nullLiteral), [
           checkReachable(true),
           checkNotPromoted(x),
           getSsaNodes((nodes) => expect(nodes[x], same(ssaBeforePromotion))),
@@ -271,7 +272,7 @@
       var x = Var('x', 'int');
       h.run([
         declare(x, initialized: true),
-        if_(x.read.eq(nullLiteral), [
+        if_(x.expr.eq(nullLiteral), [
           checkReachable(true),
           checkNotPromoted(x),
         ], [
@@ -288,7 +289,7 @@
       h.run([
         declare(x, initialized: true),
         getSsaNodes((nodes) => ssaBeforePromotion = nodes[x]!),
-        if_(nullLiteral.notEq(x.read), [
+        if_(nullLiteral.notEq(x.expr), [
           checkPromoted(x, 'int'),
           getSsaNodes((nodes) => expect(nodes[x], same(ssaBeforePromotion))),
         ], [
@@ -303,7 +304,7 @@
       var x = Var('x', 'int?');
       h.run([
         declare(x, initialized: true),
-        if_(expr('Null').notEq(x.read), [
+        if_(expr('Null').notEq(x.expr), [
           checkNotPromoted(x),
         ], [
           checkNotPromoted(x),
@@ -318,7 +319,7 @@
       h.run([
         declare(x, initialized: true),
         getSsaNodes((nodes) => ssaBeforePromotion = nodes[x]!),
-        if_(nullLiteral.eq(x.read), [
+        if_(nullLiteral.eq(x.expr), [
           checkNotPromoted(x),
           getSsaNodes((nodes) => expect(nodes[x], same(ssaBeforePromotion))),
         ], [
@@ -399,13 +400,13 @@
       var x = Var('x', 'int?');
       h.run([
         declare(x, initialized: true),
-        if_(x.read.notEq(nullLiteral), [
+        if_(x.expr.notEq(nullLiteral), [
           checkPromoted(x, 'int'),
         ]),
         localFunction([
           x.write(expr('int?')).stmt,
         ]),
-        if_(x.read.notEq(nullLiteral), [
+        if_(x.expr.notEq(nullLiteral), [
           checkNotPromoted(x),
         ]),
       ]);
@@ -439,14 +440,14 @@
       late SsaNode<Var, Type> ssaBeforeLoop;
       h.run([
         declare(x, initialized: true),
-        x.read.as_('int').stmt,
+        x.expr.as_('int').stmt,
         checkPromoted(x, 'int'),
         getSsaNodes((nodes) => ssaBeforeLoop = nodes[x]!),
-        branchTarget((t) => do_([
-              getSsaNodes((nodes) => expect(nodes[x], isNot(ssaBeforeLoop))),
-              checkNotPromoted(x),
-              x.write(expr('Null')).stmt,
-            ], expr('bool'))),
+        do_([
+          getSsaNodes((nodes) => expect(nodes[x], isNot(ssaBeforeLoop))),
+          checkNotPromoted(x),
+          x.write(expr('Null')).stmt,
+        ], expr('bool')),
       ]);
     });
 
@@ -456,7 +457,7 @@
       h.run([
         declare(x, initialized: true),
         do_([
-          x.read.as_('int').stmt,
+          x.expr.as_('int').stmt,
           // The promotion should have no effect, because the second time
           // through the loop, x has been write-captured.
           checkNotPromoted(x),
@@ -472,19 +473,19 @@
       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')))),
+        do_(
+            [
+              if_(x.expr.notEq(nullLiteral), [
+                continue_(),
+              ]),
+              return_(),
+              checkReachable(false),
+              checkNotPromoted(x),
+            ],
+            block([
+              checkReachable(true),
+              checkPromoted(x, 'int'),
+            ]).thenExpr(expr('bool'))),
       ]);
     });
 
@@ -493,8 +494,7 @@
       var x = Var('x', 'int?');
       h.run([
         declare(x, initialized: true),
-        branchTarget((t) =>
-            do_([], checkNotPromoted(x).thenExpr(x.read.eq(nullLiteral)))),
+        do_([], checkNotPromoted(x).thenExpr(x.expr.eq(nullLiteral))),
         checkPromoted(x, 'int'),
       ]);
     });
@@ -504,12 +504,12 @@
       // of "why not promoted" functionality: when storing information about an
       // attempt to promote a field (e.g. `x.y != null`) we need to make sure we
       // don't wipe out information about the target variable (`x`).
-      var h = Harness();
+      var h = Harness()..addMember('C', 'y', 'Object?');
       var x = Var('x', 'C');
       h.run([
         declare(x, initialized: true),
         checkAssigned(x, true),
-        if_(x.read.propertyGet('y').notEq(nullLiteral), [
+        if_(x.expr.property('y').notEq(nullLiteral), [
           checkAssigned(x, true),
         ], [
           checkAssigned(x, true),
@@ -518,13 +518,13 @@
     });
 
     test('equalityOp_end does not set reachability for `this`', () {
-      var h = Harness()
+      var h = Harness(thisType: 'C')
         ..addSubtype('Null', 'C', false)
         ..addFactor('C', 'Null', 'C');
       h.addSubtype('C', 'Object', true);
       h.run([
-        if_(this_('C').is_('Null'), [
-          if_(this_('C').eq(nullLiteral), [
+        if_(this_.is_('Null'), [
+          if_(this_.eq(nullLiteral), [
             checkReachable(true),
           ], [
             checkReachable(true),
@@ -535,12 +535,12 @@
 
     group('equalityOp_end does not set reachability for property gets', () {
       test('on a variable', () {
-        var h = Harness();
+        var h = Harness()..addMember('C', 'f', 'Object?');
         var x = Var('x', 'C');
         h.run([
           declare(x, initialized: true),
-          if_(x.read.propertyGet('f').is_('Null'), [
-            if_(x.read.propertyGet('f').eq(nullLiteral), [
+          if_(x.expr.property('f').is_('Null'), [
+            if_(x.expr.property('f').eq(nullLiteral), [
               checkReachable(true),
             ], [
               checkReachable(true),
@@ -550,10 +550,10 @@
       });
 
       test('on an arbitrary expression', () {
-        var h = Harness();
+        var h = Harness()..addMember('C', 'f', 'Object?');
         h.run([
-          if_(expr('C').propertyGet('f').is_('Null'), [
-            if_(expr('C').propertyGet('f').eq(nullLiteral), [
+          if_(expr('C').property('f').is_('Null'), [
+            if_(expr('C').property('f').eq(nullLiteral), [
               checkReachable(true),
             ], [
               checkReachable(true),
@@ -563,10 +563,10 @@
       });
 
       test('on explicit this', () {
-        var h = Harness();
+        var h = Harness(thisType: 'C')..addMember('C', 'f', 'Object?');
         h.run([
-          if_(this_('C').propertyGet('f').is_('Null'), [
-            if_(this_('C').propertyGet('f').eq(nullLiteral), [
+          if_(this_.property('f').is_('Null'), [
+            if_(this_.property('f').eq(nullLiteral), [
               checkReachable(true),
             ], [
               checkReachable(true),
@@ -606,7 +606,7 @@
       late SsaNode<Var, Type> ssaBeforeLoop;
       h.run([
         declare(x, initialized: true),
-        x.read.as_('int').stmt,
+        x.expr.as_('int').stmt,
         checkPromoted(x, 'int'),
         getSsaNodes((nodes) => ssaBeforeLoop = nodes[x]!),
         for_(
@@ -627,12 +627,12 @@
       var x = Var('x', 'int?');
       h.run([
         declare(x, initialized: true),
-        x.read.as_('int').stmt,
+        x.expr.as_('int').stmt,
         checkPromoted(x, 'int'),
         for_(
             null,
             block([
-              x.read.as_('int').stmt,
+              x.expr.as_('int').stmt,
               checkNotPromoted(x),
               localFunction([
                 x.write(expr('int?')).stmt,
@@ -649,7 +649,7 @@
       var y = Var('y', 'int?');
       h.run([
         declare(y, initialized: true),
-        y.read.as_('int').stmt,
+        y.expr.as_('int').stmt,
         for_(null, declare(x, initialized: true).thenExpr(expr('bool')), null, [
           x.write(expr('Null')).stmt,
         ]),
@@ -668,7 +668,7 @@
       var h = Harness();
       var x = Var('x', 'int?');
       h.run([
-        for_(declare(x, initialized: true), x.read.notEq(nullLiteral), null, [
+        for_(declare(x, initialized: true), x.expr.notEq(nullLiteral), null, [
           checkPromoted(x, 'int'),
         ]),
       ]);
@@ -679,7 +679,7 @@
       var h = Harness();
       var x = Var('x', 'int?');
       h.run([
-        for_(declare(x, initialized: true), x.read.notEq(nullLiteral), null, [],
+        for_(declare(x, initialized: true), x.expr.notEq(nullLiteral), null, [],
             forCollection: true),
       ]);
     });
@@ -696,23 +696,23 @@
         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,
-                ])),
+        for_(
+            null,
+            expr('bool'),
+            block([
+              checkPromoted(x, 'int'),
+              checkNotPromoted(y),
+              checkNotPromoted(z),
+            ]).thenExpr(expr('Null')),
+            [
+              if_(expr('bool'), [
+                x.expr.as_('int').stmt,
+                y.expr.as_('int').stmt,
+                continue_(),
+              ]),
+              x.expr.as_('int').stmt,
+              z.expr.as_('int').stmt,
+            ]),
       ]);
     });
 
@@ -728,14 +728,13 @@
         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),
-              ]),
-            ])),
+        for_(null, x.expr.eq(nullLiteral).or(z.expr.eq(nullLiteral)), null, [
+          if_(expr('bool'), [
+            x.expr.as_('int').stmt,
+            y.expr.as_('int').stmt,
+            break_(),
+          ]),
+        ]),
         checkPromoted(x, 'int'),
         checkNotPromoted(y),
         checkNotPromoted(z),
@@ -751,14 +750,14 @@
       h.run([
         declare(x, initialized: true),
         declare(y, initialized: true),
-        branchTarget((t) => for_(null, expr('bool'), null, [
-              x.write(expr('int?')).stmt,
-              if_(expr('bool'), [break_(t)]),
-              getSsaNodes((nodes) {
-                xSsaInsideLoop = nodes[x]!;
-                ySsaInsideLoop = nodes[y]!;
-              }),
-            ])),
+        for_(null, expr('bool'), null, [
+          x.write(expr('int?')).stmt,
+          if_(expr('bool'), [break_()]),
+          getSsaNodes((nodes) {
+            xSsaInsideLoop = nodes[x]!;
+            ySsaInsideLoop = nodes[y]!;
+          }),
+        ]),
         getSsaNodes((nodes) {
           // x's Ssa should have been changed because of the join at the end of
           // of the loop.  y's should not, since it retains the value it had
@@ -780,15 +779,15 @@
       h.run([
         declare(x, initialized: true),
         declare(y, initialized: true),
-        branchTarget((t) => for_(null, expr('bool'), null, [
-              x.write(expr('int?')).stmt,
-              if_(expr('bool'), [break_(t)]),
-              if_(x.read.is_('int'), []),
-              getSsaNodes((nodes) {
-                xSsaInsideLoop = nodes[x]!;
-                ySsaInsideLoop = nodes[y]!;
-              }),
-            ])),
+        for_(null, expr('bool'), null, [
+          x.write(expr('int?')).stmt,
+          if_(expr('bool'), [break_()]),
+          if_(x.expr.is_('int'), []),
+          getSsaNodes((nodes) {
+            xSsaInsideLoop = nodes[x]!;
+            ySsaInsideLoop = nodes[y]!;
+          }),
+        ]),
         getSsaNodes((nodes) {
           // x's Ssa should have been changed because of the join at the end of
           // the loop.  y's should not, since it retains the value it had prior
@@ -805,7 +804,7 @@
       late SsaNode<Var, Type> ssaBeforeLoop;
       h.run([
         declare(x, initialized: true),
-        x.read.as_('int').stmt,
+        x.expr.as_('int').stmt,
         checkPromoted(x, 'int'),
         getSsaNodes((nodes) => ssaBeforeLoop = nodes[x]!),
         forEachWithNonVariable(expr('List<int?>'), [
@@ -821,10 +820,10 @@
       var x = Var('x', 'int?');
       h.run([
         declare(x, initialized: true),
-        x.read.as_('int').stmt,
+        x.expr.as_('int').stmt,
         checkPromoted(x, 'int'),
         forEachWithNonVariable(expr('List<int?>'), [
-          x.read.as_('int').stmt,
+          x.expr.as_('int').stmt,
           checkNotPromoted(x),
           localFunction([
             x.write(expr('int?')).stmt,
@@ -854,7 +853,7 @@
         checkAssigned(x, false),
         forEachWithVariableSet(x, expr('List<int?>'), [
           checkAssigned(x, true),
-          if_(x.read.notEq(nullLiteral), [checkPromoted(x, 'int')]),
+          if_(x.expr.notEq(nullLiteral), [checkPromoted(x, 'int')]),
         ]),
         checkAssigned(x, false),
       ]);
@@ -866,12 +865,12 @@
       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,
-            ])),
+        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_(), 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.
@@ -885,7 +884,7 @@
       h.run([
         declare(x, initialized: true),
         forEachWithNonVariable(expr('List<int?>'), [
-          x.read.as_('int').stmt,
+          x.expr.as_('int').stmt,
           checkPromoted(x, 'int'),
         ]),
         checkNotPromoted(x),
@@ -900,8 +899,8 @@
       h.run([
         declare(x, initialized: true),
         declare(y, initialized: true),
-        x.read.as_('int').stmt,
-        y.read.as_('int').stmt,
+        x.expr.as_('int').stmt,
+        y.expr.as_('int').stmt,
         checkPromoted(x, 'int'),
         checkPromoted(y, 'int'),
         getSsaNodes((nodes) {
@@ -915,7 +914,7 @@
             expect(nodes[x], isNull);
             expect(nodes[y], isNotNull);
           }),
-          x.write(expr('int?')).stmt, x.read.as_('int').stmt,
+          x.write(expr('int?')).stmt, x.expr.as_('int').stmt,
         ]),
         // x is unpromoted after the local function too
         checkNotPromoted(x), checkPromoted(y, 'int'),
@@ -933,7 +932,7 @@
       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,
+        x.expr.as_('int').stmt, y.expr.as_('int').stmt,
         checkPromoted(x, 'int'), checkPromoted(y, 'int'),
         localFunction([
           // x is unpromoted within the local function, because the write
@@ -941,7 +940,7 @@
           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,
+          x.expr.as_('int').stmt,
           checkNotPromoted(x), checkPromoted(y, 'int'),
         ]),
         // x is still promoted after the local function, though, because the
@@ -965,7 +964,7 @@
       late SsaNode<Var, Type> ssaBeforeFunction;
       h.run([
         declare(x, initialized: true), declare(y, initialized: true),
-        x.read.as_('int').stmt, y.read.as_('int').stmt,
+        x.expr.as_('int').stmt, y.expr.as_('int').stmt,
         checkPromoted(x, 'int'),
         getSsaNodes((nodes) => ssaBeforeFunction = nodes[x]!),
         checkPromoted(y, 'int'),
@@ -976,7 +975,7 @@
           getSsaNodes((nodes) => expect(nodes[x], isNot(ssaBeforeFunction))),
           checkPromoted(y, 'int'),
           // But it can be re-promoted because the write isn't captured.
-          x.read.as_('int').stmt,
+          x.expr.as_('int').stmt,
           checkPromoted(x, 'int'), checkPromoted(y, 'int'),
         ]),
         // x is still promoted after the local function, though, because the
@@ -997,7 +996,7 @@
         localFunction([]),
         // x is declared after the local function, so the local function
         // cannot possibly write to x.
-        declare(x, initialized: true), x.read.as_('int').stmt,
+        declare(x, initialized: true), x.expr.as_('int').stmt,
         checkPromoted(x, 'int'), x.write(expr('Null')).stmt,
       ]);
     });
@@ -1009,11 +1008,11 @@
       var y = Var('y', 'int?');
       h.run([
         declare(y, initialized: true),
-        y.read.as_('int').stmt,
+        y.expr.as_('int').stmt,
         getSsaNodes((nodes) => expect(nodes[x], null)),
         localFunction([
           getSsaNodes((nodes) => expect(nodes[x], isNot(nodes[y]))),
-          x.read.as_('int').stmt,
+          x.expr.as_('int').stmt,
           // Promotion should not occur, because x might be write-captured by
           // the time this code is reached.
           checkNotPromoted(x),
@@ -1049,15 +1048,15 @@
     test('handleBreak handles deep nesting', () {
       var h = Harness();
       h.run([
-        branchTarget((t) => while_(booleanLiteral(true), [
-              if_(expr('bool'), [
-                if_(expr('bool'), [
-                  break_(t),
-                ]),
-              ]),
-              return_(),
-              checkReachable(false),
-            ])),
+        while_(booleanLiteral(true), [
+          if_(expr('bool'), [
+            if_(expr('bool'), [
+              break_(),
+            ]),
+          ]),
+          return_(),
+          checkReachable(false),
+        ]),
         checkReachable(true),
       ]);
     });
@@ -1065,16 +1064,16 @@
     test('handleBreak handles mixed nesting', () {
       var h = Harness();
       h.run([
-        branchTarget((t) => while_(booleanLiteral(true), [
-              if_(expr('bool'), [
-                if_(expr('bool'), [
-                  break_(t),
-                ]),
-                break_(t),
-              ]),
-              break_(t),
-              checkReachable(false),
-            ])),
+        while_(booleanLiteral(true), [
+          if_(expr('bool'), [
+            if_(expr('bool'), [
+              break_(),
+            ]),
+            break_(),
+          ]),
+          break_(),
+          checkReachable(false),
+        ]),
         checkReachable(true),
       ]);
     });
@@ -1082,15 +1081,15 @@
     test('handleContinue handles deep nesting', () {
       var h = Harness();
       h.run([
-        branchTarget((t) => do_([
-              if_(expr('bool'), [
-                if_(expr('bool'), [
-                  continue_(t),
-                ]),
-              ]),
-              return_(),
-              checkReachable(false),
-            ], checkReachable(true).thenExpr(booleanLiteral(true)))),
+        do_([
+          if_(expr('bool'), [
+            if_(expr('bool'), [
+              continue_(),
+            ]),
+          ]),
+          return_(),
+          checkReachable(false),
+        ], checkReachable(true).thenExpr(booleanLiteral(true))),
         checkReachable(false),
       ]);
     });
@@ -1098,16 +1097,16 @@
     test('handleContinue handles mixed nesting', () {
       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)))),
+        do_([
+          if_(expr('bool'), [
+            if_(expr('bool'), [
+              continue_(),
+            ]),
+            continue_(),
+          ]),
+          continue_(),
+          checkReachable(false),
+        ], checkReachable(true).thenExpr(booleanLiteral(true))),
         checkReachable(false),
       ]);
     });
@@ -1117,7 +1116,7 @@
       var x = Var('x', 'int?');
       h.run([
         declare(x, initialized: true),
-        x.read
+        x.expr
             .ifNull(block([
               checkReachable(true),
               x.write(expr('int')).stmt,
@@ -1136,10 +1135,10 @@
       var x = Var('x', 'int?');
       h.run([
         declare(x, initialized: true),
-        x.read
+        x.expr
             .ifNull(block([
               checkReachable(true),
-              x.read.as_('int').stmt,
+              x.expr.as_('int').stmt,
               checkPromoted(x, 'int'),
             ]).thenExpr(expr('int?')))
             .thenStmt(block([
@@ -1158,7 +1157,7 @@
         expr('int?')
             .ifNull(block([
               checkReachable(true),
-              x.read.as_('int').stmt,
+              x.expr.as_('int').stmt,
               checkPromoted(x, 'int'),
             ]).thenExpr(expr('int?')))
             .thenStmt(block([
@@ -1197,7 +1196,7 @@
         declare(x, initialized: true),
         return_(),
         checkReachable(false),
-        if_(x.read.eq(nullLiteral), [
+        if_(x.expr.eq(nullLiteral), [
           return_(),
         ]),
         checkReachable(false),
@@ -1210,7 +1209,7 @@
       var x = Var('x', 'int?');
       h.run([
         declare(x, initialized: true),
-        if_(x.read.eq(nullLiteral), [
+        if_(x.expr.eq(nullLiteral), [
           return_(),
         ]),
         checkPromoted(x, 'int'),
@@ -1231,15 +1230,15 @@
         declare(x, initialized: true),
         declare(y, initialized: true),
         declare(z, initialized: true),
-        x.write(w.read.is_('int')).stmt,
+        x.write(w.expr.is_('int')).stmt,
         getSsaNodes((nodes) {
           xSsaNodeBeforeIf = nodes[x]!;
           expect(xSsaNodeBeforeIf.expressionInfo, isNotNull);
         }),
         if_(expr('bool'), [
-          y.write(w.read.is_('String')).stmt,
+          y.write(w.expr.is_('String')).stmt,
         ], [
-          z.write(w.read.is_('bool')).stmt,
+          z.write(w.expr.is_('bool')).stmt,
         ]),
         getSsaNodes((nodes) {
           expect(nodes[x], same(xSsaNodeBeforeIf));
@@ -1317,7 +1316,7 @@
       h.run([
         declareInitialized(
             x,
-            y.read.eq(nullLiteral).getExpressionInfo((info) {
+            y.expr.eq(nullLiteral).getExpressionInfo((info) {
               expect(info, isNotNull);
               writtenValueInfo = info!;
             })),
@@ -1332,7 +1331,7 @@
       var x = Var('x', 'Object');
       var y = Var('y', 'int?');
       h.run([
-        declareInitialized(x, y.read.eq(nullLiteral), isLate: true),
+        declareInitialized(x, y.expr.eq(nullLiteral), isLate: true),
         getSsaNodes((nodes) {
           expect(nodes[x]!.expressionInfo, isNull);
         }),
@@ -1353,7 +1352,7 @@
             x,
             // `y == null` is a trivial expression because y has been write
             // captured.
-            y.read
+            y.expr
                 .eq(nullLiteral)
                 .getExpressionInfo((info) => expect(info, isNotNull))),
         getSsaNodes((nodes) {
@@ -1371,7 +1370,7 @@
       h.run([
         declare(x, initialized: true),
         getSsaNodes((nodes) => ssaBeforePromotion = nodes[x]!),
-        if_(x.read.is_(tryPromoteType, isInverted: inverted), [
+        if_(x.expr.is_(tryPromoteType, isInverted: inverted), [
           checkReachable(true),
           checkPromoted(x, expectedPromotedTypeThen),
           getSsaNodes((nodes) => expect(nodes[x], same(ssaBeforePromotion))),
@@ -1436,13 +1435,13 @@
       var x = Var('x', 'int?');
       h.run([
         declare(x, initialized: true),
-        if_(x.read.is_('int'), [
+        if_(x.expr.is_('int'), [
           checkPromoted(x, 'int'),
         ]),
         localFunction([
           x.write(expr('int?')).stmt,
         ]),
-        if_(x.read.is_('int'), [
+        if_(x.expr.is_('int'), [
           checkNotPromoted(x),
         ]),
       ]);
@@ -1452,7 +1451,7 @@
       var h = Harness();
       var x = Var('x', 'int?');
       h.run([
-        if_(x.read.is_('int'), [
+        if_(x.expr.is_('int'), [
           checkPromoted(x, 'int'),
         ]),
         declare(x, initialized: true),
@@ -1463,11 +1462,11 @@
     });
 
     test('isExpression_end() does not set reachability for `this`', () {
-      var h = Harness()
+      var h = Harness(thisType: 'C')
         ..addSubtype('Never', 'C', true)
         ..addFactor('C', 'Never', 'C');
       h.run([
-        if_(this_('C').is_('Never'), [
+        if_(this_.is_('Never'), [
           checkReachable(true),
         ], [
           checkReachable(true),
@@ -1477,11 +1476,11 @@
 
     group('isExpression_end() does not set reachability for property gets', () {
       test('on a variable', () {
-        var h = Harness();
+        var h = Harness()..addMember('C', 'f', 'Object?');
         var x = Var('x', 'C');
         h.run([
           declare(x, initialized: true),
-          if_(x.read.propertyGet('f').is_('Never'), [
+          if_(x.expr.property('f').is_('Never'), [
             checkReachable(true),
           ], [
             checkReachable(true),
@@ -1490,9 +1489,9 @@
       });
 
       test('on an arbitrary expression', () {
-        var h = Harness();
+        var h = Harness()..addMember('C', 'f', 'Object?');
         h.run([
-          if_(expr('C').propertyGet('f').is_('Never'), [
+          if_(expr('C').property('f').is_('Never'), [
             checkReachable(true),
           ], [
             checkReachable(true),
@@ -1501,9 +1500,9 @@
       });
 
       test('on explicit this', () {
-        var h = Harness();
+        var h = Harness(thisType: 'C')..addMember('C', 'f', 'Object?');
         h.run([
-          if_(this_('C').propertyGet('f').is_('Never'), [
+          if_(this_.property('f').is_('Never'), [
             checkReachable(true),
           ], [
             checkReachable(true),
@@ -1528,8 +1527,8 @@
       var x = Var('x', 'int?');
       h.run([
         declare(x, initialized: true),
-        if_(x.read.isNot('int'), [
-          labeled(return_()),
+        if_(x.expr.isNot('int'), [
+          labeled((_) => return_()),
         ]),
         checkPromoted(x, 'int'),
       ]);
@@ -1540,13 +1539,13 @@
       var x = Var('x', 'int?');
       h.run([
         declare(x, initialized: true),
-        if_(x.read.isNot('int'), [
-          branchTarget((t) => labeled(block([
+        if_(x.expr.isNot('int'), [
+          labeled((t) => block([
                 if_(expr('bool'), [
                   break_(t),
                 ]),
                 return_(),
-              ]))),
+              ])),
         ]),
         checkNotPromoted(x),
       ]);
@@ -1557,7 +1556,7 @@
       var x = Var('x', 'int?');
       h.run([
         declare(x, initialized: true),
-        x.read
+        x.expr
             .notEq(nullLiteral)
             .and(checkPromoted(x, 'int').thenExpr(expr('bool')))
             .stmt,
@@ -1569,7 +1568,7 @@
       var x = Var('x', 'int?');
       h.run([
         declare(x, initialized: true),
-        if_(expr('bool').and(x.read.notEq(nullLiteral)), [
+        if_(expr('bool').and(x.expr.notEq(nullLiteral)), [
           checkPromoted(x, 'int'),
         ]),
       ]);
@@ -1581,7 +1580,7 @@
       var x = Var('x', 'int?');
       h.run([
         declare(x, initialized: true),
-        if_(expr('bool').or(x.read.eq(nullLiteral)), [], [
+        if_(expr('bool').or(x.expr.eq(nullLiteral)), [], [
           checkPromoted(x, 'int'),
         ]),
       ]);
@@ -1592,7 +1591,7 @@
       var x = Var('x', 'int?');
       h.run([
         declare(x, initialized: true),
-        x.read
+        x.expr
             .eq(nullLiteral)
             .or(checkPromoted(x, 'int').thenExpr(expr('bool')))
             .stmt,
@@ -1609,7 +1608,7 @@
       h.run([
         declare(x, initialized: true),
         declare(y, initialized: true),
-        if_(x.read.notEq(nullLiteral).and(y.read.notEq(nullLiteral)), [
+        if_(x.expr.notEq(nullLiteral).and(y.expr.notEq(nullLiteral)), [
           checkPromoted(x, 'int'),
           checkPromoted(y, 'int'),
         ]),
@@ -1626,7 +1625,7 @@
       h.run([
         declare(x, initialized: true),
         declare(y, initialized: true),
-        if_(x.read.eq(nullLiteral).or(y.read.eq(nullLiteral)), [], [
+        if_(x.expr.eq(nullLiteral).or(y.expr.eq(nullLiteral)), [], [
           checkPromoted(x, 'int'),
           checkPromoted(y, 'int'),
         ]),
@@ -1638,7 +1637,7 @@
       var x = Var('x', 'int?');
       h.run([
         declare(x, initialized: true),
-        if_(x.read.eq(nullLiteral).not, [
+        if_(x.expr.eq(nullLiteral).not, [
           checkPromoted(x, 'int'),
         ], [
           checkNotPromoted(x),
@@ -1662,7 +1661,7 @@
       h.run([
         declare(x, initialized: true),
         getSsaNodes((nodes) => ssaBeforePromotion = nodes[x]!),
-        x.read.nonNullAssert.stmt,
+        x.expr.nonNullAssert.stmt,
         checkPromoted(x, 'int'),
         getSsaNodes((nodes) => expect(nodes[x], same(ssaBeforePromotion))),
       ]);
@@ -1675,7 +1674,7 @@
       h.run([
         declare(x, initialized: true),
         getSsaNodes((nodes) => ssaBeforePromotion = nodes[x]!),
-        x.read
+        x.expr
             .nullAwareAccess(block([
               checkReachable(true),
               checkPromoted(x, 'int'),
@@ -1693,7 +1692,7 @@
       var x = Var('x', 'int?');
       h.run([
         declare(x, initialized: true),
-        x.read
+        x.expr
             .nullAwareAccess(
                 block([
                   checkReachable(true),
@@ -1709,7 +1708,7 @@
       var x = Var('x', 'int?');
       h.run([
         declare(x, initialized: true),
-        x.read.as_('int').stmt,
+        x.expr.as_('int').stmt,
         expr('int')
             .nullAwareAccess(block([
               checkReachable(true),
@@ -1728,7 +1727,7 @@
         expr('int')
             .nullAwareAccess(block([
               checkReachable(true),
-              x.read.as_('int').stmt,
+              x.expr.as_('int').stmt,
               checkPromoted(x, 'int'),
             ]).thenExpr(expr('Null')))
             .stmt,
@@ -1743,7 +1742,7 @@
       var x = Var('x', 'int?');
       h.run([
         if_(
-            x.read.parenthesized.notEq(nullLiteral.parenthesized).parenthesized,
+            x.expr.parenthesized.notEq(nullLiteral.parenthesized).parenthesized,
             [
               checkPromoted(x, 'int'),
             ]),
@@ -1756,10 +1755,10 @@
       h.run([
         declare(x, initialized: true),
         checkNotPromoted(x),
-        x.read.as_('num').stmt,
+        x.expr.as_('num').stmt,
         checkPromoted(x, 'num'),
         // Check that it's a type of interest by promoting and de-promoting.
-        if_(x.read.is_('int'), [
+        if_(x.expr.is_('int'), [
           checkPromoted(x, 'int'),
           x.write(expr('num')).stmt,
           checkPromoted(x, 'num'),
@@ -1773,7 +1772,7 @@
       h.run([
         declare(x, initialized: true),
         checkNotPromoted(x),
-        x.read.as_('String').stmt,
+        x.expr.as_('String').stmt,
         checkNotPromoted(x),
       ]);
     });
@@ -1787,7 +1786,7 @@
         localFunction([
           x.write(expr('num')).stmt,
         ]),
-        x.read.as_('num').stmt,
+        x.expr.as_('num').stmt,
         checkNotPromoted(x),
       ]);
     });
@@ -1807,7 +1806,7 @@
       var x = Var('x', 'int?');
       h.run([
         declare(x, initialized: true),
-        x.read.as_('int').stmt,
+        x.expr.as_('int').stmt,
         switch_(
             expr('Null'),
             [
@@ -1831,7 +1830,7 @@
       var x = Var('x', 'int?');
       h.run([
         declare(x, initialized: true),
-        x.read.as_('int').stmt,
+        x.expr.as_('int').stmt,
         switch_(
             expr('Null'),
             [
@@ -1851,7 +1850,7 @@
       var x = Var('x', 'int?');
       h.run([
         declare(x, initialized: true),
-        x.read.as_('int').stmt,
+        x.expr.as_('int').stmt,
         switch_(
             expr('Null'),
             [
@@ -1873,7 +1872,7 @@
       late SsaNode<Var, Type> ssaBeforeSwitch;
       h.run([
         declare(x, initialized: true),
-        x.read.as_('int').stmt,
+        x.expr.as_('int').stmt,
         switch_(
             expr('Null').thenStmt(block([
               checkPromoted(x, 'int'),
@@ -1897,12 +1896,12 @@
       var x = Var('x', 'int?');
       h.run([
         declare(x, initialized: true),
-        x.read.as_('int').stmt,
+        x.expr.as_('int').stmt,
         switch_(
             expr('Null'),
             [
               case_([
-                x.read.as_('int').stmt,
+                x.expr.as_('int').stmt,
                 checkNotPromoted(x),
                 localFunction([
                   x.write(expr('int?')).stmt,
@@ -1923,18 +1922,18 @@
         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_(
+        y.expr.as_('int').stmt,
+        z.expr.as_('int').stmt,
+        switch_(
             expr('Null'),
             [
               case_([
-                x.read.as_('int').stmt,
+                x.expr.as_('int').stmt,
                 y.write(expr('int?')).stmt,
-                break_(t),
+                break_(),
               ]),
             ],
-            isExhaustive: false)),
+            isExhaustive: false),
         checkNotPromoted(x),
         checkNotPromoted(y),
         checkPromoted(z, 'int'),
@@ -1952,26 +1951,26 @@
         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_(
+        x.expr.as_('int').stmt,
+        y.expr.as_('int').stmt,
+        z.expr.as_('int').stmt,
+        switch_(
             expr('Null'),
             [
               case_([
-                w.read.as_('int').stmt,
-                y.read.as_('int').stmt,
+                w.expr.as_('int').stmt,
+                y.expr.as_('int').stmt,
                 x.write(expr('int?')).stmt,
-                break_(t),
+                break_(),
               ]),
               case_([
-                w.read.as_('int').stmt,
-                x.read.as_('int').stmt,
+                w.expr.as_('int').stmt,
+                x.expr.as_('int').stmt,
                 y.write(expr('int?')).stmt,
-                break_(t),
+                break_(),
               ]),
             ],
-            isExhaustive: true)),
+            isExhaustive: true),
         checkPromoted(w, 'int'),
         checkNotPromoted(x),
         checkNotPromoted(y),
@@ -1984,16 +1983,16 @@
       var x = Var('x', 'int?');
       h.run([
         declare(x, initialized: true),
-        branchTarget((t) => switch_(
+        switch_(
             expr('Null'),
             [
               case_([
-                x.read.as_('int').stmt,
-                break_(t),
+                x.expr.as_('int').stmt,
+                break_(),
               ]),
               case_([]),
             ],
-            isExhaustive: true)),
+            isExhaustive: true),
         checkNotPromoted(x),
       ]);
     });
@@ -2005,16 +2004,14 @@
       h.run([
         declare(x, initialized: true),
         declare(y, initialized: true),
-        y.read.as_('int').stmt,
-        tryCatch([
-          x.read.as_('int').stmt,
+        y.expr.as_('int').stmt,
+        try_([
+          x.expr.as_('int').stmt,
           checkPromoted(x, 'int'),
           checkPromoted(y, 'int'),
-        ], [
-          catch_(body: [
-            checkNotPromoted(x),
-            checkPromoted(y, 'int'),
-          ])
+        ]).catch_(body: [
+          checkNotPromoted(x),
+          checkPromoted(y, 'int'),
         ]),
       ]);
     });
@@ -2026,18 +2023,16 @@
       late SsaNode<Var, Type> ssaAfterTry;
       h.run([
         declare(x, initialized: true),
-        x.read.as_('int').stmt,
+        x.expr.as_('int').stmt,
         checkPromoted(x, 'int'),
-        tryCatch([
+        try_([
           x.write(expr('int?')).stmt,
-          x.read.as_('int').stmt,
+          x.expr.as_('int').stmt,
           checkPromoted(x, 'int'),
           getSsaNodes((nodes) => ssaAfterTry = nodes[x]!),
-        ], [
-          catch_(body: [
-            checkNotPromoted(x),
-            getSsaNodes((nodes) => expect(nodes[x], isNot(ssaAfterTry))),
-          ]),
+        ]).catch_(body: [
+          checkNotPromoted(x),
+          getSsaNodes((nodes) => expect(nodes[x], isNot(ssaAfterTry))),
         ]),
       ]);
     });
@@ -2050,18 +2045,16 @@
       var x = Var('x', 'int?');
       h.run([
         declare(x, initialized: true),
-        x.read.as_('int').stmt,
+        x.expr.as_('int').stmt,
         checkPromoted(x, 'int'),
-        tryCatch([
+        try_([
           localFunction([
             x.write(expr('int?')).stmt,
           ]),
           return_(),
-        ], [
-          catch_(body: [
-            x.read.as_('int').stmt,
-            checkNotPromoted(x),
-          ])
+        ]).catch_(body: [
+          x.expr.as_('int').stmt,
+          checkNotPromoted(x),
         ]),
       ]);
     });
@@ -2072,14 +2065,11 @@
       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),
-          ]),
+        try_([]).catch_(body: [
+          x.expr.as_('int').stmt,
+          checkPromoted(x, 'int'),
+        ]).catch_(body: [
+          checkNotPromoted(x),
         ]),
       ]);
     });
@@ -2089,11 +2079,9 @@
       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),
-          ]),
+        try_([]).catch_(exception: e, stackTrace: st, body: [
+          checkAssigned(e, true),
+          checkAssigned(st, true),
         ]),
       ]);
     });
@@ -2107,14 +2095,12 @@
       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,
-          ]),
+        try_([
+          x.expr.as_('int').stmt,
+          y.expr.as_('int').stmt,
+        ]).catch_(body: [
+          x.expr.as_('int').stmt,
+          z.expr.as_('int').stmt,
         ]),
         // Only x should be promoted, because it's the only variable
         // promoted in both the try body and the catch handler.
@@ -2130,17 +2116,14 @@
       h.run([
         declare(x, initialized: true), declare(y, initialized: true),
         declare(z, initialized: true),
-        tryCatch([
+        try_([
           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,
-          ]),
+        ]).catch_(body: [
+          x.expr.as_('int').stmt,
+          y.expr.as_('int').stmt,
+        ]).catch_(body: [
+          x.expr.as_('int').stmt,
+          z.expr.as_('int').stmt,
         ]),
         // Only x should be promoted, because it's the only variable promoted
         // in both catch handlers.
@@ -2155,12 +2138,12 @@
       h.run([
         declare(x, initialized: true),
         declare(y, initialized: true),
-        y.read.as_('int').stmt,
-        tryFinally([
-          x.read.as_('int').stmt,
+        y.expr.as_('int').stmt,
+        try_([
+          x.expr.as_('int').stmt,
           checkPromoted(x, 'int'),
           checkPromoted(y, 'int'),
-        ], [
+        ]).finally_([
           checkNotPromoted(x),
           checkPromoted(y, 'int'),
         ]),
@@ -2176,15 +2159,15 @@
       late SsaNode<Var, Type> ssaAfterTry;
       h.run([
         declare(x, initialized: true),
-        x.read.as_('int').stmt,
+        x.expr.as_('int').stmt,
         checkPromoted(x, 'int'),
-        tryFinally([
+        try_([
           getSsaNodes((nodes) => ssaAtStartOfTry = nodes[x]!),
           x.write(expr('int?')).stmt,
-          x.read.as_('int').stmt,
+          x.expr.as_('int').stmt,
           checkPromoted(x, 'int'),
           getSsaNodes((nodes) => ssaAfterTry = nodes[x]!),
-        ], [
+        ]).finally_([
           checkNotPromoted(x),
           // The SSA node for X should be different from what it was at any time
           // during the try block, because there is no telling at what point an
@@ -2206,13 +2189,13 @@
       var x = Var('x', 'int?');
       h.run([
         declare(x, initialized: true),
-        tryFinally([
+        try_([
           localFunction([
             x.write(expr('int?')).stmt,
           ]),
           return_(),
-        ], [
-          x.read.as_('int').stmt,
+        ]).finally_([
+          x.expr.as_('int').stmt,
           checkNotPromoted(x),
         ]),
       ]);
@@ -2224,12 +2207,12 @@
       var y = Var('y', 'int?');
       h.run([
         declare(x, initialized: true), declare(y, initialized: true),
-        tryFinally([
-          x.read.as_('int').stmt,
+        try_([
+          x.expr.as_('int').stmt,
           checkPromoted(x, 'int'),
-        ], [
+        ]).finally_([
           checkNotPromoted(x),
-          y.read.as_('int').stmt,
+          y.expr.as_('int').stmt,
           checkPromoted(y, 'int'),
         ]),
         // Both x and y should now be promoted.
@@ -2247,14 +2230,14 @@
       late SsaNode<Var, Type> ySsaAtEndOfFinally;
       h.run([
         declare(x, initialized: true), declare(y, initialized: true),
-        tryFinally([
-          x.read.as_('int').stmt,
+        try_([
+          x.expr.as_('int').stmt,
           checkPromoted(x, 'int'),
-        ], [
+        ]).finally_([
           checkNotPromoted(x),
           x.write(expr('int?')).stmt,
           y.write(expr('int?')).stmt,
-          y.read.as_('int').stmt,
+          y.expr.as_('int').stmt,
           checkPromoted(y, 'int'),
           getSsaNodes((nodes) {
             xSsaAtEndOfFinally = nodes[x]!;
@@ -2288,14 +2271,14 @@
         late SsaNode<Var, Type> ySsaAtEndOfFinally;
         h.run([
           declare(x, initialized: true), declare(y, initialized: true),
-          tryFinally([
+          try_([
             x.write(expr('int?')).stmt,
             y.write(expr('int?')).stmt,
             getSsaNodes((nodes) {
               xSsaAtEndOfTry = nodes[x]!;
               ySsaAtEndOfTry = nodes[y]!;
             }),
-          ], [
+          ]).finally_([
             if_(expr('bool'), [
               x.write(expr('int?')).stmt,
             ]),
@@ -2328,10 +2311,10 @@
           'unreachable', () {
         var h = Harness();
         h.run([
-          tryFinally([
+          try_([
             return_(),
             checkReachable(false),
-          ], [
+          ]).finally_([
             checkReachable(true),
           ]),
           checkReachable(false),
@@ -2343,9 +2326,9 @@
           'unreachable', () {
         var h = Harness();
         h.run([
-          tryFinally([
+          try_([
             checkReachable(true),
-          ], [
+          ]).finally_([
             return_(),
             checkReachable(false),
           ]),
@@ -2359,9 +2342,9 @@
         var h = Harness();
         var x = Var('x', 'int?');
         h.run([
-          tryFinally([
+          try_([
             declare(x, initialized: true),
-          ], []),
+          ]).finally_([]),
         ]);
       });
 
@@ -2371,7 +2354,7 @@
         var h = Harness();
         var x = Var('x', 'int?');
         h.run([
-          tryFinally([], [
+          try_([]).finally_([
             declare(x, initialized: true),
           ]),
         ]);
@@ -2384,12 +2367,12 @@
         var x = Var('x', 'int?');
         h.run([
           declare(x, initialized: true),
-          tryFinally([
+          try_([
             localFunction([
               x.write(expr('int?')).stmt,
             ]),
-          ], []),
-          if_(x.read.notEq(nullLiteral), [
+          ]).finally_([]),
+          if_(x.expr.notEq(nullLiteral), [
             checkNotPromoted(x),
           ]),
         ]);
@@ -2402,12 +2385,12 @@
         var x = Var('x', 'int?');
         h.run([
           declare(x, initialized: true),
-          tryFinally([], [
+          try_([]).finally_([
             localFunction([
               x.write(expr('int?')).stmt,
             ]),
           ]),
-          if_(x.read.notEq(nullLiteral), [
+          if_(x.expr.notEq(nullLiteral), [
             checkNotPromoted(x),
           ]),
         ]);
@@ -2420,12 +2403,12 @@
         var x = Var('x', 'int?');
         h.run([
           declare(x, initialized: true),
-          tryFinally([
-            if_(x.read.eq(nullLiteral), [
+          try_([
+            if_(x.expr.eq(nullLiteral), [
               return_(),
             ]),
             checkPromoted(x, 'int'),
-          ], [
+          ]).finally_([
             localFunction([
               x.write(expr('int?')).stmt,
             ]),
@@ -2433,7 +2416,7 @@
           // The capture in the `finally` cancels old promotions and prevents
           // future promotions.
           checkNotPromoted(x),
-          if_(x.read.notEq(nullLiteral), [
+          if_(x.expr.notEq(nullLiteral), [
             checkNotPromoted(x),
           ]),
         ]);
@@ -2446,13 +2429,13 @@
         var x = Var('x', 'Object');
         h.run([
           declare(x, initialized: true),
-          tryFinally([
-            if_(x.read.is_('num', isInverted: true), [
+          try_([
+            if_(x.expr.is_('num', isInverted: true), [
               return_(),
             ]),
             checkPromoted(x, 'num'),
-          ], [
-            if_(x.read.is_('int', isInverted: true), [
+          ]).finally_([
+            if_(x.expr.is_('int', isInverted: true), [
               return_(),
             ]),
           ]),
@@ -2470,14 +2453,14 @@
         var x = Var('x', 'Object');
         h.run([
           declare(x, initialized: true),
-          tryFinally([
-            if_(x.read.is_('String', isInverted: true), [
+          try_([
+            if_(x.expr.is_('String', isInverted: true), [
               return_(),
             ]),
             checkPromoted(x, 'String'),
-          ], [
+          ]).finally_([
             x.write(expr('Object')).stmt,
-            if_(x.read.is_('int', isInverted: true), [
+            if_(x.expr.is_('int', isInverted: true), [
               return_(),
             ]),
           ]),
@@ -2492,11 +2475,11 @@
         var x = Var('x', 'Object');
         h.run([
           declare(x, initialized: true),
-          tryFinally([
-            if_(x.read.is_('String', isInverted: true), []),
+          try_([
+            if_(x.expr.is_('String', isInverted: true), []),
             checkNotPromoted(x),
-          ], [
-            if_(x.read.is_('int', isInverted: true), []),
+          ]).finally_([
+            if_(x.expr.is_('int', isInverted: true), []),
             checkNotPromoted(x),
           ]),
           checkNotPromoted(x),
@@ -2518,12 +2501,12 @@
         h.run([
           declare(x, initialized: false),
           checkAssigned(x, false),
-          tryFinally([
+          try_([
             if_(expr('bool'), [
               x.write(expr('Object')).stmt,
             ]),
             checkAssigned(x, false),
-          ], [
+          ]).finally_([
             if_(expr('bool'), [
               x.write(expr('Object')).stmt,
             ]),
@@ -2541,10 +2524,10 @@
         h.run([
           declare(x, initialized: false),
           checkAssigned(x, false),
-          tryFinally([
+          try_([
             x.write(expr('Object')).stmt,
             checkAssigned(x, true),
-          ], [
+          ]).finally_([
             if_(expr('bool'), [
               x.write(expr('Object')).stmt,
             ]),
@@ -2562,12 +2545,12 @@
         h.run([
           declare(x, initialized: false),
           checkAssigned(x, false),
-          tryFinally([
+          try_([
             if_(expr('bool'), [
               x.write(expr('Object')).stmt,
             ]),
             checkAssigned(x, false),
-          ], [
+          ]).finally_([
             x.write(expr('Object')).stmt,
             checkAssigned(x, true),
           ]),
@@ -2583,9 +2566,9 @@
         h.run([
           declare(x, initialized: false),
           checkUnassigned(x, true),
-          tryFinally([
+          try_([
             checkUnassigned(x, true),
-          ], [
+          ]).finally_([
             checkUnassigned(x, true),
           ]),
           checkUnassigned(x, true),
@@ -2600,9 +2583,9 @@
         h.run([
           declare(x, initialized: false),
           checkUnassigned(x, true),
-          tryFinally([
+          try_([
             checkUnassigned(x, true),
-          ], [
+          ]).finally_([
             if_(expr('bool'), [
               x.write(expr('Object')).stmt,
             ]),
@@ -2620,12 +2603,12 @@
         h.run([
           declare(x, initialized: false),
           checkUnassigned(x, true),
-          tryFinally([
+          try_([
             if_(expr('bool'), [
               x.write(expr('Object')).stmt,
             ]),
             checkUnassigned(x, false),
-          ], [
+          ]).finally_([
             checkUnassigned(x, false),
           ]),
           checkUnassigned(x, false),
@@ -2645,19 +2628,19 @@
         // Create a variable that promotes x if its value is true, and y if its
         // value is false.
         z
-            .write(x.read.notEq(nullLiteral).conditional(
+            .write(x.expr.notEq(nullLiteral).conditional(
                 booleanLiteral(true),
-                y.read.notEq(nullLiteral).conditional(
+                y.expr.notEq(nullLiteral).conditional(
                     booleanLiteral(false), throw_(expr('Object')))))
             .stmt,
         checkNotPromoted(x),
         checkNotPromoted(y),
         // Simply reading the variable shouldn't promote anything.
-        z.read.stmt,
+        z.expr.stmt,
         checkNotPromoted(x),
         checkNotPromoted(y),
         // But reading it in an "if" condition should promote.
-        if_(z.read, [
+        if_(z.expr, [
           checkPromoted(x, 'int'),
           checkNotPromoted(y),
         ], [
@@ -2679,18 +2662,18 @@
         // value is false.
         declareInitialized(
             z,
-            x.read.notEq(nullLiteral).conditional(
+            x.expr.notEq(nullLiteral).conditional(
                 booleanLiteral(true),
-                y.read.notEq(nullLiteral).conditional(
+                y.expr.notEq(nullLiteral).conditional(
                     booleanLiteral(false), throw_(expr('Object'))))),
         checkNotPromoted(x),
         checkNotPromoted(y),
         // Simply reading the variable shouldn't promote anything.
-        z.read.stmt,
+        z.expr.stmt,
         checkNotPromoted(x),
         checkNotPromoted(y),
         // But reading it in an "if" condition should promote.
-        if_(z.read, [
+        if_(z.expr, [
           checkPromoted(x, 'int'),
           checkNotPromoted(y),
         ], [
@@ -2714,19 +2697,19 @@
         // Create a variable that promotes x if its value is true, and y if its
         // value is false.
         z
-            .write(x.read.notEq(nullLiteral).conditional(
+            .write(x.expr.notEq(nullLiteral).conditional(
                 booleanLiteral(true),
-                y.read.notEq(nullLiteral).conditional(
+                y.expr.notEq(nullLiteral).conditional(
                     booleanLiteral(false), throw_(expr('Object')))))
             .stmt,
         checkNotPromoted(w),
         checkNotPromoted(x),
         checkNotPromoted(y),
-        w.read.nonNullAssert.stmt,
+        w.expr.nonNullAssert.stmt,
         checkPromoted(w, 'int'),
         // Reading the value of z in an "if" condition should promote x or y,
         // and keep the promotion of w.
-        if_(z.read, [
+        if_(z.expr, [
           checkPromoted(w, 'int'),
           checkPromoted(x, 'int'),
           checkNotPromoted(y),
@@ -2752,7 +2735,7 @@
         y.write(nullLiteral).stmt,
         checkNotPromoted(x),
         checkNotPromoted(y),
-        if_(x.read.eq(y.read), [
+        if_(x.expr.eq(y.expr), [
           checkNotPromoted(x),
           checkNotPromoted(y),
         ], [
@@ -2770,7 +2753,7 @@
       late SsaNode<Var, Type> ssaBeforeLoop;
       h.run([
         declare(x, initialized: true),
-        x.read.as_('int').stmt,
+        x.expr.as_('int').stmt,
         checkPromoted(x, 'int'),
         getSsaNodes((nodes) => ssaBeforeLoop = nodes[x]!),
         while_(
@@ -2790,11 +2773,11 @@
       var x = Var('x', 'int?');
       h.run([
         declare(x, initialized: true),
-        x.read.as_('int').stmt,
+        x.expr.as_('int').stmt,
         checkPromoted(x, 'int'),
         while_(
             block([
-              x.read.as_('int').stmt,
+              x.expr.as_('int').stmt,
               checkNotPromoted(x),
               localFunction([
                 x.write(expr('int?')).stmt,
@@ -2810,7 +2793,7 @@
       var y = Var('y', 'int?');
       h.run([
         declare(y, initialized: true),
-        y.read.as_('int').stmt,
+        y.expr.as_('int').stmt,
         while_(declare(x, initialized: true).thenExpr(expr('bool')), [
           x.write(expr('Null')).stmt,
         ]),
@@ -2822,7 +2805,7 @@
       var x = Var('x', 'int?');
       h.run([
         declare(x, initialized: true),
-        while_(x.read.notEq(nullLiteral), [
+        while_(x.expr.notEq(nullLiteral), [
           checkPromoted(x, 'int'),
         ]),
       ]);
@@ -2840,14 +2823,13 @@
         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),
-                  ]),
-                ])),
+        while_(x.expr.eq(nullLiteral).or(z.expr.eq(nullLiteral)), [
+          if_(expr('bool'), [
+            x.expr.as_('int').stmt,
+            y.expr.as_('int').stmt,
+            break_(),
+          ]),
+        ]),
         checkPromoted(x, 'int'),
         checkNotPromoted(y),
         checkNotPromoted(z),
@@ -2863,14 +2845,14 @@
       h.run([
         declare(x, initialized: true),
         declare(y, initialized: true),
-        branchTarget((t) => while_(expr('bool'), [
-              x.write(expr('int?')).stmt,
-              if_(expr('bool'), [break_(t)]),
-              getSsaNodes((nodes) {
-                xSsaInsideLoop = nodes[x]!;
-                ySsaInsideLoop = nodes[y]!;
-              }),
-            ])),
+        while_(expr('bool'), [
+          x.write(expr('int?')).stmt,
+          if_(expr('bool'), [break_()]),
+          getSsaNodes((nodes) {
+            xSsaInsideLoop = nodes[x]!;
+            ySsaInsideLoop = nodes[y]!;
+          }),
+        ]),
         getSsaNodes((nodes) {
           // x's Ssa should have been changed because of the join at the end of
           // the loop.  y's should not, since it retains the value it had prior
@@ -2892,15 +2874,15 @@
       h.run([
         declare(x, initialized: true),
         declare(y, initialized: true),
-        branchTarget((t) => while_(expr('bool'), [
-              x.write(expr('int?')).stmt,
-              if_(expr('bool'), [break_(t)]),
-              if_(x.read.is_('int'), []),
-              getSsaNodes((nodes) {
-                xSsaInsideLoop = nodes[x]!;
-                ySsaInsideLoop = nodes[y]!;
-              }),
-            ])),
+        while_(expr('bool'), [
+          x.write(expr('int?')).stmt,
+          if_(expr('bool'), [break_()]),
+          if_(x.expr.is_('int'), []),
+          getSsaNodes((nodes) {
+            xSsaInsideLoop = nodes[x]!;
+            ySsaInsideLoop = nodes[y]!;
+          }),
+        ]),
         getSsaNodes((nodes) {
           // x's Ssa should have been changed because of the join at the end of
           // the loop.  y's should not, since it retains the value it had prior
@@ -2920,11 +2902,11 @@
       h.run([
         declare(x, initialized: true),
         declare(y, initialized: true),
-        x.read.as_('int').stmt,
+        x.expr.as_('int').stmt,
         checkPromoted(x, 'int'),
         getSsaNodes((nodes) => ssaBeforeWrite = nodes[x]!),
         x
-            .write(y.read.eq(nullLiteral).getExpressionInfo((info) {
+            .write(y.expr.eq(nullLiteral).getExpressionInfo((info) {
               expect(info, isNotNull);
               writtenValueInfo = info!;
             }))
@@ -2947,7 +2929,7 @@
         declare(x, initialized: true),
         getSsaNodes((nodes) => ssaBeforeWrite = nodes[x]!),
         x
-            .write(y.read.eq(nullLiteral).getExpressionInfo((info) {
+            .write(y.expr.eq(nullLiteral).getExpressionInfo((info) {
               expect(info, isNotNull);
               writtenValueInfo = info!;
             }))
@@ -2983,7 +2965,7 @@
           xSsaBeforeWrite = nodes[x]!;
           ySsa = nodes[y]!;
         }),
-        x.write(y.read).stmt,
+        x.write(y.expr).stmt,
         getSsaNodes((nodes) {
           expect(nodes[x], isNot(xSsaBeforeWrite));
           expect(nodes[x], isNot(ySsa));
@@ -3006,7 +2988,7 @@
         // `y == null` is a trivial expression because y has been write
         // captured.
         x
-            .write(y.read
+            .write(y.expr
                 .eq(nullLiteral)
                 .getExpressionInfo((info) => expect(info, isNotNull)))
             .stmt,
@@ -3049,7 +3031,7 @@
       var x = Var('x', 'Object');
       h.run([
         declare(x, initialized: true),
-        x.read.as_('int').stmt,
+        x.expr.as_('int').stmt,
         checkPromoted(x, 'int'),
         if_(booleanLiteral(false), [
           checkPromoted(x, 'int'),
@@ -3066,7 +3048,7 @@
           x.write(expr('Object')).stmt,
         ]),
         getSsaNodes((nodes) => expect(nodes[x], isNull)),
-        x.read.as_('int').stmt,
+        x.expr.as_('int').stmt,
         checkNotPromoted(x),
         getSsaNodes((nodes) => expect(nodes[x], isNull)),
       ]);
@@ -3084,12 +3066,12 @@
         ], [
           // Promotion should work here because the write capture is in the
           // other branch.
-          x.read.as_('int').stmt, checkPromoted(x, 'int'),
+          x.expr.as_('int').stmt, checkPromoted(x, 'int'),
         ]),
         // But the promotion should be cancelled now, after the join.
         checkNotPromoted(x),
         // And further attempts to promote should fail due to the write capture.
-        x.read.as_('int').stmt, checkNotPromoted(x),
+        x.expr.as_('int').stmt, checkNotPromoted(x),
       ]);
     });
   });
@@ -4746,7 +4728,7 @@
           var h = Harness(legacy: true);
           var x = Var('x', 'Object');
           h.run([
-            if_(x.read.is_('int'), [
+            if_(x.expr.is_('int'), [
               checkPromoted(x, 'int'),
             ]),
           ]);
@@ -4756,7 +4738,7 @@
           var h = Harness(legacy: true);
           var x = Var('x', 'Object');
           h.run([
-            if_(x.read.is_('int'), [], [
+            if_(x.expr.is_('int'), [], [
               checkNotPromoted(x),
             ]),
           ]);
@@ -4766,7 +4748,7 @@
           var h = Harness(legacy: true);
           var x = Var('x', 'Object');
           h.run([
-            if_(x.read.is_('int'), [
+            if_(x.expr.is_('int'), [
               checkNotPromoted(x),
               x.write(expr('int')).stmt,
             ]),
@@ -4782,7 +4764,7 @@
                     .write(expr('int'))
                     .parenthesized
                     .eq(expr('int'))
-                    .and(x.read.is_('int')),
+                    .and(x.expr.is_('int')),
                 [
                   checkPromoted(x, 'int'),
                 ]),
@@ -4793,7 +4775,7 @@
           var h = Harness(legacy: true);
           var x = Var('x', 'Object');
           h.run([
-            if_(x.read.is_('int'), [
+            if_(x.expr.is_('int'), [
               checkPromoted(x, 'int'),
             ], [
               x.write(expr('int')).stmt,
@@ -4805,7 +4787,7 @@
           var h = Harness(legacy: true);
           var x = Var('x', 'Object');
           h.run([
-            if_(x.read.is_('int'), [
+            if_(x.expr.is_('int'), [
               checkNotPromoted(x),
             ]),
             localFunction([
@@ -4820,10 +4802,10 @@
           var h = Harness(legacy: true);
           var x = Var('x', 'Object');
           h.run([
-            if_(x.read.is_('int'), [
+            if_(x.expr.is_('int'), [
               checkNotPromoted(x),
               localFunction([
-                x.read.stmt,
+                x.expr.stmt,
               ]),
             ]),
             x.write(expr('int')).stmt,
@@ -4836,11 +4818,11 @@
           var h = Harness(legacy: true);
           var x = Var('x', 'Object');
           h.run([
-            if_(x.read.is_('int'), [
+            if_(x.expr.is_('int'), [
               checkNotPromoted(x),
               localFunction([
                 localFunction([
-                  x.read.stmt,
+                  x.expr.stmt,
                 ]),
               ]),
             ]),
@@ -4856,8 +4838,8 @@
           h.run([
             if_(
                 localFunction([
-                  x.read.stmt,
-                ]).thenExpr(expr('bool')).and(x.read.is_('int')),
+                  x.expr.stmt,
+                ]).thenExpr(expr('bool')).and(x.expr.is_('int')),
                 [
                   checkPromoted(x, 'int'),
                 ]),
@@ -4871,11 +4853,11 @@
           var h = Harness(legacy: true);
           var x = Var('x', 'Object');
           h.run([
-            if_(x.read.is_('int'), [
+            if_(x.expr.is_('int'), [
               checkPromoted(x, 'int'),
             ], [
               localFunction([
-                x.read.stmt,
+                x.expr.stmt,
               ]),
             ]),
             x.write(expr('int')).stmt,
@@ -4888,10 +4870,10 @@
           var h = Harness(legacy: true);
           var x = Var('x', 'Object');
           h.run([
-            if_(x.read.is_('int'), [
+            if_(x.expr.is_('int'), [
               checkPromoted(x, 'int'),
               localFunction([
-                x.read.stmt,
+                x.expr.stmt,
               ]),
             ]),
           ]);
@@ -4909,7 +4891,7 @@
         var h = Harness(legacy: true);
         var x = Var('x', 'bool');
         h.run([
-          if_(x.read, []),
+          if_(x.expr, []),
         ]);
       });
 
@@ -4918,7 +4900,7 @@
         var x = Var('x', 'Object');
         var y = Var('y', 'Object');
         h.run([
-          if_(x.read.is_('int').and(y.read.is_('String')), [
+          if_(x.expr.is_('int').and(y.expr.is_('String')), [
             checkPromoted(x, 'int'),
             checkPromoted(y, 'String'),
           ]),
@@ -4932,7 +4914,7 @@
           var h = Harness(legacy: true);
           var x = Var('x', 'Object');
           h.run([
-            x.read
+            x.expr
                 .is_('int')
                 .conditional(checkPromoted(x, 'int').thenExpr(expr('Object')),
                     expr('Object'))
@@ -4944,7 +4926,7 @@
           var h = Harness(legacy: true);
           var x = Var('x', 'Object');
           h.run([
-            x.read
+            x.expr
                 .is_('int')
                 .conditional(expr('Object'),
                     checkNotPromoted(x).thenExpr(expr('Object')))
@@ -4956,7 +4938,7 @@
           var h = Harness(legacy: true);
           var x = Var('x', 'Object');
           h.run([
-            x.read
+            x.expr
                 .is_('int')
                 .conditional(
                     block([
@@ -4976,7 +4958,7 @@
                 .write(expr('int'))
                 .parenthesized
                 .eq(expr('int'))
-                .and(x.read.is_('int'))
+                .and(x.expr.is_('int'))
                 .conditional(checkPromoted(x, 'int').thenExpr(expr('Object')),
                     expr('Object'))
                 .stmt,
@@ -4987,7 +4969,7 @@
           var h = Harness(legacy: true);
           var x = Var('x', 'Object');
           h.run([
-            x.read
+            x.expr
                 .is_('int')
                 .conditional(checkPromoted(x, 'int').thenExpr(expr('int')),
                     x.write(expr('int')))
@@ -4999,7 +4981,7 @@
           var h = Harness(legacy: true);
           var x = Var('x', 'Object');
           h.run([
-            x.read
+            x.expr
                 .is_('int')
                 .conditional(checkNotPromoted(x).thenExpr(expr('Object')),
                     expr('Object'))
@@ -5016,13 +4998,13 @@
           var h = Harness(legacy: true);
           var x = Var('x', 'Object');
           h.run([
-            x.read
+            x.expr
                 .is_('int')
                 .conditional(
                     block([
                       checkNotPromoted(x),
                       localFunction([
-                        x.read.stmt,
+                        x.expr.stmt,
                       ]),
                     ]).thenExpr(expr('Object')),
                     expr('Object'))
@@ -5038,10 +5020,10 @@
           var x = Var('x', 'Object');
           h.run([
             localFunction([
-              x.read.stmt,
+              x.expr.stmt,
             ])
                 .thenExpr(expr('Object'))
-                .and(x.read.is_('int'))
+                .and(x.expr.is_('int'))
                 .conditional(checkPromoted(x, 'int').thenExpr(expr('Object')),
                     expr('Object'))
                 .stmt,
@@ -5055,12 +5037,12 @@
           var h = Harness(legacy: true);
           var x = Var('x', 'Object');
           h.run([
-            x.read
+            x.expr
                 .is_('int')
                 .conditional(
                     checkPromoted(x, 'int').thenExpr(expr('Object')),
                     localFunction([
-                      x.read.stmt,
+                      x.expr.stmt,
                     ]).thenExpr(expr('Object')))
                 .stmt,
             x.write(expr('int')).stmt,
@@ -5073,13 +5055,13 @@
           var h = Harness(legacy: true);
           var x = Var('x', 'Object');
           h.run([
-            x.read
+            x.expr
                 .is_('int')
                 .conditional(
                     block([
                       checkPromoted(x, 'int'),
                       localFunction([
-                        x.read.stmt,
+                        x.expr.stmt,
                       ]),
                     ]).thenExpr(expr('Object')),
                     expr('Object'))
@@ -5099,7 +5081,7 @@
         var h = Harness(legacy: true);
         var x = Var('x', 'bool');
         h.run([
-          x.read.conditional(expr('Object'), expr('Object')).stmt,
+          x.expr.conditional(expr('Object'), expr('Object')).stmt,
         ]);
       });
 
@@ -5108,9 +5090,9 @@
         var x = Var('x', 'Object');
         var y = Var('y', 'Object');
         h.run([
-          x.read
+          x.expr
               .is_('int')
-              .and(y.read.is_('String'))
+              .and(y.expr.is_('String'))
               .conditional(
                   block([
                     checkPromoted(x, 'int'),
@@ -5129,7 +5111,7 @@
             var h = Harness(legacy: true);
             var x = Var('x', 'Object');
             h.run([
-              if_(x.read.is_('int').and(expr('bool')), [
+              if_(x.expr.is_('int').and(expr('bool')), [
                 checkPromoted(x, 'int'),
               ]),
             ]);
@@ -5139,7 +5121,7 @@
             var h = Harness(legacy: true);
             var x = Var('x', 'Object');
             h.run([
-              if_(expr('bool').and(x.read.is_('int')), [
+              if_(expr('bool').and(x.expr.is_('int')), [
                 checkPromoted(x, 'int'),
               ]),
             ]);
@@ -5149,7 +5131,7 @@
             var h = Harness(legacy: true);
             var x = Var('x', 'Object');
             h.run([
-              if_(x.read.is_('int').and(x.write(expr('bool'))), [
+              if_(x.expr.is_('int').and(x.write(expr('bool'))), [
                 checkNotPromoted(x),
               ]),
             ]);
@@ -5163,7 +5145,7 @@
               if_(
                   expr('bool').and(x
                       .write(expr('Object'))
-                      .and(x.read.is_('int'))
+                      .and(x.expr.is_('int'))
                       .parenthesized),
                   [
                     checkNotPromoted(x),
@@ -5175,7 +5157,7 @@
             var h = Harness(legacy: true);
             var x = Var('x', 'Object');
             h.run([
-              if_(x.read.is_('int').and(expr('bool')), [
+              if_(x.expr.is_('int').and(expr('bool')), [
                 checkNotPromoted(x),
               ]),
               localFunction([
@@ -5190,7 +5172,7 @@
             var h = Harness(legacy: true);
             var x = Var('x', 'Object');
             h.run([
-              x.read
+              x.expr
                   .is_('int')
                   .and(checkPromoted(x, 'int').thenExpr(expr('bool')))
                   .stmt,
@@ -5205,7 +5187,7 @@
                   .write(expr('int'))
                   .parenthesized
                   .eq(expr('int'))
-                  .and(x.read.is_('int'))
+                  .and(x.expr.is_('int'))
                   .parenthesized
                   .and(checkNotPromoted(x).thenExpr(expr('bool')))
                   .stmt,
@@ -5216,7 +5198,7 @@
             var h = Harness(legacy: true);
             var x = Var('x', 'Object');
             h.run([
-              x.read
+              x.expr
                   .is_('int')
                   .and(checkNotPromoted(x).thenExpr(x.write(expr('bool'))))
                   .stmt,
@@ -5227,7 +5209,7 @@
             var h = Harness(legacy: true);
             var x = Var('x', 'Object');
             h.run([
-              x.read
+              x.expr
                   .is_('int')
                   .and(checkNotPromoted(x).thenExpr(expr('bool')))
                   .stmt,
@@ -5243,12 +5225,12 @@
             var h = Harness(legacy: true);
             var x = Var('x', 'Object');
             h.run([
-              x.read
+              x.expr
                   .is_('int')
                   .and(block([
                     checkNotPromoted(x),
                     localFunction([
-                      x.read.stmt,
+                      x.expr.stmt,
                     ]),
                   ]).thenExpr(expr('bool')))
                   .stmt,
@@ -5263,10 +5245,10 @@
             var x = Var('x', 'Object');
             h.run([
               localFunction([
-                x.read.stmt,
+                x.expr.stmt,
               ])
                   .thenExpr(expr('Object'))
-                  .and(x.read.is_('int'))
+                  .and(x.expr.is_('int'))
                   .parenthesized
                   .and(checkPromoted(x, 'int').thenExpr(expr('bool')))
                   .stmt,
@@ -5280,12 +5262,12 @@
             var h = Harness(legacy: true);
             var x = Var('x', 'Object');
             h.run([
-              x.read
+              x.expr
                   .is_('int')
                   .and(block([
                     checkPromoted(x, 'int'),
                     localFunction([
-                      x.read.stmt,
+                      x.expr.stmt,
                     ]),
                   ]).thenExpr(expr('bool')))
                   .stmt,
@@ -5304,9 +5286,9 @@
                 x
                     .write(expr('Object'))
                     .parenthesized
-                    .and(x.read.is_('int'))
+                    .and(x.expr.is_('int'))
                     .parenthesized
-                    .and(x.read.is_('num')),
+                    .and(x.expr.is_('num')),
                 [
                   checkPromoted(x, 'int'),
                 ]),
@@ -5317,7 +5299,7 @@
           var h = Harness(legacy: true);
           var x = Var('x', 'Object');
           h.run([
-            if_(x.read.is_('num').and(x.read.is_('int')), [
+            if_(x.expr.is_('num').and(x.expr.is_('int')), [
               checkPromoted(x, 'int'),
             ]),
           ]);
@@ -5328,9 +5310,9 @@
           var x = Var('x', 'Object');
           var y = Var('y', 'Object');
           h.run([
-            x.read
+            x.expr
                 .is_('int')
-                .and(y.read.is_('String'))
+                .and(y.expr.is_('String'))
                 .parenthesized
                 .and(block([
                   checkPromoted(x, 'int'),
@@ -5345,7 +5327,7 @@
           var x = Var('x', 'bool');
           var y = Var('y', 'bool');
           h.run([
-            if_(x.read.and(y.read), []),
+            if_(x.expr.and(y.expr), []),
           ]);
         });
 
@@ -5361,7 +5343,7 @@
         var h = Harness(legacy: true);
         var x = Var('x', 'Object');
         h.run([
-          if_(x.read.is_('int').or(x.read.is_('int')), [
+          if_(x.expr.is_('int').or(x.expr.is_('int')), [
             checkNotPromoted(x),
           ], [
             checkNotPromoted(x),
@@ -5376,7 +5358,7 @@
           var h = Harness(legacy: true);
           var x = Var('x', 'Object');
           h.run([
-            if_(x.read.is_('int'), [
+            if_(x.expr.is_('int'), [
               checkPromoted(x, 'int'),
             ], [
               checkNotPromoted(x),
@@ -5388,7 +5370,7 @@
           var h = Harness(legacy: true);
           var x = Var('x', 'Object');
           h.run([
-            if_(x.read.is_('int', isInverted: true), [
+            if_(x.expr.is_('int', isInverted: true), [
               checkNotPromoted(x),
             ], [
               checkNotPromoted(x),
@@ -5401,7 +5383,7 @@
           var h = Harness(legacy: true);
           var x = Var('x', 'String');
           h.run([
-            if_(x.read.is_('int'), [
+            if_(x.expr.is_('int'), [
               checkNotPromoted(x),
             ], [
               checkNotPromoted(x),
@@ -5413,8 +5395,8 @@
           var h = Harness(legacy: true);
           var x = Var('x', 'Object');
           h.run([
-            if_(x.read.is_('num'), [
-              if_(x.read.is_('int'), [
+            if_(x.expr.is_('num'), [
+              if_(x.expr.is_('int'), [
                 checkPromoted(x, 'int'),
               ], [
                 checkPromoted(x, 'num'),
@@ -5429,8 +5411,8 @@
           var h = Harness(legacy: true);
           var x = Var('x', 'Object');
           h.run([
-            if_(x.read.is_('String'), [
-              if_(x.read.is_('int'), [
+            if_(x.expr.is_('String'), [
+              if_(x.expr.is_('int'), [
                 checkPromoted(x, 'String'),
               ], [
                 checkPromoted(x, 'String'),
@@ -5444,7 +5426,7 @@
           h.addPromotionException('T', 'int', 'T&int');
           var x = Var('x', 'T');
           h.run([
-            if_(x.read.is_('int'), [
+            if_(x.expr.is_('int'), [
               checkPromoted(x, 'T&int'),
             ]),
           ]);
@@ -5464,7 +5446,7 @@
       var h = Harness(legacy: true);
       var x = Var('x', 'Object');
       h.run([
-        if_(x.read.is_('int').eq(expr('Object')).thenStmt(block([])), [
+        if_(x.expr.is_('int').eq(expr('Object')).thenStmt(block([])), [
           checkNotPromoted(x),
         ]),
       ]);
@@ -5476,7 +5458,7 @@
       var h = Harness(legacy: true);
       var x = Var('x', 'Object');
       h.run([
-        if_(x.read.is_('int').eq(expr('Object')).parenthesized, [
+        if_(x.expr.is_('int').eq(expr('Object')).parenthesized, [
           checkNotPromoted(x),
         ]),
       ]);
@@ -5506,17 +5488,17 @@
       late Expression writeExpression;
       h.run([
         declare(x, initialized: true),
-        if_(x.read.eq(nullLiteral), [
+        if_(x.expr.eq(nullLiteral), [
           return_(),
         ]),
         checkPromoted(x, 'int'),
         (writeExpression = x.write(expr('int?'))).stmt,
         checkNotPromoted(x),
-        x.read.whyNotPromoted((reasons) {
+        x.expr.whyNotPromoted((reasons) {
           expect(reasons.keys, unorderedEquals([Type('int')]));
           var nonPromotionReason =
-              reasons.values.single as DemoteViaExplicitWrite<Var, Expression>;
-          expect(nonPromotionReason.writeExpression, same(writeExpression));
+              reasons.values.single as DemoteViaExplicitWrite<Var>;
+          expect(nonPromotionReason.node, same(writeExpression));
         }).stmt,
       ]);
     });
@@ -5527,24 +5509,20 @@
       late Expression writeExpression;
       h.run([
         declare(x, initialized: true),
-        if_(x.read.isNot('int?'), [
+        if_(x.expr.isNot('int?'), [
           return_(),
         ]),
-        if_(x.read.eq(nullLiteral), [
+        if_(x.expr.eq(nullLiteral), [
           return_(),
         ]),
         checkPromoted(x, 'int'),
         (writeExpression = x.write(expr('Object?'))).stmt,
         checkNotPromoted(x),
-        x.read.whyNotPromoted((reasons) {
+        x.expr.whyNotPromoted((reasons) {
           expect(reasons.keys, unorderedEquals([Type('int'), Type('int?')]));
-          expect(
-              (reasons[Type('int')] as DemoteViaExplicitWrite<Var, Expression>)
-                  .writeExpression,
+          expect((reasons[Type('int')] as DemoteViaExplicitWrite<Var>).node,
               same(writeExpression));
-          expect(
-              (reasons[Type('int?')] as DemoteViaExplicitWrite<Var, Expression>)
-                  .writeExpression,
+          expect((reasons[Type('int?')] as DemoteViaExplicitWrite<Var>).node,
               same(writeExpression));
         }).stmt,
       ]);
@@ -5556,7 +5534,7 @@
       late Expression writeExpression;
       h.run([
         declare(x, initialized: true),
-        if_(x.read.eq(nullLiteral), [
+        if_(x.expr.eq(nullLiteral), [
           return_(),
         ]),
         checkPromoted(x, 'int'),
@@ -5565,11 +5543,11 @@
         if_(expr('bool'), [
           return_(),
         ]),
-        x.read.whyNotPromoted((reasons) {
+        x.expr.whyNotPromoted((reasons) {
           expect(reasons.keys, unorderedEquals([Type('int')]));
           var nonPromotionReason =
-              reasons.values.single as DemoteViaExplicitWrite<Var, Expression>;
-          expect(nonPromotionReason.writeExpression, same(writeExpression));
+              reasons.values.single as DemoteViaExplicitWrite<Var>;
+          expect(nonPromotionReason.node, same(writeExpression));
         }).stmt,
       ]);
     });
@@ -5580,20 +5558,20 @@
       late Expression writeExpression;
       h.run([
         declare(x, initialized: true),
-        if_(x.read.is_('int', isInverted: true), [
+        if_(x.expr.is_('int', isInverted: true), [
           return_(),
         ]),
         checkPromoted(x, 'int'),
         (writeExpression = x.write(expr('Object'))).stmt,
         checkNotPromoted(x),
-        if_(x.read.is_('num', isInverted: true), [
+        if_(x.expr.is_('num', isInverted: true), [
           return_(),
         ]),
         checkPromoted(x, 'num'),
-        x.read.whyNotPromoted((reasons) {
+        x.expr.whyNotPromoted((reasons) {
           var nonPromotionReason =
-              reasons[Type('int')] as DemoteViaExplicitWrite;
-          expect(nonPromotionReason.writeExpression, same(writeExpression));
+              reasons[Type('int')] as DemoteViaExplicitWrite<Var>;
+          expect(nonPromotionReason.node, same(writeExpression));
         }).stmt,
       ]);
     });
@@ -5603,17 +5581,17 @@
       var x = Var('x', 'int?');
       h.run([
         declare(x, initialized: true),
-        if_(x.read.eq(nullLiteral), [
+        if_(x.expr.eq(nullLiteral), [
           return_(),
         ]),
         checkPromoted(x, 'int'),
         x.write(expr('int?')).stmt,
         checkNotPromoted(x),
-        if_(x.read.eq(nullLiteral), [
+        if_(x.expr.eq(nullLiteral), [
           return_(),
         ]),
         checkPromoted(x, 'int'),
-        x.read.whyNotPromoted((reasons) {
+        x.expr.whyNotPromoted((reasons) {
           expect(reasons, isEmpty);
         }).stmt,
       ]);
@@ -5621,12 +5599,12 @@
 
     group('because property', () {
       test('via explicit this', () {
-        var h = Harness();
+        var h = Harness(thisType: 'C')..addMember('C', 'field', 'Object?');
         h.run([
-          if_(this_('C').propertyGet('field').eq(nullLiteral), [
+          if_(this_.property('field').eq(nullLiteral), [
             return_(),
           ]),
-          this_('C').propertyGet('field').whyNotPromoted((reasons) {
+          this_.property('field').whyNotPromoted((reasons) {
             expect(reasons.keys, unorderedEquals([Type('Object')]));
             var nonPromotionReason = reasons.values.single;
             expect(nonPromotionReason, TypeMatcher<PropertyNotPromoted>());
@@ -5649,14 +5627,14 @@
       });
 
       test('via variable', () {
-        var h = Harness();
+        var h = Harness()..addMember('C', 'field', 'Object?');
         var x = Var('x', 'C');
         h.run([
           declare(x, initialized: true),
-          if_(x.read.propertyGet('field').eq(nullLiteral), [
+          if_(x.expr.property('field').eq(nullLiteral), [
             return_(),
           ]),
-          x.read.propertyGet('field').whyNotPromoted((reasons) {
+          x.expr.property('field').whyNotPromoted((reasons) {
             expect(reasons.keys, unorderedEquals([Type('Object')]));
             var nonPromotionReason = reasons.values.single;
             expect(nonPromotionReason, TypeMatcher<PropertyNotPromoted>());
@@ -5667,14 +5645,14 @@
 
     group('because this', () {
       test('explicit', () {
-        var h = Harness()
+        var h = Harness(thisType: 'C')
           ..addSubtype('D', 'C', true)
           ..addFactor('C', 'D', 'C');
         h.run([
-          if_(this_('C').isNot('D'), [
+          if_(this_.isNot('D'), [
             return_(),
           ]),
-          this_('C').whyNotPromoted((reasons) {
+          this_.whyNotPromoted((reasons) {
             expect(reasons.keys, unorderedEquals([Type('D')]));
             var nonPromotionReason = reasons.values.single;
             expect(nonPromotionReason, TypeMatcher<ThisNotPromoted>());
@@ -5683,11 +5661,11 @@
       });
 
       test('implicit', () {
-        var h = Harness()
+        var h = Harness(thisType: 'C')
           ..addSubtype('D', 'C', true)
           ..addFactor('C', 'D', 'C');
         h.run([
-          if_(this_('C').isNot('D'), [
+          if_(this_.isNot('D'), [
             return_(),
           ]),
           implicitThis_whyNotPromoted('C', (reasons) {
@@ -5769,12 +5747,14 @@
 }
 
 class _MockNonPromotionReason extends NonPromotionReason {
+  @override
+  String get documentationLink => fail('Unexpected call to documentationLink');
+
   String get shortName => fail('Unexpected call to shortName');
 
-  R accept<R, Node extends Object, Expression extends Object,
-              Variable extends Object, Type extends Object>(
-          NonPromotionReasonVisitor<R, Node, Expression, Variable, Type>
-              visitor) =>
+  R accept<R, Node extends Object, Variable extends Object,
+              Type extends Object>(
+          NonPromotionReasonVisitor<R, Node, Variable, Type> visitor) =>
       fail('Unexpected call to accept');
 }
 
diff --git a/pkg/_fe_analyzer_shared/test/flow_analysis/nullability/data/null_check.dart b/pkg/_fe_analyzer_shared/test/flow_analysis/nullability/data/null_check.dart
index 51ba181..d00347b 100644
--- a/pkg/_fe_analyzer_shared/test/flow_analysis/nullability/data/null_check.dart
+++ b/pkg/_fe_analyzer_shared/test/flow_analysis/nullability/data/null_check.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:async';
+
 void bang_promotes(int? x) {
   x!;
   /*nonNullable*/ x;
@@ -33,3 +35,18 @@
   x!;
   /*nonNullable*/ x;
 }
+
+void bang_promotesNullableFutureInt(FutureOr<int>? x) {
+  x!;
+  /*nonNullable*/ x;
+}
+
+void bang_promotesFutureNullableInt(FutureOr<int?> x) {
+  x!;
+  x;
+}
+
+void bang_promotesNullableFutureNullableInt(FutureOr<int?>? x) {
+  x!;
+  x;
+}
diff --git a/pkg/_fe_analyzer_shared/test/flow_analysis/type_promotion/data/type_parameter.dart b/pkg/_fe_analyzer_shared/test/flow_analysis/type_promotion/data/type_parameter.dart
index 1b4354d..c818df6 100644
--- a/pkg/_fe_analyzer_shared/test/flow_analysis/type_promotion/data/type_parameter.dart
+++ b/pkg/_fe_analyzer_shared/test/flow_analysis/type_promotion/data/type_parameter.dart
@@ -50,7 +50,7 @@
 class F<S, T extends S> {
   void nonNull(T t) {
     if (t != null) {
-      /*analyzer.T & S & Object*/ /*cfe.T & S*/ t;
+      /*T & S & Object*/ t;
     }
   }
 }
diff --git a/pkg/_fe_analyzer_shared/test/flow_analysis/why_not_promoted/data/argument_type_not_assignable_nullability_error.dart b/pkg/_fe_analyzer_shared/test/flow_analysis/why_not_promoted/data/argument_type_not_assignable_nullability_error.dart
new file mode 100644
index 0000000..4496ca6
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/test/flow_analysis/why_not_promoted/data/argument_type_not_assignable_nullability_error.dart
@@ -0,0 +1,479 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for 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 contains a test case for each condition that can lead to the front
+// end's `ArgumentTypeNotAssignableNullability` error, for which we wish to
+// report "why not promoted" context information.
+
+class C1 {
+  int? bad;
+  f(int i) {}
+}
+
+required_unnamed(C1 c) {
+  if (c.bad == null) return;
+  c.f(
+      /*analyzer.notPromoted(propertyNotPromoted(target: member:C1.bad, type: int?))*/ c
+          . /*cfe.notPromoted(propertyNotPromoted(target: member:C1.bad, type: int?))*/ bad);
+}
+
+class C2 {
+  int? bad;
+  f([int i = 0]) {}
+}
+
+optional_unnamed(C2 c) {
+  if (c.bad == null) return;
+  c.f(
+      /*analyzer.notPromoted(propertyNotPromoted(target: member:C2.bad, type: int?))*/ c
+          . /*cfe.notPromoted(propertyNotPromoted(target: member:C2.bad, type: int?))*/ bad);
+}
+
+class C3 {
+  int? bad;
+  f({required int i}) {}
+}
+
+required_named(C3 c) {
+  if (c.bad == null) return;
+  c.f(
+      /*analyzer.notPromoted(propertyNotPromoted(target: member:C3.bad, type: int?))*/ i:
+          c. /*cfe.notPromoted(propertyNotPromoted(target: member:C3.bad, type: int?))*/ bad);
+}
+
+class C4 {
+  int? bad;
+  f({int i = 0}) {}
+}
+
+optional_named(C4 c) {
+  if (c.bad == null) return;
+  c.f(
+      /*analyzer.notPromoted(propertyNotPromoted(target: member:C4.bad, type: int?))*/ i:
+          c. /*cfe.notPromoted(propertyNotPromoted(target: member:C4.bad, type: int?))*/ bad);
+}
+
+class C5 {
+  List<int>? bad;
+  f<T>(List<T> x) {}
+}
+
+type_inferred(C5 c) {
+  if (c.bad == null) return;
+  c.f(
+      /*analyzer.notPromoted(propertyNotPromoted(target: member:C5.bad, type: List<int>?))*/ c
+          . /*cfe.notPromoted(propertyNotPromoted(target: member:C5.bad, type: List<int>?))*/ bad);
+}
+
+class C6 {
+  int? bad;
+  C6(int i);
+}
+
+C6? constructor_with_implicit_new(C6 c) {
+  if (c.bad == null) return null;
+  return C6(
+      /*analyzer.notPromoted(propertyNotPromoted(target: member:C6.bad, type: int?))*/ c
+          . /*cfe.notPromoted(propertyNotPromoted(target: member:C6.bad, type: int?))*/ bad);
+}
+
+class C7 {
+  int? bad;
+  C7(int i);
+}
+
+C7? constructor_with_explicit_new(C7 c) {
+  if (c.bad == null) return null;
+  return new C7(
+      /*analyzer.notPromoted(propertyNotPromoted(target: member:C7.bad, type: int?))*/ c
+          . /*cfe.notPromoted(propertyNotPromoted(target: member:C7.bad, type: int?))*/ bad);
+}
+
+class C8 {
+  int? bad;
+}
+
+userDefinableBinaryOpRhs(C8 c) {
+  if (c.bad == null) return;
+  1 +
+      /*analyzer.notPromoted(propertyNotPromoted(target: member:C8.bad, type: int?))*/ c
+          . /*cfe.notPromoted(propertyNotPromoted(target: member:C8.bad, type: int?))*/ bad;
+}
+
+class C9 {
+  int? bad;
+  f(int i) {}
+}
+
+questionQuestionRhs(C9 c, int? i) {
+  // Note: "why not supported" functionality is currently not supported for the
+  // RHS of `??` because it requires more clever reasoning than we currently do:
+  // we would have to understand that the reason `i ?? c.bad` has a type of
+  // `int?` rather than `int` is because `c.bad` was not promoted.  We currently
+  // only support detecting non-promotion when the expression that had the wrong
+  // type *is* the expression that wasn't promoted.
+  if (c.bad == null) return;
+  c.f(i ?? c.bad);
+}
+
+class C10 {
+  D10? bad;
+  f(bool b) {}
+}
+
+class D10 {
+  bool operator ==(covariant D10 other) => true;
+}
+
+equalRhs(C10 c, D10 d) {
+  if (c.bad == null) return;
+  // Note: we don't report an error here because `==` always accepts `null`.
+  c.f(d == c.bad);
+  c.f(d != c.bad);
+}
+
+class C11 {
+  bool? bad;
+  f(bool b) {}
+}
+
+andOperand(C11 c, bool b) {
+  if (c.bad == null) return;
+  c.f(
+      /*analyzer.notPromoted(propertyNotPromoted(target: member:C11.bad, type: bool?))*/ c
+              . /*cfe.notPromoted(propertyNotPromoted(target: member:C11.bad, type: bool?))*/ bad &&
+          b);
+  c.f(b &&
+      /*analyzer.notPromoted(propertyNotPromoted(target: member:C11.bad, type: bool?))*/ c
+          . /*cfe.notPromoted(propertyNotPromoted(target: member:C11.bad, type: bool?))*/ bad);
+}
+
+class C12 {
+  bool? bad;
+  f(bool b) {}
+}
+
+orOperand(C12 c, bool b) {
+  if (c.bad == null) return;
+  c.f(
+      /*analyzer.notPromoted(propertyNotPromoted(target: member:C12.bad, type: bool?))*/ c
+              . /*cfe.notPromoted(propertyNotPromoted(target: member:C12.bad, type: bool?))*/ bad ||
+          b);
+  c.f(b ||
+      /*analyzer.notPromoted(propertyNotPromoted(target: member:C12.bad, type: bool?))*/ c
+          . /*cfe.notPromoted(propertyNotPromoted(target: member:C12.bad, type: bool?))*/ bad);
+}
+
+class C13 {
+  bool? bad;
+}
+
+assertStatementCondition(C13 c) {
+  if (c.bad == null) return;
+  assert(
+      /*analyzer.notPromoted(propertyNotPromoted(target: member:C13.bad, type: bool?))*/ c
+          . /*cfe.notPromoted(propertyNotPromoted(target: member:C13.bad, type: bool?))*/ bad);
+}
+
+class C14 {
+  bool? bad;
+  C14.assertInitializerCondition(C14 c)
+      : bad = c.bad!,
+        assert(
+            /*analyzer.notPromoted(propertyNotPromoted(target: member:C14.bad, type: bool?))*/ c
+                . /*cfe.notPromoted(propertyNotPromoted(target: member:C14.bad, type: bool?))*/ bad);
+}
+
+class C15 {
+  bool? bad;
+  f(bool b) {}
+}
+
+notOperand(C15 c) {
+  if (c.bad == null) return;
+  c.f(!
+      /*analyzer.notPromoted(propertyNotPromoted(target: member:C15.bad, type: bool?))*/ c
+          . /*cfe.notPromoted(propertyNotPromoted(target: member:C15.bad, type: bool?))*/ bad);
+}
+
+class C16 {
+  bool? bad;
+  f(bool b) {}
+}
+
+forLoopCondition(C16 c) {
+  if (c.bad == null) return;
+  for (;
+      /*analyzer.notPromoted(propertyNotPromoted(target: member:C16.bad, type: bool?))*/ c
+          . /*cfe.notPromoted(propertyNotPromoted(target: member:C16.bad, type: bool?))*/ bad;) {}
+  [
+    for (;
+        /*analyzer.notPromoted(propertyNotPromoted(target: member:C16.bad, type: bool?))*/ c
+            . /*cfe.notPromoted(propertyNotPromoted(target: member:C16.bad, type: bool?))*/ bad;)
+      null
+  ];
+  ({
+    for (;
+        /*analyzer.notPromoted(propertyNotPromoted(target: member:C16.bad, type: bool?))*/ c
+            . /*cfe.notPromoted(propertyNotPromoted(target: member:C16.bad, type: bool?))*/ bad;)
+      null
+  });
+  ({
+    for (;
+        /*analyzer.notPromoted(propertyNotPromoted(target: member:C16.bad, type: bool?))*/ c
+            . /*cfe.notPromoted(propertyNotPromoted(target: member:C16.bad, type: bool?))*/ bad;)
+      null: null
+  });
+}
+
+class C17 {
+  bool? bad;
+  f(int i) {}
+}
+
+conditionalExpressionCondition(C17 c) {
+  if (c.bad == null) return;
+  c.f(
+      /*analyzer.notPromoted(propertyNotPromoted(target: member:C17.bad, type: bool?))*/ c
+              . /*cfe.notPromoted(propertyNotPromoted(target: member:C17.bad, type: bool?))*/ bad
+          ? 1
+          : 2);
+}
+
+class C18 {
+  bool? bad;
+}
+
+doLoopCondition(C18 c) {
+  if (c.bad == null) return;
+  do {} while (
+      /*analyzer.notPromoted(propertyNotPromoted(target: member:C18.bad, type: bool?))*/ c
+          . /*cfe.notPromoted(propertyNotPromoted(target: member:C18.bad, type: bool?))*/ bad);
+}
+
+class C19 {
+  bool? bad;
+}
+
+ifCondition(C19 c) {
+  if (c.bad == null) return;
+  if (
+      /*analyzer.notPromoted(propertyNotPromoted(target: member:C19.bad, type: bool?))*/ c
+          . /*cfe.notPromoted(propertyNotPromoted(target: member:C19.bad, type: bool?))*/ bad) {}
+  [
+    if (
+    /*analyzer.notPromoted(propertyNotPromoted(target: member:C19.bad, type: bool?))*/ c
+        . /*cfe.notPromoted(propertyNotPromoted(target: member:C19.bad, type: bool?))*/ bad)
+      null
+  ];
+  ({
+    if (
+    /*analyzer.notPromoted(propertyNotPromoted(target: member:C19.bad, type: bool?))*/ c
+        . /*cfe.notPromoted(propertyNotPromoted(target: member:C19.bad, type: bool?))*/ bad)
+      null
+  });
+  ({
+    if (
+    /*analyzer.notPromoted(propertyNotPromoted(target: member:C19.bad, type: bool?))*/ c
+        . /*cfe.notPromoted(propertyNotPromoted(target: member:C19.bad, type: bool?))*/ bad)
+      null: null
+  });
+}
+
+class C20 {
+  bool? bad;
+}
+
+whileCondition(C20 c) {
+  if (c.bad == null) return;
+  while (/*analyzer.notPromoted(propertyNotPromoted(target: member:C20.bad, type: bool?))*/ c
+      . /*cfe.notPromoted(propertyNotPromoted(target: member:C20.bad, type: bool?))*/ bad) {}
+}
+
+class C21 {
+  int? bad;
+}
+
+assignmentRhs(C21 c, int i) {
+  if (c.bad == null) return;
+  i =
+      /*analyzer.notPromoted(propertyNotPromoted(target: member:C21.bad, type: int?))*/ c
+          . /*cfe.notPromoted(propertyNotPromoted(target: member:C21.bad, type: int?))*/ bad;
+}
+
+class C22 {
+  int? bad;
+}
+
+variableInitializer(C22 c) {
+  if (c.bad == null) return;
+  int i =
+      /*analyzer.notPromoted(propertyNotPromoted(target: member:C22.bad, type: int?))*/ c
+          . /*cfe.notPromoted(propertyNotPromoted(target: member:C22.bad, type: int?))*/ bad;
+}
+
+class C23 {
+  int? bad;
+  final int x;
+  final int y;
+  C23.constructorInitializer(C23 c)
+      : x = c.bad!,
+        y =
+            /*analyzer.notPromoted(propertyNotPromoted(target: member:C23.bad, type: int?))*/ c
+                . /*cfe.notPromoted(propertyNotPromoted(target: member:C23.bad, type: int?))*/ bad;
+}
+
+class C24 {
+  int? bad;
+}
+
+forVariableInitializer(C24 c) {
+  if (c.bad == null) return;
+  for (int i =
+          /*analyzer.notPromoted(propertyNotPromoted(target: member:C24.bad, type: int?))*/ c
+              . /*cfe.notPromoted(propertyNotPromoted(target: member:C24.bad, type: int?))*/ bad;
+      false;) {}
+  [
+    for (int i =
+            /*analyzer.notPromoted(propertyNotPromoted(target: member:C24.bad, type: int?))*/ c
+                . /*cfe.notPromoted(propertyNotPromoted(target: member:C24.bad, type: int?))*/ bad;
+        false;)
+      null
+  ];
+  ({
+    for (int i =
+            /*analyzer.notPromoted(propertyNotPromoted(target: member:C24.bad, type: int?))*/ c
+                . /*cfe.notPromoted(propertyNotPromoted(target: member:C24.bad, type: int?))*/ bad;
+        false;)
+      null
+  });
+  ({
+    for (int i =
+            /*analyzer.notPromoted(propertyNotPromoted(target: member:C24.bad, type: int?))*/ c
+                . /*cfe.notPromoted(propertyNotPromoted(target: member:C24.bad, type: int?))*/ bad;
+        false;)
+      null: null
+  });
+}
+
+class C25 {
+  int? bad;
+}
+
+forAssignmentInitializer(C25 c, int i) {
+  if (c.bad == null) return;
+  for (i =
+          /*analyzer.notPromoted(propertyNotPromoted(target: member:C25.bad, type: int?))*/ c
+              . /*cfe.notPromoted(propertyNotPromoted(target: member:C25.bad, type: int?))*/ bad;
+      false;) {}
+  [
+    for (i =
+            /*analyzer.notPromoted(propertyNotPromoted(target: member:C25.bad, type: int?))*/ c
+                . /*cfe.notPromoted(propertyNotPromoted(target: member:C25.bad, type: int?))*/ bad;
+        false;)
+      null
+  ];
+  ({
+    for (i =
+            /*analyzer.notPromoted(propertyNotPromoted(target: member:C25.bad, type: int?))*/ c
+                . /*cfe.notPromoted(propertyNotPromoted(target: member:C25.bad, type: int?))*/ bad;
+        false;)
+      null
+  });
+  ({
+    for (i =
+            /*analyzer.notPromoted(propertyNotPromoted(target: member:C25.bad, type: int?))*/ c
+                . /*cfe.notPromoted(propertyNotPromoted(target: member:C25.bad, type: int?))*/ bad;
+        false;)
+      null: null
+  });
+}
+
+class C26 {
+  int? bad;
+}
+
+compoundAssignmentRhs(C26 c) {
+  num n = 0;
+  if (c.bad == null) return;
+  n +=
+      /*analyzer.notPromoted(propertyNotPromoted(target: member:C26.bad, type: int?))*/ c
+          . /*cfe.notPromoted(propertyNotPromoted(target: member:C26.bad, type: int?))*/ bad;
+}
+
+class C27 {
+  int? bad;
+}
+
+indexGet(C27 c, List<int> values) {
+  if (c.bad == null) return;
+  values[
+      /*analyzer.notPromoted(propertyNotPromoted(target: member:C27.bad, type: int?))*/ c
+          . /*cfe.notPromoted(propertyNotPromoted(target: member:C27.bad, type: int?))*/ bad];
+}
+
+class C28 {
+  int? bad;
+}
+
+indexSet(C28 c, List<int> values) {
+  if (c.bad == null) return;
+  values[
+      /*analyzer.notPromoted(propertyNotPromoted(target: member:C28.bad, type: int?))*/ c
+          . /*cfe.notPromoted(propertyNotPromoted(target: member:C28.bad, type: int?))*/ bad] = 0;
+}
+
+class C29 {
+  int? bad;
+}
+
+indexSetCompound(C29 c, List<int> values) {
+  // TODO(paulberry): get this to work with the CFE
+  if (c.bad == null) return;
+  values[
+      /*analyzer.notPromoted(propertyNotPromoted(target: member:C29.bad, type: int?))*/ c
+          .bad] += 1;
+}
+
+class C30 {
+  int? bad;
+}
+
+indexSetIfNull(C30 c, List<int?> values) {
+  // TODO(paulberry): get this to work with the CFE
+  if (c.bad == null) return;
+  values[
+      /*analyzer.notPromoted(propertyNotPromoted(target: member:C30.bad, type: int?))*/ c
+          .bad] ??= 1;
+}
+
+class C31 {
+  int? bad;
+}
+
+indexSetPreIncDec(C31 c, List<int> values) {
+  // TODO(paulberry): get this to work with the CFE
+  if (c.bad == null) return;
+  ++values[
+      /*analyzer.notPromoted(propertyNotPromoted(target: member:C31.bad, type: int?))*/ c
+          .bad];
+  --values[
+      /*analyzer.notPromoted(propertyNotPromoted(target: member:C31.bad, type: int?))*/ c
+          .bad];
+}
+
+class C32 {
+  int? bad;
+}
+
+indexSetPostIncDec(C32 c, List<int> values) {
+  // TODO(paulberry): get this to work with the CFE
+  if (c.bad == null) return;
+  values[
+      /*analyzer.notPromoted(propertyNotPromoted(target: member:C32.bad, type: int?))*/ c
+          .bad]++;
+  values[
+      /*analyzer.notPromoted(propertyNotPromoted(target: member:C32.bad, type: int?))*/ c
+          .bad]--;
+}
diff --git a/pkg/_fe_analyzer_shared/test/flow_analysis/why_not_promoted/data/extension_property.dart b/pkg/_fe_analyzer_shared/test/flow_analysis/why_not_promoted/data/extension_property.dart
index 1ac0a15..d1eedb3 100644
--- a/pkg/_fe_analyzer_shared/test/flow_analysis/why_not_promoted/data/extension_property.dart
+++ b/pkg/_fe_analyzer_shared/test/flow_analysis/why_not_promoted/data/extension_property.dart
@@ -41,11 +41,15 @@
 }
 
 get_property_via_prefixed_identifier_mismatched_target(C c1, C c2) {
+  // Note: no context on this error because the property the user is attempting
+  // to promote is on c1, but the property the user is accessing is on c2.
   if (c1.i == null) return;
   c2.i.isEven;
 }
 
 get_property_via_prefixed_identifier_mismatched_property(C c) {
+  // Note: no context on this error because the property the user is attempting
+  // to promote is C.i, but the property the user is accessing is C.j.
   if (c.i == null) return;
   c.j.isEven;
 }
diff --git a/pkg/_fe_analyzer_shared/test/flow_analysis/why_not_promoted/data/field.dart b/pkg/_fe_analyzer_shared/test/flow_analysis/why_not_promoted/data/field.dart
index bc0a5e7..c4c35cf 100644
--- a/pkg/_fe_analyzer_shared/test/flow_analysis/why_not_promoted/data/field.dart
+++ b/pkg/_fe_analyzer_shared/test/flow_analysis/why_not_promoted/data/field.dart
@@ -46,11 +46,15 @@
 }
 
 get_field_via_prefixed_identifier_mismatched_target(C c1, C c2) {
+  // Note: no context on this error because the property the user is attempting
+  // to promote is on c1, but the property the user is accessing is on c2.
   if (c1.i == null) return;
   c2.i.isEven;
 }
 
 get_field_via_prefixed_identifier_mismatched_property(C c) {
+  // Note: no context on this error because the property the user is attempting
+  // to promote is C.i, but the property the user is accessing is C.j.
   if (c.i == null) return;
   c.j.isEven;
 }
diff --git a/pkg/_fe_analyzer_shared/test/flow_analysis/why_not_promoted/data/for_in_loop_type_not_iterable_nullability_error.dart b/pkg/_fe_analyzer_shared/test/flow_analysis/why_not_promoted/data/for_in_loop_type_not_iterable_nullability_error.dart
index d43d616..5bbde08 100644
--- a/pkg/_fe_analyzer_shared/test/flow_analysis/why_not_promoted/data/for_in_loop_type_not_iterable_nullability_error.dart
+++ b/pkg/_fe_analyzer_shared/test/flow_analysis/why_not_promoted/data/for_in_loop_type_not_iterable_nullability_error.dart
@@ -7,16 +7,83 @@
 // `ForInLoopTypeNotIterablePartNullability` errors, for which we wish to report
 // "why not promoted" context information.
 
-// TODO(paulberry): get this to work with the CFE and add additional test cases
-// if needed.
-
 class C1 {
   List<int>? bad;
 }
 
-test(C1 c) {
+forStatement(C1 c) {
   if (c.bad == null) return;
   for (var x
       in /*analyzer.notPromoted(propertyNotPromoted(target: member:C1.bad, type: List<int>?))*/ c
-          .bad) {}
+          . /*cfe.notPromoted(propertyNotPromoted(target: member:C1.bad, type: List<int>?))*/ bad) {}
+}
+
+forElementInList(C1 c) {
+  if (c.bad == null) return;
+  [
+    for (var x
+        in /*analyzer.notPromoted(propertyNotPromoted(target: member:C1.bad, type: List<int>?))*/ c
+            . /*cfe.notPromoted(propertyNotPromoted(target: member:C1.bad, type: List<int>?))*/ bad)
+      null
+  ];
+}
+
+forElementInSet(C1 c) {
+  if (c.bad == null) return;
+  <dynamic>{
+    for (var x
+        in /*analyzer.notPromoted(propertyNotPromoted(target: member:C1.bad, type: List<int>?))*/ c
+            . /*cfe.notPromoted(propertyNotPromoted(target: member:C1.bad, type: List<int>?))*/ bad)
+      null
+  };
+}
+
+forElementInMap(C1 c) {
+  if (c.bad == null) return;
+  <dynamic, dynamic>{
+    for (var x
+        in /*analyzer.notPromoted(propertyNotPromoted(target: member:C1.bad, type: List<int>?))*/ c
+            . /*cfe.notPromoted(propertyNotPromoted(target: member:C1.bad, type: List<int>?))*/ bad)
+      null: null
+  };
+}
+
+forElementInAmbiguousSet_resolvableDuringParsing(C1 c) {
+  if (c.bad == null) return;
+  ({
+    for (var x
+        in /*analyzer.notPromoted(propertyNotPromoted(target: member:C1.bad, type: List<int>?))*/ c
+            . /*cfe.notPromoted(propertyNotPromoted(target: member:C1.bad, type: List<int>?))*/ bad)
+      null
+  });
+}
+
+forElementInAmbiguousMap_resolvableDuringParsing(C1 c) {
+  if (c.bad == null) return;
+  ({
+    for (var x
+        in /*analyzer.notPromoted(propertyNotPromoted(target: member:C1.bad, type: List<int>?))*/ c
+            . /*cfe.notPromoted(propertyNotPromoted(target: member:C1.bad, type: List<int>?))*/ bad)
+      null: null
+  });
+}
+
+forElementInAmbiguousSet_notResolvableDuringParsing(C1 c, List list) {
+  if (c.bad == null) return;
+  ({
+    for (var x
+        in /*analyzer.notPromoted(propertyNotPromoted(target: member:C1.bad, type: List<int>?))*/ c
+            . /*cfe.notPromoted(propertyNotPromoted(target: member:C1.bad, type: List<int>?))*/ bad)
+      ...list
+  });
+}
+
+forElementInAmbiguousMap_notResolvableDuringParsing(C1 c, Map map) {
+  if (c.bad == null) return;
+  ({
+    for (var x
+        in /*analyzer.notPromoted(propertyNotPromoted(target: member:C1.bad, type: List<int>?))*/ c
+            . /*cfe.notPromoted(propertyNotPromoted(target: member:C1.bad, type: List<int>?))*/ bad)
+      ...map
+  });
 }
diff --git a/pkg/_fe_analyzer_shared/test/flow_analysis/why_not_promoted/data/invalid_assignment_error_nullability_error.dart b/pkg/_fe_analyzer_shared/test/flow_analysis/why_not_promoted/data/invalid_assignment_error_nullability_error.dart
index a249136..a0f0388 100644
--- a/pkg/_fe_analyzer_shared/test/flow_analysis/why_not_promoted/data/invalid_assignment_error_nullability_error.dart
+++ b/pkg/_fe_analyzer_shared/test/flow_analysis/why_not_promoted/data/invalid_assignment_error_nullability_error.dart
@@ -7,9 +7,6 @@
 // `InvalidAssignmentErrorPartNullability` errors, for which we wish to report
 // "why not promoted" context information.
 
-// TODO(paulberry): get this to work with the CFE and add additional test cases
-// if needed.
-
 class C1 {
   List<int>? bad;
 }
@@ -17,5 +14,5 @@
 test(C1 c) sync* {
   if (c.bad == null) return;
   yield* /*analyzer.notPromoted(propertyNotPromoted(target: member:C1.bad, type: List<int>?))*/ c
-      .bad;
+      . /*cfe.notPromoted(propertyNotPromoted(target: member:C1.bad, type: List<int>?))*/ bad;
 }
diff --git a/pkg/_fe_analyzer_shared/test/flow_analysis/why_not_promoted/data/nullable_spread_error.dart b/pkg/_fe_analyzer_shared/test/flow_analysis/why_not_promoted/data/nullable_spread_error.dart
index 8398f56..6d05759 100644
--- a/pkg/_fe_analyzer_shared/test/flow_analysis/why_not_promoted/data/nullable_spread_error.dart
+++ b/pkg/_fe_analyzer_shared/test/flow_analysis/why_not_promoted/data/nullable_spread_error.dart
@@ -6,17 +6,146 @@
 // end's `NullableSpreadError` error, for which we wish to report "why not
 // promoted" context information.
 
-// TODO(paulberry): get this to work with the CFE and add additional test cases
-// if needed.
-
-class C1 {
-  List<int>? bad;
+class C {
+  List<int>? listQuestion;
+  Object? objectQuestion;
+  Set<int>? setQuestion;
+  Map<int, int>? mapQuestion;
 }
 
-test(C1 c) {
-  if (c.bad == null) return;
+list_from_list_question(C c) {
+  if (c.listQuestion == null) return;
   return [
-    ... /*analyzer.notPromoted(propertyNotPromoted(target: member:C1.bad, type: List<int>?))*/ c
-        .bad
+    ... /*analyzer.notPromoted(propertyNotPromoted(target: member:C.listQuestion, type: List<int>?))*/ c
+        . /*cfe.notPromoted(propertyNotPromoted(target: member:C.listQuestion, type: List<int>?))*/ listQuestion
   ];
 }
+
+list_from_set_question(C c) {
+  if (c.setQuestion == null) return;
+  return [
+    ... /*analyzer.notPromoted(propertyNotPromoted(target: member:C.setQuestion, type: Set<int>?))*/ c
+        . /*cfe.notPromoted(propertyNotPromoted(target: member:C.setQuestion, type: Set<int>?))*/ setQuestion
+  ];
+}
+
+list_from_map_question(C c) {
+  if (c.mapQuestion == null) return;
+  return [
+    ... /*analyzer.notPromoted(propertyNotPromoted(target: member:C.mapQuestion, type: Map<int, int>?))*/ c
+        . /*cfe.notPromoted(propertyNotPromoted(target: member:C.mapQuestion, type: Map<int, int>?))*/ mapQuestion
+  ];
+}
+
+list_from_object_question(C c) {
+  if (c.objectQuestion is! List<int>) return;
+  return [
+    ... /*analyzer.notPromoted(propertyNotPromoted(target: member:C.objectQuestion, type: Object?))*/ c
+        . /*cfe.notPromoted(propertyNotPromoted(target: member:C.objectQuestion, type: Object?))*/ objectQuestion
+  ];
+}
+
+set_from_list_question(C c) {
+  if (c.listQuestion == null) return;
+  return {
+    ... /*analyzer.notPromoted(propertyNotPromoted(target: member:C.listQuestion, type: List<int>?))*/ c
+        . /*cfe.notPromoted(propertyNotPromoted(target: member:C.listQuestion, type: List<int>?))*/ listQuestion
+  };
+}
+
+set_from_set_question(C c) {
+  if (c.setQuestion == null) return;
+  return {
+    ... /*analyzer.notPromoted(propertyNotPromoted(target: member:C.setQuestion, type: Set<int>?))*/ c
+        . /*cfe.notPromoted(propertyNotPromoted(target: member:C.setQuestion, type: Set<int>?))*/ setQuestion
+  };
+}
+
+set_from_map_question(C c) {
+  if (c.mapQuestion == null) return;
+  return {
+    ... /*analyzer.notPromoted(propertyNotPromoted(target: member:C.mapQuestion, type: Map<int, int>?))*/ c
+        . /*cfe.notPromoted(propertyNotPromoted(target: member:C.mapQuestion, type: Map<int, int>?))*/ mapQuestion
+  };
+}
+
+set_from_object_question_type_disambiguate_by_entry(C c) {
+  if (c.objectQuestion is! Set<int>) return;
+  return {
+    null,
+    ... /*analyzer.notPromoted(propertyNotPromoted(target: member:C.objectQuestion, type: Object?))*/ c
+        . /*cfe.notPromoted(propertyNotPromoted(target: member:C.objectQuestion, type: Object?))*/ objectQuestion
+  };
+}
+
+set_from_object_question_type_disambiguate_by_previous_spread(C c) {
+  if (c.objectQuestion is! Set<int>) return;
+  return {
+    ...<int>{},
+    ... /*analyzer.notPromoted(propertyNotPromoted(target: member:C.objectQuestion, type: Object?))*/ c
+        . /*cfe.notPromoted(propertyNotPromoted(target: member:C.objectQuestion, type: Object?))*/ objectQuestion
+  };
+}
+
+set_from_object_question_type_disambiguate_by_literal_args(C c) {
+  if (c.objectQuestion is! Set<int>) return;
+  return <int>{
+    ... /*analyzer.notPromoted(propertyNotPromoted(target: member:C.objectQuestion, type: Object?))*/ c
+        . /*cfe.notPromoted(propertyNotPromoted(target: member:C.objectQuestion, type: Object?))*/ objectQuestion
+  };
+}
+
+map_from_list_question(C c) {
+  if (c.listQuestion == null) return;
+  return {
+    ... /*analyzer.notPromoted(propertyNotPromoted(target: member:C.listQuestion, type: List<int>?))*/ c
+        . /*cfe.notPromoted(propertyNotPromoted(target: member:C.listQuestion, type: List<int>?))*/ listQuestion
+  };
+}
+
+map_from_set_question(C c) {
+  if (c.setQuestion == null) return;
+  return {
+    ... /*analyzer.notPromoted(propertyNotPromoted(target: member:C.setQuestion, type: Set<int>?))*/ c
+        . /*cfe.notPromoted(propertyNotPromoted(target: member:C.setQuestion, type: Set<int>?))*/ setQuestion
+  };
+}
+
+map_from_map_question(C c) {
+  if (c.mapQuestion == null) return;
+  return {
+    ... /*analyzer.notPromoted(propertyNotPromoted(target: member:C.mapQuestion, type: Map<int, int>?))*/ c
+        . /*cfe.notPromoted(propertyNotPromoted(target: member:C.mapQuestion, type: Map<int, int>?))*/ mapQuestion
+  };
+}
+
+map_from_object_question_type_disambiguate_by_key_value_pair(C c) {
+  if (c.objectQuestion is! Map<int, int>) return;
+  return {
+    null: null,
+    ... /*analyzer.notPromoted(propertyNotPromoted(target: member:C.objectQuestion, type: Object?))*/ c
+        . /*cfe.notPromoted(propertyNotPromoted(target: member:C.objectQuestion, type: Object?))*/ objectQuestion
+  };
+}
+
+map_from_object_question_type_disambiguate_by_previous_spread(C c) {
+  if (c.objectQuestion is! Map<int, int>) return;
+  return {
+    ...<int, int>{},
+    ... /*analyzer.notPromoted(propertyNotPromoted(target: member:C.objectQuestion, type: Object?))*/ c
+        . /*cfe.notPromoted(propertyNotPromoted(target: member:C.objectQuestion, type: Object?))*/ objectQuestion
+  };
+}
+
+map_from_set_question_type_disambiguate_by_literal_args(C c) {
+  // Note: analyzer shows "why not promoted" information here, but CFE doesn't.
+  // That's probably ok, since there are two problems here (set/map mismatch and
+  // null safety); it's a matter of interpretation whether to prioritize one or
+  // the other.
+  if (c.setQuestion == null) return;
+  return <int, int>{
+    ...
+    /*analyzer.notPromoted(propertyNotPromoted(target: member:C.setQuestion, type: Set<int>?))*/ c
+        .setQuestion
+  };
+}
diff --git a/pkg/_fe_analyzer_shared/test/flow_analysis/why_not_promoted/data/property.dart b/pkg/_fe_analyzer_shared/test/flow_analysis/why_not_promoted/data/property.dart
index 90fe382..1ba3291 100644
--- a/pkg/_fe_analyzer_shared/test/flow_analysis/why_not_promoted/data/property.dart
+++ b/pkg/_fe_analyzer_shared/test/flow_analysis/why_not_promoted/data/property.dart
@@ -46,11 +46,15 @@
 }
 
 get_property_via_prefixed_identifier_mismatched_target(C c1, C c2) {
+  // Note: no context on this error because the property the user is attempting
+  // to promote is on c1, but the property the user is accessing is on c2.
   if (c1.i == null) return;
   c2.i.isEven;
 }
 
 get_property_via_prefixed_identifier_mismatched_property(C c) {
+  // Note: no context on this error because the property the user is attempting
+  // to promote is C.i, but the property the user is accessing is C.j.
   if (c.i == null) return;
   c.j.isEven;
 }
diff --git a/pkg/_fe_analyzer_shared/test/mini_ast.dart b/pkg/_fe_analyzer_shared/test/mini_ast.dart
new file mode 100644
index 0000000..5e41049
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/test/mini_ast.dart
@@ -0,0 +1,1905 @@
+// 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:test/test.dart';
+
+import 'mini_types.dart';
+
+Expression get nullLiteral => new _NullLiteral();
+
+Expression get this_ => new _This();
+
+Statement assert_(Expression condition, [Expression? message]) =>
+    new _Assert(condition, message);
+
+Statement block(List<Statement> statements) => new _Block(statements);
+
+Expression booleanLiteral(bool value) => _BooleanLiteral(value);
+
+Statement break_([LabeledStatement? target]) => new _Break(target);
+
+SwitchCase case_(List<Statement> body, {bool hasLabel = false}) =>
+    SwitchCase._(hasLabel, new _Block(body));
+
+/// 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_() => new _Continue();
+
+Statement declare(Var variable,
+        {required bool initialized,
+        bool isFinal = false,
+        bool isLate = false}) =>
+    new _Declare(variable, initialized ? expr(variable.type.type) : null,
+        isFinal, isLate);
+
+Statement declareInitialized(Var variable, Expression initializer,
+        {bool isFinal = false, bool isLate = false}) =>
+    new _Declare(variable, initializer, isFinal, isLate);
+
+Statement do_(List<Statement> body, Expression condition) =>
+    _Do(block(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, block(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, block(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) {
+  // ignore: unnecessary_null_comparison
+  assert(variable != null);
+  return new _ForEach(variable, iterable, block(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) {
+  // ignore: unnecessary_null_comparison
+  assert(variable != null);
+  return new _ForEach(variable, iterable, block(body), false);
+}
+
+/// Creates a [Statement] that, when analyzed, will cause [callback] to be
+/// passed an [SsaNodeHarness] allowing the test to examine the values of
+/// variables' SSA nodes.
+Statement getSsaNodes(void Function(SsaNodeHarness) callback) =>
+    new _GetSsaNodes(callback);
+
+Statement if_(Expression condition, List<Statement> ifTrue,
+        [List<Statement>? ifFalse]) =>
+    new _If(condition, block(ifTrue), ifFalse == null ? null : block(ifFalse));
+
+Statement implicitThis_whyNotPromoted(String staticType,
+        void Function(Map<Type, NonPromotionReason>) callback) =>
+    new _WhyNotPromoted_ImplicitThis(Type(staticType), callback);
+
+Statement labeled(Statement Function(LabeledStatement) callback) {
+  var labeledStatement = LabeledStatement._();
+  labeledStatement._body = callback(labeledStatement);
+  return labeledStatement;
+}
+
+Statement localFunction(List<Statement> body) => _LocalFunction(block(body));
+
+Statement return_() => new _Return();
+
+Statement switch_(Expression expression, List<SwitchCase> cases,
+        {required bool isExhaustive}) =>
+    new _Switch(expression, cases, isExhaustive);
+
+Expression thisOrSuperPropertyGet(String name, {String type = 'Object?'}) =>
+    new _ThisOrSuperPropertyGet(name, Type(type));
+
+Expression throw_(Expression operand) => new _Throw(operand);
+
+TryBuilder try_(List<Statement> body) =>
+    new _TryStatement(block(body), [], null);
+
+Statement while_(Expression condition, List<Statement> body) =>
+    new _While(condition, block(body));
+
+/// 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 extends Node implements _Visitable<Type> {
+  Expression() : super._();
+
+  /// 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 not => new _Not(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);
+
+  /// Creates an [Expression] that, when analyzed, will behave the same as
+  /// `this`, but after visiting it, will cause [callback] to be passed the
+  /// [ExpressionInfo] associated with it.  If the expression has no flow
+  /// analysis information associated with it, `null` will be passed to
+  /// [callback].
+  Expression getExpressionInfo(
+          void Function(ExpressionInfo<Var, Type>?) callback) =>
+      new _GetExpressionInfo(this, callback);
+
+  /// 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 the L-value `x.name`.
+  LValue property(String name) => new _Property(this, name);
+
+  /// 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);
+
+  /// Creates an [Expression] that, when analyzed, will behave the same as
+  /// `this`, but after visiting it, will cause [callback] to be passed the
+  /// non-promotion info associated with it.  If the expression has no
+  /// non-promotion info, an empty map will be passed to [callback].
+  Expression whyNotPromoted(
+          void Function(Map<Type, NonPromotionReason>) callback) =>
+      new _WhyNotPromoted(this, callback);
+}
+
+/// 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 {
+    'bool <: int': false,
+    'bool <: Object': true,
+    '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,
+    'Never <: Object?': true,
+    'Null <: int': false,
+    'Null <: Object': false,
+    'Null <: Object?': true,
+    '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 <: Null': false,
+    'Object <: num': false,
+    'Object <: num?': false,
+    'Object <: Object?': true,
+    'Object <: String': false,
+    'Object? <: Object': false,
+    'Object? <: int': false,
+    'Object? <: int?': false,
+    'Object? <: Null': false,
+    'String <: int': false,
+    'String <: int?': false,
+    'String <: num?': false,
+    'String <: Object': true,
+    'String <: Object?': true,
+  };
+
+  static final Map<String, Type> _coreFactors = {
+    'Object? - int': Type('Object?'),
+    'Object? - int?': Type('Object'),
+    'Object? - Never': Type('Object?'),
+    'Object? - Null': Type('Object'),
+    'Object? - num?': Type('Object'),
+    'Object? - Object?': Type('Never?'),
+    'Object? - String': Type('Object?'),
+    'Object - bool': Type('Object'),
+    'Object - int': Type('Object'),
+    'Object - String': 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 bool legacy;
+
+  final Type? thisType;
+
+  final Map<String, bool> _subtypes = Map.of(_coreSubtypes);
+
+  final Map<String, Type> _factorResults = Map.of(_coreFactors);
+
+  final Map<String, Type> _members = {};
+
+  Node? _currentSwitch;
+
+  Map<String, Map<String, String>> _promotionExceptions = {};
+
+  Statement? _currentBreakTarget;
+
+  Statement? _currentContinueTarget;
+
+  Harness({this.legacy = false, String? thisType})
+      : thisType = thisType == null ? null : Type(thisType);
+
+  /// Updates the harness so that when a [factor] query is invoked on types
+  /// [from] and [what], [result] will be returned.
+  void addFactor(String from, String what, String result) {
+    var query = '$from - $what';
+    _factorResults[query] = Type(result);
+  }
+
+  /// Updates the harness so that when member [memberName] is looked up on type
+  /// [targetType], a member is found having the given [type].
+  void addMember(String targetType, String memberName, String type) {
+    var query = '$targetType.$memberName';
+    _members[query] = Type(type);
+  }
+
+  void addPromotionException(String from, String to, String result) {
+    (_promotionExceptions[from] ??= {})[to] = result;
+  }
+
+  /// Updates the harness so that when an [isSubtypeOf] query is invoked on
+  /// types [leftType] and [rightType], [isSubtype] will be returned.
+  void addSubtype(String leftType, String 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');
+  }
+
+  /// Attempts to look up a member named [memberName] in the given [type].  If
+  /// a member is found, returns its type.  Otherwise the test fails.
+  Type getMember(Type type, String memberName) {
+    var query = '$type.$memberName';
+    return _members[query] ?? fail('Unknown member 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>();
+    var b = block(statements);
+    b._preVisit(assignedVariables);
+    var flow = legacy
+        ? FlowAnalysis<Node, Statement, Expression, Var, Type>.legacy(
+            this, assignedVariables)
+        : FlowAnalysis<Node, Statement, Expression, Var, Type>(
+            this, assignedVariables);
+    b._visit(this, flow);
+    flow.finish();
+  }
+
+  @override
+  Type? tryPromoteToType(Type to, Type from) {
+    var exception = (_promotionExceptions[from.type] ?? {})[to.type];
+    if (exception != null) {
+      return Type(exception);
+    }
+    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 if (type1.type == 'Never') {
+      return type2;
+    } else if (type2.type == 'Never') {
+      return type1;
+    } else {
+      throw UnimplementedError(
+          'TODO(paulberry): least upper bound of $type1 and $type2');
+    }
+  }
+
+  void _visitLoopBody(Statement loop, Statement body,
+      FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    var previousBreakTarget = _currentBreakTarget;
+    var previousContinueTarget = _currentContinueTarget;
+    _currentBreakTarget = loop;
+    _currentContinueTarget = loop;
+    body._visit(this, flow);
+    _currentBreakTarget = previousBreakTarget;
+    _currentContinueTarget = previousContinueTarget;
+  }
+}
+
+class LabeledStatement extends Statement {
+  late final Statement _body;
+
+  LabeledStatement._() : 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();
+  }
+}
+
+/// Representation of an expression that can appear on the left hand side of an
+/// assignment (or as the target of `++` or `--`).  Methods in this class may be
+/// used to create more complex expressions based on this one.
+abstract class LValue extends Expression {
+  LValue._();
+
+  /// Creates an expression representing a write to this L-value.
+  Expression write(Expression? value) => new _Write(this, value);
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables,
+      {_LValueDisposition disposition});
+
+  void _visitWrite(FlowAnalysis<Node, Statement, Expression, Var, Type> flow,
+      Expression assignmentExpression, Type writtenType, Expression? rhs);
+}
+
+/// Representation of an expression or statement in the pseudo-Dart language
+/// used for flow analysis testing.
+class Node {
+  static int _nextId = 0;
+
+  final int id;
+
+  Node._() : id = _nextId++;
+
+  String toString() => 'Node#$id';
+}
+
+/// Helper class allowing tests to examine the values of variables' SSA nodes.
+class SsaNodeHarness {
+  final FlowAnalysis<Node, Statement, Expression, Var, Type> _flow;
+
+  SsaNodeHarness(this._flow);
+
+  /// Gets the SSA node associated with [variable] at the current point in
+  /// control flow, or `null` if the variable has been write captured.
+  SsaNode<Var, Type>? operator [](Var variable) =>
+      _flow.ssaNodeForTesting(variable);
+}
+
+/// 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 _Block _body;
+
+  SwitchCase._(this._hasLabel, this._body);
+
+  String toString() => [
+        if (_hasLabel) '<label>:',
+        'case <value>:',
+        ..._body.statements
+      ].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);
+  }
+}
+
+abstract class TryBuilder {
+  TryStatement catch_(
+      {Var? exception, Var? stackTrace, required List<Statement> body});
+
+  Statement finally_(List<Statement> statements);
+}
+
+abstract class TryStatement extends Statement implements TryBuilder {
+  TryStatement._() : super._();
+}
+
+/// 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 L-value representing a reference to this variable.
+  LValue get expr => new _VariableReference(this, null);
+
+  /// Creates an expression representing a read of this variable, which as a
+  /// side effect will call the given callback with the returned promoted type.
+  Expression readAndCheckPromotedType(void Function(Type?) callback) =>
+      new _VariableReference(this, callback);
+
+  @override
+  String toString() => '$type $name';
+
+  /// Creates an expression representing a write to this variable.
+  Expression write(Expression? value) => expr.write(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) {
+    for (var statement in statements) {
+      statement._preVisit(assignedVariables);
+    }
+  }
+
+  @override
+  void _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    for (var statement in statements) {
+      statement._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 LabeledStatement? target;
+
+  _Break(this.target) : super._();
+
+  @override
+  String toString() => 'break;';
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {}
+
+  @override
+  void _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    flow.handleBreak(target ?? h._currentBreakTarget!);
+  }
+}
+
+/// 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 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 $_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();
+  }
+}
+
+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;
+  final StackTrace _creationTrace = StackTrace.current;
+
+  _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);
+    expect(promotedType?.type, expectedTypeStr, reason: '$_creationTrace');
+  }
+}
+
+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);
+    assignedVariables.beginNode();
+    ifTrue._preVisit(assignedVariables);
+    assignedVariables.endNode(this);
+    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), this);
+    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 {
+  _Continue() : super._();
+
+  @override
+  String toString() => 'continue;';
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {}
+
+  @override
+  void _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    flow.handleContinue(h._currentContinueTarget!);
+  }
+}
+
+class _Declare extends Statement {
+  final Var variable;
+  final Expression? initializer;
+  final bool isFinal;
+  final bool isLate;
+
+  _Declare(this.variable, this.initializer, this.isFinal, this.isLate)
+      : super._();
+
+  @override
+  String toString() {
+    var latePart = isLate ? 'late ' : '';
+    var finalPart = isFinal ? 'final ' : '';
+    var initializerPart = initializer != null ? ' = $initializer' : '';
+    return '$latePart$finalPart$variable${initializerPart};';
+  }
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+    initializer?._preVisit(assignedVariables);
+  }
+
+  @override
+  void _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    var initializer = this.initializer;
+    if (initializer == null) {
+      flow.declare(variable, false);
+    } else {
+      var initializerType = initializer._visit(h, flow);
+      flow.declare(variable, true);
+      flow.initialize(variable, initializerType, initializer,
+          isFinal: isFinal, isLate: isLate);
+    }
+  }
+}
+
+class _Do extends Statement {
+  final Statement body;
+  final Expression condition;
+
+  _Do(this.body, this.condition) : super._();
+
+  @override
+  String toString() => 'do $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);
+    h._visitLoopBody(this, body, 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 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(') $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);
+    h._visitLoopBody(this, body, flow);
+    flow.for_updaterBegin();
+    updater?._visit(h, flow);
+    flow.for_end();
+  }
+}
+
+class _ForEach extends Statement {
+  final Var? variable;
+  final Expression iterable;
+  final 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) $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);
+    var variable = this.variable;
+    if (variable != null && !declaresVariable) {
+      flow.write(this, variable, iteratedType, null);
+    }
+    h._visitLoopBody(this, body, flow);
+    flow.forEach_end();
+  }
+}
+
+class _GetExpressionInfo extends Expression {
+  final Expression target;
+
+  final void Function(ExpressionInfo<Var, Type>?) callback;
+
+  _GetExpressionInfo(this.target, this.callback);
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+    target._preVisit(assignedVariables);
+  }
+
+  @override
+  Type _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    var type = target._visit(h, flow);
+    flow.forwardExpression(this, target);
+    callback(flow.expressionInfoForTesting(this));
+    return type;
+  }
+}
+
+class _GetSsaNodes extends Statement {
+  final void Function(SsaNodeHarness) callback;
+
+  _GetSsaNodes(this.callback) : super._();
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {}
+
+  @override
+  void _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    callback(SsaNodeHarness(flow));
+  }
+}
+
+class _If extends Statement {
+  final Expression condition;
+  final Statement ifTrue;
+  final Statement? ifFalse;
+
+  _If(this.condition, this.ifTrue, this.ifFalse) : super._();
+
+  @override
+  String toString() =>
+      'if ($condition) $ifTrue' + (ifFalse == null ? '' : 'else $ifFalse');
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+    condition._preVisit(assignedVariables);
+    assignedVariables.beginNode();
+    ifTrue._preVisit(assignedVariables);
+    assignedVariables.endNode(this);
+    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), this);
+    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 _LocalFunction extends Statement {
+  final Statement body;
+
+  _LocalFunction(this.body) : super._();
+
+  @override
+  String toString() => '() $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);
+    assignedVariables.beginNode();
+    rhs._preVisit(assignedVariables);
+    assignedVariables.endNode(this);
+  }
+
+  @override
+  Type _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    flow.logicalBinaryOp_begin();
+    flow.logicalBinaryOp_rightBegin(lhs.._visit(h, flow), this, isAnd: isAnd);
+    flow.logicalBinaryOp_end(this, rhs.._visit(h, flow), isAnd: isAnd);
+    return Type('bool');
+  }
+}
+
+/// Enum representing the different ways an [LValue] might be used.
+enum _LValueDisposition {
+  /// The [LValue] is being read from only, not written to.  This happens if it
+  /// appears in a place where an ordinary expression is expected.
+  read,
+
+  /// The [LValue] is being written to only, not read from.  This happens if it
+  /// appears on the left hand side of `=`.
+  write,
+
+  /// The [LValue] is being both read from and written to.  This happens if it
+  /// appears on the left and side of `op=` (where `op` is some operator), or as
+  /// the target of `++` or `--`.
+  readWrite,
+}
+
+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 _Not extends Expression {
+  final Expression operand;
+
+  _Not(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) {
+    flow.logicalNot_end(this, operand.._visit(h, flow));
+    return Type('bool');
+  }
+}
+
+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 {
+  _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 _Property extends LValue {
+  final Expression target;
+
+  final String propertyName;
+
+  _Property(this.target, this.propertyName) : super._();
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables,
+      {_LValueDisposition disposition = _LValueDisposition.read}) {
+    target._preVisit(assignedVariables);
+  }
+
+  @override
+  Type _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    var targetType = target._visit(h, flow);
+    var propertyType = h.getMember(targetType, propertyName);
+    flow.propertyGet(this, target, propertyName, propertyType);
+    return propertyType;
+  }
+
+  @override
+  void _visitWrite(FlowAnalysis<Node, Statement, Expression, Var, Type> flow,
+      Expression assignmentExpression, Type writtenType, Expression? rhs) {
+    // No flow analysis impact
+  }
+}
+
+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();
+    for (var case_ in cases) {
+      case_._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;
+    var previousBreakTarget = h._currentBreakTarget;
+    h._currentSwitch = this;
+    h._currentBreakTarget = this;
+    for (var case_ in cases) {
+      case_._visit(h, flow);
+    }
+    h._currentSwitch = oldSwitch;
+    h._currentBreakTarget = previousBreakTarget;
+    flow.switchStatement_end(isExhaustive);
+  }
+}
+
+class _This extends Expression {
+  @override
+  String toString() => 'this';
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {}
+
+  @override
+  Type _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    var thisType = h.thisType!;
+    flow.thisOrSuper(this, thisType);
+    return thisType;
+  }
+}
+
+class _ThisOrSuperPropertyGet extends Expression {
+  final String propertyName;
+
+  final Type type;
+
+  _ThisOrSuperPropertyGet(this.propertyName, this.type);
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {}
+
+  @override
+  Type _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    flow.thisOrSuperPropertyGet(this, propertyName, type);
+    return type;
+  }
+}
+
+class _Throw extends Expression {
+  final Expression operand;
+
+  _Throw(this.operand);
+
+  @override
+  String toString() => 'throw ...';
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+    operand._preVisit(assignedVariables);
+  }
+
+  @override
+  Type _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    operand._visit(h, flow);
+    flow.handleExit();
+    return Type('Never');
+  }
+}
+
+class _TryStatement extends TryStatement {
+  final Statement _body;
+  final List<_CatchClause> _catches;
+  final Statement? _finally;
+  final _bodyNode = Node._();
+
+  _TryStatement(this._body, this._catches, this._finally) : super._();
+
+  @override
+  TryStatement catch_(
+      {Var? exception, Var? stackTrace, required List<Statement> body}) {
+    assert(_finally == null, 'catch after finally');
+    return _TryStatement(_body,
+        [..._catches, _CatchClause(block(body), exception, stackTrace)], null);
+  }
+
+  @override
+  Statement finally_(List<Statement> statements) {
+    assert(_finally == null, 'multiple finally clauses');
+    return _TryStatement(_body, _catches, block(statements));
+  }
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+    if (_finally != null) {
+      assignedVariables.beginNode();
+    }
+    if (_catches.isNotEmpty) {
+      assignedVariables.beginNode();
+    }
+    _body._preVisit(assignedVariables);
+    assignedVariables.endNode(_bodyNode);
+    for (var catch_ in _catches) {
+      catch_._preVisit(assignedVariables);
+    }
+    if (_finally != null) {
+      if (_catches.isNotEmpty) {
+        assignedVariables.endNode(this);
+      }
+      _finally!._preVisit(assignedVariables);
+    }
+  }
+
+  @override
+  void _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    if (_finally != null) {
+      flow.tryFinallyStatement_bodyBegin();
+    }
+    if (_catches.isNotEmpty) {
+      flow.tryCatchStatement_bodyBegin();
+    }
+    _body._visit(h, flow);
+    if (_catches.isNotEmpty) {
+      flow.tryCatchStatement_bodyEnd(_bodyNode);
+      for (var catch_ in _catches) {
+        catch_._visit(h, flow);
+      }
+      flow.tryCatchStatement_end();
+    }
+    if (_finally != null) {
+      flow.tryFinallyStatement_finallyBegin(
+          _catches.isNotEmpty ? this : _bodyNode);
+      _finally!._visit(h, flow);
+      flow.tryFinallyStatement_end();
+    }
+  }
+}
+
+class _VariableReference extends LValue {
+  final Var variable;
+
+  final void Function(Type?)? callback;
+
+  _VariableReference(this.variable, this.callback) : super._();
+
+  @override
+  String toString() => variable.name;
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables,
+      {_LValueDisposition disposition = _LValueDisposition.read}) {
+    if (disposition != _LValueDisposition.write) {
+      assignedVariables.read(variable);
+    }
+    if (disposition != _LValueDisposition.read) {
+      assignedVariables.write(variable);
+    }
+  }
+
+  @override
+  Type _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    var readResult = flow.variableRead(this, variable);
+    callback?.call(readResult);
+    return readResult ?? variable.type;
+  }
+
+  @override
+  void _visitWrite(FlowAnalysis<Node, Statement, Expression, Var, Type> flow,
+      Expression assignmentExpression, Type writtenType, Expression? rhs) {
+    flow.write(assignmentExpression, variable, writtenType, rhs);
+  }
+}
+
+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 Statement body;
+
+  _While(this.condition, this.body) : super._();
+
+  @override
+  String toString() => 'while ($condition) $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);
+    h._visitLoopBody(this, body, flow);
+    flow.whileStatement_end();
+  }
+}
+
+class _WhyNotPromoted extends Expression {
+  final Expression target;
+
+  final void Function(Map<Type, NonPromotionReason>) callback;
+
+  _WhyNotPromoted(this.target, this.callback);
+
+  @override
+  String toString() => '$target (whyNotPromoted)';
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+    target._preVisit(assignedVariables);
+  }
+
+  @override
+  Type _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    var type = target._visit(h, flow);
+    flow.forwardExpression(this, target);
+    Type.withComparisonsAllowed(() {
+      callback(flow.whyNotPromoted(this)());
+    });
+    return type;
+  }
+}
+
+class _WhyNotPromoted_ImplicitThis extends Statement {
+  final Type staticType;
+
+  final void Function(Map<Type, NonPromotionReason>) callback;
+
+  _WhyNotPromoted_ImplicitThis(this.staticType, this.callback) : super._();
+
+  @override
+  String toString() => 'implicit this (whyNotPromoted)';
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {}
+
+  @override
+  void _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    Type.withComparisonsAllowed(() {
+      callback(flow.whyNotPromotedImplicitThis(staticType)());
+    });
+  }
+}
+
+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 LValue lhs;
+  final Expression? rhs;
+
+  _Write(this.lhs, this.rhs);
+
+  @override
+  String toString() => '$lhs = $rhs';
+
+  @override
+  void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+    lhs._preVisit(assignedVariables,
+        disposition: rhs == null
+            ? _LValueDisposition.readWrite
+            : _LValueDisposition.write);
+    rhs?._preVisit(assignedVariables);
+  }
+
+  @override
+  Type _visit(
+      Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+    var rhs = this.rhs;
+    Type type;
+    if (rhs == null) {
+      // We are simulating an increment/decrement operation.
+      // TODO(paulberry): Make a separate node type for this.
+      type = lhs._visit(h, flow);
+    } else {
+      type = rhs._visit(h, flow);
+    }
+    lhs._visitWrite(flow, this, type, rhs);
+    return type;
+  }
+}
diff --git a/pkg/_fe_analyzer_shared/test/mini_types.dart b/pkg/_fe_analyzer_shared/test/mini_types.dart
new file mode 100644
index 0000000..12546f0
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/test/mini_types.dart
@@ -0,0 +1,295 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for 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 a "mini type system" that's similar to full Dart types,
+// but light weight enough to be suitable for unit testing of code in the
+// `_fe_analyzer_shared` package.
+
+import 'package:test/test.dart';
+
+/// Representation of a function type suitable for unit testing of code in the
+/// `_fe_analyzer_shared` package.
+///
+/// Optional and named parameters are not (yet) supported.
+class FunctionType extends Type {
+  /// The return type.
+  final Type returnType;
+
+  /// A list of the types of positional parameters.
+  final List<Type> positionalParameters;
+
+  FunctionType(this.returnType, this.positionalParameters) : super._();
+
+  @override
+  String get type => '$returnType Function(${positionalParameters.join(', ')})';
+}
+
+/// Representation of a "simple" type suitable for unit testing of code in the
+/// `_fe_analyzer_shared` package.  A "simple" type is either an interface type
+/// with zero or more type parameters (e.g. `double`, or `Map<int, String>`), a
+/// reference to a type parameter, or one of the special types whose name is a
+/// single word (e.g. `dynamic`).
+class NonFunctionType extends Type {
+  /// The name of the type.
+  final String name;
+
+  /// The type arguments, or `const []` if there are no type arguments.
+  final List<Type> args;
+
+  NonFunctionType(this.name, {this.args = const []}) : super._();
+
+  @override
+  String get type {
+    if (args.isEmpty) {
+      return name;
+    } else {
+      return '$name<${args.join(', ')}>';
+    }
+  }
+}
+
+/// Representation of a promoted type parameter type suitable for unit testing
+/// of code in the `_fe_analyzer_shared` package.  A promoted type parameter is
+/// often written using the syntax `a&b`, where `a` is the type parameter and
+/// `b` is what it's promoted to.  For example, `T&int` represents the type
+/// parameter `T`, promoted to `int`.
+class PromotedTypeVariableType extends Type {
+  final Type innerType;
+
+  final Type promotion;
+
+  PromotedTypeVariableType(this.innerType, this.promotion) : super._();
+
+  @override
+  String get type => '$innerType&$promotion';
+}
+
+/// Representation of a nullable type suitable for unit testing of code in the
+/// `_fe_analyzer_shared` package.  This class is used only for nullable types
+/// that are spelled with an explicit trailing `?`, e.g. `double?`; it is not
+/// used for e.g. `dynamic` or `FutureOr<int?>`, even though those types are
+/// nullable as well.
+class QuestionType extends Type {
+  final Type innerType;
+
+  QuestionType(this.innerType) : super._();
+
+  @override
+  String get type => '$innerType?';
+}
+
+/// Representation of a "star" type suitable for unit testing of code in the
+/// `_fe_analyzer_shared` package.
+class StarType extends Type {
+  final Type innerType;
+
+  StarType(this.innerType) : super._();
+
+  @override
+  String get type => '$innerType*';
+}
+
+/// Representation of a type suitable for unit testing of code in the
+/// `_fe_analyzer_shared` package.
+///
+/// Note that we don't want code in `_fe_analyzer_shared` to inadvertently
+/// compare types using `==` (or to store types in sets/maps, which can trigger
+/// `==` to be used to compare them); this could cause bugs by causing
+/// alternative spellings of the same type to be treated differently (e.g.
+/// `FutureOr<int?>?` should be treated equivalently to `FutureOr<int?>`).  To
+/// help ensure this, both `==` and `hashCode` throw exceptions by default.  To
+/// defeat this behavior (e.g. so that a type can be passed to `expect`, use
+/// [Type.withComparisonsAllowed].
+abstract class Type {
+  static bool _allowComparisons = false;
+
+  factory Type(String typeStr) => _TypeParser.parse(typeStr);
+
+  const Type._();
+
+  @override
+  int get hashCode {
+    if (!_allowComparisons) {
+      // Types should not be compared using hashCode.  They should be compared
+      // using relations like subtyping and assignability.
+      fail('Unexpected use of operator== on types');
+    }
+    return type.hashCode;
+  }
+
+  String get type;
+
+  @override
+  bool operator ==(Object other) {
+    if (!_allowComparisons) {
+      // Types should not be compared using hashCode.  They should be compared
+      // using relations like subtyping and assignability.
+      fail('Unexpected use of operator== on types');
+    }
+    return other is Type && this.type == other.type;
+  }
+
+  @override
+  String toString() => type;
+
+  /// Executes [callback] while temporarily allowing types to be compared using
+  /// `==` and `hashCode`.
+  static T withComparisonsAllowed<T>(T Function() callback) {
+    assert(!_allowComparisons);
+    _allowComparisons = true;
+    try {
+      return callback();
+    } finally {
+      Type._allowComparisons = false;
+    }
+  }
+}
+
+/// Representation of the unknown type suitable for unit testing of code in the
+/// `_fe_analyzer_shared` package.
+class UnknownType extends Type {
+  const UnknownType() : super._();
+
+  @override
+  String get type => '?';
+}
+
+class _TypeParser {
+  static final _typeTokenizationRegexp =
+      RegExp(_identifierPattern + r'|\(|\)|<|>|,|\?|\*|&');
+
+  static const _identifierPattern = '[_a-zA-Z][_a-zA-Z0-9]*';
+
+  static final _identifierRegexp = RegExp(_identifierPattern);
+
+  final String _typeStr;
+
+  final List<String> _tokens;
+
+  int _i = 0;
+
+  _TypeParser._(this._typeStr, this._tokens);
+
+  String get _currentToken => _tokens[_i];
+
+  void _next() {
+    _i++;
+  }
+
+  Never _parseFailure(String message) {
+    fail('Error parsing type `$_typeStr` at token $_currentToken: $message');
+  }
+
+  Type _parseNullability(Type innerType) {
+    if (_currentToken == '?') {
+      _next();
+      return QuestionType(innerType);
+    } else if (_currentToken == '*') {
+      _next();
+      return StarType(innerType);
+    } else {
+      return innerType;
+    }
+  }
+
+  Type? _parseSuffix(Type type) {
+    if (_currentToken == '&') {
+      _next();
+      var promotion = _parseType();
+      return PromotedTypeVariableType(type, promotion);
+    } else if (_currentToken == 'Function') {
+      _next();
+      if (_currentToken != '(') {
+        _parseFailure('Expected `(`');
+      }
+      _next();
+      var parameterTypes = <Type>[];
+      if (_currentToken != ')') {
+        while (true) {
+          parameterTypes.add(_parseType());
+          if (_currentToken == ')') break;
+          if (_currentToken != ',') {
+            _parseFailure('Expected `,` or `)`');
+          }
+          _next();
+        }
+      }
+      _next();
+      return _parseNullability(FunctionType(type, parameterTypes));
+    } else {
+      return null;
+    }
+  }
+
+  Type _parseType() {
+    // We currently accept the following grammar for types:
+    //   type := identifier typeArgs? nullability suffix* | `?`
+    //   typeArgs := `<` type (`,` type)* `>`
+    //   nullability := (`?` | `*`)?
+    //   suffix := `Function` `(` type (`,` type)* `)` suffix
+    //           | `&` type
+    // TODO(paulberry): support more syntax if needed
+    if (_currentToken == '?') {
+      _next();
+      return const UnknownType();
+    }
+    var typeName = _currentToken;
+    if (_identifierRegexp.matchAsPrefix(typeName) == null) {
+      _parseFailure('Expected an identifier or `?`');
+    }
+    _next();
+    List<Type> typeArgs;
+    if (_currentToken == '<') {
+      _next();
+      typeArgs = [];
+      while (true) {
+        typeArgs.add(_parseType());
+        if (_currentToken == '>') break;
+        if (_currentToken != ',') {
+          _parseFailure('Expected `,` or `>`');
+        }
+        _next();
+      }
+      _next();
+    } else {
+      typeArgs = const [];
+    }
+    var result = _parseNullability(NonFunctionType(typeName, args: typeArgs));
+    while (true) {
+      var newResult = _parseSuffix(result);
+      if (newResult == null) break;
+      result = newResult;
+    }
+    return result;
+  }
+
+  static Type parse(String typeStr) {
+    var parser = _TypeParser._(typeStr, _tokenizeTypeStr(typeStr));
+    var result = parser._parseType();
+    if (parser._currentToken != '<END>') {
+      fail('Extra tokens after parsing type `$typeStr`: '
+          '${parser._tokens.sublist(parser._i, parser._tokens.length - 1)}');
+    }
+    return result;
+  }
+
+  static List<String> _tokenizeTypeStr(String typeStr) {
+    var result = <String>[];
+    int lastMatchEnd = 0;
+    for (var match in _typeTokenizationRegexp.allMatches(typeStr)) {
+      var extraChars = typeStr.substring(lastMatchEnd, match.start).trim();
+      if (extraChars.isNotEmpty) {
+        fail('Unrecognized character(s) in type `$typeStr`: $extraChars');
+      }
+      result.add(typeStr.substring(match.start, match.end));
+      lastMatchEnd = match.end;
+    }
+    var extraChars = typeStr.substring(lastMatchEnd).trim();
+    if (extraChars.isNotEmpty) {
+      fail('Unrecognized character(s) in type `$typeStr`: $extraChars');
+    }
+    result.add('<END>');
+    return result;
+  }
+}
diff --git a/pkg/_js_interop_checks/lib/src/transformations/js_util_optimizer.dart b/pkg/_js_interop_checks/lib/src/transformations/js_util_optimizer.dart
index d1d72dc..bd38471 100644
--- a/pkg/_js_interop_checks/lib/src/transformations/js_util_optimizer.dart
+++ b/pkg/_js_interop_checks/lib/src/transformations/js_util_optimizer.dart
@@ -35,20 +35,21 @@
   /// for any argument type. Lowers `getProperty(o, name)` to
   /// `JS('Object|Null', '#.#', o, name)`.
   StaticInvocation _lowerGetProperty(StaticInvocation node) {
-    Arguments args = node.arguments;
-    assert(args.positional.length == 2);
+    Arguments arguments = node.arguments;
+    assert(arguments.types.isEmpty);
+    assert(arguments.positional.length == 2);
+    assert(arguments.named.isEmpty);
     return StaticInvocation(
         _jsTarget,
         Arguments(
           [
             StringLiteral("Object|Null"),
             StringLiteral("#.#"),
-            args.positional.first,
-            args.positional.last
+            ...arguments.positional
           ],
           // TODO(rileyporter): Copy type from getProperty when it's generic.
           types: [DynamicType()],
-        ))
+        )..fileOffset = node.arguments.fileOffset)
       ..fileOffset = node.fileOffset;
   }
 }
diff --git a/pkg/analysis_server/benchmark/benchmarks.dart b/pkg/analysis_server/benchmark/benchmarks.dart
index 1dd12cb..5276220 100644
--- a/pkg/analysis_server/benchmark/benchmarks.dart
+++ b/pkg/analysis_server/benchmark/benchmarks.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
+
 import 'dart:convert';
 import 'dart:io';
 import 'dart:math' as math;
diff --git a/pkg/analysis_server/benchmark/integration/driver.dart b/pkg/analysis_server/benchmark/integration/driver.dart
index 0bb18c1..9f40d74 100644
--- a/pkg/analysis_server/benchmark/integration/driver.dart
+++ b/pkg/analysis_server/benchmark/integration/driver.dart
@@ -40,13 +40,13 @@
   final Logger logger = Logger('Driver');
 
   /// The diagnostic port for Analysis Server or `null` if none.
-  final int diagnosticPort;
+  final int? diagnosticPort;
 
   /// A flag indicating whether the server is running.
   bool running = false;
 
   @override
-  Server server;
+  late Server server;
 
   /// The results collected while running analysis server.
   final Results results = Results();
@@ -63,7 +63,7 @@
   /// Perform the given operation.
   /// Return a [Future] that completes when the next operation can be performed,
   /// or `null` if the next operation can be performed immediately
-  Future perform(Operation op) {
+  Future<void>? perform(Operation op) {
     return op.perform(this);
   }
 
@@ -73,7 +73,7 @@
   /// normal (non-error) response, the future will be completed with the
   /// 'result' field from the response.  If the server acknowledges the command
   /// with an error response, the future will be completed with an error.
-  Future<Map<String, dynamic>> send(
+  Future<Map<String, Object?>?> send(
       String method, Map<String, dynamic> params) {
     return server.send(method, params);
   }
@@ -204,14 +204,17 @@
     print('');
     print('==================================================================');
     print('');
-    var keys = measurements.keys.toList()..sort();
-    var keyLen = keys.fold(0, (int len, String key) => max(len, key.length));
+    var sortedEntries = measurements.entries.toList();
+    sortedEntries.sort((a, b) => a.key.compareTo(b.key));
+    var keyLen = sortedEntries
+        .map((e) => e.key)
+        .fold(0, (int len, String key) => max(len, key.length));
     _printGroupHeader('Request/Response', keyLen);
     var totalCount = 0;
     var totalErrorCount = 0;
     var totalUnexpectedResultCount = 0;
-    for (var tag in keys) {
-      var m = measurements[tag];
+    for (var entry in sortedEntries) {
+      var m = entry.value;
       if (!m.notification) {
         m.printSummary(keyLen);
         totalCount += m.count;
@@ -223,8 +226,8 @@
         keyLen, totalCount, totalErrorCount, totalUnexpectedResultCount);
     print('');
     _printGroupHeader('Notifications', keyLen);
-    for (var tag in keys) {
-      var m = measurements[tag];
+    for (var entry in sortedEntries) {
+      var m = entry.value;
       if (m.notification) {
         m.printSummary(keyLen);
       }
@@ -250,7 +253,7 @@
   }
 
   void recordUnexpectedResults(String tag) {
-    measurements[tag].recordUnexpectedResults();
+    measurements[tag]!.recordUnexpectedResults();
   }
 
   void _printGroupHeader(String groupName, int keyLen) {
diff --git a/pkg/analysis_server/benchmark/integration/input_converter.dart b/pkg/analysis_server/benchmark/integration/input_converter.dart
index 7f7ca06..0f86919 100644
--- a/pkg/analysis_server/benchmark/integration/input_converter.dart
+++ b/pkg/analysis_server/benchmark/integration/input_converter.dart
@@ -18,14 +18,14 @@
 import 'operation.dart';
 
 /// Common input converter superclass for sharing implementation.
-abstract class CommonInputConverter extends Converter<String, Operation> {
+abstract class CommonInputConverter extends Converter<String, Operation?> {
   static final ERROR_PREFIX = 'Server responded with an error: ';
   final Logger logger = Logger('InstrumentationInputConverter');
   final Set<String> eventsSeen = <String>{};
 
   /// A mapping from request/response id to request json
   /// for those requests for which a response has not been processed.
-  final Map<String, dynamic> requestMap = {};
+  final Map<String, Object?> requestMap = {};
 
   /// A mapping from request/response id to a completer
   /// for those requests for which a response has not been processed.
@@ -35,7 +35,7 @@
 
   /// A mapping from request/response id to the actual response result
   /// for those responses that have not been processed.
-  final Map<String, dynamic> responseMap = {};
+  final Map<String, Object?> responseMap = {};
 
   /// A mapping of current overlay content
   /// parallel to what is in the analysis server
@@ -56,16 +56,18 @@
 
   CommonInputConverter(this.tmpSrcDirPath, this.srcPathMap);
 
-  Map<String, dynamic> asMap(dynamic value) => value as Map<String, dynamic>;
+  Map<String, Object?> asMap(dynamic value) => value as Map<String, Object?>;
+
+  Map<String, Object?>? asMap2(dynamic value) => value as Map<String, Object?>?;
 
   /// Return an operation for the notification or `null` if none.
-  Operation convertNotification(Map<String, dynamic> json) {
+  Operation? convertNotification(Map<String, dynamic> json) {
     String event = json['event'];
     if (event == SERVER_NOTIFICATION_STATUS) {
       // {"event":"server.status","params":{"analysis":{"isAnalyzing":false}}}
-      var params = asMap(json['params']);
+      var params = asMap2(json['params']);
       if (params != null) {
-        var analysis = asMap(params['analysis']);
+        var analysis = asMap2(params['analysis']);
         if (analysis != null && analysis['isAnalyzing'] == false) {
           return WaitForAnalysisCompleteOperation();
         }
@@ -82,23 +84,20 @@
   }
 
   /// Return an operation for the request or `null` if none.
-  Operation convertRequest(Map<String, dynamic> origJson) {
+  Operation convertRequest(Map<String, Object?> origJson) {
     var json = asMap(translateSrcPaths(origJson));
-    requestMap[json['id']] = json;
-    String method = json['method'];
+    requestMap[json['id'] as String] = json;
+    var method = json['method'] as String;
     // Sanity check operations that modify source
     // to ensure that the operation is on source in temp space
     if (method == ANALYSIS_REQUEST_UPDATE_CONTENT) {
       // Track overlays in parallel with the analysis server
       // so that when an overlay is removed, the file can be updated on disk
-      var request = Request.fromJson(json);
+      var request = Request.fromJson(json)!;
       var params = AnalysisUpdateContentParams.fromRequest(request);
       params.files.forEach((String filePath, change) {
         if (change is AddContentOverlay) {
           var content = change.content;
-          if (content == null) {
-            throw 'expected new overlay content\n$json';
-          }
           overlays[filePath] = content;
         } else if (change is ChangeContentOverlay) {
           var content = overlays[filePath];
@@ -170,8 +169,9 @@
   void processErrorResponse(String id, exception) {
     var result = exception;
     if (exception is UnimplementedError) {
-      if (exception.message.startsWith(ERROR_PREFIX)) {
-        result = json.decode(exception.message.substring(ERROR_PREFIX.length));
+      var message = exception.message;
+      if (message!.startsWith(ERROR_PREFIX)) {
+        result = json.decode(message.substring(ERROR_PREFIX.length));
       }
     }
     processResponseResult(id, result);
@@ -184,7 +184,7 @@
   /// Return a future that completes when the response is received
   /// or `null` if the response has already been received
   /// and the completer completed.
-  Future processExpectedResponse(String id, Completer completer) {
+  Future<void>? processExpectedResponse(String id, Completer completer) {
     if (responseMap.containsKey(id)) {
       logger.log(Level.INFO, 'processing cached response $id');
       completer.complete(responseMap.remove(id));
@@ -226,7 +226,7 @@
       return result;
     }
     if (json is Map) {
-      var result = <String, dynamic>{};
+      var result = <String, Object?>{};
       json.forEach((origKey, value) {
         result[translateSrcPaths(origKey)] = translateSrcPaths(value);
       });
@@ -239,7 +239,7 @@
 /// [InputConverter] converts an input stream
 /// into a series of operations to be sent to the analysis server.
 /// The input stream can be either an instrumentation or log file.
-class InputConverter extends Converter<String, Operation> {
+class InputConverter extends Converter<String, Operation?> {
   final Logger logger = Logger('InputConverter');
 
   /// A mapping of source path prefixes
@@ -257,7 +257,7 @@
 
   /// The underlying converter used to translate lines into operations
   /// or `null` if it has not yet been determined.
-  Converter<String, Operation> converter;
+  Converter<String, Operation?>? converter;
 
   /// [active] is `true` if converting lines to operations
   /// or `false` if an exception has occurred.
@@ -266,10 +266,11 @@
   InputConverter(this.tmpSrcDirPath, this.srcPathMap);
 
   @override
-  Operation convert(String line) {
+  Operation? convert(String line) {
     if (!active) {
       return null;
     }
+    var converter = this.converter;
     if (converter != null) {
       try {
         return converter.convert(line);
@@ -333,8 +334,8 @@
 }
 
 class _InputSink extends ChunkedConversionSink<String> {
-  final Converter<String, Operation> converter;
-  final Sink<Operation> outSink;
+  final Converter<String, Operation?> converter;
+  final Sink<Operation?> outSink;
 
   _InputSink(this.converter, this.outSink);
 
diff --git a/pkg/analysis_server/benchmark/integration/instrumentation_input_converter.dart b/pkg/analysis_server/benchmark/integration/instrumentation_input_converter.dart
index e2f01d3..037c9b0 100644
--- a/pkg/analysis_server/benchmark/integration/instrumentation_input_converter.dart
+++ b/pkg/analysis_server/benchmark/integration/instrumentation_input_converter.dart
@@ -21,17 +21,18 @@
   /// [readBuffer] holds the contents of the file being read from disk
   /// as recorded in the instrumentation log
   /// or `null` if not converting a "Read" entry.
-  StringBuffer readBuffer;
+  StringBuffer? readBuffer;
 
   InstrumentationInputConverter(String tmpSrcDirPath, PathMap srcPathMap)
       : super(tmpSrcDirPath, srcPathMap);
 
   @override
-  Operation convert(String line) {
+  Operation? convert(String line) {
     List<String> fields;
     try {
       fields = _parseFields(line);
       if (fields.length < 2) {
+        var readBuffer = this.readBuffer;
         if (readBuffer != null) {
           readBuffer.writeln(fields.length == 1 ? fields[0] : '');
           return null;
@@ -76,7 +77,7 @@
     return null;
   }
 
-  Map<String, dynamic> decodeJson(String line, String text) {
+  Map<String, Object?> decodeJson(String line, String text) {
     try {
       return asMap(json.decode(text));
     } catch (e, s) {
diff --git a/pkg/analysis_server/benchmark/integration/local_runner.dart b/pkg/analysis_server/benchmark/integration/local_runner.dart
index 857d422..f8a987a 100644
--- a/pkg/analysis_server/benchmark/integration/local_runner.dart
+++ b/pkg/analysis_server/benchmark/integration/local_runner.dart
@@ -75,7 +75,7 @@
 }
 
 /// Print help and exit
-void printHelp([String errMsg]) {
+void printHelp([String? errMsg]) {
   if (errMsg != null) {
     print('');
     print('Error: $errMsg');
diff --git a/pkg/analysis_server/benchmark/integration/log_file_input_converter.dart b/pkg/analysis_server/benchmark/integration/log_file_input_converter.dart
index 6ec1a4f..bd87c70 100644
--- a/pkg/analysis_server/benchmark/integration/log_file_input_converter.dart
+++ b/pkg/analysis_server/benchmark/integration/log_file_input_converter.dart
@@ -23,7 +23,7 @@
       : super(tmpSrcDirPath, srcPathMap);
 
   @override
-  Operation convert(String line) {
+  Operation? convert(String line) {
     try {
       var timeStampString = _parseTimeStamp(line);
       var data = line.substring(timeStampString.length);
diff --git a/pkg/analysis_server/benchmark/integration/main.dart b/pkg/analysis_server/benchmark/integration/main.dart
index 8006da8..8f0a438 100644
--- a/pkg/analysis_server/benchmark/integration/main.dart
+++ b/pkg/analysis_server/benchmark/integration/main.dart
@@ -24,9 +24,9 @@
 
   var driver = Driver(diagnosticPort: args.diagnosticPort);
   var stream = openInput(args);
-  StreamSubscription<Operation> subscription;
-  subscription = stream.listen((Operation op) {
-    var future = driver.perform(op);
+  late StreamSubscription<Operation?> subscription;
+  subscription = stream.listen((Operation? op) {
+    var future = driver.perform(op!);
     if (future != null) {
       logger.log(Level.FINE, 'pausing operations for ${op.runtimeType}');
       subscription.pause(future.then((_) {
@@ -61,17 +61,15 @@
 const VERBOSE_CMDLINE_OPTION = 'verbose';
 const VERY_VERBOSE_CMDLINE_OPTION = 'vv';
 
-ArgParser _argParser;
+late final ArgParser argParser = () {
+  var argParser = ArgParser();
 
-ArgParser get argParser {
-  _argParser = ArgParser();
-
-  _argParser.addOption(INPUT_CMDLINE_OPTION,
+  argParser.addOption(INPUT_CMDLINE_OPTION,
       abbr: 'i',
       help: '<filePath>\n'
           'The input file specifying how this client should interact with the server.\n'
           'If the input file name is "stdin", then the instructions are read from standard input.');
-  _argParser.addMultiOption(MAP_OPTION,
+  argParser.addMultiOption(MAP_OPTION,
       abbr: 'm',
       splitCommas: false,
       help: '<oldSrcPath>,<newSrcPath>\n'
@@ -80,26 +78,26 @@
           'to the target source directory <newSrcPath> used during performance testing.\n'
           'Multiple mappings can be specified.\n'
           'WARNING: The contents of the target directory will be modified');
-  _argParser.addOption(TMP_SRC_DIR_OPTION,
+  argParser.addOption(TMP_SRC_DIR_OPTION,
       abbr: 't',
       help: '<dirPath>\n'
           'The temporary directory containing source used during performance measurement.\n'
           'WARNING: The contents of the target directory will be modified');
-  _argParser.addOption(DIAGNOSTIC_PORT_OPTION,
+  argParser.addOption(DIAGNOSTIC_PORT_OPTION,
       abbr: 'd',
       help: 'localhost port on which server will provide diagnostic web pages');
-  _argParser.addFlag(VERBOSE_CMDLINE_OPTION,
+  argParser.addFlag(VERBOSE_CMDLINE_OPTION,
       abbr: 'v', help: 'Verbose logging', negatable: false);
-  _argParser.addFlag(VERY_VERBOSE_CMDLINE_OPTION,
+  argParser.addFlag(VERY_VERBOSE_CMDLINE_OPTION,
       help: 'Extra verbose logging', negatable: false);
-  _argParser.addFlag(HELP_CMDLINE_OPTION,
+  argParser.addFlag(HELP_CMDLINE_OPTION,
       abbr: 'h', help: 'Print this help information', negatable: false);
-  return _argParser;
-}
+  return argParser;
+}();
 
 /// Open and return the input stream specifying how this client
 /// should interact with the analysis server.
-Stream<Operation> openInput(PerfArgs args) {
+Stream<Operation?> openInput(PerfArgs args) {
   var logger = Logger('openInput');
   Stream<List<int>> inputRaw;
   if (args.inputPath == 'stdin') {
@@ -135,12 +133,12 @@
 
   var showHelp = args[HELP_CMDLINE_OPTION] || args.rest.isNotEmpty;
 
-  bool isMissing(key) => args[key] == null || args[key].isEmpty;
-
-  perfArgs.inputPath = args[INPUT_CMDLINE_OPTION];
-  if (isMissing(INPUT_CMDLINE_OPTION)) {
+  var inputArg = args[INPUT_CMDLINE_OPTION];
+  if (inputArg is! String || inputArg.isEmpty) {
     print('missing $INPUT_CMDLINE_OPTION argument');
     showHelp = true;
+  } else {
+    perfArgs.inputPath = inputArg;
   }
 
   for (String pair in args[MAP_OPTION]) {
@@ -155,18 +153,20 @@
         }
       }
     }
-    print('must specifiy $MAP_OPTION <oldSrcPath>,<newSrcPath>');
+    print('must specify $MAP_OPTION <oldSrcPath>,<newSrcPath>');
     showHelp = true;
   }
 
-  perfArgs.tmpSrcDirPath = _withTrailingSeparator(args[TMP_SRC_DIR_OPTION]);
-  if (isMissing(TMP_SRC_DIR_OPTION)) {
+  var tmpSrcDirPathArg = args[TMP_SRC_DIR_OPTION];
+  if (tmpSrcDirPathArg is! String || tmpSrcDirPathArg.isEmpty) {
     print('missing $TMP_SRC_DIR_OPTION argument');
     showHelp = true;
+  } else {
+    perfArgs.tmpSrcDirPath = _withTrailingSeparator(tmpSrcDirPathArg);
   }
 
-  String portText = args[DIAGNOSTIC_PORT_OPTION];
-  if (portText != null) {
+  var portText = args[DIAGNOSTIC_PORT_OPTION];
+  if (portText is String) {
     if (int.tryParse(portText) == null) {
       print('invalid $DIAGNOSTIC_PORT_OPTION: $portText');
       showHelp = true;
@@ -200,7 +200,7 @@
 
 /// Ensure that the given path has a trailing separator
 String _withTrailingSeparator(String dirPath) {
-  if (dirPath != null && dirPath.length > 4) {
+  if (dirPath.length > 4) {
     if (!dirPath.endsWith(path.separator)) {
       return '$dirPath${path.separator}';
     }
@@ -213,7 +213,7 @@
   /// The file path of the instrumentation or log file
   /// used to drive performance measurement,
   /// or 'stdin' if this information should be read from standard input.
-  String inputPath;
+  late String inputPath;
 
   /// A mapping from the original source directory
   /// when the instrumentation or log file was generated
@@ -222,8 +222,8 @@
 
   /// The temporary directory containing source used during performance
   /// measurement.
-  String tmpSrcDirPath;
+  late String tmpSrcDirPath;
 
   /// The diagnostic port for Analysis Server or `null` if none.
-  int diagnosticPort;
+  int? diagnosticPort;
 }
diff --git a/pkg/analysis_server/benchmark/integration/operation.dart b/pkg/analysis_server/benchmark/integration/operation.dart
index 7532df2..311e979 100644
--- a/pkg/analysis_server/benchmark/integration/operation.dart
+++ b/pkg/analysis_server/benchmark/integration/operation.dart
@@ -13,10 +13,10 @@
 /// A [CompletionRequestOperation] tracks response time along with
 /// the first and last completion notifications.
 class CompletionRequestOperation extends RequestOperation {
-  Driver driver;
-  StreamSubscription<CompletionResultsParams> subscription;
-  String notificationId;
-  Stopwatch stopwatch;
+  late Driver driver;
+  late StreamSubscription<CompletionResultsParams> subscription;
+  late String notificationId;
+  late Stopwatch stopwatch;
   bool firstNotification = true;
 
   CompletionRequestOperation(
@@ -24,7 +24,7 @@
       : super(converter, json);
 
   @override
-  Future perform(Driver driver) {
+  Future<void>? perform(Driver driver) {
     this.driver = driver;
     subscription = driver.onCompletionResults.listen(processNotification);
     return super.perform(driver);
@@ -48,8 +48,8 @@
 
   @override
   void processResult(
-      String id, Map<String, dynamic> result, Stopwatch stopwatch) {
-    notificationId = result['id'];
+      String id, Map<String, Object?> result, Stopwatch stopwatch) {
+    notificationId = result['id'] as String;
     this.stopwatch = stopwatch;
     super.processResult(id, result, stopwatch);
   }
@@ -57,7 +57,7 @@
 
 /// An [Operation] represents an action such as sending a request to the server.
 abstract class Operation {
-  Future perform(Driver driver);
+  Future<void>? perform(Driver driver);
 }
 
 /// A [RequestOperation] sends a [JSON] request to the server.
@@ -68,7 +68,7 @@
   RequestOperation(this.converter, this.json);
 
   @override
-  Future perform(Driver driver) {
+  Future<void>? perform(Driver driver) {
     var stopwatch = Stopwatch();
     String originalId = json['id'];
     String method = json['method'];
@@ -83,11 +83,9 @@
           .log(Level.FINE, 'Response received: $method : $elapsed\n  $result');
     }
 
-    driver
-        .send(method, converter.asMap(json['params']))
-        .then((Map<String, dynamic> result) {
+    driver.send(method, converter.asMap(json['params'])).then((result) {
       recordResult(true, result);
-      processResult(originalId, result, stopwatch);
+      processResult(originalId, result!, stopwatch);
     }).catchError((exception) {
       recordResult(false, exception);
       converter.processErrorResponse(originalId, exception);
@@ -96,7 +94,7 @@
   }
 
   void processResult(
-      String id, Map<String, dynamic> result, Stopwatch stopwatch) {
+      String id, Map<String, Object?> result, Stopwatch stopwatch) {
     converter.processResponseResult(id, result);
   }
 }
@@ -105,19 +103,20 @@
 class ResponseOperation extends Operation {
   static final Duration responseTimeout = Duration(seconds: 60);
   final CommonInputConverter converter;
-  final Map<String, dynamic> requestJson;
-  final Map<String, dynamic> responseJson;
+  final Map<String, Object?> requestJson;
+  final Map<String, Object?> responseJson;
   final Completer completer = Completer();
-  Driver driver;
+  late Driver driver;
 
   ResponseOperation(this.converter, this.requestJson, this.responseJson) {
     completer.future.then(_processResult).timeout(responseTimeout);
   }
 
   @override
-  Future perform(Driver driver) {
+  Future<void>? perform(Driver driver) {
     this.driver = driver;
-    return converter.processExpectedResponse(responseJson['id'], completer);
+    var id = responseJson['id'] as String;
+    return converter.processExpectedResponse(id, completer);
   }
 
   bool _equal(expectedResult, actualResult) {
@@ -159,7 +158,8 @@
           'expected result:${format(expectedResult)}\n'
           'expected error:${format(expectedError)}\n'
           'but received:${format(actualResult)}';
-      driver.results.recordUnexpectedResults(requestJson['method']);
+      var method = requestJson['method'] as String;
+      driver.results.recordUnexpectedResults(method);
       converter.logOverlayContent();
       if (expectedError == null) {
         converter.logger.log(Level.SEVERE, message);
@@ -182,13 +182,14 @@
   Future perform(Driver driver) {
     var start = DateTime.now();
     driver.logger.log(Level.FINE, 'waiting for analysis to complete');
-    StreamSubscription<ServerStatusParams> subscription;
-    Timer timer;
+    late StreamSubscription<ServerStatusParams> subscription;
+    late Timer timer;
     var completer = Completer();
     var isAnalyzing = false;
     subscription = driver.onServerStatus.listen((ServerStatusParams params) {
-      if (params.analysis != null) {
-        if (params.analysis.isAnalyzing) {
+      var analysisStatus = params.analysis;
+      if (analysisStatus != null) {
+        if (analysisStatus.isAnalyzing) {
           isAnalyzing = true;
         } else {
           subscription.cancel();
@@ -212,7 +213,7 @@
       }
       // Timeout if no communication received within the last 60 seconds.
       var currentTime = driver.server.currentElapseTime;
-      var lastTime = driver.server.lastCommunicationTime;
+      var lastTime = driver.server.lastCommunicationTime!;
       if (currentTime - lastTime > 60) {
         subscription.cancel();
         timer.cancel();
diff --git a/pkg/analysis_server/benchmark/perf/benchmarks_impl.dart b/pkg/analysis_server/benchmark/perf/benchmarks_impl.dart
index fab0850..1a59fa6 100644
--- a/pkg/analysis_server/benchmark/perf/benchmarks_impl.dart
+++ b/pkg/analysis_server/benchmark/perf/benchmarks_impl.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
+
 import 'dart:async';
 import 'dart:io';
 
diff --git a/pkg/analysis_server/benchmark/perf/flutter_analyze_benchmark.dart b/pkg/analysis_server/benchmark/perf/flutter_analyze_benchmark.dart
index e0008e8..171aab6 100644
--- a/pkg/analysis_server/benchmark/perf/flutter_analyze_benchmark.dart
+++ b/pkg/analysis_server/benchmark/perf/flutter_analyze_benchmark.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
+
 import 'dart:convert';
 import 'dart:io';
 
diff --git a/pkg/analysis_server/benchmark/perf/memory_tests.dart b/pkg/analysis_server/benchmark/perf/memory_tests.dart
index c78c614..9a2c30c 100644
--- a/pkg/analysis_server/benchmark/perf/memory_tests.dart
+++ b/pkg/analysis_server/benchmark/perf/memory_tests.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
+
 import 'dart:async';
 import 'dart:convert' show jsonDecode, jsonEncode;
 import 'dart:io';
diff --git a/pkg/analysis_server/bin/server.dart b/pkg/analysis_server/bin/server.dart
index 7810101..a873eb1 100644
--- a/pkg/analysis_server/bin/server.dart
+++ b/pkg/analysis_server/bin/server.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
+
 import 'package:analysis_server/starter.dart';
 
 /// Create and run an analysis server.
diff --git a/pkg/analysis_server/doc/api.html b/pkg/analysis_server/doc/api.html
index 8c5161c..9fcb9a9 100644
--- a/pkg/analysis_server/doc/api.html
+++ b/pkg/analysis_server/doc/api.html
@@ -4762,6 +4762,18 @@
           The one-based index of the column containing the first character of
           the range.
         </p>
+      </dd><dt class="field"><b>endLine: int</b></dt><dd>
+        
+        <p>
+          The one-based index of the line containing the character immediately
+          following the range.
+        </p>
+      </dd><dt class="field"><b>endColumn: int</b></dt><dd>
+        
+        <p>
+          The one-based index of the column containing the character immediately
+          following the range.
+        </p>
       </dd></dl></dd><dt class="typeDefinition"><a name="type_NavigationRegion">NavigationRegion: object</a></dt><dd>
     <p>
       A description of a region from which the user can navigate to the
diff --git a/pkg/analysis_server/lib/lsp_protocol/protocol_custom_generated.dart b/pkg/analysis_server/lib/lsp_protocol/protocol_custom_generated.dart
index c67d3f7..53800de 100644
--- a/pkg/analysis_server/lib/lsp_protocol/protocol_custom_generated.dart
+++ b/pkg/analysis_server/lib/lsp_protocol/protocol_custom_generated.dart
@@ -2,17 +2,14 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+// @dart = 2.9
+
 // This file has been automatically generated. Please do not edit it manually.
 // To regenerate the file, use the script
 // "pkg/analysis_server/tool/lsp_spec/generate_all.dart".
 
 // ignore_for_file: annotate_overrides
-// ignore_for_file: deprecated_member_use
-// ignore_for_file: deprecated_member_use_from_same_package
-// ignore_for_file: unnecessary_brace_in_string_interps
 // ignore_for_file: unnecessary_parenthesis
-// ignore_for_file: unused_import
-// ignore_for_file: unused_shown_name
 
 import 'dart:core' hide deprecated;
 import 'dart:core' as core show deprecated;
@@ -20,8 +17,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/json_parsing.dart';
-import 'package:analysis_server/src/protocol/protocol_internal.dart'
-    show listEqual, mapEqual;
+import 'package:analysis_server/src/protocol/protocol_internal.dart';
 import 'package:analyzer/src/generated/utilities_general.dart';
 import 'package:meta/meta.dart';
 
@@ -1573,3 +1569,135 @@
   @override
   String toString() => jsonEncoder.convert(toJson());
 }
+
+class SnippetTextEdit implements TextEdit, ToJsonable {
+  static const jsonHandler =
+      LspJsonHandler(SnippetTextEdit.canParse, SnippetTextEdit.fromJson);
+
+  SnippetTextEdit(
+      {@required this.insertTextFormat,
+      @required this.range,
+      @required this.newText}) {
+    if (insertTextFormat == null) {
+      throw 'insertTextFormat is required but was not provided';
+    }
+    if (range == null) {
+      throw 'range is required but was not provided';
+    }
+    if (newText == null) {
+      throw 'newText is required but was not provided';
+    }
+  }
+  static SnippetTextEdit fromJson(Map<String, dynamic> json) {
+    final insertTextFormat = json['insertTextFormat'] != null
+        ? InsertTextFormat.fromJson(json['insertTextFormat'])
+        : null;
+    final range = json['range'] != null ? Range.fromJson(json['range']) : null;
+    final newText = json['newText'];
+    return SnippetTextEdit(
+        insertTextFormat: insertTextFormat, range: range, newText: newText);
+  }
+
+  final InsertTextFormat insertTextFormat;
+
+  /// The string to be inserted. For delete operations use an empty string.
+  final String newText;
+
+  /// The range of the text document to be manipulated. To insert text into a
+  /// document create a range where start === end.
+  final Range range;
+
+  Map<String, dynamic> toJson() {
+    var __result = <String, dynamic>{};
+    __result['insertTextFormat'] = insertTextFormat?.toJson() ??
+        (throw 'insertTextFormat is required but was not set');
+    __result['range'] =
+        range?.toJson() ?? (throw 'range is required but was not set');
+    __result['newText'] =
+        newText ?? (throw 'newText is required but was not set');
+    return __result;
+  }
+
+  static bool canParse(Object obj, LspJsonReporter reporter) {
+    if (obj is Map<String, dynamic>) {
+      reporter.push('insertTextFormat');
+      try {
+        if (!obj.containsKey('insertTextFormat')) {
+          reporter.reportError('must not be undefined');
+          return false;
+        }
+        if (obj['insertTextFormat'] == null) {
+          reporter.reportError('must not be null');
+          return false;
+        }
+        if (!(InsertTextFormat.canParse(obj['insertTextFormat'], reporter))) {
+          reporter.reportError('must be of type InsertTextFormat');
+          return false;
+        }
+      } finally {
+        reporter.pop();
+      }
+      reporter.push('range');
+      try {
+        if (!obj.containsKey('range')) {
+          reporter.reportError('must not be undefined');
+          return false;
+        }
+        if (obj['range'] == null) {
+          reporter.reportError('must not be null');
+          return false;
+        }
+        if (!(Range.canParse(obj['range'], reporter))) {
+          reporter.reportError('must be of type Range');
+          return false;
+        }
+      } finally {
+        reporter.pop();
+      }
+      reporter.push('newText');
+      try {
+        if (!obj.containsKey('newText')) {
+          reporter.reportError('must not be undefined');
+          return false;
+        }
+        if (obj['newText'] == null) {
+          reporter.reportError('must not be null');
+          return false;
+        }
+        if (!(obj['newText'] is String)) {
+          reporter.reportError('must be of type String');
+          return false;
+        }
+      } finally {
+        reporter.pop();
+      }
+      return true;
+    } else {
+      reporter.reportError('must be of type SnippetTextEdit');
+      return false;
+    }
+  }
+
+  @override
+  bool operator ==(Object other) {
+    if (other is SnippetTextEdit && other.runtimeType == SnippetTextEdit) {
+      return insertTextFormat == other.insertTextFormat &&
+          range == other.range &&
+          newText == other.newText &&
+          true;
+    }
+    return false;
+  }
+
+  @override
+  int get hashCode {
+    var hash = 0;
+    hash = JenkinsSmiHash.combine(hash, insertTextFormat.hashCode);
+    hash = JenkinsSmiHash.combine(hash, range.hashCode);
+    hash = JenkinsSmiHash.combine(hash, newText.hashCode);
+    return JenkinsSmiHash.finish(hash);
+  }
+
+  @override
+  String toString() => jsonEncoder.convert(toJson());
+}
diff --git a/pkg/analysis_server/lib/lsp_protocol/protocol_generated.dart b/pkg/analysis_server/lib/lsp_protocol/protocol_generated.dart
index 215bf08..ec98cde 100644
--- a/pkg/analysis_server/lib/lsp_protocol/protocol_generated.dart
+++ b/pkg/analysis_server/lib/lsp_protocol/protocol_generated.dart
@@ -2,17 +2,14 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+// @dart = 2.9
+
 // This file has been automatically generated. Please do not edit it manually.
 // To regenerate the file, use the script
 // "pkg/analysis_server/tool/lsp_spec/generate_all.dart".
 
 // ignore_for_file: annotate_overrides
-// ignore_for_file: deprecated_member_use
-// ignore_for_file: deprecated_member_use_from_same_package
-// ignore_for_file: unnecessary_brace_in_string_interps
 // ignore_for_file: unnecessary_parenthesis
-// ignore_for_file: unused_import
-// ignore_for_file: unused_shown_name
 
 import 'dart:core' hide deprecated;
 import 'dart:core' as core show deprecated;
@@ -20,8 +17,7 @@
 import 'package:analysis_server/lsp_protocol/protocol_custom_generated.dart';
 import 'package:analysis_server/lsp_protocol/protocol_special.dart';
 import 'package:analysis_server/src/lsp/json_parsing.dart';
-import 'package:analysis_server/src/protocol/protocol_internal.dart'
-    show listEqual, mapEqual;
+import 'package:analysis_server/src/protocol/protocol_internal.dart';
 import 'package:analyzer/src/generated/utilities_general.dart';
 import 'package:meta/meta.dart';
 
@@ -9537,7 +9533,7 @@
                     item != null
                         ? TextDocumentContentChangeEvent2.fromJson(item)
                         : null)
-                : (throw '''${item} was not one of (TextDocumentContentChangeEvent1, TextDocumentContentChangeEvent2)''')))
+                : (throw '''$item was not one of (TextDocumentContentChangeEvent1, TextDocumentContentChangeEvent2)''')))
         ?.cast<Either2<TextDocumentContentChangeEvent1, TextDocumentContentChangeEvent2>>()
         ?.toList();
     return DidChangeTextDocumentParams(
@@ -30666,14 +30662,17 @@
         ? OptionalVersionedTextDocumentIdentifier.fromJson(json['textDocument'])
         : null;
     final edits = json['edits']
-        ?.map((item) => TextEdit.canParse(item, nullLspJsonReporter)
-            ? Either2<TextEdit, AnnotatedTextEdit>.t1(
-                item != null ? TextEdit.fromJson(item) : null)
+        ?.map((item) => SnippetTextEdit.canParse(item, nullLspJsonReporter)
+            ? Either3<SnippetTextEdit, AnnotatedTextEdit, TextEdit>.t1(
+                item != null ? SnippetTextEdit.fromJson(item) : null)
             : (AnnotatedTextEdit.canParse(item, nullLspJsonReporter)
-                ? Either2<TextEdit, AnnotatedTextEdit>.t2(
+                ? Either3<SnippetTextEdit, AnnotatedTextEdit, TextEdit>.t2(
                     item != null ? AnnotatedTextEdit.fromJson(item) : null)
-                : (throw '''${item} was not one of (TextEdit, AnnotatedTextEdit)''')))
-        ?.cast<Either2<TextEdit, AnnotatedTextEdit>>()
+                : (TextEdit.canParse(item, nullLspJsonReporter)
+                    ? Either3<SnippetTextEdit, AnnotatedTextEdit, TextEdit>.t3(
+                        item != null ? TextEdit.fromJson(item) : null)
+                    : (throw '''$item was not one of (SnippetTextEdit, AnnotatedTextEdit, TextEdit)'''))))
+        ?.cast<Either3<SnippetTextEdit, AnnotatedTextEdit, TextEdit>>()
         ?.toList();
     return TextDocumentEdit(textDocument: textDocument, edits: edits);
   }
@@ -30681,7 +30680,7 @@
   /// The edits to be applied.
   ///  @since 3.16.0 - support for AnnotatedTextEdit. This is guarded by the
   /// client capability `workspace.workspaceEdit.changeAnnotationSupport`
-  final List<Either2<TextEdit, AnnotatedTextEdit>> edits;
+  final List<Either3<SnippetTextEdit, AnnotatedTextEdit, TextEdit>> edits;
 
   /// The text document to change.
   final OptionalVersionedTextDocumentIdentifier textDocument;
@@ -30726,10 +30725,12 @@
           return false;
         }
         if (!((obj['edits'] is List &&
-            (obj['edits'].every((item) => (TextEdit.canParse(item, reporter) ||
-                AnnotatedTextEdit.canParse(item, reporter))))))) {
+            (obj['edits'].every((item) =>
+                (SnippetTextEdit.canParse(item, reporter) ||
+                    AnnotatedTextEdit.canParse(item, reporter) ||
+                    TextEdit.canParse(item, reporter))))))) {
           reporter.reportError(
-              'must be of type List<Either2<TextEdit, AnnotatedTextEdit>>');
+              'must be of type List<Either3<SnippetTextEdit, AnnotatedTextEdit, TextEdit>>');
           return false;
         }
       } finally {
@@ -30749,8 +30750,9 @@
           listEqual(
               edits,
               other.edits,
-              (Either2<TextEdit, AnnotatedTextEdit> a,
-                      Either2<TextEdit, AnnotatedTextEdit> b) =>
+              (Either3<SnippetTextEdit, AnnotatedTextEdit, TextEdit> a,
+                      Either3<SnippetTextEdit, AnnotatedTextEdit, TextEdit>
+                          b) =>
                   a == b) &&
           true;
     }
@@ -31777,6 +31779,9 @@
     if (AnnotatedTextEdit.canParse(json, nullLspJsonReporter)) {
       return AnnotatedTextEdit.fromJson(json);
     }
+    if (SnippetTextEdit.canParse(json, nullLspJsonReporter)) {
+      return SnippetTextEdit.fromJson(json);
+    }
     final range = json['range'] != null ? Range.fromJson(json['range']) : null;
     final newText = json['newText'];
     return TextEdit(range: range, newText: newText);
@@ -33636,7 +33641,7 @@
                         item != null ? TextDocumentEdit.fromJson(item) : null)
                     : (CreateFile.canParse(item, nullLspJsonReporter)
                         ? Either4<TextDocumentEdit, CreateFile, RenameFile, DeleteFile>.t2(item != null ? CreateFile.fromJson(item) : null)
-                        : (RenameFile.canParse(item, nullLspJsonReporter) ? Either4<TextDocumentEdit, CreateFile, RenameFile, DeleteFile>.t3(item != null ? RenameFile.fromJson(item) : null) : (DeleteFile.canParse(item, nullLspJsonReporter) ? Either4<TextDocumentEdit, CreateFile, RenameFile, DeleteFile>.t4(item != null ? DeleteFile.fromJson(item) : null) : (item == null ? null : (throw '''${item} was not one of (TextDocumentEdit, CreateFile, RenameFile, DeleteFile)'''))))))
+                        : (RenameFile.canParse(item, nullLspJsonReporter) ? Either4<TextDocumentEdit, CreateFile, RenameFile, DeleteFile>.t3(item != null ? RenameFile.fromJson(item) : null) : (DeleteFile.canParse(item, nullLspJsonReporter) ? Either4<TextDocumentEdit, CreateFile, RenameFile, DeleteFile>.t4(item != null ? DeleteFile.fromJson(item) : null) : (item == null ? null : (throw '''$item was not one of (TextDocumentEdit, CreateFile, RenameFile, DeleteFile)'''))))))
                 ?.cast<Either4<TextDocumentEdit, CreateFile, RenameFile, DeleteFile>>()
                 ?.toList())
             : (json['documentChanges'] == null ? null : (throw '''${json['documentChanges']} was not one of (List<TextDocumentEdit>, List<Either4<TextDocumentEdit, CreateFile, RenameFile, DeleteFile>>)''')));
diff --git a/pkg/analysis_server/lib/lsp_protocol/protocol_special.dart b/pkg/analysis_server/lib/lsp_protocol/protocol_special.dart
index bd9b513..e1f4838 100644
--- a/pkg/analysis_server/lib/lsp_protocol/protocol_special.dart
+++ b/pkg/analysis_server/lib/lsp_protocol/protocol_special.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
+
 import 'dart:async';
 
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
diff --git a/pkg/analysis_server/lib/plugin/protocol/protocol_dart.dart b/pkg/analysis_server/lib/plugin/protocol/protocol_dart.dart
index 915d8b3..c456641 100644
--- a/pkg/analysis_server/lib/plugin/protocol/protocol_dart.dart
+++ b/pkg/analysis_server/lib/plugin/protocol/protocol_dart.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
+
 /// Utilities for converting Dart entities into analysis server's protocol
 /// entities.
 import 'package:analysis_server/src/protocol_server.dart';
diff --git a/pkg/analysis_server/lib/protocol/protocol.dart b/pkg/analysis_server/lib/protocol/protocol.dart
index f995858..8eef995 100644
--- a/pkg/analysis_server/lib/protocol/protocol.dart
+++ b/pkg/analysis_server/lib/protocol/protocol.dart
@@ -28,7 +28,7 @@
 
   /// A table mapping the names of notification parameters to their values, or
   /// `null` if there are no notification parameters.
-  final Map<String, Object> params;
+  final Map<String, Object>? params;
 
   /// Initialize a newly created [Notification] to have the given [event] name.
   /// If [params] is provided, it will be used as the params; otherwise no
@@ -38,7 +38,7 @@
   /// Initialize a newly created instance based on the given JSON data.
   factory Notification.fromJson(Map json) {
     return Notification(json[Notification.EVENT],
-        json[Notification.PARAMS] as Map<String, Object>);
+        json[Notification.PARAMS] as Map<String, Object>?);
   }
 
   /// Return a table representing the structure of the Json object that will be
@@ -46,6 +46,7 @@
   Map<String, Object> toJson() {
     var jsonObject = <String, Object>{};
     jsonObject[EVENT] = event;
+    var params = this.params;
     if (params != null) {
       jsonObject[PARAMS] = params;
     }
@@ -77,84 +78,18 @@
   final String method;
 
   /// A table mapping the names of request parameters to their values.
-  final Map<String, Object> params;
+  final Map<String, Object?> params;
 
   /// The time (milliseconds since epoch) at which the client made the request
   /// or `null` if this information is not provided by the client.
-  final int clientRequestTime;
+  final int? clientRequestTime;
 
   /// Initialize a newly created [Request] to have the given [id] and [method]
   /// name. If [params] is supplied, it is used as the "params" map for the
   /// request. Otherwise an empty "params" map is allocated.
   Request(this.id, this.method,
-      [Map<String, Object> params, this.clientRequestTime])
-      : params = params ?? <String, Object>{};
-
-  /// Return a request parsed from the given json, or `null` if the [data] is
-  /// not a valid json representation of a request. The [data] is expected to
-  /// have the following format:
-  ///
-  ///   {
-  ///     'clientRequestTime': millisecondsSinceEpoch
-  ///     'id': String,
-  ///     'method': methodName,
-  ///     'params': {
-  ///       paramter_name: value
-  ///     }
-  ///   }
-  ///
-  /// where both the parameters and clientRequestTime are optional.
-  ///
-  /// The parameters can contain any number of name/value pairs. The
-  /// clientRequestTime must be an int representing the time at which the client
-  /// issued the request (milliseconds since epoch).
-  factory Request.fromJson(Map<String, Object> result) {
-    var id = result[Request.ID];
-    var method = result[Request.METHOD];
-    if (id is! String || method is! String) {
-      return null;
-    }
-    var time = result[Request.CLIENT_REQUEST_TIME];
-    if (time != null && time is! int) {
-      return null;
-    }
-    var params = result[Request.PARAMS];
-    if (params is Map || params == null) {
-      return Request(id, method, params as Map<String, Object>, time);
-    } else {
-      return null;
-    }
-  }
-
-  /// Return a request parsed from the given [data], or `null` if the [data] is
-  /// not a valid json representation of a request. The [data] is expected to
-  /// have the following format:
-  ///
-  ///   {
-  ///     'clientRequestTime': millisecondsSinceEpoch
-  ///     'id': String,
-  ///     'method': methodName,
-  ///     'params': {
-  ///       paramter_name: value
-  ///     }
-  ///   }
-  ///
-  /// where both the parameters and clientRequestTime are optional.
-  ///
-  /// The parameters can contain any number of name/value pairs. The
-  /// clientRequestTime must be an int representing the time at which the client
-  /// issued the request (milliseconds since epoch).
-  factory Request.fromString(String data) {
-    try {
-      var result = json.decode(data);
-      if (result is Map) {
-        return Request.fromJson(result as Map<String, dynamic>);
-      }
-      return null;
-    } catch (exception) {
-      return null;
-    }
-  }
+      [Map<String, Object?>? params, this.clientRequestTime])
+      : params = params ?? <String, Object?>{};
 
   @override
   int get hashCode {
@@ -179,13 +114,14 @@
     if (params.isNotEmpty) {
       jsonObject[PARAMS] = params;
     }
+    var clientRequestTime = this.clientRequestTime;
     if (clientRequestTime != null) {
       jsonObject[CLIENT_REQUEST_TIME] = clientRequestTime;
     }
     return jsonObject;
   }
 
-  bool _equalLists(List first, List second) {
+  bool _equalLists(List? first, List? second) {
     if (first == null) {
       return second == null;
     }
@@ -204,7 +140,7 @@
     return true;
   }
 
-  bool _equalMaps(Map first, Map second) {
+  bool _equalMaps(Map? first, Map? second) {
     if (first == null) {
       return second == null;
     }
@@ -225,7 +161,7 @@
     return true;
   }
 
-  bool _equalObjects(Object first, Object second) {
+  bool _equalObjects(Object? first, Object? second) {
     if (first == null) {
       return second == null;
     }
@@ -246,6 +182,72 @@
     }
     return first == second;
   }
+
+  /// Return a request parsed from the given json, or `null` if the [data] is
+  /// not a valid json representation of a request. The [data] is expected to
+  /// have the following format:
+  ///
+  ///   {
+  ///     'clientRequestTime': millisecondsSinceEpoch
+  ///     'id': String,
+  ///     'method': methodName,
+  ///     'params': {
+  ///       paramter_name: value
+  ///     }
+  ///   }
+  ///
+  /// where both the parameters and clientRequestTime are optional.
+  ///
+  /// The parameters can contain any number of name/value pairs. The
+  /// clientRequestTime must be an int representing the time at which the client
+  /// issued the request (milliseconds since epoch).
+  static Request? fromJson(Map<String, Object?> result) {
+    var id = result[Request.ID];
+    var method = result[Request.METHOD];
+    if (id is! String || method is! String) {
+      return null;
+    }
+    var time = result[Request.CLIENT_REQUEST_TIME];
+    if (time is! int?) {
+      return null;
+    }
+    var params = result[Request.PARAMS];
+    if (params is Map<String, Object?>?) {
+      return Request(id, method, params, time);
+    } else {
+      return null;
+    }
+  }
+
+  /// Return a request parsed from the given [data], or `null` if the [data] is
+  /// not a valid json representation of a request. The [data] is expected to
+  /// have the following format:
+  ///
+  ///   {
+  ///     'clientRequestTime': millisecondsSinceEpoch
+  ///     'id': String,
+  ///     'method': methodName,
+  ///     'params': {
+  ///       paramter_name: value
+  ///     }
+  ///   }
+  ///
+  /// where both the parameters and clientRequestTime are optional.
+  ///
+  /// The parameters can contain any number of name/value pairs. The
+  /// clientRequestTime must be an int representing the time at which the client
+  /// issued the request (milliseconds since epoch).
+  static Request? fromString(String data) {
+    try {
+      var result = json.decode(data);
+      if (result is Map<String, Object?>) {
+        return Request.fromJson(result);
+      }
+      return null;
+    } catch (exception) {
+      return null;
+    }
+  }
 }
 
 /// An exception that occurred during the handling of a request that requires
@@ -295,11 +297,11 @@
 
   /// The error that was caused by attempting to handle the request, or `null`
   /// if there was no error.
-  final RequestError error;
+  final RequestError? error;
 
   /// A table mapping the names of result fields to their values.  Should be
   /// `null` if there is no result to send.
-  Map<String, Object> result;
+  Map<String, Object?>? result;
 
   /// Initialize a newly created instance to represent a response to a request
   /// with the given [id].  If [_result] is provided, it will be used as the
@@ -334,30 +336,6 @@
             error: RequestError(RequestErrorCode.FORMAT_WITH_ERRORS,
                 'Error during `edit.format`: source contains syntax errors.'));
 
-  /// Initialize a newly created instance based on the given JSON data.
-  factory Response.fromJson(Map json) {
-    try {
-      Object id = json[Response.ID];
-      if (id is! String) {
-        return null;
-      }
-      Object error = json[Response.ERROR];
-      RequestError decodedError;
-      if (error is Map) {
-        decodedError =
-            RequestError.fromJson(ResponseDecoder(null), '.error', error);
-      }
-      Object result = json[Response.RESULT];
-      Map<String, Object> decodedResult;
-      if (result is Map) {
-        decodedResult = result as Map<String, Object>;
-      }
-      return Response(id, error: decodedError, result: decodedResult);
-    } catch (exception) {
-      return null;
-    }
-  }
-
   /// Initialize a newly created instance to represent the
   /// GET_ERRORS_INVALID_FILE error condition.
   Response.getErrorsInvalidFile(Request request)
@@ -527,12 +505,41 @@
   Map<String, Object> toJson() {
     var jsonObject = <String, Object>{};
     jsonObject[ID] = id;
+    var error = this.error;
     if (error != null) {
       jsonObject[ERROR] = error.toJson();
     }
+    var result = this.result;
     if (result != null) {
       jsonObject[RESULT] = result;
     }
     return jsonObject;
   }
+
+  /// Initialize a newly created instance based on the given JSON data.
+  static Response? fromJson(Map<String, Object?> json) {
+    try {
+      var id = json[Response.ID];
+      if (id is! String) {
+        return null;
+      }
+
+      RequestError? decodedError;
+      var error = json[Response.ERROR];
+      if (error is Map) {
+        decodedError =
+            RequestError.fromJson(ResponseDecoder(null), '.error', error);
+      }
+
+      Map<String, Object?>? decodedResult;
+      var result = json[Response.RESULT];
+      if (result is Map<String, Object?>) {
+        decodedResult = result;
+      }
+
+      return Response(id, error: decodedError, result: decodedResult);
+    } catch (exception) {
+      return null;
+    }
+  }
 }
diff --git a/pkg/analysis_server/lib/protocol/protocol_generated.dart b/pkg/analysis_server/lib/protocol/protocol_generated.dart
index 1ae7337..b434a60 100644
--- a/pkg/analysis_server/lib/protocol/protocol_generated.dart
+++ b/pkg/analysis_server/lib/protocol/protocol_generated.dart
@@ -21,23 +21,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisAnalyzedFilesParams implements HasToJson {
-  List<String> _directories;
-
   /// A list of the paths of the files that are being analyzed.
-  List<String> get directories => _directories;
+  List<String> directories;
 
-  /// A list of the paths of the files that are being analyzed.
-  set directories(List<String> value) {
-    assert(value != null);
-    _directories = value;
-  }
-
-  AnalysisAnalyzedFilesParams(List<String> directories) {
-    this.directories = directories;
-  }
+  AnalysisAnalyzedFilesParams(this.directories);
 
   factory AnalysisAnalyzedFilesParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       List<String> directories;
@@ -61,8 +51,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['directories'] = directories;
     return result;
   }
@@ -100,18 +90,8 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisClosingLabelsParams implements HasToJson {
-  String _file;
-
-  List<ClosingLabel> _labels;
-
   /// The file the closing labels relate to.
-  String get file => _file;
-
-  /// The file the closing labels relate to.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// Closing labels relevant to the file. Each item represents a useful label
   /// associated with some range with may be useful to display to the user
@@ -120,27 +100,12 @@
   /// and List arguments that span multiple lines. Note that the ranges that
   /// are returned can overlap each other because they may be associated with
   /// constructs that can be nested.
-  List<ClosingLabel> get labels => _labels;
+  List<ClosingLabel> labels;
 
-  /// Closing labels relevant to the file. Each item represents a useful label
-  /// associated with some range with may be useful to display to the user
-  /// within the editor at the end of the range to indicate what construct is
-  /// closed at that location. Closing labels include constructor/method calls
-  /// and List arguments that span multiple lines. Note that the ranges that
-  /// are returned can overlap each other because they may be associated with
-  /// constructs that can be nested.
-  set labels(List<ClosingLabel> value) {
-    assert(value != null);
-    _labels = value;
-  }
-
-  AnalysisClosingLabelsParams(String file, List<ClosingLabel> labels) {
-    this.file = file;
-    this.labels = labels;
-  }
+  AnalysisClosingLabelsParams(this.file, this.labels);
 
   factory AnalysisClosingLabelsParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -154,7 +119,7 @@
         labels = jsonDecoder.decodeList(
             jsonPath + '.labels',
             json['labels'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 ClosingLabel.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'labels');
@@ -173,8 +138,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     result['labels'] =
         labels.map((ClosingLabel value) => value.toJson()).toList();
@@ -216,39 +181,17 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisErrorFixes implements HasToJson {
-  AnalysisError _error;
-
-  List<SourceChange> _fixes;
-
   /// The error with which the fixes are associated.
-  AnalysisError get error => _error;
-
-  /// The error with which the fixes are associated.
-  set error(AnalysisError value) {
-    assert(value != null);
-    _error = value;
-  }
+  AnalysisError error;
 
   /// The fixes associated with the error.
-  List<SourceChange> get fixes => _fixes;
+  List<SourceChange> fixes;
 
-  /// The fixes associated with the error.
-  set fixes(List<SourceChange> value) {
-    assert(value != null);
-    _fixes = value;
-  }
-
-  AnalysisErrorFixes(AnalysisError error, {List<SourceChange> fixes}) {
-    this.error = error;
-    if (fixes == null) {
-      this.fixes = <SourceChange>[];
-    } else {
-      this.fixes = fixes;
-    }
-  }
+  AnalysisErrorFixes(this.error, {List<SourceChange>? fixes})
+      : fixes = fixes ?? <SourceChange>[];
 
   factory AnalysisErrorFixes.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       AnalysisError error;
@@ -263,7 +206,7 @@
         fixes = jsonDecoder.decodeList(
             jsonPath + '.fixes',
             json['fixes'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 SourceChange.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'fixes');
@@ -275,8 +218,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['error'] = error.toJson();
     result['fixes'] =
         fixes.map((SourceChange value) => value.toJson()).toList();
@@ -314,35 +257,16 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisErrorsParams implements HasToJson {
-  String _file;
-
-  List<AnalysisError> _errors;
-
   /// The file containing the errors.
-  String get file => _file;
-
-  /// The file containing the errors.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// The errors contained in the file.
-  List<AnalysisError> get errors => _errors;
+  List<AnalysisError> errors;
 
-  /// The errors contained in the file.
-  set errors(List<AnalysisError> value) {
-    assert(value != null);
-    _errors = value;
-  }
-
-  AnalysisErrorsParams(String file, List<AnalysisError> errors) {
-    this.file = file;
-    this.errors = errors;
-  }
+  AnalysisErrorsParams(this.file, this.errors);
 
   factory AnalysisErrorsParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -356,7 +280,7 @@
         errors = jsonDecoder.decodeList(
             jsonPath + '.errors',
             json['errors'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 AnalysisError.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'errors');
@@ -373,8 +297,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     result['errors'] =
         errors.map((AnalysisError value) => value.toJson()).toList();
@@ -415,23 +339,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisFlushResultsParams implements HasToJson {
-  List<String> _files;
-
   /// The files that are no longer being analyzed.
-  List<String> get files => _files;
+  List<String> files;
 
-  /// The files that are no longer being analyzed.
-  set files(List<String> value) {
-    assert(value != null);
-    _files = value;
-  }
-
-  AnalysisFlushResultsParams(List<String> files) {
-    this.files = files;
-  }
+  AnalysisFlushResultsParams(this.files);
 
   factory AnalysisFlushResultsParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       List<String> files;
@@ -455,8 +369,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['files'] = files;
     return result;
   }
@@ -493,35 +407,16 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisFoldingParams implements HasToJson {
-  String _file;
-
-  List<FoldingRegion> _regions;
-
   /// The file containing the folding regions.
-  String get file => _file;
-
-  /// The file containing the folding regions.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// The folding regions contained in the file.
-  List<FoldingRegion> get regions => _regions;
+  List<FoldingRegion> regions;
 
-  /// The folding regions contained in the file.
-  set regions(List<FoldingRegion> value) {
-    assert(value != null);
-    _regions = value;
-  }
-
-  AnalysisFoldingParams(String file, List<FoldingRegion> regions) {
-    this.file = file;
-    this.regions = regions;
-  }
+  AnalysisFoldingParams(this.file, this.regions);
 
   factory AnalysisFoldingParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -535,7 +430,7 @@
         regions = jsonDecoder.decodeList(
             jsonPath + '.regions',
             json['regions'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 FoldingRegion.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'regions');
@@ -552,8 +447,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     result['regions'] =
         regions.map((FoldingRegion value) => value.toJson()).toList();
@@ -594,23 +489,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisGetErrorsParams implements RequestParams {
-  String _file;
-
   /// The file for which errors are being requested.
-  String get file => _file;
+  String file;
 
-  /// The file for which errors are being requested.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
-
-  AnalysisGetErrorsParams(String file) {
-    this.file = file;
-  }
+  AnalysisGetErrorsParams(this.file);
 
   factory AnalysisGetErrorsParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -631,8 +516,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     return result;
   }
@@ -669,23 +554,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisGetErrorsResult implements ResponseResult {
-  List<AnalysisError> _errors;
-
   /// The errors associated with the file.
-  List<AnalysisError> get errors => _errors;
+  List<AnalysisError> errors;
 
-  /// The errors associated with the file.
-  set errors(List<AnalysisError> value) {
-    assert(value != null);
-    _errors = value;
-  }
-
-  AnalysisGetErrorsResult(List<AnalysisError> errors) {
-    this.errors = errors;
-  }
+  AnalysisGetErrorsResult(this.errors);
 
   factory AnalysisGetErrorsResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       List<AnalysisError> errors;
@@ -693,7 +568,7 @@
         errors = jsonDecoder.decodeList(
             jsonPath + '.errors',
             json['errors'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 AnalysisError.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'errors');
@@ -712,8 +587,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['errors'] =
         errors.map((AnalysisError value) => value.toJson()).toList();
     return result;
@@ -753,35 +628,16 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisGetHoverParams implements RequestParams {
-  String _file;
-
-  int _offset;
-
   /// The file in which hover information is being requested.
-  String get file => _file;
-
-  /// The file in which hover information is being requested.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// The offset for which hover information is being requested.
-  int get offset => _offset;
+  int offset;
 
-  /// The offset for which hover information is being requested.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
-
-  AnalysisGetHoverParams(String file, int offset) {
-    this.file = file;
-    this.offset = offset;
-  }
+  AnalysisGetHoverParams(this.file, this.offset);
 
   factory AnalysisGetHoverParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -808,8 +664,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     result['offset'] = offset;
     return result;
@@ -848,31 +704,17 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisGetHoverResult implements ResponseResult {
-  List<HoverInformation> _hovers;
-
   /// The hover information associated with the location. The list will be
   /// empty if no information could be determined for the location. The list
   /// can contain multiple items if the file is being analyzed in multiple
   /// contexts in conflicting ways (such as a part that is included in multiple
   /// libraries).
-  List<HoverInformation> get hovers => _hovers;
+  List<HoverInformation> hovers;
 
-  /// The hover information associated with the location. The list will be
-  /// empty if no information could be determined for the location. The list
-  /// can contain multiple items if the file is being analyzed in multiple
-  /// contexts in conflicting ways (such as a part that is included in multiple
-  /// libraries).
-  set hovers(List<HoverInformation> value) {
-    assert(value != null);
-    _hovers = value;
-  }
-
-  AnalysisGetHoverResult(List<HoverInformation> hovers) {
-    this.hovers = hovers;
-  }
+  AnalysisGetHoverResult(this.hovers);
 
   factory AnalysisGetHoverResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       List<HoverInformation> hovers;
@@ -880,7 +722,7 @@
         hovers = jsonDecoder.decodeList(
             jsonPath + '.hovers',
             json['hovers'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 HoverInformation.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'hovers');
@@ -899,8 +741,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['hovers'] =
         hovers.map((HoverInformation value) => value.toJson()).toList();
     return result;
@@ -941,47 +783,19 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisGetImportedElementsParams implements RequestParams {
-  String _file;
-
-  int _offset;
-
-  int _length;
-
   /// The file in which import information is being requested.
-  String get file => _file;
-
-  /// The file in which import information is being requested.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// The offset of the region for which import information is being requested.
-  int get offset => _offset;
-
-  /// The offset of the region for which import information is being requested.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
+  int offset;
 
   /// The length of the region for which import information is being requested.
-  int get length => _length;
+  int length;
 
-  /// The length of the region for which import information is being requested.
-  set length(int value) {
-    assert(value != null);
-    _length = value;
-  }
-
-  AnalysisGetImportedElementsParams(String file, int offset, int length) {
-    this.file = file;
-    this.offset = offset;
-    this.length = length;
-  }
+  AnalysisGetImportedElementsParams(this.file, this.offset, this.length);
 
   factory AnalysisGetImportedElementsParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -1015,8 +829,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     result['offset'] = offset;
     result['length'] = length;
@@ -1059,25 +873,14 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisGetImportedElementsResult implements ResponseResult {
-  List<ImportedElements> _elements;
-
   /// The information about the elements that are referenced in the specified
   /// region of the specified file that come from imported libraries.
-  List<ImportedElements> get elements => _elements;
+  List<ImportedElements> elements;
 
-  /// The information about the elements that are referenced in the specified
-  /// region of the specified file that come from imported libraries.
-  set elements(List<ImportedElements> value) {
-    assert(value != null);
-    _elements = value;
-  }
-
-  AnalysisGetImportedElementsResult(List<ImportedElements> elements) {
-    this.elements = elements;
-  }
+  AnalysisGetImportedElementsResult(this.elements);
 
   factory AnalysisGetImportedElementsResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       List<ImportedElements> elements;
@@ -1085,7 +888,7 @@
         elements = jsonDecoder.decodeList(
             jsonPath + '.elements',
             json['elements'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 ImportedElements.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'elements');
@@ -1105,8 +908,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['elements'] =
         elements.map((ImportedElements value) => value.toJson()).toList();
     return result;
@@ -1142,7 +945,7 @@
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisGetLibraryDependenciesParams implements RequestParams {
   @override
-  Map<String, dynamic> toJson() => <String, dynamic>{};
+  Map<String, Object> toJson() => <String, Object>{};
 
   @override
   Request toRequest(String id) {
@@ -1172,42 +975,19 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisGetLibraryDependenciesResult implements ResponseResult {
-  List<String> _libraries;
-
-  Map<String, Map<String, List<String>>> _packageMap;
-
   /// A list of the paths of library elements referenced by files in existing
   /// analysis roots.
-  List<String> get libraries => _libraries;
-
-  /// A list of the paths of library elements referenced by files in existing
-  /// analysis roots.
-  set libraries(List<String> value) {
-    assert(value != null);
-    _libraries = value;
-  }
+  List<String> libraries;
 
   /// A mapping from context source roots to package maps which map package
   /// names to source directories for use in client-side package URI
   /// resolution.
-  Map<String, Map<String, List<String>>> get packageMap => _packageMap;
+  Map<String, Map<String, List<String>>> packageMap;
 
-  /// A mapping from context source roots to package maps which map package
-  /// names to source directories for use in client-side package URI
-  /// resolution.
-  set packageMap(Map<String, Map<String, List<String>>> value) {
-    assert(value != null);
-    _packageMap = value;
-  }
-
-  AnalysisGetLibraryDependenciesResult(List<String> libraries,
-      Map<String, Map<String, List<String>>> packageMap) {
-    this.libraries = libraries;
-    this.packageMap = packageMap;
-  }
+  AnalysisGetLibraryDependenciesResult(this.libraries, this.packageMap);
 
   factory AnalysisGetLibraryDependenciesResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       List<String> libraries;
@@ -1221,9 +1001,9 @@
       if (json.containsKey('packageMap')) {
         packageMap = jsonDecoder.decodeMap(
             jsonPath + '.packageMap', json['packageMap'],
-            valueDecoder: (String jsonPath, Object json) =>
+            valueDecoder: (String jsonPath, Object? json) =>
                 jsonDecoder.decodeMap(jsonPath, json,
-                    valueDecoder: (String jsonPath, Object json) => jsonDecoder
+                    valueDecoder: (String jsonPath, Object? json) => jsonDecoder
                         .decodeList(jsonPath, json, jsonDecoder.decodeString)));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'packageMap');
@@ -1243,8 +1023,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['libraries'] = libraries;
     result['packageMap'] = packageMap;
     return result;
@@ -1295,51 +1075,21 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisGetNavigationParams implements RequestParams {
-  String _file;
-
-  int _offset;
-
-  int _length;
-
   /// The file in which navigation information is being requested.
-  String get file => _file;
-
-  /// The file in which navigation information is being requested.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// The offset of the region for which navigation information is being
   /// requested.
-  int get offset => _offset;
-
-  /// The offset of the region for which navigation information is being
-  /// requested.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
+  int offset;
 
   /// The length of the region for which navigation information is being
   /// requested.
-  int get length => _length;
+  int length;
 
-  /// The length of the region for which navigation information is being
-  /// requested.
-  set length(int value) {
-    assert(value != null);
-    _length = value;
-  }
-
-  AnalysisGetNavigationParams(String file, int offset, int length) {
-    this.file = file;
-    this.offset = offset;
-    this.length = length;
-  }
+  AnalysisGetNavigationParams(this.file, this.offset, this.length);
 
   factory AnalysisGetNavigationParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -1373,8 +1123,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     result['offset'] = offset;
     result['length'] = length;
@@ -1419,52 +1169,21 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisGetNavigationResult implements ResponseResult {
-  List<String> _files;
-
-  List<NavigationTarget> _targets;
-
-  List<NavigationRegion> _regions;
-
   /// A list of the paths of files that are referenced by the navigation
   /// targets.
-  List<String> get files => _files;
-
-  /// A list of the paths of files that are referenced by the navigation
-  /// targets.
-  set files(List<String> value) {
-    assert(value != null);
-    _files = value;
-  }
+  List<String> files;
 
   /// A list of the navigation targets that are referenced by the navigation
   /// regions.
-  List<NavigationTarget> get targets => _targets;
-
-  /// A list of the navigation targets that are referenced by the navigation
-  /// regions.
-  set targets(List<NavigationTarget> value) {
-    assert(value != null);
-    _targets = value;
-  }
+  List<NavigationTarget> targets;
 
   /// A list of the navigation regions within the requested region of the file.
-  List<NavigationRegion> get regions => _regions;
+  List<NavigationRegion> regions;
 
-  /// A list of the navigation regions within the requested region of the file.
-  set regions(List<NavigationRegion> value) {
-    assert(value != null);
-    _regions = value;
-  }
-
-  AnalysisGetNavigationResult(List<String> files,
-      List<NavigationTarget> targets, List<NavigationRegion> regions) {
-    this.files = files;
-    this.targets = targets;
-    this.regions = regions;
-  }
+  AnalysisGetNavigationResult(this.files, this.targets, this.regions);
 
   factory AnalysisGetNavigationResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       List<String> files;
@@ -1479,7 +1198,7 @@
         targets = jsonDecoder.decodeList(
             jsonPath + '.targets',
             json['targets'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 NavigationTarget.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'targets');
@@ -1489,7 +1208,7 @@
         regions = jsonDecoder.decodeList(
             jsonPath + '.regions',
             json['regions'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 NavigationRegion.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'regions');
@@ -1509,8 +1228,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['files'] = files;
     result['targets'] =
         targets.map((NavigationTarget value) => value.toJson()).toList();
@@ -1557,23 +1276,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisGetReachableSourcesParams implements RequestParams {
-  String _file;
-
   /// The file for which reachable source information is being requested.
-  String get file => _file;
+  String file;
 
-  /// The file for which reachable source information is being requested.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
-
-  AnalysisGetReachableSourcesParams(String file) {
-    this.file = file;
-  }
+  AnalysisGetReachableSourcesParams(this.file);
 
   factory AnalysisGetReachableSourcesParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -1595,8 +1304,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     return result;
   }
@@ -1633,8 +1342,6 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisGetReachableSourcesResult implements ResponseResult {
-  Map<String, List<String>> _sources;
-
   /// A mapping from source URIs to directly reachable source URIs. For
   /// example, a file "foo.dart" that imports "bar.dart" would have the
   /// corresponding mapping { "file:///foo.dart" : ["file:///bar.dart"] }. If
@@ -1642,32 +1349,18 @@
   /// the URI "file:///bar.dart" to them. To check if a specific URI is
   /// reachable from a given file, clients can check for its presence in the
   /// resulting key set.
-  Map<String, List<String>> get sources => _sources;
+  Map<String, List<String>> sources;
 
-  /// A mapping from source URIs to directly reachable source URIs. For
-  /// example, a file "foo.dart" that imports "bar.dart" would have the
-  /// corresponding mapping { "file:///foo.dart" : ["file:///bar.dart"] }. If
-  /// "bar.dart" has further imports (or exports) there will be a mapping from
-  /// the URI "file:///bar.dart" to them. To check if a specific URI is
-  /// reachable from a given file, clients can check for its presence in the
-  /// resulting key set.
-  set sources(Map<String, List<String>> value) {
-    assert(value != null);
-    _sources = value;
-  }
-
-  AnalysisGetReachableSourcesResult(Map<String, List<String>> sources) {
-    this.sources = sources;
-  }
+  AnalysisGetReachableSourcesResult(this.sources);
 
   factory AnalysisGetReachableSourcesResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       Map<String, List<String>> sources;
       if (json.containsKey('sources')) {
         sources = jsonDecoder.decodeMap(jsonPath + '.sources', json['sources'],
-            valueDecoder: (String jsonPath, Object json) => jsonDecoder
+            valueDecoder: (String jsonPath, Object? json) => jsonDecoder
                 .decodeList(jsonPath, json, jsonDecoder.decodeString));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'sources');
@@ -1687,8 +1380,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['sources'] = sources;
     return result;
   }
@@ -1730,35 +1423,16 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisGetSignatureParams implements RequestParams {
-  String _file;
-
-  int _offset;
-
   /// The file in which signature information is being requested.
-  String get file => _file;
-
-  /// The file in which signature information is being requested.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// The location for which signature information is being requested.
-  int get offset => _offset;
+  int offset;
 
-  /// The location for which signature information is being requested.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
-
-  AnalysisGetSignatureParams(String file, int offset) {
-    this.file = file;
-    this.offset = offset;
-  }
+  AnalysisGetSignatureParams(this.file, this.offset);
 
   factory AnalysisGetSignatureParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -1786,8 +1460,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     result['offset'] = offset;
     return result;
@@ -1828,57 +1502,24 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisGetSignatureResult implements ResponseResult {
-  String _name;
-
-  List<ParameterInfo> _parameters;
-
-  String _dartdoc;
-
   /// The name of the function being invoked at the given offset.
-  String get name => _name;
-
-  /// The name of the function being invoked at the given offset.
-  set name(String value) {
-    assert(value != null);
-    _name = value;
-  }
+  String name;
 
   /// A list of information about each of the parameters of the function being
   /// invoked.
-  List<ParameterInfo> get parameters => _parameters;
-
-  /// A list of information about each of the parameters of the function being
-  /// invoked.
-  set parameters(List<ParameterInfo> value) {
-    assert(value != null);
-    _parameters = value;
-  }
+  List<ParameterInfo> parameters;
 
   /// The dartdoc associated with the function being invoked. Other than the
   /// removal of the comment delimiters, including leading asterisks in the
   /// case of a block comment, the dartdoc is unprocessed markdown. This data
   /// is omitted if there is no referenced element, or if the element has no
   /// dartdoc.
-  String get dartdoc => _dartdoc;
+  String? dartdoc;
 
-  /// The dartdoc associated with the function being invoked. Other than the
-  /// removal of the comment delimiters, including leading asterisks in the
-  /// case of a block comment, the dartdoc is unprocessed markdown. This data
-  /// is omitted if there is no referenced element, or if the element has no
-  /// dartdoc.
-  set dartdoc(String value) {
-    _dartdoc = value;
-  }
-
-  AnalysisGetSignatureResult(String name, List<ParameterInfo> parameters,
-      {String dartdoc}) {
-    this.name = name;
-    this.parameters = parameters;
-    this.dartdoc = dartdoc;
-  }
+  AnalysisGetSignatureResult(this.name, this.parameters, {this.dartdoc});
 
   factory AnalysisGetSignatureResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String name;
@@ -1892,12 +1533,12 @@
         parameters = jsonDecoder.decodeList(
             jsonPath + '.parameters',
             json['parameters'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 ParameterInfo.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'parameters');
       }
-      String dartdoc;
+      String? dartdoc;
       if (json.containsKey('dartdoc')) {
         dartdoc =
             jsonDecoder.decodeString(jsonPath + '.dartdoc', json['dartdoc']);
@@ -1917,11 +1558,12 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['name'] = name;
     result['parameters'] =
         parameters.map((ParameterInfo value) => value.toJson()).toList();
+    var dartdoc = this.dartdoc;
     if (dartdoc != null) {
       result['dartdoc'] = dartdoc;
     }
@@ -1966,43 +1608,20 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisHighlightsParams implements HasToJson {
-  String _file;
-
-  List<HighlightRegion> _regions;
-
   /// The file containing the highlight regions.
-  String get file => _file;
-
-  /// The file containing the highlight regions.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// The highlight regions contained in the file. Each highlight region
   /// represents a particular syntactic or semantic meaning associated with
   /// some range. Note that the highlight regions that are returned can overlap
   /// other highlight regions if there is more than one meaning associated with
   /// a particular region.
-  List<HighlightRegion> get regions => _regions;
+  List<HighlightRegion> regions;
 
-  /// The highlight regions contained in the file. Each highlight region
-  /// represents a particular syntactic or semantic meaning associated with
-  /// some range. Note that the highlight regions that are returned can overlap
-  /// other highlight regions if there is more than one meaning associated with
-  /// a particular region.
-  set regions(List<HighlightRegion> value) {
-    assert(value != null);
-    _regions = value;
-  }
-
-  AnalysisHighlightsParams(String file, List<HighlightRegion> regions) {
-    this.file = file;
-    this.regions = regions;
-  }
+  AnalysisHighlightsParams(this.file, this.regions);
 
   factory AnalysisHighlightsParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -2016,7 +1635,7 @@
         regions = jsonDecoder.decodeList(
             jsonPath + '.regions',
             json['regions'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 HighlightRegion.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'regions');
@@ -2033,8 +1652,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     result['regions'] =
         regions.map((HighlightRegion value) => value.toJson()).toList();
@@ -2077,48 +1696,19 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisImplementedParams implements HasToJson {
-  String _file;
-
-  List<ImplementedClass> _classes;
-
-  List<ImplementedMember> _members;
-
   /// The file with which the implementations are associated.
-  String get file => _file;
-
-  /// The file with which the implementations are associated.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// The classes defined in the file that are implemented or extended.
-  List<ImplementedClass> get classes => _classes;
-
-  /// The classes defined in the file that are implemented or extended.
-  set classes(List<ImplementedClass> value) {
-    assert(value != null);
-    _classes = value;
-  }
+  List<ImplementedClass> classes;
 
   /// The member defined in the file that are implemented or overridden.
-  List<ImplementedMember> get members => _members;
+  List<ImplementedMember> members;
 
-  /// The member defined in the file that are implemented or overridden.
-  set members(List<ImplementedMember> value) {
-    assert(value != null);
-    _members = value;
-  }
-
-  AnalysisImplementedParams(String file, List<ImplementedClass> classes,
-      List<ImplementedMember> members) {
-    this.file = file;
-    this.classes = classes;
-    this.members = members;
-  }
+  AnalysisImplementedParams(this.file, this.classes, this.members);
 
   factory AnalysisImplementedParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -2132,7 +1722,7 @@
         classes = jsonDecoder.decodeList(
             jsonPath + '.classes',
             json['classes'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 ImplementedClass.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'classes');
@@ -2142,7 +1732,7 @@
         members = jsonDecoder.decodeList(
             jsonPath + '.members',
             json['members'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 ImplementedMember.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'members');
@@ -2160,8 +1750,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     result['classes'] =
         classes.map((ImplementedClass value) => value.toJson()).toList();
@@ -2210,63 +1800,24 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisInvalidateParams implements HasToJson {
-  String _file;
-
-  int _offset;
-
-  int _length;
-
-  int _delta;
-
   /// The file whose information has been invalidated.
-  String get file => _file;
-
-  /// The file whose information has been invalidated.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// The offset of the invalidated region.
-  int get offset => _offset;
-
-  /// The offset of the invalidated region.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
+  int offset;
 
   /// The length of the invalidated region.
-  int get length => _length;
-
-  /// The length of the invalidated region.
-  set length(int value) {
-    assert(value != null);
-    _length = value;
-  }
+  int length;
 
   /// The delta to be applied to the offsets in information that follows the
   /// invalidated region in order to update it so that it doesn't need to be
   /// re-requested.
-  int get delta => _delta;
+  int delta;
 
-  /// The delta to be applied to the offsets in information that follows the
-  /// invalidated region in order to update it so that it doesn't need to be
-  /// re-requested.
-  set delta(int value) {
-    assert(value != null);
-    _delta = value;
-  }
-
-  AnalysisInvalidateParams(String file, int offset, int length, int delta) {
-    this.file = file;
-    this.offset = offset;
-    this.length = length;
-    this.delta = delta;
-  }
+  AnalysisInvalidateParams(this.file, this.offset, this.length, this.delta);
 
   factory AnalysisInvalidateParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -2305,8 +1856,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     result['offset'] = offset;
     result['length'] = length;
@@ -2354,22 +1905,8 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisNavigationParams implements HasToJson {
-  String _file;
-
-  List<NavigationRegion> _regions;
-
-  List<NavigationTarget> _targets;
-
-  List<String> _files;
-
   /// The file containing the navigation regions.
-  String get file => _file;
-
-  /// The file containing the navigation regions.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// The navigation regions contained in the file. The regions are sorted by
   /// their offsets. Each navigation region represents a list of targets
@@ -2378,52 +1915,20 @@
   /// multiple libraries or in Dart code that is compiled against multiple
   /// versions of a package. Note that the navigation regions that are returned
   /// do not overlap other navigation regions.
-  List<NavigationRegion> get regions => _regions;
-
-  /// The navigation regions contained in the file. The regions are sorted by
-  /// their offsets. Each navigation region represents a list of targets
-  /// associated with some range. The lists will usually contain a single
-  /// target, but can contain more in the case of a part that is included in
-  /// multiple libraries or in Dart code that is compiled against multiple
-  /// versions of a package. Note that the navigation regions that are returned
-  /// do not overlap other navigation regions.
-  set regions(List<NavigationRegion> value) {
-    assert(value != null);
-    _regions = value;
-  }
+  List<NavigationRegion> regions;
 
   /// The navigation targets referenced in the file. They are referenced by
   /// NavigationRegions by their index in this array.
-  List<NavigationTarget> get targets => _targets;
-
-  /// The navigation targets referenced in the file. They are referenced by
-  /// NavigationRegions by their index in this array.
-  set targets(List<NavigationTarget> value) {
-    assert(value != null);
-    _targets = value;
-  }
+  List<NavigationTarget> targets;
 
   /// The files containing navigation targets referenced in the file. They are
   /// referenced by NavigationTargets by their index in this array.
-  List<String> get files => _files;
+  List<String> files;
 
-  /// The files containing navigation targets referenced in the file. They are
-  /// referenced by NavigationTargets by their index in this array.
-  set files(List<String> value) {
-    assert(value != null);
-    _files = value;
-  }
-
-  AnalysisNavigationParams(String file, List<NavigationRegion> regions,
-      List<NavigationTarget> targets, List<String> files) {
-    this.file = file;
-    this.regions = regions;
-    this.targets = targets;
-    this.files = files;
-  }
+  AnalysisNavigationParams(this.file, this.regions, this.targets, this.files);
 
   factory AnalysisNavigationParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -2437,7 +1942,7 @@
         regions = jsonDecoder.decodeList(
             jsonPath + '.regions',
             json['regions'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 NavigationRegion.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'regions');
@@ -2447,7 +1952,7 @@
         targets = jsonDecoder.decodeList(
             jsonPath + '.targets',
             json['targets'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 NavigationTarget.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'targets');
@@ -2471,8 +1976,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     result['regions'] =
         regions.map((NavigationRegion value) => value.toJson()).toList();
@@ -2522,35 +2027,16 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisOccurrencesParams implements HasToJson {
-  String _file;
-
-  List<Occurrences> _occurrences;
-
   /// The file in which the references occur.
-  String get file => _file;
-
-  /// The file in which the references occur.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// The occurrences of references to elements within the file.
-  List<Occurrences> get occurrences => _occurrences;
+  List<Occurrences> occurrences;
 
-  /// The occurrences of references to elements within the file.
-  set occurrences(List<Occurrences> value) {
-    assert(value != null);
-    _occurrences = value;
-  }
-
-  AnalysisOccurrencesParams(String file, List<Occurrences> occurrences) {
-    this.file = file;
-    this.occurrences = occurrences;
-  }
+  AnalysisOccurrencesParams(this.file, this.occurrences);
 
   factory AnalysisOccurrencesParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -2564,7 +2050,7 @@
         occurrences = jsonDecoder.decodeList(
             jsonPath + '.occurrences',
             json['occurrences'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 Occurrences.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'occurrences');
@@ -2582,8 +2068,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     result['occurrences'] =
         occurrences.map((Occurrences value) => value.toJson()).toList();
@@ -2631,176 +2117,96 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisOptions implements HasToJson {
-  bool _enableAsync;
-
-  bool _enableDeferredLoading;
-
-  bool _enableEnums;
-
-  bool _enableNullAwareOperators;
-
-  bool _enableSuperMixins;
-
-  bool _generateDart2jsHints;
-
-  bool _generateHints;
-
-  bool _generateLints;
-
   /// Deprecated: this feature is always enabled.
   ///
   /// True if the client wants to enable support for the proposed async
   /// feature.
-  bool get enableAsync => _enableAsync;
-
-  /// Deprecated: this feature is always enabled.
-  ///
-  /// True if the client wants to enable support for the proposed async
-  /// feature.
-  set enableAsync(bool value) {
-    _enableAsync = value;
-  }
+  bool? enableAsync;
 
   /// Deprecated: this feature is always enabled.
   ///
   /// True if the client wants to enable support for the proposed deferred
   /// loading feature.
-  bool get enableDeferredLoading => _enableDeferredLoading;
-
-  /// Deprecated: this feature is always enabled.
-  ///
-  /// True if the client wants to enable support for the proposed deferred
-  /// loading feature.
-  set enableDeferredLoading(bool value) {
-    _enableDeferredLoading = value;
-  }
+  bool? enableDeferredLoading;
 
   /// Deprecated: this feature is always enabled.
   ///
   /// True if the client wants to enable support for the proposed enum feature.
-  bool get enableEnums => _enableEnums;
-
-  /// Deprecated: this feature is always enabled.
-  ///
-  /// True if the client wants to enable support for the proposed enum feature.
-  set enableEnums(bool value) {
-    _enableEnums = value;
-  }
+  bool? enableEnums;
 
   /// Deprecated: this feature is always enabled.
   ///
   /// True if the client wants to enable support for the proposed "null aware
   /// operators" feature.
-  bool get enableNullAwareOperators => _enableNullAwareOperators;
-
-  /// Deprecated: this feature is always enabled.
-  ///
-  /// True if the client wants to enable support for the proposed "null aware
-  /// operators" feature.
-  set enableNullAwareOperators(bool value) {
-    _enableNullAwareOperators = value;
-  }
+  bool? enableNullAwareOperators;
 
   /// True if the client wants to enable support for the proposed "less
   /// restricted mixins" proposal (DEP 34).
-  bool get enableSuperMixins => _enableSuperMixins;
-
-  /// True if the client wants to enable support for the proposed "less
-  /// restricted mixins" proposal (DEP 34).
-  set enableSuperMixins(bool value) {
-    _enableSuperMixins = value;
-  }
+  bool? enableSuperMixins;
 
   /// True if hints that are specific to dart2js should be generated. This
   /// option is ignored if generateHints is false.
-  bool get generateDart2jsHints => _generateDart2jsHints;
-
-  /// True if hints that are specific to dart2js should be generated. This
-  /// option is ignored if generateHints is false.
-  set generateDart2jsHints(bool value) {
-    _generateDart2jsHints = value;
-  }
+  bool? generateDart2jsHints;
 
   /// True if hints should be generated as part of generating errors and
   /// warnings.
-  bool get generateHints => _generateHints;
-
-  /// True if hints should be generated as part of generating errors and
-  /// warnings.
-  set generateHints(bool value) {
-    _generateHints = value;
-  }
+  bool? generateHints;
 
   /// True if lints should be generated as part of generating errors and
   /// warnings.
-  bool get generateLints => _generateLints;
-
-  /// True if lints should be generated as part of generating errors and
-  /// warnings.
-  set generateLints(bool value) {
-    _generateLints = value;
-  }
+  bool? generateLints;
 
   AnalysisOptions(
-      {bool enableAsync,
-      bool enableDeferredLoading,
-      bool enableEnums,
-      bool enableNullAwareOperators,
-      bool enableSuperMixins,
-      bool generateDart2jsHints,
-      bool generateHints,
-      bool generateLints}) {
-    this.enableAsync = enableAsync;
-    this.enableDeferredLoading = enableDeferredLoading;
-    this.enableEnums = enableEnums;
-    this.enableNullAwareOperators = enableNullAwareOperators;
-    this.enableSuperMixins = enableSuperMixins;
-    this.generateDart2jsHints = generateDart2jsHints;
-    this.generateHints = generateHints;
-    this.generateLints = generateLints;
-  }
+      {this.enableAsync,
+      this.enableDeferredLoading,
+      this.enableEnums,
+      this.enableNullAwareOperators,
+      this.enableSuperMixins,
+      this.generateDart2jsHints,
+      this.generateHints,
+      this.generateLints});
 
   factory AnalysisOptions.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
-      bool enableAsync;
+      bool? enableAsync;
       if (json.containsKey('enableAsync')) {
         enableAsync = jsonDecoder.decodeBool(
             jsonPath + '.enableAsync', json['enableAsync']);
       }
-      bool enableDeferredLoading;
+      bool? enableDeferredLoading;
       if (json.containsKey('enableDeferredLoading')) {
         enableDeferredLoading = jsonDecoder.decodeBool(
             jsonPath + '.enableDeferredLoading', json['enableDeferredLoading']);
       }
-      bool enableEnums;
+      bool? enableEnums;
       if (json.containsKey('enableEnums')) {
         enableEnums = jsonDecoder.decodeBool(
             jsonPath + '.enableEnums', json['enableEnums']);
       }
-      bool enableNullAwareOperators;
+      bool? enableNullAwareOperators;
       if (json.containsKey('enableNullAwareOperators')) {
         enableNullAwareOperators = jsonDecoder.decodeBool(
             jsonPath + '.enableNullAwareOperators',
             json['enableNullAwareOperators']);
       }
-      bool enableSuperMixins;
+      bool? enableSuperMixins;
       if (json.containsKey('enableSuperMixins')) {
         enableSuperMixins = jsonDecoder.decodeBool(
             jsonPath + '.enableSuperMixins', json['enableSuperMixins']);
       }
-      bool generateDart2jsHints;
+      bool? generateDart2jsHints;
       if (json.containsKey('generateDart2jsHints')) {
         generateDart2jsHints = jsonDecoder.decodeBool(
             jsonPath + '.generateDart2jsHints', json['generateDart2jsHints']);
       }
-      bool generateHints;
+      bool? generateHints;
       if (json.containsKey('generateHints')) {
         generateHints = jsonDecoder.decodeBool(
             jsonPath + '.generateHints', json['generateHints']);
       }
-      bool generateLints;
+      bool? generateLints;
       if (json.containsKey('generateLints')) {
         generateLints = jsonDecoder.decodeBool(
             jsonPath + '.generateLints', json['generateLints']);
@@ -2820,29 +2226,37 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
+    var enableAsync = this.enableAsync;
     if (enableAsync != null) {
       result['enableAsync'] = enableAsync;
     }
+    var enableDeferredLoading = this.enableDeferredLoading;
     if (enableDeferredLoading != null) {
       result['enableDeferredLoading'] = enableDeferredLoading;
     }
+    var enableEnums = this.enableEnums;
     if (enableEnums != null) {
       result['enableEnums'] = enableEnums;
     }
+    var enableNullAwareOperators = this.enableNullAwareOperators;
     if (enableNullAwareOperators != null) {
       result['enableNullAwareOperators'] = enableNullAwareOperators;
     }
+    var enableSuperMixins = this.enableSuperMixins;
     if (enableSuperMixins != null) {
       result['enableSuperMixins'] = enableSuperMixins;
     }
+    var generateDart2jsHints = this.generateDart2jsHints;
     if (generateDart2jsHints != null) {
       result['generateDart2jsHints'] = generateDart2jsHints;
     }
+    var generateHints = this.generateHints;
     if (generateHints != null) {
       result['generateHints'] = generateHints;
     }
+    var generateLints = this.generateLints;
     if (generateLints != null) {
       result['generateLints'] = generateLints;
     }
@@ -2893,67 +2307,26 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisOutlineParams implements HasToJson {
-  String _file;
-
-  FileKind _kind;
-
-  String _libraryName;
-
-  Outline _outline;
-
   /// The file with which the outline is associated.
-  String get file => _file;
-
-  /// The file with which the outline is associated.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// The kind of the file.
-  FileKind get kind => _kind;
-
-  /// The kind of the file.
-  set kind(FileKind value) {
-    assert(value != null);
-    _kind = value;
-  }
+  FileKind kind;
 
   /// The name of the library defined by the file using a "library" directive,
   /// or referenced by a "part of" directive. If both "library" and "part of"
   /// directives are present, then the "library" directive takes precedence.
   /// This field will be omitted if the file has neither "library" nor "part
   /// of" directives.
-  String get libraryName => _libraryName;
-
-  /// The name of the library defined by the file using a "library" directive,
-  /// or referenced by a "part of" directive. If both "library" and "part of"
-  /// directives are present, then the "library" directive takes precedence.
-  /// This field will be omitted if the file has neither "library" nor "part
-  /// of" directives.
-  set libraryName(String value) {
-    _libraryName = value;
-  }
+  String? libraryName;
 
   /// The outline associated with the file.
-  Outline get outline => _outline;
+  Outline outline;
 
-  /// The outline associated with the file.
-  set outline(Outline value) {
-    assert(value != null);
-    _outline = value;
-  }
-
-  AnalysisOutlineParams(String file, FileKind kind, Outline outline,
-      {String libraryName}) {
-    this.file = file;
-    this.kind = kind;
-    this.libraryName = libraryName;
-    this.outline = outline;
-  }
+  AnalysisOutlineParams(this.file, this.kind, this.outline, {this.libraryName});
 
   factory AnalysisOutlineParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -2968,7 +2341,7 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'kind');
       }
-      String libraryName;
+      String? libraryName;
       if (json.containsKey('libraryName')) {
         libraryName = jsonDecoder.decodeString(
             jsonPath + '.libraryName', json['libraryName']);
@@ -2993,10 +2366,11 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     result['kind'] = kind.toJson();
+    var libraryName = this.libraryName;
     if (libraryName != null) {
       result['libraryName'] = libraryName;
     }
@@ -3042,35 +2416,16 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisOverridesParams implements HasToJson {
-  String _file;
-
-  List<Override> _overrides;
-
   /// The file with which the overrides are associated.
-  String get file => _file;
-
-  /// The file with which the overrides are associated.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// The overrides associated with the file.
-  List<Override> get overrides => _overrides;
+  List<Override> overrides;
 
-  /// The overrides associated with the file.
-  set overrides(List<Override> value) {
-    assert(value != null);
-    _overrides = value;
-  }
-
-  AnalysisOverridesParams(String file, List<Override> overrides) {
-    this.file = file;
-    this.overrides = overrides;
-  }
+  AnalysisOverridesParams(this.file, this.overrides);
 
   factory AnalysisOverridesParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -3084,7 +2439,7 @@
         overrides = jsonDecoder.decodeList(
             jsonPath + '.overrides',
             json['overrides'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 Override.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'overrides');
@@ -3101,8 +2456,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     result['overrides'] =
         overrides.map((Override value) => value.toJson()).toList();
@@ -3140,7 +2495,7 @@
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisReanalyzeParams implements RequestParams {
   @override
-  Map<String, dynamic> toJson() => <String, dynamic>{};
+  Map<String, Object> toJson() => <String, Object>{};
 
   @override
   Request toRequest(String id) {
@@ -3166,7 +2521,7 @@
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisReanalyzeResult implements ResponseResult {
   @override
-  Map<String, dynamic> toJson() => <String, dynamic>{};
+  Map<String, Object> toJson() => <String, Object>{};
 
   @override
   Response toResponse(String id) {
@@ -3267,7 +2622,7 @@
   }
 
   factory AnalysisService.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     if (json is String) {
       try {
         return AnalysisService(json);
@@ -3294,31 +2649,12 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisSetAnalysisRootsParams implements RequestParams {
-  List<String> _included;
-
-  List<String> _excluded;
-
-  Map<String, String> _packageRoots;
-
   /// A list of the files and directories that should be analyzed.
-  List<String> get included => _included;
-
-  /// A list of the files and directories that should be analyzed.
-  set included(List<String> value) {
-    assert(value != null);
-    _included = value;
-  }
+  List<String> included;
 
   /// A list of the files and directories within the included directories that
   /// should not be analyzed.
-  List<String> get excluded => _excluded;
-
-  /// A list of the files and directories within the included directories that
-  /// should not be analyzed.
-  set excluded(List<String> value) {
-    assert(value != null);
-    _excluded = value;
-  }
+  List<String> excluded;
 
   /// A mapping from source directories to package roots that should override
   /// the normal package: URI resolution mechanism.
@@ -3332,33 +2668,13 @@
   /// their package: URI's resolved using the normal pubspec.yaml mechanism. If
   /// this field is absent, or the empty map is specified, that indicates that
   /// the normal pubspec.yaml mechanism should always be used.
-  Map<String, String> get packageRoots => _packageRoots;
+  Map<String, String>? packageRoots;
 
-  /// A mapping from source directories to package roots that should override
-  /// the normal package: URI resolution mechanism.
-  ///
-  /// If a package root is a file, then the analyzer will behave as though that
-  /// file is a ".packages" file in the source directory. The effect is the
-  /// same as specifying the file as a "--packages" parameter to the Dart VM
-  /// when executing any Dart file inside the source directory.
-  ///
-  /// Files in any directories that are not overridden by this mapping have
-  /// their package: URI's resolved using the normal pubspec.yaml mechanism. If
-  /// this field is absent, or the empty map is specified, that indicates that
-  /// the normal pubspec.yaml mechanism should always be used.
-  set packageRoots(Map<String, String> value) {
-    _packageRoots = value;
-  }
-
-  AnalysisSetAnalysisRootsParams(List<String> included, List<String> excluded,
-      {Map<String, String> packageRoots}) {
-    this.included = included;
-    this.excluded = excluded;
-    this.packageRoots = packageRoots;
-  }
+  AnalysisSetAnalysisRootsParams(this.included, this.excluded,
+      {this.packageRoots});
 
   factory AnalysisSetAnalysisRootsParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       List<String> included;
@@ -3375,7 +2691,7 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'excluded');
       }
-      Map<String, String> packageRoots;
+      Map<String, String>? packageRoots;
       if (json.containsKey('packageRoots')) {
         packageRoots = jsonDecoder.decodeMap(
             jsonPath + '.packageRoots', json['packageRoots'],
@@ -3395,10 +2711,11 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['included'] = included;
     result['excluded'] = excluded;
+    var packageRoots = this.packageRoots;
     if (packageRoots != null) {
       result['packageRoots'] = packageRoots;
     }
@@ -3440,7 +2757,7 @@
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisSetAnalysisRootsResult implements ResponseResult {
   @override
-  Map<String, dynamic> toJson() => <String, dynamic>{};
+  Map<String, Object> toJson() => <String, Object>{};
 
   @override
   Response toResponse(String id) {
@@ -3469,24 +2786,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisSetGeneralSubscriptionsParams implements RequestParams {
-  List<GeneralAnalysisService> _subscriptions;
-
   /// A list of the services being subscribed to.
-  List<GeneralAnalysisService> get subscriptions => _subscriptions;
+  List<GeneralAnalysisService> subscriptions;
 
-  /// A list of the services being subscribed to.
-  set subscriptions(List<GeneralAnalysisService> value) {
-    assert(value != null);
-    _subscriptions = value;
-  }
-
-  AnalysisSetGeneralSubscriptionsParams(
-      List<GeneralAnalysisService> subscriptions) {
-    this.subscriptions = subscriptions;
-  }
+  AnalysisSetGeneralSubscriptionsParams(this.subscriptions);
 
   factory AnalysisSetGeneralSubscriptionsParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       List<GeneralAnalysisService> subscriptions;
@@ -3494,7 +2800,7 @@
         subscriptions = jsonDecoder.decodeList(
             jsonPath + '.subscriptions',
             json['subscriptions'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 GeneralAnalysisService.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'subscriptions');
@@ -3512,8 +2818,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['subscriptions'] = subscriptions
         .map((GeneralAnalysisService value) => value.toJson())
         .toList();
@@ -3550,7 +2856,7 @@
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisSetGeneralSubscriptionsResult implements ResponseResult {
   @override
-  Map<String, dynamic> toJson() => <String, dynamic>{};
+  Map<String, Object> toJson() => <String, Object>{};
 
   @override
   Response toResponse(String id) {
@@ -3579,23 +2885,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisSetPriorityFilesParams implements RequestParams {
-  List<String> _files;
-
   /// The files that are to be a priority for analysis.
-  List<String> get files => _files;
+  List<String> files;
 
-  /// The files that are to be a priority for analysis.
-  set files(List<String> value) {
-    assert(value != null);
-    _files = value;
-  }
-
-  AnalysisSetPriorityFilesParams(List<String> files) {
-    this.files = files;
-  }
+  AnalysisSetPriorityFilesParams(this.files);
 
   factory AnalysisSetPriorityFilesParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       List<String> files;
@@ -3618,8 +2914,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['files'] = files;
     return result;
   }
@@ -3653,7 +2949,7 @@
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisSetPriorityFilesResult implements ResponseResult {
   @override
-  Map<String, dynamic> toJson() => <String, dynamic>{};
+  Map<String, Object> toJson() => <String, Object>{};
 
   @override
   Response toResponse(String id) {
@@ -3682,35 +2978,23 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisSetSubscriptionsParams implements RequestParams {
-  Map<AnalysisService, List<String>> _subscriptions;
-
   /// A table mapping services to a list of the files being subscribed to the
   /// service.
-  Map<AnalysisService, List<String>> get subscriptions => _subscriptions;
+  Map<AnalysisService, List<String>> subscriptions;
 
-  /// A table mapping services to a list of the files being subscribed to the
-  /// service.
-  set subscriptions(Map<AnalysisService, List<String>> value) {
-    assert(value != null);
-    _subscriptions = value;
-  }
-
-  AnalysisSetSubscriptionsParams(
-      Map<AnalysisService, List<String>> subscriptions) {
-    this.subscriptions = subscriptions;
-  }
+  AnalysisSetSubscriptionsParams(this.subscriptions);
 
   factory AnalysisSetSubscriptionsParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       Map<AnalysisService, List<String>> subscriptions;
       if (json.containsKey('subscriptions')) {
         subscriptions = jsonDecoder.decodeMap(
             jsonPath + '.subscriptions', json['subscriptions'],
-            keyDecoder: (String jsonPath, Object json) =>
+            keyDecoder: (String jsonPath, Object? json) =>
                 AnalysisService.fromJson(jsonDecoder, jsonPath, json),
-            valueDecoder: (String jsonPath, Object json) => jsonDecoder
+            valueDecoder: (String jsonPath, Object? json) => jsonDecoder
                 .decodeList(jsonPath, json, jsonDecoder.decodeString));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'subscriptions');
@@ -3728,8 +3012,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['subscriptions'] = mapMap(subscriptions,
         keyCallback: (AnalysisService value) => value.toJson());
     return result;
@@ -3768,7 +3052,7 @@
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisSetSubscriptionsResult implements ResponseResult {
   @override
-  Map<String, dynamic> toJson() => <String, dynamic>{};
+  Map<String, Object> toJson() => <String, Object>{};
 
   @override
   Response toResponse(String id) {
@@ -3798,36 +3082,17 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisStatus implements HasToJson {
-  bool _isAnalyzing;
-
-  String _analysisTarget;
-
   /// True if analysis is currently being performed.
-  bool get isAnalyzing => _isAnalyzing;
-
-  /// True if analysis is currently being performed.
-  set isAnalyzing(bool value) {
-    assert(value != null);
-    _isAnalyzing = value;
-  }
+  bool isAnalyzing;
 
   /// The name of the current target of analysis. This field is omitted if
   /// analyzing is false.
-  String get analysisTarget => _analysisTarget;
+  String? analysisTarget;
 
-  /// The name of the current target of analysis. This field is omitted if
-  /// analyzing is false.
-  set analysisTarget(String value) {
-    _analysisTarget = value;
-  }
-
-  AnalysisStatus(bool isAnalyzing, {String analysisTarget}) {
-    this.isAnalyzing = isAnalyzing;
-    this.analysisTarget = analysisTarget;
-  }
+  AnalysisStatus(this.isAnalyzing, {this.analysisTarget});
 
   factory AnalysisStatus.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       bool isAnalyzing;
@@ -3837,7 +3102,7 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'isAnalyzing');
       }
-      String analysisTarget;
+      String? analysisTarget;
       if (json.containsKey('analysisTarget')) {
         analysisTarget = jsonDecoder.decodeString(
             jsonPath + '.analysisTarget', json['analysisTarget']);
@@ -3849,9 +3114,10 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['isAnalyzing'] = isAnalyzing;
+    var analysisTarget = this.analysisTarget;
     if (analysisTarget != null) {
       result['analysisTarget'] = analysisTarget;
     }
@@ -3887,38 +3153,27 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisUpdateContentParams implements RequestParams {
-  Map<String, dynamic> _files;
-
   /// A table mapping the files whose content has changed to a description of
   /// the content change.
-  Map<String, dynamic> get files => _files;
+  Map<String, Object> files;
 
-  /// A table mapping the files whose content has changed to a description of
-  /// the content change.
-  set files(Map<String, dynamic> value) {
-    assert(value != null);
-    _files = value;
-  }
-
-  AnalysisUpdateContentParams(Map<String, dynamic> files) {
-    this.files = files;
-  }
+  AnalysisUpdateContentParams(this.files);
 
   factory AnalysisUpdateContentParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
-      Map<String, dynamic> files;
+      Map<String, Object> files;
       if (json.containsKey('files')) {
         files = jsonDecoder.decodeMap(jsonPath + '.files', json['files'],
-            valueDecoder: (String jsonPath, Object json) =>
+            valueDecoder: (String jsonPath, Object? json) =>
                 jsonDecoder.decodeUnion(jsonPath, json, 'type', {
-                  'add': (String jsonPath, Object json) =>
+                  'add': (String jsonPath, Object? json) =>
                       AddContentOverlay.fromJson(jsonDecoder, jsonPath, json),
-                  'change': (String jsonPath, Object json) =>
+                  'change': (String jsonPath, Object? json) =>
                       ChangeContentOverlay.fromJson(
                           jsonDecoder, jsonPath, json),
-                  'remove': (String jsonPath, Object json) =>
+                  'remove': (String jsonPath, Object? json) =>
                       RemoveContentOverlay.fromJson(jsonDecoder, jsonPath, json)
                 }));
       } else {
@@ -3937,10 +3192,10 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
-    result['files'] =
-        mapMap(files, valueCallback: (dynamic value) => value.toJson());
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
+    result['files'] = mapMap(files,
+        valueCallback: (Object value) => (value as dynamic).toJson());
     return result;
   }
 
@@ -3955,7 +3210,7 @@
   @override
   bool operator ==(other) {
     if (other is AnalysisUpdateContentParams) {
-      return mapEqual(files, other.files, (dynamic a, dynamic b) => a == b);
+      return mapEqual(files, other.files, (Object a, Object b) => a == b);
     }
     return false;
   }
@@ -3978,7 +3233,7 @@
   AnalysisUpdateContentResult();
 
   factory AnalysisUpdateContentResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       return AnalysisUpdateContentResult();
@@ -3996,8 +3251,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     return result;
   }
 
@@ -4032,23 +3287,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisUpdateOptionsParams implements RequestParams {
-  AnalysisOptions _options;
-
   /// The options that are to be used to control analysis.
-  AnalysisOptions get options => _options;
+  AnalysisOptions options;
 
-  /// The options that are to be used to control analysis.
-  set options(AnalysisOptions value) {
-    assert(value != null);
-    _options = value;
-  }
-
-  AnalysisUpdateOptionsParams(AnalysisOptions options) {
-    this.options = options;
-  }
+  AnalysisUpdateOptionsParams(this.options);
 
   factory AnalysisUpdateOptionsParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       AnalysisOptions options;
@@ -4071,8 +3316,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['options'] = options.toJson();
     return result;
   }
@@ -4106,7 +3351,7 @@
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisUpdateOptionsResult implements ResponseResult {
   @override
-  Map<String, dynamic> toJson() => <String, dynamic>{};
+  Map<String, Object> toJson() => <String, Object>{};
 
   @override
   Response toResponse(String id) {
@@ -4135,23 +3380,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalyticsEnableParams implements RequestParams {
-  bool _value;
-
   /// Enable or disable analytics.
-  bool get value => _value;
+  bool value;
 
-  /// Enable or disable analytics.
-  set value(bool value) {
-    assert(value != null);
-    _value = value;
-  }
-
-  AnalyticsEnableParams(bool value) {
-    this.value = value;
-  }
+  AnalyticsEnableParams(this.value);
 
   factory AnalyticsEnableParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       bool value;
@@ -4172,8 +3407,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['value'] = value;
     return result;
   }
@@ -4207,7 +3442,7 @@
 /// Clients may not extend, implement or mix-in this class.
 class AnalyticsEnableResult implements ResponseResult {
   @override
-  Map<String, dynamic> toJson() => <String, dynamic>{};
+  Map<String, Object> toJson() => <String, Object>{};
 
   @override
   Response toResponse(String id) {
@@ -4233,7 +3468,7 @@
 /// Clients may not extend, implement or mix-in this class.
 class AnalyticsIsEnabledParams implements RequestParams {
   @override
-  Map<String, dynamic> toJson() => <String, dynamic>{};
+  Map<String, Object> toJson() => <String, Object>{};
 
   @override
   Request toRequest(String id) {
@@ -4262,23 +3497,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalyticsIsEnabledResult implements ResponseResult {
-  bool _enabled;
-
   /// Whether sending analytics is enabled or not.
-  bool get enabled => _enabled;
+  bool enabled;
 
-  /// Whether sending analytics is enabled or not.
-  set enabled(bool value) {
-    assert(value != null);
-    _enabled = value;
-  }
-
-  AnalyticsIsEnabledResult(bool enabled) {
-    this.enabled = enabled;
-  }
+  AnalyticsIsEnabledResult(this.enabled);
 
   factory AnalyticsIsEnabledResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       bool enabled;
@@ -4302,8 +3527,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['enabled'] = enabled;
     return result;
   }
@@ -4340,23 +3565,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalyticsSendEventParams implements RequestParams {
-  String _action;
-
   /// The value used to indicate which action was performed.
-  String get action => _action;
+  String action;
 
-  /// The value used to indicate which action was performed.
-  set action(String value) {
-    assert(value != null);
-    _action = value;
-  }
-
-  AnalyticsSendEventParams(String action) {
-    this.action = action;
-  }
+  AnalyticsSendEventParams(this.action);
 
   factory AnalyticsSendEventParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String action;
@@ -4377,8 +3592,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['action'] = action;
     return result;
   }
@@ -4412,7 +3627,7 @@
 /// Clients may not extend, implement or mix-in this class.
 class AnalyticsSendEventResult implements ResponseResult {
   @override
-  Map<String, dynamic> toJson() => <String, dynamic>{};
+  Map<String, Object> toJson() => <String, Object>{};
 
   @override
   Response toResponse(String id) {
@@ -4442,35 +3657,16 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalyticsSendTimingParams implements RequestParams {
-  String _event;
-
-  int _millis;
-
   /// The name of the event.
-  String get event => _event;
-
-  /// The name of the event.
-  set event(String value) {
-    assert(value != null);
-    _event = value;
-  }
+  String event;
 
   /// The duration of the event in milliseconds.
-  int get millis => _millis;
+  int millis;
 
-  /// The duration of the event in milliseconds.
-  set millis(int value) {
-    assert(value != null);
-    _millis = value;
-  }
-
-  AnalyticsSendTimingParams(String event, int millis) {
-    this.event = event;
-    this.millis = millis;
-  }
+  AnalyticsSendTimingParams(this.event, this.millis);
 
   factory AnalyticsSendTimingParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String event;
@@ -4497,8 +3693,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['event'] = event;
     result['millis'] = millis;
     return result;
@@ -4534,7 +3730,7 @@
 /// Clients may not extend, implement or mix-in this class.
 class AnalyticsSendTimingResult implements ResponseResult {
   @override
-  Map<String, dynamic> toJson() => <String, dynamic>{};
+  Map<String, Object> toJson() => <String, Object>{};
 
   @override
   Response toResponse(String id) {
@@ -4571,62 +3767,19 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AvailableSuggestion implements HasToJson {
-  String _label;
-
-  String _declaringLibraryUri;
-
-  Element _element;
-
-  String _defaultArgumentListString;
-
-  List<int> _defaultArgumentListTextRanges;
-
-  List<String> _parameterNames;
-
-  List<String> _parameterTypes;
-
-  List<String> _relevanceTags;
-
-  int _requiredParameterCount;
-
   /// The identifier to present to the user for code completion.
-  String get label => _label;
-
-  /// The identifier to present to the user for code completion.
-  set label(String value) {
-    assert(value != null);
-    _label = value;
-  }
+  String label;
 
   /// The URI of the library that declares the element being suggested, not the
   /// URI of the library associated with the enclosing AvailableSuggestionSet.
-  String get declaringLibraryUri => _declaringLibraryUri;
-
-  /// The URI of the library that declares the element being suggested, not the
-  /// URI of the library associated with the enclosing AvailableSuggestionSet.
-  set declaringLibraryUri(String value) {
-    assert(value != null);
-    _declaringLibraryUri = value;
-  }
+  String declaringLibraryUri;
 
   /// Information about the element reference being suggested.
-  Element get element => _element;
-
-  /// Information about the element reference being suggested.
-  set element(Element value) {
-    assert(value != null);
-    _element = value;
-  }
+  Element element;
 
   /// A default String for use in generating argument list source contents on
   /// the client side.
-  String get defaultArgumentListString => _defaultArgumentListString;
-
-  /// A default String for use in generating argument list source contents on
-  /// the client side.
-  set defaultArgumentListString(String value) {
-    _defaultArgumentListString = value;
-  }
+  String? defaultArgumentListString;
 
   /// Pairs of offsets and lengths describing 'defaultArgumentListString' text
   /// ranges suitable for use by clients to set up linked edits of default
@@ -4634,80 +3787,35 @@
   /// y', the corresponding text range [0, 1, 3, 1], indicates two text ranges
   /// of length 1, starting at offsets 0 and 3. Clients can use these ranges to
   /// treat the 'x' and 'y' values specially for linked edits.
-  List<int> get defaultArgumentListTextRanges => _defaultArgumentListTextRanges;
-
-  /// Pairs of offsets and lengths describing 'defaultArgumentListString' text
-  /// ranges suitable for use by clients to set up linked edits of default
-  /// argument source contents. For example, given an argument list string 'x,
-  /// y', the corresponding text range [0, 1, 3, 1], indicates two text ranges
-  /// of length 1, starting at offsets 0 and 3. Clients can use these ranges to
-  /// treat the 'x' and 'y' values specially for linked edits.
-  set defaultArgumentListTextRanges(List<int> value) {
-    _defaultArgumentListTextRanges = value;
-  }
+  List<int>? defaultArgumentListTextRanges;
 
   /// If the element is an executable, the names of the formal parameters of
   /// all kinds - required, optional positional, and optional named. The names
   /// of positional parameters are empty strings. Omitted if the element is not
   /// an executable.
-  List<String> get parameterNames => _parameterNames;
-
-  /// If the element is an executable, the names of the formal parameters of
-  /// all kinds - required, optional positional, and optional named. The names
-  /// of positional parameters are empty strings. Omitted if the element is not
-  /// an executable.
-  set parameterNames(List<String> value) {
-    _parameterNames = value;
-  }
+  List<String>? parameterNames;
 
   /// If the element is an executable, the declared types of the formal
   /// parameters of all kinds - required, optional positional, and optional
   /// named. Omitted if the element is not an executable.
-  List<String> get parameterTypes => _parameterTypes;
-
-  /// If the element is an executable, the declared types of the formal
-  /// parameters of all kinds - required, optional positional, and optional
-  /// named. Omitted if the element is not an executable.
-  set parameterTypes(List<String> value) {
-    _parameterTypes = value;
-  }
+  List<String>? parameterTypes;
 
   /// This field is set if the relevance of this suggestion might be changed
   /// depending on where completion is requested.
-  List<String> get relevanceTags => _relevanceTags;
+  List<String>? relevanceTags;
 
-  /// This field is set if the relevance of this suggestion might be changed
-  /// depending on where completion is requested.
-  set relevanceTags(List<String> value) {
-    _relevanceTags = value;
-  }
+  int? requiredParameterCount;
 
-  int get requiredParameterCount => _requiredParameterCount;
-
-  set requiredParameterCount(int value) {
-    _requiredParameterCount = value;
-  }
-
-  AvailableSuggestion(String label, String declaringLibraryUri, Element element,
-      {String defaultArgumentListString,
-      List<int> defaultArgumentListTextRanges,
-      List<String> parameterNames,
-      List<String> parameterTypes,
-      List<String> relevanceTags,
-      int requiredParameterCount}) {
-    this.label = label;
-    this.declaringLibraryUri = declaringLibraryUri;
-    this.element = element;
-    this.defaultArgumentListString = defaultArgumentListString;
-    this.defaultArgumentListTextRanges = defaultArgumentListTextRanges;
-    this.parameterNames = parameterNames;
-    this.parameterTypes = parameterTypes;
-    this.relevanceTags = relevanceTags;
-    this.requiredParameterCount = requiredParameterCount;
-  }
+  AvailableSuggestion(this.label, this.declaringLibraryUri, this.element,
+      {this.defaultArgumentListString,
+      this.defaultArgumentListTextRanges,
+      this.parameterNames,
+      this.parameterTypes,
+      this.relevanceTags,
+      this.requiredParameterCount});
 
   factory AvailableSuggestion.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String label;
@@ -4730,35 +3838,35 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'element');
       }
-      String defaultArgumentListString;
+      String? defaultArgumentListString;
       if (json.containsKey('defaultArgumentListString')) {
         defaultArgumentListString = jsonDecoder.decodeString(
             jsonPath + '.defaultArgumentListString',
             json['defaultArgumentListString']);
       }
-      List<int> defaultArgumentListTextRanges;
+      List<int>? defaultArgumentListTextRanges;
       if (json.containsKey('defaultArgumentListTextRanges')) {
         defaultArgumentListTextRanges = jsonDecoder.decodeList(
             jsonPath + '.defaultArgumentListTextRanges',
             json['defaultArgumentListTextRanges'],
             jsonDecoder.decodeInt);
       }
-      List<String> parameterNames;
+      List<String>? parameterNames;
       if (json.containsKey('parameterNames')) {
         parameterNames = jsonDecoder.decodeList(jsonPath + '.parameterNames',
             json['parameterNames'], jsonDecoder.decodeString);
       }
-      List<String> parameterTypes;
+      List<String>? parameterTypes;
       if (json.containsKey('parameterTypes')) {
         parameterTypes = jsonDecoder.decodeList(jsonPath + '.parameterTypes',
             json['parameterTypes'], jsonDecoder.decodeString);
       }
-      List<String> relevanceTags;
+      List<String>? relevanceTags;
       if (json.containsKey('relevanceTags')) {
         relevanceTags = jsonDecoder.decodeList(jsonPath + '.relevanceTags',
             json['relevanceTags'], jsonDecoder.decodeString);
       }
-      int requiredParameterCount;
+      int? requiredParameterCount;
       if (json.containsKey('requiredParameterCount')) {
         requiredParameterCount = jsonDecoder.decodeInt(
             jsonPath + '.requiredParameterCount',
@@ -4777,26 +3885,32 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['label'] = label;
     result['declaringLibraryUri'] = declaringLibraryUri;
     result['element'] = element.toJson();
+    var defaultArgumentListString = this.defaultArgumentListString;
     if (defaultArgumentListString != null) {
       result['defaultArgumentListString'] = defaultArgumentListString;
     }
+    var defaultArgumentListTextRanges = this.defaultArgumentListTextRanges;
     if (defaultArgumentListTextRanges != null) {
       result['defaultArgumentListTextRanges'] = defaultArgumentListTextRanges;
     }
+    var parameterNames = this.parameterNames;
     if (parameterNames != null) {
       result['parameterNames'] = parameterNames;
     }
+    var parameterTypes = this.parameterTypes;
     if (parameterTypes != null) {
       result['parameterTypes'] = parameterTypes;
     }
+    var relevanceTags = this.relevanceTags;
     if (relevanceTags != null) {
       result['relevanceTags'] = relevanceTags;
     }
+    var requiredParameterCount = this.requiredParameterCount;
     if (requiredParameterCount != null) {
       result['requiredParameterCount'] = requiredParameterCount;
     }
@@ -4852,45 +3966,18 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AvailableSuggestionSet implements HasToJson {
-  int _id;
-
-  String _uri;
-
-  List<AvailableSuggestion> _items;
-
   /// The id associated with the library.
-  int get id => _id;
-
-  /// The id associated with the library.
-  set id(int value) {
-    assert(value != null);
-    _id = value;
-  }
+  int id;
 
   /// The URI of the library.
-  String get uri => _uri;
+  String uri;
 
-  /// The URI of the library.
-  set uri(String value) {
-    assert(value != null);
-    _uri = value;
-  }
+  List<AvailableSuggestion> items;
 
-  List<AvailableSuggestion> get items => _items;
-
-  set items(List<AvailableSuggestion> value) {
-    assert(value != null);
-    _items = value;
-  }
-
-  AvailableSuggestionSet(int id, String uri, List<AvailableSuggestion> items) {
-    this.id = id;
-    this.uri = uri;
-    this.items = items;
-  }
+  AvailableSuggestionSet(this.id, this.uri, this.items);
 
   factory AvailableSuggestionSet.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       int id;
@@ -4910,7 +3997,7 @@
         items = jsonDecoder.decodeList(
             jsonPath + '.items',
             json['items'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 AvailableSuggestion.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'items');
@@ -4922,8 +4009,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['id'] = id;
     result['uri'] = uri;
     result['items'] =
@@ -4964,35 +4051,16 @@
 ///
 /// 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;
-  }
+  String path;
 
   /// A list of bulk fix details.
-  List<BulkFixDetail> get fixes => _fixes;
+  List<BulkFixDetail> 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;
-  }
+  BulkFix(this.path, this.fixes);
 
   factory BulkFix.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String path;
@@ -5006,7 +4074,7 @@
         fixes = jsonDecoder.decodeList(
             jsonPath + '.fixes',
             json['fixes'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 BulkFixDetail.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'fixes');
@@ -5018,8 +4086,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['path'] = path;
     result['fixes'] =
         fixes.map((BulkFixDetail value) => value.toJson()).toList();
@@ -5057,37 +4125,17 @@
 ///
 /// 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;
-  }
+  String code;
 
   /// The number times the associated diagnostic was fixed in the associated
   /// source edit.
-  int get occurrences => _occurrences;
+  int 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;
-  }
+  BulkFixDetail(this.code, this.occurrences);
 
   factory BulkFixDetail.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String code;
@@ -5110,8 +4158,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['code'] = code;
     result['occurrences'] = occurrences;
     return result;
@@ -5147,49 +4195,20 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class ClosingLabel implements HasToJson {
-  int _offset;
-
-  int _length;
-
-  String _label;
-
   /// The offset of the construct being labelled.
-  int get offset => _offset;
-
-  /// The offset of the construct being labelled.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
+  int offset;
 
   /// The length of the whole construct to be labelled.
-  int get length => _length;
-
-  /// The length of the whole construct to be labelled.
-  set length(int value) {
-    assert(value != null);
-    _length = value;
-  }
+  int length;
 
   /// The label associated with this range that should be displayed to the
   /// user.
-  String get label => _label;
+  String label;
 
-  /// The label associated with this range that should be displayed to the
-  /// user.
-  set label(String value) {
-    assert(value != null);
-    _label = value;
-  }
-
-  ClosingLabel(int offset, int length, String label) {
-    this.offset = offset;
-    this.length = length;
-    this.label = label;
-  }
+  ClosingLabel(this.offset, this.length, this.label);
 
   factory ClosingLabel.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       int offset;
@@ -5217,8 +4236,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['offset'] = offset;
     result['length'] = length;
     result['label'] = label;
@@ -5257,48 +4276,29 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class CompletionAvailableSuggestionsParams implements HasToJson {
-  List<AvailableSuggestionSet> _changedLibraries;
-
-  List<int> _removedLibraries;
-
   /// A list of pre-computed, potential completions coming from this set of
   /// completion suggestions.
-  List<AvailableSuggestionSet> get changedLibraries => _changedLibraries;
-
-  /// A list of pre-computed, potential completions coming from this set of
-  /// completion suggestions.
-  set changedLibraries(List<AvailableSuggestionSet> value) {
-    _changedLibraries = value;
-  }
+  List<AvailableSuggestionSet>? changedLibraries;
 
   /// A list of library ids that no longer apply.
-  List<int> get removedLibraries => _removedLibraries;
-
-  /// A list of library ids that no longer apply.
-  set removedLibraries(List<int> value) {
-    _removedLibraries = value;
-  }
+  List<int>? removedLibraries;
 
   CompletionAvailableSuggestionsParams(
-      {List<AvailableSuggestionSet> changedLibraries,
-      List<int> removedLibraries}) {
-    this.changedLibraries = changedLibraries;
-    this.removedLibraries = removedLibraries;
-  }
+      {this.changedLibraries, this.removedLibraries});
 
   factory CompletionAvailableSuggestionsParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
-      List<AvailableSuggestionSet> changedLibraries;
+      List<AvailableSuggestionSet>? changedLibraries;
       if (json.containsKey('changedLibraries')) {
         changedLibraries = jsonDecoder.decodeList(
             jsonPath + '.changedLibraries',
             json['changedLibraries'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 AvailableSuggestionSet.fromJson(jsonDecoder, jsonPath, json));
       }
-      List<int> removedLibraries;
+      List<int>? removedLibraries;
       if (json.containsKey('removedLibraries')) {
         removedLibraries = jsonDecoder.decodeList(
             jsonPath + '.removedLibraries',
@@ -5321,13 +4321,15 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
+    var changedLibraries = this.changedLibraries;
     if (changedLibraries != null) {
       result['changedLibraries'] = changedLibraries
           .map((AvailableSuggestionSet value) => value.toJson())
           .toList();
     }
+    var removedLibraries = this.removedLibraries;
     if (removedLibraries != null) {
       result['removedLibraries'] = removedLibraries;
     }
@@ -5370,35 +4372,16 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class CompletionExistingImportsParams implements HasToJson {
-  String _file;
-
-  ExistingImports _imports;
-
   /// The defining file of the library.
-  String get file => _file;
-
-  /// The defining file of the library.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// The existing imports in the library.
-  ExistingImports get imports => _imports;
+  ExistingImports imports;
 
-  /// The existing imports in the library.
-  set imports(ExistingImports value) {
-    assert(value != null);
-    _imports = value;
-  }
-
-  CompletionExistingImportsParams(String file, ExistingImports imports) {
-    this.file = file;
-    this.imports = imports;
-  }
+  CompletionExistingImportsParams(this.file, this.imports);
 
   factory CompletionExistingImportsParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -5428,8 +4411,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     result['imports'] = imports.toJson();
     return result;
@@ -5470,64 +4453,25 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class CompletionGetSuggestionDetailsParams implements RequestParams {
-  String _file;
-
-  int _id;
-
-  String _label;
-
-  int _offset;
-
   /// The path of the file into which this completion is being inserted.
-  String get file => _file;
-
-  /// The path of the file into which this completion is being inserted.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// The identifier of the AvailableSuggestionSet containing the selected
   /// label.
-  int get id => _id;
-
-  /// The identifier of the AvailableSuggestionSet containing the selected
-  /// label.
-  set id(int value) {
-    assert(value != null);
-    _id = value;
-  }
+  int id;
 
   /// The label from the AvailableSuggestionSet with the `id` for which
   /// insertion information is requested.
-  String get label => _label;
-
-  /// The label from the AvailableSuggestionSet with the `id` for which
-  /// insertion information is requested.
-  set label(String value) {
-    assert(value != null);
-    _label = value;
-  }
+  String label;
 
   /// The offset in the file where the completion will be inserted.
-  int get offset => _offset;
-
-  /// The offset in the file where the completion will be inserted.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
+  int offset;
 
   CompletionGetSuggestionDetailsParams(
-      String file, int id, String label, int offset) {
-    this.file = file;
-    this.id = id;
-    this.label = label;
-    this.offset = offset;
-  }
+      this.file, this.id, this.label, this.offset);
 
   factory CompletionGetSuggestionDetailsParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -5567,8 +4511,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     result['id'] = id;
     result['label'] = label;
@@ -5615,39 +4559,18 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class CompletionGetSuggestionDetailsResult implements ResponseResult {
-  String _completion;
-
-  SourceChange _change;
-
   /// The full text to insert, including any optional import prefix.
-  String get completion => _completion;
-
-  /// The full text to insert, including any optional import prefix.
-  set completion(String value) {
-    assert(value != null);
-    _completion = value;
-  }
+  String completion;
 
   /// A change for the client to apply in case the library containing the
   /// accepted completion suggestion needs to be imported. The field will be
   /// omitted if there are no additional changes that need to be made.
-  SourceChange get change => _change;
+  SourceChange? change;
 
-  /// A change for the client to apply in case the library containing the
-  /// accepted completion suggestion needs to be imported. The field will be
-  /// omitted if there are no additional changes that need to be made.
-  set change(SourceChange value) {
-    _change = value;
-  }
-
-  CompletionGetSuggestionDetailsResult(String completion,
-      {SourceChange change}) {
-    this.completion = completion;
-    this.change = change;
-  }
+  CompletionGetSuggestionDetailsResult(this.completion, {this.change});
 
   factory CompletionGetSuggestionDetailsResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String completion;
@@ -5657,7 +4580,7 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'completion');
       }
-      SourceChange change;
+      SourceChange? change;
       if (json.containsKey('change')) {
         change = SourceChange.fromJson(
             jsonDecoder, jsonPath + '.change', json['change']);
@@ -5677,9 +4600,10 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['completion'] = completion;
+    var change = this.change;
     if (change != null) {
       result['change'] = change.toJson();
     }
@@ -5720,35 +4644,16 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class CompletionGetSuggestionsParams implements RequestParams {
-  String _file;
-
-  int _offset;
-
   /// The file containing the point at which suggestions are to be made.
-  String get file => _file;
-
-  /// The file containing the point at which suggestions are to be made.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// The offset within the file at which suggestions are to be made.
-  int get offset => _offset;
+  int offset;
 
-  /// The offset within the file at which suggestions are to be made.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
-
-  CompletionGetSuggestionsParams(String file, int offset) {
-    this.file = file;
-    this.offset = offset;
-  }
+  CompletionGetSuggestionsParams(this.file, this.offset);
 
   factory CompletionGetSuggestionsParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -5776,8 +4681,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     result['offset'] = offset;
     return result;
@@ -5816,23 +4721,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class CompletionGetSuggestionsResult implements ResponseResult {
-  String _id;
-
   /// The identifier used to associate results with this completion request.
-  String get id => _id;
+  String id;
 
-  /// The identifier used to associate results with this completion request.
-  set id(String value) {
-    assert(value != null);
-    _id = value;
-  }
-
-  CompletionGetSuggestionsResult(String id) {
-    this.id = id;
-  }
+  CompletionGetSuggestionsResult(this.id);
 
   factory CompletionGetSuggestionsResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String id;
@@ -5856,8 +4751,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['id'] = id;
     return result;
   }
@@ -5894,29 +4789,16 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class CompletionRegisterLibraryPathsParams implements RequestParams {
-  List<LibraryPathSet> _paths;
-
   /// A list of objects each containing a path and the additional libraries
   /// from which the client is interested in receiving completion suggestions.
   /// If one configured path is beneath another, the descendent will override
   /// the ancestors' configured libraries of interest.
-  List<LibraryPathSet> get paths => _paths;
+  List<LibraryPathSet> paths;
 
-  /// A list of objects each containing a path and the additional libraries
-  /// from which the client is interested in receiving completion suggestions.
-  /// If one configured path is beneath another, the descendent will override
-  /// the ancestors' configured libraries of interest.
-  set paths(List<LibraryPathSet> value) {
-    assert(value != null);
-    _paths = value;
-  }
-
-  CompletionRegisterLibraryPathsParams(List<LibraryPathSet> paths) {
-    this.paths = paths;
-  }
+  CompletionRegisterLibraryPathsParams(this.paths);
 
   factory CompletionRegisterLibraryPathsParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       List<LibraryPathSet> paths;
@@ -5924,7 +4806,7 @@
         paths = jsonDecoder.decodeList(
             jsonPath + '.paths',
             json['paths'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 LibraryPathSet.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'paths');
@@ -5942,8 +4824,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['paths'] =
         paths.map((LibraryPathSet value) => value.toJson()).toList();
     return result;
@@ -5979,7 +4861,7 @@
 /// Clients may not extend, implement or mix-in this class.
 class CompletionRegisterLibraryPathsResult implements ResponseResult {
   @override
-  Map<String, dynamic> toJson() => <String, dynamic>{};
+  Map<String, Object> toJson() => <String, Object>{};
 
   @override
   Response toResponse(String id) {
@@ -6016,131 +4898,48 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class CompletionResultsParams implements HasToJson {
-  String _id;
-
-  int _replacementOffset;
-
-  int _replacementLength;
-
-  List<CompletionSuggestion> _results;
-
-  bool _isLast;
-
-  String _libraryFile;
-
-  List<IncludedSuggestionSet> _includedSuggestionSets;
-
-  List<ElementKind> _includedElementKinds;
-
-  List<IncludedSuggestionRelevanceTag> _includedSuggestionRelevanceTags;
-
   /// The id associated with the completion.
-  String get id => _id;
-
-  /// The id associated with the completion.
-  set id(String value) {
-    assert(value != null);
-    _id = value;
-  }
+  String id;
 
   /// 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 offset. In
   /// particular, the replacementOffset will be the offset of the beginning of
   /// said identifier.
-  int get replacementOffset => _replacementOffset;
-
-  /// 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 offset. In
-  /// particular, the replacementOffset will be the offset of the beginning of
-  /// said identifier.
-  set replacementOffset(int value) {
-    assert(value != null);
-    _replacementOffset = value;
-  }
+  int replacementOffset;
 
   /// The length of the text to be replaced if the remainder of the identifier
   /// containing the cursor is to be replaced when the suggestion is applied
   /// (that is, the number of characters in the existing identifier).
-  int get replacementLength => _replacementLength;
-
-  /// The length of the text to be replaced if the remainder of the identifier
-  /// containing the cursor is to be replaced when the suggestion is applied
-  /// (that is, the number of characters in the existing identifier).
-  set replacementLength(int value) {
-    assert(value != null);
-    _replacementLength = value;
-  }
+  int replacementLength;
 
   /// The completion suggestions being reported. The notification contains all
   /// possible completions at the requested cursor position, even those that do
   /// not match the characters the user has already typed. This allows the
   /// client to respond to further keystrokes from the user without having to
   /// make additional requests.
-  List<CompletionSuggestion> get results => _results;
-
-  /// The completion suggestions being reported. The notification contains all
-  /// possible completions at the requested cursor position, even those that do
-  /// not match the characters the user has already typed. This allows the
-  /// client to respond to further keystrokes from the user without having to
-  /// make additional requests.
-  set results(List<CompletionSuggestion> value) {
-    assert(value != null);
-    _results = value;
-  }
+  List<CompletionSuggestion> results;
 
   /// True if this is that last set of results that will be returned for the
   /// indicated completion.
-  bool get isLast => _isLast;
-
-  /// True if this is that last set of results that will be returned for the
-  /// indicated completion.
-  set isLast(bool value) {
-    assert(value != null);
-    _isLast = value;
-  }
+  bool isLast;
 
   /// The library file that contains the file where completion was requested.
   /// The client might use it for example together with the existingImports
   /// notification to filter out available suggestions. If there were changes
   /// to existing imports in the library, the corresponding existingImports
   /// notification will be sent before the completion notification.
-  String get libraryFile => _libraryFile;
-
-  /// The library file that contains the file where completion was requested.
-  /// The client might use it for example together with the existingImports
-  /// notification to filter out available suggestions. If there were changes
-  /// to existing imports in the library, the corresponding existingImports
-  /// notification will be sent before the completion notification.
-  set libraryFile(String value) {
-    _libraryFile = value;
-  }
+  String? libraryFile;
 
   /// References to AvailableSuggestionSet objects previously sent to the
   /// client. The client can include applicable names from the referenced
   /// library in code completion suggestions.
-  List<IncludedSuggestionSet> get includedSuggestionSets =>
-      _includedSuggestionSets;
-
-  /// References to AvailableSuggestionSet objects previously sent to the
-  /// client. The client can include applicable names from the referenced
-  /// library in code completion suggestions.
-  set includedSuggestionSets(List<IncludedSuggestionSet> value) {
-    _includedSuggestionSets = value;
-  }
+  List<IncludedSuggestionSet>? includedSuggestionSets;
 
   /// The client is expected to check this list against the ElementKind sent in
   /// IncludedSuggestionSet to decide whether or not these symbols should
   /// should be presented to the user.
-  List<ElementKind> get includedElementKinds => _includedElementKinds;
-
-  /// The client is expected to check this list against the ElementKind sent in
-  /// IncludedSuggestionSet to decide whether or not these symbols should
-  /// should be presented to the user.
-  set includedElementKinds(List<ElementKind> value) {
-    _includedElementKinds = value;
-  }
+  List<ElementKind>? includedElementKinds;
 
   /// The client is expected to check this list against the values of the field
   /// relevanceTags of AvailableSuggestion to decide if the suggestion should
@@ -6150,41 +4949,17 @@
   ///
   /// If an AvailableSuggestion has relevance tags that match more than one
   /// IncludedSuggestionRelevanceTag, the maximum relevance boost is used.
-  List<IncludedSuggestionRelevanceTag> get includedSuggestionRelevanceTags =>
-      _includedSuggestionRelevanceTags;
+  List<IncludedSuggestionRelevanceTag>? includedSuggestionRelevanceTags;
 
-  /// The client is expected to check this list against the values of the field
-  /// relevanceTags of AvailableSuggestion to decide if the suggestion should
-  /// be given a different relevance than the IncludedSuggestionSet that
-  /// contains it. This might be used for example to give higher relevance to
-  /// suggestions of matching types.
-  ///
-  /// If an AvailableSuggestion has relevance tags that match more than one
-  /// IncludedSuggestionRelevanceTag, the maximum relevance boost is used.
-  set includedSuggestionRelevanceTags(
-      List<IncludedSuggestionRelevanceTag> value) {
-    _includedSuggestionRelevanceTags = value;
-  }
-
-  CompletionResultsParams(String id, int replacementOffset,
-      int replacementLength, List<CompletionSuggestion> results, bool isLast,
-      {String libraryFile,
-      List<IncludedSuggestionSet> includedSuggestionSets,
-      List<ElementKind> includedElementKinds,
-      List<IncludedSuggestionRelevanceTag> includedSuggestionRelevanceTags}) {
-    this.id = id;
-    this.replacementOffset = replacementOffset;
-    this.replacementLength = replacementLength;
-    this.results = results;
-    this.isLast = isLast;
-    this.libraryFile = libraryFile;
-    this.includedSuggestionSets = includedSuggestionSets;
-    this.includedElementKinds = includedElementKinds;
-    this.includedSuggestionRelevanceTags = includedSuggestionRelevanceTags;
-  }
+  CompletionResultsParams(this.id, this.replacementOffset,
+      this.replacementLength, this.results, this.isLast,
+      {this.libraryFile,
+      this.includedSuggestionSets,
+      this.includedElementKinds,
+      this.includedSuggestionRelevanceTags});
 
   factory CompletionResultsParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String id;
@@ -6212,7 +4987,7 @@
         results = jsonDecoder.decodeList(
             jsonPath + '.results',
             json['results'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 CompletionSuggestion.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'results');
@@ -6223,33 +4998,33 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'isLast');
       }
-      String libraryFile;
+      String? libraryFile;
       if (json.containsKey('libraryFile')) {
         libraryFile = jsonDecoder.decodeString(
             jsonPath + '.libraryFile', json['libraryFile']);
       }
-      List<IncludedSuggestionSet> includedSuggestionSets;
+      List<IncludedSuggestionSet>? includedSuggestionSets;
       if (json.containsKey('includedSuggestionSets')) {
         includedSuggestionSets = jsonDecoder.decodeList(
             jsonPath + '.includedSuggestionSets',
             json['includedSuggestionSets'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 IncludedSuggestionSet.fromJson(jsonDecoder, jsonPath, json));
       }
-      List<ElementKind> includedElementKinds;
+      List<ElementKind>? includedElementKinds;
       if (json.containsKey('includedElementKinds')) {
         includedElementKinds = jsonDecoder.decodeList(
             jsonPath + '.includedElementKinds',
             json['includedElementKinds'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 ElementKind.fromJson(jsonDecoder, jsonPath, json));
       }
-      List<IncludedSuggestionRelevanceTag> includedSuggestionRelevanceTags;
+      List<IncludedSuggestionRelevanceTag>? includedSuggestionRelevanceTags;
       if (json.containsKey('includedSuggestionRelevanceTags')) {
         includedSuggestionRelevanceTags = jsonDecoder.decodeList(
             jsonPath + '.includedSuggestionRelevanceTags',
             json['includedSuggestionRelevanceTags'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 IncludedSuggestionRelevanceTag.fromJson(
                     jsonDecoder, jsonPath, json));
       }
@@ -6270,27 +5045,31 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['id'] = id;
     result['replacementOffset'] = replacementOffset;
     result['replacementLength'] = replacementLength;
     result['results'] =
         results.map((CompletionSuggestion value) => value.toJson()).toList();
     result['isLast'] = isLast;
+    var libraryFile = this.libraryFile;
     if (libraryFile != null) {
       result['libraryFile'] = libraryFile;
     }
+    var includedSuggestionSets = this.includedSuggestionSets;
     if (includedSuggestionSets != null) {
       result['includedSuggestionSets'] = includedSuggestionSets
           .map((IncludedSuggestionSet value) => value.toJson())
           .toList();
     }
+    var includedElementKinds = this.includedElementKinds;
     if (includedElementKinds != null) {
       result['includedElementKinds'] = includedElementKinds
           .map((ElementKind value) => value.toJson())
           .toList();
     }
+    var includedSuggestionRelevanceTags = this.includedSuggestionRelevanceTags;
     if (includedSuggestionRelevanceTags != null) {
       result['includedSuggestionRelevanceTags'] =
           includedSuggestionRelevanceTags
@@ -6385,7 +5164,7 @@
   }
 
   factory CompletionService.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     if (json is String) {
       try {
         return CompletionService(json);
@@ -6410,23 +5189,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class CompletionSetSubscriptionsParams implements RequestParams {
-  List<CompletionService> _subscriptions;
-
   /// A list of the services being subscribed to.
-  List<CompletionService> get subscriptions => _subscriptions;
+  List<CompletionService> subscriptions;
 
-  /// A list of the services being subscribed to.
-  set subscriptions(List<CompletionService> value) {
-    assert(value != null);
-    _subscriptions = value;
-  }
-
-  CompletionSetSubscriptionsParams(List<CompletionService> subscriptions) {
-    this.subscriptions = subscriptions;
-  }
+  CompletionSetSubscriptionsParams(this.subscriptions);
 
   factory CompletionSetSubscriptionsParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       List<CompletionService> subscriptions;
@@ -6434,7 +5203,7 @@
         subscriptions = jsonDecoder.decodeList(
             jsonPath + '.subscriptions',
             json['subscriptions'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 CompletionService.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'subscriptions');
@@ -6452,8 +5221,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['subscriptions'] =
         subscriptions.map((CompletionService value) => value.toJson()).toList();
     return result;
@@ -6489,7 +5258,7 @@
 /// Clients may not extend, implement or mix-in this class.
 class CompletionSetSubscriptionsResult implements ResponseResult {
   @override
-  Map<String, dynamic> toJson() => <String, dynamic>{};
+  Map<String, Object> toJson() => <String, Object>{};
 
   @override
   Response toResponse(String id) {
@@ -6522,72 +5291,26 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class ContextData implements HasToJson {
-  String _name;
-
-  int _explicitFileCount;
-
-  int _implicitFileCount;
-
-  int _workItemQueueLength;
-
-  List<String> _cacheEntryExceptions;
-
   /// The name of the context.
-  String get name => _name;
-
-  /// The name of the context.
-  set name(String value) {
-    assert(value != null);
-    _name = value;
-  }
+  String name;
 
   /// Explicitly analyzed files.
-  int get explicitFileCount => _explicitFileCount;
-
-  /// Explicitly analyzed files.
-  set explicitFileCount(int value) {
-    assert(value != null);
-    _explicitFileCount = value;
-  }
+  int explicitFileCount;
 
   /// Implicitly analyzed files.
-  int get implicitFileCount => _implicitFileCount;
-
-  /// Implicitly analyzed files.
-  set implicitFileCount(int value) {
-    assert(value != null);
-    _implicitFileCount = value;
-  }
+  int implicitFileCount;
 
   /// The number of work items in the queue.
-  int get workItemQueueLength => _workItemQueueLength;
-
-  /// The number of work items in the queue.
-  set workItemQueueLength(int value) {
-    assert(value != null);
-    _workItemQueueLength = value;
-  }
+  int workItemQueueLength;
 
   /// Exceptions associated with cache entries.
-  List<String> get cacheEntryExceptions => _cacheEntryExceptions;
+  List<String> cacheEntryExceptions;
 
-  /// Exceptions associated with cache entries.
-  set cacheEntryExceptions(List<String> value) {
-    assert(value != null);
-    _cacheEntryExceptions = value;
-  }
-
-  ContextData(String name, int explicitFileCount, int implicitFileCount,
-      int workItemQueueLength, List<String> cacheEntryExceptions) {
-    this.name = name;
-    this.explicitFileCount = explicitFileCount;
-    this.implicitFileCount = implicitFileCount;
-    this.workItemQueueLength = workItemQueueLength;
-    this.cacheEntryExceptions = cacheEntryExceptions;
-  }
+  ContextData(this.name, this.explicitFileCount, this.implicitFileCount,
+      this.workItemQueueLength, this.cacheEntryExceptions);
 
   factory ContextData.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String name;
@@ -6634,8 +5357,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['name'] = name;
     result['explicitFileCount'] = explicitFileCount;
     result['implicitFileCount'] = implicitFileCount;
@@ -6757,34 +5480,16 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class DartFix implements HasToJson {
-  String _name;
-
-  String _description;
-
   /// The name of the fix.
-  String get name => _name;
-
-  /// The name of the fix.
-  set name(String value) {
-    assert(value != null);
-    _name = value;
-  }
+  String name;
 
   /// A human readable description of the fix.
-  String get description => _description;
+  String? description;
 
-  /// A human readable description of the fix.
-  set description(String value) {
-    _description = value;
-  }
-
-  DartFix(String name, {String description}) {
-    this.name = name;
-    this.description = description;
-  }
+  DartFix(this.name, {this.description});
 
   factory DartFix.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String name;
@@ -6793,7 +5498,7 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'name');
       }
-      String description;
+      String? description;
       if (json.containsKey('description')) {
         description = jsonDecoder.decodeString(
             jsonPath + '.description', json['description']);
@@ -6805,9 +5510,10 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['name'] = name;
+    var description = this.description;
     if (description != null) {
       result['description'] = description;
     }
@@ -6843,34 +5549,16 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class DartFixSuggestion implements HasToJson {
-  String _description;
-
-  Location _location;
-
   /// A human readable description of the suggested change.
-  String get description => _description;
-
-  /// A human readable description of the suggested change.
-  set description(String value) {
-    assert(value != null);
-    _description = value;
-  }
+  String description;
 
   /// The location of the suggested change.
-  Location get location => _location;
+  Location? location;
 
-  /// The location of the suggested change.
-  set location(Location value) {
-    _location = value;
-  }
-
-  DartFixSuggestion(String description, {Location location}) {
-    this.description = description;
-    this.location = location;
-  }
+  DartFixSuggestion(this.description, {this.location});
 
   factory DartFixSuggestion.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String description;
@@ -6880,7 +5568,7 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'description');
       }
-      Location location;
+      Location? location;
       if (json.containsKey('location')) {
         location = Location.fromJson(
             jsonDecoder, jsonPath + '.location', json['location']);
@@ -6892,9 +5580,10 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['description'] = description;
+    var location = this.location;
     if (location != null) {
       result['location'] = location.toJson();
     }
@@ -6926,7 +5615,7 @@
 /// Clients may not extend, implement or mix-in this class.
 class DiagnosticGetDiagnosticsParams implements RequestParams {
   @override
-  Map<String, dynamic> toJson() => <String, dynamic>{};
+  Map<String, Object> toJson() => <String, Object>{};
 
   @override
   Request toRequest(String id) {
@@ -6955,23 +5644,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class DiagnosticGetDiagnosticsResult implements ResponseResult {
-  List<ContextData> _contexts;
-
   /// The list of analysis contexts.
-  List<ContextData> get contexts => _contexts;
+  List<ContextData> contexts;
 
-  /// The list of analysis contexts.
-  set contexts(List<ContextData> value) {
-    assert(value != null);
-    _contexts = value;
-  }
-
-  DiagnosticGetDiagnosticsResult(List<ContextData> contexts) {
-    this.contexts = contexts;
-  }
+  DiagnosticGetDiagnosticsResult(this.contexts);
 
   factory DiagnosticGetDiagnosticsResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       List<ContextData> contexts;
@@ -6979,7 +5658,7 @@
         contexts = jsonDecoder.decodeList(
             jsonPath + '.contexts',
             json['contexts'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 ContextData.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'contexts');
@@ -6999,8 +5678,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['contexts'] =
         contexts.map((ContextData value) => value.toJson()).toList();
     return result;
@@ -7036,7 +5715,7 @@
 /// Clients may not extend, implement or mix-in this class.
 class DiagnosticGetServerPortParams implements RequestParams {
   @override
-  Map<String, dynamic> toJson() => <String, dynamic>{};
+  Map<String, Object> toJson() => <String, Object>{};
 
   @override
   Request toRequest(String id) {
@@ -7065,23 +5744,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class DiagnosticGetServerPortResult implements ResponseResult {
-  int _port;
-
   /// The diagnostic server port.
-  int get port => _port;
+  int port;
 
-  /// The diagnostic server port.
-  set port(int value) {
-    assert(value != null);
-    _port = value;
-  }
-
-  DiagnosticGetServerPortResult(int port) {
-    this.port = port;
-  }
+  DiagnosticGetServerPortResult(this.port);
 
   factory DiagnosticGetServerPortResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       int port;
@@ -7105,8 +5774,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['port'] = port;
     return result;
   }
@@ -7144,10 +5813,6 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class EditBulkFixesParams implements RequestParams {
-  List<String> _included;
-
-  bool _inTestMode;
-
   /// A list of the files and directories for which edits should be suggested.
   ///
   /// If a request is made with a path that is invalid, e.g. is not absolute
@@ -7156,20 +5821,7 @@
   /// is not currently subject to analysis (e.g. because it is not associated
   /// with any analysis root specified to analysis.setAnalysisRoots), an error
   /// of type FILE_NOT_ANALYZED will be generated.
-  List<String> get included => _included;
-
-  /// A list of the files and directories for which edits should be suggested.
-  ///
-  /// If a request is made with a path that is invalid, e.g. is not absolute
-  /// and normalized, an error of type INVALID_FILE_PATH_FORMAT will be
-  /// generated. If a request is made for a file which does not exist, or which
-  /// is not currently subject to analysis (e.g. because it is not associated
-  /// with any analysis root specified to analysis.setAnalysisRoots), an error
-  /// of type FILE_NOT_ANALYZED will be generated.
-  set included(List<String> value) {
-    assert(value != null);
-    _included = value;
-  }
+  List<String> included;
 
   /// A flag indicating whether the bulk fixes are being run in test mode. The
   /// only difference is that in test mode the fix processor will look for a
@@ -7177,25 +5829,12 @@
   /// compute the fixes when data-driven fixes are being considered.
   ///
   /// If this field is omitted the flag defaults to false.
-  bool get inTestMode => _inTestMode;
+  bool? inTestMode;
 
-  /// A flag indicating whether the bulk fixes are being run in test mode. The
-  /// only difference is that in test mode the fix processor will look for a
-  /// configuration file that can modify the content of the data file used to
-  /// compute the fixes when data-driven fixes are being considered.
-  ///
-  /// If this field is omitted the flag defaults to false.
-  set inTestMode(bool value) {
-    _inTestMode = value;
-  }
-
-  EditBulkFixesParams(List<String> included, {bool inTestMode}) {
-    this.included = included;
-    this.inTestMode = inTestMode;
-  }
+  EditBulkFixesParams(this.included, {this.inTestMode});
 
   factory EditBulkFixesParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       List<String> included;
@@ -7205,7 +5844,7 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'included');
       }
-      bool inTestMode;
+      bool? inTestMode;
       if (json.containsKey('inTestMode')) {
         inTestMode = jsonDecoder.decodeBool(
             jsonPath + '.inTestMode', json['inTestMode']);
@@ -7222,9 +5861,10 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['included'] = included;
+    var inTestMode = this.inTestMode;
     if (inTestMode != null) {
       result['inTestMode'] = inTestMode;
     }
@@ -7267,35 +5907,16 @@
 ///
 /// 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;
-
-  /// A list of source edits to apply the recommended changes.
-  set edits(List<SourceFileEdit> value) {
-    assert(value != null);
-    _edits = value;
-  }
+  List<SourceFileEdit> edits;
 
   /// Details that summarize the fixes associated with the recommended changes.
-  List<BulkFix> get details => _details;
+  List<BulkFix> 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;
-  }
+  EditBulkFixesResult(this.edits, this.details);
 
   factory EditBulkFixesResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       List<SourceFileEdit> edits;
@@ -7303,7 +5924,7 @@
         edits = jsonDecoder.decodeList(
             jsonPath + '.edits',
             json['edits'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 SourceFileEdit.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'edits');
@@ -7313,7 +5934,7 @@
         details = jsonDecoder.decodeList(
             jsonPath + '.details',
             json['details'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 BulkFix.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'details');
@@ -7332,8 +5953,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['edits'] =
         edits.map((SourceFileEdit value) => value.toJson()).toList();
     result['details'] = details.map((BulkFix value) => value.toJson()).toList();
@@ -7380,18 +6001,6 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class EditDartfixParams implements RequestParams {
-  List<String> _included;
-
-  List<String> _includedFixes;
-
-  bool _includePedanticFixes;
-
-  List<String> _excludedFixes;
-
-  int _port;
-
-  String _outputDir;
-
   /// A list of the files and directories for which edits should be suggested.
   ///
   /// If a request is made with a path that is invalid, e.g. is not absolute
@@ -7400,89 +6009,38 @@
   /// is not currently subject to analysis (e.g. because it is not associated
   /// with any analysis root specified to analysis.setAnalysisRoots), an error
   /// of type FILE_NOT_ANALYZED will be generated.
-  List<String> get included => _included;
-
-  /// A list of the files and directories for which edits should be suggested.
-  ///
-  /// If a request is made with a path that is invalid, e.g. is not absolute
-  /// and normalized, an error of type INVALID_FILE_PATH_FORMAT will be
-  /// generated. If a request is made for a file which does not exist, or which
-  /// is not currently subject to analysis (e.g. because it is not associated
-  /// with any analysis root specified to analysis.setAnalysisRoots), an error
-  /// of type FILE_NOT_ANALYZED will be generated.
-  set included(List<String> value) {
-    assert(value != null);
-    _included = value;
-  }
+  List<String> included;
 
   /// A list of names indicating which fixes should be applied.
   ///
   /// If a name is specified that does not match the name of a known fix, an
   /// error of type UNKNOWN_FIX will be generated.
-  List<String> get includedFixes => _includedFixes;
-
-  /// A list of names indicating which fixes should be applied.
-  ///
-  /// If a name is specified that does not match the name of a known fix, an
-  /// error of type UNKNOWN_FIX will be generated.
-  set includedFixes(List<String> value) {
-    _includedFixes = value;
-  }
+  List<String>? includedFixes;
 
   /// A flag indicating whether "pedantic" fixes should be applied.
-  bool get includePedanticFixes => _includePedanticFixes;
-
-  /// A flag indicating whether "pedantic" fixes should be applied.
-  set includePedanticFixes(bool value) {
-    _includePedanticFixes = value;
-  }
+  bool? includePedanticFixes;
 
   /// A list of names indicating which fixes should not be applied.
   ///
   /// If a name is specified that does not match the name of a known fix, an
   /// error of type UNKNOWN_FIX will be generated.
-  List<String> get excludedFixes => _excludedFixes;
-
-  /// A list of names indicating which fixes should not be applied.
-  ///
-  /// If a name is specified that does not match the name of a known fix, an
-  /// error of type UNKNOWN_FIX will be generated.
-  set excludedFixes(List<String> value) {
-    _excludedFixes = value;
-  }
+  List<String>? excludedFixes;
 
   /// Deprecated: This field is now ignored by server.
-  int get port => _port;
+  int? port;
 
   /// Deprecated: This field is now ignored by server.
-  set port(int value) {
-    _port = value;
-  }
+  String? outputDir;
 
-  /// Deprecated: This field is now ignored by server.
-  String get outputDir => _outputDir;
-
-  /// Deprecated: This field is now ignored by server.
-  set outputDir(String value) {
-    _outputDir = value;
-  }
-
-  EditDartfixParams(List<String> included,
-      {List<String> includedFixes,
-      bool includePedanticFixes,
-      List<String> excludedFixes,
-      int port,
-      String outputDir}) {
-    this.included = included;
-    this.includedFixes = includedFixes;
-    this.includePedanticFixes = includePedanticFixes;
-    this.excludedFixes = excludedFixes;
-    this.port = port;
-    this.outputDir = outputDir;
-  }
+  EditDartfixParams(this.included,
+      {this.includedFixes,
+      this.includePedanticFixes,
+      this.excludedFixes,
+      this.port,
+      this.outputDir});
 
   factory EditDartfixParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       List<String> included;
@@ -7492,26 +6050,26 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'included');
       }
-      List<String> includedFixes;
+      List<String>? includedFixes;
       if (json.containsKey('includedFixes')) {
         includedFixes = jsonDecoder.decodeList(jsonPath + '.includedFixes',
             json['includedFixes'], jsonDecoder.decodeString);
       }
-      bool includePedanticFixes;
+      bool? includePedanticFixes;
       if (json.containsKey('includePedanticFixes')) {
         includePedanticFixes = jsonDecoder.decodeBool(
             jsonPath + '.includePedanticFixes', json['includePedanticFixes']);
       }
-      List<String> excludedFixes;
+      List<String>? excludedFixes;
       if (json.containsKey('excludedFixes')) {
         excludedFixes = jsonDecoder.decodeList(jsonPath + '.excludedFixes',
             json['excludedFixes'], jsonDecoder.decodeString);
       }
-      int port;
+      int? port;
       if (json.containsKey('port')) {
         port = jsonDecoder.decodeInt(jsonPath + '.port', json['port']);
       }
-      String outputDir;
+      String? outputDir;
       if (json.containsKey('outputDir')) {
         outputDir = jsonDecoder.decodeString(
             jsonPath + '.outputDir', json['outputDir']);
@@ -7533,21 +6091,26 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['included'] = included;
+    var includedFixes = this.includedFixes;
     if (includedFixes != null) {
       result['includedFixes'] = includedFixes;
     }
+    var includePedanticFixes = this.includePedanticFixes;
     if (includePedanticFixes != null) {
       result['includePedanticFixes'] = includePedanticFixes;
     }
+    var excludedFixes = this.excludedFixes;
     if (excludedFixes != null) {
       result['excludedFixes'] = excludedFixes;
     }
+    var port = this.port;
     if (port != null) {
       result['port'] = port;
     }
+    var outputDir = this.outputDir;
     if (outputDir != null) {
       result['outputDir'] = outputDir;
     }
@@ -7605,117 +6168,42 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class EditDartfixResult implements ResponseResult {
-  List<DartFixSuggestion> _suggestions;
-
-  List<DartFixSuggestion> _otherSuggestions;
-
-  bool _hasErrors;
-
-  List<SourceFileEdit> _edits;
-
-  List<String> _details;
-
-  int _port;
-
-  List<String> _urls;
-
   /// A list of recommended changes that can be automatically made by applying
   /// the 'edits' included in this response.
-  List<DartFixSuggestion> get suggestions => _suggestions;
-
-  /// A list of recommended changes that can be automatically made by applying
-  /// the 'edits' included in this response.
-  set suggestions(List<DartFixSuggestion> value) {
-    assert(value != null);
-    _suggestions = value;
-  }
+  List<DartFixSuggestion> suggestions;
 
   /// A list of recommended changes that could not be automatically made.
-  List<DartFixSuggestion> get otherSuggestions => _otherSuggestions;
-
-  /// A list of recommended changes that could not be automatically made.
-  set otherSuggestions(List<DartFixSuggestion> value) {
-    assert(value != null);
-    _otherSuggestions = value;
-  }
+  List<DartFixSuggestion> otherSuggestions;
 
   /// True if the analyzed source contains errors that might impact the
   /// correctness of the recommended changes that can be automatically applied.
-  bool get hasErrors => _hasErrors;
-
-  /// True if the analyzed source contains errors that might impact the
-  /// correctness of the recommended changes that can be automatically applied.
-  set hasErrors(bool value) {
-    assert(value != null);
-    _hasErrors = value;
-  }
+  bool hasErrors;
 
   /// A list of source edits to apply the recommended changes.
-  List<SourceFileEdit> get edits => _edits;
-
-  /// A list of source edits to apply the recommended changes.
-  set edits(List<SourceFileEdit> value) {
-    assert(value != null);
-    _edits = value;
-  }
+  List<SourceFileEdit> edits;
 
   /// Messages that should be displayed to the user that describe details of
   /// the fix generation. For example, the messages might (a) point out details
   /// that users might want to explore before committing the changes or (b)
   /// describe exceptions that were thrown but that did not stop the fixes from
   /// being produced. The list will be omitted if it is empty.
-  List<String> get details => _details;
-
-  /// Messages that should be displayed to the user that describe details of
-  /// the fix generation. For example, the messages might (a) point out details
-  /// that users might want to explore before committing the changes or (b)
-  /// describe exceptions that were thrown but that did not stop the fixes from
-  /// being produced. The list will be omitted if it is empty.
-  set details(List<String> value) {
-    _details = value;
-  }
+  List<String>? details;
 
   /// The port on which the preview tool will respond to GET requests. The
   /// field is omitted if a preview was not requested.
-  int get port => _port;
-
-  /// The port on which the preview tool will respond to GET requests. The
-  /// field is omitted if a preview was not requested.
-  set port(int value) {
-    _port = value;
-  }
+  int? port;
 
   /// The URLs that users can visit in a browser to see a preview of the
   /// proposed changes. There is one URL for each of the included file paths.
   /// The field is omitted if a preview was not requested.
-  List<String> get urls => _urls;
-
-  /// The URLs that users can visit in a browser to see a preview of the
-  /// proposed changes. There is one URL for each of the included file paths.
-  /// The field is omitted if a preview was not requested.
-  set urls(List<String> value) {
-    _urls = value;
-  }
+  List<String>? urls;
 
   EditDartfixResult(
-      List<DartFixSuggestion> suggestions,
-      List<DartFixSuggestion> otherSuggestions,
-      bool hasErrors,
-      List<SourceFileEdit> edits,
-      {List<String> details,
-      int port,
-      List<String> urls}) {
-    this.suggestions = suggestions;
-    this.otherSuggestions = otherSuggestions;
-    this.hasErrors = hasErrors;
-    this.edits = edits;
-    this.details = details;
-    this.port = port;
-    this.urls = urls;
-  }
+      this.suggestions, this.otherSuggestions, this.hasErrors, this.edits,
+      {this.details, this.port, this.urls});
 
   factory EditDartfixResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       List<DartFixSuggestion> suggestions;
@@ -7723,7 +6211,7 @@
         suggestions = jsonDecoder.decodeList(
             jsonPath + '.suggestions',
             json['suggestions'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 DartFixSuggestion.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'suggestions');
@@ -7733,7 +6221,7 @@
         otherSuggestions = jsonDecoder.decodeList(
             jsonPath + '.otherSuggestions',
             json['otherSuggestions'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 DartFixSuggestion.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'otherSuggestions');
@@ -7750,21 +6238,21 @@
         edits = jsonDecoder.decodeList(
             jsonPath + '.edits',
             json['edits'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 SourceFileEdit.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'edits');
       }
-      List<String> details;
+      List<String>? details;
       if (json.containsKey('details')) {
         details = jsonDecoder.decodeList(
             jsonPath + '.details', json['details'], jsonDecoder.decodeString);
       }
-      int port;
+      int? port;
       if (json.containsKey('port')) {
         port = jsonDecoder.decodeInt(jsonPath + '.port', json['port']);
       }
-      List<String> urls;
+      List<String>? urls;
       if (json.containsKey('urls')) {
         urls = jsonDecoder.decodeList(
             jsonPath + '.urls', json['urls'], jsonDecoder.decodeString);
@@ -7784,8 +6272,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['suggestions'] =
         suggestions.map((DartFixSuggestion value) => value.toJson()).toList();
     result['otherSuggestions'] = otherSuggestions
@@ -7794,12 +6282,15 @@
     result['hasErrors'] = hasErrors;
     result['edits'] =
         edits.map((SourceFileEdit value) => value.toJson()).toList();
+    var details = this.details;
     if (details != null) {
       result['details'] = details;
     }
+    var port = this.port;
     if (port != null) {
       result['port'] = port;
     }
+    var urls = this.urls;
     if (urls != null) {
       result['urls'] = urls;
     }
@@ -7856,59 +6347,23 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class EditFormatParams implements RequestParams {
-  String _file;
-
-  int _selectionOffset;
-
-  int _selectionLength;
-
-  int _lineLength;
-
   /// The file containing the code to be formatted.
-  String get file => _file;
-
-  /// The file containing the code to be formatted.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// The offset of the current selection in the file.
-  int get selectionOffset => _selectionOffset;
-
-  /// The offset of the current selection in the file.
-  set selectionOffset(int value) {
-    assert(value != null);
-    _selectionOffset = value;
-  }
+  int selectionOffset;
 
   /// The length of the current selection in the file.
-  int get selectionLength => _selectionLength;
-
-  /// The length of the current selection in the file.
-  set selectionLength(int value) {
-    assert(value != null);
-    _selectionLength = value;
-  }
+  int selectionLength;
 
   /// The line length to be used by the formatter.
-  int get lineLength => _lineLength;
+  int? lineLength;
 
-  /// The line length to be used by the formatter.
-  set lineLength(int value) {
-    _lineLength = value;
-  }
-
-  EditFormatParams(String file, int selectionOffset, int selectionLength,
-      {int lineLength}) {
-    this.file = file;
-    this.selectionOffset = selectionOffset;
-    this.selectionLength = selectionLength;
-    this.lineLength = lineLength;
-  }
+  EditFormatParams(this.file, this.selectionOffset, this.selectionLength,
+      {this.lineLength});
 
   factory EditFormatParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -7931,7 +6386,7 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'selectionLength');
       }
-      int lineLength;
+      int? lineLength;
       if (json.containsKey('lineLength')) {
         lineLength =
             jsonDecoder.decodeInt(jsonPath + '.lineLength', json['lineLength']);
@@ -7949,11 +6404,12 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     result['selectionOffset'] = selectionOffset;
     result['selectionLength'] = selectionLength;
+    var lineLength = this.lineLength;
     if (lineLength != null) {
       result['lineLength'] = lineLength;
     }
@@ -8000,50 +6456,20 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class EditFormatResult implements ResponseResult {
-  List<SourceEdit> _edits;
-
-  int _selectionOffset;
-
-  int _selectionLength;
-
   /// The edit(s) to be applied in order to format the code. The list will be
   /// empty if the code was already formatted (there are no changes).
-  List<SourceEdit> get edits => _edits;
-
-  /// The edit(s) to be applied in order to format the code. The list will be
-  /// empty if the code was already formatted (there are no changes).
-  set edits(List<SourceEdit> value) {
-    assert(value != null);
-    _edits = value;
-  }
+  List<SourceEdit> edits;
 
   /// The offset of the selection after formatting the code.
-  int get selectionOffset => _selectionOffset;
-
-  /// The offset of the selection after formatting the code.
-  set selectionOffset(int value) {
-    assert(value != null);
-    _selectionOffset = value;
-  }
+  int selectionOffset;
 
   /// The length of the selection after formatting the code.
-  int get selectionLength => _selectionLength;
+  int selectionLength;
 
-  /// The length of the selection after formatting the code.
-  set selectionLength(int value) {
-    assert(value != null);
-    _selectionLength = value;
-  }
-
-  EditFormatResult(
-      List<SourceEdit> edits, int selectionOffset, int selectionLength) {
-    this.edits = edits;
-    this.selectionOffset = selectionOffset;
-    this.selectionLength = selectionLength;
-  }
+  EditFormatResult(this.edits, this.selectionOffset, this.selectionLength);
 
   factory EditFormatResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       List<SourceEdit> edits;
@@ -8051,7 +6477,7 @@
         edits = jsonDecoder.decodeList(
             jsonPath + '.edits',
             json['edits'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 SourceEdit.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'edits');
@@ -8084,8 +6510,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['edits'] = edits.map((SourceEdit value) => value.toJson()).toList();
     result['selectionOffset'] = selectionOffset;
     result['selectionLength'] = selectionLength;
@@ -8131,47 +6557,19 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class EditGetAssistsParams implements RequestParams {
-  String _file;
-
-  int _offset;
-
-  int _length;
-
   /// The file containing the code for which assists are being requested.
-  String get file => _file;
-
-  /// The file containing the code for which assists are being requested.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// The offset of the code for which assists are being requested.
-  int get offset => _offset;
-
-  /// The offset of the code for which assists are being requested.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
+  int offset;
 
   /// The length of the code for which assists are being requested.
-  int get length => _length;
+  int length;
 
-  /// The length of the code for which assists are being requested.
-  set length(int value) {
-    assert(value != null);
-    _length = value;
-  }
-
-  EditGetAssistsParams(String file, int offset, int length) {
-    this.file = file;
-    this.offset = offset;
-    this.length = length;
-  }
+  EditGetAssistsParams(this.file, this.offset, this.length);
 
   factory EditGetAssistsParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -8204,8 +6602,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     result['offset'] = offset;
     result['length'] = length;
@@ -8248,23 +6646,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class EditGetAssistsResult implements ResponseResult {
-  List<SourceChange> _assists;
-
   /// The assists that are available at the given location.
-  List<SourceChange> get assists => _assists;
+  List<SourceChange> assists;
 
-  /// The assists that are available at the given location.
-  set assists(List<SourceChange> value) {
-    assert(value != null);
-    _assists = value;
-  }
-
-  EditGetAssistsResult(List<SourceChange> assists) {
-    this.assists = assists;
-  }
+  EditGetAssistsResult(this.assists);
 
   factory EditGetAssistsResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       List<SourceChange> assists;
@@ -8272,7 +6660,7 @@
         assists = jsonDecoder.decodeList(
             jsonPath + '.assists',
             json['assists'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 SourceChange.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'assists');
@@ -8291,8 +6679,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['assists'] =
         assists.map((SourceChange value) => value.toJson()).toList();
     return result;
@@ -8333,47 +6721,19 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class EditGetAvailableRefactoringsParams implements RequestParams {
-  String _file;
-
-  int _offset;
-
-  int _length;
-
   /// The file containing the code on which the refactoring would be based.
-  String get file => _file;
-
-  /// The file containing the code on which the refactoring would be based.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// The offset of the code on which the refactoring would be based.
-  int get offset => _offset;
-
-  /// The offset of the code on which the refactoring would be based.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
+  int offset;
 
   /// The length of the code on which the refactoring would be based.
-  int get length => _length;
+  int length;
 
-  /// The length of the code on which the refactoring would be based.
-  set length(int value) {
-    assert(value != null);
-    _length = value;
-  }
-
-  EditGetAvailableRefactoringsParams(String file, int offset, int length) {
-    this.file = file;
-    this.offset = offset;
-    this.length = length;
-  }
+  EditGetAvailableRefactoringsParams(this.file, this.offset, this.length);
 
   factory EditGetAvailableRefactoringsParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -8407,8 +6767,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     result['offset'] = offset;
     result['length'] = length;
@@ -8451,23 +6811,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class EditGetAvailableRefactoringsResult implements ResponseResult {
-  List<RefactoringKind> _kinds;
-
   /// The kinds of refactorings that are valid for the given selection.
-  List<RefactoringKind> get kinds => _kinds;
+  List<RefactoringKind> kinds;
 
-  /// The kinds of refactorings that are valid for the given selection.
-  set kinds(List<RefactoringKind> value) {
-    assert(value != null);
-    _kinds = value;
-  }
-
-  EditGetAvailableRefactoringsResult(List<RefactoringKind> kinds) {
-    this.kinds = kinds;
-  }
+  EditGetAvailableRefactoringsResult(this.kinds);
 
   factory EditGetAvailableRefactoringsResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       List<RefactoringKind> kinds;
@@ -8475,7 +6825,7 @@
         kinds = jsonDecoder.decodeList(
             jsonPath + '.kinds',
             json['kinds'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 RefactoringKind.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'kinds');
@@ -8495,8 +6845,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['kinds'] =
         kinds.map((RefactoringKind value) => value.toJson()).toList();
     return result;
@@ -8537,7 +6887,7 @@
   EditGetDartfixInfoParams();
 
   factory EditGetDartfixInfoParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       return EditGetDartfixInfoParams();
@@ -8552,8 +6902,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     return result;
   }
 
@@ -8588,23 +6938,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class EditGetDartfixInfoResult implements ResponseResult {
-  List<DartFix> _fixes;
-
   /// A list of fixes that can be specified in an edit.dartfix request.
-  List<DartFix> get fixes => _fixes;
+  List<DartFix> fixes;
 
-  /// A list of fixes that can be specified in an edit.dartfix request.
-  set fixes(List<DartFix> value) {
-    assert(value != null);
-    _fixes = value;
-  }
-
-  EditGetDartfixInfoResult(List<DartFix> fixes) {
-    this.fixes = fixes;
-  }
+  EditGetDartfixInfoResult(this.fixes);
 
   factory EditGetDartfixInfoResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       List<DartFix> fixes;
@@ -8612,7 +6952,7 @@
         fixes = jsonDecoder.decodeList(
             jsonPath + '.fixes',
             json['fixes'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 DartFix.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'fixes');
@@ -8631,8 +6971,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['fixes'] = fixes.map((DartFix value) => value.toJson()).toList();
     return result;
   }
@@ -8670,35 +7010,16 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class EditGetFixesParams implements RequestParams {
-  String _file;
-
-  int _offset;
-
   /// The file containing the errors for which fixes are being requested.
-  String get file => _file;
-
-  /// The file containing the errors for which fixes are being requested.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// The offset used to select the errors for which fixes will be returned.
-  int get offset => _offset;
+  int offset;
 
-  /// The offset used to select the errors for which fixes will be returned.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
-
-  EditGetFixesParams(String file, int offset) {
-    this.file = file;
-    this.offset = offset;
-  }
+  EditGetFixesParams(this.file, this.offset);
 
   factory EditGetFixesParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -8725,8 +7046,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     result['offset'] = offset;
     return result;
@@ -8765,23 +7086,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class EditGetFixesResult implements ResponseResult {
-  List<AnalysisErrorFixes> _fixes;
-
   /// The fixes that are available for the errors at the given offset.
-  List<AnalysisErrorFixes> get fixes => _fixes;
+  List<AnalysisErrorFixes> fixes;
 
-  /// The fixes that are available for the errors at the given offset.
-  set fixes(List<AnalysisErrorFixes> value) {
-    assert(value != null);
-    _fixes = value;
-  }
-
-  EditGetFixesResult(List<AnalysisErrorFixes> fixes) {
-    this.fixes = fixes;
-  }
+  EditGetFixesResult(this.fixes);
 
   factory EditGetFixesResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       List<AnalysisErrorFixes> fixes;
@@ -8789,7 +7100,7 @@
         fixes = jsonDecoder.decodeList(
             jsonPath + '.fixes',
             json['fixes'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 AnalysisErrorFixes.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'fixes');
@@ -8808,8 +7119,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['fixes'] =
         fixes.map((AnalysisErrorFixes value) => value.toJson()).toList();
     return result;
@@ -8850,49 +7161,20 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class EditGetPostfixCompletionParams implements RequestParams {
-  String _file;
-
-  String _key;
-
-  int _offset;
-
   /// The file containing the postfix template to be expanded.
-  String get file => _file;
-
-  /// The file containing the postfix template to be expanded.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// The unique name that identifies the template in use.
-  String get key => _key;
-
-  /// The unique name that identifies the template in use.
-  set key(String value) {
-    assert(value != null);
-    _key = value;
-  }
+  String key;
 
   /// The offset used to identify the code to which the template will be
   /// applied.
-  int get offset => _offset;
+  int offset;
 
-  /// The offset used to identify the code to which the template will be
-  /// applied.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
-
-  EditGetPostfixCompletionParams(String file, String key, int offset) {
-    this.file = file;
-    this.key = key;
-    this.offset = offset;
-  }
+  EditGetPostfixCompletionParams(this.file, this.key, this.offset);
 
   factory EditGetPostfixCompletionParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -8926,8 +7208,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     result['key'] = key;
     result['offset'] = offset;
@@ -8968,23 +7250,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class EditGetPostfixCompletionResult implements ResponseResult {
-  SourceChange _change;
-
   /// The change to be applied in order to complete the statement.
-  SourceChange get change => _change;
+  SourceChange change;
 
-  /// The change to be applied in order to complete the statement.
-  set change(SourceChange value) {
-    assert(value != null);
-    _change = value;
-  }
-
-  EditGetPostfixCompletionResult(SourceChange change) {
-    this.change = change;
-  }
+  EditGetPostfixCompletionResult(this.change);
 
   factory EditGetPostfixCompletionResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       SourceChange change;
@@ -9009,8 +7281,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['change'] = change.toJson();
     return result;
   }
@@ -9052,94 +7324,35 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class EditGetRefactoringParams implements RequestParams {
-  RefactoringKind _kind;
-
-  String _file;
-
-  int _offset;
-
-  int _length;
-
-  bool _validateOnly;
-
-  RefactoringOptions _options;
-
   /// The kind of refactoring to be performed.
-  RefactoringKind get kind => _kind;
-
-  /// The kind of refactoring to be performed.
-  set kind(RefactoringKind value) {
-    assert(value != null);
-    _kind = value;
-  }
+  RefactoringKind kind;
 
   /// The file containing the code involved in the refactoring.
-  String get file => _file;
-
-  /// The file containing the code involved in the refactoring.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// The offset of the region involved in the refactoring.
-  int get offset => _offset;
-
-  /// The offset of the region involved in the refactoring.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
+  int offset;
 
   /// The length of the region involved in the refactoring.
-  int get length => _length;
-
-  /// The length of the region involved in the refactoring.
-  set length(int value) {
-    assert(value != null);
-    _length = value;
-  }
+  int length;
 
   /// True if the client is only requesting that the values of the options be
   /// validated and no change be generated.
-  bool get validateOnly => _validateOnly;
-
-  /// True if the client is only requesting that the values of the options be
-  /// validated and no change be generated.
-  set validateOnly(bool value) {
-    assert(value != null);
-    _validateOnly = value;
-  }
+  bool validateOnly;
 
   /// Data used to provide values provided by the user. The structure of the
   /// data is dependent on the kind of refactoring being performed. The data
   /// that is expected is documented in the section titled Refactorings,
   /// labeled as "Options". This field can be omitted if the refactoring does
   /// not require any options or if the values of those options are not known.
-  RefactoringOptions get options => _options;
+  RefactoringOptions? options;
 
-  /// Data used to provide values provided by the user. The structure of the
-  /// data is dependent on the kind of refactoring being performed. The data
-  /// that is expected is documented in the section titled Refactorings,
-  /// labeled as "Options". This field can be omitted if the refactoring does
-  /// not require any options or if the values of those options are not known.
-  set options(RefactoringOptions value) {
-    _options = value;
-  }
-
-  EditGetRefactoringParams(RefactoringKind kind, String file, int offset,
-      int length, bool validateOnly,
-      {RefactoringOptions options}) {
-    this.kind = kind;
-    this.file = file;
-    this.offset = offset;
-    this.length = length;
-    this.validateOnly = validateOnly;
-    this.options = options;
-  }
+  EditGetRefactoringParams(
+      this.kind, this.file, this.offset, this.length, this.validateOnly,
+      {this.options});
 
   factory EditGetRefactoringParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       RefactoringKind kind;
@@ -9174,7 +7387,7 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'validateOnly');
       }
-      RefactoringOptions options;
+      RefactoringOptions? options;
       if (json.containsKey('options')) {
         options = RefactoringOptions.fromJson(
             jsonDecoder, jsonPath + '.options', json['options'], kind);
@@ -9194,13 +7407,14 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['kind'] = kind.toJson();
     result['file'] = file;
     result['offset'] = offset;
     result['length'] = length;
     result['validateOnly'] = validateOnly;
+    var options = this.options;
     if (options != null) {
       result['options'] = options.toJson();
     }
@@ -9254,84 +7468,32 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class EditGetRefactoringResult implements ResponseResult {
-  List<RefactoringProblem> _initialProblems;
-
-  List<RefactoringProblem> _optionsProblems;
-
-  List<RefactoringProblem> _finalProblems;
-
-  RefactoringFeedback _feedback;
-
-  SourceChange _change;
-
-  List<String> _potentialEdits;
-
   /// The initial status of the refactoring, i.e. problems related to the
   /// context in which the refactoring is requested. The array will be empty if
   /// there are no known problems.
-  List<RefactoringProblem> get initialProblems => _initialProblems;
-
-  /// The initial status of the refactoring, i.e. problems related to the
-  /// context in which the refactoring is requested. The array will be empty if
-  /// there are no known problems.
-  set initialProblems(List<RefactoringProblem> value) {
-    assert(value != null);
-    _initialProblems = value;
-  }
+  List<RefactoringProblem> initialProblems;
 
   /// The options validation status, i.e. problems in the given options, such
   /// as light-weight validation of a new name, flags compatibility, etc. The
   /// array will be empty if there are no known problems.
-  List<RefactoringProblem> get optionsProblems => _optionsProblems;
-
-  /// The options validation status, i.e. problems in the given options, such
-  /// as light-weight validation of a new name, flags compatibility, etc. The
-  /// array will be empty if there are no known problems.
-  set optionsProblems(List<RefactoringProblem> value) {
-    assert(value != null);
-    _optionsProblems = value;
-  }
+  List<RefactoringProblem> optionsProblems;
 
   /// The final status of the refactoring, i.e. problems identified in the
   /// result of a full, potentially expensive validation and / or change
   /// creation. The array will be empty if there are no known problems.
-  List<RefactoringProblem> get finalProblems => _finalProblems;
-
-  /// The final status of the refactoring, i.e. problems identified in the
-  /// result of a full, potentially expensive validation and / or change
-  /// creation. The array will be empty if there are no known problems.
-  set finalProblems(List<RefactoringProblem> value) {
-    assert(value != null);
-    _finalProblems = value;
-  }
+  List<RefactoringProblem> finalProblems;
 
   /// Data used to provide feedback to the user. The structure of the data is
   /// dependent on the kind of refactoring being created. The data that is
   /// returned is documented in the section titled Refactorings, labeled as
   /// "Feedback".
-  RefactoringFeedback get feedback => _feedback;
-
-  /// Data used to provide feedback to the user. The structure of the data is
-  /// dependent on the kind of refactoring being created. The data that is
-  /// returned is documented in the section titled Refactorings, labeled as
-  /// "Feedback".
-  set feedback(RefactoringFeedback value) {
-    _feedback = value;
-  }
+  RefactoringFeedback? feedback;
 
   /// The changes that are to be applied to affect the refactoring. This field
   /// will be omitted if there are problems that prevent a set of changes from
   /// being computed, such as having no options specified for a refactoring
   /// that requires them, or if only validation was requested.
-  SourceChange get change => _change;
-
-  /// The changes that are to be applied to affect the refactoring. This field
-  /// will be omitted if there are problems that prevent a set of changes from
-  /// being computed, such as having no options specified for a refactoring
-  /// that requires them, or if only validation was requested.
-  set change(SourceChange value) {
-    _change = value;
-  }
+  SourceChange? change;
 
   /// The ids of source edits that are not known to be valid. An edit is not
   /// known to be valid if there was insufficient type information for the
@@ -9340,36 +7502,14 @@
   /// to a member from an unknown type. This field will be omitted if the
   /// change field is omitted or if there are no potential edits for the
   /// refactoring.
-  List<String> get potentialEdits => _potentialEdits;
-
-  /// The ids of source edits that are not known to be valid. An edit is not
-  /// known to be valid if there was insufficient type information for the
-  /// server to be able to determine whether or not the code needs to be
-  /// modified, such as when a member is being renamed and there is a reference
-  /// to a member from an unknown type. This field will be omitted if the
-  /// change field is omitted or if there are no potential edits for the
-  /// refactoring.
-  set potentialEdits(List<String> value) {
-    _potentialEdits = value;
-  }
+  List<String>? potentialEdits;
 
   EditGetRefactoringResult(
-      List<RefactoringProblem> initialProblems,
-      List<RefactoringProblem> optionsProblems,
-      List<RefactoringProblem> finalProblems,
-      {RefactoringFeedback feedback,
-      SourceChange change,
-      List<String> potentialEdits}) {
-    this.initialProblems = initialProblems;
-    this.optionsProblems = optionsProblems;
-    this.finalProblems = finalProblems;
-    this.feedback = feedback;
-    this.change = change;
-    this.potentialEdits = potentialEdits;
-  }
+      this.initialProblems, this.optionsProblems, this.finalProblems,
+      {this.feedback, this.change, this.potentialEdits});
 
   factory EditGetRefactoringResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       List<RefactoringProblem> initialProblems;
@@ -9377,7 +7517,7 @@
         initialProblems = jsonDecoder.decodeList(
             jsonPath + '.initialProblems',
             json['initialProblems'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 RefactoringProblem.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'initialProblems');
@@ -9387,7 +7527,7 @@
         optionsProblems = jsonDecoder.decodeList(
             jsonPath + '.optionsProblems',
             json['optionsProblems'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 RefactoringProblem.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'optionsProblems');
@@ -9397,22 +7537,22 @@
         finalProblems = jsonDecoder.decodeList(
             jsonPath + '.finalProblems',
             json['finalProblems'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 RefactoringProblem.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'finalProblems');
       }
-      RefactoringFeedback feedback;
+      RefactoringFeedback? feedback;
       if (json.containsKey('feedback')) {
         feedback = RefactoringFeedback.fromJson(
             jsonDecoder, jsonPath + '.feedback', json['feedback'], json);
       }
-      SourceChange change;
+      SourceChange? change;
       if (json.containsKey('change')) {
         change = SourceChange.fromJson(
             jsonDecoder, jsonPath + '.change', json['change']);
       }
-      List<String> potentialEdits;
+      List<String>? potentialEdits;
       if (json.containsKey('potentialEdits')) {
         potentialEdits = jsonDecoder.decodeList(jsonPath + '.potentialEdits',
             json['potentialEdits'], jsonDecoder.decodeString);
@@ -9433,8 +7573,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['initialProblems'] = initialProblems
         .map((RefactoringProblem value) => value.toJson())
         .toList();
@@ -9444,12 +7584,15 @@
     result['finalProblems'] = finalProblems
         .map((RefactoringProblem value) => value.toJson())
         .toList();
+    var feedback = this.feedback;
     if (feedback != null) {
       result['feedback'] = feedback.toJson();
     }
+    var change = this.change;
     if (change != null) {
       result['change'] = change.toJson();
     }
+    var potentialEdits = this.potentialEdits;
     if (potentialEdits != null) {
       result['potentialEdits'] = potentialEdits;
     }
@@ -9503,35 +7646,16 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class EditGetStatementCompletionParams implements RequestParams {
-  String _file;
-
-  int _offset;
-
   /// The file containing the statement to be completed.
-  String get file => _file;
-
-  /// The file containing the statement to be completed.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// The offset used to identify the statement to be completed.
-  int get offset => _offset;
+  int offset;
 
-  /// The offset used to identify the statement to be completed.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
-
-  EditGetStatementCompletionParams(String file, int offset) {
-    this.file = file;
-    this.offset = offset;
-  }
+  EditGetStatementCompletionParams(this.file, this.offset);
 
   factory EditGetStatementCompletionParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -9559,8 +7683,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     result['offset'] = offset;
     return result;
@@ -9600,37 +7724,17 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class EditGetStatementCompletionResult implements ResponseResult {
-  SourceChange _change;
-
-  bool _whitespaceOnly;
-
   /// The change to be applied in order to complete the statement.
-  SourceChange get change => _change;
-
-  /// The change to be applied in order to complete the statement.
-  set change(SourceChange value) {
-    assert(value != null);
-    _change = value;
-  }
+  SourceChange change;
 
   /// Will be true if the change contains nothing but whitespace characters, or
   /// is empty.
-  bool get whitespaceOnly => _whitespaceOnly;
+  bool whitespaceOnly;
 
-  /// Will be true if the change contains nothing but whitespace characters, or
-  /// is empty.
-  set whitespaceOnly(bool value) {
-    assert(value != null);
-    _whitespaceOnly = value;
-  }
-
-  EditGetStatementCompletionResult(SourceChange change, bool whitespaceOnly) {
-    this.change = change;
-    this.whitespaceOnly = whitespaceOnly;
-  }
+  EditGetStatementCompletionResult(this.change, this.whitespaceOnly);
 
   factory EditGetStatementCompletionResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       SourceChange change;
@@ -9662,8 +7766,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['change'] = change.toJson();
     result['whitespaceOnly'] = whitespaceOnly;
     return result;
@@ -9704,53 +7808,22 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class EditImportElementsParams implements RequestParams {
-  String _file;
-
-  List<ImportedElements> _elements;
-
-  int _offset;
-
   /// The file in which the specified elements are to be made accessible.
-  String get file => _file;
-
-  /// The file in which the specified elements are to be made accessible.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// The elements to be made accessible in the specified file.
-  List<ImportedElements> get elements => _elements;
-
-  /// The elements to be made accessible in the specified file.
-  set elements(List<ImportedElements> value) {
-    assert(value != null);
-    _elements = value;
-  }
+  List<ImportedElements> elements;
 
   /// The offset at which the specified elements need to be made accessible. If
   /// provided, this is used to guard against adding imports for text that
   /// would be inserted into a comment, string literal, or other location where
   /// the imports would not be necessary.
-  int get offset => _offset;
+  int? offset;
 
-  /// The offset at which the specified elements need to be made accessible. If
-  /// provided, this is used to guard against adding imports for text that
-  /// would be inserted into a comment, string literal, or other location where
-  /// the imports would not be necessary.
-  set offset(int value) {
-    _offset = value;
-  }
-
-  EditImportElementsParams(String file, List<ImportedElements> elements,
-      {int offset}) {
-    this.file = file;
-    this.elements = elements;
-    this.offset = offset;
-  }
+  EditImportElementsParams(this.file, this.elements, {this.offset});
 
   factory EditImportElementsParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -9764,12 +7837,12 @@
         elements = jsonDecoder.decodeList(
             jsonPath + '.elements',
             json['elements'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 ImportedElements.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'elements');
       }
-      int offset;
+      int? offset;
       if (json.containsKey('offset')) {
         offset = jsonDecoder.decodeInt(jsonPath + '.offset', json['offset']);
       }
@@ -9785,11 +7858,12 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     result['elements'] =
         elements.map((ImportedElements value) => value.toJson()).toList();
+    var offset = this.offset;
     if (offset != null) {
       result['offset'] = offset;
     }
@@ -9833,35 +7907,21 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class EditImportElementsResult implements ResponseResult {
-  SourceFileEdit _edit;
-
   /// The edits to be applied in order to make the specified elements
   /// accessible. The file to be edited will be the defining compilation unit
   /// of the library containing the file specified in the request, which can be
   /// different than the file specified in the request if the specified file is
   /// a part file. This field will be omitted if there are no edits that need
   /// to be applied.
-  SourceFileEdit get edit => _edit;
+  SourceFileEdit? edit;
 
-  /// The edits to be applied in order to make the specified elements
-  /// accessible. The file to be edited will be the defining compilation unit
-  /// of the library containing the file specified in the request, which can be
-  /// different than the file specified in the request if the specified file is
-  /// a part file. This field will be omitted if there are no edits that need
-  /// to be applied.
-  set edit(SourceFileEdit value) {
-    _edit = value;
-  }
-
-  EditImportElementsResult({SourceFileEdit edit}) {
-    this.edit = edit;
-  }
+  EditImportElementsResult({this.edit});
 
   factory EditImportElementsResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
-      SourceFileEdit edit;
+      SourceFileEdit? edit;
       if (json.containsKey('edit')) {
         edit = SourceFileEdit.fromJson(
             jsonDecoder, jsonPath + '.edit', json['edit']);
@@ -9880,8 +7940,9 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
+    var edit = this.edit;
     if (edit != null) {
       result['edit'] = edit.toJson();
     }
@@ -9922,49 +7983,20 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class EditIsPostfixCompletionApplicableParams implements RequestParams {
-  String _file;
-
-  String _key;
-
-  int _offset;
-
   /// The file containing the postfix template to be expanded.
-  String get file => _file;
-
-  /// The file containing the postfix template to be expanded.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// The unique name that identifies the template in use.
-  String get key => _key;
-
-  /// The unique name that identifies the template in use.
-  set key(String value) {
-    assert(value != null);
-    _key = value;
-  }
+  String key;
 
   /// The offset used to identify the code to which the template will be
   /// applied.
-  int get offset => _offset;
+  int offset;
 
-  /// The offset used to identify the code to which the template will be
-  /// applied.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
-
-  EditIsPostfixCompletionApplicableParams(String file, String key, int offset) {
-    this.file = file;
-    this.key = key;
-    this.offset = offset;
-  }
+  EditIsPostfixCompletionApplicableParams(this.file, this.key, this.offset);
 
   factory EditIsPostfixCompletionApplicableParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -9998,8 +8030,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     result['key'] = key;
     result['offset'] = offset;
@@ -10040,23 +8072,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class EditIsPostfixCompletionApplicableResult implements ResponseResult {
-  bool _value;
-
   /// True if the template can be expanded at the given location.
-  bool get value => _value;
+  bool value;
 
-  /// True if the template can be expanded at the given location.
-  set value(bool value) {
-    assert(value != null);
-    _value = value;
-  }
-
-  EditIsPostfixCompletionApplicableResult(bool value) {
-    this.value = value;
-  }
+  EditIsPostfixCompletionApplicableResult(this.value);
 
   factory EditIsPostfixCompletionApplicableResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       bool value;
@@ -10081,8 +8103,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['value'] = value;
     return result;
   }
@@ -10116,7 +8138,7 @@
 /// Clients may not extend, implement or mix-in this class.
 class EditListPostfixCompletionTemplatesParams implements RequestParams {
   @override
-  Map<String, dynamic> toJson() => <String, dynamic>{};
+  Map<String, Object> toJson() => <String, Object>{};
 
   @override
   Request toRequest(String id) {
@@ -10145,24 +8167,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class EditListPostfixCompletionTemplatesResult implements ResponseResult {
-  List<PostfixTemplateDescriptor> _templates;
-
   /// The list of available templates.
-  List<PostfixTemplateDescriptor> get templates => _templates;
+  List<PostfixTemplateDescriptor> templates;
 
-  /// The list of available templates.
-  set templates(List<PostfixTemplateDescriptor> value) {
-    assert(value != null);
-    _templates = value;
-  }
-
-  EditListPostfixCompletionTemplatesResult(
-      List<PostfixTemplateDescriptor> templates) {
-    this.templates = templates;
-  }
+  EditListPostfixCompletionTemplatesResult(this.templates);
 
   factory EditListPostfixCompletionTemplatesResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       List<PostfixTemplateDescriptor> templates;
@@ -10170,7 +8181,7 @@
         templates = jsonDecoder.decodeList(
             jsonPath + '.templates',
             json['templates'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 PostfixTemplateDescriptor.fromJson(
                     jsonDecoder, jsonPath, json));
       } else {
@@ -10192,8 +8203,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['templates'] = templates
         .map((PostfixTemplateDescriptor value) => value.toJson())
         .toList();
@@ -10233,23 +8244,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class EditOrganizeDirectivesParams implements RequestParams {
-  String _file;
-
   /// The Dart file to organize directives in.
-  String get file => _file;
+  String file;
 
-  /// The Dart file to organize directives in.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
-
-  EditOrganizeDirectivesParams(String file) {
-    this.file = file;
-  }
+  EditOrganizeDirectivesParams(this.file);
 
   factory EditOrganizeDirectivesParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -10271,8 +8272,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     return result;
   }
@@ -10309,25 +8310,14 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class EditOrganizeDirectivesResult implements ResponseResult {
-  SourceFileEdit _edit;
-
   /// The file edit that is to be applied to the given file to effect the
   /// organizing.
-  SourceFileEdit get edit => _edit;
+  SourceFileEdit edit;
 
-  /// The file edit that is to be applied to the given file to effect the
-  /// organizing.
-  set edit(SourceFileEdit value) {
-    assert(value != null);
-    _edit = value;
-  }
-
-  EditOrganizeDirectivesResult(SourceFileEdit edit) {
-    this.edit = edit;
-  }
+  EditOrganizeDirectivesResult(this.edit);
 
   factory EditOrganizeDirectivesResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       SourceFileEdit edit;
@@ -10352,8 +8342,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['edit'] = edit.toJson();
     return result;
   }
@@ -10390,23 +8380,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class EditSortMembersParams implements RequestParams {
-  String _file;
-
   /// The Dart file to sort.
-  String get file => _file;
+  String file;
 
-  /// The Dart file to sort.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
-
-  EditSortMembersParams(String file) {
-    this.file = file;
-  }
+  EditSortMembersParams(this.file);
 
   factory EditSortMembersParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -10427,8 +8407,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     return result;
   }
@@ -10465,25 +8445,14 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class EditSortMembersResult implements ResponseResult {
-  SourceFileEdit _edit;
-
   /// The file edit that is to be applied to the given file to effect the
   /// sorting.
-  SourceFileEdit get edit => _edit;
+  SourceFileEdit edit;
 
-  /// The file edit that is to be applied to the given file to effect the
-  /// sorting.
-  set edit(SourceFileEdit value) {
-    assert(value != null);
-    _edit = value;
-  }
-
-  EditSortMembersResult(SourceFileEdit edit) {
-    this.edit = edit;
-  }
+  EditSortMembersResult(this.edit);
 
   factory EditSortMembersResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       SourceFileEdit edit;
@@ -10507,8 +8476,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['edit'] = edit.toJson();
     return result;
   }
@@ -10555,119 +8524,37 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class ElementDeclaration implements HasToJson {
-  String _name;
-
-  ElementKind _kind;
-
-  int _fileIndex;
-
-  int _offset;
-
-  int _line;
-
-  int _column;
-
-  int _codeOffset;
-
-  int _codeLength;
-
-  String _className;
-
-  String _mixinName;
-
-  String _parameters;
-
   /// The name of the declaration.
-  String get name => _name;
-
-  /// The name of the declaration.
-  set name(String value) {
-    assert(value != null);
-    _name = value;
-  }
+  String name;
 
   /// The kind of the element that corresponds to the declaration.
-  ElementKind get kind => _kind;
-
-  /// The kind of the element that corresponds to the declaration.
-  set kind(ElementKind value) {
-    assert(value != null);
-    _kind = value;
-  }
+  ElementKind kind;
 
   /// The index of the file (in the enclosing response).
-  int get fileIndex => _fileIndex;
-
-  /// The index of the file (in the enclosing response).
-  set fileIndex(int value) {
-    assert(value != null);
-    _fileIndex = value;
-  }
+  int fileIndex;
 
   /// The offset of the declaration name in the file.
-  int get offset => _offset;
-
-  /// The offset of the declaration name in the file.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
+  int offset;
 
   /// The one-based index of the line containing the declaration name.
-  int get line => _line;
-
-  /// The one-based index of the line containing the declaration name.
-  set line(int value) {
-    assert(value != null);
-    _line = value;
-  }
+  int line;
 
   /// The one-based index of the column containing the declaration name.
-  int get column => _column;
-
-  /// The one-based index of the column containing the declaration name.
-  set column(int value) {
-    assert(value != null);
-    _column = value;
-  }
+  int column;
 
   /// The offset of the first character of the declaration code in the file.
-  int get codeOffset => _codeOffset;
-
-  /// The offset of the first character of the declaration code in the file.
-  set codeOffset(int value) {
-    assert(value != null);
-    _codeOffset = value;
-  }
+  int codeOffset;
 
   /// The length of the declaration code in the file.
-  int get codeLength => _codeLength;
-
-  /// The length of the declaration code in the file.
-  set codeLength(int value) {
-    assert(value != null);
-    _codeLength = value;
-  }
+  int codeLength;
 
   /// The name of the class enclosing this declaration. If the declaration is
   /// not a class member, this field will be absent.
-  String get className => _className;
-
-  /// The name of the class enclosing this declaration. If the declaration is
-  /// not a class member, this field will be absent.
-  set className(String value) {
-    _className = value;
-  }
+  String? className;
 
   /// The name of the mixin enclosing this declaration. If the declaration is
   /// not a mixin member, this field will be absent.
-  String get mixinName => _mixinName;
-
-  /// The name of the mixin enclosing this declaration. If the declaration is
-  /// not a mixin member, this field will be absent.
-  set mixinName(String value) {
-    _mixinName = value;
-  }
+  String? mixinName;
 
   /// The parameter list for the element. If the element is not a method or
   /// function this field will not be defined. If the element doesn't have
@@ -10675,36 +8562,14 @@
   /// has zero parameters, this field will have a value of "()". The value
   /// should not be treated as exact presentation of parameters, it is just
   /// approximation of parameters to give the user general idea.
-  String get parameters => _parameters;
+  String? parameters;
 
-  /// The parameter list for the element. If the element is not a method or
-  /// function this field will not be defined. If the element doesn't have
-  /// parameters (e.g. getter), this field will not be defined. If the element
-  /// has zero parameters, this field will have a value of "()". The value
-  /// should not be treated as exact presentation of parameters, it is just
-  /// approximation of parameters to give the user general idea.
-  set parameters(String value) {
-    _parameters = value;
-  }
-
-  ElementDeclaration(String name, ElementKind kind, int fileIndex, int offset,
-      int line, int column, int codeOffset, int codeLength,
-      {String className, String mixinName, String parameters}) {
-    this.name = name;
-    this.kind = kind;
-    this.fileIndex = fileIndex;
-    this.offset = offset;
-    this.line = line;
-    this.column = column;
-    this.codeOffset = codeOffset;
-    this.codeLength = codeLength;
-    this.className = className;
-    this.mixinName = mixinName;
-    this.parameters = parameters;
-  }
+  ElementDeclaration(this.name, this.kind, this.fileIndex, this.offset,
+      this.line, this.column, this.codeOffset, this.codeLength,
+      {this.className, this.mixinName, this.parameters});
 
   factory ElementDeclaration.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String name;
@@ -10759,17 +8624,17 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'codeLength');
       }
-      String className;
+      String? className;
       if (json.containsKey('className')) {
         className = jsonDecoder.decodeString(
             jsonPath + '.className', json['className']);
       }
-      String mixinName;
+      String? mixinName;
       if (json.containsKey('mixinName')) {
         mixinName = jsonDecoder.decodeString(
             jsonPath + '.mixinName', json['mixinName']);
       }
-      String parameters;
+      String? parameters;
       if (json.containsKey('parameters')) {
         parameters = jsonDecoder.decodeString(
             jsonPath + '.parameters', json['parameters']);
@@ -10783,8 +8648,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['name'] = name;
     result['kind'] = kind.toJson();
     result['fileIndex'] = fileIndex;
@@ -10793,12 +8658,15 @@
     result['column'] = column;
     result['codeOffset'] = codeOffset;
     result['codeLength'] = codeLength;
+    var className = this.className;
     if (className != null) {
       result['className'] = className;
     }
+    var mixinName = this.mixinName;
     if (mixinName != null) {
       result['mixinName'] = mixinName;
     }
+    var parameters = this.parameters;
     if (parameters != null) {
       result['parameters'] = parameters;
     }
@@ -10853,35 +8721,16 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class ExecutableFile implements HasToJson {
-  String _file;
-
-  ExecutableKind _kind;
-
   /// The path of the executable file.
-  String get file => _file;
-
-  /// The path of the executable file.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// The kind of the executable file.
-  ExecutableKind get kind => _kind;
+  ExecutableKind kind;
 
-  /// The kind of the executable file.
-  set kind(ExecutableKind value) {
-    assert(value != null);
-    _kind = value;
-  }
-
-  ExecutableFile(String file, ExecutableKind kind) {
-    this.file = file;
-    this.kind = kind;
-  }
+  ExecutableFile(this.file, this.kind);
 
   factory ExecutableFile.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -10904,8 +8753,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     result['kind'] = kind.toJson();
     return result;
@@ -10979,7 +8828,7 @@
   }
 
   factory ExecutableKind.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     if (json is String) {
       try {
         return ExecutableKind(json);
@@ -11004,25 +8853,14 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class ExecutionCreateContextParams implements RequestParams {
-  String _contextRoot;
-
   /// The path of the Dart or HTML file that will be launched, or the path of
   /// the directory containing the file.
-  String get contextRoot => _contextRoot;
+  String contextRoot;
 
-  /// The path of the Dart or HTML file that will be launched, or the path of
-  /// the directory containing the file.
-  set contextRoot(String value) {
-    assert(value != null);
-    _contextRoot = value;
-  }
-
-  ExecutionCreateContextParams(String contextRoot) {
-    this.contextRoot = contextRoot;
-  }
+  ExecutionCreateContextParams(this.contextRoot);
 
   factory ExecutionCreateContextParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String contextRoot;
@@ -11045,8 +8883,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['contextRoot'] = contextRoot;
     return result;
   }
@@ -11083,23 +8921,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class ExecutionCreateContextResult implements ResponseResult {
-  String _id;
-
   /// The identifier used to refer to the execution context that was created.
-  String get id => _id;
+  String id;
 
-  /// The identifier used to refer to the execution context that was created.
-  set id(String value) {
-    assert(value != null);
-    _id = value;
-  }
-
-  ExecutionCreateContextResult(String id) {
-    this.id = id;
-  }
+  ExecutionCreateContextResult(this.id);
 
   factory ExecutionCreateContextResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String id;
@@ -11123,8 +8951,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['id'] = id;
     return result;
   }
@@ -11161,23 +8989,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class ExecutionDeleteContextParams implements RequestParams {
-  String _id;
-
   /// The identifier of the execution context that is to be deleted.
-  String get id => _id;
+  String id;
 
-  /// The identifier of the execution context that is to be deleted.
-  set id(String value) {
-    assert(value != null);
-    _id = value;
-  }
-
-  ExecutionDeleteContextParams(String id) {
-    this.id = id;
-  }
+  ExecutionDeleteContextParams(this.id);
 
   factory ExecutionDeleteContextParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String id;
@@ -11199,8 +9017,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['id'] = id;
     return result;
   }
@@ -11234,7 +9052,7 @@
 /// Clients may not extend, implement or mix-in this class.
 class ExecutionDeleteContextResult implements ResponseResult {
   @override
-  Map<String, dynamic> toJson() => <String, dynamic>{};
+  Map<String, Object> toJson() => <String, Object>{};
 
   @override
   Response toResponse(String id) {
@@ -11268,72 +9086,25 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class ExecutionGetSuggestionsParams implements RequestParams {
-  String _code;
-
-  int _offset;
-
-  String _contextFile;
-
-  int _contextOffset;
-
-  List<RuntimeCompletionVariable> _variables;
-
-  List<RuntimeCompletionExpression> _expressions;
-
   /// The code to get suggestions in.
-  String get code => _code;
-
-  /// The code to get suggestions in.
-  set code(String value) {
-    assert(value != null);
-    _code = value;
-  }
+  String code;
 
   /// The offset within the code to get suggestions at.
-  int get offset => _offset;
-
-  /// The offset within the code to get suggestions at.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
+  int offset;
 
   /// The path of the context file, e.g. the file of the current debugger
   /// frame. The combination of the context file and context offset can be used
   /// to ensure that all variables of the context are available for completion
   /// (with their static types).
-  String get contextFile => _contextFile;
-
-  /// The path of the context file, e.g. the file of the current debugger
-  /// frame. The combination of the context file and context offset can be used
-  /// to ensure that all variables of the context are available for completion
-  /// (with their static types).
-  set contextFile(String value) {
-    assert(value != null);
-    _contextFile = value;
-  }
+  String contextFile;
 
   /// The offset in the context file, e.g. the line offset in the current
   /// debugger frame.
-  int get contextOffset => _contextOffset;
-
-  /// The offset in the context file, e.g. the line offset in the current
-  /// debugger frame.
-  set contextOffset(int value) {
-    assert(value != null);
-    _contextOffset = value;
-  }
+  int contextOffset;
 
   /// The runtime context variables that are potentially referenced in the
   /// code.
-  List<RuntimeCompletionVariable> get variables => _variables;
-
-  /// The runtime context variables that are potentially referenced in the
-  /// code.
-  set variables(List<RuntimeCompletionVariable> value) {
-    assert(value != null);
-    _variables = value;
-  }
+  List<RuntimeCompletionVariable> variables;
 
   /// The list of sub-expressions in the code for which the client wants to
   /// provide runtime types. It does not have to be the full list of
@@ -11344,34 +9115,14 @@
   /// only when there are no interesting sub-expressions in the given code. The
   /// client may provide an empty list, in this case the server will return
   /// completion suggestions.
-  List<RuntimeCompletionExpression> get expressions => _expressions;
+  List<RuntimeCompletionExpression>? expressions;
 
-  /// The list of sub-expressions in the code for which the client wants to
-  /// provide runtime types. It does not have to be the full list of
-  /// expressions requested by the server, for missing expressions their static
-  /// types will be used.
-  ///
-  /// When this field is omitted, the server will return completion suggestions
-  /// only when there are no interesting sub-expressions in the given code. The
-  /// client may provide an empty list, in this case the server will return
-  /// completion suggestions.
-  set expressions(List<RuntimeCompletionExpression> value) {
-    _expressions = value;
-  }
-
-  ExecutionGetSuggestionsParams(String code, int offset, String contextFile,
-      int contextOffset, List<RuntimeCompletionVariable> variables,
-      {List<RuntimeCompletionExpression> expressions}) {
-    this.code = code;
-    this.offset = offset;
-    this.contextFile = contextFile;
-    this.contextOffset = contextOffset;
-    this.variables = variables;
-    this.expressions = expressions;
-  }
+  ExecutionGetSuggestionsParams(this.code, this.offset, this.contextFile,
+      this.contextOffset, this.variables,
+      {this.expressions});
 
   factory ExecutionGetSuggestionsParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String code;
@@ -11405,18 +9156,18 @@
         variables = jsonDecoder.decodeList(
             jsonPath + '.variables',
             json['variables'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 RuntimeCompletionVariable.fromJson(
                     jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'variables');
       }
-      List<RuntimeCompletionExpression> expressions;
+      List<RuntimeCompletionExpression>? expressions;
       if (json.containsKey('expressions')) {
         expressions = jsonDecoder.decodeList(
             jsonPath + '.expressions',
             json['expressions'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 RuntimeCompletionExpression.fromJson(
                     jsonDecoder, jsonPath, json));
       }
@@ -11435,8 +9186,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['code'] = code;
     result['offset'] = offset;
     result['contextFile'] = contextFile;
@@ -11444,6 +9195,7 @@
     result['variables'] = variables
         .map((RuntimeCompletionVariable value) => value.toJson())
         .toList();
+    var expressions = this.expressions;
     if (expressions != null) {
       result['expressions'] = expressions
           .map((RuntimeCompletionExpression value) => value.toJson())
@@ -11503,10 +9255,6 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class ExecutionGetSuggestionsResult implements ResponseResult {
-  List<CompletionSuggestion> _suggestions;
-
-  List<RuntimeCompletionExpression> _expressions;
-
   /// The completion suggestions. In contrast to usual completion request,
   /// suggestions for private elements also will be provided.
   ///
@@ -11515,59 +9263,34 @@
   /// their actual runtime types can improve completion results, the server
   /// omits this field in the response, and instead will return the
   /// "expressions" field.
-  List<CompletionSuggestion> get suggestions => _suggestions;
-
-  /// The completion suggestions. In contrast to usual completion request,
-  /// suggestions for private elements also will be provided.
-  ///
-  /// If there are sub-expressions that can have different runtime types, and
-  /// are considered to be safe to evaluate at runtime (e.g. getters), so using
-  /// their actual runtime types can improve completion results, the server
-  /// omits this field in the response, and instead will return the
-  /// "expressions" field.
-  set suggestions(List<CompletionSuggestion> value) {
-    _suggestions = value;
-  }
+  List<CompletionSuggestion>? suggestions;
 
   /// The list of sub-expressions in the code for which the server would like
   /// to know runtime types to provide better completion suggestions.
   ///
   /// This field is omitted the field "suggestions" is returned.
-  List<RuntimeCompletionExpression> get expressions => _expressions;
+  List<RuntimeCompletionExpression>? expressions;
 
-  /// The list of sub-expressions in the code for which the server would like
-  /// to know runtime types to provide better completion suggestions.
-  ///
-  /// This field is omitted the field "suggestions" is returned.
-  set expressions(List<RuntimeCompletionExpression> value) {
-    _expressions = value;
-  }
-
-  ExecutionGetSuggestionsResult(
-      {List<CompletionSuggestion> suggestions,
-      List<RuntimeCompletionExpression> expressions}) {
-    this.suggestions = suggestions;
-    this.expressions = expressions;
-  }
+  ExecutionGetSuggestionsResult({this.suggestions, this.expressions});
 
   factory ExecutionGetSuggestionsResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
-      List<CompletionSuggestion> suggestions;
+      List<CompletionSuggestion>? suggestions;
       if (json.containsKey('suggestions')) {
         suggestions = jsonDecoder.decodeList(
             jsonPath + '.suggestions',
             json['suggestions'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 CompletionSuggestion.fromJson(jsonDecoder, jsonPath, json));
       }
-      List<RuntimeCompletionExpression> expressions;
+      List<RuntimeCompletionExpression>? expressions;
       if (json.containsKey('expressions')) {
         expressions = jsonDecoder.decodeList(
             jsonPath + '.expressions',
             json['expressions'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 RuntimeCompletionExpression.fromJson(
                     jsonDecoder, jsonPath, json));
       }
@@ -11587,13 +9310,15 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
+    var suggestions = this.suggestions;
     if (suggestions != null) {
       result['suggestions'] = suggestions
           .map((CompletionSuggestion value) => value.toJson())
           .toList();
     }
+    var expressions = this.expressions;
     if (expressions != null) {
       result['expressions'] = expressions
           .map((RuntimeCompletionExpression value) => value.toJson())
@@ -11643,52 +9368,22 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class ExecutionLaunchDataParams implements HasToJson {
-  String _file;
-
-  ExecutableKind _kind;
-
-  List<String> _referencedFiles;
-
   /// The file for which launch data is being provided. This will either be a
   /// Dart library or an HTML file.
-  String get file => _file;
-
-  /// The file for which launch data is being provided. This will either be a
-  /// Dart library or an HTML file.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// The kind of the executable file. This field is omitted if the file is not
   /// a Dart file.
-  ExecutableKind get kind => _kind;
-
-  /// The kind of the executable file. This field is omitted if the file is not
-  /// a Dart file.
-  set kind(ExecutableKind value) {
-    _kind = value;
-  }
+  ExecutableKind? kind;
 
   /// A list of the Dart files that are referenced by the file. This field is
   /// omitted if the file is not an HTML file.
-  List<String> get referencedFiles => _referencedFiles;
+  List<String>? referencedFiles;
 
-  /// A list of the Dart files that are referenced by the file. This field is
-  /// omitted if the file is not an HTML file.
-  set referencedFiles(List<String> value) {
-    _referencedFiles = value;
-  }
-
-  ExecutionLaunchDataParams(String file,
-      {ExecutableKind kind, List<String> referencedFiles}) {
-    this.file = file;
-    this.kind = kind;
-    this.referencedFiles = referencedFiles;
-  }
+  ExecutionLaunchDataParams(this.file, {this.kind, this.referencedFiles});
 
   factory ExecutionLaunchDataParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -11697,12 +9392,12 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'file');
       }
-      ExecutableKind kind;
+      ExecutableKind? kind;
       if (json.containsKey('kind')) {
         kind = ExecutableKind.fromJson(
             jsonDecoder, jsonPath + '.kind', json['kind']);
       }
-      List<String> referencedFiles;
+      List<String>? referencedFiles;
       if (json.containsKey('referencedFiles')) {
         referencedFiles = jsonDecoder.decodeList(jsonPath + '.referencedFiles',
             json['referencedFiles'], jsonDecoder.decodeString);
@@ -11721,12 +9416,14 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
+    var kind = this.kind;
     if (kind != null) {
       result['kind'] = kind.toJson();
     }
+    var referencedFiles = this.referencedFiles;
     if (referencedFiles != null) {
       result['referencedFiles'] = referencedFiles;
     }
@@ -11771,45 +9468,19 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class ExecutionMapUriParams implements RequestParams {
-  String _id;
-
-  String _file;
-
-  String _uri;
-
   /// The identifier of the execution context in which the URI is to be mapped.
-  String get id => _id;
-
-  /// The identifier of the execution context in which the URI is to be mapped.
-  set id(String value) {
-    assert(value != null);
-    _id = value;
-  }
+  String id;
 
   /// The path of the file to be mapped into a URI.
-  String get file => _file;
-
-  /// The path of the file to be mapped into a URI.
-  set file(String value) {
-    _file = value;
-  }
+  String? file;
 
   /// The URI to be mapped into a file path.
-  String get uri => _uri;
+  String? uri;
 
-  /// The URI to be mapped into a file path.
-  set uri(String value) {
-    _uri = value;
-  }
-
-  ExecutionMapUriParams(String id, {String file, String uri}) {
-    this.id = id;
-    this.file = file;
-    this.uri = uri;
-  }
+  ExecutionMapUriParams(this.id, {this.file, this.uri});
 
   factory ExecutionMapUriParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String id;
@@ -11818,11 +9489,11 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'id');
       }
-      String file;
+      String? file;
       if (json.containsKey('file')) {
         file = jsonDecoder.decodeString(jsonPath + '.file', json['file']);
       }
-      String uri;
+      String? uri;
       if (json.containsKey('uri')) {
         uri = jsonDecoder.decodeString(jsonPath + '.uri', json['uri']);
       }
@@ -11838,12 +9509,14 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['id'] = id;
+    var file = this.file;
     if (file != null) {
       result['file'] = file;
     }
+    var uri = this.uri;
     if (uri != null) {
       result['uri'] = uri;
     }
@@ -11885,44 +9558,25 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class ExecutionMapUriResult implements ResponseResult {
-  String _file;
-
-  String _uri;
-
   /// The file to which the URI was mapped. This field is omitted if the uri
   /// field was not given in the request.
-  String get file => _file;
-
-  /// The file to which the URI was mapped. This field is omitted if the uri
-  /// field was not given in the request.
-  set file(String value) {
-    _file = value;
-  }
+  String? file;
 
   /// The URI to which the file path was mapped. This field is omitted if the
   /// file field was not given in the request.
-  String get uri => _uri;
+  String? uri;
 
-  /// The URI to which the file path was mapped. This field is omitted if the
-  /// file field was not given in the request.
-  set uri(String value) {
-    _uri = value;
-  }
-
-  ExecutionMapUriResult({String file, String uri}) {
-    this.file = file;
-    this.uri = uri;
-  }
+  ExecutionMapUriResult({this.file, this.uri});
 
   factory ExecutionMapUriResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
-      String file;
+      String? file;
       if (json.containsKey('file')) {
         file = jsonDecoder.decodeString(jsonPath + '.file', json['file']);
       }
-      String uri;
+      String? uri;
       if (json.containsKey('uri')) {
         uri = jsonDecoder.decodeString(jsonPath + '.uri', json['uri']);
       }
@@ -11940,11 +9594,13 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
+    var file = this.file;
     if (file != null) {
       result['file'] = file;
     }
+    var uri = this.uri;
     if (uri != null) {
       result['uri'] = uri;
     }
@@ -12003,7 +9659,7 @@
   }
 
   factory ExecutionService.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     if (json is String) {
       try {
         return ExecutionService(json);
@@ -12028,23 +9684,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class ExecutionSetSubscriptionsParams implements RequestParams {
-  List<ExecutionService> _subscriptions;
-
   /// A list of the services being subscribed to.
-  List<ExecutionService> get subscriptions => _subscriptions;
+  List<ExecutionService> subscriptions;
 
-  /// A list of the services being subscribed to.
-  set subscriptions(List<ExecutionService> value) {
-    assert(value != null);
-    _subscriptions = value;
-  }
-
-  ExecutionSetSubscriptionsParams(List<ExecutionService> subscriptions) {
-    this.subscriptions = subscriptions;
-  }
+  ExecutionSetSubscriptionsParams(this.subscriptions);
 
   factory ExecutionSetSubscriptionsParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       List<ExecutionService> subscriptions;
@@ -12052,7 +9698,7 @@
         subscriptions = jsonDecoder.decodeList(
             jsonPath + '.subscriptions',
             json['subscriptions'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 ExecutionService.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'subscriptions');
@@ -12070,8 +9716,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['subscriptions'] =
         subscriptions.map((ExecutionService value) => value.toJson()).toList();
     return result;
@@ -12107,7 +9753,7 @@
 /// Clients may not extend, implement or mix-in this class.
 class ExecutionSetSubscriptionsResult implements ResponseResult {
   @override
-  Map<String, dynamic> toJson() => <String, dynamic>{};
+  Map<String, Object> toJson() => <String, Object>{};
 
   @override
   Response toResponse(String id) {
@@ -12137,37 +9783,17 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class ExistingImport implements HasToJson {
-  int _uri;
-
-  List<int> _elements;
-
   /// The URI of the imported library. It is an index in the strings field, in
   /// the enclosing ExistingImports and its ImportedElementSet object.
-  int get uri => _uri;
-
-  /// The URI of the imported library. It is an index in the strings field, in
-  /// the enclosing ExistingImports and its ImportedElementSet object.
-  set uri(int value) {
-    assert(value != null);
-    _uri = value;
-  }
+  int uri;
 
   /// The list of indexes of elements, in the enclosing ExistingImports object.
-  List<int> get elements => _elements;
+  List<int> elements;
 
-  /// The list of indexes of elements, in the enclosing ExistingImports object.
-  set elements(List<int> value) {
-    assert(value != null);
-    _elements = value;
-  }
-
-  ExistingImport(int uri, List<int> elements) {
-    this.uri = uri;
-    this.elements = elements;
-  }
+  ExistingImport(this.uri, this.elements);
 
   factory ExistingImport.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       int uri;
@@ -12190,8 +9816,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['uri'] = uri;
     result['elements'] = elements;
     return result;
@@ -12227,35 +9853,16 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class ExistingImports implements HasToJson {
-  ImportedElementSet _elements;
-
-  List<ExistingImport> _imports;
-
   /// The set of all unique imported elements for all imports.
-  ImportedElementSet get elements => _elements;
-
-  /// The set of all unique imported elements for all imports.
-  set elements(ImportedElementSet value) {
-    assert(value != null);
-    _elements = value;
-  }
+  ImportedElementSet elements;
 
   /// The list of imports in the library.
-  List<ExistingImport> get imports => _imports;
+  List<ExistingImport> imports;
 
-  /// The list of imports in the library.
-  set imports(List<ExistingImport> value) {
-    assert(value != null);
-    _imports = value;
-  }
-
-  ExistingImports(ImportedElementSet elements, List<ExistingImport> imports) {
-    this.elements = elements;
-    this.imports = imports;
-  }
+  ExistingImports(this.elements, this.imports);
 
   factory ExistingImports.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       ImportedElementSet elements;
@@ -12270,7 +9877,7 @@
         imports = jsonDecoder.decodeList(
             jsonPath + '.imports',
             json['imports'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 ExistingImport.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'imports');
@@ -12282,8 +9889,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['elements'] = elements.toJson();
     result['imports'] =
         imports.map((ExistingImport value) => value.toJson()).toList();
@@ -12324,94 +9931,42 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class ExtractLocalVariableFeedback extends RefactoringFeedback {
-  List<int> _coveringExpressionOffsets;
-
-  List<int> _coveringExpressionLengths;
-
-  List<String> _names;
-
-  List<int> _offsets;
-
-  List<int> _lengths;
-
   /// The offsets of the expressions that cover the specified selection, from
   /// the down most to the up most.
-  List<int> get coveringExpressionOffsets => _coveringExpressionOffsets;
-
-  /// The offsets of the expressions that cover the specified selection, from
-  /// the down most to the up most.
-  set coveringExpressionOffsets(List<int> value) {
-    _coveringExpressionOffsets = value;
-  }
+  List<int>? coveringExpressionOffsets;
 
   /// The lengths of the expressions that cover the specified selection, from
   /// the down most to the up most.
-  List<int> get coveringExpressionLengths => _coveringExpressionLengths;
-
-  /// The lengths of the expressions that cover the specified selection, from
-  /// the down most to the up most.
-  set coveringExpressionLengths(List<int> value) {
-    _coveringExpressionLengths = value;
-  }
+  List<int>? coveringExpressionLengths;
 
   /// The proposed names for the local variable.
-  List<String> get names => _names;
-
-  /// The proposed names for the local variable.
-  set names(List<String> value) {
-    assert(value != null);
-    _names = value;
-  }
+  List<String> names;
 
   /// The offsets of the expressions that would be replaced by a reference to
   /// the variable.
-  List<int> get offsets => _offsets;
-
-  /// The offsets of the expressions that would be replaced by a reference to
-  /// the variable.
-  set offsets(List<int> value) {
-    assert(value != null);
-    _offsets = value;
-  }
+  List<int> offsets;
 
   /// The lengths of the expressions that would be replaced by a reference to
   /// the variable. The lengths correspond to the offsets. In other words, for
   /// a given expression, if the offset of that expression is offsets[i], then
   /// the length of that expression is lengths[i].
-  List<int> get lengths => _lengths;
+  List<int> lengths;
 
-  /// The lengths of the expressions that would be replaced by a reference to
-  /// the variable. The lengths correspond to the offsets. In other words, for
-  /// a given expression, if the offset of that expression is offsets[i], then
-  /// the length of that expression is lengths[i].
-  set lengths(List<int> value) {
-    assert(value != null);
-    _lengths = value;
-  }
-
-  ExtractLocalVariableFeedback(
-      List<String> names, List<int> offsets, List<int> lengths,
-      {List<int> coveringExpressionOffsets,
-      List<int> coveringExpressionLengths}) {
-    this.coveringExpressionOffsets = coveringExpressionOffsets;
-    this.coveringExpressionLengths = coveringExpressionLengths;
-    this.names = names;
-    this.offsets = offsets;
-    this.lengths = lengths;
-  }
+  ExtractLocalVariableFeedback(this.names, this.offsets, this.lengths,
+      {this.coveringExpressionOffsets, this.coveringExpressionLengths});
 
   factory ExtractLocalVariableFeedback.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
-      List<int> coveringExpressionOffsets;
+      List<int>? coveringExpressionOffsets;
       if (json.containsKey('coveringExpressionOffsets')) {
         coveringExpressionOffsets = jsonDecoder.decodeList(
             jsonPath + '.coveringExpressionOffsets',
             json['coveringExpressionOffsets'],
             jsonDecoder.decodeInt);
       }
-      List<int> coveringExpressionLengths;
+      List<int>? coveringExpressionLengths;
       if (json.containsKey('coveringExpressionLengths')) {
         coveringExpressionLengths = jsonDecoder.decodeList(
             jsonPath + '.coveringExpressionLengths',
@@ -12449,11 +10004,13 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
+    var coveringExpressionOffsets = this.coveringExpressionOffsets;
     if (coveringExpressionOffsets != null) {
       result['coveringExpressionOffsets'] = coveringExpressionOffsets;
     }
+    var coveringExpressionLengths = this.coveringExpressionLengths;
     if (coveringExpressionLengths != null) {
       result['coveringExpressionLengths'] = coveringExpressionLengths;
     }
@@ -12501,41 +10058,19 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class ExtractLocalVariableOptions extends RefactoringOptions {
-  String _name;
-
-  bool _extractAll;
-
   /// The name that the local variable should be given.
-  String get name => _name;
-
-  /// The name that the local variable should be given.
-  set name(String value) {
-    assert(value != null);
-    _name = value;
-  }
+  String name;
 
   /// True if all occurrences of the expression within the scope in which the
   /// variable will be defined should be replaced by a reference to the local
   /// variable. The expression used to initiate the refactoring will always be
   /// replaced.
-  bool get extractAll => _extractAll;
+  bool extractAll;
 
-  /// True if all occurrences of the expression within the scope in which the
-  /// variable will be defined should be replaced by a reference to the local
-  /// variable. The expression used to initiate the refactoring will always be
-  /// replaced.
-  set extractAll(bool value) {
-    assert(value != null);
-    _extractAll = value;
-  }
-
-  ExtractLocalVariableOptions(String name, bool extractAll) {
-    this.name = name;
-    this.extractAll = extractAll;
-  }
+  ExtractLocalVariableOptions(this.name, this.extractAll);
 
   factory ExtractLocalVariableOptions.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String name;
@@ -12565,8 +10100,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['name'] = name;
     result['extractAll'] = extractAll;
     return result;
@@ -12607,129 +10142,42 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class ExtractMethodFeedback extends RefactoringFeedback {
-  int _offset;
-
-  int _length;
-
-  String _returnType;
-
-  List<String> _names;
-
-  bool _canCreateGetter;
-
-  List<RefactoringMethodParameter> _parameters;
-
-  List<int> _offsets;
-
-  List<int> _lengths;
-
   /// The offset to the beginning of the expression or statements that will be
   /// extracted.
-  int get offset => _offset;
-
-  /// The offset to the beginning of the expression or statements that will be
-  /// extracted.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
+  int offset;
 
   /// The length of the expression or statements that will be extracted.
-  int get length => _length;
-
-  /// The length of the expression or statements that will be extracted.
-  set length(int value) {
-    assert(value != null);
-    _length = value;
-  }
+  int length;
 
   /// The proposed return type for the method. If the returned element does not
   /// have a declared return type, this field will contain an empty string.
-  String get returnType => _returnType;
-
-  /// The proposed return type for the method. If the returned element does not
-  /// have a declared return type, this field will contain an empty string.
-  set returnType(String value) {
-    assert(value != null);
-    _returnType = value;
-  }
+  String returnType;
 
   /// The proposed names for the method.
-  List<String> get names => _names;
-
-  /// The proposed names for the method.
-  set names(List<String> value) {
-    assert(value != null);
-    _names = value;
-  }
+  List<String> names;
 
   /// True if a getter could be created rather than a method.
-  bool get canCreateGetter => _canCreateGetter;
-
-  /// True if a getter could be created rather than a method.
-  set canCreateGetter(bool value) {
-    assert(value != null);
-    _canCreateGetter = value;
-  }
+  bool canCreateGetter;
 
   /// The proposed parameters for the method.
-  List<RefactoringMethodParameter> get parameters => _parameters;
-
-  /// The proposed parameters for the method.
-  set parameters(List<RefactoringMethodParameter> value) {
-    assert(value != null);
-    _parameters = value;
-  }
+  List<RefactoringMethodParameter> parameters;
 
   /// The offsets of the expressions or statements that would be replaced by an
   /// invocation of the method.
-  List<int> get offsets => _offsets;
-
-  /// The offsets of the expressions or statements that would be replaced by an
-  /// invocation of the method.
-  set offsets(List<int> value) {
-    assert(value != null);
-    _offsets = value;
-  }
+  List<int> offsets;
 
   /// The lengths of the expressions or statements that would be replaced by an
   /// invocation of the method. The lengths correspond to the offsets. In other
   /// words, for a given expression (or block of statements), if the offset of
   /// that expression is offsets[i], then the length of that expression is
   /// lengths[i].
-  List<int> get lengths => _lengths;
+  List<int> lengths;
 
-  /// The lengths of the expressions or statements that would be replaced by an
-  /// invocation of the method. The lengths correspond to the offsets. In other
-  /// words, for a given expression (or block of statements), if the offset of
-  /// that expression is offsets[i], then the length of that expression is
-  /// lengths[i].
-  set lengths(List<int> value) {
-    assert(value != null);
-    _lengths = value;
-  }
-
-  ExtractMethodFeedback(
-      int offset,
-      int length,
-      String returnType,
-      List<String> names,
-      bool canCreateGetter,
-      List<RefactoringMethodParameter> parameters,
-      List<int> offsets,
-      List<int> lengths) {
-    this.offset = offset;
-    this.length = length;
-    this.returnType = returnType;
-    this.names = names;
-    this.canCreateGetter = canCreateGetter;
-    this.parameters = parameters;
-    this.offsets = offsets;
-    this.lengths = lengths;
-  }
+  ExtractMethodFeedback(this.offset, this.length, this.returnType, this.names,
+      this.canCreateGetter, this.parameters, this.offsets, this.lengths);
 
   factory ExtractMethodFeedback.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       int offset;
@@ -12770,7 +10218,7 @@
         parameters = jsonDecoder.decodeList(
             jsonPath + '.parameters',
             json['parameters'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 RefactoringMethodParameter.fromJson(
                     jsonDecoder, jsonPath, json));
       } else {
@@ -12798,8 +10246,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['offset'] = offset;
     result['length'] = length;
     result['returnType'] = returnType;
@@ -12862,44 +10310,15 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class ExtractMethodOptions extends RefactoringOptions {
-  String _returnType;
-
-  bool _createGetter;
-
-  String _name;
-
-  List<RefactoringMethodParameter> _parameters;
-
-  bool _extractAll;
-
   /// The return type that should be defined for the method.
-  String get returnType => _returnType;
-
-  /// The return type that should be defined for the method.
-  set returnType(String value) {
-    assert(value != null);
-    _returnType = value;
-  }
+  String returnType;
 
   /// True if a getter should be created rather than a method. It is an error
   /// if this field is true and the list of parameters is non-empty.
-  bool get createGetter => _createGetter;
-
-  /// True if a getter should be created rather than a method. It is an error
-  /// if this field is true and the list of parameters is non-empty.
-  set createGetter(bool value) {
-    assert(value != null);
-    _createGetter = value;
-  }
+  bool createGetter;
 
   /// The name that the method should be given.
-  String get name => _name;
-
-  /// The name that the method should be given.
-  set name(String value) {
-    assert(value != null);
-    _name = value;
-  }
+  String name;
 
   /// The parameters that should be defined for the method.
   ///
@@ -12911,47 +10330,18 @@
   ///   with the same identifiers as proposed.
   /// - To add new parameters, omit their identifier.
   /// - To remove some parameters, omit them in this list.
-  List<RefactoringMethodParameter> get parameters => _parameters;
-
-  /// The parameters that should be defined for the method.
-  ///
-  /// It is an error if a REQUIRED or NAMED parameter follows a POSITIONAL
-  /// parameter. It is an error if a REQUIRED or POSITIONAL parameter follows a
-  /// NAMED parameter.
-  ///
-  /// - To change the order and/or update proposed parameters, add parameters
-  ///   with the same identifiers as proposed.
-  /// - To add new parameters, omit their identifier.
-  /// - To remove some parameters, omit them in this list.
-  set parameters(List<RefactoringMethodParameter> value) {
-    assert(value != null);
-    _parameters = value;
-  }
+  List<RefactoringMethodParameter> parameters;
 
   /// True if all occurrences of the expression or statements should be
   /// replaced by an invocation of the method. The expression or statements
   /// used to initiate the refactoring will always be replaced.
-  bool get extractAll => _extractAll;
+  bool extractAll;
 
-  /// True if all occurrences of the expression or statements should be
-  /// replaced by an invocation of the method. The expression or statements
-  /// used to initiate the refactoring will always be replaced.
-  set extractAll(bool value) {
-    assert(value != null);
-    _extractAll = value;
-  }
-
-  ExtractMethodOptions(String returnType, bool createGetter, String name,
-      List<RefactoringMethodParameter> parameters, bool extractAll) {
-    this.returnType = returnType;
-    this.createGetter = createGetter;
-    this.name = name;
-    this.parameters = parameters;
-    this.extractAll = extractAll;
-  }
+  ExtractMethodOptions(this.returnType, this.createGetter, this.name,
+      this.parameters, this.extractAll);
 
   factory ExtractMethodOptions.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String returnType;
@@ -12979,7 +10369,7 @@
         parameters = jsonDecoder.decodeList(
             jsonPath + '.parameters',
             json['parameters'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 RefactoringMethodParameter.fromJson(
                     jsonDecoder, jsonPath, json));
       } else {
@@ -13006,8 +10396,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['returnType'] = returnType;
     result['createGetter'] = createGetter;
     result['name'] = name;
@@ -13059,7 +10449,7 @@
   ExtractWidgetFeedback();
 
   factory ExtractWidgetFeedback.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       return ExtractWidgetFeedback();
@@ -13069,8 +10459,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     return result;
   }
 
@@ -13100,23 +10490,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class ExtractWidgetOptions extends RefactoringOptions {
-  String _name;
-
   /// The name that the widget class should be given.
-  String get name => _name;
+  String name;
 
-  /// The name that the widget class should be given.
-  set name(String value) {
-    assert(value != null);
-    _name = value;
-  }
-
-  ExtractWidgetOptions(String name) {
-    this.name = name;
-  }
+  ExtractWidgetOptions(this.name);
 
   factory ExtractWidgetOptions.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String name;
@@ -13138,8 +10518,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['name'] = name;
     return result;
   }
@@ -13195,7 +10575,7 @@
   }
 
   factory FileKind.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     if (json is String) {
       try {
         return FileKind(json);
@@ -13221,35 +10601,16 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class FlutterGetWidgetDescriptionParams implements RequestParams {
-  String _file;
-
-  int _offset;
-
   /// The file where the widget instance is created.
-  String get file => _file;
-
-  /// The file where the widget instance is created.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// The offset in the file where the widget instance is created.
-  int get offset => _offset;
+  int offset;
 
-  /// The offset in the file where the widget instance is created.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
-
-  FlutterGetWidgetDescriptionParams(String file, int offset) {
-    this.file = file;
-    this.offset = offset;
-  }
+  FlutterGetWidgetDescriptionParams(this.file, this.offset);
 
   factory FlutterGetWidgetDescriptionParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -13277,8 +10638,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     result['offset'] = offset;
     return result;
@@ -13317,29 +10678,16 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class FlutterGetWidgetDescriptionResult implements ResponseResult {
-  List<FlutterWidgetProperty> _properties;
-
   /// The list of properties of the widget. Some of the properties might be
   /// read only, when their editor is not set. This might be because they have
   /// type that we don't know how to edit, or for compound properties that work
   /// as containers for sub-properties.
-  List<FlutterWidgetProperty> get properties => _properties;
+  List<FlutterWidgetProperty> properties;
 
-  /// The list of properties of the widget. Some of the properties might be
-  /// read only, when their editor is not set. This might be because they have
-  /// type that we don't know how to edit, or for compound properties that work
-  /// as containers for sub-properties.
-  set properties(List<FlutterWidgetProperty> value) {
-    assert(value != null);
-    _properties = value;
-  }
-
-  FlutterGetWidgetDescriptionResult(List<FlutterWidgetProperty> properties) {
-    this.properties = properties;
-  }
+  FlutterGetWidgetDescriptionResult(this.properties);
 
   factory FlutterGetWidgetDescriptionResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       List<FlutterWidgetProperty> properties;
@@ -13347,7 +10695,7 @@
         properties = jsonDecoder.decodeList(
             jsonPath + '.properties',
             json['properties'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 FlutterWidgetProperty.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'properties');
@@ -13367,8 +10715,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['properties'] = properties
         .map((FlutterWidgetProperty value) => value.toJson())
         .toList();
@@ -13419,178 +10767,65 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class FlutterOutline implements HasToJson {
-  FlutterOutlineKind _kind;
-
-  int _offset;
-
-  int _length;
-
-  int _codeOffset;
-
-  int _codeLength;
-
-  String _label;
-
-  Element _dartElement;
-
-  List<FlutterOutlineAttribute> _attributes;
-
-  String _className;
-
-  String _parentAssociationLabel;
-
-  String _variableName;
-
-  List<FlutterOutline> _children;
-
   /// The kind of the node.
-  FlutterOutlineKind get kind => _kind;
-
-  /// The kind of the node.
-  set kind(FlutterOutlineKind value) {
-    assert(value != null);
-    _kind = value;
-  }
+  FlutterOutlineKind kind;
 
   /// 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.
-  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.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
+  int offset;
 
   /// The length of the element.
-  int get length => _length;
-
-  /// The length of the element.
-  set length(int value) {
-    assert(value != null);
-    _length = value;
-  }
+  int length;
 
   /// The offset of the first character of the element code, which is neither
   /// documentation, nor annotation.
-  int get codeOffset => _codeOffset;
-
-  /// The offset of the first character of the element code, which is neither
-  /// documentation, nor annotation.
-  set codeOffset(int value) {
-    assert(value != null);
-    _codeOffset = value;
-  }
+  int codeOffset;
 
   /// The length of the element code.
-  int get codeLength => _codeLength;
-
-  /// The length of the element code.
-  set codeLength(int value) {
-    assert(value != null);
-    _codeLength = value;
-  }
+  int codeLength;
 
   /// The text label of the node children of the node. It is provided for any
   /// FlutterOutlineKind.GENERIC node, where better information is not
   /// available.
-  String get label => _label;
-
-  /// The text label of the node children of the node. It is provided for any
-  /// FlutterOutlineKind.GENERIC node, where better information is not
-  /// available.
-  set label(String value) {
-    _label = value;
-  }
+  String? label;
 
   /// If this node is a Dart element, the description of it; omitted otherwise.
-  Element get dartElement => _dartElement;
-
-  /// If this node is a Dart element, the description of it; omitted otherwise.
-  set dartElement(Element value) {
-    _dartElement = value;
-  }
+  Element? dartElement;
 
   /// Additional attributes for this node, which might be interesting to
   /// display on the client. These attributes are usually arguments for the
   /// instance creation or the invocation that created the widget.
-  List<FlutterOutlineAttribute> get attributes => _attributes;
-
-  /// Additional attributes for this node, which might be interesting to
-  /// display on the client. These attributes are usually arguments for the
-  /// instance creation or the invocation that created the widget.
-  set attributes(List<FlutterOutlineAttribute> value) {
-    _attributes = value;
-  }
+  List<FlutterOutlineAttribute>? attributes;
 
   /// If the node creates a new class instance, or a reference to an instance,
   /// this field has the name of the class.
-  String get className => _className;
-
-  /// If the node creates a new class instance, or a reference to an instance,
-  /// this field has the name of the class.
-  set className(String value) {
-    _className = value;
-  }
+  String? className;
 
   /// A short text description how this node is associated with the parent
   /// node. For example "appBar" or "body" in Scaffold.
-  String get parentAssociationLabel => _parentAssociationLabel;
-
-  /// A short text description how this node is associated with the parent
-  /// node. For example "appBar" or "body" in Scaffold.
-  set parentAssociationLabel(String value) {
-    _parentAssociationLabel = value;
-  }
+  String? parentAssociationLabel;
 
   /// If FlutterOutlineKind.VARIABLE, the name of the variable.
-  String get variableName => _variableName;
-
-  /// If FlutterOutlineKind.VARIABLE, the name of the variable.
-  set variableName(String value) {
-    _variableName = value;
-  }
+  String? variableName;
 
   /// The children of the node. The field will be omitted if the node has no
   /// children.
-  List<FlutterOutline> get children => _children;
+  List<FlutterOutline>? children;
 
-  /// The children of the node. The field will be omitted if the node has no
-  /// children.
-  set children(List<FlutterOutline> value) {
-    _children = value;
-  }
-
-  FlutterOutline(FlutterOutlineKind kind, int offset, int length,
-      int codeOffset, int codeLength,
-      {String label,
-      Element dartElement,
-      List<FlutterOutlineAttribute> attributes,
-      String className,
-      String parentAssociationLabel,
-      String variableName,
-      List<FlutterOutline> children}) {
-    this.kind = kind;
-    this.offset = offset;
-    this.length = length;
-    this.codeOffset = codeOffset;
-    this.codeLength = codeLength;
-    this.label = label;
-    this.dartElement = dartElement;
-    this.attributes = attributes;
-    this.className = className;
-    this.parentAssociationLabel = parentAssociationLabel;
-    this.variableName = variableName;
-    this.children = children;
-  }
+  FlutterOutline(
+      this.kind, this.offset, this.length, this.codeOffset, this.codeLength,
+      {this.label,
+      this.dartElement,
+      this.attributes,
+      this.className,
+      this.parentAssociationLabel,
+      this.variableName,
+      this.children});
 
   factory FlutterOutline.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       FlutterOutlineKind kind;
@@ -13626,45 +10861,45 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'codeLength');
       }
-      String label;
+      String? label;
       if (json.containsKey('label')) {
         label = jsonDecoder.decodeString(jsonPath + '.label', json['label']);
       }
-      Element dartElement;
+      Element? dartElement;
       if (json.containsKey('dartElement')) {
         dartElement = Element.fromJson(
             jsonDecoder, jsonPath + '.dartElement', json['dartElement']);
       }
-      List<FlutterOutlineAttribute> attributes;
+      List<FlutterOutlineAttribute>? attributes;
       if (json.containsKey('attributes')) {
         attributes = jsonDecoder.decodeList(
             jsonPath + '.attributes',
             json['attributes'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 FlutterOutlineAttribute.fromJson(jsonDecoder, jsonPath, json));
       }
-      String className;
+      String? className;
       if (json.containsKey('className')) {
         className = jsonDecoder.decodeString(
             jsonPath + '.className', json['className']);
       }
-      String parentAssociationLabel;
+      String? parentAssociationLabel;
       if (json.containsKey('parentAssociationLabel')) {
         parentAssociationLabel = jsonDecoder.decodeString(
             jsonPath + '.parentAssociationLabel',
             json['parentAssociationLabel']);
       }
-      String variableName;
+      String? variableName;
       if (json.containsKey('variableName')) {
         variableName = jsonDecoder.decodeString(
             jsonPath + '.variableName', json['variableName']);
       }
-      List<FlutterOutline> children;
+      List<FlutterOutline>? children;
       if (json.containsKey('children')) {
         children = jsonDecoder.decodeList(
             jsonPath + '.children',
             json['children'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 FlutterOutline.fromJson(jsonDecoder, jsonPath, json));
       }
       return FlutterOutline(kind, offset, length, codeOffset, codeLength,
@@ -13681,33 +10916,40 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['kind'] = kind.toJson();
     result['offset'] = offset;
     result['length'] = length;
     result['codeOffset'] = codeOffset;
     result['codeLength'] = codeLength;
+    var label = this.label;
     if (label != null) {
       result['label'] = label;
     }
+    var dartElement = this.dartElement;
     if (dartElement != null) {
       result['dartElement'] = dartElement.toJson();
     }
+    var attributes = this.attributes;
     if (attributes != null) {
       result['attributes'] = attributes
           .map((FlutterOutlineAttribute value) => value.toJson())
           .toList();
     }
+    var className = this.className;
     if (className != null) {
       result['className'] = className;
     }
+    var parentAssociationLabel = this.parentAssociationLabel;
     if (parentAssociationLabel != null) {
       result['parentAssociationLabel'] = parentAssociationLabel;
     }
+    var variableName = this.variableName;
     if (variableName != null) {
       result['variableName'] = variableName;
     }
+    var children = this.children;
     if (children != null) {
       result['children'] =
           children.map((FlutterOutline value) => value.toJson()).toList();
@@ -13775,111 +11017,44 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class FlutterOutlineAttribute implements HasToJson {
-  String _name;
-
-  String _label;
-
-  bool _literalValueBoolean;
-
-  int _literalValueInteger;
-
-  String _literalValueString;
-
-  Location _nameLocation;
-
-  Location _valueLocation;
-
   /// The name of the attribute.
-  String get name => _name;
-
-  /// The name of the attribute.
-  set name(String value) {
-    assert(value != null);
-    _name = value;
-  }
+  String name;
 
   /// The label of the attribute value, usually the Dart code. It might be
   /// quite long, the client should abbreviate as needed.
-  String get label => _label;
-
-  /// The label of the attribute value, usually the Dart code. It might be
-  /// quite long, the client should abbreviate as needed.
-  set label(String value) {
-    assert(value != null);
-    _label = value;
-  }
+  String label;
 
   /// The boolean literal value of the attribute. This field is absent if the
   /// value is not a boolean literal.
-  bool get literalValueBoolean => _literalValueBoolean;
-
-  /// The boolean literal value of the attribute. This field is absent if the
-  /// value is not a boolean literal.
-  set literalValueBoolean(bool value) {
-    _literalValueBoolean = value;
-  }
+  bool? literalValueBoolean;
 
   /// The integer literal value of the attribute. This field is absent if the
   /// value is not an integer literal.
-  int get literalValueInteger => _literalValueInteger;
-
-  /// The integer literal value of the attribute. This field is absent if the
-  /// value is not an integer literal.
-  set literalValueInteger(int value) {
-    _literalValueInteger = value;
-  }
+  int? literalValueInteger;
 
   /// The string literal value of the attribute. This field is absent if the
   /// value is not a string literal.
-  String get literalValueString => _literalValueString;
-
-  /// The string literal value of the attribute. This field is absent if the
-  /// value is not a string literal.
-  set literalValueString(String value) {
-    _literalValueString = value;
-  }
+  String? literalValueString;
 
   /// If the attribute is a named argument, the location of the name, without
   /// the colon.
-  Location get nameLocation => _nameLocation;
-
-  /// If the attribute is a named argument, the location of the name, without
-  /// the colon.
-  set nameLocation(Location value) {
-    _nameLocation = value;
-  }
+  Location? nameLocation;
 
   /// The location of the value.
   ///
   /// This field is always available, but marked optional for backward
   /// compatibility between new clients with older servers.
-  Location get valueLocation => _valueLocation;
+  Location? valueLocation;
 
-  /// The location of the value.
-  ///
-  /// This field is always available, but marked optional for backward
-  /// compatibility between new clients with older servers.
-  set valueLocation(Location value) {
-    _valueLocation = value;
-  }
-
-  FlutterOutlineAttribute(String name, String label,
-      {bool literalValueBoolean,
-      int literalValueInteger,
-      String literalValueString,
-      Location nameLocation,
-      Location valueLocation}) {
-    this.name = name;
-    this.label = label;
-    this.literalValueBoolean = literalValueBoolean;
-    this.literalValueInteger = literalValueInteger;
-    this.literalValueString = literalValueString;
-    this.nameLocation = nameLocation;
-    this.valueLocation = valueLocation;
-  }
+  FlutterOutlineAttribute(this.name, this.label,
+      {this.literalValueBoolean,
+      this.literalValueInteger,
+      this.literalValueString,
+      this.nameLocation,
+      this.valueLocation});
 
   factory FlutterOutlineAttribute.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String name;
@@ -13894,27 +11069,27 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'label');
       }
-      bool literalValueBoolean;
+      bool? literalValueBoolean;
       if (json.containsKey('literalValueBoolean')) {
         literalValueBoolean = jsonDecoder.decodeBool(
             jsonPath + '.literalValueBoolean', json['literalValueBoolean']);
       }
-      int literalValueInteger;
+      int? literalValueInteger;
       if (json.containsKey('literalValueInteger')) {
         literalValueInteger = jsonDecoder.decodeInt(
             jsonPath + '.literalValueInteger', json['literalValueInteger']);
       }
-      String literalValueString;
+      String? literalValueString;
       if (json.containsKey('literalValueString')) {
         literalValueString = jsonDecoder.decodeString(
             jsonPath + '.literalValueString', json['literalValueString']);
       }
-      Location nameLocation;
+      Location? nameLocation;
       if (json.containsKey('nameLocation')) {
         nameLocation = Location.fromJson(
             jsonDecoder, jsonPath + '.nameLocation', json['nameLocation']);
       }
-      Location valueLocation;
+      Location? valueLocation;
       if (json.containsKey('valueLocation')) {
         valueLocation = Location.fromJson(
             jsonDecoder, jsonPath + '.valueLocation', json['valueLocation']);
@@ -13931,22 +11106,27 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['name'] = name;
     result['label'] = label;
+    var literalValueBoolean = this.literalValueBoolean;
     if (literalValueBoolean != null) {
       result['literalValueBoolean'] = literalValueBoolean;
     }
+    var literalValueInteger = this.literalValueInteger;
     if (literalValueInteger != null) {
       result['literalValueInteger'] = literalValueInteger;
     }
+    var literalValueString = this.literalValueString;
     if (literalValueString != null) {
       result['literalValueString'] = literalValueString;
     }
+    var nameLocation = this.nameLocation;
     if (nameLocation != null) {
       result['nameLocation'] = nameLocation.toJson();
     }
+    var valueLocation = this.valueLocation;
     if (valueLocation != null) {
       result['valueLocation'] = valueLocation.toJson();
     }
@@ -14055,7 +11235,7 @@
   }
 
   factory FlutterOutlineKind.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     if (json is String) {
       try {
         return FlutterOutlineKind(json);
@@ -14081,35 +11261,16 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class FlutterOutlineParams implements HasToJson {
-  String _file;
-
-  FlutterOutline _outline;
-
   /// The file with which the outline is associated.
-  String get file => _file;
-
-  /// The file with which the outline is associated.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// The outline associated with the file.
-  FlutterOutline get outline => _outline;
+  FlutterOutline outline;
 
-  /// The outline associated with the file.
-  set outline(FlutterOutline value) {
-    assert(value != null);
-    _outline = value;
-  }
-
-  FlutterOutlineParams(String file, FlutterOutline outline) {
-    this.file = file;
-    this.outline = outline;
-  }
+  FlutterOutlineParams(this.file, this.outline);
 
   factory FlutterOutlineParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -14137,8 +11298,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     result['outline'] = outline.toJson();
     return result;
@@ -14195,7 +11356,7 @@
   }
 
   factory FlutterService.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     if (json is String) {
       try {
         return FlutterService(json);
@@ -14220,35 +11381,23 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class FlutterSetSubscriptionsParams implements RequestParams {
-  Map<FlutterService, List<String>> _subscriptions;
-
   /// A table mapping services to a list of the files being subscribed to the
   /// service.
-  Map<FlutterService, List<String>> get subscriptions => _subscriptions;
+  Map<FlutterService, List<String>> subscriptions;
 
-  /// A table mapping services to a list of the files being subscribed to the
-  /// service.
-  set subscriptions(Map<FlutterService, List<String>> value) {
-    assert(value != null);
-    _subscriptions = value;
-  }
-
-  FlutterSetSubscriptionsParams(
-      Map<FlutterService, List<String>> subscriptions) {
-    this.subscriptions = subscriptions;
-  }
+  FlutterSetSubscriptionsParams(this.subscriptions);
 
   factory FlutterSetSubscriptionsParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       Map<FlutterService, List<String>> subscriptions;
       if (json.containsKey('subscriptions')) {
         subscriptions = jsonDecoder.decodeMap(
             jsonPath + '.subscriptions', json['subscriptions'],
-            keyDecoder: (String jsonPath, Object json) =>
+            keyDecoder: (String jsonPath, Object? json) =>
                 FlutterService.fromJson(jsonDecoder, jsonPath, json),
-            valueDecoder: (String jsonPath, Object json) => jsonDecoder
+            valueDecoder: (String jsonPath, Object? json) => jsonDecoder
                 .decodeList(jsonPath, json, jsonDecoder.decodeString));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'subscriptions');
@@ -14266,8 +11415,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['subscriptions'] = mapMap(subscriptions,
         keyCallback: (FlutterService value) => value.toJson());
     return result;
@@ -14306,7 +11455,7 @@
 /// Clients may not extend, implement or mix-in this class.
 class FlutterSetSubscriptionsResult implements ResponseResult {
   @override
-  Map<String, dynamic> toJson() => <String, dynamic>{};
+  Map<String, Object> toJson() => <String, Object>{};
 
   @override
   Response toResponse(String id) {
@@ -14336,26 +11485,12 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class FlutterSetWidgetPropertyValueParams implements RequestParams {
-  int _id;
-
-  FlutterWidgetPropertyValue _value;
-
   /// The identifier of the property, previously returned as a part of a
   /// FlutterWidgetProperty.
   ///
   /// An error of type FLUTTER_SET_WIDGET_PROPERTY_VALUE_INVALID_ID is
   /// generated if the identifier is not valid.
-  int get id => _id;
-
-  /// The identifier of the property, previously returned as a part of a
-  /// FlutterWidgetProperty.
-  ///
-  /// An error of type FLUTTER_SET_WIDGET_PROPERTY_VALUE_INVALID_ID is
-  /// generated if the identifier is not valid.
-  set id(int value) {
-    assert(value != null);
-    _id = value;
-  }
+  int id;
 
   /// The new value to set for the property.
   ///
@@ -14366,29 +11501,12 @@
   ///
   /// If the expression is not a syntactically valid Dart code, then
   /// FLUTTER_SET_WIDGET_PROPERTY_VALUE_INVALID_EXPRESSION is reported.
-  FlutterWidgetPropertyValue get value => _value;
+  FlutterWidgetPropertyValue? value;
 
-  /// The new value to set for the property.
-  ///
-  /// If absent, indicates that the property should be removed. If the property
-  /// corresponds to an optional parameter, the corresponding named argument is
-  /// removed. If the property isRequired is true,
-  /// FLUTTER_SET_WIDGET_PROPERTY_VALUE_IS_REQUIRED error is generated.
-  ///
-  /// If the expression is not a syntactically valid Dart code, then
-  /// FLUTTER_SET_WIDGET_PROPERTY_VALUE_INVALID_EXPRESSION is reported.
-  set value(FlutterWidgetPropertyValue value) {
-    _value = value;
-  }
-
-  FlutterSetWidgetPropertyValueParams(int id,
-      {FlutterWidgetPropertyValue value}) {
-    this.id = id;
-    this.value = value;
-  }
+  FlutterSetWidgetPropertyValueParams(this.id, {this.value});
 
   factory FlutterSetWidgetPropertyValueParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       int id;
@@ -14397,7 +11515,7 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'id');
       }
-      FlutterWidgetPropertyValue value;
+      FlutterWidgetPropertyValue? value;
       if (json.containsKey('value')) {
         value = FlutterWidgetPropertyValue.fromJson(
             jsonDecoder, jsonPath + '.value', json['value']);
@@ -14415,9 +11533,10 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['id'] = id;
+    var value = this.value;
     if (value != null) {
       result['value'] = value.toJson();
     }
@@ -14457,23 +11576,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class FlutterSetWidgetPropertyValueResult implements ResponseResult {
-  SourceChange _change;
-
   /// The change that should be applied.
-  SourceChange get change => _change;
+  SourceChange change;
 
-  /// The change that should be applied.
-  set change(SourceChange value) {
-    assert(value != null);
-    _change = value;
-  }
-
-  FlutterSetWidgetPropertyValueResult(SourceChange change) {
-    this.change = change;
-  }
+  FlutterSetWidgetPropertyValueResult(this.change);
 
   factory FlutterSetWidgetPropertyValueResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       SourceChange change;
@@ -14498,8 +11607,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['change'] = change.toJson();
     return result;
   }
@@ -14544,158 +11653,66 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class FlutterWidgetProperty implements HasToJson {
-  String _documentation;
-
-  String _expression;
-
-  int _id;
-
-  bool _isRequired;
-
-  bool _isSafeToUpdate;
-
-  String _name;
-
-  List<FlutterWidgetProperty> _children;
-
-  FlutterWidgetPropertyEditor _editor;
-
-  FlutterWidgetPropertyValue _value;
-
   /// The documentation of the property to show to the user. Omitted if the
   /// server does not know the documentation, e.g. because the corresponding
   /// field is not documented.
-  String get documentation => _documentation;
-
-  /// The documentation of the property to show to the user. Omitted if the
-  /// server does not know the documentation, e.g. because the corresponding
-  /// field is not documented.
-  set documentation(String value) {
-    _documentation = value;
-  }
+  String? documentation;
 
   /// If the value of this property is set, the Dart code of the expression of
   /// this property.
-  String get expression => _expression;
-
-  /// If the value of this property is set, the Dart code of the expression of
-  /// this property.
-  set expression(String value) {
-    _expression = value;
-  }
+  String? expression;
 
   /// The unique identifier of the property, must be passed back to the server
   /// when updating the property value. Identifiers become invalid on any
   /// source code change.
-  int get id => _id;
-
-  /// The unique identifier of the property, must be passed back to the server
-  /// when updating the property value. Identifiers become invalid on any
-  /// source code change.
-  set id(int value) {
-    assert(value != null);
-    _id = value;
-  }
+  int id;
 
   /// True if the property is required, e.g. because it corresponds to a
   /// required parameter of a constructor.
-  bool get isRequired => _isRequired;
-
-  /// True if the property is required, e.g. because it corresponds to a
-  /// required parameter of a constructor.
-  set isRequired(bool value) {
-    assert(value != null);
-    _isRequired = value;
-  }
+  bool isRequired;
 
   /// If the property expression is a concrete value (e.g. a literal, or an
   /// enum constant), then it is safe to replace the expression with another
   /// concrete value. In this case this field is true. Otherwise, for example
   /// when the expression is a reference to a field, so that its value is
   /// provided from outside, this field is false.
-  bool get isSafeToUpdate => _isSafeToUpdate;
-
-  /// If the property expression is a concrete value (e.g. a literal, or an
-  /// enum constant), then it is safe to replace the expression with another
-  /// concrete value. In this case this field is true. Otherwise, for example
-  /// when the expression is a reference to a field, so that its value is
-  /// provided from outside, this field is false.
-  set isSafeToUpdate(bool value) {
-    assert(value != null);
-    _isSafeToUpdate = value;
-  }
+  bool isSafeToUpdate;
 
   /// The name of the property to display to the user.
-  String get name => _name;
-
-  /// The name of the property to display to the user.
-  set name(String value) {
-    assert(value != null);
-    _name = value;
-  }
+  String name;
 
   /// The list of children properties, if any. For example any property of type
   /// EdgeInsets will have four children properties of type double - left / top
   /// / right / bottom.
-  List<FlutterWidgetProperty> get children => _children;
-
-  /// The list of children properties, if any. For example any property of type
-  /// EdgeInsets will have four children properties of type double - left / top
-  /// / right / bottom.
-  set children(List<FlutterWidgetProperty> value) {
-    _children = value;
-  }
+  List<FlutterWidgetProperty>? children;
 
   /// The editor that should be used by the client. This field is omitted if
   /// the server does not know the editor for this property, for example
   /// because it does not have one of the supported types.
-  FlutterWidgetPropertyEditor get editor => _editor;
-
-  /// The editor that should be used by the client. This field is omitted if
-  /// the server does not know the editor for this property, for example
-  /// because it does not have one of the supported types.
-  set editor(FlutterWidgetPropertyEditor value) {
-    _editor = value;
-  }
+  FlutterWidgetPropertyEditor? editor;
 
   /// If the expression is set, and the server knows the value of the
   /// expression, this field is set.
-  FlutterWidgetPropertyValue get value => _value;
-
-  /// If the expression is set, and the server knows the value of the
-  /// expression, this field is set.
-  set value(FlutterWidgetPropertyValue value) {
-    _value = value;
-  }
+  FlutterWidgetPropertyValue? value;
 
   FlutterWidgetProperty(
-      int id, bool isRequired, bool isSafeToUpdate, String name,
-      {String documentation,
-      String expression,
-      List<FlutterWidgetProperty> children,
-      FlutterWidgetPropertyEditor editor,
-      FlutterWidgetPropertyValue value}) {
-    this.documentation = documentation;
-    this.expression = expression;
-    this.id = id;
-    this.isRequired = isRequired;
-    this.isSafeToUpdate = isSafeToUpdate;
-    this.name = name;
-    this.children = children;
-    this.editor = editor;
-    this.value = value;
-  }
+      this.id, this.isRequired, this.isSafeToUpdate, this.name,
+      {this.documentation,
+      this.expression,
+      this.children,
+      this.editor,
+      this.value});
 
   factory FlutterWidgetProperty.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
-      String documentation;
+      String? documentation;
       if (json.containsKey('documentation')) {
         documentation = jsonDecoder.decodeString(
             jsonPath + '.documentation', json['documentation']);
       }
-      String expression;
+      String? expression;
       if (json.containsKey('expression')) {
         expression = jsonDecoder.decodeString(
             jsonPath + '.expression', json['expression']);
@@ -14726,20 +11743,20 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'name');
       }
-      List<FlutterWidgetProperty> children;
+      List<FlutterWidgetProperty>? children;
       if (json.containsKey('children')) {
         children = jsonDecoder.decodeList(
             jsonPath + '.children',
             json['children'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 FlutterWidgetProperty.fromJson(jsonDecoder, jsonPath, json));
       }
-      FlutterWidgetPropertyEditor editor;
+      FlutterWidgetPropertyEditor? editor;
       if (json.containsKey('editor')) {
         editor = FlutterWidgetPropertyEditor.fromJson(
             jsonDecoder, jsonPath + '.editor', json['editor']);
       }
-      FlutterWidgetPropertyValue value;
+      FlutterWidgetPropertyValue? value;
       if (json.containsKey('value')) {
         value = FlutterWidgetPropertyValue.fromJson(
             jsonDecoder, jsonPath + '.value', json['value']);
@@ -14756,11 +11773,13 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
+    var documentation = this.documentation;
     if (documentation != null) {
       result['documentation'] = documentation;
     }
+    var expression = this.expression;
     if (expression != null) {
       result['expression'] = expression;
     }
@@ -14768,14 +11787,17 @@
     result['isRequired'] = isRequired;
     result['isSafeToUpdate'] = isSafeToUpdate;
     result['name'] = name;
+    var children = this.children;
     if (children != null) {
       result['children'] = children
           .map((FlutterWidgetProperty value) => value.toJson())
           .toList();
     }
+    var editor = this.editor;
     if (editor != null) {
       result['editor'] = editor.toJson();
     }
+    var value = this.value;
     if (value != null) {
       result['value'] = value.toJson();
     }
@@ -14827,31 +11849,14 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class FlutterWidgetPropertyEditor implements HasToJson {
-  FlutterWidgetPropertyEditorKind _kind;
+  FlutterWidgetPropertyEditorKind kind;
 
-  List<FlutterWidgetPropertyValueEnumItem> _enumItems;
+  List<FlutterWidgetPropertyValueEnumItem>? enumItems;
 
-  FlutterWidgetPropertyEditorKind get kind => _kind;
-
-  set kind(FlutterWidgetPropertyEditorKind value) {
-    assert(value != null);
-    _kind = value;
-  }
-
-  List<FlutterWidgetPropertyValueEnumItem> get enumItems => _enumItems;
-
-  set enumItems(List<FlutterWidgetPropertyValueEnumItem> value) {
-    _enumItems = value;
-  }
-
-  FlutterWidgetPropertyEditor(FlutterWidgetPropertyEditorKind kind,
-      {List<FlutterWidgetPropertyValueEnumItem> enumItems}) {
-    this.kind = kind;
-    this.enumItems = enumItems;
-  }
+  FlutterWidgetPropertyEditor(this.kind, {this.enumItems});
 
   factory FlutterWidgetPropertyEditor.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       FlutterWidgetPropertyEditorKind kind;
@@ -14861,12 +11866,12 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'kind');
       }
-      List<FlutterWidgetPropertyValueEnumItem> enumItems;
+      List<FlutterWidgetPropertyValueEnumItem>? enumItems;
       if (json.containsKey('enumItems')) {
         enumItems = jsonDecoder.decodeList(
             jsonPath + '.enumItems',
             json['enumItems'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 FlutterWidgetPropertyValueEnumItem.fromJson(
                     jsonDecoder, jsonPath, json));
       }
@@ -14877,9 +11882,10 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['kind'] = kind.toJson();
+    var enumItems = this.enumItems;
     if (enumItems != null) {
       result['enumItems'] = enumItems
           .map((FlutterWidgetPropertyValueEnumItem value) => value.toJson())
@@ -14989,7 +11995,7 @@
   }
 
   factory FlutterWidgetPropertyEditorKind.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     if (json is String) {
       try {
         return FlutterWidgetPropertyEditorKind(json);
@@ -15020,101 +12026,57 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class FlutterWidgetPropertyValue implements HasToJson {
-  bool _boolValue;
+  bool? boolValue;
 
-  double _doubleValue;
+  double? doubleValue;
 
-  int _intValue;
+  int? intValue;
 
-  String _stringValue;
+  String? stringValue;
 
-  FlutterWidgetPropertyValueEnumItem _enumValue;
-
-  String _expression;
-
-  bool get boolValue => _boolValue;
-
-  set boolValue(bool value) {
-    _boolValue = value;
-  }
-
-  double get doubleValue => _doubleValue;
-
-  set doubleValue(double value) {
-    _doubleValue = value;
-  }
-
-  int get intValue => _intValue;
-
-  set intValue(int value) {
-    _intValue = value;
-  }
-
-  String get stringValue => _stringValue;
-
-  set stringValue(String value) {
-    _stringValue = value;
-  }
-
-  FlutterWidgetPropertyValueEnumItem get enumValue => _enumValue;
-
-  set enumValue(FlutterWidgetPropertyValueEnumItem value) {
-    _enumValue = value;
-  }
+  FlutterWidgetPropertyValueEnumItem? enumValue;
 
   /// A free-form expression, which will be used as the value as is.
-  String get expression => _expression;
-
-  /// A free-form expression, which will be used as the value as is.
-  set expression(String value) {
-    _expression = value;
-  }
+  String? expression;
 
   FlutterWidgetPropertyValue(
-      {bool boolValue,
-      double doubleValue,
-      int intValue,
-      String stringValue,
-      FlutterWidgetPropertyValueEnumItem enumValue,
-      String expression}) {
-    this.boolValue = boolValue;
-    this.doubleValue = doubleValue;
-    this.intValue = intValue;
-    this.stringValue = stringValue;
-    this.enumValue = enumValue;
-    this.expression = expression;
-  }
+      {this.boolValue,
+      this.doubleValue,
+      this.intValue,
+      this.stringValue,
+      this.enumValue,
+      this.expression});
 
   factory FlutterWidgetPropertyValue.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
-      bool boolValue;
+      bool? boolValue;
       if (json.containsKey('boolValue')) {
         boolValue =
             jsonDecoder.decodeBool(jsonPath + '.boolValue', json['boolValue']);
       }
-      double doubleValue;
+      double? doubleValue;
       if (json.containsKey('doubleValue')) {
         doubleValue = jsonDecoder.decodeDouble(
             jsonPath + '.doubleValue', json['doubleValue']);
       }
-      int intValue;
+      int? intValue;
       if (json.containsKey('intValue')) {
         intValue =
             jsonDecoder.decodeInt(jsonPath + '.intValue', json['intValue']);
       }
-      String stringValue;
+      String? stringValue;
       if (json.containsKey('stringValue')) {
         stringValue = jsonDecoder.decodeString(
             jsonPath + '.stringValue', json['stringValue']);
       }
-      FlutterWidgetPropertyValueEnumItem enumValue;
+      FlutterWidgetPropertyValueEnumItem? enumValue;
       if (json.containsKey('enumValue')) {
         enumValue = FlutterWidgetPropertyValueEnumItem.fromJson(
             jsonDecoder, jsonPath + '.enumValue', json['enumValue']);
       }
-      String expression;
+      String? expression;
       if (json.containsKey('expression')) {
         expression = jsonDecoder.decodeString(
             jsonPath + '.expression', json['expression']);
@@ -15132,23 +12094,29 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
+    var boolValue = this.boolValue;
     if (boolValue != null) {
       result['boolValue'] = boolValue;
     }
+    var doubleValue = this.doubleValue;
     if (doubleValue != null) {
       result['doubleValue'] = doubleValue;
     }
+    var intValue = this.intValue;
     if (intValue != null) {
       result['intValue'] = intValue;
     }
+    var stringValue = this.stringValue;
     if (stringValue != null) {
       result['stringValue'] = stringValue;
     }
+    var enumValue = this.enumValue;
     if (enumValue != null) {
       result['enumValue'] = enumValue.toJson();
     }
+    var expression = this.expression;
     if (expression != null) {
       result['expression'] = expression;
     }
@@ -15195,70 +12163,28 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class FlutterWidgetPropertyValueEnumItem implements HasToJson {
-  String _libraryUri;
-
-  String _className;
-
-  String _name;
-
-  String _documentation;
-
   /// The URI of the library containing the className. When the enum item is
   /// passed back, this will allow the server to import the corresponding
   /// library if necessary.
-  String get libraryUri => _libraryUri;
-
-  /// The URI of the library containing the className. When the enum item is
-  /// passed back, this will allow the server to import the corresponding
-  /// library if necessary.
-  set libraryUri(String value) {
-    assert(value != null);
-    _libraryUri = value;
-  }
+  String libraryUri;
 
   /// The name of the class or enum.
-  String get className => _className;
-
-  /// The name of the class or enum.
-  set className(String value) {
-    assert(value != null);
-    _className = value;
-  }
+  String className;
 
   /// The name of the field in the enumeration, or the static field in the
   /// class.
-  String get name => _name;
-
-  /// The name of the field in the enumeration, or the static field in the
-  /// class.
-  set name(String value) {
-    assert(value != null);
-    _name = value;
-  }
+  String name;
 
   /// The documentation to show to the user. Omitted if the server does not
   /// know the documentation, e.g. because the corresponding field is not
   /// documented.
-  String get documentation => _documentation;
+  String? documentation;
 
-  /// The documentation to show to the user. Omitted if the server does not
-  /// know the documentation, e.g. because the corresponding field is not
-  /// documented.
-  set documentation(String value) {
-    _documentation = value;
-  }
-
-  FlutterWidgetPropertyValueEnumItem(
-      String libraryUri, String className, String name,
-      {String documentation}) {
-    this.libraryUri = libraryUri;
-    this.className = className;
-    this.name = name;
-    this.documentation = documentation;
-  }
+  FlutterWidgetPropertyValueEnumItem(this.libraryUri, this.className, this.name,
+      {this.documentation});
 
   factory FlutterWidgetPropertyValueEnumItem.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String libraryUri;
@@ -15281,7 +12207,7 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'name');
       }
-      String documentation;
+      String? documentation;
       if (json.containsKey('documentation')) {
         documentation = jsonDecoder.decodeString(
             jsonPath + '.documentation', json['documentation']);
@@ -15295,11 +12221,12 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['libraryUri'] = libraryUri;
     result['className'] = className;
     result['name'] = name;
+    var documentation = this.documentation;
     if (documentation != null) {
       result['documentation'] = documentation;
     }
@@ -15361,7 +12288,7 @@
   }
 
   factory GeneralAnalysisService.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     if (json is String) {
       try {
         return GeneralAnalysisService(json);
@@ -15397,195 +12324,76 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class HoverInformation implements HasToJson {
-  int _offset;
-
-  int _length;
-
-  String _containingLibraryPath;
-
-  String _containingLibraryName;
-
-  String _containingClassDescription;
-
-  String _dartdoc;
-
-  String _elementDescription;
-
-  String _elementKind;
-
-  bool _isDeprecated;
-
-  String _parameter;
-
-  String _propagatedType;
-
-  String _staticType;
-
   /// The offset of the range of characters that encompasses the cursor
   /// position and has the same hover information as the cursor position.
-  int get offset => _offset;
-
-  /// The offset of the range of characters that encompasses the cursor
-  /// position and has the same hover information as the cursor position.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
+  int offset;
 
   /// The length of the range of characters that encompasses the cursor
   /// position and has the same hover information as the cursor position.
-  int get length => _length;
-
-  /// The length of the range of characters that encompasses the cursor
-  /// position and has the same hover information as the cursor position.
-  set length(int value) {
-    assert(value != null);
-    _length = value;
-  }
+  int length;
 
   /// The path to the defining compilation unit of the library in which the
   /// referenced element is declared. This data is omitted if there is no
   /// referenced element, or if the element is declared inside an HTML file.
-  String get containingLibraryPath => _containingLibraryPath;
-
-  /// The path to the defining compilation unit of the library in which the
-  /// referenced element is declared. This data is omitted if there is no
-  /// referenced element, or if the element is declared inside an HTML file.
-  set containingLibraryPath(String value) {
-    _containingLibraryPath = value;
-  }
+  String? containingLibraryPath;
 
   /// The URI of the containing library, examples here include "dart:core",
   /// "package:.." and file uris represented by the path on disk, "/..". The
   /// data is omitted if the element is declared inside an HTML file.
-  String get containingLibraryName => _containingLibraryName;
-
-  /// The URI of the containing library, examples here include "dart:core",
-  /// "package:.." and file uris represented by the path on disk, "/..". The
-  /// data is omitted if the element is declared inside an HTML file.
-  set containingLibraryName(String value) {
-    _containingLibraryName = value;
-  }
+  String? containingLibraryName;
 
   /// A human-readable description of the class declaring the element being
   /// referenced. This data is omitted if there is no referenced element, or if
   /// the element is not a class member.
-  String get containingClassDescription => _containingClassDescription;
-
-  /// A human-readable description of the class declaring the element being
-  /// referenced. This data is omitted if there is no referenced element, or if
-  /// the element is not a class member.
-  set containingClassDescription(String value) {
-    _containingClassDescription = value;
-  }
+  String? containingClassDescription;
 
   /// The dartdoc associated with the referenced element. Other than the
   /// removal of the comment delimiters, including leading asterisks in the
   /// case of a block comment, the dartdoc is unprocessed markdown. This data
   /// is omitted if there is no referenced element, or if the element has no
   /// dartdoc.
-  String get dartdoc => _dartdoc;
-
-  /// The dartdoc associated with the referenced element. Other than the
-  /// removal of the comment delimiters, including leading asterisks in the
-  /// case of a block comment, the dartdoc is unprocessed markdown. This data
-  /// is omitted if there is no referenced element, or if the element has no
-  /// dartdoc.
-  set dartdoc(String value) {
-    _dartdoc = value;
-  }
+  String? dartdoc;
 
   /// A human-readable description of the element being referenced. This data
   /// is omitted if there is no referenced element.
-  String get elementDescription => _elementDescription;
-
-  /// A human-readable description of the element being referenced. This data
-  /// is omitted if there is no referenced element.
-  set elementDescription(String value) {
-    _elementDescription = value;
-  }
+  String? elementDescription;
 
   /// A human-readable description of the kind of element being referenced
   /// (such as "class" or "function type alias"). This data is omitted if there
   /// is no referenced element.
-  String get elementKind => _elementKind;
-
-  /// A human-readable description of the kind of element being referenced
-  /// (such as "class" or "function type alias"). This data is omitted if there
-  /// is no referenced element.
-  set elementKind(String value) {
-    _elementKind = value;
-  }
+  String? elementKind;
 
   /// True if the referenced element is deprecated.
-  bool get isDeprecated => _isDeprecated;
-
-  /// True if the referenced element is deprecated.
-  set isDeprecated(bool value) {
-    _isDeprecated = value;
-  }
+  bool? isDeprecated;
 
   /// A human-readable description of the parameter corresponding to the
   /// expression being hovered over. This data is omitted if the location is
   /// not in an argument to a function.
-  String get parameter => _parameter;
-
-  /// A human-readable description of the parameter corresponding to the
-  /// expression being hovered over. This data is omitted if the location is
-  /// not in an argument to a function.
-  set parameter(String value) {
-    _parameter = value;
-  }
+  String? parameter;
 
   /// The name of the propagated type of the expression. This data is omitted
   /// if the location does not correspond to an expression or if there is no
   /// propagated type information.
-  String get propagatedType => _propagatedType;
-
-  /// The name of the propagated type of the expression. This data is omitted
-  /// if the location does not correspond to an expression or if there is no
-  /// propagated type information.
-  set propagatedType(String value) {
-    _propagatedType = value;
-  }
+  String? propagatedType;
 
   /// The name of the static type of the expression. This data is omitted if
   /// the location does not correspond to an expression.
-  String get staticType => _staticType;
+  String? staticType;
 
-  /// The name of the static type of the expression. This data is omitted if
-  /// the location does not correspond to an expression.
-  set staticType(String value) {
-    _staticType = value;
-  }
-
-  HoverInformation(int offset, int length,
-      {String containingLibraryPath,
-      String containingLibraryName,
-      String containingClassDescription,
-      String dartdoc,
-      String elementDescription,
-      String elementKind,
-      bool isDeprecated,
-      String parameter,
-      String propagatedType,
-      String staticType}) {
-    this.offset = offset;
-    this.length = length;
-    this.containingLibraryPath = containingLibraryPath;
-    this.containingLibraryName = containingLibraryName;
-    this.containingClassDescription = containingClassDescription;
-    this.dartdoc = dartdoc;
-    this.elementDescription = elementDescription;
-    this.elementKind = elementKind;
-    this.isDeprecated = isDeprecated;
-    this.parameter = parameter;
-    this.propagatedType = propagatedType;
-    this.staticType = staticType;
-  }
+  HoverInformation(this.offset, this.length,
+      {this.containingLibraryPath,
+      this.containingLibraryName,
+      this.containingClassDescription,
+      this.dartdoc,
+      this.elementDescription,
+      this.elementKind,
+      this.isDeprecated,
+      this.parameter,
+      this.propagatedType,
+      this.staticType});
 
   factory HoverInformation.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       int offset;
@@ -15600,53 +12408,53 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'length');
       }
-      String containingLibraryPath;
+      String? containingLibraryPath;
       if (json.containsKey('containingLibraryPath')) {
         containingLibraryPath = jsonDecoder.decodeString(
             jsonPath + '.containingLibraryPath', json['containingLibraryPath']);
       }
-      String containingLibraryName;
+      String? containingLibraryName;
       if (json.containsKey('containingLibraryName')) {
         containingLibraryName = jsonDecoder.decodeString(
             jsonPath + '.containingLibraryName', json['containingLibraryName']);
       }
-      String containingClassDescription;
+      String? containingClassDescription;
       if (json.containsKey('containingClassDescription')) {
         containingClassDescription = jsonDecoder.decodeString(
             jsonPath + '.containingClassDescription',
             json['containingClassDescription']);
       }
-      String dartdoc;
+      String? dartdoc;
       if (json.containsKey('dartdoc')) {
         dartdoc =
             jsonDecoder.decodeString(jsonPath + '.dartdoc', json['dartdoc']);
       }
-      String elementDescription;
+      String? elementDescription;
       if (json.containsKey('elementDescription')) {
         elementDescription = jsonDecoder.decodeString(
             jsonPath + '.elementDescription', json['elementDescription']);
       }
-      String elementKind;
+      String? elementKind;
       if (json.containsKey('elementKind')) {
         elementKind = jsonDecoder.decodeString(
             jsonPath + '.elementKind', json['elementKind']);
       }
-      bool isDeprecated;
+      bool? isDeprecated;
       if (json.containsKey('isDeprecated')) {
         isDeprecated = jsonDecoder.decodeBool(
             jsonPath + '.isDeprecated', json['isDeprecated']);
       }
-      String parameter;
+      String? parameter;
       if (json.containsKey('parameter')) {
         parameter = jsonDecoder.decodeString(
             jsonPath + '.parameter', json['parameter']);
       }
-      String propagatedType;
+      String? propagatedType;
       if (json.containsKey('propagatedType')) {
         propagatedType = jsonDecoder.decodeString(
             jsonPath + '.propagatedType', json['propagatedType']);
       }
-      String staticType;
+      String? staticType;
       if (json.containsKey('staticType')) {
         staticType = jsonDecoder.decodeString(
             jsonPath + '.staticType', json['staticType']);
@@ -15668,37 +12476,47 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['offset'] = offset;
     result['length'] = length;
+    var containingLibraryPath = this.containingLibraryPath;
     if (containingLibraryPath != null) {
       result['containingLibraryPath'] = containingLibraryPath;
     }
+    var containingLibraryName = this.containingLibraryName;
     if (containingLibraryName != null) {
       result['containingLibraryName'] = containingLibraryName;
     }
+    var containingClassDescription = this.containingClassDescription;
     if (containingClassDescription != null) {
       result['containingClassDescription'] = containingClassDescription;
     }
+    var dartdoc = this.dartdoc;
     if (dartdoc != null) {
       result['dartdoc'] = dartdoc;
     }
+    var elementDescription = this.elementDescription;
     if (elementDescription != null) {
       result['elementDescription'] = elementDescription;
     }
+    var elementKind = this.elementKind;
     if (elementKind != null) {
       result['elementKind'] = elementKind;
     }
+    var isDeprecated = this.isDeprecated;
     if (isDeprecated != null) {
       result['isDeprecated'] = isDeprecated;
     }
+    var parameter = this.parameter;
     if (parameter != null) {
       result['parameter'] = parameter;
     }
+    var propagatedType = this.propagatedType;
     if (propagatedType != null) {
       result['propagatedType'] = propagatedType;
     }
+    var staticType = this.staticType;
     if (staticType != null) {
       result['staticType'] = staticType;
     }
@@ -15755,35 +12573,16 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class ImplementedClass implements HasToJson {
-  int _offset;
-
-  int _length;
-
   /// The offset of the name of the implemented class.
-  int get offset => _offset;
-
-  /// The offset of the name of the implemented class.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
+  int offset;
 
   /// The length of the name of the implemented class.
-  int get length => _length;
+  int length;
 
-  /// The length of the name of the implemented class.
-  set length(int value) {
-    assert(value != null);
-    _length = value;
-  }
-
-  ImplementedClass(int offset, int length) {
-    this.offset = offset;
-    this.length = length;
-  }
+  ImplementedClass(this.offset, this.length);
 
   factory ImplementedClass.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       int offset;
@@ -15805,8 +12604,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['offset'] = offset;
     result['length'] = length;
     return result;
@@ -15841,35 +12640,16 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class ImplementedMember implements HasToJson {
-  int _offset;
-
-  int _length;
-
   /// The offset of the name of the implemented member.
-  int get offset => _offset;
-
-  /// The offset of the name of the implemented member.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
+  int offset;
 
   /// The length of the name of the implemented member.
-  int get length => _length;
+  int length;
 
-  /// The length of the name of the implemented member.
-  set length(int value) {
-    assert(value != null);
-    _length = value;
-  }
-
-  ImplementedMember(int offset, int length) {
-    this.offset = offset;
-    this.length = length;
-  }
+  ImplementedMember(this.offset, this.length);
 
   factory ImplementedMember.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       int offset;
@@ -15891,8 +12671,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['offset'] = offset;
     result['length'] = length;
     return result;
@@ -15928,47 +12708,19 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class ImportedElementSet implements HasToJson {
-  List<String> _strings;
-
-  List<int> _uris;
-
-  List<int> _names;
-
   /// The list of unique strings in this object.
-  List<String> get strings => _strings;
-
-  /// The list of unique strings in this object.
-  set strings(List<String> value) {
-    assert(value != null);
-    _strings = value;
-  }
+  List<String> strings;
 
   /// The library URI part of the element. It is an index in the strings field.
-  List<int> get uris => _uris;
-
-  /// The library URI part of the element. It is an index in the strings field.
-  set uris(List<int> value) {
-    assert(value != null);
-    _uris = value;
-  }
+  List<int> uris;
 
   /// The name part of a the element. It is an index in the strings field.
-  List<int> get names => _names;
+  List<int> names;
 
-  /// The name part of a the element. It is an index in the strings field.
-  set names(List<int> value) {
-    assert(value != null);
-    _names = value;
-  }
-
-  ImportedElementSet(List<String> strings, List<int> uris, List<int> names) {
-    this.strings = strings;
-    this.uris = uris;
-    this.names = names;
-  }
+  ImportedElementSet(this.strings, this.uris, this.names);
 
   factory ImportedElementSet.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       List<String> strings;
@@ -15999,8 +12751,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['strings'] = strings;
     result['uris'] = uris;
     result['names'] = names;
@@ -16041,49 +12793,20 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class ImportedElements implements HasToJson {
-  String _path;
-
-  String _prefix;
-
-  List<String> _elements;
-
   /// The absolute and normalized path of the file containing the library.
-  String get path => _path;
-
-  /// The absolute and normalized path of the file containing the library.
-  set path(String value) {
-    assert(value != null);
-    _path = value;
-  }
+  String path;
 
   /// The prefix that was used when importing the library into the original
   /// source.
-  String get prefix => _prefix;
-
-  /// The prefix that was used when importing the library into the original
-  /// source.
-  set prefix(String value) {
-    assert(value != null);
-    _prefix = value;
-  }
+  String prefix;
 
   /// The names of the elements imported from the library.
-  List<String> get elements => _elements;
+  List<String> elements;
 
-  /// The names of the elements imported from the library.
-  set elements(List<String> value) {
-    assert(value != null);
-    _elements = value;
-  }
-
-  ImportedElements(String path, String prefix, List<String> elements) {
-    this.path = path;
-    this.prefix = prefix;
-    this.elements = elements;
-  }
+  ImportedElements(this.path, this.prefix, this.elements);
 
   factory ImportedElements.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String path;
@@ -16112,8 +12835,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['path'] = path;
     result['prefix'] = prefix;
     result['elements'] = elements;
@@ -16152,39 +12875,18 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class IncludedSuggestionRelevanceTag implements HasToJson {
-  String _tag;
-
-  int _relevanceBoost;
-
   /// The opaque value of the tag.
-  String get tag => _tag;
-
-  /// The opaque value of the tag.
-  set tag(String value) {
-    assert(value != null);
-    _tag = value;
-  }
+  String tag;
 
   /// The boost to the relevance of the completion suggestions that match this
   /// tag, which is added to the relevance of the containing
   /// IncludedSuggestionSet.
-  int get relevanceBoost => _relevanceBoost;
+  int relevanceBoost;
 
-  /// The boost to the relevance of the completion suggestions that match this
-  /// tag, which is added to the relevance of the containing
-  /// IncludedSuggestionSet.
-  set relevanceBoost(int value) {
-    assert(value != null);
-    _relevanceBoost = value;
-  }
-
-  IncludedSuggestionRelevanceTag(String tag, int relevanceBoost) {
-    this.tag = tag;
-    this.relevanceBoost = relevanceBoost;
-  }
+  IncludedSuggestionRelevanceTag(this.tag, this.relevanceBoost);
 
   factory IncludedSuggestionRelevanceTag.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String tag;
@@ -16208,8 +12910,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['tag'] = tag;
     result['relevanceBoost'] = relevanceBoost;
     return result;
@@ -16245,33 +12947,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class IncludedSuggestionSet implements HasToJson {
-  int _id;
-
-  int _relevance;
-
-  String _displayUri;
-
   /// Clients should use it to access the set of precomputed completions to be
   /// displayed to the user.
-  int get id => _id;
-
-  /// Clients should use it to access the set of precomputed completions to be
-  /// displayed to the user.
-  set id(int value) {
-    assert(value != null);
-    _id = value;
-  }
+  int id;
 
   /// The relevance of completion suggestions from this library where a higher
   /// number indicates a higher relevance.
-  int get relevance => _relevance;
-
-  /// The relevance of completion suggestions from this library where a higher
-  /// number indicates a higher relevance.
-  set relevance(int value) {
-    assert(value != null);
-    _relevance = value;
-  }
+  int relevance;
 
   /// The optional string that should be displayed instead of the uri of the
   /// referenced AvailableSuggestionSet.
@@ -16280,27 +12962,12 @@
   /// "file://" URIs, so are usually long, and don't look nice, but actual
   /// import directives will use relative URIs, which are short, so we probably
   /// want to display such relative URIs to the user.
-  String get displayUri => _displayUri;
+  String? displayUri;
 
-  /// The optional string that should be displayed instead of the uri of the
-  /// referenced AvailableSuggestionSet.
-  ///
-  /// For example libraries in the "test" directory of a package have only
-  /// "file://" URIs, so are usually long, and don't look nice, but actual
-  /// import directives will use relative URIs, which are short, so we probably
-  /// want to display such relative URIs to the user.
-  set displayUri(String value) {
-    _displayUri = value;
-  }
-
-  IncludedSuggestionSet(int id, int relevance, {String displayUri}) {
-    this.id = id;
-    this.relevance = relevance;
-    this.displayUri = displayUri;
-  }
+  IncludedSuggestionSet(this.id, this.relevance, {this.displayUri});
 
   factory IncludedSuggestionSet.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       int id;
@@ -16316,7 +12983,7 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'relevance');
       }
-      String displayUri;
+      String? displayUri;
       if (json.containsKey('displayUri')) {
         displayUri = jsonDecoder.decodeString(
             jsonPath + '.displayUri', json['displayUri']);
@@ -16328,10 +12995,11 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['id'] = id;
     result['relevance'] = relevance;
+    var displayUri = this.displayUri;
     if (displayUri != null) {
       result['displayUri'] = displayUri;
     }
@@ -16370,35 +13038,16 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class InlineLocalVariableFeedback extends RefactoringFeedback {
-  String _name;
-
-  int _occurrences;
-
   /// The name of the variable being inlined.
-  String get name => _name;
-
-  /// The name of the variable being inlined.
-  set name(String value) {
-    assert(value != null);
-    _name = value;
-  }
+  String name;
 
   /// The number of times the variable occurs.
-  int get occurrences => _occurrences;
+  int occurrences;
 
-  /// The number of times the variable occurs.
-  set occurrences(int value) {
-    assert(value != null);
-    _occurrences = value;
-  }
-
-  InlineLocalVariableFeedback(String name, int occurrences) {
-    this.name = name;
-    this.occurrences = occurrences;
-  }
+  InlineLocalVariableFeedback(this.name, this.occurrences);
 
   factory InlineLocalVariableFeedback.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String name;
@@ -16422,8 +13071,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['name'] = name;
     result['occurrences'] = occurrences;
     return result;
@@ -16478,54 +13127,24 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class InlineMethodFeedback extends RefactoringFeedback {
-  String _className;
-
-  String _methodName;
-
-  bool _isDeclaration;
-
   /// The name of the class enclosing the method being inlined. If not a class
   /// member is being inlined, this field will be absent.
-  String get className => _className;
-
-  /// The name of the class enclosing the method being inlined. If not a class
-  /// member is being inlined, this field will be absent.
-  set className(String value) {
-    _className = value;
-  }
+  String? className;
 
   /// The name of the method (or function) being inlined.
-  String get methodName => _methodName;
-
-  /// The name of the method (or function) being inlined.
-  set methodName(String value) {
-    assert(value != null);
-    _methodName = value;
-  }
+  String methodName;
 
   /// True if the declaration of the method is selected. So all references
   /// should be inlined.
-  bool get isDeclaration => _isDeclaration;
+  bool isDeclaration;
 
-  /// True if the declaration of the method is selected. So all references
-  /// should be inlined.
-  set isDeclaration(bool value) {
-    assert(value != null);
-    _isDeclaration = value;
-  }
-
-  InlineMethodFeedback(String methodName, bool isDeclaration,
-      {String className}) {
-    this.className = className;
-    this.methodName = methodName;
-    this.isDeclaration = isDeclaration;
-  }
+  InlineMethodFeedback(this.methodName, this.isDeclaration, {this.className});
 
   factory InlineMethodFeedback.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
-      String className;
+      String? className;
       if (json.containsKey('className')) {
         className = jsonDecoder.decodeString(
             jsonPath + '.className', json['className']);
@@ -16552,8 +13171,9 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
+    var className = this.className;
     if (className != null) {
       result['className'] = className;
     }
@@ -16594,39 +13214,18 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class InlineMethodOptions extends RefactoringOptions {
-  bool _deleteSource;
-
-  bool _inlineAll;
-
   /// True if the method being inlined should be removed. It is an error if
   /// this field is true and inlineAll is false.
-  bool get deleteSource => _deleteSource;
-
-  /// True if the method being inlined should be removed. It is an error if
-  /// this field is true and inlineAll is false.
-  set deleteSource(bool value) {
-    assert(value != null);
-    _deleteSource = value;
-  }
+  bool deleteSource;
 
   /// True if all invocations of the method should be inlined, or false if only
   /// the invocation site used to create this refactoring should be inlined.
-  bool get inlineAll => _inlineAll;
+  bool inlineAll;
 
-  /// True if all invocations of the method should be inlined, or false if only
-  /// the invocation site used to create this refactoring should be inlined.
-  set inlineAll(bool value) {
-    assert(value != null);
-    _inlineAll = value;
-  }
-
-  InlineMethodOptions(bool deleteSource, bool inlineAll) {
-    this.deleteSource = deleteSource;
-    this.inlineAll = inlineAll;
-  }
+  InlineMethodOptions(this.deleteSource, this.inlineAll);
 
   factory InlineMethodOptions.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       bool deleteSource;
@@ -16656,8 +13255,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['deleteSource'] = deleteSource;
     result['inlineAll'] = inlineAll;
     return result;
@@ -16691,25 +13290,14 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class KytheGetKytheEntriesParams implements RequestParams {
-  String _file;
-
   /// The file containing the code for which the Kythe Entry objects are being
   /// requested.
-  String get file => _file;
+  String file;
 
-  /// The file containing the code for which the Kythe Entry objects are being
-  /// requested.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
-
-  KytheGetKytheEntriesParams(String file) {
-    this.file = file;
-  }
+  KytheGetKytheEntriesParams(this.file);
 
   factory KytheGetKytheEntriesParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -16731,8 +13319,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     return result;
   }
@@ -16770,41 +13358,19 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class KytheGetKytheEntriesResult implements ResponseResult {
-  List<KytheEntry> _entries;
-
-  List<String> _files;
-
   /// The list of KytheEntry objects for the queried file.
-  List<KytheEntry> get entries => _entries;
-
-  /// The list of KytheEntry objects for the queried file.
-  set entries(List<KytheEntry> value) {
-    assert(value != null);
-    _entries = value;
-  }
+  List<KytheEntry> entries;
 
   /// The set of files paths that were required, but not in the file system, to
   /// give a complete and accurate Kythe graph for the file. This could be due
   /// to a referenced file that does not exist or generated files not being
   /// generated or passed before the call to "getKytheEntries".
-  List<String> get files => _files;
+  List<String> files;
 
-  /// The set of files paths that were required, but not in the file system, to
-  /// give a complete and accurate Kythe graph for the file. This could be due
-  /// to a referenced file that does not exist or generated files not being
-  /// generated or passed before the call to "getKytheEntries".
-  set files(List<String> value) {
-    assert(value != null);
-    _files = value;
-  }
-
-  KytheGetKytheEntriesResult(List<KytheEntry> entries, List<String> files) {
-    this.entries = entries;
-    this.files = files;
-  }
+  KytheGetKytheEntriesResult(this.entries, this.files);
 
   factory KytheGetKytheEntriesResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       List<KytheEntry> entries;
@@ -16812,7 +13378,7 @@
         entries = jsonDecoder.decodeList(
             jsonPath + '.entries',
             json['entries'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 KytheEntry.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'entries');
@@ -16839,8 +13405,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['entries'] =
         entries.map((KytheEntry value) => value.toJson()).toList();
     result['files'] = files;
@@ -16883,41 +13449,19 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class LibraryPathSet implements HasToJson {
-  String _scope;
-
-  List<String> _libraryPaths;
-
   /// The filepath for which this request's libraries should be active in
   /// completion suggestions. This object associates filesystem regions to
   /// libraries and library directories of interest to the client.
-  String get scope => _scope;
-
-  /// The filepath for which this request's libraries should be active in
-  /// completion suggestions. This object associates filesystem regions to
-  /// libraries and library directories of interest to the client.
-  set scope(String value) {
-    assert(value != null);
-    _scope = value;
-  }
+  String scope;
 
   /// The paths of the libraries of interest to the client for completion
   /// suggestions.
-  List<String> get libraryPaths => _libraryPaths;
+  List<String> libraryPaths;
 
-  /// The paths of the libraries of interest to the client for completion
-  /// suggestions.
-  set libraryPaths(List<String> value) {
-    assert(value != null);
-    _libraryPaths = value;
-  }
-
-  LibraryPathSet(String scope, List<String> libraryPaths) {
-    this.scope = scope;
-    this.libraryPaths = libraryPaths;
-  }
+  LibraryPathSet(this.scope, this.libraryPaths);
 
   factory LibraryPathSet.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String scope;
@@ -16940,8 +13484,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['scope'] = scope;
     result['libraryPaths'] = libraryPaths;
     return result;
@@ -16995,23 +13539,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class MoveFileOptions extends RefactoringOptions {
-  String _newFile;
-
   /// The new file path to which the given file is being moved.
-  String get newFile => _newFile;
+  String newFile;
 
-  /// The new file path to which the given file is being moved.
-  set newFile(String value) {
-    assert(value != null);
-    _newFile = value;
-  }
-
-  MoveFileOptions(String newFile) {
-    this.newFile = newFile;
-  }
+  MoveFileOptions(this.newFile);
 
   factory MoveFileOptions.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String newFile;
@@ -17034,8 +13568,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['newFile'] = newFile;
     return result;
   }
@@ -17068,35 +13602,16 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class OverriddenMember implements HasToJson {
-  Element _element;
-
-  String _className;
-
   /// The element that is being overridden.
-  Element get element => _element;
-
-  /// The element that is being overridden.
-  set element(Element value) {
-    assert(value != null);
-    _element = value;
-  }
+  Element element;
 
   /// The name of the class in which the member is defined.
-  String get className => _className;
+  String className;
 
-  /// The name of the class in which the member is defined.
-  set className(String value) {
-    assert(value != null);
-    _className = value;
-  }
-
-  OverriddenMember(Element element, String className) {
-    this.element = element;
-    this.className = className;
-  }
+  OverriddenMember(this.element, this.className);
 
   factory OverriddenMember.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       Element element;
@@ -17120,8 +13635,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['element'] = element.toJson();
     result['className'] = className;
     return result;
@@ -17158,67 +13673,27 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class Override implements HasToJson {
-  int _offset;
-
-  int _length;
-
-  OverriddenMember _superclassMember;
-
-  List<OverriddenMember> _interfaceMembers;
-
   /// The offset of the name of the overriding member.
-  int get offset => _offset;
-
-  /// The offset of the name of the overriding member.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
+  int offset;
 
   /// The length of the name of the overriding member.
-  int get length => _length;
-
-  /// The length of the name of the overriding member.
-  set length(int value) {
-    assert(value != null);
-    _length = value;
-  }
+  int length;
 
   /// The member inherited from a superclass that is overridden by the
   /// overriding member. The field is omitted if there is no superclass member,
   /// in which case there must be at least one interface member.
-  OverriddenMember get superclassMember => _superclassMember;
-
-  /// The member inherited from a superclass that is overridden by the
-  /// overriding member. The field is omitted if there is no superclass member,
-  /// in which case there must be at least one interface member.
-  set superclassMember(OverriddenMember value) {
-    _superclassMember = value;
-  }
+  OverriddenMember? superclassMember;
 
   /// The members inherited from interfaces that are overridden by the
   /// overriding member. The field is omitted if there are no interface
   /// members, in which case there must be a superclass member.
-  List<OverriddenMember> get interfaceMembers => _interfaceMembers;
+  List<OverriddenMember>? interfaceMembers;
 
-  /// The members inherited from interfaces that are overridden by the
-  /// overriding member. The field is omitted if there are no interface
-  /// members, in which case there must be a superclass member.
-  set interfaceMembers(List<OverriddenMember> value) {
-    _interfaceMembers = value;
-  }
-
-  Override(int offset, int length,
-      {OverriddenMember superclassMember,
-      List<OverriddenMember> interfaceMembers}) {
-    this.offset = offset;
-    this.length = length;
-    this.superclassMember = superclassMember;
-    this.interfaceMembers = interfaceMembers;
-  }
+  Override(this.offset, this.length,
+      {this.superclassMember, this.interfaceMembers});
 
   factory Override.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       int offset;
@@ -17233,17 +13708,17 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'length');
       }
-      OverriddenMember superclassMember;
+      OverriddenMember? superclassMember;
       if (json.containsKey('superclassMember')) {
         superclassMember = OverriddenMember.fromJson(jsonDecoder,
             jsonPath + '.superclassMember', json['superclassMember']);
       }
-      List<OverriddenMember> interfaceMembers;
+      List<OverriddenMember>? interfaceMembers;
       if (json.containsKey('interfaceMembers')) {
         interfaceMembers = jsonDecoder.decodeList(
             jsonPath + '.interfaceMembers',
             json['interfaceMembers'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 OverriddenMember.fromJson(jsonDecoder, jsonPath, json));
       }
       return Override(offset, length,
@@ -17255,13 +13730,15 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['offset'] = offset;
     result['length'] = length;
+    var superclassMember = this.superclassMember;
     if (superclassMember != null) {
       result['superclassMember'] = superclassMember.toJson();
     }
+    var interfaceMembers = this.interfaceMembers;
     if (interfaceMembers != null) {
       result['interfaceMembers'] = interfaceMembers
           .map((OverriddenMember value) => value.toJson())
@@ -17306,49 +13783,20 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class PostfixTemplateDescriptor implements HasToJson {
-  String _name;
-
-  String _key;
-
-  String _example;
-
   /// The template name, shown in the UI.
-  String get name => _name;
-
-  /// The template name, shown in the UI.
-  set name(String value) {
-    assert(value != null);
-    _name = value;
-  }
+  String name;
 
   /// The unique template key, not shown in the UI.
-  String get key => _key;
-
-  /// The unique template key, not shown in the UI.
-  set key(String value) {
-    assert(value != null);
-    _key = value;
-  }
+  String key;
 
   /// A short example of the transformation performed when the template is
   /// applied.
-  String get example => _example;
+  String example;
 
-  /// A short example of the transformation performed when the template is
-  /// applied.
-  set example(String value) {
-    assert(value != null);
-    _example = value;
-  }
-
-  PostfixTemplateDescriptor(String name, String key, String example) {
-    this.name = name;
-    this.key = key;
-    this.example = example;
-  }
+  PostfixTemplateDescriptor(this.name, this.key, this.example);
 
   factory PostfixTemplateDescriptor.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String name;
@@ -17377,8 +13825,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['name'] = name;
     result['key'] = key;
     result['example'] = example;
@@ -17414,25 +13862,14 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class PubStatus implements HasToJson {
-  bool _isListingPackageDirs;
-
   /// True if the server is currently running pub to produce a list of package
   /// directories.
-  bool get isListingPackageDirs => _isListingPackageDirs;
+  bool isListingPackageDirs;
 
-  /// True if the server is currently running pub to produce a list of package
-  /// directories.
-  set isListingPackageDirs(bool value) {
-    assert(value != null);
-    _isListingPackageDirs = value;
-  }
-
-  PubStatus(bool isListingPackageDirs) {
-    this.isListingPackageDirs = isListingPackageDirs;
-  }
+  PubStatus(this.isListingPackageDirs);
 
   factory PubStatus.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       bool isListingPackageDirs;
@@ -17449,8 +13886,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['isListingPackageDirs'] = isListingPackageDirs;
     return result;
   }
@@ -17483,15 +13920,15 @@
 class RefactoringFeedback implements HasToJson {
   RefactoringFeedback();
 
-  factory RefactoringFeedback.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json, Map responseJson) {
+  static RefactoringFeedback? fromJson(JsonDecoder jsonDecoder, String jsonPath,
+      Object? json, Map responseJson) {
     return refactoringFeedbackFromJson(
         jsonDecoder, jsonPath, json, responseJson);
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     return result;
   }
 
@@ -17522,14 +13959,14 @@
 class RefactoringOptions implements HasToJson {
   RefactoringOptions();
 
-  factory RefactoringOptions.fromJson(JsonDecoder jsonDecoder, String jsonPath,
-      Object json, RefactoringKind kind) {
+  static RefactoringOptions? fromJson(JsonDecoder jsonDecoder, String jsonPath,
+      Object? json, RefactoringKind kind) {
     return refactoringOptionsFromJson(jsonDecoder, jsonPath, json, kind);
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     return result;
   }
 
@@ -17562,64 +13999,24 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class RenameFeedback extends RefactoringFeedback {
-  int _offset;
-
-  int _length;
-
-  String _elementKindName;
-
-  String _oldName;
-
   /// The offset to the beginning of the name selected to be renamed, or -1 if
   /// the name does not exist yet.
-  int get offset => _offset;
-
-  /// The offset to the beginning of the name selected to be renamed, or -1 if
-  /// the name does not exist yet.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
+  int offset;
 
   /// The length of the name selected to be renamed.
-  int get length => _length;
-
-  /// The length of the name selected to be renamed.
-  set length(int value) {
-    assert(value != null);
-    _length = value;
-  }
+  int length;
 
   /// The human-readable description of the kind of element being renamed (such
   /// as "class" or "function type alias").
-  String get elementKindName => _elementKindName;
-
-  /// The human-readable description of the kind of element being renamed (such
-  /// as "class" or "function type alias").
-  set elementKindName(String value) {
-    assert(value != null);
-    _elementKindName = value;
-  }
+  String elementKindName;
 
   /// The old name of the element before the refactoring.
-  String get oldName => _oldName;
+  String oldName;
 
-  /// The old name of the element before the refactoring.
-  set oldName(String value) {
-    assert(value != null);
-    _oldName = value;
-  }
-
-  RenameFeedback(
-      int offset, int length, String elementKindName, String oldName) {
-    this.offset = offset;
-    this.length = length;
-    this.elementKindName = elementKindName;
-    this.oldName = oldName;
-  }
+  RenameFeedback(this.offset, this.length, this.elementKindName, this.oldName);
 
   factory RenameFeedback.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       int offset;
@@ -17655,8 +14052,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['offset'] = offset;
     result['length'] = length;
     result['elementKindName'] = elementKindName;
@@ -17697,23 +14094,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class RenameOptions extends RefactoringOptions {
-  String _newName;
-
   /// The name that the element should have after the refactoring.
-  String get newName => _newName;
+  String newName;
 
-  /// The name that the element should have after the refactoring.
-  set newName(String value) {
-    assert(value != null);
-    _newName = value;
-  }
-
-  RenameOptions(String newName) {
-    this.newName = newName;
-  }
+  RenameOptions(this.newName);
 
   factory RenameOptions.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String newName;
@@ -17736,8 +14123,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['newName'] = newName;
     return result;
   }
@@ -17771,48 +14158,20 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class RequestError implements HasToJson {
-  RequestErrorCode _code;
-
-  String _message;
-
-  String _stackTrace;
-
   /// A code that uniquely identifies the error that occurred.
-  RequestErrorCode get code => _code;
-
-  /// A code that uniquely identifies the error that occurred.
-  set code(RequestErrorCode value) {
-    assert(value != null);
-    _code = value;
-  }
+  RequestErrorCode code;
 
   /// A short description of the error.
-  String get message => _message;
-
-  /// A short description of the error.
-  set message(String value) {
-    assert(value != null);
-    _message = value;
-  }
+  String message;
 
   /// The stack trace associated with processing the request, used for
   /// debugging the server.
-  String get stackTrace => _stackTrace;
+  String? stackTrace;
 
-  /// The stack trace associated with processing the request, used for
-  /// debugging the server.
-  set stackTrace(String value) {
-    _stackTrace = value;
-  }
-
-  RequestError(RequestErrorCode code, String message, {String stackTrace}) {
-    this.code = code;
-    this.message = message;
-    this.stackTrace = stackTrace;
-  }
+  RequestError(this.code, this.message, {this.stackTrace});
 
   factory RequestError.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       RequestErrorCode code;
@@ -17829,7 +14188,7 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'message');
       }
-      String stackTrace;
+      String? stackTrace;
       if (json.containsKey('stackTrace')) {
         stackTrace = jsonDecoder.decodeString(
             jsonPath + '.stackTrace', json['stackTrace']);
@@ -17841,10 +14200,11 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['code'] = code.toJson();
     result['message'] = message;
+    var stackTrace = this.stackTrace;
     if (stackTrace != null) {
       result['stackTrace'] = stackTrace;
     }
@@ -18214,7 +14574,7 @@
   }
 
   factory RequestErrorCode.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     if (json is String) {
       try {
         return RequestErrorCode(json);
@@ -18241,51 +14601,21 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class RuntimeCompletionExpression implements HasToJson {
-  int _offset;
-
-  int _length;
-
-  RuntimeCompletionExpressionType _type;
-
   /// The offset of the expression in the code for completion.
-  int get offset => _offset;
-
-  /// The offset of the expression in the code for completion.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
+  int offset;
 
   /// The length of the expression in the code for completion.
-  int get length => _length;
-
-  /// The length of the expression in the code for completion.
-  set length(int value) {
-    assert(value != null);
-    _length = value;
-  }
+  int length;
 
   /// When the expression is sent from the server to the client, the type is
   /// omitted. The client should fill the type when it sends the request to the
   /// server again.
-  RuntimeCompletionExpressionType get type => _type;
+  RuntimeCompletionExpressionType? type;
 
-  /// When the expression is sent from the server to the client, the type is
-  /// omitted. The client should fill the type when it sends the request to the
-  /// server again.
-  set type(RuntimeCompletionExpressionType value) {
-    _type = value;
-  }
-
-  RuntimeCompletionExpression(int offset, int length,
-      {RuntimeCompletionExpressionType type}) {
-    this.offset = offset;
-    this.length = length;
-    this.type = type;
-  }
+  RuntimeCompletionExpression(this.offset, this.length, {this.type});
 
   factory RuntimeCompletionExpression.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       int offset;
@@ -18300,7 +14630,7 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'length');
       }
-      RuntimeCompletionExpressionType type;
+      RuntimeCompletionExpressionType? type;
       if (json.containsKey('type')) {
         type = RuntimeCompletionExpressionType.fromJson(
             jsonDecoder, jsonPath + '.type', json['type']);
@@ -18312,10 +14642,11 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['offset'] = offset;
     result['length'] = length;
+    var type = this.type;
     if (type != null) {
       result['type'] = type.toJson();
     }
@@ -18359,116 +14690,49 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class RuntimeCompletionExpressionType implements HasToJson {
-  String _libraryPath;
-
-  RuntimeCompletionExpressionTypeKind _kind;
-
-  String _name;
-
-  List<RuntimeCompletionExpressionType> _typeArguments;
-
-  RuntimeCompletionExpressionType _returnType;
-
-  List<RuntimeCompletionExpressionType> _parameterTypes;
-
-  List<String> _parameterNames;
-
   /// The path of the library that has this type. Omitted if the type is not
   /// declared in any library, e.g. "dynamic", or "void".
-  String get libraryPath => _libraryPath;
-
-  /// The path of the library that has this type. Omitted if the type is not
-  /// declared in any library, e.g. "dynamic", or "void".
-  set libraryPath(String value) {
-    _libraryPath = value;
-  }
+  String? libraryPath;
 
   /// The kind of the type.
-  RuntimeCompletionExpressionTypeKind get kind => _kind;
-
-  /// The kind of the type.
-  set kind(RuntimeCompletionExpressionTypeKind value) {
-    assert(value != null);
-    _kind = value;
-  }
+  RuntimeCompletionExpressionTypeKind kind;
 
   /// The name of the type. Omitted if the type does not have a name, e.g. an
   /// inline function type.
-  String get name => _name;
-
-  /// The name of the type. Omitted if the type does not have a name, e.g. an
-  /// inline function type.
-  set name(String value) {
-    _name = value;
-  }
+  String? name;
 
   /// The type arguments of the type. Omitted if the type does not have type
   /// parameters.
-  List<RuntimeCompletionExpressionType> get typeArguments => _typeArguments;
-
-  /// The type arguments of the type. Omitted if the type does not have type
-  /// parameters.
-  set typeArguments(List<RuntimeCompletionExpressionType> value) {
-    _typeArguments = value;
-  }
+  List<RuntimeCompletionExpressionType>? typeArguments;
 
   /// If the type is a function type, the return type of the function. Omitted
   /// if the type is not a function type.
-  RuntimeCompletionExpressionType get returnType => _returnType;
-
-  /// If the type is a function type, the return type of the function. Omitted
-  /// if the type is not a function type.
-  set returnType(RuntimeCompletionExpressionType value) {
-    _returnType = value;
-  }
+  RuntimeCompletionExpressionType? returnType;
 
   /// If the type is a function type, the types of the function parameters of
   /// all kinds - required, optional positional, and optional named. Omitted if
   /// the type is not a function type.
-  List<RuntimeCompletionExpressionType> get parameterTypes => _parameterTypes;
-
-  /// If the type is a function type, the types of the function parameters of
-  /// all kinds - required, optional positional, and optional named. Omitted if
-  /// the type is not a function type.
-  set parameterTypes(List<RuntimeCompletionExpressionType> value) {
-    _parameterTypes = value;
-  }
+  List<RuntimeCompletionExpressionType>? parameterTypes;
 
   /// If the type is a function type, the names of the function parameters of
   /// all kinds - required, optional positional, and optional named. The names
   /// of positional parameters are empty strings. Omitted if the type is not a
   /// function type.
-  List<String> get parameterNames => _parameterNames;
+  List<String>? parameterNames;
 
-  /// If the type is a function type, the names of the function parameters of
-  /// all kinds - required, optional positional, and optional named. The names
-  /// of positional parameters are empty strings. Omitted if the type is not a
-  /// function type.
-  set parameterNames(List<String> value) {
-    _parameterNames = value;
-  }
-
-  RuntimeCompletionExpressionType(RuntimeCompletionExpressionTypeKind kind,
-      {String libraryPath,
-      String name,
-      List<RuntimeCompletionExpressionType> typeArguments,
-      RuntimeCompletionExpressionType returnType,
-      List<RuntimeCompletionExpressionType> parameterTypes,
-      List<String> parameterNames}) {
-    this.libraryPath = libraryPath;
-    this.kind = kind;
-    this.name = name;
-    this.typeArguments = typeArguments;
-    this.returnType = returnType;
-    this.parameterTypes = parameterTypes;
-    this.parameterNames = parameterNames;
-  }
+  RuntimeCompletionExpressionType(this.kind,
+      {this.libraryPath,
+      this.name,
+      this.typeArguments,
+      this.returnType,
+      this.parameterTypes,
+      this.parameterNames});
 
   factory RuntimeCompletionExpressionType.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
-      String libraryPath;
+      String? libraryPath;
       if (json.containsKey('libraryPath')) {
         libraryPath = jsonDecoder.decodeString(
             jsonPath + '.libraryPath', json['libraryPath']);
@@ -18480,34 +14744,34 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'kind');
       }
-      String name;
+      String? name;
       if (json.containsKey('name')) {
         name = jsonDecoder.decodeString(jsonPath + '.name', json['name']);
       }
-      List<RuntimeCompletionExpressionType> typeArguments;
+      List<RuntimeCompletionExpressionType>? typeArguments;
       if (json.containsKey('typeArguments')) {
         typeArguments = jsonDecoder.decodeList(
             jsonPath + '.typeArguments',
             json['typeArguments'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 RuntimeCompletionExpressionType.fromJson(
                     jsonDecoder, jsonPath, json));
       }
-      RuntimeCompletionExpressionType returnType;
+      RuntimeCompletionExpressionType? returnType;
       if (json.containsKey('returnType')) {
         returnType = RuntimeCompletionExpressionType.fromJson(
             jsonDecoder, jsonPath + '.returnType', json['returnType']);
       }
-      List<RuntimeCompletionExpressionType> parameterTypes;
+      List<RuntimeCompletionExpressionType>? parameterTypes;
       if (json.containsKey('parameterTypes')) {
         parameterTypes = jsonDecoder.decodeList(
             jsonPath + '.parameterTypes',
             json['parameterTypes'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 RuntimeCompletionExpressionType.fromJson(
                     jsonDecoder, jsonPath, json));
       }
-      List<String> parameterNames;
+      List<String>? parameterNames;
       if (json.containsKey('parameterNames')) {
         parameterNames = jsonDecoder.decodeList(jsonPath + '.parameterNames',
             json['parameterNames'], jsonDecoder.decodeString);
@@ -18526,28 +14790,34 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
+    var libraryPath = this.libraryPath;
     if (libraryPath != null) {
       result['libraryPath'] = libraryPath;
     }
     result['kind'] = kind.toJson();
+    var name = this.name;
     if (name != null) {
       result['name'] = name;
     }
+    var typeArguments = this.typeArguments;
     if (typeArguments != null) {
       result['typeArguments'] = typeArguments
           .map((RuntimeCompletionExpressionType value) => value.toJson())
           .toList();
     }
+    var returnType = this.returnType;
     if (returnType != null) {
       result['returnType'] = returnType.toJson();
     }
+    var parameterTypes = this.parameterTypes;
     if (parameterTypes != null) {
       result['parameterTypes'] = parameterTypes
           .map((RuntimeCompletionExpressionType value) => value.toJson())
           .toList();
     }
+    var parameterNames = this.parameterNames;
     if (parameterNames != null) {
       result['parameterNames'] = parameterNames;
     }
@@ -18637,7 +14907,7 @@
   }
 
   factory RuntimeCompletionExpressionTypeKind.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     if (json is String) {
       try {
         return RuntimeCompletionExpressionTypeKind(json);
@@ -18664,39 +14934,18 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class RuntimeCompletionVariable implements HasToJson {
-  String _name;
-
-  RuntimeCompletionExpressionType _type;
-
   /// The name of the variable. The name "this" has a special meaning and is
   /// used as an implicit target for runtime completion, and in explicit "this"
   /// references.
-  String get name => _name;
-
-  /// The name of the variable. The name "this" has a special meaning and is
-  /// used as an implicit target for runtime completion, and in explicit "this"
-  /// references.
-  set name(String value) {
-    assert(value != null);
-    _name = value;
-  }
+  String name;
 
   /// The type of the variable.
-  RuntimeCompletionExpressionType get type => _type;
+  RuntimeCompletionExpressionType type;
 
-  /// The type of the variable.
-  set type(RuntimeCompletionExpressionType value) {
-    assert(value != null);
-    _type = value;
-  }
-
-  RuntimeCompletionVariable(String name, RuntimeCompletionExpressionType type) {
-    this.name = name;
-    this.type = type;
-  }
+  RuntimeCompletionVariable(this.name, this.type);
 
   factory RuntimeCompletionVariable.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String name;
@@ -18719,8 +14968,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['name'] = name;
     result['type'] = type.toJson();
     return result;
@@ -18756,52 +15005,22 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class SearchFindElementReferencesParams implements RequestParams {
-  String _file;
-
-  int _offset;
-
-  bool _includePotential;
-
   /// The file containing the declaration of or reference to the element used
   /// to define the search.
-  String get file => _file;
-
-  /// The file containing the declaration of or reference to the element used
-  /// to define the search.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// The offset within the file of the declaration of or reference to the
   /// element.
-  int get offset => _offset;
-
-  /// The offset within the file of the declaration of or reference to the
-  /// element.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
+  int offset;
 
   /// True if potential matches are to be included in the results.
-  bool get includePotential => _includePotential;
-
-  /// True if potential matches are to be included in the results.
-  set includePotential(bool value) {
-    assert(value != null);
-    _includePotential = value;
-  }
+  bool includePotential;
 
   SearchFindElementReferencesParams(
-      String file, int offset, bool includePotential) {
-    this.file = file;
-    this.offset = offset;
-    this.includePotential = includePotential;
-  }
+      this.file, this.offset, this.includePotential);
 
   factory SearchFindElementReferencesParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -18836,8 +15055,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     result['offset'] = offset;
     result['includePotential'] = includePotential;
@@ -18881,52 +15100,29 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class SearchFindElementReferencesResult implements ResponseResult {
-  String _id;
-
-  Element _element;
-
   /// The identifier used to associate results with this search request.
   ///
   /// If no element was found at the given location, this field will be absent,
   /// and no results will be reported via the search.results notification.
-  String get id => _id;
-
-  /// The identifier used to associate results with this search request.
-  ///
-  /// If no element was found at the given location, this field will be absent,
-  /// and no results will be reported via the search.results notification.
-  set id(String value) {
-    _id = value;
-  }
+  String? id;
 
   /// The element referenced or defined at the given offset and whose
   /// references will be returned in the search results.
   ///
   /// If no element was found at the given location, this field will be absent.
-  Element get element => _element;
+  Element? element;
 
-  /// The element referenced or defined at the given offset and whose
-  /// references will be returned in the search results.
-  ///
-  /// If no element was found at the given location, this field will be absent.
-  set element(Element value) {
-    _element = value;
-  }
-
-  SearchFindElementReferencesResult({String id, Element element}) {
-    this.id = id;
-    this.element = element;
-  }
+  SearchFindElementReferencesResult({this.id, this.element});
 
   factory SearchFindElementReferencesResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
-      String id;
+      String? id;
       if (json.containsKey('id')) {
         id = jsonDecoder.decodeString(jsonPath + '.id', json['id']);
       }
-      Element element;
+      Element? element;
       if (json.containsKey('element')) {
         element = Element.fromJson(
             jsonDecoder, jsonPath + '.element', json['element']);
@@ -18946,11 +15142,13 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
+    var id = this.id;
     if (id != null) {
       result['id'] = id;
     }
+    var element = this.element;
     if (element != null) {
       result['element'] = element.toJson();
     }
@@ -18990,23 +15188,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class SearchFindMemberDeclarationsParams implements RequestParams {
-  String _name;
-
   /// The name of the declarations to be found.
-  String get name => _name;
+  String name;
 
-  /// The name of the declarations to be found.
-  set name(String value) {
-    assert(value != null);
-    _name = value;
-  }
-
-  SearchFindMemberDeclarationsParams(String name) {
-    this.name = name;
-  }
+  SearchFindMemberDeclarationsParams(this.name);
 
   factory SearchFindMemberDeclarationsParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String name;
@@ -19028,8 +15216,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['name'] = name;
     return result;
   }
@@ -19066,23 +15254,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class SearchFindMemberDeclarationsResult implements ResponseResult {
-  String _id;
-
   /// The identifier used to associate results with this search request.
-  String get id => _id;
+  String id;
 
-  /// The identifier used to associate results with this search request.
-  set id(String value) {
-    assert(value != null);
-    _id = value;
-  }
-
-  SearchFindMemberDeclarationsResult(String id) {
-    this.id = id;
-  }
+  SearchFindMemberDeclarationsResult(this.id);
 
   factory SearchFindMemberDeclarationsResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String id;
@@ -19106,8 +15284,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['id'] = id;
     return result;
   }
@@ -19144,23 +15322,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class SearchFindMemberReferencesParams implements RequestParams {
-  String _name;
-
   /// The name of the references to be found.
-  String get name => _name;
+  String name;
 
-  /// The name of the references to be found.
-  set name(String value) {
-    assert(value != null);
-    _name = value;
-  }
-
-  SearchFindMemberReferencesParams(String name) {
-    this.name = name;
-  }
+  SearchFindMemberReferencesParams(this.name);
 
   factory SearchFindMemberReferencesParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String name;
@@ -19182,8 +15350,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['name'] = name;
     return result;
   }
@@ -19220,23 +15388,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class SearchFindMemberReferencesResult implements ResponseResult {
-  String _id;
-
   /// The identifier used to associate results with this search request.
-  String get id => _id;
+  String id;
 
-  /// The identifier used to associate results with this search request.
-  set id(String value) {
-    assert(value != null);
-    _id = value;
-  }
-
-  SearchFindMemberReferencesResult(String id) {
-    this.id = id;
-  }
+  SearchFindMemberReferencesResult(this.id);
 
   factory SearchFindMemberReferencesResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String id;
@@ -19260,8 +15418,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['id'] = id;
     return result;
   }
@@ -19298,25 +15456,14 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class SearchFindTopLevelDeclarationsParams implements RequestParams {
-  String _pattern;
-
   /// The regular expression used to match the names of the declarations to be
   /// found.
-  String get pattern => _pattern;
+  String pattern;
 
-  /// The regular expression used to match the names of the declarations to be
-  /// found.
-  set pattern(String value) {
-    assert(value != null);
-    _pattern = value;
-  }
-
-  SearchFindTopLevelDeclarationsParams(String pattern) {
-    this.pattern = pattern;
-  }
+  SearchFindTopLevelDeclarationsParams(this.pattern);
 
   factory SearchFindTopLevelDeclarationsParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String pattern;
@@ -19339,8 +15486,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['pattern'] = pattern;
     return result;
   }
@@ -19377,23 +15524,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class SearchFindTopLevelDeclarationsResult implements ResponseResult {
-  String _id;
-
   /// The identifier used to associate results with this search request.
-  String get id => _id;
+  String id;
 
-  /// The identifier used to associate results with this search request.
-  set id(String value) {
-    assert(value != null);
-    _id = value;
-  }
-
-  SearchFindTopLevelDeclarationsResult(String id) {
-    this.id = id;
-  }
+  SearchFindTopLevelDeclarationsResult(this.id);
 
   factory SearchFindTopLevelDeclarationsResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String id;
@@ -19417,8 +15554,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['id'] = id;
     return result;
   }
@@ -19457,63 +15594,35 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class SearchGetElementDeclarationsParams implements RequestParams {
-  String _file;
-
-  String _pattern;
-
-  int _maxResults;
-
   /// If this field is provided, return only declarations in this file. If this
   /// field is missing, return declarations in all files.
-  String get file => _file;
-
-  /// If this field is provided, return only declarations in this file. If this
-  /// field is missing, return declarations in all files.
-  set file(String value) {
-    _file = value;
-  }
+  String? file;
 
   /// The regular expression used to match the names of declarations. If this
   /// field is missing, return all declarations.
-  String get pattern => _pattern;
-
-  /// The regular expression used to match the names of declarations. If this
-  /// field is missing, return all declarations.
-  set pattern(String value) {
-    _pattern = value;
-  }
+  String? pattern;
 
   /// The maximum number of declarations to return. If this field is missing,
   /// return all matching declarations.
-  int get maxResults => _maxResults;
-
-  /// The maximum number of declarations to return. If this field is missing,
-  /// return all matching declarations.
-  set maxResults(int value) {
-    _maxResults = value;
-  }
+  int? maxResults;
 
   SearchGetElementDeclarationsParams(
-      {String file, String pattern, int maxResults}) {
-    this.file = file;
-    this.pattern = pattern;
-    this.maxResults = maxResults;
-  }
+      {this.file, this.pattern, this.maxResults});
 
   factory SearchGetElementDeclarationsParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
-      String file;
+      String? file;
       if (json.containsKey('file')) {
         file = jsonDecoder.decodeString(jsonPath + '.file', json['file']);
       }
-      String pattern;
+      String? pattern;
       if (json.containsKey('pattern')) {
         pattern =
             jsonDecoder.decodeString(jsonPath + '.pattern', json['pattern']);
       }
-      int maxResults;
+      int? maxResults;
       if (json.containsKey('maxResults')) {
         maxResults =
             jsonDecoder.decodeInt(jsonPath + '.maxResults', json['maxResults']);
@@ -19532,14 +15641,17 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
+    var file = this.file;
     if (file != null) {
       result['file'] = file;
     }
+    var pattern = this.pattern;
     if (pattern != null) {
       result['pattern'] = pattern;
     }
+    var maxResults = this.maxResults;
     if (maxResults != null) {
       result['maxResults'] = maxResults;
     }
@@ -19583,36 +15695,16 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class SearchGetElementDeclarationsResult implements ResponseResult {
-  List<ElementDeclaration> _declarations;
-
-  List<String> _files;
-
   /// The list of declarations.
-  List<ElementDeclaration> get declarations => _declarations;
-
-  /// The list of declarations.
-  set declarations(List<ElementDeclaration> value) {
-    assert(value != null);
-    _declarations = value;
-  }
+  List<ElementDeclaration> declarations;
 
   /// The list of the paths of files with declarations.
-  List<String> get files => _files;
+  List<String> files;
 
-  /// The list of the paths of files with declarations.
-  set files(List<String> value) {
-    assert(value != null);
-    _files = value;
-  }
-
-  SearchGetElementDeclarationsResult(
-      List<ElementDeclaration> declarations, List<String> files) {
-    this.declarations = declarations;
-    this.files = files;
-  }
+  SearchGetElementDeclarationsResult(this.declarations, this.files);
 
   factory SearchGetElementDeclarationsResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       List<ElementDeclaration> declarations;
@@ -19620,7 +15712,7 @@
         declarations = jsonDecoder.decodeList(
             jsonPath + '.declarations',
             json['declarations'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 ElementDeclaration.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'declarations');
@@ -19647,8 +15739,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['declarations'] =
         declarations.map((ElementDeclaration value) => value.toJson()).toList();
     result['files'] = files;
@@ -19692,50 +15784,21 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class SearchGetTypeHierarchyParams implements RequestParams {
-  String _file;
-
-  int _offset;
-
-  bool _superOnly;
-
   /// The file containing the declaration or reference to the type for which a
   /// hierarchy is being requested.
-  String get file => _file;
-
-  /// The file containing the declaration or reference to the type for which a
-  /// hierarchy is being requested.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// The offset of the name of the type within the file.
-  int get offset => _offset;
-
-  /// The offset of the name of the type within the file.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
+  int offset;
 
   /// True if the client is only requesting superclasses and interfaces
   /// hierarchy.
-  bool get superOnly => _superOnly;
+  bool? superOnly;
 
-  /// True if the client is only requesting superclasses and interfaces
-  /// hierarchy.
-  set superOnly(bool value) {
-    _superOnly = value;
-  }
-
-  SearchGetTypeHierarchyParams(String file, int offset, {bool superOnly}) {
-    this.file = file;
-    this.offset = offset;
-    this.superOnly = superOnly;
-  }
+  SearchGetTypeHierarchyParams(this.file, this.offset, {this.superOnly});
 
   factory SearchGetTypeHierarchyParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -19750,7 +15813,7 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'offset');
       }
-      bool superOnly;
+      bool? superOnly;
       if (json.containsKey('superOnly')) {
         superOnly =
             jsonDecoder.decodeBool(jsonPath + '.superOnly', json['superOnly']);
@@ -19768,10 +15831,11 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     result['offset'] = offset;
+    var superOnly = this.superOnly;
     if (superOnly != null) {
       result['superOnly'] = superOnly;
     }
@@ -19814,8 +15878,6 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class SearchGetTypeHierarchyResult implements ResponseResult {
-  List<TypeHierarchyItem> _hierarchyItems;
-
   /// A list of the types in the requested hierarchy. The first element of the
   /// list is the item representing the type for which the hierarchy was
   /// requested. The index of other elements of the list is unspecified, but
@@ -19825,35 +15887,20 @@
   /// This field will be absent if the code at the given file and offset does
   /// not represent a type, or if the file has not been sufficiently analyzed
   /// to allow a type hierarchy to be produced.
-  List<TypeHierarchyItem> get hierarchyItems => _hierarchyItems;
+  List<TypeHierarchyItem>? hierarchyItems;
 
-  /// A list of the types in the requested hierarchy. The first element of the
-  /// list is the item representing the type for which the hierarchy was
-  /// requested. The index of other elements of the list is unspecified, but
-  /// correspond to the integers used to reference supertype and subtype items
-  /// within the items.
-  ///
-  /// This field will be absent if the code at the given file and offset does
-  /// not represent a type, or if the file has not been sufficiently analyzed
-  /// to allow a type hierarchy to be produced.
-  set hierarchyItems(List<TypeHierarchyItem> value) {
-    _hierarchyItems = value;
-  }
-
-  SearchGetTypeHierarchyResult({List<TypeHierarchyItem> hierarchyItems}) {
-    this.hierarchyItems = hierarchyItems;
-  }
+  SearchGetTypeHierarchyResult({this.hierarchyItems});
 
   factory SearchGetTypeHierarchyResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
-      List<TypeHierarchyItem> hierarchyItems;
+      List<TypeHierarchyItem>? hierarchyItems;
       if (json.containsKey('hierarchyItems')) {
         hierarchyItems = jsonDecoder.decodeList(
             jsonPath + '.hierarchyItems',
             json['hierarchyItems'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 TypeHierarchyItem.fromJson(jsonDecoder, jsonPath, json));
       }
       return SearchGetTypeHierarchyResult(hierarchyItems: hierarchyItems);
@@ -19871,8 +15918,9 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
+    var hierarchyItems = this.hierarchyItems;
     if (hierarchyItems != null) {
       result['hierarchyItems'] = hierarchyItems
           .map((TypeHierarchyItem value) => value.toJson())
@@ -19917,70 +15965,27 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class SearchResult implements HasToJson {
-  Location _location;
-
-  SearchResultKind _kind;
-
-  bool _isPotential;
-
-  List<Element> _path;
-
   /// The location of the code that matched the search criteria.
-  Location get location => _location;
-
-  /// The location of the code that matched the search criteria.
-  set location(Location value) {
-    assert(value != null);
-    _location = value;
-  }
+  Location location;
 
   /// The kind of element that was found or the kind of reference that was
   /// found.
-  SearchResultKind get kind => _kind;
-
-  /// The kind of element that was found or the kind of reference that was
-  /// found.
-  set kind(SearchResultKind value) {
-    assert(value != null);
-    _kind = value;
-  }
+  SearchResultKind kind;
 
   /// True if the result is a potential match but cannot be confirmed to be a
   /// match. For example, if all references to a method m defined in some class
   /// were requested, and a reference to a method m from an unknown class were
   /// found, it would be marked as being a potential match.
-  bool get isPotential => _isPotential;
-
-  /// True if the result is a potential match but cannot be confirmed to be a
-  /// match. For example, if all references to a method m defined in some class
-  /// were requested, and a reference to a method m from an unknown class were
-  /// found, it would be marked as being a potential match.
-  set isPotential(bool value) {
-    assert(value != null);
-    _isPotential = value;
-  }
+  bool isPotential;
 
   /// The elements that contain the result, starting with the most immediately
   /// enclosing ancestor and ending with the library.
-  List<Element> get path => _path;
+  List<Element> path;
 
-  /// The elements that contain the result, starting with the most immediately
-  /// enclosing ancestor and ending with the library.
-  set path(List<Element> value) {
-    assert(value != null);
-    _path = value;
-  }
-
-  SearchResult(Location location, SearchResultKind kind, bool isPotential,
-      List<Element> path) {
-    this.location = location;
-    this.kind = kind;
-    this.isPotential = isPotential;
-    this.path = path;
-  }
+  SearchResult(this.location, this.kind, this.isPotential, this.path);
 
   factory SearchResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       Location location;
@@ -20009,7 +16014,7 @@
         path = jsonDecoder.decodeList(
             jsonPath + '.path',
             json['path'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 Element.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'path');
@@ -20021,8 +16026,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['location'] = location.toJson();
     result['kind'] = kind.toJson();
     result['isPotential'] = isPotential;
@@ -20128,7 +16133,7 @@
   }
 
   factory SearchResultKind.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     if (json is String) {
       try {
         return SearchResultKind(json);
@@ -20155,49 +16160,20 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class SearchResultsParams implements HasToJson {
-  String _id;
-
-  List<SearchResult> _results;
-
-  bool _isLast;
-
   /// The id associated with the search.
-  String get id => _id;
-
-  /// The id associated with the search.
-  set id(String value) {
-    assert(value != null);
-    _id = value;
-  }
+  String id;
 
   /// The search results being reported.
-  List<SearchResult> get results => _results;
-
-  /// The search results being reported.
-  set results(List<SearchResult> value) {
-    assert(value != null);
-    _results = value;
-  }
+  List<SearchResult> results;
 
   /// True if this is that last set of results that will be returned for the
   /// indicated search.
-  bool get isLast => _isLast;
+  bool isLast;
 
-  /// True if this is that last set of results that will be returned for the
-  /// indicated search.
-  set isLast(bool value) {
-    assert(value != null);
-    _isLast = value;
-  }
-
-  SearchResultsParams(String id, List<SearchResult> results, bool isLast) {
-    this.id = id;
-    this.results = results;
-    this.isLast = isLast;
-  }
+  SearchResultsParams(this.id, this.results, this.isLast);
 
   factory SearchResultsParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String id;
@@ -20211,7 +16187,7 @@
         results = jsonDecoder.decodeList(
             jsonPath + '.results',
             json['results'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 SearchResult.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'results');
@@ -20234,8 +16210,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['id'] = id;
     result['results'] =
         results.map((SearchResult value) => value.toJson()).toList();
@@ -20280,35 +16256,16 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class ServerConnectedParams implements HasToJson {
-  String _version;
-
-  int _pid;
-
   /// The version number of the analysis server.
-  String get version => _version;
-
-  /// The version number of the analysis server.
-  set version(String value) {
-    assert(value != null);
-    _version = value;
-  }
+  String version;
 
   /// The process id of the analysis server process.
-  int get pid => _pid;
+  int pid;
 
-  /// The process id of the analysis server process.
-  set pid(int value) {
-    assert(value != null);
-    _pid = value;
-  }
-
-  ServerConnectedParams(String version, int pid) {
-    this.version = version;
-    this.pid = pid;
-  }
+  ServerConnectedParams(this.version, this.pid);
 
   factory ServerConnectedParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String version;
@@ -20336,8 +16293,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['version'] = version;
     result['pid'] = pid;
     return result;
@@ -20377,51 +16334,21 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class ServerErrorParams implements HasToJson {
-  bool _isFatal;
-
-  String _message;
-
-  String _stackTrace;
-
   /// True if the error is a fatal error, meaning that the server will shutdown
   /// automatically after sending this notification.
-  bool get isFatal => _isFatal;
-
-  /// True if the error is a fatal error, meaning that the server will shutdown
-  /// automatically after sending this notification.
-  set isFatal(bool value) {
-    assert(value != null);
-    _isFatal = value;
-  }
+  bool isFatal;
 
   /// The error message indicating what kind of error was encountered.
-  String get message => _message;
-
-  /// The error message indicating what kind of error was encountered.
-  set message(String value) {
-    assert(value != null);
-    _message = value;
-  }
+  String message;
 
   /// The stack trace associated with the generation of the error, used for
   /// debugging the server.
-  String get stackTrace => _stackTrace;
+  String stackTrace;
 
-  /// The stack trace associated with the generation of the error, used for
-  /// debugging the server.
-  set stackTrace(String value) {
-    assert(value != null);
-    _stackTrace = value;
-  }
-
-  ServerErrorParams(bool isFatal, String message, String stackTrace) {
-    this.isFatal = isFatal;
-    this.message = message;
-    this.stackTrace = stackTrace;
-  }
+  ServerErrorParams(this.isFatal, this.message, this.stackTrace);
 
   factory ServerErrorParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       bool isFatal;
@@ -20457,8 +16384,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['isFatal'] = isFatal;
     result['message'] = message;
     result['stackTrace'] = stackTrace;
@@ -20497,7 +16424,7 @@
 /// Clients may not extend, implement or mix-in this class.
 class ServerGetVersionParams implements RequestParams {
   @override
-  Map<String, dynamic> toJson() => <String, dynamic>{};
+  Map<String, Object> toJson() => <String, Object>{};
 
   @override
   Request toRequest(String id) {
@@ -20526,23 +16453,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class ServerGetVersionResult implements ResponseResult {
-  String _version;
-
   /// The version number of the analysis server.
-  String get version => _version;
+  String version;
 
-  /// The version number of the analysis server.
-  set version(String value) {
-    assert(value != null);
-    _version = value;
-  }
-
-  ServerGetVersionResult(String version) {
-    this.version = version;
-  }
+  ServerGetVersionResult(this.version);
 
   factory ServerGetVersionResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String version;
@@ -20566,8 +16483,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['version'] = version;
     return result;
   }
@@ -20606,53 +16523,22 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class ServerLogEntry implements HasToJson {
-  int _time;
-
-  ServerLogEntryKind _kind;
-
-  String _data;
-
   /// The time (milliseconds since epoch) at which the server created this log
   /// entry.
-  int get time => _time;
-
-  /// The time (milliseconds since epoch) at which the server created this log
-  /// entry.
-  set time(int value) {
-    assert(value != null);
-    _time = value;
-  }
+  int time;
 
   /// The kind of the entry, used to determine how to interpret the "data"
   /// field.
-  ServerLogEntryKind get kind => _kind;
-
-  /// The kind of the entry, used to determine how to interpret the "data"
-  /// field.
-  set kind(ServerLogEntryKind value) {
-    assert(value != null);
-    _kind = value;
-  }
+  ServerLogEntryKind kind;
 
   /// The payload of the entry, the actual format is determined by the "kind"
   /// field.
-  String get data => _data;
+  String data;
 
-  /// The payload of the entry, the actual format is determined by the "kind"
-  /// field.
-  set data(String value) {
-    assert(value != null);
-    _data = value;
-  }
-
-  ServerLogEntry(int time, ServerLogEntryKind kind, String data) {
-    this.time = time;
-    this.kind = kind;
-    this.data = data;
-  }
+  ServerLogEntry(this.time, this.kind, this.data);
 
   factory ServerLogEntry.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       int time;
@@ -20681,8 +16567,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['time'] = time;
     result['kind'] = kind.toJson();
     result['data'] = data;
@@ -20780,7 +16666,7 @@
   }
 
   factory ServerLogEntryKind.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     if (json is String) {
       try {
         return ServerLogEntryKind(json);
@@ -20805,21 +16691,12 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class ServerLogParams implements HasToJson {
-  ServerLogEntry _entry;
+  ServerLogEntry entry;
 
-  ServerLogEntry get entry => _entry;
-
-  set entry(ServerLogEntry value) {
-    assert(value != null);
-    _entry = value;
-  }
-
-  ServerLogParams(ServerLogEntry entry) {
-    this.entry = entry;
-  }
+  ServerLogParams(this.entry);
 
   factory ServerLogParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       ServerLogEntry entry;
@@ -20841,8 +16718,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['entry'] = entry.toJson();
     return result;
   }
@@ -20902,7 +16779,7 @@
   }
 
   factory ServerService.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     if (json is String) {
       try {
         return ServerService(json);
@@ -20927,23 +16804,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class ServerSetSubscriptionsParams implements RequestParams {
-  List<ServerService> _subscriptions;
-
   /// A list of the services being subscribed to.
-  List<ServerService> get subscriptions => _subscriptions;
+  List<ServerService> subscriptions;
 
-  /// A list of the services being subscribed to.
-  set subscriptions(List<ServerService> value) {
-    assert(value != null);
-    _subscriptions = value;
-  }
-
-  ServerSetSubscriptionsParams(List<ServerService> subscriptions) {
-    this.subscriptions = subscriptions;
-  }
+  ServerSetSubscriptionsParams(this.subscriptions);
 
   factory ServerSetSubscriptionsParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       List<ServerService> subscriptions;
@@ -20951,7 +16818,7 @@
         subscriptions = jsonDecoder.decodeList(
             jsonPath + '.subscriptions',
             json['subscriptions'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 ServerService.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'subscriptions');
@@ -20969,8 +16836,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['subscriptions'] =
         subscriptions.map((ServerService value) => value.toJson()).toList();
     return result;
@@ -21006,7 +16873,7 @@
 /// Clients may not extend, implement or mix-in this class.
 class ServerSetSubscriptionsResult implements ResponseResult {
   @override
-  Map<String, dynamic> toJson() => <String, dynamic>{};
+  Map<String, Object> toJson() => <String, Object>{};
 
   @override
   Response toResponse(String id) {
@@ -21032,7 +16899,7 @@
 /// Clients may not extend, implement or mix-in this class.
 class ServerShutdownParams implements RequestParams {
   @override
-  Map<String, dynamic> toJson() => <String, dynamic>{};
+  Map<String, Object> toJson() => <String, Object>{};
 
   @override
   Request toRequest(String id) {
@@ -21058,7 +16925,7 @@
 /// Clients may not extend, implement or mix-in this class.
 class ServerShutdownResult implements ResponseResult {
   @override
-  Map<String, dynamic> toJson() => <String, dynamic>{};
+  Map<String, Object> toJson() => <String, Object>{};
 
   @override
   Response toResponse(String id) {
@@ -21088,51 +16955,29 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class ServerStatusParams implements HasToJson {
-  AnalysisStatus _analysis;
-
-  PubStatus _pub;
-
   /// The current status of analysis, including whether analysis is being
   /// performed and if so what is being analyzed.
-  AnalysisStatus get analysis => _analysis;
-
-  /// The current status of analysis, including whether analysis is being
-  /// performed and if so what is being analyzed.
-  set analysis(AnalysisStatus value) {
-    _analysis = value;
-  }
+  AnalysisStatus? analysis;
 
   /// The current status of pub execution, indicating whether we are currently
   /// running pub.
   ///
   /// Note: this status type is deprecated, and is no longer sent by the
   /// server.
-  PubStatus get pub => _pub;
+  PubStatus? pub;
 
-  /// The current status of pub execution, indicating whether we are currently
-  /// running pub.
-  ///
-  /// Note: this status type is deprecated, and is no longer sent by the
-  /// server.
-  set pub(PubStatus value) {
-    _pub = value;
-  }
-
-  ServerStatusParams({AnalysisStatus analysis, PubStatus pub}) {
-    this.analysis = analysis;
-    this.pub = pub;
-  }
+  ServerStatusParams({this.analysis, this.pub});
 
   factory ServerStatusParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
-      AnalysisStatus analysis;
+      AnalysisStatus? analysis;
       if (json.containsKey('analysis')) {
         analysis = AnalysisStatus.fromJson(
             jsonDecoder, jsonPath + '.analysis', json['analysis']);
       }
-      PubStatus pub;
+      PubStatus? pub;
       if (json.containsKey('pub')) {
         pub = PubStatus.fromJson(jsonDecoder, jsonPath + '.pub', json['pub']);
       }
@@ -21148,11 +16993,13 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
+    var analysis = this.analysis;
     if (analysis != null) {
       result['analysis'] = analysis.toJson();
     }
+    var pub = this.pub;
     if (pub != null) {
       result['pub'] = pub.toJson();
     }
@@ -21197,134 +17044,52 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class TypeHierarchyItem implements HasToJson {
-  Element _classElement;
-
-  String _displayName;
-
-  Element _memberElement;
-
-  int _superclass;
-
-  List<int> _interfaces;
-
-  List<int> _mixins;
-
-  List<int> _subclasses;
-
   /// The class element represented by this item.
-  Element get classElement => _classElement;
-
-  /// The class element represented by this item.
-  set classElement(Element value) {
-    assert(value != null);
-    _classElement = value;
-  }
+  Element classElement;
 
   /// The name to be displayed for the class. This field will be omitted if the
   /// display name is the same as the name of the element. The display name is
   /// different if there is additional type information to be displayed, such
   /// as type arguments.
-  String get displayName => _displayName;
-
-  /// The name to be displayed for the class. This field will be omitted if the
-  /// display name is the same as the name of the element. The display name is
-  /// different if there is additional type information to be displayed, such
-  /// as type arguments.
-  set displayName(String value) {
-    _displayName = value;
-  }
+  String? displayName;
 
   /// The member in the class corresponding to the member on which the
   /// hierarchy was requested. This field will be omitted if the hierarchy was
   /// not requested for a member or if the class does not have a corresponding
   /// member.
-  Element get memberElement => _memberElement;
-
-  /// The member in the class corresponding to the member on which the
-  /// hierarchy was requested. This field will be omitted if the hierarchy was
-  /// not requested for a member or if the class does not have a corresponding
-  /// member.
-  set memberElement(Element value) {
-    _memberElement = value;
-  }
+  Element? memberElement;
 
   /// The index of the item representing the superclass of this class. This
   /// field will be omitted if this item represents the class Object.
-  int get superclass => _superclass;
-
-  /// The index of the item representing the superclass of this class. This
-  /// field will be omitted if this item represents the class Object.
-  set superclass(int value) {
-    _superclass = value;
-  }
+  int? superclass;
 
   /// The indexes of the items representing the interfaces implemented by this
   /// class. The list will be empty if there are no implemented interfaces.
-  List<int> get interfaces => _interfaces;
-
-  /// The indexes of the items representing the interfaces implemented by this
-  /// class. The list will be empty if there are no implemented interfaces.
-  set interfaces(List<int> value) {
-    assert(value != null);
-    _interfaces = value;
-  }
+  List<int> interfaces;
 
   /// The indexes of the items representing the mixins referenced by this
   /// class. The list will be empty if there are no classes mixed in to this
   /// class.
-  List<int> get mixins => _mixins;
-
-  /// The indexes of the items representing the mixins referenced by this
-  /// class. The list will be empty if there are no classes mixed in to this
-  /// class.
-  set mixins(List<int> value) {
-    assert(value != null);
-    _mixins = value;
-  }
+  List<int> mixins;
 
   /// The indexes of the items representing the subtypes of this class. The
   /// list will be empty if there are no subtypes or if this item represents a
   /// supertype of the pivot type.
-  List<int> get subclasses => _subclasses;
+  List<int> subclasses;
 
-  /// The indexes of the items representing the subtypes of this class. The
-  /// list will be empty if there are no subtypes or if this item represents a
-  /// supertype of the pivot type.
-  set subclasses(List<int> value) {
-    assert(value != null);
-    _subclasses = value;
-  }
-
-  TypeHierarchyItem(Element classElement,
-      {String displayName,
-      Element memberElement,
-      int superclass,
-      List<int> interfaces,
-      List<int> mixins,
-      List<int> subclasses}) {
-    this.classElement = classElement;
-    this.displayName = displayName;
-    this.memberElement = memberElement;
-    this.superclass = superclass;
-    if (interfaces == null) {
-      this.interfaces = <int>[];
-    } else {
-      this.interfaces = interfaces;
-    }
-    if (mixins == null) {
-      this.mixins = <int>[];
-    } else {
-      this.mixins = mixins;
-    }
-    if (subclasses == null) {
-      this.subclasses = <int>[];
-    } else {
-      this.subclasses = subclasses;
-    }
-  }
+  TypeHierarchyItem(this.classElement,
+      {this.displayName,
+      this.memberElement,
+      this.superclass,
+      List<int>? interfaces,
+      List<int>? mixins,
+      List<int>? subclasses})
+      : interfaces = interfaces ?? <int>[],
+        mixins = mixins ?? <int>[],
+        subclasses = subclasses ?? <int>[];
 
   factory TypeHierarchyItem.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       Element classElement;
@@ -21334,17 +17099,17 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'classElement');
       }
-      String displayName;
+      String? displayName;
       if (json.containsKey('displayName')) {
         displayName = jsonDecoder.decodeString(
             jsonPath + '.displayName', json['displayName']);
       }
-      Element memberElement;
+      Element? memberElement;
       if (json.containsKey('memberElement')) {
         memberElement = Element.fromJson(
             jsonDecoder, jsonPath + '.memberElement', json['memberElement']);
       }
-      int superclass;
+      int? superclass;
       if (json.containsKey('superclass')) {
         superclass =
             jsonDecoder.decodeInt(jsonPath + '.superclass', json['superclass']);
@@ -21383,15 +17148,18 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['classElement'] = classElement.toJson();
+    var displayName = this.displayName;
     if (displayName != null) {
       result['displayName'] = displayName;
     }
+    var memberElement = this.memberElement;
     if (memberElement != null) {
       result['memberElement'] = memberElement.toJson();
     }
+    var superclass = this.superclass;
     if (superclass != null) {
       result['superclass'] = superclass;
     }
diff --git a/pkg/analysis_server/lib/src/analysis_server.dart b/pkg/analysis_server/lib/src/analysis_server.dart
index d32f2dd..77193b3 100644
--- a/pkg/analysis_server/lib/src/analysis_server.dart
+++ b/pkg/analysis_server/lib/src/analysis_server.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
+
 import 'dart:async';
 import 'dart:collection';
 import 'dart:core';
@@ -132,6 +134,8 @@
     RequestStatisticsHelper requestStatistics,
     DiagnosticServer diagnosticServer,
     this.detachableFileSystemManager,
+    // Disable to avoid using this in unit tests.
+    bool enableBazelWatcher = false,
   }) : super(
           options,
           sdkManager,
@@ -142,6 +146,7 @@
           httpClient,
           NotificationManager(channel, baseResourceProvider.pathContext),
           requestStatistics: requestStatistics,
+          enableBazelWatcher: enableBazelWatcher,
         ) {
     var contextManagerCallbacks =
         ServerContextManagerCallbacks(this, resourceProvider);
diff --git a/pkg/analysis_server/lib/src/analysis_server_abstract.dart b/pkg/analysis_server/lib/src/analysis_server_abstract.dart
index 22595fe..3288d8b 100644
--- a/pkg/analysis_server/lib/src/analysis_server_abstract.dart
+++ b/pkg/analysis_server/lib/src/analysis_server_abstract.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
+
 import 'dart:core';
 import 'dart:io' as io;
 import 'dart:io';
@@ -140,6 +142,7 @@
     http.Client httpClient,
     this.notificationManager, {
     this.requestStatistics,
+    bool enableBazelWatcher,
   })  : resourceProvider = OverlayResourceProvider(baseResourceProvider),
         pubApi = PubApi(instrumentationService, httpClient,
             Platform.environment['PUB_HOSTED_URL']) {
@@ -192,6 +195,7 @@
       analysisPerformanceLogger,
       analysisDriverScheduler,
       instrumentationService,
+      enableBazelWatcher: enableBazelWatcher,
     );
     searchEngine = SearchEngineImpl(driverMap.values);
   }
diff --git a/pkg/analysis_server/lib/src/channel/byte_stream_channel.dart b/pkg/analysis_server/lib/src/channel/byte_stream_channel.dart
index a6567e6..f9abadf 100644
--- a/pkg/analysis_server/lib/src/channel/byte_stream_channel.dart
+++ b/pkg/analysis_server/lib/src/channel/byte_stream_channel.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
+
 import 'dart:async';
 import 'dart:convert';
 import 'dart:io';
diff --git a/pkg/analysis_server/lib/src/channel/channel.dart b/pkg/analysis_server/lib/src/channel/channel.dart
index f8807d2..627db8a 100644
--- a/pkg/analysis_server/lib/src/channel/channel.dart
+++ b/pkg/analysis_server/lib/src/channel/channel.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
+
 import 'dart:convert';
 
 import 'package:analysis_server/protocol/protocol.dart';
diff --git a/pkg/analysis_server/lib/src/cider/assists.dart b/pkg/analysis_server/lib/src/cider/assists.dart
index ba46cce..c927a9e 100644
--- a/pkg/analysis_server/lib/src/cider/assists.dart
+++ b/pkg/analysis_server/lib/src/cider/assists.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
+
 import 'package:analysis_server/plugin/edit/assist/assist_core.dart';
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/correction/assist_internal.dart';
diff --git a/pkg/analysis_server/lib/src/cider/completion.dart b/pkg/analysis_server/lib/src/cider/completion.dart
index 8f1ec94..99eeec2 100644
--- a/pkg/analysis_server/lib/src/cider/completion.dart
+++ b/pkg/analysis_server/lib/src/cider/completion.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
+
 import 'package:analysis_server/src/protocol_server.dart';
 import 'package:analysis_server/src/services/completion/completion_core.dart';
 import 'package:analysis_server/src/services/completion/completion_performance.dart';
diff --git a/pkg/analysis_server/lib/src/cider/fixes.dart b/pkg/analysis_server/lib/src/cider/fixes.dart
index 3f3f087..ae971be 100644
--- a/pkg/analysis_server/lib/src/cider/fixes.dart
+++ b/pkg/analysis_server/lib/src/cider/fixes.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
+
 import 'package:analysis_server/plugin/edit/fix/fix_core.dart';
 import 'package:analysis_server/src/services/correction/change_workspace.dart';
 import 'package:analysis_server/src/services/correction/fix.dart';
diff --git a/pkg/analysis_server/lib/src/collections.dart b/pkg/analysis_server/lib/src/collections.dart
index 38f971a..b2e4fa3 100644
--- a/pkg/analysis_server/lib/src/collections.dart
+++ b/pkg/analysis_server/lib/src/collections.dart
@@ -3,11 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 
 /// Returns the given [list] if it is not empty, or `null` otherwise.
-List<E> nullIfEmpty<E>(List<E> list) {
-  if (list == null) {
-    return null;
-  }
-  if (list.isEmpty) {
+List<E>? nullIfEmpty<E>(List<E>? list) {
+  if (list == null || list.isEmpty) {
     return null;
   }
   return list;
diff --git a/pkg/analysis_server/lib/src/computer/computer_closingLabels.dart b/pkg/analysis_server/lib/src/computer/computer_closingLabels.dart
index dd01e3f..856e20d 100644
--- a/pkg/analysis_server/lib/src/computer/computer_closingLabels.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_closingLabels.dart
@@ -46,23 +46,21 @@
 
   _DartUnitClosingLabelsComputerVisitor(this.computer);
 
-  ClosingLabel get _currentLabel => labelStack.isEmpty ? null : labelStack.last;
+  ClosingLabel? get _currentLabel =>
+      labelStack.isEmpty ? null : labelStack.last;
 
   @override
   void visitInstanceCreationExpression(InstanceCreationExpression node) {
-    ClosingLabel label;
-
-    if (node.argumentList != null) {
-      var labelText = node.constructorName.type.name.name;
-      if (node.constructorName.name != null) {
-        labelText += '.${node.constructorName.name.name}';
-      }
-      // We override the node used for doing line calculations because otherwise
-      // constructors that split over multiple lines (but have parens on same
-      // line) would incorrectly get labels, because node.start on an instance
-      // creation expression starts at the start of the expression.
-      label = _addLabel(node, labelText, checkLinesUsing: node.argumentList);
+    var labelText = node.constructorName.type.name.name;
+    var name = node.constructorName.name;
+    if (name != null) {
+      labelText += '.${name.name}';
     }
+    // We override the node used for doing line calculations because otherwise
+    // constructors that split over multiple lines (but have parens on same
+    // line) would incorrectly get labels, because node.start on an instance
+    // creation expression starts at the start of the expression.
+    var label = _addLabel(node, labelText, checkLinesUsing: node.argumentList);
 
     if (label != null) _pushLabel(label);
 
@@ -76,9 +74,9 @@
   @override
   void visitListLiteral(ListLiteral node) {
     var args = node.typeArguments?.arguments;
-    var typeName = args != null ? args[0]?.toString() : null;
+    var typeName = args != null ? args[0].toString() : null;
 
-    ClosingLabel label;
+    ClosingLabel? label;
 
     if (typeName != null) {
       label = _addLabel(node, '<$typeName>[]');
@@ -103,8 +101,8 @@
     }
   }
 
-  ClosingLabel _addLabel(AstNode node, String label,
-      {AstNode checkLinesUsing}) {
+  ClosingLabel? _addLabel(AstNode node, String label,
+      {AstNode? checkLinesUsing}) {
     // Never add labels if we're inside strings.
     if (interpolatedStringsEntered > 0) {
       return null;
@@ -112,10 +110,8 @@
 
     checkLinesUsing = checkLinesUsing ?? node;
 
-    final CharacterLocation start =
-        computer._lineInfo.getLocation(checkLinesUsing.offset);
-    final CharacterLocation end =
-        computer._lineInfo.getLocation(checkLinesUsing.end - 1);
+    var start = computer._lineInfo.getLocation(checkLinesUsing.offset);
+    var end = computer._lineInfo.getLocation(checkLinesUsing.end - 1);
 
     var closingLabel = ClosingLabel(node.offset, node.length, label);
 
diff --git a/pkg/analysis_server/lib/src/computer/computer_folding.dart b/pkg/analysis_server/lib/src/computer/computer_folding.dart
index 2a8bc96..a279dfb 100644
--- a/pkg/analysis_server/lib/src/computer/computer_folding.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_folding.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
+
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/dart/ast/visitor.dart';
diff --git a/pkg/analysis_server/lib/src/computer/computer_highlights.dart b/pkg/analysis_server/lib/src/computer/computer_highlights.dart
index 717c136..2a97366 100644
--- a/pkg/analysis_server/lib/src/computer/computer_highlights.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_highlights.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
+
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart'
     show SemanticTokenTypes, SemanticTokenModifiers;
 import 'package:analysis_server/src/lsp/constants.dart'
diff --git a/pkg/analysis_server/lib/src/computer/computer_hover.dart b/pkg/analysis_server/lib/src/computer/computer_hover.dart
index 3207fbf..53ff8df 100644
--- a/pkg/analysis_server/lib/src/computer/computer_hover.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_hover.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
+
 import 'package:analysis_server/protocol/protocol_generated.dart'
     show HoverInformation;
 import 'package:analysis_server/src/computer/computer_overrides.dart';
diff --git a/pkg/analysis_server/lib/src/computer/computer_outline.dart b/pkg/analysis_server/lib/src/computer/computer_outline.dart
index 01a7d23..fedd848 100644
--- a/pkg/analysis_server/lib/src/computer/computer_outline.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_outline.dart
@@ -8,7 +8,6 @@
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/visitor.dart';
 import 'package:analyzer/dart/element/element.dart' as engine;
-import 'package:analyzer/source/line_info.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 
 /// A computer for [CompilationUnit] outline.
@@ -18,10 +17,19 @@
 
   DartUnitOutlineComputer(this.resolvedUnit, {this.withBasicFlutter = false});
 
+  CompilationUnit get _unit {
+    var unit = resolvedUnit.unit;
+    if (unit == null) {
+      throw StateError('DartUnitOutlineComputer created with invalid result');
+    }
+    return unit;
+  }
+
   /// Returns the computed outline, not `null`.
   Outline compute() {
+    var unit = _unit;
     var unitContents = <Outline>[];
-    for (var unitMember in resolvedUnit.unit.declarations) {
+    for (var unitMember in unit.declarations) {
       if (unitMember is ClassDeclaration) {
         unitContents.add(_newClassOutline(
             unitMember, _outlinesForMembers(unitMember.members)));
@@ -41,13 +49,11 @@
       } else if (unitMember is TopLevelVariableDeclaration) {
         var fieldDeclaration = unitMember;
         var fields = fieldDeclaration.variables;
-        if (fields != null) {
-          var fieldType = fields.type;
-          var fieldTypeName = _safeToSource(fieldType);
-          for (var field in fields.variables) {
-            unitContents.add(_newVariableOutline(
-                fieldTypeName, ElementKind.TOP_LEVEL_VARIABLE, field, false));
-          }
+        var fieldType = fields.type;
+        var fieldTypeName = _safeToSource(fieldType);
+        for (var field in fields.variables) {
+          unitContents.add(_newVariableOutline(
+              fieldTypeName, ElementKind.TOP_LEVEL_VARIABLE, field, false));
         }
       } else if (unitMember is FunctionDeclaration) {
         var functionDeclaration = unitMember;
@@ -80,10 +86,18 @@
   }
 
   Location _getLocationOffsetLength(int offset, int length) {
-    CharacterLocation lineLocation = resolvedUnit.lineInfo.getLocation(offset);
-    var startLine = lineLocation.lineNumber;
-    var startColumn = lineLocation.columnNumber;
-    return Location(resolvedUnit.path, offset, length, startLine, startColumn);
+    var path = resolvedUnit.path;
+    if (path == null) {
+      throw StateError('DartUnitOutlineComputer called with invalid result');
+    }
+    var startLocation = resolvedUnit.lineInfo.getLocation(offset);
+    var startLine = startLocation.lineNumber;
+    var startColumn = startLocation.columnNumber;
+    var endLocation = resolvedUnit.lineInfo.getLocation(offset + length);
+    var endLine = endLocation.lineNumber;
+    var endColumn = endLocation.columnNumber;
+    return Location(
+        path, offset, length, startLine, startColumn, endLine, endColumn);
   }
 
   Outline _newClassOutline(ClassDeclaration node, List<Outline> classContents) {
@@ -314,10 +328,11 @@
   }
 
   Outline _newUnitOutline(List<Outline> unitContents) {
+    var unit = _unit;
     var element = Element(
         ElementKind.COMPILATION_UNIT, '<unit>', Element.makeFlags(),
-        location: _getLocationNode(resolvedUnit.unit));
-    return _nodeOutline(resolvedUnit.unit, element, unitContents);
+        location: _getLocationNode(unit));
+    return _nodeOutline(unit, element, unitContents);
   }
 
   Outline _newVariableOutline(String typeName, ElementKind kind,
@@ -339,17 +354,20 @@
   }
 
   Outline _nodeOutline(AstNode node, Element element,
-      [List<Outline> children]) {
+      [List<Outline>? children]) {
     var offset = node.offset;
     var end = node.end;
     if (node is VariableDeclaration) {
       var parent = node.parent;
-      if (parent is VariableDeclarationList && parent.variables.isNotEmpty) {
+      var grandParent = parent?.parent;
+      if (grandParent != null &&
+          parent is VariableDeclarationList &&
+          parent.variables.isNotEmpty) {
         if (parent.variables[0] == node) {
-          offset = parent.parent.offset;
+          offset = grandParent.offset;
         }
         if (parent.variables.last == node) {
-          end = parent.parent.end;
+          end = grandParent.end;
         }
       }
     }
@@ -375,13 +393,11 @@
       if (classMember is FieldDeclaration) {
         var fieldDeclaration = classMember;
         var fields = fieldDeclaration.fields;
-        if (fields != null) {
-          var fieldType = fields.type;
-          var fieldTypeName = _safeToSource(fieldType);
-          for (var field in fields.variables) {
-            memberOutlines.add(_newVariableOutline(fieldTypeName,
-                ElementKind.FIELD, field, fieldDeclaration.isStatic));
-          }
+        var fieldType = fields.type;
+        var fieldTypeName = _safeToSource(fieldType);
+        for (var field in fields.variables) {
+          memberOutlines.add(_newVariableOutline(fieldTypeName,
+              ElementKind.FIELD, field, fieldDeclaration.isStatic));
         }
       }
       if (classMember is MethodDeclaration) {
@@ -392,7 +408,7 @@
     return memberOutlines;
   }
 
-  static String _getTypeParametersStr(TypeParameterList parameters) {
+  static String? _getTypeParametersStr(TypeParameterList? parameters) {
     if (parameters == null) {
       return null;
     }
@@ -405,7 +421,7 @@
     return element != null && element.hasDeprecated;
   }
 
-  static String _safeToSource(AstNode node) =>
+  static String _safeToSource(AstNode? node) =>
       node == null ? '' : node.toSource();
 }
 
@@ -420,7 +436,7 @@
 
   /// Return `true` if the given [element] is the method 'group' defined in the
   /// test package.
-  bool isGroup(engine.ExecutableElement element) {
+  bool isGroup(engine.ExecutableElement? element) {
     if (element != null && element.hasIsTestGroup) {
       return true;
     }
@@ -431,7 +447,7 @@
 
   /// Return `true` if the given [element] is the method 'test' defined in the
   /// test package.
-  bool isTest(engine.ExecutableElement element) {
+  bool isTest(engine.ExecutableElement? element) {
     if (element != null && element.hasIsTest) {
       return true;
     }
@@ -452,7 +468,9 @@
       node.argumentList
           .accept(_FunctionBodyOutlinesVisitor(outlineComputer, children));
 
-      var text = _flutter.getWidgetPresentationText(node);
+      // The method `getWidgetPresentationText` should not return `null` when
+      // `isWidgetCreation` returns `true`.
+      var text = _flutter.getWidgetPresentationText(node) ?? '<unknown>';
       var element = Element(ElementKind.CONSTRUCTOR_INVOCATION, text, 0,
           location: outlineComputer._getLocationOffsetLength(node.offset, 0));
 
@@ -472,9 +490,8 @@
     if (nameElement is! engine.ExecutableElement) {
       return;
     }
-    engine.ExecutableElement executableElement = nameElement;
 
-    String extractString(NodeList<Expression> arguments) {
+    String extractString(NodeList<Expression>? arguments) {
       if (arguments != null && arguments.isNotEmpty) {
         var argument = arguments[0];
         if (argument is StringLiteral) {
@@ -488,9 +505,9 @@
       return 'unnamed';
     }
 
-    void addOutlineNode(ElementKind kind, [List<Outline> children]) {
+    void addOutlineNode(ElementKind kind, [List<Outline>? children]) {
       var executableName = nameNode.name;
-      var description = extractString(node.argumentList?.arguments);
+      var description = extractString(node.argumentList.arguments);
       var name = '$executableName("$description")';
       var element = Element(kind, name, 0,
           location: outlineComputer._getLocationNode(nameNode));
@@ -499,12 +516,12 @@
           children: nullIfEmpty(children)));
     }
 
-    if (isGroup(executableElement)) {
+    if (isGroup(nameElement)) {
       var groupContents = <Outline>[];
       node.argumentList
           .accept(_FunctionBodyOutlinesVisitor(outlineComputer, groupContents));
       addOutlineNode(ElementKind.UNIT_TEST_GROUP, groupContents);
-    } else if (isTest(executableElement)) {
+    } else if (isTest(nameElement)) {
       addOutlineNode(ElementKind.UNIT_TEST_TEST);
     } else {
       super.visitMethodInvocation(node);
diff --git a/pkg/analysis_server/lib/src/computer/computer_overrides.dart b/pkg/analysis_server/lib/src/computer/computer_overrides.dart
index 9a27a6e..505abac 100644
--- a/pkg/analysis_server/lib/src/computer/computer_overrides.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_overrides.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
+
 import 'package:analysis_server/src/collections.dart';
 import 'package:analysis_server/src/protocol_server.dart' as proto;
 import 'package:analyzer/dart/ast/ast.dart';
diff --git a/pkg/analysis_server/lib/src/computer/computer_signature.dart b/pkg/analysis_server/lib/src/computer/computer_signature.dart
index bb26c6a..20bc565 100644
--- a/pkg/analysis_server/lib/src/computer/computer_signature.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_signature.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
+
 import 'package:analysis_server/src/computer/computer_hover.dart';
 import 'package:analysis_server/src/protocol_server.dart';
 import 'package:analyzer/dart/ast/ast.dart';
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 2229f6f..3a2ec51 100644
--- a/pkg/analysis_server/lib/src/computer/import_elements_computer.dart
+++ b/pkg/analysis_server/lib/src/computer/import_elements_computer.dart
@@ -31,19 +31,26 @@
   /// imported into the library at the given [path].
   Future<SourceChange> createEdits(
       List<ImportedElements> importedElementsList) async {
+    var unit = libraryResult.unit;
+    var path = libraryResult.path;
+    if (unit == null || path == null) {
+      // We should never reach this point because the libraryResult should be
+      // valid.
+      return SourceChange('');
+    }
     var filteredImportedElements =
         _filterImportedElements(importedElementsList);
     var libraryElement = libraryResult.libraryElement;
     var uriConverter = libraryResult.session.uriConverter;
     var existingImports = <ImportDirective>[];
-    for (var directive in libraryResult.unit.directives) {
+    for (var directive in unit.directives) {
       if (directive is ImportDirective) {
         existingImports.add(directive);
       }
     }
 
     var builder = ChangeBuilder(session: libraryResult.session);
-    await builder.addDartFileEdit(libraryResult.path, (builder) {
+    await builder.addDartFileEdit(path, (builder) {
       for (var importedElements in filteredImportedElements) {
         var matchingImports =
             _findMatchingImports(existingImports, importedElements);
@@ -88,8 +95,9 @@
           //
           // Apply the edits.
           //
-          for (var directive in updateMap.keys) {
-            var update = updateMap[directive];
+          for (var entry in updateMap.entries) {
+            var directive = entry.key;
+            var update = entry.value;
             var namesToUnhide = update.namesToUnhide;
             var namesToShow = update.namesToShow;
             namesToShow.sort();
@@ -127,12 +135,8 @@
                       var precedingNode = directive.prefix ??
                           directive.deferredKeyword ??
                           directive.uri;
-                      if (precedingNode == null) {
-                        builder.addDeletion(range.node(combinator));
-                      } else {
-                        builder.addDeletion(
-                            range.endEnd(precedingNode, combinator));
-                      }
+                      builder
+                          .addDeletion(range.endEnd(precedingNode, combinator));
                     }
                   } else {
                     builder.addDeletion(range.endEnd(
@@ -184,7 +188,7 @@
       return false;
     }
 
-    ImportDirective preferredDirective;
+    late ImportDirective preferredDirective;
     var bestEditCount = -1;
     var deleteHide = false;
     var addShow = false;
@@ -276,7 +280,12 @@
   /// Partially copied from DartFileEditBuilderImpl.
   _InsertionDescription _getInsertionDescription(String importUri) {
     var unit = libraryResult.unit;
-    LibraryDirective libraryDirective;
+    if (unit == null) {
+      // We should never reach this point because the libraryResult should be
+      // valid.
+      return _InsertionDescription(0, after: 2);
+    }
+    LibraryDirective? libraryDirective;
     var importDirectives = <ImportDirective>[];
     var otherDirectives = <Directive>[];
     for (var directive in unit.directives) {
@@ -341,7 +350,11 @@
   /// [importedElements]. They will match if they import the same library using
   /// the same prefix.
   bool _matches(ImportDirective import, ImportedElements importedElements) {
-    var library = import.element.importedLibrary;
+    var importElement = import.element;
+    if (importElement == null) {
+      return false;
+    }
+    var library = importElement.importedLibrary;
     return library != null &&
         library.source.fullName == importedElements.path &&
         (import.prefix?.name ?? '') == importedElements.prefix;
diff --git a/pkg/analysis_server/lib/src/computer/imported_elements_computer.dart b/pkg/analysis_server/lib/src/computer/imported_elements_computer.dart
index 8d2c2f4..a53a891 100644
--- a/pkg/analysis_server/lib/src/computer/imported_elements_computer.dart
+++ b/pkg/analysis_server/lib/src/computer/imported_elements_computer.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
+
 import 'package:analysis_server/protocol/protocol_generated.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/visitor.dart';
diff --git a/pkg/analysis_server/lib/src/context_manager.dart b/pkg/analysis_server/lib/src/context_manager.dart
index ec9494ef..108e4c63 100644
--- a/pkg/analysis_server/lib/src/context_manager.dart
+++ b/pkg/analysis_server/lib/src/context_manager.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
+
 import 'dart:async';
 import 'dart:collection';
 import 'dart:core';
@@ -15,7 +17,6 @@
 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/performance_logger.dart';
-import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/generated/sdk.dart';
 import 'package:analyzer/src/generated/source.dart';
@@ -27,8 +28,10 @@
 import 'package:analyzer/src/task/options.dart';
 import 'package:analyzer/src/util/file_paths.dart' as file_paths;
 import 'package:analyzer/src/workspace/bazel.dart';
+import 'package:analyzer/src/workspace/bazel_watcher.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart' as protocol;
 import 'package:analyzer_plugin/utilities/analyzer_converter.dart';
+import 'package:meta/meta.dart';
 import 'package:path/path.dart' as pathos;
 import 'package:watcher/watcher.dart';
 import 'package:yaml/yaml.dart';
@@ -39,7 +42,9 @@
 /// functionality due its performance issues. We plan to benchmark and optimize
 /// it and re-enable it everywhere.
 /// Not private to enable testing.
-var experimentalEnableBazelWatching = false;
+/// NB: If you set this to `false` remember to disable the
+/// `test/integration/serve/bazel_changes_test.dart`.
+var experimentalEnableBazelWatching = true;
 
 /// Class that maintains a mapping from included/excluded paths to a set of
 /// folders that should correspond to analysis contexts.
@@ -185,20 +190,35 @@
   final Map<Folder, StreamSubscription<WatchEvent>> changeSubscriptions =
       <Folder, StreamSubscription<WatchEvent>>{};
 
-  /// For each root directory stores subscriptions and watchers that we
-  /// established to detect changes to Bazel generated files.
-  final Map<Folder, _BazelWorkspaceSubscription> bazelSubscriptions =
-      <Folder, _BazelWorkspaceSubscription>{};
+  /// For each folder, stores the subscription to the Bazel workspace so that we
+  /// can establish watches for the generated files.
+  final bazelSearchSubscriptions =
+      <Folder, StreamSubscription<BazelSearchInfo>>{};
 
-  ContextManagerImpl(
-    this.resourceProvider,
-    this.sdkManager,
-    this._byteStore,
-    this._performanceLog,
-    this._scheduler,
-    this._instrumentationService,
-  ) {
+  /// The watcher service running in a separate isolate to watch for changes
+  /// to files generated by Bazel.
+  ///
+  /// Might be `null` if watching Bazel files is not enabled.
+  BazelFileWatcherService bazelWatcherService;
+
+  /// The subscription to changes in the files watched by [bazelWatcherService].
+  ///
+  /// Might be `null` if watching Bazel files is not enabled.
+  StreamSubscription<List<WatchEvent>> bazelWatcherSubscription;
+
+  /// For each [Folder] store which files are being watched. This allows us to
+  /// clean up when we destroy a context.
+  final bazelWatchedPathsPerFolder = <Folder, _BazelWatchedFiles>{};
+
+  ContextManagerImpl(this.resourceProvider, this.sdkManager, this._byteStore,
+      this._performanceLog, this._scheduler, this._instrumentationService,
+      {@required enableBazelWatcher}) {
     pathContext = resourceProvider.pathContext;
+    if (enableBazelWatcher) {
+      bazelWatcherService = BazelFileWatcherService(_instrumentationService);
+      bazelWatcherSubscription = bazelWatcherService.events
+          .listen((events) => _handleBazelWatchEvents(events));
+    }
   }
 
   @override
@@ -444,10 +464,14 @@
   /// Clean up and destroy the context associated with the given folder.
   void _destroyAnalysisContext(DriverBasedAnalysisContext context) {
     context.driver.dispose();
-
     var rootFolder = context.contextRoot.root;
     changeSubscriptions.remove(rootFolder)?.cancel();
-    bazelSubscriptions.remove(rootFolder)?.cancel();
+    var watched = bazelWatchedPathsPerFolder.remove(rootFolder);
+    if (watched != null) {
+      for (var path in watched.paths) {
+        bazelWatcherService.stopWatching(watched.workspace, path);
+      }
+    }
     driverMap.remove(rootFolder);
   }
 
@@ -465,39 +489,29 @@
   ///
   /// Whenever the files change, we trigger re-analysis. This allows us to react
   /// to creation/modification of files that were generated by Bazel.
-  void _handleBazelFileNotification(
-      Folder folder, BazelFileNotification notification) {
-    var fileSubscriptions = bazelSubscriptions[folder].fileSubscriptions;
-    if (fileSubscriptions.containsKey(notification.requested)) {
-      // We have already established a Watcher for this particular path.
-      return;
-    }
-    var watcher = notification.watcher(
-        pollingDelayShort: Duration(seconds: 10),
-        pollingDelayLong: Duration(seconds: 30));
-    var subscription = watcher.events.listen(_handleBazelWatchEvent);
-    fileSubscriptions[notification.requested] =
-        _BazelFilesSubscription(watcher, subscription);
-    watcher.start();
+  void _handleBazelSearchInfo(
+      Folder folder, String workspace, BazelSearchInfo info) {
+    var watched = bazelWatchedPathsPerFolder.putIfAbsent(
+        folder, () => _BazelWatchedFiles(workspace));
+    var added = watched.paths.add(info.requestedPath);
+    if (added) bazelWatcherService.startWatching(workspace, info);
   }
 
   /// Notifies the drivers that a generated Bazel file has changed.
-  void _handleBazelWatchEvent(WatchEvent event) {
-    if (event.type == ChangeType.ADD) {
-      for (var driver in driverMap.values) {
-        driver.addFile(event.path);
-        // Since the file has been created after we've searched for it, the
-        // URI resolution is likely wrong, so we need to reset it.
-        driver.resetUriResolution();
+  void _handleBazelWatchEvents(List<WatchEvent> events) {
+    for (var driver in driverMap.values) {
+      var needsUriReset = false;
+      for (var event in events) {
+        if (event.type == ChangeType.ADD) {
+          driver.addFile(event.path);
+          needsUriReset = true;
+        }
+        if (event.type == ChangeType.MODIFY) driver.changeFile(event.path);
+        if (event.type == ChangeType.REMOVE) driver.removeFile(event.path);
       }
-    } else if (event.type == ChangeType.MODIFY) {
-      for (var driver in driverMap.values) {
-        driver.changeFile(event.path);
-      }
-    } else if (event.type == ChangeType.REMOVE) {
-      for (var driver in driverMap.values) {
-        driver.removeFile(event.path);
-      }
+      // Since the file has been created after we've searched for it, the
+      // URI resolution is likely wrong, so we need to reset it.
+      if (needsUriReset) driver.resetUriResolution();
     }
   }
 
@@ -584,43 +598,17 @@
     if (!experimentalEnableBazelWatching) return;
     var workspace = analysisDriver.analysisContext.contextRoot.workspace;
     if (workspace is BazelWorkspace &&
-        !bazelSubscriptions.containsKey(folder)) {
-      var subscription = workspace.bazelCandidateFiles.listen(
-          (notification) => _handleBazelFileNotification(folder, notification));
-      bazelSubscriptions[folder] = _BazelWorkspaceSubscription(subscription);
+        !bazelSearchSubscriptions.containsKey(folder)) {
+      var searchSubscription = workspace.bazelCandidateFiles.listen(
+          (notification) =>
+              _handleBazelSearchInfo(folder, workspace.root, notification));
+      bazelSearchSubscriptions[folder] = searchSubscription;
     }
   }
 }
 
-/// A watcher with subscription used to detect changes to some file.
-class _BazelFilesSubscription {
-  final BazelFileWatcher watcher;
-  final StreamSubscription<WatchEvent> subscription;
-
-  _BazelFilesSubscription(this.watcher, this.subscription);
-
-  void cancel() {
-    subscription.cancel();
-    watcher.stop();
-  }
-}
-
-/// A subscription to notifications from a Bazel workspace.
-class _BazelWorkspaceSubscription {
-  final StreamSubscription<BazelFileNotification> workspaceSubscription;
-
-  /// For each absolute path that we searched for, provides the subscriptions
-  /// that we established to watch for changes.
-  ///
-  /// Note that the absolute path used when searching for a file is not
-  /// necessarily the actual path of the file (see [BazelWorkspace.findFile] for
-  /// details on how the files are searched).
-  final fileSubscriptions = <String, _BazelFilesSubscription>{};
-
-  _BazelWorkspaceSubscription(this.workspaceSubscription);
-
-  void cancel() {
-    workspaceSubscription.cancel();
-    fileSubscriptions.values.forEach((sub) => sub.cancel());
-  }
+class _BazelWatchedFiles {
+  final String workspace;
+  final paths = <String>{};
+  _BazelWatchedFiles(this.workspace);
 }
diff --git a/pkg/analysis_server/lib/src/domain_abstract.dart b/pkg/analysis_server/lib/src/domain_abstract.dart
index 3d168d5..e88d541 100644
--- a/pkg/analysis_server/lib/src/domain_abstract.dart
+++ b/pkg/analysis_server/lib/src/domain_abstract.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
+
 import 'dart:async';
 import 'dart:convert';
 import 'dart:math' as math;
diff --git a/pkg/analysis_server/lib/src/domain_analysis.dart b/pkg/analysis_server/lib/src/domain_analysis.dart
index 9785016..a9b8464 100644
--- a/pkg/analysis_server/lib/src/domain_analysis.dart
+++ b/pkg/analysis_server/lib/src/domain_analysis.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
+
 import 'dart:core';
 
 import 'package:analysis_server/protocol/protocol_constants.dart';
@@ -10,6 +12,7 @@
 import 'package:analysis_server/src/computer/computer_signature.dart';
 import 'package:analysis_server/src/computer/imported_elements_computer.dart';
 import 'package:analysis_server/src/domain_abstract.dart';
+import 'package:analysis_server/src/domain_analysis_flags.dart';
 import 'package:analysis_server/src/plugin/request_converter.dart';
 import 'package:analysis_server/src/plugin/result_merger.dart';
 import 'package:analysis_server/src/protocol/protocol_internal.dart';
@@ -20,9 +23,6 @@
 import 'package:analyzer_plugin/src/utilities/navigation/navigation.dart';
 import 'package:analyzer_plugin/utilities/navigation/navigation_dart.dart';
 
-// TODO(devoncarew): See #31456 for the tracking issue to remove this flag.
-final bool disableManageImportsOnPaste = true;
-
 /// Instances of the class [AnalysisDomainHandler] implement a [RequestHandler]
 /// that handles requests in the `analysis` domain.
 class AnalysisDomainHandler extends AbstractRequestHandler {
diff --git a/pkg/analysis_server/lib/src/domain_analysis_flags.dart b/pkg/analysis_server/lib/src/domain_analysis_flags.dart
new file mode 100644
index 0000000..c1196be
--- /dev/null
+++ b/pkg/analysis_server/lib/src/domain_analysis_flags.dart
@@ -0,0 +1,6 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// TODO(devoncarew): See #31456 for the tracking issue to remove this flag.
+final bool disableManageImportsOnPaste = true;
diff --git a/pkg/analysis_server/lib/src/domain_analytics.dart b/pkg/analysis_server/lib/src/domain_analytics.dart
index af31ca1..9a8f1aa 100644
--- a/pkg/analysis_server/lib/src/domain_analytics.dart
+++ b/pkg/analysis_server/lib/src/domain_analytics.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
+
 import 'dart:core';
 
 import 'package:analysis_server/protocol/protocol.dart';
diff --git a/pkg/analysis_server/lib/src/domain_completion.dart b/pkg/analysis_server/lib/src/domain_completion.dart
index ea54b61..8a9ff43 100644
--- a/pkg/analysis_server/lib/src/domain_completion.dart
+++ b/pkg/analysis_server/lib/src/domain_completion.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
+
 import 'dart:async';
 
 import 'package:analysis_server/protocol/protocol.dart';
diff --git a/pkg/analysis_server/lib/src/domain_diagnostic.dart b/pkg/analysis_server/lib/src/domain_diagnostic.dart
index 747fb93..6e7b6ab 100644
--- a/pkg/analysis_server/lib/src/domain_diagnostic.dart
+++ b/pkg/analysis_server/lib/src/domain_diagnostic.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
+
 import 'dart:core';
 
 import 'package:analysis_server/protocol/protocol.dart';
diff --git a/pkg/analysis_server/lib/src/domain_execution.dart b/pkg/analysis_server/lib/src/domain_execution.dart
index db74f5f..f1fec6e 100644
--- a/pkg/analysis_server/lib/src/domain_execution.dart
+++ b/pkg/analysis_server/lib/src/domain_execution.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
+
 import 'dart:collection';
 import 'dart:core';
 
diff --git a/pkg/analysis_server/lib/src/domain_kythe.dart b/pkg/analysis_server/lib/src/domain_kythe.dart
index 26e4788..14ac442 100644
--- a/pkg/analysis_server/lib/src/domain_kythe.dart
+++ b/pkg/analysis_server/lib/src/domain_kythe.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
+
 import 'dart:core';
 
 import 'package:analysis_server/protocol/protocol.dart';
diff --git a/pkg/analysis_server/lib/src/domain_server.dart b/pkg/analysis_server/lib/src/domain_server.dart
index c0d4e69..44a8b4b 100644
--- a/pkg/analysis_server/lib/src/domain_server.dart
+++ b/pkg/analysis_server/lib/src/domain_server.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
+
 import 'package:analysis_server/protocol/protocol.dart';
 import 'package:analysis_server/protocol/protocol_constants.dart';
 import 'package:analysis_server/protocol/protocol_generated.dart';
diff --git a/pkg/analysis_server/lib/src/domains/analysis/implemented_dart.dart b/pkg/analysis_server/lib/src/domains/analysis/implemented_dart.dart
index 0939d94..3058da5 100644
--- a/pkg/analysis_server/lib/src/domains/analysis/implemented_dart.dart
+++ b/pkg/analysis_server/lib/src/domains/analysis/implemented_dart.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
+
 import 'package:analysis_server/src/protocol_server.dart' as protocol;
 import 'package:analysis_server/src/services/search/search_engine.dart';
 import 'package:analyzer/dart/element/element.dart';
diff --git a/pkg/analysis_server/lib/src/domains/analysis/occurrences.dart b/pkg/analysis_server/lib/src/domains/analysis/occurrences.dart
index 295d92c..5a10351 100644
--- a/pkg/analysis_server/lib/src/domains/analysis/occurrences.dart
+++ b/pkg/analysis_server/lib/src/domains/analysis/occurrences.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
+
 import 'package:analysis_server/plugin/analysis/occurrences/occurrences_core.dart';
 import 'package:analysis_server/src/protocol_server.dart' as protocol;
 
diff --git a/pkg/analysis_server/lib/src/domains/analysis/occurrences_dart.dart b/pkg/analysis_server/lib/src/domains/analysis/occurrences_dart.dart
index f263e74..441e949 100644
--- a/pkg/analysis_server/lib/src/domains/analysis/occurrences_dart.dart
+++ b/pkg/analysis_server/lib/src/domains/analysis/occurrences_dart.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
+
 import 'package:analysis_server/plugin/analysis/occurrences/occurrences_core.dart';
 import 'package:analysis_server/src/protocol_server.dart' as protocol;
 import 'package:analyzer/dart/ast/ast.dart';
diff --git a/pkg/analysis_server/lib/src/domains/completion/available_suggestions.dart b/pkg/analysis_server/lib/src/domains/completion/available_suggestions.dart
index 79e549c..8440c7d 100644
--- a/pkg/analysis_server/lib/src/domains/completion/available_suggestions.dart
+++ b/pkg/analysis_server/lib/src/domains/completion/available_suggestions.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
+
 import 'package:analysis_server/src/protocol_server.dart' as protocol;
 import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/dart/element/element.dart';
@@ -266,6 +268,8 @@
       0, // length
       declaration.locationStartLine,
       declaration.locationStartColumn,
+      declaration.locationStartLine, // endLine
+      declaration.locationStartColumn, // endColumn
     ),
     parameters: declaration.parameters,
     returnType: declaration.returnType,
diff --git a/pkg/analysis_server/lib/src/domains/execution/completion.dart b/pkg/analysis_server/lib/src/domains/execution/completion.dart
index faad3f9..26197cd 100644
--- a/pkg/analysis_server/lib/src/domains/execution/completion.dart
+++ b/pkg/analysis_server/lib/src/domains/execution/completion.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
+
 import 'package:analysis_server/src/protocol_server.dart'
     show
         CompletionSuggestion,
diff --git a/pkg/analysis_server/lib/src/edit/edit_dartfix.dart b/pkg/analysis_server/lib/src/edit/edit_dartfix.dart
index c36f2bb..2468615 100644
--- a/pkg/analysis_server/lib/src/edit/edit_dartfix.dart
+++ b/pkg/analysis_server/lib/src/edit/edit_dartfix.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
+
 import 'package:analysis_server/protocol/protocol.dart';
 import 'package:analysis_server/protocol/protocol_generated.dart';
 import 'package:analysis_server/src/analysis_server.dart';
diff --git a/pkg/analysis_server/lib/src/edit/edit_domain.dart b/pkg/analysis_server/lib/src/edit/edit_domain.dart
index be204d6..93c8e3d 100644
--- a/pkg/analysis_server/lib/src/edit/edit_domain.dart
+++ b/pkg/analysis_server/lib/src/edit/edit_domain.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
+
 import 'dart:async';
 
 import 'package:analysis_server/plugin/edit/assist/assist_core.dart';
diff --git a/pkg/analysis_server/lib/src/edit/fix/dartfix_info.dart b/pkg/analysis_server/lib/src/edit/fix/dartfix_info.dart
index 0fe5aba..6335d65 100644
--- a/pkg/analysis_server/lib/src/edit/fix/dartfix_info.dart
+++ b/pkg/analysis_server/lib/src/edit/fix/dartfix_info.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
+
 import 'package:analysis_server/protocol/protocol_generated.dart'
     show DartFix, EditDartfixParams;
 import 'package:analysis_server/src/edit/edit_dartfix.dart';
diff --git a/pkg/analysis_server/lib/src/edit/fix/dartfix_listener.dart b/pkg/analysis_server/lib/src/edit/fix/dartfix_listener.dart
index bb4643f..556cc38 100644
--- a/pkg/analysis_server/lib/src/edit/fix/dartfix_listener.dart
+++ b/pkg/analysis_server/lib/src/edit/fix/dartfix_listener.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
+
 import 'package:analysis_server/protocol/protocol_generated.dart';
 import 'package:analysis_server/src/analysis_server.dart';
 import 'package:analyzer/dart/analysis/results.dart';
@@ -79,9 +81,16 @@
   /// Return the [Location] representing the specified offset and length
   /// in the given compilation unit.
   Location locationFor(ResolvedUnitResult result, int offset, int length) {
-    final locInfo = result.unit.lineInfo.getLocation(offset);
-    final location = Location(
-        result.path, offset, length, locInfo.lineNumber, locInfo.columnNumber);
-    return location;
+    var lineInfo = result.unit.lineInfo;
+    var startLocation = lineInfo.getLocation(offset);
+    var endLocation = lineInfo.getLocation(offset + length);
+    return Location(
+        result.path,
+        offset,
+        length,
+        startLocation.lineNumber,
+        startLocation.columnNumber,
+        endLocation.lineNumber,
+        endLocation.columnNumber);
   }
 }
diff --git a/pkg/analysis_server/lib/src/edit/fix/dartfix_registrar.dart b/pkg/analysis_server/lib/src/edit/fix/dartfix_registrar.dart
index 07652c0..f1c8b44 100644
--- a/pkg/analysis_server/lib/src/edit/fix/dartfix_registrar.dart
+++ b/pkg/analysis_server/lib/src/edit/fix/dartfix_registrar.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
+
 import 'package:analysis_server/src/edit/fix/dartfix_info.dart';
 import 'package:analysis_server/src/edit/fix/fix_code_task.dart';
 import 'package:analysis_server/src/edit/fix/fix_error_task.dart';
diff --git a/pkg/analysis_server/lib/src/edit/fix/fix_code_task.dart b/pkg/analysis_server/lib/src/edit/fix/fix_code_task.dart
index a4243a9..cca1834 100644
--- a/pkg/analysis_server/lib/src/edit/fix/fix_code_task.dart
+++ b/pkg/analysis_server/lib/src/edit/fix/fix_code_task.dart
@@ -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
+
 import 'dart:math' show max;
 
 import 'package:analysis_server/src/edit/edit_dartfix.dart';
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 b78a73b..5f7ec39 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
@@ -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
+
 import 'package:analysis_server/protocol/protocol_generated.dart';
 import 'package:analysis_server/src/edit/edit_dartfix.dart';
 import 'package:analysis_server/src/edit/fix/dartfix_listener.dart';
@@ -60,7 +62,7 @@
     } else {
       // TODO(danrubel): Determine why the fix could not be applied
       // and report that in the description.
-      listener.addRecommendation('Could not fix "${error.message}"', location);
+      listener.addRecommendation("Couldn't fix \"${error.message}\"", location);
     }
   }
 
diff --git a/pkg/analysis_server/lib/src/edit/fix/fix_lint_task.dart b/pkg/analysis_server/lib/src/edit/fix/fix_lint_task.dart
index 2aac75e..d7564a9 100644
--- a/pkg/analysis_server/lib/src/edit/fix/fix_lint_task.dart
+++ b/pkg/analysis_server/lib/src/edit/fix/fix_lint_task.dart
@@ -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
+
 import 'package:analysis_server/src/edit/edit_dartfix.dart';
 import 'package:analysis_server/src/edit/fix/dartfix_listener.dart';
 import 'package:analysis_server/src/edit/fix/fix_error_task.dart';
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 870c33f..f9ef2a5 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
@@ -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
+
 import 'package:analysis_server/protocol/protocol_generated.dart';
 import 'package:analysis_server/src/edit/fix/dartfix_listener.dart';
 import 'package:analysis_server/src/edit/fix/dartfix_registrar.dart';
@@ -54,7 +56,7 @@
           // TODO(danrubel): If assists is empty, then determine why
           // assist could not be performed and report that in the description.
           listener.addRecommendation(
-              'Could not convert ${elem.displayName} to a mixin'
+              "Couldn't convert ${elem.displayName} to a mixin"
               ' because the class contains a constructor',
               location);
         }
diff --git a/pkg/analysis_server/lib/src/flutter/flutter_domain.dart b/pkg/analysis_server/lib/src/flutter/flutter_domain.dart
index 1a5f819..6996ece 100644
--- a/pkg/analysis_server/lib/src/flutter/flutter_domain.dart
+++ b/pkg/analysis_server/lib/src/flutter/flutter_domain.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
+
 import 'package:analysis_server/protocol/protocol_constants.dart';
 import 'package:analysis_server/src/analysis_server.dart';
 import 'package:analysis_server/src/domain_abstract.dart';
diff --git a/pkg/analysis_server/lib/src/flutter/flutter_notifications.dart b/pkg/analysis_server/lib/src/flutter/flutter_notifications.dart
index 74085faa..a18cb7d 100644
--- a/pkg/analysis_server/lib/src/flutter/flutter_notifications.dart
+++ b/pkg/analysis_server/lib/src/flutter/flutter_notifications.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
+
 import 'package:analysis_server/src/analysis_server.dart';
 import 'package:analysis_server/src/flutter/flutter_outline_computer.dart';
 import 'package:analysis_server/src/protocol_server.dart' as protocol;
diff --git a/pkg/analysis_server/lib/src/flutter/flutter_outline_computer.dart b/pkg/analysis_server/lib/src/flutter/flutter_outline_computer.dart
index b2540c6..5f79173 100644
--- a/pkg/analysis_server/lib/src/flutter/flutter_outline_computer.dart
+++ b/pkg/analysis_server/lib/src/flutter/flutter_outline_computer.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
+
 import 'package:analysis_server/src/computer/computer_outline.dart';
 import 'package:analysis_server/src/protocol_server.dart' as protocol;
 import 'package:analysis_server/src/utilities/flutter.dart';
@@ -153,7 +155,31 @@
           childrenExpression = argument;
         }
 
-        if (isWidgetArgument) {
+        void addChildrenFrom(CollectionElement element) {
+          if (element is ConditionalExpression) {
+            addChildrenFrom(element.thenExpression);
+            addChildrenFrom(element.elseExpression);
+          } else if (element is Expression) {
+            var child = _createOutline(element, true);
+            if (child != null) {
+              children.add(child);
+            }
+          } else if (element is IfElement) {
+            addChildrenFrom(element.thenElement);
+            addChildrenFrom(element.elseElement);
+          } else if (element is ForElement) {
+            addChildrenFrom(element.body);
+          } else if (element is SpreadElement) {
+            // Ignored. It's possible that we might be able to extract
+            // some information from some spread expressions, but it seems
+            // unlikely enough that we're not handling it at the moment.
+          }
+        }
+
+        if (isWidgetArgument && childrenExpression is ConditionalExpression) {
+          addChildrenFrom(childrenExpression.thenExpression);
+          addChildrenFrom(childrenExpression.elseExpression);
+        } else if (isWidgetArgument) {
           var child = _createOutline(childrenExpression, true);
           if (child != null) {
             child.parentAssociationLabel = parentAssociationLabel;
@@ -162,24 +188,6 @@
         } else if (isWidgetListArgument) {
           if (childrenExpression is ListLiteral) {
             for (var element in childrenExpression.elements) {
-              void addChildrenFrom(CollectionElement element) {
-                if (element is Expression) {
-                  var child = _createOutline(element, true);
-                  if (child != null) {
-                    children.add(child);
-                  }
-                } else if (element is IfElement) {
-                  addChildrenFrom(element.thenElement);
-                  addChildrenFrom(element.elseElement);
-                } else if (element is ForElement) {
-                  addChildrenFrom(element.body);
-                } else if (element is SpreadElement) {
-                  // Ignored. It's possible that we might be able to extract
-                  // some information from some spread expressions, but it seems
-                  // unlikely enough that we're not handling it at the moment.
-                }
-              }
-
               addChildrenFrom(element);
             }
           }
diff --git a/pkg/analysis_server/lib/src/lsp/channel/lsp_byte_stream_channel.dart b/pkg/analysis_server/lib/src/lsp/channel/lsp_byte_stream_channel.dart
index acd9c2e..993ab3a 100644
--- a/pkg/analysis_server/lib/src/lsp/channel/lsp_byte_stream_channel.dart
+++ b/pkg/analysis_server/lib/src/lsp/channel/lsp_byte_stream_channel.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
+
 import 'dart:async';
 import 'dart:convert';
 import 'dart:io';
diff --git a/pkg/analysis_server/lib/src/lsp/channel/lsp_channel.dart b/pkg/analysis_server/lib/src/lsp/channel/lsp_channel.dart
index 8d488b6..5163e84 100644
--- a/pkg/analysis_server/lib/src/lsp/channel/lsp_channel.dart
+++ b/pkg/analysis_server/lib/src/lsp/channel/lsp_channel.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
+
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:analysis_server/src/lsp/lsp_analysis_server.dart';
 
diff --git a/pkg/analysis_server/lib/src/lsp/client_capabilities.dart b/pkg/analysis_server/lib/src/lsp/client_capabilities.dart
index 2c16de4..2a2039a 100644
--- a/pkg/analysis_server/lib/src/lsp/client_capabilities.dart
+++ b/pkg/analysis_server/lib/src/lsp/client_capabilities.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
+
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 
 /// Wraps the client (editor) capabilities to improve performance.
@@ -78,6 +80,7 @@
   final Set<SymbolKind> workspaceSymbolKinds;
   final Set<CompletionItemKind> completionItemKinds;
   final Set<InsertTextMode> completionInsertTextModes;
+  final bool experimentalSnippetTextEdit;
 
   LspClientCapabilities(this.raw)
       : applyEdit = raw?.workspace?.applyEdit ?? false,
@@ -125,7 +128,10 @@
         workDoneProgress = raw.window?.workDoneProgress ?? false,
         workspaceSymbolKinds = _listToSet(
             raw?.workspace?.symbol?.symbolKind?.valueSet,
-            defaults: defaultSupportedSymbolKinds);
+            defaults: defaultSupportedSymbolKinds),
+        experimentalSnippetTextEdit =
+            raw.experimental is Map<String, dynamic> &&
+                raw.experimental['snippetTextEdit'] == true;
 
   static Set<MarkupKind> _completionDocumentationFormats(
       ClientCapabilities raw) {
diff --git a/pkg/analysis_server/lib/src/lsp/constants.dart b/pkg/analysis_server/lib/src/lsp/constants.dart
index 952a5c5..d04c276 100644
--- a/pkg/analysis_server/lib/src/lsp/constants.dart
+++ b/pkg/analysis_server/lib/src/lsp/constants.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
+
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:analysis_server/lsp_protocol/protocol_special.dart';
 
diff --git a/pkg/analysis_server/lib/src/lsp/dartdoc.dart b/pkg/analysis_server/lib/src/lsp/dartdoc.dart
index ee6d6c7..fb84180 100644
--- a/pkg/analysis_server/lib/src/lsp/dartdoc.dart
+++ b/pkg/analysis_server/lib/src/lsp/dartdoc.dart
@@ -6,7 +6,7 @@
 final _dartdocDirectives =
     RegExp(r'(\n *{@.*?}$)|(^{@.*?}\n)', multiLine: true);
 
-String cleanDartdoc(String doc) {
+String? cleanDartdoc(String? doc) {
   if (doc == null) {
     return null;
   }
@@ -17,7 +17,7 @@
   // docs contain.
   doc = doc.replaceAllMapped(
     _dartdocCodeBlockSections,
-    (match) => match.group(1),
+    (match) => match.group(1)!,
   );
 
   return doc;
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/commands/organize_imports.dart b/pkg/analysis_server/lib/src/lsp/handlers/commands/organize_imports.dart
index c1c00de..998a39e 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/commands/organize_imports.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/commands/organize_imports.dart
@@ -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
+
 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';
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 6ac4547..fccceba 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
@@ -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
+
 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';
@@ -87,7 +89,7 @@
             return fileModifiedError;
           }
 
-          final edit = createWorkspaceEdit(server, change.edits);
+          final edit = createWorkspaceEdit(server, change);
           return await sendWorkspaceEditToClient(edit);
         } on InconsistentAnalysisException {
           return fileModifiedError;
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/commands/send_workspace_edit.dart b/pkg/analysis_server/lib/src/lsp/handlers/commands/send_workspace_edit.dart
index c4eda52..1f81768 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/commands/send_workspace_edit.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/commands/send_workspace_edit.dart
@@ -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
+
 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';
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/commands/simple_edit_handler.dart b/pkg/analysis_server/lib/src/lsp/handlers/commands/simple_edit_handler.dart
index c8fa759..0b3a4ef 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/commands/simple_edit_handler.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/commands/simple_edit_handler.dart
@@ -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
+
 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';
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/commands/sort_members.dart b/pkg/analysis_server/lib/src/lsp/handlers/commands/sort_members.dart
index ca10fa4..dd7b2d0 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/commands/sort_members.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/commands/sort_members.dart
@@ -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
+
 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';
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/custom/handler_diagnostic_server.dart b/pkg/analysis_server/lib/src/lsp/handlers/custom/handler_diagnostic_server.dart
index 66f95f6..8c8d812 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/custom/handler_diagnostic_server.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/custom/handler_diagnostic_server.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/custom/handler_reanalyze.dart b/pkg/analysis_server/lib/src/lsp/handlers/custom/handler_reanalyze.dart
index 0c2cde4..cd62bcc 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/custom/handler_reanalyze.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/custom/handler_reanalyze.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/custom/handler_super.dart b/pkg/analysis_server/lib/src/lsp/handlers/custom/handler_super.dart
index 9ddba98..50f0c5d 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/custom/handler_super.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/custom/handler_super.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_cancel_request.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_cancel_request.dart
index 82008a9..1bdc3db 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_cancel_request.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_cancel_request.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
+
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:analysis_server/lsp_protocol/protocol_special.dart';
 import 'package:analysis_server/src/lsp/handlers/handlers.dart';
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_change_workspace_folders.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_change_workspace_folders.dart
index c25595d..857fcb3 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_change_workspace_folders.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_change_workspace_folders.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
+
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:analysis_server/lsp_protocol/protocol_special.dart';
 import 'package:analysis_server/src/lsp/handlers/handlers.dart';
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 f51367f..219138b 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
@@ -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
+
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:analysis_server/lsp_protocol/protocol_special.dart';
 import 'package:analysis_server/plugin/edit/assist/assist_core.dart';
@@ -143,7 +145,7 @@
       title: assist.change.message,
       kind: toCodeActionKind(assist.change.id, CodeActionKind.Refactor),
       diagnostics: const [],
-      edit: createWorkspaceEdit(server, assist.change.edits),
+      edit: createWorkspaceEdit(server, assist.change),
     );
   }
 
@@ -156,7 +158,7 @@
       title: fix.change.message,
       kind: toCodeActionKind(fix.change.id, CodeActionKind.QuickFix),
       diagnostics: [diagnostic],
-      edit: createWorkspaceEdit(server, fix.change.edits),
+      edit: createWorkspaceEdit(server, fix.change),
     );
   }
 
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 f6671c6..13a5890 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_completion.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_completion.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
+
 import 'dart:math' as math;
 
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
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 3c3ea2c..95e8259 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,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
+
 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';
@@ -146,7 +148,8 @@
         // a command that the client will call to apply those edits later.
         Command command;
         if (otherFilesChanges.isNotEmpty) {
-          final workspaceEdit = createWorkspaceEdit(server, otherFilesChanges);
+          final workspaceEdit =
+              createPlainWorkspaceEdit(server, otherFilesChanges);
           command = Command(
               title: 'Add import',
               command: Commands.sendWorkspaceEdit,
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_definition.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_definition.dart
index e3599b6..5b52c33 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_definition.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_definition.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
+
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:analysis_server/lsp_protocol/protocol_special.dart';
 import 'package:analysis_server/protocol/protocol_generated.dart'
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_document_highlights.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_document_highlights.dart
index 8044281..9573acc 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_document_highlights.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_document_highlights.dart
@@ -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
+
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:analysis_server/lsp_protocol/protocol_special.dart';
 import 'package:analysis_server/src/domains/analysis/occurrences.dart';
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_document_symbols.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_document_symbols.dart
index f8ad0d6..b4b6f14 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_document_symbols.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_document_symbols.dart
@@ -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
+
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:analysis_server/lsp_protocol/protocol_special.dart';
 import 'package:analysis_server/src/computer/computer_outline.dart';
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 43d877e..40e0e03 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
@@ -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
+
 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';
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_exit.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_exit.dart
index 82b3f07..bb33c81 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_exit.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_exit.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
+
 import 'dart:io';
 
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_folding.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_folding.dart
index 988b719..cda2b35 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_folding.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_folding.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
+
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:analysis_server/lsp_protocol/protocol_special.dart';
 import 'package:analysis_server/src/computer/computer_folding.dart';
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 d34bcea..cc07266 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
@@ -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
+
 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';
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
index 3c6183d..bc83804 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_format_range.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_format_range.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
+
 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';
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 554ed01..eefcd07 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_formatting.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_formatting.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_hover.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_hover.dart
index 4e57b46..8c82497 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_hover.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_hover.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
+
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:analysis_server/lsp_protocol/protocol_special.dart';
 import 'package:analysis_server/protocol/protocol_generated.dart';
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_implementation.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_implementation.dart
index 17a3b28..822398c 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_implementation.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_implementation.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
+
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:analysis_server/lsp_protocol/protocol_special.dart';
 import 'package:analysis_server/protocol/protocol_generated.dart';
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 9174fb8..091f1e0 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_initialize.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_initialize.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
+
 import 'dart:io';
 
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_initialized.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_initialized.dart
index b42d11f..462e933 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_initialized.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_initialized.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
+
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:analysis_server/lsp_protocol/protocol_special.dart';
 import 'package:analysis_server/src/lsp/handlers/handler_states.dart';
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_references.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_references.dart
index 4dc81df..31f5872 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_references.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_references.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
+
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:analysis_server/lsp_protocol/protocol_special.dart';
 import 'package:analysis_server/src/lsp/handlers/handlers.dart';
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_reject.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_reject.dart
index a1f42ff..e841a61 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_reject.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_reject.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
+
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:analysis_server/lsp_protocol/protocol_special.dart';
 import 'package:analysis_server/src/lsp/handlers/handlers.dart';
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 eae5c8c..20f59c0 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_rename.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_rename.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
+
 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';
@@ -187,7 +189,7 @@
         return fileModifiedError;
       }
 
-      final workspaceEdit = createWorkspaceEdit(server, change.edits);
+      final workspaceEdit = createWorkspaceEdit(server, change);
       return success(workspaceEdit);
     });
   }
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_semantic_tokens.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_semantic_tokens.dart
index ad40077..61e411e 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_semantic_tokens.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_semantic_tokens.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
+
 import 'dart:async';
 
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_shutdown.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_shutdown.dart
index d591480..9746f3a 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_shutdown.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_shutdown.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
+
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:analysis_server/lsp_protocol/protocol_special.dart';
 import 'package:analysis_server/src/lsp/handlers/handler_states.dart';
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_signature_help.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_signature_help.dart
index d01e33d..5d97030 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_signature_help.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_signature_help.dart
@@ -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
+
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:analysis_server/lsp_protocol/protocol_special.dart';
 import 'package:analysis_server/src/computer/computer_signature.dart';
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 c1298e5..d1194ee 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_states.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_states.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
+
 import 'dart:async';
 
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_text_document_changes.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_text_document_changes.dart
index de9cb07..f703d18 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_text_document_changes.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_text_document_changes.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_will_rename_files.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_will_rename_files.dart
index 2beb369..c256d6d 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_will_rename_files.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_will_rename_files.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
+
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:analysis_server/lsp_protocol/protocol_special.dart';
 import 'package:analysis_server/src/lsp/handlers/handlers.dart';
@@ -53,7 +55,7 @@
     }
 
     final change = await refactoring.createChange();
-    final edit = createWorkspaceEdit(server, change.edits);
+    final edit = createWorkspaceEdit(server, change);
 
     return success(edit);
   }
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_workspace_configuration.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_workspace_configuration.dart
index 8551a6d..3be46d8 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_workspace_configuration.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_workspace_configuration.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
+
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:analysis_server/lsp_protocol/protocol_special.dart';
 import 'package:analysis_server/src/lsp/handlers/handlers.dart';
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_workspace_symbols.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_workspace_symbols.dart
index ef781d1..37f455b 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_workspace_symbols.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_workspace_symbols.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
+
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:analysis_server/lsp_protocol/protocol_special.dart';
 import 'package:analysis_server/src/lsp/handlers/handlers.dart';
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handlers.dart b/pkg/analysis_server/lib/src/lsp/handlers/handlers.dart
index 0835da5..3f5def6 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handlers.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handlers.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
+
 import 'dart:async';
 
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
diff --git a/pkg/analysis_server/lib/src/lsp/json_parsing.dart b/pkg/analysis_server/lib/src/lsp/json_parsing.dart
index 148a9ca..f396dde 100644
--- a/pkg/analysis_server/lib/src/lsp/json_parsing.dart
+++ b/pkg/analysis_server/lib/src/lsp/json_parsing.dart
@@ -16,13 +16,13 @@
   /// being validated.
   final ListQueue<String> path = ListQueue<String>();
 
-  LspJsonReporter([String initialField]) {
+  LspJsonReporter([String? initialField]) {
     if (initialField != null) {
       path.add(initialField);
     }
   }
 
-  /// Pops the last field off the stack to become the current gield.
+  /// Pops the last field off the stack to become the current field.
   void pop() => path.removeLast();
 
   /// Pushes the current field onto a stack to allow reporting errors in child
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 19afc27..afb577f 100644
--- a/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart
+++ b/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.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
+
 import 'dart:async';
 
 import 'package:analysis_server/lsp_protocol/protocol_custom_generated.dart';
@@ -137,6 +139,8 @@
     InstrumentationService instrumentationService, {
     http.Client httpClient,
     DiagnosticServer diagnosticServer,
+    // Disable to avoid using this in unit tests.
+    bool enableBazelWatcher = false,
   }) : super(
           options,
           sdkManager,
@@ -146,6 +150,7 @@
           instrumentationService,
           httpClient,
           LspNotificationManager(channel, baseResourceProvider.pathContext),
+          enableBazelWatcher: enableBazelWatcher,
         ) {
     notificationManager.server = this;
     messageHandler = UninitializedStateMessageHandler(this);
diff --git a/pkg/analysis_server/lib/src/lsp/lsp_packet_transformer.dart b/pkg/analysis_server/lib/src/lsp/lsp_packet_transformer.dart
index 8f5021f..27c652b 100644
--- a/pkg/analysis_server/lib/src/lsp/lsp_packet_transformer.dart
+++ b/pkg/analysis_server/lib/src/lsp/lsp_packet_transformer.dart
@@ -5,6 +5,9 @@
 import 'dart:async';
 import 'dart:convert';
 
+import 'package:analysis_server/src/utilities/stream.dart';
+import 'package:collection/collection.dart';
+
 class InvalidEncodingError {
   final String headers;
   InvalidEncodingError(this.headers);
@@ -17,7 +20,7 @@
 class LspHeaders {
   final String rawHeaders;
   final int contentLength;
-  final String encoding;
+  final String? encoding;
   LspHeaders(this.rawHeaders, this.contentLength, this.encoding);
 }
 
@@ -33,44 +36,46 @@
 class LspPacketTransformer extends StreamTransformerBase<List<int>, String> {
   @override
   Stream<String> bind(Stream<List<int>> stream) {
-    StreamSubscription<int> input;
-    StreamController<String> _output;
+    LspHeaders? headersState;
     final buffer = <int>[];
-    var isParsingHeaders = true;
-    LspHeaders headers;
-    _output = StreamController<String>(
-      onListen: () {
-        input = stream.expand((b) => b).listen(
+    var controller = MoreTypedStreamController<String,
+        _LspPacketTransformerListenData, _LspPacketTransformerPauseData>(
+      onListen: (controller) {
+        var input = stream.expand((b) => b).listen(
           (codeUnit) {
             buffer.add(codeUnit);
-            if (isParsingHeaders && _endsWithCrLfCrLf(buffer)) {
-              headers = _parseHeaders(buffer);
+            var headers = headersState;
+            if (headers == null && _endsWithCrLfCrLf(buffer)) {
+              headersState = _parseHeaders(buffer);
               buffer.clear();
-              isParsingHeaders = false;
-            } else if (!isParsingHeaders &&
+            } else if (headers != null &&
                 buffer.length >= headers.contentLength) {
               // UTF-8 is the default - and only supported - encoding for LSP.
               // The string 'utf8' is valid since it was published in the original spec.
               // Any other encodings should be rejected with an error.
               if ([null, 'utf-8', 'utf8']
                   .contains(headers.encoding?.toLowerCase())) {
-                _output.add(utf8.decode(buffer));
+                controller.add(utf8.decode(buffer));
               } else {
-                _output.addError(InvalidEncodingError(headers.rawHeaders));
+                controller.addError(InvalidEncodingError(headers.rawHeaders));
               }
               buffer.clear();
-              isParsingHeaders = true;
+              headersState = null;
             }
           },
-          onError: _output.addError,
-          onDone: _output.close,
+          onError: controller.addError,
+          onDone: controller.close,
         );
+        return _LspPacketTransformerListenData(input);
       },
-      onPause: () => input.pause(),
-      onResume: () => input.resume(),
-      onCancel: () => input.cancel(),
+      onPause: (listenData) {
+        listenData.input.pause();
+        return _LspPacketTransformerPauseData();
+      },
+      onResume: (listenData, pauseData) => listenData.input.resume(),
+      onCancel: (listenData) => listenData.input.cancel(),
     );
-    return _output.stream;
+    return controller.controller.stream;
   }
 
   /// Whether [buffer] ends in '\r\n\r\n'.
@@ -83,13 +88,13 @@
         buffer[l - 4] == 13;
   }
 
-  static String _extractEncoding(String header) {
+  static String? _extractEncoding(String? header) {
     final charset = header
         ?.split(';')
-        ?.map((s) => s.trim().toLowerCase())
-        ?.firstWhere((s) => s.startsWith('charset='), orElse: () => null);
+        .map((s) => s.trim().toLowerCase())
+        .firstWhereOrNull((s) => s.startsWith('charset='));
 
-    return charset == null ? null : charset.split('=')[1];
+    return charset?.split('=')[1];
   }
 
   /// Decodes [buffer] into a String and returns the 'Content-Length' header value.
@@ -100,9 +105,19 @@
     final lengthHeader =
         headers.firstWhere((h) => h.startsWith('Content-Length'));
     final length = lengthHeader.split(':').last.trim();
-    final contentTypeHeader = headers
-        .firstWhere((h) => h.startsWith('Content-Type'), orElse: () => null);
+    final contentTypeHeader =
+        headers.firstWhereOrNull((h) => h.startsWith('Content-Type'));
     final encoding = _extractEncoding(contentTypeHeader);
     return LspHeaders(asString, int.parse(length), encoding);
   }
 }
+
+/// The data class for [StreamController.onListen].
+class _LspPacketTransformerListenData {
+  final StreamSubscription<int> input;
+
+  _LspPacketTransformerListenData(this.input);
+}
+
+/// The marker class for [StreamController.onPause].
+class _LspPacketTransformerPauseData {}
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 832f432..d567d37 100644
--- a/pkg/analysis_server/lib/src/lsp/lsp_socket_server.dart
+++ b/pkg/analysis_server/lib/src/lsp/lsp_socket_server.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
+
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:analysis_server/lsp_protocol/protocol_special.dart';
 import 'package:analysis_server/src/analysis_server.dart';
@@ -68,12 +70,14 @@
         stateLocation: analysisServerOptions.cacheFolder);
 
     analysisServer = LspAnalysisServer(
-        serverChannel,
-        resourceProvider,
-        analysisServerOptions,
-        sdkManager,
-        CrashReportingAttachmentsBuilder.empty,
-        instrumentationService,
-        diagnosticServer: diagnosticServer);
+      serverChannel,
+      resourceProvider,
+      analysisServerOptions,
+      sdkManager,
+      CrashReportingAttachmentsBuilder.empty,
+      instrumentationService,
+      diagnosticServer: diagnosticServer,
+      enableBazelWatcher: true,
+    );
   }
 }
diff --git a/pkg/analysis_server/lib/src/lsp/mapping.dart b/pkg/analysis_server/lib/src/lsp/mapping.dart
index 9e59ec6..1a75652 100644
--- a/pkg/analysis_server/lib/src/lsp/mapping.dart
+++ b/pkg/analysis_server/lib/src/lsp/mapping.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
+
 import 'dart:math';
 
 import 'package:analysis_server/lsp_protocol/protocol_custom_generated.dart'
@@ -108,10 +110,12 @@
   return output.join('');
 }
 
+/// Creates a [lsp.WorkspaceEdit] from simple [server.SourceFileEdit]s.
+///
 /// Note: This code will fetch the version of each document being modified so
 /// it's important to call this immediately after computing edits to ensure
 /// the document is not modified before the version number is read.
-lsp.WorkspaceEdit createWorkspaceEdit(
+lsp.WorkspaceEdit createPlainWorkspaceEdit(
     lsp.LspAnalysisServer server, List<server.SourceFileEdit> edits) {
   return toWorkspaceEdit(
       server.clientCapabilities,
@@ -126,6 +130,52 @@
           .toList());
 }
 
+/// Creates a [lsp.WorkspaceEdit] from a [server.SourceChange] that can include
+/// experimental [server.SnippetTextEdit]s if the client has indicated support
+/// for these in the experimental section of their client capabilities.
+///
+/// Note: This code will fetch the version of each document being modified so
+/// it's important to call this immediately after computing edits to ensure
+/// the document is not modified before the version number is read.
+lsp.WorkspaceEdit createWorkspaceEdit(
+    lsp.LspAnalysisServer server, server.SourceChange change) {
+  // In order to return snippets, we must ensure we are only modifying a single
+  // existing file with a single edit and that there is a linked edit group with
+  // only one position and no suggestions.
+  if (!server.clientCapabilities.experimentalSnippetTextEdit ||
+      change.edits.length != 1 ||
+      change.edits.first.fileStamp == -1 || // new file
+      change.edits.first.edits.length != 1 ||
+      change.linkedEditGroups.isEmpty ||
+      change.linkedEditGroups.first.positions.length != 1 ||
+      change.linkedEditGroups.first.suggestions.isNotEmpty) {
+    return createPlainWorkspaceEdit(server, change.edits);
+  }
+
+  // Additionally, the selection must fall within the edit offset.
+  final edit = change.edits.first.edits.first;
+  final selectionOffset = change.linkedEditGroups.first.positions.first.offset;
+  final selectionLength = change.linkedEditGroups.first.length;
+
+  if (selectionOffset < edit.offset ||
+      selectionOffset + selectionLength > edit.offset + edit.length) {
+    return createPlainWorkspaceEdit(server, change.edits);
+  }
+
+  return toWorkspaceEdit(
+      server.clientCapabilities,
+      change.edits
+          .map((e) => FileEditInformation(
+                server.getVersionedDocumentIdentifier(e.file),
+                server.getLineInfo(e.file),
+                e.edits,
+                selectionOffsetRelative: selectionOffset - edit.offset,
+                selectionLength: selectionLength,
+                newFile: e.fileStamp == -1,
+              ))
+          .toList());
+}
+
 lsp.CompletionItemKind declarationKindToCompletionItemKind(
   Set<lsp.CompletionItemKind> supportedCompletionKinds,
   dec.DeclarationKind kind,
@@ -1224,6 +1274,21 @@
   );
 }
 
+lsp.SnippetTextEdit toSnippetTextEdit(
+    LspClientCapabilities capabilities,
+    server.LineInfo lineInfo,
+    server.SourceEdit edit,
+    int selectionOffsetRelative,
+    int selectionLength) {
+  assert(selectionOffsetRelative != null);
+  return lsp.SnippetTextEdit(
+    insertTextFormat: lsp.InsertTextFormat.Snippet,
+    range: toRange(lineInfo, edit.offset, edit.length),
+    newText: buildSnippetStringWithTabStops(
+        edit.replacement, [selectionOffsetRelative, selectionLength ?? 0]),
+  );
+}
+
 ErrorOr<server.SourceRange> toSourceRange(
     server.LineInfo lineInfo, Range range) {
   if (range == null) {
@@ -1247,14 +1312,33 @@
   return success(server.SourceRange(startOffset, endOffset - startOffset));
 }
 
-lsp.TextDocumentEdit toTextDocumentEdit(FileEditInformation edit) {
+lsp.TextDocumentEdit toTextDocumentEdit(
+    LspClientCapabilities capabilities, FileEditInformation edit) {
   return lsp.TextDocumentEdit(
-    textDocument: edit.doc,
-    edits: edit.edits
-        .map((e) => Either2<lsp.TextEdit, lsp.AnnotatedTextEdit>.t1(
-            toTextEdit(edit.lineInfo, e)))
-        .toList(),
-  );
+      textDocument: edit.doc,
+      edits: edit.edits
+          .map((e) => toTextDocumentEditEdit(capabilities, edit.lineInfo, e,
+              selectionOffsetRelative: edit.selectionOffsetRelative,
+              selectionLength: edit.selectionLength))
+          .toList());
+}
+
+Either3<lsp.SnippetTextEdit, lsp.AnnotatedTextEdit, lsp.TextEdit>
+    toTextDocumentEditEdit(
+  LspClientCapabilities capabilities,
+  server.LineInfo lineInfo,
+  server.SourceEdit edit, {
+  int selectionOffsetRelative,
+  int selectionLength,
+}) {
+  if (!capabilities.experimentalSnippetTextEdit ||
+      selectionOffsetRelative == null) {
+    return Either3<lsp.SnippetTextEdit, lsp.AnnotatedTextEdit, lsp.TextEdit>.t3(
+        toTextEdit(lineInfo, edit));
+  }
+  return Either3<lsp.SnippetTextEdit, lsp.AnnotatedTextEdit, lsp.TextEdit>.t1(
+      toSnippetTextEdit(capabilities, lineInfo, edit, selectionOffsetRelative,
+          selectionLength));
 }
 
 lsp.TextEdit toTextEdit(server.LineInfo lineInfo, server.SourceEdit edit) {
@@ -1286,7 +1370,7 @@
         changes.add(createUnion);
       }
 
-      final textDocEdit = toTextDocumentEdit(edit);
+      final textDocEdit = toTextDocumentEdit(capabilities, edit);
       final textDocEditUnion = Either4<lsp.TextDocumentEdit, lsp.CreateFile,
           lsp.RenameFile, lsp.DeleteFile>.t1(textDocEdit);
       changes.add(textDocEditUnion);
diff --git a/pkg/analysis_server/lib/src/lsp/notification_manager.dart b/pkg/analysis_server/lib/src/lsp/notification_manager.dart
index 7752a79..e6506bd 100644
--- a/pkg/analysis_server/lib/src/lsp/notification_manager.dart
+++ b/pkg/analysis_server/lib/src/lsp/notification_manager.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
+
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:analysis_server/lsp_protocol/protocol_special.dart';
 import 'package:analysis_server/src/lsp/channel/lsp_channel.dart';
diff --git a/pkg/analysis_server/lib/src/lsp/progress.dart b/pkg/analysis_server/lib/src/lsp/progress.dart
index 45c040a..6b87f74 100644
--- a/pkg/analysis_server/lib/src/lsp/progress.dart
+++ b/pkg/analysis_server/lib/src/lsp/progress.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
+
 import 'dart:async';
 import 'dart:math';
 
diff --git a/pkg/analysis_server/lib/src/lsp/semantic_tokens/encoder.dart b/pkg/analysis_server/lib/src/lsp/semantic_tokens/encoder.dart
index 4ee6f99..a3de7dd 100644
--- a/pkg/analysis_server/lib/src/lsp/semantic_tokens/encoder.dart
+++ b/pkg/analysis_server/lib/src/lsp/semantic_tokens/encoder.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
+
 import 'dart:collection';
 import 'dart:math' as math;
 
diff --git a/pkg/analysis_server/lib/src/lsp/semantic_tokens/legend.dart b/pkg/analysis_server/lib/src/lsp/semantic_tokens/legend.dart
index ef2d8c4..2b7c3e4 100644
--- a/pkg/analysis_server/lib/src/lsp/semantic_tokens/legend.dart
+++ b/pkg/analysis_server/lib/src/lsp/semantic_tokens/legend.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
+
 import 'dart:math' as math;
 
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
diff --git a/pkg/analysis_server/lib/src/lsp/semantic_tokens/mapping.dart b/pkg/analysis_server/lib/src/lsp/semantic_tokens/mapping.dart
index 7405b0e..34c7909 100644
--- a/pkg/analysis_server/lib/src/lsp/semantic_tokens/mapping.dart
+++ b/pkg/analysis_server/lib/src/lsp/semantic_tokens/mapping.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
+
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:analysis_server/src/lsp/constants.dart';
 import 'package:analysis_server/src/lsp/semantic_tokens/legend.dart';
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 808446a..72b8dbc 100644
--- a/pkg/analysis_server/lib/src/lsp/server_capabilities_computer.dart
+++ b/pkg/analysis_server/lib/src/lsp/server_capabilities_computer.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
+
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:analysis_server/lsp_protocol/protocol_special.dart';
 import 'package:analysis_server/src/lsp/client_capabilities.dart';
diff --git a/pkg/analysis_server/lib/src/lsp/source_edits.dart b/pkg/analysis_server/lib/src/lsp/source_edits.dart
index e1cc013..a1004f1 100644
--- a/pkg/analysis_server/lib/src/lsp/source_edits.dart
+++ b/pkg/analysis_server/lib/src/lsp/source_edits.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
+
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:analysis_server/lsp_protocol/protocol_special.dart';
 import 'package:analysis_server/src/lsp/mapping.dart';
@@ -307,6 +309,12 @@
   final List<server.SourceEdit> edits;
   final bool newFile;
 
+  /// The selection offset, relative to the edit.
+  final int selectionOffsetRelative;
+  final int selectionLength;
+
   FileEditInformation(this.doc, this.lineInfo, this.edits,
-      {this.newFile = false});
+      {this.newFile = false,
+      this.selectionOffsetRelative,
+      this.selectionLength});
 }
diff --git a/pkg/analysis_server/lib/src/operation/operation_analysis.dart b/pkg/analysis_server/lib/src/operation/operation_analysis.dart
index aa6443e..f612320 100644
--- a/pkg/analysis_server/lib/src/operation/operation_analysis.dart
+++ b/pkg/analysis_server/lib/src/operation/operation_analysis.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
+
 import 'package:analysis_server/src/analysis_server.dart';
 import 'package:analysis_server/src/computer/computer_closingLabels.dart';
 import 'package:analysis_server/src/computer/computer_folding.dart';
diff --git a/pkg/analysis_server/lib/src/plugin/notification_manager.dart b/pkg/analysis_server/lib/src/plugin/notification_manager.dart
index 5b3eef8..6ebbf40 100644
--- a/pkg/analysis_server/lib/src/plugin/notification_manager.dart
+++ b/pkg/analysis_server/lib/src/plugin/notification_manager.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
+
 import 'dart:collection';
 
 import 'package:analysis_server/protocol/protocol_generated.dart' as server;
diff --git a/pkg/analysis_server/lib/src/plugin/plugin_locator.dart b/pkg/analysis_server/lib/src/plugin/plugin_locator.dart
index 0ff0268..4453aea 100644
--- a/pkg/analysis_server/lib/src/plugin/plugin_locator.dart
+++ b/pkg/analysis_server/lib/src/plugin/plugin_locator.dart
@@ -24,7 +24,7 @@
   /// The resource provider used to access the file system.
   final ResourceProvider resourceProvider;
 
-  final Map<String, String> pluginMap = <String, String>{};
+  final Map<String, String?> pluginMap = {};
 
   /// Initialize a newly created plugin locator to use the given
   /// [resourceProvider] to access the file system.
@@ -46,12 +46,12 @@
   ///
   /// This method does not validate the content of the plugin directory before
   /// returning it.
-  String findPlugin(String packageRoot) {
+  String? findPlugin(String packageRoot) {
     return pluginMap.putIfAbsent(packageRoot, () => _findPlugin(packageRoot));
   }
 
   /// The implementation of [findPlugin].
-  String _findPlugin(String packageRoot) {
+  String? _findPlugin(String packageRoot) {
     var packageFolder = resourceProvider.getFolder(packageRoot);
     // TODO(brianwilkerson) Re-enable this after deciding how we want to deal
     // with discovery of plugins.
diff --git a/pkg/analysis_server/lib/src/plugin/plugin_manager.dart b/pkg/analysis_server/lib/src/plugin/plugin_manager.dart
index ccb5df1..02c1294 100644
--- a/pkg/analysis_server/lib/src/plugin/plugin_manager.dart
+++ b/pkg/analysis_server/lib/src/plugin/plugin_manager.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
+
 import 'dart:async';
 import 'dart:collection';
 import 'dart:convert';
@@ -565,7 +567,7 @@
     }
     var files = params.files;
     for (var file in files.keys) {
-      Object overlay = files[file];
+      var overlay = files[file];
       if (overlay is RemoveContentOverlay) {
         _overlayState.remove(file);
       } else if (overlay is AddContentOverlay) {
diff --git a/pkg/analysis_server/lib/src/plugin/plugin_watcher.dart b/pkg/analysis_server/lib/src/plugin/plugin_watcher.dart
index 7eab2f2..6e9bb99 100644
--- a/pkg/analysis_server/lib/src/plugin/plugin_watcher.dart
+++ b/pkg/analysis_server/lib/src/plugin/plugin_watcher.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
+
 import 'dart:convert';
 
 import 'package:analysis_server/src/plugin/plugin_locator.dart';
diff --git a/pkg/analysis_server/lib/src/plugin/request_converter.dart b/pkg/analysis_server/lib/src/plugin/request_converter.dart
index 82b2bf4..559d7ee 100644
--- a/pkg/analysis_server/lib/src/plugin/request_converter.dart
+++ b/pkg/analysis_server/lib/src/plugin/request_converter.dart
@@ -22,10 +22,10 @@
       server.AnalysisSetSubscriptionsParams params) {
     var serverSubscriptions = params.subscriptions;
     var pluginSubscriptions = <plugin.AnalysisService, List<String>>{};
-    for (var service in serverSubscriptions.keys) {
+    for (var entry in serverSubscriptions.entries) {
+      var service = entry.key;
       try {
-        pluginSubscriptions[convertAnalysisService(service)] =
-            serverSubscriptions[service];
+        pluginSubscriptions[convertAnalysisService(service)] = entry.value;
       } catch (exception) {
         // Ignore the exception. It indicates that the service isn't one that
         // should be passed along to plugins.
diff --git a/pkg/analysis_server/lib/src/plugin/result_collector.dart b/pkg/analysis_server/lib/src/plugin/result_collector.dart
index 9ce9ecc..7d695f3 100644
--- a/pkg/analysis_server/lib/src/plugin/result_collector.dart
+++ b/pkg/analysis_server/lib/src/plugin/result_collector.dart
@@ -14,7 +14,7 @@
 
   /// A function used to determine whether results should be collected for the
   /// file whose path is passed in as an argument.
-  final ShouldCollectPredicate _shouldCollect;
+  final ShouldCollectPredicate? _shouldCollect;
 
   /// A multi-keyed map, where the first key is the (normalized and absolute)
   /// path to the file associated with the results, and the second is the id of
@@ -23,7 +23,7 @@
   final Map<String, Map<String, E>> resultMap = <String, Map<String, E>>{};
 
   /// Initialize a newly created result manager.
-  ResultCollector(this.serverId, {ShouldCollectPredicate predicate})
+  ResultCollector(this.serverId, {ShouldCollectPredicate? predicate})
       : _shouldCollect = predicate;
 
   /// Clear any results that have been contributed for the file with the given
@@ -63,8 +63,9 @@
   /// Return `true` if this collector is collecting results associated with the
   /// given [filePath].
   bool isCollectingFor(String filePath) {
-    if (_shouldCollect != null) {
-      return _shouldCollect(filePath);
+    var predicate = _shouldCollect;
+    if (predicate != null) {
+      return predicate(filePath);
     }
     return resultMap.containsKey(filePath);
   }
@@ -74,7 +75,8 @@
   void putResults(String filePath, String pluginId, E partialResults) {
     var fileResults = resultMap[filePath];
     if (fileResults == null) {
-      if (_shouldCollect != null && _shouldCollect(filePath)) {
+      var predicate = _shouldCollect;
+      if (predicate != null && predicate(filePath)) {
         resultMap[filePath] = <String, E>{pluginId: partialResults};
       }
     } else {
diff --git a/pkg/analysis_server/lib/src/plugin/result_merger.dart b/pkg/analysis_server/lib/src/plugin/result_merger.dart
index 0336650b2..be59bb0 100644
--- a/pkg/analysis_server/lib/src/plugin/result_merger.dart
+++ b/pkg/analysis_server/lib/src/plugin/result_merger.dart
@@ -207,7 +207,7 @@
   /// the plugins. If a plugin contributes a navigation region that overlaps a
   /// region from a previous plugin, the overlapping region will be omitted.
   /// (For these purposes, nested regions are considered to be overlapping.)
-  AnalysisNavigationParams mergeNavigation(
+  AnalysisNavigationParams? mergeNavigation(
       List<AnalysisNavigationParams> partialResultList) {
     var count = partialResultList.length;
     if (count == 0) {
@@ -282,7 +282,7 @@
       for (var j = 0; j < targets.length; j++) {
         var target = targets[j];
         var newIndex = fileMap[target.fileIndex];
-        if (target.fileIndex != newIndex) {
+        if (newIndex != null && target.fileIndex != newIndex) {
           target = NavigationTarget(target.kind, newIndex, target.offset,
               target.length, target.startLine, target.startColumn,
               codeOffset: target.codeOffset, codeLength: target.codeLength);
@@ -301,7 +301,8 @@
         var region = regions[j];
         var newTargets = region.targets
             .map((int oldTarget) => targetMap[oldTarget])
-            .toList();
+            .toList()
+            .cast<int>();
         if (region.targets != newTargets) {
           region = NavigationRegion(region.offset, region.length, newTargets);
         }
@@ -427,23 +428,27 @@
     /// Merge the children of the [newOutline] into the list of children of the
     /// [mergedOutline].
     void mergeChildren(Outline mergedOutline, Outline newOutline) {
-      for (var newChild in newOutline.children) {
-        var mergedChild = outlineMap[computeKey(newChild.element)];
-        if (mergedChild == null) {
-          // The [newChild] isn't in the existing list.
-          var copiedOutline = copyMap.putIfAbsent(
-              mergedOutline,
-              () => Outline(
-                  mergedOutline.element,
-                  mergedOutline.offset,
-                  mergedOutline.length,
-                  mergedOutline.codeOffset,
-                  mergedOutline.codeLength,
-                  children: mergedOutline.children.toList()));
-          copiedOutline.children.add(newChild);
-          addToMap(newChild);
-        } else {
-          mergeChildren(mergedChild, newChild);
+      var newChildren = newOutline.children;
+      if (newChildren != null) {
+        for (var newChild in newChildren) {
+          var mergedChild = outlineMap[computeKey(newChild.element)];
+          if (mergedChild == null) {
+            // The [newChild] isn't in the existing list.
+            var mergedChildren = _copyList(mergedOutline.children);
+            mergedChildren.add(newChild);
+            copyMap.putIfAbsent(
+                mergedOutline,
+                () => Outline(
+                    mergedOutline.element,
+                    mergedOutline.offset,
+                    mergedOutline.length,
+                    mergedOutline.codeOffset,
+                    mergedOutline.codeLength,
+                    children: mergedChildren));
+            addToMap(newChild);
+          } else {
+            mergeChildren(mergedChild, newChild);
+          }
         }
       }
     }
@@ -531,7 +536,7 @@
   ///
   /// The feedbacks in the [partialResultList] are expected to all be of the
   /// same type. If that expectation is violated, and exception might be thrown.
-  RefactoringFeedback mergeRefactoringFeedbacks(
+  RefactoringFeedback? mergeRefactoringFeedbacks(
       List<RefactoringFeedback> feedbacks) {
     var count = feedbacks.length;
     if (count == 0) {
@@ -547,24 +552,24 @@
       // The feedbacks are empty, so there's nothing to merge.
       return first;
     } else if (first is ExtractLocalVariableFeedback) {
-      var coveringExpressionOffsets = first.coveringExpressionOffsets == null
-          ? <int>[]
-          : first.coveringExpressionOffsets.toList();
-      var coveringExpressionLengths = first.coveringExpressionLengths == null
-          ? <int>[]
-          : first.coveringExpressionLengths.toList();
+      var coveringExpressionOffsets =
+          _copyList(first.coveringExpressionOffsets);
+      var coveringExpressionLengths =
+          _copyList(first.coveringExpressionLengths);
       var names = first.names.toList();
       var offsets = first.offsets.toList();
       var lengths = first.lengths.toList();
       for (var i = 1; i < count; i++) {
-        ExtractLocalVariableFeedback feedback = feedbacks[i];
+        var feedback = feedbacks[i] as ExtractLocalVariableFeedback;
         // TODO(brianwilkerson) This doesn't ensure that the covering data is in
         // the right order and consistent.
-        if (feedback.coveringExpressionOffsets != null) {
-          coveringExpressionOffsets.addAll(feedback.coveringExpressionOffsets);
+        var coveringOffsets = feedback.coveringExpressionOffsets;
+        if (coveringOffsets != null) {
+          coveringExpressionOffsets.addAll(coveringOffsets);
         }
-        if (feedback.coveringExpressionLengths != null) {
-          coveringExpressionLengths.addAll(feedback.coveringExpressionLengths);
+        var coveringLengths = feedback.coveringExpressionLengths;
+        if (coveringLengths != null) {
+          coveringExpressionLengths.addAll(coveringLengths);
         }
         for (var name in feedback.names) {
           if (!names.contains(name)) {
@@ -591,7 +596,7 @@
       var offsets = first.offsets.toList();
       var lengths = first.lengths.toList();
       for (var i = 1; i < count; i++) {
-        ExtractMethodFeedback feedback = feedbacks[i];
+        var feedback = feedbacks[i] as ExtractMethodFeedback;
         if (returnType.isEmpty) {
           returnType = feedback.returnType;
         }
@@ -665,7 +670,7 @@
   /// The returned result will contain the concatenation of the potential edits.
   /// If two or more plugins produce the same potential edit, then the resulting
   /// list of potential edits will contain duplications.
-  EditGetRefactoringResult mergeRefactorings(
+  EditGetRefactoringResult? mergeRefactorings(
       List<EditGetRefactoringResult> partialResultList) {
     /// Return the result of merging the given list of source [changes] into a
     /// single source change.
@@ -677,7 +682,7 @@
     /// edits will be merged at the level of the file being edited, but will be
     /// a concatenation of the individual edits within each file, even if
     /// multiple plugins contribute duplicate or conflicting edits.
-    SourceChange mergeChanges(List<SourceChange> changes) {
+    SourceChange? mergeChanges(List<SourceChange> changes) {
       var count = changes.length;
       if (count == 0) {
         return null;
@@ -709,7 +714,6 @@
           }
         }
         linkedEditGroups.addAll(change.linkedEditGroups);
-        message ??= change.message;
         selection ??= change.selection;
       }
       return SourceChange(message,
@@ -729,26 +733,33 @@
     var optionsProblems = result.optionsProblems.toList();
     var finalProblems = result.finalProblems.toList();
     var feedbacks = <RefactoringFeedback>[];
-    if (result.feedback != null) {
-      feedbacks.add(result.feedback);
+    var feedback = result.feedback;
+    if (feedback != null) {
+      feedbacks.add(feedback);
     }
     var changes = <SourceChange>[];
-    if (result.change != null) {
-      changes.add(result.change);
+    var change = result.change;
+    if (change != null) {
+      changes.add(change);
     }
-    var potentialEdits = result.potentialEdits.toList();
+    var potentialEdits = _copyList(result.potentialEdits);
     for (var i = 1; i < count; i++) {
       var result = partialResultList[1];
       initialProblems.addAll(result.initialProblems);
       optionsProblems.addAll(result.optionsProblems);
       finalProblems.addAll(result.finalProblems);
-      if (result.feedback != null) {
-        feedbacks.add(result.feedback);
+      var feedback = result.feedback;
+      if (feedback != null) {
+        feedbacks.add(feedback);
       }
-      if (result.change != null) {
-        changes.add(result.change);
+      var change = result.change;
+      if (change != null) {
+        changes.add(change);
       }
-      potentialEdits.addAll(result.potentialEdits);
+      var edits = result.potentialEdits;
+      if (edits != null) {
+        potentialEdits.addAll(edits);
+      }
     }
     return EditGetRefactoringResult(
         initialProblems, optionsProblems, finalProblems,
@@ -795,4 +806,7 @@
     return !((leftStart <= rightStart && rightEnd <= leftEnd) ||
         (rightStart <= leftStart && leftEnd <= rightEnd));
   }
+
+  /// Return a copy of the [list], or an empty list if [list] is `null`.
+  List<E> _copyList<E>(List<E>? list) => list == null ? <E>[] : list.toList();
 }
diff --git a/pkg/analysis_server/lib/src/protocol/protocol_internal.dart b/pkg/analysis_server/lib/src/protocol/protocol_internal.dart
index 17d4837..e84109e 100644
--- a/pkg/analysis_server/lib/src/protocol/protocol_internal.dart
+++ b/pkg/analysis_server/lib/src/protocol/protocol_internal.dart
@@ -29,8 +29,8 @@
 
 /// Compare the lists [listA] and [listB], using [itemEqual] to compare
 /// list elements.
-bool listEqual<T1, T2>(
-    List<T1> listA, List<T2> listB, bool Function(T1 a, T2 b) itemEqual) {
+bool listEqual<T>(
+    List<T>? listA, List<T>? listB, bool Function(T a, T b) itemEqual) {
   if (listA == null) {
     return listB == null;
   }
@@ -51,7 +51,7 @@
 /// Compare the maps [mapA] and [mapB], using [valueEqual] to compare map
 /// values.
 bool mapEqual<K, V>(
-    Map<K, V> mapA, Map<K, V> mapB, bool Function(V a, V b) valueEqual) {
+    Map<K, V>? mapA, Map<K, V>? mapB, bool Function(V a, V b) valueEqual) {
   if (mapA == null) {
     return mapB == null;
   }
@@ -61,11 +61,11 @@
   if (mapA.length != mapB.length) {
     return false;
   }
-  for (var key in mapA.keys) {
-    if (!mapB.containsKey(key)) {
-      return false;
-    }
-    if (!valueEqual(mapA[key], mapB[key])) {
+  for (var entryA in mapA.entries) {
+    var key = entryA.key;
+    var valueA = entryA.value;
+    var valueB = mapB[key];
+    if (valueB == null || !valueEqual(valueA, valueB)) {
       return false;
     }
   }
@@ -75,7 +75,7 @@
 /// Translate the input [map], applying [keyCallback] to all its keys, and
 /// [valueCallback] to all its values.
 Map<KR, VR> mapMap<KP, VP, KR, VR>(Map<KP, VP> map,
-    {KR Function(KP key) keyCallback, VR Function(VP value) valueCallback}) {
+    {KR Function(KP key)? keyCallback, VR Function(VP value)? valueCallback}) {
   Map<KR, VR> result = HashMap<KR, VR>();
   map.forEach((key, value) {
     KR resultKey;
@@ -96,8 +96,8 @@
 }
 
 /// Create a [RefactoringFeedback] corresponding the given [kind].
-RefactoringFeedback refactoringFeedbackFromJson(
-    JsonDecoder jsonDecoder, String jsonPath, Object json, Map feedbackJson) {
+RefactoringFeedback? refactoringFeedbackFromJson(
+    JsonDecoder jsonDecoder, String jsonPath, Object? json, Map feedbackJson) {
   var kind = jsonDecoder.refactoringKind;
   if (kind == RefactoringKind.EXTRACT_LOCAL_VARIABLE) {
     return ExtractLocalVariableFeedback.fromJson(jsonDecoder, jsonPath, json);
@@ -121,8 +121,8 @@
 }
 
 /// Create a [RefactoringOptions] corresponding the given [kind].
-RefactoringOptions refactoringOptionsFromJson(JsonDecoder jsonDecoder,
-    String jsonPath, Object json, RefactoringKind kind) {
+RefactoringOptions? refactoringOptionsFromJson(JsonDecoder jsonDecoder,
+    String jsonPath, Object? json, RefactoringKind kind) {
   if (kind == RefactoringKind.EXTRACT_LOCAL_VARIABLE) {
     return ExtractLocalVariableOptions.fromJson(jsonDecoder, jsonPath, json);
   }
@@ -160,13 +160,13 @@
   RequestDecoder(this._request);
 
   @override
-  RefactoringKind get refactoringKind {
+  RefactoringKind? get refactoringKind {
     // Refactoring feedback objects should never appear in requests.
     return null;
   }
 
   @override
-  dynamic mismatch(String jsonPath, String expected, [Object actual]) {
+  Object mismatch(String jsonPath, String expected, [Object? actual]) {
     var buffer = StringBuffer();
     buffer.write('Expected to be ');
     buffer.write(expected);
@@ -180,7 +180,7 @@
   }
 
   @override
-  dynamic missingKey(String jsonPath, String key) {
+  Object missingKey(String jsonPath, String key) {
     return RequestFailure(Response.invalidParameter(
         _request, jsonPath, 'Expected to contain key ${json.encode(key)}'));
   }
@@ -196,12 +196,12 @@
 /// used only for testing.  Errors are reported using bare [Exception] objects.
 class ResponseDecoder extends JsonDecoder {
   @override
-  final RefactoringKind refactoringKind;
+  final RefactoringKind? refactoringKind;
 
   ResponseDecoder(this.refactoringKind);
 
   @override
-  dynamic mismatch(String jsonPath, String expected, [Object actual]) {
+  Object mismatch(String jsonPath, String expected, [Object? actual]) {
     var buffer = StringBuffer();
     buffer.write('Expected ');
     buffer.write(expected);
@@ -216,7 +216,7 @@
   }
 
   @override
-  dynamic missingKey(String jsonPath, String key) {
+  Object missingKey(String jsonPath, String key) {
     return Exception('Missing key $key at $jsonPath');
   }
 }
diff --git a/pkg/analysis_server/lib/src/protocol_server.dart b/pkg/analysis_server/lib/src/protocol_server.dart
index 598e99d..dda065c 100644
--- a/pkg/analysis_server/lib/src/protocol_server.dart
+++ b/pkg/analysis_server/lib/src/protocol_server.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
+
 import 'package:analysis_server/plugin/protocol/protocol_dart.dart';
 import 'package:analysis_server/protocol/protocol_generated.dart';
 import 'package:analysis_server/src/services/correction/fix.dart';
@@ -15,7 +17,6 @@
 import 'package:analyzer/error/error.dart' as engine;
 import 'package:analyzer/exception/exception.dart';
 import 'package:analyzer/source/error_processor.dart';
-import 'package:analyzer/source/line_info.dart';
 import 'package:analyzer/src/generated/source.dart' as engine;
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 
@@ -116,15 +117,23 @@
     var length = error.length;
     var startLine = -1;
     var startColumn = -1;
+    var endLine = -1;
+    var endColumn = -1;
     var lineInfo = result.lineInfo;
     if (lineInfo != null) {
-      CharacterLocation lineLocation = lineInfo.getLocation(offset);
-      if (lineLocation != null) {
-        startLine = lineLocation.lineNumber;
-        startColumn = lineLocation.columnNumber;
+      var startLocation = lineInfo.getLocation(offset);
+      if (startLocation != null) {
+        startLine = startLocation.lineNumber;
+        startColumn = startLocation.columnNumber;
+      }
+      var endLocation = lineInfo.getLocation(offset + length);
+      if (endLocation != null) {
+        endLine = endLocation.lineNumber;
+        endColumn = endLocation.columnNumber;
       }
     }
-    location = Location(file, offset, length, startLine, startColumn);
+    location = Location(
+        file, offset, length, startLine, startColumn, endLine, endColumn);
   }
 
   // Default to the error's severity if none is specified.
@@ -158,12 +167,18 @@
   var offset = message.offset;
   var length = message.length;
 
-  var lineLocation = result.lineInfo.getLocation(offset);
-  var startLine = lineLocation.lineNumber;
-  var startColumn = lineLocation.columnNumber;
+  var startLocation = result.lineInfo.getLocation(offset);
+  var startLine = startLocation.lineNumber;
+  var startColumn = startLocation.columnNumber;
+
+  var endLocation = result.lineInfo.getLocation(offset + length);
+  var endLine = endLocation.lineNumber;
+  var endColumn = endLocation.columnNumber;
 
   return DiagnosticMessage(
-      message.message, Location(file, offset, length, startLine, startColumn));
+      message.message,
+      Location(
+          file, offset, length, startLine, startColumn, endLine, endColumn));
 }
 
 /// Create a Location based on an [engine.Element].
@@ -286,17 +301,23 @@
     engine.CompilationUnitElement unitElement, engine.SourceRange range) {
   var startLine = 0;
   var startColumn = 0;
+  var endLine = 0;
+  var endColumn = 0;
   try {
     var lineInfo = unitElement.lineInfo;
     if (lineInfo != null) {
-      CharacterLocation offsetLocation = lineInfo.getLocation(range.offset);
-      startLine = offsetLocation.lineNumber;
-      startColumn = offsetLocation.columnNumber;
+      var startLocation = lineInfo.getLocation(range.offset);
+      startLine = startLocation.lineNumber;
+      startColumn = startLocation.columnNumber;
+
+      var endLocation = lineInfo.getLocation(range.end);
+      endLine = endLocation.lineNumber;
+      endColumn = endLocation.columnNumber;
     }
   } on AnalysisException {
     // TODO(brianwilkerson) It doesn't look like the code in the try block
     //  should be able to throw an exception. Try removing the try statement.
   }
   return Location(unitElement.source.fullName, range.offset, range.length,
-      startLine, startColumn);
+      startLine, startColumn, endLine, endColumn);
 }
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 d252dd8..d072cad 100644
--- a/pkg/analysis_server/lib/src/provisional/completion/completion_core.dart
+++ b/pkg/analysis_server/lib/src/provisional/completion/completion_core.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
+
 import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/src/generated/source.dart';
diff --git a/pkg/analysis_server/lib/src/provisional/completion/dart/completion_dart.dart b/pkg/analysis_server/lib/src/provisional/completion/dart/completion_dart.dart
index 4177a84..de9c92b 100644
--- a/pkg/analysis_server/lib/src/provisional/completion/dart/completion_dart.dart
+++ b/pkg/analysis_server/lib/src/provisional/completion/dart/completion_dart.dart
@@ -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
+
 import 'package:analysis_server/src/provisional/completion/completion_core.dart';
 import 'package:analysis_server/src/services/completion/dart/feature_computer.dart';
 import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
diff --git a/pkg/analysis_server/lib/src/search/element_references.dart b/pkg/analysis_server/lib/src/search/element_references.dart
index dc07265..9cee80a 100644
--- a/pkg/analysis_server/lib/src/search/element_references.dart
+++ b/pkg/analysis_server/lib/src/search/element_references.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
+
 import 'package:analysis_server/src/protocol_server.dart'
     show SearchResult, newSearchResult_fromMatch;
 import 'package:analysis_server/src/services/search/hierarchy.dart';
diff --git a/pkg/analysis_server/lib/src/search/search_domain.dart b/pkg/analysis_server/lib/src/search/search_domain.dart
index 9dd70bf..80b84ce 100644
--- a/pkg/analysis_server/lib/src/search/search_domain.dart
+++ b/pkg/analysis_server/lib/src/search/search_domain.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
+
 import 'package:analysis_server/protocol/protocol_constants.dart';
 import 'package:analysis_server/src/analysis_server.dart';
 import 'package:analysis_server/src/protocol_server.dart' as protocol;
diff --git a/pkg/analysis_server/lib/src/search/type_hierarchy.dart b/pkg/analysis_server/lib/src/search/type_hierarchy.dart
index d5b1804..90c3866b 100644
--- a/pkg/analysis_server/lib/src/search/type_hierarchy.dart
+++ b/pkg/analysis_server/lib/src/search/type_hierarchy.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
+
 import 'dart:collection';
 
 import 'package:analysis_server/src/protocol_server.dart'
diff --git a/pkg/analysis_server/lib/src/search/workspace_symbols.dart b/pkg/analysis_server/lib/src/search/workspace_symbols.dart
index 63adfd4..a256782 100644
--- a/pkg/analysis_server/lib/src/search/workspace_symbols.dart
+++ b/pkg/analysis_server/lib/src/search/workspace_symbols.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
+
 import 'dart:collection';
 
 import 'package:analyzer/source/line_info.dart';
diff --git a/pkg/analysis_server/lib/src/server/crash_reporting.dart b/pkg/analysis_server/lib/src/server/crash_reporting.dart
index 4849825..b5c775e 100644
--- a/pkg/analysis_server/lib/src/server/crash_reporting.dart
+++ b/pkg/analysis_server/lib/src/server/crash_reporting.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
+
 import 'package:analyzer/exception/exception.dart';
 import 'package:analyzer/instrumentation/noop_service.dart';
 import 'package:analyzer/instrumentation/plugin_data.dart';
diff --git a/pkg/analysis_server/lib/src/server/detachable_filesystem_manager.dart b/pkg/analysis_server/lib/src/server/detachable_filesystem_manager.dart
index d32ca39..1bad242 100644
--- a/pkg/analysis_server/lib/src/server/detachable_filesystem_manager.dart
+++ b/pkg/analysis_server/lib/src/server/detachable_filesystem_manager.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
+
 import 'package:analysis_server/src/analysis_server.dart';
 
 /// A class that can be used to configure an analysis server instance to better
diff --git a/pkg/analysis_server/lib/src/server/dev_server.dart b/pkg/analysis_server/lib/src/server/dev_server.dart
index 0a1593d..f15d228 100644
--- a/pkg/analysis_server/lib/src/server/dev_server.dart
+++ b/pkg/analysis_server/lib/src/server/dev_server.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
+
 import 'dart:async';
 import 'dart:io';
 
diff --git a/pkg/analysis_server/lib/src/server/driver.dart b/pkg/analysis_server/lib/src/server/driver.dart
index 46b867d..0521a2a 100644
--- a/pkg/analysis_server/lib/src/server/driver.dart
+++ b/pkg/analysis_server/lib/src/server/driver.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
+
 import 'dart:async';
 import 'dart:io';
 import 'dart:isolate';
diff --git a/pkg/analysis_server/lib/src/server/error_notifier.dart b/pkg/analysis_server/lib/src/server/error_notifier.dart
index a69f1f0..f329c92 100644
--- a/pkg/analysis_server/lib/src/server/error_notifier.dart
+++ b/pkg/analysis_server/lib/src/server/error_notifier.dart
@@ -1,3 +1,9 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart = 2.9
+
 import 'package:analysis_server/src/analysis_server_abstract.dart';
 import 'package:analyzer/exception/exception.dart';
 import 'package:analyzer/instrumentation/instrumentation.dart';
diff --git a/pkg/analysis_server/lib/src/server/http_server.dart b/pkg/analysis_server/lib/src/server/http_server.dart
index 1083d5c..1e6fc74 100644
--- a/pkg/analysis_server/lib/src/server/http_server.dart
+++ b/pkg/analysis_server/lib/src/server/http_server.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
+
 import 'dart:io';
 
 import 'package:analysis_server/src/socket_server.dart';
diff --git a/pkg/analysis_server/lib/src/server/isolate_analysis_server.dart b/pkg/analysis_server/lib/src/server/isolate_analysis_server.dart
index 2ef30d3..aaf2ae3 100644
--- a/pkg/analysis_server/lib/src/server/isolate_analysis_server.dart
+++ b/pkg/analysis_server/lib/src/server/isolate_analysis_server.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
+
 import 'dart:io' show IOSink;
 import 'dart:isolate';
 
diff --git a/pkg/analysis_server/lib/src/server/lsp_stdio_server.dart b/pkg/analysis_server/lib/src/server/lsp_stdio_server.dart
index 2fa5b8a..e96bb9c 100644
--- a/pkg/analysis_server/lib/src/server/lsp_stdio_server.dart
+++ b/pkg/analysis_server/lib/src/server/lsp_stdio_server.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
+
 import 'dart:io';
 
 import 'package:analysis_server/src/lsp/channel/lsp_byte_stream_channel.dart';
diff --git a/pkg/analysis_server/lib/src/server/sdk_configuration.dart b/pkg/analysis_server/lib/src/server/sdk_configuration.dart
index c296772..39eb0d1 100644
--- a/pkg/analysis_server/lib/src/server/sdk_configuration.dart
+++ b/pkg/analysis_server/lib/src/server/sdk_configuration.dart
@@ -40,18 +40,19 @@
   }
 
   /// Whether analytics is forced on.
-  bool get analyticsForceEnabled => _values['server.analytics.forceEnabled'];
+  bool? get analyticsForceEnabled => _values['server.analytics.forceEnabled'];
 
-  /// Return a override value for the analysis server's google analytics ID.
-  String get analyticsId => _values['server.analytics.id'];
+  /// Return an override value for the analysis server's google analytics ID, or
+  /// `null` if the default value should be used.
+  String? get analyticsId => _values['server.analytics.id'];
 
   /// Whether crash reporting is forced on.
-  bool get crashReportingForceEnabled =>
+  bool? get crashReportingForceEnabled =>
       _values['server.crash.reporting.forceEnabled'];
 
-  /// Return a override value for the analysis server's crash reporting product
-  /// ID.
-  String get crashReportingId => _values['server.crash.reporting.id'];
+  /// Return an override value for the analysis server's crash reporting product
+  /// ID, or `null` if the default value should be used.
+  String? get crashReportingId => _values['server.crash.reporting.id'];
 
   /// Return a string describing the contents of this SDK configuration.
   String get displayString {
diff --git a/pkg/analysis_server/lib/src/server/stdio_server.dart b/pkg/analysis_server/lib/src/server/stdio_server.dart
index 06c5030..337436e 100644
--- a/pkg/analysis_server/lib/src/server/stdio_server.dart
+++ b/pkg/analysis_server/lib/src/server/stdio_server.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
+
 import 'dart:io';
 
 import 'package:analysis_server/src/channel/byte_stream_channel.dart';
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 4141b3b..e69c357 100644
--- a/pkg/analysis_server/lib/src/services/completion/completion_core.dart
+++ b/pkg/analysis_server/lib/src/services/completion/completion_core.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
+
 import 'package:analysis_server/src/provisional/completion/completion_core.dart';
 import 'package:analysis_server/src/services/completion/completion_performance.dart';
 import 'package:analyzer/dart/analysis/results.dart';
diff --git a/pkg/analysis_server/lib/src/services/completion/completion_performance.dart b/pkg/analysis_server/lib/src/services/completion/completion_performance.dart
index e233d13..dd3480e 100644
--- a/pkg/analysis_server/lib/src/services/completion/completion_performance.dart
+++ b/pkg/analysis_server/lib/src/services/completion/completion_performance.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
+
 import 'package:analyzer/src/util/performance/operation_performance.dart';
 
 /// Compute a string representing a code completion operation at the
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/arglist_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/arglist_contributor.dart
index 271b7fb..5274710 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/arglist_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/arglist_contributor.dart
@@ -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
+
 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/suggestion_builder.dart';
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/combinator_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/combinator_contributor.dart
index ebebb68..c774a4e 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/combinator_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/combinator_contributor.dart
@@ -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
+
 import 'package:analysis_server/src/protocol_server.dart'
     hide Element, ElementKind;
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
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 30182b7..578501a 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
@@ -2,9 +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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/protocol_server.dart';
-import 'package:analysis_server/src/provisional/completion/completion_core.dart'
-    show AbortCompletion, CompletionRequest;
 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/completion_core.dart';
@@ -38,7 +38,6 @@
 import 'package:analyzer/dart/element/type.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';
 import 'package:analyzer/src/dartdoc/dartdoc_directive_info.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/util/file_paths.dart' as file_paths;
@@ -338,7 +337,7 @@
   @override
   bool get inConstantContext {
     var entity = target.entity;
-    return entity is ExpressionImpl && entity.inConstantContext;
+    return entity is Expression && entity.inConstantContext;
   }
 
   @override
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 f127ec1..e0232fb 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
@@ -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
+
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
 import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
 import 'package:analyzer/dart/ast/ast.dart';
@@ -150,7 +152,8 @@
       extension.extendedType,
       'extendedType',
     );
-    var typeArguments = inferrer.infer(typeParameters, failAtError: true);
+    var typeArguments = inferrer.infer(typeParameters,
+        failAtError: true, genericMetadataIsEnabled: true);
     if (typeArguments == null) {
       return null;
     }
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/feature_computer.dart b/pkg/analysis_server/lib/src/services/completion/dart/feature_computer.dart
index 795eabe..1b6eea7 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/feature_computer.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/feature_computer.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
+
 /// Utility methods to compute the value of the features used for code
 /// completion.
 import 'dart:math' as math;
@@ -78,32 +80,26 @@
     {double contextType = 0.0,
     double elementKind = 0.0,
     double hasDeprecated = 0.0,
-    double inheritanceDistance = 0.0,
     double isConstant = 0.0,
     double isNoSuchMethod = 0.0,
     double keyword = 0.0,
-    double localVariableDistance = 0.0,
     double startsWithDollar = 0.0,
     double superMatches = 0.0}) {
   assert(contextType.between(0.0, 1.0));
   assert(elementKind.between(0.0, 1.0));
   assert(hasDeprecated.between(-1.0, 0.0));
-  assert(inheritanceDistance.between(0.0, 1.0));
   assert(isConstant.between(0.0, 1.0));
   assert(isNoSuchMethod.between(-1.0, 0.0));
   assert(keyword.between(0.0, 1.0));
-  assert(localVariableDistance.between(0.0, 1.0));
   assert(startsWithDollar.between(-1.0, 0.0));
   assert(superMatches.between(0.0, 1.0));
   var average = _weightedAverage([
     contextType,
     elementKind,
     hasDeprecated,
-    inheritanceDistance,
     isConstant,
     isNoSuchMethod,
     keyword,
-    localVariableDistance,
     startsWithDollar,
     superMatches,
   ], FeatureComputer.featureWeights);
@@ -150,11 +146,9 @@
     1.00, // contextType
     1.00, // elementKind
     0.50, // hasDeprecated
-    1.00, // inheritanceDistance
     1.00, // isConstant
     1.00, // isNoSuchMethod
     1.00, // keyword
-    1.00, // localVariableDistance
     0.50, // startsWithDollar
     1.00, // superMatches
   ];
@@ -172,7 +166,9 @@
   /// offset is within the given [node], or `null` if the context does not
   /// impose any type.
   DartType computeContextType(AstNode node, int offset) {
-    var type = node.accept(_ContextTypeVisitor(typeProvider, offset));
+    var type = node
+        .accept(_ContextTypeVisitor(typeProvider, offset))
+        ?.resolveToBound(typeProvider.objectType);
     if (type == null || type.isDynamic) {
       return null;
     }
@@ -257,7 +253,7 @@
   /// completing at the given [completionLocation]. If a [distance] is given it
   /// will be used to provide finer-grained relevance scores.
   double elementKindFeature(Element element, String completionLocation,
-      {int distance}) {
+      {double distance}) {
     if (completionLocation == null) {
       return 0.0;
     }
@@ -270,9 +266,9 @@
       return 0.0;
     }
     if (distance == null) {
-      return range.upper;
+      return range.middle;
     }
-    return range.conditionalProbability(_distanceToPercent(distance));
+    return range.conditionalProbability(distance);
   }
 
   /// Return the value of the _has deprecated_ feature for the given [element].
@@ -455,7 +451,7 @@
     if (distance < 0) {
       return 0.0;
     }
-    return math.pow(0.98, distance);
+    return math.pow(0.9, distance);
   }
 
   /// Return the inheritance distance between the [subclass] and the
@@ -675,7 +671,16 @@
     if (range.endEnd(node.functionDefinition, node).contains(offset)) {
       var parent = node.parent;
       if (parent is MethodDeclaration) {
-        return BodyInferenceContext.of(parent.body).contextType;
+        var bodyContext = BodyInferenceContext.of(parent.body);
+        // TODO(scheglov) https://github.com/dart-lang/sdk/issues/45429
+        if (bodyContext == null) {
+          throw StateError('''
+Expected body context.
+Method: $parent
+Class: ${parent.parent}
+''');
+        }
+        return bodyContext.contextType;
       } else if (parent is FunctionExpression) {
         var grandparent = parent.parent;
         if (grandparent is FunctionDeclaration) {
@@ -1004,18 +1009,24 @@
 }
 
 /// Some useful extensions on [AstNode] for this computer.
-extension AstNodeFeatureComputerExtension on AstNode {
+extension on AstNode {
   bool contains(int o) => offset <= o && o <= end;
+}
 
-  /// Return the [FunctionType], if there is one, for this [AstNode].
+/// Some useful extensions on [ArgumentList] for this computer.
+extension on ArgumentList {
+  /// Return the [FunctionType], if there is one, for this [ArgumentList].
   FunctionType get functionType {
-    if (parent is MethodInvocation) {
-      var type = (parent as MethodInvocation).staticInvokeType;
+    var parent = this.parent;
+    if (parent is InstanceCreationExpression) {
+      return parent.constructorName.staticElement?.type;
+    } else if (parent is MethodInvocation) {
+      var type = parent.staticInvokeType;
       if (type is FunctionType) {
         return type;
       }
     } else if (parent is FunctionExpressionInvocation) {
-      var type = (parent as FunctionExpressionInvocation).staticInvokeType;
+      var type = parent.staticInvokeType;
       if (type is FunctionType) {
         return type;
       }
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/field_formal_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/field_formal_contributor.dart
index a24d5c4..b322111 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/field_formal_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/field_formal_contributor.dart
@@ -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
+
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
 import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
 import 'package:analyzer/dart/ast/ast.dart';
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/imported_reference_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/imported_reference_contributor.dart
index 4f560e3..dd993ba 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/imported_reference_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/imported_reference_contributor.dart
@@ -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
+
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
 import 'package:analysis_server/src/services/completion/dart/local_library_contributor.dart';
 import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart'
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 4963edb..4b48766 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
@@ -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
+
 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/suggestion_builder.dart';
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/label_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/label_contributor.dart
index 9434271..e333940 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/label_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/label_contributor.dart
@@ -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
+
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
 import 'package:analysis_server/src/services/completion/dart/completion_manager.dart'
     show DartCompletionRequestImpl;
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/library_member_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/library_member_contributor.dart
index 151f658..634cae3 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/library_member_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/library_member_contributor.dart
@@ -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
+
 import 'package:analysis_server/src/protocol_server.dart'
     show CompletionSuggestionKind;
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
@@ -54,8 +56,10 @@
               if (element is ClassElement) {
                 for (var constructor in element.constructors) {
                   if (!constructor.isPrivate) {
-                    builder.suggestConstructor(constructor,
-                        kind: CompletionSuggestionKind.INVOCATION);
+                    if (!element.isAbstract || constructor.isFactory) {
+                      builder.suggestConstructor(constructor,
+                          kind: CompletionSuggestionKind.INVOCATION);
+                    }
                   }
                 }
               }
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/library_prefix_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/library_prefix_contributor.dart
index 0fccab2..2ec7b23 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/library_prefix_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/library_prefix_contributor.dart
@@ -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
+
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
 import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
 
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 7ed705f..279f4fb 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
@@ -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
+
 import 'package:analysis_server/src/protocol_server.dart'
     show CompletionSuggestionKind;
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
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 d92cc04..546c236 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
@@ -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
+
 import 'package:analysis_server/src/protocol_server.dart'
     show CompletionSuggestionKind;
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/named_constructor_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/named_constructor_contributor.dart
index 316d282..b31253f 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/named_constructor_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/named_constructor_contributor.dart
@@ -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
+
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
 import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
 import 'package:analyzer/dart/ast/ast.dart';
@@ -42,9 +44,11 @@
     var isLocalClassDecl = classElem.library == libElem;
     for (var constructor in classElem.constructors) {
       if (isLocalClassDecl || !constructor.isPrivate) {
-        var name = constructor.name;
-        if (name != null) {
-          builder.suggestConstructor(constructor, hasClassName: true);
+        if (!classElem.isAbstract || constructor.isFactory) {
+          var name = constructor.name;
+          if (name != null) {
+            builder.suggestConstructor(constructor, hasClassName: true);
+          }
         }
       }
     }
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/override_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/override_contributor.dart
index 178dc1d..c18f91d 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/override_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/override_contributor.dart
@@ -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
+
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
 import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
 import 'package:analyzer/dart/ast/ast.dart';
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/probability_range.dart b/pkg/analysis_server/lib/src/services/completion/dart/probability_range.dart
index 2b4be44..5b6d32e 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/probability_range.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/probability_range.dart
@@ -12,12 +12,15 @@
 
   /// Initialize a newly created probability range to have the given [lower] and
   /// [upper] bounds.
-  const ProbabilityRange({this.lower, this.upper});
+  const ProbabilityRange({required this.lower, required this.upper});
+
+  /// The middle of the range.
+  double get middle => (upper + lower) / 2;
 
   /// Given the [probability] of an occurrence of an event that is conditional
   /// on the event represented by this range, return the probability of the
   /// event independent of the event based on this range.
   double conditionalProbability(double probability) {
-    return lower + ((upper - lower) * probability);
+    return middle + ((upper - lower) * probability / 2);
   }
 }
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/relevance_tables.g.dart b/pkg/analysis_server/lib/src/services/completion/dart/relevance_tables.g.dart
index 25f3857..d3b69d7 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/relevance_tables.g.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/relevance_tables.g.dart
@@ -1,7 +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.
-//
+
 // 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",
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/static_member_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/static_member_contributor.dart
index 102365e..cfd2a34 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/static_member_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/static_member_contributor.dart
@@ -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
+
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
 import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
 import 'package:analyzer/dart/ast/ast.dart';
@@ -41,7 +43,9 @@
         }
         for (var constructor in element.constructors) {
           if (isVisible(constructor)) {
-            builder.suggestConstructor(constructor, hasClassName: true);
+            if (!element.isAbstract || constructor.isFactory) {
+              builder.suggestConstructor(constructor, hasClassName: true);
+            }
           }
         }
         for (var field in element.fields) {
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 529a4d7..43af352 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
@@ -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
+
 import 'dart:collection';
 
 import 'package:_fe_analyzer_shared/src/base/syntactic_entity.dart';
@@ -111,6 +113,11 @@
         // Setters, fields, and methods shadow a setter.
         if ((alreadyGenerated & _COMPLETION_TYPE_SETTER) != 0) {
           return false;
+        } else if (element.hasDeprecated &&
+            !(element.correspondingGetter?.hasDeprecated ?? true)) {
+          // A deprecated setter should not take priority over a non-deprecated
+          // getter.
+          return false;
         }
         _completionTypesGenerated[identifier] |= _COMPLETION_TYPE_SETTER;
       }
@@ -218,7 +225,8 @@
       var featureComputer = request.featureComputer;
       var contextType =
           featureComputer.contextTypeFeature(request.contextType, type);
-      var elementKind = _computeElementKind(accessor);
+      var elementKind =
+          _computeElementKind(accessor, distance: inheritanceDistance);
       var hasDeprecated = featureComputer.hasDeprecatedFeature(accessor);
       var isConstant = request.inConstantContext
           ? featureComputer.isConstantFeature(accessor)
@@ -227,22 +235,15 @@
           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,
-          isConstant: isConstant,
-          startsWithDollar: startsWithDollar,
-          superMatches: superMatches);
+      var relevance = _computeRelevance(
+        contextType: contextType,
+        elementKind: elementKind,
+        hasDeprecated: hasDeprecated,
+        isConstant: isConstant,
+        startsWithDollar: startsWithDollar,
+        superMatches: superMatches,
+        inheritanceDistance: inheritanceDistance,
+      );
       _add(_createSuggestion(accessor, relevance: relevance));
     }
   }
@@ -256,15 +257,11 @@
     var isConstant = request.inConstantContext
         ? request.featureComputer.isConstantFeature(parameter)
         : 0.0;
-    var score = weightedAverage(
-        contextType: contextType,
-        elementKind: elementKind,
-        isConstant: isConstant);
-    var relevance = toRelevance(score);
-    listener?.computedFeatures(
-        contextType: contextType,
-        elementKind: elementKind,
-        isConstant: isConstant);
+    var relevance = _computeRelevance(
+      contextType: contextType,
+      elementKind: elementKind,
+      isConstant: isConstant,
+    );
     _add(_createSuggestion(parameter,
         elementKind: protocol.ElementKind.PARAMETER, relevance: relevance));
   }
@@ -361,7 +358,7 @@
       }
     }
     if (completion == null || completion.isEmpty) {
-      return null;
+      return;
     }
 
     var returnType = _instantiateClassElement(enclosingClass);
@@ -432,7 +429,7 @@
     var featureComputer = request.featureComputer;
     var contextType =
         featureComputer.contextTypeFeature(request.contextType, field.type);
-    var elementKind = _computeElementKind(field);
+    var elementKind = _computeElementKind(field, distance: inheritanceDistance);
     var hasDeprecated = featureComputer.hasDeprecatedFeature(field);
     var isConstant = request.inConstantContext
         ? featureComputer.isConstantFeature(field)
@@ -440,22 +437,15 @@
     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,
-        isConstant: isConstant,
-        startsWithDollar: startsWithDollar,
-        superMatches: superMatches);
+    var relevance = _computeRelevance(
+      contextType: contextType,
+      elementKind: elementKind,
+      hasDeprecated: hasDeprecated,
+      isConstant: isConstant,
+      startsWithDollar: startsWithDollar,
+      superMatches: superMatches,
+      inheritanceDistance: inheritanceDistance,
+    );
     _add(_createSuggestion(field, relevance: relevance));
   }
 
@@ -506,11 +496,10 @@
         .contextTypeFeature(request.contextType, elementType);
     var keywordFeature = request.featureComputer
         .keywordFeature(keyword, request.opType.completionLocation);
-    var score =
-        weightedAverage(contextType: contextType, keyword: keywordFeature);
-    var relevance = toRelevance(score);
-    listener?.computedFeatures(
-        contextType: contextType, keyword: keywordFeature);
+    var relevance = _computeRelevance(
+      contextType: contextType,
+      keyword: keywordFeature,
+    );
     _add(CompletionSuggestion(CompletionSuggestionKind.KEYWORD, relevance,
         keyword, offset ?? keyword.length, 0, false, false));
   }
@@ -547,23 +536,19 @@
     var node = entity is AstNode ? entity : target.containingNode;
     var contextType = request.featureComputer
         .contextTypeFeature(request.contextType, variableType);
-    var elementKind = _computeElementKind(variable);
+    var localVariableDistance =
+        request.featureComputer.localVariableDistanceFeature(node, variable);
+    var elementKind =
+        _computeElementKind(variable, distance: localVariableDistance);
     var isConstant = request.inConstantContext
         ? request.featureComputer.isConstantFeature(variable)
         : 0.0;
-    var localVariableDistance =
-        request.featureComputer.localVariableDistanceFeature(node, variable);
-    var score = weightedAverage(
-        contextType: contextType,
-        elementKind: elementKind,
-        isConstant: isConstant,
-        localVariableDistance: localVariableDistance);
-    var relevance = toRelevance(score);
-    listener?.computedFeatures(
-        contextType: contextType,
-        elementKind: elementKind,
-        isConstant: isConstant,
-        localVariableDistance: localVariableDistance);
+    var relevance = _computeRelevance(
+      contextType: contextType,
+      elementKind: elementKind,
+      isConstant: isConstant,
+      localVariableDistance: localVariableDistance,
+    );
     _add(_createSuggestion(variable, relevance: relevance));
   }
 
@@ -580,7 +565,8 @@
     var featureComputer = request.featureComputer;
     var contextType = featureComputer.contextTypeFeature(
         request.contextType, method.returnType);
-    var elementKind = _computeElementKind(method);
+    var elementKind =
+        _computeElementKind(method, distance: inheritanceDistance);
     var hasDeprecated = featureComputer.hasDeprecatedFeature(method);
     var isConstant = request.inConstantContext
         ? featureComputer.isConstantFeature(method)
@@ -590,24 +576,16 @@
     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,
-        isNoSuchMethod: isNoSuchMethod,
-        startsWithDollar: startsWithDollar,
-        superMatches: superMatches);
-    listener?.computedFeatures(
-        contextType: contextType,
-        elementKind: elementKind,
-        hasDeprecated: hasDeprecated,
-        inheritanceDistance: inheritanceDistance,
-        isConstant: isConstant,
-        isNoSuchMethod: isNoSuchMethod,
-        startsWithDollar: startsWithDollar,
-        superMatches: superMatches);
+    var relevance = _computeRelevance(
+      contextType: contextType,
+      elementKind: elementKind,
+      hasDeprecated: hasDeprecated,
+      isConstant: isConstant,
+      isNoSuchMethod: isNoSuchMethod,
+      startsWithDollar: startsWithDollar,
+      superMatches: superMatches,
+      inheritanceDistance: inheritanceDistance,
+    );
 
     var suggestion =
         _createSuggestion(method, kind: kind, relevance: relevance);
@@ -785,15 +763,11 @@
     var isConstant = request.inConstantContext
         ? request.featureComputer.isConstantFeature(parameter)
         : 0.0;
-    var score = weightedAverage(
-        contextType: contextType,
-        elementKind: elementKind,
-        isConstant: isConstant);
-    var relevance = toRelevance(score);
-    listener?.computedFeatures(
-        contextType: contextType,
-        elementKind: elementKind,
-        isConstant: isConstant);
+    var relevance = _computeRelevance(
+      contextType: contextType,
+      elementKind: elementKind,
+      isConstant: isConstant,
+    );
     _add(_createSuggestion(parameter, relevance: relevance));
   }
 
@@ -803,9 +777,9 @@
     // 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 score = weightedAverage(elementKind: elementKind);
-    var relevance = toRelevance(score);
-    listener?.computedFeatures(elementKind: elementKind);
+    var relevance = _computeRelevance(
+      elementKind: elementKind,
+    );
     _add(_createSuggestion(library,
         completion: prefix,
         kind: CompletionSuggestionKind.IDENTIFIER,
@@ -852,29 +826,20 @@
           featureComputer.contextTypeFeature(request.contextType, type);
       var elementKind = _computeElementKind(accessor);
       var hasDeprecated = featureComputer.hasDeprecatedFeature(accessor);
-      var inheritanceDistance = 0.0;
       var isConstant = request.inConstantContext
           ? featureComputer.isConstantFeature(accessor)
           : 0.0;
       var startsWithDollar =
           featureComputer.startsWithDollarFeature(accessor.name);
       var superMatches = 0.0;
-      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,
-          isConstant: isConstant,
-          startsWithDollar: startsWithDollar,
-          superMatches: superMatches);
+      var relevance = _computeRelevance(
+        contextType: contextType,
+        elementKind: elementKind,
+        hasDeprecated: hasDeprecated,
+        isConstant: isConstant,
+        startsWithDollar: startsWithDollar,
+        superMatches: superMatches,
+      );
       _add(_createSuggestion(accessor, prefix: prefix, relevance: relevance));
     }
   }
@@ -910,11 +875,10 @@
     var isConstant = request.inConstantContext
         ? request.featureComputer.isConstantFeature(parameter)
         : 0.0;
-    var score =
-        weightedAverage(elementKind: elementKind, isConstant: isConstant);
-    var relevance = toRelevance(score);
-    listener?.computedFeatures(
-        elementKind: elementKind, isConstant: isConstant);
+    var relevance = _computeRelevance(
+      elementKind: elementKind,
+      isConstant: isConstant,
+    );
     _add(_createSuggestion(parameter,
         kind: CompletionSuggestionKind.IDENTIFIER, relevance: relevance));
   }
@@ -946,10 +910,10 @@
 
   /// Compute the value of the _element kind_ feature for the given [element] in
   /// the completion context.
-  double _computeElementKind(Element element) {
+  double _computeElementKind(Element element, {double distance}) {
     var location = request.opType.completionLocation;
-    var elementKind =
-        request.featureComputer.elementKindFeature(element, location);
+    var elementKind = request.featureComputer
+        .elementKindFeature(element, location, distance: distance);
     if (elementKind < 0.0) {
       if (location == null) {
         listener?.missingCompletionLocationAt(
@@ -961,26 +925,44 @@
     return elementKind;
   }
 
-  /// Compute a relevance value from the given feature scores.
-  int _computeMemberRelevance(
-      {@required double contextType,
-      @required double elementKind,
-      @required double hasDeprecated,
-      @required double inheritanceDistance,
-      @required double isConstant,
+  /// Compute the relevance based on the given feature values and pass those
+  /// feature values to the listener if there is one.
+  int _computeRelevance(
+      {double contextType = 0.0,
+      double elementKind = 0.0,
+      double hasDeprecated = 0.0,
+      double isConstant = 0.0,
       double isNoSuchMethod = 0.0,
-      @required double startsWithDollar,
-      @required double superMatches}) {
+      double keyword = 0.0,
+      double startsWithDollar = 0.0,
+      double superMatches = 0.0,
+      // Dependent features
+      double inheritanceDistance = 0.0,
+      double localVariableDistance = 0.0}) {
     var score = weightedAverage(
         contextType: contextType,
         elementKind: elementKind,
         hasDeprecated: hasDeprecated,
-        inheritanceDistance: inheritanceDistance,
         isConstant: isConstant,
         isNoSuchMethod: isNoSuchMethod,
+        keyword: keyword,
         startsWithDollar: startsWithDollar,
         superMatches: superMatches);
-    return toRelevance(score);
+    var relevance = toRelevance(score);
+    listener?.computedFeatures(
+      contextType: contextType,
+      elementKind: elementKind,
+      hasDeprecated: hasDeprecated,
+      isConstant: isConstant,
+      isNoSuchMethod: isNoSuchMethod,
+      keyword: keyword,
+      startsWithDollar: startsWithDollar,
+      superMatches: superMatches,
+      // Dependent features
+      inheritanceDistance: inheritanceDistance,
+      localVariableDistance: localVariableDistance,
+    );
+    return relevance;
   }
 
   /// Return the relevance score for a top-level [element].
@@ -998,18 +980,12 @@
     var isConstant = request.inConstantContext
         ? featureComputer.isConstantFeature(element)
         : 0.0;
-    var score = weightedAverage(
-        contextType: contextType,
-        elementKind: elementKind,
-        hasDeprecated: hasDeprecated,
-        isConstant: isConstant);
-    var relevance = toRelevance(score);
-    listener?.computedFeatures(
-        contextType: contextType,
-        elementKind: elementKind,
-        hasDeprecated: hasDeprecated,
-        isConstant: isConstant);
-    return relevance;
+    return _computeRelevance(
+      contextType: contextType,
+      elementKind: elementKind,
+      hasDeprecated: hasDeprecated,
+      isConstant: isConstant,
+    );
   }
 
   /// Return a suggestion based on the [element], or `null` if a suggestion is
@@ -1153,13 +1129,14 @@
       {double contextType,
       double elementKind,
       double hasDeprecated,
-      double inheritanceDistance,
       double isConstant,
       double isNoSuchMethod,
       double keyword,
-      double localVariableDistance,
       double startsWithDollar,
-      double superMatches});
+      double superMatches,
+      // Dependent features
+      double inheritanceDistance,
+      double localVariableDistance});
 
   /// Invoked when an element kind feature cannot be produced because there is
   /// no completion location label associated with the completion offset.
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 e3eee98..19510c7 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
@@ -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
+
 import 'dart:collection';
 
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
@@ -47,7 +49,7 @@
     }
 
     // Determine the target expression's type.
-    var type = expression.staticType;
+    var type = expression.staticType?.resolveToBound(request.objectType);
     if (type == null || type.isDynamic) {
       // If the expression does not provide a good type, then attempt to get a
       // better type from the element.
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/uri_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/uri_contributor.dart
index fed0ed7..33dbf47 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/uri_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/uri_contributor.dart
@@ -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
+
 import 'dart:core';
 
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/utilities.dart b/pkg/analysis_server/lib/src/services/completion/dart/utilities.dart
index 5eaa1c5..75b43b9 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/utilities.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/utilities.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
+
 /// A collection of utility methods used by completion contributors.
 import 'package:analysis_server/src/protocol_server.dart'
     show CompletionSuggestion, Location;
@@ -154,10 +156,10 @@
   if (id != null) {
     name = id.name;
     // TODO(danrubel) use lineInfo to determine startLine and startColumn
-    location = Location(source.fullName, id.offset, id.length, 0, 0);
+    location = Location(source.fullName, id.offset, id.length, 0, 0, 0, 0);
   } else {
     name = '';
-    location = Location(source.fullName, -1, 0, 1, 0);
+    location = Location(source.fullName, -1, 0, 1, 0, 1, 0);
   }
   var flags = protocol.Element.makeFlags(
       isAbstract: isAbstract,
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/variable_name_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/variable_name_contributor.dart
index 1c4e0db..50e0fd16 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/variable_name_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/variable_name_contributor.dart
@@ -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
+
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
 import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
 import 'package:analysis_server/src/services/correction/name_suggestion.dart';
diff --git a/pkg/analysis_server/lib/src/services/completion/filtering/fuzzy_matcher.dart b/pkg/analysis_server/lib/src/services/completion/filtering/fuzzy_matcher.dart
index 7868f80..3b3b71d 100644
--- a/pkg/analysis_server/lib/src/services/completion/filtering/fuzzy_matcher.dart
+++ b/pkg/analysis_server/lib/src/services/completion/filtering/fuzzy_matcher.dart
@@ -83,10 +83,12 @@
   MatchStyle matchStyle;
 
   /// The lowercase version of the pattern.
-  String patternLower;
+  // Initialized in the constructor.
+  String patternLower = '';
 
   /// The first three characters of the lowercase version of the pattern.
-  String patternShort;
+  // Initialized in the constructor.
+  String patternShort = '';
 
   /// The length of the last matched candidate.
   int lastCandidateLen = 0;
@@ -107,24 +109,27 @@
   ///
   /// The zero bit of the score value keeps track of where we came from (1 if
   /// the previous character matched, and 0 otherwise).
-  List<List<int>> table;
+  List<List<int>> table = [];
 
   /// The offset of the "previous symbol matched" table on the pattern axis.
-  int matchesLayerOffset;
+  // Initialized in the constructor.
+  int matchesLayerOffset = 0;
 
   /// Pre-allocated memory for storing the role of each character in the
   /// candidate string.
   List<CharRole> candidateRoles = List.filled(maxInputSize, CharRole.NONE);
 
   /// The role of each character in the pattern.
-  List<CharRole> patternRoles;
+  List<CharRole> patternRoles = [];
 
   /// A flag indicating whether scoring should be case-sensitive. Mix-case
   /// patterns turn on case-sensitive scoring.
-  bool caseSensitive;
+  // Initialized in the constructor.
+  bool caseSensitive = false;
 
   /// Normalizes scores for the pattern length.
-  double scoreScale;
+  // Initialized in the constructor.
+  double scoreScale = 0.0;
 
   /// Initialize a newly created matcher to match the [pattern] using the given
   /// [matchStyle].
@@ -141,7 +146,6 @@
     }
     matchesLayerOffset = pattern.length + 1;
 
-    table = [];
     for (var i = 0; i <= maxInputSize; i++) {
       table.add(List.filled(2 * matchesLayerOffset, 0));
     }
diff --git a/pkg/analysis_server/lib/src/services/completion/postfix/postfix_completion.dart b/pkg/analysis_server/lib/src/services/completion/postfix/postfix_completion.dart
index b648f7f..c88f85d 100644
--- a/pkg/analysis_server/lib/src/services/completion/postfix/postfix_completion.dart
+++ b/pkg/analysis_server/lib/src/services/completion/postfix/postfix_completion.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
+
 import 'package:analysis_server/src/protocol_server.dart' hide Element;
 import 'package:analysis_server/src/services/correction/util.dart';
 import 'package:analyzer/dart/analysis/results.dart';
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 a8634ca..679b457 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
@@ -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
+
 import 'dart:math';
 
 import 'package:analysis_server/src/protocol_server.dart' hide Element;
@@ -427,14 +429,8 @@
     }
     DoStatement statement = node;
     var sb = _sourceBuilderAfterKeyword(statement.doKeyword);
-    // I modified the code and ran the tests with both the old and new parser.
-    // Apparently the old parser sometimes sticks something other than 'while'
-    // into the whileKeyword field, which causes statement completion to throw
-    // an exception further downstream.
-    // TODO(danrubel): change `statement.whileKeyword?.lexeme == "while"`
-    // to `statement.whileKeyword != null` once the fasta parser is the default.
-    var hasWhileKeyword = statement.whileKeyword?.lexeme == 'while' &&
-        !statement.whileKeyword.isSynthetic;
+    var hasWhileKeyword =
+        statement.whileKeyword != null && !statement.whileKeyword.isSynthetic;
     var exitDelta = 0;
     if (!_statementHasValidBody(statement.doKeyword, statement.body)) {
       var text = utils.getNodeText(statement.body);
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
index 7f60edd..7fd44bd 100644
--- 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
@@ -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
+
 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';
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
index 15ef594..e1f1d55 100644
--- 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
@@ -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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/completion/yaml/producer.dart b/pkg/analysis_server/lib/src/services/completion/yaml/producer.dart
index 06a5401..c56f9d2 100644
--- a/pkg/analysis_server/lib/src/services/completion/yaml/producer.dart
+++ b/pkg/analysis_server/lib/src/services/completion/yaml/producer.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
+
 import 'package:analysis_server/src/protocol_server.dart';
 import 'package:analysis_server/src/services/pub/pub_package_service.dart';
 import 'package:analyzer/file_system/file_system.dart';
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
index d167c72..629db2a 100644
--- a/pkg/analysis_server/lib/src/services/completion/yaml/pubspec_generator.dart
+++ b/pkg/analysis_server/lib/src/services/completion/yaml/pubspec_generator.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
+
 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';
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
index cfa4242e..b6bff4c 100644
--- 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
@@ -2,11 +2,14 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/protocol_server.dart';
 import 'package:analysis_server/src/services/completion/yaml/producer.dart';
 import 'package:analysis_server/src/services/pub/pub_package_service.dart';
 import 'package:analysis_server/src/utilities/extensions/yaml.dart';
 import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/src/util/yaml.dart';
 import 'package:yaml/yaml.dart';
 
 /// A completion generator that can produce completion suggestions for files
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 d304168..42230fe 100644
--- a/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/assist_internal.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
+
 import 'package:analysis_server/plugin/edit/assist/assist_core.dart';
 import 'package:analysis_server/plugin/edit/assist/assist_dart.dart';
 import 'package:analysis_server/src/services/correction/assist.dart';
@@ -299,8 +301,10 @@
     var map = <ProducerGenerator, Set<String>>{};
     for (var entry in FixProcessor.lintProducerMap.entries) {
       var lintName = entry.key;
-      for (var generator in entry.value) {
-        map.putIfAbsent(generator, () => <String>{}).add(lintName);
+      for (var fix in entry.value) {
+        for (var generator in fix.generators) {
+          map.putIfAbsent(generator, () => <String>{}).add(lintName);
+        }
       }
     }
     return map;
diff --git a/pkg/analysis_server/lib/src/services/correction/base_processor.dart b/pkg/analysis_server/lib/src/services/correction/base_processor.dart
index 836467a..0750898 100644
--- a/pkg/analysis_server/lib/src/services/correction/base_processor.dart
+++ b/pkg/analysis_server/lib/src/services/correction/base_processor.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
+
 import 'package:analysis_server/src/services/correction/util.dart';
 import 'package:analysis_server/src/utilities/flutter.dart';
 import 'package:analyzer/dart/analysis/results.dart';
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 5280479..093355b 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
@@ -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
+
 import 'dart:core';
 
 import 'package:analysis_server/plugin/edit/fix/fix_dart.dart';
@@ -9,7 +11,6 @@
 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/data_driven.dart';
-import 'package:analysis_server/src/services/correction/dart/remove_non_null_assertion.dart';
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/correction/fix/data_driven/transform_override_set.dart';
 import 'package:analysis_server/src/services/correction/fix/data_driven/transform_override_set_parser.dart';
@@ -29,6 +30,7 @@
 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';
+import 'package:collection/collection.dart';
 
 /// A fix producer that produces changes that will fix multiple diagnostics in
 /// one or more files.
@@ -127,14 +129,6 @@
     ],
   };
 
-  /// A map from an error code to a generator used to create the correction
-  /// producer used to build a fix for that diagnostic. The generators used for
-  /// lint rules are in the [lintProducerMap].
-  static const Map<ErrorCode, ProducerGenerator> nonLintProducerMap = {
-    StaticWarningCode.UNNECESSARY_NON_NULL_ASSERTION:
-        RemoveNonNullAssertion.newInstance,
-  };
-
   /// The service used to report errors when building fixes.
   final InstrumentationService instrumentationService;
 
@@ -237,22 +231,26 @@
   ) sync* {
     final errorCode = diagnostic.errorCode;
     if (errorCode is LintCode) {
-      var fixes = FixProcessor.lintProducerMap2[errorCode.name] ?? [];
+      var fixes = FixProcessor.lintProducerMap[errorCode.name] ?? [];
       for (var fix in fixes) {
         if (fix.canBeBulkApplied) {
           final generators = fix.generators;
           if (generators != null) {
-            yield* generators.map((g) => g().fixKind).where((k) => k != null);
+            yield* generators.map((g) => g().fixKind).whereNotNull();
           }
         }
       }
       return;
     }
 
-    final generator = nonLintProducerMap[errorCode];
-    if (generator != null) {
-      final kind = generator().fixKind;
-      if (kind != null) yield kind;
+    var fixes = FixProcessor.nonLintProducerMap2[errorCode] ?? [];
+    for (var fix in fixes) {
+      if (fix.canBeBulkApplied) {
+        final generators = fix.generators;
+        if (generators != null) {
+          yield* generators.map((g) => g().fixKind).whereNotNull();
+        }
+      }
     }
 
     final multiGenerators = nonLintMultiProducerMap[errorCode];
@@ -362,26 +360,28 @@
       }
     }
 
+    Future<void> bulkApply(List<FixInfo> fixes, String codeName) async {
+      for (var fix in fixes) {
+        if (fix.canBeBulkApplied) {
+          final generators = fix.generators;
+          if (generators != null) {
+            for (var generator in generators) {
+              await generate(generator(), codeName);
+            }
+          }
+        }
+      }
+    }
+
     var errorCode = diagnostic.errorCode;
     try {
       var codeName = errorCode.name;
       if (errorCode is LintCode) {
-        var fixes = FixProcessor.lintProducerMap2[errorCode.name] ?? [];
-        for (var fix in fixes) {
-          if (fix.canBeBulkApplied) {
-            final generators = fix.generators;
-            if (generators != null) {
-              for (var generator in generators) {
-                await generate(generator(), codeName);
-              }
-            }
-          }
-        }
+        var fixes = FixProcessor.lintProducerMap[errorCode.name] ?? [];
+        await bulkApply(fixes, codeName);
       } else {
-        var generator = nonLintProducerMap[errorCode];
-        if (generator != null) {
-          await generate(generator(), codeName);
-        }
+        var fixes = FixProcessor.nonLintProducerMap2[errorCode] ?? [];
+        await bulkApply(fixes, codeName);
         var multiGenerators = nonLintMultiProducerMap[errorCode];
         if (multiGenerators != null) {
           for (var multiGenerator in multiGenerators) {
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/abstract_producer.dart b/pkg/analysis_server/lib/src/services/correction/dart/abstract_producer.dart
index b7e0c1c..6bef12b 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/abstract_producer.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/abstract_producer.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
+
 import 'dart:math' as math;
 
 import 'package:_fe_analyzer_shared/src/scanner/token.dart';
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 2e73adb..79c8f63 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
@@ -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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_await.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_await.dart
index 6e72eae..7acd73c 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/add_await.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_await.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
+
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_const.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_const.dart
index c0e5abe..d4b2642 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/add_const.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_const.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_diagnostic_property_reference.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_diagnostic_property_reference.dart
index 283dfb0..649cfbc 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/add_diagnostic_property_reference.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_diagnostic_property_reference.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
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analysis_server/src/services/correction/fix.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_explicit_cast.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_explicit_cast.dart
index f66b06f..aaaf687 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/add_explicit_cast.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_explicit_cast.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
+
 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/utilities/extensions/ast.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_field_formal_parameters.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_field_formal_parameters.dart
index 6a23e04..e4ef282 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/add_field_formal_parameters.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_field_formal_parameters.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_late.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_late.dart
index 56791c0..06bb9e0 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/add_late.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_late.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_missing_enum_case_clauses.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_missing_enum_case_clauses.dart
index d4426a0..b4825c1 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/add_missing_enum_case_clauses.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_missing_enum_case_clauses.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_missing_parameter.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_missing_parameter.dart
index 9b8f484..4d7c4db 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/add_missing_parameter.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_missing_parameter.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
+
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analysis_server/src/services/correction/executable_parameters.dart';
 import 'package:analysis_server/src/services/correction/fix.dart';
@@ -16,7 +18,8 @@
     if (node.parent is! ArgumentList) {
       return;
     }
-    var context = ExecutableParameters(sessionHelper, node.parent.parent);
+    var context =
+        ExecutableParameters.forInvocation(sessionHelper, node.parent.parent);
     if (context == null) {
       return;
     }
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_missing_parameter_named.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_missing_parameter_named.dart
index 93ab6ad..cc53b3f 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/add_missing_parameter_named.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_missing_parameter_named.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
+
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analysis_server/src/services/correction/executable_parameters.dart';
 import 'package:analysis_server/src/services/correction/fix.dart';
@@ -40,7 +42,8 @@
     var argumentList = namedExpression.parent;
 
     // Prepare the invoked element.
-    var context = ExecutableParameters(sessionHelper, argumentList.parent);
+    var context =
+        ExecutableParameters.forInvocation(sessionHelper, argumentList.parent);
     if (context == null) {
       return;
     }
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_missing_required_argument.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_missing_required_argument.dart
index 40e8f6f..d95722a 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/add_missing_required_argument.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_missing_required_argument.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
+
 import 'package:_fe_analyzer_shared/src/scanner/token.dart';
 import 'package:analysis_server/src/services/completion/dart/utilities.dart';
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_ne_null.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_ne_null.dart
index ef38ab3..cd75a2b 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/add_ne_null.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_ne_null.dart
@@ -2,8 +2,13 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analysis_server/src/services/correction/fix.dart';
+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_plugin/utilities/change_builder/change_builder_core.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 
@@ -16,6 +21,13 @@
 
   @override
   Future<void> compute(ChangeBuilder builder) async {
+    if (unit.featureSet.isEnabled(Feature.non_nullable)) {
+      var node = this.node;
+      if (node is Expression &&
+          node.staticType?.nullabilitySuffix == NullabilitySuffix.none) {
+        return;
+      }
+    }
     var problemMessage = diagnostic.problemMessage;
     await builder.addDartFileEdit(file, (builder) {
       builder.addSimpleInsertion(
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_not_null_assert.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_not_null_assert.dart
index 20b8972..fe5c8f6 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/add_not_null_assert.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_not_null_assert.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
+
 import 'dart:math';
 
 import 'package:_fe_analyzer_shared/src/scanner/token.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_null_check.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_null_check.dart
index bc898f7..b7b4810 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/add_null_check.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_null_check.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
+
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer/dart/analysis/features.dart';
@@ -22,8 +24,31 @@
       return;
     }
     Expression target;
-    if (coveredNode is Expression) {
+    var coveredNodeParent = coveredNode.parent;
+    if (coveredNode is SimpleIdentifier) {
+      if (coveredNodeParent is MethodInvocation) {
+        target = coveredNodeParent.realTarget;
+      } else if (coveredNodeParent is PrefixedIdentifier) {
+        target = coveredNodeParent.prefix;
+      } else if (coveredNodeParent is PropertyAccess) {
+        target = coveredNodeParent.realTarget;
+      } else if (coveredNodeParent is BinaryExpression) {
+        target = coveredNodeParent.rightOperand;
+      } else {
+        target = coveredNode;
+      }
+    } else if (coveredNode is IndexExpression) {
+      target = (coveredNode as IndexExpression).realTarget;
+    } else if (coveredNodeParent is FunctionExpressionInvocation) {
       target = coveredNode;
+    } else if (coveredNodeParent is AssignmentExpression) {
+      target = coveredNodeParent.rightHandSide;
+    } else if (coveredNode is PostfixExpression) {
+      target = (coveredNode as PostfixExpression).operand;
+    } else if (coveredNode is PrefixExpression) {
+      target = (coveredNode as PrefixExpression).operand;
+    } else if (coveredNode is BinaryExpression) {
+      target = (coveredNode as BinaryExpression).leftOperand;
     } else {
       return;
     }
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_override.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_override.dart
index 92958f1..5f066c3 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/add_override.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_override.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
+
 import 'package:_fe_analyzer_shared/src/scanner/token.dart';
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analysis_server/src/services/correction/fix.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_required.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_required.dart
index 0a5d869..81a242b 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/add_required.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_required.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
+
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
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 8e20c54..4160520 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
@@ -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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_return_type.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_return_type.dart
index b4d5d8d..dbc3d8d 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/add_return_type.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_return_type.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
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analysis_server/src/services/correction/fix.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_static.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_static.dart
index 6f3fa92..f165efc 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/add_static.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_static.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
+
 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';
@@ -15,6 +17,9 @@
   @override
   Future<void> compute(ChangeBuilder builder) async {
     var declaration = node.thisOrAncestorOfType<FieldDeclaration>();
+    if (declaration == null) {
+      return;
+    }
     await builder.addDartFileEdit(file, (builder) {
       var offset = declaration.firstTokenAfterCommentAndMetadata.offset;
       builder.addSimpleInsertion(offset, 'static ');
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_super_constructor_invocation.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_super_constructor_invocation.dart
index 3911cf4..cce07f3 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/add_super_constructor_invocation.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_super_constructor_invocation.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
+
 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/util.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_type_annotation.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_type_annotation.dart
index e2912b0..ef04b02 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/add_type_annotation.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_type_annotation.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
+
 import 'package:_fe_analyzer_shared/src/scanner/token.dart';
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/assign_to_local_variable.dart b/pkg/analysis_server/lib/src/services/correction/dart/assign_to_local_variable.dart
index 4ecdfcf..54e77cf 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/assign_to_local_variable.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/assign_to_local_variable.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
+
 import 'package:analysis_server/src/protocol_server.dart';
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
@@ -19,7 +21,6 @@
   Future<void> compute(ChangeBuilder builder) async {
     // prepare enclosing ExpressionStatement
     ExpressionStatement expressionStatement;
-    // ignore: unnecessary_this
     for (var node = this.node; node != null; node = node.parent) {
       if (node is ExpressionStatement) {
         expressionStatement = node;
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/change_argument_name.dart b/pkg/analysis_server/lib/src/services/correction/dart/change_argument_name.dart
index 34f81c7..c7ff25f 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/change_argument_name.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/change_argument_name.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
+
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analysis_server/src/services/correction/executable_parameters.dart';
 import 'package:analysis_server/src/services/correction/fix.dart';
@@ -51,10 +53,8 @@
         namedExpression is NamedExpression &&
         namedExpression.name == node.parent &&
         namedExpression.parent is ArgumentList) {
-      var parameters = ExecutableParameters(
-        sessionHelper,
-        namedExpression.parent.parent,
-      );
+      var parameters = ExecutableParameters.forInvocation(
+          sessionHelper, namedExpression.parent.parent);
       return parameters?.namedNames;
     }
     return null;
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/change_to.dart b/pkg/analysis_server/lib/src/services/correction/dart/change_to.dart
index c62d89e..7ba2aa2 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/change_to.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/change_to.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
+
 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/levenshtein.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/change_to_nearest_precise_value.dart b/pkg/analysis_server/lib/src/services/correction/dart/change_to_nearest_precise_value.dart
index 5caea4e..ef2e3ba 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/change_to_nearest_precise_value.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/change_to_nearest_precise_value.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/change_to_static_access.dart b/pkg/analysis_server/lib/src/services/correction/dart/change_to_static_access.dart
index 02b291f..69aad4b 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/change_to_static_access.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/change_to_static_access.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/change_type_annotation.dart b/pkg/analysis_server/lib/src/services/correction/dart/change_type_annotation.dart
index 0dfea8a..9aef73e 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/change_type_annotation.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/change_type_annotation.dart
@@ -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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_add_all_to_spread.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_add_all_to_spread.dart
index 181ec8f..06de8b9 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_add_all_to_spread.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_add_all_to_spread.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
+
 import 'package:_fe_analyzer_shared/src/scanner/token.dart';
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_class_to_mixin.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_class_to_mixin.dart
index 00a5ef9..d54b755 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_class_to_mixin.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_class_to_mixin.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
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analyzer/dart/ast/ast.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_conditional_expression_to_if_element.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_conditional_expression_to_if_element.dart
index 5f8cc29..64feabda 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_conditional_expression_to_if_element.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_conditional_expression_to_if_element.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
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analysis_server/src/services/correction/fix.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_documentation_into_block.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_documentation_into_block.dart
index 7068e136..d3e57cf 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_documentation_into_block.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_documentation_into_block.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
+
 import 'package:_fe_analyzer_shared/src/scanner/token.dart';
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_documentation_into_line.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_documentation_into_line.dart
index f82eeca..5b7b37a 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_documentation_into_line.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_documentation_into_line.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
+
 import 'package:_fe_analyzer_shared/src/scanner/token.dart';
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_flutter_child.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_flutter_child.dart
index 3556de0..b767896 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_flutter_child.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_flutter_child.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_flutter_children.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_flutter_children.dart
index 29fd8d0..5e29768 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_flutter_children.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_flutter_children.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_into_async_body.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_into_async_body.dart
index 1ccaff4..5373777 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_into_async_body.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_into_async_body.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
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analyzer/dart/ast/ast.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_into_block_body.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_into_block_body.dart
index 629db9d..20c3d7c 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_into_block_body.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_into_block_body.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
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analyzer/dart/ast/ast.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_into_final_field.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_into_final_field.dart
index 9523790..0cd856c 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_into_final_field.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_into_final_field.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
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analyzer/dart/ast/ast.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_into_for_index.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_into_for_index.dart
index eee7b51..39c4e84 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_into_for_index.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_into_for_index.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
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analyzer/dart/ast/ast.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_into_getter.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_into_getter.dart
index 437bb0b..75b47ca 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_into_getter.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_into_getter.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
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analyzer/dart/ast/ast.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_into_is_not.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_into_is_not.dart
index 114f8d8..d39a67d 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_into_is_not.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_into_is_not.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
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analysis_server/src/services/correction/util.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_into_is_not_empty.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_into_is_not_empty.dart
index 98edb9b..e236dea 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_into_is_not_empty.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_into_is_not_empty.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
+
 import 'package:_fe_analyzer_shared/src/scanner/token.dart';
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_map_from_iterable_to_for_literal.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_map_from_iterable_to_for_literal.dart
index 517a309..20985e4 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_map_from_iterable_to_for_literal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_map_from_iterable_to_for_literal.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
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analysis_server/src/services/correction/fix.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_part_of_to_uri.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_part_of_to_uri.dart
index 246a7e3..e532273 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_part_of_to_uri.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_part_of_to_uri.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
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analyzer/dart/ast/ast.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_quotes.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_quotes.dart
index 0a90211..c853070 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_quotes.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_quotes.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
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analysis_server/src/services/correction/fix.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_contains.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_contains.dart
index d1a5302..7665de9 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_contains.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_contains.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_expression_function_body.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_expression_function_body.dart
index 138adcc..fd38a12 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_expression_function_body.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_expression_function_body.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
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analysis_server/src/services/correction/fix.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_field_parameter.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_field_parameter.dart
index 886c599..ef999da 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_field_parameter.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_field_parameter.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
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analyzer/dart/ast/ast.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_generic_function_syntax.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_generic_function_syntax.dart
index 9b3906c..7b197a4 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_generic_function_syntax.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_generic_function_syntax.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
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analysis_server/src/services/correction/fix.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_if_null.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_if_null.dart
index d8ca1d2..19e52d8 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_if_null.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_if_null.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_int_literal.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_int_literal.dart
index 6ccea99..ed675e7 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_int_literal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_int_literal.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
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analysis_server/src/services/correction/fix.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_list_literal.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_list_literal.dart
index 0f915cd..ba140fa 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_list_literal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_list_literal.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
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analysis_server/src/services/correction/fix.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_map_literal.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_map_literal.dart
index e1c555a..76221ea 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_map_literal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_map_literal.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
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analysis_server/src/services/correction/fix.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_multiline_string.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_multiline_string.dart
index e394659..0dd99aa 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_multiline_string.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_multiline_string.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
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analyzer/dart/ast/ast.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_named_arguments.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_named_arguments.dart
index 5f62701..a4af1c4 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_named_arguments.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_named_arguments.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_normal_parameter.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_normal_parameter.dart
index 9e488f2..b220afd 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_normal_parameter.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_normal_parameter.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
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analyzer/dart/ast/ast.dart';
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 3a92192..5307774 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
@@ -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
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analysis_server/src/services/correction/fix.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_null_aware_spread.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_null_aware_spread.dart
index 765178a..8f54f38 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_null_aware_spread.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_null_aware_spread.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_on_type.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_on_type.dart
index 470c614..ead067d 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_on_type.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_on_type.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_package_import.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_package_import.dart
index 08e3f39..074e90c 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_package_import.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_package_import.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
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analysis_server/src/services/correction/fix.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_relative_import.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_relative_import.dart
index ee82eb3..a312a32 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_relative_import.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_relative_import.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
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analysis_server/src/services/correction/fix.dart';
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 4fcf3c9..fb2b42c 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
@@ -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
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analysis_server/src/services/correction/fix.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_where_type.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_where_type.dart
index 5fe1a84..eb508d4 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_where_type.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_where_type.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/create_class.dart b/pkg/analysis_server/lib/src/services/correction/dart/create_class.dart
index 90624ae..05d4f47 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/create_class.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/create_class.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/create_constructor.dart b/pkg/analysis_server/lib/src/services/correction/dart/create_constructor.dart
index aa2739b..6526f89 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/create_constructor.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/create_constructor.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
+
 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/util.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/create_constructor_for_final_fields.dart b/pkg/analysis_server/lib/src/services/correction/dart/create_constructor_for_final_fields.dart
index 2c879f1..62a920e 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/create_constructor_for_final_fields.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/create_constructor_for_final_fields.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
+
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer/dart/analysis/features.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/create_constructor_super.dart b/pkg/analysis_server/lib/src/services/correction/dart/create_constructor_super.dart
index 23223ba..212261b 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/create_constructor_super.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/create_constructor_super.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
+
 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/util.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/create_field.dart b/pkg/analysis_server/lib/src/services/correction/dart/create_field.dart
index 1a72275..fa00de2 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/create_field.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/create_field.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
+
 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/util.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/create_file.dart b/pkg/analysis_server/lib/src/services/correction/dart/create_file.dart
index e64471b..6dd55bf 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/create_file.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/create_file.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/create_function.dart b/pkg/analysis_server/lib/src/services/correction/dart/create_function.dart
index 05a71da..2351d57 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/create_function.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/create_function.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/create_getter.dart b/pkg/analysis_server/lib/src/services/correction/dart/create_getter.dart
index 5b38e57..3ca2941 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/create_getter.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/create_getter.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
+
 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/util.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/create_local_variable.dart b/pkg/analysis_server/lib/src/services/correction/dart/create_local_variable.dart
index 08cb4f8..42ba1d7 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/create_local_variable.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/create_local_variable.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
+
 import 'package:_fe_analyzer_shared/src/scanner/token.dart';
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analysis_server/src/services/correction/fix.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/create_method.dart b/pkg/analysis_server/lib/src/services/correction/dart/create_method.dart
index 9ded1dc..66397fc 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/create_method.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/create_method.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
+
 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/util.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/create_method_or_function.dart b/pkg/analysis_server/lib/src/services/correction/dart/create_method_or_function.dart
index 166d447..c831928 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/create_method_or_function.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/create_method_or_function.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
+
 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/util.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/create_missing_overrides.dart b/pkg/analysis_server/lib/src/services/correction/dart/create_missing_overrides.dart
index d0fac46..a1e5881 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/create_missing_overrides.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/create_missing_overrides.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
+
 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/utilities/strings.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/create_mixin.dart b/pkg/analysis_server/lib/src/services/correction/dart/create_mixin.dart
index c4a8131..6f783b2 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/create_mixin.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/create_mixin.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/create_no_such_method.dart b/pkg/analysis_server/lib/src/services/correction/dart/create_no_such_method.dart
index aa62503..92af6ca 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/create_no_such_method.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/create_no_such_method.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/create_setter.dart b/pkg/analysis_server/lib/src/services/correction/dart/create_setter.dart
index c89701f..c6c7fc5 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/create_setter.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/create_setter.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
+
 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/util.dart';
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 e4c9bd3..1f2770b 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
@@ -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
+
 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';
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 23d6686..d5aa8b9 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
@@ -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
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analyzer/dart/ast/ast.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/exchange_operands.dart b/pkg/analysis_server/lib/src/services/correction/dart/exchange_operands.dart
index 54bbe13..bb6b9de 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/exchange_operands.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/exchange_operands.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
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analyzer/dart/ast/ast.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/extend_class_for_mixin.dart b/pkg/analysis_server/lib/src/services/correction/dart/extend_class_for_mixin.dart
index a2233818..e9eab92 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/extend_class_for_mixin.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/extend_class_for_mixin.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/flutter_convert_to_children.dart b/pkg/analysis_server/lib/src/services/correction/dart/flutter_convert_to_children.dart
index 5bcc3fc..01cc86a 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/flutter_convert_to_children.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/flutter_convert_to_children.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
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analyzer/dart/ast/ast.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/flutter_convert_to_stateful_widget.dart b/pkg/analysis_server/lib/src/services/correction/dart/flutter_convert_to_stateful_widget.dart
index 80aa9ae..48cf327 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/flutter_convert_to_stateful_widget.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/flutter_convert_to_stateful_widget.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
+
 import 'package:_fe_analyzer_shared/src/scanner/token.dart';
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/flutter_move_down.dart b/pkg/analysis_server/lib/src/services/correction/dart/flutter_move_down.dart
index 1e2fa0f..740afed 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/flutter_move_down.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/flutter_move_down.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
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analyzer/dart/ast/ast.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/flutter_move_up.dart b/pkg/analysis_server/lib/src/services/correction/dart/flutter_move_up.dart
index 8513af7..ec29164 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/flutter_move_up.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/flutter_move_up.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
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analyzer/dart/ast/ast.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/flutter_remove_widget.dart b/pkg/analysis_server/lib/src/services/correction/dart/flutter_remove_widget.dart
index c260fac..0158fbc 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/flutter_remove_widget.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/flutter_remove_widget.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
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analyzer/dart/ast/ast.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/flutter_swap_with_child.dart b/pkg/analysis_server/lib/src/services/correction/dart/flutter_swap_with_child.dart
index c5442e8..c1c46e5 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/flutter_swap_with_child.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/flutter_swap_with_child.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
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analyzer/dart/ast/ast.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/flutter_swap_with_parent.dart b/pkg/analysis_server/lib/src/services/correction/dart/flutter_swap_with_parent.dart
index cfb62b0..a8b9f8b 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/flutter_swap_with_parent.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/flutter_swap_with_parent.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
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/correction/dart/flutter_swap_with_child.dart';
 import 'package:analyzer/dart/ast/ast.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/flutter_wrap.dart b/pkg/analysis_server/lib/src/services/correction/dart/flutter_wrap.dart
index c8c935b..a6400d8 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/flutter_wrap.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/flutter_wrap.dart
@@ -2,13 +2,14 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analysis_server/src/services/correction/selection_analyzer.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/source/source_range.dart';
-import 'package:analyzer/src/dart/ast/ast.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
 import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
 import 'package:analyzer_plugin/utilities/range_factory.dart';
@@ -143,8 +144,7 @@
 
   @override
   List<String> get _leadingLines {
-    var keyword =
-        (widgetExpr as ExpressionImpl).inConstantContext ? '' : ' const';
+    var keyword = widgetExpr.inConstantContext ? '' : ' const';
     return ['padding:$keyword EdgeInsets.all(8.0),'];
   }
 
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/flutter_wrap_generic.dart b/pkg/analysis_server/lib/src/services/correction/dart/flutter_wrap_generic.dart
index 5fcd235..4938af4 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/flutter_wrap_generic.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/flutter_wrap_generic.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
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analyzer/dart/ast/ast.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/flutter_wrap_stream_builder.dart b/pkg/analysis_server/lib/src/services/correction/dart/flutter_wrap_stream_builder.dart
index 4e5535a..50f11bb 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/flutter_wrap_stream_builder.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/flutter_wrap_stream_builder.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
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
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 2b53b99..19ee675 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
@@ -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
+
 import 'dart:collection';
 
 import 'package:analysis_server/src/services/correction/assist.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/import_library.dart b/pkg/analysis_server/lib/src/services/correction/dart/import_library.dart
index da36857..872fd34 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/import_library.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/import_library.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
+
 import 'dart:collection';
 
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/inline_invocation.dart b/pkg/analysis_server/lib/src/services/correction/dart/inline_invocation.dart
index de2dac5..eb35756 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/inline_invocation.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/inline_invocation.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
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analysis_server/src/services/correction/fix.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/inline_typedef.dart b/pkg/analysis_server/lib/src/services/correction/dart/inline_typedef.dart
index 6cc3abd..6790500 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/inline_typedef.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/inline_typedef.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
+
 import 'package:_fe_analyzer_shared/src/scanner/token.dart';
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analysis_server/src/services/correction/fix.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/insert_semicolon.dart b/pkg/analysis_server/lib/src/services/correction/dart/insert_semicolon.dart
index 04ba0b4..8c837c1 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/insert_semicolon.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/insert_semicolon.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/introduce_local_cast_type.dart b/pkg/analysis_server/lib/src/services/correction/dart/introduce_local_cast_type.dart
index af8eb02..c696b43 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/introduce_local_cast_type.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/introduce_local_cast_type.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
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analysis_server/src/services/correction/name_suggestion.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/invert_if_statement.dart b/pkg/analysis_server/lib/src/services/correction/dart/invert_if_statement.dart
index 38e35f2..2fa703ac 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/invert_if_statement.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/invert_if_statement.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
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analyzer/dart/ast/ast.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/join_if_with_inner.dart b/pkg/analysis_server/lib/src/services/correction/dart/join_if_with_inner.dart
index 0c55e56..00337c6 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/join_if_with_inner.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/join_if_with_inner.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
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analysis_server/src/services/correction/util.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/join_if_with_outer.dart b/pkg/analysis_server/lib/src/services/correction/dart/join_if_with_outer.dart
index 1e5ca88..22761fe 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/join_if_with_outer.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/join_if_with_outer.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
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analysis_server/src/services/correction/util.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/join_variable_declaration.dart b/pkg/analysis_server/lib/src/services/correction/dart/join_variable_declaration.dart
index dfa9305..c7713a2 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/join_variable_declaration.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/join_variable_declaration.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
+
 import 'package:_fe_analyzer_shared/src/scanner/token.dart';
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/make_class_abstract.dart b/pkg/analysis_server/lib/src/services/correction/dart/make_class_abstract.dart
index c585b2e..416e4fa 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/make_class_abstract.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/make_class_abstract.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/make_field_not_final.dart b/pkg/analysis_server/lib/src/services/correction/dart/make_field_not_final.dart
index b8db161..ab137eb 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/make_field_not_final.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/make_field_not_final.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/make_final.dart b/pkg/analysis_server/lib/src/services/correction/dart/make_final.dart
index 3ae0f99a..f3063c1 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/make_final.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/make_final.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/make_return_type_nullable.dart b/pkg/analysis_server/lib/src/services/correction/dart/make_return_type_nullable.dart
index 5fdea07..bdc633e 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/make_return_type_nullable.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/make_return_type_nullable.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
+
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer/dart/analysis/features.dart';
@@ -22,18 +24,12 @@
       return;
     }
     var body = node.thisOrAncestorOfType<FunctionBody>();
-    TypeAnnotation returnType;
-    var function = body.parent;
-    if (function is FunctionExpression) {
-      function = function.parent;
-    }
-    if (function is MethodDeclaration) {
-      returnType = function.returnType;
-    } else if (function is FunctionDeclaration) {
-      returnType = function.returnType;
-    } else {
+
+    var returnType = _getReturnTypeNode(body);
+    if (returnType == null) {
       return;
     }
+
     if (body.isAsynchronous || body.isGenerator) {
       if (returnType is! NamedType) {
         return null;
@@ -60,4 +56,17 @@
 
   /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
   static MakeReturnTypeNullable newInstance() => MakeReturnTypeNullable();
+
+  static TypeAnnotation _getReturnTypeNode(FunctionBody body) {
+    var function = body.parent;
+    if (function is FunctionExpression) {
+      function = function.parent;
+    }
+    if (function is MethodDeclaration) {
+      return function.returnType;
+    } else if (function is FunctionDeclaration) {
+      return function.returnType;
+    }
+    return null;
+  }
 }
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/make_variable_not_final.dart b/pkg/analysis_server/lib/src/services/correction/dart/make_variable_not_final.dart
index 276549b..4eb043f 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/make_variable_not_final.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/make_variable_not_final.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
+
 import 'package:_fe_analyzer_shared/src/scanner/token.dart';
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analysis_server/src/services/correction/fix.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/make_variable_nullable.dart b/pkg/analysis_server/lib/src/services/correction/dart/make_variable_nullable.dart
index fcc42fd..62f8696 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/make_variable_nullable.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/make_variable_nullable.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
+
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer/dart/analysis/features.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/move_type_arguments_to_class.dart b/pkg/analysis_server/lib/src/services/correction/dart/move_type_arguments_to_class.dart
index 8381a75..95503c8 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/move_type_arguments_to_class.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/move_type_arguments_to_class.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/organize_imports.dart b/pkg/analysis_server/lib/src/services/correction/dart/organize_imports.dart
index 4c17e69..fc2aa60 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/organize_imports.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/organize_imports.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
+
 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/organize_imports.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/qualify_reference.dart b/pkg/analysis_server/lib/src/services/correction/dart/qualify_reference.dart
index fd81e75..968562b 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/qualify_reference.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/qualify_reference.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_annotation.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_annotation.dart
index 6a6d159..1ab65d1 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_annotation.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_annotation.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_argument.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_argument.dart
index e864bb9..d7a3eda 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_argument.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_argument.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_await.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_await.dart
index b5671b2..c25a7ae 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_await.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_await.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_comparison.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_comparison.dart
index 8802226..617d8e9 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_comparison.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_comparison.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_const.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_const.dart
index 485e7da..c540cec 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_const.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_const.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_dead_code.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_dead_code.dart
index bf9b3f1..3fadc64 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_dead_code.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_dead_code.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_dead_if_null.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_dead_if_null.dart
index 17e9a2d..cff4eb2 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_dead_if_null.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_dead_if_null.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_duplicate_case.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_duplicate_case.dart
index 88e3bfd..d6146ef 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_duplicate_case.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_duplicate_case.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_empty_catch.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_empty_catch.dart
index c2ac9e5..394ee32 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_empty_catch.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_empty_catch.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_empty_constructor_body.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_empty_constructor_body.dart
index 07e6a47..b72c2f2 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_empty_constructor_body.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_empty_constructor_body.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_empty_else.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_empty_else.dart
index 3c07e57..aab2666 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_empty_else.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_empty_else.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_empty_statement.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_empty_statement.dart
index e45057a..ecd86e3 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_empty_statement.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_empty_statement.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_if_null_operator.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_if_null_operator.dart
index 5d75e08..9397912 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_if_null_operator.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_if_null_operator.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_initializer.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_initializer.dart
index a927201..c1b1080 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_initializer.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_initializer.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_interpolation_braces.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_interpolation_braces.dart
index 03ceb42..8d2a673 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_interpolation_braces.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_interpolation_braces.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_method_declaration.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_method_declaration.dart
index db3ac40..d9c0e81 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_method_declaration.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_method_declaration.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_name_from_combinator.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_name_from_combinator.dart
index e0cde53..107f650 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_name_from_combinator.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_name_from_combinator.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_non_null_assertion.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_non_null_assertion.dart
index ff01bf5..79c8910 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_non_null_assertion.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_non_null_assertion.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_operator.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_operator.dart
index 1b44daf..ddbfc3b 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_operator.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_operator.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_parameters_in_getter_declaration.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_parameters_in_getter_declaration.dart
index 281e9a6..0d9cd83 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_parameters_in_getter_declaration.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_parameters_in_getter_declaration.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_parentheses_in_getter_invocation.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_parentheses_in_getter_invocation.dart
index 97e5d0f8..cd52486 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_parentheses_in_getter_invocation.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_parentheses_in_getter_invocation.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_question_mark.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_question_mark.dart
index 378c883..cadd199 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_question_mark.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_question_mark.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_this_expression.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_this_expression.dart
index 0f41278..30fd8a4 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_this_expression.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_this_expression.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_type_annotation.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_type_annotation.dart
index e58c795..997c1ee 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_type_annotation.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_type_annotation.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
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analysis_server/src/services/correction/fix.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_type_arguments.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_type_arguments.dart
index 815154e..9423b86 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_type_arguments.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_type_arguments.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_unnecessary_cast.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_unnecessary_cast.dart
index 1cf53bb..a087d1d 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_unnecessary_cast.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_unnecessary_cast.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_unnecessary_new.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_unnecessary_new.dart
index a613dfd..86e1bf9 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_unnecessary_new.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_unnecessary_new.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_unnecessary_parentheses.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_unnecessary_parentheses.dart
index 7baa9e0..39d7d8c 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_unnecessary_parentheses.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_unnecessary_parentheses.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_unnecessary_string_interpolation.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_unnecessary_string_interpolation.dart
index 6651bf4..a6cf0b9 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_unnecessary_string_interpolation.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_unnecessary_string_interpolation.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
+
 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/util.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_unused.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_unused.dart
index 156be05..700bf1a 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_unused.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_unused.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_catch_clause.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_catch_clause.dart
index 078124e..5981330 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_catch_clause.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_catch_clause.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_catch_stack.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_catch_stack.dart
index a757788..f03e3c7 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_catch_stack.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_catch_stack.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_import.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_import.dart
index 3fa7457..d5336a0 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_import.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_import.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_label.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_label.dart
index 86e508c..9939f3f 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_label.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_label.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_local_variable.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_local_variable.dart
index e3b5cf2..9fe3616 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_local_variable.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_local_variable.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
+
 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/util.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_parameter.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_parameter.dart
index 62037ee..2700eb1 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_parameter.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_parameter.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/rename_to_camel_case.dart b/pkg/analysis_server/lib/src/services/correction/dart/rename_to_camel_case.dart
index 4130747..7e61a0e 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/rename_to_camel_case.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/rename_to_camel_case.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
+
 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/util.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/replace_boolean_with_bool.dart b/pkg/analysis_server/lib/src/services/correction/dart/replace_boolean_with_bool.dart
index 0105fed..5039e9b7 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/replace_boolean_with_bool.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/replace_boolean_with_bool.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
+
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/replace_cascade_with_dot.dart b/pkg/analysis_server/lib/src/services/correction/dart/replace_cascade_with_dot.dart
index eba59da..00d41c3 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/replace_cascade_with_dot.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/replace_cascade_with_dot.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/replace_colon_with_equals.dart b/pkg/analysis_server/lib/src/services/correction/dart/replace_colon_with_equals.dart
index 70f6134..4f9b235 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/replace_colon_with_equals.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/replace_colon_with_equals.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/replace_conditional_with_if_else.dart b/pkg/analysis_server/lib/src/services/correction/dart/replace_conditional_with_if_else.dart
index 197ec2a..adb16a8 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/replace_conditional_with_if_else.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/replace_conditional_with_if_else.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
+
 import 'package:_fe_analyzer_shared/src/scanner/token.dart';
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/replace_final_with_const.dart b/pkg/analysis_server/lib/src/services/correction/dart/replace_final_with_const.dart
index c644020..3a77351 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/replace_final_with_const.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/replace_final_with_const.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/replace_final_with_var.dart b/pkg/analysis_server/lib/src/services/correction/dart/replace_final_with_var.dart
new file mode 100644
index 0000000..58a4a76
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/replace_final_with_var.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for 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 '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_plugin/utilities/change_builder/change_builder_core.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:analyzer_plugin/utilities/range_factory.dart';
+
+class ReplaceFinalWithVar extends CorrectionProducer {
+  @override
+  FixKind get fixKind => DartFixKind.REPLACE_FINAL_WITH_VAR;
+
+  @override
+  FixKind get multiFixKind => DartFixKind.REPLACE_FINAL_WITH_VAR_MULTI;
+
+  @override
+  Future<void> compute(ChangeBuilder builder) async {
+    var target = node;
+    if (target is VariableDeclarationList) {
+      if (target.type == null) {
+        await builder.addDartFileEdit(file, (builder) {
+          builder.addSimpleReplacement(range.token(target.keyword), 'var');
+        });
+      }
+    }
+  }
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static ReplaceFinalWithVar newInstance() => ReplaceFinalWithVar();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/replace_if_else_with_conditional.dart b/pkg/analysis_server/lib/src/services/correction/dart/replace_if_else_with_conditional.dart
index 85e9599..9224921 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/replace_if_else_with_conditional.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/replace_if_else_with_conditional.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
+
 import 'package:_fe_analyzer_shared/src/scanner/token.dart';
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/replace_new_with_const.dart b/pkg/analysis_server/lib/src/services/correction/dart/replace_new_with_const.dart
index 85c1ae0..9a9cd77 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/replace_new_with_const.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/replace_new_with_const.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/replace_null_with_closure.dart b/pkg/analysis_server/lib/src/services/correction/dart/replace_null_with_closure.dart
index 0744780..39aabc2 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/replace_null_with_closure.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/replace_null_with_closure.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/replace_return_type_future.dart b/pkg/analysis_server/lib/src/services/correction/dart/replace_return_type_future.dart
index 6af3d1f..3d0000a 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/replace_return_type_future.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/replace_return_type_future.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/replace_var_with_dynamic.dart b/pkg/analysis_server/lib/src/services/correction/dart/replace_var_with_dynamic.dart
index d0176ed..3da975f 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/replace_var_with_dynamic.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/replace_var_with_dynamic.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
+
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/replace_with_brackets.dart b/pkg/analysis_server/lib/src/services/correction/dart/replace_with_brackets.dart
index eb4fc02..83f4caf 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/replace_with_brackets.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/replace_with_brackets.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/replace_with_conditional_assignment.dart b/pkg/analysis_server/lib/src/services/correction/dart/replace_with_conditional_assignment.dart
index 0d81cddf..e7dfbd2 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/replace_with_conditional_assignment.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/replace_with_conditional_assignment.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/replace_with_eight_digit_hex.dart b/pkg/analysis_server/lib/src/services/correction/dart/replace_with_eight_digit_hex.dart
index 65db348..d0c7229 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/replace_with_eight_digit_hex.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/replace_with_eight_digit_hex.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/replace_with_extension_name.dart b/pkg/analysis_server/lib/src/services/correction/dart/replace_with_extension_name.dart
index 5ebc324..ed7fa48 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/replace_with_extension_name.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/replace_with_extension_name.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/replace_with_filled.dart b/pkg/analysis_server/lib/src/services/correction/dart/replace_with_filled.dart
index 860e620..fc40853 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/replace_with_filled.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/replace_with_filled.dart
@@ -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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/replace_with_identifier.dart b/pkg/analysis_server/lib/src/services/correction/dart/replace_with_identifier.dart
index 9b30817..33d0b66 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/replace_with_identifier.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/replace_with_identifier.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/replace_with_interpolation.dart b/pkg/analysis_server/lib/src/services/correction/dart/replace_with_interpolation.dart
index aaafcb8..77aa027 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/replace_with_interpolation.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/replace_with_interpolation.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/replace_with_is_empty.dart b/pkg/analysis_server/lib/src/services/correction/dart/replace_with_is_empty.dart
index 4238767..9c02fda 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/replace_with_is_empty.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/replace_with_is_empty.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/replace_with_not_null_aware.dart b/pkg/analysis_server/lib/src/services/correction/dart/replace_with_not_null_aware.dart
index 75d20bcb..4cc14c0 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/replace_with_not_null_aware.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/replace_with_not_null_aware.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/replace_with_null_aware.dart b/pkg/analysis_server/lib/src/services/correction/dart/replace_with_null_aware.dart
index 20aeeb9..0f36a39 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/replace_with_null_aware.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/replace_with_null_aware.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/replace_with_tear_off.dart b/pkg/analysis_server/lib/src/services/correction/dart/replace_with_tear_off.dart
index 6d6434f..44df3ff 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/replace_with_tear_off.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/replace_with_tear_off.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
+
 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';
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 64a2f1d..dcdee93 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
@@ -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
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analysis_server/src/services/correction/fix.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/shadow_field.dart b/pkg/analysis_server/lib/src/services/correction/dart/shadow_field.dart
index 2f96ebb..8f4de40 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/shadow_field.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/shadow_field.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
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analyzer/dart/ast/ast.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/sort_child_property_last.dart b/pkg/analysis_server/lib/src/services/correction/dart/sort_child_property_last.dart
index 4475559..6f0d392 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/sort_child_property_last.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/sort_child_property_last.dart
@@ -2,10 +2,13 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 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/token.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
 import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
@@ -45,15 +48,38 @@
     }
 
     await builder.addDartFileEdit(file, (fileEditBuilder) {
-      var start = childProp.beginToken.previous.end;
-      var end = childProp.endToken.next.end;
-      var childRange = range.startOffsetEndOffset(start, end);
+      var hasTrailingComma = last.endToken.next.type == TokenType.COMMA;
 
+      var childStart = childProp.beginToken.previous.end;
+      var childEnd = childProp.endToken.next.end;
+      var childRange = range.startOffsetEndOffset(childStart, childEnd);
+
+      var deletionRange = childRange;
+      if (childProp == args.arguments.first) {
+        var deletionStart = childProp.offset;
+        var deletionEnd = args.arguments[1].offset;
+        deletionRange = range.startOffsetEndOffset(deletionStart, deletionEnd);
+      }
+
+      if (!hasTrailingComma) {
+        childEnd = childProp.end;
+        childRange = range.startOffsetEndOffset(childStart, childEnd);
+      }
       var childText = utils.getRangeText(childRange);
-      fileEditBuilder.addSimpleReplacement(childRange, '');
-      fileEditBuilder.addSimpleInsertion(last.end + 1, childText);
 
-      builder.setSelection(Position(file, last.end + 1));
+      var insertionPoint = last.end;
+      if (hasTrailingComma) {
+        insertionPoint = last.endToken.next.end;
+      } else if (childStart == childProp.offset) {
+        childText = ', $childText';
+      } else {
+        childText = ',$childText';
+      }
+
+      fileEditBuilder.addDeletion(deletionRange);
+      fileEditBuilder.addSimpleInsertion(insertionPoint, childText);
+
+      builder.setSelection(Position(file, insertionPoint));
     });
   }
 
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/split_and_condition.dart b/pkg/analysis_server/lib/src/services/correction/dart/split_and_condition.dart
index 1f38c26..f358b4e8 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/split_and_condition.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/split_and_condition.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
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analysis_server/src/services/correction/util.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/split_variable_declaration.dart b/pkg/analysis_server/lib/src/services/correction/dart/split_variable_declaration.dart
index faac0be..c5b109e 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/split_variable_declaration.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/split_variable_declaration.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
+
 import 'package:_fe_analyzer_shared/src/scanner/token.dart';
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/surround_with.dart b/pkg/analysis_server/lib/src/services/correction/dart/surround_with.dart
index be324d4..e2868bb 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/surround_with.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/surround_with.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
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analysis_server/src/services/correction/statement_analyzer.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/update_sdk_constraints.dart b/pkg/analysis_server/lib/src/services/correction/dart/update_sdk_constraints.dart
index f25d116..dddf351 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/update_sdk_constraints.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/update_sdk_constraints.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
+
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer/file_system/file_system.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/use_const.dart b/pkg/analysis_server/lib/src/services/correction/dart/use_const.dart
index 4ac0dfc..1c9d823 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/use_const.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/use_const.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/use_curly_braces.dart b/pkg/analysis_server/lib/src/services/correction/dart/use_curly_braces.dart
index fc35192..f76e561 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/use_curly_braces.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/use_curly_braces.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
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analysis_server/src/services/correction/fix.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/use_effective_integer_division.dart b/pkg/analysis_server/lib/src/services/correction/dart/use_effective_integer_division.dart
index 7c086e3..babab16 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/use_effective_integer_division.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/use_effective_integer_division.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/use_eq_eq_null.dart b/pkg/analysis_server/lib/src/services/correction/dart/use_eq_eq_null.dart
index 86ad614..ce4e1f4 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/use_eq_eq_null.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/use_eq_eq_null.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/use_is_not_empty.dart b/pkg/analysis_server/lib/src/services/correction/dart/use_is_not_empty.dart
index 665dc9c..ca10cbf 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/use_is_not_empty.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/use_is_not_empty.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/use_not_eq_null.dart b/pkg/analysis_server/lib/src/services/correction/dart/use_not_eq_null.dart
index e53bc02..120e87d 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/use_not_eq_null.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/use_not_eq_null.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/use_rethrow.dart b/pkg/analysis_server/lib/src/services/correction/dart/use_rethrow.dart
index 8c31100..dc55220 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/use_rethrow.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/use_rethrow.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/wrap_in_future.dart b/pkg/analysis_server/lib/src/services/correction/dart/wrap_in_future.dart
index 1ccd887..794bb72 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/wrap_in_future.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/wrap_in_future.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/wrap_in_text.dart b/pkg/analysis_server/lib/src/services/correction/dart/wrap_in_text.dart
index 53776c3..bfd97f5 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/wrap_in_text.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/wrap_in_text.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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/executable_parameters.dart b/pkg/analysis_server/lib/src/services/correction/executable_parameters.dart
index 6f66ef2..30c2497 100644
--- a/pkg/analysis_server/lib/src/services/correction/executable_parameters.dart
+++ b/pkg/analysis_server/lib/src/services/correction/executable_parameters.dart
@@ -17,26 +17,6 @@
   final List<ParameterElement> optionalPositional = [];
   final List<ParameterElement> named = [];
 
-  factory ExecutableParameters(
-      AnalysisSessionHelper sessionHelper, AstNode invocation) {
-    Element element;
-    // This doesn't handle FunctionExpressionInvocation.
-    if (invocation is Annotation) {
-      element = invocation.element;
-    } else if (invocation is InstanceCreationExpression) {
-      element = invocation.constructorName.staticElement;
-    } else if (invocation is MethodInvocation) {
-      element = invocation.methodName.staticElement;
-    } else if (invocation is ConstructorReferenceNode) {
-      element = invocation.staticElement;
-    }
-    if (element is ExecutableElement && !element.isSynthetic) {
-      return ExecutableParameters._(sessionHelper, element);
-    } else {
-      return null;
-    }
-  }
-
   ExecutableParameters._(this.sessionHelper, this.executable) {
     for (var parameter in executable.parameters) {
       if (parameter.isRequiredPositional) {
@@ -59,7 +39,7 @@
 
   /// Return the [FormalParameterList] of the [executable], or `null` if it
   /// can't be found.
-  Future<FormalParameterList> getParameterList() async {
+  Future<FormalParameterList?> getParameterList() async {
     var result = await sessionHelper.getElementDeclaration(executable);
     var targetDeclaration = result?.node;
     if (targetDeclaration is ConstructorDeclaration) {
@@ -75,7 +55,7 @@
 
   /// Return the [FormalParameter] of the [element] in [FormalParameterList],
   /// or `null` if it can't be found.
-  Future<FormalParameter> getParameterNode(ParameterElement element) async {
+  Future<FormalParameter?> getParameterNode(ParameterElement element) async {
     var result = await sessionHelper.getElementDeclaration(element);
     var declaration = result?.node;
     for (var node = declaration; node != null; node = node.parent) {
@@ -85,4 +65,24 @@
     }
     return null;
   }
+
+  static ExecutableParameters? forInvocation(
+      AnalysisSessionHelper sessionHelper, AstNode invocation) {
+    Element? element;
+    // This doesn't handle FunctionExpressionInvocation.
+    if (invocation is Annotation) {
+      element = invocation.element;
+    } else if (invocation is InstanceCreationExpression) {
+      element = invocation.constructorName.staticElement;
+    } else if (invocation is MethodInvocation) {
+      element = invocation.methodName.staticElement;
+    } else if (invocation is ConstructorReferenceNode) {
+      element = invocation.staticElement;
+    }
+    if (element is ExecutableElement && !element.isSynthetic) {
+      return ExecutableParameters._(sessionHelper, element);
+    } else {
+      return null;
+    }
+  }
 }
diff --git a/pkg/analysis_server/lib/src/services/correction/fix.dart b/pkg/analysis_server/lib/src/services/correction/fix.dart
index aac827c..a2190f6 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix.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
+
 import 'package:analysis_server/plugin/edit/fix/fix_dart.dart';
 import 'package:analysis_server/src/services/correction/fix/dart/top_level_declarations.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
@@ -411,6 +413,7 @@
       DartFixKindPriority.DEFAULT, "Create local variable '{0}'");
   static const CREATE_METHOD = FixKind('dart.fix.create.method',
       DartFixKindPriority.DEFAULT, "Create method '{0}'");
+
   // todo (pq): used by LintNames.hash_and_equals; consider removing.
   static const CREATE_METHOD_MULTI = FixKind('dart.fix.create.method.multi',
       DartFixKindPriority.IN_FILE, 'Create methods in file');
@@ -468,6 +471,7 @@
       DartFixKindPriority.DEFAULT, "Make field '{0}' not final");
   static const MAKE_FINAL =
       FixKind('dart.fix.makeFinal', DartFixKindPriority.DEFAULT, 'Make final');
+
   // todo (pq): consider parameterizing: 'Make {fields} final...'
   static const MAKE_FINAL_MULTI = FixKind('dart.fix.makeFinal.multi',
       DartFixKindPriority.IN_FILE, 'Make final where possible in file');
@@ -493,6 +497,7 @@
       DartFixKindPriority.DEFAULT, "Remove the '{0}' annotation");
   static const REMOVE_ARGUMENT = FixKind('dart.fix.remove.argument',
       DartFixKindPriority.DEFAULT, 'Remove argument');
+
   // todo (pq): used by LintNames.avoid_redundant_argument_values; consider a parameterized message
   static const REMOVE_ARGUMENT_MULTI = FixKind('dart.fix.remove.argument.multi',
       DartFixKindPriority.IN_FILE, 'Remove arguments in file');
@@ -508,6 +513,7 @@
       DartFixKindPriority.DEFAULT, 'Remove dead code');
   static const REMOVE_DUPLICATE_CASE = FixKind('dart.fix.remove.duplicateCase',
       DartFixKindPriority.DEFAULT, 'Remove duplicate case statement');
+
   // todo (pq): is this dangerous to bulk apply?  Consider removing.
   static const REMOVE_DUPLICATE_CASE_MULTI = FixKind(
       'dart.fix.remove.duplicateCase.multi',
@@ -567,6 +573,7 @@
       'dart.fix.remove.methodDeclaration',
       DartFixKindPriority.DEFAULT,
       'Remove method declaration');
+
   // todo (pq): parameterize to make scope explicit
   static const REMOVE_METHOD_DECLARATION_MULTI = FixKind(
       'dart.fix.remove.methodDeclaration.multi',
@@ -746,6 +753,12 @@
       'dart.fix.replace.nullWithClosure.multi',
       DartFixKindPriority.IN_FILE,
       "Replace 'null's with closures where possible in file");
+  static const REPLACE_FINAL_WITH_VAR = FixKind('dart.fix.replace.finalWithVar',
+      DartFixKindPriority.DEFAULT, "Replace 'final' with 'var'");
+  static const REPLACE_FINAL_WITH_VAR_MULTI = FixKind(
+      'dart.fix.replace.finalWithVar.multi',
+      DartFixKindPriority.IN_FILE,
+      "Replace 'final' with 'var' where possible in file");
   static const REPLACE_RETURN_TYPE_FUTURE = FixKind(
       'dart.fix.replace.returnTypeFuture',
       DartFixKindPriority.DEFAULT,
@@ -784,6 +797,7 @@
       'dart.fix.replace.withIdentifier',
       DartFixKindPriority.DEFAULT,
       'Replace with identifier');
+
   // todo (pq): parameterize message (used by LintNames.avoid_types_on_closure_parameters)
   static const REPLACE_WITH_IDENTIFIER_MULTI = FixKind(
       'dart.fix.replace.withIdentifier.multi',
@@ -830,7 +844,7 @@
   static const REPLACE_WITH_VAR_MULTI = FixKind(
       'dart.fix.replace.withVar.multi',
       DartFixKindPriority.IN_FILE,
-      "Replace unnecessary type annotations with 'var' in file");
+      "Replace type annotations with 'var' in file");
   static const SORT_CHILD_PROPERTY_LAST = FixKind(
       'dart.fix.sort.childPropertyLast',
       DartFixKindPriority.DEFAULT,
@@ -881,10 +895,3 @@
   static const int DEFAULT = 50;
   static const int IN_FILE = 40;
 }
-
-/// An enumeration of quick fix kinds for the errors found in an Android
-/// manifest file.
-class ManifestFixKind {}
-
-/// An enumeration of quick fix kinds for the errors found in a pubspec file.
-class PubspecFixKind {}
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/analysis_options/fix_generator.dart b/pkg/analysis_server/lib/src/services/correction/fix/analysis_options/fix_generator.dart
index c435c38..31034bf 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix/analysis_options/fix_generator.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix/analysis_options/fix_generator.dart
@@ -2,12 +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.
 
+// @dart = 2.9
+
 import 'dart:math' as math;
 
 import 'package:analysis_server/plugin/edit/fix/fix_core.dart';
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/utilities/strings.dart';
 import 'package:analysis_server/src/utilities/yaml_node_locator.dart';
+import 'package:analyzer/dart/analysis/session.dart';
 import 'package:analyzer/error/error.dart';
 import 'package:analyzer/source/line_info.dart';
 import 'package:analyzer/src/analysis_options/error/option_codes.dart';
@@ -15,6 +18,7 @@
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/lint/options_rule_validator.dart';
 import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_workspace.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 import 'package:yaml/yaml.dart';
 
@@ -169,7 +173,9 @@
     var nodeToDelete = coveringNodePath[index - 1];
     deletionRange ??=
         _lines(nodeToDelete.span.start.offset, nodeToDelete.span.end.offset);
-    var builder = ChangeBuilder();
+    var builder = ChangeBuilder(
+      workspace: _NonDartChangeWorkspace(),
+    );
     await builder.addGenericFileEdit(file, (builder) {
       builder.addDeletion(deletionRange);
     });
@@ -192,3 +198,15 @@
     return SourceRange(startOffset, endOffset - startOffset);
   }
 }
+
+class _NonDartChangeWorkspace implements ChangeWorkspace {
+  @override
+  bool containsFile(String path) {
+    return true;
+  }
+
+  @override
+  AnalysisSession getSession(String path) {
+    throw UnimplementedError('Attempt to work a Dart file.');
+  }
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/dart/top_level_declarations.dart b/pkg/analysis_server/lib/src/services/correction/fix/dart/top_level_declarations.dart
index 5c51d43..e53d57d 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix/dart/top_level_declarations.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix/dart/top_level_declarations.dart
@@ -85,7 +85,7 @@
     return declarations;
   }
 
-  TopLevelDeclarationKind _getTopKind(DeclarationKind kind) {
+  TopLevelDeclarationKind? _getTopKind(DeclarationKind kind) {
     switch (kind) {
       case DeclarationKind.CLASS:
       case DeclarationKind.CLASS_TYPE_ALIAS:
@@ -93,18 +93,14 @@
       case DeclarationKind.FUNCTION_TYPE_ALIAS:
       case DeclarationKind.MIXIN:
         return TopLevelDeclarationKind.type;
-        break;
       case DeclarationKind.EXTENSION:
         return TopLevelDeclarationKind.extension;
-        break;
       case DeclarationKind.FUNCTION:
         return TopLevelDeclarationKind.function;
-        break;
       case DeclarationKind.GETTER:
       case DeclarationKind.SETTER:
       case DeclarationKind.VARIABLE:
         return TopLevelDeclarationKind.variable;
-        break;
       default:
         return null;
     }
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/accessor.dart b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/accessor.dart
index 0d17244..bbfdd2a 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/accessor.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/accessor.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
+
 import 'package:analysis_server/src/services/correction/fix/data_driven/parameter_reference.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 
@@ -49,6 +51,9 @@
     return const InvalidResult();
   }
 
+  @override
+  String toString() => 'arguments[$parameter]';
+
   /// Return the argument list associated with the [node].
   ArgumentList _getArgumentList(AstNode node) {
     if (node is Annotation) {
@@ -106,6 +111,9 @@
     return const InvalidResult();
   }
 
+  @override
+  String toString() => 'typeArguments[$index]';
+
   /// Return the type argument list associated with the [node].
   TypeArgumentList _getTypeArgumentList(AstNode node) {
     if (node is ExtensionOverride) {
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 1dc11da..c75c1dc 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
@@ -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
+
 import 'package:analysis_server/src/services/correction/dart/data_driven.dart';
 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';
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 f73f6ae..2966d55 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
@@ -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
+
 import 'package:analysis_server/src/services/correction/dart/data_driven.dart';
 import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
 
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
index c441575..e8e7a33 100644
--- 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
@@ -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
+
 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';
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 27dd4cb..bebdc17 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
@@ -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
+
 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';
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 4fc44c5..3a89d93 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.
 
+// @dart = 2.9
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/element_descriptor.dart b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/element_descriptor.dart
index ae3f501..9eeedf3 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/element_descriptor.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/element_descriptor.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
+
 import 'package:analysis_server/src/services/correction/fix/data_driven/element_kind.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart' show ClassElement;
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/element_kind.dart b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/element_kind.dart
index c0233f7..be3d61e 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/element_kind.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/element_kind.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
+
 /// An indication of the kind of an element.
 enum ElementKind {
   classKind,
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/element_matcher.dart b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/element_matcher.dart
index d07b075..fe8ba62 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/element_matcher.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/element_matcher.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
+
 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:analyzer/dart/ast/ast.dart';
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
index 96651b9..3a554d3 100644
--- 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
@@ -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
+
 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';
 
@@ -41,6 +43,9 @@
     }
     return null;
   }
+
+  @override
+  String toString() => '$leftOperand ${operator.displayName} $rightOperand';
 }
 
 /// An expression.
@@ -61,6 +66,9 @@
   String evaluateIn(TemplateContext context) {
     return value;
   }
+
+  @override
+  String toString() => '"$value"';
 }
 
 /// An operator used in a binary expression.
@@ -83,4 +91,21 @@
   String evaluateIn(TemplateContext context) {
     return generator.evaluateIn(context);
   }
+
+  @override
+  String toString() => '{$generator}';
+}
+
+extension on Operator {
+  String get displayName {
+    switch (this) {
+      case Operator.and:
+        return '&&';
+      case Operator.equal:
+        return '==';
+      case Operator.notEqual:
+        return '!=';
+    }
+    return 'impossible';
+  }
 }
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 c472d13..76ec8f6 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
@@ -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
+
 import 'package:analysis_server/src/services/correction/dart/data_driven.dart';
 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';
@@ -92,6 +94,7 @@
       }
     }
     argumentsToInsert.sort();
+    argumentsToDelete.sort();
 
     /// Write to the [builder] the argument associated with a single
     /// [parameter].
@@ -202,8 +205,20 @@
     // The remaining deletion ranges are now ready to be removed.
     //
     for (var subRange in deletionRanges) {
-      builder.addDeletion(range.argumentRange(
-          argumentList, subRange.lower, subRange.upper, true));
+      var lower = subRange.lower;
+      var upper = subRange.upper;
+      if (lower == 0 &&
+          upper == arguments.length - 1 &&
+          insertionRanges.isNotEmpty) {
+        // We're removing all of the existing arguments but we've already
+        // inserted new arguments between the parentheses. We need to handle
+        // this case specially because the default code would cause a
+        // `ConflictingEditException`.
+        builder.addDeletion(range.startEnd(arguments[lower], arguments[upper]));
+      } else {
+        builder
+            .addDeletion(range.argumentRange(argumentList, lower, upper, true));
+      }
     }
   }
 
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/parameter_reference.dart b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/parameter_reference.dart
index e67f425..662a953 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/parameter_reference.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/parameter_reference.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
+
 import 'package:analyzer/dart/ast/ast.dart';
 
 /// A reference to a named parameter.
@@ -22,6 +24,9 @@
     }
     return null;
   }
+
+  @override
+  String toString() => name;
 }
 
 /// A reference to a formal parameter.
@@ -54,4 +59,7 @@
     }
     return argument;
   }
+
+  @override
+  String toString() => '$index';
 }
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 58eb217..b7958ad9 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
@@ -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
+
 import 'package:analysis_server/src/services/correction/dart/data_driven.dart';
 import 'package:analysis_server/src/services/correction/fix/data_driven/change.dart';
 import 'package:analyzer/dart/ast/ast.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/rename_parameter.dart b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/rename_parameter.dart
index 97065b7..7f9dbac 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/rename_parameter.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/rename_parameter.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
+
 import 'package:analysis_server/src/services/correction/dart/data_driven.dart';
 import 'package:analysis_server/src/services/correction/fix/data_driven/change.dart';
 import 'package:analyzer/dart/ast/ast.dart';
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 0a60dd7..cc03b29 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,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
+
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_override.dart b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_override.dart
index abb7246..b873aba 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_override.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_override.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
+
 import 'package:meta/meta.dart';
 
 /// A description of a set of changes to a single transform.
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_override_set.dart b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_override_set.dart
index 597efde..9b18a0f 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_override_set.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_override_set.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
+
 import 'package:analysis_server/src/services/correction/fix/data_driven/transform_override.dart';
 
 /// A description of a set of transform overrides.
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_override_set_parser.dart b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_override_set_parser.dart
index 58abf49..30c3995 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_override_set_parser.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_override_set_parser.dart
@@ -2,12 +2,14 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix/data_driven/transform_override.dart';
 import 'package:analysis_server/src/services/correction/fix/data_driven/transform_override_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/transform_set_parser.dart';
-import 'package:analysis_server/src/utilities/extensions/yaml.dart';
 import 'package:analyzer/error/listener.dart';
+import 'package:analyzer/src/util/yaml.dart';
 import 'package:yaml/yaml.dart';
 
 /// A parser used to parse the content of a configuration file.
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set.dart b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set.dart
index de1b7dd..5ef1a7a 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set.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
+
 import 'package:analysis_server/src/services/correction/fix/data_driven/element_matcher.dart';
 import 'package:analysis_server/src/services/correction/fix/data_driven/transform.dart';
 import 'package:analysis_server/src/services/correction/fix/data_driven/transform_override_set.dart';
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 508635c..10a8af9 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
@@ -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
+
 // ignore_for_file: prefer_single_quotes, slash_for_doc_comments
 import 'package:analyzer/error/error.dart';
 
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set_manager.dart b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set_manager.dart
index 23ad911..38f3aa0 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set_manager.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set_manager.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
+
 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_parser.dart';
 import 'package:analyzer/dart/element/element.dart';
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 b0c122c..eb162b3 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
@@ -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
+
 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';
@@ -19,8 +21,8 @@
 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:analyzer/src/util/yaml.dart';
 import 'package:meta/meta.dart';
 import 'package:yaml/yaml.dart';
 
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 527669f..fc9b2fb 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
@@ -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
+
 import 'package:analysis_server/src/services/correction/fix/data_driven/accessor.dart';
 import 'package:analysis_server/src/services/correction/fix/data_driven/code_template.dart';
 import 'package:analyzer/dart/ast/ast.dart';
@@ -40,6 +42,9 @@
   }
 
   @override
+  String toString() => accessors.join('.');
+
+  @override
   bool validate(TemplateContext context) {
     Object target = context.node;
     for (var accessor in accessors) {
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
index 0ae0c27..6137a32 100644
--- 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
@@ -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
+
 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.
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/manifest/fix_generator.dart b/pkg/analysis_server/lib/src/services/correction/fix/manifest/fix_generator.dart
index ebc7431..1cc8e81 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix/manifest/fix_generator.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix/manifest/fix_generator.dart
@@ -14,7 +14,6 @@
 import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 import 'package:html/dom.dart';
-import 'package:meta/meta.dart';
 
 /// An object used to locate the HTML [Node] associated with a source range.
 /// More specifically, it will return the deepest HTML [Node] which completely
@@ -31,7 +30,7 @@
   ///
   /// If the [end] offset is not provided, then it is considered the same as the
   /// [start] offset.
-  HtmlNodeLocator({@required int start, int end})
+  HtmlNodeLocator({required int start, int? end})
       : _startOffset = start,
         _endOffset = end ?? start;
 
@@ -47,8 +46,10 @@
 
   void _searchWithin(List<Node> path, Node node) {
     var span = node.sourceSpan;
-    if (span.start.offset > _endOffset || span.end.offset < _startOffset) {
-      return;
+    if (span != null) {
+      if (span.start.offset > _endOffset || span.end.offset < _startOffset) {
+        return;
+      }
     }
     for (var element in node.children) {
       _searchWithin(path, element);
@@ -77,7 +78,7 @@
 
   final List<Fix> fixes = <Fix>[];
 
-  List<Node> coveringNodePath;
+  // List<Node> coveringNodePath;
 
   ManifestFixGenerator(this.error, this.content, this.document)
       : errorOffset = error.offset,
@@ -90,12 +91,12 @@
 
   /// Return the list of fixes that apply to the error being fixed.
   Future<List<Fix>> computeFixes() async {
-    var locator =
-        HtmlNodeLocator(start: errorOffset, end: errorOffset + errorLength - 1);
-    coveringNodePath = locator.searchWithin(document);
-    if (coveringNodePath.isEmpty) {
-      return fixes;
-    }
+    // var locator =
+    //     HtmlNodeLocator(start: errorOffset, end: errorOffset + errorLength - 1);
+    // coveringNodePath = locator.searchWithin(document);
+    // if (coveringNodePath.isEmpty) {
+    //   return fixes;
+    // }
 
     var errorCode = error.errorCode;
     if (errorCode == ManifestWarningCode.UNSUPPORTED_CHROME_OS_HARDWARE) {
@@ -110,7 +111,7 @@
   /// [kind]. If [args] are provided, they will be used to fill in the message
   /// for the fix.
   // ignore: unused_element
-  void _addFixFromBuilder(ChangeBuilder builder, FixKind kind, {List args}) {
+  void _addFixFromBuilder(ChangeBuilder builder, FixKind kind, {List? args}) {
     var change = builder.sourceChange;
     if (change.edits.isEmpty) {
       return;
@@ -129,9 +130,9 @@
 
   // ignore: unused_element
   SourceRange _lines(int start, int end) {
-    CharacterLocation startLocation = lineInfo.getLocation(start);
+    var startLocation = lineInfo.getLocation(start);
     var startOffset = lineInfo.getOffsetOfLine(startLocation.lineNumber - 1);
-    CharacterLocation endLocation = lineInfo.getLocation(end);
+    var endLocation = lineInfo.getLocation(end);
     var endOffset = lineInfo.getOffsetOfLine(
         math.min(endLocation.lineNumber, lineInfo.lineCount - 1));
     return SourceRange(startOffset, endOffset - startOffset);
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/pubspec/fix_generator.dart b/pkg/analysis_server/lib/src/services/correction/fix/pubspec/fix_generator.dart
index d82b128..f21a745 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix/pubspec/fix_generator.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix/pubspec/fix_generator.dart
@@ -6,7 +6,6 @@
 
 import 'package:analysis_server/plugin/edit/fix/fix_core.dart';
 import 'package:analysis_server/src/utilities/strings.dart';
-import 'package:analysis_server/src/utilities/yaml_node_locator.dart';
 import 'package:analyzer/error/error.dart';
 import 'package:analyzer/source/line_info.dart';
 import 'package:analyzer/src/generated/java_core.dart';
@@ -32,7 +31,7 @@
 
   final List<Fix> fixes = <Fix>[];
 
-  List<YamlNode> coveringNodePath;
+  // List<YamlNode> coveringNodePath;
 
   PubspecFixGenerator(this.error, this.content, this.options)
       : errorOffset = error.offset,
@@ -45,12 +44,12 @@
 
   /// Return the list of fixes that apply to the error being fixed.
   Future<List<Fix>> computeFixes() async {
-    var locator =
-        YamlNodeLocator(start: errorOffset, end: errorOffset + errorLength - 1);
-    coveringNodePath = locator.searchWithin(options);
-    if (coveringNodePath.isEmpty) {
-      return fixes;
-    }
+    // var locator =
+    //     YamlNodeLocator(start: errorOffset, end: errorOffset + errorLength - 1);
+    // coveringNodePath = locator.searchWithin(options);
+    // if (coveringNodePath.isEmpty) {
+    //   return fixes;
+    // }
 
     var errorCode = error.errorCode;
     if (errorCode == PubspecWarningCode.ASSET_DOES_NOT_EXIST) {
@@ -69,7 +68,7 @@
   /// [kind]. If [args] are provided, they will be used to fill in the message
   /// for the fix.
   // ignore: unused_element
-  void _addFixFromBuilder(ChangeBuilder builder, FixKind kind, {List args}) {
+  void _addFixFromBuilder(ChangeBuilder builder, FixKind kind, {List? args}) {
     var change = builder.sourceChange;
     if (change.edits.isEmpty) {
       return;
@@ -88,9 +87,9 @@
 
   // ignore: unused_element
   SourceRange _lines(int start, int end) {
-    CharacterLocation startLocation = lineInfo.getLocation(start);
+    var startLocation = lineInfo.getLocation(start);
     var startOffset = lineInfo.getOffsetOfLine(startLocation.lineNumber - 1);
-    CharacterLocation endLocation = lineInfo.getLocation(end);
+    var endLocation = lineInfo.getLocation(end);
     var endOffset = lineInfo.getOffsetOfLine(
         math.min(endLocation.lineNumber, lineInfo.lineCount - 1));
     return SourceRange(startOffset, endOffset - startOffset);
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 0f39775..dfc9b79 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.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
+
 import 'dart:core';
 
 import 'package:analysis_server/plugin/edit/fix/fix_core.dart';
@@ -127,6 +129,7 @@
 import 'package:analysis_server/src/services/correction/dart/replace_cascade_with_dot.dart';
 import 'package:analysis_server/src/services/correction/dart/replace_colon_with_equals.dart';
 import 'package:analysis_server/src/services/correction/dart/replace_final_with_const.dart';
+import 'package:analysis_server/src/services/correction/dart/replace_final_with_var.dart';
 import 'package:analysis_server/src/services/correction/dart/replace_new_with_const.dart';
 import 'package:analysis_server/src/services/correction/dart/replace_null_with_closure.dart';
 import 'package:analysis_server/src/services/correction/dart/replace_return_type_future.dart';
@@ -280,7 +283,7 @@
       ErrorCode errorCode, CorrectionProducerContext context) {
     var producers = <ProducerGenerator>[];
     if (errorCode is LintCode) {
-      var fixInfos = FixProcessor.lintProducerMap2[errorCode.name] ?? [];
+      var fixInfos = FixProcessor.lintProducerMap[errorCode.name] ?? [];
       for (var fixInfo in fixInfos) {
         if (fixInfo.canBeAppliedToFile) {
           producers.addAll(fixInfo.generators);
@@ -368,10 +371,22 @@
         ],
       ),
     ],
+    StaticWarningCode.UNNECESSARY_NON_NULL_ASSERTION: [
+      FixInfo(
+        // todo (pq): consider adding
+        canBeAppliedToFile: false,
+        canBeBulkApplied: true,
+        generators: [
+          RemoveNonNullAssertion.newInstance,
+        ],
+      ),
+    ],
   };
 
-  /// todo (pq): to replace lintProducerMap.
-  static const Map<String, List<FixInfo>> lintProducerMap2 = {
+  /// A map from the names of lint rules to a list of generators used to create
+  /// the correction producers used to build fixes for those diagnostics. The
+  /// generators used for non-lint diagnostics are in the [nonLintProducerMap].
+  static const Map<String, List<FixInfo>> lintProducerMap = {
     LintNames.always_declare_return_types: [
       FixInfo(
         // todo (pq): enable when tested
@@ -954,6 +969,15 @@
         ],
       )
     ],
+    LintNames.unnecessary_final: [
+      FixInfo(
+        canBeAppliedToFile: true,
+        canBeBulkApplied: true,
+        generators: [
+          ReplaceFinalWithVar.newInstance,
+        ],
+      )
+    ],
     LintNames.unnecessary_lambdas: [
       FixInfo(
         canBeAppliedToFile: true,
@@ -1057,237 +1081,6 @@
     ],
   };
 
-  /// A map from the names of lint rules to a list of generators used to create
-  /// the correction producers used to build fixes for those diagnostics. The
-  /// generators used for non-lint diagnostics are in the [nonLintProducerMap].
-  static const Map<String, List<ProducerGenerator>> lintProducerMap = {
-    LintNames.always_declare_return_types: [
-      AddReturnType.newInstance,
-    ],
-    LintNames.always_require_non_null_named_parameters: [
-      AddRequired.newInstance,
-    ],
-    LintNames.always_specify_types: [
-      AddTypeAnnotation.newInstance,
-    ],
-    LintNames.annotate_overrides: [
-      AddOverride.newInstance,
-    ],
-    LintNames.avoid_annotating_with_dynamic: [
-      RemoveTypeAnnotation.newInstance,
-    ],
-    LintNames.avoid_empty_else: [
-      RemoveEmptyElse.newInstance,
-    ],
-    LintNames.avoid_init_to_null: [
-      RemoveInitializer.newInstance,
-    ],
-    LintNames.avoid_private_typedef_functions: [
-      InlineTypedef.newInstance,
-    ],
-    LintNames.avoid_redundant_argument_values: [
-      RemoveArgument.newInstance,
-    ],
-    LintNames.avoid_relative_lib_imports: [
-      ConvertToPackageImport.newInstance,
-    ],
-    LintNames.avoid_return_types_on_setters: [
-      RemoveTypeAnnotation.newInstance,
-    ],
-    LintNames.avoid_returning_null_for_future: [
-      AddAsync.newInstance,
-      WrapInFuture.newInstance,
-    ],
-    LintNames.avoid_single_cascade_in_expression_statements: [
-      // TODO(brianwilkerson) This fix should be applied to some non-lint
-      //  diagnostics and should also be available as an assist.
-      ReplaceCascadeWithDot.newInstance,
-    ],
-    LintNames.avoid_types_as_parameter_names: [
-      ConvertToOnType.newInstance,
-    ],
-    LintNames.avoid_types_on_closure_parameters: [
-      ReplaceWithIdentifier.newInstance,
-      RemoveTypeAnnotation.newInstance,
-    ],
-    LintNames.avoid_unused_constructor_parameters: [
-      RemoveUnusedParameter.newInstance,
-    ],
-    LintNames.await_only_futures: [
-      RemoveAwait.newInstance,
-    ],
-    LintNames.curly_braces_in_flow_control_structures: [
-      UseCurlyBraces.newInstance,
-    ],
-    LintNames.diagnostic_describe_all_properties: [
-      AddDiagnosticPropertyReference.newInstance,
-    ],
-    LintNames.directives_ordering: [
-      OrganizeImports.newInstance,
-    ],
-    LintNames.empty_catches: [
-      RemoveEmptyCatch.newInstance,
-    ],
-    LintNames.empty_constructor_bodies: [
-      RemoveEmptyConstructorBody.newInstance,
-    ],
-    LintNames.empty_statements: [
-      RemoveEmptyStatement.newInstance,
-      ReplaceWithBrackets.newInstance,
-    ],
-    LintNames.hash_and_equals: [
-      CreateMethod.equalsOrHashCode,
-    ],
-    LintNames.no_duplicate_case_values: [
-      RemoveDuplicateCase.newInstance,
-    ],
-    LintNames.non_constant_identifier_names: [
-      RenameToCamelCase.newInstance,
-    ],
-    LintNames.null_closures: [
-      ReplaceNullWithClosure.newInstance,
-    ],
-    LintNames.omit_local_variable_types: [
-      ReplaceWithVar.newInstance,
-    ],
-    LintNames.prefer_adjacent_string_concatenation: [
-      RemoveOperator.newInstance,
-    ],
-    LintNames.prefer_collection_literals: [
-      ConvertToListLiteral.newInstance,
-      ConvertToMapLiteral.newInstance,
-      ConvertToSetLiteral.newInstance,
-    ],
-    LintNames.prefer_conditional_assignment: [
-      ReplaceWithConditionalAssignment.newInstance,
-    ],
-    LintNames.prefer_const_constructors: [
-      AddConst.newInstance,
-      ReplaceNewWithConst.newInstance,
-    ],
-    LintNames.prefer_const_constructors_in_immutables: [
-      AddConst.newInstance,
-    ],
-    LintNames.prefer_const_declarations: [
-      ReplaceFinalWithConst.newInstance,
-    ],
-    LintNames.prefer_contains: [
-      ConvertToContains.newInstance,
-    ],
-    LintNames.prefer_equal_for_default_values: [
-      ReplaceColonWithEquals.newInstance,
-    ],
-    LintNames.prefer_expression_function_bodies: [
-      ConvertToExpressionFunctionBody.newInstance,
-    ],
-    LintNames.prefer_final_fields: [
-      MakeFinal.newInstance,
-    ],
-    LintNames.prefer_final_in_for_each: [
-      MakeFinal.newInstance,
-    ],
-    LintNames.prefer_final_locals: [
-      MakeFinal.newInstance,
-    ],
-    LintNames.prefer_for_elements_to_map_fromIterable: [
-      ConvertMapFromIterableToForLiteral.newInstance,
-    ],
-    LintNames.prefer_generic_function_type_aliases: [
-      ConvertToGenericFunctionSyntax.newInstance,
-    ],
-    LintNames.prefer_if_elements_to_conditional_expressions: [
-      ConvertConditionalExpressionToIfElement.newInstance,
-    ],
-    LintNames.prefer_is_empty: [
-      ReplaceWithIsEmpty.newInstance,
-    ],
-    LintNames.prefer_is_not_empty: [
-      UseIsNotEmpty.newInstance,
-    ],
-    LintNames.prefer_if_null_operators: [
-      ConvertToIfNull.newInstance,
-    ],
-    LintNames.prefer_inlined_adds: [
-      ConvertAddAllToSpread.newInstance,
-      InlineInvocation.newInstance,
-    ],
-    LintNames.prefer_int_literals: [
-      ConvertToIntLiteral.newInstance,
-    ],
-    LintNames.prefer_interpolation_to_compose_strings: [
-      ReplaceWithInterpolation.newInstance,
-    ],
-    LintNames.prefer_iterable_whereType: [
-      ConvertToWhereType.newInstance,
-    ],
-    LintNames.prefer_null_aware_operators: [
-      ConvertToNullAware.newInstance,
-    ],
-    LintNames.prefer_relative_imports: [
-      ConvertToRelativeImport.newInstance,
-    ],
-    LintNames.prefer_single_quotes: [
-      ConvertToSingleQuotes.newInstance,
-    ],
-    LintNames.prefer_spread_collections: [
-      ConvertAddAllToSpread.newInstance,
-    ],
-    LintNames.slash_for_doc_comments: [
-      ConvertDocumentationIntoLine.newInstance,
-    ],
-    LintNames.sort_child_properties_last: [
-      SortChildPropertyLast.newInstance,
-    ],
-    LintNames.type_annotate_public_apis: [
-      AddTypeAnnotation.newInstance,
-    ],
-    LintNames.type_init_formals: [
-      RemoveTypeAnnotation.newInstance,
-    ],
-    LintNames.unawaited_futures: [
-      AddAwait.newInstance,
-    ],
-    LintNames.unnecessary_brace_in_string_interps: [
-      RemoveInterpolationBraces.newInstance,
-    ],
-    LintNames.unnecessary_const: [
-      RemoveUnnecessaryConst.newInstance,
-    ],
-    LintNames.unnecessary_lambdas: [
-      ReplaceWithTearOff.newInstance,
-    ],
-    LintNames.unnecessary_new: [
-      RemoveUnnecessaryNew.newInstance,
-    ],
-    LintNames.unnecessary_null_in_if_null_operators: [
-      RemoveIfNullOperator.newInstance,
-    ],
-    LintNames.unnecessary_nullable_for_final_variable_declarations: [
-      RemoveQuestionMark.newInstance,
-    ],
-    LintNames.unnecessary_overrides: [
-      RemoveMethodDeclaration.newInstance,
-    ],
-    LintNames.unnecessary_parenthesis: [
-      RemoveUnnecessaryParentheses.newInstance,
-    ],
-    LintNames.unnecessary_string_interpolations: [
-      RemoveUnnecessaryStringInterpolation.newInstance,
-    ],
-    LintNames.unnecessary_this: [
-      RemoveThisExpression.newInstance,
-    ],
-    LintNames.use_full_hex_values_for_flutter_colors: [
-      ReplaceWithEightDigitHex.newInstance,
-    ],
-    LintNames.use_function_type_syntax_for_parameters: [
-      ConvertToGenericFunctionSyntax.newInstance,
-    ],
-    LintNames.use_rethrow_when_possible: [
-      UseRethrow.newInstance,
-    ],
-  };
-
   /// A map from error codes to a list of generators used to create multiple
   /// correction producers used to build fixes for those diagnostics. The
   /// generators used for lint rules are in the [lintMultiProducerMap].
@@ -1983,9 +1776,9 @@
 
     var errorCode = error.errorCode;
     if (errorCode is LintCode) {
-      var generators = lintProducerMap[errorCode.name];
-      if (generators != null) {
-        for (var generator in generators) {
+      var fixes = lintProducerMap[errorCode.name] ?? [];
+      for (var fix in fixes) {
+        for (var generator in fix.generators) {
           await compute(generator());
         }
       }
diff --git a/pkg/analysis_server/lib/src/services/correction/levenshtein.dart b/pkg/analysis_server/lib/src/services/correction/levenshtein.dart
index 42f8cda..8f0e934 100644
--- a/pkg/analysis_server/lib/src/services/correction/levenshtein.dart
+++ b/pkg/analysis_server/lib/src/services/correction/levenshtein.dart
@@ -22,9 +22,6 @@
 /// distance algorithm.
 int levenshtein(String s, String t, int threshold,
     {bool caseSensitive = true}) {
-  if (s == null || t == null) {
-    throw ArgumentError('Strings must not be null');
-  }
   if (threshold < 0) {
     throw ArgumentError('Threshold must not be negative');
   }
diff --git a/pkg/analysis_server/lib/src/services/correction/name_suggestion.dart b/pkg/analysis_server/lib/src/services/correction/name_suggestion.dart
index a06b069..f501ed0 100644
--- a/pkg/analysis_server/lib/src/services/correction/name_suggestion.dart
+++ b/pkg/analysis_server/lib/src/services/correction/name_suggestion.dart
@@ -25,17 +25,17 @@
 
 /// Returns possible names for a variable with the given expected type and
 /// expression assigned.
-List<String> getVariableNameSuggestionsForExpression(
-    DartType expectedType, Expression assignedExpression, Set<String> excluded,
+List<String> getVariableNameSuggestionsForExpression(DartType? expectedType,
+    Expression? assignedExpression, Set<String> excluded,
     {bool isMethod = false}) {
-  String prefix;
+  String? prefix;
 
   if (isMethod) {
     // If we're in a build() method, use 'build' as the name prefix.
-    var method = assignedExpression.thisOrAncestorOfType<MethodDeclaration>();
+    var method = assignedExpression?.thisOrAncestorOfType<MethodDeclaration>();
     if (method != null) {
-      var enclosingName = method.name?.name;
-      if (enclosingName != null && enclosingName.startsWith('build')) {
+      var enclosingName = method.name.name;
+      if (enclosingName.startsWith('build')) {
         prefix = 'build';
       }
     }
@@ -46,7 +46,9 @@
   if (assignedExpression != null) {
     var nameFromExpression = _getBaseNameFromExpression(assignedExpression);
     if (nameFromExpression != null) {
-      nameFromExpression = removeStart(nameFromExpression, '_');
+      if (nameFromExpression.startsWith('_')) {
+        nameFromExpression = nameFromExpression.substring(1);
+      }
       _addAll(excluded, res, getCamelWordCombinations(nameFromExpression),
           prefix: prefix);
     }
@@ -93,7 +95,8 @@
     for (var i = 0; i < words.length; i++) {
       var word = words[i];
       if (i > 0) {
-        word = capitalize(word);
+        // `capitalize` won't return `null` unless `null` is passed in.
+        word = capitalize(word)!;
       }
       sb.write(word);
     }
@@ -107,7 +110,7 @@
 
 /// Adds [toAdd] items which are not excluded.
 void _addAll(Set<String> excluded, Set<String> result, Iterable<String> toAdd,
-    {String prefix}) {
+    {String? prefix}) {
   for (var item in toAdd) {
     // add name based on "item", but not "excluded"
     for (var suffix = 1;; suffix++) {
@@ -139,7 +142,7 @@
   }
 }
 
-String _getBaseNameFromExpression(Expression expression) {
+String? _getBaseNameFromExpression(Expression expression) {
   if (expression is AsExpression) {
     return _getBaseNameFromExpression(expression.expression);
   } else if (expression is ParenthesizedExpression) {
@@ -148,7 +151,7 @@
   return _getBaseNameFromUnwrappedExpression(expression);
 }
 
-String _getBaseNameFromLocationInParent(Expression expression) {
+String? _getBaseNameFromLocationInParent(Expression expression) {
   // value in named expression
   if (expression.parent is NamedExpression) {
     var namedExpression = expression.parent as NamedExpression;
@@ -165,8 +168,8 @@
   return null;
 }
 
-String _getBaseNameFromUnwrappedExpression(Expression expression) {
-  String name;
+String? _getBaseNameFromUnwrappedExpression(Expression expression) {
+  String? name;
   // analyze expressions
   if (expression is SimpleIdentifier) {
     return expression.name;
@@ -179,22 +182,20 @@
   } else if (expression is InstanceCreationExpression) {
     var constructorName = expression.constructorName;
     var typeName = constructorName.type;
-    if (typeName != null) {
-      var typeNameIdentifier = typeName.name;
-      // new ClassName()
-      if (typeNameIdentifier is SimpleIdentifier) {
-        return typeNameIdentifier.name;
+    var typeNameIdentifier = typeName.name;
+    // new ClassName()
+    if (typeNameIdentifier is SimpleIdentifier) {
+      return typeNameIdentifier.name;
+    }
+    // new prefix.name();
+    if (typeNameIdentifier is PrefixedIdentifier) {
+      var prefixed = typeNameIdentifier;
+      // new prefix.ClassName()
+      if (prefixed.prefix.staticElement is PrefixElement) {
+        return prefixed.identifier.name;
       }
-      // new prefix.name();
-      if (typeNameIdentifier is PrefixedIdentifier) {
-        var prefixed = typeNameIdentifier;
-        // new prefix.ClassName()
-        if (prefixed.prefix.staticElement is PrefixElement) {
-          return prefixed.identifier.name;
-        }
-        // new ClassName.constructorName()
-        return prefixed.prefix.name;
-      }
+      // new ClassName.constructorName()
+      return prefixed.prefix.name;
     }
   } else if (expression is IndexExpression) {
     name = _getBaseNameFromExpression(expression.realTarget);
diff --git a/pkg/analysis_server/lib/src/services/correction/namespace.dart b/pkg/analysis_server/lib/src/services/correction/namespace.dart
index f80cee9..affc53d 100644
--- a/pkg/analysis_server/lib/src/services/correction/namespace.dart
+++ b/pkg/analysis_server/lib/src/services/correction/namespace.dart
@@ -7,28 +7,28 @@
 import 'package:analyzer/src/dart/resolver/scope.dart';
 
 /// Returns the [Element] exported from the given [LibraryElement].
-Element getExportedElement(LibraryElement library, String name) {
+Element? getExportedElement(LibraryElement? library, String name) {
   if (library == null) {
     return null;
   }
-  return getExportNamespaceForLibrary(library)[name];
-}
-
-/// Returns the export namespace of the given [LibraryElement].
-Map<String, Element> getExportNamespaceForLibrary(LibraryElement library) {
-  var namespace = NamespaceBuilder().createExportNamespaceForLibrary(library);
-  return namespace.definedNames;
+  return _getExportNamespaceForLibrary(library)[name];
 }
 
 /// Return the [ImportElement] that is referenced by [prefixNode], or `null` if
 /// the node does not reference a prefix or if we cannot determine which import
 /// is being referenced.
-ImportElement getImportElement(SimpleIdentifier prefixNode) {
+ImportElement? getImportElement(SimpleIdentifier prefixNode) {
   var parent = prefixNode.parent;
   if (parent is ImportDirective) {
     return parent.element;
   }
-  return internal_getImportElementInfo(prefixNode);
+  return _getImportElementInfo(prefixNode);
+}
+
+/// Returns the export namespace of the given [LibraryElement].
+Map<String, Element> _getExportNamespaceForLibrary(LibraryElement library) {
+  var namespace = NamespaceBuilder().createExportNamespaceForLibrary(library);
+  return namespace.definedNames;
 }
 
 /// Return the [ImportElement] that declared [prefix] and imports [element].
@@ -37,21 +37,14 @@
 /// [prefix] - the import prefix, maybe `null`.
 /// [element] - the referenced element.
 /// [importElementsMap] - the cache of [Element]s imported by [ImportElement]s.
-ImportElement internal_getImportElement(
-    LibraryElement libraryElement,
-    String prefix,
-    Element element,
-    Map<ImportElement, Set<Element>> importElementsMap) {
-  // validate Element
-  if (element == null) {
-    return null;
-  }
+ImportElement? _getImportElement(LibraryElement libraryElement, String prefix,
+    Element element, Map<ImportElement, Set<Element>> importElementsMap) {
   if (element.enclosingElement is! CompilationUnitElement) {
     return null;
   }
   var usedLibrary = element.library;
   // find ImportElement that imports used library with used prefix
-  List<ImportElement> candidates;
+  List<ImportElement>? candidates;
   for (var importElement in libraryElement.imports) {
     // required library
     if (importElement.importedLibrary != usedLibrary) {
@@ -59,17 +52,11 @@
     }
     // required prefix
     var prefixElement = importElement.prefix;
-    if (prefix == null) {
-      if (prefixElement != null) {
-        continue;
-      }
-    } else {
-      if (prefixElement == null) {
-        continue;
-      }
-      if (prefix != prefixElement.name) {
-        continue;
-      }
+    if (prefixElement == null) {
+      continue;
+    }
+    if (prefix != prefixElement.name) {
+      continue;
     }
     // no combinators => only possible candidate
     if (importElement.combinators.isEmpty) {
@@ -97,8 +84,9 @@
     importElementsMap[importElement] = elements;
   }
   // use import namespace to choose correct one
-  for (var importElement in importElementsMap.keys) {
-    var elements = importElementsMap[importElement];
+  for (var entry in importElementsMap.entries) {
+    var importElement = entry.key;
+    var elements = entry.value;
     if (elements.contains(element)) {
       return importElement;
     }
@@ -109,20 +97,22 @@
 
 /// Returns the [ImportElement] that is referenced by [prefixNode] with a
 /// [PrefixElement], maybe `null`.
-ImportElement internal_getImportElementInfo(SimpleIdentifier prefixNode) {
+ImportElement? _getImportElementInfo(SimpleIdentifier prefixNode) {
   // prepare environment
   var parent = prefixNode.parent;
   var unit = prefixNode.thisOrAncestorOfType<CompilationUnit>();
-  var libraryElement = unit.declaredElement.library;
+  var libraryElement = unit?.declaredElement?.library;
+  if (libraryElement == null) {
+    return null;
+  }
   // prepare used element
-  Element usedElement;
+  Element? usedElement;
   if (parent is PrefixedIdentifier) {
     var prefixed = parent;
     if (prefixed.prefix == prefixNode) {
       usedElement = prefixed.staticElement;
     }
-  }
-  if (parent is MethodInvocation) {
+  } else if (parent is MethodInvocation) {
     var invocation = parent;
     if (invocation.target == prefixNode) {
       usedElement = invocation.methodName.staticElement;
@@ -135,12 +125,6 @@
   // find ImportElement
   var prefix = prefixNode.name;
   var importElementsMap = <ImportElement, Set<Element>>{};
-  return internal_getImportElement(
+  return _getImportElement(
       libraryElement, prefix, usedElement, importElementsMap);
 }
-
-/// Information about [ImportElement] and place where it is referenced using
-/// [PrefixElement].
-class ImportElementInfo {
-  ImportElement element;
-}
diff --git a/pkg/analysis_server/lib/src/services/correction/organize_imports.dart b/pkg/analysis_server/lib/src/services/correction/organize_imports.dart
index 22e440b..6a56773 100644
--- a/pkg/analysis_server/lib/src/services/correction/organize_imports.dart
+++ b/pkg/analysis_server/lib/src/services/correction/organize_imports.dart
@@ -14,17 +14,22 @@
 /// Organizer of imports (and other directives) in the [unit].
 class ImportOrganizer {
   final String initialCode;
+
   final CompilationUnit unit;
+
   final List<AnalysisError> errors;
+
   final bool removeUnused;
 
   String code;
-  String endOfLine;
-  bool hasUnresolvedIdentifierError;
+
+  String endOfLine = '\n';
+
+  bool hasUnresolvedIdentifierError = false;
 
   ImportOrganizer(this.initialCode, this.unit, this.errors,
-      {this.removeUnused = true}) {
-    code = initialCode;
+      {this.removeUnused = true})
+      : code = initialCode {
     endOfLine = getEOL(code);
     hasUnresolvedIdentifierError = errors.any((error) {
       return error.errorCode.isUnresolvedIdentifier;
@@ -58,7 +63,7 @@
 
   /// Organize all [Directive]s.
   void _organizeDirectives() {
-    var lineInfo = unit.lineInfo;
+    var lineInfo = unit.lineInfo ?? LineInfo.fromContent(code);
     var hasLibraryDirective = false;
     var directives = <_DirectiveInfo>[];
     for (var directive in unit.directives) {
@@ -75,34 +80,34 @@
           final trailingComment =
               getTrailingComment(unit, directive, lineInfo, end);
 
-          String leadingCommentText;
+          String? leadingCommentText;
           if (leadingComment != null) {
             leadingCommentText =
                 code.substring(leadingComment.offset, directive.offset);
             offset = leadingComment.offset;
           }
-          String trailingCommentText;
+          String? trailingCommentText;
           if (trailingComment != null) {
             trailingCommentText =
                 code.substring(directive.end, trailingComment.end);
             end = trailingComment.end;
           }
-          String documentationText;
-          if (directive.documentationComment != null) {
+          String? documentationText;
+          var documentationComment = directive.documentationComment;
+          if (documentationComment != null) {
             documentationText = code.substring(
-                directive.documentationComment.offset,
-                directive.documentationComment.end);
+                documentationComment.offset, documentationComment.end);
           }
-          String annotationText;
-          if (directive.metadata.beginToken != null) {
-            annotationText = code.substring(
-                directive.metadata.beginToken.offset,
-                directive.metadata.endToken.end);
+          String? annotationText;
+          var beginToken = directive.metadata.beginToken;
+          var endToken = directive.metadata.endToken;
+          if (beginToken != null && endToken != null) {
+            annotationText = code.substring(beginToken.offset, endToken.end);
           }
           var text = code.substring(
               directive.firstTokenAfterCommentAndMetadata.offset,
               directive.end);
-          var uriContent = directive.uri.stringValue;
+          var uriContent = directive.uri.stringValue ?? '';
           directives.add(
             _DirectiveInfo(
               directive,
@@ -129,7 +134,7 @@
 
     // Without a library directive, the library comment is the comment of the
     // first directive.
-    _DirectiveInfo libraryDocumentationDirective;
+    _DirectiveInfo? libraryDocumentationDirective;
     if (!hasLibraryDirective && directives.isNotEmpty) {
       libraryDocumentationDirective = directives.first;
     }
@@ -140,7 +145,8 @@
     String directivesCode;
     {
       var sb = StringBuffer();
-      if (libraryDocumentationDirective?.documentationText != null) {
+      if (libraryDocumentationDirective != null &&
+          libraryDocumentationDirective.documentationText != null) {
         sb.write(libraryDocumentationDirective.documentationText);
         sb.write(endOfLine);
       }
@@ -183,7 +189,7 @@
     code = beforeDirectives + directivesCode + afterDirectives;
   }
 
-  static _DirectivePriority getDirectivePriority(UriBasedDirective directive) {
+  static _DirectivePriority? getDirectivePriority(UriBasedDirective directive) {
     var uriContent = directive.uri.stringValue ?? '';
     if (directive is ImportDirective) {
       if (uriContent.startsWith('dart:')) {
@@ -228,28 +234,30 @@
   /// Leading comments for the first directive in a file are considered library
   /// comments and not returned unless they contain blank lines, in which case
   /// only the last part of the comment will be returned.
-  static Token getLeadingComment(
+  static Token? getLeadingComment(
       CompilationUnit unit, UriBasedDirective directive, LineInfo lineInfo) {
     if (directive.beginToken.precedingComments == null) {
       return null;
     }
 
-    var firstComment = directive.beginToken.precedingComments;
+    Token? firstComment = directive.beginToken.precedingComments;
     var comment = firstComment;
+    var nextComment = comment?.next;
     // Don't connect comments that have a blank line between them
-    while (comment.next != null) {
+    while (comment != null && nextComment != null) {
       var currentLine = lineInfo.getLocation(comment.offset).lineNumber;
-      var nextLine = lineInfo.getLocation(comment.next.offset).lineNumber;
+      var nextLine = lineInfo.getLocation(nextComment.offset).lineNumber;
       if (nextLine - currentLine > 1) {
-        firstComment = comment.next;
+        firstComment = nextComment;
       }
-      comment = comment.next;
+      comment = nextComment;
+      nextComment = comment.next;
     }
 
     // Check if the comment is the first comment in the document
     if (firstComment != unit.beginToken.precedingComments) {
       var previousDirectiveLine =
-          lineInfo.getLocation(directive.beginToken.previous.end).lineNumber;
+          lineInfo.getLocation(directive.beginToken.previous!.end).lineNumber;
 
       // Skip over any comments on the same line as the previous directive
       // as they will be attached to the end of it.
@@ -269,10 +277,10 @@
   ///
   /// To be considered a trailing comment, the comment must be on the same line
   /// as the directive.
-  static Token getTrailingComment(CompilationUnit unit,
+  static Token? getTrailingComment(CompilationUnit unit,
       UriBasedDirective directive, LineInfo lineInfo, int end) {
     var line = lineInfo.getLocation(end).lineNumber;
-    Token comment = directive.endToken.next.precedingComments;
+    Token? comment = directive.endToken.next!.precedingComments;
     while (comment != null) {
       if (lineInfo.getLocation(comment.offset).lineNumber == line) {
         return comment;
@@ -286,11 +294,11 @@
 class _DirectiveInfo implements Comparable<_DirectiveInfo> {
   final UriBasedDirective directive;
   final _DirectivePriority priority;
-  final String leadingCommentText;
-  final String documentationText;
-  final String annotationText;
+  final String? leadingCommentText;
+  final String? documentationText;
+  final String? annotationText;
   final String uri;
-  final String trailingCommentText;
+  final String? trailingCommentText;
 
   /// The offset of the first token, usually the keyword but may include leading comments.
   final int offset;
diff --git a/pkg/analysis_server/lib/src/services/correction/selection_analyzer.dart b/pkg/analysis_server/lib/src/services/correction/selection_analyzer.dart
index deac73d..d71a7e1 100644
--- a/pkg/analysis_server/lib/src/services/correction/selection_analyzer.dart
+++ b/pkg/analysis_server/lib/src/services/correction/selection_analyzer.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
+
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/visitor.dart';
 import 'package:analyzer/src/generated/source.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/sort_members.dart b/pkg/analysis_server/lib/src/services/correction/sort_members.dart
index cf3db41..93e103a 100644
--- a/pkg/analysis_server/lib/src/services/correction/sort_members.dart
+++ b/pkg/analysis_server/lib/src/services/correction/sort_members.dart
@@ -42,12 +42,14 @@
   ];
 
   final String initialCode;
-  final CompilationUnit unit;
-  String code;
-  String endOfLine;
 
-  MemberSorter(this.initialCode, this.unit) {
-    code = initialCode;
+  final CompilationUnit unit;
+
+  String code;
+
+  String endOfLine = '\n';
+
+  MemberSorter(this.initialCode, this.unit) : code = initialCode {
     endOfLine = getEOL(code);
   }
 
@@ -106,17 +108,18 @@
         } else {
           name = nameNode.name;
         }
-      }
-      if (member is FieldDeclaration) {
+      } else if (member is FieldDeclaration) {
         var fieldDeclaration = member;
         List<VariableDeclaration> fields = fieldDeclaration.fields.variables;
         if (fields.isNotEmpty) {
           kind = _MemberKind.CLASS_FIELD;
           isStatic = fieldDeclaration.isStatic;
           name = fields[0].name.name;
+        } else {
+          // Don't sort members if there are errors in the code.
+          return;
         }
-      }
-      if (member is MethodDeclaration) {
+      } else if (member is MethodDeclaration) {
         var method = member;
         isStatic = method.isStatic;
         name = method.name.name;
@@ -129,14 +132,14 @@
         } else {
           kind = _MemberKind.CLASS_METHOD;
         }
+      } else {
+        throw StateError('Unsupported class of member: ${member.runtimeType}');
       }
-      if (name != null) {
-        var item = _PriorityItem.forName(isStatic, name, kind);
-        var offset = member.offset;
-        var length = member.length;
-        var text = code.substring(offset, offset + length);
-        members.add(_MemberInfo(item, name, offset, length, text));
-      }
+      var item = _PriorityItem.forName(isStatic, name, kind);
+      var offset = member.offset;
+      var length = member.length;
+      var text = code.substring(offset, offset + length);
+      members.add(_MemberInfo(item, name, offset, length, text));
     }
     // do sort
     _sortAndReorderMembers(members);
@@ -201,15 +204,18 @@
             kind = _MemberKind.UNIT_VARIABLE;
           }
           name = variables[0].name.name;
+        } else {
+          // Don't sort members if there are errors in the code.
+          return;
         }
+      } else {
+        throw StateError('Unsupported class of member: ${member.runtimeType}');
       }
-      if (name != null) {
-        var item = _PriorityItem.forName(false, name, kind);
-        var offset = member.offset;
-        var length = member.length;
-        var text = code.substring(offset, offset + length);
-        members.add(_MemberInfo(item, name, offset, length, text));
-      }
+      var item = _PriorityItem.forName(false, name, kind);
+      var offset = member.offset;
+      var length = member.length;
+      var text = code.substring(offset, offset + length);
+      members.add(_MemberInfo(item, name, offset, length, text));
     }
     // do sort
     _sortAndReorderMembers(members);
diff --git a/pkg/analysis_server/lib/src/services/correction/source_buffer.dart b/pkg/analysis_server/lib/src/services/correction/source_buffer.dart
index 323c721..488743e 100644
--- a/pkg/analysis_server/lib/src/services/correction/source_buffer.dart
+++ b/pkg/analysis_server/lib/src/services/correction/source_buffer.dart
@@ -8,16 +8,17 @@
   final int offset;
   final StringBuffer _buffer = StringBuffer();
 
-  int _exitOffset;
+  int? _exitOffset;
 
   SourceBuilder(this.file, this.offset);
 
   /// Returns the exit offset, maybe `null` if not set.
-  int get exitOffset {
-    if (_exitOffset == null) {
+  int? get exitOffset {
+    var exitOffset = _exitOffset;
+    if (exitOffset == null) {
       return null;
     }
-    return offset + _exitOffset;
+    return offset + exitOffset;
   }
 
   int get length => _buffer.length;
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 96e8e89..3f62794 100644
--- a/pkg/analysis_server/lib/src/services/correction/statement_analyzer.dart
+++ b/pkg/analysis_server/lib/src/services/correction/statement_analyzer.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
+
 import 'package:analysis_server/src/protocol_server.dart';
 import 'package:analysis_server/src/services/correction/selection_analyzer.dart';
 import 'package:analysis_server/src/services/correction/status.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/status.dart b/pkg/analysis_server/lib/src/services/correction/status.dart
index 20c2268..d552874 100644
--- a/pkg/analysis_server/lib/src/services/correction/status.dart
+++ b/pkg/analysis_server/lib/src/services/correction/status.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
+
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 
 /// An outcome of a condition checking operation.
diff --git a/pkg/analysis_server/lib/src/services/correction/util.dart b/pkg/analysis_server/lib/src/services/correction/util.dart
index 9914359..903f88f 100644
--- a/pkg/analysis_server/lib/src/services/correction/util.dart
+++ b/pkg/analysis_server/lib/src/services/correction/util.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
+
 import 'dart:math';
 
 import 'package:analysis_server/src/protocol_server.dart'
diff --git a/pkg/analysis_server/lib/src/services/flutter/class_description.dart b/pkg/analysis_server/lib/src/services/flutter/class_description.dart
index f3b8a83..b37c741 100644
--- a/pkg/analysis_server/lib/src/services/flutter/class_description.dart
+++ b/pkg/analysis_server/lib/src/services/flutter/class_description.dart
@@ -38,7 +38,7 @@
 
   /// If we know how to materialize the [element], return [ClassDescription].
   /// Otherwise return `null`.
-  ClassDescription get(ClassElement element) {
+  ClassDescription? get(ClassElement element) {
     var description = _map[element];
     if (description == null) {
       description = _classDescription(element);
@@ -57,7 +57,7 @@
     return false;
   }
 
-  ClassDescription _classDescription(ClassElement element) {
+  ClassDescription? _classDescription(ClassElement element) {
     if (!_isOptedInClass(element)) return null;
 
     var constructor = element.unnamedConstructor;
diff --git a/pkg/analysis_server/lib/src/services/flutter/property.dart b/pkg/analysis_server/lib/src/services/flutter/property.dart
index 25f01ab..d7dce19 100644
--- a/pkg/analysis_server/lib/src/services/flutter/property.dart
+++ b/pkg/analysis_server/lib/src/services/flutter/property.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
+
 import 'package:analysis_server/src/protocol_server.dart' as protocol;
 import 'package:analysis_server/src/services/flutter/class_description.dart';
 import 'package:analysis_server/src/utilities/flutter.dart';
diff --git a/pkg/analysis_server/lib/src/services/flutter/widget_descriptions.dart b/pkg/analysis_server/lib/src/services/flutter/widget_descriptions.dart
index e24d8d5..b33557d 100644
--- a/pkg/analysis_server/lib/src/services/flutter/widget_descriptions.dart
+++ b/pkg/analysis_server/lib/src/services/flutter/widget_descriptions.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
+
 import 'package:analysis_server/src/protocol_server.dart' as protocol;
 import 'package:analysis_server/src/services/flutter/class_description.dart';
 import 'package:analysis_server/src/services/flutter/property.dart';
diff --git a/pkg/analysis_server/lib/src/services/kythe/kythe_visitors.dart b/pkg/analysis_server/lib/src/services/kythe/kythe_visitors.dart
index f2f430f..57085d1 100644
--- a/pkg/analysis_server/lib/src/services/kythe/kythe_visitors.dart
+++ b/pkg/analysis_server/lib/src/services/kythe/kythe_visitors.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
+
 import 'dart:convert';
 
 import 'package:analyzer/dart/ast/ast.dart';
diff --git a/pkg/analysis_server/lib/src/services/linter/lint_names.dart b/pkg/analysis_server/lib/src/services/linter/lint_names.dart
index 60afd1b..cc4823f 100644
--- a/pkg/analysis_server/lib/src/services/linter/lint_names.dart
+++ b/pkg/analysis_server/lib/src/services/linter/lint_names.dart
@@ -91,6 +91,7 @@
   static const String unnecessary_brace_in_string_interps =
       'unnecessary_brace_in_string_interps';
   static const String unnecessary_const = 'unnecessary_const';
+  static const String unnecessary_final = 'unnecessary_final';
   static const String unnecessary_lambdas = 'unnecessary_lambdas';
   static const String unnecessary_new = 'unnecessary_new';
   static const String unnecessary_null_in_if_null_operators =
diff --git a/pkg/analysis_server/lib/src/services/pub/pub_api.dart b/pkg/analysis_server/lib/src/services/pub/pub_api.dart
index 7f43aa0..a9e504a 100644
--- a/pkg/analysis_server/lib/src/services/pub/pub_api.dart
+++ b/pkg/analysis_server/lib/src/services/pub/pub_api.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
+
 import 'dart:async';
 import 'dart:convert';
 import 'dart:io';
diff --git a/pkg/analysis_server/lib/src/services/pub/pub_package_service.dart b/pkg/analysis_server/lib/src/services/pub/pub_package_service.dart
index aca37e4..09d0c80 100644
--- a/pkg/analysis_server/lib/src/services/pub/pub_package_service.dart
+++ b/pkg/analysis_server/lib/src/services/pub/pub_package_service.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
+
 import 'dart:async';
 import 'dart:convert';
 
diff --git a/pkg/analysis_server/lib/src/services/refactoring/convert_getter_to_method.dart b/pkg/analysis_server/lib/src/services/refactoring/convert_getter_to_method.dart
index 5c1e88a..b2f9f13 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/convert_getter_to_method.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/convert_getter_to_method.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
+
 import 'package:analysis_server/src/protocol_server.dart' hide Element;
 import 'package:analysis_server/src/services/correction/status.dart';
 import 'package:analysis_server/src/services/refactoring/refactoring.dart';
diff --git a/pkg/analysis_server/lib/src/services/refactoring/convert_method_to_getter.dart b/pkg/analysis_server/lib/src/services/refactoring/convert_method_to_getter.dart
index c1d584c..7fb6210 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/convert_method_to_getter.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/convert_method_to_getter.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
+
 import 'package:analysis_server/src/protocol_server.dart' hide Element;
 import 'package:analysis_server/src/services/correction/status.dart';
 import 'package:analysis_server/src/services/refactoring/refactoring.dart';
diff --git a/pkg/analysis_server/lib/src/services/refactoring/extract_local.dart b/pkg/analysis_server/lib/src/services/refactoring/extract_local.dart
index 792e05e..e6ffa45 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/extract_local.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/extract_local.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
+
 import 'dart:collection';
 
 import 'package:analysis_server/src/protocol_server.dart' hide Element;
diff --git a/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart b/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart
index 81e08f1..d9c1a15 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/extract_method.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
+
 import 'package:analysis_server/src/protocol_server.dart' hide Element;
 import 'package:analysis_server/src/services/correction/name_suggestion.dart';
 import 'package:analysis_server/src/services/correction/selection_analyzer.dart';
diff --git a/pkg/analysis_server/lib/src/services/refactoring/extract_widget.dart b/pkg/analysis_server/lib/src/services/refactoring/extract_widget.dart
index 9570680..f7f67c7 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/extract_widget.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/extract_widget.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
+
 import 'package:analysis_server/src/protocol_server.dart' hide Element;
 import 'package:analysis_server/src/services/correction/status.dart';
 import 'package:analysis_server/src/services/correction/util.dart';
diff --git a/pkg/analysis_server/lib/src/services/refactoring/inline_local.dart b/pkg/analysis_server/lib/src/services/refactoring/inline_local.dart
index 0710a92..bbfccb9 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/inline_local.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/inline_local.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
+
 import 'package:analysis_server/src/protocol_server.dart' hide Element;
 import 'package:analysis_server/src/services/correction/status.dart';
 import 'package:analysis_server/src/services/correction/util.dart';
diff --git a/pkg/analysis_server/lib/src/services/refactoring/inline_method.dart b/pkg/analysis_server/lib/src/services/refactoring/inline_method.dart
index 1489cd7..0b6f4a2 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/inline_method.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/inline_method.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
+
 import 'package:analysis_server/src/protocol_server.dart' hide Element;
 import 'package:analysis_server/src/services/correction/status.dart';
 import 'package:analysis_server/src/services/correction/util.dart';
diff --git a/pkg/analysis_server/lib/src/services/refactoring/move_file.dart b/pkg/analysis_server/lib/src/services/refactoring/move_file.dart
index 9e5cf33..93a7520 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/move_file.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/move_file.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
+
 import 'dart:core';
 
 import 'package:analysis_server/src/protocol_server.dart' hide Element;
@@ -78,6 +80,9 @@
     var libraryElement = element.library;
     var libraryPath = libraryElement.source.fullName;
 
+    final oldDir = pathContext.dirname(oldFile);
+    final newDir = pathContext.dirname(newFile);
+
     // If this element is a library, update outgoing references inside the file.
     if (element == libraryElement.definingCompilationUnit) {
       // Handle part-of directives in this library
@@ -94,8 +99,6 @@
             await changeBuilder.addDartFileEdit(
                 result.unit.declaredElement.source.fullName, (builder) {
               partOfs.forEach((po) {
-                final oldDir = pathContext.dirname(oldFile);
-                final newDir = pathContext.dirname(newFile);
                 var newLocation =
                     pathContext.join(newDir, pathos.basename(newFile));
                 var newUri = _getRelativeUri(newLocation, oldDir);
@@ -110,16 +113,16 @@
         }
       }
 
-      await changeBuilder.addDartFileEdit(definingUnitResult.path, (builder) {
-        var oldDir = pathContext.dirname(oldFile);
-        var newDir = pathContext.dirname(newFile);
-        for (var directive in definingUnitResult.unit.directives) {
-          if (directive is UriBasedDirective) {
-            _updateUriReference(builder, directive, oldDir, newDir);
+      if (newDir != oldDir) {
+        await changeBuilder.addDartFileEdit(definingUnitResult.path, (builder) {
+          for (var directive in definingUnitResult.unit.directives) {
+            if (directive is UriBasedDirective) {
+              _updateUriReference(builder, directive, oldDir, newDir);
+            }
           }
-        }
-      });
-    } else {
+        });
+      }
+    } else if (newDir != oldDir) {
       // Otherwise, we need to update any relative part-of references.
       var partOfs = resolvedUnit.unit.directives
           .whereType<PartOfDirective>()
@@ -128,8 +131,6 @@
       if (partOfs.isNotEmpty) {
         await changeBuilder.addDartFileEdit(element.source.fullName, (builder) {
           partOfs.forEach((po) {
-            final oldDir = pathContext.dirname(oldFile);
-            final newDir = pathContext.dirname(newFile);
             var oldLocation = pathContext.join(oldDir, po.uri.stringValue);
             var newUri = _getRelativeUri(oldLocation, newDir);
             builder.addSimpleReplacement(
@@ -161,7 +162,9 @@
       Source newSource =
           NonExistingSource(newFile, pathos.toUri(newFile), UriKind.FILE_URI);
       var restoredUri = driver.sourceFactory.restoreUri(newSource);
-      if (restoredUri != null) {
+      // If the new URI is not a package: URI, fall back to computing a relative
+      // URI below.
+      if (restoredUri?.isScheme('package') ?? false) {
         return restoredUri.toString();
       }
     }
diff --git a/pkg/analysis_server/lib/src/services/refactoring/naming_conventions.dart b/pkg/analysis_server/lib/src/services/refactoring/naming_conventions.dart
index 3cd4fe3..735bed9 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/naming_conventions.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/naming_conventions.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
+
 import 'package:_fe_analyzer_shared/src/scanner/token.dart' show Keyword;
 import 'package:analysis_server/src/services/correction/status.dart';
 import 'package:analysis_server/src/utilities/strings.dart';
diff --git a/pkg/analysis_server/lib/src/services/refactoring/refactoring.dart b/pkg/analysis_server/lib/src/services/refactoring/refactoring.dart
index 9d2e00f..fbd4d3b 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/refactoring.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/refactoring.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
+
 import 'package:analysis_server/src/services/correction/status.dart';
 import 'package:analysis_server/src/services/refactoring/convert_getter_to_method.dart';
 import 'package:analysis_server/src/services/refactoring/convert_method_to_getter.dart';
diff --git a/pkg/analysis_server/lib/src/services/refactoring/refactoring_internal.dart b/pkg/analysis_server/lib/src/services/refactoring/refactoring_internal.dart
index 1677bb8..dd05a9b 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/refactoring_internal.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/refactoring_internal.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
+
 import 'dart:collection';
 
 import 'package:analysis_server/src/protocol_server.dart' hide Element;
diff --git a/pkg/analysis_server/lib/src/services/refactoring/rename.dart b/pkg/analysis_server/lib/src/services/refactoring/rename.dart
index 6c25dd6..35d547b 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/rename.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/rename.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
+
 import 'package:analysis_server/src/protocol_server.dart' hide Element;
 import 'package:analysis_server/src/services/correction/status.dart';
 import 'package:analysis_server/src/services/correction/util.dart';
diff --git a/pkg/analysis_server/lib/src/services/refactoring/rename_class_member.dart b/pkg/analysis_server/lib/src/services/refactoring/rename_class_member.dart
index 7f96d3a..eb2ab3c 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/rename_class_member.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/rename_class_member.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
+
 import 'package:analysis_server/src/protocol_server.dart'
     hide Element, ElementKind;
 import 'package:analysis_server/src/services/correction/status.dart';
diff --git a/pkg/analysis_server/lib/src/services/refactoring/rename_constructor.dart b/pkg/analysis_server/lib/src/services/refactoring/rename_constructor.dart
index 1009de9..3d6edf8 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/rename_constructor.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/rename_constructor.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
+
 import 'package:analysis_server/src/protocol_server.dart' hide Element;
 import 'package:analysis_server/src/services/correction/status.dart';
 import 'package:analysis_server/src/services/correction/util.dart';
diff --git a/pkg/analysis_server/lib/src/services/refactoring/rename_extension_member.dart b/pkg/analysis_server/lib/src/services/refactoring/rename_extension_member.dart
index 6187abe..2665ac7 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/rename_extension_member.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/rename_extension_member.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
+
 import 'package:analysis_server/src/protocol_server.dart'
     hide Element, ElementKind;
 import 'package:analysis_server/src/services/correction/status.dart';
diff --git a/pkg/analysis_server/lib/src/services/refactoring/rename_import.dart b/pkg/analysis_server/lib/src/services/refactoring/rename_import.dart
index 0dfbac5..04eeea2 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/rename_import.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/rename_import.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
+
 import 'package:analysis_server/src/protocol_server.dart';
 import 'package:analysis_server/src/services/correction/status.dart';
 import 'package:analysis_server/src/services/refactoring/naming_conventions.dart';
diff --git a/pkg/analysis_server/lib/src/services/refactoring/rename_label.dart b/pkg/analysis_server/lib/src/services/refactoring/rename_label.dart
index d32922a..86873b0 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/rename_label.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/rename_label.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
+
 import 'package:analysis_server/src/services/correction/status.dart';
 import 'package:analysis_server/src/services/refactoring/naming_conventions.dart';
 import 'package:analysis_server/src/services/refactoring/refactoring.dart';
diff --git a/pkg/analysis_server/lib/src/services/refactoring/rename_library.dart b/pkg/analysis_server/lib/src/services/refactoring/rename_library.dart
index 68b8849..1338bbc 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/rename_library.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/rename_library.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
+
 import 'package:analysis_server/src/services/correction/status.dart';
 import 'package:analysis_server/src/services/refactoring/naming_conventions.dart';
 import 'package:analysis_server/src/services/refactoring/refactoring.dart';
diff --git a/pkg/analysis_server/lib/src/services/refactoring/rename_local.dart b/pkg/analysis_server/lib/src/services/refactoring/rename_local.dart
index 3b3d492..04fa336 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/rename_local.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/rename_local.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
+
 import 'package:analysis_server/src/protocol_server.dart'
     hide Element, ElementKind;
 import 'package:analysis_server/src/services/correction/status.dart';
diff --git a/pkg/analysis_server/lib/src/services/refactoring/rename_unit_member.dart b/pkg/analysis_server/lib/src/services/refactoring/rename_unit_member.dart
index 05cf609..2afbf50 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/rename_unit_member.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/rename_unit_member.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
+
 import 'package:analysis_server/src/protocol_server.dart'
     show newLocation_fromElement, newLocation_fromMatch;
 import 'package:analysis_server/src/services/correction/status.dart';
diff --git a/pkg/analysis_server/lib/src/services/refactoring/visible_ranges_computer.dart b/pkg/analysis_server/lib/src/services/refactoring/visible_ranges_computer.dart
index 4d15c8e..72101d6 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/visible_ranges_computer.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/visible_ranges_computer.dart
@@ -24,7 +24,9 @@
     var element = node.declaredElement;
     if (element is ParameterElement) {
       var body = _getFunctionBody(node);
-      if (body is BlockFunctionBody || body is ExpressionFunctionBody) {
+      if (body is BlockFunctionBody) {
+        _map[element] = range.node(body);
+      } else if (body is ExpressionFunctionBody) {
         _map[element] = range.node(body);
       }
     }
@@ -33,9 +35,11 @@
   @override
   void visitForPartsWithDeclarations(ForPartsWithDeclarations node) {
     var loop = node.parent;
-    for (var variable in node.variables.variables) {
-      _addLocalVariable(loop, variable.declaredElement);
-      variable.initializer?.accept(this);
+    if (loop != null) {
+      for (var variable in node.variables.variables) {
+        _addLocalVariable(loop, variable.declaredElement);
+        variable.initializer?.accept(this);
+      }
     }
   }
 
@@ -53,13 +57,15 @@
   @override
   void visitVariableDeclarationStatement(VariableDeclarationStatement node) {
     var block = node.parent;
-    for (var variable in node.variables.variables) {
-      _addLocalVariable(block, variable.declaredElement);
-      variable.initializer?.accept(this);
+    if (block != null) {
+      for (var variable in node.variables.variables) {
+        _addLocalVariable(block, variable.declaredElement);
+        variable.initializer?.accept(this);
+      }
     }
   }
 
-  void _addLocalVariable(AstNode scopeNode, Element element) {
+  void _addLocalVariable(AstNode scopeNode, Element? element) {
     if (element is LocalVariableElement) {
       _map[element] = range.node(scopeNode);
     }
@@ -73,8 +79,8 @@
 
   /// Return the body of the function that contains the given [parameter], or
   /// `null` if no function body could be found.
-  static FunctionBody _getFunctionBody(FormalParameter parameter) {
-    var parent = parameter?.parent?.parent;
+  static FunctionBody? _getFunctionBody(FormalParameter parameter) {
+    var parent = parameter.parent?.parent;
     if (parent is ConstructorDeclaration) {
       return parent.body;
     } else if (parent is FunctionExpression) {
diff --git a/pkg/analysis_server/lib/src/services/search/element_visitors.dart b/pkg/analysis_server/lib/src/services/search/element_visitors.dart
index d3e11ae..de03c6f 100644
--- a/pkg/analysis_server/lib/src/services/search/element_visitors.dart
+++ b/pkg/analysis_server/lib/src/services/search/element_visitors.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
+
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/visitor.dart';
 
diff --git a/pkg/analysis_server/lib/src/services/search/hierarchy.dart b/pkg/analysis_server/lib/src/services/search/hierarchy.dart
index 7a3f90e..6d30c6b 100644
--- a/pkg/analysis_server/lib/src/services/search/hierarchy.dart
+++ b/pkg/analysis_server/lib/src/services/search/hierarchy.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
+
 import 'dart:collection';
 
 import 'package:analysis_server/src/services/search/element_visitors.dart';
diff --git a/pkg/analysis_server/lib/src/services/search/search_engine.dart b/pkg/analysis_server/lib/src/services/search/search_engine.dart
index 95b74ec..8addf0a 100644
--- a/pkg/analysis_server/lib/src/services/search/search_engine.dart
+++ b/pkg/analysis_server/lib/src/services/search/search_engine.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
+
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/source.dart';
 
diff --git a/pkg/analysis_server/lib/src/services/search/search_engine_internal.dart b/pkg/analysis_server/lib/src/services/search/search_engine_internal.dart
index ddc1c22..3f5cd22 100644
--- a/pkg/analysis_server/lib/src/services/search/search_engine_internal.dart
+++ b/pkg/analysis_server/lib/src/services/search/search_engine_internal.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
+
 import 'package:analysis_server/src/services/search/search_engine.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/dart/analysis/driver.dart';
diff --git a/pkg/analysis_server/lib/src/socket_server.dart b/pkg/analysis_server/lib/src/socket_server.dart
index b86d18d..df0d3e2 100644
--- a/pkg/analysis_server/lib/src/socket_server.dart
+++ b/pkg/analysis_server/lib/src/socket_server.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
+
 import 'package:analysis_server/protocol/protocol.dart';
 import 'package:analysis_server/protocol/protocol_generated.dart';
 import 'package:analysis_server/src/analysis_server.dart';
@@ -81,6 +83,7 @@
       requestStatistics: requestStatistics,
       diagnosticServer: diagnosticServer,
       detachableFileSystemManager: detachableFileSystemManager,
+      enableBazelWatcher: true,
     );
     detachableFileSystemManager?.setAnalysisServer(analysisServer);
   }
diff --git a/pkg/analysis_server/lib/src/status/ast_writer.dart b/pkg/analysis_server/lib/src/status/ast_writer.dart
index 29a96b8..d3917ce 100644
--- a/pkg/analysis_server/lib/src/status/ast_writer.dart
+++ b/pkg/analysis_server/lib/src/status/ast_writer.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:collection';
-
 import 'package:analysis_server/src/status/tree_writer.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/visitor.dart';
@@ -11,11 +9,12 @@
 
 /// A visitor that will produce an HTML representation of an AST structure.
 class AstWriter extends UnifyingAstVisitor with TreeWriter {
+  @override
+  final StringBuffer buffer;
+
   /// Initialize a newly created element writer to write the HTML representation
   /// of visited nodes on the given [buffer].
-  AstWriter(StringBuffer buffer) {
-    this.buffer = buffer;
-  }
+  AstWriter(this.buffer);
 
   @override
   void visitNode(AstNode node) {
@@ -31,8 +30,8 @@
 
   /// Write a representation of the properties of the given [node] to the
   /// buffer.
-  Map<String, Object> _computeProperties(AstNode node) {
-    Map<String, Object> properties = HashMap<String, Object>();
+  Map<String, Object?> _computeProperties(AstNode node) {
+    var properties = <String, Object?>{};
 
     properties['name'] = _getName(node);
     if (node is ArgumentListImpl) {
@@ -148,26 +147,24 @@
 
   /// Return the name of the given [node], or `null` if the given node is not a
   /// declaration.
-  String _getName(AstNode node) {
+  String? _getName(AstNode node) {
     if (node is ClassTypeAlias) {
       return node.name.name;
     } else if (node is ClassDeclaration) {
       return node.name.name;
     } else if (node is ConstructorDeclaration) {
-      if (node.name == null) {
+      var name = node.name;
+      if (name == null) {
         return node.returnType.name;
       } else {
-        return node.returnType.name + '.' + node.name.name;
+        return node.returnType.name + '.' + name.name;
       }
     } else if (node is ConstructorName) {
       return node.toSource();
     } else if (node is FieldDeclaration) {
       return _getNames(node.fields);
     } else if (node is FunctionDeclaration) {
-      var nameNode = node.name;
-      if (nameNode != null) {
-        return nameNode.name;
-      }
+      return node.name.name;
     } else if (node is FunctionTypeAlias) {
       return node.name.name;
     } else if (node is Identifier) {
diff --git a/pkg/analysis_server/lib/src/status/diagnostics.dart b/pkg/analysis_server/lib/src/status/diagnostics.dart
index 7818392..bfb39c7 100644
--- a/pkg/analysis_server/lib/src/status/diagnostics.dart
+++ b/pkg/analysis_server/lib/src/status/diagnostics.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
+
 import 'dart:developer' as developer;
 import 'dart:io';
 
diff --git a/pkg/analysis_server/lib/src/status/element_writer.dart b/pkg/analysis_server/lib/src/status/element_writer.dart
index 20e2720..dffcd49 100644
--- a/pkg/analysis_server/lib/src/status/element_writer.dart
+++ b/pkg/analysis_server/lib/src/status/element_writer.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 'dart:collection';
 import 'dart:convert';
 
 import 'package:analysis_server/src/status/tree_writer.dart';
@@ -12,11 +11,12 @@
 
 /// A visitor that will produce an HTML representation of an element structure.
 class ElementWriter extends GeneralizingElementVisitor with TreeWriter {
+  @override
+  final StringBuffer buffer;
+
   /// Initialize a newly created element writer to write the HTML representation
   /// of visited elements on the given [buffer].
-  ElementWriter(StringBuffer buffer) {
-    this.buffer = buffer;
-  }
+  ElementWriter(this.buffer);
 
   @override
   void visitElement(Element element) {
@@ -32,8 +32,8 @@
 
   /// Write a representation of the properties of the given [node] to the
   /// buffer.
-  Map<String, Object> _computeProperties(Element element) {
-    Map<String, Object> properties = HashMap<String, Object>();
+  Map<String, Object?> _computeProperties(Element element) {
+    var properties = <String, Object?>{};
 
     properties['metadata'] = element.metadata;
     properties['nameOffset'] = element.nameOffset;
diff --git a/pkg/analysis_server/lib/src/status/pages.dart b/pkg/analysis_server/lib/src/status/pages.dart
index 177f04f..61f4704 100644
--- a/pkg/analysis_server/lib/src/status/pages.dart
+++ b/pkg/analysis_server/lib/src/status/pages.dart
@@ -9,7 +9,7 @@
 
 final NumberFormat numberFormat = NumberFormat.decimalPattern();
 
-String escape(String text) => text == null ? '' : htmlEscape.convert(text);
+String escape(String? text) => text == null ? '' : htmlEscape.convert(text);
 
 String printInteger(int value) => numberFormat.format(value);
 
@@ -24,13 +24,13 @@
 
   final String id;
   final String title;
-  final String description;
+  final String? description;
 
   Page(this.id, this.title, {this.description});
 
   String get path => '/$id';
 
-  Future<void> asyncDiv(void Function() gen, {String classes}) async {
+  Future<void> asyncDiv(void Function() gen, {String? classes}) async {
     if (classes != null) {
       buf.writeln('<div class="$classes">');
     } else {
@@ -46,7 +46,7 @@
     div(() => buf.writeln(str), classes: 'blankslate');
   }
 
-  void div(void Function() gen, {String classes}) {
+  void div(void Function() gen, {String? classes}) {
     if (classes != null) {
       buf.writeln('<div class="$classes">');
     } else {
@@ -66,7 +66,7 @@
 
   Future<void> generatePage(Map<String, String> params);
 
-  void h1(String text, {String classes}) {
+  void h1(String text, {String? classes}) {
     if (classes != null) {
       buf.writeln('<h1 class="$classes">${escape(text)}</h1>');
     } else {
@@ -98,7 +98,7 @@
 
   bool isCurrentPage(String pathToTest) => path == pathToTest;
 
-  void p(String text, {String style, bool raw = false, String classes}) {
+  void p(String text, {String? style, bool raw = false, String? classes}) {
     var c = classes == null ? '' : ' class="$classes"';
 
     if (style != null) {
@@ -108,7 +108,7 @@
     }
   }
 
-  void pre(void Function() gen, {String classes}) {
+  void pre(void Function() gen, {String? classes}) {
     if (classes != null) {
       buf.write('<pre class="$classes">');
     } else {
@@ -125,7 +125,7 @@
     });
   }
 
-  void ul<T>(Iterable<T> items, void Function(T item) gen, {String classes}) {
+  void ul<T>(Iterable<T> items, void Function(T item) gen, {String? classes}) {
     buf.writeln('<ul${classes == null ? '' : ' class=$classes'}>');
     for (var item in items) {
       buf.write('<li>');
@@ -211,7 +211,7 @@
     HttpRequest request, {
     int code = HttpStatus.ok,
   }) async {
-    if (request.headers.contentType.subType == 'json') {
+    if (request.headers.contentType?.subType == 'json') {
       return respondJson(request, {'success': true}, code);
     }
 
diff --git a/pkg/analysis_server/lib/src/status/tree_writer.dart b/pkg/analysis_server/lib/src/status/tree_writer.dart
index 4ed9ad0..ec20780 100644
--- a/pkg/analysis_server/lib/src/status/tree_writer.dart
+++ b/pkg/analysis_server/lib/src/status/tree_writer.dart
@@ -11,9 +11,6 @@
 /// Utility methods that can be mixed in to classes that produce an HTML
 /// representation of a tree structure.
 mixin TreeWriter {
-  /// The buffer on which the HTML is to be written.
-  StringBuffer buffer;
-
   /// The current level of indentation.
   int indentLevel = 0;
 
@@ -21,6 +18,9 @@
   /// write out the tree structure.
   List<CaughtException> exceptions = <CaughtException>[];
 
+  /// The buffer on which the HTML is to be written.
+  StringBuffer get buffer;
+
   void indent([int extra = 0]) {
     for (var i = 0; i < indentLevel; i++) {
       buffer.write('&#x250A;&nbsp;&nbsp;&nbsp;');
@@ -34,7 +34,7 @@
   }
 
   /// Write a representation of the given [properties] to the buffer.
-  void writeProperties(Map<String, Object> properties) {
+  void writeProperties(Map<String, Object?> properties) {
     var propertyNames = properties.keys.toList();
     propertyNames.sort();
     for (var propertyName in propertyNames) {
@@ -43,7 +43,7 @@
   }
 
   /// Write the [value] of the property with the given [name].
-  void writeProperty(String name, Object value) {
+  void writeProperty(String name, Object? value) {
     if (value != null) {
       indent(2);
       buffer.write('$name = ');
@@ -52,7 +52,7 @@
     }
   }
 
-  String _toString(Object value) {
+  String? _toString(Object? value) {
     try {
       if (value is Source) {
         return 'Source (uri="${value.uri}", path="${value.fullName}")';
diff --git a/pkg/analysis_server/lib/src/utilities/extensions/ast.dart b/pkg/analysis_server/lib/src/utilities/extensions/ast.dart
index 1287b2e..fd493a4 100644
--- a/pkg/analysis_server/lib/src/utilities/extensions/ast.dart
+++ b/pkg/analysis_server/lib/src/utilities/extensions/ast.dart
@@ -43,6 +43,8 @@
       var parent = body.parent;
       if (parent is ConstructorDeclaration || parent is MethodDeclaration) {
         return true;
+      } else if (parent == null) {
+        return false;
       }
       node = parent;
     }
diff --git a/pkg/analysis_server/lib/src/utilities/extensions/element.dart b/pkg/analysis_server/lib/src/utilities/extensions/element.dart
index 1d6b14c..440d3ef 100644
--- a/pkg/analysis_server/lib/src/utilities/extensions/element.dart
+++ b/pkg/analysis_server/lib/src/utilities/extensions/element.dart
@@ -7,21 +7,19 @@
 extension ClassElementExtensions on ClassElement {
   /// Return `true` if this element represents the class `Iterable` from
   /// `dart:core`.
-  bool get isDartCoreIterable =>
-      this != null && name == 'Iterable' && library.isDartCore;
+  bool get isDartCoreIterable => name == 'Iterable' && library.isDartCore;
 
   /// Return `true` if this element represents the class `List` from
   /// `dart:core`.
-  bool get isDartCoreList =>
-      this != null && name == 'List' && library.isDartCore;
+  bool get isDartCoreList => name == 'List' && library.isDartCore;
 
   /// Return `true` if this element represents the class `Map` from
   /// `dart:core`.
-  bool get isDartCoreMap => this != null && name == 'Map' && library.isDartCore;
+  bool get isDartCoreMap => name == 'Map' && library.isDartCore;
 
   /// Return `true` if this element represents the class `Set` from
   /// `dart:core`.
-  bool get isDartCoreSet => this != null && name == 'Set' && library.isDartCore;
+  bool get isDartCoreSet => name == 'Set' && library.isDartCore;
 }
 
 extension ElementExtension on Element {
@@ -51,7 +49,10 @@
     if (name != 'cast') {
       return false;
     }
-    ClassElement definingClass = enclosingElement;
+    var definingClass = enclosingElement;
+    if (definingClass is! ClassElement) {
+      return false;
+    }
     return definingClass.isDartCoreIterable ||
         definingClass.isDartCoreList ||
         definingClass.isDartCoreMap ||
@@ -64,7 +65,10 @@
     if (name != 'toList') {
       return false;
     }
-    ClassElement definingClass = enclosingElement;
+    var definingClass = enclosingElement;
+    if (definingClass is! ClassElement) {
+      return false;
+    }
     return definingClass.isDartCoreIterable || definingClass.isDartCoreList;
   }
 }
diff --git a/pkg/analysis_server/lib/src/utilities/extensions/yaml.dart b/pkg/analysis_server/lib/src/utilities/extensions/yaml.dart
index 6ce971a..dfe4983 100644
--- a/pkg/analysis_server/lib/src/utilities/extensions/yaml.dart
+++ b/pkg/analysis_server/lib/src/utilities/extensions/yaml.dart
@@ -4,34 +4,10 @@
 
 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) {
-    for (var keyNode in nodes.keys) {
-      if (keyNode is YamlScalar && keyNode.value == key) {
-        return nodes[key];
-      }
-    }
-    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) {
+  YamlNode? childContainingOffset(int offset) {
     var node = this;
     if (node is YamlList) {
       for (var element in node.nodes) {
diff --git a/pkg/analysis_server/lib/src/utilities/file_string_sink.dart b/pkg/analysis_server/lib/src/utilities/file_string_sink.dart
index 9486dfa..81f8c37 100644
--- a/pkg/analysis_server/lib/src/utilities/file_string_sink.dart
+++ b/pkg/analysis_server/lib/src/utilities/file_string_sink.dart
@@ -6,19 +6,18 @@
 
 /// A string sink that write into a file.
 class FileStringSink implements StringSink {
-  IOSink _sink;
+  final IOSink _sink;
 
-  FileStringSink(String path) {
-    _sink = File(path).openWrite(mode: FileMode.append);
-  }
+  FileStringSink(String path)
+      : _sink = File(path).openWrite(mode: FileMode.append);
 
   @override
-  void write(Object obj) {
+  void write(Object? obj) {
     throw UnimplementedError();
   }
 
   @override
-  void writeAll(Iterable objects, [String separator = '']) {
+  void writeAll(Iterable<dynamic> objects, [String separator = '']) {
     throw UnimplementedError();
   }
 
@@ -28,7 +27,7 @@
   }
 
   @override
-  void writeln([Object obj = '']) {
+  void writeln([Object? obj = '']) {
     var currentTimeMillis = DateTime.now().millisecondsSinceEpoch;
     _sink.writeln('$currentTimeMillis $obj');
   }
diff --git a/pkg/analysis_server/lib/src/utilities/flutter.dart b/pkg/analysis_server/lib/src/utilities/flutter.dart
index 9243a189..234b645 100644
--- a/pkg/analysis_server/lib/src/utilities/flutter.dart
+++ b/pkg/analysis_server/lib/src/utilities/flutter.dart
@@ -54,7 +54,7 @@
   );
 
   /// Return the argument with the given [index], or `null` if none.
-  Expression argumentByIndex(List<Expression> arguments, int index) {
+  Expression? argumentByIndex(List<Expression> arguments, int index) {
     if (index < arguments.length) {
       return arguments[index];
     }
@@ -62,7 +62,7 @@
   }
 
   /// Return the named expression with the given [name], or `null` if none.
-  NamedExpression argumentByName(List<Expression> arguments, String name) {
+  NamedExpression? argumentByName(List<Expression> arguments, String name) {
     for (var argument in arguments) {
       if (argument is NamedExpression && argument.name.label.name == name) {
         return argument;
@@ -159,26 +159,40 @@
 
   /// Return the named expression representing the `child` argument of the given
   /// [newExpr], or `null` if none.
-  NamedExpression findChildArgument(InstanceCreationExpression newExpr) =>
-      newExpr.argumentList.arguments
-          .firstWhere(isChildArgument, orElse: () => null);
+  NamedExpression? findChildArgument(InstanceCreationExpression newExpr) {
+    for (var argument in newExpr.argumentList.arguments) {
+      if (argument is NamedExpression && isChildArgument(argument)) {
+        return argument;
+      }
+    }
+    return null;
+  }
 
   /// Return the named expression representing the `children` argument of the
   /// given [newExpr], or `null` if none.
-  NamedExpression findChildrenArgument(InstanceCreationExpression newExpr) =>
-      newExpr.argumentList.arguments
-          .firstWhere(isChildrenArgument, orElse: () => null);
+  NamedExpression? findChildrenArgument(InstanceCreationExpression newExpr) {
+    for (var argument in newExpr.argumentList.arguments) {
+      if (isChildrenArgument(argument)) {
+        return argument as NamedExpression;
+      }
+    }
+    return null;
+  }
 
   /// Return the Flutter instance creation expression that is the value of the
-  /// 'child' argument of the given [newExpr], or null if none.
-  InstanceCreationExpression findChildWidget(
+  /// 'child' argument of the given [newExpr], or `null` if none.
+  InstanceCreationExpression? findChildWidget(
       InstanceCreationExpression newExpr) {
     var child = findChildArgument(newExpr);
-    return getChildWidget(child);
+    var widget = getChildWidget(child);
+    if (widget is InstanceCreationExpression) {
+      return widget;
+    }
+    return null;
   }
 
   /// Return the named expression with the given [name], or `null` if none.
-  NamedExpression findNamedArgument(
+  NamedExpression? findNamedArgument(
     InstanceCreationExpression creation,
     String name,
   ) {
@@ -189,33 +203,30 @@
   /// If the given [node] is a simple identifier, find the named expression
   /// whose name is the given [name] that is an argument to a Flutter instance
   /// creation expression. Return null if any condition cannot be satisfied.
-  NamedExpression findNamedExpression(AstNode node, String name) {
+  NamedExpression? findNamedExpression(AstNode node, String name) {
     if (node is! SimpleIdentifier) {
       return null;
     }
-    SimpleIdentifier namedArg = node;
-    NamedExpression namedExp;
-    if (namedArg.parent is Label && namedArg.parent.parent is NamedExpression) {
-      namedExp = namedArg.parent.parent;
-      if (namedArg.name != name || namedExp.expression == null) {
+    var parent = node.parent;
+    var grandParent = parent?.parent;
+    if (parent is Label && grandParent is NamedExpression) {
+      if (node.name != name) {
         return null;
       }
     } else {
       return null;
     }
-    if (namedExp.parent?.parent is! InstanceCreationExpression) {
+    var invocation = grandParent.parent?.parent;
+    if (invocation is! InstanceCreationExpression ||
+        !isWidgetCreation(invocation)) {
       return null;
     }
-    InstanceCreationExpression newExpr = namedExp.parent.parent;
-    if (newExpr == null || !isWidgetCreation(newExpr)) {
-      return null;
-    }
-    return namedExp;
+    return grandParent;
   }
 
   /// Return the expression that is a Flutter Widget that is the value of the
   /// given [child], or null if none.
-  Expression getChildWidget(NamedExpression child) {
+  Expression? getChildWidget(NamedExpression? child) {
     var expression = child?.expression;
     if (isWidgetExpression(expression)) {
       return expression;
@@ -224,7 +235,7 @@
   }
 
   /// Return the presentation for the given Flutter `Widget` creation [node].
-  String getWidgetPresentationText(InstanceCreationExpression node) {
+  String? getWidgetPresentationText(InstanceCreationExpression node) {
     var element = node.constructorName.staticElement?.enclosingElement;
     if (!isWidget(element)) {
       return null;
@@ -248,21 +259,24 @@
         return 'Text';
       }
     }
-    return element.name;
+    return element?.name;
   }
 
   /// Return the instance creation expression that surrounds the given
   /// [node], if any, else null. The [node] may be the instance creation
   /// expression itself or the identifier that names the constructor.
-  InstanceCreationExpression identifyNewExpression(AstNode node) {
-    InstanceCreationExpression newExpr;
+  InstanceCreationExpression? identifyNewExpression(AstNode node) {
+    InstanceCreationExpression? newExpr;
     if (node is SimpleIdentifier) {
-      if (node.parent is ConstructorName &&
-          node.parent.parent is InstanceCreationExpression) {
-        newExpr = node.parent.parent;
-      } else if (node.parent?.parent is ConstructorName &&
-          node.parent.parent?.parent is InstanceCreationExpression) {
-        newExpr = node.parent.parent.parent;
+      var parent = node.parent;
+      var grandParent = parent?.parent;
+      var greatGrandParent = grandParent?.parent;
+      if (parent is ConstructorName &&
+          grandParent is InstanceCreationExpression) {
+        newExpr = grandParent;
+      } else if (grandParent is ConstructorName &&
+          greatGrandParent is InstanceCreationExpression) {
+        newExpr = greatGrandParent;
       }
     } else if (node is InstanceCreationExpression) {
       newExpr = node;
@@ -272,7 +286,7 @@
 
   /// Attempt to find and return the closest expression that encloses the [node]
   /// and is an independent Flutter `Widget`.  Return `null` if nothing found.
-  Expression identifyWidgetExpression(AstNode node) {
+  Expression? identifyWidgetExpression(AstNode? node) {
     for (; node != null; node = node.parent) {
       if (isWidgetExpression(node)) {
         var parent = node.parent;
@@ -282,7 +296,7 @@
         }
         if (parent is AssignmentExpression) {
           if (parent.rightHandSide == node) {
-            return node;
+            return node as Expression;
           }
           return null;
         }
@@ -297,7 +311,7 @@
             parent is ListLiteral ||
             parent is NamedExpression && parent.expression == node ||
             parent is Statement) {
-          return node;
+          return node as Expression;
         }
       }
       if (node is ArgumentList || node is Statement || node is FunctionBody) {
@@ -323,12 +337,9 @@
     }
 
     bool isColorElement(ClassElement element) {
-      if (element == null) {
-        return false;
-      }
-
       bool isExactColor(ClassElement element) =>
-          element?.name == 'Color' && element.library.name == 'dart.ui';
+          element.name == 'Color' && element.library.name == 'dart.ui';
+
       if (isExactColor(element)) {
         return true;
       }
@@ -345,19 +356,16 @@
 
   /// Return `true` if the given [type] is the flutter mixin `Diagnosticable`
   /// or its subtype.
-  bool isDiagnosticable(DartType type) {
+  bool isDiagnosticable(DartType? type) {
     if (type is! InterfaceType) {
       return false;
     }
 
     bool isDiagnosticableElement(ClassElement element) {
-      if (element == null) {
-        return false;
-      }
-
       bool isExactDiagnosticable(ClassElement element) =>
-          element?.name == 'Diagnosticable' &&
+          element.name == 'Diagnosticable' &&
           element.source.uri == _uriDiagnostics;
+
       if (isExactDiagnosticable(element)) {
         return true;
       }
@@ -395,25 +403,25 @@
   }
 
   /// Return `true` if the [node] is creation of `Align`.
-  bool isExactlyAlignCreation(InstanceCreationExpression node) {
+  bool isExactlyAlignCreation(InstanceCreationExpression? node) {
     var type = node?.staticType;
     return isExactWidgetTypeAlign(type);
   }
 
   /// Return `true` if the [node] is creation of `Container`.
-  bool isExactlyContainerCreation(InstanceCreationExpression node) {
+  bool isExactlyContainerCreation(InstanceCreationExpression? node) {
     var type = node?.staticType;
     return isExactWidgetTypeContainer(type);
   }
 
   /// Return `true` if the [node] is creation of `Padding`.
-  bool isExactlyPaddingCreation(InstanceCreationExpression node) {
+  bool isExactlyPaddingCreation(InstanceCreationExpression? node) {
     var type = node?.staticType;
     return isExactWidgetTypePadding(type);
   }
 
   /// Return `true` if the given [type] is the Flutter class `StatefulWidget`.
-  bool isExactlyStatefulWidgetType(DartType type) {
+  bool isExactlyStatefulWidgetType(DartType? type) {
     return type is InterfaceType &&
         _isExactWidget(type.element, _nameStatefulWidget, _uriFramework);
   }
@@ -430,7 +438,7 @@
   }
 
   /// Return `true` if the given [type] is the Flutter class `Align`.
-  bool isExactWidgetTypeAlign(DartType type) {
+  bool isExactWidgetTypeAlign(DartType? type) {
     return type is InterfaceType &&
         _isExactWidget(type.element, _nameAlign, _uriBasic);
   }
@@ -442,13 +450,13 @@
   }
 
   /// Return `true` if the given [type] is the Flutter class `Container`.
-  bool isExactWidgetTypeContainer(DartType type) {
+  bool isExactWidgetTypeContainer(DartType? type) {
     return type is InterfaceType &&
         _isExactWidget(type.element, _nameContainer, _uriContainer);
   }
 
   /// Return `true` if the given [type] is the Flutter class `Padding`.
-  bool isExactWidgetTypePadding(DartType type) {
+  bool isExactWidgetTypePadding(DartType? type) {
     return type is InterfaceType &&
         _isExactWidget(type.element, _namePadding, _uriBasic);
   }
@@ -481,13 +489,9 @@
     }
 
     bool isMatrix4Element(ClassElement element) {
-      if (element == null) {
-        return false;
-      }
-
       bool isExactMatrix4(ClassElement element) =>
-          element?.name == 'Matrix4' &&
-          element.library.name == 'vector_math_64';
+          element.name == 'Matrix4' && element.library.name == 'vector_math_64';
+
       if (isExactMatrix4(element)) {
         return true;
       }
@@ -504,7 +508,7 @@
 
   /// Return `true` if the given [element] has the Flutter class `State` as
   /// a superclass.
-  bool isState(ClassElement element) {
+  bool isState(ClassElement? element) {
     return _hasSupertype(element, _uriFramework, _nameState);
   }
 
@@ -519,7 +523,7 @@
 
   /// Return `true` if the given [element] is the Flutter class `Widget`, or its
   /// subtype.
-  bool isWidget(ClassElement element) {
+  bool isWidget(ClassElement? element) {
     if (element == null) {
       return false;
     }
@@ -536,14 +540,14 @@
 
   /// Return `true` if the given [expr] is a constructor invocation for a
   /// class that has the Flutter class `Widget` as a superclass.
-  bool isWidgetCreation(InstanceCreationExpression expr) {
-    var element = expr?.constructorName?.staticElement?.enclosingElement;
+  bool isWidgetCreation(InstanceCreationExpression? expr) {
+    var element = expr?.constructorName.staticElement?.enclosingElement;
     return isWidget(element);
   }
 
   /// Return `true` if the given [node] is the Flutter class `Widget`, or its
   /// subtype.
-  bool isWidgetExpression(AstNode node) {
+  bool isWidgetExpression(AstNode? node) {
     if (node == null) {
       return false;
     }
@@ -564,14 +568,14 @@
 
   /// Return `true` if the given [type] is the Flutter class `Widget`, or its
   /// subtype.
-  bool isWidgetType(DartType type) {
+  bool isWidgetType(DartType? type) {
     return type is InterfaceType && isWidget(type.element);
   }
 
   /// Return `true` if the given [element] has a supertype with the
   /// [requiredName] defined in the file with the [requiredUri].
   bool _hasSupertype(
-      ClassElement element, Uri requiredUri, String requiredName) {
+      ClassElement? element, Uri requiredUri, String requiredName) {
     if (element == null) {
       return false;
     }
@@ -588,7 +592,7 @@
 
   /// Return `true` if the given [element] is the exact [type] defined in the
   /// file with the given [uri].
-  bool _isExactWidget(ClassElement element, String type, Uri uri) {
+  bool _isExactWidget(ClassElement? element, String type, Uri uri) {
     return element != null && element.name == type && element.source.uri == uri;
   }
 }
diff --git a/pkg/analysis_server/lib/src/utilities/mocks.dart b/pkg/analysis_server/lib/src/utilities/mocks.dart
index 9775fee..6c4134a 100644
--- a/pkg/analysis_server/lib/src/utilities/mocks.dart
+++ b/pkg/analysis_server/lib/src/utilities/mocks.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
+
 import 'dart:async';
 
 import 'package:analysis_server/protocol/protocol.dart';
diff --git a/pkg/analysis_server/lib/src/utilities/null_string_sink.dart b/pkg/analysis_server/lib/src/utilities/null_string_sink.dart
index 3f6b29e..3af2f4a 100644
--- a/pkg/analysis_server/lib/src/utilities/null_string_sink.dart
+++ b/pkg/analysis_server/lib/src/utilities/null_string_sink.dart
@@ -5,11 +5,14 @@
 /// A string sink that ignores everything written to it.
 class NullStringSink implements StringSink {
   @override
-  void write(Object obj) {}
+  void write(Object? obj) {}
+
   @override
-  void writeAll(Iterable objects, [String separator = '']) {}
+  void writeAll(Iterable<dynamic> objects, [String separator = '']) {}
+
   @override
   void writeCharCode(int charCode) {}
+
   @override
-  void writeln([Object obj = '']) {}
+  void writeln([Object? obj = '']) {}
 }
diff --git a/pkg/analysis_server/lib/src/utilities/profiling.dart b/pkg/analysis_server/lib/src/utilities/profiling.dart
index 1d18313..b5e41fb 100644
--- a/pkg/analysis_server/lib/src/utilities/profiling.dart
+++ b/pkg/analysis_server/lib/src/utilities/profiling.dart
@@ -9,12 +9,12 @@
 abstract class ProcessProfiler {
   ProcessProfiler._();
 
-  Future<UsageInfo> getProcessUsage(int processId);
+  Future<UsageInfo?> getProcessUsage(int processId);
 
   /// Return a [ProcessProfiler] instance suitable for the current host
   /// platform. This can return `null` if we're not able to gather memory and
   /// cpu information for the current platform.
-  static ProcessProfiler getProfilerForPlatform() {
+  static ProcessProfiler? getProfilerForPlatform() {
     if (Platform.isLinux || Platform.isMacOS) {
       return _PosixProcessProfiler();
     }
@@ -46,7 +46,7 @@
   _PosixProcessProfiler() : super._();
 
   @override
-  Future<UsageInfo> getProcessUsage(int processId) {
+  Future<UsageInfo?> getProcessUsage(int processId) {
     try {
       // Execution time is typically 2-4ms.
       var future =
@@ -63,7 +63,7 @@
     }
   }
 
-  UsageInfo _parse(String psResults) {
+  UsageInfo? _parse(String psResults) {
     try {
       // "  0.0 378940"
       var line = psResults.split('\n').first.trim();
diff --git a/pkg/analysis_server/lib/src/utilities/request_statistics.dart b/pkg/analysis_server/lib/src/utilities/request_statistics.dart
index 828dd36..044be84 100644
--- a/pkg/analysis_server/lib/src/utilities/request_statistics.dart
+++ b/pkg/analysis_server/lib/src/utilities/request_statistics.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
+
 import 'dart:convert';
 import 'dart:io';
 
diff --git a/pkg/analysis_server/lib/src/utilities/stream.dart b/pkg/analysis_server/lib/src/utilities/stream.dart
new file mode 100644
index 0000000..5ac8669
--- /dev/null
+++ b/pkg/analysis_server/lib/src/utilities/stream.dart
@@ -0,0 +1,61 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. 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 MoreTypedStreamController<T, ListenData, PauseData> {
+  final StreamController<T> controller;
+
+  /// A wrapper around [StreamController] that statically guarantees its
+  /// clients that [onPause] and [onCancel] can only be invoked after
+  /// [onListen], and [onResume] can only be invoked after [onPause].
+  ///
+  /// There is no static guarantee that [onPause] will not be invoked twice.
+  ///
+  /// Internally the wrapper is not safe, and uses explicit null checks.
+  factory MoreTypedStreamController({
+    required ListenData Function(StreamController<T>) onListen,
+    PauseData Function(ListenData)? onPause,
+    void Function(ListenData, PauseData)? onResume,
+    FutureOr<void> Function(ListenData)? onCancel,
+    bool sync = false,
+  }) {
+    ListenData? listenData;
+    PauseData? pauseData;
+    var controller = StreamController<T>(
+      onPause: () {
+        if (pauseData != null) {
+          throw StateError('Already paused');
+        }
+        var local_onPause = onPause;
+        if (local_onPause != null) {
+          pauseData = local_onPause(listenData!);
+        }
+      },
+      onResume: () {
+        var local_onResume = onResume;
+        if (local_onResume != null) {
+          var local_pauseData = pauseData!;
+          pauseData = null;
+          local_onResume(listenData!, local_pauseData);
+        }
+      },
+      onCancel: () {
+        var local_onCancel = onCancel;
+        if (local_onCancel != null) {
+          var local_listenData = listenData!;
+          listenData = null;
+          local_onCancel(local_listenData);
+        }
+      },
+      sync: sync,
+    );
+    controller.onListen = () {
+      listenData = onListen(controller);
+    };
+    return MoreTypedStreamController._(controller);
+  }
+
+  MoreTypedStreamController._(this.controller);
+}
diff --git a/pkg/analysis_server/lib/src/utilities/strings.dart b/pkg/analysis_server/lib/src/utilities/strings.dart
index 42155b9..e13bfae 100644
--- a/pkg/analysis_server/lib/src/utilities/strings.dart
+++ b/pkg/analysis_server/lib/src/utilities/strings.dart
@@ -4,22 +4,20 @@
 
 import 'dart:math';
 
-import 'package:analyzer_plugin/src/utilities/string_utilities.dart';
-
 /// "$"
 const int CHAR_DOLLAR = 0x24;
 
 /// "_"
 const int CHAR_UNDERSCORE = 0x5F;
 
-String capitalize(String str) {
-  if (isEmpty(str)) {
+String? capitalize(String? str) {
+  if (str == null || str.isEmpty) {
     return str;
   }
   return str.substring(0, 1).toUpperCase() + str.substring(1);
 }
 
-int compareStrings(String a, String b) {
+int compareStrings(String? a, String? b) {
   if (a == b) {
     return 0;
   }
@@ -60,8 +58,8 @@
 }
 
 /// Counts how many times [sub] appears in [str].
-int countMatches(String str, String sub) {
-  if (isEmpty(str) || isEmpty(sub)) {
+int countMatches(String? str, String? sub) {
+  if (str == null || str.isEmpty || sub == null || sub.isEmpty) {
     return 0;
   }
   var count = 0;
@@ -109,11 +107,8 @@
 }
 
 /// Checks if [str] is `null`, empty or is whitespace.
-bool isBlank(String str) {
-  if (str == null) {
-    return true;
-  }
-  if (str.isEmpty) {
+bool isBlank(String? str) {
+  if (str == null || str.isEmpty) {
     return true;
   }
   return str.codeUnits.every(isSpace);
@@ -141,8 +136,8 @@
   return isSpace(c) || isEOL(c);
 }
 
-String removeEnd(String str, String remove) {
-  if (isEmpty(str) || isEmpty(remove)) {
+String? removeEnd(String? str, String? remove) {
+  if (str == null || str.isEmpty || remove == null || remove.isEmpty) {
     return str;
   }
   if (str.endsWith(remove)) {
diff --git a/pkg/analysis_server/lib/src/utilities/tee_string_sink.dart b/pkg/analysis_server/lib/src/utilities/tee_string_sink.dart
index 978c4ed..2b715c2 100644
--- a/pkg/analysis_server/lib/src/utilities/tee_string_sink.dart
+++ b/pkg/analysis_server/lib/src/utilities/tee_string_sink.dart
@@ -10,13 +10,13 @@
   TeeStringSink(this.sink1, this.sink2);
 
   @override
-  void write(Object obj) {
+  void write(Object? obj) {
     sink1.write(obj);
     sink2.write(obj);
   }
 
   @override
-  void writeAll(Iterable objects, [String separator = '']) {
+  void writeAll(Iterable<dynamic> objects, [String separator = '']) {
     sink1.writeAll(objects, separator);
     sink2.writeAll(objects, separator);
   }
@@ -28,7 +28,7 @@
   }
 
   @override
-  void writeln([Object obj = '']) {
+  void writeln([Object? obj = '']) {
     sink1.writeln(obj);
     sink2.writeln(obj);
   }
diff --git a/pkg/analysis_server/lib/src/utilities/yaml_node_locator.dart b/pkg/analysis_server/lib/src/utilities/yaml_node_locator.dart
index 809748f..c8c49ef 100644
--- a/pkg/analysis_server/lib/src/utilities/yaml_node_locator.dart
+++ b/pkg/analysis_server/lib/src/utilities/yaml_node_locator.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:meta/meta.dart';
 import 'package:yaml/yaml.dart';
 
 /// An object used to locate the [YamlNode] associated with a source range.
@@ -20,7 +19,7 @@
   ///
   /// If the [end] offset is not provided, then it is considered the same as the
   /// [start] offset.
-  YamlNodeLocator({@required int start, int end})
+  YamlNodeLocator({required int start, int? end})
       : _startOffset = start,
         _endOffset = end ?? start;
 
@@ -49,13 +48,13 @@
       }
     } else if (node is YamlMap) {
       var nodeMap = node.nodes;
-      for (YamlNode key in nodeMap.keys) {
-        _searchWithin(path, key);
+      for (var entry in nodeMap.entries) {
+        _searchWithin(path, entry.key);
         if (path.isNotEmpty) {
           path.add(node);
           return;
         }
-        _searchWithin(path, nodeMap[key]);
+        _searchWithin(path, entry.value);
         if (path.isNotEmpty) {
           path.add(node);
           return;
diff --git a/pkg/analysis_server/lib/starter.dart b/pkg/analysis_server/lib/starter.dart
index 78fb773..a8d4451 100644
--- a/pkg/analysis_server/lib/starter.dart
+++ b/pkg/analysis_server/lib/starter.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
+
 import 'dart:isolate';
 
 import 'package:analysis_server/src/server/crash_reporting_attachments.dart';
diff --git a/pkg/analysis_server/pubspec.yaml b/pkg/analysis_server/pubspec.yaml
index c968f5b..5629eb1 100644
--- a/pkg/analysis_server/pubspec.yaml
+++ b/pkg/analysis_server/pubspec.yaml
@@ -3,7 +3,7 @@
 publish_to: none
 
 environment:
-  sdk: '>=2.6.0 <3.0.0'
+  sdk: '>=2.12.0 <3.0.0'
 
 dependencies:
   _fe_analyzer_shared:
diff --git a/pkg/analysis_server/test/abstract_context.dart b/pkg/analysis_server/test/abstract_context.dart
index 6e069d0..eeb1471 100644
--- a/pkg/analysis_server/test/abstract_context.dart
+++ b/pkg/analysis_server/test/abstract_context.dart
@@ -24,8 +24,8 @@
 import 'src/utilities/mock_packages.dart';
 
 /// Finds an [Element] with the given [name].
-Element findChildElement(Element root, String name, [ElementKind kind]) {
-  Element result;
+Element? findChildElement(Element root, String name, [ElementKind? kind]) {
+  Element? result;
   root.accept(_ElementVisitorFunctionWrapper((Element element) {
     if (element.name != name) {
       return;
@@ -47,11 +47,11 @@
   final ByteStore _byteStore = MemoryByteStore();
 
   final Map<String, String> _declaredVariables = {};
-  AnalysisContextCollectionImpl _analysisContextCollection;
+  AnalysisContextCollectionImpl? _analysisContextCollection;
 
   List<AnalysisDriver> get allDrivers {
     _createAnalysisContexts();
-    return _analysisContextCollection.contexts.map((e) => e.driver).toList();
+    return _analysisContextCollection!.contexts.map((e) => e.driver).toList();
   }
 
   /// The file system specific `/home/test/analysis_options.yaml` path.
@@ -71,7 +71,7 @@
 
   AnalysisSession get session => contextFor('/home/test').currentSession;
 
-  String get testPackageLanguageVersion => '2.9';
+  String? get testPackageLanguageVersion => '2.9';
 
   String get testPackageLibPath => '$testPackageRootPath/lib';
 
@@ -105,9 +105,9 @@
 
   /// Create an analysis options file based on the given arguments.
   void createAnalysisOptionsFile({
-    List<String> experiments,
-    bool implicitCasts,
-    List<String> lints,
+    List<String>? experiments,
+    bool? implicitCasts,
+    List<String>? lints,
   }) {
     var buffer = StringBuffer();
 
@@ -145,16 +145,16 @@
   /// Return the existing analysis context that should be used to analyze the
   /// given [path], or throw [StateError] if the [path] is not analyzed in any
   /// of the created analysis contexts.
-  AnalysisContext getContext(String path) {
+  DriverBasedAnalysisContext getContext(String path) {
     path = convertPath(path);
-    return _analysisContextCollection.contextFor(path);
+    return _analysisContextCollection!.contextFor(path);
   }
 
   /// Return the existing analysis driver that should be used to analyze the
   /// given [path], or throw [StateError] if the [path] is not analyzed in any
   /// of the created analysis contexts.
   AnalysisDriver getDriver(String path) {
-    DriverBasedAnalysisContext context = getContext(path);
+    var context = getContext(path);
     return context.driver;
   }
 
@@ -208,8 +208,8 @@
   }
 
   void writeTestPackageConfig({
-    PackageConfigFileBuilder config,
-    String languageVersion,
+    PackageConfigFileBuilder? config,
+    String? languageVersion,
     bool flutter = false,
     bool meta = false,
     bool vector_math = false,
@@ -252,7 +252,7 @@
   }
 
   void _addAnalyzedFilesToDrivers() {
-    for (var analysisContext in _analysisContextCollection.contexts) {
+    for (var analysisContext in _analysisContextCollection!.contexts) {
       for (var path in analysisContext.contextRoot.analyzedFiles()) {
         if (file_paths.isDart(resourceProvider.pathContext, path)) {
           analysisContext.driver.addFile(path);
@@ -262,8 +262,9 @@
   }
 
   void _addAnalyzedFileToDrivers(String path) {
-    if (_analysisContextCollection != null) {
-      for (var analysisContext in _analysisContextCollection.contexts) {
+    var collection = _analysisContextCollection;
+    if (collection != null) {
+      for (var analysisContext in collection.contexts) {
         if (analysisContext.contextRoot.isAnalyzed(path)) {
           analysisContext.driver.addFile(path);
         }
@@ -275,7 +276,7 @@
     _createAnalysisContexts();
 
     path = convertPath(path);
-    return _analysisContextCollection.contextFor(path);
+    return _analysisContextCollection!.contextFor(path);
   }
 
   /// Create all analysis contexts in [collectionIncludedPaths].
@@ -300,7 +301,7 @@
 
 mixin WithNonFunctionTypeAliasesMixin on AbstractContextTest {
   @override
-  String get testPackageLanguageVersion => null;
+  String? get testPackageLanguageVersion => null;
 
   @override
   void setUp() {
diff --git a/pkg/analysis_server/test/abstract_single_unit.dart b/pkg/analysis_server/test/abstract_single_unit.dart
index 1a04502..6e2a9e5 100644
--- a/pkg/analysis_server/test/abstract_single_unit.dart
+++ b/pkg/analysis_server/test/abstract_single_unit.dart
@@ -21,14 +21,14 @@
   /// Whether to rewrite line endings in test code based on platform.
   bool useLineEndingsForPlatform = false;
 
-  String testCode;
-  String testFile;
-  ResolvedUnitResult testAnalysisResult;
-  CompilationUnit testUnit;
-  CompilationUnitElement testUnitElement;
-  LibraryElement testLibraryElement;
-  FindNode findNode;
-  FindElement findElement;
+  late String testCode;
+  late String testFile;
+  ResolvedUnitResult? testAnalysisResult;
+  late CompilationUnit testUnit;
+  late CompilationUnitElement testUnitElement;
+  late LibraryElement testLibraryElement;
+  late FindNode findNode;
+  late FindElement findElement;
 
   @override
   void addSource(String path, String content) {
@@ -70,11 +70,12 @@
   }
 
   Future<void> resolveTestFile() async {
-    testAnalysisResult = await session.getResolvedUnit(testFile);
-    testCode = testAnalysisResult.content;
-    testUnit = testAnalysisResult.unit;
+    var result = await session.getResolvedUnit(testFile);
+    testAnalysisResult = result;
+    testCode = result.content!;
+    testUnit = result.unit!;
     if (verifyNoTestUnitErrors) {
-      expect(testAnalysisResult.errors.where((AnalysisError error) {
+      expect(result.errors.where((AnalysisError error) {
         return error.errorCode != HintCode.DEAD_CODE &&
             error.errorCode != HintCode.UNUSED_CATCH_CLAUSE &&
             error.errorCode != HintCode.UNUSED_CATCH_STACK &&
@@ -84,7 +85,7 @@
             error.errorCode != HintCode.UNUSED_LOCAL_VARIABLE;
       }), isEmpty);
     }
-    testUnitElement = testUnit.declaredElement;
+    testUnitElement = testUnit.declaredElement!;
     testLibraryElement = testUnitElement.library;
     findNode = FindNode(testCode, testUnit);
     findElement = FindElement(testUnit);
diff --git a/pkg/analysis_server/test/analysis/bazel_changes_test.dart b/pkg/analysis_server/test/analysis/bazel_changes_test.dart
deleted file mode 100644
index 896d08c..0000000
--- a/pkg/analysis_server/test/analysis/bazel_changes_test.dart
+++ /dev/null
@@ -1,88 +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:analysis_server/protocol/protocol.dart';
-import 'package:analysis_server/protocol/protocol_constants.dart';
-import 'package:analysis_server/protocol/protocol_generated.dart';
-import 'package:analysis_server/src/context_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 '../analysis_abstract.dart';
-
-void main() {
-  defineReflectiveSuite(() {
-    defineReflectiveTests(BazelChangesTest);
-  });
-}
-
-@reflectiveTest
-class BazelChangesTest extends AbstractAnalysisTest {
-  Map<String, List<AnalysisError>> filesErrors = {};
-  Completer<void> processedNotification;
-
-  @override
-  void processNotification(Notification notification) {
-    if (notification.event == ANALYSIS_NOTIFICATION_ERRORS) {
-      var decoded = AnalysisErrorsParams.fromNotification(notification);
-      filesErrors[decoded.file] = decoded.errors;
-      processedNotification?.complete();
-    }
-  }
-
-  @override
-  void setUp() {
-    super.setUp();
-
-    experimentalEnableBazelWatching = true;
-
-    projectPath = convertPath('/workspaceRoot/third_party/dart/project');
-    testFile =
-        convertPath('/workspaceRoot/third_party/dart/project/lib/test.dart');
-    newFile('/workspaceRoot/WORKSPACE');
-    newFolder('/workspaceRoot/bazel-lib/project');
-    newFolder('/workspaceRoot/bazel-genfiles/project');
-  }
-
-  @override
-  void tearDown() {
-    // Make sure to destroy all the contexts and cancel all subscriptions to
-    // file watchers.
-    server.contextManager.setRoots([], []);
-
-    experimentalEnableBazelWatching = false;
-
-    super.tearDown();
-  }
-
-  Future<void> test_findingFileInGenfiles() async {
-    processedNotification = Completer();
-
-    newFile(testFile, content: r'''
-import 'generated.dart';
-void main() { fun(); }
-''');
-    createProject();
-
-    // We should have some errors since the `generated.dart` is not there yet.
-    await processedNotification.future;
-    expect(filesErrors[testFile], isNotEmpty);
-
-    // Clear errors, so that we'll notice new results.
-    filesErrors.clear();
-    processedNotification = Completer();
-
-    // Simulate the creation of a generated file.
-    newFile(
-        '/workspaceRoot/bazel-genfiles/'
-        'third_party/dart/project/lib/generated.dart',
-        content: 'fun() {}');
-
-    // No errors.
-    await processedNotification.future;
-    expect(filesErrors[testFile], isEmpty);
-  }
-}
diff --git a/pkg/analysis_server/test/analysis/get_errors_test.dart b/pkg/analysis_server/test/analysis/get_errors_test.dart
index 5707925..145a3a5 100644
--- a/pkg/analysis_server/test/analysis/get_errors_test.dart
+++ b/pkg/analysis_server/test/analysis/get_errors_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/protocol/protocol.dart';
 import 'package:analysis_server/protocol/protocol_generated.dart';
 import 'package:analysis_server/src/domain_analysis.dart';
diff --git a/pkg/analysis_server/test/analysis/get_hover_test.dart b/pkg/analysis_server/test/analysis/get_hover_test.dart
index d1133a8..47d5d33 100644
--- a/pkg/analysis_server/test/analysis/get_hover_test.dart
+++ b/pkg/analysis_server/test/analysis/get_hover_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/protocol/protocol_generated.dart';
 import 'package:meta/meta.dart';
 import 'package:test/test.dart';
@@ -17,8 +19,7 @@
 }
 
 @reflectiveTest
-class AnalysisHoverTest extends AbstractAnalysisTest
-    with WithNonFunctionTypeAliasesMixin {
+class AnalysisHoverTest extends AbstractAnalysisTest {
   Future<HoverInformation> prepareHover(String search) {
     var offset = findOffset(search);
     return prepareHoverAt(offset);
diff --git a/pkg/analysis_server/test/analysis/get_navigation_test.dart b/pkg/analysis_server/test/analysis/get_navigation_test.dart
index 9e2b5d6..99943b9 100644
--- a/pkg/analysis_server/test/analysis/get_navigation_test.dart
+++ b/pkg/analysis_server/test/analysis/get_navigation_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/protocol/protocol.dart';
 import 'package:analysis_server/protocol/protocol_generated.dart';
 import 'package:analysis_server/src/domain_analysis.dart';
diff --git a/pkg/analysis_server/test/analysis/get_signature_test.dart b/pkg/analysis_server/test/analysis/get_signature_test.dart
index 3eb51ae..5d4e202 100644
--- a/pkg/analysis_server/test/analysis/get_signature_test.dart
+++ b/pkg/analysis_server/test/analysis/get_signature_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/protocol_server.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/analysis/notification_analysis_options_test.dart b/pkg/analysis_server/test/analysis/notification_analysis_options_test.dart
index d9b3a95..55924d9 100644
--- a/pkg/analysis_server/test/analysis/notification_analysis_options_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_analysis_options_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/protocol/protocol.dart';
 import 'package:analysis_server/protocol/protocol_constants.dart';
 import 'package:analysis_server/protocol/protocol_generated.dart'
diff --git a/pkg/analysis_server/test/analysis/notification_analyzed_files_test.dart b/pkg/analysis_server/test/analysis/notification_analyzed_files_test.dart
index c574991..9561c95 100644
--- a/pkg/analysis_server/test/analysis/notification_analyzed_files_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_analyzed_files_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/protocol/protocol.dart';
 import 'package:analysis_server/protocol/protocol_constants.dart';
 import 'package:analysis_server/protocol/protocol_generated.dart';
diff --git a/pkg/analysis_server/test/analysis/notification_closing_labels_test.dart b/pkg/analysis_server/test/analysis/notification_closing_labels_test.dart
index e3873d3..da4b925 100644
--- a/pkg/analysis_server/test/analysis/notification_closing_labels_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_closing_labels_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.
 
+// @dart = 2.9
+
 import 'dart:async';
 
 import 'package:analysis_server/protocol/protocol.dart';
diff --git a/pkg/analysis_server/test/analysis/notification_errors_test.dart b/pkg/analysis_server/test/analysis/notification_errors_test.dart
index 4bbe367..04dba84 100644
--- a/pkg/analysis_server/test/analysis/notification_errors_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_errors_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/protocol/protocol.dart';
 import 'package:analysis_server/protocol/protocol_constants.dart';
 import 'package:analysis_server/protocol/protocol_generated.dart';
diff --git a/pkg/analysis_server/test/analysis/notification_folding_test.dart b/pkg/analysis_server/test/analysis/notification_folding_test.dart
index 09a78a5..d00446f 100644
--- a/pkg/analysis_server/test/analysis/notification_folding_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_folding_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.
 
+// @dart = 2.9
+
 import 'dart:async';
 
 import 'package:analysis_server/protocol/protocol_constants.dart';
diff --git a/pkg/analysis_server/test/analysis/notification_highlights2_test.dart b/pkg/analysis_server/test/analysis/notification_highlights2_test.dart
index 3ac8da4..7bab497 100644
--- a/pkg/analysis_server/test/analysis/notification_highlights2_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_highlights2_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.
 
+// @dart = 2.9
+
 import 'dart:async';
 
 import 'package:analysis_server/protocol/protocol.dart';
@@ -21,8 +23,7 @@
 }
 
 @reflectiveTest
-class AnalysisNotificationHighlightsTest extends HighlightsTestSupport
-    with WithNonFunctionTypeAliasesMixin {
+class AnalysisNotificationHighlightsTest extends HighlightsTestSupport {
   Future<void> test_ANNOTATION_hasArguments() async {
     addTestFile('''
 class AAA {
@@ -35,6 +36,21 @@
     assertHasRegion(HighlightRegionType.ANNOTATION, ') main', ')'.length);
   }
 
+  Future<void> test_ANNOTATION_hasTypeArguments_hasArguments() async {
+    addTestFile('''
+class AAA<T> {
+  const AAA(a, b, c);
+}
+
+@AAA<int>(1, 2, 3) void f() {}
+''');
+    await prepareHighlights();
+    assertHasRegion(
+        HighlightRegionType.ANNOTATION, '@AAA', '@AAA<int>('.length);
+    assertHasRegion(HighlightRegionType.ANNOTATION, ') void', ')'.length);
+    assertHasRegion(HighlightRegionType.CLASS, 'int>');
+  }
+
   Future<void> test_ANNOTATION_noArguments() async {
     addTestFile('''
 const AAA = 42;
diff --git a/pkg/analysis_server/test/analysis/notification_implemented_test.dart b/pkg/analysis_server/test/analysis/notification_implemented_test.dart
index 43a5a24..cc1b1c8 100644
--- a/pkg/analysis_server/test/analysis/notification_implemented_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_implemented_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/protocol/protocol.dart';
 import 'package:analysis_server/protocol/protocol_constants.dart';
 import 'package:analysis_server/protocol/protocol_generated.dart';
diff --git a/pkg/analysis_server/test/analysis/notification_navigation_test.dart b/pkg/analysis_server/test/analysis/notification_navigation_test.dart
index f7a70e9..c99d007 100644
--- a/pkg/analysis_server/test/analysis/notification_navigation_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_navigation_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.
 
+// @dart = 2.9
+
 import 'dart:async';
 
 import 'package:analysis_server/protocol/protocol.dart';
@@ -19,8 +21,7 @@
   });
 }
 
-class AbstractNavigationTest extends AbstractAnalysisTest
-    with WithNonFunctionTypeAliasesMixin {
+class AbstractNavigationTest extends AbstractAnalysisTest {
   List<NavigationRegion> regions;
   List<NavigationTarget> targets;
   List<String> targetFiles;
@@ -197,6 +198,53 @@
     assertHasRegionTarget('AAA aaa;', 'AAA {}');
   }
 
+  Future<void> test_annotation_generic_typeArguments_class() async {
+    addTestFile('''
+class A<T> {
+  const A();
+}
+
+@A<int>()
+void f() {}
+''');
+    await prepareNavigation();
+    assertHasRegion('int>()');
+  }
+
+  Future<void> test_annotationConstructor_generic_named() async {
+    addTestFile('''
+class A<T> {
+  const A.named(_);
+}
+
+@A<int>.named(0)
+void f() {}
+''');
+    await prepareNavigation();
+    {
+      assertHasRegion('A<int>.named(0)');
+      assertHasTarget('named(_);');
+    }
+    {
+      assertHasRegion('named(0)');
+      assertHasTarget('named(_);');
+    }
+  }
+
+  Future<void> test_annotationConstructor_generic_unnamed() async {
+    addTestFile('''
+class A<T> {
+  const A(_);
+}
+
+@A<int>(0)
+void f() {}
+''');
+    await prepareNavigation();
+    assertHasRegionString('A<int>(0)', 'A'.length);
+    assertHasTarget('A(_);', 0);
+  }
+
   Future<void> test_annotationConstructor_implicit() async {
     addTestFile('''
 class A {
diff --git a/pkg/analysis_server/test/analysis/notification_occurrences_test.dart b/pkg/analysis_server/test/analysis/notification_occurrences_test.dart
index 31fe525..bf46653 100644
--- a/pkg/analysis_server/test/analysis/notification_occurrences_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_occurrences_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.
 
+// @dart = 2.9
+
 import 'dart:async';
 
 import 'package:analysis_server/protocol/protocol.dart';
diff --git a/pkg/analysis_server/test/analysis/notification_outline_test.dart b/pkg/analysis_server/test/analysis/notification_outline_test.dart
index d43aeb2..f372764 100644
--- a/pkg/analysis_server/test/analysis/notification_outline_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_outline_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.
 
+// @dart = 2.9
+
 import 'dart:async';
 
 import 'package:analysis_server/protocol/protocol.dart';
diff --git a/pkg/analysis_server/test/analysis/notification_overrides_test.dart b/pkg/analysis_server/test/analysis/notification_overrides_test.dart
index 8ac4dd2..14f5294 100644
--- a/pkg/analysis_server/test/analysis/notification_overrides_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_overrides_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.
 
+// @dart = 2.9
+
 import 'dart:async';
 
 import 'package:analysis_server/protocol/protocol.dart';
diff --git a/pkg/analysis_server/test/analysis/reanalyze_test.dart b/pkg/analysis_server/test/analysis/reanalyze_test.dart
index 358df55..934e6cc 100644
--- a/pkg/analysis_server/test/analysis/reanalyze_test.dart
+++ b/pkg/analysis_server/test/analysis/reanalyze_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/protocol/protocol.dart';
 import 'package:analysis_server/protocol/protocol_constants.dart';
 import 'package:analysis_server/protocol/protocol_generated.dart';
diff --git a/pkg/analysis_server/test/analysis/set_priority_files_test.dart b/pkg/analysis_server/test/analysis/set_priority_files_test.dart
index 46d189d..8554189 100644
--- a/pkg/analysis_server/test/analysis/set_priority_files_test.dart
+++ b/pkg/analysis_server/test/analysis/set_priority_files_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/protocol/protocol.dart';
 import 'package:analysis_server/protocol/protocol_generated.dart';
 import 'package:analysis_server/src/domain_analysis.dart';
diff --git a/pkg/analysis_server/test/analysis/test_all.dart b/pkg/analysis_server/test/analysis/test_all.dart
index 3329d7f..8954813 100644
--- a/pkg/analysis_server/test/analysis/test_all.dart
+++ b/pkg/analysis_server/test/analysis/test_all.dart
@@ -2,9 +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 'package:test_reflective_loader/test_reflective_loader.dart';
 
-import 'bazel_changes_test.dart' as bazel_changes;
 import 'get_errors_test.dart' as get_errors;
 import 'get_hover_test.dart' as get_hover;
 import 'get_navigation_test.dart' as get_navigation;
@@ -27,7 +28,6 @@
 
 void main() {
   defineReflectiveSuite(() {
-    bazel_changes.main();
     get_errors.main();
     get_hover.main();
     get_navigation.main();
diff --git a/pkg/analysis_server/test/analysis/update_content_test.dart b/pkg/analysis_server/test/analysis/update_content_test.dart
index d8ee8ac..9051b35 100644
--- a/pkg/analysis_server/test/analysis/update_content_test.dart
+++ b/pkg/analysis_server/test/analysis/update_content_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/protocol/protocol.dart';
 import 'package:analysis_server/protocol/protocol_constants.dart';
 import 'package:analysis_server/protocol/protocol_generated.dart';
@@ -233,7 +235,7 @@
     expect(params, isNotNull);
     var files = params.files;
     expect(files, hasLength(1));
-    Object overlay = files[filePath];
+    var overlay = files[filePath];
     expect(overlay, const TypeMatcher<AddContentOverlay>());
     AddContentOverlay addOverlay = overlay;
     expect(addOverlay.content, fileContent);
diff --git a/pkg/analysis_server/test/analysis_abstract.dart b/pkg/analysis_server/test/analysis_abstract.dart
index 9438324..ab75d6b 100644
--- a/pkg/analysis_server/test/analysis_abstract.dart
+++ b/pkg/analysis_server/test/analysis_abstract.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
+
 import 'package:analysis_server/protocol/protocol.dart';
 import 'package:analysis_server/protocol/protocol_constants.dart';
 import 'package:analysis_server/protocol/protocol_generated.dart'
@@ -236,27 +238,3 @@
     return serverChannel.sendRequest(request, throwOnError: throwOnError);
   }
 }
-
-mixin WithNonFunctionTypeAliasesMixin on AbstractAnalysisTest {
-  @override
-  void createProject({Map<String, String> packageRoots}) {
-    addAnalysisOptionsFile('''
-analyzer:
-  enable-experiment:
-    - nonfunction-type-aliases
-''');
-    super.createProject(packageRoots: packageRoots);
-  }
-}
-
-mixin WithNullSafetyMixin on AbstractAnalysisTest {
-  @override
-  void createProject({Map<String, String> packageRoots}) {
-    addAnalysisOptionsFile('''
-analyzer:
-  enable-experiment:
-    - non-nullable
-''');
-    super.createProject(packageRoots: packageRoots);
-  }
-}
diff --git a/pkg/analysis_server/test/analysis_server_test.dart b/pkg/analysis_server/test/analysis_server_test.dart
index f99570b..50d0459 100644
--- a/pkg/analysis_server/test/analysis_server_test.dart
+++ b/pkg/analysis_server/test/analysis_server_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/protocol/protocol.dart';
 import 'package:analysis_server/protocol/protocol_constants.dart';
 import 'package:analysis_server/protocol/protocol_generated.dart';
diff --git a/pkg/analysis_server/test/channel/byte_stream_channel_test.dart b/pkg/analysis_server/test/channel/byte_stream_channel_test.dart
index 717b50b..5d80b9b 100644
--- a/pkg/analysis_server/test/channel/byte_stream_channel_test.dart
+++ b/pkg/analysis_server/test/channel/byte_stream_channel_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.
 
+// @dart = 2.9
+
 import 'dart:async';
 import 'dart:convert';
 import 'dart:io';
diff --git a/pkg/analysis_server/test/channel/test_all.dart b/pkg/analysis_server/test/channel/test_all.dart
index b712e00..689c931 100644
--- a/pkg/analysis_server/test/channel/test_all.dart
+++ b/pkg/analysis_server/test/channel/test_all.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
+
 import 'package:test/test.dart';
 
 import 'byte_stream_channel_test.dart' as byte_stream_channel_test;
diff --git a/pkg/analysis_server/test/client/completion_driver_test.dart b/pkg/analysis_server/test/client/completion_driver_test.dart
index ace6ad3..4d6ee60 100644
--- a/pkg/analysis_server/test/client/completion_driver_test.dart
+++ b/pkg/analysis_server/test/client/completion_driver_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/analysis_server.dart';
 import 'package:analysis_server/src/services/completion/dart/utilities.dart';
 import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
diff --git a/pkg/analysis_server/test/client/impl/abstract_client.dart b/pkg/analysis_server/test/client/impl/abstract_client.dart
index a8613f8..44e67e3 100644
--- a/pkg/analysis_server/test/client/impl/abstract_client.dart
+++ b/pkg/analysis_server/test/client/impl/abstract_client.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
+
 import 'package:analysis_server/protocol/protocol.dart';
 import 'package:analysis_server/protocol/protocol_generated.dart'
     hide AnalysisOptions;
diff --git a/pkg/analysis_server/test/client/impl/completion_driver.dart b/pkg/analysis_server/test/client/impl/completion_driver.dart
index 3eabfb6..a4569aa 100644
--- a/pkg/analysis_server/test/client/impl/completion_driver.dart
+++ b/pkg/analysis_server/test/client/impl/completion_driver.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
+
 import 'dart:async';
 import 'dart:math' as math;
 
diff --git a/pkg/analysis_server/test/client/impl/expect_mixin.dart b/pkg/analysis_server/test/client/impl/expect_mixin.dart
index abbfe42..7f75f64 100644
--- a/pkg/analysis_server/test/client/impl/expect_mixin.dart
+++ b/pkg/analysis_server/test/client/impl/expect_mixin.dart
@@ -8,7 +8,7 @@
 
 /// Lightweight expect that can be run outside of a test context.
 class ExpectMixin {
-  void expect(actual, matcher, {String reason}) {
+  void expect(actual, matcher, {String? reason}) {
     matcher = _wrapMatcher(matcher);
     var matchState = {};
     try {
@@ -30,7 +30,6 @@
     } else if (x is _Predicate<Null>) {
       // x is a unary predicate, but expects a specific type
       // so wrap it.
-      // ignore: unnecessary_lambdas
       return predicate((a) => (x as dynamic)(a));
     } else {
       return equals(x);
diff --git a/pkg/analysis_server/test/client/test_all.dart b/pkg/analysis_server/test/client/test_all.dart
index 417c4d3..7887a9d 100644
--- a/pkg/analysis_server/test/client/test_all.dart
+++ b/pkg/analysis_server/test/client/test_all.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
+
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'completion_driver_test.dart' as completion_driver;
diff --git a/pkg/analysis_server/test/completion_test.dart b/pkg/analysis_server/test/completion_test.dart
index 26306df..4cefdef 100644
--- a/pkg/analysis_server/test/completion_test.dart
+++ b/pkg/analysis_server/test/completion_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.
 
+// @dart = 2.9
+
 import 'dart:collection';
 
 import 'package:test/test.dart';
@@ -2351,9 +2353,7 @@
         <String>['1+HttpServer', '1-HttpClient'],
         failingTests: '1');
 
-    buildTests(
-        'test038',
-        '''
+    buildTests('test038', '''
 class X {
   x(){}
 }
@@ -2367,9 +2367,7 @@
     ay.!1y;
     az.!2x;
   }
-}''',
-        <String>['1+y', '1-x', '2+x', '2-y'],
-        failingTests: '2');
+}''', <String>['1+y', '1-x', '2+x', '2-y']);
 
     // test analysis of untyped fields and top-level vars
     buildTests(
diff --git a/pkg/analysis_server/test/completion_test_support.dart b/pkg/analysis_server/test/completion_test_support.dart
index 4cc0967..83a70c8 100644
--- a/pkg/analysis_server/test/completion_test_support.dart
+++ b/pkg/analysis_server/test/completion_test_support.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
+
 import 'dart:collection';
 
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
@@ -17,7 +19,8 @@
       .map((CompletionSuggestion suggestion) => suggestion.completion)
       .toList();
 
-  void assertHasCompletion(String completion) {
+  void assertHasCompletion(String completion,
+      {ElementKind elementKind, bool isDeprecated}) {
     var expectedOffset = completion.indexOf(CURSOR_MARKER);
     if (expectedOffset >= 0) {
       if (completion.contains(CURSOR_MARKER, expectedOffset + 1)) {
@@ -51,6 +54,12 @@
     }
     expect(matchingSuggestion.selectionOffset, equals(expectedOffset));
     expect(matchingSuggestion.selectionLength, equals(0));
+    if (elementKind != null) {
+      expect(matchingSuggestion.element.kind, elementKind);
+    }
+    if (isDeprecated != null) {
+      expect(matchingSuggestion.isDeprecated, isDeprecated);
+    }
   }
 
   void assertHasNoCompletion(String completion) {
diff --git a/pkg/analysis_server/test/constants.dart b/pkg/analysis_server/test/constants.dart
index 817f2a2..8c6d848 100644
--- a/pkg/analysis_server/test/constants.dart
+++ b/pkg/analysis_server/test/constants.dart
@@ -7,6 +7,8 @@
 const String CONTEXT_MESSAGES = 'contextMessages';
 const String CORRECTION = 'correction';
 const String EDITS = 'edits';
+const String END_COLUMN = 'endColumn';
+const String END_LINE = 'endLine';
 const String FILE = 'file';
 const String FILE_STAMP = 'fileStamp';
 const String HAS_FIX = 'hasFix';
diff --git a/pkg/analysis_server/test/domain_analysis_test.dart b/pkg/analysis_server/test/domain_analysis_test.dart
index 2138863..b05effd 100644
--- a/pkg/analysis_server/test/domain_analysis_test.dart
+++ b/pkg/analysis_server/test/domain_analysis_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.
 
+// @dart = 2.9
+
 import 'dart:async';
 
 import 'package:analysis_server/protocol/protocol.dart';
diff --git a/pkg/analysis_server/test/domain_completion_test.dart b/pkg/analysis_server/test/domain_completion_test.dart
index bfb2c73..e31fc32 100644
--- a/pkg/analysis_server/test/domain_completion_test.dart
+++ b/pkg/analysis_server/test/domain_completion_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/protocol/protocol_generated.dart';
 import 'package:analysis_server/src/plugin/plugin_manager.dart';
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
diff --git a/pkg/analysis_server/test/domain_completion_util.dart b/pkg/analysis_server/test/domain_completion_util.dart
index 6d93dcf..1d2720a 100644
--- a/pkg/analysis_server/test/domain_completion_util.dart
+++ b/pkg/analysis_server/test/domain_completion_util.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
+
 import 'dart:async';
 
 import 'package:analysis_server/protocol/protocol.dart';
diff --git a/pkg/analysis_server/test/domain_diagnostic_test.dart b/pkg/analysis_server/test/domain_diagnostic_test.dart
index f6a615c..4f6860e 100644
--- a/pkg/analysis_server/test/domain_diagnostic_test.dart
+++ b/pkg/analysis_server/test/domain_diagnostic_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/protocol/protocol_generated.dart';
 import 'package:analysis_server/src/domain_diagnostic.dart';
 import 'package:test/test.dart';
diff --git a/pkg/analysis_server/test/domain_edit_dartfix_test.dart b/pkg/analysis_server/test/domain_edit_dartfix_test.dart
index 0d639ac..a3b114c 100644
--- a/pkg/analysis_server/test/domain_edit_dartfix_test.dart
+++ b/pkg/analysis_server/test/domain_edit_dartfix_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/protocol/protocol.dart';
 import 'package:analysis_server/protocol/protocol_generated.dart';
 import 'package:analysis_server/src/edit/edit_dartfix.dart';
diff --git a/pkg/analysis_server/test/domain_execution_test.dart b/pkg/analysis_server/test/domain_execution_test.dart
index b7b387c..ad5fb97 100644
--- a/pkg/analysis_server/test/domain_execution_test.dart
+++ b/pkg/analysis_server/test/domain_execution_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/protocol/protocol_generated.dart';
 import 'package:analysis_server/src/analysis_server.dart';
 import 'package:analysis_server/src/domain_execution.dart';
diff --git a/pkg/analysis_server/test/domain_server_test.dart b/pkg/analysis_server/test/domain_server_test.dart
index 1ac94cc..9af7c95 100644
--- a/pkg/analysis_server/test/domain_server_test.dart
+++ b/pkg/analysis_server/test/domain_server_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/protocol/protocol.dart';
 import 'package:analysis_server/protocol/protocol_constants.dart';
 import 'package:analysis_server/protocol/protocol_generated.dart';
diff --git a/pkg/analysis_server/test/edit/assists_test.dart b/pkg/analysis_server/test/edit/assists_test.dart
index 3ab55f3..93a35f0 100644
--- a/pkg/analysis_server/test/edit/assists_test.dart
+++ b/pkg/analysis_server/test/edit/assists_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/protocol/protocol_generated.dart';
 import 'package:analysis_server/src/edit/edit_domain.dart';
 import 'package:analysis_server/src/plugin/plugin_manager.dart';
diff --git a/pkg/analysis_server/test/edit/bulk_fixes_test.dart b/pkg/analysis_server/test/edit/bulk_fixes_test.dart
index 1c9b46b..5d88990 100644
--- a/pkg/analysis_server/test/edit/bulk_fixes_test.dart
+++ b/pkg/analysis_server/test/edit/bulk_fixes_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.
 
+// @dart = 2.9
+
 import 'dart:io';
 
 import 'package:analysis_server/protocol/protocol_generated.dart';
diff --git a/pkg/analysis_server/test/edit/fixes_test.dart b/pkg/analysis_server/test/edit/fixes_test.dart
index 7a0ca44..d037309 100644
--- a/pkg/analysis_server/test/edit/fixes_test.dart
+++ b/pkg/analysis_server/test/edit/fixes_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/protocol/protocol_generated.dart';
 import 'package:analysis_server/src/edit/edit_domain.dart';
 import 'package:analysis_server/src/plugin/plugin_manager.dart';
@@ -70,7 +72,7 @@
     var fixes = plugin.AnalysisErrorFixes(AnalysisError(
         AnalysisErrorSeverity.ERROR,
         AnalysisErrorType.HINT,
-        Location('', 0, 0, 0, 0),
+        Location('', 0, 0, 0, 0, 0, 0),
         'message',
         'code'));
     var result = plugin.EditGetFixesResult(<plugin.AnalysisErrorFixes>[fixes]);
diff --git a/pkg/analysis_server/test/edit/format_test.dart b/pkg/analysis_server/test/edit/format_test.dart
index ac5b566..bcab9d1 100644
--- a/pkg/analysis_server/test/edit/format_test.dart
+++ b/pkg/analysis_server/test/edit/format_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/protocol/protocol_generated.dart';
 import 'package:analysis_server/src/edit/edit_domain.dart';
 import 'package:test/test.dart';
diff --git a/pkg/analysis_server/test/edit/organize_directives_test.dart b/pkg/analysis_server/test/edit/organize_directives_test.dart
index 4a775db..e81ca0e 100644
--- a/pkg/analysis_server/test/edit/organize_directives_test.dart
+++ b/pkg/analysis_server/test/edit/organize_directives_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/protocol/protocol_generated.dart';
 import 'package:analysis_server/src/edit/edit_domain.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
diff --git a/pkg/analysis_server/test/edit/postfix_completion_test.dart b/pkg/analysis_server/test/edit/postfix_completion_test.dart
index 9f55b0f..7cbe83f 100644
--- a/pkg/analysis_server/test/edit/postfix_completion_test.dart
+++ b/pkg/analysis_server/test/edit/postfix_completion_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/protocol/protocol.dart';
 import 'package:analysis_server/protocol/protocol_generated.dart';
 import 'package:analysis_server/src/edit/edit_domain.dart';
diff --git a/pkg/analysis_server/test/edit/refactoring_test.dart b/pkg/analysis_server/test/edit/refactoring_test.dart
index 015b081..24d8e02 100644
--- a/pkg/analysis_server/test/edit/refactoring_test.dart
+++ b/pkg/analysis_server/test/edit/refactoring_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/protocol/protocol.dart';
 import 'package:analysis_server/protocol/protocol_generated.dart';
 import 'package:analysis_server/src/edit/edit_domain.dart';
diff --git a/pkg/analysis_server/test/edit/sort_members_test.dart b/pkg/analysis_server/test/edit/sort_members_test.dart
index bd226a2..083b834 100644
--- a/pkg/analysis_server/test/edit/sort_members_test.dart
+++ b/pkg/analysis_server/test/edit/sort_members_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/protocol/protocol_generated.dart';
 import 'package:analysis_server/src/edit/edit_domain.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
diff --git a/pkg/analysis_server/test/edit/statement_completion_test.dart b/pkg/analysis_server/test/edit/statement_completion_test.dart
index db31cac..c442c9c 100644
--- a/pkg/analysis_server/test/edit/statement_completion_test.dart
+++ b/pkg/analysis_server/test/edit/statement_completion_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/protocol/protocol_generated.dart';
 import 'package:analysis_server/src/edit/edit_domain.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
diff --git a/pkg/analysis_server/test/edit/test_all.dart b/pkg/analysis_server/test/edit/test_all.dart
index 21cf0bc..e1d5aec 100644
--- a/pkg/analysis_server/test/edit/test_all.dart
+++ b/pkg/analysis_server/test/edit/test_all.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
+
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'assists_test.dart' as assists;
diff --git a/pkg/analysis_server/test/integration/analysis/analysis_options_test.dart b/pkg/analysis_server/test/integration/analysis/analysis_options_test.dart
index 0324041..5033928 100644
--- a/pkg/analysis_server/test/integration/analysis/analysis_options_test.dart
+++ b/pkg/analysis_server/test/integration/analysis/analysis_options_test.dart
@@ -36,7 +36,7 @@
     await analysisFinished;
 
     expect(currentAnalysisErrors[options], isList);
-    var errors = currentAnalysisErrors[options];
+    var errors = existingErrorsForFile(options);
     expect(errors, hasLength(1));
     var error = errors[0];
     expect(error.location.file, options);
diff --git a/pkg/analysis_server/test/integration/analysis/error_test.dart b/pkg/analysis_server/test/integration/analysis/error_test.dart
index 9d503a2..e674a76 100644
--- a/pkg/analysis_server/test/integration/analysis/error_test.dart
+++ b/pkg/analysis_server/test/integration/analysis/error_test.dart
@@ -31,7 +31,7 @@
     await analysisFinished;
 
     expect(currentAnalysisErrors[filePath], isList);
-    var errors = currentAnalysisErrors[filePath];
+    var errors = existingErrorsForFile(filePath);
     expect(errors, hasLength(1));
     expect(errors[0].location.file, equals(filePath));
   }
@@ -45,7 +45,7 @@
     standardAnalysisSetup();
     return analysisFinished.then((_) {
       expect(currentAnalysisErrors[pathname], isList);
-      var errors = currentAnalysisErrors[pathname];
+      var errors = existingErrorsForFile(pathname);
       expect(errors, hasLength(1));
       expect(errors[0].location.file, equals(pathname));
     });
diff --git a/pkg/analysis_server/test/integration/analysis/get_errors_non_standard_sdk_test.dart b/pkg/analysis_server/test/integration/analysis/get_errors_non_standard_sdk_test.dart
index e80f671..fb8cb1e 100644
--- a/pkg/analysis_server/test/integration/analysis/get_errors_non_standard_sdk_test.dart
+++ b/pkg/analysis_server/test/integration/analysis/get_errors_non_standard_sdk_test.dart
@@ -76,7 +76,7 @@
   }
 
   @override
-  Future startServer({int diagnosticPort, int servicesPort}) {
+  Future startServer({int? diagnosticPort, int? servicesPort}) {
     var sdkPath = createNonStandardSdk();
     return server.start(
         diagnosticPort: diagnosticPort,
@@ -93,7 +93,7 @@
     writeFile(pathname, text);
     standardAnalysisSetup();
     await analysisFinished;
-    var errors = currentAnalysisErrors[pathname];
+    var errors = existingErrorsForFile(pathname);
     expect(errors, hasLength(1));
     expect(errors[0].code, 'unused_import');
   }
diff --git a/pkg/analysis_server/test/integration/analysis/get_hover_test.dart b/pkg/analysis_server/test/integration/analysis/get_hover_test.dart
index 385d923..2c4828c 100644
--- a/pkg/analysis_server/test/integration/analysis/get_hover_test.dart
+++ b/pkg/analysis_server/test/integration/analysis/get_hover_test.dart
@@ -19,7 +19,7 @@
 class AnalysisGetHoverIntegrationTest
     extends AbstractAnalysisServerIntegrationTest {
   /// Pathname of the file containing Dart code.
-  String pathname;
+  late String pathname;
 
   /// Dart code under test.
   final String text = r'''
@@ -53,17 +53,17 @@
   /// literal value.  [parameterRegexps] means is a set of regexps which should
   /// match the hover parameters.  [propagatedType], if specified, is the
   /// expected propagated type of the element.
-  Future<AnalysisGetHoverResult> checkHover(
+  Future<AnalysisGetHoverResult?> checkHover(
     String target,
     int length,
-    List<String> descriptionRegexps,
-    String kind,
-    List<String> staticTypeRegexps, {
+    List<String>? descriptionRegexps,
+    String? kind,
+    List<String>? staticTypeRegexps, {
     bool isLocal = false,
     bool isCore = false,
-    String docRegexp,
+    String? docRegexp,
     bool isLiteral = false,
-    List<String> parameterRegexps,
+    List<String>? parameterRegexps,
   }) {
     var offset = text.indexOf(target);
     return sendAnalysisGetHover(pathname, offset).then((result) async {
@@ -72,7 +72,7 @@
       expect(info.offset, equals(offset));
       expect(info.length, equals(length));
       if (isCore) {
-        expect(path.basename(info.containingLibraryPath), equals('core.dart'));
+        expect(path.basename(info.containingLibraryPath!), equals('core.dart'));
         expect(info.containingLibraryName, equals('dart:core'));
       } else if (isLocal || isLiteral) {
         expect(info.containingLibraryPath, isNull);
diff --git a/pkg/analysis_server/test/integration/analysis/get_imported_elements_test.dart b/pkg/analysis_server/test/integration/analysis/get_imported_elements_test.dart
index 436da25..547b6d9 100644
--- a/pkg/analysis_server/test/integration/analysis/get_imported_elements_test.dart
+++ b/pkg/analysis_server/test/integration/analysis/get_imported_elements_test.dart
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analysis_server/protocol/protocol_generated.dart';
-import 'package:analysis_server/src/domain_analysis.dart';
+import 'package:analysis_server/src/domain_analysis_flags.dart';
 import 'package:path/path.dart' as path;
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -20,10 +20,10 @@
 class AnalysisGetImportedElementsIntegrationTest
     extends AbstractAnalysisServerIntegrationTest {
   /// Pathname of the file containing Dart code.
-  String pathname;
+  late String pathname;
 
   /// Dart code under test.
-  String text;
+  late String text;
 
   /// Check that an analysis.getImportedElements request on the region starting
   /// with the first character that matches [target] and having the given
diff --git a/pkg/analysis_server/test/integration/analysis/get_library_dependencies_test.dart b/pkg/analysis_server/test/integration/analysis/get_library_dependencies_test.dart
index 568b151..caf757e 100644
--- a/pkg/analysis_server/test/integration/analysis/get_library_dependencies_test.dart
+++ b/pkg/analysis_server/test/integration/analysis/get_library_dependencies_test.dart
@@ -39,7 +39,7 @@
     expect(libraries.any((String lib) => lib.endsWith('core/core.dart')), true);
 
     expect(packageMaps.keys, hasLength(1));
-    var map = packageMaps[packageMaps.keys.first];
+    var map = packageMaps[packageMaps.keys.first]!;
     expect(map.keys, isEmpty);
   }
 }
diff --git a/pkg/analysis_server/test/integration/analysis/highlights_test.dart b/pkg/analysis_server/test/integration/analysis/highlights_test.dart
index 9dfcaf7..cb5baf6 100644
--- a/pkg/analysis_server/test/integration/analysis/highlights_test.dart
+++ b/pkg/analysis_server/test/integration/analysis/highlights_test.dart
@@ -17,7 +17,7 @@
 
 @reflectiveTest
 class AnalysisHighlightsTest extends AbstractAnalysisServerIntegrationTest {
-  Map<HighlightRegionType, Set<String>> highlights;
+  late Map<HighlightRegionType, Set<String>> highlights;
 
   void check(HighlightRegionType type, List<String> expected) {
     expect(highlights[type], equals(expected.toSet()));
@@ -39,10 +39,7 @@
         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);
+        highlights.putIfAbsent(type, () => {}).add(highlightedText);
       }
     });
     await analysisFinished;
@@ -50,8 +47,8 @@
 
   @override
   Future startServer({
-    int diagnosticPort,
-    int servicesPort,
+    int? diagnosticPort,
+    int? servicesPort,
   }) {
     return server.start(
         diagnosticPort: diagnosticPort,
diff --git a/pkg/analysis_server/test/integration/analysis/lint_test.dart b/pkg/analysis_server/test/integration/analysis/lint_test.dart
index ffc3d8b..a41d0f5 100644
--- a/pkg/analysis_server/test/integration/analysis/lint_test.dart
+++ b/pkg/analysis_server/test/integration/analysis/lint_test.dart
@@ -48,7 +48,7 @@
     await analysisFinished;
 
     expect(currentAnalysisErrors[source], isList);
-    var errors = currentAnalysisErrors[source];
+    var errors = existingErrorsForFile(source);
     expect(errors, hasLength(1));
     var error = errors[0];
     expect(error.location.file, source);
diff --git a/pkg/analysis_server/test/integration/analysis/navigation_test.dart b/pkg/analysis_server/test/integration/analysis/navigation_test.dart
index b913d75..23f6e7c 100644
--- a/pkg/analysis_server/test/integration/analysis/navigation_test.dart
+++ b/pkg/analysis_server/test/integration/analysis/navigation_test.dart
@@ -58,22 +58,19 @@
     sendAnalysisSetSubscriptions({
       AnalysisService.NAVIGATION: [pathname1]
     });
-    List<NavigationRegion> regions;
-    List<NavigationTarget> targets;
-    List<String> targetFiles;
-    onAnalysisNavigation.listen((AnalysisNavigationParams params) {
-      expect(params.file, equals(pathname1));
-      regions = params.regions;
-      targets = params.targets;
-      targetFiles = params.files;
-    });
-
-    await analysisFinished;
 
     // There should be a single error, due to the fact that 'dart:async' is not
     // used.
+    await analysisFinished;
     expect(currentAnalysisErrors[pathname1], hasLength(1));
     expect(currentAnalysisErrors[pathname2], isEmpty);
+
+    var params = await onAnalysisNavigation.first;
+    expect(params.file, equals(pathname1));
+    var regions = params.regions;
+    var targets = params.targets;
+    var targetFiles = params.files;
+
     NavigationTarget findTargetElement(int index) {
       for (var region in regions) {
         if (region.offset <= index && index < region.offset + region.length) {
@@ -119,7 +116,7 @@
     checkLocal('function(() => localVariable.field)',
         'function(FunctionTypeAlias parameter)', ElementKind.FUNCTION);
     checkLocal('FunctionTypeAlias parameter', 'FunctionTypeAlias();',
-        ElementKind.FUNCTION_TYPE_ALIAS);
+        ElementKind.TYPE_ALIAS);
     checkLocal('field)', 'field = (', ElementKind.GETTER);
     checkRemote("'dart:async'", r'async\.dart$', ElementKind.LIBRARY);
     checkLocal(
diff --git a/pkg/analysis_server/test/integration/analysis/occurrences_test.dart b/pkg/analysis_server/test/integration/analysis/occurrences_test.dart
index 112445a..e1b8d1c 100644
--- a/pkg/analysis_server/test/integration/analysis/occurrences_test.dart
+++ b/pkg/analysis_server/test/integration/analysis/occurrences_test.dart
@@ -3,7 +3,6 @@
 // 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';
 
@@ -17,7 +16,7 @@
 
 @reflectiveTest
 class OccurrencesTest extends AbstractAnalysisServerIntegrationTest {
-  Future<void> test_occurrences() {
+  Future<void> test_occurrences() async {
     var pathname = sourcePath('test.dart');
     var text = r'''
 main() {
@@ -35,33 +34,33 @@
     sendAnalysisSetSubscriptions({
       AnalysisService.OCCURRENCES: [pathname]
     });
-    List<Occurrences> occurrences;
-    onAnalysisOccurrences.listen((AnalysisOccurrencesParams params) {
-      expect(params.file, equals(pathname));
-      occurrences = params.occurrences;
-    });
-    return analysisFinished.then((_) {
-      expect(currentAnalysisErrors[pathname], isEmpty);
-      Set<int> findOffsets(String elementName) {
-        for (var occurrence in occurrences) {
-          if (occurrence.element.name == elementName) {
-            return occurrence.offsets.toSet();
-          }
+
+    await analysisFinished;
+    expect(currentAnalysisErrors[pathname], isEmpty);
+
+    var params = await onAnalysisOccurrences.first;
+    expect(params.file, equals(pathname));
+    var occurrences = params.occurrences;
+
+    Set<int> findOffsets(String elementName) {
+      for (var occurrence in occurrences) {
+        if (occurrence.element.name == elementName) {
+          return occurrence.offsets.toSet();
         }
-        fail('No element found matching $elementName');
       }
+      fail('No element found matching $elementName');
+    }
 
-      void check(String elementName, Iterable<String> expectedOccurrences) {
-        var expectedOffsets = expectedOccurrences
-            .map((String substring) => text.indexOf(substring))
-            .toSet();
-        var foundOffsets = findOffsets(elementName);
-        expect(foundOffsets, equals(expectedOffsets));
-      }
+    void check(String elementName, Iterable<String> expectedOccurrences) {
+      var expectedOffsets = expectedOccurrences
+          .map((String substring) => text.indexOf(substring))
+          .toSet();
+      var foundOffsets = findOffsets(elementName);
+      expect(foundOffsets, equals(expectedOffsets));
+    }
 
-      check('i', ['i = 0', 'i < 10', 'i++', 'i;']);
-      check('j', ['j = 0', 'j < i', 'j++', 'j;']);
-      check('sum', ['sum = 0', 'sum +=', 'sum)']);
-    });
+    check('i', ['i = 0', 'i < 10', 'i++', 'i;']);
+    check('j', ['j = 0', 'j < i', 'j++', 'j;']);
+    check('sum', ['sum = 0', 'sum +=', 'sum)']);
   }
 }
diff --git a/pkg/analysis_server/test/integration/analysis/outline_test.dart b/pkg/analysis_server/test/integration/analysis/outline_test.dart
index 7271ce6..df5a0ea 100644
--- a/pkg/analysis_server/test/integration/analysis/outline_test.dart
+++ b/pkg/analysis_server/test/integration/analysis/outline_test.dart
@@ -17,7 +17,7 @@
 
 @reflectiveTest
 class OutlineTest extends AbstractAnalysisServerIntegrationTest {
-  Future<void> test_outline() {
+  Future<void> test_outline() async {
     var pathname = sourcePath('test.dart');
     var text = r'''
 class Class1 {
@@ -45,27 +45,26 @@
     sendAnalysisSetSubscriptions({
       AnalysisService.OUTLINE: [pathname]
     });
-    Outline outline;
-    onAnalysisOutline.listen((AnalysisOutlineParams params) {
-      expect(params.file, equals(pathname));
-      outline = params.outline;
-    });
-    return analysisFinished.then((_) {
-      expect(outline.element.kind, equals(ElementKind.COMPILATION_UNIT));
-      expect(outline.offset, equals(0));
-      expect(outline.length, equals(text.length));
-      var classes = outline.children;
-      expect(classes, hasLength(2));
-      expect(classes[0].element.name, equals('Class1'));
-      expect(classes[1].element.name, equals('Class2'));
 
-      var members = classes[0].children;
-      expect(members, hasLength(5));
-      expect(members[0].element.name, equals('field'));
-      expect(members[1].element.name, equals('method'));
-      expect(members[2].element.name, equals('staticMethod'));
-      expect(members[3].element.name, equals('getter'));
-      expect(members[4].element.name, equals('setter'));
-    });
+    var params = await onAnalysisOutline.first;
+    expect(params.file, equals(pathname));
+    var outline = params.outline;
+
+    expect(outline.element.kind, equals(ElementKind.COMPILATION_UNIT));
+    expect(outline.offset, equals(0));
+    expect(outline.length, equals(text.length));
+
+    var classes = outline.children!;
+    expect(classes, hasLength(2));
+    expect(classes[0].element.name, equals('Class1'));
+    expect(classes[1].element.name, equals('Class2'));
+
+    var members = classes[0].children!;
+    expect(members, hasLength(5));
+    expect(members[0].element.name, equals('field'));
+    expect(members[1].element.name, equals('method'));
+    expect(members[2].element.name, equals('staticMethod'));
+    expect(members[3].element.name, equals('getter'));
+    expect(members[4].element.name, equals('setter'));
   }
 }
diff --git a/pkg/analysis_server/test/integration/analysis/overrides_test.dart b/pkg/analysis_server/test/integration/analysis/overrides_test.dart
index dc3167f..0358bb4 100644
--- a/pkg/analysis_server/test/integration/analysis/overrides_test.dart
+++ b/pkg/analysis_server/test/integration/analysis/overrides_test.dart
@@ -16,7 +16,7 @@
 
 @reflectiveTest
 class OverridesTest extends AbstractAnalysisServerIntegrationTest {
-  Future<void> test_overrides() {
+  Future<void> test_overrides() async {
     var pathname = sourcePath('test.dart');
     var text = r'''
 abstract class Interface1 {
@@ -56,67 +56,69 @@
     sendAnalysisSetSubscriptions({
       AnalysisService.OVERRIDES: [pathname]
     });
-    List<Override> overrides;
-    onAnalysisOverrides.listen((AnalysisOverridesParams params) {
-      expect(params.file, equals(pathname));
-      overrides = params.overrides;
-    });
-    return analysisFinished.then((_) {
-      var targetOffset = text.indexOf('Target');
-      Override findOverride(String methodName) {
-        var methodOffset = text.indexOf(methodName, targetOffset);
-        for (var override in overrides) {
-          if (override.offset == methodOffset) {
-            return override;
-          }
-        }
-        return null;
-      }
 
-      void checkOverrides(String methodName, bool expectedOverridesBase,
-          List<String> expectedOverridesInterfaces) {
-        var override = findOverride(methodName);
-        if (!expectedOverridesBase && expectedOverridesInterfaces.isEmpty) {
-          // This method overrides nothing, so it should not appear in the
-          // overrides list.
-          expect(override, isNull);
-          return;
-        } else {
-          expect(override, isNotNull);
-        }
-        expect(override.length, equals(methodName.length));
-        var superclassMember = override.superclassMember;
-        if (expectedOverridesBase) {
-          expect(superclassMember.element.name, equals(methodName));
-          expect(superclassMember.className, equals('Base'));
-        } else {
-          expect(superclassMember, isNull);
-        }
-        var interfaceMembers = override.interfaceMembers;
-        if (expectedOverridesInterfaces.isNotEmpty) {
-          expect(interfaceMembers, isNotNull);
-          var actualOverridesInterfaces = <String>{};
-          for (var overriddenMember in interfaceMembers) {
-            expect(overriddenMember.element.name, equals(methodName));
-            var className = overriddenMember.className;
-            var wasAdded = actualOverridesInterfaces.add(className);
-            expect(wasAdded, isTrue);
-          }
-          expect(actualOverridesInterfaces,
-              equals(expectedOverridesInterfaces.toSet()));
-        } else {
-          expect(interfaceMembers, isNull);
+    var params = await onAnalysisOverrides.first;
+    expect(params.file, equals(pathname));
+    var overrides = params.overrides;
+
+    var targetOffset = text.indexOf('Target');
+
+    Override? findOverride(String methodName) {
+      var methodOffset = text.indexOf(methodName, targetOffset);
+      for (var override in overrides) {
+        if (override.offset == methodOffset) {
+          return override;
         }
       }
+      return null;
+    }
 
-      checkOverrides('method0', true, ['Interface1', 'Interface2']);
-      checkOverrides('method1', false, ['Interface1', 'Interface2']);
-      checkOverrides('method2', true, ['Interface1']);
-      checkOverrides('method3', false, ['Interface1']);
-      checkOverrides('method4', true, ['Interface2']);
-      checkOverrides('method5', false, ['Interface2']);
-      checkOverrides('method6', true, []);
-      checkOverrides('method7', false, []);
-    });
+    void checkOverrides(String methodName, bool expectedOverridesBase,
+        List<String> expectedOverridesInterfaces) {
+      var override = findOverride(methodName);
+
+      if (!expectedOverridesBase && expectedOverridesInterfaces.isEmpty) {
+        // This method overrides nothing, so it should not appear in the
+        // overrides list.
+        expect(override, isNull);
+        return;
+      } else {
+        override!;
+      }
+
+      expect(override.length, equals(methodName.length));
+      var superclassMember = override.superclassMember;
+      if (expectedOverridesBase) {
+        superclassMember!;
+        expect(superclassMember.element.name, equals(methodName));
+        expect(superclassMember.className, equals('Base'));
+      } else {
+        expect(superclassMember, isNull);
+      }
+      var interfaceMembers = override.interfaceMembers;
+      if (expectedOverridesInterfaces.isNotEmpty) {
+        interfaceMembers!;
+        var actualOverridesInterfaces = <String>{};
+        for (var overriddenMember in interfaceMembers) {
+          expect(overriddenMember.element.name, equals(methodName));
+          var className = overriddenMember.className;
+          var wasAdded = actualOverridesInterfaces.add(className);
+          expect(wasAdded, isTrue);
+        }
+        expect(actualOverridesInterfaces,
+            equals(expectedOverridesInterfaces.toSet()));
+      } else {
+        expect(interfaceMembers, isNull);
+      }
+    }
+
+    checkOverrides('method0', true, ['Interface1', 'Interface2']);
+    checkOverrides('method1', false, ['Interface1', 'Interface2']);
+    checkOverrides('method2', true, ['Interface1']);
+    checkOverrides('method3', false, ['Interface1']);
+    checkOverrides('method4', true, ['Interface2']);
+    checkOverrides('method5', false, ['Interface2']);
+    checkOverrides('method6', true, []);
+    checkOverrides('method7', false, []);
   }
 }
diff --git a/pkg/analysis_server/test/integration/analysis/reanalyze_test.dart b/pkg/analysis_server/test/integration/analysis/reanalyze_test.dart
index 064d578..6534bab 100644
--- a/pkg/analysis_server/test/integration/analysis/reanalyze_test.dart
+++ b/pkg/analysis_server/test/integration/analysis/reanalyze_test.dart
@@ -25,10 +25,9 @@
       // Make sure that reanalyze causes analysis to restart.
       var analysisRestarted = false;
       onServerStatus.listen((ServerStatusParams data) {
-        if (data.analysis != null) {
-          if (data.analysis.isAnalyzing) {
-            analysisRestarted = true;
-          }
+        var analysisStatus = data.analysis;
+        if (analysisStatus != null && analysisStatus.isAnalyzing) {
+          analysisRestarted = true;
         }
       });
       sendAnalysisReanalyze();
diff --git a/pkg/analysis_server/test/integration/analysis/set_priority_files_test.dart b/pkg/analysis_server/test/integration/analysis/set_priority_files_test.dart
index a7151cf..bc7b3e4 100644
--- a/pkg/analysis_server/test/integration/analysis/set_priority_files_test.dart
+++ b/pkg/analysis_server/test/integration/analysis/set_priority_files_test.dart
@@ -24,6 +24,7 @@
     await sendAnalysisSetPriorityFiles([pathname]);
 
     var status = await analysisFinished;
-    expect(status.analysis.isAnalyzing, false);
+    var analysisStatus = status.analysis;
+    expect(analysisStatus != null && analysisStatus.isAnalyzing, false);
   }
 }
diff --git a/pkg/analysis_server/test/integration/analysis/update_content_test.dart b/pkg/analysis_server/test/integration/analysis/update_content_test.dart
index 9ab0807..524b73c 100644
--- a/pkg/analysis_server/test/integration/analysis/update_content_test.dart
+++ b/pkg/analysis_server/test/integration/analysis/update_content_test.dart
@@ -76,7 +76,7 @@
     standardAnalysisSetup();
     await analysisFinished;
     expect(currentAnalysisErrors[pathname], isList);
-    var errors1 = currentAnalysisErrors[pathname];
+    var errors1 = existingErrorsForFile(pathname);
     expect(errors1, hasLength(1));
     expect(errors1[0].location.file, equals(pathname));
 
@@ -97,7 +97,7 @@
     });
     await analysisFinished;
     expect(currentAnalysisErrors[pathname], isList);
-    var errors2 = currentAnalysisErrors[pathname];
+    var errors2 = existingErrorsForFile(pathname);
     expect(errors2, hasLength(1));
     expect(errors2[0].location.file, equals(pathname));
   }
diff --git a/pkg/analysis_server/test/integration/completion/get_suggestions_test.dart b/pkg/analysis_server/test/integration/completion/get_suggestions_test.dart
index 1dd38a1..ff29243 100644
--- a/pkg/analysis_server/test/integration/completion/get_suggestions_test.dart
+++ b/pkg/analysis_server/test/integration/completion/get_suggestions_test.dart
@@ -17,17 +17,24 @@
 
 @reflectiveTest
 class GetSuggestionsTest extends AbstractAnalysisServerIntegrationTest {
-  String path;
-  String content;
-  int completionOffset;
+  bool initialized = false;
+  late String path;
+  late String content;
+  late int completionOffset;
 
   void setTestSource(String relPath, String content) {
+    if (initialized) {
+      fail('Call addTestUnit exactly once');
+    }
+
     path = sourcePath(relPath);
-    expect(completionOffset, isNull, reason: 'Call addTestUnit exactly once');
+
     completionOffset = content.indexOf('^');
     expect(completionOffset, isNot(equals(-1)), reason: 'missing ^');
+
     var nextOffset = content.indexOf('^', completionOffset + 1);
     expect(nextOffset, equals(-1), reason: 'too many ^');
+
     this.content = content.substring(0, completionOffset) +
         content.substring(completionOffset + 1);
   }
@@ -97,7 +104,7 @@
         (CompletionSuggestion suggestion) => suggestion.completion == 'length');
   }
 
-  Future<void> test_getSuggestions_sourceMissing_noWait() {
+  Future<void> test_getSuggestions_sourceMissing_noWait() async {
     path = sourcePath('does_not_exist.dart');
     // Do not write the file to "disk"
     //   writeFile(pathname, text);
@@ -105,11 +112,7 @@
     standardAnalysisSetup(subscribeStatus: false);
     // Missing file and no overlay
     //sendAnalysisUpdateContent({path: new AddContentOverlay(content)});
-    return sendCompletionGetSuggestions(path, 0).catchError((e) {
-      // Exception expected
-      return null;
-    }).then((result) {
-      expect(result, const TypeMatcher<CompletionGetSuggestionsResult>());
-    });
+    var result = await sendCompletionGetSuggestions(path, 0);
+    expect(result, const TypeMatcher<CompletionGetSuggestionsResult>());
   }
 }
diff --git a/pkg/analysis_server/test/integration/edit/get_refactoring_test.dart b/pkg/analysis_server/test/integration/edit/get_refactoring_test.dart
index 81b5e22..6896e4b 100644
--- a/pkg/analysis_server/test/integration/edit/get_refactoring_test.dart
+++ b/pkg/analysis_server/test/integration/edit/get_refactoring_test.dart
@@ -50,12 +50,14 @@
     expect(result.optionsProblems, isEmpty);
     expect(result.finalProblems, isEmpty);
     expect(result.potentialEdits, isNull);
-    expect(result.change.edits, isNotEmpty);
+
+    var change = result.change!;
+    expect(change.edits, isNotEmpty);
+    var fileEdit = change.edits.first;
 
     // apply the refactoring, expect that the new code has no errors
-    var change = result.change;
-    expect(change.edits.first.edits, isNotEmpty);
-    for (var edit in change.edits.first.edits) {
+    expect(fileEdit.edits, isNotEmpty);
+    for (var edit in fileEdit.edits) {
       text = text.replaceRange(edit.offset, edit.end, edit.replacement);
     }
     await sendAnalysisUpdateContent({pathname: AddContentOverlay(text)});
diff --git a/pkg/analysis_server/test/integration/edit/import_elements_test.dart b/pkg/analysis_server/test/integration/edit/import_elements_test.dart
index 06ab05f..43ecb92 100644
--- a/pkg/analysis_server/test/integration/edit/import_elements_test.dart
+++ b/pkg/analysis_server/test/integration/edit/import_elements_test.dart
@@ -21,13 +21,13 @@
 class AnalysisGetImportElementsIntegrationTest
     extends AbstractAnalysisServerIntegrationTest {
   /// Pathname of the file containing Dart code.
-  String pathname;
+  late String pathname;
 
   /// Check that an edit.importElements request with the given list of
   /// [elements] produces the [expected] list of edits.
   Future<void> checkEdits(
       List<ImportedElements> elements, List<SourceEdit> expected,
-      {String expectedFile}) async {
+      {String? expectedFile}) async {
     bool equals(SourceEdit actualEdit, SourceEdit expectedEdit) {
       return actualEdit.offset == expectedEdit.offset &&
           actualEdit.length == expectedEdit.length &&
@@ -46,8 +46,7 @@
 
     var result = await sendEditImportElements(pathname, elements);
 
-    var edit = result.edit;
-    expect(edit, isNotNull);
+    var edit = result.edit!;
     if (expectedFile == null) {
       expect(edit.file, pathname);
     } else {
diff --git a/pkg/analysis_server/test/integration/execution/delete_context_test.dart b/pkg/analysis_server/test/integration/execution/delete_context_test.dart
index 4087c06..121ba2e 100644
--- a/pkg/analysis_server/test/integration/execution/delete_context_test.dart
+++ b/pkg/analysis_server/test/integration/execution/delete_context_test.dart
@@ -18,13 +18,12 @@
   Future<void> test_delete() async {
     var pathname = sourcePath('lib/main.dart');
     writeFile(pathname, '// dummy');
-    writeFile(sourcePath('.packages'), 'foo:lib/');
     standardAnalysisSetup();
 
     var contextId = (await sendExecutionCreateContext(sourceDirectory.path)).id;
 
     var result =
-        await sendExecutionMapUri(contextId, uri: 'package:foo/main.dart');
+        await sendExecutionMapUri(contextId, uri: 'package:test/main.dart');
     expect(result.file, pathname);
 
     expect(await sendExecutionDeleteContext(contextId), isNull);
@@ -32,7 +31,7 @@
     // After the delete, expect this to fail.
     try {
       result =
-          await sendExecutionMapUri(contextId, uri: 'package:foo/main.dart');
+          await sendExecutionMapUri(contextId, uri: 'package:test/main.dart');
       fail('expected exception after context delete');
     } on ServerErrorMessage catch (message) {
       expect(message.error['code'], 'INVALID_PARAMETER');
diff --git a/pkg/analysis_server/test/integration/execution/map_uri_test.dart b/pkg/analysis_server/test/integration/execution/map_uri_test.dart
index 98f9e7e..e98032f 100644
--- a/pkg/analysis_server/test/integration/execution/map_uri_test.dart
+++ b/pkg/analysis_server/test/integration/execution/map_uri_test.dart
@@ -18,21 +18,19 @@
   Future<void> test_mapUri() async {
     var pathname = sourcePath('lib/main.dart');
     writeFile(pathname, '// dummy');
-    writeFile(sourcePath('.packages'), 'foo:lib/');
     standardAnalysisSetup();
 
-    var contextId =
-        (await sendExecutionCreateContext(sourceDirectory.path))?.id;
+    var contextId = (await sendExecutionCreateContext(sourceDirectory.path)).id;
 
     {
       var result =
-          await sendExecutionMapUri(contextId, uri: 'package:foo/main.dart');
+          await sendExecutionMapUri(contextId, uri: 'package:test/main.dart');
       expect(result.file, pathname);
     }
 
     {
       var result = await sendExecutionMapUri(contextId, file: pathname);
-      expect(result.uri, 'package:foo/main.dart');
+      expect(result.uri, 'package:test/main.dart');
     }
   }
 }
diff --git a/pkg/analysis_server/test/integration/linter/lint_names_test.dart b/pkg/analysis_server/test/integration/linter/lint_names_test.dart
index f36937a..e30881f 100644
--- a/pkg/analysis_server/test/integration/linter/lint_names_test.dart
+++ b/pkg/analysis_server/test/integration/linter/lint_names_test.dart
@@ -16,7 +16,6 @@
 import 'package:analyzer/src/lint/registry.dart';
 import 'package:analyzer/src/string_source.dart';
 import 'package:linter/src/rules.dart';
-import 'package:meta/meta.dart';
 import 'package:path/path.dart' as path;
 import 'package:test/test.dart';
 
@@ -48,22 +47,24 @@
   });
 }
 
-List<LintRule> _registeredLints;
+List<LintRule>? _registeredLints;
 
 Iterable<String> get registeredLintNames => registeredLints.map((r) => r.name);
 
 List<LintRule> get registeredLints {
-  if (_registeredLints == null) {
+  var registeredLints = _registeredLints;
+  if (registeredLints == null) {
     if (Registry.ruleRegistry.isEmpty) {
       registerLintRules();
     }
-    _registeredLints = Registry.ruleRegistry.toList();
+    registeredLints = Registry.ruleRegistry.toList();
+    _registeredLints = registeredLints;
   }
-  return _registeredLints;
+  return registeredLints;
 }
 
 class CompilationUnitParser {
-  CompilationUnit parse({@required String contents, @required String name}) {
+  CompilationUnit parse({required String contents, required String name}) {
     var reader = CharSequenceReader(contents);
     var stringSource = StringSource(contents, name);
     var errorListener = _ErrorListener();
diff --git a/pkg/analysis_server/test/integration/lsp_server/analyzer_status_test.dart b/pkg/analysis_server/test/integration/lsp_server/analyzer_status_test.dart
index 0184100..94f3328 100644
--- a/pkg/analysis_server/test/integration/lsp_server/analyzer_status_test.dart
+++ b/pkg/analysis_server/test/integration/lsp_server/analyzer_status_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.
 
+// @dart = 2.9
+
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/integration/lsp_server/diagnostic_test.dart b/pkg/analysis_server/test/integration/lsp_server/diagnostic_test.dart
index 0763cda..6b026f7 100644
--- a/pkg/analysis_server/test/integration/lsp_server/diagnostic_test.dart
+++ b/pkg/analysis_server/test/integration/lsp_server/diagnostic_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.
 
+// @dart = 2.9
+
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -15,6 +17,34 @@
 
 @reflectiveTest
 class DiagnosticTest extends AbstractLspAnalysisServerIntegrationTest {
+  Future<void> test_contextMessage() async {
+    const content = '''
+void f() {
+  x = 0;
+  int [[x]] = 1;
+  print(x);
+}
+''';
+    newFile(mainFilePath, content: withoutMarkers(content));
+
+    final diagnosticsUpdate = waitForDiagnostics(mainFileUri);
+    await initialize();
+    final diagnostics = await diagnosticsUpdate;
+
+    expect(diagnostics, hasLength(1));
+    final diagnostic = diagnostics.first;
+    expect(
+        diagnostic.message,
+        startsWith(
+            "Local variable 'x' can't be referenced before it is declared"));
+
+    expect(diagnostic.relatedInformation, hasLength(1));
+    final relatedInfo = diagnostic.relatedInformation.first;
+    expect(relatedInfo.message, equals("The declaration of 'x' is here."));
+    expect(relatedInfo.location.uri, equals('$mainFileUri'));
+    expect(relatedInfo.location.range, equals(rangeFromMarkers(content)));
+  }
+
   Future<void> test_initialAnalysis() async {
     newFile(mainFilePath, content: 'String a = 1;');
 
diff --git a/pkg/analysis_server/test/integration/lsp_server/initialization_test.dart b/pkg/analysis_server/test/integration/lsp_server/initialization_test.dart
index 1759e58..422086a 100644
--- a/pkg/analysis_server/test/integration/lsp_server/initialization_test.dart
+++ b/pkg/analysis_server/test/integration/lsp_server/initialization_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:analysis_server/lsp_protocol/protocol_special.dart';
 import 'package:test/test.dart';
diff --git a/pkg/analysis_server/test/integration/lsp_server/integration_tests.dart b/pkg/analysis_server/test/integration/lsp_server/integration_tests.dart
index bd8a64f..fa871ff 100644
--- a/pkg/analysis_server/test/integration/lsp_server/integration_tests.dart
+++ b/pkg/analysis_server/test/integration/lsp_server/integration_tests.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
+
 import 'dart:async';
 import 'dart:io';
 
diff --git a/pkg/analysis_server/test/integration/lsp_server/server_test.dart b/pkg/analysis_server/test/integration/lsp_server/server_test.dart
index 8ceb281..2771564 100644
--- a/pkg/analysis_server/test/integration/lsp_server/server_test.dart
+++ b/pkg/analysis_server/test/integration/lsp_server/server_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.
 
+// @dart = 2.9
+
 import 'dart:convert';
 import 'dart:io';
 
diff --git a/pkg/analysis_server/test/integration/lsp_server/test_all.dart b/pkg/analysis_server/test/integration/lsp_server/test_all.dart
index 3c85a81..2a5741e 100644
--- a/pkg/analysis_server/test/integration/lsp_server/test_all.dart
+++ b/pkg/analysis_server/test/integration/lsp_server/test_all.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
+
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'analyzer_status_test.dart' as analyzer_status;
diff --git a/pkg/analysis_server/test/integration/search/find_element_references_test.dart b/pkg/analysis_server/test/integration/search/find_element_references_test.dart
index c0d758a..aab63ee 100644
--- a/pkg/analysis_server/test/integration/search/find_element_references_test.dart
+++ b/pkg/analysis_server/test/integration/search/find_element_references_test.dart
@@ -16,7 +16,7 @@
 
 @reflectiveTest
 class FindElementReferencesTest extends AbstractAnalysisServerIntegrationTest {
-  String pathname;
+  late String pathname;
 
   Future<void> test_badTarget() async {
     var text = r'''
@@ -50,7 +50,7 @@
     standardAnalysisSetup();
     await analysisFinished;
 
-    var results = await _findElementReferences(text);
+    var results = (await _findElementReferences(text))!;
     expect(results, hasLength(1));
     var result = results.first;
     expect(result.location.file, pathname);
@@ -59,7 +59,7 @@
     expect(result.path.first.name, 'main');
   }
 
-  Future<List<SearchResult>> _findElementReferences(String text) async {
+  Future<List<SearchResult>?> _findElementReferences(String text) async {
     var offset = text.indexOf(' /* target */') - 1;
     var result = await sendSearchFindElementReferences(pathname, offset, false);
     if (result.id == null) return null;
diff --git a/pkg/analysis_server/test/integration/search/find_member_declarations_test.dart b/pkg/analysis_server/test/integration/search/find_member_declarations_test.dart
index 74fab07..f8f65cf 100644
--- a/pkg/analysis_server/test/integration/search/find_member_declarations_test.dart
+++ b/pkg/analysis_server/test/integration/search/find_member_declarations_test.dart
@@ -16,8 +16,6 @@
 
 @reflectiveTest
 class FindMemberDeclarationsTest extends AbstractAnalysisServerIntegrationTest {
-  String pathname;
-
   Future<void> test_findMemberDeclarations() async {
     var text = r'''
 String qux() => 'qux';
@@ -28,7 +26,7 @@
 }
 ''';
 
-    pathname = sourcePath('foo.dart');
+    var pathname = sourcePath('foo.dart');
     writeFile(pathname, text);
     standardAnalysisSetup();
     await analysisFinished;
diff --git a/pkg/analysis_server/test/integration/search/find_member_references_test.dart b/pkg/analysis_server/test/integration/search/find_member_references_test.dart
index 249a3ba..176a205 100644
--- a/pkg/analysis_server/test/integration/search/find_member_references_test.dart
+++ b/pkg/analysis_server/test/integration/search/find_member_references_test.dart
@@ -16,8 +16,6 @@
 
 @reflectiveTest
 class FindMemberReferencesTest extends AbstractAnalysisServerIntegrationTest {
-  String pathname;
-
   Future<void> test_findMemberReferences() async {
     var text = r'''
 String qux() => 'qux';
@@ -28,7 +26,7 @@
 }
 ''';
 
-    pathname = sourcePath('foo.dart');
+    var pathname = sourcePath('foo.dart');
     writeFile(pathname, text);
     standardAnalysisSetup();
     await analysisFinished;
diff --git a/pkg/analysis_server/test/integration/search/find_top_level_declarations_test.dart b/pkg/analysis_server/test/integration/search/find_top_level_declarations_test.dart
index 79d3eb8..4ea563b 100644
--- a/pkg/analysis_server/test/integration/search/find_top_level_declarations_test.dart
+++ b/pkg/analysis_server/test/integration/search/find_top_level_declarations_test.dart
@@ -17,8 +17,6 @@
 @reflectiveTest
 class FindTopLevelDeclarationsTest
     extends AbstractAnalysisServerIntegrationTest {
-  String pathname;
-
   Future<void> test_findTopLevelDeclarations() async {
     var text = r'''
 String qux() => 'qux';
@@ -29,7 +27,7 @@
 }
 ''';
 
-    pathname = sourcePath('foo.dart');
+    var pathname = sourcePath('foo.dart');
     writeFile(pathname, text);
     standardAnalysisSetup();
     await analysisFinished;
diff --git a/pkg/analysis_server/test/integration/search/get_type_hierarchy_test.dart b/pkg/analysis_server/test/integration/search/get_type_hierarchy_test.dart
index 0003214..acc839e 100644
--- a/pkg/analysis_server/test/integration/search/get_type_hierarchy_test.dart
+++ b/pkg/analysis_server/test/integration/search/get_type_hierarchy_test.dart
@@ -18,9 +18,9 @@
 @reflectiveTest
 class GetTypeHierarchyTest extends AbstractAnalysisServerIntegrationTest {
   /// Pathname of the main file to run tests in.
-  String pathname;
+  late String pathname;
 
-  Future getTypeHierarchy_badTarget() {
+  Future getTypeHierarchy_badTarget() async {
     var text = r'''
 main() {
   if /* target */ (true) {
@@ -28,12 +28,11 @@
   }
 }
 ''';
-    return typeHierarchyTest(text).then((HierarchyResults results) {
-      expect(results, isNull);
-    });
+    var results = await typeHierarchyTestNullable(text);
+    expect(results, isNull);
   }
 
-  Future getTypeHierarchy_classElement() {
+  Future<void> getTypeHierarchy_classElement() {
     var text = r'''
 class Base {}
 class Pivot /* target */ extends Base {}
@@ -45,11 +44,12 @@
       void checkElement(String name) {
         // We don't check the full element data structure; just enough to make
         // sure that we're pointing to the correct element.
-        var element = results.items[results.nameToIndex[name]].classElement;
+        // var element = results.items[results.nameToIndex[name]].classElement;
+        var element = results.getItem(name).classElement;
         expect(element.kind, equals(ElementKind.CLASS));
         expect(element.name, equals(name));
         if (name != 'Object') {
-          expect(element.location.offset,
+          expect(element.location!.offset,
               equals(text.indexOf('class $name') + 'class '.length));
         }
       }
@@ -74,14 +74,13 @@
     });
   }
 
-  Future getTypeHierarchy_functionTarget() {
+  Future getTypeHierarchy_functionTarget() async {
     var text = r'''
 main /* target */ () {
 }
 ''';
-    return typeHierarchyTest(text).then((HierarchyResults results) {
-      expect(results, isNull);
-    });
+    var results = await typeHierarchyTestNullable(text);
+    expect(results, isNull);
   }
 
   Future getTypeHierarchy_interfaces() {
@@ -119,13 +118,13 @@
     return typeHierarchyTest(text).then((HierarchyResults results) {
       expect(results.items, hasLength(6));
       expect(results.getItem('Object').memberElement, isNull);
-      expect(results.getItem('Base1').memberElement.location.offset,
+      expect(results.getItem('Base1').memberElement!.location!.offset,
           equals(text.indexOf('foo /* base1 */')));
       expect(results.getItem('Base2').memberElement, isNull);
-      expect(results.getItem('Pivot').memberElement.location.offset,
+      expect(results.getItem('Pivot').memberElement!.location!.offset,
           equals(text.indexOf('foo /* target */')));
       expect(results.getItem('Derived1').memberElement, isNull);
-      expect(results.getItem('Derived2').memberElement.location.offset,
+      expect(results.getItem('Derived2').memberElement!.location!.offset,
           equals(text.indexOf('foo /* derived2 */')));
     });
   }
@@ -189,7 +188,7 @@
     });
   }
 
-  Future<void> test_getTypeHierarchy() {
+  Future<void> test_getTypeHierarchy() async {
     pathname = sourcePath('test.dart');
     // Write a dummy file which will be overridden by tests using
     // [sendAnalysisUpdateContent].
@@ -198,30 +197,34 @@
 
     // Run all the getTypeHierarchy tests at once so that the server can take
     // advantage of incremental analysis and the test doesn't time out.
-    var tests = [
-      getTypeHierarchy_classElement,
-      getTypeHierarchy_displayName,
-      getTypeHierarchy_memberElement,
-      getTypeHierarchy_superclass,
-      getTypeHierarchy_interfaces,
-      getTypeHierarchy_mixins,
-      getTypeHierarchy_subclasses,
-      getTypeHierarchy_badTarget,
-      getTypeHierarchy_functionTarget
-    ];
-    return Future.forEach(tests, (test) => test());
+    await getTypeHierarchy_classElement();
+    await getTypeHierarchy_displayName();
+    await getTypeHierarchy_memberElement();
+    await getTypeHierarchy_superclass();
+    await getTypeHierarchy_interfaces();
+    await getTypeHierarchy_mixins();
+    await getTypeHierarchy_subclasses();
+    await getTypeHierarchy_badTarget();
+    await getTypeHierarchy_functionTarget();
   }
 
   Future<HierarchyResults> typeHierarchyTest(String text) async {
+    var results = (await typeHierarchyTestNullable(text))!;
+    return results;
+  }
+
+  Future<HierarchyResults?> typeHierarchyTestNullable(String text) async {
     var offset = text.indexOf(' /* target */') - 1;
     sendAnalysisUpdateContent({pathname: AddContentOverlay(text)});
     await analysisFinished;
     var result = await sendSearchGetTypeHierarchy(pathname, offset);
-    if (result.hierarchyItems == null) {
+
+    var hierarchyItems = result.hierarchyItems;
+    if (hierarchyItems == null) {
       return null;
-    } else {
-      return HierarchyResults(result.hierarchyItems);
     }
+
+    return HierarchyResults(hierarchyItems);
   }
 }
 
@@ -232,16 +235,14 @@
 
   /// The first hierarchy item from the result, which represents the pivot
   /// class.
-  TypeHierarchyItem pivot;
+  final TypeHierarchyItem pivot;
 
   /// A map from element name to item index.
-  Map<String, int> nameToIndex;
+  final Map<String, int> nameToIndex = {};
 
   /// Create a [HierarchyResults] object based on the result from a
   /// getTypeHierarchy request.
-  HierarchyResults(this.items) {
-    pivot = items[0];
-    nameToIndex = <String, int>{};
+  HierarchyResults(this.items) : pivot = items[0] {
     for (var i = 0; i < items.length; i++) {
       nameToIndex[items[i].classElement.name] = i;
     }
@@ -249,8 +250,9 @@
 
   /// Get an item by class name.
   TypeHierarchyItem getItem(String name) {
-    if (nameToIndex.containsKey(name)) {
-      return items[nameToIndex[name]];
+    var index = nameToIndex[name];
+    if (index != null) {
+      return items[index];
     } else {
       fail('Class $name not found in hierarchy results');
     }
diff --git a/pkg/analysis_server/test/integration/server/bazel_changes_test.dart b/pkg/analysis_server/test/integration/server/bazel_changes_test.dart
new file mode 100644
index 0000000..f904df3
--- /dev/null
+++ b/pkg/analysis_server/test/integration/server/bazel_changes_test.dart
@@ -0,0 +1,161 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. 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:analyzer_plugin/protocol/protocol_common.dart';
+import 'package:path/path.dart' as path;
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../support/integration_tests.dart';
+
+void main() {
+  // Skip on Windows.
+  if (Platform.isWindows) {
+    return;
+  }
+
+  defineReflectiveSuite(() {
+    defineReflectiveTests(BazelChangesTest);
+  });
+}
+
+@reflectiveTest
+class BazelChangesTest extends AbstractAnalysisServerIntegrationTest {
+  var processedNotification = Completer<void>();
+
+  /// Path to the `command.log` file.
+  ///
+  /// Writing to it should trigger our change detection to run.
+  late String commandLogPath;
+
+  late String bazelRoot;
+  late String tmpPath;
+  late String workspacePath;
+  late String bazelOutPath;
+  late String bazelBinPath;
+  late String bazelGenfilesPath;
+  late Directory oldSourceDirectory;
+
+  String inTmpDir(String relative) =>
+      path.join(tmpPath, relative.replaceAll('/', path.separator));
+
+  String inWorkspace(String relative) =>
+      path.join(workspacePath, relative.replaceAll('/', path.separator));
+
+  @override
+  Future setUp() async {
+    await super.setUp();
+    oldSourceDirectory = sourceDirectory;
+
+    tmpPath = Directory(Directory.systemTemp
+            .createTempSync('analysisServer')
+            .resolveSymbolicLinksSync())
+        .path;
+    workspacePath = inTmpDir('workspace_root');
+    writeFile(inWorkspace('WORKSPACE'), '');
+
+    sourceDirectory = Directory(inWorkspace('third_party/dart/project'));
+    sourceDirectory.createSync(recursive: true);
+
+    bazelRoot = inTmpDir('bazel_root');
+    Directory(bazelRoot).createSync(recursive: true);
+
+    bazelOutPath = '$bazelRoot/execroot/bazel_workspace/bazel-out';
+    bazelBinPath = '$bazelRoot/execroot/bazel_workspace/bazel-out/bin';
+    bazelGenfilesPath =
+        '$bazelRoot/execroot/bazel_workspace/bazel-out/genfiles';
+
+    Directory(inTmpDir(bazelOutPath)).createSync(recursive: true);
+    Directory(inTmpDir(bazelBinPath)).createSync(recursive: true);
+    Directory(inTmpDir(bazelGenfilesPath)).createSync(recursive: true);
+
+    Link(inWorkspace('bazel-out')).createSync(bazelOutPath);
+    Link(inWorkspace('bazel-bin')).createSync(bazelBinPath);
+    Link(inWorkspace('bazel-genfiles')).createSync(bazelGenfilesPath);
+
+    commandLogPath = inTmpDir('$bazelRoot/command.log');
+  }
+
+  @override
+  Future tearDown() async {
+    Directory(tmpPath).deleteSync(recursive: true);
+    sourceDirectory = oldSourceDirectory;
+    await super.tearDown();
+  }
+
+  // Add a bit more time -- the isolate take a while to start when the test is
+  // not run from a snapshot.
+  @TestTimeout(Timeout.factor(2))
+  Future<void> test_bazelChanges() async {
+    var testFile = inWorkspace('${sourceDirectory.path}/lib/test.dart');
+
+    var errors = <AnalysisError>[];
+    onAnalysisErrors.listen((event) {
+      if (event.file == testFile) {
+        errors.addAll(event.errors);
+        processedNotification.complete();
+      }
+    });
+    var resetCompleterAndErrors = () async {
+      // This is necessary because our polling uses modification timestamps
+      // whose resolution seems to be too small for a test like this (i.e., we
+      // write to the `command.log` file, but if the modification timestamp
+      // doesn't change, we won't detect the change).
+      await Future.delayed(Duration(seconds: 1));
+      errors.clear();
+      processedNotification = Completer();
+    };
+
+    writeFile(testFile, r'''
+import 'generated.dart';
+void main() { my_fun(); }
+''');
+    standardAnalysisSetup();
+
+    await processedNotification.future;
+    expect(errors, isNotEmpty);
+    expect(errors[0].message, contains('generated.dart'));
+
+    // This seems to be necessary (at least when running the test from source),
+    // because it takes a while for the watcher isolate to start.
+    await Future.delayed(Duration(seconds: 10));
+
+    await resetCompleterAndErrors();
+    var generatedFilePath = inWorkspace(
+        '$bazelGenfilesPath/third_party/dart/project/lib/generated.dart');
+    writeFile(generatedFilePath, 'my_fun() {}');
+    writeFile(commandLogPath, 'Build completed successfully');
+
+    await processedNotification.future;
+    expect(errors, isEmpty);
+
+    // Now let's write a file that does not define `my_fun` -- we should get an
+    // error again.
+    await resetCompleterAndErrors();
+    writeFile(generatedFilePath, 'different_fun() {}');
+    writeFile(commandLogPath, 'Build completed');
+
+    await processedNotification.future;
+    expect(errors, isNotEmpty);
+
+    // Now delete the file completely.
+    await resetCompleterAndErrors();
+    File(generatedFilePath).deleteSync();
+    writeFile(commandLogPath, 'Build did NOT complete successfully');
+
+    await processedNotification.future;
+    expect(errors, isNotEmpty);
+
+    // And finally re-add the correct file -- errors should go away once again.
+    await resetCompleterAndErrors();
+    writeFile(generatedFilePath, 'my_fun() {}');
+    writeFile(commandLogPath, 'Build completed successfully');
+
+    await processedNotification.future;
+    expect(errors, isEmpty);
+  }
+}
diff --git a/pkg/analysis_server/test/integration/server/set_subscriptions_invalid_service_test.dart b/pkg/analysis_server/test/integration/server/set_subscriptions_invalid_service_test.dart
index afb3195..ce2abe6 100644
--- a/pkg/analysis_server/test/integration/server/set_subscriptions_invalid_service_test.dart
+++ b/pkg/analysis_server/test/integration/server/set_subscriptions_invalid_service_test.dart
@@ -16,15 +16,13 @@
 @reflectiveTest
 class SetSubscriptionsInvalidTest
     extends AbstractAnalysisServerIntegrationTest {
-  Future<void> test_setSubscriptions_invalidService() {
+  Future<void> test_setSubscriptions_invalidService() async {
     // TODO(paulberry): verify that if an invalid service is specified, the
     // current subscriptions are unchanged.
-    return server.send('server.setSubscriptions', {
-      'subscriptions': ['bogus']
-    }).then((_) {
-      fail('setSubscriptions should have produced an error');
-    }, onError: (error) {
-      // The expected error occurred.
-    });
+    expect(() async {
+      await server.send('server.setSubscriptions', {
+        'subscriptions': ['bogus']
+      });
+    }, throwsA(const TypeMatcher<ServerErrorMessage>()));
   }
 }
diff --git a/pkg/analysis_server/test/integration/server/status_test.dart b/pkg/analysis_server/test/integration/server/status_test.dart
index 1fdf46b..0588e16 100644
--- a/pkg/analysis_server/test/integration/server/status_test.dart
+++ b/pkg/analysis_server/test/integration/server/status_test.dart
@@ -25,8 +25,9 @@
     var analysisBegun = Completer();
     var analysisFinished = Completer();
     onServerStatus.listen((ServerStatusParams params) {
-      if (params.analysis != null) {
-        if (params.analysis.isAnalyzing) {
+      var analysisStatus = params.analysis;
+      if (analysisStatus != null) {
+        if (analysisStatus.isAnalyzing) {
           expect(analysisBegun.isCompleted, isFalse);
           analysisBegun.complete();
         } else {
diff --git a/pkg/analysis_server/test/integration/server/test_all.dart b/pkg/analysis_server/test/integration/server/test_all.dart
index 0a23427..92ae2b1 100644
--- a/pkg/analysis_server/test/integration/server/test_all.dart
+++ b/pkg/analysis_server/test/integration/server/test_all.dart
@@ -4,6 +4,7 @@
 
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
+import 'bazel_changes_test.dart' as bazel_changes_test;
 import 'get_version_test.dart' as get_version_test;
 import 'set_subscriptions_invalid_service_test.dart'
     as set_subscriptions_invalid_service_test;
@@ -13,6 +14,7 @@
 
 void main() {
   defineReflectiveSuite(() {
+    bazel_changes_test.main();
     get_version_test.main();
     set_subscriptions_test.main();
     set_subscriptions_invalid_service_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 b086276c4..c424f42 100644
--- a/pkg/analysis_server/test/integration/support/integration_test_methods.dart
+++ b/pkg/analysis_server/test/integration/support/integration_test_methods.dart
@@ -79,10 +79,10 @@
   /// pid: int
   ///
   ///   The process id of the analysis server process.
-  Stream<ServerConnectedParams> onServerConnected;
+  late Stream<ServerConnectedParams> onServerConnected;
 
   /// Stream controller for [onServerConnected].
-  StreamController<ServerConnectedParams> _onServerConnected;
+  late StreamController<ServerConnectedParams> _onServerConnected;
 
   /// Reports that an unexpected error has occurred while executing the server.
   /// This notification is not used for problems with specific requests (which
@@ -107,20 +107,20 @@
   ///
   ///   The stack trace associated with the generation of the error, used for
   ///   debugging the server.
-  Stream<ServerErrorParams> onServerError;
+  late Stream<ServerErrorParams> onServerError;
 
   /// Stream controller for [onServerError].
-  StreamController<ServerErrorParams> _onServerError;
+  late StreamController<ServerErrorParams> _onServerError;
 
   /// The stream of entries describing events happened in the server.
   ///
   /// Parameters
   ///
   /// entry: ServerLogEntry
-  Stream<ServerLogParams> onServerLog;
+  late Stream<ServerLogParams> onServerLog;
 
   /// Stream controller for [onServerLog].
-  StreamController<ServerLogParams> _onServerLog;
+  late StreamController<ServerLogParams> _onServerLog;
 
   /// Reports the current status of the server. Parameters are omitted if there
   /// has been no change in the status represented by that parameter.
@@ -143,10 +143,10 @@
   ///
   ///   Note: this status type is deprecated, and is no longer sent by the
   ///   server.
-  Stream<ServerStatusParams> onServerStatus;
+  late Stream<ServerStatusParams> onServerStatus;
 
   /// Stream controller for [onServerStatus].
-  StreamController<ServerStatusParams> _onServerStatus;
+  late StreamController<ServerStatusParams> _onServerStatus;
 
   /// Return the errors associated with the given file. If the errors for the
   /// given file have not yet been computed, or the most recently computed
@@ -490,7 +490,7 @@
   ///   that the normal pubspec.yaml mechanism should always be used.
   Future sendAnalysisSetAnalysisRoots(
       List<String> included, List<String> excluded,
-      {Map<String, String> packageRoots}) async {
+      {Map<String, String>? packageRoots}) async {
     var params = AnalysisSetAnalysisRootsParams(included, excluded,
             packageRoots: packageRoots)
         .toJson();
@@ -605,7 +605,7 @@
   ///
   /// Returns
   Future<AnalysisUpdateContentResult> sendAnalysisUpdateContent(
-      Map<String, dynamic> files) async {
+      Map<String, Object> files) async {
     var params = AnalysisUpdateContentParams(files).toJson();
     var result = await server.send('analysis.updateContent', params);
     var decoder = ResponseDecoder(null);
@@ -644,10 +644,10 @@
   /// directories: List<FilePath>
   ///
   ///   A list of the paths of the files that are being analyzed.
-  Stream<AnalysisAnalyzedFilesParams> onAnalysisAnalyzedFiles;
+  late Stream<AnalysisAnalyzedFilesParams> onAnalysisAnalyzedFiles;
 
   /// Stream controller for [onAnalysisAnalyzedFiles].
-  StreamController<AnalysisAnalyzedFilesParams> _onAnalysisAnalyzedFiles;
+  late StreamController<AnalysisAnalyzedFilesParams> _onAnalysisAnalyzedFiles;
 
   /// Reports closing labels relevant to a given file.
   ///
@@ -670,10 +670,10 @@
   ///   constructor/method calls and List arguments that span multiple lines.
   ///   Note that the ranges that are returned can overlap each other because
   ///   they may be associated with constructs that can be nested.
-  Stream<AnalysisClosingLabelsParams> onAnalysisClosingLabels;
+  late Stream<AnalysisClosingLabelsParams> onAnalysisClosingLabels;
 
   /// Stream controller for [onAnalysisClosingLabels].
-  StreamController<AnalysisClosingLabelsParams> _onAnalysisClosingLabels;
+  late StreamController<AnalysisClosingLabelsParams> _onAnalysisClosingLabels;
 
   /// Reports the errors associated with a given file. The set of errors
   /// included in the notification is always a complete list that supersedes
@@ -688,10 +688,10 @@
   /// errors: List<AnalysisError>
   ///
   ///   The errors contained in the file.
-  Stream<AnalysisErrorsParams> onAnalysisErrors;
+  late Stream<AnalysisErrorsParams> onAnalysisErrors;
 
   /// Stream controller for [onAnalysisErrors].
-  StreamController<AnalysisErrorsParams> _onAnalysisErrors;
+  late StreamController<AnalysisErrorsParams> _onAnalysisErrors;
 
   /// Reports that any analysis results that were previously associated with
   /// the given files should be considered to be invalid because those files
@@ -711,10 +711,10 @@
   /// files: List<FilePath>
   ///
   ///   The files that are no longer being analyzed.
-  Stream<AnalysisFlushResultsParams> onAnalysisFlushResults;
+  late Stream<AnalysisFlushResultsParams> onAnalysisFlushResults;
 
   /// Stream controller for [onAnalysisFlushResults].
-  StreamController<AnalysisFlushResultsParams> _onAnalysisFlushResults;
+  late StreamController<AnalysisFlushResultsParams> _onAnalysisFlushResults;
 
   /// Reports the folding regions associated with a given file. Folding regions
   /// can be nested, but will not be overlapping. Nesting occurs when a
@@ -734,10 +734,10 @@
   /// regions: List<FoldingRegion>
   ///
   ///   The folding regions contained in the file.
-  Stream<AnalysisFoldingParams> onAnalysisFolding;
+  late Stream<AnalysisFoldingParams> onAnalysisFolding;
 
   /// Stream controller for [onAnalysisFolding].
-  StreamController<AnalysisFoldingParams> _onAnalysisFolding;
+  late StreamController<AnalysisFoldingParams> _onAnalysisFolding;
 
   /// Reports the highlight regions associated with a given file.
   ///
@@ -758,10 +758,10 @@
   ///   some range. Note that the highlight regions that are returned can
   ///   overlap other highlight regions if there is more than one meaning
   ///   associated with a particular region.
-  Stream<AnalysisHighlightsParams> onAnalysisHighlights;
+  late Stream<AnalysisHighlightsParams> onAnalysisHighlights;
 
   /// Stream controller for [onAnalysisHighlights].
-  StreamController<AnalysisHighlightsParams> _onAnalysisHighlights;
+  late StreamController<AnalysisHighlightsParams> _onAnalysisHighlights;
 
   /// Reports the classes that are implemented or extended and class members
   /// that are implemented or overridden in a file.
@@ -783,10 +783,10 @@
   /// members: List<ImplementedMember>
   ///
   ///   The member defined in the file that are implemented or overridden.
-  Stream<AnalysisImplementedParams> onAnalysisImplemented;
+  late Stream<AnalysisImplementedParams> onAnalysisImplemented;
 
   /// Stream controller for [onAnalysisImplemented].
-  StreamController<AnalysisImplementedParams> _onAnalysisImplemented;
+  late StreamController<AnalysisImplementedParams> _onAnalysisImplemented;
 
   /// Reports that the navigation information associated with a region of a
   /// single file has become invalid and should be re-requested.
@@ -814,10 +814,10 @@
   ///   The delta to be applied to the offsets in information that follows the
   ///   invalidated region in order to update it so that it doesn't need to be
   ///   re-requested.
-  Stream<AnalysisInvalidateParams> onAnalysisInvalidate;
+  late Stream<AnalysisInvalidateParams> onAnalysisInvalidate;
 
   /// Stream controller for [onAnalysisInvalidate].
-  StreamController<AnalysisInvalidateParams> _onAnalysisInvalidate;
+  late StreamController<AnalysisInvalidateParams> _onAnalysisInvalidate;
 
   /// Reports the navigation targets associated with a given file.
   ///
@@ -850,10 +850,10 @@
   ///
   ///   The files containing navigation targets referenced in the file. They
   ///   are referenced by NavigationTargets by their index in this array.
-  Stream<AnalysisNavigationParams> onAnalysisNavigation;
+  late Stream<AnalysisNavigationParams> onAnalysisNavigation;
 
   /// Stream controller for [onAnalysisNavigation].
-  StreamController<AnalysisNavigationParams> _onAnalysisNavigation;
+  late StreamController<AnalysisNavigationParams> _onAnalysisNavigation;
 
   /// Reports the occurrences of references to elements within a single file.
   ///
@@ -870,10 +870,10 @@
   /// occurrences: List<Occurrences>
   ///
   ///   The occurrences of references to elements within the file.
-  Stream<AnalysisOccurrencesParams> onAnalysisOccurrences;
+  late Stream<AnalysisOccurrencesParams> onAnalysisOccurrences;
 
   /// Stream controller for [onAnalysisOccurrences].
-  StreamController<AnalysisOccurrencesParams> _onAnalysisOccurrences;
+  late StreamController<AnalysisOccurrencesParams> _onAnalysisOccurrences;
 
   /// Reports the outline associated with a single file.
   ///
@@ -902,10 +902,10 @@
   /// outline: Outline
   ///
   ///   The outline associated with the file.
-  Stream<AnalysisOutlineParams> onAnalysisOutline;
+  late Stream<AnalysisOutlineParams> onAnalysisOutline;
 
   /// Stream controller for [onAnalysisOutline].
-  StreamController<AnalysisOutlineParams> _onAnalysisOutline;
+  late StreamController<AnalysisOutlineParams> _onAnalysisOutline;
 
   /// Reports the overriding members in a file.
   ///
@@ -922,10 +922,10 @@
   /// overrides: List<Override>
   ///
   ///   The overrides associated with the file.
-  Stream<AnalysisOverridesParams> onAnalysisOverrides;
+  late Stream<AnalysisOverridesParams> onAnalysisOverrides;
 
   /// Stream controller for [onAnalysisOverrides].
-  StreamController<AnalysisOverridesParams> _onAnalysisOverrides;
+  late StreamController<AnalysisOverridesParams> _onAnalysisOverrides;
 
   /// Request that completion suggestions for the given offset in the given
   /// file be returned.
@@ -1115,10 +1115,10 @@
   ///
   ///   If an AvailableSuggestion has relevance tags that match more than one
   ///   IncludedSuggestionRelevanceTag, the maximum relevance boost is used.
-  Stream<CompletionResultsParams> onCompletionResults;
+  late Stream<CompletionResultsParams> onCompletionResults;
 
   /// Stream controller for [onCompletionResults].
-  StreamController<CompletionResultsParams> _onCompletionResults;
+  late StreamController<CompletionResultsParams> _onCompletionResults;
 
   /// Reports the pre-computed, candidate completions from symbols defined in a
   /// corresponding library. This notification may be sent multiple times. When
@@ -1138,10 +1138,11 @@
   /// removedLibraries: List<int> (optional)
   ///
   ///   A list of library ids that no longer apply.
-  Stream<CompletionAvailableSuggestionsParams> onCompletionAvailableSuggestions;
+  late Stream<CompletionAvailableSuggestionsParams>
+      onCompletionAvailableSuggestions;
 
   /// Stream controller for [onCompletionAvailableSuggestions].
-  StreamController<CompletionAvailableSuggestionsParams>
+  late StreamController<CompletionAvailableSuggestionsParams>
       _onCompletionAvailableSuggestions;
 
   /// Reports existing imports in a library. This notification may be sent
@@ -1157,10 +1158,10 @@
   /// imports: ExistingImports
   ///
   ///   The existing imports in the library.
-  Stream<CompletionExistingImportsParams> onCompletionExistingImports;
+  late Stream<CompletionExistingImportsParams> onCompletionExistingImports;
 
   /// Stream controller for [onCompletionExistingImports].
-  StreamController<CompletionExistingImportsParams>
+  late StreamController<CompletionExistingImportsParams>
       _onCompletionExistingImports;
 
   /// Perform a search for references to the element defined or referenced at
@@ -1323,7 +1324,7 @@
   ///
   ///   The list of the paths of files with declarations.
   Future<SearchGetElementDeclarationsResult> sendSearchGetElementDeclarations(
-      {String file, String pattern, int maxResults}) async {
+      {String? file, String? pattern, int? maxResults}) async {
     var params = SearchGetElementDeclarationsParams(
             file: file, pattern: pattern, maxResults: maxResults)
         .toJson();
@@ -1367,7 +1368,7 @@
   ///   to allow a type hierarchy to be produced.
   Future<SearchGetTypeHierarchyResult> sendSearchGetTypeHierarchy(
       String file, int offset,
-      {bool superOnly}) async {
+      {bool? superOnly}) async {
     var params =
         SearchGetTypeHierarchyParams(file, offset, superOnly: superOnly)
             .toJson();
@@ -1395,10 +1396,10 @@
   ///
   ///   True if this is that last set of results that will be returned for the
   ///   indicated search.
-  Stream<SearchResultsParams> onSearchResults;
+  late Stream<SearchResultsParams> onSearchResults;
 
   /// Stream controller for [onSearchResults].
-  StreamController<SearchResultsParams> _onSearchResults;
+  late StreamController<SearchResultsParams> _onSearchResults;
 
   /// Format the contents of a single file. The currently selected region of
   /// text is passed in so that the selection can be preserved across the
@@ -1448,7 +1449,7 @@
   ///   The length of the selection after formatting the code.
   Future<EditFormatResult> sendEditFormat(
       String file, int selectionOffset, int selectionLength,
-      {int lineLength}) async {
+      {int? lineLength}) async {
     var params = EditFormatParams(file, selectionOffset, selectionLength,
             lineLength: lineLength)
         .toJson();
@@ -1578,7 +1579,7 @@
   ///   Details that summarize the fixes associated with the recommended
   ///   changes.
   Future<EditBulkFixesResult> sendEditBulkFixes(List<String> included,
-      {bool inTestMode}) async {
+      {bool? inTestMode}) async {
     var params = EditBulkFixesParams(included, inTestMode: inTestMode).toJson();
     var result = await server.send('edit.bulkFixes', params);
     var decoder = ResponseDecoder(null);
@@ -1679,11 +1680,11 @@
   ///   proposed changes. There is one URL for each of the included file paths.
   ///   The field is omitted if a preview was not requested.
   Future<EditDartfixResult> sendEditDartfix(List<String> included,
-      {List<String> includedFixes,
-      bool includePedanticFixes,
-      List<String> excludedFixes,
-      int port,
-      String outputDir}) async {
+      {List<String>? includedFixes,
+      bool? includePedanticFixes,
+      List<String>? excludedFixes,
+      int? port,
+      String? outputDir}) async {
     var params = EditDartfixParams(included,
             includedFixes: includedFixes,
             includePedanticFixes: includePedanticFixes,
@@ -1839,7 +1840,7 @@
   ///   the refactoring.
   Future<EditGetRefactoringResult> sendEditGetRefactoring(RefactoringKind kind,
       String file, int offset, int length, bool validateOnly,
-      {RefactoringOptions options}) async {
+      {RefactoringOptions? options}) async {
     var params = EditGetRefactoringParams(
             kind, file, offset, length, validateOnly,
             options: options)
@@ -1973,7 +1974,7 @@
   ///   that need to be applied.
   Future<EditImportElementsResult> sendEditImportElements(
       String file, List<ImportedElements> elements,
-      {int offset}) async {
+      {int? offset}) async {
     var params =
         EditImportElementsParams(file, elements, offset: offset).toJson();
     var result = await server.send('edit.importElements', params);
@@ -2162,7 +2163,7 @@
       String contextFile,
       int contextOffset,
       List<RuntimeCompletionVariable> variables,
-      {List<RuntimeCompletionExpression> expressions}) async {
+      {List<RuntimeCompletionExpression>? expressions}) async {
     var params = ExecutionGetSuggestionsParams(
             code, offset, contextFile, contextOffset, variables,
             expressions: expressions)
@@ -2219,7 +2220,7 @@
   ///   The URI to which the file path was mapped. This field is omitted if the
   ///   file field was not given in the request.
   Future<ExecutionMapUriResult> sendExecutionMapUri(String id,
-      {String file, String uri}) async {
+      {String? file, String? uri}) async {
     var params = ExecutionMapUriParams(id, file: file, uri: uri).toJson();
     var result = await server.send('execution.mapUri', params);
     var decoder = ResponseDecoder(null);
@@ -2271,10 +2272,10 @@
   ///
   ///   A list of the Dart files that are referenced by the file. This field is
   ///   omitted if the file is not an HTML file.
-  Stream<ExecutionLaunchDataParams> onExecutionLaunchData;
+  late Stream<ExecutionLaunchDataParams> onExecutionLaunchData;
 
   /// Stream controller for [onExecutionLaunchData].
-  StreamController<ExecutionLaunchDataParams> _onExecutionLaunchData;
+  late StreamController<ExecutionLaunchDataParams> _onExecutionLaunchData;
 
   /// Return server diagnostics.
   ///
@@ -2510,7 +2511,7 @@
   ///   The change that should be applied.
   Future<FlutterSetWidgetPropertyValueResult> sendFlutterSetWidgetPropertyValue(
       int id,
-      {FlutterWidgetPropertyValue value}) async {
+      {FlutterWidgetPropertyValue? value}) async {
     var params = FlutterSetWidgetPropertyValueParams(id, value: value).toJson();
     var result = await server.send('flutter.setWidgetPropertyValue', params);
     var decoder = ResponseDecoder(null);
@@ -2571,10 +2572,10 @@
   /// outline: FlutterOutline
   ///
   ///   The outline associated with the file.
-  Stream<FlutterOutlineParams> onFlutterOutline;
+  late Stream<FlutterOutlineParams> onFlutterOutline;
 
   /// Stream controller for [onFlutterOutline].
-  StreamController<FlutterOutlineParams> _onFlutterOutline;
+  late StreamController<FlutterOutlineParams> _onFlutterOutline;
 
   /// Initialize the fields in InttestMixin, and ensure that notifications will
   /// be handled.
@@ -2760,7 +2761,6 @@
         break;
       default:
         fail('Unexpected notification: $event');
-        break;
     }
   }
 }
diff --git a/pkg/analysis_server/test/integration/support/integration_tests.dart b/pkg/analysis_server/test/integration/support/integration_tests.dart
index 69a4804..5b1c58d 100644
--- a/pkg/analysis_server/test/integration/support/integration_tests.dart
+++ b/pkg/analysis_server/test/integration/support/integration_tests.dart
@@ -9,8 +9,10 @@
 
 import 'package:analysis_server/protocol/protocol_constants.dart';
 import 'package:analysis_server/protocol/protocol_generated.dart';
+import 'package:analyzer/src/test_utilities/package_config_file_builder.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:path/path.dart';
+import 'package:path/path.dart' as pkg_path;
 import 'package:test/test.dart';
 
 import 'integration_test_methods.dart';
@@ -40,7 +42,7 @@
 
 /// Assert that [actual] matches [matcher].
 void outOfTestExpect(actual, Matcher matcher,
-    {String reason, skip, bool verbose = false}) {
+    {String? reason, skip, bool verbose = false}) {
   var matchState = {};
   try {
     if (matcher.matches(actual, matchState)) return;
@@ -51,7 +53,7 @@
 }
 
 String _defaultFailFormatter(
-    actual, Matcher matcher, String reason, Map matchState, bool verbose) {
+    actual, Matcher matcher, String? reason, Map matchState, bool verbose) {
   var description = StringDescription();
   description.add('Expected: ').addDescriptionOf(matcher).add('\n');
   description.add('  Actual: ').addDescriptionOf(actual).add('\n');
@@ -88,7 +90,7 @@
   final Server server = Server();
 
   /// Temporary directory in which source files can be stored.
-  Directory sourceDirectory;
+  late Directory sourceDirectory;
 
   /// Map from file path to the list of analysis errors which have most recently
   /// been received for the file.
@@ -96,7 +98,7 @@
       HashMap<String, List<AnalysisError>>();
 
   /// The last list of analyzed files received.
-  List<String> lastAnalyzedFiles;
+  late List<String> lastAnalyzedFiles;
 
   /// True if the teardown process should skip sending a "server.shutdown"
   /// request (e.g. because the server is known to have already shutdown).
@@ -119,12 +121,13 @@
   /// analysis to finish.
   Future<ServerStatusParams> get analysisFinished {
     var completer = Completer<ServerStatusParams>();
-    StreamSubscription<ServerStatusParams> subscription;
+    late StreamSubscription<ServerStatusParams> subscription;
     // This will only work if the caller has already subscribed to
     // SERVER_STATUS (e.g. using sendServerSetSubscriptions(['STATUS']))
     outOfTestExpect(_subscribedToServerStatus, isTrue);
     subscription = onServerStatus.listen((ServerStatusParams params) {
-      if (params.analysis != null && !params.analysis.isAnalyzing) {
+      var analysisStatus = params.analysis;
+      if (analysisStatus != null && !analysisStatus.isAnalyzing) {
         completer.complete(params);
         subscription.cancel();
       }
@@ -138,7 +141,17 @@
     server.debugStdio();
   }
 
-  List<AnalysisError> getErrors(String pathname) =>
+  /// If there was a set of errors (might be empty) received for the file
+  /// with the given [path], return it. If no errors - fail.
+  List<AnalysisError> existingErrorsForFile(String path) {
+    var errors = currentAnalysisErrors[path];
+    if (errors == null) {
+      fail('Expected errors for: $path');
+    }
+    return errors;
+  }
+
+  List<AnalysisError>? getErrors(String pathname) =>
       currentAnalysisErrors[pathname];
 
   /// Read a source file with the given absolute [pathname].
@@ -156,6 +169,7 @@
     sourceDirectory = Directory(Directory.systemTemp
         .createTempSync('analysisServer')
         .resolveSymbolicLinksSync());
+    writeTestPackageConfig();
 
     onAnalysisErrors.listen((AnalysisErrorsParams params) {
       currentAnalysisErrors[params.file] = params.errors;
@@ -217,8 +231,8 @@
 
   /// Start [server].
   Future startServer({
-    int diagnosticPort,
-    int servicesPort,
+    int? diagnosticPort,
+    int? servicesPort,
   }) {
     return server.start(
         diagnosticPort: diagnosticPort, servicesPort: servicesPort);
@@ -245,6 +259,40 @@
     file.writeAsStringSync(contents);
     return file.resolveSymbolicLinksSync();
   }
+
+  void writePackageConfig(
+    String path, {
+    required PackageConfigFileBuilder config,
+  }) {
+    writeFile(
+      path,
+      config.toContent(
+        toUriStr: (path) => '${pkg_path.toUri(path)}',
+      ),
+    );
+  }
+
+  void writeTestPackageConfig({
+    PackageConfigFileBuilder? config,
+    String? languageVersion,
+  }) {
+    if (config == null) {
+      config = PackageConfigFileBuilder();
+    } else {
+      config = config.copy();
+    }
+
+    config.add(
+      name: 'test',
+      rootPath: sourceDirectory.path,
+      languageVersion: languageVersion,
+    );
+
+    writePackageConfig(
+      sourcePath('.dart_tool/package_config.json'),
+      config: config,
+    );
+  }
 }
 
 /// Wrapper class for Matcher which doesn't create the underlying Matcher object
@@ -257,33 +305,30 @@
 
   /// The matcher returned by [_creator], if it has already been called.
   /// Otherwise null.
-  Matcher _wrappedMatcher;
+  Matcher? _wrappedMatcher;
 
   LazyMatcher(this._creator);
 
+  /// Create the wrapped matcher object, if it hasn't been created already.
+  Matcher get _matcher {
+    return _wrappedMatcher ??= _creator();
+  }
+
   @override
   Description describe(Description description) {
-    _createMatcher();
-    return _wrappedMatcher.describe(description);
+    return _matcher.describe(description);
   }
 
   @override
   Description describeMismatch(
       item, Description mismatchDescription, Map matchState, bool verbose) {
-    _createMatcher();
-    return _wrappedMatcher.describeMismatch(
+    return _matcher.describeMismatch(
         item, mismatchDescription, matchState, verbose);
   }
 
   @override
   bool matches(item, Map matchState) {
-    _createMatcher();
-    return _wrappedMatcher.matches(item, matchState);
-  }
-
-  /// Create the wrapped matcher object, if it hasn't been created already.
-  void _createMatcher() {
-    _wrappedMatcher ??= _creator();
+    return _matcher.matches(item, matchState);
   }
 }
 
@@ -315,11 +360,11 @@
 
   /// Fields that are required to be in the JSON object, and [Matcher]s
   /// describing their expected types.
-  final Map<String, Matcher> requiredFields;
+  final Map<String, Matcher>? requiredFields;
 
   /// Fields that are optional in the JSON object, and [Matcher]s describing
   /// their expected types.
-  final Map<String, Matcher> optionalFields;
+  final Map<String, Matcher>? optionalFields;
 
   const MatchesJsonObject(this.description, this.requiredFields,
       {this.optionalFields});
@@ -334,9 +379,11 @@
       mismatches.add(simpleDescription('is not a map'));
       return;
     }
+    var requiredFields = this.requiredFields;
+    var optionalFields = this.optionalFields;
     if (requiredFields != null) {
       requiredFields.forEach((String key, Matcher valueMatcher) {
-        if (!(item as Map).containsKey(key)) {
+        if (!item.containsKey(key)) {
           mismatches.add((Description mismatchDescription) =>
               mismatchDescription
                   .add('is missing field ')
@@ -352,13 +399,18 @@
     item.forEach((key, value) {
       if (requiredFields != null && requiredFields.containsKey(key)) {
         // Already checked this field
-      } else if (optionalFields != null && optionalFields.containsKey(key)) {
-        _checkField(key, value, optionalFields[key], mismatches);
-      } else {
-        mismatches.add((Description mismatchDescription) => mismatchDescription
-            .add('has unexpected field ')
-            .addDescriptionOf(key));
+        return;
       }
+      if (optionalFields != null) {
+        var optionalValue = optionalFields[key];
+        if (optionalValue != null) {
+          _checkField(key, value, optionalValue, mismatches);
+          return;
+        }
+      }
+      mismatches.add((Description mismatchDescription) => mismatchDescription
+          .add('has unexpected field ')
+          .addDescriptionOf(key));
     });
   }
 
@@ -380,13 +432,12 @@
 /// facilitate communication to and from the server.
 class Server {
   /// Server process object, or null if server hasn't been started yet.
-  Process _process;
+  late final Process _process;
 
   /// Commands that have been sent to the server but not yet acknowledged, and
   /// the [Completer] objects which should be completed when acknowledgement is
   /// received.
-  final Map<String, Completer<Map<String, dynamic>>> _pendingCommands =
-      <String, Completer<Map<String, dynamic>>>{};
+  final Map<String, Completer<Map<String, Object?>?>> _pendingCommands = {};
 
   /// Number which should be used to compute the 'id' to send in the next
   /// command sent to the server.
@@ -409,7 +460,7 @@
 
   /// The [currentElapseTime] at which the last communication was received from
   /// the server or `null` if no communication has been received.
-  double lastCommunicationTime;
+  double? lastCommunicationTime;
 
   /// The current elapse time (seconds) since the server was started.
   double get currentElapseTime => _time.elapsedTicks / _time.frequency;
@@ -533,14 +584,14 @@
   /// normal (non-error) response, the future will be completed with the
   /// 'result' field from the response.  If the server acknowledges the command
   /// with an error response, the future will be completed with an error.
-  Future<Map<String, dynamic>> send(
-      String method, Map<String, dynamic> params) {
+  Future<Map<String, Object?>?> send(
+      String method, Map<String, Object?>? params) {
     var id = '${_nextId++}';
-    var command = <String, dynamic>{'id': id, 'method': method};
+    var command = <String, Object?>{'id': id, 'method': method};
     if (params != null) {
       command['params'] = params;
     }
-    var completer = Completer<Map<String, dynamic>>();
+    var completer = Completer<Map<String, Object?>?>();
     _pendingCommands[id] = completer;
     var line = json.encode(command);
     _recordStdio('==> $line');
@@ -552,16 +603,13 @@
   /// with "--observe" and "--pause-isolates-on-exit", allowing the observatory
   /// to be used.
   Future start({
-    int diagnosticPort,
-    String instrumentationLogFile,
+    int? diagnosticPort,
+    String? instrumentationLogFile,
     bool profileServer = false,
-    String sdkPath,
-    int servicesPort,
+    String? sdkPath,
+    int? servicesPort,
     bool useAnalysisHighlight2 = false,
   }) async {
-    if (_process != null) {
-      throw Exception('Process already started');
-    }
     _time.start();
     var dartBinary = Platform.executable;
 
@@ -831,7 +879,7 @@
   @override
   Description describeMismatch(
       item, Description mismatchDescription, Map matchState, bool verbose) {
-    var mismatches = matchState['mismatches'] as List<MismatchDescriber>;
+    var mismatches = matchState['mismatches'] as List<MismatchDescriber>?;
     if (mismatches != null) {
       for (var i = 0; i < mismatches.length; i++) {
         var mismatch = mismatches[i];
diff --git a/pkg/analysis_server/test/integration/support/protocol_matchers.dart b/pkg/analysis_server/test/integration/support/protocol_matchers.dart
index 49e185e..4a8e453 100644
--- a/pkg/analysis_server/test/integration/support/protocol_matchers.dart
+++ b/pkg/analysis_server/test/integration/support/protocol_matchers.dart
@@ -1122,13 +1122,17 @@
 ///   "length": int
 ///   "startLine": int
 ///   "startColumn": int
+///   "endLine": int
+///   "endColumn": int
 /// }
 final Matcher isLocation = LazyMatcher(() => MatchesJsonObject('Location', {
       'file': isFilePath,
       'offset': isInt,
       'length': isInt,
       'startLine': isInt,
-      'startColumn': isInt
+      'startColumn': isInt,
+      'endLine': isInt,
+      'endColumn': isInt
     }));
 
 /// NavigationRegion
diff --git a/pkg/analysis_server/test/integration/test_all.dart b/pkg/analysis_server/test/integration/test_all.dart
index 9ef661b..5ed27bc1 100644
--- a/pkg/analysis_server/test/integration/test_all.dart
+++ b/pkg/analysis_server/test/integration/test_all.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
+
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'analysis/test_all.dart' as analysis;
diff --git a/pkg/analysis_server/test/lsp/analyzer_status_test.dart b/pkg/analysis_server/test/lsp/analyzer_status_test.dart
index 40cb5e4..8d1492a 100644
--- a/pkg/analysis_server/test/lsp/analyzer_status_test.dart
+++ b/pkg/analysis_server/test/lsp/analyzer_status_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/lsp/cancel_request_test.dart b/pkg/analysis_server/test/lsp/cancel_request_test.dart
index f39dff9..6780145 100644
--- a/pkg/analysis_server/test/lsp/cancel_request_test.dart
+++ b/pkg/analysis_server/test/lsp/cancel_request_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/lsp/change_workspace_folders_test.dart b/pkg/analysis_server/test/lsp/change_workspace_folders_test.dart
index 414c52d..9bec4ca 100644
--- a/pkg/analysis_server/test/lsp/change_workspace_folders_test.dart
+++ b/pkg/analysis_server/test/lsp/change_workspace_folders_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.
 
+// @dart = 2.9
+
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/lsp/closing_labels_test.dart b/pkg/analysis_server/test/lsp/closing_labels_test.dart
index 4a671a6..3a400e1 100644
--- a/pkg/analysis_server/test/lsp/closing_labels_test.dart
+++ b/pkg/analysis_server/test/lsp/closing_labels_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.
 
+// @dart = 2.9
+
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/lsp/code_actions_abstract.dart b/pkg/analysis_server/test/lsp/code_actions_abstract.dart
index 67d220b..ee4ca4d 100644
--- a/pkg/analysis_server/test/lsp/code_actions_abstract.dart
+++ b/pkg/analysis_server/test/lsp/code_actions_abstract.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
+
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:analysis_server/lsp_protocol/protocol_special.dart';
 import 'package:test/test.dart';
diff --git a/pkg/analysis_server/test/lsp/code_actions_assists_test.dart b/pkg/analysis_server/test/lsp/code_actions_assists_test.dart
index 03def9f..69e627b 100644
--- a/pkg/analysis_server/test/lsp/code_actions_assists_test.dart
+++ b/pkg/analysis_server/test/lsp/code_actions_assists_test.dart
@@ -2,7 +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.
 
+// @dart = 2.9
+
+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:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -16,6 +20,15 @@
 
 @reflectiveTest
 class AssistsCodeActionsTest extends AbstractCodeActionsTest {
+  @override
+  void setUp() {
+    super.setUp();
+    writePackageConfig(
+      projectFolderPath,
+      flutter: true,
+    );
+  }
+
   Future<void> test_appliesCorrectEdits_withDocumentChangesSupport() async {
     // This code should get an assist to add a show combinator.
     const content = '''
@@ -107,4 +120,171 @@
         await getCodeActions(pubspecFileUri.toString(), range: startOfDocRange);
     expect(codeActions, isEmpty);
   }
+
+  Future<void> test_snippetTextEdits_supported() async {
+    // This tests experimental support for including Snippets in TextEdits.
+    // https://github.com/rust-analyzer/rust-analyzer/blob/b35559a2460e7f0b2b79a7029db0c5d4e0acdb44/docs/dev/lsp-extensions.md#snippet-textedit
+    //
+    // This allows setting the cursor position/selection in TextEdits included
+    // in CodeActions, for example Flutter's "Wrap with widget" assist that
+    // should select the text "widget".
+
+    const content = '''
+    import 'package:flutter/widgets.dart';
+    build() {
+      return Container(
+        child: Row(
+          children: [^
+            Text('111'),
+            Text('222'),
+            Container(),
+          ],
+        ),
+      );
+    }
+    ''';
+
+    // For testing, the snippet will be inserted literally into the text, as
+    // this requires some magic on the client. The expected text should therefore
+    // contain the snippets in the standard format.
+    const expectedContent = r'''
+    import 'package:flutter/widgets.dart';
+    build() {
+      return Container(
+        child: Row(
+          children: [
+            ${0:widget}(
+              children: [
+                Text('111'),
+                Text('222'),
+                Container(),
+              ],
+            ),
+          ],
+        ),
+      );
+    }
+    ''';
+
+    newFile(mainFilePath, content: withoutMarkers(content));
+    await initialize(
+      textDocumentCapabilities: withCodeActionKinds(
+          emptyTextDocumentClientCapabilities, [CodeActionKind.Refactor]),
+      workspaceCapabilities:
+          withDocumentChangesSupport(emptyWorkspaceClientCapabilities),
+      experimentalCapabilities: {
+        'snippetTextEdit': true,
+      },
+    );
+
+    final marker = positionFromMarker(content);
+    final codeActions = await getCodeActions(mainFileUri.toString(),
+        range: Range(start: marker, end: marker));
+    final assist = findEditAction(codeActions,
+        CodeActionKind('refactor.flutter.wrap.generic'), 'Wrap with widget...');
+
+    // Ensure the edit came back, and using documentChanges.
+    expect(assist, isNotNull);
+    expect(assist.edit.documentChanges, isNotNull);
+    expect(assist.edit.changes, isNull);
+
+    // Ensure applying the changes will give us the expected content.
+    final contents = {
+      mainFilePath: withoutMarkers(content),
+    };
+    applyDocumentChanges(contents, assist.edit.documentChanges);
+    expect(contents[mainFilePath], equals(expectedContent));
+
+    // Also ensure there was a single edit that was correctly marked
+    // as a SnippetTextEdit.
+    final textEdits = _extractTextDocumentEdits(assist.edit.documentChanges)
+        .expand((tde) => tde.edits)
+        .map((edit) => edit.map(
+              (e) => e,
+              (e) => throw 'Expected SnippetTextEdit, got AnnotatedTextEdit',
+              (e) => throw 'Expected SnippetTextEdit, got TextEdit',
+            ))
+        .toList();
+    expect(textEdits, hasLength(1));
+    expect(textEdits.first.insertTextFormat, equals(InsertTextFormat.Snippet));
+  }
+
+  Future<void> test_snippetTextEdits_unsupported() async {
+    // This tests experimental support for including Snippets in TextEdits
+    // is not active when the client capabilities do not advertise support for it.
+    // https://github.com/rust-analyzer/rust-analyzer/blob/b35559a2460e7f0b2b79a7029db0c5d4e0acdb44/docs/dev/lsp-extensions.md#snippet-textedit
+
+    const content = '''
+    import 'package:flutter/widgets.dart';
+    build() {
+      return Container(
+        child: Row(
+          children: [^
+            Text('111'),
+            Text('222'),
+            Container(),
+          ],
+        ),
+      );
+    }
+    ''';
+
+    newFile(mainFilePath, content: withoutMarkers(content));
+    await initialize(
+      textDocumentCapabilities: withCodeActionKinds(
+          emptyTextDocumentClientCapabilities, [CodeActionKind.Refactor]),
+      workspaceCapabilities:
+          withDocumentChangesSupport(emptyWorkspaceClientCapabilities),
+    );
+
+    final marker = positionFromMarker(content);
+    final codeActions = await getCodeActions(mainFileUri.toString(),
+        range: Range(start: marker, end: marker));
+    final assist = findEditAction(codeActions,
+        CodeActionKind('refactor.flutter.wrap.generic'), 'Wrap with widget...');
+
+    // Ensure the edit came back, and using documentChanges.
+    expect(assist, isNotNull);
+    expect(assist.edit.documentChanges, isNotNull);
+    expect(assist.edit.changes, isNull);
+
+    // Extract just TextDocumentEdits, create/rename/delete are not relevant.
+    final textDocumentEdits =
+        _extractTextDocumentEdits(assist.edit.documentChanges);
+    final textEdits = textDocumentEdits
+        .expand((tde) => tde.edits)
+        .map((edit) => edit.map((e) => e, (e) => e, (e) => e))
+        .toList();
+
+    // Ensure the edit does _not_ have a format of Snippet, nor does it include
+    // any $ characters that would indicate snippet text.
+    for (final edit in textEdits) {
+      expect(edit, isNot(TypeMatcher<SnippetTextEdit>()));
+      expect(edit.newText, isNot(contains(r'$')));
+    }
+  }
+
+  List<TextDocumentEdit> _extractTextDocumentEdits(
+          Either2<
+                  List<TextDocumentEdit>,
+                  List<
+                      Either4<TextDocumentEdit, CreateFile, RenameFile,
+                          DeleteFile>>>
+              documentChanges) =>
+      documentChanges.map(
+        // Already TextDocumentEdits
+        (edits) => edits,
+        // Extract TextDocumentEdits from union of resource changes
+        (changes) => changes
+            .map(
+              (change) => change.map(
+                (textDocEdit) => textDocEdit,
+                (create) => null,
+                (rename) => null,
+                (delete) => null,
+              ),
+            )
+            .where((e) => e != null)
+            .toList(),
+      );
 }
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 abc67e7..8e6ba91 100644
--- a/pkg/analysis_server/test/lsp/code_actions_fixes_test.dart
+++ b/pkg/analysis_server/test/lsp/code_actions_fixes_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:linter/src/rules.dart';
 import 'package:path/path.dart' as path;
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 e6d10cc..1301230 100644
--- a/pkg/analysis_server/test/lsp/code_actions_refactor_test.dart
+++ b/pkg/analysis_server/test/lsp/code_actions_refactor_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.
 
+// @dart = 2.9
+
 import 'dart:async';
 
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
diff --git a/pkg/analysis_server/test/lsp/code_actions_source_test.dart b/pkg/analysis_server/test/lsp/code_actions_source_test.dart
index 9a75e7e..0d0ca6e 100644
--- a/pkg/analysis_server/test/lsp/code_actions_source_test.dart
+++ b/pkg/analysis_server/test/lsp/code_actions_source_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:analysis_server/src/lsp/constants.dart';
 import 'package:test/test.dart';
diff --git a/pkg/analysis_server/test/lsp/completion.dart b/pkg/analysis_server/test/lsp/completion.dart
index f1f5b9a..2e1e1e2 100644
--- a/pkg/analysis_server/test/lsp/completion.dart
+++ b/pkg/analysis_server/test/lsp/completion.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
+
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:test/test.dart';
 
diff --git a/pkg/analysis_server/test/lsp/completion_dart_test.dart b/pkg/analysis_server/test/lsp/completion_dart_test.dart
index 4ad9170..07e00ed 100644
--- a/pkg/analysis_server/test/lsp/completion_dart_test.dart
+++ b/pkg/analysis_server/test/lsp/completion_dart_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.
 
+// @dart = 2.9
+
 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;
diff --git a/pkg/analysis_server/test/lsp/completion_yaml_test.dart b/pkg/analysis_server/test/lsp/completion_yaml_test.dart
index 9a9da49..a00dce5 100644
--- a/pkg/analysis_server/test/lsp/completion_yaml_test.dart
+++ b/pkg/analysis_server/test/lsp/completion_yaml_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/pub/pub_api.dart';
 import 'package:http/http.dart';
 import 'package:linter/src/rules.dart';
diff --git a/pkg/analysis_server/test/lsp/configuration_test.dart b/pkg/analysis_server/test/lsp/configuration_test.dart
index 2c91650..980af42 100644
--- a/pkg/analysis_server/test/lsp/configuration_test.dart
+++ b/pkg/analysis_server/test/lsp/configuration_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/lsp/definition_test.dart b/pkg/analysis_server/test/lsp/definition_test.dart
index d64412c..f78d059 100644
--- a/pkg/analysis_server/test/lsp/definition_test.dart
+++ b/pkg/analysis_server/test/lsp/definition_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart' as lsp;
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin;
diff --git a/pkg/analysis_server/test/lsp/diagnostic_test.dart b/pkg/analysis_server/test/lsp/diagnostic_test.dart
index 5adeef9..46ace8a 100644
--- a/pkg/analysis_server/test/lsp/diagnostic_test.dart
+++ b/pkg/analysis_server/test/lsp/diagnostic_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart' as plugin;
@@ -33,12 +35,12 @@
     final pluginError = plugin.AnalysisError(
       plugin.AnalysisErrorSeverity.ERROR,
       plugin.AnalysisErrorType.STATIC_TYPE_WARNING,
-      plugin.Location(pluginAnalyzedFilePath, 0, 6, 0, 0),
+      plugin.Location(pluginAnalyzedFilePath, 0, 6, 0, 0, 0, 6),
       'Test error from plugin',
       'ERR1',
       contextMessages: [
         plugin.DiagnosticMessage('Related error',
-            plugin.Location(pluginAnalyzedFilePath, 31, 4, 1, 12))
+            plugin.Location(pluginAnalyzedFilePath, 31, 4, 1, 12, 1, 16))
       ],
     );
     final pluginResult =
diff --git a/pkg/analysis_server/test/lsp/document_changes_test.dart b/pkg/analysis_server/test/lsp/document_changes_test.dart
index a674b75..0c8f181 100644
--- a/pkg/analysis_server/test/lsp/document_changes_test.dart
+++ b/pkg/analysis_server/test/lsp/document_changes_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.
 
+// @dart = 2.9
+
 import 'dart:async';
 
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
diff --git a/pkg/analysis_server/test/lsp/document_highlights_test.dart b/pkg/analysis_server/test/lsp/document_highlights_test.dart
index 68b147d..1812f86 100644
--- a/pkg/analysis_server/test/lsp/document_highlights_test.dart
+++ b/pkg/analysis_server/test/lsp/document_highlights_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:analysis_server/src/lsp/constants.dart';
 import 'package:test/test.dart';
diff --git a/pkg/analysis_server/test/lsp/document_symbols_test.dart b/pkg/analysis_server/test/lsp/document_symbols_test.dart
index fa1e3e0..1883728 100644
--- a/pkg/analysis_server/test/lsp/document_symbols_test.dart
+++ b/pkg/analysis_server/test/lsp/document_symbols_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:analysis_server/src/lsp/constants.dart';
 import 'package:test/test.dart';
diff --git a/pkg/analysis_server/test/lsp/file_modification_test.dart b/pkg/analysis_server/test/lsp/file_modification_test.dart
index 3c9dac5..5f5e747 100644
--- a/pkg/analysis_server/test/lsp/file_modification_test.dart
+++ b/pkg/analysis_server/test/lsp/file_modification_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:analysis_server/lsp_protocol/protocol_special.dart';
 import 'package:test/test.dart';
diff --git a/pkg/analysis_server/test/lsp/flutter_outline_test.dart b/pkg/analysis_server/test/lsp/flutter_outline_test.dart
index 5ece2b69..60bb110 100644
--- a/pkg/analysis_server/test/lsp/flutter_outline_test.dart
+++ b/pkg/analysis_server/test/lsp/flutter_outline_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/lsp/folding_test.dart b/pkg/analysis_server/test/lsp/folding_test.dart
index 8b4e389..bea190d 100644
--- a/pkg/analysis_server/test/lsp/folding_test.dart
+++ b/pkg/analysis_server/test/lsp/folding_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart' as plugin;
 import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin;
diff --git a/pkg/analysis_server/test/lsp/format_test.dart b/pkg/analysis_server/test/lsp/format_test.dart
index e629a4d..ad5bb9c 100644
--- a/pkg/analysis_server/test/lsp/format_test.dart
+++ b/pkg/analysis_server/test/lsp/format_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:analysis_server/src/lsp/constants.dart';
 import 'package:test/test.dart';
diff --git a/pkg/analysis_server/test/lsp/hover_test.dart b/pkg/analysis_server/test/lsp/hover_test.dart
index de40613..0be55c5 100644
--- a/pkg/analysis_server/test/lsp/hover_test.dart
+++ b/pkg/analysis_server/test/lsp/hover_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:analysis_server/src/lsp/constants.dart';
 import 'package:test/test.dart';
diff --git a/pkg/analysis_server/test/lsp/implementation_test.dart b/pkg/analysis_server/test/lsp/implementation_test.dart
index 195b46b..63cc7f8 100644
--- a/pkg/analysis_server/test/lsp/implementation_test.dart
+++ b/pkg/analysis_server/test/lsp/implementation_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/lsp/initialization_test.dart b/pkg/analysis_server/test/lsp/initialization_test.dart
index f864ea6..032df8d 100644
--- a/pkg/analysis_server/test/lsp/initialization_test.dart
+++ b/pkg/analysis_server/test/lsp/initialization_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.
 
+// @dart = 2.9
+
 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';
diff --git a/pkg/analysis_server/test/lsp/mapping_test.dart b/pkg/analysis_server/test/lsp/mapping_test.dart
index ce08941..6c89580 100644
--- a/pkg/analysis_server/test/lsp/mapping_test.dart
+++ b/pkg/analysis_server/test/lsp/mapping_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart' as lsp;
 import 'package:analysis_server/src/lsp/mapping.dart' as lsp;
 import 'package:analysis_server/src/protocol_server.dart' as server;
diff --git a/pkg/analysis_server/test/lsp/outline_test.dart b/pkg/analysis_server/test/lsp/outline_test.dart
index 8ab0aa3..1c04b0c 100644
--- a/pkg/analysis_server/test/lsp/outline_test.dart
+++ b/pkg/analysis_server/test/lsp/outline_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/lsp/priority_files_test.dart b/pkg/analysis_server/test/lsp/priority_files_test.dart
index 028f903..8d5107c 100644
--- a/pkg/analysis_server/test/lsp/priority_files_test.dart
+++ b/pkg/analysis_server/test/lsp/priority_files_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.
 
+// @dart = 2.9
+
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/lsp/pub_package_service_test.dart b/pkg/analysis_server/test/lsp/pub_package_service_test.dart
index f76aaa9..f40f50a 100644
--- a/pkg/analysis_server/test/lsp/pub_package_service_test.dart
+++ b/pkg/analysis_server/test/lsp/pub_package_service_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/pub/pub_api.dart';
 import 'package:analysis_server/src/services/pub/pub_package_service.dart';
 import 'package:analyzer/instrumentation/service.dart';
diff --git a/pkg/analysis_server/test/lsp/reanalyze_test.dart b/pkg/analysis_server/test/lsp/reanalyze_test.dart
index 69afce8..150c8a0 100644
--- a/pkg/analysis_server/test/lsp/reanalyze_test.dart
+++ b/pkg/analysis_server/test/lsp/reanalyze_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/lsp/references_test.dart b/pkg/analysis_server/test/lsp/references_test.dart
index 350de59..9af7eef 100644
--- a/pkg/analysis_server/test/lsp/references_test.dart
+++ b/pkg/analysis_server/test/lsp/references_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/lsp/rename_test.dart b/pkg/analysis_server/test/lsp/rename_test.dart
index 6c14e48..a65a4ef 100644
--- a/pkg/analysis_server/test/lsp/rename_test.dart
+++ b/pkg/analysis_server/test/lsp/rename_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:analysis_server/src/lsp/constants.dart';
 import 'package:meta/meta.dart';
diff --git a/pkg/analysis_server/test/lsp/semantic_tokens_test.dart b/pkg/analysis_server/test/lsp/semantic_tokens_test.dart
index dfd4324..b97795e 100644
--- a/pkg/analysis_server/test/lsp/semantic_tokens_test.dart
+++ b/pkg/analysis_server/test/lsp/semantic_tokens_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:analysis_server/src/lsp/constants.dart';
 import 'package:analysis_server/src/lsp/semantic_tokens/legend.dart';
diff --git a/pkg/analysis_server/test/lsp/server_abstract.dart b/pkg/analysis_server/test/lsp/server_abstract.dart
index 2cf21e5..663687b 100644
--- a/pkg/analysis_server/test/lsp/server_abstract.dart
+++ b/pkg/analysis_server/test/lsp/server_abstract.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
+
 import 'dart:async';
 
 import 'package:analysis_server/lsp_protocol/protocol_custom_generated.dart';
@@ -650,10 +652,10 @@
     });
   }
 
-  String applyTextEdit(
-      String content, Either2<TextEdit, AnnotatedTextEdit> change) {
+  String applyTextEdit(String content,
+      Either3<SnippetTextEdit, AnnotatedTextEdit, TextEdit> change) {
     // Both sites of the union can cast to TextEdit.
-    final edit = change.map((e) => e, (e) => e);
+    final edit = change.map((e) => e, (e) => e, (e) => e);
     final startPos = edit.range.start;
     final endPos = edit.range.end;
     final lineInfo = LineInfo.fromContent(content);
@@ -714,8 +716,8 @@
       );
 
     for (final change in sortedChanges) {
-      newContent = applyTextEdit(
-          newContent, Either2<TextEdit, AnnotatedTextEdit>.t1(change));
+      newContent = applyTextEdit(newContent,
+          Either3<SnippetTextEdit, AnnotatedTextEdit, TextEdit>.t3(change));
     }
 
     return newContent;
@@ -1217,6 +1219,7 @@
     TextDocumentClientCapabilities textDocumentCapabilities,
     ClientCapabilitiesWorkspace workspaceCapabilities,
     ClientCapabilitiesWindow windowCapabilities,
+    Map<String, Object> experimentalCapabilities,
     Map<String, Object> initializationOptions,
     bool throwOnFailure = true,
     bool allowEmptyRootUri = false,
@@ -1225,6 +1228,7 @@
       workspace: workspaceCapabilities,
       textDocument: textDocumentCapabilities,
       window: windowCapabilities,
+      experimental: experimentalCapabilities,
     );
 
     // Handle any standard incoming requests that aren't test-specific, for example
diff --git a/pkg/analysis_server/test/lsp/server_test.dart b/pkg/analysis_server/test/lsp/server_test.dart
index 8b0bd596..07858b3 100644
--- a/pkg/analysis_server/test/lsp/server_test.dart
+++ b/pkg/analysis_server/test/lsp/server_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:analysis_server/lsp_protocol/protocol_special.dart';
 import 'package:test/test.dart';
diff --git a/pkg/analysis_server/test/lsp/signature_help_test.dart b/pkg/analysis_server/test/lsp/signature_help_test.dart
index 9bee6e4..13432a9 100644
--- a/pkg/analysis_server/test/lsp/signature_help_test.dart
+++ b/pkg/analysis_server/test/lsp/signature_help_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/lsp/super_test.dart b/pkg/analysis_server/test/lsp/super_test.dart
index b9192d9..29eec48 100644
--- a/pkg/analysis_server/test/lsp/super_test.dart
+++ b/pkg/analysis_server/test/lsp/super_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/lsp/test_all.dart b/pkg/analysis_server/test/lsp/test_all.dart
index dd27eb3..4972696 100644
--- a/pkg/analysis_server/test/lsp/test_all.dart
+++ b/pkg/analysis_server/test/lsp/test_all.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
+
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import '../src/lsp/lsp_packet_transformer_test.dart' as lsp_packet_transformer;
diff --git a/pkg/analysis_server/test/lsp/will_rename_files_test.dart b/pkg/analysis_server/test/lsp/will_rename_files_test.dart
index e9b6fee..124671d 100644
--- a/pkg/analysis_server/test/lsp/will_rename_files_test.dart
+++ b/pkg/analysis_server/test/lsp/will_rename_files_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.
 
+// @dart = 2.9
+
 import 'dart:async';
 
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
diff --git a/pkg/analysis_server/test/lsp/workspace_symbols_test.dart b/pkg/analysis_server/test/lsp/workspace_symbols_test.dart
index 4c53c44..d20b42e 100644
--- a/pkg/analysis_server/test/lsp/workspace_symbols_test.dart
+++ b/pkg/analysis_server/test/lsp/workspace_symbols_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:analysis_server/lsp_protocol/protocol_special.dart';
 import 'package:test/test.dart';
diff --git a/pkg/analysis_server/test/mocks.dart b/pkg/analysis_server/test/mocks.dart
index d8c9e0a..f0ca226 100644
--- a/pkg/analysis_server/test/mocks.dart
+++ b/pkg/analysis_server/test/mocks.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
+
 import 'dart:async';
 import 'dart:convert';
 
diff --git a/pkg/analysis_server/test/plugin/protocol_dart_test.dart b/pkg/analysis_server/test/plugin/protocol_dart_test.dart
index 91ab49f..da9514d 100644
--- a/pkg/analysis_server/test/plugin/protocol_dart_test.dart
+++ b/pkg/analysis_server/test/plugin/protocol_dart_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/plugin/protocol/protocol_dart.dart';
 import 'package:analyzer/dart/element/element.dart' as engine;
 import 'package:analyzer/src/dart/element/element.dart' as engine;
diff --git a/pkg/analysis_server/test/plugin/test_all.dart b/pkg/analysis_server/test/plugin/test_all.dart
index 56ce709..66ab7e3 100644
--- a/pkg/analysis_server/test/plugin/test_all.dart
+++ b/pkg/analysis_server/test/plugin/test_all.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
+
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'protocol_dart_test.dart' as protocol_dart_test;
diff --git a/pkg/analysis_server/test/protocol_server_test.dart b/pkg/analysis_server/test/protocol_server_test.dart
index 8378710..65df4b5 100644
--- a/pkg/analysis_server/test/protocol_server_test.dart
+++ b/pkg/analysis_server/test/protocol_server_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.
 
+// @dart = 2.9
+
 import 'dart:mirrors';
 
 import 'package:analysis_server/src/protocol_server.dart'
@@ -71,7 +73,9 @@
         OFFSET: 10,
         LENGTH: 20,
         START_LINE: 3,
-        START_COLUMN: 2
+        START_COLUMN: 2,
+        END_LINE: 4,
+        END_COLUMN: 11,
       },
       MESSAGE: 'my message',
       CODE: 'ambiguous_export',
@@ -84,7 +88,9 @@
             OFFSET: 30,
             LENGTH: 5,
             START_LINE: 4,
-            START_COLUMN: 11
+            START_COLUMN: 11,
+            END_LINE: 4,
+            END_COLUMN: 16,
           }
         }
       ],
@@ -103,7 +109,9 @@
         OFFSET: 10,
         LENGTH: 20,
         START_LINE: 3,
-        START_COLUMN: 2
+        START_COLUMN: 2,
+        END_LINE: 4,
+        END_COLUMN: 11,
       },
       MESSAGE: 'my message',
       CORRECTION: 'my correction',
@@ -129,7 +137,9 @@
         OFFSET: 10,
         LENGTH: 20,
         START_LINE: 3,
-        START_COLUMN: 2
+        START_COLUMN: 2,
+        END_LINE: 4,
+        END_COLUMN: 11,
       },
       MESSAGE: 'my message',
       CODE: 'test_error',
@@ -154,7 +164,9 @@
         OFFSET: 10,
         LENGTH: 20,
         START_LINE: 3,
-        START_COLUMN: 2
+        START_COLUMN: 2,
+        END_LINE: 4,
+        END_COLUMN: 11,
       },
       MESSAGE: 'my message',
       CODE: 'my_lint',
@@ -174,7 +186,9 @@
         OFFSET: 10,
         LENGTH: 20,
         START_LINE: 3,
-        START_COLUMN: 2
+        START_COLUMN: 2,
+        END_LINE: 4,
+        END_COLUMN: 11,
       },
       MESSAGE: 'my message',
       CODE: 'ambiguous_export',
@@ -197,7 +211,9 @@
         OFFSET: 10,
         LENGTH: 20,
         START_LINE: -1,
-        START_COLUMN: -1
+        START_COLUMN: -1,
+        END_LINE: -1,
+        END_COLUMN: -1,
       },
       MESSAGE: 'my message',
       CODE: 'ambiguous_export',
diff --git a/pkg/analysis_server/test/protocol_test.dart b/pkg/analysis_server/test/protocol_test.dart
index 7f534a2..dc5a293 100644
--- a/pkg/analysis_server/test/protocol_test.dart
+++ b/pkg/analysis_server/test/protocol_test.dart
@@ -90,34 +90,34 @@
 
 @reflectiveTest
 class RequestTest {
-  void test_fromJson() {
+  void test_fromString() {
     var original = Request('one', 'aMethod');
     var jsonData = json.encode(original.toJson());
-    var request = Request.fromString(jsonData);
+    var request = Request.fromString(jsonData)!;
     expect(request.id, equals('one'));
     expect(request.method, equals('aMethod'));
     expect(request.clientRequestTime, isNull);
   }
 
-  void test_fromJson_invalidId() {
+  void test_fromString_invalidId_notString() {
     var json = '{"id":{"one":"two"},"method":"aMethod","params":{"foo":"bar"}}';
     var request = Request.fromString(json);
     expect(request, isNull);
   }
 
-  void test_fromJson_invalidMethod() {
+  void test_fromString_invalidMethod_notString() {
     var json = '{"id":"one","method":{"boo":"aMethod"},"params":{"foo":"bar"}}';
     var request = Request.fromString(json);
     expect(request, isNull);
   }
 
-  void test_fromJson_invalidParams() {
+  void test_fromString_invalidParams_notMap() {
     var json = '{"id":"one","method":"aMethod","params":"foobar"}';
     var request = Request.fromString(json);
     expect(request, isNull);
   }
 
-  void test_fromJson_withBadClientTime() {
+  void test_fromString_withBadClientTime() {
     var original = Request('one', 'aMethod', null, 347);
     var map = original.toJson();
     // Insert bad value - should be int but client sent string instead
@@ -127,19 +127,19 @@
     expect(request, isNull);
   }
 
-  void test_fromJson_withClientTime() {
+  void test_fromString_withClientTime() {
     var original = Request('one', 'aMethod', null, 347);
     var jsonData = json.encode(original.toJson());
-    var request = Request.fromString(jsonData);
+    var request = Request.fromString(jsonData)!;
     expect(request.id, equals('one'));
     expect(request.method, equals('aMethod'));
     expect(request.clientRequestTime, 347);
   }
 
-  void test_fromJson_withParams() {
+  void test_fromString_withParams() {
     var original = Request('one', 'aMethod', {'foo': 'bar'});
     var jsonData = json.encode(original.toJson());
-    var request = Request.fromString(jsonData);
+    var request = Request.fromString(jsonData)!;
     expect(request.id, equals('one'));
     expect(request.method, equals('aMethod'));
     expect(request.toJson()['params'], equals({'foo': 'bar'}));
@@ -197,25 +197,25 @@
 
   void test_fromJson() {
     var original = Response('myId');
-    var response = Response.fromJson(original.toJson());
+    var response = Response.fromJson(original.toJson())!;
     expect(response.id, equals('myId'));
   }
 
   void test_fromJson_withError() {
     var original = Response.invalidRequestFormat();
-    var response = Response.fromJson(original.toJson());
+    var response = Response.fromJson(original.toJson())!;
     expect(response.id, equals(''));
     expect(response.error, isNotNull);
-    var error = response.error;
+    var error = response.error!;
     expect(error.code, equals(RequestErrorCode.INVALID_REQUEST));
     expect(error.message, equals('Invalid request'));
   }
 
   void test_fromJson_withResult() {
     var original = Response('myId', result: {'foo': 'bar'});
-    var response = Response.fromJson(original.toJson());
+    var response = Response.fromJson(original.toJson())!;
     expect(response.id, equals('myId'));
-    var result = response.toJson()['result'] as Map<String, Object>;
+    var result = response.toJson()['result'] as Map<String, Object?>;
     expect(result.length, equals(1));
     expect(result['foo'], equals('bar'));
   }
diff --git a/pkg/analysis_server/test/search/abstract_search_domain.dart b/pkg/analysis_server/test/search/abstract_search_domain.dart
index 1e5b0d1..50021f6 100644
--- a/pkg/analysis_server/test/search/abstract_search_domain.dart
+++ b/pkg/analysis_server/test/search/abstract_search_domain.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
+
 import 'package:analysis_server/protocol/protocol.dart';
 import 'package:analysis_server/protocol/protocol_constants.dart';
 import 'package:analysis_server/protocol/protocol_generated.dart';
diff --git a/pkg/analysis_server/test/search/declarations_test.dart b/pkg/analysis_server/test/search/declarations_test.dart
index cb79730..349085d 100644
--- a/pkg/analysis_server/test/search/declarations_test.dart
+++ b/pkg/analysis_server/test/search/declarations_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/protocol/protocol_generated.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:test/test.dart';
diff --git a/pkg/analysis_server/test/search/element_references_test.dart b/pkg/analysis_server/test/search/element_references_test.dart
index 5b7d558..1049186 100644
--- a/pkg/analysis_server/test/search/element_references_test.dart
+++ b/pkg/analysis_server/test/search/element_references_test.dart
@@ -2,18 +2,18 @@
 // for 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 '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';
 import 'abstract_search_domain.dart';
 
 void main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(ElementReferencesTest);
-    defineReflectiveTests(ElementReferencesWithNonFunctionTypeAliasesTest);
   });
 }
 
@@ -21,8 +21,6 @@
 class ElementReferencesTest extends AbstractSearchDomainTest {
   Element searchElement;
 
-  bool get hasNonFunctionTypeAliases => false;
-
   void assertHasRef(SearchResultKind kind, String search, bool isPotential) {
     assertHasResult(kind, search);
     expect(result.isPotential, isPotential);
@@ -874,54 +872,11 @@
 }
 ''');
     await findElementReferences('F =', false);
-    expect(
-      searchElement.kind,
-      hasNonFunctionTypeAliases
-          ? ElementKind.TYPE_ALIAS
-          : ElementKind.FUNCTION_TYPE_ALIAS,
-    );
+    expect(searchElement.kind, ElementKind.TYPE_ALIAS);
     expect(results, hasLength(1));
     assertHasResult(SearchResultKind.REFERENCE, 'F f');
   }
 
-  Future<void> test_typeReference_typeAlias_legacy() async {
-    addTestFile('''
-typedef F();
-main(F f) {
-}
-''');
-    await findElementReferences('F()', false);
-    expect(
-      searchElement.kind,
-      hasNonFunctionTypeAliases
-          ? ElementKind.TYPE_ALIAS
-          : ElementKind.FUNCTION_TYPE_ALIAS,
-    );
-    expect(results, hasLength(1));
-    assertHasResult(SearchResultKind.REFERENCE, 'F f');
-  }
-
-  Future<void> test_typeReference_typeVariable() async {
-    addTestFile('''
-class A<T> {
-  T f;
-  T m() => null;
-}
-''');
-    await findElementReferences('T> {', false);
-    expect(searchElement.kind, ElementKind.TYPE_PARAMETER);
-    expect(results, hasLength(2));
-    assertHasResult(SearchResultKind.REFERENCE, 'T f;');
-    assertHasResult(SearchResultKind.REFERENCE, 'T m()');
-  }
-}
-
-@reflectiveTest
-class ElementReferencesWithNonFunctionTypeAliasesTest
-    extends ElementReferencesTest with WithNonFunctionTypeAliasesMixin {
-  @override
-  bool get hasNonFunctionTypeAliases => true;
-
   Future<void> test_typeReference_typeAlias_interfaceType() async {
     addTestFile('''
 typedef A<T> = Map<int, T>;
@@ -939,4 +894,30 @@
     expect(searchElement.kind, ElementKind.CLASS);
     assertHasResult(SearchResultKind.REFERENCE, 'int,');
   }
+
+  Future<void> test_typeReference_typeAlias_legacy() async {
+    addTestFile('''
+typedef F();
+main(F f) {
+}
+''');
+    await findElementReferences('F()', false);
+    expect(searchElement.kind, ElementKind.TYPE_ALIAS);
+    expect(results, hasLength(1));
+    assertHasResult(SearchResultKind.REFERENCE, 'F f');
+  }
+
+  Future<void> test_typeReference_typeVariable() async {
+    addTestFile('''
+class A<T> {
+  T f;
+  T m() => null;
+}
+''');
+    await findElementReferences('T> {', false);
+    expect(searchElement.kind, ElementKind.TYPE_PARAMETER);
+    expect(results, hasLength(2));
+    assertHasResult(SearchResultKind.REFERENCE, 'T f;');
+    assertHasResult(SearchResultKind.REFERENCE, 'T m()');
+  }
 }
diff --git a/pkg/analysis_server/test/search/member_declarations_test.dart b/pkg/analysis_server/test/search/member_declarations_test.dart
index 5e02cc2..46e9a46 100644
--- a/pkg/analysis_server/test/search/member_declarations_test.dart
+++ b/pkg/analysis_server/test/search/member_declarations_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/protocol/protocol_generated.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:test/test.dart';
diff --git a/pkg/analysis_server/test/search/member_references_test.dart b/pkg/analysis_server/test/search/member_references_test.dart
index a2c7b18..ca74c67 100644
--- a/pkg/analysis_server/test/search/member_references_test.dart
+++ b/pkg/analysis_server/test/search/member_references_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/protocol/protocol_generated.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/search/search_result_test.dart b/pkg/analysis_server/test/search/search_result_test.dart
index 02c82a6..978f0ec 100644
--- a/pkg/analysis_server/test/search/search_result_test.dart
+++ b/pkg/analysis_server/test/search/search_result_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/protocol_server.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
 import 'package:test/test.dart';
diff --git a/pkg/analysis_server/test/search/test_all.dart b/pkg/analysis_server/test/search/test_all.dart
index 403be90..b4e4f8c 100644
--- a/pkg/analysis_server/test/search/test_all.dart
+++ b/pkg/analysis_server/test/search/test_all.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
+
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'declarations_test.dart' as declarations_test;
diff --git a/pkg/analysis_server/test/search/top_level_declarations_test.dart b/pkg/analysis_server/test/search/top_level_declarations_test.dart
index 84735c2..37a7cf8 100644
--- a/pkg/analysis_server/test/search/top_level_declarations_test.dart
+++ b/pkg/analysis_server/test/search/top_level_declarations_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/protocol/protocol_generated.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:test/test.dart';
@@ -78,8 +80,8 @@
     await findTopLevelDeclarations('^[A-F]\$');
     assertHasDeclaration(ElementKind.CLASS, 'A');
     assertHasDeclaration(ElementKind.CLASS, 'B');
-    assertHasDeclaration(ElementKind.FUNCTION_TYPE_ALIAS, 'C');
-    assertHasDeclaration(ElementKind.FUNCTION_TYPE_ALIAS, 'D');
+    assertHasDeclaration(ElementKind.TYPE_ALIAS, 'C');
+    assertHasDeclaration(ElementKind.TYPE_ALIAS, 'D');
     assertHasDeclaration(ElementKind.FUNCTION, 'E');
     assertHasDeclaration(ElementKind.TOP_LEVEL_VARIABLE, 'F');
     assertNoDeclaration(ElementKind.CLASS, 'ABC');
diff --git a/pkg/analysis_server/test/search/type_hierarchy_test.dart b/pkg/analysis_server/test/search/type_hierarchy_test.dart
index 2c0f034..4b11bba 100644
--- a/pkg/analysis_server/test/search/type_hierarchy_test.dart
+++ b/pkg/analysis_server/test/search/type_hierarchy_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/protocol/protocol.dart';
 import 'package:analysis_server/protocol/protocol_generated.dart';
 import 'package:analysis_server/src/search/search_domain.dart';
diff --git a/pkg/analysis_server/test/services/completion/dart/arglist_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/arglist_contributor_test.dart
index 1004b9b..dc5be49 100644
--- a/pkg/analysis_server/test/services/completion/dart/arglist_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/arglist_contributor_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
 import 'package:analysis_server/src/services/completion/dart/arglist_contributor.dart';
 import 'package:analyzer/src/dart/analysis/experiments.dart';
diff --git a/pkg/analysis_server/test/services/completion/dart/combinator_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/combinator_contributor_test.dart
index ea96470..952c66a 100644
--- a/pkg/analysis_server/test/services/completion/dart/combinator_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/combinator_contributor_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
 import 'package:analysis_server/src/services/completion/dart/combinator_contributor.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
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 bd86522..d0bb800 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
@@ -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
+
 import 'dart:async';
 
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
@@ -19,12 +21,6 @@
 
 import '../../../abstract_context.dart';
 
-int suggestionComparator(CompletionSuggestion s1, CompletionSuggestion s2) {
-  var c1 = s1.completion.toLowerCase();
-  var c2 = s2.completion.toLowerCase();
-  return c1.compareTo(c2);
-}
-
 SuggestionMatcher suggestionHas(
         {@required String completion,
         ElementKind element,
@@ -96,8 +92,6 @@
   /// where there is no `new` or `const` keyword.
   bool get suggestConstructorsWithoutNew => true;
 
-  bool get usingFastaParser => true;
-
   void addTestSource(String content) {
     expect(completionOffset, isNull, reason: 'Call addTestUnit exactly once');
     completionOffset = content.indexOf('^');
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 cd8e243..ab89e1b 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
@@ -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
+
 import 'dart:async';
 
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
diff --git a/pkg/analysis_server/test/services/completion/dart/extension_member_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/extension_member_contributor_test.dart
index 12a2cad..2d51dba 100644
--- a/pkg/analysis_server/test/services/completion/dart/extension_member_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/extension_member_contributor_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
 import 'package:analysis_server/src/services/completion/dart/extension_member_contributor.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/services/completion/dart/field_formal_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/field_formal_contributor_test.dart
index d28095f..58ed66b 100644
--- a/pkg/analysis_server/test/services/completion/dart/field_formal_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/field_formal_contributor_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
 import 'package:analysis_server/src/services/completion/dart/field_formal_contributor.dart';
 import 'package:test/test.dart';
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 ecb0f00..c1e03c4 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
@@ -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
+
 import 'package:analysis_server/src/protocol_server.dart';
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
 import 'package:analysis_server/src/services/completion/dart/imported_reference_contributor.dart';
@@ -32,6 +34,34 @@
 @reflectiveTest
 class ImportedReferenceContributorTest extends DartCompletionContributorTest
     with ImportedReferenceContributorMixin {
+  Future<void> test_Annotation_typeArguments() async {
+    addSource('/home/test/lib/a.dart', '''
+class C {}
+typedef T1 = void Function();
+typedef T2 = List<int>;
+''');
+
+    addTestSource('''
+import 'a.dart';
+
+class A<T> {
+  const A();
+}
+
+@A<^>()
+void f() {}
+''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestClass('C');
+    assertSuggestTypeAlias('T1',
+        aliasedType: 'void Function()', returnType: 'void');
+    assertSuggestTypeAlias('T2', aliasedType: 'List<int>');
+    assertNotSuggested('identical');
+  }
+
   /// Sanity check.  Permutations tested in local_ref_contributor.
   Future<void> test_ArgDefaults_function_with_required_named() async {
     writeTestPackageConfig(meta: true);
diff --git a/pkg/analysis_server/test/services/completion/dart/keyword_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/keyword_contributor_test.dart
index 5bda1ad..4abe258 100644
--- a/pkg/analysis_server/test/services/completion/dart/keyword_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/keyword_contributor_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
 import 'package:analysis_server/src/services/completion/dart/keyword_contributor.dart';
 import 'package:analyzer/dart/analysis/features.dart';
@@ -528,9 +530,7 @@
   Future<void> test_anonymous_function_async7() async {
     addTestSource('main() {foo("bar", () as^ => null');
     await computeSuggestions();
-    assertSuggestKeywords([],
-        pseudoKeywords:
-            usingFastaParser ? ['async'] : ['async', 'async*', 'sync*']);
+    assertSuggestKeywords([], pseudoKeywords: ['async']);
   }
 
   Future<void> test_anonymous_function_async8() async {
@@ -916,17 +916,13 @@
   Future<void> test_class_implements2() async {
     addTestSource('class A e^ implements foo');
     await computeSuggestions();
-    assertSuggestKeywords(usingFastaParser
-        ? [Keyword.EXTENDS]
-        : [Keyword.EXTENDS, Keyword.IMPLEMENTS]);
+    assertSuggestKeywords([Keyword.EXTENDS]);
   }
 
   Future<void> test_class_implements3() async {
     addTestSource('class A e^ implements foo { }');
     await computeSuggestions();
-    assertSuggestKeywords(usingFastaParser
-        ? [Keyword.EXTENDS]
-        : [Keyword.EXTENDS, Keyword.IMPLEMENTS]);
+    assertSuggestKeywords([Keyword.EXTENDS]);
   }
 
   Future<void> test_class_implements_name() async {
diff --git a/pkg/analysis_server/test/services/completion/dart/label_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/label_contributor_test.dart
index 6e8832b..b4223ba 100644
--- a/pkg/analysis_server/test/services/completion/dart/label_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/label_contributor_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/protocol_server.dart';
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
 import 'package:analysis_server/src/services/completion/dart/label_contributor.dart';
diff --git a/pkg/analysis_server/test/services/completion/dart/library_member_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/library_member_contributor_test.dart
index 023cef5..3ed1036 100644
--- a/pkg/analysis_server/test/services/completion/dart/library_member_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/library_member_contributor_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
 import 'package:analysis_server/src/services/completion/dart/library_member_contributor.dart';
 import 'package:test/test.dart';
diff --git a/pkg/analysis_server/test/services/completion/dart/library_prefix_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/library_prefix_contributor_test.dart
index e6e9ec2..e717c1d 100644
--- a/pkg/analysis_server/test/services/completion/dart/library_prefix_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/library_prefix_contributor_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/protocol_server.dart';
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
 import 'package:analysis_server/src/services/completion/dart/library_prefix_contributor.dart';
diff --git a/pkg/analysis_server/test/services/completion/dart/local_library_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/local_library_contributor_test.dart
index 6417557..3cabd97 100644
--- a/pkg/analysis_server/test/services/completion/dart/local_library_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/local_library_contributor_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
 import 'package:analysis_server/src/services/completion/dart/local_library_contributor.dart';
 import 'package:test/test.dart';
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 7fbc2bf..4f97ee4 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
@@ -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
+
 import 'package:analysis_server/src/protocol_server.dart';
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
 import 'package:analysis_server/src/services/completion/dart/local_reference_contributor.dart';
diff --git a/pkg/analysis_server/test/services/completion/dart/named_constructor_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/named_constructor_contributor_test.dart
index 68a9878..c058de6 100644
--- a/pkg/analysis_server/test/services/completion/dart/named_constructor_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/named_constructor_contributor_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
 import 'package:analysis_server/src/services/completion/dart/named_constructor_contributor.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
diff --git a/pkg/analysis_server/test/services/completion/dart/override_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/override_contributor_test.dart
index 34832e9..55cad3f 100644
--- a/pkg/analysis_server/test/services/completion/dart/override_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/override_contributor_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
 import 'package:analysis_server/src/services/completion/dart/override_contributor.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
diff --git a/pkg/analysis_server/test/services/completion/dart/relevance/bool_assignment_test.dart b/pkg/analysis_server/test/services/completion/dart/relevance/bool_assignment_test.dart
index 039c915..701f7c5 100644
--- a/pkg/analysis_server/test/services/completion/dart/relevance/bool_assignment_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/relevance/bool_assignment_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.
 
+// @dart = 2.9
+
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
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 81532df..8a2fcd3b 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,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
+
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:test/test.dart';
 
diff --git a/pkg/analysis_server/test/services/completion/dart/relevance/deprecated_member_test.dart b/pkg/analysis_server/test/services/completion/dart/relevance/deprecated_member_test.dart
index 44d0f92..fe82af1 100644
--- a/pkg/analysis_server/test/services/completion/dart/relevance/deprecated_member_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/relevance/deprecated_member_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.
 
+// @dart = 2.9
+
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/services/completion/dart/relevance/instance_member_test.dart b/pkg/analysis_server/test/services/completion/dart/relevance/instance_member_test.dart
index de08d73..5faa5df 100644
--- a/pkg/analysis_server/test/services/completion/dart/relevance/instance_member_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/relevance/instance_member_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.
 
+// @dart = 2.9
+
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'completion_relevance.dart';
diff --git a/pkg/analysis_server/test/services/completion/dart/relevance/is_no_such_method_test.dart b/pkg/analysis_server/test/services/completion/dart/relevance/is_no_such_method_test.dart
index 388a377..52327e6 100644
--- a/pkg/analysis_server/test/services/completion/dart/relevance/is_no_such_method_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/relevance/is_no_such_method_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.
 
+// @dart = 2.9
+
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/services/completion/dart/relevance/local_variable_test.dart b/pkg/analysis_server/test/services/completion/dart/relevance/local_variable_test.dart
index c1481fb..284020f 100644
--- a/pkg/analysis_server/test/services/completion/dart/relevance/local_variable_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/relevance/local_variable_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.
 
+// @dart = 2.9
+
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/services/completion/dart/relevance/named_argument_test.dart b/pkg/analysis_server/test/services/completion/dart/relevance/named_argument_test.dart
index ff02ed2..b9c200d 100644
--- a/pkg/analysis_server/test/services/completion/dart/relevance/named_argument_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/relevance/named_argument_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.
 
+// @dart = 2.9
+
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import '../../../../src/utilities/mock_packages.dart';
diff --git a/pkg/analysis_server/test/services/completion/dart/relevance/non_type_member_test.dart b/pkg/analysis_server/test/services/completion/dart/relevance/non_type_member_test.dart
index 084c91c..27f3789 100644
--- a/pkg/analysis_server/test/services/completion/dart/relevance/non_type_member_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/relevance/non_type_member_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.
 
+// @dart = 2.9
+
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/services/completion/dart/relevance/static_member_test.dart b/pkg/analysis_server/test/services/completion/dart/relevance/static_member_test.dart
index 314b1e0..7042169 100644
--- a/pkg/analysis_server/test/services/completion/dart/relevance/static_member_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/relevance/static_member_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.
 
+// @dart = 2.9
+
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'completion_relevance.dart';
diff --git a/pkg/analysis_server/test/services/completion/dart/relevance/test_all.dart b/pkg/analysis_server/test/services/completion/dart/relevance/test_all.dart
index d6679e5..d6bf383 100644
--- a/pkg/analysis_server/test/services/completion/dart/relevance/test_all.dart
+++ b/pkg/analysis_server/test/services/completion/dart/relevance/test_all.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
+
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'bool_assignment_test.dart' as bool_assignments;
diff --git a/pkg/analysis_server/test/services/completion/dart/static_member_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/static_member_contributor_test.dart
index 7253f49..72f6bb8 100644
--- a/pkg/analysis_server/test/services/completion/dart/static_member_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/static_member_contributor_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
 import 'package:analysis_server/src/services/completion/dart/static_member_contributor.dart';
 import 'package:test/test.dart';
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 c8ccce6..7e3c13c 100644
--- a/pkg/analysis_server/test/services/completion/dart/test_all.dart
+++ b/pkg/analysis_server/test/services/completion/dart/test_all.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
+
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'arglist_contributor_test.dart' as arglist_test;
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 894b3d0..9ff66d1 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
@@ -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
+
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
 import 'package:analysis_server/src/services/completion/dart/type_member_contributor.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
@@ -3067,6 +3069,21 @@
     assertNotSuggested('==');
   }
 
+  Future<void> test_methodInvocation_typeParameter() async {
+    addTestSource('''
+class A {
+  void a() {}
+}
+class C<T extends A> {
+  void c(T t) {
+    t.^;
+  }
+}
+''');
+    await computeSuggestions();
+    assertSuggestMethod('a', 'A', 'void');
+  }
+
   Future<void> test_mixin() async {
     addTestSource(r'''
 class A {
diff --git a/pkg/analysis_server/test/services/completion/dart/uri_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/uri_contributor_test.dart
index e19ca34..ab0b151 100644
--- a/pkg/analysis_server/test/services/completion/dart/uri_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/uri_contributor_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
 import 'package:analysis_server/src/services/completion/dart/uri_contributor.dart';
 import 'package:analyzer/file_system/memory_file_system.dart';
diff --git a/pkg/analysis_server/test/services/completion/dart/variable_name_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/variable_name_contributor_test.dart
index 3b75a53..5f252da 100644
--- a/pkg/analysis_server/test/services/completion/dart/variable_name_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/variable_name_contributor_test.dart
@@ -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
+
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
 import 'package:analysis_server/src/services/completion/dart/variable_name_contributor.dart';
 import 'package:test/test.dart';
diff --git a/pkg/analysis_server/test/services/completion/postfix/postfix_completion_test.dart b/pkg/analysis_server/test/services/completion/postfix/postfix_completion_test.dart
index fe4bbb1..a88af5a 100644
--- a/pkg/analysis_server/test/services/completion/postfix/postfix_completion_test.dart
+++ b/pkg/analysis_server/test/services/completion/postfix/postfix_completion_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/protocol_server.dart';
 import 'package:analysis_server/src/services/completion/postfix/postfix_completion.dart';
 import 'package:test/test.dart';
diff --git a/pkg/analysis_server/test/services/completion/postfix/test_all.dart b/pkg/analysis_server/test/services/completion/postfix/test_all.dart
index 36604fe..958d06b 100644
--- a/pkg/analysis_server/test/services/completion/postfix/test_all.dart
+++ b/pkg/analysis_server/test/services/completion/postfix/test_all.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
+
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'postfix_completion_test.dart' as postfix_completion_test;
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 504dc74..6d787d6 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
@@ -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
+
 import 'package:analysis_server/src/protocol_server.dart';
 import 'package:analysis_server/src/services/completion/statement/statement_completion.dart';
 import 'package:test/test.dart';
@@ -1398,17 +1400,7 @@
         (s) => _afterLast(s, '  '));
   }
 
-  @failingTest
   Future<void> test_noCloseParenWithSemicolon() async {
-    // TODO(danrubel):
-    // Fasta scanner produces an error message which is converted into
-    // an Analyzer error message before the fasta parser gets a chance
-    // to move it along with the associated synthetic ')' to a more
-    // appropriate location. This means that some statement completions,
-    // which are expecting errors in a particular location, don't work.
-    // Fixing this properly means modifying the scanner not to generate
-    // closing ')', then updating the parser to handle that situation.
-    // This is a fair amount of work and won't be tackled today.
     var before = '''
 main() {
   var s = 'sample'.substring(3;
@@ -1427,12 +1419,6 @@
     await _prepareCompletion('ing(3;', before, atEnd: true);
     _assertHasChange('Insert a newline at the end of the current line', after,
         (s) => _afterLast(s, '  '));
-
-    // The old Analyzer parser passes this test, but will be turned off soon.
-    // It is preferable to throw only if the old analyzer is being used,
-    // but there does not seem to be a reliable way to determine that here.
-    // TODO(danrubel): remove this once fasta parser is enabled by default.
-    throw 'remove this once fasta parser is enabled by default';
   }
 
   Future<void> test_semicolonFn() async {
@@ -1507,12 +1493,6 @@
 f() {}
 ''',
         (s) => _afterLast(s, '  '));
-
-    // The old Analyzer parser passes this test, but will be turned off soon.
-    // It is preferable to throw only if the old analyzer is being used,
-    // but there does not seem to be a reliable way to determine that here.
-    // TODO(danrubel): remove this once fasta parser is enabled by default.
-    throw 'remove this once fasta parser is enabled by default';
   }
 
   Future<void> test_semicolonFnExpr() async {
diff --git a/pkg/analysis_server/test/services/completion/statement/test_all.dart b/pkg/analysis_server/test/services/completion/statement/test_all.dart
index 6d4d86e..8edd7fe 100644
--- a/pkg/analysis_server/test/services/completion/statement/test_all.dart
+++ b/pkg/analysis_server/test/services/completion/statement/test_all.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
+
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'statement_completion_test.dart' as statement_completion_test;
diff --git a/pkg/analysis_server/test/services/completion/test_all.dart b/pkg/analysis_server/test/services/completion/test_all.dart
index 533fb7a..4aaa784 100644
--- a/pkg/analysis_server/test/services/completion/test_all.dart
+++ b/pkg/analysis_server/test/services/completion/test_all.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
+
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'dart/test_all.dart' as dart_all;
diff --git a/pkg/analysis_server/test/services/correction/change_test.dart b/pkg/analysis_server/test/services/correction/change_test.dart
index 90b2dd9..8616a2c 100644
--- a/pkg/analysis_server/test/services/correction/change_test.dart
+++ b/pkg/analysis_server/test/services/correction/change_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/protocol_server.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:test/test.dart';
diff --git a/pkg/analysis_server/test/services/correction/levenshtein_test.dart b/pkg/analysis_server/test/services/correction/levenshtein_test.dart
index dc320bd..fb1f656 100644
--- a/pkg/analysis_server/test/services/correction/levenshtein_test.dart
+++ b/pkg/analysis_server/test/services/correction/levenshtein_test.dart
@@ -46,15 +46,6 @@
     }, throwsArgumentError);
   }
 
-  void test_null() {
-    expect(() {
-      levenshtein('', null, 5);
-    }, throwsArgumentError);
-    expect(() {
-      levenshtein(null, '', 5);
-    }, throwsArgumentError);
-  }
-
   void test_same() {
     expect(levenshtein('', '', 5), 0);
     expect(levenshtein('test', 'test', 5), 0);
diff --git a/pkg/analysis_server/test/services/correction/organize_directives_test.dart b/pkg/analysis_server/test/services/correction/organize_directives_test.dart
index 4b8aa22..56a370b 100644
--- a/pkg/analysis_server/test/services/correction/organize_directives_test.dart
+++ b/pkg/analysis_server/test/services/correction/organize_directives_test.dart
@@ -19,7 +19,7 @@
 
 @reflectiveTest
 class OrganizeDirectivesTest extends AbstractSingleUnitTest {
-  List<AnalysisError> testErrors;
+  late List<AnalysisError> testErrors;
 
   Future<void> test_docComment_beforeDirective_hasUnresolvedIdentifier() async {
     await _computeUnitAndErrors(r'''
@@ -582,7 +582,7 @@
   Future<void> _computeUnitAndErrors(String code) async {
     addTestSource(code);
     var result = await session.getResolvedUnit(testFile);
-    testUnit = result.unit;
+    testUnit = result.unit!;
     testErrors = result.errors;
   }
 }
diff --git a/pkg/analysis_server/test/services/correction/status_test.dart b/pkg/analysis_server/test/services/correction/status_test.dart
index 96fb856..3bcc7a9 100644
--- a/pkg/analysis_server/test/services/correction/status_test.dart
+++ b/pkg/analysis_server/test/services/correction/status_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/protocol_server.dart' hide Element;
 import 'package:analysis_server/src/services/correction/status.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
@@ -98,7 +100,7 @@
   }
 
   void test_addFatalError_withLocation() {
-    var location = Location('/test.dart', 1, 2, 3, 4);
+    var location = Location('/test.dart', 1, 2, 3, 4, 5, 6);
     var refactoringStatus = RefactoringStatus();
     // initial state
     expect(refactoringStatus.severity, null);
@@ -211,7 +213,7 @@
   }
 
   void test_newError() {
-    var location = Location('/test.dart', 1, 2, 3, 4);
+    var location = Location('/test.dart', 1, 2, 3, 4, 5, 6);
     var refactoringStatus = RefactoringStatus.error('msg', location);
     expect(refactoringStatus.severity, RefactoringProblemSeverity.ERROR);
     expect(refactoringStatus.problem.message, 'msg');
diff --git a/pkg/analysis_server/test/services/correction/test_all.dart b/pkg/analysis_server/test/services/correction/test_all.dart
index 0b289d9..de358b6 100644
--- a/pkg/analysis_server/test/services/correction/test_all.dart
+++ b/pkg/analysis_server/test/services/correction/test_all.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
+
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'change_test.dart' as change_test;
diff --git a/pkg/analysis_server/test/services/correction/util_test.dart b/pkg/analysis_server/test/services/correction/util_test.dart
index cba88ef..203ccf9 100644
--- a/pkg/analysis_server/test/services/correction/util_test.dart
+++ b/pkg/analysis_server/test/services/correction/util_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/util.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
diff --git a/pkg/analysis_server/test/services/linter/linter_test.dart b/pkg/analysis_server/test/services/linter/linter_test.dart
index ec60e13..242489b 100644
--- a/pkg/analysis_server/test/services/linter/linter_test.dart
+++ b/pkg/analysis_server/test/services/linter/linter_test.dart
@@ -20,10 +20,12 @@
 @reflectiveTest
 class LinterRuleOptionsValidatorTest {
   final LinterRuleOptionsValidator validator = LinterRuleOptionsValidator();
+
   final AnalysisOptionsProvider optionsProvider = AnalysisOptionsProvider();
 
-  RecordingErrorListener recorder;
-  ErrorReporter reporter;
+  late RecordingErrorListener recorder;
+
+  late ErrorReporter reporter;
 
   List<AnalysisError> get errors => recorder.errors;
 
diff --git a/pkg/analysis_server/test/services/refactoring/abstract_refactoring.dart b/pkg/analysis_server/test/services/refactoring/abstract_refactoring.dart
index 82eca0f..7e982701 100644
--- a/pkg/analysis_server/test/services/refactoring/abstract_refactoring.dart
+++ b/pkg/analysis_server/test/services/refactoring/abstract_refactoring.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
+
 import 'package:analysis_server/src/services/correction/status.dart';
 import 'package:analysis_server/src/services/refactoring/refactoring.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
diff --git a/pkg/analysis_server/test/services/refactoring/abstract_rename.dart b/pkg/analysis_server/test/services/refactoring/abstract_rename.dart
index 3a3c7aa..1437541 100644
--- a/pkg/analysis_server/test/services/refactoring/abstract_rename.dart
+++ b/pkg/analysis_server/test/services/refactoring/abstract_rename.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
+
 import 'package:analysis_server/src/services/correction/namespace.dart';
 import 'package:analysis_server/src/services/refactoring/refactoring.dart';
 import 'package:analyzer/dart/ast/ast.dart';
diff --git a/pkg/analysis_server/test/services/refactoring/convert_getter_to_method_test.dart b/pkg/analysis_server/test/services/refactoring/convert_getter_to_method_test.dart
index 17c7103..ff2de57 100644
--- a/pkg/analysis_server/test/services/refactoring/convert_getter_to_method_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/convert_getter_to_method_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/refactoring/refactoring.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart' hide ElementKind;
diff --git a/pkg/analysis_server/test/services/refactoring/convert_method_to_getter_test.dart b/pkg/analysis_server/test/services/refactoring/convert_method_to_getter_test.dart
index 7afbb5d..d7434390 100644
--- a/pkg/analysis_server/test/services/refactoring/convert_method_to_getter_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/convert_method_to_getter_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/refactoring/refactoring.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart'
diff --git a/pkg/analysis_server/test/services/refactoring/extract_local_test.dart b/pkg/analysis_server/test/services/refactoring/extract_local_test.dart
index 4d5d5bf..215745e 100644
--- a/pkg/analysis_server/test/services/refactoring/extract_local_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/extract_local_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.
 
+// @dart = 2.9
+
 import 'dart:convert';
 
 import 'package:analysis_server/src/services/linter/lint_names.dart';
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 71155fe..06b2131 100644
--- a/pkg/analysis_server/test/services/refactoring/extract_method_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/extract_method_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/refactoring/extract_method.dart';
 import 'package:analysis_server/src/services/refactoring/refactoring.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
diff --git a/pkg/analysis_server/test/services/refactoring/extract_widget_test.dart b/pkg/analysis_server/test/services/refactoring/extract_widget_test.dart
index 23d0d92..8ceaf78 100644
--- a/pkg/analysis_server/test/services/refactoring/extract_widget_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/extract_widget_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/refactoring/extract_widget.dart';
 import 'package:analysis_server/src/services/refactoring/refactoring.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
diff --git a/pkg/analysis_server/test/services/refactoring/inline_local_test.dart b/pkg/analysis_server/test/services/refactoring/inline_local_test.dart
index 6409980..80920b8 100644
--- a/pkg/analysis_server/test/services/refactoring/inline_local_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/inline_local_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/status.dart';
 import 'package:analysis_server/src/services/refactoring/inline_local.dart';
 import 'package:analysis_server/src/services/refactoring/refactoring.dart';
diff --git a/pkg/analysis_server/test/services/refactoring/inline_method_test.dart b/pkg/analysis_server/test/services/refactoring/inline_method_test.dart
index 0f5d160..204df5c 100644
--- a/pkg/analysis_server/test/services/refactoring/inline_method_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/inline_method_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/refactoring/inline_method.dart';
 import 'package:analysis_server/src/services/refactoring/refactoring.dart';
 import 'package:analyzer/src/generated/source.dart';
diff --git a/pkg/analysis_server/test/services/refactoring/move_file_test.dart b/pkg/analysis_server/test/services/refactoring/move_file_test.dart
index fc03973..21879f2 100644
--- a/pkg/analysis_server/test/services/refactoring/move_file_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/move_file_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/protocol_server.dart';
 import 'package:analysis_server/src/services/refactoring/refactoring.dart';
 import 'package:test/test.dart';
@@ -203,6 +205,21 @@
     assertNoFileChange(testFile);
   }
 
+  Future<void> test_file_imported_with_relative_uri_same_folder() async {
+    // https://github.com/dart-lang/sdk/issues/45593
+    testFile = convertPath('/home/test/bin/aaa.dart');
+    var pathB = convertPath('/home/test/bin/bbb.dart');
+    addSource(pathB, '');
+    await resolveTestCode("import 'bbb.dart';");
+    await analyzeTestPackageFiles();
+
+    _createRefactoring('/home/test/bin/new_aaa.dart');
+    await _assertSuccessfulRefactoring();
+
+    assertNoFileChange(testFile);
+    assertNoFileChange(pathB);
+  }
+
   Future<void> test_file_imported_with_relative_uri_sideways() async {
     var pathA = convertPath('/home/test/000/1111/a.dart');
     testFile = convertPath('/home/test/000/1111/sub/folder/test.dart');
@@ -237,6 +254,31 @@
     assertNoFileChange(testFile);
   }
 
+  Future<void> test_file_moveOutOfLib() async {
+    var binMainPath = convertPath('/home/test/bin/main.dart');
+    addSource(binMainPath, '''
+import 'package:test/test.dart';
+
+main() {
+  var a = new Foo();
+}
+''');
+    await resolveTestCode('''
+class Foo {}
+''');
+    // perform refactoring
+    _createRefactoring('/home/test/bin/test.dart');
+    await _assertSuccessfulRefactoring();
+    assertFileChangeResult(binMainPath, '''
+import 'test.dart';
+
+main() {
+  var a = new Foo();
+}
+''');
+    assertNoFileChange(testFile);
+  }
+
   @failingTest
   Future<void> test_file_referenced_by_multiple_libraries() async {
     // This test fails because the search index doesn't support multiple uris for
@@ -395,9 +437,7 @@
     assertFileChangeResult(pathA, '''
 part of 'test2.dart';
 ''');
-    assertFileChangeResult(testFile, '''
-part 'a.dart';
-''');
+    assertNoFileChange(testFile);
   }
 
   Future<void> test_renaming_part_that_uses_uri_in_part_of_4() async {
@@ -445,9 +485,7 @@
     assertFileChangeResult(pathA, '''
 part 'test2.dart';
 ''');
-    assertFileChangeResult(testFile, '''
-part of 'a.dart';
-''');
+    assertNoFileChange(testFile);
   }
 
   Future _assertFailedRefactoring(RefactoringProblemSeverity expectedSeverity,
diff --git a/pkg/analysis_server/test/services/refactoring/naming_conventions_test.dart b/pkg/analysis_server/test/services/refactoring/naming_conventions_test.dart
index ea21e44..810ec9b 100644
--- a/pkg/analysis_server/test/services/refactoring/naming_conventions_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/naming_conventions_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/status.dart';
 import 'package:analysis_server/src/services/refactoring/naming_conventions.dart';
 import 'package:analysis_server/src/services/refactoring/refactoring.dart';
diff --git a/pkg/analysis_server/test/services/refactoring/rename_class_member_test.dart b/pkg/analysis_server/test/services/refactoring/rename_class_member_test.dart
index 24223d8..47a6c12 100644
--- a/pkg/analysis_server/test/services/refactoring/rename_class_member_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/rename_class_member_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.
 
+// @dart = 2.9
+
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:test/test.dart';
diff --git a/pkg/analysis_server/test/services/refactoring/rename_constructor_test.dart b/pkg/analysis_server/test/services/refactoring/rename_constructor_test.dart
index 50f73a3..2cb9270 100644
--- a/pkg/analysis_server/test/services/refactoring/rename_constructor_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/rename_constructor_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/refactoring/refactoring.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:test/test.dart';
diff --git a/pkg/analysis_server/test/services/refactoring/rename_extension_member_test.dart b/pkg/analysis_server/test/services/refactoring/rename_extension_member_test.dart
index 8490802..36f2bc3 100644
--- a/pkg/analysis_server/test/services/refactoring/rename_extension_member_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/rename_extension_member_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.
 
+// @dart = 2.9
+
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/services/refactoring/rename_import_test.dart b/pkg/analysis_server/test/services/refactoring/rename_import_test.dart
index b0305ee..0e90484 100644
--- a/pkg/analysis_server/test/services/refactoring/rename_import_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/rename_import_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.
 
+// @dart = 2.9
+
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/services/refactoring/rename_label_test.dart b/pkg/analysis_server/test/services/refactoring/rename_label_test.dart
index 6ca432e..98f5cb9 100644
--- a/pkg/analysis_server/test/services/refactoring/rename_label_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/rename_label_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.
 
+// @dart = 2.9
+
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/services/refactoring/rename_library_test.dart b/pkg/analysis_server/test/services/refactoring/rename_library_test.dart
index 38c315a..3b22091 100644
--- a/pkg/analysis_server/test/services/refactoring/rename_library_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/rename_library_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.
 
+// @dart = 2.9
+
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/services/refactoring/rename_local_test.dart b/pkg/analysis_server/test/services/refactoring/rename_local_test.dart
index 533456b..c620f97 100644
--- a/pkg/analysis_server/test/services/refactoring/rename_local_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/rename_local_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.
 
+// @dart = 2.9
+
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/services/refactoring/rename_unit_member_test.dart b/pkg/analysis_server/test/services/refactoring/rename_unit_member_test.dart
index c2afbdc..84b916e 100644
--- a/pkg/analysis_server/test/services/refactoring/rename_unit_member_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/rename_unit_member_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.
 
+// @dart = 2.9
+
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/services/refactoring/test_all.dart b/pkg/analysis_server/test/services/refactoring/test_all.dart
index d48e879..9dc8a8e 100644
--- a/pkg/analysis_server/test/services/refactoring/test_all.dart
+++ b/pkg/analysis_server/test/services/refactoring/test_all.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
+
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'convert_getter_to_method_test.dart' as convert_getter_to_method_test;
diff --git a/pkg/analysis_server/test/services/search/element_visitors_test.dart b/pkg/analysis_server/test/services/search/element_visitors_test.dart
index be601d3..3f2b9e4 100644
--- a/pkg/analysis_server/test/services/search/element_visitors_test.dart
+++ b/pkg/analysis_server/test/services/search/element_visitors_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/search/element_visitors.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:test/test.dart';
diff --git a/pkg/analysis_server/test/services/search/hierarchy_test.dart b/pkg/analysis_server/test/services/search/hierarchy_test.dart
index e576ae2..fc72aa4 100644
--- a/pkg/analysis_server/test/services/search/hierarchy_test.dart
+++ b/pkg/analysis_server/test/services/search/hierarchy_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/search/hierarchy.dart';
 import 'package:analysis_server/src/services/search/search_engine_internal.dart';
 import 'package:analyzer/dart/element/element.dart';
diff --git a/pkg/analysis_server/test/services/search/search_engine_test.dart b/pkg/analysis_server/test/services/search/search_engine_test.dart
index 9e59c61..593f483 100644
--- a/pkg/analysis_server/test/services/search/search_engine_test.dart
+++ b/pkg/analysis_server/test/services/search/search_engine_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/search/search_engine.dart';
 import 'package:analysis_server/src/services/search/search_engine_internal.dart';
 import 'package:analyzer/dart/analysis/results.dart';
diff --git a/pkg/analysis_server/test/services/search/test_all.dart b/pkg/analysis_server/test/services/search/test_all.dart
index c3f8f91..123f0cf 100644
--- a/pkg/analysis_server/test/services/search/test_all.dart
+++ b/pkg/analysis_server/test/services/search/test_all.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
+
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'element_visitors_test.dart' as element_visitors;
diff --git a/pkg/analysis_server/test/services/test_all.dart b/pkg/analysis_server/test/services/test_all.dart
index 954023d..85f29c1 100644
--- a/pkg/analysis_server/test/services/test_all.dart
+++ b/pkg/analysis_server/test/services/test_all.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
+
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'completion/test_all.dart' as completion_all;
diff --git a/pkg/analysis_server/test/socket_server_test.dart b/pkg/analysis_server/test/socket_server_test.dart
index d62ab2e..b7877f9 100644
--- a/pkg/analysis_server/test/socket_server_test.dart
+++ b/pkg/analysis_server/test/socket_server_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/protocol/protocol.dart';
 import 'package:analysis_server/protocol/protocol_constants.dart';
 import 'package:analysis_server/protocol/protocol_generated.dart';
diff --git a/pkg/analysis_server/test/src/cider/assists_test.dart b/pkg/analysis_server/test/src/cider/assists_test.dart
index aa1fc47..defbb80 100644
--- a/pkg/analysis_server/test/src/cider/assists_test.dart
+++ b/pkg/analysis_server/test/src/cider/assists_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/plugin/edit/assist/assist_core.dart';
 import 'package:analysis_server/src/cider/assists.dart';
 import 'package:analysis_server/src/services/correction/assist.dart';
@@ -11,6 +13,7 @@
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
+import '../utilities/mock_packages.dart';
 import 'cider_service.dart';
 
 void main() {
@@ -37,6 +40,12 @@
     expect(resultContent, expected);
   }
 
+  @override
+  void setUp() {
+    super.setUp();
+    BazelMockPackages.instance.addFlutter(resourceProvider);
+  }
+
   Future<void> test_addReturnType() async {
     await _compute(r'''
 void m() {
@@ -55,6 +64,29 @@
 ''');
   }
 
+  Future<void> test_aroundText() async {
+    await _compute('''
+import 'package:flutter/widgets.dart';
+
+main() {
+  ^Text('a');
+}
+''');
+
+    assertHasAssist(DartAssistKind.FLUTTER_WRAP_STREAM_BUILDER, r'''
+import 'package:flutter/widgets.dart';
+
+main() {
+  StreamBuilder<Object>(
+    stream: null,
+    builder: (context, snapshot) {
+      return Text('a');
+    }
+  );
+}
+''');
+  }
+
   Future<void> test_assignToLocalVariable() async {
     await _compute(r'''
 main() {
diff --git a/pkg/analysis_server/test/src/cider/cider_service.dart b/pkg/analysis_server/test/src/cider/cider_service.dart
index a1a0f10..92b637e 100644
--- a/pkg/analysis_server/test/src/cider/cider_service.dart
+++ b/pkg/analysis_server/test/src/cider/cider_service.dart
@@ -17,10 +17,10 @@
   final ByteStore byteStore = MemoryByteStore();
 
   final StringBuffer logBuffer = StringBuffer();
-  PerformanceLog logger;
-  MockSdk sdk;
+  late PerformanceLog logger;
+  late MockSdk sdk;
 
-  FileResolver fileResolver;
+  late FileResolver fileResolver;
 
   String testPath = '/workspace/dart/test/lib/test.dart';
 
@@ -31,7 +31,7 @@
     var workspace = BazelWorkspace.find(
       resourceProvider,
       convertPath(testPath),
-    );
+    )!;
 
     fileResolver = FileResolver(
       logger,
diff --git a/pkg/analysis_server/test/src/cider/completion_test.dart b/pkg/analysis_server/test/src/cider/completion_test.dart
index cc3ed2d..b64e585 100644
--- a/pkg/analysis_server/test/src/cider/completion_test.dart
+++ b/pkg/analysis_server/test/src/cider/completion_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/cider/completion.dart';
 import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/source/line_info.dart';
diff --git a/pkg/analysis_server/test/src/cider/fixes_test.dart b/pkg/analysis_server/test/src/cider/fixes_test.dart
index 8b8d691..590ae33 100644
--- a/pkg/analysis_server/test/src/cider/fixes_test.dart
+++ b/pkg/analysis_server/test/src/cider/fixes_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/plugin/edit/fix/fix_core.dart';
 import 'package:analysis_server/src/cider/fixes.dart';
 import 'package:analysis_server/src/services/correction/fix.dart';
diff --git a/pkg/analysis_server/test/src/cider/test_all.dart b/pkg/analysis_server/test/src/cider/test_all.dart
index 524383b..05483ca 100644
--- a/pkg/analysis_server/test/src/cider/test_all.dart
+++ b/pkg/analysis_server/test/src/cider/test_all.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
+
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'assists_test.dart' as assists;
diff --git a/pkg/analysis_server/test/src/computer/closing_labels_computer_test.dart b/pkg/analysis_server/test/src/computer/closing_labels_computer_test.dart
index 85369d1..c79006b 100644
--- a/pkg/analysis_server/test/src/computer/closing_labels_computer_test.dart
+++ b/pkg/analysis_server/test/src/computer/closing_labels_computer_test.dart
@@ -17,7 +17,7 @@
 
 @reflectiveTest
 class ClosingLabelsComputerTest extends AbstractContextTest {
-  String sourcePath;
+  late String sourcePath;
 
   @override
   void setUp() {
@@ -364,7 +364,7 @@
   /// Compares provided closing labels with expected
   /// labels extracted from the comments in the provided content.
   void _compareLabels(List<ClosingLabel> labels, String content,
-      {int expectedLabelCount}) {
+      {int? expectedLabelCount}) {
     // Require the test pass us the expected count to guard
     // against expected annotations being mistyped and not
     // extracted by the regex.
@@ -383,11 +383,11 @@
     expectedLabels.forEach((m) {
       var i = m.group(1);
       // Find the end marker.
-      var endMatch = RegExp('/\\*$i:(.+?)\\*/').firstMatch(content);
+      var endMatch = RegExp('/\\*$i:(.+?)\\*/').firstMatch(content)!;
 
       var expectedStart = m.end;
       var expectedLength = endMatch.start - expectedStart;
-      var expectedLabel = endMatch.group(1);
+      var expectedLabel = endMatch.group(1)!;
 
       expect(labels,
           contains(ClosingLabel(expectedStart, expectedLength, expectedLabel)));
@@ -397,7 +397,7 @@
   Future<List<ClosingLabel>> _computeElements(String sourceContent) async {
     newFile(sourcePath, content: sourceContent);
     var result = await session.getResolvedUnit(sourcePath);
-    var computer = DartUnitClosingLabelsComputer(result.lineInfo, result.unit);
+    var computer = DartUnitClosingLabelsComputer(result.lineInfo, result.unit!);
     return computer.compute();
   }
 }
diff --git a/pkg/analysis_server/test/src/computer/folding_computer_test.dart b/pkg/analysis_server/test/src/computer/folding_computer_test.dart
index 03534e7..6f1df02 100644
--- a/pkg/analysis_server/test/src/computer/folding_computer_test.dart
+++ b/pkg/analysis_server/test/src/computer/folding_computer_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/computer/computer_folding.dart';
 import 'package:analysis_server/src/protocol_server.dart';
 import 'package:test/test.dart';
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 5880e68..3b3aacb 100644
--- a/pkg/analysis_server/test/src/computer/highlights_computer_test.dart
+++ b/pkg/analysis_server/test/src/computer/highlights_computer_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/computer/computer_highlights.dart';
 import 'package:analysis_server/src/protocol_server.dart';
 import 'package:test/test.dart';
diff --git a/pkg/analysis_server/test/src/computer/import_elements_computer_test.dart b/pkg/analysis_server/test/src/computer/import_elements_computer_test.dart
index 8b0f30c..19bb89e 100644
--- a/pkg/analysis_server/test/src/computer/import_elements_computer_test.dart
+++ b/pkg/analysis_server/test/src/computer/import_elements_computer_test.dart
@@ -19,14 +19,14 @@
 
 @reflectiveTest
 class ImportElementsComputerTest extends AbstractContextTest {
-  String path;
-  String originalContent;
-  ImportElementsComputer computer;
-  SourceFileEdit sourceFileEdit;
+  late String path;
+  late String originalContent;
+  late ImportElementsComputer computer;
+  late SourceFileEdit? sourceFileEdit;
 
   void assertChanges(String expectedContent) {
     var resultCode =
-        SourceEdit.applySequence(originalContent, sourceFileEdit.edits);
+        SourceEdit.applySequence(originalContent, sourceFileEdit!.edits);
     expect(resultCode, expectedContent);
   }
 
diff --git a/pkg/analysis_server/test/src/computer/imported_elements_computer_test.dart b/pkg/analysis_server/test/src/computer/imported_elements_computer_test.dart
index 171d627..9f55abb 100644
--- a/pkg/analysis_server/test/src/computer/imported_elements_computer_test.dart
+++ b/pkg/analysis_server/test/src/computer/imported_elements_computer_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/protocol/protocol_generated.dart';
 import 'package:analysis_server/src/computer/imported_elements_computer.dart';
 import 'package:test/test.dart';
diff --git a/pkg/analysis_server/test/src/computer/outline_computer_test.dart b/pkg/analysis_server/test/src/computer/outline_computer_test.dart
index 7c3ca64..08abb6d 100644
--- a/pkg/analysis_server/test/src/computer/outline_computer_test.dart
+++ b/pkg/analysis_server/test/src/computer/outline_computer_test.dart
@@ -4,7 +4,6 @@
 
 import 'package:analysis_server/src/computer/computer_outline.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
-import 'package:meta/meta.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -19,8 +18,8 @@
 
 class AbstractOutlineComputerTest extends AbstractContextTest
     with WithNonFunctionTypeAliasesMixin {
-  String testPath;
-  String testCode;
+  late String testPath;
+  late String testCode;
 
   @override
   void setUp() {
@@ -68,10 +67,10 @@
       Text('aaa')
       Text('bbb')
 ''');
-    var myWidget = unitOutline.children[0];
-    var build = myWidget.children[0];
+    var myWidget = unitOutline.children![0];
+    var build = myWidget.children![0];
 
-    var columnOutline = build.children[0];
+    var columnOutline = build.children![0];
     {
       var offset = testCode.indexOf('new Column');
       var length = testCode.indexOf('; // Column') - offset;
@@ -83,7 +82,7 @@
     }
 
     {
-      var textOutline = columnOutline.children[0];
+      var textOutline = columnOutline.children![0];
       var text = "const Text('aaa')";
       var offset = testCode.indexOf(text);
       _expect(textOutline,
@@ -94,7 +93,7 @@
     }
 
     {
-      var textOutline = columnOutline.children[1];
+      var textOutline = columnOutline.children![1];
       var text = "const Text('bbb')";
       var offset = testCode.indexOf(text);
       _expect(textOutline,
@@ -106,13 +105,13 @@
   }
 
   void _expect(Outline outline,
-      {@required String name,
-      @required int elementOffset,
-      @required int offset,
-      @required int length}) {
+      {required String name,
+      required int elementOffset,
+      required int offset,
+      required int length}) {
     var element = outline.element;
     expect(element.name, name);
-    expect(element.location.offset, elementOffset);
+    expect(element.location!.offset, elementOffset);
     expect(outline.offset, offset);
     expect(outline.length, length);
   }
@@ -128,7 +127,7 @@
       }
     }
 
-    for (var child in outline.children) {
+    for (var child in outline.children!) {
       writeOutline(child, '');
     }
     return buffer.toString();
@@ -157,7 +156,7 @@
 String fa(int pa) => null;
 R fb<R, P>(P p) {}
 ''');
-    var topOutlines = unitOutline.children;
+    var topOutlines = unitOutline.children!;
     expect(topOutlines, hasLength(4));
     // A
     {
@@ -167,14 +166,14 @@
       expect(element_A.name, 'A');
       expect(element_A.typeParameters, '<K, V>');
       {
-        var location = element_A.location;
+        var location = element_A.location!;
         expect(location.offset, testCode.indexOf('A<K, V> {'));
         expect(location.length, 1);
       }
       expect(element_A.parameters, null);
       expect(element_A.returnType, null);
       // A children
-      var outlines_A = outline_A.children;
+      var outlines_A = outline_A.children!;
       expect(outlines_A, hasLength(11));
       {
         var outline = outlines_A[0];
@@ -206,7 +205,7 @@
         expect(element.kind, ElementKind.CONSTRUCTOR);
         expect(element.name, 'A');
         {
-          var location = element.location;
+          var location = element.location!;
           expect(location.offset, testCode.indexOf('A(int i, String s);'));
           expect(location.length, 'A'.length);
         }
@@ -221,7 +220,7 @@
         expect(element.kind, ElementKind.CONSTRUCTOR);
         expect(element.name, 'A.name');
         {
-          var location = element.location;
+          var location = element.location!;
           expect(location.offset, testCode.indexOf('name(num p);'));
           expect(location.length, 'name'.length);
         }
@@ -236,7 +235,7 @@
         expect(element.kind, ElementKind.CONSTRUCTOR);
         expect(element.name, 'A._privateName');
         {
-          var location = element.location;
+          var location = element.location!;
           expect(location.offset, testCode.indexOf('_privateName(num p);'));
           expect(location.length, '_privateName'.length);
         }
@@ -251,7 +250,7 @@
         expect(element.kind, ElementKind.METHOD);
         expect(element.name, 'ma');
         {
-          var location = element.location;
+          var location = element.location!;
           expect(location.offset, testCode.indexOf('ma(int pa) => null;'));
           expect(location.length, 'ma'.length);
         }
@@ -266,7 +265,7 @@
         expect(element.kind, ElementKind.METHOD);
         expect(element.name, '_mb');
         {
-          var location = element.location;
+          var location = element.location!;
           expect(location.offset, testCode.indexOf('_mb(int pb);'));
           expect(location.length, '_mb'.length);
         }
@@ -281,7 +280,7 @@
         expect(element.kind, ElementKind.METHOD);
         expect(element.name, 'mc');
         {
-          var location = element.location;
+          var location = element.location!;
           expect(location.offset, testCode.indexOf('mc<R, P>'));
           expect(location.length, 'mc'.length);
         }
@@ -297,7 +296,7 @@
         expect(element.kind, ElementKind.GETTER);
         expect(element.name, 'propA');
         {
-          var location = element.location;
+          var location = element.location!;
           expect(location.offset, testCode.indexOf('propA => null;'));
           expect(location.length, 'propA'.length);
         }
@@ -310,7 +309,7 @@
         expect(element.kind, ElementKind.SETTER);
         expect(element.name, 'propB');
         {
-          var location = element.location;
+          var location = element.location!;
           expect(location.offset, testCode.indexOf('propB(int v) {}'));
           expect(location.length, 'propB'.length);
         }
@@ -326,14 +325,14 @@
       expect(element_B.name, 'B');
       expect(element_B.typeParameters, isNull);
       {
-        var location = element_B.location;
+        var location = element_B.location!;
         expect(location.offset, testCode.indexOf('B {'));
         expect(location.length, 1);
       }
       expect(element_B.parameters, null);
       expect(element_B.returnType, null);
       // B children
-      var outlines_B = outline_B.children;
+      var outlines_B = outline_B.children!;
       expect(outlines_B, hasLength(1));
       {
         var outline = outlines_B[0];
@@ -341,7 +340,7 @@
         expect(element.kind, ElementKind.CONSTRUCTOR);
         expect(element.name, 'B');
         {
-          var location = element.location;
+          var location = element.location!;
           expect(location.offset, testCode.indexOf('B(int p);'));
           expect(location.length, 'B'.length);
         }
@@ -355,7 +354,7 @@
       expect(element.kind, ElementKind.FUNCTION);
       expect(element.name, 'fa');
       {
-        var location = element.location;
+        var location = element.location!;
         expect(location.offset, testCode.indexOf('fa(int pa)'));
         expect(location.length, 'ma'.length);
       }
@@ -370,7 +369,7 @@
       expect(element.kind, ElementKind.FUNCTION);
       expect(element.name, 'fb');
       {
-        var location = element.location;
+        var location = element.location!;
         expect(location.offset, testCode.indexOf('fb<R, P>'));
         expect(location.length, 'fb'.length);
       }
@@ -388,7 +387,7 @@
   A, B, C
 }
 ''');
-    var topOutlines = unitOutline.children;
+    var topOutlines = unitOutline.children!;
     expect(topOutlines, hasLength(1));
     // MyEnum
     {
@@ -397,14 +396,14 @@
       expect(element_MyEnum.kind, ElementKind.ENUM);
       expect(element_MyEnum.name, 'MyEnum');
       {
-        var location = element_MyEnum.location;
+        var location = element_MyEnum.location!;
         expect(location.offset, testCode.indexOf('MyEnum {'));
         expect(location.length, 'MyEnum'.length);
       }
       expect(element_MyEnum.parameters, null);
       expect(element_MyEnum.returnType, null);
       // MyEnum children
-      var outlines_MyEnum = outline_MyEnum.children;
+      var outlines_MyEnum = outline_MyEnum.children!;
       expect(outlines_MyEnum, hasLength(3));
       _isEnumConstant(outlines_MyEnum[0], 'A');
       _isEnumConstant(outlines_MyEnum[1], 'B');
@@ -421,7 +420,7 @@
   }
 }
 ''');
-    var topOutlines = unitOutline.children;
+    var topOutlines = unitOutline.children!;
     expect(topOutlines, hasLength(1));
     // MyExt
     {
@@ -430,7 +429,7 @@
       expect(element_MyExt.kind, ElementKind.EXTENSION);
       expect(element_MyExt.name, 'MyExt');
       {
-        var location = element_MyExt.location;
+        var location = element_MyExt.location!;
         expect(location.offset, testCode.indexOf('MyExt on'));
         expect(location.length, 'MyExt'.length);
       }
@@ -451,7 +450,7 @@
   }
 }
 ''');
-    var topOutlines = unitOutline.children;
+    var topOutlines = unitOutline.children!;
     expect(topOutlines, hasLength(1));
     // MyExt
     {
@@ -460,7 +459,7 @@
       expect(element_MyExt.kind, ElementKind.EXTENSION);
       expect(element_MyExt.name, '');
       {
-        var location = element_MyExt.location;
+        var location = element_MyExt.location!;
         expect(location.offset, testCode.indexOf('String'));
         expect(location.length, 'String'.length);
       }
@@ -476,7 +475,7 @@
     var unitOutline = await _computeOutline('''
 typedef F = void Function();
 ''');
-    var topOutlines = unitOutline.children;
+    var topOutlines = unitOutline.children!;
     expect(topOutlines, hasLength(1));
     // F
     var outline_F = topOutlines[0];
@@ -484,7 +483,7 @@
     expect(element_F.kind, ElementKind.FUNCTION_TYPE_ALIAS);
     expect(element_F.name, 'F');
     {
-      var location = element_F.location;
+      var location = element_F.location!;
       expect(location.offset, testCode.indexOf('F ='));
       expect(location.length, 'F'.length);
     }
@@ -498,7 +497,7 @@
     var unitOutline = await _computeOutline('''
 typedef F = Function();
 ''');
-    var topOutlines = unitOutline.children;
+    var topOutlines = unitOutline.children!;
     expect(topOutlines, hasLength(1));
     // F
     var outline_F = topOutlines[0];
@@ -506,7 +505,7 @@
     expect(element_F.kind, ElementKind.FUNCTION_TYPE_ALIAS);
     expect(element_F.name, 'F');
     {
-      var location = element_F.location;
+      var location = element_F.location!;
       expect(location.offset, testCode.indexOf('F ='));
       expect(location.length, 'F'.length);
     }
@@ -520,7 +519,7 @@
     var unitOutline = await _computeOutline('''
 typedef F<T> = Map<int, T>;
 ''');
-    var topOutlines = unitOutline.children;
+    var topOutlines = unitOutline.children!;
     expect(topOutlines, hasLength(1));
     // F
     var outline_F = topOutlines[0];
@@ -528,7 +527,7 @@
     expect(element_F.kind, ElementKind.TYPE_ALIAS);
     expect(element_F.name, 'F');
     {
-      var location = element_F.location;
+      var location = element_F.location!;
       expect(location.offset, testCode.indexOf('F<T> ='));
       expect(location.length, 'F'.length);
     }
@@ -559,7 +558,7 @@
 }
 ''');
     // unit
-    var unit_children = outline.children;
+    var unit_children = outline.children!;
     expect(unit_children, hasLength(3));
     // main
     var main_outline = unit_children[2];
@@ -569,7 +568,7 @@
         offset: testCode.indexOf('main() {'),
         parameters: '()',
         returnType: 'void');
-    var main_children = main_outline.children;
+    var main_children = main_outline.children!;
     expect(main_children, hasLength(2));
     // group1
     var group1_outline = main_children[0];
@@ -578,7 +577,7 @@
         length: 5,
         name: 'group("group1")',
         offset: testCode.indexOf("group('group1'"));
-    var group1_children = group1_outline.children;
+    var group1_children = group1_outline.children!;
     expect(group1_children, hasLength(2));
     // group1_1
     var group1_1_outline = group1_children[0];
@@ -587,7 +586,7 @@
         length: 5,
         name: 'group("group1_1")',
         offset: testCode.indexOf("group('group1_1'"));
-    var group1_1_children = group1_1_outline.children;
+    var group1_1_children = group1_1_outline.children!;
     expect(group1_1_children, hasLength(2));
     // test1_1_1
     var test1_1_1_outline = group1_1_children[0];
@@ -612,7 +611,7 @@
         length: 5,
         name: 'group("group1_2")',
         offset: testCode.indexOf("group('group1_2'"));
-    var group1_2_children = group1_2_outline.children;
+    var group1_2_children = group1_2_outline.children!;
     expect(group1_2_children, hasLength(1));
     // test2_1
     var test1_2_1_outline = group1_2_children[0];
@@ -629,7 +628,7 @@
         length: 5,
         name: 'group("group2")',
         offset: testCode.indexOf("group('group2'"));
-    var group2_children = group2_outline.children;
+    var group2_children = group2_outline.children!;
     expect(group2_children, hasLength(2));
     // test2_1
     var test2_1_outline = group2_children[0];
@@ -705,7 +704,7 @@
 }
 ''');
     // unit
-    var unit_children = outline.children;
+    var unit_children = outline.children!;
     expect(unit_children, hasLength(3));
     // main
     var main_outline = unit_children[2];
@@ -715,7 +714,7 @@
         offset: testCode.indexOf('main() {'),
         parameters: '()',
         returnType: 'void');
-    var main_children = main_outline.children;
+    var main_children = main_outline.children!;
     expect(main_children, hasLength(2));
     // group1
     var group1_outline = main_children[0];
@@ -724,7 +723,7 @@
         length: 7,
         name: 'myGroup("group1")',
         offset: testCode.indexOf("myGroup('group1'"));
-    var group1_children = group1_outline.children;
+    var group1_children = group1_outline.children!;
     expect(group1_children, hasLength(2));
     // group1_1
     var group1_1_outline = group1_children[0];
@@ -733,7 +732,7 @@
         length: 7,
         name: 'myGroup("group1_1")',
         offset: testCode.indexOf("myGroup('group1_1'"));
-    var group1_1_children = group1_1_outline.children;
+    var group1_1_children = group1_1_outline.children!;
     expect(group1_1_children, hasLength(2));
     // test1_1_1
     var test1_1_1_outline = group1_1_children[0];
@@ -758,7 +757,7 @@
         length: 7,
         name: 'myGroup("group1_2")',
         offset: testCode.indexOf("myGroup('group1_2'"));
-    var group1_2_children = group1_2_outline.children;
+    var group1_2_children = group1_2_outline.children!;
     expect(group1_2_children, hasLength(1));
     // test2_1
     var test1_2_1_outline = group1_2_children[0];
@@ -775,7 +774,7 @@
         length: 7,
         name: 'myGroup("group2")',
         offset: testCode.indexOf("myGroup('group2'"));
-    var group2_children = group2_outline.children;
+    var group2_children = group2_outline.children!;
     expect(group2_children, hasLength(2));
     // test2_1
     var test2_1_outline = group2_children[0];
@@ -812,7 +811,7 @@
   }
 }
 ''');
-    var topOutlines = unitOutline.children;
+    var topOutlines = unitOutline.children!;
     expect(topOutlines, hasLength(2));
     // A
     {
@@ -821,14 +820,14 @@
       expect(element_A.kind, ElementKind.CLASS);
       expect(element_A.name, 'A');
       {
-        var location = element_A.location;
+        var location = element_A.location!;
         expect(location.offset, testCode.indexOf('A {'));
         expect(location.length, 'A'.length);
       }
       expect(element_A.parameters, null);
       expect(element_A.returnType, null);
       // A children
-      var outlines_A = outline_A.children;
+      var outlines_A = outline_A.children!;
       expect(outlines_A, hasLength(2));
       {
         var constructorOutline = outlines_A[0];
@@ -836,14 +835,14 @@
         expect(constructorElement.kind, ElementKind.CONSTRUCTOR);
         expect(constructorElement.name, 'A');
         {
-          var location = constructorElement.location;
+          var location = constructorElement.location!;
           expect(location.offset, testCode.indexOf('A() {'));
           expect(location.length, 'A'.length);
         }
         expect(constructorElement.parameters, '()');
         expect(constructorElement.returnType, isNull);
         // local function
-        var outlines_constructor = constructorOutline.children;
+        var outlines_constructor = constructorOutline.children!;
         expect(outlines_constructor, hasLength(1));
         {
           var outline = outlines_constructor[0];
@@ -851,7 +850,7 @@
           expect(element.kind, ElementKind.FUNCTION);
           expect(element.name, 'local_A');
           {
-            var location = element.location;
+            var location = element.location!;
             expect(location.offset, testCode.indexOf('local_A() {}'));
             expect(location.length, 'local_A'.length);
           }
@@ -865,14 +864,14 @@
         expect(element_m.kind, ElementKind.METHOD);
         expect(element_m.name, 'm');
         {
-          var location = element_m.location;
+          var location = element_m.location!;
           expect(location.offset, testCode.indexOf('m() {'));
           expect(location.length, 'm'.length);
         }
         expect(element_m.parameters, '()');
         expect(element_m.returnType, '');
         // local function
-        var methodChildren = outline_m.children;
+        var methodChildren = outline_m.children!;
         expect(methodChildren, hasLength(1));
         {
           var outline = methodChildren[0];
@@ -880,7 +879,7 @@
           expect(element.kind, ElementKind.FUNCTION);
           expect(element.name, 'local_m');
           {
-            var location = element.location;
+            var location = element.location!;
             expect(location.offset, testCode.indexOf('local_m() {}'));
             expect(location.length, 'local_m'.length);
           }
@@ -896,14 +895,14 @@
       expect(element_f.kind, ElementKind.FUNCTION);
       expect(element_f.name, 'f');
       {
-        var location = element_f.location;
+        var location = element_f.location!;
         expect(location.offset, testCode.indexOf('f() {'));
         expect(location.length, 'f'.length);
       }
       expect(element_f.parameters, '()');
       expect(element_f.returnType, '');
       // f() children
-      var outlines_f = outline_f.children;
+      var outlines_f = outline_f.children!;
       expect(outlines_f, hasLength(2));
       {
         var outline_f1 = outlines_f[0];
@@ -911,7 +910,7 @@
         expect(element_f1.kind, ElementKind.FUNCTION);
         expect(element_f1.name, 'local_f1');
         {
-          var location = element_f1.location;
+          var location = element_f1.location!;
           expect(location.offset, testCode.indexOf('local_f1(int i) {}'));
           expect(location.length, 'local_f1'.length);
         }
@@ -924,14 +923,14 @@
         expect(element_f2.kind, ElementKind.FUNCTION);
         expect(element_f2.name, 'local_f2');
         {
-          var location = element_f2.location;
+          var location = element_f2.location!;
           expect(location.offset, testCode.indexOf('local_f2(String s) {'));
           expect(location.length, 'local_f2'.length);
         }
         expect(element_f2.parameters, '(String s)');
         expect(element_f2.returnType, '');
         // local_f2() local function
-        var outlines_f2 = outline_f2.children;
+        var outlines_f2 = outline_f2.children!;
         expect(outlines_f2, hasLength(1));
         {
           var outline_f21 = outlines_f2[0];
@@ -939,7 +938,7 @@
           expect(element_f21.kind, ElementKind.FUNCTION);
           expect(element_f21.name, 'local_f21');
           {
-            var location = element_f21.location;
+            var location = element_f21.location!;
             expect(location.offset, testCode.indexOf('local_f21(int p) {'));
             expect(location.length, 'local_f21'.length);
           }
@@ -958,7 +957,7 @@
   set f(int g) {}
 }
 ''');
-    var topOutlines = unitOutline.children;
+    var topOutlines = unitOutline.children!;
     expect(topOutlines, hasLength(1));
     // M
     {
@@ -968,14 +967,14 @@
       expect(element_M.name, 'M');
       expect(element_M.typeParameters, '<N>');
       {
-        var location = element_M.location;
+        var location = element_M.location!;
         expect(location.offset, testCode.indexOf('M<N>'));
         expect(location.length, 1);
       }
       expect(element_M.parameters, isNull);
       expect(element_M.returnType, isNull);
       // M children
-      var outlines_M = outline_M.children;
+      var outlines_M = outline_M.children!;
       expect(outlines_M, hasLength(3));
       {
         var outline = outlines_M[0];
@@ -983,7 +982,7 @@
         expect(element.kind, ElementKind.METHOD);
         expect(element.name, 'c');
         {
-          var location = element.location;
+          var location = element.location!;
           expect(location.offset, testCode.indexOf('c(int d)'));
           expect(location.length, 1);
         }
@@ -998,7 +997,7 @@
         expect(element.kind, ElementKind.GETTER);
         expect(element.name, 'e');
         {
-          var location = element.location;
+          var location = element.location!;
           expect(location.offset, testCode.indexOf('e => null'));
           expect(location.length, 1);
         }
@@ -1011,7 +1010,7 @@
         expect(element.kind, ElementKind.SETTER);
         expect(element.name, 'f');
         {
-          var location = element.location;
+          var location = element.location!;
           expect(location.offset, testCode.indexOf('f(int g)'));
           expect(location.length, 1);
         }
@@ -1032,7 +1031,7 @@
   int fieldD;
 }
 ''');
-    var outlines = unitOutline.children[0].children;
+    var outlines = unitOutline.children![0].children!;
     expect(outlines, hasLength(4));
 
     // fieldA
@@ -1099,7 +1098,7 @@
 
 class B {}
 ''');
-    var topOutlines = unitOutline.children;
+    var topOutlines = unitOutline.children!;
     expect(topOutlines, hasLength(2));
 
     // A
@@ -1141,7 +1140,7 @@
   int methodB() {}
 }
 ''');
-    var outlines = unitOutline.children[0].children;
+    var outlines = unitOutline.children![0].children!;
     expect(outlines, hasLength(2));
 
     // methodA
@@ -1187,7 +1186,7 @@
 String get propA => null;
 set propB(int v) {}
 ''');
-    var topOutlines = unitOutline.children;
+    var topOutlines = unitOutline.children!;
     expect(topOutlines, hasLength(11));
     // FTA
     {
@@ -1197,7 +1196,7 @@
       expect(element.name, 'FTA');
       expect(element.typeParameters, '<K, V>');
       {
-        var location = element.location;
+        var location = element.location!;
         expect(location.offset, testCode.indexOf('FTA<K, V>('));
         expect(location.length, 'FTA'.length);
       }
@@ -1212,7 +1211,7 @@
       expect(element.name, 'FTB');
       expect(element.typeParameters, isNull);
       {
-        var location = element.location;
+        var location = element.location!;
         expect(location.offset, testCode.indexOf('FTB('));
         expect(location.length, 'FTB'.length);
       }
@@ -1227,7 +1226,7 @@
       expect(element.name, 'GTAF');
       expect(element.typeParameters, '<T>');
       {
-        var location = element.location;
+        var location = element.location!;
         expect(location.offset, testCode.indexOf('GTAF<T> ='));
         expect(location.length, 'GTAF'.length);
       }
@@ -1242,7 +1241,7 @@
       expect(element.name, 'CTA');
       expect(element.typeParameters, '<T>');
       {
-        var location = element.location;
+        var location = element.location!;
         expect(location.offset, testCode.indexOf('CTA<T> ='));
         expect(location.length, 'CTA'.length);
       }
@@ -1265,7 +1264,7 @@
       expect(element.kind, ElementKind.FUNCTION);
       expect(element.name, 'fA');
       {
-        var location = element.location;
+        var location = element.location!;
         expect(location.offset, testCode.indexOf('fA('));
         expect(location.length, 'fA'.length);
       }
@@ -1279,7 +1278,7 @@
       expect(element.kind, ElementKind.FUNCTION);
       expect(element.name, 'fB');
       {
-        var location = element.location;
+        var location = element.location!;
         expect(location.offset, testCode.indexOf('fB('));
         expect(location.length, 'fB'.length);
       }
@@ -1293,7 +1292,7 @@
       expect(element.kind, ElementKind.GETTER);
       expect(element.name, 'propA');
       {
-        var location = element.location;
+        var location = element.location!;
         expect(location.offset, testCode.indexOf('propA => null;'));
         expect(location.length, 'propA'.length);
       }
@@ -1307,7 +1306,7 @@
       expect(element.kind, ElementKind.SETTER);
       expect(element.name, 'propB');
       {
-        var location = element.location;
+        var location = element.location!;
         expect(location.offset, testCode.indexOf('propB(int v) {}'));
         expect(location.length, 'propB'.length);
       }
@@ -1317,15 +1316,15 @@
   }
 
   void _expect(Outline outline,
-      {ElementKind kind,
+      {ElementKind? kind,
       bool leaf = false,
-      int length,
-      String name,
-      int offset,
-      String parameters,
-      String returnType}) {
+      int? length,
+      String? name,
+      int? offset,
+      String? parameters,
+      String? returnType}) {
     var element = outline.element;
-    var location = element.location;
+    var location = element.location!;
 
     if (kind != null) {
       expect(element.kind, kind);
diff --git a/pkg/analysis_server/test/src/computer/test_all.dart b/pkg/analysis_server/test/src/computer/test_all.dart
index 1a04173..a1243b2 100644
--- a/pkg/analysis_server/test/src/computer/test_all.dart
+++ b/pkg/analysis_server/test/src/computer/test_all.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
+
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'closing_labels_computer_test.dart' as closing_labels_computer;
diff --git a/pkg/analysis_server/test/src/domain_abstract_test.dart b/pkg/analysis_server/test/src/domain_abstract_test.dart
index 46c9aa6..73c72eb 100644
--- a/pkg/analysis_server/test/src/domain_abstract_test.dart
+++ b/pkg/analysis_server/test/src/domain_abstract_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/domain_abstract.dart';
 import 'package:analysis_server/src/plugin/plugin_manager.dart';
 import 'package:analysis_server/src/protocol_server.dart' hide Element;
diff --git a/pkg/analysis_server/test/src/domains/completion/available_suggestion_sets_test.dart b/pkg/analysis_server/test/src/domains/completion/available_suggestion_sets_test.dart
index 3e2a88f..32f0198 100644
--- a/pkg/analysis_server/test/src/domains/completion/available_suggestion_sets_test.dart
+++ b/pkg/analysis_server/test/src/domains/completion/available_suggestion_sets_test.dart
@@ -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
+
 import 'package:analysis_server/src/protocol_server.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -70,7 +72,9 @@
       "offset": 6,
       "length": 0,
       "startLine": 1,
-      "startColumn": 7
+      "startColumn": 7,
+      "endLine": 1,
+      "endColumn": 7
     },
     "flags": 0
   },
@@ -93,7 +97,9 @@
       "offset": 14,
       "length": 0,
       "startLine": 2,
-      "startColumn": 5
+      "startColumn": 5,
+      "endLine": 2,
+      "endColumn": 5
     },
     "flags": 0,
     "parameters": "()",
@@ -111,6 +117,80 @@
 ''');
   }
 
+  Future<void> test_suggestion_class_abstract() async {
+    var path = convertPath('/home/test/lib/a.dart');
+    var uriStr = 'package:test/a.dart';
+
+    newFile(path, content: r'''
+abstract class A {
+  A.a();
+  factory A.b() => _B();
+}
+class _B extends A {
+  _B() : super.a();
+}
+''');
+
+    var set = await waitForSetWithUri(uriStr);
+    assertNoSuggestion(set, 'A.a');
+    assertNoSuggestion(set, '_B');
+    assertJsonText(_getSuggestion(set, 'A'), '''
+{
+  "label": "A",
+  "declaringLibraryUri": "package:test/a.dart",
+  "element": {
+    "kind": "CLASS",
+    "name": "A",
+    "location": {
+      "file": ${jsonOfPath(path)},
+      "offset": 15,
+      "length": 0,
+      "startLine": 1,
+      "startColumn": 16,
+      "endLine": 1,
+      "endColumn": 16
+    },
+    "flags": 1
+  },
+  "relevanceTags": [
+    "ElementKind.CLASS",
+    "package:test/a.dart::A",
+    "A"
+  ]
+}
+''');
+    assertJsonText(_getSuggestion(set, 'A.b'), '''
+{
+  "label": "A.b",
+  "declaringLibraryUri": "package:test/a.dart",
+  "element": {
+    "kind": "CONSTRUCTOR",
+    "name": "b",
+    "location": {
+      "file": ${jsonOfPath(path)},
+      "offset": 40,
+      "length": 0,
+      "startLine": 3,
+      "startColumn": 13,
+      "endLine": 3,
+      "endColumn": 13
+    },
+    "flags": 0,
+    "parameters": "()",
+    "returnType": "A"
+  },
+  "parameterNames": [],
+  "parameterTypes": [],
+  "relevanceTags": [
+    "ElementKind.CONSTRUCTOR",
+    "package:test/a.dart::A",
+    "b"
+  ],
+  "requiredParameterCount": 0
+}
+''');
+  }
+
   Future<void> test_suggestion_class_part() async {
     var a_path = convertPath('/home/test/lib/a.dart');
     var b_path = convertPath('/home/test/lib/b.dart');
@@ -139,7 +219,9 @@
       "offset": 21,
       "length": 0,
       "startLine": 2,
-      "startColumn": 7
+      "startColumn": 7,
+      "endLine": 2,
+      "endColumn": 7
     },
     "flags": 0
   },
@@ -164,7 +246,9 @@
       "offset": 24,
       "length": 0,
       "startLine": 2,
-      "startColumn": 7
+      "startColumn": 7,
+      "endLine": 2,
+      "endColumn": 7
     },
     "flags": 0
   },
@@ -201,7 +285,9 @@
       "offset": 5,
       "length": 0,
       "startLine": 1,
-      "startColumn": 6
+      "startColumn": 6,
+      "endLine": 1,
+      "endColumn": 6
     },
     "flags": 0
   },
@@ -224,7 +310,9 @@
       "offset": 16,
       "length": 0,
       "startLine": 2,
-      "startColumn": 3
+      "startColumn": 3,
+      "endLine": 2,
+      "endColumn": 3
     },
     "flags": 0
   },
@@ -248,7 +336,9 @@
       "offset": 23,
       "length": 0,
       "startLine": 3,
-      "startColumn": 3
+      "startColumn": 3,
+      "endLine": 3,
+      "endColumn": 3
     },
     "flags": 0
   },
@@ -286,7 +376,9 @@
       "offset": 4,
       "length": 0,
       "startLine": 1,
-      "startColumn": 5
+      "startColumn": 5,
+      "endLine": 1,
+      "endColumn": 5
     },
     "flags": 0,
     "returnType": ""
@@ -310,7 +402,9 @@
       "offset": 23,
       "length": 0,
       "startLine": 2,
-      "startColumn": 5
+      "startColumn": 5,
+      "endLine": 2,
+      "endColumn": 5
     },
     "flags": 0,
     "returnType": ""
@@ -334,7 +428,9 @@
       "offset": 37,
       "length": 0,
       "startLine": 3,
-      "startColumn": 5
+      "startColumn": 5,
+      "endLine": 3,
+      "endColumn": 5
     },
     "flags": 0,
     "returnType": ""
@@ -358,7 +454,9 @@
       "offset": 56,
       "length": 0,
       "startLine": 4,
-      "startColumn": 5
+      "startColumn": 5,
+      "endLine": 4,
+      "endColumn": 5
     },
     "flags": 0,
     "returnType": ""
@@ -372,6 +470,14 @@
 ''');
   }
 
+  static void assertNoSuggestion(AvailableSuggestionSet set, String label,
+      {ElementKind kind}) {
+    var suggestion = set.items.singleWhere(
+        (s) => s.label == label && (kind == null || s.element.kind == kind),
+        orElse: () => null);
+    expect(suggestion, null);
+  }
+
   static AvailableSuggestion _getSuggestion(
       AvailableSuggestionSet set, String label,
       {ElementKind kind}) {
diff --git a/pkg/analysis_server/test/src/domains/completion/available_suggestions_base.dart b/pkg/analysis_server/test/src/domains/completion/available_suggestions_base.dart
index 1f4317b..76e3d5c 100644
--- a/pkg/analysis_server/test/src/domains/completion/available_suggestions_base.dart
+++ b/pkg/analysis_server/test/src/domains/completion/available_suggestions_base.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
+
 import 'dart:convert';
 
 import 'package:analysis_server/protocol/protocol_constants.dart';
diff --git a/pkg/analysis_server/test/src/domains/completion/get_suggestion_details_test.dart b/pkg/analysis_server/test/src/domains/completion/get_suggestion_details_test.dart
index 7876489..9b4d38a 100644
--- a/pkg/analysis_server/test/src/domains/completion/get_suggestion_details_test.dart
+++ b/pkg/analysis_server/test/src/domains/completion/get_suggestion_details_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/protocol_server.dart';
 import 'package:meta/meta.dart';
 import 'package:test/test.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 fe4524b..9ec1326 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
@@ -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
+
 import 'package:analysis_server/src/protocol_server.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/domains/completion/test_all.dart b/pkg/analysis_server/test/src/domains/completion/test_all.dart
index 1452e21..dc4bd6b 100644
--- a/pkg/analysis_server/test/src/domains/completion/test_all.dart
+++ b/pkg/analysis_server/test/src/domains/completion/test_all.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
+
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'available_suggestion_sets_test.dart' as available_suggestion_sets;
diff --git a/pkg/analysis_server/test/src/domains/execution/completion_test.dart b/pkg/analysis_server/test/src/domains/execution/completion_test.dart
index b70a9bb..92e3282 100644
--- a/pkg/analysis_server/test/src/domains/execution/completion_test.dart
+++ b/pkg/analysis_server/test/src/domains/execution/completion_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/domains/execution/completion.dart';
 import 'package:analysis_server/src/protocol_server.dart';
 import 'package:analyzer/file_system/overlay_file_system.dart';
diff --git a/pkg/analysis_server/test/src/domains/execution/test_all.dart b/pkg/analysis_server/test/src/domains/execution/test_all.dart
index 1cbd9d3..88b3d88 100644
--- a/pkg/analysis_server/test/src/domains/execution/test_all.dart
+++ b/pkg/analysis_server/test/src/domains/execution/test_all.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
+
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'completion_test.dart' as completion_test;
diff --git a/pkg/analysis_server/test/src/domains/flutter/base.dart b/pkg/analysis_server/test/src/domains/flutter/base.dart
index 2cadf8b..88d9c9d 100644
--- a/pkg/analysis_server/test/src/domains/flutter/base.dart
+++ b/pkg/analysis_server/test/src/domains/flutter/base.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
+
 import 'package:analysis_server/src/flutter/flutter_domain.dart';
 import 'package:analysis_server/src/protocol_server.dart';
 import 'package:test/test.dart';
diff --git a/pkg/analysis_server/test/src/domains/flutter/get_widget_description_test.dart b/pkg/analysis_server/test/src/domains/flutter/get_widget_description_test.dart
index 45affaa..fe6b73a 100644
--- a/pkg/analysis_server/test/src/domains/flutter/get_widget_description_test.dart
+++ b/pkg/analysis_server/test/src/domains/flutter/get_widget_description_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/protocol_server.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/domains/flutter/set_property_value_test.dart b/pkg/analysis_server/test/src/domains/flutter/set_property_value_test.dart
index 6475882..10c2eb9 100644
--- a/pkg/analysis_server/test/src/domains/flutter/set_property_value_test.dart
+++ b/pkg/analysis_server/test/src/domains/flutter/set_property_value_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/protocol_server.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/domains/flutter/test_all.dart b/pkg/analysis_server/test/src/domains/flutter/test_all.dart
index 2030531..97e2c81 100644
--- a/pkg/analysis_server/test/src/domains/flutter/test_all.dart
+++ b/pkg/analysis_server/test/src/domains/flutter/test_all.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
+
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'get_widget_description_test.dart' as get_widget_description;
diff --git a/pkg/analysis_server/test/src/domains/test_all.dart b/pkg/analysis_server/test/src/domains/test_all.dart
index dac4cfe..dc9a595 100644
--- a/pkg/analysis_server/test/src/domains/test_all.dart
+++ b/pkg/analysis_server/test/src/domains/test_all.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
+
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'completion/test_all.dart' as completion;
diff --git a/pkg/analysis_server/test/src/flutter/flutter_outline_computer_test.dart b/pkg/analysis_server/test/src/flutter/flutter_outline_computer_test.dart
index 81e43c3..da859cb 100644
--- a/pkg/analysis_server/test/src/flutter/flutter_outline_computer_test.dart
+++ b/pkg/analysis_server/test/src/flutter/flutter_outline_computer_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/flutter/flutter_outline_computer.dart';
 import 'package:analysis_server/src/protocol_server.dart';
 import 'package:analyzer/dart/analysis/results.dart';
@@ -159,6 +161,30 @@
     expect(rowOutline.attributes, isEmpty);
   }
 
+  Future<void> test_child_conditionalExpression() async {
+    var unitOutline = await _computeOutline('''
+import 'package:flutter/widgets.dart';
+
+
+class MyWidget extends StatelessWidget {
+  @override
+  Widget build(BuildContext context) {
+    return Container(
+      child: true ? Text() : Container(),
+    );
+  }
+}
+
+''');
+    expect(_toText(unitOutline), r'''
+(D) MyWidget
+  (D) build
+    Container
+      Text
+      Container
+''');
+  }
+
   Future<void> test_children() async {
     var unitOutline = await _computeOutline('''
 import 'package:flutter/widgets.dart';
@@ -276,6 +302,34 @@
 ''');
   }
 
+  Future<void> test_children_conditionalExpression() async {
+    var unitOutline = await _computeOutline('''
+import 'package:flutter/widgets.dart';
+
+
+class MyWidget extends StatelessWidget {
+  @override
+  Widget build(BuildContext context) {
+    return Column(
+      children: const [
+          true ? Text() : Container(),
+          Flex(),
+      ],
+    );
+  }
+}
+
+''');
+    expect(_toText(unitOutline), r'''
+(D) MyWidget
+  (D) build
+    Column
+      Text
+      Container
+      Flex
+''');
+  }
+
   Future<void> test_children_withCollectionElements() async {
     var unitOutline = await _computeOutline('''
 import 'package:flutter/widgets.dart';
@@ -287,7 +341,7 @@
     return new Column(children: [
       const Text('aaa'),
       if (includeB) const Text('bbb'),
-      for (int s in ['ccc', 'ddd'] const Text(s),
+      for (int s in ['ccc', 'ddd']) const Text(s),
     ]);
   }
 }
diff --git a/pkg/analysis_server/test/src/flutter/flutter_outline_notification_test.dart b/pkg/analysis_server/test/src/flutter/flutter_outline_notification_test.dart
index 67fec6f..7096a77 100644
--- a/pkg/analysis_server/test/src/flutter/flutter_outline_notification_test.dart
+++ b/pkg/analysis_server/test/src/flutter/flutter_outline_notification_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.
 
+// @dart = 2.9
+
 import 'dart:async';
 
 import 'package:analysis_server/protocol/protocol.dart';
diff --git a/pkg/analysis_server/test/src/flutter/test_all.dart b/pkg/analysis_server/test/src/flutter/test_all.dart
index 48db007..54e575a 100644
--- a/pkg/analysis_server/test/src/flutter/test_all.dart
+++ b/pkg/analysis_server/test/src/flutter/test_all.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
+
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'flutter_outline_computer_test.dart' as outline_computer;
diff --git a/pkg/analysis_server/test/src/lsp/lsp_packet_transformer_test.dart b/pkg/analysis_server/test/src/lsp/lsp_packet_transformer_test.dart
index 614fe4f..d25328e 100644
--- a/pkg/analysis_server/test/src/lsp/lsp_packet_transformer_test.dart
+++ b/pkg/analysis_server/test/src/lsp/lsp_packet_transformer_test.dart
@@ -83,7 +83,7 @@
   });
 }
 
-List<int> makeLspPacket(String json, [String contentType]) {
+List<int> makeLspPacket(String json, [String? contentType]) {
   final utf8EncodedBody = utf8.encode(json);
   final header = 'Content-Length: ${utf8EncodedBody.length}' +
       (contentType != null ? '\r\nContent-Type: $contentType' : '') +
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 3157c0c..25f5615 100644
--- a/pkg/analysis_server/test/src/plugin/notification_manager_test.dart
+++ b/pkg/analysis_server/test/src/plugin/notification_manager_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/protocol/protocol.dart' as server;
 import 'package:analysis_server/protocol/protocol_generated.dart' as server;
 import 'package:analysis_server/src/channel/channel.dart';
diff --git a/pkg/analysis_server/test/src/plugin/plugin_locator_test.dart b/pkg/analysis_server/test/src/plugin/plugin_locator_test.dart
index 4e4cbda..cf45244 100644
--- a/pkg/analysis_server/test/src/plugin/plugin_locator_test.dart
+++ b/pkg/analysis_server/test/src/plugin/plugin_locator_test.dart
@@ -15,10 +15,10 @@
 
 @reflectiveTest
 class PluginLocatorTest with ResourceProviderMixin {
-  String packageRoot;
-  String pubspecPath;
-  String defaultDirPath;
-  PluginLocator locator;
+  late String packageRoot;
+  late String pubspecPath;
+  late String defaultDirPath;
+  late PluginLocator locator;
 
   void setUp() {
     packageRoot = newFolder('/package').path;
diff --git a/pkg/analysis_server/test/src/plugin/plugin_manager_test.dart b/pkg/analysis_server/test/src/plugin/plugin_manager_test.dart
index d9bea42..ae1ba51 100644
--- a/pkg/analysis_server/test/src/plugin/plugin_manager_test.dart
+++ b/pkg/analysis_server/test/src/plugin/plugin_manager_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.
 
+// @dart = 2.9
+
 import 'dart:io' as io;
 
 import 'package:analysis_server/src/plugin/notification_manager.dart';
diff --git a/pkg/analysis_server/test/src/plugin/plugin_watcher_test.dart b/pkg/analysis_server/test/src/plugin/plugin_watcher_test.dart
index 361cd03..7906315 100644
--- a/pkg/analysis_server/test/src/plugin/plugin_watcher_test.dart
+++ b/pkg/analysis_server/test/src/plugin/plugin_watcher_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.
 
+// @dart = 2.9
+
 import 'dart:async';
 
 import 'package:analysis_server/src/plugin/plugin_locator.dart';
diff --git a/pkg/analysis_server/test/src/plugin/protocol_test_utilities.dart b/pkg/analysis_server/test/src/plugin/protocol_test_utilities.dart
index ce4d3c4..631dcac 100644
--- a/pkg/analysis_server/test/src/plugin/protocol_test_utilities.dart
+++ b/pkg/analysis_server/test/src/plugin/protocol_test_utilities.dart
@@ -64,7 +64,7 @@
 
   /// On return, increment [stringIndex] by 3 (or 4 if no [file] name is
   /// provided) and [intIndex] by 4.
-  AnalysisError analysisError(int stringIndex, int intIndex, {String file}) {
+  AnalysisError analysisError(int stringIndex, int intIndex, {String? file}) {
     return AnalysisError(
         AnalysisErrorSeverity.ERROR,
         AnalysisErrorType.COMPILE_TIME_ERROR,
@@ -76,10 +76,10 @@
   }
 
   /// On return, increment [stringIndex] by 5 and [intIndex] by 5.
-  Element element(int stringIndex, int intIndex, {ElementKind kind}) =>
+  Element element(int stringIndex, int intIndex, {ElementKind? kind}) =>
       Element(kind ?? ElementKind.CLASS, strings[stringIndex++], intIndex++,
           location: Location(fileName(stringIndex++), intIndex++, intIndex++,
-              intIndex++, intIndex++),
+              intIndex++, intIndex++, intIndex++, intIndex++),
           parameters: strings[stringIndex++],
           returnType: strings[stringIndex++],
           typeParameters: strings[stringIndex++]);
@@ -93,11 +93,13 @@
       HighlightRegion(HighlightRegionType.FIELD, offset, length);
 
   /// On return, increment [stringIndex] by 1 and [intIndex] by 4.
-  Location location(int stringIndex, int intIndex, {String file}) => Location(
+  Location location(int stringIndex, int intIndex, {String? file}) => Location(
       file ?? fileName(stringIndex),
       intIndex++,
       intIndex++,
       intIndex++,
+      intIndex++,
+      intIndex++,
       intIndex++);
 
   /// On return, increment [stringIndex] by 5 and [intIndex] by 7.
@@ -127,7 +129,7 @@
   /// On return, increment [stringIndex] by 2 (or 3 if no [file] name is
   /// provided) and [intIndex] by 4.
   plugin.AnalysisNavigationParams pluginNavigationParams(
-          int stringIndex, int intIndex, {String file}) =>
+          int stringIndex, int intIndex, {String? file}) =>
       plugin.AnalysisNavigationParams(
           file ?? fileName(stringIndex++), <NavigationRegion>[
         NavigationRegion(intIndex++, 2, <int>[0])
@@ -149,7 +151,7 @@
   /// On return, increment [stringIndex] by 2 (or 3 if no [file] name is
   /// provided) and [intIndex] by 4.
   server.AnalysisNavigationParams serverNavigationParams(
-          int stringIndex, int intIndex, {String file}) =>
+          int stringIndex, int intIndex, {String? file}) =>
       server.AnalysisNavigationParams(
           file ?? fileName(stringIndex++), <NavigationRegion>[
         NavigationRegion(intIndex++, 2, <int>[0])
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 7ba3049..7ca3d2a 100644
--- a/pkg/analysis_server/test/src/plugin/request_converter_test.dart
+++ b/pkg/analysis_server/test/src/plugin/request_converter_test.dart
@@ -60,7 +60,7 @@
   }
 
   void test_convertAnalysisUpdateContentParams() {
-    var serverFiles = <String, dynamic>{
+    var serverFiles = <String, Object>{
       'file1': AddContentOverlay('content1'),
       'file2': AddContentOverlay('content2'),
     };
diff --git a/pkg/analysis_server/test/src/plugin/result_merger_test.dart b/pkg/analysis_server/test/src/plugin/result_merger_test.dart
index bb31233..934e335 100644
--- a/pkg/analysis_server/test/src/plugin/result_merger_test.dart
+++ b/pkg/analysis_server/test/src/plugin/result_merger_test.dart
@@ -29,7 +29,7 @@
     AnalysisError createError(int offset) {
       var severity = AnalysisErrorSeverity.ERROR;
       var type = AnalysisErrorType.HINT;
-      var location = Location('test.dart', offset, 2, 3, 4);
+      var location = Location('test.dart', offset, 2, 3, 4, 5, 6);
       return AnalysisError(severity, type, location, '', '');
     }
 
@@ -68,7 +68,7 @@
     AnalysisError createError(int offset) {
       var severity = AnalysisErrorSeverity.ERROR;
       var type = AnalysisErrorType.HINT;
-      var location = Location('test.dart', offset, 2, 3, 4);
+      var location = Location('test.dart', offset, 2, 3, 4, 5, 6);
       return AnalysisError(severity, type, location, '', '');
     }
 
@@ -265,7 +265,7 @@
 
   void test_mergeOutline() {
     Element element(ElementKind kind, int offset) {
-      var location = Location('', offset, 0, 0, 0);
+      var location = Location('', offset, 0, 0, 0, 0, 0);
       return Element(kind, '', 0, location: location);
     }
 
diff --git a/pkg/analysis_server/test/src/plugin/test_all.dart b/pkg/analysis_server/test/src/plugin/test_all.dart
index 9240a5d..70d0fd0 100644
--- a/pkg/analysis_server/test/src/plugin/test_all.dart
+++ b/pkg/analysis_server/test/src/plugin/test_all.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
+
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'notification_manager_test.dart' as notification_manager_test;
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 b007d66..450ace8 100644
--- a/pkg/analysis_server/test/src/server/sdk_configuration_test.dart
+++ b/pkg/analysis_server/test/src/server/sdk_configuration_test.dart
@@ -10,7 +10,11 @@
 
 void main() {
   group('SdkConfiguration', () {
-    Directory tempDir;
+    Directory? tempDir;
+
+    Directory createTempDir() {
+      return tempDir = Directory.systemTemp.createTempSync('SdkConfiguration');
+    }
 
     tearDown(() {
       tempDir?.deleteSync(recursive: true);
@@ -21,8 +25,8 @@
     });
 
     test("custom settings file doesn't exist", () {
-      tempDir = Directory.systemTemp.createTempSync('SdkConfiguration');
-      var file = File(path.join(tempDir.path, 'config.json'));
+      var dir = createTempDir();
+      var file = File(path.join(dir.path, 'config.json'));
 
       expect(() {
         SdkConfiguration.readFromFile(file);
@@ -30,8 +34,8 @@
     });
 
     test('is not configured', () {
-      tempDir = Directory.systemTemp.createTempSync('SdkConfiguration');
-      var file = File(path.join(tempDir.path, 'config.json'));
+      var dir = createTempDir();
+      var file = File(path.join(dir.path, 'config.json'));
       file.writeAsStringSync('''
 {}
 ''');
@@ -46,8 +50,8 @@
     });
 
     test('is configured', () {
-      tempDir = Directory.systemTemp.createTempSync('SdkConfiguration');
-      var file = File(path.join(tempDir.path, 'config.json'));
+      var dir = createTempDir();
+      var file = File(path.join(dir.path, 'config.json'));
       file.writeAsStringSync('''
 {
   "server.analytics.id": "aaaa-1234",
diff --git a/pkg/analysis_server/test/src/services/completion/dart/completion_test.dart b/pkg/analysis_server/test/src/services/completion/dart/completion_test.dart
new file mode 100644
index 0000000..c9c355e
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/completion/dart/completion_test.dart
@@ -0,0 +1,68 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for 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 'package:analysis_server/src/protocol_server.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../../../../completion_test_support.dart';
+
+void main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(ConstructorCompletionTest);
+    defineReflectiveTests(PropertyAccessorCompletionTest);
+  });
+}
+
+@reflectiveTest
+class ConstructorCompletionTest extends CompletionTestCase {
+  Future<void> test_constructor_abstract() async {
+    addTestFile('''
+void f() {
+  g(^);
+}
+void g(C c) {}
+abstract class C {
+  C.c();
+}
+''');
+    await getSuggestions();
+    assertHasNoCompletion('C.c');
+  }
+}
+
+@reflectiveTest
+class PropertyAccessorCompletionTest extends CompletionTestCase {
+  Future<void> test_setter_deprecated() async {
+    addTestFile('''
+void f(C c) {
+  c.^;
+}
+class C {
+  @deprecated
+  set x(int x) {}
+}
+''');
+    await getSuggestions();
+    assertHasCompletion('x',
+        elementKind: ElementKind.SETTER, isDeprecated: true);
+  }
+
+  Future<void> test_setter_deprecated_withNonDeprecatedGetter() async {
+    addTestFile('''
+void f(C c) {
+  c.^;
+}
+class C {
+  int get x => 0;
+  @deprecated
+  set x(int x) {}
+}
+''');
+    await getSuggestions();
+    assertHasCompletion('x',
+        elementKind: ElementKind.GETTER, isDeprecated: false);
+  }
+}
diff --git a/pkg/analysis_server/test/src/services/completion/dart/feature_computer_test.dart b/pkg/analysis_server/test/src/services/completion/dart/feature_computer_test.dart
index d6746b3..4dbb904 100644
--- a/pkg/analysis_server/test/src/services/completion/dart/feature_computer_test.dart
+++ b/pkg/analysis_server/test/src/services/completion/dart/feature_computer_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/completion/dart/feature_computer.dart';
 import 'package:analyzer_plugin/src/utilities/completion/completion_target.dart';
 import 'package:test/test.dart';
@@ -31,6 +33,17 @@
     }
   }
 
+  Future<void> test_argumentList_instanceCreation() async {
+    await assertContextType('''
+class C {
+  C({String s}) {}
+}
+void f() {
+  C(s:^);
+}
+''', 'String');
+  }
+
   Future<void> test_argumentList_named_afterColon() async {
     await assertContextType('''
 void f({int i, String s, bool b}) {}
@@ -87,6 +100,17 @@
 ''', 'int');
   }
 
+  Future<void> test_argumentList_named_method() async {
+    await assertContextType('''
+class C {
+  void m(int i) {}
+}
+void f(C c) {
+  c.m(^);
+}
+''', 'int');
+  }
+
   Future<void> test_argumentList_named_unresolved_hasNamedParameters() async {
     await assertContextType('''
 void f({int i}) {}
@@ -335,6 +359,31 @@
 ''', 'String');
   }
 
+  Future<void> test_argumentList_typeParameter_resolved() async {
+    await assertContextType('''
+class A {}
+class B {}
+class C<T extends A> {
+  void m(T t) {}
+}
+void f(C<B> c) {
+  c.m(^);
+}
+''', 'B');
+  }
+
+  Future<void> test_argumentList_typeParameter_unresolved() async {
+    await assertContextType('''
+class A {}
+class C<T extends A> {
+  void m1(T t) {}
+  void m2() {
+    m1(^);
+  }
+}
+''', 'A');
+  }
+
   Future<void> test_assertInitializer_with_identifier() async {
     await assertContextType('''
 class C {
diff --git a/pkg/analysis_server/test/src/services/completion/dart/test_all.dart b/pkg/analysis_server/test/src/services/completion/dart/test_all.dart
index 95e24ee..06a051a 100644
--- a/pkg/analysis_server/test/src/services/completion/dart/test_all.dart
+++ b/pkg/analysis_server/test/src/services/completion/dart/test_all.dart
@@ -2,12 +2,16 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+// @dart = 2.9
+
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
+import 'completion_test.dart' as completion;
 import 'feature_computer_test.dart' as feature_computer;
 
 void main() {
   defineReflectiveSuite(() {
+    completion.main();
     feature_computer.main();
   }, name: 'dart');
 }
diff --git a/pkg/analysis_server/test/src/services/completion/filtering/fuzzy_matcher_test.dart b/pkg/analysis_server/test/src/services/completion/filtering/fuzzy_matcher_test.dart
index 3bc5d7a..e1cda4a 100644
--- a/pkg/analysis_server/test/src/services/completion/filtering/fuzzy_matcher_test.dart
+++ b/pkg/analysis_server/test/src/services/completion/filtering/fuzzy_matcher_test.dart
@@ -3,7 +3,6 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analysis_server/src/services/completion/filtering/fuzzy_matcher.dart';
-import 'package:meta/meta.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -42,8 +41,8 @@
   static MatchStyle SYM = MatchStyle.SYMBOL;
 
   void map(
-      {@required String str,
-      @required String want,
+      {required String str,
+      required String want,
       MatchStyle matchStyle = MatchStyle.TEXT}) {
 //    test('maps characters of $str', () {
     var out = List<CharRole>.filled(str.length, CharRole.NONE);
@@ -199,9 +198,9 @@
   static MatchStyle SYM = MatchStyle.SYMBOL;
 
   void score(
-      {@required String p,
-      @required String str,
-      String want,
+      {required String p,
+      required String str,
+      String? want,
       MatchStyle input = MatchStyle.TEXT}) {
 //    test('scores $str against $p', () {
     var matcher = FuzzyMatcher(p, matchStyle: input);
@@ -306,7 +305,7 @@
 @reflectiveTest
 class ScoringFunctionTest {
   ///
-  void score({@required String p, @required String str, double want}) {
+  void score({required String p, required String str, required double want}) {
 //    test('scores $str against $p', () {
     var matcher = FuzzyMatcher(p, matchStyle: MatchStyle.SYMBOL);
     expect(
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 19d31b3..75303aa 100644
--- a/pkg/analysis_server/test/src/services/completion/test_all.dart
+++ b/pkg/analysis_server/test/src/services/completion/test_all.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
+
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'dart/test_all.dart' as dart;
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
index c86dc28..c9e33de 100644
--- 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
@@ -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
+
 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';
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
index 4634360..3ded781 100644
--- 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
@@ -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
+
 import 'package:analysis_server/src/services/completion/yaml/fix_data_generator.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
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
index acfead8..07d2bb7 100644
--- 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
@@ -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
+
 import 'package:analysis_server/src/services/completion/yaml/pubspec_generator.dart';
 import 'package:analysis_server/src/services/pub/pub_api.dart';
 import 'package:analysis_server/src/services/pub/pub_package_service.dart';
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
index 0d82611..e793c59 100644
--- a/pkg/analysis_server/test/src/services/completion/yaml/test_all.dart
+++ b/pkg/analysis_server/test/src/services/completion/yaml/test_all.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
+
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'analysis_options_generator_test.dart' as analysis_options_generator;
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
index 3baebe1..254a855 100644
--- 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
@@ -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
+
 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';
diff --git a/pkg/analysis_server/test/src/services/correction/assist/add_diagnostic_property_reference_test.dart b/pkg/analysis_server/test/src/services/correction/assist/add_diagnostic_property_reference_test.dart
index f9b684c..6a79a03 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/add_diagnostic_property_reference_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/add_diagnostic_property_reference_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/assist/add_not_null_assert_test.dart b/pkg/analysis_server/test/src/services/correction/assist/add_not_null_assert_test.dart
index d100c48..ac70f98 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/add_not_null_assert_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/add_not_null_assert_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/assist/add_return_type_test.dart b/pkg/analysis_server/test/src/services/correction/assist/add_return_type_test.dart
index c288dd0..3224af1 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/add_return_type_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/add_return_type_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/assist/add_type_annotation_test.dart b/pkg/analysis_server/test/src/services/correction/assist/add_type_annotation_test.dart
index 06724fb..e897474 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/add_type_annotation_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/add_type_annotation_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/assist/assign_to_local_variable_test.dart b/pkg/analysis_server/test/src/services/correction/assist/assign_to_local_variable_test.dart
index 3fa857a..9630000 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/assign_to_local_variable_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/assign_to_local_variable_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
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 1435f6c..ae5b9a6 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
@@ -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
+
 import 'package:analysis_server/plugin/edit/assist/assist_core.dart';
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/correction/assist_internal.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/assist/convert_class_to_mixin_test.dart b/pkg/analysis_server/test/src/services/correction/assist/convert_class_to_mixin_test.dart
index 9ccf27d..20b116b 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/convert_class_to_mixin_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/convert_class_to_mixin_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/assist/convert_documentation_into_block_test.dart b/pkg/analysis_server/test/src/services/correction/assist/convert_documentation_into_block_test.dart
index 9fe4f87..b7b2a62 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/convert_documentation_into_block_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/convert_documentation_into_block_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/assist/convert_documentation_into_line_test.dart b/pkg/analysis_server/test/src/services/correction/assist/convert_documentation_into_line_test.dart
index 92a8449..660e128 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/convert_documentation_into_line_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/convert_documentation_into_line_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/assist/convert_into_async_body_test.dart b/pkg/analysis_server/test/src/services/correction/assist/convert_into_async_body_test.dart
index 0120636..353acef 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/convert_into_async_body_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/convert_into_async_body_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/assist/convert_into_block_body_test.dart b/pkg/analysis_server/test/src/services/correction/assist/convert_into_block_body_test.dart
index db04588..869228d 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/convert_into_block_body_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/convert_into_block_body_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/assist/convert_into_expression_body_test.dart b/pkg/analysis_server/test/src/services/correction/assist/convert_into_expression_body_test.dart
index 6e8152d..612ddfb 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/convert_into_expression_body_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/convert_into_expression_body_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/assist/convert_into_final_field_test.dart b/pkg/analysis_server/test/src/services/correction/assist/convert_into_final_field_test.dart
index 345eda1..5e2aaba 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/convert_into_final_field_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/convert_into_final_field_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/assist/convert_into_for_index_test.dart b/pkg/analysis_server/test/src/services/correction/assist/convert_into_for_index_test.dart
index d6aca70..6fc9393 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/convert_into_for_index_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/convert_into_for_index_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/assist/convert_into_generic_function_syntax_test.dart b/pkg/analysis_server/test/src/services/correction/assist/convert_into_generic_function_syntax_test.dart
index cb80726..90c02e0 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/convert_into_generic_function_syntax_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/convert_into_generic_function_syntax_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/assist/convert_into_getter_test.dart b/pkg/analysis_server/test/src/services/correction/assist/convert_into_getter_test.dart
index ffc7664..d806251 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/convert_into_getter_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/convert_into_getter_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/assist/convert_into_is_not_empty_test.dart b/pkg/analysis_server/test/src/services/correction/assist/convert_into_is_not_empty_test.dart
index ce777b0..c34ba7e 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/convert_into_is_not_empty_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/convert_into_is_not_empty_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/assist/convert_into_is_not_test.dart b/pkg/analysis_server/test/src/services/correction/assist/convert_into_is_not_test.dart
index 5a68942..e66f540 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/convert_into_is_not_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/convert_into_is_not_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/assist/convert_part_of_to_uri_test.dart b/pkg/analysis_server/test/src/services/correction/assist/convert_part_of_to_uri_test.dart
index 4f99ef9..e9f455e 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/convert_part_of_to_uri_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/convert_part_of_to_uri_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/assist/convert_to_double_quoted_string_test.dart b/pkg/analysis_server/test/src/services/correction/assist/convert_to_double_quoted_string_test.dart
index 813e4bc..16bd7b3 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/convert_to_double_quoted_string_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/convert_to_double_quoted_string_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/assist/convert_to_field_parameter_test.dart b/pkg/analysis_server/test/src/services/correction/assist/convert_to_field_parameter_test.dart
index f616eab..acb1577 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/convert_to_field_parameter_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/convert_to_field_parameter_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/assist/convert_to_for_element_test.dart b/pkg/analysis_server/test/src/services/correction/assist/convert_to_for_element_test.dart
index 80cd6c1..e9b0024 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/convert_to_for_element_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/convert_to_for_element_test.dart
@@ -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
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/assist/convert_to_if_element_test.dart b/pkg/analysis_server/test/src/services/correction/assist/convert_to_if_element_test.dart
index b277e60..274f6d4 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/convert_to_if_element_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/convert_to_if_element_test.dart
@@ -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
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/assist/convert_to_int_literal_test.dart b/pkg/analysis_server/test/src/services/correction/assist/convert_to_int_literal_test.dart
index 919ab32..7ebfdae 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/convert_to_int_literal_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/convert_to_int_literal_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/assist/convert_to_list_literal_test.dart b/pkg/analysis_server/test/src/services/correction/assist/convert_to_list_literal_test.dart
index 880a6f1..68a565d 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/convert_to_list_literal_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/convert_to_list_literal_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/assist/convert_to_map_literal_test.dart b/pkg/analysis_server/test/src/services/correction/assist/convert_to_map_literal_test.dart
index 9b6b24b..f2d4e19 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/convert_to_map_literal_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/convert_to_map_literal_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/assist/convert_to_multiline_string_test.dart b/pkg/analysis_server/test/src/services/correction/assist/convert_to_multiline_string_test.dart
index 1e52915..1f3291a 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/convert_to_multiline_string_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/convert_to_multiline_string_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/assist/convert_to_normal_parameter_test.dart b/pkg/analysis_server/test/src/services/correction/assist/convert_to_normal_parameter_test.dart
index 90973a6..c26c19b 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/convert_to_normal_parameter_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/convert_to_normal_parameter_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
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 7d6b659..67d578c 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
@@ -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
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/assist/convert_to_package_import_test.dart b/pkg/analysis_server/test/src/services/correction/assist/convert_to_package_import_test.dart
index 1fe3d84..417fdcc 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/convert_to_package_import_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/convert_to_package_import_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/assist/convert_to_set_literal_test.dart b/pkg/analysis_server/test/src/services/correction/assist/convert_to_set_literal_test.dart
index 76079f7..20eeb8c 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/convert_to_set_literal_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/convert_to_set_literal_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/assist/convert_to_single_quoted_string_test.dart b/pkg/analysis_server/test/src/services/correction/assist/convert_to_single_quoted_string_test.dart
index 4214de8..8515b73 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/convert_to_single_quoted_string_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/convert_to_single_quoted_string_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/assist/convert_to_spread_test.dart b/pkg/analysis_server/test/src/services/correction/assist/convert_to_spread_test.dart
index dc43575..22cf5e0 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/convert_to_spread_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/convert_to_spread_test.dart
@@ -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
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
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 5817ae2..f359ea9 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
@@ -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
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/assist/exchange_operands_test.dart b/pkg/analysis_server/test/src/services/correction/assist/exchange_operands_test.dart
index c5921f3..5ea4c1f 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/exchange_operands_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/exchange_operands_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/assist/flutter_convert_to_children_test.dart b/pkg/analysis_server/test/src/services/correction/assist/flutter_convert_to_children_test.dart
index 1bac364..6241079 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/flutter_convert_to_children_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/flutter_convert_to_children_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/assist/flutter_convert_to_stateful_widget_test.dart b/pkg/analysis_server/test/src/services/correction/assist/flutter_convert_to_stateful_widget_test.dart
index 426fa2b..16088e8 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/flutter_convert_to_stateful_widget_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/flutter_convert_to_stateful_widget_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/assist/flutter_move_down_test.dart b/pkg/analysis_server/test/src/services/correction/assist/flutter_move_down_test.dart
index 3ed98b5..ecab131 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/flutter_move_down_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/flutter_move_down_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/assist/flutter_move_up_test.dart b/pkg/analysis_server/test/src/services/correction/assist/flutter_move_up_test.dart
index 905d316..e713017 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/flutter_move_up_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/flutter_move_up_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/assist/flutter_remove_widget_test.dart b/pkg/analysis_server/test/src/services/correction/assist/flutter_remove_widget_test.dart
index f6ed88f..0cd56e9 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/flutter_remove_widget_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/flutter_remove_widget_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/assist/flutter_surround_with_set_state_test.dart b/pkg/analysis_server/test/src/services/correction/assist/flutter_surround_with_set_state_test.dart
index d13bb22..7462d46 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/flutter_surround_with_set_state_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/flutter_surround_with_set_state_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/assist/flutter_swap_with_child_test.dart b/pkg/analysis_server/test/src/services/correction/assist/flutter_swap_with_child_test.dart
index babc107..2cd225e 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/flutter_swap_with_child_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/flutter_swap_with_child_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/assist/flutter_swap_with_parent_test.dart b/pkg/analysis_server/test/src/services/correction/assist/flutter_swap_with_parent_test.dart
index 197470b..e9e36b5 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/flutter_swap_with_parent_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/flutter_swap_with_parent_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_center_test.dart b/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_center_test.dart
index 877ffb7..d34de66 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_center_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_center_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_column_test.dart b/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_column_test.dart
index fc79cb7..4b960dd 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_column_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_column_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_container_test.dart b/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_container_test.dart
index 04702fa..62aca16 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_container_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_container_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_generic_test.dart b/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_generic_test.dart
index e8df73f..5bc12d6 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_generic_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_generic_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_padding_test.dart b/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_padding_test.dart
index 685b2df..6e4e119 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_padding_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_padding_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_row_test.dart b/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_row_test.dart
index a9e6554..fd16ea4 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_row_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_row_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_sized_box_test.dart b/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_sized_box_test.dart
index 74c6918..8f7b42b 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_sized_box_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_sized_box_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_stream_builder_test.dart b/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_stream_builder_test.dart
index 4c32342..abb6e96 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_stream_builder_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_stream_builder_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/assist/import_add_show_test.dart b/pkg/analysis_server/test/src/services/correction/assist/import_add_show_test.dart
index e00ee78..66bf905 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/import_add_show_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/import_add_show_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/assist/inline_invocation_test.dart b/pkg/analysis_server/test/src/services/correction/assist/inline_invocation_test.dart
index 23749ff..41352e8 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/inline_invocation_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/inline_invocation_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/assist/introduce_local_cast_type_test.dart b/pkg/analysis_server/test/src/services/correction/assist/introduce_local_cast_type_test.dart
index 784efb9..29f7c3e 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/introduce_local_cast_type_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/introduce_local_cast_type_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/assist/invert_if_statement_test.dart b/pkg/analysis_server/test/src/services/correction/assist/invert_if_statement_test.dart
index b86a190..503faef 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/invert_if_statement_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/invert_if_statement_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/assist/join_if_with_inner_test.dart b/pkg/analysis_server/test/src/services/correction/assist/join_if_with_inner_test.dart
index 3c19528..c4e4a9a 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/join_if_with_inner_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/join_if_with_inner_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/assist/join_if_with_outer_test.dart b/pkg/analysis_server/test/src/services/correction/assist/join_if_with_outer_test.dart
index a31c29e..56a6a4a 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/join_if_with_outer_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/join_if_with_outer_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/assist/join_variable_declaration_test.dart b/pkg/analysis_server/test/src/services/correction/assist/join_variable_declaration_test.dart
index 8b885c8..f22173d 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/join_variable_declaration_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/join_variable_declaration_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/assist/remove_type_annotation_test.dart b/pkg/analysis_server/test/src/services/correction/assist/remove_type_annotation_test.dart
index a1efc00..62bfeca 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/remove_type_annotation_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/remove_type_annotation_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/assist/replace_conditional_with_if_else_test.dart b/pkg/analysis_server/test/src/services/correction/assist/replace_conditional_with_if_else_test.dart
index e5f1923..7be0adc 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/replace_conditional_with_if_else_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/replace_conditional_with_if_else_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/assist/replace_if_else_with_conditional_test.dart b/pkg/analysis_server/test/src/services/correction/assist/replace_if_else_with_conditional_test.dart
index 7641070..cbbf880 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/replace_if_else_with_conditional_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/replace_if_else_with_conditional_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/assist/replace_with_var_test.dart b/pkg/analysis_server/test/src/services/correction/assist/replace_with_var_test.dart
index 6ab4ad8..d0ab5ce 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/replace_with_var_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/replace_with_var_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/assist/shadow_field_test.dart b/pkg/analysis_server/test/src/services/correction/assist/shadow_field_test.dart
index f13b966..ba8a0e3 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/shadow_field_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/shadow_field_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/assist/sort_child_property_last_test.dart b/pkg/analysis_server/test/src/services/correction/assist/sort_child_property_last_test.dart
index 2aea7cc..96c39a9 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/sort_child_property_last_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/sort_child_property_last_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
@@ -73,11 +75,12 @@
     await assertNoAssist();
   }
 
-  Future<void> test_sort() async {
+  Future<void> test_sort_middleArgument() async {
     await resolveTestCode('''
 import 'package:flutter/material.dart';
 main() {
   Column(
+    mainAxisAlignment: MainAxisAlignment.start,
     /*caret*/children: <Widget>[
       Text('aaa'),
       Text('bbbbbb'),
@@ -91,6 +94,7 @@
 import 'package:flutter/material.dart';
 main() {
   Column(
+    mainAxisAlignment: MainAxisAlignment.start,
     crossAxisAlignment: CrossAxisAlignment.center,
     children: <Widget>[
       Text('aaa'),
@@ -121,4 +125,64 @@
 ''');
     await assertNoAssist();
   }
+
+  Future<void> test_sort_noTrailingComma() async {
+    await resolveTestCode('''
+import 'package:flutter/material.dart';
+main() {
+  Column(
+    /*caret*/children: <Widget>[
+      Text('aaa'),
+      Text('bbbbbb'),
+      Text('ccccccccc'),
+    ],
+    crossAxisAlignment: CrossAxisAlignment.center
+  );
+}
+''');
+    await assertHasAssist('''
+import 'package:flutter/material.dart';
+main() {
+  Column(
+    crossAxisAlignment: CrossAxisAlignment.center,
+    children: <Widget>[
+      Text('aaa'),
+      Text('bbbbbb'),
+      Text('ccccccccc'),
+    ]
+  );
+}
+''');
+    assertExitPosition(after: ']');
+  }
+
+  Future<void> test_sort_trailingComma() async {
+    await resolveTestCode('''
+import 'package:flutter/material.dart';
+main() {
+  Column(
+    /*caret*/children: <Widget>[
+      Text('aaa'),
+      Text('bbbbbb'),
+      Text('ccccccccc'),
+    ],
+    crossAxisAlignment: CrossAxisAlignment.center,
+  );
+}
+''');
+    await assertHasAssist('''
+import 'package:flutter/material.dart';
+main() {
+  Column(
+    crossAxisAlignment: CrossAxisAlignment.center,
+    children: <Widget>[
+      Text('aaa'),
+      Text('bbbbbb'),
+      Text('ccccccccc'),
+    ],
+  );
+}
+''');
+    assertExitPosition(after: '],');
+  }
 }
diff --git a/pkg/analysis_server/test/src/services/correction/assist/split_and_condition_test.dart b/pkg/analysis_server/test/src/services/correction/assist/split_and_condition_test.dart
index 2e96ea7..5845e92 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/split_and_condition_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/split_and_condition_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/assist/split_variable_declaration_test.dart b/pkg/analysis_server/test/src/services/correction/assist/split_variable_declaration_test.dart
index 255f6e5..c9e5eb4 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/split_variable_declaration_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/split_variable_declaration_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/assist/surround_with_block_test.dart b/pkg/analysis_server/test/src/services/correction/assist/surround_with_block_test.dart
index 54ef449..085fec0 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/surround_with_block_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/surround_with_block_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/assist/surround_with_do_while_test.dart b/pkg/analysis_server/test/src/services/correction/assist/surround_with_do_while_test.dart
index d6ad18f..ff7ca9c 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/surround_with_do_while_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/surround_with_do_while_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/assist/surround_with_for_in_test.dart b/pkg/analysis_server/test/src/services/correction/assist/surround_with_for_in_test.dart
index 6b7ca74..ecd4297 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/surround_with_for_in_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/surround_with_for_in_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/assist/surround_with_for_test.dart b/pkg/analysis_server/test/src/services/correction/assist/surround_with_for_test.dart
index ca39826..3ae3580 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/surround_with_for_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/surround_with_for_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/assist/surround_with_if_test.dart b/pkg/analysis_server/test/src/services/correction/assist/surround_with_if_test.dart
index 91ed08c..6b77b2c 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/surround_with_if_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/surround_with_if_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/assist/surround_with_try_catch_test.dart b/pkg/analysis_server/test/src/services/correction/assist/surround_with_try_catch_test.dart
index 3fa1377..823ec7a 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/surround_with_try_catch_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/surround_with_try_catch_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/assist/surround_with_try_finally_test.dart b/pkg/analysis_server/test/src/services/correction/assist/surround_with_try_finally_test.dart
index e6d5010..81a75c4 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/surround_with_try_finally_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/surround_with_try_finally_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/assist/surround_with_while_test.dart b/pkg/analysis_server/test/src/services/correction/assist/surround_with_while_test.dart
index 24eb591..c989ffd 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/surround_with_while_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/surround_with_while_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/assist/test_all.dart b/pkg/analysis_server/test/src/services/correction/assist/test_all.dart
index 9a0192e..fef565f5 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/test_all.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/test_all.dart
@@ -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
+
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'add_diagnostic_property_reference_test.dart' as add_diagnostic_property;
diff --git a/pkg/analysis_server/test/src/services/correction/assist/use_curly_braces_test.dart b/pkg/analysis_server/test/src/services/correction/assist/use_curly_braces_test.dart
index 93d28d6..df54292 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/use_curly_braces_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/use_curly_braces_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
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 bb382ff..dad6767 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
@@ -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
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer/src/error/codes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/add_await_test.dart b/pkg/analysis_server/test/src/services/correction/fix/add_await_test.dart
index 31ce0c6..45dbde2 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/add_await_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/add_await_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/add_const_test.dart b/pkg/analysis_server/test/src/services/correction/fix/add_const_test.dart
index bcb2893..c38b96f 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/add_const_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/add_const_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/add_curly_braces_test.dart b/pkg/analysis_server/test/src/services/correction/fix/add_curly_braces_test.dart
index 18da15e..8bf57b5 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/add_curly_braces_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/add_curly_braces_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/add_diagnostic_property_reference_test.dart b/pkg/analysis_server/test/src/services/correction/fix/add_diagnostic_property_reference_test.dart
index 7df0970..671d48f 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/add_diagnostic_property_reference_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/add_diagnostic_property_reference_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer/src/error/codes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/add_explicit_cast_test.dart b/pkg/analysis_server/test/src/services/correction/fix/add_explicit_cast_test.dart
index 797f097..e15b3c6 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/add_explicit_cast_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/add_explicit_cast_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/add_field_formal_parameters_test.dart b/pkg/analysis_server/test/src/services/correction/fix/add_field_formal_parameters_test.dart
index b8dbde7..6c53168 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/add_field_formal_parameters_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/add_field_formal_parameters_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/add_late_test.dart b/pkg/analysis_server/test/src/services/correction/fix/add_late_test.dart
index 039dd8d..4600c2d 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/add_late_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/add_late_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/add_missing_enum_case_clauses_test.dart b/pkg/analysis_server/test/src/services/correction/fix/add_missing_enum_case_clauses_test.dart
index f23da1c..7bdcdb5 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/add_missing_enum_case_clauses_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/add_missing_enum_case_clauses_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer/error/error.dart';
 import 'package:analyzer/src/error/codes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/add_missing_parameter_named_test.dart b/pkg/analysis_server/test/src/services/correction/fix/add_missing_parameter_named_test.dart
index d1572d6..b870f80 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/add_missing_parameter_named_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/add_missing_parameter_named_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/add_missing_parameter_positional_test.dart b/pkg/analysis_server/test/src/services/correction/fix/add_missing_parameter_positional_test.dart
index 532f7a1..9176d52 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/add_missing_parameter_positional_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/add_missing_parameter_positional_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/add_missing_parameter_required_test.dart b/pkg/analysis_server/test/src/services/correction/fix/add_missing_parameter_required_test.dart
index b073812..7649cf2 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/add_missing_parameter_required_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/add_missing_parameter_required_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/change_workspace.dart';
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer_plugin/utilities/change_builder/change_workspace.dart';
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 593c68c..d0c172f 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
@@ -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
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/add_ne_null_test.dart b/pkg/analysis_server/test/src/services/correction/fix/add_ne_null_test.dart
index fe07091..38912fd 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/add_ne_null_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/add_ne_null_test.dart
@@ -2,11 +2,14 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
+import '../../../../abstract_context.dart';
 import 'fix_processor.dart';
 
 void main() {
@@ -17,13 +20,11 @@
 }
 
 @reflectiveTest
-class AddNeNullMultiTest extends FixProcessorTest {
+class AddNeNullMultiTest extends FixProcessorTest with WithNullSafetyMixin {
   @override
   FixKind get kind => DartFixKind.ADD_NE_NULL_MULTI;
 
-  // todo (pq): add null-safe aware tests
-  // see: https://dart-review.googlesource.com/c/sdk/+/188681
-  Future<void> test_nonBoolCondition_all() async {
+  Future<void> test_nonBoolCondition_all_nonNullable() async {
     await resolveTestCode('''
 f(String p, String q) {
   if (p) {
@@ -34,8 +35,22 @@
   }
 }
 ''');
+    await assertNoFixAllFix(CompileTimeErrorCode.NON_BOOL_CONDITION);
+  }
+
+  Future<void> test_nonBoolCondition_all_nullable() async {
+    await resolveTestCode('''
+f(String? p, String? q) {
+  if (p) {
+    print(p);
+  }
+  if (q) {
+    print(q);
+  }
+}
+''');
     await assertHasFixAllFix(CompileTimeErrorCode.NON_BOOL_CONDITION, '''
-f(String p, String q) {
+f(String? p, String? q) {
   if (p != null) {
     print(p);
   }
@@ -48,11 +63,11 @@
 }
 
 @reflectiveTest
-class AddNeNullTest extends FixProcessorTest {
+class AddNeNullTest extends FixProcessorTest with WithNullSafetyMixin {
   @override
   FixKind get kind => DartFixKind.ADD_NE_NULL;
 
-  Future<void> test_nonBoolCondition() async {
+  Future<void> test_nonBoolCondition_nonNullable() async {
     await resolveTestCode('''
 f(String p) {
   if (p) {
@@ -60,8 +75,19 @@
   }
 }
 ''');
+    await assertNoFix();
+  }
+
+  Future<void> test_nonBoolCondition_nullable() async {
+    await resolveTestCode('''
+f(String? p) {
+  if (p) {
+    print(p);
+  }
+}
+''');
     await assertHasFix('''
-f(String p) {
+f(String? p) {
   if (p != null) {
     print(p);
   }
diff --git a/pkg/analysis_server/test/src/services/correction/fix/add_null_check_test.dart b/pkg/analysis_server/test/src/services/correction/fix/add_null_check_test.dart
index 84fb89a..eaeb488 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/add_null_check_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/add_null_check_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer/error/error.dart';
 import 'package:analyzer/src/error/codes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/add_override_test.dart b/pkg/analysis_server/test/src/services/correction/fix/add_override_test.dart
index 7a33711..54e6983 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/add_override_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/add_override_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
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 d5b03dc..237f0e0 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
@@ -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
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/add_return_type_test.dart b/pkg/analysis_server/test/src/services/correction/fix/add_return_type_test.dart
index 75a8383..33a21c1 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/add_return_type_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/add_return_type_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/add_static_test.dart b/pkg/analysis_server/test/src/services/correction/fix/add_static_test.dart
index 7fd378a..1c18f09 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/add_static_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/add_static_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/add_super_constructor_invocation_test.dart b/pkg/analysis_server/test/src/services/correction/fix/add_super_constructor_invocation_test.dart
index ce129cc..73348d8 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/add_super_constructor_invocation_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/add_super_constructor_invocation_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/add_type_annotation_test.dart b/pkg/analysis_server/test/src/services/correction/fix/add_type_annotation_test.dart
index dd375be..338af4b 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/add_type_annotation_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/add_type_annotation_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/analysis_options/remove_lint_test.dart b/pkg/analysis_server/test/src/services/correction/fix/analysis_options/remove_lint_test.dart
index deb6eb4..f099050 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/analysis_options/remove_lint_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/analysis_options/remove_lint_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.
 
+// @dart = 2.9
+
 import 'package:linter/src/rules.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/analysis_options/remove_setting_test.dart b/pkg/analysis_server/test/src/services/correction/fix/analysis_options/remove_setting_test.dart
index c378884..87870a2 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/analysis_options/remove_setting_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/analysis_options/remove_setting_test.dart
@@ -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
+
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'test_support.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/analysis_options/test_all.dart b/pkg/analysis_server/test/src/services/correction/fix/analysis_options/test_all.dart
index 6d61c19..68e1ceb 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/analysis_options/test_all.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/analysis_options/test_all.dart
@@ -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
+
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'remove_lint_test.dart' as remove_lint;
diff --git a/pkg/analysis_server/test/src/services/correction/fix/analysis_options/test_support.dart b/pkg/analysis_server/test/src/services/correction/fix/analysis_options/test_support.dart
index 4d1d0a8..8762e93 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/analysis_options/test_support.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/analysis_options/test_support.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
+
 import 'package:analysis_server/plugin/edit/fix/fix_core.dart';
 import 'package:analysis_server/src/protocol_server.dart' show SourceEdit;
 import 'package:analysis_server/src/services/correction/fix/analysis_options/fix_generator.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/add_await_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/add_await_test.dart
index dc61da4..66f6bdc 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/bulk/add_await_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/add_await_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/add_const_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/add_const_test.dart
index d20eaf8..0801465 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/bulk/add_const_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/add_const_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/add_diagnostic_property_reference_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/add_diagnostic_property_reference_test.dart
index 0fead9f..c0e7ad4 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/bulk/add_diagnostic_property_reference_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/add_diagnostic_property_reference_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/add_override_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/add_override_test.dart
index b62d97e..bbd1463 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/bulk/add_override_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/add_override_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/add_required_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/add_required_test.dart
index 0be6d18..ba1b000 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/bulk/add_required_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/add_required_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
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 59ae8b8..82b04e2 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
@@ -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
+
 import 'package:analysis_server/src/services/correction/bulk_fix_processor.dart';
 import 'package:analysis_server/src/services/correction/change_workspace.dart';
 import 'package:analyzer/src/dart/analysis/byte_store.dart';
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
index 2e36f14..991651f 100644
--- 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
@@ -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
+
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_documentation_into_line_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_documentation_into_line_test.dart
index 2094c37..7773740 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_documentation_into_line_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_documentation_into_line_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_map_from_iterable_to_for_literal_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_map_from_iterable_to_for_literal_test.dart
index d9e3834..51d99c2 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_map_from_iterable_to_for_literal_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_map_from_iterable_to_for_literal_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_to_contains_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_to_contains_test.dart
index eacb1cc..65b9139 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_to_contains_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_to_contains_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_to_generic_function_syntax_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_to_generic_function_syntax_test.dart
index e279e12..dccf8b9 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_to_generic_function_syntax_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_to_generic_function_syntax_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_to_if_element_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_to_if_element_test.dart
index e965e54..64cfc42 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_to_if_element_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_to_if_element_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_to_if_null_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_to_if_null_test.dart
index 5bca56c..8c7b83f 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_to_if_null_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_to_if_null_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_to_int_literal_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_to_int_literal_test.dart
index 32b17ce..b154097 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_to_int_literal_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_to_int_literal_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_to_is_not_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_to_is_not_test.dart
index 42a907d..3fe2ff6 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_to_is_not_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_to_is_not_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_to_list_literal_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_to_list_literal_test.dart
index af7f3cb..c130c0b 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_to_list_literal_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_to_list_literal_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_to_map_literal_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_to_map_literal_test.dart
index cb02894..b018ce0 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_to_map_literal_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_to_map_literal_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_to_null_aware_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_to_null_aware_test.dart
index e30e7d7..45b117a 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_to_null_aware_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_to_null_aware_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_to_package_import_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_to_package_import_test.dart
index 3c8cf2b..8bec06f 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_to_package_import_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_to_package_import_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_to_relative_import_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_to_relative_import_test.dart
index 40b022f..78f50bf 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_to_relative_import_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_to_relative_import_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_to_set_literal_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_to_set_literal_test.dart
index bfcaf1c..0ee4a40 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_to_set_literal_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_to_set_literal_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_to_single_quoted_strings_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_to_single_quoted_strings_test.dart
index 68a54c0..92d1d10 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_to_single_quoted_strings_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_to_single_quoted_strings_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_to_spread_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_to_spread_test.dart
index ddbdc0a..6219446 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_to_spread_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_to_spread_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_to_where_type_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_to_where_type_test.dart
index 62788ef..c0a382f2 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_to_where_type_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_to_where_type_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/create_method_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/create_method_test.dart
index cf17881..c111c46 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/bulk/create_method_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/create_method_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
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 a92e878..0c50eda 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,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
+
 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';
@@ -506,12 +508,14 @@
     // action accidentally executing data-driven fixes.
 
     final dataDrivenCodes = <String>{};
-    final bulkFixCodes = FixProcessor.lintProducerMap2.entries
+    final bulkFixCodes = FixProcessor.lintProducerMap.entries
         .where((e) => e.value.where((fix) => fix.canBeBulkApplied).isNotEmpty)
         .map((e) => e.key);
     final nonDataDrivenCodes = <String>{
       ...bulkFixCodes,
-      ...BulkFixProcessor.nonLintProducerMap.keys.map((c) => c.uniqueName),
+      ...FixProcessor.nonLintProducerMap2.entries
+          .where((e) => e.value.where((fix) => fix.canBeBulkApplied).isNotEmpty)
+          .map((e) => e.key.uniqueName),
     };
 
     for (final code in BulkFixProcessor.nonLintMultiProducerMap.keys) {
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/inline_invocation_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/inline_invocation_test.dart
index b34d124..8ec7bb0 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/bulk/inline_invocation_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/inline_invocation_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/inline_typedef_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/inline_typedef_test.dart
index c2612f9..0673ac0 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/bulk/inline_typedef_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/inline_typedef_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/make_final_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/make_final_test.dart
index 21724f2..4af5171 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/bulk/make_final_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/make_final_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_argument_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_argument_test.dart
index 7d87ea4..613c373 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_argument_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_argument_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_await_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_await_test.dart
index b1c9f97..85c8868 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_await_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_await_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_duplicate_case_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_duplicate_case_test.dart
index 76d7a91..350c861 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_duplicate_case_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_duplicate_case_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_empty_catch_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_empty_catch_test.dart
index a6a0897d..c23610f 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_empty_catch_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_empty_catch_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_empty_constructor_body_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_empty_constructor_body_test.dart
index 9469973..b1def09 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_empty_constructor_body_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_empty_constructor_body_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_empty_else_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_empty_else_test.dart
index 5c967e2..e184a79 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_empty_else_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_empty_else_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_empty_statement_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_empty_statement_test.dart
index fbf7b39..87bf05a 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_empty_statement_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_empty_statement_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_if_null_operator_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_if_null_operator_test.dart
index 0003079..b73ecb5 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_if_null_operator_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_if_null_operator_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_initializer_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_initializer_test.dart
index c95ede1..a8c3614 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_initializer_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_initializer_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_interpolation_braces_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_interpolation_braces_test.dart
index a291bf1..51fb561 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_interpolation_braces_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_interpolation_braces_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_method_declaration_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_method_declaration_test.dart
index 65f7918..e6b5a9b 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_method_declaration_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_method_declaration_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_non_null_assertion_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_non_null_assertion_test.dart
index eeacfbc..46e164e 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_non_null_assertion_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_non_null_assertion_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.
 
+// @dart = 2.9
+
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import '../../../../../abstract_context.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_operator_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_operator_test.dart
index f876196..a80779a 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_operator_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_operator_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_question_mark_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_question_mark_test.dart
index 48706e9..a87d83c 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_question_mark_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_question_mark_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_this_expression_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_this_expression_test.dart
index eb9eb5c..fd30b02 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_this_expression_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_this_expression_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_type_annotation_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_type_annotation_test.dart
index 600d12d..018fd3d 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_type_annotation_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_type_annotation_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_unnecessary_const_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_unnecessary_const_test.dart
index eb112f7..2bbcf70 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_unnecessary_const_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_unnecessary_const_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_unnecessary_new_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_unnecessary_new_test.dart
index 88670c3..39d2110 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_unnecessary_new_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_unnecessary_new_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_unnecessary_string_interpolation_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_unnecessary_string_interpolation_test.dart
index 1ae3d1d..bd639ad 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_unnecessary_string_interpolation_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_unnecessary_string_interpolation_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/rename_to_camel_case_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/rename_to_camel_case_test.dart
index 5248e32..9c35121 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/bulk/rename_to_camel_case_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/rename_to_camel_case_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/replace_colon_with_equals_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/replace_colon_with_equals_test.dart
index f057c74..b74ba21 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/bulk/replace_colon_with_equals_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/replace_colon_with_equals_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/replace_final_with_const_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/replace_final_with_const_test.dart
index d886f78..d5d91f3 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/bulk/replace_final_with_const_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/replace_final_with_const_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/replace_new_with_const_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/replace_new_with_const_test.dart
index f8ba7bd..982c596 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/bulk/replace_new_with_const_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/replace_new_with_const_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/replace_null_with_closure_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/replace_null_with_closure_test.dart
index 9a686bf..a82c882 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/bulk/replace_null_with_closure_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/replace_null_with_closure_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/replace_with_conditional_assignment_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/replace_with_conditional_assignment_test.dart
index 77c9615..bab21ca 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/bulk/replace_with_conditional_assignment_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/replace_with_conditional_assignment_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/replace_with_is_empty_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/replace_with_is_empty_test.dart
index b61ffd7..13b9776 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/bulk/replace_with_is_empty_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/replace_with_is_empty_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/replace_with_tear_off_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/replace_with_tear_off_test.dart
index eef575b..777ac6e 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/bulk/replace_with_tear_off_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/replace_with_tear_off_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/replace_with_var_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/replace_with_var_test.dart
index 27367dc..ac0bf55 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/bulk/replace_with_var_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/replace_with_var_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/sort_child_properties_last_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/sort_child_properties_last_test.dart
index 3cc5338..89b30db 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/bulk/sort_child_properties_last_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/sort_child_properties_last_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
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 6b8bb68..33acd38 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
@@ -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
+
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'add_await_test.dart' as add_await;
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/use_curly_braces_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/use_curly_braces_test.dart
index 8e1f19a..9bbbeea 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/bulk/use_curly_braces_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/use_curly_braces_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/use_is_not_empty_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/use_is_not_empty_test.dart
index 1f337b8..1d1268b 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/bulk/use_is_not_empty_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/use_is_not_empty_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/use_rethrow_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/use_rethrow_test.dart
index 9d4678b..cdd797d 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/bulk/use_rethrow_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/use_rethrow_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/change_argument_name_test.dart b/pkg/analysis_server/test/src/services/correction/fix/change_argument_name_test.dart
index 5bb073d..3fbed10 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/change_argument_name_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/change_argument_name_test.dart
@@ -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
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/change_to_nearest_precise_value_test.dart b/pkg/analysis_server/test/src/services/correction/fix/change_to_nearest_precise_value_test.dart
index 419a6c1..c4bf81b 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/change_to_nearest_precise_value_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/change_to_nearest_precise_value_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/change_to_static_access_test.dart b/pkg/analysis_server/test/src/services/correction/fix/change_to_static_access_test.dart
index dd985bb..a6720bf 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/change_to_static_access_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/change_to_static_access_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/change_to_test.dart b/pkg/analysis_server/test/src/services/correction/fix/change_to_test.dart
index da9231f..0131fcd 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/change_to_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/change_to_test.dart
@@ -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
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/change_type_annotation_test.dart b/pkg/analysis_server/test/src/services/correction/fix/change_type_annotation_test.dart
index c848914..3d07b71 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/change_type_annotation_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/change_type_annotation_test.dart
@@ -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
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/convert_documentation_into_line_test.dart b/pkg/analysis_server/test/src/services/correction/fix/convert_documentation_into_line_test.dart
index e68869f..51be47f 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/convert_documentation_into_line_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/convert_documentation_into_line_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/convert_flutter_child_test.dart b/pkg/analysis_server/test/src/services/correction/fix/convert_flutter_child_test.dart
index 7afc732..c4602e4 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/convert_flutter_child_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/convert_flutter_child_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/convert_flutter_children_test.dart b/pkg/analysis_server/test/src/services/correction/fix/convert_flutter_children_test.dart
index 0d5ae48..46797c9 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/convert_flutter_children_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/convert_flutter_children_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/convert_into_expression_body_test.dart b/pkg/analysis_server/test/src/services/correction/fix/convert_into_expression_body_test.dart
index 5bcdd3e..70c20334 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/convert_into_expression_body_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/convert_into_expression_body_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/convert_to_contains_test.dart b/pkg/analysis_server/test/src/services/correction/fix/convert_to_contains_test.dart
index f0edd0b..6602062 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/convert_to_contains_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/convert_to_contains_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/convert_to_for_element_test.dart b/pkg/analysis_server/test/src/services/correction/fix/convert_to_for_element_test.dart
index fafbb6e..1c35ea9 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/convert_to_for_element_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/convert_to_for_element_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/convert_to_generic_function_syntax_test.dart b/pkg/analysis_server/test/src/services/correction/fix/convert_to_generic_function_syntax_test.dart
index 6d1ed6b..634617b 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/convert_to_generic_function_syntax_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/convert_to_generic_function_syntax_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/convert_to_if_element_test.dart b/pkg/analysis_server/test/src/services/correction/fix/convert_to_if_element_test.dart
index ed2c3aa..677f515 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/convert_to_if_element_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/convert_to_if_element_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/convert_to_if_null_test.dart b/pkg/analysis_server/test/src/services/correction/fix/convert_to_if_null_test.dart
index 1a641e7..749807a 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/convert_to_if_null_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/convert_to_if_null_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer/src/dart/error/lint_codes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/convert_to_int_literal_test.dart b/pkg/analysis_server/test/src/services/correction/fix/convert_to_int_literal_test.dart
index 154e215..c70252a 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/convert_to_int_literal_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/convert_to_int_literal_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/convert_to_list_literal_test.dart b/pkg/analysis_server/test/src/services/correction/fix/convert_to_list_literal_test.dart
index 160c5f4..c77702a 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/convert_to_list_literal_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/convert_to_list_literal_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/convert_to_map_literal_test.dart b/pkg/analysis_server/test/src/services/correction/fix/convert_to_map_literal_test.dart
index 3407683..4f1a80f 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/convert_to_map_literal_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/convert_to_map_literal_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/convert_to_named_arguments_test.dart b/pkg/analysis_server/test/src/services/correction/fix/convert_to_named_arguments_test.dart
index cf35cc7..18f9934 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/convert_to_named_arguments_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/convert_to_named_arguments_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/convert_to_null_aware_spread_test.dart b/pkg/analysis_server/test/src/services/correction/fix/convert_to_null_aware_spread_test.dart
index 8cdcb25..4901a63 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/convert_to_null_aware_spread_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/convert_to_null_aware_spread_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/convert_to_null_aware_test.dart b/pkg/analysis_server/test/src/services/correction/fix/convert_to_null_aware_test.dart
index 52e07bf..4331faa 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/convert_to_null_aware_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/convert_to_null_aware_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/convert_to_on_type_test.dart b/pkg/analysis_server/test/src/services/correction/fix/convert_to_on_type_test.dart
index f14cf3c..9d765ab 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/convert_to_on_type_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/convert_to_on_type_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/convert_to_package_import_test.dart b/pkg/analysis_server/test/src/services/correction/fix/convert_to_package_import_test.dart
index e991423..3cc1704 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/convert_to_package_import_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/convert_to_package_import_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/convert_to_relative_import_test.dart b/pkg/analysis_server/test/src/services/correction/fix/convert_to_relative_import_test.dart
index 8e59b5f..b8bc8af 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/convert_to_relative_import_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/convert_to_relative_import_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer/src/error/codes.dart';
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 28674cb..ef21709 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
@@ -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
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/convert_to_single_quoted_string_test.dart b/pkg/analysis_server/test/src/services/correction/fix/convert_to_single_quoted_string_test.dart
index 12f8212..d615eb6 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/convert_to_single_quoted_string_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/convert_to_single_quoted_string_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/convert_to_spread_test.dart b/pkg/analysis_server/test/src/services/correction/fix/convert_to_spread_test.dart
index bb9b5c8..a85080b 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/convert_to_spread_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/convert_to_spread_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/convert_to_where_type_test.dart b/pkg/analysis_server/test/src/services/correction/fix/convert_to_where_type_test.dart
index 7768534..891dec0 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/convert_to_where_type_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/convert_to_where_type_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/create_class_test.dart b/pkg/analysis_server/test/src/services/correction/fix/create_class_test.dart
index b81a200..69df2df 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/create_class_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/create_class_test.dart
@@ -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
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/create_constructor_for_final_fields_test.dart b/pkg/analysis_server/test/src/services/correction/fix/create_constructor_for_final_fields_test.dart
index 32efaed..3e1e664 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/create_constructor_for_final_fields_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/create_constructor_for_final_fields_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/create_constructor_super_test.dart b/pkg/analysis_server/test/src/services/correction/fix/create_constructor_super_test.dart
index 19af80e..efb4913 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/create_constructor_super_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/create_constructor_super_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/create_constructor_test.dart b/pkg/analysis_server/test/src/services/correction/fix/create_constructor_test.dart
index 233fa51..62ef51fa 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/create_constructor_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/create_constructor_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/create_field_test.dart b/pkg/analysis_server/test/src/services/correction/fix/create_field_test.dart
index 869bda5..bcd22c6 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/create_field_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/create_field_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/create_file_test.dart b/pkg/analysis_server/test/src/services/correction/fix/create_file_test.dart
index 0c156d3..7eef88f 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/create_file_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/create_file_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 import 'package:test/test.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/create_function_test.dart b/pkg/analysis_server/test/src/services/correction/fix/create_function_test.dart
index fd2fea7..42f5940 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/create_function_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/create_function_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/protocol_server.dart';
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/create_getter_test.dart b/pkg/analysis_server/test/src/services/correction/fix/create_getter_test.dart
index af7db0e..dc573f5 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/create_getter_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/create_getter_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/create_local_variable_test.dart b/pkg/analysis_server/test/src/services/correction/fix/create_local_variable_test.dart
index 2c1d827..78960df 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/create_local_variable_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/create_local_variable_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 import 'package:test/test.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/create_method_test.dart b/pkg/analysis_server/test/src/services/correction/fix/create_method_test.dart
index 4549b21..52fec47 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/create_method_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/create_method_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/protocol_server.dart';
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/create_missing_overrides_test.dart b/pkg/analysis_server/test/src/services/correction/fix/create_missing_overrides_test.dart
index 300d9aa..e45d973 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/create_missing_overrides_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/create_missing_overrides_test.dart
@@ -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
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 import 'package:test/test.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/create_mixin_test.dart b/pkg/analysis_server/test/src/services/correction/fix/create_mixin_test.dart
index 024eab8..0efaa4c 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/create_mixin_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/create_mixin_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/create_no_such_method_test.dart b/pkg/analysis_server/test/src/services/correction/fix/create_no_such_method_test.dart
index 19bfb81..09e733a 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/create_no_such_method_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/create_no_such_method_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/create_setter_test.dart b/pkg/analysis_server/test/src/services/correction/fix/create_setter_test.dart
index 610f7dc..0c93281 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/create_setter_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/create_setter_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
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 dcda4bc..1cb910e 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
@@ -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
+
 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';
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 9a8fdc2..5117185 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
@@ -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
+
 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';
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 f6ccc74..6a20dd1 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
@@ -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
+
 import 'package:analysis_server/src/services/correction/fix/data_driven/accessor.dart';
 import 'package:analysis_server/src/services/correction/fix/data_driven/code_template.dart';
 import 'package:analysis_server/src/services/correction/fix/data_driven/parameter_reference.dart';
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 e26e0061..6149d77 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
@@ -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
+
 import 'package:analysis_server/src/services/correction/dart/data_driven.dart';
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/correction/fix/data_driven/code_template.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/conflicting_key_test.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/conflicting_key_test.dart
index 77d6de7..876aec3 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/conflicting_key_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/conflicting_key_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix/data_driven/transform_set_error_code.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
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
index 38c7e43..f9100e7 100644
--- 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
@@ -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
+
 import 'package:analysis_server/src/services/correction/fix/data_driven/transform_set_error_code.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/invalid_character_test.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/invalid_character_test.dart
index ab3ece6..1050f96 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/invalid_character_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/invalid_character_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix/data_driven/transform_set_error_code.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/invalid_key_test.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/invalid_key_test.dart
index 0a7c158..ed9a783 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/invalid_key_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/invalid_key_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix/data_driven/transform_set_error_code.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/invalid_parameter_style_test.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/invalid_parameter_style_test.dart
index 0fe38db..f2869c9 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/invalid_parameter_style_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/invalid_parameter_style_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix/data_driven/transform_set_error_code.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
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
index 5037a80..4f48576 100644
--- 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
@@ -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
+
 import 'package:analysis_server/src/services/correction/fix/data_driven/transform_set_error_code.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/invalid_value_one_of_test.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/invalid_value_one_of_test.dart
index fa9beb5..fd960eb 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/invalid_value_one_of_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/invalid_value_one_of_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix/data_driven/transform_set_error_code.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/invalid_value_test.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/invalid_value_test.dart
index 1bd6446..4fe611d 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/invalid_value_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/invalid_value_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix/data_driven/transform_set_error_code.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
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 c4a2e75..3efdb34 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
@@ -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
+
 import 'package:analysis_server/src/services/correction/fix/data_driven/transform_set_error_code.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
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 002f2f5..9a2ef98 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
@@ -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
+
 import 'package:analysis_server/src/services/correction/fix/data_driven/transform_set_error_code.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/missing_template_end_test.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/missing_template_end_test.dart
index 0301220..f9ed776 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/missing_template_end_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/missing_template_end_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix/data_driven/transform_set_error_code.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
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 c1ee9bd..549eac8 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
@@ -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
+
 import 'package:analysis_server/src/services/correction/fix/data_driven/transform_set_error_code.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/missing_uri_test.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/missing_uri_test.dart
index ac21bfc..8efa08b 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/missing_uri_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/missing_uri_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix/data_driven/transform_set_error_code.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
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 bb2464ae..8a67f05 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
@@ -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
+
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'conflicting_key_test.dart' as conflicting_key;
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/undefined_variable_test.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/undefined_variable_test.dart
index db854a5..5014984 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/undefined_variable_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/undefined_variable_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix/data_driven/transform_set_error_code.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
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
index 9f6213c..f96685d 100644
--- 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
@@ -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
+
 import 'package:analysis_server/src/services/correction/fix/data_driven/transform_set_error_code.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/unknown_accessor_test.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/unknown_accessor_test.dart
index 205ad42..c877690 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/unknown_accessor_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/unknown_accessor_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix/data_driven/transform_set_error_code.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/unsupported_key_test.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/unsupported_key_test.dart
index 64d724e..8e6df60 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/unsupported_key_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/unsupported_key_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix/data_driven/transform_set_error_code.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/unsupported_version_test.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/unsupported_version_test.dart
index 606341f..7bd3c13 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/unsupported_version_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/unsupported_version_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.
 
+// @dart = 2.9
+
 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/transform_set_parser.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
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 ed35ea9..9548a68 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
@@ -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
+
 import 'package:analysis_server/src/services/correction/fix/data_driven/transform_set_error_code.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/yaml_syntax_error_test.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/yaml_syntax_error_test.dart
index dfa3444..a74c9d2 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/yaml_syntax_error_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/yaml_syntax_error_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix/data_driven/transform_set_error_code.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/element_matcher_test.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/element_matcher_test.dart
index f462b36..aa9695e 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/data_driven/element_matcher_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/element_matcher_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.
 
+// @dart = 2.9
+
 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';
 import 'package:analyzer/src/test_utilities/package_config_file_builder.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/end_to_end_test.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/end_to_end_test.dart
index eb13dcf..dbabac1 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/data_driven/end_to_end_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/end_to_end_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.
 
+// @dart = 2.9
+
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'data_driven_test_support.dart';
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 e8d6d1b..327fe3a 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
@@ -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
+
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'data_driven_test_support.dart';
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 77e7e1f..bec1da6 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,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
+
 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';
@@ -384,12 +386,44 @@
 ''');
   }
 
+  Future<void> test_mixed_overlap_addBetweenRemoved_deprecated() async {
+    setPackageContent('''
+class C {
+  @deprecated
+  void m1({int a, int b,        int d, int e}) {}
+  void m2({int a,        int c,        int e}) {}
+}
+''');
+    setPackageData(_modify([
+      'm1',
+      'C'
+    ], [
+      AddParameter(1, 'c', true, false, codeTemplate('3')),
+      RemoveParameter(NamedParameterReference('b')),
+      RemoveParameter(NamedParameterReference('d')),
+    ], newName: 'm2'));
+    await resolveTestCode('''
+import '$importUri';
+
+void f(C c) {
+  c.m1(a: 1, b: 2, d: 4, e: 5);
+}
+''');
+    await assertHasFix('''
+import '$importUri';
+
+void f(C c) {
+  c.m2(a: 1, c: 3, e: 5);
+}
+''');
+  }
+
   Future<void> test_mixed_overlap_first_deprecated() async {
     setPackageContent('''
 class C {
   @deprecated
-  void m1(int a, int b, int d) {}
-  void m2(       int c, int d) {}
+  void m1(int a, int b,        int d) {}
+  void m2(              int c, int d) {}
 }
 ''');
     setPackageData(_modify([
@@ -420,8 +454,8 @@
     setPackageContent('''
 class C {
   @deprecated
-  void m1(int a, int b, int c) {}
-  void m2(int a,        int d) {}
+  void m1(int a, int b, int c       ) {}
+  void m2(int a,               int d) {}
 }
 ''');
     setPackageData(_modify([
@@ -452,8 +486,8 @@
     setPackageContent('''
 class C {
   @deprecated
-  void m1(       int b, int c, int e, int f, int g) {}
-  void m2(int a, int b, int d, int e,        int g) {}
+  void m1(       int b, int c,        int e, int f, int g) {}
+  void m2(int a, int b,        int d, int e,        int g) {}
 }
 ''');
     setPackageData(_modify([
@@ -481,7 +515,7 @@
 ''');
   }
 
-  Future<void> test_mixed_replaced_deprecated() async {
+  Future<void> test_mixed_replaceAll_deprecated() async {
     setPackageContent('''
 class C {
   @deprecated
@@ -512,6 +546,41 @@
 ''');
   }
 
+  Future<void> test_mixed_replaceAll_trailingComma_deprecated() async {
+    setPackageContent('''
+class C {
+  @deprecated
+  void m1({int a       }) {}
+  void m2({       int b}) {}
+}
+''');
+    setPackageData(_modify([
+      'm1',
+      'C'
+    ], [
+      AddParameter(0, 'b', true, false, codeTemplate('0')),
+      RemoveParameter(NamedParameterReference('a')),
+    ], newName: 'm2'));
+    await resolveTestCode('''
+import '$importUri';
+
+void f(C c) {
+  c.m1(
+    a: 1,
+  );
+}
+''');
+    await assertHasFix('''
+import '$importUri';
+
+void f(C c) {
+  c.m2(
+    b: 0,
+  );
+}
+''');
+  }
+
   Future<void> test_remove_first_optionalNamed_deprecated() async {
     setPackageContent('''
 class C {
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 3a189c0..856d4e0 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,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
+
 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';
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 6e0ce4a..0affe38 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,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
+
 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';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/sdk_fix_test.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/sdk_fix_test.dart
index a154782..2dfa7b4 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/data_driven/sdk_fix_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/sdk_fix_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix/data_driven/transform_set_manager.dart';
 import 'package:analyzer/src/test_utilities/mock_sdk.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/test_all.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/test_all.dart
index a21ba3c..f393c9b 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/data_driven/test_all.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/test_all.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
+
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'add_type_parameter_test.dart' as add_type_parameter;
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/transform_override_set_parser_test.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/transform_override_set_parser_test.dart
index 5aa8721..a219dbc 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/data_driven/transform_override_set_parser_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/transform_override_set_parser_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.
 
+// @dart = 2.9
+
 import 'package:_fe_analyzer_shared/src/base/errors.dart';
 import 'package:analysis_server/src/services/correction/fix/data_driven/transform_override_set.dart';
 import 'package:analysis_server/src/services/correction/fix/data_driven/transform_override_set_parser.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/transform_set_manager_test.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/transform_set_manager_test.dart
index c0f59db..e845848 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/data_driven/transform_set_manager_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/transform_set_manager_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix/data_driven/transform_set_manager.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
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 d2789c8..73ce508 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
@@ -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
+
 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';
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 af3b094..a18e9be 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
@@ -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
+
 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_parser.dart';
 import 'package:analyzer/error/error.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/extend_class_for_mixin_test.dart b/pkg/analysis_server/test/src/services/correction/fix/extend_class_for_mixin_test.dart
index 1624c7f..e534c03 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/extend_class_for_mixin_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/extend_class_for_mixin_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/fix_in_file_test.dart b/pkg/analysis_server/test/src/services/correction/fix/fix_in_file_test.dart
index 482894f..7545858 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/fix_in_file_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/fix_in_file_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix_internal.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:test/test.dart';
@@ -125,11 +127,11 @@
 
   static void verify_fixInFileFixesHaveBulkFixTests() {
     group('VerificationTests | fixInFileFixesHaveBulkFixTests |', () {
-      for (var fixEntry in FixProcessor.lintProducerMap2.entries) {
+      for (var fixEntry in FixProcessor.lintProducerMap.entries) {
         var errorCode = fixEntry.key;
         for (var fixInfo in fixEntry.value) {
           if (fixInfo.canBeAppliedToFile) {
-            test(errorCode, () {
+            test('$errorCode |', () {
               expect(fixInfo.canBeBulkApplied, isTrue);
             });
           }
@@ -140,7 +142,7 @@
 
   static void verify_fixInFileFixesHaveUniqueBulkFixes() {
     group('VerificationTests | fixInFileFixesHaveUniqueBulkFixes | lint |', () {
-      for (var fixEntry in FixProcessor.lintProducerMap2.entries) {
+      for (var fixEntry in FixProcessor.lintProducerMap.entries) {
         var errorCode = fixEntry.key;
         for (var fixInfo in fixEntry.value) {
           if (fixInfo.canBeAppliedToFile) {
@@ -166,7 +168,7 @@
     var dynamicProducerTypes = ['ReplaceWithIsEmpty'];
 
     group('VerificationTests | fixInFileFixKindsHaveMultiFixes | lint |', () {
-      for (var fixEntry in FixProcessor.lintProducerMap2.entries) {
+      for (var fixEntry in FixProcessor.lintProducerMap.entries) {
         var errorCode = fixEntry.key;
         for (var fixInfo in fixEntry.value) {
           // At least one generator should have a multiFix.
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 67e4ffe..4c8fc08 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
@@ -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
+
 import 'package:analysis_server/plugin/edit/fix/fix_core.dart';
 import 'package:analysis_server/src/services/correction/change_workspace.dart';
 import 'package:analysis_server/src/services/correction/fix.dart';
@@ -279,6 +281,11 @@
     await _assertNoFix(error);
   }
 
+  Future<void> assertNoFixAllFix(ErrorCode errorCode) async {
+    var error = await _findErrorToFixOfType(errorCode);
+    await _assertNoFixAllFix(error);
+  }
+
   List<LinkedEditSuggestion> expectedSuggestions(
       LinkedEditSuggestionKind kind, List<String> values) {
     return values.map((value) {
@@ -383,6 +390,19 @@
     }
   }
 
+  Future<void> _assertNoFixAllFix(AnalysisError error) async {
+    if (!kind.canBeAppliedTogether()) {
+      fail('Expected to find and return fix-all FixKind for $kind, '
+          'but kind.canBeAppliedTogether is ${kind.canBeAppliedTogether}');
+    }
+    var fixes = await _computeFixes(error);
+    for (var fix in fixes) {
+      if (fix.kind == kind && fix.isFixAllFix()) {
+        fail('Unexpected fix $kind in\n${fixes.join('\n')}');
+      }
+    }
+  }
+
   /// Computes fixes for the given [error] in [testUnit].
   Future<List<Fix>> _computeFixes(AnalysisError error) async {
     var analysisContext = contextFor(testFile);
diff --git a/pkg/analysis_server/test/src/services/correction/fix/fix_test.dart b/pkg/analysis_server/test/src/services/correction/fix/fix_test.dart
index b66fd12..c457918 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/fix_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/fix_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.
 
+// @dart = 2.9
+
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/import_async_test.dart b/pkg/analysis_server/test/src/services/correction/fix/import_async_test.dart
index 5fa217e..519e973 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/import_async_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/import_async_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/import_library_prefix_test.dart b/pkg/analysis_server/test/src/services/correction/fix/import_library_prefix_test.dart
index c1ffcce..821600b 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/import_library_prefix_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/import_library_prefix_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/import_library_project_test.dart b/pkg/analysis_server/test/src/services/correction/fix/import_library_project_test.dart
index fcfed31..709dd4c 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/import_library_project_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/import_library_project_test.dart
@@ -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
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/import_library_sdk_test.dart b/pkg/analysis_server/test/src/services/correction/fix/import_library_sdk_test.dart
index 8b0b7e5..54edaa4 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/import_library_sdk_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/import_library_sdk_test.dart
@@ -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
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/import_library_show_test.dart b/pkg/analysis_server/test/src/services/correction/fix/import_library_show_test.dart
index e54adba..57b95ad 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/import_library_show_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/import_library_show_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/inline_invocation_test.dart b/pkg/analysis_server/test/src/services/correction/fix/inline_invocation_test.dart
index bb8dc37..c1562ba 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/inline_invocation_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/inline_invocation_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/inline_typedef_test.dart b/pkg/analysis_server/test/src/services/correction/fix/inline_typedef_test.dart
index 39d4fdb..ff11196 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/inline_typedef_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/inline_typedef_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/insert_semicolon_test.dart b/pkg/analysis_server/test/src/services/correction/fix/insert_semicolon_test.dart
index 937ff59..1425260 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/insert_semicolon_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/insert_semicolon_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/make_class_abstract_test.dart b/pkg/analysis_server/test/src/services/correction/fix/make_class_abstract_test.dart
index f5927f9..a9d04c6 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/make_class_abstract_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/make_class_abstract_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/make_field_not_final_test.dart b/pkg/analysis_server/test/src/services/correction/fix/make_field_not_final_test.dart
index 941643a..c36b65d 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/make_field_not_final_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/make_field_not_final_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/make_final_test.dart b/pkg/analysis_server/test/src/services/correction/fix/make_final_test.dart
index fbee41d..d035112 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/make_final_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/make_final_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/make_return_type_nullable_test.dart b/pkg/analysis_server/test/src/services/correction/fix/make_return_type_nullable_test.dart
index e661f34..1e9cb8f 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/make_return_type_nullable_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/make_return_type_nullable_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -133,6 +135,21 @@
 ''');
   }
 
+  Future<void> test_method_sync_inherited() async {
+    await resolveTestCode('''
+abstract class A {
+  String m(String? s);
+}
+
+class B extends A {
+  m(String? s) {
+    return s;
+  }
+}
+''');
+    await assertNoFix();
+  }
+
   Future<void> test_returnTypeHasTypeArguments() async {
     await resolveTestCode('''
 List<String> f() {
diff --git a/pkg/analysis_server/test/src/services/correction/fix/make_variable_not_final_test.dart b/pkg/analysis_server/test/src/services/correction/fix/make_variable_not_final_test.dart
index c87fde3..cf9a788 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/make_variable_not_final_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/make_variable_not_final_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/make_variable_nullable_test.dart b/pkg/analysis_server/test/src/services/correction/fix/make_variable_nullable_test.dart
index f619f67..488331c 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/make_variable_nullable_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/make_variable_nullable_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/manifest/test_support.dart b/pkg/analysis_server/test/src/services/correction/fix/manifest/test_support.dart
deleted file mode 100644
index f071ec8..0000000
--- a/pkg/analysis_server/test/src/services/correction/fix/manifest/test_support.dart
+++ /dev/null
@@ -1,47 +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/plugin/edit/fix/fix_core.dart';
-import 'package:analysis_server/src/protocol_server.dart' show SourceEdit;
-import 'package:analysis_server/src/services/correction/fix/manifest/fix_generator.dart';
-import 'package:analyzer/src/manifest/manifest_validator.dart';
-import 'package:analyzer/src/manifest/manifest_values.dart';
-import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
-import 'package:analyzer_plugin/protocol/protocol_common.dart';
-import 'package:html/parser.dart';
-import 'package:test/test.dart';
-
-/// A base class providing utility methods for tests of fixes associated with
-/// errors in Android manifest files.
-class ManifestFixTest with ResourceProviderMixin {
-  Future<void> assertHasFix(
-      String initialContent, String expectedContent) async {
-    var fixes = await _getFixes(initialContent);
-    expect(fixes, hasLength(1));
-    var fileEdits = fixes[0].change.edits;
-    expect(fileEdits, hasLength(1));
-
-    var actualContent =
-        SourceEdit.applySequence(initialContent, fileEdits[0].edits);
-    expect(actualContent, expectedContent);
-  }
-
-  Future<void> assertHasNoFix(String initialContent) async {
-    var fixes = await _getFixes(initialContent);
-    expect(fixes, hasLength(0));
-  }
-
-  Future<List<Fix>> _getFixes(String content) {
-    var manifestFile = getFile('/package/AndroidManifest.xml');
-    var document =
-        parseFragment(content, container: MANIFEST_TAG, generateSpans: true);
-    expect(document, isNotNull);
-    var validator = ManifestValidator(manifestFile.createSource());
-    var errors = validator.validate(content, true);
-    expect(errors, hasLength(1));
-    var error = errors[0];
-    var generator = ManifestFixGenerator(error, content, document);
-    return generator.computeFixes();
-  }
-}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/move_type_arguments_to_class_test.dart b/pkg/analysis_server/test/src/services/correction/fix/move_type_arguments_to_class_test.dart
index c3b99ff..6ff66ba 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/move_type_arguments_to_class_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/move_type_arguments_to_class_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/organize_imports_test.dart b/pkg/analysis_server/test/src/services/correction/fix/organize_imports_test.dart
index 941bdf4..125a5d5 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/organize_imports_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/organize_imports_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/pubspec/test_support.dart b/pkg/analysis_server/test/src/services/correction/fix/pubspec/test_support.dart
deleted file mode 100644
index 6fc913e..0000000
--- a/pkg/analysis_server/test/src/services/correction/fix/pubspec/test_support.dart
+++ /dev/null
@@ -1,61 +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/plugin/edit/fix/fix_core.dart';
-import 'package:analysis_server/src/protocol_server.dart' show SourceEdit;
-import 'package:analysis_server/src/services/correction/fix/pubspec/fix_generator.dart';
-import 'package:analyzer/src/pubspec/pubspec_validator.dart';
-import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
-import 'package:analyzer_plugin/protocol/protocol_common.dart';
-import 'package:test/test.dart';
-import 'package:yaml/yaml.dart';
-
-/// A base class providing utility methods for tests of fixes associated with
-/// errors in pubspec files.
-class PubspecFixTest with ResourceProviderMixin {
-  Future<void> assertHasFix(
-      String initialContent, String expectedContent) async {
-    var fixes = await _getFixes(initialContent);
-    expect(fixes, hasLength(1));
-    var fileEdits = fixes[0].change.edits;
-    expect(fileEdits, hasLength(1));
-
-    var actualContent =
-        SourceEdit.applySequence(initialContent, fileEdits[0].edits);
-    expect(actualContent, expectedContent);
-  }
-
-  Future<void> assertHasNoFix(String initialContent) async {
-    var fixes = await _getFixes(initialContent);
-    expect(fixes, hasLength(0));
-  }
-
-  Future<List<Fix>> _getFixes(String content) {
-    var pubspecFile = getFile('/package/pubspec.yaml');
-    var pubspec = _parseYaml(content);
-    expect(pubspec, isNotNull);
-    var validator =
-        PubspecValidator(resourceProvider, pubspecFile.createSource());
-    var errors = validator.validate(pubspec.nodes);
-    expect(errors, hasLength(1));
-    var error = errors[0];
-    var generator = PubspecFixGenerator(error, content, pubspec);
-    return generator.computeFixes();
-  }
-
-  YamlMap _parseYaml(String content) {
-    if (content == null) {
-      return YamlMap();
-    }
-    try {
-      var doc = loadYamlNode(content);
-      if (doc is YamlMap) {
-        return doc;
-      }
-      return YamlMap();
-    } catch (exception) {
-      return null;
-    }
-  }
-}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/qualify_reference_test.dart b/pkg/analysis_server/test/src/services/correction/fix/qualify_reference_test.dart
index 5c92c08..e44250d 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/qualify_reference_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/qualify_reference_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_annotation_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_annotation_test.dart
index b693ead..36be9f6 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/remove_annotation_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_annotation_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_argument_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_argument_test.dart
index cb1dc00..c528f5b 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/remove_argument_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_argument_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_await_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_await_test.dart
index 97d8bf8..29c0674 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/remove_await_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_await_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_comparison_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_comparison_test.dart
index 5494406..97608943 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/remove_comparison_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_comparison_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_const_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_const_test.dart
index 3f347cc3..7b6b001 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/remove_const_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_const_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
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 3fd394e..dd0e173 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
@@ -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
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_duplicate_case_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_duplicate_case_test.dart
index 0d8a6b1..c6243fd 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/remove_duplicate_case_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_duplicate_case_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_empty_catch_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_empty_catch_test.dart
index ff75a69..2321c20 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/remove_empty_catch_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_empty_catch_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_empty_constructor_body_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_empty_constructor_body_test.dart
index 3f93785..51b93c3 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/remove_empty_constructor_body_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_empty_constructor_body_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.
 
+// @dart = 2.9
+
 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';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_empty_else_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_empty_else_test.dart
index b7521b3..db6fb4b 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/remove_empty_else_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_empty_else_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_empty_statement_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_empty_statement_test.dart
index 0b28f0f..1622bea 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/remove_empty_statement_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_empty_statement_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_if_null_operator_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_if_null_operator_test.dart
index 3f86e17..c92d731 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/remove_if_null_operator_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_if_null_operator_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_initializer_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_initializer_test.dart
index 7127fbd..151ac34 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/remove_initializer_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_initializer_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_interpolation_braces_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_interpolation_braces_test.dart
index eaf6bc0..76179a9 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/remove_interpolation_braces_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_interpolation_braces_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_method_declaration_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_method_declaration_test.dart
index d7d5d74..40b63e0 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/remove_method_declaration_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_method_declaration_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer/src/dart/analysis/experiments.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_name_from_combinator_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_name_from_combinator_test.dart
index e833910..9280896 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/remove_name_from_combinator_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_name_from_combinator_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_non_null_assertion_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_non_null_assertion_test.dart
index d66f1b8..643425b 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/remove_non_null_assertion_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_non_null_assertion_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_operator_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_operator_test.dart
index 22aa7e5..b71c545 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/remove_operator_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_operator_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_parameters_in_getter_declaration_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_parameters_in_getter_declaration_test.dart
index 8b96c68..b4c7466 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/remove_parameters_in_getter_declaration_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_parameters_in_getter_declaration_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_parentheses_in_getter_invocation_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_parentheses_in_getter_invocation_test.dart
index 5f0d7e3..203eae4 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/remove_parentheses_in_getter_invocation_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_parentheses_in_getter_invocation_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_question_mark_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_question_mark_test.dart
index 286b5d3..3fcd7f9 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/remove_question_mark_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_question_mark_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_this_expression_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_this_expression_test.dart
index aa1a132..6efe653 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/remove_this_expression_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_this_expression_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_type_annotation_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_type_annotation_test.dart
index d4c97ab..c26fe04 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/remove_type_annotation_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_type_annotation_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_type_arguments_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_type_arguments_test.dart
index 62bf7e6..e13eb07 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/remove_type_arguments_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_type_arguments_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_unnecessary_cast_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_unnecessary_cast_test.dart
index 57bfd6c..ea8217b 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/remove_unnecessary_cast_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_unnecessary_cast_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_unnecessary_const_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_unnecessary_const_test.dart
index 1f1e6f2..1969f3e 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/remove_unnecessary_const_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_unnecessary_const_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_unnecessary_new_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_unnecessary_new_test.dart
index dc6b443..ee1a000 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/remove_unnecessary_new_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_unnecessary_new_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_unnecessary_parentheses_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_unnecessary_parentheses_test.dart
index 166007e..f482d47 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/remove_unnecessary_parentheses_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_unnecessary_parentheses_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_unnecessary_string_interpolation_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_unnecessary_string_interpolation_test.dart
index cd6a3c4..d849c0e 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/remove_unnecessary_string_interpolation_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_unnecessary_string_interpolation_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_unused_catch_clause_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_unused_catch_clause_test.dart
index d18763d..97e20b7 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/remove_unused_catch_clause_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_unused_catch_clause_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_unused_catch_stack_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_unused_catch_stack_test.dart
index 730f44e..4d484d6 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/remove_unused_catch_stack_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_unused_catch_stack_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_unused_element_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_unused_element_test.dart
index 154a433..9faaa3a 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/remove_unused_element_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_unused_element_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer/error/error.dart';
 import 'package:analyzer/src/error/codes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_unused_field_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_unused_field_test.dart
index 8bf054c..e8419fd 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/remove_unused_field_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_unused_field_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_unused_import_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_unused_import_test.dart
index 020945a..44953fc 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/remove_unused_import_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_unused_import_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_unused_label_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_unused_label_test.dart
index df57ba1..e5525f38 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/remove_unused_label_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_unused_label_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_unused_local_variable_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_unused_local_variable_test.dart
index dac33f8..45e17e3 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/remove_unused_local_variable_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_unused_local_variable_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_unused_parameter_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_unused_parameter_test.dart
index d32eb88..d8e42b3 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/remove_unused_parameter_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_unused_parameter_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/rename_to_camel_case_test.dart b/pkg/analysis_server/test/src/services/correction/fix/rename_to_camel_case_test.dart
index 9ae1f64..7fe7132 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/rename_to_camel_case_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/rename_to_camel_case_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/replace_boolean_with_bool_test.dart b/pkg/analysis_server/test/src/services/correction/fix/replace_boolean_with_bool_test.dart
index 2d35370..6931abc 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/replace_boolean_with_bool_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/replace_boolean_with_bool_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/replace_cascade_with_dot_test.dart b/pkg/analysis_server/test/src/services/correction/fix/replace_cascade_with_dot_test.dart
index 8cf92ad..26a4c84 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/replace_cascade_with_dot_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/replace_cascade_with_dot_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/replace_colon_with_equals_test.dart b/pkg/analysis_server/test/src/services/correction/fix/replace_colon_with_equals_test.dart
index 852892b..006166c 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/replace_colon_with_equals_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/replace_colon_with_equals_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/replace_final_with_const_test.dart b/pkg/analysis_server/test/src/services/correction/fix/replace_final_with_const_test.dart
index e1ffdad..4855265 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/replace_final_with_const_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/replace_final_with_const_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/replace_final_with_var_test.dart b/pkg/analysis_server/test/src/services/correction/fix/replace_final_with_var_test.dart
new file mode 100644
index 0000000..142e6a2
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/replace_final_with_var_test.dart
@@ -0,0 +1,69 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for 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 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analysis_server/src/services/linter/lint_names.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'bulk/bulk_fix_processor.dart';
+import 'fix_processor.dart';
+
+void main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(ReplaceFinalWithVarBulkTest);
+    defineReflectiveTests(ReplaceFinalWithVarTest);
+  });
+}
+
+@reflectiveTest
+class ReplaceFinalWithVarBulkTest extends BulkFixProcessorTest {
+  @override
+  String get lintCode => LintNames.unnecessary_final;
+
+  Future<void> test_singleFile() async {
+    await resolveTestCode('''
+void f() {
+  final int a = 1;
+  final b = 1;
+  final c = 1;
+  print(a + b + c);
+}
+''');
+    await assertHasFix('''
+void f() {
+  final int a = 1;
+  var b = 1;
+  var c = 1;
+  print(a + b + c);
+}
+''');
+  }
+}
+
+@reflectiveTest
+class ReplaceFinalWithVarTest extends FixProcessorLintTest {
+  @override
+  FixKind get kind => DartFixKind.REPLACE_FINAL_WITH_VAR;
+
+  @override
+  String get lintCode => LintNames.unnecessary_final;
+
+  Future<void> test_method() async {
+    await resolveTestCode('''
+void f() {
+  final a = 1;
+  print(a);
+}
+''');
+    await assertHasFix('''
+void f() {
+  var a = 1;
+  print(a);
+}
+''');
+  }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/replace_new_with_const_test.dart b/pkg/analysis_server/test/src/services/correction/fix/replace_new_with_const_test.dart
index a1607e5..5c1dd65 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/replace_new_with_const_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/replace_new_with_const_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/replace_null_with_closure_test.dart b/pkg/analysis_server/test/src/services/correction/fix/replace_null_with_closure_test.dart
index 8c6d3b3..0588184 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/replace_null_with_closure_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/replace_null_with_closure_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/replace_return_type_future_test.dart b/pkg/analysis_server/test/src/services/correction/fix/replace_return_type_future_test.dart
index 0c42514..273fff5 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/replace_return_type_future_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/replace_return_type_future_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/replace_var_with_dynamic_test.dart b/pkg/analysis_server/test/src/services/correction/fix/replace_var_with_dynamic_test.dart
index 02b4eae..444cd2d 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/replace_var_with_dynamic_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/replace_var_with_dynamic_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer/src/dart/error/syntactic_errors.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/replace_with_brackets_test.dart b/pkg/analysis_server/test/src/services/correction/fix/replace_with_brackets_test.dart
index 21075fa..63fed72 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/replace_with_brackets_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/replace_with_brackets_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/replace_with_conditional_assignment_test.dart b/pkg/analysis_server/test/src/services/correction/fix/replace_with_conditional_assignment_test.dart
index 8964e95..7a1dbb4 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/replace_with_conditional_assignment_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/replace_with_conditional_assignment_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/replace_with_eight_digit_hex_test.dart b/pkg/analysis_server/test/src/services/correction/fix/replace_with_eight_digit_hex_test.dart
index bd4e2e1..9ec3529 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/replace_with_eight_digit_hex_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/replace_with_eight_digit_hex_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/replace_with_extension_name_test.dart b/pkg/analysis_server/test/src/services/correction/fix/replace_with_extension_name_test.dart
index 0bf4a84..8d70db9 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/replace_with_extension_name_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/replace_with_extension_name_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/replace_with_filled_test.dart b/pkg/analysis_server/test/src/services/correction/fix/replace_with_filled_test.dart
index cdfb2bc..d719d36 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/replace_with_filled_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/replace_with_filled_test.dart
@@ -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
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/replace_with_identifier_test.dart b/pkg/analysis_server/test/src/services/correction/fix/replace_with_identifier_test.dart
index ce9487a..99f9758 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/replace_with_identifier_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/replace_with_identifier_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/replace_with_interpolation_test.dart b/pkg/analysis_server/test/src/services/correction/fix/replace_with_interpolation_test.dart
index 0a2539b..4a552ee 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/replace_with_interpolation_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/replace_with_interpolation_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/replace_with_is_empty_test.dart b/pkg/analysis_server/test/src/services/correction/fix/replace_with_is_empty_test.dart
index ebff731..345ba29 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/replace_with_is_empty_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/replace_with_is_empty_test.dart
@@ -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
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/replace_with_is_not_empty_test.dart b/pkg/analysis_server/test/src/services/correction/fix/replace_with_is_not_empty_test.dart
index b7bdd71..57827f3 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/replace_with_is_not_empty_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/replace_with_is_not_empty_test.dart
@@ -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
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/replace_with_not_null_aware_test.dart b/pkg/analysis_server/test/src/services/correction/fix/replace_with_not_null_aware_test.dart
index ccbc1cf..cdce1b0 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/replace_with_not_null_aware_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/replace_with_not_null_aware_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/replace_with_null_aware_test.dart b/pkg/analysis_server/test/src/services/correction/fix/replace_with_null_aware_test.dart
index 226c4f7..05c60ac 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/replace_with_null_aware_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/replace_with_null_aware_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/replace_with_tear_off_test.dart b/pkg/analysis_server/test/src/services/correction/fix/replace_with_tear_off_test.dart
index 772ecd7..793d625 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/replace_with_tear_off_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/replace_with_tear_off_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
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 422034e..3b57554 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
@@ -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
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/sort_child_property_last_test.dart b/pkg/analysis_server/test/src/services/correction/fix/sort_child_property_last_test.dart
index 686d8f2..7c46f06 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/sort_child_property_last_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/sort_child_property_last_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/test_all.dart b/pkg/analysis_server/test/src/services/correction/fix/test_all.dart
index 41b5cce..8d78b42 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/test_all.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/test_all.dart
@@ -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
+
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'add_async_test.dart' as add_async;
@@ -147,6 +149,7 @@
 import 'replace_cascade_with_dot_test.dart' as replace_cascade_with_dot;
 import 'replace_colon_with_equals_test.dart' as replace_colon_with_equals;
 import 'replace_final_with_const_test.dart' as replace_final_with_const;
+import 'replace_final_with_var_test.dart' as replace_final_with_var;
 import 'replace_new_with_const_test.dart' as replace_new_with_const;
 import 'replace_null_with_closure_test.dart' as replace_null_with_closure;
 import 'replace_return_type_future_test.dart' as replace_return_type_future;
@@ -306,6 +309,7 @@
     replace_cascade_with_dot.main();
     replace_colon_with_equals.main();
     replace_final_with_const.main();
+    replace_final_with_var.main();
     replace_new_with_const.main();
     replace_null_with_closure.main();
     replace_return_type_future.main();
diff --git a/pkg/analysis_server/test/src/services/correction/fix/update_sdk_constraints_test.dart b/pkg/analysis_server/test/src/services/correction/fix/update_sdk_constraints_test.dart
index d6f6cf6..416be56 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/update_sdk_constraints_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/update_sdk_constraints_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.
 
+// @dart = 2.9
+
 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';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/use_const_test.dart b/pkg/analysis_server/test/src/services/correction/fix/use_const_test.dart
index 62e0701..3476b67 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/use_const_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/use_const_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/use_effective_integer_division_test.dart b/pkg/analysis_server/test/src/services/correction/fix/use_effective_integer_division_test.dart
index d8a6c78..5a861d5 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/use_effective_integer_division_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/use_effective_integer_division_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/use_eq_eq_null_test.dart b/pkg/analysis_server/test/src/services/correction/fix/use_eq_eq_null_test.dart
index 2e53d54..9173967 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/use_eq_eq_null_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/use_eq_eq_null_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/use_is_not_empty_test.dart b/pkg/analysis_server/test/src/services/correction/fix/use_is_not_empty_test.dart
index 04a82ac..7142b2f 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/use_is_not_empty_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/use_is_not_empty_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/use_not_eq_null_test.dart b/pkg/analysis_server/test/src/services/correction/fix/use_not_eq_null_test.dart
index fdd7d12..768232f 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/use_not_eq_null_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/use_not_eq_null_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/use_rethrow_test.dart b/pkg/analysis_server/test/src/services/correction/fix/use_rethrow_test.dart
index 6d78eb0..1741227 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/use_rethrow_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/use_rethrow_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/wrap_in_future_test.dart b/pkg/analysis_server/test/src/services/correction/fix/wrap_in_future_test.dart
index b86e482..f7ff631 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/wrap_in_future_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/wrap_in_future_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/wrap_in_text_test.dart b/pkg/analysis_server/test/src/services/correction/fix/wrap_in_text_test.dart
index bca0c26..60f9b0d 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/wrap_in_text_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/wrap_in_text_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/test_all.dart b/pkg/analysis_server/test/src/services/correction/test_all.dart
index abc5ddb..96c3fa6 100644
--- a/pkg/analysis_server/test/src/services/correction/test_all.dart
+++ b/pkg/analysis_server/test/src/services/correction/test_all.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
+
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'assist/test_all.dart' as assist_all;
diff --git a/pkg/analysis_server/test/src/services/flutter/container_properties_test.dart b/pkg/analysis_server/test/src/services/flutter/container_properties_test.dart
index a546043..28903bc 100644
--- a/pkg/analysis_server/test/src/services/flutter/container_properties_test.dart
+++ b/pkg/analysis_server/test/src/services/flutter/container_properties_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/protocol/protocol_generated.dart' as protocol;
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/src/services/flutter/test_all.dart b/pkg/analysis_server/test/src/services/flutter/test_all.dart
index c35d704..e45512e 100644
--- a/pkg/analysis_server/test/src/services/flutter/test_all.dart
+++ b/pkg/analysis_server/test/src/services/flutter/test_all.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
+
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'container_properties_test.dart' as container_properties;
diff --git a/pkg/analysis_server/test/src/services/flutter/widget_description.dart b/pkg/analysis_server/test/src/services/flutter/widget_description.dart
index 012b925..c4042ef 100644
--- a/pkg/analysis_server/test/src/services/flutter/widget_description.dart
+++ b/pkg/analysis_server/test/src/services/flutter/widget_description.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
+
 import 'dart:convert';
 
 import 'package:analysis_server/protocol/protocol_generated.dart' as protocol;
diff --git a/pkg/analysis_server/test/src/services/flutter/widget_descriptions_test.dart b/pkg/analysis_server/test/src/services/flutter/widget_descriptions_test.dart
index a29b993..0b80cad 100644
--- a/pkg/analysis_server/test/src/services/flutter/widget_descriptions_test.dart
+++ b/pkg/analysis_server/test/src/services/flutter/widget_descriptions_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/protocol/protocol_generated.dart' as protocol;
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -244,8 +246,9 @@
 ''');
     var property = await getWidgetProperty('Text(', 'overflow');
 
+    var json = property.toJson().cast<String, dynamic>();
     expect(
-      property.toJson()['editor']['enumItems'][0]['documentation'],
+      json['editor']['enumItems'][0]['documentation'],
       startsWith('Clip the overflowing'),
     );
 
diff --git a/pkg/analysis_server/test/src/services/test_all.dart b/pkg/analysis_server/test/src/services/test_all.dart
index e5d8aa0..2c3be26 100644
--- a/pkg/analysis_server/test/src/services/test_all.dart
+++ b/pkg/analysis_server/test/src/services/test_all.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
+
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'completion/test_all.dart' as completion;
diff --git a/pkg/analysis_server/test/src/test_all.dart b/pkg/analysis_server/test/src/test_all.dart
index 0cb76aa..ce38f77 100644
--- a/pkg/analysis_server/test/src/test_all.dart
+++ b/pkg/analysis_server/test/src/test_all.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
+
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'cider/test_all.dart' as cider;
diff --git a/pkg/analysis_server/test/src/utilities/flutter_test.dart b/pkg/analysis_server/test/src/utilities/flutter_test.dart
index cce042e..c7e6fbc 100644
--- a/pkg/analysis_server/test/src/utilities/flutter_test.dart
+++ b/pkg/analysis_server/test/src/utilities/flutter_test.dart
@@ -111,14 +111,14 @@
   Widget build(BuildContext context) => null;
 }
 ''');
-    FunctionDeclaration main = testUnit.declarations[0];
-    BlockFunctionBody body = main.functionExpression.body;
-    List<Statement> statements = body.block.statements;
+    var main = testUnit.declarations[0] as FunctionDeclaration;
+    var body = main.functionExpression.body as BlockFunctionBody;
+    var statements = body.block.statements;
 
     // new MyWidget(1234);
     {
-      ExpressionStatement statement = statements[0];
-      InstanceCreationExpression creation = statement.expression;
+      var statement = statements[0] as ExpressionStatement;
+      var creation = statement.expression as InstanceCreationExpression;
       var constructorName = creation.constructorName;
       var typeName = constructorName.type;
       var argumentList = creation.argumentList;
@@ -134,8 +134,8 @@
 
     // new MyWidget.named(5678);
     {
-      ExpressionStatement statement = statements[1];
-      InstanceCreationExpression creation = statement.expression;
+      var statement = statements[1] as ExpressionStatement;
+      var creation = statement.expression as InstanceCreationExpression;
       var constructorName = creation.constructorName;
       var typeName = constructorName.type;
       var argumentList = creation.argumentList;
@@ -494,7 +494,7 @@
     {
       var expression = findNode.simple('named(); // use');
       expect(_flutter.isWidgetExpression(expression), isFalse);
-      var creation = expression.parent.parent as InstanceCreationExpression;
+      var creation = expression.parent?.parent as InstanceCreationExpression;
       expect(_flutter.isWidgetExpression(creation), isTrue);
     }
 
@@ -534,7 +534,7 @@
     }
   }
 
-  VariableDeclaration _getTopVariable(String name, [CompilationUnit unit]) {
+  VariableDeclaration _getTopVariable(String name, [CompilationUnit? unit]) {
     unit ??= testUnit;
     for (var topDeclaration in unit.declarations) {
       if (topDeclaration is TopLevelVariableDeclaration) {
@@ -549,7 +549,7 @@
   }
 
   InstanceCreationExpression _getTopVariableCreation(String name,
-      [CompilationUnit unit]) {
+      [CompilationUnit? unit]) {
     return _getTopVariable(name, unit).initializer
         as InstanceCreationExpression;
   }
diff --git a/pkg/analysis_server/test/src/utilities/mock_packages.dart b/pkg/analysis_server/test/src/utilities/mock_packages.dart
index c60002d..3df14ee 100644
--- a/pkg/analysis_server/test/src/utilities/mock_packages.dart
+++ b/pkg/analysis_server/test/src/utilities/mock_packages.dart
@@ -7,6 +7,71 @@
 import 'package:analyzer/file_system/physical_file_system.dart';
 import 'package:analyzer_utilities/package_root.dart' as package_root;
 
+void _cacheFiles(Map<String, String> cachedFiles) {
+  var resourceProvider = PhysicalResourceProvider.INSTANCE;
+  var pathContext = resourceProvider.pathContext;
+  var packageRoot = pathContext.normalize(package_root.packageRoot);
+  var mockPath = pathContext.join(
+    packageRoot,
+    'analysis_server',
+    'test',
+    'mock_packages',
+  );
+
+  void addFiles(Resource resource) {
+    if (resource is Folder) {
+      resource.getChildren().forEach(addFiles);
+    } else if (resource is File) {
+      var relativePath = pathContext.relative(
+        resource.path,
+        from: mockPath,
+      );
+      var relativePathComponents = pathContext.split(relativePath);
+      var relativePosixPath = relativePathComponents.join('/');
+      cachedFiles[relativePosixPath] = resource.readAsStringSync();
+    }
+  }
+
+  addFiles(
+    resourceProvider.getFolder(mockPath),
+  );
+}
+
+/// Helper for copying files from "tests/mock_packages" to memory file system
+/// for Bazel.
+class BazelMockPackages {
+  static final BazelMockPackages instance = BazelMockPackages._();
+
+  /// The mapping from relative Posix paths of files to the file contents.
+  final Map<String, String> _cachedFiles = {};
+
+  BazelMockPackages._() {
+    _cacheFiles(_cachedFiles);
+  }
+
+  void addFlutter(MemoryResourceProvider provider) {
+    _addFiles(provider, 'flutter');
+  }
+
+  /// Add files of the given [packageName] to the [provider].
+  Folder _addFiles(MemoryResourceProvider provider, String packageName) {
+    var packagesPath = provider.convertPath('/workspace/third_party/dart');
+
+    for (var entry in _cachedFiles.entries) {
+      var relativePosixPath = entry.key;
+      var relativePathComponents = relativePosixPath.split('/');
+      if (relativePathComponents[0] == packageName) {
+        var relativePath = provider.pathContext.joinAll(relativePathComponents);
+        var path = provider.pathContext.join(packagesPath, relativePath);
+        provider.newFile(path, entry.value);
+      }
+    }
+
+    var packagesFolder = provider.getFolder(packagesPath);
+    return packagesFolder.getChildAssumingFolder(packageName);
+  }
+}
+
 /// Helper for copying files from "tests/mock_packages" to memory file system.
 class MockPackages {
   static final MockPackages instance = MockPackages._();
@@ -15,7 +80,7 @@
   final Map<String, String> _cachedFiles = {};
 
   MockPackages._() {
-    _cacheFiles();
+    _cacheFiles(_cachedFiles);
   }
 
   Folder addFlutter(MemoryResourceProvider provider) {
@@ -47,47 +112,17 @@
   Folder _addFiles(MemoryResourceProvider provider, String packageName) {
     var packagesPath = provider.convertPath('/packages');
 
-    for (var relativePosixPath in _cachedFiles.keys) {
+    for (var entry in _cachedFiles.entries) {
+      var relativePosixPath = entry.key;
       var relativePathComponents = relativePosixPath.split('/');
       if (relativePathComponents[0] == packageName) {
         var relativePath = provider.pathContext.joinAll(relativePathComponents);
         var path = provider.pathContext.join(packagesPath, relativePath);
-        var content = _cachedFiles[relativePosixPath];
-        provider.newFile(path, content);
+        provider.newFile(path, entry.value);
       }
     }
 
     var packagesFolder = provider.getFolder(packagesPath);
     return packagesFolder.getChildAssumingFolder(packageName);
   }
-
-  void _cacheFiles() {
-    var resourceProvider = PhysicalResourceProvider.INSTANCE;
-    var pathContext = resourceProvider.pathContext;
-    var packageRoot = pathContext.normalize(package_root.packageRoot);
-    var mockPath = pathContext.join(
-      packageRoot,
-      'analysis_server',
-      'test',
-      'mock_packages',
-    );
-
-    void addFiles(Resource resource) {
-      if (resource is Folder) {
-        resource.getChildren().forEach(addFiles);
-      } else if (resource is File) {
-        var relativePath = pathContext.relative(
-          resource.path,
-          from: mockPath,
-        );
-        var relativePathComponents = pathContext.split(relativePath);
-        var relativePosixPath = relativePathComponents.join('/');
-        _cachedFiles[relativePosixPath] = resource.readAsStringSync();
-      }
-    }
-
-    addFiles(
-      resourceProvider.getFolder(mockPath),
-    );
-  }
 }
diff --git a/pkg/analysis_server/test/src/utilities/profiling_test.dart b/pkg/analysis_server/test/src/utilities/profiling_test.dart
index 0485511..de9f186 100644
--- a/pkg/analysis_server/test/src/utilities/profiling_test.dart
+++ b/pkg/analysis_server/test/src/utilities/profiling_test.dart
@@ -19,10 +19,9 @@
     });
 
     test('getProcessUsage', () async {
-      var profiler = ProcessProfiler.getProfilerForPlatform();
-      var info = await profiler.getProcessUsage(pid);
+      var profiler = ProcessProfiler.getProfilerForPlatform()!;
+      var info = (await profiler.getProcessUsage(pid))!;
 
-      expect(info, isNotNull);
       expect(info.cpuPercentage, greaterThanOrEqualTo(0.0));
       expect(info.memoryKB, greaterThanOrEqualTo(0));
     });
diff --git a/pkg/analysis_server/test/stress/completion/completion.dart b/pkg/analysis_server/test/stress/completion/completion.dart
index b2b30f5..2f5fee0 100644
--- a/pkg/analysis_server/test/stress/completion/completion.dart
+++ b/pkg/analysis_server/test/stress/completion/completion.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
+
 import 'dart:io';
 
 import 'package:args/args.dart';
diff --git a/pkg/analysis_server/test/stress/completion/completion_runner.dart b/pkg/analysis_server/test/stress/completion/completion_runner.dart
index 7a1d675..0de5088 100644
--- a/pkg/analysis_server/test/stress/completion/completion_runner.dart
+++ b/pkg/analysis_server/test/stress/completion/completion_runner.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
+
 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';
diff --git a/pkg/analysis_server/test/stress/replay/replay.dart b/pkg/analysis_server/test/stress/replay/replay.dart
index cc487bb..5837c7d 100644
--- a/pkg/analysis_server/test/stress/replay/replay.dart
+++ b/pkg/analysis_server/test/stress/replay/replay.dart
@@ -60,32 +60,32 @@
   static String VERBOSE_FLAG_NAME = 'verbose';
 
   /// The style of interaction to use for analysis.updateContent requests.
-  OverlayStyle overlayStyle;
+  late OverlayStyle overlayStyle;
 
   /// The absolute path of the repository.
-  String repositoryPath;
+  late String repositoryPath;
 
   /// The absolute paths to the analysis roots.
-  List<String> analysisRoots;
+  late List<String> analysisRoots;
 
   /// The git repository.
-  GitRepository repository;
+  late GitRepository repository;
 
   /// The connection to the analysis server.
-  Server server;
+  late Server server;
 
   /// A list of the glob patterns used to identify the files being analyzed by
   /// the server.
-  List<Glob> fileGlobs;
+  late List<Glob> fileGlobs;
 
   /// An object gathering statistics about the simulation.
-  Statistics statistics;
+  late Statistics statistics;
 
   /// A flag indicating whether verbose output should be provided.
   bool verbose = false;
 
   /// The logger to which verbose logging data will be written.
-  Logger logger;
+  late Logger logger;
 
   /// Initialize a newly created driver.
   Driver() {
@@ -217,7 +217,7 @@
   List<int> _getBreakOffsets(String text) {
     var breakOffsets = <int>[];
     var featureSet = FeatureSet.forTesting(sdkVersion: '2.2.2');
-    var scanner = Scanner(null, CharSequenceReader(text),
+    var scanner = Scanner(_TestSource(), CharSequenceReader(text),
         error.AnalysisErrorListener.NULL_LISTENER)
       ..configureFeatures(
         featureSetForOverriding: featureSet,
@@ -234,7 +234,7 @@
       if (token.type == TokenType.IDENTIFIER && length > 3) {
         breakOffsets.add(offset + (length ~/ 2));
       }
-      token = token.next;
+      token = token.next!;
     }
     return breakOffsets;
   }
@@ -313,8 +313,8 @@
       // Iterate over the history, applying changes.
       //
       var firstCheckout = true;
-      ErrorMap expectedErrors;
-      Iterable<String> changedPubspecs;
+      ErrorMap? expectedErrors;
+      late Iterable<String> changedPubspecs;
       while (iterator.moveNext()) {
         //
         // Checkout the commit on which the changes are based.
@@ -414,8 +414,7 @@
   /// Run the simulation by starting up a server and sending it requests.
   Future<void> _runSimulation() async {
     server = Server(logger: logger);
-    var stopwatch = Stopwatch();
-    statistics.stopwatch = stopwatch;
+    var stopwatch = statistics.stopwatch;
     stopwatch.start();
     await server.start();
     server.sendServerSetSubscriptions([ServerService.STATUS]);
@@ -441,7 +440,7 @@
   }
 
   /// Display usage information, preceded by the [errorMessage] if one is given.
-  void _showUsage(ArgParser parser, [String errorMessage]) {
+  void _showUsage(ArgParser parser, [String? errorMessage]) {
     if (errorMessage != null) {
       stderr.writeln(errorMessage);
       stderr.writeln();
@@ -472,25 +471,25 @@
   OverlayStyle overlayStyle;
 
   /// The absolute path of the file to be edited.
-  String filePath;
+  late String filePath;
 
   /// The content of the file before any edits have been applied.
-  String content;
+  late String content;
 
   /// The line info for the file before any edits have been applied.
-  LineInfo lineInfo;
+  late LineInfo lineInfo;
 
   /// The lists of source edits, one list for each hunk being edited.
   List<List<SourceEdit>> editLists = <List<SourceEdit>>[];
 
   /// The current content of the file. This field is only used if the overlay
   /// style is [OverlayStyle.multipleAdd].
-  String currentContent;
+  late String currentContent;
 
   /// Initialize a collection of edits to be associated with the file at the
   /// given [filePath].
   FileEdit(this.overlayStyle, DiffRecord record) {
-    filePath = record.srcPath;
+    filePath = record.srcPath!;
     if (record.isAddition) {
       content = '';
       lineInfo = LineInfo(<int>[0]);
@@ -531,9 +530,7 @@
         } else {
           throw StateError('Failed to handle overlay style = $overlayStyle');
         }
-        if (overlay != null) {
-          addUpdateContent(overlay);
-        }
+        addUpdateContent(overlay);
       }
     }
     addUpdateContent(RemoveContentOverlay());
@@ -551,10 +548,10 @@
   final Driver driver;
 
   /// The stopwatch being used to time the simulation.
-  Stopwatch stopwatch;
+  Stopwatch stopwatch = Stopwatch();
 
   /// The total number of commits in the repository.
-  int commitCount;
+  int commitCount = 0;
 
   /// The number of commits in the repository that touched one of the files in
   /// one of the analysis roots.
@@ -600,3 +597,11 @@
     return '$seconds.$milliseconds';
   }
 }
+
+class _TestSource implements Source {
+  @override
+  String get fullName => '/package/lib/test.dart';
+
+  @override
+  dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
diff --git a/pkg/analysis_server/test/stress/utilities/git.dart b/pkg/analysis_server/test/stress/utilities/git.dart
index 7993e44..05cc2a3 100644
--- a/pkg/analysis_server/test/stress/utilities/git.dart
+++ b/pkg/analysis_server/test/stress/utilities/git.dart
@@ -39,9 +39,9 @@
   void _parseLine(String line) {
     var currentHunk = hunks.isEmpty ? null : hunks.last;
     if (line.startsWith('@@')) {
-      var match = hunkHeaderRegExp.matchAsPrefix(line);
-      var srcLine = int.parse(match.group(1));
-      var dstLine = int.parse(match.group(2));
+      var match = hunkHeaderRegExp.matchAsPrefix(line)!;
+      var srcLine = int.parse(match.group(1)!);
+      var dstLine = int.parse(match.group(2)!);
       hunks.add(DiffHunk(srcLine, dstLine));
     } else if (currentHunk != null && line.startsWith('+')) {
       currentHunk.addLines.add(line.substring(1));
@@ -88,7 +88,7 @@
   Iterable<String> filesMatching(String fileName) {
     return diffRecords
         .where((DiffRecord record) => record.isFor(fileName))
-        .map((DiffRecord record) => record.srcPath);
+        .map((DiffRecord record) => record.srcPath!);
   }
 
   /// Remove any diffs for files that are either (a) outside the given
@@ -96,7 +96,7 @@
   /// [globPatterns].
   void filterDiffs(List<String> inclusionPaths, List<Glob> globPatterns) {
     diffRecords.retainWhere((DiffRecord record) {
-      var filePath = record.srcPath ?? record.dstPath;
+      var filePath = (record.srcPath ?? record.dstPath)!;
       for (var inclusionPath in inclusionPaths) {
         if (path.isWithin(inclusionPath, filePath)) {
           for (var glob in globPatterns) {
@@ -175,7 +175,7 @@
     var srcPath = _makeAbsolute(input.substring(startIndex, endIndex));
     startIndex = endIndex + 1;
     // Parse field 14
-    String dstPath;
+    String? dstPath;
     if (status.startsWith('C') || status.startsWith('R')) {
       endIndex = _findEnd(input, startIndex);
       dstPath = _makeAbsolute(input.substring(startIndex, endIndex));
@@ -254,10 +254,10 @@
   final String status;
 
   /// The path of the src.
-  final String srcPath;
+  final String? srcPath;
 
   /// The path of the dst if this was either a copy or a rename operation.
-  final String dstPath;
+  final String? dstPath;
 
   /// Initialize a newly created diff record.
   DiffRecord(this.repository, this.srcBlob, this.dstBlob, this.status,
@@ -286,12 +286,15 @@
   BlobDiff getBlobDiff() => repository.getBlobDiff(srcBlob, dstBlob);
 
   /// Return `true` if this diff applies to a file with the given name.
-  bool isFor(String fileName) =>
-      (srcPath != null && fileName == path.basename(srcPath)) ||
-      (dstPath != null && fileName == path.basename(dstPath));
+  bool isFor(String fileName) {
+    var srcPath = this.srcPath;
+    var dstPath = this.dstPath;
+    return (srcPath != null && fileName == path.basename(srcPath)) ||
+        (dstPath != null && fileName == path.basename(dstPath));
+  }
 
   @override
-  String toString() => srcPath ?? dstPath;
+  String toString() => srcPath ?? dstPath ?? '<unknown>';
 }
 
 /// A representation of a git repository.
@@ -301,7 +304,7 @@
 
   /// The logger to which git commands should be written, or `null` if the
   /// commands should not be written.
-  final Logger logger;
+  final Logger? logger;
 
   /// Initialize a newly created repository to represent the git repository at
   /// the given [path].
@@ -385,7 +388,7 @@
   final LinearCommitHistory history;
 
   /// The index of the current commit in the list of [commitIds].
-  int currentCommit;
+  late int currentCommit;
 
   /// Initialize a newly created iterator to iterate over the commits with the
   /// given [commitIds];
diff --git a/pkg/analysis_server/test/stress/utilities/logger.dart b/pkg/analysis_server/test/stress/utilities/logger.dart
index 00d99fb..8e1d937 100644
--- a/pkg/analysis_server/test/stress/utilities/logger.dart
+++ b/pkg/analysis_server/test/stress/utilities/logger.dart
@@ -21,7 +21,7 @@
   /// The [label] is used to indicate the kind of information being logged,
   /// while the [content] contains the actual information. If a list of
   /// [arguments] is provided, then they will be written after the content.
-  void log(String label, String content, {List<String> arguments}) {
+  void log(String label, String content, {List<String>? arguments}) {
     for (var i = _labelWidth - label.length; i > 0; i--) {
       sink.write(' ');
     }
diff --git a/pkg/analysis_server/test/stress/utilities/server.dart b/pkg/analysis_server/test/stress/utilities/server.dart
index 5e652d2..888056a 100644
--- a/pkg/analysis_server/test/stress/utilities/server.dart
+++ b/pkg/analysis_server/test/stress/utilities/server.dart
@@ -48,36 +48,36 @@
   /// The method that was requested.
   final String method;
 
-  /// The request parameters.
-  final Map<String, dynamic> params;
+  /// The request parameters, or `null` if there are no parameters.
+  final Map<String, dynamic>? params;
 
   /// The time at which the request was sent.
   final int requestTime;
 
   /// The time at which the response was received, or `null` if no response has
   /// been received.
-  int responseTime;
+  int? responseTime;
 
   /// The response that was received.
-  Response _response;
+  Response? _response;
 
   /// The completer that will be completed when a response is received.
-  Completer<Response> _responseCompleter;
+  Completer<Response>? _responseCompleter;
 
   /// Initialize a newly created set of request data.
   RequestData(this.id, this.method, this.params, this.requestTime);
 
   /// Return the number of milliseconds that elapsed between the request and the
   /// response. This getter assumes that the response was received.
-  int get elapsedTime => responseTime - requestTime;
+  int get elapsedTime => responseTime! - requestTime;
 
   /// Return a future that will complete when a response is received.
   Future<Response> get respondedTo {
     if (_response != null) {
       return Future.value(_response);
     }
-    _responseCompleter ??= Completer<Response>();
-    return _responseCompleter.future;
+    var completer = _responseCompleter ??= Completer<Response>();
+    return completer.future;
   }
 
   /// Record that the given [response] was received.
@@ -89,8 +89,9 @@
     }
     responseTime = currentTime;
     _response = response;
-    if (_responseCompleter != null) {
-      _responseCompleter.complete(response);
+    var completer = _responseCompleter;
+    if (completer != null) {
+      completer.complete(response);
       _responseCompleter = null;
     }
   }
@@ -110,11 +111,11 @@
 
   /// The logger to which the communications log should be written, or `null` if
   /// the log should not be written.
-  final Logger logger;
+  final Logger? logger;
 
   /// The process in which the server is running, or `null` if the server hasn't
   /// been started yet.
-  Process _process;
+  Process? _process;
 
   /// Number that should be used to compute the 'id' to send in the next command
   /// sent to the server.
@@ -136,11 +137,11 @@
 
   /// The completer that will be completed the next time a 'server.status'
   /// notification is received from the server with 'analyzing' set to false.
-  Completer<void> _analysisFinishedCompleter;
+  Completer<void>? _analysisFinishedCompleter;
 
   /// The completer that will be completed the next time a 'server.connected'
   /// notification is received from the server.
-  Completer<void> _serverConnectedCompleter;
+  Completer<void>? _serverConnectedCompleter;
 
   /// A table mapping the ids of requests that have been sent to the server to
   /// data about those requests.
@@ -165,8 +166,8 @@
   /// multiple times in one test; each time it is used it will wait afresh for
   /// analysis to finish.
   Future get analysisFinished {
-    _analysisFinishedCompleter ??= Completer<void>();
-    return _analysisFinishedCompleter.future;
+    var completer = _analysisFinishedCompleter ??= Completer<void>();
+    return completer.future;
   }
 
   /// Return a list of the paths of files that are currently being analyzed.
@@ -241,7 +242,7 @@
           .fold(0, (int count, List<RequestData> list) => count + list.length);
       var countWidth = maxCount.toString().length;
       for (var key in keys) {
-        var requests = requestsByMethod[key];
+        var requests = requestsByMethod[key]!;
         var noResponseCount = 0;
         var responseCount = 0;
         var minTime = -1;
@@ -306,7 +307,7 @@
 
   /// Remove any existing overlays.
   void removeAllOverlays() {
-    Map<String, dynamic> files = HashMap<String, dynamic>();
+    var files = <String, Object>{};
     for (var path in filesWithOverlays) {
       files[path] = RemoveContentOverlay();
     }
@@ -344,7 +345,7 @@
 
   void sendAnalysisSetAnalysisRoots(
       List<String> included, List<String> excluded,
-      {Map<String, String> packageRoots}) {
+      {Map<String, String>? packageRoots}) {
     _analysisRootIncludes = included;
     var params = AnalysisSetAnalysisRootsParams(included, excluded,
             packageRoots: packageRoots)
@@ -369,8 +370,8 @@
     _send('analysis.setSubscriptions', params);
   }
 
-  void sendAnalysisUpdateContent(Map<String, dynamic> files) {
-    files.forEach((String path, dynamic overlay) {
+  void sendAnalysisUpdateContent(Map<String, Object> files) {
+    files.forEach((path, overlay) {
       if (overlay is AddContentOverlay) {
         filesWithOverlays.add(path);
       } else if (overlay is RemoveContentOverlay) {
@@ -397,7 +398,7 @@
 
   RequestData sendEditFormat(
       String file, int selectionOffset, int selectionLength,
-      {int lineLength}) {
+      {int? lineLength}) {
     var params = EditFormatParams(file, selectionOffset, selectionLength,
             lineLength: lineLength)
         .toJson();
@@ -423,7 +424,7 @@
 
   RequestData sendEditGetRefactoring(RefactoringKind kind, String file,
       int offset, int length, bool validateOnly,
-      {RefactoringOptions options}) {
+      {RefactoringOptions? options}) {
     var params = EditGetRefactoringParams(
             kind, file, offset, length, validateOnly,
             options: options)
@@ -451,7 +452,7 @@
     return _send('execution.deleteContext', params);
   }
 
-  RequestData sendExecutionMapUri(String id, {String file, String uri}) {
+  RequestData sendExecutionMapUri(String id, {String? file, String? uri}) {
     var params = ExecutionMapUriParams(id, file: file, uri: uri).toJson();
     return _send('execution.mapUri', params);
   }
@@ -485,7 +486,7 @@
     _send('search.findTopLevelDeclarations', params);
   }
 
-  void sendSearchGetTypeHierarchy(String file, int offset, {bool superOnly}) {
+  void sendSearchGetTypeHierarchy(String file, int offset, {bool? superOnly}) {
     var params =
         SearchGetTypeHierarchyParams(file, offset, superOnly: superOnly)
             .toJson();
@@ -519,10 +520,10 @@
   /// highlight APIs.
   Future<void> start(
       {bool checked = true,
-      int diagnosticPort,
+      int? diagnosticPort,
       bool profileServer = false,
-      String sdkPath,
-      int servicesPort,
+      String? sdkPath,
+      int? servicesPort,
       bool useAnalysisHighlight2 = false}) async {
     if (_process != null) {
       throw Exception('Process already started');
@@ -571,14 +572,15 @@
 //    stdout.writeln('Launching $serverPath');
 //    stdout.writeln('$dartBinary ${arguments.join(' ')}');
     _process = await Process.start(dartBinary, arguments);
-    _process.exitCode.then((int code) {
+    _process!.exitCode.then((int code) {
       if (code != 0) {
         throw StateError('Server terminated with exit code $code');
       }
     });
     _listenToOutput();
-    _serverConnectedCompleter = Completer<void>();
-    return _serverConnectedCompleter.future;
+    var completer = Completer<void>();
+    _serverConnectedCompleter = completer;
+    return completer.future;
   }
 
   /// Find the root directory of the analysis_server package by proceeding
@@ -599,18 +601,17 @@
     switch (notification.event) {
       case 'server.connected':
 //        new ServerConnectedParams.fromNotification(notification);
-        _serverConnectedCompleter.complete(null);
+        _serverConnectedCompleter!.complete(null);
         break;
       case 'server.error':
 //        new ServerErrorParams.fromNotification(notification);
         throw StateError('Server error: ${notification.toJson()}');
-        break;
       case 'server.status':
         if (_analysisFinishedCompleter != null) {
           var params = ServerStatusParams.fromNotification(notification);
           var analysis = params.analysis;
           if (analysis != null && !analysis.isAnalyzing) {
-            _analysisFinishedCompleter.complete(null);
+            _analysisFinishedCompleter!.complete(null);
           }
         }
         break;
@@ -667,7 +668,7 @@
   /// Handle a [response] received from the server.
   void _handleResponse(Response response) {
     var id = response.id.toString();
-    var requestData = _requestDataMap[id];
+    var requestData = _requestDataMap[id]!;
     requestData.recordResponse(response);
 //    switch (requestData.method) {
 //      case "analysis.getErrors":
@@ -752,8 +753,8 @@
   void _handleStdOut(String line) {
     /// Cast the given [value] to a Map, or throw an [ArgumentError] if the
     /// value cannot be cast.
-    Map asMap(Object value) {
-      if (value is Map) {
+    Map<String, Object?> asMap(Object value) {
+      if (value is Map<String, Object?>) {
         return value;
       }
       throw ArgumentError('Expected a Map, found a ${value.runtimeType}');
@@ -768,7 +769,7 @@
     var message = asMap(json.decoder.convert(trimmedLine));
     if (message.containsKey('id')) {
       // The message is a response.
-      var response = Response.fromJson(message);
+      var response = Response.fromJson(message)!;
       _handleResponse(response);
     } else {
       // The message is a notification.
@@ -791,12 +792,12 @@
           .listen(handler);
     }
 
-    installHandler(_process.stdout, _handleStdOut);
-    installHandler(_process.stderr, _handleStdErr);
+    installHandler(_process!.stdout, _handleStdOut);
+    installHandler(_process!.stderr, _handleStdErr);
   }
 
   /// Send a command to the server. An 'id' will be automatically assigned.
-  RequestData _send(String method, Map<String, dynamic> params) {
+  RequestData _send(String method, Map<String, dynamic>? params) {
     var id = '${_nextId++}';
     var requestData = RequestData(id, method, params, currentTime);
     _requestDataMap[id] = requestData;
@@ -805,7 +806,7 @@
       command['params'] = params;
     }
     var line = json.encode(command);
-    _process.stdin.add(utf8.encoder.convert('$line\n'));
+    _process!.stdin.add(utf8.encoder.convert('$line\n'));
     logger?.log(fromClient, '$line');
     return requestData;
   }
diff --git a/pkg/analysis_server/test/test_all.dart b/pkg/analysis_server/test/test_all.dart
index eca22e0..a042a4f 100644
--- a/pkg/analysis_server/test/test_all.dart
+++ b/pkg/analysis_server/test/test_all.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
+
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import '../tool/spec/check_all_test.dart' as check_spec;
diff --git a/pkg/analysis_server/test/timing/completion/completion_simple.dart b/pkg/analysis_server/test/timing/completion/completion_simple.dart
index 1c7b41d..3984325 100644
--- a/pkg/analysis_server/test/timing/completion/completion_simple.dart
+++ b/pkg/analysis_server/test/timing/completion/completion_simple.dart
@@ -29,17 +29,17 @@
 /// minor change inside a method body.
 class SimpleTest extends TimingTest {
   /// The path to the file in which code completion is to be performed.
-  String mainFilePath;
+  late String mainFilePath;
 
   /// The original content of the file.
-  String originalContent;
+  late String originalContent;
 
   /// The offset of the cursor when requesting code completion.
-  int cursorOffset;
+  late int cursorOffset;
 
   /// A completer that will be completed when code completion results have been
   /// received from the server.
-  Completer completionReceived;
+  late Completer completionReceived;
 
   /// Initialize a newly created test.
   SimpleTest();
diff --git a/pkg/analysis_server/test/timing/timing_framework.dart b/pkg/analysis_server/test/timing/timing_framework.dart
index f7d6da1..b9eb6d0 100644
--- a/pkg/analysis_server/test/timing/timing_framework.dart
+++ b/pkg/analysis_server/test/timing/timing_framework.dart
@@ -115,10 +115,10 @@
 
   /// The connection to the analysis server.
   @override
-  Server server;
+  late Server server;
 
   /// The temporary directory in which source files can be stored.
-  Directory sourceDirectory;
+  late Directory sourceDirectory;
 
   /// A flag indicating whether the teardown process should skip sending a
   /// "server.shutdown" request because the server is known to have already
@@ -212,7 +212,7 @@
 
   /// Repeatedly execute this test [count] times, adding timing information to
   /// the given list of [times] if it is non-`null`.
-  Future _repeat(int count, List<int> times) {
+  Future _repeat(int count, List<int>? times) {
     var stopwatch = Stopwatch();
     return setUp().then((_) {
       stopwatch.start();
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 5da637c..9b0865d 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
@@ -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
+
 import 'package:test/test.dart';
 
 import '../../../tool/code_completion/metrics_util.dart';
diff --git a/pkg/analysis_server/test/tool/completion_metrics/test_all.dart b/pkg/analysis_server/test/tool/completion_metrics/test_all.dart
index 8ca30d9..2a7e8b3 100644
--- a/pkg/analysis_server/test/tool/completion_metrics/test_all.dart
+++ b/pkg/analysis_server/test/tool/completion_metrics/test_all.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
+
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'metrics_util_test.dart' as metrics_util_test;
diff --git a/pkg/analysis_server/test/tool/lsp_spec/dart_test.dart b/pkg/analysis_server/test/tool/lsp_spec/dart_test.dart
index 7ead849..ea05eed 100644
--- a/pkg/analysis_server/test/tool/lsp_spec/dart_test.dart
+++ b/pkg/analysis_server/test/tool/lsp_spec/dart_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.
 
+// @dart = 2.9
+
 import 'package:test/test.dart';
 
 import '../../../tool/lsp_spec/typescript_parser.dart' as ast;
diff --git a/pkg/analysis_server/test/tool/lsp_spec/generated_classes_test.dart b/pkg/analysis_server/test/tool/lsp_spec/generated_classes_test.dart
index a506de9..3b034df 100644
--- a/pkg/analysis_server/test/tool/lsp_spec/generated_classes_test.dart
+++ b/pkg/analysis_server/test/tool/lsp_spec/generated_classes_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.
 
+// @dart = 2.9
+
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:analysis_server/lsp_protocol/protocol_special.dart';
 import 'package:test/test.dart';
diff --git a/pkg/analysis_server/test/tool/lsp_spec/json_test.dart b/pkg/analysis_server/test/tool/lsp_spec/json_test.dart
index 4e32945..e0b9720 100644
--- a/pkg/analysis_server/test/tool/lsp_spec/json_test.dart
+++ b/pkg/analysis_server/test/tool/lsp_spec/json_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.
 
+// @dart = 2.9
+
 import 'dart:convert';
 
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
diff --git a/pkg/analysis_server/test/tool/lsp_spec/matchers.dart b/pkg/analysis_server/test/tool/lsp_spec/matchers.dart
index e5ed507..8fa3f4f 100644
--- a/pkg/analysis_server/test/tool/lsp_spec/matchers.dart
+++ b/pkg/analysis_server/test/tool/lsp_spec/matchers.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
+
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:matcher/matcher.dart';
 
diff --git a/pkg/analysis_server/test/tool/lsp_spec/test_all.dart b/pkg/analysis_server/test/tool/lsp_spec/test_all.dart
index 07a4247..0b98b69 100644
--- a/pkg/analysis_server/test/tool/lsp_spec/test_all.dart
+++ b/pkg/analysis_server/test/tool/lsp_spec/test_all.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
+
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'dart_test.dart' as dart_test;
diff --git a/pkg/analysis_server/test/tool/lsp_spec/typescript_test.dart b/pkg/analysis_server/test/tool/lsp_spec/typescript_test.dart
index b439e68..3c69370 100644
--- a/pkg/analysis_server/test/tool/lsp_spec/typescript_test.dart
+++ b/pkg/analysis_server/test/tool/lsp_spec/typescript_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.
 
+// @dart = 2.9
+
 import 'package:test/test.dart';
 
 import '../../../tool/lsp_spec/typescript_parser.dart';
diff --git a/pkg/analysis_server/test/tool/test_all.dart b/pkg/analysis_server/test/tool/test_all.dart
index 8d2910e..4852a64 100644
--- a/pkg/analysis_server/test/tool/test_all.dart
+++ b/pkg/analysis_server/test/tool/test_all.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
+
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'completion_metrics/test_all.dart' as completion_metrics;
diff --git a/pkg/analysis_server/test/utils/test_instrumentation_service.dart b/pkg/analysis_server/test/utils/test_instrumentation_service.dart
index f271860..bd43ac2 100644
--- a/pkg/analysis_server/test/utils/test_instrumentation_service.dart
+++ b/pkg/analysis_server/test/utils/test_instrumentation_service.dart
@@ -2,18 +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/exception/exception.dart';
 import 'package:analyzer/instrumentation/service.dart';
 
 /// Implementation of [InstrumentationService] that throws on [logException].
 class TestInstrumentationService implements InstrumentationService {
   @override
   void logException(
-    exception, [
-    StackTrace stackTrace,
-    List<InstrumentationServiceAttachment> attachments = const [],
+    Object exception, [
+    StackTrace? stackTrace,
+    List<InstrumentationServiceAttachment>? attachments,
   ]) {
-    throw CaughtException(exception, stackTrace);
+    throw StateError('$exception\n\n$stackTrace');
   }
 
   @override
diff --git a/pkg/analysis_server/test/utils/test_support.dart b/pkg/analysis_server/test/utils/test_support.dart
index 811d8ce..c3f4888 100644
--- a/pkg/analysis_server/test/utils/test_support.dart
+++ b/pkg/analysis_server/test/utils/test_support.dart
@@ -23,7 +23,7 @@
   final int length;
 
   /// The message text for the error.
-  final String text;
+  final String? text;
 
   ExpectedContextMessage(this.filePath, this.offset, this.length, {this.text});
 
@@ -51,12 +51,13 @@
   /// The offset of the beginning of the error's region.
   final int length;
 
-  /// The message text of the error or `null` if the message should not be checked.
-  final String message;
+  /// The message text of the error or `null` if the message should not be
+  /// checked.
+  final String? message;
 
-  /// A pattern that should be contained in the error message or `null` if the message
-  /// contents should not be checked.
-  final Pattern messageContains;
+  /// A pattern that should be contained in the error message or `null` if the
+  /// message contents should not be checked.
+  final Pattern? messageContains;
 
   /// The list of context messages that are expected to be associated with the
   /// error.
@@ -79,8 +80,9 @@
     if (message != null && error.message != message) {
       return false;
     }
+    var messageContains = this.messageContains;
     if (messageContains != null &&
-        error.message?.contains(messageContains) != true) {
+        error.message.contains(messageContains) != true) {
       return false;
     }
     var contextMessages = error.contextMessages.toList();
@@ -357,7 +359,7 @@
 
   /// Return the line information associated with the given [source], or `null`
   /// if no line information has been associated with the source.
-  LineInfo getLineInfo(Source source) => _lineInfoMap[source];
+  LineInfo? getLineInfo(Source source) => _lineInfoMap[source];
 
   /// Return `true` if an error with the given [errorCode] has been gathered.
   bool hasError(ErrorCode errorCode) {
diff --git a/pkg/analysis_server/test/verify_sorted_test.dart b/pkg/analysis_server/test/verify_sorted_test.dart
index 869d702..dff52dd 100644
--- a/pkg/analysis_server/test/verify_sorted_test.dart
+++ b/pkg/analysis_server/test/verify_sorted_test.dart
@@ -9,7 +9,6 @@
 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';
 
 void main() {
@@ -31,8 +30,8 @@
 }
 
 void buildTests({
-  @required String packagePath,
-  @required List<String> excludedPaths,
+  required String packagePath,
+  required List<String> excludedPaths,
 }) {
   var provider = PhysicalResourceProvider.INSTANCE;
   var pkgRootPath = provider.pathContext.normalize(packageRoot);
diff --git a/pkg/analysis_server/test/verify_tests_test.dart b/pkg/analysis_server/test/verify_tests_test.dart
index 4b07a76..3277acc 100644
--- a/pkg/analysis_server/test/verify_tests_test.dart
+++ b/pkg/analysis_server/test/verify_tests_test.dart
@@ -18,7 +18,7 @@
 }
 
 class _VerifyTests extends VerifyTests {
-  _VerifyTests(String testDirPath, {List<String> excludedPaths})
+  _VerifyTests(String testDirPath, {List<String>? excludedPaths})
       : super(testDirPath, excludedPaths: excludedPaths);
 
   @override
diff --git a/pkg/analysis_server/tool/bulk_fix/supported_lints.dart b/pkg/analysis_server/tool/bulk_fix/supported_lints.dart
index 135c10c..85a6eae 100644
--- a/pkg/analysis_server/tool/bulk_fix/supported_lints.dart
+++ b/pkg/analysis_server/tool/bulk_fix/supported_lints.dart
@@ -2,12 +2,14 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+// @dart = 2.9
+
 import 'package:analysis_server/src/services/correction/fix_internal.dart';
 
 /// Print lints that are bulk-fixable in a format that can be included in
 /// analysis options.
 void main() {
-  final bulkFixCodes = FixProcessor.lintProducerMap2.entries
+  final bulkFixCodes = FixProcessor.lintProducerMap.entries
       .where((e) => e.value.where((fix) => fix.canBeBulkApplied).isNotEmpty)
       .map((e) => e.key);
   print('    # bulk-fixable lints');
diff --git a/pkg/analysis_server/tool/code_completion/code_metrics.dart b/pkg/analysis_server/tool/code_completion/code_metrics.dart
index 97510ff..27585c6 100644
--- a/pkg/analysis_server/tool/code_completion/code_metrics.dart
+++ b/pkg/analysis_server/tool/code_completion/code_metrics.dart
@@ -50,7 +50,7 @@
 }
 
 /// Print usage information for this tool.
-void printUsage(ArgParser parser, {String error}) {
+void printUsage(ArgParser parser, {String? error}) {
   if (error != null) {
     print(error);
     print('');
@@ -110,7 +110,7 @@
   /// Record that an element of the given [node] was found in the given
   /// [context].
   void recordNode(String nodeClassName, String property, AstNode node) {
-    var childClass = node?.runtimeType?.toString() ?? 'null';
+    var childClass = node.runtimeType.toString();
     if (childClass.endsWith('Impl')) {
       childClass = childClass.substring(0, childClass.length - 4);
     }
@@ -134,7 +134,7 @@
     classMap[parentClassName] = (classMap[parentClassName] ?? 0) + 1;
   }
 
-  void recordToken(String nodeClassName, String property, Token token) {
+  void recordToken(String nodeClassName, String property, Token? token) {
     var lexeme = token?.lexeme ?? 'null';
     _recordChildData(nodeClassName, property, lexeme);
   }
@@ -1311,7 +1311,7 @@
   /// Visit the children of a node. The node is an instance of the class named
   /// [parentClass] and the children are in the [childMap], keyed by the name of
   /// the child property.
-  void _visitChildren(AstNode node, Map<String, Object> childMap) {
+  void _visitChildren(AstNode node, Map<String, Object?> childMap) {
     var nodeClassName = _className(node);
 
     data.recordNodeClass(nodeClassName);
@@ -1331,7 +1331,7 @@
       } else if (child is NodeList) {
         data.recordNodeList(nodeClassName, property, child);
         visitChildren.addAll(child);
-      } else if (child is Token || child == null) {
+      } else if (child is Token?) {
         data.recordToken(nodeClassName, property, child);
       } else {
         throw ArgumentError('Unknown class of child: ${child.runtimeType}');
@@ -1411,7 +1411,7 @@
             continue;
           }
 
-          resolvedUnitResult.unit.accept(collector);
+          resolvedUnitResult.unit!.accept(collector);
         } catch (exception) {
           print('Exception caught analyzing: "$filePath"');
           print(exception.toString());
@@ -1424,9 +1424,6 @@
   /// column occupied by the map.
   List<String> _convertMap<T extends Object>(String context, Map<T, int> map) {
     var columns = <String>[];
-    if (map == null) {
-      return columns;
-    }
     var entries = map.entries.toList()
       ..sort((first, second) {
         return second.value.compareTo(first.value);
diff --git a/pkg/analysis_server/tool/code_completion/completion_metrics.dart b/pkg/analysis_server/tool/code_completion/completion_metrics.dart
index 4b13c5a8..d5b2d61 100644
--- a/pkg/analysis_server/tool/code_completion/completion_metrics.dart
+++ b/pkg/analysis_server/tool/code_completion/completion_metrics.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
+
 import 'dart:convert';
 import 'dart:io' as io;
 import 'dart:math' as math;
@@ -106,33 +108,11 @@
   print('');
   print('Metrics computed in $duration');
 
-  File uniqueDataFile() {
-    var dataDir = result['mapDir'];
-    var baseFileName = provider.pathContext.basename(rootPath);
-    var index = 1;
-    while (index < 10000) {
-      var suffix = (index++).toString();
-      suffix = '0000'.substring(suffix.length) + suffix + '.json';
-      var fileName = baseFileName + suffix;
-      var filePath = provider.pathContext.join(dataDir, fileName);
-      var file = provider.getFile(filePath);
-      if (!file.exists) {
-        return file;
-      }
-    }
-
-    /// If there are more than 10000 directories with the same name, just
-    /// overwrite a previously generated file.
-    var fileName = baseFileName + '9999';
-    var filePath = provider.pathContext.join(dataDir, fileName);
-    return provider.getFile(filePath);
-  }
-
-  if (result.wasParsed('mapDir')) {
-    var dataFile = uniqueDataFile();
+  if (result.wasParsed('mapFile')) {
+    var mapFile = provider.getFile(result['mapFile'] as String);
     var map =
         computer.targetMetrics.map((metrics) => metrics.toJson()).toList();
-    dataFile.writeAsStringSync(json.encode(map));
+    mapFile.writeAsStringSync(json.encode(map));
   } else {
     computer.printResults();
   }
@@ -210,10 +190,10 @@
             'worst mrr scores.',
         negatable: false)
     ..addOption(
-      'mapDir',
-      help: 'The absolute path of the directory to which the completion '
-          'metrics data will be written. Using this option will prevent the '
-          'completion results from being written in a textual form.',
+      'mapFile',
+      help: 'The absolute path of the file to which the completion metrics '
+          'data will be written. Using this option will prevent the completion '
+          'results from being written in a textual form.',
     )
     ..addOption(
       'reduceDir',
@@ -247,8 +227,15 @@
     printUsage(parser, error: 'No package path specified.');
     return false;
   }
-  if (result.wasParsed('mapDir')) {
-    return validateDir(parser, result['mapDir']);
+  if (result.wasParsed('mapFile')) {
+    var mapFilePath = result['mapFile'];
+    if (mapFilePath is! String ||
+        !PhysicalResourceProvider.INSTANCE.pathContext
+            .isAbsolute(mapFilePath)) {
+      printUsage(parser,
+          error: 'The path "$mapFilePath" must be an absolute path.');
+      return false;
+    }
   }
   return validateDir(parser, result.rest[0]);
 }
@@ -1349,13 +1336,13 @@
           'contextType',
           'elementKind',
           'hasDeprecated',
-          'inheritanceDistance',
           'isConstant',
           'isNoSuchMethod',
           'keyword',
-          'localVariableDistance',
           'startsWithDollar',
-          'superMatches'
+          'superMatches',
+          'inheritanceDistance',
+          'localVariableDistance',
         ]
       ];
       for (var i = 0; i < topSuggestionCount; i++) {
@@ -1738,24 +1725,26 @@
       {double contextType = 0.0,
       double elementKind = 0.0,
       double hasDeprecated = 0.0,
-      double inheritanceDistance = 0.0,
       double isConstant = 0.0,
       double isNoSuchMethod = 0.0,
       double keyword = 0.0,
-      double localVariableDistance = 0.0,
       double startsWithDollar = 0.0,
-      double superMatches = 0.0}) {
+      double superMatches = 0.0,
+      // Dependent features
+      double inheritanceDistance = 0.0,
+      double localVariableDistance = 0.0}) {
     cachedFeatures = [
       contextType,
       elementKind,
       hasDeprecated,
-      inheritanceDistance,
       isConstant,
       isNoSuchMethod,
       keyword,
-      localVariableDistance,
       startsWithDollar,
-      superMatches
+      superMatches,
+      // Dependent features
+      inheritanceDistance,
+      localVariableDistance,
     ];
   }
 
diff --git a/pkg/analysis_server/tool/code_completion/corpus.dart b/pkg/analysis_server/tool/code_completion/corpus.dart
index 8f711d2..2bde6fe 100644
--- a/pkg/analysis_server/tool/code_completion/corpus.dart
+++ b/pkg/analysis_server/tool/code_completion/corpus.dart
@@ -65,8 +65,8 @@
 final _client = http.Client();
 
 final _homeDir = Platform.isWindows
-    ? Platform.environment['LOCALAPPDATA']
-    : Platform.environment['HOME'];
+    ? Platform.environment['LOCALAPPDATA']!
+    : Platform.environment['HOME']!;
 
 final _package_config = path.join('.dart_tool', 'package_config.json');
 
@@ -141,7 +141,13 @@
     final entries = doc.querySelectorAll('entry');
     for (var entry in entries) {
       final link = entry.querySelector('link');
+      if (link == null) {
+        continue;
+      }
       final href = link.attributes['href'];
+      if (href == null) {
+        continue;
+      }
       final body = await _getBody(href);
       final doc = parse(body);
       final links = doc.querySelectorAll('a');
diff --git a/pkg/analysis_server/tool/code_completion/flutter_metrics.dart b/pkg/analysis_server/tool/code_completion/flutter_metrics.dart
index 74cc153..9942472 100644
--- a/pkg/analysis_server/tool/code_completion/flutter_metrics.dart
+++ b/pkg/analysis_server/tool/code_completion/flutter_metrics.dart
@@ -50,7 +50,7 @@
 }
 
 /// Print usage information for this tool.
-void printUsage(ArgParser parser, {String error}) {
+void printUsage(ArgParser parser, {String? error}) {
   if (error != null) {
     print(error);
     print('');
@@ -104,7 +104,7 @@
   /// Record that an instance of the [childWidget] was created. If the instance
   /// creation expression is an argument in another widget constructor
   /// invocation, then the [parentWidget] is the name of the enclosing class.
-  void recordWidgetCreation(String childWidget, String parentWidget) {
+  void recordWidgetCreation(String childWidget, String? parentWidget) {
     totalWidgetCount++;
     widgetCounts[childWidget] = (widgetCounts[childWidget] ?? 0) + 1;
 
@@ -125,11 +125,11 @@
   final FlutterData data;
 
   /// The object used to determine Flutter-specific features.
-  Flutter flutter;
+  final Flutter flutter = Flutter.instance;
 
   /// The name of the most deeply widget class whose constructor invocation we
   /// are within.
-  String parentWidget;
+  String? parentWidget;
 
   /// Initialize a newly created collector to add data points to the given
   /// [data].
@@ -211,11 +211,7 @@
           //
           // Check for errors that cause the file to be skipped.
           //
-          if (resolvedUnitResult == null) {
-            print('');
-            print('File $filePath skipped because of an internal error.');
-            continue;
-          } else if (resolvedUnitResult.state != ResultState.VALID) {
+          if (resolvedUnitResult.state != ResultState.VALID) {
             print('');
             print('File $filePath skipped because it could not be analyzed.');
             continue;
@@ -228,8 +224,7 @@
             continue;
           }
 
-          collector.flutter = Flutter.instance;
-          resolvedUnitResult.unit.accept(collector);
+          resolvedUnitResult.unit!.accept(collector);
         } catch (exception, stackTrace) {
           print('');
           print('Exception caught analyzing: "$filePath"');
@@ -268,13 +263,15 @@
   /// Write the structure data in the [structureMap] to the [sink].
   void _writeStructureData(
       StringSink sink, Map<String, Map<String, int>> structureMap) {
-    var outerKeys = structureMap.keys.toList()..sort();
-    for (var outerKey in outerKeys) {
+    var outerEntries = structureMap.entries.toList();
+    outerEntries.sort((first, second) => first.key.compareTo(second.key));
+    for (var outerEntry in outerEntries) {
+      var outerKey = outerEntry.key;
       sink.writeln(outerKey);
-      var innerMap = structureMap[outerKey];
+      var innerMap = outerEntry.value;
       var entries = innerMap.entries.toList();
       entries.sort((first, second) => second.value.compareTo(first.value));
-      var total = entries.fold(
+      var total = entries.fold<int>(
           0, (previousValue, entry) => previousValue + entry.value);
       for (var entry in entries) {
         var percent = _formatPercent(entry.value, total);
diff --git a/pkg/analysis_server/tool/code_completion/implicit_type_declarations.dart b/pkg/analysis_server/tool/code_completion/implicit_type_declarations.dart
index 056ff2e..3204eeb 100644
--- a/pkg/analysis_server/tool/code_completion/implicit_type_declarations.dart
+++ b/pkg/analysis_server/tool/code_completion/implicit_type_declarations.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
+
 import 'dart:io' as io;
 
 import 'package:analysis_server/src/status/pages.dart';
diff --git a/pkg/analysis_server/tool/code_completion/metrics_util.dart b/pkg/analysis_server/tool/code_completion/metrics_util.dart
index f5c385e..47671f0 100644
--- a/pkg/analysis_server/tool/code_completion/metrics_util.dart
+++ b/pkg/analysis_server/tool/code_completion/metrics_util.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
+
 import 'package:analysis_server/src/status/pages.dart';
 import 'package:analyzer/src/generated/utilities_general.dart';
 
diff --git a/pkg/analysis_server/tool/code_completion/output_utilities.dart b/pkg/analysis_server/tool/code_completion/output_utilities.dart
index 8f7e096..aef456c 100644
--- a/pkg/analysis_server/tool/code_completion/output_utilities.dart
+++ b/pkg/analysis_server/tool/code_completion/output_utilities.dart
@@ -11,7 +11,7 @@
   print(buffer.toString());
 }
 
-/// Return an interable that will produce all of the integer values between
+/// Return an iterable that will produce all of the integer values between
 /// [first] and [last] inclusive.
 Iterable<int> range(int first, int last) sync* {
   for (var i = first; i < last; i++) {
diff --git a/pkg/analysis_server/tool/code_completion/relevance_metrics.dart b/pkg/analysis_server/tool/code_completion/relevance_metrics.dart
index c4a6398..547bea6 100644
--- a/pkg/analysis_server/tool/code_completion/relevance_metrics.dart
+++ b/pkg/analysis_server/tool/code_completion/relevance_metrics.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
+
 import 'dart:io' as io;
 import 'dart:math' as math;
 
diff --git a/pkg/analysis_server/tool/code_completion/relevance_table_generator.dart b/pkg/analysis_server/tool/code_completion/relevance_table_generator.dart
index 4b2ee62e..004c776 100644
--- a/pkg/analysis_server/tool/code_completion/relevance_table_generator.dart
+++ b/pkg/analysis_server/tool/code_completion/relevance_table_generator.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
+
 import 'dart:convert';
 import 'dart:io' as io;
 
@@ -75,34 +77,12 @@
     var rootPath = result.rest[0];
     print('Analyzing root: "$rootPath"');
 
-    File uniqueDataFile() {
-      var dataDir = result['mapDir'];
-      var baseFileName = provider.pathContext.basename(rootPath);
-      var index = 1;
-      while (index < 10000) {
-        var suffix = (index++).toString();
-        suffix = '0000'.substring(suffix.length) + suffix + '.json';
-        var fileName = baseFileName + suffix;
-        var filePath = provider.pathContext.join(dataDir, fileName);
-        var file = provider.getFile(filePath);
-        if (!file.exists) {
-          return file;
-        }
-      }
-
-      /// If there are more than 10000 directories with the same name, just
-      /// overwrite a previously generated file.
-      var fileName = baseFileName + '9999';
-      var filePath = provider.pathContext.join(dataDir, fileName);
-      return provider.getFile(filePath);
-    }
-
     var computer = RelevanceMetricsComputer();
     var stopwatch = Stopwatch()..start();
     await computer.compute(rootPath, verbose: result['verbose']);
-    if (result.wasParsed('mapDir')) {
-      var dataFile = uniqueDataFile();
-      dataFile.writeAsStringSync(computer.data.toJson());
+    if (result.wasParsed('mapFile')) {
+      var mapFile = provider.getFile(result['mapFile'] as String);
+      mapFile.writeAsStringSync(computer.data.toJson());
     } else {
       writeRelevanceTable(computer.data);
     }
@@ -123,9 +103,9 @@
     negatable: false,
   );
   parser.addOption(
-    'mapDir',
-    help: 'The absolute path of the directory to which the relevance data will '
-        'be written. Using this option will prevent the relevance table from '
+    'mapFile',
+    help: 'The absolute path of the file to which the relevance data will be '
+        'written. Using this option will prevent the relevance table from '
         'being written.',
   );
   parser.addOption(
@@ -167,8 +147,15 @@
     printUsage(parser, error: 'No package path specified.');
     return false;
   }
-  if (result.wasParsed('mapDir')) {
-    return validateDir(parser, result['mapDir']);
+  if (result.wasParsed('mapFile')) {
+    var mapFilePath = result['mapFile'];
+    if (mapFilePath is! String ||
+        !PhysicalResourceProvider.INSTANCE.pathContext
+            .isAbsolute(mapFilePath)) {
+      printUsage(parser,
+          error: 'The path "$mapFilePath" must be an absolute path.');
+      return false;
+    }
   }
   return validateDir(parser, result.rest[0]);
 }
@@ -1607,7 +1594,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.
-//
+
 // 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",
diff --git a/pkg/analysis_server/tool/code_completion/visitors.dart b/pkg/analysis_server/tool/code_completion/visitors.dart
index 69d68eb..a4abe60 100644
--- a/pkg/analysis_server/tool/code_completion/visitors.dart
+++ b/pkg/analysis_server/tool/code_completion/visitors.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
+
 import 'package:analysis_server/src/protocol/protocol_internal.dart';
 import 'package:analysis_server/src/protocol_server.dart' as protocol;
 import 'package:analysis_server/src/services/completion/dart/keyword_contributor.dart';
diff --git a/pkg/analysis_server/tool/instrumentation/log/log.dart b/pkg/analysis_server/tool/instrumentation/log/log.dart
index f5663a0..503f991 100644
--- a/pkg/analysis_server/tool/instrumentation/log/log.dart
+++ b/pkg/analysis_server/tool/instrumentation/log/log.dart
@@ -51,7 +51,7 @@
 
   /// Return the entry group with the given [id], or `null` if there is no group
   /// with the given id.
-  static EntryGroup withId(String id) {
+  static EntryGroup? withId(String id) {
     for (var group in groups) {
       if (group.id == id) {
         return group;
@@ -135,7 +135,7 @@
   List<String> logFilePaths;
 
   /// The entries in the instrumentation log.
-  List<LogEntry> logEntries;
+  late List<LogEntry> logEntries;
 
   /// A table mapping the entry groups that have been computed to the list of
   /// entries in that group.
@@ -169,7 +169,7 @@
 
   /// The ranges of entries that are between analysis start and analysis end
   /// notifications.
-  List<EntryRange> analysisRanges;
+  late List<EntryRange> analysisRanges;
 
   /// Initialize a newly created instrumentation log by parsing each of the
   /// lines in the [logContent] into a separate entry. The log contents should
@@ -180,30 +180,30 @@
   }
 
   /// Return a list of the completion events associated with the given [id].
-  List<NotificationEntry> completionEventsWithId(String id) =>
+  List<NotificationEntry>? completionEventsWithId(String id) =>
       _completionMap[id];
 
   /// Return the log entries that are contained in the given [group].
-  List<LogEntry> entriesInGroup(EntryGroup group) =>
+  List<LogEntry>? entriesInGroup(EntryGroup group) =>
       entryGroups.putIfAbsent(group, () => group.computeMembers(logEntries));
 
   /// Return the entry that is paired with the given [entry], or `null` if there
   /// is no entry paired with it.
-  LogEntry pairedEntry(LogEntry entry) => _pairedEntries[entry];
+  LogEntry? pairedEntry(LogEntry entry) => _pairedEntries[entry];
 
   /// Return the response that corresponds to the given plugin request.
-  PluginRequestEntry pluginRequestFor(PluginResponseEntry entry) =>
+  PluginRequestEntry? pluginRequestFor(PluginResponseEntry entry) =>
       _pluginRequestMap[entry.id];
 
   /// Return the response that corresponds to the given request.
-  PluginResponseEntry pluginResponseFor(PluginRequestEntry entry) =>
+  PluginResponseEntry? pluginResponseFor(PluginRequestEntry entry) =>
       _pluginResponseMap[entry.id];
 
   /// Return the response that corresponds to the given request.
-  RequestEntry requestFor(ResponseEntry entry) => _requestMap[entry.id];
+  RequestEntry? requestFor(ResponseEntry entry) => _requestMap[entry.id];
 
   /// Return the response that corresponds to the given request.
-  ResponseEntry responseFor(RequestEntry entry) => _responseMap[entry.id];
+  ResponseEntry? responseFor(RequestEntry entry) => _responseMap[entry.id];
 
   /// Return a list containing all of the task entries between the start of
   /// analysis notification at the given [startIndex] and the matching end of
@@ -211,7 +211,7 @@
   /// corresponding end notification.
   List<TaskEntry> taskEntriesFor(int startIndex) {
     var taskEntries = <TaskEntry>[];
-    NotificationEntry startEntry = logEntries[startIndex];
+    var startEntry = logEntries[startIndex] as NotificationEntry;
     var endEntry = pairedEntry(startEntry);
     var lastIndex = endEntry == null ? logEntries.length : endEntry.index;
     for (var i = startEntry.index + 1; i < lastIndex; i++) {
@@ -289,9 +289,9 @@
     }
     logEntries = <LogEntry>[];
     analysisRanges = <EntryRange>[];
-    NotificationEntry analysisStartEntry;
+    NotificationEntry? analysisStartEntry;
     var analysisStartIndex = -1;
-    NotificationEntry pubStartEntry;
+    NotificationEntry? pubStartEntry;
     for (var line in logContent) {
       var entry = LogEntry.from(logEntries.length, line);
       if (entry != null) {
@@ -300,7 +300,7 @@
           _requestMap[entry.id] = entry;
         } else if (entry is ResponseEntry) {
           _responseMap[entry.id] = entry;
-          var request = _requestMap[entry.id];
+          var request = _requestMap[entry.id]!;
           _pairedEntries[entry] = request;
           _pairedEntries[request] = entry;
         } else if (entry is NotificationEntry) {
@@ -348,8 +348,8 @@
               }
             }
           } else if (entry.event == 'completion.results') {
-            String id = entry.param('id');
-            if (id != null) {
+            var id = entry.param('id');
+            if (id is String) {
               _completionMap
                   .putIfAbsent(id, () => <NotificationEntry>[])
                   .add(entry);
@@ -359,7 +359,7 @@
           _pluginRequestMap[entry.id] = entry;
         } else if (entry is PluginResponseEntry) {
           _pluginResponseMap[entry.id] = entry;
-          var request = _pluginRequestMap[entry.id];
+          var request = _pluginRequestMap[entry.id]!;
           _pairedEntries[entry] = request;
           _pairedEntries[request] = entry;
         }
@@ -438,7 +438,7 @@
       buffer.write(object);
     } else if (object is Map) {
       buffer.write('{<br>');
-      object.forEach((Object key, Object value) {
+      object.forEach((key, value) {
         var newIndent = indent + singleIndent;
         buffer.write(newIndent);
         _format(buffer, newIndent, key);
@@ -450,7 +450,7 @@
       buffer.write('}');
     } else if (object is List) {
       buffer.write('[<br>');
-      object.forEach((Object element) {
+      object.forEach((element) {
         var newIndent = indent + singleIndent;
         buffer.write(newIndent);
         _format(buffer, newIndent, element);
@@ -511,13 +511,53 @@
 
   /// A list containing the descriptions of problems that were found while
   /// processing the log file, or `null` if no problems were found.
-  List<String> _problems;
+  List<String>? _problems;
 
   /// Initialize a newly created log entry with the given [timeStamp].
   LogEntry(this.index, this.timeStamp);
 
+  /// Return `true` if any problems were found while processing the log file.
+  bool get hasProblems => _problems != null;
+
+  /// Return the value of the component used to indicate the kind of the entry.
+  /// This is the abbreviation recorded in the entry.
+  String get kind;
+
+  /// Return a human-readable representation of the kind of this entry.
+  String get kindName => kindMap[kind] ?? kind;
+
+  /// Return a list containing the descriptions of problems that were found
+  /// while processing the log file, or `null` if no problems were found.
+  List<String>? get problems => _problems;
+
+  /// Return a date that is equivalent to the [timeStamp].
+  DateTime get toTime => DateTime.fromMillisecondsSinceEpoch(timeStamp);
+
+  /// Return an HTML representation of the details of the entry.
+  String details() {
+    var buffer = StringBuffer();
+    _appendDetails(buffer);
+    return buffer.toString();
+  }
+
+  /// Record that the given [problem] was found while processing the log file.
+  void recordProblem(String problem) {
+    var problems = _problems ??= <String>[];
+    problems.add(problem);
+  }
+
+  /// Append details related to this entry to the given [buffer].
+  void _appendDetails(StringBuffer buffer) {
+    var problems = _problems;
+    if (problems != null) {
+      for (var problem in problems) {
+        buffer.write('<p><span class="error">$problem</span></p>');
+      }
+    }
+  }
+
   /// Create a log entry from the given encoded form of the [entry].
-  factory LogEntry.from(int index, String entry) {
+  static LogEntry? from(int index, String entry) {
     if (entry.isEmpty) {
       return null;
     }
@@ -581,45 +621,6 @@
     }
   }
 
-  /// Return `true` if any problems were found while processing the log file.
-  bool get hasProblems => _problems != null;
-
-  /// Return the value of the component used to indicate the kind of the entry.
-  /// This is the abbreviation recorded in the entry.
-  String get kind;
-
-  /// Return a human-readable representation of the kind of this entry.
-  String get kindName => kindMap[kind] ?? kind;
-
-  /// Return a list containing the descriptions of problems that were found
-  /// while processing the log file, or `null` if no problems were found.
-  List<String> get problems => _problems;
-
-  /// Return a date that is equivalent to the [timeStamp].
-  DateTime get toTime => DateTime.fromMillisecondsSinceEpoch(timeStamp);
-
-  /// Return an HTML representation of the details of the entry.
-  String details() {
-    var buffer = StringBuffer();
-    _appendDetails(buffer);
-    return buffer.toString();
-  }
-
-  /// Record that the given [problem] was found while processing the log file.
-  void recordProblem(String problem) {
-    _problems ??= <String>[];
-    _problems.add(problem);
-  }
-
-  /// Append details related to this entry to the given [buffer].
-  void _appendDetails(StringBuffer buffer) {
-    if (_problems != null) {
-      for (var problem in _problems) {
-        buffer.write('<p><span class="error">$problem</span></p>');
-      }
-    }
-  }
-
   /// Parse the given encoded form of the [entry] into a list of components. The
   /// first component is always the time stamp for when the entry was generated.
   /// The second component is always the kind of the entry. The remaining
@@ -687,7 +688,7 @@
 
   /// Return the value of the parameter with the given [parameterName], or
   /// `null` if there is no such parameter.
-  dynamic param(String parameterName) {
+  Object? param(String parameterName) {
     var parameters = data['params'];
     if (parameters is Map) {
       return parameters[parameterName];
@@ -882,10 +883,10 @@
   final String description;
 
   /// The name of the class implementing the task.
-  String _taskName;
+  String? _taskName;
 
   /// The description of the target of the task.
-  String _target;
+  String? _target;
 
   /// Initialize a newly created entry with the given [index] and [timeStamp] to
   /// represent the execution of an analysis task in the given [context] that is
@@ -901,7 +902,7 @@
     if (_target == null) {
       _splitDescription();
     }
-    return _target;
+    return _target!;
   }
 
   /// Return the name of the class implementing the task.
@@ -909,7 +910,7 @@
     if (_taskName == null) {
       _splitDescription();
     }
-    return _taskName;
+    return _taskName!;
   }
 
   @override
@@ -930,14 +931,15 @@
       _taskName = description.substring(0, index);
     }
     index = description.lastIndexOf(' ');
-    _target = description.substring(index + 1);
+    var target = description.substring(index + 1);
     var slash = context.lastIndexOf('/');
     if (slash < 0) {
       slash = context.lastIndexOf('\\');
     }
     if (slash >= 0) {
       var prefix = context.substring(0, slash);
-      _target = _target.replaceAll(prefix, '...');
+      target = target.replaceAll(prefix, '...');
     }
+    _target = target;
   }
 }
diff --git a/pkg/analysis_server/tool/instrumentation/log_viewer.dart b/pkg/analysis_server/tool/instrumentation/log_viewer.dart
index aab0190..f3e5379d 100644
--- a/pkg/analysis_server/tool/instrumentation/log_viewer.dart
+++ b/pkg/analysis_server/tool/instrumentation/log_viewer.dart
@@ -44,7 +44,7 @@
 
   /// Print usage information.
   void printUsage(ArgParser parser,
-      {String error, Object exception, StackTrace stackTrace}) {
+      {String? error, Object? exception, StackTrace? stackTrace}) {
     if (error != null) {
       print(error);
       print('');
@@ -84,7 +84,7 @@
     }
 
     var arguments = options.rest;
-    if (arguments == null || arguments.length != 1) {
+    if (arguments.length != 1) {
       printUsage(parser, error: 'Missing log file');
       return;
     }
diff --git a/pkg/analysis_server/tool/instrumentation/page/log_page.dart b/pkg/analysis_server/tool/instrumentation/page/log_page.dart
index 27a6b65..6853dc1 100644
--- a/pkg/analysis_server/tool/instrumentation/page/log_page.dart
+++ b/pkg/analysis_server/tool/instrumentation/page/log_page.dart
@@ -15,21 +15,21 @@
   InstrumentationLog log;
 
   /// The id of the entry groups to be displayed.
-  EntryGroup selectedGroup;
+  late EntryGroup selectedGroup;
 
   /// The entries in the selected group.
-  List<LogEntry> entries;
+  late List<LogEntry> entries;
 
   /// The index of the first entry to be written.
   int pageStart = 0;
 
   /// The number of entries to be written, or `null` if all of the entries
   /// should be written.
-  int pageLength;
+  int? pageLength;
 
   /// The number of digits in the event stamps that are the same for every
   /// entry.
-  int prefixLength;
+  late int prefixLength;
 
   /// A table mapping the ids of plugins to an index for the plugin.
   Map<String, int> pluginIdMap = <String, int>{};
@@ -46,7 +46,7 @@
 
   @override
   void writeBody(StringSink sink) {
-    entries = log.entriesInGroup(selectedGroup);
+    entries = log.entriesInGroup(selectedGroup)!;
     prefixLength = computePrefixLength(entries);
 
     writeMenu(sink);
@@ -100,7 +100,7 @@
 
   /// Return the number of milliseconds elapsed between the [startEntry] and the
   /// [endEntry], or a question .
-  String _getDuration(LogEntry startEntry, LogEntry endEntry) {
+  String _getDuration(LogEntry? startEntry, LogEntry? endEntry) {
     if (startEntry != null && endEntry != null) {
       return (endEntry.timeStamp - startEntry.timeStamp).toString();
     }
@@ -109,7 +109,7 @@
 
   /// Write the given log [entry] to the given [sink].
   void _writeEntry(StringSink sink, LogEntry entry) {
-    String id;
+    String? id;
     var clickHandler = 'clearHighlight()';
     var icon = '';
     var description = entry.kindName;
@@ -224,6 +224,7 @@
   /// Write the entries in the instrumentation log to the given [sink].
   void _writeLeftColumn(StringSink sink) {
     var length = entries.length;
+    var pageLength = this.pageLength;
     var pageEnd =
         pageLength == null ? length : math.min(pageStart + pageLength, length);
     //
@@ -257,7 +258,7 @@
     } else {
       sink.write('<button type="button">');
       sink.write(
-          '<a href="${WebServer.logPath}?group=${selectedGroup.id}&start=${pageStart - pageLength}">');
+          '<a href="${WebServer.logPath}?group=${selectedGroup.id}&start=${pageStart - pageLength!}">');
       sink.write('<b>&lt;</b>');
       sink.writeln('</a></button>');
     }
@@ -267,7 +268,7 @@
     } else {
       sink.write('<button type="button">');
       sink.write(
-          '<a href="${WebServer.logPath}?group=${selectedGroup.id}&start=${pageStart + pageLength}">');
+          '<a href="${WebServer.logPath}?group=${selectedGroup.id}&start=${pageStart + pageLength!}">');
       sink.write('<b>&gt;</b>');
       sink.writeln('</a></button>');
     }
diff --git a/pkg/analysis_server/tool/instrumentation/page/stats_page.dart b/pkg/analysis_server/tool/instrumentation/page/stats_page.dart
index e218583..9ef7f85 100644
--- a/pkg/analysis_server/tool/instrumentation/page/stats_page.dart
+++ b/pkg/analysis_server/tool/instrumentation/page/stats_page.dart
@@ -86,8 +86,8 @@
         if (method == 'completion.getSuggestions') {
           var response = log.responseFor(entry);
           if (response != null) {
-            String id = response.result('id');
-            if (id != null) {
+            var id = response.result('id');
+            if (id is String) {
               var events = log.completionEventsWithId(id);
               if (events != null && events.isNotEmpty) {
                 completionResponseTimes
@@ -102,7 +102,7 @@
           pluginErrorCount[entry.pluginId] = count + 1;
         }
       } else if (entry is PluginRequestEntry) {
-        var response = log.pluginResponseFor(entry);
+        var response = log.pluginResponseFor(entry)!;
         var responseTime = response.timeStamp - entry.timeStamp;
         var pluginData = pluginResponseData.putIfAbsent(
             entry.pluginId, () => <String, List<int>>{});
@@ -189,7 +189,7 @@
         '<tr><th>min</th><th>mean</th><th>max</th><th>method</th></tr>');
     var methodNames = latencyData.keys.toList()..sort();
     for (var method in methodNames) {
-      var latencies = latencyData[method]..sort();
+      var latencies = latencyData[method]!..sort();
       // TODO(brianwilkerson) Add a spark-line distribution graph.
       sink.write('<tr><td class="int">');
       sink.write(latencies[0]);
@@ -223,7 +223,7 @@
         sink.writeln('<table>');
         var methodNames = responseData.keys.toList()..sort();
         for (var method in methodNames) {
-          var responseTimes = responseData[method]..sort();
+          var responseTimes = responseData[method]!..sort();
           // TODO(brianwilkerson) Add a spark-line distribution graph.
           sink.write('<tr><td class="int">');
           sink.write(responseTimes[0]);
diff --git a/pkg/analysis_server/tool/instrumentation/server.dart b/pkg/analysis_server/tool/instrumentation/server.dart
index 150eb9e..b4a2c4e 100644
--- a/pkg/analysis_server/tool/instrumentation/server.dart
+++ b/pkg/analysis_server/tool/instrumentation/server.dart
@@ -30,7 +30,7 @@
   final InstrumentationLog log;
 
   /// Future that is completed with the HTTP server once it is running.
-  Future<HttpServer> _server;
+  late Future<HttpServer> _server;
 
   /// Initialize a newly created server.
   WebServer(this.log);
@@ -38,7 +38,7 @@
   Map<String, String> getParameterMap(HttpRequest request) {
     Map<String, String> parameterMap = HashMap<String, String>();
     var query = request.uri.query;
-    if (query != null && query.isNotEmpty) {
+    if (query.isNotEmpty) {
       var pairs = query.split('&');
       for (var pair in pairs) {
         var parts = pair.split('=');
@@ -155,7 +155,7 @@
     var groupId = parameterMap['group'];
     var startIndex = parameterMap['start'];
     var page = LogPage(log);
-    page.selectedGroup = EntryGroup.withId(groupId ?? 'nonTask');
+    page.selectedGroup = EntryGroup.withId(groupId ?? 'nonTask')!;
     if (startIndex != null) {
       page.pageStart = int.parse(startIndex);
     } else {
@@ -167,15 +167,13 @@
 
   /// Write a representation of the given [stackTrace] to the given [sink].
   void _writeStackTrace(StringSink sink, StackTrace stackTrace) {
-    if (stackTrace != null) {
-      var trace = stackTrace.toString().replaceAll('#', '<br>#');
-      if (trace.startsWith('<br>#')) {
-        trace = trace.substring(4);
-      }
-      sink.write('<p>');
-      sink.write(trace);
-      sink.write('</p>');
+    var trace = stackTrace.toString().replaceAll('#', '<br>#');
+    if (trace.startsWith('<br>#')) {
+      trace = trace.substring(4);
     }
+    sink.write('<p>');
+    sink.write(trace);
+    sink.write('</p>');
   }
 
   void _writeStatsPage(HttpRequest request, StringBuffer buffer) {
diff --git a/pkg/analysis_server/tool/lsp_spec/codegen_dart.dart b/pkg/analysis_server/tool/lsp_spec/codegen_dart.dart
index 1e17989..9c7e2b3 100644
--- a/pkg/analysis_server/tool/lsp_spec/codegen_dart.dart
+++ b/pkg/analysis_server/tool/lsp_spec/codegen_dart.dart
@@ -2,7 +2,10 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+// @dart = 2.9
+
 import 'package:dart_style/dart_style.dart';
+import 'package:meta/meta.dart';
 
 import 'typescript.dart';
 import 'typescript_parser.dart';
@@ -384,7 +387,7 @@
     ..outdent()
     ..writeIndentedln('}');
   namespace.members.whereType<Const>().forEach((cons) {
-    // We don't use any deprecated enum values, so ommit them entirely.
+    // We don't use any deprecated enum values, so omit them entirely.
     if (cons.isDeprecated) {
       return;
     }
@@ -463,7 +466,7 @@
 
 void _writeFromJsonCode(
     IndentableStringBuffer buffer, TypeBase type, String valueCode,
-    {bool allowsNull}) {
+    {bool allowsNull, bool requiresBracesInInterpolation = false}) {
   type = resolveTypeAlias(type);
 
   if (_isSimpleType(type)) {
@@ -493,7 +496,9 @@
     _writeFromJsonCodeForLiteralUnion(buffer, type, valueCode,
         allowsNull: allowsNull);
   } else if (type is UnionType) {
-    _writeFromJsonCodeForUnion(buffer, type, valueCode, allowsNull: allowsNull);
+    _writeFromJsonCodeForUnion(buffer, type, valueCode,
+        allowsNull: allowsNull,
+        requiresBracesInInterpolation: requiresBracesInInterpolation);
   } else {
     buffer.write('$valueCode');
   }
@@ -513,7 +518,7 @@
 
 void _writeFromJsonCodeForUnion(
     IndentableStringBuffer buffer, UnionType union, String valueCode,
-    {bool allowsNull}) {
+    {bool allowsNull, @required bool requiresBracesInInterpolation}) {
   // Write a check against each type, eg.:
   // x is y ? new Either.tx(x) : (...)
   var hasIncompleteCondition = false;
@@ -532,7 +537,9 @@
     // The code to construct a value with this "side" of the union.
     buffer.write('${union.dartTypeWithTypeArgs}.t${i + 1}(');
     _writeFromJsonCode(buffer, type, valueCode,
-        allowsNull: allowsNull); // Call recursively!
+        allowsNull: allowsNull,
+        requiresBracesInInterpolation:
+            requiresBracesInInterpolation); // Call recursively!
     buffer.write(')');
 
     // If we output the type condition at the top, prepare for the next condition.
@@ -551,8 +558,10 @@
       buffer.write('$valueCode == null ? null : (');
       unclosedParens++;
     }
+    var interpolation =
+        requiresBracesInInterpolation ? '\${$valueCode}' : '\$$valueCode';
     buffer.write(
-        "throw '''\${$valueCode} was not one of (${union.types.map((t) => t.dartTypeWithTypeArgs).join(', ')})'''");
+        "throw '''$interpolation was not one of (${union.types.map((t) => t.dartTypeWithTypeArgs).join(', ')})'''");
   }
   buffer.write(')' * unclosedParens);
 }
@@ -578,7 +587,8 @@
   for (final field in allFields) {
     buffer.writeIndented('final ${field.name} = ');
     _writeFromJsonCode(buffer, field.type, "json['${field.name}']",
-        allowsNull: field.allowsNull || field.allowsUndefined);
+        allowsNull: field.allowsNull || field.allowsUndefined,
+        requiresBracesInInterpolation: true);
     buffer.writeln(';');
   }
   buffer
diff --git a/pkg/analysis_server/tool/lsp_spec/generate_all.dart b/pkg/analysis_server/tool/lsp_spec/generate_all.dart
index 782aa26..24084c8 100644
--- a/pkg/analysis_server/tool/lsp_spec/generate_all.dart
+++ b/pkg/analysis_server/tool/lsp_spec/generate_all.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
+
 import 'dart:io';
 
 import 'package:analysis_server/src/utilities/strings.dart';
@@ -155,17 +157,14 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+// @dart = 2.9
+
 // This file has been automatically generated. Please do not edit it manually.
 // To regenerate the file, use the script
 // "pkg/analysis_server/tool/lsp_spec/generate_all.dart".
 
 // ignore_for_file: annotate_overrides
-// ignore_for_file: deprecated_member_use
-// ignore_for_file: deprecated_member_use_from_same_package
-// ignore_for_file: unnecessary_brace_in_string_interps
 // ignore_for_file: unnecessary_parenthesis
-// ignore_for_file: unused_import
-// ignore_for_file: unused_shown_name
 
 import 'dart:core' hide deprecated;
 import 'dart:core' as core show deprecated;
@@ -173,8 +172,7 @@
 import 'package:analysis_server/lsp_protocol/protocol${importCustom ? '_custom' : ''}_generated.dart';
 import 'package:analysis_server/lsp_protocol/protocol_special.dart';
 import 'package:analysis_server/src/lsp/json_parsing.dart';
-import 'package:analysis_server/src/protocol/protocol_internal.dart'
-    show listEqual, mapEqual;
+import 'package:analysis_server/src/protocol/protocol_internal.dart';
 import 'package:analyzer/src/generated/utilities_general.dart';
 import 'package:meta/meta.dart';
 
@@ -272,6 +270,26 @@
       ],
       baseType: 'CompletionItemResolutionInfo',
     ),
+    // Custom types for experimental SnippetTextEdits
+    // https://github.com/rust-analyzer/rust-analyzer/blob/b35559a2460e7f0b2b79a7029db0c5d4e0acdb44/docs/dev/lsp-extensions.md#snippet-textedit
+    interface(
+      'SnippetTextEdit',
+      [
+        field('insertTextFormat', type: 'InsertTextFormat'),
+      ],
+      baseType: 'TextEdit',
+    ),
+    TypeAlias(
+      null,
+      Token.identifier('TextDocumentEditEdits'),
+      ArrayType(
+        UnionType([
+          Type.identifier('SnippetTextEdit'),
+          Type.identifier('AnnotatedTextEdit'),
+          Type.identifier('TextEdit'),
+        ]),
+      ),
+    )
   ];
   return customTypes;
 }
diff --git a/pkg/analysis_server/tool/lsp_spec/markdown.dart b/pkg/analysis_server/tool/lsp_spec/markdown.dart
index fa9d47b..cf56d33 100644
--- a/pkg/analysis_server/tool/lsp_spec/markdown.dart
+++ b/pkg/analysis_server/tool/lsp_spec/markdown.dart
@@ -11,7 +11,7 @@
 List<String> extractMethodNames(String spec) {
   return _methodNamesPattern
       .allMatches(spec)
-      .map((m) => m.group(1).trim())
+      .map((m) => m.group(1)!.trim())
       .toList();
 }
 
@@ -20,6 +20,6 @@
 List<String> extractTypeScriptBlocks(String text) {
   return _typeScriptBlockPattern
       .allMatches(text)
-      .map((m) => m.group(1).trim())
+      .map((m) => m.group(1)!.trim())
       .toList();
 }
diff --git a/pkg/analysis_server/tool/lsp_spec/typescript.dart b/pkg/analysis_server/tool/lsp_spec/typescript.dart
index 575d66e..da58944 100644
--- a/pkg/analysis_server/tool/lsp_spec/typescript.dart
+++ b/pkg/analysis_server/tool/lsp_spec/typescript.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
+
 import 'typescript_parser.dart';
 
 /// Removes types that are in the spec that we don't want in other signatures.
@@ -124,6 +126,9 @@
     },
     'ServerCapabilities': {
       'changeNotifications': 'bool',
+    },
+    'TextDocumentEdit': {
+      'edits': 'TextDocumentEditEdits',
     }
   };
 
diff --git a/pkg/analysis_server/tool/lsp_spec/typescript_parser.dart b/pkg/analysis_server/tool/lsp_spec/typescript_parser.dart
index c657cab..b18b819 100644
--- a/pkg/analysis_server/tool/lsp_spec/typescript_parser.dart
+++ b/pkg/analysis_server/tool/lsp_spec/typescript_parser.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
+
 import 'dart:math';
 
 import 'package:analysis_server/src/utilities/strings.dart' show capitalize;
diff --git a/pkg/analysis_server/tool/migration_runner.dart b/pkg/analysis_server/tool/migration_runner.dart
index 1edcefa..355040f 100644
--- a/pkg/analysis_server/tool/migration_runner.dart
+++ b/pkg/analysis_server/tool/migration_runner.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
+
 /// This executable provides the ability to run the migration tool in process
 /// on a single package.  It should be invoked with two command-line arguments:
 /// a path to a configuration file and the name of a package to migrate.
diff --git a/pkg/analysis_server/tool/spec/api.dart b/pkg/analysis_server/tool/spec/api.dart
index 9619513..95fddb4f 100644
--- a/pkg/analysis_server/tool/spec/api.dart
+++ b/pkg/analysis_server/tool/spec/api.dart
@@ -17,8 +17,8 @@
 
   Api(this.version, this.domains, this.types, this.refactorings,
       dom.Element html,
-      {bool experimental})
-      : super(html, experimental, false);
+      {bool experimental = false})
+      : super(html, experimental: experimental, deprecated: false);
 }
 
 /// Base class for objects in the API model.
@@ -29,12 +29,10 @@
   /// A flag to indicate if this API is deprecated.
   final bool deprecated;
 
-  /// Html element representing this part of the API.
-  final dom.Element html;
+  /// Html element representing this part of the API, `null` if built-in.
+  final dom.Element? html;
 
-  ApiNode(this.html, bool experimental, bool deprecated)
-      : experimental = experimental ?? false,
-        deprecated = deprecated ?? false;
+  ApiNode(this.html, {this.experimental = false, this.deprecated = false});
 }
 
 /// Base class for visiting the API definition.
@@ -57,8 +55,11 @@
   final List<Notification> notifications;
 
   Domain(this.name, this.requests, this.notifications, dom.Element html,
-      {bool experimental, bool deprecated})
-      : super(html, experimental, deprecated);
+      {bool experimental = false, bool deprecated = false})
+      : super(html, experimental: experimental, deprecated: deprecated);
+
+  @override
+  dom.Element get html => super.html!;
 }
 
 /// API visitor that visits the entire API hierarchically by default.
@@ -74,8 +75,12 @@
   /// If it is not possible (because the chain ends with a [TypeReference] that
   /// is not defined in the API), then that final [TypeReference] is returned.
   TypeDecl resolveTypeReferenceChain(TypeDecl type) {
-    while (type is TypeReference && api.types.containsKey(type.typeName)) {
-      type = api.types[(type as TypeReference).typeName].type;
+    while (type is TypeReference) {
+      var newTypeRef = api.types[type.typeName];
+      if (newTypeRef == null) {
+        break;
+      }
+      type = newTypeRef.type;
     }
     return type;
   }
@@ -92,30 +97,37 @@
   }
 
   void visitNotification(Notification notification) {
-    if (notification.params != null) {
-      visitTypeDecl(notification.params);
+    var params = notification.params;
+    if (params != null) {
+      visitTypeDecl(params);
     }
   }
 
   void visitRefactoring(Refactoring refactoring) {
-    if (refactoring.feedback != null) {
-      visitTypeDecl(refactoring.feedback);
+    var feedback = refactoring.feedback;
+    if (feedback != null) {
+      visitTypeDecl(feedback);
     }
-    if (refactoring.options != null) {
-      visitTypeDecl(refactoring.options);
+
+    var options = refactoring.options;
+    if (options != null) {
+      visitTypeDecl(options);
     }
   }
 
   void visitRefactorings(Refactorings refactorings) {
-    refactorings?.forEach(visitRefactoring);
+    refactorings.forEach(visitRefactoring);
   }
 
   void visitRequest(Request request) {
-    if (request.params != null) {
-      visitTypeDecl(request.params);
+    var params = request.params;
+    if (params != null) {
+      visitTypeDecl(params);
     }
-    if (request.result != null) {
-      visitTypeDecl(request.result);
+
+    var result = request.result;
+    if (result != null) {
+      visitTypeDecl(result);
     }
   }
 
@@ -173,11 +185,11 @@
 
   /// Type of the object associated with the "params" key in the notification
   /// object, or null if the notification has no parameters.
-  final TypeObject params;
+  final TypeObject? params;
 
   Notification(this.domainName, this.event, this.params, dom.Element html,
-      {bool experimental})
-      : super(html, experimental, false);
+      {bool experimental = false})
+      : super(html, experimental: experimental, deprecated: false);
 
   /// Get the name of the notification, including the domain prefix.
   String get longEvent => '$domainName.$event';
@@ -189,9 +201,12 @@
       TypeObjectField('event', TypeReference('String', null), null,
           value: '$domainName.$event')
     ];
+
+    var params = this.params;
     if (params != null) {
       fields.add(TypeObjectField('params', params, null));
     }
+
     return TypeObject(fields, null);
   }
 }
@@ -204,23 +219,24 @@
 
   /// Type of the refactoring feedback, or null if the refactoring has no
   /// feedback.
-  final TypeObject feedback;
+  final TypeObject? feedback;
 
   /// Type of the refactoring options, or null if the refactoring has no
   /// options.
-  final TypeObject options;
+  final TypeObject? options;
 
   Refactoring(this.kind, this.feedback, this.options, dom.Element html,
-      {bool experimental})
-      : super(html, experimental, false);
+      {bool experimental = false})
+      : super(html, experimental: experimental, deprecated: false);
 }
 
 /// A collection of refactoring definitions.
 class Refactorings extends ApiNode with IterableMixin<Refactoring> {
   final List<Refactoring> refactorings;
 
-  Refactorings(this.refactorings, dom.Element html, {bool experimental})
-      : super(html, experimental, false);
+  Refactorings(this.refactorings, dom.Element? html,
+      {bool experimental = false})
+      : super(html, experimental: experimental, deprecated: false);
 
   @override
   Iterator<Refactoring> get iterator => refactorings.iterator;
@@ -236,16 +252,16 @@
 
   /// Type of the object associated with the "params" key in the request object,
   /// or null if the request has no parameters.
-  final TypeObject params;
+  final TypeObject? params;
 
   /// Type of the object associated with the "result" key in the response
   /// object, or `null` if the response has no results.
-  final TypeObject result;
+  final TypeObject? result;
 
   Request(
       this.domainName, this.method, this.params, this.result, dom.Element html,
-      {bool experimental, bool deprecated})
-      : super(html, experimental, deprecated);
+      {bool experimental = false, bool deprecated = false})
+      : super(html, experimental: experimental, deprecated: deprecated);
 
   /// Get the name of the request, including the domain prefix.
   String get longMethod => '$domainName.$method';
@@ -258,9 +274,12 @@
       TypeObjectField('method', TypeReference('String', null), null,
           value: '$domainName.$method')
     ];
+
+    var params = this.params;
     if (params != null) {
       fields.add(TypeObjectField('params', params, null));
     }
+
     return TypeObject(fields, null);
   }
 
@@ -272,17 +291,21 @@
       TypeObjectField('error', TypeReference('RequestError', null), null,
           optional: true)
     ];
+
+    var result = this.result;
     if (result != null) {
       fields.add(TypeObjectField('result', result, null));
     }
+
     return TypeObject(fields, null);
   }
 }
 
 /// Base class for all possible types.
 abstract class TypeDecl extends ApiNode {
-  TypeDecl(dom.Element html, bool experimental, bool deprecated)
-      : super(html, experimental, deprecated);
+  TypeDecl(dom.Element? html,
+      {bool experimental = false, bool deprecated = false})
+      : super(html, experimental: experimental, deprecated: deprecated);
 
   T accept<T>(ApiVisitor<T> visitor);
 }
@@ -295,8 +318,8 @@
   bool isExternal = false;
 
   TypeDefinition(this.name, this.type, dom.Element html,
-      {bool experimental, bool deprecated})
-      : super(html, experimental, deprecated);
+      {bool experimental = false, bool deprecated = false})
+      : super(html, experimental: experimental, deprecated: deprecated);
 }
 
 /// Type of an enum.  We represent enums in JSON as strings, so this type
@@ -304,8 +327,9 @@
 class TypeEnum extends TypeDecl {
   final List<TypeEnumValue> values;
 
-  TypeEnum(this.values, dom.Element html, {bool experimental, bool deprecated})
-      : super(html, experimental, deprecated);
+  TypeEnum(this.values, dom.Element html,
+      {bool experimental = false, bool deprecated = false})
+      : super(html, experimental: experimental, deprecated: deprecated);
 
   @override
   T accept<T>(ApiVisitor<T> visitor) => visitor.visitTypeEnum(this);
@@ -316,16 +340,19 @@
   final String value;
 
   TypeEnumValue(this.value, dom.Element html,
-      {bool experimental, bool deprecated})
-      : super(html, experimental, deprecated);
+      {bool experimental = false, bool deprecated = false})
+      : super(html, experimental: experimental, deprecated: deprecated);
+
+  @override
+  dom.Element get html => super.html!;
 }
 
 /// Type of a JSON list.
 class TypeList extends TypeDecl {
   final TypeDecl itemType;
 
-  TypeList(this.itemType, dom.Element html, {bool experimental})
-      : super(html, experimental, false);
+  TypeList(this.itemType, dom.Element html, {bool experimental = false})
+      : super(html, experimental: experimental, deprecated: false);
 
   @override
   T accept<T>(ApiVisitor<T> visitor) => visitor.visitTypeList(this);
@@ -342,8 +369,9 @@
   /// Type of map values.
   final TypeDecl valueType;
 
-  TypeMap(this.keyType, this.valueType, dom.Element html, {bool experimental})
-      : super(html, experimental, false);
+  TypeMap(this.keyType, this.valueType, dom.Element html,
+      {bool experimental = false})
+      : super(html, experimental: experimental, deprecated: false);
 
   @override
   T accept<T>(ApiVisitor<T> visitor) => visitor.visitTypeMap(this);
@@ -353,15 +381,15 @@
 class TypeObject extends TypeDecl {
   final List<TypeObjectField> fields;
 
-  TypeObject(this.fields, dom.Element html,
-      {bool experimental, bool deprecated})
-      : super(html, experimental, deprecated);
+  TypeObject(this.fields, dom.Element? html,
+      {bool experimental = false, bool deprecated = false})
+      : super(html, experimental: experimental, deprecated: deprecated);
 
   @override
   T accept<T>(ApiVisitor<T> visitor) => visitor.visitTypeObject(this);
 
   /// Return the field with the given [name], or null if there is no such field.
-  TypeObjectField getField(String name) {
+  TypeObjectField? getField(String name) {
     for (var field in fields) {
       if (field.name == name) {
         return field;
@@ -378,11 +406,14 @@
   final bool optional;
 
   /// Value that the field is required to contain, or null if it may vary.
-  final Object value;
+  final Object? value;
 
-  TypeObjectField(this.name, this.type, dom.Element html,
-      {this.optional = false, this.value, bool experimental, bool deprecated})
-      : super(html, experimental, deprecated);
+  TypeObjectField(this.name, this.type, dom.Element? html,
+      {this.optional = false,
+      this.value,
+      bool experimental = false,
+      bool deprecated = false})
+      : super(html, experimental: experimental, deprecated: deprecated);
 }
 
 /// A reference to a type which is either defined elsewhere in the API or which
@@ -390,8 +421,8 @@
 class TypeReference extends TypeDecl {
   final String typeName;
 
-  TypeReference(this.typeName, dom.Element html, {bool experimental})
-      : super(html, experimental, false) {
+  TypeReference(this.typeName, dom.Element? html, {bool experimental = false})
+      : super(html, experimental: experimental, deprecated: false) {
     if (typeName.isEmpty) {
       throw Exception('Empty type name');
     }
@@ -407,15 +438,15 @@
 
   List<String> importUris = <String>[];
 
-  Types(this.types, dom.Element html, {bool experimental})
-      : super(html, experimental, false);
+  Types(this.types, dom.Element? html, {bool experimental = false})
+      : super(html, experimental: experimental, deprecated: false);
 
   @override
   Iterator<TypeDefinition> get iterator => types.values.iterator;
 
   Iterable<String> get keys => types.keys;
 
-  TypeDefinition operator [](String typeName) => types[typeName];
+  TypeDefinition? operator [](String typeName) => types[typeName];
 
   bool containsKey(String typeName) => types.containsKey(typeName);
 }
@@ -427,8 +458,9 @@
   /// The field that is used to disambiguate this union
   final String field;
 
-  TypeUnion(this.choices, this.field, dom.Element html, {bool experimental})
-      : super(html, experimental, false);
+  TypeUnion(this.choices, this.field, dom.Element html,
+      {bool experimental = false})
+      : super(html, experimental: experimental, deprecated: false);
 
   @override
   T accept<T>(ApiVisitor<T> visitor) => visitor.visitTypeUnion(this);
diff --git a/pkg/analysis_server/tool/spec/codegen_analysis_server.dart b/pkg/analysis_server/tool/spec/codegen_analysis_server.dart
index 9e19fb6..096db25 100644
--- a/pkg/analysis_server/tool/spec/codegen_analysis_server.dart
+++ b/pkg/analysis_server/tool/spec/codegen_analysis_server.dart
@@ -165,14 +165,18 @@
       }));
       write('public void $methodName(');
       var arguments = <String>[];
-      if (request.params != null) {
-        for (var field in request.params.fields) {
+
+      var params = request.params;
+      if (params != null) {
+        for (var field in params.fields) {
           arguments.add('${javaType(field.type)} ${javaName(field.name)}');
         }
       }
+
       if (request.result != null) {
         arguments.add('${consumerName(request)} consumer');
       }
+
       write(arguments.join(', '));
       writeln(');');
     });
diff --git a/pkg/analysis_server/tool/spec/codegen_dart.dart b/pkg/analysis_server/tool/spec/codegen_dart.dart
index 9dacf99..7069dc0 100644
--- a/pkg/analysis_server/tool/spec/codegen_dart.dart
+++ b/pkg/analysis_server/tool/spec/codegen_dart.dart
@@ -19,8 +19,9 @@
     if (type is TypeReference) {
       var typeName = type.typeName;
       var referencedDefinition = api.types[typeName];
-      if (_typeRenames.containsKey(typeName)) {
-        return _typeRenames[typeName];
+      var typeRename = _typeRenames[typeName];
+      if (typeRename != null) {
+        return typeRename;
       }
       if (referencedDefinition == null) {
         return typeName;
@@ -35,9 +36,15 @@
     } else if (type is TypeMap) {
       return 'Map<${dartType(type.keyType)}, ${dartType(type.valueType)}>';
     } else if (type is TypeUnion) {
-      return 'dynamic';
+      return 'Object';
     } else {
       throw Exception("Can't convert to a dart type");
     }
   }
+
+  /// Return the Dart type for [field], nullable if the field is optional.
+  String fieldDartType(TypeObjectField field) {
+    var typeStr = dartType(field.type);
+    return field.optional ? '$typeStr?' : typeStr;
+  }
 }
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 65515ef..160c52d 100644
--- a/pkg/analysis_server/tool/spec/codegen_dart_notification_handler.dart
+++ b/pkg/analysis_server/tool/spec/codegen_dart_notification_handler.dart
@@ -138,6 +138,6 @@
         _generateNotificationMethodName(
             notification.domainName, notification.event),
         _generateParamTypeName(notification.domainName, notification.event),
-        _generateDartDoc(notification.html)));
+        _generateDartDoc(notification.html!)));
   }
 }
diff --git a/pkg/analysis_server/tool/spec/codegen_dart_protocol.dart b/pkg/analysis_server/tool/spec/codegen_dart_protocol.dart
index 2acef57..c17e46f 100644
--- a/pkg/analysis_server/tool/spec/codegen_dart_protocol.dart
+++ b/pkg/analysis_server/tool/spec/codegen_dart_protocol.dart
@@ -257,7 +257,7 @@
   /// Emit the toJson() code for an empty class.
   void emitEmptyToJsonMember() {
     writeln('@override');
-    writeln('Map<String, dynamic> toJson() => <String, dynamic>{};');
+    writeln('Map<String, Object> toJson() => <String, Object>{};');
   }
 
   /// Emit a class to encapsulate an enum.
@@ -266,8 +266,9 @@
       toHtmlVisitor.p(() {
         toHtmlVisitor.write(impliedType.humanReadableName);
       });
-      if (impliedType.type != null) {
-        toHtmlVisitor.showType(null, impliedType.type);
+      var impliedTypeType = impliedType.type;
+      if (impliedTypeType != null) {
+        toHtmlVisitor.showType(null, impliedTypeType);
       }
       toHtmlVisitor.p(() {
         toHtmlVisitor.write(disclaimer);
@@ -356,7 +357,7 @@
   void emitEnumFromJsonConstructor(
       String className, TypeEnum type, ImpliedType impliedType) {
     writeln(
-        'factory $className.fromJson(JsonDecoder jsonDecoder, String jsonPath, Object json) {');
+        'factory $className.fromJson(JsonDecoder jsonDecoder, String jsonPath, Object? json) {');
     indent(() {
       writeln('if (json is String) {');
       indent(() {
@@ -410,8 +411,9 @@
       toHtmlVisitor.p(() {
         toHtmlVisitor.write(impliedType.humanReadableName);
       });
-      if (impliedType.type != null) {
-        toHtmlVisitor.showType(null, impliedType.type);
+      var impliedTypeType = impliedType.type;
+      if (impliedTypeType != null) {
+        toHtmlVisitor.showType(null, impliedTypeType);
       }
       toHtmlVisitor.p(() {
         toHtmlVisitor.write(disclaimer);
@@ -437,29 +439,10 @@
         if (field.value != null) {
           continue;
         }
-        writeln('${dartType(field.type)} _${field.name};');
-        writeln();
-      }
-      for (var field in type.fields) {
-        if (field.value != null) {
-          continue;
-        }
         docComment(toHtmlVisitor.collectHtml(() {
           toHtmlVisitor.translateHtml(field.html);
         }));
-        writeln('${dartType(field.type)} get ${field.name} => _${field.name};');
-        writeln();
-        docComment(toHtmlVisitor.collectHtml(() {
-          toHtmlVisitor.translateHtml(field.html);
-        }));
-        writeln('set ${field.name}(${dartType(field.type)} value) {');
-        indent(() {
-          if (!field.optional) {
-            writeln('assert(value != null);');
-          }
-          writeln('_${field.name} = value;');
-        });
-        writeln('}');
+        writeln('${fieldDartType(field)} ${field.name};');
         writeln();
       }
       emitObjectConstructor(type, className);
@@ -503,66 +486,44 @@
   void emitObjectConstructor(TypeObject type, String className) {
     var args = <String>[];
     var optionalArgs = <String>[];
-    var extraInitCode = <CodegenCallback>[];
+    var initializers = <String>[];
     for (var field in type.fields) {
       if (field.value != null) {
         continue;
       }
-      var arg = '${dartType(field.type)} ${field.name}';
-      var setValueFromArg = 'this.${field.name} = ${field.name};';
       if (isOptionalConstructorArg(className, field)) {
-        optionalArgs.add(arg);
         if (!field.optional) {
-          // Optional constructor arg, but non-optional field.  If no arg is
+          optionalArgs.add('${dartType(field.type)}? ${field.name}');
+          // Optional constructor arg, but non-optional field. If no arg is
           // given, the constructor should populate with the empty list.
           var fieldType = field.type;
           if (fieldType is TypeList) {
-            extraInitCode.add(() {
-              writeln('if (${field.name} == null) {');
-              indent(() {
-                writeln(
-                    'this.${field.name} = <${dartType(fieldType.itemType)}>[];');
-              });
-              writeln('} else {');
-              indent(() {
-                writeln(setValueFromArg);
-              });
-              writeln('}');
-            });
+            var defaultValue = '<${dartType(fieldType.itemType)}>[]';
+            initializers.add('${field.name} = ${field.name} ?? $defaultValue');
           } else {
             throw Exception("Don't know how to create default field value.");
           }
         } else {
-          extraInitCode.add(() {
-            writeln(setValueFromArg);
-          });
+          optionalArgs.add('this.${field.name}');
         }
       } else {
-        args.add(arg);
-        extraInitCode.add(() {
-          writeln(setValueFromArg);
-        });
+        args.add('this.${field.name}');
       }
     }
     if (optionalArgs.isNotEmpty) {
       args.add('{${optionalArgs.join(', ')}}');
     }
     write('$className(${args.join(', ')})');
-    if (extraInitCode.isEmpty) {
+    if (initializers.isEmpty) {
       writeln(';');
     } else {
-      writeln(' {');
-      indent(() {
-        for (var callback in extraInitCode) {
-          callback();
-        }
-      });
-      writeln('}');
+      writeln(' : ${initializers.join(', ')}');
+      writeln(';');
     }
   }
 
   /// Emit the operator== code for an object class.
-  void emitObjectEqualsMember(TypeObject type, String className) {
+  void emitObjectEqualsMember(TypeObject? type, String className) {
     writeln('@override');
     writeln('bool operator ==(other) {');
     indent(() {
@@ -596,8 +557,8 @@
       String className, TypeObject type, ImpliedType impliedType) {
     var humanReadableNameString = literalString(impliedType.humanReadableName);
     if (className == 'RefactoringFeedback') {
-      writeln('factory RefactoringFeedback.fromJson(JsonDecoder jsonDecoder, '
-          'String jsonPath, Object json, Map responseJson) {');
+      writeln('static RefactoringFeedback? fromJson(JsonDecoder jsonDecoder, '
+          'String jsonPath, Object? json, Map responseJson) {');
       indent(() {
         writeln('return refactoringFeedbackFromJson(jsonDecoder, jsonPath, '
             'json, responseJson);');
@@ -606,8 +567,8 @@
       return;
     }
     if (className == 'RefactoringOptions') {
-      writeln('factory RefactoringOptions.fromJson(JsonDecoder jsonDecoder, '
-          'String jsonPath, Object json, RefactoringKind kind) {');
+      writeln('static RefactoringOptions? fromJson(JsonDecoder jsonDecoder, '
+          'String jsonPath, Object? json, RefactoringKind kind) {');
       indent(() {
         writeln('return refactoringOptionsFromJson(jsonDecoder, jsonPath, '
             'json, kind);');
@@ -616,7 +577,7 @@
       return;
     }
     writeln(
-        'factory $className.fromJson(JsonDecoder jsonDecoder, String jsonPath, Object json) {');
+        'factory $className.fromJson(JsonDecoder jsonDecoder, String jsonPath, Object? json) {');
     indent(() {
       writeln('json ??= {};');
       writeln('if (json is Map) {');
@@ -627,12 +588,13 @@
           var fieldNameString = literalString(field.name);
           var fieldAccessor = 'json[$fieldNameString]';
           var jsonPath = 'jsonPath + ${literalString('.${field.name}')}';
-          if (field.value != null) {
-            var valueString = literalString(field.value);
+          var fieldValue = field.value;
+          if (fieldValue is String) {
+            var valueString = literalString(fieldValue);
             writeln('if ($fieldAccessor != $valueString) {');
             indent(() {
               writeln(
-                  "throw jsonDecoder.mismatch(jsonPath, 'equal ${field.value}', json);");
+                  "throw jsonDecoder.mismatch(jsonPath, 'equal $fieldValue', json);");
             });
             writeln('}');
             continue;
@@ -642,11 +604,11 @@
           } else {
             args.add(field.name);
           }
-          var fieldType = field.type;
-          var fieldDartType = dartType(fieldType);
-          writeln('$fieldDartType ${field.name};');
+          var typeStr = fieldDartType(field);
+          writeln('$typeStr ${field.name};');
           writeln('if (json.containsKey($fieldNameString)) {');
           indent(() {
+            var fieldType = field.type;
             var fromJson =
                 fromJsonCode(fieldType).asSnippet(jsonPath, fieldAccessor);
             writeln('${field.name} = $fromJson;');
@@ -677,7 +639,7 @@
   }
 
   /// Emit the hashCode getter for an object class.
-  void emitObjectHashCode(TypeObject type, String className) {
+  void emitObjectHashCode(TypeObject? type, String className) {
     writeln('@override');
     writeln('int get hashCode {');
     indent(() {
@@ -715,7 +677,7 @@
               'Returns the [RefactoringProblemSeverity] with the maximal severity.')
         ]);
         writeln(
-            'static RefactoringProblemSeverity max(RefactoringProblemSeverity a, RefactoringProblemSeverity b) =>');
+            'static RefactoringProblemSeverity? max(RefactoringProblemSeverity? a, RefactoringProblemSeverity? b) =>');
         writeln('    maxRefactoringProblemSeverity(a, b);');
         return true;
       default:
@@ -786,7 +748,7 @@
         docComment([
           dom.Text('Returns the [FileEdit] for the given [file], maybe `null`.')
         ]);
-        writeln('SourceFileEdit getFileEdit(String file) =>');
+        writeln('SourceFileEdit? getFileEdit(String file) =>');
         writeln('    getChangeFileEdit(this, file);');
         return true;
       case 'SourceEdit':
@@ -850,19 +812,23 @@
   /// Emit the toJson() code for an object class.
   void emitToJsonMember(TypeObject type) {
     writeln('@override');
-    writeln('Map<String, dynamic> toJson() {');
+    writeln('Map<String, Object> toJson() {');
     indent(() {
-      writeln('var result = <String, dynamic>{};');
+      writeln('var result = <String, Object>{};');
       for (var field in type.fields) {
         var fieldNameString = literalString(field.name);
-        if (field.value != null) {
-          writeln('result[$fieldNameString] = ${literalString(field.value)};');
+        var fieldValue = field.value;
+        if (fieldValue is String) {
+          var valueString = literalString(fieldValue);
+          writeln('result[$fieldNameString] = $valueString;');
           continue;
         }
         var fieldToJson = toJsonCode(field.type).asSnippet(field.name);
         var populateField = 'result[$fieldNameString] = $fieldToJson;';
         if (field.optional) {
-          writeln('if (${field.name} != null) {');
+          var name = field.name;
+          writeln('var $name = this.$name;');
+          writeln('if ($name != null) {');
           indent(() {
             writeln(populateField);
           });
@@ -1019,7 +985,7 @@
                 'Each choice in the union needs a constant value for the field ${type.field}');
           }
           var closure = fromJsonCode(choice).asClosure;
-          decoders.add('${literalString(field.value)}: $closure');
+          decoders.add('${literalString(field.value as String)}: $closure');
         } else {
           throw Exception('Union types must be unions of objects.');
         }
@@ -1108,7 +1074,10 @@
           throw Exception('Union types must be unions of objects');
         }
       }
-      return ToJsonSnippet(dartType(type), (String value) => '$value.toJson()');
+      return ToJsonSnippet(
+        dartType(type),
+        (String value) => '($value as dynamic).toJson()',
+      );
     } else if (resolvedType is TypeObject || resolvedType is TypeEnum) {
       return ToJsonSnippet(dartType(type), (String value) => '$value.toJson()');
     } else {
@@ -1173,7 +1142,7 @@
 
   @override
   String get asClosure =>
-      '(String jsonPath, Object json) => ${callback('jsonPath', 'json')}';
+      '(String jsonPath, Object? json) => ${callback('jsonPath', 'json')}';
 
   @override
   bool get isIdentity => false;
diff --git a/pkg/analysis_server/tool/spec/codegen_inttest_methods.dart b/pkg/analysis_server/tool/spec/codegen_inttest_methods.dart
index 208e0a0..5864cb2 100644
--- a/pkg/analysis_server/tool/spec/codegen_inttest_methods.dart
+++ b/pkg/analysis_server/tool/spec/codegen_inttest_methods.dart
@@ -47,7 +47,7 @@
 
   /// Generate a function argument for the given parameter field.
   String formatArgument(TypeObjectField field) =>
-      '${dartType(field.type)} ${field.name}';
+      '${fieldDartType(field)} ${field.name}';
 
   /// Figure out the appropriate Dart type for data having the given API
   /// protocol [type].
@@ -130,7 +130,6 @@
           writeln('default:');
           indent(() {
             writeln("fail('Unexpected notification: \$event');");
-            writeln('break;');
           });
         });
         writeln('}');
@@ -152,12 +151,12 @@
       toHtmlVisitor.translateHtml(notification.html);
       toHtmlVisitor.describePayload(notification.params, 'Parameters');
     }));
-    writeln('Stream<$className> $streamName;');
+    writeln('late Stream<$className> $streamName;');
     writeln();
     docComment(toHtmlVisitor.collectHtml(() {
       toHtmlVisitor.write('Stream controller for [$streamName].');
     }));
-    writeln('StreamController<$className> _$streamName;');
+    writeln('late StreamController<$className> _$streamName;');
     fieldInitializationCode.add(collectCode(() {
       writeln('_$streamName = StreamController<$className>(sync: true);');
       writeln('$streamName = _$streamName.stream.asBroadcastStream();');
@@ -185,8 +184,9 @@
     var methodName = camelJoin(['send', request.domainName, request.method]);
     var args = <String>[];
     var optionalArgs = <String>[];
-    if (request.params != null) {
-      for (var field in request.params.fields) {
+    var params = request.params;
+    if (params != null) {
+      for (var field in params.fields) {
         if (field.optional) {
           optionalArgs.add(formatArgument(field));
         } else {
@@ -200,32 +200,35 @@
     writeln();
     docComment(toHtmlVisitor.collectHtml(() {
       toHtmlVisitor.translateHtml(request.html);
-      toHtmlVisitor.describePayload(request.params, 'Parameters');
+      toHtmlVisitor.describePayload(params, 'Parameters');
       toHtmlVisitor.describePayload(request.result, 'Returns');
     }));
     if (request.deprecated) {
       writeln('@deprecated');
     }
-    String resultClass;
+
+    String? resultClass;
     String futureClass;
-    if (request.result == null) {
-      futureClass = 'Future';
-    } else {
+    var hasResult = request.result != null;
+    if (hasResult) {
       resultClass = camelJoin([request.domainName, request.method, 'result'],
           doCapitalize: true);
       futureClass = 'Future<$resultClass>';
+    } else {
+      futureClass = 'Future';
     }
+
     writeln('$futureClass $methodName(${args.join(', ')}) async {');
     indent(() {
       var requestClass = camelJoin(
           [request.domainName, request.method, 'params'],
           doCapitalize: true);
       var paramsVar = 'null';
-      if (request.params != null) {
+      if (params != null) {
         paramsVar = 'params';
         var args = <String>[];
         var optionalArgs = <String>[];
-        for (var field in request.params.fields) {
+        for (var field in params.fields) {
           if (field.optional) {
             optionalArgs.add('${field.name}: ${field.name}');
           } else {
@@ -237,7 +240,7 @@
       }
       var methodJson = "'${request.longMethod}'";
       writeln('var result = await server.send($methodJson, $paramsVar);');
-      if (request.result != null) {
+      if (resultClass != null) {
         var kind = 'null';
         if (requestClass == 'EditGetRefactoringParams') {
           kind = 'kind';
diff --git a/pkg/analysis_server/tool/spec/codegen_java.dart b/pkg/analysis_server/tool/spec/codegen_java.dart
index 341e4e1..54b48e8 100644
--- a/pkg/analysis_server/tool/spec/codegen_java.dart
+++ b/pkg/analysis_server/tool/spec/codegen_java.dart
@@ -22,9 +22,9 @@
 
 /// Iterate through the values in [map] in the order of increasing keys.
 Iterable<String> _valuesSortedByKey(Map<String, String> map) {
-  var keys = map.keys.toList();
-  keys.sort();
-  return keys.map((String key) => map[key]);
+  var entries = map.entries.toList();
+  entries.sort((a, b) => a.key.compareTo(b.key));
+  return entries.map((e) => e.value);
 }
 
 /// Common code for all Java code generation.
@@ -46,7 +46,7 @@
     'Override': 'OverrideMember',
   };
 
-  _CodegenJavaState _state;
+  _CodegenJavaState _state = _CodegenJavaState();
 
   /// Visitor used to produce doc comments.
   final ToHtmlVisitor toHtmlVisitor;
@@ -125,19 +125,17 @@
 
   /// Return a suitable representation of [name] as the name of a Java variable.
   String javaName(String name) {
-    if (_variableRenames.containsKey(name)) {
-      return _variableRenames[name];
-    }
-    return name;
+    return _variableRenames[name] ?? name;
   }
 
   /// Convert the given [TypeDecl] to a Java type.
   String javaType(TypeDecl type, [bool optional = false]) {
     if (type is TypeReference) {
-      TypeReference resolvedType = resolveTypeReferenceChain(type);
+      var resolvedType = resolveTypeReferenceChain(type) as TypeReference;
       var typeName = resolvedType.typeName;
-      if (_typeRenames.containsKey(typeName)) {
-        typeName = _typeRenames[typeName];
+      var renameTo = _typeRenames[typeName];
+      if (renameTo != null) {
+        typeName = renameTo;
         if (optional) {
           if (typeName == 'boolean') {
             typeName = 'Boolean';
diff --git a/pkg/analysis_server/tool/spec/codegen_java_types.dart b/pkg/analysis_server/tool/spec/codegen_java_types.dart
index a59a788..cd11d2c 100644
--- a/pkg/analysis_server/tool/spec/codegen_java_types.dart
+++ b/pkg/analysis_server/tool/spec/codegen_java_types.dart
@@ -58,15 +58,16 @@
         isRefactoringFeedback ||
         isRefactoringOption) {
       var type = impliedType.type;
-      if (type is TypeObject || type is TypeEnum) {
+      if (type != null && (type is TypeObject || type is TypeEnum)) {
         // This is for situations such as 'Override' where the name in the spec
         // doesn't match the java object that we generate:
         var typeNameInJava = typeNameInSpec;
-        if (_typeRenames.containsKey(typeNameInSpec)) {
-          typeNameInJava = _typeRenames[typeNameInSpec];
+        var renamedTo = _typeRenames[typeNameInSpec];
+        if (renamedTo != null) {
+          typeNameInJava = renamedTo;
         }
         map['$typeNameInJava.java'] = (String pkgPath) async {
-          String superclassName;
+          String? superclassName;
           if (isRefactoringFeedback) {
             superclassName = 'RefactoringFeedback';
           }
@@ -100,7 +101,7 @@
 
 class CodegenJavaType extends CodegenJavaVisitor {
   final String className;
-  final String superclassName;
+  final String? superclassName;
   final bool generateGetters;
   final bool generateSetters;
 
@@ -114,7 +115,7 @@
     return camelJoin([request.method, 'consumer'], doCapitalize: true);
   }
 
-  void emitType(TypeDecl type, dom.Element html) {
+  void emitType(TypeDecl type, dom.Element? html) {
     outputHeader(javaStyle: true);
     writeln('package org.dartlang.analysis.server.protocol;');
     writeln();
@@ -231,7 +232,7 @@
     }
   }
 
-  void _writeTypeEnum(TypeDecl type, dom.Element html) {
+  void _writeTypeEnum(TypeDecl type, dom.Element? html) {
     javadocComment(toHtmlVisitor.collectHtml(() {
       toHtmlVisitor.translateHtml(html);
       toHtmlVisitor.br();
@@ -255,7 +256,7 @@
     });
   }
 
-  void _writeTypeObject(TypeDecl type, dom.Element html) {
+  void _writeTypeObject(TypeDecl type, dom.Element? html) {
     writeln('import java.util.Arrays;');
     writeln('import java.util.List;');
     writeln('import java.util.Map;');
diff --git a/pkg/analysis_server/tool/spec/codegen_matchers.dart b/pkg/analysis_server/tool/spec/codegen_matchers.dart
index 2e53975..9e0a9d1 100644
--- a/pkg/analysis_server/tool/spec/codegen_matchers.dart
+++ b/pkg/analysis_server/tool/spec/codegen_matchers.dart
@@ -22,7 +22,7 @@
 
   /// Short human-readable string describing the context of the matcher being
   /// created.
-  String context;
+  late String context;
 
   CodegenMatchersVisitor(Api api)
       : toHtmlVisitor = ToHtmlVisitor(api),
@@ -39,19 +39,20 @@
   /// matches the given [type].
   void makeMatcher(ImpliedType impliedType) {
     context = impliedType.humanReadableName;
+    var impliedTypeType = impliedType.type;
     docComment(toHtmlVisitor.collectHtml(() {
       toHtmlVisitor.p(() {
         toHtmlVisitor.write(context);
       });
-      if (impliedType.type != null) {
-        toHtmlVisitor.showType(null, impliedType.type);
+      if (impliedTypeType != null) {
+        toHtmlVisitor.showType(null, impliedTypeType);
       }
     }));
     write('final Matcher ${camelJoin(['is', impliedType.camelName])} = ');
-    if (impliedType.type == null) {
+    if (impliedTypeType == null) {
       write('isNull');
     } else {
-      visitTypeDecl(impliedType.type);
+      visitTypeDecl(impliedTypeType);
     }
     writeln(';');
     writeln();
diff --git a/pkg/analysis_server/tool/spec/codegen_protocol_constants.dart b/pkg/analysis_server/tool/spec/codegen_protocol_constants.dart
index 511f260..f6cf4f0 100644
--- a/pkg/analysis_server/tool/spec/codegen_protocol_constants.dart
+++ b/pkg/analysis_server/tool/spec/codegen_protocol_constants.dart
@@ -62,6 +62,15 @@
     codeGeneratorSettings.languageName = 'dart';
   }
 
+  /// Generate the given [constant].
+  void generateConstant(_Constant constant) {
+    write('const String ');
+    write(constant.name);
+    write(' = ');
+    write(constant.value);
+    writeln(';');
+  }
+
   /// Generate all of the constants associates with the [api].
   void generateConstants() {
     writeln("const String PROTOCOL_VERSION = '${api.version}';");
@@ -71,19 +80,10 @@
     var constants = visitor.constants;
     constants.sort((first, second) => first.name.compareTo(second.name));
     for (var constant in constants) {
-      generateContant(constant);
+      generateConstant(constant);
     }
   }
 
-  /// Generate the given [constant].
-  void generateContant(_Constant constant) {
-    write('const String ');
-    write(constant.name);
-    write(' = ');
-    write(constant.value);
-    writeln(';');
-  }
-
   @override
   void visitApi() {
     outputHeader(year: '2017');
@@ -139,7 +139,7 @@
   /// Generate a constant for each of the fields in the given [type], where the
   /// name of each constant will be composed from the [parentName] and the name
   /// of the field.
-  void _addFieldConstants(String parentName, TypeObject type) {
+  void _addFieldConstants(String parentName, TypeObject? type) {
     if (type == null) {
       return;
     }
diff --git a/pkg/analysis_server/tool/spec/from_html.dart b/pkg/analysis_server/tool/spec/from_html.dart
index 237a6a7..bf64d22 100644
--- a/pkg/analysis_server/tool/spec/from_html.dart
+++ b/pkg/analysis_server/tool/spec/from_html.dart
@@ -75,8 +75,8 @@
     Api api;
     var versions = <String>[];
     var domains = <Domain>[];
-    Types types;
-    Refactorings refactorings;
+    var types = Types({}, null);
+    var refactorings = Refactorings([], null);
     recurse(html, 'api', {
       'domain': (dom.Element element) {
         domains.add(domainFromHtml(element));
@@ -109,6 +109,10 @@
       {List<String> optionalAttributes = const []}) {
     var attributesFound = <String>{};
     element.attributes.forEach((name, value) {
+      if (name is! String) {
+        throw Exception(
+            '$context: Only string attribute names expected: $name');
+      }
       if (!requiredAttributes.contains(name) &&
           !optionalAttributes.contains(name)) {
         throw Exception(
@@ -125,7 +129,7 @@
   }
 
   /// Check that the given [element] has the given [expectedName].
-  void checkName(dom.Element element, String expectedName, [String context]) {
+  void checkName(dom.Element element, String expectedName, [String? context]) {
     if (element.localName != expectedName) {
       context ??= element.localName;
       throw Exception(
@@ -143,19 +147,22 @@
   /// Child elements can occur in any order.
   Domain domainFromHtml(dom.Element html) {
     checkName(html, 'domain');
+
     var name = html.attributes['name'];
-    var context = name ?? 'domain';
+    if (name == null) {
+      throw Exception('domains: name not specified');
+    }
+
     var experimental = html.attributes['experimental'] == 'true';
-    checkAttributes(html, ['name'], context,
-        optionalAttributes: ['experimental']);
+    checkAttributes(html, ['name'], name, optionalAttributes: ['experimental']);
     var requests = <Request>[];
     var notifications = <Notification>[];
-    recurse(html, context, {
+    recurse(html, name, {
       'request': (dom.Element child) {
-        requests.add(requestFromHtml(child, context));
+        requests.add(requestFromHtml(child, name));
       },
       'notification': (dom.Element child) {
-        notifications.add(notificationFromHtml(child, context));
+        notifications.add(notificationFromHtml(child, name));
       }
     });
     return Domain(name, requests, notifications, html,
@@ -188,18 +195,30 @@
   /// Child elements can occur in any order.
   Notification notificationFromHtml(dom.Element html, String context) {
     var domainName = getAncestor(html, 'domain', context).attributes['name'];
+    if (domainName == null) {
+      throw Exception('$context: domain not specified');
+    }
+
     checkName(html, 'notification', context);
+
     var event = html.attributes['event'];
-    context = '$context.${event ?? 'event'}';
-    checkAttributes(html, ['event'], context,
-        optionalAttributes: ['experimental']);
-    var experimental = html.attributes['experimental'] == 'true';
-    TypeObject params;
+    if (event == null) {
+      throw Exception('$context: event not specified');
+    }
+
+    context = '$context.$event';
+
+    TypeObject? params;
     recurse(html, context, {
       'params': (dom.Element child) {
         params = typeObjectFromHtml(child, '$context.params');
       }
     });
+
+    checkAttributes(html, ['event'], context,
+        optionalAttributes: ['experimental']);
+    var experimental = html.attributes['experimental'] == 'true';
+
     return Notification(domainName, event, params, html,
         experimental: experimental);
   }
@@ -253,25 +272,29 @@
       },
       'map': (dom.Element child) {
         checkAttributes(child, [], context);
-        TypeDecl keyType;
-        TypeDecl valueType;
+        TypeDecl? keyTypeNullable;
+        TypeDecl? valueTypeNullable;
         recurse(child, context, {
           'key': (dom.Element child) {
-            if (keyType != null) {
+            if (keyTypeNullable != null) {
               throw Exception('$context: Key type already specified');
             }
-            keyType = processContentsAsType(child, '$context.key');
+            keyTypeNullable = processContentsAsType(child, '$context.key');
           },
           'value': (dom.Element child) {
-            if (valueType != null) {
+            if (valueTypeNullable != null) {
               throw Exception('$context: Value type already specified');
             }
-            valueType = processContentsAsType(child, '$context.value');
+            valueTypeNullable = processContentsAsType(child, '$context.value');
           }
         });
-        if (keyType == null) {
-          throw Exception('$context: Key type not specified');
+        var keyType = keyTypeNullable;
+        if (keyType is! TypeReference) {
+          throw Exception(
+            '$context: Key type not specified, or not a reference',
+          );
         }
+        var valueType = valueTypeNullable;
         if (valueType == null) {
           throw Exception('$context: Value type not specified');
         }
@@ -286,7 +309,7 @@
       },
       'union': (dom.Element child) {
         checkAttributes(child, ['field'], context);
-        var field = child.attributes['field'];
+        var field = child.attributes['field']!;
         types.add(
             TypeUnion(processContentsAsTypes(child, context), field, child));
       }
@@ -299,7 +322,7 @@
     var htmlContents = File(filePath).readAsStringSync();
     var document = parser.parse(htmlContents);
     var htmlElement = document.children
-        .singleWhere((element) => element.localName.toLowerCase() == 'html');
+        .singleWhere((element) => element.localName!.toLowerCase() == 'html');
     return apiFromHtml(htmlElement);
   }
 
@@ -312,8 +335,9 @@
     }
     for (var node in parent.nodes) {
       if (node is dom.Element) {
-        if (elementProcessors.containsKey(node.localName)) {
-          elementProcessors[node.localName](node);
+        var processor = elementProcessors[node.localName];
+        if (processor != null) {
+          processor(node);
         } else if (specialElements.contains(node.localName)) {
           throw Exception('$context: Unexpected use of <${node.localName}>');
         } else {
@@ -336,17 +360,21 @@
   /// Child elements can occur in any order.
   Refactoring refactoringFromHtml(dom.Element html) {
     checkName(html, 'refactoring');
+
     var kind = html.attributes['kind'];
-    var context = kind ?? 'refactoring';
-    checkAttributes(html, ['kind'], context);
-    TypeObject feedback;
-    TypeObject options;
-    recurse(html, context, {
+    if (kind == null) {
+      throw Exception('refactorings: kind not specified');
+    }
+
+    checkAttributes(html, ['kind'], kind);
+    TypeObject? feedback;
+    TypeObject? options;
+    recurse(html, kind, {
       'feedback': (dom.Element child) {
-        feedback = typeObjectFromHtml(child, '$context.feedback');
+        feedback = typeObjectFromHtml(child, '$kind.feedback');
       },
       'options': (dom.Element child) {
-        options = typeObjectFromHtml(child, '$context.options');
+        options = typeObjectFromHtml(child, '$kind.options');
       }
     });
     return Refactoring(kind, feedback, options, html);
@@ -385,15 +413,24 @@
   /// Child elements can occur in any order.
   Request requestFromHtml(dom.Element html, String context) {
     var domainName = getAncestor(html, 'domain', context).attributes['name'];
+    if (domainName == null) {
+      throw Exception('$context: domain not specified');
+    }
+
     checkName(html, 'request', context);
+
     var method = html.attributes['method'];
-    context = '$context.${method ?? 'method'}';
+    if (method == null) {
+      throw Exception('$context: method not specified');
+    }
+
+    context = '$context.$method}';
     checkAttributes(html, ['method'], context,
         optionalAttributes: ['experimental', 'deprecated']);
     var experimental = html.attributes['experimental'] == 'true';
     var deprecated = html.attributes['deprecated'] == 'true';
-    TypeObject params;
-    TypeObject result;
+    TypeObject? params;
+    TypeObject? result;
     recurse(html, context, {
       'params': (dom.Element child) {
         params = typeObjectFromHtml(child, '$context.params');
@@ -417,11 +454,15 @@
   /// Child elements can occur in any order.
   TypeDefinition typeDefinitionFromHtml(dom.Element html) {
     checkName(html, 'type');
+
     var name = html.attributes['name'];
-    var context = name ?? 'type';
-    checkAttributes(html, ['name'], context,
+    if (name == null) {
+      throw Exception('types: name not specified');
+    }
+
+    checkAttributes(html, ['name'], name,
         optionalAttributes: ['experimental', 'deprecated']);
-    var type = processContentsAsType(html, context);
+    var type = processContentsAsType(html, name);
     var experimental = html.attributes['experimental'] == 'true';
     var deprecated = html.attributes['deprecated'] == 'true';
     return TypeDefinition(name, type, html,
@@ -482,8 +523,13 @@
   /// Child elements can occur in any order.
   TypeObjectField typeObjectFieldFromHtml(dom.Element html, String context) {
     checkName(html, 'field', context);
+
     var name = html.attributes['name'];
-    context = '$context.${name ?? 'field'}';
+    if (name == null) {
+      throw Exception('$context: name not specified');
+    }
+
+    context = '$context.$name}';
     checkAttributes(html, ['name'], context,
         optionalAttributes: [
           'optional',
@@ -554,7 +600,7 @@
         var api = reader.readApi();
         for (var typeDefinition in api.types) {
           typeDefinition.isExternal = true;
-          childElements.add(typeDefinition.html);
+          childElements.add(typeDefinition.html!);
           typeMap[typeDefinition.name] = typeDefinition;
         }
       },
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/Location.java b/pkg/analysis_server/tool/spec/generated/java/types/Location.java
index 2daf9de..1df7d78 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/Location.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/Location.java
@@ -61,14 +61,26 @@
   private final int startColumn;
 
   /**
+   * The one-based index of the line containing the character immediately following the range.
+   */
+  private final int endLine;
+
+  /**
+   * The one-based index of the column containing the character immediately following the range.
+   */
+  private final int endColumn;
+
+  /**
    * Constructor for {@link Location}.
    */
-  public Location(String file, int offset, int length, int startLine, int startColumn) {
+  public Location(String file, int offset, int length, int startLine, int startColumn, int endLine, int endColumn) {
     this.file = file;
     this.offset = offset;
     this.length = length;
     this.startLine = startLine;
     this.startColumn = startColumn;
+    this.endLine = endLine;
+    this.endColumn = endColumn;
   }
 
   @Override
@@ -80,7 +92,9 @@
         other.offset == offset &&
         other.length == length &&
         other.startLine == startLine &&
-        other.startColumn == startColumn;
+        other.startColumn == startColumn &&
+        other.endLine == endLine &&
+        other.endColumn == endColumn;
     }
     return false;
   }
@@ -91,7 +105,9 @@
     int length = jsonObject.get("length").getAsInt();
     int startLine = jsonObject.get("startLine").getAsInt();
     int startColumn = jsonObject.get("startColumn").getAsInt();
-    return new Location(file, offset, length, startLine, startColumn);
+    int endLine = jsonObject.get("endLine").getAsInt();
+    int endColumn = jsonObject.get("endColumn").getAsInt();
+    return new Location(file, offset, length, startLine, startColumn, endLine, endColumn);
   }
 
   public static List<Location> fromJsonArray(JsonArray jsonArray) {
@@ -107,6 +123,20 @@
   }
 
   /**
+   * The one-based index of the column containing the character immediately following the range.
+   */
+  public int getEndColumn() {
+    return endColumn;
+  }
+
+  /**
+   * The one-based index of the line containing the character immediately following the range.
+   */
+  public int getEndLine() {
+    return endLine;
+  }
+
+  /**
    * The file containing the range.
    */
   public String getFile() {
@@ -149,6 +179,8 @@
     builder.append(length);
     builder.append(startLine);
     builder.append(startColumn);
+    builder.append(endLine);
+    builder.append(endColumn);
     return builder.toHashCode();
   }
 
@@ -159,6 +191,8 @@
     jsonObject.addProperty("length", length);
     jsonObject.addProperty("startLine", startLine);
     jsonObject.addProperty("startColumn", startColumn);
+    jsonObject.addProperty("endLine", endLine);
+    jsonObject.addProperty("endColumn", endColumn);
     return jsonObject;
   }
 
@@ -175,7 +209,11 @@
     builder.append("startLine=");
     builder.append(startLine + ", ");
     builder.append("startColumn=");
-    builder.append(startColumn);
+    builder.append(startColumn + ", ");
+    builder.append("endLine=");
+    builder.append(endLine + ", ");
+    builder.append("endColumn=");
+    builder.append(endColumn);
     builder.append("]");
     return builder.toString();
   }
diff --git a/pkg/analysis_server/tool/spec/implied_types.dart b/pkg/analysis_server/tool/spec/implied_types.dart
index fb67058..6a49fcc 100644
--- a/pkg/analysis_server/tool/spec/implied_types.dart
+++ b/pkg/analysis_server/tool/spec/implied_types.dart
@@ -16,7 +16,7 @@
 class ImpliedType {
   final String camelName;
   final String humanReadableName;
-  final TypeDecl type;
+  final TypeDecl? type;
 
   /// Kind of implied type this is.  One of:
   /// - 'requestParams'
@@ -39,7 +39,7 @@
 
   _ImpliedTypesVisitor(Api api) : super(api);
 
-  void storeType(String name, String nameSuffix, TypeDecl type, String kind,
+  void storeType(String name, String? nameSuffix, TypeDecl? type, String kind,
       ApiNode apiNode) {
     var humanReadableName = name;
     var camelNameParts = name.split('.');
diff --git a/pkg/analysis_server/tool/spec/to_html.dart b/pkg/analysis_server/tool/spec/to_html.dart
index 35768e6..0bcc45e 100644
--- a/pkg/analysis_server/tool/spec/to_html.dart
+++ b/pkg/analysis_server/tool/spec/to_html.dart
@@ -175,9 +175,6 @@
       element('span', {'style': 'color:#999999'}, callback);
   void h1(void Function() callback) => element('h1', {}, callback);
   void h2(String cls, void Function() callback) {
-    if (cls == null) {
-      return element('h2', {}, callback);
-    }
     return element('h2', {'class': cls}, callback);
   }
 
@@ -191,7 +188,7 @@
   void i(void Function() callback) => element('i', {}, callback);
   void li(void Function() callback) => element('li', {}, callback);
   void link(String id, void Function() callback,
-      [Map<dynamic, String> attributes]) {
+      [Map<Object, String>? attributes]) {
     attributes ??= {};
     attributes['href'] = '#$id';
     element('a', attributes, callback);
@@ -226,7 +223,7 @@
   ///
   /// If [force] is true, then a section is inserted even if the payload is
   /// null.
-  void describePayload(TypeObject subType, String name, {bool force = false}) {
+  void describePayload(TypeObject? subType, String name, {bool force = false}) {
     if (force || subType != null) {
       h4(() {
         write(name);
@@ -298,9 +295,6 @@
   }
 
   void generateRefactoringsIndex(Iterable<Refactoring> refactorings) {
-    if (refactorings == null) {
-      return;
-    }
     h3(() {
       write('Refactorings');
       write(' (');
@@ -383,7 +377,7 @@
     });
   }
 
-  void javadocParams(TypeObject typeObject) {
+  void javadocParams(TypeObject? typeObject) {
     if (typeObject != null) {
       for (var field in typeObject.fields) {
         hangingIndent(() {
@@ -401,7 +395,8 @@
   ///
   /// If [typeForBolding] is supplied, then fields in this type are shown in
   /// boldface.
-  void showType(String shortDesc, TypeDecl type, [TypeObject typeForBolding]) {
+  void showType(String? shortDesc, TypeDecl type,
+      [TypeObject? typeForBolding]) {
     var fieldsToBold = <String>{};
     if (typeForBolding != null) {
       for (var field in typeForBolding.fields) {
@@ -421,19 +416,23 @@
 
   /// Copy the contents of the given HTML element, translating the special
   /// elements that define the API appropriately.
-  void translateHtml(dom.Element html, {bool squashParagraphs = false}) {
+  void translateHtml(dom.Element? html, {bool squashParagraphs = false}) {
+    if (html == null) {
+      return;
+    }
     for (var node in html.nodes) {
       if (node is dom.Element) {
-        if (squashParagraphs && node.localName == 'p') {
+        var localName = node.localName!;
+        if (squashParagraphs && localName == 'p') {
           translateHtml(node, squashParagraphs: squashParagraphs);
           continue;
         }
-        switch (node.localName) {
+        switch (localName) {
           case 'domains':
             generateDomainsHeader();
             break;
           case 'domain':
-            visitDomain(apiMappings.domains[node]);
+            visitDomain(apiMappings.domains[node]!);
             break;
           case 'head':
             head(() {
@@ -465,8 +464,8 @@
             generateIndex();
             break;
           default:
-            if (!ApiReader.specialElements.contains(node.localName)) {
-              element(node.localName, node.attributes, () {
+            if (!ApiReader.specialElements.contains(localName)) {
+              element(localName, node.attributes, () {
                 translateHtml(node, squashParagraphs: squashParagraphs);
               });
             }
@@ -705,15 +704,15 @@
 /// }
 class TypeVisitor extends HierarchicalApiVisitor
     with HtmlMixin, HtmlCodeGenerator {
-  /// Set of fields which should be shown in boldface, or null if no field
-  /// should be shown in boldface.
+  /// Set of fields which should be shown in boldface.
   final Set<String> fieldsToBold;
 
   /// True if a short description should be generated.  In a short description,
   /// objects are shown as simply "object", and enums are shown as "String".
   final bool short;
 
-  TypeVisitor(Api api, {this.fieldsToBold, this.short = false}) : super(api);
+  TypeVisitor(Api api, {this.fieldsToBold = const {}, this.short = false})
+      : super(api);
 
   @override
   void visitTypeEnum(TypeEnum typeEnum) {
@@ -756,7 +755,7 @@
     indent(() {
       for (var field in typeObject.fields) {
         write('"');
-        if (fieldsToBold != null && fieldsToBold.contains(field.name)) {
+        if (fieldsToBold.contains(field.name)) {
           b(() {
             write(field.name);
           });
diff --git a/pkg/analysis_server_client/CHANGELOG.md b/pkg/analysis_server_client/CHANGELOG.md
index 43563a1..d1f5f3f 100644
--- a/pkg/analysis_server_client/CHANGELOG.md
+++ b/pkg/analysis_server_client/CHANGELOG.md
@@ -1,3 +1,6 @@
+# 2.0.0-dev
+* Stable null safety release.
+
 # 1.1.3
  * Supports changes made to the Analysis Server protocol through Dart 2.8.0
  * Updates to use pedantic 1.9.0 and some internal refactoring. 
diff --git a/pkg/analysis_server_client/example/example.dart b/pkg/analysis_server_client/example/example.dart
index 41af85c..9790d78 100644
--- a/pkg/analysis_server_client/example/example.dart
+++ b/pkg/analysis_server_client/example/example.dart
@@ -35,7 +35,7 @@
       AnalysisSetAnalysisRootsParams([target], const []).toJson());
 
   // Continue to watch for analysis until the user presses Ctrl-C
-  StreamSubscription<ProcessSignal> subscription;
+  late StreamSubscription<ProcessSignal> subscription;
   subscription = ProcessSignal.sigint.watch().listen((_) async {
     print('Exiting...');
     // ignore: unawaited_futures
@@ -107,15 +107,14 @@
     } else {
       print('Server Error: ${params.message}');
     }
-    if (params.stackTrace != null) {
-      print(params.stackTrace);
-    }
+    print(params.stackTrace);
     super.onServerError(params);
   }
 
   @override
   void onServerStatus(ServerStatusParams params) {
-    if (!params.analysis.isAnalyzing) {
+    var analysisStatus = params.analysis;
+    if (analysisStatus != null && !analysisStatus.isAnalyzing) {
       // Whenever the server stops analyzing,
       // print a brief summary of what issues have been found.
       if (errorCount == 0) {
diff --git a/pkg/analysis_server_client/lib/handler/connection_handler.dart b/pkg/analysis_server_client/lib/handler/connection_handler.dart
index 107b361..f754fb5 100644
--- a/pkg/analysis_server_client/lib/handler/connection_handler.dart
+++ b/pkg/analysis_server_client/lib/handler/connection_handler.dart
@@ -1,10 +1,6 @@
 // Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
 // for 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".
 
 import 'dart:async';
 
@@ -58,7 +54,7 @@
 
   /// Return a future that completes with a `bool` indicating whether
   /// a connection was successfully established with the server.
-  Future<bool> serverConnected({Duration timeLimit}) {
+  Future<bool> serverConnected({Duration? timeLimit}) {
     var future = _connected.future;
     if (timeLimit != null) {
       future = future.timeout(timeLimit, onTimeout: () {
diff --git a/pkg/analysis_server_client/lib/listener/server_listener.dart b/pkg/analysis_server_client/lib/listener/server_listener.dart
index 3f1b074..6004996 100644
--- a/pkg/analysis_server_client/lib/listener/server_listener.dart
+++ b/pkg/analysis_server_client/lib/listener/server_listener.dart
@@ -43,16 +43,28 @@
 
   /// Called when the [Server] receives an unexpected message
   /// which is not a notification or response.
-  void unexpectedMessage(Map<String, dynamic> message) {
+  void unexpectedMessage(Map<String, Object?> message) {
     log('Unexpected message from server:', '$message');
   }
 
+  /// Called when the [Server] received a response, which is not an error,
+  /// but the result is not an JSON object.
+  void unexpectedNotificationFormat(Map<String, Object?> message) {
+    log('Unexpected notification format from server', '$message');
+  }
+
   /// Called when the [Server] recieved an unexpected response
   /// where the [id] does not match the [id] of an outstanding request.
-  void unexpectedResponse(Map<String, dynamic> message, id) {
+  void unexpectedResponse(Map<String, Object?> message, Object id) {
     log('Unexpected response from server', 'id=$id');
   }
 
+  /// Called when the [Server] received a response, which is not an error,
+  /// but the result is not an JSON object.
+  void unexpectedResponseFormat(Map<String, Object?> message) {
+    log('Unexpected response format from server', '$message');
+  }
+
   /// Called when the server process unexpectedly exits
   /// with a non-zero exit code.
   void unexpectedStop(int exitCode) {
diff --git a/pkg/analysis_server_client/lib/server.dart b/pkg/analysis_server_client/lib/server.dart
index d11442c..3d9dbb4 100644
--- a/pkg/analysis_server_client/lib/server.dart
+++ b/pkg/analysis_server_client/lib/server.dart
@@ -21,18 +21,20 @@
 class Server extends ServerBase {
   /// Server process object, or `null` if server hasn't been started yet
   /// or if the server has already been stopped.
-  Process _process;
+  Process? _process;
 
   /// The stderr subscription or `null` if either
   /// [listenToOutput] has not been called or [stop] has been called.
-  StreamSubscription<String> _stderrSubscription;
+  StreamSubscription<String>? _stderrSubscription;
 
   /// The stdout subscription or `null` if either
   /// [listenToOutput] has not been called or [stop] has been called.
-  StreamSubscription<String> _stdoutSubscription;
+  StreamSubscription<String>? _stdoutSubscription;
 
   Server(
-      {ServerListener listener, Process process, bool stdioPassthrough = false})
+      {ServerListener? listener,
+      Process? process,
+      bool stdioPassthrough = false})
       : _process = process,
         super(listener: listener, stdioPassthrough: stdioPassthrough);
 
@@ -40,7 +42,7 @@
   @override
   Future<int> kill({String reason = 'none'}) {
     listener?.killingServerProcess(reason);
-    final process = _process;
+    final process = _process!;
     _process = null;
     process.kill();
     return process.exitCode;
@@ -49,12 +51,12 @@
   /// Start listening to output from the server,
   /// and deliver notifications to [notificationProcessor].
   @override
-  void listenToOutput({NotificationProcessor notificationProcessor}) {
-    _stdoutSubscription = _process.stdout
+  void listenToOutput({NotificationProcessor? notificationProcessor}) {
+    _stdoutSubscription = _process!.stdout
         .transform(utf8.decoder)
         .transform(LineSplitter())
         .listen((line) => outputProcessor(line, notificationProcessor));
-    _stderrSubscription = _process.stderr
+    _stderrSubscription = _process!.stderr
         .transform(utf8.decoder)
         .transform(LineSplitter())
         .listen((line) => errorProcessor(line, notificationProcessor));
@@ -68,9 +70,9 @@
   /// If the server acknowledges the command with an error response,
   /// the future will be completed with an error.
   @override
-  Future<Map<String, dynamic>> send(
-          String method, Map<String, dynamic> params) =>
-      sendCommandWith(method, params, _process.stdin.add);
+  Future<Map<String, Object?>?> send(
+          String method, Map<String, Object?>? params) =>
+      sendCommandWith(method, params, _process!.stdin.add);
 
   /// Start the server.
   ///
@@ -86,14 +88,14 @@
   /// locally for debugging.
   @override
   Future start({
-    String clientId,
-    String clientVersion,
-    int diagnosticPort,
-    String instrumentationLogFile,
+    String? clientId,
+    String? clientVersion,
+    int? diagnosticPort,
+    String? instrumentationLogFile,
     bool profileServer = false,
-    String sdkPath,
-    String serverPath,
-    int servicesPort,
+    String? sdkPath,
+    String? serverPath,
+    int? servicesPort,
     bool suppressAnalytics = true,
     bool useAnalysisHighlight2 = false,
     bool enableAsserts = false,
@@ -152,9 +154,10 @@
         useAnalysisHighlight2: useAnalysisHighlight2));
 
     listener?.startingServer(dartBinary, arguments);
-    _process = await Process.start(dartBinary, arguments);
+    final process = await Process.start(dartBinary, arguments);
+    _process = process;
     // ignore: unawaited_futures
-    _process.exitCode.then((int code) {
+    process.exitCode.then((int code) {
       if (code != 0 && _process != null) {
         // Report an error if server abruptly terminated
         listener?.unexpectedStop(code);
@@ -165,19 +168,21 @@
   /// Attempt to gracefully shutdown the server.
   /// If that fails, then kill the process.
   @override
-  Future<int> stop({Duration timeLimit}) async {
+  Future<int> stop({Duration? timeLimit}) async {
     timeLimit ??= const Duration(seconds: 5);
-    if (_process == null) {
+
+    final process = _process;
+    if (process == null) {
       // Process already exited
       return -1;
     }
+
     final future = send(SERVER_REQUEST_SHUTDOWN, null);
-    final process = _process;
     _process = null;
     await future
         // fall through to wait for exit
         .timeout(timeLimit, onTimeout: () {
-      return null;
+      return {};
     }).whenComplete(() async {
       await _stderrSubscription?.cancel();
       _stderrSubscription = null;
diff --git a/pkg/analysis_server_client/lib/src/protocol/protocol_base.dart b/pkg/analysis_server_client/lib/src/protocol/protocol_base.dart
index 8fa072d..017d34c 100644
--- a/pkg/analysis_server_client/lib/src/protocol/protocol_base.dart
+++ b/pkg/analysis_server_client/lib/src/protocol/protocol_base.dart
@@ -34,7 +34,7 @@
 
   /// A table mapping the names of notification parameters to their values, or
   /// `null` if there are no notification parameters.
-  final Map<String, Object> params;
+  final Map<String, Object?>? params;
 
   /// Initialize a newly created [Notification] to have the given [event] name.
   /// If [params] is provided, it will be used as the params; otherwise no
@@ -44,7 +44,7 @@
   /// Initialize a newly created instance based on the given JSON data.
   factory Notification.fromJson(Map json) {
     return Notification(json[Notification.EVENT],
-        json[Notification.PARAMS] as Map<String, Object>);
+        json[Notification.PARAMS] as Map<String, Object?>);
   }
 
   /// Return a table representing the structure of the Json object that will be
@@ -52,6 +52,7 @@
   Map<String, Object> toJson() {
     var jsonObject = <String, Object>{};
     jsonObject[EVENT] = event;
+    var params = this.params;
     if (params != null) {
       jsonObject[PARAMS] = params;
     }
@@ -83,84 +84,18 @@
   final String method;
 
   /// A table mapping the names of request parameters to their values.
-  final Map<String, Object> params;
+  final Map<String, Object?> params;
 
   /// The time (milliseconds since epoch) at which the client made the request
   /// or `null` if this information is not provided by the client.
-  final int clientRequestTime;
+  final int? clientRequestTime;
 
   /// Initialize a newly created [Request] to have the given [id] and [method]
   /// name. If [params] is supplied, it is used as the "params" map for the
   /// request. Otherwise an empty "params" map is allocated.
   Request(this.id, this.method,
-      [Map<String, Object> params, this.clientRequestTime])
-      : params = params ?? <String, Object>{};
-
-  /// Return a request parsed from the given json, or `null` if the [data] is
-  /// not a valid json representation of a request. The [data] is expected to
-  /// have the following format:
-  ///
-  ///   {
-  ///     'clientRequestTime': millisecondsSinceEpoch
-  ///     'id': String,
-  ///     'method': methodName,
-  ///     'params': {
-  ///       paramter_name: value
-  ///     }
-  ///   }
-  ///
-  /// where both the parameters and clientRequestTime are optional.
-  ///
-  /// The parameters can contain any number of name/value pairs. The
-  /// clientRequestTime must be an int representing the time at which the client
-  /// issued the request (milliseconds since epoch).
-  factory Request.fromJson(Map<String, Object> result) {
-    var id = result[Request.ID];
-    var method = result[Request.METHOD];
-    if (id is! String || method is! String) {
-      return null;
-    }
-    var time = result[Request.CLIENT_REQUEST_TIME];
-    if (time != null && time is! int) {
-      return null;
-    }
-    var params = result[Request.PARAMS];
-    if (params is Map || params == null) {
-      return Request(id, method, params as Map<String, Object>, time);
-    } else {
-      return null;
-    }
-  }
-
-  /// Return a request parsed from the given [data], or `null` if the [data] is
-  /// not a valid json representation of a request. The [data] is expected to
-  /// have the following format:
-  ///
-  ///   {
-  ///     'clientRequestTime': millisecondsSinceEpoch
-  ///     'id': String,
-  ///     'method': methodName,
-  ///     'params': {
-  ///       paramter_name: value
-  ///     }
-  ///   }
-  ///
-  /// where both the parameters and clientRequestTime are optional.
-  ///
-  /// The parameters can contain any number of name/value pairs. The
-  /// clientRequestTime must be an int representing the time at which the client
-  /// issued the request (milliseconds since epoch).
-  factory Request.fromString(String data) {
-    try {
-      var result = json.decode(data);
-      if (result is Map) {
-        return Request.fromJson(result as Map<String, dynamic>);
-      }
-      return null;
-    } catch (exception) {
-      return null;
-    }
-  }
+      [Map<String, Object?>? params, this.clientRequestTime])
+      : params = params ?? <String, Object?>{};
 
   @override
   int get hashCode {
@@ -185,13 +120,14 @@
     if (params.isNotEmpty) {
       jsonObject[PARAMS] = params;
     }
+    var clientRequestTime = this.clientRequestTime;
     if (clientRequestTime != null) {
       jsonObject[CLIENT_REQUEST_TIME] = clientRequestTime;
     }
     return jsonObject;
   }
 
-  bool _equalLists(List first, List second) {
+  bool _equalLists(List? first, List? second) {
     if (first == null) {
       return second == null;
     }
@@ -210,7 +146,7 @@
     return true;
   }
 
-  bool _equalMaps(Map first, Map second) {
+  bool _equalMaps(Map? first, Map? second) {
     if (first == null) {
       return second == null;
     }
@@ -231,7 +167,7 @@
     return true;
   }
 
-  bool _equalObjects(Object first, Object second) {
+  bool _equalObjects(Object? first, Object? second) {
     if (first == null) {
       return second == null;
     }
@@ -252,6 +188,72 @@
     }
     return first == second;
   }
+
+  /// Return a request parsed from the given json, or `null` if the [data] is
+  /// not a valid json representation of a request. The [data] is expected to
+  /// have the following format:
+  ///
+  ///   {
+  ///     'clientRequestTime': millisecondsSinceEpoch
+  ///     'id': String,
+  ///     'method': methodName,
+  ///     'params': {
+  ///       paramter_name: value
+  ///     }
+  ///   }
+  ///
+  /// where both the parameters and clientRequestTime are optional.
+  ///
+  /// The parameters can contain any number of name/value pairs. The
+  /// clientRequestTime must be an int representing the time at which the client
+  /// issued the request (milliseconds since epoch).
+  static Request? fromJson(Map<String, Object?> result) {
+    var id = result[Request.ID];
+    var method = result[Request.METHOD];
+    if (id is! String || method is! String) {
+      return null;
+    }
+    var time = result[Request.CLIENT_REQUEST_TIME];
+    if (time is! int?) {
+      return null;
+    }
+    var params = result[Request.PARAMS];
+    if (params is Map<String, Object?>?) {
+      return Request(id, method, params, time);
+    } else {
+      return null;
+    }
+  }
+
+  /// Return a request parsed from the given [data], or `null` if the [data] is
+  /// not a valid json representation of a request. The [data] is expected to
+  /// have the following format:
+  ///
+  ///   {
+  ///     'clientRequestTime': millisecondsSinceEpoch
+  ///     'id': String,
+  ///     'method': methodName,
+  ///     'params': {
+  ///       paramter_name: value
+  ///     }
+  ///   }
+  ///
+  /// where both the parameters and clientRequestTime are optional.
+  ///
+  /// The parameters can contain any number of name/value pairs. The
+  /// clientRequestTime must be an int representing the time at which the client
+  /// issued the request (milliseconds since epoch).
+  static Request? fromString(String data) {
+    try {
+      var result = json.decode(data);
+      if (result is Map<String, Object?>) {
+        return Request.fromJson(result);
+      }
+      return null;
+    } catch (exception) {
+      return null;
+    }
+  }
 }
 
 /// An exception that occurred during the handling of a request that requires
@@ -301,17 +303,17 @@
 
   /// The error that was caused by attempting to handle the request, or `null` if
   /// there was no error.
-  final RequestError error;
+  final RequestError? error;
 
   /// A table mapping the names of result fields to their values. Should be
   /// `null` if there is no result to send.
-  Map<String, Object> result;
+  Map<String, Object?>? result;
 
   /// Initialize a newly created instance to represent a response to a request
-  /// with the given [id]. If [_result] is provided, it will be used as the
+  /// with the given [id]. If [result] is provided, it will be used as the
   /// result; otherwise an empty result will be used. If an [error] is provided
   /// then the response will represent an error condition.
-  Response(this.id, {Map<String, Object> result, this.error}) : result = result;
+  Response(this.id, {this.result, this.error});
 
   /// Create and return the `DEBUG_PORT_COULD_NOT_BE_OPENED` error response.
   Response.debugPortCouldNotBeOpened(Request request, dynamic error)
@@ -340,30 +342,6 @@
             error: RequestError(RequestErrorCode.FORMAT_WITH_ERRORS,
                 'Error during `edit.format`: source contains syntax errors.'));
 
-  /// Initialize a newly created instance based on the given JSON data.
-  factory Response.fromJson(Map json) {
-    try {
-      Object id = json[Response.ID];
-      if (id is! String) {
-        return null;
-      }
-      Object error = json[Response.ERROR];
-      RequestError decodedError;
-      if (error is Map) {
-        decodedError =
-            RequestError.fromJson(ResponseDecoder(null), '.error', error);
-      }
-      Object result = json[Response.RESULT];
-      Map<String, Object> decodedResult;
-      if (result is Map) {
-        decodedResult = result as Map<String, Object>;
-      }
-      return Response(id, error: decodedError, result: decodedResult);
-    } catch (exception) {
-      return null;
-    }
-  }
-
   /// Initialize a newly created instance to represent the
   /// GET_ERRORS_INVALID_FILE error condition.
   Response.getErrorsInvalidFile(Request request)
@@ -526,12 +504,41 @@
   Map<String, Object> toJson() {
     var jsonObject = <String, Object>{};
     jsonObject[ID] = id;
+    var error = this.error;
     if (error != null) {
       jsonObject[ERROR] = error.toJson();
     }
+    var result = this.result;
     if (result != null) {
       jsonObject[RESULT] = result;
     }
     return jsonObject;
   }
+
+  /// Initialize a newly created instance based on the given JSON data.
+  static Response? fromJson(Map<String, Object?> json) {
+    try {
+      var id = json[Response.ID];
+      if (id is! String) {
+        return null;
+      }
+
+      RequestError? decodedError;
+      var error = json[Response.ERROR];
+      if (error is Map) {
+        decodedError =
+            RequestError.fromJson(ResponseDecoder(null), '.error', error);
+      }
+
+      Map<String, Object?>? decodedResult;
+      var result = json[Response.RESULT];
+      if (result is Map<String, Object?>) {
+        decodedResult = result;
+      }
+
+      return Response(id, error: decodedError, result: decodedResult);
+    } catch (exception) {
+      return null;
+    }
+  }
 }
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 dc0fead..69c55bc 100644
--- a/pkg/analysis_server_client/lib/src/protocol/protocol_common.dart
+++ b/pkg/analysis_server_client/lib/src/protocol/protocol_common.dart
@@ -21,23 +21,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AddContentOverlay implements HasToJson {
-  String _content;
-
   /// The new content of the file.
-  String get content => _content;
+  String content;
 
-  /// The new content of the file.
-  set content(String value) {
-    assert(value != null);
-    _content = value;
-  }
-
-  AddContentOverlay(String content) {
-    this.content = content;
-  }
+  AddContentOverlay(this.content);
 
   factory AddContentOverlay.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       if (json['type'] != 'add') {
@@ -57,8 +47,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['type'] = 'add';
     result['content'] = content;
     return result;
@@ -100,100 +90,33 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisError implements HasToJson {
-  AnalysisErrorSeverity _severity;
-
-  AnalysisErrorType _type;
-
-  Location _location;
-
-  String _message;
-
-  String _correction;
-
-  String _code;
-
-  String _url;
-
-  List<DiagnosticMessage> _contextMessages;
-
-  bool _hasFix;
-
   /// The severity of the error.
-  AnalysisErrorSeverity get severity => _severity;
-
-  /// The severity of the error.
-  set severity(AnalysisErrorSeverity value) {
-    assert(value != null);
-    _severity = value;
-  }
+  AnalysisErrorSeverity severity;
 
   /// The type of the error.
-  AnalysisErrorType get type => _type;
-
-  /// The type of the error.
-  set type(AnalysisErrorType value) {
-    assert(value != null);
-    _type = value;
-  }
+  AnalysisErrorType type;
 
   /// The location associated with the error.
-  Location get location => _location;
-
-  /// The location associated with the error.
-  set location(Location value) {
-    assert(value != null);
-    _location = value;
-  }
+  Location location;
 
   /// The message to be displayed for this error. The message should indicate
   /// what is wrong with the code and why it is wrong.
-  String get message => _message;
-
-  /// The message to be displayed for this error. The message should indicate
-  /// what is wrong with the code and why it is wrong.
-  set message(String value) {
-    assert(value != null);
-    _message = value;
-  }
+  String message;
 
   /// The correction message to be displayed for this error. The correction
   /// message should indicate how the user can fix the error. The field is
   /// omitted if there is no correction message associated with the error code.
-  String get correction => _correction;
-
-  /// The correction message to be displayed for this error. The correction
-  /// message should indicate how the user can fix the error. The field is
-  /// omitted if there is no correction message associated with the error code.
-  set correction(String value) {
-    _correction = value;
-  }
+  String? correction;
 
   /// The name, as a string, of the error code associated with this error.
-  String get code => _code;
-
-  /// The name, as a string, of the error code associated with this error.
-  set code(String value) {
-    assert(value != null);
-    _code = value;
-  }
+  String code;
 
   /// 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;
-  }
+  String? url;
 
   /// 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;
-  }
+  List<DiagnosticMessage>? contextMessages;
 
   /// A hint to indicate to interested clients that this error has an
   /// associated fix (or fixes). The absence of this field implies there are
@@ -204,40 +127,14 @@
   /// 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;
+  bool? 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.
-  set hasFix(bool value) {
-    _hasFix = value;
-  }
-
-  AnalysisError(AnalysisErrorSeverity severity, AnalysisErrorType type,
-      Location location, String message, String code,
-      {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;
-  }
+  AnalysisError(
+      this.severity, this.type, this.location, this.message, this.code,
+      {this.correction, this.url, this.contextMessages, this.hasFix});
 
   factory AnalysisError.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       AnalysisErrorSeverity severity;
@@ -268,7 +165,7 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'message');
       }
-      String correction;
+      String? correction;
       if (json.containsKey('correction')) {
         correction = jsonDecoder.decodeString(
             jsonPath + '.correction', json['correction']);
@@ -279,19 +176,19 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'code');
       }
-      String url;
+      String? url;
       if (json.containsKey('url')) {
         url = jsonDecoder.decodeString(jsonPath + '.url', json['url']);
       }
-      List<DiagnosticMessage> contextMessages;
+      List<DiagnosticMessage>? contextMessages;
       if (json.containsKey('contextMessages')) {
         contextMessages = jsonDecoder.decodeList(
             jsonPath + '.contextMessages',
             json['contextMessages'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 DiagnosticMessage.fromJson(jsonDecoder, jsonPath, json));
       }
-      bool hasFix;
+      bool? hasFix;
       if (json.containsKey('hasFix')) {
         hasFix = jsonDecoder.decodeBool(jsonPath + '.hasFix', json['hasFix']);
       }
@@ -306,24 +203,28 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['severity'] = severity.toJson();
     result['type'] = type.toJson();
     result['location'] = location.toJson();
     result['message'] = message;
+    var correction = this.correction;
     if (correction != null) {
       result['correction'] = correction;
     }
     result['code'] = code;
+    var url = this.url;
     if (url != null) {
       result['url'] = url;
     }
+    var contextMessages = this.contextMessages;
     if (contextMessages != null) {
       result['contextMessages'] = contextMessages
           .map((DiagnosticMessage value) => value.toJson())
           .toList();
     }
+    var hasFix = this.hasFix;
     if (hasFix != null) {
       result['hasFix'] = hasFix;
     }
@@ -408,7 +309,7 @@
   }
 
   factory AnalysisErrorSeverity.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     if (json is String) {
       try {
         return AnalysisErrorSeverity(json);
@@ -501,7 +402,7 @@
   }
 
   factory AnalysisErrorType.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     if (json is String) {
       try {
         return AnalysisErrorType(json);
@@ -527,23 +428,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class ChangeContentOverlay implements HasToJson {
-  List<SourceEdit> _edits;
-
   /// The edits to be applied to the file.
-  List<SourceEdit> get edits => _edits;
+  List<SourceEdit> edits;
 
-  /// The edits to be applied to the file.
-  set edits(List<SourceEdit> value) {
-    assert(value != null);
-    _edits = value;
-  }
-
-  ChangeContentOverlay(List<SourceEdit> edits) {
-    this.edits = edits;
-  }
+  ChangeContentOverlay(this.edits);
 
   factory ChangeContentOverlay.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       if (json['type'] != 'change') {
@@ -554,7 +445,7 @@
         edits = jsonDecoder.decodeList(
             jsonPath + '.edits',
             json['edits'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 SourceEdit.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'edits');
@@ -566,8 +457,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['type'] = 'change';
     result['edits'] = edits.map((SourceEdit value) => value.toJson()).toList();
     return result;
@@ -624,210 +515,67 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class CompletionSuggestion implements HasToJson {
-  CompletionSuggestionKind _kind;
-
-  int _relevance;
-
-  String _completion;
-
-  String _displayText;
-
-  int _replacementOffset;
-
-  int _replacementLength;
-
-  int _selectionOffset;
-
-  int _selectionLength;
-
-  bool _isDeprecated;
-
-  bool _isPotential;
-
-  String _docSummary;
-
-  String _docComplete;
-
-  String _declaringType;
-
-  String _defaultArgumentListString;
-
-  List<int> _defaultArgumentListTextRanges;
-
-  Element _element;
-
-  String _returnType;
-
-  List<String> _parameterNames;
-
-  List<String> _parameterTypes;
-
-  int _requiredParameterCount;
-
-  bool _hasNamedParameters;
-
-  String _parameterName;
-
-  String _parameterType;
-
   /// The kind of element being suggested.
-  CompletionSuggestionKind get kind => _kind;
-
-  /// The kind of element being suggested.
-  set kind(CompletionSuggestionKind value) {
-    assert(value != null);
-    _kind = value;
-  }
+  CompletionSuggestionKind kind;
 
   /// The relevance of this completion suggestion where a higher number
   /// indicates a higher relevance.
-  int get relevance => _relevance;
-
-  /// The relevance of this completion suggestion where a higher number
-  /// indicates a higher relevance.
-  set relevance(int value) {
-    assert(value != null);
-    _relevance = value;
-  }
+  int relevance;
 
   /// The identifier to be inserted if the suggestion is selected. If the
   /// suggestion is for a method or function, the client might want to
   /// additionally insert a template for the parameters. The information
   /// required in order to do so is contained in other fields.
-  String get completion => _completion;
-
-  /// The identifier to be inserted if the suggestion is selected. If the
-  /// suggestion is for a method or function, the client might want to
-  /// additionally insert a template for the parameters. The information
-  /// required in order to do so is contained in other fields.
-  set completion(String value) {
-    assert(value != null);
-    _completion = value;
-  }
+  String completion;
 
   /// Text to be displayed in, for example, a completion pop-up. This field is
   /// only defined if the displayed text should be different than the
   /// completion. Otherwise it is omitted.
-  String get displayText => _displayText;
-
-  /// Text to be displayed in, for example, a completion pop-up. This field is
-  /// only defined if the displayed text should be different than the
-  /// completion. Otherwise it is omitted.
-  set displayText(String value) {
-    _displayText = value;
-  }
+  String? displayText;
 
   /// The offset of the start of the text to be replaced. If supplied, this
   /// should be used in preference to the offset provided on the containing
   /// completion results. This value may be provided independently of
   /// replacementLength (for example if only one differs from the completion
   /// result value).
-  int get replacementOffset => _replacementOffset;
-
-  /// The offset of the start of the text to be replaced. If supplied, this
-  /// should be used in preference to the offset provided on the containing
-  /// completion results. This value may be provided independently of
-  /// replacementLength (for example if only one differs from the completion
-  /// result value).
-  set replacementOffset(int value) {
-    _replacementOffset = value;
-  }
+  int? replacementOffset;
 
   /// The length of the text to be replaced. If supplied, this should be used
   /// in preference to the offset provided on the containing completion
   /// results. This value may be provided independently of replacementOffset
   /// (for example if only one differs from the completion result value).
-  int get replacementLength => _replacementLength;
-
-  /// The length of the text to be replaced. If supplied, this should be used
-  /// in preference to the offset provided on the containing completion
-  /// results. This value may be provided independently of replacementOffset
-  /// (for example if only one differs from the completion result value).
-  set replacementLength(int value) {
-    _replacementLength = value;
-  }
+  int? replacementLength;
 
   /// The offset, relative to the beginning of the completion, of where the
   /// selection should be placed after insertion.
-  int get selectionOffset => _selectionOffset;
-
-  /// The offset, relative to the beginning of the completion, of where the
-  /// selection should be placed after insertion.
-  set selectionOffset(int value) {
-    assert(value != null);
-    _selectionOffset = value;
-  }
+  int selectionOffset;
 
   /// The number of characters that should be selected after insertion.
-  int get selectionLength => _selectionLength;
-
-  /// The number of characters that should be selected after insertion.
-  set selectionLength(int value) {
-    assert(value != null);
-    _selectionLength = value;
-  }
+  int selectionLength;
 
   /// True if the suggested element is deprecated.
-  bool get isDeprecated => _isDeprecated;
-
-  /// True if the suggested element is deprecated.
-  set isDeprecated(bool value) {
-    assert(value != null);
-    _isDeprecated = value;
-  }
+  bool isDeprecated;
 
   /// True if the element is not known to be valid for the target. This happens
   /// if the type of the target is dynamic.
-  bool get isPotential => _isPotential;
-
-  /// True if the element is not known to be valid for the target. This happens
-  /// if the type of the target is dynamic.
-  set isPotential(bool value) {
-    assert(value != null);
-    _isPotential = value;
-  }
+  bool isPotential;
 
   /// An abbreviated version of the Dartdoc associated with the element being
   /// suggested. This field is omitted if there is no Dartdoc associated with
   /// the element.
-  String get docSummary => _docSummary;
-
-  /// An abbreviated version of the Dartdoc associated with the element being
-  /// suggested. This field is omitted if there is no Dartdoc associated with
-  /// the element.
-  set docSummary(String value) {
-    _docSummary = value;
-  }
+  String? docSummary;
 
   /// The Dartdoc associated with the element being suggested. This field is
   /// omitted if there is no Dartdoc associated with the element.
-  String get docComplete => _docComplete;
-
-  /// The Dartdoc associated with the element being suggested. This field is
-  /// omitted if there is no Dartdoc associated with the element.
-  set docComplete(String value) {
-    _docComplete = value;
-  }
+  String? docComplete;
 
   /// 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.
-  set declaringType(String value) {
-    _declaringType = value;
-  }
+  String? declaringType;
 
   /// A default String for use in generating argument list source contents on
   /// the client side.
-  String get defaultArgumentListString => _defaultArgumentListString;
-
-  /// A default String for use in generating argument list source contents on
-  /// the client side.
-  set defaultArgumentListString(String value) {
-    _defaultArgumentListString = value;
-  }
+  String? defaultArgumentListString;
 
   /// Pairs of offsets and lengths describing 'defaultArgumentListString' text
   /// ranges suitable for use by clients to set up linked edits of default
@@ -835,153 +583,69 @@
   /// y', the corresponding text range [0, 1, 3, 1], indicates two text ranges
   /// of length 1, starting at offsets 0 and 3. Clients can use these ranges to
   /// treat the 'x' and 'y' values specially for linked edits.
-  List<int> get defaultArgumentListTextRanges => _defaultArgumentListTextRanges;
-
-  /// Pairs of offsets and lengths describing 'defaultArgumentListString' text
-  /// ranges suitable for use by clients to set up linked edits of default
-  /// argument source contents. For example, given an argument list string 'x,
-  /// y', the corresponding text range [0, 1, 3, 1], indicates two text ranges
-  /// of length 1, starting at offsets 0 and 3. Clients can use these ranges to
-  /// treat the 'x' and 'y' values specially for linked edits.
-  set defaultArgumentListTextRanges(List<int> value) {
-    _defaultArgumentListTextRanges = value;
-  }
+  List<int>? defaultArgumentListTextRanges;
 
   /// Information about the element reference being suggested.
-  Element get element => _element;
-
-  /// Information about the element reference being suggested.
-  set element(Element value) {
-    _element = value;
-  }
+  Element? element;
 
   /// 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.
-  set returnType(String value) {
-    _returnType = value;
-  }
+  String? returnType;
 
   /// The names of the parameters of the function or method being suggested.
   /// This field is omitted if the suggested element is not a setter, function
   /// or method.
-  List<String> get parameterNames => _parameterNames;
-
-  /// The names of the parameters of the function or method being suggested.
-  /// This field is omitted if the suggested element is not a setter, function
-  /// or method.
-  set parameterNames(List<String> value) {
-    _parameterNames = value;
-  }
+  List<String>? parameterNames;
 
   /// The types of the parameters of the function or method being suggested.
   /// This field is omitted if the parameterNames field is omitted.
-  List<String> get parameterTypes => _parameterTypes;
-
-  /// The types of the parameters of the function or method being suggested.
-  /// This field is omitted if the parameterNames field is omitted.
-  set parameterTypes(List<String> value) {
-    _parameterTypes = value;
-  }
+  List<String>? parameterTypes;
 
   /// The number of required parameters for the function or method being
   /// suggested. This field is omitted if the parameterNames field is omitted.
-  int get requiredParameterCount => _requiredParameterCount;
-
-  /// The number of required parameters for the function or method being
-  /// suggested. This field is omitted if the parameterNames field is omitted.
-  set requiredParameterCount(int value) {
-    _requiredParameterCount = value;
-  }
+  int? requiredParameterCount;
 
   /// True if the function or method being suggested has at least one named
   /// parameter. This field is omitted if the parameterNames field is omitted.
-  bool get hasNamedParameters => _hasNamedParameters;
-
-  /// True if the function or method being suggested has at least one named
-  /// parameter. This field is omitted if the parameterNames field is omitted.
-  set hasNamedParameters(bool value) {
-    _hasNamedParameters = value;
-  }
+  bool? hasNamedParameters;
 
   /// The name of the optional parameter being suggested. This field is omitted
   /// if the suggestion is not the addition of an optional argument within an
   /// argument list.
-  String get parameterName => _parameterName;
-
-  /// The name of the optional parameter being suggested. This field is omitted
-  /// if the suggestion is not the addition of an optional argument within an
-  /// argument list.
-  set parameterName(String value) {
-    _parameterName = value;
-  }
+  String? parameterName;
 
   /// The type of the options parameter being suggested. This field is omitted
   /// if the parameterName field is omitted.
-  String get parameterType => _parameterType;
-
-  /// The type of the options parameter being suggested. This field is omitted
-  /// if the parameterName field is omitted.
-  set parameterType(String value) {
-    _parameterType = value;
-  }
+  String? parameterType;
 
   CompletionSuggestion(
-      CompletionSuggestionKind kind,
-      int relevance,
-      String completion,
-      int selectionOffset,
-      int selectionLength,
-      bool isDeprecated,
-      bool isPotential,
-      {String displayText,
-      int replacementOffset,
-      int replacementLength,
-      String docSummary,
-      String docComplete,
-      String declaringType,
-      String defaultArgumentListString,
-      List<int> defaultArgumentListTextRanges,
-      Element element,
-      String returnType,
-      List<String> parameterNames,
-      List<String> parameterTypes,
-      int requiredParameterCount,
-      bool hasNamedParameters,
-      String parameterName,
-      String parameterType}) {
-    this.kind = kind;
-    this.relevance = relevance;
-    this.completion = completion;
-    this.displayText = displayText;
-    this.replacementOffset = replacementOffset;
-    this.replacementLength = replacementLength;
-    this.selectionOffset = selectionOffset;
-    this.selectionLength = selectionLength;
-    this.isDeprecated = isDeprecated;
-    this.isPotential = isPotential;
-    this.docSummary = docSummary;
-    this.docComplete = docComplete;
-    this.declaringType = declaringType;
-    this.defaultArgumentListString = defaultArgumentListString;
-    this.defaultArgumentListTextRanges = defaultArgumentListTextRanges;
-    this.element = element;
-    this.returnType = returnType;
-    this.parameterNames = parameterNames;
-    this.parameterTypes = parameterTypes;
-    this.requiredParameterCount = requiredParameterCount;
-    this.hasNamedParameters = hasNamedParameters;
-    this.parameterName = parameterName;
-    this.parameterType = parameterType;
-  }
+      this.kind,
+      this.relevance,
+      this.completion,
+      this.selectionOffset,
+      this.selectionLength,
+      this.isDeprecated,
+      this.isPotential,
+      {this.displayText,
+      this.replacementOffset,
+      this.replacementLength,
+      this.docSummary,
+      this.docComplete,
+      this.declaringType,
+      this.defaultArgumentListString,
+      this.defaultArgumentListTextRanges,
+      this.element,
+      this.returnType,
+      this.parameterNames,
+      this.parameterTypes,
+      this.requiredParameterCount,
+      this.hasNamedParameters,
+      this.parameterName,
+      this.parameterType});
 
   factory CompletionSuggestion.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       CompletionSuggestionKind kind;
@@ -1005,17 +669,17 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'completion');
       }
-      String displayText;
+      String? displayText;
       if (json.containsKey('displayText')) {
         displayText = jsonDecoder.decodeString(
             jsonPath + '.displayText', json['displayText']);
       }
-      int replacementOffset;
+      int? replacementOffset;
       if (json.containsKey('replacementOffset')) {
         replacementOffset = jsonDecoder.decodeInt(
             jsonPath + '.replacementOffset', json['replacementOffset']);
       }
-      int replacementLength;
+      int? replacementLength;
       if (json.containsKey('replacementLength')) {
         replacementLength = jsonDecoder.decodeInt(
             jsonPath + '.replacementLength', json['replacementLength']);
@@ -1048,71 +712,71 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'isPotential');
       }
-      String docSummary;
+      String? docSummary;
       if (json.containsKey('docSummary')) {
         docSummary = jsonDecoder.decodeString(
             jsonPath + '.docSummary', json['docSummary']);
       }
-      String docComplete;
+      String? docComplete;
       if (json.containsKey('docComplete')) {
         docComplete = jsonDecoder.decodeString(
             jsonPath + '.docComplete', json['docComplete']);
       }
-      String declaringType;
+      String? declaringType;
       if (json.containsKey('declaringType')) {
         declaringType = jsonDecoder.decodeString(
             jsonPath + '.declaringType', json['declaringType']);
       }
-      String defaultArgumentListString;
+      String? defaultArgumentListString;
       if (json.containsKey('defaultArgumentListString')) {
         defaultArgumentListString = jsonDecoder.decodeString(
             jsonPath + '.defaultArgumentListString',
             json['defaultArgumentListString']);
       }
-      List<int> defaultArgumentListTextRanges;
+      List<int>? defaultArgumentListTextRanges;
       if (json.containsKey('defaultArgumentListTextRanges')) {
         defaultArgumentListTextRanges = jsonDecoder.decodeList(
             jsonPath + '.defaultArgumentListTextRanges',
             json['defaultArgumentListTextRanges'],
             jsonDecoder.decodeInt);
       }
-      Element element;
+      Element? element;
       if (json.containsKey('element')) {
         element = Element.fromJson(
             jsonDecoder, jsonPath + '.element', json['element']);
       }
-      String returnType;
+      String? returnType;
       if (json.containsKey('returnType')) {
         returnType = jsonDecoder.decodeString(
             jsonPath + '.returnType', json['returnType']);
       }
-      List<String> parameterNames;
+      List<String>? parameterNames;
       if (json.containsKey('parameterNames')) {
         parameterNames = jsonDecoder.decodeList(jsonPath + '.parameterNames',
             json['parameterNames'], jsonDecoder.decodeString);
       }
-      List<String> parameterTypes;
+      List<String>? parameterTypes;
       if (json.containsKey('parameterTypes')) {
         parameterTypes = jsonDecoder.decodeList(jsonPath + '.parameterTypes',
             json['parameterTypes'], jsonDecoder.decodeString);
       }
-      int requiredParameterCount;
+      int? requiredParameterCount;
       if (json.containsKey('requiredParameterCount')) {
         requiredParameterCount = jsonDecoder.decodeInt(
             jsonPath + '.requiredParameterCount',
             json['requiredParameterCount']);
       }
-      bool hasNamedParameters;
+      bool? hasNamedParameters;
       if (json.containsKey('hasNamedParameters')) {
         hasNamedParameters = jsonDecoder.decodeBool(
             jsonPath + '.hasNamedParameters', json['hasNamedParameters']);
       }
-      String parameterName;
+      String? parameterName;
       if (json.containsKey('parameterName')) {
         parameterName = jsonDecoder.decodeString(
             jsonPath + '.parameterName', json['parameterName']);
       }
-      String parameterType;
+      String? parameterType;
       if (json.containsKey('parameterType')) {
         parameterType = jsonDecoder.decodeString(
             jsonPath + '.parameterType', json['parameterType']);
@@ -1141,17 +805,20 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['kind'] = kind.toJson();
     result['relevance'] = relevance;
     result['completion'] = completion;
+    var displayText = this.displayText;
     if (displayText != null) {
       result['displayText'] = displayText;
     }
+    var replacementOffset = this.replacementOffset;
     if (replacementOffset != null) {
       result['replacementOffset'] = replacementOffset;
     }
+    var replacementLength = this.replacementLength;
     if (replacementLength != null) {
       result['replacementLength'] = replacementLength;
     }
@@ -1159,42 +826,55 @@
     result['selectionLength'] = selectionLength;
     result['isDeprecated'] = isDeprecated;
     result['isPotential'] = isPotential;
+    var docSummary = this.docSummary;
     if (docSummary != null) {
       result['docSummary'] = docSummary;
     }
+    var docComplete = this.docComplete;
     if (docComplete != null) {
       result['docComplete'] = docComplete;
     }
+    var declaringType = this.declaringType;
     if (declaringType != null) {
       result['declaringType'] = declaringType;
     }
+    var defaultArgumentListString = this.defaultArgumentListString;
     if (defaultArgumentListString != null) {
       result['defaultArgumentListString'] = defaultArgumentListString;
     }
+    var defaultArgumentListTextRanges = this.defaultArgumentListTextRanges;
     if (defaultArgumentListTextRanges != null) {
       result['defaultArgumentListTextRanges'] = defaultArgumentListTextRanges;
     }
+    var element = this.element;
     if (element != null) {
       result['element'] = element.toJson();
     }
+    var returnType = this.returnType;
     if (returnType != null) {
       result['returnType'] = returnType;
     }
+    var parameterNames = this.parameterNames;
     if (parameterNames != null) {
       result['parameterNames'] = parameterNames;
     }
+    var parameterTypes = this.parameterTypes;
     if (parameterTypes != null) {
       result['parameterTypes'] = parameterTypes;
     }
+    var requiredParameterCount = this.requiredParameterCount;
     if (requiredParameterCount != null) {
       result['requiredParameterCount'] = requiredParameterCount;
     }
+    var hasNamedParameters = this.hasNamedParameters;
     if (hasNamedParameters != null) {
       result['hasNamedParameters'] = hasNamedParameters;
     }
+    var parameterName = this.parameterName;
     if (parameterName != null) {
       result['parameterName'] = parameterName;
     }
+    var parameterType = this.parameterType;
     if (parameterType != null) {
       result['parameterType'] = parameterType;
     }
@@ -1380,7 +1060,7 @@
   }
 
   factory CompletionSuggestionKind.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     if (json is String) {
       try {
         return CompletionSuggestionKind(json);
@@ -1406,37 +1086,17 @@
 ///
 /// 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;
-  }
+  String message;
 
   /// The location associated with or referenced by the message. Clients should
   /// provide the ability to navigate to the location.
-  Location get location => _location;
+  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;
-  }
+  DiagnosticMessage(this.message, this.location);
 
   factory DiagnosticMessage.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String message;
@@ -1460,8 +1120,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['message'] = message;
     result['location'] = location.toJson();
     return result;
@@ -1526,49 +1186,15 @@
     return flags;
   }
 
-  ElementKind _kind;
-
-  String _name;
-
-  Location _location;
-
-  int _flags;
-
-  String _parameters;
-
-  String _returnType;
-
-  String _typeParameters;
-
-  String _aliasedType;
-
   /// The kind of the element.
-  ElementKind get kind => _kind;
-
-  /// The kind of the element.
-  set kind(ElementKind value) {
-    assert(value != null);
-    _kind = value;
-  }
+  ElementKind kind;
 
   /// The name of the element. This is typically used as the label in the
   /// outline.
-  String get name => _name;
-
-  /// The name of the element. This is typically used as the label in the
-  /// outline.
-  set name(String value) {
-    assert(value != null);
-    _name = value;
-  }
+  String name;
 
   /// The location of the name in the declaration of the element.
-  Location get location => _location;
-
-  /// The location of the name in the declaration of the element.
-  set location(Location value) {
-    _location = value;
-  }
+  Location? location;
 
   /// A bit-map containing the following flags:
   ///
@@ -1579,86 +1205,36 @@
   ///   top-level function or field
   /// - 0x10 - set if the element is private
   /// - 0x20 - set if the element is deprecated
-  int get flags => _flags;
-
-  /// A bit-map containing the following flags:
-  ///
-  /// - 0x01 - set if the element is explicitly or implicitly abstract
-  /// - 0x02 - set if the element was declared to be ‘const’
-  /// - 0x04 - set if the element was declared to be ‘final’
-  /// - 0x08 - set if the element is a static member of a class or is a
-  ///   top-level function or field
-  /// - 0x10 - set if the element is private
-  /// - 0x20 - set if the element is deprecated
-  set flags(int value) {
-    assert(value != null);
-    _flags = value;
-  }
+  int flags;
 
   /// The parameter list for the element. If the element is not a method or
   /// function this field will not be defined. If the element doesn't have
   /// parameters (e.g. getter), this field will not be defined. If the element
   /// has zero parameters, this field will have a value of "()".
-  String get parameters => _parameters;
-
-  /// The parameter list for the element. If the element is not a method or
-  /// function this field will not be defined. If the element doesn't have
-  /// parameters (e.g. getter), this field will not be defined. If the element
-  /// has zero parameters, this field will have a value of "()".
-  set parameters(String value) {
-    _parameters = value;
-  }
+  String? parameters;
 
   /// 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.
-  set returnType(String value) {
-    _returnType = value;
-  }
+  String? returnType;
 
   /// The type parameter list for the element. If the element doesn't have type
   /// parameters, this field will not be defined.
-  String get typeParameters => _typeParameters;
-
-  /// The type parameter list for the element. If the element doesn't have type
-  /// parameters, this field will not be defined.
-  set typeParameters(String value) {
-    _typeParameters = value;
-  }
+  String? typeParameters;
 
   /// If the element is a type alias, this field is the aliased type. Otherwise
   /// this field will not be defined.
-  String get aliasedType => _aliasedType;
+  String? aliasedType;
 
-  /// If the element is a type alias, this field is the aliased type. Otherwise
-  /// this field will not be defined.
-  set aliasedType(String value) {
-    _aliasedType = value;
-  }
-
-  Element(ElementKind kind, String name, int flags,
-      {Location location,
-      String parameters,
-      String returnType,
-      String typeParameters,
-      String aliasedType}) {
-    this.kind = kind;
-    this.name = name;
-    this.location = location;
-    this.flags = flags;
-    this.parameters = parameters;
-    this.returnType = returnType;
-    this.typeParameters = typeParameters;
-    this.aliasedType = aliasedType;
-  }
+  Element(this.kind, this.name, this.flags,
+      {this.location,
+      this.parameters,
+      this.returnType,
+      this.typeParameters,
+      this.aliasedType});
 
   factory Element.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       ElementKind kind;
@@ -1674,7 +1250,7 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'name');
       }
-      Location location;
+      Location? location;
       if (json.containsKey('location')) {
         location = Location.fromJson(
             jsonDecoder, jsonPath + '.location', json['location']);
@@ -1685,22 +1261,22 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'flags');
       }
-      String parameters;
+      String? parameters;
       if (json.containsKey('parameters')) {
         parameters = jsonDecoder.decodeString(
             jsonPath + '.parameters', json['parameters']);
       }
-      String returnType;
+      String? returnType;
       if (json.containsKey('returnType')) {
         returnType = jsonDecoder.decodeString(
             jsonPath + '.returnType', json['returnType']);
       }
-      String typeParameters;
+      String? typeParameters;
       if (json.containsKey('typeParameters')) {
         typeParameters = jsonDecoder.decodeString(
             jsonPath + '.typeParameters', json['typeParameters']);
       }
-      String aliasedType;
+      String? aliasedType;
       if (json.containsKey('aliasedType')) {
         aliasedType = jsonDecoder.decodeString(
             jsonPath + '.aliasedType', json['aliasedType']);
@@ -1724,23 +1300,28 @@
   bool get isDeprecated => (flags & FLAG_DEPRECATED) != 0;
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['kind'] = kind.toJson();
     result['name'] = name;
+    var location = this.location;
     if (location != null) {
       result['location'] = location.toJson();
     }
     result['flags'] = flags;
+    var parameters = this.parameters;
     if (parameters != null) {
       result['parameters'] = parameters;
     }
+    var returnType = this.returnType;
     if (returnType != null) {
       result['returnType'] = returnType;
     }
+    var typeParameters = this.typeParameters;
     if (typeParameters != null) {
       result['typeParameters'] = typeParameters;
     }
+    var aliasedType = this.aliasedType;
     if (aliasedType != null) {
       result['aliasedType'] = aliasedType;
     }
@@ -1975,7 +1556,7 @@
   }
 
   factory ElementKind.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     if (json is String) {
       try {
         return ElementKind(json);
@@ -2076,7 +1657,7 @@
   }
 
   factory FoldingKind.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     if (json is String) {
       try {
         return FoldingKind(json);
@@ -2103,47 +1684,19 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class FoldingRegion implements HasToJson {
-  FoldingKind _kind;
-
-  int _offset;
-
-  int _length;
-
   /// The kind of the region.
-  FoldingKind get kind => _kind;
-
-  /// The kind of the region.
-  set kind(FoldingKind value) {
-    assert(value != null);
-    _kind = value;
-  }
+  FoldingKind kind;
 
   /// The offset of the region to be folded.
-  int get offset => _offset;
-
-  /// The offset of the region to be folded.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
+  int offset;
 
   /// The length of the region to be folded.
-  int get length => _length;
+  int length;
 
-  /// The length of the region to be folded.
-  set length(int value) {
-    assert(value != null);
-    _length = value;
-  }
-
-  FoldingRegion(FoldingKind kind, int offset, int length) {
-    this.kind = kind;
-    this.offset = offset;
-    this.length = length;
-  }
+  FoldingRegion(this.kind, this.offset, this.length);
 
   factory FoldingRegion.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       FoldingKind kind;
@@ -2172,8 +1725,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['kind'] = kind.toJson();
     result['offset'] = offset;
     result['length'] = length;
@@ -2213,47 +1766,19 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class HighlightRegion implements HasToJson {
-  HighlightRegionType _type;
-
-  int _offset;
-
-  int _length;
-
   /// The type of highlight associated with the region.
-  HighlightRegionType get type => _type;
-
-  /// The type of highlight associated with the region.
-  set type(HighlightRegionType value) {
-    assert(value != null);
-    _type = value;
-  }
+  HighlightRegionType type;
 
   /// The offset of the region to be highlighted.
-  int get offset => _offset;
-
-  /// The offset of the region to be highlighted.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
+  int offset;
 
   /// The length of the region to be highlighted.
-  int get length => _length;
+  int length;
 
-  /// The length of the region to be highlighted.
-  set length(int value) {
-    assert(value != null);
-    _length = value;
-  }
-
-  HighlightRegion(HighlightRegionType type, int offset, int length) {
-    this.type = type;
-    this.offset = offset;
-    this.length = length;
-  }
+  HighlightRegion(this.type, this.offset, this.length);
 
   factory HighlightRegion.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       HighlightRegionType type;
@@ -2282,8 +1807,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['type'] = type.toJson();
     result['offset'] = offset;
     result['length'] = length;
@@ -2860,7 +2385,7 @@
   }
 
   factory HighlightRegionType.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     if (json is String) {
       try {
         return HighlightRegionType(json);
@@ -2889,69 +2414,25 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class KytheEntry implements HasToJson {
-  KytheVName _source;
-
-  String _kind;
-
-  KytheVName _target;
-
-  String _fact;
-
-  List<int> _value;
-
   /// The ticket of the source node.
-  KytheVName get source => _source;
-
-  /// The ticket of the source node.
-  set source(KytheVName value) {
-    assert(value != null);
-    _source = value;
-  }
+  KytheVName source;
 
   /// An edge label. The schema defines which labels are meaningful.
-  String get kind => _kind;
-
-  /// An edge label. The schema defines which labels are meaningful.
-  set kind(String value) {
-    _kind = value;
-  }
+  String? kind;
 
   /// The ticket of the target node.
-  KytheVName get target => _target;
-
-  /// The ticket of the target node.
-  set target(KytheVName value) {
-    _target = value;
-  }
+  KytheVName? target;
 
   /// A fact label. The schema defines which fact labels are meaningful.
-  String get fact => _fact;
-
-  /// A fact label. The schema defines which fact labels are meaningful.
-  set fact(String value) {
-    assert(value != null);
-    _fact = value;
-  }
+  String fact;
 
   /// The String value of the fact.
-  List<int> get value => _value;
+  List<int>? value;
 
-  /// The String value of the fact.
-  set value(List<int> value) {
-    _value = value;
-  }
-
-  KytheEntry(KytheVName source, String fact,
-      {String kind, KytheVName target, List<int> value}) {
-    this.source = source;
-    this.kind = kind;
-    this.target = target;
-    this.fact = fact;
-    this.value = value;
-  }
+  KytheEntry(this.source, this.fact, {this.kind, this.target, this.value});
 
   factory KytheEntry.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       KytheVName source;
@@ -2961,11 +2442,11 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'source');
       }
-      String kind;
+      String? kind;
       if (json.containsKey('kind')) {
         kind = jsonDecoder.decodeString(jsonPath + '.kind', json['kind']);
       }
-      KytheVName target;
+      KytheVName? target;
       if (json.containsKey('target')) {
         target = KytheVName.fromJson(
             jsonDecoder, jsonPath + '.target', json['target']);
@@ -2976,7 +2457,7 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'fact');
       }
-      List<int> value;
+      List<int>? value;
       if (json.containsKey('value')) {
         value = jsonDecoder.decodeList(
             jsonPath + '.value', json['value'], jsonDecoder.decodeInt);
@@ -2988,16 +2469,19 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['source'] = source.toJson();
+    var kind = this.kind;
     if (kind != null) {
       result['kind'] = kind;
     }
+    var target = this.target;
     if (target != null) {
       result['target'] = target.toJson();
     }
     result['fact'] = fact;
+    var value = this.value;
     if (value != null) {
       result['value'] = value;
     }
@@ -3043,82 +2527,30 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class KytheVName implements HasToJson {
-  String _signature;
-
-  String _corpus;
-
-  String _root;
-
-  String _path;
-
-  String _language;
-
   /// An opaque signature generated by the analyzer.
-  String get signature => _signature;
-
-  /// An opaque signature generated by the analyzer.
-  set signature(String value) {
-    assert(value != null);
-    _signature = value;
-  }
+  String signature;
 
   /// 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
-  /// repository.
-  set corpus(String value) {
-    assert(value != null);
-    _corpus = value;
-  }
+  String corpus;
 
   /// A corpus-specific root label, typically a directory path or project
   /// identifier, denoting a distinct subset of the corpus. This may also be
   /// used to designate virtual collections like generated files.
-  String get root => _root;
-
-  /// A corpus-specific root label, typically a directory path or project
-  /// identifier, denoting a distinct subset of the corpus. This may also be
-  /// used to designate virtual collections like generated files.
-  set root(String value) {
-    assert(value != null);
-    _root = value;
-  }
+  String root;
 
   /// A path-structured label describing the “location” of the named object
   /// relative to the corpus and the root.
-  String get path => _path;
-
-  /// A path-structured label describing the “location” of the named object
-  /// relative to the corpus and the root.
-  set path(String value) {
-    assert(value != null);
-    _path = value;
-  }
+  String path;
 
   /// The language this name belongs to.
-  String get language => _language;
+  String language;
 
-  /// The language this name belongs to.
-  set language(String value) {
-    assert(value != null);
-    _language = value;
-  }
-
-  KytheVName(String signature, String corpus, String root, String path,
-      String language) {
-    this.signature = signature;
-    this.corpus = corpus;
-    this.root = root;
-    this.path = path;
-    this.language = language;
-  }
+  KytheVName(this.signature, this.corpus, this.root, this.path, this.language);
 
   factory KytheVName.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String signature;
@@ -3160,8 +2592,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['signature'] = signature;
     result['corpus'] = corpus;
     result['root'] = root;
@@ -3207,50 +2639,20 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class LinkedEditGroup implements HasToJson {
-  List<Position> _positions;
-
-  int _length;
-
-  List<LinkedEditSuggestion> _suggestions;
-
   /// The positions of the regions that should be edited simultaneously.
-  List<Position> get positions => _positions;
-
-  /// The positions of the regions that should be edited simultaneously.
-  set positions(List<Position> value) {
-    assert(value != null);
-    _positions = value;
-  }
+  List<Position> positions;
 
   /// The length of the regions that should be edited simultaneously.
-  int get length => _length;
-
-  /// The length of the regions that should be edited simultaneously.
-  set length(int value) {
-    assert(value != null);
-    _length = value;
-  }
+  int length;
 
   /// Pre-computed suggestions for what every region might want to be changed
   /// to.
-  List<LinkedEditSuggestion> get suggestions => _suggestions;
+  List<LinkedEditSuggestion> suggestions;
 
-  /// Pre-computed suggestions for what every region might want to be changed
-  /// to.
-  set suggestions(List<LinkedEditSuggestion> value) {
-    assert(value != null);
-    _suggestions = value;
-  }
-
-  LinkedEditGroup(List<Position> positions, int length,
-      List<LinkedEditSuggestion> suggestions) {
-    this.positions = positions;
-    this.length = length;
-    this.suggestions = suggestions;
-  }
+  LinkedEditGroup(this.positions, this.length, this.suggestions);
 
   factory LinkedEditGroup.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       List<Position> positions;
@@ -3258,7 +2660,7 @@
         positions = jsonDecoder.decodeList(
             jsonPath + '.positions',
             json['positions'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 Position.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'positions');
@@ -3274,7 +2676,7 @@
         suggestions = jsonDecoder.decodeList(
             jsonPath + '.suggestions',
             json['suggestions'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 LinkedEditSuggestion.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'suggestions');
@@ -3289,8 +2691,8 @@
   LinkedEditGroup.empty() : this(<Position>[], 0, <LinkedEditSuggestion>[]);
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['positions'] =
         positions.map((Position value) => value.toJson()).toList();
     result['length'] = length;
@@ -3345,35 +2747,16 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class LinkedEditSuggestion implements HasToJson {
-  String _value;
-
-  LinkedEditSuggestionKind _kind;
-
   /// The value that could be used to replace all of the linked edit regions.
-  String get value => _value;
-
-  /// The value that could be used to replace all of the linked edit regions.
-  set value(String value) {
-    assert(value != null);
-    _value = value;
-  }
+  String value;
 
   /// The kind of value being proposed.
-  LinkedEditSuggestionKind get kind => _kind;
+  LinkedEditSuggestionKind kind;
 
-  /// The kind of value being proposed.
-  set kind(LinkedEditSuggestionKind value) {
-    assert(value != null);
-    _kind = value;
-  }
-
-  LinkedEditSuggestion(String value, LinkedEditSuggestionKind kind) {
-    this.value = value;
-    this.kind = kind;
-  }
+  LinkedEditSuggestion(this.value, this.kind);
 
   factory LinkedEditSuggestion.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String value;
@@ -3396,8 +2779,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['value'] = value;
     result['kind'] = kind.toJson();
     return result;
@@ -3470,7 +2853,7 @@
   }
 
   factory LinkedEditSuggestionKind.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     if (json is String) {
       try {
         return LinkedEditSuggestionKind(json);
@@ -3495,80 +2878,42 @@
 ///   "length": int
 ///   "startLine": int
 ///   "startColumn": int
+///   "endLine": int
+///   "endColumn": int
 /// }
 ///
 /// Clients may not extend, implement or mix-in this class.
 class Location implements HasToJson {
-  String _file;
-
-  int _offset;
-
-  int _length;
-
-  int _startLine;
-
-  int _startColumn;
-
   /// The file containing the range.
-  String get file => _file;
-
-  /// The file containing the range.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// The offset of the range.
-  int get offset => _offset;
-
-  /// The offset of the range.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
+  int offset;
 
   /// The length of the range.
-  int get length => _length;
-
-  /// The length of the range.
-  set length(int value) {
-    assert(value != null);
-    _length = value;
-  }
+  int length;
 
   /// The one-based index of the line containing the first character of the
   /// range.
-  int get startLine => _startLine;
-
-  /// The one-based index of the line containing the first character of the
-  /// range.
-  set startLine(int value) {
-    assert(value != null);
-    _startLine = value;
-  }
+  int startLine;
 
   /// The one-based index of the column containing the first character of the
   /// range.
-  int get startColumn => _startColumn;
+  int startColumn;
 
-  /// The one-based index of the column containing the first character of the
-  /// range.
-  set startColumn(int value) {
-    assert(value != null);
-    _startColumn = value;
-  }
+  /// The one-based index of the line containing the character immediately
+  /// following the range.
+  int endLine;
 
-  Location(
-      String file, int offset, int length, int startLine, int startColumn) {
-    this.file = file;
-    this.offset = offset;
-    this.length = length;
-    this.startLine = startLine;
-    this.startColumn = startColumn;
-  }
+  /// The one-based index of the column containing the character immediately
+  /// following the range.
+  int endColumn;
+
+  Location(this.file, this.offset, this.length, this.startLine,
+      this.startColumn, this.endLine, this.endColumn);
 
   factory Location.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -3603,20 +2948,36 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'startColumn');
       }
-      return Location(file, offset, length, startLine, startColumn);
+      int endLine;
+      if (json.containsKey('endLine')) {
+        endLine = jsonDecoder.decodeInt(jsonPath + '.endLine', json['endLine']);
+      } else {
+        throw jsonDecoder.mismatch(jsonPath, 'endLine');
+      }
+      int endColumn;
+      if (json.containsKey('endColumn')) {
+        endColumn =
+            jsonDecoder.decodeInt(jsonPath + '.endColumn', json['endColumn']);
+      } else {
+        throw jsonDecoder.mismatch(jsonPath, 'endColumn');
+      }
+      return Location(
+          file, offset, length, startLine, startColumn, endLine, endColumn);
     } else {
       throw jsonDecoder.mismatch(jsonPath, 'Location', json);
     }
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     result['offset'] = offset;
     result['length'] = length;
     result['startLine'] = startLine;
     result['startColumn'] = startColumn;
+    result['endLine'] = endLine;
+    result['endColumn'] = endColumn;
     return result;
   }
 
@@ -3630,7 +2991,9 @@
           offset == other.offset &&
           length == other.length &&
           startLine == other.startLine &&
-          startColumn == other.startColumn;
+          startColumn == other.startColumn &&
+          endLine == other.endLine &&
+          endColumn == other.endColumn;
     }
     return false;
   }
@@ -3643,6 +3006,8 @@
     hash = JenkinsSmiHash.combine(hash, length.hashCode);
     hash = JenkinsSmiHash.combine(hash, startLine.hashCode);
     hash = JenkinsSmiHash.combine(hash, startColumn.hashCode);
+    hash = JenkinsSmiHash.combine(hash, endLine.hashCode);
+    hash = JenkinsSmiHash.combine(hash, endColumn.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
 }
@@ -3657,51 +3022,21 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class NavigationRegion implements HasToJson {
-  int _offset;
-
-  int _length;
-
-  List<int> _targets;
-
   /// The offset of the region from which the user can navigate.
-  int get offset => _offset;
-
-  /// The offset of the region from which the user can navigate.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
+  int offset;
 
   /// The length of the region from which the user can navigate.
-  int get length => _length;
-
-  /// The length of the region from which the user can navigate.
-  set length(int value) {
-    assert(value != null);
-    _length = value;
-  }
+  int length;
 
   /// 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;
+  List<int> 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.
-  set targets(List<int> value) {
-    assert(value != null);
-    _targets = value;
-  }
-
-  NavigationRegion(int offset, int length, List<int> targets) {
-    this.offset = offset;
-    this.length = length;
-    this.targets = targets;
-  }
+  NavigationRegion(this.offset, this.length, this.targets);
 
   factory NavigationRegion.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       int offset;
@@ -3730,8 +3065,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['offset'] = offset;
     result['length'] = length;
     result['targets'] = targets;
@@ -3776,113 +3111,39 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class NavigationTarget implements HasToJson {
-  ElementKind _kind;
-
-  int _fileIndex;
-
-  int _offset;
-
-  int _length;
-
-  int _startLine;
-
-  int _startColumn;
-
-  int _codeOffset;
-
-  int _codeLength;
-
   /// The kind of the element.
-  ElementKind get kind => _kind;
-
-  /// The kind of the element.
-  set kind(ElementKind value) {
-    assert(value != null);
-    _kind = value;
-  }
+  ElementKind kind;
 
   /// The index of the file (in the enclosing navigation response) to navigate
   /// to.
-  int get fileIndex => _fileIndex;
-
-  /// The index of the file (in the enclosing navigation response) to navigate
-  /// to.
-  set fileIndex(int value) {
-    assert(value != null);
-    _fileIndex = value;
-  }
+  int fileIndex;
 
   /// The offset of the name of the target to which the user can navigate.
-  int get offset => _offset;
-
-  /// The offset of the name of the target to which the user can navigate.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
+  int offset;
 
   /// The length of the name of the target to which the user can navigate.
-  int get length => _length;
-
-  /// The length of the name of the target to which the user can navigate.
-  set length(int value) {
-    assert(value != null);
-    _length = value;
-  }
+  int length;
 
   /// The one-based index of the line containing the first character of the
   /// name of the target.
-  int get startLine => _startLine;
-
-  /// The one-based index of the line containing the first character of the
-  /// name of the target.
-  set startLine(int value) {
-    assert(value != null);
-    _startLine = value;
-  }
+  int startLine;
 
   /// The one-based index of the column containing the first character of the
   /// name of the target.
-  int get startColumn => _startColumn;
-
-  /// The one-based index of the column containing the first character of the
-  /// name of the target.
-  set startColumn(int value) {
-    assert(value != null);
-    _startColumn = value;
-  }
+  int startColumn;
 
   /// 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;
-  }
+  int? codeOffset;
 
   /// The length of the target code to which the user can navigate.
-  int get codeLength => _codeLength;
+  int? 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 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;
-  }
+  NavigationTarget(this.kind, this.fileIndex, this.offset, this.length,
+      this.startLine, this.startColumn,
+      {this.codeOffset, this.codeLength});
 
   factory NavigationTarget.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       ElementKind kind;
@@ -3925,12 +3186,12 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'startColumn');
       }
-      int codeOffset;
+      int? codeOffset;
       if (json.containsKey('codeOffset')) {
         codeOffset =
             jsonDecoder.decodeInt(jsonPath + '.codeOffset', json['codeOffset']);
       }
-      int codeLength;
+      int? codeLength;
       if (json.containsKey('codeLength')) {
         codeLength =
             jsonDecoder.decodeInt(jsonPath + '.codeLength', json['codeLength']);
@@ -3944,17 +3205,19 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['kind'] = kind.toJson();
     result['fileIndex'] = fileIndex;
     result['offset'] = offset;
     result['length'] = length;
     result['startLine'] = startLine;
     result['startColumn'] = startColumn;
+    var codeOffset = this.codeOffset;
     if (codeOffset != null) {
       result['codeOffset'] = codeOffset;
     }
+    var codeLength = this.codeLength;
     if (codeLength != null) {
       result['codeLength'] = codeLength;
     }
@@ -4004,47 +3267,19 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class Occurrences implements HasToJson {
-  Element _element;
-
-  List<int> _offsets;
-
-  int _length;
-
   /// The element that was referenced.
-  Element get element => _element;
-
-  /// The element that was referenced.
-  set element(Element value) {
-    assert(value != null);
-    _element = value;
-  }
+  Element element;
 
   /// The offsets of the name of the referenced element within the file.
-  List<int> get offsets => _offsets;
-
-  /// The offsets of the name of the referenced element within the file.
-  set offsets(List<int> value) {
-    assert(value != null);
-    _offsets = value;
-  }
+  List<int> offsets;
 
   /// The length of the name of the referenced element.
-  int get length => _length;
+  int length;
 
-  /// The length of the name of the referenced element.
-  set length(int value) {
-    assert(value != null);
-    _length = value;
-  }
-
-  Occurrences(Element element, List<int> offsets, int length) {
-    this.element = element;
-    this.offsets = offsets;
-    this.length = length;
-  }
+  Occurrences(this.element, this.offsets, this.length);
 
   factory Occurrences.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       Element element;
@@ -4074,8 +3309,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['element'] = element.toJson();
     result['offsets'] = offsets;
     result['length'] = length;
@@ -4118,94 +3353,35 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class Outline implements HasToJson {
-  Element _element;
-
-  int _offset;
-
-  int _length;
-
-  int _codeOffset;
-
-  int _codeLength;
-
-  List<Outline> _children;
-
   /// A description of the element represented by this node.
-  Element get element => _element;
-
-  /// A description of the element represented by this node.
-  set element(Element value) {
-    assert(value != null);
-    _element = value;
-  }
+  Element element;
 
   /// 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.
-  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.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
+  int offset;
 
   /// The length of the element.
-  int get length => _length;
-
-  /// The length of the element.
-  set length(int value) {
-    assert(value != null);
-    _length = value;
-  }
+  int length;
 
   /// The offset of the first character of the element code, which is neither
   /// documentation, nor annotation.
-  int get codeOffset => _codeOffset;
-
-  /// The offset of the first character of the element code, which is neither
-  /// documentation, nor annotation.
-  set codeOffset(int value) {
-    assert(value != null);
-    _codeOffset = value;
-  }
+  int codeOffset;
 
   /// The length of the element code.
-  int get codeLength => _codeLength;
-
-  /// The length of the element code.
-  set codeLength(int value) {
-    assert(value != null);
-    _codeLength = value;
-  }
+  int codeLength;
 
   /// The children of the node. The field will be omitted if the node has no
   /// children. Children are sorted by offset.
-  List<Outline> get children => _children;
-
-  /// The children of the node. The field will be omitted if the node has no
-  /// children. Children are sorted by offset.
-  set children(List<Outline> value) {
-    _children = value;
-  }
+  List<Outline>? children;
 
   Outline(
-      Element element, int offset, int length, int codeOffset, int codeLength,
-      {List<Outline> children}) {
-    this.element = element;
-    this.offset = offset;
-    this.length = length;
-    this.codeOffset = codeOffset;
-    this.codeLength = codeLength;
-    this.children = children;
-  }
+      this.element, this.offset, this.length, this.codeOffset, this.codeLength,
+      {this.children});
 
   factory Outline.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       Element element;
@@ -4241,12 +3417,12 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'codeLength');
       }
-      List<Outline> children;
+      List<Outline>? children;
       if (json.containsKey('children')) {
         children = jsonDecoder.decodeList(
             jsonPath + '.children',
             json['children'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 Outline.fromJson(jsonDecoder, jsonPath, json));
       }
       return Outline(element, offset, length, codeOffset, codeLength,
@@ -4257,13 +3433,14 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['element'] = element.toJson();
     result['offset'] = offset;
     result['length'] = length;
     result['codeOffset'] = codeOffset;
     result['codeLength'] = codeLength;
+    var children = this.children;
     if (children != null) {
       result['children'] =
           children.map((Outline value) => value.toJson()).toList();
@@ -4311,61 +3488,23 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class ParameterInfo implements HasToJson {
-  ParameterKind _kind;
-
-  String _name;
-
-  String _type;
-
-  String _defaultValue;
-
   /// The kind of the parameter.
-  ParameterKind get kind => _kind;
-
-  /// The kind of the parameter.
-  set kind(ParameterKind value) {
-    assert(value != null);
-    _kind = value;
-  }
+  ParameterKind kind;
 
   /// The name of the parameter.
-  String get name => _name;
-
-  /// The name of the parameter.
-  set name(String value) {
-    assert(value != null);
-    _name = value;
-  }
+  String name;
 
   /// The type of the parameter.
-  String get type => _type;
-
-  /// The type of the parameter.
-  set type(String value) {
-    assert(value != null);
-    _type = value;
-  }
+  String type;
 
   /// The default value for this parameter. This value will be omitted if the
   /// parameter does not have a default value.
-  String get defaultValue => _defaultValue;
+  String? defaultValue;
 
-  /// The default value for this parameter. This value will be omitted if the
-  /// parameter does not have a default value.
-  set defaultValue(String value) {
-    _defaultValue = value;
-  }
-
-  ParameterInfo(ParameterKind kind, String name, String type,
-      {String defaultValue}) {
-    this.kind = kind;
-    this.name = name;
-    this.type = type;
-    this.defaultValue = defaultValue;
-  }
+  ParameterInfo(this.kind, this.name, this.type, {this.defaultValue});
 
   factory ParameterInfo.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       ParameterKind kind;
@@ -4387,7 +3526,7 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'type');
       }
-      String defaultValue;
+      String? defaultValue;
       if (json.containsKey('defaultValue')) {
         defaultValue = jsonDecoder.decodeString(
             jsonPath + '.defaultValue', json['defaultValue']);
@@ -4399,11 +3538,12 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['kind'] = kind.toJson();
     result['name'] = name;
     result['type'] = type;
+    var defaultValue = this.defaultValue;
     if (defaultValue != null) {
       result['defaultValue'] = defaultValue;
     }
@@ -4488,7 +3628,7 @@
   }
 
   factory ParameterKind.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     if (json is String) {
       try {
         return ParameterKind(json);
@@ -4514,35 +3654,16 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class Position implements HasToJson {
-  String _file;
-
-  int _offset;
-
   /// The file containing the position.
-  String get file => _file;
-
-  /// The file containing the position.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// The offset of the position.
-  int get offset => _offset;
+  int offset;
 
-  /// The offset of the position.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
-
-  Position(String file, int offset) {
-    this.file = file;
-    this.offset = offset;
-  }
+  Position(this.file, this.offset);
 
   factory Position.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -4564,8 +3685,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     result['offset'] = offset;
     return result;
@@ -4675,7 +3796,7 @@
   }
 
   factory RefactoringKind.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     if (json is String) {
       try {
         return RefactoringKind(json);
@@ -4704,82 +3825,33 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class RefactoringMethodParameter implements HasToJson {
-  String _id;
-
-  RefactoringMethodParameterKind _kind;
-
-  String _type;
-
-  String _name;
-
-  String _parameters;
-
   /// The unique identifier of the parameter. Clients may omit this field for
   /// the parameters they want to add.
-  String get id => _id;
-
-  /// The unique identifier of the parameter. Clients may omit this field for
-  /// the parameters they want to add.
-  set id(String value) {
-    _id = value;
-  }
+  String? id;
 
   /// The kind of the parameter.
-  RefactoringMethodParameterKind get kind => _kind;
-
-  /// The kind of the parameter.
-  set kind(RefactoringMethodParameterKind value) {
-    assert(value != null);
-    _kind = value;
-  }
+  RefactoringMethodParameterKind kind;
 
   /// The type that should be given to the parameter, or the return type of the
   /// parameter's function type.
-  String get type => _type;
-
-  /// The type that should be given to the parameter, or the return type of the
-  /// parameter's function type.
-  set type(String value) {
-    assert(value != null);
-    _type = value;
-  }
+  String type;
 
   /// The name that should be given to the parameter.
-  String get name => _name;
-
-  /// The name that should be given to the parameter.
-  set name(String value) {
-    assert(value != null);
-    _name = value;
-  }
+  String name;
 
   /// The parameter list of the parameter's function type. If the parameter is
   /// not of a function type, this field will not be defined. If the function
   /// type has zero parameters, this field will have a value of '()'.
-  String get parameters => _parameters;
+  String? parameters;
 
-  /// The parameter list of the parameter's function type. If the parameter is
-  /// not of a function type, this field will not be defined. If the function
-  /// type has zero parameters, this field will have a value of '()'.
-  set parameters(String value) {
-    _parameters = value;
-  }
-
-  RefactoringMethodParameter(
-      RefactoringMethodParameterKind kind, String type, String name,
-      {String id, String parameters}) {
-    this.id = id;
-    this.kind = kind;
-    this.type = type;
-    this.name = name;
-    this.parameters = parameters;
-  }
+  RefactoringMethodParameter(this.kind, this.type, this.name,
+      {this.id, this.parameters});
 
   factory RefactoringMethodParameter.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
-      String id;
+      String? id;
       if (json.containsKey('id')) {
         id = jsonDecoder.decodeString(jsonPath + '.id', json['id']);
       }
@@ -4802,7 +3874,7 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'name');
       }
-      String parameters;
+      String? parameters;
       if (json.containsKey('parameters')) {
         parameters = jsonDecoder.decodeString(
             jsonPath + '.parameters', json['parameters']);
@@ -4815,14 +3887,16 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
+    var id = this.id;
     if (id != null) {
       result['id'] = id;
     }
     result['kind'] = kind.toJson();
     result['type'] = type;
     result['name'] = name;
+    var parameters = this.parameters;
     if (parameters != null) {
       result['parameters'] = parameters;
     }
@@ -4897,7 +3971,7 @@
   }
 
   factory RefactoringMethodParameterKind.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     if (json is String) {
       try {
         return RefactoringMethodParameterKind(json);
@@ -4925,51 +3999,21 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class RefactoringProblem implements HasToJson {
-  RefactoringProblemSeverity _severity;
-
-  String _message;
-
-  Location _location;
-
   /// The severity of the problem being represented.
-  RefactoringProblemSeverity get severity => _severity;
-
-  /// The severity of the problem being represented.
-  set severity(RefactoringProblemSeverity value) {
-    assert(value != null);
-    _severity = value;
-  }
+  RefactoringProblemSeverity severity;
 
   /// A human-readable description of the problem being represented.
-  String get message => _message;
-
-  /// A human-readable description of the problem being represented.
-  set message(String value) {
-    assert(value != null);
-    _message = value;
-  }
+  String message;
 
   /// 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).
-  Location get location => _location;
+  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).
-  set location(Location value) {
-    _location = value;
-  }
-
-  RefactoringProblem(RefactoringProblemSeverity severity, String message,
-      {Location location}) {
-    this.severity = severity;
-    this.message = message;
-    this.location = location;
-  }
+  RefactoringProblem(this.severity, this.message, {this.location});
 
   factory RefactoringProblem.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       RefactoringProblemSeverity severity;
@@ -4986,7 +4030,7 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'message');
       }
-      Location location;
+      Location? location;
       if (json.containsKey('location')) {
         location = Location.fromJson(
             jsonDecoder, jsonPath + '.location', json['location']);
@@ -4998,10 +4042,11 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['severity'] = severity.toJson();
     result['message'] = message;
+    var location = this.location;
     if (location != null) {
       result['location'] = location.toJson();
     }
@@ -5095,7 +4140,7 @@
   }
 
   factory RefactoringProblemSeverity.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     if (json is String) {
       try {
         return RefactoringProblemSeverity(json);
@@ -5107,8 +4152,8 @@
   }
 
   /// Returns the [RefactoringProblemSeverity] with the maximal severity.
-  static RefactoringProblemSeverity max(
-          RefactoringProblemSeverity a, RefactoringProblemSeverity b) =>
+  static RefactoringProblemSeverity? max(
+          RefactoringProblemSeverity? a, RefactoringProblemSeverity? b) =>
       maxRefactoringProblemSeverity(a, b);
 
   @override
@@ -5128,7 +4173,7 @@
   RemoveContentOverlay();
 
   factory RemoveContentOverlay.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       if (json['type'] != 'remove') {
@@ -5141,8 +4186,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['type'] = 'remove';
     return result;
   }
@@ -5178,85 +4223,33 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class SourceChange implements HasToJson {
-  String _message;
-
-  List<SourceFileEdit> _edits;
-
-  List<LinkedEditGroup> _linkedEditGroups;
-
-  Position _selection;
-
-  String _id;
-
   /// A human-readable description of the change to be applied.
-  String get message => _message;
-
-  /// A human-readable description of the change to be applied.
-  set message(String value) {
-    assert(value != null);
-    _message = value;
-  }
+  String message;
 
   /// A list of the edits used to effect the change, grouped by file.
-  List<SourceFileEdit> get edits => _edits;
-
-  /// A list of the edits used to effect the change, grouped by file.
-  set edits(List<SourceFileEdit> value) {
-    assert(value != null);
-    _edits = value;
-  }
+  List<SourceFileEdit> edits;
 
   /// A list of the linked editing groups used to customize the changes that
   /// were made.
-  List<LinkedEditGroup> get linkedEditGroups => _linkedEditGroups;
-
-  /// A list of the linked editing groups used to customize the changes that
-  /// were made.
-  set linkedEditGroups(List<LinkedEditGroup> value) {
-    assert(value != null);
-    _linkedEditGroups = value;
-  }
+  List<LinkedEditGroup> linkedEditGroups;
 
   /// The position that should be selected after the edits have been applied.
-  Position get selection => _selection;
-
-  /// The position that should be selected after the edits have been applied.
-  set selection(Position value) {
-    _selection = value;
-  }
+  Position? selection;
 
   /// The optional identifier of the change kind. The identifier remains stable
   /// even if the message changes, or is parameterized.
-  String get id => _id;
+  String? id;
 
-  /// The optional identifier of the change kind. The identifier remains stable
-  /// even if the message changes, or is parameterized.
-  set id(String value) {
-    _id = value;
-  }
-
-  SourceChange(String message,
-      {List<SourceFileEdit> edits,
-      List<LinkedEditGroup> linkedEditGroups,
-      Position selection,
-      String id}) {
-    this.message = message;
-    if (edits == null) {
-      this.edits = <SourceFileEdit>[];
-    } else {
-      this.edits = edits;
-    }
-    if (linkedEditGroups == null) {
-      this.linkedEditGroups = <LinkedEditGroup>[];
-    } else {
-      this.linkedEditGroups = linkedEditGroups;
-    }
-    this.selection = selection;
-    this.id = id;
-  }
+  SourceChange(this.message,
+      {List<SourceFileEdit>? edits,
+      List<LinkedEditGroup>? linkedEditGroups,
+      this.selection,
+      this.id})
+      : edits = edits ?? <SourceFileEdit>[],
+        linkedEditGroups = linkedEditGroups ?? <LinkedEditGroup>[];
 
   factory SourceChange.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String message;
@@ -5271,7 +4264,7 @@
         edits = jsonDecoder.decodeList(
             jsonPath + '.edits',
             json['edits'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 SourceFileEdit.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'edits');
@@ -5281,17 +4274,17 @@
         linkedEditGroups = jsonDecoder.decodeList(
             jsonPath + '.linkedEditGroups',
             json['linkedEditGroups'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 LinkedEditGroup.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'linkedEditGroups');
       }
-      Position selection;
+      Position? selection;
       if (json.containsKey('selection')) {
         selection = Position.fromJson(
             jsonDecoder, jsonPath + '.selection', json['selection']);
       }
-      String id;
+      String? id;
       if (json.containsKey('id')) {
         id = jsonDecoder.decodeString(jsonPath + '.id', json['id']);
       }
@@ -5306,17 +4299,19 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['message'] = message;
     result['edits'] =
         edits.map((SourceFileEdit value) => value.toJson()).toList();
     result['linkedEditGroups'] = linkedEditGroups
         .map((LinkedEditGroup value) => value.toJson())
         .toList();
+    var selection = this.selection;
     if (selection != null) {
       result['selection'] = selection.toJson();
     }
+    var id = this.id;
     if (id != null) {
       result['id'] = id;
     }
@@ -5338,7 +4333,7 @@
   }
 
   /// Returns the [FileEdit] for the given [file], maybe `null`.
-  SourceFileEdit getFileEdit(String file) => getChangeFileEdit(this, file);
+  SourceFileEdit? getFileEdit(String file) => getChangeFileEdit(this, file);
 
   @override
   String toString() => json.encode(toJson());
@@ -5385,40 +4380,14 @@
   static String applySequence(String code, Iterable<SourceEdit> edits) =>
       applySequenceOfEdits(code, edits);
 
-  int _offset;
-
-  int _length;
-
-  String _replacement;
-
-  String _id;
-
   /// The offset of the region to be modified.
-  int get offset => _offset;
-
-  /// The offset of the region to be modified.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
+  int offset;
 
   /// The length of the region to be modified.
-  int get length => _length;
-
-  /// The length of the region to be modified.
-  set length(int value) {
-    assert(value != null);
-    _length = value;
-  }
+  int length;
 
   /// The code that is to replace the specified region in the original code.
-  String get replacement => _replacement;
-
-  /// The code that is to replace the specified region in the original code.
-  set replacement(String value) {
-    assert(value != null);
-    _replacement = value;
-  }
+  String replacement;
 
   /// An identifier that uniquely identifies this source edit from other edits
   /// in the same response. This field is omitted unless a containing structure
@@ -5428,29 +4397,12 @@
   /// be appropriate (referred to as potential edits). Such edits will have an
   /// id so that they can be referenced. Edits in the same response that do not
   /// need to be referenced will not have an id.
-  String get id => _id;
+  String? id;
 
-  /// An identifier that uniquely identifies this source edit from other edits
-  /// in the same response. This field is omitted unless a containing structure
-  /// needs to be able to identify the edit for some reason.
-  ///
-  /// For example, some refactoring operations can produce edits that might not
-  /// be appropriate (referred to as potential edits). Such edits will have an
-  /// id so that they can be referenced. Edits in the same response that do not
-  /// need to be referenced will not have an id.
-  set id(String value) {
-    _id = value;
-  }
-
-  SourceEdit(int offset, int length, String replacement, {String id}) {
-    this.offset = offset;
-    this.length = length;
-    this.replacement = replacement;
-    this.id = id;
-  }
+  SourceEdit(this.offset, this.length, this.replacement, {this.id});
 
   factory SourceEdit.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       int offset;
@@ -5472,7 +4424,7 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'replacement');
       }
-      String id;
+      String? id;
       if (json.containsKey('id')) {
         id = jsonDecoder.decodeString(jsonPath + '.id', json['id']);
       }
@@ -5486,11 +4438,12 @@
   int get end => offset + length;
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['offset'] = offset;
     result['length'] = length;
     result['replacement'] = replacement;
+    var id = this.id;
     if (id != null) {
       result['id'] = id;
     }
@@ -5535,59 +4488,24 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class SourceFileEdit implements HasToJson {
-  String _file;
-
-  int _fileStamp;
-
-  List<SourceEdit> _edits;
-
   /// The file containing the code to be modified.
-  String get file => _file;
-
-  /// The file containing the code to be modified.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// 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.
-  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.
-  set fileStamp(int value) {
-    assert(value != null);
-    _fileStamp = value;
-  }
+  int fileStamp;
 
   /// A list of the edits used to effect the change.
-  List<SourceEdit> get edits => _edits;
+  List<SourceEdit> edits;
 
-  /// A list of the edits used to effect the change.
-  set edits(List<SourceEdit> value) {
-    assert(value != null);
-    _edits = value;
-  }
-
-  SourceFileEdit(String file, int fileStamp, {List<SourceEdit> edits}) {
-    this.file = file;
-    this.fileStamp = fileStamp;
-    if (edits == null) {
-      this.edits = <SourceEdit>[];
-    } else {
-      this.edits = edits;
-    }
-  }
+  SourceFileEdit(this.file, this.fileStamp, {List<SourceEdit>? edits})
+      : edits = edits ?? <SourceEdit>[];
 
   factory SourceFileEdit.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -5608,7 +4526,7 @@
         edits = jsonDecoder.decodeList(
             jsonPath + '.edits',
             json['edits'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 SourceEdit.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'edits');
@@ -5620,8 +4538,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     result['fileStamp'] = fileStamp;
     result['edits'] = edits.map((SourceEdit value) => value.toJson()).toList();
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 e5dd041..5a777f6 100644
--- a/pkg/analysis_server_client/lib/src/protocol/protocol_generated.dart
+++ b/pkg/analysis_server_client/lib/src/protocol/protocol_generated.dart
@@ -21,23 +21,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisAnalyzedFilesParams implements HasToJson {
-  List<String> _directories;
-
   /// A list of the paths of the files that are being analyzed.
-  List<String> get directories => _directories;
+  List<String> directories;
 
-  /// A list of the paths of the files that are being analyzed.
-  set directories(List<String> value) {
-    assert(value != null);
-    _directories = value;
-  }
-
-  AnalysisAnalyzedFilesParams(List<String> directories) {
-    this.directories = directories;
-  }
+  AnalysisAnalyzedFilesParams(this.directories);
 
   factory AnalysisAnalyzedFilesParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       List<String> directories;
@@ -61,8 +51,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['directories'] = directories;
     return result;
   }
@@ -100,18 +90,8 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisClosingLabelsParams implements HasToJson {
-  String _file;
-
-  List<ClosingLabel> _labels;
-
   /// The file the closing labels relate to.
-  String get file => _file;
-
-  /// The file the closing labels relate to.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// Closing labels relevant to the file. Each item represents a useful label
   /// associated with some range with may be useful to display to the user
@@ -120,27 +100,12 @@
   /// and List arguments that span multiple lines. Note that the ranges that
   /// are returned can overlap each other because they may be associated with
   /// constructs that can be nested.
-  List<ClosingLabel> get labels => _labels;
+  List<ClosingLabel> labels;
 
-  /// Closing labels relevant to the file. Each item represents a useful label
-  /// associated with some range with may be useful to display to the user
-  /// within the editor at the end of the range to indicate what construct is
-  /// closed at that location. Closing labels include constructor/method calls
-  /// and List arguments that span multiple lines. Note that the ranges that
-  /// are returned can overlap each other because they may be associated with
-  /// constructs that can be nested.
-  set labels(List<ClosingLabel> value) {
-    assert(value != null);
-    _labels = value;
-  }
-
-  AnalysisClosingLabelsParams(String file, List<ClosingLabel> labels) {
-    this.file = file;
-    this.labels = labels;
-  }
+  AnalysisClosingLabelsParams(this.file, this.labels);
 
   factory AnalysisClosingLabelsParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -154,7 +119,7 @@
         labels = jsonDecoder.decodeList(
             jsonPath + '.labels',
             json['labels'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 ClosingLabel.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'labels');
@@ -173,8 +138,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     result['labels'] =
         labels.map((ClosingLabel value) => value.toJson()).toList();
@@ -216,39 +181,17 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisErrorFixes implements HasToJson {
-  AnalysisError _error;
-
-  List<SourceChange> _fixes;
-
   /// The error with which the fixes are associated.
-  AnalysisError get error => _error;
-
-  /// The error with which the fixes are associated.
-  set error(AnalysisError value) {
-    assert(value != null);
-    _error = value;
-  }
+  AnalysisError error;
 
   /// The fixes associated with the error.
-  List<SourceChange> get fixes => _fixes;
+  List<SourceChange> fixes;
 
-  /// The fixes associated with the error.
-  set fixes(List<SourceChange> value) {
-    assert(value != null);
-    _fixes = value;
-  }
-
-  AnalysisErrorFixes(AnalysisError error, {List<SourceChange> fixes}) {
-    this.error = error;
-    if (fixes == null) {
-      this.fixes = <SourceChange>[];
-    } else {
-      this.fixes = fixes;
-    }
-  }
+  AnalysisErrorFixes(this.error, {List<SourceChange>? fixes})
+      : fixes = fixes ?? <SourceChange>[];
 
   factory AnalysisErrorFixes.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       AnalysisError error;
@@ -263,7 +206,7 @@
         fixes = jsonDecoder.decodeList(
             jsonPath + '.fixes',
             json['fixes'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 SourceChange.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'fixes');
@@ -275,8 +218,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['error'] = error.toJson();
     result['fixes'] =
         fixes.map((SourceChange value) => value.toJson()).toList();
@@ -314,35 +257,16 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisErrorsParams implements HasToJson {
-  String _file;
-
-  List<AnalysisError> _errors;
-
   /// The file containing the errors.
-  String get file => _file;
-
-  /// The file containing the errors.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// The errors contained in the file.
-  List<AnalysisError> get errors => _errors;
+  List<AnalysisError> errors;
 
-  /// The errors contained in the file.
-  set errors(List<AnalysisError> value) {
-    assert(value != null);
-    _errors = value;
-  }
-
-  AnalysisErrorsParams(String file, List<AnalysisError> errors) {
-    this.file = file;
-    this.errors = errors;
-  }
+  AnalysisErrorsParams(this.file, this.errors);
 
   factory AnalysisErrorsParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -356,7 +280,7 @@
         errors = jsonDecoder.decodeList(
             jsonPath + '.errors',
             json['errors'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 AnalysisError.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'errors');
@@ -373,8 +297,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     result['errors'] =
         errors.map((AnalysisError value) => value.toJson()).toList();
@@ -415,23 +339,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisFlushResultsParams implements HasToJson {
-  List<String> _files;
-
   /// The files that are no longer being analyzed.
-  List<String> get files => _files;
+  List<String> files;
 
-  /// The files that are no longer being analyzed.
-  set files(List<String> value) {
-    assert(value != null);
-    _files = value;
-  }
-
-  AnalysisFlushResultsParams(List<String> files) {
-    this.files = files;
-  }
+  AnalysisFlushResultsParams(this.files);
 
   factory AnalysisFlushResultsParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       List<String> files;
@@ -455,8 +369,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['files'] = files;
     return result;
   }
@@ -493,35 +407,16 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisFoldingParams implements HasToJson {
-  String _file;
-
-  List<FoldingRegion> _regions;
-
   /// The file containing the folding regions.
-  String get file => _file;
-
-  /// The file containing the folding regions.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// The folding regions contained in the file.
-  List<FoldingRegion> get regions => _regions;
+  List<FoldingRegion> regions;
 
-  /// The folding regions contained in the file.
-  set regions(List<FoldingRegion> value) {
-    assert(value != null);
-    _regions = value;
-  }
-
-  AnalysisFoldingParams(String file, List<FoldingRegion> regions) {
-    this.file = file;
-    this.regions = regions;
-  }
+  AnalysisFoldingParams(this.file, this.regions);
 
   factory AnalysisFoldingParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -535,7 +430,7 @@
         regions = jsonDecoder.decodeList(
             jsonPath + '.regions',
             json['regions'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 FoldingRegion.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'regions');
@@ -552,8 +447,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     result['regions'] =
         regions.map((FoldingRegion value) => value.toJson()).toList();
@@ -594,23 +489,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisGetErrorsParams implements RequestParams {
-  String _file;
-
   /// The file for which errors are being requested.
-  String get file => _file;
+  String file;
 
-  /// The file for which errors are being requested.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
-
-  AnalysisGetErrorsParams(String file) {
-    this.file = file;
-  }
+  AnalysisGetErrorsParams(this.file);
 
   factory AnalysisGetErrorsParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -631,8 +516,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     return result;
   }
@@ -669,23 +554,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisGetErrorsResult implements ResponseResult {
-  List<AnalysisError> _errors;
-
   /// The errors associated with the file.
-  List<AnalysisError> get errors => _errors;
+  List<AnalysisError> errors;
 
-  /// The errors associated with the file.
-  set errors(List<AnalysisError> value) {
-    assert(value != null);
-    _errors = value;
-  }
-
-  AnalysisGetErrorsResult(List<AnalysisError> errors) {
-    this.errors = errors;
-  }
+  AnalysisGetErrorsResult(this.errors);
 
   factory AnalysisGetErrorsResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       List<AnalysisError> errors;
@@ -693,7 +568,7 @@
         errors = jsonDecoder.decodeList(
             jsonPath + '.errors',
             json['errors'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 AnalysisError.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'errors');
@@ -712,8 +587,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['errors'] =
         errors.map((AnalysisError value) => value.toJson()).toList();
     return result;
@@ -753,35 +628,16 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisGetHoverParams implements RequestParams {
-  String _file;
-
-  int _offset;
-
   /// The file in which hover information is being requested.
-  String get file => _file;
-
-  /// The file in which hover information is being requested.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// The offset for which hover information is being requested.
-  int get offset => _offset;
+  int offset;
 
-  /// The offset for which hover information is being requested.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
-
-  AnalysisGetHoverParams(String file, int offset) {
-    this.file = file;
-    this.offset = offset;
-  }
+  AnalysisGetHoverParams(this.file, this.offset);
 
   factory AnalysisGetHoverParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -808,8 +664,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     result['offset'] = offset;
     return result;
@@ -848,31 +704,17 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisGetHoverResult implements ResponseResult {
-  List<HoverInformation> _hovers;
-
   /// The hover information associated with the location. The list will be
   /// empty if no information could be determined for the location. The list
   /// can contain multiple items if the file is being analyzed in multiple
   /// contexts in conflicting ways (such as a part that is included in multiple
   /// libraries).
-  List<HoverInformation> get hovers => _hovers;
+  List<HoverInformation> hovers;
 
-  /// The hover information associated with the location. The list will be
-  /// empty if no information could be determined for the location. The list
-  /// can contain multiple items if the file is being analyzed in multiple
-  /// contexts in conflicting ways (such as a part that is included in multiple
-  /// libraries).
-  set hovers(List<HoverInformation> value) {
-    assert(value != null);
-    _hovers = value;
-  }
-
-  AnalysisGetHoverResult(List<HoverInformation> hovers) {
-    this.hovers = hovers;
-  }
+  AnalysisGetHoverResult(this.hovers);
 
   factory AnalysisGetHoverResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       List<HoverInformation> hovers;
@@ -880,7 +722,7 @@
         hovers = jsonDecoder.decodeList(
             jsonPath + '.hovers',
             json['hovers'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 HoverInformation.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'hovers');
@@ -899,8 +741,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['hovers'] =
         hovers.map((HoverInformation value) => value.toJson()).toList();
     return result;
@@ -941,47 +783,19 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisGetImportedElementsParams implements RequestParams {
-  String _file;
-
-  int _offset;
-
-  int _length;
-
   /// The file in which import information is being requested.
-  String get file => _file;
-
-  /// The file in which import information is being requested.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// The offset of the region for which import information is being requested.
-  int get offset => _offset;
-
-  /// The offset of the region for which import information is being requested.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
+  int offset;
 
   /// The length of the region for which import information is being requested.
-  int get length => _length;
+  int length;
 
-  /// The length of the region for which import information is being requested.
-  set length(int value) {
-    assert(value != null);
-    _length = value;
-  }
-
-  AnalysisGetImportedElementsParams(String file, int offset, int length) {
-    this.file = file;
-    this.offset = offset;
-    this.length = length;
-  }
+  AnalysisGetImportedElementsParams(this.file, this.offset, this.length);
 
   factory AnalysisGetImportedElementsParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -1015,8 +829,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     result['offset'] = offset;
     result['length'] = length;
@@ -1059,25 +873,14 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisGetImportedElementsResult implements ResponseResult {
-  List<ImportedElements> _elements;
-
   /// The information about the elements that are referenced in the specified
   /// region of the specified file that come from imported libraries.
-  List<ImportedElements> get elements => _elements;
+  List<ImportedElements> elements;
 
-  /// The information about the elements that are referenced in the specified
-  /// region of the specified file that come from imported libraries.
-  set elements(List<ImportedElements> value) {
-    assert(value != null);
-    _elements = value;
-  }
-
-  AnalysisGetImportedElementsResult(List<ImportedElements> elements) {
-    this.elements = elements;
-  }
+  AnalysisGetImportedElementsResult(this.elements);
 
   factory AnalysisGetImportedElementsResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       List<ImportedElements> elements;
@@ -1085,7 +888,7 @@
         elements = jsonDecoder.decodeList(
             jsonPath + '.elements',
             json['elements'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 ImportedElements.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'elements');
@@ -1105,8 +908,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['elements'] =
         elements.map((ImportedElements value) => value.toJson()).toList();
     return result;
@@ -1142,7 +945,7 @@
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisGetLibraryDependenciesParams implements RequestParams {
   @override
-  Map<String, dynamic> toJson() => <String, dynamic>{};
+  Map<String, Object> toJson() => <String, Object>{};
 
   @override
   Request toRequest(String id) {
@@ -1172,42 +975,19 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisGetLibraryDependenciesResult implements ResponseResult {
-  List<String> _libraries;
-
-  Map<String, Map<String, List<String>>> _packageMap;
-
   /// A list of the paths of library elements referenced by files in existing
   /// analysis roots.
-  List<String> get libraries => _libraries;
-
-  /// A list of the paths of library elements referenced by files in existing
-  /// analysis roots.
-  set libraries(List<String> value) {
-    assert(value != null);
-    _libraries = value;
-  }
+  List<String> libraries;
 
   /// A mapping from context source roots to package maps which map package
   /// names to source directories for use in client-side package URI
   /// resolution.
-  Map<String, Map<String, List<String>>> get packageMap => _packageMap;
+  Map<String, Map<String, List<String>>> packageMap;
 
-  /// A mapping from context source roots to package maps which map package
-  /// names to source directories for use in client-side package URI
-  /// resolution.
-  set packageMap(Map<String, Map<String, List<String>>> value) {
-    assert(value != null);
-    _packageMap = value;
-  }
-
-  AnalysisGetLibraryDependenciesResult(List<String> libraries,
-      Map<String, Map<String, List<String>>> packageMap) {
-    this.libraries = libraries;
-    this.packageMap = packageMap;
-  }
+  AnalysisGetLibraryDependenciesResult(this.libraries, this.packageMap);
 
   factory AnalysisGetLibraryDependenciesResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       List<String> libraries;
@@ -1221,9 +1001,9 @@
       if (json.containsKey('packageMap')) {
         packageMap = jsonDecoder.decodeMap(
             jsonPath + '.packageMap', json['packageMap'],
-            valueDecoder: (String jsonPath, Object json) =>
+            valueDecoder: (String jsonPath, Object? json) =>
                 jsonDecoder.decodeMap(jsonPath, json,
-                    valueDecoder: (String jsonPath, Object json) => jsonDecoder
+                    valueDecoder: (String jsonPath, Object? json) => jsonDecoder
                         .decodeList(jsonPath, json, jsonDecoder.decodeString)));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'packageMap');
@@ -1243,8 +1023,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['libraries'] = libraries;
     result['packageMap'] = packageMap;
     return result;
@@ -1295,51 +1075,21 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisGetNavigationParams implements RequestParams {
-  String _file;
-
-  int _offset;
-
-  int _length;
-
   /// The file in which navigation information is being requested.
-  String get file => _file;
-
-  /// The file in which navigation information is being requested.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// The offset of the region for which navigation information is being
   /// requested.
-  int get offset => _offset;
-
-  /// The offset of the region for which navigation information is being
-  /// requested.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
+  int offset;
 
   /// The length of the region for which navigation information is being
   /// requested.
-  int get length => _length;
+  int length;
 
-  /// The length of the region for which navigation information is being
-  /// requested.
-  set length(int value) {
-    assert(value != null);
-    _length = value;
-  }
-
-  AnalysisGetNavigationParams(String file, int offset, int length) {
-    this.file = file;
-    this.offset = offset;
-    this.length = length;
-  }
+  AnalysisGetNavigationParams(this.file, this.offset, this.length);
 
   factory AnalysisGetNavigationParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -1373,8 +1123,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     result['offset'] = offset;
     result['length'] = length;
@@ -1419,52 +1169,21 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisGetNavigationResult implements ResponseResult {
-  List<String> _files;
-
-  List<NavigationTarget> _targets;
-
-  List<NavigationRegion> _regions;
-
   /// A list of the paths of files that are referenced by the navigation
   /// targets.
-  List<String> get files => _files;
-
-  /// A list of the paths of files that are referenced by the navigation
-  /// targets.
-  set files(List<String> value) {
-    assert(value != null);
-    _files = value;
-  }
+  List<String> files;
 
   /// A list of the navigation targets that are referenced by the navigation
   /// regions.
-  List<NavigationTarget> get targets => _targets;
-
-  /// A list of the navigation targets that are referenced by the navigation
-  /// regions.
-  set targets(List<NavigationTarget> value) {
-    assert(value != null);
-    _targets = value;
-  }
+  List<NavigationTarget> targets;
 
   /// A list of the navigation regions within the requested region of the file.
-  List<NavigationRegion> get regions => _regions;
+  List<NavigationRegion> regions;
 
-  /// A list of the navigation regions within the requested region of the file.
-  set regions(List<NavigationRegion> value) {
-    assert(value != null);
-    _regions = value;
-  }
-
-  AnalysisGetNavigationResult(List<String> files,
-      List<NavigationTarget> targets, List<NavigationRegion> regions) {
-    this.files = files;
-    this.targets = targets;
-    this.regions = regions;
-  }
+  AnalysisGetNavigationResult(this.files, this.targets, this.regions);
 
   factory AnalysisGetNavigationResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       List<String> files;
@@ -1479,7 +1198,7 @@
         targets = jsonDecoder.decodeList(
             jsonPath + '.targets',
             json['targets'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 NavigationTarget.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'targets');
@@ -1489,7 +1208,7 @@
         regions = jsonDecoder.decodeList(
             jsonPath + '.regions',
             json['regions'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 NavigationRegion.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'regions');
@@ -1509,8 +1228,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['files'] = files;
     result['targets'] =
         targets.map((NavigationTarget value) => value.toJson()).toList();
@@ -1557,23 +1276,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisGetReachableSourcesParams implements RequestParams {
-  String _file;
-
   /// The file for which reachable source information is being requested.
-  String get file => _file;
+  String file;
 
-  /// The file for which reachable source information is being requested.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
-
-  AnalysisGetReachableSourcesParams(String file) {
-    this.file = file;
-  }
+  AnalysisGetReachableSourcesParams(this.file);
 
   factory AnalysisGetReachableSourcesParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -1595,8 +1304,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     return result;
   }
@@ -1633,8 +1342,6 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisGetReachableSourcesResult implements ResponseResult {
-  Map<String, List<String>> _sources;
-
   /// A mapping from source URIs to directly reachable source URIs. For
   /// example, a file "foo.dart" that imports "bar.dart" would have the
   /// corresponding mapping { "file:///foo.dart" : ["file:///bar.dart"] }. If
@@ -1642,32 +1349,18 @@
   /// the URI "file:///bar.dart" to them. To check if a specific URI is
   /// reachable from a given file, clients can check for its presence in the
   /// resulting key set.
-  Map<String, List<String>> get sources => _sources;
+  Map<String, List<String>> sources;
 
-  /// A mapping from source URIs to directly reachable source URIs. For
-  /// example, a file "foo.dart" that imports "bar.dart" would have the
-  /// corresponding mapping { "file:///foo.dart" : ["file:///bar.dart"] }. If
-  /// "bar.dart" has further imports (or exports) there will be a mapping from
-  /// the URI "file:///bar.dart" to them. To check if a specific URI is
-  /// reachable from a given file, clients can check for its presence in the
-  /// resulting key set.
-  set sources(Map<String, List<String>> value) {
-    assert(value != null);
-    _sources = value;
-  }
-
-  AnalysisGetReachableSourcesResult(Map<String, List<String>> sources) {
-    this.sources = sources;
-  }
+  AnalysisGetReachableSourcesResult(this.sources);
 
   factory AnalysisGetReachableSourcesResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       Map<String, List<String>> sources;
       if (json.containsKey('sources')) {
         sources = jsonDecoder.decodeMap(jsonPath + '.sources', json['sources'],
-            valueDecoder: (String jsonPath, Object json) => jsonDecoder
+            valueDecoder: (String jsonPath, Object? json) => jsonDecoder
                 .decodeList(jsonPath, json, jsonDecoder.decodeString));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'sources');
@@ -1687,8 +1380,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['sources'] = sources;
     return result;
   }
@@ -1730,35 +1423,16 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisGetSignatureParams implements RequestParams {
-  String _file;
-
-  int _offset;
-
   /// The file in which signature information is being requested.
-  String get file => _file;
-
-  /// The file in which signature information is being requested.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// The location for which signature information is being requested.
-  int get offset => _offset;
+  int offset;
 
-  /// The location for which signature information is being requested.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
-
-  AnalysisGetSignatureParams(String file, int offset) {
-    this.file = file;
-    this.offset = offset;
-  }
+  AnalysisGetSignatureParams(this.file, this.offset);
 
   factory AnalysisGetSignatureParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -1786,8 +1460,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     result['offset'] = offset;
     return result;
@@ -1828,57 +1502,24 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisGetSignatureResult implements ResponseResult {
-  String _name;
-
-  List<ParameterInfo> _parameters;
-
-  String _dartdoc;
-
   /// The name of the function being invoked at the given offset.
-  String get name => _name;
-
-  /// The name of the function being invoked at the given offset.
-  set name(String value) {
-    assert(value != null);
-    _name = value;
-  }
+  String name;
 
   /// A list of information about each of the parameters of the function being
   /// invoked.
-  List<ParameterInfo> get parameters => _parameters;
-
-  /// A list of information about each of the parameters of the function being
-  /// invoked.
-  set parameters(List<ParameterInfo> value) {
-    assert(value != null);
-    _parameters = value;
-  }
+  List<ParameterInfo> parameters;
 
   /// The dartdoc associated with the function being invoked. Other than the
   /// removal of the comment delimiters, including leading asterisks in the
   /// case of a block comment, the dartdoc is unprocessed markdown. This data
   /// is omitted if there is no referenced element, or if the element has no
   /// dartdoc.
-  String get dartdoc => _dartdoc;
+  String? dartdoc;
 
-  /// The dartdoc associated with the function being invoked. Other than the
-  /// removal of the comment delimiters, including leading asterisks in the
-  /// case of a block comment, the dartdoc is unprocessed markdown. This data
-  /// is omitted if there is no referenced element, or if the element has no
-  /// dartdoc.
-  set dartdoc(String value) {
-    _dartdoc = value;
-  }
-
-  AnalysisGetSignatureResult(String name, List<ParameterInfo> parameters,
-      {String dartdoc}) {
-    this.name = name;
-    this.parameters = parameters;
-    this.dartdoc = dartdoc;
-  }
+  AnalysisGetSignatureResult(this.name, this.parameters, {this.dartdoc});
 
   factory AnalysisGetSignatureResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String name;
@@ -1892,12 +1533,12 @@
         parameters = jsonDecoder.decodeList(
             jsonPath + '.parameters',
             json['parameters'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 ParameterInfo.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'parameters');
       }
-      String dartdoc;
+      String? dartdoc;
       if (json.containsKey('dartdoc')) {
         dartdoc =
             jsonDecoder.decodeString(jsonPath + '.dartdoc', json['dartdoc']);
@@ -1917,11 +1558,12 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['name'] = name;
     result['parameters'] =
         parameters.map((ParameterInfo value) => value.toJson()).toList();
+    var dartdoc = this.dartdoc;
     if (dartdoc != null) {
       result['dartdoc'] = dartdoc;
     }
@@ -1966,43 +1608,20 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisHighlightsParams implements HasToJson {
-  String _file;
-
-  List<HighlightRegion> _regions;
-
   /// The file containing the highlight regions.
-  String get file => _file;
-
-  /// The file containing the highlight regions.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// The highlight regions contained in the file. Each highlight region
   /// represents a particular syntactic or semantic meaning associated with
   /// some range. Note that the highlight regions that are returned can overlap
   /// other highlight regions if there is more than one meaning associated with
   /// a particular region.
-  List<HighlightRegion> get regions => _regions;
+  List<HighlightRegion> regions;
 
-  /// The highlight regions contained in the file. Each highlight region
-  /// represents a particular syntactic or semantic meaning associated with
-  /// some range. Note that the highlight regions that are returned can overlap
-  /// other highlight regions if there is more than one meaning associated with
-  /// a particular region.
-  set regions(List<HighlightRegion> value) {
-    assert(value != null);
-    _regions = value;
-  }
-
-  AnalysisHighlightsParams(String file, List<HighlightRegion> regions) {
-    this.file = file;
-    this.regions = regions;
-  }
+  AnalysisHighlightsParams(this.file, this.regions);
 
   factory AnalysisHighlightsParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -2016,7 +1635,7 @@
         regions = jsonDecoder.decodeList(
             jsonPath + '.regions',
             json['regions'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 HighlightRegion.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'regions');
@@ -2033,8 +1652,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     result['regions'] =
         regions.map((HighlightRegion value) => value.toJson()).toList();
@@ -2077,48 +1696,19 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisImplementedParams implements HasToJson {
-  String _file;
-
-  List<ImplementedClass> _classes;
-
-  List<ImplementedMember> _members;
-
   /// The file with which the implementations are associated.
-  String get file => _file;
-
-  /// The file with which the implementations are associated.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// The classes defined in the file that are implemented or extended.
-  List<ImplementedClass> get classes => _classes;
-
-  /// The classes defined in the file that are implemented or extended.
-  set classes(List<ImplementedClass> value) {
-    assert(value != null);
-    _classes = value;
-  }
+  List<ImplementedClass> classes;
 
   /// The member defined in the file that are implemented or overridden.
-  List<ImplementedMember> get members => _members;
+  List<ImplementedMember> members;
 
-  /// The member defined in the file that are implemented or overridden.
-  set members(List<ImplementedMember> value) {
-    assert(value != null);
-    _members = value;
-  }
-
-  AnalysisImplementedParams(String file, List<ImplementedClass> classes,
-      List<ImplementedMember> members) {
-    this.file = file;
-    this.classes = classes;
-    this.members = members;
-  }
+  AnalysisImplementedParams(this.file, this.classes, this.members);
 
   factory AnalysisImplementedParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -2132,7 +1722,7 @@
         classes = jsonDecoder.decodeList(
             jsonPath + '.classes',
             json['classes'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 ImplementedClass.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'classes');
@@ -2142,7 +1732,7 @@
         members = jsonDecoder.decodeList(
             jsonPath + '.members',
             json['members'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 ImplementedMember.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'members');
@@ -2160,8 +1750,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     result['classes'] =
         classes.map((ImplementedClass value) => value.toJson()).toList();
@@ -2210,63 +1800,24 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisInvalidateParams implements HasToJson {
-  String _file;
-
-  int _offset;
-
-  int _length;
-
-  int _delta;
-
   /// The file whose information has been invalidated.
-  String get file => _file;
-
-  /// The file whose information has been invalidated.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// The offset of the invalidated region.
-  int get offset => _offset;
-
-  /// The offset of the invalidated region.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
+  int offset;
 
   /// The length of the invalidated region.
-  int get length => _length;
-
-  /// The length of the invalidated region.
-  set length(int value) {
-    assert(value != null);
-    _length = value;
-  }
+  int length;
 
   /// The delta to be applied to the offsets in information that follows the
   /// invalidated region in order to update it so that it doesn't need to be
   /// re-requested.
-  int get delta => _delta;
+  int delta;
 
-  /// The delta to be applied to the offsets in information that follows the
-  /// invalidated region in order to update it so that it doesn't need to be
-  /// re-requested.
-  set delta(int value) {
-    assert(value != null);
-    _delta = value;
-  }
-
-  AnalysisInvalidateParams(String file, int offset, int length, int delta) {
-    this.file = file;
-    this.offset = offset;
-    this.length = length;
-    this.delta = delta;
-  }
+  AnalysisInvalidateParams(this.file, this.offset, this.length, this.delta);
 
   factory AnalysisInvalidateParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -2305,8 +1856,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     result['offset'] = offset;
     result['length'] = length;
@@ -2354,22 +1905,8 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisNavigationParams implements HasToJson {
-  String _file;
-
-  List<NavigationRegion> _regions;
-
-  List<NavigationTarget> _targets;
-
-  List<String> _files;
-
   /// The file containing the navigation regions.
-  String get file => _file;
-
-  /// The file containing the navigation regions.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// The navigation regions contained in the file. The regions are sorted by
   /// their offsets. Each navigation region represents a list of targets
@@ -2378,52 +1915,20 @@
   /// multiple libraries or in Dart code that is compiled against multiple
   /// versions of a package. Note that the navigation regions that are returned
   /// do not overlap other navigation regions.
-  List<NavigationRegion> get regions => _regions;
-
-  /// The navigation regions contained in the file. The regions are sorted by
-  /// their offsets. Each navigation region represents a list of targets
-  /// associated with some range. The lists will usually contain a single
-  /// target, but can contain more in the case of a part that is included in
-  /// multiple libraries or in Dart code that is compiled against multiple
-  /// versions of a package. Note that the navigation regions that are returned
-  /// do not overlap other navigation regions.
-  set regions(List<NavigationRegion> value) {
-    assert(value != null);
-    _regions = value;
-  }
+  List<NavigationRegion> regions;
 
   /// The navigation targets referenced in the file. They are referenced by
   /// NavigationRegions by their index in this array.
-  List<NavigationTarget> get targets => _targets;
-
-  /// The navigation targets referenced in the file. They are referenced by
-  /// NavigationRegions by their index in this array.
-  set targets(List<NavigationTarget> value) {
-    assert(value != null);
-    _targets = value;
-  }
+  List<NavigationTarget> targets;
 
   /// The files containing navigation targets referenced in the file. They are
   /// referenced by NavigationTargets by their index in this array.
-  List<String> get files => _files;
+  List<String> files;
 
-  /// The files containing navigation targets referenced in the file. They are
-  /// referenced by NavigationTargets by their index in this array.
-  set files(List<String> value) {
-    assert(value != null);
-    _files = value;
-  }
-
-  AnalysisNavigationParams(String file, List<NavigationRegion> regions,
-      List<NavigationTarget> targets, List<String> files) {
-    this.file = file;
-    this.regions = regions;
-    this.targets = targets;
-    this.files = files;
-  }
+  AnalysisNavigationParams(this.file, this.regions, this.targets, this.files);
 
   factory AnalysisNavigationParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -2437,7 +1942,7 @@
         regions = jsonDecoder.decodeList(
             jsonPath + '.regions',
             json['regions'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 NavigationRegion.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'regions');
@@ -2447,7 +1952,7 @@
         targets = jsonDecoder.decodeList(
             jsonPath + '.targets',
             json['targets'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 NavigationTarget.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'targets');
@@ -2471,8 +1976,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     result['regions'] =
         regions.map((NavigationRegion value) => value.toJson()).toList();
@@ -2522,35 +2027,16 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisOccurrencesParams implements HasToJson {
-  String _file;
-
-  List<Occurrences> _occurrences;
-
   /// The file in which the references occur.
-  String get file => _file;
-
-  /// The file in which the references occur.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// The occurrences of references to elements within the file.
-  List<Occurrences> get occurrences => _occurrences;
+  List<Occurrences> occurrences;
 
-  /// The occurrences of references to elements within the file.
-  set occurrences(List<Occurrences> value) {
-    assert(value != null);
-    _occurrences = value;
-  }
-
-  AnalysisOccurrencesParams(String file, List<Occurrences> occurrences) {
-    this.file = file;
-    this.occurrences = occurrences;
-  }
+  AnalysisOccurrencesParams(this.file, this.occurrences);
 
   factory AnalysisOccurrencesParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -2564,7 +2050,7 @@
         occurrences = jsonDecoder.decodeList(
             jsonPath + '.occurrences',
             json['occurrences'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 Occurrences.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'occurrences');
@@ -2582,8 +2068,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     result['occurrences'] =
         occurrences.map((Occurrences value) => value.toJson()).toList();
@@ -2631,176 +2117,96 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisOptions implements HasToJson {
-  bool _enableAsync;
-
-  bool _enableDeferredLoading;
-
-  bool _enableEnums;
-
-  bool _enableNullAwareOperators;
-
-  bool _enableSuperMixins;
-
-  bool _generateDart2jsHints;
-
-  bool _generateHints;
-
-  bool _generateLints;
-
   /// Deprecated: this feature is always enabled.
   ///
   /// True if the client wants to enable support for the proposed async
   /// feature.
-  bool get enableAsync => _enableAsync;
-
-  /// Deprecated: this feature is always enabled.
-  ///
-  /// True if the client wants to enable support for the proposed async
-  /// feature.
-  set enableAsync(bool value) {
-    _enableAsync = value;
-  }
+  bool? enableAsync;
 
   /// Deprecated: this feature is always enabled.
   ///
   /// True if the client wants to enable support for the proposed deferred
   /// loading feature.
-  bool get enableDeferredLoading => _enableDeferredLoading;
-
-  /// Deprecated: this feature is always enabled.
-  ///
-  /// True if the client wants to enable support for the proposed deferred
-  /// loading feature.
-  set enableDeferredLoading(bool value) {
-    _enableDeferredLoading = value;
-  }
+  bool? enableDeferredLoading;
 
   /// Deprecated: this feature is always enabled.
   ///
   /// True if the client wants to enable support for the proposed enum feature.
-  bool get enableEnums => _enableEnums;
-
-  /// Deprecated: this feature is always enabled.
-  ///
-  /// True if the client wants to enable support for the proposed enum feature.
-  set enableEnums(bool value) {
-    _enableEnums = value;
-  }
+  bool? enableEnums;
 
   /// Deprecated: this feature is always enabled.
   ///
   /// True if the client wants to enable support for the proposed "null aware
   /// operators" feature.
-  bool get enableNullAwareOperators => _enableNullAwareOperators;
-
-  /// Deprecated: this feature is always enabled.
-  ///
-  /// True if the client wants to enable support for the proposed "null aware
-  /// operators" feature.
-  set enableNullAwareOperators(bool value) {
-    _enableNullAwareOperators = value;
-  }
+  bool? enableNullAwareOperators;
 
   /// True if the client wants to enable support for the proposed "less
   /// restricted mixins" proposal (DEP 34).
-  bool get enableSuperMixins => _enableSuperMixins;
-
-  /// True if the client wants to enable support for the proposed "less
-  /// restricted mixins" proposal (DEP 34).
-  set enableSuperMixins(bool value) {
-    _enableSuperMixins = value;
-  }
+  bool? enableSuperMixins;
 
   /// True if hints that are specific to dart2js should be generated. This
   /// option is ignored if generateHints is false.
-  bool get generateDart2jsHints => _generateDart2jsHints;
-
-  /// True if hints that are specific to dart2js should be generated. This
-  /// option is ignored if generateHints is false.
-  set generateDart2jsHints(bool value) {
-    _generateDart2jsHints = value;
-  }
+  bool? generateDart2jsHints;
 
   /// True if hints should be generated as part of generating errors and
   /// warnings.
-  bool get generateHints => _generateHints;
-
-  /// True if hints should be generated as part of generating errors and
-  /// warnings.
-  set generateHints(bool value) {
-    _generateHints = value;
-  }
+  bool? generateHints;
 
   /// True if lints should be generated as part of generating errors and
   /// warnings.
-  bool get generateLints => _generateLints;
-
-  /// True if lints should be generated as part of generating errors and
-  /// warnings.
-  set generateLints(bool value) {
-    _generateLints = value;
-  }
+  bool? generateLints;
 
   AnalysisOptions(
-      {bool enableAsync,
-      bool enableDeferredLoading,
-      bool enableEnums,
-      bool enableNullAwareOperators,
-      bool enableSuperMixins,
-      bool generateDart2jsHints,
-      bool generateHints,
-      bool generateLints}) {
-    this.enableAsync = enableAsync;
-    this.enableDeferredLoading = enableDeferredLoading;
-    this.enableEnums = enableEnums;
-    this.enableNullAwareOperators = enableNullAwareOperators;
-    this.enableSuperMixins = enableSuperMixins;
-    this.generateDart2jsHints = generateDart2jsHints;
-    this.generateHints = generateHints;
-    this.generateLints = generateLints;
-  }
+      {this.enableAsync,
+      this.enableDeferredLoading,
+      this.enableEnums,
+      this.enableNullAwareOperators,
+      this.enableSuperMixins,
+      this.generateDart2jsHints,
+      this.generateHints,
+      this.generateLints});
 
   factory AnalysisOptions.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
-      bool enableAsync;
+      bool? enableAsync;
       if (json.containsKey('enableAsync')) {
         enableAsync = jsonDecoder.decodeBool(
             jsonPath + '.enableAsync', json['enableAsync']);
       }
-      bool enableDeferredLoading;
+      bool? enableDeferredLoading;
       if (json.containsKey('enableDeferredLoading')) {
         enableDeferredLoading = jsonDecoder.decodeBool(
             jsonPath + '.enableDeferredLoading', json['enableDeferredLoading']);
       }
-      bool enableEnums;
+      bool? enableEnums;
       if (json.containsKey('enableEnums')) {
         enableEnums = jsonDecoder.decodeBool(
             jsonPath + '.enableEnums', json['enableEnums']);
       }
-      bool enableNullAwareOperators;
+      bool? enableNullAwareOperators;
       if (json.containsKey('enableNullAwareOperators')) {
         enableNullAwareOperators = jsonDecoder.decodeBool(
             jsonPath + '.enableNullAwareOperators',
             json['enableNullAwareOperators']);
       }
-      bool enableSuperMixins;
+      bool? enableSuperMixins;
       if (json.containsKey('enableSuperMixins')) {
         enableSuperMixins = jsonDecoder.decodeBool(
             jsonPath + '.enableSuperMixins', json['enableSuperMixins']);
       }
-      bool generateDart2jsHints;
+      bool? generateDart2jsHints;
       if (json.containsKey('generateDart2jsHints')) {
         generateDart2jsHints = jsonDecoder.decodeBool(
             jsonPath + '.generateDart2jsHints', json['generateDart2jsHints']);
       }
-      bool generateHints;
+      bool? generateHints;
       if (json.containsKey('generateHints')) {
         generateHints = jsonDecoder.decodeBool(
             jsonPath + '.generateHints', json['generateHints']);
       }
-      bool generateLints;
+      bool? generateLints;
       if (json.containsKey('generateLints')) {
         generateLints = jsonDecoder.decodeBool(
             jsonPath + '.generateLints', json['generateLints']);
@@ -2820,29 +2226,37 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
+    var enableAsync = this.enableAsync;
     if (enableAsync != null) {
       result['enableAsync'] = enableAsync;
     }
+    var enableDeferredLoading = this.enableDeferredLoading;
     if (enableDeferredLoading != null) {
       result['enableDeferredLoading'] = enableDeferredLoading;
     }
+    var enableEnums = this.enableEnums;
     if (enableEnums != null) {
       result['enableEnums'] = enableEnums;
     }
+    var enableNullAwareOperators = this.enableNullAwareOperators;
     if (enableNullAwareOperators != null) {
       result['enableNullAwareOperators'] = enableNullAwareOperators;
     }
+    var enableSuperMixins = this.enableSuperMixins;
     if (enableSuperMixins != null) {
       result['enableSuperMixins'] = enableSuperMixins;
     }
+    var generateDart2jsHints = this.generateDart2jsHints;
     if (generateDart2jsHints != null) {
       result['generateDart2jsHints'] = generateDart2jsHints;
     }
+    var generateHints = this.generateHints;
     if (generateHints != null) {
       result['generateHints'] = generateHints;
     }
+    var generateLints = this.generateLints;
     if (generateLints != null) {
       result['generateLints'] = generateLints;
     }
@@ -2893,67 +2307,26 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisOutlineParams implements HasToJson {
-  String _file;
-
-  FileKind _kind;
-
-  String _libraryName;
-
-  Outline _outline;
-
   /// The file with which the outline is associated.
-  String get file => _file;
-
-  /// The file with which the outline is associated.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// The kind of the file.
-  FileKind get kind => _kind;
-
-  /// The kind of the file.
-  set kind(FileKind value) {
-    assert(value != null);
-    _kind = value;
-  }
+  FileKind kind;
 
   /// The name of the library defined by the file using a "library" directive,
   /// or referenced by a "part of" directive. If both "library" and "part of"
   /// directives are present, then the "library" directive takes precedence.
   /// This field will be omitted if the file has neither "library" nor "part
   /// of" directives.
-  String get libraryName => _libraryName;
-
-  /// The name of the library defined by the file using a "library" directive,
-  /// or referenced by a "part of" directive. If both "library" and "part of"
-  /// directives are present, then the "library" directive takes precedence.
-  /// This field will be omitted if the file has neither "library" nor "part
-  /// of" directives.
-  set libraryName(String value) {
-    _libraryName = value;
-  }
+  String? libraryName;
 
   /// The outline associated with the file.
-  Outline get outline => _outline;
+  Outline outline;
 
-  /// The outline associated with the file.
-  set outline(Outline value) {
-    assert(value != null);
-    _outline = value;
-  }
-
-  AnalysisOutlineParams(String file, FileKind kind, Outline outline,
-      {String libraryName}) {
-    this.file = file;
-    this.kind = kind;
-    this.libraryName = libraryName;
-    this.outline = outline;
-  }
+  AnalysisOutlineParams(this.file, this.kind, this.outline, {this.libraryName});
 
   factory AnalysisOutlineParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -2968,7 +2341,7 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'kind');
       }
-      String libraryName;
+      String? libraryName;
       if (json.containsKey('libraryName')) {
         libraryName = jsonDecoder.decodeString(
             jsonPath + '.libraryName', json['libraryName']);
@@ -2993,10 +2366,11 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     result['kind'] = kind.toJson();
+    var libraryName = this.libraryName;
     if (libraryName != null) {
       result['libraryName'] = libraryName;
     }
@@ -3042,35 +2416,16 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisOverridesParams implements HasToJson {
-  String _file;
-
-  List<Override> _overrides;
-
   /// The file with which the overrides are associated.
-  String get file => _file;
-
-  /// The file with which the overrides are associated.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// The overrides associated with the file.
-  List<Override> get overrides => _overrides;
+  List<Override> overrides;
 
-  /// The overrides associated with the file.
-  set overrides(List<Override> value) {
-    assert(value != null);
-    _overrides = value;
-  }
-
-  AnalysisOverridesParams(String file, List<Override> overrides) {
-    this.file = file;
-    this.overrides = overrides;
-  }
+  AnalysisOverridesParams(this.file, this.overrides);
 
   factory AnalysisOverridesParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -3084,7 +2439,7 @@
         overrides = jsonDecoder.decodeList(
             jsonPath + '.overrides',
             json['overrides'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 Override.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'overrides');
@@ -3101,8 +2456,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     result['overrides'] =
         overrides.map((Override value) => value.toJson()).toList();
@@ -3140,7 +2495,7 @@
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisReanalyzeParams implements RequestParams {
   @override
-  Map<String, dynamic> toJson() => <String, dynamic>{};
+  Map<String, Object> toJson() => <String, Object>{};
 
   @override
   Request toRequest(String id) {
@@ -3166,7 +2521,7 @@
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisReanalyzeResult implements ResponseResult {
   @override
-  Map<String, dynamic> toJson() => <String, dynamic>{};
+  Map<String, Object> toJson() => <String, Object>{};
 
   @override
   Response toResponse(String id) {
@@ -3267,7 +2622,7 @@
   }
 
   factory AnalysisService.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     if (json is String) {
       try {
         return AnalysisService(json);
@@ -3294,31 +2649,12 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisSetAnalysisRootsParams implements RequestParams {
-  List<String> _included;
-
-  List<String> _excluded;
-
-  Map<String, String> _packageRoots;
-
   /// A list of the files and directories that should be analyzed.
-  List<String> get included => _included;
-
-  /// A list of the files and directories that should be analyzed.
-  set included(List<String> value) {
-    assert(value != null);
-    _included = value;
-  }
+  List<String> included;
 
   /// A list of the files and directories within the included directories that
   /// should not be analyzed.
-  List<String> get excluded => _excluded;
-
-  /// A list of the files and directories within the included directories that
-  /// should not be analyzed.
-  set excluded(List<String> value) {
-    assert(value != null);
-    _excluded = value;
-  }
+  List<String> excluded;
 
   /// A mapping from source directories to package roots that should override
   /// the normal package: URI resolution mechanism.
@@ -3332,33 +2668,13 @@
   /// their package: URI's resolved using the normal pubspec.yaml mechanism. If
   /// this field is absent, or the empty map is specified, that indicates that
   /// the normal pubspec.yaml mechanism should always be used.
-  Map<String, String> get packageRoots => _packageRoots;
+  Map<String, String>? packageRoots;
 
-  /// A mapping from source directories to package roots that should override
-  /// the normal package: URI resolution mechanism.
-  ///
-  /// If a package root is a file, then the analyzer will behave as though that
-  /// file is a ".packages" file in the source directory. The effect is the
-  /// same as specifying the file as a "--packages" parameter to the Dart VM
-  /// when executing any Dart file inside the source directory.
-  ///
-  /// Files in any directories that are not overridden by this mapping have
-  /// their package: URI's resolved using the normal pubspec.yaml mechanism. If
-  /// this field is absent, or the empty map is specified, that indicates that
-  /// the normal pubspec.yaml mechanism should always be used.
-  set packageRoots(Map<String, String> value) {
-    _packageRoots = value;
-  }
-
-  AnalysisSetAnalysisRootsParams(List<String> included, List<String> excluded,
-      {Map<String, String> packageRoots}) {
-    this.included = included;
-    this.excluded = excluded;
-    this.packageRoots = packageRoots;
-  }
+  AnalysisSetAnalysisRootsParams(this.included, this.excluded,
+      {this.packageRoots});
 
   factory AnalysisSetAnalysisRootsParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       List<String> included;
@@ -3375,7 +2691,7 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'excluded');
       }
-      Map<String, String> packageRoots;
+      Map<String, String>? packageRoots;
       if (json.containsKey('packageRoots')) {
         packageRoots = jsonDecoder.decodeMap(
             jsonPath + '.packageRoots', json['packageRoots'],
@@ -3395,10 +2711,11 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['included'] = included;
     result['excluded'] = excluded;
+    var packageRoots = this.packageRoots;
     if (packageRoots != null) {
       result['packageRoots'] = packageRoots;
     }
@@ -3440,7 +2757,7 @@
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisSetAnalysisRootsResult implements ResponseResult {
   @override
-  Map<String, dynamic> toJson() => <String, dynamic>{};
+  Map<String, Object> toJson() => <String, Object>{};
 
   @override
   Response toResponse(String id) {
@@ -3469,24 +2786,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisSetGeneralSubscriptionsParams implements RequestParams {
-  List<GeneralAnalysisService> _subscriptions;
-
   /// A list of the services being subscribed to.
-  List<GeneralAnalysisService> get subscriptions => _subscriptions;
+  List<GeneralAnalysisService> subscriptions;
 
-  /// A list of the services being subscribed to.
-  set subscriptions(List<GeneralAnalysisService> value) {
-    assert(value != null);
-    _subscriptions = value;
-  }
-
-  AnalysisSetGeneralSubscriptionsParams(
-      List<GeneralAnalysisService> subscriptions) {
-    this.subscriptions = subscriptions;
-  }
+  AnalysisSetGeneralSubscriptionsParams(this.subscriptions);
 
   factory AnalysisSetGeneralSubscriptionsParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       List<GeneralAnalysisService> subscriptions;
@@ -3494,7 +2800,7 @@
         subscriptions = jsonDecoder.decodeList(
             jsonPath + '.subscriptions',
             json['subscriptions'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 GeneralAnalysisService.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'subscriptions');
@@ -3512,8 +2818,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['subscriptions'] = subscriptions
         .map((GeneralAnalysisService value) => value.toJson())
         .toList();
@@ -3550,7 +2856,7 @@
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisSetGeneralSubscriptionsResult implements ResponseResult {
   @override
-  Map<String, dynamic> toJson() => <String, dynamic>{};
+  Map<String, Object> toJson() => <String, Object>{};
 
   @override
   Response toResponse(String id) {
@@ -3579,23 +2885,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisSetPriorityFilesParams implements RequestParams {
-  List<String> _files;
-
   /// The files that are to be a priority for analysis.
-  List<String> get files => _files;
+  List<String> files;
 
-  /// The files that are to be a priority for analysis.
-  set files(List<String> value) {
-    assert(value != null);
-    _files = value;
-  }
-
-  AnalysisSetPriorityFilesParams(List<String> files) {
-    this.files = files;
-  }
+  AnalysisSetPriorityFilesParams(this.files);
 
   factory AnalysisSetPriorityFilesParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       List<String> files;
@@ -3618,8 +2914,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['files'] = files;
     return result;
   }
@@ -3653,7 +2949,7 @@
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisSetPriorityFilesResult implements ResponseResult {
   @override
-  Map<String, dynamic> toJson() => <String, dynamic>{};
+  Map<String, Object> toJson() => <String, Object>{};
 
   @override
   Response toResponse(String id) {
@@ -3682,35 +2978,23 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisSetSubscriptionsParams implements RequestParams {
-  Map<AnalysisService, List<String>> _subscriptions;
-
   /// A table mapping services to a list of the files being subscribed to the
   /// service.
-  Map<AnalysisService, List<String>> get subscriptions => _subscriptions;
+  Map<AnalysisService, List<String>> subscriptions;
 
-  /// A table mapping services to a list of the files being subscribed to the
-  /// service.
-  set subscriptions(Map<AnalysisService, List<String>> value) {
-    assert(value != null);
-    _subscriptions = value;
-  }
-
-  AnalysisSetSubscriptionsParams(
-      Map<AnalysisService, List<String>> subscriptions) {
-    this.subscriptions = subscriptions;
-  }
+  AnalysisSetSubscriptionsParams(this.subscriptions);
 
   factory AnalysisSetSubscriptionsParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       Map<AnalysisService, List<String>> subscriptions;
       if (json.containsKey('subscriptions')) {
         subscriptions = jsonDecoder.decodeMap(
             jsonPath + '.subscriptions', json['subscriptions'],
-            keyDecoder: (String jsonPath, Object json) =>
+            keyDecoder: (String jsonPath, Object? json) =>
                 AnalysisService.fromJson(jsonDecoder, jsonPath, json),
-            valueDecoder: (String jsonPath, Object json) => jsonDecoder
+            valueDecoder: (String jsonPath, Object? json) => jsonDecoder
                 .decodeList(jsonPath, json, jsonDecoder.decodeString));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'subscriptions');
@@ -3728,8 +3012,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['subscriptions'] = mapMap(subscriptions,
         keyCallback: (AnalysisService value) => value.toJson());
     return result;
@@ -3768,7 +3052,7 @@
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisSetSubscriptionsResult implements ResponseResult {
   @override
-  Map<String, dynamic> toJson() => <String, dynamic>{};
+  Map<String, Object> toJson() => <String, Object>{};
 
   @override
   Response toResponse(String id) {
@@ -3798,36 +3082,17 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisStatus implements HasToJson {
-  bool _isAnalyzing;
-
-  String _analysisTarget;
-
   /// True if analysis is currently being performed.
-  bool get isAnalyzing => _isAnalyzing;
-
-  /// True if analysis is currently being performed.
-  set isAnalyzing(bool value) {
-    assert(value != null);
-    _isAnalyzing = value;
-  }
+  bool isAnalyzing;
 
   /// The name of the current target of analysis. This field is omitted if
   /// analyzing is false.
-  String get analysisTarget => _analysisTarget;
+  String? analysisTarget;
 
-  /// The name of the current target of analysis. This field is omitted if
-  /// analyzing is false.
-  set analysisTarget(String value) {
-    _analysisTarget = value;
-  }
-
-  AnalysisStatus(bool isAnalyzing, {String analysisTarget}) {
-    this.isAnalyzing = isAnalyzing;
-    this.analysisTarget = analysisTarget;
-  }
+  AnalysisStatus(this.isAnalyzing, {this.analysisTarget});
 
   factory AnalysisStatus.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       bool isAnalyzing;
@@ -3837,7 +3102,7 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'isAnalyzing');
       }
-      String analysisTarget;
+      String? analysisTarget;
       if (json.containsKey('analysisTarget')) {
         analysisTarget = jsonDecoder.decodeString(
             jsonPath + '.analysisTarget', json['analysisTarget']);
@@ -3849,9 +3114,10 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['isAnalyzing'] = isAnalyzing;
+    var analysisTarget = this.analysisTarget;
     if (analysisTarget != null) {
       result['analysisTarget'] = analysisTarget;
     }
@@ -3887,38 +3153,27 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisUpdateContentParams implements RequestParams {
-  Map<String, dynamic> _files;
-
   /// A table mapping the files whose content has changed to a description of
   /// the content change.
-  Map<String, dynamic> get files => _files;
+  Map<String, Object> files;
 
-  /// A table mapping the files whose content has changed to a description of
-  /// the content change.
-  set files(Map<String, dynamic> value) {
-    assert(value != null);
-    _files = value;
-  }
-
-  AnalysisUpdateContentParams(Map<String, dynamic> files) {
-    this.files = files;
-  }
+  AnalysisUpdateContentParams(this.files);
 
   factory AnalysisUpdateContentParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
-      Map<String, dynamic> files;
+      Map<String, Object> files;
       if (json.containsKey('files')) {
         files = jsonDecoder.decodeMap(jsonPath + '.files', json['files'],
-            valueDecoder: (String jsonPath, Object json) =>
+            valueDecoder: (String jsonPath, Object? json) =>
                 jsonDecoder.decodeUnion(jsonPath, json, 'type', {
-                  'add': (String jsonPath, Object json) =>
+                  'add': (String jsonPath, Object? json) =>
                       AddContentOverlay.fromJson(jsonDecoder, jsonPath, json),
-                  'change': (String jsonPath, Object json) =>
+                  'change': (String jsonPath, Object? json) =>
                       ChangeContentOverlay.fromJson(
                           jsonDecoder, jsonPath, json),
-                  'remove': (String jsonPath, Object json) =>
+                  'remove': (String jsonPath, Object? json) =>
                       RemoveContentOverlay.fromJson(jsonDecoder, jsonPath, json)
                 }));
       } else {
@@ -3937,10 +3192,10 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
-    result['files'] =
-        mapMap(files, valueCallback: (dynamic value) => value.toJson());
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
+    result['files'] = mapMap(files,
+        valueCallback: (Object value) => (value as dynamic).toJson());
     return result;
   }
 
@@ -3955,7 +3210,7 @@
   @override
   bool operator ==(other) {
     if (other is AnalysisUpdateContentParams) {
-      return mapEqual(files, other.files, (dynamic a, dynamic b) => a == b);
+      return mapEqual(files, other.files, (Object a, Object b) => a == b);
     }
     return false;
   }
@@ -3978,7 +3233,7 @@
   AnalysisUpdateContentResult();
 
   factory AnalysisUpdateContentResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       return AnalysisUpdateContentResult();
@@ -3996,8 +3251,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     return result;
   }
 
@@ -4032,23 +3287,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisUpdateOptionsParams implements RequestParams {
-  AnalysisOptions _options;
-
   /// The options that are to be used to control analysis.
-  AnalysisOptions get options => _options;
+  AnalysisOptions options;
 
-  /// The options that are to be used to control analysis.
-  set options(AnalysisOptions value) {
-    assert(value != null);
-    _options = value;
-  }
-
-  AnalysisUpdateOptionsParams(AnalysisOptions options) {
-    this.options = options;
-  }
+  AnalysisUpdateOptionsParams(this.options);
 
   factory AnalysisUpdateOptionsParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       AnalysisOptions options;
@@ -4071,8 +3316,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['options'] = options.toJson();
     return result;
   }
@@ -4106,7 +3351,7 @@
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisUpdateOptionsResult implements ResponseResult {
   @override
-  Map<String, dynamic> toJson() => <String, dynamic>{};
+  Map<String, Object> toJson() => <String, Object>{};
 
   @override
   Response toResponse(String id) {
@@ -4135,23 +3380,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalyticsEnableParams implements RequestParams {
-  bool _value;
-
   /// Enable or disable analytics.
-  bool get value => _value;
+  bool value;
 
-  /// Enable or disable analytics.
-  set value(bool value) {
-    assert(value != null);
-    _value = value;
-  }
-
-  AnalyticsEnableParams(bool value) {
-    this.value = value;
-  }
+  AnalyticsEnableParams(this.value);
 
   factory AnalyticsEnableParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       bool value;
@@ -4172,8 +3407,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['value'] = value;
     return result;
   }
@@ -4207,7 +3442,7 @@
 /// Clients may not extend, implement or mix-in this class.
 class AnalyticsEnableResult implements ResponseResult {
   @override
-  Map<String, dynamic> toJson() => <String, dynamic>{};
+  Map<String, Object> toJson() => <String, Object>{};
 
   @override
   Response toResponse(String id) {
@@ -4233,7 +3468,7 @@
 /// Clients may not extend, implement or mix-in this class.
 class AnalyticsIsEnabledParams implements RequestParams {
   @override
-  Map<String, dynamic> toJson() => <String, dynamic>{};
+  Map<String, Object> toJson() => <String, Object>{};
 
   @override
   Request toRequest(String id) {
@@ -4262,23 +3497,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalyticsIsEnabledResult implements ResponseResult {
-  bool _enabled;
-
   /// Whether sending analytics is enabled or not.
-  bool get enabled => _enabled;
+  bool enabled;
 
-  /// Whether sending analytics is enabled or not.
-  set enabled(bool value) {
-    assert(value != null);
-    _enabled = value;
-  }
-
-  AnalyticsIsEnabledResult(bool enabled) {
-    this.enabled = enabled;
-  }
+  AnalyticsIsEnabledResult(this.enabled);
 
   factory AnalyticsIsEnabledResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       bool enabled;
@@ -4302,8 +3527,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['enabled'] = enabled;
     return result;
   }
@@ -4340,23 +3565,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalyticsSendEventParams implements RequestParams {
-  String _action;
-
   /// The value used to indicate which action was performed.
-  String get action => _action;
+  String action;
 
-  /// The value used to indicate which action was performed.
-  set action(String value) {
-    assert(value != null);
-    _action = value;
-  }
-
-  AnalyticsSendEventParams(String action) {
-    this.action = action;
-  }
+  AnalyticsSendEventParams(this.action);
 
   factory AnalyticsSendEventParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String action;
@@ -4377,8 +3592,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['action'] = action;
     return result;
   }
@@ -4412,7 +3627,7 @@
 /// Clients may not extend, implement or mix-in this class.
 class AnalyticsSendEventResult implements ResponseResult {
   @override
-  Map<String, dynamic> toJson() => <String, dynamic>{};
+  Map<String, Object> toJson() => <String, Object>{};
 
   @override
   Response toResponse(String id) {
@@ -4442,35 +3657,16 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalyticsSendTimingParams implements RequestParams {
-  String _event;
-
-  int _millis;
-
   /// The name of the event.
-  String get event => _event;
-
-  /// The name of the event.
-  set event(String value) {
-    assert(value != null);
-    _event = value;
-  }
+  String event;
 
   /// The duration of the event in milliseconds.
-  int get millis => _millis;
+  int millis;
 
-  /// The duration of the event in milliseconds.
-  set millis(int value) {
-    assert(value != null);
-    _millis = value;
-  }
-
-  AnalyticsSendTimingParams(String event, int millis) {
-    this.event = event;
-    this.millis = millis;
-  }
+  AnalyticsSendTimingParams(this.event, this.millis);
 
   factory AnalyticsSendTimingParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String event;
@@ -4497,8 +3693,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['event'] = event;
     result['millis'] = millis;
     return result;
@@ -4534,7 +3730,7 @@
 /// Clients may not extend, implement or mix-in this class.
 class AnalyticsSendTimingResult implements ResponseResult {
   @override
-  Map<String, dynamic> toJson() => <String, dynamic>{};
+  Map<String, Object> toJson() => <String, Object>{};
 
   @override
   Response toResponse(String id) {
@@ -4571,62 +3767,19 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AvailableSuggestion implements HasToJson {
-  String _label;
-
-  String _declaringLibraryUri;
-
-  Element _element;
-
-  String _defaultArgumentListString;
-
-  List<int> _defaultArgumentListTextRanges;
-
-  List<String> _parameterNames;
-
-  List<String> _parameterTypes;
-
-  List<String> _relevanceTags;
-
-  int _requiredParameterCount;
-
   /// The identifier to present to the user for code completion.
-  String get label => _label;
-
-  /// The identifier to present to the user for code completion.
-  set label(String value) {
-    assert(value != null);
-    _label = value;
-  }
+  String label;
 
   /// The URI of the library that declares the element being suggested, not the
   /// URI of the library associated with the enclosing AvailableSuggestionSet.
-  String get declaringLibraryUri => _declaringLibraryUri;
-
-  /// The URI of the library that declares the element being suggested, not the
-  /// URI of the library associated with the enclosing AvailableSuggestionSet.
-  set declaringLibraryUri(String value) {
-    assert(value != null);
-    _declaringLibraryUri = value;
-  }
+  String declaringLibraryUri;
 
   /// Information about the element reference being suggested.
-  Element get element => _element;
-
-  /// Information about the element reference being suggested.
-  set element(Element value) {
-    assert(value != null);
-    _element = value;
-  }
+  Element element;
 
   /// A default String for use in generating argument list source contents on
   /// the client side.
-  String get defaultArgumentListString => _defaultArgumentListString;
-
-  /// A default String for use in generating argument list source contents on
-  /// the client side.
-  set defaultArgumentListString(String value) {
-    _defaultArgumentListString = value;
-  }
+  String? defaultArgumentListString;
 
   /// Pairs of offsets and lengths describing 'defaultArgumentListString' text
   /// ranges suitable for use by clients to set up linked edits of default
@@ -4634,80 +3787,35 @@
   /// y', the corresponding text range [0, 1, 3, 1], indicates two text ranges
   /// of length 1, starting at offsets 0 and 3. Clients can use these ranges to
   /// treat the 'x' and 'y' values specially for linked edits.
-  List<int> get defaultArgumentListTextRanges => _defaultArgumentListTextRanges;
-
-  /// Pairs of offsets and lengths describing 'defaultArgumentListString' text
-  /// ranges suitable for use by clients to set up linked edits of default
-  /// argument source contents. For example, given an argument list string 'x,
-  /// y', the corresponding text range [0, 1, 3, 1], indicates two text ranges
-  /// of length 1, starting at offsets 0 and 3. Clients can use these ranges to
-  /// treat the 'x' and 'y' values specially for linked edits.
-  set defaultArgumentListTextRanges(List<int> value) {
-    _defaultArgumentListTextRanges = value;
-  }
+  List<int>? defaultArgumentListTextRanges;
 
   /// If the element is an executable, the names of the formal parameters of
   /// all kinds - required, optional positional, and optional named. The names
   /// of positional parameters are empty strings. Omitted if the element is not
   /// an executable.
-  List<String> get parameterNames => _parameterNames;
-
-  /// If the element is an executable, the names of the formal parameters of
-  /// all kinds - required, optional positional, and optional named. The names
-  /// of positional parameters are empty strings. Omitted if the element is not
-  /// an executable.
-  set parameterNames(List<String> value) {
-    _parameterNames = value;
-  }
+  List<String>? parameterNames;
 
   /// If the element is an executable, the declared types of the formal
   /// parameters of all kinds - required, optional positional, and optional
   /// named. Omitted if the element is not an executable.
-  List<String> get parameterTypes => _parameterTypes;
-
-  /// If the element is an executable, the declared types of the formal
-  /// parameters of all kinds - required, optional positional, and optional
-  /// named. Omitted if the element is not an executable.
-  set parameterTypes(List<String> value) {
-    _parameterTypes = value;
-  }
+  List<String>? parameterTypes;
 
   /// This field is set if the relevance of this suggestion might be changed
   /// depending on where completion is requested.
-  List<String> get relevanceTags => _relevanceTags;
+  List<String>? relevanceTags;
 
-  /// This field is set if the relevance of this suggestion might be changed
-  /// depending on where completion is requested.
-  set relevanceTags(List<String> value) {
-    _relevanceTags = value;
-  }
+  int? requiredParameterCount;
 
-  int get requiredParameterCount => _requiredParameterCount;
-
-  set requiredParameterCount(int value) {
-    _requiredParameterCount = value;
-  }
-
-  AvailableSuggestion(String label, String declaringLibraryUri, Element element,
-      {String defaultArgumentListString,
-      List<int> defaultArgumentListTextRanges,
-      List<String> parameterNames,
-      List<String> parameterTypes,
-      List<String> relevanceTags,
-      int requiredParameterCount}) {
-    this.label = label;
-    this.declaringLibraryUri = declaringLibraryUri;
-    this.element = element;
-    this.defaultArgumentListString = defaultArgumentListString;
-    this.defaultArgumentListTextRanges = defaultArgumentListTextRanges;
-    this.parameterNames = parameterNames;
-    this.parameterTypes = parameterTypes;
-    this.relevanceTags = relevanceTags;
-    this.requiredParameterCount = requiredParameterCount;
-  }
+  AvailableSuggestion(this.label, this.declaringLibraryUri, this.element,
+      {this.defaultArgumentListString,
+      this.defaultArgumentListTextRanges,
+      this.parameterNames,
+      this.parameterTypes,
+      this.relevanceTags,
+      this.requiredParameterCount});
 
   factory AvailableSuggestion.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String label;
@@ -4730,35 +3838,35 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'element');
       }
-      String defaultArgumentListString;
+      String? defaultArgumentListString;
       if (json.containsKey('defaultArgumentListString')) {
         defaultArgumentListString = jsonDecoder.decodeString(
             jsonPath + '.defaultArgumentListString',
             json['defaultArgumentListString']);
       }
-      List<int> defaultArgumentListTextRanges;
+      List<int>? defaultArgumentListTextRanges;
       if (json.containsKey('defaultArgumentListTextRanges')) {
         defaultArgumentListTextRanges = jsonDecoder.decodeList(
             jsonPath + '.defaultArgumentListTextRanges',
             json['defaultArgumentListTextRanges'],
             jsonDecoder.decodeInt);
       }
-      List<String> parameterNames;
+      List<String>? parameterNames;
       if (json.containsKey('parameterNames')) {
         parameterNames = jsonDecoder.decodeList(jsonPath + '.parameterNames',
             json['parameterNames'], jsonDecoder.decodeString);
       }
-      List<String> parameterTypes;
+      List<String>? parameterTypes;
       if (json.containsKey('parameterTypes')) {
         parameterTypes = jsonDecoder.decodeList(jsonPath + '.parameterTypes',
             json['parameterTypes'], jsonDecoder.decodeString);
       }
-      List<String> relevanceTags;
+      List<String>? relevanceTags;
       if (json.containsKey('relevanceTags')) {
         relevanceTags = jsonDecoder.decodeList(jsonPath + '.relevanceTags',
             json['relevanceTags'], jsonDecoder.decodeString);
       }
-      int requiredParameterCount;
+      int? requiredParameterCount;
       if (json.containsKey('requiredParameterCount')) {
         requiredParameterCount = jsonDecoder.decodeInt(
             jsonPath + '.requiredParameterCount',
@@ -4777,26 +3885,32 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['label'] = label;
     result['declaringLibraryUri'] = declaringLibraryUri;
     result['element'] = element.toJson();
+    var defaultArgumentListString = this.defaultArgumentListString;
     if (defaultArgumentListString != null) {
       result['defaultArgumentListString'] = defaultArgumentListString;
     }
+    var defaultArgumentListTextRanges = this.defaultArgumentListTextRanges;
     if (defaultArgumentListTextRanges != null) {
       result['defaultArgumentListTextRanges'] = defaultArgumentListTextRanges;
     }
+    var parameterNames = this.parameterNames;
     if (parameterNames != null) {
       result['parameterNames'] = parameterNames;
     }
+    var parameterTypes = this.parameterTypes;
     if (parameterTypes != null) {
       result['parameterTypes'] = parameterTypes;
     }
+    var relevanceTags = this.relevanceTags;
     if (relevanceTags != null) {
       result['relevanceTags'] = relevanceTags;
     }
+    var requiredParameterCount = this.requiredParameterCount;
     if (requiredParameterCount != null) {
       result['requiredParameterCount'] = requiredParameterCount;
     }
@@ -4852,45 +3966,18 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AvailableSuggestionSet implements HasToJson {
-  int _id;
-
-  String _uri;
-
-  List<AvailableSuggestion> _items;
-
   /// The id associated with the library.
-  int get id => _id;
-
-  /// The id associated with the library.
-  set id(int value) {
-    assert(value != null);
-    _id = value;
-  }
+  int id;
 
   /// The URI of the library.
-  String get uri => _uri;
+  String uri;
 
-  /// The URI of the library.
-  set uri(String value) {
-    assert(value != null);
-    _uri = value;
-  }
+  List<AvailableSuggestion> items;
 
-  List<AvailableSuggestion> get items => _items;
-
-  set items(List<AvailableSuggestion> value) {
-    assert(value != null);
-    _items = value;
-  }
-
-  AvailableSuggestionSet(int id, String uri, List<AvailableSuggestion> items) {
-    this.id = id;
-    this.uri = uri;
-    this.items = items;
-  }
+  AvailableSuggestionSet(this.id, this.uri, this.items);
 
   factory AvailableSuggestionSet.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       int id;
@@ -4910,7 +3997,7 @@
         items = jsonDecoder.decodeList(
             jsonPath + '.items',
             json['items'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 AvailableSuggestion.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'items');
@@ -4922,8 +4009,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['id'] = id;
     result['uri'] = uri;
     result['items'] =
@@ -4964,35 +4051,16 @@
 ///
 /// 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;
-  }
+  String path;
 
   /// A list of bulk fix details.
-  List<BulkFixDetail> get fixes => _fixes;
+  List<BulkFixDetail> 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;
-  }
+  BulkFix(this.path, this.fixes);
 
   factory BulkFix.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String path;
@@ -5006,7 +4074,7 @@
         fixes = jsonDecoder.decodeList(
             jsonPath + '.fixes',
             json['fixes'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 BulkFixDetail.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'fixes');
@@ -5018,8 +4086,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['path'] = path;
     result['fixes'] =
         fixes.map((BulkFixDetail value) => value.toJson()).toList();
@@ -5057,37 +4125,17 @@
 ///
 /// 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;
-  }
+  String code;
 
   /// The number times the associated diagnostic was fixed in the associated
   /// source edit.
-  int get occurrences => _occurrences;
+  int 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;
-  }
+  BulkFixDetail(this.code, this.occurrences);
 
   factory BulkFixDetail.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String code;
@@ -5110,8 +4158,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['code'] = code;
     result['occurrences'] = occurrences;
     return result;
@@ -5147,49 +4195,20 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class ClosingLabel implements HasToJson {
-  int _offset;
-
-  int _length;
-
-  String _label;
-
   /// The offset of the construct being labelled.
-  int get offset => _offset;
-
-  /// The offset of the construct being labelled.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
+  int offset;
 
   /// The length of the whole construct to be labelled.
-  int get length => _length;
-
-  /// The length of the whole construct to be labelled.
-  set length(int value) {
-    assert(value != null);
-    _length = value;
-  }
+  int length;
 
   /// The label associated with this range that should be displayed to the
   /// user.
-  String get label => _label;
+  String label;
 
-  /// The label associated with this range that should be displayed to the
-  /// user.
-  set label(String value) {
-    assert(value != null);
-    _label = value;
-  }
-
-  ClosingLabel(int offset, int length, String label) {
-    this.offset = offset;
-    this.length = length;
-    this.label = label;
-  }
+  ClosingLabel(this.offset, this.length, this.label);
 
   factory ClosingLabel.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       int offset;
@@ -5217,8 +4236,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['offset'] = offset;
     result['length'] = length;
     result['label'] = label;
@@ -5257,48 +4276,29 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class CompletionAvailableSuggestionsParams implements HasToJson {
-  List<AvailableSuggestionSet> _changedLibraries;
-
-  List<int> _removedLibraries;
-
   /// A list of pre-computed, potential completions coming from this set of
   /// completion suggestions.
-  List<AvailableSuggestionSet> get changedLibraries => _changedLibraries;
-
-  /// A list of pre-computed, potential completions coming from this set of
-  /// completion suggestions.
-  set changedLibraries(List<AvailableSuggestionSet> value) {
-    _changedLibraries = value;
-  }
+  List<AvailableSuggestionSet>? changedLibraries;
 
   /// A list of library ids that no longer apply.
-  List<int> get removedLibraries => _removedLibraries;
-
-  /// A list of library ids that no longer apply.
-  set removedLibraries(List<int> value) {
-    _removedLibraries = value;
-  }
+  List<int>? removedLibraries;
 
   CompletionAvailableSuggestionsParams(
-      {List<AvailableSuggestionSet> changedLibraries,
-      List<int> removedLibraries}) {
-    this.changedLibraries = changedLibraries;
-    this.removedLibraries = removedLibraries;
-  }
+      {this.changedLibraries, this.removedLibraries});
 
   factory CompletionAvailableSuggestionsParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
-      List<AvailableSuggestionSet> changedLibraries;
+      List<AvailableSuggestionSet>? changedLibraries;
       if (json.containsKey('changedLibraries')) {
         changedLibraries = jsonDecoder.decodeList(
             jsonPath + '.changedLibraries',
             json['changedLibraries'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 AvailableSuggestionSet.fromJson(jsonDecoder, jsonPath, json));
       }
-      List<int> removedLibraries;
+      List<int>? removedLibraries;
       if (json.containsKey('removedLibraries')) {
         removedLibraries = jsonDecoder.decodeList(
             jsonPath + '.removedLibraries',
@@ -5321,13 +4321,15 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
+    var changedLibraries = this.changedLibraries;
     if (changedLibraries != null) {
       result['changedLibraries'] = changedLibraries
           .map((AvailableSuggestionSet value) => value.toJson())
           .toList();
     }
+    var removedLibraries = this.removedLibraries;
     if (removedLibraries != null) {
       result['removedLibraries'] = removedLibraries;
     }
@@ -5370,35 +4372,16 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class CompletionExistingImportsParams implements HasToJson {
-  String _file;
-
-  ExistingImports _imports;
-
   /// The defining file of the library.
-  String get file => _file;
-
-  /// The defining file of the library.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// The existing imports in the library.
-  ExistingImports get imports => _imports;
+  ExistingImports imports;
 
-  /// The existing imports in the library.
-  set imports(ExistingImports value) {
-    assert(value != null);
-    _imports = value;
-  }
-
-  CompletionExistingImportsParams(String file, ExistingImports imports) {
-    this.file = file;
-    this.imports = imports;
-  }
+  CompletionExistingImportsParams(this.file, this.imports);
 
   factory CompletionExistingImportsParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -5428,8 +4411,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     result['imports'] = imports.toJson();
     return result;
@@ -5470,64 +4453,25 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class CompletionGetSuggestionDetailsParams implements RequestParams {
-  String _file;
-
-  int _id;
-
-  String _label;
-
-  int _offset;
-
   /// The path of the file into which this completion is being inserted.
-  String get file => _file;
-
-  /// The path of the file into which this completion is being inserted.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// The identifier of the AvailableSuggestionSet containing the selected
   /// label.
-  int get id => _id;
-
-  /// The identifier of the AvailableSuggestionSet containing the selected
-  /// label.
-  set id(int value) {
-    assert(value != null);
-    _id = value;
-  }
+  int id;
 
   /// The label from the AvailableSuggestionSet with the `id` for which
   /// insertion information is requested.
-  String get label => _label;
-
-  /// The label from the AvailableSuggestionSet with the `id` for which
-  /// insertion information is requested.
-  set label(String value) {
-    assert(value != null);
-    _label = value;
-  }
+  String label;
 
   /// The offset in the file where the completion will be inserted.
-  int get offset => _offset;
-
-  /// The offset in the file where the completion will be inserted.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
+  int offset;
 
   CompletionGetSuggestionDetailsParams(
-      String file, int id, String label, int offset) {
-    this.file = file;
-    this.id = id;
-    this.label = label;
-    this.offset = offset;
-  }
+      this.file, this.id, this.label, this.offset);
 
   factory CompletionGetSuggestionDetailsParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -5567,8 +4511,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     result['id'] = id;
     result['label'] = label;
@@ -5615,39 +4559,18 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class CompletionGetSuggestionDetailsResult implements ResponseResult {
-  String _completion;
-
-  SourceChange _change;
-
   /// The full text to insert, including any optional import prefix.
-  String get completion => _completion;
-
-  /// The full text to insert, including any optional import prefix.
-  set completion(String value) {
-    assert(value != null);
-    _completion = value;
-  }
+  String completion;
 
   /// A change for the client to apply in case the library containing the
   /// accepted completion suggestion needs to be imported. The field will be
   /// omitted if there are no additional changes that need to be made.
-  SourceChange get change => _change;
+  SourceChange? change;
 
-  /// A change for the client to apply in case the library containing the
-  /// accepted completion suggestion needs to be imported. The field will be
-  /// omitted if there are no additional changes that need to be made.
-  set change(SourceChange value) {
-    _change = value;
-  }
-
-  CompletionGetSuggestionDetailsResult(String completion,
-      {SourceChange change}) {
-    this.completion = completion;
-    this.change = change;
-  }
+  CompletionGetSuggestionDetailsResult(this.completion, {this.change});
 
   factory CompletionGetSuggestionDetailsResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String completion;
@@ -5657,7 +4580,7 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'completion');
       }
-      SourceChange change;
+      SourceChange? change;
       if (json.containsKey('change')) {
         change = SourceChange.fromJson(
             jsonDecoder, jsonPath + '.change', json['change']);
@@ -5677,9 +4600,10 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['completion'] = completion;
+    var change = this.change;
     if (change != null) {
       result['change'] = change.toJson();
     }
@@ -5720,35 +4644,16 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class CompletionGetSuggestionsParams implements RequestParams {
-  String _file;
-
-  int _offset;
-
   /// The file containing the point at which suggestions are to be made.
-  String get file => _file;
-
-  /// The file containing the point at which suggestions are to be made.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// The offset within the file at which suggestions are to be made.
-  int get offset => _offset;
+  int offset;
 
-  /// The offset within the file at which suggestions are to be made.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
-
-  CompletionGetSuggestionsParams(String file, int offset) {
-    this.file = file;
-    this.offset = offset;
-  }
+  CompletionGetSuggestionsParams(this.file, this.offset);
 
   factory CompletionGetSuggestionsParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -5776,8 +4681,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     result['offset'] = offset;
     return result;
@@ -5816,23 +4721,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class CompletionGetSuggestionsResult implements ResponseResult {
-  String _id;
-
   /// The identifier used to associate results with this completion request.
-  String get id => _id;
+  String id;
 
-  /// The identifier used to associate results with this completion request.
-  set id(String value) {
-    assert(value != null);
-    _id = value;
-  }
-
-  CompletionGetSuggestionsResult(String id) {
-    this.id = id;
-  }
+  CompletionGetSuggestionsResult(this.id);
 
   factory CompletionGetSuggestionsResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String id;
@@ -5856,8 +4751,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['id'] = id;
     return result;
   }
@@ -5894,29 +4789,16 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class CompletionRegisterLibraryPathsParams implements RequestParams {
-  List<LibraryPathSet> _paths;
-
   /// A list of objects each containing a path and the additional libraries
   /// from which the client is interested in receiving completion suggestions.
   /// If one configured path is beneath another, the descendent will override
   /// the ancestors' configured libraries of interest.
-  List<LibraryPathSet> get paths => _paths;
+  List<LibraryPathSet> paths;
 
-  /// A list of objects each containing a path and the additional libraries
-  /// from which the client is interested in receiving completion suggestions.
-  /// If one configured path is beneath another, the descendent will override
-  /// the ancestors' configured libraries of interest.
-  set paths(List<LibraryPathSet> value) {
-    assert(value != null);
-    _paths = value;
-  }
-
-  CompletionRegisterLibraryPathsParams(List<LibraryPathSet> paths) {
-    this.paths = paths;
-  }
+  CompletionRegisterLibraryPathsParams(this.paths);
 
   factory CompletionRegisterLibraryPathsParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       List<LibraryPathSet> paths;
@@ -5924,7 +4806,7 @@
         paths = jsonDecoder.decodeList(
             jsonPath + '.paths',
             json['paths'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 LibraryPathSet.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'paths');
@@ -5942,8 +4824,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['paths'] =
         paths.map((LibraryPathSet value) => value.toJson()).toList();
     return result;
@@ -5979,7 +4861,7 @@
 /// Clients may not extend, implement or mix-in this class.
 class CompletionRegisterLibraryPathsResult implements ResponseResult {
   @override
-  Map<String, dynamic> toJson() => <String, dynamic>{};
+  Map<String, Object> toJson() => <String, Object>{};
 
   @override
   Response toResponse(String id) {
@@ -6016,131 +4898,48 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class CompletionResultsParams implements HasToJson {
-  String _id;
-
-  int _replacementOffset;
-
-  int _replacementLength;
-
-  List<CompletionSuggestion> _results;
-
-  bool _isLast;
-
-  String _libraryFile;
-
-  List<IncludedSuggestionSet> _includedSuggestionSets;
-
-  List<ElementKind> _includedElementKinds;
-
-  List<IncludedSuggestionRelevanceTag> _includedSuggestionRelevanceTags;
-
   /// The id associated with the completion.
-  String get id => _id;
-
-  /// The id associated with the completion.
-  set id(String value) {
-    assert(value != null);
-    _id = value;
-  }
+  String id;
 
   /// 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 offset. In
   /// particular, the replacementOffset will be the offset of the beginning of
   /// said identifier.
-  int get replacementOffset => _replacementOffset;
-
-  /// 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 offset. In
-  /// particular, the replacementOffset will be the offset of the beginning of
-  /// said identifier.
-  set replacementOffset(int value) {
-    assert(value != null);
-    _replacementOffset = value;
-  }
+  int replacementOffset;
 
   /// The length of the text to be replaced if the remainder of the identifier
   /// containing the cursor is to be replaced when the suggestion is applied
   /// (that is, the number of characters in the existing identifier).
-  int get replacementLength => _replacementLength;
-
-  /// The length of the text to be replaced if the remainder of the identifier
-  /// containing the cursor is to be replaced when the suggestion is applied
-  /// (that is, the number of characters in the existing identifier).
-  set replacementLength(int value) {
-    assert(value != null);
-    _replacementLength = value;
-  }
+  int replacementLength;
 
   /// The completion suggestions being reported. The notification contains all
   /// possible completions at the requested cursor position, even those that do
   /// not match the characters the user has already typed. This allows the
   /// client to respond to further keystrokes from the user without having to
   /// make additional requests.
-  List<CompletionSuggestion> get results => _results;
-
-  /// The completion suggestions being reported. The notification contains all
-  /// possible completions at the requested cursor position, even those that do
-  /// not match the characters the user has already typed. This allows the
-  /// client to respond to further keystrokes from the user without having to
-  /// make additional requests.
-  set results(List<CompletionSuggestion> value) {
-    assert(value != null);
-    _results = value;
-  }
+  List<CompletionSuggestion> results;
 
   /// True if this is that last set of results that will be returned for the
   /// indicated completion.
-  bool get isLast => _isLast;
-
-  /// True if this is that last set of results that will be returned for the
-  /// indicated completion.
-  set isLast(bool value) {
-    assert(value != null);
-    _isLast = value;
-  }
+  bool isLast;
 
   /// The library file that contains the file where completion was requested.
   /// The client might use it for example together with the existingImports
   /// notification to filter out available suggestions. If there were changes
   /// to existing imports in the library, the corresponding existingImports
   /// notification will be sent before the completion notification.
-  String get libraryFile => _libraryFile;
-
-  /// The library file that contains the file where completion was requested.
-  /// The client might use it for example together with the existingImports
-  /// notification to filter out available suggestions. If there were changes
-  /// to existing imports in the library, the corresponding existingImports
-  /// notification will be sent before the completion notification.
-  set libraryFile(String value) {
-    _libraryFile = value;
-  }
+  String? libraryFile;
 
   /// References to AvailableSuggestionSet objects previously sent to the
   /// client. The client can include applicable names from the referenced
   /// library in code completion suggestions.
-  List<IncludedSuggestionSet> get includedSuggestionSets =>
-      _includedSuggestionSets;
-
-  /// References to AvailableSuggestionSet objects previously sent to the
-  /// client. The client can include applicable names from the referenced
-  /// library in code completion suggestions.
-  set includedSuggestionSets(List<IncludedSuggestionSet> value) {
-    _includedSuggestionSets = value;
-  }
+  List<IncludedSuggestionSet>? includedSuggestionSets;
 
   /// The client is expected to check this list against the ElementKind sent in
   /// IncludedSuggestionSet to decide whether or not these symbols should
   /// should be presented to the user.
-  List<ElementKind> get includedElementKinds => _includedElementKinds;
-
-  /// The client is expected to check this list against the ElementKind sent in
-  /// IncludedSuggestionSet to decide whether or not these symbols should
-  /// should be presented to the user.
-  set includedElementKinds(List<ElementKind> value) {
-    _includedElementKinds = value;
-  }
+  List<ElementKind>? includedElementKinds;
 
   /// The client is expected to check this list against the values of the field
   /// relevanceTags of AvailableSuggestion to decide if the suggestion should
@@ -6150,41 +4949,17 @@
   ///
   /// If an AvailableSuggestion has relevance tags that match more than one
   /// IncludedSuggestionRelevanceTag, the maximum relevance boost is used.
-  List<IncludedSuggestionRelevanceTag> get includedSuggestionRelevanceTags =>
-      _includedSuggestionRelevanceTags;
+  List<IncludedSuggestionRelevanceTag>? includedSuggestionRelevanceTags;
 
-  /// The client is expected to check this list against the values of the field
-  /// relevanceTags of AvailableSuggestion to decide if the suggestion should
-  /// be given a different relevance than the IncludedSuggestionSet that
-  /// contains it. This might be used for example to give higher relevance to
-  /// suggestions of matching types.
-  ///
-  /// If an AvailableSuggestion has relevance tags that match more than one
-  /// IncludedSuggestionRelevanceTag, the maximum relevance boost is used.
-  set includedSuggestionRelevanceTags(
-      List<IncludedSuggestionRelevanceTag> value) {
-    _includedSuggestionRelevanceTags = value;
-  }
-
-  CompletionResultsParams(String id, int replacementOffset,
-      int replacementLength, List<CompletionSuggestion> results, bool isLast,
-      {String libraryFile,
-      List<IncludedSuggestionSet> includedSuggestionSets,
-      List<ElementKind> includedElementKinds,
-      List<IncludedSuggestionRelevanceTag> includedSuggestionRelevanceTags}) {
-    this.id = id;
-    this.replacementOffset = replacementOffset;
-    this.replacementLength = replacementLength;
-    this.results = results;
-    this.isLast = isLast;
-    this.libraryFile = libraryFile;
-    this.includedSuggestionSets = includedSuggestionSets;
-    this.includedElementKinds = includedElementKinds;
-    this.includedSuggestionRelevanceTags = includedSuggestionRelevanceTags;
-  }
+  CompletionResultsParams(this.id, this.replacementOffset,
+      this.replacementLength, this.results, this.isLast,
+      {this.libraryFile,
+      this.includedSuggestionSets,
+      this.includedElementKinds,
+      this.includedSuggestionRelevanceTags});
 
   factory CompletionResultsParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String id;
@@ -6212,7 +4987,7 @@
         results = jsonDecoder.decodeList(
             jsonPath + '.results',
             json['results'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 CompletionSuggestion.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'results');
@@ -6223,33 +4998,33 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'isLast');
       }
-      String libraryFile;
+      String? libraryFile;
       if (json.containsKey('libraryFile')) {
         libraryFile = jsonDecoder.decodeString(
             jsonPath + '.libraryFile', json['libraryFile']);
       }
-      List<IncludedSuggestionSet> includedSuggestionSets;
+      List<IncludedSuggestionSet>? includedSuggestionSets;
       if (json.containsKey('includedSuggestionSets')) {
         includedSuggestionSets = jsonDecoder.decodeList(
             jsonPath + '.includedSuggestionSets',
             json['includedSuggestionSets'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 IncludedSuggestionSet.fromJson(jsonDecoder, jsonPath, json));
       }
-      List<ElementKind> includedElementKinds;
+      List<ElementKind>? includedElementKinds;
       if (json.containsKey('includedElementKinds')) {
         includedElementKinds = jsonDecoder.decodeList(
             jsonPath + '.includedElementKinds',
             json['includedElementKinds'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 ElementKind.fromJson(jsonDecoder, jsonPath, json));
       }
-      List<IncludedSuggestionRelevanceTag> includedSuggestionRelevanceTags;
+      List<IncludedSuggestionRelevanceTag>? includedSuggestionRelevanceTags;
       if (json.containsKey('includedSuggestionRelevanceTags')) {
         includedSuggestionRelevanceTags = jsonDecoder.decodeList(
             jsonPath + '.includedSuggestionRelevanceTags',
             json['includedSuggestionRelevanceTags'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 IncludedSuggestionRelevanceTag.fromJson(
                     jsonDecoder, jsonPath, json));
       }
@@ -6270,27 +5045,31 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['id'] = id;
     result['replacementOffset'] = replacementOffset;
     result['replacementLength'] = replacementLength;
     result['results'] =
         results.map((CompletionSuggestion value) => value.toJson()).toList();
     result['isLast'] = isLast;
+    var libraryFile = this.libraryFile;
     if (libraryFile != null) {
       result['libraryFile'] = libraryFile;
     }
+    var includedSuggestionSets = this.includedSuggestionSets;
     if (includedSuggestionSets != null) {
       result['includedSuggestionSets'] = includedSuggestionSets
           .map((IncludedSuggestionSet value) => value.toJson())
           .toList();
     }
+    var includedElementKinds = this.includedElementKinds;
     if (includedElementKinds != null) {
       result['includedElementKinds'] = includedElementKinds
           .map((ElementKind value) => value.toJson())
           .toList();
     }
+    var includedSuggestionRelevanceTags = this.includedSuggestionRelevanceTags;
     if (includedSuggestionRelevanceTags != null) {
       result['includedSuggestionRelevanceTags'] =
           includedSuggestionRelevanceTags
@@ -6385,7 +5164,7 @@
   }
 
   factory CompletionService.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     if (json is String) {
       try {
         return CompletionService(json);
@@ -6410,23 +5189,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class CompletionSetSubscriptionsParams implements RequestParams {
-  List<CompletionService> _subscriptions;
-
   /// A list of the services being subscribed to.
-  List<CompletionService> get subscriptions => _subscriptions;
+  List<CompletionService> subscriptions;
 
-  /// A list of the services being subscribed to.
-  set subscriptions(List<CompletionService> value) {
-    assert(value != null);
-    _subscriptions = value;
-  }
-
-  CompletionSetSubscriptionsParams(List<CompletionService> subscriptions) {
-    this.subscriptions = subscriptions;
-  }
+  CompletionSetSubscriptionsParams(this.subscriptions);
 
   factory CompletionSetSubscriptionsParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       List<CompletionService> subscriptions;
@@ -6434,7 +5203,7 @@
         subscriptions = jsonDecoder.decodeList(
             jsonPath + '.subscriptions',
             json['subscriptions'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 CompletionService.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'subscriptions');
@@ -6452,8 +5221,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['subscriptions'] =
         subscriptions.map((CompletionService value) => value.toJson()).toList();
     return result;
@@ -6489,7 +5258,7 @@
 /// Clients may not extend, implement or mix-in this class.
 class CompletionSetSubscriptionsResult implements ResponseResult {
   @override
-  Map<String, dynamic> toJson() => <String, dynamic>{};
+  Map<String, Object> toJson() => <String, Object>{};
 
   @override
   Response toResponse(String id) {
@@ -6522,72 +5291,26 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class ContextData implements HasToJson {
-  String _name;
-
-  int _explicitFileCount;
-
-  int _implicitFileCount;
-
-  int _workItemQueueLength;
-
-  List<String> _cacheEntryExceptions;
-
   /// The name of the context.
-  String get name => _name;
-
-  /// The name of the context.
-  set name(String value) {
-    assert(value != null);
-    _name = value;
-  }
+  String name;
 
   /// Explicitly analyzed files.
-  int get explicitFileCount => _explicitFileCount;
-
-  /// Explicitly analyzed files.
-  set explicitFileCount(int value) {
-    assert(value != null);
-    _explicitFileCount = value;
-  }
+  int explicitFileCount;
 
   /// Implicitly analyzed files.
-  int get implicitFileCount => _implicitFileCount;
-
-  /// Implicitly analyzed files.
-  set implicitFileCount(int value) {
-    assert(value != null);
-    _implicitFileCount = value;
-  }
+  int implicitFileCount;
 
   /// The number of work items in the queue.
-  int get workItemQueueLength => _workItemQueueLength;
-
-  /// The number of work items in the queue.
-  set workItemQueueLength(int value) {
-    assert(value != null);
-    _workItemQueueLength = value;
-  }
+  int workItemQueueLength;
 
   /// Exceptions associated with cache entries.
-  List<String> get cacheEntryExceptions => _cacheEntryExceptions;
+  List<String> cacheEntryExceptions;
 
-  /// Exceptions associated with cache entries.
-  set cacheEntryExceptions(List<String> value) {
-    assert(value != null);
-    _cacheEntryExceptions = value;
-  }
-
-  ContextData(String name, int explicitFileCount, int implicitFileCount,
-      int workItemQueueLength, List<String> cacheEntryExceptions) {
-    this.name = name;
-    this.explicitFileCount = explicitFileCount;
-    this.implicitFileCount = implicitFileCount;
-    this.workItemQueueLength = workItemQueueLength;
-    this.cacheEntryExceptions = cacheEntryExceptions;
-  }
+  ContextData(this.name, this.explicitFileCount, this.implicitFileCount,
+      this.workItemQueueLength, this.cacheEntryExceptions);
 
   factory ContextData.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String name;
@@ -6634,8 +5357,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['name'] = name;
     result['explicitFileCount'] = explicitFileCount;
     result['implicitFileCount'] = implicitFileCount;
@@ -6757,34 +5480,16 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class DartFix implements HasToJson {
-  String _name;
-
-  String _description;
-
   /// The name of the fix.
-  String get name => _name;
-
-  /// The name of the fix.
-  set name(String value) {
-    assert(value != null);
-    _name = value;
-  }
+  String name;
 
   /// A human readable description of the fix.
-  String get description => _description;
+  String? description;
 
-  /// A human readable description of the fix.
-  set description(String value) {
-    _description = value;
-  }
-
-  DartFix(String name, {String description}) {
-    this.name = name;
-    this.description = description;
-  }
+  DartFix(this.name, {this.description});
 
   factory DartFix.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String name;
@@ -6793,7 +5498,7 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'name');
       }
-      String description;
+      String? description;
       if (json.containsKey('description')) {
         description = jsonDecoder.decodeString(
             jsonPath + '.description', json['description']);
@@ -6805,9 +5510,10 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['name'] = name;
+    var description = this.description;
     if (description != null) {
       result['description'] = description;
     }
@@ -6843,34 +5549,16 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class DartFixSuggestion implements HasToJson {
-  String _description;
-
-  Location _location;
-
   /// A human readable description of the suggested change.
-  String get description => _description;
-
-  /// A human readable description of the suggested change.
-  set description(String value) {
-    assert(value != null);
-    _description = value;
-  }
+  String description;
 
   /// The location of the suggested change.
-  Location get location => _location;
+  Location? location;
 
-  /// The location of the suggested change.
-  set location(Location value) {
-    _location = value;
-  }
-
-  DartFixSuggestion(String description, {Location location}) {
-    this.description = description;
-    this.location = location;
-  }
+  DartFixSuggestion(this.description, {this.location});
 
   factory DartFixSuggestion.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String description;
@@ -6880,7 +5568,7 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'description');
       }
-      Location location;
+      Location? location;
       if (json.containsKey('location')) {
         location = Location.fromJson(
             jsonDecoder, jsonPath + '.location', json['location']);
@@ -6892,9 +5580,10 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['description'] = description;
+    var location = this.location;
     if (location != null) {
       result['location'] = location.toJson();
     }
@@ -6926,7 +5615,7 @@
 /// Clients may not extend, implement or mix-in this class.
 class DiagnosticGetDiagnosticsParams implements RequestParams {
   @override
-  Map<String, dynamic> toJson() => <String, dynamic>{};
+  Map<String, Object> toJson() => <String, Object>{};
 
   @override
   Request toRequest(String id) {
@@ -6955,23 +5644,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class DiagnosticGetDiagnosticsResult implements ResponseResult {
-  List<ContextData> _contexts;
-
   /// The list of analysis contexts.
-  List<ContextData> get contexts => _contexts;
+  List<ContextData> contexts;
 
-  /// The list of analysis contexts.
-  set contexts(List<ContextData> value) {
-    assert(value != null);
-    _contexts = value;
-  }
-
-  DiagnosticGetDiagnosticsResult(List<ContextData> contexts) {
-    this.contexts = contexts;
-  }
+  DiagnosticGetDiagnosticsResult(this.contexts);
 
   factory DiagnosticGetDiagnosticsResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       List<ContextData> contexts;
@@ -6979,7 +5658,7 @@
         contexts = jsonDecoder.decodeList(
             jsonPath + '.contexts',
             json['contexts'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 ContextData.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'contexts');
@@ -6999,8 +5678,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['contexts'] =
         contexts.map((ContextData value) => value.toJson()).toList();
     return result;
@@ -7036,7 +5715,7 @@
 /// Clients may not extend, implement or mix-in this class.
 class DiagnosticGetServerPortParams implements RequestParams {
   @override
-  Map<String, dynamic> toJson() => <String, dynamic>{};
+  Map<String, Object> toJson() => <String, Object>{};
 
   @override
   Request toRequest(String id) {
@@ -7065,23 +5744,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class DiagnosticGetServerPortResult implements ResponseResult {
-  int _port;
-
   /// The diagnostic server port.
-  int get port => _port;
+  int port;
 
-  /// The diagnostic server port.
-  set port(int value) {
-    assert(value != null);
-    _port = value;
-  }
-
-  DiagnosticGetServerPortResult(int port) {
-    this.port = port;
-  }
+  DiagnosticGetServerPortResult(this.port);
 
   factory DiagnosticGetServerPortResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       int port;
@@ -7105,8 +5774,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['port'] = port;
     return result;
   }
@@ -7144,10 +5813,6 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class EditBulkFixesParams implements RequestParams {
-  List<String> _included;
-
-  bool _inTestMode;
-
   /// A list of the files and directories for which edits should be suggested.
   ///
   /// If a request is made with a path that is invalid, e.g. is not absolute
@@ -7156,20 +5821,7 @@
   /// is not currently subject to analysis (e.g. because it is not associated
   /// with any analysis root specified to analysis.setAnalysisRoots), an error
   /// of type FILE_NOT_ANALYZED will be generated.
-  List<String> get included => _included;
-
-  /// A list of the files and directories for which edits should be suggested.
-  ///
-  /// If a request is made with a path that is invalid, e.g. is not absolute
-  /// and normalized, an error of type INVALID_FILE_PATH_FORMAT will be
-  /// generated. If a request is made for a file which does not exist, or which
-  /// is not currently subject to analysis (e.g. because it is not associated
-  /// with any analysis root specified to analysis.setAnalysisRoots), an error
-  /// of type FILE_NOT_ANALYZED will be generated.
-  set included(List<String> value) {
-    assert(value != null);
-    _included = value;
-  }
+  List<String> included;
 
   /// A flag indicating whether the bulk fixes are being run in test mode. The
   /// only difference is that in test mode the fix processor will look for a
@@ -7177,25 +5829,12 @@
   /// compute the fixes when data-driven fixes are being considered.
   ///
   /// If this field is omitted the flag defaults to false.
-  bool get inTestMode => _inTestMode;
+  bool? inTestMode;
 
-  /// A flag indicating whether the bulk fixes are being run in test mode. The
-  /// only difference is that in test mode the fix processor will look for a
-  /// configuration file that can modify the content of the data file used to
-  /// compute the fixes when data-driven fixes are being considered.
-  ///
-  /// If this field is omitted the flag defaults to false.
-  set inTestMode(bool value) {
-    _inTestMode = value;
-  }
-
-  EditBulkFixesParams(List<String> included, {bool inTestMode}) {
-    this.included = included;
-    this.inTestMode = inTestMode;
-  }
+  EditBulkFixesParams(this.included, {this.inTestMode});
 
   factory EditBulkFixesParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       List<String> included;
@@ -7205,7 +5844,7 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'included');
       }
-      bool inTestMode;
+      bool? inTestMode;
       if (json.containsKey('inTestMode')) {
         inTestMode = jsonDecoder.decodeBool(
             jsonPath + '.inTestMode', json['inTestMode']);
@@ -7222,9 +5861,10 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['included'] = included;
+    var inTestMode = this.inTestMode;
     if (inTestMode != null) {
       result['inTestMode'] = inTestMode;
     }
@@ -7267,35 +5907,16 @@
 ///
 /// 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;
-
-  /// A list of source edits to apply the recommended changes.
-  set edits(List<SourceFileEdit> value) {
-    assert(value != null);
-    _edits = value;
-  }
+  List<SourceFileEdit> edits;
 
   /// Details that summarize the fixes associated with the recommended changes.
-  List<BulkFix> get details => _details;
+  List<BulkFix> 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;
-  }
+  EditBulkFixesResult(this.edits, this.details);
 
   factory EditBulkFixesResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       List<SourceFileEdit> edits;
@@ -7303,7 +5924,7 @@
         edits = jsonDecoder.decodeList(
             jsonPath + '.edits',
             json['edits'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 SourceFileEdit.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'edits');
@@ -7313,7 +5934,7 @@
         details = jsonDecoder.decodeList(
             jsonPath + '.details',
             json['details'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 BulkFix.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'details');
@@ -7332,8 +5953,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['edits'] =
         edits.map((SourceFileEdit value) => value.toJson()).toList();
     result['details'] = details.map((BulkFix value) => value.toJson()).toList();
@@ -7380,18 +6001,6 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class EditDartfixParams implements RequestParams {
-  List<String> _included;
-
-  List<String> _includedFixes;
-
-  bool _includePedanticFixes;
-
-  List<String> _excludedFixes;
-
-  int _port;
-
-  String _outputDir;
-
   /// A list of the files and directories for which edits should be suggested.
   ///
   /// If a request is made with a path that is invalid, e.g. is not absolute
@@ -7400,89 +6009,38 @@
   /// is not currently subject to analysis (e.g. because it is not associated
   /// with any analysis root specified to analysis.setAnalysisRoots), an error
   /// of type FILE_NOT_ANALYZED will be generated.
-  List<String> get included => _included;
-
-  /// A list of the files and directories for which edits should be suggested.
-  ///
-  /// If a request is made with a path that is invalid, e.g. is not absolute
-  /// and normalized, an error of type INVALID_FILE_PATH_FORMAT will be
-  /// generated. If a request is made for a file which does not exist, or which
-  /// is not currently subject to analysis (e.g. because it is not associated
-  /// with any analysis root specified to analysis.setAnalysisRoots), an error
-  /// of type FILE_NOT_ANALYZED will be generated.
-  set included(List<String> value) {
-    assert(value != null);
-    _included = value;
-  }
+  List<String> included;
 
   /// A list of names indicating which fixes should be applied.
   ///
   /// If a name is specified that does not match the name of a known fix, an
   /// error of type UNKNOWN_FIX will be generated.
-  List<String> get includedFixes => _includedFixes;
-
-  /// A list of names indicating which fixes should be applied.
-  ///
-  /// If a name is specified that does not match the name of a known fix, an
-  /// error of type UNKNOWN_FIX will be generated.
-  set includedFixes(List<String> value) {
-    _includedFixes = value;
-  }
+  List<String>? includedFixes;
 
   /// A flag indicating whether "pedantic" fixes should be applied.
-  bool get includePedanticFixes => _includePedanticFixes;
-
-  /// A flag indicating whether "pedantic" fixes should be applied.
-  set includePedanticFixes(bool value) {
-    _includePedanticFixes = value;
-  }
+  bool? includePedanticFixes;
 
   /// A list of names indicating which fixes should not be applied.
   ///
   /// If a name is specified that does not match the name of a known fix, an
   /// error of type UNKNOWN_FIX will be generated.
-  List<String> get excludedFixes => _excludedFixes;
-
-  /// A list of names indicating which fixes should not be applied.
-  ///
-  /// If a name is specified that does not match the name of a known fix, an
-  /// error of type UNKNOWN_FIX will be generated.
-  set excludedFixes(List<String> value) {
-    _excludedFixes = value;
-  }
+  List<String>? excludedFixes;
 
   /// Deprecated: This field is now ignored by server.
-  int get port => _port;
+  int? port;
 
   /// Deprecated: This field is now ignored by server.
-  set port(int value) {
-    _port = value;
-  }
+  String? outputDir;
 
-  /// Deprecated: This field is now ignored by server.
-  String get outputDir => _outputDir;
-
-  /// Deprecated: This field is now ignored by server.
-  set outputDir(String value) {
-    _outputDir = value;
-  }
-
-  EditDartfixParams(List<String> included,
-      {List<String> includedFixes,
-      bool includePedanticFixes,
-      List<String> excludedFixes,
-      int port,
-      String outputDir}) {
-    this.included = included;
-    this.includedFixes = includedFixes;
-    this.includePedanticFixes = includePedanticFixes;
-    this.excludedFixes = excludedFixes;
-    this.port = port;
-    this.outputDir = outputDir;
-  }
+  EditDartfixParams(this.included,
+      {this.includedFixes,
+      this.includePedanticFixes,
+      this.excludedFixes,
+      this.port,
+      this.outputDir});
 
   factory EditDartfixParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       List<String> included;
@@ -7492,26 +6050,26 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'included');
       }
-      List<String> includedFixes;
+      List<String>? includedFixes;
       if (json.containsKey('includedFixes')) {
         includedFixes = jsonDecoder.decodeList(jsonPath + '.includedFixes',
             json['includedFixes'], jsonDecoder.decodeString);
       }
-      bool includePedanticFixes;
+      bool? includePedanticFixes;
       if (json.containsKey('includePedanticFixes')) {
         includePedanticFixes = jsonDecoder.decodeBool(
             jsonPath + '.includePedanticFixes', json['includePedanticFixes']);
       }
-      List<String> excludedFixes;
+      List<String>? excludedFixes;
       if (json.containsKey('excludedFixes')) {
         excludedFixes = jsonDecoder.decodeList(jsonPath + '.excludedFixes',
             json['excludedFixes'], jsonDecoder.decodeString);
       }
-      int port;
+      int? port;
       if (json.containsKey('port')) {
         port = jsonDecoder.decodeInt(jsonPath + '.port', json['port']);
       }
-      String outputDir;
+      String? outputDir;
       if (json.containsKey('outputDir')) {
         outputDir = jsonDecoder.decodeString(
             jsonPath + '.outputDir', json['outputDir']);
@@ -7533,21 +6091,26 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['included'] = included;
+    var includedFixes = this.includedFixes;
     if (includedFixes != null) {
       result['includedFixes'] = includedFixes;
     }
+    var includePedanticFixes = this.includePedanticFixes;
     if (includePedanticFixes != null) {
       result['includePedanticFixes'] = includePedanticFixes;
     }
+    var excludedFixes = this.excludedFixes;
     if (excludedFixes != null) {
       result['excludedFixes'] = excludedFixes;
     }
+    var port = this.port;
     if (port != null) {
       result['port'] = port;
     }
+    var outputDir = this.outputDir;
     if (outputDir != null) {
       result['outputDir'] = outputDir;
     }
@@ -7605,117 +6168,42 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class EditDartfixResult implements ResponseResult {
-  List<DartFixSuggestion> _suggestions;
-
-  List<DartFixSuggestion> _otherSuggestions;
-
-  bool _hasErrors;
-
-  List<SourceFileEdit> _edits;
-
-  List<String> _details;
-
-  int _port;
-
-  List<String> _urls;
-
   /// A list of recommended changes that can be automatically made by applying
   /// the 'edits' included in this response.
-  List<DartFixSuggestion> get suggestions => _suggestions;
-
-  /// A list of recommended changes that can be automatically made by applying
-  /// the 'edits' included in this response.
-  set suggestions(List<DartFixSuggestion> value) {
-    assert(value != null);
-    _suggestions = value;
-  }
+  List<DartFixSuggestion> suggestions;
 
   /// A list of recommended changes that could not be automatically made.
-  List<DartFixSuggestion> get otherSuggestions => _otherSuggestions;
-
-  /// A list of recommended changes that could not be automatically made.
-  set otherSuggestions(List<DartFixSuggestion> value) {
-    assert(value != null);
-    _otherSuggestions = value;
-  }
+  List<DartFixSuggestion> otherSuggestions;
 
   /// True if the analyzed source contains errors that might impact the
   /// correctness of the recommended changes that can be automatically applied.
-  bool get hasErrors => _hasErrors;
-
-  /// True if the analyzed source contains errors that might impact the
-  /// correctness of the recommended changes that can be automatically applied.
-  set hasErrors(bool value) {
-    assert(value != null);
-    _hasErrors = value;
-  }
+  bool hasErrors;
 
   /// A list of source edits to apply the recommended changes.
-  List<SourceFileEdit> get edits => _edits;
-
-  /// A list of source edits to apply the recommended changes.
-  set edits(List<SourceFileEdit> value) {
-    assert(value != null);
-    _edits = value;
-  }
+  List<SourceFileEdit> edits;
 
   /// Messages that should be displayed to the user that describe details of
   /// the fix generation. For example, the messages might (a) point out details
   /// that users might want to explore before committing the changes or (b)
   /// describe exceptions that were thrown but that did not stop the fixes from
   /// being produced. The list will be omitted if it is empty.
-  List<String> get details => _details;
-
-  /// Messages that should be displayed to the user that describe details of
-  /// the fix generation. For example, the messages might (a) point out details
-  /// that users might want to explore before committing the changes or (b)
-  /// describe exceptions that were thrown but that did not stop the fixes from
-  /// being produced. The list will be omitted if it is empty.
-  set details(List<String> value) {
-    _details = value;
-  }
+  List<String>? details;
 
   /// The port on which the preview tool will respond to GET requests. The
   /// field is omitted if a preview was not requested.
-  int get port => _port;
-
-  /// The port on which the preview tool will respond to GET requests. The
-  /// field is omitted if a preview was not requested.
-  set port(int value) {
-    _port = value;
-  }
+  int? port;
 
   /// The URLs that users can visit in a browser to see a preview of the
   /// proposed changes. There is one URL for each of the included file paths.
   /// The field is omitted if a preview was not requested.
-  List<String> get urls => _urls;
-
-  /// The URLs that users can visit in a browser to see a preview of the
-  /// proposed changes. There is one URL for each of the included file paths.
-  /// The field is omitted if a preview was not requested.
-  set urls(List<String> value) {
-    _urls = value;
-  }
+  List<String>? urls;
 
   EditDartfixResult(
-      List<DartFixSuggestion> suggestions,
-      List<DartFixSuggestion> otherSuggestions,
-      bool hasErrors,
-      List<SourceFileEdit> edits,
-      {List<String> details,
-      int port,
-      List<String> urls}) {
-    this.suggestions = suggestions;
-    this.otherSuggestions = otherSuggestions;
-    this.hasErrors = hasErrors;
-    this.edits = edits;
-    this.details = details;
-    this.port = port;
-    this.urls = urls;
-  }
+      this.suggestions, this.otherSuggestions, this.hasErrors, this.edits,
+      {this.details, this.port, this.urls});
 
   factory EditDartfixResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       List<DartFixSuggestion> suggestions;
@@ -7723,7 +6211,7 @@
         suggestions = jsonDecoder.decodeList(
             jsonPath + '.suggestions',
             json['suggestions'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 DartFixSuggestion.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'suggestions');
@@ -7733,7 +6221,7 @@
         otherSuggestions = jsonDecoder.decodeList(
             jsonPath + '.otherSuggestions',
             json['otherSuggestions'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 DartFixSuggestion.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'otherSuggestions');
@@ -7750,21 +6238,21 @@
         edits = jsonDecoder.decodeList(
             jsonPath + '.edits',
             json['edits'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 SourceFileEdit.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'edits');
       }
-      List<String> details;
+      List<String>? details;
       if (json.containsKey('details')) {
         details = jsonDecoder.decodeList(
             jsonPath + '.details', json['details'], jsonDecoder.decodeString);
       }
-      int port;
+      int? port;
       if (json.containsKey('port')) {
         port = jsonDecoder.decodeInt(jsonPath + '.port', json['port']);
       }
-      List<String> urls;
+      List<String>? urls;
       if (json.containsKey('urls')) {
         urls = jsonDecoder.decodeList(
             jsonPath + '.urls', json['urls'], jsonDecoder.decodeString);
@@ -7784,8 +6272,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['suggestions'] =
         suggestions.map((DartFixSuggestion value) => value.toJson()).toList();
     result['otherSuggestions'] = otherSuggestions
@@ -7794,12 +6282,15 @@
     result['hasErrors'] = hasErrors;
     result['edits'] =
         edits.map((SourceFileEdit value) => value.toJson()).toList();
+    var details = this.details;
     if (details != null) {
       result['details'] = details;
     }
+    var port = this.port;
     if (port != null) {
       result['port'] = port;
     }
+    var urls = this.urls;
     if (urls != null) {
       result['urls'] = urls;
     }
@@ -7856,59 +6347,23 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class EditFormatParams implements RequestParams {
-  String _file;
-
-  int _selectionOffset;
-
-  int _selectionLength;
-
-  int _lineLength;
-
   /// The file containing the code to be formatted.
-  String get file => _file;
-
-  /// The file containing the code to be formatted.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// The offset of the current selection in the file.
-  int get selectionOffset => _selectionOffset;
-
-  /// The offset of the current selection in the file.
-  set selectionOffset(int value) {
-    assert(value != null);
-    _selectionOffset = value;
-  }
+  int selectionOffset;
 
   /// The length of the current selection in the file.
-  int get selectionLength => _selectionLength;
-
-  /// The length of the current selection in the file.
-  set selectionLength(int value) {
-    assert(value != null);
-    _selectionLength = value;
-  }
+  int selectionLength;
 
   /// The line length to be used by the formatter.
-  int get lineLength => _lineLength;
+  int? lineLength;
 
-  /// The line length to be used by the formatter.
-  set lineLength(int value) {
-    _lineLength = value;
-  }
-
-  EditFormatParams(String file, int selectionOffset, int selectionLength,
-      {int lineLength}) {
-    this.file = file;
-    this.selectionOffset = selectionOffset;
-    this.selectionLength = selectionLength;
-    this.lineLength = lineLength;
-  }
+  EditFormatParams(this.file, this.selectionOffset, this.selectionLength,
+      {this.lineLength});
 
   factory EditFormatParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -7931,7 +6386,7 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'selectionLength');
       }
-      int lineLength;
+      int? lineLength;
       if (json.containsKey('lineLength')) {
         lineLength =
             jsonDecoder.decodeInt(jsonPath + '.lineLength', json['lineLength']);
@@ -7949,11 +6404,12 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     result['selectionOffset'] = selectionOffset;
     result['selectionLength'] = selectionLength;
+    var lineLength = this.lineLength;
     if (lineLength != null) {
       result['lineLength'] = lineLength;
     }
@@ -8000,50 +6456,20 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class EditFormatResult implements ResponseResult {
-  List<SourceEdit> _edits;
-
-  int _selectionOffset;
-
-  int _selectionLength;
-
   /// The edit(s) to be applied in order to format the code. The list will be
   /// empty if the code was already formatted (there are no changes).
-  List<SourceEdit> get edits => _edits;
-
-  /// The edit(s) to be applied in order to format the code. The list will be
-  /// empty if the code was already formatted (there are no changes).
-  set edits(List<SourceEdit> value) {
-    assert(value != null);
-    _edits = value;
-  }
+  List<SourceEdit> edits;
 
   /// The offset of the selection after formatting the code.
-  int get selectionOffset => _selectionOffset;
-
-  /// The offset of the selection after formatting the code.
-  set selectionOffset(int value) {
-    assert(value != null);
-    _selectionOffset = value;
-  }
+  int selectionOffset;
 
   /// The length of the selection after formatting the code.
-  int get selectionLength => _selectionLength;
+  int selectionLength;
 
-  /// The length of the selection after formatting the code.
-  set selectionLength(int value) {
-    assert(value != null);
-    _selectionLength = value;
-  }
-
-  EditFormatResult(
-      List<SourceEdit> edits, int selectionOffset, int selectionLength) {
-    this.edits = edits;
-    this.selectionOffset = selectionOffset;
-    this.selectionLength = selectionLength;
-  }
+  EditFormatResult(this.edits, this.selectionOffset, this.selectionLength);
 
   factory EditFormatResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       List<SourceEdit> edits;
@@ -8051,7 +6477,7 @@
         edits = jsonDecoder.decodeList(
             jsonPath + '.edits',
             json['edits'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 SourceEdit.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'edits');
@@ -8084,8 +6510,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['edits'] = edits.map((SourceEdit value) => value.toJson()).toList();
     result['selectionOffset'] = selectionOffset;
     result['selectionLength'] = selectionLength;
@@ -8131,47 +6557,19 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class EditGetAssistsParams implements RequestParams {
-  String _file;
-
-  int _offset;
-
-  int _length;
-
   /// The file containing the code for which assists are being requested.
-  String get file => _file;
-
-  /// The file containing the code for which assists are being requested.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// The offset of the code for which assists are being requested.
-  int get offset => _offset;
-
-  /// The offset of the code for which assists are being requested.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
+  int offset;
 
   /// The length of the code for which assists are being requested.
-  int get length => _length;
+  int length;
 
-  /// The length of the code for which assists are being requested.
-  set length(int value) {
-    assert(value != null);
-    _length = value;
-  }
-
-  EditGetAssistsParams(String file, int offset, int length) {
-    this.file = file;
-    this.offset = offset;
-    this.length = length;
-  }
+  EditGetAssistsParams(this.file, this.offset, this.length);
 
   factory EditGetAssistsParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -8204,8 +6602,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     result['offset'] = offset;
     result['length'] = length;
@@ -8248,23 +6646,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class EditGetAssistsResult implements ResponseResult {
-  List<SourceChange> _assists;
-
   /// The assists that are available at the given location.
-  List<SourceChange> get assists => _assists;
+  List<SourceChange> assists;
 
-  /// The assists that are available at the given location.
-  set assists(List<SourceChange> value) {
-    assert(value != null);
-    _assists = value;
-  }
-
-  EditGetAssistsResult(List<SourceChange> assists) {
-    this.assists = assists;
-  }
+  EditGetAssistsResult(this.assists);
 
   factory EditGetAssistsResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       List<SourceChange> assists;
@@ -8272,7 +6660,7 @@
         assists = jsonDecoder.decodeList(
             jsonPath + '.assists',
             json['assists'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 SourceChange.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'assists');
@@ -8291,8 +6679,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['assists'] =
         assists.map((SourceChange value) => value.toJson()).toList();
     return result;
@@ -8333,47 +6721,19 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class EditGetAvailableRefactoringsParams implements RequestParams {
-  String _file;
-
-  int _offset;
-
-  int _length;
-
   /// The file containing the code on which the refactoring would be based.
-  String get file => _file;
-
-  /// The file containing the code on which the refactoring would be based.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// The offset of the code on which the refactoring would be based.
-  int get offset => _offset;
-
-  /// The offset of the code on which the refactoring would be based.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
+  int offset;
 
   /// The length of the code on which the refactoring would be based.
-  int get length => _length;
+  int length;
 
-  /// The length of the code on which the refactoring would be based.
-  set length(int value) {
-    assert(value != null);
-    _length = value;
-  }
-
-  EditGetAvailableRefactoringsParams(String file, int offset, int length) {
-    this.file = file;
-    this.offset = offset;
-    this.length = length;
-  }
+  EditGetAvailableRefactoringsParams(this.file, this.offset, this.length);
 
   factory EditGetAvailableRefactoringsParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -8407,8 +6767,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     result['offset'] = offset;
     result['length'] = length;
@@ -8451,23 +6811,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class EditGetAvailableRefactoringsResult implements ResponseResult {
-  List<RefactoringKind> _kinds;
-
   /// The kinds of refactorings that are valid for the given selection.
-  List<RefactoringKind> get kinds => _kinds;
+  List<RefactoringKind> kinds;
 
-  /// The kinds of refactorings that are valid for the given selection.
-  set kinds(List<RefactoringKind> value) {
-    assert(value != null);
-    _kinds = value;
-  }
-
-  EditGetAvailableRefactoringsResult(List<RefactoringKind> kinds) {
-    this.kinds = kinds;
-  }
+  EditGetAvailableRefactoringsResult(this.kinds);
 
   factory EditGetAvailableRefactoringsResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       List<RefactoringKind> kinds;
@@ -8475,7 +6825,7 @@
         kinds = jsonDecoder.decodeList(
             jsonPath + '.kinds',
             json['kinds'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 RefactoringKind.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'kinds');
@@ -8495,8 +6845,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['kinds'] =
         kinds.map((RefactoringKind value) => value.toJson()).toList();
     return result;
@@ -8537,7 +6887,7 @@
   EditGetDartfixInfoParams();
 
   factory EditGetDartfixInfoParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       return EditGetDartfixInfoParams();
@@ -8552,8 +6902,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     return result;
   }
 
@@ -8588,23 +6938,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class EditGetDartfixInfoResult implements ResponseResult {
-  List<DartFix> _fixes;
-
   /// A list of fixes that can be specified in an edit.dartfix request.
-  List<DartFix> get fixes => _fixes;
+  List<DartFix> fixes;
 
-  /// A list of fixes that can be specified in an edit.dartfix request.
-  set fixes(List<DartFix> value) {
-    assert(value != null);
-    _fixes = value;
-  }
-
-  EditGetDartfixInfoResult(List<DartFix> fixes) {
-    this.fixes = fixes;
-  }
+  EditGetDartfixInfoResult(this.fixes);
 
   factory EditGetDartfixInfoResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       List<DartFix> fixes;
@@ -8612,7 +6952,7 @@
         fixes = jsonDecoder.decodeList(
             jsonPath + '.fixes',
             json['fixes'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 DartFix.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'fixes');
@@ -8631,8 +6971,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['fixes'] = fixes.map((DartFix value) => value.toJson()).toList();
     return result;
   }
@@ -8670,35 +7010,16 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class EditGetFixesParams implements RequestParams {
-  String _file;
-
-  int _offset;
-
   /// The file containing the errors for which fixes are being requested.
-  String get file => _file;
-
-  /// The file containing the errors for which fixes are being requested.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// The offset used to select the errors for which fixes will be returned.
-  int get offset => _offset;
+  int offset;
 
-  /// The offset used to select the errors for which fixes will be returned.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
-
-  EditGetFixesParams(String file, int offset) {
-    this.file = file;
-    this.offset = offset;
-  }
+  EditGetFixesParams(this.file, this.offset);
 
   factory EditGetFixesParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -8725,8 +7046,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     result['offset'] = offset;
     return result;
@@ -8765,23 +7086,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class EditGetFixesResult implements ResponseResult {
-  List<AnalysisErrorFixes> _fixes;
-
   /// The fixes that are available for the errors at the given offset.
-  List<AnalysisErrorFixes> get fixes => _fixes;
+  List<AnalysisErrorFixes> fixes;
 
-  /// The fixes that are available for the errors at the given offset.
-  set fixes(List<AnalysisErrorFixes> value) {
-    assert(value != null);
-    _fixes = value;
-  }
-
-  EditGetFixesResult(List<AnalysisErrorFixes> fixes) {
-    this.fixes = fixes;
-  }
+  EditGetFixesResult(this.fixes);
 
   factory EditGetFixesResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       List<AnalysisErrorFixes> fixes;
@@ -8789,7 +7100,7 @@
         fixes = jsonDecoder.decodeList(
             jsonPath + '.fixes',
             json['fixes'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 AnalysisErrorFixes.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'fixes');
@@ -8808,8 +7119,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['fixes'] =
         fixes.map((AnalysisErrorFixes value) => value.toJson()).toList();
     return result;
@@ -8850,49 +7161,20 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class EditGetPostfixCompletionParams implements RequestParams {
-  String _file;
-
-  String _key;
-
-  int _offset;
-
   /// The file containing the postfix template to be expanded.
-  String get file => _file;
-
-  /// The file containing the postfix template to be expanded.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// The unique name that identifies the template in use.
-  String get key => _key;
-
-  /// The unique name that identifies the template in use.
-  set key(String value) {
-    assert(value != null);
-    _key = value;
-  }
+  String key;
 
   /// The offset used to identify the code to which the template will be
   /// applied.
-  int get offset => _offset;
+  int offset;
 
-  /// The offset used to identify the code to which the template will be
-  /// applied.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
-
-  EditGetPostfixCompletionParams(String file, String key, int offset) {
-    this.file = file;
-    this.key = key;
-    this.offset = offset;
-  }
+  EditGetPostfixCompletionParams(this.file, this.key, this.offset);
 
   factory EditGetPostfixCompletionParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -8926,8 +7208,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     result['key'] = key;
     result['offset'] = offset;
@@ -8968,23 +7250,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class EditGetPostfixCompletionResult implements ResponseResult {
-  SourceChange _change;
-
   /// The change to be applied in order to complete the statement.
-  SourceChange get change => _change;
+  SourceChange change;
 
-  /// The change to be applied in order to complete the statement.
-  set change(SourceChange value) {
-    assert(value != null);
-    _change = value;
-  }
-
-  EditGetPostfixCompletionResult(SourceChange change) {
-    this.change = change;
-  }
+  EditGetPostfixCompletionResult(this.change);
 
   factory EditGetPostfixCompletionResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       SourceChange change;
@@ -9009,8 +7281,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['change'] = change.toJson();
     return result;
   }
@@ -9052,94 +7324,35 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class EditGetRefactoringParams implements RequestParams {
-  RefactoringKind _kind;
-
-  String _file;
-
-  int _offset;
-
-  int _length;
-
-  bool _validateOnly;
-
-  RefactoringOptions _options;
-
   /// The kind of refactoring to be performed.
-  RefactoringKind get kind => _kind;
-
-  /// The kind of refactoring to be performed.
-  set kind(RefactoringKind value) {
-    assert(value != null);
-    _kind = value;
-  }
+  RefactoringKind kind;
 
   /// The file containing the code involved in the refactoring.
-  String get file => _file;
-
-  /// The file containing the code involved in the refactoring.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// The offset of the region involved in the refactoring.
-  int get offset => _offset;
-
-  /// The offset of the region involved in the refactoring.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
+  int offset;
 
   /// The length of the region involved in the refactoring.
-  int get length => _length;
-
-  /// The length of the region involved in the refactoring.
-  set length(int value) {
-    assert(value != null);
-    _length = value;
-  }
+  int length;
 
   /// True if the client is only requesting that the values of the options be
   /// validated and no change be generated.
-  bool get validateOnly => _validateOnly;
-
-  /// True if the client is only requesting that the values of the options be
-  /// validated and no change be generated.
-  set validateOnly(bool value) {
-    assert(value != null);
-    _validateOnly = value;
-  }
+  bool validateOnly;
 
   /// Data used to provide values provided by the user. The structure of the
   /// data is dependent on the kind of refactoring being performed. The data
   /// that is expected is documented in the section titled Refactorings,
   /// labeled as "Options". This field can be omitted if the refactoring does
   /// not require any options or if the values of those options are not known.
-  RefactoringOptions get options => _options;
+  RefactoringOptions? options;
 
-  /// Data used to provide values provided by the user. The structure of the
-  /// data is dependent on the kind of refactoring being performed. The data
-  /// that is expected is documented in the section titled Refactorings,
-  /// labeled as "Options". This field can be omitted if the refactoring does
-  /// not require any options or if the values of those options are not known.
-  set options(RefactoringOptions value) {
-    _options = value;
-  }
-
-  EditGetRefactoringParams(RefactoringKind kind, String file, int offset,
-      int length, bool validateOnly,
-      {RefactoringOptions options}) {
-    this.kind = kind;
-    this.file = file;
-    this.offset = offset;
-    this.length = length;
-    this.validateOnly = validateOnly;
-    this.options = options;
-  }
+  EditGetRefactoringParams(
+      this.kind, this.file, this.offset, this.length, this.validateOnly,
+      {this.options});
 
   factory EditGetRefactoringParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       RefactoringKind kind;
@@ -9174,7 +7387,7 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'validateOnly');
       }
-      RefactoringOptions options;
+      RefactoringOptions? options;
       if (json.containsKey('options')) {
         options = RefactoringOptions.fromJson(
             jsonDecoder, jsonPath + '.options', json['options'], kind);
@@ -9194,13 +7407,14 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['kind'] = kind.toJson();
     result['file'] = file;
     result['offset'] = offset;
     result['length'] = length;
     result['validateOnly'] = validateOnly;
+    var options = this.options;
     if (options != null) {
       result['options'] = options.toJson();
     }
@@ -9254,84 +7468,32 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class EditGetRefactoringResult implements ResponseResult {
-  List<RefactoringProblem> _initialProblems;
-
-  List<RefactoringProblem> _optionsProblems;
-
-  List<RefactoringProblem> _finalProblems;
-
-  RefactoringFeedback _feedback;
-
-  SourceChange _change;
-
-  List<String> _potentialEdits;
-
   /// The initial status of the refactoring, i.e. problems related to the
   /// context in which the refactoring is requested. The array will be empty if
   /// there are no known problems.
-  List<RefactoringProblem> get initialProblems => _initialProblems;
-
-  /// The initial status of the refactoring, i.e. problems related to the
-  /// context in which the refactoring is requested. The array will be empty if
-  /// there are no known problems.
-  set initialProblems(List<RefactoringProblem> value) {
-    assert(value != null);
-    _initialProblems = value;
-  }
+  List<RefactoringProblem> initialProblems;
 
   /// The options validation status, i.e. problems in the given options, such
   /// as light-weight validation of a new name, flags compatibility, etc. The
   /// array will be empty if there are no known problems.
-  List<RefactoringProblem> get optionsProblems => _optionsProblems;
-
-  /// The options validation status, i.e. problems in the given options, such
-  /// as light-weight validation of a new name, flags compatibility, etc. The
-  /// array will be empty if there are no known problems.
-  set optionsProblems(List<RefactoringProblem> value) {
-    assert(value != null);
-    _optionsProblems = value;
-  }
+  List<RefactoringProblem> optionsProblems;
 
   /// The final status of the refactoring, i.e. problems identified in the
   /// result of a full, potentially expensive validation and / or change
   /// creation. The array will be empty if there are no known problems.
-  List<RefactoringProblem> get finalProblems => _finalProblems;
-
-  /// The final status of the refactoring, i.e. problems identified in the
-  /// result of a full, potentially expensive validation and / or change
-  /// creation. The array will be empty if there are no known problems.
-  set finalProblems(List<RefactoringProblem> value) {
-    assert(value != null);
-    _finalProblems = value;
-  }
+  List<RefactoringProblem> finalProblems;
 
   /// Data used to provide feedback to the user. The structure of the data is
   /// dependent on the kind of refactoring being created. The data that is
   /// returned is documented in the section titled Refactorings, labeled as
   /// "Feedback".
-  RefactoringFeedback get feedback => _feedback;
-
-  /// Data used to provide feedback to the user. The structure of the data is
-  /// dependent on the kind of refactoring being created. The data that is
-  /// returned is documented in the section titled Refactorings, labeled as
-  /// "Feedback".
-  set feedback(RefactoringFeedback value) {
-    _feedback = value;
-  }
+  RefactoringFeedback? feedback;
 
   /// The changes that are to be applied to affect the refactoring. This field
   /// will be omitted if there are problems that prevent a set of changes from
   /// being computed, such as having no options specified for a refactoring
   /// that requires them, or if only validation was requested.
-  SourceChange get change => _change;
-
-  /// The changes that are to be applied to affect the refactoring. This field
-  /// will be omitted if there are problems that prevent a set of changes from
-  /// being computed, such as having no options specified for a refactoring
-  /// that requires them, or if only validation was requested.
-  set change(SourceChange value) {
-    _change = value;
-  }
+  SourceChange? change;
 
   /// The ids of source edits that are not known to be valid. An edit is not
   /// known to be valid if there was insufficient type information for the
@@ -9340,36 +7502,14 @@
   /// to a member from an unknown type. This field will be omitted if the
   /// change field is omitted or if there are no potential edits for the
   /// refactoring.
-  List<String> get potentialEdits => _potentialEdits;
-
-  /// The ids of source edits that are not known to be valid. An edit is not
-  /// known to be valid if there was insufficient type information for the
-  /// server to be able to determine whether or not the code needs to be
-  /// modified, such as when a member is being renamed and there is a reference
-  /// to a member from an unknown type. This field will be omitted if the
-  /// change field is omitted or if there are no potential edits for the
-  /// refactoring.
-  set potentialEdits(List<String> value) {
-    _potentialEdits = value;
-  }
+  List<String>? potentialEdits;
 
   EditGetRefactoringResult(
-      List<RefactoringProblem> initialProblems,
-      List<RefactoringProblem> optionsProblems,
-      List<RefactoringProblem> finalProblems,
-      {RefactoringFeedback feedback,
-      SourceChange change,
-      List<String> potentialEdits}) {
-    this.initialProblems = initialProblems;
-    this.optionsProblems = optionsProblems;
-    this.finalProblems = finalProblems;
-    this.feedback = feedback;
-    this.change = change;
-    this.potentialEdits = potentialEdits;
-  }
+      this.initialProblems, this.optionsProblems, this.finalProblems,
+      {this.feedback, this.change, this.potentialEdits});
 
   factory EditGetRefactoringResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       List<RefactoringProblem> initialProblems;
@@ -9377,7 +7517,7 @@
         initialProblems = jsonDecoder.decodeList(
             jsonPath + '.initialProblems',
             json['initialProblems'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 RefactoringProblem.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'initialProblems');
@@ -9387,7 +7527,7 @@
         optionsProblems = jsonDecoder.decodeList(
             jsonPath + '.optionsProblems',
             json['optionsProblems'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 RefactoringProblem.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'optionsProblems');
@@ -9397,22 +7537,22 @@
         finalProblems = jsonDecoder.decodeList(
             jsonPath + '.finalProblems',
             json['finalProblems'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 RefactoringProblem.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'finalProblems');
       }
-      RefactoringFeedback feedback;
+      RefactoringFeedback? feedback;
       if (json.containsKey('feedback')) {
         feedback = RefactoringFeedback.fromJson(
             jsonDecoder, jsonPath + '.feedback', json['feedback'], json);
       }
-      SourceChange change;
+      SourceChange? change;
       if (json.containsKey('change')) {
         change = SourceChange.fromJson(
             jsonDecoder, jsonPath + '.change', json['change']);
       }
-      List<String> potentialEdits;
+      List<String>? potentialEdits;
       if (json.containsKey('potentialEdits')) {
         potentialEdits = jsonDecoder.decodeList(jsonPath + '.potentialEdits',
             json['potentialEdits'], jsonDecoder.decodeString);
@@ -9433,8 +7573,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['initialProblems'] = initialProblems
         .map((RefactoringProblem value) => value.toJson())
         .toList();
@@ -9444,12 +7584,15 @@
     result['finalProblems'] = finalProblems
         .map((RefactoringProblem value) => value.toJson())
         .toList();
+    var feedback = this.feedback;
     if (feedback != null) {
       result['feedback'] = feedback.toJson();
     }
+    var change = this.change;
     if (change != null) {
       result['change'] = change.toJson();
     }
+    var potentialEdits = this.potentialEdits;
     if (potentialEdits != null) {
       result['potentialEdits'] = potentialEdits;
     }
@@ -9503,35 +7646,16 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class EditGetStatementCompletionParams implements RequestParams {
-  String _file;
-
-  int _offset;
-
   /// The file containing the statement to be completed.
-  String get file => _file;
-
-  /// The file containing the statement to be completed.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// The offset used to identify the statement to be completed.
-  int get offset => _offset;
+  int offset;
 
-  /// The offset used to identify the statement to be completed.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
-
-  EditGetStatementCompletionParams(String file, int offset) {
-    this.file = file;
-    this.offset = offset;
-  }
+  EditGetStatementCompletionParams(this.file, this.offset);
 
   factory EditGetStatementCompletionParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -9559,8 +7683,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     result['offset'] = offset;
     return result;
@@ -9600,37 +7724,17 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class EditGetStatementCompletionResult implements ResponseResult {
-  SourceChange _change;
-
-  bool _whitespaceOnly;
-
   /// The change to be applied in order to complete the statement.
-  SourceChange get change => _change;
-
-  /// The change to be applied in order to complete the statement.
-  set change(SourceChange value) {
-    assert(value != null);
-    _change = value;
-  }
+  SourceChange change;
 
   /// Will be true if the change contains nothing but whitespace characters, or
   /// is empty.
-  bool get whitespaceOnly => _whitespaceOnly;
+  bool whitespaceOnly;
 
-  /// Will be true if the change contains nothing but whitespace characters, or
-  /// is empty.
-  set whitespaceOnly(bool value) {
-    assert(value != null);
-    _whitespaceOnly = value;
-  }
-
-  EditGetStatementCompletionResult(SourceChange change, bool whitespaceOnly) {
-    this.change = change;
-    this.whitespaceOnly = whitespaceOnly;
-  }
+  EditGetStatementCompletionResult(this.change, this.whitespaceOnly);
 
   factory EditGetStatementCompletionResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       SourceChange change;
@@ -9662,8 +7766,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['change'] = change.toJson();
     result['whitespaceOnly'] = whitespaceOnly;
     return result;
@@ -9704,53 +7808,22 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class EditImportElementsParams implements RequestParams {
-  String _file;
-
-  List<ImportedElements> _elements;
-
-  int _offset;
-
   /// The file in which the specified elements are to be made accessible.
-  String get file => _file;
-
-  /// The file in which the specified elements are to be made accessible.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// The elements to be made accessible in the specified file.
-  List<ImportedElements> get elements => _elements;
-
-  /// The elements to be made accessible in the specified file.
-  set elements(List<ImportedElements> value) {
-    assert(value != null);
-    _elements = value;
-  }
+  List<ImportedElements> elements;
 
   /// The offset at which the specified elements need to be made accessible. If
   /// provided, this is used to guard against adding imports for text that
   /// would be inserted into a comment, string literal, or other location where
   /// the imports would not be necessary.
-  int get offset => _offset;
+  int? offset;
 
-  /// The offset at which the specified elements need to be made accessible. If
-  /// provided, this is used to guard against adding imports for text that
-  /// would be inserted into a comment, string literal, or other location where
-  /// the imports would not be necessary.
-  set offset(int value) {
-    _offset = value;
-  }
-
-  EditImportElementsParams(String file, List<ImportedElements> elements,
-      {int offset}) {
-    this.file = file;
-    this.elements = elements;
-    this.offset = offset;
-  }
+  EditImportElementsParams(this.file, this.elements, {this.offset});
 
   factory EditImportElementsParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -9764,12 +7837,12 @@
         elements = jsonDecoder.decodeList(
             jsonPath + '.elements',
             json['elements'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 ImportedElements.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'elements');
       }
-      int offset;
+      int? offset;
       if (json.containsKey('offset')) {
         offset = jsonDecoder.decodeInt(jsonPath + '.offset', json['offset']);
       }
@@ -9785,11 +7858,12 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     result['elements'] =
         elements.map((ImportedElements value) => value.toJson()).toList();
+    var offset = this.offset;
     if (offset != null) {
       result['offset'] = offset;
     }
@@ -9833,35 +7907,21 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class EditImportElementsResult implements ResponseResult {
-  SourceFileEdit _edit;
-
   /// The edits to be applied in order to make the specified elements
   /// accessible. The file to be edited will be the defining compilation unit
   /// of the library containing the file specified in the request, which can be
   /// different than the file specified in the request if the specified file is
   /// a part file. This field will be omitted if there are no edits that need
   /// to be applied.
-  SourceFileEdit get edit => _edit;
+  SourceFileEdit? edit;
 
-  /// The edits to be applied in order to make the specified elements
-  /// accessible. The file to be edited will be the defining compilation unit
-  /// of the library containing the file specified in the request, which can be
-  /// different than the file specified in the request if the specified file is
-  /// a part file. This field will be omitted if there are no edits that need
-  /// to be applied.
-  set edit(SourceFileEdit value) {
-    _edit = value;
-  }
-
-  EditImportElementsResult({SourceFileEdit edit}) {
-    this.edit = edit;
-  }
+  EditImportElementsResult({this.edit});
 
   factory EditImportElementsResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
-      SourceFileEdit edit;
+      SourceFileEdit? edit;
       if (json.containsKey('edit')) {
         edit = SourceFileEdit.fromJson(
             jsonDecoder, jsonPath + '.edit', json['edit']);
@@ -9880,8 +7940,9 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
+    var edit = this.edit;
     if (edit != null) {
       result['edit'] = edit.toJson();
     }
@@ -9922,49 +7983,20 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class EditIsPostfixCompletionApplicableParams implements RequestParams {
-  String _file;
-
-  String _key;
-
-  int _offset;
-
   /// The file containing the postfix template to be expanded.
-  String get file => _file;
-
-  /// The file containing the postfix template to be expanded.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// The unique name that identifies the template in use.
-  String get key => _key;
-
-  /// The unique name that identifies the template in use.
-  set key(String value) {
-    assert(value != null);
-    _key = value;
-  }
+  String key;
 
   /// The offset used to identify the code to which the template will be
   /// applied.
-  int get offset => _offset;
+  int offset;
 
-  /// The offset used to identify the code to which the template will be
-  /// applied.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
-
-  EditIsPostfixCompletionApplicableParams(String file, String key, int offset) {
-    this.file = file;
-    this.key = key;
-    this.offset = offset;
-  }
+  EditIsPostfixCompletionApplicableParams(this.file, this.key, this.offset);
 
   factory EditIsPostfixCompletionApplicableParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -9998,8 +8030,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     result['key'] = key;
     result['offset'] = offset;
@@ -10040,23 +8072,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class EditIsPostfixCompletionApplicableResult implements ResponseResult {
-  bool _value;
-
   /// True if the template can be expanded at the given location.
-  bool get value => _value;
+  bool value;
 
-  /// True if the template can be expanded at the given location.
-  set value(bool value) {
-    assert(value != null);
-    _value = value;
-  }
-
-  EditIsPostfixCompletionApplicableResult(bool value) {
-    this.value = value;
-  }
+  EditIsPostfixCompletionApplicableResult(this.value);
 
   factory EditIsPostfixCompletionApplicableResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       bool value;
@@ -10081,8 +8103,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['value'] = value;
     return result;
   }
@@ -10116,7 +8138,7 @@
 /// Clients may not extend, implement or mix-in this class.
 class EditListPostfixCompletionTemplatesParams implements RequestParams {
   @override
-  Map<String, dynamic> toJson() => <String, dynamic>{};
+  Map<String, Object> toJson() => <String, Object>{};
 
   @override
   Request toRequest(String id) {
@@ -10145,24 +8167,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class EditListPostfixCompletionTemplatesResult implements ResponseResult {
-  List<PostfixTemplateDescriptor> _templates;
-
   /// The list of available templates.
-  List<PostfixTemplateDescriptor> get templates => _templates;
+  List<PostfixTemplateDescriptor> templates;
 
-  /// The list of available templates.
-  set templates(List<PostfixTemplateDescriptor> value) {
-    assert(value != null);
-    _templates = value;
-  }
-
-  EditListPostfixCompletionTemplatesResult(
-      List<PostfixTemplateDescriptor> templates) {
-    this.templates = templates;
-  }
+  EditListPostfixCompletionTemplatesResult(this.templates);
 
   factory EditListPostfixCompletionTemplatesResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       List<PostfixTemplateDescriptor> templates;
@@ -10170,7 +8181,7 @@
         templates = jsonDecoder.decodeList(
             jsonPath + '.templates',
             json['templates'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 PostfixTemplateDescriptor.fromJson(
                     jsonDecoder, jsonPath, json));
       } else {
@@ -10192,8 +8203,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['templates'] = templates
         .map((PostfixTemplateDescriptor value) => value.toJson())
         .toList();
@@ -10233,23 +8244,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class EditOrganizeDirectivesParams implements RequestParams {
-  String _file;
-
   /// The Dart file to organize directives in.
-  String get file => _file;
+  String file;
 
-  /// The Dart file to organize directives in.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
-
-  EditOrganizeDirectivesParams(String file) {
-    this.file = file;
-  }
+  EditOrganizeDirectivesParams(this.file);
 
   factory EditOrganizeDirectivesParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -10271,8 +8272,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     return result;
   }
@@ -10309,25 +8310,14 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class EditOrganizeDirectivesResult implements ResponseResult {
-  SourceFileEdit _edit;
-
   /// The file edit that is to be applied to the given file to effect the
   /// organizing.
-  SourceFileEdit get edit => _edit;
+  SourceFileEdit edit;
 
-  /// The file edit that is to be applied to the given file to effect the
-  /// organizing.
-  set edit(SourceFileEdit value) {
-    assert(value != null);
-    _edit = value;
-  }
-
-  EditOrganizeDirectivesResult(SourceFileEdit edit) {
-    this.edit = edit;
-  }
+  EditOrganizeDirectivesResult(this.edit);
 
   factory EditOrganizeDirectivesResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       SourceFileEdit edit;
@@ -10352,8 +8342,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['edit'] = edit.toJson();
     return result;
   }
@@ -10390,23 +8380,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class EditSortMembersParams implements RequestParams {
-  String _file;
-
   /// The Dart file to sort.
-  String get file => _file;
+  String file;
 
-  /// The Dart file to sort.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
-
-  EditSortMembersParams(String file) {
-    this.file = file;
-  }
+  EditSortMembersParams(this.file);
 
   factory EditSortMembersParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -10427,8 +8407,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     return result;
   }
@@ -10465,25 +8445,14 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class EditSortMembersResult implements ResponseResult {
-  SourceFileEdit _edit;
-
   /// The file edit that is to be applied to the given file to effect the
   /// sorting.
-  SourceFileEdit get edit => _edit;
+  SourceFileEdit edit;
 
-  /// The file edit that is to be applied to the given file to effect the
-  /// sorting.
-  set edit(SourceFileEdit value) {
-    assert(value != null);
-    _edit = value;
-  }
-
-  EditSortMembersResult(SourceFileEdit edit) {
-    this.edit = edit;
-  }
+  EditSortMembersResult(this.edit);
 
   factory EditSortMembersResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       SourceFileEdit edit;
@@ -10507,8 +8476,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['edit'] = edit.toJson();
     return result;
   }
@@ -10555,119 +8524,37 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class ElementDeclaration implements HasToJson {
-  String _name;
-
-  ElementKind _kind;
-
-  int _fileIndex;
-
-  int _offset;
-
-  int _line;
-
-  int _column;
-
-  int _codeOffset;
-
-  int _codeLength;
-
-  String _className;
-
-  String _mixinName;
-
-  String _parameters;
-
   /// The name of the declaration.
-  String get name => _name;
-
-  /// The name of the declaration.
-  set name(String value) {
-    assert(value != null);
-    _name = value;
-  }
+  String name;
 
   /// The kind of the element that corresponds to the declaration.
-  ElementKind get kind => _kind;
-
-  /// The kind of the element that corresponds to the declaration.
-  set kind(ElementKind value) {
-    assert(value != null);
-    _kind = value;
-  }
+  ElementKind kind;
 
   /// The index of the file (in the enclosing response).
-  int get fileIndex => _fileIndex;
-
-  /// The index of the file (in the enclosing response).
-  set fileIndex(int value) {
-    assert(value != null);
-    _fileIndex = value;
-  }
+  int fileIndex;
 
   /// The offset of the declaration name in the file.
-  int get offset => _offset;
-
-  /// The offset of the declaration name in the file.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
+  int offset;
 
   /// The one-based index of the line containing the declaration name.
-  int get line => _line;
-
-  /// The one-based index of the line containing the declaration name.
-  set line(int value) {
-    assert(value != null);
-    _line = value;
-  }
+  int line;
 
   /// The one-based index of the column containing the declaration name.
-  int get column => _column;
-
-  /// The one-based index of the column containing the declaration name.
-  set column(int value) {
-    assert(value != null);
-    _column = value;
-  }
+  int column;
 
   /// The offset of the first character of the declaration code in the file.
-  int get codeOffset => _codeOffset;
-
-  /// The offset of the first character of the declaration code in the file.
-  set codeOffset(int value) {
-    assert(value != null);
-    _codeOffset = value;
-  }
+  int codeOffset;
 
   /// The length of the declaration code in the file.
-  int get codeLength => _codeLength;
-
-  /// The length of the declaration code in the file.
-  set codeLength(int value) {
-    assert(value != null);
-    _codeLength = value;
-  }
+  int codeLength;
 
   /// The name of the class enclosing this declaration. If the declaration is
   /// not a class member, this field will be absent.
-  String get className => _className;
-
-  /// The name of the class enclosing this declaration. If the declaration is
-  /// not a class member, this field will be absent.
-  set className(String value) {
-    _className = value;
-  }
+  String? className;
 
   /// The name of the mixin enclosing this declaration. If the declaration is
   /// not a mixin member, this field will be absent.
-  String get mixinName => _mixinName;
-
-  /// The name of the mixin enclosing this declaration. If the declaration is
-  /// not a mixin member, this field will be absent.
-  set mixinName(String value) {
-    _mixinName = value;
-  }
+  String? mixinName;
 
   /// The parameter list for the element. If the element is not a method or
   /// function this field will not be defined. If the element doesn't have
@@ -10675,36 +8562,14 @@
   /// has zero parameters, this field will have a value of "()". The value
   /// should not be treated as exact presentation of parameters, it is just
   /// approximation of parameters to give the user general idea.
-  String get parameters => _parameters;
+  String? parameters;
 
-  /// The parameter list for the element. If the element is not a method or
-  /// function this field will not be defined. If the element doesn't have
-  /// parameters (e.g. getter), this field will not be defined. If the element
-  /// has zero parameters, this field will have a value of "()". The value
-  /// should not be treated as exact presentation of parameters, it is just
-  /// approximation of parameters to give the user general idea.
-  set parameters(String value) {
-    _parameters = value;
-  }
-
-  ElementDeclaration(String name, ElementKind kind, int fileIndex, int offset,
-      int line, int column, int codeOffset, int codeLength,
-      {String className, String mixinName, String parameters}) {
-    this.name = name;
-    this.kind = kind;
-    this.fileIndex = fileIndex;
-    this.offset = offset;
-    this.line = line;
-    this.column = column;
-    this.codeOffset = codeOffset;
-    this.codeLength = codeLength;
-    this.className = className;
-    this.mixinName = mixinName;
-    this.parameters = parameters;
-  }
+  ElementDeclaration(this.name, this.kind, this.fileIndex, this.offset,
+      this.line, this.column, this.codeOffset, this.codeLength,
+      {this.className, this.mixinName, this.parameters});
 
   factory ElementDeclaration.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String name;
@@ -10759,17 +8624,17 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'codeLength');
       }
-      String className;
+      String? className;
       if (json.containsKey('className')) {
         className = jsonDecoder.decodeString(
             jsonPath + '.className', json['className']);
       }
-      String mixinName;
+      String? mixinName;
       if (json.containsKey('mixinName')) {
         mixinName = jsonDecoder.decodeString(
             jsonPath + '.mixinName', json['mixinName']);
       }
-      String parameters;
+      String? parameters;
       if (json.containsKey('parameters')) {
         parameters = jsonDecoder.decodeString(
             jsonPath + '.parameters', json['parameters']);
@@ -10783,8 +8648,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['name'] = name;
     result['kind'] = kind.toJson();
     result['fileIndex'] = fileIndex;
@@ -10793,12 +8658,15 @@
     result['column'] = column;
     result['codeOffset'] = codeOffset;
     result['codeLength'] = codeLength;
+    var className = this.className;
     if (className != null) {
       result['className'] = className;
     }
+    var mixinName = this.mixinName;
     if (mixinName != null) {
       result['mixinName'] = mixinName;
     }
+    var parameters = this.parameters;
     if (parameters != null) {
       result['parameters'] = parameters;
     }
@@ -10853,35 +8721,16 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class ExecutableFile implements HasToJson {
-  String _file;
-
-  ExecutableKind _kind;
-
   /// The path of the executable file.
-  String get file => _file;
-
-  /// The path of the executable file.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// The kind of the executable file.
-  ExecutableKind get kind => _kind;
+  ExecutableKind kind;
 
-  /// The kind of the executable file.
-  set kind(ExecutableKind value) {
-    assert(value != null);
-    _kind = value;
-  }
-
-  ExecutableFile(String file, ExecutableKind kind) {
-    this.file = file;
-    this.kind = kind;
-  }
+  ExecutableFile(this.file, this.kind);
 
   factory ExecutableFile.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -10904,8 +8753,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     result['kind'] = kind.toJson();
     return result;
@@ -10979,7 +8828,7 @@
   }
 
   factory ExecutableKind.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     if (json is String) {
       try {
         return ExecutableKind(json);
@@ -11004,25 +8853,14 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class ExecutionCreateContextParams implements RequestParams {
-  String _contextRoot;
-
   /// The path of the Dart or HTML file that will be launched, or the path of
   /// the directory containing the file.
-  String get contextRoot => _contextRoot;
+  String contextRoot;
 
-  /// The path of the Dart or HTML file that will be launched, or the path of
-  /// the directory containing the file.
-  set contextRoot(String value) {
-    assert(value != null);
-    _contextRoot = value;
-  }
-
-  ExecutionCreateContextParams(String contextRoot) {
-    this.contextRoot = contextRoot;
-  }
+  ExecutionCreateContextParams(this.contextRoot);
 
   factory ExecutionCreateContextParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String contextRoot;
@@ -11045,8 +8883,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['contextRoot'] = contextRoot;
     return result;
   }
@@ -11083,23 +8921,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class ExecutionCreateContextResult implements ResponseResult {
-  String _id;
-
   /// The identifier used to refer to the execution context that was created.
-  String get id => _id;
+  String id;
 
-  /// The identifier used to refer to the execution context that was created.
-  set id(String value) {
-    assert(value != null);
-    _id = value;
-  }
-
-  ExecutionCreateContextResult(String id) {
-    this.id = id;
-  }
+  ExecutionCreateContextResult(this.id);
 
   factory ExecutionCreateContextResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String id;
@@ -11123,8 +8951,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['id'] = id;
     return result;
   }
@@ -11161,23 +8989,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class ExecutionDeleteContextParams implements RequestParams {
-  String _id;
-
   /// The identifier of the execution context that is to be deleted.
-  String get id => _id;
+  String id;
 
-  /// The identifier of the execution context that is to be deleted.
-  set id(String value) {
-    assert(value != null);
-    _id = value;
-  }
-
-  ExecutionDeleteContextParams(String id) {
-    this.id = id;
-  }
+  ExecutionDeleteContextParams(this.id);
 
   factory ExecutionDeleteContextParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String id;
@@ -11199,8 +9017,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['id'] = id;
     return result;
   }
@@ -11234,7 +9052,7 @@
 /// Clients may not extend, implement or mix-in this class.
 class ExecutionDeleteContextResult implements ResponseResult {
   @override
-  Map<String, dynamic> toJson() => <String, dynamic>{};
+  Map<String, Object> toJson() => <String, Object>{};
 
   @override
   Response toResponse(String id) {
@@ -11268,72 +9086,25 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class ExecutionGetSuggestionsParams implements RequestParams {
-  String _code;
-
-  int _offset;
-
-  String _contextFile;
-
-  int _contextOffset;
-
-  List<RuntimeCompletionVariable> _variables;
-
-  List<RuntimeCompletionExpression> _expressions;
-
   /// The code to get suggestions in.
-  String get code => _code;
-
-  /// The code to get suggestions in.
-  set code(String value) {
-    assert(value != null);
-    _code = value;
-  }
+  String code;
 
   /// The offset within the code to get suggestions at.
-  int get offset => _offset;
-
-  /// The offset within the code to get suggestions at.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
+  int offset;
 
   /// The path of the context file, e.g. the file of the current debugger
   /// frame. The combination of the context file and context offset can be used
   /// to ensure that all variables of the context are available for completion
   /// (with their static types).
-  String get contextFile => _contextFile;
-
-  /// The path of the context file, e.g. the file of the current debugger
-  /// frame. The combination of the context file and context offset can be used
-  /// to ensure that all variables of the context are available for completion
-  /// (with their static types).
-  set contextFile(String value) {
-    assert(value != null);
-    _contextFile = value;
-  }
+  String contextFile;
 
   /// The offset in the context file, e.g. the line offset in the current
   /// debugger frame.
-  int get contextOffset => _contextOffset;
-
-  /// The offset in the context file, e.g. the line offset in the current
-  /// debugger frame.
-  set contextOffset(int value) {
-    assert(value != null);
-    _contextOffset = value;
-  }
+  int contextOffset;
 
   /// The runtime context variables that are potentially referenced in the
   /// code.
-  List<RuntimeCompletionVariable> get variables => _variables;
-
-  /// The runtime context variables that are potentially referenced in the
-  /// code.
-  set variables(List<RuntimeCompletionVariable> value) {
-    assert(value != null);
-    _variables = value;
-  }
+  List<RuntimeCompletionVariable> variables;
 
   /// The list of sub-expressions in the code for which the client wants to
   /// provide runtime types. It does not have to be the full list of
@@ -11344,34 +9115,14 @@
   /// only when there are no interesting sub-expressions in the given code. The
   /// client may provide an empty list, in this case the server will return
   /// completion suggestions.
-  List<RuntimeCompletionExpression> get expressions => _expressions;
+  List<RuntimeCompletionExpression>? expressions;
 
-  /// The list of sub-expressions in the code for which the client wants to
-  /// provide runtime types. It does not have to be the full list of
-  /// expressions requested by the server, for missing expressions their static
-  /// types will be used.
-  ///
-  /// When this field is omitted, the server will return completion suggestions
-  /// only when there are no interesting sub-expressions in the given code. The
-  /// client may provide an empty list, in this case the server will return
-  /// completion suggestions.
-  set expressions(List<RuntimeCompletionExpression> value) {
-    _expressions = value;
-  }
-
-  ExecutionGetSuggestionsParams(String code, int offset, String contextFile,
-      int contextOffset, List<RuntimeCompletionVariable> variables,
-      {List<RuntimeCompletionExpression> expressions}) {
-    this.code = code;
-    this.offset = offset;
-    this.contextFile = contextFile;
-    this.contextOffset = contextOffset;
-    this.variables = variables;
-    this.expressions = expressions;
-  }
+  ExecutionGetSuggestionsParams(this.code, this.offset, this.contextFile,
+      this.contextOffset, this.variables,
+      {this.expressions});
 
   factory ExecutionGetSuggestionsParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String code;
@@ -11405,18 +9156,18 @@
         variables = jsonDecoder.decodeList(
             jsonPath + '.variables',
             json['variables'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 RuntimeCompletionVariable.fromJson(
                     jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'variables');
       }
-      List<RuntimeCompletionExpression> expressions;
+      List<RuntimeCompletionExpression>? expressions;
       if (json.containsKey('expressions')) {
         expressions = jsonDecoder.decodeList(
             jsonPath + '.expressions',
             json['expressions'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 RuntimeCompletionExpression.fromJson(
                     jsonDecoder, jsonPath, json));
       }
@@ -11435,8 +9186,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['code'] = code;
     result['offset'] = offset;
     result['contextFile'] = contextFile;
@@ -11444,6 +9195,7 @@
     result['variables'] = variables
         .map((RuntimeCompletionVariable value) => value.toJson())
         .toList();
+    var expressions = this.expressions;
     if (expressions != null) {
       result['expressions'] = expressions
           .map((RuntimeCompletionExpression value) => value.toJson())
@@ -11503,10 +9255,6 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class ExecutionGetSuggestionsResult implements ResponseResult {
-  List<CompletionSuggestion> _suggestions;
-
-  List<RuntimeCompletionExpression> _expressions;
-
   /// The completion suggestions. In contrast to usual completion request,
   /// suggestions for private elements also will be provided.
   ///
@@ -11515,59 +9263,34 @@
   /// their actual runtime types can improve completion results, the server
   /// omits this field in the response, and instead will return the
   /// "expressions" field.
-  List<CompletionSuggestion> get suggestions => _suggestions;
-
-  /// The completion suggestions. In contrast to usual completion request,
-  /// suggestions for private elements also will be provided.
-  ///
-  /// If there are sub-expressions that can have different runtime types, and
-  /// are considered to be safe to evaluate at runtime (e.g. getters), so using
-  /// their actual runtime types can improve completion results, the server
-  /// omits this field in the response, and instead will return the
-  /// "expressions" field.
-  set suggestions(List<CompletionSuggestion> value) {
-    _suggestions = value;
-  }
+  List<CompletionSuggestion>? suggestions;
 
   /// The list of sub-expressions in the code for which the server would like
   /// to know runtime types to provide better completion suggestions.
   ///
   /// This field is omitted the field "suggestions" is returned.
-  List<RuntimeCompletionExpression> get expressions => _expressions;
+  List<RuntimeCompletionExpression>? expressions;
 
-  /// The list of sub-expressions in the code for which the server would like
-  /// to know runtime types to provide better completion suggestions.
-  ///
-  /// This field is omitted the field "suggestions" is returned.
-  set expressions(List<RuntimeCompletionExpression> value) {
-    _expressions = value;
-  }
-
-  ExecutionGetSuggestionsResult(
-      {List<CompletionSuggestion> suggestions,
-      List<RuntimeCompletionExpression> expressions}) {
-    this.suggestions = suggestions;
-    this.expressions = expressions;
-  }
+  ExecutionGetSuggestionsResult({this.suggestions, this.expressions});
 
   factory ExecutionGetSuggestionsResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
-      List<CompletionSuggestion> suggestions;
+      List<CompletionSuggestion>? suggestions;
       if (json.containsKey('suggestions')) {
         suggestions = jsonDecoder.decodeList(
             jsonPath + '.suggestions',
             json['suggestions'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 CompletionSuggestion.fromJson(jsonDecoder, jsonPath, json));
       }
-      List<RuntimeCompletionExpression> expressions;
+      List<RuntimeCompletionExpression>? expressions;
       if (json.containsKey('expressions')) {
         expressions = jsonDecoder.decodeList(
             jsonPath + '.expressions',
             json['expressions'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 RuntimeCompletionExpression.fromJson(
                     jsonDecoder, jsonPath, json));
       }
@@ -11587,13 +9310,15 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
+    var suggestions = this.suggestions;
     if (suggestions != null) {
       result['suggestions'] = suggestions
           .map((CompletionSuggestion value) => value.toJson())
           .toList();
     }
+    var expressions = this.expressions;
     if (expressions != null) {
       result['expressions'] = expressions
           .map((RuntimeCompletionExpression value) => value.toJson())
@@ -11643,52 +9368,22 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class ExecutionLaunchDataParams implements HasToJson {
-  String _file;
-
-  ExecutableKind _kind;
-
-  List<String> _referencedFiles;
-
   /// The file for which launch data is being provided. This will either be a
   /// Dart library or an HTML file.
-  String get file => _file;
-
-  /// The file for which launch data is being provided. This will either be a
-  /// Dart library or an HTML file.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// The kind of the executable file. This field is omitted if the file is not
   /// a Dart file.
-  ExecutableKind get kind => _kind;
-
-  /// The kind of the executable file. This field is omitted if the file is not
-  /// a Dart file.
-  set kind(ExecutableKind value) {
-    _kind = value;
-  }
+  ExecutableKind? kind;
 
   /// A list of the Dart files that are referenced by the file. This field is
   /// omitted if the file is not an HTML file.
-  List<String> get referencedFiles => _referencedFiles;
+  List<String>? referencedFiles;
 
-  /// A list of the Dart files that are referenced by the file. This field is
-  /// omitted if the file is not an HTML file.
-  set referencedFiles(List<String> value) {
-    _referencedFiles = value;
-  }
-
-  ExecutionLaunchDataParams(String file,
-      {ExecutableKind kind, List<String> referencedFiles}) {
-    this.file = file;
-    this.kind = kind;
-    this.referencedFiles = referencedFiles;
-  }
+  ExecutionLaunchDataParams(this.file, {this.kind, this.referencedFiles});
 
   factory ExecutionLaunchDataParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -11697,12 +9392,12 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'file');
       }
-      ExecutableKind kind;
+      ExecutableKind? kind;
       if (json.containsKey('kind')) {
         kind = ExecutableKind.fromJson(
             jsonDecoder, jsonPath + '.kind', json['kind']);
       }
-      List<String> referencedFiles;
+      List<String>? referencedFiles;
       if (json.containsKey('referencedFiles')) {
         referencedFiles = jsonDecoder.decodeList(jsonPath + '.referencedFiles',
             json['referencedFiles'], jsonDecoder.decodeString);
@@ -11721,12 +9416,14 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
+    var kind = this.kind;
     if (kind != null) {
       result['kind'] = kind.toJson();
     }
+    var referencedFiles = this.referencedFiles;
     if (referencedFiles != null) {
       result['referencedFiles'] = referencedFiles;
     }
@@ -11771,45 +9468,19 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class ExecutionMapUriParams implements RequestParams {
-  String _id;
-
-  String _file;
-
-  String _uri;
-
   /// The identifier of the execution context in which the URI is to be mapped.
-  String get id => _id;
-
-  /// The identifier of the execution context in which the URI is to be mapped.
-  set id(String value) {
-    assert(value != null);
-    _id = value;
-  }
+  String id;
 
   /// The path of the file to be mapped into a URI.
-  String get file => _file;
-
-  /// The path of the file to be mapped into a URI.
-  set file(String value) {
-    _file = value;
-  }
+  String? file;
 
   /// The URI to be mapped into a file path.
-  String get uri => _uri;
+  String? uri;
 
-  /// The URI to be mapped into a file path.
-  set uri(String value) {
-    _uri = value;
-  }
-
-  ExecutionMapUriParams(String id, {String file, String uri}) {
-    this.id = id;
-    this.file = file;
-    this.uri = uri;
-  }
+  ExecutionMapUriParams(this.id, {this.file, this.uri});
 
   factory ExecutionMapUriParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String id;
@@ -11818,11 +9489,11 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'id');
       }
-      String file;
+      String? file;
       if (json.containsKey('file')) {
         file = jsonDecoder.decodeString(jsonPath + '.file', json['file']);
       }
-      String uri;
+      String? uri;
       if (json.containsKey('uri')) {
         uri = jsonDecoder.decodeString(jsonPath + '.uri', json['uri']);
       }
@@ -11838,12 +9509,14 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['id'] = id;
+    var file = this.file;
     if (file != null) {
       result['file'] = file;
     }
+    var uri = this.uri;
     if (uri != null) {
       result['uri'] = uri;
     }
@@ -11885,44 +9558,25 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class ExecutionMapUriResult implements ResponseResult {
-  String _file;
-
-  String _uri;
-
   /// The file to which the URI was mapped. This field is omitted if the uri
   /// field was not given in the request.
-  String get file => _file;
-
-  /// The file to which the URI was mapped. This field is omitted if the uri
-  /// field was not given in the request.
-  set file(String value) {
-    _file = value;
-  }
+  String? file;
 
   /// The URI to which the file path was mapped. This field is omitted if the
   /// file field was not given in the request.
-  String get uri => _uri;
+  String? uri;
 
-  /// The URI to which the file path was mapped. This field is omitted if the
-  /// file field was not given in the request.
-  set uri(String value) {
-    _uri = value;
-  }
-
-  ExecutionMapUriResult({String file, String uri}) {
-    this.file = file;
-    this.uri = uri;
-  }
+  ExecutionMapUriResult({this.file, this.uri});
 
   factory ExecutionMapUriResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
-      String file;
+      String? file;
       if (json.containsKey('file')) {
         file = jsonDecoder.decodeString(jsonPath + '.file', json['file']);
       }
-      String uri;
+      String? uri;
       if (json.containsKey('uri')) {
         uri = jsonDecoder.decodeString(jsonPath + '.uri', json['uri']);
       }
@@ -11940,11 +9594,13 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
+    var file = this.file;
     if (file != null) {
       result['file'] = file;
     }
+    var uri = this.uri;
     if (uri != null) {
       result['uri'] = uri;
     }
@@ -12003,7 +9659,7 @@
   }
 
   factory ExecutionService.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     if (json is String) {
       try {
         return ExecutionService(json);
@@ -12028,23 +9684,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class ExecutionSetSubscriptionsParams implements RequestParams {
-  List<ExecutionService> _subscriptions;
-
   /// A list of the services being subscribed to.
-  List<ExecutionService> get subscriptions => _subscriptions;
+  List<ExecutionService> subscriptions;
 
-  /// A list of the services being subscribed to.
-  set subscriptions(List<ExecutionService> value) {
-    assert(value != null);
-    _subscriptions = value;
-  }
-
-  ExecutionSetSubscriptionsParams(List<ExecutionService> subscriptions) {
-    this.subscriptions = subscriptions;
-  }
+  ExecutionSetSubscriptionsParams(this.subscriptions);
 
   factory ExecutionSetSubscriptionsParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       List<ExecutionService> subscriptions;
@@ -12052,7 +9698,7 @@
         subscriptions = jsonDecoder.decodeList(
             jsonPath + '.subscriptions',
             json['subscriptions'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 ExecutionService.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'subscriptions');
@@ -12070,8 +9716,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['subscriptions'] =
         subscriptions.map((ExecutionService value) => value.toJson()).toList();
     return result;
@@ -12107,7 +9753,7 @@
 /// Clients may not extend, implement or mix-in this class.
 class ExecutionSetSubscriptionsResult implements ResponseResult {
   @override
-  Map<String, dynamic> toJson() => <String, dynamic>{};
+  Map<String, Object> toJson() => <String, Object>{};
 
   @override
   Response toResponse(String id) {
@@ -12137,37 +9783,17 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class ExistingImport implements HasToJson {
-  int _uri;
-
-  List<int> _elements;
-
   /// The URI of the imported library. It is an index in the strings field, in
   /// the enclosing ExistingImports and its ImportedElementSet object.
-  int get uri => _uri;
-
-  /// The URI of the imported library. It is an index in the strings field, in
-  /// the enclosing ExistingImports and its ImportedElementSet object.
-  set uri(int value) {
-    assert(value != null);
-    _uri = value;
-  }
+  int uri;
 
   /// The list of indexes of elements, in the enclosing ExistingImports object.
-  List<int> get elements => _elements;
+  List<int> elements;
 
-  /// The list of indexes of elements, in the enclosing ExistingImports object.
-  set elements(List<int> value) {
-    assert(value != null);
-    _elements = value;
-  }
-
-  ExistingImport(int uri, List<int> elements) {
-    this.uri = uri;
-    this.elements = elements;
-  }
+  ExistingImport(this.uri, this.elements);
 
   factory ExistingImport.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       int uri;
@@ -12190,8 +9816,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['uri'] = uri;
     result['elements'] = elements;
     return result;
@@ -12227,35 +9853,16 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class ExistingImports implements HasToJson {
-  ImportedElementSet _elements;
-
-  List<ExistingImport> _imports;
-
   /// The set of all unique imported elements for all imports.
-  ImportedElementSet get elements => _elements;
-
-  /// The set of all unique imported elements for all imports.
-  set elements(ImportedElementSet value) {
-    assert(value != null);
-    _elements = value;
-  }
+  ImportedElementSet elements;
 
   /// The list of imports in the library.
-  List<ExistingImport> get imports => _imports;
+  List<ExistingImport> imports;
 
-  /// The list of imports in the library.
-  set imports(List<ExistingImport> value) {
-    assert(value != null);
-    _imports = value;
-  }
-
-  ExistingImports(ImportedElementSet elements, List<ExistingImport> imports) {
-    this.elements = elements;
-    this.imports = imports;
-  }
+  ExistingImports(this.elements, this.imports);
 
   factory ExistingImports.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       ImportedElementSet elements;
@@ -12270,7 +9877,7 @@
         imports = jsonDecoder.decodeList(
             jsonPath + '.imports',
             json['imports'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 ExistingImport.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'imports');
@@ -12282,8 +9889,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['elements'] = elements.toJson();
     result['imports'] =
         imports.map((ExistingImport value) => value.toJson()).toList();
@@ -12324,94 +9931,42 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class ExtractLocalVariableFeedback extends RefactoringFeedback {
-  List<int> _coveringExpressionOffsets;
-
-  List<int> _coveringExpressionLengths;
-
-  List<String> _names;
-
-  List<int> _offsets;
-
-  List<int> _lengths;
-
   /// The offsets of the expressions that cover the specified selection, from
   /// the down most to the up most.
-  List<int> get coveringExpressionOffsets => _coveringExpressionOffsets;
-
-  /// The offsets of the expressions that cover the specified selection, from
-  /// the down most to the up most.
-  set coveringExpressionOffsets(List<int> value) {
-    _coveringExpressionOffsets = value;
-  }
+  List<int>? coveringExpressionOffsets;
 
   /// The lengths of the expressions that cover the specified selection, from
   /// the down most to the up most.
-  List<int> get coveringExpressionLengths => _coveringExpressionLengths;
-
-  /// The lengths of the expressions that cover the specified selection, from
-  /// the down most to the up most.
-  set coveringExpressionLengths(List<int> value) {
-    _coveringExpressionLengths = value;
-  }
+  List<int>? coveringExpressionLengths;
 
   /// The proposed names for the local variable.
-  List<String> get names => _names;
-
-  /// The proposed names for the local variable.
-  set names(List<String> value) {
-    assert(value != null);
-    _names = value;
-  }
+  List<String> names;
 
   /// The offsets of the expressions that would be replaced by a reference to
   /// the variable.
-  List<int> get offsets => _offsets;
-
-  /// The offsets of the expressions that would be replaced by a reference to
-  /// the variable.
-  set offsets(List<int> value) {
-    assert(value != null);
-    _offsets = value;
-  }
+  List<int> offsets;
 
   /// The lengths of the expressions that would be replaced by a reference to
   /// the variable. The lengths correspond to the offsets. In other words, for
   /// a given expression, if the offset of that expression is offsets[i], then
   /// the length of that expression is lengths[i].
-  List<int> get lengths => _lengths;
+  List<int> lengths;
 
-  /// The lengths of the expressions that would be replaced by a reference to
-  /// the variable. The lengths correspond to the offsets. In other words, for
-  /// a given expression, if the offset of that expression is offsets[i], then
-  /// the length of that expression is lengths[i].
-  set lengths(List<int> value) {
-    assert(value != null);
-    _lengths = value;
-  }
-
-  ExtractLocalVariableFeedback(
-      List<String> names, List<int> offsets, List<int> lengths,
-      {List<int> coveringExpressionOffsets,
-      List<int> coveringExpressionLengths}) {
-    this.coveringExpressionOffsets = coveringExpressionOffsets;
-    this.coveringExpressionLengths = coveringExpressionLengths;
-    this.names = names;
-    this.offsets = offsets;
-    this.lengths = lengths;
-  }
+  ExtractLocalVariableFeedback(this.names, this.offsets, this.lengths,
+      {this.coveringExpressionOffsets, this.coveringExpressionLengths});
 
   factory ExtractLocalVariableFeedback.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
-      List<int> coveringExpressionOffsets;
+      List<int>? coveringExpressionOffsets;
       if (json.containsKey('coveringExpressionOffsets')) {
         coveringExpressionOffsets = jsonDecoder.decodeList(
             jsonPath + '.coveringExpressionOffsets',
             json['coveringExpressionOffsets'],
             jsonDecoder.decodeInt);
       }
-      List<int> coveringExpressionLengths;
+      List<int>? coveringExpressionLengths;
       if (json.containsKey('coveringExpressionLengths')) {
         coveringExpressionLengths = jsonDecoder.decodeList(
             jsonPath + '.coveringExpressionLengths',
@@ -12449,11 +10004,13 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
+    var coveringExpressionOffsets = this.coveringExpressionOffsets;
     if (coveringExpressionOffsets != null) {
       result['coveringExpressionOffsets'] = coveringExpressionOffsets;
     }
+    var coveringExpressionLengths = this.coveringExpressionLengths;
     if (coveringExpressionLengths != null) {
       result['coveringExpressionLengths'] = coveringExpressionLengths;
     }
@@ -12501,41 +10058,19 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class ExtractLocalVariableOptions extends RefactoringOptions {
-  String _name;
-
-  bool _extractAll;
-
   /// The name that the local variable should be given.
-  String get name => _name;
-
-  /// The name that the local variable should be given.
-  set name(String value) {
-    assert(value != null);
-    _name = value;
-  }
+  String name;
 
   /// True if all occurrences of the expression within the scope in which the
   /// variable will be defined should be replaced by a reference to the local
   /// variable. The expression used to initiate the refactoring will always be
   /// replaced.
-  bool get extractAll => _extractAll;
+  bool extractAll;
 
-  /// True if all occurrences of the expression within the scope in which the
-  /// variable will be defined should be replaced by a reference to the local
-  /// variable. The expression used to initiate the refactoring will always be
-  /// replaced.
-  set extractAll(bool value) {
-    assert(value != null);
-    _extractAll = value;
-  }
-
-  ExtractLocalVariableOptions(String name, bool extractAll) {
-    this.name = name;
-    this.extractAll = extractAll;
-  }
+  ExtractLocalVariableOptions(this.name, this.extractAll);
 
   factory ExtractLocalVariableOptions.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String name;
@@ -12565,8 +10100,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['name'] = name;
     result['extractAll'] = extractAll;
     return result;
@@ -12607,129 +10142,42 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class ExtractMethodFeedback extends RefactoringFeedback {
-  int _offset;
-
-  int _length;
-
-  String _returnType;
-
-  List<String> _names;
-
-  bool _canCreateGetter;
-
-  List<RefactoringMethodParameter> _parameters;
-
-  List<int> _offsets;
-
-  List<int> _lengths;
-
   /// The offset to the beginning of the expression or statements that will be
   /// extracted.
-  int get offset => _offset;
-
-  /// The offset to the beginning of the expression or statements that will be
-  /// extracted.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
+  int offset;
 
   /// The length of the expression or statements that will be extracted.
-  int get length => _length;
-
-  /// The length of the expression or statements that will be extracted.
-  set length(int value) {
-    assert(value != null);
-    _length = value;
-  }
+  int length;
 
   /// The proposed return type for the method. If the returned element does not
   /// have a declared return type, this field will contain an empty string.
-  String get returnType => _returnType;
-
-  /// The proposed return type for the method. If the returned element does not
-  /// have a declared return type, this field will contain an empty string.
-  set returnType(String value) {
-    assert(value != null);
-    _returnType = value;
-  }
+  String returnType;
 
   /// The proposed names for the method.
-  List<String> get names => _names;
-
-  /// The proposed names for the method.
-  set names(List<String> value) {
-    assert(value != null);
-    _names = value;
-  }
+  List<String> names;
 
   /// True if a getter could be created rather than a method.
-  bool get canCreateGetter => _canCreateGetter;
-
-  /// True if a getter could be created rather than a method.
-  set canCreateGetter(bool value) {
-    assert(value != null);
-    _canCreateGetter = value;
-  }
+  bool canCreateGetter;
 
   /// The proposed parameters for the method.
-  List<RefactoringMethodParameter> get parameters => _parameters;
-
-  /// The proposed parameters for the method.
-  set parameters(List<RefactoringMethodParameter> value) {
-    assert(value != null);
-    _parameters = value;
-  }
+  List<RefactoringMethodParameter> parameters;
 
   /// The offsets of the expressions or statements that would be replaced by an
   /// invocation of the method.
-  List<int> get offsets => _offsets;
-
-  /// The offsets of the expressions or statements that would be replaced by an
-  /// invocation of the method.
-  set offsets(List<int> value) {
-    assert(value != null);
-    _offsets = value;
-  }
+  List<int> offsets;
 
   /// The lengths of the expressions or statements that would be replaced by an
   /// invocation of the method. The lengths correspond to the offsets. In other
   /// words, for a given expression (or block of statements), if the offset of
   /// that expression is offsets[i], then the length of that expression is
   /// lengths[i].
-  List<int> get lengths => _lengths;
+  List<int> lengths;
 
-  /// The lengths of the expressions or statements that would be replaced by an
-  /// invocation of the method. The lengths correspond to the offsets. In other
-  /// words, for a given expression (or block of statements), if the offset of
-  /// that expression is offsets[i], then the length of that expression is
-  /// lengths[i].
-  set lengths(List<int> value) {
-    assert(value != null);
-    _lengths = value;
-  }
-
-  ExtractMethodFeedback(
-      int offset,
-      int length,
-      String returnType,
-      List<String> names,
-      bool canCreateGetter,
-      List<RefactoringMethodParameter> parameters,
-      List<int> offsets,
-      List<int> lengths) {
-    this.offset = offset;
-    this.length = length;
-    this.returnType = returnType;
-    this.names = names;
-    this.canCreateGetter = canCreateGetter;
-    this.parameters = parameters;
-    this.offsets = offsets;
-    this.lengths = lengths;
-  }
+  ExtractMethodFeedback(this.offset, this.length, this.returnType, this.names,
+      this.canCreateGetter, this.parameters, this.offsets, this.lengths);
 
   factory ExtractMethodFeedback.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       int offset;
@@ -12770,7 +10218,7 @@
         parameters = jsonDecoder.decodeList(
             jsonPath + '.parameters',
             json['parameters'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 RefactoringMethodParameter.fromJson(
                     jsonDecoder, jsonPath, json));
       } else {
@@ -12798,8 +10246,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['offset'] = offset;
     result['length'] = length;
     result['returnType'] = returnType;
@@ -12862,44 +10310,15 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class ExtractMethodOptions extends RefactoringOptions {
-  String _returnType;
-
-  bool _createGetter;
-
-  String _name;
-
-  List<RefactoringMethodParameter> _parameters;
-
-  bool _extractAll;
-
   /// The return type that should be defined for the method.
-  String get returnType => _returnType;
-
-  /// The return type that should be defined for the method.
-  set returnType(String value) {
-    assert(value != null);
-    _returnType = value;
-  }
+  String returnType;
 
   /// True if a getter should be created rather than a method. It is an error
   /// if this field is true and the list of parameters is non-empty.
-  bool get createGetter => _createGetter;
-
-  /// True if a getter should be created rather than a method. It is an error
-  /// if this field is true and the list of parameters is non-empty.
-  set createGetter(bool value) {
-    assert(value != null);
-    _createGetter = value;
-  }
+  bool createGetter;
 
   /// The name that the method should be given.
-  String get name => _name;
-
-  /// The name that the method should be given.
-  set name(String value) {
-    assert(value != null);
-    _name = value;
-  }
+  String name;
 
   /// The parameters that should be defined for the method.
   ///
@@ -12911,47 +10330,18 @@
   ///   with the same identifiers as proposed.
   /// - To add new parameters, omit their identifier.
   /// - To remove some parameters, omit them in this list.
-  List<RefactoringMethodParameter> get parameters => _parameters;
-
-  /// The parameters that should be defined for the method.
-  ///
-  /// It is an error if a REQUIRED or NAMED parameter follows a POSITIONAL
-  /// parameter. It is an error if a REQUIRED or POSITIONAL parameter follows a
-  /// NAMED parameter.
-  ///
-  /// - To change the order and/or update proposed parameters, add parameters
-  ///   with the same identifiers as proposed.
-  /// - To add new parameters, omit their identifier.
-  /// - To remove some parameters, omit them in this list.
-  set parameters(List<RefactoringMethodParameter> value) {
-    assert(value != null);
-    _parameters = value;
-  }
+  List<RefactoringMethodParameter> parameters;
 
   /// True if all occurrences of the expression or statements should be
   /// replaced by an invocation of the method. The expression or statements
   /// used to initiate the refactoring will always be replaced.
-  bool get extractAll => _extractAll;
+  bool extractAll;
 
-  /// True if all occurrences of the expression or statements should be
-  /// replaced by an invocation of the method. The expression or statements
-  /// used to initiate the refactoring will always be replaced.
-  set extractAll(bool value) {
-    assert(value != null);
-    _extractAll = value;
-  }
-
-  ExtractMethodOptions(String returnType, bool createGetter, String name,
-      List<RefactoringMethodParameter> parameters, bool extractAll) {
-    this.returnType = returnType;
-    this.createGetter = createGetter;
-    this.name = name;
-    this.parameters = parameters;
-    this.extractAll = extractAll;
-  }
+  ExtractMethodOptions(this.returnType, this.createGetter, this.name,
+      this.parameters, this.extractAll);
 
   factory ExtractMethodOptions.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String returnType;
@@ -12979,7 +10369,7 @@
         parameters = jsonDecoder.decodeList(
             jsonPath + '.parameters',
             json['parameters'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 RefactoringMethodParameter.fromJson(
                     jsonDecoder, jsonPath, json));
       } else {
@@ -13006,8 +10396,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['returnType'] = returnType;
     result['createGetter'] = createGetter;
     result['name'] = name;
@@ -13059,7 +10449,7 @@
   ExtractWidgetFeedback();
 
   factory ExtractWidgetFeedback.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       return ExtractWidgetFeedback();
@@ -13069,8 +10459,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     return result;
   }
 
@@ -13100,23 +10490,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class ExtractWidgetOptions extends RefactoringOptions {
-  String _name;
-
   /// The name that the widget class should be given.
-  String get name => _name;
+  String name;
 
-  /// The name that the widget class should be given.
-  set name(String value) {
-    assert(value != null);
-    _name = value;
-  }
-
-  ExtractWidgetOptions(String name) {
-    this.name = name;
-  }
+  ExtractWidgetOptions(this.name);
 
   factory ExtractWidgetOptions.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String name;
@@ -13138,8 +10518,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['name'] = name;
     return result;
   }
@@ -13195,7 +10575,7 @@
   }
 
   factory FileKind.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     if (json is String) {
       try {
         return FileKind(json);
@@ -13221,35 +10601,16 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class FlutterGetWidgetDescriptionParams implements RequestParams {
-  String _file;
-
-  int _offset;
-
   /// The file where the widget instance is created.
-  String get file => _file;
-
-  /// The file where the widget instance is created.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// The offset in the file where the widget instance is created.
-  int get offset => _offset;
+  int offset;
 
-  /// The offset in the file where the widget instance is created.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
-
-  FlutterGetWidgetDescriptionParams(String file, int offset) {
-    this.file = file;
-    this.offset = offset;
-  }
+  FlutterGetWidgetDescriptionParams(this.file, this.offset);
 
   factory FlutterGetWidgetDescriptionParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -13277,8 +10638,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     result['offset'] = offset;
     return result;
@@ -13317,29 +10678,16 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class FlutterGetWidgetDescriptionResult implements ResponseResult {
-  List<FlutterWidgetProperty> _properties;
-
   /// The list of properties of the widget. Some of the properties might be
   /// read only, when their editor is not set. This might be because they have
   /// type that we don't know how to edit, or for compound properties that work
   /// as containers for sub-properties.
-  List<FlutterWidgetProperty> get properties => _properties;
+  List<FlutterWidgetProperty> properties;
 
-  /// The list of properties of the widget. Some of the properties might be
-  /// read only, when their editor is not set. This might be because they have
-  /// type that we don't know how to edit, or for compound properties that work
-  /// as containers for sub-properties.
-  set properties(List<FlutterWidgetProperty> value) {
-    assert(value != null);
-    _properties = value;
-  }
-
-  FlutterGetWidgetDescriptionResult(List<FlutterWidgetProperty> properties) {
-    this.properties = properties;
-  }
+  FlutterGetWidgetDescriptionResult(this.properties);
 
   factory FlutterGetWidgetDescriptionResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       List<FlutterWidgetProperty> properties;
@@ -13347,7 +10695,7 @@
         properties = jsonDecoder.decodeList(
             jsonPath + '.properties',
             json['properties'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 FlutterWidgetProperty.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'properties');
@@ -13367,8 +10715,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['properties'] = properties
         .map((FlutterWidgetProperty value) => value.toJson())
         .toList();
@@ -13419,178 +10767,65 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class FlutterOutline implements HasToJson {
-  FlutterOutlineKind _kind;
-
-  int _offset;
-
-  int _length;
-
-  int _codeOffset;
-
-  int _codeLength;
-
-  String _label;
-
-  Element _dartElement;
-
-  List<FlutterOutlineAttribute> _attributes;
-
-  String _className;
-
-  String _parentAssociationLabel;
-
-  String _variableName;
-
-  List<FlutterOutline> _children;
-
   /// The kind of the node.
-  FlutterOutlineKind get kind => _kind;
-
-  /// The kind of the node.
-  set kind(FlutterOutlineKind value) {
-    assert(value != null);
-    _kind = value;
-  }
+  FlutterOutlineKind kind;
 
   /// 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.
-  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.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
+  int offset;
 
   /// The length of the element.
-  int get length => _length;
-
-  /// The length of the element.
-  set length(int value) {
-    assert(value != null);
-    _length = value;
-  }
+  int length;
 
   /// The offset of the first character of the element code, which is neither
   /// documentation, nor annotation.
-  int get codeOffset => _codeOffset;
-
-  /// The offset of the first character of the element code, which is neither
-  /// documentation, nor annotation.
-  set codeOffset(int value) {
-    assert(value != null);
-    _codeOffset = value;
-  }
+  int codeOffset;
 
   /// The length of the element code.
-  int get codeLength => _codeLength;
-
-  /// The length of the element code.
-  set codeLength(int value) {
-    assert(value != null);
-    _codeLength = value;
-  }
+  int codeLength;
 
   /// The text label of the node children of the node. It is provided for any
   /// FlutterOutlineKind.GENERIC node, where better information is not
   /// available.
-  String get label => _label;
-
-  /// The text label of the node children of the node. It is provided for any
-  /// FlutterOutlineKind.GENERIC node, where better information is not
-  /// available.
-  set label(String value) {
-    _label = value;
-  }
+  String? label;
 
   /// If this node is a Dart element, the description of it; omitted otherwise.
-  Element get dartElement => _dartElement;
-
-  /// If this node is a Dart element, the description of it; omitted otherwise.
-  set dartElement(Element value) {
-    _dartElement = value;
-  }
+  Element? dartElement;
 
   /// Additional attributes for this node, which might be interesting to
   /// display on the client. These attributes are usually arguments for the
   /// instance creation or the invocation that created the widget.
-  List<FlutterOutlineAttribute> get attributes => _attributes;
-
-  /// Additional attributes for this node, which might be interesting to
-  /// display on the client. These attributes are usually arguments for the
-  /// instance creation or the invocation that created the widget.
-  set attributes(List<FlutterOutlineAttribute> value) {
-    _attributes = value;
-  }
+  List<FlutterOutlineAttribute>? attributes;
 
   /// If the node creates a new class instance, or a reference to an instance,
   /// this field has the name of the class.
-  String get className => _className;
-
-  /// If the node creates a new class instance, or a reference to an instance,
-  /// this field has the name of the class.
-  set className(String value) {
-    _className = value;
-  }
+  String? className;
 
   /// A short text description how this node is associated with the parent
   /// node. For example "appBar" or "body" in Scaffold.
-  String get parentAssociationLabel => _parentAssociationLabel;
-
-  /// A short text description how this node is associated with the parent
-  /// node. For example "appBar" or "body" in Scaffold.
-  set parentAssociationLabel(String value) {
-    _parentAssociationLabel = value;
-  }
+  String? parentAssociationLabel;
 
   /// If FlutterOutlineKind.VARIABLE, the name of the variable.
-  String get variableName => _variableName;
-
-  /// If FlutterOutlineKind.VARIABLE, the name of the variable.
-  set variableName(String value) {
-    _variableName = value;
-  }
+  String? variableName;
 
   /// The children of the node. The field will be omitted if the node has no
   /// children.
-  List<FlutterOutline> get children => _children;
+  List<FlutterOutline>? children;
 
-  /// The children of the node. The field will be omitted if the node has no
-  /// children.
-  set children(List<FlutterOutline> value) {
-    _children = value;
-  }
-
-  FlutterOutline(FlutterOutlineKind kind, int offset, int length,
-      int codeOffset, int codeLength,
-      {String label,
-      Element dartElement,
-      List<FlutterOutlineAttribute> attributes,
-      String className,
-      String parentAssociationLabel,
-      String variableName,
-      List<FlutterOutline> children}) {
-    this.kind = kind;
-    this.offset = offset;
-    this.length = length;
-    this.codeOffset = codeOffset;
-    this.codeLength = codeLength;
-    this.label = label;
-    this.dartElement = dartElement;
-    this.attributes = attributes;
-    this.className = className;
-    this.parentAssociationLabel = parentAssociationLabel;
-    this.variableName = variableName;
-    this.children = children;
-  }
+  FlutterOutline(
+      this.kind, this.offset, this.length, this.codeOffset, this.codeLength,
+      {this.label,
+      this.dartElement,
+      this.attributes,
+      this.className,
+      this.parentAssociationLabel,
+      this.variableName,
+      this.children});
 
   factory FlutterOutline.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       FlutterOutlineKind kind;
@@ -13626,45 +10861,45 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'codeLength');
       }
-      String label;
+      String? label;
       if (json.containsKey('label')) {
         label = jsonDecoder.decodeString(jsonPath + '.label', json['label']);
       }
-      Element dartElement;
+      Element? dartElement;
       if (json.containsKey('dartElement')) {
         dartElement = Element.fromJson(
             jsonDecoder, jsonPath + '.dartElement', json['dartElement']);
       }
-      List<FlutterOutlineAttribute> attributes;
+      List<FlutterOutlineAttribute>? attributes;
       if (json.containsKey('attributes')) {
         attributes = jsonDecoder.decodeList(
             jsonPath + '.attributes',
             json['attributes'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 FlutterOutlineAttribute.fromJson(jsonDecoder, jsonPath, json));
       }
-      String className;
+      String? className;
       if (json.containsKey('className')) {
         className = jsonDecoder.decodeString(
             jsonPath + '.className', json['className']);
       }
-      String parentAssociationLabel;
+      String? parentAssociationLabel;
       if (json.containsKey('parentAssociationLabel')) {
         parentAssociationLabel = jsonDecoder.decodeString(
             jsonPath + '.parentAssociationLabel',
             json['parentAssociationLabel']);
       }
-      String variableName;
+      String? variableName;
       if (json.containsKey('variableName')) {
         variableName = jsonDecoder.decodeString(
             jsonPath + '.variableName', json['variableName']);
       }
-      List<FlutterOutline> children;
+      List<FlutterOutline>? children;
       if (json.containsKey('children')) {
         children = jsonDecoder.decodeList(
             jsonPath + '.children',
             json['children'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 FlutterOutline.fromJson(jsonDecoder, jsonPath, json));
       }
       return FlutterOutline(kind, offset, length, codeOffset, codeLength,
@@ -13681,33 +10916,40 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['kind'] = kind.toJson();
     result['offset'] = offset;
     result['length'] = length;
     result['codeOffset'] = codeOffset;
     result['codeLength'] = codeLength;
+    var label = this.label;
     if (label != null) {
       result['label'] = label;
     }
+    var dartElement = this.dartElement;
     if (dartElement != null) {
       result['dartElement'] = dartElement.toJson();
     }
+    var attributes = this.attributes;
     if (attributes != null) {
       result['attributes'] = attributes
           .map((FlutterOutlineAttribute value) => value.toJson())
           .toList();
     }
+    var className = this.className;
     if (className != null) {
       result['className'] = className;
     }
+    var parentAssociationLabel = this.parentAssociationLabel;
     if (parentAssociationLabel != null) {
       result['parentAssociationLabel'] = parentAssociationLabel;
     }
+    var variableName = this.variableName;
     if (variableName != null) {
       result['variableName'] = variableName;
     }
+    var children = this.children;
     if (children != null) {
       result['children'] =
           children.map((FlutterOutline value) => value.toJson()).toList();
@@ -13775,111 +11017,44 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class FlutterOutlineAttribute implements HasToJson {
-  String _name;
-
-  String _label;
-
-  bool _literalValueBoolean;
-
-  int _literalValueInteger;
-
-  String _literalValueString;
-
-  Location _nameLocation;
-
-  Location _valueLocation;
-
   /// The name of the attribute.
-  String get name => _name;
-
-  /// The name of the attribute.
-  set name(String value) {
-    assert(value != null);
-    _name = value;
-  }
+  String name;
 
   /// The label of the attribute value, usually the Dart code. It might be
   /// quite long, the client should abbreviate as needed.
-  String get label => _label;
-
-  /// The label of the attribute value, usually the Dart code. It might be
-  /// quite long, the client should abbreviate as needed.
-  set label(String value) {
-    assert(value != null);
-    _label = value;
-  }
+  String label;
 
   /// The boolean literal value of the attribute. This field is absent if the
   /// value is not a boolean literal.
-  bool get literalValueBoolean => _literalValueBoolean;
-
-  /// The boolean literal value of the attribute. This field is absent if the
-  /// value is not a boolean literal.
-  set literalValueBoolean(bool value) {
-    _literalValueBoolean = value;
-  }
+  bool? literalValueBoolean;
 
   /// The integer literal value of the attribute. This field is absent if the
   /// value is not an integer literal.
-  int get literalValueInteger => _literalValueInteger;
-
-  /// The integer literal value of the attribute. This field is absent if the
-  /// value is not an integer literal.
-  set literalValueInteger(int value) {
-    _literalValueInteger = value;
-  }
+  int? literalValueInteger;
 
   /// The string literal value of the attribute. This field is absent if the
   /// value is not a string literal.
-  String get literalValueString => _literalValueString;
-
-  /// The string literal value of the attribute. This field is absent if the
-  /// value is not a string literal.
-  set literalValueString(String value) {
-    _literalValueString = value;
-  }
+  String? literalValueString;
 
   /// If the attribute is a named argument, the location of the name, without
   /// the colon.
-  Location get nameLocation => _nameLocation;
-
-  /// If the attribute is a named argument, the location of the name, without
-  /// the colon.
-  set nameLocation(Location value) {
-    _nameLocation = value;
-  }
+  Location? nameLocation;
 
   /// The location of the value.
   ///
   /// This field is always available, but marked optional for backward
   /// compatibility between new clients with older servers.
-  Location get valueLocation => _valueLocation;
+  Location? valueLocation;
 
-  /// The location of the value.
-  ///
-  /// This field is always available, but marked optional for backward
-  /// compatibility between new clients with older servers.
-  set valueLocation(Location value) {
-    _valueLocation = value;
-  }
-
-  FlutterOutlineAttribute(String name, String label,
-      {bool literalValueBoolean,
-      int literalValueInteger,
-      String literalValueString,
-      Location nameLocation,
-      Location valueLocation}) {
-    this.name = name;
-    this.label = label;
-    this.literalValueBoolean = literalValueBoolean;
-    this.literalValueInteger = literalValueInteger;
-    this.literalValueString = literalValueString;
-    this.nameLocation = nameLocation;
-    this.valueLocation = valueLocation;
-  }
+  FlutterOutlineAttribute(this.name, this.label,
+      {this.literalValueBoolean,
+      this.literalValueInteger,
+      this.literalValueString,
+      this.nameLocation,
+      this.valueLocation});
 
   factory FlutterOutlineAttribute.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String name;
@@ -13894,27 +11069,27 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'label');
       }
-      bool literalValueBoolean;
+      bool? literalValueBoolean;
       if (json.containsKey('literalValueBoolean')) {
         literalValueBoolean = jsonDecoder.decodeBool(
             jsonPath + '.literalValueBoolean', json['literalValueBoolean']);
       }
-      int literalValueInteger;
+      int? literalValueInteger;
       if (json.containsKey('literalValueInteger')) {
         literalValueInteger = jsonDecoder.decodeInt(
             jsonPath + '.literalValueInteger', json['literalValueInteger']);
       }
-      String literalValueString;
+      String? literalValueString;
       if (json.containsKey('literalValueString')) {
         literalValueString = jsonDecoder.decodeString(
             jsonPath + '.literalValueString', json['literalValueString']);
       }
-      Location nameLocation;
+      Location? nameLocation;
       if (json.containsKey('nameLocation')) {
         nameLocation = Location.fromJson(
             jsonDecoder, jsonPath + '.nameLocation', json['nameLocation']);
       }
-      Location valueLocation;
+      Location? valueLocation;
       if (json.containsKey('valueLocation')) {
         valueLocation = Location.fromJson(
             jsonDecoder, jsonPath + '.valueLocation', json['valueLocation']);
@@ -13931,22 +11106,27 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['name'] = name;
     result['label'] = label;
+    var literalValueBoolean = this.literalValueBoolean;
     if (literalValueBoolean != null) {
       result['literalValueBoolean'] = literalValueBoolean;
     }
+    var literalValueInteger = this.literalValueInteger;
     if (literalValueInteger != null) {
       result['literalValueInteger'] = literalValueInteger;
     }
+    var literalValueString = this.literalValueString;
     if (literalValueString != null) {
       result['literalValueString'] = literalValueString;
     }
+    var nameLocation = this.nameLocation;
     if (nameLocation != null) {
       result['nameLocation'] = nameLocation.toJson();
     }
+    var valueLocation = this.valueLocation;
     if (valueLocation != null) {
       result['valueLocation'] = valueLocation.toJson();
     }
@@ -14055,7 +11235,7 @@
   }
 
   factory FlutterOutlineKind.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     if (json is String) {
       try {
         return FlutterOutlineKind(json);
@@ -14081,35 +11261,16 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class FlutterOutlineParams implements HasToJson {
-  String _file;
-
-  FlutterOutline _outline;
-
   /// The file with which the outline is associated.
-  String get file => _file;
-
-  /// The file with which the outline is associated.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// The outline associated with the file.
-  FlutterOutline get outline => _outline;
+  FlutterOutline outline;
 
-  /// The outline associated with the file.
-  set outline(FlutterOutline value) {
-    assert(value != null);
-    _outline = value;
-  }
-
-  FlutterOutlineParams(String file, FlutterOutline outline) {
-    this.file = file;
-    this.outline = outline;
-  }
+  FlutterOutlineParams(this.file, this.outline);
 
   factory FlutterOutlineParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -14137,8 +11298,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     result['outline'] = outline.toJson();
     return result;
@@ -14195,7 +11356,7 @@
   }
 
   factory FlutterService.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     if (json is String) {
       try {
         return FlutterService(json);
@@ -14220,35 +11381,23 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class FlutterSetSubscriptionsParams implements RequestParams {
-  Map<FlutterService, List<String>> _subscriptions;
-
   /// A table mapping services to a list of the files being subscribed to the
   /// service.
-  Map<FlutterService, List<String>> get subscriptions => _subscriptions;
+  Map<FlutterService, List<String>> subscriptions;
 
-  /// A table mapping services to a list of the files being subscribed to the
-  /// service.
-  set subscriptions(Map<FlutterService, List<String>> value) {
-    assert(value != null);
-    _subscriptions = value;
-  }
-
-  FlutterSetSubscriptionsParams(
-      Map<FlutterService, List<String>> subscriptions) {
-    this.subscriptions = subscriptions;
-  }
+  FlutterSetSubscriptionsParams(this.subscriptions);
 
   factory FlutterSetSubscriptionsParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       Map<FlutterService, List<String>> subscriptions;
       if (json.containsKey('subscriptions')) {
         subscriptions = jsonDecoder.decodeMap(
             jsonPath + '.subscriptions', json['subscriptions'],
-            keyDecoder: (String jsonPath, Object json) =>
+            keyDecoder: (String jsonPath, Object? json) =>
                 FlutterService.fromJson(jsonDecoder, jsonPath, json),
-            valueDecoder: (String jsonPath, Object json) => jsonDecoder
+            valueDecoder: (String jsonPath, Object? json) => jsonDecoder
                 .decodeList(jsonPath, json, jsonDecoder.decodeString));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'subscriptions');
@@ -14266,8 +11415,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['subscriptions'] = mapMap(subscriptions,
         keyCallback: (FlutterService value) => value.toJson());
     return result;
@@ -14306,7 +11455,7 @@
 /// Clients may not extend, implement or mix-in this class.
 class FlutterSetSubscriptionsResult implements ResponseResult {
   @override
-  Map<String, dynamic> toJson() => <String, dynamic>{};
+  Map<String, Object> toJson() => <String, Object>{};
 
   @override
   Response toResponse(String id) {
@@ -14336,26 +11485,12 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class FlutterSetWidgetPropertyValueParams implements RequestParams {
-  int _id;
-
-  FlutterWidgetPropertyValue _value;
-
   /// The identifier of the property, previously returned as a part of a
   /// FlutterWidgetProperty.
   ///
   /// An error of type FLUTTER_SET_WIDGET_PROPERTY_VALUE_INVALID_ID is
   /// generated if the identifier is not valid.
-  int get id => _id;
-
-  /// The identifier of the property, previously returned as a part of a
-  /// FlutterWidgetProperty.
-  ///
-  /// An error of type FLUTTER_SET_WIDGET_PROPERTY_VALUE_INVALID_ID is
-  /// generated if the identifier is not valid.
-  set id(int value) {
-    assert(value != null);
-    _id = value;
-  }
+  int id;
 
   /// The new value to set for the property.
   ///
@@ -14366,29 +11501,12 @@
   ///
   /// If the expression is not a syntactically valid Dart code, then
   /// FLUTTER_SET_WIDGET_PROPERTY_VALUE_INVALID_EXPRESSION is reported.
-  FlutterWidgetPropertyValue get value => _value;
+  FlutterWidgetPropertyValue? value;
 
-  /// The new value to set for the property.
-  ///
-  /// If absent, indicates that the property should be removed. If the property
-  /// corresponds to an optional parameter, the corresponding named argument is
-  /// removed. If the property isRequired is true,
-  /// FLUTTER_SET_WIDGET_PROPERTY_VALUE_IS_REQUIRED error is generated.
-  ///
-  /// If the expression is not a syntactically valid Dart code, then
-  /// FLUTTER_SET_WIDGET_PROPERTY_VALUE_INVALID_EXPRESSION is reported.
-  set value(FlutterWidgetPropertyValue value) {
-    _value = value;
-  }
-
-  FlutterSetWidgetPropertyValueParams(int id,
-      {FlutterWidgetPropertyValue value}) {
-    this.id = id;
-    this.value = value;
-  }
+  FlutterSetWidgetPropertyValueParams(this.id, {this.value});
 
   factory FlutterSetWidgetPropertyValueParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       int id;
@@ -14397,7 +11515,7 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'id');
       }
-      FlutterWidgetPropertyValue value;
+      FlutterWidgetPropertyValue? value;
       if (json.containsKey('value')) {
         value = FlutterWidgetPropertyValue.fromJson(
             jsonDecoder, jsonPath + '.value', json['value']);
@@ -14415,9 +11533,10 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['id'] = id;
+    var value = this.value;
     if (value != null) {
       result['value'] = value.toJson();
     }
@@ -14457,23 +11576,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class FlutterSetWidgetPropertyValueResult implements ResponseResult {
-  SourceChange _change;
-
   /// The change that should be applied.
-  SourceChange get change => _change;
+  SourceChange change;
 
-  /// The change that should be applied.
-  set change(SourceChange value) {
-    assert(value != null);
-    _change = value;
-  }
-
-  FlutterSetWidgetPropertyValueResult(SourceChange change) {
-    this.change = change;
-  }
+  FlutterSetWidgetPropertyValueResult(this.change);
 
   factory FlutterSetWidgetPropertyValueResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       SourceChange change;
@@ -14498,8 +11607,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['change'] = change.toJson();
     return result;
   }
@@ -14544,158 +11653,66 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class FlutterWidgetProperty implements HasToJson {
-  String _documentation;
-
-  String _expression;
-
-  int _id;
-
-  bool _isRequired;
-
-  bool _isSafeToUpdate;
-
-  String _name;
-
-  List<FlutterWidgetProperty> _children;
-
-  FlutterWidgetPropertyEditor _editor;
-
-  FlutterWidgetPropertyValue _value;
-
   /// The documentation of the property to show to the user. Omitted if the
   /// server does not know the documentation, e.g. because the corresponding
   /// field is not documented.
-  String get documentation => _documentation;
-
-  /// The documentation of the property to show to the user. Omitted if the
-  /// server does not know the documentation, e.g. because the corresponding
-  /// field is not documented.
-  set documentation(String value) {
-    _documentation = value;
-  }
+  String? documentation;
 
   /// If the value of this property is set, the Dart code of the expression of
   /// this property.
-  String get expression => _expression;
-
-  /// If the value of this property is set, the Dart code of the expression of
-  /// this property.
-  set expression(String value) {
-    _expression = value;
-  }
+  String? expression;
 
   /// The unique identifier of the property, must be passed back to the server
   /// when updating the property value. Identifiers become invalid on any
   /// source code change.
-  int get id => _id;
-
-  /// The unique identifier of the property, must be passed back to the server
-  /// when updating the property value. Identifiers become invalid on any
-  /// source code change.
-  set id(int value) {
-    assert(value != null);
-    _id = value;
-  }
+  int id;
 
   /// True if the property is required, e.g. because it corresponds to a
   /// required parameter of a constructor.
-  bool get isRequired => _isRequired;
-
-  /// True if the property is required, e.g. because it corresponds to a
-  /// required parameter of a constructor.
-  set isRequired(bool value) {
-    assert(value != null);
-    _isRequired = value;
-  }
+  bool isRequired;
 
   /// If the property expression is a concrete value (e.g. a literal, or an
   /// enum constant), then it is safe to replace the expression with another
   /// concrete value. In this case this field is true. Otherwise, for example
   /// when the expression is a reference to a field, so that its value is
   /// provided from outside, this field is false.
-  bool get isSafeToUpdate => _isSafeToUpdate;
-
-  /// If the property expression is a concrete value (e.g. a literal, or an
-  /// enum constant), then it is safe to replace the expression with another
-  /// concrete value. In this case this field is true. Otherwise, for example
-  /// when the expression is a reference to a field, so that its value is
-  /// provided from outside, this field is false.
-  set isSafeToUpdate(bool value) {
-    assert(value != null);
-    _isSafeToUpdate = value;
-  }
+  bool isSafeToUpdate;
 
   /// The name of the property to display to the user.
-  String get name => _name;
-
-  /// The name of the property to display to the user.
-  set name(String value) {
-    assert(value != null);
-    _name = value;
-  }
+  String name;
 
   /// The list of children properties, if any. For example any property of type
   /// EdgeInsets will have four children properties of type double - left / top
   /// / right / bottom.
-  List<FlutterWidgetProperty> get children => _children;
-
-  /// The list of children properties, if any. For example any property of type
-  /// EdgeInsets will have four children properties of type double - left / top
-  /// / right / bottom.
-  set children(List<FlutterWidgetProperty> value) {
-    _children = value;
-  }
+  List<FlutterWidgetProperty>? children;
 
   /// The editor that should be used by the client. This field is omitted if
   /// the server does not know the editor for this property, for example
   /// because it does not have one of the supported types.
-  FlutterWidgetPropertyEditor get editor => _editor;
-
-  /// The editor that should be used by the client. This field is omitted if
-  /// the server does not know the editor for this property, for example
-  /// because it does not have one of the supported types.
-  set editor(FlutterWidgetPropertyEditor value) {
-    _editor = value;
-  }
+  FlutterWidgetPropertyEditor? editor;
 
   /// If the expression is set, and the server knows the value of the
   /// expression, this field is set.
-  FlutterWidgetPropertyValue get value => _value;
-
-  /// If the expression is set, and the server knows the value of the
-  /// expression, this field is set.
-  set value(FlutterWidgetPropertyValue value) {
-    _value = value;
-  }
+  FlutterWidgetPropertyValue? value;
 
   FlutterWidgetProperty(
-      int id, bool isRequired, bool isSafeToUpdate, String name,
-      {String documentation,
-      String expression,
-      List<FlutterWidgetProperty> children,
-      FlutterWidgetPropertyEditor editor,
-      FlutterWidgetPropertyValue value}) {
-    this.documentation = documentation;
-    this.expression = expression;
-    this.id = id;
-    this.isRequired = isRequired;
-    this.isSafeToUpdate = isSafeToUpdate;
-    this.name = name;
-    this.children = children;
-    this.editor = editor;
-    this.value = value;
-  }
+      this.id, this.isRequired, this.isSafeToUpdate, this.name,
+      {this.documentation,
+      this.expression,
+      this.children,
+      this.editor,
+      this.value});
 
   factory FlutterWidgetProperty.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
-      String documentation;
+      String? documentation;
       if (json.containsKey('documentation')) {
         documentation = jsonDecoder.decodeString(
             jsonPath + '.documentation', json['documentation']);
       }
-      String expression;
+      String? expression;
       if (json.containsKey('expression')) {
         expression = jsonDecoder.decodeString(
             jsonPath + '.expression', json['expression']);
@@ -14726,20 +11743,20 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'name');
       }
-      List<FlutterWidgetProperty> children;
+      List<FlutterWidgetProperty>? children;
       if (json.containsKey('children')) {
         children = jsonDecoder.decodeList(
             jsonPath + '.children',
             json['children'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 FlutterWidgetProperty.fromJson(jsonDecoder, jsonPath, json));
       }
-      FlutterWidgetPropertyEditor editor;
+      FlutterWidgetPropertyEditor? editor;
       if (json.containsKey('editor')) {
         editor = FlutterWidgetPropertyEditor.fromJson(
             jsonDecoder, jsonPath + '.editor', json['editor']);
       }
-      FlutterWidgetPropertyValue value;
+      FlutterWidgetPropertyValue? value;
       if (json.containsKey('value')) {
         value = FlutterWidgetPropertyValue.fromJson(
             jsonDecoder, jsonPath + '.value', json['value']);
@@ -14756,11 +11773,13 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
+    var documentation = this.documentation;
     if (documentation != null) {
       result['documentation'] = documentation;
     }
+    var expression = this.expression;
     if (expression != null) {
       result['expression'] = expression;
     }
@@ -14768,14 +11787,17 @@
     result['isRequired'] = isRequired;
     result['isSafeToUpdate'] = isSafeToUpdate;
     result['name'] = name;
+    var children = this.children;
     if (children != null) {
       result['children'] = children
           .map((FlutterWidgetProperty value) => value.toJson())
           .toList();
     }
+    var editor = this.editor;
     if (editor != null) {
       result['editor'] = editor.toJson();
     }
+    var value = this.value;
     if (value != null) {
       result['value'] = value.toJson();
     }
@@ -14827,31 +11849,14 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class FlutterWidgetPropertyEditor implements HasToJson {
-  FlutterWidgetPropertyEditorKind _kind;
+  FlutterWidgetPropertyEditorKind kind;
 
-  List<FlutterWidgetPropertyValueEnumItem> _enumItems;
+  List<FlutterWidgetPropertyValueEnumItem>? enumItems;
 
-  FlutterWidgetPropertyEditorKind get kind => _kind;
-
-  set kind(FlutterWidgetPropertyEditorKind value) {
-    assert(value != null);
-    _kind = value;
-  }
-
-  List<FlutterWidgetPropertyValueEnumItem> get enumItems => _enumItems;
-
-  set enumItems(List<FlutterWidgetPropertyValueEnumItem> value) {
-    _enumItems = value;
-  }
-
-  FlutterWidgetPropertyEditor(FlutterWidgetPropertyEditorKind kind,
-      {List<FlutterWidgetPropertyValueEnumItem> enumItems}) {
-    this.kind = kind;
-    this.enumItems = enumItems;
-  }
+  FlutterWidgetPropertyEditor(this.kind, {this.enumItems});
 
   factory FlutterWidgetPropertyEditor.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       FlutterWidgetPropertyEditorKind kind;
@@ -14861,12 +11866,12 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'kind');
       }
-      List<FlutterWidgetPropertyValueEnumItem> enumItems;
+      List<FlutterWidgetPropertyValueEnumItem>? enumItems;
       if (json.containsKey('enumItems')) {
         enumItems = jsonDecoder.decodeList(
             jsonPath + '.enumItems',
             json['enumItems'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 FlutterWidgetPropertyValueEnumItem.fromJson(
                     jsonDecoder, jsonPath, json));
       }
@@ -14877,9 +11882,10 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['kind'] = kind.toJson();
+    var enumItems = this.enumItems;
     if (enumItems != null) {
       result['enumItems'] = enumItems
           .map((FlutterWidgetPropertyValueEnumItem value) => value.toJson())
@@ -14989,7 +11995,7 @@
   }
 
   factory FlutterWidgetPropertyEditorKind.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     if (json is String) {
       try {
         return FlutterWidgetPropertyEditorKind(json);
@@ -15020,101 +12026,57 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class FlutterWidgetPropertyValue implements HasToJson {
-  bool _boolValue;
+  bool? boolValue;
 
-  double _doubleValue;
+  double? doubleValue;
 
-  int _intValue;
+  int? intValue;
 
-  String _stringValue;
+  String? stringValue;
 
-  FlutterWidgetPropertyValueEnumItem _enumValue;
-
-  String _expression;
-
-  bool get boolValue => _boolValue;
-
-  set boolValue(bool value) {
-    _boolValue = value;
-  }
-
-  double get doubleValue => _doubleValue;
-
-  set doubleValue(double value) {
-    _doubleValue = value;
-  }
-
-  int get intValue => _intValue;
-
-  set intValue(int value) {
-    _intValue = value;
-  }
-
-  String get stringValue => _stringValue;
-
-  set stringValue(String value) {
-    _stringValue = value;
-  }
-
-  FlutterWidgetPropertyValueEnumItem get enumValue => _enumValue;
-
-  set enumValue(FlutterWidgetPropertyValueEnumItem value) {
-    _enumValue = value;
-  }
+  FlutterWidgetPropertyValueEnumItem? enumValue;
 
   /// A free-form expression, which will be used as the value as is.
-  String get expression => _expression;
-
-  /// A free-form expression, which will be used as the value as is.
-  set expression(String value) {
-    _expression = value;
-  }
+  String? expression;
 
   FlutterWidgetPropertyValue(
-      {bool boolValue,
-      double doubleValue,
-      int intValue,
-      String stringValue,
-      FlutterWidgetPropertyValueEnumItem enumValue,
-      String expression}) {
-    this.boolValue = boolValue;
-    this.doubleValue = doubleValue;
-    this.intValue = intValue;
-    this.stringValue = stringValue;
-    this.enumValue = enumValue;
-    this.expression = expression;
-  }
+      {this.boolValue,
+      this.doubleValue,
+      this.intValue,
+      this.stringValue,
+      this.enumValue,
+      this.expression});
 
   factory FlutterWidgetPropertyValue.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
-      bool boolValue;
+      bool? boolValue;
       if (json.containsKey('boolValue')) {
         boolValue =
             jsonDecoder.decodeBool(jsonPath + '.boolValue', json['boolValue']);
       }
-      double doubleValue;
+      double? doubleValue;
       if (json.containsKey('doubleValue')) {
         doubleValue = jsonDecoder.decodeDouble(
             jsonPath + '.doubleValue', json['doubleValue']);
       }
-      int intValue;
+      int? intValue;
       if (json.containsKey('intValue')) {
         intValue =
             jsonDecoder.decodeInt(jsonPath + '.intValue', json['intValue']);
       }
-      String stringValue;
+      String? stringValue;
       if (json.containsKey('stringValue')) {
         stringValue = jsonDecoder.decodeString(
             jsonPath + '.stringValue', json['stringValue']);
       }
-      FlutterWidgetPropertyValueEnumItem enumValue;
+      FlutterWidgetPropertyValueEnumItem? enumValue;
       if (json.containsKey('enumValue')) {
         enumValue = FlutterWidgetPropertyValueEnumItem.fromJson(
             jsonDecoder, jsonPath + '.enumValue', json['enumValue']);
       }
-      String expression;
+      String? expression;
       if (json.containsKey('expression')) {
         expression = jsonDecoder.decodeString(
             jsonPath + '.expression', json['expression']);
@@ -15132,23 +12094,29 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
+    var boolValue = this.boolValue;
     if (boolValue != null) {
       result['boolValue'] = boolValue;
     }
+    var doubleValue = this.doubleValue;
     if (doubleValue != null) {
       result['doubleValue'] = doubleValue;
     }
+    var intValue = this.intValue;
     if (intValue != null) {
       result['intValue'] = intValue;
     }
+    var stringValue = this.stringValue;
     if (stringValue != null) {
       result['stringValue'] = stringValue;
     }
+    var enumValue = this.enumValue;
     if (enumValue != null) {
       result['enumValue'] = enumValue.toJson();
     }
+    var expression = this.expression;
     if (expression != null) {
       result['expression'] = expression;
     }
@@ -15195,70 +12163,28 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class FlutterWidgetPropertyValueEnumItem implements HasToJson {
-  String _libraryUri;
-
-  String _className;
-
-  String _name;
-
-  String _documentation;
-
   /// The URI of the library containing the className. When the enum item is
   /// passed back, this will allow the server to import the corresponding
   /// library if necessary.
-  String get libraryUri => _libraryUri;
-
-  /// The URI of the library containing the className. When the enum item is
-  /// passed back, this will allow the server to import the corresponding
-  /// library if necessary.
-  set libraryUri(String value) {
-    assert(value != null);
-    _libraryUri = value;
-  }
+  String libraryUri;
 
   /// The name of the class or enum.
-  String get className => _className;
-
-  /// The name of the class or enum.
-  set className(String value) {
-    assert(value != null);
-    _className = value;
-  }
+  String className;
 
   /// The name of the field in the enumeration, or the static field in the
   /// class.
-  String get name => _name;
-
-  /// The name of the field in the enumeration, or the static field in the
-  /// class.
-  set name(String value) {
-    assert(value != null);
-    _name = value;
-  }
+  String name;
 
   /// The documentation to show to the user. Omitted if the server does not
   /// know the documentation, e.g. because the corresponding field is not
   /// documented.
-  String get documentation => _documentation;
+  String? documentation;
 
-  /// The documentation to show to the user. Omitted if the server does not
-  /// know the documentation, e.g. because the corresponding field is not
-  /// documented.
-  set documentation(String value) {
-    _documentation = value;
-  }
-
-  FlutterWidgetPropertyValueEnumItem(
-      String libraryUri, String className, String name,
-      {String documentation}) {
-    this.libraryUri = libraryUri;
-    this.className = className;
-    this.name = name;
-    this.documentation = documentation;
-  }
+  FlutterWidgetPropertyValueEnumItem(this.libraryUri, this.className, this.name,
+      {this.documentation});
 
   factory FlutterWidgetPropertyValueEnumItem.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String libraryUri;
@@ -15281,7 +12207,7 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'name');
       }
-      String documentation;
+      String? documentation;
       if (json.containsKey('documentation')) {
         documentation = jsonDecoder.decodeString(
             jsonPath + '.documentation', json['documentation']);
@@ -15295,11 +12221,12 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['libraryUri'] = libraryUri;
     result['className'] = className;
     result['name'] = name;
+    var documentation = this.documentation;
     if (documentation != null) {
       result['documentation'] = documentation;
     }
@@ -15361,7 +12288,7 @@
   }
 
   factory GeneralAnalysisService.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     if (json is String) {
       try {
         return GeneralAnalysisService(json);
@@ -15397,195 +12324,76 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class HoverInformation implements HasToJson {
-  int _offset;
-
-  int _length;
-
-  String _containingLibraryPath;
-
-  String _containingLibraryName;
-
-  String _containingClassDescription;
-
-  String _dartdoc;
-
-  String _elementDescription;
-
-  String _elementKind;
-
-  bool _isDeprecated;
-
-  String _parameter;
-
-  String _propagatedType;
-
-  String _staticType;
-
   /// The offset of the range of characters that encompasses the cursor
   /// position and has the same hover information as the cursor position.
-  int get offset => _offset;
-
-  /// The offset of the range of characters that encompasses the cursor
-  /// position and has the same hover information as the cursor position.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
+  int offset;
 
   /// The length of the range of characters that encompasses the cursor
   /// position and has the same hover information as the cursor position.
-  int get length => _length;
-
-  /// The length of the range of characters that encompasses the cursor
-  /// position and has the same hover information as the cursor position.
-  set length(int value) {
-    assert(value != null);
-    _length = value;
-  }
+  int length;
 
   /// The path to the defining compilation unit of the library in which the
   /// referenced element is declared. This data is omitted if there is no
   /// referenced element, or if the element is declared inside an HTML file.
-  String get containingLibraryPath => _containingLibraryPath;
-
-  /// The path to the defining compilation unit of the library in which the
-  /// referenced element is declared. This data is omitted if there is no
-  /// referenced element, or if the element is declared inside an HTML file.
-  set containingLibraryPath(String value) {
-    _containingLibraryPath = value;
-  }
+  String? containingLibraryPath;
 
   /// The URI of the containing library, examples here include "dart:core",
   /// "package:.." and file uris represented by the path on disk, "/..". The
   /// data is omitted if the element is declared inside an HTML file.
-  String get containingLibraryName => _containingLibraryName;
-
-  /// The URI of the containing library, examples here include "dart:core",
-  /// "package:.." and file uris represented by the path on disk, "/..". The
-  /// data is omitted if the element is declared inside an HTML file.
-  set containingLibraryName(String value) {
-    _containingLibraryName = value;
-  }
+  String? containingLibraryName;
 
   /// A human-readable description of the class declaring the element being
   /// referenced. This data is omitted if there is no referenced element, or if
   /// the element is not a class member.
-  String get containingClassDescription => _containingClassDescription;
-
-  /// A human-readable description of the class declaring the element being
-  /// referenced. This data is omitted if there is no referenced element, or if
-  /// the element is not a class member.
-  set containingClassDescription(String value) {
-    _containingClassDescription = value;
-  }
+  String? containingClassDescription;
 
   /// The dartdoc associated with the referenced element. Other than the
   /// removal of the comment delimiters, including leading asterisks in the
   /// case of a block comment, the dartdoc is unprocessed markdown. This data
   /// is omitted if there is no referenced element, or if the element has no
   /// dartdoc.
-  String get dartdoc => _dartdoc;
-
-  /// The dartdoc associated with the referenced element. Other than the
-  /// removal of the comment delimiters, including leading asterisks in the
-  /// case of a block comment, the dartdoc is unprocessed markdown. This data
-  /// is omitted if there is no referenced element, or if the element has no
-  /// dartdoc.
-  set dartdoc(String value) {
-    _dartdoc = value;
-  }
+  String? dartdoc;
 
   /// A human-readable description of the element being referenced. This data
   /// is omitted if there is no referenced element.
-  String get elementDescription => _elementDescription;
-
-  /// A human-readable description of the element being referenced. This data
-  /// is omitted if there is no referenced element.
-  set elementDescription(String value) {
-    _elementDescription = value;
-  }
+  String? elementDescription;
 
   /// A human-readable description of the kind of element being referenced
   /// (such as "class" or "function type alias"). This data is omitted if there
   /// is no referenced element.
-  String get elementKind => _elementKind;
-
-  /// A human-readable description of the kind of element being referenced
-  /// (such as "class" or "function type alias"). This data is omitted if there
-  /// is no referenced element.
-  set elementKind(String value) {
-    _elementKind = value;
-  }
+  String? elementKind;
 
   /// True if the referenced element is deprecated.
-  bool get isDeprecated => _isDeprecated;
-
-  /// True if the referenced element is deprecated.
-  set isDeprecated(bool value) {
-    _isDeprecated = value;
-  }
+  bool? isDeprecated;
 
   /// A human-readable description of the parameter corresponding to the
   /// expression being hovered over. This data is omitted if the location is
   /// not in an argument to a function.
-  String get parameter => _parameter;
-
-  /// A human-readable description of the parameter corresponding to the
-  /// expression being hovered over. This data is omitted if the location is
-  /// not in an argument to a function.
-  set parameter(String value) {
-    _parameter = value;
-  }
+  String? parameter;
 
   /// The name of the propagated type of the expression. This data is omitted
   /// if the location does not correspond to an expression or if there is no
   /// propagated type information.
-  String get propagatedType => _propagatedType;
-
-  /// The name of the propagated type of the expression. This data is omitted
-  /// if the location does not correspond to an expression or if there is no
-  /// propagated type information.
-  set propagatedType(String value) {
-    _propagatedType = value;
-  }
+  String? propagatedType;
 
   /// The name of the static type of the expression. This data is omitted if
   /// the location does not correspond to an expression.
-  String get staticType => _staticType;
+  String? staticType;
 
-  /// The name of the static type of the expression. This data is omitted if
-  /// the location does not correspond to an expression.
-  set staticType(String value) {
-    _staticType = value;
-  }
-
-  HoverInformation(int offset, int length,
-      {String containingLibraryPath,
-      String containingLibraryName,
-      String containingClassDescription,
-      String dartdoc,
-      String elementDescription,
-      String elementKind,
-      bool isDeprecated,
-      String parameter,
-      String propagatedType,
-      String staticType}) {
-    this.offset = offset;
-    this.length = length;
-    this.containingLibraryPath = containingLibraryPath;
-    this.containingLibraryName = containingLibraryName;
-    this.containingClassDescription = containingClassDescription;
-    this.dartdoc = dartdoc;
-    this.elementDescription = elementDescription;
-    this.elementKind = elementKind;
-    this.isDeprecated = isDeprecated;
-    this.parameter = parameter;
-    this.propagatedType = propagatedType;
-    this.staticType = staticType;
-  }
+  HoverInformation(this.offset, this.length,
+      {this.containingLibraryPath,
+      this.containingLibraryName,
+      this.containingClassDescription,
+      this.dartdoc,
+      this.elementDescription,
+      this.elementKind,
+      this.isDeprecated,
+      this.parameter,
+      this.propagatedType,
+      this.staticType});
 
   factory HoverInformation.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       int offset;
@@ -15600,53 +12408,53 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'length');
       }
-      String containingLibraryPath;
+      String? containingLibraryPath;
       if (json.containsKey('containingLibraryPath')) {
         containingLibraryPath = jsonDecoder.decodeString(
             jsonPath + '.containingLibraryPath', json['containingLibraryPath']);
       }
-      String containingLibraryName;
+      String? containingLibraryName;
       if (json.containsKey('containingLibraryName')) {
         containingLibraryName = jsonDecoder.decodeString(
             jsonPath + '.containingLibraryName', json['containingLibraryName']);
       }
-      String containingClassDescription;
+      String? containingClassDescription;
       if (json.containsKey('containingClassDescription')) {
         containingClassDescription = jsonDecoder.decodeString(
             jsonPath + '.containingClassDescription',
             json['containingClassDescription']);
       }
-      String dartdoc;
+      String? dartdoc;
       if (json.containsKey('dartdoc')) {
         dartdoc =
             jsonDecoder.decodeString(jsonPath + '.dartdoc', json['dartdoc']);
       }
-      String elementDescription;
+      String? elementDescription;
       if (json.containsKey('elementDescription')) {
         elementDescription = jsonDecoder.decodeString(
             jsonPath + '.elementDescription', json['elementDescription']);
       }
-      String elementKind;
+      String? elementKind;
       if (json.containsKey('elementKind')) {
         elementKind = jsonDecoder.decodeString(
             jsonPath + '.elementKind', json['elementKind']);
       }
-      bool isDeprecated;
+      bool? isDeprecated;
       if (json.containsKey('isDeprecated')) {
         isDeprecated = jsonDecoder.decodeBool(
             jsonPath + '.isDeprecated', json['isDeprecated']);
       }
-      String parameter;
+      String? parameter;
       if (json.containsKey('parameter')) {
         parameter = jsonDecoder.decodeString(
             jsonPath + '.parameter', json['parameter']);
       }
-      String propagatedType;
+      String? propagatedType;
       if (json.containsKey('propagatedType')) {
         propagatedType = jsonDecoder.decodeString(
             jsonPath + '.propagatedType', json['propagatedType']);
       }
-      String staticType;
+      String? staticType;
       if (json.containsKey('staticType')) {
         staticType = jsonDecoder.decodeString(
             jsonPath + '.staticType', json['staticType']);
@@ -15668,37 +12476,47 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['offset'] = offset;
     result['length'] = length;
+    var containingLibraryPath = this.containingLibraryPath;
     if (containingLibraryPath != null) {
       result['containingLibraryPath'] = containingLibraryPath;
     }
+    var containingLibraryName = this.containingLibraryName;
     if (containingLibraryName != null) {
       result['containingLibraryName'] = containingLibraryName;
     }
+    var containingClassDescription = this.containingClassDescription;
     if (containingClassDescription != null) {
       result['containingClassDescription'] = containingClassDescription;
     }
+    var dartdoc = this.dartdoc;
     if (dartdoc != null) {
       result['dartdoc'] = dartdoc;
     }
+    var elementDescription = this.elementDescription;
     if (elementDescription != null) {
       result['elementDescription'] = elementDescription;
     }
+    var elementKind = this.elementKind;
     if (elementKind != null) {
       result['elementKind'] = elementKind;
     }
+    var isDeprecated = this.isDeprecated;
     if (isDeprecated != null) {
       result['isDeprecated'] = isDeprecated;
     }
+    var parameter = this.parameter;
     if (parameter != null) {
       result['parameter'] = parameter;
     }
+    var propagatedType = this.propagatedType;
     if (propagatedType != null) {
       result['propagatedType'] = propagatedType;
     }
+    var staticType = this.staticType;
     if (staticType != null) {
       result['staticType'] = staticType;
     }
@@ -15755,35 +12573,16 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class ImplementedClass implements HasToJson {
-  int _offset;
-
-  int _length;
-
   /// The offset of the name of the implemented class.
-  int get offset => _offset;
-
-  /// The offset of the name of the implemented class.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
+  int offset;
 
   /// The length of the name of the implemented class.
-  int get length => _length;
+  int length;
 
-  /// The length of the name of the implemented class.
-  set length(int value) {
-    assert(value != null);
-    _length = value;
-  }
-
-  ImplementedClass(int offset, int length) {
-    this.offset = offset;
-    this.length = length;
-  }
+  ImplementedClass(this.offset, this.length);
 
   factory ImplementedClass.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       int offset;
@@ -15805,8 +12604,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['offset'] = offset;
     result['length'] = length;
     return result;
@@ -15841,35 +12640,16 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class ImplementedMember implements HasToJson {
-  int _offset;
-
-  int _length;
-
   /// The offset of the name of the implemented member.
-  int get offset => _offset;
-
-  /// The offset of the name of the implemented member.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
+  int offset;
 
   /// The length of the name of the implemented member.
-  int get length => _length;
+  int length;
 
-  /// The length of the name of the implemented member.
-  set length(int value) {
-    assert(value != null);
-    _length = value;
-  }
-
-  ImplementedMember(int offset, int length) {
-    this.offset = offset;
-    this.length = length;
-  }
+  ImplementedMember(this.offset, this.length);
 
   factory ImplementedMember.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       int offset;
@@ -15891,8 +12671,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['offset'] = offset;
     result['length'] = length;
     return result;
@@ -15928,47 +12708,19 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class ImportedElementSet implements HasToJson {
-  List<String> _strings;
-
-  List<int> _uris;
-
-  List<int> _names;
-
   /// The list of unique strings in this object.
-  List<String> get strings => _strings;
-
-  /// The list of unique strings in this object.
-  set strings(List<String> value) {
-    assert(value != null);
-    _strings = value;
-  }
+  List<String> strings;
 
   /// The library URI part of the element. It is an index in the strings field.
-  List<int> get uris => _uris;
-
-  /// The library URI part of the element. It is an index in the strings field.
-  set uris(List<int> value) {
-    assert(value != null);
-    _uris = value;
-  }
+  List<int> uris;
 
   /// The name part of a the element. It is an index in the strings field.
-  List<int> get names => _names;
+  List<int> names;
 
-  /// The name part of a the element. It is an index in the strings field.
-  set names(List<int> value) {
-    assert(value != null);
-    _names = value;
-  }
-
-  ImportedElementSet(List<String> strings, List<int> uris, List<int> names) {
-    this.strings = strings;
-    this.uris = uris;
-    this.names = names;
-  }
+  ImportedElementSet(this.strings, this.uris, this.names);
 
   factory ImportedElementSet.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       List<String> strings;
@@ -15999,8 +12751,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['strings'] = strings;
     result['uris'] = uris;
     result['names'] = names;
@@ -16041,49 +12793,20 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class ImportedElements implements HasToJson {
-  String _path;
-
-  String _prefix;
-
-  List<String> _elements;
-
   /// The absolute and normalized path of the file containing the library.
-  String get path => _path;
-
-  /// The absolute and normalized path of the file containing the library.
-  set path(String value) {
-    assert(value != null);
-    _path = value;
-  }
+  String path;
 
   /// The prefix that was used when importing the library into the original
   /// source.
-  String get prefix => _prefix;
-
-  /// The prefix that was used when importing the library into the original
-  /// source.
-  set prefix(String value) {
-    assert(value != null);
-    _prefix = value;
-  }
+  String prefix;
 
   /// The names of the elements imported from the library.
-  List<String> get elements => _elements;
+  List<String> elements;
 
-  /// The names of the elements imported from the library.
-  set elements(List<String> value) {
-    assert(value != null);
-    _elements = value;
-  }
-
-  ImportedElements(String path, String prefix, List<String> elements) {
-    this.path = path;
-    this.prefix = prefix;
-    this.elements = elements;
-  }
+  ImportedElements(this.path, this.prefix, this.elements);
 
   factory ImportedElements.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String path;
@@ -16112,8 +12835,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['path'] = path;
     result['prefix'] = prefix;
     result['elements'] = elements;
@@ -16152,39 +12875,18 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class IncludedSuggestionRelevanceTag implements HasToJson {
-  String _tag;
-
-  int _relevanceBoost;
-
   /// The opaque value of the tag.
-  String get tag => _tag;
-
-  /// The opaque value of the tag.
-  set tag(String value) {
-    assert(value != null);
-    _tag = value;
-  }
+  String tag;
 
   /// The boost to the relevance of the completion suggestions that match this
   /// tag, which is added to the relevance of the containing
   /// IncludedSuggestionSet.
-  int get relevanceBoost => _relevanceBoost;
+  int relevanceBoost;
 
-  /// The boost to the relevance of the completion suggestions that match this
-  /// tag, which is added to the relevance of the containing
-  /// IncludedSuggestionSet.
-  set relevanceBoost(int value) {
-    assert(value != null);
-    _relevanceBoost = value;
-  }
-
-  IncludedSuggestionRelevanceTag(String tag, int relevanceBoost) {
-    this.tag = tag;
-    this.relevanceBoost = relevanceBoost;
-  }
+  IncludedSuggestionRelevanceTag(this.tag, this.relevanceBoost);
 
   factory IncludedSuggestionRelevanceTag.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String tag;
@@ -16208,8 +12910,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['tag'] = tag;
     result['relevanceBoost'] = relevanceBoost;
     return result;
@@ -16245,33 +12947,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class IncludedSuggestionSet implements HasToJson {
-  int _id;
-
-  int _relevance;
-
-  String _displayUri;
-
   /// Clients should use it to access the set of precomputed completions to be
   /// displayed to the user.
-  int get id => _id;
-
-  /// Clients should use it to access the set of precomputed completions to be
-  /// displayed to the user.
-  set id(int value) {
-    assert(value != null);
-    _id = value;
-  }
+  int id;
 
   /// The relevance of completion suggestions from this library where a higher
   /// number indicates a higher relevance.
-  int get relevance => _relevance;
-
-  /// The relevance of completion suggestions from this library where a higher
-  /// number indicates a higher relevance.
-  set relevance(int value) {
-    assert(value != null);
-    _relevance = value;
-  }
+  int relevance;
 
   /// The optional string that should be displayed instead of the uri of the
   /// referenced AvailableSuggestionSet.
@@ -16280,27 +12962,12 @@
   /// "file://" URIs, so are usually long, and don't look nice, but actual
   /// import directives will use relative URIs, which are short, so we probably
   /// want to display such relative URIs to the user.
-  String get displayUri => _displayUri;
+  String? displayUri;
 
-  /// The optional string that should be displayed instead of the uri of the
-  /// referenced AvailableSuggestionSet.
-  ///
-  /// For example libraries in the "test" directory of a package have only
-  /// "file://" URIs, so are usually long, and don't look nice, but actual
-  /// import directives will use relative URIs, which are short, so we probably
-  /// want to display such relative URIs to the user.
-  set displayUri(String value) {
-    _displayUri = value;
-  }
-
-  IncludedSuggestionSet(int id, int relevance, {String displayUri}) {
-    this.id = id;
-    this.relevance = relevance;
-    this.displayUri = displayUri;
-  }
+  IncludedSuggestionSet(this.id, this.relevance, {this.displayUri});
 
   factory IncludedSuggestionSet.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       int id;
@@ -16316,7 +12983,7 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'relevance');
       }
-      String displayUri;
+      String? displayUri;
       if (json.containsKey('displayUri')) {
         displayUri = jsonDecoder.decodeString(
             jsonPath + '.displayUri', json['displayUri']);
@@ -16328,10 +12995,11 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['id'] = id;
     result['relevance'] = relevance;
+    var displayUri = this.displayUri;
     if (displayUri != null) {
       result['displayUri'] = displayUri;
     }
@@ -16370,35 +13038,16 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class InlineLocalVariableFeedback extends RefactoringFeedback {
-  String _name;
-
-  int _occurrences;
-
   /// The name of the variable being inlined.
-  String get name => _name;
-
-  /// The name of the variable being inlined.
-  set name(String value) {
-    assert(value != null);
-    _name = value;
-  }
+  String name;
 
   /// The number of times the variable occurs.
-  int get occurrences => _occurrences;
+  int occurrences;
 
-  /// The number of times the variable occurs.
-  set occurrences(int value) {
-    assert(value != null);
-    _occurrences = value;
-  }
-
-  InlineLocalVariableFeedback(String name, int occurrences) {
-    this.name = name;
-    this.occurrences = occurrences;
-  }
+  InlineLocalVariableFeedback(this.name, this.occurrences);
 
   factory InlineLocalVariableFeedback.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String name;
@@ -16422,8 +13071,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['name'] = name;
     result['occurrences'] = occurrences;
     return result;
@@ -16478,54 +13127,24 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class InlineMethodFeedback extends RefactoringFeedback {
-  String _className;
-
-  String _methodName;
-
-  bool _isDeclaration;
-
   /// The name of the class enclosing the method being inlined. If not a class
   /// member is being inlined, this field will be absent.
-  String get className => _className;
-
-  /// The name of the class enclosing the method being inlined. If not a class
-  /// member is being inlined, this field will be absent.
-  set className(String value) {
-    _className = value;
-  }
+  String? className;
 
   /// The name of the method (or function) being inlined.
-  String get methodName => _methodName;
-
-  /// The name of the method (or function) being inlined.
-  set methodName(String value) {
-    assert(value != null);
-    _methodName = value;
-  }
+  String methodName;
 
   /// True if the declaration of the method is selected. So all references
   /// should be inlined.
-  bool get isDeclaration => _isDeclaration;
+  bool isDeclaration;
 
-  /// True if the declaration of the method is selected. So all references
-  /// should be inlined.
-  set isDeclaration(bool value) {
-    assert(value != null);
-    _isDeclaration = value;
-  }
-
-  InlineMethodFeedback(String methodName, bool isDeclaration,
-      {String className}) {
-    this.className = className;
-    this.methodName = methodName;
-    this.isDeclaration = isDeclaration;
-  }
+  InlineMethodFeedback(this.methodName, this.isDeclaration, {this.className});
 
   factory InlineMethodFeedback.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
-      String className;
+      String? className;
       if (json.containsKey('className')) {
         className = jsonDecoder.decodeString(
             jsonPath + '.className', json['className']);
@@ -16552,8 +13171,9 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
+    var className = this.className;
     if (className != null) {
       result['className'] = className;
     }
@@ -16594,39 +13214,18 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class InlineMethodOptions extends RefactoringOptions {
-  bool _deleteSource;
-
-  bool _inlineAll;
-
   /// True if the method being inlined should be removed. It is an error if
   /// this field is true and inlineAll is false.
-  bool get deleteSource => _deleteSource;
-
-  /// True if the method being inlined should be removed. It is an error if
-  /// this field is true and inlineAll is false.
-  set deleteSource(bool value) {
-    assert(value != null);
-    _deleteSource = value;
-  }
+  bool deleteSource;
 
   /// True if all invocations of the method should be inlined, or false if only
   /// the invocation site used to create this refactoring should be inlined.
-  bool get inlineAll => _inlineAll;
+  bool inlineAll;
 
-  /// True if all invocations of the method should be inlined, or false if only
-  /// the invocation site used to create this refactoring should be inlined.
-  set inlineAll(bool value) {
-    assert(value != null);
-    _inlineAll = value;
-  }
-
-  InlineMethodOptions(bool deleteSource, bool inlineAll) {
-    this.deleteSource = deleteSource;
-    this.inlineAll = inlineAll;
-  }
+  InlineMethodOptions(this.deleteSource, this.inlineAll);
 
   factory InlineMethodOptions.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       bool deleteSource;
@@ -16656,8 +13255,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['deleteSource'] = deleteSource;
     result['inlineAll'] = inlineAll;
     return result;
@@ -16691,25 +13290,14 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class KytheGetKytheEntriesParams implements RequestParams {
-  String _file;
-
   /// The file containing the code for which the Kythe Entry objects are being
   /// requested.
-  String get file => _file;
+  String file;
 
-  /// The file containing the code for which the Kythe Entry objects are being
-  /// requested.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
-
-  KytheGetKytheEntriesParams(String file) {
-    this.file = file;
-  }
+  KytheGetKytheEntriesParams(this.file);
 
   factory KytheGetKytheEntriesParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -16731,8 +13319,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     return result;
   }
@@ -16770,41 +13358,19 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class KytheGetKytheEntriesResult implements ResponseResult {
-  List<KytheEntry> _entries;
-
-  List<String> _files;
-
   /// The list of KytheEntry objects for the queried file.
-  List<KytheEntry> get entries => _entries;
-
-  /// The list of KytheEntry objects for the queried file.
-  set entries(List<KytheEntry> value) {
-    assert(value != null);
-    _entries = value;
-  }
+  List<KytheEntry> entries;
 
   /// The set of files paths that were required, but not in the file system, to
   /// give a complete and accurate Kythe graph for the file. This could be due
   /// to a referenced file that does not exist or generated files not being
   /// generated or passed before the call to "getKytheEntries".
-  List<String> get files => _files;
+  List<String> files;
 
-  /// The set of files paths that were required, but not in the file system, to
-  /// give a complete and accurate Kythe graph for the file. This could be due
-  /// to a referenced file that does not exist or generated files not being
-  /// generated or passed before the call to "getKytheEntries".
-  set files(List<String> value) {
-    assert(value != null);
-    _files = value;
-  }
-
-  KytheGetKytheEntriesResult(List<KytheEntry> entries, List<String> files) {
-    this.entries = entries;
-    this.files = files;
-  }
+  KytheGetKytheEntriesResult(this.entries, this.files);
 
   factory KytheGetKytheEntriesResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       List<KytheEntry> entries;
@@ -16812,7 +13378,7 @@
         entries = jsonDecoder.decodeList(
             jsonPath + '.entries',
             json['entries'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 KytheEntry.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'entries');
@@ -16839,8 +13405,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['entries'] =
         entries.map((KytheEntry value) => value.toJson()).toList();
     result['files'] = files;
@@ -16883,41 +13449,19 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class LibraryPathSet implements HasToJson {
-  String _scope;
-
-  List<String> _libraryPaths;
-
   /// The filepath for which this request's libraries should be active in
   /// completion suggestions. This object associates filesystem regions to
   /// libraries and library directories of interest to the client.
-  String get scope => _scope;
-
-  /// The filepath for which this request's libraries should be active in
-  /// completion suggestions. This object associates filesystem regions to
-  /// libraries and library directories of interest to the client.
-  set scope(String value) {
-    assert(value != null);
-    _scope = value;
-  }
+  String scope;
 
   /// The paths of the libraries of interest to the client for completion
   /// suggestions.
-  List<String> get libraryPaths => _libraryPaths;
+  List<String> libraryPaths;
 
-  /// The paths of the libraries of interest to the client for completion
-  /// suggestions.
-  set libraryPaths(List<String> value) {
-    assert(value != null);
-    _libraryPaths = value;
-  }
-
-  LibraryPathSet(String scope, List<String> libraryPaths) {
-    this.scope = scope;
-    this.libraryPaths = libraryPaths;
-  }
+  LibraryPathSet(this.scope, this.libraryPaths);
 
   factory LibraryPathSet.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String scope;
@@ -16940,8 +13484,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['scope'] = scope;
     result['libraryPaths'] = libraryPaths;
     return result;
@@ -16995,23 +13539,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class MoveFileOptions extends RefactoringOptions {
-  String _newFile;
-
   /// The new file path to which the given file is being moved.
-  String get newFile => _newFile;
+  String newFile;
 
-  /// The new file path to which the given file is being moved.
-  set newFile(String value) {
-    assert(value != null);
-    _newFile = value;
-  }
-
-  MoveFileOptions(String newFile) {
-    this.newFile = newFile;
-  }
+  MoveFileOptions(this.newFile);
 
   factory MoveFileOptions.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String newFile;
@@ -17034,8 +13568,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['newFile'] = newFile;
     return result;
   }
@@ -17068,35 +13602,16 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class OverriddenMember implements HasToJson {
-  Element _element;
-
-  String _className;
-
   /// The element that is being overridden.
-  Element get element => _element;
-
-  /// The element that is being overridden.
-  set element(Element value) {
-    assert(value != null);
-    _element = value;
-  }
+  Element element;
 
   /// The name of the class in which the member is defined.
-  String get className => _className;
+  String className;
 
-  /// The name of the class in which the member is defined.
-  set className(String value) {
-    assert(value != null);
-    _className = value;
-  }
-
-  OverriddenMember(Element element, String className) {
-    this.element = element;
-    this.className = className;
-  }
+  OverriddenMember(this.element, this.className);
 
   factory OverriddenMember.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       Element element;
@@ -17120,8 +13635,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['element'] = element.toJson();
     result['className'] = className;
     return result;
@@ -17158,67 +13673,27 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class Override implements HasToJson {
-  int _offset;
-
-  int _length;
-
-  OverriddenMember _superclassMember;
-
-  List<OverriddenMember> _interfaceMembers;
-
   /// The offset of the name of the overriding member.
-  int get offset => _offset;
-
-  /// The offset of the name of the overriding member.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
+  int offset;
 
   /// The length of the name of the overriding member.
-  int get length => _length;
-
-  /// The length of the name of the overriding member.
-  set length(int value) {
-    assert(value != null);
-    _length = value;
-  }
+  int length;
 
   /// The member inherited from a superclass that is overridden by the
   /// overriding member. The field is omitted if there is no superclass member,
   /// in which case there must be at least one interface member.
-  OverriddenMember get superclassMember => _superclassMember;
-
-  /// The member inherited from a superclass that is overridden by the
-  /// overriding member. The field is omitted if there is no superclass member,
-  /// in which case there must be at least one interface member.
-  set superclassMember(OverriddenMember value) {
-    _superclassMember = value;
-  }
+  OverriddenMember? superclassMember;
 
   /// The members inherited from interfaces that are overridden by the
   /// overriding member. The field is omitted if there are no interface
   /// members, in which case there must be a superclass member.
-  List<OverriddenMember> get interfaceMembers => _interfaceMembers;
+  List<OverriddenMember>? interfaceMembers;
 
-  /// The members inherited from interfaces that are overridden by the
-  /// overriding member. The field is omitted if there are no interface
-  /// members, in which case there must be a superclass member.
-  set interfaceMembers(List<OverriddenMember> value) {
-    _interfaceMembers = value;
-  }
-
-  Override(int offset, int length,
-      {OverriddenMember superclassMember,
-      List<OverriddenMember> interfaceMembers}) {
-    this.offset = offset;
-    this.length = length;
-    this.superclassMember = superclassMember;
-    this.interfaceMembers = interfaceMembers;
-  }
+  Override(this.offset, this.length,
+      {this.superclassMember, this.interfaceMembers});
 
   factory Override.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       int offset;
@@ -17233,17 +13708,17 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'length');
       }
-      OverriddenMember superclassMember;
+      OverriddenMember? superclassMember;
       if (json.containsKey('superclassMember')) {
         superclassMember = OverriddenMember.fromJson(jsonDecoder,
             jsonPath + '.superclassMember', json['superclassMember']);
       }
-      List<OverriddenMember> interfaceMembers;
+      List<OverriddenMember>? interfaceMembers;
       if (json.containsKey('interfaceMembers')) {
         interfaceMembers = jsonDecoder.decodeList(
             jsonPath + '.interfaceMembers',
             json['interfaceMembers'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 OverriddenMember.fromJson(jsonDecoder, jsonPath, json));
       }
       return Override(offset, length,
@@ -17255,13 +13730,15 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['offset'] = offset;
     result['length'] = length;
+    var superclassMember = this.superclassMember;
     if (superclassMember != null) {
       result['superclassMember'] = superclassMember.toJson();
     }
+    var interfaceMembers = this.interfaceMembers;
     if (interfaceMembers != null) {
       result['interfaceMembers'] = interfaceMembers
           .map((OverriddenMember value) => value.toJson())
@@ -17306,49 +13783,20 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class PostfixTemplateDescriptor implements HasToJson {
-  String _name;
-
-  String _key;
-
-  String _example;
-
   /// The template name, shown in the UI.
-  String get name => _name;
-
-  /// The template name, shown in the UI.
-  set name(String value) {
-    assert(value != null);
-    _name = value;
-  }
+  String name;
 
   /// The unique template key, not shown in the UI.
-  String get key => _key;
-
-  /// The unique template key, not shown in the UI.
-  set key(String value) {
-    assert(value != null);
-    _key = value;
-  }
+  String key;
 
   /// A short example of the transformation performed when the template is
   /// applied.
-  String get example => _example;
+  String example;
 
-  /// A short example of the transformation performed when the template is
-  /// applied.
-  set example(String value) {
-    assert(value != null);
-    _example = value;
-  }
-
-  PostfixTemplateDescriptor(String name, String key, String example) {
-    this.name = name;
-    this.key = key;
-    this.example = example;
-  }
+  PostfixTemplateDescriptor(this.name, this.key, this.example);
 
   factory PostfixTemplateDescriptor.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String name;
@@ -17377,8 +13825,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['name'] = name;
     result['key'] = key;
     result['example'] = example;
@@ -17414,25 +13862,14 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class PubStatus implements HasToJson {
-  bool _isListingPackageDirs;
-
   /// True if the server is currently running pub to produce a list of package
   /// directories.
-  bool get isListingPackageDirs => _isListingPackageDirs;
+  bool isListingPackageDirs;
 
-  /// True if the server is currently running pub to produce a list of package
-  /// directories.
-  set isListingPackageDirs(bool value) {
-    assert(value != null);
-    _isListingPackageDirs = value;
-  }
-
-  PubStatus(bool isListingPackageDirs) {
-    this.isListingPackageDirs = isListingPackageDirs;
-  }
+  PubStatus(this.isListingPackageDirs);
 
   factory PubStatus.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       bool isListingPackageDirs;
@@ -17449,8 +13886,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['isListingPackageDirs'] = isListingPackageDirs;
     return result;
   }
@@ -17483,15 +13920,15 @@
 class RefactoringFeedback implements HasToJson {
   RefactoringFeedback();
 
-  factory RefactoringFeedback.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json, Map responseJson) {
+  static RefactoringFeedback? fromJson(JsonDecoder jsonDecoder, String jsonPath,
+      Object? json, Map responseJson) {
     return refactoringFeedbackFromJson(
         jsonDecoder, jsonPath, json, responseJson);
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     return result;
   }
 
@@ -17522,14 +13959,14 @@
 class RefactoringOptions implements HasToJson {
   RefactoringOptions();
 
-  factory RefactoringOptions.fromJson(JsonDecoder jsonDecoder, String jsonPath,
-      Object json, RefactoringKind kind) {
+  static RefactoringOptions? fromJson(JsonDecoder jsonDecoder, String jsonPath,
+      Object? json, RefactoringKind kind) {
     return refactoringOptionsFromJson(jsonDecoder, jsonPath, json, kind);
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     return result;
   }
 
@@ -17562,64 +13999,24 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class RenameFeedback extends RefactoringFeedback {
-  int _offset;
-
-  int _length;
-
-  String _elementKindName;
-
-  String _oldName;
-
   /// The offset to the beginning of the name selected to be renamed, or -1 if
   /// the name does not exist yet.
-  int get offset => _offset;
-
-  /// The offset to the beginning of the name selected to be renamed, or -1 if
-  /// the name does not exist yet.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
+  int offset;
 
   /// The length of the name selected to be renamed.
-  int get length => _length;
-
-  /// The length of the name selected to be renamed.
-  set length(int value) {
-    assert(value != null);
-    _length = value;
-  }
+  int length;
 
   /// The human-readable description of the kind of element being renamed (such
   /// as "class" or "function type alias").
-  String get elementKindName => _elementKindName;
-
-  /// The human-readable description of the kind of element being renamed (such
-  /// as "class" or "function type alias").
-  set elementKindName(String value) {
-    assert(value != null);
-    _elementKindName = value;
-  }
+  String elementKindName;
 
   /// The old name of the element before the refactoring.
-  String get oldName => _oldName;
+  String oldName;
 
-  /// The old name of the element before the refactoring.
-  set oldName(String value) {
-    assert(value != null);
-    _oldName = value;
-  }
-
-  RenameFeedback(
-      int offset, int length, String elementKindName, String oldName) {
-    this.offset = offset;
-    this.length = length;
-    this.elementKindName = elementKindName;
-    this.oldName = oldName;
-  }
+  RenameFeedback(this.offset, this.length, this.elementKindName, this.oldName);
 
   factory RenameFeedback.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       int offset;
@@ -17655,8 +14052,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['offset'] = offset;
     result['length'] = length;
     result['elementKindName'] = elementKindName;
@@ -17697,23 +14094,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class RenameOptions extends RefactoringOptions {
-  String _newName;
-
   /// The name that the element should have after the refactoring.
-  String get newName => _newName;
+  String newName;
 
-  /// The name that the element should have after the refactoring.
-  set newName(String value) {
-    assert(value != null);
-    _newName = value;
-  }
-
-  RenameOptions(String newName) {
-    this.newName = newName;
-  }
+  RenameOptions(this.newName);
 
   factory RenameOptions.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String newName;
@@ -17736,8 +14123,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['newName'] = newName;
     return result;
   }
@@ -17771,48 +14158,20 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class RequestError implements HasToJson {
-  RequestErrorCode _code;
-
-  String _message;
-
-  String _stackTrace;
-
   /// A code that uniquely identifies the error that occurred.
-  RequestErrorCode get code => _code;
-
-  /// A code that uniquely identifies the error that occurred.
-  set code(RequestErrorCode value) {
-    assert(value != null);
-    _code = value;
-  }
+  RequestErrorCode code;
 
   /// A short description of the error.
-  String get message => _message;
-
-  /// A short description of the error.
-  set message(String value) {
-    assert(value != null);
-    _message = value;
-  }
+  String message;
 
   /// The stack trace associated with processing the request, used for
   /// debugging the server.
-  String get stackTrace => _stackTrace;
+  String? stackTrace;
 
-  /// The stack trace associated with processing the request, used for
-  /// debugging the server.
-  set stackTrace(String value) {
-    _stackTrace = value;
-  }
-
-  RequestError(RequestErrorCode code, String message, {String stackTrace}) {
-    this.code = code;
-    this.message = message;
-    this.stackTrace = stackTrace;
-  }
+  RequestError(this.code, this.message, {this.stackTrace});
 
   factory RequestError.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       RequestErrorCode code;
@@ -17829,7 +14188,7 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'message');
       }
-      String stackTrace;
+      String? stackTrace;
       if (json.containsKey('stackTrace')) {
         stackTrace = jsonDecoder.decodeString(
             jsonPath + '.stackTrace', json['stackTrace']);
@@ -17841,10 +14200,11 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['code'] = code.toJson();
     result['message'] = message;
+    var stackTrace = this.stackTrace;
     if (stackTrace != null) {
       result['stackTrace'] = stackTrace;
     }
@@ -18214,7 +14574,7 @@
   }
 
   factory RequestErrorCode.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     if (json is String) {
       try {
         return RequestErrorCode(json);
@@ -18241,51 +14601,21 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class RuntimeCompletionExpression implements HasToJson {
-  int _offset;
-
-  int _length;
-
-  RuntimeCompletionExpressionType _type;
-
   /// The offset of the expression in the code for completion.
-  int get offset => _offset;
-
-  /// The offset of the expression in the code for completion.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
+  int offset;
 
   /// The length of the expression in the code for completion.
-  int get length => _length;
-
-  /// The length of the expression in the code for completion.
-  set length(int value) {
-    assert(value != null);
-    _length = value;
-  }
+  int length;
 
   /// When the expression is sent from the server to the client, the type is
   /// omitted. The client should fill the type when it sends the request to the
   /// server again.
-  RuntimeCompletionExpressionType get type => _type;
+  RuntimeCompletionExpressionType? type;
 
-  /// When the expression is sent from the server to the client, the type is
-  /// omitted. The client should fill the type when it sends the request to the
-  /// server again.
-  set type(RuntimeCompletionExpressionType value) {
-    _type = value;
-  }
-
-  RuntimeCompletionExpression(int offset, int length,
-      {RuntimeCompletionExpressionType type}) {
-    this.offset = offset;
-    this.length = length;
-    this.type = type;
-  }
+  RuntimeCompletionExpression(this.offset, this.length, {this.type});
 
   factory RuntimeCompletionExpression.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       int offset;
@@ -18300,7 +14630,7 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'length');
       }
-      RuntimeCompletionExpressionType type;
+      RuntimeCompletionExpressionType? type;
       if (json.containsKey('type')) {
         type = RuntimeCompletionExpressionType.fromJson(
             jsonDecoder, jsonPath + '.type', json['type']);
@@ -18312,10 +14642,11 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['offset'] = offset;
     result['length'] = length;
+    var type = this.type;
     if (type != null) {
       result['type'] = type.toJson();
     }
@@ -18359,116 +14690,49 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class RuntimeCompletionExpressionType implements HasToJson {
-  String _libraryPath;
-
-  RuntimeCompletionExpressionTypeKind _kind;
-
-  String _name;
-
-  List<RuntimeCompletionExpressionType> _typeArguments;
-
-  RuntimeCompletionExpressionType _returnType;
-
-  List<RuntimeCompletionExpressionType> _parameterTypes;
-
-  List<String> _parameterNames;
-
   /// The path of the library that has this type. Omitted if the type is not
   /// declared in any library, e.g. "dynamic", or "void".
-  String get libraryPath => _libraryPath;
-
-  /// The path of the library that has this type. Omitted if the type is not
-  /// declared in any library, e.g. "dynamic", or "void".
-  set libraryPath(String value) {
-    _libraryPath = value;
-  }
+  String? libraryPath;
 
   /// The kind of the type.
-  RuntimeCompletionExpressionTypeKind get kind => _kind;
-
-  /// The kind of the type.
-  set kind(RuntimeCompletionExpressionTypeKind value) {
-    assert(value != null);
-    _kind = value;
-  }
+  RuntimeCompletionExpressionTypeKind kind;
 
   /// The name of the type. Omitted if the type does not have a name, e.g. an
   /// inline function type.
-  String get name => _name;
-
-  /// The name of the type. Omitted if the type does not have a name, e.g. an
-  /// inline function type.
-  set name(String value) {
-    _name = value;
-  }
+  String? name;
 
   /// The type arguments of the type. Omitted if the type does not have type
   /// parameters.
-  List<RuntimeCompletionExpressionType> get typeArguments => _typeArguments;
-
-  /// The type arguments of the type. Omitted if the type does not have type
-  /// parameters.
-  set typeArguments(List<RuntimeCompletionExpressionType> value) {
-    _typeArguments = value;
-  }
+  List<RuntimeCompletionExpressionType>? typeArguments;
 
   /// If the type is a function type, the return type of the function. Omitted
   /// if the type is not a function type.
-  RuntimeCompletionExpressionType get returnType => _returnType;
-
-  /// If the type is a function type, the return type of the function. Omitted
-  /// if the type is not a function type.
-  set returnType(RuntimeCompletionExpressionType value) {
-    _returnType = value;
-  }
+  RuntimeCompletionExpressionType? returnType;
 
   /// If the type is a function type, the types of the function parameters of
   /// all kinds - required, optional positional, and optional named. Omitted if
   /// the type is not a function type.
-  List<RuntimeCompletionExpressionType> get parameterTypes => _parameterTypes;
-
-  /// If the type is a function type, the types of the function parameters of
-  /// all kinds - required, optional positional, and optional named. Omitted if
-  /// the type is not a function type.
-  set parameterTypes(List<RuntimeCompletionExpressionType> value) {
-    _parameterTypes = value;
-  }
+  List<RuntimeCompletionExpressionType>? parameterTypes;
 
   /// If the type is a function type, the names of the function parameters of
   /// all kinds - required, optional positional, and optional named. The names
   /// of positional parameters are empty strings. Omitted if the type is not a
   /// function type.
-  List<String> get parameterNames => _parameterNames;
+  List<String>? parameterNames;
 
-  /// If the type is a function type, the names of the function parameters of
-  /// all kinds - required, optional positional, and optional named. The names
-  /// of positional parameters are empty strings. Omitted if the type is not a
-  /// function type.
-  set parameterNames(List<String> value) {
-    _parameterNames = value;
-  }
-
-  RuntimeCompletionExpressionType(RuntimeCompletionExpressionTypeKind kind,
-      {String libraryPath,
-      String name,
-      List<RuntimeCompletionExpressionType> typeArguments,
-      RuntimeCompletionExpressionType returnType,
-      List<RuntimeCompletionExpressionType> parameterTypes,
-      List<String> parameterNames}) {
-    this.libraryPath = libraryPath;
-    this.kind = kind;
-    this.name = name;
-    this.typeArguments = typeArguments;
-    this.returnType = returnType;
-    this.parameterTypes = parameterTypes;
-    this.parameterNames = parameterNames;
-  }
+  RuntimeCompletionExpressionType(this.kind,
+      {this.libraryPath,
+      this.name,
+      this.typeArguments,
+      this.returnType,
+      this.parameterTypes,
+      this.parameterNames});
 
   factory RuntimeCompletionExpressionType.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
-      String libraryPath;
+      String? libraryPath;
       if (json.containsKey('libraryPath')) {
         libraryPath = jsonDecoder.decodeString(
             jsonPath + '.libraryPath', json['libraryPath']);
@@ -18480,34 +14744,34 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'kind');
       }
-      String name;
+      String? name;
       if (json.containsKey('name')) {
         name = jsonDecoder.decodeString(jsonPath + '.name', json['name']);
       }
-      List<RuntimeCompletionExpressionType> typeArguments;
+      List<RuntimeCompletionExpressionType>? typeArguments;
       if (json.containsKey('typeArguments')) {
         typeArguments = jsonDecoder.decodeList(
             jsonPath + '.typeArguments',
             json['typeArguments'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 RuntimeCompletionExpressionType.fromJson(
                     jsonDecoder, jsonPath, json));
       }
-      RuntimeCompletionExpressionType returnType;
+      RuntimeCompletionExpressionType? returnType;
       if (json.containsKey('returnType')) {
         returnType = RuntimeCompletionExpressionType.fromJson(
             jsonDecoder, jsonPath + '.returnType', json['returnType']);
       }
-      List<RuntimeCompletionExpressionType> parameterTypes;
+      List<RuntimeCompletionExpressionType>? parameterTypes;
       if (json.containsKey('parameterTypes')) {
         parameterTypes = jsonDecoder.decodeList(
             jsonPath + '.parameterTypes',
             json['parameterTypes'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 RuntimeCompletionExpressionType.fromJson(
                     jsonDecoder, jsonPath, json));
       }
-      List<String> parameterNames;
+      List<String>? parameterNames;
       if (json.containsKey('parameterNames')) {
         parameterNames = jsonDecoder.decodeList(jsonPath + '.parameterNames',
             json['parameterNames'], jsonDecoder.decodeString);
@@ -18526,28 +14790,34 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
+    var libraryPath = this.libraryPath;
     if (libraryPath != null) {
       result['libraryPath'] = libraryPath;
     }
     result['kind'] = kind.toJson();
+    var name = this.name;
     if (name != null) {
       result['name'] = name;
     }
+    var typeArguments = this.typeArguments;
     if (typeArguments != null) {
       result['typeArguments'] = typeArguments
           .map((RuntimeCompletionExpressionType value) => value.toJson())
           .toList();
     }
+    var returnType = this.returnType;
     if (returnType != null) {
       result['returnType'] = returnType.toJson();
     }
+    var parameterTypes = this.parameterTypes;
     if (parameterTypes != null) {
       result['parameterTypes'] = parameterTypes
           .map((RuntimeCompletionExpressionType value) => value.toJson())
           .toList();
     }
+    var parameterNames = this.parameterNames;
     if (parameterNames != null) {
       result['parameterNames'] = parameterNames;
     }
@@ -18637,7 +14907,7 @@
   }
 
   factory RuntimeCompletionExpressionTypeKind.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     if (json is String) {
       try {
         return RuntimeCompletionExpressionTypeKind(json);
@@ -18664,39 +14934,18 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class RuntimeCompletionVariable implements HasToJson {
-  String _name;
-
-  RuntimeCompletionExpressionType _type;
-
   /// The name of the variable. The name "this" has a special meaning and is
   /// used as an implicit target for runtime completion, and in explicit "this"
   /// references.
-  String get name => _name;
-
-  /// The name of the variable. The name "this" has a special meaning and is
-  /// used as an implicit target for runtime completion, and in explicit "this"
-  /// references.
-  set name(String value) {
-    assert(value != null);
-    _name = value;
-  }
+  String name;
 
   /// The type of the variable.
-  RuntimeCompletionExpressionType get type => _type;
+  RuntimeCompletionExpressionType type;
 
-  /// The type of the variable.
-  set type(RuntimeCompletionExpressionType value) {
-    assert(value != null);
-    _type = value;
-  }
-
-  RuntimeCompletionVariable(String name, RuntimeCompletionExpressionType type) {
-    this.name = name;
-    this.type = type;
-  }
+  RuntimeCompletionVariable(this.name, this.type);
 
   factory RuntimeCompletionVariable.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String name;
@@ -18719,8 +14968,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['name'] = name;
     result['type'] = type.toJson();
     return result;
@@ -18756,52 +15005,22 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class SearchFindElementReferencesParams implements RequestParams {
-  String _file;
-
-  int _offset;
-
-  bool _includePotential;
-
   /// The file containing the declaration of or reference to the element used
   /// to define the search.
-  String get file => _file;
-
-  /// The file containing the declaration of or reference to the element used
-  /// to define the search.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// The offset within the file of the declaration of or reference to the
   /// element.
-  int get offset => _offset;
-
-  /// The offset within the file of the declaration of or reference to the
-  /// element.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
+  int offset;
 
   /// True if potential matches are to be included in the results.
-  bool get includePotential => _includePotential;
-
-  /// True if potential matches are to be included in the results.
-  set includePotential(bool value) {
-    assert(value != null);
-    _includePotential = value;
-  }
+  bool includePotential;
 
   SearchFindElementReferencesParams(
-      String file, int offset, bool includePotential) {
-    this.file = file;
-    this.offset = offset;
-    this.includePotential = includePotential;
-  }
+      this.file, this.offset, this.includePotential);
 
   factory SearchFindElementReferencesParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -18836,8 +15055,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     result['offset'] = offset;
     result['includePotential'] = includePotential;
@@ -18881,52 +15100,29 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class SearchFindElementReferencesResult implements ResponseResult {
-  String _id;
-
-  Element _element;
-
   /// The identifier used to associate results with this search request.
   ///
   /// If no element was found at the given location, this field will be absent,
   /// and no results will be reported via the search.results notification.
-  String get id => _id;
-
-  /// The identifier used to associate results with this search request.
-  ///
-  /// If no element was found at the given location, this field will be absent,
-  /// and no results will be reported via the search.results notification.
-  set id(String value) {
-    _id = value;
-  }
+  String? id;
 
   /// The element referenced or defined at the given offset and whose
   /// references will be returned in the search results.
   ///
   /// If no element was found at the given location, this field will be absent.
-  Element get element => _element;
+  Element? element;
 
-  /// The element referenced or defined at the given offset and whose
-  /// references will be returned in the search results.
-  ///
-  /// If no element was found at the given location, this field will be absent.
-  set element(Element value) {
-    _element = value;
-  }
-
-  SearchFindElementReferencesResult({String id, Element element}) {
-    this.id = id;
-    this.element = element;
-  }
+  SearchFindElementReferencesResult({this.id, this.element});
 
   factory SearchFindElementReferencesResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
-      String id;
+      String? id;
       if (json.containsKey('id')) {
         id = jsonDecoder.decodeString(jsonPath + '.id', json['id']);
       }
-      Element element;
+      Element? element;
       if (json.containsKey('element')) {
         element = Element.fromJson(
             jsonDecoder, jsonPath + '.element', json['element']);
@@ -18946,11 +15142,13 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
+    var id = this.id;
     if (id != null) {
       result['id'] = id;
     }
+    var element = this.element;
     if (element != null) {
       result['element'] = element.toJson();
     }
@@ -18990,23 +15188,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class SearchFindMemberDeclarationsParams implements RequestParams {
-  String _name;
-
   /// The name of the declarations to be found.
-  String get name => _name;
+  String name;
 
-  /// The name of the declarations to be found.
-  set name(String value) {
-    assert(value != null);
-    _name = value;
-  }
-
-  SearchFindMemberDeclarationsParams(String name) {
-    this.name = name;
-  }
+  SearchFindMemberDeclarationsParams(this.name);
 
   factory SearchFindMemberDeclarationsParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String name;
@@ -19028,8 +15216,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['name'] = name;
     return result;
   }
@@ -19066,23 +15254,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class SearchFindMemberDeclarationsResult implements ResponseResult {
-  String _id;
-
   /// The identifier used to associate results with this search request.
-  String get id => _id;
+  String id;
 
-  /// The identifier used to associate results with this search request.
-  set id(String value) {
-    assert(value != null);
-    _id = value;
-  }
-
-  SearchFindMemberDeclarationsResult(String id) {
-    this.id = id;
-  }
+  SearchFindMemberDeclarationsResult(this.id);
 
   factory SearchFindMemberDeclarationsResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String id;
@@ -19106,8 +15284,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['id'] = id;
     return result;
   }
@@ -19144,23 +15322,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class SearchFindMemberReferencesParams implements RequestParams {
-  String _name;
-
   /// The name of the references to be found.
-  String get name => _name;
+  String name;
 
-  /// The name of the references to be found.
-  set name(String value) {
-    assert(value != null);
-    _name = value;
-  }
-
-  SearchFindMemberReferencesParams(String name) {
-    this.name = name;
-  }
+  SearchFindMemberReferencesParams(this.name);
 
   factory SearchFindMemberReferencesParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String name;
@@ -19182,8 +15350,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['name'] = name;
     return result;
   }
@@ -19220,23 +15388,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class SearchFindMemberReferencesResult implements ResponseResult {
-  String _id;
-
   /// The identifier used to associate results with this search request.
-  String get id => _id;
+  String id;
 
-  /// The identifier used to associate results with this search request.
-  set id(String value) {
-    assert(value != null);
-    _id = value;
-  }
-
-  SearchFindMemberReferencesResult(String id) {
-    this.id = id;
-  }
+  SearchFindMemberReferencesResult(this.id);
 
   factory SearchFindMemberReferencesResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String id;
@@ -19260,8 +15418,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['id'] = id;
     return result;
   }
@@ -19298,25 +15456,14 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class SearchFindTopLevelDeclarationsParams implements RequestParams {
-  String _pattern;
-
   /// The regular expression used to match the names of the declarations to be
   /// found.
-  String get pattern => _pattern;
+  String pattern;
 
-  /// The regular expression used to match the names of the declarations to be
-  /// found.
-  set pattern(String value) {
-    assert(value != null);
-    _pattern = value;
-  }
-
-  SearchFindTopLevelDeclarationsParams(String pattern) {
-    this.pattern = pattern;
-  }
+  SearchFindTopLevelDeclarationsParams(this.pattern);
 
   factory SearchFindTopLevelDeclarationsParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String pattern;
@@ -19339,8 +15486,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['pattern'] = pattern;
     return result;
   }
@@ -19377,23 +15524,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class SearchFindTopLevelDeclarationsResult implements ResponseResult {
-  String _id;
-
   /// The identifier used to associate results with this search request.
-  String get id => _id;
+  String id;
 
-  /// The identifier used to associate results with this search request.
-  set id(String value) {
-    assert(value != null);
-    _id = value;
-  }
-
-  SearchFindTopLevelDeclarationsResult(String id) {
-    this.id = id;
-  }
+  SearchFindTopLevelDeclarationsResult(this.id);
 
   factory SearchFindTopLevelDeclarationsResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String id;
@@ -19417,8 +15554,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['id'] = id;
     return result;
   }
@@ -19457,63 +15594,35 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class SearchGetElementDeclarationsParams implements RequestParams {
-  String _file;
-
-  String _pattern;
-
-  int _maxResults;
-
   /// If this field is provided, return only declarations in this file. If this
   /// field is missing, return declarations in all files.
-  String get file => _file;
-
-  /// If this field is provided, return only declarations in this file. If this
-  /// field is missing, return declarations in all files.
-  set file(String value) {
-    _file = value;
-  }
+  String? file;
 
   /// The regular expression used to match the names of declarations. If this
   /// field is missing, return all declarations.
-  String get pattern => _pattern;
-
-  /// The regular expression used to match the names of declarations. If this
-  /// field is missing, return all declarations.
-  set pattern(String value) {
-    _pattern = value;
-  }
+  String? pattern;
 
   /// The maximum number of declarations to return. If this field is missing,
   /// return all matching declarations.
-  int get maxResults => _maxResults;
-
-  /// The maximum number of declarations to return. If this field is missing,
-  /// return all matching declarations.
-  set maxResults(int value) {
-    _maxResults = value;
-  }
+  int? maxResults;
 
   SearchGetElementDeclarationsParams(
-      {String file, String pattern, int maxResults}) {
-    this.file = file;
-    this.pattern = pattern;
-    this.maxResults = maxResults;
-  }
+      {this.file, this.pattern, this.maxResults});
 
   factory SearchGetElementDeclarationsParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
-      String file;
+      String? file;
       if (json.containsKey('file')) {
         file = jsonDecoder.decodeString(jsonPath + '.file', json['file']);
       }
-      String pattern;
+      String? pattern;
       if (json.containsKey('pattern')) {
         pattern =
             jsonDecoder.decodeString(jsonPath + '.pattern', json['pattern']);
       }
-      int maxResults;
+      int? maxResults;
       if (json.containsKey('maxResults')) {
         maxResults =
             jsonDecoder.decodeInt(jsonPath + '.maxResults', json['maxResults']);
@@ -19532,14 +15641,17 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
+    var file = this.file;
     if (file != null) {
       result['file'] = file;
     }
+    var pattern = this.pattern;
     if (pattern != null) {
       result['pattern'] = pattern;
     }
+    var maxResults = this.maxResults;
     if (maxResults != null) {
       result['maxResults'] = maxResults;
     }
@@ -19583,36 +15695,16 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class SearchGetElementDeclarationsResult implements ResponseResult {
-  List<ElementDeclaration> _declarations;
-
-  List<String> _files;
-
   /// The list of declarations.
-  List<ElementDeclaration> get declarations => _declarations;
-
-  /// The list of declarations.
-  set declarations(List<ElementDeclaration> value) {
-    assert(value != null);
-    _declarations = value;
-  }
+  List<ElementDeclaration> declarations;
 
   /// The list of the paths of files with declarations.
-  List<String> get files => _files;
+  List<String> files;
 
-  /// The list of the paths of files with declarations.
-  set files(List<String> value) {
-    assert(value != null);
-    _files = value;
-  }
-
-  SearchGetElementDeclarationsResult(
-      List<ElementDeclaration> declarations, List<String> files) {
-    this.declarations = declarations;
-    this.files = files;
-  }
+  SearchGetElementDeclarationsResult(this.declarations, this.files);
 
   factory SearchGetElementDeclarationsResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       List<ElementDeclaration> declarations;
@@ -19620,7 +15712,7 @@
         declarations = jsonDecoder.decodeList(
             jsonPath + '.declarations',
             json['declarations'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 ElementDeclaration.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'declarations');
@@ -19647,8 +15739,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['declarations'] =
         declarations.map((ElementDeclaration value) => value.toJson()).toList();
     result['files'] = files;
@@ -19692,50 +15784,21 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class SearchGetTypeHierarchyParams implements RequestParams {
-  String _file;
-
-  int _offset;
-
-  bool _superOnly;
-
   /// The file containing the declaration or reference to the type for which a
   /// hierarchy is being requested.
-  String get file => _file;
-
-  /// The file containing the declaration or reference to the type for which a
-  /// hierarchy is being requested.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// The offset of the name of the type within the file.
-  int get offset => _offset;
-
-  /// The offset of the name of the type within the file.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
+  int offset;
 
   /// True if the client is only requesting superclasses and interfaces
   /// hierarchy.
-  bool get superOnly => _superOnly;
+  bool? superOnly;
 
-  /// True if the client is only requesting superclasses and interfaces
-  /// hierarchy.
-  set superOnly(bool value) {
-    _superOnly = value;
-  }
-
-  SearchGetTypeHierarchyParams(String file, int offset, {bool superOnly}) {
-    this.file = file;
-    this.offset = offset;
-    this.superOnly = superOnly;
-  }
+  SearchGetTypeHierarchyParams(this.file, this.offset, {this.superOnly});
 
   factory SearchGetTypeHierarchyParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -19750,7 +15813,7 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'offset');
       }
-      bool superOnly;
+      bool? superOnly;
       if (json.containsKey('superOnly')) {
         superOnly =
             jsonDecoder.decodeBool(jsonPath + '.superOnly', json['superOnly']);
@@ -19768,10 +15831,11 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     result['offset'] = offset;
+    var superOnly = this.superOnly;
     if (superOnly != null) {
       result['superOnly'] = superOnly;
     }
@@ -19814,8 +15878,6 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class SearchGetTypeHierarchyResult implements ResponseResult {
-  List<TypeHierarchyItem> _hierarchyItems;
-
   /// A list of the types in the requested hierarchy. The first element of the
   /// list is the item representing the type for which the hierarchy was
   /// requested. The index of other elements of the list is unspecified, but
@@ -19825,35 +15887,20 @@
   /// This field will be absent if the code at the given file and offset does
   /// not represent a type, or if the file has not been sufficiently analyzed
   /// to allow a type hierarchy to be produced.
-  List<TypeHierarchyItem> get hierarchyItems => _hierarchyItems;
+  List<TypeHierarchyItem>? hierarchyItems;
 
-  /// A list of the types in the requested hierarchy. The first element of the
-  /// list is the item representing the type for which the hierarchy was
-  /// requested. The index of other elements of the list is unspecified, but
-  /// correspond to the integers used to reference supertype and subtype items
-  /// within the items.
-  ///
-  /// This field will be absent if the code at the given file and offset does
-  /// not represent a type, or if the file has not been sufficiently analyzed
-  /// to allow a type hierarchy to be produced.
-  set hierarchyItems(List<TypeHierarchyItem> value) {
-    _hierarchyItems = value;
-  }
-
-  SearchGetTypeHierarchyResult({List<TypeHierarchyItem> hierarchyItems}) {
-    this.hierarchyItems = hierarchyItems;
-  }
+  SearchGetTypeHierarchyResult({this.hierarchyItems});
 
   factory SearchGetTypeHierarchyResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
-      List<TypeHierarchyItem> hierarchyItems;
+      List<TypeHierarchyItem>? hierarchyItems;
       if (json.containsKey('hierarchyItems')) {
         hierarchyItems = jsonDecoder.decodeList(
             jsonPath + '.hierarchyItems',
             json['hierarchyItems'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 TypeHierarchyItem.fromJson(jsonDecoder, jsonPath, json));
       }
       return SearchGetTypeHierarchyResult(hierarchyItems: hierarchyItems);
@@ -19871,8 +15918,9 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
+    var hierarchyItems = this.hierarchyItems;
     if (hierarchyItems != null) {
       result['hierarchyItems'] = hierarchyItems
           .map((TypeHierarchyItem value) => value.toJson())
@@ -19917,70 +15965,27 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class SearchResult implements HasToJson {
-  Location _location;
-
-  SearchResultKind _kind;
-
-  bool _isPotential;
-
-  List<Element> _path;
-
   /// The location of the code that matched the search criteria.
-  Location get location => _location;
-
-  /// The location of the code that matched the search criteria.
-  set location(Location value) {
-    assert(value != null);
-    _location = value;
-  }
+  Location location;
 
   /// The kind of element that was found or the kind of reference that was
   /// found.
-  SearchResultKind get kind => _kind;
-
-  /// The kind of element that was found or the kind of reference that was
-  /// found.
-  set kind(SearchResultKind value) {
-    assert(value != null);
-    _kind = value;
-  }
+  SearchResultKind kind;
 
   /// True if the result is a potential match but cannot be confirmed to be a
   /// match. For example, if all references to a method m defined in some class
   /// were requested, and a reference to a method m from an unknown class were
   /// found, it would be marked as being a potential match.
-  bool get isPotential => _isPotential;
-
-  /// True if the result is a potential match but cannot be confirmed to be a
-  /// match. For example, if all references to a method m defined in some class
-  /// were requested, and a reference to a method m from an unknown class were
-  /// found, it would be marked as being a potential match.
-  set isPotential(bool value) {
-    assert(value != null);
-    _isPotential = value;
-  }
+  bool isPotential;
 
   /// The elements that contain the result, starting with the most immediately
   /// enclosing ancestor and ending with the library.
-  List<Element> get path => _path;
+  List<Element> path;
 
-  /// The elements that contain the result, starting with the most immediately
-  /// enclosing ancestor and ending with the library.
-  set path(List<Element> value) {
-    assert(value != null);
-    _path = value;
-  }
-
-  SearchResult(Location location, SearchResultKind kind, bool isPotential,
-      List<Element> path) {
-    this.location = location;
-    this.kind = kind;
-    this.isPotential = isPotential;
-    this.path = path;
-  }
+  SearchResult(this.location, this.kind, this.isPotential, this.path);
 
   factory SearchResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       Location location;
@@ -20009,7 +16014,7 @@
         path = jsonDecoder.decodeList(
             jsonPath + '.path',
             json['path'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 Element.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'path');
@@ -20021,8 +16026,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['location'] = location.toJson();
     result['kind'] = kind.toJson();
     result['isPotential'] = isPotential;
@@ -20128,7 +16133,7 @@
   }
 
   factory SearchResultKind.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     if (json is String) {
       try {
         return SearchResultKind(json);
@@ -20155,49 +16160,20 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class SearchResultsParams implements HasToJson {
-  String _id;
-
-  List<SearchResult> _results;
-
-  bool _isLast;
-
   /// The id associated with the search.
-  String get id => _id;
-
-  /// The id associated with the search.
-  set id(String value) {
-    assert(value != null);
-    _id = value;
-  }
+  String id;
 
   /// The search results being reported.
-  List<SearchResult> get results => _results;
-
-  /// The search results being reported.
-  set results(List<SearchResult> value) {
-    assert(value != null);
-    _results = value;
-  }
+  List<SearchResult> results;
 
   /// True if this is that last set of results that will be returned for the
   /// indicated search.
-  bool get isLast => _isLast;
+  bool isLast;
 
-  /// True if this is that last set of results that will be returned for the
-  /// indicated search.
-  set isLast(bool value) {
-    assert(value != null);
-    _isLast = value;
-  }
-
-  SearchResultsParams(String id, List<SearchResult> results, bool isLast) {
-    this.id = id;
-    this.results = results;
-    this.isLast = isLast;
-  }
+  SearchResultsParams(this.id, this.results, this.isLast);
 
   factory SearchResultsParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String id;
@@ -20211,7 +16187,7 @@
         results = jsonDecoder.decodeList(
             jsonPath + '.results',
             json['results'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 SearchResult.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'results');
@@ -20234,8 +16210,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['id'] = id;
     result['results'] =
         results.map((SearchResult value) => value.toJson()).toList();
@@ -20280,35 +16256,16 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class ServerConnectedParams implements HasToJson {
-  String _version;
-
-  int _pid;
-
   /// The version number of the analysis server.
-  String get version => _version;
-
-  /// The version number of the analysis server.
-  set version(String value) {
-    assert(value != null);
-    _version = value;
-  }
+  String version;
 
   /// The process id of the analysis server process.
-  int get pid => _pid;
+  int pid;
 
-  /// The process id of the analysis server process.
-  set pid(int value) {
-    assert(value != null);
-    _pid = value;
-  }
-
-  ServerConnectedParams(String version, int pid) {
-    this.version = version;
-    this.pid = pid;
-  }
+  ServerConnectedParams(this.version, this.pid);
 
   factory ServerConnectedParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String version;
@@ -20336,8 +16293,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['version'] = version;
     result['pid'] = pid;
     return result;
@@ -20377,51 +16334,21 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class ServerErrorParams implements HasToJson {
-  bool _isFatal;
-
-  String _message;
-
-  String _stackTrace;
-
   /// True if the error is a fatal error, meaning that the server will shutdown
   /// automatically after sending this notification.
-  bool get isFatal => _isFatal;
-
-  /// True if the error is a fatal error, meaning that the server will shutdown
-  /// automatically after sending this notification.
-  set isFatal(bool value) {
-    assert(value != null);
-    _isFatal = value;
-  }
+  bool isFatal;
 
   /// The error message indicating what kind of error was encountered.
-  String get message => _message;
-
-  /// The error message indicating what kind of error was encountered.
-  set message(String value) {
-    assert(value != null);
-    _message = value;
-  }
+  String message;
 
   /// The stack trace associated with the generation of the error, used for
   /// debugging the server.
-  String get stackTrace => _stackTrace;
+  String stackTrace;
 
-  /// The stack trace associated with the generation of the error, used for
-  /// debugging the server.
-  set stackTrace(String value) {
-    assert(value != null);
-    _stackTrace = value;
-  }
-
-  ServerErrorParams(bool isFatal, String message, String stackTrace) {
-    this.isFatal = isFatal;
-    this.message = message;
-    this.stackTrace = stackTrace;
-  }
+  ServerErrorParams(this.isFatal, this.message, this.stackTrace);
 
   factory ServerErrorParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       bool isFatal;
@@ -20457,8 +16384,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['isFatal'] = isFatal;
     result['message'] = message;
     result['stackTrace'] = stackTrace;
@@ -20497,7 +16424,7 @@
 /// Clients may not extend, implement or mix-in this class.
 class ServerGetVersionParams implements RequestParams {
   @override
-  Map<String, dynamic> toJson() => <String, dynamic>{};
+  Map<String, Object> toJson() => <String, Object>{};
 
   @override
   Request toRequest(String id) {
@@ -20526,23 +16453,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class ServerGetVersionResult implements ResponseResult {
-  String _version;
-
   /// The version number of the analysis server.
-  String get version => _version;
+  String version;
 
-  /// The version number of the analysis server.
-  set version(String value) {
-    assert(value != null);
-    _version = value;
-  }
-
-  ServerGetVersionResult(String version) {
-    this.version = version;
-  }
+  ServerGetVersionResult(this.version);
 
   factory ServerGetVersionResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String version;
@@ -20566,8 +16483,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['version'] = version;
     return result;
   }
@@ -20606,53 +16523,22 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class ServerLogEntry implements HasToJson {
-  int _time;
-
-  ServerLogEntryKind _kind;
-
-  String _data;
-
   /// The time (milliseconds since epoch) at which the server created this log
   /// entry.
-  int get time => _time;
-
-  /// The time (milliseconds since epoch) at which the server created this log
-  /// entry.
-  set time(int value) {
-    assert(value != null);
-    _time = value;
-  }
+  int time;
 
   /// The kind of the entry, used to determine how to interpret the "data"
   /// field.
-  ServerLogEntryKind get kind => _kind;
-
-  /// The kind of the entry, used to determine how to interpret the "data"
-  /// field.
-  set kind(ServerLogEntryKind value) {
-    assert(value != null);
-    _kind = value;
-  }
+  ServerLogEntryKind kind;
 
   /// The payload of the entry, the actual format is determined by the "kind"
   /// field.
-  String get data => _data;
+  String data;
 
-  /// The payload of the entry, the actual format is determined by the "kind"
-  /// field.
-  set data(String value) {
-    assert(value != null);
-    _data = value;
-  }
-
-  ServerLogEntry(int time, ServerLogEntryKind kind, String data) {
-    this.time = time;
-    this.kind = kind;
-    this.data = data;
-  }
+  ServerLogEntry(this.time, this.kind, this.data);
 
   factory ServerLogEntry.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       int time;
@@ -20681,8 +16567,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['time'] = time;
     result['kind'] = kind.toJson();
     result['data'] = data;
@@ -20780,7 +16666,7 @@
   }
 
   factory ServerLogEntryKind.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     if (json is String) {
       try {
         return ServerLogEntryKind(json);
@@ -20805,21 +16691,12 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class ServerLogParams implements HasToJson {
-  ServerLogEntry _entry;
+  ServerLogEntry entry;
 
-  ServerLogEntry get entry => _entry;
-
-  set entry(ServerLogEntry value) {
-    assert(value != null);
-    _entry = value;
-  }
-
-  ServerLogParams(ServerLogEntry entry) {
-    this.entry = entry;
-  }
+  ServerLogParams(this.entry);
 
   factory ServerLogParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       ServerLogEntry entry;
@@ -20841,8 +16718,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['entry'] = entry.toJson();
     return result;
   }
@@ -20902,7 +16779,7 @@
   }
 
   factory ServerService.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     if (json is String) {
       try {
         return ServerService(json);
@@ -20927,23 +16804,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class ServerSetSubscriptionsParams implements RequestParams {
-  List<ServerService> _subscriptions;
-
   /// A list of the services being subscribed to.
-  List<ServerService> get subscriptions => _subscriptions;
+  List<ServerService> subscriptions;
 
-  /// A list of the services being subscribed to.
-  set subscriptions(List<ServerService> value) {
-    assert(value != null);
-    _subscriptions = value;
-  }
-
-  ServerSetSubscriptionsParams(List<ServerService> subscriptions) {
-    this.subscriptions = subscriptions;
-  }
+  ServerSetSubscriptionsParams(this.subscriptions);
 
   factory ServerSetSubscriptionsParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       List<ServerService> subscriptions;
@@ -20951,7 +16818,7 @@
         subscriptions = jsonDecoder.decodeList(
             jsonPath + '.subscriptions',
             json['subscriptions'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 ServerService.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'subscriptions');
@@ -20969,8 +16836,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['subscriptions'] =
         subscriptions.map((ServerService value) => value.toJson()).toList();
     return result;
@@ -21006,7 +16873,7 @@
 /// Clients may not extend, implement or mix-in this class.
 class ServerSetSubscriptionsResult implements ResponseResult {
   @override
-  Map<String, dynamic> toJson() => <String, dynamic>{};
+  Map<String, Object> toJson() => <String, Object>{};
 
   @override
   Response toResponse(String id) {
@@ -21032,7 +16899,7 @@
 /// Clients may not extend, implement or mix-in this class.
 class ServerShutdownParams implements RequestParams {
   @override
-  Map<String, dynamic> toJson() => <String, dynamic>{};
+  Map<String, Object> toJson() => <String, Object>{};
 
   @override
   Request toRequest(String id) {
@@ -21058,7 +16925,7 @@
 /// Clients may not extend, implement or mix-in this class.
 class ServerShutdownResult implements ResponseResult {
   @override
-  Map<String, dynamic> toJson() => <String, dynamic>{};
+  Map<String, Object> toJson() => <String, Object>{};
 
   @override
   Response toResponse(String id) {
@@ -21088,51 +16955,29 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class ServerStatusParams implements HasToJson {
-  AnalysisStatus _analysis;
-
-  PubStatus _pub;
-
   /// The current status of analysis, including whether analysis is being
   /// performed and if so what is being analyzed.
-  AnalysisStatus get analysis => _analysis;
-
-  /// The current status of analysis, including whether analysis is being
-  /// performed and if so what is being analyzed.
-  set analysis(AnalysisStatus value) {
-    _analysis = value;
-  }
+  AnalysisStatus? analysis;
 
   /// The current status of pub execution, indicating whether we are currently
   /// running pub.
   ///
   /// Note: this status type is deprecated, and is no longer sent by the
   /// server.
-  PubStatus get pub => _pub;
+  PubStatus? pub;
 
-  /// The current status of pub execution, indicating whether we are currently
-  /// running pub.
-  ///
-  /// Note: this status type is deprecated, and is no longer sent by the
-  /// server.
-  set pub(PubStatus value) {
-    _pub = value;
-  }
-
-  ServerStatusParams({AnalysisStatus analysis, PubStatus pub}) {
-    this.analysis = analysis;
-    this.pub = pub;
-  }
+  ServerStatusParams({this.analysis, this.pub});
 
   factory ServerStatusParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
-      AnalysisStatus analysis;
+      AnalysisStatus? analysis;
       if (json.containsKey('analysis')) {
         analysis = AnalysisStatus.fromJson(
             jsonDecoder, jsonPath + '.analysis', json['analysis']);
       }
-      PubStatus pub;
+      PubStatus? pub;
       if (json.containsKey('pub')) {
         pub = PubStatus.fromJson(jsonDecoder, jsonPath + '.pub', json['pub']);
       }
@@ -21148,11 +16993,13 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
+    var analysis = this.analysis;
     if (analysis != null) {
       result['analysis'] = analysis.toJson();
     }
+    var pub = this.pub;
     if (pub != null) {
       result['pub'] = pub.toJson();
     }
@@ -21197,134 +17044,52 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class TypeHierarchyItem implements HasToJson {
-  Element _classElement;
-
-  String _displayName;
-
-  Element _memberElement;
-
-  int _superclass;
-
-  List<int> _interfaces;
-
-  List<int> _mixins;
-
-  List<int> _subclasses;
-
   /// The class element represented by this item.
-  Element get classElement => _classElement;
-
-  /// The class element represented by this item.
-  set classElement(Element value) {
-    assert(value != null);
-    _classElement = value;
-  }
+  Element classElement;
 
   /// The name to be displayed for the class. This field will be omitted if the
   /// display name is the same as the name of the element. The display name is
   /// different if there is additional type information to be displayed, such
   /// as type arguments.
-  String get displayName => _displayName;
-
-  /// The name to be displayed for the class. This field will be omitted if the
-  /// display name is the same as the name of the element. The display name is
-  /// different if there is additional type information to be displayed, such
-  /// as type arguments.
-  set displayName(String value) {
-    _displayName = value;
-  }
+  String? displayName;
 
   /// The member in the class corresponding to the member on which the
   /// hierarchy was requested. This field will be omitted if the hierarchy was
   /// not requested for a member or if the class does not have a corresponding
   /// member.
-  Element get memberElement => _memberElement;
-
-  /// The member in the class corresponding to the member on which the
-  /// hierarchy was requested. This field will be omitted if the hierarchy was
-  /// not requested for a member or if the class does not have a corresponding
-  /// member.
-  set memberElement(Element value) {
-    _memberElement = value;
-  }
+  Element? memberElement;
 
   /// The index of the item representing the superclass of this class. This
   /// field will be omitted if this item represents the class Object.
-  int get superclass => _superclass;
-
-  /// The index of the item representing the superclass of this class. This
-  /// field will be omitted if this item represents the class Object.
-  set superclass(int value) {
-    _superclass = value;
-  }
+  int? superclass;
 
   /// The indexes of the items representing the interfaces implemented by this
   /// class. The list will be empty if there are no implemented interfaces.
-  List<int> get interfaces => _interfaces;
-
-  /// The indexes of the items representing the interfaces implemented by this
-  /// class. The list will be empty if there are no implemented interfaces.
-  set interfaces(List<int> value) {
-    assert(value != null);
-    _interfaces = value;
-  }
+  List<int> interfaces;
 
   /// The indexes of the items representing the mixins referenced by this
   /// class. The list will be empty if there are no classes mixed in to this
   /// class.
-  List<int> get mixins => _mixins;
-
-  /// The indexes of the items representing the mixins referenced by this
-  /// class. The list will be empty if there are no classes mixed in to this
-  /// class.
-  set mixins(List<int> value) {
-    assert(value != null);
-    _mixins = value;
-  }
+  List<int> mixins;
 
   /// The indexes of the items representing the subtypes of this class. The
   /// list will be empty if there are no subtypes or if this item represents a
   /// supertype of the pivot type.
-  List<int> get subclasses => _subclasses;
+  List<int> subclasses;
 
-  /// The indexes of the items representing the subtypes of this class. The
-  /// list will be empty if there are no subtypes or if this item represents a
-  /// supertype of the pivot type.
-  set subclasses(List<int> value) {
-    assert(value != null);
-    _subclasses = value;
-  }
-
-  TypeHierarchyItem(Element classElement,
-      {String displayName,
-      Element memberElement,
-      int superclass,
-      List<int> interfaces,
-      List<int> mixins,
-      List<int> subclasses}) {
-    this.classElement = classElement;
-    this.displayName = displayName;
-    this.memberElement = memberElement;
-    this.superclass = superclass;
-    if (interfaces == null) {
-      this.interfaces = <int>[];
-    } else {
-      this.interfaces = interfaces;
-    }
-    if (mixins == null) {
-      this.mixins = <int>[];
-    } else {
-      this.mixins = mixins;
-    }
-    if (subclasses == null) {
-      this.subclasses = <int>[];
-    } else {
-      this.subclasses = subclasses;
-    }
-  }
+  TypeHierarchyItem(this.classElement,
+      {this.displayName,
+      this.memberElement,
+      this.superclass,
+      List<int>? interfaces,
+      List<int>? mixins,
+      List<int>? subclasses})
+      : interfaces = interfaces ?? <int>[],
+        mixins = mixins ?? <int>[],
+        subclasses = subclasses ?? <int>[];
 
   factory TypeHierarchyItem.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       Element classElement;
@@ -21334,17 +17099,17 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'classElement');
       }
-      String displayName;
+      String? displayName;
       if (json.containsKey('displayName')) {
         displayName = jsonDecoder.decodeString(
             jsonPath + '.displayName', json['displayName']);
       }
-      Element memberElement;
+      Element? memberElement;
       if (json.containsKey('memberElement')) {
         memberElement = Element.fromJson(
             jsonDecoder, jsonPath + '.memberElement', json['memberElement']);
       }
-      int superclass;
+      int? superclass;
       if (json.containsKey('superclass')) {
         superclass =
             jsonDecoder.decodeInt(jsonPath + '.superclass', json['superclass']);
@@ -21383,15 +17148,18 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['classElement'] = classElement.toJson();
+    var displayName = this.displayName;
     if (displayName != null) {
       result['displayName'] = displayName;
     }
+    var memberElement = this.memberElement;
     if (memberElement != null) {
       result['memberElement'] = memberElement.toJson();
     }
+    var superclass = this.superclass;
     if (superclass != null) {
       result['superclass'] = superclass;
     }
diff --git a/pkg/analysis_server_client/lib/src/protocol/protocol_internal.dart b/pkg/analysis_server_client/lib/src/protocol/protocol_internal.dart
index e35a40d..399fb51 100644
--- a/pkg/analysis_server_client/lib/src/protocol/protocol_internal.dart
+++ b/pkg/analysis_server_client/lib/src/protocol/protocol_internal.dart
@@ -59,7 +59,7 @@
 }
 
 /// Returns the [FileEdit] for the given [file], maybe `null`.
-SourceFileEdit getChangeFileEdit(SourceChange change, String file) {
+SourceFileEdit? getChangeFileEdit(SourceChange change, String file) {
   for (var fileEdit in change.edits) {
     if (fileEdit.file == file) {
       return fileEdit;
@@ -70,8 +70,8 @@
 
 /// Compare the lists [listA] and [listB], using [itemEqual] to compare
 /// list elements.
-bool listEqual<T1, T2>(
-    List<T1> listA, List<T2> listB, bool Function(T1 a, T2 b) itemEqual) {
+bool listEqual<T>(
+    List<T>? listA, List<T>? listB, bool Function(T a, T b) itemEqual) {
   if (listA == null) {
     return listB == null;
   }
@@ -92,7 +92,7 @@
 /// Compare the maps [mapA] and [mapB], using [valueEqual] to compare map
 /// values.
 bool mapEqual<K, V>(
-    Map<K, V> mapA, Map<K, V> mapB, bool Function(V a, V b) valueEqual) {
+    Map<K, V>? mapA, Map<K, V>? mapB, bool Function(V a, V b) valueEqual) {
   if (mapA == null) {
     return mapB == null;
   }
@@ -102,11 +102,11 @@
   if (mapA.length != mapB.length) {
     return false;
   }
-  for (var key in mapA.keys) {
-    if (!mapB.containsKey(key)) {
-      return false;
-    }
-    if (!valueEqual(mapA[key], mapB[key])) {
+  for (var entryA in mapA.entries) {
+    var key = entryA.key;
+    var valueA = entryA.value;
+    var valueB = mapB[key];
+    if (valueB == null || !valueEqual(valueA, valueB)) {
       return false;
     }
   }
@@ -116,7 +116,7 @@
 /// Translate the input [map], applying [keyCallback] to all its keys, and
 /// [valueCallback] to all its values.
 Map<KR, VR> mapMap<KP, VP, KR, VR>(Map<KP, VP> map,
-    {KR Function(KP key) keyCallback, VR Function(VP value) valueCallback}) {
+    {KR Function(KP key)? keyCallback, VR Function(VP value)? valueCallback}) {
   Map<KR, VR> result = HashMap<KR, VR>();
   map.forEach((key, value) {
     KR resultKey;
@@ -136,8 +136,8 @@
   return result;
 }
 
-RefactoringProblemSeverity maxRefactoringProblemSeverity(
-    RefactoringProblemSeverity a, RefactoringProblemSeverity b) {
+RefactoringProblemSeverity? maxRefactoringProblemSeverity(
+    RefactoringProblemSeverity? a, RefactoringProblemSeverity? b) {
   if (b == null) {
     return a;
   }
@@ -159,8 +159,8 @@
 }
 
 /// Create a [RefactoringFeedback] corresponding the given [kind].
-RefactoringFeedback refactoringFeedbackFromJson(
-    JsonDecoder jsonDecoder, String jsonPath, Object json, Map feedbackJson) {
+RefactoringFeedback? refactoringFeedbackFromJson(
+    JsonDecoder jsonDecoder, String jsonPath, Object? json, Map feedbackJson) {
   var kind = jsonDecoder.refactoringKind;
   if (kind == RefactoringKind.EXTRACT_LOCAL_VARIABLE) {
     return ExtractLocalVariableFeedback.fromJson(jsonDecoder, jsonPath, json);
@@ -184,8 +184,8 @@
 }
 
 /// Create a [RefactoringOptions] corresponding the given [kind].
-RefactoringOptions refactoringOptionsFromJson(JsonDecoder jsonDecoder,
-    String jsonPath, Object json, RefactoringKind kind) {
+RefactoringOptions? refactoringOptionsFromJson(JsonDecoder jsonDecoder,
+    String jsonPath, Object? json, RefactoringKind kind) {
   if (kind == RefactoringKind.EXTRACT_LOCAL_VARIABLE) {
     return ExtractLocalVariableOptions.fromJson(jsonDecoder, jsonPath, json);
   }
@@ -210,7 +210,8 @@
 /// Type of callbacks used to decode parts of JSON objects. [jsonPath] is a
 /// string describing the part of the JSON object being decoded, and [value] is
 /// the part to decode.
-typedef JsonDecoderCallback<E> = E Function(String jsonPath, Object value);
+typedef JsonDecoderCallback<E extends Object> = E Function(
+    String jsonPath, Object? value);
 
 /// Instances of the class [HasToJson] implement [toJson] method that returns
 /// a JSON presentation.
@@ -225,7 +226,7 @@
   /// Retrieve the RefactoringKind that should be assumed when decoding
   /// refactoring feedback objects, or null if no refactoring feedback object is
   /// expected to be encountered.
-  RefactoringKind get refactoringKind;
+  RefactoringKind? get refactoringKind;
 
   /// Decode a JSON object that is expected to be a boolean. The strings "true"
   /// and "false" are also accepted.
@@ -259,7 +260,7 @@
 
   /// Decode a JSON object that is expected to be an integer. A string
   /// representation of an integer is also accepted.
-  int decodeInt(String jsonPath, Object json) {
+  int decodeInt(String jsonPath, Object? json) {
     if (json is int) {
       return json;
     } else if (json is String) {
@@ -276,8 +277,8 @@
   /// to decode the items in the list.
   ///
   /// The type parameter [E] is the expected type of the elements in the list.
-  List<E> decodeList<E>(String jsonPath, Object json,
-      [JsonDecoderCallback<E> decoder]) {
+  List<E> decodeList<E extends Object>(
+      String jsonPath, Object? json, JsonDecoderCallback<E> decoder) {
     if (json == null) {
       return <E>[];
     } else if (json is List) {
@@ -293,9 +294,10 @@
 
   /// Decode a JSON object that is expected to be a Map. [keyDecoder] is used
   /// to decode the keys, and [valueDecoder] is used to decode the values.
-  Map<K, V> decodeMap<K, V>(String jsonPath, Object jsonData,
-      {JsonDecoderCallback<K> keyDecoder,
-      JsonDecoderCallback<V> valueDecoder}) {
+  Map<K, V> decodeMap<K extends Object, V extends Object>(
+      String jsonPath, Object? jsonData,
+      {JsonDecoderCallback<K>? keyDecoder,
+      JsonDecoderCallback<V>? valueDecoder}) {
     if (jsonData == null) {
       return {};
     } else if (jsonData is Map) {
@@ -319,7 +321,7 @@
   }
 
   /// Decode a JSON object that is expected to be a string.
-  String decodeString(String jsonPath, Object json) {
+  String decodeString(String jsonPath, Object? json) {
     if (json is String) {
       return json;
     } else {
@@ -331,7 +333,7 @@
   /// where the choices are disambiguated by the contents of the field [field].
   /// [decoders] is a map from each possible string in the field to the decoder
   /// that should be used to decode the JSON object.
-  Object decodeUnion(String jsonPath, Map jsonData, String field,
+  Object decodeUnion(String jsonPath, Object? jsonData, String field,
       Map<String, JsonDecoderCallback> decoders) {
     if (jsonData is Map) {
       if (!jsonData.containsKey(field)) {
@@ -339,11 +341,12 @@
       }
       var disambiguatorPath = '$jsonPath[${json.encode(field)}]';
       var disambiguator = decodeString(disambiguatorPath, jsonData[field]);
-      if (!decoders.containsKey(disambiguator)) {
+      var decoder = decoders[disambiguator];
+      if (decoder == null) {
         throw mismatch(
             disambiguatorPath, 'One of: ${decoders.keys.toList()}', jsonData);
       }
-      return decoders[disambiguator](jsonPath, jsonData);
+      return decoder(jsonPath, jsonData);
     } else {
       throw mismatch(jsonPath, 'Map', jsonData);
     }
@@ -351,7 +354,7 @@
 
   /// Create an exception to throw if the JSON object at [jsonPath] fails to
   /// match the API definition of [expected].
-  dynamic mismatch(String jsonPath, String expected, [Object actual]);
+  dynamic mismatch(String jsonPath, String expected, [Object? actual]);
 
   /// Create an exception to throw if the JSON object at [jsonPath] is missing
   /// the key [key].
@@ -367,13 +370,13 @@
   RequestDecoder(this._request);
 
   @override
-  RefactoringKind get refactoringKind {
+  RefactoringKind? get refactoringKind {
     // Refactoring feedback objects should never appear in requests.
     return null;
   }
 
   @override
-  dynamic mismatch(String jsonPath, String expected, [Object actual]) {
+  dynamic mismatch(String jsonPath, String expected, [Object? actual]) {
     var buffer = StringBuffer();
     buffer.write('Expected to be ');
     buffer.write(expected);
@@ -403,12 +406,12 @@
 /// used only for testing. Errors are reported using bare [Exception] objects.
 class ResponseDecoder extends JsonDecoder {
   @override
-  final RefactoringKind refactoringKind;
+  final RefactoringKind? refactoringKind;
 
   ResponseDecoder(this.refactoringKind);
 
   @override
-  dynamic mismatch(String jsonPath, String expected, [Object actual]) {
+  dynamic mismatch(String jsonPath, String expected, [Object? actual]) {
     var buffer = StringBuffer();
     buffer.write('Expected ');
     buffer.write(expected);
diff --git a/pkg/analysis_server_client/lib/src/server_base.dart b/pkg/analysis_server_client/lib/src/server_base.dart
index 39e9c1d..dd9668c 100644
--- a/pkg/analysis_server_client/lib/src/server_base.dart
+++ b/pkg/analysis_server_client/lib/src/server_base.dart
@@ -15,12 +15,12 @@
 /// TODO(danrubel): Consider moving all cmdline argument consts
 /// out of analysis_server and into analysis_server_client.
 List<String> getServerArguments({
-  String clientId,
-  String clientVersion,
-  int diagnosticPort,
-  String instrumentationLogFile,
-  String sdkPath,
-  bool suppressAnalytics,
+  String? clientId,
+  String? clientVersion,
+  int? diagnosticPort,
+  String? instrumentationLogFile,
+  String? sdkPath,
+  bool suppressAnalytics = true,
   bool useAnalysisHighlight2 = false,
 }) {
   var arguments = <String>[];
@@ -72,24 +72,24 @@
 
   /// If not `null`, [_listener] will be sent information
   /// about interactions with the server.
-  final ServerListener _listener;
+  final ServerListener? _listener;
 
   /// Commands that have been sent to the server but not yet acknowledged,
   /// and the [Completer] objects which should be completed
   /// when acknowledgement is received.
-  final _pendingCommands = <String, Completer<Map<String, dynamic>>>{};
+  final _pendingCommands = <String, Completer<Map<String, Object?>?>>{};
 
-  ServerBase({ServerListener listener, bool stdioPassthrough = false})
+  ServerBase({ServerListener? listener, bool stdioPassthrough = false})
       : _listener = listener,
         _stdioPassthrough = stdioPassthrough;
 
-  ServerListener get listener => _listener;
+  ServerListener? get listener => _listener;
 
   /// If the implementation of [ServerBase] captures an error stream,
   /// it can use this to forward the errors to [listener] and [stderr] if
   /// appropriate.
   void errorProcessor(
-      String line, NotificationProcessor notificationProcessor) {
+      String line, NotificationProcessor? notificationProcessor) {
     if (_stdioPassthrough) stderr.writeln(line);
     var trimmedLine = line.trim();
     listener?.errorMessage(trimmedLine);
@@ -108,7 +108,7 @@
   /// decoding or message synchronization using [listener], and replicates
   /// raw data to [stdout] as appropriate.
   void outputProcessor(
-      String line, NotificationProcessor notificationProcessor) {
+      String line, NotificationProcessor? notificationProcessor) {
     if (_stdioPassthrough) stdout.writeln(line);
     var trimmedLine = line.trim();
 
@@ -125,7 +125,7 @@
     }
 
     listener?.messageReceived(trimmedLine);
-    Map<String, dynamic> message;
+    Map<String, Object?> message;
     try {
       message = json.decoder.convert(trimmedLine);
     } catch (exception) {
@@ -133,31 +133,47 @@
       return;
     }
 
+    // Handle response.
     final id = message[Response.ID];
     if (id != null) {
-      // Handle response
       final completer = _pendingCommands.remove(id);
       if (completer == null) {
         listener?.unexpectedResponse(message, id);
+        return;
       }
-      if (message.containsKey(Response.ERROR)) {
-        completer.completeError(RequestError.fromJson(
-            ResponseDecoder(null), '.error', message[Response.ERROR]));
-      } else {
-        completer.complete(message[Response.RESULT]);
+
+      final errorJson = message[Response.ERROR];
+      if (errorJson != null) {
+        completer.completeError(
+            RequestError.fromJson(ResponseDecoder(null), '.error', errorJson));
+        return;
       }
-    } else {
-      // Handle notification
-      final String event = message[Notification.EVENT];
-      if (event != null) {
+
+      final resultJson = message[Response.RESULT];
+      if (resultJson is Map<String, Object?>?) {
+        completer.complete(resultJson);
+        return;
+      }
+
+      listener?.unexpectedResponseFormat(message);
+      return;
+    }
+
+    // Handle notification.
+    final event = message[Notification.EVENT];
+    if (event is String) {
+      final paramsJson = message[Notification.PARAMS];
+      if (paramsJson is Map<String, Object?>) {
         if (notificationProcessor != null) {
-          notificationProcessor(
-              Notification(event, message[Notification.PARAMS]));
+          notificationProcessor(Notification(event, paramsJson));
         }
       } else {
-        listener?.unexpectedMessage(message);
+        listener?.unexpectedNotificationFormat(message);
       }
+      return;
     }
+
+    listener?.unexpectedMessage(message);
   }
 
   /// Send a command to the server. An 'id' will be automatically assigned.
@@ -167,18 +183,19 @@
   /// the future will be completed with the 'result' field from the response.
   /// If the server acknowledges the command with an error response,
   /// the future will be completed with an error.
-  Future<Map<String, dynamic>> send(String method, Map<String, dynamic> params);
+  Future<Map<String, Object?>?> send(
+      String method, Map<String, Object?>? params);
 
   /// Encodes a request for transmission and sends it as a utf8 encoded byte
   /// string with [sendWith].
-  Future<Map<String, dynamic>> sendCommandWith(
-      String method, Map<String, dynamic> params, CommandSender sendWith) {
+  Future<Map<String, Object?>?> sendCommandWith(
+      String method, Map<String, Object?>? params, CommandSender sendWith) {
     var id = '${_nextId++}';
     var command = <String, dynamic>{Request.ID: id, Request.METHOD: method};
     if (params != null) {
       command[Request.PARAMS] = params;
     }
-    final completer = Completer<Map<String, dynamic>>();
+    final completer = Completer<Map<String, Object?>?>();
     _pendingCommands[id] = completer;
     var line = json.encode(command);
     listener?.requestSent(line);
diff --git a/pkg/analysis_server_client/pubspec.yaml b/pkg/analysis_server_client/pubspec.yaml
index 0589bc3..8b9c795 100644
--- a/pkg/analysis_server_client/pubspec.yaml
+++ b/pkg/analysis_server_client/pubspec.yaml
@@ -1,15 +1,15 @@
 name: analysis_server_client
-version: 1.1.3
+version: 2.0.0-dev
 description:
   A client wrapper over analysis_server.
   Instances of the class [Server] manage a connection to a server process,
   and facilitate communication to and from the server.
 homepage: https://github.com/dart-lang/sdk/tree/master/pkg/analysis_server_client
 environment:
-  sdk: '>=2.8.0 <3.0.0'
+  sdk: '>=2.12.0 <3.0.0'
 dependencies:
-  path: ^1.7.0
-  pub_semver: ^1.4.4
+  path: ^1.8.0
+  pub_semver: ^2.0.0
 dev_dependencies:
   analyzer:
     path: ../analyzer
diff --git a/pkg/analysis_server_client/test/server_test.dart b/pkg/analysis_server_client/test/server_test.dart
index 2442e5b..286938d 100644
--- a/pkg/analysis_server_client/test/server_test.dart
+++ b/pkg/analysis_server_client/test/server_test.dart
@@ -6,17 +6,20 @@
 import 'dart:convert';
 import 'dart:io';
 
+import 'package:analysis_server_client/listener/server_listener.dart';
 import 'package:analysis_server_client/protocol.dart';
 import 'package:analysis_server_client/server.dart';
 import 'package:test/test.dart';
 
 void main() {
-  MockProcess process;
-  Server server;
+  late _ServerListener listener;
+  late MockProcess process;
+  late Server server;
 
   setUp(() async {
     process = MockProcess();
-    server = Server(process: process);
+    listener = _ServerListener();
+    server = Server(process: process, listener: listener);
   });
 
   group('listenToOutput', () {
@@ -27,7 +30,7 @@
       final future = server.send('blahMethod', null);
       server.listenToOutput();
 
-      final response = await future;
+      final response = (await future)!;
       expect(response['foo'], 'bar');
     });
 
@@ -43,6 +46,7 @@
         expect(error.code, RequestErrorCode.UNKNOWN_REQUEST);
         expect(error.message, 'something went wrong');
         expect(error.stackTrace, 'some long stack trace');
+        return <String, Object?>{};
       });
       server.listenToOutput();
     });
@@ -54,9 +58,10 @@
       final completer = Completer();
       void eventHandler(Notification notification) {
         expect(notification.event, 'fooEvent');
-        expect(notification.params.length, 2);
-        expect(notification.params['foo'] as String, 'bar');
-        expect(notification.params['baz'] as String, 'bang');
+        var params = notification.params!;
+        expect(params.length, 2);
+        expect(params['foo'] as String, 'bar');
+        expect(params['baz'] as String, 'bang');
         completer.complete();
       }
 
@@ -65,6 +70,61 @@
       server.listenToOutput(notificationProcessor: eventHandler);
       await completer.future;
     });
+
+    test('unexpected message', () async {
+      // No 'id', so not a response.
+      // No 'event', so not a notification.
+      process.stdout = Stream.value(
+        utf8.encoder.convert(json.encode({'foo': 'bar'})),
+      );
+      process.stderr = _noMessage();
+
+      server.listenToOutput();
+
+      // Must happen for the test to pass.
+      await listener.unexpectedMessageController.stream.first;
+    });
+
+    test('unexpected notification format', () async {
+      process.stdout = Stream.value(
+        utf8.encoder.convert(json.encode({'event': 'foo', 'noParams': '42'})),
+      );
+      process.stderr = _noMessage();
+
+      server.listenToOutput();
+
+      // Must happen for the test to pass.
+      await listener.unexpectedNotificationFormatCompleter.stream.first;
+    });
+
+    test('unexpected response', () async {
+      // We have no asked anything, but got a response.
+      process.stdout = Stream.value(
+        utf8.encoder.convert(json.encode({'id': '0'})),
+      );
+      process.stderr = _noMessage();
+
+      server.listenToOutput();
+
+      // Must happen for the test to pass.
+      await listener.unexpectedResponseCompleter.stream.first;
+    });
+
+    test('unexpected response format', () async {
+      // We expect that the first request has id `0`.
+      // The response is invalid - the "result" field is not an object.
+      process.stdout = Stream.value(
+        utf8.encoder.convert(json.encode({'id': '0', 'result': '42'})),
+      );
+      process.stderr = _noMessage();
+
+      // ignore: unawaited_futures
+      server.send('blahMethod', null);
+      server.listenToOutput();
+
+      // Must happen for the test to pass.
+      await listener.unexpectedResponseFormatCompleter.stream.first;
+    });
   });
 
   group('stop', () {
@@ -149,16 +209,13 @@
   bool killed = false;
 
   @override
-  Stream<List<int>> stderr;
+  late Stream<List<int>> stderr;
 
   @override
-  Stream<List<int>> stdout;
+  late Stream<List<int>> stdout;
 
   @override
-  Future<int> exitCode;
-
-  @override
-  int get pid => null;
+  late Future<int> exitCode;
 
   @override
   IOSink get stdin => mockin;
@@ -169,43 +226,49 @@
     killed = true;
     return !wasKilled;
   }
+
+  @override
+  dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
 class MockStdin implements IOSink {
   final controller = StreamController<String>();
 
   @override
-  Encoding encoding;
-
-  @override
-  Future get done => null;
-
-  @override
   void add(List<int> data) {
     controller.add(utf8.decode(data));
   }
 
   @override
-  void addError(Object error, [StackTrace stackTrace]) {}
+  dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
+
+class _ServerListener with ServerListener {
+  final unexpectedMessageController = StreamController<Object>();
+  final unexpectedNotificationFormatCompleter = StreamController<Object>();
+  final unexpectedResponseCompleter = StreamController<Object>();
+  final unexpectedResponseFormatCompleter = StreamController<Object>();
 
   @override
-  Future addStream(Stream<List<int>> stream) => null;
+  void log(String prefix, String details) {}
 
   @override
-  Future close() => null;
+  void unexpectedMessage(Map<String, Object?> message) {
+    unexpectedMessageController.add(message);
+  }
 
   @override
-  Future flush() => null;
+  void unexpectedNotificationFormat(Map<String, Object?> message) {
+    unexpectedNotificationFormatCompleter.add(message);
+  }
 
   @override
-  void write(Object obj) {}
+  void unexpectedResponse(Map<String, Object?> message, Object id) {
+    unexpectedResponseCompleter.add(message);
+  }
 
   @override
-  void writeAll(Iterable objects, [String separator = '']) {}
-
-  @override
-  void writeCharCode(int charCode) {}
-
-  @override
-  void writeln([Object obj = '']) {}
+  void unexpectedResponseFormat(Map<String, Object?> message) {
+    unexpectedResponseFormatCompleter.add(message);
+  }
 }
diff --git a/pkg/analyzer/CHANGELOG.md b/pkg/analyzer/CHANGELOG.md
index 0b7792e..53c5713 100644
--- a/pkg/analyzer/CHANGELOG.md
+++ b/pkg/analyzer/CHANGELOG.md
@@ -1,5 +1,19 @@
+## 1.4.0-dev
+* Deprecated `TypeProvider.nonSubtypableClasses`.
+  Use `TypeProvider.isNonSubtypableClass` instead.
+
+## 1.3.0
+* Added `Expression.inConstantContext` to API.
+* Updated documentation comments for some getters that don't return `null`.
+* Fixed an issue with accessing `CompilationUnitElement.mixins` before `types`.
+* Implemented metadata resolution with type arguments and inference.
+* Fixed issue with metadata on enum constants.
+
 ## 1.2.0
 * Deprecated all setters in API of AST. Use `parseString()` instead.
+* `AnalysisSession.getErrors()` does not return `null`, check its `state`.
+* Support for `aliasElement` and `aliasArguments` for aliases of
+  `InterfaceType`s and `TypeParameterType`s.
 
 ## 1.1.0
 * Deprecated `TypeProvider.futureType2()`, `iterableType2()`, etc.
diff --git a/pkg/analyzer/analysis_options.yaml b/pkg/analyzer/analysis_options.yaml
index ed9332f..9996e7f 100644
--- a/pkg/analyzer/analysis_options.yaml
+++ b/pkg/analyzer/analysis_options.yaml
@@ -27,6 +27,7 @@
 linter:
   rules:
     - always_use_package_imports
+    - avoid_dynamic_calls
     - avoid_unused_constructor_parameters
     - await_only_futures
     - empty_statements
diff --git a/pkg/analyzer/example/analyze.dart b/pkg/analyzer/example/analyze.dart
index dcd2920..7442e33 100644
--- a/pkg/analyzer/example/analyze.dart
+++ b/pkg/analyzer/example/analyze.dart
@@ -31,7 +31,7 @@
         continue;
       }
 
-      final errorsResult = (await context.currentSession.getErrors(filePath))!;
+      final errorsResult = await context.currentSession.getErrors(filePath);
       for (final error in errorsResult.errors) {
         if (error.errorCode.type != ErrorType.TODO) {
           print(
diff --git a/pkg/analyzer/lib/dart/analysis/results.dart b/pkg/analyzer/lib/dart/analysis/results.dart
index 7e16f11..4a17594 100644
--- a/pkg/analyzer/lib/dart/analysis/results.dart
+++ b/pkg/analyzer/lib/dart/analysis/results.dart
@@ -16,17 +16,20 @@
 /// Clients may not extend, implement or mix-in this class.
 abstract class AnalysisResult {
   /// The absolute and normalized path of the file that was analyzed.
+  /// If [state] is not [ResultState.VALID], throws [StateError].
   ///
   /// TODO(migration): should not be nullable
   String? get path;
 
   /// Return the session used to compute this result.
+  /// If [state] is not [ResultState.VALID], throws [StateError].
   AnalysisSession get session;
 
   /// The state of the results.
   ResultState get state;
 
   /// The absolute URI of the file that was analyzed.
+  /// If [state] is not [ResultState.VALID], throws [StateError].
   Uri get uri;
 }
 
@@ -35,6 +38,7 @@
 /// Clients may not extend, implement or mix-in this class.
 abstract class AnalysisResultWithErrors implements FileResult {
   /// The analysis errors that were computed during analysis.
+  /// If [state] is not [ResultState.VALID], throws [StateError].
   List<AnalysisError> get errors;
 }
 
@@ -69,9 +73,11 @@
 /// Clients may not extend, implement or mix-in this class.
 abstract class FileResult implements AnalysisResult {
   /// Whether the file is a part.
+  /// If [state] is not [ResultState.VALID], throws [StateError].
   bool get isPart;
 
   /// Information about lines in the content.
+  /// If [state] is not [ResultState.VALID], throws [StateError].
   LineInfo get lineInfo;
 }
 
@@ -174,6 +180,14 @@
   /// directory, or it might not represent anything.
   NOT_A_FILE,
 
+  /// An indication that analysis could not be performed because the path does
+  /// not represent the corresponding URI.
+  ///
+  /// This usually happens in Bazel workspaces, when a URI is resolved to
+  /// a generated file, but there is also a writable file to which this URI
+  /// would be resolved, if there were no generated file.
+  NOT_FILE_OF_URI,
+
   /// An indication that analysis completed normally and the results are valid.
   VALID
 }
diff --git a/pkg/analyzer/lib/dart/analysis/session.dart b/pkg/analyzer/lib/dart/analysis/session.dart
index b922cb2..9fe33e3 100644
--- a/pkg/analyzer/lib/dart/analysis/session.dart
+++ b/pkg/analyzer/lib/dart/analysis/session.dart
@@ -36,9 +36,7 @@
   ///
   /// If the file cannot be analyzed by this session, then the result will have
   /// a result state indicating the nature of the problem.
-  ///
-  /// TODO(migration): should not be nullable
-  Future<ErrorsResult?> getErrors(String path);
+  Future<ErrorsResult> getErrors(String path);
 
   /// Return information about the file at the given absolute, normalized
   /// [path].
@@ -82,9 +80,7 @@
 
   /// Return a future that will complete with information about the results of
   /// resolving the file with the given absolute, normalized [path].
-  ///
-  /// TODO(migration): should not be nullable
-  Future<ResolvedUnitResult?> getResolvedUnit(String path);
+  Future<ResolvedUnitResult> getResolvedUnit(String path);
 
   /// Return a future that will complete with the source kind of the file with
   /// the given absolute, normalized [path]. If the path does not represent a
@@ -96,10 +92,8 @@
 
   /// Return a future that will complete with information about the results of
   /// building the element model for the file with the given absolute,
-  /// normalized[path].
-  ///
-  /// TODO(migration): should not be nullable
-  Future<UnitElementResult?> getUnitElement(String path);
+  /// normalized [path].
+  Future<UnitElementResult> getUnitElement(String path);
 
   /// Return a future that will complete with the signature for the file with
   /// the given absolute, normalized [path], or `null` if the file cannot be
diff --git a/pkg/analyzer/lib/dart/ast/ast.dart b/pkg/analyzer/lib/dart/ast/ast.dart
index 64526cc..41b1d1c 100644
--- a/pkg/analyzer/lib/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/dart/ast/ast.dart
@@ -2144,6 +2144,29 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 abstract class Expression implements CollectionElement {
+  /// An expression _e_ is said to _occur in a constant context_,
+  /// * if _e_ is an element of a constant list literal, or a key or value of an
+  ///   entry of a constant map literal.
+  /// * if _e_ is an actual argument of a constant object expression or of a
+  ///   metadata annotation.
+  /// * if _e_ is the initializing expression of a constant variable
+  ///   declaration.
+  /// * if _e_ is a switch case expression.
+  /// * if _e_ is an immediate subexpression of an expression _e1_ which occurs
+  ///   in a constant context, unless _e1_ is a `throw` expression or a function
+  ///   literal.
+  ///
+  /// This roughly means that everything which is inside a syntactically
+  /// constant expression is in a constant context. A `throw` expression is
+  /// currently not allowed in a constant expression, but extensions affecting
+  /// that status may be considered. A similar situation arises for function
+  /// literals.
+  ///
+  /// Note that the default value of an optional formal parameter is _not_ a
+  /// constant context. This choice reserves some freedom to modify the
+  /// semantics of default values.
+  bool get inConstantContext;
+
   /// Return `true` if this expression is syntactically valid for the LHS of an
   /// [AssignmentExpression].
   bool get isAssignable;
diff --git a/pkg/analyzer/lib/dart/element/element.dart b/pkg/analyzer/lib/dart/element/element.dart
index 85778f6..edfcd2e 100644
--- a/pkg/analyzer/lib/dart/element/element.dart
+++ b/pkg/analyzer/lib/dart/element/element.dart
@@ -531,8 +531,8 @@
   /// element, e.g. a synthetic property accessor), return itself.
   Element? get declaration;
 
-  /// Return the display name of this element, or `null` if this element does
-  /// not have a name.
+  /// Return the display name of this element, possibly the empty string if
+  /// this element does not have a name.
   ///
   /// In most cases the name and the display name are the same. Differences
   /// though are cases such as setters where the name of some setter `set f(x)`
@@ -1041,9 +1041,7 @@
   Element get enclosingElement;
 
   /// Return `true` if this executable element did not have an explicit return
-  /// type specified for it in the original source. Note that if there was no
-  /// explicit return type, and if the element model is fully populated, then
-  /// the [returnType] will not be `null`.
+  /// type specified for it in the original source.
   bool get hasImplicitReturnType;
 
   /// Return `true` if this executable element is abstract. Executable elements
@@ -1231,9 +1229,7 @@
   /// element.
   List<ParameterElement> get parameters;
 
-  /// Return the return type defined by this element. If the element model is
-  /// fully populated, then the [returnType] will not be `null`, even if no
-  /// return type was explicitly specified.
+  /// Return the return type defined by this element.
   DartType get returnType;
 
   /// Return the type defined by this element.
@@ -1874,9 +1870,7 @@
   /// > implicitly static.
   bool get isStatic;
 
-  /// Return the declared type of this variable, or `null` if the variable did
-  /// not have a declared type (such as if it was declared using the keyword
-  /// 'var').
+  /// Return the declared type of this variable.
   DartType get type;
 
   /// Return a representation of the value of this variable, forcing the value
diff --git a/pkg/analyzer/lib/dart/element/type_provider.dart b/pkg/analyzer/lib/dart/element/type_provider.dart
index 75bcf74..f1fb800 100644
--- a/pkg/analyzer/lib/dart/element/type_provider.dart
+++ b/pkg/analyzer/lib/dart/element/type_provider.dart
@@ -78,6 +78,7 @@
 
   /// Return a list containing all of the types that cannot be either extended
   /// or implemented.
+  @Deprecated('Use isNonSubtypableClass instead')
   Set<ClassElement> get nonSubtypableClasses;
 
   /// Return the element representing the built-in class `Null`.
@@ -143,6 +144,9 @@
   @Deprecated('Use futureType instead')
   InterfaceType futureType2(DartType valueType);
 
+  /// Return `true` if [element] cannot be extended, implemented, or mixed in.
+  bool isNonSubtypableClass(ClassElement element);
+
   /// Return 'true' if [id] is the name of a getter on the `Object` type.
   bool isObjectGetter(String id);
 
diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart
index 04edcc1..0317cd7 100644
--- a/pkg/analyzer/lib/error/error.dart
+++ b/pkg/analyzer/lib/error/error.dart
@@ -164,6 +164,7 @@
   CompileTimeErrorCode.EXTENDS_DEFERRED_CLASS,
   CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS,
   CompileTimeErrorCode.EXTENDS_NON_CLASS,
+  CompileTimeErrorCode.EXTENDS_TYPE_ALIAS_EXPANDS_TO_TYPE_PARAMETER,
   CompileTimeErrorCode.EXTENSION_AS_EXPRESSION,
   CompileTimeErrorCode.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE,
   CompileTimeErrorCode.EXTENSION_DECLARES_MEMBER_OF_OBJECT,
@@ -206,6 +207,7 @@
   CompileTimeErrorCode.IMPLEMENTS_NON_CLASS,
   CompileTimeErrorCode.IMPLEMENTS_REPEATED,
   CompileTimeErrorCode.IMPLEMENTS_SUPER_CLASS,
+  CompileTimeErrorCode.IMPLEMENTS_TYPE_ALIAS_EXPANDS_TO_TYPE_PARAMETER,
   CompileTimeErrorCode.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER,
   CompileTimeErrorCode.IMPORT_INTERNAL_LIBRARY,
   CompileTimeErrorCode.IMPORT_OF_NON_LIBRARY,
@@ -287,6 +289,8 @@
   CompileTimeErrorCode.MIXIN_INSTANTIATE,
   CompileTimeErrorCode.MIXIN_OF_DISALLOWED_CLASS,
   CompileTimeErrorCode.MIXIN_OF_NON_CLASS,
+  CompileTimeErrorCode.MIXIN_OF_TYPE_ALIAS_EXPANDS_TO_TYPE_PARAMETER,
+  CompileTimeErrorCode.MIXIN_ON_TYPE_ALIAS_EXPANDS_TO_TYPE_PARAMETER,
   CompileTimeErrorCode.MIXIN_SUPER_CLASS_CONSTRAINT_DEFERRED_CLASS,
   CompileTimeErrorCode.MIXIN_SUPER_CLASS_CONSTRAINT_DISALLOWED_CLASS,
   CompileTimeErrorCode.MIXIN_SUPER_CLASS_CONSTRAINT_NON_INTERFACE,
@@ -476,6 +480,10 @@
   FfiCode.NON_CONSTANT_TYPE_ARGUMENT,
   FfiCode.NON_NATIVE_FUNCTION_TYPE_ARGUMENT_TO_POINTER,
   FfiCode.NON_SIZED_TYPE_ARGUMENT,
+  FfiCode.PACKED_ANNOTATION,
+  FfiCode.PACKED_ANNOTATION_ALIGNMENT,
+  FfiCode.PACKED_NESTING_NON_PACKED,
+  FfiCode.SIZE_ANNOTATION_DIMENSIONS,
   FfiCode.SUBTYPE_OF_FFI_CLASS_IN_EXTENDS,
   FfiCode.SUBTYPE_OF_FFI_CLASS_IN_IMPLEMENTS,
   FfiCode.SUBTYPE_OF_FFI_CLASS_IN_WITH,
@@ -586,6 +594,7 @@
   HintCode.UNNECESSARY_NO_SUCH_METHOD,
   HintCode.UNNECESSARY_NULL_COMPARISON_FALSE,
   HintCode.UNNECESSARY_NULL_COMPARISON_TRUE,
+  HintCode.UNNECESSARY_QUESTION_MARK,
   HintCode.UNNECESSARY_TYPE_CHECK_FALSE,
   HintCode.UNNECESSARY_TYPE_CHECK_TRUE,
   HintCode.UNUSED_CATCH_CLAUSE,
@@ -729,6 +738,9 @@
   ParserErrorCode.INVALID_UNICODE_ESCAPE,
   ParserErrorCode.INVALID_USE_OF_COVARIANT_IN_EXTENSION,
   ParserErrorCode.LIBRARY_DIRECTIVE_NOT_FIRST,
+  ParserErrorCode.LITERAL_WITH_CLASS_AND_NEW,
+  ParserErrorCode.LITERAL_WITH_CLASS,
+  ParserErrorCode.LITERAL_WITH_NEW,
   ParserErrorCode.LOCAL_FUNCTION_DECLARATION_MODIFIER,
   ParserErrorCode.MEMBER_WITH_CLASS_NAME,
   ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR,
diff --git a/pkg/analyzer/lib/error/listener.dart b/pkg/analyzer/lib/error/listener.dart
index e89e8b6..b37838a2 100644
--- a/pkg/analyzer/lib/error/listener.dart
+++ b/pkg/analyzer/lib/error/listener.dart
@@ -120,8 +120,9 @@
   /// Report an error with the given [errorCode] and [arguments]. The [token] is
   /// used to compute the location of the error.
   void reportErrorForToken(ErrorCode errorCode, Token token,
-      [List<Object?>? arguments]) {
-    reportErrorForOffset(errorCode, token.offset, token.length, arguments);
+      [List<Object?>? arguments, List<DiagnosticMessage>? messages]) {
+    reportErrorForOffset(
+        errorCode, token.offset, token.length, arguments, messages);
   }
 
   /// Report an error with the given [errorCode] and [message]. The location of
diff --git a/pkg/analyzer/lib/src/analysis_options/analysis_options_provider.dart b/pkg/analyzer/lib/src/analysis_options/analysis_options_provider.dart
index 6193114..3e512c7 100644
--- a/pkg/analyzer/lib/src/analysis_options/analysis_options_provider.dart
+++ b/pkg/analyzer/lib/src/analysis_options/analysis_options_provider.dart
@@ -62,7 +62,7 @@
   /// Return an empty options map if the file does not exist.
   YamlMap getOptionsFromSource(Source source) {
     YamlMap options = getOptionsFromString(_readAnalysisOptions(source));
-    var node = getValue(options, AnalyzerOptions.include);
+    var node = options.valueAt(AnalyzerOptions.include);
     var sourceFactory = this.sourceFactory;
     if (sourceFactory != null && node is YamlScalar) {
       var path = node.value;
diff --git a/pkg/analyzer/lib/src/command_line/arguments.dart b/pkg/analyzer/lib/src/command_line/arguments.dart
deleted file mode 100644
index 4d71ec1..0000000
--- a/pkg/analyzer/lib/src/command_line/arguments.dart
+++ /dev/null
@@ -1,311 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:collection';
-
-import 'package:analyzer/dart/analysis/features.dart';
-import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/src/context/builder.dart';
-import 'package:analyzer/src/dart/analysis/experiments.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:args/args.dart';
-
-const String analysisOptionsFileOption = 'options';
-const String defaultLanguageVersionOption = 'default-language-version';
-const String defineVariableOption = 'D';
-const String enableExperimentOption = 'enable-experiment';
-const String enableInitializingFormalAccessFlag = 'initializing-formal-access';
-@deprecated
-const String enableSuperMixinFlag = 'supermixin';
-const String flutterAnalysisOptionsPath =
-    'package:flutter/analysis_options_user.yaml';
-const String ignoreUnrecognizedFlagsFlag = 'ignore-unrecognized-flags';
-const String implicitCastsFlag = 'implicit-casts';
-const String lintsFlag = 'lints';
-const String noImplicitDynamicFlag = 'no-implicit-dynamic';
-const String packagesOption = 'packages';
-const String sdkPathOption = 'dart-sdk';
-
-const String sdkSummaryPathOption = 'dart-sdk-summary';
-
-/// Update [options] with the value of each analysis option command line flag.
-void applyAnalysisOptionFlags(AnalysisOptionsImpl options, ArgResults args,
-    {void Function(String text)? verbosePrint}) {
-  void verbose(String text) {
-    if (verbosePrint != null) {
-      verbosePrint('Analysis options: $text');
-    }
-  }
-
-  if (args.wasParsed(enableExperimentOption)) {
-    var flags = args[enableExperimentOption] as List<String>;
-    options.contextFeatures = FeatureSet.fromEnableFlags2(
-      sdkLanguageVersion: ExperimentStatus.currentVersion,
-      flags: flags,
-    );
-  }
-
-  if (args.wasParsed(implicitCastsFlag)) {
-    options.implicitCasts = args[implicitCastsFlag];
-    verbose('$implicitCastsFlag = ${options.implicitCasts}');
-  }
-  if (args.wasParsed(noImplicitDynamicFlag)) {
-    options.implicitDynamic = !args[noImplicitDynamicFlag];
-    verbose('$noImplicitDynamicFlag = ${options.implicitDynamic}');
-  }
-  try {
-    if (args.wasParsed(lintsFlag)) {
-      options.lint = args[lintsFlag];
-      verbose('$lintsFlag = ${options.lint}');
-    }
-  } on ArgumentError {
-    // lints were not defined - ignore and fall through
-  }
-}
-
-/// Use the command-line [args] to create a context builder options.
-ContextBuilderOptions createContextBuilderOptions(
-  ResourceProvider resourceProvider,
-  ArgResults args,
-) {
-  String? absoluteNormalizedPath(String? path) {
-    if (path == null) {
-      return null;
-    }
-    var pathContext = resourceProvider.pathContext;
-    return pathContext.normalize(
-      pathContext.absolute(path),
-    );
-  }
-
-  ContextBuilderOptions builderOptions = ContextBuilderOptions();
-  builderOptions.argResults = args;
-  //
-  // File locations.
-  //
-  builderOptions.dartSdkSummaryPath = absoluteNormalizedPath(
-    args[sdkSummaryPathOption],
-  );
-  builderOptions.defaultAnalysisOptionsFilePath = absoluteNormalizedPath(
-    args[analysisOptionsFileOption],
-  );
-  builderOptions.defaultPackageFilePath = absoluteNormalizedPath(
-    args[packagesOption],
-  );
-  //
-  // Analysis options.
-  //
-  AnalysisOptionsImpl defaultOptions = AnalysisOptionsImpl();
-  applyAnalysisOptionFlags(defaultOptions, args);
-  builderOptions.defaultOptions = defaultOptions;
-  //
-  // Declared variables.
-  //
-  Map<String, String> declaredVariables = <String, String>{};
-  List<String> variables = (args[defineVariableOption] as List).cast<String>();
-  for (String variable in variables) {
-    int index = variable.indexOf('=');
-    if (index < 0) {
-      // TODO (brianwilkerson) Decide the semantics we want in this case.
-      // The VM prints "No value given to -D option", then tries to load '-Dfoo'
-      // as a file and dies. Unless there was nothing after the '-D', in which
-      // case it prints the warning and ignores the option.
-    } else {
-      String name = variable.substring(0, index);
-      if (name.isNotEmpty) {
-        // TODO (brianwilkerson) Decide the semantics we want in the case where
-        // there is no name. If there is no name, the VM tries to load a file
-        // named '-D' and dies.
-        declaredVariables[name] = variable.substring(index + 1);
-      }
-    }
-  }
-  builderOptions.declaredVariables = declaredVariables;
-
-  return builderOptions;
-}
-
-/// 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.
-///
-/// TODO(danrubel) Update DDC to support all the options defined in this method
-/// then remove the [ddc] named argument from this method.
-void defineAnalysisArguments(ArgParser parser,
-    {bool hide = true, bool ddc = false}) {
-  parser.addOption(sdkPathOption,
-      help: 'The path to the Dart SDK.', hide: ddc && hide);
-  parser.addOption(analysisOptionsFileOption,
-      help: 'Path to an analysis options file.', hide: ddc && hide);
-  parser.addFlag('strong',
-      help: 'Enable strong mode (deprecated); this option is now ignored.',
-      defaultsTo: true,
-      hide: true,
-      negatable: true);
-  parser.addFlag('declaration-casts',
-      negatable: true,
-      help: 'Disable declaration casts in strong mode (https://goo.gl/cTLz40)\n'
-          'This option is now ignored and will be removed in a future release.',
-      hide: ddc && hide);
-  parser.addMultiOption(enableExperimentOption,
-      help: 'Enable one or more experimental features. If multiple features '
-          'are being added, they should be comma separated.',
-      splitCommas: true);
-  parser.addFlag(implicitCastsFlag,
-      negatable: true,
-      help: 'Disable implicit casts in strong mode (https://goo.gl/cTLz40).',
-      hide: ddc && hide);
-  parser.addFlag(noImplicitDynamicFlag,
-      negatable: false,
-      help: 'Disable implicit dynamic (https://goo.gl/m0UgXD).',
-      hide: ddc && hide);
-
-  //
-  // Hidden flags and options.
-  //
-  parser.addMultiOption(defineVariableOption,
-      abbr: 'D',
-      help:
-          'Define an environment declaration. For example, "-Dfoo=bar" defines '
-          'an environment declaration named "foo" whose value is "bar".',
-      hide: hide);
-  parser.addOption(packagesOption,
-      help: 'The path to the package resolution configuration file, which '
-          'supplies a mapping of package names\nto paths.',
-      hide: ddc);
-  parser.addOption(sdkSummaryPathOption,
-      help: 'The path to the Dart SDK summary file.', hide: hide);
-  parser.addFlag(enableInitializingFormalAccessFlag,
-      help:
-          'Enable support for allowing access to field formal parameters in a '
-          'constructor\'s initializer list (deprecated).',
-      defaultsTo: false,
-      negatable: false,
-      hide: hide || ddc);
-  if (!ddc) {
-    parser.addFlag(lintsFlag,
-        help: 'Show lint results.', defaultsTo: false, negatable: true);
-  }
-}
-
-/// Find arguments of the form -Dkey=value
-/// or argument pairs of the form -Dkey value
-/// and place those key/value pairs into [definedVariables].
-/// Return a list of arguments with the key/value arguments removed.
-List<String> extractDefinedVariables(
-    List<String> args, Map<String, String> definedVariables) {
-  //TODO(danrubel) extracting defined variables is already handled by the
-  // createContextBuilderOptions method.
-  // Long term we should switch to using that instead.
-  int count = args.length;
-  List<String> remainingArgs = <String>[];
-  for (int i = 0; i < count; i++) {
-    String arg = args[i];
-    if (arg == '--') {
-      while (i < count) {
-        remainingArgs.add(args[i++]);
-      }
-    } else if (arg.startsWith("-D")) {
-      int end = arg.indexOf('=');
-      if (end > 2) {
-        definedVariables[arg.substring(2, end)] = arg.substring(end + 1);
-      } else if (i + 1 < count) {
-        definedVariables[arg.substring(2)] = args[++i];
-      } else {
-        remainingArgs.add(arg);
-      }
-    } else {
-      remainingArgs.add(arg);
-    }
-  }
-  return remainingArgs;
-}
-
-/// Return a list of command-line arguments containing all of the given [args]
-/// that are defined by the given [parser]. An argument is considered to be
-/// defined by the parser if
-/// - it starts with '--' and the rest of the argument (minus any value
-///   introduced by '=') is the name of a known option,
-/// - it starts with '-' and the rest of the argument (minus any value
-///   introduced by '=') is the name of a known abbreviation, or
-/// - it starts with something other than '--' or '-'.
-///
-/// This function allows command-line tools to implement the
-/// '--ignore-unrecognized-flags' option.
-List<String> filterUnknownArguments(List<String> args, ArgParser parser) {
-  Set<String> knownOptions = HashSet<String>();
-  Set<String> knownAbbreviations = HashSet<String>();
-  parser.options.forEach((String name, Option option) {
-    knownOptions.add(name);
-    String? abbreviation = option.abbr;
-    if (abbreviation != null) {
-      knownAbbreviations.add(abbreviation);
-    }
-    if (option.negatable ?? false) {
-      knownOptions.add('no-$name');
-    }
-  });
-  String optionName(int prefixLength, String argument) {
-    int equalsOffset = argument.lastIndexOf('=');
-    if (equalsOffset < 0) {
-      return argument.substring(prefixLength);
-    }
-    return argument.substring(prefixLength, equalsOffset);
-  }
-
-  List<String> filtered = <String>[];
-  for (int i = 0; i < args.length; i++) {
-    String argument = args[i];
-    if (argument.startsWith('--') && argument.length > 2) {
-      if (knownOptions.contains(optionName(2, argument))) {
-        filtered.add(argument);
-      }
-    } else if (argument.startsWith('-') && argument.length > 1) {
-      if (knownAbbreviations.contains(optionName(1, argument))) {
-        filtered.add(argument);
-      }
-    } else {
-      filtered.add(argument);
-    }
-  }
-  return filtered;
-}
-
-/// Use the given [parser] to parse the given command-line [args], and return
-/// the result.
-ArgResults parse(
-    ResourceProvider provider, ArgParser parser, List<String> args) {
-  args = preprocessArgs(provider, args);
-  if (args.contains('--$ignoreUnrecognizedFlagsFlag')) {
-    args = filterUnknownArguments(args, parser);
-  }
-  return parser.parse(args);
-}
-
-/// Preprocess the given list of command line [args].
-/// If the final arg is `@file_path` (Bazel worker mode),
-/// then read in all the lines of that file and add those as args.
-/// Always returns a new modifiable list.
-List<String> preprocessArgs(ResourceProvider provider, List<String> args) {
-  args = List.from(args);
-  if (args.isEmpty) {
-    return args;
-  }
-  String lastArg = args.last;
-  if (lastArg.startsWith('@')) {
-    File argsFile = provider.getFile(lastArg.substring(1));
-    try {
-      args.removeLast();
-      args.addAll(argsFile
-          .readAsStringSync()
-          .replaceAll('\r\n', '\n')
-          .replaceAll('\r', '\n')
-          .split('\n')
-          .where((String line) => line.isNotEmpty));
-    } on FileSystemException catch (e) {
-      throw Exception('Failed to read file specified by $lastArg : $e');
-    }
-  }
-  return args;
-}
diff --git a/pkg/analyzer/lib/src/context/builder.dart b/pkg/analyzer/lib/src/context/builder.dart
index a388bb3..7df7c16 100644
--- a/pkg/analyzer/lib/src/context/builder.dart
+++ b/pkg/analyzer/lib/src/context/builder.dart
@@ -8,8 +8,6 @@
 import 'package:analyzer/dart/analysis/declared_variables.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/src/analysis_options/analysis_options_provider.dart';
-import 'package:analyzer/src/command_line/arguments.dart'
-    show applyAnalysisOptionFlags;
 import 'package:analyzer/src/context/context_root.dart';
 import 'package:analyzer/src/context/packages.dart';
 import 'package:analyzer/src/dart/analysis/byte_store.dart';
@@ -25,14 +23,12 @@
 import 'package:analyzer/src/summary/package_bundle_reader.dart';
 import 'package:analyzer/src/summary/summary_sdk.dart';
 import 'package:analyzer/src/task/options.dart';
-import 'package:analyzer/src/util/file_paths.dart' as file_paths;
 import 'package:analyzer/src/workspace/basic.dart';
 import 'package:analyzer/src/workspace/bazel.dart';
 import 'package:analyzer/src/workspace/gn.dart';
 import 'package:analyzer/src/workspace/package_build.dart';
 import 'package:analyzer/src/workspace/pub.dart';
 import 'package:analyzer/src/workspace/workspace.dart';
-import 'package:args/args.dart';
 import 'package:yaml/yaml.dart';
 
 /// A utility class used to build an analysis context for a given directory.
@@ -145,15 +141,6 @@
     return driver;
   }
 
-  /// Return an analysis options object containing the default option values.
-  AnalysisOptionsImpl createDefaultOptions() {
-    AnalysisOptions? defaultOptions = builderOptions.defaultOptions;
-    if (defaultOptions == null) {
-      return AnalysisOptionsImpl();
-    }
-    return AnalysisOptionsImpl.from(defaultOptions);
-  }
-
 //  void _processAnalysisOptions(
 //      AnalysisContext context, Map<String, YamlNode> optionMap) {
 //    List<OptionsProcessor> optionsProcessors =
@@ -266,30 +253,20 @@
     AnalysisOptionsProvider optionsProvider =
         AnalysisOptionsProvider(sourceFactory);
 
-    AnalysisOptionsImpl options = createDefaultOptions();
-    File? optionsFile = getOptionsFile(path);
-    YamlMap? optionMap;
+    AnalysisOptionsImpl options = AnalysisOptionsImpl();
 
-    if (optionsFile != null) {
+    var optionsPath = builderOptions.defaultAnalysisOptionsFilePath;
+    if (optionsPath != null) {
+      var optionsFile = resourceProvider.getFile(optionsPath);
       try {
-        optionMap = optionsProvider.getOptionsFromFile(optionsFile);
-        if (contextRoot != null) {
-          contextRoot.optionsFilePath = optionsFile.path;
-        }
+        contextRoot?.optionsFilePath = optionsFile.path;
+        var optionsMap = optionsProvider.getOptionsFromFile(optionsFile);
+        applyToAnalysisOptions(options, optionsMap);
         verbose('Loaded analysis options from ${optionsFile.path}');
       } catch (e) {
         // Ignore exceptions thrown while trying to load the options file.
         verbose('Exception: $e\n  when loading ${optionsFile.path}');
       }
-    }
-
-    if (optionMap != null) {
-      applyToAnalysisOptions(options, optionMap);
-      var argResults = builderOptions.argResults;
-      if (argResults != null) {
-        applyAnalysisOptionFlags(options, argResults,
-            verbosePrint: verbosePrint);
-      }
     } else {
       verbose('Using default analysis options');
     }
@@ -306,29 +283,6 @@
     return options;
   }
 
-  /// Return the analysis options file that should be used when analyzing code in
-  /// the directory with the given [path].
-  ///
-  /// If [forceSearch] is true, then don't return the default analysis options
-  /// path. This allows cli to locate what *would* have been the analysis options
-  /// file path, and super-impose the defaults over it in-place.
-  File? getOptionsFile(String path, {bool forceSearch = false}) {
-    if (!forceSearch) {
-      String? filePath = builderOptions.defaultAnalysisOptionsFilePath;
-      if (filePath != null) {
-        return resourceProvider.getFile(filePath);
-      }
-    }
-
-    var folder = resourceProvider.getFolder(path);
-    for (var current in folder.withAncestors) {
-      var file = current.getChildAssumingFile(file_paths.analysisOptionsYaml);
-      if (file.exists) {
-        return file;
-      }
-    }
-  }
-
   /// Return the `pubspec.yaml` file that should be used when analyzing code in
   /// the directory with the given [path], possibly `null`.
   File? _findPubspecFile(String path) {
@@ -411,10 +365,6 @@
 
 /// Options used by a [ContextBuilder].
 class ContextBuilderOptions {
-  /// The results of parsing the command line arguments as defined by
-  /// [defineAnalysisArguments] or `null` if none.
-  ArgResults? argResults;
-
   /// The file path of the file containing the summary of the SDK that should be
   /// used to "analyze" the SDK. This option should only be specified by
   /// command-line tools such as 'dartanalyzer' or 'ddc'.
@@ -428,11 +378,6 @@
   /// A table mapping variable names to values for the declared variables.
   Map<String, String> declaredVariables = {};
 
-  /// The default analysis options that should be used unless some or all of them
-  /// are overridden in the analysis options file, or `null` if the default
-  /// defaults should be used.
-  AnalysisOptions? defaultOptions;
-
   /// The file path of the .packages file that should be used in place of any
   /// file found using the normal (Package Specification DEP) lookup mechanism,
   /// or `null` if the normal lookup mechanism should be used.
diff --git a/pkg/analyzer/lib/src/context/packages.dart b/pkg/analyzer/lib/src/context/packages.dart
index f3dad37..d63d228 100644
--- a/pkg/analyzer/lib/src/context/packages.dart
+++ b/pkg/analyzer/lib/src/context/packages.dart
@@ -5,7 +5,6 @@
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/src/context/package_config_json.dart';
 import 'package:analyzer/src/util/uri.dart';
-// ignore: import_of_legacy_library_into_null_safe
 import 'package:package_config/src/packages_file.dart'
     as package_config_packages_file;
 import 'package:pub_semver/pub_semver.dart';
diff --git a/pkg/analyzer/lib/src/dart/analysis/context_locator.dart b/pkg/analyzer/lib/src/dart/analysis/context_locator.dart
index 6b341e8..3044e88 100644
--- a/pkg/analyzer/lib/src/dart/analysis/context_locator.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/context_locator.dart
@@ -101,7 +101,8 @@
 
       ContextRootImpl? root;
       for (var existingRoot in roots) {
-        if (existingRoot.root == location.rootFolder) {
+        if (existingRoot.root.isOrContains(folder.path) &&
+            _matchRootWithLocation(existingRoot, location)) {
           root = existingRoot;
           break;
         }
@@ -123,11 +124,6 @@
           root.excludedGlobs, defaultOptionsFile, defaultPackagesFile);
     }
 
-    var rootMap = <Folder, ContextRootImpl>{};
-    for (var root in roots) {
-      rootMap[root.root] = root;
-    }
-
     for (File file in includedFiles) {
       Folder parent = file.parent2;
 
@@ -138,16 +134,22 @@
         defaultRootFolder: () => _fileSystemRoot(parent),
       );
 
-      var rootFolder = location.rootFolder;
-      var root = rootMap.putIfAbsent(rootFolder, () {
-        return _createContextRoot(
-          roots,
-          rootFolder: rootFolder,
-          workspace: location.workspace,
-          optionsFile: location.optionsFile,
-          packagesFile: location.packagesFile,
-        );
-      });
+      ContextRootImpl? root;
+      for (var existingRoot in roots) {
+        if (existingRoot.root.isOrContains(file.path) &&
+            _matchRootWithLocation(existingRoot, location)) {
+          root = existingRoot;
+          break;
+        }
+      }
+
+      root ??= _createContextRoot(
+        roots,
+        rootFolder: location.rootFolder,
+        workspace: location.workspace,
+        optionsFile: location.optionsFile,
+        packagesFile: location.packagesFile,
+      );
 
       if (!root.isAnalyzed(file.path)) {
         root.included.add(file);
@@ -433,32 +435,29 @@
             .getOptionsFromFile(optionsFile);
 
         if (doc is YamlMap) {
-          var analyzerOptions = getValue(doc, AnalyzerOptions.analyzer);
+          var analyzerOptions = doc.valueAt(AnalyzerOptions.analyzer);
           if (analyzerOptions is YamlMap) {
             var excludeOptions =
-                getValue(analyzerOptions, AnalyzerOptions.exclude);
+                analyzerOptions.valueAt(AnalyzerOptions.exclude);
             if (excludeOptions is YamlList) {
-              List<String>? excludeList = toStringList(excludeOptions);
-              if (excludeList != null) {
-                var pathContext = resourceProvider.pathContext;
+              var pathContext = resourceProvider.pathContext;
 
-                void addGlob(List<String> components) {
-                  var pattern = posix.joinAll(components);
-                  patterns.add(Glob(pattern, context: pathContext));
+              void addGlob(List<String> components) {
+                var pattern = posix.joinAll(components);
+                patterns.add(Glob(pattern, context: pathContext));
+              }
+
+              for (String excludedPath in excludeOptions.whereType<String>()) {
+                var excludedComponents = posix.split(excludedPath);
+                if (pathContext.isRelative(excludedPath)) {
+                  excludedComponents = [
+                    ...pathContext.split(optionsFile.parent2.path),
+                    ...excludedComponents,
+                  ];
                 }
-
-                for (String excludedPath in excludeList) {
-                  var excludedComponents = posix.split(excludedPath);
-                  if (pathContext.isRelative(excludedPath)) {
-                    excludedComponents = [
-                      ...pathContext.split(optionsFile.parent2.path),
-                      ...excludedComponents,
-                    ];
-                  }
-                  addGlob(excludedComponents);
-                  if (excludedComponents.last == '**') {
-                    addGlob(excludedComponents..removeLast());
-                  }
+                addGlob(excludedComponents);
+                if (excludedComponents.last == '**') {
+                  addGlob(excludedComponents..removeLast());
                 }
               }
             }
@@ -545,6 +544,32 @@
     }
     return second;
   }
+
+  /// Return `true` if the configuration of [existingRoot] is the same as
+  /// the requested configuration for the [location].
+  static bool _matchRootWithLocation(
+    ContextRootImpl existingRoot,
+    _RootLocation location,
+  ) {
+    if (existingRoot.optionsFile != location.optionsFile) {
+      return false;
+    }
+
+    if (existingRoot.packagesFile != location.packagesFile) {
+      return false;
+    }
+
+    // BasicWorkspace has no special meaning, so can be ignored.
+    // Other workspaces have semantic meaning, so must match.
+    var workspace = location.workspace;
+    if (workspace is! BasicWorkspace) {
+      if (existingRoot.workspace.root != workspace.root) {
+        return false;
+      }
+    }
+
+    return true;
+  }
 }
 
 /// The packages [file] found for the [parent].
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index 80c2790..8f17b48 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -44,12 +44,6 @@
 import 'package:analyzer/src/util/file_paths.dart' as file_paths;
 import 'package:meta/meta.dart';
 
-/// TODO(scheglov) We could use generalized Function in
-/// [AnalysisDriverTestView], but this breaks `AnalysisContext` and code
-/// generation. So, for now let's work around them, and rewrite generators to
-/// [AnalysisDriver].
-typedef WorkToWaitAfterComputingResult = Future<void> Function(String path);
-
 /// This class computes [AnalysisResult]s for Dart files.
 ///
 /// Let the set of "explicitly analyzed files" denote the set of paths that have
@@ -86,7 +80,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 = 128;
+  static const int DATA_VERSION = 135;
 
   /// The length of the list returned by [_computeDeclaredVariablesSignature].
   static const int _declaredVariablesSignatureLength = 4;
@@ -528,7 +522,7 @@
     }
     _discoverAvailableFiles();
     _scheduler.notify(this);
-    return _discoverAvailableFilesTask!.completer!.future;
+    return _discoverAvailableFilesTask!.completer.future;
   }
 
   @override
@@ -549,17 +543,16 @@
   }
 
   /// Return a [Future] that completes with the [ErrorsResult] for the Dart
-  /// file with the given [path]. If the file is not a Dart file or cannot
-  /// be analyzed, the [Future] completes with `null`.
+  /// file with the given [path].
   ///
   /// The [path] must be absolute and normalized.
   ///
   /// This method does not use analysis priorities, and must not be used in
   /// interactive analysis, such as Analysis Server or its plugins.
-  Future<ErrorsResult?> getErrors(String path) async {
+  Future<ErrorsResult> getErrors(String path) async {
     _throwIfNotAbsolutePath(path);
     if (!_fsState.hasUri(path)) {
-      return null;
+      return NotValidErrorsResultImpl(ResultState.NOT_FILE_OF_URI);
     }
 
     var completer = Completer<ErrorsResult>();
@@ -642,7 +635,7 @@
       throw ArgumentError('$uri is not a library.');
     }
 
-    UnitElementResult unitResult = (await getUnitElement(file.path!))!;
+    UnitElementResult unitResult = await getUnitElement(file.path!);
     return unitResult.element.library;
   }
 
@@ -784,8 +777,7 @@
   }
 
   /// Return a [Future] that completes with a [ResolvedUnitResult] for the Dart
-  /// file with the given [path]. If the file is not a Dart file or cannot
-  /// be analyzed, the [Future] completes with `null`.
+  /// file with the given [path].
   ///
   /// The [path] must be absolute and normalized.
   ///
@@ -800,11 +792,13 @@
   /// it, which is consistent with the current file state (including new states
   /// of the files previously reported using [changeFile]), prior to the next
   /// time the analysis state transitions to "idle".
-  Future<ResolvedUnitResult?> getResult(String path,
+  Future<ResolvedUnitResult> getResult(String path,
       {bool sendCachedToStream = false}) {
     _throwIfNotAbsolutePath(path);
     if (!_fsState.hasUri(path)) {
-      return Future.value();
+      return Future.value(
+        NotValidResolvedUnitResultImpl(ResultState.NOT_FILE_OF_URI),
+      );
     }
 
     // Return the cached result.
@@ -842,11 +836,13 @@
   }
 
   /// Return a [Future] that completes with the [UnitElementResult] for the
-  /// file with the given [path], or with `null` if the file cannot be analyzed.
-  Future<UnitElementResult?> getUnitElement(String path) {
+  /// file with the given [path].
+  Future<UnitElementResult> getUnitElement(String path) {
     _throwIfNotAbsolutePath(path);
     if (!_fsState.hasUri(path)) {
-      return Future.value();
+      return Future.value(
+        NotValidUnitElementResultImpl(ResultState.NOT_FILE_OF_URI),
+      );
     }
     var completer = Completer<UnitElementResult>();
     _unitElementRequestedFiles
@@ -1312,7 +1308,7 @@
             sourceFactory,
             libraryContext.isLibraryUri,
             libraryContext.analysisContext,
-            libraryContext.elementFactory,
+            libraryContext.elementFactory.libraryOfUri2(library.uriStr),
             libraryContext.analysisSession.inheritanceManager,
             library,
             testingData: testingData);
@@ -1402,7 +1398,7 @@
           sourceFactory,
           libraryContext.isLibraryUri,
           libraryContext.analysisContext,
-          libraryContext.elementFactory,
+          libraryContext.elementFactory.libraryOfUri2(library.uriStr),
           libraryContext.analysisSession.inheritanceManager,
           library,
           testingData: testingData);
@@ -2212,28 +2208,31 @@
 
   final AnalysisDriver driver;
 
-  bool isCompleted = false;
-  Completer<void>? completer = Completer<void>();
+  final Completer<void> completer = Completer<void>();
 
   Iterator<Folder>? folderIterator;
-  List<String>? files = [];
+
+  final List<String> files = [];
+
   int fileIndex = 0;
 
   _DiscoverAvailableFilesTask(this.driver);
 
+  bool get isCompleted => completer.isCompleted;
+
   /// Perform the next piece of work, and set [isCompleted] to `true` to
   /// indicate that the task is done, or keeps it `false` to indicate that the
   /// task should continue to be run.
   void perform() {
     if (folderIterator == null) {
-      files!.addAll(driver.addedFiles);
+      files.addAll(driver.addedFiles);
 
       // Discover SDK libraries.
       var dartSdk = driver._sourceFactory.dartSdk;
       if (dartSdk != null) {
         for (var sdkLibrary in dartSdk.sdkLibraries) {
           var file = dartSdk.mapDartUri(sdkLibrary.shortName)!.fullName;
-          files!.add(file);
+          files.add(file);
         }
       }
 
@@ -2260,22 +2259,18 @@
     }
 
     // Get know files one by one.
-    while (fileIndex < files!.length) {
+    while (fileIndex < files.length) {
       if (timer.elapsedMilliseconds > _MS_WORK_INTERVAL) {
         return;
       }
-      var file = files![fileIndex++];
+      var file = files[fileIndex++];
       driver._fsState.getFileForPath(file);
     }
 
     // The task is done, clean up.
     folderIterator = null;
-    files = null;
-
-    // Complete and clean up.
-    isCompleted = true;
-    completer!.complete();
-    completer = null;
+    files.clear();
+    completer.complete();
   }
 
   void _appendFilesRecursively(Folder folder) {
@@ -2285,7 +2280,7 @@
         if (child is File) {
           var path = child.path;
           if (file_paths.isDart(pathContext, path)) {
-            files!.add(path);
+            files.add(path);
           }
         } else if (child is Folder) {
           _appendFilesRecursively(child);
diff --git a/pkg/analyzer/lib/src/dart/analysis/experiments.g.dart b/pkg/analyzer/lib/src/dart/analysis/experiments.g.dart
index 5d7c6ec..74cac9d 100644
--- a/pkg/analyzer/lib/src/dart/analysis/experiments.g.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/experiments.g.dart
@@ -152,7 +152,7 @@
     isExpired: IsExpired.nonfunction_type_aliases,
     documentation: 'Type aliases define a <type>, not just a <functionType>',
     experimentalReleaseVersion: null,
-    releaseVersion: null,
+    releaseVersion: Version.parse('2.13.0'),
   );
 
   static final set_literals = ExperimentalFeature(
@@ -231,7 +231,7 @@
   static const bool non_nullable = true;
 
   /// Default state of the experiment "nonfunction-type-aliases"
-  static const bool nonfunction_type_aliases = false;
+  static const bool nonfunction_type_aliases = true;
 
   /// Default state of the experiment "set-literals"
   static const bool set_literals = true;
diff --git a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
index 82b883d..137eec9 100644
--- a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
@@ -45,7 +45,6 @@
 import 'package:analyzer/src/lint/linter.dart';
 import 'package:analyzer/src/lint/linter_visitor.dart';
 import 'package:analyzer/src/services/lint.dart';
-import 'package:analyzer/src/summary2/linked_element_factory.dart';
 import 'package:analyzer/src/task/strong/checker.dart';
 import 'package:pub_semver/pub_semver.dart';
 
@@ -70,9 +69,8 @@
   final InheritanceManager3 _inheritance;
   final bool Function(Uri) _isLibraryUri;
   final AnalysisContext _context;
-  final LinkedElementFactory _elementFactory;
 
-  late final LibraryElementImpl _libraryElement;
+  final LibraryElementImpl _libraryElement;
 
   final Map<FileState, LineInfo> _fileToLineInfo = {};
 
@@ -91,7 +89,7 @@
       this._sourceFactory,
       this._isLibraryUri,
       this._context,
-      this._elementFactory,
+      this._libraryElement,
       this._inheritance,
       this._library,
       {TestingData? testingData})
@@ -118,8 +116,6 @@
     }
     timerLibraryAnalyzerFreshUnit.stop();
 
-    _libraryElement = _elementFactory.libraryOfUri2(_library.uriStr);
-
     // Resolve URIs in directives to corresponding sources.
     FeatureSet featureSet = units[_library]!.featureSet;
     units.forEach((file, unit) {
@@ -180,9 +176,13 @@
     // before the list of diagnostics has been filtered.
     for (var file in _library.libraryFiles) {
       if (file.source != null) {
-        IgnoreValidator(_getErrorReporter(file), _getErrorListener(file).errors,
-                _fileToIgnoreInfo[file]!, _fileToLineInfo[file]!)
-            .reportErrors();
+        IgnoreValidator(
+          _getErrorReporter(file),
+          _getErrorListener(file).errors,
+          _fileToIgnoreInfo[file]!,
+          _fileToLineInfo[file]!,
+          _analysisOptions.unignorableNames,
+        ).reportErrors();
       }
     }
 
@@ -429,10 +429,15 @@
 
     LineInfo lineInfo = _fileToLineInfo[file]!;
 
+    var unignorableCodes = _analysisOptions.unignorableNames;
+
     bool isIgnored(AnalysisError error) {
       var code = error.errorCode;
-      // Don't allow error severity issues to be ignored.
-      if (!IgnoreValidator.isIgnorable(file.path!, code)) {
+      // Don't allow un-ignorable codes to be ignored.
+      if (unignorableCodes.contains(code.name) ||
+          unignorableCodes.contains(code.uniqueName) ||
+          // Lint rules have lower case names.
+          unignorableCodes.contains(code.name.toUpperCase())) {
         return false;
       }
 
diff --git a/pkg/analyzer/lib/src/dart/analysis/results.dart b/pkg/analyzer/lib/src/dart/analysis/results.dart
index f8932cd..c2e5b28 100644
--- a/pkg/analyzer/lib/src/dart/analysis/results.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/results.dart
@@ -8,6 +8,7 @@
 import 'package:analyzer/dart/ast/visitor.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type_provider.dart';
+import 'package:analyzer/dart/element/type_system.dart';
 import 'package:analyzer/error/error.dart';
 import 'package:analyzer/source/line_info.dart';
 import 'package:analyzer/src/dart/element/type_system.dart';
@@ -66,6 +67,108 @@
   ResultState get state => ResultState.VALID;
 }
 
+/// The implementation of [AnalysisResult] when not [ResultState.VALID].
+class NotValidAnalysisResultImpl implements AnalysisResult {
+  @override
+  final ResultState state;
+
+  NotValidAnalysisResultImpl(this.state);
+
+  @override
+  String? get path {
+    throw StateError('This result is not valid');
+  }
+
+  @override
+  AnalysisSession get session {
+    throw StateError('This result is not valid');
+  }
+
+  @override
+  Uri get uri {
+    throw StateError('This result is not valid');
+  }
+}
+
+/// The implementation of [ErrorsResult] when not [ResultState.VALID].
+class NotValidErrorsResultImpl extends NotValidFileResultImpl
+    implements ErrorsResult {
+  NotValidErrorsResultImpl(ResultState state) : super(state);
+
+  @override
+  List<AnalysisError> get errors {
+    throw StateError('This result is not valid');
+  }
+}
+
+/// The implementation of [FileResult] when not [ResultState.VALID].
+class NotValidFileResultImpl extends NotValidAnalysisResultImpl
+    implements FileResult {
+  NotValidFileResultImpl(ResultState state) : super(state);
+
+  @override
+  bool get isPart {
+    throw StateError('This result is not valid');
+  }
+
+  @override
+  LineInfo get lineInfo {
+    throw StateError('This result is not valid');
+  }
+}
+
+/// The implementation of [ResolvedUnitResult] when not [ResultState.VALID].
+class NotValidResolvedUnitResultImpl extends NotValidFileResultImpl
+    implements ResolvedUnitResult {
+  NotValidResolvedUnitResultImpl(ResultState state) : super(state);
+
+  @override
+  String? get content {
+    throw StateError('This result is not valid');
+  }
+
+  @override
+  List<AnalysisError> get errors {
+    throw StateError('This result is not valid');
+  }
+
+  @override
+  LibraryElement get libraryElement {
+    throw StateError('This result is not valid');
+  }
+
+  @override
+  TypeProvider get typeProvider {
+    throw StateError('This result is not valid');
+  }
+
+  @override
+  TypeSystem get typeSystem {
+    throw StateError('This result is not valid');
+  }
+
+  @override
+  CompilationUnit? get unit {
+    throw StateError('This result is not valid');
+  }
+}
+
+/// The implementation of [UnitElementResult] when not [ResultState.VALID].
+class NotValidUnitElementResultImpl extends NotValidAnalysisResultImpl
+    implements UnitElementResult {
+  NotValidUnitElementResultImpl(ResultState state) : super(state);
+
+  @override
+  CompilationUnitElement get element {
+    throw StateError('This result is not valid');
+  }
+
+  @override
+  String get signature {
+    throw StateError('This result is not valid');
+  }
+}
+
 class ParsedLibraryResultImpl extends AnalysisResultImpl
     implements ParsedLibraryResult {
   @override
@@ -199,8 +302,13 @@
       (r) => r.path == elementPath,
       orElse: () {
         var elementStr = element.getDisplayString(withNullability: true);
-        throw ArgumentError('Element (${element.runtimeType}) $elementStr is '
-            'not defined in this library.');
+        var buffer = StringBuffer();
+        buffer.write('Element (${element.runtimeType}) $elementStr');
+        buffer.writeln(' is not defined in this library.');
+        // TODO(scheglov) https://github.com/dart-lang/sdk/issues/45430
+        buffer.writeln('elementPath: $elementPath');
+        buffer.writeln('unitPaths: ${units!.map((e) => e.path).toList()}');
+        throw ArgumentError('$buffer');
       },
     );
 
diff --git a/pkg/analyzer/lib/src/dart/analysis/search.dart b/pkg/analyzer/lib/src/dart/analysis/search.dart
index 821ebf0..7d24cf9 100644
--- a/pkg/analyzer/lib/src/dart/analysis/search.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/search.dart
@@ -55,7 +55,7 @@
     for (String file in files) {
       if (searchedFiles.add(file, this)) {
         var unitResult = await _driver.getUnitElement(file);
-        if (unitResult != null) {
+        if (unitResult.state == ResultState.VALID) {
           unitResult.element.types.forEach(addElements);
           unitResult.element.mixins.forEach(addElements);
         }
@@ -175,7 +175,7 @@
     List<FileState> knownFiles = _driver.fsState.knownFiles.toList();
     for (FileState file in knownFiles) {
       var unitResult = await _driver.getUnitElement(file.path!);
-      if (unitResult != null) {
+      if (unitResult.state == ResultState.VALID) {
         CompilationUnitElement unitElement = unitResult.element;
         unitElement.accessors.forEach(addElement);
         unitElement.enums.forEach(addElement);
@@ -284,7 +284,7 @@
 
   Future<CompilationUnitElement?> _getUnitElement(String file) async {
     var result = await _driver.getUnitElement(file);
-    return result?.element;
+    return result.state == ResultState.VALID ? result.element : null;
   }
 
   Future<List<SearchResult>> _searchReferences(
@@ -378,7 +378,7 @@
     LibraryElement libraryElement = element.library;
     for (CompilationUnitElement unitElement in libraryElement.units) {
       String unitPath = unitElement.source.fullName;
-      ResolvedUnitResult unitResult = (await _driver.getResult(unitPath))!;
+      ResolvedUnitResult unitResult = await _driver.getResult(unitPath);
       _ImportElementReferencesVisitor visitor =
           _ImportElementReferencesVisitor(element, unitElement);
       unitResult.unit!.accept(visitor);
@@ -397,7 +397,7 @@
     List<SearchResult> results = <SearchResult>[];
     for (CompilationUnitElement unitElement in element.units) {
       String unitPath = unitElement.source.fullName;
-      ResolvedUnitResult unitResult = (await _driver.getResult(unitPath))!;
+      ResolvedUnitResult unitResult = await _driver.getResult(unitPath);
       CompilationUnit unit = unitResult.unit!;
       for (Directive directive in unit.directives) {
         if (directive is PartOfDirective && directive.element == element) {
@@ -422,7 +422,7 @@
     }
 
     // Prepare the unit.
-    ResolvedUnitResult unitResult = (await _driver.getResult(path))!;
+    ResolvedUnitResult unitResult = await _driver.getResult(path);
     var unit = unitResult.unit;
     if (unit == null) {
       return const <SearchResult>[];
@@ -475,7 +475,7 @@
     LibraryElement libraryElement = element.library;
     for (CompilationUnitElement unitElement in libraryElement.units) {
       String unitPath = unitElement.source.fullName;
-      ResolvedUnitResult unitResult = (await _driver.getResult(unitPath))!;
+      ResolvedUnitResult unitResult = await _driver.getResult(unitPath);
       _LocalReferencesVisitor visitor =
           _LocalReferencesVisitor(element, unitElement);
       unitResult.unit!.accept(visitor);
diff --git a/pkg/analyzer/lib/src/dart/analysis/session.dart b/pkg/analyzer/lib/src/dart/analysis/session.dart
index 7754ffa..7153b15 100644
--- a/pkg/analyzer/lib/src/dart/analysis/session.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/session.dart
@@ -59,7 +59,7 @@
   driver.AnalysisDriver getDriver() => _driver;
 
   @override
-  Future<ErrorsResult?> getErrors(String path) {
+  Future<ErrorsResult> getErrors(String path) {
     _checkConsistency();
     return _driver.getErrors(path);
   }
@@ -115,7 +115,7 @@
   }
 
   @override
-  Future<ResolvedUnitResult?> getResolvedUnit(String path) {
+  Future<ResolvedUnitResult> getResolvedUnit(String path) {
     _checkConsistency();
     return _driver.getResult(path);
   }
@@ -127,7 +127,7 @@
   }
 
   @override
-  Future<UnitElementResult?> getUnitElement(String path) {
+  Future<UnitElementResult> getUnitElement(String path) {
     _checkConsistency();
     return _driver.getUnitElement(path);
   }
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 b9658e1..74e302c 100644
--- a/pkg/analyzer/lib/src/dart/analysis/unlinked_api_signature.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/unlinked_api_signature.dart
@@ -20,11 +20,40 @@
   static const int _kindConstructorDeclaration = 1;
   static const int _kindFieldDeclaration = 2;
   static const int _kindMethodDeclaration = 3;
+  static const int _nullNode = 0;
+  static const int _notNullNode = 1;
+  static const int _nullToken = 0;
+  static const int _notNullToken = 1;
 
   final ApiSignature signature = ApiSignature();
 
-  void addClassOrMixin(ClassOrMixinDeclaration node) {
-    addTokens(node.beginToken, node.leftBracket);
+  void compute(CompilationUnit unit) {
+    signature.addFeatureSet(unit.featureSet);
+
+    signature.addInt(unit.directives.length);
+    unit.directives.forEach(_addNode);
+
+    signature.addInt(unit.declarations.length);
+    for (var declaration in unit.declarations) {
+      if (declaration is ClassOrMixinDeclaration) {
+        _addClassOrMixin(declaration);
+      } else if (declaration is FunctionDeclaration) {
+        var functionExpression = declaration.functionExpression;
+        _addTokens(
+          declaration.beginToken,
+          (functionExpression.parameters ?? declaration.name).endToken,
+        );
+        _addFunctionBodyModifiers(functionExpression.body);
+      } else if (declaration is TopLevelVariableDeclaration) {
+        _topLevelVariableDeclaration(declaration);
+      } else {
+        _addNode(declaration);
+      }
+    }
+  }
+
+  void _addClassOrMixin(ClassOrMixinDeclaration node) {
+    _addTokens(node.beginToken, node.leftBracket);
 
     bool hasConstConstructor = node.members
         .any((m) => m is ConstructorDeclaration && m.constKeyword != null);
@@ -33,67 +62,70 @@
     for (var member in node.members) {
       if (member is ConstructorDeclaration) {
         signature.addInt(_kindConstructorDeclaration);
-        addTokens(member.beginToken, member.parameters.endToken);
+        _addTokens(member.beginToken, member.parameters.endToken);
         if (member.constKeyword != null) {
-          addNodeList(member.initializers);
+          _addNodeList(member.initializers);
         }
-        addNode(member.redirectedConstructor);
+        _addNode(member.redirectedConstructor);
       } else if (member is FieldDeclaration) {
         signature.addInt(_kindFieldDeclaration);
-        var variableList = member.fields;
-        addVariables(
-          member,
-          variableList,
-          !member.isStatic && variableList.isFinal && hasConstConstructor,
-        );
+        _fieldDeclaration(member, hasConstConstructor);
       } else if (member is MethodDeclaration) {
         signature.addInt(_kindMethodDeclaration);
-        addTokens(
+        _addTokens(
           member.beginToken,
           (member.parameters ?? member.name).endToken,
         );
         signature.addBool(member.body is EmptyFunctionBody);
-        addFunctionBodyModifiers(member.body);
+        _addFunctionBodyModifiers(member.body);
       } else {
         throw UnimplementedError('(${member.runtimeType}) $member');
       }
     }
 
-    addToken(node.rightBracket);
+    _addToken(node.rightBracket);
   }
 
-  void addFunctionBodyModifiers(FunctionBody? node) {
+  void _addFunctionBodyModifiers(FunctionBody? node) {
     if (node != null) {
       signature.addBool(node.isSynchronous);
       signature.addBool(node.isGenerator);
     }
   }
 
-  void addNode(AstNode? node) {
+  void _addNode(AstNode? node) {
     if (node != null) {
-      addTokens(node.beginToken, node.endToken);
+      signature.addInt(_notNullNode);
+      _addTokens(node.beginToken, node.endToken);
+    } else {
+      signature.addInt(_nullNode);
     }
   }
 
-  void addNodeList(List<AstNode> nodes) {
+  void _addNodeList(List<AstNode> nodes) {
     for (var node in nodes) {
-      addNode(node);
+      _addNode(node);
     }
   }
 
-  void addToken(Token token) {
-    signature.addString(token.lexeme);
+  void _addToken(Token? token) {
+    if (token != null) {
+      signature.addInt(_notNullToken);
+      signature.addString(token.lexeme);
+    } else {
+      signature.addInt(_nullToken);
+    }
   }
 
   /// Appends tokens from [begin] (including), to [end] (also including).
-  void addTokens(Token begin, Token end) {
+  void _addTokens(Token begin, Token end) {
     if (begin is CommentToken) {
       begin = begin.parent!;
     }
 
     Token? token = begin;
     while (token != null) {
-      addToken(token);
+      _addToken(token);
 
       if (token == end) {
         break;
@@ -110,48 +142,42 @@
     }
   }
 
-  void addVariables(
-    AstNode node,
-    VariableDeclarationList variableList,
-    bool includeInitializers,
-  ) {
-    if (variableList.type == null ||
-        variableList.isConst ||
-        includeInitializers) {
-      addTokens(node.beginToken, node.endToken);
-    } else {
-      addTokens(node.beginToken, variableList.type!.endToken);
+  void _fieldDeclaration(FieldDeclaration node, bool hasConstConstructor) {
+    _addToken(node.abstractKeyword);
+    _addToken(node.covariantKeyword);
+    _addToken(node.externalKeyword);
+    _addToken(node.staticKeyword);
+    _addNodeList(node.metadata);
 
-      signature.addInt(variableList.variables.length);
-      for (var variable in variableList.variables) {
-        addTokens(variable.beginToken, variable.name.endToken);
-        signature.addBool(variable.initializer != null);
-        addToken(variable.endToken.next!); // `,` or `;`
-      }
-    }
+    var variableList = node.fields;
+    var includeInitializers = variableList.type == null ||
+        variableList.isConst ||
+        hasConstConstructor && !node.isStatic && variableList.isFinal;
+    _variableList(variableList, includeInitializers);
   }
 
-  void compute(CompilationUnit unit) {
-    signature.addFeatureSet(unit.featureSet);
+  void _topLevelVariableDeclaration(TopLevelVariableDeclaration node) {
+    _addToken(node.externalKeyword);
+    _addNodeList(node.metadata);
 
-    signature.addInt(unit.directives.length);
-    unit.directives.forEach(addNode);
+    var variableList = node.variables;
+    var includeInitializers = variableList.type == null || variableList.isConst;
+    _variableList(variableList, includeInitializers);
+  }
 
-    signature.addInt(unit.declarations.length);
-    for (var declaration in unit.declarations) {
-      if (declaration is ClassOrMixinDeclaration) {
-        addClassOrMixin(declaration);
-      } else if (declaration is FunctionDeclaration) {
-        var functionExpression = declaration.functionExpression;
-        addTokens(
-          declaration.beginToken,
-          (functionExpression.parameters ?? declaration.name).endToken,
-        );
-        addFunctionBodyModifiers(functionExpression.body);
-      } else if (declaration is TopLevelVariableDeclaration) {
-        addVariables(declaration, declaration.variables, false);
-      } else {
-        addNode(declaration);
+  void _variableList(VariableDeclarationList node, bool includeInitializers) {
+    _addToken(node.keyword);
+    _addToken(node.lateKeyword);
+    _addNode(node.type);
+
+    var variables = node.variables;
+    signature.addInt(variables.length);
+
+    for (var variable in variables) {
+      _addNode(variable.name);
+      signature.addBool(variable.initializer != null);
+      if (includeInitializers) {
+        _addNode(variable.initializer);
       }
     }
   }
diff --git a/pkg/analyzer/lib/src/dart/ast/ast.dart b/pkg/analyzer/lib/src/dart/ast/ast.dart
index e38573d..e2f7ed12 100644
--- a/pkg/analyzer/lib/src/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/src/dart/ast/ast.dart
@@ -1488,10 +1488,7 @@
 
   @override
   Token get firstTokenAfterCommentAndMetadata {
-    if (abstractKeyword != null) {
-      return abstractKeyword!;
-    }
-    return classKeyword;
+    return abstractKeyword ?? classKeyword;
   }
 
   @override
@@ -1727,10 +1724,7 @@
 
   @override
   Token get firstTokenAfterCommentAndMetadata {
-    if (abstractKeyword != null) {
-      return abstractKeyword!;
-    }
-    return typedefKeyword;
+    return abstractKeyword ?? typedefKeyword;
   }
 
   @override
@@ -2478,12 +2472,9 @@
 
   @override
   Token get firstTokenAfterCommentAndMetadata {
-    Token? leftMost =
-        Token.lexicallyFirst([externalKeyword, constKeyword, factoryKeyword]);
-    if (leftMost != null) {
-      return leftMost;
-    }
-    return _returnType.beginToken;
+    return Token.lexicallyFirst(
+            externalKeyword, constKeyword, factoryKeyword) ??
+        _returnType.beginToken;
   }
 
   @override
@@ -2810,12 +2801,7 @@
 
   @override
   Token get firstTokenAfterCommentAndMetadata {
-    if (keyword != null) {
-      return keyword!;
-    } else if (_type != null) {
-      return _type!.beginToken;
-    }
-    return _identifier.beginToken;
+    return keyword ?? _type?.beginToken ?? _identifier.beginToken;
   }
 
   @override
@@ -3490,27 +3476,7 @@
   @override
   DartType? staticType;
 
-  /// An expression _e_ is said to _occur in a constant context_,
-  /// * if _e_ is an element of a constant list literal, or a key or value of an
-  ///   entry of a constant map literal.
-  /// * if _e_ is an actual argument of a constant object expression or of a
-  ///   metadata annotation.
-  /// * if _e_ is the initializing expression of a constant variable
-  ///   declaration.
-  /// * if _e_ is a switch case expression.
-  /// * if _e_ is an immediate subexpression of an expression _e1_ which occurs
-  ///   in a constant context, unless _e1_ is a `throw` expression or a function
-  ///   literal.
-  ///
-  /// This roughly means that everything which is inside a syntactically
-  /// constant expression is in a constant context. A `throw` expression is
-  /// currently not allowed in a constant expression, but extensions affecting
-  /// that status may be considered. A similar situation arises for function
-  /// literals.
-  ///
-  /// Note that the default value of an optional formal parameter is _not_ a
-  /// constant context. This choice reserves some freedom to modify the
-  /// semantics of default values.
+  @override
   bool get inConstantContext {
     AstNode child = this;
     while (child is Expression ||
@@ -3958,16 +3924,9 @@
 
   @override
   Token get firstTokenAfterCommentAndMetadata {
-    if (abstractKeyword != null) {
-      return abstractKeyword!;
-    } else if (externalKeyword != null) {
-      return externalKeyword!;
-    } else if (covariantKeyword != null) {
-      return covariantKeyword!;
-    } else if (staticKeyword != null) {
-      return staticKeyword!;
-    }
-    return _fieldList.beginToken;
+    return Token.lexicallyFirst(abstractKeyword, externalKeyword,
+            covariantKeyword, staticKeyword) ??
+        _fieldList.beginToken;
   }
 
   @override
@@ -4802,14 +4761,10 @@
 
   @override
   Token get firstTokenAfterCommentAndMetadata {
-    if (externalKeyword != null) {
-      return externalKeyword!;
-    } else if (_returnType != null) {
-      return _returnType!.beginToken;
-    } else if (propertyKeyword != null) {
-      return propertyKeyword!;
-    }
-    return _name.beginToken;
+    return externalKeyword ??
+        _returnType?.beginToken ??
+        propertyKeyword ??
+        _name.beginToken;
   }
 
   @override
@@ -6926,18 +6881,10 @@
 
   @override
   Token get firstTokenAfterCommentAndMetadata {
-    if (externalKeyword != null) {
-      return externalKeyword!;
-    } else if (modifierKeyword != null) {
-      return modifierKeyword!;
-    } else if (_returnType != null) {
-      return _returnType!.beginToken;
-    } else if (propertyKeyword != null) {
-      return propertyKeyword!;
-    } else if (operatorKeyword != null) {
-      return operatorKeyword!;
-    }
-    return _name.beginToken;
+    return Token.lexicallyFirst(externalKeyword, modifierKeyword) ??
+        _returnType?.beginToken ??
+        Token.lexicallyFirst(propertyKeyword, operatorKeyword) ??
+        _name.beginToken;
   }
 
   @override
@@ -10530,14 +10477,9 @@
 
   @override
   Token get firstTokenAfterCommentAndMetadata {
-    if (lateKeyword != null) {
-      return lateKeyword!;
-    } else if (keyword != null) {
-      return keyword!;
-    } else if (_type != null) {
-      return _type!.beginToken;
-    }
-    return _variables.beginToken!;
+    return Token.lexicallyFirst(lateKeyword, keyword) ??
+        _type?.beginToken ??
+        _variables.beginToken!;
   }
 
   @override
diff --git a/pkg/analyzer/lib/src/dart/ast/constant_evaluator.dart b/pkg/analyzer/lib/src/dart/ast/constant_evaluator.dart
index f2e5968..ae49c26 100644
--- a/pkg/analyzer/lib/src/dart/ast/constant_evaluator.dart
+++ b/pkg/analyzer/lib/src/dart/ast/constant_evaluator.dart
@@ -179,6 +179,14 @@
         if (leftOperand is int && rightOperand is int) {
           return leftOperand >> rightOperand;
         }
+      } else if (node.operator.type == TokenType.GT_GT_GT) {
+        if (leftOperand is int && rightOperand is int) {
+          // TODO(srawlins): Replace with native VM implementation once stable.
+          return rightOperand >= 64
+              ? 0
+              : (leftOperand >> rightOperand) &
+                  ((1 << (64 - rightOperand)) - 1);
+        }
       } else if (node.operator.type == TokenType.LT) {
         // numeric or {@code null}
         if (leftOperand is num && rightOperand is num) {
diff --git a/pkg/analyzer/lib/src/dart/ast/extensions.dart b/pkg/analyzer/lib/src/dart/ast/extensions.dart
index 7451b12..03225d1 100644
--- a/pkg/analyzer/lib/src/dart/ast/extensions.dart
+++ b/pkg/analyzer/lib/src/dart/ast/extensions.dart
@@ -143,3 +143,18 @@
     return cast<FormalParameterImpl>();
   }
 }
+
+extension TypeAnnotationExtension on TypeAnnotation {
+  /// Return the static type of this type annotation.
+  ///
+  /// This accessor should be used on expressions that are expected to
+  /// be already resolved. Every such expression must have the type set,
+  /// at least `dynamic`.
+  DartType get typeOrThrow {
+    var type = this.type;
+    if (type == null) {
+      throw StateError('No type: $this');
+    }
+    return type;
+  }
+}
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 4335edf..0f5f371 100644
--- a/pkg/analyzer/lib/src/dart/ast/to_source_visitor.dart
+++ b/pkg/analyzer/lib/src/dart/ast/to_source_visitor.dart
@@ -367,9 +367,6 @@
 
   @override
   void visitDefaultFormalParameter(DefaultFormalParameter node) {
-    if (node.isRequiredNamed) {
-      sink.write('required ');
-    }
     safelyVisitNode(node.parameter);
     if (node.separator != null) {
       if (node.separator!.lexeme != ":") {
@@ -974,6 +971,7 @@
   @override
   void visitSimpleFormalParameter(SimpleFormalParameter node) {
     safelyVisitNodeListWithSeparatorAndSuffix(node.metadata, ' ', ' ');
+    safelyVisitTokenWithSuffix(node.requiredKeyword, ' ');
     safelyVisitTokenWithSuffix(node.covariantKeyword, ' ');
     safelyVisitTokenWithSuffix(node.keyword, " ");
     safelyVisitNode(node.type);
diff --git a/pkg/analyzer/lib/src/dart/ast/utilities.dart b/pkg/analyzer/lib/src/dart/ast/utilities.dart
index 33092e5..8989422 100644
--- a/pkg/analyzer/lib/src/dart/ast/utilities.dart
+++ b/pkg/analyzer/lib/src/dart/ast/utilities.dart
@@ -80,7 +80,7 @@
       if (_lastClonedOffset <= token.offset) {
         _cloneTokens(_nextToClone ?? token, token.offset);
       }
-      return _clonedTokens[token]!;
+      return _clonedTokens[token];
     } else {
       return token;
     }
@@ -4002,1528 +4002,6 @@
   }
 }
 
-/// An object that copies resolution information from one AST structure to
-/// another as long as the structures of the corresponding children of a pair of
-/// nodes are the same.
-class ResolutionCopier implements AstVisitor<bool> {
-  /// The AST node with which the node being visited is to be compared. This is
-  /// only valid at the beginning of each visit method (until [isEqualNodes] is
-  /// invoked).
-  AstNode? _toNode;
-
-  @override
-  bool visitAdjacentStrings(AdjacentStrings node) {
-    var toNode = _toNode as AdjacentStringsImpl;
-    if (_isEqualNodeLists(node.strings, toNode.strings)) {
-      toNode.staticType = node.staticType;
-      return true;
-    }
-    return false;
-  }
-
-  @override
-  bool visitAnnotation(Annotation node) {
-    var toNode = _toNode as AnnotationImpl;
-    if (_and(
-        _isEqualTokens(node.atSign, toNode.atSign),
-        _isEqualNodes(node.name, toNode.name),
-        _isEqualNodes(node.typeArguments, toNode.typeArguments),
-        _isEqualTokens(node.period, toNode.period),
-        _isEqualNodes(node.constructorName, toNode.constructorName),
-        _isEqualNodes(node.arguments, toNode.arguments))) {
-      toNode.element = node.element;
-      return true;
-    }
-    return false;
-  }
-
-  @override
-  bool visitArgumentList(ArgumentList node) {
-    var toNode = _toNode as ArgumentListImpl;
-    return _and(
-        _isEqualTokens(node.leftParenthesis, toNode.leftParenthesis),
-        _isEqualNodeLists(node.arguments, toNode.arguments),
-        _isEqualTokens(node.rightParenthesis, toNode.rightParenthesis));
-  }
-
-  @override
-  bool visitAsExpression(AsExpression node) {
-    var toNode = _toNode as AsExpressionImpl;
-    if (_and(
-        _isEqualNodes(node.expression, toNode.expression),
-        _isEqualTokens(node.asOperator, toNode.asOperator),
-        _isEqualNodes(node.type, toNode.type))) {
-      toNode.staticType = node.staticType;
-      return true;
-    }
-    return false;
-  }
-
-  @override
-  bool visitAssertInitializer(AssertInitializer node) {
-    var toNode = _toNode as AssertInitializerImpl;
-    return _and(
-        _isEqualTokens(node.assertKeyword, toNode.assertKeyword),
-        _isEqualTokens(node.leftParenthesis, toNode.leftParenthesis),
-        _isEqualNodes(node.condition, toNode.condition),
-        _isEqualTokens(node.comma, toNode.comma),
-        _isEqualNodes(node.message, toNode.message),
-        _isEqualTokens(node.rightParenthesis, toNode.rightParenthesis));
-  }
-
-  @override
-  bool visitAssertStatement(AssertStatement node) {
-    var toNode = _toNode as AssertStatementImpl;
-    return _and(
-        _isEqualTokens(node.assertKeyword, toNode.assertKeyword),
-        _isEqualTokens(node.leftParenthesis, toNode.leftParenthesis),
-        _isEqualNodes(node.condition, toNode.condition),
-        _isEqualTokens(node.comma, toNode.comma),
-        _isEqualNodes(node.message, toNode.message),
-        _isEqualTokens(node.rightParenthesis, toNode.rightParenthesis),
-        _isEqualTokens(node.semicolon, toNode.semicolon));
-  }
-
-  @override
-  bool visitAssignmentExpression(AssignmentExpression node) {
-    var toNode = _toNode as AssignmentExpressionImpl;
-    if (_and(
-        _isEqualNodes(node.leftHandSide, toNode.leftHandSide),
-        _isEqualTokens(node.operator, toNode.operator),
-        _isEqualNodes(node.rightHandSide, toNode.rightHandSide))) {
-      toNode.staticElement = node.staticElement;
-      toNode.staticType = node.staticType;
-      return true;
-    }
-    return false;
-  }
-
-  @override
-  bool visitAwaitExpression(AwaitExpression node) {
-    var toNode = _toNode as AwaitExpressionImpl;
-    if (_and(_isEqualTokens(node.awaitKeyword, toNode.awaitKeyword),
-        _isEqualNodes(node.expression, toNode.expression))) {
-      toNode.staticType = node.staticType;
-      return true;
-    }
-    return false;
-  }
-
-  @override
-  bool visitBinaryExpression(BinaryExpression node) {
-    var toNode = _toNode as BinaryExpressionImpl;
-    if (_and(
-        _isEqualNodes(node.leftOperand, toNode.leftOperand),
-        _isEqualTokens(node.operator, toNode.operator),
-        _isEqualNodes(node.rightOperand, toNode.rightOperand))) {
-      toNode.staticElement = node.staticElement;
-      toNode.staticType = node.staticType;
-      return true;
-    }
-    return false;
-  }
-
-  @override
-  bool visitBlock(Block node) {
-    var toNode = _toNode as BlockImpl;
-    return _and(
-        _isEqualTokens(node.leftBracket, toNode.leftBracket),
-        _isEqualNodeLists(node.statements, toNode.statements),
-        _isEqualTokens(node.rightBracket, toNode.rightBracket));
-  }
-
-  @override
-  bool visitBlockFunctionBody(BlockFunctionBody node) {
-    var toNode = _toNode as BlockFunctionBodyImpl;
-    return _isEqualNodes(node.block, toNode.block);
-  }
-
-  @override
-  bool visitBooleanLiteral(BooleanLiteral node) {
-    var toNode = _toNode as BooleanLiteralImpl;
-    if (_and(_isEqualTokens(node.literal, toNode.literal),
-        node.value == toNode.value)) {
-      toNode.staticType = node.staticType;
-      return true;
-    }
-    return false;
-  }
-
-  @override
-  bool visitBreakStatement(BreakStatement node) {
-    var toNode = _toNode as BreakStatementImpl;
-    if (_and(
-        _isEqualTokens(node.breakKeyword, toNode.breakKeyword),
-        _isEqualNodes(node.label, toNode.label),
-        _isEqualTokens(node.semicolon, toNode.semicolon))) {
-      // TODO(paulberry): map node.target to toNode.target.
-      return true;
-    }
-    return false;
-  }
-
-  @override
-  bool visitCascadeExpression(CascadeExpression node) {
-    var toNode = _toNode as CascadeExpressionImpl;
-    if (_and(_isEqualNodes(node.target, toNode.target),
-        _isEqualNodeLists(node.cascadeSections, toNode.cascadeSections))) {
-      toNode.staticType = node.staticType;
-      return true;
-    }
-    return false;
-  }
-
-  @override
-  bool visitCatchClause(CatchClause node) {
-    var toNode = _toNode as CatchClauseImpl;
-    return _and(
-        _isEqualTokens(node.onKeyword, toNode.onKeyword),
-        _isEqualNodes(node.exceptionType, toNode.exceptionType),
-        _isEqualTokens(node.catchKeyword, toNode.catchKeyword),
-        _isEqualTokens(node.leftParenthesis, toNode.leftParenthesis),
-        _isEqualNodes(node.exceptionParameter, toNode.exceptionParameter),
-        _isEqualTokens(node.comma, toNode.comma),
-        _isEqualNodes(node.stackTraceParameter, toNode.stackTraceParameter),
-        _isEqualTokens(node.rightParenthesis, toNode.rightParenthesis),
-        _isEqualNodes(node.body, toNode.body));
-  }
-
-  @override
-  bool visitClassDeclaration(ClassDeclaration node) {
-    var toNode = _toNode as ClassDeclarationImpl;
-    return _and(
-        _isEqualNodes(node.documentationComment, toNode.documentationComment),
-        _isEqualNodeLists(node.metadata, toNode.metadata),
-        _isEqualTokens(node.abstractKeyword, toNode.abstractKeyword),
-        _isEqualTokens(node.classKeyword, toNode.classKeyword),
-        _isEqualNodes(node.name, toNode.name),
-        _isEqualNodes(node.typeParameters, toNode.typeParameters),
-        _isEqualNodes(node.extendsClause, toNode.extendsClause),
-        _isEqualNodes(node.withClause, toNode.withClause),
-        _isEqualNodes(node.implementsClause, toNode.implementsClause),
-        _isEqualTokens(node.leftBracket, toNode.leftBracket),
-        _isEqualNodeLists(node.members, toNode.members),
-        _isEqualTokens(node.rightBracket, toNode.rightBracket));
-  }
-
-  @override
-  bool visitClassTypeAlias(ClassTypeAlias node) {
-    var toNode = _toNode as ClassTypeAliasImpl;
-    return _and(
-        _isEqualNodes(node.documentationComment, toNode.documentationComment),
-        _isEqualNodeLists(node.metadata, toNode.metadata),
-        _isEqualTokens(node.typedefKeyword, toNode.typedefKeyword),
-        _isEqualNodes(node.name, toNode.name),
-        _isEqualNodes(node.typeParameters, toNode.typeParameters),
-        _isEqualTokens(node.equals, toNode.equals),
-        _isEqualTokens(node.abstractKeyword, toNode.abstractKeyword),
-        _isEqualNodes(node.superclass, toNode.superclass),
-        _isEqualNodes(node.withClause, toNode.withClause),
-        _isEqualNodes(node.implementsClause, toNode.implementsClause),
-        _isEqualTokens(node.semicolon, toNode.semicolon));
-  }
-
-  @override
-  bool visitComment(Comment node) {
-    var toNode = _toNode as CommentImpl;
-    return _isEqualNodeLists(node.references, toNode.references);
-  }
-
-  @override
-  bool visitCommentReference(CommentReference node) {
-    var toNode = _toNode as CommentReferenceImpl;
-    return _and(_isEqualTokens(node.newKeyword, toNode.newKeyword),
-        _isEqualNodes(node.identifier, toNode.identifier));
-  }
-
-  @override
-  bool visitCompilationUnit(CompilationUnit node) {
-    var toNode = _toNode as CompilationUnitImpl;
-    if (_and(
-        _isEqualTokens(node.beginToken, toNode.beginToken),
-        _isEqualNodes(node.scriptTag, toNode.scriptTag),
-        _isEqualNodeLists(node.directives, toNode.directives),
-        _isEqualNodeLists(node.declarations, toNode.declarations),
-        _isEqualTokens(node.endToken, toNode.endToken))) {
-      toNode.element = node.declaredElement;
-      return true;
-    }
-    return false;
-  }
-
-  @override
-  bool visitConditionalExpression(ConditionalExpression node) {
-    var toNode = _toNode as ConditionalExpressionImpl;
-    if (_and(
-        _isEqualNodes(node.condition, toNode.condition),
-        _isEqualTokens(node.question, toNode.question),
-        _isEqualNodes(node.thenExpression, toNode.thenExpression),
-        _isEqualTokens(node.colon, toNode.colon),
-        _isEqualNodes(node.elseExpression, toNode.elseExpression))) {
-      toNode.staticType = node.staticType;
-      return true;
-    }
-    return false;
-  }
-
-  @override
-  bool visitConfiguration(Configuration node) {
-    var toNode = _toNode as ConfigurationImpl;
-    if (_and(
-        _isEqualTokens(node.ifKeyword, toNode.ifKeyword),
-        _isEqualTokens(node.leftParenthesis, toNode.leftParenthesis),
-        _isEqualNodes(node.name, toNode.name),
-        _isEqualTokens(node.equalToken, toNode.equalToken),
-        _isEqualNodes(node.value, toNode.value),
-        _isEqualTokens(node.rightParenthesis, toNode.rightParenthesis),
-        _isEqualNodes(node.uri, toNode.uri))) {
-      return true;
-    }
-    return false;
-  }
-
-  @override
-  bool visitConstructorDeclaration(ConstructorDeclaration node) {
-    var toNode = _toNode as ConstructorDeclarationImpl;
-    if (_and(
-        _isEqualNodes(node.documentationComment, toNode.documentationComment),
-        _isEqualNodeLists(node.metadata, toNode.metadata),
-        _isEqualTokens(node.externalKeyword, toNode.externalKeyword),
-        _isEqualTokens(node.constKeyword, toNode.constKeyword),
-        _isEqualTokens(node.factoryKeyword, toNode.factoryKeyword),
-        _isEqualNodes(node.returnType, toNode.returnType),
-        _isEqualTokens(node.period, toNode.period),
-        _isEqualNodes(node.name, toNode.name),
-        _isEqualNodes(node.parameters, toNode.parameters),
-        _isEqualTokens(node.separator, toNode.separator),
-        _isEqualNodeLists(node.initializers, toNode.initializers),
-        _isEqualNodes(node.redirectedConstructor, toNode.redirectedConstructor),
-        _isEqualNodes(node.body, toNode.body))) {
-      toNode.declaredElement = node.declaredElement;
-      return true;
-    }
-    return false;
-  }
-
-  @override
-  bool visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
-    var toNode = _toNode as ConstructorFieldInitializerImpl;
-    return _and(
-        _isEqualTokens(node.thisKeyword, toNode.thisKeyword),
-        _isEqualTokens(node.period, toNode.period),
-        _isEqualNodes(node.fieldName, toNode.fieldName),
-        _isEqualTokens(node.equals, toNode.equals),
-        _isEqualNodes(node.expression, toNode.expression));
-  }
-
-  @override
-  bool visitConstructorName(ConstructorName node) {
-    var toNode = _toNode as ConstructorNameImpl;
-    if (_and(
-        _isEqualNodes(node.type, toNode.type),
-        _isEqualTokens(node.period, toNode.period),
-        _isEqualNodes(node.name, toNode.name))) {
-      toNode.staticElement = node.staticElement;
-      return true;
-    }
-    return false;
-  }
-
-  @override
-  bool visitContinueStatement(ContinueStatement node) {
-    var toNode = _toNode as ContinueStatementImpl;
-    if (_and(
-        _isEqualTokens(node.continueKeyword, toNode.continueKeyword),
-        _isEqualNodes(node.label, toNode.label),
-        _isEqualTokens(node.semicolon, toNode.semicolon))) {
-      // TODO(paulberry): map node.target to toNode.target.
-      return true;
-    }
-    return false;
-  }
-
-  @override
-  bool visitDeclaredIdentifier(DeclaredIdentifier node) {
-    var toNode = _toNode as DeclaredIdentifierImpl;
-    return _and(
-        _isEqualNodes(node.documentationComment, toNode.documentationComment),
-        _isEqualNodeLists(node.metadata, toNode.metadata),
-        _isEqualTokens(node.keyword, toNode.keyword),
-        _isEqualNodes(node.type, toNode.type),
-        _isEqualNodes(node.identifier, toNode.identifier));
-  }
-
-  @override
-  bool visitDefaultFormalParameter(covariant DefaultFormalParameterImpl node) {
-    var toNode = _toNode as DefaultFormalParameterImpl;
-    return _and(
-        _isEqualNodes(node.parameter, toNode.parameter),
-        node.kind == toNode.kind,
-        _isEqualTokens(node.separator, toNode.separator),
-        _isEqualNodes(node.defaultValue, toNode.defaultValue));
-  }
-
-  @override
-  bool visitDoStatement(DoStatement node) {
-    var toNode = _toNode as DoStatementImpl;
-    return _and(
-        _isEqualTokens(node.doKeyword, toNode.doKeyword),
-        _isEqualNodes(node.body, toNode.body),
-        _isEqualTokens(node.whileKeyword, toNode.whileKeyword),
-        _isEqualTokens(node.leftParenthesis, toNode.leftParenthesis),
-        _isEqualNodes(node.condition, toNode.condition),
-        _isEqualTokens(node.rightParenthesis, toNode.rightParenthesis),
-        _isEqualTokens(node.semicolon, toNode.semicolon));
-  }
-
-  @override
-  bool visitDottedName(DottedName node) {
-    var toNode = _toNode as DottedNameImpl;
-    return _isEqualNodeLists(node.components, toNode.components);
-  }
-
-  @override
-  bool visitDoubleLiteral(DoubleLiteral node) {
-    var toNode = _toNode as DoubleLiteralImpl;
-    if (_and(_isEqualTokens(node.literal, toNode.literal),
-        node.value == toNode.value)) {
-      toNode.staticType = node.staticType;
-      return true;
-    }
-    return false;
-  }
-
-  @override
-  bool visitEmptyFunctionBody(EmptyFunctionBody node) {
-    var toNode = _toNode as EmptyFunctionBodyImpl;
-    return _isEqualTokens(node.semicolon, toNode.semicolon);
-  }
-
-  @override
-  bool visitEmptyStatement(EmptyStatement node) {
-    var toNode = _toNode as EmptyStatementImpl;
-    return _isEqualTokens(node.semicolon, toNode.semicolon);
-  }
-
-  @override
-  bool visitEnumConstantDeclaration(EnumConstantDeclaration node) {
-    var toNode = _toNode as EnumConstantDeclarationImpl;
-    return _and(
-        _isEqualNodes(node.documentationComment, toNode.documentationComment),
-        _isEqualNodeLists(node.metadata, toNode.metadata),
-        _isEqualNodes(node.name, toNode.name));
-  }
-
-  @override
-  bool visitEnumDeclaration(EnumDeclaration node) {
-    var toNode = _toNode as EnumDeclarationImpl;
-    return _and(
-        _isEqualNodes(node.documentationComment, toNode.documentationComment),
-        _isEqualNodeLists(node.metadata, toNode.metadata),
-        _isEqualTokens(node.enumKeyword, toNode.enumKeyword),
-        _isEqualNodes(node.name, toNode.name),
-        _isEqualTokens(node.leftBracket, toNode.leftBracket),
-        _isEqualNodeLists(node.constants, toNode.constants),
-        _isEqualTokens(node.rightBracket, toNode.rightBracket));
-  }
-
-  @override
-  bool visitExportDirective(ExportDirective node) {
-    var toNode = _toNode as ExportDirectiveImpl;
-    if (_and(
-        _isEqualNodes(node.documentationComment, toNode.documentationComment),
-        _isEqualNodeLists(node.metadata, toNode.metadata),
-        _isEqualTokens(node.keyword, toNode.keyword),
-        _isEqualNodes(node.uri, toNode.uri),
-        _isEqualNodeLists(node.combinators, toNode.combinators),
-        _isEqualTokens(node.semicolon, toNode.semicolon))) {
-      toNode.element = node.element;
-      return true;
-    }
-    return false;
-  }
-
-  @override
-  bool visitExpressionFunctionBody(ExpressionFunctionBody node) {
-    var toNode = _toNode as ExpressionFunctionBodyImpl;
-    return _and(
-        _isEqualTokens(node.functionDefinition, toNode.functionDefinition),
-        _isEqualNodes(node.expression, toNode.expression),
-        _isEqualTokens(node.semicolon, toNode.semicolon));
-  }
-
-  @override
-  bool visitExpressionStatement(ExpressionStatement node) {
-    var toNode = _toNode as ExpressionStatementImpl;
-    return _and(_isEqualNodes(node.expression, toNode.expression),
-        _isEqualTokens(node.semicolon, toNode.semicolon));
-  }
-
-  @override
-  bool visitExtendsClause(ExtendsClause node) {
-    var toNode = _toNode as ExtendsClauseImpl;
-    return _and(_isEqualTokens(node.extendsKeyword, toNode.extendsKeyword),
-        _isEqualNodes(node.superclass, toNode.superclass));
-  }
-
-  @override
-  bool visitExtensionDeclaration(ExtensionDeclaration node) {
-    var toNode = _toNode as ExtensionDeclarationImpl;
-    if (_and(
-        _isEqualNodes(node.documentationComment, toNode.documentationComment),
-        _isEqualNodeLists(node.metadata, toNode.metadata),
-        _isEqualTokens(node.extensionKeyword, toNode.extensionKeyword),
-        _isEqualNodes(node.name, toNode.name),
-        _isEqualNodes(node.typeParameters, toNode.typeParameters),
-        _isEqualTokens(node.onKeyword, toNode.onKeyword),
-        _isEqualNodes(node.extendedType, toNode.extendedType),
-        _isEqualTokens(node.leftBracket, toNode.leftBracket),
-        _isEqualNodeLists(node.members, toNode.members),
-        _isEqualTokens(node.rightBracket, toNode.rightBracket))) {
-      return true;
-    }
-    return false;
-  }
-
-  @override
-  bool visitExtensionOverride(ExtensionOverride node) {
-    var toNode = _toNode as ExtensionOverrideImpl;
-    return _and(
-        _isEqualNodes(node.extensionName, toNode.extensionName),
-        _isEqualNodes(node.typeArguments, toNode.typeArguments),
-        _isEqualNodes(node.argumentList, toNode.argumentList));
-  }
-
-  @override
-  bool visitFieldDeclaration(FieldDeclaration node) {
-    var toNode = _toNode as FieldDeclarationImpl;
-    return _and(
-        _isEqualTokens(node.abstractKeyword, toNode.abstractKeyword),
-        _isEqualNodes(node.documentationComment, toNode.documentationComment),
-        _isEqualTokens(node.externalKeyword, toNode.externalKeyword),
-        _isEqualNodeLists(node.metadata, toNode.metadata),
-        _isEqualTokens(node.staticKeyword, toNode.staticKeyword),
-        _isEqualNodes(node.fields, toNode.fields),
-        _isEqualTokens(node.semicolon, toNode.semicolon));
-  }
-
-  @override
-  bool visitFieldFormalParameter(FieldFormalParameter node) {
-    var toNode = _toNode as FieldFormalParameterImpl;
-    return _and(
-        _isEqualNodes(node.documentationComment, toNode.documentationComment),
-        _isEqualNodeLists(node.metadata, toNode.metadata),
-        _isEqualTokens(node.keyword, toNode.keyword),
-        _isEqualNodes(node.type, toNode.type),
-        _isEqualTokens(node.thisKeyword, toNode.thisKeyword),
-        _isEqualTokens(node.period, toNode.period),
-        _isEqualNodes(node.identifier, toNode.identifier));
-  }
-
-  @override
-  bool visitForEachPartsWithDeclaration(ForEachPartsWithDeclaration node) {
-    var toNode = _toNode as ForEachPartsWithDeclarationImpl;
-    return _and(
-        _isEqualNodes(node.loopVariable, toNode.loopVariable),
-        _isEqualTokens(node.inKeyword, toNode.inKeyword),
-        _isEqualNodes(node.iterable, toNode.iterable));
-  }
-
-  @override
-  bool visitForEachPartsWithIdentifier(ForEachPartsWithIdentifier node) {
-    var toNode = _toNode as ForEachPartsWithIdentifierImpl;
-    return _and(
-        _isEqualNodes(node.identifier, toNode.identifier),
-        _isEqualTokens(node.inKeyword, toNode.inKeyword),
-        _isEqualNodes(node.iterable, toNode.iterable));
-  }
-
-  @override
-  bool visitForElement(ForElement node) {
-    var toNode = _toNode as ForElementImpl;
-    return _and(
-        _isEqualTokens(node.awaitKeyword, toNode.awaitKeyword),
-        _isEqualTokens(node.forKeyword, toNode.forKeyword),
-        _isEqualTokens(node.leftParenthesis, toNode.leftParenthesis),
-        _isEqualNodes(node.forLoopParts, toNode.forLoopParts),
-        _isEqualTokens(node.rightParenthesis, toNode.rightParenthesis),
-        _isEqualNodes(node.body, toNode.body));
-  }
-
-  @override
-  bool visitFormalParameterList(FormalParameterList node) {
-    var toNode = _toNode as FormalParameterListImpl;
-    return _and(
-        _isEqualTokens(node.leftParenthesis, toNode.leftParenthesis),
-        _isEqualNodeLists(node.parameters, toNode.parameters),
-        _isEqualTokens(node.leftDelimiter, toNode.leftDelimiter),
-        _isEqualTokens(node.rightDelimiter, toNode.rightDelimiter),
-        _isEqualTokens(node.rightParenthesis, toNode.rightParenthesis));
-  }
-
-  @override
-  bool visitForPartsWithDeclarations(ForPartsWithDeclarations node) {
-    var toNode = _toNode as ForPartsWithDeclarationsImpl;
-    return _and(
-        _isEqualNodes(node.variables, toNode.variables),
-        _isEqualTokens(node.leftSeparator, toNode.leftSeparator),
-        _isEqualNodes(node.condition, toNode.condition),
-        _isEqualTokens(node.rightSeparator, toNode.rightSeparator),
-        _isEqualNodeLists(node.updaters, toNode.updaters));
-  }
-
-  @override
-  bool visitForPartsWithExpression(ForPartsWithExpression node) {
-    var toNode = _toNode as ForPartsWithExpressionImpl;
-    return _and(
-        _isEqualNodes(node.initialization, toNode.initialization),
-        _isEqualTokens(node.leftSeparator, toNode.leftSeparator),
-        _isEqualNodes(node.condition, toNode.condition),
-        _isEqualTokens(node.rightSeparator, toNode.rightSeparator),
-        _isEqualNodeLists(node.updaters, toNode.updaters));
-  }
-
-  @override
-  bool visitForStatement(ForStatement node) {
-    var toNode = _toNode as ForStatementImpl;
-    return _and(
-        _isEqualTokens(node.awaitKeyword, toNode.awaitKeyword),
-        _isEqualTokens(node.forKeyword, toNode.forKeyword),
-        _isEqualTokens(node.leftParenthesis, toNode.leftParenthesis),
-        _isEqualNodes(node.forLoopParts, toNode.forLoopParts),
-        _isEqualTokens(node.rightParenthesis, toNode.rightParenthesis),
-        _isEqualNodes(node.body, toNode.body));
-  }
-
-  @override
-  bool visitFunctionDeclaration(FunctionDeclaration node) {
-    var toNode = _toNode as FunctionDeclarationImpl;
-    return _and(
-        _isEqualNodes(node.documentationComment, toNode.documentationComment),
-        _isEqualNodeLists(node.metadata, toNode.metadata),
-        _isEqualTokens(node.externalKeyword, toNode.externalKeyword),
-        _isEqualNodes(node.returnType, toNode.returnType),
-        _isEqualTokens(node.propertyKeyword, toNode.propertyKeyword),
-        _isEqualNodes(node.name, toNode.name),
-        _isEqualNodes(node.functionExpression, toNode.functionExpression));
-  }
-
-  @override
-  bool visitFunctionDeclarationStatement(FunctionDeclarationStatement node) {
-    FunctionDeclarationStatement toNode =
-        _toNode as FunctionDeclarationStatement;
-    return _isEqualNodes(node.functionDeclaration, toNode.functionDeclaration);
-  }
-
-  @override
-  bool visitFunctionExpression(FunctionExpression node) {
-    var toNode = _toNode as FunctionExpressionImpl;
-    if (_and(_isEqualNodes(node.parameters, toNode.parameters),
-        _isEqualNodes(node.body, toNode.body))) {
-      toNode.declaredElement = node.declaredElement;
-      toNode.staticType = node.staticType;
-      return true;
-    }
-    return false;
-  }
-
-  @override
-  bool visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
-    var toNode = _toNode as FunctionExpressionInvocationImpl;
-    if (_and(
-        _isEqualNodes(node.function, toNode.function),
-        _isEqualNodes(node.typeArguments, toNode.typeArguments),
-        _isEqualNodes(node.argumentList, toNode.argumentList))) {
-      toNode.staticInvokeType = node.staticInvokeType;
-      toNode.staticElement = node.staticElement;
-      toNode.staticType = node.staticType;
-      return true;
-    }
-    return false;
-  }
-
-  @override
-  bool visitFunctionTypeAlias(FunctionTypeAlias node) {
-    var toNode = _toNode as FunctionTypeAliasImpl;
-    return _and(
-        _isEqualNodes(node.documentationComment, toNode.documentationComment),
-        _isEqualNodeLists(node.metadata, toNode.metadata),
-        _isEqualTokens(node.typedefKeyword, toNode.typedefKeyword),
-        _isEqualNodes(node.returnType, toNode.returnType),
-        _isEqualNodes(node.name, toNode.name),
-        _isEqualNodes(node.typeParameters, toNode.typeParameters),
-        _isEqualNodes(node.parameters, toNode.parameters),
-        _isEqualTokens(node.semicolon, toNode.semicolon));
-  }
-
-  @override
-  bool visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
-    FunctionTypedFormalParameter toNode =
-        _toNode as FunctionTypedFormalParameter;
-    return _and(
-        _isEqualNodes(node.documentationComment, toNode.documentationComment),
-        _isEqualNodeLists(node.metadata, toNode.metadata),
-        _isEqualNodes(node.returnType, toNode.returnType),
-        _isEqualNodes(node.identifier, toNode.identifier),
-        _isEqualNodes(node.parameters, toNode.parameters));
-  }
-
-  @override
-  bool visitGenericFunctionType(GenericFunctionType node) {
-    var toNode = _toNode as GenericFunctionTypeImpl;
-    if (_and(
-        _isEqualNodes(node.returnType, toNode.returnType),
-        _isEqualTokens(node.functionKeyword, toNode.functionKeyword),
-        _isEqualNodes(node.typeParameters, toNode.typeParameters),
-        _isEqualNodes(node.parameters, toNode.parameters),
-        _isEqualTokens(node.question, toNode.question))) {
-      toNode.type = node.type;
-      return true;
-    }
-    return false;
-  }
-
-  @override
-  bool visitGenericTypeAlias(GenericTypeAlias node) {
-    var toNode = _toNode as GenericTypeAliasImpl;
-    if (_and(
-        _isEqualNodes(node.documentationComment, toNode.documentationComment),
-        _isEqualNodeLists(node.metadata, toNode.metadata),
-        _isEqualTokens(node.typedefKeyword, toNode.typedefKeyword),
-        _isEqualNodes(node.name, toNode.name),
-        _isEqualNodes(node.typeParameters, toNode.typeParameters),
-        _isEqualTokens(node.equals, toNode.equals),
-        _isEqualNodes(node.type, toNode.type),
-        _isEqualTokens(node.semicolon, toNode.semicolon))) {
-      return true;
-    }
-    return false;
-  }
-
-  @override
-  bool visitHideCombinator(HideCombinator node) {
-    var toNode = _toNode as HideCombinatorImpl;
-    return _and(_isEqualTokens(node.keyword, toNode.keyword),
-        _isEqualNodeLists(node.hiddenNames, toNode.hiddenNames));
-  }
-
-  @override
-  bool visitIfElement(IfElement node) {
-    var toNode = _toNode as IfElementImpl;
-    return _and(
-        _isEqualTokens(node.ifKeyword, toNode.ifKeyword),
-        _isEqualTokens(node.leftParenthesis, toNode.leftParenthesis),
-        _isEqualNodes(node.condition, toNode.condition),
-        _isEqualTokens(node.rightParenthesis, toNode.rightParenthesis),
-        _isEqualNodes(node.thenElement, toNode.thenElement),
-        _isEqualTokens(node.elseKeyword, toNode.elseKeyword),
-        _isEqualNodes(node.elseElement, toNode.elseElement));
-  }
-
-  @override
-  bool visitIfStatement(IfStatement node) {
-    var toNode = _toNode as IfStatementImpl;
-    return _and(
-        _isEqualTokens(node.ifKeyword, toNode.ifKeyword),
-        _isEqualTokens(node.leftParenthesis, toNode.leftParenthesis),
-        _isEqualNodes(node.condition, toNode.condition),
-        _isEqualTokens(node.rightParenthesis, toNode.rightParenthesis),
-        _isEqualNodes(node.thenStatement, toNode.thenStatement),
-        _isEqualTokens(node.elseKeyword, toNode.elseKeyword),
-        _isEqualNodes(node.elseStatement, toNode.elseStatement));
-  }
-
-  @override
-  bool visitImplementsClause(ImplementsClause node) {
-    var toNode = _toNode as ImplementsClauseImpl;
-    return _and(
-        _isEqualTokens(node.implementsKeyword, toNode.implementsKeyword),
-        _isEqualNodeLists(node.interfaces, toNode.interfaces));
-  }
-
-  @override
-  bool visitImportDirective(ImportDirective node) {
-    var toNode = _toNode as ImportDirectiveImpl;
-    if (_and(
-        _isEqualNodes(node.documentationComment, toNode.documentationComment),
-        _isEqualNodeLists(node.metadata, toNode.metadata),
-        _isEqualTokens(node.keyword, toNode.keyword),
-        _isEqualNodes(node.uri, toNode.uri),
-        _isEqualTokens(node.asKeyword, toNode.asKeyword),
-        _isEqualNodes(node.prefix, toNode.prefix),
-        _isEqualNodeLists(node.combinators, toNode.combinators),
-        _isEqualTokens(node.semicolon, toNode.semicolon))) {
-      toNode.element = node.element;
-      return true;
-    }
-    return false;
-  }
-
-  @override
-  bool visitIndexExpression(IndexExpression node) {
-    var toNode = _toNode as IndexExpressionImpl;
-    if (_and(
-        _isEqualNodes(node.target, toNode.target),
-        _isEqualTokens(node.leftBracket, toNode.leftBracket),
-        _isEqualNodes(node.index, toNode.index),
-        _isEqualTokens(node.rightBracket, toNode.rightBracket))) {
-      toNode.staticElement = node.staticElement;
-      toNode.staticType = node.staticType;
-      return true;
-    }
-    return false;
-  }
-
-  @override
-  bool visitInstanceCreationExpression(InstanceCreationExpression node) {
-    var toNode = _toNode as InstanceCreationExpressionImpl;
-    if (_and(
-        _isEqualTokens(node.keyword, toNode.keyword),
-        _isEqualNodes(node.constructorName, toNode.constructorName),
-        _isEqualNodes(node.argumentList, toNode.argumentList))) {
-      toNode.staticType = node.staticType;
-      return true;
-    }
-    return false;
-  }
-
-  @override
-  bool visitIntegerLiteral(IntegerLiteral node) {
-    var toNode = _toNode as IntegerLiteralImpl;
-    if (_and(_isEqualTokens(node.literal, toNode.literal),
-        node.value == toNode.value)) {
-      toNode.staticType = node.staticType;
-      return true;
-    }
-    return false;
-  }
-
-  @override
-  bool visitInterpolationExpression(InterpolationExpression node) {
-    var toNode = _toNode as InterpolationExpressionImpl;
-    return _and(
-        _isEqualTokens(node.leftBracket, toNode.leftBracket),
-        _isEqualNodes(node.expression, toNode.expression),
-        _isEqualTokens(node.rightBracket, toNode.rightBracket));
-  }
-
-  @override
-  bool visitInterpolationString(InterpolationString node) {
-    var toNode = _toNode as InterpolationStringImpl;
-    return _and(_isEqualTokens(node.contents, toNode.contents),
-        node.value == toNode.value);
-  }
-
-  @override
-  bool visitIsExpression(IsExpression node) {
-    var toNode = _toNode as IsExpressionImpl;
-    if (_and(
-        _isEqualNodes(node.expression, toNode.expression),
-        _isEqualTokens(node.isOperator, toNode.isOperator),
-        _isEqualTokens(node.notOperator, toNode.notOperator),
-        _isEqualNodes(node.type, toNode.type))) {
-      toNode.staticType = node.staticType;
-      return true;
-    }
-    return false;
-  }
-
-  @override
-  bool visitLabel(Label node) {
-    var toNode = _toNode as LabelImpl;
-    return _and(_isEqualNodes(node.label, toNode.label),
-        _isEqualTokens(node.colon, toNode.colon));
-  }
-
-  @override
-  bool visitLabeledStatement(LabeledStatement node) {
-    var toNode = _toNode as LabeledStatementImpl;
-    return _and(_isEqualNodeLists(node.labels, toNode.labels),
-        _isEqualNodes(node.statement, toNode.statement));
-  }
-
-  @override
-  bool visitLibraryDirective(LibraryDirective node) {
-    var toNode = _toNode as LibraryDirectiveImpl;
-    if (_and(
-        _isEqualNodes(node.documentationComment, toNode.documentationComment),
-        _isEqualNodeLists(node.metadata, toNode.metadata),
-        _isEqualTokens(node.libraryKeyword, toNode.libraryKeyword),
-        _isEqualNodes(node.name, toNode.name),
-        _isEqualTokens(node.semicolon, toNode.semicolon))) {
-      toNode.element = node.element;
-      return true;
-    }
-    return false;
-  }
-
-  @override
-  bool visitLibraryIdentifier(LibraryIdentifier node) {
-    var toNode = _toNode as LibraryIdentifierImpl;
-    if (_isEqualNodeLists(node.components, toNode.components)) {
-      toNode.staticType = node.staticType;
-      return true;
-    }
-    return false;
-  }
-
-  @override
-  bool visitListLiteral(ListLiteral node) {
-    var toNode = _toNode as ListLiteralImpl;
-    if (_and(
-        _isEqualTokens(node.constKeyword, toNode.constKeyword),
-        _isEqualNodes(node.typeArguments, toNode.typeArguments),
-        _isEqualTokens(node.leftBracket, toNode.leftBracket),
-        _isEqualNodeLists(node.elements, toNode.elements),
-        _isEqualTokens(node.rightBracket, toNode.rightBracket))) {
-      toNode.staticType = node.staticType;
-      return true;
-    }
-    return false;
-  }
-
-  @override
-  bool visitMapLiteralEntry(MapLiteralEntry node) {
-    var toNode = _toNode as MapLiteralEntryImpl;
-    return _and(
-        _isEqualNodes(node.key, toNode.key),
-        _isEqualTokens(node.separator, toNode.separator),
-        _isEqualNodes(node.value, toNode.value));
-  }
-
-  @override
-  bool visitMethodDeclaration(MethodDeclaration node) {
-    var toNode = _toNode as MethodDeclarationImpl;
-    return _and(
-        _isEqualNodes(node.documentationComment, toNode.documentationComment),
-        _isEqualNodeLists(node.metadata, toNode.metadata),
-        _isEqualTokens(node.externalKeyword, toNode.externalKeyword),
-        _isEqualTokens(node.modifierKeyword, toNode.modifierKeyword),
-        _isEqualNodes(node.returnType, toNode.returnType),
-        _isEqualTokens(node.propertyKeyword, toNode.propertyKeyword),
-        _isEqualTokens(node.propertyKeyword, toNode.propertyKeyword),
-        _isEqualNodes(node.name, toNode.name),
-        _isEqualNodes(node.parameters, toNode.parameters),
-        _isEqualNodes(node.body, toNode.body));
-  }
-
-  @override
-  bool visitMethodInvocation(MethodInvocation node) {
-    var toNode = _toNode as MethodInvocationImpl;
-    if (_and(
-        _isEqualNodes(node.target, toNode.target),
-        _isEqualTokens(node.operator, toNode.operator),
-        _isEqualNodes(node.typeArguments, toNode.typeArguments),
-        _isEqualNodes(node.methodName, toNode.methodName),
-        _isEqualNodes(node.argumentList, toNode.argumentList))) {
-      toNode.staticInvokeType = node.staticInvokeType;
-      toNode.staticType = node.staticType;
-      return true;
-    }
-    return false;
-  }
-
-  @override
-  bool visitMixinDeclaration(MixinDeclaration node) {
-    var toNode = _toNode as MixinDeclarationImpl;
-    return _and(
-        _isEqualNodes(node.documentationComment, toNode.documentationComment),
-        _isEqualNodeLists(node.metadata, toNode.metadata),
-        _isEqualTokens(node.mixinKeyword, toNode.mixinKeyword),
-        _isEqualNodes(node.name, toNode.name),
-        _isEqualNodes(node.typeParameters, toNode.typeParameters),
-        _isEqualNodes(node.onClause, toNode.onClause),
-        _isEqualNodes(node.implementsClause, toNode.implementsClause),
-        _isEqualTokens(node.leftBracket, toNode.leftBracket),
-        _isEqualNodeLists(node.members, toNode.members),
-        _isEqualTokens(node.rightBracket, toNode.rightBracket));
-  }
-
-  @override
-  bool visitNamedExpression(NamedExpression node) {
-    var toNode = _toNode as NamedExpressionImpl;
-    if (_and(_isEqualNodes(node.name, toNode.name),
-        _isEqualNodes(node.expression, toNode.expression))) {
-      toNode.staticType = node.staticType;
-      return true;
-    }
-    return false;
-  }
-
-  @override
-  bool visitNativeClause(NativeClause node) {
-    var toNode = _toNode as NativeClauseImpl;
-    return _and(_isEqualTokens(node.nativeKeyword, toNode.nativeKeyword),
-        _isEqualNodes(node.name, toNode.name));
-  }
-
-  @override
-  bool visitNativeFunctionBody(NativeFunctionBody node) {
-    var toNode = _toNode as NativeFunctionBodyImpl;
-    return _and(
-        _isEqualTokens(node.nativeKeyword, toNode.nativeKeyword),
-        _isEqualNodes(node.stringLiteral, toNode.stringLiteral),
-        _isEqualTokens(node.semicolon, toNode.semicolon));
-  }
-
-  @override
-  bool visitNullLiteral(NullLiteral node) {
-    var toNode = _toNode as NullLiteralImpl;
-    if (_isEqualTokens(node.literal, toNode.literal)) {
-      toNode.staticType = node.staticType;
-      return true;
-    }
-    return false;
-  }
-
-  @override
-  bool visitOnClause(OnClause node) {
-    var toNode = _toNode as OnClauseImpl;
-    return _and(
-        _isEqualTokens(node.onKeyword, toNode.onKeyword),
-        _isEqualNodeLists(
-            node.superclassConstraints, toNode.superclassConstraints));
-  }
-
-  @override
-  bool visitParenthesizedExpression(ParenthesizedExpression node) {
-    var toNode = _toNode as ParenthesizedExpressionImpl;
-    if (_and(
-        _isEqualTokens(node.leftParenthesis, toNode.leftParenthesis),
-        _isEqualNodes(node.expression, toNode.expression),
-        _isEqualTokens(node.rightParenthesis, toNode.rightParenthesis))) {
-      toNode.staticType = node.staticType;
-      return true;
-    }
-    return false;
-  }
-
-  @override
-  bool visitPartDirective(PartDirective node) {
-    var toNode = _toNode as PartDirectiveImpl;
-    if (_and(
-        _isEqualNodes(node.documentationComment, toNode.documentationComment),
-        _isEqualNodeLists(node.metadata, toNode.metadata),
-        _isEqualTokens(node.partKeyword, toNode.partKeyword),
-        _isEqualNodes(node.uri, toNode.uri),
-        _isEqualTokens(node.semicolon, toNode.semicolon))) {
-      toNode.element = node.element;
-      return true;
-    }
-    return false;
-  }
-
-  @override
-  bool visitPartOfDirective(PartOfDirective node) {
-    var toNode = _toNode as PartOfDirectiveImpl;
-    if (_and(
-        _isEqualNodes(node.documentationComment, toNode.documentationComment),
-        _isEqualNodeLists(node.metadata, toNode.metadata),
-        _isEqualTokens(node.partKeyword, toNode.partKeyword),
-        _isEqualTokens(node.ofKeyword, toNode.ofKeyword),
-        _isEqualNodes(node.libraryName, toNode.libraryName),
-        _isEqualTokens(node.semicolon, toNode.semicolon))) {
-      toNode.element = node.element;
-      return true;
-    }
-    return false;
-  }
-
-  @override
-  bool visitPostfixExpression(PostfixExpression node) {
-    var toNode = _toNode as PostfixExpressionImpl;
-    if (_and(_isEqualNodes(node.operand, toNode.operand),
-        _isEqualTokens(node.operator, toNode.operator))) {
-      toNode.staticElement = node.staticElement;
-      toNode.staticType = node.staticType;
-      return true;
-    }
-    return false;
-  }
-
-  @override
-  bool visitPrefixedIdentifier(PrefixedIdentifier node) {
-    var toNode = _toNode as PrefixedIdentifierImpl;
-    if (_and(
-        _isEqualNodes(node.prefix, toNode.prefix),
-        _isEqualTokens(node.period, toNode.period),
-        _isEqualNodes(node.identifier, toNode.identifier))) {
-      toNode.staticType = node.staticType;
-      return true;
-    }
-    return false;
-  }
-
-  @override
-  bool visitPrefixExpression(PrefixExpression node) {
-    var toNode = _toNode as PrefixExpressionImpl;
-    if (_and(_isEqualTokens(node.operator, toNode.operator),
-        _isEqualNodes(node.operand, toNode.operand))) {
-      toNode.staticElement = node.staticElement;
-      toNode.staticType = node.staticType;
-      return true;
-    }
-    return false;
-  }
-
-  @override
-  bool visitPropertyAccess(PropertyAccess node) {
-    var toNode = _toNode as PropertyAccessImpl;
-    if (_and(
-        _isEqualNodes(node.target, toNode.target),
-        _isEqualTokens(node.operator, toNode.operator),
-        _isEqualNodes(node.propertyName, toNode.propertyName))) {
-      toNode.staticType = node.staticType;
-      return true;
-    }
-    return false;
-  }
-
-  @override
-  bool visitRedirectingConstructorInvocation(
-      RedirectingConstructorInvocation node) {
-    var toNode = _toNode as RedirectingConstructorInvocationImpl;
-    if (_and(
-        _isEqualTokens(node.thisKeyword, toNode.thisKeyword),
-        _isEqualTokens(node.period, toNode.period),
-        _isEqualNodes(node.constructorName, toNode.constructorName),
-        _isEqualNodes(node.argumentList, toNode.argumentList))) {
-      toNode.staticElement = node.staticElement;
-      return true;
-    }
-    return false;
-  }
-
-  @override
-  bool visitRethrowExpression(RethrowExpression node) {
-    var toNode = _toNode as RethrowExpressionImpl;
-    if (_isEqualTokens(node.rethrowKeyword, toNode.rethrowKeyword)) {
-      toNode.staticType = node.staticType;
-      return true;
-    }
-    return false;
-  }
-
-  @override
-  bool visitReturnStatement(ReturnStatement node) {
-    var toNode = _toNode as ReturnStatementImpl;
-    return _and(
-        _isEqualTokens(node.returnKeyword, toNode.returnKeyword),
-        _isEqualNodes(node.expression, toNode.expression),
-        _isEqualTokens(node.semicolon, toNode.semicolon));
-  }
-
-  @override
-  bool visitScriptTag(ScriptTag node) {
-    var toNode = _toNode as ScriptTagImpl;
-    return _isEqualTokens(node.scriptTag, toNode.scriptTag);
-  }
-
-  @override
-  bool visitSetOrMapLiteral(SetOrMapLiteral node) {
-    var toNode = _toNode as SetOrMapLiteralImpl;
-    if (_and(
-        _isEqualTokens(node.constKeyword, toNode.constKeyword),
-        _isEqualNodes(node.typeArguments, toNode.typeArguments),
-        _isEqualTokens(node.leftBracket, toNode.leftBracket),
-        _isEqualNodeLists(node.elements, toNode.elements),
-        _isEqualTokens(node.rightBracket, toNode.rightBracket))) {
-      toNode.staticType = node.staticType;
-      return true;
-    }
-    return false;
-  }
-
-  @override
-  bool visitShowCombinator(ShowCombinator node) {
-    var toNode = _toNode as ShowCombinatorImpl;
-    return _and(_isEqualTokens(node.keyword, toNode.keyword),
-        _isEqualNodeLists(node.shownNames, toNode.shownNames));
-  }
-
-  @override
-  bool visitSimpleFormalParameter(SimpleFormalParameter node) {
-    var toNode = _toNode as SimpleFormalParameterImpl;
-    if (_and(
-        _isEqualNodes(node.documentationComment, toNode.documentationComment),
-        _isEqualNodeLists(node.metadata, toNode.metadata),
-        _isEqualTokens(node.keyword, toNode.keyword),
-        _isEqualNodes(node.type, toNode.type),
-        _isEqualNodes(node.identifier, toNode.identifier))) {
-      toNode.declaredElement = node.declaredElement;
-      return true;
-    }
-    return false;
-  }
-
-  @override
-  bool visitSimpleIdentifier(SimpleIdentifier node) {
-    var toNode = _toNode as SimpleIdentifierImpl;
-    if (_isEqualTokens(node.token, toNode.token)) {
-      toNode.staticElement = node.staticElement;
-      toNode.staticType = node.staticType;
-      toNode.tearOffTypeArgumentTypes = node.tearOffTypeArgumentTypes;
-      return true;
-    }
-    return false;
-  }
-
-  @override
-  bool visitSimpleStringLiteral(SimpleStringLiteral node) {
-    var toNode = _toNode as SimpleStringLiteralImpl;
-    if (_and(_isEqualTokens(node.literal, toNode.literal),
-        node.value == toNode.value)) {
-      toNode.staticType = node.staticType;
-      return true;
-    }
-    return false;
-  }
-
-  @override
-  bool visitSpreadElement(SpreadElement node) {
-    var toNode = _toNode as SpreadElementImpl;
-    return _and(_isEqualTokens(node.spreadOperator, toNode.spreadOperator),
-        _isEqualNodes(node.expression, toNode.expression));
-  }
-
-  @override
-  bool visitStringInterpolation(StringInterpolation node) {
-    var toNode = _toNode as StringInterpolationImpl;
-    if (_isEqualNodeLists(node.elements, toNode.elements)) {
-      toNode.staticType = node.staticType;
-      return true;
-    }
-    return false;
-  }
-
-  @override
-  bool visitSuperConstructorInvocation(SuperConstructorInvocation node) {
-    var toNode = _toNode as SuperConstructorInvocationImpl;
-    if (_and(
-        _isEqualTokens(node.superKeyword, toNode.superKeyword),
-        _isEqualTokens(node.period, toNode.period),
-        _isEqualNodes(node.constructorName, toNode.constructorName),
-        _isEqualNodes(node.argumentList, toNode.argumentList))) {
-      toNode.staticElement = node.staticElement;
-      return true;
-    }
-    return false;
-  }
-
-  @override
-  bool visitSuperExpression(SuperExpression node) {
-    var toNode = _toNode as SuperExpressionImpl;
-    if (_isEqualTokens(node.superKeyword, toNode.superKeyword)) {
-      toNode.staticType = node.staticType;
-      return true;
-    }
-    return false;
-  }
-
-  @override
-  bool visitSwitchCase(SwitchCase node) {
-    var toNode = _toNode as SwitchCaseImpl;
-    return _and(
-        _isEqualNodeLists(node.labels, toNode.labels),
-        _isEqualTokens(node.keyword, toNode.keyword),
-        _isEqualNodes(node.expression, toNode.expression),
-        _isEqualTokens(node.colon, toNode.colon),
-        _isEqualNodeLists(node.statements, toNode.statements));
-  }
-
-  @override
-  bool visitSwitchDefault(SwitchDefault node) {
-    var toNode = _toNode as SwitchDefaultImpl;
-    return _and(
-        _isEqualNodeLists(node.labels, toNode.labels),
-        _isEqualTokens(node.keyword, toNode.keyword),
-        _isEqualTokens(node.colon, toNode.colon),
-        _isEqualNodeLists(node.statements, toNode.statements));
-  }
-
-  @override
-  bool visitSwitchStatement(SwitchStatement node) {
-    var toNode = _toNode as SwitchStatementImpl;
-    return _and(
-        _isEqualTokens(node.switchKeyword, toNode.switchKeyword),
-        _isEqualTokens(node.leftParenthesis, toNode.leftParenthesis),
-        _isEqualNodes(node.expression, toNode.expression),
-        _isEqualTokens(node.rightParenthesis, toNode.rightParenthesis),
-        _isEqualTokens(node.leftBracket, toNode.leftBracket),
-        _isEqualNodeLists(node.members, toNode.members),
-        _isEqualTokens(node.rightBracket, toNode.rightBracket));
-  }
-
-  @override
-  bool visitSymbolLiteral(SymbolLiteral node) {
-    var toNode = _toNode as SymbolLiteralImpl;
-    if (_and(_isEqualTokens(node.poundSign, toNode.poundSign),
-        _isEqualTokenLists(node.components, toNode.components))) {
-      toNode.staticType = node.staticType;
-      return true;
-    }
-    return false;
-  }
-
-  @override
-  bool visitThisExpression(ThisExpression node) {
-    var toNode = _toNode as ThisExpressionImpl;
-    if (_isEqualTokens(node.thisKeyword, toNode.thisKeyword)) {
-      toNode.staticType = node.staticType;
-      return true;
-    }
-    return false;
-  }
-
-  @override
-  bool visitThrowExpression(ThrowExpression node) {
-    var toNode = _toNode as ThrowExpressionImpl;
-    if (_and(_isEqualTokens(node.throwKeyword, toNode.throwKeyword),
-        _isEqualNodes(node.expression, toNode.expression))) {
-      toNode.staticType = node.staticType;
-      return true;
-    }
-    return false;
-  }
-
-  @override
-  bool visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
-    var toNode = _toNode as TopLevelVariableDeclarationImpl;
-    return _and(
-        _isEqualNodes(node.documentationComment, toNode.documentationComment),
-        _isEqualNodeLists(node.metadata, toNode.metadata),
-        _isEqualTokens(node.externalKeyword, toNode.externalKeyword),
-        _isEqualNodes(node.variables, toNode.variables),
-        _isEqualTokens(node.semicolon, toNode.semicolon));
-  }
-
-  @override
-  bool visitTryStatement(TryStatement node) {
-    var toNode = _toNode as TryStatementImpl;
-    return _and(
-        _isEqualTokens(node.tryKeyword, toNode.tryKeyword),
-        _isEqualNodes(node.body, toNode.body),
-        _isEqualNodeLists(node.catchClauses, toNode.catchClauses),
-        _isEqualTokens(node.finallyKeyword, toNode.finallyKeyword),
-        _isEqualNodes(node.finallyBlock, toNode.finallyBlock));
-  }
-
-  @override
-  bool visitTypeArgumentList(TypeArgumentList node) {
-    var toNode = _toNode as TypeArgumentListImpl;
-    return _and(
-        _isEqualTokens(node.leftBracket, toNode.leftBracket),
-        _isEqualNodeLists(node.arguments, toNode.arguments),
-        _isEqualTokens(node.rightBracket, toNode.rightBracket));
-  }
-
-  @override
-  bool visitTypeName(TypeName node) {
-    var toNode = _toNode as TypeNameImpl;
-    if (_and(
-        _isEqualNodes(node.name, toNode.name),
-        _isEqualNodes(node.typeArguments, toNode.typeArguments),
-        _isEqualTokens(node.question, toNode.question))) {
-      toNode.type = node.type;
-      return true;
-    }
-    return false;
-  }
-
-  @override
-  bool visitTypeParameter(TypeParameter node) {
-    var toNode = _toNode as TypeParameterImpl;
-    // TODO (kallentu) : Clean up TypeParameterImpl casting once variance is
-    // added to the interface.
-    return _and(
-        _isEqualNodes(node.documentationComment, toNode.documentationComment),
-        _isEqualNodeLists(node.metadata, toNode.metadata),
-        _isEqualNodes(node.name, toNode.name),
-        _isEqualTokens((node as TypeParameterImpl).varianceKeyword,
-            toNode.varianceKeyword),
-        _isEqualTokens(node.extendsKeyword, toNode.extendsKeyword),
-        _isEqualNodes(node.bound, toNode.bound));
-  }
-
-  @override
-  bool visitTypeParameterList(TypeParameterList node) {
-    var toNode = _toNode as TypeParameterListImpl;
-    return _and(
-        _isEqualTokens(node.leftBracket, toNode.leftBracket),
-        _isEqualNodeLists(node.typeParameters, toNode.typeParameters),
-        _isEqualTokens(node.rightBracket, toNode.rightBracket));
-  }
-
-  @override
-  bool visitVariableDeclaration(VariableDeclaration node) {
-    var toNode = _toNode as VariableDeclarationImpl;
-    return _and(
-        _isEqualNodes(node.documentationComment, toNode.documentationComment),
-        _isEqualNodeLists(node.metadata, toNode.metadata),
-        _isEqualNodes(node.name, toNode.name),
-        _isEqualTokens(node.equals, toNode.equals),
-        _isEqualNodes(node.initializer, toNode.initializer));
-  }
-
-  @override
-  bool visitVariableDeclarationList(VariableDeclarationList node) {
-    var toNode = _toNode as VariableDeclarationListImpl;
-    return _and(
-        _isEqualNodes(node.documentationComment, toNode.documentationComment),
-        _isEqualNodeLists(node.metadata, toNode.metadata),
-        _isEqualTokens(node.keyword, toNode.keyword),
-        _isEqualNodes(node.type, toNode.type),
-        _isEqualNodeLists(node.variables, toNode.variables));
-  }
-
-  @override
-  bool visitVariableDeclarationStatement(VariableDeclarationStatement node) {
-    VariableDeclarationStatement toNode =
-        _toNode as VariableDeclarationStatement;
-    return _and(_isEqualNodes(node.variables, toNode.variables),
-        _isEqualTokens(node.semicolon, toNode.semicolon));
-  }
-
-  @override
-  bool visitWhileStatement(WhileStatement node) {
-    var toNode = _toNode as WhileStatementImpl;
-    return _and(
-        _isEqualTokens(node.whileKeyword, toNode.whileKeyword),
-        _isEqualTokens(node.leftParenthesis, toNode.leftParenthesis),
-        _isEqualNodes(node.condition, toNode.condition),
-        _isEqualTokens(node.rightParenthesis, toNode.rightParenthesis),
-        _isEqualNodes(node.body, toNode.body));
-  }
-
-  @override
-  bool visitWithClause(WithClause node) {
-    var toNode = _toNode as WithClauseImpl;
-    return _and(_isEqualTokens(node.withKeyword, toNode.withKeyword),
-        _isEqualNodeLists(node.mixinTypes, toNode.mixinTypes));
-  }
-
-  @override
-  bool visitYieldStatement(YieldStatement node) {
-    var toNode = _toNode as YieldStatementImpl;
-    return _and(
-        _isEqualTokens(node.yieldKeyword, toNode.yieldKeyword),
-        _isEqualNodes(node.expression, toNode.expression),
-        _isEqualTokens(node.semicolon, toNode.semicolon));
-  }
-
-  /// Return `true` if all of the parameters are `true`.
-  bool _and(bool b1, bool b2,
-      [bool b3 = true,
-      bool b4 = true,
-      bool b5 = true,
-      bool b6 = true,
-      bool b7 = true,
-      bool b8 = true,
-      bool b9 = true,
-      bool b10 = true,
-      bool b11 = true,
-      bool b12 = true,
-      bool b13 = true]) {
-    // TODO(brianwilkerson) Inline this method.
-    return b1 &&
-        b2 &&
-        b3 &&
-        b4 &&
-        b5 &&
-        b6 &&
-        b7 &&
-        b8 &&
-        b9 &&
-        b10 &&
-        b11 &&
-        b12 &&
-        b13;
-  }
-
-  /// Return `true` if the [first] and [second] lists of AST nodes have the same
-  /// size and corresponding elements are equal.
-  bool _isEqualNodeLists(NodeList? first, NodeList? second) {
-    if (first == null) {
-      return second == null;
-    } else if (second == null) {
-      return false;
-    }
-    int size = first.length;
-    if (second.length != size) {
-      return false;
-    }
-    bool equal = true;
-    for (int i = 0; i < size; i++) {
-      if (!_isEqualNodes(first[i], second[i])) {
-        equal = false;
-      }
-    }
-    return equal;
-  }
-
-  /// Return `true` if the [fromNode] and [toNode] have the same structure. As a
-  /// side-effect, if the nodes do have the same structure, any resolution data
-  /// from the first node will be copied to the second node.
-  bool _isEqualNodes(AstNode? fromNode, AstNode? toNode) {
-    if (fromNode == null) {
-      return toNode == null;
-    } else if (toNode == null) {
-      return false;
-    } else if (fromNode.runtimeType == toNode.runtimeType) {
-      _toNode = toNode;
-      return fromNode.accept(this)!;
-    }
-    //
-    // Check for a simple transformation caused by entering a period.
-    //
-    if (toNode is PrefixedIdentifier) {
-      SimpleIdentifier prefix = toNode.prefix;
-      if (fromNode.runtimeType == prefix.runtimeType) {
-        _toNode = prefix;
-        return fromNode.accept(this)!;
-      }
-    } else if (toNode is PropertyAccess) {
-      var target = toNode.target;
-      if (fromNode.runtimeType == target.runtimeType) {
-        _toNode = target;
-        return fromNode.accept(this)!;
-      }
-    }
-    return false;
-  }
-
-  /// Return `true` if the [first] and [second] arrays of tokens have the same
-  /// length and corresponding elements are equal.
-  bool _isEqualTokenLists(List<Token> first, List<Token> second) {
-    int length = first.length;
-    if (second.length != length) {
-      return false;
-    }
-    for (int i = 0; i < length; i++) {
-      if (!_isEqualTokens(first[i], second[i])) {
-        return false;
-      }
-    }
-    return true;
-  }
-
-  /// Return `true` if the [first] and [second] tokens have the same structure.
-  bool _isEqualTokens(Token? first, Token? second) {
-    if (first == null) {
-      return second == null;
-    } else if (second == null) {
-      return false;
-    }
-    return first.lexeme == second.lexeme;
-  }
-
-  /// Copy resolution data from the [fromNode] to the [toNode].
-  static void copyResolutionData(AstNode fromNode, AstNode toNode) {
-    ResolutionCopier copier = ResolutionCopier();
-    copier._isEqualNodes(fromNode, toNode);
-  }
-}
-
 /// Traverse the AST from initial child node to successive parents, building a
 /// collection of local variable and parameter names visible to the initial
 /// child node. In case of name shadowing, the first name seen is the most
diff --git a/pkg/analyzer/lib/src/dart/constant/value.dart b/pkg/analyzer/lib/src/dart/constant/value.dart
index ca4a5a1..6bb7701 100644
--- a/pkg/analyzer/lib/src/dart/constant/value.dart
+++ b/pkg/analyzer/lib/src/dart/constant/value.dart
@@ -2063,21 +2063,13 @@
       var rightValue = rightOperand.value;
       if (rightValue == null) {
         return UNKNOWN_VALUE;
-      } else if (rightValue.bitLength > 31) {
-        return UNKNOWN_VALUE;
-      }
-      if (rightValue >= 0) {
-        // TODO(brianwilkerson) After the analyzer package has a minimum SDK
-        // constraint that includes support for the real operator, consider
-        // changing the line below to
-        //   return new IntState(value >>> rightValue);
-        int divisor = 1 << rightValue;
-        if (divisor == 0) {
-          // The `rightValue` is large enough to cause all of the non-zero bits
-          // in the left operand to be shifted out of the value.
-          return IntState(0);
-        }
-        return IntState(value! ~/ divisor);
+      } else if (rightValue >= 64) {
+        return IntState(0);
+      } else if (rightValue >= 0) {
+        // TODO(srawlins): Replace with real operator once stable, like:
+        //     return new IntState(value >>> rightValue);
+        return IntState(
+            (value! >> rightValue) & ((1 << (64 - rightValue)) - 1));
       }
     }
     throw EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index e0f5421..a656852 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -17,6 +17,7 @@
 import 'package:analyzer/src/dart/analysis/experiments.dart';
 import 'package:analyzer/src/dart/analysis/session.dart';
 import 'package:analyzer/src/dart/ast/ast.dart';
+import 'package:analyzer/src/dart/ast/extensions.dart';
 import 'package:analyzer/src/dart/constant/compute.dart';
 import 'package:analyzer/src/dart/constant/evaluation.dart';
 import 'package:analyzer/src/dart/constant/value.dart';
@@ -1234,9 +1235,8 @@
 
     if (linkedNode != null) {
       var containerRef = reference!.getChild('@enum');
-      var linkedNode = this.linkedNode as CompilationUnit;
       _enums =
-          linkedNode.declarations.whereType<EnumDeclarationImpl>().map((node) {
+          _linkedUnitDeclarations.whereType<EnumDeclarationImpl>().map((node) {
         var name = node.name.name;
         var reference = containerRef.getChild(name);
         var element = node.declaredElement;
@@ -1263,11 +1263,10 @@
     }
 
     if (linkedNode != null) {
-      var linkedNode = this.linkedNode as CompilationUnit;
       var containerRef = reference!.getChild('@extension');
       _extensions = <ExtensionElement>[];
       var nextUnnamedExtensionId = 0;
-      for (var node in linkedNode.declarations) {
+      for (var node in _linkedUnitDeclarations) {
         if (node is ExtensionDeclarationImpl) {
           var nameIdentifier = node.name;
           var refName = nameIdentifier != null
@@ -1302,7 +1301,7 @@
 
     if (linkedNode != null) {
       var containerRef = reference!.getChild('@function');
-      return _functions = linkedContext!.unit_withDeclarations.declarations
+      return _functions = _linkedUnitDeclarations
           .whereType<FunctionDeclarationImpl>()
           .where((node) => !node.isGetter && !node.isSetter)
           .map((node) {
@@ -1372,9 +1371,8 @@
     }
 
     if (linkedNode != null) {
-      var linkedNode = this.linkedNode as CompilationUnit;
       var containerRef = reference!.getChild('@mixin');
-      var declarations = linkedNode.declarations;
+      var declarations = _linkedUnitDeclarations;
       return _mixins =
           declarations.whereType<MixinDeclarationImpl>().map((node) {
         var name = node.name.name;
@@ -1431,7 +1429,7 @@
     if (linkedNode != null) {
       var containerRef = reference!.getChild('@typeAlias');
       _typeAliases = <TypeAliasElement>[];
-      for (var node in linkedContext!.unit_withDeclarations.declarations) {
+      for (var node in _linkedUnitDeclarations) {
         String name;
         if (node is FunctionTypeAlias) {
           name = node.name.name;
@@ -1472,7 +1470,8 @@
     if (linkedNode != null) {
       var containerRef = reference!.getChild('@class');
       _types = <ClassElement>[];
-      for (var node in linkedContext!.unit_withDeclarations.declarations) {
+      var declarations = _linkedUnitDeclarations;
+      for (var node in declarations) {
         if (node is ClassDeclaration) {
           var name = node.name.name;
           var reference = containerRef.getChild(name);
@@ -1507,6 +1506,10 @@
     _types = types;
   }
 
+  List<CompilationUnitMember> get _linkedUnitDeclarations {
+    return linkedContext!.unit_withDeclarations.declarations;
+  }
+
   @override
   bool operator ==(Object object) =>
       object is CompilationUnitElementImpl && source == object.source;
@@ -3873,7 +3876,7 @@
     if (linkedNode != null) {
       var linkedNode = this.linkedNode as ExtensionDeclaration;
       linkedContext!.applyResolution(linkedNode);
-      return _extendedType = linkedNode.extendedType.type!;
+      return _extendedType = linkedNode.extendedType.typeOrThrow;
     }
 
     return _extendedType!;
@@ -4336,7 +4339,6 @@
 
   @override
   T? accept<T>(ElementVisitor<T> visitor) {
-    // ignore: deprecated_member_use_from_same_package
     visitor.visitFunctionTypeAliasElement(this);
     return visitor.visitTypeAliasElement(this);
   }
@@ -7151,6 +7153,13 @@
         aliasElement: this,
         aliasArguments: typeArguments,
       );
+    } else if (type is TypeParameterType) {
+      return TypeParameterTypeImpl(
+        element: type.element,
+        nullabilitySuffix: resultNullability,
+        aliasElement: this,
+        aliasArguments: typeArguments,
+      );
     } else {
       return (type as TypeImpl).withNullability(resultNullability);
     }
diff --git a/pkg/analyzer/lib/src/dart/element/generic_inferrer.dart b/pkg/analyzer/lib/src/dart/element/generic_inferrer.dart
index 387ca4a..7486d35 100644
--- a/pkg/analyzer/lib/src/dart/element/generic_inferrer.dart
+++ b/pkg/analyzer/lib/src/dart/element/generic_inferrer.dart
@@ -118,12 +118,15 @@
   /// `_` to precisely represent an unknown type. If [downwardsInferPhase] is
   /// false, we are on our final inference pass, have all available information
   /// including argument types, and must not conclude `_` for any type formal.
-  List<DartType>? infer(List<TypeParameterElement> typeFormals,
-      {bool considerExtendsClause = true,
-      ErrorReporter? errorReporter,
-      AstNode? errorNode,
-      bool failAtError = false,
-      bool downwardsInferPhase = false}) {
+  List<DartType>? infer(
+    List<TypeParameterElement> typeFormals, {
+    bool considerExtendsClause = true,
+    ErrorReporter? errorReporter,
+    AstNode? errorNode,
+    bool failAtError = false,
+    bool downwardsInferPhase = false,
+    required bool genericMetadataIsEnabled,
+  }) {
     // Initialize the inferred type array.
     //
     // In the downwards phase, they all start as `_` to offer reasonable
@@ -204,7 +207,9 @@
         // more errors (e.g. because `dynamic` is the most common bound).
       }
 
-      if (inferred is FunctionType && inferred.typeFormals.isNotEmpty) {
+      if (inferred is FunctionType &&
+          inferred.typeFormals.isNotEmpty &&
+          !genericMetadataIsEnabled) {
         if (failAtError) return null;
         var typeFormals = inferred.typeFormals;
         var typeFormalsStr = typeFormals.map(_elementStr).join(', ');
@@ -215,12 +220,6 @@
               ' [$typeFormalsStr], but a function with'
               ' type parameters cannot be used as a type argument.'
         ]);
-
-        // Heuristic: Using a generic function type as a bound makes subtyping
-        // undecidable. Therefore, we cannot keep [inferred] unless we wish to
-        // generate bogus subtyping errors. Instead generate plain [Function],
-        // which is the most general function type.
-        inferred = typeProvider.functionType;
       }
 
       if (UnknownInferredType.isKnown(inferred)) {
diff --git a/pkg/analyzer/lib/src/dart/element/replacement_visitor.dart b/pkg/analyzer/lib/src/dart/element/replacement_visitor.dart
index 8f1d3e5..e4f5c28 100644
--- a/pkg/analyzer/lib/src/dart/element/replacement_visitor.dart
+++ b/pkg/analyzer/lib/src/dart/element/replacement_visitor.dart
@@ -135,6 +135,8 @@
       element: type.element,
       nullabilitySuffix: newNullability ?? type.nullabilitySuffix,
       promotedBound: newPromotedBound ?? promotedBound,
+      aliasElement: type.aliasElement,
+      aliasArguments: type.aliasArguments,
     );
   }
 
@@ -149,6 +151,8 @@
     return TypeParameterTypeImpl(
       element: type.element,
       nullabilitySuffix: newNullability,
+      aliasElement: type.aliasElement,
+      aliasArguments: type.aliasArguments,
     );
   }
 
diff --git a/pkg/analyzer/lib/src/dart/element/type.dart b/pkg/analyzer/lib/src/dart/element/type.dart
index 5611186..a1b36a1 100644
--- a/pkg/analyzer/lib/src/dart/element/type.dart
+++ b/pkg/analyzer/lib/src/dart/element/type.dart
@@ -1801,7 +1801,13 @@
     required TypeParameterElement element,
     required this.nullabilitySuffix,
     this.promotedBound,
-  }) : super(element);
+    TypeAliasElement? aliasElement,
+    List<DartType>? aliasArguments,
+  }) : super(
+          element,
+          aliasElement: aliasElement,
+          aliasArguments: aliasArguments,
+        );
 
   @override
   DartType get bound =>
@@ -1885,8 +1891,9 @@
 
   @override
   DartType resolveToBound(DartType objectType) {
+    var promotedBound = this.promotedBound;
     if (promotedBound != null) {
-      return promotedBound!;
+      return promotedBound.resolveToBound(objectType);
     }
 
     var bound = element.bound;
diff --git a/pkg/analyzer/lib/src/dart/element/type_demotion.dart b/pkg/analyzer/lib/src/dart/element/type_demotion.dart
index 92390a4..4b1cc1a 100644
--- a/pkg/analyzer/lib/src/dart/element/type_demotion.dart
+++ b/pkg/analyzer/lib/src/dart/element/type_demotion.dart
@@ -38,6 +38,8 @@
         return TypeParameterTypeImpl(
           element: type.element,
           nullabilitySuffix: newNullability ?? type.nullabilitySuffix,
+          aliasElement: type.aliasElement,
+          aliasArguments: type.aliasArguments,
         );
       }
     }
diff --git a/pkg/analyzer/lib/src/dart/element/type_provider.dart b/pkg/analyzer/lib/src/dart/element/type_provider.dart
index 19def0f..2831cb48 100644
--- a/pkg/analyzer/lib/src/dart/element/type_provider.dart
+++ b/pkg/analyzer/lib/src/dart/element/type_provider.dart
@@ -8,6 +8,29 @@
 import 'package:analyzer/dart/element/type_provider.dart';
 import 'package:analyzer/src/dart/element/type.dart';
 
+const Map<String, Set<String>> _nonSubtypableClassMap = {
+  'dart:async': _nonSubtypableDartAsyncClassNames,
+  'dart:core': _nonSubtypableDartCoreClassNames,
+};
+
+const Set<String> _nonSubtypableClassNames = {
+  ..._nonSubtypableDartCoreClassNames,
+  ..._nonSubtypableDartAsyncClassNames,
+};
+
+const Set<String> _nonSubtypableDartAsyncClassNames = {
+  'FutureOr',
+};
+
+const Set<String> _nonSubtypableDartCoreClassNames = {
+  'bool',
+  'double',
+  'int',
+  'Null',
+  'num',
+  'String',
+};
+
 /// Provide common functionality shared by the various TypeProvider
 /// implementations.
 abstract class TypeProviderBase implements TypeProvider {
@@ -257,6 +280,7 @@
       ? NeverTypeImpl.instance
       : NeverTypeImpl.instanceLegacy;
 
+  @Deprecated('Use isNonSubtypableClass instead')
   @override
   Set<ClassElement> get nonSubtypableClasses => _nonSubtypableClasses ??= {
         boolElement,
@@ -397,6 +421,17 @@
   }
 
   @override
+  bool isNonSubtypableClass(ClassElement element) {
+    var name = element.name;
+    if (_nonSubtypableClassNames.contains(name)) {
+      var libraryUriStr = element.library.source.uri.toString();
+      var ofLibrary = _nonSubtypableClassMap[libraryUriStr];
+      return ofLibrary != null && ofLibrary.contains(name);
+    }
+    return false;
+  }
+
+  @override
   InterfaceType iterableType(DartType elementType) {
     return iterableElement.instantiate(
       typeArguments: [elementType],
diff --git a/pkg/analyzer/lib/src/dart/element/type_system.dart b/pkg/analyzer/lib/src/dart/element/type_system.dart
index 01d2255..ca7f2f9 100644
--- a/pkg/analyzer/lib/src/dart/element/type_system.dart
+++ b/pkg/analyzer/lib/src/dart/element/type_system.dart
@@ -419,8 +419,12 @@
   /// uninstantiated, or a [fnType] that is already instantiated, it will have
   /// no effect and return `null`.
   List<DartType>? inferFunctionTypeInstantiation(
-      FunctionType contextType, FunctionType fnType,
-      {ErrorReporter? errorReporter, AstNode? errorNode}) {
+    FunctionType contextType,
+    FunctionType fnType, {
+    ErrorReporter? errorReporter,
+    AstNode? errorNode,
+    required bool genericMetadataIsEnabled,
+  }) {
     if (contextType.typeFormals.isNotEmpty || fnType.typeFormals.isEmpty) {
       return const <DartType>[];
     }
@@ -437,6 +441,7 @@
       fnType.typeFormals,
       errorReporter: errorReporter,
       errorNode: errorNode,
+      genericMetadataIsEnabled: genericMetadataIsEnabled,
     );
   }
 
@@ -472,6 +477,7 @@
     AstNode? errorNode,
     bool downwards = false,
     bool isConst = false,
+    required bool genericMetadataIsEnabled,
   }) {
     if (typeParameters.isEmpty) {
       return null;
@@ -506,6 +512,7 @@
       errorReporter: errorReporter,
       errorNode: errorNode,
       downwardsInferPhase: downwards,
+      genericMetadataIsEnabled: genericMetadataIsEnabled,
     );
   }
 
@@ -1250,8 +1257,9 @@
   List<DartType>? matchSupertypeConstraints(
     ClassElement mixinElement,
     List<DartType> srcTypes,
-    List<DartType> destTypes,
-  ) {
+    List<DartType> destTypes, {
+    required bool genericMetadataIsEnabled,
+  }) {
     var typeParameters = mixinElement.typeParameters;
     var inferrer = GenericInferrer(this, typeParameters);
     for (int i = 0; i < srcTypes.length; i++) {
@@ -1262,6 +1270,7 @@
     var inferredTypes = inferrer.infer(
       typeParameters,
       considerExtendsClause: false,
+      genericMetadataIsEnabled: genericMetadataIsEnabled,
     )!;
     inferredTypes =
         inferredTypes.map(_removeBoundsOfGenericFunctionTypes).toList();
diff --git a/pkg/analyzer/lib/src/dart/error/ffi_code.dart b/pkg/analyzer/lib/src/dart/error/ffi_code.dart
index 83f1a49..dc8e106 100644
--- a/pkg/analyzer/lib/src/dart/error/ffi_code.dart
+++ b/pkg/analyzer/lib/src/dart/error/ffi_code.dart
@@ -207,6 +207,44 @@
           "or subtype of 'Struct'.");
 
   /**
+   * No parameters.
+   */
+  static const FfiCode PACKED_ANNOTATION = FfiCode(
+      name: 'PACKED_ANNOTATION',
+      message: "Structs must have at most one 'Packed' annotation.",
+      correction: "Try removing extra 'Packed' annotations.");
+
+  /**
+   * No parameters.
+   */
+  static const FfiCode PACKED_ANNOTATION_ALIGNMENT = FfiCode(
+      name: 'PACKED_ANNOTATION_ALIGNMENT',
+      message: "Only packing to 1, 2, 4, 8, and 16 bytes is supported.",
+      correction:
+          "Try changing the 'Packed' annotation alignment to 1, 2, 4, 8, or 16.");
+
+  /**
+   * Parameters:
+   * 0: the name of the outer struct
+   * 1: the name of the struct being nested
+   */
+  static const FfiCode PACKED_NESTING_NON_PACKED = FfiCode(
+      name: 'PACKED_NESTING_NON_PACKED',
+      message:
+          "Nesting the non-packed or less tightly packed struct '{0}' in a packed struct '{1}' is not supported.",
+      correction:
+          "Try packing the nested struct or packing the nested struct more tightly.");
+
+  /**
+   * No parameters.
+   */
+  static const FfiCode SIZE_ANNOTATION_DIMENSIONS = FfiCode(
+      name: 'SIZE_ANNOTATION_DIMENSIONS',
+      message:
+          "'Array's must have an 'Array' annotation that matches the dimensions.",
+      correction: "Try adjusting the arguments in the 'Array' annotation.");
+
+  /**
    * Parameters:
    * 0: the name of the subclass
    * 1: the name of the class being extended, implemented, or mixed in
diff --git a/pkg/analyzer/lib/src/dart/error/hint_codes.dart b/pkg/analyzer/lib/src/dart/error/hint_codes.dart
index 3621e3b..c50558f 100644
--- a/pkg/analyzer/lib/src/dart/error/hint_codes.dart
+++ b/pkg/analyzer/lib/src/dart/error/hint_codes.dart
@@ -19,6 +19,58 @@
    * 0: the name of the actual argument type
    * 1: the name of the expected function return type
    */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when an invocation of
+  // `Future.catchError` has an argument that is a function whose parameters
+  // aren't compatible with the arguments that will be passed to the function
+  // when it's invoked. The static type of the first argument to `catchError`
+  // is just `Function`, even though the function that is passed in is expected
+  // to have either a single parameter of type `Object` or two parameters of
+  // type `Object` and `StackTrace`.
+  //
+  // #### Example
+  //
+  // The following code produces this diagnostic because the closure being
+  // passed to `catchError` doesn't take any parameters, but the function is
+  // required to take at least one parameter:
+  //
+  // ```dart
+  // void f(Future<int> f) {
+  //   f.catchError([!() => 0!]);
+  // }
+  // ```
+  //
+  // The following code produces this diagnostic because the closure being
+  // passed to `catchError` takes three parameters, but it can't have more than
+  // two required parameters:
+  //
+  // ```dart
+  // void f(Future<int> f) {
+  //   f.catchError([!(one, two, three) => 0!]);
+  // }
+  // ```
+  //
+  // The following code produces this diagnostic because even though the closure
+  // being passed to `catchError` takes one parameter, the closure doesn't have
+  // a type that is compatible with `Object`:
+  //
+  // ```dart
+  // void f(Future<int> f) {
+  //   f.catchError([!(String error) => 0!]);
+  // }
+  // ```
+  //
+  // #### Common fixes
+  //
+  // Change the function being passed to `catchError` so that it has either one
+  // or two required parameters, and the parameters have the required types:
+  //
+  // ```dart
+  // void f(Future<int> f) {
+  //   f.catchError((Object error) => 0);
+  // }
+  // ```
   static const HintCode ARGUMENT_TYPE_NOT_ASSIGNABLE_TO_ERROR_HANDLER =
       HintCode(
           'ARGUMENT_TYPE_NOT_ASSIGNABLE_TO_ERROR_HANDLER',
@@ -1764,11 +1816,60 @@
    * 0: the return type as declared in the return statement
    * 1: the expected return type as defined by the type of the Future
    */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when an invocation of
+  // `Future.catchError` has an argument whose return type isn't compatible with
+  // the type returned by the instance of `Future`. At runtime, the method
+  // `catchError` attempts to return the value from the callback as the result
+  // of the future, which results in another exception being thrown.
+  //
+  // #### Example
+  //
+  // The following code produces this diagnostic because `future` is declared to
+  // return an `int` while `callback` is declared to return a `String`, and
+  // `String` isn't a subtype of `int`:
+  //
+  // ```dart
+  // void f(Future<int> future, String Function(dynamic, StackTrace) callback) {
+  //   future.catchError([!callback!]);
+  // }
+  // ```
+  //
+  // The following code produces this diagnostic because the closure being
+  // passed to `catchError` returns an `int` while `future` is declared to
+  // return a `String`:
+  //
+  // ```dart
+  // void f(Future<String> future) {
+  //   future.catchError((error, stackTrace) => [!3!]);
+  // }
+  // ```
+  //
+  // #### Common fixes
+  //
+  // If the instance of `Future` is declared correctly, then change the callback
+  // to match:
+  //
+  // ```dart
+  // void f(Future<int> future, int Function(dynamic, StackTrace) callback) {
+  //   future.catchError(callback);
+  // }
+  // ```
+  //
+  // If the declaration of the instance of `Future` is wrong, then change it to
+  // match the callback:
+  //
+  // ```dart
+  // void f(Future<String> future, String Function(dynamic, StackTrace) callback) {
+  //   future.catchError(callback);
+  // }
+  // ```
   static const HintCode RETURN_OF_INVALID_TYPE_FROM_CATCH_ERROR = HintCode(
-    'RETURN_OF_INVALID_TYPE_FROM_CATCH_ERROR',
-    "A value of type '{0}' can't be returned by the 'onError' handler because "
-        "it must be assignable to '{1}'.",
-  );
+      'INVALID_RETURN_TYPE_FOR_CATCH_ERROR',
+      "A value of type '{0}' can't be returned by the 'onError' handler "
+          "because it must be assignable to '{1}'.",
+      uniqueName: 'RETURN_OF_INVALID_TYPE_FROM_CATCH_ERROR');
 
   /**
    * Parameters:
@@ -1776,9 +1877,10 @@
    * 1: the expected return type as defined by the type of the Future
    */
   static const HintCode RETURN_TYPE_INVALID_FOR_CATCH_ERROR = HintCode(
-      'RETURN_TYPE_INVALID_FOR_CATCH_ERROR',
+      'INVALID_RETURN_TYPE_FOR_CATCH_ERROR',
       "The return type '{0}' isn't assignable to '{1}', as required by "
-          "'Future.catchError'.");
+          "'Future.catchError'.",
+      uniqueName: 'RETURN_TYPE_INVALID_FOR_CATCH_ERROR');
 
   /**
    * No parameters.
@@ -2661,6 +2763,14 @@
   );
 
   /**
+   * Parameters:
+   * 0: the name of the type
+   */
+  static const HintCode UNNECESSARY_QUESTION_MARK = HintCode(
+      'UNNECESSARY_QUESTION_MARK',
+      "The '?' is unnecessary because '{0}' is nullable without it.");
+
+  /**
    * No parameters.
    */
   // #### Description
diff --git a/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart b/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart
index e881af8..e1358f1 100644
--- a/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart
+++ b/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart
@@ -555,6 +555,13 @@
   static const ParserErrorCode LIBRARY_DIRECTIVE_NOT_FIRST =
       _LIBRARY_DIRECTIVE_NOT_FIRST;
 
+  static const ParserErrorCode LITERAL_WITH_CLASS_AND_NEW =
+      _LITERAL_WITH_CLASS_AND_NEW;
+
+  static const ParserErrorCode LITERAL_WITH_CLASS = _LITERAL_WITH_CLASS;
+
+  static const ParserErrorCode LITERAL_WITH_NEW = _LITERAL_WITH_NEW;
+
   static const ParserErrorCode LOCAL_FUNCTION_DECLARATION_MODIFIER =
       ParserErrorCode('LOCAL_FUNCTION_DECLARATION_MODIFIER',
           "Local function declarations can't specify any modifiers.",
diff --git a/pkg/analyzer/lib/src/dart/error/syntactic_errors.g.dart b/pkg/analyzer/lib/src/dart/error/syntactic_errors.g.dart
index 5265c24..36a49fe 100644
--- a/pkg/analyzer/lib/src/dart/error/syntactic_errors.g.dart
+++ b/pkg/analyzer/lib/src/dart/error/syntactic_errors.g.dart
@@ -122,6 +122,9 @@
   _BINARY_OPERATOR_WRITTEN_OUT,
   _EXPECTED_IDENTIFIER_BUT_GOT_KEYWORD,
   _ANNOTATION_WITH_TYPE_ARGUMENTS_UNINSTANTIATED,
+  _LITERAL_WITH_CLASS_AND_NEW,
+  _LITERAL_WITH_CLASS,
+  _LITERAL_WITH_NEW,
 ];
 
 const ParserErrorCode _ABSTRACT_CLASS_MEMBER = ParserErrorCode(
@@ -474,6 +477,20 @@
     correction:
         "Try moving the library directive before any other directives.");
 
+const ParserErrorCode _LITERAL_WITH_CLASS = ParserErrorCode(
+    'LITERAL_WITH_CLASS',
+    r"The name of the class '#lexeme' can't be included in a #string literal.",
+    correction: "Try removing '#lexeme'");
+
+const ParserErrorCode _LITERAL_WITH_CLASS_AND_NEW = ParserErrorCode(
+    'LITERAL_WITH_CLASS_AND_NEW',
+    r"Neither 'new' nor the name of the class '#lexeme' can be included in a #string literal.",
+    correction: "Try removing 'new' and '#lexeme'");
+
+const ParserErrorCode _LITERAL_WITH_NEW = ParserErrorCode(
+    'LITERAL_WITH_NEW', r"A literal can't use 'new'.",
+    correction: "Try removing 'new'");
+
 const ParserErrorCode _MEMBER_WITH_CLASS_NAME = ParserErrorCode(
     'MEMBER_WITH_CLASS_NAME',
     r"A class member can't have the same name as the enclosing class.",
diff --git a/pkg/analyzer/lib/src/dart/micro/analysis_context.dart b/pkg/analyzer/lib/src/dart/micro/analysis_context.dart
index 0193a85..5e45d1e7 100644
--- a/pkg/analyzer/lib/src/dart/micro/analysis_context.dart
+++ b/pkg/analyzer/lib/src/dart/micro/analysis_context.dart
@@ -2,11 +2,14 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'dart:async';
+
 import 'package:analyzer/dart/analysis/analysis_context.dart';
 import 'package:analyzer/dart/analysis/context_root.dart';
 import 'package:analyzer/dart/analysis/declared_variables.dart';
 import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/dart/analysis/uri_converter.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/src/context/context.dart';
 import 'package:analyzer/src/dart/analysis/context_root.dart';
@@ -39,6 +42,7 @@
   );
 
   var analysisSession = _MicroAnalysisSessionImpl(
+    fileResolver,
     declaredVariables,
     sourceFactory,
   );
@@ -89,6 +93,19 @@
 }
 
 class _FakeAnalysisDriver implements AnalysisDriver {
+  final FileResolver fileResolver;
+
+  late _MicroAnalysisSessionImpl _currentSession;
+
+  _FakeAnalysisDriver(this.fileResolver);
+
+  @override
+  AnalysisSessionImpl get currentSession {
+    _currentSession = fileResolver.contextObjects?.analysisSession
+        as _MicroAnalysisSessionImpl;
+    return _currentSession;
+  }
+
   @override
   noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
@@ -137,6 +154,8 @@
 }
 
 class _MicroAnalysisSessionImpl extends AnalysisSessionImpl {
+  final FileResolver fileResolver;
+
   @override
   final DeclaredVariables declaredVariables;
 
@@ -146,9 +165,10 @@
   late _MicroAnalysisContextImpl analysisContext;
 
   _MicroAnalysisSessionImpl(
+    this.fileResolver,
     this.declaredVariables,
     this.sourceFactory,
-  ) : super(_FakeAnalysisDriver());
+  ) : super(_FakeAnalysisDriver(fileResolver));
 
   @override
   ResourceProvider get resourceProvider =>
@@ -178,15 +198,13 @@
   }
 
   @override
+  Future<LibraryElement> getLibraryByUri(String uriStr) async {
+    return analysisContext.fileResolver.getLibraryByUri(uriStr: uriStr);
+  }
+
+  @override
   Future<ResolvedLibraryResult> getResolvedLibrary(String path) async {
-    var resolvedUnit = await getResolvedUnit(path);
-    return ResolvedLibraryResultImpl(
-      this,
-      path,
-      resolvedUnit.uri,
-      resolvedUnit.libraryElement,
-      [resolvedUnit],
-    );
+    return analysisContext.fileResolver.resolveLibrary(path: path);
   }
 
   @override
diff --git a/pkg/analyzer/lib/src/dart/micro/library_analyzer.dart b/pkg/analyzer/lib/src/dart/micro/library_analyzer.dart
index 2886408..c394437 100644
--- a/pkg/analyzer/lib/src/dart/micro/library_analyzer.dart
+++ b/pkg/analyzer/lib/src/dart/micro/library_analyzer.dart
@@ -244,9 +244,13 @@
     // This must happen after all other diagnostics have been computed but
     // before the list of diagnostics has been filtered.
     for (var file in _library.libraryFiles) {
-      IgnoreValidator(_getErrorReporter(file), _getErrorListener(file).errors,
-              _fileToIgnoreInfo[file]!, _fileToLineInfo[file]!)
-          .reportErrors();
+      IgnoreValidator(
+        _getErrorReporter(file),
+        _getErrorListener(file).errors,
+        _fileToIgnoreInfo[file]!,
+        _fileToLineInfo[file]!,
+        _analysisOptions.unignorableNames,
+      ).reportErrors();
     }
   }
 
diff --git a/pkg/analyzer/lib/src/dart/micro/library_graph.dart b/pkg/analyzer/lib/src/dart/micro/library_graph.dart
index 376a4c6..f4cce34 100644
--- a/pkg/analyzer/lib/src/dart/micro/library_graph.dart
+++ b/pkg/analyzer/lib/src/dart/micro/library_graph.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 'dart:collection';
 import 'dart:convert';
 import 'dart:typed_data';
 
@@ -135,13 +134,11 @@
   /// Return the [uri] string.
   String get uriStr => uri.toString();
 
-  /// Recursively traverse imports, exports, and parts to collect all
-  /// files that are accessed.
+  /// Collect all files that are transitively referenced by this file via
+  /// imports, exports, and parts.
   void collectAllReferencedFiles(Set<String> referencedFiles) {
-    var deps = {...importedFiles, ...exportedFiles, ...partedFiles};
-    for (var file in deps) {
-      if (!referencedFiles.contains(file.path)) {
-        referencedFiles.add(file.path);
+    for (var file in {...importedFiles, ...exportedFiles, ...partedFiles}) {
+      if (referencedFiles.add(file.path)) {
         file.collectAllReferencedFiles(referencedFiles);
       }
     }
@@ -626,29 +623,30 @@
   /// [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>();
+    var allReferenced = <String>{};
     for (var path in files) {
-      unusedFiles.remove(path);
-      _pathToFile[path]!.collectAllReferencedFiles(deps);
+      allReferenced.add(path);
+      _pathToFile[path]?.collectAllReferencedFiles(allReferenced);
     }
-    for (var path in deps) {
-      unusedFiles.remove(path);
-    }
-    for (var path in unusedFiles) {
+
+    var unusedPaths = _pathToFile.keys.toSet();
+    unusedPaths.removeAll(allReferenced);
+    testView.removedPaths = unusedPaths;
+
+    var removedFiles = <FileState>[];
+    for (var path in unusedPaths) {
       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 = {};
+  Set<String> removedPaths = {};
 }
 
 class FileSystemStateTimer {
diff --git a/pkg/analyzer/lib/src/dart/micro/resolve_file.dart b/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
index 583f799..03b5275 100644
--- a/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
+++ b/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
@@ -5,6 +5,7 @@
 import 'dart:typed_data';
 
 import 'package:analyzer/dart/analysis/results.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/error/error.dart';
 import 'package:analyzer/error/listener.dart';
 import 'package:analyzer/file_system/file_system.dart';
@@ -85,7 +86,7 @@
   /// It is used to allow assists and fixes without resolving the same file
   /// multiple times, as we compute more than one assist, or fixes when there
   /// are more than one error on a line.
-  final Map<String, ResolvedUnitResult> _cachedResults = {};
+  final Map<String, ResolvedLibraryResult> _cachedResults = {};
 
   FileResolver(
     PerformanceLog logger,
@@ -93,7 +94,7 @@
     @deprecated ByteStore byteStore,
     SourceFactory sourceFactory,
     String Function(String path) getFileDigest,
-    void Function(List<String> paths) prefetchFiles, {
+    void Function(List<String> paths)? prefetchFiles, {
     required Workspace workspace,
     @deprecated Duration? libraryContextResetTimeout,
   }) : this.from(
@@ -256,6 +257,39 @@
     });
   }
 
+  LibraryElement getLibraryByUri({
+    required String uriStr,
+    OperationPerformanceImpl? performance,
+  }) {
+    performance ??= OperationPerformanceImpl('<default>');
+
+    var uri = Uri.parse(uriStr);
+    var path = sourceFactory.forUri2(uri)?.fullName;
+
+    if (path == null) {
+      throw ArgumentError('$uri cannot be resolved to a file.');
+    }
+
+    var fileContext = getFileContext(
+      path: path,
+      performance: performance,
+    );
+    var file = fileContext.file;
+
+    if (file.partOfLibrary != null) {
+      throw ArgumentError('$uri is not a library.');
+    }
+
+    performance.run('libraryContext', (performance) {
+      libraryContext!.load2(
+        targetLibrary: file,
+        performance: performance,
+      );
+    });
+
+    return libraryContext!.elementFactory.libraryOfUri2(uriStr);
+  }
+
   String getLibraryLinkedSignature({
     required String path,
     required OperationPerformanceImpl performance,
@@ -339,6 +373,48 @@
 
     performance ??= OperationPerformanceImpl('<default>');
 
+    return logger.run('Resolve $path', () {
+      var fileContext = getFileContext(
+        path: path,
+        performance: performance!,
+      );
+      var file = fileContext.file;
+
+      // If we have a `part of` directive, we want to analyze this library.
+      // But the library must include the file, so have its element.
+      var libraryFile = file;
+      var partOfLibrary = file.partOfLibrary;
+      if (partOfLibrary != null) {
+        if (partOfLibrary.libraryFiles.contains(file)) {
+          libraryFile = partOfLibrary;
+        }
+      }
+
+      var libraryUnit = resolveLibrary(
+        completionLine: completionLine,
+        completionColumn: completionColumn,
+        path: libraryFile.path,
+        completionPath: path,
+        performance: performance,
+      );
+      var result =
+          libraryUnit.units!.firstWhere((element) => element.path == path);
+      return result;
+    });
+  }
+
+  /// The [completionLine] and [completionColumn] are zero based.
+  ResolvedLibraryResult resolveLibrary({
+    int? completionLine,
+    int? completionColumn,
+    String? completionPath,
+    required String path,
+    OperationPerformanceImpl? performance,
+  }) {
+    _throwIfNotAbsoluteNormalizedPath(path);
+
+    performance ??= OperationPerformanceImpl('<default>');
+
     var cachedResult = _cachedResults[path];
     if (cachedResult != null) {
       return cachedResult;
@@ -376,10 +452,6 @@
 
       testView?.addResolvedFile(path);
 
-      var content = _getFileContent(path);
-      var errorListener = RecordingErrorListener();
-      var unit = file.parse(errorListener, content);
-
       late Map<FileState, UnitAnalysisResult> results;
 
       logger.run('Compute analysis results', () {
@@ -398,7 +470,7 @@
         try {
           results = performance!.run('analyze', (performance) {
             return libraryAnalyzer.analyzeSync(
-              completionPath: completionOffset != null ? path : null,
+              completionPath: completionOffset != null ? completionPath : null,
               completionOffset: completionOffset,
               performance: performance,
             );
@@ -416,19 +488,28 @@
           );
         }
       });
-      UnitAnalysisResult fileResult = results[file]!;
 
-      var result = ResolvedUnitResultImpl(
-        contextObjects!.analysisSession,
-        path,
-        file.uri,
-        file.exists,
-        content,
-        unit.lineInfo!,
-        false, // isPart
-        fileResult.unit,
-        fileResult.errors,
-      );
+      results.forEach((key, value) {
+        print('$key: $value');
+      });
+      var resolvedUnits = results.values.map((fileResult) {
+        var file = fileResult.file;
+        return ResolvedUnitResultImpl(
+          contextObjects!.analysisSession,
+          file.path,
+          file.uri,
+          file.exists,
+          file.getContent(),
+          file.lineInfo,
+          file.unlinked2.hasPartOfDirective,
+          fileResult.unit,
+          fileResult.errors,
+        );
+      }).toList();
+
+      var libraryUnit = resolvedUnits.first;
+      var result = ResolvedLibraryResultImpl(contextObjects!.analysisSession,
+          path, libraryUnit.uri, libraryUnit.libraryElement, resolvedUnits);
       _cachedResults[path] = result;
       return result;
     });
@@ -583,6 +664,10 @@
       });
     }
 
+    if (isThirdParty) {
+      options.hint = false;
+    }
+
     return options;
   }
 
diff --git a/pkg/analyzer/lib/src/dart/resolver/annotation_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/annotation_resolver.dart
index 7294a2a..efa3e86c 100644
--- a/pkg/analyzer/lib/src/dart/resolver/annotation_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/annotation_resolver.dart
@@ -2,15 +2,20 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'package:_fe_analyzer_shared/src/flow_analysis/flow_analysis.dart';
+import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/error/listener.dart';
 import 'package:analyzer/src/dart/ast/ast.dart';
+import 'package:analyzer/src/dart/ast/extensions.dart';
 import 'package:analyzer/src/dart/constant/utilities.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/resolver/property_element_resolver.dart';
+import 'package:analyzer/src/dart/element/type_algebra.dart';
+import 'package:analyzer/src/dart/resolver/invocation_inference_helper.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 
@@ -23,18 +28,15 @@
 
   ErrorReporter get _errorReporter => _resolver.errorReporter;
 
-  void resolve(AnnotationImpl node) {
+  bool get _genericMetadataIsEnabled =>
+      _definingLibrary.featureSet.isEnabled(Feature.generic_metadata);
+
+  void resolve(AnnotationImpl node,
+      List<Map<DartType, NonPromotionReason> Function()> whyNotPromotedList) {
     AstNode parent = node.parent;
 
-    _resolve1(node);
-
-    node.constructorName?.accept(_resolver);
-    var element = node.element;
-    if (element is ExecutableElement) {
-      InferenceContext.setType(node.arguments, element.type);
-    }
     node.typeArguments?.accept(_resolver);
-    node.arguments?.accept(_resolver);
+    _resolve(node, whyNotPromotedList);
 
     var elementAnnotationImpl =
         node.elementAnnotation as ElementAnnotationImpl?;
@@ -46,6 +48,207 @@
     }
   }
 
+  void _classConstructorInvocation(
+    AnnotationImpl node,
+    ClassElement classElement,
+    SimpleIdentifierImpl? constructorName,
+    ArgumentList argumentList,
+    List<Map<DartType, NonPromotionReason> Function()> whyNotPromotedList,
+  ) {
+    ConstructorElement? constructorElement;
+    if (constructorName != null) {
+      constructorElement = classElement.getNamedConstructor(
+        constructorName.name,
+      );
+    } else {
+      constructorElement = classElement.unnamedConstructor;
+    }
+
+    _constructorInvocation(
+      node,
+      classElement.name,
+      constructorName,
+      classElement.typeParameters,
+      constructorElement,
+      argumentList,
+      (typeArguments) {
+        return classElement.instantiate(
+          typeArguments: typeArguments,
+          nullabilitySuffix: _resolver.noneOrStarSuffix,
+        );
+      },
+      whyNotPromotedList,
+    );
+  }
+
+  void _classGetter(
+    AnnotationImpl node,
+    ClassElement classElement,
+    SimpleIdentifierImpl? getterName,
+    List<Map<DartType, NonPromotionReason> Function()> whyNotPromotedList,
+  ) {
+    ExecutableElement? getter;
+    if (getterName != null) {
+      getter = classElement.getGetter(getterName.name);
+      getter = _resolver.toLegacyElement(getter);
+      // Recovery, try to find a constructor.
+      getter ??= classElement.getNamedConstructor(getterName.name);
+    } else {
+      getter = classElement.unnamedConstructor;
+    }
+
+    getterName?.staticElement = getter;
+    node.element = getter;
+
+    if (getterName != null && getter is PropertyAccessorElement) {
+      _propertyAccessorElement(node, getterName, getter, whyNotPromotedList);
+      _resolveAnnotationElementGetter(node, getter);
+    } else if (getter is! ConstructorElement) {
+      _errorReporter.reportErrorForNode(
+        CompileTimeErrorCode.INVALID_ANNOTATION,
+        node,
+      );
+    }
+
+    _visitArguments(node, whyNotPromotedList);
+  }
+
+  void _constructorInvocation(
+    AnnotationImpl node,
+    String typeDisplayName,
+    SimpleIdentifierImpl? constructorName,
+    List<TypeParameterElement> typeParameters,
+    ConstructorElement? constructorElement,
+    ArgumentList argumentList,
+    InterfaceType Function(List<DartType> typeArguments) instantiateElement,
+    List<Map<DartType, NonPromotionReason> Function()> whyNotPromotedList,
+  ) {
+    constructorElement = _resolver.toLegacyElement(constructorElement);
+    constructorName?.staticElement = constructorElement;
+    node.element = constructorElement;
+
+    if (constructorElement == null) {
+      _errorReporter.reportErrorForNode(
+        CompileTimeErrorCode.INVALID_ANNOTATION,
+        node,
+      );
+      _resolver.visitArgumentList(argumentList,
+          whyNotPromotedList: whyNotPromotedList);
+      return;
+    }
+
+    // If no type parameters, the elements are correct.
+    if (typeParameters.isEmpty) {
+      var typeArgumentList = node.typeArguments;
+      if (typeArgumentList != null) {
+        _errorReporter.reportErrorForNode(
+          CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS,
+          typeArgumentList,
+          [
+            typeDisplayName,
+            typeParameters.length,
+            typeArgumentList.arguments.length,
+          ],
+        );
+      }
+      _resolveConstructorInvocationArguments(node);
+      InferenceContext.setType(argumentList, constructorElement.type);
+      _resolver.visitArgumentList(argumentList,
+          whyNotPromotedList: whyNotPromotedList);
+      return;
+    }
+
+    void resolveWithFixedTypeArguments(
+      List<DartType> typeArguments,
+      ConstructorElement constructorElement,
+    ) {
+      var type = instantiateElement(typeArguments);
+      constructorElement = ConstructorMember.from(constructorElement, type);
+      constructorName?.staticElement = constructorElement;
+      node.element = constructorElement;
+      _resolveConstructorInvocationArguments(node);
+
+      InferenceContext.setType(argumentList, constructorElement.type);
+      _resolver.visitArgumentList(argumentList,
+          whyNotPromotedList: whyNotPromotedList);
+    }
+
+    if (!_genericMetadataIsEnabled) {
+      var typeArguments = List.filled(
+        typeParameters.length,
+        DynamicTypeImpl.instance,
+      );
+      resolveWithFixedTypeArguments(typeArguments, constructorElement);
+      return;
+    }
+
+    var typeArgumentList = node.typeArguments;
+    if (typeArgumentList != null) {
+      List<DartType> typeArguments;
+      if (typeArgumentList.arguments.length == typeParameters.length) {
+        typeArguments = typeArgumentList.arguments
+            .map((element) => element.typeOrThrow)
+            .toList();
+        var substitution = Substitution.fromPairs(
+          typeParameters,
+          typeArguments,
+        );
+        for (var i = 0; i < typeParameters.length; i++) {
+          var typeParameter = typeParameters[i];
+          var bound = typeParameter.bound;
+          if (bound != null) {
+            bound = substitution.substituteType(bound);
+            var typeArgument = typeArguments[i];
+            if (!_resolver.typeSystem.isSubtypeOf(typeArgument, bound)) {
+              _errorReporter.reportErrorForNode(
+                CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS,
+                typeArgumentList.arguments[i],
+                [typeArgument, typeParameter.name, bound],
+              );
+            }
+          }
+        }
+      } else {
+        _errorReporter.reportErrorForNode(
+          CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS,
+          typeArgumentList,
+          [
+            typeDisplayName,
+            typeParameters.length,
+            typeArgumentList.arguments.length,
+          ],
+        );
+        typeArguments = List.filled(
+          typeParameters.length,
+          DynamicTypeImpl.instance,
+        );
+      }
+      resolveWithFixedTypeArguments(typeArguments, constructorElement);
+      return;
+    }
+
+    _resolver.visitArgumentList(argumentList,
+        whyNotPromotedList: whyNotPromotedList);
+
+    var elementToInfer = ConstructorElementToInfer(
+      typeParameters,
+      constructorElement,
+    );
+    var constructorRawType = elementToInfer.asType;
+
+    var inferred = _resolver.inferenceHelper.inferGenericInvoke(
+        node, constructorRawType, typeArgumentList, argumentList, node,
+        isConst: true)!;
+
+    constructorElement = ConstructorMember.from(
+      constructorElement,
+      inferred.returnType as InterfaceType,
+    );
+    constructorName?.staticElement = constructorElement;
+    node.element = constructorElement;
+    _resolveConstructorInvocationArguments(node);
+  }
+
   /// Return a newly created cloner that can be used to clone constant
   /// expressions.
   ///
@@ -54,218 +257,175 @@
     return ConstantAstCloner();
   }
 
-  InterfaceType _instantiateAnnotationClass(ClassElement element) {
-    return element.instantiate(
-      typeArguments: List.filled(
-        element.typeParameters.length,
-        DynamicTypeImpl.instance,
-      ),
-      nullabilitySuffix: _resolver.noneOrStarSuffix,
-    );
+  void _extensionGetter(
+    AnnotationImpl node,
+    ExtensionElement extensionElement,
+    SimpleIdentifierImpl? getterName,
+    List<Map<DartType, NonPromotionReason> Function()> whyNotPromotedList,
+  ) {
+    ExecutableElement? getter;
+    if (getterName != null) {
+      getter = extensionElement.getGetter(getterName.name);
+      getter = _resolver.toLegacyElement(getter);
+    }
+
+    getterName?.staticElement = getter;
+    node.element = getter;
+
+    if (getterName != null && getter is PropertyAccessorElement) {
+      _propertyAccessorElement(node, getterName, getter, whyNotPromotedList);
+      _resolveAnnotationElementGetter(node, getter);
+    } else {
+      _errorReporter.reportErrorForNode(
+        CompileTimeErrorCode.INVALID_ANNOTATION,
+        node,
+      );
+    }
+
+    _visitArguments(node, whyNotPromotedList);
   }
 
-  void _resolve1(AnnotationImpl node) {
-    var nodeName = node.name;
+  void _propertyAccessorElement(
+    AnnotationImpl node,
+    SimpleIdentifierImpl name,
+    PropertyAccessorElement element,
+    List<Map<DartType, NonPromotionReason> Function()> whyNotPromotedList,
+  ) {
+    element = _resolver.toLegacyElement(element);
+    name.staticElement = element;
+    node.element = element;
 
-    if (nodeName is PrefixedIdentifierImpl) {
-      var prefix = nodeName.prefix;
-      var identifier = nodeName.identifier;
+    _resolveAnnotationElementGetter(node, element);
+    _visitArguments(node, whyNotPromotedList);
+  }
 
-      prefix.accept(_resolver);
-      var prefixElement = prefix.staticElement;
+  void _resolve(AnnotationImpl node,
+      List<Map<DartType, NonPromotionReason> Function()> whyNotPromotedList) {
+    SimpleIdentifierImpl name1;
+    SimpleIdentifierImpl? name2;
+    SimpleIdentifierImpl? name3;
+    var nameNode = node.name;
+    if (nameNode is PrefixedIdentifierImpl) {
+      name1 = nameNode.prefix;
+      name2 = nameNode.identifier;
+      name3 = node.constructorName;
+    } else {
+      name1 = nameNode as SimpleIdentifierImpl;
+      name2 = node.constructorName;
+    }
+    var argumentList = node.arguments;
 
-      if (prefixElement is ClassElement && node.arguments != null) {
-        var element = prefixElement.getNamedConstructor(identifier.name);
-        element = _resolver.toLegacyElement(element);
+    var element1 = _resolver.nameScope.lookup(name1.name).getter;
+    name1.staticElement = element1;
 
-        identifier.staticElement = element;
-        // TODO(scheglov) error?
-      } else if (prefixElement is PrefixElement) {
-        var resolver = PropertyElementResolver(_resolver);
-        var result = resolver.resolvePrefixedIdentifier(
-          node: nodeName,
-          hasRead: true,
-          hasWrite: false,
-          forAnnotation: true,
-        );
+    if (element1 == null) {
+      _errorReporter.reportErrorForNode(
+        CompileTimeErrorCode.UNDEFINED_ANNOTATION,
+        node,
+        [name1.name],
+      );
+      _visitArguments(node, whyNotPromotedList);
+      return;
+    }
 
-        var element = result.readElement;
-        identifier.staticElement = element;
+    // Class(args) or Class.CONST
+    if (element1 is ClassElement) {
+      if (argumentList != null) {
+        _classConstructorInvocation(
+            node, element1, name2, argumentList, whyNotPromotedList);
+      } else {
+        _classGetter(node, element1, name2, whyNotPromotedList);
+      }
+      return;
+    }
 
-        if (element == null) {
+    // Extension.CONST
+    if (element1 is ExtensionElement) {
+      _extensionGetter(node, element1, name2, whyNotPromotedList);
+      return;
+    }
+
+    // prefix.*
+    if (element1 is PrefixElement) {
+      if (name2 != null) {
+        var element2 = element1.scope.lookup(name2.name).getter;
+        name2.staticElement = element2;
+        // prefix.Class(args) or prefix.Class.CONST
+        if (element2 is ClassElement) {
+          if (argumentList != null) {
+            _classConstructorInvocation(
+                node, element2, name3, argumentList, whyNotPromotedList);
+          } else {
+            _classGetter(node, element2, name3, whyNotPromotedList);
+          }
+          return;
+        }
+        // prefix.Extension.CONST
+        if (element2 is ExtensionElement) {
+          _extensionGetter(node, element2, name3, whyNotPromotedList);
+          return;
+        }
+        // prefix.CONST
+        if (element2 is PropertyAccessorElement) {
+          _propertyAccessorElement(node, name2, element2, whyNotPromotedList);
+          return;
+        }
+
+        // prefix.TypeAlias(args) or prefix.TypeAlias.CONST
+        if (element2 is TypeAliasElement) {
+          var aliasedType = element2.aliasedType;
+          var argumentList = node.arguments;
+          if (aliasedType is InterfaceType && argumentList != null) {
+            _typeAliasConstructorInvocation(node, element2, name3, aliasedType,
+                argumentList, whyNotPromotedList);
+          } else {
+            _typeAliasGetter(node, element2, name3, whyNotPromotedList);
+          }
+          return;
+        }
+        // undefined
+        if (element2 == null) {
           _errorReporter.reportErrorForNode(
             CompileTimeErrorCode.UNDEFINED_ANNOTATION,
             node,
-            [identifier.name],
+            [name2.name],
           );
-        }
-      } else {
-        var resolver = PropertyElementResolver(_resolver);
-        var result = resolver.resolvePrefixedIdentifier(
-          node: nodeName,
-          hasRead: true,
-          hasWrite: false,
-          forAnnotation: true,
-        );
-
-        var element = result.readElement;
-        identifier.staticElement = element;
-      }
-    } else {
-      var identifier = nodeName as SimpleIdentifierImpl;
-
-      var resolver = PropertyElementResolver(_resolver);
-      var result = resolver.resolveSimpleIdentifier(
-        node: identifier,
-        hasRead: true,
-        hasWrite: false,
-      );
-
-      var element = result.readElement;
-      identifier.staticElement = element;
-
-      if (element == null) {
-        _errorReporter.reportErrorForNode(
-          CompileTimeErrorCode.UNDEFINED_ANNOTATION,
-          node,
-          [identifier.name],
-        );
-      }
-    }
-
-    _resolveAnnotationElement(node);
-  }
-
-  void _resolveAnnotationConstructorInvocationArguments(
-      AnnotationImpl annotation, ConstructorElement constructor) {
-    var argumentList = annotation.arguments;
-    // error will be reported in ConstantVerifier
-    if (argumentList == null) {
-      return;
-    }
-    // resolve arguments to parameters
-    var parameters = _resolveArgumentsToFunction(argumentList, constructor);
-    if (parameters != null) {
-      argumentList.correspondingStaticParameters = parameters;
-    }
-  }
-
-  /// Continues resolution of the given [annotation].
-  void _resolveAnnotationElement(AnnotationImpl annotation) {
-    late final SimpleIdentifier nameNode1;
-    SimpleIdentifierImpl? nameNode2;
-    {
-      Identifier annName = annotation.name;
-      if (annName is PrefixedIdentifierImpl) {
-        nameNode1 = annName.prefix;
-        nameNode2 = annName.identifier;
-      } else {
-        nameNode1 = annName as SimpleIdentifier;
-        nameNode2 = null;
-      }
-    }
-    SimpleIdentifierImpl? nameNode3 = annotation.constructorName;
-    ConstructorElement? constructor;
-    bool undefined = false;
-    //
-    // CONST or Class(args)
-    //
-    if (nameNode2 == null && nameNode3 == null) {
-      var element1 = nameNode1.staticElement;
-      // TODO(scheglov) Must be const.
-      if (element1 is VariableElement) {
-        return;
-      }
-      // CONST
-      if (element1 is PropertyAccessorElement) {
-        _resolveAnnotationElementGetter(annotation, element1);
-        return;
-      }
-      // Class(args)
-      if (element1 is ClassElement) {
-        constructor = _instantiateAnnotationClass(element1)
-            .lookUpConstructor(null, _definingLibrary);
-        constructor = _resolver.toLegacyElement(constructor);
-      } else if (element1 == null) {
-        undefined = true;
-      }
-    }
-    //
-    // prefix.CONST or prefix.Class() or Class.CONST or Class.constructor(args)
-    //
-    if (nameNode2 != null && nameNode3 == null) {
-      var element1 = nameNode1.staticElement;
-      var element2 = nameNode2.staticElement;
-      // Class.CONST - not resolved yet
-      if (element1 is ClassElement) {
-        element2 = element1.lookUpGetter(nameNode2.name, _definingLibrary);
-        element2 = _resolver.toLegacyElement(element2);
-      }
-      // prefix.CONST or Class.CONST
-      if (element2 is PropertyAccessorElement) {
-        nameNode2.staticElement = element2;
-        annotation.element = element2;
-        _resolveAnnotationElementGetter(annotation, element2);
-        return;
-      }
-      // prefix.Class()
-      if (element2 is ClassElement) {
-        constructor = element2.unnamedConstructor;
-        constructor = _resolver.toLegacyElement(constructor);
-      }
-      // Class.constructor(args)
-      if (element1 is ClassElement) {
-        constructor = _instantiateAnnotationClass(element1)
-            .lookUpConstructor(nameNode2.name, _definingLibrary);
-        constructor = _resolver.toLegacyElement(constructor);
-        nameNode2.staticElement = constructor;
-      }
-      if (element1 is PrefixElement && element2 == null) {
-        undefined = true;
-      }
-      if (element1 == null && element2 == null) {
-        undefined = true;
-      }
-    }
-    //
-    // prefix.Class.CONST or prefix.Class.constructor(args)
-    //
-    if (nameNode2 != null && nameNode3 != null) {
-      var element2 = nameNode2.staticElement;
-      // element2 should be ClassElement
-      if (element2 is ClassElement) {
-        String name3 = nameNode3.name;
-        // prefix.Class.CONST
-        var getter = element2.lookUpGetter(name3, _definingLibrary);
-        if (getter != null) {
-          getter = _resolver.toLegacyElement(getter)!;
-          nameNode3.staticElement = getter;
-          annotation.element = getter;
-          _resolveAnnotationElementGetter(annotation, getter);
+          _visitArguments(node, whyNotPromotedList);
           return;
         }
-        // prefix.Class.constructor(args)
-        constructor = _instantiateAnnotationClass(element2)
-            .lookUpConstructor(name3, _definingLibrary);
-        constructor = _resolver.toLegacyElement(constructor);
-        nameNode3.staticElement = constructor;
-      } else if (element2 == null) {
-        undefined = true;
       }
     }
-    // we need constructor
-    if (constructor == null) {
-      if (!undefined) {
-        // If the class was not found then we've already reported the error.
-        _errorReporter.reportErrorForNode(
-            CompileTimeErrorCode.INVALID_ANNOTATION, annotation);
+
+    // CONST
+    if (element1 is PropertyAccessorElement) {
+      _propertyAccessorElement(node, name1, element1, whyNotPromotedList);
+      return;
+    }
+
+    // TypeAlias(args) or TypeAlias.CONST
+    if (element1 is TypeAliasElement) {
+      var aliasedType = element1.aliasedType;
+      var argumentList = node.arguments;
+      if (aliasedType is InterfaceType && argumentList != null) {
+        _typeAliasConstructorInvocation(node, element1, name2, aliasedType,
+            argumentList, whyNotPromotedList);
+      } else {
+        _typeAliasGetter(node, element1, name2, whyNotPromotedList);
       }
       return;
     }
-    // record element
-    annotation.element = constructor;
-    // resolve arguments
-    _resolveAnnotationConstructorInvocationArguments(annotation, constructor);
+
+    // TODO(scheglov) Must be const.
+    if (element1 is VariableElement) {
+      return;
+    }
+
+    _errorReporter.reportErrorForNode(
+      CompileTimeErrorCode.INVALID_ANNOTATION,
+      node,
+    );
+
+    _visitArguments(node, whyNotPromotedList);
   }
 
   void _resolveAnnotationElementGetter(
@@ -309,4 +469,91 @@
     return ResolverVisitor.resolveArgumentsToParameters(
         argumentList, parameters, _errorReporter.reportErrorForNode);
   }
+
+  void _resolveConstructorInvocationArguments(AnnotationImpl node) {
+    var argumentList = node.arguments;
+    // error will be reported in ConstantVerifier
+    if (argumentList == null) {
+      return;
+    }
+    // resolve arguments to parameters
+    var constructor = node.element;
+    if (constructor is ConstructorElement) {
+      var parameters = _resolveArgumentsToFunction(argumentList, constructor);
+      if (parameters != null) {
+        argumentList.correspondingStaticParameters = parameters;
+      }
+    }
+  }
+
+  void _typeAliasConstructorInvocation(
+    AnnotationImpl node,
+    TypeAliasElement typeAliasElement,
+    SimpleIdentifierImpl? constructorName,
+    InterfaceType aliasedType,
+    ArgumentList argumentList,
+    List<Map<DartType, NonPromotionReason> Function()> whyNotPromotedList,
+  ) {
+    var constructorElement = aliasedType.lookUpConstructor(
+      constructorName?.name,
+      _definingLibrary,
+    );
+
+    _constructorInvocation(
+      node,
+      typeAliasElement.name,
+      constructorName,
+      typeAliasElement.typeParameters,
+      constructorElement,
+      argumentList,
+      (typeArguments) {
+        return typeAliasElement.instantiate(
+          typeArguments: typeArguments,
+          nullabilitySuffix: _resolver.noneOrStarSuffix,
+        ) as InterfaceType;
+      },
+      whyNotPromotedList,
+    );
+  }
+
+  void _typeAliasGetter(
+    AnnotationImpl node,
+    TypeAliasElement typeAliasElement,
+    SimpleIdentifierImpl? getterName,
+    List<Map<DartType, NonPromotionReason> Function()> whyNotPromotedList,
+  ) {
+    ExecutableElement? getter;
+    var aliasedType = typeAliasElement.aliasedType;
+    if (aliasedType is InterfaceType) {
+      var classElement = aliasedType.element;
+      if (getterName != null) {
+        getter = classElement.getGetter(getterName.name);
+        getter = _resolver.toLegacyElement(getter);
+      }
+    }
+
+    getterName?.staticElement = getter;
+    node.element = getter;
+
+    if (getterName != null && getter is PropertyAccessorElement) {
+      _propertyAccessorElement(node, getterName, getter, whyNotPromotedList);
+      _resolveAnnotationElementGetter(node, getter);
+    } else if (getter is! ConstructorElement) {
+      _errorReporter.reportErrorForNode(
+        CompileTimeErrorCode.INVALID_ANNOTATION,
+        node,
+      );
+    }
+
+    _visitArguments(node, whyNotPromotedList);
+  }
+
+  void _visitArguments(AnnotationImpl node,
+      List<Map<DartType, NonPromotionReason> Function()> whyNotPromotedList) {
+    var arguments = node.arguments;
+    if (arguments != null) {
+      _resolver.visitArgumentList(arguments,
+          whyNotPromotedList: whyNotPromotedList);
+    }
+  }
 }
diff --git a/pkg/analyzer/lib/src/dart/resolver/assignment_expression_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/assignment_expression_resolver.dart
index 339901a..aaaa182 100644
--- a/pkg/analyzer/lib/src/dart/resolver/assignment_expression_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/assignment_expression_resolver.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:_fe_analyzer_shared/src/flow_analysis/flow_analysis.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/dart/element/element.dart';
@@ -84,8 +85,10 @@
     }
 
     right.accept(_resolver);
+    right = node.rightHandSide;
+    var whyNotPromoted = flow?.whyNotPromoted(right);
 
-    _resolveTypes(node);
+    _resolveTypes(node, whyNotPromoted: whyNotPromoted);
 
     if (flow != null) {
       if (writeElement is PromotableElement) {
@@ -103,8 +106,9 @@
   void _checkForInvalidAssignment(
     DartType writeType,
     Expression right,
-    DartType rightType,
-  ) {
+    DartType rightType, {
+    required Map<DartType, NonPromotionReason> Function()? whyNotPromoted,
+  }) {
     if (!writeType.isVoid && _checkForUseOfVoidResult(right)) {
       return;
     }
@@ -117,6 +121,8 @@
       CompileTimeErrorCode.INVALID_ASSIGNMENT,
       right,
       [rightType, writeType],
+      _resolver.computeWhyNotPromotedMessages(
+          right, right, whyNotPromoted?.call()),
     );
   }
 
@@ -179,7 +185,7 @@
       receiver: left,
       receiverType: leftType,
       name: methodName,
-      receiverErrorNode: left,
+      propertyErrorEntity: operator,
       nameErrorEntity: operator,
     );
     node.staticElement = result.getter as MethodElement?;
@@ -192,7 +198,8 @@
     }
   }
 
-  void _resolveTypes(AssignmentExpressionImpl node) {
+  void _resolveTypes(AssignmentExpressionImpl node,
+      {required Map<DartType, NonPromotionReason> Function()? whyNotPromoted}) {
     DartType assignedType;
     DartType nodeType;
 
@@ -239,7 +246,13 @@
       node.writeType!,
       node.rightHandSide,
       assignedType,
+      whyNotPromoted: operator == TokenType.EQ ? whyNotPromoted : null,
     );
+    if (operator != TokenType.EQ &&
+        operator != TokenType.QUESTION_QUESTION_EQ) {
+      _resolver.checkForArgumentTypeNotAssignableForArgument(node.rightHandSide,
+          whyNotPromoted: whyNotPromoted);
+    }
   }
 
   void _setRhsContext(AssignmentExpressionImpl node, DartType leftType,
diff --git a/pkg/analyzer/lib/src/dart/resolver/binary_expression_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/binary_expression_resolver.dart
index 7fd4b29..e4b016a 100644
--- a/pkg/analyzer/lib/src/dart/resolver/binary_expression_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/binary_expression_resolver.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:_fe_analyzer_shared/src/flow_analysis/flow_analysis.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/dart/element/element.dart';
@@ -86,11 +87,13 @@
     _inferenceHelper.recordStaticType(node, staticType);
   }
 
-  void _checkNonBoolOperand(Expression operand, String operator) {
+  void _checkNonBoolOperand(Expression operand, String operator,
+      {required Map<DartType, NonPromotionReason> Function()? whyNotPromoted}) {
     _resolver.boolExpressionVerifier.checkForNonBoolExpression(
       operand,
       errorCode: CompileTimeErrorCode.NON_BOOL_OPERAND,
       arguments: [operator],
+      whyNotPromoted: whyNotPromoted,
     );
   }
 
@@ -108,6 +111,7 @@
     var right = node.rightOperand;
     right.accept(_resolver);
     right = node.rightOperand;
+    var whyNotPromoted = _resolver.flowAnalysis?.flow?.whyNotPromoted(right);
 
     if (!leftExtensionOverride) {
       flow?.equalityOp_end(node, right, right.typeOrThrow, notEqual: notEqual);
@@ -119,6 +123,8 @@
       promoteLeftTypeToNonNull: true,
     );
     _resolveUserDefinableType(node);
+    _resolver.checkForArgumentTypeNotAssignableForArgument(node.rightOperand,
+        promoteParameterToNullable: true, whyNotPromoted: whyNotPromoted);
   }
 
   void _resolveIfNull(BinaryExpressionImpl node) {
@@ -154,6 +160,7 @@
     } else {
       _analyzeLeastUpperBoundTypes(node, leftType, rightType);
     }
+    _resolver.checkForArgumentTypeNotAssignableForArgument(right);
   }
 
   void _resolveLogicalAnd(BinaryExpressionImpl node) {
@@ -167,13 +174,16 @@
     flow?.logicalBinaryOp_begin();
     left.accept(_resolver);
     left = node.leftOperand;
+    var leftWhyNotPromoted = _resolver.flowAnalysis?.flow?.whyNotPromoted(left);
 
+    Map<DartType, NonPromotionReason> Function()? rightWhyNotPromoted;
     if (_resolver.flowAnalysis != null) {
       flow?.logicalBinaryOp_rightBegin(left, node, isAnd: true);
       _resolver.checkUnreachableNode(right);
 
       right.accept(_resolver);
       right = node.rightOperand;
+      rightWhyNotPromoted = _resolver.flowAnalysis!.flow?.whyNotPromoted(right);
 
       _resolver.nullSafetyDeadCodeVerifier.flowEnd(right);
       flow?.logicalBinaryOp_end(node, right, isAnd: true);
@@ -188,8 +198,8 @@
       );
     }
 
-    _checkNonBoolOperand(left, '&&');
-    _checkNonBoolOperand(right, '&&');
+    _checkNonBoolOperand(left, '&&', whyNotPromoted: leftWhyNotPromoted);
+    _checkNonBoolOperand(right, '&&', whyNotPromoted: rightWhyNotPromoted);
 
     _inferenceHelper.recordStaticType(node, _typeProvider.boolType);
   }
@@ -205,18 +215,21 @@
     flow?.logicalBinaryOp_begin();
     left.accept(_resolver);
     left = node.leftOperand;
+    var leftWhyNotPromoted = _resolver.flowAnalysis?.flow?.whyNotPromoted(left);
 
     flow?.logicalBinaryOp_rightBegin(left, node, isAnd: false);
     _resolver.checkUnreachableNode(right);
 
     right.accept(_resolver);
     right = node.rightOperand;
+    var rightWhyNotPromoted =
+        _resolver.flowAnalysis?.flow?.whyNotPromoted(right);
 
     _resolver.nullSafetyDeadCodeVerifier.flowEnd(right);
     flow?.logicalBinaryOp_end(node, right, isAnd: false);
 
-    _checkNonBoolOperand(left, '||');
-    _checkNonBoolOperand(right, '||');
+    _checkNonBoolOperand(left, '||', whyNotPromoted: leftWhyNotPromoted);
+    _checkNonBoolOperand(right, '||', whyNotPromoted: rightWhyNotPromoted);
 
     _inferenceHelper.recordStaticType(node, _typeProvider.boolType);
   }
@@ -259,8 +272,12 @@
     }
 
     right.accept(_resolver);
+    right = node.rightOperand;
+    var whyNotPromoted = _resolver.flowAnalysis?.flow?.whyNotPromoted(right);
 
     _resolveUserDefinableType(node);
+    _resolver.checkForArgumentTypeNotAssignableForArgument(right,
+        whyNotPromoted: whyNotPromoted);
   }
 
   void _resolveUserDefinableElement(
@@ -305,7 +322,7 @@
       receiver: leftOperand,
       receiverType: leftType,
       name: methodName,
-      receiverErrorNode: leftOperand,
+      propertyErrorEntity: node.operator,
       nameErrorEntity: node,
     );
 
diff --git a/pkg/analyzer/lib/src/dart/resolver/body_inference_context.dart b/pkg/analyzer/lib/src/dart/resolver/body_inference_context.dart
index e74356b..e043a3f 100644
--- a/pkg/analyzer/lib/src/dart/resolver/body_inference_context.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/body_inference_context.dart
@@ -14,10 +14,14 @@
   static const _key = 'BodyInferenceContext';
 
   final TypeSystemImpl _typeSystem;
-  final bool _isAsynchronous;
-  final bool _isGenerator;
+  final bool isAsynchronous;
+  final bool isGenerator;
 
-  /// The context type, computed from the imposed return type schema.
+  /// The imposed return type, from the typing context.
+  /// Might be `null` if an empty typing context.
+  final DartType? imposedType;
+
+  /// The context type, computed from [imposedType].
   /// Might be `null` if an empty typing context.
   final DartType? contextType;
 
@@ -35,6 +39,7 @@
       typeSystem: typeSystem,
       isAsynchronous: node.isAsynchronous,
       isGenerator: node.isGenerator,
+      imposedType: imposedType,
       contextType: contextType,
     );
     node.setProperty(_key, bodyContext);
@@ -44,12 +49,13 @@
 
   BodyInferenceContext._({
     required TypeSystemImpl typeSystem,
-    required bool isAsynchronous,
-    required bool isGenerator,
+    required this.isAsynchronous,
+    required this.isGenerator,
+    required this.imposedType,
     required this.contextType,
-  })   : _typeSystem = typeSystem,
-        _isAsynchronous = isAsynchronous,
-        _isGenerator = isGenerator;
+  }) : _typeSystem = typeSystem;
+
+  bool get isSynchronous => !isAsynchronous;
 
   TypeProvider get _typeProvider => _typeSystem.typeProvider;
 
@@ -58,7 +64,7 @@
       _returnTypes.add(_typeProvider.nullType);
     } else {
       var type = expression.typeOrThrow;
-      if (_isAsynchronous) {
+      if (isAsynchronous) {
         type = _typeSystem.flatten(type);
       }
       _returnTypes.add(type);
@@ -73,8 +79,8 @@
       return;
     }
 
-    if (_isGenerator) {
-      var requiredClass = _isAsynchronous
+    if (isGenerator) {
+      var requiredClass = isAsynchronous
           ? _typeProvider.streamElement
           : _typeProvider.iterableElement;
       var type = _argumentOf(expressionType, requiredClass);
@@ -93,14 +99,14 @@
 
     var clampedReturnedType = _clampToContextType(actualReturnedType);
 
-    if (_isGenerator) {
-      if (_isAsynchronous) {
+    if (isGenerator) {
+      if (isAsynchronous) {
         return _typeProvider.streamType(clampedReturnedType);
       } else {
         return _typeProvider.iterableType(clampedReturnedType);
       }
     } else {
-      if (_isAsynchronous) {
+      if (isAsynchronous) {
         return _typeProvider.futureType(
           _typeSystem.flatten(clampedReturnedType),
         );
@@ -122,7 +128,7 @@
     // `FutureOr<void>`, let `S` be `void`.
     if (_typeSystem.isNonNullableByDefault) {
       if (R.isVoid ||
-          _isAsynchronous &&
+          isAsynchronous &&
               R is InterfaceType &&
               R.isDartAsyncFutureOr &&
               R.typeArguments[0].isVoid) {
@@ -142,7 +148,7 @@
   DartType _computeActualReturnedType({
     required bool endOfBlockIsReachable,
   }) {
-    if (_isGenerator) {
+    if (isGenerator) {
       if (_returnTypes.isEmpty) {
         return DynamicTypeImpl.instance;
       }
diff --git a/pkg/analyzer/lib/src/dart/resolver/extension_member_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/extension_member_resolver.dart
index 03c7351..93cc5b6 100644
--- a/pkg/analyzer/lib/src/dart/resolver/extension_member_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/extension_member_resolver.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/ast/syntactic_entity.dart';
 import 'package:analyzer/dart/element/element.dart';
@@ -31,6 +32,9 @@
 
   ErrorReporter get _errorReporter => _resolver.errorReporter;
 
+  bool get _genericMetadataIsEnabled =>
+      _resolver.definingLibrary.featureSet.isEnabled(Feature.generic_metadata);
+
   Scope get _nameScope => _resolver.nameScope;
 
   TypeProvider get _typeProvider => _resolver.typeProvider;
@@ -195,7 +199,7 @@
     if (typeArguments != null) {
       var arguments = typeArguments.arguments;
       if (arguments.length == typeParameters.length) {
-        typeArgumentTypes = arguments.map((a) => a.type!).toList();
+        typeArgumentTypes = arguments.map((a) => a.typeOrThrow).toList();
       } else {
         typeArgumentTypes = _listOfDynamic(typeParameters);
       }
@@ -289,6 +293,7 @@
       var typeArguments = inferrer.infer(
         freshTypeParameters,
         failAtError: true,
+        genericMetadataIsEnabled: _genericMetadataIsEnabled,
       );
       if (typeArguments == null) {
         continue;
@@ -387,7 +392,7 @@
         if (typeParameters.isEmpty) {
           return const <DartType>[];
         }
-        return arguments.map((a) => a.type!).toList();
+        return arguments.map((a) => a.typeOrThrow).toList();
       } else {
         _errorReporter.reportErrorForNode(
           CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_EXTENSION,
@@ -407,6 +412,7 @@
         typeParameters,
         errorReporter: _errorReporter,
         errorNode: node.extensionName,
+        genericMetadataIsEnabled: _genericMetadataIsEnabled,
       );
     }
   }
diff --git a/pkg/analyzer/lib/src/dart/resolver/flow_analysis_visitor.dart b/pkg/analyzer/lib/src/dart/resolver/flow_analysis_visitor.dart
index 658adba..2478a00 100644
--- a/pkg/analyzer/lib/src/dart/resolver/flow_analysis_visitor.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/flow_analysis_visitor.dart
@@ -9,6 +9,7 @@
 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/extensions.dart';
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/type_system.dart' show TypeSystemImpl;
 import 'package:analyzer/src/generated/migration.dart';
@@ -86,7 +87,7 @@
     var expression = node.expression;
     var typeAnnotation = node.type;
 
-    flow!.asExpression_end(expression, typeAnnotation.type!);
+    flow!.asExpression_end(expression, typeAnnotation.typeOrThrow);
   }
 
   void assignmentExpression(AssignmentExpression node) {
@@ -200,7 +201,7 @@
       node,
       expression,
       node.notOperator != null,
-      typeAnnotation.type!,
+      typeAnnotation.typeOrThrow,
     );
   }
 
diff --git a/pkg/analyzer/lib/src/dart/resolver/for_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/for_resolver.dart
index 7e600a4..1797cfc 100644
--- a/pkg/analyzer/lib/src/dart/resolver/for_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/for_resolver.dart
@@ -132,13 +132,12 @@
           ?.declare(loopVariable.declaredElement!, true);
     }
 
-    _resolver.flowAnalysis?.flow?.forEach_bodyBegin(
-      node,
-      identifierElement is PromotableElement
-          ? identifierElement
-          : loopVariable?.declaredElement,
-      elementType ?? DynamicTypeImpl.instance,
-    );
+    _resolver.flowAnalysis?.flow?.forEach_bodyBegin(node);
+    if (identifierElement is PromotableElement &&
+        forEachParts is ForEachPartsWithIdentifier) {
+      _resolver.flowAnalysis?.flow?.write(forEachParts, identifierElement,
+          elementType ?? DynamicTypeImpl.instance, null);
+    }
 
     _resolveBody(body);
 
@@ -159,7 +158,10 @@
       InferenceContext.setType(condition, _resolver.typeProvider.boolType);
       condition.accept(_resolver);
       condition = forParts.condition!;
-      _resolver.boolExpressionVerifier.checkForNonBoolCondition(condition);
+      var whyNotPromoted =
+          _resolver.flowAnalysis?.flow?.whyNotPromoted(condition);
+      _resolver.boolExpressionVerifier
+          .checkForNonBoolCondition(condition, whyNotPromoted: whyNotPromoted);
     }
 
     _resolver.flowAnalysis?.for_bodyBegin(node, condition);
diff --git a/pkg/analyzer/lib/src/dart/resolver/function_expression_invocation_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/function_expression_invocation_resolver.dart
index 4dfeb7d..199ea71 100644
--- a/pkg/analyzer/lib/src/dart/resolver/function_expression_invocation_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/function_expression_invocation_resolver.dart
@@ -2,11 +2,13 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'package:_fe_analyzer_shared/src/flow_analysis/flow_analysis.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/error/listener.dart';
 import 'package:analyzer/src/dart/ast/ast.dart';
+import 'package:analyzer/src/dart/ast/extensions.dart';
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/resolver/extension_member_resolver.dart';
 import 'package:analyzer/src/dart/resolver/invocation_inference_helper.dart';
@@ -34,21 +36,28 @@
   NullableDereferenceVerifier get _nullableDereferenceVerifier =>
       _resolver.nullableDereferenceVerifier;
 
-  void resolve(FunctionExpressionInvocationImpl node) {
+  void resolve(FunctionExpressionInvocationImpl node,
+      List<Map<DartType, NonPromotionReason> Function()> whyNotPromotedList) {
     var function = node.function;
 
     if (function is ExtensionOverrideImpl) {
-      _resolveReceiverExtensionOverride(node, function);
+      _resolveReceiverExtensionOverride(node, function, whyNotPromotedList);
       return;
     }
 
-    var receiverType = function.staticType;
+    var receiverType = function.typeOrThrow;
     if (receiverType is InterfaceType) {
       // Note: in this circumstance it's not necessary to call
       // `_nullableDereferenceVerifier.expression` because
       // `_resolveReceiverInterfaceType` calls `TypePropertyResolver.resolve`,
       // which does the necessary null checking.
-      _resolveReceiverInterfaceType(node, function, receiverType);
+      _resolveReceiverInterfaceType(
+          node, function, receiverType, whyNotPromotedList);
+      return;
+    }
+
+    if (_checkForUseOfVoidResult(function, receiverType)) {
+      _unresolved(node, DynamicTypeImpl.instance, whyNotPromotedList);
       return;
     }
 
@@ -56,22 +65,50 @@
         errorCode: CompileTimeErrorCode.UNCHECKED_INVOCATION_OF_NULLABLE_VALUE);
 
     if (receiverType is FunctionType) {
-      _resolve(node, receiverType);
+      _resolve(node, receiverType, whyNotPromotedList);
       return;
     }
 
     if (identical(receiverType, NeverTypeImpl.instance)) {
-      _unresolved(node, NeverTypeImpl.instance);
+      _errorReporter.reportErrorForNode(
+          HintCode.RECEIVER_OF_TYPE_NEVER, function);
+      _unresolved(node, NeverTypeImpl.instance, whyNotPromotedList);
       return;
     }
 
-    _unresolved(node, DynamicTypeImpl.instance);
+    _unresolved(node, DynamicTypeImpl.instance, whyNotPromotedList);
   }
 
-  void _resolve(FunctionExpressionInvocationImpl node, FunctionType rawType) {
+  /// Check for situations where the result of a method or function is used,
+  /// when it returns 'void'. Or, in rare cases, when other types of expressions
+  /// are void, such as identifiers.
+  ///
+  /// See [StaticWarningCode.USE_OF_VOID_RESULT].
+  ///
+  /// TODO(scheglov) this is duplicate
+  bool _checkForUseOfVoidResult(Expression expression, DartType type) {
+    if (!identical(type, VoidTypeImpl.instance)) {
+      return false;
+    }
+
+    if (expression is MethodInvocation) {
+      SimpleIdentifier methodName = expression.methodName;
+      _errorReporter.reportErrorForNode(
+          CompileTimeErrorCode.USE_OF_VOID_RESULT, methodName, []);
+    } else {
+      _errorReporter.reportErrorForNode(
+          CompileTimeErrorCode.USE_OF_VOID_RESULT, expression, []);
+    }
+
+    return true;
+  }
+
+  void _resolve(FunctionExpressionInvocationImpl node, FunctionType rawType,
+      List<Map<DartType, NonPromotionReason> Function()> whyNotPromotedList) {
     _inferenceHelper.resolveFunctionExpressionInvocation(
       node: node,
       rawType: rawType,
+      whyNotPromotedList: whyNotPromotedList,
     );
 
     var returnType = _inferenceHelper.computeInvokeReturnType(
@@ -80,13 +117,16 @@
     _inferenceHelper.recordStaticType(node, returnType);
   }
 
-  void _resolveArguments(FunctionExpressionInvocationImpl node) {
-    node.argumentList.accept(_resolver);
+  void _resolveArguments(FunctionExpressionInvocationImpl node,
+      List<Map<DartType, NonPromotionReason> Function()> whyNotPromotedList) {
+    _resolver.visitArgumentList(node.argumentList,
+        whyNotPromotedList: whyNotPromotedList);
   }
 
   void _resolveReceiverExtensionOverride(
     FunctionExpressionInvocationImpl node,
     ExtensionOverride function,
+    List<Map<DartType, NonPromotionReason> Function()> whyNotPromotedList,
   ) {
     var result = _extensionResolver.getOverrideMember(
       function,
@@ -101,7 +141,7 @@
         function,
         [function.extensionName.name],
       );
-      return _unresolved(node, DynamicTypeImpl.instance);
+      return _unresolved(node, DynamicTypeImpl.instance, whyNotPromotedList);
     }
 
     if (callElement.isStatic) {
@@ -112,36 +152,53 @@
     }
 
     var rawType = callElement.type;
-    _resolve(node, rawType);
+    _resolve(node, rawType, whyNotPromotedList);
   }
 
   void _resolveReceiverInterfaceType(
     FunctionExpressionInvocationImpl node,
     Expression function,
     InterfaceType receiverType,
+    List<Map<DartType, NonPromotionReason> Function()> whyNotPromotedList,
   ) {
     var result = _typePropertyResolver.resolve(
       receiver: function,
       receiverType: receiverType,
       name: FunctionElement.CALL_METHOD_NAME,
-      receiverErrorNode: function,
+      propertyErrorEntity: function,
       nameErrorEntity: function,
     );
     var callElement = result.getter;
 
-    if (callElement == null || callElement.kind != ElementKind.METHOD) {
-      _unresolved(node, DynamicTypeImpl.instance);
+    if (callElement == null) {
+      if (result.needsGetterError) {
+        _errorReporter.reportErrorForNode(
+          CompileTimeErrorCode.INVOCATION_OF_NON_FUNCTION_EXPRESSION,
+          function,
+        );
+      }
+      _unresolved(node, DynamicTypeImpl.instance, whyNotPromotedList);
+      return;
+    }
+
+    if (callElement.kind != ElementKind.METHOD) {
+      _errorReporter.reportErrorForNode(
+        CompileTimeErrorCode.INVOCATION_OF_NON_FUNCTION_EXPRESSION,
+        function,
+      );
+      _unresolved(node, DynamicTypeImpl.instance, whyNotPromotedList);
       return;
     }
 
     node.staticElement = callElement;
     var rawType = callElement.type;
-    _resolve(node, rawType);
+    _resolve(node, rawType, whyNotPromotedList);
   }
 
-  void _unresolved(FunctionExpressionInvocationImpl node, DartType type) {
+  void _unresolved(FunctionExpressionInvocationImpl node, DartType type,
+      List<Map<DartType, NonPromotionReason> Function()> whyNotPromotedList) {
     _setExplicitTypeArgumentTypes(node);
-    _resolveArguments(node);
+    _resolveArguments(node, whyNotPromotedList);
     node.staticInvokeType = DynamicTypeImpl.instance;
     node.staticType = type;
   }
@@ -153,7 +210,7 @@
     var typeArguments = node.typeArguments;
     if (typeArguments != null) {
       node.typeArgumentTypes = typeArguments.arguments
-          .map((typeArgument) => typeArgument.type!)
+          .map((typeArgument) => typeArgument.typeOrThrow)
           .toList();
     } else {
       node.typeArgumentTypes = const <DartType>[];
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 1ee93cf..4635774 100644
--- a/pkg/analyzer/lib/src/dart/resolver/invocation_inference_helper.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/invocation_inference_helper.dart
@@ -2,12 +2,16 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'package:_fe_analyzer_shared/src/flow_analysis/flow_analysis.dart';
+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';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/error/listener.dart';
 import 'package:analyzer/src/dart/ast/ast.dart';
 import 'package:analyzer/src/dart/ast/extensions.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/dart/element/type_system.dart';
@@ -15,24 +19,64 @@
 import 'package:analyzer/src/generated/migration.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 
+/// Information about a constructor element to instantiate.
+///
+/// If the target is a [ClassElement], the [element] is a raw
+/// [ConstructorElement] from the class, and [typeParameters] are the
+/// type parameters of the class.
+///
+/// If the target is a [TypeAliasElement] with an [InterfaceType] as the
+/// aliased type, the [element] is a [ConstructorMember] created from the
+/// [ConstructorElement] of the corresponding class, and substituting
+/// the class type parameters with the type arguments specified in the alias,
+/// explicit types or the type parameters of the alias. The [typeParameters]
+/// are the type parameters of the alias.
+class ConstructorElementToInfer {
+  /// The type parameters used in [element].
+  final List<TypeParameterElement> typeParameters;
+
+  /// The element, might be [ConstructorMember].
+  final ConstructorElement element;
+
+  ConstructorElementToInfer(this.typeParameters, this.element);
+
+  /// Return the equivalent generic function type that we could use to
+  /// forward to the constructor, or for a non-generic type simply returns
+  /// the constructor type.
+  ///
+  /// For example given the type `class C<T> { C(T arg); }`, the generic
+  /// function type is `<T>(T) -> C<T>`.
+  FunctionType get asType {
+    return FunctionTypeImpl(
+      typeFormals: typeParameters,
+      parameters: element.parameters,
+      returnType: element.returnType,
+      nullabilitySuffix: NullabilitySuffix.star,
+    );
+  }
+}
+
 class InvocationInferenceHelper {
   final ResolverVisitor _resolver;
   final ErrorReporter _errorReporter;
   final TypeSystemImpl _typeSystem;
   final MigrationResolutionHooks? _migrationResolutionHooks;
+  final bool _genericMetadataIsEnabled;
 
   List<DartType>? _typeArgumentTypes;
   FunctionType? _invokeType;
 
-  InvocationInferenceHelper(
-      {required ResolverVisitor resolver,
-      required ErrorReporter errorReporter,
-      required TypeSystemImpl typeSystem,
-      required MigrationResolutionHooks? migrationResolutionHooks})
-      : _resolver = resolver,
+  InvocationInferenceHelper({
+    required ResolverVisitor resolver,
+    required ErrorReporter errorReporter,
+    required TypeSystemImpl typeSystem,
+    required MigrationResolutionHooks? migrationResolutionHooks,
+  })   : _resolver = resolver,
         _errorReporter = errorReporter,
         _typeSystem = typeSystem,
-        _migrationResolutionHooks = migrationResolutionHooks;
+        _migrationResolutionHooks = migrationResolutionHooks,
+        _genericMetadataIsEnabled = resolver.definingLibrary.featureSet
+            .isEnabled(Feature.generic_metadata);
 
   /// Compute the return type of the method or function represented by the given
   /// type that is being invoked.
@@ -44,6 +88,50 @@
     }
   }
 
+  /// If the constructor referenced by the [constructorName] is generic,
+  /// and the [constructorName] does not have explicit type arguments,
+  /// return the element and type parameters to infer. Otherwise return `null`.
+  ConstructorElementToInfer? constructorElementToInfer({
+    required ConstructorName constructorName,
+    required LibraryElement definingLibrary,
+  }) {
+    List<TypeParameterElement>? typeParameters;
+    ConstructorElement? rawElement;
+
+    var typeName = constructorName.type;
+    var typeArguments = typeName.typeArguments;
+    var typeElement = typeName.name.staticElement;
+    if (typeElement is ClassElement) {
+      typeParameters = typeElement.typeParameters;
+      if (typeParameters.isNotEmpty && typeArguments == null) {
+        var constructorIdentifier = constructorName.name;
+        if (constructorIdentifier == null) {
+          rawElement = typeElement.unnamedConstructor;
+        } else {
+          var name = constructorIdentifier.name;
+          rawElement = typeElement.getNamedConstructor(name);
+        }
+      }
+    } else if (typeElement is TypeAliasElement) {
+      typeParameters = typeElement.typeParameters;
+      var aliasedType = typeElement.aliasedType;
+      if (aliasedType is InterfaceType) {
+        if (typeParameters.isNotEmpty && typeArguments == null) {
+          var constructorIdentifier = constructorName.name;
+          rawElement = aliasedType.lookUpConstructor(
+            constructorIdentifier?.name,
+            definingLibrary,
+          );
+        }
+      }
+    }
+
+    if (typeParameters != null && rawElement != null) {
+      rawElement = _resolver.toLegacyElement(rawElement);
+      return ConstructorElementToInfer(typeParameters, rawElement);
+    }
+  }
+
   FunctionType? inferArgumentTypesForGeneric(AstNode inferenceNode,
       DartType? uninstantiatedType, TypeArgumentList? typeArguments,
       {AstNode? errorNode, bool isConst = false}) {
@@ -62,6 +150,7 @@
         isConst: isConst,
         errorReporter: _errorReporter,
         errorNode: errorNode,
+        genericMetadataIsEnabled: _genericMetadataIsEnabled,
       );
       if (typeArguments != null) {
         return uninstantiatedType.instantiate(typeArguments);
@@ -109,7 +198,7 @@
   /// This takes into account both the context type, as well as information from
   /// the argument types.
   FunctionType? inferGenericInvoke(
-      Expression node,
+      AstNode node,
       DartType? fnType,
       TypeArgumentList? typeArguments,
       ArgumentList argumentList,
@@ -139,7 +228,8 @@
     // for FunctionExpressionInvocation(s), so set it here, if not inferred.
     if (node is FunctionExpressionInvocationImpl) {
       if (typeArguments != null) {
-        var typeArgs = typeArguments.arguments.map((n) => n.type!).toList();
+        var typeArgs =
+            typeArguments.arguments.map((n) => n.typeOrThrow).toList();
         node.typeArgumentTypes = typeArgs;
       } else {
         node.typeArgumentTypes = const <DartType>[];
@@ -164,6 +254,7 @@
         tearOffType,
         errorReporter: _resolver.errorReporter,
         errorNode: expression,
+        genericMetadataIsEnabled: _genericMetadataIsEnabled,
       )!;
       (identifier as SimpleIdentifierImpl).tearOffTypeArgumentTypes =
           typeArguments;
@@ -200,6 +291,8 @@
   void resolveFunctionExpressionInvocation({
     required FunctionExpressionInvocationImpl node,
     required FunctionType rawType,
+    required List<Map<DartType, NonPromotionReason> Function()>
+        whyNotPromotedList,
   }) {
     _resolveInvocation(
       rawType: rawType,
@@ -208,6 +301,7 @@
       contextType: InferenceContext.getContext(node),
       isConst: false,
       errorNode: node.function,
+      whyNotPromotedList: whyNotPromotedList,
     );
 
     node.typeArgumentTypes = _typeArgumentTypes;
@@ -222,6 +316,8 @@
   void resolveMethodInvocation({
     required MethodInvocationImpl node,
     required FunctionType rawType,
+    required List<Map<DartType, NonPromotionReason> Function()>
+        whyNotPromotedList,
   }) {
     _resolveInvocation(
       rawType: rawType,
@@ -230,6 +326,7 @@
       contextType: InferenceContext.getContext(node),
       isConst: false,
       errorNode: node.function,
+      whyNotPromotedList: whyNotPromotedList,
     );
 
     node.typeArgumentTypes = _typeArgumentTypes;
@@ -266,6 +363,7 @@
       isConst: isConst,
       errorReporter: _errorReporter,
       errorNode: errorNode,
+      genericMetadataIsEnabled: _genericMetadataIsEnabled,
     );
   }
 
@@ -302,6 +400,7 @@
       isConst: isConst,
       errorReporter: _errorReporter,
       errorNode: errorNode,
+      genericMetadataIsEnabled: _genericMetadataIsEnabled,
     );
     return typeArgs;
   }
@@ -316,9 +415,11 @@
     return false;
   }
 
-  void _resolveArguments(ArgumentList argumentList) {
+  void _resolveArguments(ArgumentList argumentList,
+      List<Map<DartType, NonPromotionReason> Function()> whyNotPromotedList) {
     _resolver.visitArgumentList(argumentList,
-        isIdentical: _isCallToIdentical(argumentList.parent));
+        isIdentical: _isCallToIdentical(argumentList.parent),
+        whyNotPromotedList: whyNotPromotedList);
   }
 
   void _resolveInvocation({
@@ -328,12 +429,15 @@
     required ArgumentListImpl argumentList,
     required bool isConst,
     required AstNode errorNode,
+    required List<Map<DartType, NonPromotionReason> Function()>
+        whyNotPromotedList,
   }) {
     if (typeArgumentList != null) {
       _resolveInvocationWithTypeArguments(
         rawType: rawType,
         typeArgumentList: typeArgumentList,
         argumentList: argumentList,
+        whyNotPromotedList: whyNotPromotedList,
       );
     } else {
       _resolveInvocationWithoutTypeArguments(
@@ -342,6 +446,7 @@
         argumentList: argumentList,
         isConst: isConst,
         errorNode: errorNode,
+        whyNotPromotedList: whyNotPromotedList,
       );
     }
     _setCorrespondingParameters(argumentList, _invokeType!);
@@ -353,12 +458,14 @@
     required ArgumentList argumentList,
     required bool isConst,
     required AstNode errorNode,
+    required List<Map<DartType, NonPromotionReason> Function()>
+        whyNotPromotedList,
   }) {
     var typeParameters = rawType.typeFormals;
 
     if (typeParameters.isEmpty) {
       InferenceContext.setType(argumentList, rawType);
-      _resolveArguments(argumentList);
+      _resolveArguments(argumentList, whyNotPromotedList);
 
       _typeArgumentTypes = const <DartType>[];
       _invokeType = rawType;
@@ -375,7 +482,7 @@
       var downwardsInvokeType = rawType.instantiate(downwardsTypeArguments);
       InferenceContext.setType(argumentList, downwardsInvokeType);
 
-      _resolveArguments(argumentList);
+      _resolveArguments(argumentList, whyNotPromotedList);
 
       _typeArgumentTypes = _inferUpwards(
         rawType: rawType,
@@ -392,6 +499,8 @@
     required FunctionType rawType,
     required TypeArgumentList typeArgumentList,
     required ArgumentList argumentList,
+    required List<Map<DartType, NonPromotionReason> Function()>
+        whyNotPromotedList,
   }) {
     var typeParameters = rawType.typeFormals;
 
@@ -412,14 +521,14 @@
       );
     } else {
       typeArguments = typeArgumentList.arguments
-          .map((typeArgument) => typeArgument.type!)
+          .map((typeArgument) => typeArgument.typeOrThrow)
           .toList(growable: true);
     }
 
     var invokeType = rawType.instantiate(typeArguments);
     InferenceContext.setType(argumentList, invokeType);
 
-    _resolveArguments(argumentList);
+    _resolveArguments(argumentList, whyNotPromotedList);
 
     _typeArgumentTypes = typeArguments;
     _invokeType = invokeType;
diff --git a/pkg/analyzer/lib/src/dart/resolver/lexical_lookup.dart b/pkg/analyzer/lib/src/dart/resolver/lexical_lookup.dart
index f9256ea..63bc1cf 100644
--- a/pkg/analyzer/lib/src/dart/resolver/lexical_lookup.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/lexical_lookup.dart
@@ -56,7 +56,7 @@
       receiver: null,
       receiverType: thisType,
       name: id,
-      receiverErrorNode: node,
+      propertyErrorEntity: node,
       nameErrorEntity: node,
     );
 
diff --git a/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart
index 77429cb..caff683 100644
--- a/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.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:_fe_analyzer_shared/src/flow_analysis/flow_analysis.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/scope.dart';
@@ -80,7 +81,8 @@
 
   TypeSystemImpl get _typeSystem => _resolver.typeSystem;
 
-  void resolve(MethodInvocationImpl node) {
+  void resolve(MethodInvocationImpl node,
+      List<Map<DartType, NonPromotionReason> Function()> whyNotPromotedList) {
     _invocation = node;
 
     var nameNode = node.methodName;
@@ -90,14 +92,15 @@
     var receiver = node.realTarget;
 
     if (receiver == null) {
-      _resolveReceiverNull(node, nameNode, name);
+      _resolveReceiverNull(node, nameNode, name, whyNotPromotedList);
       return;
     }
 
     if (receiver is SimpleIdentifierImpl) {
       var receiverElement = receiver.staticElement;
       if (receiverElement is PrefixElement) {
-        _resolveReceiverPrefix(node, receiverElement, nameNode, name);
+        _resolveReceiverPrefix(
+            node, receiverElement, nameNode, name, whyNotPromotedList);
         return;
       }
     }
@@ -105,32 +108,34 @@
     if (receiver is IdentifierImpl) {
       var receiverElement = receiver.staticElement;
       if (receiverElement is ExtensionElement) {
-        _resolveExtensionMember(
-            node, receiver, receiverElement, nameNode, name);
+        _resolveExtensionMember(node, receiver, receiverElement, nameNode, name,
+            whyNotPromotedList);
         return;
       }
     }
 
     if (receiver is SuperExpressionImpl) {
-      _resolveReceiverSuper(node, receiver, nameNode, name);
+      _resolveReceiverSuper(node, receiver, nameNode, name, whyNotPromotedList);
       return;
     }
 
     if (receiver is ExtensionOverrideImpl) {
-      _resolveExtensionOverride(node, receiver, nameNode, name);
+      _resolveExtensionOverride(
+          node, receiver, nameNode, name, whyNotPromotedList);
       return;
     }
 
     if (receiver is IdentifierImpl) {
       var element = receiver.staticElement;
       if (element is ClassElement) {
-        _resolveReceiverTypeLiteral(node, element, nameNode, name);
+        _resolveReceiverTypeLiteral(
+            node, element, nameNode, name, whyNotPromotedList);
         return;
       } else if (element is TypeAliasElement) {
         var aliasedType = element.aliasedType;
         if (aliasedType is InterfaceType) {
           _resolveReceiverTypeLiteral(
-              node, aliasedType.element, nameNode, name);
+              node, aliasedType.element, nameNode, name, whyNotPromotedList);
           return;
         }
       }
@@ -139,17 +144,17 @@
     DartType receiverType = receiver.typeOrThrow;
 
     if (_typeSystem.isDynamicBounded(receiverType)) {
-      _resolveReceiverDynamicBounded(node);
+      _resolveReceiverDynamicBounded(node, whyNotPromotedList);
       return;
     }
 
     if (receiverType is NeverTypeImpl) {
-      _resolveReceiverNever(node, receiver, receiverType);
+      _resolveReceiverNever(node, receiver, receiverType, whyNotPromotedList);
       return;
     }
 
     if (receiverType is VoidType) {
-      _reportUseOfVoidType(node, receiver);
+      _reportUseOfVoidType(node, receiver, whyNotPromotedList);
       return;
     }
 
@@ -160,7 +165,7 @@
 
     if (_typeSystem.isFunctionBounded(receiverType)) {
       _resolveReceiverFunctionBounded(
-          node, receiver, receiverType, nameNode, name);
+          node, receiver, receiverType, nameNode, name, whyNotPromotedList);
       return;
     }
 
@@ -171,6 +176,7 @@
       nameNode: nameNode,
       name: name,
       receiverErrorNode: receiver,
+      whyNotPromotedList: whyNotPromotedList,
     );
   }
 
@@ -210,8 +216,10 @@
     }
   }
 
-  void _reportInvocationOfNonFunction(MethodInvocationImpl node) {
-    _setDynamicResolution(node, setNameTypeToDynamic: false);
+  void _reportInvocationOfNonFunction(MethodInvocationImpl node,
+      List<Map<DartType, NonPromotionReason> Function()> whyNotPromotedList) {
+    _setDynamicResolution(node,
+        setNameTypeToDynamic: false, whyNotPromotedList: whyNotPromotedList);
     _resolver.errorReporter.reportErrorForNode(
       CompileTimeErrorCode.INVOCATION_OF_NON_FUNCTION,
       node.methodName,
@@ -242,8 +250,10 @@
     MethodInvocationImpl node, {
     required String? prefix,
     required String name,
+    required List<Map<DartType, NonPromotionReason> Function()>
+        whyNotPromotedList,
   }) {
-    _setDynamicResolution(node);
+    _setDynamicResolution(node, whyNotPromotedList: whyNotPromotedList);
 
     if (nameScope.shouldIgnoreUndefined2(prefix: prefix, name: name)) {
       return;
@@ -257,8 +267,11 @@
   }
 
   void _reportUndefinedMethod(
-      MethodInvocationImpl node, String name, ClassElement typeReference) {
-    _setDynamicResolution(node);
+      MethodInvocationImpl node,
+      String name,
+      ClassElement typeReference,
+      List<Map<DartType, NonPromotionReason> Function()> whyNotPromotedList) {
+    _setDynamicResolution(node, whyNotPromotedList: whyNotPromotedList);
     _resolver.errorReporter.reportErrorForNode(
       CompileTimeErrorCode.UNDEFINED_METHOD,
       node.methodName,
@@ -266,8 +279,9 @@
     );
   }
 
-  void _reportUseOfVoidType(MethodInvocationImpl node, AstNode errorNode) {
-    _setDynamicResolution(node);
+  void _reportUseOfVoidType(MethodInvocationImpl node, AstNode errorNode,
+      List<Map<DartType, NonPromotionReason> Function()> whyNotPromotedList) {
+    _setDynamicResolution(node, whyNotPromotedList: whyNotPromotedList);
     _resolver.errorReporter.reportErrorForNode(
       CompileTimeErrorCode.USE_OF_VOID_RESULT,
       errorNode,
@@ -276,17 +290,20 @@
 
   /// [InvocationExpression.staticInvokeType] has been set for the [node].
   /// Use it to set context for arguments, and resolve them.
-  void _resolveArguments(MethodInvocationImpl node) {
+  void _resolveArguments(MethodInvocationImpl node,
+      List<Map<DartType, NonPromotionReason> Function()> whyNotPromotedList) {
     // TODO(scheglov) This is bad, don't write raw type, carry it
     _inferenceHelper.inferArgumentTypesForInvocation(
       node,
       node.methodName.staticType,
     );
-    node.argumentList.accept(_resolver);
+    _resolver.visitArgumentList(node.argumentList,
+        whyNotPromotedList: whyNotPromotedList);
   }
 
-  void _resolveArguments_finishInference(MethodInvocationImpl node) {
-    _resolveArguments(node);
+  void _resolveArguments_finishInference(MethodInvocationImpl node,
+      List<Map<DartType, NonPromotionReason> Function()> whyNotPromotedList) {
+    _resolveArguments(node, whyNotPromotedList);
 
     // TODO(scheglov) This is bad, don't put / get raw FunctionType this way.
     _inferenceHelper.inferGenericInvocationExpression(
@@ -318,8 +335,13 @@
     return null;
   }
 
-  void _resolveExtensionMember(MethodInvocationImpl node, Identifier receiver,
-      ExtensionElement extension, SimpleIdentifierImpl nameNode, String name) {
+  void _resolveExtensionMember(
+      MethodInvocationImpl node,
+      Identifier receiver,
+      ExtensionElement extension,
+      SimpleIdentifierImpl nameNode,
+      String name,
+      List<Map<DartType, NonPromotionReason> Function()> whyNotPromotedList) {
     var getter = extension.getGetter(name);
     if (getter != null) {
       getter = _resolver.toLegacyElement(getter);
@@ -334,11 +356,11 @@
       method = _resolver.toLegacyElement(method);
       nameNode.staticElement = method;
       _reportStaticAccessToInstanceMember(method, nameNode);
-      _setResolution(node, method.type);
+      _setResolution(node, method.type, whyNotPromotedList);
       return;
     }
 
-    _setDynamicResolution(node);
+    _setDynamicResolution(node, whyNotPromotedList: whyNotPromotedList);
     _resolver.errorReporter.reportErrorForNode(
       CompileTimeErrorCode.UNDEFINED_EXTENSION_METHOD,
       nameNode,
@@ -346,13 +368,17 @@
     );
   }
 
-  void _resolveExtensionOverride(MethodInvocationImpl node,
-      ExtensionOverride override, SimpleIdentifierImpl nameNode, String name) {
+  void _resolveExtensionOverride(
+      MethodInvocationImpl node,
+      ExtensionOverride override,
+      SimpleIdentifierImpl nameNode,
+      String name,
+      List<Map<DartType, NonPromotionReason> Function()> whyNotPromotedList) {
     var result = _extensionResolver.getOverrideMember(override, name);
     var member = _resolver.toLegacyElement(result.getter);
 
     if (member == null) {
-      _setDynamicResolution(node);
+      _setDynamicResolution(node, whyNotPromotedList: whyNotPromotedList);
       _resolver.errorReporter.reportErrorForNode(
         CompileTimeErrorCode.UNDEFINED_EXTENSION_METHOD,
         nameNode,
@@ -382,10 +408,11 @@
       return _rewriteAsFunctionExpressionInvocation(node, member.returnType);
     }
 
-    _setResolution(node, member.type);
+    _setResolution(node, member.type, whyNotPromotedList);
   }
 
-  void _resolveReceiverDynamicBounded(MethodInvocationImpl node) {
+  void _resolveReceiverDynamicBounded(MethodInvocationImpl node,
+      List<Map<DartType, NonPromotionReason> Function()> whyNotPromotedList) {
     var nameNode = node.methodName;
 
     var objectElement = _typeSystem.typeProvider.objectElement;
@@ -411,7 +438,8 @@
     }
 
     _setExplicitTypeArgumentTypes();
-    node.argumentList.accept(_resolver);
+    _resolver.visitArgumentList(node.argumentList,
+        whyNotPromotedList: whyNotPromotedList);
   }
 
   void _resolveReceiverFunctionBounded(
@@ -420,9 +448,10 @@
     DartType receiverType,
     SimpleIdentifierImpl nameNode,
     String name,
+    List<Map<DartType, NonPromotionReason> Function()> whyNotPromotedList,
   ) {
     if (name == FunctionElement.CALL_METHOD_NAME) {
-      _setResolution(node, receiverType);
+      _setResolution(node, receiverType, whyNotPromotedList);
       // TODO(scheglov) Replace this with using FunctionType directly.
       // Here was erase resolution that _setResolution() sets.
       nameNode.staticElement = null;
@@ -437,6 +466,7 @@
       nameNode: nameNode,
       name: name,
       receiverErrorNode: nameNode,
+      whyNotPromotedList: whyNotPromotedList,
     );
   }
 
@@ -444,6 +474,7 @@
     MethodInvocationImpl node,
     Expression receiver,
     DartType receiverType,
+    List<Map<DartType, NonPromotionReason> Function()> whyNotPromotedList,
   ) {
     _setExplicitTypeArgumentTypes();
 
@@ -457,10 +488,11 @@
         _setResolution(
           node,
           objectMember.type,
+          whyNotPromotedList,
         );
       } else {
-        _setDynamicResolution(node);
-        _resolver.nullableDereferenceVerifier.report(receiver, receiverType,
+        _setDynamicResolution(node, whyNotPromotedList: whyNotPromotedList);
+        _resolver.nullableDereferenceVerifier.report(methodName, receiverType,
             errorCode: CompileTimeErrorCode
                 .UNCHECKED_METHOD_INVOCATION_OF_NULLABLE_VALUE);
       }
@@ -472,7 +504,7 @@
       node.staticInvokeType = _dynamicType;
       node.staticType = NeverTypeImpl.instance;
 
-      _resolveArguments(node);
+      _resolveArguments(node, whyNotPromotedList);
 
       _resolver.errorReporter.reportErrorForNode(
         HintCode.RECEIVER_OF_TYPE_NEVER,
@@ -486,13 +518,16 @@
       node.staticInvokeType = _dynamicType;
       node.staticType = _dynamicType;
 
-      _resolveArguments(node);
+      _resolveArguments(node, whyNotPromotedList);
       return;
     }
   }
 
   void _resolveReceiverNull(
-      MethodInvocationImpl node, SimpleIdentifierImpl nameNode, String name) {
+      MethodInvocationImpl node,
+      SimpleIdentifierImpl nameNode,
+      String name,
+      List<Map<DartType, NonPromotionReason> Function()> whyNotPromotedList) {
     var element = nameScope.lookup(name).getter;
     if (element != null) {
       element = _resolver.toLegacyElement(element);
@@ -505,7 +540,7 @@
         return _rewriteAsFunctionExpressionInvocation(node, element.returnType);
       }
       if (element is ExecutableElement) {
-        return _setResolution(node, element.type);
+        return _setResolution(node, element.type, whyNotPromotedList);
       }
       if (element is VariableElement) {
         _resolver.checkReadOfNotAssignedLocalVariable(nameNode, element);
@@ -514,10 +549,10 @@
       }
       // TODO(scheglov) This is a questionable distinction.
       if (element is PrefixElement) {
-        _setDynamicResolution(node);
+        _setDynamicResolution(node, whyNotPromotedList: whyNotPromotedList);
         return _reportPrefixIdentifierNotFollowedByDot(nameNode);
       }
-      return _reportInvocationOfNonFunction(node);
+      return _reportInvocationOfNonFunction(node, whyNotPromotedList);
     }
 
     DartType receiverType;
@@ -530,6 +565,7 @@
         node,
         prefix: null,
         name: node.methodName.name,
+        whyNotPromotedList: whyNotPromotedList,
       );
     }
 
@@ -540,11 +576,16 @@
       nameNode: nameNode,
       name: name,
       receiverErrorNode: nameNode,
+      whyNotPromotedList: whyNotPromotedList,
     );
   }
 
-  void _resolveReceiverPrefix(MethodInvocationImpl node, PrefixElement prefix,
-      SimpleIdentifierImpl nameNode, String name) {
+  void _resolveReceiverPrefix(
+      MethodInvocationImpl node,
+      PrefixElement prefix,
+      SimpleIdentifierImpl nameNode,
+      String name,
+      List<Map<DartType, NonPromotionReason> Function()> whyNotPromotedList) {
     // Note: prefix?.bar is reported as an error in ElementResolver.
 
     if (name == FunctionElement.LOAD_LIBRARY_NAME) {
@@ -555,7 +596,8 @@
         element = _resolver.toLegacyElement(element);
         if (element is ExecutableElement) {
           nameNode.staticElement = element;
-          return _setResolution(node, (element as ExecutableElement).type);
+          return _setResolution(
+              node, (element as ExecutableElement).type, whyNotPromotedList);
         }
       }
     }
@@ -574,21 +616,26 @@
     }
 
     if (element is ExecutableElement) {
-      return _setResolution(node, element.type);
+      return _setResolution(node, element.type, whyNotPromotedList);
     }
 
     _reportUndefinedFunction(
       node,
       prefix: prefix.name,
       name: name,
+      whyNotPromotedList: whyNotPromotedList,
     );
   }
 
-  void _resolveReceiverSuper(MethodInvocationImpl node,
-      SuperExpression receiver, SimpleIdentifierImpl nameNode, String name) {
+  void _resolveReceiverSuper(
+      MethodInvocationImpl node,
+      SuperExpression receiver,
+      SimpleIdentifierImpl nameNode,
+      String name,
+      List<Map<DartType, NonPromotionReason> Function()> whyNotPromotedList) {
     var enclosingClass = _resolver.enclosingClass;
     if (SuperContext.of(receiver) != SuperContext.valid) {
-      _setDynamicResolution(node);
+      _setDynamicResolution(node, whyNotPromotedList: whyNotPromotedList);
       return;
     }
 
@@ -605,7 +652,7 @@
       if (target is PropertyAccessorElement) {
         return _rewriteAsFunctionExpressionInvocation(node, target.returnType);
       }
-      _setResolution(node, target.type);
+      _setResolution(node, target.type, whyNotPromotedList);
       return;
     }
 
@@ -615,7 +662,7 @@
     target = _inheritance.getInherited2(enclosingClass, _currentName!);
     if (target != null) {
       nameNode.staticElement = target;
-      _setResolution(node, target.type);
+      _setResolution(node, target.type, whyNotPromotedList);
 
       _resolver.errorReporter.reportErrorForNode(
           CompileTimeErrorCode.ABSTRACT_SUPER_MEMBER_REFERENCE,
@@ -625,7 +672,7 @@
     }
 
     // Nothing help, there is no target at all.
-    _setDynamicResolution(node);
+    _setDynamicResolution(node, whyNotPromotedList: whyNotPromotedList);
     _resolver.errorReporter.reportErrorForNode(
         CompileTimeErrorCode.UNDEFINED_SUPER_METHOD,
         nameNode,
@@ -639,12 +686,14 @@
     required SimpleIdentifierImpl nameNode,
     required String name,
     required Expression receiverErrorNode,
+    required List<Map<DartType, NonPromotionReason> Function()>
+        whyNotPromotedList,
   }) {
     var result = _resolver.typePropertyResolver.resolve(
       receiver: receiver,
       receiverType: receiverType,
       name: name,
-      receiverErrorNode: receiverErrorNode,
+      propertyErrorEntity: nameNode,
       nameErrorEntity: nameNode,
     );
 
@@ -663,10 +712,10 @@
       if (target is PropertyAccessorElement) {
         return _rewriteAsFunctionExpressionInvocation(node, target.returnType);
       }
-      return _setResolution(node, target.type);
+      return _setResolution(node, target.type, whyNotPromotedList);
     }
 
-    _setDynamicResolution(node);
+    _setDynamicResolution(node, whyNotPromotedList: whyNotPromotedList);
 
     if (!result.needsGetterError) {
       return;
@@ -688,8 +737,12 @@
     }
   }
 
-  void _resolveReceiverTypeLiteral(MethodInvocationImpl node,
-      ClassElement receiver, SimpleIdentifierImpl nameNode, String name) {
+  void _resolveReceiverTypeLiteral(
+      MethodInvocationImpl node,
+      ClassElement receiver,
+      SimpleIdentifierImpl nameNode,
+      String name,
+      List<Map<DartType, NonPromotionReason> Function()> whyNotPromotedList) {
     if (node.isCascaded) {
       receiver = _typeType.element;
     }
@@ -703,14 +756,14 @@
           return _rewriteAsFunctionExpressionInvocation(
               node, element.returnType);
         }
-        _setResolution(node, element.type);
+        _setResolution(node, element.type, whyNotPromotedList);
       } else {
-        _reportInvocationOfNonFunction(node);
+        _reportInvocationOfNonFunction(node, whyNotPromotedList);
       }
       return;
     }
 
-    _reportUndefinedMethod(node, name, receiver);
+    _reportUndefinedMethod(node, name, receiver, whyNotPromotedList);
   }
 
   /// If the given [type] is a type parameter, replace with its bound.
@@ -770,14 +823,16 @@
   }
 
   void _setDynamicResolution(MethodInvocationImpl node,
-      {bool setNameTypeToDynamic = true}) {
+      {bool setNameTypeToDynamic = true,
+      required List<Map<DartType, NonPromotionReason> Function()>
+          whyNotPromotedList}) {
     if (setNameTypeToDynamic) {
       node.methodName.staticType = _dynamicType;
     }
     node.staticInvokeType = _dynamicType;
     node.staticType = _dynamicType;
     _setExplicitTypeArgumentTypes();
-    _resolveArguments_finishInference(node);
+    _resolveArguments_finishInference(node, whyNotPromotedList);
   }
 
   /// Set explicitly specified type argument types, or empty if not specified.
@@ -789,32 +844,36 @@
     var typeArgumentList = _invocation!.typeArguments;
     if (typeArgumentList != null) {
       var arguments = typeArgumentList.arguments;
-      _invocation!.typeArgumentTypes = arguments.map((n) => n.type!).toList();
+      _invocation!.typeArgumentTypes =
+          arguments.map((n) => n.typeOrThrow).toList();
     } else {
       _invocation!.typeArgumentTypes = [];
     }
   }
 
-  void _setResolution(MethodInvocationImpl node, DartType type) {
+  void _setResolution(MethodInvocationImpl node, DartType type,
+      List<Map<DartType, NonPromotionReason> Function()> whyNotPromotedList) {
     // TODO(scheglov) We need this for StaticTypeAnalyzer to run inference.
     // But it seems weird. Do we need to know the raw type of a function?!
     node.methodName.staticType = type;
 
     if (type == _dynamicType || _isCoreFunction(type)) {
-      _setDynamicResolution(node, setNameTypeToDynamic: false);
+      _setDynamicResolution(node,
+          setNameTypeToDynamic: false, whyNotPromotedList: whyNotPromotedList);
       return;
     }
 
     if (type is FunctionType) {
-      _inferenceHelper.resolveMethodInvocation(node: node, rawType: type);
+      _inferenceHelper.resolveMethodInvocation(
+          node: node, rawType: type, whyNotPromotedList: whyNotPromotedList);
       return;
     }
 
     if (type is VoidType) {
-      return _reportUseOfVoidType(node, node.methodName);
+      return _reportUseOfVoidType(node, node.methodName, whyNotPromotedList);
     }
 
-    _reportInvocationOfNonFunction(node);
+    _reportInvocationOfNonFunction(node, whyNotPromotedList);
   }
 
   /// Resolver visitor is separated from the elements resolver, which calls
diff --git a/pkg/analyzer/lib/src/dart/resolver/postfix_expression_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/postfix_expression_resolver.dart
index e8adbbb..c09803d 100644
--- a/pkg/analyzer/lib/src/dart/resolver/postfix_expression_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/postfix_expression_resolver.dart
@@ -134,7 +134,7 @@
       receiver: operand,
       receiverType: receiverType,
       name: methodName,
-      receiverErrorNode: operand,
+      propertyErrorEntity: node.operator,
       nameErrorEntity: operand,
     );
     node.staticElement = result.getter as MethodElement?;
diff --git a/pkg/analyzer/lib/src/dart/resolver/prefix_expression_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/prefix_expression_resolver.dart
index 99ed1ac..6e787e6 100644
--- a/pkg/analyzer/lib/src/dart/resolver/prefix_expression_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/prefix_expression_resolver.dart
@@ -168,7 +168,7 @@
         receiver: operand,
         receiverType: readType,
         name: methodName,
-        receiverErrorNode: operand,
+        propertyErrorEntity: node.operator,
         nameErrorEntity: operand,
       );
       node.staticElement = result.getter as MethodElement?;
@@ -226,8 +226,10 @@
 
     operand.accept(_resolver);
     operand = node.operand;
+    var whyNotPromoted = _resolver.flowAnalysis?.flow?.whyNotPromoted(operand);
 
-    _resolver.boolExpressionVerifier.checkForNonBoolNegationExpression(operand);
+    _resolver.boolExpressionVerifier.checkForNonBoolNegationExpression(operand,
+        whyNotPromoted: whyNotPromoted);
 
     _recordStaticType(node, _typeProvider.boolType);
 
diff --git a/pkg/analyzer/lib/src/dart/resolver/property_element_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/property_element_resolver.dart
index 23fcd9b..8a64758 100644
--- a/pkg/analyzer/lib/src/dart/resolver/property_element_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/property_element_resolver.dart
@@ -8,7 +8,6 @@
 import 'package:analyzer/error/error.dart';
 import 'package:analyzer/error/listener.dart';
 import 'package:analyzer/src/dart/ast/extensions.dart';
-import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/inheritance_manager3.dart';
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/type_system.dart';
@@ -96,7 +95,7 @@
       receiver: target,
       receiverType: targetType,
       name: '[]',
-      receiverErrorNode: target,
+      propertyErrorEntity: node.leftBracket,
       nameErrorEntity: target,
     );
 
@@ -370,7 +369,7 @@
       receiver: target,
       receiverType: targetType,
       name: propertyName.name,
-      receiverErrorNode: target,
+      propertyErrorEntity: propertyName,
       nameErrorEntity: propertyName,
     );
 
@@ -677,15 +676,11 @@
             inherited: true,
           );
           if (writeElement != null) {
-            var receiverSuperClass =
-                targetType.element.supertype!.element as ClassElementImpl;
-            if (!receiverSuperClass.hasNoSuchMethod) {
-              _errorReporter.reportErrorForNode(
-                CompileTimeErrorCode.ABSTRACT_SUPER_MEMBER_REFERENCE,
-                propertyName,
-                [writeElement.kind.displayName, propertyName.name],
-              );
-            }
+            _errorReporter.reportErrorForNode(
+              CompileTimeErrorCode.ABSTRACT_SUPER_MEMBER_REFERENCE,
+              propertyName,
+              [writeElement.kind.displayName, propertyName.name],
+            );
           } else {
             _errorReporter.reportErrorForNode(
               CompileTimeErrorCode.UNDEFINED_SUPER_SETTER,
diff --git a/pkg/analyzer/lib/src/dart/resolver/resolution_visitor.dart b/pkg/analyzer/lib/src/dart/resolver/resolution_visitor.dart
index 49c88e6..91d1ae7 100644
--- a/pkg/analyzer/lib/src/dart/resolver/resolution_visitor.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/resolution_visitor.dart
@@ -13,6 +13,7 @@
 import 'package:analyzer/error/error.dart';
 import 'package:analyzer/error/listener.dart';
 import 'package:analyzer/src/dart/ast/ast.dart';
+import 'package:analyzer/src/dart/ast/extensions.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/scope.dart';
 import 'package:analyzer/src/dart/element/type.dart';
@@ -180,7 +181,7 @@
           element.type = type;
           exceptionNode.staticType = type;
         } else {
-          element.type = exceptionTypeNode.type!;
+          element.type = exceptionTypeNode.typeOrThrow;
           exceptionNode.staticType = exceptionTypeNode.type;
         }
 
@@ -321,7 +322,7 @@
       element.type = _dynamicType;
     } else {
       node.type!.accept(this);
-      element.type = node.type!.type!;
+      element.type = node.type!.typeOrThrow;
     }
 
     _setCodeRange(element, node);
@@ -1192,7 +1193,11 @@
     visitTypeName(typeName);
     _typeNameResolver.classHierarchy_typeName = null;
 
-    DartType type = typeName.type!;
+    if (_typeNameResolver.hasErrorReported) {
+      return;
+    }
+
+    DartType type = typeName.typeOrThrow;
     if (type is InterfaceType) {
       ClassElement element = type.element;
       if (element.isEnum || element.isMixin && asClass) {
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 fe60568..4acea06 100644
--- a/pkg/analyzer/lib/src/dart/resolver/type_name_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/type_name_resolver.dart
@@ -2,14 +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/features.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/nullability_suffix.dart';
 import 'package:analyzer/dart/element/scope.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/dart/element/type_provider.dart';
+import 'package:analyzer/error/error.dart';
 import 'package:analyzer/error/listener.dart';
 import 'package:analyzer/src/dart/ast/ast.dart';
+import 'package:analyzer/src/dart/ast/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_system.dart';
@@ -50,10 +53,16 @@
   /// [ConstructorName]. Otherwise this field will be set `null`.
   ConstructorName? rewriteResult;
 
+  /// If [resolveTypeName] reported an error, this flag is set to `true`.
+  bool hasErrorReported = false;
+
   TypeNameResolver(this.typeSystem, TypeProvider typeProvider,
       this.isNonNullableByDefault, this.errorReporter)
       : dynamicType = typeProvider.dynamicType;
 
+  bool get _genericMetadataIsEnabled =>
+      enclosingClass!.library.featureSet.isEnabled(Feature.generic_metadata);
+
   NullabilitySuffix get _noneOrStarSuffix {
     return isNonNullableByDefault
         ? NullabilitySuffix.none
@@ -66,6 +75,7 @@
   /// The client must set [nameScope] before calling [resolveTypeName].
   void resolveTypeName(TypeNameImpl node) {
     rewriteResult = null;
+    hasErrorReported = false;
 
     var typeIdentifier = node.name;
     if (typeIdentifier is PrefixedIdentifierImpl) {
@@ -136,7 +146,7 @@
 
     return List.generate(
       parameterCount,
-      (i) => arguments[i].type!,
+      (i) => arguments[i].typeOrThrow,
     );
   }
 
@@ -167,6 +177,7 @@
           declaredReturnType: element.thisType,
           argumentTypes: const [],
           contextReturnType: enclosingClass!.thisType,
+          genericMetadataIsEnabled: _genericMetadataIsEnabled,
         )!;
         return element.instantiate(
           typeArguments: typeArguments,
@@ -380,11 +391,50 @@
     TypeAliasElement element,
     DartType type,
   ) {
+    // If a type alias that expands to a type parameter.
     if (element.aliasedType is TypeParameterType) {
-      var constructorName = node.parent;
-      if (constructorName is ConstructorName) {
-        _ErrorHelper(errorReporter)
-            .reportTypeAliasExpandsToTypeParameter(constructorName, element);
+      var parent = node.parent;
+      if (parent is ConstructorName) {
+        var errorNode = _ErrorHelper._getErrorNode(node);
+        var constructorUsage = parent.parent;
+        if (constructorUsage is InstanceCreationExpression) {
+          errorReporter.reportErrorForNode(
+            CompileTimeErrorCode
+                .INSTANTIATE_TYPE_ALIAS_EXPANDS_TO_TYPE_PARAMETER,
+            errorNode,
+          );
+        } else if (constructorUsage is ConstructorDeclaration &&
+            constructorUsage.redirectedConstructor == parent) {
+          errorReporter.reportErrorForNode(
+            CompileTimeErrorCode
+                .REDIRECT_TO_TYPE_ALIAS_EXPANDS_TO_TYPE_PARAMETER,
+            errorNode,
+          );
+        } else {
+          throw UnimplementedError('${constructorUsage.runtimeType}');
+        }
+        return dynamicType;
+      }
+
+      // Report if this type is used as a class in hierarchy.
+      ErrorCode? errorCode;
+      if (parent is ExtendsClause) {
+        errorCode =
+            CompileTimeErrorCode.EXTENDS_TYPE_ALIAS_EXPANDS_TO_TYPE_PARAMETER;
+      } else if (parent is ImplementsClause) {
+        errorCode = CompileTimeErrorCode
+            .IMPLEMENTS_TYPE_ALIAS_EXPANDS_TO_TYPE_PARAMETER;
+      } else if (parent is OnClause) {
+        errorCode =
+            CompileTimeErrorCode.MIXIN_ON_TYPE_ALIAS_EXPANDS_TO_TYPE_PARAMETER;
+      } else if (parent is WithClause) {
+        errorCode =
+            CompileTimeErrorCode.MIXIN_OF_TYPE_ALIAS_EXPANDS_TO_TYPE_PARAMETER;
+      }
+      if (errorCode != null) {
+        var errorNode = _ErrorHelper._getErrorNode(node);
+        errorReporter.reportErrorForNode(errorCode, errorNode);
+        hasErrorReported = true;
         return dynamicType;
       }
     }
@@ -544,28 +594,6 @@
     );
   }
 
-  void reportTypeAliasExpandsToTypeParameter(
-    ConstructorName constructorName,
-    TypeAliasElement element,
-  ) {
-    var errorNode = _getErrorNode(constructorName.type);
-    var constructorUsage = constructorName.parent;
-    if (constructorUsage is InstanceCreationExpression) {
-      errorReporter.reportErrorForNode(
-        CompileTimeErrorCode.INSTANTIATE_TYPE_ALIAS_EXPANDS_TO_TYPE_PARAMETER,
-        errorNode,
-      );
-    } else if (constructorUsage is ConstructorDeclaration &&
-        constructorUsage.redirectedConstructor == constructorName) {
-      errorReporter.reportErrorForNode(
-        CompileTimeErrorCode.REDIRECT_TO_TYPE_ALIAS_EXPANDS_TO_TYPE_PARAMETER,
-        errorNode,
-      );
-    } else {
-      throw UnimplementedError('${constructorUsage.runtimeType}');
-    }
-  }
-
   /// Returns the simple identifier of the given (maybe prefixed) identifier.
   static Identifier _getErrorNode(TypeName node) {
     Identifier identifier = node.name;
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 b189618..cff8b7e 100644
--- a/pkg/analyzer/lib/src/dart/resolver/type_property_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/type_property_resolver.dart
@@ -54,15 +54,15 @@
   ///
   /// The [receiver] might be `null`, used to identify `super`.
   ///
-  /// The [receiverErrorNode] is the node to report nullable dereference,
+  /// The [propertyErrorNode] is the node to report nullable dereference,
   /// if the [receiverType] is potentially nullable.
   ///
-  /// The [nameErrorEntity] is used to report the ambiguous extension issue.
+  /// The [nameErrorEntity] is used to report an ambiguous extension issue.
   ResolutionResult resolve({
     required Expression? receiver,
     required DartType receiverType,
     required String name,
-    required AstNode receiverErrorNode,
+    required SyntacticEntity propertyErrorEntity,
     required SyntacticEntity nameErrorEntity,
   }) {
     _receiver = receiver;
@@ -91,7 +91,17 @@
         return _toResult();
       }
 
-      var parentExpression = (receiver ?? receiverErrorNode).parent;
+      AstNode? parentExpression;
+      if (receiver != null) {
+        parentExpression = receiver.parent;
+      } else if (propertyErrorEntity is AstNode) {
+        parentExpression = propertyErrorEntity.parent;
+      } else {
+        throw StateError('Either `receiver` must be non-null or'
+            '`propertyErrorEntity` must be an AstNode to report an unchecked '
+            'invocation of a nullable value.');
+      }
+
       CompileTimeErrorCode errorCode;
       if (parentExpression == null) {
         errorCode = CompileTimeErrorCode.UNCHECKED_INVOCATION_OF_NULLABLE_VALUE;
@@ -120,17 +130,17 @@
       if (flow != null) {
         if (receiver != null) {
           messages = _resolver.computeWhyNotPromotedMessages(
-              receiver, nameErrorEntity, flow.whyNotPromoted(receiver));
+              receiver, nameErrorEntity, flow.whyNotPromoted(receiver)());
         } else {
           var thisType = _resolver.thisType;
           if (thisType != null) {
             messages = _resolver.computeWhyNotPromotedMessages(receiver,
-                nameErrorEntity, flow.whyNotPromotedImplicitThis(thisType));
+                nameErrorEntity, flow.whyNotPromotedImplicitThis(thisType)());
           }
         }
       }
       _resolver.nullableDereferenceVerifier.report(
-          receiverErrorNode, receiverType,
+          propertyErrorEntity, receiverType,
           errorCode: errorCode, arguments: [name], messages: messages);
       _reportedGetterError = true;
       _reportedSetterError = true;
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 8e659b2..ee009b4 100644
--- a/pkg/analyzer/lib/src/dart/resolver/typed_literal_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/typed_literal_resolver.dart
@@ -64,6 +64,9 @@
 
   DynamicTypeImpl get _dynamicType => DynamicTypeImpl.instance;
 
+  bool get _genericMetadataIsEnabled =>
+      _resolver.definingLibrary.featureSet.isEnabled(Feature.generic_metadata);
+
   NullabilitySuffix get _noneOrStarSuffix {
     return _isNonNullableByDefault
         ? NullabilitySuffix.none
@@ -76,7 +79,7 @@
     var typeArguments = node.typeArguments?.arguments;
     if (typeArguments != null) {
       if (typeArguments.length == 1) {
-        DartType elementType = typeArguments[0].type!;
+        DartType elementType = typeArguments[0].typeOrThrow;
         if (!elementType.isDynamic) {
           listType = _typeProvider.listType(elementType);
         }
@@ -106,7 +109,7 @@
     var literalResolution = _computeSetOrMapResolution(node);
     if (literalResolution.kind == _LiteralResolutionKind.set) {
       if (typeArguments != null && typeArguments.length == 1) {
-        var elementType = typeArguments[0].type!;
+        var elementType = typeArguments[0].typeOrThrow;
         literalType = _typeProvider.setType(elementType);
       } else {
         literalType =
@@ -114,8 +117,8 @@
       }
     } else if (literalResolution.kind == _LiteralResolutionKind.map) {
       if (typeArguments != null && typeArguments.length == 2) {
-        var keyType = typeArguments[0].type!;
-        var valueType = typeArguments[1].type!;
+        var keyType = typeArguments[0].typeOrThrow;
+        var valueType = typeArguments[1].typeOrThrow;
         literalType = _typeProvider.mapType(keyType, valueType);
       } else {
         literalType =
@@ -310,10 +313,12 @@
     if (arguments != null) {
       if (arguments.length == 1) {
         return _LiteralResolution(_LiteralResolutionKind.set,
-            _typeProvider.setType(arguments[0].type!));
+            _typeProvider.setType(arguments[0].typeOrThrow));
       } else if (arguments.length == 2) {
-        return _LiteralResolution(_LiteralResolutionKind.map,
-            _typeProvider.mapType(arguments[0].type!, arguments[1].type!));
+        return _LiteralResolution(
+            _LiteralResolutionKind.map,
+            _typeProvider.mapType(
+                arguments[0].typeOrThrow, arguments[1].typeOrThrow));
       }
     }
     return _LiteralResolution(_LiteralResolutionKind.ambiguous, null);
@@ -460,6 +465,7 @@
       isConst: node.isConst,
       errorReporter: _errorReporter,
       errorNode: node,
+      genericMetadataIsEnabled: _genericMetadataIsEnabled,
     )!;
     return element.instantiate(
       typeArguments: typeArguments,
@@ -484,6 +490,7 @@
       isConst: node.isConst,
       errorReporter: _errorReporter,
       errorNode: node,
+      genericMetadataIsEnabled: _genericMetadataIsEnabled,
     )!;
     return element.instantiate(
       typeArguments: typeArguments,
@@ -582,6 +589,7 @@
       isConst: node.isConst,
       errorReporter: _errorReporter,
       errorNode: node,
+      genericMetadataIsEnabled: _genericMetadataIsEnabled,
     )!;
     return element.instantiate(
       typeArguments: typeArguments,
@@ -663,7 +671,7 @@
     if (typeArguments != null) {
       DartType elementType = _dynamicType;
       if (typeArguments.length == 1) {
-        elementType = typeArguments[0].type!;
+        elementType = typeArguments[0].typeOrThrow;
       }
       _recordStaticType(
         node,
@@ -700,7 +708,7 @@
     if (typeArguments != null) {
       if (typeArguments.length == 1) {
         node.becomeSet();
-        var elementType = typeArguments[0].type!;
+        var elementType = typeArguments[0].typeOrThrow;
         _recordStaticType(
           node,
           _typeProvider.setElement.instantiate(
@@ -711,8 +719,8 @@
         return;
       } else if (typeArguments.length == 2) {
         node.becomeMap();
-        var keyType = typeArguments[0].type!;
-        var valueType = typeArguments[1].type!;
+        var keyType = typeArguments[0].typeOrThrow;
+        var valueType = typeArguments[1].typeOrThrow;
         _recordStaticType(
           node,
           _typeProvider.mapElement.instantiate(
@@ -782,6 +790,7 @@
       declaredReturnType: element.thisType,
       argumentTypes: argumentTypes,
       contextReturnType: contextType,
+      genericMetadataIsEnabled: _genericMetadataIsEnabled,
     )!;
     return element.instantiate(
       typeArguments: typeArguments,
@@ -813,6 +822,7 @@
       declaredReturnType: element.thisType,
       argumentTypes: argumentTypes,
       contextReturnType: contextType,
+      genericMetadataIsEnabled: _genericMetadataIsEnabled,
     )!;
     return element.instantiate(
       typeArguments: typeArguments,
diff --git a/pkg/analyzer/lib/src/dart/resolver/variable_declaration_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/variable_declaration_resolver.dart
index 01fbab4..1dc6a6b 100644
--- a/pkg/analyzer/lib/src/dart/resolver/variable_declaration_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/variable_declaration_resolver.dart
@@ -52,10 +52,12 @@
     }
 
     initializer.accept(_resolver);
-    initializer = node.initializer;
+    initializer = node.initializer!;
+    var whyNotPromoted =
+        _resolver.flowAnalysis?.flow?.whyNotPromoted(initializer);
 
     if (parent.type == null) {
-      _setInferredType(element, initializer!.typeOrThrow);
+      _setInferredType(element, initializer.typeOrThrow);
     }
 
     if (isTopLevel) {
@@ -72,6 +74,8 @@
       (element as ConstVariableElement).constantInitializer =
           ConstantAstCloner().cloneNullableNode(initializer);
     }
+    _resolver.checkForInvalidAssignment(node.name, initializer,
+        whyNotPromoted: whyNotPromoted);
   }
 
   void _setInferredType(VariableElement element, DartType initializerType) {
diff --git a/pkg/analyzer/lib/src/dart/resolver/yield_statement_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/yield_statement_resolver.dart
index c241eb0..4238870 100644
--- a/pkg/analyzer/lib/src/dart/resolver/yield_statement_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/yield_statement_resolver.dart
@@ -3,13 +3,13 @@
 // 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/dart/element/type_provider.dart';
 import 'package:analyzer/error/listener.dart';
 import 'package:analyzer/src/dart/ast/extensions.dart';
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/type_system.dart';
+import 'package:analyzer/src/dart/resolver/body_inference_context.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 
@@ -21,8 +21,6 @@
     required ResolverVisitor resolver,
   }) : _resolver = resolver;
 
-  ExecutableElement get _enclosingFunction => _resolver.enclosingFunction!;
-
   ErrorReporter get _errorReporter => _resolver.errorReporter;
 
   TypeProvider get _typeProvider => _resolver.typeProvider;
@@ -30,8 +28,9 @@
   TypeSystemImpl get _typeSystem => _resolver.typeSystem;
 
   void resolve(YieldStatement node) {
-    if (_enclosingFunction.isGenerator) {
-      _resolve_generator(node);
+    var bodyContext = _resolver.inferenceContext.bodyContext;
+    if (bodyContext != null && bodyContext.isGenerator) {
+      _resolve_generator(bodyContext, node);
     } else {
       _resolve_notGenerator(node);
     }
@@ -69,26 +68,30 @@
   /// return type of a generator function.
   ///
   /// This method should only be called in generator functions.
-  void _checkForYieldOfInvalidType(YieldStatement node, bool isYieldEach) {
-    var declaredReturnType = _enclosingFunction.returnType;
-
+  void _checkForYieldOfInvalidType(
+    BodyInferenceContext bodyContext,
+    YieldStatement node,
+    bool isYieldEach,
+  ) {
     var expression = node.expression;
     var expressionType = expression.typeOrThrow;
 
     DartType impliedReturnType;
     if (isYieldEach) {
       impliedReturnType = expressionType;
-    } else if (_enclosingFunction.isSynchronous) {
+    } else if (bodyContext.isSynchronous) {
       impliedReturnType = _typeProvider.iterableType(expressionType);
     } else {
       impliedReturnType = _typeProvider.streamType(expressionType);
     }
 
-    if (!_typeSystem.isAssignableTo(impliedReturnType, declaredReturnType)) {
+    var imposedReturnType = bodyContext.imposedType;
+    if (imposedReturnType != null &&
+        !_typeSystem.isAssignableTo(impliedReturnType, imposedReturnType)) {
       _errorReporter.reportErrorForNode(
         CompileTimeErrorCode.YIELD_OF_INVALID_TYPE,
         expression,
-        [impliedReturnType, declaredReturnType],
+        [impliedReturnType, imposedReturnType],
       );
       return;
     }
@@ -98,7 +101,7 @@
       // also check that the implied return type is assignable to generic
       // Iterable/Stream.
       DartType requiredReturnType;
-      if (_enclosingFunction.isSynchronous) {
+      if (bodyContext.isSynchronous) {
         requiredReturnType = _typeProvider.iterableDynamicType;
       } else {
         requiredReturnType = _typeProvider.streamDynamicType;
@@ -114,21 +117,11 @@
     }
   }
 
-  void _computeElementType(YieldStatement node) {
-    var elementType = _resolver.inferenceContext.bodyContext?.contextType;
-    if (elementType != null) {
-      var contextType = elementType;
-      if (node.star != null) {
-        contextType = _enclosingFunction.isSynchronous
-            ? _typeProvider.iterableType(elementType)
-            : _typeProvider.streamType(elementType);
-      }
-      InferenceContext.setType(node.expression, contextType);
-    }
-  }
-
-  void _resolve_generator(YieldStatement node) {
-    _computeElementType(node);
+  void _resolve_generator(
+    BodyInferenceContext bodyContext,
+    YieldStatement node,
+  ) {
+    _setContextType(bodyContext, node);
 
     node.expression.accept(_resolver);
 
@@ -138,9 +131,9 @@
               .UNCHECKED_USE_OF_NULLABLE_VALUE_IN_YIELD_EACH);
     }
 
-    _resolver.inferenceContext.bodyContext?.addYield(node);
+    bodyContext.addYield(node);
 
-    _checkForYieldOfInvalidType(node, node.star != null);
+    _checkForYieldOfInvalidType(bodyContext, node, node.star != null);
     _checkForUseOfVoidResult(node.expression);
   }
 
@@ -156,4 +149,20 @@
 
     _checkForUseOfVoidResult(node.expression);
   }
+
+  void _setContextType(
+    BodyInferenceContext bodyContext,
+    YieldStatement node,
+  ) {
+    var elementType = bodyContext.contextType;
+    if (elementType != null) {
+      var contextType = elementType;
+      if (node.star != null) {
+        contextType = bodyContext.isSynchronous
+            ? _typeProvider.iterableType(elementType)
+            : _typeProvider.streamType(elementType);
+      }
+      InferenceContext.setType(node.expression, contextType);
+    }
+  }
 }
diff --git a/pkg/analyzer/lib/src/diagnostic/diagnostic_factory.dart b/pkg/analyzer/lib/src/diagnostic/diagnostic_factory.dart
index 45533a1..d76f15c5 100644
--- a/pkg/analyzer/lib/src/diagnostic/diagnostic_factory.dart
+++ b/pkg/analyzer/lib/src/diagnostic/diagnostic_factory.dart
@@ -76,13 +76,10 @@
     List<DiagnosticMessage>? contextMessages;
     int declarationOffset = staticElement.nameOffset;
     if (declarationOffset >= 0) {
-      CompilationUnitElement unit = staticElement.thisOrAncestorOfType()!;
-      var location = unit.lineInfo!.getLocation(declarationOffset);
       contextMessages = [
         DiagnosticMessageImpl(
             filePath: source.fullName,
-            message:
-                "The declaration of '$name' is on line ${location.lineNumber}.",
+            message: "The declaration of '$name' is here.",
             offset: declarationOffset,
             length: staticElement.nameLength)
       ];
diff --git a/pkg/analyzer/lib/src/error/best_practices_verifier.dart b/pkg/analyzer/lib/src/error/best_practices_verifier.dart
index e68cf25..c2c568d 100644
--- a/pkg/analyzer/lib/src/error/best_practices_verifier.dart
+++ b/pkg/analyzer/lib/src/error/best_practices_verifier.dart
@@ -689,6 +689,23 @@
     }
   }
 
+  @override
+  void visitTypeName(TypeName node) {
+    if (node.question != null) {
+      var name = node.name.name;
+      var type = node.typeOrThrow;
+      // Only report non-aliased, non-user-defined `Null?` and `dynamic?`. Do
+      // not report synthetic `dynamic` in place of an unresolved type.
+      if ((type.element == _nullType.element ||
+              (type.isDynamic && name == 'dynamic')) &&
+          type.aliasElement == null) {
+        _errorReporter.reportErrorForNode(
+            HintCode.UNNECESSARY_QUESTION_MARK, node, [name]);
+      }
+    }
+    super.visitTypeName(node);
+  }
+
   /// Check for the passed is expression for the unnecessary type check hint
   /// codes as well as null checks expressed using an is expression.
   ///
@@ -1207,7 +1224,7 @@
       return;
     }
 
-    if (_typeSystem.isPotentiallyNullable(type.type!)) {
+    if (_typeSystem.isPotentiallyNullable(type.typeOrThrow)) {
       _errorReporter.reportErrorForNode(
         HintCode.NULLABLE_TYPE_IN_CATCH_CLAUSE,
         type,
@@ -1596,7 +1613,7 @@
   /// on [node].  See [HintCode.UNNECESSARY_CAST].
   static bool isUnnecessaryCast(AsExpression node, TypeSystemImpl typeSystem) {
     var leftType = node.expression.typeOrThrow;
-    var rightType = node.type.type!;
+    var rightType = node.type.typeOrThrow;
 
     // `dynamicValue as SomeType` is a valid use case.
     if (leftType.isDynamic) {
diff --git a/pkg/analyzer/lib/src/error/bool_expression_verifier.dart b/pkg/analyzer/lib/src/error/bool_expression_verifier.dart
index 79d5369..43d2462 100644
--- a/pkg/analyzer/lib/src/error/bool_expression_verifier.dart
+++ b/pkg/analyzer/lib/src/error/bool_expression_verifier.dart
@@ -2,55 +2,62 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'package:_fe_analyzer_shared/src/flow_analysis/flow_analysis.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/error/error.dart';
 import 'package:analyzer/error/listener.dart';
 import 'package:analyzer/src/dart/ast/extensions.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/error/nullable_dereference_verifier.dart';
+import 'package:analyzer/src/generated/resolver.dart';
 
 /// Helper for verifying expression that should be of type bool.
 class BoolExpressionVerifier {
-  final TypeSystemImpl _typeSystem;
+  final ResolverVisitor _resolver;
   final ErrorReporter _errorReporter;
   final NullableDereferenceVerifier _nullableDereferenceVerifier;
 
   final InterfaceType _boolType;
 
   BoolExpressionVerifier({
-    required TypeSystemImpl typeSystem,
+    required ResolverVisitor resolver,
     required ErrorReporter errorReporter,
     required NullableDereferenceVerifier nullableDereferenceVerifier,
-  })   : _typeSystem = typeSystem,
+  })   : _resolver = resolver,
         _errorReporter = errorReporter,
         _nullableDereferenceVerifier = nullableDereferenceVerifier,
-        _boolType = typeSystem.typeProvider.boolType;
+        _boolType = resolver.typeSystem.typeProvider.boolType;
 
   /// Check to ensure that the [condition] is of type bool, are. Otherwise an
   /// error is reported on the expression.
   ///
   /// See [CompileTimeErrorCode.NON_BOOL_CONDITION].
-  void checkForNonBoolCondition(Expression condition) {
+  void checkForNonBoolCondition(Expression condition,
+      {required Map<DartType, NonPromotionReason> Function()? whyNotPromoted}) {
     checkForNonBoolExpression(
       condition,
       errorCode: CompileTimeErrorCode.NON_BOOL_CONDITION,
+      whyNotPromoted: whyNotPromoted,
     );
   }
 
   /// Verify that the given [expression] is of type 'bool', and report
   /// [errorCode] if not, or a nullability error if its improperly nullable.
   void checkForNonBoolExpression(Expression expression,
-      {required ErrorCode errorCode, List<Object>? arguments}) {
+      {required ErrorCode errorCode,
+      List<Object>? arguments,
+      required Map<DartType, NonPromotionReason> Function()? whyNotPromoted}) {
     var type = expression.typeOrThrow;
     if (!_checkForUseOfVoidResult(expression) &&
-        !_typeSystem.isAssignableTo(type, _boolType)) {
+        !_resolver.typeSystem.isAssignableTo(type, _boolType)) {
       if (type.isDartCoreBool) {
         _nullableDereferenceVerifier.report(expression, type,
             errorCode: CompileTimeErrorCode
-                .UNCHECKED_USE_OF_NULLABLE_VALUE_AS_CONDITION);
+                .UNCHECKED_USE_OF_NULLABLE_VALUE_AS_CONDITION,
+            messages: _resolver.computeWhyNotPromotedMessages(
+                expression, expression, whyNotPromoted?.call()));
       } else {
         _errorReporter.reportErrorForNode(errorCode, expression, arguments);
       }
@@ -58,10 +65,12 @@
   }
 
   /// Checks to ensure that the given [expression] is assignable to bool.
-  void checkForNonBoolNegationExpression(Expression expression) {
+  void checkForNonBoolNegationExpression(Expression expression,
+      {required Map<DartType, NonPromotionReason> Function()? whyNotPromoted}) {
     checkForNonBoolExpression(
       expression,
       errorCode: CompileTimeErrorCode.NON_BOOL_NEGATION_EXPRESSION,
+      whyNotPromoted: whyNotPromoted,
     );
   }
 
diff --git a/pkg/analyzer/lib/src/error/codes.dart b/pkg/analyzer/lib/src/error/codes.dart
index 92d84fd..58fcf57 100644
--- a/pkg/analyzer/lib/src/error/codes.dart
+++ b/pkg/analyzer/lib/src/error/codes.dart
@@ -1629,20 +1629,46 @@
       'COULD_NOT_INFER', "Couldn't infer type parameter '{0}'.{1}");
 
   /**
-   * 10.10 Superinterfaces: It is a compile-time error if a class `C` has two
-   * superinterfaces that are different instantiations of the same generic
-   * class. For example, a class may not have both `List<int>` and `List<num>`
-   * as superinterfaces.
-   *
    * Parameters:
    * 0: the name of the class implementing the conflicting interface
    * 1: the first conflicting type
    * 2: the second conflicting type
    */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when a class attempts to implement a
+  // generic interface multiple times, and the values of the type arguments
+  // aren't the same.
+  //
+  // #### Example
+  //
+  // The following code produces this diagnostic because `C` is defined to
+  // implement both `I<int>` (because it extends `A`) and `I<String>` (because
+  // it implements`B`), but `int` and `String` aren't the same type:
+  //
+  // ```dart
+  // class I<T> {}
+  // class A implements I<int> {}
+  // class B implements I<String> {}
+  // [!class C extends A implements B {}!]
+  // ```
+  //
+  // #### Common fixes
+  //
+  // Rework the type hierarchy to avoid this situation. For example, you might
+  // make one or both of the inherited types generic so that `C` can specify the
+  // same type for both type arguments:
+  //
+  // ```dart
+  // class I<T> {}
+  // class A<S> implements I<S> {}
+  // class B implements I<String> {}
+  // class C extends A<String> implements B {}
+  // ```
   static const CompileTimeErrorCode CONFLICTING_GENERIC_INTERFACES =
       CompileTimeErrorCode(
           'CONFLICTING_GENERIC_INTERFACES',
-          "The class '{0}' cannot implement both '{1}' and '{2}' because the "
+          "The class '{0}' can't implement both '{1}' and '{2}' because the "
               "type arguments are different.");
 
   /**
@@ -1924,21 +1950,83 @@
   );
 
   /**
-   * 7.6.3 Constant Constructors: The superinitializer that appears, explicitly
-   * or implicitly, in the initializer list of a constant constructor must
-   * specify a constant constructor of the superclass of the immediately
-   * enclosing class or a compile-time error occurs.
-   *
    * Parameters:
    * 0: the name of the superclass
    */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when a constructor that is marked as
+  // `const` invokes a constructor from its superclass that isn't marked as
+  // `const`.
+  //
+  // #### Example
+  //
+  // The following code produces this diagnostic because the `const` constructor
+  // in `B` invokes the constructor `nonConst` from the class `A`, and the
+  // superclass constructor isn't a `const` constructor:
+  //
+  // ```dart
+  // class A {
+  //   const A();
+  //   A.nonConst();
+  // }
+  //
+  // class B extends A {
+  //   const B() : [!super.nonConst()!];
+  // }
+  // ```
+  //
+  // #### Common fixes
+  //
+  // If it isn't essential to invoke the superclass constructor that is
+  // currently being invoked, then invoke a constant constructor from the
+  // superclass:
+  //
+  // ```dart
+  // class A {
+  //   const A();
+  //   A.nonConst();
+  // }
+  //
+  // class B extends A {
+  //   const B() : super();
+  // }
+  // ```
+  //
+  // If it's essential that the current constructor be invoked and if you can
+  // modify it, then add `const` to the constructor in the superclass:
+  //
+  // ```dart
+  // class A {
+  //   const A();
+  //   const A.nonConst();
+  // }
+  //
+  // class B extends A {
+  //   const B() : super.nonConst();
+  // }
+  // ```
+  //
+  // If it's essential that the current constructor be invoked and you can't
+  // modify it, then remove `const` from the constructor in the subclass:
+  //
+  // ```dart
+  // class A {
+  //   const A();
+  //   A.nonConst();
+  // }
+  //
+  // class B extends A {
+  //   B() : super.nonConst();
+  // }
+  // ```
   static const CompileTimeErrorCode CONST_CONSTRUCTOR_WITH_NON_CONST_SUPER =
       CompileTimeErrorCode(
           'CONST_CONSTRUCTOR_WITH_NON_CONST_SUPER',
-          "Constant constructor can't call non-constant super constructor of "
-              "'{0}'.",
-          correction: "Try calling a const constructor in the superclass, or "
-              "removing the keyword 'const' from the constructor.");
+          "A constant constructor can't call a non-constant super constructor "
+              "of '{0}'.",
+          correction: "Try calling a constant constructor in the superclass, "
+              "or removing the keyword 'const' from the constructor.");
 
   /**
    * No parameters.
@@ -1992,8 +2080,48 @@
           hasPublishedDocs: true);
 
   /**
-   * 12.12.2 Const: It is a compile-time error if <i>T</i> is a deferred type.
+   * No parameters.
    */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when a class from a library that is
+  // imported using a deferred import is used to create a `const` object.
+  // Constants are evaluated at compile time, and classes from deferred
+  // libraries aren't available at compile time.
+  //
+  // For more information, see the language tour's coverage of
+  // [deferred loading](https://dart.dev/guides/language/language-tour#lazily-loading-a-library).
+  //
+  // #### Example
+  //
+  // The following code produces this diagnostic because it attempts to create a
+  // `const` instance of a class from a deferred library:
+  //
+  // ```dart
+  // import 'dart:convert' deferred as convert;
+  //
+  // const json2 = [!convert.JsonCodec()!];
+  // ```
+  //
+  // #### Common fixes
+  //
+  // If the object isn't required to be a constant, then change the code so that
+  // a non-constant instance is created:
+  //
+  // ```dart
+  // import 'dart:convert' deferred as convert;
+  //
+  // final json2 = convert.JsonCodec();
+  // ```
+  //
+  // If the object must be a constant, then remove `deferred` from the import
+  // directive:
+  //
+  // ```dart
+  // import 'dart:convert' as convert;
+  //
+  // const json2 = convert.JsonCodec();
+  // ```
   static const CompileTimeErrorCode CONST_DEFERRED_CLASS = CompileTimeErrorCode(
       'CONST_DEFERRED_CLASS', "Deferred classes can't be created with 'const'.",
       correction: "Try using 'new' to create the instance, or "
@@ -2134,18 +2262,53 @@
           hasPublishedDocs: true);
 
   /**
-   * 5 Variables: A constant variable must be initialized to a compile-time
-   * constant or a compile-time error occurs.
-   *
-   * 12.1 Constants: A qualified reference to a static constant variable that is
-   * not qualified by a deferred prefix.
+   * No parameters.
    */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when a `const` variable is
+  // initialized using a `const` variable from a library that is imported using
+  // a deferred import. Constants are evaluated at compile time, and values from
+  // deferred libraries aren't available at compile time.
+  //
+  // For more information, see the language tour's coverage of
+  // [deferred loading](https://dart.dev/guides/language/language-tour#lazily-loading-a-library).
+  //
+  // #### Example
+  //
+  // The following code produces this diagnostic because the variable `pi` is
+  // being initialized using the constant `math.pi` from the library
+  // `dart:math`, and `dart:math` is imported as a deferred library:
+  //
+  // ```dart
+  // import 'dart:math' deferred as math;
+  //
+  // const pi = [!math.pi!];
+  // ```
+  //
+  // #### Common fixes
+  //
+  // If you need to reference the value of the constant from the imported
+  // library, then remove the keyword `deferred`:
+  //
+  // ```dart
+  // import 'dart:math' as math;
+  //
+  // const pi = math.pi;
+  // ```
+  //
+  // If you don't need to reference the imported constant, then remove the
+  // reference:
+  //
+  // ```dart
+  // const pi = 3.14;
+  // ```
   static const CompileTimeErrorCode
       CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE_FROM_DEFERRED_LIBRARY =
       CompileTimeErrorCode(
           'CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE_FROM_DEFERRED_LIBRARY',
-          "Constant values from a deferred library can't be used to "
-              "initialized a const variable.",
+          "Constant values from a deferred library can't be used to initialize "
+              "a 'const' variable.",
           correction:
               "Try initializing the variable without referencing members of "
               "the deferred library, or changing the import to not be "
@@ -2195,18 +2358,62 @@
       hasPublishedDocs: true);
 
   /**
-   * 12.8 Maps: It is a compile-time error if the key of an entry in a constant
-   * map literal is an instance of a class that implements the operator
-   * <i>==</i> unless the key is a string or integer.
-   *
    * Parameters:
    * 0: the type of the entry's key
    */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when the class of object used as a
+  // key in a constant map literal implements the `==` operator. The
+  // implementation of constant maps uses the `==` operator, so any
+  // implementation other than the one inherited from `Object` requires
+  // executing arbitrary code at compile time, which isn't supported.
+  //
+  // #### Example
+  //
+  // The following code produces this diagnostic because the constant map
+  // contains a key whose type is `C`, and the class `C` overrides the
+  // implementation of `==`:
+  //
+  // ```dart
+  // class C {
+  //   const C();
+  //
+  //   bool operator ==(Object other) => true;
+  // }
+  //
+  // const map = {[!C()!] : 0};
+  // ```
+  //
+  // #### Common fixes
+  //
+  // If you can remove the implementation of `==` from the class, then do so:
+  //
+  // ```dart
+  // class C {
+  //   const C();
+  // }
+  //
+  // const map = {C() : 0};
+  // ```
+  //
+  // If you can't remove the implementation of `==` from the class, then make
+  // the map be non-constant:
+  //
+  // ```dart
+  // class C {
+  //   const C();
+  //
+  //   bool operator ==(Object other) => true;
+  // }
+  //
+  // final map = {C() : 0};
+  // ```
   static const CompileTimeErrorCode
       CONST_MAP_KEY_EXPRESSION_TYPE_IMPLEMENTS_EQUALS = CompileTimeErrorCode(
           'CONST_MAP_KEY_EXPRESSION_TYPE_IMPLEMENTS_EQUALS',
-          "The constant map entry key expression type '{0}' can't override "
-              "the == operator.",
+          "The type of a key in a constant map can't override the '==' "
+              "operator, but the class '{0}' does.",
           correction: "Try using a different value for the key, or "
               "removing the keyword 'const' from the map.");
 
@@ -2244,11 +2451,59 @@
    * Parameters:
    * 0: the type of the element
    */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when the class of object used as an
+  // element in a constant set literal implements the `==` operator. The
+  // implementation of constant sets uses the `==` operator, so any
+  // implementation other than the one inherited from `Object` requires
+  // executing arbitrary code at compile time, which isn't supported.
+  //
+  // #### Example
+  //
+  // The following code produces this diagnostic because the constant set
+  // contains an element whose type is `C`, and the class `C` overrides the
+  // implementation of `==`:
+  //
+  // ```dart
+  // class C {
+  //   const C();
+  //
+  //   bool operator ==(Object other) => true;
+  // }
+  //
+  // const set = {[!C()!]};
+  // ```
+  //
+  // #### Common fixes
+  //
+  // If you can remove the implementation of `==` from the class, then do so:
+  //
+  // ```dart
+  // class C {
+  //   const C();
+  // }
+  //
+  // const set = {C()};
+  // ```
+  //
+  // If you can't remove the implementation of `==` from the class, then make
+  // the set be non-constant:
+  //
+  // ```dart
+  // class C {
+  //   const C();
+  //
+  //   bool operator ==(Object other) => true;
+  // }
+  //
+  // final set = {C()};
+  // ```
   static const CompileTimeErrorCode CONST_SET_ELEMENT_TYPE_IMPLEMENTS_EQUALS =
       CompileTimeErrorCode(
           'CONST_SET_ELEMENT_TYPE_IMPLEMENTS_EQUALS',
-          "The constant set element type '{0}' can't override "
-              "the == operator.",
+          "The type of an element in a constant set can't override the '==' "
+              "operator, but the type '{0}' does.",
           correction: "Try using a different value for the element, or "
               "removing the keyword 'const' from the set.");
 
@@ -2651,9 +2906,82 @@
   /**
    * No parameters.
    */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when a library that is imported using
+  // a deferred import declares an extension that is visible in the importing
+  // library. Extension methods are resolved at compile time, and extensions
+  // from deferred libraries aren't available at compile time.
+  //
+  // For more information, see the language tour's coverage of
+  // [deferred loading](https://dart.dev/guides/language/language-tour#lazily-loading-a-library).
+  //
+  // #### Example
+  //
+  // Given a file (`a.dart`) that defines a named extension:
+  //
+  // ```dart
+  // %uri="lib/a.dart"
+  // class C {}
+  //
+  // extension E on String {
+  //   int get size => length;
+  // }
+  // ```
+  //
+  // The following code produces this diagnostic because the named extension is
+  // visible to the library:
+  //
+  // ```dart
+  // import [!'a.dart'!] deferred as a;
+  //
+  // void f() {
+  //   a.C();
+  // }
+  // ```
+  //
+  // #### Common fixes
+  //
+  // If the library must be imported as `deferred`, then either add a `show`
+  // clause listing the names being referenced or add a `hide` clause listing
+  // all of the named extensions. Adding a `show` clause would look like this:
+  //
+  // ```dart
+  // import 'a.dart' deferred as a show C;
+  //
+  // void f() {
+  //   a.C();
+  // }
+  // ```
+  //
+  // Adding a `hide` clause would look like this:
+  //
+  // ```dart
+  // import 'a.dart' deferred as a hide E;
+  //
+  // void f() {
+  //   a.C();
+  // }
+  // ```
+  //
+  // With the first fix, the benefit is that if new extensions are added to the
+  // imported library, then the extensions won't cause a diagnostic to be
+  // generated.
+  //
+  // If the library doesn't need to be imported as `deferred`, or if you need to
+  // make use of the extension method declared in it, then remove the keyword
+  // `deferred`:
+  //
+  // ```dart
+  // import 'a.dart' as a;
+  //
+  // void f() {
+  //   a.C();
+  // }
+  // ```
   static const CompileTimeErrorCode DEFERRED_IMPORT_OF_EXTENSION =
       CompileTimeErrorCode('DEFERRED_IMPORT_OF_EXTENSION',
-          "Imports of deferred libraries must hide all extensions",
+          "Imports of deferred libraries must hide all extensions.",
           correction:
               "Try adding either a show combinator listing the names you need "
               "to reference or a hide combinator listing all of the "
@@ -3253,19 +3581,53 @@
       hasPublishedDocs: true);
 
   /**
-   * 7.9 Superclasses: It is a compile-time error if the extends clause of a
-   * class <i>C</i> includes a deferred type expression.
-   *
-   * Parameters:
-   * 0: the name of the type that cannot be extended
-   *
-   * See [IMPLEMENTS_DEFERRED_CLASS], and [MIXIN_DEFERRED_CLASS].
+   * No parameters.
    */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when a type (class or mixin) is a
+  // subtype of a class from a library being imported using a deferred import.
+  // The supertypes of a type must be compiled at the same time as the type, and
+  // classes from deferred libraries aren't compiled until the library is
+  // loaded.
+  //
+  // For more information, see the language tour's coverage of
+  // [deferred loading](https://dart.dev/guides/language/language-tour#lazily-loading-a-library).
+  //
+  // #### Example
+  //
+  // Given a file (`a.dart`) that defines the class `A`:
+  //
+  // ```dart
+  // %uri="lib/a.dart"
+  // class A {}
+  // ```
+  //
+  // The following code produces this diagnostic because the superclass of `B`
+  // is declared in a deferred library:
+  //
+  // ```dart
+  // import 'a.dart' deferred as a;
+  //
+  // class B extends [!a.A!] {}
+  // ```
+  //
+  // #### Common fixes
+  //
+  // If you need to create a subtype of a type from the deferred library, then
+  // remove the `deferred` keyword:
+  //
+  // ```dart
+  // import 'a.dart' as a;
+  //
+  // class B extends a.A {}
+  // ```
   static const CompileTimeErrorCode EXTENDS_DEFERRED_CLASS =
       CompileTimeErrorCode(
-          'EXTENDS_DEFERRED_CLASS', "Classes can't extend deferred classes.",
+          'SUBTYPE_OF_DEFERRED_CLASS', "Classes can't extend deferred classes.",
           correction: "Try specifying a different superclass, or "
-              "removing the extends clause.");
+              "removing the extends clause.",
+          uniqueName: 'EXTENDS_DEFERRED_CLASS');
 
   /**
    * Parameters:
@@ -3383,6 +3745,15 @@
       hasPublishedDocs: true,
       isUnresolvedIdentifier: true);
 
+  static const CompileTimeErrorCode
+      EXTENDS_TYPE_ALIAS_EXPANDS_TO_TYPE_PARAMETER = CompileTimeErrorCode(
+          'EXTENDS_TYPE_ALIAS_EXPANDS_TO_TYPE_PARAMETER',
+          "Type aliases that expand to a type parameter can't be used as "
+              "superclasses.",
+          correction:
+              "Try specifying a different superclass, or removing the extends "
+              "clause.");
+
   /**
    * Parameters:
    * 0: the name of the extension
@@ -4468,19 +4839,58 @@
   );
 
   /**
-   * 17.6.2 For-in. It the iterable expression does not implement Iterable with
-   * a type argument that can be assigned to the for-in variable's type, this
-   * warning is reported.
-   *
    * Parameters:
    * 0: The type of the iterable expression.
    * 1: The sequence type -- Iterable for `for` or Stream for `await for`.
    * 2: The loop variable type.
    */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when the `Iterable` or `Stream` in a
+  // for-in loop has an element type that can't be assigned to the loop
+  // variable.
+  //
+  // #### Example
+  //
+  // The following code produces this diagnostic because `<String>[]` has an
+  // element type of `String`, and `String` can't be assigned to the type of `e`
+  // (`int`):
+  //
+  // ```dart
+  // void f() {
+  //   for (int e in [!<String>[]!]) {
+  //     print(e);
+  //   }
+  // }
+  // ```
+  //
+  // #### Common fixes
+  //
+  // If the type of the loop variable is correct, then update the type of the
+  // iterable:
+  //
+  // ```dart
+  // void f() {
+  //   for (int e in <int>[]) {
+  //     print(e);
+  //   }
+  // }
+  // ```
+  //
+  // If the type of the iterable is correct, then update the type of the loop
+  // variable:
+  //
+  // ```dart
+  // void f() {
+  //   for (String e in <String>[]) {
+  //     print(e);
+  //   }
+  // }
+  // ```
   static const CompileTimeErrorCode FOR_IN_OF_INVALID_ELEMENT_TYPE =
       CompileTimeErrorCode(
           'FOR_IN_OF_INVALID_ELEMENT_TYPE',
-          "The type '{0}' used in the 'for' loop must implement {1} with a "
+          "The type '{0}' used in the 'for' loop must implement '{1}' with a "
               "type argument that can be assigned to '{2}'.");
 
   /**
@@ -4522,9 +4932,46 @@
           "The type '{0}' used in the 'for' loop must implement {1}.",
           hasPublishedDocs: true);
 
+  /**
+   * No parameters.
+   */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when the loop variable declared in a
+  // for-in loop is declared to be a `const`. The variable can't be a `const`
+  // because the value can't be computed at compile time.
+  //
+  // #### Example
+  //
+  // The following code produces this diagnostic because the loop variable `x`
+  // is declared to be a `const`:
+  //
+  // ```dart
+  // void f() {
+  //   for ([!const!] x in [0, 1, 2]) {
+  //     print(x);
+  //   }
+  // }
+  // ```
+  //
+  // #### Common fixes
+  //
+  // If there's a type annotation, then remove the `const` modifier from the
+  // declaration.
+  //
+  // If there's no type, then replace the `const` modifier with `final`, `var`,
+  // or a type annotation:
+  //
+  // ```dart
+  // void f() {
+  //   for (final x in [0, 1, 2]) {
+  //     print(x);
+  //   }
+  // }
+  // ```
   static const CompileTimeErrorCode FOR_IN_WITH_CONST_VARIABLE =
       CompileTimeErrorCode('FOR_IN_WITH_CONST_VARIABLE',
-          "A for-in loop-variable can't be 'const'.",
+          "A for-in loop variable can't be a 'const'.",
           correction: "Try removing the 'const' modifier from the variable, or "
               "use a different variable.");
 
@@ -4765,18 +5212,15 @@
           hasPublishedDocs: true);
 
   /**
-   * 7.10 Superinterfaces: It is a compile-time error if the implements clause
-   * of a class <i>C</i> specifies a malformed type or deferred type as a
-   * superinterface.
-   *
-   * See [EXTENDS_DEFERRED_CLASS], and [MIXIN_DEFERRED_CLASS].
+   * No parameters.
    */
   static const CompileTimeErrorCode IMPLEMENTS_DEFERRED_CLASS =
-      CompileTimeErrorCode('IMPLEMENTS_DEFERRED_CLASS',
+      CompileTimeErrorCode('SUBTYPE_OF_DEFERRED_CLASS',
           "Classes and mixins can't implement deferred classes.",
           correction: "Try specifying a different interface, "
               "removing the class from the list, or "
-              "changing the import to not be deferred.");
+              "changing the import to not be deferred.",
+          uniqueName: 'IMPLEMENTS_DEFERRED_CLASS');
 
   /**
    * Parameters:
@@ -4911,6 +5355,12 @@
           correction: "Try removing one of the occurrences.",
           hasPublishedDocs: true);
 
+  static const CompileTimeErrorCode
+      IMPLEMENTS_TYPE_ALIAS_EXPANDS_TO_TYPE_PARAMETER = CompileTimeErrorCode(
+          'IMPLEMENTS_TYPE_ALIAS_EXPANDS_TO_TYPE_PARAMETER',
+          "Type aliases that expand to a type parameter can't be implemented.",
+          correction: "Try specifying a class or mixin, or removing the list.");
+
   /**
    * Parameters:
    * 0: the name of the instance member
@@ -5474,9 +5924,37 @@
           hasPublishedDocs: true);
 
   /**
-   * Enum proposal: It is also a compile-time error to explicitly instantiate an
-   * enum via 'new' or 'const' or to access its private fields.
+   * No parameters.
    */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when an enum is instantiated. It's
+  // invalid to create an instance of an enum by invoking a constructor; only
+  // the instances named in the declaration of the enum can exist.
+  //
+  // #### Example
+  //
+  // The following code produces this diagnostic because the enum `E` is being
+  // instantiated:
+  //
+  // ```dart
+  // enum E {a}
+  //
+  // var e = [!E!]();
+  // ```
+  //
+  // #### Common fixes
+  //
+  // If you intend to use an instance of the enum, then reference one of the
+  // constants defined in the enum:
+  //
+  // ```dart
+  // enum E {a}
+  //
+  // var e = E.a;
+  // ```
+  //
+  // If you intend to use an instance of a class, then use the name of that class in place of the name of the enum.
   static const CompileTimeErrorCode INSTANTIATE_ENUM = CompileTimeErrorCode(
       'INSTANTIATE_ENUM', "Enums can't be instantiated.",
       correction: "Try using one of the defined constants.");
@@ -5620,14 +6098,50 @@
       hasPublishedDocs: true);
 
   /**
-   * 15 Metadata: Metadata consists of a series of annotations, each of which
-   * begin with the character @, followed by a constant expression that must be
-   * either a reference to a compile-time constant variable, or a call to a
-   * constant constructor.
-   *
-   * 12.1 Constants: A qualified reference to a static constant variable that is
-   * not qualified by a deferred prefix.
+   * No parameters.
    */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when a constant from a library that
+  // is imported using a deferred import is used as an annotation. Annotations
+  // are evaluated at compile time, and constants from deferred libraries aren't
+  // available at compile time.
+  //
+  // For more information, see the language tour's coverage of
+  // [deferred loading](https://dart.dev/guides/language/language-tour#lazily-loading-a-library).
+  //
+  // #### Example
+  //
+  // The following code produces this diagnostic because the constant `pi` is
+  // being used as an annotation when the library `dart:math` is imported as
+  // `deferred`:
+  //
+  // ```dart
+  // import 'dart:math' deferred as math;
+  //
+  // @[!math.pi!]
+  // void f() {}
+  // ```
+  //
+  // #### Common fixes
+  //
+  // If you need to reference the constant as an annotation, then remove the
+  // keyword `deferred` from the import:
+  //
+  // ```dart
+  // import 'dart:math' as math;
+  //
+  // @math.pi
+  // void f() {}
+  // ```
+  //
+  // If you can use a different constant as an annotation, then replace the
+  // annotation with a different constant:
+  //
+  // ```dart
+  // @deprecated
+  // void f() {}
+  // ```
   static const CompileTimeErrorCode INVALID_ANNOTATION_FROM_DEFERRED_LIBRARY =
       CompileTimeErrorCode(
           'INVALID_ANNOTATION_FROM_DEFERRED_LIBRARY',
@@ -5925,6 +6439,86 @@
    * These parameters must be kept in sync with those of
    * [CompileTimeErrorCode.INVALID_OVERRIDE].
    */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when all of the following are true:
+  //
+  // - A class defines an abstract member.
+  // - There is a concrete implementation of that member in a superclass.
+  // - The concrete implementation isn't a valid implementation of the abstract
+  //   method.
+  //
+  // The concrete implementation can be invalid because of incompatibilities in
+  // either the return type, the types of parameters, or the type variables.
+  //
+  // #### Example
+  //
+  // The following code produces this diagnostic because the method `A.add` has
+  // a parameter of type `int`, and the overriding method `B.add` has a
+  // corresponding parameter of type `num`:
+  //
+  // ```dart
+  // class A {
+  //   int add(int a) => a;
+  // }
+  // class [!B!] extends A {
+  //   int add(num a);
+  // }
+  // ```
+  //
+  // This is a problem because in an invocation of `B.add` like the following:
+  //
+  // ```dart
+  // void f(B b) {
+  //   b.add(3.4);
+  // }
+  // ```
+  //
+  // `B.add` is expecting to be able to take, for example, a `double`, but when
+  // the method `A.add` is executed (because it's the only concrete
+  // implementation of `add`), a runtime exception will be thrown because a
+  // `double` can't be assigned to a parameter of type `int`.
+  //
+  // #### Common fixes
+  //
+  // If the method in the subclass can conform to the implementation in the
+  // superclass, then change the declaration in the subclass (or remove it if
+  // it's the same):
+  //
+  // ```dart
+  // class A {
+  //   int add(int a) => a;
+  // }
+  // class B	extends A {
+  //   int add(int a);
+  // }
+  // ```
+  //
+  // If the method in the superclass can be generalized to be a valid
+  // implementation of the method in the subclass, then change the superclass
+  // method:
+  //
+  // ```dart
+  // class A {
+  //   int add(num a) => a.floor();
+  // }
+  // class B	extends A {
+  //   int add(num a);
+  // }
+  // ```
+  //
+  // If neither the method in the superclass nor the method in the subclass can
+  // be changed, then provide a concrete implementation of the method in the
+  // subclass:
+  //
+  // ```dart
+  // class A {
+  //   int add(int a) => a;
+  // }
+  // class B	extends A {
+  //   int add(num a) => a.floor();
+  // }
+  // ```
   static const CompileTimeErrorCode INVALID_IMPLEMENTATION_OVERRIDE =
       CompileTimeErrorCode(
           'INVALID_IMPLEMENTATION_OVERRIDE',
@@ -6260,7 +6854,7 @@
   // #### Description
   //
   // The analyzer produces this diagnostic when an expression whose value will
-  // always be `null` is dererenced.
+  // always be `null` is dereferenced.
   //
   // #### Example
   //
@@ -7013,9 +7607,21 @@
               "expression.",
           correction: "Try adding the keyword 'const' before the literal.");
 
+  /**
+   * No parameters.
+   */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when either the Dart or Flutter SDK
+  // isn’t installed correctly, and, as a result, one of the `dart:` libraries
+  // can't be found.
+  //
+  // #### Common fixes
+  //
+  // Reinstall the Dart or Flutter SDK.
   static const CompileTimeErrorCode MISSING_DART_LIBRARY = CompileTimeErrorCode(
       'MISSING_DART_LIBRARY', "Required library '{0}' is missing.",
-      correction: "Check your Dart SDK installation for completeness.");
+      correction: "Re-install the Dart or Flutter SDK.");
 
   /**
    * No parameters.
@@ -7139,13 +7745,76 @@
               "concrete member in the class has type '{2}'.");
 
   /**
-   * It's a compile-time error to apply a mixin containing super-invocations to
-   * a class that doesn't have a concrete implementation of the super-invoked
-   * members compatible with the super-constraint interface.
-   *
    * Parameters:
    * 0: the display name of the member without a concrete implementation
    */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when a [mixin application][] contains
+  // an invocation of a member from its superclass, and there's no concrete
+  // member of that name in the mixin application's superclass.
+  //
+  // #### Example
+  //
+  // The following code produces this diagnostic because the mixin `M` contains
+  // the invocation `super.m()`, and the class `A`, which is the superclass of
+  // the [mixin application][] `A+M`, doesn't define a concrete implementation
+  // of `m`:
+  //
+  // ```dart
+  // abstract class A {
+  //   void m();
+  // }
+  //
+  // mixin M on A {
+  //   void bar() {
+  //     super.m();
+  //   }
+  // }
+  //
+  // abstract class B extends A with [!M!] {}
+  // ```
+  //
+  // #### Common fixes
+  //
+  // If you intended to apply the mixin `M` to a different class, one that has a
+  // concrete implementation of `m`, then change the superclass of `B` to that
+  // class:
+  //
+  // ```dart
+  // abstract class A {
+  //   void m();
+  // }
+  //
+  // mixin M on A {
+  //   void bar() {
+  //     super.m();
+  //   }
+  // }
+  //
+  // class C implements A {
+  //   void m() {}
+  // }
+  //
+  // abstract class B extends C with M {}
+  // ```
+  //
+  // If you need to make `B` a subclass of `A`, then add a concrete
+  // implementation of `m` in `A`:
+  //
+  // ```dart
+  // abstract class A {
+  //   void m() {}
+  // }
+  //
+  // mixin M on A {
+  //   void bar() {
+  //     super.m();
+  //   }
+  // }
+  //
+  // abstract class B extends A with M {}
+  // ```
   static const CompileTimeErrorCode
       MIXIN_APPLICATION_NO_CONCRETE_SUPER_INVOKED_MEMBER = CompileTimeErrorCode(
           'MIXIN_APPLICATION_NO_CONCRETE_SUPER_INVOKED_MEMBER',
@@ -7190,17 +7859,12 @@
           'MIXIN_DECLARES_CONSTRUCTOR', "Mixins can't declare constructors.");
 
   /**
-   * 9.1 Mixin Application: It is a compile-time error if the with clause of a
-   * mixin application <i>C</i> includes a deferred type expression.
-   *
-   * Parameters:
-   * 0: the name of the type that cannot be extended
-   *
-   * See [EXTENDS_DEFERRED_CLASS], and [IMPLEMENTS_DEFERRED_CLASS].
+   * No parameters.
    */
   static const CompileTimeErrorCode MIXIN_DEFERRED_CLASS = CompileTimeErrorCode(
-      'MIXIN_DEFERRED_CLASS', "Classes can't mixin deferred classes.",
-      correction: "Try changing the import to not be deferred.");
+      'SUBTYPE_OF_DEFERRED_CLASS', "Classes can't mixin deferred classes.",
+      correction: "Try changing the import to not be deferred.",
+      uniqueName: 'MIXIN_DEFERRED_CLASS');
 
   static const CompileTimeErrorCode
       MIXIN_INFERENCE_INCONSISTENT_MATCHING_CLASSES = CompileTimeErrorCode(
@@ -7237,8 +7901,27 @@
               "other than Object.");
 
   /**
-   * A mixin declaration introduces a mixin and an interface, but not a class.
+   * No parameters.
    */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when a mixin is instantiated.
+  //
+  // #### Example
+  //
+  // The following code produces this diagnostic because the mixin `M` is being
+  // instantiated:
+  //
+  // ```dart
+  // mixin M {}
+  //
+  // var m = [!M!]();
+  // ```
+  //
+  // #### Common fixes
+  //
+  // If you intend to use an instance of a class, then use the name of that
+  // class in place of the name of the mixin.
   static const CompileTimeErrorCode MIXIN_INSTANTIATE = CompileTimeErrorCode(
       'MIXIN_INSTANTIATE', "Mixins can't be instantiated.");
 
@@ -7289,6 +7972,17 @@
       'MIXIN_OF_NON_CLASS', "Classes can only mix in mixins and classes.",
       hasPublishedDocs: true);
 
+  static const CompileTimeErrorCode
+      MIXIN_OF_TYPE_ALIAS_EXPANDS_TO_TYPE_PARAMETER = CompileTimeErrorCode(
+          'MIXIN_OF_TYPE_ALIAS_EXPANDS_TO_TYPE_PARAMETER',
+          "Type aliases that expand to a type parameter can't be mixed in.");
+
+  static const CompileTimeErrorCode
+      MIXIN_ON_TYPE_ALIAS_EXPANDS_TO_TYPE_PARAMETER = CompileTimeErrorCode(
+          'MIXIN_ON_TYPE_ALIAS_EXPANDS_TO_TYPE_PARAMETER',
+          "Type aliases that expand to a type parameter can't be used as"
+              "superclass constraints.");
+
   /**
    * No parameters.
    */
@@ -8031,19 +8725,87 @@
           hasPublishedDocs: true);
 
   /**
-   * 13.9 Switch: Given a switch statement of the form <i>switch (e) {
-   * label<sub>11</sub> &hellip; label<sub>1j1</sub> case e<sub>1</sub>:
-   * s<sub>1</sub> &hellip; label<sub>n1</sub> &hellip; label<sub>njn</sub> case
-   * e<sub>n</sub>: s<sub>n</sub> default: s<sub>n+1</sub>}</i> or the form
-   * <i>switch (e) { label<sub>11</sub> &hellip; label<sub>1j1</sub> case
-   * e<sub>1</sub>: s<sub>1</sub> &hellip; label<sub>n1</sub> &hellip;
-   * label<sub>njn</sub> case e<sub>n</sub>: s<sub>n</sub>}</i>, it is a
-   * compile-time error if the expressions <i>e<sub>k</sub></i> are not
-   * compile-time constants, for all <i>1 &lt;= k &lt;= n</i>.
-   *
-   * 12.1 Constants: A qualified reference to a static constant variable that is
-   * not qualified by a deferred prefix.
+   * No parameters.
    */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when the expression in a case clause
+  // references a constant from a library that is imported using a deferred
+  // import. In order for switch statements to be compiled efficiently, the
+  // constants referenced in case clauses need to be available at compile time,
+  // and constants from deferred libraries aren't available at compile time.
+  //
+  // For more information, see the language tour's coverage of
+  // [deferred loading](https://dart.dev/guides/language/language-tour#lazily-loading-a-library).
+  //
+  // #### Example
+  //
+  // Given a file (`a.dart`) that defines the constant `zero`:
+  //
+  // ```dart
+  // %uri="lib/a.dart"
+  // const zero = 0;
+  // ```
+  //
+  // The following code produces this diagnostic because the library `a.dart` is
+  // imported using a `deferred` import, and the constant `a.zero`, declared in
+  // the imported library, is used in a case clause:
+  //
+  // ```dart
+  // import 'a.dart' deferred as a;
+  //
+  // void f(int x) {
+  //   switch (x) {
+  //     case [!a.zero!]:
+  //       // ...
+  //       break;
+  //   }
+  // }
+  // ```
+  //
+  // #### Common fixes
+  //
+  // If you need to reference the constant from the imported library, then
+  // remove the `deferred` keyword:
+  //
+  // ```dart
+  // import 'a.dart' as a;
+  //
+  // void f(int x) {
+  //   switch (x) {
+  //     case a.zero:
+  //       // ...
+  //       break;
+  //   }
+  // }
+  // ```
+  //
+  // If you need to reference the constant from the imported library and also
+  // need the imported library to be deferred, then rewrite the switch statement
+  // as a sequence of `if` statements:
+  //
+  // ```dart
+  // import 'a.dart' deferred as a;
+  //
+  // void f(int x) {
+  //   if (x == a.zero) {
+  //     // ...
+  //   }
+  // }
+  // ```
+  //
+  // If you don't need to reference the constant, then replace the case
+  // expression:
+  //
+  // ```dart
+  // void f(int x) {
+  //   switch (x) {
+  //     case 0:
+  //       // ...
+  //       break;
+  //   }
+  // }
+  // ```
   static const CompileTimeErrorCode
       NON_CONSTANT_CASE_EXPRESSION_FROM_DEFERRED_LIBRARY = CompileTimeErrorCode(
           'NON_CONSTANT_CASE_EXPRESSION_FROM_DEFERRED_LIBRARY',
@@ -8101,12 +8863,53 @@
           hasPublishedDocs: true);
 
   /**
-   * 6.2.2 Optional Formals: It is a compile-time error if the default value of
-   * an optional parameter is not a compile-time constant.
-   *
-   * 12.1 Constants: A qualified reference to a static constant variable that is
-   * not qualified by a deferred prefix.
+   * No parameters.
    */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when the default value of an optional
+  // parameter uses a constant from a library imported using a deferred import.
+  // Default values need to be available at compile time, and constants from
+  // deferred libraries aren't available at compile time.
+  //
+  // For more information, see the language tour's coverage of
+  // [deferred loading](https://dart.dev/guides/language/language-tour#lazily-loading-a-library).
+  //
+  // #### Example
+  //
+  // Given a file (`a.dart`) that defines the constant `zero`:
+  //
+  // ```dart
+  // %uri="lib/a.dart"
+  // const zero = 0;
+  // ```
+  //
+  // The following code produces this diagnostic because `zero` is declared in a
+  // library imported using a deferred import:
+  //
+  // ```dart
+  // import 'a.dart' deferred as a;
+  //
+  // void f({int x = [!a.zero!]}) {}
+  // ```
+  //
+  // #### Common fixes
+  //
+  // If you need to reference the constant from the imported library, then
+  // remove the `deferred` keyword:
+  //
+  // ```dart
+  // import 'a.dart' as a;
+  //
+  // void f({int x = a.zero}) {}
+  // ```
+  //
+  // If you don't need to reference the constant, then replace the default
+  // value:
+  //
+  // ```dart
+  // void f({int x = 0}) {}
+  // ```
   static const CompileTimeErrorCode
       NON_CONSTANT_DEFAULT_VALUE_FROM_DEFERRED_LIBRARY = CompileTimeErrorCode(
           'NON_CONSTANT_DEFAULT_VALUE_FROM_DEFERRED_LIBRARY',
@@ -8163,19 +8966,72 @@
           hasPublishedDocs: true);
 
   /**
-   * 12.6 Lists: It is a compile time error if an element of a constant list
-   * literal is not a compile-time constant.
-   *
-   * 12.1 Constants: A qualified reference to a static constant variable that is
-   * not qualified by a deferred prefix.
+   * No parameters.
    */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when a collection literal that is
+  // either explicitly (because it's prefixed by the `const` keyword) or
+  // implicitly (because it appears in a [constant context][]) a constant
+  // contains a value that is declared in a library that is imported using a
+  // deferred import. Constants are evaluated at compile time, and values from
+  // deferred libraries aren't available at compile time.
+  //
+  // For more information, see the language tour's coverage of
+  // [deferred loading](https://dart.dev/guides/language/language-tour#lazily-loading-a-library).
+  //
+  // #### Example
+  //
+  // Given a file (`a.dart`) that defines the constant `zero`:
+  //
+  // ```dart
+  // %uri="lib/a.dart"
+  // const zero = 0;
+  // ```
+  //
+  // The following code produces this diagnostic because the constant list
+  // literal contains `a.zero`, which is imported using a `deferred` import:
+  //
+  // ```dart
+  // import 'a.dart' deferred as a;
+  //
+  // var l = const [[!a.zero!]];
+  // ```
+  //
+  // #### Common fixes
+  //
+  // If the collection literal isn't required to be constant, then remove the
+  // `const` keyword:
+  //
+  // ```dart
+  // import 'a.dart' deferred as a;
+  //
+  // var l = [a.zero];
+  // ```
+  //
+  // If the collection is required to be constant and the imported constant must
+  // be referenced, then remove the keyword `deferred` from the import:
+  //
+  // ```dart
+  // import 'a.dart' as a;
+  //
+  // var l = const [a.zero];
+  // ```
+  //
+  // If you don't need to reference the constant, then replace it with a
+  // suitable value:
+  //
+  // ```dart
+  // var l = const [0];
+  // ```
   static const CompileTimeErrorCode
       NON_CONSTANT_LIST_ELEMENT_FROM_DEFERRED_LIBRARY = CompileTimeErrorCode(
-          'NON_CONSTANT_LIST_ELEMENT_FROM_DEFERRED_LIBRARY',
+          'COLLECTION_ELEMENT_FROM_DEFERRED_LIBRARY',
           "Constant values from a deferred library can't be used as values in "
-              "a 'const' list.",
-          correction:
-              "Try removing the keyword 'const' from the list literal.");
+              "a 'const' list literal.",
+          correction: "Try removing the keyword 'const' from the list literal "
+              "or removing the keyword 'deferred' from the import.",
+          uniqueName: 'NON_CONSTANT_LIST_ELEMENT_FROM_DEFERRED_LIBRARY');
 
   /**
    * No parameters.
@@ -8267,18 +9123,17 @@
       hasPublishedDocs: true);
 
   /**
-   * 12.7 Maps: It is a compile time error if either a key or a value of an
-   * entry in a constant map literal is not a compile-time constant.
-   *
-   * 12.1 Constants: A qualified reference to a static constant variable that is
-   * not qualified by a deferred prefix.
+   * No parameters.
    */
   static const CompileTimeErrorCode NON_CONSTANT_MAP_KEY_FROM_DEFERRED_LIBRARY =
       CompileTimeErrorCode(
-          'NON_CONSTANT_MAP_KEY_FROM_DEFERRED_LIBRARY',
+          'COLLECTION_ELEMENT_FROM_DEFERRED_LIBRARY',
           "Constant values from a deferred library can't be used as keys in a "
-              "const map literal.",
-          correction: "Try removing the keyword 'const' from the map literal.");
+              "'const' map literal.",
+          correction:
+              "Try removing the keyword 'const' from the map literal or removing "
+              "the keyword 'deferred' from the import.",
+          uniqueName: 'NON_CONSTANT_MAP_KEY_FROM_DEFERRED_LIBRARY');
 
   /**
    * No parameters.
@@ -8320,18 +9175,17 @@
           hasPublishedDocs: true);
 
   /**
-   * 12.7 Maps: It is a compile time error if either a key or a value of an
-   * entry in a constant map literal is not a compile-time constant.
-   *
-   * 12.1 Constants: A qualified reference to a static constant variable that is
-   * not qualified by a deferred prefix.
+   * No parameters.
    */
   static const CompileTimeErrorCode
       NON_CONSTANT_MAP_VALUE_FROM_DEFERRED_LIBRARY = CompileTimeErrorCode(
-          'NON_CONSTANT_MAP_VALUE_FROM_DEFERRED_LIBRARY',
+          'COLLECTION_ELEMENT_FROM_DEFERRED_LIBRARY',
           "Constant values from a deferred library can't be used as values in "
-              "a const map literal.",
-          correction: "Try removing the keyword 'const' from the map literal.");
+              "a 'const' map literal.",
+          correction:
+              "Try removing the keyword 'const' from the map literal or removing "
+              "the keyword 'deferred' from the import.",
+          uniqueName: 'NON_CONSTANT_MAP_VALUE_FROM_DEFERRED_LIBRARY');
 
   /**
    * No parameters.
@@ -10410,12 +11264,18 @@
       'RETURN_WITHOUT_VALUE', "The return value is missing after 'return'.",
       hasPublishedDocs: true);
 
+  /**
+   * No parameters.
+   */
   static const CompileTimeErrorCode SET_ELEMENT_FROM_DEFERRED_LIBRARY =
       CompileTimeErrorCode(
-          'SET_ELEMENT_FROM_DEFERRED_LIBRARY',
+          'COLLECTION_ELEMENT_FROM_DEFERRED_LIBRARY',
           "Constant values from a deferred library can't be used as values in "
-              "a const set.",
-          correction: "Try making the deferred import non-deferred.");
+              "a 'const' set literal.",
+          correction:
+              "Try removing the keyword 'const' from the set literal or removing "
+              "the keyword 'deferred' from the import.",
+          uniqueName: 'SET_ELEMENT_FROM_DEFERRED_LIBRARY');
 
   /**
    * Parameters:
@@ -10781,17 +11641,49 @@
               "another typedef.");
 
   /**
-   * 15.1 Static Types: It is a static warning to use a deferred type in a type
-   * annotation.
-   *
    * Parameters:
    * 0: the name of the type that is deferred and being used in a type
    *    annotation
    */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when the type annotation is in a
+  // variable declaration, or the type used in a cast (`as`) or type test (`is`)
+  // is a type declared in a library that is imported using a deferred import.
+  // These types are required to be available at compile time, but aren't.
+  //
+  // For more information, see the language tour's coverage of
+  // [deferred loading](https://dart.dev/guides/language/language-tour#lazily-loading-a-library).
+  //
+  // #### Example
+  //
+  // The following code produces this diagnostic because the type of the
+  // parameter `f` is imported from a deferred library:
+  //
+  // ```dart
+  // import 'dart:io' deferred as io;
+  //
+  // void f([!io.File!] f) {}
+  // ```
+  //
+  // #### Common fixes
+  //
+  // If you need to reference the imported type, then remove the `deferred`
+  // keyword:
+  //
+  // ```dart
+  // import 'dart:io' as io;
+  //
+  // void f(io.File f) {}
+  // ```
+  //
+  // If the import is required to be deferred and there's another type that is
+  // appropriate, then use that type in place of the type from the deferred
+  // library.
   static const CompileTimeErrorCode TYPE_ANNOTATION_DEFERRED_CLASS =
       CompileTimeErrorCode(
           'TYPE_ANNOTATION_DEFERRED_CLASS',
-          "The deferred type '{0}' can't be used in a declaration, cast or "
+          "The deferred type '{0}' can't be used in a declaration, cast, or "
               "type test.",
           correction: "Try using a different type, or "
               "changing the import to not be deferred.");
@@ -11005,7 +11897,7 @@
   //
   // ```dart
   // void f(String? s) {
-  //   if ([!s!].length > 3) {
+  //   if (s.[!length!] > 3) {
   //     // ...
   //   }
   // }
@@ -13079,6 +13971,20 @@
   // [Understanding null safety](/null-safety/understanding-null-safety#smarter-null-aware-methods)
   // for more details.
   //
+  // The following code produces this diagnostic because `s` can't be `null`.
+  //
+  // ```dart
+  // void f(Object? o) {
+  //   var s = o as String;
+  //   s[!?.!]length;
+  // }
+  // ```
+  //
+  // The reason `s` can't be null, despite the fact that `o` can be `null`, is
+  // because of the cast to `String`, which is a non-nullable type. If `o` ever
+  // has the value `null`, the cast will fail and the invocation of `length`
+  // will not happen.
+  //
   // #### Common fixes
   //
   // Replace the null-aware operator with a non-null-aware equivalent; for
diff --git a/pkg/analyzer/lib/src/error/ignore_validator.dart b/pkg/analyzer/lib/src/error/ignore_validator.dart
index 0d02ce8..5b9844a 100644
--- a/pkg/analyzer/lib/src/error/ignore_validator.dart
+++ b/pkg/analyzer/lib/src/error/ignore_validator.dart
@@ -5,7 +5,6 @@
 import 'package:analyzer/error/error.dart';
 import 'package:analyzer/error/listener.dart';
 import 'package:analyzer/source/line_info.dart';
-import 'package:analyzer/src/dart/error/syntactic_errors.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/ignore_comments/ignore_info.dart';
@@ -28,16 +27,13 @@
   /// 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.
-  late final Set<String> _unignorableNames;
+  final 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
   /// the [_errorReporter].
   IgnoreValidator(this._errorReporter, this._reportedErrors, this._ignoreInfo,
-      this._lineInfo) {
-    var filePath = _errorReporter.source.fullName;
-    _unignorableNames = _UnignorableNames.forFile(filePath);
-  }
+      this._lineInfo, this._unignorableNames);
 
   /// Report any issues with ignore comments in the file being analyzed.
   void reportErrors() {
@@ -129,99 +125,6 @@
     //       [name]);
     // }
   }
-
-  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;
-    }
-    // The [code] is not ignorable, but we've allowed a few "privileged"
-    // cases. Each is annotated with an issue which represents technical
-    // debt. Once cleaned up, we may remove this notion of "privileged".
-    // In the case of [CompileTimeErrorCode.IMPORT_INTERNAL_LIBRARY], we may
-    // just decide that it happens enough in tests that it can be declared
-    // an ignorable error, and in practice other back ends will prevent
-    // non-internal code from importing internal code.
-    if (code == CompileTimeErrorCode.UNDEFINED_FUNCTION ||
-        code == CompileTimeErrorCode.UNDEFINED_PREFIXED_NAME) {
-      // Special case a small number of errors in Flutter code which are
-      // ignored. The erroneous code is found in a conditionally imported
-      // 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 (isFlutter) {
-        return true;
-      }
-    }
-
-    if ((code == CompileTimeErrorCode.IMPORT_INTERNAL_LIBRARY ||
-            code == CompileTimeErrorCode.UNDEFINED_ANNOTATION ||
-            code == ParserErrorCode.NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE) &&
-        isDart2jsTest) {
-      // Special case the dart2js language tests. Some of these import
-      // various internal libraries.
-      return true;
-    }
-    return false;
-  }
 }
 
 extension on AnalysisError {
diff --git a/pkg/analyzer/lib/src/error/imports_verifier.dart b/pkg/analyzer/lib/src/error/imports_verifier.dart
index c421a30..6759bd2 100644
--- a/pkg/analyzer/lib/src/error/imports_verifier.dart
+++ b/pkg/analyzer/lib/src/error/imports_verifier.dart
@@ -438,7 +438,12 @@
           continue;
         }
         for (var element in elements) {
-          if (namespace.getPrefixed(prefix.name, element.name!) != null) {
+          var elementFromNamespace =
+              namespace.getPrefixed(prefix.name, element.name!);
+          if (elementFromNamespace != null) {
+            if (_isShadowing(element, elementFromNamespace)) {
+              continue;
+            }
             _unusedImports.remove(importDirective);
             _removeFromUnusedShownNamesMap(element, importDirective);
           }
@@ -454,7 +459,14 @@
       // Find import directives using namespaces.
       for (ImportDirective importDirective in _allImports) {
         var namespace = _computeNamespace(importDirective);
-        if (namespace?.get(element.name!) != null) {
+        if (namespace == null) {
+          continue;
+        }
+        var elementFromNamespace = namespace.get(element.name!);
+        if (elementFromNamespace != null) {
+          if (_isShadowing(element, elementFromNamespace)) {
+            continue;
+          }
           _unusedImports.remove(importDirective);
           _removeFromUnusedShownNamesMap(element, importDirective);
         }
@@ -563,6 +575,22 @@
     return namespace;
   }
 
+  /// Returns whether [e1] shadows [e2], assuming each is an imported element,
+  /// and that each is imported with the same prefix.
+  ///
+  /// Returns false if the source of either element is `null`.
+  bool _isShadowing(Element e1, Element e2) {
+    var source1 = e1.source;
+    if (source1 == null) {
+      return false;
+    }
+    var source2 = e2.source;
+    if (source2 == null) {
+      return false;
+    }
+    return !source1.isInSystemLibrary && source2.isInSystemLibrary;
+  }
+
   /// Remove [element] from the list of names shown by [importDirective].
   void _removeFromUnusedShownNamesMap(
       Element element, ImportDirective importDirective) {
diff --git a/pkg/analyzer/lib/src/error/inheritance_override.dart b/pkg/analyzer/lib/src/error/inheritance_override.dart
index 4b4e865..696dfb6 100644
--- a/pkg/analyzer/lib/src/error/inheritance_override.dart
+++ b/pkg/analyzer/lib/src/error/inheritance_override.dart
@@ -10,6 +10,7 @@
 import 'package:analyzer/dart/element/type_provider.dart';
 import 'package:analyzer/error/error.dart';
 import 'package:analyzer/error/listener.dart';
+import 'package:analyzer/src/dart/ast/extensions.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/inheritance_manager3.dart';
 import 'package:analyzer/src/dart/element/type_system.dart';
@@ -330,9 +331,9 @@
       return false;
     }
 
-    DartType type = typeName.type!;
+    DartType type = typeName.typeOrThrow;
     if (type is InterfaceType &&
-        typeProvider.nonSubtypableClasses.contains(type.element)) {
+        typeProvider.isNonSubtypableClass(type.element)) {
       reporter.reportErrorForNode(errorCode, typeName, [type]);
       return true;
     }
diff --git a/pkg/analyzer/lib/src/error/nullable_dereference_verifier.dart b/pkg/analyzer/lib/src/error/nullable_dereference_verifier.dart
index 87f07b8..cf1f3b5 100644
--- a/pkg/analyzer/lib/src/error/nullable_dereference_verifier.dart
+++ b/pkg/analyzer/lib/src/error/nullable_dereference_verifier.dart
@@ -3,6 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/syntactic_entity.dart';
+import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/diagnostic/diagnostic.dart';
 import 'package:analyzer/error/error.dart';
@@ -39,7 +41,7 @@
     return _check(expression, type, errorCode: errorCode);
   }
 
-  void report(AstNode errorNode, DartType receiverType,
+  void report(SyntacticEntity errorEntity, DartType receiverType,
       {ErrorCode? errorCode,
       List<String> arguments = const <String>[],
       List<DiagnosticMessage>? messages}) {
@@ -48,8 +50,15 @@
     } else {
       errorCode ??= CompileTimeErrorCode.UNCHECKED_USE_OF_NULLABLE_VALUE;
     }
-    _errorReporter.reportErrorForNode(
-        errorCode, errorNode, arguments, messages);
+    if (errorEntity is AstNode) {
+      _errorReporter.reportErrorForNode(
+          errorCode, errorEntity, arguments, messages);
+    } else if (errorEntity is Token) {
+      _errorReporter.reportErrorForToken(
+          errorCode, errorEntity, arguments, messages);
+    } else {
+      throw StateError('Syntactic entity must be AstNode or Token to report.');
+    }
   }
 
   /// If the [receiverType] is potentially nullable, report it.
@@ -68,7 +77,7 @@
     List<DiagnosticMessage>? messages;
     if (errorNode is Expression) {
       messages = _resolver.computeWhyNotPromotedMessages(errorNode, errorNode,
-          _resolver.flowAnalysis?.flow?.whyNotPromoted(errorNode));
+          _resolver.flowAnalysis?.flow?.whyNotPromoted(errorNode)());
     }
     report(errorNode, receiverType, errorCode: errorCode, messages: messages);
     return true;
diff --git a/pkg/analyzer/lib/src/error/override_verifier.dart b/pkg/analyzer/lib/src/error/override_verifier.dart
index 71a6d88..795a093 100644
--- a/pkg/analyzer/lib/src/error/override_verifier.dart
+++ b/pkg/analyzer/lib/src/error/override_verifier.dart
@@ -89,7 +89,12 @@
 
   /// Return `true` if the [member] overrides a member from a superinterface.
   bool _isOverride(ExecutableElement member) {
-    var name = Name(_libraryUri, member.name);
-    return _inheritance.getOverridden2(_currentClass!, name) != null;
+    var currentClass = _currentClass;
+    if (currentClass != null) {
+      var name = Name(_libraryUri, member.name);
+      return _inheritance.getOverridden2(currentClass, name) != null;
+    } else {
+      return false;
+    }
   }
 }
diff --git a/pkg/analyzer/lib/src/error/type_arguments_verifier.dart b/pkg/analyzer/lib/src/error/type_arguments_verifier.dart
index 2da84df..a14d9f4 100644
--- a/pkg/analyzer/lib/src/error/type_arguments_verifier.dart
+++ b/pkg/analyzer/lib/src/error/type_arguments_verifier.dart
@@ -4,6 +4,7 @@
 
 import "dart:math" as math;
 
+import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
@@ -174,7 +175,7 @@
       return;
     }
     if (_isMissingTypeArguments(
-        node, node.type!, node.name.staticElement, null)) {
+        node, node.typeOrThrow, node.name.staticElement, null)) {
       AstNode unwrappedParent = parentEscapingTypeArguments(node);
       if (unwrappedParent is AsExpression || unwrappedParent is IsExpression) {
         // Do not report a "Strict raw type" error in this case; too noisy.
@@ -189,7 +190,7 @@
   /// Verify that the type arguments in the given [typeName] are all within
   /// their bounds.
   void _checkForTypeArgumentNotMatchingBounds(TypeName typeName) {
-    var type = typeName.type!;
+    var type = typeName.typeOrThrow;
 
     List<TypeParameterElement> typeParameters;
     List<DartType> typeArguments;
@@ -216,11 +217,13 @@
       var typeArgument = typeArguments[i];
 
       if (typeArgument is FunctionType && typeArgument.typeFormals.isNotEmpty) {
-        _errorReporter.reportErrorForNode(
-          CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT,
-          _typeArgumentErrorNode(typeName, i),
-        );
-        continue;
+        if (!_libraryElement.featureSet.isEnabled(Feature.generic_metadata)) {
+          _errorReporter.reportErrorForNode(
+            CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT,
+            _typeArgumentErrorNode(typeName, i),
+          );
+          continue;
+        }
       }
 
       var bound = typeParameter.bound;
@@ -333,7 +336,7 @@
     var instantiatedType = node.staticInvokeType;
     if (genericType is FunctionType && instantiatedType is FunctionType) {
       var fnTypeParams = genericType.typeFormals;
-      var typeArgs = typeArgumentList.map((t) => t.type!).toList();
+      var typeArgs = typeArgumentList.map((t) => t.typeOrThrow).toList();
 
       // If the amount mismatches, clean up the lists to be substitutable. The
       // mismatch in size is reported elsewhere, but we must successfully
@@ -354,11 +357,14 @@
         DartType argType = typeArgs[i];
 
         if (argType is FunctionType && argType.typeFormals.isNotEmpty) {
-          _errorReporter.reportErrorForNode(
-            CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT,
-            typeArgumentList[i],
-          );
-          continue;
+          if (!_libraryElement.featureSet.isEnabled(Feature.generic_metadata)) {
+            _errorReporter.reportErrorForNode(
+              CompileTimeErrorCode
+                  .GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT,
+              typeArgumentList[i],
+            );
+            continue;
+          }
         }
 
         var fnTypeParam = fnTypeParams[i];
@@ -438,6 +444,7 @@
     if (parent is WithClause) return false;
     if (parent is ConstructorName) return false;
     if (parent is ImplementsClause) return false;
+    if (parent is GenericTypeAlias) return false;
     return true;
   }
 
diff --git a/pkg/analyzer/lib/src/fasta/ast_builder.dart b/pkg/analyzer/lib/src/fasta/ast_builder.dart
index 9b9b7af..0036512 100644
--- a/pkg/analyzer/lib/src/fasta/ast_builder.dart
+++ b/pkg/analyzer/lib/src/fasta/ast_builder.dart
@@ -11,6 +11,7 @@
         messageAbstractLateField,
         messageAbstractStaticField,
         messageConstConstructorWithBody,
+        messageConstFactory,
         messageConstructorWithTypeParameters,
         messageDirectiveAfterDeclaration,
         messageExpectedStatement,
@@ -26,7 +27,6 @@
         messageMissingAssignableSelector,
         messageNativeClauseShouldBeAnnotation,
         messageOperatorWithTypeParameters,
-        messageTypedefNotFunction,
         templateDuplicateLabelInSwitchStatement,
         templateExpectedButGot,
         templateExpectedIdentifier,
@@ -1549,7 +1549,15 @@
       var metadata = pop() as List<Annotation>?;
       var comment = _findComment(metadata, typedefKeyword);
       if (type is! GenericFunctionType && !enableNonFunctionTypeAliases) {
-        handleRecoverableError(messageTypedefNotFunction, equals, equals);
+        var feature = Feature.nonfunction_type_aliases;
+        handleRecoverableError(
+          templateExperimentNotEnabled.withArguments(
+            feature.enableString,
+            _versionAsString(ExperimentStatus.currentVersion),
+          ),
+          equals,
+          equals,
+        );
       }
       declarations.add(ast.genericTypeAlias(comment, metadata, typedefKeyword,
           name, templateParameters, equals, type, semicolon));
@@ -2568,6 +2576,13 @@
   }
 
   @override
+  void handleConstFactory(Token constKeyword) {
+    debugEvent("ConstFactory");
+    // TODO(kallentu): Removal of const factory error for const function feature
+    handleRecoverableError(messageConstFactory, constKeyword, constKeyword);
+  }
+
+  @override
   void handleContinueStatement(
       bool hasTarget, Token continueKeyword, Token semicolon) {
     assert(optional('continue', continueKeyword));
diff --git a/pkg/analyzer/lib/src/generated/element_resolver.dart b/pkg/analyzer/lib/src/generated/element_resolver.dart
index 7b163a73..1da17d4 100644
--- a/pkg/analyzer/lib/src/generated/element_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/element_resolver.dart
@@ -2,12 +2,14 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'package:_fe_analyzer_shared/src/flow_analysis/flow_analysis.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/error/listener.dart';
 import 'package:analyzer/src/dart/ast/ast.dart';
+import 'package:analyzer/src/dart/ast/extensions.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/type_provider.dart';
 import 'package:analyzer/src/dart/resolver/method_invocation_resolver.dart';
@@ -245,7 +247,7 @@
 
   @override
   void visitConstructorName(covariant ConstructorNameImpl node) {
-    DartType type = node.type.type!;
+    DartType type = node.type.typeOrThrow;
     if (type.isDynamic) {
       // Nothing to do.
     } else if (type is InterfaceType) {
@@ -393,8 +395,12 @@
   }
 
   @override
-  void visitMethodInvocation(MethodInvocation node) {
-    _methodInvocationResolver.resolve(node as MethodInvocationImpl);
+  void visitMethodInvocation(MethodInvocation node,
+      {List<Map<DartType, NonPromotionReason> Function()>?
+          whyNotPromotedList}) {
+    whyNotPromotedList ??= [];
+    _methodInvocationResolver.resolve(
+        node as MethodInvocationImpl, whyNotPromotedList);
   }
 
   @override
@@ -659,7 +665,7 @@
             receiver: null,
             receiverType: enclosingClass.thisType,
             name: identifier.name,
-            receiverErrorNode: identifier,
+            propertyErrorEntity: identifier,
             nameErrorEntity: identifier,
           );
           setter = result.setter;
@@ -700,7 +706,7 @@
           receiver: null,
           receiverType: enclosingType,
           name: identifier.name,
-          receiverErrorNode: identifier,
+          propertyErrorEntity: identifier,
           nameErrorEntity: identifier,
         );
         if (identifier.inSetterContext() ||
diff --git a/pkg/analyzer/lib/src/generated/engine.dart b/pkg/analyzer/lib/src/generated/engine.dart
index 14eda22..3b4543e 100644
--- a/pkg/analyzer/lib/src/generated/engine.dart
+++ b/pkg/analyzer/lib/src/generated/engine.dart
@@ -303,6 +303,10 @@
   @override
   bool chromeOsManifestChecks = false;
 
+  /// The set of "un-ignorable" error names, as parsed in [AnalyzerOptions] from
+  /// an analysis options file.
+  Set<String> unignorableNames = {};
+
   /// Initialize a newly created set of analysis options to have their default
   /// values.
   AnalysisOptionsImpl();
@@ -383,7 +387,6 @@
       }
 
       // Append boolean flags.
-      // ignore: deprecated_member_use_from_same_package
       buffer.addBool(implicitCasts);
       buffer.addBool(implicitDynamic);
       buffer.addBool(strictInference);
diff --git a/pkg/analyzer/lib/src/generated/error_detection_helpers.dart b/pkg/analyzer/lib/src/generated/error_detection_helpers.dart
new file mode 100644
index 0000000..af745c8
--- /dev/null
+++ b/pkg/analyzer/lib/src/generated/error_detection_helpers.dart
@@ -0,0 +1,323 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:_fe_analyzer_shared/src/flow_analysis/flow_analysis.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/syntactic_entity.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/diagnostic/diagnostic.dart';
+import 'package:analyzer/error/error.dart';
+import 'package:analyzer/error/listener.dart';
+import 'package:analyzer/src/dart/ast/extensions.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';
+
+/// Methods useful in detecting errors.  This mixin exists to allow code to be
+/// more easily shared between the two visitors that do the majority of error
+/// reporting (ResolverVisitor and ErrorVerifier).
+mixin ErrorDetectionHelpers {
+  ErrorReporter get errorReporter;
+
+  TypeSystemImpl get typeSystem;
+
+  /// Verify that the given [expression] can be assigned to its corresponding
+  /// parameters. The [expectedStaticType] is the expected static type of the
+  /// parameter. The [actualStaticType] is the actual static type of the
+  /// argument.
+  void checkForArgumentTypeNotAssignable(
+      Expression expression,
+      DartType? expectedStaticType,
+      DartType actualStaticType,
+      ErrorCode errorCode,
+      {Map<DartType, NonPromotionReason> Function()? whyNotPromoted}) {
+    // Warning case: test static type information
+    if (expectedStaticType != null) {
+      if (!expectedStaticType.isVoid && checkForUseOfVoidResult(expression)) {
+        return;
+      }
+
+      _checkForAssignableExpressionAtType(
+          expression, actualStaticType, expectedStaticType, errorCode,
+          whyNotPromoted: whyNotPromoted);
+    }
+  }
+
+  /// Verify that the given [argument] can be assigned to its corresponding
+  /// parameter.
+  ///
+  /// This method corresponds to
+  /// [BestPracticesVerifier.checkForArgumentTypeNotAssignableForArgument].
+  ///
+  /// See [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE].
+  void checkForArgumentTypeNotAssignableForArgument(Expression argument,
+      {bool promoteParameterToNullable = false,
+      Map<DartType, NonPromotionReason> Function()? whyNotPromoted}) {
+    _checkForArgumentTypeNotAssignableForArgument2(
+      argument: argument,
+      parameter: argument.staticParameterElement,
+      promoteParameterToNullable: promoteParameterToNullable,
+      whyNotPromoted: whyNotPromoted,
+    );
+  }
+
+  /// Verify that the given constructor field [initializer] has compatible field
+  /// and initializer expression types. The [fieldElement] is the static element
+  /// from the name in the [ConstructorFieldInitializer].
+  ///
+  /// See [CompileTimeErrorCode.CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE], and
+  /// [StaticWarningCode.FIELD_INITIALIZER_NOT_ASSIGNABLE].
+  void checkForFieldInitializerNotAssignable(
+      ConstructorFieldInitializer initializer, FieldElement fieldElement,
+      {required bool isConstConstructor,
+      required Map<DartType, NonPromotionReason> Function()? whyNotPromoted}) {
+    // prepare field type
+    DartType fieldType = fieldElement.type;
+    // prepare expression type
+    Expression expression = initializer.expression;
+    // test the static type of the expression
+    DartType staticType = expression.typeOrThrow;
+    if (typeSystem.isAssignableTo(staticType, fieldType)) {
+      if (!fieldType.isVoid) {
+        checkForUseOfVoidResult(expression);
+      }
+      return;
+    }
+    var messages = computeWhyNotPromotedMessages(
+        expression, expression, whyNotPromoted?.call());
+    // report problem
+    if (isConstConstructor) {
+      // TODO(paulberry): this error should be based on the actual type of the
+      // constant, not the static type.  See dartbug.com/21119.
+      errorReporter.reportErrorForNode(
+          CompileTimeErrorCode.CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE,
+          expression,
+          [staticType, fieldType],
+          messages);
+    }
+    errorReporter.reportErrorForNode(
+        CompileTimeErrorCode.FIELD_INITIALIZER_NOT_ASSIGNABLE,
+        expression,
+        [staticType, fieldType],
+        messages);
+    // TODO(brianwilkerson) Define a hint corresponding to these errors and
+    // report it if appropriate.
+//        // test the propagated type of the expression
+//        Type propagatedType = expression.getPropagatedType();
+//        if (propagatedType != null && propagatedType.isAssignableTo(fieldType)) {
+//          return false;
+//        }
+//        // report problem
+//        if (isEnclosingConstructorConst) {
+//          errorReporter.reportTypeErrorForNode(
+//              CompileTimeErrorCode.CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE,
+//              expression,
+//              propagatedType == null ? staticType : propagatedType,
+//              fieldType);
+//        } else {
+//          errorReporter.reportTypeErrorForNode(
+//              StaticWarningCode.FIELD_INITIALIZER_NOT_ASSIGNABLE,
+//              expression,
+//              propagatedType == null ? staticType : propagatedType,
+//              fieldType);
+//        }
+//        return true;
+  }
+
+  /// Verify that the given left hand side ([lhs]) and right hand side ([rhs])
+  /// represent a valid assignment.
+  ///
+  /// See [CompileTimeErrorCode.INVALID_ASSIGNMENT].
+  void checkForInvalidAssignment(Expression? lhs, Expression? rhs,
+      {Map<DartType, NonPromotionReason> Function()? whyNotPromoted}) {
+    if (lhs == null || rhs == null) {
+      return;
+    }
+
+    if (lhs is IndexExpression &&
+            identical(lhs.realTarget.staticType, NeverTypeImpl.instance) ||
+        lhs is PrefixedIdentifier &&
+            identical(lhs.prefix.staticType, NeverTypeImpl.instance) ||
+        lhs is PropertyAccess &&
+            identical(lhs.realTarget.staticType, NeverTypeImpl.instance)) {
+      return;
+    }
+
+    DartType leftType;
+    var parent = lhs.parent;
+    if (parent is AssignmentExpression && parent.leftHandSide == lhs) {
+      leftType = parent.writeType!;
+    } else {
+      var leftVariableElement = getVariableElement(lhs);
+      leftType = (leftVariableElement == null)
+          ? lhs.typeOrThrow
+          : leftVariableElement.type;
+    }
+
+    if (!leftType.isVoid && checkForUseOfVoidResult(rhs)) {
+      return;
+    }
+
+    _checkForAssignableExpression(
+        rhs, leftType, CompileTimeErrorCode.INVALID_ASSIGNMENT,
+        whyNotPromoted: whyNotPromoted);
+  }
+
+  /// Check for situations where the result of a method or function is used,
+  /// when it returns 'void'. Or, in rare cases, when other types of expressions
+  /// are void, such as identifiers.
+  ///
+  /// See [StaticWarningCode.USE_OF_VOID_RESULT].
+  bool checkForUseOfVoidResult(Expression expression) {
+    if (!identical(expression.staticType, VoidTypeImpl.instance)) {
+      return false;
+    }
+
+    if (expression is MethodInvocation) {
+      SimpleIdentifier methodName = expression.methodName;
+      errorReporter.reportErrorForNode(
+          CompileTimeErrorCode.USE_OF_VOID_RESULT, methodName, []);
+    } else {
+      errorReporter.reportErrorForNode(
+          CompileTimeErrorCode.USE_OF_VOID_RESULT, expression, []);
+    }
+
+    return true;
+  }
+
+  void checkIndexExpressionIndex(
+    Expression index, {
+    required ExecutableElement? readElement,
+    required ExecutableElement? writeElement,
+    required Map<DartType, NonPromotionReason> Function()? whyNotPromoted,
+  }) {
+    if (readElement is MethodElement) {
+      var parameters = readElement.parameters;
+      if (parameters.isNotEmpty) {
+        _checkForArgumentTypeNotAssignableForArgument2(
+          argument: index,
+          parameter: parameters[0],
+          promoteParameterToNullable: false,
+          whyNotPromoted: whyNotPromoted,
+        );
+      }
+    }
+
+    if (writeElement is MethodElement) {
+      var parameters = writeElement.parameters;
+      if (parameters.isNotEmpty) {
+        _checkForArgumentTypeNotAssignableForArgument2(
+          argument: index,
+          parameter: parameters[0],
+          promoteParameterToNullable: false,
+        );
+      }
+    }
+  }
+
+  /// Computes the appropriate set of context messages to report along with an
+  /// error that may have occurred because [expression] was not type promoted.
+  ///
+  /// If [expression] is `null`, it means the expression that was not type
+  /// promoted was an implicit `this`.
+  ///
+  /// [errorEntity] is the entity whose location will be associated with the
+  /// error.  This is needed for test instrumentation.
+  ///
+  /// [whyNotPromoted] should be the non-promotion details returned by the flow
+  /// analysis engine.
+  List<DiagnosticMessage> computeWhyNotPromotedMessages(
+      Expression? expression,
+      SyntacticEntity errorEntity,
+      Map<DartType, NonPromotionReason>? whyNotPromoted);
+
+  /// Return the variable element represented by the given [expression], or
+  /// `null` if there is no such element.
+  VariableElement? getVariableElement(Expression? expression) {
+    if (expression is Identifier) {
+      var element = expression.staticElement;
+      if (element is VariableElement) {
+        return element;
+      }
+    }
+    return null;
+  }
+
+  void _checkForArgumentTypeNotAssignableForArgument2({
+    required Expression argument,
+    required ParameterElement? parameter,
+    required bool promoteParameterToNullable,
+    Map<DartType, NonPromotionReason> Function()? whyNotPromoted,
+  }) {
+    var staticParameterType = parameter?.type;
+    if (promoteParameterToNullable && staticParameterType != null) {
+      staticParameterType =
+          typeSystem.makeNullable(staticParameterType as TypeImpl);
+    }
+    _checkForArgumentTypeNotAssignableWithExpectedTypes(
+        argument,
+        staticParameterType,
+        CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE,
+        whyNotPromoted);
+  }
+
+  /// Verify that the given [expression] can be assigned to its corresponding
+  /// parameters.
+  ///
+  /// See [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE],
+  /// [CompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE],
+  /// [StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE],
+  /// [CompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE],
+  /// [CompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE],
+  /// [StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE], and
+  /// [StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE].
+  void _checkForArgumentTypeNotAssignableWithExpectedTypes(
+      Expression expression,
+      DartType? expectedStaticType,
+      ErrorCode errorCode,
+      Map<DartType, NonPromotionReason> Function()? whyNotPromoted) {
+    checkForArgumentTypeNotAssignable(
+        expression, expectedStaticType, expression.typeOrThrow, errorCode,
+        whyNotPromoted: whyNotPromoted);
+  }
+
+  bool _checkForAssignableExpression(
+      Expression expression, DartType expectedStaticType, ErrorCode errorCode,
+      {required Map<DartType, NonPromotionReason> Function()? whyNotPromoted}) {
+    DartType actualStaticType = expression.typeOrThrow;
+    return _checkForAssignableExpressionAtType(
+        expression, actualStaticType, expectedStaticType, errorCode,
+        whyNotPromoted: whyNotPromoted);
+  }
+
+  bool _checkForAssignableExpressionAtType(
+      Expression expression,
+      DartType actualStaticType,
+      DartType expectedStaticType,
+      ErrorCode errorCode,
+      {Map<DartType, NonPromotionReason> Function()? whyNotPromoted}) {
+    if (!typeSystem.isAssignableTo(actualStaticType, expectedStaticType)) {
+      AstNode getErrorNode(AstNode node) {
+        if (node is CascadeExpression) {
+          return getErrorNode(node.target);
+        }
+        if (node is ParenthesizedExpression) {
+          return getErrorNode(node.expression);
+        }
+        return node;
+      }
+
+      errorReporter.reportErrorForNode(
+        errorCode,
+        getErrorNode(expression),
+        [actualStaticType, expectedStaticType],
+        computeWhyNotPromotedMessages(
+            expression, expression, whyNotPromoted?.call()),
+      );
+      return false;
+    }
+    return true;
+  }
+}
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index 1971848..9601c2e9 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -4,6 +4,7 @@
 
 import 'dart:collection';
 
+import 'package:_fe_analyzer_shared/src/flow_analysis/flow_analysis.dart';
 import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/syntactic_entity.dart';
@@ -13,6 +14,7 @@
 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/diagnostic/diagnostic.dart';
 import 'package:analyzer/error/error.dart';
 import 'package:analyzer/error/listener.dart';
 import 'package:analyzer/src/dart/analysis/session.dart';
@@ -38,6 +40,7 @@
 import 'package:analyzer/src/error/type_arguments_verifier.dart';
 import 'package:analyzer/src/generated/element_resolver.dart';
 import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/error_detection_helpers.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/generated/parser.dart' show ParserErrorCode;
 import 'package:analyzer/src/generated/this_access_tracker.dart';
@@ -142,9 +145,11 @@
 
 /// A visitor used to traverse an AST structure looking for additional errors
 /// and warnings not covered by the parser and resolver.
-class ErrorVerifier extends RecursiveAstVisitor<void> {
+class ErrorVerifier extends RecursiveAstVisitor<void>
+    with ErrorDetectionHelpers {
   /// The error reporter by which errors will be reported.
-  final ErrorReporter _errorReporter;
+  @override
+  final ErrorReporter errorReporter;
 
   /// The current library that is being analyzed.
   final LibraryElementImpl _currentLibrary;
@@ -159,7 +164,8 @@
   final TypeProvider _typeProvider;
 
   /// The type system primitives
-  late final TypeSystemImpl _typeSystem;
+  @override
+  late final TypeSystemImpl typeSystem;
 
   /// The manager for the inheritance mappings.
   final InheritanceManager3 _inheritanceManager;
@@ -248,10 +254,9 @@
   late final ReturnTypeVerifier _returnTypeVerifier;
 
   /// Initialize a newly created error verifier.
-  ErrorVerifier(ErrorReporter errorReporter, this._currentLibrary,
-      this._typeProvider, this._inheritanceManager)
-      : _errorReporter = errorReporter,
-        _uninstantiatedBoundChecker =
+  ErrorVerifier(this.errorReporter, this._currentLibrary, this._typeProvider,
+      this._inheritanceManager)
+      : _uninstantiatedBoundChecker =
             _UninstantiatedBoundChecker(errorReporter),
         _requiredParametersVerifier = RequiredParametersVerifier(errorReporter),
         _duplicateDefinitionVerifier =
@@ -262,18 +267,18 @@
     _isInStaticVariableDeclaration = false;
     _isInConstructorInitializer = false;
     _intType = _typeProvider.intType;
-    _typeSystem = _currentLibrary.typeSystem;
+    typeSystem = _currentLibrary.typeSystem;
     _options = _currentLibrary.context.analysisOptions as AnalysisOptionsImpl;
     _typeArgumentsVerifier =
-        TypeArgumentsVerifier(_options, _currentLibrary, _errorReporter);
+        TypeArgumentsVerifier(_options, _currentLibrary, errorReporter);
     _constructorFieldsVerifier = ConstructorFieldsVerifier(
-      typeSystem: _typeSystem,
-      errorReporter: _errorReporter,
+      typeSystem: typeSystem,
+      errorReporter: errorReporter,
     );
     _returnTypeVerifier = ReturnTypeVerifier(
       typeProvider: _typeProvider as TypeProviderImpl,
-      typeSystem: _typeSystem,
-      errorReporter: _errorReporter,
+      typeSystem: typeSystem,
+      errorReporter: errorReporter,
     );
   }
 
@@ -306,6 +311,14 @@
       _featureSet?.isEnabled(Feature.non_nullable) ?? false;
 
   @override
+  List<DiagnosticMessage> computeWhyNotPromotedMessages(
+      Expression? expression,
+      SyntacticEntity errorEntity,
+      Map<DartType, NonPromotionReason>? whyNotPromoted) {
+    return [];
+  }
+
+  @override
   void visitAnnotation(Annotation node) {
     _checkForInvalidAnnotationFromDeferredLibrary(node);
     _checkForMissingJSLibAnnotation(node);
@@ -313,14 +326,6 @@
   }
 
   @override
-  void visitArgumentList(ArgumentList node) {
-    if (node.parent is! ExtensionOverride) {
-      _checkForArgumentTypesNotAssignableInList(node);
-    }
-    super.visitArgumentList(node);
-  }
-
-  @override
   void visitAsExpression(AsExpression node) {
     _checkForTypeAnnotationDeferredClass(node.type);
     super.visitAsExpression(node);
@@ -340,38 +345,21 @@
   void visitAssignmentExpression(AssignmentExpression node) {
     TokenType operatorType = node.operator.type;
     Expression lhs = node.leftHandSide;
-    Expression rhs = node.rightHandSide;
-    if (operatorType == TokenType.EQ ||
-        operatorType == TokenType.QUESTION_QUESTION_EQ) {
-      // Already handled in the assignment resolver.
-      if (lhs is! SimpleIdentifier) {
-        _checkForInvalidAssignment(lhs, rhs);
-      }
-    } else {
-      _checkForArgumentTypeNotAssignableForArgument(rhs);
-    }
     if (operatorType == TokenType.QUESTION_QUESTION_EQ) {
       _checkForDeadNullCoalesce(node.readType as TypeImpl, node.rightHandSide);
     }
     _checkForAssignmentToFinal(lhs);
-    if (lhs is IndexExpression) {
-      _checkIndexExpressionIndex(
-        lhs.index,
-        readElement: node.readElement as ExecutableElement?,
-        writeElement: node.writeElement as ExecutableElement?,
-      );
-    }
     super.visitAssignmentExpression(node);
   }
 
   @override
   void visitAwaitExpression(AwaitExpression node) {
     if (!_enclosingExecutable.isAsynchronous) {
-      _errorReporter.reportErrorForToken(
+      errorReporter.reportErrorForToken(
           CompileTimeErrorCode.AWAIT_IN_WRONG_CONTEXT, node.awaitKeyword);
     }
     if (_isNonNullableByDefault) {
-      _checkForUseOfVoidResult(node.expression);
+      checkForUseOfVoidResult(node.expression);
     }
     _checkForAwaitInLateLocalVariableInitializer(node);
     super.visitAwaitExpression(node);
@@ -382,14 +370,9 @@
     Token operator = node.operator;
     TokenType type = operator.type;
     if (type == TokenType.AMPERSAND_AMPERSAND || type == TokenType.BAR_BAR) {
-      _checkForUseOfVoidResult(node.rightOperand);
-    } else if (type == TokenType.EQ_EQ || type == TokenType.BANG_EQ) {
-      _checkForArgumentTypeNotAssignableForArgument(node.rightOperand,
-          promoteParameterToNullable: true);
-    } else if (type != TokenType.QUESTION_QUESTION) {
-      _checkForArgumentTypeNotAssignableForArgument(node.rightOperand);
+      checkForUseOfVoidResult(node.rightOperand);
     } else {
-      _checkForArgumentTypeNotAssignableForArgument(node.rightOperand);
+      // Assignability checking is done by the resolver.
     }
 
     if (type == TokenType.QUESTION_QUESTION) {
@@ -397,7 +380,7 @@
           node.leftOperand.staticType as TypeImpl, node.rightOperand);
     }
 
-    _checkForUseOfVoidResult(node.leftOperand);
+    checkForUseOfVoidResult(node.leftOperand);
 
     super.visitBinaryExpression(node);
   }
@@ -426,7 +409,7 @@
     if (labelNode != null) {
       var labelElement = labelNode.staticElement;
       if (labelElement is LabelElementImpl && labelElement.isOnSwitchMember) {
-        _errorReporter.reportErrorForNode(
+        errorReporter.reportErrorForNode(
             CompileTimeErrorCode.BREAK_LABEL_ON_SWITCH_MEMBER, labelNode);
       }
     }
@@ -547,7 +530,6 @@
       var staticElement = fieldName.staticElement;
       _checkForInvalidField(node, fieldName, staticElement);
       if (staticElement is FieldElement) {
-        _checkForFieldInitializerNotAssignable(node, staticElement);
         _checkForAbstractOrExternalFieldConstructorInitializer(
             node.fieldName, staticElement);
       }
@@ -564,7 +546,7 @@
       var labelElement = labelNode.staticElement;
       if (labelElement is LabelElementImpl &&
           labelElement.isOnSwitchStatement) {
-        _errorReporter.reportErrorForNode(
+        errorReporter.reportErrorForNode(
             CompileTimeErrorCode.CONTINUE_LABEL_ON_SWITCH, labelNode);
       }
     }
@@ -572,7 +554,7 @@
 
   @override
   void visitDefaultFormalParameter(DefaultFormalParameter node) {
-    _checkForInvalidAssignment(node.identifier, node.defaultValue);
+    checkForInvalidAssignment(node.identifier, node.defaultValue);
     super.visitDefaultFormalParameter(node);
   }
 
@@ -619,8 +601,8 @@
     _checkForFinalNotInitializedInClass(node.members);
 
     GetterSetterTypesVerifier(
-      typeSystem: _typeSystem,
-      errorReporter: _errorReporter,
+      typeSystem: typeSystem,
+      errorReporter: errorReporter,
     ).checkExtension(node);
 
     final name = node.name;
@@ -641,7 +623,7 @@
         !node.isStatic && !node.fields.isLate;
     if (!_isInStaticVariableDeclaration) {
       if (fields.isConst) {
-        _errorReporter.reportErrorForToken(
+        errorReporter.reportErrorForToken(
             CompileTimeErrorCode.CONST_INSTANCE_FIELD, fields.keyword!);
       }
     }
@@ -679,7 +661,7 @@
     DeclaredIdentifier loopVariable = node.loopVariable;
     if (_checkForEachParts(node, loopVariable.identifier)) {
       if (loopVariable.isConst) {
-        _errorReporter.reportErrorForToken(
+        errorReporter.reportErrorForToken(
             CompileTimeErrorCode.FOR_IN_WITH_CONST_VARIABLE,
             loopVariable.keyword!);
       }
@@ -722,8 +704,8 @@
       TypeAnnotation? returnType = node.returnType;
       if (node.isGetter) {
         GetterSetterTypesVerifier(
-          typeSystem: _typeSystem,
-          errorReporter: _errorReporter,
+          typeSystem: typeSystem,
+          errorReporter: errorReporter,
         ).checkGetter(
             node.name, node.declaredElement as PropertyAccessorElement);
       }
@@ -765,14 +747,7 @@
     }
 
     DartType expressionType = functionExpression.typeOrThrow;
-    if (!_checkForUseOfVoidResult(functionExpression) &&
-        !_checkForUseOfNever(functionExpression) &&
-        node.staticElement == null &&
-        !_isFunctionType(expressionType)) {
-      _errorReporter.reportErrorForNode(
-          CompileTimeErrorCode.INVOCATION_OF_NON_FUNCTION_EXPRESSION,
-          functionExpression);
-    } else if (expressionType is FunctionType) {
+    if (expressionType is FunctionType) {
       _typeArgumentsVerifier.checkFunctionExpressionInvocation(node);
     }
     _requiredParametersVerifier.visitFunctionExpressionInvocation(node);
@@ -803,10 +778,8 @@
         DartType parameterType = node.declaredElement!.type;
         if (parameterType is FunctionType &&
             parameterType.returnType.isDynamic) {
-          _errorReporter.reportErrorForNode(
-              LanguageCode.IMPLICIT_DYNAMIC_RETURN,
-              node.identifier,
-              [node.identifier]);
+          errorReporter.reportErrorForNode(LanguageCode.IMPLICIT_DYNAMIC_RETURN,
+              node.identifier, [node.identifier]);
         }
       }
 
@@ -850,12 +823,6 @@
 
   @override
   void visitIndexExpression(IndexExpression node) {
-    _checkIndexExpressionIndex(
-      node.index,
-      readElement: node.staticElement,
-      writeElement: null,
-    );
-
     if (node.isNullAware) {
       _checkForUnnecessaryNullAware(
         node.realTarget,
@@ -870,7 +837,7 @@
   void visitInstanceCreationExpression(InstanceCreationExpression node) {
     ConstructorName constructorName = node.constructorName;
     TypeName typeName = constructorName.type;
-    DartType type = typeName.type!;
+    DartType type = typeName.typeOrThrow;
     if (type is InterfaceType) {
       _checkForConstOrNewWithAbstractClass(node, typeName, type);
       _checkForConstOrNewWithEnum(node, typeName, type);
@@ -897,14 +864,14 @@
 
   @override
   void visitInterpolationExpression(InterpolationExpression node) {
-    _checkForUseOfVoidResult(node.expression);
+    checkForUseOfVoidResult(node.expression);
     super.visitInterpolationExpression(node);
   }
 
   @override
   void visitIsExpression(IsExpression node) {
     _checkForTypeAnnotationDeferredClass(node.type);
-    _checkForUseOfVoidResult(node.expression);
+    checkForUseOfVoidResult(node.expression);
     super.visitIsExpression(node);
   }
 
@@ -922,8 +889,8 @@
       var returnType = node.returnType;
       if (node.isStatic && node.isGetter) {
         GetterSetterTypesVerifier(
-          typeSystem: _typeSystem,
-          errorReporter: _errorReporter,
+          typeSystem: typeSystem,
+          errorReporter: errorReporter,
         ).checkGetter(
             node.name, node.declaredElement as PropertyAccessorElement);
       }
@@ -1004,7 +971,7 @@
     // TODO(brianwilkerson) Figure out the right rule for when 'native' is
     // allowed.
     if (!_isInSystemLibrary) {
-      _errorReporter.reportErrorForNode(
+      errorReporter.reportErrorForNode(
           ParserErrorCode.NATIVE_CLAUSE_IN_NON_SDK_CODE, node);
     }
     super.visitNativeClause(node);
@@ -1020,19 +987,12 @@
   void visitPostfixExpression(PostfixExpression node) {
     var operand = node.operand;
     if (node.operator.type == TokenType.BANG) {
-      _checkForUseOfVoidResult(node);
+      checkForUseOfVoidResult(node);
       _checkForUnnecessaryNullAware(operand, node.operator);
     } else {
       _checkForAssignmentToFinal(operand);
       _checkForIntNotAssignable(operand);
     }
-    if (operand is IndexExpression) {
-      _checkIndexExpressionIndex(
-        operand.index,
-        readElement: node.readElement as ExecutableElement?,
-        writeElement: node.writeElement as ExecutableElement?,
-      );
-    }
     super.visitPostfixExpression(node);
   }
 
@@ -1055,16 +1015,9 @@
       if (operatorType.isIncrementOperator) {
         _checkForAssignmentToFinal(operand);
       }
-      _checkForUseOfVoidResult(operand);
+      checkForUseOfVoidResult(operand);
       _checkForIntNotAssignable(operand);
     }
-    if (operand is IndexExpression) {
-      _checkIndexExpressionIndex(
-        operand.index,
-        readElement: node.readElement as ExecutableElement?,
-        writeElement: node.writeElement as ExecutableElement?,
-      );
-    }
     super.visitPrefixExpression(node);
   }
 
@@ -1203,7 +1156,7 @@
   @override
   void visitThrowExpression(ThrowExpression node) {
     _checkForConstEvalThrowsException(node);
-    _checkForUseOfVoidResult(node.expression);
+    checkForUseOfVoidResult(node.expression);
     _checkForThrowOfInvalidType(node);
     super.visitThrowExpression(node);
   }
@@ -1258,7 +1211,6 @@
     SimpleIdentifier nameNode = node.name;
     var initializerNode = node.initializer;
     // do checks
-    _checkForInvalidAssignment(nameNode, initializerNode);
     _checkForImplicitDynamicIdentifier(node, nameNode);
     _checkForAbstractOrExternalVariableInitializer(node);
     // visit name
@@ -1345,7 +1297,7 @@
       for (int i = 0; i < count; i++) {
         var deferredToken = directives[i].deferredKeyword;
         if (deferredToken != null) {
-          _errorReporter.reportErrorForToken(
+          errorReporter.reportErrorForToken(
               CompileTimeErrorCode.SHARED_DEFERRED_PREFIX, deferredToken);
         }
       }
@@ -1355,11 +1307,11 @@
   void _checkForAbstractOrExternalFieldConstructorInitializer(
       AstNode node, FieldElement fieldElement) {
     if (fieldElement.isAbstract) {
-      _errorReporter.reportErrorForNode(
+      errorReporter.reportErrorForNode(
           CompileTimeErrorCode.ABSTRACT_FIELD_CONSTRUCTOR_INITIALIZER, node);
     }
     if (fieldElement.isExternal) {
-      _errorReporter.reportErrorForNode(
+      errorReporter.reportErrorForNode(
           CompileTimeErrorCode.EXTERNAL_FIELD_CONSTRUCTOR_INITIALIZER, node);
     }
   }
@@ -1370,16 +1322,16 @@
     if (node.initializer != null) {
       if (declaredElement is FieldElement) {
         if (declaredElement.isAbstract) {
-          _errorReporter.reportErrorForNode(
+          errorReporter.reportErrorForNode(
               CompileTimeErrorCode.ABSTRACT_FIELD_INITIALIZER, node.name);
         }
         if (declaredElement.isExternal) {
-          _errorReporter.reportErrorForNode(
+          errorReporter.reportErrorForNode(
               CompileTimeErrorCode.EXTERNAL_FIELD_INITIALIZER, node.name);
         }
       } else if (declaredElement is TopLevelVariableElement) {
         if (declaredElement.isExternal) {
-          _errorReporter.reportErrorForNode(
+          errorReporter.reportErrorForNode(
               CompileTimeErrorCode.EXTERNAL_VARIABLE_INITIALIZER, node.name);
         }
       }
@@ -1400,7 +1352,7 @@
         mixinNameIndex < withClause.mixinTypes.length;
         mixinNameIndex++) {
       TypeName mixinName = withClause.mixinTypes[mixinNameIndex];
-      DartType mixinType = mixinName.type!;
+      DartType mixinType = mixinName.typeOrThrow;
       if (mixinType is InterfaceType) {
         mixinTypeIndex++;
         if (_checkForExtendsOrImplementsDisallowedClass(
@@ -1450,14 +1402,14 @@
       // If the element is null, we check for the
       // REDIRECT_TO_MISSING_CONSTRUCTOR case
       TypeName constructorTypeName = redirectedConstructor.type;
-      DartType redirectedType = constructorTypeName.type!;
+      DartType redirectedType = constructorTypeName.typeOrThrow;
       if (redirectedType.element != null && !redirectedType.isDynamic) {
         // Prepare the constructor name
         String constructorStrName = constructorTypeName.name.name;
         if (redirectedConstructor.name != null) {
           constructorStrName += ".${redirectedConstructor.name!.name}";
         }
-        _errorReporter.reportErrorForNode(
+        errorReporter.reportErrorForNode(
             CompileTimeErrorCode.REDIRECT_TO_MISSING_CONSTRUCTOR,
             redirectedConstructor,
             [constructorStrName, redirectedType]);
@@ -1470,16 +1422,16 @@
     // Report specific problem when return type is incompatible
     FunctionType constructorType = declaration.declaredElement!.type;
     DartType constructorReturnType = constructorType.returnType;
-    if (!_typeSystem.isAssignableTo(
+    if (!typeSystem.isAssignableTo(
         redirectedReturnType, constructorReturnType)) {
-      _errorReporter.reportErrorForNode(
+      errorReporter.reportErrorForNode(
           CompileTimeErrorCode.REDIRECT_TO_INVALID_RETURN_TYPE,
           redirectedConstructor,
           [redirectedReturnType, constructorReturnType]);
       return;
-    } else if (!_typeSystem.isSubtypeOf(redirectedType, constructorType)) {
+    } else if (!typeSystem.isSubtypeOf(redirectedType, constructorType)) {
       // Check parameters.
-      _errorReporter.reportErrorForNode(
+      errorReporter.reportErrorForNode(
           CompileTimeErrorCode.REDIRECT_TO_INVALID_FUNCTION_TYPE,
           redirectedConstructor,
           [redirectedType, constructorType]);
@@ -1506,7 +1458,7 @@
       var element = definedNames[name]!;
       var prevElement = _exportedElements[name];
       if (prevElement != null && prevElement != element) {
-        _errorReporter.reportErrorForNode(
+        errorReporter.reportErrorForNode(
             CompileTimeErrorCode.AMBIGUOUS_EXPORT, directive.uri, [
           name,
           prevElement.library!.definingCompilationUnit.source.uri,
@@ -1529,125 +1481,11 @@
       var libraryNames =
           conflictingMembers.map((e) => _getLibraryName(e)).toList();
       libraryNames.sort();
-      _errorReporter.reportErrorForNode(CompileTimeErrorCode.AMBIGUOUS_IMPORT,
+      errorReporter.reportErrorForNode(CompileTimeErrorCode.AMBIGUOUS_IMPORT,
           node, [name, StringUtilities.printListOfQuotedNames(libraryNames)]);
     }
   }
 
-  /// Verify that the given [expression] can be assigned to its corresponding
-  /// parameters. The [expectedStaticType] is the expected static type of the
-  /// parameter. The [actualStaticType] is the actual static type of the
-  /// argument.
-  void _checkForArgumentTypeNotAssignable(
-      Expression expression,
-      DartType? expectedStaticType,
-      DartType actualStaticType,
-      ErrorCode errorCode) {
-    // Warning case: test static type information
-    if (expectedStaticType != null) {
-      if (!expectedStaticType.isVoid && _checkForUseOfVoidResult(expression)) {
-        return;
-      }
-
-      _checkForAssignableExpressionAtType(
-          expression, actualStaticType, expectedStaticType, errorCode);
-    }
-  }
-
-  /// Verify that the given [argument] can be assigned to its corresponding
-  /// parameter.
-  ///
-  /// This method corresponds to
-  /// [BestPracticesVerifier.checkForArgumentTypeNotAssignableForArgument].
-  ///
-  /// See [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE].
-  void _checkForArgumentTypeNotAssignableForArgument(Expression argument,
-      {bool promoteParameterToNullable = false}) {
-    _checkForArgumentTypeNotAssignableForArgument2(
-      argument: argument,
-      parameter: argument.staticParameterElement,
-      promoteParameterToNullable: promoteParameterToNullable,
-    );
-  }
-
-  void _checkForArgumentTypeNotAssignableForArgument2({
-    required Expression argument,
-    required ParameterElement? parameter,
-    required bool promoteParameterToNullable,
-  }) {
-    var staticParameterType = parameter?.type;
-    if (promoteParameterToNullable && staticParameterType != null) {
-      staticParameterType =
-          _typeSystem.makeNullable(staticParameterType as TypeImpl);
-    }
-    _checkForArgumentTypeNotAssignableWithExpectedTypes(argument,
-        staticParameterType, CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE);
-  }
-
-  /// Verify that the given [expression] can be assigned to its corresponding
-  /// parameters.
-  ///
-  /// See [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE],
-  /// [CompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE],
-  /// [StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE],
-  /// [CompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE],
-  /// [CompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE],
-  /// [StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE], and
-  /// [StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE].
-  void _checkForArgumentTypeNotAssignableWithExpectedTypes(
-      Expression expression,
-      DartType? expectedStaticType,
-      ErrorCode errorCode) {
-    _checkForArgumentTypeNotAssignable(
-        expression, expectedStaticType, expression.typeOrThrow, errorCode);
-  }
-
-  /// Verify that the arguments in the given [argumentList] can be assigned to
-  /// their corresponding parameters.
-  ///
-  /// This method corresponds to
-  /// [BestPracticesVerifier.checkForArgumentTypesNotAssignableInList].
-  ///
-  /// See [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE].
-  void _checkForArgumentTypesNotAssignableInList(ArgumentList argumentList) {
-    for (Expression argument in argumentList.arguments) {
-      _checkForArgumentTypeNotAssignableForArgument(argument);
-    }
-  }
-
-  bool _checkForAssignableExpression(
-      Expression expression, DartType expectedStaticType, ErrorCode errorCode) {
-    DartType actualStaticType = expression.typeOrThrow;
-    return _checkForAssignableExpressionAtType(
-        expression, actualStaticType, expectedStaticType, errorCode);
-  }
-
-  bool _checkForAssignableExpressionAtType(
-      Expression expression,
-      DartType actualStaticType,
-      DartType expectedStaticType,
-      ErrorCode errorCode) {
-    if (!_typeSystem.isAssignableTo(actualStaticType, expectedStaticType)) {
-      AstNode getErrorNode(AstNode node) {
-        if (node is CascadeExpression) {
-          return getErrorNode(node.target);
-        }
-        if (node is ParenthesizedExpression) {
-          return getErrorNode(node.expression);
-        }
-        return node;
-      }
-
-      _errorReporter.reportErrorForNode(
-        errorCode,
-        getErrorNode(expression),
-        [actualStaticType, expectedStaticType],
-      );
-      return false;
-    }
-    return true;
-  }
-
   /// Verify that the given [expression] is not final.
   ///
   /// See [StaticWarningCode.ASSIGNMENT_TO_CONST],
@@ -1680,7 +1518,7 @@
     // check if element is assignable
     if (element is VariableElement) {
       if (element.isConst) {
-        _errorReporter.reportErrorForNode(
+        errorReporter.reportErrorForNode(
           CompileTimeErrorCode.ASSIGNMENT_TO_CONST,
           expression,
         );
@@ -1688,7 +1526,7 @@
         if (_isNonNullableByDefault) {
           // Handled during resolution, with flow analysis.
         } else {
-          _errorReporter.reportErrorForNode(
+          errorReporter.reportErrorForNode(
             CompileTimeErrorCode.ASSIGNMENT_TO_FINAL_LOCAL,
             expression,
             [element.name],
@@ -1698,40 +1536,40 @@
     } else if (element is PropertyAccessorElement && element.isGetter) {
       var variable = element.variable;
       if (variable.isConst) {
-        _errorReporter.reportErrorForNode(
+        errorReporter.reportErrorForNode(
           CompileTimeErrorCode.ASSIGNMENT_TO_CONST,
           expression,
         );
       } else if (variable is FieldElement && variable.isSynthetic) {
-        _errorReporter.reportErrorForNode(
+        errorReporter.reportErrorForNode(
           CompileTimeErrorCode.ASSIGNMENT_TO_FINAL_NO_SETTER,
           highlightedNode,
           [variable.name, variable.enclosingElement.displayName],
         );
       } else {
-        _errorReporter.reportErrorForNode(
+        errorReporter.reportErrorForNode(
           CompileTimeErrorCode.ASSIGNMENT_TO_FINAL,
           highlightedNode,
           [variable.name],
         );
       }
     } else if (element is FunctionElement) {
-      _errorReporter.reportErrorForNode(
+      errorReporter.reportErrorForNode(
           CompileTimeErrorCode.ASSIGNMENT_TO_FUNCTION, expression);
     } else if (element is MethodElement) {
-      _errorReporter.reportErrorForNode(
+      errorReporter.reportErrorForNode(
           CompileTimeErrorCode.ASSIGNMENT_TO_METHOD, expression);
     } else if (element is ClassElement ||
         element is DynamicElementImpl ||
         element is TypeParameterElement) {
-      _errorReporter.reportErrorForNode(
+      errorReporter.reportErrorForNode(
           CompileTimeErrorCode.ASSIGNMENT_TO_TYPE, expression);
     }
   }
 
   void _checkForAwaitInLateLocalVariableInitializer(AwaitExpression node) {
     if (_isInLateLocalVariable.last) {
-      _errorReporter.reportErrorForToken(
+      errorReporter.reportErrorForToken(
         CompileTimeErrorCode.AWAIT_IN_LATE_LOCAL_VARIABLE_INITIALIZER,
         node.awaitKeyword,
       );
@@ -1745,14 +1583,14 @@
     var withClause = node.withClause;
 
     if (node.name.name == "Function") {
-      _errorReporter.reportErrorForNode(
+      errorReporter.reportErrorForNode(
           HintCode.DEPRECATED_FUNCTION_CLASS_DECLARATION, node.name);
     }
 
     if (extendsClause != null) {
       var superElement = extendsClause.superclass.name.staticElement;
       if (superElement != null && superElement.name == "Function") {
-        _errorReporter.reportErrorForNode(
+        errorReporter.reportErrorForNode(
             HintCode.DEPRECATED_EXTENDS_FUNCTION, extendsClause.superclass);
       }
     }
@@ -1761,7 +1599,7 @@
       for (TypeName type in withClause.mixinTypes) {
         var mixinElement = type.name.staticElement;
         if (mixinElement != null && mixinElement.name == "Function") {
-          _errorReporter.reportErrorForNode(
+          errorReporter.reportErrorForNode(
               HintCode.DEPRECATED_MIXIN_FUNCTION, type);
         }
       }
@@ -1779,7 +1617,7 @@
       SimpleIdentifier identifier, ErrorCode errorCode) {
     Token token = identifier.token;
     if (token.type.isKeyword && token.keyword?.isPseudo != true) {
-      _errorReporter
+      errorReporter
           .reportErrorForNode(errorCode, identifier, [identifier.name]);
     }
   }
@@ -1822,7 +1660,7 @@
       }
     }
 
-    _errorReporter.reportErrorForToken(
+    errorReporter.reportErrorForToken(
         CompileTimeErrorCode.CASE_BLOCK_NOT_TERMINATED, switchCase.keyword);
   }
 
@@ -1866,14 +1704,14 @@
           _enclosingClass!, Name(libraryUri, '$name='));
 
       if (method.isStatic && inherited != null) {
-        _errorReporter.reportErrorForElement(
+        errorReporter.reportErrorForElement(
             CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, method, [
           _enclosingClass!.displayName,
           name,
           inherited.enclosingElement.displayName,
         ]);
       } else if (inherited is PropertyAccessorElement) {
-        _errorReporter.reportErrorForElement(
+        errorReporter.reportErrorForElement(
             CompileTimeErrorCode.CONFLICTING_METHOD_AND_FIELD, method, [
           _enclosingClass!.displayName,
           name,
@@ -1893,14 +1731,14 @@
           _enclosingClass!, Name(libraryUri, '$name='));
 
       if (accessor.isStatic && inherited != null) {
-        _errorReporter.reportErrorForElement(
+        errorReporter.reportErrorForElement(
             CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, accessor, [
           _enclosingClass!.displayName,
           name,
           inherited.enclosingElement.displayName,
         ]);
       } else if (inherited is MethodElement) {
-        _errorReporter.reportErrorForElement(
+        errorReporter.reportErrorForElement(
             CompileTimeErrorCode.CONFLICTING_FIELD_AND_METHOD, accessor, [
           _enclosingClass!.displayName,
           name,
@@ -1921,7 +1759,7 @@
       String name = typeParameter.name;
       // name is same as the name of the enclosing class
       if (_enclosingClass!.name == name) {
-        _errorReporter.reportErrorForElement(
+        errorReporter.reportErrorForElement(
             CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_CLASS,
             typeParameter,
             [name]);
@@ -1930,7 +1768,7 @@
       if (_enclosingClass!.getMethod(name) != null ||
           _enclosingClass!.getGetter(name) != null ||
           _enclosingClass!.getSetter(name) != null) {
-        _errorReporter.reportErrorForElement(
+        errorReporter.reportErrorForElement(
             CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER_CLASS,
             typeParameter,
             [name]);
@@ -1948,7 +1786,7 @@
       String name = typeParameter.name;
       // name is same as the name of the enclosing class
       if (_enclosingExtension!.name == name) {
-        _errorReporter.reportErrorForElement(
+        errorReporter.reportErrorForElement(
             CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_EXTENSION,
             typeParameter,
             [name]);
@@ -1957,7 +1795,7 @@
       if (_enclosingExtension!.getMethod(name) != null ||
           _enclosingExtension!.getGetter(name) != null ||
           _enclosingExtension!.getSetter(name) != null) {
-        _errorReporter.reportErrorForElement(
+        errorReporter.reportErrorForElement(
             CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER_EXTENSION,
             typeParameter,
             [name]);
@@ -1973,7 +1811,7 @@
 
     for (var error in errors) {
       if (error is IncompatibleInterfacesClassHierarchyError) {
-        _errorReporter.reportErrorForNode(
+        errorReporter.reportErrorForNode(
           CompileTimeErrorCode.CONFLICTING_GENERIC_INTERFACES,
           node,
           [
@@ -2012,7 +1850,7 @@
     }
     if (instanceFields.length == 1) {
       var field = instanceFields.single;
-      _errorReporter.reportErrorForNode(
+      errorReporter.reportErrorForNode(
           CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_MIXIN_WITH_FIELD,
           constructor.returnType,
           ["'${field.enclosingElement.name}.${field.name}'"]);
@@ -2021,7 +1859,7 @@
       var fieldNames = instanceFields
           .map((field) => "'${field.enclosingElement.name}.${field.name}'")
           .join(', ');
-      _errorReporter.reportErrorForNode(
+      errorReporter.reportErrorForNode(
           CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_MIXIN_WITH_FIELDS,
           constructor.returnType,
           [fieldNames]);
@@ -2035,7 +1873,7 @@
         if (element == null || element.isConst) {
           return;
         }
-        _errorReporter.reportErrorForNode(
+        errorReporter.reportErrorForNode(
             CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_CONST_SUPER,
             initializer,
             [element.enclosingElement.displayName]);
@@ -2056,7 +1894,7 @@
     }
 
     // default constructor is not 'const', report problem
-    _errorReporter.reportErrorForNode(
+    errorReporter.reportErrorForNode(
         CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_CONST_SUPER,
         constructor.returnType,
         [supertype]);
@@ -2080,7 +1918,7 @@
     //  CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD when either
     //  CONST_CONSTRUCTOR_WITH_NON_CONST_SUPER or
     //  CONST_CONSTRUCTOR_WITH_MIXIN_WITH_FIELD is also generated.
-    _errorReporter.reportErrorForName(
+    errorReporter.reportErrorForName(
         CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD,
         constructor);
   }
@@ -2094,7 +1932,7 @@
   void _checkForConstDeferredClass(InstanceCreationExpression expression,
       ConstructorName constructorName, TypeName typeName) {
     if (typeName.isDeferred) {
-      _errorReporter.reportErrorForNode(
+      errorReporter.reportErrorForNode(
           CompileTimeErrorCode.CONST_DEFERRED_CLASS,
           constructorName,
           [typeName.name.name]);
@@ -2107,7 +1945,7 @@
   /// See [CompileTimeErrorCode.CONST_CONSTRUCTOR_THROWS_EXCEPTION].
   void _checkForConstEvalThrowsException(ThrowExpression expression) {
     if (_enclosingExecutable.isConstConstructor) {
-      _errorReporter.reportErrorForNode(
+      errorReporter.reportErrorForNode(
           CompileTimeErrorCode.CONST_CONSTRUCTOR_THROWS_EXCEPTION, expression);
     }
   }
@@ -2127,10 +1965,10 @@
         bool isImplicit =
             (expression as InstanceCreationExpressionImpl).isImplicit;
         if (!isImplicit) {
-          _errorReporter.reportErrorForNode(
+          errorReporter.reportErrorForNode(
               CompileTimeErrorCode.INSTANTIATE_ABSTRACT_CLASS, typeName);
         } else {
-          _errorReporter.reportErrorForNode(
+          errorReporter.reportErrorForNode(
               CompileTimeErrorCode.INSTANTIATE_ABSTRACT_CLASS, typeName);
         }
       }
@@ -2147,7 +1985,7 @@
   void _checkForConstOrNewWithEnum(InstanceCreationExpression expression,
       TypeName typeName, InterfaceType type) {
     if (type.element.isEnum) {
-      _errorReporter.reportErrorForNode(
+      errorReporter.reportErrorForNode(
           CompileTimeErrorCode.INSTANTIATE_ENUM, typeName);
     }
   }
@@ -2156,7 +1994,7 @@
   void _checkForConstOrNewWithMixin(InstanceCreationExpression expression,
       TypeName typeName, InterfaceType type) {
     if (type.element.isMixin) {
-      _errorReporter.reportErrorForNode(
+      errorReporter.reportErrorForNode(
           CompileTimeErrorCode.MIXIN_INSTANTIATE, typeName);
     }
   }
@@ -2172,10 +2010,10 @@
     var constructorElement = expression.constructorName.staticElement;
     if (constructorElement != null && !constructorElement.isConst) {
       if (expression.keyword != null) {
-        _errorReporter.reportErrorForToken(
+        errorReporter.reportErrorForToken(
             CompileTimeErrorCode.CONST_WITH_NON_CONST, expression.keyword!);
       } else {
-        _errorReporter.reportErrorForNode(
+        errorReporter.reportErrorForNode(
             CompileTimeErrorCode.CONST_WITH_NON_CONST, expression);
       }
     }
@@ -2199,7 +2037,7 @@
     if (constructorName.staticElement != null) {
       return;
     }
-    DartType type = typeName.type!;
+    DartType type = typeName.typeOrThrow;
     if (type is InterfaceType) {
       ClassElement element = type.element;
       if (element.isEnum) {
@@ -2211,12 +2049,12 @@
     // report as named or default constructor absence
     var name = constructorName.name;
     if (name != null) {
-      _errorReporter.reportErrorForNode(
+      errorReporter.reportErrorForNode(
           CompileTimeErrorCode.CONST_WITH_UNDEFINED_CONSTRUCTOR,
           name,
           [className, name]);
     } else {
-      _errorReporter.reportErrorForNode(
+      errorReporter.reportErrorForNode(
           CompileTimeErrorCode.CONST_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT,
           constructorName,
           [className]);
@@ -2226,8 +2064,8 @@
   void _checkForDeadNullCoalesce(TypeImpl lhsType, Expression rhs) {
     if (!_isNonNullableByDefault) return;
 
-    if (_typeSystem.isStrictlyNonNullable(lhsType)) {
-      _errorReporter.reportErrorForNode(
+    if (typeSystem.isStrictlyNonNullable(lhsType)) {
+      errorReporter.reportErrorForNode(
         StaticWarningCode.DEAD_NULL_AWARE_EXPRESSION,
         rhs,
       );
@@ -2240,7 +2078,7 @@
       ImportDirective directive, ImportElement importElement) {
     for (var element in importElement.namespace.definedNames.values) {
       if (element is ExtensionElement) {
-        _errorReporter.reportErrorForNode(
+        errorReporter.reportErrorForNode(
           CompileTimeErrorCode.DEFERRED_IMPORT_OF_EXTENSION,
           directive.uri,
         );
@@ -2285,7 +2123,7 @@
   /// Return `true` if the caller should continue checking the rest of the
   /// information in the for-each part.
   bool _checkForEachParts(ForEachParts node, SimpleIdentifier variable) {
-    if (_checkForUseOfVoidResult(node.iterable)) {
+    if (checkForUseOfVoidResult(node.iterable)) {
       return false;
     }
 
@@ -2293,7 +2131,7 @@
 
     // TODO(scheglov) use NullableDereferenceVerifier
     if (_isNonNullableByDefault) {
-      if (_typeSystem.isNullable(iterableType)) {
+      if (typeSystem.isNullable(iterableType)) {
         return false;
       }
     }
@@ -2327,12 +2165,12 @@
         ? _typeProvider.streamDynamicType
         : _typeProvider.iterableDynamicType;
 
-    if (_typeSystem.isTop(iterableType)) {
+    if (typeSystem.isTop(iterableType)) {
       iterableType = requiredSequenceType;
     }
 
-    if (!_typeSystem.isAssignableTo(iterableType, requiredSequenceType)) {
-      _errorReporter.reportErrorForNode(
+    if (!typeSystem.isAssignableTo(iterableType, requiredSequenceType)) {
+      errorReporter.reportErrorForNode(
         CompileTimeErrorCode.FOR_IN_OF_INVALID_TYPE,
         node.iterable,
         [iterableType, loopTypeName],
@@ -2355,8 +2193,8 @@
       return true;
     }
 
-    if (!_typeSystem.isAssignableTo(sequenceElementType, variableType)) {
-      _errorReporter.reportErrorForNode(
+    if (!typeSystem.isAssignableTo(sequenceElementType, variableType)) {
+      errorReporter.reportErrorForNode(
         CompileTimeErrorCode.FOR_IN_OF_INVALID_ELEMENT_TYPE,
         node.iterable,
         [iterableType, loopTypeName, variableType],
@@ -2394,7 +2232,7 @@
       return;
     }
 
-    _errorReporter.reportErrorForNode(
+    errorReporter.reportErrorForNode(
         CompileTimeErrorCode.EXPORT_INTERNAL_LIBRARY,
         directive,
         [directive.uri]);
@@ -2417,7 +2255,7 @@
         continue;
       }
       if (!element.library!.isNonNullableByDefault) {
-        _errorReporter.reportErrorForNode(
+        errorReporter.reportErrorForNode(
           CompileTimeErrorCode.EXPORT_LEGACY_SYMBOL,
           node.uri,
           [element.displayName],
@@ -2468,7 +2306,7 @@
       return false;
     }
     if (typeName.isDeferred) {
-      _errorReporter.reportErrorForNode(errorCode, typeName);
+      errorReporter.reportErrorForNode(errorCode, typeName);
       return true;
     }
     return false;
@@ -2491,8 +2329,9 @@
     if (_currentLibrary.source.isInSystemLibrary) {
       return false;
     }
-    return typeName.type is InterfaceType &&
-        _typeProvider.nonSubtypableClasses.contains(typeName.type!.element);
+    var type = typeName.type;
+    return type is InterfaceType &&
+        _typeProvider.isNonSubtypableClass(type.element);
   }
 
   void _checkForExtensionDeclaresMemberOfObject(MethodDeclaration node) {
@@ -2504,70 +2343,13 @@
         name == 'toString' ||
         name == 'runtimeType' ||
         name == 'noSuchMethod') {
-      _errorReporter.reportErrorForNode(
+      errorReporter.reportErrorForNode(
         CompileTimeErrorCode.EXTENSION_DECLARES_MEMBER_OF_OBJECT,
         node.name,
       );
     }
   }
 
-  /// Verify that the given constructor field [initializer] has compatible field
-  /// and initializer expression types. The [fieldElement] is the static element
-  /// from the name in the [ConstructorFieldInitializer].
-  ///
-  /// See [CompileTimeErrorCode.CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE], and
-  /// [StaticWarningCode.FIELD_INITIALIZER_NOT_ASSIGNABLE].
-  void _checkForFieldInitializerNotAssignable(
-      ConstructorFieldInitializer initializer, FieldElement fieldElement) {
-    // prepare field type
-    DartType fieldType = fieldElement.type;
-    // prepare expression type
-    Expression expression = initializer.expression;
-    // test the static type of the expression
-    DartType staticType = expression.typeOrThrow;
-    if (_typeSystem.isAssignableTo(staticType, fieldType)) {
-      if (!fieldType.isVoid) {
-        _checkForUseOfVoidResult(expression);
-      }
-      return;
-    }
-    // report problem
-    if (_enclosingExecutable.isConstConstructor) {
-      // TODO(paulberry): this error should be based on the actual type of the
-      // constant, not the static type.  See dartbug.com/21119.
-      _errorReporter.reportErrorForNode(
-          CompileTimeErrorCode.CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE,
-          expression,
-          [staticType, fieldType]);
-    }
-    _errorReporter.reportErrorForNode(
-        CompileTimeErrorCode.FIELD_INITIALIZER_NOT_ASSIGNABLE,
-        expression,
-        [staticType, fieldType]);
-    // TODO(brianwilkerson) Define a hint corresponding to these errors and
-    // report it if appropriate.
-//        // test the propagated type of the expression
-//        Type propagatedType = expression.getPropagatedType();
-//        if (propagatedType != null && propagatedType.isAssignableTo(fieldType)) {
-//          return false;
-//        }
-//        // report problem
-//        if (isEnclosingConstructorConst) {
-//          errorReporter.reportTypeErrorForNode(
-//              CompileTimeErrorCode.CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE,
-//              expression,
-//              propagatedType == null ? staticType : propagatedType,
-//              fieldType);
-//        } else {
-//          errorReporter.reportTypeErrorForNode(
-//              StaticWarningCode.FIELD_INITIALIZER_NOT_ASSIGNABLE,
-//              expression,
-//              propagatedType == null ? staticType : propagatedType,
-//              fieldType);
-//        }
-//        return true;
-  }
-
   /// Verify that the given field formal [parameter] is in a constructor
   /// declaration.
   ///
@@ -2584,7 +2366,7 @@
     if (constructor is ConstructorDeclaration) {
       // constructor cannot be a factory
       if (constructor.factoryKeyword != null) {
-        _errorReporter.reportErrorForNode(
+        errorReporter.reportErrorForNode(
             CompileTimeErrorCode.FIELD_INITIALIZER_FACTORY_CONSTRUCTOR,
             parameter);
         return;
@@ -2592,14 +2374,14 @@
       // constructor cannot have a redirection
       for (ConstructorInitializer initializer in constructor.initializers) {
         if (initializer is RedirectingConstructorInvocation) {
-          _errorReporter.reportErrorForNode(
+          errorReporter.reportErrorForNode(
               CompileTimeErrorCode.FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR,
               parameter);
           return;
         }
       }
     } else {
-      _errorReporter.reportErrorForNode(
+      errorReporter.reportErrorForNode(
           CompileTimeErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR,
           parameter);
     }
@@ -2630,7 +2412,7 @@
     for (VariableDeclaration variable in variables) {
       if (variable.initializer == null) {
         if (isConst) {
-          _errorReporter.reportErrorForNode(
+          errorReporter.reportErrorForNode(
               CompileTimeErrorCode.CONST_NOT_INITIALIZED,
               variable.name,
               [variable.name.name]);
@@ -2643,7 +2425,7 @@
               variableElement.isExternal) {
             // External top level variables can't be initialized, so no error.
           } else if (!_isNonNullableByDefault || !variable.isLate) {
-            _errorReporter.reportErrorForNode(
+            errorReporter.reportErrorForNode(
                 CompileTimeErrorCode.FINAL_NOT_INITIALIZED,
                 variable.name,
                 [variable.name.name]);
@@ -2684,9 +2466,12 @@
     if (node == null) {
       return;
     }
-    DartType type = node.type!;
+    if (_featureSet?.isEnabled(Feature.generic_metadata) ?? false) {
+      return;
+    }
+    DartType type = node.typeOrThrow;
     if (type is FunctionType && type.typeFormals.isNotEmpty) {
-      _errorReporter.reportErrorForNode(
+      errorReporter.reportErrorForNode(
           CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_BOUND,
           node,
           [type]);
@@ -2731,7 +2516,7 @@
       } else {
         errorCode = LanguageCode.IMPLICIT_DYNAMIC_VARIABLE;
       }
-      _errorReporter.reportErrorForNode(errorCode, node, [id]);
+      errorReporter.reportErrorForNode(errorCode, node, [id]);
     }
   }
 
@@ -2744,7 +2529,7 @@
       return;
     }
     if (element.hasImplicitReturnType && element.returnType.isDynamic) {
-      _errorReporter.reportErrorForNode(LanguageCode.IMPLICIT_DYNAMIC_RETURN,
+      errorReporter.reportErrorForNode(LanguageCode.IMPLICIT_DYNAMIC_RETURN,
           functionName, [element.displayName]);
     }
   }
@@ -2755,11 +2540,11 @@
         (node is TypeName && node.typeArguments != null)) {
       return;
     }
-    DartType type = node.type!;
+    DartType type = node.typeOrThrow;
     if (type is ParameterizedType &&
         type.typeArguments.isNotEmpty &&
         type.typeArguments.any((t) => t.isDynamic)) {
-      _errorReporter
+      errorReporter
           .reportErrorForNode(LanguageCode.IMPLICIT_DYNAMIC_TYPE, node, [type]);
     }
   }
@@ -2789,7 +2574,7 @@
       return;
     }
 
-    _errorReporter.reportErrorForNode(
+    errorReporter.reportErrorForNode(
         CompileTimeErrorCode.IMPORT_INTERNAL_LIBRARY,
         directive.uri,
         [directive.uri.stringValue]);
@@ -2834,7 +2619,7 @@
           return;
         }
       }
-      _errorReporter.reportErrorForNode(
+      errorReporter.reportErrorForNode(
           CompileTimeErrorCode.INSTANCE_ACCESS_TO_STATIC_MEMBER,
           name,
           [name.name, _getKind(element), element.enclosingElement.name]);
@@ -2849,7 +2634,7 @@
   void _checkForIntNotAssignable(Expression argument) {
     var staticParameterElement = argument.staticParameterElement;
     var staticParameterType = staticParameterElement?.type;
-    _checkForArgumentTypeNotAssignable(argument, staticParameterType, _intType,
+    checkForArgumentTypeNotAssignable(argument, staticParameterType, _intType,
         CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE);
   }
 
@@ -2859,49 +2644,12 @@
   void _checkForInvalidAnnotationFromDeferredLibrary(Annotation annotation) {
     Identifier nameIdentifier = annotation.name;
     if (nameIdentifier is PrefixedIdentifier && nameIdentifier.isDeferred) {
-      _errorReporter.reportErrorForNode(
+      errorReporter.reportErrorForNode(
           CompileTimeErrorCode.INVALID_ANNOTATION_FROM_DEFERRED_LIBRARY,
           annotation.name);
     }
   }
 
-  /// Verify that the given left hand side ([lhs]) and right hand side ([rhs])
-  /// represent a valid assignment.
-  ///
-  /// See [CompileTimeErrorCode.INVALID_ASSIGNMENT].
-  void _checkForInvalidAssignment(Expression? lhs, Expression? rhs) {
-    if (lhs == null || rhs == null) {
-      return;
-    }
-
-    if (lhs is IndexExpression &&
-            identical(lhs.realTarget.staticType, NeverTypeImpl.instance) ||
-        lhs is PrefixedIdentifier &&
-            identical(lhs.prefix.staticType, NeverTypeImpl.instance) ||
-        lhs is PropertyAccess &&
-            identical(lhs.realTarget.staticType, NeverTypeImpl.instance)) {
-      return;
-    }
-
-    DartType leftType;
-    var parent = lhs.parent;
-    if (parent is AssignmentExpression && parent.leftHandSide == lhs) {
-      leftType = parent.writeType!;
-    } else {
-      var leftVariableElement = getVariableElement(lhs);
-      leftType = (leftVariableElement == null)
-          ? lhs.typeOrThrow
-          : leftVariableElement.type;
-    }
-
-    if (!leftType.isVoid && _checkForUseOfVoidResult(rhs)) {
-      return;
-    }
-
-    _checkForAssignableExpression(
-        rhs, leftType, CompileTimeErrorCode.INVALID_ASSIGNMENT);
-  }
-
   /// Check the given [initializer] to ensure that the field being initialized
   /// is a valid field. The [fieldName] is the field name from the
   /// [ConstructorFieldInitializer]. The [staticElement] is the static element
@@ -2910,18 +2658,18 @@
       SimpleIdentifier fieldName, Element? staticElement) {
     if (staticElement is FieldElement) {
       if (staticElement.isSynthetic) {
-        _errorReporter.reportErrorForNode(
+        errorReporter.reportErrorForNode(
             CompileTimeErrorCode.INITIALIZER_FOR_NON_EXISTENT_FIELD,
             initializer,
             [fieldName]);
       } else if (staticElement.isStatic) {
-        _errorReporter.reportErrorForNode(
+        errorReporter.reportErrorForNode(
             CompileTimeErrorCode.INITIALIZER_FOR_STATIC_FIELD,
             initializer,
             [fieldName]);
       }
     } else {
-      _errorReporter.reportErrorForNode(
+      errorReporter.reportErrorForNode(
           CompileTimeErrorCode.INITIALIZER_FOR_NON_EXISTENT_FIELD,
           initializer,
           [fieldName]);
@@ -2983,13 +2731,13 @@
     }
 
     if (_enclosingExecutable.inStaticMethod) {
-      _errorReporter.reportErrorForNode(
+      errorReporter.reportErrorForNode(
           CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_STATIC, identifier);
     } else if (_enclosingExecutable.inFactoryConstructor) {
-      _errorReporter.reportErrorForNode(
+      errorReporter.reportErrorForNode(
           CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_FACTORY, identifier);
     } else {
-      _errorReporter.reportErrorForNode(
+      errorReporter.reportErrorForNode(
           CompileTimeErrorCode.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER,
           identifier,
           [identifier.name]);
@@ -3002,7 +2750,7 @@
       FunctionBody body, CompileTimeErrorCode errorCode) {
     var keyword = body.keyword;
     if (keyword != null) {
-      _errorReporter.reportErrorForToken(errorCode, keyword, [keyword.lexeme]);
+      errorReporter.reportErrorForToken(errorCode, keyword, [keyword.lexeme]);
     }
   }
 
@@ -3011,7 +2759,7 @@
   /// See [CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS].
   void _checkForInvalidReferenceToThis(ThisExpression expression) {
     if (!_thisAccessTracker.hasAccess) {
-      _errorReporter.reportErrorForNode(
+      errorReporter.reportErrorForNode(
           CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS, expression);
     }
   }
@@ -3029,7 +2777,7 @@
         _enclosingClass!.constructors.any((c) => c.isConst);
     if (!hasConstConstructor) return;
 
-    _errorReporter.reportErrorForToken(
+    errorReporter.reportErrorForToken(
       CompileTimeErrorCode.LATE_FINAL_FIELD_WITH_CONST_CONSTRUCTOR,
       lateKeyword,
     );
@@ -3040,7 +2788,7 @@
     if (!_isNonNullableByDefault) return;
 
     if (node.constructorName.name == null && type.isDartCoreList) {
-      _errorReporter.reportErrorForNode(
+      errorReporter.reportErrorForNode(
         CompileTimeErrorCode.DEFAULT_LIST_CONSTRUCTOR,
         node.constructorName,
       );
@@ -3068,9 +2816,9 @@
     // Check every list element.
     var verifier = LiteralElementVerifier(
       _typeProvider,
-      _typeSystem,
-      _errorReporter,
-      _checkForUseOfVoidResult,
+      typeSystem,
+      errorReporter,
+      checkForUseOfVoidResult,
       forList: true,
       elementType: listElementType,
       featureSet: _featureSet!,
@@ -3097,7 +2845,7 @@
     }
 
     if (element is! FunctionElement) {
-      _errorReporter.reportErrorForNode(
+      errorReporter.reportErrorForNode(
         CompileTimeErrorCode.MAIN_IS_NOT_FUNCTION,
         nameNode,
       );
@@ -3112,14 +2860,14 @@
         parameters.where((e) => e.isRequiredPositional).toList();
 
     if (requiredPositional.length > 2) {
-      _errorReporter.reportErrorForNode(
+      errorReporter.reportErrorForNode(
         CompileTimeErrorCode.MAIN_HAS_TOO_MANY_REQUIRED_POSITIONAL_PARAMETERS,
         nameNode,
       );
     }
 
     if (parameters.any((e) => e.isRequiredNamed)) {
-      _errorReporter.reportErrorForNode(
+      errorReporter.reportErrorForNode(
         CompileTimeErrorCode.MAIN_HAS_REQUIRED_NAMED_PARAMETERS,
         nameNode,
       );
@@ -3129,8 +2877,8 @@
       var first = positional.first;
       var type = first.declaredElement!.type;
       var listOfString = _typeProvider.listType(_typeProvider.stringType);
-      if (!_typeSystem.isSubtypeOf(listOfString, type)) {
-        _errorReporter.reportErrorForNode(
+      if (!typeSystem.isSubtypeOf(listOfString, type)) {
+        errorReporter.reportErrorForNode(
           CompileTimeErrorCode.MAIN_FIRST_POSITIONAL_PARAMETER_TYPE,
           first.notDefault.typeOrSelf,
         );
@@ -3156,9 +2904,9 @@
 
       var verifier = LiteralElementVerifier(
         _typeProvider,
-        _typeSystem,
-        _errorReporter,
-        _checkForUseOfVoidResult,
+        typeSystem,
+        errorReporter,
+        checkForUseOfVoidResult,
         forMap: true,
         mapKeyType: keyType,
         mapValueType: valueType,
@@ -3205,7 +2953,7 @@
         for (var constantName in constantNames) {
           int offset = statement.offset;
           int end = statement.rightParenthesis.end;
-          _errorReporter.reportErrorForOffset(
+          errorReporter.reportErrorForOffset(
             StaticWarningCode.MISSING_ENUM_CONSTANT_IN_SWITCH,
             offset,
             end - offset,
@@ -3213,10 +2961,10 @@
           );
         }
 
-        if (_typeSystem.isNullable(expressionType) && !hasCaseNull) {
+        if (typeSystem.isNullable(expressionType) && !hasCaseNull) {
           int offset = statement.offset;
           int end = statement.rightParenthesis.end;
-          _errorReporter.reportErrorForOffset(
+          errorReporter.reportErrorForOffset(
             StaticWarningCode.MISSING_ENUM_CONSTANT_IN_SWITCH,
             offset,
             end - offset,
@@ -3230,7 +2978,7 @@
   void _checkForMissingJSLibAnnotation(Annotation node) {
     if (node.elementAnnotation?.isJS ?? false) {
       if (_currentLibrary.hasJS != true) {
-        _errorReporter.reportErrorForNode(
+        errorReporter.reportErrorForNode(
             HintCode.MISSING_JS_LIB_ANNOTATION, node);
       }
     }
@@ -3245,7 +2993,7 @@
       TypeName mixinName, ClassElement mixinElement) {
     for (ConstructorElement constructor in mixinElement.constructors) {
       if (!constructor.isSynthetic && !constructor.isFactory) {
-        _errorReporter.reportErrorForNode(
+        errorReporter.reportErrorForNode(
             CompileTimeErrorCode.MIXIN_CLASS_DECLARES_CONSTRUCTOR,
             mixinName,
             [mixinElement.name]);
@@ -3264,17 +3012,20 @@
   bool _checkForMixinInheritsNotFromObject(
       TypeName mixinName, ClassElement mixinElement) {
     var mixinSupertype = mixinElement.supertype;
-    if (mixinSupertype != null) {
-      if (!mixinSupertype.isDartCoreObject ||
-          !mixinElement.isMixinApplication && mixinElement.mixins.isNotEmpty) {
-        _errorReporter.reportErrorForNode(
-            CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT,
-            mixinName,
-            [mixinElement.name]);
-        return true;
+    if (mixinSupertype == null || mixinSupertype.isDartCoreObject) {
+      var mixins = mixinElement.mixins;
+      if (mixins.isEmpty ||
+          mixinElement.isMixinApplication && mixins.length < 2) {
+        return false;
       }
     }
-    return false;
+
+    errorReporter.reportErrorForNode(
+      CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT,
+      mixinName,
+      [mixinElement.name],
+    );
+    return true;
   }
 
   /// Check that superclass constrains for the mixin type of [mixinName] at
@@ -3288,15 +3039,15 @@
         superType = superType.withNullability(NullabilitySuffix.none);
       }
 
-      bool isSatisfied = _typeSystem.isSubtypeOf(superType, constraint);
+      bool isSatisfied = typeSystem.isSubtypeOf(superType, constraint);
       if (!isSatisfied) {
         for (int i = 0; i < mixinIndex && !isSatisfied; i++) {
           isSatisfied =
-              _typeSystem.isSubtypeOf(_enclosingClass!.mixins[i], constraint);
+              typeSystem.isSubtypeOf(_enclosingClass!.mixins[i], constraint);
         }
       }
       if (!isSatisfied) {
-        _errorReporter.reportErrorForNode(
+        errorReporter.reportErrorForNode(
           CompileTimeErrorCode.MIXIN_APPLICATION_NOT_IMPLEMENTED_INTERFACE,
           mixinName.name,
           [
@@ -3330,7 +3081,7 @@
           forMixinIndex: mixinIndex, concrete: true, forSuper: true);
 
       if (superMember == null) {
-        _errorReporter.reportErrorForNode(
+        errorReporter.reportErrorForNode(
             CompileTimeErrorCode
                 .MIXIN_APPLICATION_NO_CONCRETE_SUPER_INVOKED_MEMBER,
             mixinName.name,
@@ -3349,7 +3100,7 @@
           superMember: mixinMember,
         );
         if (!isCorrect) {
-          _errorReporter.reportErrorForNode(
+          errorReporter.reportErrorForNode(
             CompileTimeErrorCode
                 .MIXIN_APPLICATION_CONCRETE_SUPER_INVOKED_MEMBER_TYPE,
             mixinName.name,
@@ -3386,7 +3137,7 @@
         Map<String, String> names =
             mixedInNames.putIfAbsent(library, () => <String, String>{});
         if (names.containsKey(name)) {
-          _errorReporter.reportErrorForNode(
+          errorReporter.reportErrorForNode(
               CompileTimeErrorCode.PRIVATE_COLLISION_IN_MIXIN_APPLICATION,
               typeName,
               [name, typeName.name.name, names[name]]);
@@ -3399,7 +3150,7 @@
           concrete: true,
         );
         if (inheritedMember != null) {
-          _errorReporter.reportErrorForNode(
+          errorReporter.reportErrorForNode(
               CompileTimeErrorCode.PRIVATE_COLLISION_IN_MIXIN_APPLICATION,
               typeName, [
             name,
@@ -3413,7 +3164,7 @@
     }
 
     for (TypeName mixinType in withClause.mixinTypes) {
-      DartType type = mixinType.type!;
+      DartType type = mixinType.typeOrThrow;
       if (type is InterfaceType) {
         LibraryElement library = type.element.library;
         if (library != _currentLibrary) {
@@ -3446,7 +3197,7 @@
     for (ConstructorInitializer initializer in constructor.initializers) {
       if (initializer is SuperConstructorInvocation) {
         if (hasSuperInitializer) {
-          _errorReporter.reportErrorForNode(
+          errorReporter.reportErrorForNode(
               CompileTimeErrorCode.MULTIPLE_SUPER_INITIALIZERS, initializer);
         }
         hasSuperInitializer = true;
@@ -3459,7 +3210,7 @@
   /// See [ParserErrorCode.NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE].
   void _checkForNativeFunctionBodyInNonSdkCode(NativeFunctionBody body) {
     if (!_isInSystemLibrary && !_hasExtUri) {
-      _errorReporter.reportErrorForNode(
+      errorReporter.reportErrorForNode(
           ParserErrorCode.NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE, body);
     }
   }
@@ -3480,7 +3231,7 @@
     if (constructorName.staticElement != null) {
       return;
     }
-    DartType type = typeName.type!;
+    DartType type = typeName.typeOrThrow;
     if (type is InterfaceType) {
       ClassElement element = type.element;
       if (element.isEnum || element.isMixin) {
@@ -3493,12 +3244,12 @@
     // report as named or default constructor absence
     var name = constructorName.name;
     if (name != null) {
-      _errorReporter.reportErrorForNode(
+      errorReporter.reportErrorForNode(
           CompileTimeErrorCode.NEW_WITH_UNDEFINED_CONSTRUCTOR,
           name,
           [className, name]);
     } else {
-      _errorReporter.reportErrorForNode(
+      errorReporter.reportErrorForNode(
           CompileTimeErrorCode.NEW_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT,
           constructorName,
           [className]);
@@ -3530,7 +3281,7 @@
         : superUnnamedConstructor;
     if (superUnnamedConstructor != null) {
       if (superUnnamedConstructor.isFactory) {
-        _errorReporter.reportErrorForNode(
+        errorReporter.reportErrorForNode(
             CompileTimeErrorCode.NON_GENERATIVE_IMPLICIT_CONSTRUCTOR,
             declaration.name, [
           superElement.name,
@@ -3544,10 +3295,10 @@
       }
     }
 
-    if (!_typeProvider.nonSubtypableClasses.contains(superType.element)) {
+    if (!_typeProvider.isNonSubtypableClass(superType.element)) {
       // Don't report this diagnostic for non-subtypable classes because the
       // real problem was already reported.
-      _errorReporter.reportErrorForNode(
+      errorReporter.reportErrorForNode(
           CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT,
           declaration.name,
           [superType, _enclosingClass!.displayName]);
@@ -3574,7 +3325,7 @@
         .every((constructor) => constructor.isFactory)) {
       // For `E extends Exception`, etc., this will never work, because it has
       // no generative constructors. State this clearly to users.
-      _errorReporter.reportErrorForNode(
+      errorReporter.reportErrorForNode(
           CompileTimeErrorCode.NO_GENERATIVE_CONSTRUCTORS_IN_SUPERCLASS,
           superclass!,
           [_enclosingClass!.name, superElement.name]);
@@ -3609,7 +3360,7 @@
     }
 
     /// TODO(srawlins): Add any tests showing this is reported.
-    _errorReporter.reportErrorForNode(
+    errorReporter.reportErrorForNode(
         CompileTimeErrorCode.NON_CONST_MAP_AS_EXPRESSION_STATEMENT, literal);
   }
 
@@ -3626,9 +3377,9 @@
     // check return type
     var annotation = declaration.returnType;
     if (annotation != null) {
-      DartType type = annotation.type!;
+      DartType type = annotation.typeOrThrow;
       if (!type.isVoid) {
-        _errorReporter.reportErrorForNode(
+        errorReporter.reportErrorForNode(
             CompileTimeErrorCode.NON_VOID_RETURN_FOR_OPERATOR, annotation);
       }
     }
@@ -3640,9 +3391,9 @@
   /// See [StaticWarningCode.NON_VOID_RETURN_FOR_SETTER].
   void _checkForNonVoidReturnTypeForSetter(TypeAnnotation? typeName) {
     if (typeName != null) {
-      DartType type = typeName.type!;
+      DartType type = typeName.typeOrThrow;
       if (!type.isVoid) {
-        _errorReporter.reportErrorForNode(
+        errorReporter.reportErrorForNode(
             CompileTimeErrorCode.NON_VOID_RETURN_FOR_SETTER, typeName);
       }
     }
@@ -3667,9 +3418,9 @@
       if (field.initializer != null) continue;
 
       var type = fieldElement.type;
-      if (!_typeSystem.isPotentiallyNonNullable(type)) continue;
+      if (!typeSystem.isPotentiallyNonNullable(type)) continue;
 
-      _errorReporter.reportErrorForNode(
+      errorReporter.reportErrorForNode(
         CompileTimeErrorCode.NOT_INITIALIZED_NON_NULLABLE_INSTANCE_FIELD,
         field,
         [field.name.name],
@@ -3714,15 +3465,15 @@
     if (node.type == null) {
       return;
     }
-    var type = node.type!.type!;
+    var type = node.type!.typeOrThrow;
 
-    if (!_typeSystem.isPotentiallyNonNullable(type)) {
+    if (!typeSystem.isPotentiallyNonNullable(type)) {
       return;
     }
 
     for (var variable in node.variables) {
       if (variable.initializer == null) {
-        _errorReporter.reportErrorForNode(
+        errorReporter.reportErrorForNode(
           CompileTimeErrorCode.NOT_INITIALIZED_NON_NULLABLE_VARIABLE,
           variable.name,
           [variable.name.name],
@@ -3741,7 +3492,7 @@
     }
     bool problemReported = false;
     for (TypeName typeName in onClause.superclassConstraints) {
-      DartType type = typeName.type!;
+      DartType type = typeName.typeOrThrow;
       if (type is InterfaceType) {
         if (_checkForExtendsOrImplementsDisallowedClass(
             typeName,
@@ -3777,7 +3528,7 @@
     NodeList<FormalParameter> formalParameters = parameterList.parameters;
     for (FormalParameter formalParameter in formalParameters) {
       if (formalParameter.isOptional) {
-        _errorReporter.reportErrorForNode(
+        errorReporter.reportErrorForNode(
             CompileTimeErrorCode.OPTIONAL_PARAMETER_IN_OPERATOR,
             formalParameter);
       }
@@ -3822,7 +3573,7 @@
             .add(BigInt.from(IntegerLiteralImpl.nearestValidDouble(lexeme)));
       }
 
-      _errorReporter.reportErrorForNode(
+      errorReporter.reportErrorForNode(
           treatedAsDouble
               ? CompileTimeErrorCode.INTEGER_LITERAL_IMPRECISE_AS_DOUBLE
               : CompileTimeErrorCode.INTEGER_LITERAL_OUT_OF_RANGE,
@@ -3843,7 +3594,7 @@
       return;
     }
 
-    _errorReporter.reportErrorForNode(
+    errorReporter.reportErrorForNode(
         CompileTimeErrorCode.PRIVATE_OPTIONAL_PARAMETER, name);
   }
 
@@ -3863,7 +3614,7 @@
     for (ConstructorInitializer initializer in declaration.initializers) {
       if (initializer is RedirectingConstructorInvocation) {
         if (_hasRedirectingFactoryConstructorCycle(constructorElement)) {
-          _errorReporter.reportErrorForNode(
+          errorReporter.reportErrorForNode(
               CompileTimeErrorCode.RECURSIVE_CONSTRUCTOR_REDIRECT, initializer);
         }
         return;
@@ -3888,7 +3639,7 @@
       return false;
     }
     // report error
-    _errorReporter.reportErrorForNode(
+    errorReporter.reportErrorForNode(
         CompileTimeErrorCode.RECURSIVE_FACTORY_REDIRECT,
         redirectedConstructorNode);
     return true;
@@ -3912,7 +3663,7 @@
       for (FormalParameter parameter in declaration.parameters.parameters) {
         if (parameter is DefaultFormalParameter &&
             parameter.defaultValue != null) {
-          _errorReporter.reportErrorForNode(
+          errorReporter.reportErrorForNode(
               CompileTimeErrorCode
                   .DEFAULT_VALUE_IN_REDIRECTING_FACTORY_CONSTRUCTOR,
               parameter.identifier!);
@@ -3934,7 +3685,7 @@
         if (declaration.name != null) {
           constructorStrName += ".${declaration.name!.name}";
         }
-        _errorReporter.reportErrorForNode(
+        errorReporter.reportErrorForNode(
             CompileTimeErrorCode.REDIRECT_TO_ABSTRACT_CLASS_CONSTRUCTOR,
             redirectedConstructor,
             [constructorStrName, redirectedClass.name]);
@@ -3945,7 +3696,7 @@
     for (ConstructorInitializer initializer in declaration.initializers) {
       if (initializer is RedirectingConstructorInvocation) {
         if (numRedirections > 0) {
-          _errorReporter.reportErrorForNode(
+          errorReporter.reportErrorForNode(
               CompileTimeErrorCode.MULTIPLE_REDIRECTING_CONSTRUCTOR_INVOCATIONS,
               initializer);
         }
@@ -3958,13 +3709,13 @@
             if (invocation.constructorName != null) {
               constructorStrName += ".${invocation.constructorName!.name}";
             }
-            _errorReporter.reportErrorForNode(
+            errorReporter.reportErrorForNode(
                 CompileTimeErrorCode.REDIRECT_GENERATIVE_TO_MISSING_CONSTRUCTOR,
                 invocation,
                 [constructorStrName, enclosingTypeName]);
           } else {
             if (redirectingElement.isFactory) {
-              _errorReporter.reportErrorForNode(
+              errorReporter.reportErrorForNode(
                   CompileTimeErrorCode
                       .REDIRECT_GENERATIVE_TO_NON_GENERATIVE_CONSTRUCTOR,
                   initializer);
@@ -3985,17 +3736,17 @@
     if (numRedirections > 0) {
       for (ConstructorInitializer initializer in declaration.initializers) {
         if (initializer is SuperConstructorInvocation) {
-          _errorReporter.reportErrorForNode(
+          errorReporter.reportErrorForNode(
               CompileTimeErrorCode.SUPER_IN_REDIRECTING_CONSTRUCTOR,
               initializer);
         }
         if (initializer is ConstructorFieldInitializer) {
-          _errorReporter.reportErrorForNode(
+          errorReporter.reportErrorForNode(
               CompileTimeErrorCode.FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR,
               initializer);
         }
         if (initializer is AssertInitializer) {
-          _errorReporter.reportErrorForNode(
+          errorReporter.reportErrorForNode(
               CompileTimeErrorCode.ASSERT_IN_REDIRECTING_CONSTRUCTOR,
               initializer);
         }
@@ -4016,7 +3767,7 @@
     if (redirectedElement != null &&
         element.isConst &&
         !redirectedElement.isConst) {
-      _errorReporter.reportErrorForOffset(
+      errorReporter.reportErrorForOffset(
         CompileTimeErrorCode.REDIRECT_TO_NON_CONST_CONSTRUCTOR,
         errorEntity.offset,
         errorEntity.end - errorEntity.offset,
@@ -4031,8 +3782,8 @@
         _hiddenElements != null &&
         _hiddenElements!.contains(element) &&
         node.parent is! CommentReference) {
-      _errorReporter.reportError(DiagnosticFactory()
-          .referencedBeforeDeclaration(_errorReporter.source, node));
+      errorReporter.reportError(DiagnosticFactory()
+          .referencedBeforeDeclaration(errorReporter.source, node));
     }
   }
 
@@ -4043,18 +3794,19 @@
 
     int count = typeNames.length;
     List<bool> detectedRepeatOnIndex = List<bool>.filled(count, false);
-    for (int i = 0; i < detectedRepeatOnIndex.length; i++) {
-      detectedRepeatOnIndex[i] = false;
-    }
     for (int i = 0; i < count; i++) {
       if (!detectedRepeatOnIndex[i]) {
-        var element = typeNames[i].name.staticElement;
-        for (int j = i + 1; j < count; j++) {
-          TypeName typeName = typeNames[j];
-          if (typeName.name.staticElement == element) {
-            detectedRepeatOnIndex[j] = true;
-            _errorReporter
-                .reportErrorForNode(errorCode, typeName, [typeName.name.name]);
+        var type = typeNames[i].type;
+        if (type is InterfaceType) {
+          var element = type.element;
+          for (int j = i + 1; j < count; j++) {
+            var otherNode = typeNames[j];
+            var otherType = otherNode.type;
+            if (otherType is InterfaceType && otherType.element == element) {
+              detectedRepeatOnIndex[j] = true;
+              errorReporter
+                  .reportErrorForNode(errorCode, otherNode, [element.name]);
+            }
           }
         }
       }
@@ -4066,7 +3818,7 @@
   /// See [CompileTimeErrorCode.RETHROW_OUTSIDE_CATCH].
   void _checkForRethrowOutsideCatch(RethrowExpression expression) {
     if (!_isInCatchClause) {
-      _errorReporter.reportErrorForNode(
+      errorReporter.reportErrorForNode(
           CompileTimeErrorCode.RETHROW_OUTSIDE_CATCH, expression);
     }
   }
@@ -4087,7 +3839,7 @@
       return;
     }
 
-    _errorReporter.reportErrorForNode(
+    errorReporter.reportErrorForNode(
         CompileTimeErrorCode.RETURN_IN_GENERATIVE_CONSTRUCTOR, body);
   }
 
@@ -4114,9 +3866,9 @@
       // Check every set element.
       var verifier = LiteralElementVerifier(
         _typeProvider,
-        _typeSystem,
-        _errorReporter,
-        _checkForUseOfVoidResult,
+        typeSystem,
+        errorReporter,
+        checkForUseOfVoidResult,
         forSet: true,
         elementType: setElementType,
         featureSet: _featureSet!,
@@ -4148,7 +3900,7 @@
       if (element.isStatic || element is ConstructorElement) {
         return;
       }
-      _errorReporter.reportErrorForNode(
+      errorReporter.reportErrorForNode(
           CompileTimeErrorCode.STATIC_ACCESS_TO_INSTANCE_MEMBER,
           name,
           [name.name]);
@@ -4166,7 +3918,7 @@
     }
 
     Expression expression = statement.expression;
-    if (_checkForUseOfVoidResult(expression)) {
+    if (checkForUseOfVoidResult(expression)) {
       return;
     }
 
@@ -4183,8 +3935,8 @@
     DartType caseType = caseExpression.typeOrThrow;
 
     // check types
-    if (!_typeSystem.isAssignableTo(expressionType, caseType)) {
-      _errorReporter.reportErrorForNode(
+    if (!typeSystem.isAssignableTo(expressionType, caseType)) {
+      errorReporter.reportErrorForNode(
           CompileTimeErrorCode.SWITCH_EXPRESSION_NOT_ASSIGNABLE,
           expression,
           [expressionType, caseType]);
@@ -4197,8 +3949,8 @@
     var expression = node.expression;
     var type = node.expression.typeOrThrow;
 
-    if (!_typeSystem.isAssignableTo(type, _typeSystem.objectNone)) {
-      _errorReporter.reportErrorForNode(
+    if (!typeSystem.isAssignableTo(type, typeSystem.objectNone)) {
+      errorReporter.reportErrorForNode(
         CompileTimeErrorCode.THROW_OF_INVALID_TYPE,
         expression,
         [type],
@@ -4215,7 +3967,7 @@
     TypeAliasElementImpl element,
   ) {
     if (element.hasSelfReference) {
-      _errorReporter.reportErrorForNode(
+      errorReporter.reportErrorForNode(
         CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF,
         node,
       );
@@ -4227,7 +3979,7 @@
   /// See [StaticWarningCode.TYPE_ANNOTATION_DEFERRED_CLASS].
   void _checkForTypeAnnotationDeferredClass(TypeAnnotation? type) {
     if (type is TypeName && type.isDeferred) {
-      _errorReporter.reportErrorForNode(
+      errorReporter.reportErrorForNode(
           CompileTimeErrorCode.TYPE_ANNOTATION_DEFERRED_CLASS,
           type,
           [type.name]);
@@ -4258,7 +4010,7 @@
           }
           if (step == parameters.length) {
             var element = parameter.declaredElement!;
-            _errorReporter.reportErrorForNode(
+            errorReporter.reportErrorForNode(
               CompileTimeErrorCode.TYPE_PARAMETER_SUPERTYPE_OF_ITS_BOUND,
               parameter,
               [element.displayName, element.bound],
@@ -4278,7 +4030,7 @@
         // The class's type parameters are not in scope for static methods.
         // However all other type parameters are legal (e.g. the static method's
         // type parameters, or a local function's type parameters).
-        _errorReporter.reportErrorForNode(
+        errorReporter.reportErrorForNode(
             CompileTimeErrorCode.TYPE_PARAMETER_REFERENCED_BY_STATIC,
             identifier);
       }
@@ -4337,7 +4089,7 @@
         : superUnnamedConstructor;
     if (superUnnamedConstructor != null) {
       if (superUnnamedConstructor.isFactory) {
-        _errorReporter.reportErrorForNode(
+        errorReporter.reportErrorForNode(
             CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR,
             constructor.returnType,
             [superUnnamedConstructor]);
@@ -4346,14 +4098,14 @@
         var name = constructor.name;
         int offset = returnType.offset;
         int length = (name != null ? name.end : returnType.end) - offset;
-        _errorReporter.reportErrorForOffset(
+        errorReporter.reportErrorForOffset(
             CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT,
             offset,
             length,
             [superType]);
       }
     } else {
-      _errorReporter.reportErrorForNode(
+      errorReporter.reportErrorForNode(
           CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT,
           constructor.returnType,
           [superElement.name]);
@@ -4429,13 +4181,13 @@
       return;
     }
 
-    if (_typeSystem.isStrictlyNonNullable(targetType)) {
+    if (typeSystem.isStrictlyNonNullable(targetType)) {
       if (errorCode == StaticWarningCode.INVALID_NULL_AWARE_OPERATOR) {
         var previousOperator = previousShortCircuitingOperator(target);
         if (previousOperator != null) {
-          _errorReporter.reportError(DiagnosticFactory()
+          errorReporter.reportError(DiagnosticFactory()
               .invalidNullAwareAfterShortCircuit(
-                  _errorReporter.source,
+                  errorReporter.source,
                   operator.offset,
                   endToken.end - operator.offset,
                   arguments,
@@ -4443,7 +4195,7 @@
           return;
         }
       }
-      _errorReporter.reportErrorForOffset(
+      errorReporter.reportErrorForOffset(
         errorCode,
         operator.offset,
         endToken.end - operator.offset,
@@ -4482,59 +4234,19 @@
       return;
     }
     if (_enclosingExtension != null) {
-      _errorReporter.reportErrorForNode(
+      errorReporter.reportErrorForNode(
           CompileTimeErrorCode
               .UNQUALIFIED_REFERENCE_TO_STATIC_MEMBER_OF_EXTENDED_TYPE,
           name,
           [enclosingElement.displayName]);
     } else {
-      _errorReporter.reportErrorForNode(
+      errorReporter.reportErrorForNode(
           CompileTimeErrorCode.UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER,
           name,
           [enclosingElement.displayName]);
     }
   }
 
-  /// While in general Never is a sort of placehold type that should be usable
-  /// anywhere, we explicitly bar it from some dubious syntactic locations such
-  /// as calling a method on Never, which in practice would look something like
-  /// `(throw x).toString()` which is clearly something between a mistake and
-  /// dead code.
-  ///
-  /// See [StaticWarningCode.RECEIVER_OF_TYPE_NEVER].
-  bool _checkForUseOfNever(Expression expression) {
-    if (!identical(expression.staticType, NeverTypeImpl.instance)) {
-      return false;
-    }
-
-    _errorReporter.reportErrorForNode(
-        HintCode.RECEIVER_OF_TYPE_NEVER, expression);
-
-    return true;
-  }
-
-  /// Check for situations where the result of a method or function is used,
-  /// when it returns 'void'. Or, in rare cases, when other types of expressions
-  /// are void, such as identifiers.
-  ///
-  /// See [StaticWarningCode.USE_OF_VOID_RESULT].
-  bool _checkForUseOfVoidResult(Expression expression) {
-    if (!identical(expression.staticType, VoidTypeImpl.instance)) {
-      return false;
-    }
-
-    if (expression is MethodInvocation) {
-      SimpleIdentifier methodName = expression.methodName;
-      _errorReporter.reportErrorForNode(
-          CompileTimeErrorCode.USE_OF_VOID_RESULT, methodName, []);
-    } else {
-      _errorReporter.reportErrorForNode(
-          CompileTimeErrorCode.USE_OF_VOID_RESULT, expression, []);
-    }
-
-    return true;
-  }
-
   void _checkForValidField(FieldFormalParameter parameter) {
     var parent2 = parameter.parent?.parent;
     if (parent2 is! ConstructorDeclaration &&
@@ -4545,7 +4257,7 @@
     if (element is FieldFormalParameterElement) {
       var fieldElement = element.field;
       if (fieldElement == null || fieldElement.isSynthetic) {
-        _errorReporter.reportErrorForNode(
+        errorReporter.reportErrorForNode(
             CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTENT_FIELD,
             parameter,
             [parameter.identifier.name]);
@@ -4555,29 +4267,29 @@
           DartType declaredType = parameterElement.type;
           DartType fieldType = fieldElement.type;
           if (fieldElement.isSynthetic) {
-            _errorReporter.reportErrorForNode(
+            errorReporter.reportErrorForNode(
                 CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTENT_FIELD,
                 parameter,
                 [parameter.identifier.name]);
           } else if (fieldElement.isStatic) {
-            _errorReporter.reportErrorForNode(
+            errorReporter.reportErrorForNode(
                 CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_STATIC_FIELD,
                 parameter,
                 [parameter.identifier.name]);
-          } else if (!_typeSystem.isSubtypeOf(declaredType, fieldType)) {
-            _errorReporter.reportErrorForNode(
+          } else if (!typeSystem.isSubtypeOf(declaredType, fieldType)) {
+            errorReporter.reportErrorForNode(
                 CompileTimeErrorCode.FIELD_INITIALIZING_FORMAL_NOT_ASSIGNABLE,
                 parameter,
                 [declaredType, fieldType]);
           }
         } else {
           if (fieldElement.isSynthetic) {
-            _errorReporter.reportErrorForNode(
+            errorReporter.reportErrorForNode(
                 CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTENT_FIELD,
                 parameter,
                 [parameter.identifier.name]);
           } else if (fieldElement.isStatic) {
-            _errorReporter.reportErrorForNode(
+            errorReporter.reportErrorForNode(
                 CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_STATIC_FIELD,
                 parameter,
                 [parameter.identifier.name]);
@@ -4635,13 +4347,13 @@
       expected = 0;
     }
     if (expected != -1 && numParameters != expected) {
-      _errorReporter.reportErrorForNode(
+      errorReporter.reportErrorForNode(
           CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR,
           nameNode,
           [name, expected, numParameters]);
       return true;
     } else if ("-" == name && numParameters > 1) {
-      _errorReporter.reportErrorForNode(
+      errorReporter.reportErrorForNode(
           CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR_MINUS,
           nameNode,
           [numParameters]);
@@ -4666,7 +4378,7 @@
 
     NodeList<FormalParameter> parameters = parameterList.parameters;
     if (parameters.length != 1 || !parameters[0].isRequiredPositional) {
-      _errorReporter.reportErrorForNode(
+      errorReporter.reportErrorForNode(
           CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER,
           setterName);
     }
@@ -4717,7 +4429,7 @@
             continue;
           }
           var methodTypeParameterVariance = Variance.invariant.combine(
-            Variance(typeParameter, methodTypeParameter.bound!.type!),
+            Variance(typeParameter, methodTypeParameter.bound!.typeOrThrow),
           );
           _checkForWrongVariancePosition(
               methodTypeParameterVariance, typeParameter, methodTypeParameter);
@@ -4742,7 +4454,7 @@
       var returnType = method.returnType;
       if (returnType != null) {
         var methodReturnTypeVariance =
-            Variance(typeParameter, returnType.type!);
+            Variance(typeParameter, returnType.typeOrThrow);
         _checkForWrongVariancePosition(
             methodReturnTypeVariance, typeParameter, returnType);
       }
@@ -4770,7 +4482,7 @@
           if (!superVariance
               .greaterThanOrEqual(typeParameterElementImpl.variance)) {
             if (!typeParameterElementImpl.isLegacyCovariant) {
-              _errorReporter.reportErrorForElement(
+              errorReporter.reportErrorForElement(
                 CompileTimeErrorCode
                     .WRONG_EXPLICIT_TYPE_PARAMETER_VARIANCE_IN_SUPERINTERFACE,
                 typeParameter,
@@ -4782,7 +4494,7 @@
                 ],
               );
             } else {
-              _errorReporter.reportErrorForElement(
+              errorReporter.reportErrorForElement(
                 CompileTimeErrorCode
                     .WRONG_TYPE_PARAMETER_VARIANCE_IN_SUPERINTERFACE,
                 typeParameter,
@@ -4818,7 +4530,7 @@
     TypeParameterElementImpl typeParameterImpl =
         typeParameter as TypeParameterElementImpl;
     if (!variance.greaterThanOrEqual(typeParameterImpl.variance)) {
-      _errorReporter.reportErrorForNode(
+      errorReporter.reportErrorForNode(
         CompileTimeErrorCode.WRONG_TYPE_PARAMETER_VARIANCE_POSITION,
         node,
         [
@@ -4847,7 +4559,7 @@
     for (var interfaceNode in implementsClause.interfaces) {
       var type = interfaceNode.type;
       if (type is InterfaceType && type.element == superElement) {
-        _errorReporter.reportErrorForNode(
+        errorReporter.reportErrorForNode(
           CompileTimeErrorCode.IMPLEMENTS_SUPER_CLASS,
           interfaceNode,
           [superElement],
@@ -4856,34 +4568,6 @@
     }
   }
 
-  void _checkIndexExpressionIndex(
-    Expression index, {
-    required ExecutableElement? readElement,
-    required ExecutableElement? writeElement,
-  }) {
-    if (readElement is MethodElement) {
-      var parameters = readElement.parameters;
-      if (parameters.isNotEmpty) {
-        _checkForArgumentTypeNotAssignableForArgument2(
-          argument: index,
-          parameter: parameters[0],
-          promoteParameterToNullable: false,
-        );
-      }
-    }
-
-    if (writeElement is MethodElement) {
-      var parameters = writeElement.parameters;
-      if (parameters.isNotEmpty) {
-        _checkForArgumentTypeNotAssignableForArgument2(
-          argument: index,
-          parameter: parameters[0],
-          promoteParameterToNullable: false,
-        );
-      }
-    }
-  }
-
   void _checkMixinInference(
       NamedCompilationUnitMember node, WithClause? withClause) {
     if (withClause == null) {
@@ -4892,7 +4576,7 @@
     var classElement = node.declaredElement as ClassElement;
     var supertype = classElement.supertype;
 
-    var interfacesMerger = InterfacesMerger(_typeSystem);
+    var interfacesMerger = InterfacesMerger(typeSystem);
     interfacesMerger.addWithSupertypes(supertype);
 
     for (var typeName in withClause.mixinTypes) {
@@ -4900,7 +4584,7 @@
       if (mixinType is InterfaceType) {
         var mixinElement = mixinType.element;
         if (typeName.typeArguments == null) {
-          var mixinSupertypeConstraints = _typeSystem
+          var mixinSupertypeConstraints = typeSystem
               .gatherMixinSupertypeConstraintsForInference(mixinElement);
           if (mixinSupertypeConstraints.isNotEmpty) {
             var matchingInterfaceTypes = _findInterfaceTypesForConstraints(
@@ -4912,13 +4596,15 @@
               // Try to pattern match matchingInterfaceType against
               // mixinSupertypeConstraint to find the correct set of type
               // parameters to apply to the mixin.
-              var inferredTypeArguments = _typeSystem.matchSupertypeConstraints(
+              var inferredTypeArguments = typeSystem.matchSupertypeConstraints(
                 mixinElement,
                 mixinSupertypeConstraints,
                 matchingInterfaceTypes,
+                genericMetadataIsEnabled: _currentLibrary.featureSet
+                    .isEnabled(Feature.generic_metadata),
               );
               if (inferredTypeArguments == null) {
-                _errorReporter.reportErrorForToken(
+                errorReporter.reportErrorForToken(
                     CompileTimeErrorCode
                         .MIXIN_INFERENCE_NO_POSSIBLE_SUBSTITUTION,
                     typeName.name.beginToken,
@@ -4970,7 +4656,7 @@
     for (var mixinNode in withClause.mixinTypes) {
       var type = mixinNode.type;
       if (type is InterfaceType && type.element == superElement) {
-        _errorReporter.reportErrorForNode(
+        errorReporter.reportErrorForNode(
           CompileTimeErrorCode.MIXINS_SUPER_CLASS,
           mixinNode,
           [superElement],
@@ -4999,7 +4685,7 @@
         if (_enclosingExtension != null) {
           // Reported by the parser.
         } else {
-          _errorReporter.reportErrorForToken(
+          errorReporter.reportErrorForToken(
             CompileTimeErrorCode.INVALID_USE_OF_COVARIANT,
             keyword,
           );
@@ -5047,16 +4733,16 @@
         if (parameter.isRequiredNamed) {
           if (parameter.defaultValue != null) {
             var parameterName = _parameterName(parameter);
-            _errorReporter.reportErrorForNode(
+            errorReporter.reportErrorForNode(
               CompileTimeErrorCode.DEFAULT_VALUE_ON_REQUIRED_PARAMETER,
               parameterName ?? parameter,
             );
           }
         } else if (defaultValuesAreExpected && parameter.defaultValue == null) {
           var type = parameter.declaredElement!.type;
-          if (_typeSystem.isPotentiallyNonNullable(type)) {
+          if (typeSystem.isPotentiallyNonNullable(type)) {
             var parameterName = _parameterName(parameter);
-            _errorReporter.reportErrorForNode(
+            errorReporter.reportErrorForNode(
               CompileTimeErrorCode.MISSING_DEFAULT_VALUE_FOR_PARAMETER,
               parameterName ?? parameter,
               [parameterName?.name ?? '?'],
@@ -5077,7 +4763,7 @@
         foundInterfaceType = interfaceType;
       } else {
         if (interfaceType != foundInterfaceType) {
-          _errorReporter.reportErrorForToken(
+          errorReporter.reportErrorForToken(
               CompileTimeErrorCode
                   .MIXIN_INFERENCE_INCONSISTENT_MATCHING_CLASSES,
               mixin.name.beginToken,
@@ -5086,7 +4772,7 @@
       }
     }
     if (foundInterfaceType == null) {
-      _errorReporter.reportErrorForToken(
+      errorReporter.reportErrorForToken(
           CompileTimeErrorCode.MIXIN_INFERENCE_NO_MATCHING_CLASS,
           mixin.name.beginToken,
           [mixin, supertypeConstraint]);
@@ -5211,19 +4897,6 @@
     return false;
   }
 
-  bool _isFunctionType(DartType type) {
-    if (type.isDynamic || type.isDartCoreNull) {
-      return true;
-    } else if (type is FunctionType || type.isDartCoreFunction) {
-      return true;
-    } else if (type is InterfaceType) {
-      var callMethod =
-          type.lookUpMethod2(FunctionElement.CALL_METHOD_NAME, _currentLibrary);
-      return callMethod != null;
-    }
-    return false;
-  }
-
   /// Return `true` if the given [identifier] is in a location where it is
   /// allowed to resolve to a static member of a supertype.
   bool _isUnqualifiedReferenceToNonLocalStaticMemberAllowed(
@@ -5327,18 +5000,6 @@
 
     return fields.toList();
   }
-
-  /// Return the variable element represented by the given [expression], or
-  /// `null` if there is no such element.
-  static VariableElement? getVariableElement(Expression? expression) {
-    if (expression is Identifier) {
-      var element = expression.staticElement;
-      if (element is VariableElement) {
-        return element;
-      }
-    }
-    return null;
-  }
 }
 
 /// A record of the elements that will be declared in some scope (block), but
diff --git a/pkg/analyzer/lib/src/generated/ffi_verifier.dart b/pkg/analyzer/lib/src/generated/ffi_verifier.dart
index 7ab1196..694d0ad 100644
--- a/pkg/analyzer/lib/src/generated/ffi_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/ffi_verifier.dart
@@ -18,7 +18,7 @@
   static const _allocatorClassName = 'Allocator';
   static const _allocateExtensionMethodName = 'call';
   static const _allocatorExtensionName = 'AllocatorAlloc';
-  static const _cArrayClassName = 'Array';
+  static const _arrayClassName = 'Array';
   static const _dartFfiLibraryName = 'dart.ffi';
   static const _opaqueClassName = 'Opaque';
 
@@ -51,12 +51,16 @@
   /// `Struct`.
   bool inStruct = false;
 
+  /// Subclass of `Struct` we are currently visiting, or `null`.
+  ClassDeclaration? struct;
+
   /// Initialize a newly created verifier.
   FfiVerifier(this.typeSystem, this._errorReporter);
 
   @override
   void visitClassDeclaration(ClassDeclaration node) {
     inStruct = false;
+    struct = null;
     // Only the Allocator, Opaque and Struct class may be extended.
     var extendsClause = node.extendsClause;
     if (extendsClause != null) {
@@ -66,10 +70,12 @@
         final className = ffiClass.name;
         if (className == _structClassName) {
           inStruct = true;
+          struct = node;
           if (node.declaredElement!.isEmptyStruct) {
             _errorReporter
                 .reportErrorForNode(FfiCode.EMPTY_STRUCT, node, [node.name]);
           }
+          _validatePackedAnnotation(node.metadata);
         } else if (className != _allocatorClassName &&
             className != _opaqueClassName) {
           _errorReporter.reportErrorForNode(
@@ -248,6 +254,9 @@
     if (nativeType.isPointer) {
       return true;
     }
+    if (nativeType.isArray) {
+      return true;
+    }
     return false;
   }
 
@@ -260,13 +269,13 @@
         return false;
       }
       if (!_isValidFfiNativeType(nativeType.returnType,
-          allowVoid: true, allowEmptyStruct: false)) {
+          allowVoid: true, allowEmptyStruct: false, allowHandle: true)) {
         return false;
       }
 
       for (final DartType typeArg in nativeType.normalParameterTypes) {
         if (!_isValidFfiNativeType(typeArg,
-            allowVoid: false, allowEmptyStruct: false)) {
+            allowVoid: false, allowEmptyStruct: false, allowHandle: true)) {
           return false;
         }
       }
@@ -279,13 +288,21 @@
   bool _isValidFfiNativeType(DartType? nativeType,
       {bool allowVoid = false,
       bool allowEmptyStruct = false,
-      bool allowArray = false}) {
+      bool allowArray = false,
+      bool allowHandle = false}) {
     if (nativeType is InterfaceType) {
-      // Is it a primitive integer/double type (or ffi.Void if we allow it).
       final primitiveType = _primitiveNativeType(nativeType);
-      if (primitiveType != _PrimitiveDartType.none &&
-          (primitiveType != _PrimitiveDartType.void_ || allowVoid)) {
-        return true;
+      switch (primitiveType) {
+        case _PrimitiveDartType.void_:
+          return allowVoid;
+        case _PrimitiveDartType.handle:
+          return allowHandle;
+        case _PrimitiveDartType.double:
+        case _PrimitiveDartType.int:
+          return true;
+        case _PrimitiveDartType.none:
+          // These are the cases below.
+          break;
       }
       if (nativeType.isNativeFunction) {
         return _isValidFfiNativeFunctionType(nativeType.typeArguments.single);
@@ -293,7 +310,7 @@
       if (nativeType.isPointer) {
         final nativeArgumentType = nativeType.typeArguments.single;
         return _isValidFfiNativeType(nativeArgumentType,
-                allowVoid: true, allowEmptyStruct: true) ||
+                allowVoid: true, allowEmptyStruct: true, allowHandle: true) ||
             nativeArgumentType.isStructSubtype ||
             nativeArgumentType.isNativeType;
       }
@@ -543,7 +560,7 @@
       _errorReporter.reportErrorForNode(
           FfiCode.MISSING_FIELD_TYPE_IN_STRUCT, fields.variables[0].name);
     } else {
-      DartType declaredType = fieldType.type!;
+      DartType declaredType = fieldType.typeOrThrow;
       if (declaredType.isDartCoreInt) {
         _validateAnnotations(fieldType, annotations, _PrimitiveDartType.int);
       } else if (declaredType.isDartCoreDouble) {
@@ -554,15 +571,24 @@
         final typeArg = (declaredType as InterfaceType).typeArguments.single;
         if (!_isSized(typeArg)) {
           _errorReporter.reportErrorForNode(FfiCode.NON_SIZED_TYPE_ARGUMENT,
-              fieldType, [_cArrayClassName, typeArg.toString()]);
+              fieldType, [_arrayClassName, typeArg.toString()]);
         }
-        _validateSizeOfAnnotation(fieldType, annotations);
+        final arrayDimensions = declaredType.arrayDimensions;
+        _validateSizeOfAnnotation(fieldType, annotations, arrayDimensions);
+        final arrayElement = declaredType.arrayElementType;
+        if (arrayElement.isStructSubtype) {
+          final elementClass = (arrayElement as InterfaceType).element;
+          _validatePackingNesting(struct!.declaredElement!, elementClass,
+              errorNode: fieldType);
+        }
       } else if (declaredType.isStructSubtype) {
         final clazz = (declaredType as InterfaceType).element;
         if (clazz.isEmptyStruct) {
           _errorReporter
               .reportErrorForNode(FfiCode.EMPTY_STRUCT, node, [clazz.name]);
         }
+        _validatePackingNesting(struct!.declaredElement!, clazz,
+            errorNode: fieldType);
       } else {
         _errorReporter.reportErrorForNode(FfiCode.INVALID_FIELD_TYPE_IN_STRUCT,
             fieldType, [fieldType.toSource()]);
@@ -660,6 +686,54 @@
     }
   }
 
+  /// Validate that the [annotations] include at most one packed annotation.
+  void _validatePackedAnnotation(NodeList<Annotation> annotations) {
+    final ffiPackedAnnotations =
+        annotations.where((annotation) => annotation.isPacked).toList();
+
+    if (ffiPackedAnnotations.isEmpty) {
+      return;
+    }
+
+    if (ffiPackedAnnotations.length > 1) {
+      final extraAnnotations = ffiPackedAnnotations.skip(1);
+      for (final annotation in extraAnnotations) {
+        _errorReporter.reportErrorForNode(
+            FfiCode.PACKED_ANNOTATION, annotation);
+      }
+    }
+
+    // Check number of dimensions.
+    final annotation = ffiPackedAnnotations.first;
+    final value = annotation.elementAnnotation?.packedMemberAlignment;
+    if (![1, 2, 4, 8, 16].contains(value)) {
+      _errorReporter.reportErrorForNode(
+          FfiCode.PACKED_ANNOTATION_ALIGNMENT, annotation);
+    }
+  }
+
+  void _validatePackingNesting(ClassElement outer, ClassElement nested,
+      {required TypeAnnotation errorNode}) {
+    final outerPacking = outer.structPacking;
+    if (outerPacking == null) {
+      // No packing for outer class, so we're done.
+      return;
+    }
+    bool error = false;
+    final nestedPacking = nested.structPacking;
+    if (nestedPacking == null) {
+      // The outer struct packs, but the nested struct does not.
+      error = true;
+    } else if (outerPacking < nestedPacking) {
+      // The outer struct packs tighter than the nested struct.
+      error = true;
+    }
+    if (error) {
+      _errorReporter.reportErrorForNode(FfiCode.PACKED_NESTING_NON_PACKED,
+          errorNode, [nested.name, outer.name]);
+    }
+  }
+
   void _validateRefIndexed(IndexExpression node) {
     var targetType = node.realTarget.staticType;
     if (!_isValidFfiNativeType(targetType,
@@ -708,19 +782,17 @@
   /// Validate that the [annotations] include exactly one size annotation. If
   /// an error is produced that cannot be associated with an annotation,
   /// associate it with the [errorNode].
-  void _validateSizeOfAnnotation(
-      AstNode errorNode, NodeList<Annotation> annotations) {
-    final ffiSizeAnnotations = annotations.where((annotation) {
-      final element = annotation.element;
-      return element is ConstructorElement &&
-          element.ffiClass != null &&
-          element.enclosingElement.name == 'Array';
-    }).toList();
+  void _validateSizeOfAnnotation(AstNode errorNode,
+      NodeList<Annotation> annotations, int arrayDimensions) {
+    final ffiSizeAnnotations =
+        annotations.where((annotation) => annotation.isArray).toList();
 
     if (ffiSizeAnnotations.isEmpty) {
       _errorReporter.reportErrorForNode(
           FfiCode.MISSING_SIZE_ANNOTATION_CARRAY, errorNode);
+      return;
     }
+
     if (ffiSizeAnnotations.length > 1) {
       final extraAnnotations = ffiSizeAnnotations.skip(1);
       for (final annotation in extraAnnotations) {
@@ -728,6 +800,15 @@
             FfiCode.EXTRA_SIZE_ANNOTATION_CARRAY, annotation);
       }
     }
+
+    // Check number of dimensions.
+    final annotation = ffiSizeAnnotations.first;
+    final dimensions = annotation.elementAnnotation?.arraySizeDimensions ?? [];
+    final annotationDimensions = dimensions.length;
+    if (annotationDimensions != arrayDimensions) {
+      _errorReporter.reportErrorForNode(
+          FfiCode.SIZE_ANNOTATION_DIMENSIONS, annotation);
+    }
   }
 
   /// Validate that the given [typeArgument] has a constant value. Return `true`
@@ -750,6 +831,81 @@
   none,
 }
 
+extension on Annotation {
+  bool get isArray {
+    final element = this.element;
+    return element is ConstructorElement &&
+        element.ffiClass != null &&
+        element.enclosingElement.name == 'Array';
+  }
+
+  bool get isPacked {
+    final element = this.element;
+    return element is ConstructorElement &&
+        element.ffiClass != null &&
+        element.enclosingElement.name == 'Packed';
+  }
+}
+
+extension on ElementAnnotation {
+  bool get isArray {
+    final element = this.element;
+    return element is ConstructorElement &&
+        element.ffiClass != null &&
+        element.enclosingElement.name == 'Array';
+    // Note: this is 'Array' instead of '_ArraySize' because it finds the
+    // forwarding factory instead of the forwarded constructor.
+  }
+
+  bool get isPacked {
+    final element = this.element;
+    return element is ConstructorElement &&
+        element.ffiClass != null &&
+        element.enclosingElement.name == 'Packed';
+  }
+
+  List<int> get arraySizeDimensions {
+    assert(isArray);
+    final value = computeConstantValue();
+
+    // Element of `@Array.multi([1, 2, 3])`.
+    final listField = value?.getField('dimensions');
+    if (listField != null) {
+      final listValues = listField
+          .toListValue()
+          ?.map((dartValue) => dartValue.toIntValue())
+          .whereType<int>()
+          .toList();
+      if (listValues != null) {
+        return listValues;
+      }
+    }
+
+    // Element of `@Array(1, 2, 3)`.
+    const dimensionFieldNames = [
+      'dimension1',
+      'dimension2',
+      'dimension3',
+      'dimension4',
+      'dimension5',
+    ];
+    var result = <int>[];
+    for (final dimensionFieldName in dimensionFieldNames) {
+      final dimensionValue = value?.getField(dimensionFieldName)?.toIntValue();
+      if (dimensionValue != null) {
+        result.add(dimensionValue);
+      }
+    }
+    return result;
+  }
+
+  int? get packedMemberAlignment {
+    assert(isPacked);
+    final value = computeConstantValue();
+    return value?.getField('memberAlignment')?.toIntValue();
+  }
+}
+
 extension on Element? {
   /// Return `true` if this represents the extension `AllocatorAlloc`.
   bool get isAllocatorExtension {
@@ -831,6 +987,17 @@
   bool get isFfiClass {
     return library.name == FfiVerifier._dartFfiLibraryName;
   }
+
+  int? get structPacking {
+    final packedAnnotations =
+        metadata.where((annotation) => annotation.isPacked);
+
+    if (packedAnnotations.isEmpty) {
+      return null;
+    }
+
+    return packedAnnotations.first.packedMemberAlignment;
+  }
 }
 
 extension on ExtensionElement {
@@ -845,11 +1012,33 @@
     final self = this;
     if (self is InterfaceType) {
       final element = self.element;
-      return element.name == FfiVerifier._cArrayClassName && element.isFfiClass;
+      return element.name == FfiVerifier._arrayClassName && element.isFfiClass;
     }
     return false;
   }
 
+  int get arrayDimensions {
+    DartType iterator = this;
+    int dimensions = 0;
+    while (iterator is InterfaceType &&
+        iterator.element.name == FfiVerifier._arrayClassName &&
+        iterator.element.isFfiClass) {
+      dimensions++;
+      iterator = iterator.typeArguments.single;
+    }
+    return dimensions;
+  }
+
+  DartType get arrayElementType {
+    DartType iterator = this;
+    while (iterator is InterfaceType &&
+        iterator.element.name == FfiVerifier._arrayClassName &&
+        iterator.element.isFfiClass) {
+      iterator = iterator.typeArguments.single;
+    }
+    return iterator;
+  }
+
   bool get isPointer {
     final self = this;
     return self is InterfaceType && self.element.isPointer;
diff --git a/pkg/analyzer/lib/src/generated/parser.dart b/pkg/analyzer/lib/src/generated/parser.dart
index a00a27d..ff6050c 100644
--- a/pkg/analyzer/lib/src/generated/parser.dart
+++ b/pkg/analyzer/lib/src/generated/parser.dart
@@ -17,7 +17,6 @@
 import 'package:analyzer/src/fasta/ast_builder.dart';
 import 'package:analyzer/src/generated/source.dart';
 
-export 'package:analyzer/src/dart/ast/utilities.dart' show ResolutionCopier;
 export 'package:analyzer/src/dart/error/syntactic_errors.dart';
 
 /// A simple data-holder for a method that needs to return multiple values.
@@ -94,7 +93,7 @@
     return buffer.toString();
   }
 
-  /// If the given [keyword] is not `null`, append it to the given [builder],
+  /// If the given [keyword] is not `null`, append it to the given [buffer],
   /// prefixing it with a space if [needsSpace] is `true`. Return `true` if
   /// subsequent keywords need to be prefixed with a space.
   bool _appendKeyword(StringBuffer buffer, bool needsSpace, Token? keyword) {
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 5f3f78f..1a1918d 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -58,6 +58,7 @@
 import 'package:analyzer/src/generated/constant.dart';
 import 'package:analyzer/src/generated/element_resolver.dart';
 import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/error_detection_helpers.dart';
 import 'package:analyzer/src/generated/migratable_ast_info_provider.dart';
 import 'package:analyzer/src/generated/migration.dart';
 import 'package:analyzer/src/generated/source.dart';
@@ -154,7 +155,7 @@
 
 /// Instances of the class `ResolverVisitor` are used to resolve the nodes
 /// within a single compilation unit.
-class ResolverVisitor extends ScopedVisitor {
+class ResolverVisitor extends ScopedVisitor with ErrorDetectionHelpers {
   /// The manager for the inheritance mappings.
   final InheritanceManager3 inheritance;
 
@@ -203,6 +204,7 @@
   late final StaticTypeAnalyzer typeAnalyzer;
 
   /// The type system in use during resolution.
+  @override
   final TypeSystemImpl typeSystem;
 
   /// The class declaration representing the class containing the current node,
@@ -323,7 +325,7 @@
       resolver: this,
     );
     boolExpressionVerifier = BoolExpressionVerifier(
-      typeSystem: typeSystem,
+      resolver: this,
       errorReporter: errorReporter,
       nullableDereferenceVerifier: nullableDereferenceVerifier,
     );
@@ -333,10 +335,11 @@
     extensionResolver = ExtensionMemberResolver(this);
     typePropertyResolver = TypePropertyResolver(this);
     inferenceHelper = InvocationInferenceHelper(
-        resolver: this,
-        errorReporter: errorReporter,
-        typeSystem: typeSystem,
-        migrationResolutionHooks: migrationResolutionHooks);
+      resolver: this,
+      errorReporter: errorReporter,
+      typeSystem: typeSystem,
+      migrationResolutionHooks: migrationResolutionHooks,
+    );
     _assignmentExpressionResolver = AssignmentExpressionResolver(
       resolver: this,
     );
@@ -417,6 +420,23 @@
   bool get _isNonNullableByDefault =>
       _featureSet.isEnabled(Feature.non_nullable);
 
+  /// Verify that the arguments in the given [argumentList] can be assigned to
+  /// their corresponding parameters.
+  ///
+  /// This method corresponds to
+  /// [BestPracticesVerifier.checkForArgumentTypesNotAssignableInList].
+  ///
+  /// See [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE].
+  void checkForArgumentTypesNotAssignableInList(ArgumentList argumentList,
+      List<Map<DartType, NonPromotionReason> Function()> whyNotPromotedList) {
+    var arguments = argumentList.arguments;
+    for (int i = 0; i < arguments.length; i++) {
+      checkForArgumentTypeNotAssignableForArgument(arguments[i],
+          whyNotPromoted:
+              flowAnalysis?.flow == null ? null : whyNotPromotedList[i]);
+    }
+  }
+
   void checkForBodyMayCompleteNormally({
     required DartType? returnType,
     required FunctionBody body,
@@ -511,17 +531,19 @@
     nullSafetyDeadCodeVerifier.visitNode(node);
   }
 
-  /// Computes the appropriate set of context messages to report along with an
-  /// error that may have occurred because [receiver] was not type promoted.
+  @override
   List<DiagnosticMessage> computeWhyNotPromotedMessages(
-      Expression? receiver,
+      Expression? expression,
       SyntacticEntity errorEntity,
       Map<DartType, NonPromotionReason>? whyNotPromoted) {
+    if (expression is NamedExpression) {
+      expression = expression.expression;
+    }
     List<DiagnosticMessage> messages = [];
     if (whyNotPromoted != null) {
       for (var entry in whyNotPromoted.entries) {
         var whyNotPromotedVisitor = _WhyNotPromotedVisitor(
-            source, receiver, errorEntity, flowAnalysis!.dataForTesting);
+            source, expression, errorEntity, flowAnalysis!.dataForTesting);
         if (typeSystem.isPotentiallyNullable(entry.key)) continue;
         var message = entry.value.accept(whyNotPromotedVisitor);
         if (message != null) {
@@ -687,6 +709,13 @@
 
       InferenceContext.setType(node.index, result.indexContextType);
       node.index.accept(this);
+      var whyNotPromoted = flowAnalysis?.flow?.whyNotPromoted(node.index);
+      checkIndexExpressionIndex(
+        node.index,
+        readElement: result.readElement as ExecutableElement?,
+        writeElement: result.writeElement as ExecutableElement?,
+        whyNotPromoted: whyNotPromoted,
+      );
 
       return result;
     } else if (node is PrefixedIdentifier) {
@@ -860,17 +889,25 @@
 
   @override
   void visitAnnotation(covariant AnnotationImpl node) {
+    var whyNotPromotedList = <Map<DartType, NonPromotionReason> Function()>[];
     AstNode parent = node.parent;
     if (identical(parent, _enclosingClassDeclaration) ||
         identical(parent, _enclosingFunctionTypeAlias) ||
         identical(parent, _enclosingMixinDeclaration)) {
       return;
     }
-    AnnotationResolver(this).resolve(node);
+    AnnotationResolver(this).resolve(node, whyNotPromotedList);
+    var arguments = node.arguments;
+    if (arguments != null) {
+      checkForArgumentTypesNotAssignableInList(arguments, whyNotPromotedList);
+    }
   }
 
   @override
-  void visitArgumentList(ArgumentList node, {bool isIdentical = false}) {
+  void visitArgumentList(ArgumentList node,
+      {bool isIdentical = false,
+      List<Map<DartType, NonPromotionReason> Function()>? whyNotPromotedList}) {
+    whyNotPromotedList ??= [];
     var callerType = InferenceContext.getContext(node);
     NodeList<Expression> arguments = node.arguments;
     if (callerType is FunctionType) {
@@ -929,17 +966,20 @@
     }
     checkUnreachableNode(node);
     int length = arguments.length;
+    var flow = flowAnalysis?.flow;
     for (var i = 0; i < length; i++) {
       if (isIdentical && length > 1 && i == 1) {
         var firstArg = arguments[0];
-        flowAnalysis?.flow
-            ?.equalityOp_rightBegin(firstArg, firstArg.typeOrThrow);
+        flow?.equalityOp_rightBegin(firstArg, firstArg.typeOrThrow);
       }
       arguments[i].accept(this);
+      if (flow != null) {
+        whyNotPromotedList.add(flow.whyNotPromoted(arguments[i]));
+      }
     }
     if (isIdentical && length > 1) {
       var secondArg = arguments[1];
-      flowAnalysis?.flow?.equalityOp_end(
+      flow?.equalityOp_end(
           node.parent as Expression, secondArg, secondArg.typeOrThrow);
     }
     node.accept(elementResolver);
@@ -960,6 +1000,7 @@
     boolExpressionVerifier.checkForNonBoolExpression(
       node.condition,
       errorCode: CompileTimeErrorCode.NON_BOOL_EXPRESSION,
+      whyNotPromoted: flowAnalysis?.flow?.whyNotPromoted(node.condition),
     );
     flowAnalysis?.flow?.assert_afterCondition(node.condition);
     node.message?.accept(this);
@@ -974,6 +1015,7 @@
     boolExpressionVerifier.checkForNonBoolExpression(
       node.condition,
       errorCode: CompileTimeErrorCode.NON_BOOL_EXPRESSION,
+      whyNotPromoted: flowAnalysis?.flow?.whyNotPromoted(node.condition),
     );
     flowAnalysis?.flow?.assert_afterCondition(node.condition);
     node.message?.accept(this);
@@ -1154,7 +1196,9 @@
     // TODO(scheglov) Do we need these checks for null?
     condition.accept(this);
     condition = node.condition;
-    boolExpressionVerifier.checkForNonBoolCondition(condition);
+    var whyNotPromoted = flowAnalysis?.flow?.whyNotPromoted(condition);
+    boolExpressionVerifier.checkForNonBoolCondition(condition,
+        whyNotPromoted: whyNotPromoted);
 
     Expression thenExpression = node.thenExpression;
     InferenceContext.setTypeFromNode(thenExpression, node);
@@ -1260,8 +1304,15 @@
     var fieldElement = enclosingClass!.getField(node.fieldName.name);
     InferenceContext.setType(node.expression, fieldElement?.type);
     node.expression.accept(this);
+    var whyNotPromoted = flowAnalysis?.flow?.whyNotPromoted(node.expression);
     node.accept(elementResolver);
     node.accept(typeAnalyzer);
+    var enclosingConstructor = enclosingFunction as ConstructorElement;
+    if (fieldElement != null) {
+      checkForFieldInitializerNotAssignable(node, fieldElement,
+          isConstConstructor: enclosingConstructor.isConst,
+          whyNotPromoted: whyNotPromoted);
+    }
   }
 
   @override
@@ -1316,7 +1367,9 @@
     InferenceContext.setType(condition, typeProvider.boolType);
     condition.accept(this);
     condition = node.condition;
-    boolExpressionVerifier.checkForNonBoolCondition(condition);
+    var whyNotPromoted = flowAnalysis?.flow?.whyNotPromoted(condition);
+    boolExpressionVerifier.checkForNonBoolCondition(condition,
+        whyNotPromoted: whyNotPromoted);
 
     flowAnalysis?.flow?.doStatement_end(condition);
   }
@@ -1398,11 +1451,13 @@
 
   @override
   void visitExtensionOverride(ExtensionOverride node) {
+    var whyNotPromotedList = <Map<DartType, NonPromotionReason> Function()>[];
     node.extensionName.accept(this);
     node.typeArguments?.accept(this);
 
     ExtensionMemberResolver(this).setOverrideReceiverContextType(node);
-    node.argumentList.accept(this);
+    visitArgumentList(node.argumentList,
+        whyNotPromotedList: whyNotPromotedList);
 
     node.accept(elementResolver);
     node.accept(typeAnalyzer);
@@ -1519,10 +1574,13 @@
 
   @override
   void visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
+    var whyNotPromotedList = <Map<DartType, NonPromotionReason> Function()>[];
     node.function.accept(this);
-    _functionExpressionInvocationResolver
-        .resolve(node as FunctionExpressionInvocationImpl);
+    _functionExpressionInvocationResolver.resolve(
+        node as FunctionExpressionInvocationImpl, whyNotPromotedList);
     nullShortingTermination(node);
+    checkForArgumentTypesNotAssignableInList(
+        node.argumentList, whyNotPromotedList);
   }
 
   @override
@@ -1560,8 +1618,10 @@
     InferenceContext.setType(condition, typeProvider.boolType);
     condition.accept(this);
     condition = node.condition;
+    var whyNotPromoted = flowAnalysis?.flow?.whyNotPromoted(condition);
 
-    boolExpressionVerifier.checkForNonBoolCondition(condition);
+    boolExpressionVerifier.checkForNonBoolCondition(condition,
+        whyNotPromoted: whyNotPromoted);
 
     CollectionElement thenElement = node.thenElement;
     if (flowAnalysis != null) {
@@ -1599,8 +1659,10 @@
     InferenceContext.setType(condition, typeProvider.boolType);
     condition.accept(this);
     condition = node.condition;
+    var whyNotPromoted = flowAnalysis?.flow?.whyNotPromoted(condition);
 
-    boolExpressionVerifier.checkForNonBoolCondition(condition);
+    boolExpressionVerifier.checkForNonBoolCondition(condition,
+        whyNotPromoted: whyNotPromoted);
 
     Statement thenStatement = node.thenStatement;
     if (flowAnalysis != null) {
@@ -1647,6 +1709,13 @@
 
     InferenceContext.setType(node.index, result.indexContextType);
     node.index.accept(this);
+    var whyNotPromoted = flowAnalysis?.flow?.whyNotPromoted(node.index);
+    checkIndexExpressionIndex(
+      node.index,
+      readElement: result.readElement as ExecutableElement?,
+      writeElement: null,
+      whyNotPromoted: whyNotPromoted,
+    );
 
     DartType type;
     if (identical(node.realTarget.staticType, NeverTypeImpl.instance)) {
@@ -1664,11 +1733,15 @@
   @override
   void visitInstanceCreationExpression(
       covariant InstanceCreationExpressionImpl node) {
+    var whyNotPromotedList = <Map<DartType, NonPromotionReason> Function()>[];
     node.constructorName.accept(this);
     _inferArgumentTypesForInstanceCreate(node);
-    node.argumentList.accept(this);
+    visitArgumentList(node.argumentList,
+        whyNotPromotedList: whyNotPromotedList);
     node.accept(elementResolver);
     node.accept(typeAnalyzer);
+    checkForArgumentTypesNotAssignableInList(
+        node.argumentList, whyNotPromotedList);
   }
 
   @override
@@ -1733,6 +1806,7 @@
 
   @override
   void visitMethodInvocation(covariant MethodInvocationImpl node) {
+    var whyNotPromotedList = <Map<DartType, NonPromotionReason> Function()>[];
     var target = node.target;
     target?.accept(this);
 
@@ -1751,15 +1825,19 @@
     }
 
     node.typeArguments?.accept(this);
-    node.accept(elementResolver);
+    elementResolver.visitMethodInvocation(node,
+        whyNotPromotedList: whyNotPromotedList);
 
     var functionRewrite = MethodInvocationResolver.getRewriteResult(node);
     if (functionRewrite != null) {
       nullShortingTermination(node, discardType: true);
-      _resolveRewrittenFunctionExpressionInvocation(functionRewrite);
+      _resolveRewrittenFunctionExpressionInvocation(
+          functionRewrite, whyNotPromotedList);
     } else {
       nullShortingTermination(node);
     }
+    checkForArgumentTypesNotAssignableInList(
+        node.argumentList, whyNotPromotedList);
   }
 
   @override
@@ -1790,6 +1868,10 @@
   void visitNamedExpression(NamedExpression node) {
     InferenceContext.setTypeFromNode(node.expression, node);
     super.visitNamedExpression(node);
+    // Any "why not promoted" information that flow analysis had associated with
+    // `node.expression` now needs to be forwarded to `node`, so that when
+    // `visitArgumentList` iterates through the arguments, it will find it.
+    flowAnalysis?.flow?.forwardExpression(node, node.expression);
   }
 
   @override
@@ -1872,10 +1954,14 @@
     // because it needs to be visited in the context of the constructor
     // invocation.
     //
+    var whyNotPromotedList = <Map<DartType, NonPromotionReason> Function()>[];
     node.accept(elementResolver);
     InferenceContext.setType(node.argumentList, node.staticElement?.type);
-    node.argumentList.accept(this);
+    visitArgumentList(node.argumentList,
+        whyNotPromotedList: whyNotPromotedList);
     node.accept(typeAnalyzer);
+    checkForArgumentTypesNotAssignableInList(
+        node.argumentList, whyNotPromotedList);
   }
 
   @override
@@ -1929,10 +2015,14 @@
     // because it needs to be visited in the context of the constructor
     // invocation.
     //
+    var whyNotPromotedList = <Map<DartType, NonPromotionReason> Function()>[];
     node.accept(elementResolver);
     InferenceContext.setType(node.argumentList, node.staticElement?.type);
-    node.argumentList.accept(this);
+    visitArgumentList(node.argumentList,
+        whyNotPromotedList: whyNotPromotedList);
     node.accept(typeAnalyzer);
+    checkForArgumentTypesNotAssignableInList(
+        node.argumentList, whyNotPromotedList);
   }
 
   @override
@@ -2054,7 +2144,7 @@
       flow.tryFinallyStatement_finallyBegin(
           catchClauses.isNotEmpty ? node : body);
       finallyBlock.accept(this);
-      flow.tryFinallyStatement_end(finallyBlock);
+      flow.tryFinallyStatement_end();
     }
   }
 
@@ -2113,8 +2203,11 @@
 
       flowAnalysis?.flow?.whileStatement_conditionBegin(node);
       condition.accept(this);
+      condition = node.condition;
+      var whyNotPromoted = flowAnalysis?.flow?.whyNotPromoted(condition);
 
-      boolExpressionVerifier.checkForNonBoolCondition(node.condition);
+      boolExpressionVerifier.checkForNonBoolCondition(node.condition,
+          whyNotPromoted: whyNotPromoted);
 
       Statement body = node.body;
       flowAnalysis?.flow?.whileStatement_bodyBegin(node, condition);
@@ -2165,13 +2258,16 @@
 
   void _inferArgumentTypesForInstanceCreate(
       covariant InstanceCreationExpressionImpl node) {
-    var constructor = node.constructorName;
-    TypeName classTypeName = constructor.type;
-    // if (classTypeName == null) {
-    //   return;
-    // }
+    var constructorName = node.constructorName;
 
-    var originalElement = constructor.staticElement;
+    var typeName = constructorName.type;
+    var typeArguments = typeName.typeArguments;
+
+    var elementToInfer = inferenceHelper.constructorElementToInfer(
+      constructorName: constructorName,
+      definingLibrary: definingLibrary,
+    );
+
     FunctionType? inferred;
     // If the constructor is generic, we'll have a ConstructorMember that
     // substitutes in type arguments (possibly `dynamic`) from earlier in
@@ -2179,8 +2275,7 @@
     //
     // Otherwise we'll have a ConstructorElement, and we can skip inference
     // because there's nothing to infer in a non-generic type.
-    if (classTypeName.typeArguments == null &&
-        originalElement is ConstructorMember) {
+    if (elementToInfer != null) {
       // TODO(leafp): Currently, we may re-infer types here, since we
       // sometimes resolve multiple times.  We should really check that we
       // have not already inferred something.  However, the obvious ways to
@@ -2191,14 +2286,11 @@
       // Get back to the uninstantiated generic constructor.
       // TODO(jmesserly): should we store this earlier in resolution?
       // Or look it up, instead of jumping backwards through the Member?
-      var rawElement = originalElement.declaration;
-      rawElement = toLegacyElement(rawElement);
-
-      FunctionType constructorType =
-          typeAnalyzer.constructorToGenericFunctionType(rawElement);
+      var rawElement = elementToInfer.element;
+      var constructorType = elementToInfer.asType;
 
       inferred = inferenceHelper.inferArgumentTypesForGeneric(
-          node, constructorType, constructor.type.typeArguments,
+          node, constructorType, typeArguments,
           isConst: node.isConst, errorNode: node.constructorName);
 
       if (inferred != null) {
@@ -2208,7 +2300,7 @@
         arguments.correspondingStaticParameters =
             resolveArgumentsToParameters(arguments, inferred.parameters, null);
 
-        constructor.type.type = inferred.returnType;
+        constructorName.type.type = inferred.returnType;
 
         // Update the static element as well. This is used in some cases, such
         // as computing constant values. It is stored in two places.
@@ -2216,15 +2308,17 @@
           rawElement,
           inferred.returnType as InterfaceType,
         );
-        constructorElement = toLegacyElement(constructorElement);
-        constructor.staticElement = constructorElement;
+        constructorName.staticElement = constructorElement;
       }
     }
 
     if (inferred == null) {
-      var type = originalElement?.type;
-      type = type != null ? toLegacyTypeIfOptOut(type) as FunctionType : null;
-      InferenceContext.setType(node.argumentList, type);
+      var constructorElement = constructorName.staticElement;
+      if (constructorElement != null) {
+        var type = constructorElement.type;
+        type = toLegacyTypeIfOptOut(type) as FunctionType;
+        InferenceContext.setType(node.argumentList, type);
+      }
     }
   }
 
@@ -2237,6 +2331,7 @@
   /// as for method invocations.
   void _resolveRewrittenFunctionExpressionInvocation(
     FunctionExpressionInvocation node,
+    List<Map<DartType, NonPromotionReason> Function()> whyNotPromotedList,
   ) {
     var function = node.function;
 
@@ -2253,8 +2348,8 @@
       }
     }
 
-    _functionExpressionInvocationResolver
-        .resolve(node as FunctionExpressionInvocationImpl);
+    _functionExpressionInvocationResolver.resolve(
+        node as FunctionExpressionInvocationImpl, whyNotPromotedList);
 
     nullShortingTermination(node);
   }
@@ -3348,11 +3443,13 @@
 
 class _WhyNotPromotedVisitor
     implements
-        NonPromotionReasonVisitor<DiagnosticMessage?, AstNode, Expression,
+        NonPromotionReasonVisitor<DiagnosticMessage?, AstNode,
             PromotableElement, DartType> {
   final Source source;
 
-  final Expression? _receiver;
+  /// The expression that was not promoted, or `null` if the thing that was not
+  /// promoted was an implicit `this`.
+  final Expression? _expression;
 
   final SyntacticEntity _errorEntity;
 
@@ -3363,70 +3460,46 @@
   DartType? propertyType;
 
   _WhyNotPromotedVisitor(
-      this.source, this._receiver, this._errorEntity, this._dataForTesting);
+      this.source, this._expression, this._errorEntity, this._dataForTesting);
 
   @override
   DiagnosticMessage? visitDemoteViaExplicitWrite(
-      DemoteViaExplicitWrite<PromotableElement, Expression> reason) {
-    var writeExpression = reason.writeExpression;
+      DemoteViaExplicitWrite<PromotableElement> reason) {
+    var node = reason.node as AstNode;
+    if (node is ForEachPartsWithIdentifier) {
+      node = node.identifier;
+    }
     if (_dataForTesting != null) {
-      _dataForTesting!.nonPromotionReasonTargets[writeExpression] =
-          reason.shortName;
+      _dataForTesting!.nonPromotionReasonTargets[node] = reason.shortName;
     }
     var variableName = reason.variable.name;
     if (variableName == null) return null;
-    return _contextMessageForWrite(variableName, writeExpression);
-  }
-
-  @override
-  DiagnosticMessage? visitDemoteViaForEachVariableWrite(
-      DemoteViaForEachVariableWrite<PromotableElement, AstNode> reason) {
-    var node = reason.node;
-    var variableName = reason.variable.name;
-    if (variableName == null) return null;
-    ForLoopParts parts;
-    if (node is ForStatement) {
-      parts = node.forLoopParts;
-    } else if (node is ForElement) {
-      parts = node.forLoopParts;
-    } else {
-      assert(false, 'Unexpected node type');
-      return null;
-    }
-    if (parts is ForEachPartsWithIdentifier) {
-      var identifier = parts.identifier;
-      if (_dataForTesting != null) {
-        _dataForTesting!.nonPromotionReasonTargets[identifier] =
-            reason.shortName;
-      }
-      return _contextMessageForWrite(variableName, identifier);
-    } else {
-      assert(false, 'Unexpected parts type');
-      return null;
-    }
+    return _contextMessageForWrite(variableName, node, reason);
   }
 
   @override
   DiagnosticMessage? visitPropertyNotPromoted(
       PropertyNotPromoted<DartType> reason) {
-    var receiver = _receiver;
+    var expression = _expression;
     Element? receiverElement;
-    if (receiver is SimpleIdentifier) {
-      receiverElement = receiver.staticElement;
-    } else if (receiver is PropertyAccess) {
-      receiverElement = receiver.propertyName.staticElement;
-    } else if (receiver is PrefixedIdentifier) {
-      receiverElement = receiver.identifier.staticElement;
+    if (expression is SimpleIdentifier) {
+      receiverElement = expression.staticElement;
+    } else if (expression is PropertyAccess) {
+      receiverElement = expression.propertyName.staticElement;
+    } else if (expression is PrefixedIdentifier) {
+      receiverElement = expression.identifier.staticElement;
     } else {
-      assert(false, 'Unrecognized receiver: ${receiver.runtimeType}');
+      assert(false,
+          'Unrecognized property access expression: ${expression.runtimeType}');
     }
     if (receiverElement is PropertyAccessorElement) {
       propertyReference = receiverElement;
       propertyType = reason.staticType;
-      return _contextMessageForProperty(receiverElement, reason.propertyName);
+      return _contextMessageForProperty(
+          receiverElement, reason.propertyName, reason);
     } else {
       assert(receiverElement == null,
-          'Unrecognized receiver element: ${receiverElement.runtimeType}');
+          'Unrecognized property element: ${receiverElement.runtimeType}');
       return null;
     }
   }
@@ -3435,28 +3508,30 @@
   DiagnosticMessage? visitThisNotPromoted(ThisNotPromoted reason) {
     return DiagnosticMessageImpl(
         filePath: source.fullName,
-        message: "'this' can't be promoted.",
+        message: "'this' can't be promoted.  See ${reason.documentationLink}",
         offset: _errorEntity.offset,
         length: _errorEntity.length);
   }
 
   DiagnosticMessageImpl _contextMessageForProperty(
-      PropertyAccessorElement property, String propertyName) {
+      PropertyAccessorElement property,
+      String propertyName,
+      NonPromotionReason reason) {
     return DiagnosticMessageImpl(
         filePath: property.source.fullName,
-        message:
-            "'$propertyName' refers to a property so it could not be promoted.",
+        message: "'$propertyName' refers to a property so it couldn't be "
+            "promoted.  See ${reason.documentationLink}",
         offset: property.nameOffset,
         length: property.nameLength);
   }
 
   DiagnosticMessageImpl _contextMessageForWrite(
-      String variableName, Expression writeExpression) {
+      String variableName, AstNode node, NonPromotionReason reason) {
     return DiagnosticMessageImpl(
         filePath: source.fullName,
-        message: "Variable '$variableName' could be null due to an intervening "
-            "write.",
-        offset: writeExpression.offset,
-        length: writeExpression.length);
+        message: "Variable '$variableName' could not be promoted due to an "
+            "assignment.  See ${reason.documentationLink}",
+        offset: node.offset,
+        length: node.length);
   }
 }
diff --git a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
index 45632ba..ead332f 100644
--- a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
+++ b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
@@ -4,13 +4,10 @@
 
 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/nullability_suffix.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/dart/ast/ast.dart';
 import 'package:analyzer/src/dart/ast/extensions.dart';
 import 'package:analyzer/src/dart/element/member.dart' show ConstructorMember;
-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/generated/migration.dart';
@@ -48,28 +45,6 @@
     _dynamicType = _typeProvider.dynamicType;
   }
 
-  /// Given a constructor for a generic type, returns the equivalent generic
-  /// function type that we could use to forward to the constructor, or for a
-  /// non-generic type simply returns the constructor type.
-  ///
-  /// For example given the type `class C<T> { C(T arg); }`, the generic function
-  /// type is `<T>(T) -> C<T>`.
-  FunctionType constructorToGenericFunctionType(
-      ConstructorElement constructor) {
-    var classElement = constructor.enclosingElement;
-    var typeParameters = classElement.typeParameters;
-    if (typeParameters.isEmpty) {
-      return constructor.type;
-    }
-
-    return FunctionTypeImpl(
-      typeFormals: typeParameters,
-      parameters: constructor.parameters,
-      returnType: constructor.returnType,
-      nullabilitySuffix: NullabilitySuffix.star,
-    );
-  }
-
   /// Record that the static type of the given node is the given type.
   ///
   /// @param expression the node whose type is to be recorded
@@ -198,7 +173,7 @@
   void visitInstanceCreationExpression(
       covariant InstanceCreationExpressionImpl node) {
     _inferInstanceCreationExpression(node);
-    recordStaticType(node, node.constructorName.type.type!);
+    recordStaticType(node, node.constructorName.type.typeOrThrow);
   }
 
   /// <blockquote>
@@ -362,18 +337,6 @@
   /// Given an instance creation of a possibly generic type, infer the type
   /// arguments using the current context type as well as the argument types.
   void _inferInstanceCreationExpression(InstanceCreationExpressionImpl node) {
-    var constructor = node.constructorName;
-    var originalElement = constructor.staticElement;
-    // If the constructor is generic, we'll have a ConstructorMember that
-    // substitutes in type arguments (possibly `dynamic`) from earlier in
-    // resolution.
-    //
-    // Otherwise we'll have a ConstructorElement, and we can skip inference
-    // because there's nothing to infer in a non-generic type.
-    if (originalElement is! ConstructorMember) {
-      return;
-    }
-
     // TODO(leafp): Currently, we may re-infer types here, since we
     // sometimes resolve multiple times.  We should really check that we
     // have not already inferred something.  However, the obvious ways to
@@ -384,35 +347,39 @@
     // Get back to the uninstantiated generic constructor.
     // TODO(jmesserly): should we store this earlier in resolution?
     // Or look it up, instead of jumping backwards through the Member?
-    var rawElement = originalElement.declaration;
-    rawElement = _resolver.toLegacyElement(rawElement);
+    var constructorName = node.constructorName;
+    var elementToInfer = _resolver.inferenceHelper.constructorElementToInfer(
+      constructorName: constructorName,
+      definingLibrary: _resolver.definingLibrary,
+    );
 
-    FunctionType constructorType = constructorToGenericFunctionType(rawElement);
+    // If the constructor is not generic, we are done.
+    if (elementToInfer == null) {
+      return;
+    }
 
+    var typeName = constructorName.type;
+    var typeArguments = typeName.typeArguments;
+
+    var constructorType = elementToInfer.asType;
     var arguments = node.argumentList;
     var inferred = _resolver.inferenceHelper.inferGenericInvoke(
-        node,
-        constructorType,
-        constructor.type.typeArguments,
-        arguments,
-        node.constructorName,
+        node, constructorType, typeArguments, arguments, constructorName,
         isConst: node.isConst);
 
-    if (inferred != null && inferred != originalElement.type) {
-      inferred = _resolver.toLegacyTypeIfOptOut(inferred) as FunctionType;
+    if (inferred != null) {
       // Fix up the parameter elements based on inferred method.
       arguments.correspondingStaticParameters =
           ResolverVisitor.resolveArgumentsToParameters(
               arguments, inferred.parameters, null);
-      constructor.type.type = inferred.returnType;
+      typeName.type = inferred.returnType;
       // Update the static element as well. This is used in some cases, such as
       // computing constant values. It is stored in two places.
       var constructorElement = ConstructorMember.from(
-        rawElement,
+        elementToInfer.element,
         inferred.returnType as InterfaceType,
       );
-      constructorElement = _resolver.toLegacyElement(constructorElement);
-      constructor.staticElement = constructorElement;
+      constructorName.staticElement = constructorElement;
     }
   }
 }
diff --git a/pkg/analyzer/lib/src/generated/type_promotion_manager.dart b/pkg/analyzer/lib/src/generated/type_promotion_manager.dart
index de3e0a0..965b30f 100644
--- a/pkg/analyzer/lib/src/generated/type_promotion_manager.dart
+++ b/pkg/analyzer/lib/src/generated/type_promotion_manager.dart
@@ -259,7 +259,7 @@
       }
     } else if (condition is IsExpression) {
       if (condition.notOperator == null) {
-        _promote(condition.expression, condition.type.type!);
+        _promote(condition.expression, condition.type.typeOrThrow);
       }
     } else if (condition is ParenthesizedExpression) {
       _promoteTypes(condition.expression);
diff --git a/pkg/analyzer/lib/src/hint/sdk_constraint_verifier.dart b/pkg/analyzer/lib/src/hint/sdk_constraint_verifier.dart
index 336b180..e0c34fd 100644
--- a/pkg/analyzer/lib/src/hint/sdk_constraint_verifier.dart
+++ b/pkg/analyzer/lib/src/hint/sdk_constraint_verifier.dart
@@ -9,7 +9,6 @@
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/dart/element/type_provider.dart';
 import 'package:analyzer/error/listener.dart';
-import 'package:analyzer/src/dart/ast/ast.dart';
 import 'package:analyzer/src/dart/ast/extensions.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:pub_semver/pub_semver.dart';
@@ -113,8 +112,7 @@
 
   @override
   void visitAsExpression(AsExpression node) {
-    if (checkConstantUpdate2018 &&
-        (node as AsExpressionImpl).inConstantContext) {
+    if (checkConstantUpdate2018 && node.inConstantContext) {
       _errorReporter.reportErrorForNode(
           HintCode.SDK_VERSION_AS_EXPRESSION_IN_CONST_CONTEXT, node);
     }
@@ -131,15 +129,14 @@
       } else if ((operatorType == TokenType.AMPERSAND ||
               operatorType == TokenType.BAR ||
               operatorType == TokenType.CARET) &&
-          (node as BinaryExpressionImpl).inConstantContext) {
+          node.inConstantContext) {
         if (node.leftOperand.typeOrThrow.isDartCoreBool) {
           _errorReporter.reportErrorForToken(
               HintCode.SDK_VERSION_BOOL_OPERATOR_IN_CONST_CONTEXT,
               node.operator,
               [node.operator.lexeme]);
         }
-      } else if (operatorType == TokenType.EQ_EQ &&
-          (node as BinaryExpressionImpl).inConstantContext) {
+      } else if (operatorType == TokenType.EQ_EQ && node.inConstantContext) {
         bool primitive(Expression node) {
           DartType type = node.typeOrThrow;
           return type.isDartCoreBool ||
@@ -204,8 +201,7 @@
 
   @override
   void visitIsExpression(IsExpression node) {
-    if (checkConstantUpdate2018 &&
-        (node as IsExpressionImpl).inConstantContext) {
+    if (checkConstantUpdate2018 && node.inConstantContext) {
       _errorReporter.reportErrorForNode(
           HintCode.SDK_VERSION_IS_EXPRESSION_IN_CONST_CONTEXT, node);
     }
diff --git a/pkg/analyzer/lib/src/ignore_comments/ignore_info.dart b/pkg/analyzer/lib/src/ignore_comments/ignore_info.dart
index 507ea06..a6f0f56 100644
--- a/pkg/analyzer/lib/src/ignore_comments/ignore_info.dart
+++ b/pkg/analyzer/lib/src/ignore_comments/ignore_info.dart
@@ -209,15 +209,23 @@
 }
 
 extension on CommentToken {
+  /// The error codes currently do not contain dollar signs, so we can be a bit
+  /// more restrictive in this test.
+  static final _errorCodeNameRegExp = RegExp(r'^[a-zA-Z][_a-z0-9A-Z]*$');
+
   /// Return the diagnostic names contained in this comment, assuming that it is
   /// a correctly formatted ignore comment.
   Iterable<DiagnosticName> get diagnosticNames sync* {
+    bool isValidErrorCodeName(String text) {
+      return text.contains(_errorCodeNameRegExp);
+    }
+
     int offset = lexeme.indexOf(':') + 1;
     var names = lexeme.substring(offset).split(',');
     offset += this.offset;
     for (var name in names) {
       var trimmedName = name.trim();
-      if (trimmedName.isNotEmpty) {
+      if (trimmedName.isNotEmpty && isValidErrorCodeName(trimmedName)) {
         var innerOffset = name.indexOf(trimmedName);
         yield DiagnosticName(trimmedName.toLowerCase(), offset + innerOffset);
       }
diff --git a/pkg/analyzer/lib/src/lint/analysis.dart b/pkg/analyzer/lib/src/lint/analysis.dart
index 5e0e60d..6869458 100644
--- a/pkg/analyzer/lib/src/lint/analysis.dart
+++ b/pkg/analyzer/lib/src/lint/analysis.dart
@@ -201,7 +201,7 @@
 
     List<AnalysisErrorInfo> errors = [];
     for (Source source in sources) {
-      var errorsResult = (await analysisDriver.getErrors(source.fullName))!;
+      var errorsResult = await analysisDriver.getErrors(source.fullName);
       errors.add(
           AnalysisErrorInfoImpl(errorsResult.errors, errorsResult.lineInfo));
       _sourcesAnalyzed.add(source);
diff --git a/pkg/analyzer/lib/src/lint/config.dart b/pkg/analyzer/lib/src/lint/config.dart
index 4b0dd66..288bf06 100644
--- a/pkg/analyzer/lib/src/lint/config.dart
+++ b/pkg/analyzer/lib/src/lint/config.dart
@@ -9,7 +9,7 @@
 /// Return `null` if [optionsMap] is `null` or does not have `linter` map.
 LintConfig? parseConfig(YamlMap? optionsMap) {
   if (optionsMap != null) {
-    var options = getValue(optionsMap, 'linter');
+    var options = optionsMap.valueAt('linter');
     // Quick check of basic contract.
     if (options is YamlMap) {
       return LintConfig.parseMap(options);
diff --git a/pkg/analyzer/lib/src/lint/linter.dart b/pkg/analyzer/lib/src/lint/linter.dart
index 3a4d2a3..0fb77cf 100644
--- a/pkg/analyzer/lib/src/lint/linter.dart
+++ b/pkg/analyzer/lib/src/lint/linter.dart
@@ -849,6 +849,7 @@
         case CompileTimeErrorCode.MISSING_CONST_IN_MAP_LITERAL:
         case CompileTimeErrorCode.MISSING_CONST_IN_SET_LITERAL:
         case CompileTimeErrorCode.NON_CONSTANT_LIST_ELEMENT:
+        case CompileTimeErrorCode.NON_CONSTANT_MAP_ELEMENT:
         case CompileTimeErrorCode.NON_CONSTANT_MAP_KEY:
         case CompileTimeErrorCode.NON_CONSTANT_MAP_VALUE:
         case CompileTimeErrorCode.NON_CONSTANT_SET_ELEMENT:
diff --git a/pkg/analyzer/lib/src/lint/options_rule_validator.dart b/pkg/analyzer/lib/src/lint/options_rule_validator.dart
index 71e8620..6f326b1 100644
--- a/pkg/analyzer/lib/src/lint/options_rule_validator.dart
+++ b/pkg/analyzer/lib/src/lint/options_rule_validator.dart
@@ -68,9 +68,9 @@
   @override
   List<AnalysisError> validate(ErrorReporter reporter, YamlMap options) {
     List<AnalysisError> errors = <AnalysisError>[];
-    var node = getValue(options, linter);
+    var node = options.valueAt(linter);
     if (node is YamlMap) {
-      var rules = getValue(node, rulesKey);
+      var rules = node.valueAt(rulesKey);
       validateRules(rules, reporter);
     }
     return errors;
diff --git a/pkg/analyzer/lib/src/lint/project.dart b/pkg/analyzer/lib/src/lint/project.dart
index 759dddc..ff937d9 100644
--- a/pkg/analyzer/lib/src/lint/project.dart
+++ b/pkg/analyzer/lib/src/lint/project.dart
@@ -134,7 +134,7 @@
     for (Source source in sources!) {
       String path = source.uri.path;
       if (path.startsWith(libDir) && !path.startsWith(libSrcDir)) {
-        ResolvedUnitResult result = (await driver.getResult(source.fullName))!;
+        ResolvedUnitResult result = await driver.getResult(source.fullName);
         LibraryElement library = result.libraryElement;
 
         NamespaceBuilder namespaceBuilder = NamespaceBuilder();
diff --git a/pkg/analyzer/lib/src/pubspec/pubspec_validator.dart b/pkg/analyzer/lib/src/pubspec/pubspec_validator.dart
index 36d2133..077b56b 100644
--- a/pkg/analyzer/lib/src/pubspec/pubspec_validator.dart
+++ b/pkg/analyzer/lib/src/pubspec/pubspec_validator.dart
@@ -5,7 +5,6 @@
 import 'package:analyzer/error/error.dart';
 import 'package:analyzer/error/listener.dart';
 import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/pubspec/pubspec_warning_code.dart';
 import 'package:analyzer/src/util/file_paths.dart' as file_paths;
@@ -157,7 +156,7 @@
     }
 
     for (var dependency in declaredDevDependencies.entries) {
-      var packageName = dependency.key;
+      var packageName = dependency.key as YamlNode;
       if (declaredDependencies.containsKey(packageName)) {
         _reportErrorForNode(reporter, packageName,
             PubspecWarningCode.UNNECESSARY_DEV_DEPENDENCY, [packageName.value]);
@@ -248,8 +247,8 @@
     if (dependency is YamlMap) {
       var pathEntry = _asString(dependency[PATH_FIELD]);
       if (pathEntry != null) {
-        YamlNode pathKey() => getKey(dependency, PATH_FIELD)!;
-        YamlNode pathValue() => getValue(dependency, PATH_FIELD)!;
+        YamlNode pathKey() => dependency.getKey(PATH_FIELD)!;
+        YamlNode pathValue() => dependency.valueAt(PATH_FIELD)!;
 
         if (pathEntry.contains(r'\')) {
           _reportErrorForNode(reporter, pathValue(),
@@ -280,7 +279,7 @@
 
       var gitEntry = dependency[GIT_FIELD];
       if (gitEntry != null && checkForPathAndGitDeps) {
-        _reportErrorForNode(reporter, getKey(dependency, GIT_FIELD)!,
+        _reportErrorForNode(reporter, dependency.getKey(GIT_FIELD)!,
             PubspecWarningCode.INVALID_DEPENDENCY, [GIT_FIELD]);
       }
     }
diff --git a/pkg/analyzer/lib/src/services/available_declarations.dart b/pkg/analyzer/lib/src/services/available_declarations.dart
index 22ddf8d..577424b 100644
--- a/pkg/analyzer/lib/src/services/available_declarations.dart
+++ b/pkg/analyzer/lib/src/services/available_declarations.dart
@@ -596,7 +596,7 @@
 
     if (_scheduledFiles.isNotEmpty) {
       var scheduledFile = _scheduledFiles.removeLast();
-      var file = _getFileByPath(scheduledFile.context, scheduledFile.path)!;
+      var file = _getFileByPath(scheduledFile.context, [], scheduledFile.path)!;
 
       if (!file.isLibrary) return;
 
@@ -653,6 +653,16 @@
     }
   }
 
+  /// TODO(scheglov) Remove after fixing
+  /// https://github.com/dart-lang/sdk/issues/45233
+  void _addPathOrUri(List<String> pathOrUriList, String path, Uri uri) {
+    pathOrUriList.add('(uri: $uri, path: $path)');
+
+    if (pathOrUriList.length > 200) {
+      throw StateError('Suspected cycle. $pathOrUriList');
+    }
+  }
+
   /// Compute exported declarations for the given [libraries].
   void _computeExportedDeclarations(Set<_File> libraries) {
     var walker = _LibraryWalker();
@@ -686,7 +696,8 @@
     return null;
   }
 
-  _File? _getFileByPath(DeclarationsContext context, String path) {
+  _File? _getFileByPath(
+      DeclarationsContext context, List<String> partOrUriList, String path) {
     var file = _pathToFile[path];
     if (file == null) {
       var uri = context._restoreUri(path);
@@ -694,13 +705,16 @@
         file = _File(this, path, uri);
         _pathToFile[path] = file;
         _uriToFile[uri] = file;
-        file.refresh(context);
+        _addPathOrUri(partOrUriList, path, uri);
+        file.refresh(context, partOrUriList);
+        partOrUriList.removeLast();
       }
     }
     return file;
   }
 
-  _File? _getFileByUri(DeclarationsContext context, Uri uri) {
+  _File? _getFileByUri(
+      DeclarationsContext context, List<String> partOrUriList, Uri uri) {
     var file = _uriToFile[uri];
     if (file != null) {
       return file;
@@ -726,7 +740,9 @@
     _pathToFile[path] = file;
     _uriToFile[uri] = file;
 
-    file.refresh(context);
+    _addPathOrUri(partOrUriList, path, uri);
+    file.refresh(context, partOrUriList);
+    partOrUriList.removeLast();
     return file;
   }
 
@@ -745,13 +761,13 @@
     var containingContext = _findContextOfPath(path);
     if (containingContext == null) return;
 
-    var file = _getFileByPath(containingContext, path);
+    var file = _getFileByPath(containingContext, [], path);
     if (file == null) return;
 
     var wasLibrary = file.isLibrary;
     var oldLibrary = wasLibrary ? file : file.library;
 
-    file.refresh(containingContext);
+    file.refresh(containingContext, []);
     var isLibrary = file.isLibrary;
     var newLibrary = isLibrary ? file : file.library;
 
@@ -763,17 +779,17 @@
       } else {
         notLibraries.add(file);
         if (newLibrary != null) {
-          newLibrary.refresh(containingContext);
+          newLibrary.refresh(containingContext, []);
           _invalidateExportedDeclarations(invalidatedLibraries, newLibrary);
         }
       }
     } else {
       if (oldLibrary != null) {
-        oldLibrary.refresh(containingContext);
+        oldLibrary.refresh(containingContext, []);
         _invalidateExportedDeclarations(invalidatedLibraries, oldLibrary);
       }
       if (newLibrary != null && newLibrary != oldLibrary) {
-        newLibrary.refresh(containingContext);
+        newLibrary.refresh(containingContext, []);
         _invalidateExportedDeclarations(invalidatedLibraries, newLibrary);
       }
     }
@@ -1164,7 +1180,7 @@
 
   String get uriStr => uri.toString();
 
-  void refresh(DeclarationsContext context) {
+  void refresh(DeclarationsContext context, List<String> partOrUriList) {
     var resource = tracker._resourceProvider.getFile(path);
 
     int modificationStamp;
@@ -1225,10 +1241,10 @@
 
     // Resolve exports and parts.
     for (var export in exports) {
-      export.file = _fileForRelativeUri(context, export.uri);
+      export.file = _fileForRelativeUri(context, partOrUriList, export.uri);
     }
     for (var part in parts) {
-      part.file = _fileForRelativeUri(context, part.uri);
+      part.file = _fileForRelativeUri(context, partOrUriList, part.uri);
     }
     exports.removeWhere((e) => e.file == null);
     parts.removeWhere((e) => e.file == null);
@@ -1409,13 +1425,15 @@
       var isDeprecated = _hasDeprecatedAnnotation(node);
 
       var hasConstructor = false;
-      void addClassMembers(Declaration parent, List<ClassMember> members) {
+      void addClassMembers(Declaration parent, bool parentIsAbstract,
+          List<ClassMember> members) {
         for (var classMember in members) {
           setCodeRange(classMember);
           setDartDoc(classMember);
           isDeprecated = _hasDeprecatedAnnotation(classMember);
 
-          if (classMember is ConstructorDeclaration) {
+          if (classMember is ConstructorDeclaration &&
+              (!parentIsAbstract || classMember.factoryKeyword != null)) {
             var parameters = classMember.parameters;
             var defaultArguments = _computeDefaultArguments(parameters);
             var isConst = classMember.constKeyword != null;
@@ -1534,7 +1552,8 @@
         );
         if (classDeclaration == null) continue;
 
-        addClassMembers(classDeclaration, node.members);
+        addClassMembers(
+            classDeclaration, classDeclaration.isAbstract, node.members);
 
         if (!hasConstructor) {
           classDeclaration.children.add(Declaration(
@@ -1689,7 +1708,7 @@
           relevanceTags: ['ElementKind.MIXIN'],
         );
         if (mixinDeclaration == null) continue;
-        addClassMembers(mixinDeclaration, node.members);
+        addClassMembers(mixinDeclaration, false, node.members);
       } else if (node is TopLevelVariableDeclaration) {
         var isConst = node.variables.isConst;
         var isFinal = node.variables.isFinal;
@@ -1750,9 +1769,13 @@
   }
 
   /// Return the [_File] for the given [relative] URI, maybe `null`.
-  _File? _fileForRelativeUri(DeclarationsContext context, Uri relative) {
+  _File? _fileForRelativeUri(
+    DeclarationsContext context,
+    List<String> partOrUriList,
+    Uri relative,
+  ) {
     var absoluteUri = resolveRelativeUri(uri, relative);
-    return tracker._getFileByUri(context, absoluteUri);
+    return tracker._getFileByUri(context, partOrUriList, absoluteUri);
   }
 
   void _putFileDeclarationsToByteStore(String contentKey) {
diff --git a/pkg/analyzer/lib/src/summary2/apply_resolution.dart b/pkg/analyzer/lib/src/summary2/apply_resolution.dart
index 20308e2..e8fd2a7 100644
--- a/pkg/analyzer/lib/src/summary2/apply_resolution.dart
+++ b/pkg/analyzer/lib/src/summary2/apply_resolution.dart
@@ -84,6 +84,8 @@
   void visitAnnotation(covariant AnnotationImpl node) {
     _expectMarker(MarkerTag.Annotation_name);
     node.name.accept(this);
+    _expectMarker(MarkerTag.Annotation_typeArguments);
+    node.typeArguments?.accept(this);
     _expectMarker(MarkerTag.Annotation_constructorName);
     node.constructorName?.accept(this);
     _expectMarker(MarkerTag.Annotation_arguments);
diff --git a/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart b/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
index 5282bec..ab2b7b2 100644
--- a/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
+++ b/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
@@ -258,11 +258,13 @@
 
   Annotation _readAnnotation() {
     var name = readNode() as Identifier;
+    var typeArguments = _readOptionalNode() as TypeArgumentList?;
     var constructorName = _readOptionalNode() as SimpleIdentifier?;
     var arguments = _readOptionalNode() as ArgumentList?;
     return astFactory.annotation(
       atSign: Tokens.AT,
       name: name,
+      typeArguments: typeArguments,
       period: Tokens.PERIOD,
       constructorName: constructorName,
       arguments: arguments,
@@ -612,7 +614,7 @@
       node,
       codeOffset: codeOffset,
       codeLength: codeLength,
-      resolutionIndex: -1,
+      resolutionIndex: _readUInt30(),
       documentationTokenIndexList: documentationTokenIndexList,
     );
 
diff --git a/pkg/analyzer/lib/src/summary2/ast_binary_tag.dart b/pkg/analyzer/lib/src/summary2/ast_binary_tag.dart
index 7fd7486..933b12b 100644
--- a/pkg/analyzer/lib/src/summary2/ast_binary_tag.dart
+++ b/pkg/analyzer/lib/src/summary2/ast_binary_tag.dart
@@ -11,6 +11,7 @@
   AnnotatedNode_metadata,
   AnnotatedNode_end,
   Annotation_name,
+  Annotation_typeArguments,
   Annotation_constructorName,
   Annotation_arguments,
   Annotation_element,
diff --git a/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart b/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
index be8cfa6..e4ff4f3 100644
--- a/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
+++ b/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
@@ -61,6 +61,8 @@
 
     _writeMarker(MarkerTag.Annotation_name);
     _writeNode(node.name);
+    _writeMarker(MarkerTag.Annotation_typeArguments);
+    _writeOptionalNode(node.typeArguments);
     _writeMarker(MarkerTag.Annotation_constructorName);
     _writeOptionalNode(node.constructorName);
 
@@ -532,6 +534,7 @@
 
   @override
   void visitEnumConstantDeclaration(EnumConstantDeclaration node) {
+    var resolutionIndex = _getNextResolutionIndex();
     _writeByte(Tag.EnumConstantDeclaration);
 
     _writeInformativeUint30(node.offset);
@@ -543,6 +546,7 @@
     _writeMarker(MarkerTag.EnumConstantDeclaration_declaration);
     _storeDeclaration(node);
     _writeMarker(MarkerTag.EnumConstantDeclaration_end);
+    _writeUInt30(resolutionIndex);
   }
 
   @override
diff --git a/pkg/analyzer/lib/src/summary2/bundle_reader.dart b/pkg/analyzer/lib/src/summary2/bundle_reader.dart
index ecace4e..38a0e91 100644
--- a/pkg/analyzer/lib/src/summary2/bundle_reader.dart
+++ b/pkg/analyzer/lib/src/summary2/bundle_reader.dart
@@ -489,12 +489,6 @@
     }
     _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,
@@ -630,51 +624,60 @@
     if (tag == Tag.NullType) {
       return null;
     } else if (tag == Tag.DynamicType) {
-      return DynamicTypeImpl.instance;
+      var type = DynamicTypeImpl.instance;
+      return _readAliasElementArguments(type);
     } else if (tag == Tag.FunctionType) {
-      return _readFunctionType();
+      var type = _readFunctionType();
+      return _readAliasElementArguments(type);
     } else if (tag == Tag.InterfaceType) {
       var element = nextElement() as ClassElement;
       var typeArguments = _readTypeList();
       var nullability = _readNullability();
-      return InterfaceTypeImpl(
+      var type = InterfaceTypeImpl(
         element: element,
         typeArguments: typeArguments,
         nullabilitySuffix: nullability,
       );
+      return _readAliasElementArguments(type);
     } else if (tag == Tag.InterfaceType_noTypeArguments_none) {
       var element = nextElement() as ClassElement;
-      return InterfaceTypeImpl(
+      var type = InterfaceTypeImpl(
         element: element,
         typeArguments: const <DartType>[],
         nullabilitySuffix: NullabilitySuffix.none,
       );
+      return _readAliasElementArguments(type);
     } else if (tag == Tag.InterfaceType_noTypeArguments_question) {
       var element = nextElement() as ClassElement;
-      return InterfaceTypeImpl(
+      var type = InterfaceTypeImpl(
         element: element,
         typeArguments: const <DartType>[],
         nullabilitySuffix: NullabilitySuffix.question,
       );
+      return _readAliasElementArguments(type);
     } else if (tag == Tag.InterfaceType_noTypeArguments_star) {
       var element = nextElement() as ClassElement;
-      return InterfaceTypeImpl(
+      var type = InterfaceTypeImpl(
         element: element,
         typeArguments: const <DartType>[],
         nullabilitySuffix: NullabilitySuffix.star,
       );
+      return _readAliasElementArguments(type);
     } else if (tag == Tag.NeverType) {
       var nullability = _readNullability();
-      return NeverTypeImpl.instance.withNullability(nullability);
+      var type = NeverTypeImpl.instance.withNullability(nullability);
+      return _readAliasElementArguments(type);
     } else if (tag == Tag.TypeParameterType) {
       var element = nextElement() as TypeParameterElement;
       var nullability = _readNullability();
-      return TypeParameterTypeImpl(
+      var type = TypeParameterTypeImpl(
         element: element,
         nullabilitySuffix: nullability,
       );
+      return _readAliasElementArguments(type);
     } else if (tag == Tag.VoidType) {
-      return VoidTypeImpl.instance;
+      var type = VoidTypeImpl.instance;
+      return _readAliasElementArguments(type);
     } else {
       throw UnimplementedError('$tag');
     }
@@ -711,6 +714,47 @@
     }
   }
 
+  DartType _readAliasElementArguments(DartType type) {
+    var aliasElement = _readRawElement();
+    if (aliasElement is TypeAliasElement) {
+      var aliasArguments = _readTypeList();
+      if (type is DynamicType) {
+        // TODO(scheglov) add support for `dynamic` aliasing
+        return type;
+      } else if (type is FunctionType) {
+        return FunctionTypeImpl(
+          typeFormals: type.typeFormals,
+          parameters: type.parameters,
+          returnType: type.returnType,
+          nullabilitySuffix: type.nullabilitySuffix,
+          aliasElement: aliasElement,
+          aliasArguments: aliasArguments,
+        );
+      } else if (type is InterfaceType) {
+        return InterfaceTypeImpl(
+          element: type.element,
+          typeArguments: type.typeArguments,
+          nullabilitySuffix: type.nullabilitySuffix,
+          aliasElement: aliasElement,
+          aliasArguments: aliasArguments,
+        );
+      } else if (type is TypeParameterType) {
+        return TypeParameterTypeImpl(
+          element: type.element,
+          nullabilitySuffix: type.nullabilitySuffix,
+          aliasElement: aliasElement,
+          aliasArguments: aliasArguments,
+        );
+      } else if (type is VoidType) {
+        // TODO(scheglov) add support for `void` aliasing
+        return type;
+      } else {
+        throw UnimplementedError('${type.runtimeType}');
+      }
+    }
+    return type;
+  }
+
   /// TODO(scheglov) Optimize for write/read of types without type parameters.
   FunctionType _readFunctionType() {
     var typeParameters = <TypeParameterElement>[];
@@ -727,9 +771,6 @@
       element.bound = bound;
     }
 
-    var aliasElement = nextElement() as TypeAliasElement?;
-    var aliasArguments = aliasElement != null ? _readTypeList() : null;
-
     var returnType = nextType()!;
 
     var formalParameters = <ParameterElement>[];
@@ -756,8 +797,6 @@
       parameters: formalParameters,
       returnType: returnType,
       nullabilitySuffix: nullability,
-      aliasElement: aliasElement,
-      aliasArguments: aliasArguments,
     );
   }
 
diff --git a/pkg/analyzer/lib/src/summary2/bundle_writer.dart b/pkg/analyzer/lib/src/summary2/bundle_writer.dart
index 687b4f2..9f0dbdd 100644
--- a/pkg/analyzer/lib/src/summary2/bundle_writer.dart
+++ b/pkg/analyzer/lib/src/summary2/bundle_writer.dart
@@ -427,8 +427,10 @@
       writeByte(Tag.NullType);
     } else if (type is DynamicType) {
       writeByte(Tag.DynamicType);
+      _writeTypeAliasElementArguments(type);
     } else if (type is FunctionType) {
       _writeFunctionType(type);
+      _writeTypeAliasElementArguments(type);
     } else if (type is InterfaceType) {
       var typeArguments = type.typeArguments;
       var nullabilitySuffix = type.nullabilitySuffix;
@@ -452,17 +454,20 @@
         }
         _writeNullabilitySuffix(nullabilitySuffix);
       }
+      _writeTypeAliasElementArguments(type);
     } else if (type is NeverType) {
       writeByte(Tag.NeverType);
       _writeNullabilitySuffix(type.nullabilitySuffix);
+      _writeTypeAliasElementArguments(type);
     } else if (type is TypeParameterType) {
       writeByte(Tag.TypeParameterType);
       writeElement(type.element);
       _writeNullabilitySuffix(type.nullabilitySuffix);
+      _writeTypeAliasElementArguments(type);
     } else if (type is VoidType) {
       writeByte(Tag.VoidType);
+      _writeTypeAliasElementArguments(type);
     } else {
-      // TODO
       throw UnimplementedError('${type.runtimeType}');
     }
   }
@@ -530,12 +535,6 @@
       writeType(typeParameter.bound);
     }
 
-    var aliasElement = type.aliasElement;
-    writeElement(aliasElement);
-    if (aliasElement != null) {
-      _writeTypeList(type.aliasArguments!);
-    }
-
     writeType(type.returnType);
 
     var parameters = type.parameters;
@@ -561,6 +560,14 @@
     _sink.writeUInt30(index);
   }
 
+  void _writeTypeAliasElementArguments(DartType type) {
+    var aliasElement = type.aliasElement;
+    writeElement0(aliasElement);
+    if (aliasElement != null) {
+      _writeTypeList(type.aliasArguments!);
+    }
+  }
+
   void _writeTypeList(List<DartType> types) {
     _sink.writeUInt30(types.length);
     for (var type in types) {
diff --git a/pkg/analyzer/lib/src/summary2/default_types_builder.dart b/pkg/analyzer/lib/src/summary2/default_types_builder.dart
index 4401ee5..8657fc7 100644
--- a/pkg/analyzer/lib/src/summary2/default_types_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/default_types_builder.dart
@@ -6,6 +6,7 @@
 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/extensions.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/replacement_visitor.dart';
 import 'package:analyzer/src/dart/element/type.dart';
@@ -73,7 +74,7 @@
 
       var cycles = _findRawTypePathsToDeclaration(
         parameter,
-        boundNode.type!,
+        boundNode.typeOrThrow,
         declarationElement,
         Set<Element>.identity(),
       );
@@ -83,7 +84,9 @@
     for (var cycle in allCycles) {
       for (var element in cycle) {
         var boundNode = element.parameter.bound;
-        if (boundNode is TypeNameImpl) {
+        if (boundNode is GenericFunctionTypeImpl) {
+          boundNode.type = DynamicTypeImpl.instance;
+        } else if (boundNode is TypeNameImpl) {
           boundNode.type = DynamicTypeImpl.instance;
         } else {
           throw UnimplementedError('(${boundNode.runtimeType}) $boundNode');
@@ -244,7 +247,7 @@
               if (bound != null) {
                 var tails = _findRawTypePathsToDeclaration(
                   parameterNode,
-                  bound.type!,
+                  bound.typeOrThrow,
                   end,
                   visited,
                 );
@@ -286,6 +289,19 @@
           visited,
         ),
       );
+      for (var typeParameter in startType.typeFormals) {
+        var bound = typeParameter.bound;
+        if (bound != null) {
+          paths.addAll(
+            _findRawTypePathsToDeclaration(
+              startParameter,
+              bound,
+              end,
+              visited,
+            ),
+          );
+        }
+      }
       for (var formalParameter in startType.parameters) {
         paths.addAll(
           _findRawTypePathsToDeclaration(
diff --git a/pkg/analyzer/lib/src/summary2/function_type_builder.dart b/pkg/analyzer/lib/src/summary2/function_type_builder.dart
index bdbc0ba..faeefe2 100644
--- a/pkg/analyzer/lib/src/summary2/function_type_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/function_type_builder.dart
@@ -168,7 +168,7 @@
     if (node == null) {
       return _dynamicType;
     } else {
-      return node.type!;
+      return node.typeOrThrow;
     }
   }
 
diff --git a/pkg/analyzer/lib/src/summary2/named_type_builder.dart b/pkg/analyzer/lib/src/summary2/named_type_builder.dart
index 47ea3f0..56056ce 100644
--- a/pkg/analyzer/lib/src/summary2/named_type_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/named_type_builder.dart
@@ -57,7 +57,7 @@
     List<DartType> arguments;
     var argumentList = node.typeArguments;
     if (argumentList != null) {
-      arguments = argumentList.arguments.map((n) => n.type!).toList();
+      arguments = argumentList.arguments.map((n) => n.typeOrThrow).toList();
     } else {
       arguments = <DartType>[];
     }
@@ -154,13 +154,13 @@
   DartType _buildAliasedType(TypeAnnotation? node) {
     if (_isNonFunctionTypeAliasesEnabled) {
       if (node != null) {
-        return _buildType(node.type!);
+        return _buildType(node.typeOrThrow);
       } else {
         return _dynamicType;
       }
     } else {
       if (node is GenericFunctionType) {
-        return _buildType(node.type!);
+        return _buildType(node.typeOrThrow);
       } else {
         return FunctionTypeImpl(
           typeFormals: const <TypeParameterElement>[],
@@ -233,7 +233,7 @@
     if (node == null) {
       return _dynamicType;
     } else {
-      return _buildType(node.type!);
+      return _buildType(node.typeOrThrow);
     }
   }
 
diff --git a/pkg/analyzer/lib/src/summary2/simply_bounded.dart b/pkg/analyzer/lib/src/summary2/simply_bounded.dart
index a325de8..45a0336 100644
--- a/pkg/analyzer/lib/src/summary2/simply_bounded.dart
+++ b/pkg/analyzer/lib/src/summary2/simply_bounded.dart
@@ -145,6 +145,7 @@
       var collector = _TypeCollector();
       if (type is GenericFunctionType) {
         collector.addType(type.returnType);
+        collector.visitTypeParameters(type.typeParameters);
         collector.visitParameters(type.parameters);
       } else {
         collector.addType(type);
@@ -283,6 +284,7 @@
     if (type is GenericFunctionType) {
       var collector = _TypeCollector();
       collector.addType(type.returnType);
+      collector.visitTypeParameters(type.typeParameters);
       collector.visitParameters(type.parameters);
       for (var type in collector.types) {
         if (!_visitType(dependencies, type, allowTypeParameters)) {
@@ -326,4 +328,12 @@
       visitParameter(parameter);
     }
   }
+
+  void visitTypeParameters(TypeParameterList? node) {
+    if (node != null) {
+      for (var typeParameter in node.typeParameters) {
+        addType(typeParameter.bound);
+      }
+    }
+  }
 }
diff --git a/pkg/analyzer/lib/src/summary2/types_builder.dart b/pkg/analyzer/lib/src/summary2/types_builder.dart
index 3555861..af20893 100644
--- a/pkg/analyzer/lib/src/summary2/types_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/types_builder.dart
@@ -264,7 +264,7 @@
   }
 
   InterfaceType _inferSingle(TypeNameImpl mixinNode) {
-    var mixinType = _interfaceType(mixinNode.type!);
+    var mixinType = _interfaceType(mixinNode.typeOrThrow);
 
     if (mixinNode.typeArguments != null) {
       return mixinType;
@@ -303,6 +303,8 @@
       mixinElement,
       mixinSupertypeConstraints,
       matchingInterfaceTypes,
+      genericMetadataIsEnabled:
+          mixinElement.library.featureSet.isEnabled(Feature.generic_metadata),
     );
     if (inferredTypeArguments != null) {
       var inferredMixin = mixinElement.instantiate(
diff --git a/pkg/analyzer/lib/src/task/options.dart b/pkg/analyzer/lib/src/task/options.dart
index 5ed06e0..5110041 100644
--- a/pkg/analyzer/lib/src/task/options.dart
+++ b/pkg/analyzer/lib/src/task/options.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:collection';
-
 import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/error/error.dart';
 import 'package:analyzer/error/listener.dart';
@@ -21,6 +19,7 @@
 import 'package:analyzer/src/lint/registry.dart';
 import 'package:analyzer/src/plugin/options.dart';
 import 'package:analyzer/src/util/yaml.dart';
+import 'package:analyzer/src/utilities/extensions/string.dart';
 import 'package:source_span/source_span.dart';
 import 'package:yaml/yaml.dart';
 
@@ -57,7 +56,7 @@
       errors.addAll(validationErrors);
     }
 
-    var node = getValue(options, AnalyzerOptions.include);
+    var node = options.valueAt(AnalyzerOptions.include);
     if (node == null) {
       return;
     }
@@ -117,6 +116,7 @@
   static const String enableSuperMixins = 'enableSuperMixins';
   static const String enablePreviewDart2 = 'enablePreviewDart2';
 
+  static const String cannotIgnore = 'cannot-ignore';
   static const String enableExperiment = 'enable-experiment';
   static const String errors = 'errors';
   static const String exclude = 'exclude';
@@ -152,6 +152,7 @@
 
   /// Supported top-level `analyzer` options.
   static const List<String> topLevel = [
+    cannotIgnore,
     enableExperiment,
     errors,
     exclude,
@@ -171,10 +172,14 @@
   /// Supported `analyzer` language options.
   static const List<String> languageOptions = [strictInference, strictRawTypes];
 
-  // Supported 'analyzer' optional checks options.
+  /// Supported 'analyzer' optional checks options.
   static const List<String> optionalChecksOptions = [
     chromeOsManifestChecks,
   ];
+
+  /// Proposed values for a `true` or `false` option.
+  static String get trueOrFalseProposal =>
+      AnalyzerOptions.trueOrFalse.quotedAndCommaSeparatedWithAnd;
 }
 
 /// Validates `analyzer` options.
@@ -186,10 +191,69 @@
           ErrorFilterOptionValidator(),
           EnabledExperimentsValidator(),
           LanguageOptionValidator(),
-          OptionalChecksValueValidator()
+          OptionalChecksValueValidator(),
+          CannotIgnoreOptionValidator(),
         ]);
 }
 
+/// Validates the `analyzer` `cannot-ignore` option.
+///
+/// This includes the format of the `cannot-ignore` section, the format of
+/// values in the section, and whether each value is a valid string.
+class CannotIgnoreOptionValidator extends OptionsValidator {
+  /// Lazily populated set of error codes.
+  static final Set<String> _errorCodes =
+      errorCodeValues.map((ErrorCode code) => code.name).toSet();
+
+  /// Lazily populated set of lint codes.
+  late final Set<String> _lintCodes = Registry.ruleRegistry.rules
+      .map((rule) => rule.name.toUpperCase())
+      .toSet();
+
+  @override
+  void validate(ErrorReporter reporter, YamlMap options) {
+    var analyzer = options.valueAt(AnalyzerOptions.analyzer);
+    if (analyzer is YamlMap) {
+      var unignorableNames = analyzer.valueAt(AnalyzerOptions.cannotIgnore);
+      if (unignorableNames is YamlList) {
+        var listedNames = <String>{};
+        for (var unignorableNameNode in unignorableNames.nodes) {
+          var unignorableName = unignorableNameNode.value;
+          if (unignorableName is String) {
+            if (AnalyzerOptions.severities.contains(unignorableName)) {
+              listedNames.add(unignorableName);
+              continue;
+            }
+            var upperCaseName = unignorableName.toUpperCase();
+            if (!_errorCodes.contains(upperCaseName) &&
+                !_lintCodes.contains(upperCaseName)) {
+              reporter.reportErrorForSpan(
+                  AnalysisOptionsWarningCode.UNRECOGNIZED_ERROR_CODE,
+                  unignorableNameNode.span,
+                  [unignorableName]);
+            } else if (listedNames.contains(upperCaseName)) {
+              // TODO(srawlins): Create a "duplicate value" code and report it
+              // here.
+            } else {
+              listedNames.add(upperCaseName);
+            }
+          } else {
+            reporter.reportErrorForSpan(
+                AnalysisOptionsWarningCode.INVALID_SECTION_FORMAT,
+                unignorableNameNode.span,
+                [AnalyzerOptions.cannotIgnore]);
+          }
+        }
+      } else if (unignorableNames != null) {
+        reporter.reportErrorForSpan(
+            AnalysisOptionsWarningCode.INVALID_SECTION_FORMAT,
+            unignorableNames.span,
+            [AnalyzerOptions.cannotIgnore]);
+      }
+    }
+  }
+}
+
 /// Convenience class for composing validators.
 class CompositeValidator extends OptionsValidator {
   final List<OptionsValidator> validators;
@@ -203,15 +267,11 @@
 
 /// Validates `analyzer` language configuration options.
 class EnabledExperimentsValidator extends OptionsValidator {
-  ErrorBuilder builder = ErrorBuilder(AnalyzerOptions.languageOptions);
-  ErrorBuilder trueOrFalseBuilder = TrueOrFalseValueErrorBuilder();
-
   @override
   void validate(ErrorReporter reporter, YamlMap options) {
-    var analyzer = getValue(options, AnalyzerOptions.analyzer);
+    var analyzer = options.valueAt(AnalyzerOptions.analyzer);
     if (analyzer is YamlMap) {
-      var experimentNames =
-          getValue(analyzer, AnalyzerOptions.enableExperiment);
+      var experimentNames = analyzer.valueAt(AnalyzerOptions.enableExperiment);
       if (experimentNames is YamlList) {
         var flags =
             experimentNames.nodes.map((node) => node.toString()).toList();
@@ -242,34 +302,39 @@
 
 /// Builds error reports with value proposals.
 class ErrorBuilder {
-  String? proposal;
-  late final AnalysisOptionsWarningCode code;
+  static AnalysisOptionsWarningCode get noProposalCode =>
+      AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITHOUT_VALUES;
+
+  static AnalysisOptionsWarningCode get pluralProposalCode =>
+      AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUES;
+
+  static AnalysisOptionsWarningCode get singularProposalCode =>
+      AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUE;
+
+  final String proposal;
+
+  final AnalysisOptionsWarningCode code;
 
   /// Create a builder for the given [supportedOptions].
-  ErrorBuilder(List<String> supportedOptions) {
+  factory ErrorBuilder(List<String> supportedOptions) {
+    var proposal = supportedOptions.quotedAndCommaSeparatedWithAnd;
     if (supportedOptions.isEmpty) {
-      code = noProposalCode;
+      return ErrorBuilder._(proposal: proposal, code: noProposalCode);
     } else if (supportedOptions.length == 1) {
-      proposal = "'${supportedOptions.join()}'";
-      code = singularProposalCode;
+      return ErrorBuilder._(proposal: proposal, code: singularProposalCode);
     } else {
-      proposal = StringUtilities.printListOfQuotedNames(supportedOptions);
-      code = pluralProposalCode;
+      return ErrorBuilder._(proposal: proposal, code: pluralProposalCode);
     }
   }
 
-  AnalysisOptionsWarningCode get noProposalCode =>
-      AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITHOUT_VALUES;
-
-  AnalysisOptionsWarningCode get pluralProposalCode =>
-      AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUES;
-
-  AnalysisOptionsWarningCode get singularProposalCode =>
-      AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUE;
+  ErrorBuilder._({
+    required this.proposal,
+    required this.code,
+  });
 
   /// Report an unsupported [node] value, defined in the given [scopeName].
   void reportError(ErrorReporter reporter, String scopeName, YamlNode node) {
-    if (proposal != null) {
+    if (proposal.isNotEmpty) {
       reporter.reportErrorForSpan(
           code, node.span, [scopeName, node.value, proposal]);
     } else {
@@ -290,38 +355,26 @@
   static final String legalValueString =
       StringUtilities.printListOfQuotedNames(legalValues);
 
-  /// Lazily populated set of error codes (hashed for speedy lookup).
-  static HashSet<String>? _errorCodes;
-
-  /// Legal error code names.
-  static Set<String> get errorCodes {
-    if (_errorCodes == null) {
-      _errorCodes = HashSet<String>();
-      // Engine codes.
-      _errorCodes!.addAll(errorCodeValues.map((ErrorCode code) => code.name));
-    }
-    return _errorCodes!;
-  }
+  /// Lazily populated set of error codes.
+  static final Set<String> _errorCodes =
+      errorCodeValues.map((ErrorCode code) => code.name).toSet();
 
   /// Lazily populated set of lint codes.
-  Set<String>? _lintCodes;
-
-  Set<String> get lintCodes {
-    return _lintCodes ??= Set.from(
-        Registry.ruleRegistry.rules.map((rule) => rule.name.toUpperCase()));
-  }
+  late final Set<String> _lintCodes = Registry.ruleRegistry.rules
+      .map((rule) => rule.name.toUpperCase())
+      .toSet();
 
   @override
   void validate(ErrorReporter reporter, YamlMap options) {
-    var analyzer = getValue(options, AnalyzerOptions.analyzer);
+    var analyzer = options.valueAt(AnalyzerOptions.analyzer);
     if (analyzer is YamlMap) {
-      var filters = getValue(analyzer, AnalyzerOptions.errors);
+      var filters = analyzer.valueAt(AnalyzerOptions.errors);
       if (filters is YamlMap) {
-        String? value;
         filters.nodes.forEach((k, v) {
+          String? value;
           if (k is YamlScalar) {
             value = toUpperCase(k.value);
-            if (!errorCodes.contains(value) && !lintCodes.contains(value)) {
+            if (!_errorCodes.contains(value) && !_lintCodes.contains(value)) {
               reporter.reportErrorForSpan(
                   AnalysisOptionsWarningCode.UNRECOGNIZED_ERROR_CODE,
                   k.span,
@@ -341,8 +394,18 @@
                     legalValueString
                   ]);
             }
+          } else {
+            reporter.reportErrorForSpan(
+                AnalysisOptionsWarningCode.INVALID_SECTION_FORMAT,
+                v.span,
+                [AnalyzerOptions.enableExperiment]);
           }
         });
+      } else if (filters != null) {
+        reporter.reportErrorForSpan(
+            AnalysisOptionsWarningCode.INVALID_SECTION_FORMAT,
+            filters.span,
+            [AnalyzerOptions.enableExperiment]);
       }
     }
   }
@@ -350,14 +413,13 @@
 
 /// Validates `analyzer` language configuration options.
 class LanguageOptionValidator extends OptionsValidator {
-  ErrorBuilder builder = ErrorBuilder(AnalyzerOptions.languageOptions);
-  ErrorBuilder trueOrFalseBuilder = TrueOrFalseValueErrorBuilder();
+  final ErrorBuilder _builder = ErrorBuilder(AnalyzerOptions.languageOptions);
 
   @override
   void validate(ErrorReporter reporter, YamlMap options) {
-    var analyzer = getValue(options, AnalyzerOptions.analyzer);
+    var analyzer = options.valueAt(AnalyzerOptions.analyzer);
     if (analyzer is YamlMap) {
-      var language = getValue(analyzer, AnalyzerOptions.language);
+      var language = analyzer.valueAt(AnalyzerOptions.language);
       if (language is YamlMap) {
         language.nodes.forEach((k, v) {
           String? key, value;
@@ -373,7 +435,7 @@
                   AnalysisOptionsHintCode.SUPER_MIXINS_SETTING_DEPRECATED,
                   k.span);
             } else if (!AnalyzerOptions.languageOptions.contains(key)) {
-              builder.reportError(reporter, AnalyzerOptions.language, k);
+              _builder.reportError(reporter, AnalyzerOptions.language, k);
             } else {
               // If we have a valid key, go on and check the value.
               validKey = true;
@@ -382,7 +444,10 @@
           if (validKey && v is YamlScalar) {
             value = toLowerCase(v.value);
             if (!AnalyzerOptions.trueOrFalse.contains(value)) {
-              trueOrFalseBuilder.reportError(reporter, key!, v);
+              reporter.reportErrorForSpan(
+                  AnalysisOptionsWarningCode.UNSUPPORTED_VALUE,
+                  v.span,
+                  [key, v.value, AnalyzerOptions.trueOrFalseProposal]);
             }
           }
         });
@@ -409,18 +474,18 @@
 
 /// Validates `analyzer` optional-checks value configuration options.
 class OptionalChecksValueValidator extends OptionsValidator {
-  ErrorBuilder builder = ErrorBuilder(AnalyzerOptions.optionalChecksOptions);
-  ErrorBuilder trueOrFalseBuilder = TrueOrFalseValueErrorBuilder();
+  final ErrorBuilder _builder =
+      ErrorBuilder(AnalyzerOptions.optionalChecksOptions);
 
   @override
   void validate(ErrorReporter reporter, YamlMap options) {
-    var analyzer = getValue(options, AnalyzerOptions.analyzer);
+    var analyzer = options.valueAt(AnalyzerOptions.analyzer);
     if (analyzer is YamlMap) {
-      var v = getValue(analyzer, AnalyzerOptions.optionalChecks);
+      var v = analyzer.valueAt(AnalyzerOptions.optionalChecks);
       if (v is YamlScalar) {
         var value = toLowerCase(v.value);
         if (value != AnalyzerOptions.chromeOsManifestChecks) {
-          builder.reportError(
+          _builder.reportError(
               reporter, AnalyzerOptions.chromeOsManifestChecks, v);
         }
       } else if (v is YamlMap) {
@@ -429,16 +494,24 @@
           if (k is YamlScalar) {
             key = k.value?.toString();
             if (key != AnalyzerOptions.chromeOsManifestChecks) {
-              builder.reportError(
+              _builder.reportError(
                   reporter, AnalyzerOptions.chromeOsManifestChecks, k);
             } else {
               value = toLowerCase(v.value);
               if (!AnalyzerOptions.trueOrFalse.contains(value)) {
-                trueOrFalseBuilder.reportError(reporter, key!, v);
+                reporter.reportErrorForSpan(
+                    AnalysisOptionsWarningCode.UNSUPPORTED_VALUE,
+                    v.span,
+                    [key!, v.value, AnalyzerOptions.trueOrFalseProposal]);
               }
             }
           }
         });
+      } else if (v != null) {
+        reporter.reportErrorForSpan(
+            AnalysisOptionsWarningCode.INVALID_SECTION_FORMAT,
+            v.span,
+            [AnalyzerOptions.enableExperiment]);
       }
     }
   }
@@ -471,19 +544,22 @@
 
 /// Validates `analyzer` strong-mode value configuration options.
 class StrongModeOptionValueValidator extends OptionsValidator {
-  ErrorBuilder builder = ErrorBuilder(AnalyzerOptions.strongModeOptions);
-  ErrorBuilder trueOrFalseBuilder = TrueOrFalseValueErrorBuilder();
+  final ErrorBuilder _builder = ErrorBuilder(AnalyzerOptions.strongModeOptions);
 
   @override
   void validate(ErrorReporter reporter, YamlMap options) {
-    var analyzer = getValue(options, AnalyzerOptions.analyzer);
+    var analyzer = options.valueAt(AnalyzerOptions.analyzer);
     if (analyzer is YamlMap) {
-      var v = getValue(analyzer, AnalyzerOptions.strong_mode);
+      var v = analyzer.valueAt(AnalyzerOptions.strong_mode);
       if (v is YamlScalar) {
         var value = toLowerCase(v.value);
         if (!AnalyzerOptions.trueOrFalse.contains(value)) {
-          trueOrFalseBuilder.reportError(
-              reporter, AnalyzerOptions.strong_mode, v);
+          reporter.reportErrorForSpan(
+              AnalysisOptionsWarningCode.UNSUPPORTED_VALUE, v.span, [
+            AnalyzerOptions.strong_mode,
+            v.value,
+            AnalyzerOptions.trueOrFalseProposal
+          ]);
         } else if (value == 'false') {
           reporter.reportErrorForSpan(
               AnalysisOptionsWarningCode.SPEC_MODE_REMOVED, v.span);
@@ -498,7 +574,7 @@
           if (k is YamlScalar) {
             key = k.value?.toString();
             if (!AnalyzerOptions.strongModeOptions.contains(key)) {
-              builder.reportError(reporter, AnalyzerOptions.strong_mode, k);
+              _builder.reportError(reporter, AnalyzerOptions.strong_mode, k);
             } else if (key == AnalyzerOptions.declarationCasts) {
               reporter.reportErrorForSpan(
                   AnalysisOptionsWarningCode.ANALYSIS_OPTION_DEPRECATED,
@@ -512,10 +588,18 @@
           if (validKey && v is YamlScalar) {
             value = toLowerCase(v.value);
             if (!AnalyzerOptions.trueOrFalse.contains(value)) {
-              trueOrFalseBuilder.reportError(reporter, key!, v);
+              reporter.reportErrorForSpan(
+                  AnalysisOptionsWarningCode.UNSUPPORTED_VALUE,
+                  v.span,
+                  [key!, v.value, AnalyzerOptions.trueOrFalseProposal]);
             }
           }
         });
+      } else if (v != null) {
+        reporter.reportErrorForSpan(
+            AnalysisOptionsWarningCode.INVALID_SECTION_FORMAT,
+            v.span,
+            [AnalyzerOptions.enableExperiment]);
       }
     }
   }
@@ -533,25 +617,19 @@
 class TopLevelOptionValidator extends OptionsValidator {
   final String pluginName;
   final List<String> supportedOptions;
-  late final String _valueProposal;
-  late final AnalysisOptionsWarningCode _warningCode;
+  final String _valueProposal;
+  final AnalysisOptionsWarningCode _warningCode;
 
-  TopLevelOptionValidator(this.pluginName, this.supportedOptions) {
-    assert(supportedOptions.isNotEmpty);
-    if (supportedOptions.length > 1) {
-      _valueProposal = StringUtilities.printListOfQuotedNames(supportedOptions);
-      _warningCode =
-          AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUES;
-    } else {
-      _valueProposal = "'${supportedOptions.join()}'";
-      _warningCode =
-          AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUE;
-    }
-  }
+  TopLevelOptionValidator(this.pluginName, this.supportedOptions)
+      : assert(supportedOptions.isNotEmpty),
+        _valueProposal = supportedOptions.quotedAndCommaSeparatedWithAnd,
+        _warningCode = supportedOptions.length == 1
+            ? AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUE
+            : AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUES;
 
   @override
   void validate(ErrorReporter reporter, YamlMap options) {
-    var node = getValue(options, pluginName);
+    var node = options.valueAt(pluginName);
     if (node is YamlMap) {
       node.nodes.forEach((k, v) {
         if (k is YamlScalar) {
@@ -563,18 +641,11 @@
         //TODO(pq): consider an error if the node is not a Scalar.
       });
     }
+    // TODO(srawlins): Report non-Map with
+    //  AnalysisOptionsWarningCode.INVALID_SECTION_FORMAT.
   }
 }
 
-/// An error-builder that knows about `true` and `false` legal values.
-class TrueOrFalseValueErrorBuilder extends ErrorBuilder {
-  TrueOrFalseValueErrorBuilder() : super(AnalyzerOptions.trueOrFalse);
-
-  @override
-  AnalysisOptionsWarningCode get pluralProposalCode =>
-      AnalysisOptionsWarningCode.UNSUPPORTED_VALUE;
-}
-
 class _OptionsProcessor {
   /// Apply the options in the given [optionMap] to the given analysis
   /// [options].
@@ -582,19 +653,18 @@
     if (optionMap == null) {
       return;
     }
-    var analyzer = getValue(optionMap, AnalyzerOptions.analyzer);
+    var analyzer = optionMap.valueAt(AnalyzerOptions.analyzer);
     if (analyzer is YamlMap) {
       // Process strong mode option.
-      var strongMode = getValue(analyzer, AnalyzerOptions.strong_mode);
+      var strongMode = analyzer.valueAt(AnalyzerOptions.strong_mode);
       _applyStrongOptions(options, strongMode);
 
       // Process filters.
-      var filters = getValue(analyzer, AnalyzerOptions.errors);
+      var filters = analyzer.valueAt(AnalyzerOptions.errors);
       _applyProcessors(options, filters);
 
       // Process enabled experiments.
-      var experimentNames =
-          getValue(analyzer, AnalyzerOptions.enableExperiment);
+      var experimentNames = analyzer.valueAt(AnalyzerOptions.enableExperiment);
       if (experimentNames is YamlList) {
         List<String> enabledExperiments = <String>[];
         for (var element in experimentNames.nodes) {
@@ -610,19 +680,22 @@
       }
 
       // Process optional checks options.
-      var optionalChecks = getValue(analyzer, AnalyzerOptions.optionalChecks);
+      var optionalChecks = analyzer.valueAt(AnalyzerOptions.optionalChecks);
       _applyOptionalChecks(options, optionalChecks);
 
       // Process language options.
-      var language = getValue(analyzer, AnalyzerOptions.language);
+      var language = analyzer.valueAt(AnalyzerOptions.language);
       _applyLanguageOptions(options, language);
 
       // Process excludes.
-      var excludes = getValue(analyzer, AnalyzerOptions.exclude);
+      var excludes = analyzer.valueAt(AnalyzerOptions.exclude);
       _applyExcludes(options, excludes);
 
+      var cannotIgnore = analyzer.valueAt(AnalyzerOptions.cannotIgnore);
+      _applyUnignorables(options, cannotIgnore);
+
       // Process plugins.
-      var names = getValue(analyzer, AnalyzerOptions.plugins);
+      var names = analyzer.valueAt(AnalyzerOptions.plugins);
       List<String> pluginNames = <String>[];
       var pluginName = _toString(names);
       if (pluginName != null) {
@@ -657,11 +730,11 @@
 
   void _applyExcludes(AnalysisOptionsImpl options, YamlNode? excludes) {
     if (excludes is YamlList) {
-      var excludeList = toStringList(excludes);
-      if (excludeList != null) {
-        options.excludePatterns = excludeList;
-      }
+      // TODO(srawlins): Report non-String items
+      options.excludePatterns = excludes.whereType<String>().toList();
     }
+    // TODO(srawlins): Report non-List with
+    //  AnalysisOptionsWarningCode.INVALID_SECTION_FORMAT.
   }
 
   void _applyLanguageOption(
@@ -741,6 +814,39 @@
     }
   }
 
+  void _applyUnignorables(AnalysisOptionsImpl options, YamlNode? cannotIgnore) {
+    if (cannotIgnore is YamlList) {
+      var names = <String>{};
+      var stringValues = cannotIgnore.whereType<String>().toSet();
+      for (var severity in AnalyzerOptions.severities) {
+        if (stringValues.contains(severity)) {
+          // [severity] is a marker denoting all error codes with severity
+          // equal to [severity].
+          stringValues.remove(severity);
+          // Replace name like 'error' with error codes with this named
+          // severity.
+          for (var e in errorCodeValues) {
+            // If the severity of [error] is also changed in this options file
+            // to be [severity], we add [error] to the un-ignorable list.
+            var processors = options.errorProcessors
+                .where((processor) => processor.code == e.name);
+            if (processors.isNotEmpty &&
+                processors.first.severity?.displayName == severity) {
+              names.add(e.name);
+              continue;
+            }
+            // Otherwise, add [error] if its default severity is [severity].
+            if (e.errorSeverity.displayName == severity) {
+              names.add(e.name);
+            }
+          }
+        }
+      }
+      names.addAll(stringValues.map((name) => name.toUpperCase()));
+      options.unignorableNames = names;
+    }
+  }
+
   String? _toString(YamlNode? node) {
     if (node is YamlScalar) {
       var value = node.value;
diff --git a/pkg/analyzer/lib/src/task/strong/checker.dart b/pkg/analyzer/lib/src/task/strong/checker.dart
index 0c4053d..e4fea47 100644
--- a/pkg/analyzer/lib/src/task/strong/checker.dart
+++ b/pkg/analyzer/lib/src/task/strong/checker.dart
@@ -21,14 +21,6 @@
     show CompileTimeErrorCode, StrongModeCode;
 import 'package:analyzer/src/task/inference_error.dart';
 
-DartType _elementType(Element? e) {
-  if (e == null) {
-    // Malformed code - just return dynamic.
-    return DynamicTypeImpl.instance;
-  }
-  return (e as dynamic).type;
-}
-
 Element? _getKnownElement(Expression expression) {
   if (expression is ParenthesizedExpression) {
     return _getKnownElement(expression.expression);
@@ -86,7 +78,7 @@
         // so no need to insert an error for this here.
         continue;
       }
-      checkArgument(arg, _elementType(element));
+      checkArgument(arg, element.type);
     }
   }
 
@@ -244,7 +236,6 @@
     node.visitChildren(this);
   }
 
-  // Check invocations
   /// Check constructor declaration to ensure correct super call placement.
   @override
   void visitConstructorDeclaration(ConstructorDeclaration node) {
@@ -270,8 +261,9 @@
   void visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
     var field = node.fieldName;
     var element = field.staticElement;
-    DartType staticType = _elementType(element);
-    checkAssignment(node.expression, staticType);
+    if (element != null) {
+      checkAssignment(node.expression, _elementType(element));
+    }
     node.visitChildren(this);
   }
 
@@ -279,9 +271,10 @@
   void visitDefaultFormalParameter(DefaultFormalParameter node) {
     // Check that defaults have the proper subtype.
     var parameter = node.parameter;
-    var parameterType = _elementType(parameter.declaredElement);
     var defaultValue = node.defaultValue;
-    if (defaultValue != null) {
+    var element = parameter.declaredElement;
+    if (defaultValue != null && element != null) {
+      var parameterType = _elementType(element);
       checkAssignment(defaultValue, parameterType);
     }
 
@@ -363,7 +356,7 @@
     var arguments = node.argumentList;
     var element = node.constructorName.staticElement;
     if (element != null) {
-      var type = _elementType(element) as FunctionType;
+      var type = element.type;
       checkArgumentList(arguments, type);
     }
     node.visitChildren(this);
@@ -376,7 +369,7 @@
     if (typeArgumentList != null) {
       var typeArguments = typeArgumentList.arguments;
       if (typeArguments.isNotEmpty) {
-        type = typeArguments[0].type!;
+        type = typeArguments[0].typeOrThrow;
       }
     } else {
       DartType staticType = node.typeOrThrow;
@@ -447,10 +440,10 @@
       if (typeArgumentsList != null) {
         NodeList<TypeAnnotation> typeArguments = typeArgumentsList.arguments;
         if (typeArguments.isNotEmpty) {
-          keyType = typeArguments[0].type!;
+          keyType = typeArguments[0].typeOrThrow;
         }
         if (typeArguments.length > 1) {
-          valueType = typeArguments[1].type!;
+          valueType = typeArguments[1].typeOrThrow;
         }
       } else {
         DartType staticType = node.typeOrThrow;
@@ -467,7 +460,7 @@
       if (typeArgumentsList != null) {
         NodeList<TypeAnnotation> typeArguments = typeArgumentsList.arguments;
         if (typeArguments.isNotEmpty) {
-          type = typeArguments[0].type!;
+          type = typeArguments[0].typeOrThrow;
         }
       } else {
         DartType staticType = node.typeOrThrow;
@@ -525,7 +518,7 @@
         var initializer = variable.initializer;
         if (initializer != null) {
           checkForCast(initializer,
-              from: initializer.typeOrThrow, to: type.type!);
+              from: initializer.typeOrThrow, to: type.typeOrThrow);
         }
       }
     }
@@ -709,7 +702,7 @@
     FunctionType functionType;
     var parent = body.parent;
     if (parent is Declaration) {
-      functionType = _elementType(parent.declaredElement) as FunctionType;
+      functionType = _elementType(parent.declaredElement!) as FunctionType;
     } else {
       assert(parent is FunctionExpression);
       functionType = (parent as FunctionExpression).staticType as FunctionType;
@@ -974,6 +967,21 @@
           to: loopVariableElement.type, from: elementType);
     }
   }
+
+  static DartType _elementType(Element e) {
+    if (e is ConstructorElement) {
+      return e.type;
+    } else if (e is FieldElement) {
+      return e.type;
+    } else if (e is MethodElement) {
+      return e.type;
+    } else if (e is ParameterElement) {
+      return e.type;
+    } else if (e is PropertyAccessorElement) {
+      return e.type;
+    }
+    throw StateError('${e.runtimeType} is unhandled type');
+  }
 }
 
 class _TopLevelInitializerValidator extends RecursiveAstVisitor<void> {
diff --git a/pkg/analyzer/lib/src/test_utilities/find_element.dart b/pkg/analyzer/lib/src/test_utilities/find_element.dart
index 53cdcc4..75e989e 100644
--- a/pkg/analyzer/lib/src/test_utilities/find_element.dart
+++ b/pkg/analyzer/lib/src/test_utilities/find_element.dart
@@ -149,6 +149,7 @@
     return result!;
   }
 
+  @override
   ParameterElement parameter(String name) {
     ParameterElement? result;
 
@@ -527,6 +528,28 @@
     throw StateError('Not found: $name');
   }
 
+  ParameterElement parameter(String name) {
+    ParameterElement? result;
+
+    for (var class_ in unitElement.types) {
+      for (var constructor in class_.constructors) {
+        for (var parameter in constructor.parameters) {
+          if (parameter.name == name) {
+            if (result != null) {
+              throw StateError('Not unique: $name');
+            }
+            result = parameter;
+          }
+        }
+      }
+    }
+
+    if (result != null) {
+      return result;
+    }
+    throw StateError('Not found: $name');
+  }
+
   PropertyAccessorElement setter(String name, {String? of}) {
     PropertyAccessorElement? result;
 
diff --git a/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart b/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
index 04e8cc2..8c3a9a5 100644
--- a/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
+++ b/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
@@ -459,7 +459,7 @@
   int get length => 0;
   Iterable<V> get values;
 
-  V? operator [](K key);
+  V? operator [](Object? key);
   void operator []=(K key, V value);
 
   Map<RK, RV> cast<RK, RV>();
@@ -677,6 +677,12 @@
 
 class Struct extends NativeType {}
 
+class Packed {
+  final int memberAlignment;
+
+  const Packed(this.memberAlignment);
+}
+
 abstract class DynamicLibrary {}
 
 extension DynamicLibraryExtension on DynamicLibrary {
@@ -691,7 +697,34 @@
 }
 
 class Array<T extends NativeType> extends NativeType {
-  external const factory Array(int dimension1);
+  const factory Array(int dimension1,
+      [int dimension2,
+      int dimension3,
+      int dimension4,
+      int dimension5]) = _ArraySize<T>;
+
+  const factory Array.multi(List<int> dimensions) = _ArraySize<T>.multi;
+}
+
+class _ArraySize<T extends NativeType> implements Array<T> {
+  final int? dimension1;
+  final int? dimension2;
+  final int? dimension3;
+  final int? dimension4;
+  final int? dimension5;
+
+  final List<int>? dimensions;
+
+  const _ArraySize(this.dimension1,
+      [this.dimension2, this.dimension3, this.dimension4, this.dimension5])
+      : dimensions = null;
+
+  const _ArraySize.multi(this.dimensions)
+      : dimension1 = null,
+        dimension2 = null,
+        dimension3 = null,
+        dimension4 = null,
+        dimension5 = null;
 }
 
 extension StructPointer<T extends Struct> on Pointer<T> {
diff --git a/pkg/analyzer/lib/src/util/yaml.dart b/pkg/analyzer/lib/src/util/yaml.dart
index 1696085..108ea8d 100644
--- a/pkg/analyzer/lib/src/util/yaml.dart
+++ b/pkg/analyzer/lib/src/util/yaml.dart
@@ -8,45 +8,6 @@
 import 'package:yaml/src/event.dart';
 import 'package:yaml/yaml.dart';
 
-/// Given a [map], return the [YamlNode] associated with the given [key], or
-/// `null` if there is no matching key.
-YamlNode? getKey(YamlMap map, String key) {
-  for (YamlNode k in map.nodes.keys) {
-    if (k is YamlScalar && k.value == key) {
-      return k;
-    }
-  }
-  return null;
-}
-
-/// Given a [map], return the value associated with the key whose value matches
-/// the given [key], or `null` if there is no matching key.
-YamlNode? getValue(YamlMap map, String key) {
-  for (var k in map.nodes.keys) {
-    if (k is YamlScalar && k.value == key) {
-      return map.nodes[k];
-    }
-  }
-  return null;
-}
-
-/// If all of the elements of [list] are strings, return a list of strings
-/// containing the same elements. Otherwise, return `null`.
-List<String>? toStringList(List? list) {
-  if (list == null) {
-    return null;
-  }
-  List<String> stringList = <String>[];
-  for (var element in list) {
-    if (element is String) {
-      stringList.add(element);
-    } else {
-      return null;
-    }
-  }
-  return stringList;
-}
-
 bool _contains(YamlList l1, YamlNode n2) {
   for (YamlNode n1 in l1.nodes) {
     if (n1.value == n2.value) {
@@ -82,9 +43,9 @@
       return YamlMap.internal(map, o1.span, CollectionStyle.BLOCK);
     }
 
-    if (isListOfString(o1) && isMapToBools(o2)) {
+    if (_isListOfString(o1) && _isMapToBools(o2)) {
       o1 = listToMap(o1 as YamlList);
-    } else if (isMapToBools(o1) && isListOfString(o2)) {
+    } else if (_isMapToBools(o1) && _isListOfString(o2)) {
       o2 = listToMap(o2 as YamlList);
     }
 
@@ -117,9 +78,10 @@
     m1.nodes.forEach((k, v) {
       merged[k] = v;
     });
-    m2.nodes.forEach((k, v) {
+    m2.nodeMap.forEach((k, v) {
+      var value = k.value;
       var mergedKey =
-          merged.keys.firstWhere((key) => key.value == k.value, orElse: () => k)
+          merged.keys.firstWhere((key) => key.value == value, orElse: () => k)
               as YamlScalar;
       var o1 = merged[mergedKey];
       if (o1 != null) {
@@ -131,11 +93,49 @@
     return YamlMap.internal(merged, m1.span, CollectionStyle.BLOCK);
   }
 
-  static bool isListOfString(Object? o) =>
+  static bool _isListOfString(Object? o) =>
       o is YamlList &&
       o.nodes.every((e) => e is YamlScalar && e.value is String);
 
-  static bool isMapToBools(Object? o) =>
+  static bool _isMapToBools(Object? o) =>
       o is YamlMap &&
       o.nodes.values.every((v) => v is YamlScalar && v.value is bool);
 }
+
+extension YamlMapExtensions on YamlMap {
+  /// 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) {
+    for (var keyNode in nodes.keys) {
+      if (keyNode is YamlScalar && keyNode.value == key) {
+        return nodes[keyNode];
+      }
+    }
+    return null;
+  }
+
+  /// Return the [YamlNode] 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 [YamlNode] associated with the given [key], or `null` if there
+  /// is no matching key.
+  YamlNode? getKey(String key) {
+    for (YamlNode k in nodes.keys) {
+      if (k is YamlScalar && k.value == key) {
+        return k;
+      }
+    }
+    return null;
+  }
+
+  /// Return [nodes] as a Map with [YamlNode] keys.
+  Map<YamlNode, YamlNode> get nodeMap => nodes.cast<YamlNode, YamlNode>();
+}
diff --git a/pkg/analyzer/lib/src/utilities/extensions/string.dart b/pkg/analyzer/lib/src/utilities/extensions/string.dart
index d583029..6651cd7 100644
--- a/pkg/analyzer/lib/src/utilities/extensions/string.dart
+++ b/pkg/analyzer/lib/src/utilities/extensions/string.dart
@@ -14,24 +14,46 @@
   String get commaSeparatedWithOr => _commaSeparated('or');
 
   /// Produce a comma-separated representation of this list, with the last
+  /// element preceded by 'and' when there are more than two elements in this
+  /// list, and a pair of single quotes surrounding each element.
+  String get quotedAndCommaSeparatedWithAnd =>
+      _commaSeparated('and', quoted: true);
+
+  /// Produce a comma-separated representation of this list, with the last
   /// element preceded by the [conjunction] when there are more than two
   /// elements in this list.
-  String _commaSeparated(String conjunction) {
+  ///
+  /// Each element is surrounded by a pair of single quotes if [quoted] is true.
+  String _commaSeparated(String conjunction, {bool quoted = false}) {
     if (length == 0) {
       return '';
     } else if (length == 1) {
-      return this[0];
+      return quoted ? "'${this[0]}'" : this[0];
     } else if (length == 2) {
-      return '${this[0]} $conjunction ${this[1]}';
+      return quoted
+          ? "'${this[0]}' $conjunction '${this[1]}'"
+          : '${this[0]} $conjunction ${this[1]}';
     } else {
       var buffer = StringBuffer();
       for (int i = 0; i < length - 1; i++) {
+        if (quoted) {
+          buffer.write("'");
+        }
         buffer.write(this[i]);
+        if (quoted) {
+          buffer.write("'");
+        }
         buffer.write(', ');
       }
       buffer.write(conjunction);
       buffer.write(' ');
+      if (quoted) {
+        buffer.write("'");
+      }
       buffer.write(this[length - 1]);
+      if (quoted) {
+        buffer.write("'");
+      }
       return buffer.toString();
     }
   }
diff --git a/pkg/analyzer/lib/src/workspace/bazel.dart b/pkg/analyzer/lib/src/workspace/bazel.dart
index fdf4b00..ee0c6d9 100644
--- a/pkg/analyzer/lib/src/workspace/bazel.dart
+++ b/pkg/analyzer/lib/src/workspace/bazel.dart
@@ -13,44 +13,11 @@
 import 'package:analyzer/src/generated/source_io.dart';
 import 'package:analyzer/src/summary/package_bundle_reader.dart';
 import 'package:analyzer/src/util/uri.dart';
+import 'package:analyzer/src/workspace/bazel_watcher.dart';
 import 'package:analyzer/src/workspace/workspace.dart';
 import 'package:collection/collection.dart';
 import 'package:path/path.dart' as path;
 import 'package:pub_semver/pub_semver.dart';
-import 'package:watcher/watcher.dart';
-
-/// Notification that we issue in [BazelWorkspace.findFile] when searching for
-/// generated files.
-///
-/// This allows clients to watch for changes to the generated files.
-class BazelFileNotification {
-  /// Candidate paths that we searched.
-  ///
-  /// If it's a singleton, then the file was found/resolved.
-  final List<String> candidates;
-
-  /// Absolute path that we tried searching for.
-  ///
-  /// This is not necessarily the path of the actual file that will be used. See
-  /// [BazelWorkspace.findFile] for details.
-  final String requested;
-
-  final ResourceProvider _provider;
-
-  BazelFileNotification(this.requested, this.candidates, this._provider);
-
-  BazelFileWatcher watcher(
-          {required Duration pollingDelayShort,
-          required Duration pollingDelayLong,
-          Timer Function(Duration, void Function(Timer)) timerFactory =
-              _defaultTimerFactory}) =>
-      BazelFileWatcher(candidates, _provider, pollingDelayShort,
-          pollingDelayLong, timerFactory);
-
-  static Timer _defaultTimerFactory(
-          Duration duration, void Function(Timer) callback) =>
-      Timer.periodic(duration, callback);
-}
 
 /// Instances of the class `BazelFileUriResolver` resolve `file` URI's by first
 /// resolving file uri's in the expected way, and then by looking in the
@@ -76,140 +43,6 @@
   }
 }
 
-/// Watches a list of files that should be generated by Bazel.
-///
-/// If we didn't find the file initially, we'll have more that one potential
-/// path. We'll poll them with a shorter delay waiting for at least one
-/// of the paths to become valid (we assume that users will generate the rather
-/// sooner than later since they will likely see errors due to unresolved
-/// files). Once a file appears, we switch to a different mode, where we only
-/// watch that particular file and poll it less frequently. If the file is
-/// deleted we go back to the initial mode of eager polling for all paths.
-class BazelFileWatcher {
-  /// The paths of files that we watch for.
-  ///
-  /// If it's a singleton, then the file was found/resolved by the
-  /// [BazelWorkspace].
-  final List<String> _candidates;
-
-  final _eventsController = StreamController<WatchEvent>.broadcast();
-
-  /// The time of last modification of the file under [_validPath].
-  int? _lastModified;
-
-  /// How often do we poll a file that we have found.
-  final Duration _pollingDelayLong;
-
-  /// How often do we poll when none of potential files exist.
-  final Duration _pollingDelayShort;
-
-  final ResourceProvider _provider;
-
-  /// One of the [_candidates] that is valid, i.e., we found a file with that
-  /// path.
-  String? _validPath;
-
-  Timer? _timer;
-
-  /// Used to contruct a [Timer] for polling.
-  final Timer Function(Duration, void Function(Timer)) _timerFactory;
-
-  BazelFileWatcher(this._candidates, this._provider, this._pollingDelayShort,
-      this._pollingDelayLong, this._timerFactory);
-
-  Stream<WatchEvent> get events => _eventsController.stream;
-
-  /// Starts watching the files.
-  ///
-  /// To avoid missing events, the clients should first start listening on
-  /// [events] and then call [start].
-  void start() {
-    assert(_timer == null);
-    var info = _pollAll();
-    if (info != null) {
-      _validPath = info.path;
-      _lastModified = info.modified;
-      _setPollingDelayToLong();
-    } else {
-      _setPollingDelayToShort();
-    }
-  }
-
-  void stop() {
-    _timer?.cancel();
-    _eventsController.close();
-  }
-
-  void _poll() {
-    if (_eventsController.isClosed) return;
-
-    int? modified;
-    if (_validPath == null) {
-      var info = _pollAll();
-      if (info != null) {
-        _validPath = info.path;
-        modified = info.modified;
-      }
-    } else {
-      modified = _pollOne(_validPath!);
-    }
-
-    // If there is no file, then we have nothing to do.
-    if (_validPath == null) return;
-
-    if (modified == null && _lastModified != null) {
-      // The file is no longer there, so let's issue a REMOVE event, unset
-      // `_validPath` and set the timer to poll more frequently.
-      _eventsController.add(WatchEvent(ChangeType.REMOVE, _validPath!));
-      _validPath = null;
-      _setPollingDelayToShort();
-    } else if (modified != null && _lastModified == null) {
-      _eventsController.add(WatchEvent(ChangeType.ADD, _validPath!));
-      _setPollingDelayToLong();
-    } else if (_lastModified != null && modified != _lastModified) {
-      _eventsController.add(WatchEvent(ChangeType.MODIFY, _validPath!));
-    }
-    _lastModified = modified;
-  }
-
-  /// Tries polling all the possible paths.
-  ///
-  /// Will set [_validPath] and return its modified time if a file is found.
-  /// Returns [null] if nothing is found.
-  FileInfo? _pollAll() {
-    assert(_validPath == null);
-    for (var path in _candidates) {
-      var modified = _pollOne(path);
-      if (modified != null) {
-        return FileInfo(path, modified);
-      }
-    }
-    return null;
-  }
-
-  /// Returns the modified time of the path or `null` if the file does not
-  /// exist.
-  int? _pollOne(String path) {
-    try {
-      var file = _provider.getFile(path);
-      return file.modificationStamp;
-    } on FileSystemException catch (_) {
-      // File doesn't exist, so return null.
-      return null;
-    }
-  }
-
-  void _setPollingDelayToLong() {
-    _timer?.cancel();
-    _timer = _timerFactory(_pollingDelayLong, (_) => _poll());
-  }
-
-  void _setPollingDelayToShort() {
-    _timer?.cancel();
-    _timer = _timerFactory(_pollingDelayShort, (_) => _poll());
-  }
-}
-
 /// The [UriResolver] that can resolve `package` URIs in [BazelWorkspace].
 class BazelPackageUriResolver extends UriResolver {
   final BazelWorkspace _workspace;
@@ -377,8 +210,7 @@
   /// the corresponding package.
   final Map<String, BazelWorkspacePackage> _directoryToPackage = {};
 
-  final _bazelCandidateFiles =
-      StreamController<BazelFileNotification>.broadcast();
+  final _bazelCandidateFiles = StreamController<BazelSearchInfo>.broadcast();
 
   BazelWorkspace._(
     this.provider,
@@ -391,7 +223,7 @@
 
   /// Stream of files that we tried to find along with their potential or actual
   /// paths.
-  Stream<BazelFileNotification> get bazelCandidateFiles =>
+  Stream<BazelSearchInfo> get bazelCandidateFiles =>
       _bazelCandidateFiles.stream;
 
   @override
@@ -435,8 +267,8 @@
       for (var path in generatedCandidates) {
         File file = provider.getFile(path);
         if (file.exists) {
-          _bazelCandidateFiles.add(BazelFileNotification(
-              relative, generatedCandidates.toList(), provider));
+          _bazelCandidateFiles
+              .add(BazelSearchInfo(relative, generatedCandidates.toList()));
           return file;
         }
       }
@@ -455,8 +287,8 @@
       }
       // If we couldn't find the file, assume that it has not yet been
       // generated, so send an event with all the paths that we tried.
-      _bazelCandidateFiles.add(BazelFileNotification(
-          relative, generatedCandidates.toList(), provider));
+      _bazelCandidateFiles
+          .add(BazelSearchInfo(relative, generatedCandidates.toList()));
       // Not generated, return the default one.
       return writableFile;
     } catch (_) {
@@ -833,9 +665,3 @@
     }
   }
 }
-
-class FileInfo {
-  String path;
-  int modified;
-  FileInfo(this.path, this.modified);
-}
diff --git a/pkg/analyzer/lib/src/workspace/bazel_watcher.dart b/pkg/analyzer/lib/src/workspace/bazel_watcher.dart
new file mode 100644
index 0000000..1109c63
--- /dev/null
+++ b/pkg/analyzer/lib/src/workspace/bazel_watcher.dart
@@ -0,0 +1,548 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. 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:core';
+import 'dart:io' as io;
+import 'dart:isolate';
+import 'dart:math';
+
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/file_system/physical_file_system.dart';
+import 'package:analyzer/instrumentation/service.dart';
+import 'package:pedantic/pedantic.dart';
+import 'package:watcher/watcher.dart';
+
+Future<void> _isolateMain(SendPort sendPort) async {
+  var fromMainIsolate = ReceivePort();
+  var bazelIsolate = BazelFileWatcherIsolate(
+      fromMainIsolate, sendPort, PhysicalResourceProvider.INSTANCE)
+    ..start();
+  await bazelIsolate.hasFinished;
+}
+
+/// Exposes the ability to poll for changes in generated files.
+///
+/// The only logic here is that we may have multiple "candidate" paths where the
+/// file might be located, but after the first time we actually find the file,
+/// we can only focus on that particular path, since the files should be
+/// consistently in the same place after rebuilds.
+class BazelFilePoller {
+  /// The possible "candidate" paths that we watch.
+  final List<String> _candidates;
+
+  /// The time of last modification of the file under [_validPath].
+  int? _lastModified;
+
+  /// The resource provider used for polling the files.
+  final ResourceProvider _provider;
+
+  /// One of the [_candidates] that is valid, i.e. we found a file with that
+  /// path.
+  String? _validPath;
+
+  BazelFilePoller(this._provider, this._candidates);
+
+  /// Checks if the file corresponding to the watched path has changed and
+  /// returns the event or `null` if nothing changed.
+  WatchEvent? poll() {
+    int? modified;
+    if (_validPath == null) {
+      var info = _pollAll();
+      if (info != null) {
+        _validPath = info.path;
+        modified = info.modified;
+      }
+    } else {
+      modified = _pollOne(_validPath!);
+    }
+
+    // If there is no file, then we have nothing to do.
+    if (_validPath == null) return null;
+
+    WatchEvent? result;
+    if (modified == null && _lastModified != null) {
+      // The file is no longer there, so let's issue a REMOVE event, unset
+      // `_validPath` and set the timer to poll more frequently.
+      result = WatchEvent(ChangeType.REMOVE, _validPath!);
+      _validPath = null;
+    } else if (modified != null && _lastModified == null) {
+      result = WatchEvent(ChangeType.ADD, _validPath!);
+    } else if (_lastModified != null && modified != _lastModified) {
+      result = WatchEvent(ChangeType.MODIFY, _validPath!);
+    }
+    _lastModified = modified;
+    return result;
+  }
+
+  /// Starts watching the files.
+  ///
+  /// This should be called when creating an instance of this class to correctly
+  /// categorize events (e.g. whether a file already existed or was added).
+  void start() {
+    assert(_validPath == null);
+    assert(_lastModified == null);
+    var info = _pollAll();
+    if (info != null) {
+      _validPath = info.path;
+      _lastModified = info.modified;
+    }
+  }
+
+  /// Tries polling all the possible paths.
+  ///
+  /// Will set [_validPath] and return its modified time if a file is found.
+  /// Returns [null] if nothing is found.
+  FileInfo? _pollAll() {
+    assert(_validPath == null);
+    for (var path in _candidates) {
+      var modified = _pollOne(path);
+      if (modified != null) {
+        return FileInfo(path, modified);
+      }
+    }
+    return null;
+  }
+
+  /// Returns the modified time of the path or `null` if the file does not
+  /// exist.
+  int? _pollOne(String path) {
+    try {
+      var file = _provider.getFile(path);
+      return file.modificationStamp;
+    } on FileSystemException catch (_) {
+      // File doesn't exist, so return null.
+      return null;
+    }
+  }
+}
+
+/// The watcher implementation that runs in a separate isolate.
+///
+/// It'll try to detect when Bazel finished running (through [PollTrigger] which
+/// usually will be [_BazelInvocationWatcher]) and then poll all the files to
+/// find any changes, which will be sent to the main isolate as
+/// [BazelWatcherEvents].
+class BazelFileWatcherIsolate {
+  final ReceivePort _fromMainIsolate;
+  final SendPort _toMainIsolate;
+  late final StreamSubscription _fromMainIsolateSubscription;
+
+  /// For each workspace tracks all the data associated with it.
+  final _perWorkspaceData = <String, _PerWorkspaceData>{};
+
+  /// A factory for [PollTrigger].
+  ///
+  /// Used mostly for testing to allow using a different trigger.
+  late final PollTrigger Function(String) _pollTriggerFactory;
+
+  /// Resource provider used for polling.
+  ///
+  /// NB: The default [PollTrigger] (i.e., [_BazelInvocationWatcher]) uses
+  /// `dart:io` directly. So for testing both [_provider] and
+  /// [_pollTriggerFactory] should be provided.
+  final ResourceProvider _provider;
+
+  final _hasFinished = Completer<void>();
+
+  BazelFileWatcherIsolate(
+      this._fromMainIsolate, this._toMainIsolate, this._provider,
+      {PollTrigger Function(String)? pollTriggerFactory}) {
+    _pollTriggerFactory = pollTriggerFactory ?? _defaultPollTrigger;
+  }
+
+  Future<void> get hasFinished => _hasFinished.future;
+
+  void handleRequest(dynamic request) async {
+    if (request is BazelWatcherStartWatching) {
+      var workspaceData = _perWorkspaceData[request.workspace];
+      if (workspaceData == null) {
+        var trigger = _pollTriggerFactory(request.workspace);
+        var subscription =
+            trigger.stream.listen((_) => _pollAllWatchers(request.workspace));
+        workspaceData = _PerWorkspaceData(trigger, subscription);
+        _perWorkspaceData[request.workspace] = workspaceData;
+      }
+      var requestedPath = request.info.requestedPath;
+      var count = workspaceData.watched.add(requestedPath);
+      if (count > 1) {
+        assert(workspaceData.pollers.containsKey(requestedPath));
+        return;
+      }
+      workspaceData.pollers[requestedPath] =
+          BazelFilePoller(_provider, request.info.candidatePaths)..start();
+    } else if (request is BazelWatcherStopWatching) {
+      var workspaceData = _perWorkspaceData[request.workspace];
+      if (workspaceData == null) return;
+      var count = workspaceData.watched.remove(request.requestedPath);
+      if (count == 0) {
+        workspaceData.pollers.remove(request.requestedPath);
+        if (workspaceData.watched.isEmpty) {
+          workspaceData.trigger.cancel();
+          unawaited(workspaceData.pollSubscription.cancel());
+          _perWorkspaceData.remove(request.workspace);
+        }
+      }
+    } else if (request is BazelWatcherShutdownIsolate) {
+      unawaited(_fromMainIsolateSubscription.cancel());
+      _fromMainIsolate.close();
+      for (var data in _perWorkspaceData.values) {
+        data.trigger.cancel();
+        unawaited(data.pollSubscription.cancel());
+      }
+      _hasFinished.complete();
+      _perWorkspaceData.clear();
+    } else {
+      // We don't have access to the `InstrumentationService` so we send the
+      // message to the main isolate to log it.
+      _toMainIsolate.send(BazelWatcherError(
+          'BazelFileWatcherIsolate got unexpected request: $request'));
+    }
+  }
+
+  /// Returns the total number of requested file paths that are being watched.
+  ///
+  /// This is for testing *only*.
+  int numWatchedFiles() {
+    var total = 0;
+    for (var data in _perWorkspaceData.values) {
+      total += data.watched.length;
+    }
+    return total;
+  }
+
+  /// Starts listening for messages from the main isolate and sends it
+  /// [BazelWatcherIsolateStarted].
+  void start() {
+    _fromMainIsolateSubscription = _fromMainIsolate.listen(handleRequest);
+    _toMainIsolate.send(BazelWatcherIsolateStarted(_fromMainIsolate.sendPort));
+  }
+
+  PollTrigger _defaultPollTrigger(String workspacePath) =>
+      _BazelInvocationWatcher(_provider, workspacePath);
+
+  void _pollAllWatchers(String workspace) {
+    try {
+      var events = <WatchEvent>[];
+      for (var watcher in _perWorkspaceData[workspace]!.pollers.values) {
+        var event = watcher.poll();
+        if (event != null) events.add(event);
+      }
+      if (events.isNotEmpty) {
+        _toMainIsolate.send(BazelWatcherEvents(events));
+      }
+    } on Exception catch (_) {
+      // This shouldn't really happen, but we shouldn't crash when polling
+      // either, so just ignore the error and rely on the next try.
+      return;
+    }
+  }
+}
+
+/// A watcher service that exposes batch-oriented notification interface for
+/// changes to watched files.
+///
+/// The actual `stat`ing of file takes place in a separate isolate to avoid
+/// blocking the main one. Since much of the analysis server is synchronous, we
+/// can't use async functions and resort to launching the isolate and buffering
+/// the requests until the isolate has started.
+///
+/// The isolate is started lazily on the first request to watch a path, so
+/// instantiating [BazelFileWatcherService] is very cheap.
+///
+/// The protocol when communicating with the isolate:
+/// 1. The watcher isolate sends to the main one a [BazelWatcherIsolateStarted]
+///    and expects a [BazelWatcherInitializeIsolate] to be sent from the main
+///    isolate as a reply.
+/// 2. The main isolate can request to start watching a file by sending
+///    [BazelWatcherStartWatching] request. There is no response expected.
+/// 3. The watcher isolate will send a [BazelWatcherEvents] notification when
+///    changes are detected. Again, no response from the main isolate is
+///    expected.
+/// 4. The main isolate will send a [BazelWatcherShutdownIsolate] when the
+///    isolate is supposed to shut down. No more messages should be exchanged
+///    afterwards.
+class BazelFileWatcherService {
+  final InstrumentationService _instrumetation;
+
+  final _events = StreamController<List<WatchEvent>>.broadcast();
+
+  /// Buffers files to watch until the isolate is ready.
+  final _buffer = <BazelWatcherMessage>[];
+
+  late final ReceivePort _fromIsolatePort;
+  late final SendPort _toIsolatePort;
+  late final StreamSubscription _fromIsolateSubscription;
+
+  /// True if we have launched the isolate.
+  bool _isolateIsStarting = false;
+
+  /// True if the isolate is ready to watch files.
+  final _isolateHasStarted = Completer<void>();
+
+  BazelFileWatcherService(this._instrumetation);
+
+  Stream<List<WatchEvent>> get events => _events.stream;
+
+  /// Shuts everything down including the watcher isolate.
+  /// FIXME(michalt): Remove this if we really never need to shut down the
+  /// isolate.
+  void shutdown() {
+    if (_isolateHasStarted.isCompleted) {
+      _toIsolatePort.send(BazelWatcherShutdownIsolate());
+    }
+    if (_isolateIsStarting) {
+      _fromIsolateSubscription.cancel();
+      _fromIsolatePort.close();
+    }
+    _events.close();
+  }
+
+  void startWatching(String workspace, BazelSearchInfo info) {
+    assert(!_events.isClosed);
+    _startIsolateIfNeeded();
+    var request = BazelWatcherStartWatching(workspace, info);
+    if (!_isolateHasStarted.isCompleted) {
+      _buffer.add(request);
+    } else {
+      _toIsolatePort.send(request);
+    }
+  }
+
+  void stopWatching(String workspace, String requestedPath) {
+    assert(!_events.isClosed);
+    var request = BazelWatcherStopWatching(workspace, requestedPath);
+    if (!_isolateHasStarted.isCompleted) {
+      _buffer.add(request);
+    } else {
+      _toIsolatePort.send(request);
+    }
+  }
+
+  void _handleIsolateMessage(dynamic message) {
+    if (message is BazelWatcherIsolateStarted) {
+      _toIsolatePort = message.sendPort;
+      _isolateHasStarted.complete();
+    } else if (message is BazelWatcherEvents) {
+      _events.add(message.events);
+    } else if (message is BazelWatcherError) {
+      _instrumetation.logError(message.message);
+    } else {
+      _instrumetation.logError(
+          'Received unexpected message from BazelFileWatcherIsolate: $message');
+    }
+  }
+
+  /// Starts the isolate if it has not yet been started.
+  void _startIsolateIfNeeded() {
+    if (_isolateIsStarting) return;
+    _isolateIsStarting = true;
+    _startIsolateImpl();
+    _isolateHasStarted.future.then((_) {
+      _buffer.forEach(_toIsolatePort.send);
+      _buffer.clear();
+    });
+  }
+
+  Future<void> _startIsolateImpl() async {
+    _fromIsolatePort = ReceivePort();
+    _fromIsolateSubscription = _fromIsolatePort.listen(_handleIsolateMessage);
+    await Isolate.spawn(_isolateMain, _fromIsolatePort.sendPort);
+  }
+}
+
+/// Notification that we issue when searching for generated files in a Bazel
+/// workspace.
+///
+/// This allows clients to watch for changes to the generated files.
+class BazelSearchInfo {
+  /// Candidate paths that we searched.
+  final List<String> candidatePaths;
+
+  /// Absolute path that we tried searching for.
+  ///
+  /// This is not necessarily the path of the actual file that will be used. See
+  /// `BazelWorkspace.findFile` for details.
+  final String requestedPath;
+
+  BazelSearchInfo(this.requestedPath, this.candidatePaths);
+}
+
+class BazelWatcherError implements BazelWatcherMessage {
+  final String message;
+  BazelWatcherError(this.message);
+}
+
+class BazelWatcherEvents implements BazelWatcherMessage {
+  final List<WatchEvent> events;
+  BazelWatcherEvents(this.events);
+}
+
+/// Sent by the watcher isolate to transfer the [SendPort] to the main isolate.
+class BazelWatcherIsolateStarted implements BazelWatcherMessage {
+  final SendPort sendPort;
+  BazelWatcherIsolateStarted(this.sendPort);
+}
+
+abstract class BazelWatcherMessage {}
+
+class BazelWatcherShutdownIsolate implements BazelWatcherMessage {}
+
+class BazelWatcherStartWatching implements BazelWatcherMessage {
+  final String workspace;
+  final BazelSearchInfo info;
+  BazelWatcherStartWatching(this.workspace, this.info);
+}
+
+class BazelWatcherStopWatching implements BazelWatcherMessage {
+  final String workspace;
+  final String requestedPath;
+  BazelWatcherStopWatching(this.workspace, this.requestedPath);
+}
+
+class FileInfo {
+  String path;
+  int modified;
+  FileInfo(this.path, this.modified);
+}
+
+/// Triggers polling every time something appears in the [stream].
+abstract class PollTrigger {
+  Stream<Object> get stream;
+  void cancel();
+}
+
+/// Watches for finished Bazel invocations.
+///
+/// The idea here is to detect when Bazel finished running and use that to
+/// trigger polling. To detect that we use the `command.log` file that bazel
+/// contiuously updates as the build progresses. We find that file based on [1]:
+///
+/// - In the workspace directory there should be a `bazel-out` symlink whose
+///   target should be of the form:
+///   `[...]/<hash of workspace>/execroot/<workspace name>/bazel-out`
+/// - The file should be in `[...]/<hash of workspace>/command.log`.
+///
+/// In other words, we need to get the target of the symlink and then trim three
+/// last parts of the path.
+///
+/// [1] https://docs.bazel.build/versions/master/output_directories.html
+///
+/// NB: We're not using a [ResourceProvider] because it doesn't support finding a
+/// target of a symlink.
+class _BazelInvocationWatcher implements PollTrigger {
+  /// Determines how often do we check for `command.log` changes.
+  static const _pollInterval = Duration(seconds: 1);
+
+  /// To confirm that a build finished, we check for these messages in the
+  /// `command.log`.
+  static const _buildCompletedMsgs = [
+    'Build completed successfully',
+    'Build completed',
+    'Build did NOT complete successfully',
+  ];
+
+  final _controller = StreamController<WatchEvent>.broadcast();
+  final ResourceProvider _provider;
+  final String _workspacePath;
+  late final Timer _timer;
+  BazelFilePoller? _poller;
+  String? _commandLogPath;
+
+  _BazelInvocationWatcher(this._provider, this._workspacePath) {
+    _timer = Timer.periodic(_pollInterval, _poll);
+  }
+
+  @override
+  Stream<WatchEvent> get stream => _controller.stream;
+
+  @override
+  void cancel() => _timer.cancel();
+
+  bool _buildFinished(String contents) {
+    // Only look at the last 100 characters.
+    var offset = max(0, contents.length - 100);
+    return _buildCompletedMsgs.any((msg) => contents.contains(msg, offset));
+  }
+
+  Future<String?> _getCommandLogPath() async {
+    String? resolvedLink;
+    var bazelOut = _inWorkspace('bazel-out');
+    var blazeOut = _inWorkspace('blaze-out');
+    if (await io.Link(bazelOut).exists()) {
+      resolvedLink = await io.Link(bazelOut).target();
+    } else if (await io.Link(blazeOut).exists()) {
+      resolvedLink = await io.Link(blazeOut).target();
+    }
+    if (resolvedLink == null) return null;
+    var pathContext = _provider.pathContext;
+    return pathContext.join(
+        pathContext
+            .dirname(pathContext.dirname(pathContext.dirname(resolvedLink))),
+        'command.log');
+  }
+
+  String _inWorkspace(String p) =>
+      _provider.pathContext.join(_workspacePath, p);
+
+  Future<void> _poll(Timer _) async {
+    try {
+      _commandLogPath ??= await _getCommandLogPath();
+      if (_commandLogPath == null) return;
+
+      _poller ??= BazelFilePoller(_provider, [_commandLogPath!]);
+      var event = _poller!.poll();
+      if (event == null) return;
+
+      var file = io.File(_commandLogPath!);
+      var contents = file.readAsStringSync();
+      if (_buildFinished(contents)) {
+        _controller.add(WatchEvent(ChangeType.MODIFY, _commandLogPath!));
+      }
+    } on Exception catch (_) {
+      // Ignore failures, it's possible that the file was deleted between when
+      // we checked and tried to read it, etc.
+      return;
+    }
+  }
+}
+
+class _Multiset<T> {
+  final _counts = <T, int>{};
+
+  bool get isEmpty => _counts.isEmpty;
+
+  int get length =>
+      _counts.values.fold(0, (accumulator, count) => accumulator + count);
+
+  /// Returns the number of [elem] objects after the addition.
+  int add(T elem) =>
+      _counts.update(elem, (count) => count + 1, ifAbsent: () => 1);
+
+  /// Returns the number of [elem] objects after the removal.
+  int remove(T elem) {
+    var newCount = _counts.update(elem, (count) => count - 1);
+    if (newCount == 0) {
+      _counts.remove(elem);
+    }
+    return newCount;
+  }
+}
+
+class _PerWorkspaceData {
+  /// For each requested file stores the corresponding [BazelFilePoller].
+  final pollers = <String, BazelFilePoller>{};
+
+  /// Keeps count of the number of requests to watch a file, so that we can stop
+  /// watching when we reach 0 clients.
+  final watched = _Multiset();
+
+  /// The [PollTrigger] that detects when we should poll files.
+  final PollTrigger trigger;
+
+  /// Subscription of [trigger].
+  final StreamSubscription<Object> pollSubscription;
+
+  _PerWorkspaceData(this.trigger, this.pollSubscription);
+}
diff --git a/pkg/analyzer/lib/src/workspace/package_build.dart b/pkg/analyzer/lib/src/workspace/package_build.dart
index 09a3446..8f09c11 100644
--- a/pkg/analyzer/lib/src/workspace/package_build.dart
+++ b/pkg/analyzer/lib/src/workspace/package_build.dart
@@ -287,7 +287,7 @@
       // pubspec, to know the package name that package:build will assume.
       if (dartToolBuildDir.exists && pubspec.exists) {
         try {
-          final yaml = loadYaml(pubspec.readAsStringSync());
+          final yaml = loadYaml(pubspec.readAsStringSync()) as YamlMap;
           final packageName = yaml['name'] as String;
           final generatedRootPath = provider.pathContext
               .joinAll([folder.path, ..._generatedPathParts]);
diff --git a/pkg/analyzer/pubspec.yaml b/pkg/analyzer/pubspec.yaml
index 3ba35e2..6d4c820 100644
--- a/pkg/analyzer/pubspec.yaml
+++ b/pkg/analyzer/pubspec.yaml
@@ -1,5 +1,5 @@
 name: analyzer
-version: 1.2.0-dev
+version: 1.4.0-dev
 description: This package provides a library that performs static analysis of Dart code.
 homepage: https://github.com/dart-lang/sdk/tree/master/pkg/analyzer
 
@@ -7,8 +7,7 @@
   sdk: '>=2.12.0-0 <3.0.0'
 
 dependencies:
-  _fe_analyzer_shared: ^17.0.0
-  args: ^2.0.0
+  _fe_analyzer_shared: ^19.0.0
   cli_util: ^0.3.0
   collection: ^1.15.0
   convert: ^3.0.0
@@ -21,13 +20,14 @@
   source_span: ^1.8.0
   watcher: ^1.0.0
   yaml: ^3.0.0
+  pedantic: ^1.10.0
 dev_dependencies:
   analyzer_utilities:
     path: ../analyzer_utilities
+  args: ^2.0.0
   async: ^2.5.0
-#  linter: any
+  linter: any
   matcher: ^0.12.10
-  pedantic: ^1.10.0
   test: ^1.16.0
   test_api: ^0.2.19
   test_reflective_loader: ^0.2.0
diff --git a/pkg/analyzer/test/generated/error_parser_test.dart b/pkg/analyzer/test/generated/error_parser_test.dart
index 4889978..9115cc0 100644
--- a/pkg/analyzer/test/generated/error_parser_test.dart
+++ b/pkg/analyzer/test/generated/error_parser_test.dart
@@ -1698,7 +1698,7 @@
         errors: [
           expectedError(ParserErrorCode.EXPECTED_TYPE_NAME, 12, 7),
           expectedError(ParserErrorCode.EXPECTED_TOKEN, 12, 7),
-          expectedError(ParserErrorCode.INVALID_GENERIC_FUNCTION_TYPE, 10, 1),
+          expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 10, 1),
         ]);
   }
 
@@ -1886,8 +1886,8 @@
         expectedEndOffset: 14 /* parsing ends at synthetic ')' */);
     FormalParameterList list = parser.parseFormalParameterList();
     expectNotNullIfNoErrors(list);
-    listener.errors
-        .contains(expectedError(ParserErrorCode.EXPECTED_TOKEN, 14, 1));
+    listener
+        .assertErrors([expectedError(ScannerErrorCode.EXPECTED_TOKEN, 14, 1)]);
   }
 
   void test_missingConstFinalVarOrType_static() {
diff --git a/pkg/analyzer/test/generated/error_suppression_test.dart b/pkg/analyzer/test/generated/error_suppression_test.dart
index 3c020cb..b7a1e9c 100644
--- a/pkg/analyzer/test/generated/error_suppression_test.dart
+++ b/pkg/analyzer/test/generated/error_suppression_test.dart
@@ -17,23 +17,6 @@
 class ErrorSuppressionTest extends PubPackageResolutionTest {
   String get ignoredCode => 'unused_element';
 
-  test_does_not_ignore_errors() async {
-    await assertErrorsInCode('''
-int x = ''; // ignore: invalid_assignment
-''', [
-      error(CompileTimeErrorCode.INVALID_ASSIGNMENT, 8, 2),
-    ]);
-  }
-
-  test_error_cannot_be_ignored() async {
-    await assertErrorsInCode('''
-// ignore: unused_import, undefined_function
-f() => g();
-''', [
-      error(CompileTimeErrorCode.UNDEFINED_FUNCTION, 52, 1),
-    ]);
-  }
-
   test_error_code_mismatch() async {
     await assertErrorsInCode('''
 // ignore: $ignoredCode
diff --git a/pkg/analyzer/test/generated/non_error_resolver_test.dart b/pkg/analyzer/test/generated/non_error_resolver_test.dart
index 6536e46..402d7cc 100644
--- a/pkg/analyzer/test/generated/non_error_resolver_test.dart
+++ b/pkg/analyzer/test/generated/non_error_resolver_test.dart
@@ -2340,13 +2340,15 @@
     // B's superclass is "Object with A1<T>".  So mixin type inference succeeds
     // (since C's base class implements A1<int>), and "with B" is interpreted as
     // "with B<int>".
-    await assertNoErrorsInCode('''
+    await assertErrorsInCode('''
 class A1<T> {}
 class A2<T> {}
 class B<T> = Object with A1<T>, A2<T>;
 class Base implements A1<int> {}
 class C = Base with B;
-''');
+''', [
+      error(CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT, 122, 1),
+    ]);
     var bReference = result.unit!.declaredElement!.getType('C')!.mixins[0];
     assertType(bReference.typeArguments[0], 'int');
   }
@@ -3309,7 +3311,7 @@
   p is F;
 }
 ''', [
-      error(ParserErrorCode.INVALID_GENERIC_FUNCTION_TYPE, 10, 1),
+      error(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 10, 1),
     ]);
   }
 
diff --git a/pkg/analyzer/test/generated/recovery_parser_test.dart b/pkg/analyzer/test/generated/recovery_parser_test.dart
index 2c31385..1abb18e 100644
--- a/pkg/analyzer/test/generated/recovery_parser_test.dart
+++ b/pkg/analyzer/test/generated/recovery_parser_test.dart
@@ -1034,12 +1034,13 @@
 
   void test_invalidMapLiteral() {
     parseCompilationUnit("class C { var f = Map<A, B> {}; }", codes: [
-// TODO(danrubel): Improve error message to indicate
-// that "Map" should be removed.
-      ParserErrorCode.EXPECTED_TOKEN,
-      ParserErrorCode.MISSING_KEYWORD_OPERATOR,
-      ParserErrorCode.MISSING_METHOD_PARAMETERS,
-      ParserErrorCode.EXPECTED_CLASS_MEMBER,
+      ParserErrorCode.LITERAL_WITH_CLASS,
+    ]);
+    parseCompilationUnit("class C { var f = new Map<A, B> {}; }", codes: [
+      ParserErrorCode.LITERAL_WITH_CLASS_AND_NEW,
+    ]);
+    parseCompilationUnit("class C { var f = new <A, B> {}; }", codes: [
+      ParserErrorCode.LITERAL_WITH_NEW,
     ]);
   }
 
diff --git a/pkg/analyzer/test/generated/strong_mode_test.dart b/pkg/analyzer/test/generated/strong_mode_test.dart
index 9a88a32..aa67fe2 100644
--- a/pkg/analyzer/test/generated/strong_mode_test.dart
+++ b/pkg/analyzer/test/generated/strong_mode_test.dart
@@ -372,7 +372,7 @@
     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);
+    expect(exp.constructorName.type.typeOrThrow.element, elementB);
     _isInstantiationOf(_hasElement(elementB))([
       _isType(elementA.typeParameters[0]
           .instantiate(nullabilitySuffix: NullabilitySuffix.star))
diff --git a/pkg/analyzer/test/source/analysis_options_provider_test.dart b/pkg/analyzer/test/source/analysis_options_provider_test.dart
index ac4ea13..64cc0a4 100644
--- a/pkg/analyzer/test/source/analysis_options_provider_test.dart
+++ b/pkg/analyzer/test/source/analysis_options_provider_test.dart
@@ -131,9 +131,9 @@
     YamlMap options = _getOptions('/foo/bar');
     expect(options, hasLength(1));
     {
-      var analyzer = getValue(options, 'analyzer') as YamlMap;
+      var analyzer = options.valueAt('analyzer') as YamlMap;
       expect(analyzer, isNotNull);
-      expect(getValue(analyzer, 'ignore'), unorderedEquals(['bar']));
+      expect(analyzer.valueAt('ignore'), unorderedEquals(['bar']));
     }
   }
 
@@ -152,9 +152,9 @@
     YamlMap options = _getOptions('/foo/bar/baz');
     expect(options, hasLength(1));
     {
-      var analyzer = getValue(options, 'analyzer') as YamlMap;
+      var analyzer = options.valueAt('analyzer') as YamlMap;
       expect(analyzer, isNotNull);
-      expect(getValue(analyzer, 'ignore'), unorderedEquals(['bar']));
+      expect(analyzer.valueAt('ignore'), unorderedEquals(['bar']));
     }
   }
 
@@ -184,10 +184,10 @@
     YamlMap options = _getOptions('/');
     expect(options, hasLength(2));
     {
-      var analyzer = getValue(options, 'analyzer') as YamlMap;
+      var analyzer = options.valueAt('analyzer') as YamlMap;
       expect(analyzer, hasLength(1));
       {
-        var ignore = getValue(analyzer, 'ignore') as YamlList;
+        var ignore = analyzer.valueAt('ignore') as YamlList;
         expect(ignore, hasLength(2));
         expect(ignore[0], 'ignoreme.dart');
         expect(ignore[1], 'sdk_ext/**');
@@ -219,10 +219,10 @@
     YamlMap options = _getOptions('/');
     expect(options, hasLength(1));
     {
-      var analyzer = getValue(options, 'analyzer') as YamlMap;
+      var analyzer = options.valueAt('analyzer') as YamlMap;
       expect(analyzer, hasLength(1));
       {
-        var ignore = getValue(analyzer, 'ignore') as YamlList;
+        var ignore = analyzer.valueAt('ignore') as YamlList;
         expect(ignore, hasLength(2));
         expect(ignore[0], 'ignoreme.dart');
         expect(ignore[1], 'sdk_ext/**');
diff --git a/pkg/analyzer/test/src/command_line/arguments_test.dart b/pkg/analyzer/test/src/command_line/arguments_test.dart
deleted file mode 100644
index 139dcda5..0000000
--- a/pkg/analyzer/test/src/command_line/arguments_test.dart
+++ /dev/null
@@ -1,196 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:analyzer/src/command_line/arguments.dart';
-import 'package:analyzer/src/context/builder.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
-import 'package:args/args.dart';
-import 'package:test/test.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-main() {
-  defineReflectiveSuite(() {
-    defineReflectiveTests(ArgumentsTest);
-  });
-}
-
-@reflectiveTest
-class ArgumentsTest with ResourceProviderMixin {
-  void test_createContextBuilderOptions_all() {
-    String dartSdkSummaryPath = 'a';
-    String defaultAnalysisOptionsFilePath = 'b';
-    String defaultPackageFilePath = 'c';
-    ArgParser parser = ArgParser();
-    defineAnalysisArguments(parser);
-    List<String> args = [
-      '--dart-sdk-summary=$dartSdkSummaryPath',
-      '-Dfoo=1',
-      '-Dbar=2',
-      '--no-implicit-casts',
-      '--no-implicit-dynamic',
-      '--options=$defaultAnalysisOptionsFilePath',
-      '--packages=$defaultPackageFilePath',
-    ];
-    ArgResults result = parse(resourceProvider, parser, args);
-    ContextBuilderOptions options =
-        createContextBuilderOptions(resourceProvider, result);
-    expect(options, isNotNull);
-
-    expect(
-      options.defaultAnalysisOptionsFilePath,
-      endsWith(defaultAnalysisOptionsFilePath),
-    );
-    expect(
-      options.defaultPackageFilePath,
-      endsWith(defaultPackageFilePath),
-    );
-    expect(
-      options.dartSdkSummaryPath,
-      endsWith(dartSdkSummaryPath),
-    );
-
-    var declaredVariables = options.declaredVariables;
-    expect(declaredVariables, hasLength(2));
-    expect(declaredVariables['foo'], '1');
-    expect(declaredVariables['bar'], '2');
-
-    var defaultOptions = options.defaultOptions as AnalysisOptionsImpl;
-    expect(defaultOptions, isNotNull);
-    expect(defaultOptions.implicitCasts, false);
-    expect(defaultOptions.implicitDynamic, false);
-  }
-
-  void test_createContextBuilderOptions_none() {
-    ArgParser parser = ArgParser();
-    defineAnalysisArguments(parser);
-    List<String> args = [];
-    ArgResults result = parse(resourceProvider, parser, args);
-    ContextBuilderOptions options =
-        createContextBuilderOptions(resourceProvider, result);
-    expect(options, isNotNull);
-    expect(options.dartSdkSummaryPath, isNull);
-    expect(options.declaredVariables, isEmpty);
-    expect(options.defaultAnalysisOptionsFilePath, isNull);
-    expect(options.defaultPackageFilePath, isNull);
-    var defaultOptions = options.defaultOptions as AnalysisOptionsImpl;
-    expect(defaultOptions, isNotNull);
-    expect(defaultOptions.implicitCasts, true);
-    expect(defaultOptions.implicitDynamic, true);
-  }
-
-  void test_defineAnalysisArguments() {
-    ArgParser parser = ArgParser();
-    defineAnalysisArguments(parser);
-    expect(parser.options, hasLength(12));
-  }
-
-  void test_extractDefinedVariables() {
-    List<String> args = ['--a', '-Dbaz', 'go', '-Dc=d', 'e=f', '-Dy=', '-Dx'];
-    Map<String, String> definedVariables = {'one': 'two'};
-    args = extractDefinedVariables(args, definedVariables);
-    expect(args, orderedEquals(['--a', 'e=f', '-Dx']));
-    expect(definedVariables['one'], 'two');
-    expect(definedVariables['two'], isNull);
-    expect(definedVariables['baz'], 'go');
-    expect(definedVariables['go'], isNull);
-    expect(definedVariables['c'], 'd');
-    expect(definedVariables['d'], isNull);
-    expect(definedVariables['y'], '');
-    expect(definedVariables, hasLength(4));
-  }
-
-  void test_filterUnknownArguments() {
-    List<String> args = ['--a', '--b', '--c=0', '--d=1', '-e=2', '-f', 'bar'];
-    ArgParser parser = ArgParser();
-    parser.addFlag('a');
-    parser.addOption('c');
-    parser.addOption('ee', abbr: 'e');
-    parser.addFlag('ff', abbr: 'f');
-    List<String> result = filterUnknownArguments(args, parser);
-    expect(result, orderedEquals(['--a', '--c=0', '-e=2', '-f', 'bar']));
-  }
-
-  void test_implicitCast() {
-    ArgParser parser = ArgParser();
-    defineAnalysisArguments(parser);
-    List<String> args = [
-      '--implicit-casts',
-    ];
-    ArgResults result = parse(resourceProvider, parser, args);
-    ContextBuilderOptions options =
-        createContextBuilderOptions(resourceProvider, result);
-    expect(options, isNotNull);
-    var defaultOptions = options.defaultOptions as AnalysisOptionsImpl;
-    expect(defaultOptions, isNotNull);
-    expect(defaultOptions.implicitCasts, true);
-  }
-
-  void test_noImplicitCast() {
-    ArgParser parser = ArgParser();
-    defineAnalysisArguments(parser);
-    List<String> args = [
-      '--no-implicit-casts',
-    ];
-    ArgResults result = parse(resourceProvider, parser, args);
-    ContextBuilderOptions options =
-        createContextBuilderOptions(resourceProvider, result);
-    expect(options, isNotNull);
-    var defaultOptions = options.defaultOptions as AnalysisOptionsImpl;
-    expect(defaultOptions, isNotNull);
-    expect(defaultOptions.implicitCasts, false);
-  }
-
-  void test_parse_noReplacement_noIgnored() {
-    ArgParser parser = ArgParser();
-    parser.addFlag('xx');
-    parser.addOption('yy');
-    List<String> args = ['--xx', '--yy=abc', 'foo', 'bar'];
-    ArgResults result = parse(resourceProvider, parser, args);
-    expect(result, isNotNull);
-    expect(result['xx'], true);
-    expect(result['yy'], 'abc');
-    expect(result.rest, orderedEquals(['foo', 'bar']));
-  }
-
-  void test_preprocessArgs_noReplacement() {
-    List<String> original = ['--xx' '--yy' 'baz'];
-    List<String> result = preprocessArgs(resourceProvider, original);
-    expect(result, orderedEquals(original));
-    expect(identical(original, result), isFalse);
-  }
-
-  void test_preprocessArgs_replacement_exists() {
-    String filePath = convertPath('/args.txt');
-    newFile(filePath, content: '''
--a
---xx
-
-foo
-bar
-''');
-    List<String> result =
-        preprocessArgs(resourceProvider, ['--preserved', '@$filePath']);
-    expect(result, orderedEquals(['--preserved', '-a', '--xx', 'foo', 'bar']));
-  }
-
-  void test_preprocessArgs_replacement_nonexistent() {
-    String filePath = convertPath('/args.txt');
-    List<String> args = ['ignored', '@$filePath'];
-    try {
-      preprocessArgs(resourceProvider, args);
-      fail('Expect exception');
-    } on Exception catch (e) {
-      expect(e.toString(), contains('Failed to read file'));
-      expect(e.toString(), contains('@$filePath'));
-    }
-  }
-
-  void test_preprocessArgs_replacement_notLast() {
-    String filePath = convertPath('/args.txt');
-    List<String> args = ['a', '@$filePath', 'b'];
-    List<String> result = preprocessArgs(resourceProvider, args);
-    expect(result, orderedEquals(args));
-  }
-}
diff --git a/pkg/analyzer/test/src/command_line/test_all.dart b/pkg/analyzer/test/src/command_line/test_all.dart
deleted file mode 100644
index a4c4e71..0000000
--- a/pkg/analyzer/test/src/command_line/test_all.dart
+++ /dev/null
@@ -1,13 +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:test_reflective_loader/test_reflective_loader.dart';
-
-import 'arguments_test.dart' as arguments_test;
-
-main() {
-  defineReflectiveSuite(() {
-    arguments_test.main();
-  }, name: 'command_line');
-}
diff --git a/pkg/analyzer/test/src/context/builder_test.dart b/pkg/analyzer/test/src/context/builder_test.dart
index 55fb085..bd4a9fe 100644
--- a/pkg/analyzer/test/src/context/builder_test.dart
+++ b/pkg/analyzer/test/src/context/builder_test.dart
@@ -3,18 +3,13 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/src/command_line/arguments.dart';
 import 'package:analyzer/src/context/builder.dart';
 import 'package:analyzer/src/context/context_root.dart';
 import 'package:analyzer/src/context/packages.dart';
 import 'package:analyzer/src/context/source.dart';
-import 'package:analyzer/src/dart/error/lint_codes.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/sdk.dart';
 import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/lint/linter.dart';
-import 'package:analyzer/src/lint/registry.dart';
-import 'package:analyzer/src/services/lint.dart';
 import 'package:analyzer/src/source/package_map_resolver.dart';
 import 'package:analyzer/src/test_utilities/mock_sdk.dart';
 import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
@@ -24,7 +19,6 @@
 import 'package:analyzer/src/workspace/package_build.dart';
 import 'package:analyzer/src/workspace/pub.dart';
 import 'package:analyzer/src/workspace/workspace.dart';
-import 'package:args/args.dart';
 import 'package:path/path.dart' as path;
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -56,11 +50,6 @@
   /// invoked [createDefaultSdk].
   late final String defaultSdkPath;
 
-  late final _MockLintRule _mockLintRule;
-  late final _MockLintRule _mockLintRule2;
-  late final _MockLintRule _mockLintRule3;
-  late final _MockLintRule _mockPublicMemberApiDocs;
-
   Uri convertedDirectoryUri(String directoryPath) {
     return Uri.directory(convertPath(directoryPath),
         windows: resourceProvider.pathContext.style == path.windows.style);
@@ -88,98 +77,6 @@
     fail('Incomplete test');
   }
 
-  void test_cmdline_lint_defined() {
-    _defineMockLintRules();
-    ArgParser argParser = ArgParser();
-    defineAnalysisArguments(argParser);
-    ArgResults argResults = argParser.parse(['--$lintsFlag']);
-    var builder = ContextBuilder(resourceProvider, sdkManager, contentCache,
-        options: createContextBuilderOptions(resourceProvider, argResults));
-
-    AnalysisOptionsImpl expected = AnalysisOptionsImpl();
-    expected.lint = true;
-    expected.lintRules = <LintRule>[
-      Registry.ruleRegistry['mock_lint_rule']!,
-    ];
-
-    String path = convertPath('/some/directory/path');
-    newAnalysisOptionsYamlFile(path, content: '''
-linter:
-  rules:
-    - mock_lint_rule
-''');
-
-    var options = _getAnalysisOptions(builder, path);
-    _expectEqualOptions(options, expected);
-  }
-
-  void test_cmdline_lint_off() {
-    ArgParser argParser = ArgParser();
-    defineAnalysisArguments(argParser);
-    ArgResults argResults = argParser.parse(['--no-$lintsFlag']);
-    var builder = ContextBuilder(resourceProvider, sdkManager, contentCache,
-        options: createContextBuilderOptions(resourceProvider, argResults));
-
-    AnalysisOptionsImpl expected = AnalysisOptionsImpl();
-    expected.lint = false;
-    expected.lintRules = <LintRule>[
-      Registry.ruleRegistry['mock_lint_rule']!,
-    ];
-
-    String path = convertPath('/some/directory/path');
-    newAnalysisOptionsYamlFile(path, content: '''
-linter:
-  rules:
-    - mock_lint_rule
-''');
-
-    var options = _getAnalysisOptions(builder, path);
-    _expectEqualOptions(options, expected);
-  }
-
-  void test_cmdline_lint_unspecified_1() {
-    ArgParser argParser = ArgParser();
-    defineAnalysisArguments(argParser);
-    ArgResults argResults = argParser.parse([]);
-    var builder = ContextBuilder(resourceProvider, sdkManager, contentCache,
-        options: createContextBuilderOptions(resourceProvider, argResults));
-
-    AnalysisOptionsImpl expected = AnalysisOptionsImpl();
-    expected.lint = true;
-    expected.lintRules = <LintRule>[
-      Registry.ruleRegistry['mock_lint_rule']!,
-    ];
-
-    String path = convertPath('/some/directory/path');
-    newAnalysisOptionsYamlFile(path, content: '''
-linter:
-  rules:
-    - mock_lint_rule
-''');
-
-    var options = _getAnalysisOptions(builder, path);
-    _expectEqualOptions(options, expected);
-  }
-
-  void test_cmdline_lint_unspecified_2() {
-    ArgParser argParser = ArgParser();
-    defineAnalysisArguments(argParser);
-    ArgResults argResults = argParser.parse([]);
-    var builder = ContextBuilder(resourceProvider, sdkManager, contentCache,
-        options: createContextBuilderOptions(resourceProvider, argResults));
-
-    AnalysisOptionsImpl expected = AnalysisOptionsImpl();
-    expected.lint = false;
-    expected.lintRules = <LintRule>[];
-
-    String path = convertPath('/some/directory/path');
-    newAnalysisOptionsYamlFile(path, content: '''
-''');
-
-    var options = _getAnalysisOptions(builder, path);
-    _expectEqualOptions(options, expected);
-  }
-
   @failingTest
   void test_cmdline_options_override_options_file() {
     fail('No clear choice of option to override.');
@@ -205,21 +102,6 @@
 //    _expectEqualOptions(options, expected);
   }
 
-  void test_createDefaultOptions_default() {
-    // Invert a subset of the options to ensure that the default options are
-    // being returned.
-    AnalysisOptionsImpl defaultOptions = AnalysisOptionsImpl();
-    defaultOptions.implicitCasts = !defaultOptions.implicitCasts;
-    builderOptions.defaultOptions = defaultOptions;
-    var options = builder.createDefaultOptions();
-    _expectEqualOptions(options, defaultOptions);
-  }
-
-  void test_createDefaultOptions_noDefault() {
-    var options = builder.createDefaultOptions();
-    _expectEqualOptions(options, AnalysisOptionsImpl());
-  }
-
   void test_createPackageMap_fromPackageFile_explicit() {
     // Use a package file that is outside the project directory's hierarchy.
     String rootPath = convertPath('/root');
@@ -484,49 +366,12 @@
     expect(htmlSource.exists(), isTrue);
   }
 
-  void test_getAnalysisOptions_default_noOverrides() {
-    AnalysisOptionsImpl defaultOptions = AnalysisOptionsImpl();
-    builderOptions.defaultOptions = defaultOptions;
-    AnalysisOptionsImpl expected = AnalysisOptionsImpl();
-    String path = convertPath('/some/directory/path');
-    newAnalysisOptionsYamlFile(path, content: '''
-linter:
-  rules:
-    - non_existent_lint_rule
-''');
-
-    var options = _getAnalysisOptions(builder, path);
-    _expectEqualOptions(options, expected);
-  }
-
-  void test_getAnalysisOptions_default_overrides() {
-    AnalysisOptionsImpl defaultOptions = AnalysisOptionsImpl();
-    defaultOptions.implicitDynamic = true;
-    builderOptions.defaultOptions = defaultOptions;
-    AnalysisOptionsImpl expected = AnalysisOptionsImpl();
-    expected.implicitDynamic = false;
-    String path = convertPath('/some/directory/path');
-    newAnalysisOptionsYamlFile(path, content: '''
-analyzer:
-  strong-mode:
-    implicit-dynamic: false
-''');
-
-    var options = _getAnalysisOptions(builder, path);
-    _expectEqualOptions(options, expected);
-  }
-
   void test_getAnalysisOptions_gnWorkspace() {
-    String _p(String path) => convertPath(path);
-    String projectPath = _p('/workspace/some/path');
+    String projectPath = convertPath('/workspace/some/path');
     newFolder('/workspace/.jiri_root');
     newFile('/workspace/out/debug/gen/dart.sources/foo_pkg',
-        content: _p('/workspace/foo_pkg/lib'));
+        content: convertPath('/workspace/foo_pkg/lib'));
     newFolder(projectPath);
-    ArgParser argParser = ArgParser();
-    defineAnalysisArguments(argParser);
-    ArgResults argResults = argParser.parse([]);
-    builderOptions = createContextBuilderOptions(resourceProvider, argResults);
     builder = ContextBuilder(resourceProvider, sdkManager, contentCache,
         options: builderOptions);
     AnalysisOptionsImpl expected = AnalysisOptionsImpl();
@@ -534,43 +379,6 @@
     _expectEqualOptions(options, expected);
   }
 
-  void test_getAnalysisOptions_includes() {
-    _defineMockLintRules();
-    AnalysisOptionsImpl defaultOptions = AnalysisOptionsImpl();
-    builderOptions.defaultOptions = defaultOptions;
-    AnalysisOptionsImpl expected = AnalysisOptionsImpl();
-    expected.lint = true;
-    expected.lintRules = <Linter>[
-      _mockLintRule,
-      _mockLintRule2,
-      _mockLintRule3
-    ];
-    newFile('/mypkgs/somepkg/lib/here.yaml', content: '''
-linter:
-  rules:
-    - mock_lint_rule3
-''');
-    String path = convertPath('/some/directory/path');
-    newFile(join(path, '.packages'), content: '''
-somepkg:../../../mypkgs/somepkg/lib
-''');
-    newFile(join(path, 'bar.yaml'), content: '''
-include: package:somepkg/here.yaml
-linter:
-  rules:
-    - mock_lint_rule2
-''');
-    newAnalysisOptionsYamlFile(path, content: '''
-include: bar.yaml
-linter:
-  rules:
-    - mock_lint_rule
-''');
-
-    var options = _getAnalysisOptions(builder, path);
-    _expectEqualOptions(options, expected);
-  }
-
   void test_getAnalysisOptions_invalid() {
     String path = convertPath('/some/directory/path');
     newAnalysisOptionsYamlFile(path, content: ';');
@@ -591,34 +399,6 @@
     _expectEqualOptions(options, AnalysisOptionsImpl());
   }
 
-  void test_getAnalysisOptions_noDefault_overrides() {
-    AnalysisOptionsImpl expected = AnalysisOptionsImpl();
-    expected.implicitDynamic = false;
-    String path = convertPath('/some/directory/path');
-    newAnalysisOptionsYamlFile(path, content: '''
-analyzer:
-  strong-mode:
-    implicit-dynamic: false
-''');
-
-    var options = _getAnalysisOptions(builder, path);
-    _expectEqualOptions(options, expected);
-  }
-
-  void test_getAnalysisOptions_optionsPath() {
-    String path = convertPath('/some/directory/path');
-    String filePath = newAnalysisOptionsYamlFile(path, content: '''
-linter:
-  rules:
-    - empty_constructor_bodies
-''').path;
-
-    ContextRoot root =
-        ContextRoot(path, [], pathContext: resourceProvider.pathContext);
-    _getAnalysisOptions(builder, path, contextRoot: root);
-    expect(root.optionsFilePath, filePath);
-  }
-
   void test_getAnalysisOptions_sdkVersionConstraint() {
     var projectPath = convertPath('/test');
     newPubspecYamlFile(projectPath, '''
@@ -636,36 +416,6 @@
     expect(options.sdkVersionConstraint, isNull);
   }
 
-  void test_getOptionsFile_explicit() {
-    String path = convertPath('/some/directory/path');
-    String filePath = convertPath('/options/analysis.yaml');
-    newFile(filePath);
-
-    builderOptions.defaultAnalysisOptionsFilePath = filePath;
-    var result = builder.getOptionsFile(path)!;
-    expect(result, isNotNull);
-    expect(result.path, filePath);
-  }
-
-  void test_getOptionsFile_inParentOfRoot_new() {
-    String parentPath = convertPath('/some/directory');
-    String path = join(parentPath, 'path');
-    String filePath = newAnalysisOptionsYamlFile(path).path;
-
-    var result = builder.getOptionsFile(path)!;
-    expect(result, isNotNull);
-    expect(result.path, filePath);
-  }
-
-  void test_getOptionsFile_inRoot_new() {
-    String path = convertPath('/some/directory/path');
-    String filePath = newAnalysisOptionsYamlFile(path).path;
-
-    var result = builder.getOptionsFile(path)!;
-    expect(result, isNotNull);
-    expect(result.path, filePath);
-  }
-
   void _assertPackages(Packages packages, Map<String, String> nameToPath) {
     expect(packages, isNotNull);
     expect(packages.packages, hasLength(nameToPath.length));
@@ -702,17 +452,6 @@
     );
   }
 
-  _defineMockLintRules() {
-    _mockLintRule = _MockLintRule('mock_lint_rule');
-    Registry.ruleRegistry.register(_mockLintRule);
-    _mockLintRule2 = _MockLintRule('mock_lint_rule2');
-    Registry.ruleRegistry.register(_mockLintRule2);
-    _mockLintRule3 = _MockLintRule('mock_lint_rule3');
-    Registry.ruleRegistry.register(_mockLintRule3);
-    _mockPublicMemberApiDocs = _MockLintRule('public_member_api_docs');
-    Registry.ruleRegistry.register(_mockPublicMemberApiDocs);
-  }
-
   void _expectEqualOptions(
       AnalysisOptionsImpl actual, AnalysisOptionsImpl expected) {
     // TODO(brianwilkerson) Consider moving this to AnalysisOptionsImpl.==.
@@ -772,18 +511,3 @@
     expect(locator.embedderYamls, hasLength(1));
   }
 }
-
-class _MockLintRule implements LintRule {
-  final String _name;
-
-  _MockLintRule(this._name);
-
-  @override
-  List<LintCode> get lintCodes => [LintCode(_name, '')];
-
-  @override
-  String get name => _name;
-
-  @override
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
diff --git a/pkg/analyzer/test/src/dart/analysis/analysis_context_collection_test.dart b/pkg/analyzer/test/src/dart/analysis/analysis_context_collection_test.dart
index ba7dffe..d532b29 100644
--- a/pkg/analyzer/test/src/dart/analysis/analysis_context_collection_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/analysis_context_collection_test.dart
@@ -5,9 +5,12 @@
 import 'package:analyzer/src/dart/analysis/analysis_context_collection.dart';
 import 'package:analyzer/src/test_utilities/mock_sdk.dart';
 import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
+import 'package:linter/src/rules.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
+import '../resolution/context_collection_resolution.dart';
+
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(AnalysisContextCollectionTest);
@@ -18,6 +21,7 @@
 class AnalysisContextCollectionTest with ResourceProviderMixin {
   void setUp() {
     MockSdk(resourceProvider: resourceProvider);
+    registerLintRules();
   }
 
   test_contextFor_noContext() {
@@ -44,6 +48,59 @@
     );
   }
 
+  test_new_analysisOptions_includes() {
+    var rootFolder = newFolder('/home/test');
+    var fooFolder = newFolder('/home/packages/foo');
+    newFile('${fooFolder.path}/lib/included.yaml', content: r'''
+linter:
+  rules:
+    - empty_statements
+''');
+
+    var packageConfigFileBuilder = PackageConfigFileBuilder()
+      ..add(name: 'foo', rootPath: fooFolder.path);
+    newPackageConfigJsonFile(
+      rootFolder.path,
+      content: packageConfigFileBuilder.toContent(toUriStr: toUriStr),
+    );
+
+    newAnalysisOptionsYamlFile(rootFolder.path, content: r'''
+include: package:foo/included.yaml
+
+linter:
+  rules:
+    - unnecessary_parenthesis
+''');
+
+    var collection = _newCollection(includedPaths: [rootFolder.path]);
+    var analysisContext = collection.contextFor(rootFolder.path);
+    var analysisOptions = analysisContext.analysisOptions;
+
+    expect(
+      analysisOptions.lintRules.map((e) => e.name),
+      unorderedEquals(['empty_statements', 'unnecessary_parenthesis']),
+    );
+  }
+
+  test_new_analysisOptions_lintRules() {
+    var rootFolder = newFolder('/home/test');
+    newAnalysisOptionsYamlFile(rootFolder.path, content: r'''
+linter:
+  rules:
+    - non_existent_lint_rule
+    - unnecessary_parenthesis
+''');
+
+    var collection = _newCollection(includedPaths: [rootFolder.path]);
+    var analysisContext = collection.contextFor(rootFolder.path);
+    var analysisOptions = analysisContext.analysisOptions;
+
+    expect(
+      analysisOptions.lintRules.map((e) => e.name),
+      unorderedEquals(['unnecessary_parenthesis']),
+    );
+  }
+
   test_new_includedPaths_notAbsolute() {
     expect(
       () => AnalysisContextCollectionImpl(includedPaths: ['root']),
diff --git a/pkg/analyzer/test/src/dart/analysis/base.dart b/pkg/analyzer/test/src/dart/analysis/base.dart
index ea7e629..6b9f30f 100644
--- a/pkg/analyzer/test/src/dart/analysis/base.dart
+++ b/pkg/analyzer/test/src/dart/analysis/base.dart
@@ -39,7 +39,6 @@
   final List<ExceptionResult> allExceptions = <ExceptionResult>[];
 
   late final String testProject;
-  late final String testProject2;
   late final String testFile;
   late final String testCode;
 
@@ -139,7 +138,6 @@
   void setUp() {
     sdk = MockSdk(resourceProvider: resourceProvider);
     testProject = convertPath('/test');
-    testProject2 = convertPath('/test/lib');
     testFile = convertPath('/test/lib/test.dart');
     logger = PerformanceLog(logBuffer);
     scheduler = AnalysisDriverScheduler(logger);
diff --git a/pkg/analyzer/test/src/dart/analysis/context_locator_test.dart b/pkg/analyzer/test/src/dart/analysis/context_locator_test.dart
index 1166f42..63b08a5 100644
--- a/pkg/analyzer/test/src/dart/analysis/context_locator_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/context_locator_test.dart
@@ -176,23 +176,6 @@
     ]);
   }
 
-  void test_locateRoots_multiple_dirAndNestedDir() {
-    Folder outerRootFolder = newFolder('/test/outer');
-    File outerOptionsFile = newAnalysisOptionsYamlFile('/test/outer');
-    File outerPackagesFile = newDotPackagesFile('/test/outer');
-    Folder innerRootFolder = newFolder('/test/outer/examples/inner');
-
-    List<ContextRoot> roots = contextLocator.locateRoots(
-        includedPaths: [outerRootFolder.path, innerRootFolder.path]);
-    expect(roots, hasLength(1));
-
-    ContextRoot outerRoot = findRoot(roots, outerRootFolder);
-    expect(outerRoot.includedPaths, unorderedEquals([outerRootFolder.path]));
-    expect(outerRoot.excludedPaths, isEmpty);
-    expect(outerRoot.optionsFile, outerOptionsFile);
-    expect(outerRoot.packagesFile, outerPackagesFile);
-  }
-
   void test_locateRoots_multiple_dirAndNestedDir_excludedByOptions() {
     var rootPath = convertPath('/home/test');
     var rootFolder = newFolder(rootPath);
@@ -219,14 +202,53 @@
     expect(outerRoot.packagesFile, packagesFile);
   }
 
-  void test_locateRoots_multiple_dirAndNestedFile() {
+  void test_locateRoots_multiple_dirAndNestedDir_innerConfigurationFiles() {
+    var outerRootFolder = newFolder('/outer');
+    var innerOptionsFile = newAnalysisOptionsYamlFile('/outer/examples/inner');
+    var innerPackagesFile = newDotPackagesFile('/outer/examples/inner');
+    var innerRootFolder = newFolder('/outer/examples/inner');
+
+    var roots = contextLocator.locateRoots(
+      includedPaths: [outerRootFolder.path, innerRootFolder.path],
+    );
+    expect(roots, hasLength(2));
+
+    var outerRoot = findRoot(roots, outerRootFolder);
+    expect(outerRoot.includedPaths, unorderedEquals([outerRootFolder.path]));
+    expect(outerRoot.excludedPaths, unorderedEquals([innerRootFolder.path]));
+    expect(outerRoot.optionsFile, isNull);
+    expect(outerRoot.packagesFile, isNull);
+
+    var innerRoot = findRoot(roots, innerRootFolder);
+    expect(innerRoot.includedPaths, unorderedEquals([innerRootFolder.path]));
+    expect(innerRoot.excludedPaths, isEmpty);
+    expect(innerRoot.optionsFile, innerOptionsFile);
+    expect(innerRoot.packagesFile, innerPackagesFile);
+  }
+
+  void test_locateRoots_multiple_dirAndNestedDir_noConfigurationFiles() {
+    Folder outerRootFolder = newFolder('/test/outer');
+    Folder innerRootFolder = newFolder('/test/outer/examples/inner');
+
+    List<ContextRoot> roots = contextLocator.locateRoots(
+        includedPaths: [outerRootFolder.path, innerRootFolder.path]);
+    expect(roots, hasLength(1));
+
+    ContextRoot outerRoot = findRoot(roots, outerRootFolder);
+    expect(outerRoot.includedPaths, unorderedEquals([outerRootFolder.path]));
+    expect(outerRoot.excludedPaths, isEmpty);
+    expect(outerRoot.optionsFile, isNull);
+    expect(outerRoot.packagesFile, isNull);
+  }
+
+  void test_locateRoots_multiple_dirAndNestedDir_outerConfigurationFiles() {
     Folder outerRootFolder = newFolder('/test/outer');
     File outerOptionsFile = newAnalysisOptionsYamlFile('/test/outer');
     File outerPackagesFile = newDotPackagesFile('/test/outer');
-    File testFile = newFile('/test/outer/examples/inner/test.dart');
+    Folder innerRootFolder = newFolder('/test/outer/examples/inner');
 
-    List<ContextRoot> roots = contextLocator
-        .locateRoots(includedPaths: [outerRootFolder.path, testFile.path]);
+    List<ContextRoot> roots = contextLocator.locateRoots(
+        includedPaths: [outerRootFolder.path, innerRootFolder.path]);
     expect(roots, hasLength(1));
 
     ContextRoot outerRoot = findRoot(roots, outerRootFolder);
@@ -266,7 +288,39 @@
     _assertAnalyzedFiles2(root, [optionsFile, fooFile, barFile]);
   }
 
-  void test_locateRoots_multiple_dirAndSiblingDir() {
+  void test_locateRoots_multiple_dirAndNestedFile_noConfigurationFiles() {
+    Folder outerRootFolder = newFolder('/test/outer');
+    File testFile = newFile('/test/outer/examples/inner/test.dart');
+
+    List<ContextRoot> roots = contextLocator
+        .locateRoots(includedPaths: [outerRootFolder.path, testFile.path]);
+    expect(roots, hasLength(1));
+
+    ContextRoot outerRoot = findRoot(roots, outerRootFolder);
+    expect(outerRoot.includedPaths, unorderedEquals([outerRootFolder.path]));
+    expect(outerRoot.excludedPaths, isEmpty);
+    expect(outerRoot.optionsFile, isNull);
+    expect(outerRoot.packagesFile, isNull);
+  }
+
+  void test_locateRoots_multiple_dirAndNestedFile_outerConfigurationFiles() {
+    Folder outerRootFolder = newFolder('/test/outer');
+    File outerOptionsFile = newAnalysisOptionsYamlFile('/test/outer');
+    File outerPackagesFile = newDotPackagesFile('/test/outer');
+    File testFile = newFile('/test/outer/examples/inner/test.dart');
+
+    List<ContextRoot> roots = contextLocator
+        .locateRoots(includedPaths: [outerRootFolder.path, testFile.path]);
+    expect(roots, hasLength(1));
+
+    ContextRoot outerRoot = findRoot(roots, outerRootFolder);
+    expect(outerRoot.includedPaths, unorderedEquals([outerRootFolder.path]));
+    expect(outerRoot.excludedPaths, isEmpty);
+    expect(outerRoot.optionsFile, outerOptionsFile);
+    expect(outerRoot.packagesFile, outerPackagesFile);
+  }
+
+  void test_locateRoots_multiple_dirAndSiblingDir_bothConfigurationFiles() {
     Folder outer1RootFolder = newFolder('/test/outer1');
     File outer1OptionsFile = newAnalysisOptionsYamlFile('/test/outer1');
     File outer1PackagesFile = newDotPackagesFile('/test/outer1');
@@ -292,6 +346,27 @@
     expect(outer2Root.packagesFile, outer2PackagesFile);
   }
 
+  void test_locateRoots_multiple_dirAndSiblingDir_noConfigurationFiles() {
+    Folder outer1RootFolder = newFolder('/test/outer1');
+    Folder outer2RootFolder = newFolder('/test/outer2');
+
+    List<ContextRoot> roots = contextLocator.locateRoots(
+        includedPaths: [outer1RootFolder.path, outer2RootFolder.path]);
+    expect(roots, hasLength(2));
+
+    ContextRoot outer1Root = findRoot(roots, outer1RootFolder);
+    expect(outer1Root.includedPaths, unorderedEquals([outer1RootFolder.path]));
+    expect(outer1Root.excludedPaths, isEmpty);
+    expect(outer1Root.optionsFile, isNull);
+    expect(outer1Root.packagesFile, isNull);
+
+    ContextRoot outer2Root = findRoot(roots, outer2RootFolder);
+    expect(outer2Root.includedPaths, unorderedEquals([outer2RootFolder.path]));
+    expect(outer2Root.excludedPaths, isEmpty);
+    expect(outer2Root.optionsFile, isNull);
+    expect(outer2Root.packagesFile, isNull);
+  }
+
   void test_locateRoots_multiple_dirAndSiblingFile() {
     Folder outer1RootFolder = newFolder('/test/outer1');
     File outer1OptionsFile = newAnalysisOptionsYamlFile('/test/outer1');
@@ -318,6 +393,65 @@
     expect(outer2Root.packagesFile, outer2PackagesFile);
   }
 
+  void test_locateRoots_multiple_dirAndSiblingFile_noConfigurationFiles() {
+    Folder outer1RootFolder = newFolder('/test/outer1');
+    File testFile = newFile('/test/outer2/test.dart');
+
+    List<ContextRoot> roots = contextLocator
+        .locateRoots(includedPaths: [outer1RootFolder.path, testFile.path]);
+    expect(roots, hasLength(2));
+
+    ContextRoot outer1Root = findRoot(roots, outer1RootFolder);
+    expect(outer1Root.includedPaths, unorderedEquals([outer1RootFolder.path]));
+    expect(outer1Root.excludedPaths, isEmpty);
+    expect(outer1Root.optionsFile, isNull);
+    expect(outer1Root.packagesFile, isNull);
+
+    ContextRoot outer2Root = findRoot(roots, getFolder('/'));
+    expect(outer2Root.includedPaths, unorderedEquals([testFile.path]));
+    expect(outer2Root.excludedPaths, isEmpty);
+    expect(outer2Root.optionsFile, isNull);
+    expect(outer2Root.packagesFile, isNull);
+  }
+
+  void test_locateRoots_multiple_dirs_bazel_differentWorkspaces() {
+    var workspacePath1 = '/home/workspace1';
+    var workspacePath2 = '/home/workspace2';
+    var pkgPath1 = '$workspacePath1/pkg1';
+    var pkgPath2 = '$workspacePath2/pkg2';
+
+    newFile('$workspacePath1/WORKSPACE');
+    newFile('$workspacePath2/WORKSPACE');
+    newBazelBuildFile(pkgPath1, '');
+    newBazelBuildFile(pkgPath2, '');
+
+    var folder1 = newFolder('$pkgPath1/lib/folder1');
+    var folder2 = newFolder('$pkgPath2/lib/folder2');
+    var file1 = newFile('$pkgPath1/lib/folder1/file1.dart');
+    var file2 = newFile('$pkgPath2/lib/folder2/file2.dart');
+
+    var roots = contextLocator.locateRoots(
+      includedPaths: [folder1.path, folder2.path],
+    );
+    expect(roots, hasLength(2));
+
+    var root1 = findRoot(roots, getFolder(folder1.path));
+    expect(root1.includedPaths, unorderedEquals([folder1.path]));
+    expect(root1.excludedPaths, isEmpty);
+    expect(root1.optionsFile, isNull);
+    expect(root1.packagesFile, isNull);
+    _assertBazelWorkspace(root1.workspace, workspacePath1);
+    _assertAnalyzedFiles2(root1, [file1]);
+
+    var root2 = findRoot(roots, getFolder(folder2.path));
+    expect(root2.includedPaths, unorderedEquals([folder2.path]));
+    expect(root2.excludedPaths, isEmpty);
+    expect(root2.optionsFile, isNull);
+    expect(root2.packagesFile, isNull);
+    _assertBazelWorkspace(root2.workspace, workspacePath2);
+    _assertAnalyzedFiles2(root2, [file2]);
+  }
+
   /// Even if a file is excluded by the options, when it is explicitly included
   /// into analysis, it should be analyzed.
   void test_locateRoots_multiple_fileAndSiblingFile_excludedByOptions() {
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 932abb8..ac0dca1 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,21 @@
     return driver.test.libraryContext.linkedCycles;
   }
 
+  test_change_factoryConstructor_addEqNothing() async {
+    await resolveTestCode(r'''
+class A {
+  factory A();
+}
+''');
+
+    driverFor(testFilePath).changeFile(testFilePath);
+    await resolveTestCode(r'''
+class A {
+  factory A() =;
+}
+''');
+  }
+
   test_change_factoryConstructor_moveStaticToken() async {
     await resolveTestCode(r'''
 class A {
@@ -39,6 +54,22 @@
 ''');
   }
 
+  test_change_field_outOfOrderStaticConst() async {
+    await resolveTestCode(r'''
+class A {
+  static f = Object();
+}
+''');
+
+    driverFor(testFilePath).changeFile(testFilePath);
+    await resolveTestCode(r'''
+class A {
+  const
+  static f = Object();
+}
+''');
+  }
+
   test_change_field_staticFinal_hasConstConstructor_changeInitializer() async {
     useEmptyByteStore();
 
@@ -113,10 +144,14 @@
     _assertNoLinkedCycles();
   }
 
-  @FailingTest(issue: 'https://github.com/dart-lang/linter/issues/2399')
   test_lints() async {
     useEmptyByteStore();
 
+    // Configure without any lint, but without experiments as well.
+    writeTestPackageAnalysisOptionsFile(
+      AnalysisOptionsFileConfig(lints: []),
+    );
+
     newFile(testFilePath, content: r'''
 void f() {
   ![0].isEmpty;
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
index f3bb485..5a0883d 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
@@ -427,7 +427,7 @@
     expect(prefixed.prefix.staticType, isNull);
 
     expect(annotation.constructorName!.staticElement, aGetter);
-    expect(annotation.constructorName!.staticType, typeProvider.intType);
+    assertTypeNull(annotation.constructorName!);
 
     expect(annotation.arguments, isNull);
   }
@@ -508,7 +508,7 @@
 
     var constructorName = annotation.constructorName as SimpleIdentifier;
     expect(constructorName.staticElement, same(constructor));
-    assertType(constructorName.staticType, 'A Function(int, {int b})');
+    assertTypeNull(constructorName);
 
     var arguments = annotation.arguments!.arguments;
     var parameters = constructor.parameters;
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
index 6ba7bff..9ddda1e 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
@@ -13,6 +13,7 @@
 import 'package:analyzer/src/dart/analysis/file_state.dart';
 import 'package:analyzer/src/dart/analysis/performance_logger.dart';
 import 'package:analyzer/src/dart/analysis/status.dart';
+import 'package:analyzer/src/dart/ast/extensions.dart';
 import 'package:analyzer/src/dart/constant/evaluation.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/error/codes.dart';
@@ -193,7 +194,7 @@
     driver1.priorityFiles = [a];
     driver2.priorityFiles = [a];
 
-    ResolvedUnitResult result = (await driver2.getResult(b))!;
+    ResolvedUnitResult result = await driver2.getResult(b);
     expect(result.path, b);
 
     await scheduler.status.firstWhere((status) => status.isIdle);
@@ -442,9 +443,9 @@
 part of 'lib.dart';
 ''');
 
-    ResolvedUnitResult libResult = (await driver.getResult(lib))!;
-    ResolvedUnitResult partResult1 = (await driver.getResult(part1))!;
-    ResolvedUnitResult partResult2 = (await driver.getResult(part2))!;
+    ResolvedUnitResult libResult = await driver.getResult(lib);
+    ResolvedUnitResult partResult1 = await driver.getResult(part1);
+    ResolvedUnitResult partResult2 = await driver.getResult(part2);
 
     CompilationUnit libUnit = libResult.unit!;
     CompilationUnit partUnit1 = partResult1.unit!;
@@ -489,7 +490,7 @@
 
     driver.addFile(lib);
 
-    ResolvedUnitResult libResult = (await driver.getResult(lib))!;
+    ResolvedUnitResult libResult = await driver.getResult(lib);
     List<AnalysisError> errors = libResult.errors;
     expect(errors, hasLength(1));
     expect(errors[0].errorCode, CompileTimeErrorCode.PART_OF_UNNAMED_LIBRARY);
@@ -508,7 +509,7 @@
 
     driver.addFile(lib);
 
-    ResolvedUnitResult libResult = (await driver.getResult(lib))!;
+    ResolvedUnitResult libResult = await driver.getResult(lib);
     List<AnalysisError> errors = libResult.errors;
     expect(errors, hasLength(1));
     expect(errors[0].errorCode, CompileTimeErrorCode.PART_OF_DIFFERENT_LIBRARY);
@@ -527,7 +528,7 @@
 
     driver.addFile(lib);
 
-    ResolvedUnitResult libResult = (await driver.getResult(lib))!;
+    ResolvedUnitResult libResult = await driver.getResult(lib);
     List<AnalysisError> errors = libResult.errors;
     expect(errors, hasLength(1));
     expect(errors[0].errorCode, CompileTimeErrorCode.PART_OF_DIFFERENT_LIBRARY);
@@ -546,7 +547,7 @@
 
     driver.addFile(lib);
 
-    ResolvedUnitResult libResult = (await driver.getResult(lib))!;
+    ResolvedUnitResult libResult = await driver.getResult(lib);
     List<AnalysisError> errors = libResult.errors;
     expect(errors, hasLength(1));
     expect(errors[0].errorCode, CompileTimeErrorCode.PART_OF_NON_PART);
@@ -558,7 +559,7 @@
 
     driver.priorityFiles = [a];
 
-    ResolvedUnitResult result1 = (await driver.getResult(a))!;
+    ResolvedUnitResult result1 = await driver.getResult(a);
     expect(driver.test.priorityResults, containsPair(a, result1));
 
     await waitForIdleWithoutExceptions();
@@ -566,7 +567,7 @@
 
     // Get the (cached) result, not reported to the stream.
     {
-      ResolvedUnitResult result2 = (await driver.getResult(a))!;
+      ResolvedUnitResult result2 = await driver.getResult(a);
       expect(result2, same(result1));
       expect(allResults, isEmpty);
     }
@@ -574,7 +575,7 @@
     // Get the (cached) result, reported to the stream.
     {
       ResolvedUnitResult result2 =
-          (await driver.getResult(a, sendCachedToStream: true))!;
+          await driver.getResult(a, sendCachedToStream: true);
       expect(result2, same(result1));
 
       expect(allResults, hasLength(1));
@@ -590,21 +591,21 @@
 
     driver.priorityFiles = [a];
 
-    ResolvedUnitResult result1 = (await driver.getResult(a))!;
+    ResolvedUnitResult result1 = await driver.getResult(a);
     expect(driver.test.priorityResults, containsPair(a, result1));
 
     // Change a file.
     // The cache is flushed.
     driver.changeFile(a);
     expect(driver.test.priorityResults, isEmpty);
-    ResolvedUnitResult result2 = (await driver.getResult(a))!;
+    ResolvedUnitResult result2 = await driver.getResult(a);
     expect(driver.test.priorityResults, containsPair(a, result2));
 
     // Add a file.
     // The cache is flushed.
     driver.addFile(b);
     expect(driver.test.priorityResults, isEmpty);
-    ResolvedUnitResult result3 = (await driver.getResult(a))!;
+    ResolvedUnitResult result3 = await driver.getResult(a);
     expect(driver.test.priorityResults, containsPair(a, result3));
 
     // Remove a file.
@@ -621,7 +622,7 @@
 
     driver.priorityFiles = [a];
 
-    ResolvedUnitResult result1 = (await driver.getResult(a))!;
+    ResolvedUnitResult result1 = await driver.getResult(a);
     expect(driver.test.priorityResults, hasLength(1));
     expect(driver.test.priorityResults, containsPair(a, result1));
 
@@ -632,7 +633,7 @@
     expect(driver.test.priorityResults, containsPair(a, result1));
 
     // Get the result for "b".
-    ResolvedUnitResult result2 = (await driver.getResult(b))!;
+    ResolvedUnitResult result2 = await driver.getResult(b);
     expect(driver.test.priorityResults, hasLength(2));
     expect(driver.test.priorityResults, containsPair(a, result1));
     expect(driver.test.priorityResults, containsPair(b, result2));
@@ -648,11 +649,11 @@
     var a = convertPath('/test/bin/a.dart');
     newFile(a, content: 'var a = 1;');
 
-    ResolvedUnitResult result1 = (await driver.getResult(a))!;
+    ResolvedUnitResult result1 = await driver.getResult(a);
     expect(driver.test.priorityResults, isEmpty);
 
     // The file is not priority, so its result is not cached.
-    ResolvedUnitResult result2 = (await driver.getResult(a))!;
+    ResolvedUnitResult result2 = await driver.getResult(a);
     expect(result2, isNot(same(result1)));
   }
 
@@ -822,7 +823,7 @@
 @A(5)
 class C {}
 ''');
-    var result = (await driver.getResult(testFile))!;
+    var result = await driver.getResult(testFile);
     var atD = AstFinder.getClass(result.unit!, 'C').metadata[0];
     var atDI = atD.elementAnnotation as ElementAnnotationImpl;
     var value = atDI.evaluationResult!.value;
@@ -839,7 +840,7 @@
   final value;
 }
 ''');
-    var result = (await driver.getResult(testFile))!;
+    var result = await driver.getResult(testFile);
     var atD = AstFinder.getClass(result.unit!, 'C').metadata[0];
     var atDI = atD.elementAnnotation as ElementAnnotationImpl;
     var value = atDI.evaluationResult!.value!;
@@ -855,7 +856,7 @@
 const x = 1;
 @x class C {}
 ''');
-    var result = (await driver.getResult(testFile))!;
+    var result = await driver.getResult(testFile);
     Annotation at_x = AstFinder.getClass(result.unit!, 'C').metadata[0];
     expect(at_x.elementAnnotation!.computeConstantValue()!.toIntValue(), 1);
   }
@@ -865,7 +866,7 @@
 const x = y + 1;
 const y = x + 1;
 ''');
-    var result = (await driver.getResult(testFile))!;
+    var result = await driver.getResult(testFile);
     var x = AstFinder.getTopLevelVariableElement(result.unit!, 'x')
         as TopLevelVariableElementImpl;
     _expectCircularityError(x.evaluationResult!);
@@ -876,7 +877,7 @@
 const x = y + 1;
 const y = 1;
 ''');
-    var result = (await driver.getResult(testFile))!;
+    var result = await driver.getResult(testFile);
     var x = AstFinder.getTopLevelVariableElement(result.unit!, 'x');
     var y = AstFinder.getTopLevelVariableElement(result.unit!, 'y');
     expect(x.computeConstantValue()!.toIntValue(), 2);
@@ -893,7 +894,7 @@
 
 class B {}
 ''');
-    var result = (await driver.getResult(testFile))!;
+    var result = await driver.getResult(testFile);
     var x = AstFinder.getTopLevelVariableElement(result.unit!, 'x');
     expect(x.computeConstantValue(), isNotNull);
   }
@@ -918,7 +919,7 @@
 const c = C.WARNING;
 const d = D.WARNING;
 ''');
-    ResolvedUnitResult result = (await driver.getResult(b))!;
+    ResolvedUnitResult result = await driver.getResult(b);
     expect(result.errors, isEmpty);
   }
 
@@ -947,7 +948,7 @@
   const C();
 }
 ''');
-    ResolvedUnitResult result = (await driver.getResult(b))!;
+    ResolvedUnitResult result = await driver.getResult(b);
     expect(result.errors, isEmpty);
   }
 
@@ -959,7 +960,7 @@
 }
 const x = const Derived();
 ''');
-    var result = (await driver.getResult(testFile))!;
+    var result = await driver.getResult(testFile);
     var x = AstFinder.getTopLevelVariableElement(result.unit!, 'x');
     expect(x.computeConstantValue(), isNotNull);
   }
@@ -968,7 +969,7 @@
     addTestFile('''
 const x = 1;
 ''');
-    var result = (await driver.getResult(testFile))!;
+    var result = await driver.getResult(testFile);
     var x = AstFinder.getTopLevelVariableElement(result.unit!, 'x');
     expect(x.computeConstantValue()!.toIntValue(), 1);
   }
@@ -977,14 +978,14 @@
     var a = convertPath('/a.dart');
 
     newFile(a, content: 'var V = 1;');
-    (await driver.getResult(a))!;
+    await driver.getResult(a);
 
     var session1 = driver.currentSession;
     expect(session1, isNotNull);
 
     modifyFile(a, 'var V = 2;');
     driver.changeFile(a);
-    (await driver.getResult(a))!;
+    await driver.getResult(a);
 
     var session2 = driver.currentSession;
     expect(session2, isNotNull);
@@ -1045,7 +1046,7 @@
 export 'foo.dart';
 ''');
 
-    ResolvedUnitResult result = (await driver.getResult(testFile))!;
+    ResolvedUnitResult result = await driver.getResult(testFile);
     List<AnalysisError> errors = result.errors;
     expect(errors, hasLength(1));
     expect(errors[0].errorCode, CompileTimeErrorCode.URI_DOES_NOT_EXIST);
@@ -1056,7 +1057,7 @@
 import 'foo.dart';
 ''');
 
-    ResolvedUnitResult result = (await driver.getResult(testFile))!;
+    ResolvedUnitResult result = await driver.getResult(testFile);
     List<AnalysisError> errors = result.errors;
     expect(errors, hasLength(1));
     expect(errors[0].errorCode, CompileTimeErrorCode.URI_DOES_NOT_EXIST);
@@ -1070,7 +1071,7 @@
 }
 ''', priority: true);
 
-    ResolvedUnitResult result = (await driver.getResult(testFile))!;
+    ResolvedUnitResult result = await driver.getResult(testFile);
     List<AnalysisError> errors = result.errors;
     expect(errors, hasLength(1));
     expect(errors[0].errorCode, CompileTimeErrorCode.URI_DOES_NOT_EXIST);
@@ -1082,7 +1083,7 @@
 part 'foo.dart';
 ''');
 
-    ResolvedUnitResult result = (await driver.getResult(testFile))!;
+    ResolvedUnitResult result = await driver.getResult(testFile);
     List<AnalysisError> errors = result.errors;
     expect(errors, hasLength(1));
     expect(errors[0].errorCode, CompileTimeErrorCode.URI_DOES_NOT_EXIST);
@@ -1122,12 +1123,12 @@
     expect(allResults, isEmpty);
 
     var result = await driver.getResult(templatePath);
-    expect(result, isNull);
+    expect(result.state, ResultState.NOT_FILE_OF_URI);
     expect(allExceptions, isEmpty);
     expect(allResults, isEmpty);
 
-    var element = await driver.getUnitElement(templatePath);
-    expect(element, isNull);
+    var elementResult = await driver.getUnitElement(templatePath);
+    expect(elementResult.state, ResultState.NOT_FILE_OF_URI);
     expect(allExceptions, isEmpty);
     expect(allResults, isEmpty);
 
@@ -1147,7 +1148,7 @@
     expect(driver.getCachedResult(a), isNull);
 
     driver.priorityFiles = [a];
-    ResolvedUnitResult result = (await driver.getResult(a))!;
+    ResolvedUnitResult result = await driver.getResult(a);
 
     expect(driver.getCachedResult(a), same(result));
   }
@@ -1156,7 +1157,7 @@
     String content = 'int f() => 42 + bar();';
     addTestFile(content, priority: true);
 
-    var result = (await driver.getErrors(testFile))!;
+    var result = await driver.getErrors(testFile);
     expect(result.path, testFile);
     expect(result.uri.toString(), 'package:test/test.dart');
     expect(result.errors, hasLength(1));
@@ -1284,7 +1285,7 @@
 
     // Ensure that [a.dart] library cycle is loaded.
     // So, `a.dart` is in the library context.
-    (await driver.getResult(a))!;
+    await driver.getResult(a);
 
     // Update the file, changing its API signature.
     // Note that we don't call `changeFile`.
@@ -1298,14 +1299,14 @@
     expect(driver.getFileSync(a).lineInfo.lineCount, 1);
 
     // We have not read `a.dart`, so `A` is still not declared.
-    expect(((await driver.getResult(b))!).errors, isNotEmpty);
+    expect((await driver.getResult(b)).errors, isNotEmpty);
 
     // Notify the driver that the file was changed.
     driver.changeFile(a);
 
     // So, `class A {}` is declared now.
     expect(driver.getFileSync(a).lineInfo.lineCount, 2);
-    expect(((await driver.getResult(b))!).errors, isEmpty);
+    expect((await driver.getResult(b)).errors, isEmpty);
   }
 
   test_getFileSync_library() async {
@@ -1394,7 +1395,7 @@
     String content = 'int f() => 42;';
     addTestFile(content, priority: true);
 
-    ResolvedUnitResult result = (await driver.getResult(testFile))!;
+    ResolvedUnitResult result = await driver.getResult(testFile);
     expect(result.path, testFile);
     expect(result.uri.toString(), 'package:test/test.dart');
     expect(result.state, ResultState.VALID);
@@ -1404,7 +1405,7 @@
 
     var f = result.unit!.declarations[0] as FunctionDeclaration;
     assertType(f.declaredElement!.type, 'int Function()');
-    assertType(f.returnType!.type!, 'int');
+    assertType(f.returnType!.typeOrThrow, 'int');
 
     // The same result is also received through the stream.
     await waitForIdleWithoutExceptions();
@@ -1426,14 +1427,14 @@
     driver.addFile(b);
     await waitForIdleWithoutExceptions();
 
-    ResolvedUnitResult result = (await driver.getResult(b))!;
+    ResolvedUnitResult result = await driver.getResult(b);
     expect(result.errors, isEmpty);
   }
 
   test_getResult_doesNotExist() async {
     var a = convertPath('/test/lib/a.dart');
 
-    ResolvedUnitResult result = (await driver.getResult(a))!;
+    ResolvedUnitResult result = await driver.getResult(a);
     expect(result.path, a);
     expect(result.uri.toString(), 'package:test/a.dart');
     expect(result.state, ResultState.NOT_A_FILE);
@@ -1444,7 +1445,7 @@
     String content = 'main() { int vv; }';
     addTestFile(content, priority: true);
 
-    ResolvedUnitResult result = (await driver.getResult(testFile))!;
+    ResolvedUnitResult result = await driver.getResult(testFile);
     expect(result.path, testFile);
     expect(result.errors, hasLength(1));
     {
@@ -1467,7 +1468,7 @@
 class B {}
 ''');
 
-    ResolvedUnitResult result = (await driver.getResult(testFile))!;
+    ResolvedUnitResult result = await driver.getResult(testFile);
     expect(result.path, testFile);
   }
 
@@ -1479,7 +1480,7 @@
 ''';
     addTestFile(content, priority: true);
 
-    var result = (await driver.getResult(testFile))!;
+    var result = await driver.getResult(testFile);
     expect(result.errors, isEmpty);
   }
 
@@ -1498,7 +1499,7 @@
 
     // No errors in b.dart
     {
-      ResolvedUnitResult result = (await driver.getResult(b))!;
+      ResolvedUnitResult result = await driver.getResult(b);
       expect(result.errors, isEmpty);
     }
 
@@ -1508,7 +1509,7 @@
 
     // The unresolved URI error must be reported.
     {
-      ResolvedUnitResult result = (await driver.getResult(b))!;
+      ResolvedUnitResult result = await driver.getResult(b);
       expect(
           result.errors,
           contains(predicate((AnalysisError e) =>
@@ -1521,7 +1522,7 @@
 
     // No errors in b.dart again.
     {
-      ResolvedUnitResult result = (await driver.getResult(b))!;
+      ResolvedUnitResult result = await driver.getResult(b);
       expect(result.errors, isEmpty);
     }
   }
@@ -1534,7 +1535,7 @@
 ''', priority: true);
     await waitForIdleWithoutExceptions();
 
-    ResolvedUnitResult result = (await driver.getResult(testFile))!;
+    ResolvedUnitResult result = await driver.getResult(testFile);
     _assertClassFieldType(result.unit!, 'C', 'f', 'int');
   }
 
@@ -1549,7 +1550,7 @@
 ''', priority: true);
     await waitForIdleWithoutExceptions();
 
-    ResolvedUnitResult result = (await driver.getResult(testFile))!;
+    ResolvedUnitResult result = await driver.getResult(testFile);
     _assertClassMethodReturnType(result.unit!, 'A', 'm', 'int');
     _assertClassMethodReturnType(result.unit!, 'B', 'm', 'int');
   }
@@ -1562,7 +1563,7 @@
 class C {}
 ''', priority: true);
 
-    ResolvedUnitResult result = (await driver.getResult(testFile))!;
+    ResolvedUnitResult result = await driver.getResult(testFile);
     ClassDeclaration c = result.unit!.declarations[1] as ClassDeclaration;
     Annotation a = c.metadata[0];
     expect(a.name.name, 'fff');
@@ -1589,7 +1590,7 @@
 ''';
     addTestFile(content);
 
-    ResolvedUnitResult result = (await driver.getResult(testFile))!;
+    ResolvedUnitResult result = await driver.getResult(testFile);
     expect(result.path, testFile);
   }
 
@@ -1601,7 +1602,7 @@
 ''';
     addTestFile(content, priority: true);
 
-    ResolvedUnitResult result = (await driver.getResult(testFile))!;
+    ResolvedUnitResult result = await driver.getResult(testFile);
     expect(result.path, testFile);
     // Has only exports for valid URIs.
     List<ExportElement> imports = result.libraryElement.exports;
@@ -1618,7 +1619,7 @@
 ''';
     addTestFile(content, priority: true);
 
-    ResolvedUnitResult result = (await driver.getResult(testFile))!;
+    ResolvedUnitResult result = await driver.getResult(testFile);
     expect(result.path, testFile);
     // Has only imports for valid URIs.
     List<ImportElement> imports = result.libraryElement.imports;
@@ -1639,7 +1640,7 @@
 part '';
 ''';
     addTestFile(content);
-    (await driver.getResult(testFile))!;
+    await driver.getResult(testFile);
   }
 
   test_getResult_languageVersion() async {
@@ -1649,7 +1650,7 @@
 class A{}
 ''');
 
-    var result = (await driver.getResult(path))!;
+    var result = await driver.getResult(path);
     var languageVersion = result.unit!.languageVersionToken!;
     expect(languageVersion.major, 2);
     expect(languageVersion.minor, 7);
@@ -1686,7 +1687,7 @@
     // package:my_pkg/c.dart's import is erroneous, causing y's reference to z
     // to be unresolved (and therefore have type dynamic).
     {
-      ResolvedUnitResult result = (await driver.getResult(a))!;
+      ResolvedUnitResult result = await driver.getResult(a);
       expect(result.errors, isEmpty);
     }
 
@@ -1696,7 +1697,7 @@
     // successfully imports file:///my_pkg/test/d.dart, causing y to have an
     // inferred type of String.
     {
-      ResolvedUnitResult result = (await driver.getResult(b))!;
+      ResolvedUnitResult result = await driver.getResult(b);
       List<AnalysisError> errors = result.errors;
       expect(errors, hasLength(1));
       expect(errors[0].errorCode, CompileTimeErrorCode.INVALID_ASSIGNMENT);
@@ -1710,7 +1711,7 @@
 var V;
 ''';
     addTestFile(content);
-    (await driver.getResult(testFile))!;
+    await driver.getResult(testFile);
   }
 
   test_getResult_nameConflict_local_typeInference() async {
@@ -1724,7 +1725,7 @@
 }
 ''';
     addTestFile(content);
-    (await driver.getResult(testFile))!;
+    await driver.getResult(testFile);
   }
 
   test_getResult_notAbsolutePath() async {
@@ -1737,7 +1738,7 @@
     var path = convertPath('/test/lib/test.txt');
     newFile(path, content: 'class A {}');
 
-    ResolvedUnitResult result = (await driver.getResult(path))!;
+    ResolvedUnitResult result = await driver.getResult(path);
     expect(result, isNotNull);
     expect(result.unit!.declaredElement!.types.map((e) => e.name), ['A']);
   }
@@ -1749,7 +1750,7 @@
 ''';
     addTestFile(content);
     // Should not throw exceptions.
-    (await driver.getResult(testFile))!;
+    await driver.getResult(testFile);
   }
 
   test_getResult_sameFile_twoUris() async {
@@ -1771,14 +1772,14 @@
     await waitForIdleWithoutExceptions();
 
     {
-      ResolvedUnitResult result = (await driver.getResult(b))!;
+      ResolvedUnitResult result = await driver.getResult(b);
       expect(_getImportSource(result.unit!, 0).uri.toString(),
           'package:test/a.dart');
       _assertTopLevelVarType(result.unit!, 'VB', 'A<int>');
     }
 
     {
-      ResolvedUnitResult result = (await driver.getResult(c))!;
+      ResolvedUnitResult result = await driver.getResult(c);
       expect(
         _getImportSource(result.unit!, 0).uri,
         toUri('/test/lib/a.dart'),
@@ -1805,7 +1806,7 @@
     await waitForIdleWithoutExceptions();
 
     {
-      ResolvedUnitResult result = (await driver.getResult(a))!;
+      ResolvedUnitResult result = await driver.getResult(a);
       _assertTopLevelVarType(result.unit!, 'A1', 'int');
       _assertTopLevelVarType(result.unit!, 'A2', 'int');
     }
@@ -1825,7 +1826,7 @@
     driver.changeFile(a);
 
     {
-      ResolvedUnitResult result = (await driver.getResult(a))!;
+      ResolvedUnitResult result = await driver.getResult(a);
       _assertTopLevelVarType(result.unit!, 'A1', 'double');
       _assertTopLevelVarType(result.unit!, 'A2', 'double');
     }
@@ -1837,7 +1838,7 @@
     var resultFuture = driver.getResult(testFile);
     driver.removeFile(testFile);
 
-    var result = (await resultFuture)!;
+    var result = await resultFuture;
     expect(result.path, testFile);
     expect(result.unit!, isNotNull);
   }
@@ -1850,8 +1851,8 @@
     var future2 = driver.getResult(testFile);
 
     // Both futures complete, with the same result.
-    ResolvedUnitResult result1 = (await future1)!;
-    ResolvedUnitResult result2 = (await future2)!;
+    ResolvedUnitResult result1 = await future1;
+    ResolvedUnitResult result2 = await future2;
     expect(result2, same(result1));
     expect(result1.path, testFile);
     expect(result1.unit!, isNotNull);
@@ -1870,7 +1871,7 @@
 
     // Ensure that [a.dart] library cycle is loaded.
     // So, `a.dart` is in the library context.
-    (await driver.getResult(a))!;
+    await driver.getResult(a);
 
     // Update the file, changing its API signature.
     // Note that we don't call `changeFile`.
@@ -1884,14 +1885,14 @@
     expect(await driver.getSourceKind(a), SourceKind.PART);
 
     // We have not read `a.dart`, so `A` is still not declared.
-    expect(((await driver.getResult(b))!).errors, isNotEmpty);
+    expect((await driver.getResult(b)).errors, isNotEmpty);
 
     // Notify the driver that the file was changed.
     driver.changeFile(a);
 
     // So, `class A {}` is declared now.
     expect(await driver.getSourceKind(a), SourceKind.LIBRARY);
-    expect(((await driver.getResult(b))!).errors, isEmpty);
+    expect((await driver.getResult(b)).errors, isEmpty);
   }
 
   test_getSourceKind_changeFile() async {
@@ -1945,7 +1946,7 @@
 ''';
     addTestFile(content);
 
-    UnitElementResult unitResult = (await driver.getUnitElement(testFile))!;
+    UnitElementResult unitResult = await driver.getUnitElement(testFile);
     CompilationUnitElement unitElement = unitResult.element;
     expect(unitElement.source.fullName, testFile);
     expect(unitElement.functions.map((c) => c.name),
@@ -1973,7 +1974,7 @@
   test_getUnitElement_notDart() async {
     var path = convertPath('/test.txt');
     newFile(path, content: 'class A {}');
-    UnitElementResult unitResult = (await driver.getUnitElement(path))!;
+    UnitElementResult unitResult = await driver.getUnitElement(path);
     expect(unitResult.element.types.map((e) => e.name), ['A']);
   }
 
@@ -1985,7 +1986,7 @@
     String signature = await driver.getUnitElementSignature(a);
     expect(signature, isNotNull);
 
-    UnitElementResult unitResult = (await driver.getUnitElement(a))!;
+    UnitElementResult unitResult = await driver.getUnitElement(a);
     expect(unitResult.path, a);
     expect(unitResult.signature, signature);
 
@@ -2047,7 +2048,7 @@
     driver.addFile(a);
     driver.addFile(b);
 
-    (await driver.getResult(b))!;
+    await driver.getResult(b);
 
     // Modify the library, but don't notify the driver.
     // The driver should use the previous library content and elements.
@@ -2059,7 +2060,7 @@
 }
 ''');
 
-    var result = (await driver.getResult(b))!;
+    var result = await driver.getResult(b);
     var c = _getTopLevelVar(result.unit!, 'c');
     var typeC = c.declaredElement!.type as InterfaceType;
     // The class C has an old field 'foo', not the new 'bar'.
@@ -2081,7 +2082,7 @@
     driver.addFile(a);
     driver.addFile(b);
 
-    ResolvedUnitResult result = (await driver.getResult(a))!;
+    ResolvedUnitResult result = await driver.getResult(a);
     expect(result.errors, isEmpty);
     _assertTopLevelVarType(result.unit!, 'b', 'B');
   }
@@ -2106,10 +2107,10 @@
 ''');
 
     // This ensures that `a.dart` linked library is cached.
-    (await driver.getResult(a))!;
+    await driver.getResult(a);
 
     // Should not fail because of considering `b.dart` part as `a.dart` library.
-    (await driver.getResult(c))!;
+    await driver.getResult(c);
   }
 
   test_instantiateToBounds_invalid() async {
@@ -2212,7 +2213,7 @@
     getFile(asyncPath).delete();
     addTestFile('class C {}');
 
-    ErrorsResult result = (await driver.getErrors(testFile))!;
+    ErrorsResult result = await driver.getErrors(testFile);
     expect(result.errors, hasLength(1));
 
     AnalysisError error = result.errors[0];
@@ -2224,7 +2225,7 @@
     getFile(corePath).delete();
     addTestFile('class C {}');
 
-    ErrorsResult result = (await driver.getErrors(testFile))!;
+    ErrorsResult result = await driver.getErrors(testFile);
     expect(result.errors, hasLength(1));
 
     AnalysisError error = result.errors[0];
@@ -2244,7 +2245,7 @@
 
     // Ensure that [a.dart] library cycle is loaded.
     // So, `a.dart` is in the library context.
-    (await driver.getResult(a))!;
+    await driver.getResult(a);
 
     // Update the file, changing its API signature.
     // Note that we don't call `changeFile`.
@@ -2262,7 +2263,7 @@
 
     // We have not read `a.dart`, so `A` is still not declared.
     {
-      var bResult = (await driver.getResult(b))!;
+      var bResult = await driver.getResult(b);
       expect(bResult.errors, isNotEmpty);
     }
 
@@ -2275,7 +2276,7 @@
       expect(parseResult.unit.declarations, hasLength(1));
     }
     {
-      var bResult = (await driver.getResult(b))!;
+      var bResult = await driver.getResult(b);
       expect(bResult.errors, isEmpty);
     }
   }
@@ -2308,7 +2309,7 @@
 
     // Ensure that [a.dart] library cycle is loaded.
     // So, `a.dart` is in the library context.
-    (await driver.getResult(a))!;
+    await driver.getResult(a);
 
     // Update the file, changing its API signature.
     // Note that we don't call `changeFile`.
@@ -2326,7 +2327,7 @@
 
     // We have not read `a.dart`, so `A` is still not declared.
     {
-      var bResult = (await driver.getResult(b))!;
+      var bResult = await driver.getResult(b);
       expect(bResult.errors, isNotEmpty);
     }
 
@@ -2339,7 +2340,7 @@
       expect(parseResult.unit.declarations, hasLength(1));
     }
     {
-      var bResult = (await driver.getResult(b))!;
+      var bResult = await driver.getResult(b);
       expect(bResult.errors, isEmpty);
     }
   }
@@ -2452,13 +2453,13 @@
 
     // Process a.dart so that we know that it's a library for c.dart later.
     {
-      ErrorsResult result = (await driver.getErrors(a))!;
+      ErrorsResult result = await driver.getErrors(a);
       expect(result.errors, isEmpty);
     }
 
     // c.dart does not have errors in the context of a.dart
     {
-      ErrorsResult result = (await driver.getErrors(c))!;
+      ErrorsResult result = await driver.getErrors(c);
       expect(result.errors, isEmpty);
     }
   }
@@ -2488,7 +2489,7 @@
 
     // c.dart is resolve in the context of a.dart, so have no errors
     {
-      ErrorsResult result = (await driver.getErrors(c))!;
+      ErrorsResult result = await driver.getErrors(c);
       expect(result.errors, isEmpty);
     }
   }
@@ -2518,14 +2519,14 @@
 
     // Process a.dart so that we know that it's a library for c.dart later.
     {
-      ResolvedUnitResult result = (await driver.getResult(a))!;
+      ResolvedUnitResult result = await driver.getResult(a);
       expect(result.errors, isEmpty);
       _assertTopLevelVarType(result.unit!, 'c', 'C');
     }
 
     // Now c.dart can be resolved without errors in the context of a.dart
     {
-      ResolvedUnitResult result = (await driver.getResult(c))!;
+      ResolvedUnitResult result = await driver.getResult(c);
       expect(result.errors, isEmpty);
       _assertTopLevelVarType(result.unit!, 'a', 'A');
       _assertTopLevelVarType(result.unit!, 'b', 'B');
@@ -2557,7 +2558,7 @@
 
     // b.dart will be analyzed after a.dart is analyzed.
     // So, A and B references are resolved.
-    ResolvedUnitResult result = (await driver.getResult(c))!;
+    ResolvedUnitResult result = await driver.getResult(c);
     expect(result.errors, isEmpty);
     _assertTopLevelVarType(result.unit!, 'a', 'A');
     _assertTopLevelVarType(result.unit!, 'b', 'B');
@@ -2573,7 +2574,7 @@
     driver.addFile(a);
 
     // Analyze the library without the part.
-    (await driver.getResult(a))!;
+    await driver.getResult(a);
 
     // Create the part file.
     // This should invalidate library file state (specifically the library
@@ -2585,7 +2586,7 @@
     driver.changeFile(b);
 
     // This should not crash.
-    var result = (await driver.getResult(b))!;
+    var result = await driver.getResult(b);
     expect(result.errors, isEmpty);
   }
 
@@ -2602,7 +2603,7 @@
 
     // There is no library which c.dart is a part of, so it has unresolved
     // A and B references.
-    ResolvedUnitResult result = (await driver.getResult(c))!;
+    ResolvedUnitResult result = await driver.getResult(c);
     expect(result.errors, isNotEmpty);
     expect(result.unit!, isNotNull);
   }
@@ -2631,11 +2632,11 @@
     driver.addFile(c);
 
     // Process a.dart so that we know that it's a library for c.dart later.
-    (await driver.getResult(a))!;
+    await driver.getResult(a);
 
     // c.dart is resolve in the context of a.dart, knows 'A' and 'B'.
     {
-      UnitElementResult result = (await driver.getUnitElement(c))!;
+      UnitElementResult result = await driver.getUnitElement(c);
       var partUnit = result.element;
 
       assertType(partUnit.topLevelVariables[0].type, 'A');
@@ -2671,7 +2672,7 @@
 
     // c.dart is resolve in the context of a.dart, knows 'A' and 'B'.
     {
-      UnitElementResult result = (await driver.getUnitElement(c))!;
+      UnitElementResult result = await driver.getUnitElement(c);
       var partUnit = result.element;
 
       assertType(partUnit.topLevelVariables[0].type, 'A');
@@ -2695,7 +2696,7 @@
     // We don't know the library of c.dart, but we should get a result.
     // The types "A" and "B" are unresolved.
     {
-      UnitElementResult result = (await driver.getUnitElement(c))!;
+      UnitElementResult result = await driver.getUnitElement(c);
       var partUnit = result.element;
 
       expect(partUnit.topLevelVariables[0].name, 'a');
@@ -2733,7 +2734,7 @@
     String signatureBefore = await driver.getUnitElementSignature(c);
 
     // Process a.dart so that we know that it's a library for c.dart later.
-    (await driver.getResult(a))!;
+    await driver.getResult(a);
 
     // The before and after signatures must be the same.
     String signatureAfter = await driver.getUnitElementSignature(c);
@@ -3131,7 +3132,7 @@
 
     var f = result.unit!.declarations[0] as FunctionDeclaration;
     assertType(f.declaredElement!.type, 'int Function()');
-    assertType(f.returnType!.type!, 'int');
+    assertType(f.returnType!.typeOrThrow, 'int');
   }
 
   test_results_priorityFirst() async {
diff --git a/pkg/analyzer/test/src/dart/analysis/index_test.dart b/pkg/analyzer/test/src/dart/analysis/index_test.dart
index 080532a..8251b43 100644
--- a/pkg/analyzer/test/src/dart/analysis/index_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/index_test.dart
@@ -552,6 +552,20 @@
     assertThat(element).isReferencedAt('A();', false);
   }
 
+  test_isReferencedBy_ClassElement_inGenericAnnotation() async {
+    await _indexTestUnit('''
+class A<T> {
+  const A();
+}
+
+@A<A>()
+void f() {}
+''');
+    assertThat(findElement.class_('A'))
+      ..isReferencedAt('A<A', false)
+      ..isReferencedAt('A>()', false);
+  }
+
   test_isReferencedBy_ClassElement_inTypeAlias() async {
     await _indexTestUnit('''
 class A<T> {}
diff --git a/pkg/analyzer/test/src/dart/analysis/search_test.dart b/pkg/analyzer/test/src/dart/analysis/search_test.dart
index b27723e..10ac334 100644
--- a/pkg/analyzer/test/src/dart/analysis/search_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/search_test.dart
@@ -303,6 +303,25 @@
     await _verifyReferences(element, expected);
   }
 
+  test_searchReferences_ClassElement_typeArgument_ofGenericAnnotation() async {
+    await resolveTestCode('''
+class A<T> {
+  const A();
+}
+
+class B {}
+
+@A<B>()
+void f() {}
+''');
+
+    var element = findElement.class_('B');
+    var f = findElement.topFunction('f');
+    await _verifyReferences(element, [
+      _expectId(f, SearchResultKind.REFERENCE, 'B>()'),
+    ]);
+  }
+
   test_searchReferences_CompilationUnitElement() async {
     newFile('$testPackageLibPath/foo.dart');
     await resolveTestCode('''
@@ -357,7 +376,7 @@
 ''');
     var element = findElement.unnamedConstructor('A');
 
-    CompilationUnit otherUnit = (await driver.getResult(other))!.unit!;
+    CompilationUnit otherUnit = (await driver.getResult(other)).unit!;
     Element main = otherUnit.declaredElement!.functions[0];
     var expected = [
       ExpectedResult(main, SearchResultKind.REFERENCE,
diff --git a/pkg/analyzer/test/src/dart/analysis/session_test.dart b/pkg/analyzer/test/src/dart/analysis/session_test.dart
index a1c0131..f1235ca 100644
--- a/pkg/analyzer/test/src/dart/analysis/session_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/session_test.dart
@@ -4,6 +4,7 @@
 
 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/ast/ast.dart';
 import 'package:analyzer/src/dart/analysis/analysis_context_collection.dart';
 import 'package:analyzer/src/dart/analysis/session.dart';
@@ -13,13 +14,95 @@
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
+import '../resolution/context_collection_resolution.dart';
+
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(AnalysisSessionImplTest);
+    defineReflectiveTests(AnalysisSessionImpl_BazelWorkspaceTest);
   });
 }
 
 @reflectiveTest
+class AnalysisSessionImpl_BazelWorkspaceTest
+    extends BazelWorkspaceResolutionTest {
+  void test_getErrors_notFileOfUri() async {
+    var relPath = 'dart/my/lib/a.dart';
+    newFile('$workspaceRootPath/bazel-bin/$relPath');
+
+    var path = convertPath('$workspaceRootPath/$relPath');
+    var session = contextFor(path).currentSession;
+    var result = await session.getErrors(path);
+    expect(result.state, ResultState.NOT_FILE_OF_URI);
+    expect(() => result.errors, throwsStateError);
+  }
+
+  void test_getErrors_valid() async {
+    var file = newFile(
+      '$workspaceRootPath/dart/my/lib/a.dart',
+      content: 'var x = 0',
+    );
+
+    var session = contextFor(file.path).currentSession;
+    var result = await session.getErrors(file.path);
+    expect(result.state, ResultState.VALID);
+    expect(result.path, file.path);
+    expect(result.errors, hasLength(1));
+    expect(result.uri.toString(), 'package:dart.my/a.dart');
+  }
+
+  void test_getResolvedUnit_notFileOfUri() async {
+    var relPath = 'dart/my/lib/a.dart';
+    newFile('$workspaceRootPath/bazel-bin/$relPath');
+
+    var path = convertPath('$workspaceRootPath/$relPath');
+    var session = contextFor(path).currentSession;
+    var result = await session.getResolvedUnit(path);
+    expect(result.state, ResultState.NOT_FILE_OF_URI);
+    expect(() => result.errors, throwsStateError);
+  }
+
+  void test_getResolvedUnit_valid() async {
+    var file = newFile(
+      '$workspaceRootPath/dart/my/lib/a.dart',
+      content: 'class A {}',
+    );
+
+    var session = contextFor(file.path).currentSession;
+    var result = await session.getResolvedUnit(file.path);
+    expect(result.state, ResultState.VALID);
+    expect(result.path, file.path);
+    expect(result.errors, isEmpty);
+    expect(result.uri.toString(), 'package:dart.my/a.dart');
+  }
+
+  void test_getUnitElement_notFileOfUri() async {
+    var relPath = 'dart/my/lib/a.dart';
+    newFile('$workspaceRootPath/bazel-bin/$relPath');
+
+    var path = convertPath('$workspaceRootPath/$relPath');
+    var session = contextFor(path).currentSession;
+    var result = await session.getUnitElement(path);
+    expect(result.state, ResultState.NOT_FILE_OF_URI);
+    expect(() => result.element, throwsStateError);
+  }
+
+  void test_getUnitElement_valid() async {
+    var file = newFile(
+      '$workspaceRootPath/dart/my/lib/a.dart',
+      content: 'class A {}',
+    );
+
+    var session = contextFor(file.path).currentSession;
+    var result = await session.getUnitElement(file.path);
+    expect(result.state, ResultState.VALID);
+    expect(result.path, file.path);
+    expect(result.element.types, hasLength(1));
+    expect(result.uri.toString(), 'package:dart.my/a.dart');
+  }
+}
+
+@reflectiveTest
 class AnalysisSessionImplTest with ResourceProviderMixin {
   late final AnalysisContextCollection contextCollection;
   late final AnalysisContext context;
@@ -55,7 +138,7 @@
 
   test_getErrors() async {
     newFile(testPath, content: 'class C {');
-    var errorsResult = (await session.getErrors(testPath))!;
+    var errorsResult = await session.getErrors(testPath);
     expect(errorsResult.session, session);
     expect(errorsResult.path, testPath);
     expect(errorsResult.errors, isNotEmpty);
@@ -120,7 +203,7 @@
   test_getParsedLibrary_getElementDeclaration_notThisLibrary() async {
     newFile(testPath, content: '');
 
-    var resolvedUnit = (await session.getResolvedUnit(testPath))!;
+    var resolvedUnit = await session.getResolvedUnit(testPath);
     var typeProvider = resolvedUnit.typeProvider;
     var intClass = typeProvider.intType.element;
 
@@ -138,7 +221,7 @@
 
     var parsedLibrary = session.getParsedLibrary(testPath);
 
-    var unitElement = (await session.getUnitElement(testPath))!.element;
+    var unitElement = (await session.getUnitElement(testPath)).element;
     var fooElement = unitElement.topLevelVariables[0];
     expect(fooElement.name, 'foo');
 
@@ -448,7 +531,7 @@
 class B {}
 ''');
 
-    var unitResult = (await session.getResolvedUnit(testPath))!;
+    var unitResult = await session.getResolvedUnit(testPath);
     expect(unitResult.session, session);
     expect(unitResult.path, testPath);
     expect(unitResult.uri, Uri.parse('package:test/test.dart'));
@@ -477,7 +560,7 @@
 class B {}
 ''');
 
-    var unitResult = (await session.getUnitElement(testPath))!;
+    var unitResult = await session.getUnitElement(testPath);
     expect(unitResult.session, session);
     expect(unitResult.path, testPath);
     expect(unitResult.uri, Uri.parse('package:test/test.dart'));
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 cb996f9..fc8a498 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
@@ -242,6 +242,22 @@
 ''');
   }
 
+  /// The code `=;` is parsed as `= <emptyString>;`, and there was a bug that
+  /// the absence of the redirecting constructor was encoded as the same
+  /// byte sequence as the empty string. But these are different ASTs,
+  /// so they should have different signatures.
+  test_class_factoryConstructor_addEqNothing() {
+    assertNotSameSignature(r'''
+class A {
+  factory A();
+}
+''', r'''
+class A {
+  factory A() =;
+}
+''');
+  }
+
   /// The token `static` is moving from the field declaration to the factory
   /// constructor (its redirected constructor), so semantically its meaning
   /// changes. But we had a bug that we put `static` into the signature
@@ -261,6 +277,32 @@
 ''');
   }
 
+  test_class_field_const_add_outOfOrder() {
+    assertNotSameSignature(r'''
+class A {
+  static f = Object();
+}
+''', r'''
+class A {
+  const
+  static f = Object();
+}
+''');
+  }
+
+  test_class_field_const_add_outOfOrder_hasFinal() {
+    assertNotSameSignature(r'''
+class A {
+  static final f = Object();
+}
+''', r'''
+class A {
+  const
+  static final f = Object();
+}
+''');
+  }
+
   test_class_field_final_add() {
     assertNotSameSignature(r'''
 class C {
diff --git a/pkg/analyzer/test/src/dart/ast/to_source_visitor_test.dart b/pkg/analyzer/test/src/dart/ast/to_source_visitor_test.dart
index bd36abc..aaf0550 100644
--- a/pkg/analyzer/test/src/dart/ast/to_source_visitor_test.dart
+++ b/pkg/analyzer/test/src/dart/ast/to_source_visitor_test.dart
@@ -1090,6 +1090,24 @@
         ]));
   }
 
+  void test_visitFormalParameterList_namedRequired() {
+    _assertSource(
+        "({required a, required A b})",
+        AstTestFactory.formalParameterList([
+          AstTestFactory.namedFormalParameter(
+              AstTestFactory.simpleFormalParameter3("a")
+                ..requiredKeyword =
+                    TokenFactory.tokenFromKeyword(Keyword.REQUIRED),
+              null),
+          AstTestFactory.namedFormalParameter(
+              AstTestFactory.simpleFormalParameter2(
+                  null, AstTestFactory.typeName4('A'), "b")
+                ..requiredKeyword =
+                    TokenFactory.tokenFromKeyword(Keyword.REQUIRED),
+              null),
+        ]));
+  }
+
   void test_visitFormalParameterList_nn() {
     _assertSource(
         "({a: 0, b: 1})",
diff --git a/pkg/analyzer/test/src/dart/ast/utilities_test.dart b/pkg/analyzer/test/src/dart/ast/utilities_test.dart
index 901b093..9d96e0e 100644
--- a/pkg/analyzer/test/src/dart/ast/utilities_test.dart
+++ b/pkg/analyzer/test/src/dart/ast/utilities_test.dart
@@ -2,26 +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:analyzer/dart/analysis/features.dart';
-import 'package:analyzer/dart/analysis/session.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/dart/element/type.dart';
-import 'package:analyzer/dart/element/type_provider.dart';
-import 'package:analyzer/src/dart/ast/ast.dart';
-import 'package:analyzer/src/dart/ast/ast_factory.dart';
 import 'package:analyzer/src/dart/ast/utilities.dart';
-import 'package:analyzer/src/dart/element/element.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/testing/ast_test_factory.dart';
-import 'package:analyzer/src/generated/testing/element_factory.dart';
-import 'package:analyzer/src/generated/testing/test_type_provider.dart';
-import 'package:analyzer/src/generated/testing/token_factory.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
-import '../../../generated/elements_types_mixin.dart';
 import '../../../generated/parser_test_base.dart' show ParserTestCase;
 import '../../../util/ast_type_matchers.dart';
 
@@ -29,7 +14,6 @@
   defineReflectiveSuite(() {
     defineReflectiveTests(NodeLocatorTest);
     defineReflectiveTests(NodeLocator2Test);
-    defineReflectiveTests(ResolutionCopierTest);
   });
 }
 
@@ -128,938 +112,3 @@
     return node;
   }
 }
-
-@reflectiveTest
-class ResolutionCopierTest with ElementsTypesMixin {
-  @override
-  final TypeProvider typeProvider = TestTypeProvider();
-
-  void test_topLevelVariableDeclaration_external() {
-    var fromNode = AstTestFactory.topLevelVariableDeclaration2(
-        Keyword.VAR, [AstTestFactory.variableDeclaration('x')],
-        isExternal: false);
-    TopLevelVariableElement element = TopLevelVariableElementImpl('x', -1);
-    (fromNode.variables.variables[0] as VariableDeclarationImpl)
-        .name
-        .staticElement = element;
-    TopLevelVariableDeclaration toNode1 =
-        AstTestFactory.topLevelVariableDeclaration2(
-            Keyword.VAR, [AstTestFactory.variableDeclaration('x')],
-            isExternal: false);
-    ResolutionCopier.copyResolutionData(fromNode, toNode1);
-    // Nodes matched so resolution data should have been copied.
-    expect(toNode1.variables.variables[0].declaredElement, same(element));
-    TopLevelVariableDeclaration toNode2 =
-        AstTestFactory.topLevelVariableDeclaration2(
-            Keyword.VAR, [AstTestFactory.variableDeclaration('x')],
-            isExternal: true);
-    ResolutionCopier.copyResolutionData(fromNode, toNode1);
-    // Nodes didn't match so resolution data should not have been copied.
-    expect(toNode2.variables.variables[0].declaredElement, isNull);
-  }
-
-  void test_visitAdjacentStrings() {
-    AdjacentStringsImpl createNode() => astFactory.adjacentStrings([
-          astFactory.simpleStringLiteral(
-            TokenFactory.tokenFromString('hello'),
-            'hello',
-          ),
-          astFactory.simpleStringLiteral(
-            TokenFactory.tokenFromString('world'),
-            'world',
-          )
-        ]);
-
-    var fromNode = createNode();
-    DartType staticType = interfaceTypeStar(ElementFactory.classElement2('B'));
-    fromNode.staticType = staticType;
-
-    AdjacentStrings toNode = createNode();
-    ResolutionCopier.copyResolutionData(fromNode, toNode);
-    expect(toNode.staticType, same(staticType));
-  }
-
-  void test_visitAnnotation() {
-    String annotationName = "proxy";
-    var fromNode =
-        AstTestFactory.annotation(AstTestFactory.identifier3(annotationName));
-    Element element = ElementFactory.topLevelVariableElement2(annotationName);
-    fromNode.element = element;
-    Annotation toNode =
-        AstTestFactory.annotation(AstTestFactory.identifier3(annotationName));
-    ResolutionCopier.copyResolutionData(fromNode, toNode);
-    expect(toNode.element, same(element));
-  }
-
-  void test_visitAnnotation_generic() {
-    var annotationClassName = "A";
-    var annotationConstructorName = "named";
-    var argumentName = "x";
-    var fromNode = AstTestFactory.annotation2(
-        AstTestFactory.identifier3(annotationClassName),
-        AstTestFactory.identifier3(annotationConstructorName),
-        AstTestFactory.argumentList(
-            [AstTestFactory.identifier3(argumentName)]));
-    var elementA = ElementFactory.classElement2(annotationClassName, ['T']);
-    var element = ElementFactory.constructorElement(
-        elementA, annotationConstructorName, true, [typeProvider.dynamicType]);
-    fromNode.element = element;
-    var typeArgumentName = 'U';
-    var elementU = ElementFactory.classElement2(typeArgumentName);
-    fromNode.typeArguments =
-        AstTestFactory.typeArgumentList2([AstTestFactory.typeName(elementU)]);
-    var toNode = AstTestFactory.annotation2(
-        AstTestFactory.identifier3(annotationClassName),
-        AstTestFactory.identifier3(annotationConstructorName),
-        AstTestFactory.argumentList(
-            [AstTestFactory.identifier3(argumentName)]));
-    toNode.typeArguments = AstTestFactory.typeArgumentList2(
-        [AstTestFactory.typeName4(typeArgumentName)]);
-    ResolutionCopier.copyResolutionData(fromNode, toNode);
-    expect(toNode.element, same(element));
-    expect(
-        (toNode.typeArguments!.arguments.single as TypeName).name.staticElement,
-        same(elementU));
-  }
-
-  void test_visitAsExpression() {
-    var fromNode = AstTestFactory.asExpression(
-        AstTestFactory.identifier3("x"), AstTestFactory.typeName4("A"));
-    DartType staticType = interfaceTypeStar(ElementFactory.classElement2('B'));
-    fromNode.staticType = staticType;
-    AsExpression toNode = AstTestFactory.asExpression(
-        AstTestFactory.identifier3("x"), AstTestFactory.typeName4("A"));
-    ResolutionCopier.copyResolutionData(fromNode, toNode);
-    expect(toNode.staticType, same(staticType));
-  }
-
-  void test_visitAssignmentExpression() {
-    var fromNode = AstTestFactory.assignmentExpression(
-        AstTestFactory.identifier3("a"),
-        TokenType.PLUS_EQ,
-        AstTestFactory.identifier3("b"));
-    DartType staticType = interfaceTypeStar(ElementFactory.classElement2('C'));
-    MethodElement staticElement = ElementFactory.methodElement("+", staticType);
-    fromNode.staticElement = staticElement;
-    fromNode.staticType = staticType;
-    AssignmentExpression toNode = AstTestFactory.assignmentExpression(
-        AstTestFactory.identifier3("a"),
-        TokenType.PLUS_EQ,
-        AstTestFactory.identifier3("b"));
-    ResolutionCopier.copyResolutionData(fromNode, toNode);
-    expect(toNode.staticElement, same(staticElement));
-    expect(toNode.staticType, same(staticType));
-  }
-
-  void test_visitBinaryExpression() {
-    var fromNode = AstTestFactory.binaryExpression(
-        AstTestFactory.identifier3("a"),
-        TokenType.PLUS,
-        AstTestFactory.identifier3("b"));
-    DartType staticType = interfaceTypeStar(ElementFactory.classElement2('C'));
-    MethodElement staticElement = ElementFactory.methodElement("+", staticType);
-    fromNode.staticElement = staticElement;
-    fromNode.staticType = staticType;
-    BinaryExpression toNode = AstTestFactory.binaryExpression(
-        AstTestFactory.identifier3("a"),
-        TokenType.PLUS,
-        AstTestFactory.identifier3("b"));
-    ResolutionCopier.copyResolutionData(fromNode, toNode);
-    expect(toNode.staticElement, same(staticElement));
-    expect(toNode.staticType, same(staticType));
-  }
-
-  void test_visitBooleanLiteral() {
-    var fromNode = AstTestFactory.booleanLiteral(true);
-    DartType staticType = interfaceTypeStar(ElementFactory.classElement2('C'));
-    fromNode.staticType = staticType;
-    BooleanLiteral toNode = AstTestFactory.booleanLiteral(true);
-    ResolutionCopier.copyResolutionData(fromNode, toNode);
-    expect(toNode.staticType, same(staticType));
-  }
-
-  void test_visitCascadeExpression() {
-    var fromNode = AstTestFactory.cascadeExpression(
-        AstTestFactory.identifier3("a"), [AstTestFactory.identifier3("b")]);
-    DartType staticType = interfaceTypeStar(ElementFactory.classElement2('C'));
-    fromNode.staticType = staticType;
-    CascadeExpression toNode = AstTestFactory.cascadeExpression(
-        AstTestFactory.identifier3("a"), [AstTestFactory.identifier3("b")]);
-    ResolutionCopier.copyResolutionData(fromNode, toNode);
-    expect(toNode.staticType, same(staticType));
-  }
-
-  void test_visitCompilationUnit() {
-    var fromNode = AstTestFactory.compilationUnit();
-    CompilationUnitElement element = CompilationUnitElementImpl();
-    fromNode.element = element;
-    CompilationUnit toNode = AstTestFactory.compilationUnit();
-    ResolutionCopier.copyResolutionData(fromNode, toNode);
-    expect(toNode.declaredElement, same(element));
-  }
-
-  void test_visitConditionalExpression() {
-    var fromNode = AstTestFactory.conditionalExpression(
-        AstTestFactory.identifier3("c"),
-        AstTestFactory.identifier3("a"),
-        AstTestFactory.identifier3("b"));
-    DartType staticType = interfaceTypeStar(ElementFactory.classElement2('C'));
-    fromNode.staticType = staticType;
-    ConditionalExpression toNode = AstTestFactory.conditionalExpression(
-        AstTestFactory.identifier3("c"),
-        AstTestFactory.identifier3("a"),
-        AstTestFactory.identifier3("b"));
-    ResolutionCopier.copyResolutionData(fromNode, toNode);
-    expect(toNode.staticType, same(staticType));
-  }
-
-  void test_visitConstructorDeclaration() {
-    String className = "A";
-    String constructorName = "c";
-    var fromNode = AstTestFactory.constructorDeclaration(
-        AstTestFactory.identifier3(className),
-        constructorName,
-        AstTestFactory.formalParameterList(), []);
-    ConstructorElement element = ElementFactory.constructorElement2(
-        ElementFactory.classElement2(className), constructorName);
-    fromNode.declaredElement = element;
-    ConstructorDeclaration toNode = AstTestFactory.constructorDeclaration(
-        AstTestFactory.identifier3(className),
-        constructorName,
-        AstTestFactory.formalParameterList(), []);
-    ResolutionCopier.copyResolutionData(fromNode, toNode);
-    expect(toNode.declaredElement, same(element));
-  }
-
-  void test_visitConstructorName() {
-    var fromNode =
-        AstTestFactory.constructorName(AstTestFactory.typeName4("A"), "c");
-    ConstructorElement staticElement = ElementFactory.constructorElement2(
-        ElementFactory.classElement2("A"), "c");
-    fromNode.staticElement = staticElement;
-    ConstructorName toNode =
-        AstTestFactory.constructorName(AstTestFactory.typeName4("A"), "c");
-    ResolutionCopier.copyResolutionData(fromNode, toNode);
-    expect(toNode.staticElement, same(staticElement));
-  }
-
-  void test_visitDoubleLiteral() {
-    var fromNode = AstTestFactory.doubleLiteral(1.0);
-    DartType staticType = interfaceTypeStar(ElementFactory.classElement2('C'));
-    fromNode.staticType = staticType;
-    DoubleLiteral toNode = AstTestFactory.doubleLiteral(1.0);
-    ResolutionCopier.copyResolutionData(fromNode, toNode);
-    expect(toNode.staticType, same(staticType));
-  }
-
-  void test_visitExportDirective() {
-    var fromNode = AstTestFactory.exportDirective2("dart:uri");
-    ExportElement element = ExportElementImpl(-1);
-    fromNode.element = element;
-    ExportDirective toNode = AstTestFactory.exportDirective2("dart:uri");
-    ResolutionCopier.copyResolutionData(fromNode, toNode);
-    expect(toNode.element, same(element));
-  }
-
-  void test_visitFieldDeclaration_abstract() {
-    FieldDeclaration fromNode = AstTestFactory.fieldDeclaration(
-        false, Keyword.VAR, null, [AstTestFactory.variableDeclaration('x')],
-        isAbstract: false);
-    FieldElement element = FieldElementImpl('x', -1);
-    (fromNode.fields.variables[0] as VariableDeclarationImpl)
-        .name
-        .staticElement = element;
-    FieldDeclaration toNode1 = AstTestFactory.fieldDeclaration(
-        false, Keyword.VAR, null, [AstTestFactory.variableDeclaration('x')],
-        isAbstract: false);
-    ResolutionCopier.copyResolutionData(fromNode, toNode1);
-    // Nodes matched so resolution data should have been copied.
-    expect(toNode1.fields.variables[0].declaredElement, same(element));
-    FieldDeclaration toNode2 = AstTestFactory.fieldDeclaration(
-        false, Keyword.VAR, null, [AstTestFactory.variableDeclaration('x')],
-        isAbstract: true);
-    ResolutionCopier.copyResolutionData(fromNode, toNode1);
-    // Nodes didn't match so resolution data should not have been copied.
-    expect(toNode2.fields.variables[0].declaredElement, isNull);
-  }
-
-  void test_visitFieldDeclaration_external() {
-    FieldDeclaration fromNode = AstTestFactory.fieldDeclaration(
-        false, Keyword.VAR, null, [AstTestFactory.variableDeclaration('x')],
-        isExternal: false);
-    FieldElement element = FieldElementImpl('x', -1);
-    (fromNode.fields.variables[0] as VariableDeclarationImpl)
-        .name
-        .staticElement = element;
-    FieldDeclaration toNode1 = AstTestFactory.fieldDeclaration(
-        false, Keyword.VAR, null, [AstTestFactory.variableDeclaration('x')],
-        isExternal: false);
-    ResolutionCopier.copyResolutionData(fromNode, toNode1);
-    // Nodes matched so resolution data should have been copied.
-    expect(toNode1.fields.variables[0].declaredElement, same(element));
-    FieldDeclaration toNode2 = AstTestFactory.fieldDeclaration(
-        false, Keyword.VAR, null, [AstTestFactory.variableDeclaration('x')],
-        isExternal: true);
-    ResolutionCopier.copyResolutionData(fromNode, toNode1);
-    // Nodes didn't match so resolution data should not have been copied.
-    expect(toNode2.fields.variables[0].declaredElement, isNull);
-  }
-
-  void test_visitForEachPartsWithDeclaration() {
-    ForEachPartsWithDeclaration createNode() =>
-        astFactory.forEachPartsWithDeclaration(
-            loopVariable: AstTestFactory.declaredIdentifier3('a'),
-            inKeyword: TokenFactory.tokenFromKeyword(Keyword.IN),
-            iterable: AstTestFactory.identifier3('b'));
-
-    DartType typeB = interfaceTypeStar(ElementFactory.classElement2('B'));
-
-    ForEachPartsWithDeclaration fromNode = createNode();
-    (fromNode.iterable as SimpleIdentifierImpl).staticType = typeB;
-
-    ForEachPartsWithDeclaration toNode = createNode();
-    ResolutionCopier.copyResolutionData(fromNode, toNode);
-    expect((toNode.iterable as SimpleIdentifier).staticType, same(typeB));
-  }
-
-  void test_visitForEachPartsWithIdentifier() {
-    ForEachPartsWithIdentifierImpl createNode() =>
-        astFactory.forEachPartsWithIdentifier(
-            identifier: AstTestFactory.identifier3('a'),
-            inKeyword: TokenFactory.tokenFromKeyword(Keyword.IN),
-            iterable: AstTestFactory.identifier3('b'));
-
-    DartType typeA = interfaceTypeStar(ElementFactory.classElement2('A'));
-    DartType typeB = interfaceTypeStar(ElementFactory.classElement2('B'));
-
-    var fromNode = createNode();
-    fromNode.identifier.staticType = typeA;
-    (fromNode.iterable as SimpleIdentifierImpl).staticType = typeB;
-
-    ForEachPartsWithIdentifier toNode = createNode();
-    ResolutionCopier.copyResolutionData(fromNode, toNode);
-    expect(toNode.identifier.staticType, same(typeA));
-    expect((toNode.iterable as SimpleIdentifier).staticType, same(typeB));
-  }
-
-  void test_visitForElement() {
-    ForElementImpl createNode() => astFactory.forElement(
-        forKeyword: TokenFactory.tokenFromKeyword(Keyword.FOR),
-        leftParenthesis: TokenFactory.tokenFromType(TokenType.OPEN_PAREN),
-        forLoopParts: astFactory.forEachPartsWithIdentifier(
-            identifier: AstTestFactory.identifier3('a'),
-            inKeyword: TokenFactory.tokenFromKeyword(Keyword.IN),
-            iterable: AstTestFactory.identifier3('b')),
-        rightParenthesis: TokenFactory.tokenFromType(TokenType.CLOSE_PAREN),
-        body: AstTestFactory.identifier3('c'));
-
-    DartType typeC = interfaceTypeStar(ElementFactory.classElement2('C'));
-
-    ForElement fromNode = createNode();
-    (fromNode.body as SimpleIdentifierImpl).staticType = typeC;
-
-    ForElement toNode = createNode();
-    ResolutionCopier.copyResolutionData(fromNode, toNode);
-    expect((toNode.body as SimpleIdentifier).staticType, same(typeC));
-  }
-
-  void test_visitForPartsWithDeclarations() {
-    ForPartsWithDeclarations createNode() =>
-        astFactory.forPartsWithDeclarations(
-            variables: AstTestFactory.variableDeclarationList2(
-                Keyword.VAR, [AstTestFactory.variableDeclaration('a')]),
-            leftSeparator: TokenFactory.tokenFromType(TokenType.SEMICOLON),
-            condition: AstTestFactory.identifier3('b'),
-            rightSeparator: TokenFactory.tokenFromType(TokenType.SEMICOLON),
-            updaters: [AstTestFactory.identifier3('c')]);
-
-    DartType typeB = interfaceTypeStar(ElementFactory.classElement2('B'));
-    DartType typeC = interfaceTypeStar(ElementFactory.classElement2('C'));
-
-    ForPartsWithDeclarations fromNode = createNode();
-    (fromNode.condition as SimpleIdentifierImpl).staticType = typeB;
-    (fromNode.updaters[0] as SimpleIdentifierImpl).staticType = typeC;
-
-    ForPartsWithDeclarations toNode = createNode();
-    ResolutionCopier.copyResolutionData(fromNode, toNode);
-    expect((toNode.condition as SimpleIdentifier).staticType, same(typeB));
-    expect((toNode.updaters[0] as SimpleIdentifier).staticType, same(typeC));
-  }
-
-  void test_visitForPartsWithExpression() {
-    ForPartsWithExpression createNode() => astFactory.forPartsWithExpression(
-        initialization: AstTestFactory.identifier3('a'),
-        leftSeparator: TokenFactory.tokenFromType(TokenType.SEMICOLON),
-        condition: AstTestFactory.identifier3('b'),
-        rightSeparator: TokenFactory.tokenFromType(TokenType.SEMICOLON),
-        updaters: [AstTestFactory.identifier3('c')]);
-
-    DartType typeA = interfaceTypeStar(ElementFactory.classElement2('A'));
-    DartType typeB = interfaceTypeStar(ElementFactory.classElement2('B'));
-    DartType typeC = interfaceTypeStar(ElementFactory.classElement2('C'));
-
-    ForPartsWithExpression fromNode = createNode();
-    (fromNode.initialization as SimpleIdentifierImpl).staticType = typeA;
-    (fromNode.condition as SimpleIdentifierImpl).staticType = typeB;
-    (fromNode.updaters[0] as SimpleIdentifierImpl).staticType = typeC;
-
-    ForPartsWithExpression toNode = createNode();
-    ResolutionCopier.copyResolutionData(fromNode, toNode);
-    expect((toNode.initialization as SimpleIdentifier).staticType, same(typeA));
-    expect((toNode.condition as SimpleIdentifier).staticType, same(typeB));
-    expect((toNode.updaters[0] as SimpleIdentifier).staticType, same(typeC));
-  }
-
-  void test_visitForStatement() {
-    ForStatement createNode() => astFactory.forStatement(
-        forKeyword: TokenFactory.tokenFromKeyword(Keyword.FOR),
-        leftParenthesis: TokenFactory.tokenFromType(TokenType.OPEN_PAREN),
-        forLoopParts: astFactory.forEachPartsWithIdentifier(
-            identifier: AstTestFactory.identifier3('a'),
-            inKeyword: TokenFactory.tokenFromKeyword(Keyword.IN),
-            iterable: AstTestFactory.identifier3('b')),
-        rightParenthesis: TokenFactory.tokenFromType(TokenType.CLOSE_PAREN),
-        body: AstTestFactory.expressionStatement(
-            AstTestFactory.identifier3('c')));
-
-    DartType typeA = interfaceTypeStar(ElementFactory.classElement2('A'));
-    DartType typeB = interfaceTypeStar(ElementFactory.classElement2('B'));
-    DartType typeC = interfaceTypeStar(ElementFactory.classElement2('C'));
-
-    ForStatement fromNode = createNode();
-    var fromForLoopParts =
-        fromNode.forLoopParts as ForEachPartsWithIdentifierImpl;
-    fromForLoopParts.identifier.staticType = typeA;
-    fromForLoopParts.iterable.staticType = typeB;
-    (fromNode.body as ExpressionStatementImpl).expression.staticType = typeC;
-
-    ForStatement toNode = createNode();
-    ResolutionCopier.copyResolutionData(fromNode, toNode);
-    var toForLoopParts = fromNode.forLoopParts as ForEachPartsWithIdentifier;
-    expect(toForLoopParts.identifier.staticType, same(typeA));
-    expect(
-        (toForLoopParts.iterable as SimpleIdentifier).staticType, same(typeB));
-    expect(
-        ((toNode.body as ExpressionStatement).expression as SimpleIdentifier)
-            .staticType,
-        same(typeC));
-  }
-
-  void test_visitFunctionExpression() {
-    var fromNode = AstTestFactory.functionExpression2(
-        AstTestFactory.formalParameterList(),
-        AstTestFactory.emptyFunctionBody());
-    MethodElement element = ElementFactory.methodElement(
-        "m", interfaceTypeStar(ElementFactory.classElement2('C')));
-    fromNode.declaredElement = element;
-    DartType staticType = interfaceTypeStar(ElementFactory.classElement2('C'));
-    fromNode.staticType = staticType;
-    FunctionExpression toNode = AstTestFactory.functionExpression2(
-        AstTestFactory.formalParameterList(),
-        AstTestFactory.emptyFunctionBody());
-    ResolutionCopier.copyResolutionData(fromNode, toNode);
-    expect(toNode.declaredElement, same(element));
-    expect(toNode.staticType, same(staticType));
-  }
-
-  void test_visitFunctionExpressionInvocation() {
-    var fromNode = AstTestFactory.functionExpressionInvocation(
-        AstTestFactory.identifier3("f"));
-    MethodElement staticElement = ElementFactory.methodElement(
-        "m", interfaceTypeStar(ElementFactory.classElement2('C')));
-    fromNode.staticElement = staticElement;
-    var toNode = AstTestFactory.functionExpressionInvocation(
-        AstTestFactory.identifier3("f"));
-    ClassElement elementT = ElementFactory.classElement2('T');
-    fromNode.typeArguments = AstTestFactory.typeArgumentList(
-        <TypeAnnotation>[AstTestFactory.typeName(elementT)]);
-    toNode.typeArguments = AstTestFactory.typeArgumentList(
-        <TypeAnnotation>[AstTestFactory.typeName4('T')]);
-
-    _copyAndVerifyInvocation(fromNode, toNode);
-
-    expect(toNode.staticElement, same(staticElement));
-  }
-
-  void test_visitIfElement() {
-    IfElementImpl createNode() => astFactory.ifElement(
-        ifKeyword: TokenFactory.tokenFromKeyword(Keyword.IF),
-        leftParenthesis: TokenFactory.tokenFromType(TokenType.OPEN_PAREN),
-        condition: AstTestFactory.identifier3('a'),
-        rightParenthesis: TokenFactory.tokenFromType(TokenType.CLOSE_PAREN),
-        thenElement: AstTestFactory.identifier3('b'),
-        elseElement: AstTestFactory.identifier3('c'));
-
-    DartType typeA = interfaceTypeStar(ElementFactory.classElement2('A'));
-    DartType typeB = interfaceTypeStar(ElementFactory.classElement2('B'));
-    DartType typeC = interfaceTypeStar(ElementFactory.classElement2('C'));
-
-    var fromNode = createNode();
-    (fromNode.condition as SimpleIdentifierImpl).staticType = typeA;
-    (fromNode.thenElement as SimpleIdentifierImpl).staticType = typeB;
-    (fromNode.elseElement as SimpleIdentifierImpl).staticType = typeC;
-
-    IfElement toNode = createNode();
-    ResolutionCopier.copyResolutionData(fromNode, toNode);
-    expect(toNode.condition.staticType, same(typeA));
-    expect((toNode.thenElement as SimpleIdentifier).staticType, same(typeB));
-    expect((toNode.elseElement as SimpleIdentifier).staticType, same(typeC));
-  }
-
-  void test_visitImportDirective() {
-    var fromNode = AstTestFactory.importDirective3("dart:uri", null);
-    ImportElement element = ImportElementImpl(0);
-    fromNode.element = element;
-    ImportDirective toNode = AstTestFactory.importDirective3("dart:uri", null);
-    ResolutionCopier.copyResolutionData(fromNode, toNode);
-    expect(toNode.element, same(element));
-  }
-
-  void test_visitIndexExpression() {
-    var fromNode = AstTestFactory.indexExpression(
-      target: AstTestFactory.identifier3("a"),
-      index: AstTestFactory.integer(0),
-    );
-    MethodElement staticElement = ElementFactory.methodElement(
-        "m", interfaceTypeStar(ElementFactory.classElement2('C')));
-    fromNode.staticElement = staticElement;
-    DartType staticType = interfaceTypeStar(ElementFactory.classElement2('C'));
-    fromNode.staticType = staticType;
-    IndexExpression toNode = AstTestFactory.indexExpression(
-      target: AstTestFactory.identifier3("a"),
-      index: AstTestFactory.integer(0),
-    );
-    ResolutionCopier.copyResolutionData(fromNode, toNode);
-    expect(toNode.staticElement, same(staticElement));
-    expect(toNode.staticType, same(staticType));
-  }
-
-  void test_visitInstanceCreationExpression() {
-    var fromNode = AstTestFactory.instanceCreationExpression2(
-        Keyword.NEW, AstTestFactory.typeName4("C"));
-    ConstructorElement staticElement = ElementFactory.constructorElement2(
-        ElementFactory.classElement2("C"), null);
-    fromNode.constructorName.staticElement = staticElement;
-    DartType staticType = interfaceTypeStar(ElementFactory.classElement2('C'));
-    fromNode.staticType = staticType;
-    InstanceCreationExpression toNode =
-        AstTestFactory.instanceCreationExpression2(
-            Keyword.NEW, AstTestFactory.typeName4("C"));
-    ResolutionCopier.copyResolutionData(fromNode, toNode);
-    expect(toNode.constructorName.staticElement, same(staticElement));
-    expect(toNode.staticType, same(staticType));
-  }
-
-  void test_visitIntegerLiteral() {
-    var fromNode = AstTestFactory.integer(2);
-    DartType staticType = interfaceTypeStar(ElementFactory.classElement2('C'));
-    fromNode.staticType = staticType;
-    IntegerLiteral toNode = AstTestFactory.integer(2);
-    ResolutionCopier.copyResolutionData(fromNode, toNode);
-    expect(toNode.staticType, same(staticType));
-  }
-
-  void test_visitIsExpression() {
-    var fromNode = AstTestFactory.isExpression(
-        AstTestFactory.identifier3("x"), false, AstTestFactory.typeName4("A"));
-    DartType staticType = interfaceTypeStar(ElementFactory.classElement2('C'));
-    fromNode.staticType = staticType;
-    IsExpression toNode = AstTestFactory.isExpression(
-        AstTestFactory.identifier3("x"), false, AstTestFactory.typeName4("A"));
-    ResolutionCopier.copyResolutionData(fromNode, toNode);
-    expect(toNode.staticType, same(staticType));
-  }
-
-  void test_visitLibraryIdentifier() {
-    var fromNode =
-        AstTestFactory.libraryIdentifier([AstTestFactory.identifier3("lib")]);
-    DartType staticType = interfaceTypeStar(ElementFactory.classElement2('C'));
-    fromNode.staticType = staticType;
-    LibraryIdentifier toNode =
-        AstTestFactory.libraryIdentifier([AstTestFactory.identifier3("lib")]);
-    ResolutionCopier.copyResolutionData(fromNode, toNode);
-    expect(toNode.staticType, same(staticType));
-  }
-
-  void test_visitListLiteral() {
-    ListLiteralImpl createNode() => astFactory.listLiteral(
-          null,
-          AstTestFactory.typeArgumentList([AstTestFactory.typeName4('A')]),
-          TokenFactory.tokenFromType(TokenType.OPEN_SQUARE_BRACKET),
-          [AstTestFactory.identifier3('b')],
-          TokenFactory.tokenFromType(TokenType.CLOSE_SQUARE_BRACKET),
-        );
-
-    DartType typeA = interfaceTypeStar(ElementFactory.classElement2('A'));
-    DartType typeB = interfaceTypeStar(ElementFactory.classElement2('B'));
-    DartType typeC = interfaceTypeStar(ElementFactory.classElement2('C'));
-
-    var fromNode = createNode();
-    (fromNode.typeArguments!.arguments[0] as TypeNameImpl).type = typeA;
-    (fromNode.elements[0] as SimpleIdentifierImpl).staticType = typeB;
-    fromNode.staticType = typeC;
-
-    ListLiteral toNode = createNode();
-    ResolutionCopier.copyResolutionData(fromNode, toNode);
-    expect((toNode.typeArguments!.arguments[0] as TypeName).type, same(typeA));
-    expect((toNode.elements[0] as SimpleIdentifier).staticType, same(typeB));
-    expect(fromNode.staticType, same(typeC));
-  }
-
-  void test_visitMapLiteral() {
-    var fromNode = AstTestFactory.setOrMapLiteral(null, null);
-    DartType staticType = interfaceTypeStar(ElementFactory.classElement2('C'));
-    fromNode.staticType = staticType;
-    SetOrMapLiteral toNode = AstTestFactory.setOrMapLiteral(null, null);
-    ResolutionCopier.copyResolutionData(fromNode, toNode);
-    expect(toNode.staticType, same(staticType));
-  }
-
-  void test_visitMethodInvocation() {
-    var fromNode = AstTestFactory.methodInvocation2("m");
-    var toNode = AstTestFactory.methodInvocation2("m");
-    ClassElement elementT = ElementFactory.classElement2('T');
-    fromNode.typeArguments = AstTestFactory.typeArgumentList(
-        <TypeAnnotation>[AstTestFactory.typeName(elementT)]);
-    toNode.typeArguments = AstTestFactory.typeArgumentList(
-        <TypeAnnotation>[AstTestFactory.typeName4('T')]);
-    _copyAndVerifyInvocation(fromNode, toNode);
-  }
-
-  void test_visitNamedExpression() {
-    var fromNode =
-        AstTestFactory.namedExpression2("n", AstTestFactory.integer(0));
-    DartType staticType = interfaceTypeStar(ElementFactory.classElement2('C'));
-    fromNode.staticType = staticType;
-    NamedExpression toNode =
-        AstTestFactory.namedExpression2("n", AstTestFactory.integer(0));
-    ResolutionCopier.copyResolutionData(fromNode, toNode);
-    expect(toNode.staticType, same(staticType));
-  }
-
-  void test_visitNullLiteral() {
-    var fromNode = AstTestFactory.nullLiteral();
-    DartType staticType = interfaceTypeStar(ElementFactory.classElement2('C'));
-    fromNode.staticType = staticType;
-    NullLiteral toNode = AstTestFactory.nullLiteral();
-    ResolutionCopier.copyResolutionData(fromNode, toNode);
-    expect(toNode.staticType, same(staticType));
-  }
-
-  void test_visitParenthesizedExpression() {
-    var fromNode =
-        AstTestFactory.parenthesizedExpression(AstTestFactory.integer(0));
-    DartType staticType = interfaceTypeStar(ElementFactory.classElement2('C'));
-    fromNode.staticType = staticType;
-    ParenthesizedExpression toNode =
-        AstTestFactory.parenthesizedExpression(AstTestFactory.integer(0));
-    ResolutionCopier.copyResolutionData(fromNode, toNode);
-    expect(toNode.staticType, same(staticType));
-  }
-
-  void test_visitPartDirective() {
-    var fromNode = AstTestFactory.partDirective2("part.dart");
-    LibraryElement element = LibraryElementImpl(
-        _AnalysisContextMock(),
-        _AnalysisSessionMock(),
-        'lib',
-        -1,
-        0,
-        FeatureSet.latestLanguageVersion());
-    fromNode.element = element;
-    PartDirective toNode = AstTestFactory.partDirective2("part.dart");
-    ResolutionCopier.copyResolutionData(fromNode, toNode);
-    expect(toNode.element, same(element));
-  }
-
-  void test_visitPartOfDirective() {
-    var fromNode = AstTestFactory.partOfDirective(
-        AstTestFactory.libraryIdentifier2(["lib"]));
-    LibraryElement element = LibraryElementImpl(
-        _AnalysisContextMock(),
-        _AnalysisSessionMock(),
-        'lib',
-        -1,
-        0,
-        FeatureSet.latestLanguageVersion());
-    fromNode.element = element;
-    PartOfDirective toNode = AstTestFactory.partOfDirective(
-        AstTestFactory.libraryIdentifier2(["lib"]));
-    ResolutionCopier.copyResolutionData(fromNode, toNode);
-    expect(toNode.element, same(element));
-  }
-
-  void test_visitPostfixExpression() {
-    String variableName = "x";
-    var fromNode = AstTestFactory.postfixExpression(
-        AstTestFactory.identifier3(variableName), TokenType.PLUS_PLUS);
-    MethodElement staticElement = ElementFactory.methodElement(
-        "+", interfaceTypeStar(ElementFactory.classElement2('C')));
-    fromNode.staticElement = staticElement;
-    DartType staticType = interfaceTypeStar(ElementFactory.classElement2('C'));
-    fromNode.staticType = staticType;
-    PostfixExpression toNode = AstTestFactory.postfixExpression(
-        AstTestFactory.identifier3(variableName), TokenType.PLUS_PLUS);
-    ResolutionCopier.copyResolutionData(fromNode, toNode);
-    expect(toNode.staticElement, same(staticElement));
-    expect(toNode.staticType, same(staticType));
-  }
-
-  void test_visitPrefixedIdentifier() {
-    var fromNode = AstTestFactory.identifier5("p", "f");
-    DartType staticType = interfaceTypeStar(ElementFactory.classElement2('C'));
-    fromNode.staticType = staticType;
-    PrefixedIdentifier toNode = AstTestFactory.identifier5("p", "f");
-    ResolutionCopier.copyResolutionData(fromNode, toNode);
-    expect(toNode.staticType, same(staticType));
-  }
-
-  void test_visitPrefixExpression() {
-    var fromNode = AstTestFactory.prefixExpression(
-        TokenType.PLUS_PLUS, AstTestFactory.identifier3("x"));
-    DartType staticType = interfaceTypeStar(ElementFactory.classElement2('C'));
-    MethodElement staticElement = ElementFactory.methodElement(
-        "+", interfaceTypeStar(ElementFactory.classElement2('C')));
-    fromNode.staticElement = staticElement;
-    fromNode.staticType = staticType;
-    PrefixExpression toNode = AstTestFactory.prefixExpression(
-        TokenType.PLUS_PLUS, AstTestFactory.identifier3("x"));
-    ResolutionCopier.copyResolutionData(fromNode, toNode);
-    expect(toNode.staticElement, same(staticElement));
-    expect(toNode.staticType, same(staticType));
-  }
-
-  void test_visitPropertyAccess() {
-    var fromNode =
-        AstTestFactory.propertyAccess2(AstTestFactory.identifier3("x"), "y");
-    DartType staticType = interfaceTypeStar(ElementFactory.classElement2('C'));
-    fromNode.staticType = staticType;
-    PropertyAccess toNode =
-        AstTestFactory.propertyAccess2(AstTestFactory.identifier3("x"), "y");
-    ResolutionCopier.copyResolutionData(fromNode, toNode);
-    expect(toNode.staticType, same(staticType));
-  }
-
-  void test_visitRedirectingConstructorInvocation() {
-    var fromNode = AstTestFactory.redirectingConstructorInvocation();
-    ConstructorElement staticElement = ElementFactory.constructorElement2(
-        ElementFactory.classElement2("C"), null);
-    fromNode.staticElement = staticElement;
-    RedirectingConstructorInvocation toNode =
-        AstTestFactory.redirectingConstructorInvocation();
-    ResolutionCopier.copyResolutionData(fromNode, toNode);
-    expect(toNode.staticElement, same(staticElement));
-  }
-
-  void test_visitRethrowExpression() {
-    var fromNode = AstTestFactory.rethrowExpression();
-    DartType staticType = interfaceTypeStar(ElementFactory.classElement2('C'));
-    fromNode.staticType = staticType;
-    RethrowExpression toNode = AstTestFactory.rethrowExpression();
-    ResolutionCopier.copyResolutionData(fromNode, toNode);
-    expect(toNode.staticType, same(staticType));
-  }
-
-  void test_visitSetOrMapLiteral_map() {
-    SetOrMapLiteralImpl createNode() => astFactory.setOrMapLiteral(
-          typeArguments: AstTestFactory.typeArgumentList(
-              [AstTestFactory.typeName4('A'), AstTestFactory.typeName4('B')]),
-          leftBracket: TokenFactory.tokenFromType(TokenType.OPEN_CURLY_BRACKET),
-          elements: [AstTestFactory.mapLiteralEntry3('c', 'd')],
-          rightBracket:
-              TokenFactory.tokenFromType(TokenType.CLOSE_CURLY_BRACKET),
-        );
-
-    DartType typeA = interfaceTypeStar(ElementFactory.classElement2('A'));
-    DartType typeB = interfaceTypeStar(ElementFactory.classElement2('B'));
-    DartType typeC = interfaceTypeStar(ElementFactory.classElement2('C'));
-    DartType typeD = interfaceTypeStar(ElementFactory.classElement2('D'));
-
-    SetOrMapLiteral fromNode = createNode();
-    (fromNode.typeArguments!.arguments[0] as TypeNameImpl).type = typeA;
-    (fromNode.typeArguments!.arguments[1] as TypeNameImpl).type = typeB;
-    MapLiteralEntry fromEntry = fromNode.elements[0] as MapLiteralEntry;
-    (fromEntry.key as SimpleStringLiteralImpl).staticType = typeC;
-    (fromEntry.value as SimpleStringLiteralImpl).staticType = typeD;
-
-    SetOrMapLiteral toNode = createNode();
-    ResolutionCopier.copyResolutionData(fromNode, toNode);
-    expect((toNode.typeArguments!.arguments[0] as TypeName).type, same(typeA));
-    expect((toNode.typeArguments!.arguments[1] as TypeName).type, same(typeB));
-    MapLiteralEntry toEntry = fromNode.elements[0] as MapLiteralEntry;
-    expect((toEntry.key as SimpleStringLiteral).staticType, same(typeC));
-    expect((toEntry.value as SimpleStringLiteral).staticType, same(typeD));
-  }
-
-  void test_visitSetOrMapLiteral_set() {
-    SetOrMapLiteralImpl createNode() => astFactory.setOrMapLiteral(
-          typeArguments:
-              AstTestFactory.typeArgumentList([AstTestFactory.typeName4('A')]),
-          leftBracket: TokenFactory.tokenFromType(TokenType.OPEN_CURLY_BRACKET),
-          elements: [AstTestFactory.identifier3('b')],
-          rightBracket:
-              TokenFactory.tokenFromType(TokenType.CLOSE_CURLY_BRACKET),
-        );
-
-    DartType typeA = interfaceTypeStar(ElementFactory.classElement2('A'));
-    DartType typeB = interfaceTypeStar(ElementFactory.classElement2('B'));
-
-    SetOrMapLiteral fromNode = createNode();
-    (fromNode.typeArguments!.arguments[0] as TypeNameImpl).type = typeA;
-    (fromNode.elements[0] as SimpleIdentifierImpl).staticType = typeB;
-
-    SetOrMapLiteral toNode = createNode();
-    ResolutionCopier.copyResolutionData(fromNode, toNode);
-    expect((toNode.typeArguments!.arguments[0] as TypeName).type, same(typeA));
-    expect((toNode.elements[0] as SimpleIdentifier).staticType, same(typeB));
-  }
-
-  void test_visitSimpleIdentifier() {
-    var fromNode = AstTestFactory.identifier3("x");
-    MethodElement staticElement = ElementFactory.methodElement(
-        "m", interfaceTypeStar(ElementFactory.classElement2('C')));
-    fromNode.staticElement = staticElement;
-    DartType staticType = interfaceTypeStar(ElementFactory.classElement2('C'));
-    fromNode.staticType = staticType;
-    SimpleIdentifier toNode = AstTestFactory.identifier3("x");
-    ResolutionCopier.copyResolutionData(fromNode, toNode);
-    expect(toNode.staticElement, same(staticElement));
-    expect(toNode.staticType, same(staticType));
-  }
-
-  void test_visitSimpleStringLiteral() {
-    var fromNode = AstTestFactory.string2("abc");
-    DartType staticType = interfaceTypeStar(ElementFactory.classElement2('C'));
-    fromNode.staticType = staticType;
-    SimpleStringLiteral toNode = AstTestFactory.string2("abc");
-    ResolutionCopier.copyResolutionData(fromNode, toNode);
-    expect(toNode.staticType, same(staticType));
-  }
-
-  void test_visitSpreadElement() {
-    SpreadElement createNode() => astFactory.spreadElement(
-        spreadOperator:
-            TokenFactory.tokenFromType(TokenType.PERIOD_PERIOD_PERIOD),
-        expression: astFactory.listLiteral(
-            null,
-            null,
-            TokenFactory.tokenFromType(TokenType.OPEN_SQUARE_BRACKET),
-            [AstTestFactory.identifier3('a')],
-            TokenFactory.tokenFromType(TokenType.CLOSE_SQUARE_BRACKET)));
-
-    DartType typeA = interfaceTypeStar(ElementFactory.classElement2('A'));
-
-    SpreadElement fromNode = createNode();
-    ((fromNode.expression as ListLiteral).elements[0] as SimpleIdentifierImpl)
-        .staticType = typeA;
-
-    SpreadElement toNode = createNode();
-    ResolutionCopier.copyResolutionData(fromNode, toNode);
-    expect(
-        ((toNode.expression as ListLiteral).elements[0] as SimpleIdentifier)
-            .staticType,
-        same(typeA));
-  }
-
-  void test_visitStringInterpolation() {
-    var fromNode =
-        AstTestFactory.string([AstTestFactory.interpolationString("a", "'a'")]);
-    DartType staticType = interfaceTypeStar(ElementFactory.classElement2('C'));
-    fromNode.staticType = staticType;
-    StringInterpolation toNode =
-        AstTestFactory.string([AstTestFactory.interpolationString("a", "'a'")]);
-    ResolutionCopier.copyResolutionData(fromNode, toNode);
-    expect(toNode.staticType, same(staticType));
-  }
-
-  void test_visitSuperConstructorInvocation() {
-    var fromNode = AstTestFactory.superConstructorInvocation();
-    ConstructorElement staticElement = ElementFactory.constructorElement2(
-        ElementFactory.classElement2("C"), null);
-    fromNode.staticElement = staticElement;
-    SuperConstructorInvocation toNode =
-        AstTestFactory.superConstructorInvocation();
-    ResolutionCopier.copyResolutionData(fromNode, toNode);
-    expect(toNode.staticElement, same(staticElement));
-  }
-
-  void test_visitSuperExpression() {
-    var fromNode = AstTestFactory.superExpression();
-    DartType staticType = interfaceTypeStar(ElementFactory.classElement2('C'));
-    fromNode.staticType = staticType;
-    SuperExpression toNode = AstTestFactory.superExpression();
-    ResolutionCopier.copyResolutionData(fromNode, toNode);
-    expect(toNode.staticType, same(staticType));
-  }
-
-  void test_visitSymbolLiteral() {
-    var fromNode = AstTestFactory.symbolLiteral(["s"]);
-    DartType staticType = interfaceTypeStar(ElementFactory.classElement2('C'));
-    fromNode.staticType = staticType;
-    SymbolLiteral toNode = AstTestFactory.symbolLiteral(["s"]);
-    ResolutionCopier.copyResolutionData(fromNode, toNode);
-    expect(toNode.staticType, same(staticType));
-  }
-
-  void test_visitThisExpression() {
-    var fromNode = AstTestFactory.thisExpression();
-    DartType staticType = interfaceTypeStar(ElementFactory.classElement2('C'));
-    fromNode.staticType = staticType;
-    ThisExpression toNode = AstTestFactory.thisExpression();
-    ResolutionCopier.copyResolutionData(fromNode, toNode);
-    expect(toNode.staticType, same(staticType));
-  }
-
-  void test_visitThrowExpression() {
-    var fromNode = AstTestFactory.throwExpression2(
-      AstTestFactory.integer(0),
-    );
-    DartType staticType = interfaceTypeStar(ElementFactory.classElement2('C'));
-    fromNode.staticType = staticType;
-    ThrowExpression toNode = AstTestFactory.throwExpression2(
-      AstTestFactory.integer(0),
-    );
-    ResolutionCopier.copyResolutionData(fromNode, toNode);
-    expect(toNode.staticType, same(staticType));
-  }
-
-  void test_visitTypeName() {
-    var fromNode = AstTestFactory.typeName4("C");
-    DartType type = interfaceTypeStar(ElementFactory.classElement2('C'));
-    fromNode.type = type;
-    TypeName toNode = AstTestFactory.typeName4("C");
-    ResolutionCopier.copyResolutionData(fromNode, toNode);
-    expect(toNode.type, same(type));
-  }
-
-  void _copyAndVerifyInvocation(
-      InvocationExpressionImpl fromNode, InvocationExpression toNode) {
-    DartType staticType = interfaceTypeStar(ElementFactory.classElement2('C'));
-    fromNode.staticType = staticType;
-
-    DartType staticInvokeType =
-        interfaceTypeStar(ElementFactory.classElement2('C'));
-    fromNode.staticInvokeType = staticInvokeType;
-
-    ResolutionCopier.copyResolutionData(fromNode, toNode);
-    expect(toNode.staticType, same(staticType));
-    expect(toNode.staticInvokeType, same(staticInvokeType));
-    List<TypeAnnotation> fromTypeArguments = toNode.typeArguments!.arguments;
-    List<TypeAnnotation> toTypeArguments = fromNode.typeArguments!.arguments;
-    for (int i = 0; i < fromTypeArguments.length; i++) {
-      TypeAnnotation toArgument = fromTypeArguments[i];
-      TypeAnnotation fromArgument = toTypeArguments[i];
-      expect(toArgument.type, same(fromArgument.type));
-    }
-  }
-}
-
-class _AnalysisContextMock implements AnalysisContext {
-  @override
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
-
-class _AnalysisSessionMock implements AnalysisSession {
-  @override
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
diff --git a/pkg/analyzer/test/src/dart/element/element_test.dart b/pkg/analyzer/test/src/dart/element/element_test.dart
index 03658e3..0f8202f 100644
--- a/pkg/analyzer/test/src/dart/element/element_test.dart
+++ b/pkg/analyzer/test/src/dart/element/element_test.dart
@@ -2242,6 +2242,27 @@
     expect(typeF.resolveToBound(objectNone), interfaceTypeStar(classS));
   }
 
+  void test_resolveToBound_promotedBound_interfaceType() {
+    var A = class_(name: 'A');
+    var A_none = interfaceTypeNone(A);
+
+    var T = typeParameter('T');
+    var T_A = typeParameterTypeNone(T, promotedBound: A_none);
+    expect(T_A.resolveToBound(objectQuestion), A_none);
+  }
+
+  void test_resolveToBound_promotedBound_typeParameterType_interfaceType() {
+    var A = class_(name: 'A');
+    var A_none = interfaceTypeNone(A);
+
+    var T = typeParameter('T', bound: A_none);
+    var T_none = typeParameterTypeNone(T);
+
+    var U = typeParameter('U');
+    var U_T = typeParameterTypeNone(U, promotedBound: T_none);
+    expect(U_T.resolveToBound(objectQuestion), A_none);
+  }
+
   void test_resolveToBound_unbound() {
     TypeParameterTypeImpl type =
         typeParameterTypeStar(TypeParameterElementImpl('E', -1));
diff --git a/pkg/analyzer/test/src/dart/element/generic_inferrer_test.dart b/pkg/analyzer/test/src/dart/element/generic_inferrer_test.dart
index b59d6fd..7933c6f 100644
--- a/pkg/analyzer/test/src/dart/element/generic_inferrer_test.dart
+++ b/pkg/analyzer/test/src/dart/element/generic_inferrer_test.dart
@@ -654,6 +654,7 @@
       contextReturnType: returnType,
       errorReporter: reporter,
       errorNode: astFactory.nullLiteral(KeywordToken(Keyword.NULL, 0)),
+      genericMetadataIsEnabled: true,
     );
 
     if (expectError) {
diff --git a/pkg/analyzer/test/src/dart/micro/file_resolution.dart b/pkg/analyzer/test/src/dart/micro/file_resolution.dart
index d2c3eaf..55d7031 100644
--- a/pkg/analyzer/test/src/dart/micro/file_resolution.dart
+++ b/pkg/analyzer/test/src/dart/micro/file_resolution.dart
@@ -14,8 +14,7 @@
 import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
 import 'package:analyzer/src/workspace/bazel.dart';
 import 'package:crypto/crypto.dart';
-
-// import 'package:linter/src/rules.dart';
+import 'package:linter/src/rules.dart';
 
 import '../resolution/resolution.dart';
 
@@ -66,7 +65,8 @@
 
   @override
   Future<ResolvedUnitResult> resolveFile(String path) async {
-    return fileResolver.resolve(path: path);
+    result = fileResolver.resolve(path: path);
+    return result;
   }
 
   @override
@@ -78,7 +78,7 @@
   }
 
   void setUp() {
-    // registerLintRules();
+    registerLintRules();
 
     logger = PerformanceLog(logBuffer);
     sdk = MockSdk(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 8709a1f..aa6dfb3 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
@@ -296,7 +296,6 @@
     ]);
   }
 
-  @FailingTest(issue: 'https://github.com/dart-lang/linter/issues/2399')
   test_analysisOptions_lints() async {
     newFile('/workspace/dart/analysis_options/lib/default.yaml', content: r'''
 linter:
@@ -438,6 +437,42 @@
     expect(fileResolver.testView!.resolvedFiles, <Object>[]);
   }
 
+  test_getLibraryByUri() {
+    newFile('/workspace/dart/my/lib/a.dart', content: r'''
+class A {}
+''');
+
+    var element = fileResolver.getLibraryByUri(
+      uriStr: 'package:dart.my/a.dart',
+    );
+    expect(element.definingCompilationUnit.types, hasLength(1));
+  }
+
+  test_getLibraryByUri_notExistingFile() {
+    var element = fileResolver.getLibraryByUri(
+      uriStr: 'package:dart.my/a.dart',
+    );
+    expect(element.definingCompilationUnit.types, isEmpty);
+  }
+
+  test_getLibraryByUri_partOf() {
+    newFile('/workspace/dart/my/lib/a.dart', content: r'''
+part of 'b.dart';
+''');
+
+    expect(() {
+      fileResolver.getLibraryByUri(
+        uriStr: 'package:dart.my/a.dart',
+      );
+    }, throwsArgumentError);
+  }
+
+  test_getLibraryByUri_unresolvedUri() {
+    expect(() {
+      fileResolver.getLibraryByUri(uriStr: 'my:unresolved');
+    }, throwsArgumentError);
+  }
+
   test_hint() async {
     await assertErrorsInCode(r'''
 import 'dart:math';
@@ -446,6 +481,15 @@
     ]);
   }
 
+  test_hint_in_third_party() async {
+    var aPath = convertPath('/workspace/third_party/dart/aaa/lib/a.dart');
+    newFile(aPath, content: r'''
+import 'dart:math';
+''');
+    await resolveFile(aPath);
+    assertNoErrorsInResult();
+  }
+
   test_linkLibraries_getErrors() {
     addTestFile(r'''
 var a = b;
@@ -509,6 +553,81 @@
 ''');
   }
 
+  test_removeFilesNotNecessaryForAnalysisOf() async {
+    var aPath = convertPath('/workspace/dart/aaa/lib/a.dart');
+    var bPath = convertPath('/workspace/dart/aaa/lib/b.dart');
+    var cPath = convertPath('/workspace/dart/aaa/lib/c.dart');
+
+    newFile(aPath, 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]);
+    _assertRemovedPaths(unorderedEquals([bPath]));
+  }
+
+  test_removeFilesNotNecessaryForAnalysisOf_multiple() async {
+    var bPath = convertPath('/workspace/dart/aaa/lib/b.dart');
+    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(bPath, 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]);
+    _assertRemovedPaths(unorderedEquals([bPath, ePath]));
+  }
+
+  test_removeFilesNotNecessaryForAnalysisOf_unknown() async {
+    var aPath = convertPath('/workspace/dart/aaa/lib/a.dart');
+    var bPath = convertPath('/workspace/dart/aaa/lib/b.dart');
+
+    newFile(aPath, content: r'''
+class A {}
+''');
+
+    await resolveFile(aPath);
+
+    fileResolver.removeFilesNotNecessaryForAnalysisOf([aPath, bPath]);
+    _assertRemovedPaths(isEmpty);
+  }
+
   test_resolve_part_of() async {
     newFile('/workspace/dart/test/lib/a.dart', content: r'''
 part 'test.dart';
@@ -560,6 +679,30 @@
     expect(result, isNot(same(result1)));
   }
 
+  test_resolveLibrary() async {
+    var aPath = convertPath('/workspace/dart/test/lib/a.dart');
+    newFile(aPath, content: r'''
+part 'test.dart';
+
+class A {
+  int m;
+}
+''');
+
+    newFile('/workspace/dart/test/lib/test.dart', content: r'''
+part of 'a.dart';
+
+void func() {
+  var a = A();
+  print(a.m);
+}
+''');
+
+    var result = fileResolver.resolveLibrary(path: aPath);
+    expect(result.path, aPath);
+    expect(result.units?.length, 2);
+  }
+
   test_reuse_compatibleOptions() async {
     newFile('/workspace/dart/aaa/BUILD', content: '');
     newFile('/workspace/dart/bbb/BUILD', content: '');
@@ -647,64 +790,7 @@
     ]);
   }
 
-  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);
+  void _assertRemovedPaths(Matcher matcher) {
+    expect(fileResolver.fsState!.testView.removedPaths, matcher);
   }
 }
diff --git a/pkg/analyzer/test/src/dart/resolution/class_test.dart b/pkg/analyzer/test/src/dart/resolution/class_test.dart
index da64df0..f58dbf4 100644
--- a/pkg/analyzer/test/src/dart/resolution/class_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/class_test.dart
@@ -432,30 +432,6 @@
     assertType(a.supertype, 'Object');
   }
 
-  test_error_implementsRepeated() async {
-    await assertErrorsInCode(r'''
-class A {}
-class B implements A, A {} // ref
-''', [
-      error(CompileTimeErrorCode.IMPLEMENTS_REPEATED, 33, 1),
-    ]);
-
-    var a = findElement.class_('A');
-    assertTypeName(findNode.typeName('A, A {} // ref'), a, 'A');
-    assertTypeName(findNode.typeName('A {} // ref'), a, 'A');
-  }
-
-  test_error_implementsRepeated_3times() async {
-    await assertErrorsInCode(r'''
-class A {} class C{}
-class B implements A, A, A, A {}
-''', [
-      error(CompileTimeErrorCode.IMPLEMENTS_REPEATED, 43, 1),
-      error(CompileTimeErrorCode.IMPLEMENTS_REPEATED, 46, 1),
-      error(CompileTimeErrorCode.IMPLEMENTS_REPEATED, 49, 1),
-    ]);
-  }
-
   test_error_memberWithClassName_field() async {
     await assertErrorsInCode(r'''
 class C {
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 84d9950..2b7598a 100644
--- a/pkg/analyzer/test/src/dart/resolution/context_collection_resolution.dart
+++ b/pkg/analyzer/test/src/dart/resolution/context_collection_resolution.dart
@@ -21,7 +21,7 @@
 import 'package:analyzer/src/workspace/gn.dart';
 import 'package:analyzer/src/workspace/package_build.dart';
 import 'package:analyzer/src/workspace/pub.dart';
-// import 'package:linter/src/rules.dart';
+import 'package:linter/src/rules.dart';
 import 'package:meta/meta.dart';
 import 'package:test/test.dart';
 
@@ -37,6 +37,7 @@
   final List<String> lints;
   final bool strictInference;
   final bool strictRawTypes;
+  final List<String> unignorableNames;
 
   AnalysisOptionsFileConfig({
     this.experiments = const [],
@@ -45,6 +46,7 @@
     this.lints = const [],
     this.strictInference = false,
     this.strictRawTypes = false,
+    this.unignorableNames = const [],
   });
 
   String toContent() {
@@ -61,6 +63,10 @@
     buffer.writeln('  strong-mode:');
     buffer.writeln('    implicit-casts: $implicitCasts');
     buffer.writeln('    implicit-dynamic: $implicitDynamic');
+    buffer.writeln('  cannot-ignore:');
+    for (var name in unignorableNames) {
+      buffer.writeln('    - $name');
+    }
 
     buffer.writeln('linter:');
     buffer.writeln('  rules:');
@@ -183,13 +189,13 @@
   Future<ResolvedUnitResult> resolveFile(String path) async {
     var analysisContext = contextFor(pathForContextSelection ?? path);
     var session = analysisContext.currentSession;
-    return (await session.getResolvedUnit(path))!;
+    return await session.getResolvedUnit(path);
   }
 
   @mustCallSuper
   void setUp() {
     if (!_lintRulesAreRegistered) {
-      // registerLintRules();
+      registerLintRules();
       _lintRulesAreRegistered = true;
     }
 
@@ -243,6 +249,12 @@
   @override
   List<String> get collectionIncludedPaths => [workspaceRootPath];
 
+  List<String> get experiments => [
+        EnableString.generic_metadata,
+        EnableString.nonfunction_type_aliases,
+        EnableString.triple_shift,
+      ];
+
   /// The path that is not in [workspaceRootPath], contains external packages.
   String get packagesRootPath => '/packages';
 
@@ -266,10 +278,7 @@
     super.setUp();
     writeTestPackageAnalysisOptionsFile(
       AnalysisOptionsFileConfig(
-        experiments: [
-          EnableString.nonfunction_type_aliases,
-          EnableString.triple_shift,
-        ],
+        experiments: experiments,
       ),
     );
     writeTestPackageConfig(
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 99c2406..0cd0ac8 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
@@ -4,6 +4,7 @@
 
 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/error/syntactic_errors.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:test/test.dart';
@@ -14,63 +15,54 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(GenericTypeAliasDriverResolutionTest);
+    defineReflectiveTests(
+        GenericTypeAliasDriverResolutionWithoutGenericMetadataTest);
   });
 }
 
 @reflectiveTest
-class GenericTypeAliasDriverResolutionTest extends PubPackageResolutionTest {
+class GenericTypeAliasDriverResolutionTest extends PubPackageResolutionTest
+    with GenericTypeAliasDriverResolutionTestCases {
   test_genericFunctionTypeCannotBeTypeArgument_def_class() async {
-    await assertErrorsInCode(r'''
+    await assertNoErrorsInCode(r'''
 class C<T> {}
 
 typedef G = Function<S>();
 
 C<G>? x;
-''', [
-      error(CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT,
-          45, 1),
-    ]);
+''');
   }
 
   test_genericFunctionTypeCannotBeTypeArgument_literal_class() async {
-    await assertErrorsInCode(r'''
+    await assertNoErrorsInCode(r'''
 class C<T> {}
 
 C<Function<S>()>? x;
-''', [
-      error(CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT,
-          17, 13),
-    ]);
+''');
   }
 
   test_genericFunctionTypeCannotBeTypeArgument_literal_function() async {
-    await assertErrorsInCode(r'''
+    await assertNoErrorsInCode(r'''
 void f<T>(T) {}
 
 main() {
   f<Function<S>()>(null);
 }
-''', [
-      error(CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT,
-          30, 13),
-    ]);
+''');
   }
 
   test_genericFunctionTypeCannotBeTypeArgument_literal_functionType() async {
-    await assertErrorsInCode(r'''
+    await assertNoErrorsInCode(r'''
 late T Function<T>(T?) f;
 
 main() {
   f<Function<S>()>(null);
 }
-''', [
-      error(CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT,
-          40, 13),
-    ]);
+''');
   }
 
   test_genericFunctionTypeCannotBeTypeArgument_literal_method() async {
-    await assertErrorsInCode(r'''
+    await assertNoErrorsInCode(r'''
 class C {
   void f<T>(T) {}
 }
@@ -78,23 +70,34 @@
 main() {
   new C().f<Function<S>()>(null);
 }
-''', [
-      error(CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT,
-          52, 13),
-    ]);
+''');
   }
 
   test_genericFunctionTypeCannotBeTypeArgument_literal_typedef() async {
-    await assertErrorsInCode(r'''
+    await assertNoErrorsInCode(r'''
 typedef T F<T>(T t);
 
 F<Function<S>()>? x;
-''', [
-      error(CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT,
-          24, 13),
-    ]);
+''');
   }
 
+  test_genericFunctionTypeCannotBeTypeArgument_optOutOfGenericMetadata() async {
+    newFile('$testPackageLibPath/a.dart', content: '''
+typedef G = Function<S>();
+''');
+    await assertErrorsInCode('''
+// @dart=2.12
+import 'a.dart';
+class C<T> {}
+C<G>? x;
+''', [
+      error(CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT,
+          47, 1),
+    ]);
+  }
+}
+
+mixin GenericTypeAliasDriverResolutionTestCases on PubPackageResolutionTest {
   test_genericFunctionTypeCannotBeTypeArgument_OK_def_class() async {
     await assertNoErrorsInCode(r'''
 class C<T> {}
@@ -180,3 +183,88 @@
     assertType(u.bound, 'B');
   }
 }
+
+@reflectiveTest
+class GenericTypeAliasDriverResolutionWithoutGenericMetadataTest
+    extends PubPackageResolutionTest
+    with GenericTypeAliasDriverResolutionTestCases {
+  @override
+  List<String> get experiments =>
+      super.experiments..remove(EnableString.generic_metadata);
+
+  test_genericFunctionTypeCannotBeTypeArgument_def_class() async {
+    await assertErrorsInCode(r'''
+class C<T> {}
+
+typedef G = Function<S>();
+
+C<G>? x;
+''', [
+      error(CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT,
+          45, 1),
+    ]);
+  }
+
+  test_genericFunctionTypeCannotBeTypeArgument_literal_class() async {
+    await assertErrorsInCode(r'''
+class C<T> {}
+
+C<Function<S>()>? x;
+''', [
+      error(CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT,
+          17, 13),
+    ]);
+  }
+
+  test_genericFunctionTypeCannotBeTypeArgument_literal_function() async {
+    await assertErrorsInCode(r'''
+void f<T>(T) {}
+
+main() {
+  f<Function<S>()>(null);
+}
+''', [
+      error(CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT,
+          30, 13),
+    ]);
+  }
+
+  test_genericFunctionTypeCannotBeTypeArgument_literal_functionType() async {
+    await assertErrorsInCode(r'''
+late T Function<T>(T?) f;
+
+main() {
+  f<Function<S>()>(null);
+}
+''', [
+      error(CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT,
+          40, 13),
+    ]);
+  }
+
+  test_genericFunctionTypeCannotBeTypeArgument_literal_method() async {
+    await assertErrorsInCode(r'''
+class C {
+  void f<T>(T) {}
+}
+
+main() {
+  new C().f<Function<S>()>(null);
+}
+''', [
+      error(CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT,
+          52, 13),
+    ]);
+  }
+
+  test_genericFunctionTypeCannotBeTypeArgument_literal_typedef() async {
+    await assertErrorsInCode(r'''
+typedef T F<T>(T t);
+
+F<Function<S>()>? x;
+''', [
+      error(CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT,
+          24, 13),
+    ]);
+  }
+}
diff --git a/pkg/analyzer/test/src/dart/resolution/instance_creation_test.dart b/pkg/analyzer/test/src/dart/resolution/instance_creation_test.dart
index 5bf3bac..206f003 100644
--- a/pkg/analyzer/test/src/dart/resolution/instance_creation_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/instance_creation_test.dart
@@ -18,6 +18,112 @@
     with InstanceCreationTestCases {}
 
 mixin InstanceCreationTestCases on PubPackageResolutionTest {
+  test_class_generic_named_inferTypeArguments() async {
+    await assertNoErrorsInCode(r'''
+class A<T> {
+  A.named(T t);
+}
+
+void f() {
+  A.named(0);
+}
+
+''');
+
+    var creation = findNode.instanceCreation('A.named(0)');
+    assertInstanceCreation(
+      creation,
+      findElement.class_('A'),
+      'A<int>',
+      constructorName: 'named',
+      expectedConstructorMember: true,
+      expectedSubstitution: {'T': 'int'},
+    );
+  }
+
+  test_class_generic_named_withTypeArguments() async {
+    await assertNoErrorsInCode(r'''
+class A<T> {
+  A.named();
+}
+
+void f() {
+  A<int>.named();
+}
+
+''');
+
+    var creation = findNode.instanceCreation('A<int>');
+    assertInstanceCreation(
+      creation,
+      findElement.class_('A'),
+      'A<int>',
+      constructorName: 'named',
+      expectedConstructorMember: true,
+      expectedSubstitution: {'T': 'int'},
+    );
+    assertTypeName(findNode.typeName('int>'), intElement, 'int');
+  }
+
+  test_class_generic_unnamed_inferTypeArguments() async {
+    await assertNoErrorsInCode(r'''
+class A<T> {
+  A(T t);
+}
+
+void f() {
+  A(0);
+}
+
+''');
+
+    var creation = findNode.instanceCreation('A(0)');
+    assertInstanceCreation(
+      creation,
+      findElement.class_('A'),
+      'A<int>',
+      expectedConstructorMember: true,
+      expectedSubstitution: {'T': 'int'},
+    );
+  }
+
+  test_class_generic_unnamed_withTypeArguments() async {
+    await assertNoErrorsInCode(r'''
+class A<T> {}
+
+void f() {
+  A<int>();
+}
+
+''');
+
+    var creation = findNode.instanceCreation('A<int>');
+    assertInstanceCreation(
+      creation,
+      findElement.class_('A'),
+      'A<int>',
+      expectedConstructorMember: true,
+      expectedSubstitution: {'T': 'int'},
+    );
+    assertTypeName(findNode.typeName('int>'), intElement, 'int');
+  }
+
+  test_class_notGeneric() async {
+    await assertNoErrorsInCode(r'''
+class A {
+  A(int a);
+}
+
+void f() {
+  A(0);
+}
+
+''');
+
+    var creation = findNode.instanceCreation('A(0)');
+    assertInstanceCreation(creation, findElement.class_('A'), 'A');
+  }
+
   test_demoteType() async {
     await assertNoErrorsInCode(r'''
 class A<T> {
@@ -169,4 +275,155 @@
       expectedSubstitution: {'X': 'int'},
     );
   }
+
+  test_typeAlias_generic_class_generic_named_infer_all() async {
+    await assertNoErrorsInCode(r'''
+class A<T> {
+  A.named(T t);
+}
+
+typedef B<U> = A<U>;
+
+void f() {
+  B.named(0);
+}
+''');
+
+    var creation = findNode.instanceCreation('B.named(0)');
+    assertInstanceCreation(
+      creation,
+      findElement.class_('A'),
+      'A<int>',
+      constructorName: 'named',
+      expectedTypeNameElement: findElement.typeAlias('B'),
+      expectedConstructorMember: true,
+      expectedSubstitution: {'T': 'int'},
+    );
+  }
+
+  test_typeAlias_generic_class_generic_named_infer_partial() async {
+    await assertNoErrorsInCode(r'''
+class A<T, U> {
+  A.named(T t, U u);
+}
+
+typedef B<V> = A<V, String>;
+
+void f() {
+  B.named(0, '');
+}
+''');
+
+    var creation = findNode.instanceCreation('B.named(0, ');
+    assertInstanceCreation(
+      creation,
+      findElement.class_('A'),
+      'A<int, String>',
+      constructorName: 'named',
+      expectedTypeNameElement: findElement.typeAlias('B'),
+      expectedConstructorMember: true,
+      expectedSubstitution: {'T': 'int', 'U': 'String'},
+    );
+  }
+
+  test_typeAlias_generic_class_generic_unnamed_infer_all() async {
+    await assertNoErrorsInCode(r'''
+class A<T> {
+  A(T t);
+}
+
+typedef B<U> = A<U>;
+
+void f() {
+  B(0);
+}
+''');
+
+    var creation = findNode.instanceCreation('B(0)');
+    assertInstanceCreation(
+      creation,
+      findElement.class_('A'),
+      'A<int>',
+      expectedTypeNameElement: findElement.typeAlias('B'),
+      expectedConstructorMember: true,
+      expectedSubstitution: {'T': 'int'},
+    );
+  }
+
+  test_typeAlias_generic_class_generic_unnamed_infer_partial() async {
+    await assertNoErrorsInCode(r'''
+class A<T, U> {
+  A(T t, U u);
+}
+
+typedef B<V> = A<V, String>;
+
+void f() {
+  B(0, '');
+}
+''');
+
+    var creation = findNode.instanceCreation('B(0, ');
+    assertInstanceCreation(
+      creation,
+      findElement.class_('A'),
+      'A<int, String>',
+      expectedTypeNameElement: findElement.typeAlias('B'),
+      expectedConstructorMember: true,
+      expectedSubstitution: {'T': 'int', 'U': 'String'},
+    );
+  }
+
+  test_typeAlias_notGeneric_class_generic_named_argumentTypeMismatch() async {
+    await assertErrorsInCode(r'''
+class A<T> {
+  A.named(T t);
+}
+
+typedef B = A<String>;
+
+void f() {
+  B.named(0);
+}
+''', [
+      error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 77, 1),
+    ]);
+
+    var creation = findNode.instanceCreation('B.named(0)');
+    assertInstanceCreation(
+      creation,
+      findElement.class_('A'),
+      'A<String>',
+      constructorName: 'named',
+      expectedTypeNameElement: findElement.typeAlias('B'),
+      expectedConstructorMember: true,
+      expectedSubstitution: {'T': 'String'},
+    );
+  }
+
+  test_typeAlias_notGeneric_class_generic_unnamed_argumentTypeMismatch() async {
+    await assertErrorsInCode(r'''
+class A<T> {
+  A(T t);
+}
+
+typedef B = A<String>;
+
+void f() {
+  B(0);
+}
+''', [
+      error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 65, 1),
+    ]);
+
+    var creation = findNode.instanceCreation('B(0)');
+    assertInstanceCreation(
+      creation,
+      findElement.class_('A'),
+      'A<String>',
+      expectedTypeNameElement: findElement.typeAlias('B'),
+      expectedConstructorMember: true,
+      expectedSubstitution: {'T': 'String'},
+    );
+  }
 }
diff --git a/pkg/analyzer/test/src/dart/resolution/metadata_test.dart b/pkg/analyzer/test/src/dart/resolution/metadata_test.dart
index 796316c..75eaf41 100644
--- a/pkg/analyzer/test/src/dart/resolution/metadata_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/metadata_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 'dart:collection';
+
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/constant/value.dart';
 import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/dart/constant/value.dart';
 import 'package:analyzer/src/test_utilities/find_element.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -15,139 +18,29 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(MetadataResolutionTest);
-    defineReflectiveTests(MetadataResolutionWithNullSafetyTest);
   });
 }
 
 @reflectiveTest
-class MetadataResolutionTest extends PubPackageResolutionTest
-    with WithoutNullSafetyMixin {
-  test_genericClass_instanceGetter() async {
-    await resolveTestCode(r'''
-class A<T> {
-  T get foo {}
-}
-
-@A.foo
-void f() {}
-''');
-
-    _assertResolvedNodeText(findNode.annotation('@A'), r'''
-Annotation
-  element: self::@class::A::@getter::foo
-  name: PrefixedIdentifier
-    identifier: SimpleIdentifier
-      staticElement: self::@class::A::@getter::foo
-      staticType: null
-      token: foo
-    period: .
-    prefix: SimpleIdentifier
-      staticElement: self::@class::A
-      staticType: null
-      token: A
-    staticElement: self::@class::A::@getter::foo
-    staticType: null
-''');
-  }
-
-  test_genericClass_namedConstructor() async {
-    await assertNoErrorsInCode(r'''
-class A<T> {
-  const A.named();
-}
-
-@A.named()
-void f() {}
-''');
-
-    _assertResolvedNodeText(findNode.annotation('@A'), r'''
-Annotation
-  arguments: ArgumentList
-  element: ConstructorMember
-    base: self::@class::A::@constructor::named
-    substitution: {T: dynamic}
-  name: PrefixedIdentifier
-    identifier: SimpleIdentifier
-      staticElement: ConstructorMember
-        base: self::@class::A::@constructor::named
-        substitution: {T: dynamic}
-      staticType: null
-      token: named
-    period: .
-    prefix: SimpleIdentifier
-      staticElement: self::@class::A
-      staticType: null
-      token: A
-    staticElement: ConstructorMember
-      base: self::@class::A::@constructor::named
-      substitution: {T: dynamic}
-    staticType: null
-''');
-  }
-
-  test_genericClass_staticGetter() async {
-    await resolveTestCode(r'''
-class A<T> {
-  static T get foo {}
-}
-
-@A.foo
-void f() {}
-''');
-
-    _assertResolvedNodeText(findNode.annotation('@A'), r'''
-Annotation
-  element: self::@class::A::@getter::foo
-  name: PrefixedIdentifier
-    identifier: SimpleIdentifier
-      staticElement: self::@class::A::@getter::foo
-      staticType: null
-      token: foo
-    period: .
-    prefix: SimpleIdentifier
-      staticElement: self::@class::A
-      staticType: null
-      token: A
-    staticElement: self::@class::A::@getter::foo
-    staticType: null
-''');
-  }
-
-  test_genericClass_unnamedConstructor() async {
-    await assertNoErrorsInCode(r'''
-class A<T> {
-  const A();
-}
-
-@A()
-void f() {}
-''');
-
-    _assertResolvedNodeText(findNode.annotation('@A'), r'''
-Annotation
-  arguments: ArgumentList
-  element: ConstructorMember
-    base: self::@class::A::@constructor::•
-    substitution: {T: dynamic}
-  name: SimpleIdentifier
-    staticElement: self::@class::A
-    staticType: null
-    token: A
-''');
+class MetadataResolutionTest extends PubPackageResolutionTest {
+  ImportFindElement get import_a {
+    return findElement.importFind('package:test/a.dart');
   }
 
   test_onFieldFormal() async {
     await assertNoErrorsInCode(r'''
 class A {
-  const A(_);
+  final Object f;
+  const A(this.f);
 }
 
 class B {
   final int f;
-  B({@A( A(0) ) this.f});
+  B({@A( A(0) ) required this.f});
 }
 ''');
-    _assertResolvedNodeText(findNode.annotation('@A'), r'''
+    var annotation = findNode.annotation('@A');
+    _assertResolvedNodeText(annotation, r'''
 Annotation
   arguments: ArgumentList
     arguments
@@ -172,132 +65,11 @@
     staticType: null
     token: A
 ''');
-  }
-
-  test_otherLibrary_constructor_named() async {
-    newFile('$testPackageLibPath/a.dart', content: r'''
-class A {
-  final int f;
-  const A.named(this.f);
-}
+    _assertAnnotationValueText(annotation, r'''
+A
+  f: A
+    f: int 0
 ''');
-
-    newFile('$testPackageLibPath/b.dart', content: r'''
-import 'a.dart';
-
-@A.named(42)
-class B {}
-''');
-
-    await assertNoErrorsInCode(r'''
-import 'b.dart';
-
-B b;
-''');
-
-    var classB = findNode.typeName('B b;').name.staticElement!;
-    var annotation = classB.metadata.single;
-    var value = annotation.computeConstantValue()!;
-    assertType(value.type, 'A');
-    expect(value.getField('f')!.toIntValue(), 42);
-  }
-
-  test_otherLibrary_constructor_unnamed() async {
-    newFile('$testPackageLibPath/a.dart', content: r'''
-class A {
-  final int f;
-  const A(this.f);
-}
-''');
-
-    newFile('$testPackageLibPath/b.dart', content: r'''
-import 'a.dart';
-
-@A(42)
-class B {}
-''');
-
-    await assertNoErrorsInCode(r'''
-import 'b.dart';
-
-B b;
-''');
-
-    var classB = findNode.typeName('B b;').name.staticElement!;
-    var annotation = classB.metadata.single;
-    var value = annotation.computeConstantValue()!;
-    assertType(value.type, 'A');
-    expect(value.getField('f')!.toIntValue(), 42);
-  }
-
-  test_otherLibrary_implicitConst() async {
-    newFile('$testPackageLibPath/a.dart', content: r'''
-class A {
-  final int f;
-  const A(this.f);
-}
-
-class B {
-  final A a;
-  const B(this.a);
-}
-
-@B( A(42) )
-class C {}
-''');
-
-    await assertNoErrorsInCode(r'''
-import 'a.dart';
-
-C c;
-''');
-
-    var classC = findNode.typeName('C c;').name.staticElement!;
-    var annotation = classC.metadata.single;
-    var value = annotation.computeConstantValue()!;
-    assertType(value.type, 'B');
-    expect(value.getField('a')!.getField('f')!.toIntValue(), 42);
-  }
-
-  @FailingTest(reason: 'Reverted because of dartbug.com/38565')
-  test_sameLibrary_genericClass_constructor_unnamed() async {
-    await assertNoErrorsInCode(r'''
-class A<T> {
-  final T f;
-  const A(this.f);
-}
-
-@A(42)
-class B {}
-''');
-    var annotation = findElement.class_('B').metadata.single;
-    var value = annotation.computeConstantValue()!;
-    assertType(value.type, 'A<int>');
-    expect(value.getField('f')!.toIntValue(), 42);
-  }
-
-  void _assertResolvedNodeText(AstNode node, String expected) {
-    var actual = _resolvedNodeText(node);
-    expect(actual, expected);
-  }
-
-  String _resolvedNodeText(AstNode node) {
-    var buffer = StringBuffer();
-    node.accept(
-      ResolvedAstPrinter(
-        selfUriStr: result.uri.toString(),
-        sink: buffer,
-        indent: '',
-      ),
-    );
-    return buffer.toString();
-  }
-}
-
-@reflectiveTest
-class MetadataResolutionWithNullSafetyTest extends PubPackageResolutionTest {
-  ImportFindElement get import_a {
-    return findElement.importFind('package:test/a.dart');
   }
 
   test_optIn_fromOptOut_class() async {
@@ -354,11 +126,11 @@
       isLegacy: true,
     );
 
-    _assertConstantValue(
-      findElement.function('f').metadata[0].computeConstantValue()!,
-      type: 'A*',
-      fieldMap: {'a': 42},
-    );
+    _assertElementAnnotationValueText(
+        findElement.function('f').metadata[0], r'''
+A*
+  a: int 42
+''');
   }
 
   test_optIn_fromOptOut_class_constructor_withDefault() async {
@@ -388,11 +160,11 @@
       isLegacy: true,
     );
 
-    _assertConstantValue(
-      findElement.function('f').metadata[0].computeConstantValue()!,
-      type: 'A*',
-      fieldMap: {'a': 42},
-    );
+    _assertElementAnnotationValueText(
+        findElement.function('f').metadata[0], r'''
+A*
+  a: int 42
+''');
   }
 
   test_optIn_fromOptOut_class_getter() async {
@@ -421,7 +193,10 @@
       isLegacy: true,
     );
 
-    _assertIntValue(findElement.function('f').metadata[0], 42);
+    _assertElementAnnotationValueText(
+        findElement.function('f').metadata[0], r'''
+int 42
+''');
   }
 
   test_optIn_fromOptOut_getter() async {
@@ -443,7 +218,10 @@
       isLegacy: true,
     );
 
-    _assertIntValue(findElement.function('f').metadata[0], 42);
+    _assertElementAnnotationValueText(
+        findElement.function('f').metadata[0], r'''
+int 42
+''');
   }
 
   test_optIn_fromOptOut_prefix_class() async {
@@ -547,35 +325,1426 @@
     );
   }
 
-  void _assertConstantValue(
-    DartObject object, {
-    required String type,
-    Map<String, Object>? fieldMap,
-    int? intValue,
-  }) {
-    assertType(object.type, type);
-    if (fieldMap != null) {
-      for (var entry in fieldMap.entries) {
-        var actual = object.getField(entry.key);
-        var expected = entry.value;
-        if (expected is int) {
-          expect(actual!.toIntValue(), expected);
-        } else {
-          fail('Unsupported expected type: ${expected.runtimeType} $expected');
-        }
-      }
-    } else if (intValue != null) {
-      expect(object.toIntValue(), intValue);
-    } else {
-      fail('No expectations.');
-    }
+  test_value_class_inference_namedConstructor() async {
+    await assertNoErrorsInCode(r'''
+class A {
+  final int f;
+  const A.named(this.f);
+}
+
+@A.named(42)
+void f() {}
+''');
+
+    var annotation = findNode.annotation('@A');
+    _assertResolvedNodeText(annotation, r'''
+Annotation
+  arguments: ArgumentList
+    arguments
+      IntegerLiteral
+        literal: 42
+        staticType: int
+  element: self::@class::A::@constructor::named
+  name: PrefixedIdentifier
+    identifier: SimpleIdentifier
+      staticElement: self::@class::A::@constructor::named
+      staticType: null
+      token: named
+    period: .
+    prefix: SimpleIdentifier
+      staticElement: self::@class::A
+      staticType: null
+      token: A
+    staticElement: self::@class::A::@constructor::named
+    staticType: null
+''');
+    _assertAnnotationValueText(annotation, '''
+A
+  f: int 42
+''');
+
+    assertElement2(
+      findNode.integerLiteral('42').staticParameterElement,
+      declaration: findElement.fieldFormalParameter('f'),
+    );
   }
 
-  void _assertIntValue(ElementAnnotation annotation, int intValue) {
-    _assertConstantValue(
-      annotation.computeConstantValue()!,
-      type: 'int',
-      intValue: intValue,
+  test_value_class_staticConstField() async {
+    await assertNoErrorsInCode(r'''
+class A {
+  static const int foo = 42;
+}
+
+@A.foo
+void f() {}
+''');
+
+    var annotation = findNode.annotation('@A');
+    _assertResolvedNodeText(annotation, r'''
+Annotation
+  element: self::@class::A::@getter::foo
+  name: PrefixedIdentifier
+    identifier: SimpleIdentifier
+      staticElement: self::@class::A::@getter::foo
+      staticType: null
+      token: foo
+    period: .
+    prefix: SimpleIdentifier
+      staticElement: self::@class::A
+      staticType: null
+      token: A
+    staticElement: self::@class::A::@getter::foo
+    staticType: null
+''');
+    _assertAnnotationValueText(annotation, '''
+int 42
+''');
+  }
+
+  test_value_class_unnamedConstructor() async {
+    await assertNoErrorsInCode(r'''
+ class A {
+  final int f;
+  const A(this.f);
+}
+
+@A(42)
+void f() {}
+''');
+
+    var annotation = findNode.annotation('@A');
+    _assertResolvedNodeText(annotation, r'''
+Annotation
+  arguments: ArgumentList
+    arguments
+      IntegerLiteral
+        literal: 42
+        staticType: int
+  element: self::@class::A::@constructor::•
+  name: SimpleIdentifier
+    staticElement: self::@class::A
+    staticType: null
+    token: A
+''');
+    _assertAnnotationValueText(annotation, r'''
+A
+  f: int 42
+''');
+
+    assertElement2(
+      findNode.integerLiteral('42').staticParameterElement,
+      declaration: findElement.fieldFormalParameter('f'),
     );
   }
+
+  test_value_genericClass_inference_namedConstructor() async {
+    await assertNoErrorsInCode(r'''
+class A<T> {
+  final T f;
+  const A.named(this.f);
+}
+
+@A.named(42)
+void f() {}
+''');
+
+    var annotation = findNode.annotation('@A');
+    _assertResolvedNodeText(annotation, r'''
+Annotation
+  arguments: ArgumentList
+    arguments
+      IntegerLiteral
+        literal: 42
+        staticType: int
+  element: ConstructorMember
+    base: self::@class::A::@constructor::named
+    substitution: {T: int}
+  name: PrefixedIdentifier
+    identifier: SimpleIdentifier
+      staticElement: ConstructorMember
+        base: self::@class::A::@constructor::named
+        substitution: {T: int}
+      staticType: null
+      token: named
+    period: .
+    prefix: SimpleIdentifier
+      staticElement: self::@class::A
+      staticType: null
+      token: A
+    staticElement: ConstructorMember
+      base: self::@class::A::@constructor::named
+      substitution: {T: int}
+    staticType: null
+''');
+    _assertAnnotationValueText(annotation, '''
+A<int>
+  f: int 42
+''');
+    assertElement2(
+      findNode.integerLiteral('42').staticParameterElement,
+      declaration: findElement.fieldFormalParameter('f'),
+      substitution: {'T': 'int'},
+    );
+  }
+
+  test_value_genericClass_inference_unnamedConstructor() async {
+    await assertNoErrorsInCode(r'''
+ class A<T> {
+  final T f;
+  const A(this.f);
+}
+
+@A(42)
+void f() {}
+''');
+
+    var annotation = findNode.annotation('@A');
+    _assertResolvedNodeText(annotation, r'''
+Annotation
+  arguments: ArgumentList
+    arguments
+      IntegerLiteral
+        literal: 42
+        staticType: int
+  element: ConstructorMember
+    base: self::@class::A::@constructor::•
+    substitution: {T: int}
+  name: SimpleIdentifier
+    staticElement: self::@class::A
+    staticType: null
+    token: A
+''');
+    _assertAnnotationValueText(annotation, r'''
+A<int>
+  f: int 42
+''');
+    assertElement2(
+      findNode.integerLiteral('42').staticParameterElement,
+      declaration: findElement.fieldFormalParameter('f'),
+      substitution: {'T': 'int'},
+    );
+  }
+
+  test_value_genericClass_instanceGetter() async {
+    await resolveTestCode(r'''
+class A<T> {
+  T get foo {}
+}
+
+@A.foo
+void f() {}
+''');
+
+    _assertResolvedNodeText(findNode.annotation('@A'), r'''
+Annotation
+  element: self::@class::A::@getter::foo
+  name: PrefixedIdentifier
+    identifier: SimpleIdentifier
+      staticElement: self::@class::A::@getter::foo
+      staticType: null
+      token: foo
+    period: .
+    prefix: SimpleIdentifier
+      staticElement: self::@class::A
+      staticType: null
+      token: A
+    staticElement: self::@class::A::@getter::foo
+    staticType: null
+''');
+  }
+
+  test_value_genericClass_namedConstructor() async {
+    await assertNoErrorsInCode(r'''
+class A<T> {
+  final int f;
+  const A.named(this.f);
+}
+
+@A.named(42)
+void f() {}
+''');
+
+    var annotation = findNode.annotation('@A');
+    _assertResolvedNodeText(annotation, r'''
+Annotation
+  arguments: ArgumentList
+    arguments
+      IntegerLiteral
+        literal: 42
+        staticType: int
+  element: ConstructorMember
+    base: self::@class::A::@constructor::named
+    substitution: {T: dynamic}
+  name: PrefixedIdentifier
+    identifier: SimpleIdentifier
+      staticElement: ConstructorMember
+        base: self::@class::A::@constructor::named
+        substitution: {T: dynamic}
+      staticType: null
+      token: named
+    period: .
+    prefix: SimpleIdentifier
+      staticElement: self::@class::A
+      staticType: null
+      token: A
+    staticElement: ConstructorMember
+      base: self::@class::A::@constructor::named
+      substitution: {T: dynamic}
+    staticType: null
+''');
+    _assertAnnotationValueText(annotation, '''
+A<dynamic>
+  f: int 42
+''');
+  }
+
+  test_value_genericClass_staticGetter() async {
+    await resolveTestCode(r'''
+class A<T> {
+  static T get foo {}
+}
+
+@A.foo
+void f() {}
+''');
+
+    var annotation = findNode.annotation('@A');
+    _assertResolvedNodeText(annotation, r'''
+Annotation
+  element: self::@class::A::@getter::foo
+  name: PrefixedIdentifier
+    identifier: SimpleIdentifier
+      staticElement: self::@class::A::@getter::foo
+      staticType: null
+      token: foo
+    period: .
+    prefix: SimpleIdentifier
+      staticElement: self::@class::A
+      staticType: null
+      token: A
+    staticElement: self::@class::A::@getter::foo
+    staticType: null
+''');
+    _assertAnnotationValueText(annotation, '''
+<null>
+''');
+  }
+
+  test_value_genericClass_typeArguments_namedConstructor() async {
+    await assertNoErrorsInCode(r'''
+class A<T> {
+  final T f;
+  const A.named(this.f);
+}
+
+@A<int>.named(42)
+void f() {}
+''');
+
+    var annotation = findNode.annotation('@A');
+    _assertResolvedNodeText(annotation, r'''
+Annotation
+  arguments: ArgumentList
+    arguments
+      IntegerLiteral
+        literal: 42
+        staticType: int
+  constructorName: SimpleIdentifier
+    staticElement: ConstructorMember
+      base: self::@class::A::@constructor::named
+      substitution: {T: int}
+    staticType: null
+    token: named
+  element: ConstructorMember
+    base: self::@class::A::@constructor::named
+    substitution: {T: int}
+  name: SimpleIdentifier
+    staticElement: self::@class::A
+    staticType: null
+    token: A
+  typeArguments: TypeArgumentList
+    arguments
+      TypeName
+        name: SimpleIdentifier
+          staticElement: dart:core::@class::int
+          staticType: null
+          token: int
+        type: int
+''');
+    _assertAnnotationValueText(annotation, '''
+A<int>
+  f: int 42
+''');
+    assertElement2(
+      findNode.integerLiteral('42').staticParameterElement,
+      declaration: findElement.fieldFormalParameter('f'),
+      substitution: {'T': 'int'},
+    );
+  }
+
+  test_value_genericClass_typeArguments_unnamedConstructor() async {
+    await assertNoErrorsInCode(r'''
+ class A<T> {
+  final T f;
+  const A(this.f);
+}
+
+@A<int>(42)
+void f() {}
+''');
+
+    var annotation = findNode.annotation('@A');
+    _assertResolvedNodeText(annotation, r'''
+Annotation
+  arguments: ArgumentList
+    arguments
+      IntegerLiteral
+        literal: 42
+        staticType: int
+  element: ConstructorMember
+    base: self::@class::A::@constructor::•
+    substitution: {T: int}
+  name: SimpleIdentifier
+    staticElement: self::@class::A
+    staticType: null
+    token: A
+  typeArguments: TypeArgumentList
+    arguments
+      TypeName
+        name: SimpleIdentifier
+          staticElement: dart:core::@class::int
+          staticType: null
+          token: int
+        type: int
+''');
+    _assertAnnotationValueText(annotation, r'''
+A<int>
+  f: int 42
+''');
+    assertElement2(
+      findNode.integerLiteral('42').staticParameterElement,
+      declaration: findElement.fieldFormalParameter('f'),
+      substitution: {'T': 'int'},
+    );
+  }
+
+  test_value_genericClass_unnamedConstructor_noGenericMetadata() async {
+    writeTestPackageConfig(PackageConfigFileBuilder(), languageVersion: '2.12');
+    await assertNoErrorsInCode(r'''
+class A<T> {
+  final T f;
+  const A(this.f);
+}
+
+@A(42)
+void f() {}
+''');
+
+    var annotation = findNode.annotation('@A');
+    _assertResolvedNodeText(annotation, r'''
+Annotation
+  arguments: ArgumentList
+    arguments
+      IntegerLiteral
+        literal: 42
+        staticType: int
+  element: ConstructorMember
+    base: self::@class::A::@constructor::•
+    substitution: {T: dynamic}
+  name: SimpleIdentifier
+    staticElement: self::@class::A
+    staticType: null
+    token: A
+''');
+    _assertAnnotationValueText(annotation, r'''
+A<dynamic>
+  f: int 42
+''');
+    assertElement2(
+      findNode.integerLiteral('42').staticParameterElement,
+      declaration: findElement.fieldFormalParameter('f'),
+      substitution: {'T': 'dynamic'},
+    );
+  }
+
+  test_value_otherLibrary_implicitConst() async {
+    newFile('$testPackageLibPath/a.dart', content: r'''
+class A {
+  final int f;
+  const A(this.f);
+}
+
+class B {
+  final A a;
+  const B(this.a);
+}
+
+@B( A(42) )
+class C {}
+''');
+
+    await assertNoErrorsInCode(r'''
+import 'a.dart';
+
+void f(C c) {}
+''');
+
+    var classC = findNode.typeName('C c').name.staticElement!;
+    var annotation = classC.metadata.single;
+    _assertElementAnnotationValueText(annotation, r'''
+B
+  a: A
+    f: int 42
+''');
+  }
+
+  test_value_otherLibrary_namedConstructor() async {
+    newFile('$testPackageLibPath/a.dart', content: r'''
+class A {
+  final int f;
+  const A.named(this.f);
+}
+''');
+
+    newFile('$testPackageLibPath/b.dart', content: r'''
+import 'a.dart';
+
+@A.named(42)
+class B {}
+''');
+
+    await assertNoErrorsInCode(r'''
+import 'b.dart';
+
+void f(B b) {}
+''');
+
+    var classB = findNode.typeName('B b').name.staticElement!;
+    var annotation = classB.metadata.single;
+    _assertElementAnnotationValueText(annotation, r'''
+A
+  f: int 42
+''');
+  }
+
+  test_value_otherLibrary_unnamedConstructor() async {
+    newFile('$testPackageLibPath/a.dart', content: r'''
+class A {
+  final int f;
+  const A(this.f);
+}
+''');
+
+    newFile('$testPackageLibPath/b.dart', content: r'''
+import 'a.dart';
+
+@A(42)
+class B {}
+''');
+
+    await assertNoErrorsInCode(r'''
+import 'b.dart';
+
+void f(B b) {}
+''');
+
+    var classB = findNode.typeName('B b').name.staticElement!;
+    var annotation = classB.metadata.single;
+    _assertElementAnnotationValueText(annotation, r'''
+A
+  f: int 42
+''');
+  }
+
+  test_value_prefix_typeAlias_class_staticConstField() async {
+    newFile('$testPackageLibPath/a.dart', content: r'''
+class A {
+  static const int foo = 42;
+}
+
+typedef B = A;
+''');
+    await assertNoErrorsInCode(r'''
+import 'a.dart' as prefix;
+
+@prefix.B.foo
+void f() {}
+''');
+
+    var annotation = findNode.annotation('@prefix.B');
+    _assertResolvedNodeText(annotation, r'''
+Annotation
+  constructorName: SimpleIdentifier
+    staticElement: package:test/a.dart::@class::A::@getter::foo
+    staticType: null
+    token: foo
+  element: package:test/a.dart::@class::A::@getter::foo
+  name: PrefixedIdentifier
+    identifier: SimpleIdentifier
+      staticElement: package:test/a.dart::@typeAlias::B
+      staticType: null
+      token: B
+    period: .
+    prefix: SimpleIdentifier
+      staticElement: self::@prefix::prefix
+      staticType: null
+      token: prefix
+    staticElement: package:test/a.dart::@typeAlias::B
+    staticType: null
+''');
+    _assertAnnotationValueText(annotation, '''
+int 42
+''');
+  }
+
+  test_value_prefix_typeAlias_generic_class_generic_all_inference_namedConstructor() async {
+    newFile('$testPackageLibPath/a.dart', content: r'''
+class A<T> {
+  final T f;
+  const A.named(this.f);
+}
+
+typedef B<U> = A<U>;
+''');
+    await assertNoErrorsInCode(r'''
+import 'a.dart' as prefix;
+
+@prefix.B.named(42)
+void f() {}
+''');
+
+    var annotation = findNode.annotation('@prefix.B');
+    _assertResolvedNodeText(annotation, r'''
+Annotation
+  arguments: ArgumentList
+    arguments
+      IntegerLiteral
+        literal: 42
+        staticType: int
+  constructorName: SimpleIdentifier
+    staticElement: ConstructorMember
+      base: package:test/a.dart::@class::A::@constructor::named
+      substitution: {T: int}
+    staticType: null
+    token: named
+  element: ConstructorMember
+    base: package:test/a.dart::@class::A::@constructor::named
+    substitution: {T: int}
+  name: PrefixedIdentifier
+    identifier: SimpleIdentifier
+      staticElement: package:test/a.dart::@typeAlias::B
+      staticType: null
+      token: B
+    period: .
+    prefix: SimpleIdentifier
+      staticElement: self::@prefix::prefix
+      staticType: null
+      token: prefix
+    staticElement: package:test/a.dart::@typeAlias::B
+    staticType: null
+''');
+    _assertAnnotationValueText(annotation, r'''
+A<int>
+  f: int 42
+''');
+
+    assertElement2(
+      findNode.integerLiteral('42').staticParameterElement,
+      declaration: findElement.importFind('package:test/a.dart').parameter('f'),
+      substitution: {'T': 'int'},
+    );
+  }
+
+  test_value_prefix_typeAlias_generic_class_generic_all_inference_unnamedConstructor() async {
+    newFile('$testPackageLibPath/a.dart', content: r'''
+class A<T> {
+  final T f;
+  const A(this.f);
+}
+
+typedef B<U> = A<U>;
+''');
+    await assertNoErrorsInCode(r'''
+import 'a.dart' as prefix;
+
+@prefix.B(42)
+void f() {}
+''');
+
+    var annotation = findNode.annotation('@prefix.B');
+    _assertResolvedNodeText(annotation, r'''
+Annotation
+  arguments: ArgumentList
+    arguments
+      IntegerLiteral
+        literal: 42
+        staticType: int
+  element: ConstructorMember
+    base: package:test/a.dart::@class::A::@constructor::•
+    substitution: {T: int}
+  name: PrefixedIdentifier
+    identifier: SimpleIdentifier
+      staticElement: package:test/a.dart::@typeAlias::B
+      staticType: null
+      token: B
+    period: .
+    prefix: SimpleIdentifier
+      staticElement: self::@prefix::prefix
+      staticType: null
+      token: prefix
+    staticElement: package:test/a.dart::@typeAlias::B
+    staticType: null
+''');
+    _assertAnnotationValueText(annotation, r'''
+A<int>
+  f: int 42
+''');
+
+    assertElement2(
+      findNode.integerLiteral('42').staticParameterElement,
+      declaration: findElement.importFind('package:test/a.dart').parameter('f'),
+      substitution: {'T': 'int'},
+    );
+  }
+
+  test_value_prefix_typeAlias_generic_class_generic_all_typeArguments_namedConstructor() async {
+    newFile('$testPackageLibPath/a.dart', content: r'''
+class A<T> {
+  final T f;
+  const A.named(this.f);
+}
+
+typedef B<U> = A<U>;
+''');
+    await assertNoErrorsInCode(r'''
+import 'a.dart' as prefix;
+
+@prefix.B<int>.named(42)
+void f() {}
+''');
+
+    var annotation = findNode.annotation('@prefix.B');
+    _assertResolvedNodeText(annotation, r'''
+Annotation
+  arguments: ArgumentList
+    arguments
+      IntegerLiteral
+        literal: 42
+        staticType: int
+  constructorName: SimpleIdentifier
+    staticElement: ConstructorMember
+      base: package:test/a.dart::@class::A::@constructor::named
+      substitution: {T: int}
+    staticType: null
+    token: named
+  element: ConstructorMember
+    base: package:test/a.dart::@class::A::@constructor::named
+    substitution: {T: int}
+  name: PrefixedIdentifier
+    identifier: SimpleIdentifier
+      staticElement: package:test/a.dart::@typeAlias::B
+      staticType: null
+      token: B
+    period: .
+    prefix: SimpleIdentifier
+      staticElement: self::@prefix::prefix
+      staticType: null
+      token: prefix
+    staticElement: package:test/a.dart::@typeAlias::B
+    staticType: null
+  typeArguments: TypeArgumentList
+    arguments
+      TypeName
+        name: SimpleIdentifier
+          staticElement: dart:core::@class::int
+          staticType: null
+          token: int
+        type: int
+''');
+    _assertAnnotationValueText(annotation, r'''
+A<int>
+  f: int 42
+''');
+
+    assertElement2(
+      findNode.integerLiteral('42').staticParameterElement,
+      declaration: findElement.importFind('package:test/a.dart').parameter('f'),
+      substitution: {'T': 'int'},
+    );
+  }
+
+  test_value_prefix_typeAlias_generic_class_generic_all_typeArguments_unnamedConstructor() async {
+    newFile('$testPackageLibPath/a.dart', content: r'''
+class A<T> {
+  final T f;
+  const A(this.f);
+}
+
+typedef B<U> = A<U>;
+''');
+    await assertNoErrorsInCode(r'''
+import 'a.dart' as prefix;
+
+@prefix.B<int>(42)
+void f() {}
+''');
+
+    var annotation = findNode.annotation('@prefix.B');
+    _assertResolvedNodeText(annotation, r'''
+Annotation
+  arguments: ArgumentList
+    arguments
+      IntegerLiteral
+        literal: 42
+        staticType: int
+  element: ConstructorMember
+    base: package:test/a.dart::@class::A::@constructor::•
+    substitution: {T: int}
+  name: PrefixedIdentifier
+    identifier: SimpleIdentifier
+      staticElement: package:test/a.dart::@typeAlias::B
+      staticType: null
+      token: B
+    period: .
+    prefix: SimpleIdentifier
+      staticElement: self::@prefix::prefix
+      staticType: null
+      token: prefix
+    staticElement: package:test/a.dart::@typeAlias::B
+    staticType: null
+  typeArguments: TypeArgumentList
+    arguments
+      TypeName
+        name: SimpleIdentifier
+          staticElement: dart:core::@class::int
+          staticType: null
+          token: int
+        type: int
+''');
+    _assertAnnotationValueText(annotation, r'''
+A<int>
+  f: int 42
+''');
+
+    assertElement2(
+      findNode.integerLiteral('42').staticParameterElement,
+      declaration: findElement.importFind('package:test/a.dart').parameter('f'),
+      substitution: {'T': 'int'},
+    );
+  }
+
+  test_value_typeAlias_class_staticConstField() async {
+    await assertNoErrorsInCode(r'''
+class A {
+  static const int foo = 42;
+}
+
+typedef B = A;
+
+@B.foo
+void f() {}
+''');
+
+    var annotation = findNode.annotation('@B');
+    _assertResolvedNodeText(annotation, r'''
+Annotation
+  element: self::@class::A::@getter::foo
+  name: PrefixedIdentifier
+    identifier: SimpleIdentifier
+      staticElement: self::@class::A::@getter::foo
+      staticType: null
+      token: foo
+    period: .
+    prefix: SimpleIdentifier
+      staticElement: self::@typeAlias::B
+      staticType: null
+      token: B
+    staticElement: self::@class::A::@getter::foo
+    staticType: null
+''');
+    _assertAnnotationValueText(annotation, '''
+int 42
+''');
+  }
+
+  test_value_typeAlias_generic_class_generic_1of2_typeArguments_namedConstructor() async {
+    await assertNoErrorsInCode(r'''
+class A<T, U> {
+  final T t;
+  final U u;
+  const A.named(this.t, this.u);
+}
+
+typedef B<T> = A<T, double>;
+
+@B<int>.named(42, 1.2)
+void f() {}
+''');
+
+    var annotation = findNode.annotation('@B');
+    _assertResolvedNodeText(annotation, r'''
+Annotation
+  arguments: ArgumentList
+    arguments
+      IntegerLiteral
+        literal: 42
+        staticType: int
+      DoubleLiteral
+        literal: 1.2
+        staticType: double
+  constructorName: SimpleIdentifier
+    staticElement: ConstructorMember
+      base: self::@class::A::@constructor::named
+      substitution: {T: int, U: double}
+    staticType: null
+    token: named
+  element: ConstructorMember
+    base: self::@class::A::@constructor::named
+    substitution: {T: int, U: double}
+  name: SimpleIdentifier
+    staticElement: self::@typeAlias::B
+    staticType: null
+    token: B
+  typeArguments: TypeArgumentList
+    arguments
+      TypeName
+        name: SimpleIdentifier
+          staticElement: dart:core::@class::int
+          staticType: null
+          token: int
+        type: int
+''');
+    _assertAnnotationValueText(annotation, r'''
+A<int, double>
+  t: int 42
+  u: double 1.2
+''');
+
+    assertElement2(
+      findNode.integerLiteral('42').staticParameterElement,
+      declaration: findElement.fieldFormalParameter('t'),
+      substitution: {'T': 'int', 'U': 'double'},
+    );
+
+    assertElement2(
+      findNode.doubleLiteral('1.2').staticParameterElement,
+      declaration: findElement.fieldFormalParameter('u'),
+      substitution: {'T': 'int', 'U': 'double'},
+    );
+  }
+
+  test_value_typeAlias_generic_class_generic_1of2_typeArguments_unnamedConstructor() async {
+    await assertNoErrorsInCode(r'''
+class A<T, U> {
+  final T t;
+  final U u;
+  const A(this.t, this.u);
+}
+
+typedef B<T> = A<T, double>;
+
+@B<int>(42, 1.2)
+void f() {}
+''');
+
+    var annotation = findNode.annotation('@B');
+    _assertResolvedNodeText(annotation, r'''
+Annotation
+  arguments: ArgumentList
+    arguments
+      IntegerLiteral
+        literal: 42
+        staticType: int
+      DoubleLiteral
+        literal: 1.2
+        staticType: double
+  element: ConstructorMember
+    base: self::@class::A::@constructor::•
+    substitution: {T: int, U: double}
+  name: SimpleIdentifier
+    staticElement: self::@typeAlias::B
+    staticType: null
+    token: B
+  typeArguments: TypeArgumentList
+    arguments
+      TypeName
+        name: SimpleIdentifier
+          staticElement: dart:core::@class::int
+          staticType: null
+          token: int
+        type: int
+''');
+    _assertAnnotationValueText(annotation, r'''
+A<int, double>
+  t: int 42
+  u: double 1.2
+''');
+
+    assertElement2(
+      findNode.integerLiteral('42').staticParameterElement,
+      declaration: findElement.fieldFormalParameter('t'),
+      substitution: {'T': 'int', 'U': 'double'},
+    );
+
+    assertElement2(
+      findNode.doubleLiteral('1.2').staticParameterElement,
+      declaration: findElement.fieldFormalParameter('u'),
+      substitution: {'T': 'int', 'U': 'double'},
+    );
+  }
+
+  test_value_typeAlias_generic_class_generic_all_inference_namedConstructor() async {
+    await assertNoErrorsInCode(r'''
+class A<T> {
+  final T f;
+  const A.named(this.f);
+}
+
+typedef B<U> = A<U>;
+
+@B.named(42)
+void f() {}
+''');
+
+    var annotation = findNode.annotation('@B');
+    _assertResolvedNodeText(annotation, r'''
+Annotation
+  arguments: ArgumentList
+    arguments
+      IntegerLiteral
+        literal: 42
+        staticType: int
+  element: ConstructorMember
+    base: self::@class::A::@constructor::named
+    substitution: {T: int}
+  name: PrefixedIdentifier
+    identifier: SimpleIdentifier
+      staticElement: ConstructorMember
+        base: self::@class::A::@constructor::named
+        substitution: {T: int}
+      staticType: null
+      token: named
+    period: .
+    prefix: SimpleIdentifier
+      staticElement: self::@typeAlias::B
+      staticType: null
+      token: B
+    staticElement: ConstructorMember
+      base: self::@class::A::@constructor::named
+      substitution: {T: int}
+    staticType: null
+''');
+    _assertAnnotationValueText(annotation, r'''
+A<int>
+  f: int 42
+''');
+
+    assertElement2(
+      findNode.integerLiteral('42').staticParameterElement,
+      declaration: findElement.fieldFormalParameter('f'),
+      substitution: {'T': 'int'},
+    );
+  }
+
+  test_value_typeAlias_generic_class_generic_all_inference_unnamedConstructor() async {
+    await assertNoErrorsInCode(r'''
+class A<T> {
+  final T f;
+  const A(this.f);
+}
+
+typedef B<U> = A<U>;
+
+@B(42)
+void f() {}
+''');
+
+    var annotation = findNode.annotation('@B');
+    _assertResolvedNodeText(annotation, r'''
+Annotation
+  arguments: ArgumentList
+    arguments
+      IntegerLiteral
+        literal: 42
+        staticType: int
+  element: ConstructorMember
+    base: self::@class::A::@constructor::•
+    substitution: {T: int}
+  name: SimpleIdentifier
+    staticElement: self::@typeAlias::B
+    staticType: null
+    token: B
+''');
+    _assertAnnotationValueText(annotation, r'''
+A<int>
+  f: int 42
+''');
+
+    assertElement2(
+      findNode.integerLiteral('42').staticParameterElement,
+      declaration: findElement.fieldFormalParameter('f'),
+      substitution: {'T': 'int'},
+    );
+  }
+
+  test_value_typeAlias_generic_class_generic_all_typeArguments_namedConstructor() async {
+    await assertNoErrorsInCode(r'''
+class A<T> {
+  final T f;
+  const A.named(this.f);
+}
+
+typedef B<U> = A<U>;
+
+@B<int>.named(42)
+void f() {}
+''');
+
+    var annotation = findNode.annotation('@B');
+    _assertResolvedNodeText(annotation, r'''
+Annotation
+  arguments: ArgumentList
+    arguments
+      IntegerLiteral
+        literal: 42
+        staticType: int
+  constructorName: SimpleIdentifier
+    staticElement: ConstructorMember
+      base: self::@class::A::@constructor::named
+      substitution: {T: int}
+    staticType: null
+    token: named
+  element: ConstructorMember
+    base: self::@class::A::@constructor::named
+    substitution: {T: int}
+  name: SimpleIdentifier
+    staticElement: self::@typeAlias::B
+    staticType: null
+    token: B
+  typeArguments: TypeArgumentList
+    arguments
+      TypeName
+        name: SimpleIdentifier
+          staticElement: dart:core::@class::int
+          staticType: null
+          token: int
+        type: int
+''');
+    _assertAnnotationValueText(annotation, r'''
+A<int>
+  f: int 42
+''');
+
+    assertElement2(
+      findNode.integerLiteral('42').staticParameterElement,
+      declaration: findElement.fieldFormalParameter('f'),
+      substitution: {'T': 'int'},
+    );
+  }
+
+  test_value_typeAlias_generic_class_generic_all_typeArguments_unnamedConstructor() async {
+    await assertNoErrorsInCode(r'''
+class A<T> {
+  final T f;
+  const A(this.f);
+}
+
+typedef B<U> = A<U>;
+
+@B<int>(42)
+void f() {}
+''');
+
+    var annotation = findNode.annotation('@B');
+    _assertResolvedNodeText(annotation, r'''
+Annotation
+  arguments: ArgumentList
+    arguments
+      IntegerLiteral
+        literal: 42
+        staticType: int
+  element: ConstructorMember
+    base: self::@class::A::@constructor::•
+    substitution: {T: int}
+  name: SimpleIdentifier
+    staticElement: self::@typeAlias::B
+    staticType: null
+    token: B
+  typeArguments: TypeArgumentList
+    arguments
+      TypeName
+        name: SimpleIdentifier
+          staticElement: dart:core::@class::int
+          staticType: null
+          token: int
+        type: int
+''');
+    _assertAnnotationValueText(annotation, r'''
+A<int>
+  f: int 42
+''');
+
+    assertElement2(
+      findNode.integerLiteral('42').staticParameterElement,
+      declaration: findElement.fieldFormalParameter('f'),
+      substitution: {'T': 'int'},
+    );
+  }
+
+  test_value_typeAlias_notGeneric_class_generic_namedConstructor() async {
+    await assertNoErrorsInCode(r'''
+class A<T> {
+  final T f;
+  const A.named(this.f);
+}
+
+typedef B = A<int>;
+
+@B.named(42)
+void f() {}
+''');
+
+    var annotation = findNode.annotation('@B');
+    _assertResolvedNodeText(annotation, r'''
+Annotation
+  arguments: ArgumentList
+    arguments
+      IntegerLiteral
+        literal: 42
+        staticType: int
+  element: ConstructorMember
+    base: self::@class::A::@constructor::named
+    substitution: {T: int}
+  name: PrefixedIdentifier
+    identifier: SimpleIdentifier
+      staticElement: ConstructorMember
+        base: self::@class::A::@constructor::named
+        substitution: {T: int}
+      staticType: null
+      token: named
+    period: .
+    prefix: SimpleIdentifier
+      staticElement: self::@typeAlias::B
+      staticType: null
+      token: B
+    staticElement: ConstructorMember
+      base: self::@class::A::@constructor::named
+      substitution: {T: int}
+    staticType: null
+''');
+    _assertAnnotationValueText(annotation, r'''
+A<int>
+  f: int 42
+''');
+
+    assertElement2(
+      findNode.integerLiteral('42').staticParameterElement,
+      declaration: findElement.fieldFormalParameter('f'),
+      substitution: {'T': 'int'},
+    );
+  }
+
+  test_value_typeAlias_notGeneric_class_generic_unnamedConstructor() async {
+    await assertNoErrorsInCode(r'''
+class A<T> {
+  final T f;
+  const A(this.f);
+}
+
+typedef B = A<int>;
+
+@B(42)
+void f() {}
+''');
+
+    var annotation = findNode.annotation('@B');
+    _assertResolvedNodeText(annotation, r'''
+Annotation
+  arguments: ArgumentList
+    arguments
+      IntegerLiteral
+        literal: 42
+        staticType: int
+  element: ConstructorMember
+    base: self::@class::A::@constructor::•
+    substitution: {T: int}
+  name: SimpleIdentifier
+    staticElement: self::@typeAlias::B
+    staticType: null
+    token: B
+''');
+    _assertAnnotationValueText(annotation, r'''
+A<int>
+  f: int 42
+''');
+
+    assertElement2(
+      findNode.integerLiteral('42').staticParameterElement,
+      declaration: findElement.fieldFormalParameter('f'),
+      substitution: {'T': 'int'},
+    );
+  }
+
+  test_value_typeAlias_notGeneric_class_notGeneric_namedConstructor() async {
+    await assertNoErrorsInCode(r'''
+class A {
+  final int f;
+  const A.named(this.f);
+}
+
+typedef B = A;
+
+@B.named(42)
+void f() {}
+''');
+
+    var annotation = findNode.annotation('@B');
+    _assertResolvedNodeText(annotation, r'''
+Annotation
+  arguments: ArgumentList
+    arguments
+      IntegerLiteral
+        literal: 42
+        staticType: int
+  element: self::@class::A::@constructor::named
+  name: PrefixedIdentifier
+    identifier: SimpleIdentifier
+      staticElement: self::@class::A::@constructor::named
+      staticType: null
+      token: named
+    period: .
+    prefix: SimpleIdentifier
+      staticElement: self::@typeAlias::B
+      staticType: null
+      token: B
+    staticElement: self::@class::A::@constructor::named
+    staticType: null
+''');
+    _assertAnnotationValueText(annotation, r'''
+A
+  f: int 42
+''');
+
+    assertElement2(
+      findNode.integerLiteral('42').staticParameterElement,
+      declaration: findElement.fieldFormalParameter('f'),
+    );
+  }
+
+  test_value_typeAlias_notGeneric_class_notGeneric_unnamedConstructor() async {
+    await assertNoErrorsInCode(r'''
+class A {
+  final int f;
+  const A(this.f);
+}
+
+typedef B = A;
+
+@B(42)
+void f() {}
+''');
+
+    var annotation = findNode.annotation('@B');
+    _assertResolvedNodeText(annotation, r'''
+Annotation
+  arguments: ArgumentList
+    arguments
+      IntegerLiteral
+        literal: 42
+        staticType: int
+  element: self::@class::A::@constructor::•
+  name: SimpleIdentifier
+    staticElement: self::@typeAlias::B
+    staticType: null
+    token: B
+''');
+    _assertAnnotationValueText(annotation, r'''
+A
+  f: int 42
+''');
+
+    assertElement2(
+      findNode.integerLiteral('42').staticParameterElement,
+      declaration: findElement.fieldFormalParameter('f'),
+    );
+  }
+
+  void _assertAnnotationValueText(Annotation annotation, String expected) {
+    var elementAnnotation = annotation.elementAnnotation!;
+    _assertElementAnnotationValueText(elementAnnotation, expected);
+  }
+
+  void _assertDartObjectText(DartObject? object, String expected) {
+    var buffer = StringBuffer();
+    _DartObjectPrinter(buffer).write(object as DartObjectImpl?, '');
+    var actual = buffer.toString();
+    if (actual != expected) {
+      print(buffer);
+    }
+    expect(actual, expected);
+  }
+
+  void _assertElementAnnotationValueText(
+    ElementAnnotation annotation,
+    String expected,
+  ) {
+    var value = annotation.computeConstantValue();
+    _assertDartObjectText(value, expected);
+  }
+
+  void _assertResolvedNodeText(AstNode node, String expected) {
+    var actual = _resolvedNodeText(node);
+    if (actual != expected) {
+      print(actual);
+    }
+    expect(actual, expected);
+  }
+
+  String _resolvedNodeText(AstNode node) {
+    var buffer = StringBuffer();
+    node.accept(
+      ResolvedAstPrinter(
+        selfUriStr: result.uri.toString(),
+        sink: buffer,
+        indent: '',
+      ),
+    );
+    return buffer.toString();
+  }
+}
+
+class _DartObjectPrinter {
+  final StringBuffer sink;
+
+  _DartObjectPrinter(this.sink);
+
+  void write(DartObjectImpl? object, String indent) {
+    if (object != null) {
+      var type = object.type;
+      if (type.isDartCoreDouble) {
+        sink.write('double ');
+        sink.writeln(object.toDoubleValue());
+      } else if (type.isDartCoreInt) {
+        sink.write('int ');
+        sink.writeln(object.toIntValue());
+      } else if (object.isUserDefinedObject) {
+        var newIndent = '$indent  ';
+        var typeStr = type.getDisplayString(withNullability: true);
+        sink.writeln(typeStr);
+        var fields = object.fields;
+        if (fields != null) {
+          var sortedFields = SplayTreeMap.of(fields);
+          for (var entry in sortedFields.entries) {
+            sink.write(newIndent);
+            sink.write('${entry.key}: ');
+            write(entry.value, newIndent);
+          }
+        }
+      } else {
+        throw UnimplementedError();
+      }
+    } else {
+      sink.writeln('<null>');
+    }
+  }
 }
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 60d4e16..28b1f8c 100644
--- a/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart
@@ -1000,7 +1000,7 @@
 }
 ''', [
       if (typeToStringWithNullability)
-        error(CompileTimeErrorCode.INVALID_USE_OF_NULL_VALUE, 11, 4)
+        error(CompileTimeErrorCode.INVALID_USE_OF_NULL_VALUE, 16, 3)
       else
         error(CompileTimeErrorCode.UNDEFINED_METHOD, 16, 3),
     ]);
@@ -1155,9 +1155,6 @@
   c.foo();
 }
 ''', [
-      if (typeToStringWithNullability)
-        error(
-            CompileTimeErrorCode.UNCHECKED_INVOCATION_OF_NULLABLE_VALUE, 61, 5),
       error(CompileTimeErrorCode.USE_OF_VOID_RESULT, 61, 5),
     ]);
 
@@ -1179,9 +1176,6 @@
   foo();
 }
 ''', [
-      if (typeToStringWithNullability)
-        error(
-            CompileTimeErrorCode.UNCHECKED_INVOCATION_OF_NULLABLE_VALUE, 23, 3),
       error(CompileTimeErrorCode.USE_OF_VOID_RESULT, 23, 3),
     ]);
 
@@ -1203,9 +1197,6 @@
   foo()();
 }
 ''', [
-      if (typeToStringWithNullability)
-        error(
-            CompileTimeErrorCode.UNCHECKED_INVOCATION_OF_NULLABLE_VALUE, 26, 5),
       error(CompileTimeErrorCode.USE_OF_VOID_RESULT, 26, 3),
     ]);
     assertMethodInvocation(
@@ -1223,9 +1214,6 @@
   foo();
 }
 ''', [
-      if (typeToStringWithNullability)
-        error(
-            CompileTimeErrorCode.UNCHECKED_INVOCATION_OF_NULLABLE_VALUE, 22, 3),
       error(CompileTimeErrorCode.USE_OF_VOID_RESULT, 22, 3),
     ]);
 
@@ -2498,7 +2486,7 @@
 }
 ''', [
       error(CompileTimeErrorCode.UNCHECKED_METHOD_INVOCATION_OF_NULLABLE_VALUE,
-          26, 3),
+          30, 4),
     ]);
 
     assertMethodInvocation2(
@@ -2550,7 +2538,7 @@
 }
 ''', [
       error(CompileTimeErrorCode.UNCHECKED_METHOD_INVOCATION_OF_NULLABLE_VALUE,
-          46, 1),
+          48, 3),
     ]);
 
     assertMethodInvocation2(
@@ -2577,7 +2565,7 @@
 }
 ''', [
       error(CompileTimeErrorCode.UNCHECKED_METHOD_INVOCATION_OF_NULLABLE_VALUE,
-          84, 1),
+          86, 3),
     ]);
 
     assertMethodInvocation2(
@@ -2645,7 +2633,7 @@
 }
 ''', [
       error(CompileTimeErrorCode.UNCHECKED_METHOD_INVOCATION_OF_NULLABLE_VALUE,
-          29, 1),
+          31, 3),
     ]);
 
     assertMethodInvocation2(
@@ -2670,7 +2658,7 @@
 }
 ''', [
       error(CompileTimeErrorCode.UNCHECKED_METHOD_INVOCATION_OF_NULLABLE_VALUE,
-          67, 1),
+          69, 3),
     ]);
 
     assertMethodInvocation2(
@@ -2772,6 +2760,30 @@
     );
   }
 
+  test_hasReceiver_typeParameter_promotedToOtherTypeParameter() async {
+    await assertNoErrorsInCode('''
+abstract class A {}
+
+abstract class B extends A {
+  void foo();
+}
+
+void f<T extends A, U extends B>(T a) {
+  if (a is U) {
+    a.foo();
+  }
+}
+''');
+
+    assertMethodInvocation2(
+      findNode.methodInvocation('a.foo()'),
+      element: findElement.method('foo'),
+      typeArgumentTypes: [],
+      invokeType: 'void Function()',
+      type: 'void',
+    );
+  }
+
   test_nullShorting_cascade_firstMethodInvocation() async {
     await assertNoErrorsInCode(r'''
 class A {
diff --git a/pkg/analyzer/test/src/dart/resolution/mixin_test.dart b/pkg/analyzer/test/src/dart/resolution/mixin_test.dart
index 7c8bd6a..71db9f6 100644
--- a/pkg/analyzer/test/src/dart/resolution/mixin_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/mixin_test.dart
@@ -359,15 +359,6 @@
     assertTypeName(typeRef, null, 'void');
   }
 
-  test_error_implementsRepeated() async {
-    await assertErrorsInCode(r'''
-class A {}
-mixin M implements A, A {}
-''', [
-      error(CompileTimeErrorCode.IMPLEMENTS_REPEATED, 33, 1),
-    ]);
-  }
-
   test_error_memberWithClassName_getter() async {
     await assertErrorsInCode(r'''
 mixin M {
@@ -939,15 +930,6 @@
     ]);
   }
 
-  test_error_onRepeated() async {
-    await assertErrorsInCode(r'''
-class A {}
-mixin M on A, A {}
-''', [
-      error(CompileTimeErrorCode.ON_REPEATED, 25, 1),
-    ]);
-  }
-
   test_error_undefinedSuperMethod() async {
     await assertErrorsInCode(r'''
 class A {}
diff --git a/pkg/analyzer/test/src/dart/resolution/prefix_expression_test.dart b/pkg/analyzer/test/src/dart/resolution/prefix_expression_test.dart
index eb49c3f..c49b4a6 100644
--- a/pkg/analyzer/test/src/dart/resolution/prefix_expression_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/prefix_expression_test.dart
@@ -675,7 +675,7 @@
 }
 ''', [
       error(CompileTimeErrorCode.UNCHECKED_METHOD_INVOCATION_OF_NULLABLE_VALUE,
-          51, 6),
+          50, 1),
     ]);
 
     assertPrefixExpression(
@@ -750,7 +750,7 @@
 }
 ''', [
       error(CompileTimeErrorCode.UNCHECKED_METHOD_INVOCATION_OF_NULLABLE_VALUE,
-          51, 6),
+          50, 1),
     ]);
 
     assertPrefixExpression(
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 9c22823..b95d627 100644
--- a/pkg/analyzer/test/src/dart/resolution/property_access_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/property_access_test.dart
@@ -522,7 +522,7 @@
     assertErrorsInResult(expectedErrorsByNullability(
       nullable: [
         error(CompileTimeErrorCode.UNCHECKED_PROPERTY_ACCESS_OF_NULLABLE_VALUE,
-            33, 3),
+            37, 3),
       ],
       legacy: [
         error(CompileTimeErrorCode.UNDEFINED_GETTER, 37, 3),
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 89086df..733a4aa 100644
--- a/pkg/analyzer/test/src/dart/resolution/type_name_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/type_name_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/ast/extensions.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/test_utilities/find_element.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -310,7 +311,6 @@
     );
   }
 
-  @FailingTest(reason: 'We attempt to do type inference on A')
   test_typeAlias_asInstanceCreation_implicitNew_toBounds_noTypeParameters_interfaceType_none() async {
     await assertNoErrorsInCode(r'''
 class A<T> {}
@@ -615,7 +615,7 @@
     assertTypeName(typeName, element, 'int* Function(bool*)*');
 
     assertTypeAlias(
-      typeName.type!,
+      typeName.typeOrThrow,
       element: element,
       typeArguments: [],
     );
@@ -639,7 +639,7 @@
     assertTypeName(typeName, element, 'dynamic Function(bool*)*');
 
     assertTypeAlias(
-      typeName.type!,
+      typeName.typeOrThrow,
       element: element,
       typeArguments: ['dynamic'],
     );
@@ -663,7 +663,7 @@
     assertTypeName(typeName, element, 'num* Function(bool*)*');
 
     assertTypeAlias(
-      typeName.type!,
+      typeName.typeOrThrow,
       element: element,
       typeArguments: ['num*'],
     );
@@ -687,7 +687,7 @@
     assertTypeName(typeName, element, 'int* Function(bool*)*');
 
     assertTypeAlias(
-      typeName.type!,
+      typeName.typeOrThrow,
       element: element,
       typeArguments: ['int*'],
     );
diff --git a/pkg/analyzer/test/src/diagnostics/abstract_super_member_reference_test.dart b/pkg/analyzer/test/src/diagnostics/abstract_super_member_reference_test.dart
index 4a78f7c..762abe6 100644
--- a/pkg/analyzer/test/src/diagnostics/abstract_super_member_reference_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/abstract_super_member_reference_test.dart
@@ -378,6 +378,34 @@
     }
   }
 
+  test_propertyAccess_setter_mixin_implements() async {
+    await assertErrorsInCode(r'''
+class A {
+  set foo(int _) {}
+}
+
+mixin M implements A {
+  void bar() {
+    super.foo = 0;
+  }
+}
+''', [
+      error(CompileTimeErrorCode.ABSTRACT_SUPER_MEMBER_REFERENCE, 81, 3),
+    ]);
+
+    assertSuperExpression(findNode.super_('super.foo'));
+
+    assertAssignment(
+      findNode.assignment('foo ='),
+      readElement: null,
+      readType: null,
+      writeElement: findElement.setter('foo'),
+      writeType: 'int',
+      operatorElement: null,
+      type: 'int',
+    );
+  }
+
   test_propertyAccess_setter_mixinHasNoSuchMethod() async {
     await assertErrorsInCode('''
 class A {
diff --git a/pkg/analyzer/test/src/diagnostics/ambiguous_extension_member_access_test.dart b/pkg/analyzer/test/src/diagnostics/ambiguous_extension_member_access_test.dart
index eb82661..424912e 100644
--- a/pkg/analyzer/test/src/diagnostics/ambiguous_extension_member_access_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/ambiguous_extension_member_access_test.dart
@@ -30,7 +30,6 @@
 int f(A a) => a();
 ''', [
       error(CompileTimeErrorCode.AMBIGUOUS_EXTENSION_MEMBER_ACCESS, 110, 1),
-      error(CompileTimeErrorCode.INVOCATION_OF_NON_FUNCTION_EXPRESSION, 110, 1),
     ]);
   }
 
diff --git a/pkg/analyzer/test/src/diagnostics/argument_type_not_assignable_test.dart b/pkg/analyzer/test/src/diagnostics/argument_type_not_assignable_test.dart
index 1ce8a4b..096fcdc 100644
--- a/pkg/analyzer/test/src/diagnostics/argument_type_not_assignable_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/argument_type_not_assignable_test.dart
@@ -11,13 +11,103 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(ArgumentTypeNotAssignableTest);
-    defineReflectiveTests(ArgumentTypeNotAssignableWithNullSafetyTest);
+    defineReflectiveTests(ArgumentTypeNotAssignableWithoutNullSafetyTest);
   });
 }
 
 @reflectiveTest
 class ArgumentTypeNotAssignableTest extends PubPackageResolutionTest
-    with WithoutNullSafetyMixin {
+    with ArgumentTypeNotAssignableTestCases {
+  test_annotation_namedConstructor_generic() async {
+    await assertErrorsInCode('''
+class A<T> {
+  const A.fromInt(T p);
+}
+@A<int>.fromInt('0')
+main() {
+}''', [
+      error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 55, 3),
+    ]);
+  }
+
+  test_binary_eqEq_covariantParameterType() async {
+    await assertErrorsInCode(r'''
+class A {
+  bool operator==(covariant A other) => false;
+}
+
+void f(A a, A? aq) {
+  a == 0;
+  aq == 1;
+  aq == aq;
+  aq == null;
+}
+''', [
+      error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 88, 1),
+      error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 99, 1),
+    ]);
+  }
+
+  test_downcast() async {
+    await assertErrorsInCode(r'''
+m() {
+  num y = 1;
+  n(y);
+}
+n(int x) {}
+''', [
+      error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 23, 1),
+    ]);
+  }
+
+  test_downcast_nullableNonNullable() async {
+    await assertErrorsInCode(r'''
+m() {
+  int? y;
+  n(y);
+}
+n(int x) {}
+''', [
+      error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 20, 1),
+    ]);
+  }
+
+  test_dynamicCast() async {
+    await assertNoErrorsInCode(r'''
+m() {
+  dynamic i;
+  n(i);
+}
+n(int i) {}
+''');
+  }
+
+  test_invocation_functionTypes_optional() async {
+    await assertErrorsInCode('''
+void acceptFunOptBool(void funNumOptBool([bool b])) {}
+void funBool(bool b) {}
+main() {
+  acceptFunOptBool(funBool);
+}''', [
+      error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 107, 7),
+    ]);
+  }
+
+  test_invocation_functionTypes_optional_method() async {
+    await assertErrorsInCode('''
+void acceptFunOptBool(void funOptBool([bool b])) {}
+class C {
+  static void funBool(bool b) {}
+}
+main() {
+  acceptFunOptBool(C.funBool);
+}''', [
+      error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 125, 9),
+    ]);
+  }
+}
+
+mixin ArgumentTypeNotAssignableTestCases on PubPackageResolutionTest {
   test_ambiguousClassName() async {
     // See dartbug.com/19624
     newFile('$testPackageLibPath/lib2.dart', content: '''
@@ -290,30 +380,6 @@
     ]);
   }
 
-  test_invocation_functionTypes_optional() async {
-    await assertErrorsInCode('''
-void acceptFunOptBool(void funNumOptBool([bool b])) {}
-void funBool(bool b) {}
-main() {
-  acceptFunOptBool(funBool);
-}''', [
-      error(CompileTimeErrorCode.INVALID_CAST_FUNCTION, 107, 7),
-    ]);
-  }
-
-  test_invocation_functionTypes_optional_method() async {
-    await assertErrorsInCode('''
-void acceptFunOptBool(void funOptBool([bool b])) {}
-class C {
-  static void funBool(bool b) {}
-}
-main() {
-  acceptFunOptBool(C.funBool);
-}''', [
-      error(CompileTimeErrorCode.INVALID_CAST_METHOD, 125, 9),
-    ]);
-  }
-
   test_invocation_generic() async {
     await assertErrorsInCode('''
 class A<T> {
@@ -388,6 +454,40 @@
     ]);
   }
 
+  test_map_indexGet() async {
+    // Any type may be passed to Map.operator[].
+    await assertNoErrorsInCode('''
+main() {
+  Map<int, int> m = <int, int>{};
+  m['x'];
+}
+''');
+  }
+
+  test_map_indexSet() async {
+    // The type passed to Map.operator[]= must match the key type.
+    await assertErrorsInCode('''
+main() {
+  Map<int, int> m = <int, int>{};
+  m['x'] = 0;
+}
+''', [
+      error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 47, 3),
+    ]);
+  }
+
+  test_map_indexSet_ifNull() async {
+    // The type passed to Map.operator[]= must match the key type.
+    await assertErrorsInCode('''
+main() {
+  Map<int, int> m = <int, int>{};
+  m['x'] ??= 0;
+}
+''', [
+      error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 47, 3),
+    ]);
+  }
+
   test_new_generic() async {
     await assertErrorsInCode('''
 class A<T> {
@@ -441,69 +541,20 @@
 }
 
 @reflectiveTest
-class ArgumentTypeNotAssignableWithNullSafetyTest
-    extends ArgumentTypeNotAssignableTest with WithNullSafetyMixin {
-  test_binary_eqEq_covariantParameterType() async {
-    await assertErrorsInCode(r'''
-class A {
-  bool operator==(covariant A other) => false;
-}
-
-void f(A a, A? aq) {
-  a == 0;
-  aq == 1;
-  aq == aq;
-  aq == null;
-}
-''', [
-      error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 88, 1),
-      error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 99, 1),
-    ]);
-  }
-
-  test_downcast() async {
-    await assertErrorsInCode(r'''
-m() {
-  num y = 1;
-  n(y);
-}
-n(int x) {}
-''', [
-      error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 23, 1),
-    ]);
-  }
-
-  @failingTest
-  test_downcast_nullableNonNullable() async {
-    await assertErrorsInCode(r'''
-m() {
-  int? y;
-  n(y);
-}
-n(int x) {}
-''', [
-      error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 24, 1),
-    ]);
-  }
-
-  test_dynamicCast() async {
-    await assertNoErrorsInCode(r'''
-m() {
-  dynamic i;
-  n(i);
-}
-n(int i) {}
-''');
-  }
-
-  @failingTest
-  @override
+class ArgumentTypeNotAssignableWithoutNullSafetyTest
+    extends PubPackageResolutionTest
+    with WithoutNullSafetyMixin, ArgumentTypeNotAssignableTestCases {
   test_invocation_functionTypes_optional() async {
-    // The test is currently generating an error where none is expected.
-    await super.test_invocation_functionTypes_optional();
+    await assertErrorsInCode('''
+void acceptFunOptBool(void funNumOptBool([bool b])) {}
+void funBool(bool b) {}
+main() {
+  acceptFunOptBool(funBool);
+}''', [
+      error(CompileTimeErrorCode.INVALID_CAST_FUNCTION, 107, 7),
+    ]);
   }
 
-  @override
   test_invocation_functionTypes_optional_method() async {
     await assertErrorsInCode('''
 void acceptFunOptBool(void funOptBool([bool b])) {}
@@ -513,7 +564,7 @@
 main() {
   acceptFunOptBool(C.funBool);
 }''', [
-      error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 125, 9),
+      error(CompileTimeErrorCode.INVALID_CAST_METHOD, 125, 9),
     ]);
   }
 }
diff --git a/pkg/analyzer/test/src/diagnostics/could_not_infer_test.dart b/pkg/analyzer/test/src/diagnostics/could_not_infer_test.dart
index fe029e8..611cdb6 100644
--- a/pkg/analyzer/test/src/diagnostics/could_not_infer_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/could_not_infer_test.dart
@@ -271,4 +271,51 @@
 }
 ''');
   }
+
+  test_functionType() async {
+    await assertNoErrorsInCode('''
+void f<X>() {}
+
+main() {
+  [f];
+}
+''');
+  }
+
+  test_functionType_optOutOfGenericMetadata() async {
+    newFile('$testPackageLibPath/a.dart', content: '''
+void f<X>() {}
+''');
+    await assertErrorsInCode('''
+// @dart=2.12
+import 'a.dart';
+main() {
+  [f];
+}
+''', [
+      error(CompileTimeErrorCode.COULD_NOT_INFER, 42, 3),
+    ]);
+  }
+
+  test_instanceCreation_viaTypeAlias_notWellBounded() async {
+    await assertErrorsInCode('''
+class C<X> {
+  C();
+  factory C.foo() => C();
+  factory C.bar() = C;
+}
+typedef G<X> = X Function(X);
+typedef A<X extends G<C<X>>> = C<X>;
+
+void f() {
+  A(); // Error.
+  A.foo(); // Error.
+  A.bar(); // Error.
+}
+''', [
+      error(CompileTimeErrorCode.COULD_NOT_INFER, 152, 1),
+      error(CompileTimeErrorCode.COULD_NOT_INFER, 169, 5),
+      error(CompileTimeErrorCode.COULD_NOT_INFER, 190, 5),
+    ]);
+  }
 }
diff --git a/pkg/analyzer/test/src/diagnostics/experiment_not_enabled_test.dart b/pkg/analyzer/test/src/diagnostics/experiment_not_enabled_test.dart
new file mode 100644
index 0000000..07eeb68
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/experiment_not_enabled_test.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All 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:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/context_collection_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(ExperimentNotEnabledTest);
+  });
+}
+
+@reflectiveTest
+class ExperimentNotEnabledTest extends PubPackageResolutionTest {
+  test_nonFunctionTypeAliases_disabled() async {
+    await assertErrorsInCode(r'''
+// @dart = 2.12
+typedef A = int;
+''', [
+      error(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 26, 1),
+    ]);
+  }
+
+  test_nonFunctionTypeAliases_disabled_nullable() async {
+    await assertErrorsInCode(r'''
+// @dart = 2.12
+typedef A = int?;
+''', [
+      error(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 26, 1),
+    ]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/extends_non_class_test.dart b/pkg/analyzer/test/src/diagnostics/extends_non_class_test.dart
index 95db122..ab697b0 100644
--- a/pkg/analyzer/test/src/diagnostics/extends_non_class_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/extends_non_class_test.dart
@@ -10,13 +10,19 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(ExtendsNonClassTest);
-    defineReflectiveTests(ExtendsNonClassWithNullSafetyTest);
   });
 }
 
 @reflectiveTest
-class ExtendsNonClassTest extends PubPackageResolutionTest
-    with WithoutNullSafetyMixin {
+class ExtendsNonClassTest extends PubPackageResolutionTest {
+  test_Never() async {
+    await assertErrorsInCode('''
+class A extends Never {}
+''', [
+      error(CompileTimeErrorCode.EXTENDS_NON_CLASS, 16, 5),
+    ]);
+  }
+
   test_undefined() async {
     await assertErrorsInCode(r'''
 class C extends A {}
@@ -123,15 +129,3 @@
     ]);
   }
 }
-
-@reflectiveTest
-class ExtendsNonClassWithNullSafetyTest extends ExtendsNonClassTest
-    with WithNullSafetyMixin {
-  test_Never() async {
-    await assertErrorsInCode('''
-class A extends Never {}
-''', [
-      error(CompileTimeErrorCode.EXTENDS_NON_CLASS, 16, 5),
-    ]);
-  }
-}
diff --git a/pkg/analyzer/test/src/diagnostics/extends_type_alias_expands_to_type_parameter_test.dart b/pkg/analyzer/test/src/diagnostics/extends_type_alias_expands_to_type_parameter_test.dart
new file mode 100644
index 0000000..9737d88
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/extends_type_alias_expands_to_type_parameter_test.dart
@@ -0,0 +1,48 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All 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(ExtendsTypeAliasExpandsToTypeParameterTest);
+  });
+}
+
+@reflectiveTest
+class ExtendsTypeAliasExpandsToTypeParameterTest
+    extends PubPackageResolutionTest {
+  test_class() async {
+    await assertNoErrorsInCode(r'''
+class A {}
+typedef T = A;
+class B extends A {}
+''');
+  }
+
+  test_class_noTypeArguments() async {
+    await assertErrorsInCode(r'''
+class A {}
+typedef T<X extends A> = X;
+class B extends T {}
+''', [
+      error(CompileTimeErrorCode.EXTENDS_TYPE_ALIAS_EXPANDS_TO_TYPE_PARAMETER,
+          55, 1),
+    ]);
+  }
+
+  test_class_withTypeArguments() async {
+    await assertErrorsInCode(r'''
+class A {}
+typedef T<X extends A> = X;
+class B extends T<A> {}
+''', [
+      error(CompileTimeErrorCode.EXTENDS_TYPE_ALIAS_EXPANDS_TO_TYPE_PARAMETER,
+          55, 1),
+    ]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/extra_size_annotation_carray_test.dart b/pkg/analyzer/test/src/diagnostics/extra_size_annotation_carray_test.dart
index b3058ba..e0fd420 100644
--- a/pkg/analyzer/test/src/diagnostics/extra_size_annotation_carray_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/extra_size_annotation_carray_test.dart
@@ -15,6 +15,19 @@
 
 @reflectiveTest
 class ExtraSizeAnnotationArray extends PubPackageResolutionTest {
+  test_const() async {
+    await assertNoErrorsInCode(r'''
+import 'dart:ffi';
+
+const EIGHT = 8;
+
+class Struct8BytesInlineArrayInt extends Struct {
+  @Array(EIGHT)
+  Array<Uint8> a0;
+}
+''');
+  }
+
   test_one() async {
     await assertNoErrorsInCode(r'''
 import 'dart:ffi';
diff --git a/pkg/analyzer/test/src/diagnostics/generic_function_type_cannot_be_bound_test.dart b/pkg/analyzer/test/src/diagnostics/generic_function_type_cannot_be_bound_test.dart
index 89fde84..583a9a5 100644
--- a/pkg/analyzer/test/src/diagnostics/generic_function_type_cannot_be_bound_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/generic_function_type_cannot_be_bound_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/analysis/experiments.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -10,12 +11,66 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(GenericFunctionTypeCannotBeBoundTest);
+    defineReflectiveTests(
+        GenericFunctionTypeCannotBeBoundWithoutGenericMetadataTest);
   });
 }
 
 @reflectiveTest
 class GenericFunctionTypeCannotBeBoundTest extends PubPackageResolutionTest {
   test_class() async {
+    await assertNoErrorsInCode(r'''
+class C<T extends S Function<S>(S)> {
+}
+''');
+  }
+
+  test_genericFunction() async {
+    await assertNoErrorsInCode(r'''
+late T Function<T extends S Function<S>(S)>(T) fun;
+''');
+  }
+
+  test_genericFunction_optOutOfGenericMetadata() async {
+    newFile('$testPackageLibPath/a.dart', content: '''
+typedef F = S Function<S>(S);
+''');
+    await assertErrorsInCode('''
+// @dart=2.12
+import 'a.dart';
+late T Function<T extends F>(T) fun;
+''', [
+      error(CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_BOUND, 57, 1),
+    ]);
+  }
+
+  test_genericFunctionTypedef() async {
+    await assertNoErrorsInCode(r'''
+typedef foo = T Function<T extends S Function<S>(S)>(T t);
+''');
+  }
+
+  test_parameterOfFunction() async {
+    await assertNoErrorsInCode(r'''
+class C<T extends void Function(S Function<S>(S))> {}
+''');
+  }
+
+  test_typedef() async {
+    await assertNoErrorsInCode(r'''
+typedef T foo<T extends S Function<S>(S)>(T t);
+''');
+  }
+}
+
+@reflectiveTest
+class GenericFunctionTypeCannotBeBoundWithoutGenericMetadataTest
+    extends PubPackageResolutionTest {
+  @override
+  List<String> get experiments =>
+      super.experiments..remove(EnableString.generic_metadata);
+
+  test_class() async {
     await assertErrorsInCode(r'''
 class C<T extends S Function<S>(S)> {
 }
diff --git a/pkg/analyzer/test/src/diagnostics/implements_repeated_test.dart b/pkg/analyzer/test/src/diagnostics/implements_repeated_test.dart
new file mode 100644
index 0000000..01da5dc
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/implements_repeated_test.dart
@@ -0,0 +1,83 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All 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(ImplementsRepeatedTest);
+  });
+}
+
+@reflectiveTest
+class ImplementsRepeatedTest extends PubPackageResolutionTest {
+  test_class_implements_2times() async {
+    await assertErrorsInCode(r'''
+class A {}
+class B implements A, A {} // ref
+''', [
+      error(CompileTimeErrorCode.IMPLEMENTS_REPEATED, 33, 1),
+    ]);
+
+    var A = findElement.class_('A');
+    assertTypeName(findNode.typeName('A, A {} // ref'), A, 'A');
+    assertTypeName(findNode.typeName('A {} // ref'), A, 'A');
+  }
+
+  test_class_implements_2times_viaTypeAlias() async {
+    await assertErrorsInCode(r'''
+class A {}
+typedef B = A;
+class C implements A, B {} // ref
+''', [
+      error(CompileTimeErrorCode.IMPLEMENTS_REPEATED, 48, 1),
+    ]);
+
+    assertTypeName(
+      findNode.typeName('A, B {} // ref'),
+      findElement.class_('A'),
+      'A',
+    );
+
+    assertTypeName(
+      findNode.typeName('B {} // ref'),
+      findElement.typeAlias('B'),
+      'A',
+    );
+  }
+
+  test_class_implements_4times() async {
+    await assertErrorsInCode(r'''
+class A {} class C{}
+class B implements A, A, A, A {}
+''', [
+      error(CompileTimeErrorCode.IMPLEMENTS_REPEATED, 43, 1),
+      error(CompileTimeErrorCode.IMPLEMENTS_REPEATED, 46, 1),
+      error(CompileTimeErrorCode.IMPLEMENTS_REPEATED, 49, 1),
+    ]);
+  }
+
+  test_mixin_implements_2times() async {
+    await assertErrorsInCode(r'''
+class A {}
+mixin M implements A, A {}
+''', [
+      error(CompileTimeErrorCode.IMPLEMENTS_REPEATED, 33, 1),
+    ]);
+  }
+
+  test_mixin_implements_4times() async {
+    await assertErrorsInCode(r'''
+class A {}
+mixin M implements A, A, A, A {}
+''', [
+      error(CompileTimeErrorCode.IMPLEMENTS_REPEATED, 33, 1),
+      error(CompileTimeErrorCode.IMPLEMENTS_REPEATED, 36, 1),
+      error(CompileTimeErrorCode.IMPLEMENTS_REPEATED, 39, 1),
+    ]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/implements_super_class_test.dart b/pkg/analyzer/test/src/diagnostics/implements_super_class_test.dart
index c6ba3d3..cab2312 100644
--- a/pkg/analyzer/test/src/diagnostics/implements_super_class_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/implements_super_class_test.dart
@@ -15,7 +15,7 @@
 
 @reflectiveTest
 class ImplementsSuperClassTest extends PubPackageResolutionTest {
-  test_implements_super_class() async {
+  test_class() async {
     await assertErrorsInCode(r'''
 class A {}
 class B extends A implements A {}
@@ -24,7 +24,7 @@
     ]);
   }
 
-  test_Object() async {
+  test_class_Object() async {
     await assertErrorsInCode('''
 class A implements Object {}
 ''', [
@@ -32,7 +32,27 @@
     ]);
   }
 
-  test_Object_typeAlias() async {
+  test_class_viaTypeAlias() async {
+    await assertErrorsInCode(r'''
+class A {}
+typedef B = A;
+class C extends A implements B {}
+''', [
+      error(CompileTimeErrorCode.IMPLEMENTS_SUPER_CLASS, 55, 1),
+    ]);
+  }
+
+  test_classAlias() async {
+    await assertErrorsInCode(r'''
+class A {}
+mixin M {}
+class B = A with M implements A;
+''', [
+      error(CompileTimeErrorCode.IMPLEMENTS_SUPER_CLASS, 52, 1),
+    ]);
+  }
+
+  test_classAlias_Object() async {
     await assertErrorsInCode(r'''
 class M {}
 class A = Object with M implements Object;
@@ -41,13 +61,14 @@
     ]);
   }
 
-  test_typeAlias() async {
+  test_classAlias_viaTypeAlias() async {
     await assertErrorsInCode(r'''
 class A {}
-class M {}
-class B = A with M implements A;
+mixin M {}
+typedef B = A;
+class C = A with M implements B;
 ''', [
-      error(CompileTimeErrorCode.IMPLEMENTS_SUPER_CLASS, 52, 1),
+      error(CompileTimeErrorCode.IMPLEMENTS_SUPER_CLASS, 67, 1),
     ]);
   }
 }
diff --git a/pkg/analyzer/test/src/diagnostics/implements_type_alias_expands_to_type_parameter_test.dart b/pkg/analyzer/test/src/diagnostics/implements_type_alias_expands_to_type_parameter_test.dart
new file mode 100644
index 0000000..2810170
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/implements_type_alias_expands_to_type_parameter_test.dart
@@ -0,0 +1,65 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All 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(ImplementsTypeAliasExpandsToTypeParameterTest);
+  });
+}
+
+@reflectiveTest
+class ImplementsTypeAliasExpandsToTypeParameterTest
+    extends PubPackageResolutionTest {
+  test_class() async {
+    await assertNoErrorsInCode(r'''
+class A {}
+typedef T = A;
+class B implements T {}
+''');
+  }
+
+  test_class_typeParameter_noTypeArguments() async {
+    await assertErrorsInCode(r'''
+class A {}
+typedef T<X extends A> = X;
+class B implements T {}
+''', [
+      error(
+          CompileTimeErrorCode.IMPLEMENTS_TYPE_ALIAS_EXPANDS_TO_TYPE_PARAMETER,
+          58,
+          1),
+    ]);
+  }
+
+  test_class_typeParameter_withTypeArguments() async {
+    await assertErrorsInCode(r'''
+class A {}
+typedef T<X extends A> = X;
+class B implements T<A> {}
+''', [
+      error(
+          CompileTimeErrorCode.IMPLEMENTS_TYPE_ALIAS_EXPANDS_TO_TYPE_PARAMETER,
+          58,
+          1),
+    ]);
+  }
+
+  test_mixin_typeParameter_noTypeArguments() async {
+    await assertErrorsInCode(r'''
+class A {}
+typedef T<X extends A> = X;
+mixin M implements T {}
+''', [
+      error(
+          CompileTimeErrorCode.IMPLEMENTS_TYPE_ALIAS_EXPANDS_TO_TYPE_PARAMETER,
+          58,
+          1),
+    ]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/inference_failure_on_instance_creation_test.dart b/pkg/analyzer/test/src/diagnostics/inference_failure_on_instance_creation_test.dart
index 89c6db9..69e9b22 100644
--- a/pkg/analyzer/test/src/diagnostics/inference_failure_on_instance_creation_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/inference_failure_on_instance_creation_test.dart
@@ -71,15 +71,15 @@
   }
 
   test_missingTypeArgument_interfaceTypeTypedef_noInference() async {
-    await assertErrorsInCode(r'''
+    // `typedef A = HashMap;` means `typedef A = HashMap<dynamic, dynamic>;`.
+    // So, there is no inference failure on `new A();`.
+    await assertNoErrorsInCode(r'''
 import 'dart:collection';
 typedef A = HashMap;
 void f() {
   A();
 }
-''', [
-      error(HintCode.INFERENCE_FAILURE_ON_INSTANCE_CREATION, 60, 1),
-    ]);
+''');
   }
 
   test_missingTypeArgument_noInference() async {
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_annotation_from_deferred_library_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_annotation_from_deferred_library_test.dart
index 88263a6..589f88c 100644
--- a/pkg/analyzer/test/src/diagnostics/invalid_annotation_from_deferred_library_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/invalid_annotation_from_deferred_library_test.dart
@@ -31,6 +31,22 @@
     ]);
   }
 
+  @FailingTest(reason: 'https://github.com/dart-lang/sdk/issues/45418')
+  test_constructor_argument() async {
+    newFile('$testPackageLibPath/lib1.dart', content: '''
+const x = 0;
+''');
+    await assertErrorsInCode('''
+library root;
+import 'lib1.dart' deferred as a;
+class C { const C(int i); }
+@C(a.x) main () {}
+''', [
+      error(
+          CompileTimeErrorCode.INVALID_ANNOTATION_FROM_DEFERRED_LIBRARY, 49, 3),
+    ]);
+  }
+
   test_from_deferred_library() async {
     newFile('$testPackageLibPath/lib1.dart', content: '''
 library lib1;
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_annotation_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_annotation_test.dart
index 1795ae3..a72d21b 100644
--- a/pkg/analyzer/test/src/diagnostics/invalid_annotation_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/invalid_annotation_test.dart
@@ -15,6 +15,45 @@
 
 @reflectiveTest
 class InvalidAnnotationTest extends PubPackageResolutionTest {
+  test_class_noUnnamedConstructor() async {
+    await assertErrorsInCode(r'''
+class A {
+  const A.named();
+}
+
+@A
+void f() {}
+''', [
+      error(CompileTimeErrorCode.INVALID_ANNOTATION, 32, 2),
+    ]);
+  }
+
+  test_class_staticMethod() async {
+    await assertErrorsInCode(r'''
+class A {
+  static int foo() => 0;
+}
+
+@A.foo
+void f() {}
+''', [
+      error(CompileTimeErrorCode.INVALID_ANNOTATION, 38, 6),
+    ]);
+  }
+
+  test_class_staticMethod_arguments() async {
+    await assertErrorsInCode(r'''
+class A {
+  static int foo() => 0;
+}
+
+@A.foo()
+void f() {}
+''', [
+      error(CompileTimeErrorCode.INVALID_ANNOTATION, 38, 8),
+    ]);
+  }
+
   test_getter() async {
     await assertErrorsInCode(r'''
 get V => 0;
@@ -129,6 +168,28 @@
     ]);
   }
 
+  test_prefix_function() async {
+    await assertErrorsInCode(r'''
+import 'dart:math' as p;
+
+@p.sin(0)
+class B {}
+''', [
+      error(CompileTimeErrorCode.INVALID_ANNOTATION, 26, 9),
+    ]);
+  }
+
+  test_prefix_function_unresolved() async {
+    await assertErrorsInCode(r'''
+import 'dart:math' as p;
+
+@p.sin.cos(0)
+class B {}
+''', [
+      error(CompileTimeErrorCode.INVALID_ANNOTATION, 26, 13),
+    ]);
+  }
+
   test_staticMethodReference() async {
     await assertErrorsInCode(r'''
 class A {
diff --git a/pkg/analyzer/test/src/diagnostics/invocation_of_non_function_expression_test.dart b/pkg/analyzer/test/src/diagnostics/invocation_of_non_function_expression_test.dart
index 1a329c0..77ac7e9 100644
--- a/pkg/analyzer/test/src/diagnostics/invocation_of_non_function_expression_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/invocation_of_non_function_expression_test.dart
@@ -15,13 +15,35 @@
 
 @reflectiveTest
 class InvocationOfNonFunctionExpressionTest extends PubPackageResolutionTest {
-  test_invocationOfNonFunctionExpression_literal() async {
+  test_literal_int() async {
     await assertErrorsInCode(r'''
-f() {
+void f() {
   3(5);
 }
 ''', [
-      error(CompileTimeErrorCode.INVOCATION_OF_NON_FUNCTION_EXPRESSION, 8, 1),
+      error(CompileTimeErrorCode.INVOCATION_OF_NON_FUNCTION_EXPRESSION, 13, 1),
+    ]);
+  }
+
+  test_literal_null() async {
+    await assertErrorsInCode(r'''
+// @dart = 2.9
+void f() {
+  null();
+}
+''', [
+      error(CompileTimeErrorCode.INVOCATION_OF_NON_FUNCTION_EXPRESSION, 28, 4),
+    ]);
+  }
+
+  test_type_Null() async {
+    await assertErrorsInCode(r'''
+// @dart = 2.9
+void f(Null a) {
+  a();
+}
+''', [
+      error(CompileTimeErrorCode.INVOCATION_OF_NON_FUNCTION_EXPRESSION, 34, 1),
     ]);
   }
 }
diff --git a/pkg/analyzer/test/src/diagnostics/mixin_inherits_from_not_object_test.dart b/pkg/analyzer/test/src/diagnostics/mixin_inherits_from_not_object_test.dart
index 7bcbe74..5af77a8 100644
--- a/pkg/analyzer/test/src/diagnostics/mixin_inherits_from_not_object_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/mixin_inherits_from_not_object_test.dart
@@ -15,43 +15,7 @@
 
 @reflectiveTest
 class MixinInheritsFromNotObjectTest extends PubPackageResolutionTest {
-  test_classDeclaration_extends() async {
-    await assertErrorsInCode(r'''
-class A {}
-class B extends A {}
-class C extends Object with B {}
-''', [
-      error(CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT, 60, 1),
-    ]);
-  }
-
-  test_classDeclaration_extends_new_syntax() async {
-    await assertNoErrorsInCode(r'''
-class A {}
-mixin B on A {}
-class C extends A with B {}
-''');
-  }
-
-  test_classDeclaration_mixTypeAlias() async {
-    await assertNoErrorsInCode(r'''
-class A {}
-class B = Object with A;
-class C extends Object with B {}
-''');
-  }
-
-  test_classDeclaration_with() async {
-    await assertErrorsInCode(r'''
-class A {}
-class B extends Object with A {}
-class C extends Object with B {}
-''', [
-      error(CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT, 72, 1),
-    ]);
-  }
-
-  test_typeAlias_extends() async {
+  test_classAlias_class_extends() async {
     await assertErrorsInCode(r'''
 class A {}
 class B extends A {}
@@ -61,15 +25,7 @@
     ]);
   }
 
-  test_typeAlias_extends_new_syntax() async {
-    await assertNoErrorsInCode(r'''
-class A {}
-mixin B on A {}
-class C = A with B;
-''');
-  }
-
-  test_typeAlias_with() async {
+  test_classAlias_class_with() async {
     await assertErrorsInCode(r'''
 class A {}
 class B extends Object with A {}
@@ -79,11 +35,85 @@
     ]);
   }
 
-  test_typedef_mixTypeAlias() async {
+  test_classAlias_classAlias_with() async {
     await assertNoErrorsInCode(r'''
 class A {}
 class B = Object with A;
 class C = Object with B;
 ''');
   }
+
+  test_classAlias_classAlias_with2() async {
+    await assertErrorsInCode(r'''
+class A {}
+class B {}
+class C = Object with A, B;
+class D = Object with C;
+''', [
+      error(CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT, 72, 1),
+    ]);
+  }
+
+  test_classAlias_mixin() async {
+    await assertNoErrorsInCode(r'''
+class A {}
+mixin B on A {}
+class C = A with B;
+''');
+  }
+
+  test_classDeclaration_class_extends() async {
+    await assertErrorsInCode(r'''
+class A {}
+class B extends A {}
+class C extends Object with B {}
+''', [
+      error(CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT, 60, 1),
+    ]);
+  }
+
+  test_classDeclaration_class_extends_Object() async {
+    await assertNoErrorsInCode(r'''
+class A {}
+class B extends Object {}
+class C extends Object with B {}
+''');
+  }
+
+  test_classDeclaration_class_with() async {
+    await assertErrorsInCode(r'''
+class A {}
+class B extends Object with A {}
+class C extends Object with B {}
+''', [
+      error(CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT, 72, 1),
+    ]);
+  }
+
+  test_classDeclaration_classAlias_with() async {
+    await assertNoErrorsInCode(r'''
+class A {}
+class B = Object with A;
+class C extends Object with B {}
+''');
+  }
+
+  test_classDeclaration_classAlias_with2() async {
+    await assertErrorsInCode(r'''
+class A {}
+class B {}
+class C = Object with A, B;
+class D extends Object with C {}
+''', [
+      error(CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT, 78, 1),
+    ]);
+  }
+
+  test_classDeclaration_mixin() async {
+    await assertNoErrorsInCode(r'''
+class A {}
+mixin B on A {}
+class C extends A with B {}
+''');
+  }
 }
diff --git a/pkg/analyzer/test/src/diagnostics/mixin_of_type_alias_expands_to_type_parameter_test.dart b/pkg/analyzer/test/src/diagnostics/mixin_of_type_alias_expands_to_type_parameter_test.dart
new file mode 100644
index 0000000..558e767
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/mixin_of_type_alias_expands_to_type_parameter_test.dart
@@ -0,0 +1,48 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All 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(MixinOfTypeAliasExpandsToTypeParameterTest);
+  });
+}
+
+@reflectiveTest
+class MixinOfTypeAliasExpandsToTypeParameterTest
+    extends PubPackageResolutionTest {
+  test_class() async {
+    await assertNoErrorsInCode(r'''
+class A {}
+typedef T = A;
+class B with A {}
+''');
+  }
+
+  test_class_noTypeArguments() async {
+    await assertErrorsInCode(r'''
+class A {}
+typedef T<X extends A> = X;
+class B with T {}
+''', [
+      error(CompileTimeErrorCode.MIXIN_OF_TYPE_ALIAS_EXPANDS_TO_TYPE_PARAMETER,
+          52, 1),
+    ]);
+  }
+
+  test_class_withTypeArguments() async {
+    await assertErrorsInCode(r'''
+class A {}
+typedef T<X extends A> = X;
+class B with T<A> {}
+''', [
+      error(CompileTimeErrorCode.MIXIN_OF_TYPE_ALIAS_EXPANDS_TO_TYPE_PARAMETER,
+          52, 1),
+    ]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/mixin_on_type_alias_expands_to_type_parameter_test.dart b/pkg/analyzer/test/src/diagnostics/mixin_on_type_alias_expands_to_type_parameter_test.dart
new file mode 100644
index 0000000..26be464
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/mixin_on_type_alias_expands_to_type_parameter_test.dart
@@ -0,0 +1,48 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All 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(MixinOnTypeAliasExpandsToTypeParameterTest);
+  });
+}
+
+@reflectiveTest
+class MixinOnTypeAliasExpandsToTypeParameterTest
+    extends PubPackageResolutionTest {
+  test_class() async {
+    await assertNoErrorsInCode(r'''
+class A {}
+typedef T = A;
+mixin M on A {}
+''');
+  }
+
+  test_class_noTypeArguments() async {
+    await assertErrorsInCode(r'''
+class A {}
+typedef T<X extends A> = X;
+mixin M on T {}
+''', [
+      error(CompileTimeErrorCode.MIXIN_ON_TYPE_ALIAS_EXPANDS_TO_TYPE_PARAMETER,
+          50, 1),
+    ]);
+  }
+
+  test_class_withTypeArguments() async {
+    await assertErrorsInCode(r'''
+class A {}
+typedef T<X extends A> = X;
+mixin M on T<A> {}
+''', [
+      error(CompileTimeErrorCode.MIXIN_ON_TYPE_ALIAS_EXPANDS_TO_TYPE_PARAMETER,
+          50, 1),
+    ]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/mixins_super_class_test.dart b/pkg/analyzer/test/src/diagnostics/mixins_super_class_test.dart
index b7b7ff6..d5e4ac8 100644
--- a/pkg/analyzer/test/src/diagnostics/mixins_super_class_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/mixins_super_class_test.dart
@@ -24,6 +24,16 @@
     ]);
   }
 
+  test_class_viaTypeAlias() async {
+    await assertErrorsInCode(r'''
+class A {}
+typedef B = A;
+class C extends A with B {}
+''', [
+      error(CompileTimeErrorCode.MIXINS_SUPER_CLASS, 49, 1),
+    ]);
+  }
+
   test_classAlias() async {
     await assertErrorsInCode(r'''
 class A {}
@@ -32,4 +42,14 @@
       error(CompileTimeErrorCode.MIXINS_SUPER_CLASS, 28, 1),
     ]);
   }
+
+  test_classAlias_viaTypeAlias() async {
+    await assertErrorsInCode(r'''
+class A {}
+typedef B = A;
+class C = A with B;
+''', [
+      error(CompileTimeErrorCode.MIXINS_SUPER_CLASS, 43, 1),
+    ]);
+  }
 }
diff --git a/pkg/analyzer/test/src/diagnostics/non_sized_type_argument_test.dart b/pkg/analyzer/test/src/diagnostics/non_sized_type_argument_test.dart
index 85b1793..ec3f26d 100644
--- a/pkg/analyzer/test/src/diagnostics/non_sized_type_argument_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/non_sized_type_argument_test.dart
@@ -32,10 +32,10 @@
 
 class C extends Struct {
   @Array(8)
-  Array<Array<Uint8>> a0;
+  Array<Void> a0;
 }
 ''', [
-      error(FfiCode.NON_SIZED_TYPE_ARGUMENT, 59, 19),
+      error(FfiCode.NON_SIZED_TYPE_ARGUMENT, 59, 11),
     ]);
   }
 }
diff --git a/pkg/analyzer/test/src/diagnostics/not_instantiated_bound_test.dart b/pkg/analyzer/test/src/diagnostics/not_instantiated_bound_test.dart
index 969205a..c7254f7 100644
--- a/pkg/analyzer/test/src/diagnostics/not_instantiated_bound_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/not_instantiated_bound_test.dart
@@ -94,6 +94,22 @@
     ]);
   }
 
+  test_class_recursion_notInstantiated_genericFunctionType() async {
+    await assertErrorsInCode(r'''
+class A<T extends void Function(A)> {}
+''', [
+      error(CompileTimeErrorCode.NOT_INSTANTIATED_BOUND, 32, 1),
+    ]);
+  }
+
+  test_class_recursion_notInstantiated_genericFunctionType2() async {
+    await assertErrorsInCode(r'''
+class A<T extends void Function<U extends A>()> {}
+''', [
+      error(CompileTimeErrorCode.NOT_INSTANTIATED_BOUND, 42, 1),
+    ]);
+  }
+
   test_class_recursion_typedef_notInstantiated() async {
     await assertErrorsInCode(r'''
 typedef F(C value);
diff --git a/pkg/analyzer/test/src/diagnostics/null_safety_read_write_test.dart b/pkg/analyzer/test/src/diagnostics/null_safety_read_write_test.dart
index 1d73a79..ef2d1d9 100644
--- a/pkg/analyzer/test/src/diagnostics/null_safety_read_write_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/null_safety_read_write_test.dart
@@ -514,7 +514,7 @@
       error(CompileTimeErrorCode.DEFINITELY_UNASSIGNED_LATE_LOCAL_VARIABLE, 68,
           1),
       error(CompileTimeErrorCode.UNCHECKED_METHOD_INVOCATION_OF_NULLABLE_VALUE,
-          68, 1),
+          70, 2),
     ]);
     _assertAssigned('x +=', assigned: false, unassigned: true);
   }
@@ -530,7 +530,7 @@
       error(CompileTimeErrorCode.DEFINITELY_UNASSIGNED_LATE_LOCAL_VARIABLE, 68,
           1),
       error(CompileTimeErrorCode.UNCHECKED_METHOD_INVOCATION_OF_NULLABLE_VALUE,
-          68, 1),
+          69, 2),
     ]);
     _assertAssigned('x++', assigned: false, unassigned: true);
   }
@@ -546,7 +546,7 @@
       error(CompileTimeErrorCode.DEFINITELY_UNASSIGNED_LATE_LOCAL_VARIABLE, 70,
           1),
       error(CompileTimeErrorCode.UNCHECKED_METHOD_INVOCATION_OF_NULLABLE_VALUE,
-          70, 1),
+          68, 2),
     ]);
     _assertAssigned('x; // 0', assigned: false, unassigned: true);
   }
@@ -583,7 +583,7 @@
 }
 ''', [
       error(CompileTimeErrorCode.UNCHECKED_METHOD_INVOCATION_OF_NULLABLE_VALUE,
-          90, 1),
+          92, 2),
     ]);
     _assertAssigned('x +=', assigned: false, unassigned: false);
   }
@@ -598,7 +598,7 @@
 }
 ''', [
       error(CompileTimeErrorCode.UNCHECKED_METHOD_INVOCATION_OF_NULLABLE_VALUE,
-          90, 1),
+          91, 2),
     ]);
     _assertAssigned('x++', assigned: false, unassigned: false);
   }
@@ -613,7 +613,7 @@
 }
 ''', [
       error(CompileTimeErrorCode.UNCHECKED_METHOD_INVOCATION_OF_NULLABLE_VALUE,
-          92, 1),
+          90, 2),
     ]);
     _assertAssigned('x; // 0', assigned: false, unassigned: false);
   }
diff --git a/pkg/analyzer/test/src/diagnostics/on_repeated_test.dart b/pkg/analyzer/test/src/diagnostics/on_repeated_test.dart
new file mode 100644
index 0000000..41c3a90
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/on_repeated_test.dart
@@ -0,0 +1,36 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All 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(OnRepeatedTest);
+  });
+}
+
+@reflectiveTest
+class OnRepeatedTest extends PubPackageResolutionTest {
+  test_2times() async {
+    await assertErrorsInCode(r'''
+class A {}
+mixin M on A, A {}
+''', [
+      error(CompileTimeErrorCode.ON_REPEATED, 25, 1),
+    ]);
+  }
+
+  test_2times_viaTypeAlias() async {
+    await assertErrorsInCode(r'''
+class A {}
+typedef B = A;
+mixin M on A, B {}
+''', [
+      error(CompileTimeErrorCode.ON_REPEATED, 40, 1),
+    ]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/override_on_non_overriding_getter_test.dart b/pkg/analyzer/test/src/diagnostics/override_on_non_overriding_getter_test.dart
index d07c28e..44ce6f8 100644
--- a/pkg/analyzer/test/src/diagnostics/override_on_non_overriding_getter_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/override_on_non_overriding_getter_test.dart
@@ -37,15 +37,40 @@
 }''');
   }
 
-  test_invalid() async {
+  test_invalid_class() async {
     await assertErrorsInCode(r'''
-class A {
-}
+class A {}
+
 class B extends A {
   @override
-  int get m => 1;
-}''', [
-      error(HintCode.OVERRIDE_ON_NON_OVERRIDING_GETTER, 54, 1),
+  int get foo => 1;
+}
+''', [
+      error(HintCode.OVERRIDE_ON_NON_OVERRIDING_GETTER, 54, 3),
+    ]);
+  }
+
+  test_invalid_extension() async {
+    await assertErrorsInCode(r'''
+extension E on int {
+  @override
+  int get foo => 1;
+}
+''', [
+      error(HintCode.OVERRIDE_ON_NON_OVERRIDING_GETTER, 43, 3),
+    ]);
+  }
+
+  test_invalid_mixin() async {
+    await assertErrorsInCode(r'''
+class A {}
+
+mixin M on A {
+  @override
+  int get foo => 1;
+}
+''', [
+      error(HintCode.OVERRIDE_ON_NON_OVERRIDING_GETTER, 49, 3),
     ]);
   }
 }
diff --git a/pkg/analyzer/test/src/diagnostics/override_on_non_overriding_method_test.dart b/pkg/analyzer/test/src/diagnostics/override_on_non_overriding_method_test.dart
index 3720caa..2d47c68 100644
--- a/pkg/analyzer/test/src/diagnostics/override_on_non_overriding_method_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/override_on_non_overriding_method_test.dart
@@ -64,15 +64,40 @@
 }''');
   }
 
-  test_invalid() async {
+  test_invalid_class() async {
     await assertErrorsInCode(r'''
-class A {
-}
+class A {}
+
 class B extends A {
   @override
-  int m() => 1;
-}''', [
-      error(HintCode.OVERRIDE_ON_NON_OVERRIDING_METHOD, 50, 1),
+  void foo() {}
+}
+''', [
+      error(HintCode.OVERRIDE_ON_NON_OVERRIDING_METHOD, 51, 3),
+    ]);
+  }
+
+  test_invalid_extension() async {
+    await assertErrorsInCode(r'''
+extension E on int {
+  @override
+  void foo() {}
+}
+''', [
+      error(HintCode.OVERRIDE_ON_NON_OVERRIDING_METHOD, 40, 3),
+    ]);
+  }
+
+  test_invalid_mixin() async {
+    await assertErrorsInCode(r'''
+class A {}
+
+mixin M on A {
+  @override
+  void foo() {}
+}
+''', [
+      error(HintCode.OVERRIDE_ON_NON_OVERRIDING_METHOD, 46, 3),
     ]);
   }
 }
diff --git a/pkg/analyzer/test/src/diagnostics/override_on_non_overriding_setter_test.dart b/pkg/analyzer/test/src/diagnostics/override_on_non_overriding_setter_test.dart
index b2f6683..ae370bf 100644
--- a/pkg/analyzer/test/src/diagnostics/override_on_non_overriding_setter_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/override_on_non_overriding_setter_test.dart
@@ -37,15 +37,40 @@
 }''');
   }
 
-  test_invalid() async {
+  test_invalid_class() async {
     await assertErrorsInCode(r'''
-class A {
-}
+class A {}
+
 class B extends A {
   @override
-  set m(int x) {}
-}''', [
-      error(HintCode.OVERRIDE_ON_NON_OVERRIDING_SETTER, 50, 1),
+  set foo(int _) {}
+}
+''', [
+      error(HintCode.OVERRIDE_ON_NON_OVERRIDING_SETTER, 50, 3),
+    ]);
+  }
+
+  test_invalid_extension() async {
+    await assertErrorsInCode(r'''
+extension E on int {
+  @override
+  set foo(int _) {}
+}
+''', [
+      error(HintCode.OVERRIDE_ON_NON_OVERRIDING_SETTER, 39, 3),
+    ]);
+  }
+
+  test_invalid_mixin() async {
+    await assertErrorsInCode(r'''
+class A {}
+
+mixin M on A {
+  @override
+  set foo(int _) {}
+}
+''', [
+      error(HintCode.OVERRIDE_ON_NON_OVERRIDING_SETTER, 45, 3),
     ]);
   }
 }
diff --git a/pkg/analyzer/test/src/diagnostics/packed_annotation_alignment_test.dart b/pkg/analyzer/test/src/diagnostics/packed_annotation_alignment_test.dart
new file mode 100644
index 0000000..b5e9223
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/packed_annotation_alignment_test.dart
@@ -0,0 +1,41 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All 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/ffi_code.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/context_collection_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(PackedAnnotationAlignment);
+  });
+}
+
+@reflectiveTest
+class PackedAnnotationAlignment extends PubPackageResolutionTest {
+  test_error() async {
+    await assertErrorsInCode(r'''
+import 'dart:ffi';
+
+@Packed(3)
+class C extends Struct {
+  external Pointer<Uint8> notEmpty;
+}
+''', [
+      error(FfiCode.PACKED_ANNOTATION_ALIGNMENT, 20, 10),
+    ]);
+  }
+
+  test_no_error() async {
+    await assertNoErrorsInCode(r'''
+import 'dart:ffi';
+
+@Packed(1)
+class C extends Struct {
+  external Pointer<Uint8> notEmpty;
+}
+''');
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/packed_annotation_test.dart b/pkg/analyzer/test/src/diagnostics/packed_annotation_test.dart
new file mode 100644
index 0000000..21a5454
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/packed_annotation_test.dart
@@ -0,0 +1,68 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All 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/ffi_code.dart';
+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(PackedAnnotation);
+  });
+}
+
+@reflectiveTest
+class PackedAnnotation extends PubPackageResolutionTest {
+  test_error_1() async {
+    await assertErrorsInCode(r'''
+import 'dart:ffi';
+
+@Packed(1)
+@Packed(1)
+class C extends Struct {
+  external Pointer<Uint8> notEmpty;
+}
+''', [
+      error(FfiCode.PACKED_ANNOTATION, 31, 10),
+    ]);
+  }
+
+  /// Regress test for http://dartbug.com/45498.
+  test_error_2() async {
+    await assertErrorsInCode(r'''
+import 'dart:ffi';
+
+@Packed()
+class C extends Struct {
+  external Pointer<Uint8> notEmpty;
+}
+''', [
+      error(FfiCode.PACKED_ANNOTATION_ALIGNMENT, 20, 9),
+      error(CompileTimeErrorCode.NOT_ENOUGH_POSITIONAL_ARGUMENTS, 27, 2),
+    ]);
+  }
+
+  test_no_error_1() async {
+    await assertNoErrorsInCode(r'''
+import 'dart:ffi';
+
+class C extends Struct {
+  external Pointer<Uint8> notEmpty;
+}
+''');
+  }
+
+  test_no_error_2() async {
+    await assertNoErrorsInCode(r'''
+import 'dart:ffi';
+
+@Packed(1)
+class C extends Struct {
+  external Pointer<Uint8> notEmpty;
+}
+''');
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/packed_nesting_non_packed_test.dart b/pkg/analyzer/test/src/diagnostics/packed_nesting_non_packed_test.dart
new file mode 100644
index 0000000..9751139
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/packed_nesting_non_packed_test.dart
@@ -0,0 +1,116 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All 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/ffi_code.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/context_collection_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(PackedAnnotationNestingNonPacked);
+  });
+}
+
+@reflectiveTest
+class PackedAnnotationNestingNonPacked extends PubPackageResolutionTest {
+  test_error_1() async {
+    await assertErrorsInCode(r'''
+import 'dart:ffi';
+
+class TestStruct1603 extends Struct {
+  external Pointer<Uint8> notEmpty;
+}
+
+@Packed(1)
+class TestStruct1603Packed extends Struct {
+  external Pointer<Uint8> notEmpty;
+
+  external TestStruct1603 nestedNotPacked;
+}
+''', [
+      error(FfiCode.PACKED_NESTING_NON_PACKED, 200, 14),
+    ]);
+  }
+
+  test_error_2() async {
+    await assertErrorsInCode(r'''
+import 'dart:ffi';
+
+@Packed(8)
+class TestStruct1604 extends Struct {
+  external Pointer<Uint8> notEmpty;
+}
+
+@Packed(1)
+class TestStruct1604Packed extends Struct {
+  external Pointer<Uint8> notEmpty;
+
+  external TestStruct1604 nestedLooselyPacked;
+}
+''', [
+      error(FfiCode.PACKED_NESTING_NON_PACKED, 211, 14),
+    ]);
+  }
+
+  test_error_3() async {
+    await assertErrorsInCode(r'''
+import 'dart:ffi';
+
+class TestStruct1603 extends Struct {
+  external Pointer<Uint8> notEmpty;
+}
+
+@Packed(1)
+class TestStruct1605Packed extends Struct {
+  external Pointer<Uint8> notEmpty;
+
+  @Array(2)
+  external Array<TestStruct1603> nestedNotPacked;
+}
+''', [
+      error(FfiCode.PACKED_NESTING_NON_PACKED, 212, 21),
+    ]);
+  }
+
+  test_error_4() async {
+    await assertErrorsInCode(r'''
+import 'dart:ffi';
+
+@Packed(8)
+class TestStruct1604 extends Struct {
+  external Pointer<Uint8> notEmpty;
+}
+
+@Packed(1)
+class TestStruct1606Packed extends Struct {
+  external Pointer<Uint8> notEmpty;
+
+  @Array(2)
+  external Array<TestStruct1604> nestedLooselyPacked;
+}
+''', [
+      error(FfiCode.PACKED_NESTING_NON_PACKED, 223, 21),
+    ]);
+  }
+
+  test_no_error() async {
+    await assertNoErrorsInCode(r'''
+import 'dart:ffi';
+
+@Packed(1)
+class TestStruct1604 extends Struct {
+  external Pointer<Uint8> notEmpty;
+}
+
+@Packed(1)
+class TestStruct1606Packed extends Struct {
+  external Pointer<Uint8> notEmpty;
+
+  @Array(2)
+  external Array<TestStruct1604> nestedLooselyPacked;
+}
+''');
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/receiver_of_type_never_test.dart b/pkg/analyzer/test/src/diagnostics/receiver_of_type_never_test.dart
index 9a85f2f..b65d7e4 100644
--- a/pkg/analyzer/test/src/diagnostics/receiver_of_type_never_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/receiver_of_type_never_test.dart
@@ -78,7 +78,7 @@
 ''', [
       error(
           CompileTimeErrorCode.UNCHECKED_OPERATOR_INVOCATION_OF_NULLABLE_VALUE,
-          21,
+          23,
           1),
     ]);
 
@@ -204,7 +204,7 @@
 }
 ''', [
       error(CompileTimeErrorCode.UNCHECKED_METHOD_INVOCATION_OF_NULLABLE_VALUE,
-          21, 1),
+          22, 1),
     ]);
 
     assertIndexExpression(
@@ -222,7 +222,7 @@
 }
 ''', [
       error(CompileTimeErrorCode.UNCHECKED_METHOD_INVOCATION_OF_NULLABLE_VALUE,
-          21, 1),
+          22, 1),
     ]);
 
     assertAssignment(
@@ -254,7 +254,7 @@
 }
 ''', [
       error(CompileTimeErrorCode.UNCHECKED_METHOD_INVOCATION_OF_NULLABLE_VALUE,
-          21, 1),
+          22, 1),
     ]);
 
     assertIndexExpression(
@@ -364,7 +364,7 @@
 }
 ''', [
       error(CompileTimeErrorCode.UNCHECKED_METHOD_INVOCATION_OF_NULLABLE_VALUE,
-          21, 1),
+          22, 2),
     ]);
 
     assertPostfixExpression(
@@ -406,7 +406,7 @@
 }
 ''', [
       error(CompileTimeErrorCode.UNCHECKED_METHOD_INVOCATION_OF_NULLABLE_VALUE,
-          23, 1),
+          21, 2),
     ]);
 
     assertPrefixExpression(
@@ -517,7 +517,7 @@
 }
 ''', [
       error(CompileTimeErrorCode.UNCHECKED_PROPERTY_ACCESS_OF_NULLABLE_VALUE,
-          21, 1),
+          23, 3),
     ]);
 
     assertSimpleIdentifier(
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 5f103da..ec6150f 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
@@ -6,7 +6,6 @@
 import 'package:analyzer/src/error/codes.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
-import '../dart/resolution/context_collection_resolution.dart';
 import 'sdk_constraint_verifier_support.dart';
 
 main() {
@@ -22,18 +21,6 @@
       '${ExperimentStatus.currentVersion.major}.'
       '${ExperimentStatus.currentVersion.minor}';
 
-  @override
-  void setUp() {
-    super.setUp();
-    writeTestPackageAnalysisOptionsFile(
-      AnalysisOptionsFileConfig(
-        experiments: [
-          EnableString.triple_shift,
-        ],
-      ),
-    );
-  }
-
   test_const_equals() async {
     // TODO(brianwilkerson) Add '>>>' to MockSdk and remove the code
     //  UNDEFINED_OPERATOR when triple_shift is enabled by default.
@@ -75,7 +62,7 @@
 
   test_nonConst_equals() async {
     // TODO(brianwilkerson) Add '>>>' to MockSdk and remove the code
-    //  UNDEFINED_OPERATOR when constant update is enabled by default.
+    //  UNDEFINED_OPERATOR when triple_shift is enabled by default.
     await verifyVersion('2.5.0', '''
 var a = 42 >>> 3;
 ''', expectedErrors: [
@@ -85,7 +72,7 @@
 
   test_nonConst_lessThan() async {
     // TODO(brianwilkerson) Add '>>>' to MockSdk and remove the code
-    //  UNDEFINED_OPERATOR when constant update is enabled by default.
+    //  UNDEFINED_OPERATOR when triple_shift is enabled by default.
     await verifyVersion('2.2.0', '''
 var a = 42 >>> 3;
 ''', expectedErrors: [
diff --git a/pkg/analyzer/test/src/diagnostics/size_annotation_dimensions_test.dart b/pkg/analyzer/test/src/diagnostics/size_annotation_dimensions_test.dart
new file mode 100644
index 0000000..8a53708
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/size_annotation_dimensions_test.dart
@@ -0,0 +1,67 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All 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/ffi_code.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/context_collection_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(SizeAnnotationDimensions);
+  });
+}
+
+@reflectiveTest
+class SizeAnnotationDimensions extends PubPackageResolutionTest {
+  test_error_array_2_3() async {
+    await assertErrorsInCode(r'''
+import 'dart:ffi';
+
+class C extends Struct {
+  @Array(8, 8)
+  Array<Array<Array<Uint8>>> a0;
+}
+''', [
+      error(FfiCode.SIZE_ANNOTATION_DIMENSIONS, 47, 12),
+    ]);
+  }
+
+  test_error_array_3_2() async {
+    await assertErrorsInCode(r'''
+import 'dart:ffi';
+
+class C extends Struct {
+  @Array(8, 8, 8)
+  Array<Array<Uint8>> a0;
+}
+''', [
+      error(FfiCode.SIZE_ANNOTATION_DIMENSIONS, 47, 15),
+    ]);
+  }
+
+  test_error_multi_2_3() async {
+    await assertErrorsInCode(r'''
+import 'dart:ffi';
+
+class C extends Struct {
+  @Array.multi([8, 8])
+  Array<Array<Array<Uint8>>> a0;
+}
+''', [
+      error(FfiCode.SIZE_ANNOTATION_DIMENSIONS, 47, 20),
+    ]);
+  }
+
+  test_no_error() async {
+    await assertNoErrorsInCode(r'''
+import 'dart:ffi';
+
+class C extends Struct {
+  @Array(8, 8)
+  Array<Array<Uint8>> a0;
+}
+''');
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/test_all.dart b/pkg/analyzer/test/src/diagnostics/test_all.dart
index 11cd8e8..6bd56ae 100644
--- a/pkg/analyzer/test/src/diagnostics/test_all.dart
+++ b/pkg/analyzer/test/src/diagnostics/test_all.dart
@@ -147,6 +147,7 @@
     as expected_one_set_type_arguments;
 import 'expected_two_map_type_arguments_test.dart'
     as expected_two_map_type_arguments;
+import 'experiment_not_enabled_test.dart' as experiment_not_enabled;
 import 'export_internal_library_test.dart' as export_internal_library;
 import 'export_legacy_symbol_test.dart' as export_legacy_symbol;
 import 'export_of_non_library_test.dart' as export_of_non_library;
@@ -154,6 +155,8 @@
 import 'extends_deferred_class_test.dart' as extends_deferred_class;
 import 'extends_disallowed_class_test.dart' as extends_disallowed_class;
 import 'extends_non_class_test.dart' as extends_non_class;
+import 'extends_type_alias_expands_to_type_parameter_test.dart'
+    as extends_type_alias_expands_to_type_parameter;
 import 'extension_as_expression_test.dart' as extension_as_expression;
 import 'extension_conflicting_static_and_instance_test.dart'
     as extension_conflicting_static_and_instance;
@@ -228,7 +231,10 @@
 import 'implements_deferred_class_test.dart' as implements_deferred_class;
 import 'implements_disallowed_class_test.dart' as implements_disallowed_class;
 import 'implements_non_class_test.dart' as implements_non_class;
+import 'implements_repeated_test.dart' as implements_repeated;
 import 'implements_super_class_test.dart' as implements_super_class;
+import 'implements_type_alias_expands_to_type_parameter_test.dart'
+    as implements_type_alias_expands_to_type_parameter;
 import 'implicit_this_reference_in_initializer_test.dart'
     as implicit_this_reference_in_initializer;
 import 'import_deferred_library_with_load_function_test.dart'
@@ -391,7 +397,11 @@
     as mixin_inherits_from_not_object;
 import 'mixin_of_disallowed_class_test.dart' as mixin_of_disallowed_class;
 import 'mixin_of_non_class_test.dart' as mixin_of_non_class;
+import 'mixin_of_type_alias_expands_to_type_parameter_test.dart'
+    as mixin_of_type_alias_expands_to_type_parameter;
 import 'mixin_on_sealed_class_test.dart' as mixin_on_sealed_class;
+import 'mixin_on_type_alias_expands_to_type_parameter_test.dart'
+    as mixin_on_type_alias_expands_to_type_parameter;
 import 'mixin_super_class_constraint_non_interface_test.dart'
     as mixin_super_class_constraint_non_interface;
 import 'mixin_with_non_class_superclass_test.dart'
@@ -488,6 +498,7 @@
 import 'nullable_type_in_with_clause_test.dart' as nullable_type_in_with_clause;
 import 'object_cannot_extend_another_class_test.dart'
     as object_cannot_extend_another_class;
+import 'on_repeated_test.dart' as on_repeated;
 import 'optional_parameter_in_operator_test.dart'
     as optional_parameter_in_operator;
 import 'override_on_non_overriding_field_test.dart'
@@ -498,6 +509,9 @@
     as override_on_non_overriding_method;
 import 'override_on_non_overriding_setter_test.dart'
     as override_on_non_overriding_setter;
+import 'packed_annotation_alignment_test.dart' as packed_annotation_alignment;
+import 'packed_annotation_test.dart' as packed_annotation;
+import 'packed_nesting_non_packed_test.dart' as packed_nesting_non_packed;
 import 'part_of_different_library_test.dart' as part_of_different_library;
 import 'part_of_non_part_test.dart' as part_of_non_part;
 import 'prefix_collides_with_top_level_member_test.dart'
@@ -571,6 +585,7 @@
 import 'set_element_type_not_assignable_test.dart'
     as set_element_type_not_assignable;
 import 'shared_deferred_prefix_test.dart' as shared_deferred_prefix;
+import 'size_annotation_dimensions_test.dart' as size_annotation_dimensions;
 import 'spread_expression_from_deferred_library_test.dart'
     as spread_expression_from_deferred_library;
 import 'static_access_to_instance_member_test.dart'
@@ -637,6 +652,7 @@
 import 'unnecessary_non_null_assertion_test.dart'
     as unnecessary_non_null_assertion;
 import 'unnecessary_null_comparison_test.dart' as unnecessary_null_comparison;
+import 'unnecessary_question_mark_test.dart' as unnecessary_question_mark;
 import 'unnecessary_type_check_test.dart' as unnecessary_type_check;
 import 'unqualified_reference_to_non_local_static_member_test.dart'
     as unqualified_reference_to_non_local_static_member;
@@ -771,6 +787,7 @@
     expected_one_list_type_arguments.main();
     expected_one_set_type_arguments.main();
     expected_two_map_type_arguments.main();
+    experiment_not_enabled.main();
     export_internal_library.main();
     export_legacy_symbol.main();
     export_of_non_library.main();
@@ -778,6 +795,7 @@
     extends_deferred_class.main();
     extends_disallowed_class.main();
     extends_non_class.main();
+    extends_type_alias_expands_to_type_parameter.main();
     extension_as_expression.main();
     extension_conflicting_static_and_instance.main();
     extension_declares_abstract_method.main();
@@ -822,7 +840,9 @@
     implements_deferred_class.main();
     implements_disallowed_class.main();
     implements_non_class.main();
+    implements_repeated.main();
     implements_super_class.main();
+    implements_type_alias_expands_to_type_parameter.main();
     implicit_this_reference_in_initializer.main();
     import_deferred_library_with_load_function.main();
     import_internal_library.main();
@@ -926,7 +946,9 @@
     mixin_inherits_from_not_object.main();
     mixin_of_disallowed_class.main();
     mixin_of_non_class.main();
+    mixin_of_type_alias_expands_to_type_parameter.main();
     mixin_on_sealed_class.main();
+    mixin_on_type_alias_expands_to_type_parameter.main();
     mixin_super_class_constraint_non_interface.main();
     mixin_with_non_class_superclass.main();
     mixins_super_class.main();
@@ -994,11 +1016,15 @@
     nullable_type_in_on_clause.main();
     nullable_type_in_with_clause.main();
     object_cannot_extend_another_class.main();
+    on_repeated.main();
     optional_parameter_in_operator.main();
     override_on_non_overriding_field.main();
     override_on_non_overriding_getter.main();
     override_on_non_overriding_method.main();
     override_on_non_overriding_setter.main();
+    packed_annotation.main();
+    packed_annotation_alignment.main();
+    packed_nesting_non_packed.main();
     part_of_different_library.main();
     part_of_non_part.main();
     prefix_collides_with_top_level_member.main();
@@ -1044,6 +1070,7 @@
     sdk_version_ui_as_code_in_const_context.main();
     set_element_type_not_assignable.main();
     shared_deferred_prefix.main();
+    size_annotation_dimensions.main();
     spread_expression_from_deferred_library.main();
     static_access_to_instance_member.main();
     strict_raw_type.main();
@@ -1096,6 +1123,7 @@
     unnecessary_no_such_method.main();
     unnecessary_non_null_assertion.main();
     unnecessary_null_comparison.main();
+    unnecessary_question_mark.main();
     unnecessary_type_check.main();
     unqualified_reference_to_non_local_static_member.main();
     unqualified_reference_to_static_member_of_extended_type.main();
diff --git a/pkg/analyzer/test/src/diagnostics/type_annotation_deferred_class_test.dart b/pkg/analyzer/test/src/diagnostics/type_annotation_deferred_class_test.dart
index 1068226..c622fb0 100644
--- a/pkg/analyzer/test/src/diagnostics/type_annotation_deferred_class_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/type_annotation_deferred_class_test.dart
@@ -15,6 +15,20 @@
 
 @reflectiveTest
 class TypeAnnotationDeferredClassTest extends PubPackageResolutionTest {
+  test_annotation_typeArgument() async {
+    newFile('$testPackageLibPath/lib1.dart', content: '''
+class D {}
+''');
+    await assertErrorsInCode('''
+library root;
+import 'lib1.dart' deferred as a;
+class C<T> { const C(); }
+@C<a.D>() main () {}
+''', [
+      error(CompileTimeErrorCode.TYPE_ANNOTATION_DEFERRED_CLASS, 77, 3),
+    ]);
+  }
+
   test_asExpression() async {
     newFile('$testPackageLibPath/lib1.dart', content: '''
 library lib1;
diff --git a/pkg/analyzer/test/src/diagnostics/type_argument_not_matching_bounds_test.dart b/pkg/analyzer/test/src/diagnostics/type_argument_not_matching_bounds_test.dart
index b9850fb..25184c2 100644
--- a/pkg/analyzer/test/src/diagnostics/type_argument_not_matching_bounds_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/type_argument_not_matching_bounds_test.dart
@@ -451,6 +451,143 @@
 ''');
   }
 
+  test_genericFunctionTypeArgument_invariant() async {
+    await assertErrorsInCode(r'''
+typedef F = T Function<T>(T);
+typedef FB<T extends F> = S Function<S extends T>(S);
+class CB<T extends F> {}
+void f(CB<FB<F>> a) {}
+''', [
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 119, 5),
+    ]);
+  }
+
+  test_genericFunctionTypeArgument_regularBounded() async {
+    await assertNoErrorsInCode(r'''
+typedef F1 = T Function<T>(T);
+typedef F2 = S Function<S>(S);
+class CB<T extends F1> {}
+void f(CB<F2> a) {}
+''');
+  }
+
+  test_metadata_matching() async {
+    await assertNoErrorsInCode(r'''
+class A<T extends num> {
+  const A();
+}
+
+@A<int>()
+void f() {}
+''');
+  }
+
+  test_metadata_notMatching() async {
+    await assertErrorsInCode(r'''
+class A<T extends num> {
+  const A();
+}
+
+@A<String>()
+void f() {}
+''', [
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 44, 6),
+    ]);
+  }
+
+  test_metadata_notMatching_viaTypeAlias() async {
+    await assertErrorsInCode(r'''
+class A<T> {
+  const A();
+}
+
+typedef B<T extends num> = A<T>;
+
+@B<String>()
+void f() {}
+''', [
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 66, 6),
+    ]);
+  }
+
+  test_methodInvocation_genericFunctionTypeArgument_match() async {
+    await assertNoErrorsInCode(r'''
+typedef F = void Function<T extends num>();
+void f<T extends void Function<X extends num>()>() {}
+void g() {
+  f<F>();
+}
+''');
+  }
+
+  test_methodInvocation_genericFunctionTypeArgument_mismatch() async {
+    await assertErrorsInCode(r'''
+class A {}
+class B {}
+typedef F = void Function<T extends A>();
+void f<T extends void Function<U extends B>()>() {}
+void g() {
+  f<F>();
+}
+''', [
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 131, 1),
+    ]);
+  }
+
+  test_nonFunctionTypeAlias_body_typeArgument_mismatch() async {
+    await assertErrorsInCode(r'''
+class A {}
+class B {}
+class G<T extends A> {}
+typedef X = G<B>;
+''', [
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 60, 1),
+    ]);
+  }
+
+  test_nonFunctionTypeAlias_body_typeArgument_regularBounded() async {
+    await assertNoErrorsInCode(r'''
+class A {}
+class B extends A {}
+class G<T extends A> {}
+typedef X = G<B>;
+''');
+  }
+
+  test_nonFunctionTypeAlias_body_typeArgument_superBounded() async {
+    await assertNoErrorsInCode(r'''
+class A<T extends A<T>> {}
+typedef X = List<A>;
+''');
+  }
+
+  test_nonFunctionTypeAlias_interfaceType_body_mismatch() async {
+    await assertErrorsInCode(r'''
+class A {}
+class B {}
+class G<T extends A> {}
+typedef X = G<B>;
+''', [
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 60, 1),
+    ]);
+  }
+
+  test_nonFunctionTypeAlias_interfaceType_body_regularBounded() async {
+    await assertNoErrorsInCode(r'''
+class A<T> {}
+typedef X<T> = A;
+''');
+  }
+
+  test_nonFunctionTypeAlias_interfaceType_body_superBounded() async {
+    await assertErrorsInCode(r'''
+class A<T extends A<T>> {}
+typedef X<T> = A;
+''', [
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 42, 1),
+    ]);
+  }
+
   test_nonFunctionTypeAlias_interfaceType_parameter() async {
     await assertErrorsInCode(r'''
 class A {}
@@ -470,15 +607,7 @@
 ''');
   }
 
-  test_nonFunctionTypeAlias_interfaceType_parameter_superBounded() async {
-    await assertNoErrorsInCode(r'''
-class A {}
-typedef X<T extends A> = Map<int, T>;
-void f(X<Never> a) {}
-''');
-  }
-
-  test_notRegularBounded_notSuperBounded_invariant() async {
+  test_notRegularBounded_notSuperBounded_parameter_invariant() async {
     await assertErrorsInCode(r'''
 typedef A<X> = X Function(X);
 typedef G<X extends A<X>> = void Function<Y extends X>();
diff --git a/pkg/analyzer/test/src/diagnostics/undefined_annotation_test.dart b/pkg/analyzer/test/src/diagnostics/undefined_annotation_test.dart
index 711ac51..b8c6202 100644
--- a/pkg/analyzer/test/src/diagnostics/undefined_annotation_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/undefined_annotation_test.dart
@@ -45,6 +45,26 @@
     ]);
   }
 
+  test_unresolved_prefix() async {
+    await assertErrorsInCode(r'''
+@p.A(0)
+class B {}
+''', [
+      error(CompileTimeErrorCode.UNDEFINED_ANNOTATION, 0, 7),
+    ]);
+  }
+
+  test_unresolved_prefixed() async {
+    await assertErrorsInCode(r'''
+import 'dart:math' as p;
+
+@p.A(0)
+class B {}
+''', [
+      error(CompileTimeErrorCode.UNDEFINED_ANNOTATION, 26, 7),
+    ]);
+  }
+
   test_unresolved_prefixedIdentifier() async {
     await assertErrorsInCode(r'''
 import 'dart:math' as p;
diff --git a/pkg/analyzer/test/src/diagnostics/undefined_getter_test.dart b/pkg/analyzer/test/src/diagnostics/undefined_getter_test.dart
index e00bb5f..193e74a 100644
--- a/pkg/analyzer/test/src/diagnostics/undefined_getter_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/undefined_getter_test.dart
@@ -247,7 +247,7 @@
 }
 ''',
         expectedErrorsByNullability(nullable: [
-          error(CompileTimeErrorCode.INVALID_USE_OF_NULL_VALUE, 22, 5),
+          error(CompileTimeErrorCode.INVALID_USE_OF_NULL_VALUE, 28, 3),
         ], legacy: [
           error(CompileTimeErrorCode.UNDEFINED_GETTER, 28, 3),
         ]));
diff --git a/pkg/analyzer/test/src/diagnostics/unignorable_ignore_test.dart b/pkg/analyzer/test/src/diagnostics/unignorable_ignore_test.dart
index 33ef317..07802b1 100644
--- a/pkg/analyzer/test/src/diagnostics/unignorable_ignore_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/unignorable_ignore_test.dart
@@ -2,7 +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:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
 import 'package:analyzer/src/error/codes.dart';
+import 'package:analyzer/src/lint/linter.dart';
+import 'package:analyzer/src/lint/registry.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import '../dart/resolution/context_collection_resolution.dart';
@@ -15,23 +19,84 @@
 
 @reflectiveTest
 class UnignorableIgnoreTest extends PubPackageResolutionTest {
-  @failingTest
-  test_file() async {
+  test_file_lowerCase() async {
+    writeTestPackageAnalysisOptionsFile(
+      AnalysisOptionsFileConfig(unignorableNames: ['undefined_annotation']),
+    );
     await assertErrorsInCode(r'''
-// ignore_for_file: top_level_cycle
-var x = 0;
+// ignore_for_file: undefined_annotation
+@x int a = 0;
 ''', [
-      error(HintCode.UNIGNORABLE_IGNORE, 20, 15),
+      error(CompileTimeErrorCode.UNDEFINED_ANNOTATION, 41, 2),
     ]);
   }
 
-  @failingTest
-  test_line() async {
+  test_file_upperCase() async {
+    writeTestPackageAnalysisOptionsFile(
+      AnalysisOptionsFileConfig(unignorableNames: ['UNDEFINED_ANNOTATION']),
+    );
     await assertErrorsInCode(r'''
-// ignore: top_level_cycle
-var x = 0;
+// ignore_for_file: UNDEFINED_ANNOTATION
+@x int a = 0;
 ''', [
-      error(HintCode.UNIGNORABLE_IGNORE, 11, 15),
+      error(CompileTimeErrorCode.UNDEFINED_ANNOTATION, 41, 2),
     ]);
   }
+
+  test_line() async {
+    writeTestPackageAnalysisOptionsFile(
+      AnalysisOptionsFileConfig(unignorableNames: ['undefined_annotation']),
+    );
+    await assertErrorsInCode(r'''
+// ignore: undefined_annotation
+@x int a = 0;
+''', [
+      error(CompileTimeErrorCode.UNDEFINED_ANNOTATION, 32, 2),
+    ]);
+  }
+
+  test_lint() async {
+    writeTestPackageAnalysisOptionsFile(
+      AnalysisOptionsFileConfig(
+          unignorableNames: ['avoid_int'], lints: ['avoid_int']),
+    );
+    var avoidIntRule = _AvoidIntRule();
+    Registry.ruleRegistry.register(avoidIntRule);
+    await assertErrorsInCode(r'''
+// ignore: avoid_int
+int a = 0;
+''', [
+      error(avoidIntRule.lintCode, 21, 3),
+    ]);
+  }
+}
+
+class _AvoidIntRule extends LintRule {
+  _AvoidIntRule()
+      : super(
+          name: 'avoid_int',
+          description: '',
+          details: '',
+          group: Group.errors,
+        );
+
+  @override
+  void registerNodeProcessors(
+      NodeLintRegistry registry, LinterContext context) {
+    final visitor = _AvoidIntVisitor(this);
+    registry.addTypeName(this, visitor);
+  }
+}
+
+class _AvoidIntVisitor extends SimpleAstVisitor {
+  final LintRule rule;
+
+  _AvoidIntVisitor(this.rule);
+
+  @override
+  void visitTypeName(TypeName node) {
+    if (node.name.name == 'int') {
+      rule.reportLint(node.name);
+    }
+  }
 }
diff --git a/pkg/analyzer/test/src/diagnostics/unnecessary_question_mark_test.dart b/pkg/analyzer/test/src/diagnostics/unnecessary_question_mark_test.dart
new file mode 100644
index 0000000..337484e
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/unnecessary_question_mark_test.dart
@@ -0,0 +1,52 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All 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(UnnecessaryQuestionMarkTest);
+  });
+}
+
+@reflectiveTest
+class UnnecessaryQuestionMarkTest extends PubPackageResolutionTest {
+  test_dynamic() async {
+    await assertNoErrorsInCode('''
+dynamic a;
+''');
+  }
+
+  test_dynamicQuestionMark() async {
+    await assertErrorsInCode('''
+dynamic? a;
+''', [
+      error(HintCode.UNNECESSARY_QUESTION_MARK, 0, 8),
+    ]);
+  }
+
+  test_Null() async {
+    await assertNoErrorsInCode('''
+Null a;
+''');
+  }
+
+  test_NullQuestionMark() async {
+    await assertErrorsInCode('''
+Null? a;
+''', [
+      error(HintCode.UNNECESSARY_QUESTION_MARK, 0, 5),
+    ]);
+  }
+
+  test_typeAliasQuestionMark() async {
+    await assertNoErrorsInCode('''
+typedef n = Null;
+n? a;
+''');
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/unused_import_test.dart b/pkg/analyzer/test/src/diagnostics/unused_import_test.dart
index b9ac11a..8cce111 100644
--- a/pkg/analyzer/test/src/diagnostics/unused_import_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/unused_import_test.dart
@@ -138,6 +138,19 @@
 ''');
   }
 
+  test_as_systemLibrary() async {
+    newFile('$testPackageLibPath/a.dart', content: '''
+class File {}
+''');
+    await assertErrorsInCode(r'''
+import 'dart:io' as prefix;
+import 'a.dart' as prefix;
+prefix.File? f;
+''', [
+      error(HintCode.UNUSED_IMPORT, 7, 9),
+    ]);
+  }
+
   test_core_library() async {
     await assertNoErrorsInCode(r'''
 import 'dart:core';
@@ -429,6 +442,19 @@
     ]);
   }
 
+  test_systemLibrary() async {
+    newFile('$testPackageLibPath/lib1.dart', content: '''
+class File {}
+''');
+    await assertErrorsInCode(r'''
+import 'dart:io';
+import 'lib1.dart';
+File? f;
+''', [
+      error(HintCode.UNUSED_IMPORT, 7, 9),
+    ]);
+  }
+
   test_unusedImport() async {
     newFile('$testPackageLibPath/lib1.dart');
     await assertErrorsInCode(r'''
diff --git a/pkg/analyzer/test/src/diagnostics/use_of_nullable_value_test.dart b/pkg/analyzer/test/src/diagnostics/use_of_nullable_value_test.dart
index 7ca7f8d..f76dd2b 100644
--- a/pkg/analyzer/test/src/diagnostics/use_of_nullable_value_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/use_of_nullable_value_test.dart
@@ -161,9 +161,9 @@
 }
 ''', [
       error(CompileTimeErrorCode.UNCHECKED_METHOD_INVOCATION_OF_NULLABLE_VALUE,
-          126, 4),
+          130, 1),
       error(CompileTimeErrorCode.UNCHECKED_METHOD_INVOCATION_OF_NULLABLE_VALUE,
-          154, 4),
+          158, 1),
     ]);
   }
 
@@ -206,7 +206,7 @@
       error(CompileTimeErrorCode.UNCHECKED_METHOD_INVOCATION_OF_NULLABLE_VALUE,
           68, 3),
       error(CompileTimeErrorCode.UNCHECKED_METHOD_INVOCATION_OF_NULLABLE_VALUE,
-          79, 4),
+          84, 3),
     ]);
   }
 
@@ -237,7 +237,7 @@
 }
 ''', [
       error(CompileTimeErrorCode.UNCHECKED_METHOD_INVOCATION_OF_NULLABLE_VALUE,
-          78, 4),
+          77, 1),
     ]);
   }
 
@@ -284,7 +284,7 @@
       error(CompileTimeErrorCode.UNCHECKED_PROPERTY_ACCESS_OF_NULLABLE_VALUE,
           93, 3),
       error(CompileTimeErrorCode.UNCHECKED_PROPERTY_ACCESS_OF_NULLABLE_VALUE,
-          102, 4),
+          107, 3),
     ]);
   }
 
@@ -331,7 +331,7 @@
       error(CompileTimeErrorCode.UNCHECKED_METHOD_INVOCATION_OF_NULLABLE_VALUE,
           93, 3),
       error(CompileTimeErrorCode.UNCHECKED_PROPERTY_ACCESS_OF_NULLABLE_VALUE,
-          106, 4),
+          111, 3),
     ]);
   }
 }
@@ -407,7 +407,7 @@
 }
 ''', [
       error(CompileTimeErrorCode.UNCHECKED_PROPERTY_ACCESS_OF_NULLABLE_VALUE,
-          100, 3,
+          104, 1,
           contextMessages: [message('/home/test/lib/test.dart', 56, 1)]),
     ]);
 
@@ -494,7 +494,7 @@
 }
 ''', [
       error(CompileTimeErrorCode.UNCHECKED_METHOD_INVOCATION_OF_NULLABLE_VALUE,
-          109, 5),
+          115, 2),
     ]);
 
     assertAssignment(
@@ -549,7 +549,7 @@
 }
 ''', [
       error(CompileTimeErrorCode.UNCHECKED_PROPERTY_ACCESS_OF_NULLABLE_VALUE,
-          101, 3,
+          105, 1,
           contextMessages: [message('/home/test/lib/test.dart', 56, 1)]),
     ]);
 
@@ -595,7 +595,7 @@
 }
 ''', [
       error(CompileTimeErrorCode.UNCHECKED_METHOD_INVOCATION_OF_NULLABLE_VALUE,
-          31, 1),
+          33, 2),
     ]);
     var assignment1 = findNode.assignment('x +=');
     var assignment2 = findNode.assignment('y +=');
@@ -667,7 +667,7 @@
 }
 ''', [
       error(CompileTimeErrorCode.UNCHECKED_METHOD_INVOCATION_OF_NULLABLE_VALUE,
-          24, 1),
+          27, 1),
     ]);
   }
 
@@ -688,7 +688,7 @@
 }
 ''', [
       error(CompileTimeErrorCode.UNCHECKED_METHOD_INVOCATION_OF_NULLABLE_VALUE,
-          18, 1),
+          21, 3),
     ]);
   }
 
@@ -709,7 +709,7 @@
 }
 ''', [
       error(CompileTimeErrorCode.UNCHECKED_PROPERTY_ACCESS_OF_NULLABLE_VALUE,
-          18, 1),
+          21, 6),
     ]);
   }
 
@@ -766,7 +766,7 @@
 }
 ''', [
       error(CompileTimeErrorCode.UNCHECKED_PROPERTY_ACCESS_OF_NULLABLE_VALUE,
-          58, 1),
+          60, 3),
     ]);
   }
 
@@ -808,7 +808,7 @@
 }
 ''', [
       error(CompileTimeErrorCode.UNCHECKED_METHOD_INVOCATION_OF_NULLABLE_VALUE,
-          19, 1),
+          20, 1),
     ]);
   }
 
@@ -832,6 +832,17 @@
     ]);
   }
 
+  test_invoke_dynamicFunctionType_nullable2() async {
+    await assertErrorsInCode(r'''
+void f<F extends Function>(List<F?> funcList) {
+  funcList[0]();
+}
+''', [
+      error(
+          CompileTimeErrorCode.UNCHECKED_INVOCATION_OF_NULLABLE_VALUE, 50, 11),
+    ]);
+  }
+
   test_invoke_nonNullable() async {
     await assertNoErrorsInCode(r'''
 m() {
@@ -905,7 +916,7 @@
 }
 ''', [
       error(CompileTimeErrorCode.UNCHECKED_PROPERTY_ACCESS_OF_NULLABLE_VALUE,
-          18, 1),
+          20, 6),
     ]);
     assertSimpleIdentifier(
       findNode.simple('isEven'),
@@ -931,7 +942,7 @@
 }
 ''', [
       error(CompileTimeErrorCode.UNCHECKED_PROPERTY_ACCESS_OF_NULLABLE_VALUE,
-          18, 3),
+          22, 6),
     ]);
   }
 
@@ -951,7 +962,7 @@
 }
 ''', [
       error(CompileTimeErrorCode.UNCHECKED_PROPERTY_ACCESS_OF_NULLABLE_VALUE,
-          27, 1),
+          29, 6),
     ]);
   }
 
@@ -1008,7 +1019,7 @@
 }
 ''', [
       error(CompileTimeErrorCode.UNCHECKED_METHOD_INVOCATION_OF_NULLABLE_VALUE,
-          18, 1),
+          20, 5),
     ]);
   }
 
@@ -1023,7 +1034,7 @@
 }
 ''', [
       error(CompileTimeErrorCode.UNCHECKED_METHOD_INVOCATION_OF_NULLABLE_VALUE,
-          54, 1),
+          56, 3),
     ]);
   }
 
@@ -1059,7 +1070,7 @@
 }
 ''', [
       error(CompileTimeErrorCode.UNCHECKED_METHOD_INVOCATION_OF_NULLABLE_VALUE,
-          19, 1),
+          21, 4),
     ]);
   }
 
@@ -1083,7 +1094,7 @@
 ''', [
       error(HintCode.UNUSED_LOCAL_VARIABLE, 13, 1),
       error(CompileTimeErrorCode.UNCHECKED_METHOD_INVOCATION_OF_NULLABLE_VALUE,
-          18, 1),
+          20, 2),
     ]);
   }
 
@@ -1165,7 +1176,7 @@
 ''', [
       error(
           CompileTimeErrorCode.UNCHECKED_OPERATOR_INVOCATION_OF_NULLABLE_VALUE,
-          18,
+          20,
           1),
     ]);
   }
@@ -1188,7 +1199,7 @@
 ''', [
       error(
           CompileTimeErrorCode.UNCHECKED_OPERATOR_INVOCATION_OF_NULLABLE_VALUE,
-          18,
+          20,
           1),
     ]);
   }
@@ -1213,7 +1224,7 @@
 ''', [
       error(HintCode.UNUSED_LOCAL_VARIABLE, 13, 1),
       error(CompileTimeErrorCode.UNCHECKED_METHOD_INVOCATION_OF_NULLABLE_VALUE,
-          18, 1),
+          19, 2),
     ]);
   }
 
@@ -1232,7 +1243,7 @@
 }
 ''', [
       error(CompileTimeErrorCode.UNCHECKED_METHOD_INVOCATION_OF_NULLABLE_VALUE,
-          14, 1),
+          15, 2),
     ]);
   }
 
@@ -1249,7 +1260,7 @@
 }
 ''', [
       error(CompileTimeErrorCode.UNCHECKED_METHOD_INVOCATION_OF_NULLABLE_VALUE,
-          77, 1),
+          78, 2),
     ]);
   }
 
@@ -1273,7 +1284,7 @@
 ''', [
       error(HintCode.UNUSED_LOCAL_VARIABLE, 13, 1),
       error(CompileTimeErrorCode.UNCHECKED_METHOD_INVOCATION_OF_NULLABLE_VALUE,
-          20, 1),
+          18, 2),
     ]);
   }
 
@@ -1292,7 +1303,7 @@
 }
 ''', [
       error(CompileTimeErrorCode.UNCHECKED_METHOD_INVOCATION_OF_NULLABLE_VALUE,
-          16, 1),
+          14, 2),
     ]);
   }
 
@@ -1316,7 +1327,7 @@
 ''', [
       error(HintCode.UNUSED_LOCAL_VARIABLE, 13, 1),
       error(CompileTimeErrorCode.UNCHECKED_METHOD_INVOCATION_OF_NULLABLE_VALUE,
-          19, 1),
+          18, 1),
     ]);
   }
 
@@ -1333,7 +1344,7 @@
 }
 ''', [
       error(CompileTimeErrorCode.UNCHECKED_METHOD_INVOCATION_OF_NULLABLE_VALUE,
-          73, 1),
+          72, 1),
     ]);
   }
 
@@ -1375,7 +1386,7 @@
 }
 ''', [
       error(CompileTimeErrorCode.UNCHECKED_METHOD_INVOCATION_OF_NULLABLE_VALUE,
-          14, 1),
+          16, 2),
     ]);
   }
 
@@ -1392,7 +1403,7 @@
 }
 ''', [
       error(CompileTimeErrorCode.UNCHECKED_PROPERTY_ACCESS_OF_NULLABLE_VALUE,
-          66, 1),
+          68, 1),
     ]);
     var propertyAccess1 = findNode.propertyAccess('a?.x; // 1');
     var propertyAccess2 = findNode.prefixed('a.x; // 2');
@@ -1424,7 +1435,7 @@
 }
 ''', [
       error(CompileTimeErrorCode.UNCHECKED_PROPERTY_ACCESS_OF_NULLABLE_VALUE,
-          101, 3,
+          105, 1,
           contextMessages: [message('/home/test/lib/test.dart', 56, 1)]),
     ]);
     var propertyAccess1 = findNode.propertyAccess('b.a?.x; // 1');
@@ -1457,7 +1468,7 @@
 }
 ''', [
       error(CompileTimeErrorCode.UNCHECKED_PROPERTY_ACCESS_OF_NULLABLE_VALUE,
-          101, 1),
+          103, 1),
     ]);
     var propertyAccess1 = findNode.propertyAccess('x; // 1');
     var propertyAccess2 = findNode.propertyAccess('x; // 2');
@@ -1494,7 +1505,7 @@
 }
 ''', [
       error(CompileTimeErrorCode.UNCHECKED_PROPERTY_ACCESS_OF_NULLABLE_VALUE,
-          142, 5,
+          148, 1,
           contextMessages: [message('/home/test/lib/test.dart', 56, 1)]),
     ]);
     var propertyAccess1 = findNode.propertyAccess('x; // 1');
@@ -1532,7 +1543,7 @@
 }
 ''', [
       error(CompileTimeErrorCode.UNCHECKED_PROPERTY_ACCESS_OF_NULLABLE_VALUE,
-          148, 3,
+          152, 1,
           contextMessages: [message('/home/test/lib/test.dart', 101, 1)]),
     ]);
     var propertyAccess1 = findNode.propertyAccess('x; // 1');
@@ -1619,8 +1630,8 @@
 ''', [
       error(
           CompileTimeErrorCode.UNCHECKED_OPERATOR_INVOCATION_OF_NULLABLE_VALUE,
-          17,
-          9),
+          27,
+          3),
     ]);
   }
 
diff --git a/pkg/analyzer/test/src/diagnostics/wrong_number_of_type_arguments_test.dart b/pkg/analyzer/test/src/diagnostics/wrong_number_of_type_arguments_test.dart
index 29e3eee..6754881 100644
--- a/pkg/analyzer/test/src/diagnostics/wrong_number_of_type_arguments_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/wrong_number_of_type_arguments_test.dart
@@ -93,6 +93,90 @@
     ]);
   }
 
+  test_metadata_1of0() async {
+    await assertErrorsInCode(r'''
+class A {
+  const A();
+}
+
+@A<int>()
+void f() {}
+''', [
+      error(CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS, 28, 5),
+    ]);
+  }
+
+  test_metadata_1of0_viaTypeAlias() async {
+    await assertErrorsInCode(r'''
+class A {
+  const A();
+}
+
+typedef B = A;
+
+@B<int>()
+void f() {}
+''', [
+      error(CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS, 44, 5),
+    ]);
+  }
+
+  test_metadata_1of2() async {
+    await assertErrorsInCode(r'''
+class A<T, U> {
+  const A();
+}
+
+@A<int>()
+void f() {}
+''', [
+      error(CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS, 34, 5),
+    ]);
+  }
+
+  test_metadata_1of2_viaTypeAlias() async {
+    await assertErrorsInCode(r'''
+class A {
+  const A();
+}
+
+typedef B<T, U> = A;
+
+@B<int>()
+void f() {}
+''', [
+      error(CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS, 50, 5),
+    ]);
+  }
+
+  test_metadata_2of1() async {
+    await assertErrorsInCode(r'''
+class A<T> {
+  const A();
+}
+
+@A<int, String>()
+void f() {}
+''', [
+      error(CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS, 31, 13),
+    ]);
+  }
+
+  test_metadata_2of1_viaTypeAlias() async {
+    await assertErrorsInCode(r'''
+class A {
+  const A();
+}
+
+typedef B<T> = A;
+
+@B<int, String>()
+void f() {}
+''', [
+      error(CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS, 47, 13),
+    ]);
+  }
+
   test_new_nonGeneric() async {
     await assertErrorsInCode('''
 class C {}
diff --git a/pkg/analyzer/test/src/diagnostics/wrong_type_parameter_variance_in_superinterface_test.dart b/pkg/analyzer/test/src/diagnostics/wrong_type_parameter_variance_in_superinterface_test.dart
index 71e8ff7..52b3fab 100644
--- a/pkg/analyzer/test/src/diagnostics/wrong_type_parameter_variance_in_superinterface_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/wrong_type_parameter_variance_in_superinterface_test.dart
@@ -317,8 +317,6 @@
           CompileTimeErrorCode.WRONG_TYPE_PARAMETER_VARIANCE_IN_SUPERINTERFACE,
           22,
           1),
-      error(CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT,
-          35, 28),
     ]);
   }
 }
diff --git a/pkg/analyzer/test/src/diagnostics/yield_of_invalid_type_test.dart b/pkg/analyzer/test/src/diagnostics/yield_of_invalid_type_test.dart
index a107230..a5453bd 100644
--- a/pkg/analyzer/test/src/diagnostics/yield_of_invalid_type_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/yield_of_invalid_type_test.dart
@@ -86,6 +86,19 @@
     ]);
   }
 
+  test_none_asyncStar_int_to_streamString_functionExpression() async {
+    await assertErrorsInCode('''
+void f() {
+  // ignore:unused_local_variable
+  Stream<String> Function() v = () async* {
+    yield 1;
+  };
+}
+''', [
+      error(CompileTimeErrorCode.YIELD_OF_INVALID_TYPE, 99, 1),
+    ]);
+  }
+
   test_none_asyncStar_int_to_untyped() async {
     await assertNoErrorsInCode('''
 f() async* {
@@ -152,6 +165,19 @@
     ]);
   }
 
+  test_none_syncStar_int_to_iterableString_functionExpression() async {
+    await assertErrorsInCode('''
+void f() {
+  // ignore:unused_local_variable
+  Iterable<String> Function() v = () sync* {
+    yield 1;
+  };
+}
+''', [
+      error(CompileTimeErrorCode.YIELD_OF_INVALID_TYPE, 100, 1),
+    ]);
+  }
+
   test_none_syncStar_int_to_stream() async {
     await assertErrorsInCode('''
 Stream<int> f() sync* {
diff --git a/pkg/analyzer/test/src/fasta/recovery/partial_code/typedef_test.dart b/pkg/analyzer/test/src/fasta/recovery/partial_code/typedef_test.dart
index fc7f670..bd6536c 100644
--- a/pkg/analyzer/test/src/fasta/recovery/partial_code/typedef_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/partial_code/typedef_test.dart
@@ -50,11 +50,11 @@
               [
                 ParserErrorCode.EXPECTED_TYPE_NAME,
                 ParserErrorCode.EXPECTED_TOKEN,
-                ParserErrorCode.INVALID_GENERIC_FUNCTION_TYPE
+                ParserErrorCode.EXPERIMENT_NOT_ENABLED
               ],
               "typedef T = _s_;",
               expectedErrorsInValidCode: [
-                ParserErrorCode.INVALID_GENERIC_FUNCTION_TYPE
+                ParserErrorCode.EXPERIMENT_NOT_ENABLED
               ],
               failing: ['functionVoid', 'functionNonVoid', 'getter', 'mixin']),
         ],
diff --git a/pkg/analyzer/test/src/lint/lint_rule_test.dart b/pkg/analyzer/test/src/lint/lint_rule_test.dart
index 5db743a..9298033 100644
--- a/pkg/analyzer/test/src/lint/lint_rule_test.dart
+++ b/pkg/analyzer/test/src/lint/lint_rule_test.dart
@@ -87,7 +87,7 @@
 
   @override
   void reportErrorForToken(ErrorCode errorCode, Token token,
-      [List<Object?>? arguments]) {
+      [List<Object?>? arguments, List<DiagnosticMessage>? messages]) {
     code = errorCode;
   }
 }
diff --git a/pkg/analyzer/test/src/lint/linter/linter_context_impl_test.dart b/pkg/analyzer/test/src/lint/linter/linter_context_impl_test.dart
index f7e2b7d..99cce62 100644
--- a/pkg/analyzer/test/src/lint/linter/linter_context_impl_test.dart
+++ b/pkg/analyzer/test/src/lint/linter/linter_context_impl_test.dart
@@ -311,6 +311,13 @@
     expect(context.canBeConst(node), expectedResult);
   }
 
+  void test_listLiteral_false_forElement() async {
+    await resolve('''
+f() => [for (var i = 0; i < 10; i++) i];
+''');
+    assertCanBeConst('[for', false);
+  }
+
   void test_listLiteral_false_methodInvocation() async {
     await resolve('''
 f() => [g()];
@@ -354,6 +361,14 @@
     assertCanBeConst('[', true);
   }
 
+  void test_listLiteral_true_ifElement() async {
+    await resolve('''
+const a = true;
+f() => [if (a) 0 else 1];
+''');
+    assertCanBeConst('[if', true);
+  }
+
   void test_listLiteral_true_integerLiteral() async {
     await resolve('''
 f() => [1, 2, 3];
@@ -361,6 +376,13 @@
     assertCanBeConst('[', true);
   }
 
+  void test_mapLiteral_false_forElement() async {
+    await resolve('''
+f() => {for (var i = 0; i < 10; i++) i: 0};
+''');
+    assertCanBeConst('{', false);
+  }
+
   void test_mapLiteral_false_methodInvocation_key() async {
     await resolve('''
 f() => {g(): 0};
@@ -377,6 +399,14 @@
     assertCanBeConst('{', false);
   }
 
+  void test_mapLiteral_true_ifElement() async {
+    await resolve('''
+const a = true;
+f() => {if (a) 0: 0 else 1: 1};
+''');
+    assertCanBeConst('{', true);
+  }
+
   void test_mapLiteral_true_integerLiteral() async {
     await resolve('''
 f() => {1: 2, 3: 4};
@@ -384,6 +414,13 @@
     assertCanBeConst('{', true);
   }
 
+  void test_setLiteral_false_forElement() async {
+    await resolve('''
+f() => {for (var i = 0; i < 10; i++) i};
+''');
+    assertCanBeConst('{for', false);
+  }
+
   void test_setLiteral_false_methodInvocation() async {
     await resolve('''
 f() => {g()};
@@ -392,6 +429,14 @@
     assertCanBeConst('{', false);
   }
 
+  void test_setLiteral_true_ifElement() async {
+    await resolve('''
+const a = true;
+f() => {if (a) 0 else 1};
+''');
+    assertCanBeConst('{', true);
+  }
+
   void test_setLiteral_true_integerLiteral() async {
     await resolve('''
 f() => {1, 2, 3};
diff --git a/pkg/analyzer/test/src/summary/element_text.dart b/pkg/analyzer/test/src/summary/element_text.dart
index 69609aa..a159287 100644
--- a/pkg/analyzer/test/src/summary/element_text.dart
+++ b/pkg/analyzer/test/src/summary/element_text.dart
@@ -11,6 +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/summary2/reference.dart';
 import 'package:analyzer/src/task/inference_error.dart';
 import 'package:test/test.dart';
 
@@ -47,6 +48,7 @@
 void checkElementText(
   LibraryElement library,
   String expected, {
+  bool withAliasElementArguments = false,
   bool withCodeRanges = false,
   bool withConstElements = true,
   bool withExportScope = false,
@@ -59,6 +61,7 @@
 }) {
   var writer = _ElementWriter(
     selfUriStr: '${library.source.uri}',
+    withAliasElementArguments: withAliasElementArguments,
     withCodeRanges: withCodeRanges,
     withConstElements: withConstElements,
     withExportScope: withExportScope,
@@ -129,6 +132,7 @@
 /// Writes the canonical text presentation of elements.
 class _ElementWriter {
   final String? selfUriStr;
+  final bool withAliasElementArguments;
   final bool withCodeRanges;
   final bool withExportScope;
   final bool withFullyResolvedAst;
@@ -144,6 +148,7 @@
 
   _ElementWriter({
     this.selfUriStr,
+    this.withAliasElementArguments = false,
     this.withCodeRanges = false,
     this.withConstElements = true,
     this.withExportScope = false,
@@ -1011,6 +1016,17 @@
   void writeType(DartType type) {
     var typeStr = _typeStr(type);
     buffer.write(typeStr);
+
+    if (withAliasElementArguments) {
+      var aliasElement = type.aliasElement;
+      if (aliasElement is TypeAliasElementImpl) {
+        buffer.write('<aliasElement: ');
+        buffer.write(_referenceToString(aliasElement.reference!));
+        var typeArguments = type.aliasArguments!;
+        writeList(', aliasArguments: [', ']', typeArguments, ', ', writeType);
+        buffer.write('>');
+      }
+    }
   }
 
   void writeType2(DartType type) {
@@ -1175,6 +1191,25 @@
     return components.join(';');
   }
 
+  String _referenceToString(Reference reference) {
+    var parent = reference.parent!;
+    if (parent.parent == null) {
+      var libraryUriStr = reference.name;
+      if (libraryUriStr == selfUriStr) {
+        return 'self';
+      }
+      return libraryUriStr;
+    }
+
+    // Ignore the unit, skip to the library.
+    if (parent.name == '@unit') {
+      return _referenceToString(parent.parent!);
+    }
+
+    var name = reference.name;
+    return _referenceToString(parent) + '::$name';
+  }
+
   String? _typeStr(DartType? type) {
     return type?.getDisplayString(
       withNullability: true,
diff --git a/pkg/analyzer/test/src/summary/resolved_ast_printer.dart b/pkg/analyzer/test/src/summary/resolved_ast_printer.dart
index 3b4f286..b90d591 100644
--- a/pkg/analyzer/test/src/summary/resolved_ast_printer.dart
+++ b/pkg/analyzer/test/src/summary/resolved_ast_printer.dart
@@ -71,6 +71,7 @@
       _writeNode('constructorName', node.constructorName);
       _writeElement('element', node.element);
       _writeNode('name', node.name);
+      _writeNode('typeArguments', node.typeArguments);
     });
   }
 
diff --git a/pkg/analyzer/test/src/summary/resynthesize_common.dart b/pkg/analyzer/test/src/summary/resynthesize_common.dart
index 43a2c53..7403527 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_common.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_common.dart
@@ -11,6 +11,7 @@
 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/source/package_map_resolver.dart';
 import 'package:analyzer/src/test_utilities/mock_sdk.dart';
 import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
 import 'package:pub_semver/pub_semver.dart';
@@ -40,6 +41,11 @@
     sourceFactory = SourceFactory(
       [
         DartUriResolver(sdk),
+        PackageMapUriResolver(resourceProvider, {
+          'test': [
+            getFolder('/home/test/lib'),
+          ],
+        }),
         ResourceUriResolver(resourceProvider),
       ],
     );
@@ -60,8 +66,9 @@
 
   Source addSource(String path, String contents) {
     var file = newFile(path, content: contents);
-    var source = file.createSource();
-    return source;
+    var fileSource = file.createSource();
+    var uri = sourceFactory.restoreUri(fileSource)!;
+    return sourceFactory.forUri2(uri)!;
   }
 
   Source addTestSource(String code, [Uri? uri]) {
@@ -88,6 +95,11 @@
     sdkLanguageVersion: Version.parse('2.12.0'),
     flags: [EnableString.nonfunction_type_aliases],
   );
+
+  static final FeatureSet genericMetadata = FeatureSet.fromEnableFlags2(
+    sdkLanguageVersion: Version.parse('2.13.0'),
+    flags: [EnableString.generic_metadata],
+  );
 }
 
 /// Mixin containing test cases exercising summary resynthesis.  Intended to be
@@ -1753,6 +1765,33 @@
 ''');
   }
 
+  test_class_typeParameters_defaultType_cycle_genericFunctionType() async {
+    var library = await checkLibrary(r'''
+class A<T extends void Function(A)> {}
+''');
+    checkElementText(
+        library,
+        r'''
+notSimplyBounded class A<covariant T extends void Function(A<dynamic>)> {
+}
+''',
+        withTypeParameterVariance: true);
+  }
+
+  test_class_typeParameters_defaultType_cycle_genericFunctionType2() async {
+    featureSet = FeatureSets.genericMetadata;
+    var library = await checkLibrary(r'''
+class C<T extends void Function<U extends C>()> {}
+''');
+    checkElementText(
+        library,
+        r'''
+notSimplyBounded class C<covariant T extends void Function<U extends C<dynamic>>()> {
+}
+''',
+        withTypeParameterVariance: true);
+  }
+
   test_class_typeParameters_defaultType_functionTypeAlias_contravariant_legacy() async {
     featureSet = FeatureSets.beforeNullSafe;
     var library = await checkLibrary(r'''
@@ -9068,46 +9107,81 @@
   }
 
   test_invalid_annotation_prefixed_constructor() async {
-    addLibrarySource('/a.dart', r'''
-class C {
-  const C.named();
+    testFile = convertPath('/home/test/lib/test.dart');
+    addLibrarySource('/home/test/lib/a.dart', r'''
+class A {
+  const A.named();
 }
 ''');
     var library = await checkLibrary('''
 import "a.dart" as a;
-@a.C.named
-class D {}
+@a.A.named
+class C {}
 ''');
-    checkElementText(library, r'''
-import 'a.dart' as a;
-@
-        a/*location: test.dart;a*/.
-        C/*location: a.dart;C*/.
-        named/*location: a.dart;C;named*/
-class D {
+    checkElementText(
+        library,
+        r'''
+import 'package:test/a.dart' as a;
+class C {
 }
-''');
+  metadata
+    Annotation
+      constructorName: SimpleIdentifier
+        staticElement: package:test/a.dart::@class::A::@constructor::named
+        staticType: null
+        token: named
+      element: package:test/a.dart::@class::A::@constructor::named
+      name: PrefixedIdentifier
+        identifier: SimpleIdentifier
+          staticElement: package:test/a.dart::@class::A
+          staticType: null
+          token: A
+        period: .
+        prefix: SimpleIdentifier
+          staticElement: self::@prefix::a
+          staticType: null
+          token: a
+        staticElement: package:test/a.dart::@class::A
+        staticType: null
+''',
+        withFullyResolvedAst: true);
   }
 
   test_invalid_annotation_unprefixed_constructor() async {
-    addLibrarySource('/a.dart', r'''
-class C {
-  const C.named();
+    testFile = convertPath('/home/test/lib/test.dart');
+    addLibrarySource('/home/test/lib/a.dart', r'''
+class A {
+  const A.named();
 }
 ''');
     var library = await checkLibrary('''
 import "a.dart";
-@C.named
-class D {}
+@A.named
+class C {}
 ''');
-    checkElementText(library, r'''
-import 'a.dart';
-@
-        C/*location: a.dart;C*/.
-        named/*location: a.dart;C;named*/
-class D {
+    checkElementText(
+        library,
+        r'''
+import 'package:test/a.dart';
+class C {
 }
-''');
+  metadata
+    Annotation
+      element: package:test/a.dart::@class::A::@constructor::named
+      name: PrefixedIdentifier
+        identifier: SimpleIdentifier
+          staticElement: package:test/a.dart::@class::A::@constructor::named
+          staticType: null
+          token: named
+        period: .
+        prefix: SimpleIdentifier
+          staticElement: package:test/a.dart::@class::A
+          staticType: null
+          token: A
+        staticElement: package:test/a.dart::@class::A::@constructor::named
+        staticType: null
+''',
+        withFullyResolvedAst: true);
   }
 
   test_invalid_importPrefix_asTypeArgument() async {
@@ -9615,41 +9689,347 @@
   }
 
   test_metadata_constructor_call_named() async {
+    testFile = convertPath('/home/test/lib/test.dart');
     var library = await checkLibrary('''
 class A {
-  const A.named();
+  const A.named(int _);
 }
-@A.named()
+@A.named(0)
 class C {}
 ''');
-    checkElementText(library, r'''
+    checkElementText(
+        library,
+        r'''
+class A {
+  const A.named(int _);
+}
+class C {
+}
+  metadata
+    Annotation
+      arguments: ArgumentList
+        arguments
+          IntegerLiteral
+            literal: 0
+            staticType: int
+      element: self::@class::A::@constructor::named
+      name: PrefixedIdentifier
+        identifier: SimpleIdentifier
+          staticElement: self::@class::A::@constructor::named
+          staticType: null
+          token: named
+        period: .
+        prefix: SimpleIdentifier
+          staticElement: self::@class::A
+          staticType: null
+          token: A
+        staticElement: self::@class::A::@constructor::named
+        staticType: null
+''',
+        withFullyResolvedAst: true);
+  }
+
+  test_metadata_constructor_call_named_generic_inference() async {
+    featureSet = FeatureSets.genericMetadata;
+    var library = await checkLibrary('''
+class A<T> {
+  const A.named(T _);
+}
+
+@A.named(0)
+class C {}
+''');
+    checkElementText(
+        library,
+        r'''
+class A {
+  const A.named(T _);
+}
+  typeParameters
+    T
+      bound: null
+      defaultType: dynamic
+class C {
+}
+  metadata
+    Annotation
+      arguments: ArgumentList
+        arguments
+          IntegerLiteral
+            literal: 0
+            staticType: int
+      element: ConstructorMember
+        base: self::@class::A::@constructor::named
+        substitution: {T: int}
+      name: PrefixedIdentifier
+        identifier: SimpleIdentifier
+          staticElement: ConstructorMember
+            base: self::@class::A::@constructor::named
+            substitution: {T: int}
+          staticType: null
+          token: named
+        period: .
+        prefix: SimpleIdentifier
+          staticElement: self::@class::A
+          staticType: null
+          token: A
+        staticElement: ConstructorMember
+          base: self::@class::A::@constructor::named
+          substitution: {T: int}
+        staticType: null
+''',
+        withFullyResolvedAst: true);
+  }
+
+  test_metadata_constructor_call_named_generic_typeArguments() async {
+    featureSet = FeatureSets.genericMetadata;
+    var library = await checkLibrary('''
+class A<T> {
+  const A.named();
+}
+
+@A<int>.named()
+class C {}
+''');
+    checkElementText(
+        library,
+        r'''
 class A {
   const A.named();
 }
-@
-        A/*location: test.dart;A*/.
-        named/*location: test.dart;A;named*/()
+  typeParameters
+    T
+      bound: null
+      defaultType: dynamic
 class C {
 }
+  metadata
+    Annotation
+      arguments: ArgumentList
+      constructorName: SimpleIdentifier
+        staticElement: ConstructorMember
+          base: self::@class::A::@constructor::named
+          substitution: {T: int}
+        staticType: null
+        token: named
+      element: ConstructorMember
+        base: self::@class::A::@constructor::named
+        substitution: {T: int}
+      name: SimpleIdentifier
+        staticElement: self::@class::A
+        staticType: null
+        token: A
+      typeArguments: TypeArgumentList
+        arguments
+          TypeName
+            name: SimpleIdentifier
+              staticElement: dart:core::@class::int
+              staticType: null
+              token: int
+            type: int
+''',
+        withFullyResolvedAst: true);
+  }
+
+  test_metadata_constructor_call_named_generic_typeArguments_disabledGenericMetadata() async {
+    var library = await checkLibrary('''
+class A<T> {
+  const A.named();
+}
+
+@A<int>.named()
+class C {}
 ''');
+    checkElementText(
+        library,
+        r'''
+class A {
+  const A.named();
+}
+  typeParameters
+    T
+      bound: null
+      defaultType: dynamic
+class C {
+}
+  metadata
+    Annotation
+      arguments: ArgumentList
+      constructorName: SimpleIdentifier
+        staticElement: ConstructorMember
+          base: self::@class::A::@constructor::named
+          substitution: {T: dynamic}
+        staticType: null
+        token: named
+      element: ConstructorMember
+        base: self::@class::A::@constructor::named
+        substitution: {T: dynamic}
+      name: SimpleIdentifier
+        staticElement: self::@class::A
+        staticType: null
+        token: A
+      typeArguments: TypeArgumentList
+        arguments
+          TypeName
+            name: SimpleIdentifier
+              staticElement: dart:core::@class::int
+              staticType: null
+              token: int
+            type: int
+''',
+        withFullyResolvedAst: true);
   }
 
   test_metadata_constructor_call_named_prefixed() async {
-    addLibrarySource('/foo.dart', 'class A { const A.named(); }');
-    var library = await checkLibrary('''
-import 'foo.dart' as foo;
-@foo.A.named()
-class C {}
-''');
-    checkElementText(library, r'''
-import 'foo.dart' as foo;
-@
-        foo/*location: test.dart;foo*/.
-        A/*location: foo.dart;A*/.
-        named/*location: foo.dart;A;named*/()
-class C {
+    testFile = convertPath('/home/test/lib/test.dart');
+    addLibrarySource('/home/test/lib/foo.dart', '''
+class A {
+  const A.named(int _);
 }
 ''');
+    var library = await checkLibrary('''
+import 'foo.dart' as foo;
+@foo.A.named(0)
+class C {}
+''');
+    checkElementText(
+        library,
+        r'''
+import 'package:test/foo.dart' as foo;
+class C {
+}
+  metadata
+    Annotation
+      arguments: ArgumentList
+        arguments
+          IntegerLiteral
+            literal: 0
+            staticType: int
+      constructorName: SimpleIdentifier
+        staticElement: package:test/foo.dart::@class::A::@constructor::named
+        staticType: null
+        token: named
+      element: package:test/foo.dart::@class::A::@constructor::named
+      name: PrefixedIdentifier
+        identifier: SimpleIdentifier
+          staticElement: package:test/foo.dart::@class::A
+          staticType: null
+          token: A
+        period: .
+        prefix: SimpleIdentifier
+          staticElement: self::@prefix::foo
+          staticType: null
+          token: foo
+        staticElement: package:test/foo.dart::@class::A
+        staticType: null
+''',
+        withFullyResolvedAst: true);
+  }
+
+  test_metadata_constructor_call_named_prefixed_generic_inference() async {
+    featureSet = FeatureSets.genericMetadata;
+    addLibrarySource('/home/test/lib/foo.dart', '''
+class A<T> {
+  const A.named(T _);
+}
+''');
+    testFile = convertPath('/home/test/lib/test.dart');
+    var library = await checkLibrary('''
+import "foo.dart" as foo;
+@foo.A.named(0)
+class C {}
+''');
+    checkElementText(
+        library,
+        r'''
+import 'package:test/foo.dart' as foo;
+class C {
+}
+  metadata
+    Annotation
+      arguments: ArgumentList
+        arguments
+          IntegerLiteral
+            literal: 0
+            staticType: int
+      constructorName: SimpleIdentifier
+        staticElement: ConstructorMember
+          base: package:test/foo.dart::@class::A::@constructor::named
+          substitution: {T: int}
+        staticType: null
+        token: named
+      element: ConstructorMember
+        base: package:test/foo.dart::@class::A::@constructor::named
+        substitution: {T: int}
+      name: PrefixedIdentifier
+        identifier: SimpleIdentifier
+          staticElement: package:test/foo.dart::@class::A
+          staticType: null
+          token: A
+        period: .
+        prefix: SimpleIdentifier
+          staticElement: self::@prefix::foo
+          staticType: null
+          token: foo
+        staticElement: package:test/foo.dart::@class::A
+        staticType: null
+''',
+        withFullyResolvedAst: true);
+  }
+
+  test_metadata_constructor_call_named_prefixed_generic_typeArguments() async {
+    featureSet = FeatureSets.genericMetadata;
+    addLibrarySource('/home/test/lib/foo.dart', '''
+class A<T> {
+  const A.named();
+}
+''');
+    testFile = convertPath('/home/test/lib/test.dart');
+    var library = await checkLibrary('''
+import "foo.dart" as foo;
+@foo.A<int>.named()
+class C {}
+''');
+    checkElementText(
+        library,
+        r'''
+import 'package:test/foo.dart' as foo;
+class C {
+}
+  metadata
+    Annotation
+      arguments: ArgumentList
+      constructorName: SimpleIdentifier
+        staticElement: ConstructorMember
+          base: package:test/foo.dart::@class::A::@constructor::named
+          substitution: {T: int}
+        staticType: null
+        token: named
+      element: ConstructorMember
+        base: package:test/foo.dart::@class::A::@constructor::named
+        substitution: {T: int}
+      name: PrefixedIdentifier
+        identifier: SimpleIdentifier
+          staticElement: package:test/foo.dart::@class::A
+          staticType: null
+          token: A
+        period: .
+        prefix: SimpleIdentifier
+          staticElement: self::@prefix::foo
+          staticType: null
+          token: foo
+        staticElement: package:test/foo.dart::@class::A
+        staticType: null
+      typeArguments: TypeArgumentList
+        arguments
+          TypeName
+            name: SimpleIdentifier
+              staticElement: dart:core::@class::int
+              staticType: null
+              token: int
+            type: int
+''',
+        withFullyResolvedAst: true);
   }
 
   test_metadata_constructor_call_named_synthetic_ofClassAlias_generic() async {
@@ -9660,7 +10040,7 @@
 
 mixin B {}
 
-class C<T> = A with B; 
+class C<T> = A with B;
 
 @C.named()
 class D {}
@@ -9709,30 +10089,249 @@
   }
 
   test_metadata_constructor_call_unnamed() async {
-    var library = await checkLibrary('class A { const A(); } @A() class C {}');
-    checkElementText(library, r'''
+    testFile = convertPath('/home/test/lib/test.dart');
+    var library = await checkLibrary('''
+class A {
+  const A(int _);
+}
+@A(0)
+class C {}
+''');
+    checkElementText(
+        library,
+        r'''
+class A {
+  const A(int _);
+}
+class C {
+}
+  metadata
+    Annotation
+      arguments: ArgumentList
+        arguments
+          IntegerLiteral
+            literal: 0
+            staticType: int
+      element: self::@class::A::@constructor::•
+      name: SimpleIdentifier
+        staticElement: self::@class::A
+        staticType: null
+        token: A
+''',
+        withFullyResolvedAst: true);
+  }
+
+  test_metadata_constructor_call_unnamed_generic_inference() async {
+    featureSet = FeatureSets.genericMetadata;
+    var library = await checkLibrary('''
+class A<T> {
+  const A(T _);
+}
+
+@A(0)
+class C {}
+''');
+    checkElementText(
+        library,
+        r'''
+class A {
+  const A(T _);
+}
+  typeParameters
+    T
+      bound: null
+      defaultType: dynamic
+class C {
+}
+  metadata
+    Annotation
+      arguments: ArgumentList
+        arguments
+          IntegerLiteral
+            literal: 0
+            staticType: int
+      element: ConstructorMember
+        base: self::@class::A::@constructor::•
+        substitution: {T: int}
+      name: SimpleIdentifier
+        staticElement: self::@class::A
+        staticType: null
+        token: A
+''',
+        withFullyResolvedAst: true);
+  }
+
+  test_metadata_constructor_call_unnamed_generic_typeArguments() async {
+    featureSet = FeatureSets.genericMetadata;
+    var library = await checkLibrary('''
+class A<T> {
+  const A();
+}
+
+@A<int>()
+class C {}
+''');
+    checkElementText(
+        library,
+        r'''
 class A {
   const A();
 }
-@
-        A/*location: test.dart;A*/()
+  typeParameters
+    T
+      bound: null
+      defaultType: dynamic
 class C {
 }
-''');
+  metadata
+    Annotation
+      arguments: ArgumentList
+      element: ConstructorMember
+        base: self::@class::A::@constructor::•
+        substitution: {T: int}
+      name: SimpleIdentifier
+        staticElement: self::@class::A
+        staticType: null
+        token: A
+      typeArguments: TypeArgumentList
+        arguments
+          TypeName
+            name: SimpleIdentifier
+              staticElement: dart:core::@class::int
+              staticType: null
+              token: int
+            type: int
+''',
+        withFullyResolvedAst: true);
   }
 
   test_metadata_constructor_call_unnamed_prefixed() async {
-    addLibrarySource('/foo.dart', 'class A { const A(); }');
+    testFile = convertPath('/home/test/lib/test.dart');
+    addLibrarySource('/home/test/lib/foo.dart', 'class A { const A(_); }');
     var library =
-        await checkLibrary('import "foo.dart" as foo; @foo.A() class C {}');
-    checkElementText(library, r'''
-import 'foo.dart' as foo;
-@
-        foo/*location: test.dart;foo*/.
-        A/*location: foo.dart;A*/()
+        await checkLibrary('import "foo.dart" as foo; @foo.A(0) class C {}');
+    checkElementText(
+        library,
+        r'''
+import 'package:test/foo.dart' as foo;
 class C {
 }
+  metadata
+    Annotation
+      arguments: ArgumentList
+        arguments
+          IntegerLiteral
+            literal: 0
+            staticType: int
+      element: package:test/foo.dart::@class::A::@constructor::•
+      name: PrefixedIdentifier
+        identifier: SimpleIdentifier
+          staticElement: package:test/foo.dart::@class::A
+          staticType: null
+          token: A
+        period: .
+        prefix: SimpleIdentifier
+          staticElement: self::@prefix::foo
+          staticType: null
+          token: foo
+        staticElement: package:test/foo.dart::@class::A
+        staticType: null
+''',
+        withFullyResolvedAst: true);
+  }
+
+  test_metadata_constructor_call_unnamed_prefixed_generic_inference() async {
+    featureSet = FeatureSets.genericMetadata;
+    addLibrarySource('/home/test/lib/foo.dart', '''
+class A<T> {
+  const A(T _);
+}
 ''');
+    testFile = convertPath('/home/test/lib/test.dart');
+    var library = await checkLibrary('''
+import "foo.dart" as foo;
+@foo.A(0)
+class C {}
+''');
+    checkElementText(
+        library,
+        r'''
+import 'package:test/foo.dart' as foo;
+class C {
+}
+  metadata
+    Annotation
+      arguments: ArgumentList
+        arguments
+          IntegerLiteral
+            literal: 0
+            staticType: int
+      element: ConstructorMember
+        base: package:test/foo.dart::@class::A::@constructor::•
+        substitution: {T: int}
+      name: PrefixedIdentifier
+        identifier: SimpleIdentifier
+          staticElement: package:test/foo.dart::@class::A
+          staticType: null
+          token: A
+        period: .
+        prefix: SimpleIdentifier
+          staticElement: self::@prefix::foo
+          staticType: null
+          token: foo
+        staticElement: package:test/foo.dart::@class::A
+        staticType: null
+''',
+        withFullyResolvedAst: true);
+  }
+
+  test_metadata_constructor_call_unnamed_prefixed_generic_typeArguments() async {
+    featureSet = FeatureSets.genericMetadata;
+    addLibrarySource('/home/test/lib/foo.dart', '''
+class A<T> {
+  const A();
+}
+''');
+    testFile = convertPath('/home/test/lib/test.dart');
+    var library = await checkLibrary('''
+import "foo.dart" as foo;
+@foo.A<int>()
+class C {}
+''');
+    checkElementText(
+        library,
+        r'''
+import 'package:test/foo.dart' as foo;
+class C {
+}
+  metadata
+    Annotation
+      arguments: ArgumentList
+      element: ConstructorMember
+        base: package:test/foo.dart::@class::A::@constructor::•
+        substitution: {T: int}
+      name: PrefixedIdentifier
+        identifier: SimpleIdentifier
+          staticElement: package:test/foo.dart::@class::A
+          staticType: null
+          token: A
+        period: .
+        prefix: SimpleIdentifier
+          staticElement: self::@prefix::foo
+          staticType: null
+          token: foo
+        staticElement: package:test/foo.dart::@class::A
+        staticType: null
+      typeArguments: TypeArgumentList
+        arguments
+          TypeName
+            name: SimpleIdentifier
+              staticElement: dart:core::@class::int
+              staticType: null
+              token: int
+            type: int
+''',
+        withFullyResolvedAst: true);
   }
 
   test_metadata_constructor_call_unnamed_synthetic_ofClassAlias_generic() async {
@@ -9743,7 +10342,7 @@
 
 mixin B {}
 
-class C<T> = A with B; 
+class C<T> = A with B;
 
 @C()
 class D {}
@@ -9819,33 +10418,113 @@
   }
 
   test_metadata_enumConstantDeclaration() async {
-    var library = await checkLibrary('const a = null; enum E { @a v }');
-    checkElementText(library, r'''
+    var library = await checkLibrary('const a = 42; enum E { @a v }');
+    checkElementText(
+        library,
+        r'''
 enum E {
   synthetic final int index;
   synthetic static const List<E> values;
-  @
-        a/*location: test.dart;a?*/
   static const E v;
+    metadata
+      Annotation
+        element: self::@getter::a
+        name: SimpleIdentifier
+          staticElement: self::@getter::a
+          staticType: null
+          token: a
   String toString() {}
 }
-const dynamic a = null;
+const int a;
+  constantInitializer
+    IntegerLiteral
+      literal: 42
+      staticType: int
+''',
+        withFullyResolvedAst: true);
+  }
+
+  test_metadata_enumConstantDeclaration_instanceCreation() async {
+    var library = await checkLibrary('''
+class A {
+  final dynamic value;
+  const A(this.value);
+}
+
+enum E {
+  @A(100) a,
+  b,
+  @A(300) c,
+}
 ''');
+    checkElementText(
+        library,
+        r'''
+enum E {
+  synthetic final int index;
+  synthetic static const List<E> values;
+  static const E a;
+    metadata
+      Annotation
+        arguments: ArgumentList
+          arguments
+            IntegerLiteral
+              literal: 100
+              staticType: int
+        element: self::@class::A::@constructor::•
+        name: SimpleIdentifier
+          staticElement: self::@class::A
+          staticType: null
+          token: A
+  static const E b;
+  static const E c;
+    metadata
+      Annotation
+        arguments: ArgumentList
+          arguments
+            IntegerLiteral
+              literal: 300
+              staticType: int
+        element: self::@class::A::@constructor::•
+        name: SimpleIdentifier
+          staticElement: self::@class::A
+          staticType: null
+          token: A
+  String toString() {}
+}
+class A {
+  final dynamic value;
+  const A(dynamic this.value);
+}
+''',
+        withFullyResolvedAst: true);
   }
 
   test_metadata_enumDeclaration() async {
-    var library = await checkLibrary('const a = null; @a enum E { v }');
-    checkElementText(library, r'''
-@
-        a/*location: test.dart;a?*/
+    var library = await checkLibrary('const a = 42; @a enum E { v }');
+    checkElementText(
+        library,
+        r'''
 enum E {
   synthetic final int index;
   synthetic static const List<E> values;
   static const E v;
   String toString() {}
 }
-const dynamic a = null;
-''');
+  metadata
+    Annotation
+      element: self::@getter::a
+      name: SimpleIdentifier
+        staticElement: self::@getter::a
+        staticType: null
+        token: a
+const int a;
+  constantInitializer
+    IntegerLiteral
+      literal: 42
+      staticType: int
+''',
+        withFullyResolvedAst: true);
   }
 
   test_metadata_exportDirective() async {
@@ -10427,6 +11106,166 @@
 ''');
   }
 
+  test_metadata_value_class_staticField() async {
+    testFile = convertPath('/home/test/lib/test.dart');
+    var library = await checkLibrary('''
+class A {
+  static const x = 0;
+}
+@A.x
+class C {}
+''');
+    checkElementText(
+        library,
+        r'''
+class A {
+  static const int x;
+    constantInitializer
+      IntegerLiteral
+        literal: 0
+        staticType: int
+}
+class C {
+}
+  metadata
+    Annotation
+      element: self::@class::A::@getter::x
+      name: PrefixedIdentifier
+        identifier: SimpleIdentifier
+          staticElement: self::@class::A::@getter::x
+          staticType: null
+          token: x
+        period: .
+        prefix: SimpleIdentifier
+          staticElement: self::@class::A
+          staticType: null
+          token: A
+        staticElement: self::@class::A::@getter::x
+        staticType: null
+''',
+        withFullyResolvedAst: true);
+  }
+
+  test_metadata_value_enum_constant() async {
+    testFile = convertPath('/home/test/lib/test.dart');
+    var library = await checkLibrary('''
+enum E {a, b, c}
+@E.b
+class C {}
+''');
+    checkElementText(
+        library,
+        r'''
+enum E {
+  synthetic final int index;
+  synthetic static const List<E> values;
+  static const E a;
+  static const E b;
+  static const E c;
+  String toString() {}
+}
+class C {
+}
+  metadata
+    Annotation
+      element: self::@enum::E::@getter::b
+      name: PrefixedIdentifier
+        identifier: SimpleIdentifier
+          staticElement: self::@enum::E::@getter::b
+          staticType: null
+          token: b
+        period: .
+        prefix: SimpleIdentifier
+          staticElement: self::@enum::E
+          staticType: null
+          token: E
+        staticElement: self::@enum::E::@getter::b
+        staticType: null
+''',
+        withFullyResolvedAst: true);
+  }
+
+  test_metadata_value_extension_staticField() async {
+    testFile = convertPath('/home/test/lib/test.dart');
+    var library = await checkLibrary('''
+extension E on int {
+  static const x = 0;
+}
+@E.x
+class C {}
+''');
+    checkElementText(
+        library,
+        r'''
+class C {
+}
+  metadata
+    Annotation
+      element: self::@extension::E::@getter::x
+      name: PrefixedIdentifier
+        identifier: SimpleIdentifier
+          staticElement: self::@extension::E::@getter::x
+          staticType: null
+          token: x
+        period: .
+        prefix: SimpleIdentifier
+          staticElement: self::@extension::E
+          staticType: null
+          token: E
+        staticElement: self::@extension::E::@getter::x
+        staticType: null
+extension E on int {
+  static const int x;
+    constantInitializer
+      IntegerLiteral
+        literal: 0
+        staticType: int
+}
+''',
+        withFullyResolvedAst: true);
+  }
+
+  test_metadata_value_prefix_extension_staticField() async {
+    testFile = convertPath('/home/test/lib/test.dart');
+    addLibrarySource('/home/test/lib/foo.dart', '''
+extension E on int {
+  static const x = 0;
+}
+''');
+    var library = await checkLibrary('''
+import 'foo.dart' as foo;
+@foo.E.x
+class C {}
+''');
+    checkElementText(
+        library,
+        r'''
+import 'package:test/foo.dart' as foo;
+class C {
+}
+  metadata
+    Annotation
+      constructorName: SimpleIdentifier
+        staticElement: package:test/foo.dart::@extension::E::@getter::x
+        staticType: null
+        token: x
+      element: package:test/foo.dart::@extension::E::@getter::x
+      name: PrefixedIdentifier
+        identifier: SimpleIdentifier
+          staticElement: package:test/foo.dart::@extension::E
+          staticType: null
+          token: E
+        period: .
+        prefix: SimpleIdentifier
+          staticElement: self::@prefix::foo
+          staticType: null
+          token: foo
+        staticElement: package:test/foo.dart::@extension::E
+        staticType: null
+''',
+        withFullyResolvedAst: true);
+  }
+
   test_method_documented() async {
     var library = await checkLibrary('''
 class C {
@@ -10595,6 +11434,18 @@
 ''');
   }
 
+  test_mixin_first() async {
+    var library = await checkLibrary(r'''
+mixin M {}
+''');
+
+    // We intentionally ask `mixins` directly, to check that we can ask them
+    // separately, without asking classes.
+    var mixins = library.definingCompilationUnit.mixins;
+    expect(mixins, hasLength(1));
+    expect(mixins[0].name, 'M');
+  }
+
   test_mixin_implicitObjectSuperclassConstraint() async {
     var library = await checkLibrary(r'''
 mixin M {}
@@ -12425,6 +13276,126 @@
 ''');
   }
 
+  @FailingTest(
+    issue: 'https://github.com/dart-lang/sdk/issues/45291',
+    reason: 'Type dynamic is special, no support for its aliases yet',
+  )
+  test_typedef_nonFunction_aliasElement_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<aliasElement: self::@typeAlias::A> a) {}
+''',
+        withAliasElementArguments: true);
+  }
+
+  test_typedef_nonFunction_aliasElement_functionType() async {
+    featureSet = FeatureSets.nonFunctionTypeAliases;
+    var library = await checkLibrary(r'''
+typedef A1 = void Function();
+typedef A2<R> = R Function();
+void f1(A1 a) {}
+void f2(A2<int> a) {}
+''');
+
+    checkElementText(
+        library,
+        r'''
+typedef A1 = void Function();
+typedef A2<R> = R Function();
+void f1(void Function()<aliasElement: self::@typeAlias::A1> a) {}
+void f2(int Function()<aliasElement: self::@typeAlias::A2, aliasArguments: [int]> a) {}
+''',
+        withAliasElementArguments: true);
+  }
+
+  test_typedef_nonFunction_aliasElement_interfaceType() async {
+    featureSet = FeatureSets.nonFunctionTypeAliases;
+    var library = await checkLibrary(r'''
+typedef A1 = List<int>;
+typedef A2<T, U> = Map<T, U>;
+void f1(A1 a) {}
+void f2(A2<int, String> a) {}
+''');
+
+    checkElementText(
+        library,
+        r'''
+typedef A1 = List<int>;
+typedef A2<T, U> = Map<T, U>;
+void f1(List<int><aliasElement: self::@typeAlias::A1> a) {}
+void f2(Map<int, String><aliasElement: self::@typeAlias::A2, aliasArguments: [int, String]> a) {}
+''',
+        withAliasElementArguments: true);
+  }
+
+  @FailingTest(
+    issue: 'https://github.com/dart-lang/sdk/issues/45291',
+    reason: 'Type Never is special, no support for its aliases yet',
+  )
+  test_typedef_nonFunction_aliasElement_never() async {
+    featureSet = FeatureSets.nonFunctionTypeAliases;
+    var library = await checkLibrary(r'''
+typedef A1 = Never;
+typedef A2<T> = Never?;
+void f1(A1 a) {}
+void f2(A2<int> a) {}
+''');
+
+    checkElementText(
+        library,
+        r'''
+typedef A1 = Never;
+typedef A2<T> = Never?;
+void f1(Never<aliasElement: self::@typeAlias::A1> a) {}
+void f2(Never?<aliasElement: self::@typeAlias::A2, aliasArguments: [int]> a) {}
+''',
+        withAliasElementArguments: true);
+  }
+
+  test_typedef_nonFunction_aliasElement_typeParameterType() async {
+    featureSet = FeatureSets.nonFunctionTypeAliases;
+    var library = await checkLibrary(r'''
+typedef A<T> = T;
+void f<U>(A<U> a) {}
+''');
+
+    checkElementText(
+        library,
+        r'''
+typedef A<T> = T;
+void f<U>(U<aliasElement: self::@typeAlias::A, aliasArguments: [U]> a) {}
+''',
+        withAliasElementArguments: true);
+  }
+
+  @FailingTest(
+    issue: 'https://github.com/dart-lang/sdk/issues/45291',
+    reason: 'Type void is special, no support for its aliases yet',
+  )
+  test_typedef_nonFunction_aliasElement_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<aliasElement: self::@typeAlias::A> a) {}
+''',
+        withAliasElementArguments: true);
+  }
+
   test_typedef_nonFunction_asInterfaceType_interfaceType_none() async {
     featureSet = FeatureSets.nonFunctionTypeAliases;
     var library = await checkLibrary(r'''
diff --git a/pkg/analyzer/test/src/summary/top_level_inference_test.dart b/pkg/analyzer/test/src/summary/top_level_inference_test.dart
index fb39435..fc25b65 100644
--- a/pkg/analyzer/test/src/summary/top_level_inference_test.dart
+++ b/pkg/analyzer/test/src/summary/top_level_inference_test.dart
@@ -2712,7 +2712,7 @@
 
     var path = convertPath(testFilePath);
     var analysisSession = contextFor(path).currentSession;
-    var result = (await analysisSession.getUnitElement(path))!;
+    var result = await analysisSession.getUnitElement(path);
     return result.element.library;
   }
 }
diff --git a/pkg/analyzer/test/src/task/options_test.dart b/pkg/analyzer/test/src/task/options_test.dart
index 150398a..1deba37c 100644
--- a/pkg/analyzer/test/src/task/options_test.dart
+++ b/pkg/analyzer/test/src/task/options_test.dart
@@ -43,6 +43,43 @@
   YamlMap parseOptions(String source) =>
       optionsProvider.getOptionsFromString(source);
 
+  test_configure_cannotIgnore() {
+    configureContext('''
+analyzer:
+  cannot-ignore:
+    - one_error_code
+    - another
+''');
+
+    var unignorableNames = analysisOptions.unignorableNames;
+    expect(unignorableNames, unorderedEquals(['ONE_ERROR_CODE', 'ANOTHER']));
+  }
+
+  test_configure_cannotIgnore_severity() {
+    configureContext('''
+analyzer:
+  cannot-ignore:
+    - error
+''');
+
+    var unignorableNames = analysisOptions.unignorableNames;
+    expect(unignorableNames, contains('INVALID_ANNOTATION'));
+    expect(unignorableNames.length, greaterThan(500));
+  }
+
+  test_configure_cannotIgnore_severity_withProcessor() {
+    configureContext('''
+analyzer:
+  errors:
+    unused_import: error
+  cannot-ignore:
+    - error
+''');
+
+    var unignorableNames = analysisOptions.unignorableNames;
+    expect(unignorableNames, contains('UNUSED_IMPORT'));
+  }
+
   test_configure_chromeos_checks() {
     configureContext('''
 analyzer:
@@ -104,6 +141,19 @@
     expect(excludes, unorderedEquals(['foo/bar.dart', 'test/**']));
   }
 
+  test_configure_excludes_withNonStrings() {
+    configureContext('''
+analyzer:
+  exclude:
+    - foo/bar.dart
+    - 'test/**'
+    - a: b
+''');
+
+    List<String> excludes = analysisOptions.excludePatterns;
+    expect(excludes, unorderedEquals(['foo/bar.dart', 'test/**']));
+  }
+
   test_configure_plugins_list() {
     configureContext('''
 analyzer:
@@ -205,6 +255,56 @@
   final OptionsFileValidator validator = OptionsFileValidator(TestSource());
   final AnalysisOptionsProvider optionsProvider = AnalysisOptionsProvider();
 
+  test_analyzer_cannotIgnore_badValue() {
+    validate('''
+analyzer:
+  cannot-ignore:
+    - not_an_error_code
+''', [AnalysisOptionsWarningCode.UNRECOGNIZED_ERROR_CODE]);
+  }
+
+  test_analyzer_cannotIgnore_goodValue() {
+    validate('''
+analyzer:
+  cannot-ignore:
+    - invalid_annotation
+''', []);
+  }
+
+  test_analyzer_cannotIgnore_lintRule() {
+    Registry.ruleRegistry.register(TestRule());
+    validate('''
+analyzer:
+  cannot-ignore:
+    - fantastic_test_rule
+''', []);
+  }
+
+  test_analyzer_cannotIgnore_notAList() {
+    validate('''
+analyzer:
+  cannot-ignore:
+    one_error_code: true
+''', [AnalysisOptionsWarningCode.INVALID_SECTION_FORMAT]);
+  }
+
+  test_analyzer_cannotIgnore_severity() {
+    validate('''
+analyzer:
+  cannot-ignore:
+    - error
+''', []);
+  }
+
+  test_analyzer_cannotIgnore_valueNotAString() {
+    validate('''
+analyzer:
+  cannot-ignore:
+    one_error_code:
+      foo: bar
+''', [AnalysisOptionsWarningCode.INVALID_SECTION_FORMAT]);
+  }
+
   test_analyzer_enableExperiment_badValue() {
     validate('''
 analyzer:
@@ -248,6 +348,24 @@
     ''', [AnalysisOptionsWarningCode.UNRECOGNIZED_ERROR_CODE]);
   }
 
+  test_analyzer_errors_notAMap() {
+    validate('''
+analyzer:
+  errors:
+    - invalid_annotation
+    - unused_import
+    ''', [AnalysisOptionsWarningCode.INVALID_SECTION_FORMAT]);
+  }
+
+  test_analyzer_errors_valueNotAScalar() {
+    validate('''
+analyzer:
+  errors:
+    invalid_annotation: ignore
+    unused_import: [1, 2, 3]
+    ''', [AnalysisOptionsWarningCode.INVALID_SECTION_FORMAT]);
+  }
+
   test_analyzer_language_bad_format_list() {
     validate('''
 analyzer:
@@ -284,14 +402,14 @@
 analyzer:
   errors:
     fantastic_test_rule: ignore
-    ''', []);
+''', []);
   }
 
   test_analyzer_strong_mode_deprecated() {
     validate('''
 analyzer:
   strong-mode: true
-    ''', [AnalysisOptionsHintCode.STRONG_MODE_SETTING_DEPRECATED]);
+''', [AnalysisOptionsHintCode.STRONG_MODE_SETTING_DEPRECATED]);
   }
 
   test_analyzer_strong_mode_deprecated_key() {
@@ -314,7 +432,15 @@
     validate('''
 analyzer:
   strong-mode: false
-    ''', [AnalysisOptionsWarningCode.SPEC_MODE_REMOVED]);
+''', [AnalysisOptionsWarningCode.SPEC_MODE_REMOVED]);
+  }
+
+  test_analyzer_strong_mode_notAMap() {
+    validate('''
+analyzer:
+  strong-mode:
+    - implicit_casts
+''', [AnalysisOptionsWarningCode.INVALID_SECTION_FORMAT]);
   }
 
   test_analyzer_strong_mode_unsupported_key() {
@@ -338,21 +464,21 @@
 analyzer:
   exclude:
     - test/_data/p4/lib/lib1.dart
-    ''', []);
+''', []);
   }
 
   test_analyzer_supported_strong_mode_supported_bad_value() {
     validate('''
 analyzer:
   strong-mode: w00t
-    ''', [AnalysisOptionsWarningCode.UNSUPPORTED_VALUE]);
+''', [AnalysisOptionsWarningCode.UNSUPPORTED_VALUE]);
   }
 
   test_analyzer_unsupported_option() {
     validate('''
 analyzer:
   not_supported: true
-    ''', [AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUES]);
+''', [AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUES]);
   }
 
   test_chromeos_manifest_checks() {
@@ -371,6 +497,14 @@
 ''', [AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUE]);
   }
 
+  test_chromeos_manifest_checks_notAMap() {
+    validate('''
+analyzer:
+  optional-checks:
+    - chrome-os-manifest-checks
+''', [AnalysisOptionsWarningCode.INVALID_SECTION_FORMAT]);
+  }
+
   test_linter_supported_rules() {
     Registry.ruleRegistry.register(TestRule());
     validate('''
diff --git a/pkg/analyzer/test/src/test_all.dart b/pkg/analyzer/test/src/test_all.dart
index 02ae355..9969e39 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 'command_line/test_all.dart' as command_line;
 import 'context/test_all.dart' as context;
 import 'dart/test_all.dart' as dart;
 import 'dartdoc/test_all.dart' as dartdoc;
@@ -26,7 +25,6 @@
 
 main() {
   defineReflectiveSuite(() {
-    command_line.main();
     context.main();
     dart.main();
     dartdoc.main();
diff --git a/pkg/analyzer/test/src/utilities/extensions/string_test.dart b/pkg/analyzer/test/src/utilities/extensions/string_test.dart
index 2d9d373..ccf3226 100644
--- a/pkg/analyzer/test/src/utilities/extensions/string_test.dart
+++ b/pkg/analyzer/test/src/utilities/extensions/string_test.dart
@@ -32,7 +32,7 @@
   }
 
   void test_commaSeparatedWithAnd_zero() {
-    expect(<String>[].commaSeparatedWithOr, isEmpty);
+    expect(<String>[].commaSeparatedWithAnd, isEmpty);
   }
 
   void test_commaSeparatedWithOr_five() {
@@ -55,4 +55,21 @@
   void test_commaSeparatedWithOr_zero() {
     expect(<String>[].commaSeparatedWithOr, isEmpty);
   }
+
+  void test_quotedAndCommaSeparatedWithAnd_one() {
+    expect(<String>['a'].quotedAndCommaSeparatedWithAnd, "'a'");
+  }
+
+  void test_quotedAndCommaSeparatedWithAnd_three() {
+    expect(<String>['a', 'b', 'c'].quotedAndCommaSeparatedWithAnd,
+        "'a', 'b', and 'c'");
+  }
+
+  void test_quotedAndCommaSeparatedWithAnd_two() {
+    expect(<String>['a', 'b'].quotedAndCommaSeparatedWithAnd, "'a' and 'b'");
+  }
+
+  void test_quotedAndCommaSeparatedWithAnd_zero() {
+    expect(<String>[].quotedAndCommaSeparatedWithAnd, isEmpty);
+  }
 }
diff --git a/pkg/analyzer/test/src/workspace/bazel_test.dart b/pkg/analyzer/test/src/workspace/bazel_test.dart
index fe83186..3e22df8 100644
--- a/pkg/analyzer/test/src/workspace/bazel_test.dart
+++ b/pkg/analyzer/test/src/workspace/bazel_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:async';
-
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/summary/package_bundle_reader.dart';
 import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
@@ -11,7 +9,6 @@
 import 'package:async/async.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:watcher/watcher.dart';
 
 import '../../generated/test_support.dart';
 
@@ -811,120 +808,6 @@
 class BazelWorkspaceTest with ResourceProviderMixin {
   late final BazelWorkspace workspace;
 
-  void test_bazelFileWatcher() async {
-    _addResources([
-      '/workspace/WORKSPACE',
-    ]);
-    late _MockTimer timer;
-    var timerFactory = (Duration _, void Function(Timer) callback) {
-      timer = _MockTimer(callback);
-      return timer;
-    };
-    var candidates = [
-      convertPath('/workspace/bazel-bin/my/module/test1.dart'),
-      convertPath('/workspace/bazel-genfiles/my/module/test1.dart'),
-    ];
-    var watcher = BazelFileWatcher(candidates, resourceProvider, Duration.zero,
-        Duration.zero, timerFactory);
-    var events = StreamQueue(watcher.events);
-    watcher.start();
-
-    // First do some tests with the first candidate path.
-    _addResources([candidates[0]]);
-    timer.triggerCallback();
-
-    var event = await events.next;
-    expect(event.type, ChangeType.ADD);
-    expect(event.path, candidates[0]);
-
-    modifyFile(candidates[0], 'const foo = 42;');
-    timer.triggerCallback();
-
-    event = await events.next;
-    expect(event.type, ChangeType.MODIFY);
-    expect(event.path, candidates[0]);
-
-    _deleteResources([candidates[0]]);
-    timer.triggerCallback();
-
-    event = await events.next;
-    expect(event.type, ChangeType.REMOVE);
-    expect(event.path, candidates[0]);
-
-    // Now check that if we add the *second* candidate, we'll get the
-    // notification for it.
-    _addResources([candidates[1]]);
-    timer.triggerCallback();
-
-    event = await events.next;
-    expect(event.type, ChangeType.ADD);
-    expect(event.path, candidates[1]);
-
-    watcher.stop();
-    expect(await events.rest.isEmpty, true);
-  }
-
-  void test_bazelFileWatcher_existingFile() async {
-    _addResources([
-      '/workspace/WORKSPACE',
-      '/workspace/bazel-bin/my/module/test1.dart',
-    ]);
-    var workspace = BazelWorkspace.find(
-        resourceProvider, convertPath('/workspace/my/module'))!;
-    late _MockTimer timer;
-    var timerFactory = (Duration _, void Function(Timer) callback) {
-      timer = _MockTimer(callback);
-      return timer;
-    };
-    var watcherCompleter = Completer<BazelFileWatcher>();
-    workspace.bazelCandidateFiles.listen((notification) =>
-        watcherCompleter.complete(notification.watcher(
-            pollingDelayLong: Duration.zero,
-            pollingDelayShort: Duration.zero,
-            timerFactory: timerFactory)));
-
-    var file1 =
-        workspace.findFile(convertPath('/workspace/my/module/test1.dart'))!;
-    expect(file1.exists, true);
-    var watcher = await watcherCompleter.future;
-    var events = StreamQueue(watcher.events);
-    watcher.start();
-
-    // Make sure that triggering the callback, will not generate extra events.
-    timer.triggerCallback();
-
-    var convertedPath =
-        convertPath('/workspace/bazel-bin/my/module/test1.dart');
-
-    // Change the file -- we should get a single MODIFY event and not an ADD
-    // event, since the file already existed.
-    modifyFile(convertedPath, 'const foo = 42;');
-    timer.triggerCallback();
-    var event = await events.next;
-
-    expect(event.type, ChangeType.MODIFY);
-    expect(event.path, convertedPath);
-
-    // But if we delete the file and then re-create it, we should get an ADD
-    // event (after the REMOVE one).
-    deleteFile(convertedPath);
-    timer.triggerCallback();
-    event = await events.next;
-
-    expect(event.type, ChangeType.REMOVE);
-    expect(event.path, convertedPath);
-
-    newFile(convertedPath);
-    timer.triggerCallback();
-    event = await events.next;
-
-    expect(event.type, ChangeType.ADD);
-    expect(event.path, convertedPath);
-
-    watcher.stop();
-    expect(await events.rest.isEmpty, true);
-  }
-
   void test_bazelNotifications() async {
     _addResources([
       '/workspace/WORKSPACE',
@@ -937,20 +820,22 @@
     var file1 =
         workspace.findFile(convertPath('/workspace/my/module/test1.dart'))!;
     expect(file1.exists, true);
-    var notification = await notifications.next;
-    expect(notification.requested, convertPath('my/module/test1.dart'));
+    var info = await notifications.next;
+    expect(info.requestedPath, convertPath('my/module/test1.dart'));
     expect(
-        notification.candidates,
-        containsAll(
-            [convertPath('/workspace/bazel-bin/my/module/test1.dart')]));
+        info.candidatePaths,
+        containsAll([
+          convertPath('/workspace/bazel-bin/my/module/test1.dart'),
+          convertPath('/workspace/bazel-genfiles/my/module/test1.dart'),
+        ]));
 
     var file2 =
         workspace.findFile(convertPath('/workspace/my/module/test2.dart'))!;
     expect(file2.exists, false);
-    notification = await notifications.next;
-    expect(notification.requested, convertPath('my/module/test2.dart'));
+    info = await notifications.next;
+    expect(info.requestedPath, convertPath('my/module/test2.dart'));
     expect(
-        notification.candidates,
+        info.candidatePaths,
         containsAll([
           convertPath('/workspace/bazel-bin/my/module/test2.dart'),
           convertPath('/workspace/bazel-genfiles/my/module/test2.dart'),
@@ -1205,17 +1090,6 @@
     }
   }
 
-  /// Create new files and directories from [paths].
-  void _deleteResources(List<String> paths) {
-    for (String path in paths) {
-      if (path.endsWith('/')) {
-        deleteFolder(path.substring(0, path.length - 1));
-      } else {
-        deleteFile(path);
-      }
-    }
-  }
-
   /// Expect that [BazelWorkspace.findFile], given [path], returns [equals].
   void _expectFindFile(String path, {required String equals}) =>
       expect(workspace.findFile(convertPath(path))!.path, convertPath(equals));
@@ -1232,20 +1106,3 @@
     throw StateError('Unexpected invocation of ${invocation.memberName}');
   }
 }
-
-class _MockTimer implements Timer {
-  final void Function(Timer) callback;
-
-  @override
-  bool isActive = true;
-
-  _MockTimer(this.callback);
-
-  @override
-  int get tick => throw UnimplementedError();
-
-  @override
-  void cancel() => isActive = false;
-
-  void triggerCallback() => callback(this);
-}
diff --git a/pkg/analyzer/test/src/workspace/bazel_watcher_test.dart b/pkg/analyzer/test/src/workspace/bazel_watcher_test.dart
new file mode 100644
index 0000000..16df3e4
--- /dev/null
+++ b/pkg/analyzer/test/src/workspace/bazel_watcher_test.dart
@@ -0,0 +1,269 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:isolate';
+
+import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
+import 'package:analyzer/src/workspace/bazel.dart';
+import 'package:analyzer/src/workspace/bazel_watcher.dart';
+import 'package:async/async.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+import 'package:watcher/watcher.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(BazelWatcherTest);
+  });
+}
+
+@reflectiveTest
+class BazelWatcherTest with ResourceProviderMixin {
+  late final BazelWorkspace workspace;
+
+  void test_bazelFileWatcher() async {
+    _addResources([
+      '/workspace/WORKSPACE',
+    ]);
+    var candidates = [
+      convertPath('/workspace/bazel-bin/my/module/test1.dart'),
+      convertPath('/workspace/bazel-genfiles/my/module/test1.dart'),
+    ];
+    var watcher = BazelFilePoller(resourceProvider, candidates);
+
+    // First do some tests with the first candidate path.
+    _addResources([candidates[0]]);
+
+    var event = watcher.poll()!;
+
+    expect(event.type, ChangeType.ADD);
+    expect(event.path, candidates[0]);
+
+    modifyFile(candidates[0], 'const foo = 42;');
+
+    event = watcher.poll()!;
+
+    expect(event.type, ChangeType.MODIFY);
+    expect(event.path, candidates[0]);
+
+    _deleteResources([candidates[0]]);
+
+    event = watcher.poll()!;
+
+    expect(event.type, ChangeType.REMOVE);
+    expect(event.path, candidates[0]);
+
+    // Now check that if we add the *second* candidate, we'll get the
+    // notification for it.
+    _addResources([candidates[1]]);
+
+    event = watcher.poll()!;
+
+    expect(event.type, ChangeType.ADD);
+    expect(event.path, candidates[1]);
+
+    // Next poll should be `null` since there were no changes.
+    expect(watcher.poll(), isNull);
+  }
+
+  void test_bazelFileWatcherIsolate() async {
+    _addResources([
+      '/workspace/WORKSPACE',
+    ]);
+    var candidates1 = [
+      convertPath('/workspace/bazel-bin/my/module/test1.dart'),
+      convertPath('/workspace/bazel-genfiles/my/module/test1.dart'),
+    ];
+    var candidates2 = [
+      convertPath('/workspace/bazel-bin/my/module/test2.dart'),
+      convertPath('/workspace/bazel-genfiles/my/module/test2.dart'),
+    ];
+    var trigger = _MockPollTrigger();
+    var recPort = ReceivePort();
+    // Note that we provide below a dummy `ReceivePort` that will *not* be used.
+    // We'll directly call `handleRequest` to avoid any problems with various
+    // interleavings of async functions.
+    var dummyRecPort = ReceivePort();
+    var watcher = BazelFileWatcherIsolate(
+        dummyRecPort, recPort.sendPort, resourceProvider,
+        pollTriggerFactory: (_) => trigger)
+      ..start();
+    var queue = StreamQueue(recPort);
+
+    await queue.next as BazelWatcherIsolateStarted;
+
+    watcher.handleRequest(BazelWatcherStartWatching(
+        convertPath('/workspace'),
+        BazelSearchInfo(
+            convertPath('/workspace/my/module/test1.dart'), candidates1)));
+    watcher.handleRequest(BazelWatcherStartWatching(
+        convertPath('/workspace'),
+        BazelSearchInfo(
+            convertPath('/workspace/my/module/test2.dart'), candidates2)));
+
+    // First do some tests with the first candidate path.
+    _addResources([candidates1[0]]);
+
+    trigger.controller.add('');
+    var events = (await queue.next as BazelWatcherEvents).events;
+
+    expect(events, hasLength(1));
+    expect(events[0].path, candidates1[0]);
+    expect(events[0].type, ChangeType.ADD);
+
+    // Now let's take a look at the second file.
+    _addResources([candidates2[1]]);
+
+    trigger.controller.add('');
+    events = (await queue.next as BazelWatcherEvents).events;
+
+    expect(events, hasLength(1));
+    expect(events[0].path, candidates2[1]);
+    expect(events[0].type, ChangeType.ADD);
+
+    expect(watcher.numWatchedFiles(), 2);
+
+    watcher.handleRequest(BazelWatcherStopWatching(convertPath('/workspace'),
+        convertPath('/workspace/my/module/test1.dart')));
+
+    expect(watcher.numWatchedFiles(), 1);
+
+    watcher.handleRequest(BazelWatcherStopWatching(convertPath('/workspace'),
+        convertPath('/workspace/my/module/test2.dart')));
+
+    expect(watcher.numWatchedFiles(), 0);
+
+    watcher.handleRequest(BazelWatcherShutdownIsolate());
+    await watcher.hasFinished;
+
+    // We need to do this manually, since it's the callers responsibility to
+    // close this port (the one owned by `watcher` should've been closed when
+    // handling the "shutdown" request).
+    recPort.close();
+  }
+
+  void test_bazelFileWatcherIsolate_multipleWorkspaces() async {
+    _addResources([
+      '/workspace1/WORKSPACE',
+      '/workspace2/WORKSPACE',
+    ]);
+    var candidates1 = [
+      convertPath('/workspace1/bazel-bin/my/module/test1.dart'),
+      convertPath('/workspace1/bazel-genfiles/my/module/test1.dart'),
+    ];
+    var candidates2 = [
+      convertPath('/workspace2/bazel-bin/my/module/test2.dart'),
+      convertPath('/workspace2/bazel-genfiles/my/module/test2.dart'),
+    ];
+    _MockPollTrigger? trigger1;
+    _MockPollTrigger? trigger2;
+    var triggerFactory = (String workspace) {
+      if (workspace == convertPath('/workspace1')) {
+        trigger1 = _MockPollTrigger();
+        return trigger1!;
+      } else if (workspace == convertPath('/workspace2')) {
+        trigger2 = _MockPollTrigger();
+        return trigger2!;
+      } else {
+        throw ArgumentError('Got unexpected workspace: `$workspace`');
+      }
+    };
+    var recPort = ReceivePort();
+    // Note that we provide below a dummy `ReceivePort` that will *not* be used.
+    // We'll directly call `handleRequest` to avoid any problems with various
+    // interleavings of async functions.
+    var dummyRecPort = ReceivePort();
+    var watcher = BazelFileWatcherIsolate(
+        dummyRecPort, recPort.sendPort, resourceProvider,
+        pollTriggerFactory: triggerFactory)
+      ..start();
+    var queue = StreamQueue(recPort);
+
+    await queue.next as BazelWatcherIsolateStarted;
+
+    watcher.handleRequest(BazelWatcherStartWatching(
+        convertPath('/workspace1'),
+        BazelSearchInfo(
+            convertPath('/workspace1/my/module/test1.dart'), candidates1)));
+    watcher.handleRequest(BazelWatcherStartWatching(
+        convertPath('/workspace2'),
+        BazelSearchInfo(
+            convertPath('/workspace2/my/module/test2.dart'), candidates2)));
+
+    // First do some tests with the first candidate path.
+    _addResources([candidates1[0]]);
+
+    trigger1!.controller.add('');
+    var events = (await queue.next as BazelWatcherEvents).events;
+
+    expect(events, hasLength(1));
+    expect(events[0].path, candidates1[0]);
+    expect(events[0].type, ChangeType.ADD);
+
+    // Now let's take a look at the second file.
+    _addResources([candidates2[1]]);
+
+    trigger2!.controller.add('');
+    events = (await queue.next as BazelWatcherEvents).events;
+
+    expect(events, hasLength(1));
+    expect(events[0].path, candidates2[1]);
+    expect(events[0].type, ChangeType.ADD);
+
+    expect(watcher.numWatchedFiles(), 2);
+
+    watcher.handleRequest(BazelWatcherStopWatching(convertPath('/workspace1'),
+        convertPath('/workspace1/my/module/test1.dart')));
+
+    expect(watcher.numWatchedFiles(), 1);
+
+    watcher.handleRequest(BazelWatcherStopWatching(convertPath('/workspace2'),
+        convertPath('/workspace2/my/module/test2.dart')));
+
+    expect(watcher.numWatchedFiles(), 0);
+
+    watcher.handleRequest(BazelWatcherShutdownIsolate());
+    await watcher.hasFinished;
+
+    // We need to do this manually, since it's the callers responsibility to
+    // close this port (the one owned by `watcher` should've been closed when
+    // handling the "shutdown" request).
+    recPort.close();
+  }
+
+  /// Create new files and directories from [paths].
+  void _addResources(List<String> paths) {
+    for (String path in paths) {
+      if (path.endsWith('/')) {
+        newFolder(path.substring(0, path.length - 1));
+      } else {
+        newFile(path);
+      }
+    }
+  }
+
+  /// Create new files and directories from [paths].
+  void _deleteResources(List<String> paths) {
+    for (String path in paths) {
+      if (path.endsWith('/')) {
+        deleteFolder(path.substring(0, path.length - 1));
+      } else {
+        deleteFile(path);
+      }
+    }
+  }
+}
+
+class _MockPollTrigger implements PollTrigger {
+  final controller = StreamController<Object>();
+
+  @override
+  Stream<Object> get stream => controller.stream;
+
+  @override
+  void cancel() {
+    return;
+  }
+}
diff --git a/pkg/analyzer/test/src/workspace/test_all.dart b/pkg/analyzer/test/src/workspace/test_all.dart
index edf5bd0..dc1b496 100644
--- a/pkg/analyzer/test/src/workspace/test_all.dart
+++ b/pkg/analyzer/test/src/workspace/test_all.dart
@@ -6,6 +6,7 @@
 
 import 'basic_test.dart' as basic;
 import 'bazel_test.dart' as bazel;
+import 'bazel_watcher_test.dart' as bazel_watcher;
 import 'gn_test.dart' as gn;
 import 'package_build_test.dart' as package_build;
 import 'pub_test.dart' as pub;
@@ -14,6 +15,7 @@
   defineReflectiveSuite(() {
     basic.main();
     bazel.main();
+    bazel_watcher.main();
     gn.main();
     package_build.main();
     pub.main();
diff --git a/pkg/analyzer/test/util/id_testing_helper.dart b/pkg/analyzer/test/util/id_testing_helper.dart
index 08e94dd..19c16a4 100644
--- a/pkg/analyzer/test/util/id_testing_helper.dart
+++ b/pkg/analyzer/test/util/id_testing_helper.dart
@@ -173,7 +173,7 @@
   var results = <Uri, ResolvedUnitResult>{};
   for (var testUri in testUris) {
     var path = resourceProvider.convertPath(testUri.path);
-    var result = (await driver.getResult(path))!;
+    var result = await driver.getResult(path);
     var errors =
         result.errors.where((e) => e.severity == Severity.error).toList();
     if (errors.isNotEmpty) {
diff --git a/pkg/analyzer/test/verify_diagnostics_test.dart b/pkg/analyzer/test/verify_diagnostics_test.dart
index 34f18aa..f99f600 100644
--- a/pkg/analyzer/test/verify_diagnostics_test.dart
+++ b/pkg/analyzer/test/verify_diagnostics_test.dart
@@ -38,6 +38,12 @@
     'CompileTimeErrorCode.AMBIGUOUS_IMPORT',
     // Produces two diagnostics when it should only produce one.
     'CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE',
+    // Produces two diagnostics when it should only produce one.
+    'CompileTimeErrorCode.CONST_DEFERRED_CLASS',
+    // Has code in the example section that needs to be skipped (because it's
+    // part of the explanitory text not part of the example), but there's
+    // currently no way to do that.
+    'CompileTimeErrorCode.INVALID_IMPLEMENTATION_OVERRIDE',
     // Produces two diagnostics when it should only produce one. We could get
     // rid of the invalid error by adding a declaration of a top-level variable
     // (such as `JSBool b;`), but that would complicate the example.
@@ -46,6 +52,8 @@
     'CompileTimeErrorCode.INVALID_URI',
     // Produces two diagnostics when it should only produce one.
     'CompileTimeErrorCode.INVALID_USE_OF_NULL_VALUE',
+    // No example, by design.
+    'CompileTimeErrorCode.MISSING_DART_LIBRARY',
     // Produces two diagnostics when it should only produce one.
     'CompileTimeErrorCode.NON_SYNC_FACTORY',
     // Need a way to make auxiliary files that (a) are not included in the
diff --git a/pkg/analyzer/test/verify_docs_test.dart b/pkg/analyzer/test/verify_docs_test.dart
index 76acfa9..841fe15 100644
--- a/pkg/analyzer/test/verify_docs_test.dart
+++ b/pkg/analyzer/test/verify_docs_test.dart
@@ -119,7 +119,7 @@
         fail('The snippets directory contains multiple analysis contexts.');
       }
       ErrorsResult results =
-          (await contexts[0].currentSession.getErrors(snippetPath))!;
+          await contexts[0].currentSession.getErrors(snippetPath);
       Iterable<AnalysisError> errors = results.errors.where((error) {
         ErrorCode errorCode = error.errorCode;
         return errorCode != HintCode.UNUSED_IMPORT &&
diff --git a/pkg/analyzer/tool/diagnostics/diagnostics.md b/pkg/analyzer/tool/diagnostics/diagnostics.md
index 6778017..767c77a 100644
--- a/pkg/analyzer/tool/diagnostics/diagnostics.md
+++ b/pkg/analyzer/tool/diagnostics/diagnostics.md
@@ -19,11 +19,13 @@
 
 * [constant context][]
 * [definite assignment][]
+* [mixin application][]
 * [override inference][]
 * [potentially non-nullable][]
 
 [constant context]: #constant-context
 [definite assignment]: #definite-assignment
+[mixin application]: #mixin-application
 [override inference]: #override-inference
 [potentially non-nullable]: #potentially-non-nullable
 
@@ -154,6 +156,40 @@
 
 [definiteAssignmentSpec](https://github.com/dart-lang/language/blob/master/resources/type-system/flow-analysis.md)
 
+### Mixin Application
+
+A _mixin application_ is the class created when a mixin is applied to a class.
+For example, consider the following declarations:
+
+```dart
+class A {}
+
+mixin M {}
+
+class B extends A with M {}
+```
+
+The class `B` is a subclass of the mixin application of `M` to `A`, sometimes
+nomenclated as `A+M`. The class `A+M` is a subclass of `A` and has members that
+are copied from `M`.
+
+You can give an actual name to a mixin application by defining it as:
+
+```dart
+class A {}
+
+mixin M {}
+
+class A_M = A with M;
+```
+
+Given this declaration of `A_M`, the following declaration of `B` is equivalent
+to the declaration of `B` in the original example:
+
+```dart
+class B extends A_M {}
+```
+
 ### Override inference
 
 Override inference is the process by which any missing types in a method
@@ -667,6 +703,64 @@
 String g(num y) => f(y as String);
 {% endprettify %}
 
+### argument_type_not_assignable_to_error_handler
+
+_The argument type '{0}' can't be assigned to the parameter type '{1}
+Function(Object)' or '{1} Function(Object, StackTrace)'._
+
+#### Description
+
+The analyzer produces this diagnostic when an invocation of
+`Future.catchError` has an argument that is a function whose parameters
+aren't compatible with the arguments that will be passed to the function
+when it's invoked. The static type of the first argument to `catchError`
+is just `Function`, even though the function that is passed in is expected
+to have either a single parameter of type `Object` or two parameters of
+type `Object` and `StackTrace`.
+
+#### Example
+
+The following code produces this diagnostic because the closure being
+passed to `catchError` doesn't take any parameters, but the function is
+required to take at least one parameter:
+
+{% prettify dart tag=pre+code %}
+void f(Future<int> f) {
+  f.catchError([!() => 0!]);
+}
+{% endprettify %}
+
+The following code produces this diagnostic because the closure being
+passed to `catchError` takes three parameters, but it can't have more than
+two required parameters:
+
+{% prettify dart tag=pre+code %}
+void f(Future<int> f) {
+  f.catchError([!(one, two, three) => 0!]);
+}
+{% endprettify %}
+
+The following code produces this diagnostic because even though the closure
+being passed to `catchError` takes one parameter, the closure doesn't have
+a type that is compatible with `Object`:
+
+{% prettify dart tag=pre+code %}
+void f(Future<int> f) {
+  f.catchError([!(String error) => 0!]);
+}
+{% endprettify %}
+
+#### Common fixes
+
+Change the function being passed to `catchError` so that it has either one
+or two required parameters, and the parameters have the required types:
+
+{% prettify dart tag=pre+code %}
+void f(Future<int> f) {
+  f.catchError((Object error) => 0);
+}
+{% endprettify %}
+
 ### assert_in_redirecting_constructor
 
 _A redirecting constructor can't have an 'assert' initializer._
@@ -1503,6 +1597,76 @@
 int y = x as int;
 {% endprettify %}
 
+### collection_element_from_deferred_library
+
+_Constant values from a deferred library can't be used as keys in a 'const' map
+literal._
+
+_Constant values from a deferred library can't be used as values in a 'const'
+list literal._
+
+_Constant values from a deferred library can't be used as values in a 'const'
+map literal._
+
+_Constant values from a deferred library can't be used as values in a 'const'
+set literal._
+
+#### Description
+
+The analyzer produces this diagnostic when a collection literal that is
+either explicitly (because it's prefixed by the `const` keyword) or
+implicitly (because it appears in a [constant context][]) a constant
+contains a value that is declared in a library that is imported using a
+deferred import. Constants are evaluated at compile time, and values from
+deferred libraries aren't available at compile time.
+
+For more information, see the language tour's coverage of
+[deferred loading](https://dart.dev/guides/language/language-tour#lazily-loading-a-library).
+
+#### Example
+
+Given a file (`a.dart`) that defines the constant `zero`:
+
+{% prettify dart tag=pre+code %}
+const zero = 0;
+{% endprettify %}
+
+The following code produces this diagnostic because the constant list
+literal contains `a.zero`, which is imported using a `deferred` import:
+
+{% prettify dart tag=pre+code %}
+import 'a.dart' deferred as a;
+
+var l = const [[!a.zero!]];
+{% endprettify %}
+
+#### Common fixes
+
+If the collection literal isn't required to be constant, then remove the
+`const` keyword:
+
+{% prettify dart tag=pre+code %}
+import 'a.dart' deferred as a;
+
+var l = [a.zero];
+{% endprettify %}
+
+If the collection is required to be constant and the imported constant must
+be referenced, then remove the keyword `deferred` from the import:
+
+{% prettify dart tag=pre+code %}
+import 'a.dart' as a;
+
+var l = const [a.zero];
+{% endprettify %}
+
+If you don't need to reference the constant, then replace it with a
+suitable value:
+
+{% prettify dart tag=pre+code %}
+var l = const [0];
+{% endprettify %}
+
 ### concrete_class_with_abstract_member
 
 _'{0}' must have a method body because '{1}' isn't abstract._
@@ -1544,6 +1708,43 @@
 }
 {% endprettify %}
 
+### conflicting_generic_interfaces
+
+_The class '{0}' can't implement both '{1}' and '{2}' because the type arguments
+are different._
+
+#### Description
+
+The analyzer produces this diagnostic when a class attempts to implement a
+generic interface multiple times, and the values of the type arguments
+aren't the same.
+
+#### Example
+
+The following code produces this diagnostic because `C` is defined to
+implement both `I<int>` (because it extends `A`) and `I<String>` (because
+it implements`B`), but `int` and `String` aren't the same type:
+
+{% prettify dart tag=pre+code %}
+class I<T> {}
+class A implements I<int> {}
+class B implements I<String> {}
+[!class C extends A implements B {}!]
+{% endprettify %}
+
+#### Common fixes
+
+Rework the type hierarchy to avoid this situation. For example, you might
+make one or both of the inherited types generic so that `C` can specify the
+same type for both type arguments:
+
+{% prettify dart tag=pre+code %}
+class I<T> {}
+class A<S> implements I<S> {}
+class B implements I<String> {}
+class C extends A<String> implements B {}
+{% endprettify %}
+
 ### const_constructor_param_type_mismatch
 
 _A value of type '{0}' can't be assigned to a parameter of type '{1}' in a const
@@ -1636,6 +1837,78 @@
 }
 {% endprettify %}
 
+### const_constructor_with_non_const_super
+
+_A constant constructor can't call a non-constant super constructor of '{0}'._
+
+#### Description
+
+The analyzer produces this diagnostic when a constructor that is marked as
+`const` invokes a constructor from its superclass that isn't marked as
+`const`.
+
+#### Example
+
+The following code produces this diagnostic because the `const` constructor
+in `B` invokes the constructor `nonConst` from the class `A`, and the
+superclass constructor isn't a `const` constructor:
+
+{% prettify dart tag=pre+code %}
+class A {
+  const A();
+  A.nonConst();
+}
+
+class B extends A {
+  const B() : [!super.nonConst()!];
+}
+{% endprettify %}
+
+#### Common fixes
+
+If it isn't essential to invoke the superclass constructor that is
+currently being invoked, then invoke a constant constructor from the
+superclass:
+
+{% prettify dart tag=pre+code %}
+class A {
+  const A();
+  A.nonConst();
+}
+
+class B extends A {
+  const B() : super();
+}
+{% endprettify %}
+
+If it's essential that the current constructor be invoked and if you can
+modify it, then add `const` to the constructor in the superclass:
+
+{% prettify dart tag=pre+code %}
+class A {
+  const A();
+  const A.nonConst();
+}
+
+class B extends A {
+  const B() : super.nonConst();
+}
+{% endprettify %}
+
+If it's essential that the current constructor be invoked and you can't
+modify it, then remove `const` from the constructor in the subclass:
+
+{% prettify dart tag=pre+code %}
+class A {
+  const A();
+  A.nonConst();
+}
+
+class B extends A {
+  B() : super.nonConst();
+}
+{% endprettify %}
+
 ### const_constructor_with_non_final_field
 
 _Can't define a const constructor for a class with non-final fields._
@@ -1682,6 +1955,51 @@
 }
 {% endprettify %}
 
+### const_deferred_class
+
+_Deferred classes can't be created with 'const'._
+
+#### Description
+
+The analyzer produces this diagnostic when a class from a library that is
+imported using a deferred import is used to create a `const` object.
+Constants are evaluated at compile time, and classes from deferred
+libraries aren't available at compile time.
+
+For more information, see the language tour's coverage of
+[deferred loading](https://dart.dev/guides/language/language-tour#lazily-loading-a-library).
+
+#### Example
+
+The following code produces this diagnostic because it attempts to create a
+`const` instance of a class from a deferred library:
+
+{% prettify dart tag=pre+code %}
+import 'dart:convert' deferred as convert;
+
+const json2 = [!convert.JsonCodec()!];
+{% endprettify %}
+
+#### Common fixes
+
+If the object isn't required to be a constant, then change the code so that
+a non-constant instance is created:
+
+{% prettify dart tag=pre+code %}
+import 'dart:convert' deferred as convert;
+
+final json2 = convert.JsonCodec();
+{% endprettify %}
+
+If the object must be a constant, then remove `deferred` from the import
+directive:
+
+{% prettify dart tag=pre+code %}
+import 'dart:convert' as convert;
+
+const json2 = convert.JsonCodec();
+{% endprettify %}
+
 ### const_initialized_with_non_constant_value
 
 _Const variables must be initialized with a constant value._
@@ -1720,6 +2038,51 @@
 final y = x;
 {% endprettify %}
 
+### const_initialized_with_non_constant_value_from_deferred_library
+
+_Constant values from a deferred library can't be used to initialize a 'const'
+variable._
+
+#### Description
+
+The analyzer produces this diagnostic when a `const` variable is
+initialized using a `const` variable from a library that is imported using
+a deferred import. Constants are evaluated at compile time, and values from
+deferred libraries aren't available at compile time.
+
+For more information, see the language tour's coverage of
+[deferred loading](https://dart.dev/guides/language/language-tour#lazily-loading-a-library).
+
+#### Example
+
+The following code produces this diagnostic because the variable `pi` is
+being initialized using the constant `math.pi` from the library
+`dart:math`, and `dart:math` is imported as a deferred library:
+
+{% prettify dart tag=pre+code %}
+import 'dart:math' deferred as math;
+
+const pi = [!math.pi!];
+{% endprettify %}
+
+#### Common fixes
+
+If you need to reference the value of the constant from the imported
+library, then remove the keyword `deferred`:
+
+{% prettify dart tag=pre+code %}
+import 'dart:math' as math;
+
+const pi = math.pi;
+{% endprettify %}
+
+If you don't need to reference the imported constant, then remove the
+reference:
+
+{% prettify dart tag=pre+code %}
+const pi = 3.14;
+{% endprettify %}
+
 ### const_instance_field
 
 _Only static fields can be declared as const._
@@ -1759,6 +2122,60 @@
 }
 {% endprettify %}
 
+### const_map_key_expression_type_implements_equals
+
+_The type of a key in a constant map can't override the '==' operator, but the
+class '{0}' does._
+
+#### Description
+
+The analyzer produces this diagnostic when the class of object used as a
+key in a constant map literal implements the `==` operator. The
+implementation of constant maps uses the `==` operator, so any
+implementation other than the one inherited from `Object` requires
+executing arbitrary code at compile time, which isn't supported.
+
+#### Example
+
+The following code produces this diagnostic because the constant map
+contains a key whose type is `C`, and the class `C` overrides the
+implementation of `==`:
+
+{% prettify dart tag=pre+code %}
+class C {
+  const C();
+
+  bool operator ==(Object other) => true;
+}
+
+const map = {[!C()!] : 0};
+{% endprettify %}
+
+#### Common fixes
+
+If you can remove the implementation of `==` from the class, then do so:
+
+{% prettify dart tag=pre+code %}
+class C {
+  const C();
+}
+
+const map = {C() : 0};
+{% endprettify %}
+
+If you can't remove the implementation of `==` from the class, then make
+the map be non-constant:
+
+{% prettify dart tag=pre+code %}
+class C {
+  const C();
+
+  bool operator ==(Object other) => true;
+}
+
+final map = {C() : 0};
+{% endprettify %}
+
 ### const_not_initialized
 
 _The constant '{0}' must be initialized._
@@ -1784,6 +2201,60 @@
 const c = 'c';
 {% endprettify %}
 
+### const_set_element_type_implements_equals
+
+_The type of an element in a constant set can't override the '==' operator, but
+the type '{0}' does._
+
+#### Description
+
+The analyzer produces this diagnostic when the class of object used as an
+element in a constant set literal implements the `==` operator. The
+implementation of constant sets uses the `==` operator, so any
+implementation other than the one inherited from `Object` requires
+executing arbitrary code at compile time, which isn't supported.
+
+#### Example
+
+The following code produces this diagnostic because the constant set
+contains an element whose type is `C`, and the class `C` overrides the
+implementation of `==`:
+
+{% prettify dart tag=pre+code %}
+class C {
+  const C();
+
+  bool operator ==(Object other) => true;
+}
+
+const set = {[!C()!]};
+{% endprettify %}
+
+#### Common fixes
+
+If you can remove the implementation of `==` from the class, then do so:
+
+{% prettify dart tag=pre+code %}
+class C {
+  const C();
+}
+
+const set = {C()};
+{% endprettify %}
+
+If you can't remove the implementation of `==` from the class, then make
+the set be non-constant:
+
+{% prettify dart tag=pre+code %}
+class C {
+  const C();
+
+  bool operator ==(Object other) => true;
+}
+
+final set = {C()};
+{% endprettify %}
+
 ### const_spread_expected_list_or_set
 
 _A list or a set is expected in this spread._
@@ -2372,6 +2843,83 @@
 }
 {% endprettify %}
 
+### deferred_import_of_extension
+
+_Imports of deferred libraries must hide all extensions._
+
+#### Description
+
+The analyzer produces this diagnostic when a library that is imported using
+a deferred import declares an extension that is visible in the importing
+library. Extension methods are resolved at compile time, and extensions
+from deferred libraries aren't available at compile time.
+
+For more information, see the language tour's coverage of
+[deferred loading](https://dart.dev/guides/language/language-tour#lazily-loading-a-library).
+
+#### Example
+
+Given a file (`a.dart`) that defines a named extension:
+
+{% prettify dart tag=pre+code %}
+class C {}
+
+extension E on String {
+  int get size => length;
+}
+{% endprettify %}
+
+The following code produces this diagnostic because the named extension is
+visible to the library:
+
+{% prettify dart tag=pre+code %}
+import [!'a.dart'!] deferred as a;
+
+void f() {
+  a.C();
+}
+{% endprettify %}
+
+#### Common fixes
+
+If the library must be imported as `deferred`, then either add a `show`
+clause listing the names being referenced or add a `hide` clause listing
+all of the named extensions. Adding a `show` clause would look like this:
+
+{% prettify dart tag=pre+code %}
+import 'a.dart' deferred as a show C;
+
+void f() {
+  a.C();
+}
+{% endprettify %}
+
+Adding a `hide` clause would look like this:
+
+{% prettify dart tag=pre+code %}
+import 'a.dart' deferred as a hide E;
+
+void f() {
+  a.C();
+}
+{% endprettify %}
+
+With the first fix, the benefit is that if new extensions are added to the
+imported library, then the extensions won't cause a diagnostic to be
+generated.
+
+If the library doesn't need to be imported as `deferred`, or if you need to
+make use of the extension method declared in it, then remove the keyword
+`deferred`:
+
+{% prettify dart tag=pre+code %}
+import 'a.dart' as a;
+
+void f() {
+  a.C();
+}
+{% endprettify %}
+
 ### definitely_unassigned_late_local_variable
 
 _The late local variable '{0}' is definitely unassigned at this point._
@@ -4176,6 +4724,55 @@
 }
 {% endprettify %}
 
+### for_in_of_invalid_element_type
+
+_The type '{0}' used in the 'for' loop must implement '{1}' with a type argument
+that can be assigned to '{2}'._
+
+#### Description
+
+The analyzer produces this diagnostic when the `Iterable` or `Stream` in a
+for-in loop has an element type that can't be assigned to the loop
+variable.
+
+#### Example
+
+The following code produces this diagnostic because `<String>[]` has an
+element type of `String`, and `String` can't be assigned to the type of `e`
+(`int`):
+
+{% prettify dart tag=pre+code %}
+void f() {
+  for (int e in [!<String>[]!]) {
+    print(e);
+  }
+}
+{% endprettify %}
+
+#### Common fixes
+
+If the type of the loop variable is correct, then update the type of the
+iterable:
+
+{% prettify dart tag=pre+code %}
+void f() {
+  for (int e in <int>[]) {
+    print(e);
+  }
+}
+{% endprettify %}
+
+If the type of the iterable is correct, then update the type of the loop
+variable:
+
+{% prettify dart tag=pre+code %}
+void f() {
+  for (String e in <String>[]) {
+    print(e);
+  }
+}
+{% endprettify %}
+
 ### for_in_of_invalid_type
 
 _The type '{0}' used in the 'for' loop must implement {1}._
@@ -4210,6 +4807,45 @@
 }
 {% endprettify %}
 
+### for_in_with_const_variable
+
+_A for-in loop variable can't be a 'const'._
+
+#### Description
+
+The analyzer produces this diagnostic when the loop variable declared in a
+for-in loop is declared to be a `const`. The variable can't be a `const`
+because the value can't be computed at compile time.
+
+#### Example
+
+The following code produces this diagnostic because the loop variable `x`
+is declared to be a `const`:
+
+{% prettify dart tag=pre+code %}
+void f() {
+  for ([!const!] x in [0, 1, 2]) {
+    print(x);
+  }
+}
+{% endprettify %}
+
+#### Common fixes
+
+If there's a type annotation, then remove the `const` modifier from the
+declaration.
+
+If there's no type, then replace the `const` modifier with `final`, `var`,
+or a type annotation:
+
+{% prettify dart tag=pre+code %}
+void f() {
+  for (final x in [0, 1, 2]) {
+    print(x);
+  }
+}
+{% endprettify %}
+
 ### getter_not_subtype_setter_types
 
 _The return type of getter '{0}' is '{1}' which isn't a subtype of the type
@@ -4873,6 +5509,40 @@
 If there's a concrete subclass of the abstract class that can be used, then
 create an instance of the concrete subclass.
 
+### instantiate_enum
+
+_Enums can't be instantiated._
+
+#### Description
+
+The analyzer produces this diagnostic when an enum is instantiated. It's
+invalid to create an instance of an enum by invoking a constructor; only
+the instances named in the declaration of the enum can exist.
+
+#### Example
+
+The following code produces this diagnostic because the enum `E` is being
+instantiated:
+
+{% prettify dart tag=pre+code %}
+enum E {a}
+
+var e = [!E!]();
+{% endprettify %}
+
+#### Common fixes
+
+If you intend to use an instance of the enum, then reference one of the
+constants defined in the enum:
+
+{% prettify dart tag=pre+code %}
+enum E {a}
+
+var e = E.a;
+{% endprettify %}
+
+If you intend to use an instance of a class, then use the name of that class in place of the name of the enum.
+
 ### integer_literal_out_of_range
 
 _The integer literal {0} can't be represented in 64 bits._
@@ -4973,6 +5643,53 @@
 }
 {% endprettify %}
 
+### invalid_annotation_from_deferred_library
+
+_Constant values from a deferred library can't be used as annotations._
+
+#### Description
+
+The analyzer produces this diagnostic when a constant from a library that
+is imported using a deferred import is used as an annotation. Annotations
+are evaluated at compile time, and constants from deferred libraries aren't
+available at compile time.
+
+For more information, see the language tour's coverage of
+[deferred loading](https://dart.dev/guides/language/language-tour#lazily-loading-a-library).
+
+#### Example
+
+The following code produces this diagnostic because the constant `pi` is
+being used as an annotation when the library `dart:math` is imported as
+`deferred`:
+
+{% prettify dart tag=pre+code %}
+import 'dart:math' deferred as math;
+
+@[!math.pi!]
+void f() {}
+{% endprettify %}
+
+#### Common fixes
+
+If you need to reference the constant as an annotation, then remove the
+keyword `deferred` from the import:
+
+{% prettify dart tag=pre+code %}
+import 'dart:math' as math;
+
+@math.pi
+void f() {}
+{% endprettify %}
+
+If you can use a different constant as an annotation, then replace the
+annotation with a different constant:
+
+{% prettify dart tag=pre+code %}
+@deprecated
+void f() {}
+{% endprettify %}
+
 ### invalid_assignment
 
 _A value of type '{0}' can't be assigned to a variable of type '{1}'._
@@ -5127,6 +5844,91 @@
 }
 {% endprettify %}
 
+### invalid_implementation_override
+
+_'{1}.{0}' ('{2}') isn't a valid concrete implementation of '{3}.{0}' ('{4}')._
+
+#### Description
+
+The analyzer produces this diagnostic when all of the following are true:
+
+- A class defines an abstract member.
+- There is a concrete implementation of that member in a superclass.
+- The concrete implementation isn't a valid implementation of the abstract
+  method.
+
+The concrete implementation can be invalid because of incompatibilities in
+either the return type, the types of parameters, or the type variables.
+
+#### Example
+
+The following code produces this diagnostic because the method `A.add` has
+a parameter of type `int`, and the overriding method `B.add` has a
+corresponding parameter of type `num`:
+
+{% prettify dart tag=pre+code %}
+class A {
+  int add(int a) => a;
+}
+class [!B!] extends A {
+  int add(num a);
+}
+{% endprettify %}
+
+This is a problem because in an invocation of `B.add` like the following:
+
+{% prettify dart tag=pre+code %}
+void f(B b) {
+  b.add(3.4);
+}
+{% endprettify %}
+
+`B.add` is expecting to be able to take, for example, a `double`, but when
+the method `A.add` is executed (because it's the only concrete
+implementation of `add`), a runtime exception will be thrown because a
+`double` can't be assigned to a parameter of type `int`.
+
+#### Common fixes
+
+If the method in the subclass can conform to the implementation in the
+superclass, then change the declaration in the subclass (or remove it if
+it's the same):
+
+{% prettify dart tag=pre+code %}
+class A {
+  int add(int a) => a;
+}
+class B	extends A {
+  int add(int a);
+}
+{% endprettify %}
+
+If the method in the superclass can be generalized to be a valid
+implementation of the method in the subclass, then change the superclass
+method:
+
+{% prettify dart tag=pre+code %}
+class A {
+  int add(num a) => a.floor();
+}
+class B	extends A {
+  int add(num a);
+}
+{% endprettify %}
+
+If neither the method in the superclass nor the method in the subclass can
+be changed, then provide a concrete implementation of the method in the
+subclass:
+
+{% prettify dart tag=pre+code %}
+class A {
+  int add(int a) => a;
+}
+class B	extends A {
+  int add(num a) => a.floor();
+}
+{% endprettify %}
+
 ### invalid_inline_function_type
 
 _Inline function types can't be used for parameters in a generic function type._
@@ -5260,6 +6062,20 @@
 [Understanding null safety](/null-safety/understanding-null-safety#smarter-null-aware-methods)
 for more details.
 
+The following code produces this diagnostic because `s` can't be `null`.
+
+{% prettify dart tag=pre+code %}
+void f(Object? o) {
+  var s = o as String;
+  s[!?.!]length;
+}
+{% endprettify %}
+
+The reason `s` can't be null, despite the fact that `o` can be `null`, is
+because of the cast to `String`, which is a non-nullable type. If `o` ever
+has the value `null`, the cast will fail and the invocation of `length`
+will not happen.
+
 #### Common fixes
 
 Replace the null-aware operator with a non-null-aware equivalent; for
@@ -5368,6 +6184,64 @@
 class C {}
 {% endprettify %}
 
+### invalid_return_type_for_catch_error
+
+_A value of type '{0}' can't be returned by the 'onError' handler because it
+must be assignable to '{1}'._
+
+_The return type '{0}' isn't assignable to '{1}', as required by
+'Future.catchError'._
+
+#### Description
+
+The analyzer produces this diagnostic when an invocation of
+`Future.catchError` has an argument whose return type isn't compatible with
+the type returned by the instance of `Future`. At runtime, the method
+`catchError` attempts to return the value from the callback as the result
+of the future, which results in another exception being thrown.
+
+#### Example
+
+The following code produces this diagnostic because `future` is declared to
+return an `int` while `callback` is declared to return a `String`, and
+`String` isn't a subtype of `int`:
+
+{% prettify dart tag=pre+code %}
+void f(Future<int> future, String Function(dynamic, StackTrace) callback) {
+  future.catchError([!callback!]);
+}
+{% endprettify %}
+
+The following code produces this diagnostic because the closure being
+passed to `catchError` returns an `int` while `future` is declared to
+return a `String`:
+
+{% prettify dart tag=pre+code %}
+void f(Future<String> future) {
+  future.catchError((error, stackTrace) => [!3!]);
+}
+{% endprettify %}
+
+#### Common fixes
+
+If the instance of `Future` is declared correctly, then change the callback
+to match:
+
+{% prettify dart tag=pre+code %}
+void f(Future<int> future, int Function(dynamic, StackTrace) callback) {
+  future.catchError(callback);
+}
+{% endprettify %}
+
+If the declaration of the instance of `Future` is wrong, then change it to
+match the callback:
+
+{% prettify dart tag=pre+code %}
+void f(Future<String> future, String Function(dynamic, StackTrace) callback) {
+  future.catchError(callback);
+}
+{% endprettify %}
+
 ### invalid_super_invocation
 
 _The superclass call must be last in an initializer list: '{0}'._
@@ -5526,7 +6400,7 @@
 #### Description
 
 The analyzer produces this diagnostic when an expression whose value will
-always be `null` is dererenced.
+always be `null` is dereferenced.
 
 #### Example
 
@@ -6204,6 +7078,20 @@
 var m = <String, int>{'a' : 2};
 {% endprettify %}
 
+### missing_dart_library
+
+_Required library '{0}' is missing._
+
+#### Description
+
+The analyzer produces this diagnostic when either the Dart or Flutter SDK
+isn’t installed correctly, and, as a result, one of the `dart:` libraries
+can't be found.
+
+#### Common fixes
+
+Reinstall the Dart or Flutter SDK.
+
 ### missing_default_value_for_parameter
 
 _The parameter '{0}' can't have a value of 'null' because of its type, but the
@@ -6421,6 +7309,103 @@
 Add a `return` statement that makes the return value explicit, even if
 `null` is the appropriate value.
 
+### mixin_application_no_concrete_super_invoked_member
+
+_The class doesn't have a concrete implementation of the super-invoked member
+'{0}'._
+
+#### Description
+
+The analyzer produces this diagnostic when a [mixin application][] contains
+an invocation of a member from its superclass, and there's no concrete
+member of that name in the mixin application's superclass.
+
+#### Example
+
+The following code produces this diagnostic because the mixin `M` contains
+the invocation `super.m()`, and the class `A`, which is the superclass of
+the [mixin application][] `A+M`, doesn't define a concrete implementation
+of `m`:
+
+{% prettify dart tag=pre+code %}
+abstract class A {
+  void m();
+}
+
+mixin M on A {
+  void bar() {
+    super.m();
+  }
+}
+
+abstract class B extends A with [!M!] {}
+{% endprettify %}
+
+#### Common fixes
+
+If you intended to apply the mixin `M` to a different class, one that has a
+concrete implementation of `m`, then change the superclass of `B` to that
+class:
+
+{% prettify dart tag=pre+code %}
+abstract class A {
+  void m();
+}
+
+mixin M on A {
+  void bar() {
+    super.m();
+  }
+}
+
+class C implements A {
+  void m() {}
+}
+
+abstract class B extends C with M {}
+{% endprettify %}
+
+If you need to make `B` a subclass of `A`, then add a concrete
+implementation of `m` in `A`:
+
+{% prettify dart tag=pre+code %}
+abstract class A {
+  void m() {}
+}
+
+mixin M on A {
+  void bar() {
+    super.m();
+  }
+}
+
+abstract class B extends A with M {}
+{% endprettify %}
+
+### mixin_instantiate
+
+_Mixins can't be instantiated._
+
+#### Description
+
+The analyzer produces this diagnostic when a mixin is instantiated.
+
+#### Example
+
+The following code produces this diagnostic because the mixin `M` is being
+instantiated:
+
+{% prettify dart tag=pre+code %}
+mixin M {}
+
+var m = [!M!]();
+{% endprettify %}
+
+#### Common fixes
+
+If you intend to use an instance of a class, then use the name of that
+class in place of the name of the mixin.
+
 ### mixin_of_non_class
 
 _Classes can only mix in mixins and classes._
@@ -6941,6 +7926,89 @@
 }
 {% endprettify %}
 
+### non_constant_case_expression_from_deferred_library
+
+_Constant values from a deferred library can't be used as a case expression._
+
+#### Description
+
+The analyzer produces this diagnostic when the expression in a case clause
+references a constant from a library that is imported using a deferred
+import. In order for switch statements to be compiled efficiently, the
+constants referenced in case clauses need to be available at compile time,
+and constants from deferred libraries aren't available at compile time.
+
+For more information, see the language tour's coverage of
+[deferred loading](https://dart.dev/guides/language/language-tour#lazily-loading-a-library).
+
+#### Example
+
+Given a file (`a.dart`) that defines the constant `zero`:
+
+{% prettify dart tag=pre+code %}
+const zero = 0;
+{% endprettify %}
+
+The following code produces this diagnostic because the library `a.dart` is
+imported using a `deferred` import, and the constant `a.zero`, declared in
+the imported library, is used in a case clause:
+
+{% prettify dart tag=pre+code %}
+import 'a.dart' deferred as a;
+
+void f(int x) {
+  switch (x) {
+    case [!a.zero!]:
+      // ...
+      break;
+  }
+}
+{% endprettify %}
+
+#### Common fixes
+
+If you need to reference the constant from the imported library, then
+remove the `deferred` keyword:
+
+{% prettify dart tag=pre+code %}
+import 'a.dart' as a;
+
+void f(int x) {
+  switch (x) {
+    case a.zero:
+      // ...
+      break;
+  }
+}
+{% endprettify %}
+
+If you need to reference the constant from the imported library and also
+need the imported library to be deferred, then rewrite the switch statement
+as a sequence of `if` statements:
+
+{% prettify dart tag=pre+code %}
+import 'a.dart' deferred as a;
+
+void f(int x) {
+  if (x == a.zero) {
+    // ...
+  }
+}
+{% endprettify %}
+
+If you don't need to reference the constant, then replace the case
+expression:
+
+{% prettify dart tag=pre+code %}
+void f(int x) {
+  switch (x) {
+    case 0:
+      // ...
+      break;
+  }
+}
+{% endprettify %}
+
 ### non_constant_default_value
 
 _The default value of an optional parameter must be constant._
@@ -6982,6 +8050,56 @@
 }
 {% endprettify %}
 
+### non_constant_default_value_from_deferred_library
+
+_Constant values from a deferred library can't be used as a default parameter
+value._
+
+#### Description
+
+The analyzer produces this diagnostic when the default value of an optional
+parameter uses a constant from a library imported using a deferred import.
+Default values need to be available at compile time, and constants from
+deferred libraries aren't available at compile time.
+
+For more information, see the language tour's coverage of
+[deferred loading](https://dart.dev/guides/language/language-tour#lazily-loading-a-library).
+
+#### Example
+
+Given a file (`a.dart`) that defines the constant `zero`:
+
+{% prettify dart tag=pre+code %}
+const zero = 0;
+{% endprettify %}
+
+The following code produces this diagnostic because `zero` is declared in a
+library imported using a deferred import:
+
+{% prettify dart tag=pre+code %}
+import 'a.dart' deferred as a;
+
+void f({int x = [!a.zero!]}) {}
+{% endprettify %}
+
+#### Common fixes
+
+If you need to reference the constant from the imported library, then
+remove the `deferred` keyword:
+
+{% prettify dart tag=pre+code %}
+import 'a.dart' as a;
+
+void f({int x = a.zero}) {}
+{% endprettify %}
+
+If you don't need to reference the constant, then replace the default
+value:
+
+{% prettify dart tag=pre+code %}
+void f({int x = 0}) {}
+{% endprettify %}
+
 ### non_constant_list_element
 
 _The values in a const list literal must be constants._
@@ -9518,6 +10636,53 @@
 int f(C c) => c.b;
 {% endprettify %}
 
+### subtype_of_deferred_class
+
+_Classes and mixins can't implement deferred classes._
+
+_Classes can't extend deferred classes._
+
+_Classes can't mixin deferred classes._
+
+#### Description
+
+The analyzer produces this diagnostic when a type (class or mixin) is a
+subtype of a class from a library being imported using a deferred import.
+The supertypes of a type must be compiled at the same time as the type, and
+classes from deferred libraries aren't compiled until the library is
+loaded.
+
+For more information, see the language tour's coverage of
+[deferred loading](https://dart.dev/guides/language/language-tour#lazily-loading-a-library).
+
+#### Example
+
+Given a file (`a.dart`) that defines the class `A`:
+
+{% prettify dart tag=pre+code %}
+class A {}
+{% endprettify %}
+
+The following code produces this diagnostic because the superclass of `B`
+is declared in a deferred library:
+
+{% prettify dart tag=pre+code %}
+import 'a.dart' deferred as a;
+
+class B extends [!a.A!] {}
+{% endprettify %}
+
+#### Common fixes
+
+If you need to create a subtype of a type from the deferred library, then
+remove the `deferred` keyword:
+
+{% prettify dart tag=pre+code %}
+import 'a.dart' as a;
+
+class B extends a.A {}
+{% endprettify %}
+
 ### subtype_of_disallowed_type
 
 _''{0}' can't be used as a superclass constraint._
@@ -9753,6 +10918,46 @@
 }
 {% endprettify %}
 
+### type_annotation_deferred_class
+
+_The deferred type '{0}' can't be used in a declaration, cast, or type test._
+
+#### Description
+
+The analyzer produces this diagnostic when the type annotation is in a
+variable declaration, or the type used in a cast (`as`) or type test (`is`)
+is a type declared in a library that is imported using a deferred import.
+These types are required to be available at compile time, but aren't.
+
+For more information, see the language tour's coverage of
+[deferred loading](https://dart.dev/guides/language/language-tour#lazily-loading-a-library).
+
+#### Example
+
+The following code produces this diagnostic because the type of the
+parameter `f` is imported from a deferred library:
+
+{% prettify dart tag=pre+code %}
+import 'dart:io' deferred as io;
+
+void f([!io.File!] f) {}
+{% endprettify %}
+
+#### Common fixes
+
+If you need to reference the imported type, then remove the `deferred`
+keyword:
+
+{% prettify dart tag=pre+code %}
+import 'dart:io' as io;
+
+void f(io.File f) {}
+{% endprettify %}
+
+If the import is required to be deferred and there's another type that is
+appropriate, then use that type in place of the type from the deferred
+library.
+
 ### type_argument_not_matching_bounds
 
 _'{0}' doesn't conform to the bound '{2}' of the type parameter '{1}'._
@@ -9896,7 +11101,7 @@
 
 {% prettify dart tag=pre+code %}
 void f(String? s) {
-  if ([!s!].length > 3) {
+  if (s.[!length!] > 3) {
     // ...
   }
 }
diff --git a/pkg/analyzer/tool/diagnostics/generate.dart b/pkg/analyzer/tool/diagnostics/generate.dart
index 1680135..5f8db9e 100644
--- a/pkg/analyzer/tool/diagnostics/generate.dart
+++ b/pkg/analyzer/tool/diagnostics/generate.dart
@@ -410,11 +410,13 @@
 
 * [constant context][]
 * [definite assignment][]
+* [mixin application][]
 * [override inference][]
 * [potentially non-nullable][]
 
 [constant context]: #constant-context
 [definite assignment]: #definite-assignment
+[mixin application]: #mixin-application
 [override inference]: #override-inference
 [potentially non-nullable]: #potentially-non-nullable
 
@@ -545,6 +547,40 @@
 
 [definiteAssignmentSpec](https://github.com/dart-lang/language/blob/master/resources/type-system/flow-analysis.md)
 
+### Mixin Application
+
+A _mixin application_ is the class created when a mixin is applied to a class.
+For example, consider the following declarations:
+
+```dart
+class A {}
+
+mixin M {}
+
+class B extends A with M {}
+```
+
+The class `B` is a subclass of the mixin application of `M` to `A`, sometimes
+nomenclated as `A+M`. The class `A+M` is a subclass of `A` and has members that
+are copied from `M`.
+
+You can give an actual name to a mixin application by defining it as:
+
+```dart
+class A {}
+
+mixin M {}
+
+class A_M = A with M;
+```
+
+Given this declaration of `A_M`, the following declaration of `B` is equivalent
+to the declaration of `B` in the original example:
+
+```dart
+class B extends A_M {}
+```
+
 ### Override inference
 
 Override inference is the process by which any missing types in a method
diff --git a/pkg/analyzer/tool/experiments/generate.dart b/pkg/analyzer/tool/experiments/generate.dart
index f57961d..3aabe61 100644
--- a/pkg/analyzer/tool/experiments/generate.dart
+++ b/pkg/analyzer/tool/experiments/generate.dart
@@ -68,7 +68,7 @@
     features = <String, dynamic>{};
     Map yamlFeatures = experimentsYaml['features'];
     for (MapEntry entry in yamlFeatures.entries) {
-      String category = entry.value['category'] ?? 'language';
+      String category = (entry.value as YamlMap)['category'] ?? 'language';
       if (category != "language") {
         // Skip a feature with a category that's not language. In the future
         // possibly allow e.g. 'analyzer' etc.
diff --git a/pkg/analyzer/tool/summary/stats.dart b/pkg/analyzer/tool/summary/stats.dart
index 86c0677..d03b7db 100644
--- a/pkg/analyzer/tool/summary/stats.dart
+++ b/pkg/analyzer/tool/summary/stats.dart
@@ -66,6 +66,9 @@
           value == false ||
           value == '' ||
           value is List && value.isEmpty ||
+          // TODO(srawlins): Remove this and enumerate each enum which may
+          // be encountered.
+          // ignore: avoid_dynamic_calls
           reflect(value).type.isEnum && (value as dynamic).index == 0) {
         return;
       }
diff --git a/pkg/analyzer_cli/bin/analyzer.dart b/pkg/analyzer_cli/bin/analyzer.dart
index 4381de7..e7fa96b 100644
--- a/pkg/analyzer_cli/bin/analyzer.dart
+++ b/pkg/analyzer_cli/bin/analyzer.dart
@@ -3,17 +3,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 'dart:isolate';
-
 import 'package:analyzer_cli/starter.dart';
 
 /// The entry point for the command-line analyzer.
-///
-/// [sendPort] may be passed in when started in an isolate. If provided, it is
-/// used for bazel worker communication instead of stdin/stdout.
-void main(List<String> args, [SendPort sendPort]) async {
+void main(List<String> args) async {
   var starter = CommandLineStarter();
 
   // Wait for the starter to complete.
-  await starter.start(args, sendPort: sendPort);
+  await starter.start(args);
 }
diff --git a/pkg/analyzer_cli/lib/src/build_mode.dart b/pkg/analyzer_cli/lib/src/build_mode.dart
deleted file mode 100644
index 5223b4a..0000000
--- a/pkg/analyzer_cli/lib/src/build_mode.dart
+++ /dev/null
@@ -1,727 +0,0 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart: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';
-import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/error/error.dart';
-import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/src/context/context.dart';
-import 'package:analyzer/src/context/packages.dart';
-import 'package:analyzer/src/dart/analysis/byte_store.dart';
-import 'package:analyzer/src/dart/analysis/cache.dart';
-import 'package:analyzer/src/dart/analysis/driver.dart';
-import 'package:analyzer/src/dart/analysis/driver_based_analysis_context.dart'
-    as api;
-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';
-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/package_bundle_reader.dart';
-import 'package:analyzer/src/summary/summary_sdk.dart' show SummaryBasedDartSdk;
-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';
-import 'package:analyzer_cli/src/error_severity.dart';
-import 'package:analyzer_cli/src/has_context_mixin.dart';
-import 'package:analyzer_cli/src/options.dart';
-import 'package:bazel_worker/bazel_worker.dart';
-import 'package:collection/collection.dart';
-import 'package:convert/convert.dart';
-
-/// Persistent Bazel worker.
-class AnalyzerWorkerLoop extends AsyncWorkerLoop {
-  final ResourceProvider resourceProvider;
-  final PerformanceLog logger = PerformanceLog(null);
-  final String dartSdkPath;
-  WorkerPackageBundleCache packageBundleCache;
-
-  final StringBuffer errorBuffer = StringBuffer();
-  final StringBuffer outBuffer = StringBuffer();
-
-  AnalyzerWorkerLoop(this.resourceProvider, AsyncWorkerConnection connection,
-      {this.dartSdkPath})
-      : super(connection: connection) {
-    packageBundleCache =
-        WorkerPackageBundleCache(resourceProvider, logger, 256 * 1024 * 1024);
-  }
-
-  factory AnalyzerWorkerLoop.sendPort(
-      ResourceProvider resourceProvider, SendPort sendPort,
-      {String dartSdkPath}) {
-    AsyncWorkerConnection connection = SendPortAsyncWorkerConnection(sendPort);
-    return AnalyzerWorkerLoop(resourceProvider, connection,
-        dartSdkPath: dartSdkPath);
-  }
-
-  factory AnalyzerWorkerLoop.std(ResourceProvider resourceProvider,
-      {io.Stdin stdinStream, io.Stdout stdoutStream, String dartSdkPath}) {
-    AsyncWorkerConnection connection = StdAsyncWorkerConnection(
-        inputStream: stdinStream, outputStream: stdoutStream);
-    return AnalyzerWorkerLoop(resourceProvider, connection,
-        dartSdkPath: dartSdkPath);
-  }
-
-  /// Performs analysis with given [options].
-  Future<void> analyze(
-      CommandLineOptions options, Map<String, WorkerInput> inputs) async {
-    var packageBundleProvider =
-        WorkerPackageBundleProvider(packageBundleCache, inputs);
-    var buildMode = BuildMode(resourceProvider, options, AnalysisStats(),
-        ContextCache(resourceProvider, options, Driver.verbosePrint),
-        logger: logger, packageBundleProvider: packageBundleProvider);
-    await buildMode.analyze();
-    AnalysisEngine.instance.clearCaches();
-  }
-
-  /// Perform a single loop step.
-  @override
-  Future<WorkResponse> performRequest(WorkRequest request) async {
-    return logger.runAsync('Perform request', () async {
-      errorBuffer.clear();
-      outBuffer.clear();
-      try {
-        // Prepare inputs with their digests.
-        var inputs = <String, WorkerInput>{};
-        for (var input in request.inputs) {
-          inputs[input.path] = WorkerInput(input.path, input.digest);
-        }
-
-        // Add in the dart-sdk argument if `dartSdkPath` is not null,
-        // otherwise it will try to find the currently installed sdk.
-        var arguments = request.arguments.toList();
-        if (dartSdkPath != null &&
-            !arguments.any((arg) => arg.startsWith('--dart-sdk'))) {
-          arguments.add('--dart-sdk=$dartSdkPath');
-        }
-
-        // Prepare options.
-        var options = CommandLineOptions.parse(resourceProvider, arguments,
-            printAndFail: (String msg) {
-          throw ArgumentError(msg);
-        });
-
-        // Analyze and respond.
-        await analyze(options, inputs);
-        var msg = _getErrorOutputBuffersText();
-        return WorkResponse()
-          ..exitCode = EXIT_CODE_OK
-          ..output = msg;
-      } catch (e, st) {
-        var msg = _getErrorOutputBuffersText();
-        msg += '$e\n$st';
-        return WorkResponse()
-          ..exitCode = EXIT_CODE_ERROR
-          ..output = msg;
-      }
-    });
-  }
-
-  /// Run the worker loop.
-  @override
-  Future<void> run() async {
-    errorSink = errorBuffer;
-    outSink = outBuffer;
-    exitHandler = (int exitCode) {
-      throw StateError('Exit called: $exitCode');
-    };
-    await super.run();
-  }
-
-  String _getErrorOutputBuffersText() {
-    var msg = '';
-    if (errorBuffer.isNotEmpty) {
-      msg += errorBuffer.toString() + '\n';
-    }
-    if (outBuffer.isNotEmpty) {
-      msg += outBuffer.toString() + '\n';
-    }
-    return msg;
-  }
-}
-
-/// Analyzer used when the "--build-mode" option is supplied.
-class BuildMode with HasContextMixin {
-  @override
-  final ResourceProvider resourceProvider;
-  final CommandLineOptions options;
-  final AnalysisStats stats;
-  final PerformanceLog logger;
-  final PackageBundleProvider packageBundleProvider;
-
-  @override
-  final ContextCache contextCache;
-
-  SummaryDataStore summaryDataStore;
-  AnalysisOptionsImpl analysisOptions;
-  Map<Uri, File> uriToFileMap;
-  final List<Source> explicitSources = <Source>[];
-
-  SourceFactory sourceFactory;
-  DeclaredVariables declaredVariables;
-  AnalysisDriver analysisDriver;
-
-  LinkedElementFactory elementFactory;
-
-  // May be null.
-  final DependencyTracker dependencyTracker;
-
-  BuildMode(this.resourceProvider, this.options, this.stats, this.contextCache,
-      {PerformanceLog logger, PackageBundleProvider packageBundleProvider})
-      : logger = logger ?? PerformanceLog(null),
-        packageBundleProvider = packageBundleProvider ??
-            DirectPackageBundleProvider(resourceProvider),
-        dependencyTracker = options.summaryDepsOutput != null
-            ? DependencyTracker(options.summaryDepsOutput)
-            : null;
-
-  bool get _shouldOutputSummary =>
-      options.buildSummaryOutput != null ||
-      options.buildSummaryOutputSemantic != null;
-
-  /// Perform package analysis according to the given [options].
-  Future<ErrorSeverity> analyze() async {
-    return await logger.runAsync('Analyze', () async {
-      // Write initial progress message.
-      if (!options.machineFormat) {
-        outSink.writeln("Analyzing ${options.sourceFiles.join(', ')}...");
-      }
-
-      // Create the URI to file map.
-      uriToFileMap = _createUriToFileMap(options.sourceFiles);
-      if (uriToFileMap == null) {
-        io.exitCode = ErrorSeverity.ERROR.ordinal;
-        return ErrorSeverity.ERROR;
-      }
-
-      // BuildMode expects sourceFiles in the format "<uri>|<filepath>",
-      // but the rest of the code base does not understand this format.
-      // Rewrite sourceFiles, stripping the "<uri>|" prefix, so that it
-      // does not cause problems with code that does not expect this format.
-      options.rewriteSourceFiles(options.sourceFiles
-          .map((String uriPipePath) =>
-              uriPipePath.substring(uriPipePath.indexOf('|') + 1))
-          .toList());
-
-      // Prepare the analysis driver.
-      try {
-        logger.run('Prepare analysis driver', () {
-          _createAnalysisDriver();
-        });
-      } on ConflictingSummaryException catch (e) {
-        errorSink.writeln('$e');
-        io.exitCode = ErrorSeverity.ERROR.ordinal;
-        return ErrorSeverity.ERROR;
-      }
-
-      // Add sources.
-      for (var uri in uriToFileMap.keys) {
-        var file = uriToFileMap[uri];
-        if (!file.exists) {
-          errorSink.writeln('File not found: ${file.path}');
-          io.exitCode = ErrorSeverity.ERROR.ordinal;
-          return ErrorSeverity.ERROR;
-        }
-        Source source = FileSource(file, uri);
-        explicitSources.add(source);
-      }
-
-      // Write summary.
-      if (_shouldOutputSummary) {
-        await logger.runAsync('Build and write output summary', () async {
-          // Build and assemble linked libraries.
-          var bytes = _computeLinkedLibraries2();
-
-          // Write the whole package bundle.
-          // TODO(scheglov) Remove support for `buildSummaryOutput`.
-          if (options.buildSummaryOutput != null) {
-            var file = io.File(options.buildSummaryOutput);
-            file.writeAsBytesSync(bytes, mode: io.FileMode.writeOnly);
-          }
-          if (options.buildSummaryOutputSemantic != null) {
-            var file = io.File(options.buildSummaryOutputSemantic);
-            file.writeAsBytesSync(bytes, mode: io.FileMode.writeOnly);
-          }
-        });
-      } else {
-        // Build the graph, e.g. associate parts with libraries.
-        for (var file in uriToFileMap.values) {
-          analysisDriver.fsState.getFileForPath(file.path);
-        }
-      }
-
-      ErrorSeverity severity;
-      if (options.buildSummaryOnly) {
-        severity = ErrorSeverity.NONE;
-      } else {
-        // Process errors.
-        await _printErrors(outputPath: options.buildAnalysisOutput);
-        severity = await _computeMaxSeverity();
-      }
-
-      if (dependencyTracker != null) {
-        var file = io.File(dependencyTracker.outputPath);
-        file.writeAsStringSync(dependencyTracker.dependencies.join('\n'));
-      }
-
-      return severity;
-    });
-  }
-
-  /// Use [elementFactory] filled with input summaries, and link libraries
-  /// 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;
-
-        var parseResult = analysisDriver.parseFileSync(path);
-        if (parseResult == null) {
-          throw ArgumentError('No parsed unit for $path');
-        }
-
-        var unit = parseResult.unit;
-        var isPart = unit.directives.any((d) => d is PartOfDirective);
-        if (isPart) {
-          continue;
-        }
-
-        var inputUnits = <LinkInputUnit>[];
-        inputUnits.add(
-          LinkInputUnit(null, librarySource, false, unit),
-        );
-
-        for (var directive in unit.directives) {
-          if (directive is PartDirective) {
-            var partUri = directive.uri.stringValue;
-            var partSource = sourceFactory.resolveUri(librarySource, partUri);
-
-            // Add empty synthetic units for unresolved `part` URIs.
-            if (partSource == null) {
-              continue;
-            }
-
-            var partPath = partSource.fullName;
-            var partParseResult = analysisDriver.parseFileSync(partPath);
-            if (partParseResult == null) {
-              throw ArgumentError('No parsed unit for part $partPath in $path');
-            }
-            inputUnits.add(
-              LinkInputUnit(
-                partUri,
-                partSource,
-                false,
-                partParseResult.unit,
-              ),
-            );
-          }
-        }
-
-        inputLibraries.add(
-          LinkInputLibrary(librarySource, inputUnits),
-        );
-      }
-
-      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,
-      );
-    });
-  }
-
-  Future<ErrorSeverity> _computeMaxSeverity() async {
-    var maxSeverity = ErrorSeverity.NONE;
-    if (!options.buildSuppressExitCode) {
-      for (var source in explicitSources) {
-        var result = await analysisDriver.getErrors(source.fullName);
-        for (var error in result.errors) {
-          var processedSeverity = determineProcessedSeverity(
-              error, options, analysisDriver.analysisOptions);
-          if (processedSeverity != null) {
-            maxSeverity = maxSeverity.max(processedSeverity);
-          }
-        }
-      }
-    }
-    return maxSeverity;
-  }
-
-  void _createAnalysisDriver() {
-    // Read the summaries.
-    summaryDataStore = SummaryDataStore(<String>[]);
-
-    // Adds a bundle at `path` to `summaryDataStore`.
-    PackageBundleReader addBundle(String path) {
-      var bundle = packageBundleProvider.get(path);
-      summaryDataStore.addBundle(path, bundle);
-      return bundle;
-    }
-
-    SummaryBasedDartSdk sdk;
-    logger.run('Add SDK bundle', () {
-      sdk = SummaryBasedDartSdk(options.dartSdkSummaryPath, true);
-      summaryDataStore.addBundle(null, sdk.bundle);
-    });
-
-    var numInputs = options.buildSummaryInputs.length;
-    logger.run('Add $numInputs input summaries', () {
-      for (var path in options.buildSummaryInputs) {
-        addBundle(path);
-      }
-    });
-
-    var rootPath =
-        options.sourceFiles.isEmpty ? null : options.sourceFiles.first;
-
-    var packages = _findPackages(rootPath);
-
-    sourceFactory = SourceFactory(<UriResolver>[
-      DartUriResolver(sdk),
-      TrackingInSummaryUriResolver(
-          InSummaryUriResolver(resourceProvider, summaryDataStore),
-          dependencyTracker),
-      ExplicitSourceResolver(uriToFileMap)
-    ]);
-
-    analysisOptions =
-        createAnalysisOptionsForCommandLineOptions(options, rootPath);
-
-    var scheduler = AnalysisDriverScheduler(logger);
-    analysisDriver = AnalysisDriver(
-      scheduler,
-      logger,
-      resourceProvider,
-      MemoryByteStore(),
-      FileContentOverlay(),
-      null,
-      sourceFactory,
-      analysisOptions,
-      externalSummaries: summaryDataStore,
-      packages: packages,
-    );
-
-    _setAnalysisDriverAnalysisContext(rootPath);
-
-    declaredVariables = DeclaredVariables.fromMap(options.definedVariables);
-    analysisDriver.declaredVariables = declaredVariables;
-
-    _createLinkedElementFactory();
-
-    scheduler.start();
-  }
-
-  void _createLinkedElementFactory() {
-    var analysisContext = AnalysisContextImpl(
-      SynchronousSession(analysisOptions, declaredVariables),
-      sourceFactory,
-    );
-
-    elementFactory = LinkedElementFactory(
-      analysisContext,
-      AnalysisSessionImpl(null),
-      Reference.root(),
-    );
-
-    for (var bundle in summaryDataStore.bundles) {
-      elementFactory.addBundle(
-        BundleReader(
-          elementFactory: elementFactory,
-          astBytes: bundle.astBytes,
-          resolutionBytes: bundle.resolutionBytes,
-        ),
-      );
-    }
-  }
-
-  /// Convert [sourceEntities] (a list of file specifications of the form
-  /// "$uri|$path") to a map from URI to path. If an error occurs, report the
-  /// error and return null.
-  Map<Uri, File> _createUriToFileMap(List<String> sourceEntities) {
-    var uriToFileMap = <Uri, File>{};
-    for (var sourceFile in sourceEntities) {
-      var pipeIndex = sourceFile.indexOf('|');
-      if (pipeIndex == -1) {
-        // TODO(paulberry): add the ability to guess the URI from the path.
-        errorSink.writeln(
-            'Illegal input file (must be "\$uri|\$path"): $sourceFile');
-        return null;
-      }
-      var uri = Uri.parse(sourceFile.substring(0, pipeIndex));
-      var path = sourceFile.substring(pipeIndex + 1);
-      path = resourceProvider.pathContext.absolute(path);
-      path = resourceProvider.pathContext.normalize(path);
-      uriToFileMap[uri] = resourceProvider.getFile(path);
-    }
-    return uriToFileMap;
-  }
-
-  Packages _findPackages(String path) {
-    var configPath = options.packageConfigPath;
-    if (configPath != null) {
-      var configFile = resourceProvider.getFile(configPath);
-      return parsePackagesFile(resourceProvider, configFile);
-    }
-
-    if (path != null) {
-      var file = resourceProvider.getFile(path);
-      return findPackagesFrom(resourceProvider, file);
-    }
-
-    return Packages.empty;
-  }
-
-  /// Print errors for all explicit sources. If [outputPath] is supplied, output
-  /// is sent to a new file at that path.
-  Future<void> _printErrors({String outputPath}) async {
-    await logger.runAsync('Compute and print analysis errors', () async {
-      var buffer = StringBuffer();
-      var severityProcessor = (AnalysisError error) =>
-          determineProcessedSeverity(error, options, analysisOptions);
-      var formatter = options.machineFormat
-          ? MachineErrorFormatter(buffer, options, stats,
-              severityProcessor: severityProcessor)
-          : HumanErrorFormatter(buffer, options, stats,
-              severityProcessor: severityProcessor);
-      for (var source in explicitSources) {
-        var result = await analysisDriver.getErrors(source.fullName);
-        formatter.formatErrors([result]);
-      }
-      formatter.flush();
-      if (!options.machineFormat) {
-        stats.print(buffer);
-      }
-      if (outputPath == null) {
-        var sink = options.machineFormat ? errorSink : outSink;
-        sink.write(buffer);
-      } else {
-        io.File(outputPath).writeAsStringSync(buffer.toString());
-      }
-    });
-  }
-
-  void _setAnalysisDriverAnalysisContext(String rootPath) {
-    if (rootPath == null) {
-      return;
-    }
-
-    var apiContextRoots = api.ContextLocator(
-      resourceProvider: resourceProvider,
-    ).locateRoots(
-      includedPaths: [rootPath],
-      excludedPaths: [],
-    );
-
-    if (apiContextRoots.isEmpty) {
-      return;
-    }
-
-    analysisDriver.configure(
-      analysisContext: api.DriverBasedAnalysisContext(
-        resourceProvider,
-        apiContextRoots.first,
-        analysisDriver,
-      ),
-    );
-  }
-}
-
-/// Tracks paths to dependencies, really just a thin api around a Set<String>.
-class DependencyTracker {
-  final _dependencies = <String>{};
-
-  /// The path to the file to create once tracking is done.
-  final String outputPath;
-
-  DependencyTracker(this.outputPath);
-
-  Iterable<String> get dependencies => _dependencies;
-
-  void record(String path) => _dependencies.add(path);
-}
-
-/// [PackageBundleProvider] that always reads from the [ResourceProvider].
-class DirectPackageBundleProvider implements PackageBundleProvider {
-  final ResourceProvider resourceProvider;
-
-  DirectPackageBundleProvider(this.resourceProvider);
-
-  @override
-  PackageBundleReader get(String path) {
-    var bytes = io.File(path).readAsBytesSync();
-    return PackageBundleReader(bytes);
-  }
-}
-
-/// Instances of the class [ExplicitSourceResolver] map URIs to files on disk
-/// using a fixed mapping provided at construction time.
-class ExplicitSourceResolver extends UriResolver {
-  final Map<Uri, File> uriToFileMap;
-  final Map<String, Uri> pathToUriMap;
-
-  /// Construct an [ExplicitSourceResolver] based on the given [uriToFileMap].
-  ExplicitSourceResolver(Map<Uri, File> uriToFileMap)
-      : uriToFileMap = uriToFileMap,
-        pathToUriMap = _computePathToUriMap(uriToFileMap);
-
-  @override
-  Source resolveAbsolute(Uri uri, [Uri actualUri]) {
-    var file = uriToFileMap[uri];
-    actualUri ??= uri;
-    if (file == null) {
-      return null;
-    } else {
-      return FileSource(file, actualUri);
-    }
-  }
-
-  @override
-  Uri restoreAbsolute(Source source) {
-    return pathToUriMap[source.fullName];
-  }
-
-  /// Build the inverse mapping of [uriToSourceMap].
-  static Map<String, Uri> _computePathToUriMap(Map<Uri, File> uriToSourceMap) {
-    var pathToUriMap = <String, Uri>{};
-    uriToSourceMap.forEach((Uri uri, File file) {
-      pathToUriMap[file.path] = uri;
-    });
-    return pathToUriMap;
-  }
-}
-
-/// Provider for [PackageBundleReader]s by file paths.
-abstract class PackageBundleProvider {
-  /// Return the [PackageBundleReader] for the file with the given [path].
-  PackageBundleReader get(String path);
-}
-
-/// Wrapper for [InSummaryUriResolver] that tracks accesses to summaries.
-class TrackingInSummaryUriResolver extends UriResolver {
-  // May be null.
-  final DependencyTracker dependencyTracker;
-  final InSummaryUriResolver inSummaryUriResolver;
-
-  TrackingInSummaryUriResolver(
-      this.inSummaryUriResolver, this.dependencyTracker);
-
-  @override
-  Source resolveAbsolute(Uri uri) {
-    var source = inSummaryUriResolver.resolveAbsolute(uri);
-    if (dependencyTracker != null &&
-        source != null &&
-        source is InSummarySource) {
-      dependencyTracker.record(source.summaryPath);
-    }
-    return source;
-  }
-}
-
-/// Worker input.
-///
-/// Bazel does not specify the format of the digest, so we cannot assume that
-/// the digest itself is enough to uniquely identify inputs. So, we use a pair
-/// of path + digest.
-class WorkerInput {
-  static const _digestEquality = ListEquality<int>();
-
-  final String path;
-  final List<int> digest;
-
-  WorkerInput(this.path, this.digest);
-
-  @override
-  int get hashCode => _digestEquality.hash(digest);
-
-  @override
-  bool operator ==(Object other) {
-    return other is WorkerInput &&
-        other.path == path &&
-        _digestEquality.equals(other.digest, digest);
-  }
-
-  @override
-  String toString() => '$path @ ${hex.encode(digest)}';
-}
-
-/// Value object for [WorkerPackageBundleCache].
-class WorkerPackageBundle {
-  final List<int> bytes;
-  final PackageBundleReader bundle;
-
-  WorkerPackageBundle(this.bytes, this.bundle);
-
-  /// Approximation of a bundle size in memory.
-  int get size => bytes.length * 3;
-}
-
-/// Cache of [PackageBundleReader]s.
-class WorkerPackageBundleCache {
-  final ResourceProvider resourceProvider;
-  final PerformanceLog logger;
-  final Cache<WorkerInput, WorkerPackageBundle> _cache;
-
-  WorkerPackageBundleCache(this.resourceProvider, this.logger, int maxSizeBytes)
-      : _cache = Cache<WorkerInput, WorkerPackageBundle>(
-            maxSizeBytes, (value) => value.size);
-
-  /// Get the [PackageBundleReader] from the file with the given [path] in the context
-  /// of the given worker [inputs].
-  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 file = resourceProvider.getFile(path);
-      var bytes = file.readAsBytesSync() as Uint8List;
-      return PackageBundleReader(bytes);
-    }
-
-    return _cache.get(input, () {
-      logger.writeln('Read $input.');
-      var file = resourceProvider.getFile(path);
-      var bytes = file.readAsBytesSync() as Uint8List;
-      var bundle = PackageBundleReader(bytes);
-      return WorkerPackageBundle(bytes, bundle);
-    }).bundle;
-  }
-}
-
-/// [PackageBundleProvider] that reads from [WorkerPackageBundleCache] using
-/// the request specific [inputs].
-class WorkerPackageBundleProvider implements PackageBundleProvider {
-  final WorkerPackageBundleCache cache;
-  final Map<String, WorkerInput> inputs;
-
-  WorkerPackageBundleProvider(this.cache, this.inputs);
-
-  @override
-  PackageBundleReader get(String path) {
-    return cache.get(inputs, path);
-  }
-}
diff --git a/pkg/analyzer_cli/lib/src/context_cache.dart b/pkg/analyzer_cli/lib/src/context_cache.dart
deleted file mode 100644
index 876239c..0000000
--- a/pkg/analyzer_cli/lib/src/context_cache.dart
+++ /dev/null
@@ -1,139 +0,0 @@
-// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:analyzer/dart/analysis/features.dart';
-import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/src/context/builder.dart';
-import 'package:analyzer/src/dart/analysis/experiments.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer_cli/src/options.dart';
-import 'package:path/path.dart' as path;
-import 'package:pub_semver/pub_semver.dart';
-
-/// Cache of [AnalysisOptionsImpl] objects that correspond to directories
-/// with analyzed files, used to reduce searching for `analysis_options.yaml`
-/// files.
-class ContextCache {
-  final ResourceProvider resourceProvider;
-  final CommandLineOptions clOptions;
-  final void Function(String) verbosePrint;
-
-  /// A mapping from normalized paths (currently, directories) to cache entries
-  /// which include builder, analysis_options paths, and [AnalysisOptionImpl]s.
-  final Map<String, ContextCacheEntry> _byDirectory = {};
-
-  ContextCache(this.resourceProvider, this.clOptions, this.verbosePrint);
-
-  /// Look up info about a context from the cache. You can pass in any [path],
-  /// and it will try to provide an existing [ContextCacheEntry] that is
-  /// suitable for that [path] if one exists.
-  ContextCacheEntry forSource(String path) {
-    path = _normalizeSourcePath(path);
-    return _byDirectory.putIfAbsent(path, () {
-      final builder = ContextBuilder(resourceProvider, null, null,
-          options: clOptions.contextBuilderOptions);
-      return ContextCacheEntry(builder, path, clOptions, verbosePrint);
-    });
-  }
-
-  /// Cheaply normalize source paths so we can increase cache performance.
-  /// Getting the location of an analysis_options.yaml file for a given source
-  /// can be expensive, so we want to reduce extra lookups where possible. We
-  /// know that two files in the same directory share an analysis options file,
-  /// so that's the normalization we perform currently. However, this could be
-  /// any form of performance-increasing cache key normalization.
-  String _normalizeSourcePath(String sourcePath) {
-    if (!resourceProvider.pathContext.isAbsolute(sourcePath)) {
-      // TODO(mfairhurst) Use resourceProvider.pathContext.absolute(). For the
-      // moment, we get an issues where pathContext.current is `.`, which causes
-      // pathContext.absolute() to produce `./foo` instead of `/absolute/foo`.
-      sourcePath = path.absolute(sourcePath);
-    }
-
-    sourcePath = resourceProvider.pathContext.normalize(sourcePath);
-
-    // Prepare the directory which is, or contains, the context root.
-    if (resourceProvider.getFolder(sourcePath).exists) {
-      return sourcePath;
-    }
-
-    return resourceProvider.pathContext.dirname(sourcePath);
-  }
-}
-
-/// Each entry of the [ContextCache] caches three things: the [ContextBuilder],
-/// the analysis_options.yaml path of the context, and the [AnalysisOptionsImpl]
-/// of the context.
-class ContextCacheEntry {
-  final CommandLineOptions clOptions;
-  final ContextBuilder builder;
-  final String requestedSourceDirectory;
-  final void Function(String) verbosePrint;
-
-  AnalysisOptionsImpl _analysisOptions;
-  String _analysisRoot;
-
-  ContextCacheEntry(this.builder, this.requestedSourceDirectory, this.clOptions,
-      this.verbosePrint);
-
-  /// Get the fully parsed [AnalysisOptionsImpl] for this entry.
-  AnalysisOptionsImpl get analysisOptions =>
-      _analysisOptions ??= _getAnalysisOptions();
-
-  /// Find the root path from which excludes should be considered due to where
-  /// the analysis_options.yaml was defined.
-  String get analysisRoot => _analysisRoot ??= _getAnalysisRoot();
-
-  void _buildContextFeatureSet(AnalysisOptionsImpl analysisOptions) {
-    var featureSet = FeatureSet.fromEnableFlags2(
-      sdkLanguageVersion: ExperimentStatus.currentVersion,
-      flags: clOptions.enabledExperiments,
-    );
-
-    analysisOptions.contextFeatures = featureSet;
-
-    if (clOptions.defaultLanguageVersion != null) {
-      var nonPackageLanguageVersion = Version.parse(
-        clOptions.defaultLanguageVersion + '.0',
-      );
-      analysisOptions.nonPackageLanguageVersion = nonPackageLanguageVersion;
-      analysisOptions.nonPackageFeatureSet = FeatureSet.latestLanguageVersion()
-          .restrictToVersion(nonPackageLanguageVersion);
-    }
-  }
-
-  /// The actual calculation to get the [AnalysisOptionsImpl], with no caching.
-  /// This should not be used except behind the getter which caches this result
-  /// automatically.
-  AnalysisOptionsImpl _getAnalysisOptions() {
-    var workspace = ContextBuilder.createWorkspace(
-      resourceProvider: builder.resourceProvider,
-      options: builder.builderOptions,
-      rootPath: requestedSourceDirectory,
-    );
-    var contextOptions = builder.getAnalysisOptions(
-        requestedSourceDirectory, workspace,
-        verbosePrint: clOptions.verbose ? verbosePrint : null);
-
-    _buildContextFeatureSet(contextOptions);
-    contextOptions.hint = !clOptions.disableHints;
-    return contextOptions;
-  }
-
-  /// The actual calculation to get the analysis root, with no caching. This
-  /// should not be used except behind the getter which caches this result
-  /// automatically.
-  String _getAnalysisRoot() {
-    // The analysis yaml defines the root, if it exists.
-    var analysisOptionsPath = builder
-        .getOptionsFile(requestedSourceDirectory, forceSearch: true)
-        ?.path;
-
-    if (analysisOptionsPath == null) {
-      return requestedSourceDirectory;
-    }
-
-    return path.dirname(analysisOptionsPath);
-  }
-}
diff --git a/pkg/analyzer_cli/lib/src/driver.dart b/pkg/analyzer_cli/lib/src/driver.dart
index 2767510..480cbea 100644
--- a/pkg/analyzer_cli/lib/src/driver.dart
+++ b/pkg/analyzer_cli/lib/src/driver.dart
@@ -3,16 +3,12 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'dart:io' as io;
-import 'dart:isolate';
 
-import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/sdk/build_sdk_summary.dart';
 import 'package:analyzer/error/error.dart';
 import 'package:analyzer/error/listener.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/file_system/physical_file_system.dart';
-import 'package:analyzer/src/command_line/arguments.dart'
-    show applyAnalysisOptionFlags;
 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';
@@ -34,18 +30,14 @@
 import 'package:analyzer/src/util/yaml.dart';
 import 'package:analyzer_cli/src/analyzer_impl.dart';
 import 'package:analyzer_cli/src/batch_mode.dart';
-import 'package:analyzer_cli/src/build_mode.dart';
-import 'package:analyzer_cli/src/context_cache.dart';
 import 'package:analyzer_cli/src/error_formatter.dart';
 import 'package:analyzer_cli/src/error_severity.dart';
-import 'package:analyzer_cli/src/has_context_mixin.dart';
 import 'package:analyzer_cli/src/options.dart';
 import 'package:analyzer_cli/src/perf_report.dart';
 import 'package:analyzer_cli/starter.dart' show CommandLineStarter;
 import 'package:linter/src/rules.dart' as linter;
 import 'package:meta/meta.dart';
 import 'package:path/path.dart' as path;
-import 'package:pub_semver/pub_semver.dart';
 import 'package:yaml/yaml.dart';
 
 /// Shared IO sink for standard error reporting.
@@ -56,16 +48,13 @@
 
 /// Test this option map to see if it specifies lint rules.
 bool containsLintRuleEntry(YamlMap options) {
-  var linterNode = getValue(options, 'linter');
-  return linterNode is YamlMap && getValue(linterNode, 'rules') != null;
+  var linterNode = options.valueAt('linter');
+  return linterNode is YamlMap && linterNode.valueAt('rules') != null;
 }
 
-class Driver with HasContextMixin implements CommandLineStarter {
+class Driver implements CommandLineStarter {
   static final ByteStore analysisDriverMemoryByteStore = MemoryByteStore();
 
-  @override
-  ContextCache contextCache;
-
   _AnalysisContextProvider _analysisContextProvider;
   DriverBasedAnalysisContext analysisContext;
 
@@ -78,7 +67,6 @@
   int _analyzedFileCount = 0;
 
   /// The resource provider used to access the file system.
-  @override
   final ResourceProvider resourceProvider = PhysicalResourceProvider.INSTANCE;
 
   /// Collected analysis statistics.
@@ -99,7 +87,7 @@
   }
 
   @override
-  Future<void> start(List<String> args, {SendPort sendPort}) async {
+  Future<void> start(List<String> args) async {
     if (analysisDriver != null) {
       throw StateError('start() can only be called once');
     }
@@ -115,13 +103,7 @@
     _analysisContextProvider = _AnalysisContextProvider(resourceProvider);
 
     // Do analysis.
-    if (options.buildMode) {
-      var severity = await _buildModeAnalyze(options, sendPort);
-      // Propagate issues to the exit code.
-      if (_shouldBeFatal(severity, options)) {
-        io.exitCode = severity.ordinal;
-      }
-    } else if (options.batchMode) {
+    if (options.batchMode) {
       var batchRunner = BatchRunner(outSink, errorSink);
       batchRunner.runAsBatch(args, (List<String> args) async {
         var options = CommandLineOptions.parse(resourceProvider, args);
@@ -167,7 +149,7 @@
 
   /// Perform analysis according to the given [options].
   Future<ErrorSeverity> _analyzeAll(CommandLineOptions options) async {
-    if (!options.machineFormat) {
+    if (!options.jsonFormat && !options.machineFormat) {
       var fileNames = options.sourceFiles.map((String file) {
         file = path.normalize(file);
         if (file == '.') {
@@ -202,7 +184,10 @@
     // batch mode which removes the batch flag to prevent the "cannot have the
     // batch flag and source file" error message.
     ErrorFormatter formatter;
-    if (options.machineFormat) {
+    if (options.jsonFormat) {
+      formatter = JsonErrorFormatter(errorSink, options, stats,
+          severityProcessor: defaultSeverityProcessor);
+    } else if (options.machineFormat) {
       formatter = MachineErrorFormatter(errorSink, options, stats,
           severityProcessor: defaultSeverityProcessor);
     } else {
@@ -385,27 +370,6 @@
     return allResult;
   }
 
-  /// Perform analysis in build mode according to the given [options].
-  ///
-  /// If [sendPort] is provided it is used for bazel worker communication
-  /// instead of stdin/stdout.
-  Future<ErrorSeverity> _buildModeAnalyze(
-      CommandLineOptions options, SendPort sendPort) async {
-    if (options.buildModePersistentWorker) {
-      var workerLoop = sendPort == null
-          ? AnalyzerWorkerLoop.std(resourceProvider,
-              dartSdkPath: options.dartSdkPath)
-          : AnalyzerWorkerLoop.sendPort(resourceProvider, sendPort,
-              dartSdkPath: options.dartSdkPath);
-      await workerLoop.run();
-      return ErrorSeverity.NONE;
-    } else {
-      return await BuildMode(resourceProvider, options, stats,
-              ContextCache(resourceProvider, options, verbosePrint))
-          .analyze();
-    }
-  }
-
   /// Collect all analyzable files at [filePath], recursively if it's a
   /// directory, ignoring links.
   Iterable<io.File> _collectFiles(String filePath, AnalysisOptions options) {
@@ -487,8 +451,6 @@
             previous.showPackageWarningsPrefix &&
         newOptions.showSdkWarnings == previous.showSdkWarnings &&
         newOptions.lints == previous.lints &&
-        _equalLists(
-            newOptions.buildSummaryInputs, previous.buildSummaryInputs) &&
         newOptions.defaultLanguageVersion == previous.defaultLanguageVersion &&
         newOptions.disableCacheFlushing == previous.disableCacheFlushing &&
         _equalLists(newOptions.enabledExperiments, previous.enabledExperiments);
@@ -600,16 +562,6 @@
   }
 
   void _updateAnalysisOptions(AnalysisOptionsImpl analysisOptions) {
-    var args = _commandLineOptions.contextBuilderOptions.argResults;
-    applyAnalysisOptionFlags(analysisOptions, args);
-
-    var defaultLanguageVersion = _commandLineOptions.defaultLanguageVersion;
-    if (defaultLanguageVersion != null) {
-      var nonPackageLanguageVersion =
-          Version.parse('$defaultLanguageVersion.0');
-      analysisOptions.nonPackageLanguageVersion = nonPackageLanguageVersion;
-      analysisOptions.nonPackageFeatureSet = FeatureSet.latestLanguageVersion()
-          .restrictToVersion(nonPackageLanguageVersion);
-    }
+    _commandLineOptions.updateAnalysisOptions(analysisOptions);
   }
 }
diff --git a/pkg/analyzer_cli/lib/src/error_formatter.dart b/pkg/analyzer_cli/lib/src/error_formatter.dart
index a807955..2301bf0 100644
--- a/pkg/analyzer_cli/lib/src/error_formatter.dart
+++ b/pkg/analyzer_cli/lib/src/error_formatter.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:convert';
+
 import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/error/error.dart';
 import 'package:analyzer/src/dart/analysis/driver_based_analysis_context.dart';
@@ -332,6 +334,87 @@
   }
 }
 
+class JsonErrorFormatter extends ErrorFormatter {
+  JsonErrorFormatter(
+      StringSink out, CommandLineOptions options, AnalysisStats stats,
+      {SeverityProcessor severityProcessor})
+      : super(out, options, stats, severityProcessor: severityProcessor);
+
+  @override
+  void flush() {}
+
+  @override
+  void formatError(
+      Map<AnalysisError, ErrorsResult> errorToLine, AnalysisError error) {
+    throw UnsupportedError('Cannot format a single error');
+  }
+
+  @override
+  void formatErrors(List<ErrorsResult> results) {
+    Map<String, dynamic> range(
+            Map<String, dynamic> start, Map<String, dynamic> end) =>
+        {
+          'start': start,
+          'end': end,
+        };
+
+    Map<String, dynamic> position(int offset, int line, int column) => {
+          'offset': offset,
+          'line': line,
+          'column': column,
+        };
+
+    Map<String, dynamic> location(
+        String filePath, int offset, int length, LineInfo lineInfo) {
+      var startLocation = lineInfo.getLocation(offset);
+      var startLine = startLocation.lineNumber;
+      var startColumn = startLocation.columnNumber;
+      var endLocation = lineInfo.getLocation(offset + length);
+      var endLine = endLocation.lineNumber;
+      var endColumn = endLocation.columnNumber;
+      return {
+        'file': filePath,
+        'range': range(position(offset, startLine, startColumn),
+            position(offset + length, endLine, endColumn)),
+      };
+    }
+
+    var diagnostics = <Map<String, dynamic>>[];
+    for (var result in results) {
+      var errors = result.errors;
+      var lineInfo = result.lineInfo;
+      for (var error in errors) {
+        var contextMessages = <Map<String, dynamic>>[];
+        for (var contextMessage in error.contextMessages) {
+          contextMessages.add({
+            'location': location(contextMessage.filePath, contextMessage.offset,
+                contextMessage.length, lineInfo),
+            'message': contextMessage.message,
+          });
+        }
+        var errorCode = error.errorCode;
+        var problemMessage = error.problemMessage;
+        var url = error.errorCode.url;
+        diagnostics.add({
+          'code': errorCode.name.toLowerCase(),
+          'severity': errorCode.errorSeverity.name,
+          'type': errorCode.type.name,
+          'location': location(problemMessage.filePath, problemMessage.offset,
+              problemMessage.length, lineInfo),
+          'problemMessage': problemMessage.message,
+          if (error.correction != null) 'correctionMessage': error.correction,
+          if (contextMessages.isNotEmpty) 'contextMessages': contextMessages,
+          if (url != null) 'documentation': url,
+        });
+      }
+    }
+    out.writeln(json.encode({
+      'version': 1,
+      'diagnostics': diagnostics,
+    }));
+  }
+}
+
 class MachineErrorFormatter extends ErrorFormatter {
   static final int _pipeCodeUnit = '|'.codeUnitAt(0);
   static final int _slashCodeUnit = '\\'.codeUnitAt(0);
diff --git a/pkg/analyzer_cli/lib/src/has_context_mixin.dart b/pkg/analyzer_cli/lib/src/has_context_mixin.dart
deleted file mode 100644
index 554deca..0000000
--- a/pkg/analyzer_cli/lib/src/has_context_mixin.dart
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:analyzer/error/error.dart';
-import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer_cli/src/context_cache.dart';
-import 'package:analyzer_cli/src/options.dart';
-
-abstract class HasContextMixin {
-  ContextCache get contextCache;
-  ResourceProvider get resourceProvider;
-
-  /// Based on the command line options, performantly get cached analysis
-  /// options for the context.
-  AnalysisOptionsImpl createAnalysisOptionsForCommandLineOptions(
-      CommandLineOptions options, String source) {
-    if (options.analysisOptionsFile != null) {
-      var file = resourceProvider.getFile(options.analysisOptionsFile);
-      if (!file.exists) {
-        printAndFail('Options file not found: ${options.analysisOptionsFile}',
-            exitCode: ErrorSeverity.ERROR.ordinal);
-      }
-    }
-
-    return getContextInfo(options, source).analysisOptions;
-  }
-
-  /// Based on the [CommandLineOptions], and a specific [Source] within those
-  /// options if any are specified, performantly get cached info about the
-  /// context.
-  ContextCacheEntry getContextInfo(CommandLineOptions options, String source) {
-    if (options.sourceFiles.isEmpty) {
-      return contextCache.forSource(resourceProvider.pathContext.current);
-    }
-
-    return contextCache.forSource(source);
-  }
-}
diff --git a/pkg/analyzer_cli/lib/src/options.dart b/pkg/analyzer_cli/lib/src/options.dart
index faba081..bb2da44 100644
--- a/pkg/analyzer_cli/lib/src/options.dart
+++ b/pkg/analyzer_cli/lib/src/options.dart
@@ -4,18 +4,30 @@
 
 import 'dart:io' as io;
 
+import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/file_system/physical_file_system.dart';
-import 'package:analyzer/src/command_line/arguments.dart';
 import 'package:analyzer/src/context/builder.dart';
 import 'package:analyzer/src/dart/analysis/experiments.dart';
+import 'package:analyzer/src/generated/engine.dart' show AnalysisOptionsImpl;
 import 'package:analyzer/src/util/file_paths.dart' as file_paths;
 import 'package:analyzer/src/util/sdk.dart';
 import 'package:analyzer_cli/src/ansi.dart' as ansi;
 import 'package:analyzer_cli/src/driver.dart';
 import 'package:args/args.dart';
+import 'package:pub_semver/pub_semver.dart';
 
+const _analysisOptionsFileOption = 'options';
 const _binaryName = 'dartanalyzer';
+const _defaultLanguageVersionOption = 'default-language-version';
+const _defineVariableOption = 'D';
+const _enableExperimentOption = 'enable-experiment';
+const _enableInitializingFormalAccessFlag = 'initializing-formal-access';
+const _ignoreUnrecognizedFlagsFlag = 'ignore-unrecognized-flags';
+const _implicitCastsFlag = 'implicit-casts';
+const _lintsFlag = 'lints';
+const _noImplicitDynamicFlag = 'no-implicit-dynamic';
+const _packagesOption = 'packages';
+const _sdkPathOption = 'dart-sdk';
 
 /// Shared exit handler.
 ///
@@ -37,30 +49,7 @@
 
 /// Analyzer commandline configuration options.
 class CommandLineOptions {
-  /// The path to output analysis results when in build mode.
-  final String buildAnalysisOutput;
-
-  /// Whether to use build mode.
-  final bool buildMode;
-
-  /// Whether to use build mode as a Bazel persistent worker.
-  final bool buildModePersistentWorker;
-
-  /// List of summary file paths to use in build mode.
-  final List<String> buildSummaryInputs;
-
-  /// Whether to skip analysis when creating summaries in build mode.
-  final bool buildSummaryOnly;
-
-  /// The path to output the summary when creating summaries in build mode.
-  final String buildSummaryOutput;
-
-  /// The path to output the semantic-only summary when creating summaries in
-  /// build mode.
-  final String buildSummaryOutputSemantic;
-
-  /// Whether to suppress a nonzero exit code in build mode.
-  final bool buildSuppressExitCode;
+  final ArgResults _argResults;
 
   /// The options defining the context in which analysis is performed.
   final ContextBuilderOptions contextBuilderOptions;
@@ -68,13 +57,6 @@
   /// The path to the dart SDK.
   String dartSdkPath;
 
-  /// The path to the dart SDK summary file.
-  final String dartSdkSummaryPath;
-
-  /// The default language version for files that are not in a package.
-  /// (Or null if no default language version to force.)
-  final String defaultLanguageVersion;
-
   /// Whether to disable cache flushing. This option can improve analysis
   /// speed at the expense of memory usage. It may also be useful for working
   /// around bugs.
@@ -86,19 +68,16 @@
   /// Whether to display version information
   final bool displayVersion;
 
-  /// A list of the names of the experiments that are to be enabled.
-  final List<String> enabledExperiments;
-
   /// Whether to ignore unrecognized flags
   final bool ignoreUnrecognizedFlags;
 
-  /// Whether to report lints
-  final bool lints;
-
   /// Whether to log additional analysis messages and exceptions
   final bool log;
 
-  /// Whether to use machine format for error display
+  /// Whether to use 'json' format for error display
+  final bool jsonFormat;
+
+  /// Whether to use 'machine' format for error display
   final bool machineFormat;
 
   /// The path to a file to write a performance log.
@@ -118,7 +97,7 @@
   final bool showSdkWarnings;
 
   /// The source files to analyze
-  List<String> _sourceFiles;
+  final List<String> sourceFiles;
 
   /// Whether to treat warnings as fatal
   final bool warningsAreFatal;
@@ -140,39 +119,22 @@
   /// Dart analyzer snapshot.
   final bool trainSnapshot;
 
-  /// Path to a file to dump summary dependency information to for any given
-  /// build.
-  final String summaryDepsOutput;
-
   /// Initialize options from the given parsed [args].
   CommandLineOptions._fromArgs(
     ResourceProvider resourceProvider,
     ArgResults args,
-  )   : buildAnalysisOutput = cast(args['build-analysis-output']),
-        buildMode = cast(args['build-mode']),
-        buildModePersistentWorker = cast(args['persistent_worker']),
-        buildSummaryInputs =
-            (args['build-summary-input'] as List).cast<String>(),
-        buildSummaryOnly = cast(args['build-summary-only']),
-        buildSummaryOutput = cast(args['build-summary-output']),
-        buildSummaryOutputSemantic =
-            cast(args['build-summary-output-semantic']),
-        buildSuppressExitCode = cast(args['build-suppress-exit-code']),
-        contextBuilderOptions = createContextBuilderOptions(
+  )   : _argResults = args,
+        contextBuilderOptions = _createContextBuilderOptions(
           resourceProvider,
           args,
         ),
-        dartSdkPath = cast(args['dart-sdk']),
-        dartSdkSummaryPath = cast(args['dart-sdk-summary']),
-        defaultLanguageVersion = cast(args['default-language-version']),
+        dartSdkPath = cast(args[_sdkPathOption]),
         disableCacheFlushing = cast(args['disable-cache-flushing']),
         disableHints = cast(args['no-hints']),
         displayVersion = cast(args['version']),
-        enabledExperiments =
-            cast(args['enable-experiment'] ?? const <String>[]),
-        ignoreUnrecognizedFlags = cast(args['ignore-unrecognized-flags']),
-        lints = cast(args[lintsFlag]),
+        ignoreUnrecognizedFlags = cast(args[_ignoreUnrecognizedFlagsFlag]),
         log = cast(args['log']),
+        jsonFormat = args['format'] == 'json',
         machineFormat = args['format'] == 'machine',
         perfReport = cast(args['x-perf-report']),
         batchMode = cast(args['batch']),
@@ -181,32 +143,133 @@
             args['x-package-warnings-prefix'] != null,
         showPackageWarningsPrefix = cast(args['x-package-warnings-prefix']),
         showSdkWarnings = cast(args['sdk-warnings']),
-        _sourceFiles = args.rest,
+        sourceFiles = args.rest,
         infosAreFatal = cast(args['fatal-infos']) || cast(args['fatal-hints']),
         warningsAreFatal = cast(args['fatal-warnings']),
         lintsAreFatal = cast(args['fatal-lints']),
         trainSnapshot = cast(args['train-snapshot']),
         verbose = cast(args['verbose']),
-        color = cast(args['color']),
-        summaryDepsOutput = cast(args['summary-deps-output']);
+        color = cast(args['color']);
 
   /// The path to an analysis options file
   String get analysisOptionsFile =>
       contextBuilderOptions.defaultAnalysisOptionsFilePath;
 
+  /// The default language version for files that are not in a package.
+  /// (Or null if no default language version to force.)
+  String get defaultLanguageVersion {
+    return cast(_argResults[_defaultLanguageVersionOption]);
+  }
+
   /// A table mapping the names of defined variables to their values.
   Map<String, String> get definedVariables =>
       contextBuilderOptions.declaredVariables;
 
+  /// A list of the names of the experiments that are to be enabled.
+  List<String> get enabledExperiments {
+    return cast(_argResults[_enableExperimentOption]);
+  }
+
+  bool get implicitCasts => _argResults[_implicitCastsFlag] as bool;
+
+  bool get lints => _argResults[_lintsFlag] as bool;
+
+  bool get noImplicitDynamic => _argResults[_noImplicitDynamicFlag] as bool;
+
   /// The path to a `.packages` configuration file
   String get packageConfigPath => contextBuilderOptions.defaultPackageFilePath;
 
-  /// The source files to analyze
-  List<String> get sourceFiles => _sourceFiles;
+  /// Update the [analysisOptions] with flags that the user specified
+  /// explicitly. The [analysisOptions] are usually loaded from one of
+  /// `analysis_options.yaml` files, possibly with includes. We consider
+  /// flags that the user specified as command line options more important,
+  /// so override the corresponding options.
+  void updateAnalysisOptions(AnalysisOptionsImpl analysisOptions) {
+    var defaultLanguageVersion = this.defaultLanguageVersion;
+    if (defaultLanguageVersion != null) {
+      var nonPackageLanguageVersion =
+          Version.parse('$defaultLanguageVersion.0');
+      analysisOptions.nonPackageLanguageVersion = nonPackageLanguageVersion;
+      analysisOptions.nonPackageFeatureSet = FeatureSet.latestLanguageVersion()
+          .restrictToVersion(nonPackageLanguageVersion);
+    }
 
-  /// Replace the sourceFiles parsed from the command line.
-  void rewriteSourceFiles(List<String> newSourceFiles) {
-    _sourceFiles = newSourceFiles;
+    var enabledExperiments = this.enabledExperiments;
+    if (enabledExperiments.isNotEmpty) {
+      analysisOptions.contextFeatures = FeatureSet.fromEnableFlags2(
+        sdkLanguageVersion: ExperimentStatus.currentVersion,
+        flags: enabledExperiments,
+      );
+    }
+
+    var implicitCasts = this.implicitCasts;
+    if (implicitCasts != null) {
+      analysisOptions.implicitCasts = implicitCasts;
+    }
+
+    var lints = this.lints;
+    if (lints != null) {
+      analysisOptions.lint = lints;
+    }
+
+    var noImplicitDynamic = this.noImplicitDynamic;
+    if (noImplicitDynamic != null) {
+      analysisOptions.implicitDynamic = !noImplicitDynamic;
+    }
+  }
+
+  /// Return a list of command-line arguments containing all of the given [args]
+  /// that are defined by the given [parser]. An argument is considered to be
+  /// defined by the parser if
+  /// - it starts with '--' and the rest of the argument (minus any value
+  ///   introduced by '=') is the name of a known option,
+  /// - it starts with '-' and the rest of the argument (minus any value
+  ///   introduced by '=') is the name of a known abbreviation, or
+  /// - it starts with something other than '--' or '-'.
+  ///
+  /// This function allows command-line tools to implement the
+  /// '--ignore-unrecognized-flags' option.
+  static List<String> filterUnknownArguments(
+      List<String> args, ArgParser parser) {
+    var knownOptions = <String>{};
+    var knownAbbreviations = <String>{};
+    parser.options.forEach((String name, Option option) {
+      knownOptions.add(name);
+      var abbreviation = option.abbr;
+      if (abbreviation != null) {
+        knownAbbreviations.add(abbreviation);
+      }
+      if (option.negatable ?? false) {
+        knownOptions.add('no-$name');
+      }
+    });
+    String optionName(int prefixLength, String argument) {
+      var equalsOffset = argument.lastIndexOf('=');
+      if (equalsOffset < 0) {
+        return argument.substring(prefixLength);
+      }
+      return argument.substring(prefixLength, equalsOffset);
+    }
+
+    var filtered = <String>[];
+    for (var i = 0; i < args.length; i++) {
+      var argument = args[i];
+      if (argument.startsWith('--') && argument.length > 2) {
+        if (knownOptions.contains(optionName(2, argument))) {
+          filtered.add(argument);
+        }
+      } else if (argument.startsWith('-D') && argument.indexOf('=') > 0) {
+        filtered.add(argument);
+      }
+      if (argument.startsWith('-') && argument.length > 1) {
+        if (knownAbbreviations.contains(optionName(1, argument))) {
+          filtered.add(argument);
+        }
+      } else {
+        filtered.add(argument);
+      }
+    }
+    return filtered;
   }
 
   /// Parse [args] into [CommandLineOptions] describing the specified
@@ -223,7 +286,7 @@
     }
 
     // Check SDK.
-    if (!options.buildModePersistentWorker) {
+    {
       var sdkPath = options.dartSdkPath;
 
       // Check that SDK is existing directory.
@@ -241,30 +304,124 @@
       options.dartSdkPath = file_paths.absoluteNormalized(pathContext, sdkPath);
     }
 
-    // Build mode.
-    if (options.buildMode) {
-      if (options.dartSdkSummaryPath == null) {
-        // It is OK to not specify when persistent worker.
-        // We will be given another set of options with each request.
-        if (!options.buildModePersistentWorker) {
-          printAndFail(
-            'The option --build-mode also requires --dart-sdk-summary '
-            'to be specified.',
-          );
-          return null; // Only reachable in testing.
-        }
+    return options;
+  }
+
+  /// Use the command-line [args] to create a context builder options.
+  static ContextBuilderOptions _createContextBuilderOptions(
+    ResourceProvider resourceProvider,
+    ArgResults args,
+  ) {
+    String absoluteNormalizedPath(String path) {
+      if (path == null) {
+        return null;
       }
-    } else {
-      if (options.buildModePersistentWorker) {
-        printAndFail(
-          'The option --persistent_worker can be used only '
-          'together with --build-mode.',
-        );
-        return null; // Only reachable in testing.
-      }
+      var pathContext = resourceProvider.pathContext;
+      return pathContext.normalize(
+        pathContext.absolute(path),
+      );
     }
 
-    return options;
+    var builderOptions = ContextBuilderOptions();
+
+    //
+    // File locations.
+    //
+    builderOptions.defaultAnalysisOptionsFilePath = absoluteNormalizedPath(
+      cast(args[_analysisOptionsFileOption]),
+    );
+    builderOptions.defaultPackageFilePath = absoluteNormalizedPath(
+      cast(args[_packagesOption]),
+    );
+    //
+    // Declared variables.
+    //
+    var declaredVariables = <String, String>{};
+    var variables = (args[_defineVariableOption] as List).cast<String>();
+    for (var variable in variables) {
+      var index = variable.indexOf('=');
+      if (index < 0) {
+        // TODO (brianwilkerson) Decide the semantics we want in this case.
+        // The VM prints "No value given to -D option", then tries to load '-Dfoo'
+        // as a file and dies. Unless there was nothing after the '-D', in which
+        // case it prints the warning and ignores the option.
+      } else {
+        var name = variable.substring(0, index);
+        if (name.isNotEmpty) {
+          // TODO (brianwilkerson) Decide the semantics we want in the case where
+          // there is no name. If there is no name, the VM tries to load a file
+          // named '-D' and dies.
+          declaredVariables[name] = variable.substring(index + 1);
+        }
+      }
+    }
+    builderOptions.declaredVariables = declaredVariables;
+
+    return builderOptions;
+  }
+
+  /// 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.
+  ///
+  /// TODO(danrubel) Update DDC to support all the options defined in this method
+  /// then remove the [ddc] named argument from this method.
+  static void _defineAnalysisArguments(ArgParser parser,
+      {bool hide = true, bool ddc = false}) {
+    parser.addOption(_sdkPathOption,
+        help: 'The path to the Dart SDK.', hide: ddc && hide);
+    parser.addOption(_analysisOptionsFileOption,
+        help: 'Path to an analysis options file.', hide: ddc && hide);
+    parser.addFlag('strong',
+        help: 'Enable strong mode (deprecated); this option is now ignored.',
+        defaultsTo: true,
+        hide: true,
+        negatable: true);
+    parser.addFlag('declaration-casts',
+        negatable: true,
+        help:
+            'Disable declaration casts in strong mode (https://goo.gl/cTLz40)\n'
+            'This option is now ignored and will be removed in a future release.',
+        hide: ddc && hide);
+    parser.addMultiOption(_enableExperimentOption,
+        help: 'Enable one or more experimental features. If multiple features '
+            'are being added, they should be comma separated.',
+        splitCommas: true);
+    parser.addFlag(_implicitCastsFlag,
+        negatable: true,
+        help: 'Disable implicit casts in strong mode (https://goo.gl/cTLz40).',
+        defaultsTo: null,
+        hide: ddc && hide);
+    parser.addFlag(_noImplicitDynamicFlag,
+        defaultsTo: null,
+        negatable: false,
+        help: 'Disable implicit dynamic (https://goo.gl/m0UgXD).',
+        hide: ddc && hide);
+
+    //
+    // Hidden flags and options.
+    //
+    parser.addMultiOption(_defineVariableOption,
+        abbr: 'D',
+        help:
+            'Define an environment declaration. For example, "-Dfoo=bar" defines '
+            'an environment declaration named "foo" whose value is "bar".',
+        hide: hide);
+    parser.addOption(_packagesOption,
+        help: 'The path to the package resolution configuration file, which '
+            'supplies a mapping of package names\nto paths.',
+        hide: ddc);
+    parser.addFlag(_enableInitializingFormalAccessFlag,
+        help:
+            'Enable support for allowing access to field formal parameters in a '
+            'constructor\'s initializer list (deprecated).',
+        defaultsTo: false,
+        negatable: false,
+        hide: hide || ddc);
+    if (!ddc) {
+      parser.addFlag(_lintsFlag,
+          help: 'Show lint results.', defaultsTo: null, negatable: true);
+    }
   }
 
   static String _getVersion() {
@@ -284,8 +441,6 @@
     ResourceProvider resourceProvider,
     List<String> args,
   ) {
-    args = preprocessArgs(PhysicalResourceProvider.INSTANCE, args);
-
     var verbose = args.contains('-v') || args.contains('--verbose');
     var hide = !verbose;
 
@@ -298,12 +453,12 @@
     // TODO(devoncarew): This defines some hidden flags, which would be better
     // defined with the rest of the hidden flags below (to group well with the
     // other flags).
-    defineAnalysisArguments(parser, hide: hide);
+    _defineAnalysisArguments(parser, hide: hide);
 
     parser
       ..addOption('format',
           help: 'Specifies the format in which errors are displayed; the only '
-              'currently allowed value is \'machine\'.')
+              'currently recognized values are \'json\' and \'machine\'.')
       ..addFlag('version',
           help: 'Print the analyzer version.',
           defaultsTo: false,
@@ -330,56 +485,10 @@
           help: 'Verbose output.',
           negatable: false);
 
-    // Build mode options.
-    if (!hide) {
-      parser.addSeparator('Build mode flags:');
-    }
-
-    parser
-      ..addFlag('persistent_worker',
-          help: 'Enable Bazel persistent worker mode.',
-          defaultsTo: false,
-          negatable: false,
-          hide: hide)
-      ..addOption('build-analysis-output',
-          help: 'Specifies the path to the file where analysis results should '
-              'be written.',
-          hide: hide)
-      ..addFlag('build-mode',
-          help: 'Run in build mode; '
-              'this is used to generate analyzer summaries for build systems.',
-          defaultsTo: false,
-          negatable: false,
-          hide: hide)
-      ..addMultiOption('build-summary-input',
-          help: 'Path to a linked summary file that contains information from '
-              'a previous analysis run; may be specified multiple times.',
-          hide: hide)
-      ..addOption('build-summary-output',
-          help: 'Specifies the path to the file where the full summary '
-              'information should be written.',
-          hide: hide)
-      ..addOption('build-summary-output-semantic',
-          help: 'Specifies the path to the file where the semantic summary '
-              'information should be written.',
-          hide: hide)
-      ..addFlag('build-summary-only',
-          help: 'Disable analysis (only generate summaries).',
-          defaultsTo: false,
-          negatable: false,
-          hide: hide)
-      ..addFlag('build-suppress-exit-code',
-          help: 'Exit with code 0 even if errors are found.',
-          defaultsTo: false,
-          negatable: false,
-          hide: hide)
-      ..addFlag('color',
-          help: 'Use ansi colors when printing messages.',
-          defaultsTo: ansi.terminalSupportsAnsi(),
-          hide: hide)
-      ..addOption('summary-deps-output',
-          help: 'Path to a file to dump summary dependency info to.',
-          hide: hide);
+    parser.addFlag('color',
+        help: 'Use ansi colors when printing messages.',
+        defaultsTo: ansi.terminalSupportsAnsi(),
+        hide: hide);
 
     // Hidden flags.
     if (!hide) {
@@ -392,12 +501,12 @@
           defaultsTo: false,
           negatable: false,
           hide: hide)
-      ..addFlag(ignoreUnrecognizedFlagsFlag,
+      ..addFlag(_ignoreUnrecognizedFlagsFlag,
           help: 'Ignore unrecognized command line flags.',
           defaultsTo: false,
           negatable: false,
           hide: hide)
-      ..addOption('default-language-version',
+      ..addOption(_defaultLanguageVersionOption,
           help: 'The default language version when it is not specified via '
               'other ways (internal, tests only).',
           hide: false)
@@ -468,26 +577,11 @@
           negatable: false);
 
     try {
-      if (args.contains('--$ignoreUnrecognizedFlagsFlag')) {
+      if (args.contains('--$_ignoreUnrecognizedFlagsFlag')) {
         args = filterUnknownArguments(args, parser);
       }
       var results = parser.parse(args);
 
-      // Persistent worker.
-      if (args.contains('--persistent_worker')) {
-        var hasBuildMode = args.contains('--build-mode');
-        var onlyDartSdkArg = args.length == 2 ||
-            (args.length == 3 && args.any((a) => a.startsWith('--dart-sdk'))) ||
-            (args.length == 4 && args.contains('--dart-sdk'));
-        if (!(hasBuildMode && onlyDartSdkArg)) {
-          printAndFail('The --persistent_worker flag should be used with and '
-              'only with the --build-mode flag, and possibly the --dart-sdk '
-              'option. Got: $args');
-          return null; // Only reachable in testing.
-        }
-        return CommandLineOptions._fromArgs(resourceProvider, results);
-      }
-
       // Help requests.
       if (cast(results['help'])) {
         _showUsage(parser, fromHelp: true);
@@ -503,20 +597,12 @@
           exitHandler(15);
           return null; // Only reachable in testing.
         }
-      } else if (cast(results['persistent_worker'])) {
-        if (results.rest.isNotEmpty) {
-          errorSink.writeln(
-              'No source files expected in the persistent worker mode.');
-          _showUsage(parser);
-          exitHandler(15);
-          return null; // Only reachable in testing.
-        }
       } else if (cast(results['version'])) {
         outSink.writeln('$_binaryName version ${_getVersion()}');
         exitHandler(0);
         return null; // Only reachable in testing.
       } else {
-        if (results.rest.isEmpty && !cast<bool>(results['build-mode'])) {
+        if (results.rest.isEmpty) {
           _showUsage(parser, fromHelp: true);
           exitHandler(15);
           return null; // Only reachable in testing.
@@ -528,9 +614,9 @@
             'Note: the --strong flag is deprecated and will be removed in an '
             'future release.\n');
       }
-      if (results.wasParsed('enable-experiment')) {
+      if (results.wasParsed(_enableExperimentOption)) {
         var names =
-            (results['enable-experiment'] as List).cast<String>().toList();
+            (results[_enableExperimentOption] as List).cast<String>().toList();
         var errorFound = false;
         for (var validationResult in validateFlags(names)) {
           if (validationResult.isError) {
diff --git a/pkg/analyzer_cli/lib/starter.dart b/pkg/analyzer_cli/lib/starter.dart
index ad8e268..4f04f28 100644
--- a/pkg/analyzer_cli/lib/starter.dart
+++ b/pkg/analyzer_cli/lib/starter.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'dart:isolate';
-
 import 'package:analyzer_cli/src/driver.dart';
 
 /// An object that can be used to start a command-line analysis. This class
@@ -16,8 +14,5 @@
   factory CommandLineStarter() = Driver;
 
   /// Use the given command-line [arguments] to start this analyzer.
-  ///
-  /// If [sendPort] is provided it is used for bazel worker communication
-  /// instead of stdin/stdout.
-  Future<void> start(List<String> arguments, {SendPort sendPort});
+  Future<void> start(List<String> arguments);
 }
diff --git a/pkg/analyzer_cli/pubspec.yaml b/pkg/analyzer_cli/pubspec.yaml
index da7989b..9ad9601 100644
--- a/pkg/analyzer_cli/pubspec.yaml
+++ b/pkg/analyzer_cli/pubspec.yaml
@@ -11,9 +11,6 @@
   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:
     path: ../meta
@@ -23,6 +20,5 @@
 
 dev_dependencies:
   pedantic: ^1.9.0
-  protobuf: ^0.13.0
   test_reflective_loader: ^0.1.8
   test: ^1.0.0
diff --git a/pkg/analyzer_cli/test/all.dart b/pkg/analyzer_cli/test/all.dart
index 55beb94..c56ee1b 100644
--- a/pkg/analyzer_cli/test/all.dart
+++ b/pkg/analyzer_cli/test/all.dart
@@ -3,7 +3,6 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'analysis_options_test.dart' as analysis_options;
-import 'build_mode_test.dart' as build_mode;
 import 'driver_test.dart' as driver;
 import 'embedder_test.dart' as embedder;
 import 'errors_reported_once_test.dart' as errors_reported_once;
@@ -16,7 +15,6 @@
 
 void main() {
   analysis_options.main();
-  build_mode.main();
   driver.main();
   embedder.main();
   errors_reported_once.main();
diff --git a/pkg/analyzer_cli/test/build_mode_test.dart b/pkg/analyzer_cli/test/build_mode_test.dart
deleted file mode 100644
index 5027e1f..0000000
--- a/pkg/analyzer_cli/test/build_mode_test.dart
+++ /dev/null
@@ -1,139 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:analyzer/file_system/memory_file_system.dart';
-import 'package:analyzer_cli/src/build_mode.dart';
-import 'package:analyzer_cli/src/driver.dart';
-import 'package:analyzer_cli/src/options.dart';
-import 'package:bazel_worker/bazel_worker.dart';
-import 'package:bazel_worker/testing.dart';
-import 'package:protobuf/protobuf.dart';
-import 'package:test/test.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-void main() {
-  defineReflectiveTests(WorkerLoopTest);
-}
-
-typedef _TestWorkerLoopAnalyze = void Function(CommandLineOptions options);
-
-/// [AnalyzerWorkerLoop] for testing.
-class TestAnalyzerWorkerLoop extends AnalyzerWorkerLoop {
-  final _TestWorkerLoopAnalyze _analyze;
-
-  TestAnalyzerWorkerLoop(AsyncWorkerConnection connection, [this._analyze])
-      : super(MemoryResourceProvider(), connection);
-
-  @override
-  Future<void> analyze(
-      CommandLineOptions options, Map<String, WorkerInput> inputs) async {
-    if (_analyze != null) {
-      _analyze(options);
-    }
-  }
-}
-
-@reflectiveTest
-class WorkerLoopTest {
-  final TestStdinAsync stdinStream = TestStdinAsync();
-  final TestStdoutStream stdoutStream = TestStdoutStream();
-  TestAsyncWorkerConnection connection;
-
-  WorkerLoopTest() {
-    connection = TestAsyncWorkerConnection(stdinStream, stdoutStream);
-  }
-
-  void setUp() {}
-
-  Future<void> test_run() async {
-    var request = WorkRequest();
-    request.arguments.addAll([
-      '--build-summary-input=/tmp/1.sum',
-      '--build-summary-input=/tmp/2.sum',
-      'package:foo/foo.dart|/inputs/foo/lib/foo.dart',
-      'package:foo/bar.dart|/inputs/foo/lib/bar.dart',
-    ]);
-    stdinStream.addInputBytes(_serializeProto(request));
-    stdinStream.close();
-
-    await TestAnalyzerWorkerLoop(connection, (CommandLineOptions options) {
-      expect(options.buildSummaryInputs,
-          unorderedEquals(['/tmp/1.sum', '/tmp/2.sum']));
-      expect(
-          options.sourceFiles,
-          unorderedEquals([
-            'package:foo/foo.dart|/inputs/foo/lib/foo.dart',
-            'package:foo/bar.dart|/inputs/foo/lib/bar.dart'
-          ]));
-      outSink.writeln('outSink a');
-      errorSink.writeln('errorSink a');
-      outSink.writeln('outSink b');
-      errorSink.writeln('errorSink b');
-    }).run();
-    expect(connection.responses, hasLength(1));
-
-    var response = connection.responses[0];
-    expect(response.exitCode, EXIT_CODE_OK, reason: response.output);
-    expect(
-        response.output,
-        allOf(contains('errorSink a'), contains('errorSink a'),
-            contains('outSink a'), contains('outSink b')));
-
-    // Check that a serialized version was written to std out.
-    expect(stdoutStream.writes, hasLength(1));
-    expect(stdoutStream.writes[0], _serializeProto(response));
-  }
-
-  Future<void> test_run_invalidOptions() async {
-    var request = WorkRequest();
-    request.arguments.addAll(['--unknown-option', '/foo.dart', '/bar.dart']);
-    stdinStream.addInputBytes(_serializeProto(request));
-    stdinStream.close();
-    await TestAnalyzerWorkerLoop(connection).run();
-    expect(connection.responses, hasLength(1));
-
-    var response = connection.responses[0];
-    expect(response.exitCode, EXIT_CODE_ERROR);
-    expect(response.output, anything);
-  }
-
-  Future<void> test_run_invalidRequest_noArgumentsInputs() async {
-    stdinStream.addInputBytes(_serializeProto(WorkRequest()));
-    stdinStream.close();
-
-    await TestAnalyzerWorkerLoop(connection).run();
-    expect(connection.responses, hasLength(1));
-
-    var response = connection.responses[0];
-    expect(response.exitCode, EXIT_CODE_ERROR);
-    expect(response.output, anything);
-  }
-
-  Future<void> test_run_invalidRequest_randomBytes() async {
-    stdinStream.addInputBytes([1, 2, 3]);
-    stdinStream.close();
-    await TestAnalyzerWorkerLoop(connection).run();
-    expect(connection.responses, hasLength(1));
-
-    var response = connection.responses[0];
-    expect(response.exitCode, EXIT_CODE_ERROR);
-    expect(response.output, anything);
-  }
-
-  Future<void> test_run_stopAtEOF() async {
-    stdinStream.close();
-    await TestAnalyzerWorkerLoop(connection).run();
-  }
-
-  List<int> _serializeProto(GeneratedMessage message) {
-    var buffer = message.writeToBuffer();
-    var writer = CodedBufferWriter();
-    writer.writeInt32NoTag(buffer.length);
-
-    var result = <int>[];
-    result.addAll(writer.toBuffer());
-    result.addAll(buffer);
-    return result;
-  }
-}
diff --git a/pkg/analyzer_cli/test/driver_test.dart b/pkg/analyzer_cli/test/driver_test.dart
index 6d818d6..d2a575b 100644
--- a/pkg/analyzer_cli/test/driver_test.dart
+++ b/pkg/analyzer_cli/test/driver_test.dart
@@ -10,7 +10,6 @@
 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/summary2/package_bundle_format.dart';
 import 'package:analyzer/src/util/file_paths.dart' as file_paths;
 import 'package:analyzer/src/util/sdk.dart';
 import 'package:analyzer_cli/src/ansi.dart' as ansi;
@@ -25,8 +24,6 @@
 
 void main() {
   defineReflectiveSuite(() {
-    defineReflectiveTests(BuildModeTest);
-    defineReflectiveTests(BuildModeSummaryDependenciesTest);
     defineReflectiveTests(ExitCodesTest);
     defineReflectiveTests(LinterTest);
     defineReflectiveTests(NonDartFilesTest);
@@ -34,52 +31,6 @@
   }, name: 'Driver');
 }
 
-class AbstractBuildModeTest extends BaseTest {
-  List<String> get _sdkSummaryArguments {
-    var sdkPath = path.dirname(
-      path.dirname(
-        Platform.resolvedExecutable,
-      ),
-    );
-
-    var dartSdkSummaryPath = path.join(
-      sdkPath,
-      'lib',
-      '_internal',
-      'strong.sum',
-    );
-
-    return ['--dart-sdk-summary', dartSdkSummaryPath];
-  }
-
-  Future<void> _doDrive(
-    String filePath, {
-    String sourceArgument,
-    String fileUri,
-    List<String> additionalArgs = const [],
-  }) async {
-    filePath = _posixToPlatformPath(filePath);
-
-    var options = _posixToPlatformPath(
-      'data/options_tests_project/' + file_paths.analysisOptionsYaml,
-    );
-
-    var args = <String>[];
-    args.add('--build-mode');
-    args.add('--format=machine');
-
-    args.addAll(_sdkSummaryArguments);
-    args.addAll(additionalArgs);
-
-    if (sourceArgument == null) {
-      fileUri ??= 'file:///test_file.dart';
-      sourceArgument = '$fileUri|$filePath';
-    }
-
-    await drive(sourceArgument, args: args, options: options);
-  }
-}
-
 class BaseTest {
   static const emptyOptionsFile = 'data/empty_options.yaml';
 
@@ -174,544 +125,6 @@
 }
 
 @reflectiveTest
-class BuildModeSummaryDependenciesTest extends AbstractBuildModeTest {
-  String tempDir;
-
-  /// Any direct export is a dependency.
-  Future<void> test_export_direct() async {
-    await _withTempDir(() async {
-      var a = await _buildPackage('a', [], 'class A {}');
-      await _assertDependencies('c', [a], '''
-export 'package:a/a.dart';
-''', [a]);
-    });
-  }
-
-  /// Imports of dependencies are not necessary dependencies.
-  /// Here our dependency does not use its dependency.
-  Future<void> test_import2_notUsed() async {
-    await _withTempDir(() async {
-      var a = await _buildPackage('a', [], '');
-      var b = await _buildPackage('b', [a], '''
-import 'package:a/a.dart';
-''');
-      await _assertDependencies('c', [a, b], '''
-import 'package:b/b.dart';
-''', [b]);
-    });
-  }
-
-  Future<void> test_import2_usedAsFieldType() async {
-    await _withTempDir(() async {
-      var a = await _buildPackage('a', [], 'class A {}');
-      var b = await _buildPackage('b', [a], '''
-import 'package:a/a.dart';
-class B {
-  A f;
-}
-''');
-
-      // We don't use `f`, so don't depend on "a".
-      await _assertDependencies('c', [a, b], '''
-import 'package:b/b.dart';
-var x = B();
-''', [b]);
-
-      // We use `f` for type inference.
-      // So, dependency on "a".
-      await _assertDependencies('c', [a, b], '''
-import 'package:b/b.dart';
-var x = B().f;
-''', [a, b]);
-
-      // We reference `f` in initializer, but not for type inference.
-      // So, no dependency on "a".
-      await _assertDependencies('c', [a, b], '''
-import 'package:b/b.dart';
-Object x = B().f;
-''', [b]);
-
-      // We perform full analysis, so request the type of `f`;
-      // So, dependency on "a".
-      await _assertDependencies(
-        'c',
-        [a, b],
-        '''
-import 'package:b/b.dart';
-Object x = B().f;
-''',
-        [a, b],
-        summaryOnly: false,
-      );
-    });
-  }
-
-  Future<void> test_import2_usedAsSupertype() async {
-    await _withTempDir(() async {
-      var a = await _buildPackage('a', [], 'class A {}');
-      var b = await _buildPackage('b', [], 'class B {}');
-      var c = await _buildPackage('c', [a], '''
-import 'package:a/a.dart';
-import 'package:b/b.dart';
-class C1 extends A {}
-class C2 extends B {}
-''');
-
-      // 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]);
-    });
-  }
-
-  Future<void> test_import2_usedAsTopLevelVariableType() async {
-    await _withTempDir(() async {
-      var a = await _buildPackage('a', [], 'class A {}');
-      var b = await _buildPackage('b', [a], '''
-import 'package:a/a.dart';
-A v;
-''');
-
-      // We don't use `v`.
-      // So, no dependency on "a".
-      await _assertDependencies('c', [a, b], '''
-import 'package:b/b.dart';
-''', [b]);
-
-      // We use `v` for type inference.
-      // So, dependency on "a".
-      await _assertDependencies('c', [a, b], '''
-import 'package:b/b.dart';
-var x = v;
-''', [a, b]);
-
-      // We don't use `v` for type inference.
-      // So, no dependency on "a".
-      await _assertDependencies('c', [a, b], '''
-import 'package:b/b.dart';
-Object x = v;
-''', [b]);
-
-      // We perform full analysis, and request the type of `v`.
-      // So, dependency on "a".
-      await _assertDependencies(
-        'c',
-        [a, b],
-        '''
-import 'package:b/b.dart';
-Object x = v;
-''',
-        [a, b],
-        summaryOnly: false,
-      );
-
-      // We use `v` in a method body.
-      // So, no dependency on "a".
-      await _assertDependencies('c', [a, b], '''
-import 'package:b/b.dart';
-main() {
-  v;
-}
-''', [b]);
-
-      // We perform full analysis, so ask for the type of `v`.
-      // So, dependency on "a".
-      await _assertDependencies(
-        'c',
-        [a, b],
-        '''
-import 'package:b/b.dart';
-main() {
-  v;
-}
-''',
-        [a, b],
-        summaryOnly: false,
-      );
-    });
-  }
-
-  /// Any direct import is a dependency.
-  Future<void> test_import_direct() async {
-    await _withTempDir(() async {
-      var a = await _buildPackage('a', [], '');
-      var b = await _buildPackage('b', [], '');
-      await _assertDependencies('c', [a, b], '''
-import 'package:a/a.dart';
-import 'package:b/b.dart';
-''', [a, b]);
-    });
-  }
-
-  /// Exports of dependencies are dependencies.
-  Future<void> test_import_export() async {
-    await _withTempDir(() async {
-      var a = await _buildPackage('a', [], 'class A {}');
-      var b = await _buildPackage('b', [a], '''
-export 'package:a/a.dart';
-''');
-      await _assertDependencies('c', [a, b], '''
-import 'package:b/b.dart';
-''', [a, b]);
-    });
-  }
-
-  Future<void> _assertDependencies(
-    String name,
-    List<_DependencyPackage> inputPackages,
-    String content,
-    List<_DependencyPackage> expectedPackages, {
-    bool summaryOnly = true,
-  }) async {
-    var pkg = await _buildPackage(name, inputPackages, content,
-        summaryOnly: summaryOnly);
-
-    var depString = File(pkg.dep).readAsStringSync();
-    var expectedList = expectedPackages.map((p) => p.sum).toList();
-    expect(depString.split('\n'), unorderedEquals(expectedList));
-  }
-
-  Future<_DependencyPackage> _buildPackage(
-    String name,
-    List<_DependencyPackage> inputPackages,
-    String content, {
-    bool summaryOnly = true,
-  }) async {
-    var filePath = path.join(tempDir, '$name.dart');
-    File(filePath).writeAsStringSync(content);
-    var pkg = _DependencyPackage(
-      name: name,
-      path: filePath,
-      uri: 'package:$name/$name.dart',
-      sum: path.join(tempDir, '$name.sum'),
-      dep: path.join(tempDir, '$name.dep'),
-    );
-
-    var args = <String>[];
-    if (summaryOnly) {
-      args.add('--build-summary-only');
-    }
-    for (var input in inputPackages) {
-      args.add('--build-summary-input=${input.sum}');
-    }
-    args.add('--build-summary-output=${pkg.sum}');
-    args.add('--summary-deps-output=${pkg.dep}');
-
-    await _doDrive(pkg.path, fileUri: pkg.uri, additionalArgs: args);
-    expect(exitCode, 0);
-
-    return pkg;
-  }
-
-  Future<void> _withTempDir(Future<void> Function() f) async {
-    await withTempDirAsync((tempDir) async {
-      this.tempDir = tempDir;
-      await f();
-    });
-  }
-}
-
-@reflectiveTest
-class BuildModeTest extends AbstractBuildModeTest {
-  Future<void> test_buildLinked() async {
-    await withTempDirAsync((tempDir) async {
-      var outputPath = path.join(tempDir, 'test_file.dart.sum');
-      await _doDrive(path.join('data', 'test_file.dart'), additionalArgs: [
-        '--build-summary-only',
-        '--build-summary-output=$outputPath'
-      ]);
-      var output = File(outputPath);
-      expect(output.existsSync(), isTrue);
-      var bundle = PackageBundleReader(await output.readAsBytes());
-      var testFileUri = 'file:///test_file.dart';
-
-      expect(_linkedLibraryUriList(bundle), [testFileUri]);
-      expect(
-        _linkedLibraryUnitUriList(bundle, testFileUri),
-        [testFileUri],
-      );
-
-      expect(exitCode, 0);
-    });
-  }
-
-  Future<void> test_buildLinked_invalidPartUri() async {
-    await withTempDirAsync((tempDir) async {
-      var aDart = path.join(tempDir, 'a.dart');
-
-      var aUri = 'package:aaa/a.dart';
-
-      var aSum = path.join(tempDir, 'a.sum');
-
-      File(aDart).writeAsStringSync('''
-part '[invalid]';
-''');
-
-      await _doDrive(aDart,
-          fileUri: aUri, additionalArgs: ['--build-summary-output=$aSum']);
-      expect(exitCode, ErrorSeverity.ERROR.ordinal);
-      var bytes = File(aSum).readAsBytesSync();
-      var bundle = PackageBundleReader(bytes);
-      expect(_linkedLibraryUriList(bundle), [aUri]);
-      expect(_linkedLibraryUnitUriList(bundle, aUri), [aUri]);
-    });
-  }
-
-  Future<void> test_buildSuppressExitCode_fail_whenFileNotFound() async {
-    await _doDrive(path.join('data', 'non_existent_file.dart'),
-        additionalArgs: ['--build-suppress-exit-code']);
-    expect(exitCode, isNot(0));
-  }
-
-  Future<void> test_buildSuppressExitCode_success_evenIfHasError() async {
-    await _doDrive(path.join('data', 'file_with_error.dart'),
-        additionalArgs: ['--build-suppress-exit-code']);
-    expect(exitCode, 0);
-  }
-
-  Future<void> test_consumeLinked() async {
-    await withTempDirAsync((tempDir) async {
-      var aDart = path.join(tempDir, 'a.dart');
-      var bDart = path.join(tempDir, 'b.dart');
-      var cDart = path.join(tempDir, 'c.dart');
-
-      var aUri = 'package:aaa/a.dart';
-      var bUri = 'package:bbb/b.dart';
-      var cUri = 'package:ccc/c.dart';
-
-      var aSum = path.join(tempDir, 'a.sum');
-      var bSum = path.join(tempDir, 'b.sum');
-      var cSum = path.join(tempDir, 'c.sum');
-
-      File(aDart).writeAsStringSync('class A {}');
-      File(bDart).writeAsStringSync('''
-export 'package:aaa/a.dart';
-class B {}
-''');
-      File(cDart).writeAsStringSync('''
-import 'package:bbb/b.dart';
-var a = new A();
-var b = new B();
-''');
-
-      // Analyze package:aaa/a.dart and compute summary.
-      {
-        await _doDrive(aDart,
-            fileUri: aUri, additionalArgs: ['--build-summary-output=$aSum']);
-        expect(exitCode, 0);
-        var bytes = File(aSum).readAsBytesSync();
-        var bundle = PackageBundleReader(bytes);
-        expect(_linkedLibraryUriList(bundle), [aUri]);
-        expect(_linkedLibraryUnitUriList(bundle, aUri), [aUri]);
-      }
-
-      // Analyze package:bbb/b.dart and compute summary.
-      {
-        await _doDrive(bDart, fileUri: bUri, additionalArgs: [
-          '--build-summary-input=$aSum',
-          '--build-summary-output=$bSum'
-        ]);
-        expect(exitCode, 0);
-        var bytes = File(bSum).readAsBytesSync();
-        var bundle = PackageBundleReader(bytes);
-        expect(_linkedLibraryUriList(bundle), [bUri]);
-        expect(_linkedLibraryUnitUriList(bundle, bUri), [bUri]);
-      }
-
-      // Analyze package:ccc/c.dart and compute summary.
-      {
-        await _doDrive(cDart, fileUri: cUri, additionalArgs: [
-          '--build-summary-input=$aSum,$bSum',
-          '--build-summary-output=$cSum'
-        ]);
-        expect(exitCode, 0);
-        var bytes = File(cSum).readAsBytesSync();
-        var bundle = PackageBundleReader(bytes);
-        expect(_linkedLibraryUriList(bundle), [cUri]);
-        expect(_linkedLibraryUnitUriList(bundle, cUri), [cUri]);
-      }
-    });
-  }
-
-  Future<void> test_error_notUriPipePath() async {
-    await withTempDirAsync((tempDir) async {
-      var testDart = path.join(tempDir, 'test.dart');
-      File(testDart).writeAsStringSync('var v = 42;');
-
-      // We pass just path, not "uri|path", this is a fatal error.
-      await _doDrive(
-        testDart,
-        additionalArgs: ['--build-mode', '--format=machine'],
-        sourceArgument: testDart,
-      );
-      expect(exitCode, ErrorSeverity.ERROR.ordinal);
-    });
-  }
-
-  Future<void> test_fail_whenHasError() async {
-    await _doDrive(path.join('data', 'file_with_error.dart'));
-    expect(exitCode, isNot(0));
-  }
-
-  Future<void> test_noInputs() async {
-    await withTempDirAsync((tempDir) async {
-      var outputPath = path.join(tempDir, 'test.sum');
-
-      await driveMany([], args: [
-        '--build-mode',
-        '--format=machine',
-        ..._sdkSummaryArguments,
-        '--build-summary-only',
-        '--build-summary-output=$outputPath',
-      ]);
-
-      var output = File(outputPath);
-      expect(output.existsSync(), isTrue);
-
-      expect(exitCode, 0);
-    });
-  }
-
-  Future<void> test_noStatistics() async {
-    await _doDrive(path.join('data', 'test_file.dart'));
-    // Should not print statistics summary.
-    expect(outSink.toString(), isEmpty);
-    expect(errorSink.toString(), isEmpty);
-    expect(exitCode, 0);
-  }
-
-  Future<void> test_onlyErrors_partFirst() async {
-    await withTempDirAsync((tempDir) async {
-      var aDart = path.join(tempDir, 'a.dart');
-      var bDart = path.join(tempDir, 'b.dart');
-
-      var aUri = 'package:aaa/a.dart';
-      var bUri = 'package:aaa/b.dart';
-
-      File(aDart).writeAsStringSync(r'''
-library lib;
-part 'b.dart';
-class A {}
-''');
-      File(bDart).writeAsStringSync('''
-part of lib;
-class B {}
-var a = new A();
-var b = new B();
-''');
-
-      // Analyze b.dart (part) and then a.dart (its library).
-      // No errors should be reported - the part should know its library.
-      await _doDrive(bDart, fileUri: bUri, additionalArgs: ['$aUri|$aDart']);
-      expect(errorSink, isEmpty);
-    });
-  }
-
-  Future<void> test_packageConfig_packagesOptions() async {
-    await withTempDirAsync((tempDir) async {
-      var packagesPath = path.join(tempDir, 'aaa.packages');
-
-      var aaaRoot = path.join(tempDir, 'packages', 'aaa');
-      var aPath = path.join(aaaRoot, 'lib', 'a.dart');
-
-      var aUri = 'package:aaa/a.dart';
-
-      File(packagesPath).createSync(recursive: true);
-      File(packagesPath).writeAsStringSync('''
-{
-  "configVersion": 2,
-  "packages": [
-    {
-      "name": "aaa",
-      "rootUri": "${path.toUri(aaaRoot)}",
-      "packageUri": "lib/",
-      "languageVersion": "2.4"
-    }
-  ]
-}
-''');
-
-      File(aPath).createSync(recursive: true);
-      File(aPath).writeAsStringSync(r'''
-extension E on int {}
-''');
-
-      // Analyze package:aaa/a.dart and compute errors.
-      await _doDrive(
-        aPath,
-        fileUri: aUri,
-        additionalArgs: [
-          '--packages=$packagesPath',
-        ],
-      );
-      expect(exitCode, ErrorSeverity.ERROR.ordinal);
-      expect(errorSink.toString(), contains('extension-methods'));
-    });
-  }
-
-  Future<void> test_packageConfig_relativeToFile() async {
-    await withTempDirAsync((tempDir) async {
-      var packagesPath = path.join(tempDir, '.dart_tool/package_config.json');
-
-      var aaaRoot = path.join(tempDir, 'packages', 'aaa');
-      var aPath = path.join(aaaRoot, 'lib', 'a.dart');
-
-      var aUri = 'package:aaa/a.dart';
-
-      File(packagesPath).createSync(recursive: true);
-      File(packagesPath).writeAsStringSync('''
-{
-  "configVersion": 2,
-  "packages": [
-    {
-      "name": "aaa",
-      "rootUri": "${path.toUri(aaaRoot)}",
-      "packageUri": "lib/",
-      "languageVersion": "2.4"
-    }
-  ]
-}
-''');
-
-      File(aPath).createSync(recursive: true);
-      File(aPath).writeAsStringSync(r'''
-extension E on int {}
-''');
-
-      // Analyze package:aaa/a.dart and compute errors.
-      await _doDrive(
-        aPath,
-        fileUri: aUri,
-        additionalArgs: [],
-      );
-      expect(exitCode, ErrorSeverity.ERROR.ordinal);
-      expect(errorSink.toString(), contains('extension-methods'));
-    });
-  }
-
-  Iterable<String> _linkedLibraryUnitUriList(
-    PackageBundleReader bundle,
-    String libraryUriStr,
-  ) {
-    var libraries = bundle.libraries;
-    var library = libraries.singleWhere((l) => l.uriStr == libraryUriStr);
-    return library.units.map((u) => u.uriStr).toList();
-  }
-
-  Iterable<String> _linkedLibraryUriList(PackageBundleReader bundle) {
-    var libraries = bundle.libraries;
-    return libraries.map((l) => l.uriStr).toList();
-  }
-}
-
-@reflectiveTest
 class ExitCodesTest extends BaseTest {
   @SkippedTest(reason: 'Fails on bots, passes locally. Do not know why.')
   Future<void> test_bazelWorkspace_relativePath() async {
@@ -1092,13 +505,3 @@
   @override
   dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
-
-class _DependencyPackage {
-  final String name;
-  final String path;
-  final String uri;
-  final String sum;
-  final String dep;
-
-  _DependencyPackage({this.name, this.path, this.uri, this.sum, this.dep});
-}
diff --git a/pkg/analyzer_cli/test/mocks.dart b/pkg/analyzer_cli/test/mocks.dart
index 219b110..918b2d6 100644
--- a/pkg/analyzer_cli/test/mocks.dart
+++ b/pkg/analyzer_cli/test/mocks.dart
@@ -5,6 +5,7 @@
 import 'package:analyzer/diagnostic/diagnostic.dart';
 import 'package:analyzer/error/error.dart';
 import 'package:analyzer/source/line_info.dart';
+import 'package:analyzer/src/diagnostic/diagnostic.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer_cli/src/options.dart';
@@ -23,7 +24,7 @@
   String message;
 
   @override
-  int length;
+  int length = 3;
 
   MockAnalysisError(this.source, this.errorCode, this.offset, this.message);
 
@@ -37,7 +38,11 @@
   String get correctionMessage => null;
 
   @override
-  DiagnosticMessage get problemMessage => null;
+  DiagnosticMessage get problemMessage => DiagnosticMessageImpl(
+      filePath: source.fullName,
+      length: length,
+      message: message,
+      offset: offset);
 
   @override
   Severity get severity => null;
@@ -58,6 +63,8 @@
   @override
   bool infosAreFatal = false;
   @override
+  bool jsonFormat = false;
+  @override
   bool machineFormat = false;
   @override
   bool verbose = false;
diff --git a/pkg/analyzer_cli/test/options_test.dart b/pkg/analyzer_cli/test/options_test.dart
index 12ff74c..242c86d 100644
--- a/pkg/analyzer_cli/test/options_test.dart
+++ b/pkg/analyzer_cli/test/options_test.dart
@@ -4,12 +4,17 @@
 
 import 'dart:io';
 
+import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/file_system/physical_file_system.dart';
 import 'package:analyzer/src/dart/analysis/experiments.dart';
 import 'package:analyzer/src/dart/analysis/experiments_impl.dart'
     show overrideKnownFeatures;
+import 'package:analyzer/src/generated/engine.dart' show AnalysisOptionsImpl;
+import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
 import 'package:analyzer_cli/src/driver.dart';
 import 'package:analyzer_cli/src/options.dart';
+import 'package:args/args.dart';
+import 'package:pub_semver/pub_semver.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -50,23 +55,19 @@
       test('defaults', () {
         var options = parse(['--dart-sdk', '.', 'foo.dart']);
         expect(options, isNotNull);
-        expect(options.buildMode, isFalse);
-        expect(options.buildAnalysisOutput, isNull);
-        expect(options.buildSummaryInputs, isEmpty);
-        expect(options.buildSummaryOnly, isFalse);
-        expect(options.buildSummaryOutput, isNull);
-        expect(options.buildSummaryOutputSemantic, isNull);
-        expect(options.buildSuppressExitCode, isFalse);
         expect(options.dartSdkPath, isNotNull);
         expect(options.disableCacheFlushing, isFalse);
         expect(options.disableHints, isFalse);
         expect(options.enabledExperiments, isEmpty);
-        expect(options.lints, isFalse);
+        expect(options.lints, isNull);
         expect(options.displayVersion, isFalse);
         expect(options.infosAreFatal, isFalse);
         expect(options.ignoreUnrecognizedFlags, isFalse);
+        expect(options.implicitCasts, isNull);
         expect(options.log, isFalse);
+        expect(options.jsonFormat, isFalse);
         expect(options.machineFormat, isFalse);
+        expect(options.noImplicitDynamic, isNull);
         expect(options.batchMode, isFalse);
         expect(options.showPackageWarnings, isFalse);
         expect(options.showSdkWarnings, isFalse);
@@ -186,10 +187,19 @@
         expect(options.log, isTrue);
       });
 
-      test('machine format', () {
-        var options =
-            parse(['--dart-sdk', '.', '--format=machine', 'foo.dart']);
-        expect(options.machineFormat, isTrue);
+      group('format', () {
+        test('json', () {
+          var options = parse(['--dart-sdk', '.', '--format=json', 'foo.dart']);
+          expect(options.jsonFormat, isTrue);
+          expect(options.machineFormat, isFalse);
+        });
+
+        test('machine', () {
+          var options =
+              parse(['--dart-sdk', '.', '--format=machine', 'foo.dart']);
+          expect(options.jsonFormat, isFalse);
+          expect(options.machineFormat, isTrue);
+        });
       });
 
       test('no-hints', () {
@@ -263,172 +273,308 @@
       });
     });
   });
-  defineReflectiveTests(CommandLineOptions_BuildMode_Test);
+  defineReflectiveTests(ArgumentsTest);
 }
 
 @reflectiveTest
-class AbstractStatusTest {
-  int lastExitHandlerCode;
-  StringBuffer outStringBuffer = StringBuffer();
-  StringBuffer errorStringBuffer = StringBuffer();
-
-  StringSink savedOutSink, savedErrorSink;
-  int savedExitCode;
-  ExitHandler savedExitHandler;
-
-  void setUp() {
-    savedOutSink = outSink;
-    savedErrorSink = errorSink;
-    savedExitHandler = exitHandler;
-    savedExitCode = exitCode;
-    exitHandler = (int code) {
-      lastExitHandlerCode = code;
-    };
-    outSink = outStringBuffer;
-    errorSink = errorStringBuffer;
-  }
-
-  void tearDown() {
-    outSink = savedOutSink;
-    errorSink = savedErrorSink;
-    exitCode = savedExitCode;
-    exitHandler = savedExitHandler;
-  }
-}
-
-@reflectiveTest
-class CommandLineOptions_BuildMode_Test extends AbstractStatusTest {
-  CommandLineOptions options;
+class ArgumentsTest with ResourceProviderMixin {
+  CommandLineOptions commandLineOptions;
   String failureMessage;
 
-  void test_buildAnalysisOutput() {
-    _parseBuildMode([
-      '--build-analysis-output=//path/to/output.analysis',
-      'package:p/foo.dart|/path/to/p/lib/foo.dart',
-    ]);
-    expect(options.buildMode, isTrue);
-    expect(options.buildAnalysisOutput, '//path/to/output.analysis');
+  void test_declaredVariables() {
+    _parse(['-Da=0', '-Db=', 'a.dart']);
+
+    var options = commandLineOptions.contextBuilderOptions;
+    var definedVariables = options.declaredVariables;
+
+    expect(definedVariables['a'], '0');
+    expect(definedVariables['b'], '');
+    expect(definedVariables['c'], isNull);
   }
 
-  void test_buildMode() {
-    _parseBuildMode([
-      'package:p/foo.dart|/path/to/p/lib/foo.dart',
-    ]);
-    expect(options.buildMode, isTrue);
-  }
+  void test_defaultAnalysisOptionsFilePath() {
+    var expected = 'my_options.yaml';
+    _parse(['--options=$expected', 'a.dart']);
 
-  void test_buildMode_allowsEmptyFileList() {
-    _parseBuildMode([]);
-    expect(options.buildMode, isTrue);
-    expect(options.sourceFiles, isEmpty);
-  }
-
-  void test_buildMode_noDartSdkSummary() {
-    _parseBuildMode(
-      ['package:aaa/a.dart|/aaa/lib/a.dart'],
-      withDartSdkSummary: false,
+    var builderOptions = commandLineOptions.contextBuilderOptions;
+    expect(
+      builderOptions.defaultAnalysisOptionsFilePath,
+      endsWith(expected),
     );
-    expect(options, isNull);
-    expect(failureMessage, contains('--dart-sdk-summary'));
   }
 
-  void test_buildSummaryInputs_commaSeparated() {
-    _parseBuildMode([
-      '--build-summary-input=/path/to/aaa.sum,/path/to/bbb.sum',
-      'package:p/foo.dart|/path/to/p/lib/foo.dart',
-    ]);
-    expect(options.buildMode, isTrue);
+  void test_defaultPackageFilePath() {
+    var expected = 'my_package_config.json';
+    _parse(['--packages=$expected', 'a.dart']);
+
+    var builderOptions = commandLineOptions.contextBuilderOptions;
     expect(
-        options.buildSummaryInputs, ['/path/to/aaa.sum', '/path/to/bbb.sum']);
+      builderOptions.defaultPackageFilePath,
+      endsWith(expected),
+    );
   }
 
-  void test_buildSummaryInputs_commaSeparated_normalMode() {
-    _parse([
-      '--build-summary-input=/path/to/aaa.sum,/path/to/bbb.sum',
-      '/path/to/p/lib/foo.dart',
-    ]);
-    expect(options.buildMode, isFalse);
+  void test_defaults() {
+    _parse(['a.dart']);
+    var builderOptions = commandLineOptions.contextBuilderOptions;
+    expect(builderOptions, isNotNull);
+    expect(builderOptions.dartSdkSummaryPath, isNull);
+    expect(builderOptions.declaredVariables, isEmpty);
+    expect(builderOptions.defaultAnalysisOptionsFilePath, isNull);
+    expect(builderOptions.defaultPackageFilePath, isNull);
+  }
+
+  void test_filterUnknownArguments() {
+    var args = ['--a', '--b', '--c=0', '--d=1', '-Da=b', '-e=2', '-f', 'bar'];
+    var parser = ArgParser();
+    parser.addFlag('a');
+    parser.addOption('c');
+    parser.addOption('ee', abbr: 'e');
+    parser.addFlag('ff', abbr: 'f');
+    var result = CommandLineOptions.filterUnknownArguments(args, parser);
     expect(
-        options.buildSummaryInputs, ['/path/to/aaa.sum', '/path/to/bbb.sum']);
+      result,
+      orderedEquals(['--a', '--c=0', '-Da=b', '-e=2', '-f', 'bar']),
+    );
   }
 
-  void test_buildSummaryInputs_separateFlags() {
-    _parseBuildMode([
-      '--build-summary-input=/path/to/aaa.sum',
-      '--build-summary-input=/path/to/bbb.sum',
-      'package:p/foo.dart|/path/to/p/lib/foo.dart',
-    ]);
-    expect(options.buildMode, isTrue);
-    expect(
-        options.buildSummaryInputs, ['/path/to/aaa.sum', '/path/to/bbb.sum']);
+  void test_updateAnalysisOptions_defaultLanguageVersion() {
+    _applyAnalysisOptions(
+      ['a.dart'],
+      (analysisOptions) {},
+      (analysisOptions) {
+        expect(
+          analysisOptions.nonPackageLanguageVersion,
+          ExperimentStatus.currentVersion,
+        );
+        var featureSet = analysisOptions.nonPackageFeatureSet;
+        expect(featureSet.isEnabled(Feature.non_nullable), isTrue);
+      },
+    );
+
+    _applyAnalysisOptions(
+      ['--default-language-version=2.7', 'a.dart'],
+      (analysisOptions) {},
+      (analysisOptions) {
+        expect(
+          analysisOptions.nonPackageLanguageVersion,
+          Version.parse('2.7.0'),
+        );
+        var featureSet = analysisOptions.nonPackageFeatureSet;
+        expect(featureSet.isEnabled(Feature.non_nullable), isFalse);
+      },
+    );
   }
 
-  void test_buildSummaryInputs_separateFlags_normalMode() {
-    _parse([
-      '--build-summary-input=/path/to/aaa.sum',
-      '--build-summary-input=/path/to/bbb.sum',
-      'package:p/foo.dart|/path/to/p/lib/foo.dart',
-    ]);
-    expect(options.buildMode, isFalse);
-    expect(
-        options.buildSummaryInputs, ['/path/to/aaa.sum', '/path/to/bbb.sum']);
-  }
+  void test_updateAnalysisOptions_enableExperiment() {
+    var feature_a = ExperimentalFeature(
+      index: 0,
+      enableString: 'a',
+      isEnabledByDefault: false,
+      isExpired: false,
+      documentation: 'a',
+      experimentalReleaseVersion: null,
+      releaseVersion: null,
+    );
 
-  void test_buildSummaryOnly() {
-    _parseBuildMode([
-      '--build-summary-output=/path/to/aaa.sum',
-      '--build-summary-only',
-      'package:p/foo.dart|/path/to/p/lib/foo.dart',
-    ]);
-    expect(options.buildMode, isTrue);
-    expect(options.buildSummaryOnly, isTrue);
-  }
+    var feature_b = ExperimentalFeature(
+      index: 1,
+      enableString: 'a',
+      isEnabledByDefault: false,
+      isExpired: false,
+      documentation: 'a',
+      experimentalReleaseVersion: null,
+      releaseVersion: null,
+    );
 
-  void test_buildSummaryOutput() {
-    _parseBuildMode([
-      '--build-summary-output=//path/to/output.sum',
-      'package:p/foo.dart|/path/to/p/lib/foo.dart',
-    ]);
-    expect(options.buildMode, isTrue);
-    expect(options.buildSummaryOutput, '//path/to/output.sum');
-  }
+    FeatureSet featuresWithExperiments(List<String> experiments) {
+      return FeatureSet.fromEnableFlags2(
+        sdkLanguageVersion: ExperimentStatus.currentVersion,
+        flags: experiments,
+      );
+    }
 
-  void test_buildSummaryOutputSemantic() {
-    _parseBuildMode([
-      '--build-summary-output-semantic=//path/to/output.sum',
-      'package:p/foo.dart|/path/to/p/lib/foo.dart',
-    ]);
-    expect(options.buildMode, isTrue);
-    expect(options.buildSummaryOutputSemantic, '//path/to/output.sum');
-  }
+    overrideKnownFeatures({'a': feature_a, 'b': feature_b}, () {
+      // Replace.
+      _applyAnalysisOptions(
+        ['--enable-experiment=b', 'a.dart'],
+        (analysisOptions) {
+          analysisOptions.contextFeatures = featuresWithExperiments(['a']);
+        },
+        (analysisOptions) {
+          var featureSet = analysisOptions.contextFeatures;
+          expect(featureSet.isEnabled(feature_a), isFalse);
+          expect(featureSet.isEnabled(feature_b), isTrue);
+        },
+      );
 
-  void test_buildSuppressExitCode() {
-    _parseBuildMode([
-      '--build-suppress-exit-code',
-      'package:p/foo.dart|/path/to/p/lib/foo.dart',
-    ]);
-    expect(options.buildMode, isTrue);
-    expect(options.buildSuppressExitCode, isTrue);
-  }
-
-  void _parse(List<String> args) {
-    var resourceProvider = PhysicalResourceProvider.INSTANCE;
-    options =
-        CommandLineOptions.parse(resourceProvider, args, printAndFail: (msg) {
-      failureMessage = msg;
+      // Don't change if not provided.
+      _applyAnalysisOptions(
+        ['a.dart'],
+        (analysisOptions) {
+          analysisOptions.contextFeatures = featuresWithExperiments(['a']);
+        },
+        (analysisOptions) {
+          var featureSet = analysisOptions.contextFeatures;
+          expect(featureSet.isEnabled(feature_a), isTrue);
+          expect(featureSet.isEnabled(feature_b), isFalse);
+        },
+      );
     });
   }
 
-  void _parseBuildMode(List<String> specificArguments,
-      {bool withDartSdkSummary = true}) {
-    var args = [
-      '--build-mode',
-      if (withDartSdkSummary) ...[
-        '--dart-sdk-summary',
-        '/sdk/lib/strong.sum',
-      ],
-      ...specificArguments
-    ];
+  void test_updateAnalysisOptions_implicitCasts() {
+    // Turn on.
+    _applyAnalysisOptions(
+      ['--implicit-casts', 'a.dart'],
+      (analysisOptions) {
+        analysisOptions.implicitCasts = false;
+      },
+      (analysisOptions) {
+        expect(analysisOptions.implicitCasts, isTrue);
+      },
+    );
+
+    // Turn off.
+    _applyAnalysisOptions(
+      ['--no-implicit-casts', 'a.dart'],
+      (analysisOptions) {
+        analysisOptions.implicitCasts = true;
+      },
+      (analysisOptions) {
+        expect(analysisOptions.implicitCasts, isFalse);
+      },
+    );
+
+    // Don't change if not provided, false.
+    _applyAnalysisOptions(
+      ['a.dart'],
+      (analysisOptions) {
+        analysisOptions.implicitCasts = false;
+      },
+      (analysisOptions) {
+        expect(analysisOptions.implicitCasts, isFalse);
+      },
+    );
+
+    // Don't change if not provided, true.
+    _applyAnalysisOptions(
+      ['a.dart'],
+      (analysisOptions) {
+        analysisOptions.implicitCasts = true;
+      },
+      (analysisOptions) {
+        expect(analysisOptions.implicitCasts, isTrue);
+      },
+    );
+  }
+
+  void test_updateAnalysisOptions_lints() {
+    // Turn lints on.
+    _applyAnalysisOptions(
+      ['--lints', 'a.dart'],
+      (analysisOptions) {
+        analysisOptions.lint = false;
+      },
+      (analysisOptions) {
+        expect(analysisOptions.lint, isTrue);
+      },
+    );
+
+    // Turn lints off.
+    _applyAnalysisOptions(
+      ['--no-lints', 'a.dart'],
+      (analysisOptions) {
+        analysisOptions.lint = true;
+      },
+      (analysisOptions) {
+        expect(analysisOptions.lint, isFalse);
+      },
+    );
+
+    // Don't change if not provided, false.
+    _applyAnalysisOptions(
+      ['a.dart'],
+      (analysisOptions) {
+        analysisOptions.lint = false;
+      },
+      (analysisOptions) {
+        expect(analysisOptions.lint, isFalse);
+      },
+    );
+
+    // Don't change if not provided, true.
+    _applyAnalysisOptions(
+      ['a.dart'],
+      (analysisOptions) {
+        analysisOptions.lint = true;
+      },
+      (analysisOptions) {
+        expect(analysisOptions.lint, isTrue);
+      },
+    );
+  }
+
+  void test_updateAnalysisOptions_noImplicitDynamic() {
+    _applyAnalysisOptions(
+      ['--no-implicit-dynamic', 'a.dart'],
+      (analysisOptions) {
+        analysisOptions.implicitDynamic = true;
+      },
+      (analysisOptions) {
+        expect(analysisOptions.implicitDynamic, isFalse);
+      },
+    );
+
+    // Don't change if not provided, false.
+    _applyAnalysisOptions(
+      ['a.dart'],
+      (analysisOptions) {
+        analysisOptions.implicitDynamic = false;
+      },
+      (analysisOptions) {
+        expect(analysisOptions.implicitDynamic, isFalse);
+      },
+    );
+
+    // Don't change if not provided, true.
+    _applyAnalysisOptions(
+      ['a.dart'],
+      (analysisOptions) {
+        analysisOptions.implicitDynamic = true;
+      },
+      (analysisOptions) {
+        expect(analysisOptions.implicitDynamic, isTrue);
+      },
+    );
+  }
+
+  void _applyAnalysisOptions(
+    List<String> args,
+    void Function(AnalysisOptionsImpl) configureInitial,
+    void Function(AnalysisOptionsImpl) checkApplied,
+  ) {
     _parse(args);
+    expect(commandLineOptions, isNotNull);
+
+    var analysisOptions = AnalysisOptionsImpl();
+    configureInitial(analysisOptions);
+
+    commandLineOptions.updateAnalysisOptions(analysisOptions);
+    checkApplied(analysisOptions);
+  }
+
+  void _parse(List<String> args, {bool ignoreUnrecognized = true}) {
+    var resourceProvider = PhysicalResourceProvider.INSTANCE;
+    commandLineOptions = CommandLineOptions.parse(
+      resourceProvider,
+      [
+        if (ignoreUnrecognized) '--ignore-unrecognized-flags',
+        ...args,
+      ],
+      printAndFail: (msg) {
+        failureMessage = msg;
+      },
+    );
   }
 }
diff --git a/pkg/analyzer_cli/test/reporter_test.dart b/pkg/analyzer_cli/test/reporter_test.dart
index de8e15c..e0edaba 100644
--- a/pkg/analyzer_cli/test/reporter_test.dart
+++ b/pkg/analyzer_cli/test/reporter_test.dart
@@ -27,44 +27,70 @@
       options = MockCommandLineOptions();
       options.enableTypeChecks = false;
       options.infosAreFatal = false;
+      options.jsonFormat = false;
       options.machineFormat = false;
       options.verbose = false;
       options.color = false;
-
-      reporter = HumanErrorFormatter(out, options, stats);
     });
 
     tearDown(() {
       ansi.runningTests = false;
     });
 
-    test('error', () {
-      var error = mockResult(ErrorType.SYNTACTIC_ERROR, ErrorSeverity.ERROR);
-      reporter.formatErrors([error]);
-      reporter.flush();
+    group('human', () {
+      setUp(() {
+        reporter = HumanErrorFormatter(out, options, stats);
+      });
 
-      expect(out.toString().trim(),
-          'error • MSG • /foo/bar/baz.dart:3:3 • mock_code');
+      test('error', () {
+        var error = mockResult(ErrorType.SYNTACTIC_ERROR, ErrorSeverity.ERROR);
+        reporter.formatErrors([error]);
+        reporter.flush();
+
+        expect(out.toString().trim(),
+            'error • MSG • /foo/bar/baz.dart:3:3 • mock_code');
+      });
+
+      test('hint', () {
+        var error = mockResult(ErrorType.HINT, ErrorSeverity.INFO);
+        reporter.formatErrors([error]);
+        reporter.flush();
+
+        expect(out.toString().trim(),
+            'hint • MSG • /foo/bar/baz.dart:3:3 • mock_code');
+      });
+
+      test('stats', () {
+        var error = mockResult(ErrorType.HINT, ErrorSeverity.INFO);
+        reporter.formatErrors([error]);
+        reporter.flush();
+        stats.print(out);
+        expect(
+            out.toString().trim(),
+            'hint • MSG • /foo/bar/baz.dart:3:3 • mock_code\n'
+            '1 hint found.');
+      });
     });
 
-    test('hint', () {
-      var error = mockResult(ErrorType.HINT, ErrorSeverity.INFO);
-      reporter.formatErrors([error]);
-      reporter.flush();
+    group('json', () {
+      setUp(() {
+        reporter = JsonErrorFormatter(out, options, stats);
+      });
 
-      expect(out.toString().trim(),
-          'hint • MSG • /foo/bar/baz.dart:3:3 • mock_code');
-    });
+      test('error', () {
+        var error = mockResult(ErrorType.SYNTACTIC_ERROR, ErrorSeverity.ERROR);
+        reporter.formatErrors([error]);
+        reporter.flush();
 
-    test('stats', () {
-      var error = mockResult(ErrorType.HINT, ErrorSeverity.INFO);
-      reporter.formatErrors([error]);
-      reporter.flush();
-      stats.print(out);
-      expect(
-          out.toString().trim(),
-          'hint • MSG • /foo/bar/baz.dart:3:3 • mock_code\n'
-          '1 hint found.');
+        expect(
+            out.toString().trim(),
+            '{"version":1,"diagnostics":[{'
+            '"code":"mock_code","severity":"ERROR","type":"SYNTACTIC_ERROR",'
+            '"location":{"file":"/foo/bar/baz.dart","range":{'
+            '"start":{"offset":20,"line":3,"column":3},'
+            '"end":{"offset":23,"line":3,"column":3}}},'
+            '"problemMessage":"MSG"}]}');
+      });
     });
   });
 }
diff --git a/pkg/analyzer_plugin/CHANGELOG.md b/pkg/analyzer_plugin/CHANGELOG.md
index 8215421..0fec00f 100644
--- a/pkg/analyzer_plugin/CHANGELOG.md
+++ b/pkg/analyzer_plugin/CHANGELOG.md
@@ -1,7 +1,11 @@
-## 0.5.0-dev
-- Changed the support version range of the analyzer to `>=0.42.0 <0.43.0`.
+## 0.5.0
+- Changed the support version range of the analyzer to `^1.3.0`.
 - Removed `Plugin.fileContentOverlay`, instead `Plugin.resourceProvider` is
   now `OverlayResourceProvider`, and `analysis.updateContent` updates it.
+- Removed deprecated `DartChangeBuilder` and `DartChangeBuilderImpl`.
+- Removed deprecated `ChangeBuilder.addFileEdit()`.
+- Stable null safety release.
+- Updated dependencies to null safe releases.
 
 ## 0.4.0
 - Deprecated the class `DartChangeBuilder` and enhanced `ChangeBuilder` to be
diff --git a/pkg/analyzer_plugin/doc/api.html b/pkg/analyzer_plugin/doc/api.html
index 768e479..52db9f4 100644
--- a/pkg/analyzer_plugin/doc/api.html
+++ b/pkg/analyzer_plugin/doc/api.html
@@ -1579,6 +1579,18 @@
           The one-based index of the column containing the first character of
           the range.
         </p>
+      </dd><dt class="field"><b>endLine: int</b></dt><dd>
+        
+        <p>
+          The one-based index of the line containing the character immediately
+          following the range.
+        </p>
+      </dd><dt class="field"><b>endColumn: int</b></dt><dd>
+        
+        <p>
+          The one-based index of the column containing the character immediately
+          following the range.
+        </p>
       </dd></dl></dd><dt class="typeDefinition"><a name="type_NavigationRegion">NavigationRegion: object</a></dt><dd>
     <p>
       A description of a region from which the user can navigate to the
diff --git a/pkg/analyzer_plugin/lib/channel/channel.dart b/pkg/analyzer_plugin/lib/channel/channel.dart
index d2479e0..36ae448 100644
--- a/pkg/analyzer_plugin/lib/channel/channel.dart
+++ b/pkg/analyzer_plugin/lib/channel/channel.dart
@@ -19,7 +19,7 @@
   /// client, invoke the [onDone] function. Only one listener is allowed per
   /// channel.
   void listen(void Function(Request request) onRequest,
-      {Function onError, void Function() onDone});
+      {Function? onError, void Function()? onDone});
 
   /// Send the given [notification] to the server.
   void sendNotification(Notification notification);
@@ -49,7 +49,7 @@
   /// listener is allowed per channel.
   void listen(void Function(Response response) onResponse,
       void Function(Notification notification) onNotification,
-      {void Function(dynamic error) onError, void Function() onDone});
+      {void Function(dynamic error)? onError, void Function()? onDone});
 
   /// Send the given [request] to the plugin.
   void sendRequest(Request request);
diff --git a/pkg/analyzer_plugin/lib/plugin/completion_mixin.dart b/pkg/analyzer_plugin/lib/plugin/completion_mixin.dart
index 4bbf59a..f208d20 100644
--- a/pkg/analyzer_plugin/lib/plugin/completion_mixin.dart
+++ b/pkg/analyzer_plugin/lib/plugin/completion_mixin.dart
@@ -34,7 +34,7 @@
     var generator = CompletionGenerator(getCompletionContributors(path));
     var result = await generator.generateCompletionResponse(request);
     result.sendNotifications(channel);
-    return result.result;
+    return result.result!;
   }
 }
 
diff --git a/pkg/analyzer_plugin/lib/plugin/navigation_mixin.dart b/pkg/analyzer_plugin/lib/plugin/navigation_mixin.dart
index 07dbddb..de11deb 100644
--- a/pkg/analyzer_plugin/lib/plugin/navigation_mixin.dart
+++ b/pkg/analyzer_plugin/lib/plugin/navigation_mixin.dart
@@ -27,7 +27,7 @@
     var length = parameters.length;
     if (offset < 0 && length < 0) {
       offset = 0;
-      length = result.content.length;
+      length = result.content?.length ?? 0;
     }
     return DartNavigationRequestImpl(resourceProvider, offset, length, result);
   }
diff --git a/pkg/analyzer_plugin/lib/plugin/plugin.dart b/pkg/analyzer_plugin/lib/plugin/plugin.dart
index 9fb108f..0a5fa70 100644
--- a/pkg/analyzer_plugin/lib/plugin/plugin.dart
+++ b/pkg/analyzer_plugin/lib/plugin/plugin.dart
@@ -33,7 +33,7 @@
 
   /// The communication channel being used to communicate with the analysis
   /// server.
-  PluginCommunicationChannel _channel;
+  late PluginCommunicationChannel _channel;
 
   /// The resource provider used to access the file system.
   final OverlayResourceProvider resourceProvider;
@@ -45,7 +45,7 @@
   final SubscriptionManager subscriptionManager = SubscriptionManager();
 
   /// The scheduler used by any analysis drivers that are created.
-  AnalysisDriverScheduler analysisDriverScheduler;
+  late AnalysisDriverScheduler analysisDriverScheduler;
 
   /// A table mapping the current context roots to the analysis driver created
   /// for that root.
@@ -58,15 +58,15 @@
   /// The byte store used by any analysis drivers that are created, or `null` if
   /// the cache location isn't known because the 'plugin.version' request has not
   /// yet been received.
-  ByteStore _byteStore;
+  late ByteStore _byteStore;
 
   /// The SDK manager used to manage SDKs.
-  DartSdkManager _sdkManager;
+  late DartSdkManager _sdkManager;
 
   /// Initialize a newly created analysis server plugin. If a resource [provider]
   /// is given, then it will be used to access the file system. Otherwise a
   /// resource provider that accesses the physical file system will be used.
-  ServerPlugin(ResourceProvider provider)
+  ServerPlugin(ResourceProvider? provider)
       : resourceProvider = OverlayResourceProvider(
             provider ?? PhysicalResourceProvider.INSTANCE) {
     analysisDriverScheduler = AnalysisDriverScheduler(performanceLog);
@@ -84,7 +84,7 @@
 
   /// Return the user visible information about how to contact the plugin authors
   /// with any problems that are found, or `null` if there is no contact info.
-  String get contactInfo => null;
+  String? get contactInfo => null;
 
   /// Return a list of glob patterns selecting the files that this plugin is
   /// interested in analyzing.
@@ -106,7 +106,7 @@
   }
 
   /// Return the context root containing the file at the given [filePath].
-  ContextRoot contextRootContaining(String filePath) {
+  ContextRoot? contextRootContaining(String filePath) {
     var pathContext = resourceProvider.pathContext;
 
     /// Return `true` if the given [child] is either the same as or within the
@@ -142,7 +142,7 @@
   AnalysisDriverGeneric createAnalysisDriver(ContextRoot contextRoot);
 
   /// Return the driver being used to analyze the file with the given [path].
-  AnalysisDriverGeneric driverForPath(String path) {
+  AnalysisDriverGeneric? driverForPath(String path) {
     var contextRoot = contextRootContaining(path);
     if (contextRoot == null) {
       return null;
@@ -161,7 +161,7 @@
       throw RequestFailure(
           RequestErrorFactory.pluginError('Failed to analyze $path', null));
     }
-    var result = await (driver as AnalysisDriver).getResult(path);
+    var result = await driver.getResult(path);
     var state = result.state;
     if (state != ResultState.VALID) {
       // Return an error from the request.
@@ -228,7 +228,7 @@
       var driver = driverMap.remove(contextRoot);
       // The `dispose` method has the side-effect of removing the driver from
       // the analysis driver scheduler.
-      driver.dispose();
+      driver?.dispose();
     }
     return AnalysisSetContextRootsResult();
   }
@@ -244,7 +244,7 @@
       var contextRoot = contextRootContaining(file);
       if (contextRoot != null) {
         // TODO(brianwilkerson) Which driver should we use if there is no context root?
-        var driver = driverMap[contextRoot];
+        var driver = driverMap[contextRoot]!;
         filesByDriver.putIfAbsent(driver, () => <String>[]).add(file);
       }
     }
@@ -274,10 +274,10 @@
   /// Throw a [RequestFailure] if the request could not be handled.
   Future<AnalysisUpdateContentResult> handleAnalysisUpdateContent(
       AnalysisUpdateContentParams parameters) async {
-    Map<String, Object> files = parameters.files;
-    files.forEach((String filePath, Object overlay) {
+    var files = parameters.files;
+    files.forEach((String filePath, Object? overlay) {
       // Prepare the old overlay contents.
-      String oldContents;
+      String? oldContents;
       try {
         if (resourceProvider.hasOverlay(filePath)) {
           var file = resourceProvider.getFile(filePath);
@@ -286,7 +286,7 @@
       } catch (_) {}
 
       // Prepare the new contents.
-      String newContents;
+      String? newContents;
       if (overlay is AddContentOverlay) {
         newContents = overlay.content;
       } else if (overlay is ChangeContentOverlay) {
@@ -359,7 +359,7 @@
   /// Handle an 'edit.getRefactoring' request.
   ///
   /// Throw a [RequestFailure] if the request could not be handled.
-  Future<EditGetRefactoringResult> handleEditGetRefactoring(
+  Future<EditGetRefactoringResult?> handleEditGetRefactoring(
       EditGetRefactoringParams parameters) async {
     return null;
   }
@@ -367,7 +367,7 @@
   /// Handle a 'kythe.getKytheEntries' request.
   ///
   /// Throw a [RequestFailure] if the request could not be handled.
-  Future<KytheGetKytheEntriesResult> handleKytheGetKytheEntries(
+  Future<KytheGetKytheEntriesResult?> handleKytheGetKytheEntries(
       KytheGetKytheEntriesParams parameters) async {
     return null;
   }
@@ -503,8 +503,8 @@
 
   /// Compute the response that should be returned for the given [request], or
   /// `null` if the response has already been sent.
-  Future<Response> _getResponse(Request request, int requestTime) async {
-    ResponseResult result;
+  Future<Response?> _getResponse(Request request, int requestTime) async {
+    ResponseResult? result;
     switch (request.method) {
       case ANALYSIS_REQUEST_GET_NAVIGATION:
         var params = AnalysisGetNavigationParams.fromRequest(request);
@@ -577,7 +577,7 @@
   Future<void> _onRequest(Request request) async {
     var requestTime = DateTime.now().millisecondsSinceEpoch;
     var id = request.id;
-    Response response;
+    Response? response;
     try {
       response = await _getResponse(request, requestTime);
     } on RequestFailure catch (exception) {
diff --git a/pkg/analyzer_plugin/lib/protocol/protocol.dart b/pkg/analyzer_plugin/lib/protocol/protocol.dart
index e661567..f0d4f317 100644
--- a/pkg/analyzer_plugin/lib/protocol/protocol.dart
+++ b/pkg/analyzer_plugin/lib/protocol/protocol.dart
@@ -30,7 +30,7 @@
 
   /// A table mapping the names of notification parameters to their values, or
   /// `null` if there are no notification parameters.
-  final Map<String, Object> params;
+  final Map<String, Object>? params;
 
   /// Initialize a newly created [Notification] to have the given [event] name.
   /// If [params] is provided, it will be used as the params; otherwise no
@@ -48,6 +48,7 @@
   Map<String, Object> toJson() {
     var jsonObject = <String, Object>{};
     jsonObject[EVENT] = event;
+    var params = this.params;
     if (params != null) {
       jsonObject[PARAMS] = params;
     }
@@ -79,18 +80,18 @@
   final String method;
 
   /// A table mapping the names of request parameters to their values.
-  final Map<String, Object> params;
+  final Map<String, Object?> params;
 
   /// The time (milliseconds since epoch) at which the server made the request,
   /// or `null` if this information is not provided by the server.
-  final int serverRequestTime;
+  final int? serverRequestTime;
 
   /// Initialize a newly created [Request] to have the given [id] and [method]
   /// name. If [params] is supplied, it is used as the "params" map for the
   /// request. Otherwise an empty "params" map is allocated.
   Request(this.id, this.method,
-      [Map<String, Object> params, this.serverRequestTime])
-      : params = params ?? <String, Object>{};
+      [Map<String, Object?>? params, this.serverRequestTime])
+      : params = params ?? <String, Object?>{};
 
   /// Return a request parsed from the given json, or `null` if the [data] is
   /// not a valid json representation of a request. The [data] is expected to
@@ -110,22 +111,21 @@
   /// The parameters can contain any number of name/value pairs. The
   /// clientRequestTime must be an int representing the time at which the client
   /// issued the request (milliseconds since epoch).
-  factory Request.fromJson(Map<String, Object> result) {
+  factory Request.fromJson(Map<String, Object?> result) {
     var id = result[Request.ID];
     var method = result[Request.METHOD];
     if (id is! String || method is! String) {
-      return null;
+      throw StateError('Unexpected type for id or method');
     }
     var time = result[Request.SERVER_REQUEST_TIME];
-    if (time != null && time is! int) {
-      return null;
+    if (time is! int?) {
+      throw StateError('Unexpected type for server request time');
     }
     var params = result[Request.PARAMS];
-    if (params is Map || params == null) {
-      return Request(id as String, method as String,
-          params as Map<String, Object>, time as int);
+    if (params is Map<String, Object?>?) {
+      return Request(id, method, params, time);
     } else {
-      return null;
+      throw StateError('Unexpected type for params');
     }
   }
 
@@ -152,13 +152,14 @@
     if (params.isNotEmpty) {
       jsonObject[PARAMS] = params;
     }
+    var serverRequestTime = this.serverRequestTime;
     if (serverRequestTime != null) {
       jsonObject[SERVER_REQUEST_TIME] = serverRequestTime;
     }
     return jsonObject;
   }
 
-  bool _equalLists(List first, List second) {
+  bool _equalLists(List? first, List? second) {
     if (first == null) {
       return second == null;
     }
@@ -177,7 +178,7 @@
     return true;
   }
 
-  bool _equalMaps(Map first, Map second) {
+  bool _equalMaps(Map? first, Map? second) {
     if (first == null) {
       return second == null;
     }
@@ -198,7 +199,7 @@
     return true;
   }
 
-  bool _equalObjects(Object first, Object second) {
+  bool _equalObjects(Object? first, Object? second) {
     if (first == null) {
       return second == null;
     }
@@ -249,7 +250,7 @@
           "Invalid parameter '$path'. $expectation.");
 
   /// Return a request error representing an error that occurred in the plugin.
-  static RequestError pluginError(dynamic exception, String stackTrace) =>
+  static RequestError pluginError(dynamic exception, String? stackTrace) =>
       RequestError(RequestErrorCode.PLUGIN_ERROR, exception.toString(),
           stackTrace: stackTrace);
 
@@ -296,49 +297,48 @@
 
   /// The error that was caused by attempting to handle the request, or `null` if
   /// there was no error.
-  final RequestError error;
+  final RequestError? error;
 
   /// The time at which the request was handled by the plugin.
   final int requestTime;
 
   /// A table mapping the names of result fields to their values. Should be
   /// `null` if there is no result to send.
-  Map<String, Object> result;
+  Map<String, Object?>? result;
 
   /// Initialize a newly created instance to represent a response to a request
-  /// with the given [id]. If [_result] is provided, it will be used as the
+  /// with the given [id]. If [result] is provided, it will be used as the
   /// result; otherwise an empty result will be used. If an [error] is provided
   /// then the response will represent an error condition.
-  Response(this.id, this.requestTime, {this.error, Map<String, Object> result})
-      : result = result;
+  Response(this.id, this.requestTime, {this.error, this.result});
 
   /// Initialize a newly created instance based on the given JSON data.
-  factory Response.fromJson(Map json) {
-    try {
-      Object id = json[ID];
-      if (id is! String) {
-        return null;
-      }
-      Object error = json[ERROR];
-      RequestError decodedError;
-      if (error is Map) {
-        decodedError =
-            RequestError.fromJson(ResponseDecoder(null), '.error', error);
-      }
-      Object requestTime = json[REQUEST_TIME];
-      if (requestTime is! int) {
-        return null;
-      }
-      Object result = json[RESULT];
-      Map<String, Object> decodedResult;
-      if (result is Map) {
-        decodedResult = result as Map<String, Object>;
-      }
-      return Response(id as String, requestTime as int,
-          error: decodedError, result: decodedResult);
-    } catch (exception) {
-      return null;
+  factory Response.fromJson(Map<String, Object?> json) {
+    var id = json[ID];
+    if (id is! String) {
+      throw StateError('Unexpected type for id');
     }
+
+    RequestError? decodedError;
+    var error = json[ERROR];
+    if (error is Map) {
+      decodedError =
+          RequestError.fromJson(ResponseDecoder(null), '.error', error);
+    }
+
+    var requestTime = json[REQUEST_TIME];
+    if (requestTime is! int) {
+      throw StateError('Unexpected type for requestTime');
+    }
+
+    Map<String, Object?>? decodedResult;
+    var result = json[Response.RESULT];
+    if (result is Map<String, Object?>) {
+      decodedResult = result;
+    }
+
+    return Response(id, requestTime,
+        error: decodedError, result: decodedResult);
   }
 
   /// Return a table representing the structure of the Json object that will be
@@ -346,10 +346,12 @@
   Map<String, Object> toJson() {
     var jsonObject = <String, Object>{};
     jsonObject[ID] = id;
+    var error = this.error;
     if (error != null) {
       jsonObject[ERROR] = error.toJson();
     }
     jsonObject[REQUEST_TIME] = requestTime;
+    var result = this.result;
     if (result != null) {
       jsonObject[RESULT] = result;
     }
diff --git a/pkg/analyzer_plugin/lib/protocol/protocol_common.dart b/pkg/analyzer_plugin/lib/protocol/protocol_common.dart
index 5dbc101..1132b0a 100644
--- a/pkg/analyzer_plugin/lib/protocol/protocol_common.dart
+++ b/pkg/analyzer_plugin/lib/protocol/protocol_common.dart
@@ -21,23 +21,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AddContentOverlay implements HasToJson {
-  String _content;
-
   /// The new content of the file.
-  String get content => _content;
+  String content;
 
-  /// The new content of the file.
-  set content(String value) {
-    assert(value != null);
-    _content = value;
-  }
-
-  AddContentOverlay(String content) {
-    this.content = content;
-  }
+  AddContentOverlay(this.content);
 
   factory AddContentOverlay.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       if (json['type'] != 'add') {
@@ -57,8 +47,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['type'] = 'add';
     result['content'] = content;
     return result;
@@ -100,100 +90,33 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisError implements HasToJson {
-  AnalysisErrorSeverity _severity;
-
-  AnalysisErrorType _type;
-
-  Location _location;
-
-  String _message;
-
-  String _correction;
-
-  String _code;
-
-  String _url;
-
-  List<DiagnosticMessage> _contextMessages;
-
-  bool _hasFix;
-
   /// The severity of the error.
-  AnalysisErrorSeverity get severity => _severity;
-
-  /// The severity of the error.
-  set severity(AnalysisErrorSeverity value) {
-    assert(value != null);
-    _severity = value;
-  }
+  AnalysisErrorSeverity severity;
 
   /// The type of the error.
-  AnalysisErrorType get type => _type;
-
-  /// The type of the error.
-  set type(AnalysisErrorType value) {
-    assert(value != null);
-    _type = value;
-  }
+  AnalysisErrorType type;
 
   /// The location associated with the error.
-  Location get location => _location;
-
-  /// The location associated with the error.
-  set location(Location value) {
-    assert(value != null);
-    _location = value;
-  }
+  Location location;
 
   /// The message to be displayed for this error. The message should indicate
   /// what is wrong with the code and why it is wrong.
-  String get message => _message;
-
-  /// The message to be displayed for this error. The message should indicate
-  /// what is wrong with the code and why it is wrong.
-  set message(String value) {
-    assert(value != null);
-    _message = value;
-  }
+  String message;
 
   /// The correction message to be displayed for this error. The correction
   /// message should indicate how the user can fix the error. The field is
   /// omitted if there is no correction message associated with the error code.
-  String get correction => _correction;
-
-  /// The correction message to be displayed for this error. The correction
-  /// message should indicate how the user can fix the error. The field is
-  /// omitted if there is no correction message associated with the error code.
-  set correction(String value) {
-    _correction = value;
-  }
+  String? correction;
 
   /// The name, as a string, of the error code associated with this error.
-  String get code => _code;
-
-  /// The name, as a string, of the error code associated with this error.
-  set code(String value) {
-    assert(value != null);
-    _code = value;
-  }
+  String code;
 
   /// 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;
-  }
+  String? url;
 
   /// 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;
-  }
+  List<DiagnosticMessage>? contextMessages;
 
   /// A hint to indicate to interested clients that this error has an
   /// associated fix (or fixes). The absence of this field implies there are
@@ -204,40 +127,14 @@
   /// 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;
+  bool? 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.
-  set hasFix(bool value) {
-    _hasFix = value;
-  }
-
-  AnalysisError(AnalysisErrorSeverity severity, AnalysisErrorType type,
-      Location location, String message, String code,
-      {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;
-  }
+  AnalysisError(
+      this.severity, this.type, this.location, this.message, this.code,
+      {this.correction, this.url, this.contextMessages, this.hasFix});
 
   factory AnalysisError.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       AnalysisErrorSeverity severity;
@@ -268,7 +165,7 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'message');
       }
-      String correction;
+      String? correction;
       if (json.containsKey('correction')) {
         correction = jsonDecoder.decodeString(
             jsonPath + '.correction', json['correction']);
@@ -279,19 +176,19 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'code');
       }
-      String url;
+      String? url;
       if (json.containsKey('url')) {
         url = jsonDecoder.decodeString(jsonPath + '.url', json['url']);
       }
-      List<DiagnosticMessage> contextMessages;
+      List<DiagnosticMessage>? contextMessages;
       if (json.containsKey('contextMessages')) {
         contextMessages = jsonDecoder.decodeList(
             jsonPath + '.contextMessages',
             json['contextMessages'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 DiagnosticMessage.fromJson(jsonDecoder, jsonPath, json));
       }
-      bool hasFix;
+      bool? hasFix;
       if (json.containsKey('hasFix')) {
         hasFix = jsonDecoder.decodeBool(jsonPath + '.hasFix', json['hasFix']);
       }
@@ -306,24 +203,28 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['severity'] = severity.toJson();
     result['type'] = type.toJson();
     result['location'] = location.toJson();
     result['message'] = message;
+    var correction = this.correction;
     if (correction != null) {
       result['correction'] = correction;
     }
     result['code'] = code;
+    var url = this.url;
     if (url != null) {
       result['url'] = url;
     }
+    var contextMessages = this.contextMessages;
     if (contextMessages != null) {
       result['contextMessages'] = contextMessages
           .map((DiagnosticMessage value) => value.toJson())
           .toList();
     }
+    var hasFix = this.hasFix;
     if (hasFix != null) {
       result['hasFix'] = hasFix;
     }
@@ -408,7 +309,7 @@
   }
 
   factory AnalysisErrorSeverity.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     if (json is String) {
       try {
         return AnalysisErrorSeverity(json);
@@ -501,7 +402,7 @@
   }
 
   factory AnalysisErrorType.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     if (json is String) {
       try {
         return AnalysisErrorType(json);
@@ -527,23 +428,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class ChangeContentOverlay implements HasToJson {
-  List<SourceEdit> _edits;
-
   /// The edits to be applied to the file.
-  List<SourceEdit> get edits => _edits;
+  List<SourceEdit> edits;
 
-  /// The edits to be applied to the file.
-  set edits(List<SourceEdit> value) {
-    assert(value != null);
-    _edits = value;
-  }
-
-  ChangeContentOverlay(List<SourceEdit> edits) {
-    this.edits = edits;
-  }
+  ChangeContentOverlay(this.edits);
 
   factory ChangeContentOverlay.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       if (json['type'] != 'change') {
@@ -554,7 +445,7 @@
         edits = jsonDecoder.decodeList(
             jsonPath + '.edits',
             json['edits'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 SourceEdit.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'edits');
@@ -566,8 +457,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['type'] = 'change';
     result['edits'] = edits.map((SourceEdit value) => value.toJson()).toList();
     return result;
@@ -624,210 +515,67 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class CompletionSuggestion implements HasToJson {
-  CompletionSuggestionKind _kind;
-
-  int _relevance;
-
-  String _completion;
-
-  String _displayText;
-
-  int _replacementOffset;
-
-  int _replacementLength;
-
-  int _selectionOffset;
-
-  int _selectionLength;
-
-  bool _isDeprecated;
-
-  bool _isPotential;
-
-  String _docSummary;
-
-  String _docComplete;
-
-  String _declaringType;
-
-  String _defaultArgumentListString;
-
-  List<int> _defaultArgumentListTextRanges;
-
-  Element _element;
-
-  String _returnType;
-
-  List<String> _parameterNames;
-
-  List<String> _parameterTypes;
-
-  int _requiredParameterCount;
-
-  bool _hasNamedParameters;
-
-  String _parameterName;
-
-  String _parameterType;
-
   /// The kind of element being suggested.
-  CompletionSuggestionKind get kind => _kind;
-
-  /// The kind of element being suggested.
-  set kind(CompletionSuggestionKind value) {
-    assert(value != null);
-    _kind = value;
-  }
+  CompletionSuggestionKind kind;
 
   /// The relevance of this completion suggestion where a higher number
   /// indicates a higher relevance.
-  int get relevance => _relevance;
-
-  /// The relevance of this completion suggestion where a higher number
-  /// indicates a higher relevance.
-  set relevance(int value) {
-    assert(value != null);
-    _relevance = value;
-  }
+  int relevance;
 
   /// The identifier to be inserted if the suggestion is selected. If the
   /// suggestion is for a method or function, the client might want to
   /// additionally insert a template for the parameters. The information
   /// required in order to do so is contained in other fields.
-  String get completion => _completion;
-
-  /// The identifier to be inserted if the suggestion is selected. If the
-  /// suggestion is for a method or function, the client might want to
-  /// additionally insert a template for the parameters. The information
-  /// required in order to do so is contained in other fields.
-  set completion(String value) {
-    assert(value != null);
-    _completion = value;
-  }
+  String completion;
 
   /// Text to be displayed in, for example, a completion pop-up. This field is
   /// only defined if the displayed text should be different than the
   /// completion. Otherwise it is omitted.
-  String get displayText => _displayText;
-
-  /// Text to be displayed in, for example, a completion pop-up. This field is
-  /// only defined if the displayed text should be different than the
-  /// completion. Otherwise it is omitted.
-  set displayText(String value) {
-    _displayText = value;
-  }
+  String? displayText;
 
   /// The offset of the start of the text to be replaced. If supplied, this
   /// should be used in preference to the offset provided on the containing
   /// completion results. This value may be provided independently of
   /// replacementLength (for example if only one differs from the completion
   /// result value).
-  int get replacementOffset => _replacementOffset;
-
-  /// The offset of the start of the text to be replaced. If supplied, this
-  /// should be used in preference to the offset provided on the containing
-  /// completion results. This value may be provided independently of
-  /// replacementLength (for example if only one differs from the completion
-  /// result value).
-  set replacementOffset(int value) {
-    _replacementOffset = value;
-  }
+  int? replacementOffset;
 
   /// The length of the text to be replaced. If supplied, this should be used
   /// in preference to the offset provided on the containing completion
   /// results. This value may be provided independently of replacementOffset
   /// (for example if only one differs from the completion result value).
-  int get replacementLength => _replacementLength;
-
-  /// The length of the text to be replaced. If supplied, this should be used
-  /// in preference to the offset provided on the containing completion
-  /// results. This value may be provided independently of replacementOffset
-  /// (for example if only one differs from the completion result value).
-  set replacementLength(int value) {
-    _replacementLength = value;
-  }
+  int? replacementLength;
 
   /// The offset, relative to the beginning of the completion, of where the
   /// selection should be placed after insertion.
-  int get selectionOffset => _selectionOffset;
-
-  /// The offset, relative to the beginning of the completion, of where the
-  /// selection should be placed after insertion.
-  set selectionOffset(int value) {
-    assert(value != null);
-    _selectionOffset = value;
-  }
+  int selectionOffset;
 
   /// The number of characters that should be selected after insertion.
-  int get selectionLength => _selectionLength;
-
-  /// The number of characters that should be selected after insertion.
-  set selectionLength(int value) {
-    assert(value != null);
-    _selectionLength = value;
-  }
+  int selectionLength;
 
   /// True if the suggested element is deprecated.
-  bool get isDeprecated => _isDeprecated;
-
-  /// True if the suggested element is deprecated.
-  set isDeprecated(bool value) {
-    assert(value != null);
-    _isDeprecated = value;
-  }
+  bool isDeprecated;
 
   /// True if the element is not known to be valid for the target. This happens
   /// if the type of the target is dynamic.
-  bool get isPotential => _isPotential;
-
-  /// True if the element is not known to be valid for the target. This happens
-  /// if the type of the target is dynamic.
-  set isPotential(bool value) {
-    assert(value != null);
-    _isPotential = value;
-  }
+  bool isPotential;
 
   /// An abbreviated version of the Dartdoc associated with the element being
   /// suggested. This field is omitted if there is no Dartdoc associated with
   /// the element.
-  String get docSummary => _docSummary;
-
-  /// An abbreviated version of the Dartdoc associated with the element being
-  /// suggested. This field is omitted if there is no Dartdoc associated with
-  /// the element.
-  set docSummary(String value) {
-    _docSummary = value;
-  }
+  String? docSummary;
 
   /// The Dartdoc associated with the element being suggested. This field is
   /// omitted if there is no Dartdoc associated with the element.
-  String get docComplete => _docComplete;
-
-  /// The Dartdoc associated with the element being suggested. This field is
-  /// omitted if there is no Dartdoc associated with the element.
-  set docComplete(String value) {
-    _docComplete = value;
-  }
+  String? docComplete;
 
   /// 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.
-  set declaringType(String value) {
-    _declaringType = value;
-  }
+  String? declaringType;
 
   /// A default String for use in generating argument list source contents on
   /// the client side.
-  String get defaultArgumentListString => _defaultArgumentListString;
-
-  /// A default String for use in generating argument list source contents on
-  /// the client side.
-  set defaultArgumentListString(String value) {
-    _defaultArgumentListString = value;
-  }
+  String? defaultArgumentListString;
 
   /// Pairs of offsets and lengths describing 'defaultArgumentListString' text
   /// ranges suitable for use by clients to set up linked edits of default
@@ -835,153 +583,69 @@
   /// y', the corresponding text range [0, 1, 3, 1], indicates two text ranges
   /// of length 1, starting at offsets 0 and 3. Clients can use these ranges to
   /// treat the 'x' and 'y' values specially for linked edits.
-  List<int> get defaultArgumentListTextRanges => _defaultArgumentListTextRanges;
-
-  /// Pairs of offsets and lengths describing 'defaultArgumentListString' text
-  /// ranges suitable for use by clients to set up linked edits of default
-  /// argument source contents. For example, given an argument list string 'x,
-  /// y', the corresponding text range [0, 1, 3, 1], indicates two text ranges
-  /// of length 1, starting at offsets 0 and 3. Clients can use these ranges to
-  /// treat the 'x' and 'y' values specially for linked edits.
-  set defaultArgumentListTextRanges(List<int> value) {
-    _defaultArgumentListTextRanges = value;
-  }
+  List<int>? defaultArgumentListTextRanges;
 
   /// Information about the element reference being suggested.
-  Element get element => _element;
-
-  /// Information about the element reference being suggested.
-  set element(Element value) {
-    _element = value;
-  }
+  Element? element;
 
   /// 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.
-  set returnType(String value) {
-    _returnType = value;
-  }
+  String? returnType;
 
   /// The names of the parameters of the function or method being suggested.
   /// This field is omitted if the suggested element is not a setter, function
   /// or method.
-  List<String> get parameterNames => _parameterNames;
-
-  /// The names of the parameters of the function or method being suggested.
-  /// This field is omitted if the suggested element is not a setter, function
-  /// or method.
-  set parameterNames(List<String> value) {
-    _parameterNames = value;
-  }
+  List<String>? parameterNames;
 
   /// The types of the parameters of the function or method being suggested.
   /// This field is omitted if the parameterNames field is omitted.
-  List<String> get parameterTypes => _parameterTypes;
-
-  /// The types of the parameters of the function or method being suggested.
-  /// This field is omitted if the parameterNames field is omitted.
-  set parameterTypes(List<String> value) {
-    _parameterTypes = value;
-  }
+  List<String>? parameterTypes;
 
   /// The number of required parameters for the function or method being
   /// suggested. This field is omitted if the parameterNames field is omitted.
-  int get requiredParameterCount => _requiredParameterCount;
-
-  /// The number of required parameters for the function or method being
-  /// suggested. This field is omitted if the parameterNames field is omitted.
-  set requiredParameterCount(int value) {
-    _requiredParameterCount = value;
-  }
+  int? requiredParameterCount;
 
   /// True if the function or method being suggested has at least one named
   /// parameter. This field is omitted if the parameterNames field is omitted.
-  bool get hasNamedParameters => _hasNamedParameters;
-
-  /// True if the function or method being suggested has at least one named
-  /// parameter. This field is omitted if the parameterNames field is omitted.
-  set hasNamedParameters(bool value) {
-    _hasNamedParameters = value;
-  }
+  bool? hasNamedParameters;
 
   /// The name of the optional parameter being suggested. This field is omitted
   /// if the suggestion is not the addition of an optional argument within an
   /// argument list.
-  String get parameterName => _parameterName;
-
-  /// The name of the optional parameter being suggested. This field is omitted
-  /// if the suggestion is not the addition of an optional argument within an
-  /// argument list.
-  set parameterName(String value) {
-    _parameterName = value;
-  }
+  String? parameterName;
 
   /// The type of the options parameter being suggested. This field is omitted
   /// if the parameterName field is omitted.
-  String get parameterType => _parameterType;
-
-  /// The type of the options parameter being suggested. This field is omitted
-  /// if the parameterName field is omitted.
-  set parameterType(String value) {
-    _parameterType = value;
-  }
+  String? parameterType;
 
   CompletionSuggestion(
-      CompletionSuggestionKind kind,
-      int relevance,
-      String completion,
-      int selectionOffset,
-      int selectionLength,
-      bool isDeprecated,
-      bool isPotential,
-      {String displayText,
-      int replacementOffset,
-      int replacementLength,
-      String docSummary,
-      String docComplete,
-      String declaringType,
-      String defaultArgumentListString,
-      List<int> defaultArgumentListTextRanges,
-      Element element,
-      String returnType,
-      List<String> parameterNames,
-      List<String> parameterTypes,
-      int requiredParameterCount,
-      bool hasNamedParameters,
-      String parameterName,
-      String parameterType}) {
-    this.kind = kind;
-    this.relevance = relevance;
-    this.completion = completion;
-    this.displayText = displayText;
-    this.replacementOffset = replacementOffset;
-    this.replacementLength = replacementLength;
-    this.selectionOffset = selectionOffset;
-    this.selectionLength = selectionLength;
-    this.isDeprecated = isDeprecated;
-    this.isPotential = isPotential;
-    this.docSummary = docSummary;
-    this.docComplete = docComplete;
-    this.declaringType = declaringType;
-    this.defaultArgumentListString = defaultArgumentListString;
-    this.defaultArgumentListTextRanges = defaultArgumentListTextRanges;
-    this.element = element;
-    this.returnType = returnType;
-    this.parameterNames = parameterNames;
-    this.parameterTypes = parameterTypes;
-    this.requiredParameterCount = requiredParameterCount;
-    this.hasNamedParameters = hasNamedParameters;
-    this.parameterName = parameterName;
-    this.parameterType = parameterType;
-  }
+      this.kind,
+      this.relevance,
+      this.completion,
+      this.selectionOffset,
+      this.selectionLength,
+      this.isDeprecated,
+      this.isPotential,
+      {this.displayText,
+      this.replacementOffset,
+      this.replacementLength,
+      this.docSummary,
+      this.docComplete,
+      this.declaringType,
+      this.defaultArgumentListString,
+      this.defaultArgumentListTextRanges,
+      this.element,
+      this.returnType,
+      this.parameterNames,
+      this.parameterTypes,
+      this.requiredParameterCount,
+      this.hasNamedParameters,
+      this.parameterName,
+      this.parameterType});
 
   factory CompletionSuggestion.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       CompletionSuggestionKind kind;
@@ -1005,17 +669,17 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'completion');
       }
-      String displayText;
+      String? displayText;
       if (json.containsKey('displayText')) {
         displayText = jsonDecoder.decodeString(
             jsonPath + '.displayText', json['displayText']);
       }
-      int replacementOffset;
+      int? replacementOffset;
       if (json.containsKey('replacementOffset')) {
         replacementOffset = jsonDecoder.decodeInt(
             jsonPath + '.replacementOffset', json['replacementOffset']);
       }
-      int replacementLength;
+      int? replacementLength;
       if (json.containsKey('replacementLength')) {
         replacementLength = jsonDecoder.decodeInt(
             jsonPath + '.replacementLength', json['replacementLength']);
@@ -1048,71 +712,71 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'isPotential');
       }
-      String docSummary;
+      String? docSummary;
       if (json.containsKey('docSummary')) {
         docSummary = jsonDecoder.decodeString(
             jsonPath + '.docSummary', json['docSummary']);
       }
-      String docComplete;
+      String? docComplete;
       if (json.containsKey('docComplete')) {
         docComplete = jsonDecoder.decodeString(
             jsonPath + '.docComplete', json['docComplete']);
       }
-      String declaringType;
+      String? declaringType;
       if (json.containsKey('declaringType')) {
         declaringType = jsonDecoder.decodeString(
             jsonPath + '.declaringType', json['declaringType']);
       }
-      String defaultArgumentListString;
+      String? defaultArgumentListString;
       if (json.containsKey('defaultArgumentListString')) {
         defaultArgumentListString = jsonDecoder.decodeString(
             jsonPath + '.defaultArgumentListString',
             json['defaultArgumentListString']);
       }
-      List<int> defaultArgumentListTextRanges;
+      List<int>? defaultArgumentListTextRanges;
       if (json.containsKey('defaultArgumentListTextRanges')) {
         defaultArgumentListTextRanges = jsonDecoder.decodeList(
             jsonPath + '.defaultArgumentListTextRanges',
             json['defaultArgumentListTextRanges'],
             jsonDecoder.decodeInt);
       }
-      Element element;
+      Element? element;
       if (json.containsKey('element')) {
         element = Element.fromJson(
             jsonDecoder, jsonPath + '.element', json['element']);
       }
-      String returnType;
+      String? returnType;
       if (json.containsKey('returnType')) {
         returnType = jsonDecoder.decodeString(
             jsonPath + '.returnType', json['returnType']);
       }
-      List<String> parameterNames;
+      List<String>? parameterNames;
       if (json.containsKey('parameterNames')) {
         parameterNames = jsonDecoder.decodeList(jsonPath + '.parameterNames',
             json['parameterNames'], jsonDecoder.decodeString);
       }
-      List<String> parameterTypes;
+      List<String>? parameterTypes;
       if (json.containsKey('parameterTypes')) {
         parameterTypes = jsonDecoder.decodeList(jsonPath + '.parameterTypes',
             json['parameterTypes'], jsonDecoder.decodeString);
       }
-      int requiredParameterCount;
+      int? requiredParameterCount;
       if (json.containsKey('requiredParameterCount')) {
         requiredParameterCount = jsonDecoder.decodeInt(
             jsonPath + '.requiredParameterCount',
             json['requiredParameterCount']);
       }
-      bool hasNamedParameters;
+      bool? hasNamedParameters;
       if (json.containsKey('hasNamedParameters')) {
         hasNamedParameters = jsonDecoder.decodeBool(
             jsonPath + '.hasNamedParameters', json['hasNamedParameters']);
       }
-      String parameterName;
+      String? parameterName;
       if (json.containsKey('parameterName')) {
         parameterName = jsonDecoder.decodeString(
             jsonPath + '.parameterName', json['parameterName']);
       }
-      String parameterType;
+      String? parameterType;
       if (json.containsKey('parameterType')) {
         parameterType = jsonDecoder.decodeString(
             jsonPath + '.parameterType', json['parameterType']);
@@ -1141,17 +805,20 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['kind'] = kind.toJson();
     result['relevance'] = relevance;
     result['completion'] = completion;
+    var displayText = this.displayText;
     if (displayText != null) {
       result['displayText'] = displayText;
     }
+    var replacementOffset = this.replacementOffset;
     if (replacementOffset != null) {
       result['replacementOffset'] = replacementOffset;
     }
+    var replacementLength = this.replacementLength;
     if (replacementLength != null) {
       result['replacementLength'] = replacementLength;
     }
@@ -1159,42 +826,55 @@
     result['selectionLength'] = selectionLength;
     result['isDeprecated'] = isDeprecated;
     result['isPotential'] = isPotential;
+    var docSummary = this.docSummary;
     if (docSummary != null) {
       result['docSummary'] = docSummary;
     }
+    var docComplete = this.docComplete;
     if (docComplete != null) {
       result['docComplete'] = docComplete;
     }
+    var declaringType = this.declaringType;
     if (declaringType != null) {
       result['declaringType'] = declaringType;
     }
+    var defaultArgumentListString = this.defaultArgumentListString;
     if (defaultArgumentListString != null) {
       result['defaultArgumentListString'] = defaultArgumentListString;
     }
+    var defaultArgumentListTextRanges = this.defaultArgumentListTextRanges;
     if (defaultArgumentListTextRanges != null) {
       result['defaultArgumentListTextRanges'] = defaultArgumentListTextRanges;
     }
+    var element = this.element;
     if (element != null) {
       result['element'] = element.toJson();
     }
+    var returnType = this.returnType;
     if (returnType != null) {
       result['returnType'] = returnType;
     }
+    var parameterNames = this.parameterNames;
     if (parameterNames != null) {
       result['parameterNames'] = parameterNames;
     }
+    var parameterTypes = this.parameterTypes;
     if (parameterTypes != null) {
       result['parameterTypes'] = parameterTypes;
     }
+    var requiredParameterCount = this.requiredParameterCount;
     if (requiredParameterCount != null) {
       result['requiredParameterCount'] = requiredParameterCount;
     }
+    var hasNamedParameters = this.hasNamedParameters;
     if (hasNamedParameters != null) {
       result['hasNamedParameters'] = hasNamedParameters;
     }
+    var parameterName = this.parameterName;
     if (parameterName != null) {
       result['parameterName'] = parameterName;
     }
+    var parameterType = this.parameterType;
     if (parameterType != null) {
       result['parameterType'] = parameterType;
     }
@@ -1380,7 +1060,7 @@
   }
 
   factory CompletionSuggestionKind.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     if (json is String) {
       try {
         return CompletionSuggestionKind(json);
@@ -1406,37 +1086,17 @@
 ///
 /// 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;
-  }
+  String message;
 
   /// The location associated with or referenced by the message. Clients should
   /// provide the ability to navigate to the location.
-  Location get location => _location;
+  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;
-  }
+  DiagnosticMessage(this.message, this.location);
 
   factory DiagnosticMessage.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String message;
@@ -1460,8 +1120,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['message'] = message;
     result['location'] = location.toJson();
     return result;
@@ -1526,49 +1186,15 @@
     return flags;
   }
 
-  ElementKind _kind;
-
-  String _name;
-
-  Location _location;
-
-  int _flags;
-
-  String _parameters;
-
-  String _returnType;
-
-  String _typeParameters;
-
-  String _aliasedType;
-
   /// The kind of the element.
-  ElementKind get kind => _kind;
-
-  /// The kind of the element.
-  set kind(ElementKind value) {
-    assert(value != null);
-    _kind = value;
-  }
+  ElementKind kind;
 
   /// The name of the element. This is typically used as the label in the
   /// outline.
-  String get name => _name;
-
-  /// The name of the element. This is typically used as the label in the
-  /// outline.
-  set name(String value) {
-    assert(value != null);
-    _name = value;
-  }
+  String name;
 
   /// The location of the name in the declaration of the element.
-  Location get location => _location;
-
-  /// The location of the name in the declaration of the element.
-  set location(Location value) {
-    _location = value;
-  }
+  Location? location;
 
   /// A bit-map containing the following flags:
   ///
@@ -1579,86 +1205,36 @@
   ///   top-level function or field
   /// - 0x10 - set if the element is private
   /// - 0x20 - set if the element is deprecated
-  int get flags => _flags;
-
-  /// A bit-map containing the following flags:
-  ///
-  /// - 0x01 - set if the element is explicitly or implicitly abstract
-  /// - 0x02 - set if the element was declared to be ‘const’
-  /// - 0x04 - set if the element was declared to be ‘final’
-  /// - 0x08 - set if the element is a static member of a class or is a
-  ///   top-level function or field
-  /// - 0x10 - set if the element is private
-  /// - 0x20 - set if the element is deprecated
-  set flags(int value) {
-    assert(value != null);
-    _flags = value;
-  }
+  int flags;
 
   /// The parameter list for the element. If the element is not a method or
   /// function this field will not be defined. If the element doesn't have
   /// parameters (e.g. getter), this field will not be defined. If the element
   /// has zero parameters, this field will have a value of "()".
-  String get parameters => _parameters;
-
-  /// The parameter list for the element. If the element is not a method or
-  /// function this field will not be defined. If the element doesn't have
-  /// parameters (e.g. getter), this field will not be defined. If the element
-  /// has zero parameters, this field will have a value of "()".
-  set parameters(String value) {
-    _parameters = value;
-  }
+  String? parameters;
 
   /// 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.
-  set returnType(String value) {
-    _returnType = value;
-  }
+  String? returnType;
 
   /// The type parameter list for the element. If the element doesn't have type
   /// parameters, this field will not be defined.
-  String get typeParameters => _typeParameters;
-
-  /// The type parameter list for the element. If the element doesn't have type
-  /// parameters, this field will not be defined.
-  set typeParameters(String value) {
-    _typeParameters = value;
-  }
+  String? typeParameters;
 
   /// If the element is a type alias, this field is the aliased type. Otherwise
   /// this field will not be defined.
-  String get aliasedType => _aliasedType;
+  String? aliasedType;
 
-  /// If the element is a type alias, this field is the aliased type. Otherwise
-  /// this field will not be defined.
-  set aliasedType(String value) {
-    _aliasedType = value;
-  }
-
-  Element(ElementKind kind, String name, int flags,
-      {Location location,
-      String parameters,
-      String returnType,
-      String typeParameters,
-      String aliasedType}) {
-    this.kind = kind;
-    this.name = name;
-    this.location = location;
-    this.flags = flags;
-    this.parameters = parameters;
-    this.returnType = returnType;
-    this.typeParameters = typeParameters;
-    this.aliasedType = aliasedType;
-  }
+  Element(this.kind, this.name, this.flags,
+      {this.location,
+      this.parameters,
+      this.returnType,
+      this.typeParameters,
+      this.aliasedType});
 
   factory Element.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       ElementKind kind;
@@ -1674,7 +1250,7 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'name');
       }
-      Location location;
+      Location? location;
       if (json.containsKey('location')) {
         location = Location.fromJson(
             jsonDecoder, jsonPath + '.location', json['location']);
@@ -1685,22 +1261,22 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'flags');
       }
-      String parameters;
+      String? parameters;
       if (json.containsKey('parameters')) {
         parameters = jsonDecoder.decodeString(
             jsonPath + '.parameters', json['parameters']);
       }
-      String returnType;
+      String? returnType;
       if (json.containsKey('returnType')) {
         returnType = jsonDecoder.decodeString(
             jsonPath + '.returnType', json['returnType']);
       }
-      String typeParameters;
+      String? typeParameters;
       if (json.containsKey('typeParameters')) {
         typeParameters = jsonDecoder.decodeString(
             jsonPath + '.typeParameters', json['typeParameters']);
       }
-      String aliasedType;
+      String? aliasedType;
       if (json.containsKey('aliasedType')) {
         aliasedType = jsonDecoder.decodeString(
             jsonPath + '.aliasedType', json['aliasedType']);
@@ -1724,23 +1300,28 @@
   bool get isDeprecated => (flags & FLAG_DEPRECATED) != 0;
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['kind'] = kind.toJson();
     result['name'] = name;
+    var location = this.location;
     if (location != null) {
       result['location'] = location.toJson();
     }
     result['flags'] = flags;
+    var parameters = this.parameters;
     if (parameters != null) {
       result['parameters'] = parameters;
     }
+    var returnType = this.returnType;
     if (returnType != null) {
       result['returnType'] = returnType;
     }
+    var typeParameters = this.typeParameters;
     if (typeParameters != null) {
       result['typeParameters'] = typeParameters;
     }
+    var aliasedType = this.aliasedType;
     if (aliasedType != null) {
       result['aliasedType'] = aliasedType;
     }
@@ -1975,7 +1556,7 @@
   }
 
   factory ElementKind.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     if (json is String) {
       try {
         return ElementKind(json);
@@ -2076,7 +1657,7 @@
   }
 
   factory FoldingKind.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     if (json is String) {
       try {
         return FoldingKind(json);
@@ -2103,47 +1684,19 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class FoldingRegion implements HasToJson {
-  FoldingKind _kind;
-
-  int _offset;
-
-  int _length;
-
   /// The kind of the region.
-  FoldingKind get kind => _kind;
-
-  /// The kind of the region.
-  set kind(FoldingKind value) {
-    assert(value != null);
-    _kind = value;
-  }
+  FoldingKind kind;
 
   /// The offset of the region to be folded.
-  int get offset => _offset;
-
-  /// The offset of the region to be folded.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
+  int offset;
 
   /// The length of the region to be folded.
-  int get length => _length;
+  int length;
 
-  /// The length of the region to be folded.
-  set length(int value) {
-    assert(value != null);
-    _length = value;
-  }
-
-  FoldingRegion(FoldingKind kind, int offset, int length) {
-    this.kind = kind;
-    this.offset = offset;
-    this.length = length;
-  }
+  FoldingRegion(this.kind, this.offset, this.length);
 
   factory FoldingRegion.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       FoldingKind kind;
@@ -2172,8 +1725,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['kind'] = kind.toJson();
     result['offset'] = offset;
     result['length'] = length;
@@ -2213,47 +1766,19 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class HighlightRegion implements HasToJson {
-  HighlightRegionType _type;
-
-  int _offset;
-
-  int _length;
-
   /// The type of highlight associated with the region.
-  HighlightRegionType get type => _type;
-
-  /// The type of highlight associated with the region.
-  set type(HighlightRegionType value) {
-    assert(value != null);
-    _type = value;
-  }
+  HighlightRegionType type;
 
   /// The offset of the region to be highlighted.
-  int get offset => _offset;
-
-  /// The offset of the region to be highlighted.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
+  int offset;
 
   /// The length of the region to be highlighted.
-  int get length => _length;
+  int length;
 
-  /// The length of the region to be highlighted.
-  set length(int value) {
-    assert(value != null);
-    _length = value;
-  }
-
-  HighlightRegion(HighlightRegionType type, int offset, int length) {
-    this.type = type;
-    this.offset = offset;
-    this.length = length;
-  }
+  HighlightRegion(this.type, this.offset, this.length);
 
   factory HighlightRegion.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       HighlightRegionType type;
@@ -2282,8 +1807,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['type'] = type.toJson();
     result['offset'] = offset;
     result['length'] = length;
@@ -2860,7 +2385,7 @@
   }
 
   factory HighlightRegionType.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     if (json is String) {
       try {
         return HighlightRegionType(json);
@@ -2889,69 +2414,25 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class KytheEntry implements HasToJson {
-  KytheVName _source;
-
-  String _kind;
-
-  KytheVName _target;
-
-  String _fact;
-
-  List<int> _value;
-
   /// The ticket of the source node.
-  KytheVName get source => _source;
-
-  /// The ticket of the source node.
-  set source(KytheVName value) {
-    assert(value != null);
-    _source = value;
-  }
+  KytheVName source;
 
   /// An edge label. The schema defines which labels are meaningful.
-  String get kind => _kind;
-
-  /// An edge label. The schema defines which labels are meaningful.
-  set kind(String value) {
-    _kind = value;
-  }
+  String? kind;
 
   /// The ticket of the target node.
-  KytheVName get target => _target;
-
-  /// The ticket of the target node.
-  set target(KytheVName value) {
-    _target = value;
-  }
+  KytheVName? target;
 
   /// A fact label. The schema defines which fact labels are meaningful.
-  String get fact => _fact;
-
-  /// A fact label. The schema defines which fact labels are meaningful.
-  set fact(String value) {
-    assert(value != null);
-    _fact = value;
-  }
+  String fact;
 
   /// The String value of the fact.
-  List<int> get value => _value;
+  List<int>? value;
 
-  /// The String value of the fact.
-  set value(List<int> value) {
-    _value = value;
-  }
-
-  KytheEntry(KytheVName source, String fact,
-      {String kind, KytheVName target, List<int> value}) {
-    this.source = source;
-    this.kind = kind;
-    this.target = target;
-    this.fact = fact;
-    this.value = value;
-  }
+  KytheEntry(this.source, this.fact, {this.kind, this.target, this.value});
 
   factory KytheEntry.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       KytheVName source;
@@ -2961,11 +2442,11 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'source');
       }
-      String kind;
+      String? kind;
       if (json.containsKey('kind')) {
         kind = jsonDecoder.decodeString(jsonPath + '.kind', json['kind']);
       }
-      KytheVName target;
+      KytheVName? target;
       if (json.containsKey('target')) {
         target = KytheVName.fromJson(
             jsonDecoder, jsonPath + '.target', json['target']);
@@ -2976,7 +2457,7 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'fact');
       }
-      List<int> value;
+      List<int>? value;
       if (json.containsKey('value')) {
         value = jsonDecoder.decodeList(
             jsonPath + '.value', json['value'], jsonDecoder.decodeInt);
@@ -2988,16 +2469,19 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['source'] = source.toJson();
+    var kind = this.kind;
     if (kind != null) {
       result['kind'] = kind;
     }
+    var target = this.target;
     if (target != null) {
       result['target'] = target.toJson();
     }
     result['fact'] = fact;
+    var value = this.value;
     if (value != null) {
       result['value'] = value;
     }
@@ -3043,82 +2527,30 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class KytheVName implements HasToJson {
-  String _signature;
-
-  String _corpus;
-
-  String _root;
-
-  String _path;
-
-  String _language;
-
   /// An opaque signature generated by the analyzer.
-  String get signature => _signature;
-
-  /// An opaque signature generated by the analyzer.
-  set signature(String value) {
-    assert(value != null);
-    _signature = value;
-  }
+  String signature;
 
   /// 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
-  /// repository.
-  set corpus(String value) {
-    assert(value != null);
-    _corpus = value;
-  }
+  String corpus;
 
   /// A corpus-specific root label, typically a directory path or project
   /// identifier, denoting a distinct subset of the corpus. This may also be
   /// used to designate virtual collections like generated files.
-  String get root => _root;
-
-  /// A corpus-specific root label, typically a directory path or project
-  /// identifier, denoting a distinct subset of the corpus. This may also be
-  /// used to designate virtual collections like generated files.
-  set root(String value) {
-    assert(value != null);
-    _root = value;
-  }
+  String root;
 
   /// A path-structured label describing the “location” of the named object
   /// relative to the corpus and the root.
-  String get path => _path;
-
-  /// A path-structured label describing the “location” of the named object
-  /// relative to the corpus and the root.
-  set path(String value) {
-    assert(value != null);
-    _path = value;
-  }
+  String path;
 
   /// The language this name belongs to.
-  String get language => _language;
+  String language;
 
-  /// The language this name belongs to.
-  set language(String value) {
-    assert(value != null);
-    _language = value;
-  }
-
-  KytheVName(String signature, String corpus, String root, String path,
-      String language) {
-    this.signature = signature;
-    this.corpus = corpus;
-    this.root = root;
-    this.path = path;
-    this.language = language;
-  }
+  KytheVName(this.signature, this.corpus, this.root, this.path, this.language);
 
   factory KytheVName.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String signature;
@@ -3160,8 +2592,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['signature'] = signature;
     result['corpus'] = corpus;
     result['root'] = root;
@@ -3207,50 +2639,20 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class LinkedEditGroup implements HasToJson {
-  List<Position> _positions;
-
-  int _length;
-
-  List<LinkedEditSuggestion> _suggestions;
-
   /// The positions of the regions that should be edited simultaneously.
-  List<Position> get positions => _positions;
-
-  /// The positions of the regions that should be edited simultaneously.
-  set positions(List<Position> value) {
-    assert(value != null);
-    _positions = value;
-  }
+  List<Position> positions;
 
   /// The length of the regions that should be edited simultaneously.
-  int get length => _length;
-
-  /// The length of the regions that should be edited simultaneously.
-  set length(int value) {
-    assert(value != null);
-    _length = value;
-  }
+  int length;
 
   /// Pre-computed suggestions for what every region might want to be changed
   /// to.
-  List<LinkedEditSuggestion> get suggestions => _suggestions;
+  List<LinkedEditSuggestion> suggestions;
 
-  /// Pre-computed suggestions for what every region might want to be changed
-  /// to.
-  set suggestions(List<LinkedEditSuggestion> value) {
-    assert(value != null);
-    _suggestions = value;
-  }
-
-  LinkedEditGroup(List<Position> positions, int length,
-      List<LinkedEditSuggestion> suggestions) {
-    this.positions = positions;
-    this.length = length;
-    this.suggestions = suggestions;
-  }
+  LinkedEditGroup(this.positions, this.length, this.suggestions);
 
   factory LinkedEditGroup.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       List<Position> positions;
@@ -3258,7 +2660,7 @@
         positions = jsonDecoder.decodeList(
             jsonPath + '.positions',
             json['positions'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 Position.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'positions');
@@ -3274,7 +2676,7 @@
         suggestions = jsonDecoder.decodeList(
             jsonPath + '.suggestions',
             json['suggestions'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 LinkedEditSuggestion.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'suggestions');
@@ -3289,8 +2691,8 @@
   LinkedEditGroup.empty() : this(<Position>[], 0, <LinkedEditSuggestion>[]);
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['positions'] =
         positions.map((Position value) => value.toJson()).toList();
     result['length'] = length;
@@ -3345,35 +2747,16 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class LinkedEditSuggestion implements HasToJson {
-  String _value;
-
-  LinkedEditSuggestionKind _kind;
-
   /// The value that could be used to replace all of the linked edit regions.
-  String get value => _value;
-
-  /// The value that could be used to replace all of the linked edit regions.
-  set value(String value) {
-    assert(value != null);
-    _value = value;
-  }
+  String value;
 
   /// The kind of value being proposed.
-  LinkedEditSuggestionKind get kind => _kind;
+  LinkedEditSuggestionKind kind;
 
-  /// The kind of value being proposed.
-  set kind(LinkedEditSuggestionKind value) {
-    assert(value != null);
-    _kind = value;
-  }
-
-  LinkedEditSuggestion(String value, LinkedEditSuggestionKind kind) {
-    this.value = value;
-    this.kind = kind;
-  }
+  LinkedEditSuggestion(this.value, this.kind);
 
   factory LinkedEditSuggestion.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String value;
@@ -3396,8 +2779,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['value'] = value;
     result['kind'] = kind.toJson();
     return result;
@@ -3470,7 +2853,7 @@
   }
 
   factory LinkedEditSuggestionKind.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     if (json is String) {
       try {
         return LinkedEditSuggestionKind(json);
@@ -3495,80 +2878,42 @@
 ///   "length": int
 ///   "startLine": int
 ///   "startColumn": int
+///   "endLine": int
+///   "endColumn": int
 /// }
 ///
 /// Clients may not extend, implement or mix-in this class.
 class Location implements HasToJson {
-  String _file;
-
-  int _offset;
-
-  int _length;
-
-  int _startLine;
-
-  int _startColumn;
-
   /// The file containing the range.
-  String get file => _file;
-
-  /// The file containing the range.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// The offset of the range.
-  int get offset => _offset;
-
-  /// The offset of the range.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
+  int offset;
 
   /// The length of the range.
-  int get length => _length;
-
-  /// The length of the range.
-  set length(int value) {
-    assert(value != null);
-    _length = value;
-  }
+  int length;
 
   /// The one-based index of the line containing the first character of the
   /// range.
-  int get startLine => _startLine;
-
-  /// The one-based index of the line containing the first character of the
-  /// range.
-  set startLine(int value) {
-    assert(value != null);
-    _startLine = value;
-  }
+  int startLine;
 
   /// The one-based index of the column containing the first character of the
   /// range.
-  int get startColumn => _startColumn;
+  int startColumn;
 
-  /// The one-based index of the column containing the first character of the
-  /// range.
-  set startColumn(int value) {
-    assert(value != null);
-    _startColumn = value;
-  }
+  /// The one-based index of the line containing the character immediately
+  /// following the range.
+  int endLine;
 
-  Location(
-      String file, int offset, int length, int startLine, int startColumn) {
-    this.file = file;
-    this.offset = offset;
-    this.length = length;
-    this.startLine = startLine;
-    this.startColumn = startColumn;
-  }
+  /// The one-based index of the column containing the character immediately
+  /// following the range.
+  int endColumn;
+
+  Location(this.file, this.offset, this.length, this.startLine,
+      this.startColumn, this.endLine, this.endColumn);
 
   factory Location.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -3603,20 +2948,36 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'startColumn');
       }
-      return Location(file, offset, length, startLine, startColumn);
+      int endLine;
+      if (json.containsKey('endLine')) {
+        endLine = jsonDecoder.decodeInt(jsonPath + '.endLine', json['endLine']);
+      } else {
+        throw jsonDecoder.mismatch(jsonPath, 'endLine');
+      }
+      int endColumn;
+      if (json.containsKey('endColumn')) {
+        endColumn =
+            jsonDecoder.decodeInt(jsonPath + '.endColumn', json['endColumn']);
+      } else {
+        throw jsonDecoder.mismatch(jsonPath, 'endColumn');
+      }
+      return Location(
+          file, offset, length, startLine, startColumn, endLine, endColumn);
     } else {
       throw jsonDecoder.mismatch(jsonPath, 'Location', json);
     }
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     result['offset'] = offset;
     result['length'] = length;
     result['startLine'] = startLine;
     result['startColumn'] = startColumn;
+    result['endLine'] = endLine;
+    result['endColumn'] = endColumn;
     return result;
   }
 
@@ -3630,7 +2991,9 @@
           offset == other.offset &&
           length == other.length &&
           startLine == other.startLine &&
-          startColumn == other.startColumn;
+          startColumn == other.startColumn &&
+          endLine == other.endLine &&
+          endColumn == other.endColumn;
     }
     return false;
   }
@@ -3643,6 +3006,8 @@
     hash = JenkinsSmiHash.combine(hash, length.hashCode);
     hash = JenkinsSmiHash.combine(hash, startLine.hashCode);
     hash = JenkinsSmiHash.combine(hash, startColumn.hashCode);
+    hash = JenkinsSmiHash.combine(hash, endLine.hashCode);
+    hash = JenkinsSmiHash.combine(hash, endColumn.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
 }
@@ -3657,51 +3022,21 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class NavigationRegion implements HasToJson {
-  int _offset;
-
-  int _length;
-
-  List<int> _targets;
-
   /// The offset of the region from which the user can navigate.
-  int get offset => _offset;
-
-  /// The offset of the region from which the user can navigate.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
+  int offset;
 
   /// The length of the region from which the user can navigate.
-  int get length => _length;
-
-  /// The length of the region from which the user can navigate.
-  set length(int value) {
-    assert(value != null);
-    _length = value;
-  }
+  int length;
 
   /// 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;
+  List<int> 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.
-  set targets(List<int> value) {
-    assert(value != null);
-    _targets = value;
-  }
-
-  NavigationRegion(int offset, int length, List<int> targets) {
-    this.offset = offset;
-    this.length = length;
-    this.targets = targets;
-  }
+  NavigationRegion(this.offset, this.length, this.targets);
 
   factory NavigationRegion.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       int offset;
@@ -3730,8 +3065,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['offset'] = offset;
     result['length'] = length;
     result['targets'] = targets;
@@ -3776,113 +3111,39 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class NavigationTarget implements HasToJson {
-  ElementKind _kind;
-
-  int _fileIndex;
-
-  int _offset;
-
-  int _length;
-
-  int _startLine;
-
-  int _startColumn;
-
-  int _codeOffset;
-
-  int _codeLength;
-
   /// The kind of the element.
-  ElementKind get kind => _kind;
-
-  /// The kind of the element.
-  set kind(ElementKind value) {
-    assert(value != null);
-    _kind = value;
-  }
+  ElementKind kind;
 
   /// The index of the file (in the enclosing navigation response) to navigate
   /// to.
-  int get fileIndex => _fileIndex;
-
-  /// The index of the file (in the enclosing navigation response) to navigate
-  /// to.
-  set fileIndex(int value) {
-    assert(value != null);
-    _fileIndex = value;
-  }
+  int fileIndex;
 
   /// The offset of the name of the target to which the user can navigate.
-  int get offset => _offset;
-
-  /// The offset of the name of the target to which the user can navigate.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
+  int offset;
 
   /// The length of the name of the target to which the user can navigate.
-  int get length => _length;
-
-  /// The length of the name of the target to which the user can navigate.
-  set length(int value) {
-    assert(value != null);
-    _length = value;
-  }
+  int length;
 
   /// The one-based index of the line containing the first character of the
   /// name of the target.
-  int get startLine => _startLine;
-
-  /// The one-based index of the line containing the first character of the
-  /// name of the target.
-  set startLine(int value) {
-    assert(value != null);
-    _startLine = value;
-  }
+  int startLine;
 
   /// The one-based index of the column containing the first character of the
   /// name of the target.
-  int get startColumn => _startColumn;
-
-  /// The one-based index of the column containing the first character of the
-  /// name of the target.
-  set startColumn(int value) {
-    assert(value != null);
-    _startColumn = value;
-  }
+  int startColumn;
 
   /// 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;
-  }
+  int? codeOffset;
 
   /// The length of the target code to which the user can navigate.
-  int get codeLength => _codeLength;
+  int? 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 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;
-  }
+  NavigationTarget(this.kind, this.fileIndex, this.offset, this.length,
+      this.startLine, this.startColumn,
+      {this.codeOffset, this.codeLength});
 
   factory NavigationTarget.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       ElementKind kind;
@@ -3925,12 +3186,12 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'startColumn');
       }
-      int codeOffset;
+      int? codeOffset;
       if (json.containsKey('codeOffset')) {
         codeOffset =
             jsonDecoder.decodeInt(jsonPath + '.codeOffset', json['codeOffset']);
       }
-      int codeLength;
+      int? codeLength;
       if (json.containsKey('codeLength')) {
         codeLength =
             jsonDecoder.decodeInt(jsonPath + '.codeLength', json['codeLength']);
@@ -3944,17 +3205,19 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['kind'] = kind.toJson();
     result['fileIndex'] = fileIndex;
     result['offset'] = offset;
     result['length'] = length;
     result['startLine'] = startLine;
     result['startColumn'] = startColumn;
+    var codeOffset = this.codeOffset;
     if (codeOffset != null) {
       result['codeOffset'] = codeOffset;
     }
+    var codeLength = this.codeLength;
     if (codeLength != null) {
       result['codeLength'] = codeLength;
     }
@@ -4004,47 +3267,19 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class Occurrences implements HasToJson {
-  Element _element;
-
-  List<int> _offsets;
-
-  int _length;
-
   /// The element that was referenced.
-  Element get element => _element;
-
-  /// The element that was referenced.
-  set element(Element value) {
-    assert(value != null);
-    _element = value;
-  }
+  Element element;
 
   /// The offsets of the name of the referenced element within the file.
-  List<int> get offsets => _offsets;
-
-  /// The offsets of the name of the referenced element within the file.
-  set offsets(List<int> value) {
-    assert(value != null);
-    _offsets = value;
-  }
+  List<int> offsets;
 
   /// The length of the name of the referenced element.
-  int get length => _length;
+  int length;
 
-  /// The length of the name of the referenced element.
-  set length(int value) {
-    assert(value != null);
-    _length = value;
-  }
-
-  Occurrences(Element element, List<int> offsets, int length) {
-    this.element = element;
-    this.offsets = offsets;
-    this.length = length;
-  }
+  Occurrences(this.element, this.offsets, this.length);
 
   factory Occurrences.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       Element element;
@@ -4074,8 +3309,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['element'] = element.toJson();
     result['offsets'] = offsets;
     result['length'] = length;
@@ -4118,94 +3353,35 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class Outline implements HasToJson {
-  Element _element;
-
-  int _offset;
-
-  int _length;
-
-  int _codeOffset;
-
-  int _codeLength;
-
-  List<Outline> _children;
-
   /// A description of the element represented by this node.
-  Element get element => _element;
-
-  /// A description of the element represented by this node.
-  set element(Element value) {
-    assert(value != null);
-    _element = value;
-  }
+  Element element;
 
   /// 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.
-  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.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
+  int offset;
 
   /// The length of the element.
-  int get length => _length;
-
-  /// The length of the element.
-  set length(int value) {
-    assert(value != null);
-    _length = value;
-  }
+  int length;
 
   /// The offset of the first character of the element code, which is neither
   /// documentation, nor annotation.
-  int get codeOffset => _codeOffset;
-
-  /// The offset of the first character of the element code, which is neither
-  /// documentation, nor annotation.
-  set codeOffset(int value) {
-    assert(value != null);
-    _codeOffset = value;
-  }
+  int codeOffset;
 
   /// The length of the element code.
-  int get codeLength => _codeLength;
-
-  /// The length of the element code.
-  set codeLength(int value) {
-    assert(value != null);
-    _codeLength = value;
-  }
+  int codeLength;
 
   /// The children of the node. The field will be omitted if the node has no
   /// children. Children are sorted by offset.
-  List<Outline> get children => _children;
-
-  /// The children of the node. The field will be omitted if the node has no
-  /// children. Children are sorted by offset.
-  set children(List<Outline> value) {
-    _children = value;
-  }
+  List<Outline>? children;
 
   Outline(
-      Element element, int offset, int length, int codeOffset, int codeLength,
-      {List<Outline> children}) {
-    this.element = element;
-    this.offset = offset;
-    this.length = length;
-    this.codeOffset = codeOffset;
-    this.codeLength = codeLength;
-    this.children = children;
-  }
+      this.element, this.offset, this.length, this.codeOffset, this.codeLength,
+      {this.children});
 
   factory Outline.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       Element element;
@@ -4241,12 +3417,12 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'codeLength');
       }
-      List<Outline> children;
+      List<Outline>? children;
       if (json.containsKey('children')) {
         children = jsonDecoder.decodeList(
             jsonPath + '.children',
             json['children'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 Outline.fromJson(jsonDecoder, jsonPath, json));
       }
       return Outline(element, offset, length, codeOffset, codeLength,
@@ -4257,13 +3433,14 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['element'] = element.toJson();
     result['offset'] = offset;
     result['length'] = length;
     result['codeOffset'] = codeOffset;
     result['codeLength'] = codeLength;
+    var children = this.children;
     if (children != null) {
       result['children'] =
           children.map((Outline value) => value.toJson()).toList();
@@ -4311,61 +3488,23 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class ParameterInfo implements HasToJson {
-  ParameterKind _kind;
-
-  String _name;
-
-  String _type;
-
-  String _defaultValue;
-
   /// The kind of the parameter.
-  ParameterKind get kind => _kind;
-
-  /// The kind of the parameter.
-  set kind(ParameterKind value) {
-    assert(value != null);
-    _kind = value;
-  }
+  ParameterKind kind;
 
   /// The name of the parameter.
-  String get name => _name;
-
-  /// The name of the parameter.
-  set name(String value) {
-    assert(value != null);
-    _name = value;
-  }
+  String name;
 
   /// The type of the parameter.
-  String get type => _type;
-
-  /// The type of the parameter.
-  set type(String value) {
-    assert(value != null);
-    _type = value;
-  }
+  String type;
 
   /// The default value for this parameter. This value will be omitted if the
   /// parameter does not have a default value.
-  String get defaultValue => _defaultValue;
+  String? defaultValue;
 
-  /// The default value for this parameter. This value will be omitted if the
-  /// parameter does not have a default value.
-  set defaultValue(String value) {
-    _defaultValue = value;
-  }
-
-  ParameterInfo(ParameterKind kind, String name, String type,
-      {String defaultValue}) {
-    this.kind = kind;
-    this.name = name;
-    this.type = type;
-    this.defaultValue = defaultValue;
-  }
+  ParameterInfo(this.kind, this.name, this.type, {this.defaultValue});
 
   factory ParameterInfo.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       ParameterKind kind;
@@ -4387,7 +3526,7 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'type');
       }
-      String defaultValue;
+      String? defaultValue;
       if (json.containsKey('defaultValue')) {
         defaultValue = jsonDecoder.decodeString(
             jsonPath + '.defaultValue', json['defaultValue']);
@@ -4399,11 +3538,12 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['kind'] = kind.toJson();
     result['name'] = name;
     result['type'] = type;
+    var defaultValue = this.defaultValue;
     if (defaultValue != null) {
       result['defaultValue'] = defaultValue;
     }
@@ -4488,7 +3628,7 @@
   }
 
   factory ParameterKind.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     if (json is String) {
       try {
         return ParameterKind(json);
@@ -4514,35 +3654,16 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class Position implements HasToJson {
-  String _file;
-
-  int _offset;
-
   /// The file containing the position.
-  String get file => _file;
-
-  /// The file containing the position.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// The offset of the position.
-  int get offset => _offset;
+  int offset;
 
-  /// The offset of the position.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
-
-  Position(String file, int offset) {
-    this.file = file;
-    this.offset = offset;
-  }
+  Position(this.file, this.offset);
 
   factory Position.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -4564,8 +3685,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     result['offset'] = offset;
     return result;
@@ -4675,7 +3796,7 @@
   }
 
   factory RefactoringKind.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     if (json is String) {
       try {
         return RefactoringKind(json);
@@ -4704,82 +3825,33 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class RefactoringMethodParameter implements HasToJson {
-  String _id;
-
-  RefactoringMethodParameterKind _kind;
-
-  String _type;
-
-  String _name;
-
-  String _parameters;
-
   /// The unique identifier of the parameter. Clients may omit this field for
   /// the parameters they want to add.
-  String get id => _id;
-
-  /// The unique identifier of the parameter. Clients may omit this field for
-  /// the parameters they want to add.
-  set id(String value) {
-    _id = value;
-  }
+  String? id;
 
   /// The kind of the parameter.
-  RefactoringMethodParameterKind get kind => _kind;
-
-  /// The kind of the parameter.
-  set kind(RefactoringMethodParameterKind value) {
-    assert(value != null);
-    _kind = value;
-  }
+  RefactoringMethodParameterKind kind;
 
   /// The type that should be given to the parameter, or the return type of the
   /// parameter's function type.
-  String get type => _type;
-
-  /// The type that should be given to the parameter, or the return type of the
-  /// parameter's function type.
-  set type(String value) {
-    assert(value != null);
-    _type = value;
-  }
+  String type;
 
   /// The name that should be given to the parameter.
-  String get name => _name;
-
-  /// The name that should be given to the parameter.
-  set name(String value) {
-    assert(value != null);
-    _name = value;
-  }
+  String name;
 
   /// The parameter list of the parameter's function type. If the parameter is
   /// not of a function type, this field will not be defined. If the function
   /// type has zero parameters, this field will have a value of '()'.
-  String get parameters => _parameters;
+  String? parameters;
 
-  /// The parameter list of the parameter's function type. If the parameter is
-  /// not of a function type, this field will not be defined. If the function
-  /// type has zero parameters, this field will have a value of '()'.
-  set parameters(String value) {
-    _parameters = value;
-  }
-
-  RefactoringMethodParameter(
-      RefactoringMethodParameterKind kind, String type, String name,
-      {String id, String parameters}) {
-    this.id = id;
-    this.kind = kind;
-    this.type = type;
-    this.name = name;
-    this.parameters = parameters;
-  }
+  RefactoringMethodParameter(this.kind, this.type, this.name,
+      {this.id, this.parameters});
 
   factory RefactoringMethodParameter.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
-      String id;
+      String? id;
       if (json.containsKey('id')) {
         id = jsonDecoder.decodeString(jsonPath + '.id', json['id']);
       }
@@ -4802,7 +3874,7 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'name');
       }
-      String parameters;
+      String? parameters;
       if (json.containsKey('parameters')) {
         parameters = jsonDecoder.decodeString(
             jsonPath + '.parameters', json['parameters']);
@@ -4815,14 +3887,16 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
+    var id = this.id;
     if (id != null) {
       result['id'] = id;
     }
     result['kind'] = kind.toJson();
     result['type'] = type;
     result['name'] = name;
+    var parameters = this.parameters;
     if (parameters != null) {
       result['parameters'] = parameters;
     }
@@ -4897,7 +3971,7 @@
   }
 
   factory RefactoringMethodParameterKind.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     if (json is String) {
       try {
         return RefactoringMethodParameterKind(json);
@@ -4925,51 +3999,21 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class RefactoringProblem implements HasToJson {
-  RefactoringProblemSeverity _severity;
-
-  String _message;
-
-  Location _location;
-
   /// The severity of the problem being represented.
-  RefactoringProblemSeverity get severity => _severity;
-
-  /// The severity of the problem being represented.
-  set severity(RefactoringProblemSeverity value) {
-    assert(value != null);
-    _severity = value;
-  }
+  RefactoringProblemSeverity severity;
 
   /// A human-readable description of the problem being represented.
-  String get message => _message;
-
-  /// A human-readable description of the problem being represented.
-  set message(String value) {
-    assert(value != null);
-    _message = value;
-  }
+  String message;
 
   /// 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).
-  Location get location => _location;
+  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).
-  set location(Location value) {
-    _location = value;
-  }
-
-  RefactoringProblem(RefactoringProblemSeverity severity, String message,
-      {Location location}) {
-    this.severity = severity;
-    this.message = message;
-    this.location = location;
-  }
+  RefactoringProblem(this.severity, this.message, {this.location});
 
   factory RefactoringProblem.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       RefactoringProblemSeverity severity;
@@ -4986,7 +4030,7 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'message');
       }
-      Location location;
+      Location? location;
       if (json.containsKey('location')) {
         location = Location.fromJson(
             jsonDecoder, jsonPath + '.location', json['location']);
@@ -4998,10 +4042,11 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['severity'] = severity.toJson();
     result['message'] = message;
+    var location = this.location;
     if (location != null) {
       result['location'] = location.toJson();
     }
@@ -5095,7 +4140,7 @@
   }
 
   factory RefactoringProblemSeverity.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     if (json is String) {
       try {
         return RefactoringProblemSeverity(json);
@@ -5107,8 +4152,8 @@
   }
 
   /// Returns the [RefactoringProblemSeverity] with the maximal severity.
-  static RefactoringProblemSeverity max(
-          RefactoringProblemSeverity a, RefactoringProblemSeverity b) =>
+  static RefactoringProblemSeverity? max(
+          RefactoringProblemSeverity? a, RefactoringProblemSeverity? b) =>
       maxRefactoringProblemSeverity(a, b);
 
   @override
@@ -5128,7 +4173,7 @@
   RemoveContentOverlay();
 
   factory RemoveContentOverlay.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       if (json['type'] != 'remove') {
@@ -5141,8 +4186,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['type'] = 'remove';
     return result;
   }
@@ -5178,85 +4223,33 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class SourceChange implements HasToJson {
-  String _message;
-
-  List<SourceFileEdit> _edits;
-
-  List<LinkedEditGroup> _linkedEditGroups;
-
-  Position _selection;
-
-  String _id;
-
   /// A human-readable description of the change to be applied.
-  String get message => _message;
-
-  /// A human-readable description of the change to be applied.
-  set message(String value) {
-    assert(value != null);
-    _message = value;
-  }
+  String message;
 
   /// A list of the edits used to effect the change, grouped by file.
-  List<SourceFileEdit> get edits => _edits;
-
-  /// A list of the edits used to effect the change, grouped by file.
-  set edits(List<SourceFileEdit> value) {
-    assert(value != null);
-    _edits = value;
-  }
+  List<SourceFileEdit> edits;
 
   /// A list of the linked editing groups used to customize the changes that
   /// were made.
-  List<LinkedEditGroup> get linkedEditGroups => _linkedEditGroups;
-
-  /// A list of the linked editing groups used to customize the changes that
-  /// were made.
-  set linkedEditGroups(List<LinkedEditGroup> value) {
-    assert(value != null);
-    _linkedEditGroups = value;
-  }
+  List<LinkedEditGroup> linkedEditGroups;
 
   /// The position that should be selected after the edits have been applied.
-  Position get selection => _selection;
-
-  /// The position that should be selected after the edits have been applied.
-  set selection(Position value) {
-    _selection = value;
-  }
+  Position? selection;
 
   /// The optional identifier of the change kind. The identifier remains stable
   /// even if the message changes, or is parameterized.
-  String get id => _id;
+  String? id;
 
-  /// The optional identifier of the change kind. The identifier remains stable
-  /// even if the message changes, or is parameterized.
-  set id(String value) {
-    _id = value;
-  }
-
-  SourceChange(String message,
-      {List<SourceFileEdit> edits,
-      List<LinkedEditGroup> linkedEditGroups,
-      Position selection,
-      String id}) {
-    this.message = message;
-    if (edits == null) {
-      this.edits = <SourceFileEdit>[];
-    } else {
-      this.edits = edits;
-    }
-    if (linkedEditGroups == null) {
-      this.linkedEditGroups = <LinkedEditGroup>[];
-    } else {
-      this.linkedEditGroups = linkedEditGroups;
-    }
-    this.selection = selection;
-    this.id = id;
-  }
+  SourceChange(this.message,
+      {List<SourceFileEdit>? edits,
+      List<LinkedEditGroup>? linkedEditGroups,
+      this.selection,
+      this.id})
+      : edits = edits ?? <SourceFileEdit>[],
+        linkedEditGroups = linkedEditGroups ?? <LinkedEditGroup>[];
 
   factory SourceChange.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String message;
@@ -5271,7 +4264,7 @@
         edits = jsonDecoder.decodeList(
             jsonPath + '.edits',
             json['edits'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 SourceFileEdit.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'edits');
@@ -5281,17 +4274,17 @@
         linkedEditGroups = jsonDecoder.decodeList(
             jsonPath + '.linkedEditGroups',
             json['linkedEditGroups'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 LinkedEditGroup.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'linkedEditGroups');
       }
-      Position selection;
+      Position? selection;
       if (json.containsKey('selection')) {
         selection = Position.fromJson(
             jsonDecoder, jsonPath + '.selection', json['selection']);
       }
-      String id;
+      String? id;
       if (json.containsKey('id')) {
         id = jsonDecoder.decodeString(jsonPath + '.id', json['id']);
       }
@@ -5306,17 +4299,19 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['message'] = message;
     result['edits'] =
         edits.map((SourceFileEdit value) => value.toJson()).toList();
     result['linkedEditGroups'] = linkedEditGroups
         .map((LinkedEditGroup value) => value.toJson())
         .toList();
+    var selection = this.selection;
     if (selection != null) {
       result['selection'] = selection.toJson();
     }
+    var id = this.id;
     if (id != null) {
       result['id'] = id;
     }
@@ -5338,7 +4333,7 @@
   }
 
   /// Returns the [FileEdit] for the given [file], maybe `null`.
-  SourceFileEdit getFileEdit(String file) => getChangeFileEdit(this, file);
+  SourceFileEdit? getFileEdit(String file) => getChangeFileEdit(this, file);
 
   @override
   String toString() => json.encode(toJson());
@@ -5385,40 +4380,14 @@
   static String applySequence(String code, Iterable<SourceEdit> edits) =>
       applySequenceOfEdits(code, edits);
 
-  int _offset;
-
-  int _length;
-
-  String _replacement;
-
-  String _id;
-
   /// The offset of the region to be modified.
-  int get offset => _offset;
-
-  /// The offset of the region to be modified.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
+  int offset;
 
   /// The length of the region to be modified.
-  int get length => _length;
-
-  /// The length of the region to be modified.
-  set length(int value) {
-    assert(value != null);
-    _length = value;
-  }
+  int length;
 
   /// The code that is to replace the specified region in the original code.
-  String get replacement => _replacement;
-
-  /// The code that is to replace the specified region in the original code.
-  set replacement(String value) {
-    assert(value != null);
-    _replacement = value;
-  }
+  String replacement;
 
   /// An identifier that uniquely identifies this source edit from other edits
   /// in the same response. This field is omitted unless a containing structure
@@ -5428,29 +4397,12 @@
   /// be appropriate (referred to as potential edits). Such edits will have an
   /// id so that they can be referenced. Edits in the same response that do not
   /// need to be referenced will not have an id.
-  String get id => _id;
+  String? id;
 
-  /// An identifier that uniquely identifies this source edit from other edits
-  /// in the same response. This field is omitted unless a containing structure
-  /// needs to be able to identify the edit for some reason.
-  ///
-  /// For example, some refactoring operations can produce edits that might not
-  /// be appropriate (referred to as potential edits). Such edits will have an
-  /// id so that they can be referenced. Edits in the same response that do not
-  /// need to be referenced will not have an id.
-  set id(String value) {
-    _id = value;
-  }
-
-  SourceEdit(int offset, int length, String replacement, {String id}) {
-    this.offset = offset;
-    this.length = length;
-    this.replacement = replacement;
-    this.id = id;
-  }
+  SourceEdit(this.offset, this.length, this.replacement, {this.id});
 
   factory SourceEdit.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       int offset;
@@ -5472,7 +4424,7 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'replacement');
       }
-      String id;
+      String? id;
       if (json.containsKey('id')) {
         id = jsonDecoder.decodeString(jsonPath + '.id', json['id']);
       }
@@ -5486,11 +4438,12 @@
   int get end => offset + length;
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['offset'] = offset;
     result['length'] = length;
     result['replacement'] = replacement;
+    var id = this.id;
     if (id != null) {
       result['id'] = id;
     }
@@ -5535,59 +4488,24 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class SourceFileEdit implements HasToJson {
-  String _file;
-
-  int _fileStamp;
-
-  List<SourceEdit> _edits;
-
   /// The file containing the code to be modified.
-  String get file => _file;
-
-  /// The file containing the code to be modified.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// 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.
-  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.
-  set fileStamp(int value) {
-    assert(value != null);
-    _fileStamp = value;
-  }
+  int fileStamp;
 
   /// A list of the edits used to effect the change.
-  List<SourceEdit> get edits => _edits;
+  List<SourceEdit> edits;
 
-  /// A list of the edits used to effect the change.
-  set edits(List<SourceEdit> value) {
-    assert(value != null);
-    _edits = value;
-  }
-
-  SourceFileEdit(String file, int fileStamp, {List<SourceEdit> edits}) {
-    this.file = file;
-    this.fileStamp = fileStamp;
-    if (edits == null) {
-      this.edits = <SourceEdit>[];
-    } else {
-      this.edits = edits;
-    }
-  }
+  SourceFileEdit(this.file, this.fileStamp, {List<SourceEdit>? edits})
+      : edits = edits ?? <SourceEdit>[];
 
   factory SourceFileEdit.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -5608,7 +4526,7 @@
         edits = jsonDecoder.decodeList(
             jsonPath + '.edits',
             json['edits'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 SourceEdit.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'edits');
@@ -5620,8 +4538,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     result['fileStamp'] = fileStamp;
     result['edits'] = edits.map((SourceEdit value) => value.toJson()).toList();
diff --git a/pkg/analyzer_plugin/lib/protocol/protocol_generated.dart b/pkg/analyzer_plugin/lib/protocol/protocol_generated.dart
index 22b7fc2..937d5c2 100644
--- a/pkg/analyzer_plugin/lib/protocol/protocol_generated.dart
+++ b/pkg/analyzer_plugin/lib/protocol/protocol_generated.dart
@@ -22,40 +22,17 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisErrorFixes implements HasToJson {
-  AnalysisError _error;
-
-  List<PrioritizedSourceChange> _fixes;
-
   /// The error with which the fixes are associated.
-  AnalysisError get error => _error;
-
-  /// The error with which the fixes are associated.
-  set error(AnalysisError value) {
-    assert(value != null);
-    _error = value;
-  }
+  AnalysisError error;
 
   /// The fixes associated with the error.
-  List<PrioritizedSourceChange> get fixes => _fixes;
+  List<PrioritizedSourceChange> fixes;
 
-  /// The fixes associated with the error.
-  set fixes(List<PrioritizedSourceChange> value) {
-    assert(value != null);
-    _fixes = value;
-  }
-
-  AnalysisErrorFixes(AnalysisError error,
-      {List<PrioritizedSourceChange> fixes}) {
-    this.error = error;
-    if (fixes == null) {
-      this.fixes = <PrioritizedSourceChange>[];
-    } else {
-      this.fixes = fixes;
-    }
-  }
+  AnalysisErrorFixes(this.error, {List<PrioritizedSourceChange>? fixes})
+      : fixes = fixes ?? <PrioritizedSourceChange>[];
 
   factory AnalysisErrorFixes.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       AnalysisError error;
@@ -70,7 +47,7 @@
         fixes = jsonDecoder.decodeList(
             jsonPath + '.fixes',
             json['fixes'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 PrioritizedSourceChange.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'fixes');
@@ -82,8 +59,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['error'] = error.toJson();
     result['fixes'] =
         fixes.map((PrioritizedSourceChange value) => value.toJson()).toList();
@@ -121,35 +98,16 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisErrorsParams implements HasToJson {
-  String _file;
-
-  List<AnalysisError> _errors;
-
   /// The file containing the errors.
-  String get file => _file;
-
-  /// The file containing the errors.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// The errors contained in the file.
-  List<AnalysisError> get errors => _errors;
+  List<AnalysisError> errors;
 
-  /// The errors contained in the file.
-  set errors(List<AnalysisError> value) {
-    assert(value != null);
-    _errors = value;
-  }
-
-  AnalysisErrorsParams(String file, List<AnalysisError> errors) {
-    this.file = file;
-    this.errors = errors;
-  }
+  AnalysisErrorsParams(this.file, this.errors);
 
   factory AnalysisErrorsParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -163,7 +121,7 @@
         errors = jsonDecoder.decodeList(
             jsonPath + '.errors',
             json['errors'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 AnalysisError.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'errors');
@@ -180,8 +138,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     result['errors'] =
         errors.map((AnalysisError value) => value.toJson()).toList();
@@ -223,35 +181,16 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisFoldingParams implements HasToJson {
-  String _file;
-
-  List<FoldingRegion> _regions;
-
   /// The file containing the folding regions.
-  String get file => _file;
-
-  /// The file containing the folding regions.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// The folding regions contained in the file.
-  List<FoldingRegion> get regions => _regions;
+  List<FoldingRegion> regions;
 
-  /// The folding regions contained in the file.
-  set regions(List<FoldingRegion> value) {
-    assert(value != null);
-    _regions = value;
-  }
-
-  AnalysisFoldingParams(String file, List<FoldingRegion> regions) {
-    this.file = file;
-    this.regions = regions;
-  }
+  AnalysisFoldingParams(this.file, this.regions);
 
   factory AnalysisFoldingParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -265,7 +204,7 @@
         regions = jsonDecoder.decodeList(
             jsonPath + '.regions',
             json['regions'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 FoldingRegion.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'regions');
@@ -282,8 +221,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     result['regions'] =
         regions.map((FoldingRegion value) => value.toJson()).toList();
@@ -326,51 +265,21 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisGetNavigationParams implements RequestParams {
-  String _file;
-
-  int _offset;
-
-  int _length;
-
   /// The file in which navigation information is being requested.
-  String get file => _file;
-
-  /// The file in which navigation information is being requested.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// The offset of the region for which navigation information is being
   /// requested.
-  int get offset => _offset;
-
-  /// The offset of the region for which navigation information is being
-  /// requested.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
+  int offset;
 
   /// The length of the region for which navigation information is being
   /// requested.
-  int get length => _length;
+  int length;
 
-  /// The length of the region for which navigation information is being
-  /// requested.
-  set length(int value) {
-    assert(value != null);
-    _length = value;
-  }
-
-  AnalysisGetNavigationParams(String file, int offset, int length) {
-    this.file = file;
-    this.offset = offset;
-    this.length = length;
-  }
+  AnalysisGetNavigationParams(this.file, this.offset, this.length);
 
   factory AnalysisGetNavigationParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -404,8 +313,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     result['offset'] = offset;
     result['length'] = length;
@@ -450,52 +359,21 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisGetNavigationResult implements ResponseResult {
-  List<String> _files;
-
-  List<NavigationTarget> _targets;
-
-  List<NavigationRegion> _regions;
-
   /// A list of the paths of files that are referenced by the navigation
   /// targets.
-  List<String> get files => _files;
-
-  /// A list of the paths of files that are referenced by the navigation
-  /// targets.
-  set files(List<String> value) {
-    assert(value != null);
-    _files = value;
-  }
+  List<String> files;
 
   /// A list of the navigation targets that are referenced by the navigation
   /// regions.
-  List<NavigationTarget> get targets => _targets;
-
-  /// A list of the navigation targets that are referenced by the navigation
-  /// regions.
-  set targets(List<NavigationTarget> value) {
-    assert(value != null);
-    _targets = value;
-  }
+  List<NavigationTarget> targets;
 
   /// A list of the navigation regions within the requested region of the file.
-  List<NavigationRegion> get regions => _regions;
+  List<NavigationRegion> regions;
 
-  /// A list of the navigation regions within the requested region of the file.
-  set regions(List<NavigationRegion> value) {
-    assert(value != null);
-    _regions = value;
-  }
-
-  AnalysisGetNavigationResult(List<String> files,
-      List<NavigationTarget> targets, List<NavigationRegion> regions) {
-    this.files = files;
-    this.targets = targets;
-    this.regions = regions;
-  }
+  AnalysisGetNavigationResult(this.files, this.targets, this.regions);
 
   factory AnalysisGetNavigationResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       List<String> files;
@@ -510,7 +388,7 @@
         targets = jsonDecoder.decodeList(
             jsonPath + '.targets',
             json['targets'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 NavigationTarget.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'targets');
@@ -520,7 +398,7 @@
         regions = jsonDecoder.decodeList(
             jsonPath + '.regions',
             json['regions'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 NavigationRegion.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'regions');
@@ -540,8 +418,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['files'] = files;
     result['targets'] =
         targets.map((NavigationTarget value) => value.toJson()).toList();
@@ -588,23 +466,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisHandleWatchEventsParams implements RequestParams {
-  List<WatchEvent> _events;
-
   /// The watch events that the plugin should handle.
-  List<WatchEvent> get events => _events;
+  List<WatchEvent> events;
 
-  /// The watch events that the plugin should handle.
-  set events(List<WatchEvent> value) {
-    assert(value != null);
-    _events = value;
-  }
-
-  AnalysisHandleWatchEventsParams(List<WatchEvent> events) {
-    this.events = events;
-  }
+  AnalysisHandleWatchEventsParams(this.events);
 
   factory AnalysisHandleWatchEventsParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       List<WatchEvent> events;
@@ -612,7 +480,7 @@
         events = jsonDecoder.decodeList(
             jsonPath + '.events',
             json['events'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 WatchEvent.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'events');
@@ -630,8 +498,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['events'] =
         events.map((WatchEvent value) => value.toJson()).toList();
     return result;
@@ -667,7 +535,7 @@
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisHandleWatchEventsResult implements ResponseResult {
   @override
-  Map<String, dynamic> toJson() => <String, dynamic>{};
+  Map<String, Object> toJson() => <String, Object>{};
 
   @override
   Response toResponse(String id, int requestTime) {
@@ -697,35 +565,16 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisHighlightsParams implements HasToJson {
-  String _file;
-
-  List<HighlightRegion> _regions;
-
   /// The file containing the highlight regions.
-  String get file => _file;
-
-  /// The file containing the highlight regions.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// The highlight regions contained in the file.
-  List<HighlightRegion> get regions => _regions;
+  List<HighlightRegion> regions;
 
-  /// The highlight regions contained in the file.
-  set regions(List<HighlightRegion> value) {
-    assert(value != null);
-    _regions = value;
-  }
-
-  AnalysisHighlightsParams(String file, List<HighlightRegion> regions) {
-    this.file = file;
-    this.regions = regions;
-  }
+  AnalysisHighlightsParams(this.file, this.regions);
 
   factory AnalysisHighlightsParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -739,7 +588,7 @@
         regions = jsonDecoder.decodeList(
             jsonPath + '.regions',
             json['regions'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 HighlightRegion.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'regions');
@@ -756,8 +605,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     result['regions'] =
         regions.map((HighlightRegion value) => value.toJson()).toList();
@@ -801,64 +650,24 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisNavigationParams implements HasToJson {
-  String _file;
-
-  List<NavigationRegion> _regions;
-
-  List<NavigationTarget> _targets;
-
-  List<String> _files;
-
   /// The file containing the navigation regions.
-  String get file => _file;
-
-  /// The file containing the navigation regions.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// The navigation regions contained in the file.
-  List<NavigationRegion> get regions => _regions;
-
-  /// The navigation regions contained in the file.
-  set regions(List<NavigationRegion> value) {
-    assert(value != null);
-    _regions = value;
-  }
+  List<NavigationRegion> regions;
 
   /// The navigation targets referenced in the file. They are referenced by
   /// NavigationRegions by their index in this array.
-  List<NavigationTarget> get targets => _targets;
-
-  /// The navigation targets referenced in the file. They are referenced by
-  /// NavigationRegions by their index in this array.
-  set targets(List<NavigationTarget> value) {
-    assert(value != null);
-    _targets = value;
-  }
+  List<NavigationTarget> targets;
 
   /// The files containing navigation targets referenced in the file. They are
   /// referenced by NavigationTargets by their index in this array.
-  List<String> get files => _files;
+  List<String> files;
 
-  /// The files containing navigation targets referenced in the file. They are
-  /// referenced by NavigationTargets by their index in this array.
-  set files(List<String> value) {
-    assert(value != null);
-    _files = value;
-  }
-
-  AnalysisNavigationParams(String file, List<NavigationRegion> regions,
-      List<NavigationTarget> targets, List<String> files) {
-    this.file = file;
-    this.regions = regions;
-    this.targets = targets;
-    this.files = files;
-  }
+  AnalysisNavigationParams(this.file, this.regions, this.targets, this.files);
 
   factory AnalysisNavigationParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -872,7 +681,7 @@
         regions = jsonDecoder.decodeList(
             jsonPath + '.regions',
             json['regions'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 NavigationRegion.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'regions');
@@ -882,7 +691,7 @@
         targets = jsonDecoder.decodeList(
             jsonPath + '.targets',
             json['targets'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 NavigationTarget.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'targets');
@@ -906,8 +715,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     result['regions'] =
         regions.map((NavigationRegion value) => value.toJson()).toList();
@@ -957,35 +766,16 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisOccurrencesParams implements HasToJson {
-  String _file;
-
-  List<Occurrences> _occurrences;
-
   /// The file in which the references occur.
-  String get file => _file;
-
-  /// The file in which the references occur.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// The occurrences of references to elements within the file.
-  List<Occurrences> get occurrences => _occurrences;
+  List<Occurrences> occurrences;
 
-  /// The occurrences of references to elements within the file.
-  set occurrences(List<Occurrences> value) {
-    assert(value != null);
-    _occurrences = value;
-  }
-
-  AnalysisOccurrencesParams(String file, List<Occurrences> occurrences) {
-    this.file = file;
-    this.occurrences = occurrences;
-  }
+  AnalysisOccurrencesParams(this.file, this.occurrences);
 
   factory AnalysisOccurrencesParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -999,7 +789,7 @@
         occurrences = jsonDecoder.decodeList(
             jsonPath + '.occurrences',
             json['occurrences'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 Occurrences.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'occurrences');
@@ -1017,8 +807,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     result['occurrences'] =
         occurrences.map((Occurrences value) => value.toJson()).toList();
@@ -1060,35 +850,16 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisOutlineParams implements HasToJson {
-  String _file;
-
-  List<Outline> _outline;
-
   /// The file with which the outline is associated.
-  String get file => _file;
-
-  /// The file with which the outline is associated.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// The outline fragments associated with the file.
-  List<Outline> get outline => _outline;
+  List<Outline> outline;
 
-  /// The outline fragments associated with the file.
-  set outline(List<Outline> value) {
-    assert(value != null);
-    _outline = value;
-  }
-
-  AnalysisOutlineParams(String file, List<Outline> outline) {
-    this.file = file;
-    this.outline = outline;
-  }
+  AnalysisOutlineParams(this.file, this.outline);
 
   factory AnalysisOutlineParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -1102,7 +873,7 @@
         outline = jsonDecoder.decodeList(
             jsonPath + '.outline',
             json['outline'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 Outline.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'outline');
@@ -1119,8 +890,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     result['outline'] = outline.map((Outline value) => value.toJson()).toList();
     return result;
@@ -1204,7 +975,7 @@
   }
 
   factory AnalysisService.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     if (json is String) {
       try {
         return AnalysisService(json);
@@ -1229,23 +1000,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisSetContextRootsParams implements RequestParams {
-  List<ContextRoot> _roots;
-
   /// A list of the context roots that should be analyzed.
-  List<ContextRoot> get roots => _roots;
+  List<ContextRoot> roots;
 
-  /// A list of the context roots that should be analyzed.
-  set roots(List<ContextRoot> value) {
-    assert(value != null);
-    _roots = value;
-  }
-
-  AnalysisSetContextRootsParams(List<ContextRoot> roots) {
-    this.roots = roots;
-  }
+  AnalysisSetContextRootsParams(this.roots);
 
   factory AnalysisSetContextRootsParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       List<ContextRoot> roots;
@@ -1253,7 +1014,7 @@
         roots = jsonDecoder.decodeList(
             jsonPath + '.roots',
             json['roots'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 ContextRoot.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'roots');
@@ -1271,8 +1032,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['roots'] = roots.map((ContextRoot value) => value.toJson()).toList();
     return result;
   }
@@ -1307,7 +1068,7 @@
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisSetContextRootsResult implements ResponseResult {
   @override
-  Map<String, dynamic> toJson() => <String, dynamic>{};
+  Map<String, Object> toJson() => <String, Object>{};
 
   @override
   Response toResponse(String id, int requestTime) {
@@ -1336,23 +1097,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisSetPriorityFilesParams implements RequestParams {
-  List<String> _files;
-
   /// The files that are to be a priority for analysis.
-  List<String> get files => _files;
+  List<String> files;
 
-  /// The files that are to be a priority for analysis.
-  set files(List<String> value) {
-    assert(value != null);
-    _files = value;
-  }
-
-  AnalysisSetPriorityFilesParams(List<String> files) {
-    this.files = files;
-  }
+  AnalysisSetPriorityFilesParams(this.files);
 
   factory AnalysisSetPriorityFilesParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       List<String> files;
@@ -1375,8 +1126,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['files'] = files;
     return result;
   }
@@ -1410,7 +1161,7 @@
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisSetPriorityFilesResult implements ResponseResult {
   @override
-  Map<String, dynamic> toJson() => <String, dynamic>{};
+  Map<String, Object> toJson() => <String, Object>{};
 
   @override
   Response toResponse(String id, int requestTime) {
@@ -1439,35 +1190,23 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisSetSubscriptionsParams implements RequestParams {
-  Map<AnalysisService, List<String>> _subscriptions;
-
   /// A table mapping services to a list of the files being subscribed to the
   /// service.
-  Map<AnalysisService, List<String>> get subscriptions => _subscriptions;
+  Map<AnalysisService, List<String>> subscriptions;
 
-  /// A table mapping services to a list of the files being subscribed to the
-  /// service.
-  set subscriptions(Map<AnalysisService, List<String>> value) {
-    assert(value != null);
-    _subscriptions = value;
-  }
-
-  AnalysisSetSubscriptionsParams(
-      Map<AnalysisService, List<String>> subscriptions) {
-    this.subscriptions = subscriptions;
-  }
+  AnalysisSetSubscriptionsParams(this.subscriptions);
 
   factory AnalysisSetSubscriptionsParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       Map<AnalysisService, List<String>> subscriptions;
       if (json.containsKey('subscriptions')) {
         subscriptions = jsonDecoder.decodeMap(
             jsonPath + '.subscriptions', json['subscriptions'],
-            keyDecoder: (String jsonPath, Object json) =>
+            keyDecoder: (String jsonPath, Object? json) =>
                 AnalysisService.fromJson(jsonDecoder, jsonPath, json),
-            valueDecoder: (String jsonPath, Object json) => jsonDecoder
+            valueDecoder: (String jsonPath, Object? json) => jsonDecoder
                 .decodeList(jsonPath, json, jsonDecoder.decodeString));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'subscriptions');
@@ -1485,8 +1224,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['subscriptions'] = mapMap(subscriptions,
         keyCallback: (AnalysisService value) => value.toJson());
     return result;
@@ -1525,7 +1264,7 @@
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisSetSubscriptionsResult implements ResponseResult {
   @override
-  Map<String, dynamic> toJson() => <String, dynamic>{};
+  Map<String, Object> toJson() => <String, Object>{};
 
   @override
   Response toResponse(String id, int requestTime) {
@@ -1554,38 +1293,27 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisUpdateContentParams implements RequestParams {
-  Map<String, dynamic> _files;
-
   /// A table mapping the files whose content has changed to a description of
   /// the content change.
-  Map<String, dynamic> get files => _files;
+  Map<String, Object> files;
 
-  /// A table mapping the files whose content has changed to a description of
-  /// the content change.
-  set files(Map<String, dynamic> value) {
-    assert(value != null);
-    _files = value;
-  }
-
-  AnalysisUpdateContentParams(Map<String, dynamic> files) {
-    this.files = files;
-  }
+  AnalysisUpdateContentParams(this.files);
 
   factory AnalysisUpdateContentParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
-      Map<String, dynamic> files;
+      Map<String, Object> files;
       if (json.containsKey('files')) {
         files = jsonDecoder.decodeMap(jsonPath + '.files', json['files'],
-            valueDecoder: (String jsonPath, Object json) =>
-                jsonDecoder.decodeUnion(jsonPath, json as Map, 'type', {
-                  'add': (String jsonPath, Object json) =>
+            valueDecoder: (String jsonPath, Object? json) =>
+                jsonDecoder.decodeUnion(jsonPath, json, 'type', {
+                  'add': (String jsonPath, Object? json) =>
                       AddContentOverlay.fromJson(jsonDecoder, jsonPath, json),
-                  'change': (String jsonPath, Object json) =>
+                  'change': (String jsonPath, Object? json) =>
                       ChangeContentOverlay.fromJson(
                           jsonDecoder, jsonPath, json),
-                  'remove': (String jsonPath, Object json) =>
+                  'remove': (String jsonPath, Object? json) =>
                       RemoveContentOverlay.fromJson(jsonDecoder, jsonPath, json)
                 }));
       } else {
@@ -1604,10 +1332,10 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
-    result['files'] =
-        mapMap(files, valueCallback: (dynamic value) => value.toJson());
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
+    result['files'] = mapMap(files,
+        valueCallback: (Object value) => (value as dynamic).toJson());
     return result;
   }
 
@@ -1622,7 +1350,7 @@
   @override
   bool operator ==(other) {
     if (other is AnalysisUpdateContentParams) {
-      return mapEqual(files, other.files, (dynamic a, dynamic b) => a == b);
+      return mapEqual(files, other.files, (Object a, Object b) => a == b);
     }
     return false;
   }
@@ -1640,7 +1368,7 @@
 /// Clients may not extend, implement or mix-in this class.
 class AnalysisUpdateContentResult implements ResponseResult {
   @override
-  Map<String, dynamic> toJson() => <String, dynamic>{};
+  Map<String, Object> toJson() => <String, Object>{};
 
   @override
   Response toResponse(String id, int requestTime) {
@@ -1670,35 +1398,16 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class CompletionGetSuggestionsParams implements RequestParams {
-  String _file;
-
-  int _offset;
-
   /// The file containing the point at which suggestions are to be made.
-  String get file => _file;
-
-  /// The file containing the point at which suggestions are to be made.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// The offset within the file at which suggestions are to be made.
-  int get offset => _offset;
+  int offset;
 
-  /// The offset within the file at which suggestions are to be made.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
-
-  CompletionGetSuggestionsParams(String file, int offset) {
-    this.file = file;
-    this.offset = offset;
-  }
+  CompletionGetSuggestionsParams(this.file, this.offset);
 
   factory CompletionGetSuggestionsParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -1726,8 +1435,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     result['offset'] = offset;
     return result;
@@ -1768,68 +1477,30 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class CompletionGetSuggestionsResult implements ResponseResult {
-  int _replacementOffset;
-
-  int _replacementLength;
-
-  List<CompletionSuggestion> _results;
-
   /// 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 offset. In
   /// particular, the replacementOffset will be the offset of the beginning of
   /// said identifier.
-  int get replacementOffset => _replacementOffset;
-
-  /// 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 offset. In
-  /// particular, the replacementOffset will be the offset of the beginning of
-  /// said identifier.
-  set replacementOffset(int value) {
-    assert(value != null);
-    _replacementOffset = value;
-  }
+  int replacementOffset;
 
   /// The length of the text to be replaced if the remainder of the identifier
   /// containing the cursor is to be replaced when the suggestion is applied
   /// (that is, the number of characters in the existing identifier).
-  int get replacementLength => _replacementLength;
-
-  /// The length of the text to be replaced if the remainder of the identifier
-  /// containing the cursor is to be replaced when the suggestion is applied
-  /// (that is, the number of characters in the existing identifier).
-  set replacementLength(int value) {
-    assert(value != null);
-    _replacementLength = value;
-  }
+  int replacementLength;
 
   /// The completion suggestions being reported. The notification contains all
   /// possible completions at the requested cursor position, even those that do
   /// not match the characters the user has already typed. This allows the
   /// client to respond to further keystrokes from the user without having to
   /// make additional requests.
-  List<CompletionSuggestion> get results => _results;
+  List<CompletionSuggestion> results;
 
-  /// The completion suggestions being reported. The notification contains all
-  /// possible completions at the requested cursor position, even those that do
-  /// not match the characters the user has already typed. This allows the
-  /// client to respond to further keystrokes from the user without having to
-  /// make additional requests.
-  set results(List<CompletionSuggestion> value) {
-    assert(value != null);
-    _results = value;
-  }
-
-  CompletionGetSuggestionsResult(int replacementOffset, int replacementLength,
-      List<CompletionSuggestion> results) {
-    this.replacementOffset = replacementOffset;
-    this.replacementLength = replacementLength;
-    this.results = results;
-  }
+  CompletionGetSuggestionsResult(
+      this.replacementOffset, this.replacementLength, this.results);
 
   factory CompletionGetSuggestionsResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       int replacementOffset;
@@ -1851,7 +1522,7 @@
         results = jsonDecoder.decodeList(
             jsonPath + '.results',
             json['results'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 CompletionSuggestion.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'results');
@@ -1872,8 +1543,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['replacementOffset'] = replacementOffset;
     result['replacementLength'] = replacementLength;
     result['results'] =
@@ -1920,52 +1591,22 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class ContextRoot implements HasToJson {
-  String _root;
-
-  List<String> _exclude;
-
-  String _optionsFile;
-
   /// The absolute path of the root directory containing the files to be
   /// analyzed.
-  String get root => _root;
-
-  /// The absolute path of the root directory containing the files to be
-  /// analyzed.
-  set root(String value) {
-    assert(value != null);
-    _root = value;
-  }
+  String root;
 
   /// A list of the absolute paths of files and directories within the root
   /// directory that should not be analyzed.
-  List<String> get exclude => _exclude;
-
-  /// A list of the absolute paths of files and directories within the root
-  /// directory that should not be analyzed.
-  set exclude(List<String> value) {
-    assert(value != null);
-    _exclude = value;
-  }
+  List<String> exclude;
 
   /// The absolute path of the analysis options file that should be used to
   /// control the analysis of the files in the context.
-  String get optionsFile => _optionsFile;
+  String? optionsFile;
 
-  /// The absolute path of the analysis options file that should be used to
-  /// control the analysis of the files in the context.
-  set optionsFile(String value) {
-    _optionsFile = value;
-  }
-
-  ContextRoot(String root, List<String> exclude, {String optionsFile}) {
-    this.root = root;
-    this.exclude = exclude;
-    this.optionsFile = optionsFile;
-  }
+  ContextRoot(this.root, this.exclude, {this.optionsFile});
 
   factory ContextRoot.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String root;
@@ -1981,7 +1622,7 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'exclude');
       }
-      String optionsFile;
+      String? optionsFile;
       if (json.containsKey('optionsFile')) {
         optionsFile = jsonDecoder.decodeString(
             jsonPath + '.optionsFile', json['optionsFile']);
@@ -1993,10 +1634,11 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['root'] = root;
     result['exclude'] = exclude;
+    var optionsFile = this.optionsFile;
     if (optionsFile != null) {
       result['optionsFile'] = optionsFile;
     }
@@ -2112,47 +1754,19 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class EditGetAssistsParams implements RequestParams {
-  String _file;
-
-  int _offset;
-
-  int _length;
-
   /// The file containing the code for which assists are being requested.
-  String get file => _file;
-
-  /// The file containing the code for which assists are being requested.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// The offset of the code for which assists are being requested.
-  int get offset => _offset;
-
-  /// The offset of the code for which assists are being requested.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
+  int offset;
 
   /// The length of the code for which assists are being requested.
-  int get length => _length;
+  int length;
 
-  /// The length of the code for which assists are being requested.
-  set length(int value) {
-    assert(value != null);
-    _length = value;
-  }
-
-  EditGetAssistsParams(String file, int offset, int length) {
-    this.file = file;
-    this.offset = offset;
-    this.length = length;
-  }
+  EditGetAssistsParams(this.file, this.offset, this.length);
 
   factory EditGetAssistsParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -2185,8 +1799,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     result['offset'] = offset;
     result['length'] = length;
@@ -2229,23 +1843,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class EditGetAssistsResult implements ResponseResult {
-  List<PrioritizedSourceChange> _assists;
-
   /// The assists that are available at the given location.
-  List<PrioritizedSourceChange> get assists => _assists;
+  List<PrioritizedSourceChange> assists;
 
-  /// The assists that are available at the given location.
-  set assists(List<PrioritizedSourceChange> value) {
-    assert(value != null);
-    _assists = value;
-  }
-
-  EditGetAssistsResult(List<PrioritizedSourceChange> assists) {
-    this.assists = assists;
-  }
+  EditGetAssistsResult(this.assists);
 
   factory EditGetAssistsResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       List<PrioritizedSourceChange> assists;
@@ -2253,7 +1857,7 @@
         assists = jsonDecoder.decodeList(
             jsonPath + '.assists',
             json['assists'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 PrioritizedSourceChange.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'assists');
@@ -2272,8 +1876,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['assists'] =
         assists.map((PrioritizedSourceChange value) => value.toJson()).toList();
     return result;
@@ -2314,47 +1918,19 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class EditGetAvailableRefactoringsParams implements RequestParams {
-  String _file;
-
-  int _offset;
-
-  int _length;
-
   /// The file containing the code on which the refactoring would be based.
-  String get file => _file;
-
-  /// The file containing the code on which the refactoring would be based.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// The offset of the code on which the refactoring would be based.
-  int get offset => _offset;
-
-  /// The offset of the code on which the refactoring would be based.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
+  int offset;
 
   /// The length of the code on which the refactoring would be based.
-  int get length => _length;
+  int length;
 
-  /// The length of the code on which the refactoring would be based.
-  set length(int value) {
-    assert(value != null);
-    _length = value;
-  }
-
-  EditGetAvailableRefactoringsParams(String file, int offset, int length) {
-    this.file = file;
-    this.offset = offset;
-    this.length = length;
-  }
+  EditGetAvailableRefactoringsParams(this.file, this.offset, this.length);
 
   factory EditGetAvailableRefactoringsParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -2388,8 +1964,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     result['offset'] = offset;
     result['length'] = length;
@@ -2432,33 +2008,18 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class EditGetAvailableRefactoringsResult implements ResponseResult {
-  List<RefactoringKind> _kinds;
-
   /// The kinds of refactorings that are valid for the given selection.
   ///
   /// The list of refactoring kinds is currently limited to those defined by
   /// the server API, preventing plugins from adding their own refactorings.
   /// However, plugins can support pre-defined refactorings, such as a rename
   /// refactoring, at locations not supported by server.
-  List<RefactoringKind> get kinds => _kinds;
+  List<RefactoringKind> kinds;
 
-  /// The kinds of refactorings that are valid for the given selection.
-  ///
-  /// The list of refactoring kinds is currently limited to those defined by
-  /// the server API, preventing plugins from adding their own refactorings.
-  /// However, plugins can support pre-defined refactorings, such as a rename
-  /// refactoring, at locations not supported by server.
-  set kinds(List<RefactoringKind> value) {
-    assert(value != null);
-    _kinds = value;
-  }
-
-  EditGetAvailableRefactoringsResult(List<RefactoringKind> kinds) {
-    this.kinds = kinds;
-  }
+  EditGetAvailableRefactoringsResult(this.kinds);
 
   factory EditGetAvailableRefactoringsResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       List<RefactoringKind> kinds;
@@ -2466,7 +2027,7 @@
         kinds = jsonDecoder.decodeList(
             jsonPath + '.kinds',
             json['kinds'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 RefactoringKind.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'kinds');
@@ -2486,8 +2047,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['kinds'] =
         kinds.map((RefactoringKind value) => value.toJson()).toList();
     return result;
@@ -2527,35 +2088,16 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class EditGetFixesParams implements RequestParams {
-  String _file;
-
-  int _offset;
-
   /// The file containing the errors for which fixes are being requested.
-  String get file => _file;
-
-  /// The file containing the errors for which fixes are being requested.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// The offset used to select the errors for which fixes will be returned.
-  int get offset => _offset;
+  int offset;
 
-  /// The offset used to select the errors for which fixes will be returned.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
-
-  EditGetFixesParams(String file, int offset) {
-    this.file = file;
-    this.offset = offset;
-  }
+  EditGetFixesParams(this.file, this.offset);
 
   factory EditGetFixesParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -2582,8 +2124,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     result['offset'] = offset;
     return result;
@@ -2622,23 +2164,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class EditGetFixesResult implements ResponseResult {
-  List<AnalysisErrorFixes> _fixes;
-
   /// The fixes that are available for the errors at the given offset.
-  List<AnalysisErrorFixes> get fixes => _fixes;
+  List<AnalysisErrorFixes> fixes;
 
-  /// The fixes that are available for the errors at the given offset.
-  set fixes(List<AnalysisErrorFixes> value) {
-    assert(value != null);
-    _fixes = value;
-  }
-
-  EditGetFixesResult(List<AnalysisErrorFixes> fixes) {
-    this.fixes = fixes;
-  }
+  EditGetFixesResult(this.fixes);
 
   factory EditGetFixesResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       List<AnalysisErrorFixes> fixes;
@@ -2646,7 +2178,7 @@
         fixes = jsonDecoder.decodeList(
             jsonPath + '.fixes',
             json['fixes'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 AnalysisErrorFixes.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'fixes');
@@ -2665,8 +2197,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['fixes'] =
         fixes.map((AnalysisErrorFixes value) => value.toJson()).toList();
     return result;
@@ -2710,94 +2242,35 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class EditGetRefactoringParams implements RequestParams {
-  RefactoringKind _kind;
-
-  String _file;
-
-  int _offset;
-
-  int _length;
-
-  bool _validateOnly;
-
-  RefactoringOptions _options;
-
   /// The kind of refactoring to be performed.
-  RefactoringKind get kind => _kind;
-
-  /// The kind of refactoring to be performed.
-  set kind(RefactoringKind value) {
-    assert(value != null);
-    _kind = value;
-  }
+  RefactoringKind kind;
 
   /// The file containing the code involved in the refactoring.
-  String get file => _file;
-
-  /// The file containing the code involved in the refactoring.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
+  String file;
 
   /// The offset of the region involved in the refactoring.
-  int get offset => _offset;
-
-  /// The offset of the region involved in the refactoring.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
+  int offset;
 
   /// The length of the region involved in the refactoring.
-  int get length => _length;
-
-  /// The length of the region involved in the refactoring.
-  set length(int value) {
-    assert(value != null);
-    _length = value;
-  }
+  int length;
 
   /// True if the client is only requesting that the values of the options be
   /// validated and no change be generated.
-  bool get validateOnly => _validateOnly;
-
-  /// True if the client is only requesting that the values of the options be
-  /// validated and no change be generated.
-  set validateOnly(bool value) {
-    assert(value != null);
-    _validateOnly = value;
-  }
+  bool validateOnly;
 
   /// Data used to provide values provided by the user. The structure of the
   /// data is dependent on the kind of refactoring being performed. The data
   /// that is expected is documented in the section titled Refactorings,
   /// labeled as "Options". This field can be omitted if the refactoring does
   /// not require any options or if the values of those options are not known.
-  RefactoringOptions get options => _options;
+  RefactoringOptions? options;
 
-  /// Data used to provide values provided by the user. The structure of the
-  /// data is dependent on the kind of refactoring being performed. The data
-  /// that is expected is documented in the section titled Refactorings,
-  /// labeled as "Options". This field can be omitted if the refactoring does
-  /// not require any options or if the values of those options are not known.
-  set options(RefactoringOptions value) {
-    _options = value;
-  }
-
-  EditGetRefactoringParams(RefactoringKind kind, String file, int offset,
-      int length, bool validateOnly,
-      {RefactoringOptions options}) {
-    this.kind = kind;
-    this.file = file;
-    this.offset = offset;
-    this.length = length;
-    this.validateOnly = validateOnly;
-    this.options = options;
-  }
+  EditGetRefactoringParams(
+      this.kind, this.file, this.offset, this.length, this.validateOnly,
+      {this.options});
 
   factory EditGetRefactoringParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       RefactoringKind kind;
@@ -2832,7 +2305,7 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'validateOnly');
       }
-      RefactoringOptions options;
+      RefactoringOptions? options;
       if (json.containsKey('options')) {
         options = RefactoringOptions.fromJson(
             jsonDecoder, jsonPath + '.options', json['options'], kind);
@@ -2852,13 +2325,14 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['kind'] = kind.toJson();
     result['file'] = file;
     result['offset'] = offset;
     result['length'] = length;
     result['validateOnly'] = validateOnly;
+    var options = this.options;
     if (options != null) {
       result['options'] = options.toJson();
     }
@@ -2912,84 +2386,32 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class EditGetRefactoringResult implements ResponseResult {
-  List<RefactoringProblem> _initialProblems;
-
-  List<RefactoringProblem> _optionsProblems;
-
-  List<RefactoringProblem> _finalProblems;
-
-  RefactoringFeedback _feedback;
-
-  SourceChange _change;
-
-  List<String> _potentialEdits;
-
   /// The initial status of the refactoring, that is, problems related to the
   /// context in which the refactoring is requested. The list should be empty
   /// if there are no known problems.
-  List<RefactoringProblem> get initialProblems => _initialProblems;
-
-  /// The initial status of the refactoring, that is, problems related to the
-  /// context in which the refactoring is requested. The list should be empty
-  /// if there are no known problems.
-  set initialProblems(List<RefactoringProblem> value) {
-    assert(value != null);
-    _initialProblems = value;
-  }
+  List<RefactoringProblem> initialProblems;
 
   /// The options validation status, that is, problems in the given options,
   /// such as light-weight validation of a new name, flags compatibility, etc.
   /// The list should be empty if there are no known problems.
-  List<RefactoringProblem> get optionsProblems => _optionsProblems;
-
-  /// The options validation status, that is, problems in the given options,
-  /// such as light-weight validation of a new name, flags compatibility, etc.
-  /// The list should be empty if there are no known problems.
-  set optionsProblems(List<RefactoringProblem> value) {
-    assert(value != null);
-    _optionsProblems = value;
-  }
+  List<RefactoringProblem> optionsProblems;
 
   /// The final status of the refactoring, that is, problems identified in the
   /// result of a full, potentially expensive validation and / or change
   /// creation. The list should be empty if there are no known problems.
-  List<RefactoringProblem> get finalProblems => _finalProblems;
-
-  /// The final status of the refactoring, that is, problems identified in the
-  /// result of a full, potentially expensive validation and / or change
-  /// creation. The list should be empty if there are no known problems.
-  set finalProblems(List<RefactoringProblem> value) {
-    assert(value != null);
-    _finalProblems = value;
-  }
+  List<RefactoringProblem> finalProblems;
 
   /// Data used to provide feedback to the user. The structure of the data is
   /// dependent on the kind of refactoring being created. The data that is
   /// returned is documented in the section titled Refactorings, labeled as
   /// "Feedback".
-  RefactoringFeedback get feedback => _feedback;
-
-  /// Data used to provide feedback to the user. The structure of the data is
-  /// dependent on the kind of refactoring being created. The data that is
-  /// returned is documented in the section titled Refactorings, labeled as
-  /// "Feedback".
-  set feedback(RefactoringFeedback value) {
-    _feedback = value;
-  }
+  RefactoringFeedback? feedback;
 
   /// The changes that are to be applied to affect the refactoring. This field
   /// can be omitted if there are problems that prevent a set of changes from
   /// being computed, such as having no options specified for a refactoring
   /// that requires them, or if only validation was requested.
-  SourceChange get change => _change;
-
-  /// The changes that are to be applied to affect the refactoring. This field
-  /// can be omitted if there are problems that prevent a set of changes from
-  /// being computed, such as having no options specified for a refactoring
-  /// that requires them, or if only validation was requested.
-  set change(SourceChange value) {
-    _change = value;
-  }
+  SourceChange? change;
 
   /// The ids of source edits that are not known to be valid. An edit is not
   /// known to be valid if there was insufficient type information for the
@@ -2997,35 +2419,14 @@
   /// modified, such as when a member is being renamed and there is a reference
   /// to a member from an unknown type. This field can be omitted if the change
   /// field is omitted or if there are no potential edits for the refactoring.
-  List<String> get potentialEdits => _potentialEdits;
-
-  /// The ids of source edits that are not known to be valid. An edit is not
-  /// known to be valid if there was insufficient type information for the
-  /// plugin to be able to determine whether or not the code needs to be
-  /// modified, such as when a member is being renamed and there is a reference
-  /// to a member from an unknown type. This field can be omitted if the change
-  /// field is omitted or if there are no potential edits for the refactoring.
-  set potentialEdits(List<String> value) {
-    _potentialEdits = value;
-  }
+  List<String>? potentialEdits;
 
   EditGetRefactoringResult(
-      List<RefactoringProblem> initialProblems,
-      List<RefactoringProblem> optionsProblems,
-      List<RefactoringProblem> finalProblems,
-      {RefactoringFeedback feedback,
-      SourceChange change,
-      List<String> potentialEdits}) {
-    this.initialProblems = initialProblems;
-    this.optionsProblems = optionsProblems;
-    this.finalProblems = finalProblems;
-    this.feedback = feedback;
-    this.change = change;
-    this.potentialEdits = potentialEdits;
-  }
+      this.initialProblems, this.optionsProblems, this.finalProblems,
+      {this.feedback, this.change, this.potentialEdits});
 
   factory EditGetRefactoringResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       List<RefactoringProblem> initialProblems;
@@ -3033,7 +2434,7 @@
         initialProblems = jsonDecoder.decodeList(
             jsonPath + '.initialProblems',
             json['initialProblems'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 RefactoringProblem.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'initialProblems');
@@ -3043,7 +2444,7 @@
         optionsProblems = jsonDecoder.decodeList(
             jsonPath + '.optionsProblems',
             json['optionsProblems'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 RefactoringProblem.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'optionsProblems');
@@ -3053,22 +2454,22 @@
         finalProblems = jsonDecoder.decodeList(
             jsonPath + '.finalProblems',
             json['finalProblems'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 RefactoringProblem.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'finalProblems');
       }
-      RefactoringFeedback feedback;
+      RefactoringFeedback? feedback;
       if (json.containsKey('feedback')) {
         feedback = RefactoringFeedback.fromJson(
             jsonDecoder, jsonPath + '.feedback', json['feedback'], json);
       }
-      SourceChange change;
+      SourceChange? change;
       if (json.containsKey('change')) {
         change = SourceChange.fromJson(
             jsonDecoder, jsonPath + '.change', json['change']);
       }
-      List<String> potentialEdits;
+      List<String>? potentialEdits;
       if (json.containsKey('potentialEdits')) {
         potentialEdits = jsonDecoder.decodeList(jsonPath + '.potentialEdits',
             json['potentialEdits'], jsonDecoder.decodeString);
@@ -3089,8 +2490,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['initialProblems'] = initialProblems
         .map((RefactoringProblem value) => value.toJson())
         .toList();
@@ -3100,12 +2501,15 @@
     result['finalProblems'] = finalProblems
         .map((RefactoringProblem value) => value.toJson())
         .toList();
+    var feedback = this.feedback;
     if (feedback != null) {
       result['feedback'] = feedback.toJson();
     }
+    var change = this.change;
     if (change != null) {
       result['change'] = change.toJson();
     }
+    var potentialEdits = this.potentialEdits;
     if (potentialEdits != null) {
       result['potentialEdits'] = potentialEdits;
     }
@@ -3162,94 +2566,42 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class ExtractLocalVariableFeedback extends RefactoringFeedback {
-  List<int> _coveringExpressionOffsets;
-
-  List<int> _coveringExpressionLengths;
-
-  List<String> _names;
-
-  List<int> _offsets;
-
-  List<int> _lengths;
-
   /// The offsets of the expressions that cover the specified selection, from
   /// the down most to the up most.
-  List<int> get coveringExpressionOffsets => _coveringExpressionOffsets;
-
-  /// The offsets of the expressions that cover the specified selection, from
-  /// the down most to the up most.
-  set coveringExpressionOffsets(List<int> value) {
-    _coveringExpressionOffsets = value;
-  }
+  List<int>? coveringExpressionOffsets;
 
   /// The lengths of the expressions that cover the specified selection, from
   /// the down most to the up most.
-  List<int> get coveringExpressionLengths => _coveringExpressionLengths;
-
-  /// The lengths of the expressions that cover the specified selection, from
-  /// the down most to the up most.
-  set coveringExpressionLengths(List<int> value) {
-    _coveringExpressionLengths = value;
-  }
+  List<int>? coveringExpressionLengths;
 
   /// The proposed names for the local variable.
-  List<String> get names => _names;
-
-  /// The proposed names for the local variable.
-  set names(List<String> value) {
-    assert(value != null);
-    _names = value;
-  }
+  List<String> names;
 
   /// The offsets of the expressions that would be replaced by a reference to
   /// the variable.
-  List<int> get offsets => _offsets;
-
-  /// The offsets of the expressions that would be replaced by a reference to
-  /// the variable.
-  set offsets(List<int> value) {
-    assert(value != null);
-    _offsets = value;
-  }
+  List<int> offsets;
 
   /// The lengths of the expressions that would be replaced by a reference to
   /// the variable. The lengths correspond to the offsets. In other words, for
   /// a given expression, if the offset of that expression is offsets[i], then
   /// the length of that expression is lengths[i].
-  List<int> get lengths => _lengths;
+  List<int> lengths;
 
-  /// The lengths of the expressions that would be replaced by a reference to
-  /// the variable. The lengths correspond to the offsets. In other words, for
-  /// a given expression, if the offset of that expression is offsets[i], then
-  /// the length of that expression is lengths[i].
-  set lengths(List<int> value) {
-    assert(value != null);
-    _lengths = value;
-  }
-
-  ExtractLocalVariableFeedback(
-      List<String> names, List<int> offsets, List<int> lengths,
-      {List<int> coveringExpressionOffsets,
-      List<int> coveringExpressionLengths}) {
-    this.coveringExpressionOffsets = coveringExpressionOffsets;
-    this.coveringExpressionLengths = coveringExpressionLengths;
-    this.names = names;
-    this.offsets = offsets;
-    this.lengths = lengths;
-  }
+  ExtractLocalVariableFeedback(this.names, this.offsets, this.lengths,
+      {this.coveringExpressionOffsets, this.coveringExpressionLengths});
 
   factory ExtractLocalVariableFeedback.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
-      List<int> coveringExpressionOffsets;
+      List<int>? coveringExpressionOffsets;
       if (json.containsKey('coveringExpressionOffsets')) {
         coveringExpressionOffsets = jsonDecoder.decodeList(
             jsonPath + '.coveringExpressionOffsets',
             json['coveringExpressionOffsets'],
             jsonDecoder.decodeInt);
       }
-      List<int> coveringExpressionLengths;
+      List<int>? coveringExpressionLengths;
       if (json.containsKey('coveringExpressionLengths')) {
         coveringExpressionLengths = jsonDecoder.decodeList(
             jsonPath + '.coveringExpressionLengths',
@@ -3287,11 +2639,13 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
+    var coveringExpressionOffsets = this.coveringExpressionOffsets;
     if (coveringExpressionOffsets != null) {
       result['coveringExpressionOffsets'] = coveringExpressionOffsets;
     }
+    var coveringExpressionLengths = this.coveringExpressionLengths;
     if (coveringExpressionLengths != null) {
       result['coveringExpressionLengths'] = coveringExpressionLengths;
     }
@@ -3339,41 +2693,19 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class ExtractLocalVariableOptions extends RefactoringOptions {
-  String _name;
-
-  bool _extractAll;
-
   /// The name that the local variable should be given.
-  String get name => _name;
-
-  /// The name that the local variable should be given.
-  set name(String value) {
-    assert(value != null);
-    _name = value;
-  }
+  String name;
 
   /// True if all occurrences of the expression within the scope in which the
   /// variable will be defined should be replaced by a reference to the local
   /// variable. The expression used to initiate the refactoring will always be
   /// replaced.
-  bool get extractAll => _extractAll;
+  bool extractAll;
 
-  /// True if all occurrences of the expression within the scope in which the
-  /// variable will be defined should be replaced by a reference to the local
-  /// variable. The expression used to initiate the refactoring will always be
-  /// replaced.
-  set extractAll(bool value) {
-    assert(value != null);
-    _extractAll = value;
-  }
-
-  ExtractLocalVariableOptions(String name, bool extractAll) {
-    this.name = name;
-    this.extractAll = extractAll;
-  }
+  ExtractLocalVariableOptions(this.name, this.extractAll);
 
   factory ExtractLocalVariableOptions.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String name;
@@ -3403,8 +2735,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['name'] = name;
     result['extractAll'] = extractAll;
     return result;
@@ -3445,129 +2777,42 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class ExtractMethodFeedback extends RefactoringFeedback {
-  int _offset;
-
-  int _length;
-
-  String _returnType;
-
-  List<String> _names;
-
-  bool _canCreateGetter;
-
-  List<RefactoringMethodParameter> _parameters;
-
-  List<int> _offsets;
-
-  List<int> _lengths;
-
   /// The offset to the beginning of the expression or statements that will be
   /// extracted.
-  int get offset => _offset;
-
-  /// The offset to the beginning of the expression or statements that will be
-  /// extracted.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
+  int offset;
 
   /// The length of the expression or statements that will be extracted.
-  int get length => _length;
-
-  /// The length of the expression or statements that will be extracted.
-  set length(int value) {
-    assert(value != null);
-    _length = value;
-  }
+  int length;
 
   /// The proposed return type for the method. If the returned element does not
   /// have a declared return type, this field will contain an empty string.
-  String get returnType => _returnType;
-
-  /// The proposed return type for the method. If the returned element does not
-  /// have a declared return type, this field will contain an empty string.
-  set returnType(String value) {
-    assert(value != null);
-    _returnType = value;
-  }
+  String returnType;
 
   /// The proposed names for the method.
-  List<String> get names => _names;
-
-  /// The proposed names for the method.
-  set names(List<String> value) {
-    assert(value != null);
-    _names = value;
-  }
+  List<String> names;
 
   /// True if a getter could be created rather than a method.
-  bool get canCreateGetter => _canCreateGetter;
-
-  /// True if a getter could be created rather than a method.
-  set canCreateGetter(bool value) {
-    assert(value != null);
-    _canCreateGetter = value;
-  }
+  bool canCreateGetter;
 
   /// The proposed parameters for the method.
-  List<RefactoringMethodParameter> get parameters => _parameters;
-
-  /// The proposed parameters for the method.
-  set parameters(List<RefactoringMethodParameter> value) {
-    assert(value != null);
-    _parameters = value;
-  }
+  List<RefactoringMethodParameter> parameters;
 
   /// The offsets of the expressions or statements that would be replaced by an
   /// invocation of the method.
-  List<int> get offsets => _offsets;
-
-  /// The offsets of the expressions or statements that would be replaced by an
-  /// invocation of the method.
-  set offsets(List<int> value) {
-    assert(value != null);
-    _offsets = value;
-  }
+  List<int> offsets;
 
   /// The lengths of the expressions or statements that would be replaced by an
   /// invocation of the method. The lengths correspond to the offsets. In other
   /// words, for a given expression (or block of statements), if the offset of
   /// that expression is offsets[i], then the length of that expression is
   /// lengths[i].
-  List<int> get lengths => _lengths;
+  List<int> lengths;
 
-  /// The lengths of the expressions or statements that would be replaced by an
-  /// invocation of the method. The lengths correspond to the offsets. In other
-  /// words, for a given expression (or block of statements), if the offset of
-  /// that expression is offsets[i], then the length of that expression is
-  /// lengths[i].
-  set lengths(List<int> value) {
-    assert(value != null);
-    _lengths = value;
-  }
-
-  ExtractMethodFeedback(
-      int offset,
-      int length,
-      String returnType,
-      List<String> names,
-      bool canCreateGetter,
-      List<RefactoringMethodParameter> parameters,
-      List<int> offsets,
-      List<int> lengths) {
-    this.offset = offset;
-    this.length = length;
-    this.returnType = returnType;
-    this.names = names;
-    this.canCreateGetter = canCreateGetter;
-    this.parameters = parameters;
-    this.offsets = offsets;
-    this.lengths = lengths;
-  }
+  ExtractMethodFeedback(this.offset, this.length, this.returnType, this.names,
+      this.canCreateGetter, this.parameters, this.offsets, this.lengths);
 
   factory ExtractMethodFeedback.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       int offset;
@@ -3608,7 +2853,7 @@
         parameters = jsonDecoder.decodeList(
             jsonPath + '.parameters',
             json['parameters'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 RefactoringMethodParameter.fromJson(
                     jsonDecoder, jsonPath, json));
       } else {
@@ -3636,8 +2881,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['offset'] = offset;
     result['length'] = length;
     result['returnType'] = returnType;
@@ -3700,44 +2945,15 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class ExtractMethodOptions extends RefactoringOptions {
-  String _returnType;
-
-  bool _createGetter;
-
-  String _name;
-
-  List<RefactoringMethodParameter> _parameters;
-
-  bool _extractAll;
-
   /// The return type that should be defined for the method.
-  String get returnType => _returnType;
-
-  /// The return type that should be defined for the method.
-  set returnType(String value) {
-    assert(value != null);
-    _returnType = value;
-  }
+  String returnType;
 
   /// True if a getter should be created rather than a method. It is an error
   /// if this field is true and the list of parameters is non-empty.
-  bool get createGetter => _createGetter;
-
-  /// True if a getter should be created rather than a method. It is an error
-  /// if this field is true and the list of parameters is non-empty.
-  set createGetter(bool value) {
-    assert(value != null);
-    _createGetter = value;
-  }
+  bool createGetter;
 
   /// The name that the method should be given.
-  String get name => _name;
-
-  /// The name that the method should be given.
-  set name(String value) {
-    assert(value != null);
-    _name = value;
-  }
+  String name;
 
   /// The parameters that should be defined for the method.
   ///
@@ -3749,47 +2965,18 @@
   ///   with the same identifiers as proposed.
   /// - To add new parameters, omit their identifier.
   /// - To remove some parameters, omit them in this list.
-  List<RefactoringMethodParameter> get parameters => _parameters;
-
-  /// The parameters that should be defined for the method.
-  ///
-  /// It is an error if a REQUIRED or NAMED parameter follows a POSITIONAL
-  /// parameter. It is an error if a REQUIRED or POSITIONAL parameter follows a
-  /// NAMED parameter.
-  ///
-  /// - To change the order and/or update proposed parameters, add parameters
-  ///   with the same identifiers as proposed.
-  /// - To add new parameters, omit their identifier.
-  /// - To remove some parameters, omit them in this list.
-  set parameters(List<RefactoringMethodParameter> value) {
-    assert(value != null);
-    _parameters = value;
-  }
+  List<RefactoringMethodParameter> parameters;
 
   /// True if all occurrences of the expression or statements should be
   /// replaced by an invocation of the method. The expression or statements
   /// used to initiate the refactoring will always be replaced.
-  bool get extractAll => _extractAll;
+  bool extractAll;
 
-  /// True if all occurrences of the expression or statements should be
-  /// replaced by an invocation of the method. The expression or statements
-  /// used to initiate the refactoring will always be replaced.
-  set extractAll(bool value) {
-    assert(value != null);
-    _extractAll = value;
-  }
-
-  ExtractMethodOptions(String returnType, bool createGetter, String name,
-      List<RefactoringMethodParameter> parameters, bool extractAll) {
-    this.returnType = returnType;
-    this.createGetter = createGetter;
-    this.name = name;
-    this.parameters = parameters;
-    this.extractAll = extractAll;
-  }
+  ExtractMethodOptions(this.returnType, this.createGetter, this.name,
+      this.parameters, this.extractAll);
 
   factory ExtractMethodOptions.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String returnType;
@@ -3817,7 +3004,7 @@
         parameters = jsonDecoder.decodeList(
             jsonPath + '.parameters',
             json['parameters'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 RefactoringMethodParameter.fromJson(
                     jsonDecoder, jsonPath, json));
       } else {
@@ -3844,8 +3031,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['returnType'] = returnType;
     result['createGetter'] = createGetter;
     result['name'] = name;
@@ -3896,35 +3083,16 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class InlineLocalVariableFeedback extends RefactoringFeedback {
-  String _name;
-
-  int _occurrences;
-
   /// The name of the variable being inlined.
-  String get name => _name;
-
-  /// The name of the variable being inlined.
-  set name(String value) {
-    assert(value != null);
-    _name = value;
-  }
+  String name;
 
   /// The number of times the variable occurs.
-  int get occurrences => _occurrences;
+  int occurrences;
 
-  /// The number of times the variable occurs.
-  set occurrences(int value) {
-    assert(value != null);
-    _occurrences = value;
-  }
-
-  InlineLocalVariableFeedback(String name, int occurrences) {
-    this.name = name;
-    this.occurrences = occurrences;
-  }
+  InlineLocalVariableFeedback(this.name, this.occurrences);
 
   factory InlineLocalVariableFeedback.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String name;
@@ -3948,8 +3116,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['name'] = name;
     result['occurrences'] = occurrences;
     return result;
@@ -4004,54 +3172,24 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class InlineMethodFeedback extends RefactoringFeedback {
-  String _className;
-
-  String _methodName;
-
-  bool _isDeclaration;
-
   /// The name of the class enclosing the method being inlined. If not a class
   /// member is being inlined, this field will be absent.
-  String get className => _className;
-
-  /// The name of the class enclosing the method being inlined. If not a class
-  /// member is being inlined, this field will be absent.
-  set className(String value) {
-    _className = value;
-  }
+  String? className;
 
   /// The name of the method (or function) being inlined.
-  String get methodName => _methodName;
-
-  /// The name of the method (or function) being inlined.
-  set methodName(String value) {
-    assert(value != null);
-    _methodName = value;
-  }
+  String methodName;
 
   /// True if the declaration of the method is selected and all references
   /// should be inlined.
-  bool get isDeclaration => _isDeclaration;
+  bool isDeclaration;
 
-  /// True if the declaration of the method is selected and all references
-  /// should be inlined.
-  set isDeclaration(bool value) {
-    assert(value != null);
-    _isDeclaration = value;
-  }
-
-  InlineMethodFeedback(String methodName, bool isDeclaration,
-      {String className}) {
-    this.className = className;
-    this.methodName = methodName;
-    this.isDeclaration = isDeclaration;
-  }
+  InlineMethodFeedback(this.methodName, this.isDeclaration, {this.className});
 
   factory InlineMethodFeedback.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
-      String className;
+      String? className;
       if (json.containsKey('className')) {
         className = jsonDecoder.decodeString(
             jsonPath + '.className', json['className']);
@@ -4078,8 +3216,9 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
+    var className = this.className;
     if (className != null) {
       result['className'] = className;
     }
@@ -4120,39 +3259,18 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class InlineMethodOptions extends RefactoringOptions {
-  bool _deleteSource;
-
-  bool _inlineAll;
-
   /// True if the method being inlined should be removed. It is an error if
   /// this field is true and inlineAll is false.
-  bool get deleteSource => _deleteSource;
-
-  /// True if the method being inlined should be removed. It is an error if
-  /// this field is true and inlineAll is false.
-  set deleteSource(bool value) {
-    assert(value != null);
-    _deleteSource = value;
-  }
+  bool deleteSource;
 
   /// True if all invocations of the method should be inlined, or false if only
   /// the invocation site used to create this refactoring should be inlined.
-  bool get inlineAll => _inlineAll;
+  bool inlineAll;
 
-  /// True if all invocations of the method should be inlined, or false if only
-  /// the invocation site used to create this refactoring should be inlined.
-  set inlineAll(bool value) {
-    assert(value != null);
-    _inlineAll = value;
-  }
-
-  InlineMethodOptions(bool deleteSource, bool inlineAll) {
-    this.deleteSource = deleteSource;
-    this.inlineAll = inlineAll;
-  }
+  InlineMethodOptions(this.deleteSource, this.inlineAll);
 
   factory InlineMethodOptions.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       bool deleteSource;
@@ -4182,8 +3300,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['deleteSource'] = deleteSource;
     result['inlineAll'] = inlineAll;
     return result;
@@ -4217,25 +3335,14 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class KytheGetKytheEntriesParams implements RequestParams {
-  String _file;
-
   /// The file containing the code for which the Kythe Entry objects are being
   /// requested.
-  String get file => _file;
+  String file;
 
-  /// The file containing the code for which the Kythe Entry objects are being
-  /// requested.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
-
-  KytheGetKytheEntriesParams(String file) {
-    this.file = file;
-  }
+  KytheGetKytheEntriesParams(this.file);
 
   factory KytheGetKytheEntriesParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String file;
@@ -4257,8 +3364,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['file'] = file;
     return result;
   }
@@ -4296,41 +3403,19 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class KytheGetKytheEntriesResult implements ResponseResult {
-  List<KytheEntry> _entries;
-
-  List<String> _files;
-
   /// The list of KytheEntry objects for the queried file.
-  List<KytheEntry> get entries => _entries;
-
-  /// The list of KytheEntry objects for the queried file.
-  set entries(List<KytheEntry> value) {
-    assert(value != null);
-    _entries = value;
-  }
+  List<KytheEntry> entries;
 
   /// The set of files paths that were required, but not in the file system, to
   /// give a complete and accurate Kythe graph for the file. This could be due
   /// to a referenced file that does not exist or generated files not being
   /// generated or passed before the call to "getKytheEntries".
-  List<String> get files => _files;
+  List<String> files;
 
-  /// The set of files paths that were required, but not in the file system, to
-  /// give a complete and accurate Kythe graph for the file. This could be due
-  /// to a referenced file that does not exist or generated files not being
-  /// generated or passed before the call to "getKytheEntries".
-  set files(List<String> value) {
-    assert(value != null);
-    _files = value;
-  }
-
-  KytheGetKytheEntriesResult(List<KytheEntry> entries, List<String> files) {
-    this.entries = entries;
-    this.files = files;
-  }
+  KytheGetKytheEntriesResult(this.entries, this.files);
 
   factory KytheGetKytheEntriesResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       List<KytheEntry> entries;
@@ -4338,7 +3423,7 @@
         entries = jsonDecoder.decodeList(
             jsonPath + '.entries',
             json['entries'],
-            (String jsonPath, Object json) =>
+            (String jsonPath, Object? json) =>
                 KytheEntry.fromJson(jsonDecoder, jsonPath, json));
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'entries');
@@ -4365,8 +3450,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['entries'] =
         entries.map((KytheEntry value) => value.toJson()).toList();
     result['files'] = files;
@@ -4426,23 +3511,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class MoveFileOptions extends RefactoringOptions {
-  String _newFile;
-
   /// The new file path to which the given file is being moved.
-  String get newFile => _newFile;
+  String newFile;
 
-  /// The new file path to which the given file is being moved.
-  set newFile(String value) {
-    assert(value != null);
-    _newFile = value;
-  }
-
-  MoveFileOptions(String newFile) {
-    this.newFile = newFile;
-  }
+  MoveFileOptions(this.newFile);
 
   factory MoveFileOptions.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String newFile;
@@ -4465,8 +3540,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['newFile'] = newFile;
     return result;
   }
@@ -4500,55 +3575,23 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class PluginErrorParams implements HasToJson {
-  bool _isFatal;
-
-  String _message;
-
-  String _stackTrace;
-
   /// A flag indicating whether the error is a fatal error, meaning that the
   /// plugin will shutdown automatically after sending this notification. If
   /// true, the server will not expect any other responses or notifications
   /// from the plugin.
-  bool get isFatal => _isFatal;
-
-  /// A flag indicating whether the error is a fatal error, meaning that the
-  /// plugin will shutdown automatically after sending this notification. If
-  /// true, the server will not expect any other responses or notifications
-  /// from the plugin.
-  set isFatal(bool value) {
-    assert(value != null);
-    _isFatal = value;
-  }
+  bool isFatal;
 
   /// The error message indicating what kind of error was encountered.
-  String get message => _message;
-
-  /// The error message indicating what kind of error was encountered.
-  set message(String value) {
-    assert(value != null);
-    _message = value;
-  }
+  String message;
 
   /// The stack trace associated with the generation of the error, used for
   /// debugging the plugin.
-  String get stackTrace => _stackTrace;
+  String stackTrace;
 
-  /// The stack trace associated with the generation of the error, used for
-  /// debugging the plugin.
-  set stackTrace(String value) {
-    assert(value != null);
-    _stackTrace = value;
-  }
-
-  PluginErrorParams(bool isFatal, String message, String stackTrace) {
-    this.isFatal = isFatal;
-    this.message = message;
-    this.stackTrace = stackTrace;
-  }
+  PluginErrorParams(this.isFatal, this.message, this.stackTrace);
 
   factory PluginErrorParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       bool isFatal;
@@ -4584,8 +3627,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['isFatal'] = isFatal;
     result['message'] = message;
     result['stackTrace'] = stackTrace;
@@ -4624,7 +3667,7 @@
 /// Clients may not extend, implement or mix-in this class.
 class PluginShutdownParams implements RequestParams {
   @override
-  Map<String, dynamic> toJson() => <String, dynamic>{};
+  Map<String, Object> toJson() => <String, Object>{};
 
   @override
   Request toRequest(String id) {
@@ -4650,7 +3693,7 @@
 /// Clients may not extend, implement or mix-in this class.
 class PluginShutdownResult implements ResponseResult {
   @override
-  Map<String, dynamic> toJson() => <String, dynamic>{};
+  Map<String, Object> toJson() => <String, Object>{};
 
   @override
   Response toResponse(String id, int requestTime) {
@@ -4681,54 +3724,22 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class PluginVersionCheckParams implements RequestParams {
-  String _byteStorePath;
-
-  String _sdkPath;
-
-  String _version;
-
   /// The path to the directory containing the on-disk byte store that is to be
   /// used by any analysis drivers that are created.
-  String get byteStorePath => _byteStorePath;
-
-  /// The path to the directory containing the on-disk byte store that is to be
-  /// used by any analysis drivers that are created.
-  set byteStorePath(String value) {
-    assert(value != null);
-    _byteStorePath = value;
-  }
+  String byteStorePath;
 
   /// The path to the directory containing the SDK that is to be used by any
   /// analysis drivers that are created.
-  String get sdkPath => _sdkPath;
-
-  /// The path to the directory containing the SDK that is to be used by any
-  /// analysis drivers that are created.
-  set sdkPath(String value) {
-    assert(value != null);
-    _sdkPath = value;
-  }
+  String sdkPath;
 
   /// The version number of the plugin spec supported by the analysis server
   /// that is executing the plugin.
-  String get version => _version;
+  String version;
 
-  /// The version number of the plugin spec supported by the analysis server
-  /// that is executing the plugin.
-  set version(String value) {
-    assert(value != null);
-    _version = value;
-  }
-
-  PluginVersionCheckParams(
-      String byteStorePath, String sdkPath, String version) {
-    this.byteStorePath = byteStorePath;
-    this.sdkPath = sdkPath;
-    this.version = version;
-  }
+  PluginVersionCheckParams(this.byteStorePath, this.sdkPath, this.version);
 
   factory PluginVersionCheckParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String byteStorePath;
@@ -4764,8 +3775,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['byteStorePath'] = byteStorePath;
     result['sdkPath'] = sdkPath;
     result['version'] = version;
@@ -4812,88 +3823,35 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class PluginVersionCheckResult implements ResponseResult {
-  bool _isCompatible;
-
-  String _name;
-
-  String _version;
-
-  String _contactInfo;
-
-  List<String> _interestingFiles;
-
   /// A flag indicating whether the plugin supports the same version of the
   /// plugin spec as the analysis server. If the value is false, then the
   /// plugin is expected to shutdown after returning the response.
-  bool get isCompatible => _isCompatible;
-
-  /// A flag indicating whether the plugin supports the same version of the
-  /// plugin spec as the analysis server. If the value is false, then the
-  /// plugin is expected to shutdown after returning the response.
-  set isCompatible(bool value) {
-    assert(value != null);
-    _isCompatible = value;
-  }
+  bool isCompatible;
 
   /// The name of the plugin. This value is only used when the server needs to
   /// identify the plugin, either to the user or for debugging purposes.
-  String get name => _name;
-
-  /// The name of the plugin. This value is only used when the server needs to
-  /// identify the plugin, either to the user or for debugging purposes.
-  set name(String value) {
-    assert(value != null);
-    _name = value;
-  }
+  String name;
 
   /// The version of the plugin. This value is only used when the server needs
   /// to identify the plugin, either to the user or for debugging purposes.
-  String get version => _version;
-
-  /// The version of the plugin. This value is only used when the server needs
-  /// to identify the plugin, either to the user or for debugging purposes.
-  set version(String value) {
-    assert(value != null);
-    _version = value;
-  }
+  String version;
 
   /// Information that the user can use to use to contact the maintainers of
   /// the plugin when there is a problem.
-  String get contactInfo => _contactInfo;
-
-  /// Information that the user can use to use to contact the maintainers of
-  /// the plugin when there is a problem.
-  set contactInfo(String value) {
-    _contactInfo = value;
-  }
+  String? contactInfo;
 
   /// The glob patterns of the files for which the plugin will provide
   /// information. This value is ignored if the isCompatible field is false.
   /// Otherwise, it will be used to identify the files for which the plugin
   /// should be notified of changes.
-  List<String> get interestingFiles => _interestingFiles;
+  List<String> interestingFiles;
 
-  /// The glob patterns of the files for which the plugin will provide
-  /// information. This value is ignored if the isCompatible field is false.
-  /// Otherwise, it will be used to identify the files for which the plugin
-  /// should be notified of changes.
-  set interestingFiles(List<String> value) {
-    assert(value != null);
-    _interestingFiles = value;
-  }
-
-  PluginVersionCheckResult(bool isCompatible, String name, String version,
-      List<String> interestingFiles,
-      {String contactInfo}) {
-    this.isCompatible = isCompatible;
-    this.name = name;
-    this.version = version;
-    this.contactInfo = contactInfo;
-    this.interestingFiles = interestingFiles;
-  }
+  PluginVersionCheckResult(
+      this.isCompatible, this.name, this.version, this.interestingFiles,
+      {this.contactInfo});
 
   factory PluginVersionCheckResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       bool isCompatible;
@@ -4916,7 +3874,7 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'version');
       }
-      String contactInfo;
+      String? contactInfo;
       if (json.containsKey('contactInfo')) {
         contactInfo = jsonDecoder.decodeString(
             jsonPath + '.contactInfo', json['contactInfo']);
@@ -4946,11 +3904,12 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['isCompatible'] = isCompatible;
     result['name'] = name;
     result['version'] = version;
+    var contactInfo = this.contactInfo;
     if (contactInfo != null) {
       result['contactInfo'] = contactInfo;
     }
@@ -5000,37 +3959,17 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class PrioritizedSourceChange implements HasToJson {
-  int _priority;
-
-  SourceChange _change;
-
   /// The priority of the change. The value is expected to be non-negative, and
   /// zero (0) is the lowest priority.
-  int get priority => _priority;
-
-  /// The priority of the change. The value is expected to be non-negative, and
-  /// zero (0) is the lowest priority.
-  set priority(int value) {
-    assert(value != null);
-    _priority = value;
-  }
+  int priority;
 
   /// The change with which the relevance is associated.
-  SourceChange get change => _change;
+  SourceChange change;
 
-  /// The change with which the relevance is associated.
-  set change(SourceChange value) {
-    assert(value != null);
-    _change = value;
-  }
-
-  PrioritizedSourceChange(int priority, SourceChange change) {
-    this.priority = priority;
-    this.change = change;
-  }
+  PrioritizedSourceChange(this.priority, this.change);
 
   factory PrioritizedSourceChange.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       int priority;
@@ -5054,8 +3993,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['priority'] = priority;
     result['change'] = change.toJson();
     return result;
@@ -5090,15 +4029,15 @@
 class RefactoringFeedback implements HasToJson {
   RefactoringFeedback();
 
-  factory RefactoringFeedback.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json, Map responseJson) {
+  factory RefactoringFeedback.fromJson(JsonDecoder jsonDecoder, String jsonPath,
+      Object? json, Map responseJson) {
     return refactoringFeedbackFromJson(
         jsonDecoder, jsonPath, json, responseJson);
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     return result;
   }
 
@@ -5130,13 +4069,13 @@
   RefactoringOptions();
 
   factory RefactoringOptions.fromJson(JsonDecoder jsonDecoder, String jsonPath,
-      Object json, RefactoringKind kind) {
+      Object? json, RefactoringKind kind) {
     return refactoringOptionsFromJson(jsonDecoder, jsonPath, json, kind);
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     return result;
   }
 
@@ -5169,62 +4108,23 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class RenameFeedback extends RefactoringFeedback {
-  int _offset;
-
-  int _length;
-
-  String _elementKindName;
-
-  String _oldName;
-
   /// The offset to the beginning of the name selected to be renamed.
-  int get offset => _offset;
-
-  /// The offset to the beginning of the name selected to be renamed.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
+  int offset;
 
   /// The length of the name selected to be renamed.
-  int get length => _length;
-
-  /// The length of the name selected to be renamed.
-  set length(int value) {
-    assert(value != null);
-    _length = value;
-  }
+  int length;
 
   /// The human-readable description of the kind of element being renamed (such
   /// as “class” or “function type alias”).
-  String get elementKindName => _elementKindName;
-
-  /// The human-readable description of the kind of element being renamed (such
-  /// as “class” or “function type alias”).
-  set elementKindName(String value) {
-    assert(value != null);
-    _elementKindName = value;
-  }
+  String elementKindName;
 
   /// The old name of the element before the refactoring.
-  String get oldName => _oldName;
+  String oldName;
 
-  /// The old name of the element before the refactoring.
-  set oldName(String value) {
-    assert(value != null);
-    _oldName = value;
-  }
-
-  RenameFeedback(
-      int offset, int length, String elementKindName, String oldName) {
-    this.offset = offset;
-    this.length = length;
-    this.elementKindName = elementKindName;
-    this.oldName = oldName;
-  }
+  RenameFeedback(this.offset, this.length, this.elementKindName, this.oldName);
 
   factory RenameFeedback.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       int offset;
@@ -5260,8 +4160,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['offset'] = offset;
     result['length'] = length;
     result['elementKindName'] = elementKindName;
@@ -5302,23 +4202,13 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class RenameOptions extends RefactoringOptions {
-  String _newName;
-
   /// The name that the element should have after the refactoring.
-  String get newName => _newName;
+  String newName;
 
-  /// The name that the element should have after the refactoring.
-  set newName(String value) {
-    assert(value != null);
-    _newName = value;
-  }
-
-  RenameOptions(String newName) {
-    this.newName = newName;
-  }
+  RenameOptions(this.newName);
 
   factory RenameOptions.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       String newName;
@@ -5341,8 +4231,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['newName'] = newName;
     return result;
   }
@@ -5376,48 +4266,20 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class RequestError implements HasToJson {
-  RequestErrorCode _code;
-
-  String _message;
-
-  String _stackTrace;
-
   /// A code that uniquely identifies the error that occurred.
-  RequestErrorCode get code => _code;
-
-  /// A code that uniquely identifies the error that occurred.
-  set code(RequestErrorCode value) {
-    assert(value != null);
-    _code = value;
-  }
+  RequestErrorCode code;
 
   /// A short description of the error.
-  String get message => _message;
-
-  /// A short description of the error.
-  set message(String value) {
-    assert(value != null);
-    _message = value;
-  }
+  String message;
 
   /// The stack trace associated with processing the request, used for
   /// debugging the plugin.
-  String get stackTrace => _stackTrace;
+  String? stackTrace;
 
-  /// The stack trace associated with processing the request, used for
-  /// debugging the plugin.
-  set stackTrace(String value) {
-    _stackTrace = value;
-  }
-
-  RequestError(RequestErrorCode code, String message, {String stackTrace}) {
-    this.code = code;
-    this.message = message;
-    this.stackTrace = stackTrace;
-  }
+  RequestError(this.code, this.message, {this.stackTrace});
 
   factory RequestError.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       RequestErrorCode code;
@@ -5434,7 +4296,7 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'message');
       }
-      String stackTrace;
+      String? stackTrace;
       if (json.containsKey('stackTrace')) {
         stackTrace = jsonDecoder.decodeString(
             jsonPath + '.stackTrace', json['stackTrace']);
@@ -5446,10 +4308,11 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['code'] = code.toJson();
     result['message'] = message;
+    var stackTrace = this.stackTrace;
     if (stackTrace != null) {
       result['stackTrace'] = stackTrace;
     }
@@ -5543,7 +4406,7 @@
   }
 
   factory RequestErrorCode.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     if (json is String) {
       try {
         return RequestErrorCode(json);
@@ -5569,35 +4432,16 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class WatchEvent implements HasToJson {
-  WatchEventType _type;
-
-  String _path;
-
   /// The type of change represented by this event.
-  WatchEventType get type => _type;
-
-  /// The type of change represented by this event.
-  set type(WatchEventType value) {
-    assert(value != null);
-    _type = value;
-  }
+  WatchEventType type;
 
   /// The absolute path of the file or directory that changed.
-  String get path => _path;
+  String path;
 
-  /// The absolute path of the file or directory that changed.
-  set path(String value) {
-    assert(value != null);
-    _path = value;
-  }
-
-  WatchEvent(WatchEventType type, String path) {
-    this.type = type;
-    this.path = path;
-  }
+  WatchEvent(this.type, this.path);
 
   factory WatchEvent.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
       WatchEventType type;
@@ -5620,8 +4464,8 @@
   }
 
   @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
+  Map<String, Object> toJson() {
+    var result = <String, Object>{};
     result['type'] = type.toJson();
     result['path'] = path;
     return result;
@@ -5691,7 +4535,7 @@
   }
 
   factory WatchEventType.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     if (json is String) {
       try {
         return WatchEventType(json);
diff --git a/pkg/analyzer_plugin/lib/src/channel/isolate_channel.dart b/pkg/analyzer_plugin/lib/src/channel/isolate_channel.dart
index 2b35cc7..f7cdfcb 100644
--- a/pkg/analyzer_plugin/lib/src/channel/isolate_channel.dart
+++ b/pkg/analyzer_plugin/lib/src/channel/isolate_channel.dart
@@ -31,7 +31,7 @@
   @override
   Future<Isolate> _spawnIsolate() {
     return Isolate.spawn(
-        (message) => entryPoint(message as SendPort), _receivePort.sendPort,
+        (message) => entryPoint(message as SendPort), _receivePort?.sendPort,
         onError: _errorPort?.sendPort, onExit: _exitPort?.sendPort);
   }
 }
@@ -57,7 +57,7 @@
 
   @override
   Future<Isolate> _spawnIsolate() {
-    return Isolate.spawnUri(pluginUri, <String>[], _receivePort.sendPort,
+    return Isolate.spawnUri(pluginUri, <String>[], _receivePort?.sendPort,
         onError: _errorPort?.sendPort,
         onExit: _exitPort?.sendPort,
         packageConfig: packagesUri);
@@ -72,10 +72,10 @@
   final SendPort _sendPort;
 
   /// The port used to receive requests from the server.
-  ReceivePort _receivePort;
+  late final ReceivePort _receivePort;
 
   /// The subscription that needs to be cancelled when the channel is closed.
-  StreamSubscription _subscription;
+  StreamSubscription? _subscription;
 
   /// Initialize a newly created channel to communicate with the server.
   PluginIsolateChannel(this._sendPort) {
@@ -85,21 +85,17 @@
 
   @override
   void close() {
-    if (_subscription != null) {
-      _subscription.cancel();
-      _subscription = null;
-    }
+    _subscription?.cancel();
+    _subscription = null;
   }
 
   @override
   void listen(void Function(Request request) onRequest,
-      {Function onError, void Function() onDone}) {
+      {Function? onError, void Function()? onDone}) {
     void onData(data) {
       var requestMap = data as Map<String, Object>;
       var request = Request.fromJson(requestMap);
-      if (request != null) {
-        onRequest(request);
-      }
+      onRequest(request);
     }
 
     if (_subscription != null) {
@@ -130,20 +126,20 @@
 
   /// The isolate in which the plugin is running, or `null` if the plugin has
   /// not yet been started by invoking [listen].
-  Isolate _isolate;
+  Isolate? _isolate;
 
   /// The port used to send requests to the plugin, or `null` if the plugin has
   /// not yet been started by invoking [listen].
-  SendPort _sendPort;
+  SendPort? _sendPort;
 
   /// The port used to receive responses and notifications from the plugin.
-  ReceivePort _receivePort;
+  ReceivePort? _receivePort;
 
   /// The port used to receive unhandled exceptions thrown in the plugin.
-  ReceivePort _errorPort;
+  ReceivePort? _errorPort;
 
   /// The port used to receive notification when the plugin isolate has exited.
-  ReceivePort _exitPort;
+  ReceivePort? _exitPort;
 
   /// Return a communication channel appropriate for communicating with a
   /// built-in plugin.
@@ -180,23 +176,30 @@
   @override
   Future<void> listen(void Function(Response response) onResponse,
       void Function(Notification notification) onNotification,
-      {void Function(dynamic error) onError, void Function() onDone}) async {
+      {void Function(dynamic error)? onError, void Function()? onDone}) async {
     if (_isolate != null) {
       throw StateError('Cannot listen to the same channel more than once.');
     }
-    _receivePort = ReceivePort();
+
+    var receivePort = ReceivePort();
+    _receivePort = receivePort;
+
     if (onError != null) {
-      _errorPort = ReceivePort();
-      _errorPort.listen((error) {
+      var errorPort = ReceivePort();
+      _errorPort = errorPort;
+      errorPort.listen((error) {
         onError(error);
       });
     }
+
     if (onDone != null) {
-      _exitPort = ReceivePort();
-      _exitPort.listen((_) {
+      var exitPort = ReceivePort();
+      _exitPort = exitPort;
+      exitPort.listen((_) {
         onDone();
       });
     }
+
     try {
       _isolate = await _spawnIsolate();
     } catch (exception, stackTrace) {
@@ -214,12 +217,13 @@
       close();
       return null;
     }
+
     var channelReady = Completer<void>();
-    _receivePort.listen((dynamic input) {
+    receivePort.listen((dynamic input) {
       if (input is SendPort) {
         _sendPort = input;
         channelReady.complete(null);
-      } else if (input is Map) {
+      } else if (input is Map<String, Object?>) {
         if (input.containsKey('id')) {
           var encodedInput = json.encode(input);
           instrumentationService.logPluginResponse(pluginId, encodedInput);
@@ -231,16 +235,18 @@
         }
       }
     });
+
     return channelReady.future;
   }
 
   @override
   void sendRequest(Request request) {
-    if (_sendPort != null) {
+    var sendPort = _sendPort;
+    if (sendPort != null) {
       var jsonData = request.toJson();
       var encodedRequest = json.encode(jsonData);
       instrumentationService.logPluginRequest(pluginId, encodedRequest);
-      _sendPort.send(jsonData);
+      sendPort.send(jsonData);
     }
   }
 
diff --git a/pkg/analyzer_plugin/lib/src/protocol/protocol_internal.dart b/pkg/analyzer_plugin/lib/src/protocol/protocol_internal.dart
index 5615b1b..777ccda 100644
--- a/pkg/analyzer_plugin/lib/src/protocol/protocol_internal.dart
+++ b/pkg/analyzer_plugin/lib/src/protocol/protocol_internal.dart
@@ -93,7 +93,7 @@
 }
 
 /// Returns the [FileEdit] for the given [file], maybe `null`.
-SourceFileEdit getChangeFileEdit(SourceChange change, String file) {
+SourceFileEdit? getChangeFileEdit(SourceChange change, String file) {
   for (var fileEdit in change.edits) {
     if (fileEdit.file == file) {
       return fileEdit;
@@ -105,7 +105,7 @@
 /// Compare the lists [listA] and [listB], using [itemEqual] to compare
 /// list elements.
 bool listEqual<T>(
-    List<T> listA, List<T> listB, bool Function(T a, T b) itemEqual) {
+    List<T>? listA, List<T>? listB, bool Function(T a, T b) itemEqual) {
   if (listA == null) {
     return listB == null;
   }
@@ -126,7 +126,7 @@
 /// Compare the maps [mapA] and [mapB], using [valueEqual] to compare map
 /// values.
 bool mapEqual<K, V>(
-    Map<K, V> mapA, Map<K, V> mapB, bool Function(V a, V b) valueEqual) {
+    Map<K, V>? mapA, Map<K, V>? mapB, bool Function(V a, V b) valueEqual) {
   if (mapA == null) {
     return mapB == null;
   }
@@ -136,11 +136,11 @@
   if (mapA.length != mapB.length) {
     return false;
   }
-  for (var key in mapA.keys) {
-    if (!mapB.containsKey(key)) {
-      return false;
-    }
-    if (!valueEqual(mapA[key], mapB[key])) {
+  for (var entryA in mapA.entries) {
+    var key = entryA.key;
+    var valueA = entryA.value;
+    var valueB = mapB[key];
+    if (valueB == null || !valueEqual(valueA, valueB)) {
       return false;
     }
   }
@@ -150,7 +150,7 @@
 /// Translate the input [map], applying [keyCallback] to all its keys, and
 /// [valueCallback] to all its values.
 Map<KR, VR> mapMap<KP, VP, KR, VR>(Map<KP, VP> map,
-    {KR Function(KP key) keyCallback, VR Function(VP value) valueCallback}) {
+    {KR Function(KP key)? keyCallback, VR Function(VP value)? valueCallback}) {
   Map<KR, VR> result = HashMap<KR, VR>();
   map.forEach((key, value) {
     KR resultKey;
@@ -170,8 +170,8 @@
   return result;
 }
 
-RefactoringProblemSeverity maxRefactoringProblemSeverity(
-    RefactoringProblemSeverity a, RefactoringProblemSeverity b) {
+RefactoringProblemSeverity? maxRefactoringProblemSeverity(
+    RefactoringProblemSeverity? a, RefactoringProblemSeverity? b) {
   if (b == null) {
     return a;
   }
@@ -194,7 +194,7 @@
 
 /// Create a [RefactoringFeedback] corresponding the given [kind].
 RefactoringFeedback refactoringFeedbackFromJson(
-    JsonDecoder jsonDecoder, String jsonPath, Object json, Map feedbackJson) {
+    JsonDecoder jsonDecoder, String jsonPath, Object? json, Map feedbackJson) {
   var kind = jsonDecoder.refactoringKind;
   if (kind == RefactoringKind.EXTRACT_LOCAL_VARIABLE) {
     return ExtractLocalVariableFeedback.fromJson(jsonDecoder, jsonPath, json);
@@ -211,12 +211,12 @@
   if (kind == RefactoringKind.RENAME) {
     return RenameFeedback.fromJson(jsonDecoder, jsonPath, json);
   }
-  return null;
+  throw StateError('Unexpected refactoring kind');
 }
 
 /// Create a [RefactoringOptions] corresponding the given [kind].
 RefactoringOptions refactoringOptionsFromJson(JsonDecoder jsonDecoder,
-    String jsonPath, Object json, RefactoringKind kind) {
+    String jsonPath, Object? json, RefactoringKind kind) {
   if (kind == RefactoringKind.EXTRACT_LOCAL_VARIABLE) {
     return ExtractLocalVariableOptions.fromJson(jsonDecoder, jsonPath, json);
   }
@@ -232,13 +232,14 @@
   if (kind == RefactoringKind.RENAME) {
     return RenameOptions.fromJson(jsonDecoder, jsonPath, json);
   }
-  return null;
+  throw StateError('Unexpected refactoring kind');
 }
 
 /// Type of callbacks used to decode parts of JSON objects. [jsonPath] is a
 /// string describing the part of the JSON object being decoded, and [value] is
 /// the part to decode.
-typedef JsonDecoderCallback<E> = E Function(String jsonPath, dynamic value);
+typedef JsonDecoderCallback<E extends Object> = E Function(
+    String jsonPath, Object? value);
 
 /// Instances of the class [HasToJson] implement [toJson] method that returns
 /// a JSON presentation.
@@ -253,11 +254,11 @@
   /// Retrieve the RefactoringKind that should be assumed when decoding
   /// refactoring feedback objects, or null if no refactoring feedback object is
   /// expected to be encountered.
-  RefactoringKind get refactoringKind;
+  RefactoringKind? get refactoringKind;
 
   /// Decode a JSON object that is expected to be a boolean. The strings "true"
   /// and "false" are also accepted.
-  bool decodeBool(String jsonPath, Object json) {
+  bool decodeBool(String jsonPath, Object? json) {
     if (json is bool) {
       return json;
     } else if (json == 'true') {
@@ -287,7 +288,7 @@
 
   /// Decode a JSON object that is expected to be an integer. A string
   /// representation of an integer is also accepted.
-  int decodeInt(String jsonPath, Object json) {
+  int decodeInt(String jsonPath, Object? json) {
     if (json is int) {
       return json;
     } else if (json is String) {
@@ -304,11 +305,11 @@
   /// to decode the items in the list.
   ///
   /// The type parameter [E] is the expected type of the elements in the list.
-  List<E> decodeList<E>(String jsonPath, Object json,
-      [JsonDecoderCallback<E> decoder]) {
+  List<E> decodeList<E extends Object>(String jsonPath, Object? json,
+      [JsonDecoderCallback<E>? decoder]) {
     if (json == null) {
       return <E>[];
-    } else if (json is List) {
+    } else if (json is List && decoder != null) {
       var result = <E>[];
       for (var i = 0; i < json.length; i++) {
         result.add(decoder('$jsonPath[$i]', json[i]));
@@ -321,9 +322,10 @@
 
   /// Decode a JSON object that is expected to be a Map. [keyDecoder] is used
   /// to decode the keys, and [valueDecoder] is used to decode the values.
-  Map<K, V> decodeMap<K, V>(String jsonPath, Object jsonData,
-      {JsonDecoderCallback<K> keyDecoder,
-      JsonDecoderCallback<V> valueDecoder}) {
+  Map<K, V> decodeMap<K extends Object, V extends Object>(
+      String jsonPath, Object? jsonData,
+      {JsonDecoderCallback<K>? keyDecoder,
+      JsonDecoderCallback<V>? valueDecoder}) {
     if (jsonData == null) {
       return {};
     } else if (jsonData is Map) {
@@ -347,7 +349,7 @@
   }
 
   /// Decode a JSON object that is expected to be a string.
-  String decodeString(String jsonPath, Object json) {
+  String decodeString(String jsonPath, Object? json) {
     if (json is String) {
       return json;
     } else {
@@ -359,7 +361,7 @@
   /// where the choices are disambiguated by the contents of the field [field].
   /// [decoders] is a map from each possible string in the field to the decoder
   /// that should be used to decode the JSON object.
-  Object decodeUnion(String jsonPath, Map jsonData, String field,
+  Object decodeUnion(String jsonPath, Object? jsonData, String field,
       Map<String, JsonDecoderCallback> decoders) {
     if (jsonData is Map) {
       if (!jsonData.containsKey(field)) {
@@ -371,7 +373,11 @@
         throw mismatch(
             disambiguatorPath, 'One of: ${decoders.keys.toList()}', jsonData);
       }
-      return decoders[disambiguator](jsonPath, jsonData);
+      var decoder = decoders[disambiguator];
+      if (decoder == null) {
+        throw mismatch(disambiguatorPath, 'Non-null decoder', jsonData);
+      }
+      return decoder(jsonPath, jsonData);
     } else {
       throw mismatch(jsonPath, 'Map', jsonData);
     }
@@ -379,11 +385,11 @@
 
   /// Create an exception to throw if the JSON object at [jsonPath] fails to
   /// match the API definition of [expected].
-  dynamic mismatch(String jsonPath, String expected, [Object actual]);
+  Object mismatch(String jsonPath, String expected, [Object? actual]);
 
   /// Create an exception to throw if the JSON object at [jsonPath] is missing
   /// the key [key].
-  dynamic missingKey(String jsonPath, String key);
+  Object missingKey(String jsonPath, String key);
 }
 
 /// JsonDecoder for decoding requests. Errors are reporting by throwing a
@@ -395,13 +401,13 @@
   RequestDecoder(this.request);
 
   @override
-  RefactoringKind get refactoringKind {
+  RefactoringKind? get refactoringKind {
     // Refactoring feedback objects should never appear in requests.
     return null;
   }
 
   @override
-  dynamic mismatch(String jsonPath, String expected, [Object actual]) {
+  Object mismatch(String jsonPath, String expected, [Object? actual]) {
     var buffer = StringBuffer();
     buffer.write('Expected to be ');
     buffer.write(expected);
@@ -415,7 +421,7 @@
   }
 
   @override
-  dynamic missingKey(String jsonPath, String key) {
+  Object missingKey(String jsonPath, String key) {
     return RequestFailure(RequestErrorFactory.invalidParameter(
         jsonPath, 'Expected to contain key ${json.encode(key)}'));
   }
@@ -431,12 +437,12 @@
 /// used only for testing. Errors are reported using bare [Exception] objects.
 class ResponseDecoder extends JsonDecoder {
   @override
-  final RefactoringKind refactoringKind;
+  final RefactoringKind? refactoringKind;
 
   ResponseDecoder(this.refactoringKind);
 
   @override
-  dynamic mismatch(String jsonPath, String expected, [Object actual]) {
+  Object mismatch(String jsonPath, String expected, [Object? actual]) {
     var buffer = StringBuffer();
     buffer.write('Expected ');
     buffer.write(expected);
@@ -451,7 +457,7 @@
   }
 
   @override
-  dynamic missingKey(String jsonPath, String key) {
+  Object missingKey(String jsonPath, String key) {
     return Exception('Missing key $key at $jsonPath');
   }
 }
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 58d3a20..eb1cded 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
@@ -17,24 +17,23 @@
 
 /// A builder used to build a [SourceChange].
 class ChangeBuilderImpl implements ChangeBuilder {
-  /// The workspace in which the change builder should operate, or `null` if no
-  /// Dart files will be changed.
+  /// The workspace in which the change builder should operate.
   final ChangeWorkspace workspace;
 
   /// The end-of-line marker used in the file being edited, or `null` if the
   /// default marker should be used.
-  final String eol;
+  final String? eol;
 
   /// A table mapping group ids to the associated linked edit groups.
   final Map<String, LinkedEditGroup> _linkedEditGroups =
       <String, LinkedEditGroup>{};
 
   /// The source change selection or `null` if none.
-  Position _selection;
+  Position? _selection;
 
   /// The range of the selection for the change being built, or `null` if there
   /// is no selection.
-  SourceRange _selectionRange;
+  SourceRange? _selectionRange;
 
   /// The set of [Position]s that belong to the current [EditBuilderImpl] and
   /// should not be updated in result of inserting this builder.
@@ -50,12 +49,12 @@
   /// create changes for Dart files, then either a [session] or a [workspace]
   /// must be provided (but not both).
   ChangeBuilderImpl(
-      {AnalysisSession session, ChangeWorkspace workspace, this.eol})
+      {AnalysisSession? session, ChangeWorkspace? workspace, this.eol})
       : assert(session == null || workspace == null),
-        workspace = workspace ?? _SingleSessionWorkspace(session);
+        workspace = workspace ?? _SingleSessionWorkspace(session!);
 
   @override
-  SourceRange get selectionRange => _selectionRange;
+  SourceRange? get selectionRange => _selectionRange;
 
   @override
   SourceChange get sourceChange {
@@ -75,8 +74,9 @@
     _linkedEditGroups.forEach((String name, LinkedEditGroup group) {
       change.addLinkedEditGroup(group);
     });
-    if (_selection != null) {
-      change.selection = _selection;
+    var selection = _selection;
+    if (selection != null) {
+      change.selection = selection;
     }
     return change;
   }
@@ -84,14 +84,14 @@
   @override
   Future<void> addDartFileEdit(
       String path, void Function(DartFileEditBuilder builder) buildFileEdit,
-      {ImportPrefixGenerator importPrefixGenerator}) async {
+      {ImportPrefixGenerator? importPrefixGenerator}) async {
     if (_genericFileEditBuilders.containsKey(path)) {
       throw StateError("Can't create both a generic file edit and a dart file "
           'edit for the same file');
     }
     var builder = _dartFileEditBuilders[path];
     if (builder == null) {
-      builder = await createDartFileEditBuilder(path);
+      builder = await _createDartFileEditBuilder(path);
       if (builder != null) {
         _dartFileEditBuilders[path] = builder;
       }
@@ -102,13 +102,6 @@
     }
   }
 
-  @Deprecated('Use either addDartFileEdit or addGenericFileEdit')
-  @override
-  Future<void> addFileEdit(
-      String path, void Function(FileEditBuilder builder) buildFileEdit) async {
-    return addGenericFileEdit(path, buildFileEdit);
-  }
-
   @override
   Future<void> addGenericFileEdit(
       String path, void Function(FileEditBuilder builder) buildFileEdit) async {
@@ -118,14 +111,10 @@
     }
     var builder = _genericFileEditBuilders[path];
     if (builder == null) {
-      builder = await createGenericFileEditBuilder(path);
-      if (builder != null) {
-        _genericFileEditBuilders[path] = builder;
-      }
+      builder = FileEditBuilderImpl(this, path, 0);
+      _genericFileEditBuilders[path] = builder;
     }
-    if (builder != null) {
-      buildFileEdit(builder);
-    }
+    buildFileEdit(builder);
   }
 
   @override
@@ -134,7 +123,10 @@
     for (var entry in _linkedEditGroups.entries) {
       copy._linkedEditGroups[entry.key] = _copyLinkedEditGroup(entry.value);
     }
-    copy._selection = _copyPosition(_selection);
+    var selection = _selection;
+    if (selection != null) {
+      copy._selection = _copyPosition(selection);
+    }
     copy._selectionRange = _selectionRange;
     copy._lockedPositions.addAll(_lockedPositions);
     for (var entry in _genericFileEditBuilders.entries) {
@@ -165,50 +157,6 @@
     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 {
-    // TODO(brianwilkerson) Make this method private when
-    //  `DartChangeBuilderImpl` is removed.
-    if (workspace == null) {
-      throw StateError("Can't create a DartFileEditBuilder without providing "
-          'either a session or a workspace');
-    }
-    if (!workspace.containsFile(path)) {
-      return null;
-    }
-
-    var session = workspace.getSession(path);
-    var result = await session.getResolvedUnit(path);
-    var state = result?.state ?? ResultState.INVALID_FILE_TYPE;
-    if (state == ResultState.INVALID_FILE_TYPE) {
-      throw AnalysisException('Cannot analyze "$path"');
-    }
-    var timeStamp = state == ResultState.VALID ? 0 : -1;
-
-    var declaredUnit = result.unit.declaredElement;
-    var libraryUnit = declaredUnit.library.definingCompilationUnit;
-
-    DartFileEditBuilderImpl libraryEditBuilder;
-    if (libraryUnit != declaredUnit) {
-      // If the receiver is a part file builder, then proactively cache the
-      // library file builder so that imports can be finalized synchronously.
-      await addDartFileEdit(libraryUnit.source.fullName, (builder) {
-        libraryEditBuilder = builder as DartFileEditBuilderImpl;
-      });
-    }
-
-    return DartFileEditBuilderImpl(this, result, timeStamp, libraryEditBuilder);
-  }
-
-  /// Create and return a [FileEditBuilder] that can be used to build edits to
-  /// the file with the given [path].
-  Future<FileEditBuilderImpl> createGenericFileEditBuilder(String path) async {
-    // TODO(brianwilkerson) Make this method private when
-    //  `DartChangeBuilderImpl` is removed.
-    return FileEditBuilderImpl(this, path, 0);
-  }
-
   /// Return the linked edit group with the given [groupName], creating it if it
   /// did not already exist.
   LinkedEditGroup getLinkedEditGroup(String groupName) {
@@ -233,7 +181,38 @@
 
   /// Return a copy of the [position].
   Position _copyPosition(Position position) {
-    return position == null ? null : Position(position.file, position.offset);
+    return Position(position.file, position.offset);
+  }
+
+  /// 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 {
+    if (path == null || !(workspace.containsFile(path) ?? false)) {
+      return null;
+    }
+
+    var session = workspace.getSession(path);
+    var result = await session?.getResolvedUnit(path);
+    var state = result?.state ?? ResultState.INVALID_FILE_TYPE;
+    if (state == ResultState.INVALID_FILE_TYPE) {
+      throw AnalysisException('Cannot analyze "$path"');
+    }
+    var timeStamp = state == ResultState.VALID ? 0 : -1;
+
+    var declaredUnit = result!.unit?.declaredElement;
+    var libraryUnit = declaredUnit?.library.definingCompilationUnit;
+
+    DartFileEditBuilderImpl? libraryEditBuilder;
+    if (libraryUnit != null && libraryUnit != declaredUnit) {
+      // If the receiver is a part file builder, then proactively cache the
+      // library file builder so that imports can be finalized synchronously.
+      await addDartFileEdit(libraryUnit.source.fullName, (builder) {
+        libraryEditBuilder = builder as DartFileEditBuilderImpl;
+      });
+    }
+
+    return DartFileEditBuilderImpl(this, result, timeStamp, libraryEditBuilder);
   }
 
   void _setSelectionRange(SourceRange range) {
@@ -255,8 +234,9 @@
         _updatePosition(position);
       }
     }
-    if (_selection != null) {
-      _updatePosition(_selection);
+    var selection = _selection;
+    if (selection != null) {
+      _updatePosition(selection);
     }
   }
 }
@@ -275,11 +255,11 @@
 
   /// The range of the selection for the change being built, or `null` if the
   /// selection is not inside the change being built.
-  SourceRange _selectionRange;
+  SourceRange? _selectionRange;
 
   /// The end-of-line marker used in the file being edited, or `null` if the
   /// default marker should be used.
-  String _eol;
+  String? _eol;
 
   /// The buffer in which the content of the edit is being composed.
   final StringBuffer _buffer = StringBuffer();
@@ -317,7 +297,7 @@
 
   @override
   void addSimpleLinkedEdit(String groupName, String text,
-      {LinkedEditSuggestionKind kind, List<String> suggestions}) {
+      {LinkedEditSuggestionKind? kind, List<String>? suggestions}) {
     addLinkedEdit(groupName, (LinkedEditBuilder builder) {
       builder.write(text);
       if (kind != null && suggestions != null) {
@@ -354,7 +334,7 @@
   }
 
   @override
-  void writeln([String string]) {
+  void writeln([String? string]) {
     if (string != null) {
       _buffer.write(string);
     }
@@ -561,7 +541,7 @@
   }
 
   @override
-  void writeln([String string]) {
+  void writeln([String? string]) {
     editBuilder.writeln(string);
   }
 }
@@ -573,14 +553,14 @@
   _SingleSessionWorkspace(this.session);
 
   @override
-  bool containsFile(String path) {
+  bool? containsFile(String path) {
     var analysisContext = session.analysisContext;
     return analysisContext.contextRoot.isAnalyzed(path);
   }
 
   @override
-  AnalysisSession getSession(String path) {
-    if (containsFile(path)) {
+  AnalysisSession? getSession(String path) {
+    if (containsFile(path) ?? false) {
       return session;
     }
     throw StateError('Not in a context root: $path');
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 6f0ab75..443c711 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
@@ -4,7 +4,6 @@
 
 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/ast/token.dart';
 import 'package:analyzer/dart/element/element.dart';
@@ -21,38 +20,8 @@
 import 'package:analyzer_plugin/src/utilities/string_utilities.dart';
 import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
 import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
-import 'package:analyzer_plugin/utilities/change_builder/change_workspace.dart';
 import 'package:analyzer_plugin/utilities/range_factory.dart';
 import 'package:dart_style/dart_style.dart';
-import 'package:meta/meta.dart';
-
-/// A [ChangeBuilder] used to build changes in Dart files.
-@Deprecated('Use ChangeBuilder')
-class DartChangeBuilderImpl extends ChangeBuilderImpl
-    implements DartChangeBuilder {
-  /// Initialize a newly created change builder.
-  @Deprecated('Use ChangeBuilder(session: session)')
-  DartChangeBuilderImpl(AnalysisSession session) : super(session: session);
-
-  @Deprecated('Use ChangeBuilder(workspace: workspace)')
-  DartChangeBuilderImpl.forWorkspace(ChangeWorkspace workspace)
-      : super(workspace: workspace);
-
-  @Deprecated('Use ChangeBuilder.addDartFileEdit')
-  @override
-  Future<void> addFileEdit(
-      String path, void Function(DartFileEditBuilder builder) buildFileEdit,
-      {ImportPrefixGenerator importPrefixGenerator}) {
-    return super.addDartFileEdit(path, buildFileEdit,
-        importPrefixGenerator: importPrefixGenerator);
-  }
-
-  @override
-  Future<DartFileEditBuilderImpl> createGenericFileEditBuilder(
-      String path) async {
-    return super.createDartFileEditBuilder(path);
-  }
-}
 
 /// An [EditBuilder] used to build edits in Dart files.
 class DartEditBuilderImpl extends EditBuilderImpl implements DartEditBuilder {
@@ -64,14 +33,14 @@
 
   /// The enclosing class element, possibly `null`.
   /// This field is lazily initialized in [_initializeEnclosingElements].
-  ClassElement _enclosingClass;
+  ClassElement? _enclosingClass;
 
   /// The enclosing executable element, possibly `null`.
   /// This field is lazily initialized in [_initializeEnclosingElements].
-  ExecutableElement _enclosingExecutable;
+  ExecutableElement? _enclosingExecutable;
 
   /// If not `null`, [write] will copy everything into this buffer.
-  StringBuffer _carbonCopyBuffer;
+  StringBuffer? _carbonCopyBuffer;
 
   /// Initialize a newly created builder to build a source edit.
   DartEditBuilderImpl(
@@ -103,13 +72,13 @@
 
   @override
   void writeClassDeclaration(String name,
-      {Iterable<DartType> interfaces,
+      {Iterable<DartType>? interfaces,
       bool isAbstract = false,
-      void Function() membersWriter,
-      Iterable<DartType> mixins,
-      String nameGroupName,
-      DartType superclass,
-      String superclassGroupName}) {
+      void Function()? membersWriter,
+      Iterable<DartType>? mixins,
+      String? nameGroupName,
+      DartType? superclass,
+      String? superclassGroupName}) {
     // TODO(brianwilkerson) Add support for type parameters, probably as a
     // parameterWriter parameter.
     if (isAbstract) {
@@ -141,15 +110,15 @@
 
   @override
   void writeConstructorDeclaration(String className,
-      {ArgumentList argumentList,
-      void Function() bodyWriter,
-      String classNameGroupName,
-      SimpleIdentifier constructorName,
-      String constructorNameGroupName,
-      List<String> fieldNames,
-      void Function() initializerWriter,
+      {ArgumentList? argumentList,
+      void Function()? bodyWriter,
+      String? classNameGroupName,
+      SimpleIdentifier? constructorName,
+      String? constructorNameGroupName,
+      List<String>? fieldNames,
+      void Function()? initializerWriter,
       bool isConst = false,
-      void Function() parameterWriter}) {
+      void Function()? parameterWriter}) {
     if (isConst) {
       write(Keyword.CONST.lexeme);
       write(' ');
@@ -197,13 +166,13 @@
 
   @override
   void writeFieldDeclaration(String name,
-      {void Function() initializerWriter,
+      {void Function()? initializerWriter,
       bool isConst = false,
       bool isFinal = false,
       bool isStatic = false,
-      String nameGroupName,
-      DartType type,
-      String typeGroupName}) {
+      String? nameGroupName,
+      DartType? type,
+      String? typeGroupName}) {
     if (isStatic) {
       write(Keyword.STATIC.lexeme);
       write(' ');
@@ -239,12 +208,12 @@
 
   @override
   void writeFunctionDeclaration(String name,
-      {void Function() bodyWriter,
+      {void Function()? bodyWriter,
       bool isStatic = false,
-      String nameGroupName,
-      void Function() parameterWriter,
-      DartType returnType,
-      String returnTypeGroupName}) {
+      String? nameGroupName,
+      void Function()? parameterWriter,
+      DartType? returnType,
+      String? returnTypeGroupName}) {
     if (isStatic) {
       write(Keyword.STATIC.lexeme);
       write(' ');
@@ -278,11 +247,11 @@
 
   @override
   void writeGetterDeclaration(String name,
-      {void Function() bodyWriter,
+      {void Function()? bodyWriter,
       bool isStatic = false,
-      String nameGroupName,
-      DartType returnType,
-      String returnTypeGroupName}) {
+      String? nameGroupName,
+      DartType? returnType,
+      String? returnTypeGroupName}) {
     if (isStatic) {
       write(Keyword.STATIC.lexeme);
       write(' ');
@@ -317,13 +286,15 @@
     var import = _getBestImportForName(imports, name);
     if (import == null) {
       var library = dartFileEditBuilder._importLibrary(uris[0]);
-      if (library.prefix != null) {
-        write(library.prefix);
+      var prefix = library.prefix;
+      if (prefix != null) {
+        write(prefix);
         write('.');
       }
     } else {
-      if (import.prefix != null) {
-        write(import.prefix.displayName);
+      var prefix = import.prefix;
+      if (prefix != null) {
+        write(prefix.displayName);
         write('.');
       }
     }
@@ -332,12 +303,12 @@
 
   @override
   void writeLocalVariableDeclaration(String name,
-      {void Function() initializerWriter,
+      {void Function()? initializerWriter,
       bool isConst = false,
       bool isFinal = false,
-      String nameGroupName,
-      DartType type,
-      String typeGroupName}) {
+      String? nameGroupName,
+      DartType? type,
+      String? typeGroupName}) {
     var typeRequired = true;
     if (isConst) {
       write(Keyword.CONST.lexeme);
@@ -370,10 +341,10 @@
 
   @override
   void writeMixinDeclaration(String name,
-      {Iterable<DartType> interfaces,
-      void Function() membersWriter,
-      String nameGroupName,
-      Iterable<DartType> superclassConstraints}) {
+      {Iterable<DartType>? interfaces,
+      void Function()? membersWriter,
+      String? nameGroupName,
+      Iterable<DartType>? superclassConstraints}) {
     // TODO(brianwilkerson) Add support for type parameters, probably as a
     // parameterWriter parameter.
     write('mixin ');
@@ -394,8 +365,8 @@
   @override
   void writeOverride(
     ExecutableElement element, {
-    StringBuffer displayTextBuffer,
-    String returnTypeGroupName,
+    StringBuffer? displayTextBuffer,
+    String? returnTypeGroupName,
     bool invokeSuper = false,
   }) {
     void withCarbonCopyBuffer(Function() f) {
@@ -536,13 +507,13 @@
   void writeParameter(String name,
       {bool isCovariant = false,
       bool isRequiredNamed = false,
-      ExecutableElement methodBeingCopied,
-      String nameGroupName,
-      DartType type,
-      String typeGroupName}) {
+      ExecutableElement? methodBeingCopied,
+      String? nameGroupName,
+      DartType? type,
+      String? typeGroupName}) {
     bool writeType() {
       if (typeGroupName != null) {
-        bool hasType;
+        late bool hasType;
         addLinkedEdit(typeGroupName, (DartLinkedEditBuilder builder) {
           hasType = _writeType(type, methodBeingCopied: methodBeingCopied);
           builder.addSuperTypesAsSuggestions(type);
@@ -619,7 +590,7 @@
 
   @override
   void writeParameters(Iterable<ParameterElement> parameters,
-      {ExecutableElement methodBeingCopied}) {
+      {ExecutableElement? methodBeingCopied}) {
     var parameterNames = <String>{};
     for (var i = 0; i < parameters.length; i++) {
       var name = parameters.elementAt(i).name;
@@ -713,11 +684,11 @@
 
   @override
   void writeSetterDeclaration(String name,
-      {void Function() bodyWriter,
+      {void Function()? bodyWriter,
       bool isStatic = false,
-      String nameGroupName,
-      DartType parameterType,
-      String parameterTypeGroupName}) {
+      String? nameGroupName,
+      DartType? parameterType,
+      String? parameterTypeGroupName}) {
     if (isStatic) {
       write(Keyword.STATIC.lexeme);
       write(' ');
@@ -747,10 +718,10 @@
   }
 
   @override
-  bool writeType(DartType type,
+  bool writeType(DartType? type,
       {bool addSupertypeProposals = false,
-      String groupName,
-      ExecutableElement methodBeingCopied,
+      String? groupName,
+      ExecutableElement? methodBeingCopied,
       bool required = false}) {
     var wroteType = false;
     if (type != null && !type.isDynamic) {
@@ -774,7 +745,7 @@
 
   @override
   void writeTypeParameter(TypeParameterElement typeParameter,
-      {ExecutableElement methodBeingCopied}) {
+      {ExecutableElement? methodBeingCopied}) {
     write(typeParameter.name);
     if (typeParameter.bound != null) {
       write(' extends ');
@@ -784,7 +755,7 @@
 
   @override
   void writeTypeParameters(List<TypeParameterElement> typeParameters,
-      {ExecutableElement methodBeingCopied}) {
+      {ExecutableElement? methodBeingCopied}) {
     if (typeParameters.isNotEmpty) {
       write('<');
       var isFirst = true;
@@ -800,7 +771,7 @@
   }
 
   @override
-  void writeTypes(Iterable<DartType> types, {String prefix}) {
+  void writeTypes(Iterable<DartType>? types, {String? prefix}) {
     if (types == null || types.isEmpty) {
       return;
     }
@@ -854,7 +825,7 @@
   }
 
   void _addSuperTypeProposals(
-      LinkedEditBuilder builder, DartType type, Set<DartType> alreadyAdded) {
+      LinkedEditBuilder builder, DartType? type, Set<DartType> alreadyAdded) {
     if (type is InterfaceType && alreadyAdded.add(type)) {
       builder.addSuggestion(
         LinkedEditSuggestionKind.TYPE,
@@ -879,7 +850,7 @@
     return name;
   }
 
-  String _getBaseNameFromExpression(Expression expression) {
+  String? _getBaseNameFromExpression(Expression expression) {
     if (expression is AsExpression) {
       return _getBaseNameFromExpression(expression.expression);
     } else if (expression is ParenthesizedExpression) {
@@ -888,7 +859,7 @@
     return _getBaseNameFromUnwrappedExpression(expression);
   }
 
-  String _getBaseNameFromLocationInParent(Expression expression) {
+  String? _getBaseNameFromLocationInParent(Expression expression) {
     // value in named expression
     if (expression.parent is NamedExpression) {
       var namedExpression = expression.parent as NamedExpression;
@@ -906,8 +877,8 @@
     return null;
   }
 
-  String _getBaseNameFromUnwrappedExpression(Expression expression) {
-    String name;
+  String? _getBaseNameFromUnwrappedExpression(Expression expression) {
+    String? name;
     // analyze expressions
     if (expression is SimpleIdentifier) {
       return expression.name;
@@ -920,22 +891,20 @@
     } else if (expression is InstanceCreationExpression) {
       var constructorName = expression.constructorName;
       var typeName = constructorName.type;
-      if (typeName != null) {
-        var typeNameIdentifier = typeName.name;
-        // new ClassName()
-        if (typeNameIdentifier is SimpleIdentifier) {
-          return typeNameIdentifier.name;
+      var typeNameIdentifier = typeName.name;
+      // new ClassName()
+      if (typeNameIdentifier is SimpleIdentifier) {
+        return typeNameIdentifier.name;
+      }
+      // new prefix.name();
+      if (typeNameIdentifier is PrefixedIdentifier) {
+        var prefixed = typeNameIdentifier;
+        // new prefix.ClassName()
+        if (prefixed.prefix.staticElement is PrefixElement) {
+          return prefixed.identifier.name;
         }
-        // new prefix.name();
-        if (typeNameIdentifier is PrefixedIdentifier) {
-          var prefixed = typeNameIdentifier;
-          // new prefix.ClassName()
-          if (prefixed.prefix.staticElement is PrefixElement) {
-            return prefixed.identifier.name;
-          }
-          // new ClassName.constructorName()
-          return prefixed.prefix.name;
-        }
+        // new ClassName.constructorName()
+        return prefixed.prefix.name;
       }
     } else if (expression is IndexExpression) {
       name = _getBaseNameFromExpression(expression.realTarget);
@@ -966,7 +935,7 @@
 
   /// Given a list of [imports] that do, or can, make the [name] visible in
   /// scope, return the one that will lead to the cleanest code.
-  ImportElement _getBestImportForName(
+  ImportElement? _getBestImportForName(
       List<ImportElement> imports, String name) {
     if (imports.isEmpty) {
       return null;
@@ -992,7 +961,7 @@
   }
 
   /// Returns all variants of names by removing leading words one by one.
-  List<String> _getCamelWordCombinations(String name) {
+  List<String> _getCamelWordCombinations(String? name) {
     var result = <String>[];
     var parts = getCamelWords(name);
     for (var i = 0; i < parts.length; i++) {
@@ -1023,8 +992,8 @@
 
   /// Returns possible names for a variable with the given expected type and
   /// expression assigned.
-  List<String> _getVariableNameSuggestionsForExpression(DartType expectedType,
-      Expression assignedExpression, Set<String> excluded) {
+  List<String> _getVariableNameSuggestionsForExpression(DartType? expectedType,
+      Expression? assignedExpression, Set<String> excluded) {
     var res = <String>{};
     // use expression
     if (assignedExpression != null) {
@@ -1059,8 +1028,8 @@
   /// [_enclosingClass], or if there is a local equivalent to the type (such as
   /// in the case of a type parameter from a superclass), then return the type
   /// that is locally visible. Otherwise, return `null`.
-  DartType _getVisibleType(DartType type,
-      {ExecutableElement methodBeingCopied}) {
+  DartType? _getVisibleType(DartType? type,
+      {ExecutableElement? methodBeingCopied}) {
     if (type is InterfaceType) {
       var element = type.element;
       if (element.isPrivate &&
@@ -1075,7 +1044,7 @@
       var enclosing = element.enclosingElement;
       while (enclosing is GenericFunctionTypeElement ||
           enclosing is ParameterElement) {
-        enclosing = enclosing.enclosingElement;
+        enclosing = enclosing!.enclosingElement;
       }
       if (enclosing == _enclosingExecutable ||
           enclosing == _enclosingClass ||
@@ -1119,16 +1088,20 @@
 
     var import = dartFileEditBuilder._getImportElement(element);
     if (import != null) {
-      if (import.prefix != null) {
-        write(import.prefix.displayName);
+      var prefix = import.prefix;
+      if (prefix != null) {
+        write(prefix.displayName);
         write('.');
       }
     } else {
-      var library = element.library.source.uri;
-      var import = dartFileEditBuilder._importLibrary(library);
-      if (import.prefix != null) {
-        write(import.prefix);
-        write('.');
+      var library = element.library?.source.uri;
+      if (library != null) {
+        var import = dartFileEditBuilder._importLibrary(library);
+        var prefix = import.prefix;
+        if (prefix != null) {
+          write(prefix);
+          write('.');
+        }
       }
     }
   }
@@ -1158,8 +1131,8 @@
   ///
   /// Causes any libraries whose elements are used by the generated code, to be
   /// imported.
-  bool _writeType(DartType type,
-      {ExecutableElement methodBeingCopied, bool required = false}) {
+  bool _writeType(DartType? type,
+      {ExecutableElement? methodBeingCopied, bool required = false}) {
     type = _getVisibleType(type, methodBeingCopied: methodBeingCopied);
 
     // If not a useful type, don't write it.
@@ -1183,10 +1156,11 @@
     }
 
     var aliasElement = type.aliasElement;
-    if (aliasElement != null) {
+    var aliasArguments = type.aliasArguments;
+    if (aliasElement != null && aliasArguments != null) {
       _writeTypeElementArguments(
         element: aliasElement,
-        typeArguments: type.aliasArguments,
+        typeArguments: aliasArguments,
         methodBeingCopied: methodBeingCopied,
       );
       _writeTypeNullability(type);
@@ -1235,9 +1209,9 @@
   }
 
   void _writeTypeElementArguments({
-    @required Element element,
-    @required List<DartType> typeArguments,
-    @required ExecutableElement methodBeingCopied,
+    required Element element,
+    required List<DartType> typeArguments,
+    required ExecutableElement? methodBeingCopied,
   }) {
     // Ensure that the element is imported.
     _writeLibraryReference(element);
@@ -1288,10 +1262,10 @@
 
   /// The change builder for the library
   /// or `null` if the receiver is the builder for the library.
-  final DartFileEditBuilderImpl libraryChangeBuilder;
+  final DartFileEditBuilderImpl? libraryChangeBuilder;
 
   /// The optional generator of prefixes for new imports.
-  ImportPrefixGenerator importPrefixGenerator;
+  ImportPrefixGenerator? importPrefixGenerator;
 
   /// A mapping from libraries that need to be imported in order to make visible
   /// the names used in generated code, to information about these imports.
@@ -1307,7 +1281,7 @@
   /// the given [resolvedUnit] and [timeStamp].
   DartFileEditBuilderImpl(ChangeBuilderImpl changeBuilder, this.resolvedUnit,
       int timeStamp, this.libraryChangeBuilder)
-      : super(changeBuilder, resolvedUnit.path, timeStamp);
+      : super(changeBuilder, resolvedUnit.path!, timeStamp);
 
   @override
   bool get hasEdits =>
@@ -1329,8 +1303,8 @@
 
   @override
   void convertFunctionFromSyncToAsync(
-      FunctionBody body, TypeProvider typeProvider) {
-    if (body == null && body.keyword != null) {
+      FunctionBody? body, TypeProvider typeProvider) {
+    if (body == null || body.keyword != null) {
       throw ArgumentError(
           'The function must have a synchronous, non-generator body.');
     }
@@ -1379,7 +1353,7 @@
 
   @override
   void format(SourceRange range) {
-    var newContent = resolvedUnit.content;
+    var newContent = resolvedUnit.content!;
     var newRangeOffset = range.offset;
     var newRangeLength = range.length;
     for (var edit in fileEdit.edits) {
@@ -1434,13 +1408,13 @@
     return ImportLibraryElementResultImpl(null);
   }
 
-  String importLibraryWithRelativeUri(String uriText, [String prefix]) {
+  String importLibraryWithRelativeUri(String uriText, [String? prefix]) {
     return _importLibraryWithRelativeUri(uriText, prefix).uriText;
   }
 
   @override
   void replaceTypeWithFuture(
-      TypeAnnotation typeAnnotation, TypeProvider typeProvider) {
+      TypeAnnotation? typeAnnotation, TypeProvider typeProvider) {
     //
     // Check whether the type needs to be replaced.
     //
@@ -1449,7 +1423,7 @@
       return;
     }
 
-    addReplacement(range.node(typeAnnotation), (EditBuilder builder) {
+    addReplacement(range.node(typeAnnotation!), (EditBuilder builder) {
       var futureType = typeProvider.futureType(type);
       if (!(builder as DartEditBuilder).writeType(futureType)) {
         builder.write('void');
@@ -1460,10 +1434,11 @@
   /// Adds edits ensure that all the [imports] are imported into the library.
   void _addLibraryImports(Iterable<_LibraryToImport> imports) {
     // Prepare information about existing imports.
-    LibraryDirective libraryDirective;
+    LibraryDirective? libraryDirective;
     var importDirectives = <ImportDirective>[];
-    PartDirective partDirective;
-    for (var directive in resolvedUnit.unit.directives) {
+    PartDirective? partDirective;
+    var unit = resolvedUnit.unit!;
+    for (var directive in unit.directives) {
       if (directive is LibraryDirective) {
         libraryDirective = directive;
       } else if (directive is ImportDirective) {
@@ -1481,9 +1456,10 @@
       builder.write("import '");
       builder.write(import.uriText);
       builder.write("'");
-      if (import.prefix != null) {
+      var prefix = import.prefix;
+      if (prefix != null) {
         builder.write(' as ');
-        builder.write(import.prefix);
+        builder.write(prefix);
       }
       builder.write(';');
     }
@@ -1496,14 +1472,14 @@
         var inserted = false;
 
         void insert(
-            {ImportDirective prev,
-            ImportDirective next,
+            {ImportDirective? prev,
+            required ImportDirective next,
             bool trailingNewLine = false}) {
           var lineInfo = resolvedUnit.lineInfo;
           if (prev != null) {
             var offset = prev.end;
             var line = lineInfo.getLocation(offset).lineNumber;
-            Token comment = prev.endToken.next.precedingComments;
+            Token? comment = prev.endToken.next?.precedingComments;
             while (comment != null) {
               if (lineInfo.getLocation(comment.offset).lineNumber == line) {
                 offset = comment.end;
@@ -1534,9 +1510,9 @@
           inserted = true;
         }
 
-        ImportDirective lastExisting;
-        ImportDirective lastExistingDart;
-        ImportDirective lastExistingPackage;
+        ImportDirective? lastExisting;
+        ImportDirective? lastExistingDart;
+        ImportDirective? lastExistingPackage;
         var isLastExistingDart = false;
         var isLastExistingPackage = false;
         for (var existingImport in importDirectives) {
@@ -1581,7 +1557,7 @@
           isLastExistingPackage = isExistingPackage;
         }
         if (!inserted) {
-          addInsertion(lastExisting.end, (EditBuilder builder) {
+          addInsertion(lastExisting!.end, (EditBuilder builder) {
             if (isPackage) {
               if (isLastExistingDart) {
                 builder.writeln();
@@ -1631,11 +1607,11 @@
     // If still at the beginning of the file, add before the first declaration.
     int offset;
     var insertEmptyLineAfter = false;
-    if (resolvedUnit.unit.declarations.isNotEmpty) {
-      offset = resolvedUnit.unit.declarations.first.offset;
+    if (unit.declarations.isNotEmpty) {
+      offset = unit.declarations.first.offset;
       insertEmptyLineAfter = true;
     } else {
-      offset = resolvedUnit.unit.end;
+      offset = unit.end;
     }
     addInsertion(offset, (EditBuilder builder) {
       for (var i = 0; i < importList.length; i++) {
@@ -1652,7 +1628,7 @@
   /// Return the import element used to import the given [element] into the
   /// target library, or `null` if the element was not imported, such as when
   /// the element is declared in the same library.
-  ImportElement _getImportElement(Element element) {
+  ImportElement? _getImportElement(Element element) {
     for (var import in resolvedUnit.libraryElement.imports) {
       var definedNames = import.namespace.definedNames;
       if (definedNames.containsValue(element)) {
@@ -1664,7 +1640,7 @@
 
   Iterable<ImportElement> _getImportsForUri(Uri uri) sync* {
     for (var import in resolvedUnit.libraryElement.imports) {
-      var importUri = import.importedLibrary.source.uri;
+      var importUri = import.importedLibrary?.source.uri;
       if (importUri == uri) {
         yield import;
       }
@@ -1690,7 +1666,7 @@
     if (import == null) {
       var uriText = _getLibraryUriText(uri);
       var prefix =
-          importPrefixGenerator != null ? importPrefixGenerator(uri) : null;
+          importPrefixGenerator != null ? importPrefixGenerator!(uri) : null;
       import = _LibraryToImport(uriText, prefix);
       (libraryChangeBuilder ?? this).librariesToImport[uri] = import;
     }
@@ -1700,7 +1676,7 @@
   /// Arrange to have an import added for the library with the given relative
   /// [uriText].
   _LibraryToImport _importLibraryWithRelativeUri(String uriText,
-      [String prefix]) {
+      [String? prefix]) {
     var import = librariesToRelativelyImport[uriText];
     if (import == null) {
       import = _LibraryToImport(uriText, prefix);
@@ -1718,7 +1694,7 @@
   /// containing the given [node] with the type `Future`. The [typeProvider] is
   /// used to check the current return type, because if it is already `Future`
   /// no edit will be added.
-  void _replaceReturnTypeWithFuture(AstNode node, TypeProvider typeProvider) {
+  void _replaceReturnTypeWithFuture(AstNode? node, TypeProvider typeProvider) {
     while (node != null) {
       node = node.parent;
       if (node is FunctionDeclaration) {
@@ -1736,7 +1712,7 @@
   }
 
   static bool _isFusedWithPreviousToken(Token token) {
-    return token.previous.end == token.offset;
+    return token.previous?.end == token.offset;
   }
 }
 
@@ -1749,13 +1725,13 @@
   DartLinkedEditBuilderImpl(EditBuilderImpl editBuilder) : super(editBuilder);
 
   @override
-  void addSuperTypesAsSuggestions(DartType type) {
+  void addSuperTypesAsSuggestions(DartType? type) {
     _addSuperTypesAsSuggestions(type, <DartType>{});
   }
 
   /// Safely implement [addSuperTypesAsSuggestions] by using the set of
   /// [alreadyAdded] types to prevent infinite loops.
-  void _addSuperTypesAsSuggestions(DartType type, Set<DartType> alreadyAdded) {
+  void _addSuperTypesAsSuggestions(DartType? type, Set<DartType> alreadyAdded) {
     if (type is InterfaceType && alreadyAdded.add(type)) {
       addSuggestion(
         LinkedEditSuggestionKind.TYPE,
@@ -1772,18 +1748,18 @@
 /// Information about a library to import.
 class ImportLibraryElementResultImpl implements ImportLibraryElementResult {
   @override
-  final String prefix;
+  final String? prefix;
 
   ImportLibraryElementResultImpl(this.prefix);
 }
 
 class _EnclosingElementFinder {
-  ClassElement enclosingClass;
-  ExecutableElement enclosingExecutable;
+  ClassElement? enclosingClass;
+  ExecutableElement? enclosingExecutable;
 
   _EnclosingElementFinder();
 
-  void find(AstNode target, int offset) {
+  void find(AstNode? target, int offset) {
     var node = NodeLocator2(offset).searchWithin(target);
     while (node != null) {
       if (node is ClassDeclaration) {
@@ -1803,7 +1779,7 @@
 /// Information about a new library to import.
 class _LibraryToImport {
   final String uriText;
-  final String prefix;
+  final String? prefix;
 
   _LibraryToImport(this.uriText, this.prefix);
 
diff --git a/pkg/analyzer_plugin/lib/src/utilities/completion/completion_core.dart b/pkg/analyzer_plugin/lib/src/utilities/completion/completion_core.dart
index a2e052a..b0e6bdc 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/completion/completion_core.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/completion/completion_core.dart
@@ -11,11 +11,11 @@
 class CompletionCollectorImpl implements CompletionCollector {
   /// The length of the region of text that should be replaced by the selected
   /// completion suggestion.
-  int _length;
+  int? _length;
 
   /// The offset of the region of text that should be replaced by the selected
   /// completion suggestion.
-  int _offset;
+  int? _offset;
 
   /// A list of the completion suggestions that have been collected.
   List<CompletionSuggestion> suggestions = <CompletionSuggestion>[];
@@ -25,10 +25,10 @@
 
   /// Return the length of the region of text that should be replaced by the
   /// selected completion suggestion, or `null` if the length has not been set.
-  int get length => _length;
+  int? get length => _length;
 
   @override
-  set length(int length) {
+  set length(int? length) {
     if (_length != null) {
       throw StateError('The length can only be set once');
     }
@@ -37,10 +37,10 @@
 
   /// Return the offset of the region of text that should be replaced by the
   /// selected completion suggestion, or `null` if the offset has not been set.
-  int get offset => _offset;
+  int? get offset => _offset;
 
   @override
-  set offset(int length) {
+  set offset(int? length) {
     if (_offset != null) {
       throw StateError('The offset can only be set once');
     }
diff --git a/pkg/analyzer_plugin/lib/src/utilities/completion/completion_target.dart b/pkg/analyzer_plugin/lib/src/utilities/completion/completion_target.dart
index 0b47a56..4781140 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/completion/completion_target.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/completion/completion_target.dart
@@ -86,7 +86,7 @@
   /// or keyword that is part of the token stream, but that the parser has
   /// skipped and not reported in to the parser listeners, meaning that it is
   /// not part of the AST.
-  Token droppedToken;
+  Token? droppedToken;
 
   /// 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
@@ -97,7 +97,7 @@
   /// possible). However, there is one exception: when the cursor is inside of
   /// a multi-character token which is not a keyword or identifier (e.g. a
   /// comment, or a token like "+=", the entity will be always be the token.
-  final SyntacticEntity entity;
+  final SyntacticEntity? entity;
 
   /// The [entity] is a comment token, which is either not a documentation
   /// comment or the position is not in a [CommentReference].
@@ -105,21 +105,21 @@
 
   /// If the target is an argument in an [ArgumentList], then this is the index
   /// of the argument in the list, otherwise this is `null`.
-  final int argIndex;
+  final int? argIndex;
 
   /// If the target is an argument in an [ArgumentList], then this is the
   /// invoked [ExecutableElement], otherwise this is `null`.
-  ExecutableElement _executableElement;
+  ExecutableElement? _executableElement;
 
   /// If the target is in an argument list of a [FunctionExpressionInvocation],
   /// then this is the static type of the function being invoked, otherwise this
   /// is `null`.
-  FunctionType _functionType;
+  FunctionType? _functionType;
 
   /// If the target is an argument in an [ArgumentList], then this is the
   /// corresponding [ParameterElement] in the invoked [ExecutableElement],
   /// otherwise this is `null`.
-  ParameterElement _parameterElement;
+  ParameterElement? _parameterElement;
 
   /// Compute the appropriate [CompletionTarget] for the given [offset] within
   /// the [compilationUnit].
@@ -129,7 +129,7 @@
   /// [compilationUnit] such as dart expressions within angular templates.
   factory CompletionTarget.forOffset(
       CompilationUnit compilationUnit, int offset,
-      {AstNode entryPoint}) {
+      {AstNode? entryPoint}) {
     // The precise algorithm is as follows. We perform a depth-first search of
     // all edges in the parse tree (both those that point to AST nodes and
     // those that point to tokens), visiting parents before children. The
@@ -151,7 +151,7 @@
       if (containingNode is Comment) {
         // Comments are handled specially: we descend into any CommentReference
         // child node that contains the cursor offset.
-        var comment = containingNode as Comment;
+        var comment = containingNode;
         for (var commentReference in comment.references) {
           if (commentReference.offset <= offset &&
               offset <= commentReference.end) {
@@ -245,7 +245,7 @@
   /// Create a [CompletionTarget] holding the given [containingNode] and
   /// [entity].
   CompletionTarget._(this.unit, this.offset, AstNode containingNode,
-      SyntacticEntity entity, this.isCommentText)
+      SyntacticEntity? entity, this.isCommentText)
       : containingNode = containingNode,
         entity = entity,
         argIndex = _computeArgIndex(containingNode, entity),
@@ -253,9 +253,9 @@
 
   /// If the target is an argument in an argument list, and the invocation is
   /// resolved, return the invoked [ExecutableElement].
-  ExecutableElement get executableElement {
+  ExecutableElement? get executableElement {
     if (_executableElement == null) {
-      var argumentList = containingNode;
+      AstNode? argumentList = containingNode;
       if (argumentList is NamedExpression) {
         argumentList = argumentList.parent;
       }
@@ -265,7 +265,7 @@
 
       var invocation = argumentList.parent;
 
-      Element executable;
+      Element? executable;
       if (invocation is Annotation) {
         executable = invocation.element;
       } else if (invocation is InstanceCreationExpression) {
@@ -286,9 +286,9 @@
   /// If the target is in an argument list of a [FunctionExpressionInvocation],
   /// then this is the static type of the function being invoked, otherwise this
   /// is `null`.
-  FunctionType get functionType {
+  FunctionType? get functionType {
     if (_functionType == null) {
-      var argumentList = containingNode;
+      AstNode? argumentList = containingNode;
       if (argumentList is NamedExpression) {
         argumentList = argumentList.parent;
       }
@@ -319,14 +319,17 @@
       return node.isCascaded && offset > node.operator.offset + 1;
     }
     if (node is MethodInvocation) {
-      return node.isCascaded && offset > node.operator.offset + 1;
+      var operator = node.operator;
+      if (operator != null) {
+        return node.isCascaded && offset > operator.offset + 1;
+      }
     }
     return false;
   }
 
   /// If the target is an argument in an argument list, and the invocation is
   /// resolved, return the corresponding [ParameterElement].
-  ParameterElement get parameterElement {
+  ParameterElement? get parameterElement {
     if (_parameterElement == null) {
       var executable = executableElement;
       if (executable != null) {
@@ -345,7 +348,7 @@
         token.type.isKeyword || token.type == TokenType.IDENTIFIER;
 
     var token = droppedToken ??
-        (entity is AstNode ? (entity as AstNode).beginToken : entity as Token);
+        (entity is AstNode ? (entity as AstNode).beginToken : entity as Token?);
     if (token != null && requestOffset < token.offset) {
       token = containingNode.findPrevious(token);
     }
@@ -399,7 +402,7 @@
 
   /// Given that the [node] contains the [offset], return the [FormalParameter]
   /// that encloses the [offset], or `null`.
-  static FormalParameter findFormalParameter(
+  static FormalParameter? findFormalParameter(
     FormalParameterList node,
     int offset,
   ) {
@@ -423,8 +426,8 @@
     return null;
   }
 
-  static int _computeArgIndex(AstNode containingNode, Object entity) {
-    var argList = containingNode;
+  static int? _computeArgIndex(AstNode containingNode, Object? entity) {
+    AstNode? argList = containingNode;
     if (argList is NamedExpression) {
       entity = argList;
       argList = argList.parent;
@@ -451,8 +454,8 @@
     return null;
   }
 
-  static Token _computeDroppedToken(
-      AstNode containingNode, Object entity, int offset) {
+  static Token? _computeDroppedToken(
+      AstNode containingNode, Object? entity, int offset) {
     // Find the last token of the member before the entity.
     var previousMember;
     for (var member in containingNode.childEntities) {
@@ -463,7 +466,7 @@
         previousMember = member;
       }
     }
-    Token token;
+    Token? token;
     if (previousMember is AstNode) {
       token = previousMember.endToken;
     } else if (previousMember is Token) {
@@ -474,7 +477,7 @@
     }
 
     // Find the first token of the entity (which may be the entity itself).
-    Token endSearch;
+    Token? endSearch;
     if (entity is AstNode) {
       endSearch = entity.beginToken;
     } else if (entity is Token) {
@@ -486,7 +489,7 @@
 
     // Find a dropped token that overlaps the offset.
     token = token.next;
-    while (token != endSearch && !token.isEof) {
+    while (token != endSearch && !token!.isEof) {
       if (token.isKeywordOrIdentifier &&
           token.offset <= offset &&
           offset <= token.end) {
@@ -499,7 +502,7 @@
 
   /// Determine if the offset is contained in a preceding comment token
   /// and return that token, otherwise return `null`.
-  static Token _getContainingCommentToken(Token token, int offset) {
+  static Token? _getContainingCommentToken(Token? token, int offset) {
     if (token == null) {
       return null;
     }
@@ -522,7 +525,7 @@
   }
 
   /// Determine if the given token is part of the given node's dart doc.
-  static Comment _getContainingDocComment(AstNode node, Token token) {
+  static Comment? _getContainingDocComment(AstNode node, Token token) {
     if (node is AnnotatedNode) {
       var docComment = node.documentationComment;
       if (docComment != null && docComment.tokens.contains(token)) {
@@ -534,13 +537,13 @@
 
   /// Return the [ParameterElement] that corresponds to the given [argumentNode]
   /// at the given [argumentIndex].
-  static ParameterElement _getParameterElement(
+  static ParameterElement? _getParameterElement(
     List<ParameterElement> parameters,
     AstNode argumentNode,
-    int argumentIndex,
+    int? argumentIndex,
   ) {
     if (argumentNode is NamedExpression) {
-      var name = argumentNode.name?.label?.name;
+      var name = argumentNode.name.label.name;
       for (var parameter in parameters) {
         if (parameter.name == name) {
           return parameter;
@@ -549,7 +552,7 @@
       return null;
     }
 
-    if (argumentIndex < parameters.length) {
+    if (argumentIndex != null && argumentIndex < parameters.length) {
       return parameters[argumentIndex];
     }
 
@@ -575,7 +578,7 @@
 
   /// Determine whether [token] could possibly be the [entity] for a
   /// [CompletionTarget] associated with the given [offset].
-  static bool _isCandidateToken(AstNode node, Token token, int offset) {
+  static bool _isCandidateToken(AstNode node, Token? token, int offset) {
     if (token == null) {
       return false;
     }
diff --git a/pkg/analyzer_plugin/lib/src/utilities/completion/element_suggestion_builder.dart b/pkg/analyzer_plugin/lib/src/utilities/completion/element_suggestion_builder.dart
index 298c5b5..127cb49 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/completion/element_suggestion_builder.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/completion/element_suggestion_builder.dart
@@ -24,17 +24,17 @@
       <String, CompletionSuggestion>{};
 
   /// Return the library in which the completion is requested.
-  LibraryElement get containingLibrary;
+  LibraryElement? get containingLibrary;
 
   /// Return the kind of suggestions that should be built.
-  CompletionSuggestionKind get kind;
+  CompletionSuggestionKind? get kind;
 
   /// Return the resource provider used to access the file system.
-  ResourceProvider get resourceProvider;
+  ResourceProvider? get resourceProvider;
 
   /// Add a suggestion based upon the given element.
   void addSuggestion(Element element,
-      {String prefix, int relevance = DART_RELEVANCE_DEFAULT}) {
+      {String? prefix, int relevance = DART_RELEVANCE_DEFAULT}) {
     if (element.isPrivate) {
       if (element.library != containingLibrary) {
         return;
@@ -42,13 +42,13 @@
     }
     var completion = element.displayName;
     if (prefix != null && prefix.isNotEmpty) {
-      if (completion == null || completion.isEmpty) {
+      if (completion.isEmpty) {
         completion = prefix;
       } else {
         completion = '$prefix.$completion';
       }
     }
-    if (completion == null || completion.isEmpty) {
+    if (completion.isEmpty) {
       return;
     }
     var builder = SuggestionBuilderImpl(resourceProvider);
@@ -56,7 +56,7 @@
         completion: completion, kind: kind, relevance: relevance);
     if (suggestion != null) {
       if (element.isSynthetic && element is PropertyAccessorElement) {
-        String cacheKey;
+        String? cacheKey;
         if (element.isGetter) {
           cacheKey = element.name;
         }
@@ -75,10 +75,10 @@
                 : protocol.ElementKind.TOP_LEVEL_VARIABLE;
             existingSuggestion.element = protocol.Element(
                 elemKind,
-                existingSuggestion.element.name,
-                existingSuggestion.element.flags,
-                location: getter.element.location,
-                typeParameters: getter.element.typeParameters,
+                existingSuggestion.element!.name,
+                existingSuggestion.element!.flags,
+                location: getter.element?.location,
+                typeParameters: getter.element?.typeParameters,
                 parameters: null,
                 returnType: getter.returnType);
             return;
diff --git a/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart b/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart
index ae49588..7148d29 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart
@@ -1,7 +1,6 @@
 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/syntactic_entity.dart';
 import 'package:analyzer/dart/ast/token.dart';
@@ -13,15 +12,16 @@
 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:collection/collection.dart';
 
-typedef SuggestionsFilter = int Function(DartType dartType, int relevance);
+typedef SuggestionsFilter = int? Function(DartType dartType, int relevance);
 
 /// An [AstVisitor] for determining whether top level suggestions or invocation
 /// suggestions should be made based upon the type of node in which the
 /// suggestions were requested.
 class OpType {
   /// The [TypeSystem] used during resolution of the current unit.
-  TypeSystem _typeSystem;
+  TypeSystem? _typeSystem;
 
   /// Indicates whether constructor suggestions should be included.
   bool includeConstructorSuggestions = false;
@@ -74,11 +74,11 @@
   CompletionSuggestionKind suggestKind = CompletionSuggestionKind.INVOCATION;
 
   /// An representation of the location at which completion was requested.
-  String completionLocation;
+  String? completionLocation;
 
   /// The type that is required by the context in which the completion was
   /// activated, or `null` if there is no such type, or it cannot be determined.
-  DartType _requiredType;
+  DartType? _requiredType;
 
   /// Determine the suggestions that should be made based upon the given
   /// [CompletionTarget] and [offset].
@@ -90,7 +90,7 @@
       return optype;
     }
 
-    optype._typeSystem = target.unit?.declaredElement?.library?.typeSystem;
+    optype._typeSystem = target.unit.declaredElement?.library.typeSystem;
 
     var targetNode = target.containingNode;
     targetNode.accept(_OpTypeAstVisitor(optype, target.entity, offset));
@@ -112,7 +112,7 @@
     // If a value should be suggested, suggest also constructors.
     if (optype.includeReturnValueSuggestions) {
       // Careful: in angular plugin, `target.unit` may be null!
-      var unitElement = target.unit?.declaredElement;
+      var unitElement = target.unit.declaredElement;
       if (unitElement != null) {
         optype.includeConstructorSuggestions = true;
       }
@@ -145,7 +145,7 @@
   /// Try to determine the required context type, and configure filters.
   void _computeRequiredTypeAndFilters(CompletionTarget target) {
     var entity = target.entity;
-    var node = target.containingNode;
+    AstNode? node = target.containingNode;
 
     if (node is InstanceCreationExpression &&
         node.keyword != null &&
@@ -157,28 +157,29 @@
     if (node is AssignmentExpression &&
         node.operator.type == TokenType.EQ &&
         node.rightHandSide == entity) {
-      _requiredType = node.leftHandSide?.staticType;
+      _requiredType = node.leftHandSide.staticType;
     } else if (node is BinaryExpression &&
         node.operator.type == TokenType.EQ_EQ &&
         node.rightOperand == entity) {
-      _requiredType = node.leftOperand?.staticType;
+      _requiredType = node.leftOperand.staticType;
     } else if (node is NamedExpression && node.expression == entity) {
       _requiredType = node.staticParameterElement?.type;
     } else if (node is SwitchCase && node.expression == entity) {
       var parent = node.parent;
       if (parent is SwitchStatement) {
-        _requiredType = parent.expression?.staticType;
+        _requiredType = parent.expression.staticType;
       }
     } else if (node is VariableDeclaration && node.initializer == entity) {
       _requiredType = node.declaredElement?.type;
     } else if (entity is Expression && entity.staticParameterElement != null) {
-      _requiredType = entity.staticParameterElement.type;
+      _requiredType = entity.staticParameterElement?.type;
     }
 
-    if (_requiredType == null) {
+    var requiredType = _requiredType;
+    if (requiredType == null) {
       return;
     }
-    if (_requiredType.isDynamic || _requiredType.isDartCoreObject) {
+    if (requiredType.isDynamic || requiredType.isDartCoreObject) {
       _requiredType = null;
       return;
     }
@@ -186,16 +187,17 @@
 
   /// Return `true` if the [leftType] is a subtype of the [rightType].
   bool _isSubtypeOf(DartType leftType, DartType rightType) {
-    if (_typeSystem == null) {
+    var typeSystem = _typeSystem;
+    if (typeSystem == null) {
       return false;
     }
 
-    return _typeSystem.isSubtypeOf(leftType, rightType);
+    return typeSystem.isSubtypeOf(leftType, rightType);
   }
 
   /// Return the statement before [entity]
   /// where [entity] can be a statement or the `}` closing the given block.
-  static Statement getPreviousStatement(Block node, Object entity) {
+  static Statement? getPreviousStatement(Block node, Object? entity) {
     if (entity == node.rightBracket) {
       return node.statements.isNotEmpty ? node.statements.last : null;
     }
@@ -213,7 +215,7 @@
 class _OpTypeAstVisitor extends GeneralizingAstVisitor<void> {
   /// The entity (AstNode or Token) that will be replaced or displaced by the
   /// added text.
-  final SyntacticEntity entity;
+  final SyntacticEntity? entity;
 
   /// The offset within the source at which the completion is requested.
   final int offset;
@@ -245,14 +247,14 @@
   @override
   void visitArgumentList(ArgumentList node) {
     var parent = node.parent;
-    List<ParameterElement> parameters;
+    List<ParameterElement>? parameters;
     if (parent is InstanceCreationExpression) {
-      Element constructor;
-      var name = parent.constructorName?.name;
+      Element? constructor;
+      var name = parent.constructorName.name;
       if (name != null) {
         constructor = name.staticElement;
       } else {
-        var classElem = parent.constructorName?.type?.name?.staticElement;
+        var classElem = parent.constructorName.type.name.staticElement;
         if (classElem is ClassElement) {
           constructor = classElem.unnamedConstructor;
         }
@@ -306,7 +308,7 @@
       }
       if (0 <= index && index < parameters.length) {
         var param = parameters[index];
-        if (param?.isNamed == true) {
+        if (param.isNamed == true) {
           var context = _argumentListContext(node);
           optype.completionLocation = 'ArgumentList_${context}_named';
           optype.includeNamedArgumentSuggestions = true;
@@ -476,6 +478,7 @@
         return node.end;
       }
 
+      var entity = this.entity;
       if (entity != null) {
         if (entity.offset <= declarationStart()) {
           optype.completionLocation = 'CompilationUnit_declaration';
@@ -522,14 +525,8 @@
     // some PrefixedIdentifier nodes are transformed into
     // ConstructorName nodes during the resolution process.
     if (identical(entity, node.name)) {
-      var type = node.type;
-      if (type != null) {
-        var prefix = type.name;
-        if (prefix != null) {
-          optype.includeConstructorSuggestions = true;
-          optype.isPrefixed = true;
-        }
-      }
+      optype.includeConstructorSuggestions = true;
+      optype.isPrefixed = true;
     }
   }
 
@@ -659,8 +656,8 @@
   @override
   void visitForEachParts(ForEachParts node) {
     if (identical(entity, node.inKeyword) && offset <= node.inKeyword.offset) {
-      if (!(node is ForEachPartsWithIdentifier && node.identifier != null ||
-          node is ForEachPartsWithDeclaration && node.loopVariable != null)) {
+      if (!(node is ForEachPartsWithIdentifier ||
+          node is ForEachPartsWithDeclaration)) {
         optype.includeTypeNameSuggestions = true;
       }
     }
@@ -728,7 +725,7 @@
 
     // Handle default normal parameter just as a normal parameter.
     if (parameter is DefaultFormalParameter) {
-      parameter = (parameter as DefaultFormalParameter).parameter;
+      parameter = parameter.parameter;
     }
 
     // "(^ this.field)"
@@ -955,7 +952,10 @@
   @override
   void visitMethodInvocation(MethodInvocation node) {
     var isThis = node.target is ThisExpression;
-    if (identical(entity, node.operator) && offset > node.operator.offset) {
+    var operator = node.operator;
+    if (operator != null &&
+        identical(entity, operator) &&
+        offset > operator.offset) {
       // The cursor is between the two dots of a ".." token, so we need to
       // generate the completions we would generate after a "." token.
       optype.includeReturnValueSuggestions = true;
@@ -1004,17 +1004,17 @@
       optype.includeTypeNameSuggestions = true;
 
       // Check for named parameters in constructor calls.
-      var grandparent = node.parent.parent;
+      var grandparent = node.parent?.parent;
       if (grandparent is ConstructorReferenceNode) {
         var element = grandparent.staticElement;
         if (element != null) {
           var parameters = element.parameters;
-          var parameterElement = parameters.firstWhere((e) {
+          var parameterElement = parameters.firstWhereOrNull((e) {
             if (e is DefaultFieldFormalParameterElementImpl) {
-              return e.field?.name == node.name.label?.name;
+              return e.field?.name == node.name.label.name;
             }
-            return e.isNamed && e.name == node.name.label?.name;
-          }, orElse: () => null);
+            return e.isNamed && e.name == node.name.label.name;
+          });
           // Suggest tear-offs.
           if (parameterElement?.type is FunctionType) {
             optype.includeVoidReturnSuggestions = true;
@@ -1064,8 +1064,7 @@
         // In addition to the standard case,
         // handle the exceptional case where the parser considers the would-be
         // identifier to be a keyword and inserts a synthetic identifier
-        (node.identifier != null &&
-            node.identifier.isSynthetic &&
+        (node.identifier.isSynthetic &&
             identical(entity, node.findPrevious(node.identifier.beginToken)))) {
       if (node.prefix.isSynthetic) {
         // If the access has no target (empty string)
@@ -1073,7 +1072,7 @@
         return;
       }
       optype.isPrefixed = true;
-      if (node.parent is TypeName && node.parent.parent is ConstructorName) {
+      if (node.parent is TypeName && node.parent?.parent is ConstructorName) {
         optype.includeConstructorSuggestions = true;
       } else if (node.parent is Annotation) {
         optype.includeConstructorSuggestions = true;
@@ -1162,15 +1161,18 @@
     }
 
     // If "(^ Type)", then include types.
-    if (type == null && offset < name.offset) {
+    if (type == null && name != null && offset < name.offset) {
       optype.includeTypeNameSuggestions = true;
       return;
     }
 
     // If "(Type ^)", then include parameter names.
-    if (type == null && name.end < offset && offset <= name.token.next.offset) {
-      optype.includeVarNameSuggestions = true;
-      return;
+    if (type == null && name != null && name.end < offset) {
+      var nextToken = name.token.next;
+      if (nextToken != null && offset <= nextToken.offset) {
+        optype.includeVarNameSuggestions = true;
+        return;
+      }
     }
 
     // If inside of "Type" in "(Type^ name)", then include types.
@@ -1332,7 +1334,7 @@
 
   @override
   void visitVariableDeclarationList(VariableDeclarationList node) {
-    if (node.keyword == null || node.keyword.lexeme != 'var') {
+    if (node.keyword == null || node.keyword?.lexeme != 'var') {
       if (node.type == null || identical(entity, node.type)) {
         optype.completionLocation = 'VariableDeclarationList_type';
         optype.includeTypeNameSuggestions = true;
@@ -1375,7 +1377,7 @@
 
   /// Return the context in which the [node] occurs. The [node] is expected to
   /// be the parent of the argument expression.
-  String _argumentListContext(AstNode node) {
+  String _argumentListContext(AstNode? node) {
     if (node is ArgumentList) {
       var parent = node.parent;
       if (parent is Annotation) {
@@ -1406,7 +1408,7 @@
       return 'index';
     }
     throw ArgumentError(
-        'Unknown parent of ${node.runtimeType}: ${node.parent.runtimeType}');
+        'Unknown parent of ${node.runtimeType}: ${node?.parent.runtimeType}');
   }
 
   bool _isEntityPrevTokenSynthetic() {
@@ -1422,7 +1424,7 @@
 
   /// A filter used to disable everything except classes (such as functions and
   /// mixins).
-  int _nonMixinClasses(DartType type, int relevance) {
+  int? _nonMixinClasses(DartType type, int relevance) {
     if (type is InterfaceType) {
       if (type.element.isMixin) {
         return null;
diff --git a/pkg/analyzer_plugin/lib/src/utilities/completion/suggestion_builder.dart b/pkg/analyzer_plugin/lib/src/utilities/completion/suggestion_builder.dart
index 946ad5b..e452d3d 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/completion/suggestion_builder.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/completion/suggestion_builder.dart
@@ -14,7 +14,7 @@
 /// An object used to build code completion suggestions for Dart code.
 class SuggestionBuilderImpl implements SuggestionBuilder {
   /// The resource provider used to access the file system.
-  final ResourceProvider resourceProvider;
+  final ResourceProvider? resourceProvider;
 
   /// The converter used to convert analyzer objects to protocol objects.
   final AnalyzerConverter converter = AnalyzerConverter();
@@ -65,9 +65,9 @@
   }
 
   @override
-  CompletionSuggestion forElement(Element element,
-      {String completion,
-      CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION,
+  CompletionSuggestion? forElement(Element? element,
+      {String? completion,
+      CompletionSuggestionKind? kind,
       int relevance = DART_RELEVANCE_DEFAULT}) {
     // Copied from analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
     if (element == null) {
@@ -80,7 +80,7 @@
     completion ??= element.displayName;
     var isDeprecated = element.hasDeprecated;
     var suggestion = CompletionSuggestion(
-        kind,
+        kind ?? CompletionSuggestionKind.INVOCATION,
         isDeprecated ? DART_RELEVANCE_LOW : relevance,
         completion,
         completion.length,
@@ -105,11 +105,7 @@
           .toList();
       suggestion.parameterTypes =
           element.parameters.map((ParameterElement parameter) {
-        var paramType = parameter.type;
-        // Gracefully degrade if type not resolved yet
-        return paramType != null
-            ? paramType.getDisplayString(withNullability: false)
-            : 'var';
+        return parameter.type.getDisplayString(withNullability: false);
       }).toList();
 
       var requiredParameters = element.parameters
@@ -126,19 +122,17 @@
     return suggestion;
   }
 
-  String getReturnTypeString(Element element) {
+  String? getReturnTypeString(Element element) {
     // Copied from analysis_server/lib/src/protocol_server.dart
     if (element is ExecutableElement) {
       if (element.kind == ElementKind.SETTER) {
         return null;
       } else {
-        return element.returnType?.getDisplayString(withNullability: false);
+        return element.returnType.getDisplayString(withNullability: false);
       }
     } else if (element is VariableElement) {
       var type = element.type;
-      return type != null
-          ? type.getDisplayString(withNullability: false)
-          : 'dynamic';
+      return type.getDisplayString(withNullability: false);
     } else if (element is TypeAliasElement) {
       var aliasedElement = element.aliasedElement;
       if (aliasedElement is GenericFunctionTypeElement) {
diff --git a/pkg/analyzer_plugin/lib/src/utilities/documentation.dart b/pkg/analyzer_plugin/lib/src/utilities/documentation.dart
index 50299be..69dcb9b 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/documentation.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/documentation.dart
@@ -4,7 +4,7 @@
 
 /// Return the summary of the given DartDoc [string], which is the content of
 /// the lines before the first blank line.
-String getDartDocSummary(String string) {
+String? getDartDocSummary(String? string) {
   if (string == null) {
     return null;
   }
@@ -26,7 +26,7 @@
 
 /// Converts [string] from a DartDoc comment with slashes and stars to a plain
 /// text representation of the comment.
-String removeDartDocDelimiters(String string) {
+String? removeDartDocDelimiters(String? string) {
   if (string == null) {
     return null;
   }
diff --git a/pkg/analyzer_plugin/lib/src/utilities/folding/folding.dart b/pkg/analyzer_plugin/lib/src/utilities/folding/folding.dart
index d424abf..a302a76 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/folding/folding.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/folding/folding.dart
@@ -21,7 +21,7 @@
   DartFoldingRequestImpl(this.resourceProvider, this.result);
 
   @override
-  String get path => result.path;
+  String get path => result.path!;
 }
 
 /// A concrete implementation of [FoldingCollector].
diff --git a/pkg/analyzer_plugin/lib/src/utilities/highlights/highlights.dart b/pkg/analyzer_plugin/lib/src/utilities/highlights/highlights.dart
index 95bd889..5e55b48 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/highlights/highlights.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/highlights/highlights.dart
@@ -21,7 +21,7 @@
   DartHighlightsRequestImpl(this.resourceProvider, this.result);
 
   @override
-  String get path => result.path;
+  String get path => result.path!;
 }
 
 /// A concrete implementation of [HighlightsCollector].
diff --git a/pkg/analyzer_plugin/lib/src/utilities/kythe/entries.dart b/pkg/analyzer_plugin/lib/src/utilities/kythe/entries.dart
index 684e9e7..191101c 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/kythe/entries.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/kythe/entries.dart
@@ -19,7 +19,7 @@
   DartEntryRequestImpl(this.resourceProvider, this.result);
 
   @override
-  String get path => result.path;
+  String get path => result.path!;
 }
 
 /// A concrete implementation of [EntryCollector].
diff --git a/pkg/analyzer_plugin/lib/src/utilities/navigation/navigation.dart b/pkg/analyzer_plugin/lib/src/utilities/navigation/navigation.dart
index c660f85..4e1850c 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/navigation/navigation.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/navigation/navigation.dart
@@ -28,7 +28,7 @@
       this.resourceProvider, this.offset, this.length, this.result);
 
   @override
-  String get path => result.path;
+  String get path => result.path!;
 }
 
 /// A concrete implementation of [NavigationCollector].
@@ -59,7 +59,7 @@
   @override
   void addRange(
       SourceRange range, ElementKind targetKind, Location targetLocation,
-      {Location targetCodeLocation}) {
+      {Location? targetCodeLocation}) {
     addRegion(range.offset, range.length, targetKind, targetLocation,
         targetCodeLocation: targetCodeLocation);
   }
@@ -67,7 +67,7 @@
   @override
   void addRegion(
       int offset, int length, ElementKind targetKind, Location targetLocation,
-      {Location targetCodeLocation}) {
+      {Location? targetCodeLocation}) {
     var range = SourceRange(offset, length);
     // add new target
     var targets = regionMap.putIfAbsent(range, () => <int>[]);
@@ -96,7 +96,7 @@
     return index;
   }
 
-  int _addTarget(ElementKind kind, Location location, Location codeLocation) {
+  int _addTarget(ElementKind kind, Location location, Location? codeLocation) {
     var pair = Pair<ElementKind, Location>(kind, location);
     var index = targetMap[pair];
     if (index == null) {
diff --git a/pkg/analyzer_plugin/lib/src/utilities/null_string_sink.dart b/pkg/analyzer_plugin/lib/src/utilities/null_string_sink.dart
index ec2cc26..012bb11 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/null_string_sink.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/null_string_sink.dart
@@ -5,7 +5,7 @@
 /// A string sink that ignores everything written to it.
 class NullStringSink implements StringSink {
   @override
-  void write(Object obj) {}
+  void write(Object? obj) {}
 
   @override
   void writeAll(Iterable objects, [String separator = '']) {}
@@ -14,5 +14,5 @@
   void writeCharCode(int charCode) {}
 
   @override
-  void writeln([Object obj = '']) {}
+  void writeln([Object? obj = '']) {}
 }
diff --git a/pkg/analyzer_plugin/lib/src/utilities/occurrences/occurrences.dart b/pkg/analyzer_plugin/lib/src/utilities/occurrences/occurrences.dart
index f436774..6bd0592 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/occurrences/occurrences.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/occurrences/occurrences.dart
@@ -20,7 +20,7 @@
   DartOccurrencesRequestImpl(this.resourceProvider, this.result);
 
   @override
-  String get path => result.path;
+  String get path => result.path!;
 }
 
 /// A concrete implementation of [OccurrencesCollector].
diff --git a/pkg/analyzer_plugin/lib/src/utilities/outline/outline.dart b/pkg/analyzer_plugin/lib/src/utilities/outline/outline.dart
index 284f140..44d4dd9 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/outline/outline.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/outline/outline.dart
@@ -20,7 +20,7 @@
   DartOutlineRequestImpl(this.resourceProvider, this.result);
 
   @override
-  String get path => result.path;
+  String get path => result.path!;
 }
 
 /// A concrete implementation of [OutlineCollector].
diff --git a/pkg/analyzer_plugin/lib/src/utilities/string_utilities.dart b/pkg/analyzer_plugin/lib/src/utilities/string_utilities.dart
index 9575749..7c8d1be 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/string_utilities.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/string_utilities.dart
@@ -9,7 +9,7 @@
 ///
 /// 'getCamelWords' => ['get', 'Camel', 'Words']
 /// 'getHTMLText' => ['get', 'HTML', 'Text']
-List<String> getCamelWords(String string) {
+List<String> getCamelWords(String? string) {
   if (string == null || string.isEmpty) {
     return const <String>[];
   }
@@ -44,7 +44,7 @@
 }
 
 /// Return `true` if the given [string] is either `null` or empty.
-bool isEmpty(String string) => string == null || string.isEmpty;
+bool isEmpty(String? string) => string == null || string.isEmpty;
 
 /// Return `true` if the given [character] is a lowercase ASCII character.
 bool isLowerCase(int character) => character >= $a && character <= $z;
@@ -55,8 +55,11 @@
 /// If the given [string] starts with the text to [remove], then return the
 /// portion of the string after the text to remove. Otherwise, return the
 /// original string unmodified.
-String removeStart(String string, String remove) {
-  if (isEmpty(string) || isEmpty(remove)) {
+String? removeStart(String? string, String? remove) {
+  if (string == null || string.isEmpty) {
+    return string;
+  }
+  if (remove == null || remove.isEmpty) {
     return string;
   }
   if (string.startsWith(remove)) {
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 c561be1..a7ea9aa 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
@@ -41,13 +41,13 @@
 
   void declaredLabel(Label label, bool isCaseLabel) {}
 
-  void declaredLocalVar(SimpleIdentifier name, TypeAnnotation type) {}
+  void declaredLocalVar(SimpleIdentifier name, TypeAnnotation? type) {}
 
   void declaredMethod(MethodDeclaration declaration) {}
 
   void declaredMixin(MixinDeclaration declaration) {}
 
-  void declaredParam(SimpleIdentifier name, TypeAnnotation type) {}
+  void declaredParam(SimpleIdentifier name, TypeAnnotation? type) {}
 
   void declaredTopLevelVar(
       VariableDeclarationList varList, VariableDeclaration varDecl) {}
@@ -116,11 +116,9 @@
       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);
-        });
-      }
+      varList.variables.forEach((VariableDeclaration varDecl) {
+        declaredLocalVar(varDecl.name, varList.type);
+      });
     }
     visitNode(node);
   }
@@ -133,11 +131,9 @@
       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);
-        });
-      }
+      varList.variables.forEach((VariableDeclaration varDecl) {
+        declaredLocalVar(varDecl.name, varList.type);
+      });
     }
     visitNode(node);
   }
@@ -255,11 +251,9 @@
         );
       } else if (declaration is TopLevelVariableDeclaration) {
         var varList = declaration.variables;
-        if (varList != null) {
-          varList.variables.forEach((VariableDeclaration varDecl) {
-            declaredTopLevelVar(varList, varDecl);
-          });
-        }
+        varList.variables.forEach((VariableDeclaration varDecl) {
+          declaredTopLevelVar(varList, varDecl);
+        });
       } else if (declaration is ClassTypeAlias) {
         declaredClassTypeAlias(declaration);
         _visitTypeParameters(declaration, declaration.typeParameters);
@@ -269,10 +263,11 @@
       } else if (declaration is GenericTypeAlias) {
         declaredGenericTypeAlias(declaration);
         _visitTypeParameters(declaration, declaration.typeParameters);
-        _visitTypeParameters(
-          declaration.functionType,
-          declaration.functionType?.typeParameters,
-        );
+
+        var type = declaration.type;
+        if (type is GenericFunctionType) {
+          _visitTypeParameters(type, type.typeParameters);
+        }
       } else if (declaration is MixinDeclaration) {
         declaredMixin(declaration);
         _visitTypeParameters(declaration, declaration.typeParameters);
@@ -280,16 +275,16 @@
     });
   }
 
-  void _visitParamList(FormalParameterList paramList) {
+  void _visitParamList(FormalParameterList? paramList) {
     if (paramList != null) {
       paramList.parameters.forEach((FormalParameter param) {
-        NormalFormalParameter normalParam;
+        NormalFormalParameter? normalParam;
         if (param is DefaultFormalParameter) {
           normalParam = param.parameter;
         } else if (param is NormalFormalParameter) {
           normalParam = param;
         }
-        TypeAnnotation type;
+        TypeAnnotation? type;
         if (normalParam is FieldFormalParameter) {
           type = normalParam.type;
         } else if (normalParam is FunctionTypedFormalParameter) {
@@ -298,7 +293,7 @@
           type = normalParam.type;
         }
         var name = param.identifier;
-        declaredParam(name, type);
+        declaredParam(name!, type);
       });
     }
   }
@@ -308,26 +303,21 @@
       if (stmt.offset < offset) {
         if (stmt is VariableDeclarationStatement) {
           var varList = stmt.variables;
-          if (varList != null) {
-            for (var varDecl in varList.variables) {
-              if (varDecl.end < offset) {
-                declaredLocalVar(varDecl.name, varList.type);
-              }
+          for (var varDecl in varList.variables) {
+            if (varDecl.end < offset) {
+              declaredLocalVar(varDecl.name, varList.type);
             }
           }
         } else if (stmt is FunctionDeclarationStatement) {
           var declaration = stmt.functionDeclaration;
-          if (declaration != null && declaration.offset < offset) {
-            var id = declaration.name;
-            if (id != null) {
-              var name = id.name;
-              if (name != null && name.isNotEmpty) {
-                declaredFunction(declaration);
-                _visitTypeParameters(
-                  declaration,
-                  declaration.functionExpression.typeParameters,
-                );
-              }
+          if (declaration.offset < offset) {
+            var name = declaration.name.name;
+            if (name.isNotEmpty) {
+              declaredFunction(declaration);
+              _visitTypeParameters(
+                declaration,
+                declaration.functionExpression.typeParameters,
+              );
             }
           }
         }
@@ -335,7 +325,7 @@
     }
   }
 
-  void _visitTypeParameters(AstNode node, TypeParameterList typeParameters) {
+  void _visitTypeParameters(AstNode node, TypeParameterList? typeParameters) {
     if (typeParameters == null) return;
 
     if (node.offset < offset && offset < node.end) {
diff --git a/pkg/analyzer_plugin/lib/utilities/analyzer_converter.dart b/pkg/analyzer_plugin/lib/utilities/analyzer_converter.dart
index cc0e5b8..40f3d2e 100644
--- a/pkg/analyzer_plugin/lib/utilities/analyzer_converter.dart
+++ b/pkg/analyzer_plugin/lib/utilities/analyzer_converter.dart
@@ -23,21 +23,23 @@
   /// error's location will have a start line and start column. If a [severity]
   /// is provided, then it will override the severity defined by the error.
   plugin.AnalysisError convertAnalysisError(analyzer.AnalysisError error,
-      {analyzer.LineInfo lineInfo, analyzer.ErrorSeverity severity}) {
+      {analyzer.LineInfo? lineInfo, analyzer.ErrorSeverity? severity}) {
     var errorCode = error.errorCode;
     severity ??= errorCode.errorSeverity;
     var offset = error.offset;
     var startLine = -1;
     var startColumn = -1;
+    var endLine = -1;
+    var endColumn = -1;
     if (lineInfo != null) {
-      var lineLocation =
-          lineInfo.getLocation(offset) as analyzer.CharacterLocation;
-      if (lineLocation != null) {
-        startLine = lineLocation.lineNumber;
-        startColumn = lineLocation.columnNumber;
-      }
+      var startLocation = lineInfo.getLocation(offset);
+      startLine = startLocation.lineNumber;
+      startColumn = startLocation.columnNumber;
+      var endLocation = lineInfo.getLocation(offset + error.length);
+      endLine = endLocation.lineNumber;
+      endColumn = endLocation.columnNumber;
     }
-    List<plugin.DiagnosticMessage> contextMessages;
+    List<plugin.DiagnosticMessage>? contextMessages;
     if (error.contextMessages.isNotEmpty) {
       contextMessages = error.contextMessages
           .map((message) =>
@@ -48,7 +50,7 @@
         convertErrorSeverity(severity),
         convertErrorType(errorCode.type),
         plugin.Location(error.source.fullName, offset, error.length, startLine,
-            startColumn),
+            startColumn, endLine, endColumn),
         error.message,
         errorCode.name.toLowerCase(),
         contextMessages: contextMessages,
@@ -63,8 +65,8 @@
   /// the errors will be altered based on those options.
   List<plugin.AnalysisError> convertAnalysisErrors(
       List<analyzer.AnalysisError> errors,
-      {analyzer.LineInfo lineInfo,
-      analyzer.AnalysisOptions options}) {
+      {analyzer.LineInfo? lineInfo,
+      analyzer.AnalysisOptions? options}) {
     var serverErrors = <plugin.AnalysisError>[];
     for (var error in errors) {
       var processor = analyzer.ErrorProcessor.getProcessor(options, error);
@@ -88,22 +90,26 @@
   /// the error's location will have a start line and start column.
   plugin.DiagnosticMessage convertDiagnosticMessage(
       analyzer.DiagnosticMessage message,
-      {analyzer.LineInfo lineInfo}) {
+      {analyzer.LineInfo? lineInfo}) {
     var file = message.filePath;
     var offset = message.offset;
     var length = message.length;
     var startLine = -1;
     var startColumn = -1;
+    var endLine = -1;
+    var endColumn = -1;
     if (lineInfo != null) {
-      var lineLocation =
-          lineInfo.getLocation(offset) as analyzer.CharacterLocation;
-      if (lineLocation != null) {
-        startLine = lineLocation.lineNumber;
-        startColumn = lineLocation.columnNumber;
-      }
+      var lineLocation = lineInfo.getLocation(offset);
+      startLine = lineLocation.lineNumber;
+      startColumn = lineLocation.columnNumber;
+      var endLocation = lineInfo.getLocation(offset + length);
+      endLine = endLocation.lineNumber;
+      endColumn = endLocation.columnNumber;
     }
-    return plugin.DiagnosticMessage(message.message,
-        plugin.Location(file, offset, length, startLine, startColumn));
+    return plugin.DiagnosticMessage(
+        message.message,
+        plugin.Location(
+            file, offset, length, startLine, startColumn, endLine, endColumn));
   }
 
   /// Convert the given [element] from the 'analyzer' package to an element
@@ -188,8 +194,8 @@
       plugin.AnalysisErrorType(type.name);
 
   /// Create a location based on an the given [element].
-  plugin.Location locationFromElement(analyzer.Element element,
-      {int offset, int length}) {
+  plugin.Location? locationFromElement(analyzer.Element? element,
+      {int? offset, int? length}) {
     if (element == null || element.source == null) {
       return null;
     }
@@ -220,14 +226,13 @@
         // so should it return isEnumConstant = true?
         // Or should we return ElementKind.ENUM_CONSTANT here
         // in either or both of these cases?
-        element.type != null &&
         element.type.element == element.enclosingElement) {
       return plugin.ElementKind.ENUM_CONSTANT;
     }
     return convertElementKind(element.kind);
   }
 
-  String _getAliasedTypeString(analyzer.Element element) {
+  String? _getAliasedTypeString(analyzer.Element element) {
     if (element is analyzer.TypeAliasElement) {
       var aliasedType = element.aliasedType;
       return aliasedType.getDisplayString(withNullability: false);
@@ -237,7 +242,7 @@
 
   /// Return a textual representation of the parameters of the given [element],
   /// or `null` if the element does not have any parameters.
-  String _getParametersString(analyzer.Element element) {
+  String? _getParametersString(analyzer.Element element) {
     // TODO(scheglov) expose the corresponding feature from ExecutableElement
     List<analyzer.ParameterElement> parameters;
     if (element is analyzer.ExecutableElement) {
@@ -283,17 +288,14 @@
 
   /// Return a textual representation of the return type of the given [element],
   /// or `null` if the element does not have a return type.
-  String _getReturnTypeString(analyzer.Element element) {
+  String? _getReturnTypeString(analyzer.Element element) {
     if (element is analyzer.ExecutableElement) {
       if (element.kind == analyzer.ElementKind.SETTER) {
         return null;
       }
-      return element.returnType?.getDisplayString(withNullability: false);
+      return element.returnType.getDisplayString(withNullability: false);
     } else if (element is analyzer.VariableElement) {
-      var type = element.type;
-      return type != null
-          ? type.getDisplayString(withNullability: false)
-          : 'dynamic';
+      return element.type.getDisplayString(withNullability: false);
     } else if (element is analyzer.TypeAliasElement) {
       var aliasedType = element.aliasedType;
       if (aliasedType is FunctionType) {
@@ -306,10 +308,10 @@
 
   /// Return a textual representation of the type parameters of the given
   /// [element], or `null` if the element does not have type parameters.
-  String _getTypeParametersString(analyzer.Element element) {
+  String? _getTypeParametersString(analyzer.Element element) {
     if (element is analyzer.TypeParameterizedElement) {
       var typeParameters = element.typeParameters;
-      if (typeParameters == null || typeParameters.isEmpty) {
+      if (typeParameters.isEmpty) {
         return null;
       }
       return '<${typeParameters.join(', ')}>';
@@ -318,19 +320,22 @@
   }
 
   /// Return the compilation unit containing the given [element].
-  analyzer.CompilationUnitElement _getUnitElement(analyzer.Element element) {
-    if (element is analyzer.CompilationUnitElement) {
-      return element;
+  analyzer.CompilationUnitElement? _getUnitElement(analyzer.Element element) {
+    analyzer.Element? currentElement = element;
+    if (currentElement is analyzer.CompilationUnitElement) {
+      return currentElement;
     }
-    if (element?.enclosingElement is analyzer.LibraryElement) {
-      element = element.enclosingElement;
+    if (currentElement.enclosingElement is analyzer.LibraryElement) {
+      currentElement = currentElement.enclosingElement;
     }
-    if (element is analyzer.LibraryElement) {
-      return element.definingCompilationUnit;
+    if (currentElement is analyzer.LibraryElement) {
+      return currentElement.definingCompilationUnit;
     }
-    for (; element != null; element = element.enclosingElement) {
-      if (element is analyzer.CompilationUnitElement) {
-        return element;
+    for (;
+        currentElement != null;
+        currentElement = currentElement.enclosingElement) {
+      if (currentElement is analyzer.CompilationUnitElement) {
+        return currentElement;
       }
     }
     return null;
@@ -378,22 +383,31 @@
 
   /// Create and return a location within the given [unitElement] at the given
   /// [range].
-  plugin.Location _locationForArgs(
-      analyzer.CompilationUnitElement unitElement, analyzer.SourceRange range) {
+  plugin.Location? _locationForArgs(
+      analyzer.CompilationUnitElement? unitElement,
+      analyzer.SourceRange range) {
     var startLine = 0;
     var startColumn = 0;
+    var endLine = 0;
+    var endColumn = 0;
+
+    if (unitElement == null) {
+      return null;
+    }
     try {
       var lineInfo = unitElement.lineInfo;
       if (lineInfo != null) {
-        var offsetLocation =
-            lineInfo.getLocation(range.offset) as analyzer.CharacterLocation;
+        var offsetLocation = lineInfo.getLocation(range.offset);
         startLine = offsetLocation.lineNumber;
         startColumn = offsetLocation.columnNumber;
+        var endLocation = lineInfo.getLocation(range.offset + range.length);
+        endLine = endLocation.lineNumber;
+        endColumn = endLocation.columnNumber;
       }
     } on analyzer.AnalysisException {
       // Ignore exceptions
     }
     return plugin.Location(unitElement.source.fullName, range.offset,
-        range.length, startLine, startColumn);
+        range.length, startLine, startColumn, endLine, endColumn);
   }
 }
diff --git a/pkg/analyzer_plugin/lib/utilities/assist/assist_contributor_mixin.dart b/pkg/analyzer_plugin/lib/utilities/assist/assist_contributor_mixin.dart
index 1546f14..811a510 100644
--- a/pkg/analyzer_plugin/lib/utilities/assist/assist_contributor_mixin.dart
+++ b/pkg/analyzer_plugin/lib/utilities/assist/assist_contributor_mixin.dart
@@ -20,14 +20,13 @@
   /// priority, and use the change [builder] to get the edits that comprise the
   /// assist. If the message has parameters, then use the list of [args] to
   /// populate the message.
-  void addAssist(AssistKind kind, ChangeBuilder builder, {List<Object> args}) {
+  void addAssist(AssistKind kind, ChangeBuilder builder, {List<Object>? args}) {
     var change = builder.sourceChange;
     if (change.edits.isEmpty) {
       return;
     }
     change.id = kind.id;
     change.message = formatList(kind.message, args);
-    collector.addAssist(
-        PrioritizedSourceChange(kind.priority, change));
+    collector.addAssist(PrioritizedSourceChange(kind.priority, change));
   }
 }
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 d4e9f29..d64f540 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
@@ -23,7 +23,7 @@
 
   /// Return the range of the selection for the change being built, or `null` if
   /// there is no selection.
-  SourceRange get selectionRange;
+  SourceRange? get selectionRange;
 
   /// Return the source change that was built. The source change will not be
   /// complete until all of the futures returned by the add*FileEdit methods
@@ -43,13 +43,6 @@
   /// Use the [buildFileEdit] function to create a collection of edits to the
   /// file with the given [path]. The edits will be added to the source change
   /// that is being built.
-  @Deprecated('Use either addDartFileEdit or addGenericFileEdit')
-  Future<void> addFileEdit(
-      String path, void Function(FileEditBuilder builder) buildFileEdit);
-
-  /// Use the [buildFileEdit] function to create a collection of edits to the
-  /// file with the given [path]. The edits will be added to the source change
-  /// that is being built.
   ///
   /// The builder passed to the [buildFileEdit] function has no special support
   /// for any particular kind of file.
diff --git a/pkg/analyzer_plugin/lib/utilities/change_builder/change_builder_dart.dart b/pkg/analyzer_plugin/lib/utilities/change_builder/change_builder_dart.dart
index 1b513a2..af9b40a 100644
--- a/pkg/analyzer_plugin/lib/utilities/change_builder/change_builder_dart.dart
+++ b/pkg/analyzer_plugin/lib/utilities/change_builder/change_builder_dart.dart
@@ -2,40 +2,16 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-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/type.dart';
 import 'package:analyzer/dart/element/type_provider.dart';
 import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer_plugin/src/utilities/change_builder/change_builder_dart.dart';
 import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
 
 /// The optional generator for prefix that should be used for new imports.
 typedef ImportPrefixGenerator = String Function(Uri);
 
-/// A [ChangeBuilder] used to build changes in Dart files.
-///
-/// Clients may not extend, implement or mix-in this class.
-@Deprecated('Use ChangeBuilder')
-abstract class DartChangeBuilder implements ChangeBuilder {
-  /// Initialize a newly created change builder.
-  @Deprecated('Use ChangeBuilder(session: session)')
-  factory DartChangeBuilder(AnalysisSession session) = DartChangeBuilderImpl;
-
-  /// Use the [buildFileEdit] function to create a collection of edits to the
-  /// file with the given [path]. The edits will be added to the source change
-  /// that is being built.
-  ///
-  /// If [importPrefixGenerator] is provided, it will be asked to generate an
-  /// import prefix for every newly imported library.
-  @Deprecated('Use ChangeBuilder.addDartFileEdit')
-  @override
-  Future<void> addFileEdit(
-      String path, void Function(DartFileEditBuilder builder) buildFileEdit,
-      {ImportPrefixGenerator importPrefixGenerator});
-}
-
 /// An [EditBuilder] used to build edits in Dart files.
 ///
 /// Clients may not extend, implement or mix-in this class.
@@ -55,13 +31,13 @@
   /// list of [mixins] is provided but no [superclass] is given then the class
   /// will extend `Object`.)
   void writeClassDeclaration(String name,
-      {Iterable<DartType> interfaces,
+      {Iterable<DartType>? interfaces,
       bool isAbstract = false,
-      void Function() membersWriter,
-      Iterable<DartType> mixins,
-      String nameGroupName,
-      DartType superclass,
-      String superclassGroupName});
+      void Function()? membersWriter,
+      Iterable<DartType>? mixins,
+      String? nameGroupName,
+      DartType? superclass,
+      String? superclassGroupName});
 
   /// Write the code for a constructor declaration in the class with the given
   /// [className]. If [isConst] is `true`, then the constructor will be marked
@@ -79,15 +55,15 @@
   /// for you). If a [bodyWriter] is provided then it is used to write the
   /// constructor body, otherwise an empty body is written.
   void writeConstructorDeclaration(String className,
-      {ArgumentList argumentList,
-      void Function() bodyWriter,
-      String classNameGroupName,
-      SimpleIdentifier constructorName,
-      String constructorNameGroupName,
-      List<String> fieldNames,
-      void Function() initializerWriter,
+      {ArgumentList? argumentList,
+      void Function()? bodyWriter,
+      String? classNameGroupName,
+      SimpleIdentifier? constructorName,
+      String? constructorNameGroupName,
+      List<String>? fieldNames,
+      void Function()? initializerWriter,
       bool isConst = false,
-      void Function() parameterWriter});
+      void Function()? parameterWriter});
 
   /// Write the code for a declaration of a field with the given [name]. If an
   /// [initializerWriter] is provided, it will be invoked to write the content
@@ -104,13 +80,13 @@
   /// required.) If a [typeGroupName] is provided, then if a type was written
   /// it will be in the linked edit group with that name.
   void writeFieldDeclaration(String name,
-      {void Function() initializerWriter,
+      {void Function()? initializerWriter,
       bool isConst = false,
       bool isFinal = false,
       bool isStatic = false,
-      String nameGroupName,
-      DartType type,
-      String typeGroupName});
+      String? nameGroupName,
+      DartType? type,
+      String? typeGroupName});
 
   /// Write the code for a declaration of a function with the given [name]. If a
   /// [bodyWriter] is provided, it will be invoked to write the body of the
@@ -125,12 +101,12 @@
   /// declarations of the parameters to the function. (The parentheses around
   /// the parameters will automatically be written.)
   void writeFunctionDeclaration(String name,
-      {void Function() bodyWriter,
+      {void Function()? bodyWriter,
       bool isStatic = false,
-      String nameGroupName,
-      void Function() parameterWriter,
-      DartType returnType,
-      String returnTypeGroupName});
+      String? nameGroupName,
+      void Function()? parameterWriter,
+      DartType? returnType,
+      String? returnTypeGroupName});
 
   /// Write the code for a declaration of a getter with the given [name]. If a
   /// [bodyWriter] is provided, it will be invoked to write the body of the
@@ -166,12 +142,12 @@
   /// when required.) If a [typeGroupName] is provided, then if a type was
   /// written it will be in the linked edit group with that name.
   void writeLocalVariableDeclaration(String name,
-      {void Function() initializerWriter,
+      {void Function()? initializerWriter,
       bool isConst = false,
       bool isFinal = false,
-      String nameGroupName,
-      DartType type,
-      String typeGroupName});
+      String? nameGroupName,
+      DartType? type,
+      String? typeGroupName});
 
   /// Write the code for a declaration of a mixin with the given [name]. If a
   /// list of [interfaces] is provided, then the mixin will implement those
@@ -180,10 +156,10 @@
   /// name of the class will be included in the linked edit group with that
   /// name.
   void writeMixinDeclaration(String name,
-      {Iterable<DartType> interfaces,
-      void Function() membersWriter,
-      String nameGroupName,
-      Iterable<DartType> superclassConstraints});
+      {Iterable<DartType>? interfaces,
+      void Function()? membersWriter,
+      String? nameGroupName,
+      Iterable<DartType>? superclassConstraints});
 
   /// Append a placeholder for an override of the specified inherited [element].
   /// If provided, write a string value suitable for display (e.g., in a
@@ -191,7 +167,7 @@
   /// `true`, then the corresponding `super.name()` will be added in the body.
   void writeOverride(
     ExecutableElement element, {
-    StringBuffer displayTextBuffer,
+    StringBuffer? displayTextBuffer,
     bool invokeSuper = false,
   });
 
@@ -218,10 +194,10 @@
   void writeParameter(String name,
       {bool isCovariant,
       bool isRequiredNamed,
-      ExecutableElement methodBeingCopied,
-      String nameGroupName,
-      DartType type,
-      String typeGroupName});
+      ExecutableElement? methodBeingCopied,
+      String? nameGroupName,
+      DartType? type,
+      String? typeGroupName});
 
   /// Write the code for a parameter that would match the given [argument]. The
   /// name of the parameter will be generated based on the type of the argument,
@@ -238,7 +214,7 @@
   /// method are assumed to be part of what is being written and hence valid
   /// types.
   void writeParameters(Iterable<ParameterElement> parameters,
-      {ExecutableElement methodBeingCopied});
+      {ExecutableElement? methodBeingCopied});
 
   /// Write the code for a list of parameters that would match the given list of
   /// [arguments]. The surrounding parentheses are *not* written.
@@ -259,11 +235,11 @@
   /// parameter. If a [parameterTypeGroupName] is provided, then if a parameter
   /// type was written it will be in the linked edit group with that name.
   void writeSetterDeclaration(String name,
-      {void Function() bodyWriter,
+      {void Function()? bodyWriter,
       bool isStatic = false,
-      String nameGroupName,
-      DartType parameterType,
-      String parameterTypeGroupName});
+      String? nameGroupName,
+      DartType? parameterType,
+      String? parameterTypeGroupName});
 
   /// Write the code for a type annotation for the given [type]. If the [type]
   /// is either `null` or represents the type 'dynamic', then the behavior
@@ -281,10 +257,10 @@
   /// types.
   ///
   /// Return `true` if some text was written.
-  bool writeType(DartType type,
+  bool writeType(DartType? type,
       {bool addSupertypeProposals = false,
-      String groupName,
-      ExecutableElement methodBeingCopied,
+      String? groupName,
+      ExecutableElement? methodBeingCopied,
       bool required = false});
 
   /// Write the code to declare the given [typeParameter]. The enclosing angle
@@ -294,7 +270,7 @@
   /// method are assumed to be part of what is being written and hence valid
   /// types.
   void writeTypeParameter(TypeParameterElement typeParameter,
-      {ExecutableElement methodBeingCopied});
+      {ExecutableElement? methodBeingCopied});
 
   /// Write the code to declare the given list of [typeParameters]. The
   /// enclosing angle brackets are automatically written.
@@ -303,12 +279,12 @@
   /// method are assumed to be part of what is being written and hence valid
   /// types.
   void writeTypeParameters(List<TypeParameterElement> typeParameters,
-      {ExecutableElement methodBeingCopied});
+      {ExecutableElement? methodBeingCopied});
 
   /// Write the code for a comma-separated list of [types], optionally prefixed
   /// by a [prefix]. If the list of [types] is `null` or does not contain any
   /// types, then nothing will be written.
-  void writeTypes(Iterable<DartType> types, {String prefix});
+  void writeTypes(Iterable<DartType>? types, {String? prefix});
 }
 
 /// A [FileEditBuilder] used to build edits for Dart files.
@@ -371,12 +347,12 @@
 abstract class DartLinkedEditBuilder implements LinkedEditBuilder {
   /// Add the given [type] and all of its supertypes (other than mixins) as
   /// suggestions for the current linked edit group.
-  void addSuperTypesAsSuggestions(DartType type);
+  void addSuperTypesAsSuggestions(DartType? type);
 }
 
 /// Information about a library to import.
 abstract class ImportLibraryElementResult {
   /// If the library is already imported with a prefix, or should be imported
   /// with a prefix, the prefix name (without `.`). Otherwise `null`.
-  String get prefix;
+  String? get prefix;
 }
diff --git a/pkg/analyzer_plugin/lib/utilities/change_builder/change_workspace.dart b/pkg/analyzer_plugin/lib/utilities/change_builder/change_workspace.dart
index a0f4469..c89a52c 100644
--- a/pkg/analyzer_plugin/lib/utilities/change_builder/change_workspace.dart
+++ b/pkg/analyzer_plugin/lib/utilities/change_builder/change_workspace.dart
@@ -7,9 +7,9 @@
 /// Information about the workspace in which change builders operate.
 abstract class ChangeWorkspace {
   /// Return `true` if the file with the given [path] is in a context root.
-  bool containsFile(String path);
+  bool? containsFile(String path);
 
   /// Return the session that should analyze the given [path], or throw
   /// [StateError] if the [path] does not belong to a context root.
-  AnalysisSession getSession(String path);
+  AnalysisSession? getSession(String path);
 }
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
index db5a55f..624a43f 100644
--- a/pkg/analyzer_plugin/lib/utilities/change_builder/conflicting_edit_exception.dart
+++ b/pkg/analyzer_plugin/lib/utilities/change_builder/conflicting_edit_exception.dart
@@ -3,7 +3,6 @@
 // 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.
@@ -15,8 +14,7 @@
   final SourceEdit existingEdit;
 
   /// Initialize a newly created exception indicating that the [newEdit].
-  ConflictingEditException(
-      {@required this.newEdit, @required this.existingEdit});
+  ConflictingEditException({required this.newEdit, required this.existingEdit});
 
   @override
   String toString() =>
diff --git a/pkg/analyzer_plugin/lib/utilities/completion/completion_core.dart b/pkg/analyzer_plugin/lib/utilities/completion/completion_core.dart
index 4c225fe..f12f931 100644
--- a/pkg/analyzer_plugin/lib/utilities/completion/completion_core.dart
+++ b/pkg/analyzer_plugin/lib/utilities/completion/completion_core.dart
@@ -70,7 +70,7 @@
   /// Create a 'completion.getSuggestions' response for the file with the given
   /// [path]. If any of the contributors throws an exception, also create a
   /// non-fatal 'plugin.error' notification.
-  Future<GeneratorResult<CompletionGetSuggestionsResult>>
+  Future<GeneratorResult<CompletionGetSuggestionsResult?>>
       generateCompletionResponse(CompletionRequest request) async {
     var notifications = <Notification>[];
     var collector = CompletionCollectorImpl();
@@ -92,7 +92,7 @@
     collector.length ??= 0;
 
     var result = CompletionGetSuggestionsResult(
-        collector.offset, collector.length, collector.suggestions);
+        collector.offset!, collector.length!, collector.suggestions);
     return GeneratorResult(result, notifications);
   }
 }
diff --git a/pkg/analyzer_plugin/lib/utilities/completion/inherited_reference_contributor.dart b/pkg/analyzer_plugin/lib/utilities/completion/inherited_reference_contributor.dart
index bac46ee..a605f4e 100644
--- a/pkg/analyzer_plugin/lib/utilities/completion/inherited_reference_contributor.dart
+++ b/pkg/analyzer_plugin/lib/utilities/completion/inherited_reference_contributor.dart
@@ -20,13 +20,13 @@
     with ElementSuggestionBuilder
     implements CompletionContributor {
   @override
-  LibraryElement containingLibrary;
+  LibraryElement? containingLibrary;
 
   @override
-  CompletionSuggestionKind kind;
+  CompletionSuggestionKind? kind;
 
   @override
-  ResourceProvider resourceProvider;
+  ResourceProvider? resourceProvider;
 
   /// Plugin contributors should primarily overload this function. Should more
   /// parameters be needed for autocompletion needs, the overloaded function
@@ -35,7 +35,7 @@
   Future<void> computeSuggestions(
       DartCompletionRequest request, CompletionCollector collector) async {
     var target =
-        CompletionTarget.forOffset(request.result.unit, request.offset);
+        CompletionTarget.forOffset(request.result.unit!, request.offset);
     var optype = OpType.forCompletion(target, request.offset);
     if (!optype.includeIdentifiers) {
       return;
@@ -46,20 +46,20 @@
     }
     containingLibrary = request.result.libraryElement;
     _computeSuggestionsForClass2(
-        collector, target, classDecl.declaredElement, optype);
+        collector, target, classDecl.declaredElement!, optype);
   }
 
   /// Clients should not overload this function.
   Future<void> computeSuggestionsForClass(
     DartCompletionRequest request,
     CompletionCollector collector,
-    ClassElement classElement, {
-    AstNode entryPoint,
-    bool skipChildClass,
-    CompletionTarget target,
-    OpType optype,
+    ClassElement? classElement, {
+    AstNode? entryPoint,
+    bool skipChildClass = true,
+    CompletionTarget? target,
+    OpType? optype,
   }) async {
-    target ??= CompletionTarget.forOffset(request.result.unit, request.offset,
+    target ??= CompletionTarget.forOffset(request.result.unit!, request.offset,
         entryPoint: entryPoint);
     optype ??= OpType.forCompletion(target, request.offset);
     if (!optype.includeIdentifiers) {
@@ -73,7 +73,7 @@
       classElement = classDecl.declaredElement;
     }
     containingLibrary = request.result.libraryElement;
-    _computeSuggestionsForClass2(collector, target, classElement, optype,
+    _computeSuggestionsForClass2(collector, target, classElement!, optype,
         skipChildClass: skipChildClass);
   }
 
@@ -93,9 +93,7 @@
       }
     }
     for (var elem in type.methods) {
-      if (elem.returnType == null) {
-        addSuggestion(elem);
-      } else if (!elem.returnType.isVoid) {
+      if (!elem.returnType.isVoid) {
         if (optype.includeReturnValueSuggestions) {
           addSuggestion(elem);
         }
@@ -131,8 +129,8 @@
 
   /// Return the class containing the target or `null` if the target is in a
   /// static method or field or not in a class.
-  ClassDeclaration _enclosingClass(CompletionTarget target) {
-    var node = target.containingNode;
+  ClassDeclaration? _enclosingClass(CompletionTarget? target) {
+    var node = target?.containingNode;
     while (node != null) {
       if (node is ClassDeclaration) {
         return node;
diff --git a/pkg/analyzer_plugin/lib/utilities/completion/suggestion_builder.dart b/pkg/analyzer_plugin/lib/utilities/completion/suggestion_builder.dart
index a386ba7..2c8531c 100644
--- a/pkg/analyzer_plugin/lib/utilities/completion/suggestion_builder.dart
+++ b/pkg/analyzer_plugin/lib/utilities/completion/suggestion_builder.dart
@@ -10,8 +10,8 @@
 abstract class SuggestionBuilder {
   /// Return a suggestion based on the given [element], or `null` if a
   /// suggestion is not appropriate for the given element.
-  CompletionSuggestion forElement(Element element,
-      {String completion,
+  CompletionSuggestion? forElement(Element element,
+      {String? completion,
       CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION,
       int relevance = DART_RELEVANCE_DEFAULT});
 }
diff --git a/pkg/analyzer_plugin/lib/utilities/completion/type_member_contributor.dart b/pkg/analyzer_plugin/lib/utilities/completion/type_member_contributor.dart
index 19b3cb0..1009c12 100644
--- a/pkg/analyzer_plugin/lib/utilities/completion/type_member_contributor.dart
+++ b/pkg/analyzer_plugin/lib/utilities/completion/type_member_contributor.dart
@@ -27,11 +27,6 @@
   Future<void> computeSuggestions(
       DartCompletionRequest request, CompletionCollector collector) async {
     var containingLibrary = request.result.libraryElement;
-    // Gracefully degrade if the library element is not resolved
-    // e.g. detached part file or source change
-    if (containingLibrary == null) {
-      return;
-    }
 
     // Recompute the target since resolution may have changed it
     var expression = _computeDotTarget(request, null);
@@ -45,11 +40,6 @@
   Future<void> computeSuggestionsWithEntryPoint(DartCompletionRequest request,
       CompletionCollector collector, AstNode entryPoint) async {
     var containingLibrary = request.result.libraryElement;
-    // Gracefully degrade if the library element is not resolved
-    // e.g. detached part file or source change
-    if (containingLibrary == null) {
-      return;
-    }
 
     // Recompute the target since resolution may have changed it
     var expression = _computeDotTarget(request, entryPoint);
@@ -60,16 +50,20 @@
   }
 
   /// Update the completion [target] and [dotTarget] based on the given [unit].
-  Expression _computeDotTarget(
-      DartCompletionRequest request, AstNode entryPoint) {
-    var target = CompletionTarget.forOffset(request.result.unit, request.offset,
+  Expression? _computeDotTarget(
+      DartCompletionRequest request, AstNode? entryPoint) {
+    var target = CompletionTarget.forOffset(
+        request.result.unit!, request.offset,
         entryPoint: entryPoint);
     var node = target.containingNode;
     if (node is MethodInvocation) {
       if (identical(node.methodName, target.entity)) {
         return node.realTarget;
-      } else if (node.isCascaded && node.operator.offset + 1 == target.offset) {
-        return node.realTarget;
+      } else if (node.isCascaded) {
+        var operator = node.operator;
+        if (operator != null && operator.offset + 1 == target.offset) {
+          return node.realTarget;
+        }
       }
     }
     if (node is PropertyAccess) {
@@ -129,19 +123,17 @@
         }
       }
     }
-    String containingMethodName;
+    String? containingMethodName;
     if (expression is SuperExpression && type is InterfaceType) {
       // Suggest members from superclass if target is "super"
-      type = (type as InterfaceType).superclass;
+      type = type.superclass;
       // Determine the name of the containing method because
       // the most likely completion is a super expression with same name
       var containingMethod =
           expression.thisOrAncestorOfType<MethodDeclaration>();
-      if (containingMethod != null) {
-        var id = containingMethod.name;
-        if (id != null) {
-          containingMethodName = id.name;
-        }
+      var id = containingMethod?.name;
+      if (id != null) {
+        containingMethodName = id.name;
       }
     }
     if (type == null || type.isDynamic) {
@@ -166,7 +158,7 @@
 
   /// The best type for the found declaration,
   /// or `null` if no declaration found or failed to determine a type.
-  DartType typeFound;
+  DartType? typeFound;
 
   /// Construct a new instance to search for a declaration
   _LocalBestTypeVisitor(this.targetName, int offset) : super(offset);
@@ -240,7 +232,7 @@
   }
 
   @override
-  void declaredLocalVar(SimpleIdentifier name, TypeAnnotation type) {
+  void declaredLocalVar(SimpleIdentifier name, TypeAnnotation? type) {
     if (name.name == targetName) {
       var element = name.staticElement as VariableElement;
       typeFound = element.type;
@@ -260,7 +252,7 @@
   }
 
   @override
-  void declaredParam(SimpleIdentifier name, TypeAnnotation type) {
+  void declaredParam(SimpleIdentifier name, TypeAnnotation? type) {
     if (name.name == targetName) {
       // Type provided by the element in computeFull above
       finished();
@@ -330,7 +322,7 @@
   /// Create completion suggestions for 'dot' completions on the given [type].
   /// If the 'dot' completion is a super expression, then [containingMethodName]
   /// is the name of the method in which the completion is requested.
-  void buildSuggestions(InterfaceType type, String containingMethodName) {
+  void buildSuggestions(InterfaceType type, String? containingMethodName) {
     // Visit all of the types in the class hierarchy, collecting possible
     // completions. If multiple elements are found that complete to the same
     // identifier, addSuggestion will discard all but the first (with a few
@@ -368,7 +360,7 @@
 
   /// Add a suggestion based upon the given element, provided that it is not
   /// shadowed by a previously added suggestion.
-  void _addSuggestion(Element element, {int relevance}) {
+  void _addSuggestion(Element element, {int? relevance}) {
     if (element.isPrivate) {
       if (element.library != containingLibrary) {
         // Do not suggest private members for imported libraries
@@ -380,7 +372,7 @@
     if (relevance == null) {
       // Decrease relevance of suggestions starting with $
       // https://github.com/dart-lang/sdk/issues/27303
-      if (identifier != null && identifier.startsWith(r'$')) {
+      if (identifier.startsWith(r'$')) {
         relevance = DART_RELEVANCE_LOW;
       } else {
         relevance = DART_RELEVANCE_DEFAULT;
@@ -402,13 +394,15 @@
         if ((alreadyGenerated & _COMPLETION_TYPE_GETTER) != 0) {
           return;
         }
-        _completionTypesGenerated[identifier] |= _COMPLETION_TYPE_GETTER;
+        _completionTypesGenerated[identifier] =
+            _completionTypesGenerated[identifier]! | _COMPLETION_TYPE_GETTER;
       } else {
         // Setters, fields, and methods shadow a setter.
         if ((alreadyGenerated & _COMPLETION_TYPE_SETTER) != 0) {
           return;
         }
-        _completionTypesGenerated[identifier] |= _COMPLETION_TYPE_SETTER;
+        _completionTypesGenerated[identifier] =
+            _completionTypesGenerated[identifier]! | _COMPLETION_TYPE_SETTER;
       }
     } else if (element is FieldElement) {
       // Fields and methods shadow a field. A getter/setter pair shadows a
@@ -457,7 +451,7 @@
       // in the reverse order.
       typesToVisit.addAll(nextType.interfaces);
       if (nextType.superclass != null) {
-        typesToVisit.add(nextType.superclass);
+        typesToVisit.add(nextType.superclass!);
       }
       typesToVisit.addAll(nextType.mixins);
     }
diff --git a/pkg/analyzer_plugin/lib/utilities/fixes/fix_contributor_mixin.dart b/pkg/analyzer_plugin/lib/utilities/fixes/fix_contributor_mixin.dart
index b4be5b0..2edbd4c 100644
--- a/pkg/analyzer_plugin/lib/utilities/fixes/fix_contributor_mixin.dart
+++ b/pkg/analyzer_plugin/lib/utilities/fixes/fix_contributor_mixin.dart
@@ -15,29 +15,29 @@
 /// a mix-in when creating a subclass of [FixContributor].
 abstract class FixContributorMixin implements FixContributor {
   /// The request that specifies the fixes that are to be built.
-  DartFixesRequest request;
+  DartFixesRequest? request;
 
   /// The collector to which fixes should be added.
-  FixCollector collector;
+  FixCollector? collector;
 
   /// Add a fix for the given [error]. Use the [kind] of the fix to get the
   /// message and priority, and use the change [builder] to get the edits that
   /// comprise the fix. If the message has parameters, then use the list of
   /// [args] to populate the message.
   void addFix(AnalysisError error, FixKind kind, ChangeBuilder builder,
-      {List<Object> args}) {
+      {List<Object>? args}) {
     var change = builder.sourceChange;
     if (change.edits.isEmpty) {
       return;
     }
     change.id = kind.id;
     change.message = formatList(kind.message, args);
-    collector.addFix(
-        error, PrioritizedSourceChange(kind.priority, change));
+    collector?.addFix(error, PrioritizedSourceChange(kind.priority, change));
   }
 
   @override
-  Future<void> computeFixes(DartFixesRequest request, FixCollector collector) async {
+  Future<void> computeFixes(
+      DartFixesRequest request, FixCollector collector) async {
     this.request = request;
     this.collector = collector;
     try {
diff --git a/pkg/analyzer_plugin/lib/utilities/generator.dart b/pkg/analyzer_plugin/lib/utilities/generator.dart
index 4012c9a..80fabb9 100644
--- a/pkg/analyzer_plugin/lib/utilities/generator.dart
+++ b/pkg/analyzer_plugin/lib/utilities/generator.dart
@@ -9,7 +9,7 @@
 /// The result produced by a generator.
 ///
 /// Clients may not extend, implement or mix-in this class.
-class GeneratorResult<T extends ResponseResult> {
+class GeneratorResult<T extends ResponseResult?> {
   /// The result to be sent to the server, or `null` if there is no response, as
   /// when the generator is generating a notification.
   final T result;
diff --git a/pkg/analyzer_plugin/lib/utilities/navigation/navigation.dart b/pkg/analyzer_plugin/lib/utilities/navigation/navigation.dart
index 74d0821..9e02f7a4f 100644
--- a/pkg/analyzer_plugin/lib/utilities/navigation/navigation.dart
+++ b/pkg/analyzer_plugin/lib/utilities/navigation/navigation.dart
@@ -40,7 +40,7 @@
   /// should navigate to the given [targetNameLocation].
   void addRegion(int offset, int length, ElementKind targetKind,
       Location targetNameLocation,
-      {Location targetCodeLocation});
+      {Location? targetCodeLocation});
 }
 
 /// An object used to produce navigation regions.
@@ -115,7 +115,7 @@
 abstract class NavigationRequest {
   /// Return the length of the region within the source for which navigation
   /// regions are being requested.
-  int get length;
+  int? get length;
 
   /// Return the offset of the region within the source for which navigation
   /// regions are being requested.
diff --git a/pkg/analyzer_plugin/lib/utilities/navigation/navigation_dart.dart b/pkg/analyzer_plugin/lib/utilities/navigation/navigation_dart.dart
index 1fe66bc..dde44ba 100644
--- a/pkg/analyzer_plugin/lib/utilities/navigation/navigation_dart.dart
+++ b/pkg/analyzer_plugin/lib/utilities/navigation/navigation_dart.dart
@@ -18,8 +18,8 @@
     ResourceProvider resourceProvider,
     NavigationCollector collector,
     CompilationUnit unit,
-    int offset,
-    int length) {
+    int? offset,
+    int? length) {
   var dartCollector = _DartNavigationCollector(collector, offset, length);
   var visitor = _DartNavigationComputerVisitor(resourceProvider, dartCollector);
   if (offset == null || length == null) {
@@ -31,7 +31,7 @@
   return collector;
 }
 
-AstNode _getNodeForRange(CompilationUnit unit, int offset, int length) {
+AstNode? _getNodeForRange(CompilationUnit unit, int offset, int length) {
   var node = NodeLocator(offset, offset + length).searchWithin(unit);
   for (var n = node; n != null; n = n.parent) {
     if (n is Directive) {
@@ -44,15 +44,15 @@
 /// A Dart specific wrapper around [NavigationCollector].
 class _DartNavigationCollector {
   final NavigationCollector collector;
-  final int requestedOffset;
-  final int requestedLength;
+  final int? requestedOffset;
+  final int? requestedLength;
 
   _DartNavigationCollector(
       this.collector, this.requestedOffset, this.requestedLength);
 
-  void _addRegion(int offset, int length, Element element) {
+  void _addRegion(int offset, int length, Element? element) {
     if (element is FieldFormalParameterElement) {
-      element = (element as FieldFormalParameterElement).field;
+      element = element.field;
     }
     if (element == null || element == DynamicElementImpl.instance) {
       return;
@@ -62,8 +62,8 @@
     }
     // Discard elements that don't span the offset/range given (if provided).
     if (requestedOffset != null &&
-        (offset > requestedOffset + (requestedLength ?? 0) ||
-            offset + length < requestedOffset)) {
+        (offset > requestedOffset! + (requestedLength ?? 0) ||
+            offset + length < requestedOffset!)) {
       return;
     }
     var converter = AnalyzerConverter();
@@ -81,13 +81,13 @@
         targetCodeLocation: codeLocation);
   }
 
-  void _addRegion_nodeStart_nodeEnd(AstNode a, AstNode b, Element element) {
+  void _addRegion_nodeStart_nodeEnd(AstNode a, AstNode b, Element? element) {
     var offset = a.offset;
     var length = b.end - offset;
     _addRegion(offset, length, element);
   }
 
-  void _addRegionForNode(AstNode node, Element element) {
+  void _addRegionForNode(AstNode? node, Element? element) {
     if (node == null) {
       return;
     }
@@ -96,20 +96,20 @@
     _addRegion(offset, length, element);
   }
 
-  void _addRegionForToken(Token token, Element element) {
+  void _addRegionForToken(Token token, Element? element) {
     var offset = token.offset;
     var length = token.length;
     _addRegion(offset, length, element);
   }
 
   /// Get the location of the code (excluding leading doc comments) for this element.
-  protocol.Location _getCodeLocation(Element element,
+  protocol.Location? _getCodeLocation(Element element,
       protocol.Location location, AnalyzerConverter converter) {
     var codeElement = element;
     // For synthetic getters created for fields, we need to access the associated
     // variable to get the codeOffset/codeLength.
     if (codeElement.isSynthetic && codeElement is PropertyAccessorElementImpl) {
-      final variable = (codeElement as PropertyAccessorElementImpl).variable;
+      final variable = codeElement.variable;
       if (variable is ElementImpl) {
         codeElement = variable as ElementImpl;
       }
@@ -117,7 +117,7 @@
 
     // Read the main codeOffset from the element. This may include doc comments
     // but will give the correct end position.
-    int codeOffset, codeLength;
+    int? codeOffset, codeLength;
     if (codeElement is ElementImpl) {
       codeOffset = codeElement.codeOffset;
       codeLength = codeElement.codeLength;
@@ -130,11 +130,13 @@
     // Read the declaration so we can get the offset after the doc comments.
     // TODO(dantup): Skip this for parts (getParsedLibrary will throw), but find
     // a better solution.
-    final declaration = !codeElement.session.getFile(location.file).isPart
-        ? codeElement.session
-            .getParsedLibrary(location.file)
-            .getElementDeclaration(codeElement)
-        : null;
+    var session = codeElement.session;
+    final declaration =
+        session != null && !session.getFile(location.file).isPart
+            ? session
+                .getParsedLibrary(location.file)
+                .getElementDeclaration(codeElement)
+            : null;
     var node = declaration?.node;
     if (node is VariableDeclaration) {
       node = node.parent;
@@ -147,10 +149,6 @@
       codeOffset = offsetAfterDocs;
     }
 
-    if (codeOffset == null || codeLength == null) {
-      return null;
-    }
-
     return converter.locationFromElement(element,
         offset: codeOffset, length: codeLength);
   }
@@ -182,22 +180,24 @@
       computer._addRegionForNode(name, element);
     }
     computer._addRegionForNode(node.constructorName, element);
+    // type arguments
+    node.typeArguments?.accept(this);
     // arguments
     node.arguments?.accept(this);
   }
 
   @override
   void visitAssignmentExpression(AssignmentExpression node) {
-    node.leftHandSide?.accept(this);
+    node.leftHandSide.accept(this);
     computer._addRegionForToken(node.operator, node.staticElement);
-    node.rightHandSide?.accept(this);
+    node.rightHandSide.accept(this);
   }
 
   @override
   void visitBinaryExpression(BinaryExpression node) {
-    node.leftOperand?.accept(this);
+    node.leftOperand.accept(this);
     computer._addRegionForToken(node.operator, node.staticElement);
-    node.rightOperand?.accept(this);
+    node.rightOperand.accept(this);
   }
 
   @override
@@ -227,7 +227,7 @@
             uriNode.offset,
             uriNode.length,
             protocol.ElementKind.LIBRARY,
-            protocol.Location(source.fullName, 0, 0, 0, 0));
+            protocol.Location(source.fullName, 0, 0, 0, 0, 0, 0));
       }
     }
     super.visitConfiguration(node);
@@ -238,12 +238,10 @@
     // associate constructor with "T" or "T.name"
     {
       AstNode firstNode = node.returnType;
-      AstNode lastNode = node.name;
+      AstNode? lastNode = node.name;
       lastNode ??= firstNode;
-      if (firstNode != null && lastNode != null) {
-        computer._addRegion_nodeStart_nodeEnd(
-            firstNode, lastNode, node.declaredElement);
-      }
+      computer._addRegion_nodeStart_nodeEnd(
+          firstNode, lastNode, node.declaredElement);
     }
     super.visitConstructorDeclaration(node);
   }
@@ -264,7 +262,7 @@
   void visitDeclaredIdentifier(DeclaredIdentifier node) {
     if (node.type == null) {
       var token = node.keyword;
-      if (token?.keyword == Keyword.VAR) {
+      if (token != null && token.keyword == Keyword.VAR) {
         var inferredType = node.declaredElement?.type;
         var element = inferredType?.element;
         if (element != null) {
@@ -279,7 +277,7 @@
   void visitExportDirective(ExportDirective node) {
     var exportElement = node.element;
     if (exportElement != null) {
-      Element libraryElement = exportElement.exportedLibrary;
+      Element? libraryElement = exportElement.exportedLibrary;
       _addUriDirectiveRegion(node, libraryElement);
     }
     super.visitExportDirective(node);
@@ -289,7 +287,7 @@
   void visitImportDirective(ImportDirective node) {
     var importElement = node.element;
     if (importElement != null) {
-      Element libraryElement = importElement.importedLibrary;
+      Element? libraryElement = importElement.importedLibrary;
       _addUriDirectiveRegion(node, libraryElement);
     }
     super.visitImportDirective(node);
@@ -335,7 +333,7 @@
   @override
   void visitRedirectingConstructorInvocation(
       RedirectingConstructorInvocation node) {
-    Element element = node.staticElement;
+    Element? element = node.staticElement;
     if (element != null && element.isSynthetic) {
       element = element.enclosingElement;
     }
@@ -343,7 +341,7 @@
     computer._addRegionForToken(node.thisKeyword, element);
     computer._addRegionForNode(node.constructorName, element);
     // process arguments
-    node.argumentList?.accept(this);
+    node.argumentList.accept(this);
   }
 
   @override
@@ -357,7 +355,7 @@
 
   @override
   void visitSuperConstructorInvocation(SuperConstructorInvocation node) {
-    Element element = node.staticElement;
+    Element? element = node.staticElement;
     if (element != null && element.isSynthetic) {
       element = element.enclosingElement;
     }
@@ -365,7 +363,7 @@
     computer._addRegionForToken(node.superKeyword, element);
     computer._addRegionForNode(node.constructorName, element);
     // process arguments
-    node.argumentList?.accept(this);
+    node.argumentList.accept(this);
   }
 
   @override
@@ -373,13 +371,13 @@
     /// Return the element for the type inferred for each of the variables in
     /// the given list of [variables], or `null` if not all variable have the
     /// same inferred type.
-    Element getCommonElement(List<VariableDeclaration> variables) {
-      var firstElement = variables[0].declaredElement.type?.element;
+    Element? getCommonElement(List<VariableDeclaration> variables) {
+      var firstElement = variables[0].declaredElement?.type.element;
       if (firstElement == null) {
         return null;
       }
       for (var i = 1; i < variables.length; i++) {
-        var element = variables[1].declaredElement.type?.element;
+        var element = variables[1].declaredElement?.type.element;
         if (element != firstElement) {
           return null;
         }
@@ -392,7 +390,7 @@
       if (token?.keyword == Keyword.VAR) {
         var element = getCommonElement(node.variables);
         if (element != null) {
-          computer._addRegionForToken(token, element);
+          computer._addRegionForToken(token!, element);
         }
       }
     }
@@ -400,7 +398,7 @@
   }
 
   void _addConstructorName(AstNode parent, ConstructorName node) {
-    Element element = node.staticElement;
+    Element? element = node.staticElement;
     if (element == null) {
       return;
     }
@@ -433,7 +431,7 @@
 
   /// If the source of the given [element] (referenced by the [node]) exists,
   /// then add the navigation region from the [node] to the [element].
-  void _addUriDirectiveRegion(UriBasedDirective node, Element element) {
+  void _addUriDirectiveRegion(UriBasedDirective node, Element? element) {
     var source = element?.source;
     if (source != null) {
       if (resourceProvider.getResource(source.fullName).exists) {
diff --git a/pkg/analyzer_plugin/lib/utilities/range_factory.dart b/pkg/analyzer_plugin/lib/utilities/range_factory.dart
index fbcbaa3..b967af5 100644
--- a/pkg/analyzer_plugin/lib/utilities/range_factory.dart
+++ b/pkg/analyzer_plugin/lib/utilities/range_factory.dart
@@ -103,8 +103,8 @@
   SourceRange nodeInList<T extends AstNode>(NodeList<T> list, T item) {
     if (list.length == 1) {
       var nextToken = item.endToken.next;
-      if (nextToken.type == TokenType.COMMA) {
-        return startEnd(item, nextToken);
+      if (nextToken?.type == TokenType.COMMA) {
+        return startEnd(item, nextToken!);
       }
       return node(item);
     }
diff --git a/pkg/analyzer_plugin/lib/utilities/subscriptions/subscription_manager.dart b/pkg/analyzer_plugin/lib/utilities/subscriptions/subscription_manager.dart
index 22b0fec..5022374 100644
--- a/pkg/analyzer_plugin/lib/utilities/subscriptions/subscription_manager.dart
+++ b/pkg/analyzer_plugin/lib/utilities/subscriptions/subscription_manager.dart
@@ -9,7 +9,7 @@
 /// Clients may not extend, implement or mix-in this class.
 class SubscriptionManager {
   /// The current set of subscriptions.
-  Map<AnalysisService, List<String>> _subscriptions;
+  Map<AnalysisService, List<String>>? _subscriptions;
 
   /// Initialize a newly created subscription manager to have no subscriptions.
   SubscriptionManager();
@@ -17,10 +17,11 @@
   /// Return `true` if the file with the given [filePath] has a subscription for
   /// the given [service].
   bool hasSubscriptionForFile(String filePath, AnalysisService service) {
-    if (_subscriptions == null) {
+    var subscriptions = _subscriptions;
+    if (subscriptions == null) {
       return false;
     }
-    var files = _subscriptions[service];
+    var files = subscriptions[service];
     return files != null && files.contains(filePath);
   }
 
@@ -28,8 +29,9 @@
   /// has been subscribed.
   List<AnalysisService> servicesForFile(String filePath) {
     var services = <AnalysisService>[];
-    if (_subscriptions != null) {
-      _subscriptions.forEach((AnalysisService service, List<String> files) {
+    var subscriptions = _subscriptions;
+    if (subscriptions != null) {
+      subscriptions.forEach((AnalysisService service, List<String> files) {
         if (files.contains(filePath)) {
           services.add(service);
         }
@@ -47,7 +49,8 @@
   Map<String, List<AnalysisService>> setSubscriptions(
       Map<AnalysisService, List<String>> subscriptions) {
     var newSubscriptions = <String, List<AnalysisService>>{};
-    if (_subscriptions == null) {
+    var currentSubscriptions = _subscriptions;
+    if (currentSubscriptions == null) {
       // This is the first time subscriptions have been set, so all of the
       // subscriptions are new.
       subscriptions.forEach((AnalysisService service, List<String> paths) {
@@ -61,9 +64,9 @@
       // The subscriptions have been changed, to we need to compute the
       // difference.
       subscriptions.forEach((AnalysisService service, List<String> paths) {
-        var oldPaths = _subscriptions[service];
+        var oldPaths = currentSubscriptions[service];
         for (var path in paths) {
-          if (!oldPaths.contains(path)) {
+          if (oldPaths == null || !oldPaths.contains(path)) {
             newSubscriptions
                 .putIfAbsent(path, () => <AnalysisService>[])
                 .add(service);
diff --git a/pkg/analyzer_plugin/pubspec.yaml b/pkg/analyzer_plugin/pubspec.yaml
index 2a91465..2572cff 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.5.0-dev
+version: 0.5.0
 author: Dart Team <misc@dartlang.org>
 homepage: https://github.com/dart-lang/sdk/tree/master/pkg/analyzer_plugin
 
 environment:
-  sdk: '>=2.9.0 <3.0.0'
+  sdk: '>=2.12.0 <3.0.0'
 
 dependencies:
-  analyzer: '>=0.42.0 <0.43.0'
-  dart_style: '^1.2.0'
-  meta: ^1.2.3
-  pub_semver: '^1.3.2'
+  analyzer: ^1.3.0
+  collection: ^1.15.0
+  dart_style: ^2.0.0
+  pub_semver: ^2.0.0
 
 dev_dependencies:
   analyzer_utilities:
     path: ../analyzer_utilities
-  html: '>=0.13.1 <0.15.0'
-  path: '^1.4.1'
-  test_reflective_loader: ^0.1.8
-  test: ^1.0.0
+  html: ^0.15.0
+  path: ^1.8.0
+  test_reflective_loader: ^0.2.0
+  test: ^1.16.6
diff --git a/pkg/analyzer_plugin/test/integration/support/integration_test_methods.dart b/pkg/analyzer_plugin/test/integration/support/integration_test_methods.dart
index 7bc81f3..79c042c 100644
--- a/pkg/analyzer_plugin/test/integration/support/integration_test_methods.dart
+++ b/pkg/analyzer_plugin/test/integration/support/integration_test_methods.dart
@@ -112,10 +112,10 @@
   ///
   ///   The stack trace associated with the generation of the error, used for
   ///   debugging the plugin.
-  Stream<PluginErrorParams> onPluginError;
+  late Stream<PluginErrorParams> onPluginError;
 
   /// Stream controller for [onPluginError].
-  StreamController<PluginErrorParams> _onPluginError;
+  late StreamController<PluginErrorParams> _onPluginError;
 
   /// Return the navigation information associated with the given region of the
   /// given file. If the navigation information for the given file has not yet
@@ -257,7 +257,7 @@
   ///
   ///   A table mapping the files whose content has changed to a description of
   ///   the content change.
-  Future sendAnalysisUpdateContent(Map<String, dynamic> files) async {
+  Future sendAnalysisUpdateContent(Map<String, Object> files) async {
     var params = AnalysisUpdateContentParams(files).toJson();
     var result = await server.send('analysis.updateContent', params);
     outOfTestExpect(result, isNull);
@@ -277,10 +277,10 @@
   /// errors: List<AnalysisError>
   ///
   ///   The errors contained in the file.
-  Stream<AnalysisErrorsParams> onAnalysisErrors;
+  late Stream<AnalysisErrorsParams> onAnalysisErrors;
 
   /// Stream controller for [onAnalysisErrors].
-  StreamController<AnalysisErrorsParams> _onAnalysisErrors;
+  late StreamController<AnalysisErrorsParams> _onAnalysisErrors;
 
   /// Used to report the folding regions associated with a given file. Folding
   /// regions can be nested, but cannot be overlapping. Nesting occurs when a
@@ -304,10 +304,10 @@
   /// regions: List<FoldingRegion>
   ///
   ///   The folding regions contained in the file.
-  Stream<AnalysisFoldingParams> onAnalysisFolding;
+  late Stream<AnalysisFoldingParams> onAnalysisFolding;
 
   /// Stream controller for [onAnalysisFolding].
-  StreamController<AnalysisFoldingParams> _onAnalysisFolding;
+  late StreamController<AnalysisFoldingParams> _onAnalysisFolding;
 
   /// Used to report the highlight regions associated with a given file. Each
   /// highlight region represents a particular syntactic or semantic meaning
@@ -328,10 +328,10 @@
   /// regions: List<HighlightRegion>
   ///
   ///   The highlight regions contained in the file.
-  Stream<AnalysisHighlightsParams> onAnalysisHighlights;
+  late Stream<AnalysisHighlightsParams> onAnalysisHighlights;
 
   /// Stream controller for [onAnalysisHighlights].
-  StreamController<AnalysisHighlightsParams> _onAnalysisHighlights;
+  late StreamController<AnalysisHighlightsParams> _onAnalysisHighlights;
 
   /// Used to report the navigation regions associated with a given file. Each
   /// navigation region represents a list of targets associated with some
@@ -369,10 +369,10 @@
   ///
   ///   The files containing navigation targets referenced in the file. They
   ///   are referenced by NavigationTargets by their index in this array.
-  Stream<AnalysisNavigationParams> onAnalysisNavigation;
+  late Stream<AnalysisNavigationParams> onAnalysisNavigation;
 
   /// Stream controller for [onAnalysisNavigation].
-  StreamController<AnalysisNavigationParams> _onAnalysisNavigation;
+  late StreamController<AnalysisNavigationParams> _onAnalysisNavigation;
 
   /// Used to report the occurrences of references to elements within a single
   /// file. None of the occurrence regions should overlap.
@@ -395,10 +395,10 @@
   /// occurrences: List<Occurrences>
   ///
   ///   The occurrences of references to elements within the file.
-  Stream<AnalysisOccurrencesParams> onAnalysisOccurrences;
+  late Stream<AnalysisOccurrencesParams> onAnalysisOccurrences;
 
   /// Stream controller for [onAnalysisOccurrences].
-  StreamController<AnalysisOccurrencesParams> _onAnalysisOccurrences;
+  late StreamController<AnalysisOccurrencesParams> _onAnalysisOccurrences;
 
   /// Used to report the outline fragments associated with a single file.
   ///
@@ -419,10 +419,10 @@
   /// outline: List<Outline>
   ///
   ///   The outline fragments associated with the file.
-  Stream<AnalysisOutlineParams> onAnalysisOutline;
+  late Stream<AnalysisOutlineParams> onAnalysisOutline;
 
   /// Stream controller for [onAnalysisOutline].
-  StreamController<AnalysisOutlineParams> _onAnalysisOutline;
+  late StreamController<AnalysisOutlineParams> _onAnalysisOutline;
 
   /// Used to request that completion suggestions for the given offset in the
   /// given file be returned.
@@ -642,7 +642,7 @@
   ///   the refactoring.
   Future<EditGetRefactoringResult> sendEditGetRefactoring(RefactoringKind kind,
       String file, int offset, int length, bool validateOnly,
-      {RefactoringOptions options}) async {
+      {RefactoringOptions? options}) async {
     var params = EditGetRefactoringParams(
             kind, file, offset, length, validateOnly,
             options: options)
@@ -746,7 +746,6 @@
         break;
       default:
         fail('Unexpected notification: $event');
-        break;
     }
   }
 }
diff --git a/pkg/analyzer_plugin/test/integration/support/integration_tests.dart b/pkg/analyzer_plugin/test/integration/support/integration_tests.dart
index 3d3391c..0fe14b2 100644
--- a/pkg/analyzer_plugin/test/integration/support/integration_tests.dart
+++ b/pkg/analyzer_plugin/test/integration/support/integration_tests.dart
@@ -39,7 +39,7 @@
 
 /// Assert that [actual] matches [matcher].
 void outOfTestExpect(actual, Matcher matcher,
-    {String reason, skip, bool verbose = false}) {
+    {String? reason, skip, bool verbose = false}) {
   var matchState = {};
   try {
     if (matcher.matches(actual, matchState)) return;
@@ -50,7 +50,7 @@
 }
 
 String _defaultFailFormatter(
-    actual, Matcher matcher, String reason, Map matchState, bool verbose) {
+    actual, Matcher matcher, String? reason, Map matchState, bool verbose) {
   var description = StringDescription();
   description.add('Expected: ').addDescriptionOf(matcher).add('\n');
   description.add('  Actual: ').addDescriptionOf(actual).add('\n');
@@ -87,7 +87,7 @@
   final Server server = Server();
 
   /// Temporary directory in which source files can be stored.
-  Directory sourceDirectory;
+  Directory? sourceDirectory;
 
   /// Map from file path to the list of analysis errors which have most recently
   /// been received for the file.
@@ -176,7 +176,7 @@
   /// relative to [sourceDirectory]. On Windows any forward slashes in
   /// [relativePath] are converted to backslashes.
   String sourcePath(String relativePath) {
-    return join(sourceDirectory.path, relativePath.replaceAll('/', separator));
+    return join(sourceDirectory!.path, relativePath.replaceAll('/', separator));
   }
 
   /// Send the server an 'analysis.setAnalysisRoots' command directing it to
@@ -195,7 +195,7 @@
 
   /// Start [server].
   Future startServer(
-          {bool checked = true, int diagnosticPort, int servicesPort}) =>
+          {bool checked = true, int? diagnosticPort, int? servicesPort}) =>
       server.start(
           checked: checked,
           diagnosticPort: diagnosticPort,
@@ -204,7 +204,7 @@
   /// After every test, the server is stopped and [sourceDirectory] is deleted.
   Future tearDown() {
     return shutdownIfNeeded().then((_) {
-      sourceDirectory.deleteSync(recursive: true);
+      sourceDirectory!.deleteSync(recursive: true);
     });
   }
 
@@ -234,28 +234,28 @@
 
   /// The matcher returned by [_creator], if it has already been called.
   /// Otherwise null.
-  Matcher _wrappedMatcher;
+  Matcher? _wrappedMatcher;
 
   LazyMatcher(this._creator);
 
   @override
   Description describe(Description description) {
     _createMatcher();
-    return _wrappedMatcher.describe(description);
+    return _wrappedMatcher!.describe(description);
   }
 
   @override
   Description describeMismatch(
       item, Description mismatchDescription, Map matchState, bool verbose) {
     _createMatcher();
-    return _wrappedMatcher.describeMismatch(
-        item, mismatchDescription, matchState, verbose);
+    return _wrappedMatcher!
+        .describeMismatch(item, mismatchDescription, matchState, verbose);
   }
 
   @override
   bool matches(item, Map matchState) {
     _createMatcher();
-    return _wrappedMatcher.matches(item, matchState);
+    return _wrappedMatcher!.matches(item, matchState);
   }
 
   /// Create the wrapped matcher object, if it hasn't been created already.
@@ -292,11 +292,11 @@
 
   /// Fields that are required to be in the JSON object, and [Matcher]s describing
   /// their expected types.
-  final Map<String, Matcher> requiredFields;
+  final Map<String, Matcher>? requiredFields;
 
   /// Fields that are optional in the JSON object, and [Matcher]s describing
   /// their expected types.
-  final Map<String, Matcher> optionalFields;
+  final Map<String, Matcher>? optionalFields;
 
   const MatchesJsonObject(this.description, this.requiredFields,
       {this.optionalFields});
@@ -311,9 +311,10 @@
       mismatches.add(simpleDescription('is not a map'));
       return;
     }
+    var requiredFields = this.requiredFields;
     if (requiredFields != null) {
       requiredFields.forEach((String key, Matcher valueMatcher) {
-        if (!(item as Map).containsKey(key)) {
+        if (!item.containsKey(key)) {
           mismatches.add((Description mismatchDescription) =>
               mismatchDescription
                   .add('is missing field ')
@@ -326,11 +327,12 @@
         }
       });
     }
+    var optionalFields = this.optionalFields;
     item.forEach((key, value) {
       if (requiredFields != null && requiredFields.containsKey(key)) {
         // Already checked this field
       } else if (optionalFields != null && optionalFields.containsKey(key)) {
-        _checkField(key as String, value, optionalFields[key], mismatches);
+        _checkField(key as String, value, optionalFields[key]!, mismatches);
       } else {
         mismatches.add((Description mismatchDescription) => mismatchDescription
             .add('has unexpected field ')
@@ -357,7 +359,7 @@
 /// facilitate communication to and from the server.
 class Server {
   /// Server process object, or null if server hasn't been started yet.
-  Process _process;
+  Process? _process;
 
   /// Commands that have been sent to the server but not yet acknowledged, and
   /// the [Completer] objects which should be completed when acknowledgement is
@@ -385,13 +387,13 @@
 
   /// The [currentElapseTime] at which the last communication was received from the server
   /// or `null` if no communication has been received.
-  double lastCommunicationTime;
+  double? lastCommunicationTime;
 
   /// The current elapse time (seconds) since the server was started.
   double get currentElapseTime => _time.elapsedTicks / _time.frequency;
 
   /// Future that completes when the server process exits.
-  Future<int> get exitCode => _process.exitCode;
+  Future<int> get exitCode => _process!.exitCode;
 
   /// Print out any messages exchanged with the server. If some messages have
   /// already been exchanged with the server, they are printed out immediately.
@@ -421,21 +423,21 @@
   /// Return a future that will complete when all commands that have been sent
   /// to the server so far have been flushed to the OS buffer.
   Future flushCommands() {
-    return _process.stdin.flush();
+    return _process!.stdin.flush();
   }
 
   /// Stop the server.
   Future<int> kill(String reason) {
     debugStdio();
     _recordStdio('FORCIBLY TERMINATING PROCESS: $reason');
-    _process.kill();
-    return _process.exitCode;
+    _process!.kill();
+    return _process!.exitCode;
   }
 
   /// Start listening to output from the server, and deliver notifications to
   /// [notificationProcessor].
   void listenToOutput(NotificationProcessor notificationProcessor) {
-    _process.stdout
+    _process!.stdout
         .transform((Utf8Codec()).decoder)
         .transform(LineSplitter())
         .listen((String line) {
@@ -485,7 +487,7 @@
         outOfTestExpect(message, isNotification);
       }
     });
-    _process.stderr
+    _process!.stderr
         .transform((Utf8Codec()).decoder)
         .transform(LineSplitter())
         .listen((String line) {
@@ -501,7 +503,7 @@
   /// normal (non-error) response, the future will be completed with the 'result'
   /// field from the response. If the server acknowledges the command with an
   /// error response, the future will be completed with an error.
-  Future send(String method, Map<String, dynamic> params) {
+  Future send(String method, Map<String, dynamic>? params) {
     var id = '${_nextId++}';
     var command = <String, dynamic>{'id': id, 'method': method};
     if (params != null) {
@@ -511,7 +513,7 @@
     _pendingCommands[id] = completer;
     var line = json.encode(command);
     _recordStdio('SEND: $line');
-    _process.stdin.add(utf8.encoder.convert('$line\n'));
+    _process!.stdin.add(utf8.encoder.convert('$line\n'));
     return completer.future;
   }
 
@@ -522,10 +524,10 @@
   Future start(
       {bool checked = true,
       bool debugServer = false,
-      int diagnosticPort,
+      int? diagnosticPort,
       bool profileServer = false,
-      String sdkPath,
-      int servicesPort,
+      String? sdkPath,
+      int? servicesPort,
       bool useAnalysisHighlight2 = false}) {
     if (_process != null) {
       throw Exception('Process already started');
@@ -782,7 +784,7 @@
   @override
   Description describeMismatch(
       item, Description mismatchDescription, Map matchState, bool verbose) {
-    var mismatches = matchState['mismatches'] as List<MismatchDescriber>;
+    var mismatches = matchState['mismatches'] as List<MismatchDescriber>?;
     if (mismatches != null) {
       for (var i = 0; i < mismatches.length; i++) {
         var mismatch = mismatches[i];
diff --git a/pkg/analyzer_plugin/test/integration/support/protocol_matchers.dart b/pkg/analyzer_plugin/test/integration/support/protocol_matchers.dart
index e00577b..308bad8 100644
--- a/pkg/analyzer_plugin/test/integration/support/protocol_matchers.dart
+++ b/pkg/analyzer_plugin/test/integration/support/protocol_matchers.dart
@@ -589,13 +589,17 @@
 ///   "length": int
 ///   "startLine": int
 ///   "startColumn": int
+///   "endLine": int
+///   "endColumn": int
 /// }
 final Matcher isLocation = LazyMatcher(() => MatchesJsonObject('Location', {
       'file': isFilePath,
       'offset': isInt,
       'length': isInt,
       'startLine': isInt,
-      'startColumn': isInt
+      'startColumn': isInt,
+      'endLine': isInt,
+      'endColumn': isInt
     }));
 
 /// NavigationRegion
diff --git a/pkg/analyzer_plugin/test/plugin/assist_mixin_test.dart b/pkg/analyzer_plugin/test/plugin/assist_mixin_test.dart
index 955290a..4a5899e 100644
--- a/pkg/analyzer_plugin/test/plugin/assist_mixin_test.dart
+++ b/pkg/analyzer_plugin/test/plugin/assist_mixin_test.dart
@@ -20,12 +20,12 @@
 
 @reflectiveTest
 class AssistsMixinTest with ResourceProviderMixin {
-  String packagePath1;
-  String filePath1;
-  ContextRoot contextRoot1;
+  late String packagePath1;
+  late String filePath1;
+  late ContextRoot contextRoot1;
 
-  MockChannel channel;
-  _TestServerPlugin plugin;
+  late MockChannel channel;
+  late _TestServerPlugin plugin;
 
   void setUp() {
     packagePath1 = convertPath('/package1');
@@ -55,7 +55,8 @@
   _TestAssistContributor(this.changes);
 
   @override
-  Future<void> computeAssists(AssistRequest request, AssistCollector collector) async {
+  Future<void> computeAssists(
+      AssistRequest request, AssistCollector collector) async {
     for (var change in changes) {
       collector.addAssist(change);
     }
diff --git a/pkg/analyzer_plugin/test/plugin/completion_mixin_test.dart b/pkg/analyzer_plugin/test/plugin/completion_mixin_test.dart
index 36ce569..35ecf19 100644
--- a/pkg/analyzer_plugin/test/plugin/completion_mixin_test.dart
+++ b/pkg/analyzer_plugin/test/plugin/completion_mixin_test.dart
@@ -20,12 +20,12 @@
 
 @reflectiveTest
 class CompletionMixinTest with ResourceProviderMixin {
-  String packagePath1;
-  String filePath1;
-  ContextRoot contextRoot1;
+  late String packagePath1;
+  late String filePath1;
+  late ContextRoot contextRoot1;
 
-  MockChannel channel;
-  _TestServerPlugin plugin;
+  late MockChannel channel;
+  late _TestServerPlugin plugin;
 
   void setUp() {
     packagePath1 = convertPath('/package1');
diff --git a/pkg/analyzer_plugin/test/plugin/fix_mixin_test.dart b/pkg/analyzer_plugin/test/plugin/fix_mixin_test.dart
index 06a1c7f..edb6601 100644
--- a/pkg/analyzer_plugin/test/plugin/fix_mixin_test.dart
+++ b/pkg/analyzer_plugin/test/plugin/fix_mixin_test.dart
@@ -24,12 +24,12 @@
 
 @reflectiveTest
 class FixesMixinTest with ResourceProviderMixin {
-  String packagePath1;
-  String filePath1;
-  ContextRoot contextRoot1;
+  late String packagePath1;
+  late String filePath1;
+  late ContextRoot contextRoot1;
 
-  MockChannel channel;
-  _TestServerPlugin plugin;
+  late MockChannel channel;
+  late _TestServerPlugin plugin;
 
   void setUp() {
     packagePath1 = convertPath('/package1');
@@ -61,7 +61,8 @@
   _TestFixContributor(this.changes);
 
   @override
-  Future<void> computeFixes(FixesRequest request, FixCollector collector) async {
+  Future<void> computeFixes(
+      FixesRequest request, FixCollector collector) async {
     for (var change in changes) {
       collector.addFix(request.errorsToFix[0], change);
     }
diff --git a/pkg/analyzer_plugin/test/plugin/folding_mixin_test.dart b/pkg/analyzer_plugin/test/plugin/folding_mixin_test.dart
index 0b2f063..ef7d1cd0 100644
--- a/pkg/analyzer_plugin/test/plugin/folding_mixin_test.dart
+++ b/pkg/analyzer_plugin/test/plugin/folding_mixin_test.dart
@@ -23,12 +23,12 @@
 
 @reflectiveTest
 class FoldingMixinTest with ResourceProviderMixin {
-  String packagePath1;
-  String filePath1;
-  ContextRoot contextRoot1;
+  late String packagePath1;
+  late String filePath1;
+  late ContextRoot contextRoot1;
 
-  MockChannel channel;
-  _TestServerPlugin plugin;
+  late MockChannel channel;
+  late _TestServerPlugin plugin;
 
   void setUp() {
     packagePath1 = convertPath('/package1');
diff --git a/pkg/analyzer_plugin/test/plugin/highlights_mixin_test.dart b/pkg/analyzer_plugin/test/plugin/highlights_mixin_test.dart
index 98e39d5..bbf3d1a 100644
--- a/pkg/analyzer_plugin/test/plugin/highlights_mixin_test.dart
+++ b/pkg/analyzer_plugin/test/plugin/highlights_mixin_test.dart
@@ -23,12 +23,12 @@
 
 @reflectiveTest
 class HighlightsMixinTest with ResourceProviderMixin {
-  String packagePath1;
-  String filePath1;
-  ContextRoot contextRoot1;
+  late String packagePath1;
+  late String filePath1;
+  late ContextRoot contextRoot1;
 
-  MockChannel channel;
-  _TestServerPlugin plugin;
+  late MockChannel channel;
+  late _TestServerPlugin plugin;
 
   void setUp() {
     packagePath1 = convertPath('/package1');
diff --git a/pkg/analyzer_plugin/test/plugin/kythe_mixin_test.dart b/pkg/analyzer_plugin/test/plugin/kythe_mixin_test.dart
index 45588b4..c1df465 100644
--- a/pkg/analyzer_plugin/test/plugin/kythe_mixin_test.dart
+++ b/pkg/analyzer_plugin/test/plugin/kythe_mixin_test.dart
@@ -20,12 +20,12 @@
 
 @reflectiveTest
 class KytheMixinTest with ResourceProviderMixin {
-  String packagePath1;
-  String filePath1;
-  ContextRoot contextRoot1;
+  late String packagePath1;
+  late String filePath1;
+  late ContextRoot contextRoot1;
 
-  MockChannel channel;
-  _TestServerPlugin plugin;
+  late MockChannel channel;
+  late _TestServerPlugin plugin;
 
   void setUp() {
     packagePath1 = convertPath('/package1');
diff --git a/pkg/analyzer_plugin/test/plugin/mocks.dart b/pkg/analyzer_plugin/test/plugin/mocks.dart
index 6d466d2..338593b 100644
--- a/pkg/analyzer_plugin/test/plugin/mocks.dart
+++ b/pkg/analyzer_plugin/test/plugin/mocks.dart
@@ -39,10 +39,10 @@
 class MockChannel implements PluginCommunicationChannel {
   bool _closed = false;
 
-  void Function() _onDone;
-  Function _onError;
-  void Function(Notification) _onNotification;
-  void Function(Request) _onRequest;
+  void Function()? _onDone;
+  Function? _onError;
+  void Function(Notification)? _onNotification;
+  void Function(Request)? _onRequest;
 
   List<Notification> sentNotifications = <Notification>[];
 
@@ -56,10 +56,10 @@
   }
 
   @override
-  void listen(void Function(Request request) onRequest,
-      {void Function() onDone,
-      Function onError,
-      Function(Notification) onNotification}) {
+  void listen(void Function(Request request)? onRequest,
+      {void Function()? onDone,
+      Function? onError,
+      Function(Notification)? onNotification}) {
     _onDone = onDone;
     _onError = onError;
     _onNotification = onNotification;
@@ -67,11 +67,15 @@
   }
 
   void sendDone() {
-    _onDone();
+    if (_onDone != null) {
+      _onDone!();
+    }
   }
 
   void sendError(Object exception, StackTrace stackTrace) {
-    _onError(exception, stackTrace);
+    if (_onError != null) {
+      _onError!(exception, stackTrace);
+    }
   }
 
   @override
@@ -82,7 +86,7 @@
     if (_onNotification == null) {
       fail('Unexpected invocation of sendNotification');
     }
-    _onNotification(notification);
+    _onNotification!(notification);
   }
 
   Future<Response> sendRequest(RequestParams params) {
@@ -93,7 +97,7 @@
     var request = params.toRequest(id);
     var completer = Completer<Response>();
     completers[request.id] = completer;
-    _onRequest(request);
+    _onRequest!(request);
     return completer.future;
   }
 
@@ -103,7 +107,7 @@
       throw StateError('Sent a response to a closed channel');
     }
     var completer = completers.remove(response.id);
-    completer.complete(response);
+    completer?.complete(response);
   }
 }
 
@@ -117,7 +121,11 @@
   @override
   final String path;
 
-  MockResolvedUnitResult({this.errors, this.lineInfo, this.path});
+  MockResolvedUnitResult(
+      {List<AnalysisError>? errors, LineInfo? lineInfo, String? path})
+      : errors = errors ?? [],
+        lineInfo = lineInfo ?? LineInfo([0]),
+        path = path ?? '';
 
   @override
   dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
@@ -149,10 +157,10 @@
 
 class MockSource implements Source {
   @override
-  TimestampedData<String> get contents => null;
+  TimestampedData<String> get contents => TimestampedData(0, '');
 
   @override
-  String get encoding => null;
+  String get encoding => '';
 
   @override
   String get fullName => '/pkg/lib/test.dart';
diff --git a/pkg/analyzer_plugin/test/plugin/navigation_mixin_test.dart b/pkg/analyzer_plugin/test/plugin/navigation_mixin_test.dart
index 9763b14..2c3dcfd 100644
--- a/pkg/analyzer_plugin/test/plugin/navigation_mixin_test.dart
+++ b/pkg/analyzer_plugin/test/plugin/navigation_mixin_test.dart
@@ -23,12 +23,12 @@
 
 @reflectiveTest
 class NavigationMixinTest with ResourceProviderMixin {
-  String packagePath1;
-  String filePath1;
-  ContextRoot contextRoot1;
+  late String packagePath1;
+  late String filePath1;
+  late ContextRoot contextRoot1;
 
-  MockChannel channel;
-  _TestServerPlugin plugin;
+  late MockChannel channel;
+  late _TestServerPlugin plugin;
 
   void setUp() {
     packagePath1 = convertPath('/package1');
@@ -80,7 +80,8 @@
   void computeNavigation(
       NavigationRequest request, NavigationCollector collector) {
     for (var i = 0; i < regionCount; i++) {
-      collector.addRegion(i, 5, ElementKind.METHOD, Location('a', 5, 5, 1, 5));
+      collector.addRegion(
+          i, 5, ElementKind.METHOD, Location('a', 5, 5, 1, 5, 1, 10));
     }
   }
 }
diff --git a/pkg/analyzer_plugin/test/plugin/occurrences_mixin_test.dart b/pkg/analyzer_plugin/test/plugin/occurrences_mixin_test.dart
index e0159c1..319e1bd 100644
--- a/pkg/analyzer_plugin/test/plugin/occurrences_mixin_test.dart
+++ b/pkg/analyzer_plugin/test/plugin/occurrences_mixin_test.dart
@@ -23,12 +23,12 @@
 
 @reflectiveTest
 class OccurrencesMixinTest with ResourceProviderMixin {
-  String packagePath1;
-  String filePath1;
-  ContextRoot contextRoot1;
+  late String packagePath1;
+  late String filePath1;
+  late ContextRoot contextRoot1;
 
-  MockChannel channel;
-  _TestServerPlugin plugin;
+  late MockChannel channel;
+  late _TestServerPlugin plugin;
 
   void setUp() {
     packagePath1 = convertPath('/package1');
diff --git a/pkg/analyzer_plugin/test/plugin/outline_mixin_test.dart b/pkg/analyzer_plugin/test/plugin/outline_mixin_test.dart
index f3510165..5844fde 100644
--- a/pkg/analyzer_plugin/test/plugin/outline_mixin_test.dart
+++ b/pkg/analyzer_plugin/test/plugin/outline_mixin_test.dart
@@ -23,12 +23,12 @@
 
 @reflectiveTest
 class OutlineMixinTest with ResourceProviderMixin {
-  String packagePath1;
-  String filePath1;
-  ContextRoot contextRoot1;
+  late String packagePath1;
+  late String filePath1;
+  late ContextRoot contextRoot1;
 
-  MockChannel channel;
-  _TestServerPlugin plugin;
+  late MockChannel channel;
+  late _TestServerPlugin plugin;
 
   void setUp() {
     packagePath1 = convertPath('/package1');
diff --git a/pkg/analyzer_plugin/test/plugin/plugin_test.dart b/pkg/analyzer_plugin/test/plugin/plugin_test.dart
index 92d227b..18d77ba 100644
--- a/pkg/analyzer_plugin/test/plugin/plugin_test.dart
+++ b/pkg/analyzer_plugin/test/plugin/plugin_test.dart
@@ -19,16 +19,16 @@
 
 @reflectiveTest
 class ServerPluginTest with ResourceProviderMixin {
-  MockChannel channel;
-  _TestServerPlugin plugin;
+  late MockChannel channel;
+  late _TestServerPlugin plugin;
 
-  String packagePath1;
-  String filePath1;
-  ContextRoot contextRoot1;
+  late String packagePath1;
+  late String filePath1;
+  late ContextRoot contextRoot1;
 
-  String packagePath2;
-  String filePath2;
-  ContextRoot contextRoot2;
+  late String packagePath2;
+  late String filePath2;
+  late ContextRoot contextRoot2;
 
   void setUp() {
     packagePath1 = convertPath('/package1');
@@ -363,12 +363,12 @@
       var notifiedServices = notifications[path];
       expect(notifiedServices, isNotNull,
           reason: 'Not notified for file $path');
-      expect(notifiedServices, unorderedEquals(subscribedServices),
+      expect(notifiedServices, unorderedEquals(subscribedServices!),
           reason: 'Wrong notifications for file $path');
     }
   }
 
-  AnalysisDriverGeneric _getDriver(ContextRoot targetRoot) {
+  AnalysisDriverGeneric? _getDriver(ContextRoot targetRoot) {
     for (var root in plugin.driverMap.keys) {
       if (root.root == targetRoot.root) {
         return plugin.driverMap[root];
diff --git a/pkg/analyzer_plugin/test/src/channel/isolate_channel_test.dart b/pkg/analyzer_plugin/test/src/channel/isolate_channel_test.dart
index 05b5876..d4399d9 100644
--- a/pkg/analyzer_plugin/test/src/channel/isolate_channel_test.dart
+++ b/pkg/analyzer_plugin/test/src/channel/isolate_channel_test.dart
@@ -16,8 +16,8 @@
 
 @reflectiveTest
 class PluginIsolateChannelTest {
-  TestSendPort sendPort;
-  PluginIsolateChannel channel;
+  late TestSendPort sendPort;
+  late PluginIsolateChannel channel;
 
   void setUp() {
     sendPort = TestSendPort();
@@ -50,11 +50,11 @@
 
   Future<void> test_listen() async {
     var sentRequest = PluginShutdownParams().toRequest('5');
-    Request receivedRequest;
+    Request? receivedRequest;
     channel.listen((Request request) {
       receivedRequest = request;
     });
-    sendPort.receivePort.send(sentRequest.toJson());
+    sendPort.receivePort?.send(sentRequest.toJson());
     await _pumpEventQueue(1);
     expect(receivedRequest, sentRequest);
   }
@@ -89,7 +89,7 @@
 /// A send port used in tests.
 class TestSendPort implements SendPort {
   /// The receive port used to receive messages from the server.
-  SendPort receivePort;
+  SendPort? receivePort;
 
   /// The messages sent to the server.
   List<Object> sentMessages = <Object>[];
@@ -103,7 +103,7 @@
         fail('Did not receive a receive port as the first communication.');
       }
     } else {
-      sentMessages.add(message);
+      sentMessages.add(message!);
     }
   }
 }
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 0e27f7f..4d1c17e 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
@@ -10,6 +10,8 @@
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
+import 'mocks.dart';
+
 void main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(ChangeBuilderImplTest);
@@ -22,7 +24,7 @@
 @reflectiveTest
 class ChangeBuilderImplTest {
   void test_copy_empty() {
-    var builder = ChangeBuilderImpl();
+    var builder = ChangeBuilderImpl(session: MockAnalysisSession());
     var copy = builder.copy() as ChangeBuilderImpl;
     expect(identical(copy, builder), isFalse);
     expect(copy.workspace, builder.workspace);
@@ -30,7 +32,7 @@
   }
 
   Future<void> test_copy_newEdit() async {
-    var builder = ChangeBuilderImpl();
+    var builder = ChangeBuilderImpl(session: MockAnalysisSession());
     await builder.addGenericFileEdit('/test.dart', (builder) {
       builder.addSimpleInsertion(0, 'x');
     });
@@ -43,7 +45,7 @@
   }
 
   Future<void> test_copy_newFile() async {
-    var builder = ChangeBuilderImpl();
+    var builder = ChangeBuilderImpl(session: MockAnalysisSession());
     await builder.addGenericFileEdit('/test1.dart', (builder) {
       builder.addSimpleInsertion(0, 'x');
     });
@@ -56,7 +58,7 @@
   }
 
   Future<void> test_copy_newLinkedEditGroup() async {
-    var builder = ChangeBuilderImpl();
+    var builder = ChangeBuilderImpl(session: MockAnalysisSession());
     await builder.addGenericFileEdit('/test.dart', (builder) {
       builder.addLinkedPosition(SourceRange(1, 2), 'a');
     });
@@ -69,7 +71,7 @@
   }
 
   Future<void> test_copy_newLinkedPosition() async {
-    var builder = ChangeBuilderImpl();
+    var builder = ChangeBuilderImpl(session: MockAnalysisSession());
     await builder.addGenericFileEdit('/test.dart', (builder) {
       builder.addLinkedPosition(SourceRange(1, 2), 'a');
     });
@@ -82,25 +84,16 @@
   }
 
   Future<void> test_copy_selection() async {
-    var builder = ChangeBuilderImpl();
+    var builder = ChangeBuilderImpl(session: MockAnalysisSession());
     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';
-    var fileEditBuilder = await builder.createGenericFileEditBuilder(path);
-    expect(fileEditBuilder, const TypeMatcher<FileEditBuilder>());
-    var fileEdit = fileEditBuilder.fileEdit;
-    expect(fileEdit.file, path);
+    expect(change.selection!.offset, 5);
   }
 
   void test_getLinkedEditGroup() {
-    var builder = ChangeBuilderImpl();
+    var builder = ChangeBuilderImpl(session: MockAnalysisSession());
     var group = builder.getLinkedEditGroup('a');
     expect(identical(builder.getLinkedEditGroup('b'), group), isFalse);
     expect(identical(builder.getLinkedEditGroup('a'), group), isTrue);
@@ -108,13 +101,13 @@
 
   void test_setSelection() {
     var position = Position('test.dart', 3);
-    var builder = ChangeBuilderImpl();
+    var builder = ChangeBuilderImpl(session: MockAnalysisSession());
     builder.setSelection(position);
     expect(builder.sourceChange.selection, position);
   }
 
   void test_sourceChange_emptyEdit() async {
-    var builder = ChangeBuilderImpl();
+    var builder = ChangeBuilderImpl(session: MockAnalysisSession());
     var path = '/test.dart';
     await builder.addGenericFileEdit(path, (builder) {});
     var sourceChange = builder.sourceChange;
@@ -126,7 +119,7 @@
   }
 
   void test_sourceChange_noEdits() {
-    var builder = ChangeBuilderImpl();
+    var builder = ChangeBuilderImpl(session: MockAnalysisSession());
     var sourceChange = builder.sourceChange;
     expect(sourceChange, isNotNull);
     expect(sourceChange.edits, isEmpty);
@@ -136,7 +129,7 @@
   }
 
   Future<void> test_sourceChange_oneChange() async {
-    var builder = ChangeBuilderImpl();
+    var builder = ChangeBuilderImpl(session: MockAnalysisSession());
     var path = '/test.dart';
     await builder.addGenericFileEdit(path, (builder) {
       builder.addSimpleInsertion(0, '_');
@@ -156,7 +149,7 @@
   String path = '/test.dart';
 
   Future<void> test_addLinkedEdit() async {
-    var builder = ChangeBuilderImpl();
+    var builder = ChangeBuilderImpl(session: MockAnalysisSession());
     var offset = 10;
     var text = 'content';
     await builder.addGenericFileEdit(path, (builder) {
@@ -181,7 +174,7 @@
   }
 
   Future<void> test_addSimpleLinkedEdit() async {
-    var builder = ChangeBuilderImpl();
+    var builder = ChangeBuilderImpl(session: MockAnalysisSession());
     var offset = 10;
     var text = 'content';
     await builder.addGenericFileEdit(path, (builder) {
@@ -204,7 +197,7 @@
   }
 
   Future<void> test_createLinkedEditBuilder() async {
-    var builder = ChangeBuilderImpl();
+    var builder = ChangeBuilderImpl(session: MockAnalysisSession());
     await builder.addGenericFileEdit(path, (builder) {
       builder.addInsertion(10, (builder) {
         var linkBuilder =
@@ -215,17 +208,17 @@
   }
 
   Future<void> test_selectHere() async {
-    var builder = ChangeBuilderImpl();
+    var builder = ChangeBuilderImpl(session: MockAnalysisSession());
     await builder.addGenericFileEdit(path, (builder) {
       builder.addInsertion(10, (EditBuilder builder) {
         builder.selectHere();
       });
     });
-    expect(builder.sourceChange.selection.offset, 10);
+    expect(builder.sourceChange.selection!.offset, 10);
   }
 
   Future<void> test_write() async {
-    var builder = ChangeBuilderImpl();
+    var builder = ChangeBuilderImpl(session: MockAnalysisSession());
     var offset = 10;
     var text = 'write';
     await builder.addGenericFileEdit(path, (builder) {
@@ -253,7 +246,7 @@
   }
 
   Future<void> test_writeln_withoutText() async {
-    var builder = ChangeBuilderImpl();
+    var builder = ChangeBuilderImpl(session: MockAnalysisSession());
     var offset = 52;
     var length = 12;
     await builder.addGenericFileEdit(path, (builder) {
@@ -281,7 +274,7 @@
   }
 
   Future<void> test_writeln_withText() async {
-    var builder = ChangeBuilderImpl();
+    var builder = ChangeBuilderImpl(session: MockAnalysisSession());
     var offset = 52;
     var length = 12;
     var text = 'writeln';
@@ -318,7 +311,7 @@
   Future<void> test_addDeletion() async {
     var offset = 23;
     var length = 7;
-    var builder = ChangeBuilderImpl();
+    var builder = ChangeBuilderImpl(session: MockAnalysisSession());
     await builder.addGenericFileEdit(path, (builder) {
       builder.addDeletion(SourceRange(offset, length));
     });
@@ -337,7 +330,7 @@
     var firstLength = 7;
     var secondOffset = 30;
     var secondLength = 5;
-    var builder = ChangeBuilderImpl();
+    var builder = ChangeBuilderImpl(session: MockAnalysisSession());
     await builder.addGenericFileEdit(path, (builder) {
       builder.addDeletion(SourceRange(firstOffset, firstLength));
       builder.addDeletion(SourceRange(secondOffset, secondLength));
@@ -360,7 +353,7 @@
     var firstLength = 7;
     var secondOffset = 30;
     var secondLength = 5;
-    var builder = ChangeBuilderImpl();
+    var builder = ChangeBuilderImpl(session: MockAnalysisSession());
     await builder.addGenericFileEdit(path, (builder) {
       builder.addDeletion(SourceRange(secondOffset, secondLength));
       builder.addDeletion(SourceRange(firstOffset, firstLength));
@@ -382,7 +375,7 @@
     var firstLength = 7;
     var secondOffset = 27;
     var secondLength = 8;
-    var builder = ChangeBuilderImpl();
+    var builder = ChangeBuilderImpl(session: MockAnalysisSession());
     await builder.addGenericFileEdit(path, (builder) {
       builder.addDeletion(SourceRange(firstOffset, firstLength));
       builder.addDeletion(SourceRange(secondOffset, secondLength));
@@ -395,7 +388,7 @@
   }
 
   Future<void> test_addInsertion() async {
-    var builder = ChangeBuilderImpl();
+    var builder = ChangeBuilderImpl(session: MockAnalysisSession());
     await builder.addGenericFileEdit(path, (builder) {
       builder.addInsertion(10, (builder) {
         expect(builder, isNotNull);
@@ -404,7 +397,7 @@
   }
 
   Future<void> test_addLinkedPosition() async {
-    var builder = ChangeBuilderImpl();
+    var builder = ChangeBuilderImpl(session: MockAnalysisSession());
     var groupName = 'a';
     await builder.addGenericFileEdit(path, (builder) {
       builder.addLinkedPosition(SourceRange(3, 6), groupName);
@@ -420,7 +413,7 @@
   }
 
   Future<void> test_addReplacement() async {
-    var builder = ChangeBuilderImpl();
+    var builder = ChangeBuilderImpl(session: MockAnalysisSession());
     await builder.addGenericFileEdit(path, (builder) {
       builder.addReplacement(SourceRange(4, 5), (builder) {
         expect(builder, isNotNull);
@@ -431,7 +424,7 @@
   Future<void> test_addSimpleInsertion() async {
     var offset = 23;
     var text = 'xyz';
-    var builder = ChangeBuilderImpl();
+    var builder = ChangeBuilderImpl(session: MockAnalysisSession());
     await builder.addGenericFileEdit(path, (builder) {
       builder.addSimpleInsertion(offset, text);
     });
@@ -445,7 +438,7 @@
   Future<void> test_addSimpleInsertion_sameOffset() async {
     var offset = 23;
     var text = 'xyz';
-    var builder = ChangeBuilderImpl();
+    var builder = ChangeBuilderImpl(session: MockAnalysisSession());
     await builder.addGenericFileEdit(path, (builder) {
       builder.addSimpleInsertion(offset, text);
       builder.addSimpleInsertion(offset, 'abc');
@@ -464,7 +457,7 @@
     var offset = 23;
     var length = 7;
     var text = 'xyz';
-    var builder = ChangeBuilderImpl();
+    var builder = ChangeBuilderImpl(session: MockAnalysisSession());
     await builder.addGenericFileEdit(path, (builder) {
       builder.addSimpleReplacement(SourceRange(offset, length), text);
     });
@@ -481,7 +474,7 @@
     var secondOffset = firstOffset + firstLength;
     var secondLength = 5;
     var text = 'xyz';
-    var builder = ChangeBuilderImpl();
+    var builder = ChangeBuilderImpl(session: MockAnalysisSession());
     await builder.addGenericFileEdit(path, (builder) {
       builder.addSimpleReplacement(SourceRange(firstOffset, firstLength), text);
       builder.addSimpleReplacement(
@@ -501,7 +494,7 @@
     var offset = 23;
     var length = 7;
     var text = 'xyz';
-    var builder = ChangeBuilderImpl();
+    var builder = ChangeBuilderImpl(session: MockAnalysisSession());
     await builder.addGenericFileEdit(path, (builder) {
       builder.addSimpleReplacement(SourceRange(offset, length), text);
       expect(() {
@@ -519,7 +512,7 @@
     var offset = 23;
     var length = 7;
     var text = 'xyz';
-    var builder = ChangeBuilderImpl();
+    var builder = ChangeBuilderImpl(session: MockAnalysisSession());
     await builder.addGenericFileEdit(path, (builder) {
       builder.addSimpleReplacement(SourceRange(offset, length), text);
       expect(() {
@@ -534,7 +527,7 @@
   }
 
   Future<void> test_createEditBuilder() async {
-    var builder = ChangeBuilderImpl();
+    var builder = ChangeBuilderImpl(session: MockAnalysisSession());
     await builder.addGenericFileEdit(path, (builder) {
       var offset = 4;
       var length = 5;
@@ -555,7 +548,7 @@
 
   Future<void> test_addSuggestion() async {
     var groupName = 'a';
-    var builder = ChangeBuilderImpl();
+    var builder = ChangeBuilderImpl(session: MockAnalysisSession());
     await builder.addGenericFileEdit(path, (builder) {
       builder.addInsertion(10, (builder) {
         builder.addLinkedEdit(groupName, (builder) {
@@ -571,7 +564,7 @@
 
   Future<void> test_addSuggestion_zeroLength() async {
     var groupName = 'a';
-    var builder = ChangeBuilderImpl();
+    var builder = ChangeBuilderImpl(session: MockAnalysisSession());
     await builder.addGenericFileEdit(path, (builder) {
       builder.addInsertion(10, (builder) {
         builder.addLinkedEdit(groupName, (builder) {
@@ -585,7 +578,7 @@
 
   Future<void> test_addSuggestions() async {
     var groupName = 'a';
-    var builder = ChangeBuilderImpl();
+    var builder = ChangeBuilderImpl(session: MockAnalysisSession());
     await builder.addGenericFileEdit(path, (builder) {
       builder.addInsertion(10, (builder) {
         builder.addLinkedEdit(groupName, (builder) {
diff --git a/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart b/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart
index 430be10..c1f201f 100644
--- a/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart
+++ b/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart
@@ -18,6 +18,7 @@
 
 import '../../../support/abstract_context.dart';
 import 'dart/dart_change_builder_mixin.dart';
+import 'mocks.dart';
 
 void main() {
   defineReflectiveSuite(() {
@@ -787,9 +788,9 @@
 }
 class MyClass {}''';
     addSource(path, content);
-    var unit = (await resolveFile(path))?.unit;
+    var unit = (await resolveFile(path)).unit;
 
-    var A = unit.declarations[1] as ClassDeclaration;
+    var A = unit?.declarations[1] as ClassDeclaration;
 
     var builder = newBuilder();
     await builder.addDartFileEdit(path, (builder) {
@@ -799,7 +800,7 @@
           initializerWriter: () {
             builder.write('null');
           },
-          type: A.declaredElement.instantiate(
+          type: A.declaredElement?.instantiate(
             typeArguments: [],
             nullabilitySuffix: NullabilitySuffix.star,
           ),
@@ -818,16 +819,16 @@
 }
 class MyClass {}''';
     addSource(path, content);
-    var unit = (await resolveFile(path))?.unit;
+    var unit = (await resolveFile(path)).unit;
 
-    var A = unit.declarations[1] as ClassDeclaration;
+    var A = unit?.declarations[1] as ClassDeclaration;
 
     var builder = newBuilder();
     await builder.addDartFileEdit(path, (builder) {
       builder.addInsertion(11, (builder) {
         builder.writeLocalVariableDeclaration(
           'foo',
-          type: A.declaredElement.instantiate(
+          type: A.declaredElement?.instantiate(
             typeArguments: [],
             nullabilitySuffix: NullabilitySuffix.star,
           ),
@@ -854,9 +855,9 @@
 }
 class MyClass {}''';
     addSource(path, content);
-    var unit = (await resolveFile(path))?.unit;
+    var unit = (await resolveFile(path)).unit;
 
-    var A = unit.declarations[1] as ClassDeclaration;
+    var A = unit?.declarations[1] as ClassDeclaration;
 
     var builder = newBuilder();
     await builder.addDartFileEdit(path, (builder) {
@@ -864,7 +865,7 @@
         builder.writeLocalVariableDeclaration(
           'foo',
           isFinal: true,
-          type: A.declaredElement.instantiate(
+          type: A.declaredElement?.instantiate(
             typeArguments: [],
             nullabilitySuffix: NullabilitySuffix.star,
           ),
@@ -1024,8 +1025,8 @@
 class A {}
 ''';
     addSource(path, content);
-    var unit = (await resolveFile(path))?.unit;
-    var g = unit.declarations[1] as FunctionDeclaration;
+    var unit = (await resolveFile(path)).unit;
+    var g = unit?.declarations[1] as FunctionDeclaration;
     var body = g.functionExpression.body as BlockFunctionBody;
     var statement = body.block.statements[0] as ExpressionStatement;
     var invocation = statement.expression as MethodInvocation;
@@ -1046,15 +1047,15 @@
     var content = 'f(int a, {bool b = false, String c}) {}';
     addSource(path, content);
 
-    var unit = (await resolveFile(path))?.unit;
-    var f = unit.declarations[0] as FunctionDeclaration;
+    var unit = (await resolveFile(path)).unit;
+    var f = unit?.declarations[0] as FunctionDeclaration;
     var parameters = f.functionExpression.parameters;
-    var elements = parameters.parameters.map((p) => p.declaredElement);
+    var elements = parameters?.parameters.map((p) => p.declaredElement!);
 
     var builder = newBuilder();
     await builder.addDartFileEdit(path, (builder) {
       builder.addInsertion(content.length - 1, (builder) {
-        builder.writeParameters(elements);
+        builder.writeParameters(elements!);
       });
     });
     var edit = getEdit(builder);
@@ -1066,15 +1067,15 @@
     var path = convertPath('/home/test/lib/test.dart');
     var content = 'f(int a, [bool b = false, String c]) {}';
     addSource(path, content);
-    var unit = (await resolveFile(path))?.unit;
-    var f = unit.declarations[0] as FunctionDeclaration;
+    var unit = (await resolveFile(path)).unit;
+    var f = unit?.declarations[0] as FunctionDeclaration;
     var parameters = f.functionExpression.parameters;
-    var elements = parameters.parameters.map((p) => p.declaredElement);
+    var elements = parameters?.parameters.map((p) => p.declaredElement!);
 
     var builder = newBuilder();
     await builder.addDartFileEdit(path, (builder) {
       builder.addInsertion(content.length - 1, (builder) {
-        builder.writeParameters(elements);
+        builder.writeParameters(elements!);
       });
     });
     var edit = getEdit(builder);
@@ -1086,15 +1087,15 @@
     var path = convertPath('/home/test/lib/test.dart');
     var content = 'f(int i, String s) {}';
     addSource(path, content);
-    var unit = (await resolveFile(path))?.unit;
-    var f = unit.declarations[0] as FunctionDeclaration;
+    var unit = (await resolveFile(path)).unit;
+    var f = unit?.declarations[0] as FunctionDeclaration;
     var parameters = f.functionExpression.parameters;
-    var elements = parameters.parameters.map((p) => p.declaredElement);
+    var elements = parameters?.parameters.map((p) => p.declaredElement!);
 
     var builder = newBuilder();
     await builder.addDartFileEdit(path, (builder) {
       builder.addInsertion(content.length - 1, (builder) {
-        builder.writeParameters(elements);
+        builder.writeParameters(elements!);
       });
     });
     var edit = getEdit(builder);
@@ -1108,8 +1109,8 @@
   g(s, index: i);
 }''';
     addSource(path, content);
-    var unit = (await resolveFile(path))?.unit;
-    var f = unit.declarations[0] as FunctionDeclaration;
+    var unit = (await resolveFile(path)).unit;
+    var f = unit?.declarations[0] as FunctionDeclaration;
     var body = f.functionExpression.body as BlockFunctionBody;
     var statement = body.block.statements[0] as ExpressionStatement;
     var invocation = statement.expression as MethodInvocation;
@@ -1131,8 +1132,8 @@
   g(s, i);
 }''';
     addSource(path, content);
-    var unit = (await resolveFile(path))?.unit;
-    var f = unit.declarations[0] as FunctionDeclaration;
+    var unit = (await resolveFile(path)).unit;
+    var f = unit?.declarations[0] as FunctionDeclaration;
     var body = f.functionExpression.body as BlockFunctionBody;
     var statement = body.block.statements[0] as ExpressionStatement;
     var invocation = statement.expression as MethodInvocation;
@@ -1324,12 +1325,12 @@
     var path = convertPath('/home/test/lib/test.dart');
     var content = 'class A {}';
     addSource(path, content);
-    var unit = (await resolveFile(path))?.unit;
+    var unit = (await resolveFile(path)).unit;
 
     var builder = newBuilder();
     await builder.addDartFileEdit(path, (builder) {
       builder.addInsertion(content.length - 1, (builder) {
-        var typeProvider = unit.declaredElement.library.typeProvider;
+        var typeProvider = unit!.declaredElement!.library.typeProvider;
         builder.writeType(typeProvider.dynamicType);
       });
     });
@@ -1537,12 +1538,12 @@
     var path = convertPath('/home/test/lib/test.dart');
     var content = 'class A {}';
     addSource(path, content);
-    var unit = (await resolveFile(path))?.unit;
+    var unit = (await resolveFile(path)).unit;
 
     var builder = newBuilder();
     await builder.addDartFileEdit(path, (builder) {
       builder.addInsertion(content.length - 1, (builder) {
-        var typeProvider = unit.declaredElement.library.typeProvider;
+        var typeProvider = unit!.declaredElement!.library.typeProvider;
         builder.writeType(typeProvider.dynamicType, required: true);
       });
     });
@@ -1670,7 +1671,7 @@
     expect(edit.replacement, equalsIgnoringWhitespace('implements A, B'));
   }
 
-  Future<void> _assertWriteType(String typeCode, {String declarations}) async {
+  Future<void> _assertWriteType(String typeCode, {String? declarations}) async {
     var path = convertPath('/home/test/lib/test.dart');
     var content = (declarations ?? '') + '$typeCode v;';
     addSource(path, content);
@@ -1688,14 +1689,14 @@
   }
 
   Future<ClassElement> _getClassElement(String path, String name) async {
-    var result = (await resolveFile(path))?.unit;
-    return result.declaredElement.getType(name);
+    var result = (await resolveFile(path)).unit;
+    return result!.declaredElement!.getType(name)!;
   }
 
   Future<PropertyAccessorElement> _getTopLevelAccessorElement(
       String path, String name) async {
-    var result = (await resolveFile(path))?.unit;
-    return result.declaredElement.accessors.firstWhere((v) => v.name == name);
+    var result = (await resolveFile(path)).unit;
+    return result!.declaredElement!.accessors.firstWhere((v) => v.name == name);
   }
 
   Future<InterfaceType> _getType(
@@ -1719,7 +1720,7 @@
     addSource(path, '''var f = () {}''');
 
     var resolvedUnit = await resolveFile(path);
-    var findNode = FindNode(resolvedUnit.content, resolvedUnit.unit);
+    var findNode = FindNode(resolvedUnit.content!, resolvedUnit.unit!);
     var body = findNode.functionBody('{}');
 
     var builder = newBuilder();
@@ -1736,7 +1737,7 @@
     addSource(path, 'String f() {}');
 
     var resolvedUnit = await resolveFile(path);
-    var findNode = FindNode(resolvedUnit.content, resolvedUnit.unit);
+    var findNode = FindNode(resolvedUnit.content!, resolvedUnit.unit!);
     var body = findNode.functionBody('{}');
 
     var builder = newBuilder();
@@ -1849,7 +1850,7 @@
     addSource(path, 'String f() {}');
 
     var resolvedUnit = await resolveFile(path);
-    var findNode = FindNode(resolvedUnit.content, resolvedUnit.unit);
+    var findNode = FindNode(resolvedUnit.content!, resolvedUnit.unit!);
     var type = findNode.typeAnnotation('String');
 
     var builder = newBuilder();
@@ -1871,11 +1872,11 @@
 class B extends A {}
 class C extends B {}
 ''');
-    var unit = (await resolveFile(path))?.unit;
-    var classC = unit.declarations[2] as ClassDeclaration;
-    var builder = DartLinkedEditBuilderImpl(null);
+    var unit = (await resolveFile(path)).unit;
+    var classC = unit?.declarations[2] as ClassDeclaration;
+    var builder = DartLinkedEditBuilderImpl(MockEditBuilderImpl());
     builder.addSuperTypesAsSuggestions(
-      classC.declaredElement.instantiate(
+      classC.declaredElement?.instantiate(
         typeArguments: [],
         nullabilitySuffix: NullabilitySuffix.star,
       ),
@@ -2328,9 +2329,9 @@
   }
 
   Future<void> _assertImportLibrary({
-    String initialCode,
-    List<String> uriList,
-    String expectedCode,
+    required String initialCode,
+    required List<String> uriList,
+    required String expectedCode,
   }) async {
     var path = convertPath('/home/test/lib/test.dart');
     addSource(path, initialCode);
@@ -2878,26 +2879,26 @@
   /// given [displayText]. If a [selection] is provided, assert that the
   /// generated selection range matches it.
   Future<void> _assertWriteOverride({
-    String content,
-    String nameToOverride,
-    String expected,
-    String displayText,
-    SourceRange selection,
+    required String content,
+    required String nameToOverride,
+    required String expected,
+    String? displayText,
+    SourceRange? selection,
     String targetClassName = 'B',
-    String targetMixinName,
+    String? targetMixinName,
     bool invokeSuper = false,
   }) async {
     var path = convertPath('/home/test/lib/test.dart');
     addSource(path, content);
 
-    ClassElement targetElement;
+    ClassElement? targetElement;
     {
-      var unitResult = (await resolveFile(path))?.unit;
+      var unitResult = (await resolveFile(path)).unit;
       if (targetMixinName != null) {
-        targetElement = unitResult.declaredElement.mixins
+        targetElement = unitResult!.declaredElement!.mixins
             .firstWhere((e) => e.name == targetMixinName);
       } else {
-        targetElement = unitResult.declaredElement.types
+        targetElement = unitResult!.declaredElement!.types
             .firstWhere((e) => e.name == targetClassName);
       }
     }
@@ -2913,7 +2914,7 @@
     await builder.addDartFileEdit(path, (builder) {
       builder.addInsertion(content.length - 2, (builder) {
         builder.writeOverride(
-          inherited,
+          inherited!,
           displayTextBuffer: displayBuffer,
           invokeSuper: invokeSuper,
         );
diff --git a/pkg/analyzer_plugin/test/src/utilities/change_builder/dart/import_library_element_test.dart b/pkg/analyzer_plugin/test/src/utilities/change_builder/dart/import_library_element_test.dart
index 341d53a..84f4e90 100644
--- a/pkg/analyzer_plugin/test/src/utilities/change_builder/dart/import_library_element_test.dart
+++ b/pkg/analyzer_plugin/test/src/utilities/change_builder/dart/import_library_element_test.dart
@@ -451,11 +451,11 @@
   }
 
   Future<void> _assertImportLibraryElement(
-      {String initialCode,
-      String uriStr,
-      String name,
-      String expectedPrefix,
-      String expectedCode}) async {
+      {required String initialCode,
+      required String uriStr,
+      required String name,
+      String? expectedPrefix,
+      String? expectedCode}) async {
     var offset = initialCode.indexOf('^');
     if (offset > 0) {
       initialCode =
diff --git a/pkg/analyzer_plugin/test/src/utilities/change_builder/mocks.dart b/pkg/analyzer_plugin/test/src/utilities/change_builder/mocks.dart
new file mode 100644
index 0000000..5d31e68
--- /dev/null
+++ b/pkg/analyzer_plugin/test/src/utilities/change_builder/mocks.dart
@@ -0,0 +1,16 @@
+import 'package:analyzer/dart/analysis/session.dart';
+import 'package:analyzer_plugin/src/utilities/change_builder/change_builder_core.dart';
+
+class MockAnalysisSession implements AnalysisSession {
+  @override
+  dynamic noSuchMethod(Invocation invocation) {
+    return super.noSuchMethod(invocation);
+  }
+}
+
+class MockEditBuilderImpl implements EditBuilderImpl {
+  @override
+  dynamic noSuchMethod(Invocation invocation) {
+    return super.noSuchMethod(invocation);
+  }
+}
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 7a0c3d4..71b649d 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
@@ -531,7 +531,7 @@
       zoo(z) { } String name;''');
     assertTarget('/// some dartdoc ', '');
     expect(target.containingNode is Comment, isTrue);
-    expect(target.containingNode.parent.toSource(), 'zoo(z) {}');
+    expect(target.containingNode.parent!.toSource(), 'zoo(z) {}');
   }
 
   Future<void> test_FunctionDeclaration_inLineDocComment2() async {
@@ -541,7 +541,7 @@
       zoo(z) { } String name;''');
     assertTarget('/// some dartdoc', '');
     expect(target.containingNode is Comment, isTrue);
-    expect(target.containingNode.parent.toSource(), 'zoo(z) {}');
+    expect(target.containingNode.parent!.toSource(), 'zoo(z) {}');
   }
 
   Future<void> test_FunctionDeclaration_inStarComment() async {
@@ -561,7 +561,7 @@
     await createTarget('/** ^ */ zoo(z) { } String name;');
     assertTarget('/**  */', '');
     expect(target.containingNode is Comment, isTrue);
-    expect(target.containingNode.parent.toSource(), 'zoo(z) {}');
+    expect(target.containingNode.parent!.toSource(), 'zoo(z) {}');
   }
 
   Future<void> test_FunctionDeclaration_inStarDocComment2() async {
@@ -569,7 +569,7 @@
     await createTarget('/**  *^/ zoo(z) { } String name;');
     assertTarget('/**  */', '');
     expect(target.containingNode is Comment, isTrue);
-    expect(target.containingNode.parent.toSource(), 'zoo(z) {}');
+    expect(target.containingNode.parent!.toSource(), 'zoo(z) {}');
   }
 
   Future<void> test_FunctionDeclaration_returnType() async {
@@ -726,7 +726,7 @@
         zoo(z) { } String name; }''');
     assertTarget('/// some dartdoc ', '');
     expect(target.containingNode is Comment, isTrue);
-    expect(target.containingNode.parent.toSource(), 'zoo(z) {}');
+    expect(target.containingNode.parent!.toSource(), 'zoo(z) {}');
   }
 
   Future<void> test_MethodDeclaration_inLineDocComment2() async {
@@ -737,7 +737,7 @@
         zoo(z) { } String name; }''');
     assertTarget('/// some dartdoc', '');
     expect(target.containingNode is Comment, isTrue);
-    expect(target.containingNode.parent.toSource(), 'zoo(z) {}');
+    expect(target.containingNode.parent!.toSource(), 'zoo(z) {}');
   }
 
   Future<void> test_MethodDeclaration_inStarComment() async {
@@ -757,7 +757,7 @@
     await createTarget('class C2 {/** ^ */ zoo(z) { } String name; }');
     assertTarget('/**  */', '');
     expect(target.containingNode is Comment, isTrue);
-    expect(target.containingNode.parent.toSource(), 'zoo(z) {}');
+    expect(target.containingNode.parent!.toSource(), 'zoo(z) {}');
   }
 
   Future<void> test_MethodDeclaration_inStarDocComment2() async {
@@ -765,7 +765,7 @@
     await createTarget('class C2 {/**  *^/ zoo(z) { } String name; }');
     assertTarget('/**  */', '');
     expect(target.containingNode is Comment, isTrue);
-    expect(target.containingNode.parent.toSource(), 'zoo(z) {}');
+    expect(target.containingNode.parent!.toSource(), 'zoo(z) {}');
   }
 
   Future<void> test_MethodDeclaration_returnType() async {
@@ -885,18 +885,18 @@
 }
 
 class _Base extends AbstractContextTest {
-  int offset;
-  CompletionTarget target;
-  FindElement findElement;
+  int? offset;
+  late CompletionTarget target;
+  late FindElement findElement;
 
   void assertTarget(
     String entityText,
     String nodeText, {
-    int argIndex,
-    String droppedToken,
+    int? argIndex,
+    String? droppedToken,
     bool isFunctionalArgument = false,
-    String expectedExecutable,
-    String expectedParameter,
+    String? expectedExecutable,
+    String? expectedParameter,
   }) {
     expect(
       target.entity.toString(),
@@ -926,14 +926,14 @@
     if (expectedExecutable == null) {
       expect(actualExecutable, isNull);
     } else {
-      expect(_executableStr(actualExecutable), expectedExecutable);
+      expect(_executableStr(actualExecutable!), expectedExecutable);
     }
 
     var actualParameter = target.parameterElement;
     if (expectedParameter == null) {
       expect(actualParameter, isNull);
     } else {
-      expect(_parameterStr(actualParameter), expectedParameter);
+      expect(_parameterStr(actualParameter!), expectedParameter);
     }
 
     expect(target.isFunctionalArgument(), isFunctionalArgument);
@@ -945,18 +945,18 @@
     offset = content.indexOf('^');
     expect(offset, isNot(equals(-1)), reason: 'missing ^');
 
-    var nextOffset = content.indexOf('^', offset + 1);
+    var nextOffset = content.indexOf('^', offset! + 1);
     expect(nextOffset, equals(-1), reason: 'too many ^');
 
-    content = content.substring(0, offset) + content.substring(offset + 1);
+    content = content.substring(0, offset) + content.substring(offset! + 1);
 
     var path = convertPath('/home/test/lib/test.dart');
     newFile(path, content: content);
 
     var result = await resolveFile(path);
-    findElement = FindElement(result.unit);
+    findElement = FindElement(result.unit!);
 
-    target = CompletionTarget.forOffset(result.unit, offset);
+    target = CompletionTarget.forOffset(result.unit!, offset!);
   }
 
   static String _executableNameStr(ExecutableElement executable) {
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 57a6f59..66c0b73 100644
--- a/pkg/analyzer_plugin/test/src/utilities/completion/optype_test.dart
+++ b/pkg/analyzer_plugin/test/src/utilities/completion/optype_test.dart
@@ -18,8 +18,8 @@
 
 /// Common test methods to Dart1/Dart2 versions of OpType tests.
 abstract class AbstractOpTypeTest extends AbstractContextTest {
-  String testPath;
-  int completionOffset;
+  late String testPath;
+  late int completionOffset;
 
   void addTestSource(String content) {
     completionOffset = content.indexOf('^');
@@ -33,7 +33,7 @@
 
   Future<void> assertOpType(
       {bool caseLabel = false,
-      String completionLocation,
+      String? completionLocation,
       bool constructors = false,
       bool namedArgs = false,
       bool prefixed = false,
@@ -50,7 +50,7 @@
     //
     var resolvedUnit = await resolveFile(testPath);
     var completionTarget =
-        CompletionTarget.forOffset(resolvedUnit.unit, completionOffset);
+        CompletionTarget.forOffset(resolvedUnit.unit!, completionOffset);
     var opType = OpType.forCompletion(completionTarget, completionOffset);
     //
     // Validate the OpType.
diff --git a/pkg/analyzer_plugin/test/src/utilities/navigation/navigation_test.dart b/pkg/analyzer_plugin/test/src/utilities/navigation/navigation_test.dart
index de76c3c..45179b0 100644
--- a/pkg/analyzer_plugin/test/src/utilities/navigation/navigation_test.dart
+++ b/pkg/analyzer_plugin/test/src/utilities/navigation/navigation_test.dart
@@ -24,14 +24,14 @@
     var targetStartColumnA1 = 4;
     var targetKindA1 = ElementKind.CLASS;
     var targetLocationA1 = Location(fileA, targetOffsetA1, targetLengthA1,
-        targetStartLineA1, targetStartColumnA1);
+        targetStartLineA1, targetStartColumnA1, 0, 0);
     var targetOffsetA2 = 5;
     var targetLengthA2 = 6;
     var targetStartLineA2 = 7;
     var targetStartColumnA2 = 8;
     var targetKindA2 = ElementKind.FUNCTION;
     var targetLocationA2 = Location(fileA, targetOffsetA2, targetLengthA2,
-        targetStartLineA2, targetStartColumnA2);
+        targetStartLineA2, targetStartColumnA2, 0, 0);
 
     var fileB = 'b.dart';
     var targetOffsetB1 = 9;
@@ -40,14 +40,14 @@
     var targetStartColumnB1 = 12;
     var targetKindB1 = ElementKind.ENUM;
     var targetLocationB1 = Location(fileB, targetOffsetB1, targetLengthB1,
-        targetStartLineB1, targetStartColumnB1);
+        targetStartLineB1, targetStartColumnB1, 0, 0);
     var targetOffsetB2 = 13;
     var targetLengthB2 = 14;
     var targetStartLineB2 = 15;
     var targetStartColumnB2 = 16;
     var targetKindB2 = ElementKind.METHOD;
     var targetLocationB2 = Location(fileB, targetOffsetB2, targetLengthB2,
-        targetStartLineB2, targetStartColumnB2);
+        targetStartLineB2, targetStartColumnB2, 0, 0);
 
     // Six regions targeting a1, b1, a2, b1, a1, b2
     var regionOffsets = <int>[17, 18, 19, 20, 21, 22];
@@ -112,7 +112,7 @@
     var targetStartLine = 5;
     var targetStartColumn = 1;
     var targetLocation = Location(targetFile, targetOffset, targetLength,
-        targetStartLine, targetStartColumn);
+        targetStartLine, targetStartColumn, 0, 0);
     collector.addRegion(regionOffset, regionLength, targetKind, targetLocation);
     collector.createRegions();
     expect(collector.files, [targetFile]);
diff --git a/pkg/analyzer_plugin/test/src/utilities/visitors/local_declaration_visitor_test.dart b/pkg/analyzer_plugin/test/src/utilities/visitors/local_declaration_visitor_test.dart
index bf85a20..f06dbb2 100644
--- a/pkg/analyzer_plugin/test/src/utilities/visitors/local_declaration_visitor_test.dart
+++ b/pkg/analyzer_plugin/test/src/utilities/visitors/local_declaration_visitor_test.dart
@@ -42,7 +42,7 @@
   TestVisitor(int offset) : super(offset);
 
   @override
-  void declaredLocalVar(SimpleIdentifier name, TypeAnnotation type) {
+  void declaredLocalVar(SimpleIdentifier name, TypeAnnotation? type) {
     expect(name, isNotNull);
   }
 }
diff --git a/pkg/analyzer_plugin/test/support/abstract_context.dart b/pkg/analyzer_plugin/test/support/abstract_context.dart
index d9f4ca7..e0776c3 100644
--- a/pkg/analyzer_plugin/test/support/abstract_context.dart
+++ b/pkg/analyzer_plugin/test/support/abstract_context.dart
@@ -19,8 +19,8 @@
 import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
 
 /// Finds an [Element] with the given [name].
-Element findChildElement(Element root, String name, [ElementKind kind]) {
-  Element result;
+Element? findChildElement(Element root, String name, [ElementKind? kind]) {
+  Element? result;
   root.accept(_ElementVisitorFunctionWrapper((Element element) {
     if (element.name != name) {
       return;
@@ -41,7 +41,7 @@
 
   final Map<String, String> _declaredVariables = {};
 
-  AnalysisContextCollection _analysisContextCollection;
+  AnalysisContextCollection? _analysisContextCollection;
 
   List<String> get collectionIncludedPaths => [workspaceRootPath];
 
@@ -51,7 +51,7 @@
   String get testPackageAnalysisOptionsPath =>
       convertPath('$testPackageRootPath/analysis_options.yaml');
 
-  String get testPackageLanguageVersion => '2.9';
+  String? get testPackageLanguageVersion => '2.9';
 
   /// The file system-specific `pubspec.yaml` path.
   String get testPackagePubspecPath =>
@@ -69,11 +69,11 @@
     _createAnalysisContexts();
 
     path = convertPath(path);
-    return _analysisContextCollection.contextFor(path);
+    return _analysisContextCollection!.contextFor(path);
   }
 
   /// Create an analysis options file based on the given arguments.
-  void createAnalysisOptionsFile({List<String> experiments}) {
+  void createAnalysisOptionsFile({List<String>? experiments}) {
     var buffer = StringBuffer();
     buffer.writeln('analyzer:');
 
@@ -116,8 +116,8 @@
   }
 
   void writeTestPackageConfig({
-    PackageConfigFileBuilder config,
-    String languageVersion,
+    PackageConfigFileBuilder? config,
+    String? languageVersion,
     bool meta = false,
   }) {
     if (config == null) {
@@ -163,7 +163,7 @@
 
 mixin WithNonFunctionTypeAliasesMixin on AbstractContextTest {
   @override
-  String get testPackageLanguageVersion => null;
+  String? get testPackageLanguageVersion => null;
 
   @override
   void setUp() {
@@ -179,7 +179,7 @@
 
 mixin WithNullSafetyMixin on AbstractContextTest {
   @override
-  String get testPackageLanguageVersion => null;
+  String? get testPackageLanguageVersion => null;
 }
 
 /// 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 c46632a..afa5699 100644
--- a/pkg/analyzer_plugin/test/support/abstract_single_unit.dart
+++ b/pkg/analyzer_plugin/test/support/abstract_single_unit.dart
@@ -18,11 +18,11 @@
 class AbstractSingleUnitTest extends AbstractContextTest {
   bool verifyNoTestUnitErrors = true;
 
-  String testCode;
-  String testFile;
-  CompilationUnit testUnit;
-  FindNode findNode;
-  FindElement findElement;
+  late String testCode;
+  late String testFile;
+  late CompilationUnit testUnit;
+  late FindNode findNode;
+  late FindElement findElement;
 
   void addTestSource(String code) {
     testCode = code;
@@ -39,7 +39,7 @@
         as SimpleIdentifier;
   }
 
-  AstNode findNodeAtOffset(int offset, [Predicate<AstNode> predicate]) {
+  AstNode? findNodeAtOffset(int offset, [Predicate<AstNode>? predicate]) {
     var result = NodeLocator(offset).searchWithin(testUnit);
     if (result != null && predicate != null) {
       result = result.thisOrAncestorMatching(predicate);
@@ -47,13 +47,13 @@
     return result;
   }
 
-  AstNode findNodeAtString(String search, [Predicate<AstNode> predicate]) {
+  AstNode? findNodeAtString(String search, [Predicate<AstNode>? predicate]) {
     var offset = findOffset(search);
     return findNodeAtOffset(offset, predicate);
   }
 
-  Element findNodeElementAtString(String search,
-      [Predicate<AstNode> predicate]) {
+  Element? findNodeElementAtString(String search,
+      [Predicate<AstNode>? predicate]) {
     var node = findNodeAtString(search, predicate);
     if (node == null) {
       return null;
@@ -95,8 +95,8 @@
 
   Future<void> resolveTestFile() async {
     var result = await resolveFile(testFile);
-    testCode = result.content;
-    testUnit = result.unit;
+    testCode = result.content!;
+    testUnit = result.unit!;
     if (verifyNoTestUnitErrors) {
       expect(result.errors.where((AnalysisError error) {
         return error.errorCode != HintCode.DEAD_CODE &&
diff --git a/pkg/analyzer_plugin/test/utilities/analyzer_converter_test.dart b/pkg/analyzer_plugin/test/utilities/analyzer_converter_test.dart
index 7acc4203..18c6333 100644
--- a/pkg/analyzer_plugin/test/utilities/analyzer_converter_test.dart
+++ b/pkg/analyzer_plugin/test/utilities/analyzer_converter_test.dart
@@ -38,7 +38,7 @@
     expect(element.kind, plugin.ElementKind.METHOD);
     expect(element.name, 'myMethod');
     {
-      var location = element.location;
+      var location = element.location!;
       expect(location.file, testFile);
       expect(location.offset, 32);
       expect(location.length, 'myGetter'.length);
@@ -57,7 +57,7 @@
   /// Assert that the given [pluginError] matches the given [analyzerError].
   void assertError(
       plugin.AnalysisError pluginError, analyzer.AnalysisError analyzerError,
-      {analyzer.ErrorSeverity severity,
+      {analyzer.ErrorSeverity? severity,
       int startColumn = -1,
       int startLine = -1}) {
     var errorCode = analyzerError.errorCode;
@@ -77,7 +77,7 @@
     expect(pluginError.type, converter.convertErrorType(errorCode.type));
   }
 
-  analyzer.AnalysisError createError(int offset, {String contextMessage}) {
+  analyzer.AnalysisError createError(int offset, {String? contextMessage}) {
     var contextMessages = <analyzer.DiagnosticMessageImpl>[];
     if (contextMessage != null) {
       contextMessages.add(analyzer.DiagnosticMessageImpl(
@@ -105,7 +105,7 @@
     assertError(pluginError, analyzerError,
         startColumn: 4, startLine: 2, severity: severity);
     expect(pluginError.contextMessages, hasLength(1));
-    var message = pluginError.contextMessages[0];
+    var message = pluginError.contextMessages![0];
     expect(message.message, 'here');
     expect(message.location.offset, 53);
     expect(message.location.length, 7);
@@ -232,7 +232,7 @@
       expect(element.name, '_A');
       expect(element.typeParameters, isNull);
       {
-        var location = element.location;
+        var location = element.location!;
         expect(location.file, testFile);
         expect(location.offset, 27);
         expect(location.length, '_A'.length);
@@ -269,7 +269,7 @@
     expect(element.name, 'myConstructor');
     expect(element.typeParameters, isNull);
     {
-      var location = element.location;
+      var location = element.location!;
       expect(location.file, testFile);
       expect(location.offset, 20);
       expect(location.length, 'myConstructor'.length);
@@ -307,7 +307,7 @@
       expect(element.name, '_E1');
       expect(element.typeParameters, isNull);
       {
-        var location = element.location;
+        var location = element.location!;
         expect(location.file, testFile);
         expect(location.offset, 17);
         expect(location.length, '_E1'.length);
@@ -343,7 +343,7 @@
       expect(element.kind, plugin.ElementKind.ENUM_CONSTANT);
       expect(element.name, 'one');
       {
-        var location = element.location;
+        var location = element.location!;
         expect(location.file, testFile);
         expect(location.offset, 23);
         expect(location.length, 'one'.length);
@@ -367,7 +367,7 @@
       expect(element.kind, plugin.ElementKind.ENUM_CONSTANT);
       expect(element.name, 'three');
       {
-        var location = element.location;
+        var location = element.location!;
         expect(location.file, testFile);
         expect(location.offset, 44);
         expect(location.length, 'three'.length);
@@ -386,7 +386,7 @@
       expect(element.kind, plugin.ElementKind.FIELD);
       expect(element.name, 'index');
       {
-        var location = element.location;
+        var location = element.location!;
         expect(location.file, testFile);
         expect(location.offset, -1);
         expect(location.length, 'index'.length);
@@ -405,7 +405,7 @@
       expect(element.kind, plugin.ElementKind.FIELD);
       expect(element.name, 'values');
       {
-        var location = element.location;
+        var location = element.location!;
         expect(location.file, testFile);
         expect(location.offset, -1);
         expect(location.length, 'values'.length);
@@ -430,7 +430,7 @@
     expect(element.kind, plugin.ElementKind.FIELD);
     expect(element.name, 'myField');
     {
-      var location = element.location;
+      var location = element.location!;
       expect(location.file, testFile);
       expect(location.offset, 25);
       expect(location.length, 'myField'.length);
@@ -454,7 +454,7 @@
     expect(element.name, 'F');
     expect(element.typeParameters, '<T>');
     {
-      var location = element.location;
+      var location = element.location!;
       expect(location.file, testFile);
       expect(location.offset, 12);
       expect(location.length, 'F'.length);
@@ -477,7 +477,7 @@
     expect(element.kind, plugin.ElementKind.GETTER);
     expect(element.name, 'myGetter');
     {
-      var location = element.location;
+      var location = element.location!;
       expect(location.file, testFile);
       expect(location.offset, 20);
       expect(location.length, 'myGetter'.length);
@@ -503,7 +503,7 @@
     expect(element.kind, plugin.ElementKind.LABEL);
     expect(element.name, 'myLabel');
     {
-      var location = element.location;
+      var location = element.location!;
       expect(location.file, testFile);
       expect(location.offset, 9);
       expect(location.length, 'myLabel'.length);
@@ -528,7 +528,7 @@
     expect(element.kind, plugin.ElementKind.METHOD);
     expect(element.name, 'myMethod');
     {
-      var location = element.location;
+      var location = element.location!;
       expect(location.file, testFile);
       expect(location.offset, 32);
       expect(location.length, 'myGetter'.length);
@@ -551,7 +551,7 @@
     expect(element.kind, plugin.ElementKind.SETTER);
     expect(element.name, 'mySetter');
     {
-      var location = element.location;
+      var location = element.location!;
       expect(location.file, testFile);
       expect(location.offset, 16);
       expect(location.length, 'mySetter'.length);
@@ -574,7 +574,7 @@
     expect(element.name, 'F');
     expect(element.typeParameters, '<T>');
     {
-      var location = element.location;
+      var location = element.location!;
       expect(location.file, testFile);
       expect(location.offset, 8);
       expect(location.length, 'F'.length);
@@ -597,7 +597,7 @@
     expect(element.name, 'A');
     expect(element.typeParameters, '<out T>');
     {
-      var location = element.location;
+      var location = element.location!;
       expect(location.file, testFile);
       expect(location.offset, 8);
       expect(location.length, 'A'.length);
@@ -665,7 +665,7 @@
 
 class _AnalyzerConverterTest extends AbstractSingleUnitTest {
   AnalyzerConverter converter = AnalyzerConverter();
-  analyzer.Source source;
+  late analyzer.Source source;
 
   @override
   void setUp() {
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 2697933..a7899a0 100644
--- a/pkg/analyzer_plugin/test/utilities/completion/completion_contributor_util.dart
+++ b/pkg/analyzer_plugin/test/utilities/completion/completion_contributor_util.dart
@@ -9,6 +9,7 @@
 import 'package:analyzer_plugin/src/utilities/completion/completion_target.dart';
 import 'package:analyzer_plugin/utilities/completion/completion_core.dart';
 import 'package:analyzer_plugin/utilities/completion/relevance.dart';
+import 'package:collection/collection.dart';
 import 'package:test/test.dart';
 
 import '../../support/abstract_context.dart';
@@ -21,13 +22,13 @@
 
 abstract class DartCompletionContributorTest extends AbstractContextTest {
   static const String _UNCHECKED = '__UNCHECKED__';
-  String testFile;
-  int completionOffset;
-  int replacementOffset;
-  int replacementLength;
-  CompletionContributor contributor;
-  DartCompletionRequest request;
-  List<CompletionSuggestion> suggestions;
+  late String testFile;
+  int? completionOffset;
+  int? replacementOffset;
+  int? replacementLength;
+  late CompletionContributor contributor;
+  DartCompletionRequest? request;
+  List<CompletionSuggestion>? suggestions;
 
   /// If `true` and `null` is specified as the suggestion's expected returnType
   /// then the actual suggestion is expected to have a `dynamic` returnType.
@@ -40,10 +41,10 @@
     expect(completionOffset, isNull, reason: 'Call addTestUnit exactly once');
     completionOffset = content.indexOf('^');
     expect(completionOffset, isNot(equals(-1)), reason: 'missing ^');
-    var nextOffset = content.indexOf('^', completionOffset + 1);
+    var nextOffset = content.indexOf('^', completionOffset! + 1);
     expect(nextOffset, equals(-1), reason: 'too many ^');
     content = content.substring(0, completionOffset) +
-        content.substring(completionOffset + 1);
+        content.substring(completionOffset! + 1);
     addSource(testFile, content);
   }
 
@@ -57,31 +58,31 @@
   void assertHasParameterInfo(CompletionSuggestion suggestion) {
     expect(suggestion.parameterNames, isNotNull);
     expect(suggestion.parameterTypes, isNotNull);
-    expect(suggestion.parameterNames.length, suggestion.parameterTypes.length);
+    expect(
+        suggestion.parameterNames!.length, suggestion.parameterTypes!.length);
     expect(suggestion.requiredParameterCount,
-        lessThanOrEqualTo(suggestion.parameterNames.length));
+        lessThanOrEqualTo(suggestion.parameterNames!.length));
     expect(suggestion.hasNamedParameters, isNotNull);
   }
 
-  void assertNoSuggestions({CompletionSuggestionKind kind}) {
+  void assertNoSuggestions({CompletionSuggestionKind? kind}) {
     if (kind == null) {
-      if (suggestions.isNotEmpty) {
+      var suggestions = this.suggestions;
+      if (suggestions != null && suggestions.isNotEmpty) {
         failedCompletion('Expected no suggestions', suggestions);
       }
       return;
     }
-    var suggestion = suggestions.firstWhere(
-        (CompletionSuggestion cs) => cs.kind == kind,
-        orElse: () => null);
+    var suggestion = suggestions
+        ?.firstWhereOrNull((CompletionSuggestion cs) => cs.kind == kind);
     if (suggestion != null) {
       failedCompletion('did not expect completion: $completion\n  $suggestion');
     }
   }
 
   void assertNotSuggested(String completion) {
-    var suggestion = suggestions.firstWhere(
-        (CompletionSuggestion cs) => cs.completion == completion,
-        orElse: () => null);
+    var suggestion = suggestions?.firstWhereOrNull(
+        (CompletionSuggestion cs) => cs.completion == completion);
     if (suggestion != null) {
       failedCompletion('did not expect completion: $completion\n  $suggestion');
     }
@@ -90,22 +91,22 @@
   CompletionSuggestion assertSuggest(String completion,
       {CompletionSuggestionKind csKind = CompletionSuggestionKind.INVOCATION,
       int relevance = DART_RELEVANCE_DEFAULT,
-      ElementKind elemKind,
+      ElementKind? elemKind,
       bool isDeprecated = false,
       bool isPotential = false,
-      String elemFile,
-      int elemOffset,
-      int selectionOffset,
-      String paramName,
-      String paramType,
-      String defaultArgListString = _UNCHECKED,
-      List<int> defaultArgumentListTextRanges}) {
+      String? elemFile,
+      int? elemOffset,
+      int? selectionOffset,
+      String? paramName,
+      String? paramType,
+      String? defaultArgListString = _UNCHECKED,
+      List<int>? defaultArgumentListTextRanges}) {
     var cs =
         getSuggest(completion: completion, csKind: csKind, elemKind: elemKind);
     if (cs == null) {
       failedCompletion('expected $completion $csKind $elemKind', suggestions);
     }
-    expect(cs.kind, equals(csKind));
+    expect(cs!.kind, equals(csKind));
     if (isDeprecated) {
       expect(cs.relevance, equals(DART_RELEVANCE_LOW));
     } else {
@@ -115,19 +116,20 @@
     expect(cs.selectionLength, equals(0));
     expect(cs.isDeprecated, equals(isDeprecated));
     expect(cs.isPotential, equals(isPotential));
-    if (cs.element != null) {
-      expect(cs.element.location, isNotNull);
-      expect(cs.element.location.file, isNotNull);
-      expect(cs.element.location.offset, isNotNull);
-      expect(cs.element.location.length, isNotNull);
-      expect(cs.element.location.startColumn, isNotNull);
-      expect(cs.element.location.startLine, isNotNull);
+    var element = cs.element;
+    if (element != null) {
+      expect(element.location, isNotNull);
+      expect(element.location!.file, isNotNull);
+      expect(element.location!.offset, isNotNull);
+      expect(element.location!.length, isNotNull);
+      expect(element.location!.startColumn, isNotNull);
+      expect(element.location!.startLine, isNotNull);
     }
-    if (elemFile != null) {
-      expect(cs.element.location.file, elemFile);
+    if (element != null && elemFile != null) {
+      expect(element.location!.file, elemFile);
     }
-    if (elemOffset != null) {
-      expect(cs.element.location.offset, elemOffset);
+    if (element != null && elemOffset != null) {
+      expect(element.location!.offset, elemOffset);
     }
     if (paramName != null) {
       expect(cs.parameterName, paramName);
@@ -148,16 +150,16 @@
       {int relevance = DART_RELEVANCE_DEFAULT,
       CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION,
       bool isDeprecated = false,
-      String elemFile,
-      String elemName,
-      int elemOffset}) {
+      String? elemFile,
+      String? elemName,
+      int? elemOffset}) {
     var cs = assertSuggest(name,
         csKind: kind,
         relevance: relevance,
         isDeprecated: isDeprecated,
         elemFile: elemFile,
         elemOffset: elemOffset);
-    var element = cs.element;
+    var element = cs.element!;
     expect(element, isNotNull);
     expect(element.kind, equals(ElementKind.CLASS));
     expect(element.name, equals(elemName ?? name));
@@ -171,7 +173,7 @@
       {int relevance = DART_RELEVANCE_DEFAULT,
       CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION}) {
     var cs = assertSuggest(name, csKind: kind, relevance: relevance);
-    var element = cs.element;
+    var element = cs.element!;
     expect(element, isNotNull);
     expect(element.kind, equals(ElementKind.CLASS_TYPE_ALIAS));
     expect(element.name, equals(name));
@@ -183,9 +185,9 @@
 
   CompletionSuggestion assertSuggestConstructor(String name,
       {int relevance = DART_RELEVANCE_DEFAULT,
-      int elemOffset,
+      int? elemOffset,
       String defaultArgListString = _UNCHECKED,
-      List<int> defaultArgumentListTextRanges}) {
+      List<int>? defaultArgumentListTextRanges}) {
     var cs = assertSuggest(name,
         relevance: relevance,
         elemOffset: elemOffset,
@@ -193,7 +195,7 @@
         defaultArgumentListTextRanges: defaultArgumentListTextRanges);
     var element = cs.element;
     expect(element, isNotNull);
-    expect(element.kind, equals(ElementKind.CONSTRUCTOR));
+    expect(element!.kind, equals(ElementKind.CONSTRUCTOR));
     var index = name.indexOf('.');
     expect(element.name, index >= 0 ? name.substring(index + 1) : '');
     return cs;
@@ -203,7 +205,7 @@
       {bool isDeprecated = false}) {
     var suggestion = assertSuggest(completion, isDeprecated: isDeprecated);
     expect(suggestion.isDeprecated, isDeprecated);
-    expect(suggestion.element.kind, ElementKind.ENUM);
+    expect(suggestion.element!.kind, ElementKind.ENUM);
     return suggestion;
   }
 
@@ -213,11 +215,11 @@
         relevance: relevance, isDeprecated: isDeprecated);
     expect(suggestion.completion, completion);
     expect(suggestion.isDeprecated, isDeprecated);
-    expect(suggestion.element.kind, ElementKind.ENUM_CONSTANT);
+    expect(suggestion.element!.kind, ElementKind.ENUM_CONSTANT);
     return suggestion;
   }
 
-  CompletionSuggestion assertSuggestField(String name, String type,
+  CompletionSuggestion assertSuggestField(String name, String? type,
       {int relevance = DART_RELEVANCE_DEFAULT,
       CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION,
       bool isDeprecated = false}) {
@@ -228,7 +230,7 @@
         isDeprecated: isDeprecated);
     // The returnType represents the type of a field
     expect(cs.returnType, type ?? 'dynamic');
-    var element = cs.element;
+    var element = cs.element!;
     expect(element, isNotNull);
     expect(element.kind, equals(ElementKind.FIELD));
     expect(element.name, equals(name));
@@ -239,12 +241,12 @@
     return cs;
   }
 
-  CompletionSuggestion assertSuggestFunction(String name, String returnType,
+  CompletionSuggestion assertSuggestFunction(String name, String? returnType,
       {CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION,
       bool isDeprecated = false,
       int relevance = DART_RELEVANCE_DEFAULT,
       String defaultArgListString = _UNCHECKED,
-      List<int> defaultArgumentListTextRanges}) {
+      List<int>? defaultArgumentListTextRanges}) {
     var cs = assertSuggest(name,
         csKind: kind,
         relevance: relevance,
@@ -256,12 +258,12 @@
     } else if (isNullExpectedReturnTypeConsideredDynamic) {
       expect(cs.returnType, 'dynamic');
     }
-    var element = cs.element;
+    var element = cs.element!;
     expect(element, isNotNull);
     expect(element.kind, equals(ElementKind.FUNCTION));
     expect(element.name, equals(name));
     expect(element.isDeprecated, equals(isDeprecated));
-    var param = element.parameters;
+    var param = element.parameters!;
     expect(param, isNotNull);
     expect(param[0], equals('('));
     expect(param[param.length - 1], equals(')'));
@@ -275,7 +277,7 @@
   }
 
   CompletionSuggestion assertSuggestFunctionTypeAlias(
-      String name, String returnType,
+      String name, String? returnType,
       {bool isDeprecated = false,
       int relevance = DART_RELEVANCE_DEFAULT,
       CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION}) {
@@ -288,7 +290,7 @@
     } else {
       expect(cs.returnType, isNull);
     }
-    var element = cs.element;
+    var element = cs.element!;
     expect(element, isNotNull);
     expect(element.kind, equals(ElementKind.FUNCTION_TYPE_ALIAS));
     expect(element.name, equals(name));
@@ -304,7 +306,7 @@
     return cs;
   }
 
-  CompletionSuggestion assertSuggestGetter(String name, String returnType,
+  CompletionSuggestion assertSuggestGetter(String name, String? returnType,
       {int relevance = DART_RELEVANCE_DEFAULT,
       CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION,
       bool isDeprecated = false}) {
@@ -314,7 +316,7 @@
         elemKind: ElementKind.GETTER,
         isDeprecated: isDeprecated);
     expect(cs.returnType, returnType ?? 'dynamic');
-    var element = cs.element;
+    var element = cs.element!;
     expect(element, isNotNull);
     expect(element.kind, equals(ElementKind.GETTER));
     expect(element.name, equals(name));
@@ -325,12 +327,12 @@
   }
 
   CompletionSuggestion assertSuggestMethod(
-      String name, String declaringType, String returnType,
+      String name, String declaringType, String? returnType,
       {int relevance = DART_RELEVANCE_DEFAULT,
       CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION,
       bool isDeprecated = false,
-      String defaultArgListString = _UNCHECKED,
-      List<int> defaultArgumentListTextRanges}) {
+      String? defaultArgListString = _UNCHECKED,
+      List<int>? defaultArgumentListTextRanges}) {
     var cs = assertSuggest(name,
         csKind: kind,
         relevance: relevance,
@@ -339,11 +341,11 @@
         defaultArgumentListTextRanges: defaultArgumentListTextRanges);
     expect(cs.declaringType, equals(declaringType));
     expect(cs.returnType, returnType ?? 'dynamic');
-    var element = cs.element;
+    var element = cs.element!;
     expect(element, isNotNull);
     expect(element.kind, equals(ElementKind.METHOD));
     expect(element.name, equals(name));
-    var param = element.parameters;
+    var param = element.parameters!;
     expect(param, isNotNull);
     expect(param[0], equals('('));
     expect(param[param.length - 1], equals(')'));
@@ -369,7 +371,7 @@
       CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION}) {
     var cs = assertSuggest(name,
         csKind: kind, relevance: relevance, elemKind: ElementKind.SETTER);
-    var element = cs.element;
+    var element = cs.element!;
     expect(element, isNotNull);
     expect(element.kind, equals(ElementKind.SETTER));
     expect(element.name, equals(name));
@@ -383,7 +385,7 @@
     return cs;
   }
 
-  CompletionSuggestion assertSuggestTopLevelVar(String name, String returnType,
+  CompletionSuggestion assertSuggestTopLevelVar(String name, String? returnType,
       {int relevance = DART_RELEVANCE_DEFAULT,
       CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION}) {
     var cs = assertSuggest(name, csKind: kind, relevance: relevance);
@@ -392,7 +394,7 @@
     } else if (isNullExpectedReturnTypeConsideredDynamic) {
       expect(cs.returnType, 'dynamic');
     }
-    var element = cs.element;
+    var element = cs.element!;
     expect(element, isNotNull);
     expect(element.kind, equals(ElementKind.TOP_LEVEL_VARIABLE));
     expect(element.name, equals(name));
@@ -413,17 +415,17 @@
   Future computeSuggestions() async {
     var result = await resolveFile(testFile);
     request =
-        DartCompletionRequestImpl(resourceProvider, completionOffset, result);
+        DartCompletionRequestImpl(resourceProvider, completionOffset!, result);
 
     var target =
-        CompletionTarget.forOffset(request.result.unit, request.offset);
-    var range = target.computeReplacementRange(request.offset);
+        CompletionTarget.forOffset(request!.result.unit!, request!.offset);
+    var range = target.computeReplacementRange(request!.offset);
     replacementOffset = range.offset;
     replacementLength = range.length;
 
     // Request completions
     var collector = CompletionCollectorImpl();
-    await contributor.computeSuggestions(request, collector);
+    await contributor.computeSuggestions(request!, collector);
     suggestions = collector.suggestions;
     expect(suggestions, isNotNull, reason: 'expected suggestions');
   }
@@ -431,7 +433,7 @@
   CompletionContributor createContributor();
 
   void failedCompletion(String message,
-      [Iterable<CompletionSuggestion> completions]) {
+      [Iterable<CompletionSuggestion>? completions]) {
     var sb = StringBuffer(message);
     if (completions != null) {
       sb.write('\n  found');
@@ -444,13 +446,13 @@
     fail(sb.toString());
   }
 
-  CompletionSuggestion getSuggest(
-      {String completion,
-      CompletionSuggestionKind csKind,
-      ElementKind elemKind}) {
-    CompletionSuggestion cs;
+  CompletionSuggestion? getSuggest(
+      {String? completion,
+      CompletionSuggestionKind? csKind,
+      ElementKind? elemKind}) {
+    CompletionSuggestion? cs;
     if (suggestions != null) {
-      suggestions.forEach((CompletionSuggestion s) {
+      suggestions?.forEach((CompletionSuggestion s) {
         if (completion != null && completion != s.completion) {
           return;
         }
@@ -467,7 +469,7 @@
           cs = s;
         } else {
           failedCompletion('expected exactly one $cs',
-              suggestions.where((s) => s.completion == completion));
+              suggestions!.where((s) => s.completion == completion));
         }
       });
     }
diff --git a/pkg/analyzer_plugin/test/utilities/completion/inherited_reference_contributor_test.dart b/pkg/analyzer_plugin/test/utilities/completion/inherited_reference_contributor_test.dart
index 2b63605..9ee63f3 100644
--- a/pkg/analyzer_plugin/test/utilities/completion/inherited_reference_contributor_test.dart
+++ b/pkg/analyzer_plugin/test/utilities/completion/inherited_reference_contributor_test.dart
@@ -200,10 +200,10 @@
     await computeSuggestions();
     var suggestion = assertSuggestMethod('m', 'A', 'void');
     expect(suggestion.parameterNames, hasLength(2));
-    expect(suggestion.parameterNames[0], 'x');
-    expect(suggestion.parameterTypes[0], 'dynamic');
-    expect(suggestion.parameterNames[1], 'y');
-    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.parameterNames![0], 'x');
+    expect(suggestion.parameterTypes![0], 'dynamic');
+    expect(suggestion.parameterNames![1], 'y');
+    expect(suggestion.parameterTypes![1], 'int');
     expect(suggestion.requiredParameterCount, 1);
     expect(suggestion.hasNamedParameters, true);
   }
@@ -220,10 +220,10 @@
     await computeSuggestions();
     var suggestion = assertSuggestMethod('m', 'A', 'void');
     expect(suggestion.parameterNames, hasLength(2));
-    expect(suggestion.parameterNames[0], 'x');
-    expect(suggestion.parameterTypes[0], 'dynamic');
-    expect(suggestion.parameterNames[1], 'y');
-    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.parameterNames![0], 'x');
+    expect(suggestion.parameterTypes![0], 'dynamic');
+    expect(suggestion.parameterNames![1], 'y');
+    expect(suggestion.parameterTypes![1], 'int');
     expect(suggestion.requiredParameterCount, 1);
     expect(suggestion.hasNamedParameters, true);
   }
@@ -243,10 +243,10 @@
     await computeSuggestions();
     var suggestion = assertSuggestMethod('m', 'A', 'void');
     expect(suggestion.parameterNames, hasLength(2));
-    expect(suggestion.parameterNames[0], 'x');
-    expect(suggestion.parameterTypes[0], 'dynamic');
-    expect(suggestion.parameterNames[1], 'y');
-    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.parameterNames![0], 'x');
+    expect(suggestion.parameterTypes![0], 'dynamic');
+    expect(suggestion.parameterNames![1], 'y');
+    expect(suggestion.parameterTypes![1], 'int');
     expect(suggestion.requiredParameterCount, 1);
     expect(suggestion.hasNamedParameters, false);
   }
@@ -264,10 +264,10 @@
     await computeSuggestions();
     var suggestion = assertSuggestMethod('m', 'A', 'void');
     expect(suggestion.parameterNames, hasLength(2));
-    expect(suggestion.parameterNames[0], 'x');
-    expect(suggestion.parameterTypes[0], 'dynamic');
-    expect(suggestion.parameterNames[1], 'y');
-    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.parameterNames![0], 'x');
+    expect(suggestion.parameterTypes![0], 'dynamic');
+    expect(suggestion.parameterNames![1], 'y');
+    expect(suggestion.parameterTypes![1], 'int');
     expect(suggestion.requiredParameterCount, 1);
     expect(suggestion.hasNamedParameters, false);
   }
@@ -287,10 +287,10 @@
     await computeSuggestions();
     var suggestion = assertSuggestMethod('m', 'A', 'void');
     expect(suggestion.parameterNames, hasLength(2));
-    expect(suggestion.parameterNames[0], 'x');
-    expect(suggestion.parameterTypes[0], 'dynamic');
-    expect(suggestion.parameterNames[1], 'y');
-    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.parameterNames![0], 'x');
+    expect(suggestion.parameterTypes![0], 'dynamic');
+    expect(suggestion.parameterNames![1], 'y');
+    expect(suggestion.parameterTypes![1], 'int');
     expect(suggestion.requiredParameterCount, 0);
     expect(suggestion.hasNamedParameters, true);
   }
@@ -307,10 +307,10 @@
     await computeSuggestions();
     var suggestion = assertSuggestMethod('m', 'A', 'void');
     expect(suggestion.parameterNames, hasLength(2));
-    expect(suggestion.parameterNames[0], 'x');
-    expect(suggestion.parameterTypes[0], 'dynamic');
-    expect(suggestion.parameterNames[1], 'y');
-    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.parameterNames![0], 'x');
+    expect(suggestion.parameterTypes![0], 'dynamic');
+    expect(suggestion.parameterNames![1], 'y');
+    expect(suggestion.parameterTypes![1], 'int');
     expect(suggestion.requiredParameterCount, 0);
     expect(suggestion.hasNamedParameters, true);
   }
@@ -367,10 +367,10 @@
     await computeSuggestions();
     var suggestion = assertSuggestMethod('m', 'A', 'void');
     expect(suggestion.parameterNames, hasLength(2));
-    expect(suggestion.parameterNames[0], 'x');
-    expect(suggestion.parameterTypes[0], 'dynamic');
-    expect(suggestion.parameterNames[1], 'y');
-    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.parameterNames![0], 'x');
+    expect(suggestion.parameterTypes![0], 'dynamic');
+    expect(suggestion.parameterNames![1], 'y');
+    expect(suggestion.parameterTypes![1], 'int');
     expect(suggestion.requiredParameterCount, 0);
     expect(suggestion.hasNamedParameters, false);
   }
@@ -387,10 +387,10 @@
     await computeSuggestions();
     var suggestion = assertSuggestMethod('m', 'A', 'void');
     expect(suggestion.parameterNames, hasLength(2));
-    expect(suggestion.parameterNames[0], 'x');
-    expect(suggestion.parameterTypes[0], 'dynamic');
-    expect(suggestion.parameterNames[1], 'y');
-    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.parameterNames![0], 'x');
+    expect(suggestion.parameterTypes![0], 'dynamic');
+    expect(suggestion.parameterNames![1], 'y');
+    expect(suggestion.parameterTypes![1], 'int');
     expect(suggestion.requiredParameterCount, 0);
     expect(suggestion.hasNamedParameters, false);
   }
@@ -410,10 +410,10 @@
     await computeSuggestions();
     var suggestion = assertSuggestMethod('m', 'A', 'void');
     expect(suggestion.parameterNames, hasLength(2));
-    expect(suggestion.parameterNames[0], 'x');
-    expect(suggestion.parameterTypes[0], 'dynamic');
-    expect(suggestion.parameterNames[1], 'y');
-    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.parameterNames![0], 'x');
+    expect(suggestion.parameterTypes![0], 'dynamic');
+    expect(suggestion.parameterNames![1], 'y');
+    expect(suggestion.parameterTypes![1], 'int');
     expect(suggestion.requiredParameterCount, 2);
     expect(suggestion.hasNamedParameters, false);
   }
diff --git a/pkg/analyzer_plugin/test/utilities/completion/type_member_contributor_test.dart b/pkg/analyzer_plugin/test/utilities/completion/type_member_contributor_test.dart
index 59a19c1..4f20366 100644
--- a/pkg/analyzer_plugin/test/utilities/completion/type_member_contributor_test.dart
+++ b/pkg/analyzer_plugin/test/utilities/completion/type_member_contributor_test.dart
@@ -39,13 +39,13 @@
 ''');
     await computeSuggestions();
     var suggestionsForX = suggestions
-        .where((CompletionSuggestion s) => s.completion == 'x')
+        ?.where((CompletionSuggestion s) => s.completion == 'x')
         .toList();
     expect(suggestionsForX, hasLength(1));
     if (shouldBeShadowed) {
-      expect(suggestionsForX[0].declaringType, 'Derived');
+      expect(suggestionsForX![0].declaringType, 'Derived');
     } else {
-      expect(suggestionsForX[0].declaringType, 'Base');
+      expect(suggestionsForX![0].declaringType, 'Base');
     }
   }
 
@@ -428,7 +428,7 @@
           int a;
           int^ b = 1;}''');
     await computeSuggestions();
-    expect(replacementOffset, completionOffset - 3);
+    expect(replacementOffset, completionOffset! - 3);
     expect(replacementLength, 3);
     assertNotSuggested('A');
     assertNotSuggested('int');
@@ -451,7 +451,7 @@
           i^
           b = 1;}''');
     await computeSuggestions();
-    expect(replacementOffset, completionOffset - 1);
+    expect(replacementOffset, completionOffset! - 1);
     expect(replacementLength, 1);
     assertNotSuggested('A');
     assertNotSuggested('int');
@@ -934,7 +934,7 @@
         class Z { }''');
     await computeSuggestions();
 
-    expect(replacementOffset, completionOffset - 1);
+    expect(replacementOffset, completionOffset! - 1);
     expect(replacementLength, 1);
 
     assertNotSuggested('X');
@@ -1075,7 +1075,7 @@
           void b() { }}
         class Z { }''');
     await computeSuggestions();
-    expect(replacementOffset, completionOffset - 1);
+    expect(replacementOffset, completionOffset! - 1);
     expect(replacementLength, 1);
     assertNotSuggested('partT8');
     assertNotSuggested('partBoo');
@@ -1090,7 +1090,7 @@
         '/proj/testAB.dart', 'import "package:myBar/bar.dart"; class Foo { }');
     addTestSource('class C {foo(){F^}}');
     await computeSuggestions();
-    expect(replacementOffset, completionOffset - 1);
+    expect(replacementOffset, completionOffset! - 1);
     expect(replacementLength, 1);
     assertNotSuggested('Foo');
     // TODO(danrubel) implement
@@ -1197,7 +1197,7 @@
         class X{}
         main() {A a; a^..b}''');
     await computeSuggestions();
-    expect(replacementOffset, completionOffset - 1);
+    expect(replacementOffset, completionOffset! - 1);
     expect(replacementLength, 1);
     assertNotSuggested('b');
     assertNotSuggested('_c');
@@ -1324,7 +1324,7 @@
         class _B {}
         A Sew;''');
     await computeSuggestions();
-    expect(replacementOffset, completionOffset - 1);
+    expect(replacementOffset, completionOffset! - 1);
     expect(replacementLength, 1);
     assertNotSuggested('A');
     assertNotSuggested('_B');
@@ -1580,7 +1580,7 @@
     addTestSource('''
         main() {new String.fr^omCharCodes([]);}''');
     await computeSuggestions();
-    expect(replacementOffset, completionOffset - 2);
+    expect(replacementOffset, completionOffset! - 2);
     expect(replacementLength, 13);
     // Suggested by NamedConstructorContributor
     assertNotSuggested('fromCharCodes');
@@ -1837,7 +1837,7 @@
     // DeclaredIdentifier  ForEachStatement  Block
     addTestSource('main(args) {for (S^ foo in args) {}}');
     await computeSuggestions();
-    expect(replacementOffset, completionOffset - 1);
+    expect(replacementOffset, completionOffset! - 1);
     expect(replacementLength, 1);
     assertNotSuggested('args');
     assertNotSuggested('foo');
@@ -1875,7 +1875,7 @@
     // SimpleIdentifier  ForStatement
     addTestSource('main() {for (int index = 0; i^)}');
     await computeSuggestions();
-    expect(replacementOffset, completionOffset - 1);
+    expect(replacementOffset, completionOffset! - 1);
     expect(replacementLength, 1);
     assertNotSuggested('index');
   }
@@ -1895,7 +1895,7 @@
     // SimpleIdentifier  ForStatement
     addTestSource('main() {for (int index = 0; index < 10; i^)}');
     await computeSuggestions();
-    expect(replacementOffset, completionOffset - 1);
+    expect(replacementOffset, completionOffset! - 1);
     expect(replacementLength, 1);
     assertNotSuggested('index');
   }
@@ -1906,7 +1906,7 @@
         void bar() { }
         main() {for (int index = 0; index < 10; ++i^)}''');
     await computeSuggestions();
-    expect(replacementOffset, completionOffset - 1);
+    expect(replacementOffset, completionOffset! - 1);
     expect(replacementLength, 1);
     assertNotSuggested('index');
     assertNotSuggested('main');
@@ -2054,9 +2054,9 @@
 ''');
     await computeSuggestions();
     var suggestion = assertSuggestMethod('m', 'C', 'int');
-    expect(suggestion.parameterTypes[0], 'int');
-    expect(suggestion.element.returnType, 'int');
-    expect(suggestion.element.parameters, '(int t)');
+    expect(suggestion.parameterTypes![0], 'int');
+    expect(suggestion.element!.returnType, 'int');
+    expect(suggestion.element!.parameters, '(int t)');
   }
 
   Future<void> test_generic_setter() async {
@@ -2073,7 +2073,7 @@
     // as a parmeter to it, and it will check the appropriate field in
     // the suggestion object.
     var suggestion = assertSuggestSetter('t');
-    expect(suggestion.element.parameters, '(int value)');
+    expect(suggestion.element!.parameters, '(int value)');
   }
 
   Future<void> test_genericTypeAlias_noFunctionType() async {
@@ -2227,7 +2227,7 @@
     addSource('/testAB.dart', 'class Foo { }');
     addTestSource('class C {foo(){new F^}}');
     await computeSuggestions();
-    expect(replacementOffset, completionOffset - 1);
+    expect(replacementOffset, completionOffset! - 1);
     expect(replacementLength, 1);
     assertNotSuggested('Future');
     assertNotSuggested('Foo');
@@ -2386,7 +2386,7 @@
         class A {int x; int y() => 0;}
         main(){var a; if (a is Obj^)}''');
     await computeSuggestions();
-    expect(replacementOffset, completionOffset - 3);
+    expect(replacementOffset, completionOffset! - 3);
     expect(replacementLength, 3);
     assertNotSuggested('a');
     assertNotSuggested('main');
@@ -2414,7 +2414,7 @@
         var m;
         main() {new^ X.c();}''');
     await computeSuggestions();
-    expect(replacementOffset, completionOffset - 3);
+    expect(replacementOffset, completionOffset! - 3);
     expect(replacementLength, 3);
     assertNotSuggested('c');
     assertNotSuggested('_d');
@@ -2561,7 +2561,7 @@
         class C2 { }
         foo = {T^''');
     await computeSuggestions();
-    expect(replacementOffset, completionOffset - 1);
+    expect(replacementOffset, completionOffset! - 1);
     expect(replacementLength, 1);
     assertNotSuggested('T2');
   }
@@ -2581,7 +2581,7 @@
         class C2 { }
         foo = {7:T^};''');
     await computeSuggestions();
-    expect(replacementOffset, completionOffset - 1);
+    expect(replacementOffset, completionOffset! - 1);
     expect(replacementLength, 1);
     assertNotSuggested('T2');
   }
@@ -2595,10 +2595,10 @@
     await computeSuggestions();
     var suggestion = assertSuggestMethod('m', 'C', 'void');
     expect(suggestion.parameterNames, hasLength(2));
-    expect(suggestion.parameterNames[0], 'x');
-    expect(suggestion.parameterTypes[0], 'dynamic');
-    expect(suggestion.parameterNames[1], 'y');
-    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.parameterNames![0], 'x');
+    expect(suggestion.parameterTypes![0], 'dynamic');
+    expect(suggestion.parameterNames![1], 'y');
+    expect(suggestion.parameterTypes![1], 'int');
     expect(suggestion.requiredParameterCount, 1);
     expect(suggestion.hasNamedParameters, true);
   }
@@ -2612,10 +2612,10 @@
     await computeSuggestions();
     var suggestion = assertSuggestMethod('m', 'C', 'void');
     expect(suggestion.parameterNames, hasLength(2));
-    expect(suggestion.parameterNames[0], 'x');
-    expect(suggestion.parameterTypes[0], 'dynamic');
-    expect(suggestion.parameterNames[1], 'y');
-    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.parameterNames![0], 'x');
+    expect(suggestion.parameterTypes![0], 'dynamic');
+    expect(suggestion.parameterNames![1], 'y');
+    expect(suggestion.parameterTypes![1], 'int');
     expect(suggestion.requiredParameterCount, 1);
     expect(suggestion.hasNamedParameters, false);
   }
@@ -2629,10 +2629,10 @@
     await computeSuggestions();
     var suggestion = assertSuggestMethod('m', 'C', 'void');
     expect(suggestion.parameterNames, hasLength(2));
-    expect(suggestion.parameterNames[0], 'x');
-    expect(suggestion.parameterTypes[0], 'dynamic');
-    expect(suggestion.parameterNames[1], 'y');
-    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.parameterNames![0], 'x');
+    expect(suggestion.parameterTypes![0], 'dynamic');
+    expect(suggestion.parameterNames![1], 'y');
+    expect(suggestion.parameterTypes![1], 'int');
     expect(suggestion.requiredParameterCount, 0);
     expect(suggestion.hasNamedParameters, true);
   }
@@ -2660,10 +2660,10 @@
     await computeSuggestions();
     var suggestion = assertSuggestMethod('m', 'C', 'void');
     expect(suggestion.parameterNames, hasLength(2));
-    expect(suggestion.parameterNames[0], 'x');
-    expect(suggestion.parameterTypes[0], 'dynamic');
-    expect(suggestion.parameterNames[1], 'y');
-    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.parameterNames![0], 'x');
+    expect(suggestion.parameterTypes![0], 'dynamic');
+    expect(suggestion.parameterNames![1], 'y');
+    expect(suggestion.parameterTypes![1], 'int');
     expect(suggestion.requiredParameterCount, 0);
     expect(suggestion.hasNamedParameters, false);
   }
@@ -2677,10 +2677,10 @@
     await computeSuggestions();
     var suggestion = assertSuggestMethod('m', 'C', 'void');
     expect(suggestion.parameterNames, hasLength(2));
-    expect(suggestion.parameterNames[0], 'x');
-    expect(suggestion.parameterTypes[0], 'dynamic');
-    expect(suggestion.parameterNames[1], 'y');
-    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.parameterNames![0], 'x');
+    expect(suggestion.parameterTypes![0], 'dynamic');
+    expect(suggestion.parameterNames![1], 'y');
+    expect(suggestion.parameterTypes![1], 'int');
     expect(suggestion.requiredParameterCount, 2);
     expect(suggestion.hasNamedParameters, false);
   }
@@ -3347,7 +3347,7 @@
         import "a.dart";
         class X {foo(){A^.bar}}''');
     await computeSuggestions();
-    expect(replacementOffset, completionOffset - 1);
+    expect(replacementOffset, completionOffset! - 1);
     expect(replacementLength, 1);
     assertNotSuggested('A');
     assertNotSuggested('X');
@@ -3465,7 +3465,7 @@
     // SimpleIdentifier  MethodInvocation  PropertyAccess  ExpressionStatement
     addTestSource('class A {a() {"hello".to^String().length}}');
     await computeSuggestions();
-    expect(replacementOffset, completionOffset - 2);
+    expect(replacementOffset, completionOffset! - 2);
     expect(replacementLength, 8);
     assertSuggestGetter('length', 'int');
     assertNotSuggested('A');
@@ -3798,7 +3798,7 @@
           m(X x) {} I _n(X x) {}}
         class X{}''');
     await computeSuggestions();
-    expect(replacementOffset, completionOffset - 1);
+    expect(replacementOffset, completionOffset! - 1);
     expect(replacementLength, 1);
     // Contributed by FieldFormalConstructorContributor
     assertNotSuggested('b');
@@ -3946,7 +3946,7 @@
         class C<E> {}
         main() { C<C^> c; }''');
     await computeSuggestions();
-    expect(replacementOffset, completionOffset - 1);
+    expect(replacementOffset, completionOffset! - 1);
     expect(replacementLength, 1);
     assertNotSuggested('C1');
     assertNotSuggested('C2');
diff --git a/pkg/analyzer_plugin/test/verify_tests_test.dart b/pkg/analyzer_plugin/test/verify_tests_test.dart
index 48657ce..f7414bb 100644
--- a/pkg/analyzer_plugin/test/verify_tests_test.dart
+++ b/pkg/analyzer_plugin/test/verify_tests_test.dart
@@ -16,7 +16,7 @@
 }
 
 class _VerifyTests extends VerifyTests {
-  _VerifyTests(String testDirPath, {List<String> excludedPaths})
+  _VerifyTests(String testDirPath, {List<String>? excludedPaths})
       : super(testDirPath, excludedPaths: excludedPaths);
 
   @override
diff --git a/pkg/analyzer_plugin/tool/spec/api.dart b/pkg/analyzer_plugin/tool/spec/api.dart
index 6b4508a..04ef8d8 100644
--- a/pkg/analyzer_plugin/tool/spec/api.dart
+++ b/pkg/analyzer_plugin/tool/spec/api.dart
@@ -13,11 +13,11 @@
   final String version;
   final List<Domain> domains;
   final Types types;
-  final Refactorings refactorings;
+  final Refactorings? refactorings;
 
   Api(this.version, this.domains, this.types, this.refactorings,
       dom.Element html,
-      {bool experimental})
+      {bool? experimental})
       : super(html, experimental, false);
 }
 
@@ -30,9 +30,9 @@
   final bool deprecated;
 
   /// Html element representing this part of the API.
-  final dom.Element html;
+  final dom.Element? html;
 
-  ApiNode(this.html, bool experimental, bool deprecated)
+  ApiNode(this.html, bool? experimental, bool? deprecated)
       : experimental = experimental ?? false,
         deprecated = deprecated ?? false;
 }
@@ -57,7 +57,7 @@
   final List<Notification> notifications;
 
   Domain(this.name, this.requests, this.notifications, dom.Element html,
-      {bool experimental, bool deprecated})
+      {bool? experimental, bool? deprecated})
       : super(html, experimental, deprecated);
 }
 
@@ -73,9 +73,9 @@
   ///
   /// If it is not possible (because the chain ends with a [TypeReference] that
   /// is not defined in the API), then that final [TypeReference] is returned.
-  TypeDecl resolveTypeReferenceChain(TypeDecl type) {
+  TypeDecl? resolveTypeReferenceChain(TypeDecl? type) {
     while (type is TypeReference && api.types.containsKey(type.typeName)) {
-      type = api.types[(type as TypeReference).typeName].type;
+      type = api.types[type.typeName]?.type;
     }
     return type;
   }
@@ -93,29 +93,29 @@
 
   void visitNotification(Notification notification) {
     if (notification.params != null) {
-      visitTypeDecl(notification.params);
+      visitTypeDecl(notification.params!);
     }
   }
 
   void visitRefactoring(Refactoring refactoring) {
     if (refactoring.feedback != null) {
-      visitTypeDecl(refactoring.feedback);
+      visitTypeDecl(refactoring.feedback!);
     }
     if (refactoring.options != null) {
-      visitTypeDecl(refactoring.options);
+      visitTypeDecl(refactoring.options!);
     }
   }
 
-  void visitRefactorings(Refactorings refactorings) {
+  void visitRefactorings(Refactorings? refactorings) {
     refactorings?.forEach(visitRefactoring);
   }
 
   void visitRequest(Request request) {
     if (request.params != null) {
-      visitTypeDecl(request.params);
+      visitTypeDecl(request.params!);
     }
     if (request.result != null) {
-      visitTypeDecl(request.result);
+      visitTypeDecl(request.result!);
     }
   }
 
@@ -173,10 +173,10 @@
 
   /// Type of the object associated with the "params" key in the notification
   /// object, or null if the notification has no parameters.
-  final TypeObject params;
+  final TypeObject? params;
 
   Notification(this.domainName, this.event, this.params, dom.Element html,
-      {bool experimental})
+      {bool? experimental})
       : super(html, experimental, false);
 
   /// Get the name of the notification, including the domain prefix.
@@ -190,7 +190,7 @@
           value: '$domainName.$event')
     ];
     if (params != null) {
-      fields.add(TypeObjectField('params', params, null));
+      fields.add(TypeObjectField('params', params!, null));
     }
     return TypeObject(fields, null);
   }
@@ -204,14 +204,14 @@
 
   /// Type of the refactoring feedback, or null if the refactoring has no
   /// feedback.
-  final TypeObject feedback;
+  final TypeObject? feedback;
 
   /// Type of the refactoring options, or null if the refactoring has no
   /// options.
-  final TypeObject options;
+  final TypeObject? options;
 
   Refactoring(this.kind, this.feedback, this.options, dom.Element html,
-      {bool experimental})
+      {bool? experimental})
       : super(html, experimental, false);
 }
 
@@ -219,7 +219,7 @@
 class Refactorings extends ApiNode with IterableMixin<Refactoring> {
   final List<Refactoring> refactorings;
 
-  Refactorings(this.refactorings, dom.Element html, {bool experimental})
+  Refactorings(this.refactorings, dom.Element html, {bool? experimental})
       : super(html, experimental, false);
 
   @override
@@ -236,15 +236,15 @@
 
   /// Type of the object associated with the "params" key in the request object,
   /// or null if the request has no parameters.
-  final TypeObject params;
+  final TypeObject? params;
 
   /// Type of the object associated with the "result" key in the response
   /// object, or null if the response has no results.
-  final TypeObject result;
+  final TypeObject? result;
 
   Request(
       this.domainName, this.method, this.params, this.result, dom.Element html,
-      {bool experimental, bool deprecated})
+      {bool? experimental, bool? deprecated})
       : super(html, experimental, deprecated);
 
   /// Get the name of the request, including the domain prefix.
@@ -259,7 +259,7 @@
           value: '$domainName.$method')
     ];
     if (params != null) {
-      fields.add(TypeObjectField('params', params, null));
+      fields.add(TypeObjectField('params', params!, null));
     }
     return TypeObject(fields, null);
   }
@@ -273,7 +273,7 @@
           optional: true)
     ];
     if (result != null) {
-      fields.add(TypeObjectField('result', result, null));
+      fields.add(TypeObjectField('result', result!, null));
     }
     return TypeObject(fields, null);
   }
@@ -281,7 +281,7 @@
 
 /// Base class for all possible types.
 abstract class TypeDecl extends ApiNode {
-  TypeDecl(dom.Element html, bool experimental, bool deprecated)
+  TypeDecl(dom.Element? html, bool? experimental, bool? deprecated)
       : super(html, experimental, deprecated);
 
   T accept<T>(ApiVisitor<T> visitor);
@@ -295,7 +295,7 @@
   bool isExternal = false;
 
   TypeDefinition(this.name, this.type, dom.Element html,
-      {bool experimental, bool deprecated})
+      {bool? experimental, bool? deprecated})
       : super(html, experimental, deprecated);
 }
 
@@ -304,7 +304,8 @@
 class TypeEnum extends TypeDecl {
   final List<TypeEnumValue> values;
 
-  TypeEnum(this.values, dom.Element html, {bool experimental, bool deprecated})
+  TypeEnum(this.values, dom.Element html,
+      {bool? experimental, bool? deprecated})
       : super(html, experimental, deprecated);
 
   @override
@@ -316,7 +317,7 @@
   final String value;
 
   TypeEnumValue(this.value, dom.Element html,
-      {bool experimental, bool deprecated})
+      {bool? experimental, bool? deprecated})
       : super(html, experimental, deprecated);
 }
 
@@ -324,7 +325,7 @@
 class TypeList extends TypeDecl {
   final TypeDecl itemType;
 
-  TypeList(this.itemType, dom.Element html, {bool experimental})
+  TypeList(this.itemType, dom.Element html, {bool? experimental})
       : super(html, experimental, false);
 
   @override
@@ -342,7 +343,7 @@
   /// Type of map values.
   final TypeDecl valueType;
 
-  TypeMap(this.keyType, this.valueType, dom.Element html, {bool experimental})
+  TypeMap(this.keyType, this.valueType, dom.Element html, {bool? experimental})
       : super(html, experimental, false);
 
   @override
@@ -353,15 +354,15 @@
 class TypeObject extends TypeDecl {
   final List<TypeObjectField> fields;
 
-  TypeObject(this.fields, dom.Element html,
-      {bool experimental, bool deprecated})
+  TypeObject(this.fields, dom.Element? html,
+      {bool? experimental, bool? deprecated})
       : super(html, experimental, deprecated);
 
   @override
   T accept<T>(ApiVisitor<T> visitor) => visitor.visitTypeObject(this);
 
   /// Return the field with the given [name], or null if there is no such field.
-  TypeObjectField getField(String name) {
+  TypeObjectField? getField(String name) {
     for (var field in fields) {
       if (field.name == name) {
         return field;
@@ -378,10 +379,10 @@
   final bool optional;
 
   /// Value that the field is required to contain, or null if it may vary.
-  final Object value;
+  final Object? value;
 
-  TypeObjectField(this.name, this.type, dom.Element html,
-      {this.optional = false, this.value, bool experimental, bool deprecated})
+  TypeObjectField(this.name, this.type, dom.Element? html,
+      {this.optional = false, this.value, bool? experimental, bool? deprecated})
       : super(html, experimental, deprecated);
 }
 
@@ -390,7 +391,7 @@
 class TypeReference extends TypeDecl {
   final String typeName;
 
-  TypeReference(this.typeName, dom.Element html, {bool experimental})
+  TypeReference(this.typeName, dom.Element? html, {bool? experimental})
       : super(html, experimental, false) {
     if (typeName.isEmpty) {
       throw Exception('Empty type name');
@@ -407,7 +408,7 @@
 
   List<String> importUris = <String>[];
 
-  Types(this.types, dom.Element html, {bool experimental})
+  Types(this.types, dom.Element html, {bool? experimental})
       : super(html, experimental, false);
 
   @override
@@ -415,7 +416,7 @@
 
   Iterable<String> get keys => types.keys;
 
-  TypeDefinition operator [](String typeName) => types[typeName];
+  TypeDefinition? operator [](String typeName) => types[typeName];
 
   bool containsKey(String typeName) => types.containsKey(typeName);
 }
@@ -427,7 +428,7 @@
   /// The field that is used to disambiguate this union
   final String field;
 
-  TypeUnion(this.choices, this.field, dom.Element html, {bool experimental})
+  TypeUnion(this.choices, this.field, dom.Element html, {bool? experimental})
       : super(html, experimental, false);
 
   @override
diff --git a/pkg/analyzer_plugin/tool/spec/codegen_dart.dart b/pkg/analyzer_plugin/tool/spec/codegen_dart.dart
index 9dacf99..d0d03f1 100644
--- a/pkg/analyzer_plugin/tool/spec/codegen_dart.dart
+++ b/pkg/analyzer_plugin/tool/spec/codegen_dart.dart
@@ -20,7 +20,7 @@
       var typeName = type.typeName;
       var referencedDefinition = api.types[typeName];
       if (_typeRenames.containsKey(typeName)) {
-        return _typeRenames[typeName];
+        return _typeRenames[typeName]!;
       }
       if (referencedDefinition == null) {
         return typeName;
@@ -35,9 +35,15 @@
     } else if (type is TypeMap) {
       return 'Map<${dartType(type.keyType)}, ${dartType(type.valueType)}>';
     } else if (type is TypeUnion) {
-      return 'dynamic';
+      return 'Object';
     } else {
       throw Exception("Can't convert to a dart type");
     }
   }
+
+  /// Return the Dart type for [field], nullable if the field is optional.
+  String fieldDartType(TypeObjectField field) {
+    var typeStr = dartType(field.type);
+    return field.optional ? '$typeStr?' : typeStr;
+  }
 }
diff --git a/pkg/analyzer_plugin/tool/spec/codegen_dart_protocol.dart b/pkg/analyzer_plugin/tool/spec/codegen_dart_protocol.dart
index 6497fe8..85fb45a 100644
--- a/pkg/analyzer_plugin/tool/spec/codegen_dart_protocol.dart
+++ b/pkg/analyzer_plugin/tool/spec/codegen_dart_protocol.dart
@@ -243,7 +243,7 @@
   /// Emit the toJson() code for an empty class.
   void emitEmptyToJsonMember() {
     writeln('@override');
-    writeln('Map<String, dynamic> toJson() => <String, dynamic>{};');
+    writeln('Map<String, Object> toJson() => <String, Object>{};');
   }
 
   /// Emit a class to encapsulate an enum.
@@ -253,7 +253,7 @@
         toHtmlVisitor.write(impliedType.humanReadableName);
       });
       if (impliedType.type != null) {
-        toHtmlVisitor.showType(null, impliedType.type);
+        toHtmlVisitor.showType(null, impliedType.type!);
       }
       toHtmlVisitor.p(() {
         toHtmlVisitor.write(disclaimer);
@@ -342,7 +342,7 @@
   void emitEnumFromJsonConstructor(
       String className, TypeEnum type, ImpliedType impliedType) {
     writeln(
-        'factory $className.fromJson(JsonDecoder jsonDecoder, String jsonPath, Object json) {');
+        'factory $className.fromJson(JsonDecoder jsonDecoder, String jsonPath, Object? json) {');
     indent(() {
       writeln('if (json is String) {');
       indent(() {
@@ -387,7 +387,7 @@
         toHtmlVisitor.write(impliedType.humanReadableName);
       });
       if (impliedType.type != null) {
-        toHtmlVisitor.showType(null, impliedType.type);
+        toHtmlVisitor.showType(null, impliedType.type!);
       }
       toHtmlVisitor.p(() {
         toHtmlVisitor.write(disclaimer);
@@ -413,29 +413,10 @@
         if (field.value != null) {
           continue;
         }
-        writeln('${dartType(field.type)} _${field.name};');
-        writeln();
-      }
-      for (var field in type.fields) {
-        if (field.value != null) {
-          continue;
-        }
         docComment(toHtmlVisitor.collectHtml(() {
           toHtmlVisitor.translateHtml(field.html);
         }));
-        writeln('${dartType(field.type)} get ${field.name} => _${field.name};');
-        writeln();
-        docComment(toHtmlVisitor.collectHtml(() {
-          toHtmlVisitor.translateHtml(field.html);
-        }));
-        writeln('set ${field.name}(${dartType(field.type)} value) {');
-        indent(() {
-          if (!field.optional) {
-            writeln('assert(value != null);');
-          }
-          writeln('_${field.name} = value;');
-        });
-        writeln('}');
+        writeln('${fieldDartType(field)} ${field.name};');
         writeln();
       }
       emitObjectConstructor(type, className);
@@ -479,66 +460,44 @@
   void emitObjectConstructor(TypeObject type, String className) {
     var args = <String>[];
     var optionalArgs = <String>[];
-    var extraInitCode = <CodegenCallback>[];
+    var initializers = <String>[];
     for (var field in type.fields) {
       if (field.value != null) {
         continue;
       }
-      var arg = '${dartType(field.type)} ${field.name}';
-      var setValueFromArg = 'this.${field.name} = ${field.name};';
       if (isOptionalConstructorArg(className, field)) {
-        optionalArgs.add(arg);
         if (!field.optional) {
+          optionalArgs.add('${dartType(field.type)}? ${field.name}');
           // Optional constructor arg, but non-optional field. If no arg is
           // given, the constructor should populate with the empty list.
           var fieldType = field.type;
           if (fieldType is TypeList) {
-            extraInitCode.add(() {
-              writeln('if (${field.name} == null) {');
-              indent(() {
-                writeln(
-                    'this.${field.name} = <${dartType(fieldType.itemType)}>[];');
-              });
-              writeln('} else {');
-              indent(() {
-                writeln(setValueFromArg);
-              });
-              writeln('}');
-            });
+            var defaultValue = '<${dartType(fieldType.itemType)}>[]';
+            initializers.add('${field.name} = ${field.name} ?? $defaultValue');
           } else {
             throw Exception("Don't know how to create default field value.");
           }
         } else {
-          extraInitCode.add(() {
-            writeln(setValueFromArg);
-          });
+          optionalArgs.add('this.${field.name}');
         }
       } else {
-        args.add(arg);
-        extraInitCode.add(() {
-          writeln(setValueFromArg);
-        });
+        args.add('this.${field.name}');
       }
     }
     if (optionalArgs.isNotEmpty) {
       args.add('{${optionalArgs.join(', ')}}');
     }
     write('$className(${args.join(', ')})');
-    if (extraInitCode.isEmpty) {
+    if (initializers.isEmpty) {
       writeln(';');
     } else {
-      writeln(' {');
-      indent(() {
-        for (var callback in extraInitCode) {
-          callback();
-        }
-      });
-      writeln('}');
+      writeln(' : ${initializers.join(', ')}');
+      writeln(';');
     }
   }
 
   /// Emit the operator== code for an object class.
-  void emitObjectEqualsMember(TypeObject type, String className) {
+  void emitObjectEqualsMember(TypeObject? type, String className) {
     writeln('@override');
     writeln('bool operator ==(other) {');
     indent(() {
@@ -573,7 +532,7 @@
     var humanReadableNameString = literalString(impliedType.humanReadableName);
     if (className == 'RefactoringFeedback') {
       writeln('factory RefactoringFeedback.fromJson(JsonDecoder jsonDecoder, '
-          'String jsonPath, Object json, Map responseJson) {');
+          'String jsonPath, Object? json, Map responseJson) {');
       indent(() {
         writeln('return refactoringFeedbackFromJson(jsonDecoder, jsonPath, '
             'json, responseJson);');
@@ -583,7 +542,7 @@
     }
     if (className == 'RefactoringOptions') {
       writeln('factory RefactoringOptions.fromJson(JsonDecoder jsonDecoder, '
-          'String jsonPath, Object json, RefactoringKind kind) {');
+          'String jsonPath, Object? json, RefactoringKind kind) {');
       indent(() {
         writeln('return refactoringOptionsFromJson(jsonDecoder, jsonPath, '
             'json, kind);');
@@ -592,7 +551,7 @@
       return;
     }
     writeln(
-        'factory $className.fromJson(JsonDecoder jsonDecoder, String jsonPath, Object json) {');
+        'factory $className.fromJson(JsonDecoder jsonDecoder, String jsonPath, Object? json) {');
     indent(() {
       writeln('json ??= {};');
       writeln('if (json is Map) {');
@@ -618,11 +577,11 @@
           } else {
             args.add(field.name);
           }
-          var fieldType = field.type;
-          var fieldDartType = dartType(fieldType);
-          writeln('$fieldDartType ${field.name};');
+          var typeStr = fieldDartType(field);
+          writeln('$typeStr ${field.name};');
           writeln('if (json.containsKey($fieldNameString)) {');
           indent(() {
+            var fieldType = field.type;
             var fromJson =
                 fromJsonCode(fieldType).asSnippet(jsonPath, fieldAccessor);
             writeln('${field.name} = $fromJson;');
@@ -653,7 +612,7 @@
   }
 
   /// Emit the hashCode getter for an object class.
-  void emitObjectHashCode(TypeObject type, String className) {
+  void emitObjectHashCode(TypeObject? type, String className) {
     writeln('@override');
     writeln('int get hashCode {');
     indent(() {
@@ -691,7 +650,7 @@
               'Returns the [RefactoringProblemSeverity] with the maximal severity.')
         ]);
         writeln(
-            'static RefactoringProblemSeverity max(RefactoringProblemSeverity a, RefactoringProblemSeverity b) =>');
+            'static RefactoringProblemSeverity? max(RefactoringProblemSeverity? a, RefactoringProblemSeverity? b) =>');
         writeln('    maxRefactoringProblemSeverity(a, b);');
         return true;
       default:
@@ -762,7 +721,7 @@
         docComment([
           dom.Text('Returns the [FileEdit] for the given [file], maybe `null`.')
         ]);
-        writeln('SourceFileEdit getFileEdit(String file) =>');
+        writeln('SourceFileEdit? getFileEdit(String file) =>');
         writeln('    getChangeFileEdit(this, file);');
         return true;
       case 'SourceEdit':
@@ -826,9 +785,9 @@
   /// Emit the toJson() code for an object class.
   void emitToJsonMember(TypeObject type) {
     writeln('@override');
-    writeln('Map<String, dynamic> toJson() {');
+    writeln('Map<String, Object> toJson() {');
     indent(() {
-      writeln('var result = <String, dynamic>{};');
+      writeln('var result = <String, Object>{};');
       for (var field in type.fields) {
         var fieldNameString = literalString(field.name);
         if (field.value != null) {
@@ -839,7 +798,9 @@
         var fieldToJson = toJsonCode(field.type).asSnippet(field.name);
         var populateField = 'result[$fieldNameString] = $fieldToJson;';
         if (field.optional) {
-          writeln('if (${field.name} != null) {');
+          var name = field.name;
+          writeln('var $name = this.$name;');
+          writeln('if ($name != null) {');
           indent(() {
             writeln(populateField);
           });
@@ -1000,7 +961,7 @@
         }
       }
       return FromJsonSnippet((String jsonPath, String json) =>
-          'jsonDecoder.decodeUnion($jsonPath, $json as Map, ${literalString(type.field)}, {${decoders.join(', ')}})');
+          'jsonDecoder.decodeUnion($jsonPath, $json, ${literalString(type.field)}, {${decoders.join(', ')}})');
     } else {
       throw Exception("Can't convert $type from JSON");
     }
@@ -1083,7 +1044,10 @@
           throw Exception('Union types must be unions of objects');
         }
       }
-      return ToJsonSnippet(dartType(type), (String value) => '$value.toJson()');
+      return ToJsonSnippet(
+        dartType(type),
+        (String value) => '($value as dynamic).toJson()',
+      );
     } else if (resolvedType is TypeObject || resolvedType is TypeEnum) {
       return ToJsonSnippet(dartType(type), (String value) => '$value.toJson()');
     } else {
@@ -1148,7 +1112,7 @@
 
   @override
   String get asClosure =>
-      '(String jsonPath, Object json) => ${callback('jsonPath', 'json')}';
+      '(String jsonPath, Object? json) => ${callback('jsonPath', 'json')}';
 
   @override
   bool get isIdentity => false;
diff --git a/pkg/analyzer_plugin/tool/spec/codegen_inttest_methods.dart b/pkg/analyzer_plugin/tool/spec/codegen_inttest_methods.dart
index fe65490..0a44cfc 100644
--- a/pkg/analyzer_plugin/tool/spec/codegen_inttest_methods.dart
+++ b/pkg/analyzer_plugin/tool/spec/codegen_inttest_methods.dart
@@ -47,11 +47,11 @@
 
   /// Generate a function argument for the given parameter field.
   String formatArgument(TypeObjectField field) =>
-      '${dartType(field.type)} ${field.name}';
+      '${fieldDartType(field)} ${field.name}';
 
   /// Figure out the appropriate Dart type for data having the given API
   /// protocol [type].
-  String jsonType(TypeDecl type) {
+  String jsonType(TypeDecl? type) {
     type = resolveTypeReferenceChain(type);
     if (type is TypeEnum) {
       return 'String';
@@ -130,7 +130,6 @@
           writeln('default:');
           indent(() {
             writeln("fail('Unexpected notification: \$event');");
-            writeln('break;');
           });
         });
         writeln('}');
@@ -152,12 +151,12 @@
       toHtmlVisitor.translateHtml(notification.html);
       toHtmlVisitor.describePayload(notification.params, 'Parameters');
     }));
-    writeln('Stream<$className> $streamName;');
+    writeln('late Stream<$className> $streamName;');
     writeln();
     docComment(toHtmlVisitor.collectHtml(() {
       toHtmlVisitor.write('Stream controller for [$streamName].');
     }));
-    writeln('StreamController<$className> _$streamName;');
+    writeln('late StreamController<$className> _$streamName;');
     fieldInitializationCode.add(collectCode(() {
       writeln('_$streamName = StreamController<$className>(sync: true);');
       writeln('$streamName = _$streamName.stream.asBroadcastStream();');
@@ -185,8 +184,9 @@
     var methodName = camelJoin(['send', request.domainName, request.method]);
     var args = <String>[];
     var optionalArgs = <String>[];
-    if (request.params != null) {
-      for (var field in request.params.fields) {
+    var params = request.params;
+    if (params != null) {
+      for (var field in params.fields) {
         if (field.optional) {
           optionalArgs.add(formatArgument(field));
         } else {
@@ -206,8 +206,8 @@
     if (request.deprecated) {
       writeln('@deprecated');
     }
-    String resultClass;
-    String futureClass;
+    String? resultClass;
+    String? futureClass;
     if (request.result == null) {
       futureClass = 'Future';
     } else {
@@ -221,11 +221,12 @@
           [request.domainName, request.method, 'params'],
           doCapitalize: true);
       var paramsVar = 'null';
-      if (request.params != null) {
+      var params = request.params;
+      if (params != null) {
         paramsVar = 'params';
         var args = <String>[];
         var optionalArgs = <String>[];
-        for (var field in request.params.fields) {
+        for (var field in params.fields) {
           if (field.optional) {
             optionalArgs.add('${field.name}: ${field.name}');
           } else {
diff --git a/pkg/analyzer_plugin/tool/spec/codegen_matchers.dart b/pkg/analyzer_plugin/tool/spec/codegen_matchers.dart
index 9e3e2fd..f9a7d27 100644
--- a/pkg/analyzer_plugin/tool/spec/codegen_matchers.dart
+++ b/pkg/analyzer_plugin/tool/spec/codegen_matchers.dart
@@ -22,7 +22,7 @@
 
   /// Short human-readable string describing the context of the matcher being
   /// created.
-  String context;
+  String? context;
 
   CodegenMatchersVisitor(Api api)
       : toHtmlVisitor = ToHtmlVisitor(api),
@@ -41,17 +41,19 @@
     context = impliedType.humanReadableName;
     docComment(toHtmlVisitor.collectHtml(() {
       toHtmlVisitor.p(() {
-        toHtmlVisitor.write(context);
+        toHtmlVisitor.write(context!);
       });
-      if (impliedType.type != null) {
-        toHtmlVisitor.showType(null, impliedType.type);
+      var type = impliedType.type;
+      if (type != null) {
+        toHtmlVisitor.showType(null, type);
       }
     }));
     write('final Matcher ${camelJoin(['is', impliedType.camelName])} = ');
-    if (impliedType.type == null) {
+    var type = impliedType.type;
+    if (type == null) {
       write('isNull');
     } else {
-      visitTypeDecl(impliedType.type);
+      visitTypeDecl(type);
     }
     writeln(';');
     writeln();
diff --git a/pkg/analyzer_plugin/tool/spec/codegen_protocol_constants.dart b/pkg/analyzer_plugin/tool/spec/codegen_protocol_constants.dart
index 52618ac..648859a 100644
--- a/pkg/analyzer_plugin/tool/spec/codegen_protocol_constants.dart
+++ b/pkg/analyzer_plugin/tool/spec/codegen_protocol_constants.dart
@@ -99,7 +99,7 @@
   /// Generate a constant for each of the fields in the given [type], where the
   /// name of each constant will be composed from the [parentName] and the name
   /// of the field.
-  void _addFieldConstants(String parentName, TypeObject type) {
+  void _addFieldConstants(String parentName, TypeObject? type) {
     if (type == null) {
       return;
     }
diff --git a/pkg/analyzer_plugin/tool/spec/common_types_spec.html b/pkg/analyzer_plugin/tool/spec/common_types_spec.html
index 984b617..adadbe5 100644
--- a/pkg/analyzer_plugin/tool/spec/common_types_spec.html
+++ b/pkg/analyzer_plugin/tool/spec/common_types_spec.html
@@ -1056,6 +1056,20 @@
           the range.
         </p>
       </field>
+      <field name="endLine">
+        <ref>int</ref>
+        <p>
+          The one-based index of the line containing the character immediately
+          following the range.
+        </p>
+      </field>
+      <field name="endColumn">
+        <ref>int</ref>
+        <p>
+          The one-based index of the column containing the character immediately
+          following the range.
+        </p>
+      </field>
     </object>
   </type>
   <type name="NavigationRegion">
diff --git a/pkg/analyzer_plugin/tool/spec/from_html.dart b/pkg/analyzer_plugin/tool/spec/from_html.dart
index 977737b..cd144a9 100644
--- a/pkg/analyzer_plugin/tool/spec/from_html.dart
+++ b/pkg/analyzer_plugin/tool/spec/from_html.dart
@@ -75,8 +75,8 @@
     Api api;
     var versions = <String>[];
     var domains = <Domain>[];
-    Types types;
-    Refactorings refactorings;
+    Types? types;
+    Refactorings? refactorings;
     recurse(html, 'api', {
       'domain': (dom.Element element) {
         domains.add(domainFromHtml(element));
@@ -97,7 +97,7 @@
     if (versions.length != 1) {
       throw Exception('The API must contain exactly one <version> element');
     }
-    api = Api(versions[0], domains, types, refactorings, html);
+    api = Api(versions[0], domains, types!, refactorings, html);
     return api;
   }
 
@@ -125,7 +125,7 @@
   }
 
   /// Check that the given [element] has the given [expectedName].
-  void checkName(dom.Element element, String expectedName, [String context]) {
+  void checkName(dom.Element element, String expectedName, [String? context]) {
     if (element.localName != expectedName) {
       context ??= element.localName;
       throw Exception(
@@ -158,7 +158,7 @@
         notifications.add(notificationFromHtml(child, context));
       }
     });
-    return Domain(name, requests, notifications, html,
+    return Domain(name!, requests, notifications, html,
         experimental: experimental);
   }
 
@@ -186,18 +186,18 @@
   ///
   /// Child elements can occur in any order.
   Notification notificationFromHtml(dom.Element html, String context) {
-    var domainName = getAncestor(html, 'domain', context).attributes['name'];
+    var domainName = getAncestor(html, 'domain', context).attributes['name']!;
     checkName(html, 'notification', context);
     var event = html.attributes['event'];
     context = '$context.${event ?? 'event'}';
     checkAttributes(html, ['event'], context);
-    TypeObject params;
+    late TypeObject params;
     recurse(html, context, {
       'params': (dom.Element child) {
         params = typeObjectFromHtml(child, '$context.params');
       }
     });
-    return Notification(domainName, event, params, html);
+    return Notification(domainName, event!, params, html);
   }
 
   /// Create a single of [TypeDecl] corresponding to the type defined inside the
@@ -249,8 +249,8 @@
       },
       'map': (dom.Element child) {
         checkAttributes(child, [], context);
-        TypeDecl keyType;
-        TypeDecl valueType;
+        TypeDecl? keyType;
+        TypeDecl? valueType;
         recurse(child, context, {
           'key': (dom.Element child) {
             if (keyType != null) {
@@ -271,7 +271,7 @@
         if (valueType == null) {
           throw Exception('$context: Value type not specified');
         }
-        types.add(TypeMap(keyType as TypeReference, valueType, child));
+        types.add(TypeMap(keyType as TypeReference, valueType!, child));
       },
       'enum': (dom.Element child) {
         types.add(typeEnumFromHtml(child, context));
@@ -284,7 +284,7 @@
         checkAttributes(child, ['field'], context);
         var field = child.attributes['field'];
         types.add(
-            TypeUnion(processContentsAsTypes(child, context), field, child));
+            TypeUnion(processContentsAsTypes(child, context), field!, child));
       }
     });
     return types;
@@ -295,7 +295,7 @@
     var htmlContents = File(filePath).readAsStringSync();
     var document = parser.parse(htmlContents);
     var htmlElement = document.children
-        .singleWhere((element) => element.localName.toLowerCase() == 'html');
+        .singleWhere((element) => element.localName?.toLowerCase() == 'html');
     return apiFromHtml(htmlElement);
   }
 
@@ -309,7 +309,7 @@
     for (var node in parent.nodes) {
       if (node is dom.Element) {
         if (elementProcessors.containsKey(node.localName)) {
-          elementProcessors[node.localName](node);
+          elementProcessors[node.localName]!(node);
         } else if (specialElements.contains(node.localName)) {
           throw Exception('$context: Unexpected use of <${node.localName}>');
         } else {
@@ -335,8 +335,8 @@
     var kind = html.attributes['kind'];
     var context = kind ?? 'refactoring';
     checkAttributes(html, ['kind'], context);
-    TypeObject feedback;
-    TypeObject options;
+    TypeObject? feedback;
+    TypeObject? options;
     recurse(html, context, {
       'feedback': (dom.Element child) {
         feedback = typeObjectFromHtml(child, '$context.feedback');
@@ -345,7 +345,7 @@
         options = typeObjectFromHtml(child, '$context.options');
       }
     });
-    return Refactoring(kind, feedback, options, html);
+    return Refactoring(kind!, feedback, options, html);
   }
 
   /// Create a [Refactorings] object from an HTML representation such as:
@@ -380,7 +380,7 @@
   ///
   /// Child elements can occur in any order.
   Request requestFromHtml(dom.Element html, String context) {
-    var domainName = getAncestor(html, 'domain', context).attributes['name'];
+    var domainName = getAncestor(html, 'domain', context).attributes['name']!;
     checkName(html, 'request', context);
     var method = html.attributes['method'];
     context = '$context.${method ?? 'method'}';
@@ -388,8 +388,8 @@
         optionalAttributes: ['experimental', 'deprecated']);
     var experimental = html.attributes['experimental'] == 'true';
     var deprecated = html.attributes['deprecated'] == 'true';
-    TypeObject params;
-    TypeObject result;
+    TypeObject? params;
+    TypeObject? result;
     recurse(html, context, {
       'params': (dom.Element child) {
         params = typeObjectFromHtml(child, '$context.params');
@@ -398,7 +398,7 @@
         result = typeObjectFromHtml(child, '$context.result');
       }
     });
-    return Request(domainName, method, params, result, html,
+    return Request(domainName, method!, params, result, html,
         experimental: experimental, deprecated: deprecated);
   }
 
@@ -420,7 +420,7 @@
     var type = processContentsAsType(html, context);
     var experimental = html.attributes['experimental'] == 'true';
     var deprecated = html.attributes['deprecated'] == 'true';
-    return TypeDefinition(name, type, html,
+    return TypeDefinition(name!, type, html,
         experimental: experimental, deprecated: deprecated);
   }
 
@@ -500,7 +500,7 @@
     }
     var value = html.attributes['value'];
     var type = processContentsAsType(html, context);
-    return TypeObjectField(name, type, html,
+    return TypeObjectField(name!, type, html,
         optional: optional, value: value, deprecated: deprecated);
   }
 
@@ -541,7 +541,7 @@
         var api = reader.readApi();
         for (var typeDefinition in api.types) {
           typeDefinition.isExternal = true;
-          childElements.add(typeDefinition.html);
+          childElements.add(typeDefinition.html!);
           typeMap[typeDefinition.name] = typeDefinition;
         }
       },
diff --git a/pkg/analyzer_plugin/tool/spec/implied_types.dart b/pkg/analyzer_plugin/tool/spec/implied_types.dart
index 04f217c..21e2639 100644
--- a/pkg/analyzer_plugin/tool/spec/implied_types.dart
+++ b/pkg/analyzer_plugin/tool/spec/implied_types.dart
@@ -16,7 +16,7 @@
 class ImpliedType {
   final String camelName;
   final String humanReadableName;
-  final TypeDecl type;
+  final TypeDecl? type;
 
   /// Kind of implied type this is. One of:
   /// - 'requestParams'
@@ -39,7 +39,7 @@
 
   _ImpliedTypesVisitor(Api api) : super(api);
 
-  void storeType(String name, String nameSuffix, TypeDecl type, String kind,
+  void storeType(String name, String? nameSuffix, TypeDecl? type, String kind,
       ApiNode apiNode) {
     var humanReadableName = name;
     var camelNameParts = name.split('.');
diff --git a/pkg/analyzer_plugin/tool/spec/to_html.dart b/pkg/analyzer_plugin/tool/spec/to_html.dart
index 8c9ea33..b2d4d67 100644
--- a/pkg/analyzer_plugin/tool/spec/to_html.dart
+++ b/pkg/analyzer_plugin/tool/spec/to_html.dart
@@ -148,7 +148,7 @@
 
   @override
   void visitDomain(Domain domain) {
-    domains[domain.html] = domain;
+    domains[domain.html!] = domain;
   }
 }
 
@@ -170,11 +170,11 @@
   void dt(String cls, void Function() callback) =>
       element('dt', {'class': cls}, callback);
   void element(String name, Map<Object, String> attributes,
-      [void Function() callback]);
+      [void Function()? callback]);
   void gray(void Function() callback) =>
       element('span', {'style': 'color:#999999'}, callback);
   void h1(void Function() callback) => element('h1', {}, callback);
-  void h2(String cls, void Function() callback) {
+  void h2(String? cls, void Function() callback) {
     if (cls == null) {
       return element('h2', {}, callback);
     }
@@ -191,7 +191,7 @@
   void i(void Function() callback) => element('i', {}, callback);
   void li(void Function() callback) => element('li', {}, callback);
   void link(String id, void Function() callback,
-      [Map<dynamic, String> attributes]) {
+      [Map<Object, String>? attributes]) {
     attributes ??= {};
     attributes['href'] = '#$id';
     element('a', attributes, callback);
@@ -226,7 +226,7 @@
   ///
   /// If [force] is true, then a section is inserted even if the payload is
   /// null.
-  void describePayload(TypeObject subType, String name, {bool force = false}) {
+  void describePayload(TypeObject? subType, String name, {bool force = false}) {
     if (force || subType != null) {
       h4(() {
         write(name);
@@ -279,7 +279,7 @@
     }
 
     generateTypesIndex(definedTypes);
-    generateRefactoringsIndex(api.refactorings);
+    generateRefactoringsIndex(api.refactorings!);
   }
 
   void generateNotificationsIndex(Iterable<Notification> notifications) {
@@ -298,9 +298,6 @@
   }
 
   void generateRefactoringsIndex(Iterable<Refactoring> refactorings) {
-    if (refactorings == null) {
-      return;
-    }
     h3(() {
       write('Refactorings');
       write(' (');
@@ -384,13 +381,11 @@
   }
 
   void javadocParams(TypeObject typeObject) {
-    if (typeObject != null) {
-      for (var field in typeObject.fields) {
-        hangingIndent(() {
-          write('@param ${field.name} ');
-          translateHtml(field.html, squashParagraphs: true);
-        });
-      }
+    for (var field in typeObject.fields) {
+      hangingIndent(() {
+        write('@param ${field.name} ');
+        translateHtml(field.html, squashParagraphs: true);
+      });
     }
   }
 
@@ -401,7 +396,8 @@
   ///
   /// If [typeForBolding] is supplied, then fields in this type are shown in
   /// boldface.
-  void showType(String shortDesc, TypeDecl type, [TypeObject typeForBolding]) {
+  void showType(String? shortDesc, TypeDecl type,
+      [TypeObject? typeForBolding]) {
     var fieldsToBold = <String>{};
     if (typeForBolding != null) {
       for (var field in typeForBolding.fields) {
@@ -421,7 +417,10 @@
 
   /// Copy the contents of the given HTML element, translating the special
   /// elements that define the API appropriately.
-  void translateHtml(dom.Element html, {bool squashParagraphs = false}) {
+  void translateHtml(dom.Element? html, {bool squashParagraphs = false}) {
+    if (html == null) {
+      return;
+    }
     for (var node in html.nodes) {
       if (node is dom.Element) {
         if (squashParagraphs && node.localName == 'p') {
@@ -433,7 +432,7 @@
             generateDomainsHeader();
             break;
           case 'domain':
-            visitDomain(apiMappings.domains[node]);
+            visitDomain(apiMappings.domains[node]!);
             break;
           case 'head':
             head(() {
@@ -466,7 +465,7 @@
             break;
           default:
             if (!ApiReader.specialElements.contains(node.localName)) {
-              element(node.localName, node.attributes, () {
+              element(node.localName!, node.attributes, () {
                 translateHtml(node, squashParagraphs: squashParagraphs);
               });
             }
@@ -547,8 +546,8 @@
   }
 
   @override
-  void visitRefactorings(Refactorings refactorings) {
-    translateHtml(refactorings.html);
+  void visitRefactorings(Refactorings? refactorings) {
+    translateHtml(refactorings?.html);
     dl(() {
       super.visitRefactorings(refactorings);
     });
@@ -609,7 +608,7 @@
   @override
   void visitTypeEnumValue(TypeEnumValue typeEnumValue) {
     var isDocumented = false;
-    for (var node in typeEnumValue.html.nodes) {
+    for (var node in typeEnumValue.html?.nodes ?? []) {
       if ((node is dom.Element && node.localName != 'code') ||
           (node is dom.Text && node.text.trim().isNotEmpty)) {
         isDocumented = true;
@@ -701,7 +700,7 @@
     with HtmlMixin, HtmlCodeGenerator {
   /// Set of fields which should be shown in boldface, or null if no field
   /// should be shown in boldface.
-  final Set<String> fieldsToBold;
+  final Set<String>? fieldsToBold;
 
   /// True if a short description should be generated. In a short description,
   /// objects are shown as simply "object", and enums are shown as "String".
@@ -750,6 +749,7 @@
     indent(() {
       for (var field in typeObject.fields) {
         write('"');
+        var fieldsToBold = this.fieldsToBold;
         if (fieldsToBold != null && fieldsToBold.contains(field.name)) {
           b(() {
             write(field.name);
diff --git a/pkg/compiler/lib/src/commandline_options.dart b/pkg/compiler/lib/src/commandline_options.dart
index e0c45c8..45b02a0 100644
--- a/pkg/compiler/lib/src/commandline_options.dart
+++ b/pkg/compiler/lib/src/commandline_options.dart
@@ -106,6 +106,7 @@
   static const String dillDependencies = '--dill-dependencies';
   static const String readData = '--read-data';
   static const String writeData = '--write-data';
+  static const String noClosedWorldInData = '--no-closed-world-in-data';
   static const String writeClosedWorld = '--write-closed-world';
   static const String readClosedWorld = '--read-closed-world';
   static const String readCodegen = '--read-codegen';
diff --git a/pkg/compiler/lib/src/compiler.dart b/pkg/compiler/lib/src/compiler.dart
index e921146..8f52c10 100644
--- a/pkg/compiler/lib/src/compiler.dart
+++ b/pkg/compiler/lib/src/compiler.dart
@@ -20,7 +20,6 @@
 import 'common_elements.dart' show ElementEnvironment;
 import 'deferred_load.dart' show DeferredLoadTask, OutputUnitData;
 import 'diagnostics/code_location.dart';
-import 'diagnostics/diagnostic_listener.dart' show DiagnosticReporter;
 import 'diagnostics/messages.dart' show Message, MessageTemplate;
 import 'dump_info.dart' show DumpInfoTask;
 import 'elements/entities.dart';
@@ -237,6 +236,10 @@
         options.readCodegenUri == null;
   }
 
+  bool get onlyPerformCodegen {
+    return options.readClosedWorldUri != null && options.readDataUri != null;
+  }
+
   Future runInternal(Uri uri) async {
     clearState();
     assert(uri != null);
@@ -251,30 +254,32 @@
       GlobalTypeInferenceResults globalTypeInferenceResults =
           performGlobalTypeInference(closedWorld);
       if (options.writeDataUri != null) {
-        serializationTask
-            .serializeGlobalTypeInference(globalTypeInferenceResults);
+        if (options.noClosedWorldInData) {
+          serializationTask
+              .serializeGlobalTypeInference(globalTypeInferenceResults);
+        } else {
+          serializationTask
+              .serializeGlobalTypeInferenceLegacy(globalTypeInferenceResults);
+        }
         return;
       }
       await generateJavaScriptCode(globalTypeInferenceResults);
-    } else if (options.readDataUri != null) {
+    } else if (onlyPerformCodegen) {
       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;
-      }
+      ir.Component component =
+          await serializationTask.deserializeComponentAndUpdateOptions();
+      JsClosedWorld closedWorld =
+          await serializationTask.deserializeClosedWorld(
+              environment, abstractValueStrategy, component);
+      globalTypeInferenceResults =
+          await serializationTask.deserializeGlobalTypeInferenceResults(
+              environment, abstractValueStrategy, component, closedWorld);
+      await generateJavaScriptCode(globalTypeInferenceResults);
+    } else if (options.readDataUri != null) {
+      // TODO(joshualitt) delete and clean up after google3 roll
+      var globalTypeInferenceResults =
+          await serializationTask.deserializeGlobalTypeInferenceLegacy(
+              environment, abstractValueStrategy);
       await generateJavaScriptCode(globalTypeInferenceResults);
     } else {
       KernelResult result = await kernelLoader.load(uri);
@@ -445,14 +450,18 @@
       GlobalTypeInferenceResults results) {
     SerializationStrategy strategy = const BytesInMemorySerializationStrategy();
     List<int> irData = strategy.unpackAndSerializeComponent(results);
-    List worldData = strategy.serializeGlobalTypeInferenceResults(results);
+    List<int> closedWorldData =
+        strategy.serializeClosedWorld(results.closedWorld);
+    List<int> globalTypeInferenceResultsData =
+        strategy.serializeGlobalTypeInferenceResults(results);
     return strategy.deserializeGlobalTypeInferenceResults(
         options,
         reporter,
         environment,
         abstractValueStrategy,
         strategy.deserializeComponent(irData),
-        worldData);
+        closedWorldData,
+        globalTypeInferenceResultsData);
   }
 
   void compileFromKernel(Uri rootLibraryUri, Iterable<Uri> libraries) {
@@ -476,7 +485,14 @@
       GlobalTypeInferenceResults globalInferenceResults =
           performGlobalTypeInference(closedWorld);
       if (options.writeDataUri != null) {
-        serializationTask.serializeGlobalTypeInference(globalInferenceResults);
+        // TODO(joshualitt) delete after google3 roll.
+        if (options.noClosedWorldInData) {
+          serializationTask
+              .serializeGlobalTypeInference(globalInferenceResults);
+        } else {
+          serializationTask
+              .serializeGlobalTypeInferenceLegacy(globalInferenceResults);
+        }
         return;
       }
       if (options.testMode) {
diff --git a/pkg/compiler/lib/src/constants/constant_system.dart b/pkg/compiler/lib/src/constants/constant_system.dart
index 11ac356..b10c628 100644
--- a/pkg/compiler/lib/src/constants/constant_system.dart
+++ b/pkg/compiler/lib/src/constants/constant_system.dart
@@ -36,6 +36,7 @@
 const remainder = const RemainderOperation();
 const shiftLeft = const ShiftLeftOperation();
 const shiftRight = const ShiftRightOperation();
+const shiftRightUnsigned = const ShiftRightUnsignedOperation();
 const subtract = const SubtractOperation();
 const truncatingDivide = const TruncatingDivideOperation();
 const codeUnitAt = const CodeUnitAtOperation();
@@ -472,6 +473,24 @@
   apply(left, right) => left >> right;
 }
 
+class ShiftRightUnsignedOperation extends BinaryBitOperation {
+  @override
+  final String name = '>>>';
+
+  const ShiftRightUnsignedOperation();
+
+  @override
+  BigInt foldInts(BigInt left, BigInt right) {
+    if (right < BigInt.zero) return null;
+    return left.toUnsigned(32) >> right.toInt();
+  }
+
+  @override
+  apply(left, right) {
+    throw UnimplementedError('ShiftRightUnsignedOperation.apply');
+  }
+}
+
 abstract class BinaryBoolOperation implements BinaryOperation {
   const BinaryBoolOperation();
 
diff --git a/pkg/compiler/lib/src/dart2js.dart b/pkg/compiler/lib/src/dart2js.dart
index d4a9558..b96bd5d 100644
--- a/pkg/compiler/lib/src/dart2js.dart
+++ b/pkg/compiler/lib/src/dart2js.dart
@@ -277,8 +277,15 @@
     if (argument != Flags.readData) {
       readDataUri = fe.nativeToUri(extractPath(argument, isDirectory: false));
     }
-    if (readStrategy != ReadStrategy.fromCodegen) {
+
+    if (readStrategy == ReadStrategy.fromDart) {
       readStrategy = ReadStrategy.fromData;
+    } else if (readStrategy == ReadStrategy.fromClosedWorld) {
+      readStrategy = ReadStrategy.fromDataAndClosedWorld;
+    } else if (readStrategy == ReadStrategy.fromCodegen) {
+      readStrategy = ReadStrategy.fromCodegenAndData;
+    } else if (readStrategy == ReadStrategy.fromCodegenAndClosedWorld) {
+      readStrategy = ReadStrategy.fromCodegenAndClosedWorldAndData;
     }
   }
 
@@ -287,7 +294,16 @@
       readClosedWorldUri =
           fe.nativeToUri(extractPath(argument, isDirectory: false));
     }
-    readStrategy = ReadStrategy.fromClosedWorld;
+
+    if (readStrategy == ReadStrategy.fromDart) {
+      readStrategy = ReadStrategy.fromClosedWorld;
+    } else if (readStrategy == ReadStrategy.fromData) {
+      readStrategy = ReadStrategy.fromDataAndClosedWorld;
+    } else if (readStrategy == ReadStrategy.fromCodegen) {
+      readStrategy = ReadStrategy.fromCodegenAndClosedWorld;
+    } else if (readStrategy == ReadStrategy.fromCodegenAndData) {
+      readStrategy = ReadStrategy.fromCodegenAndClosedWorldAndData;
+    }
   }
 
   void setDillDependencies(String argument) {
@@ -318,7 +334,16 @@
       readCodegenUri =
           fe.nativeToUri(extractPath(argument, isDirectory: false));
     }
-    readStrategy = ReadStrategy.fromCodegen;
+
+    if (readStrategy == ReadStrategy.fromDart) {
+      readStrategy = ReadStrategy.fromCodegen;
+    } else if (readStrategy == ReadStrategy.fromClosedWorld) {
+      readStrategy = ReadStrategy.fromCodegenAndClosedWorld;
+    } else if (readStrategy == ReadStrategy.fromData) {
+      readStrategy = ReadStrategy.fromCodegenAndData;
+    } else if (readStrategy == ReadStrategy.fromDataAndClosedWorld) {
+      readStrategy = ReadStrategy.fromCodegenAndClosedWorldAndData;
+    }
   }
 
   void setWriteData(String argument) {
@@ -466,6 +491,7 @@
     new OptionHandler('${Flags.dillDependencies}=.+', setDillDependencies),
     new OptionHandler('${Flags.readData}|${Flags.readData}=.+', setReadData),
     new OptionHandler('${Flags.writeData}|${Flags.writeData}=.+', setWriteData),
+    new OptionHandler(Flags.noClosedWorldInData, passThrough),
     new OptionHandler('${Flags.readClosedWorld}|${Flags.readClosedWorld}=.+',
         setReadClosedWorld),
     new OptionHandler('${Flags.writeClosedWorld}|${Flags.writeClosedWorld}=.+',
@@ -709,7 +735,9 @@
       if (readStrategy == ReadStrategy.fromCodegen) {
         fail("Cannot read and write serialized codegen simultaneously.");
       }
-      if (readStrategy != ReadStrategy.fromData) {
+      // TODO(joshualitt) cleanup after google3 roll.
+      if (readStrategy != ReadStrategy.fromData &&
+          readStrategy != ReadStrategy.fromDataAndClosedWorld) {
         fail("Can only write serialized codegen from serialized data.");
       }
       if (codegenShards == null) {
@@ -737,6 +765,8 @@
       options.add('${Flags.readClosedWorld}=${readClosedWorldUri}');
       break;
     case ReadStrategy.fromData:
+      // TODO(joshualitt): fail after Google3 roll.
+      // fail("Must read from closed world and data.");
       readDataUri ??= Uri.base.resolve('$scriptName.data');
       options.add('${Flags.readData}=${readDataUri}');
       break;
@@ -747,6 +777,8 @@
       options.add('${Flags.readData}=${readDataUri}');
       break;
     case ReadStrategy.fromCodegen:
+    case ReadStrategy.fromCodegenAndData:
+      // TODO(joshualitt): fall through to fail after google3 roll.
       readDataUri ??= Uri.base.resolve('$scriptName.data');
       options.add('${Flags.readData}=${readDataUri}');
       readCodegenUri ??= Uri.base.resolve('$scriptName.code');
@@ -760,6 +792,9 @@
       options.add('${Flags.codegenShards}=$codegenShards');
       break;
     case ReadStrategy.fromCodegenAndClosedWorld:
+      fail("Must read from closed world, data, and codegen");
+      break;
+    case ReadStrategy.fromCodegenAndClosedWorldAndData:
       readClosedWorldUri ??= Uri.base.resolve('$scriptName.world');
       options.add('${Flags.readClosedWorld}=${readClosedWorldUri}');
       readDataUri ??= Uri.base.resolve('$scriptName.data');
@@ -816,6 +851,8 @@
         summary = 'Data files $input and $dataInput ';
         break;
       case ReadStrategy.fromData:
+        // TODO(joshualitt): fail after google3 roll.
+        //fail("Must read from closed world and data.");
         inputName = 'bytes data';
         inputSize = inputProvider.dartCharactersRead;
         String dataInput =
@@ -832,6 +869,8 @@
         summary = 'Data files $input, $worldInput, and $dataInput ';
         break;
       case ReadStrategy.fromCodegen:
+      case ReadStrategy.fromCodegenAndData:
+        // TODO(joshualitt): Fall through to fail after google3 roll.
         inputName = 'bytes data';
         inputSize = inputProvider.dartCharactersRead;
         String dataInput =
@@ -842,6 +881,9 @@
             '${codeInput}[0-${codegenShards - 1}] ';
         break;
       case ReadStrategy.fromCodegenAndClosedWorld:
+        fail("Must read from closed world, data, and codegen");
+        break;
+      case ReadStrategy.fromCodegenAndClosedWorldAndData:
         inputName = 'bytes data';
         inputSize = inputProvider.dartCharactersRead;
         String worldInput =
@@ -1373,12 +1415,17 @@
   });
 }
 
+// TODO(joshualitt): Clean up the combinatorial explosion of read strategies.
+// Right now only fromClosedWorld, fromDataAndClosedWorld, and
+// fromCodegenAndClosedWorldAndData are valid.
 enum ReadStrategy {
   fromDart,
   fromClosedWorld,
   fromData,
   fromDataAndClosedWorld,
   fromCodegen,
-  fromCodegenAndClosedWorld
+  fromCodegenAndClosedWorld,
+  fromCodegenAndData,
+  fromCodegenAndClosedWorldAndData,
 }
 enum WriteStrategy { toKernel, toClosedWorld, toData, toCodegen, toJs }
diff --git a/pkg/compiler/lib/src/deferred_load.dart b/pkg/compiler/lib/src/deferred_load.dart
index a78e3bfc4..974e8a0 100644
--- a/pkg/compiler/lib/src/deferred_load.dart
+++ b/pkg/compiler/lib/src/deferred_load.dart
@@ -14,8 +14,7 @@
 import 'common/metrics.dart' show Metric, Metrics, CountMetric, DurationMetric;
 import 'common/tasks.dart' show CompilerTask;
 import 'common.dart';
-import 'common_elements.dart'
-    show CommonElements, ElementEnvironment, KElementEnvironment;
+import 'common_elements.dart' show CommonElements, KElementEnvironment;
 import 'compiler.dart' show Compiler;
 import 'constants/values.dart'
     show
@@ -80,13 +79,6 @@
     return name.compareTo(other.name);
   }
 
-  void merge(OutputUnit that) {
-    assert(this != that);
-    // We don't currently support merging code into the main output unit.
-    assert(!isMainOutput);
-    this.imports.addAll(that.imports);
-  }
-
   @override
   String toString() => "OutputUnit($name, $imports)";
 }
@@ -96,13 +88,13 @@
   String get namespace => 'deferred_load';
 
   DurationMetric time = DurationMetric('time');
-  CountMetric hunkListElements = CountMetric('hunkListElements');
+  CountMetric outputUnitElements = CountMetric('outputUnitElements');
 
   @override
   Iterable<Metric> get primary => [time];
 
   @override
-  Iterable<Metric> get secondary => [hunkListElements];
+  Iterable<Metric> get secondary => [outputUnitElements];
 }
 
 /// For each deferred import, find elements and constants to be loaded when that
@@ -126,7 +118,7 @@
 
   /// A cache of the result of calling `computeImportDeferName` on the keys of
   /// this map.
-  final Map<ImportEntity, String> _importDeferName = {};
+  final Map<ImportEntity, String> importDeferName = {};
 
   /// A mapping from classes to their import set.
   Map<ClassEntity, ImportSet> _classToSet = {};
@@ -662,6 +654,7 @@
       counter++;
       importSet.unit = unit;
       _allOutputUnits.add(unit);
+      metrics.outputUnitElements.add(1);
     }
 
     // Generate an output unit for all import sets that are associated with an
@@ -676,8 +669,7 @@
     _allOutputUnits.sort();
   }
 
-  Map<String, List<OutputUnit>> _setupHunksToLoad() {
-    Map<String, List<OutputUnit>> hunksToLoad = {};
+  void _setupImportNames() {
     Set<String> usedImportNames = {};
 
     for (ImportEntity import in _allDeferredImports) {
@@ -686,38 +678,8 @@
       // Note: tools that process the json file to build multi-part initial load
       // bundles depend on the fact that makeUnique appends only digits, or a
       // period followed by digits.
-      _importDeferName[import] = makeUnique(result, usedImportNames, '.');
+      importDeferName[import] = makeUnique(result, usedImportNames, '.');
     }
-
-    // Sort the output units in descending order of the number of imports they
-    // include.
-
-    // The loading of the output units must be ordered because a superclass
-    // needs to be initialized before its subclass.
-    // But a class can only depend on another class in an output unit shared by
-    // a strict superset of the imports:
-    // By contradiction: Assume a class C in output unit shared by imports in
-    // the set S1 = (lib1,.., lib_n) depends on a class D in an output unit
-    // shared by S2 such that S2 not a superset of S1. Let lib_s be a library in
-    // S1 not in S2. lib_s must depend on C, and then in turn on D. Therefore D
-    // is not in the right output unit.
-    List<OutputUnit> sortedOutputUnits = _allOutputUnits.reversed.toList();
-
-    // For each deferred import we find out which outputUnits to load.
-    for (ImportEntity import in _allDeferredImports) {
-      // We expect to find an entry for any call to `loadLibrary`, even if
-      // there is no code to load. In that case, the entry will be an empty
-      // list.
-      hunksToLoad[_importDeferName[import]] = [];
-      for (OutputUnit outputUnit in sortedOutputUnits) {
-        if (outputUnit == _mainOutputUnit) continue;
-        if (outputUnit.imports.contains(import)) {
-          hunksToLoad[_importDeferName[import]].add(outputUnit);
-          metrics.hunkListElements.add(1);
-        }
-      }
-    }
-    return hunksToLoad;
   }
 
   /// Returns a name for a deferred import.
@@ -865,6 +827,7 @@
     Map<ImportEntity, int> importMap = {};
     var entities = _deferredImportDescriptions.keys.toList();
     entities.sort(_compareImportEntities);
+    entities = entities.reversed.toList();
     for (var key in entities) {
       importMap[key] = id++;
     }
@@ -886,7 +849,7 @@
 
   OutputUnitData _buildResult() {
     _createOutputUnits();
-    Map<String, List<OutputUnit>> hunksToLoad = _setupHunksToLoad();
+    _setupImportNames();
     if (compiler.options.deferredGraphUri != null) {
       _dumpDeferredGraph();
     }
@@ -917,8 +880,7 @@
         localFunctionMap,
         constantMap,
         _allOutputUnits,
-        _importDeferName,
-        hunksToLoad,
+        importDeferName,
         _deferredImportDescriptions);
   }
 
@@ -1037,10 +999,10 @@
   /// The prefix this import is imported as.
   final String prefix;
 
-  final LibraryEntity _importingLibrary;
+  final LibraryEntity importingLibrary;
 
   ImportDescription.internal(
-      this.importingUri, this.prefix, this._importingLibrary);
+      this.importingUri, this.prefix, this.importingLibrary);
 
   ImportDescription(
       ImportEntity import, LibraryEntity importingLibrary, Uri mainLibraryUri)
@@ -1418,20 +1380,11 @@
   final Map<Local, OutputUnit> _localFunctionToUnit;
   final Map<ConstantValue, OutputUnit> _constantToUnit;
   final List<OutputUnit> outputUnits;
-  final Map<ImportEntity, String> _importDeferName;
-
-  /// A mapping from the name of a defer import to all the output units it
-  /// depends on in a list of lists to be loaded in the order they appear.
-  ///
-  /// For example {"lib1": [[lib1_lib2_lib3], [lib1_lib2, lib1_lib3],
-  /// [lib1]]} would mean that in order to load "lib1" first the hunk
-  /// lib1_lib2_lib2 should be loaded, then the hunks lib1_lib2 and lib1_lib3
-  /// can be loaded in parallel. And finally lib1 can be loaded.
-  final Map<String, List<OutputUnit>> hunksToLoad;
+  final Map<ImportEntity, String> importDeferName;
 
   /// Because the token-stream is forgotten later in the program, we cache a
   /// description of each deferred import.
-  final Map<ImportEntity, ImportDescription> _deferredImportDescriptions;
+  final Map<ImportEntity, ImportDescription> deferredImportDescriptions;
 
   OutputUnitData(
       this.isProgramSplit,
@@ -1442,9 +1395,8 @@
       this._localFunctionToUnit,
       this._constantToUnit,
       this.outputUnits,
-      this._importDeferName,
-      this.hunksToLoad,
-      this._deferredImportDescriptions);
+      this.importDeferName,
+      this.deferredImportDescriptions);
 
   // Creates J-world data from the K-world data.
   factory OutputUnitData.from(
@@ -1467,12 +1419,12 @@
     Map<ConstantValue, OutputUnit> constantToUnit =
         convertConstantMap(other._constantToUnit);
     Map<ImportEntity, ImportDescription> deferredImportDescriptions = {};
-    other._deferredImportDescriptions
+    other.deferredImportDescriptions
         .forEach((ImportEntity import, ImportDescription description) {
       deferredImportDescriptions[import] = ImportDescription.internal(
           description.importingUri,
           description.prefix,
-          convertLibrary(description._importingLibrary));
+          convertLibrary(description.importingLibrary));
     });
 
     return OutputUnitData(
@@ -1485,8 +1437,7 @@
         const {},
         constantToUnit,
         other.outputUnits,
-        other._importDeferName,
-        other.hunksToLoad,
+        other.importDeferName,
         deferredImportDescriptions);
   }
 
@@ -1517,11 +1468,6 @@
     });
     Map<ImportEntity, String> importDeferName =
         source.readImportMap(source.readString);
-    Map<String, List<OutputUnit>> hunksToLoad = source.readStringMap(() {
-      return source.readList(() {
-        return outputUnits[source.readInt()];
-      });
-    });
     Map<ImportEntity, ImportDescription> deferredImportDescriptions =
         source.readImportMap(() {
       String importingUri = source.readString();
@@ -1541,7 +1487,6 @@
         constantToUnit,
         outputUnits,
         importDeferName,
-        hunksToLoad,
         deferredImportDescriptions);
   }
 
@@ -1570,18 +1515,12 @@
     sink.writeConstantMap(_constantToUnit, (OutputUnit outputUnit) {
       sink.writeInt(outputUnitIndices[outputUnit]);
     });
-    sink.writeImportMap(_importDeferName, sink.writeString);
-    sink.writeStringMap(hunksToLoad, (List<OutputUnit> outputUnits) {
-      sink.writeList(
-          outputUnits,
-          (OutputUnit outputUnit) =>
-              sink.writeInt(outputUnitIndices[outputUnit]));
-    });
-    sink.writeImportMap(_deferredImportDescriptions,
+    sink.writeImportMap(importDeferName, sink.writeString);
+    sink.writeImportMap(deferredImportDescriptions,
         (ImportDescription importDescription) {
       sink.writeString(importDescription.importingUri);
       sink.writeString(importDescription.prefix);
-      sink.writeLibrary(importDescription._importingLibrary);
+      sink.writeLibrary(importDescription.importingLibrary);
     });
     sink.end(tag);
   }
@@ -1696,7 +1635,7 @@
 
   /// Returns the unique name for the given deferred [import].
   String getImportDeferName(Spannable node, ImportEntity import) {
-    String name = _importDeferName[import];
+    String name = importDeferName[import];
     if (name == null) {
       throw SpannableAssertionFailure(node, "No deferred name for $import.");
     }
@@ -1705,48 +1644,7 @@
 
   /// Returns the names associated with each deferred import in [unit].
   Iterable<String> getImportNames(OutputUnit unit) {
-    return unit.imports.map((i) => _importDeferName[i]);
-  }
-
-  /// Returns a json-style map for describing what files that are loaded by a
-  /// given deferred import.
-  /// The mapping is structured as:
-  /// library uri -> {"name": library name, "files": (prefix -> list of files)}
-  /// Where
-  ///
-  /// - <library uri> is the relative uri of the library making a deferred
-  ///   import.
-  /// - <library name> is the name of the library, or "<unnamed>" if it is
-  ///   unnamed.
-  /// - <prefix> is the `as` prefix used for a given deferred import.
-  /// - <list of files> is a list of the filenames the must be loaded when that
-  ///   import is loaded.
-  Map<String, Map<String, dynamic>> computeDeferredMap(
-      CompilerOptions options, ElementEnvironment elementEnvironment,
-      {Set<OutputUnit> omittedUnits}) {
-    omittedUnits ??= Set();
-    Map<String, Map<String, dynamic>> mapping = {};
-
-    _deferredImportDescriptions.keys.forEach((ImportEntity import) {
-      List<OutputUnit> outputUnits = hunksToLoad[_importDeferName[import]];
-      ImportDescription description = _deferredImportDescriptions[import];
-      String getName(LibraryEntity library) {
-        var name = elementEnvironment.getLibraryName(library);
-        return name == '' ? '<unnamed>' : name;
-      }
-
-      Map<String, dynamic> libraryMap = mapping.putIfAbsent(
-          description.importingUri,
-          () =>
-              {"name": getName(description._importingLibrary), "imports": {}});
-
-      List<String> partFileNames = outputUnits
-          .where((outputUnit) => !omittedUnits.contains(outputUnit))
-          .map((outputUnit) => deferredPartFileName(options, outputUnit.name))
-          .toList();
-      libraryMap["imports"][_importDeferName[import]] = partFileNames;
-    });
-    return mapping;
+    return unit.imports.map((i) => importDeferName[i]);
   }
 }
 
diff --git a/pkg/compiler/lib/src/dump_info.dart b/pkg/compiler/lib/src/dump_info.dart
index 882895c..aff886a 100644
--- a/pkg/compiler/lib/src/dump_info.dart
+++ b/pkg/compiler/lib/src/dump_info.dart
@@ -651,8 +651,11 @@
       }
     }
 
-    result.deferredFiles = closedWorld.outputUnitData
-        .computeDeferredMap(compiler.options, closedWorld.elementEnvironment);
+    var fragmentsToLoad =
+        compiler.backendStrategy.emitterTask.emitter.finalizedFragmentsToLoad;
+    var fragmentMerger =
+        compiler.backendStrategy.emitterTask.emitter.fragmentMerger;
+    result.deferredFiles = fragmentMerger.computeDeferredMap(fragmentsToLoad);
     stopwatch.stop();
 
     result.program = new ProgramInfo(
diff --git a/pkg/compiler/lib/src/elements/operators.dart b/pkg/compiler/lib/src/elements/operators.dart
index 4f3e95c..182511b 100644
--- a/pkg/compiler/lib/src/elements/operators.dart
+++ b/pkg/compiler/lib/src/elements/operators.dart
@@ -152,7 +152,7 @@
 
   /// The binary >>> operator.
   static const BinaryOperator SHRU =
-      const BinaryOperator._(BinaryOperatorKind.SHRU, '>>');
+      const BinaryOperator._(BinaryOperatorKind.SHRU, '>>>');
 
   /// The binary >= operator.
   static const BinaryOperator GTEQ =
diff --git a/pkg/compiler/lib/src/elements/types.dart b/pkg/compiler/lib/src/elements/types.dart
index 4c261da..41e58eb 100644
--- a/pkg/compiler/lib/src/elements/types.dart
+++ b/pkg/compiler/lib/src/elements/types.dart
@@ -1381,7 +1381,7 @@
 
   @override
   bool visitNeverType(NeverType type, List<FunctionTypeVariable> bindings) =>
-      false;
+      handleNeverType(type);
 
   @override
   bool visitVoidType(VoidType type, List<FunctionTypeVariable> bindings) =>
diff --git a/pkg/compiler/lib/src/helpers/helpers.dart b/pkg/compiler/lib/src/helpers/helpers.dart
index 910485e9..a59366a 100644
--- a/pkg/compiler/lib/src/helpers/helpers.dart
+++ b/pkg/compiler/lib/src/helpers/helpers.dart
@@ -10,7 +10,6 @@
 import '../common.dart';
 import '../diagnostics/invariant.dart' show DEBUG_MODE;
 import '../util/util.dart';
-import 'trace.dart';
 
 export 'debug_collection.dart';
 export 'expensive_map.dart';
diff --git a/pkg/compiler/lib/src/inferrer/builder_kernel.dart b/pkg/compiler/lib/src/inferrer/builder_kernel.dart
index 17d63df..aebbf7b 100644
--- a/pkg/compiler/lib/src/inferrer/builder_kernel.dart
+++ b/pkg/compiler/lib/src/inferrer/builder_kernel.dart
@@ -919,20 +919,23 @@
         node, node.variable.parent, node.arguments, selector);
   }
 
-  TypeInformation _handleEqualsNull(ir.Expression node, ir.Expression operand,
-      {bool isNot}) {
-    assert(isNot != null);
-    _potentiallyAddNullCheck(node, operand, isNot: isNot);
-    return _types.boolType;
-  }
-
   @override
   TypeInformation visitEqualsNull(ir.EqualsNull node) {
-    // TODO(johnniwinther). This triggers the computation of the mask for the
-    // receiver of the call to `==`, which doesn't happen in this case. Remove
-    // this when the ssa builder recognized `== null` directly.
-    _typeOfReceiver(node, node.expression);
-    return _handleEqualsNull(node, node.expression, isNot: node.isNot);
+    visit(node.expression);
+    if (node.fileOffset < node.expression.fileOffset) {
+      // Hack to detect `null == o`.
+      // TODO(johnniwinther): Remove this after the new method invocation has
+      //  landed stably. This is only included to make the transition a no-op.
+      KernelGlobalTypeInferenceElementData data = _memberData;
+      data.setReceiverTypeMask(node, _closedWorld.abstractValueDomain.nullType);
+    } else {
+      // TODO(johnniwinther). This triggers the computation of the mask for the
+      // receiver of the call to `==`, which doesn't happen in this case. Remove
+      // this when the ssa builder recognized `== null` directly.
+      _typeOfReceiver(node, node.expression);
+    }
+    _potentiallyAddNullCheck(node, node.expression);
+    return _types.boolType;
   }
 
   TypeInformation _handleMethodInvocation(
@@ -947,8 +950,8 @@
       _checkIfExposesThis(
           selector, _types.newTypedSelector(receiverType, mask));
     }
-    TypeInformation type = handleDynamicInvoke(
-        CallType.access, node, selector, mask, receiverType, arguments);
+    TypeInformation type = handleDynamicInvoke(CallType.access, node, selector,
+        mask, receiverType, arguments, _getVariableDeclaration(receiver));
     if (interfaceTarget != null) {
       if (interfaceTarget is ir.Procedure &&
           (interfaceTarget.kind == ir.ProcedureKind.Method ||
@@ -975,20 +978,30 @@
     return type;
   }
 
-  TypeInformation _handleEqualsCall(ir.Expression node, ir.Expression left,
-      TypeInformation leftType, ir.Expression right, TypeInformation rightType,
-      {bool isNot}) {
-    assert(isNot != null);
+  TypeInformation _handleEqualsCall(
+      ir.Expression node,
+      ir.Expression left,
+      TypeInformation leftType,
+      ir.Expression right,
+      TypeInformation rightType) {
     // TODO(johnniwinther). This triggers the computation of the mask for the
     // receiver of the call to `==`, which might not happen in this case. Remove
     // this when the ssa builder recognized `== null` directly.
     _typeOfReceiver(node, left);
-    if (_types.isNull(leftType)) {
-      // null == o
-      return _handleEqualsNull(node, right, isNot: isNot);
-    } else if (_types.isNull(rightType)) {
-      // o == null
-      return _handleEqualsNull(node, left, isNot: isNot);
+    bool leftIsNull = _types.isNull(leftType);
+    bool rightIsNull = _types.isNull(rightType);
+    if (leftIsNull) {
+      // [right] is `null` if [node] evaluates to `true`.
+      _potentiallyAddNullCheck(node, right);
+    }
+    if (rightIsNull) {
+      // [left] is `null` if [node] evaluates to `true`.
+      _potentiallyAddNullCheck(node, left);
+    }
+    if (leftIsNull || rightIsNull) {
+      // `left == right` where `left` and/or `right` is known to have type
+      // `Null` so we have no invocation to register.
+      return _types.boolType;
     }
     Selector selector = Selector.binaryOperator('==');
     ArgumentsTypes arguments = ArgumentsTypes([rightType], null);
@@ -1000,8 +1013,7 @@
   TypeInformation visitEqualsCall(ir.EqualsCall node) {
     TypeInformation leftType = visit(node.left);
     TypeInformation rightType = visit(node.right);
-    return _handleEqualsCall(node, node.left, leftType, node.right, rightType,
-        isNot: node.isNot);
+    return _handleEqualsCall(node, node.left, leftType, node.right, rightType);
   }
 
   @override
@@ -1015,6 +1027,17 @@
   }
 
   @override
+  TypeInformation visitInstanceGetterInvocation(
+      ir.InstanceGetterInvocation node) {
+    Selector selector = _elementMap.getSelector(node);
+    ir.Expression receiver = node.receiver;
+    TypeInformation receiverType = visit(receiver);
+    ArgumentsTypes arguments = analyzeArguments(node.arguments);
+    return _handleMethodInvocation(node, node.receiver, receiverType, selector,
+        arguments, node.interfaceTarget);
+  }
+
+  @override
   TypeInformation visitDynamicInvocation(ir.DynamicInvocation node) {
     Selector selector = _elementMap.getSelector(node);
     ir.Expression receiver = node.receiver;
@@ -1053,21 +1076,25 @@
     ArgumentsTypes arguments = analyzeArguments(node.arguments);
     if (selector.name == '==') {
       return _handleEqualsCall(node, node.receiver, receiverType,
-          node.arguments.positional.first, arguments.positional[0],
-          isNot: false);
+          node.arguments.positional.first, arguments.positional[0]);
     }
 
     return _handleMethodInvocation(node, node.receiver, receiverType, selector,
         arguments, node.interfaceTarget);
   }
 
+  ir.VariableDeclaration _getVariableDeclaration(ir.Expression node) {
+    return node is ir.VariableGet ? node.variable : null;
+  }
+
   TypeInformation _handleDynamic(
       CallType callType,
       ir.Node node,
       Selector selector,
       AbstractValue mask,
       TypeInformation receiverType,
-      ArgumentsTypes arguments) {
+      ArgumentsTypes arguments,
+      ir.VariableDeclaration variable) {
     assert(receiverType != null);
     if (_types.selectorNeedsUpdate(receiverType, mask)) {
       mask = receiverType == _types.dynamicType
@@ -1077,18 +1104,6 @@
           _analyzedMember, callType, node, selector, mask);
     }
 
-    ir.VariableDeclaration variable;
-    if (node is ir.MethodInvocation && node.receiver is ir.VariableGet) {
-      ir.VariableGet get = node.receiver;
-      variable = get.variable;
-    } else if (node is ir.PropertyGet && node.receiver is ir.VariableGet) {
-      ir.VariableGet get = node.receiver;
-      variable = get.variable;
-    } else if (node is ir.PropertySet && node.receiver is ir.VariableGet) {
-      ir.VariableGet get = node.receiver;
-      variable = get.variable;
-    }
-
     if (variable != null) {
       Local local = _localsMap.getLocalVariable(variable);
       if (!_capturedVariables.contains(local)) {
@@ -1105,10 +1120,14 @@
         inLoop: inLoop, isConditional: false);
   }
 
-  TypeInformation handleDynamicGet(ir.Node node, Selector selector,
-      AbstractValue mask, TypeInformation receiverType) {
+  TypeInformation handleDynamicGet(
+      ir.Node node,
+      Selector selector,
+      AbstractValue mask,
+      TypeInformation receiverType,
+      ir.VariableDeclaration variable) {
     return _handleDynamic(
-        CallType.access, node, selector, mask, receiverType, null);
+        CallType.access, node, selector, mask, receiverType, null, variable);
   }
 
   TypeInformation handleDynamicSet(
@@ -1116,10 +1135,11 @@
       Selector selector,
       AbstractValue mask,
       TypeInformation receiverType,
-      TypeInformation rhsType) {
+      TypeInformation rhsType,
+      ir.VariableDeclaration variable) {
     ArgumentsTypes arguments = new ArgumentsTypes([rhsType], null);
-    return _handleDynamic(
-        CallType.access, node, selector, mask, receiverType, arguments);
+    return _handleDynamic(CallType.access, node, selector, mask, receiverType,
+        arguments, variable);
   }
 
   TypeInformation handleDynamicInvoke(
@@ -1128,9 +1148,10 @@
       Selector selector,
       AbstractValue mask,
       TypeInformation receiverType,
-      ArgumentsTypes arguments) {
+      ArgumentsTypes arguments,
+      ir.VariableDeclaration variable) {
     return _handleDynamic(
-        callType, node, selector, mask, receiverType, arguments);
+        callType, node, selector, mask, receiverType, arguments, variable);
   }
 
   @override
@@ -1176,18 +1197,19 @@
       moveNextMask = _memberData.typeOfIteratorMoveNext(node);
 
       iteratorType = handleDynamicInvoke(CallType.forIn, node, iteratorSelector,
-          iteratorMask, expressionType, new ArgumentsTypes.empty());
+          iteratorMask, expressionType, new ArgumentsTypes.empty(), null);
     }
 
     handleDynamicInvoke(CallType.forIn, node, Selectors.moveNext, moveNextMask,
-        iteratorType, new ArgumentsTypes.empty());
+        iteratorType, new ArgumentsTypes.empty(), null);
     TypeInformation currentType = handleDynamicInvoke(
         CallType.forIn,
         node,
         Selectors.current,
         currentMask,
         iteratorType,
-        new ArgumentsTypes.empty());
+        new ArgumentsTypes.empty(),
+        null);
 
     Local variable = _localsMap.getLocalVariable(node.variable);
     DartType variableType = _localsMap.getLocalType(_elementMap, variable);
@@ -1596,7 +1618,8 @@
       _checkIfExposesThis(
           selector, _types.newTypedSelector(receiverType, mask));
     }
-    TypeInformation type = handleDynamicGet(node, selector, mask, receiverType);
+    TypeInformation type = handleDynamicGet(
+        node, selector, mask, receiverType, _getVariableDeclaration(receiver));
     if (interfaceTarget != null) {
       // Pull the type from kernel (instead of from the J-model) because the
       // interface target might be abstract and therefore not part of the
@@ -1672,7 +1695,8 @@
       _checkIfExposesThis(
           selector, _types.newTypedSelector(receiverType, mask));
     }
-    handleDynamicSet(node, selector, mask, receiverType, rhsType);
+    handleDynamicSet(node, selector, mask, receiverType, rhsType,
+        _getVariableDeclaration(receiver));
     return rhsType;
   }
 
@@ -1725,9 +1749,7 @@
     }
   }
 
-  void _potentiallyAddNullCheck(ir.Expression node, ir.Expression receiver,
-      {bool isNot}) {
-    assert(isNot != null);
+  void _potentiallyAddNullCheck(ir.Expression node, ir.Expression receiver) {
     if (!_accumulateIsChecks) return;
     if (receiver is ir.VariableGet) {
       Local local = _localsMap.getLocalVariable(receiver.variable);
@@ -1750,14 +1772,8 @@
           node,
           _closedWorld.commonElements.objectType,
           excludeNull: true);
-
-      if (isNot) {
-        _setStateAfter(
-            _state, stateAfterCheckWhenNotNull, stateAfterCheckWhenNull);
-      } else {
-        _setStateAfter(
-            _state, stateAfterCheckWhenNull, stateAfterCheckWhenNotNull);
-      }
+      _setStateAfter(
+          _state, stateAfterCheckWhenNull, stateAfterCheckWhenNotNull);
     }
   }
 
diff --git a/pkg/compiler/lib/src/inferrer/inferrer_engine.dart b/pkg/compiler/lib/src/inferrer/inferrer_engine.dart
index 02ae17c..45dea65 100644
--- a/pkg/compiler/lib/src/inferrer/inferrer_engine.dart
+++ b/pkg/compiler/lib/src/inferrer/inferrer_engine.dart
@@ -651,10 +651,24 @@
     // mimicks that ast inferrer which return `true` for [ast.Send] and
     // non-const [ast.NewExpression].
     if (initializer is ir.MethodInvocation ||
+        initializer is ir.InstanceInvocation ||
+        initializer is ir.InstanceGetterInvocation ||
+        initializer is ir.DynamicInvocation ||
+        initializer is ir.FunctionInvocation ||
+        initializer is ir.LocalFunctionInvocation ||
+        initializer is ir.EqualsNull ||
+        initializer is ir.EqualsCall ||
         initializer is ir.PropertyGet ||
+        initializer is ir.InstanceGet ||
+        initializer is ir.DynamicGet ||
+        initializer is ir.InstanceTearOff ||
+        initializer is ir.FunctionTearOff ||
         initializer is ir.PropertySet ||
+        initializer is ir.InstanceSet ||
+        initializer is ir.DynamicSet ||
         initializer is ir.StaticInvocation ||
         initializer is ir.StaticGet ||
+        initializer is ir.StaticTearOff ||
         initializer is ir.StaticSet ||
         initializer is ir.Let ||
         initializer is ir.ConstructorInvocation && !initializer.isConst) {
diff --git a/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart b/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
index f791743..02b8bab 100644
--- a/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
+++ b/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
@@ -1307,6 +1307,13 @@
         }
         return null;
 
+      case '>>>':
+        if (isEmpty(argument)) return tryLater();
+        if (isUInt31(receiver)) {
+          return inferrer.types.uint31Type;
+        }
+        return null;
+
       case '&':
         if (isEmpty(argument)) return tryLater();
         if (isUInt31(receiver) || isUInt31(argument)) {
diff --git a/pkg/compiler/lib/src/ir/debug.dart b/pkg/compiler/lib/src/ir/debug.dart
index 8e2adfa..3b9e11a 100644
--- a/pkg/compiler/lib/src/ir/debug.dart
+++ b/pkg/compiler/lib/src/ir/debug.dart
@@ -7,7 +7,6 @@
 library kernel.debug;
 
 import 'package:kernel/ast.dart';
-import 'package:kernel/visitor.dart';
 
 import '../util/util.dart' show Indentation, Tagging;
 
@@ -50,6 +49,37 @@
   }
 
   @override
+  visitStaticInvocation(StaticInvocation node) {
+    openNode(node, '${node.runtimeType}', {'target': '${node.target}'});
+    node.visitChildren(this);
+    closeNode();
+  }
+
+  @override
+  visitArguments(Arguments node) {
+    openNode(node, '${node.runtimeType}', {
+      'typeArgs': '${node.types}',
+      'positionalArgs': '${node.positional}',
+      'namedArgs': '${node.named}'
+    });
+    node.visitChildren(this);
+    closeNode();
+  }
+
+  @override
+  visitAsExpression(AsExpression node) {
+    openNode(node, '${node.runtimeType}',
+        {'operand': '${node.operand}', 'DartType': '${node.type}'});
+    node.visitChildren(this);
+    closeNode();
+  }
+
+  @override
+  visitStringLiteral(StringLiteral node) {
+    openAndCloseNode(node, '${node.runtimeType}', {'value': '${node.value}'});
+  }
+
+  @override
   void visitVariableDeclaration(VariableDeclaration node) {
     openNode(node, '${node.runtimeType}', {
       'name': '${node.name ?? '--unnamed--'}',
diff --git a/pkg/compiler/lib/src/ir/impact.dart b/pkg/compiler/lib/src/ir/impact.dart
index 1d8b365..803aed8 100644
--- a/pkg/compiler/lib/src/ir/impact.dart
+++ b/pkg/compiler/lib/src/ir/impact.dart
@@ -178,7 +178,9 @@
       List<String> namedArguments,
       List<ir.DartType> typeArguments);
 
-  void registerRuntimeTypeUse(ir.PropertyGet node, RuntimeTypeUseKind kind,
+  // TODO(johnniwinther): Change [node] to `InstanceGet` when the old method
+  // invocation encoding is no longer used.
+  void registerRuntimeTypeUse(ir.Expression node, RuntimeTypeUseKind kind,
       ir.DartType receiverType, ir.DartType argumentType);
 
   // TODO(johnniwinther): Remove these when CFE provides constants.
@@ -595,6 +597,20 @@
   }
 
   @override
+  void handleEqualsNull(ir.EqualsNull node, ir.DartType expressionType) {
+    // TODO(johnniwinther): Remove this after the new method invocation has landed
+    // stably. This is only included to make the transition a no-op.
+    if (node.fileOffset < node.expression.fileOffset) {
+      // Hack to detect `null == o`.
+      expressionType = const ir.NullType();
+    }
+    ClassRelation relation = computeClassRelationFromType(expressionType);
+    registerDynamicInvocation(
+        expressionType, relation, ir.Name.equalsName, 1, const [], const []);
+    registerNullLiteral();
+  }
+
+  @override
   void handleDynamicGet(ir.Expression node, ir.DartType receiverType,
       ir.Name name, ir.DartType resultType) {
     ClassRelation relation = computeClassRelationFromType(receiverType);
@@ -660,8 +676,10 @@
     return super.visitSwitchStatement(node);
   }
 
+  // TODO(johnniwinther): Change [node] `InstanceGet` when the old method
+  // invocation encoding is no longer used.
   @override
-  void handleRuntimeTypeUse(ir.PropertyGet node, RuntimeTypeUseKind kind,
+  void handleRuntimeTypeUse(ir.Expression node, RuntimeTypeUseKind kind,
       ir.DartType receiverType, ir.DartType argumentType) {
     registerRuntimeTypeUse(node, kind, receiverType, argumentType);
   }
diff --git a/pkg/compiler/lib/src/ir/impact_data.dart b/pkg/compiler/lib/src/ir/impact_data.dart
index eecf083..f259a4f 100644
--- a/pkg/compiler/lib/src/ir/impact_data.dart
+++ b/pkg/compiler/lib/src/ir/impact_data.dart
@@ -418,8 +418,10 @@
     _data._intLiterals.add(value);
   }
 
+  // TODO(johnniwinther): Change [node] `InstanceGet` when the old method
+  // invocation encoding is no longer used.
   @override
-  void registerRuntimeTypeUse(ir.PropertyGet node, RuntimeTypeUseKind kind,
+  void registerRuntimeTypeUse(ir.Expression node, RuntimeTypeUseKind kind,
       ir.DartType receiverType, ir.DartType argumentType) {
     _data._runtimeTypeUses ??= [];
     _data._runtimeTypeUses
@@ -1577,7 +1579,9 @@
 class _RuntimeTypeUse {
   static const String tag = '_RuntimeTypeUse';
 
-  final ir.PropertyGet node;
+  // TODO(johnniwinther): Change [node] `InstanceGet` when the old method
+  // invocation encoding is no longer used.
+  final ir.Expression node;
   final RuntimeTypeUseKind kind;
   final ir.DartType receiverType;
   final ir.DartType argumentType;
diff --git a/pkg/compiler/lib/src/ir/runtime_type_analysis.dart b/pkg/compiler/lib/src/ir/runtime_type_analysis.dart
index b62aafc..2fe49b8 100644
--- a/pkg/compiler/lib/src/ir/runtime_type_analysis.dart
+++ b/pkg/compiler/lib/src/ir/runtime_type_analysis.dart
@@ -29,7 +29,9 @@
   final RuntimeTypeUseKind kind;
 
   /// The property get for the left (or single) occurrence of `.runtimeType`.
-  final ir.PropertyGet leftRuntimeTypeExpression;
+  // TODO(johnniwinther): Change this to `InstanceGet` when the old method
+  // invocation encoding is no longer used.
+  final ir.Expression leftRuntimeTypeExpression;
 
   /// The receiver expression.
   final ir.Expression receiver;
@@ -40,7 +42,9 @@
 
   /// The property get for the right occurrence of `.runtimeType` when [kind]
   /// is `RuntimeTypeUseKind.equals`.
-  final ir.PropertyGet rightRuntimeTypeExpression;
+  // TODO(johnniwinther): Change this to `InstanceGet` when the old method
+  // invocation encoding is no longer used.
+  final ir.Expression rightRuntimeTypeExpression;
 
   /// The argument expression if [kind] is `RuntimeTypeUseKind.equals`.
   final ir.Expression argument;
@@ -77,37 +81,43 @@
 ///
 /// [cache] is used to ensure that only one [RuntimeTypeUseData] object is
 /// created per case, even for the `==` case.
+// TODO(johnniwinther): Change [cache] key and [node] to `InstanceGet` when the
+// old method invocation encoding is no longer used.
 RuntimeTypeUseData computeRuntimeTypeUse(
-    Map<ir.PropertyGet, RuntimeTypeUseData> cache, ir.PropertyGet node) {
+    Map<ir.Expression, RuntimeTypeUseData> cache, ir.Expression node) {
   RuntimeTypeUseData receiverData = cache[node];
   if (receiverData != null) return receiverData;
 
   /// Returns `true` if [node] is of the form `e.runtimeType`.
   bool isGetRuntimeType(ir.TreeNode node) {
-    return node is ir.PropertyGet && node.name.text == Identifiers.runtimeType_;
-  }
-
-  /// Returns [node] if [node] is of the form `e.runtimeType` and `null`
-  /// otherwise.
-  ir.PropertyGet asGetRuntimeType(ir.TreeNode node) {
-    return isGetRuntimeType(node) ? node : null;
+    return node is ir.PropertyGet &&
+            node.name.text == Identifiers.runtimeType_ ||
+        node is ir.InstanceGet && node.name.text == Identifiers.runtimeType_ ||
+        node is ir.DynamicGet && node.name.text == Identifiers.runtimeType_;
   }
 
   /// Returns `true` if [node] is of the form `e.toString()`.
   bool isInvokeToString(ir.TreeNode node) {
-    return node is ir.MethodInvocation && node.name.text == 'toString';
+    return node is ir.MethodInvocation && node.name.text == 'toString' ||
+        node is ir.InstanceInvocation && node.name.text == 'toString';
   }
 
   assert(isGetRuntimeType(node));
+  // TODO(johnniwinther): Replace this with `node.receiver` when the old method
+  // invocation encoding is no longer used.
+  _RuntimeTypeAccess runtimeTypeAccess = _getRuntimeTypeAccess(node);
+  assert(runtimeTypeAccess != null);
 
+  // TODO(johnniwinther): Change [receiverGet] and [argumentGet] to
+  // `InstanceGet` when the old method invocation encoding is no longer used.
   // TODO(johnniwinther): Special-case `this.runtimeType`.
-  ir.PropertyGet receiverGet;
+  ir.Expression receiverGet;
   ir.Expression receiver;
-  ir.PropertyGet argumentGet;
+  ir.Expression argumentGet;
   ir.Expression argument;
   RuntimeTypeUseKind kind;
 
-  if (node.receiver is ir.VariableGet &&
+  if (runtimeTypeAccess.receiver is ir.VariableGet &&
       node.parent is ir.ConditionalExpression &&
       node.parent.parent is ir.Let) {
     NullAwareExpression nullAware = getNullAwareExpression(node.parent.parent);
@@ -138,15 +148,16 @@
           receiver = nullAware.receiver;
           receiverGet = node;
         }
-      } else if (nullAware.parent is ir.MethodInvocation) {
-        ir.MethodInvocation methodInvocation = nullAware.parent;
-        if (methodInvocation.receiver == nullAware.let &&
-            methodInvocation.name.text == '==') {
+      } else if (_isObjectMethodInvocation(nullAware.parent)) {
+        _EqualsInvocation equalsInvocation =
+            _getEqualsInvocation(nullAware.parent);
+        if (equalsInvocation != null &&
+            equalsInvocation.left == nullAware.let) {
           // Detected
           //
           //  e0?.runtimeType == other
-          ir.PropertyGet otherGetRuntimeType =
-              asGetRuntimeType(methodInvocation.arguments.positional.first);
+          _RuntimeTypeAccess otherGetRuntimeType =
+              _getRuntimeTypeAccess(equalsInvocation.right);
           if (otherGetRuntimeType != null) {
             // Detected
             //
@@ -161,11 +172,11 @@
             receiver = nullAware.receiver;
             receiverGet = node;
             argument = otherGetRuntimeType.receiver;
-            argumentGet = methodInvocation.arguments.positional.first;
+            argumentGet = otherGetRuntimeType.node;
           }
 
-          NullAwareExpression otherNullAware = getNullAwareExpression(
-              methodInvocation.arguments.positional.first);
+          NullAwareExpression otherNullAware =
+              getNullAwareExpression(equalsInvocation.right);
           if (otherNullAware != null &&
               isGetRuntimeType(otherNullAware.expression)) {
             // Detected
@@ -200,16 +211,17 @@
           receiverGet = node;
         }
       } else if (nullAware.parent is ir.Arguments &&
-          nullAware.parent.parent is ir.MethodInvocation) {
-        ir.MethodInvocation methodInvocation = nullAware.parent.parent;
-        if (methodInvocation.name.text == '==' &&
-            methodInvocation.arguments.positional.first == nullAware.let) {
+          _isObjectMethodInvocation(nullAware.parent.parent)) {
+        _EqualsInvocation equalsInvocation =
+            _getEqualsInvocation(nullAware.parent.parent);
+        if (equalsInvocation != null &&
+            equalsInvocation.right == nullAware.let) {
           // [nullAware] is the right hand side of ==.
 
-          ir.PropertyGet otherGetRuntimeType =
-              asGetRuntimeType(methodInvocation.receiver);
+          _RuntimeTypeAccess otherGetRuntimeType =
+              _getRuntimeTypeAccess(equalsInvocation.left);
           NullAwareExpression otherNullAware =
-              getNullAwareExpression(methodInvocation.receiver);
+              getNullAwareExpression(equalsInvocation.left);
 
           if (otherGetRuntimeType != null) {
             // Detected
@@ -223,7 +235,7 @@
             //                                                  ^
             kind = RuntimeTypeUseKind.equals;
             receiver = otherGetRuntimeType.receiver;
-            receiverGet = otherGetRuntimeType;
+            receiverGet = otherGetRuntimeType.node;
             argument = nullAware.receiver;
             argumentGet = node;
           }
@@ -285,19 +297,18 @@
       //     let #t1 = e.runtimeType in #t1 == null ? null : #t1.toString()
       //                 ^
       kind = RuntimeTypeUseKind.string;
-      receiver = node.receiver;
+      receiver = runtimeTypeAccess.receiver;
       receiverGet = node;
     }
-  } else if (node.parent is ir.MethodInvocation) {
-    ir.MethodInvocation methodInvocation = node.parent;
-    if (methodInvocation.name.text == '==' &&
-        methodInvocation.receiver == node) {
+  } else if (_isObjectMethodInvocation(node.parent)) {
+    _EqualsInvocation equalsInvocation = _getEqualsInvocation(node.parent);
+    if (equalsInvocation != null && equalsInvocation.left == node) {
       // [node] is the left hand side of ==.
 
-      ir.PropertyGet otherGetRuntimeType =
-          asGetRuntimeType(methodInvocation.arguments.positional.first);
+      _RuntimeTypeAccess otherGetRuntimeType =
+          _getRuntimeTypeAccess(equalsInvocation.right);
       NullAwareExpression nullAware =
-          getNullAwareExpression(methodInvocation.arguments.positional.first);
+          getNullAwareExpression(equalsInvocation.right);
       if (otherGetRuntimeType != null) {
         // Detected
         //
@@ -308,10 +319,10 @@
         //     e0.runtimeType.==(e1.runtimeType)
         //        ^
         kind = RuntimeTypeUseKind.equals;
-        receiver = node.receiver;
+        receiver = runtimeTypeAccess.receiver;
         receiverGet = node;
         argument = otherGetRuntimeType.receiver;
-        argumentGet = otherGetRuntimeType;
+        argumentGet = otherGetRuntimeType.node;
       } else if (nullAware != null && isGetRuntimeType(nullAware.expression)) {
         // Detected
         //
@@ -323,7 +334,7 @@
         //        ^
         //         let #t1 = e1 in #t1 == null ? null : #t1.runtimeType)
         kind = RuntimeTypeUseKind.equals;
-        receiver = node.receiver;
+        receiver = runtimeTypeAccess.receiver;
         receiverGet = node;
         argument = nullAware.receiver;
         argumentGet = nullAware.expression;
@@ -334,19 +345,19 @@
       //     e.runtimeType.toString()
       //       ^
       kind = RuntimeTypeUseKind.string;
-      receiver = node.receiver;
+      receiver = runtimeTypeAccess.receiver;
       receiverGet = node;
     }
   } else if (node.parent is ir.Arguments &&
-      node.parent.parent is ir.MethodInvocation) {
-    ir.MethodInvocation methodInvocation = node.parent.parent;
-    if (methodInvocation.name.text == '==' &&
-        methodInvocation.arguments.positional.first == node) {
+      _isObjectMethodInvocation(node.parent.parent)) {
+    _EqualsInvocation _equalsInvocation =
+        _getEqualsInvocation(node.parent.parent);
+    if (_equalsInvocation != null && _equalsInvocation.right == node) {
       // [node] is the right hand side of ==.
-      ir.PropertyGet otherGetRuntimeType =
-          asGetRuntimeType(methodInvocation.receiver);
+      _RuntimeTypeAccess otherGetRuntimeType =
+          _getRuntimeTypeAccess(_equalsInvocation.left);
       NullAwareExpression nullAware =
-          getNullAwareExpression(methodInvocation.receiver);
+          getNullAwareExpression(_equalsInvocation.left);
 
       if (otherGetRuntimeType != null) {
         // Detected
@@ -359,8 +370,8 @@
         //                          ^
         kind = RuntimeTypeUseKind.equals;
         receiver = otherGetRuntimeType.receiver;
-        receiverGet = otherGetRuntimeType;
-        argument = node.receiver;
+        receiverGet = otherGetRuntimeType.node;
+        argument = runtimeTypeAccess.receiver;
         argumentGet = node;
       } else if (nullAware != null && isGetRuntimeType(nullAware.expression)) {
         // Detected
@@ -375,7 +386,7 @@
         kind = RuntimeTypeUseKind.equals;
         receiver = nullAware.receiver;
         receiverGet = nullAware.expression;
-        argument = node.receiver;
+        argument = runtimeTypeAccess.receiver;
         argumentGet = node;
       }
     }
@@ -385,7 +396,7 @@
     //     '${e.runtimeType}'
     //          ^
     kind = RuntimeTypeUseKind.string;
-    receiver = node.receiver;
+    receiver = runtimeTypeAccess.receiver;
     receiverGet = node;
   }
 
@@ -395,7 +406,7 @@
     //     e.runtimeType
     //       ^
     kind = RuntimeTypeUseKind.unknown;
-    receiver = node.receiver;
+    receiver = runtimeTypeAccess.receiver;
     receiverGet = node;
   }
 
@@ -413,3 +424,50 @@
       receiverGet != argumentGet, "Duplicate property get in $data for $node.");
   return data;
 }
+
+/// Returns `true` if [node] is a potential invocation of an Object method.
+bool _isObjectMethodInvocation(ir.TreeNode node) {
+  return node is ir.MethodInvocation ||
+      node is ir.InstanceInvocation ||
+      node is ir.EqualsCall;
+}
+
+/// Returns the [_RuntimeTypeAccess] corresponding to [node] if it is an access
+/// of `.runtimeType`, and `null` otherwise.
+_RuntimeTypeAccess _getRuntimeTypeAccess(ir.TreeNode node) {
+  if (node is ir.PropertyGet && node.name.text == 'runtimeType') {
+    return _RuntimeTypeAccess(node, node.receiver);
+  } else if (node is ir.InstanceGet && node.name.text == 'runtimeType') {
+    return _RuntimeTypeAccess(node, node.receiver);
+  } else if (node is ir.DynamicGet && node.name.text == 'runtimeType') {
+    return _RuntimeTypeAccess(node, node.receiver);
+  }
+  return null;
+}
+
+class _RuntimeTypeAccess {
+  final ir.Expression node;
+  final ir.Expression receiver;
+
+  _RuntimeTypeAccess(this.node, this.receiver);
+}
+
+/// Returns the [_EqualsInvocation] corresponding to [node] if it is a call to
+/// of `==`, and `null` otherwise.
+_EqualsInvocation _getEqualsInvocation(ir.TreeNode node) {
+  if (node is ir.MethodInvocation && node.name.text == '==') {
+    return _EqualsInvocation(
+        node, node.receiver, node.arguments.positional.single);
+  } else if (node is ir.EqualsCall) {
+    return _EqualsInvocation(node, node.left, node.right);
+  }
+  return null;
+}
+
+class _EqualsInvocation {
+  final ir.Expression node;
+  final ir.Expression left;
+  final ir.Expression right;
+
+  _EqualsInvocation(this.node, this.left, this.right);
+}
diff --git a/pkg/compiler/lib/src/ir/scope_visitor.dart b/pkg/compiler/lib/src/ir/scope_visitor.dart
index 1fa89f1..3004f39 100644
--- a/pkg/compiler/lib/src/ir/scope_visitor.dart
+++ b/pkg/compiler/lib/src/ir/scope_visitor.dart
@@ -1070,6 +1070,24 @@
   }
 
   @override
+  EvaluationComplexity visitInstanceGetterInvocation(
+      ir.InstanceGetterInvocation node) {
+    node.receiver = _handleExpression(node.receiver);
+    if (node.arguments.types.isNotEmpty) {
+      ir.TreeNode receiver = node.receiver;
+      assert(
+          !(receiver is ir.VariableGet &&
+              receiver.variable.parent is ir.LocalFunction),
+          "Unexpected local function invocation ${node} "
+          "(${node.runtimeType}).");
+      VariableUse usage = new VariableUse.instanceTypeArgument(node);
+      visitNodesInContext(node.arguments.types, usage);
+    }
+    visitArguments(node.arguments);
+    return const EvaluationComplexity.lazy();
+  }
+
+  @override
   EvaluationComplexity visitDynamicInvocation(ir.DynamicInvocation node) {
     node.receiver = _handleExpression(node.receiver);
     if (node.arguments.types.isNotEmpty) {
@@ -1106,13 +1124,10 @@
   @override
   EvaluationComplexity visitLocalFunctionInvocation(
       ir.LocalFunctionInvocation node) {
+    _markVariableAsUsed(node.variable, VariableUse.explicit);
     if (node.arguments.types.isNotEmpty) {
-      assert(
-          node.variable.parent is ir.LocalFunction,
-          "Unexpected variable in local function invocation ${node} "
-          "(${node.runtimeType}).");
       VariableUse usage =
-          new VariableUse.localTypeArgument(node.variable.parent, node);
+          new VariableUse.localTypeArgument(node.localFunction, node);
       visitNodesInContext(node.arguments.types, usage);
     }
     visitArguments(node.arguments);
@@ -1145,7 +1160,7 @@
   EvaluationComplexity visitPropertyGet(ir.PropertyGet node) {
     node.receiver = _handleExpression(node.receiver);
     EvaluationComplexity complexity = _lastExpressionComplexity;
-    if (complexity.isConstant && node.name.name == 'length') {
+    if (complexity.isConstant && node.name.text == 'length') {
       return _evaluateImplicitConstant(node);
     }
     return const EvaluationComplexity.lazy();
@@ -1155,7 +1170,7 @@
   EvaluationComplexity visitInstanceGet(ir.InstanceGet node) {
     node.receiver = _handleExpression(node.receiver);
     EvaluationComplexity complexity = _lastExpressionComplexity;
-    if (complexity.isConstant && node.name.name == 'length') {
+    if (complexity.isConstant && node.name.text == 'length') {
       return _evaluateImplicitConstant(node);
     }
     return const EvaluationComplexity.lazy();
@@ -1171,7 +1186,7 @@
   EvaluationComplexity visitDynamicGet(ir.DynamicGet node) {
     node.receiver = _handleExpression(node.receiver);
     EvaluationComplexity complexity = _lastExpressionComplexity;
-    if (complexity.isConstant && node.name.name == 'length') {
+    if (complexity.isConstant && node.name.text == 'length') {
       return _evaluateImplicitConstant(node);
     }
     return const EvaluationComplexity.lazy();
diff --git a/pkg/compiler/lib/src/ir/static_type.dart b/pkg/compiler/lib/src/ir/static_type.dart
index 7ecbbe2..fd85772 100644
--- a/pkg/compiler/lib/src/ir/static_type.dart
+++ b/pkg/compiler/lib/src/ir/static_type.dart
@@ -73,7 +73,9 @@
 abstract class StaticTypeVisitor extends StaticTypeBase {
   final StaticTypeCacheImpl _staticTypeCache;
   Map<ir.Expression, TypeMap> typeMapsForTesting;
-  Map<ir.PropertyGet, RuntimeTypeUseData> _pendingRuntimeTypeUseData = {};
+  // TODO(johnniwinther): Change the key to `InstanceGet` when the old method
+  //  invocation encoding is no longer used.
+  Map<ir.Expression, RuntimeTypeUseData> _pendingRuntimeTypeUseData = {};
 
   final ir.ClassHierarchy hierarchy;
 
@@ -130,13 +132,19 @@
   TypeMap _typeMapWhenTrue;
   TypeMap _typeMapWhenFalse;
 
-  /// Returns the local variable type promotions for when the boolean value of
-  /// the most recent node is not taken into account.
-  TypeMap get typeMap {
+  /// Joins [_typeMapWhenTrue] and [_typeMapWhenFalse] and stores the result
+  /// in [_typeMapBase].
+  void _flattenTypeMap() {
     if (_typeMapBase == null) {
       _typeMapBase = _typeMapWhenTrue.join(_typeMapWhenFalse);
       _typeMapWhenTrue = _typeMapWhenFalse = null;
     }
+  }
+
+  /// Returns the local variable type promotions for when the boolean value of
+  /// the most recent node is not taken into account.
+  TypeMap get typeMap {
+    _flattenTypeMap();
     return _typeMapBase;
   }
 
@@ -282,13 +290,22 @@
     return const ir.DynamicType();
   }
 
+  /// Replaces [original] with [replacement] in the AST and removes cached
+  /// expression type information for [original].
+  void _replaceExpression(ir.Expression original, ir.Expression replacement) {
+    original.replaceWith(replacement);
+    _staticTypeCache._expressionTypes.remove(original);
+  }
+
   void handleDynamicGet(ir.Expression node, ir.DartType receiverType,
       ir.Name name, ir.DartType resultType) {}
 
   void handleInstanceGet(ir.Expression node, ir.DartType receiverType,
       ir.Member interfaceTarget, ir.DartType resultType) {}
 
-  void handleRuntimeTypeUse(ir.PropertyGet node, RuntimeTypeUseKind kind,
+  // TODO(johnniwinther): Change [node] to `InstanceGet` when the old method
+  // invocation encoding is no longer used.
+  void handleRuntimeTypeUse(ir.Expression node, RuntimeTypeUseKind kind,
       ir.DartType receiverType, ir.DartType argumentType) {}
 
   @override
@@ -343,13 +360,25 @@
       resultType = _computeInstanceGetType(receiverType, interfaceTarget);
       ir.InstanceGet instanceGet = ir.InstanceGet(
           ir.InstanceAccessKind.Instance, node.receiver, node.name,
-          interfaceTarget: interfaceTarget, resultType: resultType);
-      node.replaceWith(instanceGet);
+          interfaceTarget: interfaceTarget, resultType: resultType)
+        ..fileOffset = node.fileOffset;
+      _replaceExpression(node, instanceGet);
       handleInstanceGet(instanceGet, receiverType, interfaceTarget, resultType);
+    } else if (node.name == ir.Name.callName &&
+        (receiverType is ir.FunctionType ||
+            (receiverType is ir.InterfaceType &&
+                receiverType.classNode == typeEnvironment.functionClass))) {
+      ir.FunctionTearOff functionTearOff = ir.FunctionTearOff(node.receiver)
+        ..fileOffset = node.fileOffset;
+      _replaceExpression(node, functionTearOff);
+      handleDynamicGet(
+          functionTearOff, receiverType, ir.Name.callName, resultType);
+      resultType = receiverType;
     } else {
       handleDynamicGet(node, receiverType, node.name, resultType);
     }
     if (node.name.text == Identifiers.runtimeType_) {
+      // This handles `runtimeType` access on `Never`.
       handleRuntimeTypeGet(receiverType, node);
     }
     return resultType;
@@ -358,9 +387,17 @@
   @override
   ir.DartType visitInstanceGet(ir.InstanceGet node) {
     ir.DartType receiverType = visitNode(node.receiver);
-    ir.DartType resultType = super.visitInstanceGet(node);
+    // We compute the function type instead of reading it of [node] since the
+    // receiver and argument types might have improved through inference of
+    // effectively final variable types and type promotion.
+    ir.DartType resultType =
+        _computeInstanceGetType(receiverType, node.interfaceTarget);
+    node.resultType = resultType;
+    receiverType = _narrowInstanceReceiver(node.interfaceTarget, receiverType);
     handleInstanceGet(node, receiverType, node.interfaceTarget, resultType);
     if (node.name.text == Identifiers.runtimeType_) {
+      // This handles `runtimeType` access on non-Never types, like in
+      // `(throw 'foo').runtimeType`.
       handleRuntimeTypeGet(receiverType, node);
     }
     return resultType;
@@ -369,8 +406,14 @@
   @override
   ir.DartType visitInstanceTearOff(ir.InstanceTearOff node) {
     ir.DartType receiverType = visitNode(node.receiver);
-    ir.DartType resultType = super.visitInstanceTearOff(node);
-    assert(node.name.text == Identifiers.runtimeType_,
+    // We compute the function type instead of reading it of [node] since the
+    // receiver and argument types might have improved through inference of
+    // effectively final variable types and type promotion.
+    ir.DartType resultType =
+        _computeInstanceGetType(receiverType, node.interfaceTarget);
+    node.resultType = resultType;
+    receiverType = _narrowInstanceReceiver(node.interfaceTarget, receiverType);
+    assert(node.name.text != Identifiers.runtimeType_,
         "Unexpected .runtimeType instance tear-off.");
     handleInstanceGet(node, receiverType, node.interfaceTarget, resultType);
     return resultType;
@@ -379,9 +422,8 @@
   @override
   ir.DartType visitFunctionTearOff(ir.FunctionTearOff node) {
     ir.DartType receiverType = visitNode(node.receiver);
-    ir.DartType resultType = super.visitFunctionTearOff(node);
-    handleDynamicGet(node, receiverType, ir.Name.callName, resultType);
-    return resultType;
+    handleDynamicGet(node, receiverType, ir.Name.callName, receiverType);
+    return receiverType;
   }
 
   void handleDynamicSet(ir.Expression node, ir.DartType receiverType,
@@ -452,7 +494,7 @@
   @override
   ir.DartType visitDynamicSet(ir.DynamicSet node) {
     ir.DartType receiverType = visitNode(node.receiver);
-    ir.DartType valueType = super.visitDynamicSet(node);
+    ir.DartType valueType = visitNode(node.value);
     ir.Member interfaceTarget = _resolveDynamicSet(receiverType, node.name);
     if (interfaceTarget != null) {
       ir.DartType setterType =
@@ -470,7 +512,7 @@
       ir.InstanceSet instanceSet = ir.InstanceSet(
           ir.InstanceAccessKind.Instance, node.receiver, node.name, value,
           interfaceTarget: interfaceTarget);
-      node.replaceWith(instanceSet);
+      _replaceExpression(node, instanceSet);
       receiverType = _narrowInstanceReceiver(interfaceTarget, receiverType);
       handleInstanceSet(node, receiverType, interfaceTarget, valueType);
     } else {
@@ -482,7 +524,7 @@
   @override
   ir.DartType visitInstanceSet(ir.InstanceSet node) {
     ir.DartType receiverType = visitNode(node.receiver);
-    ir.DartType valueType = super.visitInstanceSet(node);
+    ir.DartType valueType = visitNode(node.value);
     handleInstanceSet(node, receiverType, node.interfaceTarget, valueType);
     return valueType;
   }
@@ -522,74 +564,77 @@
     return receiverType;
   }
 
-  /// Returns `true` if [member] can be called with the structure of
-  /// [arguments].
-  bool _isApplicable(ir.Arguments arguments, ir.Member member) {
-    /// Returns `true` if [arguments] are applicable to the function type
-    /// structure.
-    bool isFunctionTypeApplicable(
-        int typeParameterCount,
-        int requiredParameterCount,
-        int positionalParameterCount,
-        Iterable<String> Function() getNamedParameters) {
-      if (arguments.types.isNotEmpty &&
-          arguments.types.length != typeParameterCount) {
-        return false;
-      }
-      if (arguments.positional.length < requiredParameterCount) {
-        return false;
-      }
-      if (arguments.positional.length > positionalParameterCount) {
-        return false;
-      }
-      Iterable<String> namedParameters = getNamedParameters();
-      if (arguments.named.length > namedParameters.length) {
-        return false;
-      }
-      if (arguments.named.isNotEmpty) {
-        for (ir.NamedExpression namedArguments in arguments.named) {
-          if (!namedParameters.contains(namedArguments.name)) {
-            return false;
-          }
-        }
-      }
-      return true;
-    }
-
-    /// Returns `true` if [arguments] are applicable to a value of the static
-    /// [type].
-    bool isTypeApplicable(ir.DartType type) {
-      if (type is ir.DynamicType) return true;
-      if (type == typeEnvironment.coreTypes.functionLegacyRawType ||
-          type == typeEnvironment.coreTypes.functionNullableRawType ||
-          type == typeEnvironment.coreTypes.functionNonNullableRawType)
-        return true;
-      if (type is ir.FunctionType) {
-        return isFunctionTypeApplicable(
-            type.typeParameters.length,
-            type.requiredParameterCount,
-            type.positionalParameters.length,
-            () => type.namedParameters.map((p) => p.name).toSet());
-      }
+  /// Returns `true` if [arguments] are applicable to the function type
+  /// structure.
+  bool _isApplicableToFunctionType(
+      ir.Arguments arguments,
+      int typeParameterCount,
+      int requiredParameterCount,
+      int positionalParameterCount,
+      Iterable<String> Function() getNamedParameters) {
+    if (arguments.types.isNotEmpty &&
+        arguments.types.length != typeParameterCount) {
       return false;
     }
+    if (arguments.positional.length < requiredParameterCount) {
+      return false;
+    }
+    if (arguments.positional.length > positionalParameterCount) {
+      return false;
+    }
+    Iterable<String> namedParameters = getNamedParameters();
+    if (arguments.named.length > namedParameters.length) {
+      return false;
+    }
+    if (arguments.named.isNotEmpty) {
+      for (ir.NamedExpression namedArguments in arguments.named) {
+        if (!namedParameters.contains(namedArguments.name)) {
+          return false;
+        }
+      }
+    }
+    return true;
+  }
 
+  /// Returns `true` if [arguments] are applicable to a value of the static
+  /// [type].
+  bool _isApplicableToType(ir.Arguments arguments, ir.DartType type) {
+    if (type is ir.DynamicType) return true;
+    if (type == typeEnvironment.coreTypes.functionLegacyRawType ||
+        type == typeEnvironment.coreTypes.functionNullableRawType ||
+        type == typeEnvironment.coreTypes.functionNonNullableRawType)
+      return true;
+    if (type is ir.FunctionType) {
+      return _isApplicableToFunctionType(
+          arguments,
+          type.typeParameters.length,
+          type.requiredParameterCount,
+          type.positionalParameters.length,
+          () => type.namedParameters.map((p) => p.name).toSet());
+    }
+    return false;
+  }
+
+  /// Returns `true` if [member] can be called with the structure of
+  /// [arguments].
+  bool _isApplicableToMember(ir.Arguments arguments, ir.Member member) {
     if (member is ir.Procedure) {
       if (member.kind == ir.ProcedureKind.Setter ||
           member.kind == ir.ProcedureKind.Factory) {
         return false;
       } else if (member.kind == ir.ProcedureKind.Getter) {
-        return isTypeApplicable(member.getterType);
+        return _isApplicableToType(arguments, member.getterType);
       } else if (member.kind == ir.ProcedureKind.Method ||
           member.kind == ir.ProcedureKind.Operator) {
-        return isFunctionTypeApplicable(
+        return _isApplicableToFunctionType(
+            arguments,
             member.function.typeParameters.length,
             member.function.requiredParameterCount,
             member.function.positionalParameters.length,
             () => member.function.namedParameters.map((p) => p.name).toSet());
       }
     } else if (member is ir.Field) {
-      return isTypeApplicable(member.type);
+      return _isApplicableToType(arguments, member.type);
     }
     return false;
   }
@@ -703,18 +748,41 @@
     if (receiverType is ir.InterfaceType) {
       ir.Member member =
           hierarchy.getInterfaceMember(receiverType.classNode, name);
-      if (_isApplicable(arguments, member)) {
+      if (_isApplicableToMember(arguments, member)) {
         return member;
       }
     }
     return null;
   }
 
+  /// Computes the function type of the function invocation of type
+  /// [functionType] with the given [argument].
+  ir.DartType _computeFunctionInvocationType(
+      ir.DartType functionType, ir.Arguments arguments) {
+    if (functionType is ir.FunctionType) {
+      List<ir.DartType> typeArguments = arguments.types;
+      if (functionType.typeParameters.isNotEmpty && typeArguments.isEmpty) {
+        // If this was a dynamic call the invocation does not have the
+        // inferred default type arguments so we need to create them here
+        // to perform a valid substitution.
+        typeArguments =
+            functionType.typeParameters.map((t) => t.defaultType).toList();
+      }
+      return ir.Substitution.fromPairs(
+              functionType.typeParameters, typeArguments)
+          .substituteType(functionType.withoutTypeParameters);
+    }
+    return functionType;
+  }
+
   /// Computes the function type of the instance invocation [node] on a receiver
   /// of type [receiverType] on the [interfaceTarget] with the given
   /// [argumentTypes].
-  ir.DartType _computeInvocationFunctionType(ir.DartType receiverType,
-      ir.Member interfaceTarget, ir.Arguments arguments) {
+  ir.DartType _computeInstanceInvocationType(
+      ir.DartType receiverType,
+      ir.Member interfaceTarget,
+      ir.Arguments arguments,
+      ArgumentTypes argumentTypes) {
     ir.Class superclass = interfaceTarget.enclosingClass;
     ir.Substitution receiverSubstitution = ir.Substitution.fromInterfaceType(
         getTypeAsInstanceOf(receiverType, superclass));
@@ -737,27 +805,20 @@
           ir.Substitution.fromPairs(functionType.typeParameters, typeArguments)
               .substituteType(functionType.withoutTypeParameters);
     }
+    if (isSpecialCasedBinaryOperator(interfaceTarget)) {
+      ir.DartType argumentType = argumentTypes.positional[0];
+      ir.DartType resultType = typeEnvironment
+          .getTypeOfSpecialCasedBinaryOperator(receiverType, argumentType);
+      return new ir.FunctionType(
+          <ir.DartType>[argumentType], resultType, currentLibrary.nonNullable);
+    }
     return getterType;
   }
 
-  /// Computes the result type of the instance invocation [node] on a receiver
-  /// of type [receiverType] on the [interfaceTarget] with the [functionType]
-  /// computed from the [receiverType], [argumentTypes] and the
-  /// [interfaceTarget].
-  ir.DartType _computeInstanceInvocationReturnTypeFromFunctionType(
-      ir.DartType receiverType,
-      ir.Member interfaceTarget,
-      ArgumentTypes argumentTypes,
-      ir.DartType functionType) {
-    if (isSpecialCasedBinaryOperator(interfaceTarget)) {
-      ir.DartType argumentType = argumentTypes.positional[0];
-      return typeEnvironment.getTypeOfSpecialCasedBinaryOperator(
-          receiverType, argumentType);
-    } else if (functionType is ir.FunctionType) {
-      return functionType.returnType;
-    } else {
-      return const ir.DynamicType();
-    }
+  ir.DartType _getFunctionReturnType(ir.DartType functionType) {
+    return functionType is ir.FunctionType
+        ? functionType.returnType
+        : const ir.DynamicType();
   }
 
   /// Computes the result type of the dynamic invocation [node] on a receiver of
@@ -833,8 +894,7 @@
   void handleEqualsCall(ir.Expression left, ir.DartType leftType,
       ir.Expression right, ir.DartType rightType, ir.Member interfaceTarget) {}
 
-  void _registerEqualsNull(TypeMap afterInvocation, ir.Expression expression,
-      {bool isNot: false}) {
+  void _registerEqualsNull(TypeMap afterInvocation, ir.Expression expression) {
     if (expression is ir.VariableGet &&
         !_invalidatedVariables.contains(expression.variable)) {
       // If `expression == null` is true, we promote the type of the
@@ -845,13 +905,8 @@
           isTrue: false);
       TypeMap ofItsDeclaredType = afterInvocation
           .promote(expression.variable, expression.variable.type, isTrue: true);
-      if (isNot) {
-        typeMapWhenTrue = ofItsDeclaredType;
-        typeMapWhenFalse = notOfItsDeclaredType;
-      } else {
-        typeMapWhenTrue = notOfItsDeclaredType;
-        typeMapWhenFalse = ofItsDeclaredType;
-      }
+      typeMapWhenTrue = notOfItsDeclaredType;
+      typeMapWhenFalse = ofItsDeclaredType;
     }
   }
 
@@ -864,8 +919,8 @@
             receiverType, node.name, node.arguments);
     ir.DartType returnType;
     if (interfaceTarget != null) {
-      ir.DartType functionType = _computeInvocationFunctionType(
-          receiverType, interfaceTarget, node.arguments);
+      ir.DartType functionType = _computeInstanceInvocationType(
+          receiverType, interfaceTarget, node.arguments, argumentTypes);
       if (node.interfaceTarget == null) {
         // We change [node] from being a dynamic invocation to an instance
         // invocation, so we need to add static type checks to the arguments to
@@ -874,8 +929,7 @@
         _updateMethodInvocationTarget(node, argumentTypes, functionType);
         node.interfaceTarget = interfaceTarget;
       }
-      returnType = _computeInstanceInvocationReturnTypeFromFunctionType(
-          receiverType, interfaceTarget, argumentTypes, functionType);
+      returnType = _getFunctionReturnType(functionType);
     } else {
       returnType = _computeDynamicInvocationReturnType(node, receiverType);
     }
@@ -920,6 +974,57 @@
   }
 
   @override
+  ir.DartType visitInstanceInvocation(ir.InstanceInvocation node) {
+    ArgumentTypes argumentTypes = _visitArguments(node.arguments);
+    ir.DartType receiverType = visitNode(node.receiver);
+    ir.Member interfaceTarget = node.interfaceTarget;
+    // We compute the function type instead of reading it of [node] since the
+    // receiver and argument types might have improved through inference of
+    // effectively final variable types and type promotion.
+    ir.DartType functionType = _computeInstanceInvocationType(
+        receiverType, interfaceTarget, node.arguments, argumentTypes);
+    if (functionType != node.functionType) {
+      node.functionType = functionType;
+      // TODO(johnniwinther): To provide the static guarantee that arguments
+      // of a statically typed call have been checked against the parameter
+      // types we need to call [_updateMethodInvocationTarget]. This can create
+      // uses of type variables are not registered with the closure model so
+      // we skip it for now. Note that this invariant is not currently used
+      // in later phases since it wasn't provided for function invocations in
+      // the old method invocation encoding.
+      //_updateMethodInvocationTarget(node, argumentTypes, functionType);
+    }
+    ir.DartType returnType = _getFunctionReturnType(functionType);
+    receiverType = _narrowInstanceReceiver(node.interfaceTarget, receiverType);
+    handleInstanceInvocation(
+        node, receiverType, interfaceTarget, argumentTypes);
+    _staticTypeCache._expressionTypes[node] = returnType;
+    return returnType;
+  }
+
+  @override
+  ir.DartType visitInstanceGetterInvocation(ir.InstanceGetterInvocation node) {
+    ArgumentTypes argumentTypes = _visitArguments(node.arguments);
+    ir.DartType receiverType = visitNode(node.receiver);
+    ir.Member interfaceTarget = node.interfaceTarget;
+    // We compute the function type instead of reading it of [node] since the
+    // receiver and argument types might have improved through inference of
+    // effectively final variable types and type promotion.
+    ir.DartType functionType = _computeInstanceInvocationType(
+        receiverType, interfaceTarget, node.arguments, argumentTypes);
+    if (functionType is ir.FunctionType && functionType != node.functionType) {
+      node.functionType = functionType;
+      _updateMethodInvocationTarget(node, argumentTypes, functionType);
+    }
+    ir.DartType returnType = _getFunctionReturnType(functionType);
+    receiverType = _narrowInstanceReceiver(node.interfaceTarget, receiverType);
+    handleInstanceInvocation(
+        node, receiverType, interfaceTarget, argumentTypes);
+    _staticTypeCache._expressionTypes[node] = returnType;
+    return returnType;
+  }
+
+  @override
   ir.DartType visitDynamicInvocation(ir.DynamicInvocation node) {
     ArgumentTypes argumentTypes = _visitArguments(node.arguments);
     ir.DartType receiverType = visitNode(node.receiver);
@@ -927,31 +1032,71 @@
         receiverType, node.name, node.arguments);
     if (interfaceTarget != null) {
       // We can turn the dynamic invocation into an instance invocation.
-      ir.DartType functionType = _computeInvocationFunctionType(
-          receiverType, interfaceTarget, node.arguments);
-      ir.InstanceInvocation instanceInvocation = ir.InstanceInvocation(
-          ir.InstanceAccessKind.Instance,
-          node.receiver,
-          node.name,
-          node.arguments,
-          interfaceTarget: interfaceTarget,
-          functionType: functionType);
-      node.replaceWith(instanceInvocation);
-      _updateMethodInvocationTarget(
-          instanceInvocation, argumentTypes, functionType);
-      ir.DartType returnType =
-          _computeInstanceInvocationReturnTypeFromFunctionType(
-              receiverType, interfaceTarget, argumentTypes, functionType);
+      ir.DartType functionType = _computeInstanceInvocationType(
+          receiverType, interfaceTarget, node.arguments, argumentTypes);
+      ir.Expression replacement;
+      if (interfaceTarget is ir.Field ||
+          (interfaceTarget is ir.Procedure && interfaceTarget.isGetter)) {
+        // This should actually be a function invocation of an instance get but
+        // this doesn't work for invocation of js-interop properties. We
+        // therefore use [ir.InstanceGetterInvocation] instead.
+        replacement = ir.InstanceGetterInvocation(
+            ir.InstanceAccessKind.Instance,
+            node.receiver,
+            node.name,
+            node.arguments,
+            interfaceTarget: interfaceTarget,
+            functionType: functionType is ir.FunctionType ? functionType : null)
+          ..fileOffset = node.fileOffset;
+      } else {
+        replacement = ir.InstanceInvocation(ir.InstanceAccessKind.Instance,
+            node.receiver, node.name, node.arguments,
+            interfaceTarget: interfaceTarget, functionType: functionType)
+          ..fileOffset = node.fileOffset;
+      }
+      _replaceExpression(node, replacement);
+      _updateMethodInvocationTarget(replacement, argumentTypes, functionType);
+      ir.DartType resultType = _getFunctionReturnType(functionType);
       receiverType = _narrowInstanceReceiver(interfaceTarget, receiverType);
       handleInstanceInvocation(
-          instanceInvocation, receiverType, interfaceTarget, argumentTypes);
-      _staticTypeCache._expressionTypes[node] = returnType;
-      return returnType;
+          replacement, receiverType, interfaceTarget, argumentTypes);
+      if (replacement is ir.MethodInvocation) {
+        _staticTypeCache._expressionTypes[replacement] = resultType;
+      }
+      return resultType;
+    } else if (node.name == ir.Name.callName &&
+        (receiverType is ir.FunctionType ||
+            (receiverType is ir.InterfaceType &&
+                receiverType.classNode == typeEnvironment.functionClass)) &&
+        _isApplicableToType(node.arguments, receiverType)) {
+      ir.DartType functionType =
+          _computeFunctionInvocationType(receiverType, node.arguments);
+      bool hasFunctionType = functionType is ir.FunctionType;
+      ir.FunctionInvocation replacement = ir.FunctionInvocation(
+          hasFunctionType
+              ? ir.FunctionAccessKind.FunctionType
+              : ir.FunctionAccessKind.Function,
+          node.receiver,
+          node.arguments,
+          functionType: hasFunctionType ? functionType : null)
+        ..fileOffset = node.fileOffset;
+      ir.DartType resultType = _getFunctionReturnType(functionType);
+      _replaceExpression(node, replacement);
+      _updateMethodInvocationTarget(replacement, argumentTypes, functionType);
+      handleFunctionInvocation(
+          replacement, receiverType, argumentTypes, resultType);
+      return resultType;
     } else {
       ir.DartType returnType =
           _computeDynamicInvocationReturnType(node, receiverType);
       _staticTypeCache._expressionTypes[node] = returnType;
       handleDynamicInvocation(node, receiverType, argumentTypes, returnType);
+      if (operatorFromString(node.name.text) == null &&
+          receiverType is ir.DynamicType) {
+        // We might implicitly call a getter that returns a function.
+        handleFunctionInvocation(
+            node, const ir.DynamicType(), argumentTypes, returnType);
+      }
       return returnType;
     }
   }
@@ -960,15 +1105,30 @@
   ir.DartType visitEqualsCall(ir.EqualsCall node) {
     ir.DartType leftType = visitNode(node.left);
     ir.DartType rightType = visitNode(node.right);
+    // This is accessed to ensure that [typeMapWhenTrue] and [typeMapWhenFalse]
+    // are joined as the result of this node.
+    // This is related to dartbug.com/45053
+    _flattenTypeMap();
+    leftType = _narrowInstanceReceiver(node.interfaceTarget, leftType);
     handleEqualsCall(
         node.left, leftType, node.right, rightType, node.interfaceTarget);
     return super.visitEqualsCall(node);
   }
 
+  // TODO(johnniwinther): Remove this after the new method invocation has landed
+  // stably. This is only included to make the transition a no-op.
+  void handleEqualsNull(ir.EqualsNull node, ir.DartType expressionType) {}
+
   @override
   ir.DartType visitEqualsNull(ir.EqualsNull node) {
-    visitNode(node.expression);
-    _registerEqualsNull(typeMap, node.expression, isNot: node.isNot);
+    ir.DartType expressionType = visitNode(node.expression);
+    if (expressionType is ir.DynamicType) {
+      expressionType = currentLibrary.isNonNullableByDefault
+          ? typeEnvironment.objectNullableRawType
+          : typeEnvironment.objectLegacyRawType;
+    }
+    _registerEqualsNull(typeMap, node.expression);
+    handleEqualsNull(node, expressionType);
     return super.visitEqualsNull(node);
   }
 
@@ -976,15 +1136,25 @@
   ir.DartType visitFunctionInvocation(ir.FunctionInvocation node) {
     ArgumentTypes argumentTypes = _visitArguments(node.arguments);
     ir.DartType receiverType = visitNode(node.receiver);
-    ir.DartType returnType = super.visitFunctionInvocation(node);
-    handleFunctionInvocation(node, receiverType, argumentTypes, returnType);
+    ir.DartType functionType =
+        _computeFunctionInvocationType(receiverType, node.arguments);
+    if (functionType is ir.FunctionType) {
+      // We might have improved the known function type through inference of
+      // effectively final variable types and type promotion.
+      node.functionType = functionType;
+    }
+    // We compute the return type instead of reading it of [node] since the
+    // receiver and argument types might have improved through inference of
+    // effectively final variable types and type promotion.
+    ir.DartType returnType = _getFunctionReturnType(functionType);
+    handleFunctionInvocation(node, functionType, argumentTypes, returnType);
     return returnType;
   }
 
   @override
   ir.DartType visitLocalFunctionInvocation(ir.LocalFunctionInvocation node) {
     ArgumentTypes argumentTypes = _visitArguments(node.arguments);
-    ir.FunctionDeclaration localFunction = node.variable.parent;
+    ir.FunctionDeclaration localFunction = node.localFunction;
     ir.DartType returnType = super.visitLocalFunctionInvocation(node);
     handleLocalFunctionInvocation(
         node, localFunction, argumentTypes, returnType);
@@ -1275,7 +1445,8 @@
 
   @override
   ir.DartType visitBlock(ir.Block node) {
-    assert(_pendingRuntimeTypeUseData.isEmpty);
+    assert(_pendingRuntimeTypeUseData.isEmpty,
+        "Incomplete RuntimeTypeUseData: $_pendingRuntimeTypeUseData");
     ir.DartType type;
     for (ir.Statement statement in node.statements) {
       if (!completes(visitNode(statement))) {
@@ -1776,6 +1947,12 @@
   final List<ir.DartType> named;
 
   ArgumentTypes(this.positional, this.named);
+
+  @override
+  String toString() {
+    return 'ArgumentTypes(position=[${positional.join(',')}],'
+        ' named=[${named.join(',')}])';
+  }
 }
 
 /// Type information collected for a single path for a local variable.
diff --git a/pkg/compiler/lib/src/ir/static_type_base.dart b/pkg/compiler/lib/src/ir/static_type_base.dart
index 7330972..315ee23 100644
--- a/pkg/compiler/lib/src/ir/static_type_base.dart
+++ b/pkg/compiler/lib/src/ir/static_type_base.dart
@@ -262,6 +262,10 @@
       node.getStaticType(staticTypeContext);
 
   @override
+  ir.DartType visitInstanceGetterInvocation(ir.InstanceGetterInvocation node) =>
+      node.getStaticType(staticTypeContext);
+
+  @override
   ir.DartType visitFunctionTearOff(ir.FunctionTearOff node) =>
       node.getStaticType(staticTypeContext);
 
diff --git a/pkg/compiler/lib/src/ir/util.dart b/pkg/compiler/lib/src/ir/util.dart
index 44de884..eab6a08 100644
--- a/pkg/compiler/lib/src/ir/util.dart
+++ b/pkg/compiler/lib/src/ir/util.dart
@@ -118,18 +118,26 @@
     ir.Expression body = node.body;
     if (node.variable.name == null &&
         node.variable.isFinal &&
-        body is ir.ConditionalExpression &&
-        body.condition is ir.MethodInvocation &&
-        isNullLiteral(body.then)) {
-      ir.MethodInvocation invocation = body.condition;
-      ir.Expression receiver = invocation.receiver;
-      if (invocation.name.text == '==' &&
-          receiver is ir.VariableGet &&
-          receiver.variable == node.variable &&
-          isNullLiteral(invocation.arguments.positional.single)) {
-        // We have
-        //   let #t1 = e0 in #t1 == null ? null : e1
-        return new NullAwareExpression(node.variable, body.otherwise);
+        body is ir.ConditionalExpression) {
+      if (body.condition is ir.MethodInvocation && isNullLiteral(body.then)) {
+        ir.MethodInvocation invocation = body.condition;
+        ir.Expression receiver = invocation.receiver;
+        if (invocation.name.text == '==' &&
+            receiver is ir.VariableGet &&
+            receiver.variable == node.variable &&
+            isNullLiteral(invocation.arguments.positional.single)) {
+          // We have
+          //   let #t1 = e0 in #t1 == null ? null : e1
+          return new NullAwareExpression(node.variable, body.otherwise);
+        }
+      } else if (body.condition is ir.EqualsNull) {
+        ir.EqualsNull equalsNull = body.condition;
+        ir.Expression receiver = equalsNull.expression;
+        if (receiver is ir.VariableGet && receiver.variable == node.variable) {
+          // We have
+          //   let #t1 = e0 in #t1 == null ? null : e1
+          return new NullAwareExpression(node.variable, body.otherwise);
+        }
       }
     }
   }
@@ -153,7 +161,16 @@
   //
   //   (let _ = check(prefix) in prefix::field).property
   if (node is ir.StaticGet || node is ir.ConstantExpression) {
-    while (parent is ir.PropertyGet || parent is ir.MethodInvocation) {
+    while (parent is ir.PropertyGet ||
+        parent is ir.InstanceGet ||
+        parent is ir.DynamicGet ||
+        parent is ir.InstanceTearOff ||
+        parent is ir.FunctionTearOff ||
+        parent is ir.MethodInvocation ||
+        parent is ir.InstanceInvocation ||
+        parent is ir.InstanceGetterInvocation ||
+        parent is ir.DynamicInvocation ||
+        parent is ir.FunctionInvocation) {
       parent = parent.parent;
     }
   }
@@ -208,6 +225,11 @@
   }
 
   @override
+  bool visitExtensionType(ir.ExtensionType node) {
+    return visitList(node.typeArguments);
+  }
+
+  @override
   bool visitFutureOrType(ir.FutureOrType node) {
     return visit(node.typeArgument);
   }
diff --git a/pkg/compiler/lib/src/js_backend/annotations.dart b/pkg/compiler/lib/src/js_backend/annotations.dart
index 8955a8d..f702ca37 100644
--- a/pkg/compiler/lib/src/js_backend/annotations.dart
+++ b/pkg/compiler/lib/src/js_backend/annotations.dart
@@ -7,8 +7,6 @@
 import 'package:kernel/ast.dart' as ir;
 
 import '../common.dart';
-import '../diagnostics/diagnostic_listener.dart';
-import '../diagnostics/messages.dart';
 import '../elements/entities.dart';
 import '../ir/annotations.dart';
 import '../ir/util.dart';
diff --git a/pkg/compiler/lib/src/js_backend/constant_emitter.dart b/pkg/compiler/lib/src/js_backend/constant_emitter.dart
index 4d0546c..9fea86f 100644
--- a/pkg/compiler/lib/src/js_backend/constant_emitter.dart
+++ b/pkg/compiler/lib/src/js_backend/constant_emitter.dart
@@ -18,7 +18,6 @@
 import '../js_emitter/code_emitter_task.dart';
 import '../js_model/type_recipe.dart' show TypeExpressionRecipe;
 import '../options.dart';
-import 'field_analysis.dart' show JFieldAnalysis;
 import 'namer.dart';
 import 'runtime_types_new.dart' show RecipeEncoder;
 import 'runtime_types_resolution.dart';
diff --git a/pkg/compiler/lib/src/js_backend/impact_transformer.dart b/pkg/compiler/lib/src/js_backend/impact_transformer.dart
index 474f127..9596fd0 100644
--- a/pkg/compiler/lib/src/js_backend/impact_transformer.dart
+++ b/pkg/compiler/lib/src/js_backend/impact_transformer.dart
@@ -11,7 +11,6 @@
 import '../common/backend_api.dart' show ImpactTransformer;
 import '../common/codegen.dart' show CodegenImpact;
 import '../common/resolution.dart' show ResolutionImpact;
-import '../common_elements.dart' show ElementEnvironment;
 import '../constants/values.dart';
 import '../elements/entities.dart';
 import '../elements/types.dart';
@@ -415,11 +414,17 @@
         case ConstantValueKind.SET:
         case ConstantValueKind.MAP:
         case ConstantValueKind.CONSTRUCTED:
-        case ConstantValueKind.INSTANTIATION:
         case ConstantValueKind.LIST:
           transformed.registerStaticUse(StaticUse.staticInvoke(
               _closedWorld.commonElements.findType, CallStructure.ONE_ARG));
           break;
+        case ConstantValueKind.INSTANTIATION:
+          transformed.registerStaticUse(StaticUse.staticInvoke(
+              _closedWorld.commonElements.findType, CallStructure.ONE_ARG));
+          InstantiationConstantValue instantiation = constantUse.value;
+          _rtiChecksBuilder.registerGenericInstantiation(GenericInstantiation(
+              instantiation.function.type, instantiation.typeArguments));
+          break;
         case ConstantValueKind.DEFERRED_GLOBAL:
           _closedWorld.outputUnitData
               .registerConstantDeferredUse(constantUse.value);
diff --git a/pkg/compiler/lib/src/js_backend/namer_names.dart b/pkg/compiler/lib/src/js_backend/namer_names.dart
index ce57087..233f053 100644
--- a/pkg/compiler/lib/src/js_backend/namer_names.dart
+++ b/pkg/compiler/lib/src/js_backend/namer_names.dart
@@ -146,6 +146,9 @@
   CompoundName.from(List<jsAst.Name> parts) : this(<_NamerName>[...parts]);
 
   @override
+  bool get isFinalized => _parts.every((name) => name.isFinalized);
+
+  @override
   String get name {
     if (_cachedName == null) {
       _cachedName = _parts.map((jsAst.Name name) => name.name).join();
diff --git a/pkg/compiler/lib/src/js_backend/runtime_types.dart b/pkg/compiler/lib/src/js_backend/runtime_types.dart
index c24e828..e7113df 100644
--- a/pkg/compiler/lib/src/js_backend/runtime_types.dart
+++ b/pkg/compiler/lib/src/js_backend/runtime_types.dart
@@ -533,7 +533,6 @@
     TypeVariableTests typeVariableTests = new TypeVariableTests(
         _elementEnvironment,
         _commonElements,
-        _types,
         codegenWorld,
         _genericInstantiations,
         forRtiNeeds: false);
diff --git a/pkg/compiler/lib/src/js_backend/runtime_types_codegen.dart b/pkg/compiler/lib/src/js_backend/runtime_types_codegen.dart
index ce9fd1d..76e240e 100644
--- a/pkg/compiler/lib/src/js_backend/runtime_types_codegen.dart
+++ b/pkg/compiler/lib/src/js_backend/runtime_types_codegen.dart
@@ -57,6 +57,10 @@
     _map[check.cls] = check;
   }
 
+  void addAll(Iterable<TypeCheck> checks) {
+    checks.forEach(add);
+  }
+
   TypeCheck operator [](ClassEntity cls) => _map[cls];
 
   Iterable<TypeCheck> get checks => _map.values;
diff --git a/pkg/compiler/lib/src/js_backend/runtime_types_new.dart b/pkg/compiler/lib/src/js_backend/runtime_types_new.dart
index 49e6c25..3c9f11f 100644
--- a/pkg/compiler/lib/src/js_backend/runtime_types_new.dart
+++ b/pkg/compiler/lib/src/js_backend/runtime_types_new.dart
@@ -466,6 +466,7 @@
   bool get isNotEmpty => _redirections.isNotEmpty || _entries.isNotEmpty;
 
   void addRedirection(ClassEntity redirectee, ClassEntity target) {
+    assert(redirectee != target);
     _redirections[redirectee] = target;
   }
 
diff --git a/pkg/compiler/lib/src/js_backend/runtime_types_resolution.dart b/pkg/compiler/lib/src/js_backend/runtime_types_resolution.dart
index 7afc77e..258fe15 100644
--- a/pkg/compiler/lib/src/js_backend/runtime_types_resolution.dart
+++ b/pkg/compiler/lib/src/js_backend/runtime_types_resolution.dart
@@ -197,11 +197,18 @@
 }
 
 class TypeVariableTests {
-  Map<ClassEntity, ClassNode> _classes = {};
-  Map<Entity, MethodNode> _methods = {};
-  Map<MemberEntity, CallablePropertyNode> _callableProperties = {};
+  final ElementEnvironment _elementEnvironment;
+  final CommonElements _commonElements;
+  final BuiltWorld _world;
+  final Set<GenericInstantiation> _genericInstantiations;
+  final bool forRtiNeeds;
+
+  final Map<ClassEntity, ClassNode> _classes = {};
+  final Map<Entity, MethodNode> _methods = {};
+  final Map<MemberEntity, CallablePropertyNode> _callableProperties = {};
   Map<Selector, Set<Entity>> _appliedSelectorMap;
-  Map<GenericInstantiation, Set<Entity>> _instantiationMap;
+  final Map<Entity, Set<GenericInstantiation>> _instantiationMap = {};
+  final Map<ClassEntity, Set<InterfaceType>> _classInstantiationMap = {};
 
   /// All explicit is-tests.
   final Set<DartType> explicitIsChecks;
@@ -209,25 +216,22 @@
   /// All implicit is-tests.
   final Set<DartType> implicitIsChecks = new Set<DartType>();
 
-  TypeVariableTests(
-      ElementEnvironment elementEnvironment,
-      CommonElements commonElements,
-      DartTypes types,
-      BuiltWorld world,
-      Set<GenericInstantiation> genericInstantiations,
-      {bool forRtiNeeds: true})
-      : explicitIsChecks = new Set<DartType>.from(world.isChecks) {
-    _setupDependencies(
-        elementEnvironment, commonElements, world, genericInstantiations,
-        forRtiNeeds: forRtiNeeds);
-    _propagateTests(commonElements, elementEnvironment, world);
+  TypeVariableTests(this._elementEnvironment, this._commonElements, this._world,
+      this._genericInstantiations,
+      {this.forRtiNeeds: true})
+      : explicitIsChecks = _world.isChecks.toSet() {
+    _setupDependencies();
+    _propagateTests();
     if (forRtiNeeds) {
-      _propagateLiterals(elementEnvironment, world);
+      _propagateLiterals();
     }
-    _collectResults(commonElements, elementEnvironment, types, world,
-        forRtiNeeds: forRtiNeeds);
+    _collectResults();
   }
 
+  ClassHierarchy get _classHierarchy => _world.classHierarchy;
+
+  DartTypes get _dartTypes => _commonElements.dartTypes;
+
   /// Classes whose type variables are explicitly or implicitly used in
   /// is-tests.
   ///
@@ -323,17 +327,16 @@
 
   /// Calls [f] for each generic instantiation that applies to generic
   /// closurized [targets].
-  void forEachGenericInstantiation(
-      void f(GenericInstantiation instantiation, Set<Entity> targets)) {
-    _instantiationMap?.forEach(f);
+  void forEachInstantiatedEntity(
+      void f(Entity target, Set<GenericInstantiation> instantiations)) {
+    _instantiationMap.forEach(f);
   }
 
   ClassNode _getClassNode(ClassEntity cls) {
     return _classes.putIfAbsent(cls, () => ClassNode(cls));
   }
 
-  MethodNode _getMethodNode(ElementEnvironment elementEnvironment,
-      BuiltWorld world, Entity function) {
+  MethodNode _getMethodNode(Entity function) {
     return _methods.putIfAbsent(function, () {
       MethodNode node;
       if (function is FunctionEntity) {
@@ -341,11 +344,11 @@
         bool isCallTarget;
         bool isNoSuchMethod;
         if (function.isInstanceMember) {
-          isCallTarget = world.closurizedMembers.contains(function);
+          isCallTarget = _world.closurizedMembers.contains(function);
           instanceName = function.memberName;
           isNoSuchMethod = instanceName.text == Identifiers.noSuchMethod_;
         } else {
-          isCallTarget = world.closurizedStatics.contains(function);
+          isCallTarget = _world.closurizedStatics.contains(function);
           isNoSuchMethod = false;
         }
         node = new MethodNode(function, function.parameterStructure,
@@ -354,7 +357,7 @@
             isNoSuchMethod: isNoSuchMethod);
       } else {
         ParameterStructure parameterStructure = new ParameterStructure.fromType(
-            elementEnvironment.getLocalFunctionType(function));
+            _elementEnvironment.getLocalFunctionType(function));
         node = new MethodNode(function, parameterStructure, isCallTarget: true);
       }
       return node;
@@ -366,12 +369,7 @@
       _callableProperties.putIfAbsent(
           property, () => CallablePropertyNode(property, type));
 
-  void _setupDependencies(
-      ElementEnvironment elementEnvironment,
-      CommonElements commonElements,
-      BuiltWorld world,
-      Set<GenericInstantiation> genericInstantiations,
-      {bool forRtiNeeds: true}) {
+  void _setupDependencies() {
     /// Register that if `node.entity` needs type arguments then so do entities
     /// whose type variables occur in [type].
     ///
@@ -386,12 +384,32 @@
         if (typeDeclaration is ClassEntity) {
           node.addDependency(_getClassNode(typeDeclaration));
         } else {
-          node.addDependency(
-              _getMethodNode(elementEnvironment, world, typeDeclaration));
+          node.addDependency(_getMethodNode(typeDeclaration));
         }
       });
     }
 
+    void registerDependenciesForInstantiation(RtiNode node, DartType type) {
+      void onInterface(InterfaceType type) {
+        if (type.typeArguments.isNotEmpty) {
+          node.addDependency(_getClassNode(type.element));
+        }
+      }
+
+      void onTypeVariable(TypeVariableType type) {
+        Entity declaration = type.element.typeDeclaration;
+        if (declaration is ClassEntity) {
+          node.addDependency(_getClassNode(declaration));
+        } else {
+          node.addDependency(_getMethodNode(declaration));
+        }
+      }
+
+      _DependencyVisitor(
+              onInterface: onInterface, onTypeVariable: onTypeVariable)
+          .run(type);
+    }
+
     // Add the rti dependencies that are implicit in the way the backend
     // generates code: when we create a new [List], we actually create a
     // [JSArray] in the backend and we need to add type arguments to the calls
@@ -412,17 +430,17 @@
     //
     // TODO(johnniwinther): Make this dependency visible from code, possibly
     // using generic methods.
-    if (commonElements.jsArrayClass != null) {
-      _getClassNode(commonElements.jsArrayClass)
-          .addDependency(_getClassNode(commonElements.listClass));
+    if (_commonElements.jsArrayClass != null) {
+      _getClassNode(_commonElements.jsArrayClass)
+          .addDependency(_getClassNode(_commonElements.listClass));
     }
-    if (commonElements.setLiteralClass != null) {
-      _getClassNode(commonElements.setLiteralClass)
-          .addDependency(_getClassNode(commonElements.setClass));
+    if (_commonElements.setLiteralClass != null) {
+      _getClassNode(_commonElements.setLiteralClass)
+          .addDependency(_getClassNode(_commonElements.setClass));
     }
-    if (commonElements.mapLiteralClass != null) {
-      _getClassNode(commonElements.mapLiteralClass)
-          .addDependency(_getClassNode(commonElements.mapClass));
+    if (_commonElements.mapLiteralClass != null) {
+      _getClassNode(_commonElements.mapLiteralClass)
+          .addDependency(_getClassNode(_commonElements.mapClass));
     }
 
     void processCheckedType(DartType type) {
@@ -439,36 +457,36 @@
         // For the implied `is Future<X>` test, register that if `Future` needs
         // type arguments then so do the entities that declare type variables
         // occurring in `type.typeArgument`.
-        registerDependencies(_getClassNode(commonElements.futureClass),
+        registerDependencies(_getClassNode(_commonElements.futureClass),
             typeWithoutNullability.typeArgument);
         // Process `type.typeArgument` for the implied `is X` test.
         processCheckedType(typeWithoutNullability.typeArgument);
       }
     }
 
-    world.isChecks.forEach(processCheckedType);
+    _world.isChecks.forEach(processCheckedType);
 
-    world.instantiatedTypes.forEach((InterfaceType type) {
+    _world.instantiatedTypes.forEach((InterfaceType type) {
       // Register that if [cls] needs type arguments then so do the entities
       // that declare type variables occurring in [type].
       ClassEntity cls = type.element;
       registerDependencies(_getClassNode(cls), type);
+      _classInstantiationMap.putIfAbsent(cls, () => {}).add(type);
     });
 
-    world.forEachStaticTypeArgument(
+    _world.forEachStaticTypeArgument(
         (Entity entity, Iterable<DartType> typeArguments) {
       for (DartType type in typeArguments) {
         // Register that if [entity] needs type arguments then so do the
         // entities that declare type variables occurring in [type].
-        registerDependencies(
-            _getMethodNode(elementEnvironment, world, entity), type);
+        registerDependencies(_getMethodNode(entity), type);
       }
     });
 
-    world.forEachDynamicTypeArgument(
+    _world.forEachDynamicTypeArgument(
         (Selector selector, Iterable<DartType> typeArguments) {
       void processCallableNode(CallableNode node) {
-        if (node.selectorApplies(selector, world)) {
+        if (node.selectorApplies(selector, _world)) {
           for (DartType type in typeArguments) {
             // Register that if `node.entity` needs type arguments then so do
             // the entities that declare type variables occurring in [type].
@@ -478,7 +496,7 @@
       }
 
       void processMethod(Entity entity) {
-        MethodNode node = _getMethodNode(elementEnvironment, world, entity);
+        MethodNode node = _getMethodNode(entity);
         processCallableNode(node);
       }
 
@@ -487,55 +505,45 @@
         processCallableNode(node);
       }
 
-      world.forEachGenericInstanceMethod(processMethod);
-      world.genericLocalFunctions.forEach(processMethod);
-      world.closurizedStatics.forEach(processMethod);
-      world.userNoSuchMethods.forEach(processMethod);
-      world.genericCallableProperties.forEach(processCallableProperty);
+      _world.forEachGenericInstanceMethod(processMethod);
+      _world.genericLocalFunctions.forEach(processMethod);
+      _world.closurizedStatics.forEach(processMethod);
+      _world.userNoSuchMethods.forEach(processMethod);
+      _world.genericCallableProperties.forEach(processCallableProperty);
     });
 
-    for (GenericInstantiation instantiation in genericInstantiations) {
+    for (GenericInstantiation instantiation in _genericInstantiations) {
       void processEntity(Entity entity) {
-        MethodNode node = _getMethodNode(elementEnvironment, world, entity);
-        if (node.parameterStructure.typeParameters ==
-            instantiation.typeArguments.length) {
-          if (forRtiNeeds) {
-            _instantiationMap ??= <GenericInstantiation, Set<Entity>>{};
-            _instantiationMap
-                .putIfAbsent(instantiation, () => new Set<Entity>())
-                .add(entity);
-          }
+        MethodNode node = _getMethodNode(entity);
+        if (node.parameterStructure ==
+            ParameterStructure.fromType(instantiation.functionType)) {
+          _instantiationMap.putIfAbsent(entity, () => {}).add(instantiation);
           for (DartType type in instantiation.typeArguments) {
-            // Register that if `node.entity` needs type arguments then so do
-            // the entities that declare type variables occurring in [type].
-            registerDependencies(node, type);
+            registerDependenciesForInstantiation(node, type);
           }
         }
       }
 
-      world.closurizedMembers.forEach(processEntity);
-      world.closurizedStatics.forEach(processEntity);
-      world.genericLocalFunctions.forEach(processEntity);
+      _world.closurizedMembers.forEach(processEntity);
+      _world.closurizedStatics.forEach(processEntity);
+      _world.genericLocalFunctions.forEach(processEntity);
     }
   }
 
-  void _propagateTests(CommonElements commonElements,
-      ElementEnvironment elementEnvironment, BuiltWorld worldBuilder) {
+  void _propagateTests() {
     void processTypeVariableType(TypeVariableType type, {bool direct: true}) {
       TypeVariableEntity variable = type.element;
       if (variable.typeDeclaration is ClassEntity) {
         _getClassNode(variable.typeDeclaration).markTest(direct: direct);
       } else {
-        _getMethodNode(
-                elementEnvironment, worldBuilder, variable.typeDeclaration)
-            .markTest(direct: direct);
+        _getMethodNode(variable.typeDeclaration).markTest(direct: direct);
       }
     }
 
     void processType(DartType type, {bool direct: true}) {
       var typeWithoutNullability = type.withoutNullability;
       if (typeWithoutNullability is FutureOrType) {
-        _getClassNode(commonElements.futureClass).markIndirectTest();
+        _getClassNode(_commonElements.futureClass).markIndirectTest();
         processType(typeWithoutNullability.typeArgument, direct: false);
       } else {
         typeWithoutNullability.forEachTypeVariable((TypeVariableType type) {
@@ -544,18 +552,17 @@
       }
     }
 
-    worldBuilder.isChecks.forEach(processType);
+    _world.isChecks.forEach(processType);
   }
 
-  void _propagateLiterals(
-      ElementEnvironment elementEnvironment, BuiltWorld world) {
-    world.typeVariableTypeLiterals.forEach((TypeVariableType typeVariableType) {
+  void _propagateLiterals() {
+    _world.typeVariableTypeLiterals
+        .forEach((TypeVariableType typeVariableType) {
       TypeVariableEntity variable = typeVariableType.element;
       if (variable.typeDeclaration is ClassEntity) {
         _getClassNode(variable.typeDeclaration).markDirectLiteral();
       } else {
-        _getMethodNode(elementEnvironment, world, variable.typeDeclaration)
-            .markDirectLiteral();
+        _getMethodNode(variable.typeDeclaration).markDirectLiteral();
       }
     });
   }
@@ -608,34 +615,63 @@
     return sb.toString();
   }
 
-  void _collectResults(CommonElements commonElements,
-      ElementEnvironment elementEnvironment, DartTypes types, BuiltWorld world,
-      {bool forRtiNeeds: true}) {
-    /// Register the implicit is-test of [type].
-    ///
-    /// If [type] is of the form `FutureOr<X>`, also register the implicit
-    /// is-tests of `Future<X>` and `X`.
-    void addImplicitCheck(DartType type) {
-      var typeWithoutNullability = type.withoutNullability;
-      if (implicitIsChecks.add(typeWithoutNullability)) {
-        if (typeWithoutNullability is FutureOrType) {
-          addImplicitCheck(
-              commonElements.futureType(typeWithoutNullability.typeArgument));
-          addImplicitCheck(typeWithoutNullability.typeArgument);
-        }
+  /// Register the implicit is-test of [type].
+  ///
+  /// If [type] is of the form `FutureOr<X>`, also register the implicit
+  /// is-tests of `Future<X>` and `X`.
+  void _addImplicitCheck(DartType type) {
+    var typeWithoutNullability = type.withoutNullability;
+    if (implicitIsChecks.add(typeWithoutNullability)) {
+      if (typeWithoutNullability is FutureOrType) {
+        _addImplicitCheck(
+            _commonElements.futureType(typeWithoutNullability.typeArgument));
+        _addImplicitCheck(typeWithoutNullability.typeArgument);
+      } else if (typeWithoutNullability is TypeVariableType) {
+        _addImplicitChecksViaInstantiation(typeWithoutNullability);
       }
     }
+  }
 
-    void addImplicitChecks(Iterable<DartType> types) {
-      types.forEach(addImplicitCheck);
+  void _addImplicitChecks(Iterable<DartType> types) {
+    types.forEach(_addImplicitCheck);
+  }
+
+  void _addImplicitChecksViaInstantiation(TypeVariableType variable) {
+    TypeVariableEntity entity = variable.element;
+    Entity declaration = entity.typeDeclaration;
+    if (declaration is ClassEntity) {
+      _classInstantiationMap[declaration]?.forEach((InterfaceType type) {
+        _addImplicitCheck(type.typeArguments[entity.index]);
+      });
+    } else {
+      _instantiationMap[declaration]
+          ?.forEach((GenericInstantiation instantiation) {
+        _addImplicitCheck(instantiation.typeArguments[entity.index]);
+      });
+      _world.forEachStaticTypeArgument(
+          (Entity function, Set<DartType> typeArguments) {
+        if (declaration == function) {
+          _addImplicitChecks(typeArguments);
+        }
+      });
+      _world.forEachDynamicTypeArgument(
+          (Selector selector, Set<DartType> typeArguments) {
+        if (_getMethodNode(declaration).selectorApplies(selector, _world)) {
+          _addImplicitChecks(typeArguments);
+        }
+      });
     }
+  }
 
-    world.isChecks.forEach((DartType type) {
+  void _collectResults() {
+    _world.isChecks.forEach((DartType type) {
       var typeWithoutNullability = type.withoutNullability;
       if (typeWithoutNullability is FutureOrType) {
-        addImplicitCheck(
-            commonElements.futureType(typeWithoutNullability.typeArgument));
-        addImplicitCheck(typeWithoutNullability.typeArgument);
+        _addImplicitCheck(
+            _commonElements.futureType(typeWithoutNullability.typeArgument));
+        _addImplicitCheck(typeWithoutNullability.typeArgument);
+      } else if (typeWithoutNullability is TypeVariableType) {
+        _addImplicitChecksViaInstantiation(typeWithoutNullability);
       }
     });
 
@@ -643,48 +679,45 @@
     // is-checks and add the is-checks that they imply.
     _classes.forEach((ClassEntity cls, ClassNode node) {
       if (!node.hasTest) return;
+
       // Find all instantiated types that are a subtype of a class that uses
       // one of its type arguments in an is-check and add the arguments to the
       // set of is-checks.
-      for (InterfaceType type in world.instantiatedTypes) {
-        // We need the type as instance of its superclass anyway, so we just
-        // try to compute the substitution; if the result is [:null:], the
-        // classes are not related.
-        InterfaceType instance = types.asInstanceOf(type, cls);
-        if (instance != null) {
-          for (DartType argument in instance.typeArguments) {
-            addImplicitCheck(argument);
-          }
-        }
+      for (ClassEntity base in _classHierarchy.allSubtypesOf(cls)) {
+        _classInstantiationMap[base]?.forEach((InterfaceType subtype) {
+          InterfaceType instance = _dartTypes.asInstanceOf(subtype, cls);
+          assert(instance != null);
+          _addImplicitChecks(instance.typeArguments);
+        });
       }
     });
 
-    world.forEachStaticTypeArgument(
+    _world.forEachStaticTypeArgument(
         (Entity function, Iterable<DartType> typeArguments) {
-      if (!_getMethodNode(elementEnvironment, world, function).hasTest) {
+      if (!_getMethodNode(function).hasTest) {
         return;
       }
-      addImplicitChecks(typeArguments);
+      _addImplicitChecks(typeArguments);
     });
 
     if (forRtiNeeds) {
       _appliedSelectorMap = <Selector, Set<Entity>>{};
     }
 
-    world.forEachDynamicTypeArgument(
+    _world.forEachDynamicTypeArgument(
         (Selector selector, Iterable<DartType> typeArguments) {
       for (CallableNode node in [
         ..._methods.values,
         ..._callableProperties.values
       ]) {
-        if (node.selectorApplies(selector, world)) {
+        if (node.selectorApplies(selector, _world)) {
           if (forRtiNeeds) {
             _appliedSelectorMap
                 .putIfAbsent(selector, () => {})
                 .add(node.entity);
           }
           if (node.hasTest) {
-            addImplicitChecks(typeArguments);
+            _addImplicitChecks(typeArguments);
           }
         }
       }
@@ -692,6 +725,25 @@
   }
 }
 
+class _DependencyVisitor extends DartTypeStructuralPredicateVisitor {
+  void Function(InterfaceType) onInterface;
+  void Function(TypeVariableType) onTypeVariable;
+
+  _DependencyVisitor({this.onInterface, this.onTypeVariable});
+
+  @override
+  bool handleInterfaceType(InterfaceType type) {
+    onInterface(type);
+    return false;
+  }
+
+  @override
+  bool handleTypeVariableType(TypeVariableType type) {
+    onTypeVariable(type);
+    return false;
+  }
+}
+
 /// Interface for the classes and methods that need runtime types.
 abstract class RuntimeTypesNeed {
   /// Deserializes a [RuntimeTypesNeed] object from [source].
@@ -770,7 +822,7 @@
   /// arguments.
   // TODO(johnniwinther): Use [functionType].
   bool instantiationNeedsTypeArguments(
-      DartType functionType, int typeArgumentCount);
+      FunctionType functionType, int typeArgumentCount);
 }
 
 class TrivialRuntimeTypesNeed implements RuntimeTypesNeed {
@@ -804,7 +856,7 @@
 
   @override
   bool instantiationNeedsTypeArguments(
-      DartType functionType, int typeArgumentCount) {
+      FunctionType functionType, int typeArgumentCount) {
     return true;
   }
 }
@@ -903,7 +955,7 @@
 
   @override
   bool instantiationNeedsTypeArguments(
-      DartType functionType, int typeArgumentCount) {
+      FunctionType functionType, int typeArgumentCount) {
     return instantiationsNeedingTypeArguments.contains(typeArgumentCount);
   }
 }
@@ -963,8 +1015,11 @@
 
   Map<Selector, Set<Entity>> selectorsNeedingTypeArgumentsForTesting;
 
-  Map<GenericInstantiation, Set<Entity>>
-      instantiationsNeedingTypeArgumentsForTesting;
+  Map<Entity, Set<GenericInstantiation>>
+      _instantiatedEntitiesNeedingTypeArgumentsForTesting;
+  Map<Entity, Set<GenericInstantiation>>
+      get instantiatedEntitiesNeedingTypeArgumentsForTesting =>
+          _instantiatedEntitiesNeedingTypeArgumentsForTesting ?? const {};
 
   final Set<GenericInstantiation> _genericInstantiations =
       new Set<GenericInstantiation>();
@@ -999,7 +1054,6 @@
     TypeVariableTests typeVariableTests = new TypeVariableTests(
         closedWorld.elementEnvironment,
         closedWorld.commonElements,
-        closedWorld.dartTypes,
         closedWorld,
         _genericInstantiations);
     Set<ClassEntity> classesNeedingTypeArguments = new Set<ClassEntity>();
@@ -1348,24 +1402,19 @@
       }
     });
     Set<int> instantiationsNeedingTypeArguments = new Set<int>();
-    typeVariableTests.forEachGenericInstantiation(
-        (GenericInstantiation instantiation, Set<Entity> targets) {
-      for (Entity target in targets) {
-        if (methodsNeedingTypeArguments.contains(target) ||
-            localFunctionsNeedingTypeArguments.contains(target)) {
-          // TODO(johnniwinther): Use the static type of the instantiated
-          // expression.
-          instantiationsNeedingTypeArguments
-              .add(instantiation.typeArguments.length);
-          if (retainDataForTesting) {
-            instantiationsNeedingTypeArgumentsForTesting ??=
-                <GenericInstantiation, Set<Entity>>{};
-            instantiationsNeedingTypeArgumentsForTesting
-                .putIfAbsent(instantiation, () => new Set<Entity>())
-                .add(target);
-          } else {
-            return;
-          }
+    typeVariableTests.forEachInstantiatedEntity(
+        (Entity target, Set<GenericInstantiation> instantiations) {
+      if (methodsNeedingTypeArguments.contains(target) ||
+          localFunctionsNeedingTypeArguments.contains(target)) {
+        // TODO(johnniwinther): Use the static type of the instantiated
+        // expression.
+        instantiationsNeedingTypeArguments
+            .add(instantiations.first.typeArguments.length);
+        if (retainDataForTesting) {
+          _instantiatedEntitiesNeedingTypeArgumentsForTesting ??= {};
+          _instantiatedEntitiesNeedingTypeArgumentsForTesting
+              .putIfAbsent(target, () => {})
+              .addAll(instantiations);
         }
       }
     });
diff --git a/pkg/compiler/lib/src/js_emitter/code_emitter_task.dart b/pkg/compiler/lib/src/js_emitter/code_emitter_task.dart
index fb72825..d52a591 100644
--- a/pkg/compiler/lib/src/js_emitter/code_emitter_task.dart
+++ b/pkg/compiler/lib/src/js_emitter/code_emitter_task.dart
@@ -5,6 +5,7 @@
 library dart2js.js_emitter.code_emitter_task;
 
 import '../common.dart';
+import '../common/metrics.dart' show Metric, Metrics, CountMetric;
 import '../common/tasks.dart' show CompilerTask;
 import '../compiler.dart' show Compiler;
 import '../constants/values.dart';
@@ -20,7 +21,7 @@
 import '../world.dart' show JClosedWorld;
 import 'program_builder/program_builder.dart';
 import 'startup_emitter/emitter.dart' as startup_js_emitter;
-import 'startup_emitter/fragment_merger.dart' as fragment_merger;
+import 'startup_emitter/fragment_merger.dart';
 
 import 'metadata_collector.dart' show MetadataCollector;
 import 'model.dart';
@@ -50,6 +51,9 @@
   /// Contains a list of all classes that are emitted.
   Set<ClassEntity> neededClasses;
 
+  @override
+  final _EmitterMetrics metrics = _EmitterMetrics();
+
   CodeEmitterTask(this._compiler, this._generateSourceMap)
       : super(_compiler.measurer);
 
@@ -207,7 +211,16 @@
 abstract class Emitter implements ModularEmitter {
   Program get programForTesting;
 
-  List<fragment_merger.PreFragment> get preDeferredFragmentsForTesting;
+  List<PreFragment> get preDeferredFragmentsForTesting;
+
+  /// The set of omitted [OutputUnits].
+  Set<OutputUnit> get omittedOutputUnits;
+
+  /// A map of loadId to list of [FinalizedFragments].
+  Map<String, List<FinalizedFragment>> get finalizedFragmentsToLoad;
+
+  /// The [FragmentMerger] itself.
+  FragmentMerger get fragmentMerger;
 
   /// Uses the [programBuilder] to generate a model of the program, emits
   /// the program, and returns the size of the generated output.
@@ -228,3 +241,16 @@
   /// Returns the size of the code generated for a given output [unit].
   int generatedSize(OutputUnit unit);
 }
+
+class _EmitterMetrics implements Metrics {
+  @override
+  String get namespace => 'emitter';
+
+  CountMetric hunkListElements = CountMetric('hunkListElements');
+
+  @override
+  Iterable<Metric> get primary => [];
+
+  @override
+  Iterable<Metric> get secondary => [hunkListElements];
+}
diff --git a/pkg/compiler/lib/src/js_emitter/model.dart b/pkg/compiler/lib/src/js_emitter/model.dart
index 2cdfb73..1ab1d09 100644
--- a/pkg/compiler/lib/src/js_emitter/model.dart
+++ b/pkg/compiler/lib/src/js_emitter/model.dart
@@ -21,9 +21,6 @@
   final bool needsNativeSupport;
   final bool hasSoftDeferredClasses;
 
-  /// A map from load id to the list of fragments that need to be loaded.
-  final Map<String, List<Fragment>> loadMap;
-
   // If this field is not `null` then its value must be emitted in the embedded
   // global `TYPE_TO_INTERCEPTOR_MAP`. The map references constants and classes.
   final js.Expression typeToInterceptorMap;
@@ -33,7 +30,7 @@
   final MetadataCollector _metadataCollector;
   final Iterable<js.TokenFinalizer> finalizers;
 
-  Program(this.fragments, this.holders, this.loadMap, this.typeToInterceptorMap,
+  Program(this.fragments, this.holders, this.typeToInterceptorMap,
       this._metadataCollector, this.finalizers,
       {this.needsNativeSupport,
       this.outputContainsConstantList,
@@ -264,6 +261,9 @@
   /// Uses indicate missing information in the model.
   final ClassEntity element;
 
+  // TODO(joshualitt): Now that we collect all rti needed classes and handle
+  // them separately, we should investigate whether or not we still need to
+  // store the type data on the class.
   final ClassTypeData typeData;
 
   final js.Name name;
diff --git a/pkg/compiler/lib/src/js_emitter/program_builder/collector.dart b/pkg/compiler/lib/src/js_emitter/program_builder/collector.dart
index bac69a0..f4afd75 100644
--- a/pkg/compiler/lib/src/js_emitter/program_builder/collector.dart
+++ b/pkg/compiler/lib/src/js_emitter/program_builder/collector.dart
@@ -24,7 +24,6 @@
 
   final Set<ClassEntity> neededClasses = {};
   final Set<ClassEntity> neededClassTypes = {};
-  final Set<ClassEntity> classesOnlyNeededForRti = {};
   final Set<ClassEntity> classesOnlyNeededForConstructor = {};
   final Map<OutputUnit, List<ClassEntity>> outputClassLists = {};
   final Map<OutputUnit, List<ClassEntity>> outputClassTypeLists = {};
@@ -140,17 +139,6 @@
     Set<ClassEntity> backendTypeHelpers =
         getBackendTypeHelpers(_commonElements).toSet();
 
-    /// A class type is 'shadowed' if the class is needed for direct
-    /// instantiation in one OutputUnit while its type is needed in another
-    /// OutputUnit.
-    bool isClassTypeShadowed(ClassEntity cls) {
-      return !backendTypeHelpers.contains(cls) &&
-          _rtiNeededClasses.contains(cls) &&
-          !classesOnlyNeededForRti.contains(cls) &&
-          _outputUnitData.outputUnitForClass(cls) !=
-              _outputUnitData.outputUnitForClassType(cls);
-    }
-
     // Compute needed classes.
     Set<ClassEntity> instantiatedClasses =
         // TODO(johnniwinther): This should be accessed from a codegen closed
@@ -184,20 +172,10 @@
       }
     }
 
-    // 4. Find all classes needed for rti.
-    // It is important that this is the penultimate step, at this point,
-    // neededClasses must only contain classes that have been resolved and
-    // codegen'd. The rtiNeededClasses may contain additional classes, but
-    // these are thought to not have been instantiated, so we need to be able
-    // to identify them later and make sure we only emit "empty shells" without
-    // fields, etc.
+    // 4. Find all class types needed for rti.
     for (ClassEntity cls in _rtiNeededClasses) {
       if (backendTypeHelpers.contains(cls)) continue;
-      while (cls != null && !neededClasses.contains(cls)) {
-        if (!classesOnlyNeededForRti.add(cls)) break;
-        // TODO(joshualitt) delete classesOnlyNeededForRti when the
-        // no-defer-class_types flag is removed.
-        neededClassTypes.add(cls);
+      while (cls != null && neededClassTypes.add(cls)) {
         cls = _elementEnvironment.getSuperClass(cls);
       }
     }
@@ -219,14 +197,7 @@
       }
     }
 
-    // 6. Collect any class types 'shadowed' by direct instantiation.
-    for (ClassEntity cls in _rtiNeededClasses) {
-      if (isClassTypeShadowed(cls)) {
-        neededClassTypes.add(cls);
-      }
-    }
-
-    // 7. Sort classes needed for type checking and then add them to their
+    // 6. Sort classes needed for type checking and then add them to their
     // respective OutputUnits.
     for (ClassEntity cls in _sorter.sortClasses(neededClassTypes)) {
       outputClassTypeLists
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 0cd7059..fdb45f9 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
@@ -27,6 +27,7 @@
 import '../../js_backend/namer.dart' show Namer, StringBackedName;
 import '../../js_backend/native_data.dart';
 import '../../js_backend/runtime_types.dart' show RuntimeTypesChecks;
+import '../../js_backend/runtime_types_codegen.dart' show TypeCheck;
 import '../../js_backend/runtime_types_new.dart'
     show RecipeEncoder, RecipeEncoding;
 import '../../js_backend/runtime_types_new.dart' as newRti;
@@ -167,7 +168,10 @@
 
   Set<Class> _unneededNativeClasses;
 
+  ClassEntity get _jsInteropInterceptor =>
+      _commonElements.jsJavaScriptObjectClass;
   List<StubMethod> _jsInteropIsChecks = [];
+  final Set<TypeCheck> _jsInteropTypeChecks = {};
 
   /// Classes that have been allocated during a profile run.
   ///
@@ -199,15 +203,14 @@
     // We need to run the native-preparation before we build the output. The
     // preparation code, in turn needs the classes to be set up.
     // We thus build the classes before building their containers.
-    collector.outputClassLists
-        .forEach((OutputUnit _, List<ClassEntity> classes) {
-      classes.forEach(_buildClass);
-    });
-
     collector.outputClassTypeLists
         .forEach((OutputUnit _, List<ClassEntity> types) {
       types.forEach(_buildClassTypeData);
     });
+    collector.outputClassLists
+        .forEach((OutputUnit _, List<ClassEntity> classes) {
+      classes.forEach(_buildClass);
+    });
 
     // Resolve the superclass references after we've processed all the classes.
     _classes.forEach((ClassEntity cls, Class c) {
@@ -273,8 +276,8 @@
       finalizers.add(namingFinalizer as js.TokenFinalizer);
     }
 
-    return new Program(fragments, holders, _buildLoadMap(),
-        _buildTypeToInterceptorMap(), _task.metadataCollector, finalizers,
+    return new Program(fragments, holders, _buildTypeToInterceptorMap(),
+        _task.metadataCollector, finalizers,
         needsNativeSupport: needsNativeSupport,
         outputContainsConstantList: collector.outputContainsConstantList,
         hasSoftDeferredClasses: _notSoftDeferred != null);
@@ -348,18 +351,6 @@
     }
   }
 
-  /// Builds a map from loadId to outputs-to-load.
-  Map<String, List<Fragment>> _buildLoadMap() {
-    Map<String, List<Fragment>> loadMap = <String, List<Fragment>>{};
-    _closedWorld.outputUnitData.hunksToLoad
-        .forEach((String loadId, List<OutputUnit> outputUnits) {
-      loadMap[loadId] = outputUnits
-          .map((OutputUnit unit) => _outputs[unit])
-          .toList(growable: false);
-    });
-    return loadMap;
-  }
-
   js.Expression _buildTypeToInterceptorMap() {
     InterceptorStubGenerator stubGenerator = new InterceptorStubGenerator(
         _commonElements,
@@ -509,9 +500,12 @@
     // a regular getter that returns a JavaScript function and tearing off
     // a method in the case where there exist multiple JavaScript classes
     // that conflict on whether the member is a getter or a method.
-    Class interceptorClass = _classes[_commonElements.jsJavaScriptObjectClass];
+    Class interceptorClass = _classes[_jsInteropInterceptor];
+    ClassTypeData interceptorTypeData = _classTypeData[_jsInteropInterceptor];
 
     interceptorClass?.isChecks?.addAll(_jsInteropIsChecks);
+    interceptorTypeData?.classChecks?.addAll(_jsInteropTypeChecks);
+
     Set<String> stubNames = {};
     librariesMap.forEach((LibraryEntity library,
         List<ClassEntity> classElements, _memberElement, _typeElement) {
@@ -652,6 +646,8 @@
   }
 
   Class _buildClass(ClassEntity cls) {
+    ClassTypeData typeData = _buildClassTypeData(cls);
+
     bool onlyForConstructor =
         collector.classesOnlyNeededForConstructor.contains(cls);
     // TODO(joshualitt): Can we just emit JSInteropClasses as types?
@@ -778,6 +774,8 @@
       typeTests.forEachProperty(_sorter, (js.Name name, js.Node code) {
         _jsInteropIsChecks.add(_buildStubMethod(name, code));
       });
+
+      _jsInteropTypeChecks.addAll(typeData.classChecks?.checks ?? const []);
     } else {
       for (Field field in instanceFields) {
         if (field.needsCheckedSetter) {
@@ -809,7 +807,6 @@
     bool isInstantiated = !_nativeData.isJsInteropClass(cls) &&
         _codegenWorld.directlyInstantiatedClasses.contains(cls);
 
-    ClassTypeData typeData = ClassTypeData(cls, _rtiChecks.requiredChecks[cls]);
     Class result;
     if (_elementEnvironment.isMixinApplication(cls) &&
         !onlyForConstructorOrRti &&
@@ -860,9 +857,9 @@
     return result;
   }
 
-  void _buildClassTypeData(ClassEntity cls) {
-    _classTypeData[cls] = ClassTypeData(cls, _rtiChecks.requiredChecks[cls]);
-  }
+  ClassTypeData _buildClassTypeData(ClassEntity cls) =>
+      _classTypeData.putIfAbsent(
+          cls, () => ClassTypeData(cls, _rtiChecks.requiredChecks[cls]));
 
   void associateNamedTypeVariablesNewRti() {
     for (TypeVariableType typeVariable in _codegenWorld.namedTypeVariablesNewRti
@@ -873,14 +870,10 @@
               ? _classHierarchy.subtypesOf(declaration)
               : _classHierarchy.subclassesOf(declaration);
       for (ClassEntity entity in subtypes) {
-        Class cls = _classes[entity];
-        if (cls != null) {
-          cls.typeData.namedTypeVariables.add(typeVariable);
-        }
-        ClassTypeData classTypeData = _classTypeData[entity];
-        if (classTypeData != null) {
-          classTypeData.namedTypeVariables.add(typeVariable);
-        }
+        ClassTypeData classTypeData = _nativeData.isJsInteropClass(entity)
+            ? _buildClassTypeData(_jsInteropInterceptor)
+            : _buildClassTypeData(entity);
+        classTypeData.namedTypeVariables.add(typeVariable);
       }
     }
   }
diff --git a/pkg/compiler/lib/src/js_emitter/startup_emitter/emitter.dart b/pkg/compiler/lib/src/js_emitter/startup_emitter/emitter.dart
index ca28cdb..01c863f 100644
--- a/pkg/compiler/lib/src/js_emitter/startup_emitter/emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/startup_emitter/emitter.dart
@@ -7,7 +7,6 @@
 import '../../../compiler_new.dart';
 import '../../common.dart';
 import '../../common/codegen.dart';
-import '../../common/tasks.dart';
 import '../../constants/values.dart';
 import '../../deferred_load.dart' show OutputUnit;
 import '../../dump_info.dart';
@@ -20,7 +19,7 @@
 import '../../options.dart';
 import '../../universe/codegen_world_builder.dart' show CodegenWorld;
 import '../../world.dart' show JClosedWorld;
-import '../js_emitter.dart' show Emitter, ModularEmitter;
+import '../js_emitter.dart' show CodeEmitterTask, Emitter, ModularEmitter;
 import '../model.dart';
 import '../native_emitter.dart';
 import '../program_builder/program_builder.dart' show ProgramBuilder;
@@ -150,7 +149,7 @@
   final DiagnosticReporter _reporter;
   final JClosedWorld _closedWorld;
   final RecipeEncoder _rtiRecipeEncoder;
-  final CompilerTask _task;
+  final CodeEmitterTask _task;
   ModelEmitter _emitter;
   final NativeEmitter _nativeEmitter;
 
@@ -160,6 +159,15 @@
   @override
   List<PreFragment> preDeferredFragmentsForTesting;
 
+  @override
+  Set<OutputUnit> omittedOutputUnits;
+
+  @override
+  Map<String, List<FinalizedFragment>> finalizedFragmentsToLoad;
+
+  @override
+  FragmentMerger fragmentMerger;
+
   EmitterImpl(
       CompilerOptions options,
       this._reporter,
@@ -201,6 +209,12 @@
     }
     return _task.measureSubtask('emit program', () {
       var size = _emitter.emitProgram(program, codegenWorld);
+      omittedOutputUnits = _emitter.omittedOutputUnits;
+      finalizedFragmentsToLoad = _emitter.finalizedFragmentsToLoad;
+      fragmentMerger = _emitter.fragmentMerger;
+      finalizedFragmentsToLoad.values.forEach((fragments) {
+        _task.metrics.hunkListElements.add(fragments.length);
+      });
       if (retainDataForTesting) {
         preDeferredFragmentsForTesting =
             _emitter.preDeferredFragmentsForTesting;
diff --git a/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart b/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
index 939a39f..2d30782 100644
--- a/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
@@ -713,8 +713,25 @@
     var lazyInitializers = emitLazilyInitializedStatics(fragment);
     // TODO(floitsch): only call emitNativeSupport if we need native.
     var nativeSupport = emitNativeSupport(fragment);
-    return PreFragment(
-        fragment,
+    int size = 0;
+    if (estimateSize) {
+      var estimator = SizeEstimator();
+      estimator.visit(classPrototypes);
+      estimator.visit(closurePrototypes);
+      estimator.visit(inheritance);
+      estimator.visit(methodAliases);
+      estimator.visit(tearOffs);
+      estimator.visit(constants);
+      estimator.visit(typeRules);
+      estimator.visit(variances);
+      estimator.visit(staticNonFinalFields);
+      estimator.visit(lazyInitializers);
+      estimator.visit(nativeSupport);
+      size = estimator.charCount;
+    }
+    var emittedOutputUnit = EmittedOutputUnit(
+        fragment.outputUnit,
+        fragment.libraries,
         classPrototypes,
         closurePrototypes,
         inheritance,
@@ -725,12 +742,14 @@
         variances,
         staticNonFinalFields,
         lazyInitializers,
-        nativeSupport,
-        estimateSize);
+        nativeSupport);
+    return PreFragment(fragment.outputFileName, emittedOutputUnit, size);
   }
 
   js.Statement emitMainFragment(
-      Program program, DeferredLoadingState deferredLoadingState) {
+      Program program,
+      Map<String, List<FinalizedFragment>> fragmentsToLoad,
+      DeferredLoadingState deferredLoadingState) {
     MainFragment fragment = program.fragments.first;
 
     Iterable<Holder> nonStaticStateHolders =
@@ -778,8 +797,8 @@
       'constants': emitConstants(fragment),
       'staticNonFinalFields': emitStaticNonFinalFields(fragment),
       'lazyStatics': emitLazilyInitializedStatics(fragment),
-      'embeddedGlobalsPart1':
-          emitEmbeddedGlobalsPart1(program, deferredLoadingState),
+      'embeddedGlobalsPart1': emitEmbeddedGlobalsPart1(
+          program, fragmentsToLoad, deferredLoadingState),
       'embeddedGlobalsPart2':
           emitEmbeddedGlobalsPart2(program, deferredLoadingState),
       'typeRules': emitTypeRules(fragment),
@@ -830,8 +849,7 @@
     return new js.Block(holderInits);
   }
 
-  js.Expression emitDeferredFragment(
-      FinalizedFragment fragment, List<Holder> holders) {
+  js.Expression emitCodeFragment(CodeFragment fragment, List<Holder> holders) {
     HolderCode holderCode =
         emitHolders(holders, fragment.libraries, initializeEmptyHolders: false);
 
@@ -1874,10 +1892,11 @@
   // array of hashes indexed by part.
   // [deferredLoadHashes] may have missing entries to indicate empty parts.
   void finalizeDeferredLoadingData(
-      Map<String, List<FinalizedFragment>> loadMap,
+      Map<String, List<CodeFragment>> codeFragmentsToLoad,
+      Map<CodeFragment, FinalizedFragment> codeFragmentMap,
       Map<FinalizedFragment, String> deferredLoadHashes,
       DeferredLoadingState deferredLoadingState) {
-    if (loadMap.isEmpty) return;
+    if (codeFragmentsToLoad.isEmpty) return;
 
     Map<FinalizedFragment, int> fragmentIndexes = {};
     List<String> fragmentUris = [];
@@ -1885,9 +1904,11 @@
 
     List<js.Property> libraryPartsMapEntries = [];
 
-    loadMap.forEach((String loadId, List<FinalizedFragment> fragmentList) {
+    codeFragmentsToLoad
+        .forEach((String loadId, List<CodeFragment> codeFragments) {
       List<js.Expression> indexes = [];
-      for (FinalizedFragment fragment in fragmentList) {
+      for (var codeFragment in codeFragments) {
+        var fragment = codeFragmentMap[codeFragment];
         String fragmentHash = deferredLoadHashes[fragment];
         if (fragmentHash == null) continue;
         int index = fragmentIndexes[fragment];
@@ -1971,10 +1992,12 @@
 
   /// Emits all embedded globals.
   js.Statement emitEmbeddedGlobalsPart1(
-      Program program, DeferredLoadingState deferredLoadingState) {
+      Program program,
+      Map<String, List<FinalizedFragment>> fragmentsToLoad,
+      DeferredLoadingState deferredLoadingState) {
     List<js.Property> globals = [];
 
-    if (program.loadMap.isNotEmpty) {
+    if (fragmentsToLoad.isNotEmpty) {
       globals
           .addAll(emitEmbeddedGlobalsForDeferredLoading(deferredLoadingState));
     }
@@ -2037,9 +2060,7 @@
   js.Block emitTypeRules(Fragment fragment) {
     List<js.Statement> statements = [];
 
-    bool addJsObjectRedirections = false;
     ClassEntity jsObjectClass = _commonElements.jsJavaScriptObjectClass;
-    InterfaceType jsObjectType = _elementEnvironment.getThisType(jsObjectClass);
 
     Map<ClassTypeData, List<ClassTypeData>> nativeRedirections =
         _nativeEmitter.typeRedirections;
@@ -2059,50 +2080,44 @@
 
       bool isInterop = _classHierarchy.isSubclassOf(element, jsObjectClass);
 
-      Iterable<TypeCheck> checks = typeData.classChecks?.checks ?? [];
-      Iterable<InterfaceType> supertypes = isInterop
-          ? checks
-              .map((check) => _elementEnvironment.getJsInteropType(check.cls))
-          : checks
-              .map((check) => _dartTypes.asInstanceOf(targetType, check.cls));
-
-      Map<TypeVariableType, DartType> typeVariables = {};
-      Set<TypeVariableType> namedTypeVariables = typeData.namedTypeVariables;
-      nativeRedirections[typeData]?.forEach((ClassTypeData redirectee) {
-        namedTypeVariables.addAll(redirectee.namedTypeVariables);
-      });
-      for (TypeVariableType typeVariable in typeData.namedTypeVariables) {
-        TypeVariableEntity element = typeVariable.element;
-        InterfaceType supertype = isInterop
-            ? _elementEnvironment.getJsInteropType(element.typeDeclaration)
-            : _dartTypes.asInstanceOf(targetType, element.typeDeclaration);
-        List<DartType> supertypeArguments = supertype.typeArguments;
-        typeVariables[typeVariable] = supertypeArguments[element.index];
-      }
-
-      if (isInterop) {
-        ruleset.addEntry(jsObjectType, supertypes, typeVariables);
-        addJsObjectRedirections = true;
+      if (isInterop && element != jsObjectClass) {
+        ruleset.addRedirection(element, jsObjectClass);
       } else {
+        Iterable<TypeCheck> checks = typeData.classChecks?.checks ?? const [];
+        Iterable<InterfaceType> supertypes = isInterop
+            ? checks
+                .map((check) => _elementEnvironment.getJsInteropType(check.cls))
+            : checks
+                .map((check) => _dartTypes.asInstanceOf(targetType, check.cls));
+
+        Map<TypeVariableType, DartType> typeVariables = {};
+        Set<TypeVariableType> namedTypeVariables = typeData.namedTypeVariables;
+        nativeRedirections[typeData]?.forEach((ClassTypeData redirectee) {
+          namedTypeVariables.addAll(redirectee.namedTypeVariables);
+        });
+        for (TypeVariableType typeVariable in typeData.namedTypeVariables) {
+          TypeVariableEntity element = typeVariable.element;
+          InterfaceType supertype = isInterop
+              ? _elementEnvironment.getJsInteropType(element.typeDeclaration)
+              : _dartTypes.asInstanceOf(targetType, element.typeDeclaration);
+          List<DartType> supertypeArguments = supertype.typeArguments;
+          typeVariables[typeVariable] = supertypeArguments[element.index];
+        }
         ruleset.addEntry(targetType, supertypes, typeVariables);
       }
     });
 
-    if (addJsObjectRedirections) {
-      _classHierarchy
-          .strictSubclassesOf(jsObjectClass)
-          .forEach((ClassEntity subclass) {
-        ruleset.addRedirection(subclass, jsObjectClass);
+    // We add native redirections only to the main fragment in order to avoid
+    // duplicating them in multiple deferred units.
+    if (fragment.outputUnit.isMainOutput) {
+      nativeRedirections
+          .forEach((ClassTypeData target, List<ClassTypeData> redirectees) {
+        for (ClassTypeData redirectee in redirectees) {
+          ruleset.addRedirection(redirectee.element, target.element);
+        }
       });
     }
 
-    nativeRedirections
-        .forEach((ClassTypeData target, List<ClassTypeData> redirectees) {
-      for (ClassTypeData redirectee in redirectees) {
-        ruleset.addRedirection(redirectee.element, target.element);
-      }
-    });
-
     if (ruleset.isNotEmpty) {
       FunctionEntity addRules = _closedWorld.commonElements.rtiAddRulesMethod;
       statements.add(js.js.statement('#(init.#,JSON.parse(#));', [
diff --git a/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_merger.dart b/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_merger.dart
index 4802555..8eefc10 100644
--- a/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_merger.dart
+++ b/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_merger.dart
@@ -2,141 +2,239 @@
 // for details. 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 '../../common_elements.dart' show ElementEnvironment;
+import '../../deferred_load.dart'
+    show ImportDescription, OutputUnit, OutputUnitData, deferredPartFileName;
+import '../../elements/entities.dart';
 import '../../deferred_load.dart' show OutputUnit;
 import '../../js/js.dart' as js;
-import '../../js/size_estimator.dart';
 import '../../options.dart';
 import '../model.dart';
 
+/// This file contains a number of abstractions used by dart2js for emitting and
+/// merging deferred fragments.
+///
+/// The initial deferred loading algorithm breaks a program up into multiple
+/// [OutputUnits] where each [OutputUnit] represents part of the user's
+/// program. [OutputUnits] are represented by a unique intersection of imports
+/// known as an import set. Thus, each [OutputUnit] is a node in a deferred
+/// graph. Edges in this graph are dependencies between [OutputUnits].
+///
+/// [OutputUnits] have a notion of successors and predecessors, that is a
+/// successor to an [OutputUnit] is an [OutputUnit] that must be loaded first. A
+/// predecessor to an [OutputUnit] is an [OutputUnit] that must be loaded later.
+///
+/// To load some given deferred library, a list of [OutputUnits] must be loaded
+/// in the correct order, with their successors loaded first, then the given
+/// [OutputUnit], then the [OutputUnits] predecessors.
+///
+/// To give a concrete example, say our graph looks like:
+///    {a}   {b}   {c}
+///
+///     {a, b} {b, c}
+///
+///       {a, b, c}
+///
+/// Where each set above is the import set of an [OutputUnit]. We say that
+/// {a}, {b}, and {c} are root [OutputUnits], i.e. [OutputUnits] with no
+/// predecessors, and {a, b, c} is a leaf [OutputUnit], i.e. [OutputUnits]
+/// with no successors.
+///
+/// We then have three load lists:
+///   a: {a, b, c}, {a, b}, {a}
+///   b: {a, b, c}, {a, b}, {b, c}, {b}
+///   c: {a, b, c}, {b, c}, {c}
+///
+/// In all 3 load lists, {a, b, c} must be loaded first. All of the other
+/// [OutputUnits] are predecessors of {a, b, c}. {a, b, c} is a successor to all
+/// other [OutputUnits].
+///
+/// However, the dart2js deferred loading algorithm generates a very granular
+/// sparse graph of [OutputUnits] and in many cases it is desireable to coalesce
+/// smaller [OutputUnits] together into larger chunks of code to reduce the
+/// number of files which have to be sent to the client. To do this
+/// cleanly, we use various abstractions to merge [OutputUnits].
+///
+/// First, we emit the code for each [OutputUnit] into an [EmittedOutputUnit].
+/// An [EmittedOutputUnit] is the Javascript representation of an [OutputUnit].
+/// [EmittedOutputUnits] map 1:1 to [OutputUnits].
+///
+/// We wrap each [EmittedOutputUnit] in a [PreFragment], which is just a wrapper
+/// to facilitate merging of [EmittedOutputUnits]. Then, we run a merge
+/// algorithm on these [PreFragments], merging them together until some
+/// threshold.
+///
+/// Once we are finished merging [PreFragments], we must now decide on their
+/// final representation in Javascript.
+///
+/// Depending on the results of the merge, we chose one of two representations.
+/// For example, say we merge {a, b} and {a} into {a, b}+{a}. In this case our
+/// new load lists look like:
+///
+///   a: {a, b, c}, {a, b}+{a}
+///   b: {a, b, c}, {a, b}+{a}, {b, c}, {b}
+///   c: {a, b, c}, {b, c}, {c}
+///
+/// This adds a bit of extra code to the 'b' load list, but otherwise there are
+/// no problems. In this case, we will interleave [EmittedOutputUnits] into a
+/// single [CodeFragment], with a single top level initialization function. This
+/// approach results in lower overhead, because the runtime can initialize the
+/// {a, b}+{a} [CodeFragment] with a single invocation of a top level function.
+///
+/// Ideally we would interleave all [EmittedOutputUnits] in each [PreFragment]
+/// into a single [CodeFragment]. We would then write this single
+/// [CodeFragment] into a single [FinalizedFragment], where a
+/// [FinalizedFragment] is just an abstraction representing a single file on
+/// disk. Unfortunately this is not always possible to do efficiently.
+///
+/// Specifically, lets say we decide to merge {a} and {c} into {a}+{c}
+/// In this case, our load lists now look like:
+///
+///   a: {a, b, c}, {a, b}, {a}+{c}
+///   b: {a, b, c}, {a, b}, {b, c}, {b}
+///   c: {a, b, c}, {b, c}, {a}+{c}
+///
+/// Now, load lists 'a' and 'c' are invalid. Specifically, load list 'a' is
+/// missing {c}'s dependency {b, c} and load list 'c' is missing {a}'s
+/// dependency {a, b}. We could bloat both load lists with the necessary
+/// dependencies, but this would negate any performance benefit from
+/// interleaving.
+///
+/// Instead, when this happens we emit {a} and {c} into separate
+/// [CodeFragments], with separate top level initalization functions that are
+/// only called when the necessary dependencies for initialization are
+/// present. These [CodeFragments] end up in a single [FinalizedFragment].
+/// While this approach doesn't have the performance benefits of
+/// interleaving, it at least reduces the total number of files which need to be
+/// sent to the client.
+
+class EmittedOutputUnit {
+  final OutputUnit outputUnit;
+  final List<Library> libraries;
+  final js.Statement classPrototypes;
+  final js.Statement closurePrototypes;
+  final js.Statement inheritance;
+  final js.Statement methodAliases;
+  final js.Statement tearOffs;
+  final js.Statement constants;
+  final js.Statement typeRules;
+  final js.Statement variances;
+  final js.Statement staticNonFinalFields;
+  final js.Statement lazyInitializers;
+  final js.Statement nativeSupport;
+
+  EmittedOutputUnit(
+      this.outputUnit,
+      this.libraries,
+      this.classPrototypes,
+      this.closurePrototypes,
+      this.inheritance,
+      this.methodAliases,
+      this.tearOffs,
+      this.constants,
+      this.typeRules,
+      this.variances,
+      this.staticNonFinalFields,
+      this.lazyInitializers,
+      this.nativeSupport);
+
+  CodeFragment toCodeFragment(Program program) {
+    return CodeFragment(
+        [outputUnit],
+        libraries,
+        classPrototypes,
+        closurePrototypes,
+        inheritance,
+        methodAliases,
+        tearOffs,
+        constants,
+        typeRules,
+        variances,
+        staticNonFinalFields,
+        lazyInitializers,
+        nativeSupport,
+        program.metadataTypesForOutputUnit(outputUnit));
+  }
+}
+
 class PreFragment {
-  final List<DeferredFragment> fragments = [];
-  final List<js.Statement> classPrototypes = [];
-  final List<js.Statement> closurePrototypes = [];
-  final List<js.Statement> inheritance = [];
-  final List<js.Statement> methodAliases = [];
-  final List<js.Statement> tearOffs = [];
-  final List<js.Statement> constants = [];
-  final List<js.Statement> typeRules = [];
-  final List<js.Statement> variances = [];
-  final List<js.Statement> staticNonFinalFields = [];
-  final List<js.Statement> lazyInitializers = [];
-  final List<js.Statement> nativeSupport = [];
+  final String outputFileName;
+  final List<EmittedOutputUnit> emittedOutputUnits = [];
   final Set<PreFragment> successors = {};
   final Set<PreFragment> predecessors = {};
+  FinalizedFragment finalizedFragment;
   int size = 0;
+  bool shouldInterleave = true;
 
   PreFragment(
-      Fragment fragment,
-      js.Statement classPrototypes,
-      js.Statement closurePrototypes,
-      js.Statement inheritance,
-      js.Statement methodAliases,
-      js.Statement tearOffs,
-      js.Statement constants,
-      js.Statement typeRules,
-      js.Statement variances,
-      js.Statement staticNonFinalFields,
-      js.Statement lazyInitializers,
-      js.Statement nativeSupport,
-      bool estimateSize) {
-    this.fragments.add(fragment);
-    this.classPrototypes.add(classPrototypes);
-    this.closurePrototypes.add(closurePrototypes);
-    this.inheritance.add(inheritance);
-    this.methodAliases.add(methodAliases);
-    this.tearOffs.add(tearOffs);
-    this.constants.add(constants);
-    this.typeRules.add(typeRules);
-    this.variances.add(variances);
-    this.staticNonFinalFields.add(staticNonFinalFields);
-    this.lazyInitializers.add(lazyInitializers);
-    this.nativeSupport.add(nativeSupport);
-    if (estimateSize) {
-      var estimator = SizeEstimator();
-      estimator.visit(classPrototypes);
-      estimator.visit(closurePrototypes);
-      estimator.visit(inheritance);
-      estimator.visit(methodAliases);
-      estimator.visit(tearOffs);
-      estimator.visit(constants);
-      estimator.visit(typeRules);
-      estimator.visit(variances);
-      estimator.visit(staticNonFinalFields);
-      estimator.visit(lazyInitializers);
-      estimator.visit(nativeSupport);
-      size = estimator.charCount;
-    }
+      this.outputFileName, EmittedOutputUnit emittedOutputUnit, this.size) {
+    emittedOutputUnits.add(emittedOutputUnit);
   }
 
   PreFragment mergeAfter(PreFragment that) {
     assert(this != that);
-    this.fragments.addAll(that.fragments);
-    this.classPrototypes.addAll(that.classPrototypes);
-    this.closurePrototypes.addAll(that.closurePrototypes);
-    this.inheritance.addAll(that.inheritance);
-    this.methodAliases.addAll(that.methodAliases);
-    this.tearOffs.addAll(that.tearOffs);
-    this.constants.addAll(that.constants);
-    this.typeRules.addAll(that.typeRules);
-    this.variances.addAll(that.variances);
-    this.staticNonFinalFields.addAll(that.staticNonFinalFields);
-    this.lazyInitializers.addAll(that.lazyInitializers);
-    this.nativeSupport.addAll(that.nativeSupport);
+    this.emittedOutputUnits.addAll(that.emittedOutputUnits);
     this.successors.remove(that);
+    this.predecessors.remove(that);
     that.successors.forEach((fragment) {
+      if (fragment == this) return;
+      this.successors.add(fragment);
       fragment.predecessors.remove(that);
       fragment.predecessors.add(this);
     });
-    this.successors.addAll(that.successors);
-    that.predecessors.remove(this);
     that.predecessors.forEach((fragment) {
+      if (fragment == this) return;
+      this.predecessors.add(fragment);
       fragment.successors.remove(that);
       fragment.successors.add(this);
     });
-    this.predecessors.addAll(that.predecessors);
+    that.clearAll();
     this.size += that.size;
     return this;
   }
 
-  FinalizedFragment finalize(
-      Program program, Map<Fragment, FinalizedFragment> fragmentMap) {
-    FinalizedFragment finalizedFragment;
-    var seedFragment = fragments.first;
-
-    // If we only have a single fragment, then wen just finalize it by itself.
-    // Otherwise, we finalize an entire group of fragments into a single
-    // merged and finalized fragment.
-    if (fragments.length == 1) {
-      finalizedFragment = FinalizedFragment(
-          seedFragment.outputFileName,
-          seedFragment.outputUnit,
-          seedFragment.libraries,
-          classPrototypes.first,
-          closurePrototypes.first,
-          inheritance.first,
-          methodAliases.first,
-          tearOffs.first,
-          constants.first,
-          typeRules.first,
-          variances.first,
-          staticNonFinalFields.first,
-          lazyInitializers.first,
-          nativeSupport.first,
-          program.metadataTypesForOutputUnit(seedFragment.outputUnit));
-      fragmentMap[seedFragment] = finalizedFragment;
+  /// Interleaves the [EmittedOutputUnits] into a single [CodeFragment].
+  CodeFragment interleaveEmittedOutputUnits(Program program) {
+    var seedEmittedOutputUnit = emittedOutputUnits.first;
+    if (emittedOutputUnits.length == 1) {
+      return seedEmittedOutputUnit.toCodeFragment(program);
     } else {
+      var seedOutputUnit = seedEmittedOutputUnit.outputUnit;
       List<Library> libraries = [];
-      for (var fragment in fragments) {
-        if (seedFragment.outputUnit != fragment.outputUnit) {
-          program.mergeOutputUnitMetadata(
-              seedFragment.outputUnit, fragment.outputUnit);
-          seedFragment.outputUnit.merge(fragment.outputUnit);
+      List<OutputUnit> outputUnits = [seedOutputUnit];
+      List<js.Statement> classPrototypes = [];
+      List<js.Statement> closurePrototypes = [];
+      List<js.Statement> inheritance = [];
+      List<js.Statement> methodAliases = [];
+      List<js.Statement> tearOffs = [];
+      List<js.Statement> constants = [];
+      List<js.Statement> typeRules = [];
+      List<js.Statement> variances = [];
+      List<js.Statement> staticNonFinalFields = [];
+      List<js.Statement> lazyInitializers = [];
+      List<js.Statement> nativeSupport = [];
+      for (var emittedOutputUnit in emittedOutputUnits) {
+        var thatOutputUnit = emittedOutputUnit.outputUnit;
+        if (seedOutputUnit != thatOutputUnit) {
+          program.mergeOutputUnitMetadata(seedOutputUnit, thatOutputUnit);
+          outputUnits.add(thatOutputUnit);
         }
-        libraries.addAll(fragment.libraries);
+        libraries.addAll(emittedOutputUnit.libraries);
+        classPrototypes.add(emittedOutputUnit.classPrototypes);
+        closurePrototypes.add(emittedOutputUnit.closurePrototypes);
+        inheritance.add(emittedOutputUnit.inheritance);
+        methodAliases.add(emittedOutputUnit.methodAliases);
+        tearOffs.add(emittedOutputUnit.tearOffs);
+        constants.add(emittedOutputUnit.constants);
+        typeRules.add(emittedOutputUnit.typeRules);
+        variances.add(emittedOutputUnit.variances);
+        staticNonFinalFields.add(emittedOutputUnit.staticNonFinalFields);
+        lazyInitializers.add(emittedOutputUnit.lazyInitializers);
+        nativeSupport.add(emittedOutputUnit.nativeSupport);
       }
-      finalizedFragment = FinalizedFragment(
-          seedFragment.outputFileName,
-          seedFragment.outputUnit,
+      return CodeFragment(
+          outputUnits,
           libraries,
           js.Block(classPrototypes),
           js.Block(closurePrototypes),
@@ -149,11 +247,37 @@
           js.Block(staticNonFinalFields),
           js.Block(lazyInitializers),
           js.Block(nativeSupport),
-          program.metadataTypesForOutputUnit(seedFragment.outputUnit));
-      for (var fragment in fragments) {
-        fragmentMap[fragment] = finalizedFragment;
-      }
+          program.metadataTypesForOutputUnit(seedOutputUnit));
     }
+  }
+
+  /// Bundles [EmittedOutputUnits] into multiple [CodeFragments].
+  List<CodeFragment> bundleEmittedOutputUnits(Program program) {
+    List<CodeFragment> codeFragments = [];
+    for (var emittedOutputUnit in emittedOutputUnits) {
+      codeFragments.add(emittedOutputUnit.toCodeFragment(program));
+    }
+    return codeFragments;
+  }
+
+  /// Finalizes this [PreFragment] into a single [FinalizedFragment] by either
+  /// interleaving [EmittedOutputUnits] into a single [CodeFragment] or by
+  /// bundling [EmittedOutputUnits] into multiple [CodeFragments].
+  FinalizedFragment finalize(
+      Program program,
+      Map<OutputUnit, CodeFragment> outputUnitMap,
+      Map<CodeFragment, FinalizedFragment> codeFragmentMap) {
+    assert(finalizedFragment == null);
+    List<CodeFragment> codeFragments = shouldInterleave
+        ? [interleaveEmittedOutputUnits(program)]
+        : bundleEmittedOutputUnits(program);
+    finalizedFragment = FinalizedFragment(outputFileName, codeFragments);
+    codeFragments.forEach((codeFragment) {
+      codeFragmentMap[codeFragment] = finalizedFragment;
+      codeFragment.outputUnits.forEach((outputUnit) {
+        outputUnitMap[outputUnit] = codeFragment;
+      });
+    });
     return finalizedFragment;
   }
 
@@ -170,24 +294,29 @@
   }
 
   String debugName() {
-    List<String> names = [];
-    this.fragments.forEach(
-        (fragment) => names.add(fragment.outputUnit.imports.toString()));
     var outputUnitStrings = [];
-    for (var fragment in fragments) {
+    for (var emittedOutputUnit in emittedOutputUnits) {
       var importString = [];
-      for (var import in fragment.outputUnit.imports) {
+      for (var import in emittedOutputUnit.outputUnit.imports) {
         importString.add(import.name);
       }
       outputUnitStrings.add('{${importString.join(', ')}}');
     }
     return "${outputUnitStrings.join('+')}";
   }
+
+  /// Clears all [PreFragment] data structure and zeros out the size. Should be
+  /// used only after merging to GC internal data structures.
+  void clearAll() {
+    emittedOutputUnits.clear();
+    successors.clear();
+    predecessors.clear();
+    size = 0;
+  }
 }
 
-class FinalizedFragment {
-  final String outputFileName;
-  final OutputUnit outputUnit;
+class CodeFragment {
+  final List<OutputUnit> outputUnits;
   final List<Library> libraries;
   final js.Statement classPrototypes;
   final js.Statement closurePrototypes;
@@ -202,9 +331,8 @@
   final js.Statement nativeSupport;
   final js.Expression deferredTypes;
 
-  FinalizedFragment(
-      this.outputFileName,
-      this.outputUnit,
+  CodeFragment(
+      this.outputUnits,
       this.libraries,
       this.classPrototypes,
       this.closurePrototypes,
@@ -247,11 +375,47 @@
         isEmptyStatement(lazyInitializers) &&
         isEmptyStatement(nativeSupport);
   }
+
+  @override
+  String toString() {
+    List<String> outputUnitStrings = [];
+    for (var outputUnit in outputUnits) {
+      List<String> importStrings = [];
+      for (var import in outputUnit.imports) {
+        importStrings.add(import.name);
+      }
+      outputUnitStrings.add('{${importStrings.join(', ')}}');
+    }
+    return outputUnitStrings.join('+');
+  }
+}
+
+class FinalizedFragment {
+  final String outputFileName;
+  final List<CodeFragment> codeFragments;
+
+  FinalizedFragment(this.outputFileName, this.codeFragments);
+
+  // The 'main' [OutputUnit] for this [FinalizedFragment].
+  // TODO(joshualitt): Refactor this to more clearly disambiguate between
+  // [OutputUnits](units of deferred merging), fragments(units of emitted code),
+  // and files.
+  OutputUnit get canonicalOutputUnit => codeFragments.first.outputUnits.first;
+
+  @override
+  String toString() {
+    List<String> strings = [];
+    for (var codeFragment in codeFragments) {
+      strings.add(codeFragment.toString());
+    }
+    return 'FinalizedFragment([${strings.join(', ')}])';
+  }
 }
 
 class _Partition {
   int size = 0;
   List<PreFragment> fragments = [];
+  bool isClosed = false;
 
   void add(PreFragment that) {
     size += that.size;
@@ -261,41 +425,133 @@
 
 class FragmentMerger {
   final CompilerOptions _options;
+  final ElementEnvironment _elementEnvironment;
+  final OutputUnitData outputUnitData;
+  int totalSize = 0;
 
-  FragmentMerger(this._options);
+  FragmentMerger(this._options, this._elementEnvironment, this.outputUnitData);
 
-  // Converts a map of (loadId, List<fragments>) to a map of
-  // (loadId, List<FinalizedFragment>).
-  static Map<String, List<FinalizedFragment>> processLoadMap(
-      Map<String, List<Fragment>> programLoadMap,
-      Map<Fragment, FinalizedFragment> fragmentMap) {
-    Map<String, List<FinalizedFragment>> loadMap = {};
-    programLoadMap.forEach((loadId, fragments) {
-      Set<FinalizedFragment> unique = {};
+  // Converts a map of (loadId, List<OutputUnit>) to two maps.
+  // The first is a map of (loadId, List<FinalizedFragment>), which is used to
+  // compute which files need to be loaded for a given loadId.
+  // The second is a map of (loadId, List<CodeFragment>) which is used to
+  // compute which CodeFragments need to be loaded for a given loadId.
+  void computeFragmentsToLoad(
+      Map<String, List<OutputUnit>> outputUnitsToLoad,
+      Map<OutputUnit, CodeFragment> outputUnitMap,
+      Map<CodeFragment, FinalizedFragment> codeFragmentMap,
+      Set<OutputUnit> omittedOutputUnits,
+      Map<String, List<CodeFragment>> codeFragmentsToLoad,
+      Map<String, List<FinalizedFragment>> finalizedFragmentsToLoad) {
+    outputUnitsToLoad.forEach((loadId, outputUnits) {
+      Set<CodeFragment> uniqueCodeFragments = {};
+      Set<FinalizedFragment> uniqueFinalizedFragments = {};
       List<FinalizedFragment> finalizedFragments = [];
-      loadMap[loadId] = finalizedFragments;
-      for (var fragment in fragments) {
-        var finalizedFragment = fragmentMap[fragment];
-        if (unique.add(finalizedFragment)) {
+      List<CodeFragment> codeFragments = [];
+      for (var outputUnit in outputUnits) {
+        if (omittedOutputUnits.contains(outputUnit)) continue;
+        var codeFragment = outputUnitMap[outputUnit];
+        if (uniqueCodeFragments.add(codeFragment)) {
+          codeFragments.add(codeFragment);
+        }
+        var finalizedFragment = codeFragmentMap[codeFragment];
+        if (uniqueFinalizedFragments.add(finalizedFragment)) {
           finalizedFragments.add(finalizedFragment);
         }
       }
+      codeFragmentsToLoad[loadId] = codeFragments;
+      finalizedFragmentsToLoad[loadId] = finalizedFragments;
     });
-    return loadMap;
   }
 
-  // Attaches predecessors to each PreFragment. We only care about
-  // direct predecessors.
-  static void attachDependencies(Map<String, List<Fragment>> programLoadMap,
-      Map<Fragment, PreFragment> fragmentMap) {
-    programLoadMap.forEach((loadId, fragments) {
-      for (int i = 0; i < fragments.length - 1; i++) {
-        var fragment = fragmentMap[fragments[i]];
-        var nextFragment = fragmentMap[fragments[i + 1]];
-        fragment.successors.add(nextFragment);
-        nextFragment.predecessors.add(fragment);
+  /// Given a list of OutputUnits sorted by their import entites,
+  /// returns a map of all the direct edges between output units.
+  Map<OutputUnit, Set<OutputUnit>> createDirectEdges(
+      List<OutputUnit> allOutputUnits) {
+    Map<OutputUnit, Set<OutputUnit>> backEdges = {};
+    for (int i = 0; i < allOutputUnits.length; i++) {
+      var a = allOutputUnits[i];
+      var aImports = a.imports;
+      for (int j = i + 1; j < allOutputUnits.length; j++) {
+        var b = allOutputUnits[j];
+        if (b.imports.containsAll(aImports)) {
+          backEdges[b] ??= {};
+
+          // Remove transitive edges from nodes that will reach 'b' from the
+          // edge we just added.
+          // Note: Because we add edges in order (starting from the smallest
+          // sets) we always add transitive edges before the last direct edge.
+          backEdges[b].removeWhere((c) => aImports.containsAll(c.imports));
+
+          // Create an edge to denote that 'b' must be loaded before 'a'.
+          backEdges[b].add(a);
+        }
+      }
+    }
+
+    Map<OutputUnit, Set<OutputUnit>> forwardEdges = {};
+    backEdges.forEach((b, edges) {
+      for (var a in edges) {
+        (forwardEdges[a] ??= {}).add(b);
       }
     });
+    return forwardEdges;
+  }
+
+  /// Attachs predecessors and successors to each PreFragment.
+  /// Expects outputUnits to be sorted.
+  void attachDependencies(
+      List<OutputUnit> outputUnits, List<PreFragment> preDeferredFragments) {
+    // Create a map of OutputUnit to Fragment.
+    Map<OutputUnit, PreFragment> outputUnitMap = {};
+    for (var preFragment in preDeferredFragments) {
+      var outputUnit = preFragment.emittedOutputUnits.single.outputUnit;
+      outputUnitMap[outputUnit] = preFragment;
+      totalSize += preFragment.size;
+    }
+
+    // Get a list of direct edges and then attach them to PreFragments.
+    var allEdges = createDirectEdges(outputUnits);
+    allEdges.forEach((outputUnit, edges) {
+      var predecessor = outputUnitMap[outputUnit];
+      for (var edge in edges) {
+        var successor = outputUnitMap[edge];
+        predecessor.successors.add(successor);
+        successor.predecessors.add(predecessor);
+      }
+    });
+  }
+
+  /// Given a list of [PreFragments], returns a list of lists of [PreFragments]
+  /// where each list represents a component in the graph.
+  List<List<PreFragment>> separateComponents(
+      List<PreFragment> preDeferredFragments) {
+    List<List<PreFragment>> components = [];
+    Set<PreFragment> visited = {};
+
+    // Starting from each 'root' in the graph, use bfs to find a component.
+    for (var preFragment in preDeferredFragments) {
+      if (preFragment.predecessors.isEmpty && visited.add(preFragment)) {
+        List<PreFragment> component = [];
+        var queue = Queue<PreFragment>();
+        queue.add(preFragment);
+        while (queue.isNotEmpty) {
+          var preFragment = queue.removeFirst();
+          component.add(preFragment);
+          preFragment.predecessors.where(visited.add).forEach(queue.add);
+          preFragment.successors.where(visited.add).forEach(queue.add);
+        }
+
+        // Sort the fragments in the component so they will be in a canonical
+        // order.
+        component.sort((a, b) {
+          return a.emittedOutputUnits.single.outputUnit
+              .compareTo(b.emittedOutputUnits.single.outputUnit);
+        });
+        components.add(component);
+      }
+    }
+    return components;
   }
 
   /// A trivial greedy merge that uses the sorted order of the output units to
@@ -307,34 +563,26 @@
   /// fragment size of 5. Our final partitions would look like:
   ///   {a}, {b}, {c}+{a, b}, {b, c}+{a, b, c}.
   List<PreFragment> mergeFragments(List<PreFragment> preDeferredFragments) {
-    // Sort PreFragments by their initial OutputUnit so they are in canonical
-    // order.
-    preDeferredFragments.sort((a, b) {
-      return a.fragments.single.outputUnit
-          .compareTo(b.fragments.single.outputUnit);
-    });
+    var components = separateComponents(preDeferredFragments);
     int desiredNumberOfFragment = _options.mergeFragmentsThreshold;
-
-    // TODO(joshualitt): Precalculate totalSize when computing dependencies.
-    int totalSize = 0;
-    for (var preFragment in preDeferredFragments) {
-      totalSize += preFragment.size;
-    }
-
     int idealFragmentSize = (totalSize / desiredNumberOfFragment).ceil();
     List<_Partition> partitions = [];
     void add(PreFragment next) {
       // Create a new partition if the current one grows too large, otherwise
       // just add to the most recent partition.
       if (partitions.isEmpty ||
+          partitions.last.isClosed ||
           partitions.last.size + next.size > idealFragmentSize) {
         partitions.add(_Partition());
       }
       partitions.last.add(next);
     }
 
-    // Greedily group fragments into partitions.
-    preDeferredFragments.forEach(add);
+    // Greedily group fragments into partitions, but only within each component.
+    for (var component in components) {
+      component.forEach(add);
+      partitions.last.isClosed = true;
+    }
 
     // Reduce fragments by merging fragments with fewer imports into fragments
     // with more imports.
@@ -344,4 +592,79 @@
     }
     return merged;
   }
+
+  /// Computes load lists using a list of sorted OutputUnits.
+  Map<String, List<OutputUnit>> computeOutputUnitsToLoad(
+      List<OutputUnit> outputUnits) {
+    // Sort the output units in descending order of the number of imports they
+    // include.
+
+    // The loading of the output units must be ordered because a superclass
+    // needs to be initialized before its subclass.
+    // But a class can only depend on another class in an output unit shared by
+    // a strict superset of the imports:
+    // By contradiction: Assume a class C in output unit shared by imports in
+    // the set S1 = (lib1,.., lib_n) depends on a class D in an output unit
+    // shared by S2 such that S2 not a superset of S1. Let lib_s be a library in
+    // S1 not in S2. lib_s must depend on C, and then in turn on D. Therefore D
+    // is not in the right output unit.
+    List<OutputUnit> sortedOutputUnits = outputUnits.reversed.toList();
+
+    Map<String, List<OutputUnit>> outputUnitsToLoad = {};
+    for (var import in outputUnitData.deferredImportDescriptions.keys) {
+      var loadId = outputUnitData.importDeferName[import];
+      List<OutputUnit> loadList = [];
+      for (var outputUnit in sortedOutputUnits) {
+        assert(!outputUnit.isMainOutput);
+        if (outputUnit.imports.contains(import)) {
+          loadList.add(outputUnit);
+        }
+      }
+      outputUnitsToLoad[loadId] = loadList;
+    }
+    return outputUnitsToLoad;
+  }
+
+  /// Returns a json-style map for describing what files that are loaded by a
+  /// given deferred import.
+  /// The mapping is structured as:
+  /// library uri -> {"name": library name, "files": (prefix -> list of files)}
+  /// Where
+  ///
+  /// - <library uri> is the import uri of the library making a deferred
+  ///   import.
+  /// - <library name> is the name of the library, or "<unnamed>" if it is
+  ///   unnamed.
+  /// - <prefix> is the `as` prefix used for a given deferred import.
+  /// - <list of files> is a list of the filenames the must be loaded when that
+  ///   import is loaded.
+  /// TODO(joshualitt): the library name is unused and should be removed. This
+  /// will be a breaking change.
+  Map<String, Map<String, dynamic>> computeDeferredMap(
+      Map<String, List<FinalizedFragment>> fragmentsToLoad) {
+    Map<String, Map<String, dynamic>> mapping = {};
+
+    outputUnitData.deferredImportDescriptions.keys
+        .forEach((ImportEntity import) {
+      var importDeferName = outputUnitData.importDeferName[import];
+      List<FinalizedFragment> fragments = fragmentsToLoad[importDeferName];
+      ImportDescription description =
+          outputUnitData.deferredImportDescriptions[import];
+      String getName(LibraryEntity library) {
+        var name = _elementEnvironment.getLibraryName(library);
+        return name == '' ? '<unnamed>' : name;
+      }
+
+      Map<String, dynamic> libraryMap = mapping.putIfAbsent(
+          description.importingUri,
+          () => {"name": getName(description.importingLibrary), "imports": {}});
+
+      List<String> partFileNames = fragments
+          .map((fragment) =>
+              deferredPartFileName(_options, fragment.canonicalOutputUnit.name))
+          .toList();
+      libraryMap["imports"][importDeferName] = partFileNames;
+    });
+    return mapping;
+  }
 }
diff --git a/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart b/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart
index e12027b..97b7f0d 100644
--- a/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart
@@ -52,6 +52,7 @@
 import '../../io/source_information.dart';
 import '../../io/source_map_builder.dart' show SourceMapBuilder;
 import '../../js/js.dart' as js;
+import '../../js/size_estimator.dart';
 import '../../js_backend/js_backend.dart'
     show Namer, ConstantEmitter, StringBackedName;
 import '../../js_backend/js_interop_analysis.dart' as jsInteropAnalysis;
@@ -84,6 +85,13 @@
 
 part 'fragment_emitter.dart';
 
+class EmittedCodeFragment {
+  final CodeFragment codeFragment;
+  final js.Expression code;
+
+  EmittedCodeFragment(this.codeFragment, this.code);
+}
+
 class ModelEmitter {
   final CompilerOptions _options;
   final DiagnosticReporter _reporter;
@@ -98,6 +106,7 @@
   final JClosedWorld _closedWorld;
   final ConstantOrdering _constantOrdering;
   final SourceInformationStrategy _sourceInformationStrategy;
+  final FragmentMerger fragmentMerger;
 
   // The full code that is written to each hunk part-file.
   final Map<OutputUnit, CodeOutput> emittedOutputBuffers = {};
@@ -106,6 +115,19 @@
 
   List<PreFragment> preDeferredFragmentsForTesting;
 
+  /// A mapping from the name of a defer import to all the fragments it
+  /// depends on in a list of lists to be loaded in the order they appear.
+  ///
+  /// For example {"lib1": [[lib1_lib2_lib3], [lib1_lib2, lib1_lib3],
+  /// [lib1]]} would mean that in order to load "lib1" first the hunk
+  /// lib1_lib2_lib2 should be loaded, then the hunks lib1_lib2 and lib1_lib3
+  /// can be loaded in parallel. And fially lib1 can be loaded.
+  final Map<String, List<FinalizedFragment>> finalizedFragmentsToLoad = {};
+
+  /// Similar to the above map, but more granular as each [FinalizedFragment]
+  /// may have multiple CodeFragments.
+  final Map<String, List<CodeFragment>> codeFragmentsToLoad = {};
+
   /// For deferred loading we communicate the initializers via this global var.
   static const String deferredInitializersGlobal =
       r"$__dart_deferred_initializers__";
@@ -128,7 +150,9 @@
       this._sourceInformationStrategy,
       RecipeEncoder rtiRecipeEncoder,
       this._shouldGenerateSourceMap)
-      : _constantOrdering = new ConstantOrdering(_closedWorld.sorter) {
+      : _constantOrdering = new ConstantOrdering(_closedWorld.sorter),
+        fragmentMerger = FragmentMerger(_options,
+            _closedWorld.elementEnvironment, _closedWorld.outputUnitData) {
     this.constantEmitter = new ConstantEmitter(
         _options,
         _namer,
@@ -211,28 +235,29 @@
         _closedWorld,
         codegenWorld);
 
-    var deferredLoadingState = new DeferredLoadingState();
-    js.Statement mainCode =
-        fragmentEmitter.emitMainFragment(program, deferredLoadingState);
-
     // In order to get size estimates, we partially emit deferred fragments.
+    List<OutputUnit> outputUnits = [];
     List<PreFragment> preDeferredFragments = [];
-    Map<DeferredFragment, PreFragment> preFragmentMap = {};
     _task.measureSubtask('emit prefragments', () {
       for (var fragment in deferredFragments) {
         var preFragment =
             fragmentEmitter.emitPreFragment(fragment, shouldMergeFragments);
-        preFragmentMap[fragment] = preFragment;
+        outputUnits.add(fragment.outputUnit);
         preDeferredFragments.add(preFragment);
       }
     });
 
-    // Attach dependencies to each PreFragment.
-    FragmentMerger.attachDependencies(program.loadMap, preFragmentMap);
+    // Sort output units so they are in a canonical order and generate a map of
+    // loadId to list of OutputUnits to load.
+    outputUnits.sort();
+    var outputUnitsToLoad =
+        fragmentMerger.computeOutputUnitsToLoad(outputUnits);
 
+    // If we are going to merge, then we attach dependencies to each PreFragment
+    // and merge.
     if (shouldMergeFragments) {
       preDeferredFragments = _task.measureSubtask('merge fragments', () {
-        FragmentMerger fragmentMerger = FragmentMerger(_options);
+        fragmentMerger.attachDependencies(outputUnits, preDeferredFragments);
         return fragmentMerger.mergeFragments(preDeferredFragments);
       });
     }
@@ -242,22 +267,48 @@
       preDeferredFragmentsForTesting = preDeferredFragments;
     }
 
-    Map<DeferredFragment, FinalizedFragment> fragmentMap = {};
-    Map<FinalizedFragment, js.Expression> deferredFragmentsCode = {};
+    // Finalize and emit fragments.
+    Map<OutputUnit, CodeFragment> outputUnitMap = {};
+    Map<CodeFragment, FinalizedFragment> codeFragmentMap = {};
+    Map<FinalizedFragment, EmittedCodeFragment> deferredFragmentsCode = {};
     for (var preDeferredFragment in preDeferredFragments) {
       var finalizedFragment =
-          preDeferredFragment.finalize(program, fragmentMap);
-      js.Expression fragmentCode = fragmentEmitter.emitDeferredFragment(
-          finalizedFragment, program.holders);
+          preDeferredFragment.finalize(program, outputUnitMap, codeFragmentMap);
+      // TODO(joshualitt): Support bundling.
+      assert(finalizedFragment.codeFragments.length == 1);
+      var codeFragment = finalizedFragment.codeFragments.single;
+      js.Expression fragmentCode =
+          fragmentEmitter.emitCodeFragment(codeFragment, program.holders);
       if (fragmentCode != null) {
-        deferredFragmentsCode[finalizedFragment] = fragmentCode;
+        deferredFragmentsCode[finalizedFragment] =
+            EmittedCodeFragment(codeFragment, fragmentCode);
       } else {
-        omittedOutputUnits.add(finalizedFragment.outputUnit);
+        finalizedFragment.codeFragments.forEach((codeFragment) {
+          omittedOutputUnits.addAll(codeFragment.outputUnits);
+        });
       }
     }
 
+    // With all deferred fragments finalized, we can now compute a map of
+    // loadId to the files(FinalizedFragments) which need to be loaded.
+    fragmentMerger.computeFragmentsToLoad(
+        outputUnitsToLoad,
+        outputUnitMap,
+        codeFragmentMap,
+        omittedOutputUnits,
+        codeFragmentsToLoad,
+        finalizedFragmentsToLoad);
+
+    // Emit main Fragment.
+    var deferredLoadingState = new DeferredLoadingState();
+    js.Statement mainCode = fragmentEmitter.emitMainFragment(
+        program, finalizedFragmentsToLoad, deferredLoadingState);
+
+    // Count tokens and run finalizers.
     js.TokenCounter counter = new js.TokenCounter();
-    deferredFragmentsCode.values.forEach(counter.countTokens);
+    deferredFragmentsCode.values.forEach((emittedCodeFragment) {
+      counter.countTokens(emittedCodeFragment.code);
+    });
     counter.countTokens(mainCode);
 
     program.finalizers.forEach((js.TokenFinalizer f) => f.finalizeTokens());
@@ -273,10 +324,8 @@
 
     // Now that we have written the deferred hunks, we can create the deferred
     // loading data.
-    Map<String, List<FinalizedFragment>> loadMap =
-        FragmentMerger.processLoadMap(program.loadMap, fragmentMap);
     fragmentEmitter.finalizeDeferredLoadingData(
-        loadMap, hunkHashes, deferredLoadingState);
+        codeFragmentsToLoad, codeFragmentMap, hunkHashes, deferredLoadingState);
 
     _task.measureSubtask('write fragments', () {
       writeMainFragment(mainFragment, mainCode,
@@ -320,11 +369,13 @@
   ///
   /// Updates the shared [outputBuffers] field with the output.
   Map<FinalizedFragment, String> writeDeferredFragments(
-      Map<FinalizedFragment, js.Expression> fragmentsCode) {
+      Map<FinalizedFragment, EmittedCodeFragment> fragmentsCode) {
     Map<FinalizedFragment, String> hunkHashes = {};
 
-    fragmentsCode.forEach((FinalizedFragment fragment, js.Expression code) {
-      hunkHashes[fragment] = writeDeferredFragment(fragment, code);
+    fragmentsCode.forEach(
+        (FinalizedFragment fragment, EmittedCodeFragment emittedCodeFragment) {
+      hunkHashes[fragment] =
+          writeDeferredFragment(fragment, emittedCodeFragment.code);
     });
 
     return hunkHashes;
@@ -419,7 +470,9 @@
             hunkPrefix, deferredExtension, OutputType.jsPart),
         outputListeners);
 
-    emittedOutputBuffers[fragment.outputUnit] = output;
+    // TODO(joshualitt): This breaks dump_info when we merge, but fixing it will
+    // require updating the schema.
+    emittedOutputBuffers[fragment.canonicalOutputUnit] = output;
 
     // The [code] contains the function that must be invoked when the deferred
     // hunk is loaded.
@@ -495,9 +548,7 @@
     // data.
     mapping["_comment"] = "This mapping shows which compiled `.js` files are "
         "needed for a given deferred library import.";
-    mapping.addAll(_closedWorld.outputUnitData.computeDeferredMap(
-        _options, _closedWorld.elementEnvironment,
-        omittedUnits: omittedOutputUnits));
+    mapping.addAll(fragmentMerger.computeDeferredMap(finalizedFragmentsToLoad));
     _outputProvider.createOutputSink(
         _options.deferredMapUri.path, '', OutputType.deferredMap)
       ..add(const JsonEncoder.withIndent("  ").convert(mapping))
diff --git a/pkg/compiler/lib/src/js_model/closure.dart b/pkg/compiler/lib/src/js_model/closure.dart
index 41f9170..216f25e 100644
--- a/pkg/compiler/lib/src/js_model/closure.dart
+++ b/pkg/compiler/lib/src/js_model/closure.dart
@@ -1411,5 +1411,5 @@
   bool selectorNeedsTypeArguments(Selector selector);
 
   bool instantiationNeedsTypeArguments(
-      DartType functionType, int typeArgumentCount);
+      FunctionType functionType, int typeArgumentCount);
 }
diff --git a/pkg/compiler/lib/src/js_model/element_map.dart b/pkg/compiler/lib/src/js_model/element_map.dart
index 44b6cd1..d63ee32 100644
--- a/pkg/compiler/lib/src/js_model/element_map.dart
+++ b/pkg/compiler/lib/src/js_model/element_map.dart
@@ -15,7 +15,6 @@
 import '../ir/closure.dart';
 import '../ir/static_type_provider.dart';
 import '../ir/util.dart';
-import '../js_model/closure.dart' show JRecordField;
 import '../js_model/elements.dart' show JGeneratorBody;
 import '../native/behavior.dart';
 import '../serialization/serialization.dart';
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 ba0057a..5849d77 100644
--- a/pkg/compiler/lib/src/js_model/element_map_impl.dart
+++ b/pkg/compiler/lib/src/js_model/element_map_impl.dart
@@ -1249,12 +1249,30 @@
     if (node is ir.PropertyGet) {
       return getGetterSelector(node.name);
     }
+    if (node is ir.InstanceGet) {
+      return getGetterSelector(node.name);
+    }
+    if (node is ir.InstanceTearOff) {
+      return getGetterSelector(node.name);
+    }
+    if (node is ir.DynamicGet) {
+      return getGetterSelector(node.name);
+    }
+    if (node is ir.FunctionTearOff) {
+      return getGetterSelector(ir.Name.callName);
+    }
     if (node is ir.SuperPropertyGet) {
       return getGetterSelector(node.name);
     }
     if (node is ir.PropertySet) {
       return getSetterSelector(node.name);
     }
+    if (node is ir.InstanceSet) {
+      return getSetterSelector(node.name);
+    }
+    if (node is ir.DynamicSet) {
+      return getSetterSelector(node.name);
+    }
     if (node is ir.SuperPropertySet) {
       return getSetterSelector(node.name);
     }
@@ -2121,7 +2139,7 @@
         break;
       } else if (node is ir.Field) {
         // Add the field name for closures in field initializers.
-        String name = node.name?.name;
+        String name = node.name?.text;
         if (name != null) parts.add(name);
       }
       current = current.parent;
diff --git a/pkg/compiler/lib/src/js_model/js_world.dart b/pkg/compiler/lib/src/js_model/js_world.dart
index 868ef6f..66f8efc 100644
--- a/pkg/compiler/lib/src/js_model/js_world.dart
+++ b/pkg/compiler/lib/src/js_model/js_world.dart
@@ -10,7 +10,6 @@
 import '../common/names.dart';
 import '../common_elements.dart' show JCommonElements, JElementEnvironment;
 import '../deferred_load.dart';
-import '../diagnostics/diagnostic_listener.dart';
 import '../elements/entities.dart';
 import '../elements/entity_utils.dart' as utils;
 import '../elements/names.dart';
diff --git a/pkg/compiler/lib/src/js_model/js_world_builder.dart b/pkg/compiler/lib/src/js_model/js_world_builder.dart
index f2fdbe6..c07ccea 100644
--- a/pkg/compiler/lib/src/js_model/js_world_builder.dart
+++ b/pkg/compiler/lib/src/js_model/js_world_builder.dart
@@ -528,7 +528,7 @@
 
   @override
   bool instantiationNeedsTypeArguments(
-          DartType functionType, int typeArgumentCount) =>
+          FunctionType functionType, int typeArgumentCount) =>
       true;
 }
 
@@ -568,7 +568,7 @@
 
   @override
   bool instantiationNeedsTypeArguments(
-          DartType functionType, int typeArgumentCount) =>
+          FunctionType functionType, int typeArgumentCount) =>
       rtiNeed.instantiationNeedsTypeArguments(functionType, typeArgumentCount);
 }
 
diff --git a/pkg/compiler/lib/src/kernel/dart2js_target.dart b/pkg/compiler/lib/src/kernel/dart2js_target.dart
index 60301f2..a0ce422 100644
--- a/pkg/compiler/lib/src/kernel/dart2js_target.dart
+++ b/pkg/compiler/lib/src/kernel/dart2js_target.dart
@@ -86,7 +86,7 @@
   bool get supportsExplicitGetterCalls => false;
 
   @override
-  bool get supportsNewMethodInvocationEncoding => false;
+  bool get supportsNewMethodInvocationEncoding => true;
 
   @override
   List<String> get extraRequiredLibraries => _requiredLibraries[name];
diff --git a/pkg/compiler/lib/src/kernel/kernel_impact.dart b/pkg/compiler/lib/src/kernel/kernel_impact.dart
index f3df3a2..bd6095b 100644
--- a/pkg/compiler/lib/src/kernel/kernel_impact.dart
+++ b/pkg/compiler/lib/src/kernel/kernel_impact.dart
@@ -665,8 +665,10 @@
         const <DartType>[]));
   }
 
+  // TODO(johnniwinther): Change [node] `InstanceGet` when the old method
+  // invocation encoding is no longer used.
   @override
-  void registerRuntimeTypeUse(ir.PropertyGet node, RuntimeTypeUseKind kind,
+  void registerRuntimeTypeUse(ir.Expression node, RuntimeTypeUseKind kind,
       ir.DartType receiverType, ir.DartType argumentType) {
     DartType receiverDartType = elementMap.getDartType(receiverType);
     DartType argumentDartType =
@@ -700,7 +702,7 @@
       ir.FunctionType expressionType, List<ir.DartType> typeArguments) {
     // TODO(johnniwinther): Track which arities are used in instantiation.
     impactBuilder.registerInstantiation(new GenericInstantiation(
-        elementMap.getDartType(expressionType),
+        elementMap.getDartType(expressionType).withoutNullability,
         typeArguments.map(elementMap.getDartType).toList()));
   }
 
diff --git a/pkg/compiler/lib/src/kernel/transformations/list_factory_specializer.dart b/pkg/compiler/lib/src/kernel/transformations/list_factory_specializer.dart
index 5c10d5f..b14d9e2 100644
--- a/pkg/compiler/lib/src/kernel/transformations/list_factory_specializer.dart
+++ b/pkg/compiler/lib/src/kernel/transformations/list_factory_specializer.dart
@@ -283,7 +283,7 @@
         type: closureParameter.type)
       ..fileOffset = closureParameter.fileOffset;
     this.argument = argument;
-    variables[closureParameter] = parameter;
+    setVariableClone(closureParameter, parameter);
   }
 
   Statement run() {
@@ -340,17 +340,8 @@
   }
 
   @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;
+  VariableDeclaration getVariableClone(VariableDeclaration variable) {
+    VariableDeclaration clone = super.getVariableClone(variable);
+    return clone ?? variable;
   }
 }
diff --git a/pkg/compiler/lib/src/options.dart b/pkg/compiler/lib/src/options.dart
index 03edd91..ce9cddb 100644
--- a/pkg/compiler/lib/src/options.dart
+++ b/pkg/compiler/lib/src/options.dart
@@ -77,6 +77,11 @@
   /// If this is set, the compilation stops after type inference.
   Uri writeDataUri;
 
+  /// Serialize data without the closed world.
+  /// TODO(joshualitt) make this the default right after landing in Google3 and
+  /// clean up.
+  bool noClosedWorldInData = false;
+
   /// Location from which the serialized closed world is read.
   ///
   /// If this is set, the [entryPoint] is expected to be a .dill file and the
@@ -542,6 +547,7 @@
           _extractUriListOption(options, '${Flags.dillDependencies}')
       ..readDataUri = _extractUriOption(options, '${Flags.readData}=')
       ..writeDataUri = _extractUriOption(options, '${Flags.writeData}=')
+      ..noClosedWorldInData = _hasOption(options, Flags.noClosedWorldInData)
       ..readClosedWorldUri =
           _extractUriOption(options, '${Flags.readClosedWorld}=')
       ..writeClosedWorldUri =
diff --git a/pkg/compiler/lib/src/serialization/node_indexer.dart b/pkg/compiler/lib/src/serialization/node_indexer.dart
index 6846687..663e593 100644
--- a/pkg/compiler/lib/src/serialization/node_indexer.dart
+++ b/pkg/compiler/lib/src/serialization/node_indexer.dart
@@ -166,6 +166,12 @@
   }
 
   @override
+  void visitInstanceGetterInvocation(ir.InstanceGetterInvocation node) {
+    registerNode(node);
+    super.visitInstanceGetterInvocation(node);
+  }
+
+  @override
   void visitDynamicInvocation(ir.DynamicInvocation node) {
     registerNode(node);
     super.visitDynamicInvocation(node);
diff --git a/pkg/compiler/lib/src/serialization/strategies.dart b/pkg/compiler/lib/src/serialization/strategies.dart
index 37fbe89..9269eed 100644
--- a/pkg/compiler/lib/src/serialization/strategies.dart
+++ b/pkg/compiler/lib/src/serialization/strategies.dart
@@ -49,7 +49,8 @@
       Environment environment,
       AbstractValueStrategy abstractValueStrategy,
       ir.Component component,
-      List<T> data);
+      List<T> closedWorldData,
+      List<T> globalTypeInferenceResultsData);
 
   List<T> serializeClosedWorld(JsClosedWorld closedWorld);
 
@@ -83,10 +84,28 @@
       Environment environment,
       AbstractValueStrategy abstractValueStrategy,
       ir.Component component,
-      List<int> data) {
-    DataSource source = new BinarySourceImpl(data, useDataKinds: useDataKinds);
-    return deserializeGlobalTypeInferenceResultsFromSource(options, reporter,
-        environment, abstractValueStrategy, component, source);
+      List<int> closedWorldData,
+      List<int> globalTypeInferenceResultsData) {
+    DataSource closedWorldSource =
+        BinarySourceImpl(closedWorldData, useDataKinds: useDataKinds);
+    DataSource globalTypeInferenceResultsSource = BinarySourceImpl(
+        globalTypeInferenceResultsData,
+        useDataKinds: useDataKinds);
+    JsClosedWorld closedWorld = deserializeClosedWorldFromSource(
+        options,
+        reporter,
+        environment,
+        abstractValueStrategy,
+        component,
+        closedWorldSource);
+    return deserializeGlobalTypeInferenceResultsFromSource(
+        options,
+        reporter,
+        environment,
+        abstractValueStrategy,
+        component,
+        closedWorld,
+        globalTypeInferenceResultsSource);
   }
 
   @override
@@ -134,10 +153,28 @@
       Environment environment,
       AbstractValueStrategy abstractValueStrategy,
       ir.Component component,
-      List<int> data) {
-    DataSource source = new BinarySourceImpl(data, useDataKinds: useDataKinds);
-    return deserializeGlobalTypeInferenceResultsFromSource(options, reporter,
-        environment, abstractValueStrategy, component, source);
+      List<int> closedWorldData,
+      List<int> globalTypeInferenceResultsData) {
+    DataSource closedWorldSource =
+        BinarySourceImpl(closedWorldData, useDataKinds: useDataKinds);
+    DataSource globalTypeInferenceResultsSource = BinarySourceImpl(
+        globalTypeInferenceResultsData,
+        useDataKinds: useDataKinds);
+    JsClosedWorld closedWorld = deserializeClosedWorldFromSource(
+        options,
+        reporter,
+        environment,
+        abstractValueStrategy,
+        component,
+        closedWorldSource);
+    return deserializeGlobalTypeInferenceResultsFromSource(
+        options,
+        reporter,
+        environment,
+        abstractValueStrategy,
+        component,
+        closedWorld,
+        globalTypeInferenceResultsSource);
   }
 
   @override
@@ -186,10 +223,28 @@
       Environment environment,
       AbstractValueStrategy abstractValueStrategy,
       ir.Component component,
-      List<Object> data) {
-    DataSource source = new ObjectSource(data, useDataKinds: useDataKinds);
-    return deserializeGlobalTypeInferenceResultsFromSource(options, reporter,
-        environment, abstractValueStrategy, component, source);
+      List<Object> closedWorldData,
+      List<Object> globalTypeInferenceResultsData) {
+    DataSource closedWorldSource =
+        ObjectSource(closedWorldData, useDataKinds: useDataKinds);
+    DataSource globalTypeInferenceResultsSource = ObjectSource(
+        globalTypeInferenceResultsData,
+        useDataKinds: useDataKinds);
+    JsClosedWorld closedWorld = deserializeClosedWorldFromSource(
+        options,
+        reporter,
+        environment,
+        abstractValueStrategy,
+        component,
+        closedWorldSource);
+    return deserializeGlobalTypeInferenceResultsFromSource(
+        options,
+        reporter,
+        environment,
+        abstractValueStrategy,
+        component,
+        closedWorld,
+        globalTypeInferenceResultsSource);
   }
 
   @override
diff --git a/pkg/compiler/lib/src/serialization/task.dart b/pkg/compiler/lib/src/serialization/task.dart
index 6e5c4c8..cfc2b0d 100644
--- a/pkg/compiler/lib/src/serialization/task.dart
+++ b/pkg/compiler/lib/src/serialization/task.dart
@@ -19,6 +19,7 @@
 import '../js_backend/backend.dart';
 import '../js_backend/inferred_data.dart';
 import '../js_model/js_world.dart';
+import '../js_model/element_map_impl.dart';
 import '../js_model/locals.dart';
 import '../options.dart';
 import '../util/sink_adapter.dart';
@@ -30,40 +31,50 @@
   JsClosedWorld closedWorld = results.closedWorld;
   GlobalLocalsMap globalLocalsMap = results.globalLocalsMap;
   InferredData inferredData = results.inferredData;
-  closedWorld.writeToDataSink(sink);
   globalLocalsMap.writeToDataSink(sink);
   inferredData.writeToDataSink(sink);
   results.writeToDataSink(sink, closedWorld.elementMap);
   sink.close();
 }
 
-GlobalTypeInferenceResults deserializeGlobalAnalysisFromSource(
-    CompilerOptions options,
-    DiagnosticReporter reporter,
-    Environment environment,
-    AbstractValueStrategy abstractValueStrategy,
-    ir.Component component,
-    JsClosedWorld newClosedWorld,
-    DataSource source) {
-  GlobalLocalsMap newGlobalLocalsMap = GlobalLocalsMap.readFromDataSource(
-      newClosedWorld.closureDataLookup.getEnclosingMember, source);
-  InferredData newInferredData =
-      InferredData.readFromDataSource(source, newClosedWorld);
-  return GlobalTypeInferenceResults.readFromDataSource(
-      source,
-      newClosedWorld.elementMap,
-      newClosedWorld,
-      newGlobalLocalsMap,
-      newInferredData);
-}
-
 GlobalTypeInferenceResults deserializeGlobalTypeInferenceResultsFromSource(
     CompilerOptions options,
     DiagnosticReporter reporter,
     Environment environment,
     AbstractValueStrategy abstractValueStrategy,
     ir.Component component,
+    JsClosedWorld closedWorld,
     DataSource source) {
+  source.registerComponentLookup(ComponentLookup(component));
+  source.registerEntityLookup(ClosedEntityLookup(closedWorld.elementMap));
+  GlobalLocalsMap globalLocalsMap = GlobalLocalsMap.readFromDataSource(
+      closedWorld.closureDataLookup.getEnclosingMember, source);
+  InferredData inferredData =
+      InferredData.readFromDataSource(source, closedWorld);
+  return GlobalTypeInferenceResults.readFromDataSource(source,
+      closedWorld.elementMap, closedWorld, globalLocalsMap, inferredData);
+}
+
+void serializeGlobalTypeInferenceResultsToSinkLegacy(
+    GlobalTypeInferenceResults results, DataSink sink) {
+  JsClosedWorld closedWorld = results.closedWorld;
+  GlobalLocalsMap globalLocalsMap = results.globalLocalsMap;
+  InferredData inferredData = results.inferredData;
+  closedWorld.writeToDataSink(sink);
+  globalLocalsMap.writeToDataSink(sink);
+  inferredData.writeToDataSink(sink);
+  results.writeToDataSink(sink, closedWorld.elementMap);
+  sink.close();
+}
+
+GlobalTypeInferenceResults
+    deserializeGlobalTypeInferenceResultsFromSourceLegacy(
+        CompilerOptions options,
+        DiagnosticReporter reporter,
+        Environment environment,
+        AbstractValueStrategy abstractValueStrategy,
+        ir.Component component,
+        DataSource source) {
   JsClosedWorld newClosedWorld = new JsClosedWorld.readFromDataSource(
       options, reporter, environment, abstractValueStrategy, component, source);
   GlobalLocalsMap newGlobalLocalsMap = GlobalLocalsMap.readFromDataSource(
@@ -213,23 +224,7 @@
     });
   }
 
-  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 =
-          BinarySourceImpl(dataInput.data, stringInterner: _stringInterner);
-      return deserializeGlobalTypeInferenceResultsFromSource(_options,
-          _reporter, environment, abstractValueStrategy, component, source);
-    });
-  }
-
-  Future<GlobalTypeInferenceResults> deserializeGlobalAnalysis(
+  Future<GlobalTypeInferenceResults> deserializeGlobalTypeInferenceResults(
       Environment environment,
       AbstractValueStrategy abstractValueStrategy,
       ir.Component component,
@@ -240,8 +235,45 @@
           .readFromUri(_options.readDataUri, inputKind: api.InputKind.binary);
       DataSource source =
           BinarySourceImpl(dataInput.data, stringInterner: _stringInterner);
-      return deserializeGlobalAnalysisFromSource(_options, _reporter,
-          environment, abstractValueStrategy, component, closedWorld, source);
+      return deserializeGlobalTypeInferenceResultsFromSource(
+          _options,
+          _reporter,
+          environment,
+          abstractValueStrategy,
+          component,
+          closedWorld,
+          source);
+    });
+  }
+
+  // TODO(joshualitt) get rid of legacy functions after Google3 roll.
+  void serializeGlobalTypeInferenceLegacy(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));
+      serializeGlobalTypeInferenceResultsToSinkLegacy(results, sink);
+    });
+  }
+
+  Future<GlobalTypeInferenceResults> deserializeGlobalTypeInferenceLegacy(
+      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 =
+          BinarySourceImpl(dataInput.data, stringInterner: _stringInterner);
+      return deserializeGlobalTypeInferenceResultsFromSourceLegacy(_options,
+          _reporter, environment, abstractValueStrategy, component, source);
     });
   }
 
diff --git a/pkg/compiler/lib/src/source_file_provider.dart b/pkg/compiler/lib/src/source_file_provider.dart
index f8b1da3..9a7fe7f 100644
--- a/pkg/compiler/lib/src/source_file_provider.dart
+++ b/pkg/compiler/lib/src/source_file_provider.dart
@@ -11,7 +11,6 @@
 
 import 'package:front_end/src/api_unstable/dart2js.dart' as fe;
 
-import '../compiler.dart' as api show Diagnostic;
 import '../compiler_new.dart' as api;
 import '../compiler_new.dart';
 import 'colors.dart' as colors;
diff --git a/pkg/compiler/lib/src/ssa/builder_kernel.dart b/pkg/compiler/lib/src/ssa/builder_kernel.dart
index ef086e0..864f6a8 100644
--- a/pkg/compiler/lib/src/ssa/builder_kernel.dart
+++ b/pkg/compiler/lib/src/ssa/builder_kernel.dart
@@ -5060,6 +5060,9 @@
     if (node is ir.MethodInvocation) {
       invoke.isInvariant = node.isInvariant;
       invoke.isBoundsSafe = node.isBoundsSafe;
+    } else if (node is ir.InstanceInvocation) {
+      invoke.isInvariant = node.isInvariant;
+      invoke.isBoundsSafe = node.isBoundsSafe;
     }
     push(invoke);
   }
@@ -5193,15 +5196,16 @@
     node.expression.accept(this);
     arguments.add(pop());
     StaticType expressionType = _getStaticType(node.expression);
+    FunctionType functionType = expressionType.type.withoutNullability;
     bool typeArgumentsNeeded = _rtiNeed.instantiationNeedsTypeArguments(
-        expressionType.type, node.typeArguments.length);
+        functionType, node.typeArguments.length);
     List<DartType> typeArguments = node.typeArguments
         .map((type) => typeArgumentsNeeded
             ? _elementMap.getDartType(type)
             : _commonElements.dynamicType)
         .toList();
     registry.registerGenericInstantiation(
-        new GenericInstantiation(expressionType.type, typeArguments));
+        new GenericInstantiation(functionType, typeArguments));
     // TODO(johnniwinther): Can we avoid creating the instantiation object?
     for (DartType type in typeArguments) {
       HInstruction instruction =
@@ -5256,6 +5260,11 @@
   }
 
   @override
+  void visitInstanceGetterInvocation(ir.InstanceGetterInvocation node) {
+    _handleMethodInvocation(node, node.receiver, node.arguments);
+  }
+
+  @override
   void visitDynamicInvocation(ir.DynamicInvocation node) {
     _handleMethodInvocation(node, node.receiver, node.arguments);
   }
@@ -5267,8 +5276,27 @@
 
   @override
   void visitLocalFunctionInvocation(ir.LocalFunctionInvocation node) {
-    _handleMethodInvocation(
-        node, ir.VariableGet(node.variable), node.arguments);
+    Local local = _localsMap.getLocalVariable(node.variable);
+    stack.add(localsHandler.readLocal(local,
+        sourceInformation: _sourceInformationBuilder.buildGet(node)));
+    HInstruction receiverInstruction = pop();
+    Selector selector = _elementMap.getSelector(node);
+    List<DartType> typeArguments = [];
+    selector =
+        _fillDynamicTypeArguments(selector, node.arguments, typeArguments);
+    _pushDynamicInvocation(
+        node,
+        StaticType(_elementMap.getDartType(node.variable.type),
+            computeClassRelationFromType(node.variable.type)),
+        _typeInferenceMap.receiverTypeOfInvocation(node, _abstractValueDomain),
+        selector,
+        [
+          receiverInstruction,
+          ..._visitArgumentsForDynamicTarget(
+              selector, node.arguments, typeArguments)
+        ],
+        typeArguments,
+        _sourceInformationBuilder.buildCall(node, node));
   }
 
   @override
@@ -5277,9 +5305,7 @@
   }
 
   void _handleEquals(ir.Expression node, ir.Expression left,
-      HInstruction leftInstruction, HInstruction rightInstruction,
-      {bool isNot}) {
-    assert(isNot != null);
+      HInstruction leftInstruction, HInstruction rightInstruction) {
     _pushDynamicInvocation(
         node,
         _getStaticType(left),
@@ -5288,19 +5314,34 @@
         <HInstruction>[leftInstruction, rightInstruction],
         const <DartType>[],
         _sourceInformationBuilder.buildCall(left, node));
-    if (isNot) {
-      push(new HNot(popBoolified(), _abstractValueDomain.boolType)
-        ..sourceInformation = _sourceInformationBuilder.buildUnary(node));
-    }
   }
 
   @override
   void visitEqualsNull(ir.EqualsNull node) {
     node.expression.accept(this);
     HInstruction receiverInstruction = pop();
-    return _handleEquals(node, node.expression, receiverInstruction,
-        graph.addConstantNull(closedWorld),
-        isNot: node.isNot);
+
+    // Hack to detect `null == o`.
+    // TODO(johnniwinther): Remove this after the new method invocation has
+    // landed stably. This is only included to make the transition a no-op.
+    if (node.fileOffset < node.expression.fileOffset) {
+      _pushDynamicInvocation(
+          node,
+          new StaticType(
+              _elementMap.commonElements.nullType, ClassRelation.subtype),
+          _typeInferenceMap.receiverTypeOfInvocation(
+              node, _abstractValueDomain),
+          Selectors.equals,
+          <HInstruction>[
+            graph.addConstantNull(closedWorld),
+            receiverInstruction
+          ],
+          const <DartType>[],
+          _sourceInformationBuilder.buildCall(node.expression, node));
+    } else {
+      _handleEquals(node, node.expression, receiverInstruction,
+          graph.addConstantNull(closedWorld));
+    }
   }
 
   @override
@@ -5309,8 +5350,7 @@
     HInstruction leftInstruction = pop();
     node.right.accept(this);
     HInstruction rightInstruction = pop();
-    return _handleEquals(node, node.left, leftInstruction, rightInstruction,
-        isNot: node.isNot);
+    return _handleEquals(node, node.left, leftInstruction, rightInstruction);
   }
 
   HInterceptor _interceptorFor(
@@ -7373,6 +7413,16 @@
   }
 
   @override
+  visitInstanceGetterInvocation(ir.InstanceGetterInvocation node) {
+    registerRegularNode();
+    registerReductiveNode();
+    registerCall();
+    visit(node.receiver);
+    skipReductiveNodes(() => visit(node.name));
+    _processArguments(node.arguments, null);
+  }
+
+  @override
   visitDynamicInvocation(ir.DynamicInvocation node) {
     registerRegularNode();
     registerReductiveNode();
diff --git a/pkg/compiler/lib/src/ssa/codegen_helpers.dart b/pkg/compiler/lib/src/ssa/codegen_helpers.dart
index cb8a95e..d643936 100644
--- a/pkg/compiler/lib/src/ssa/codegen_helpers.dart
+++ b/pkg/compiler/lib/src/ssa/codegen_helpers.dart
@@ -22,7 +22,18 @@
 }
 
 /// Replaces some instructions with specialized versions to make codegen easier.
-/// Caches codegen information on nodes.
+///
+/// - Caches codegen information on nodes.
+///
+/// - Remove NullChecks where the next instruction would fail on the operand.
+///
+/// - Dummy receiver optimization.
+///
+/// - One-shot interceptor optimization.
+///
+/// - Combine read/modify/write sequences into HReadModifyWrite instructions to
+///   simplify codegen of expressions like `a.x += y`.
+
 class SsaInstructionSelection extends HBaseVisitor with CodegenPhase {
   final JClosedWorld _closedWorld;
   final InterceptorData _interceptorData;
@@ -52,12 +63,9 @@
 
         // If the replacement instruction does not know its source element, use
         // the source element of the instruction.
-        if (replacement.sourceElement == null) {
-          replacement.sourceElement = instruction.sourceElement;
-        }
-        if (replacement.sourceInformation == null) {
-          replacement.sourceInformation = instruction.sourceInformation;
-        }
+        replacement.sourceElement ??= instruction.sourceElement;
+        replacement.sourceInformation ??= instruction.sourceInformation;
+
         if (!replacement.isInBasicBlock()) {
           // The constant folding can return an instruction that is already
           // part of the graph (like an input), so we only add the replacement
@@ -222,8 +230,54 @@
 
   @override
   HInstruction visitInvokeDynamic(HInvokeDynamic node) {
+    if (!node.isInterceptedCall) return node;
+
     tryReplaceExplicitReceiverWithDummy(
         node, node.selector, node.element, node.receiverType);
+
+    // Try to replace
+    //
+    //     getInterceptor(o).method(o, ...)
+    //
+    // with a 'one shot interceptor' which is a call to a synthesized static
+    // helper function that combines the two operations.
+    //
+    //     oneShotMethod(o, 1, 2)
+    //
+    // This saves code size and makes the receiver of an intercepted call a
+    // candidate for being generated at use site.
+    //
+    // Avoid combining a hoisted interceptor back into a loop, and the faster
+    // almost-constant kind of interceptor.
+
+    HInstruction interceptor = node.inputs[0];
+    if (interceptor is HInterceptor &&
+        interceptor.usedBy.length == 1 &&
+        !interceptor.isConditionalConstantInterceptor &&
+        interceptor.hasSameLoopHeaderAs(node)) {
+      // Copy inputs and replace interceptor with `null`.
+      List<HInstruction> inputs = List.of(node.inputs);
+      inputs[0] = graph.addConstantNull(_closedWorld);
+
+      HOneShotInterceptor oneShot = HOneShotInterceptor(
+          node.selector,
+          node.receiverType,
+          inputs,
+          node.instructionType,
+          node.typeArguments,
+          interceptor.interceptedClasses);
+      oneShot.sourceInformation = node.sourceInformation;
+      oneShot.sourceElement = node.sourceElement;
+      oneShot.sideEffects.setTo(node.sideEffects);
+
+      HBasicBlock block = node.block;
+      block.addAfter(node, oneShot);
+      block.rewrite(node, oneShot);
+      block.remove(node);
+      interceptor.block.remove(interceptor);
+      return null;
+    }
+
     return node;
   }
 
@@ -236,8 +290,7 @@
 
   @override
   HInstruction visitOneShotInterceptor(HOneShotInterceptor node) {
-    // The receiver parameter should never be replaced with a dummy constant.
-    return node;
+    throw StateError('Should not see HOneShotInterceptor: $node');
   }
 
   void tryReplaceExplicitReceiverWithDummy(HInvoke node, Selector selector,
diff --git a/pkg/compiler/lib/src/ssa/interceptor_simplifier.dart b/pkg/compiler/lib/src/ssa/interceptor_simplifier.dart
index c7ffca6..968cf4f 100644
--- a/pkg/compiler/lib/src/ssa/interceptor_simplifier.dart
+++ b/pkg/compiler/lib/src/ssa/interceptor_simplifier.dart
@@ -353,40 +353,7 @@
       }
     }
 
-    // Try creating a one-shot interceptor or optimized is-check
-    if (node.usedBy.length != 1) return false;
-    HInstruction user = node.usedBy.single;
-
-    // If the interceptor [node] was loop hoisted, we keep the interceptor.
-    if (!user.hasSameLoopHeaderAs(node)) return false;
-
-    bool replaceUserWith(HInstruction replacement) {
-      HBasicBlock block = user.block;
-      block.addAfter(user, replacement);
-      block.rewrite(user, replacement);
-      block.remove(user);
-      return false;
-    }
-
-    if (user is HInvokeDynamic) {
-      if (node == user.inputs[0]) {
-        // Replace the user with a [HOneShotInterceptor].
-        HConstant nullConstant = _graph.addConstantNull(_closedWorld);
-        List<HInstruction> inputs = new List<HInstruction>.from(user.inputs);
-        inputs[0] = nullConstant;
-        HOneShotInterceptor oneShotInterceptor = new HOneShotInterceptor(
-            _abstractValueDomain,
-            user.selector,
-            user.receiverType,
-            inputs,
-            user.instructionType,
-            user.typeArguments,
-            interceptedClasses);
-        oneShotInterceptor.sourceInformation = user.sourceInformation;
-        oneShotInterceptor.sourceElement = user.sourceElement;
-        return replaceUserWith(oneShotInterceptor);
-      }
-    }
+    // One-shot interceptor optimization is done in instruction selection.
 
     return false;
   }
@@ -439,45 +406,6 @@
 
   @override
   bool visitOneShotInterceptor(HOneShotInterceptor node) {
-    // 'Undo' the one-shot transformation if the receiver has a constant
-    // interceptor.
-    HInstruction constant =
-        tryComputeConstantInterceptor(node.inputs[1], node.interceptedClasses);
-
-    if (constant == null) return false;
-
-    Selector selector = node.selector;
-    AbstractValue receiverType = node.receiverType;
-    HInstruction instruction;
-    if (selector.isGetter) {
-      instruction = new HInvokeDynamicGetter(
-          selector,
-          receiverType,
-          node.element,
-          <HInstruction>[constant, node.inputs[1]],
-          true,
-          node.instructionType,
-          node.sourceInformation);
-    } else if (selector.isSetter) {
-      instruction = new HInvokeDynamicSetter(
-          selector,
-          receiverType,
-          node.element,
-          <HInstruction>[constant, node.inputs[1], node.inputs[2]],
-          true,
-          node.instructionType,
-          node.sourceInformation);
-    } else {
-      List<HInstruction> inputs = new List<HInstruction>.from(node.inputs);
-      inputs[0] = constant;
-      instruction = new HInvokeDynamicMethod(selector, receiverType, inputs,
-          node.instructionType, node.typeArguments, node.sourceInformation,
-          isIntercepted: true);
-    }
-
-    HBasicBlock block = node.block;
-    block.addAfter(node, instruction);
-    block.rewrite(node, instruction);
-    return true;
+    throw StateError('Should not see HOneShotInterceptor: $node');
   }
 }
diff --git a/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart b/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart
index 61d417f..ba133a6 100644
--- a/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart
+++ b/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart
@@ -67,8 +67,9 @@
       if (name == '/') return const DivideSpecializer();
       if (name == '~/') return const TruncatingDivideSpecializer();
       if (name == '%') return const ModuloSpecializer();
-      if (name == '>>') return const ShiftRightSpecializer();
       if (name == '<<') return const ShiftLeftSpecializer();
+      if (name == '>>') return const ShiftRightSpecializer();
+      if (name == '>>>') return const ShiftRightUnsignedSpecializer();
       if (name == '&') return const BitAndSpecializer();
       if (name == '|') return const BitOrSpecializer();
       if (name == '^') return const BitXorSpecializer();
@@ -163,7 +164,7 @@
     return canBeNegativeZero(input.left) && canBePositiveZero(input.right);
   }
   if (input is HPhi) {
-    if (input.inputs.any((phiInput) => phiInput.block.id > input.block.id)) {
+    if (input.inputs.any((phiInput) => phiInput.block.id >= input.block.id)) {
       return true; // Assume back-edge may be negative zero.
     }
     return input.inputs.any(canBeNegativeZero);
@@ -1045,6 +1046,71 @@
   }
 }
 
+class ShiftRightUnsignedSpecializer extends BinaryBitOpSpecializer {
+  const ShiftRightUnsignedSpecializer();
+
+  @override
+  AbstractValue computeTypeFromInputTypes(HInvokeDynamic instruction,
+      GlobalTypeInferenceResults results, JClosedWorld closedWorld) {
+    HInstruction left = instruction.inputs[1];
+    if (left.isUInt32(closedWorld.abstractValueDomain).isDefinitelyTrue) {
+      return left.instructionType;
+    }
+    return super.computeTypeFromInputTypes(instruction, results, closedWorld);
+  }
+
+  @override
+  HInstruction tryConvertToBuiltin(
+      HInvokeDynamic instruction,
+      HGraph graph,
+      GlobalTypeInferenceResults results,
+      JCommonElements commonElements,
+      JClosedWorld closedWorld,
+      OptimizationTestLog log) {
+    HInstruction left = instruction.inputs[1];
+    HInstruction right = instruction.inputs[2];
+    if (left.isInteger(closedWorld.abstractValueDomain).isDefinitelyTrue) {
+      if (argumentLessThan32(right)) {
+        HInstruction converted =
+            newBuiltinVariant(instruction, results, closedWorld);
+        if (log != null) {
+          registerOptimization(log, instruction, converted);
+        }
+        return converted;
+      }
+      // Even if there is no builtin equivalent instruction, we know
+      // the instruction does not have any side effect, and that it
+      // can be GVN'ed.
+      clearAllSideEffects(instruction);
+      if (isPositive(right, closedWorld)) {
+        redirectSelector(instruction, '_shruOtherPositive', commonElements);
+        if (log != null) {
+          registerOptimization(log, instruction, null);
+        }
+      }
+    }
+    return null;
+  }
+
+  @override
+  HInstruction newBuiltinVariant(HInvokeDynamic instruction,
+      GlobalTypeInferenceResults results, JClosedWorld closedWorld) {
+    return HShiftRight(instruction.inputs[1], instruction.inputs[2],
+        computeTypeFromInputTypes(instruction, results, closedWorld));
+  }
+
+  @override
+  constant_system.BinaryOperation operation() {
+    return constant_system.shiftRightUnsigned;
+  }
+
+  @override
+  void registerOptimization(
+      OptimizationTestLog log, HInstruction original, HInstruction converted) {
+    log.registerShiftRightUnsigned(original, converted);
+  }
+}
+
 class BitOrSpecializer extends BinaryBitOpSpecializer {
   const BitOrSpecializer();
 
diff --git a/pkg/compiler/lib/src/ssa/logging.dart b/pkg/compiler/lib/src/ssa/logging.dart
index 4eff5a9..e2c63af 100644
--- a/pkg/compiler/lib/src/ssa/logging.dart
+++ b/pkg/compiler/lib/src/ssa/logging.dart
@@ -179,6 +179,12 @@
         'ShiftRight.${original.selector.name}');
   }
 
+  void registerShiftRightUnsigned(
+      HInvokeDynamic original, HShiftRight converted) {
+    _registerSpecializer(original, converted, 'ShiftRightUnsigned',
+        'ShiftRightUnsigned.${original.selector.name}');
+  }
+
   void registerBitOr(HInvokeDynamic original, HBitOr converted) {
     _registerSpecializer(original, converted, 'BitOr');
   }
diff --git a/pkg/compiler/lib/src/ssa/nodes.dart b/pkg/compiler/lib/src/ssa/nodes.dart
index fee62dd..47298de 100644
--- a/pkg/compiler/lib/src/ssa/nodes.dart
+++ b/pkg/compiler/lib/src/ssa/nodes.dart
@@ -3325,20 +3325,19 @@
   }
 }
 
-/// A "one-shot" interceptor is a call to a synthetized method that
-/// will fetch the interceptor of its first parameter, and make a call
-/// on a given selector with the remaining parameters.
+/// A "one-shot" interceptor is a call to a synthetized method that will fetch
+/// the interceptor of its first parameter, and make a call on a given selector
+/// with the remaining parameters.
 ///
-/// In order to share the same optimizations with regular interceptor
-/// calls, this class extends [HInvokeDynamic] and also has the null
-/// constant as the first input.
+/// In order to share the same optimizations with regular interceptor calls,
+/// this class extends [HInvokeDynamic] and also has the null constant as the
+/// first input.
 class HOneShotInterceptor extends HInvokeDynamic {
   @override
   List<DartType> typeArguments;
   Set<ClassEntity> interceptedClasses;
 
   HOneShotInterceptor(
-      AbstractValueDomain domain,
       Selector selector,
       AbstractValue receiverType,
       List<HInstruction> inputs,
@@ -3346,8 +3345,7 @@
       this.typeArguments,
       this.interceptedClasses)
       : super(selector, receiverType, null, inputs, true, resultType) {
-    assert(inputs[0] is HConstant);
-    assert(inputs[0].instructionType == domain.nullType);
+    assert(inputs[0].isConstantNull());
     assert(selector.callStructure.typeArgumentCount == typeArguments.length);
   }
   @override
diff --git a/pkg/compiler/lib/src/ssa/optimize.dart b/pkg/compiler/lib/src/ssa/optimize.dart
index 02feb06..e0f7369 100644
--- a/pkg/compiler/lib/src/ssa/optimize.dart
+++ b/pkg/compiler/lib/src/ssa/optimize.dart
@@ -18,7 +18,6 @@
     show FieldAnalysisData, JFieldAnalysis;
 import '../js_backend/backend.dart' show CodegenInputs;
 import '../js_backend/native_data.dart' show NativeData;
-import '../js_backend/runtime_types_codegen.dart';
 import '../js_model/type_recipe.dart'
     show
         TypeRecipe,
@@ -89,14 +88,8 @@
       List<OptimizationPhase> phases = <OptimizationPhase>[
         // Run trivial instruction simplification first to optimize
         // some patterns useful for type conversion.
-        new SsaInstructionSimplifier(
-            globalInferenceResults,
-            _options,
-            codegen.rtiSubstitutions,
-            closedWorld,
-            typeRecipeDomain,
-            registry,
-            log),
+        new SsaInstructionSimplifier(globalInferenceResults, _options,
+            closedWorld, typeRecipeDomain, registry, log),
         new SsaTypeConversionInserter(closedWorld),
         new SsaRedundantPhiEliminator(),
         new SsaDeadPhiEliminator(),
@@ -104,22 +97,10 @@
             closedWorld.commonElements, closedWorld, log),
         // After type propagation, more instructions can be
         // simplified.
-        new SsaInstructionSimplifier(
-            globalInferenceResults,
-            _options,
-            codegen.rtiSubstitutions,
-            closedWorld,
-            typeRecipeDomain,
-            registry,
-            log),
-        new SsaInstructionSimplifier(
-            globalInferenceResults,
-            _options,
-            codegen.rtiSubstitutions,
-            closedWorld,
-            typeRecipeDomain,
-            registry,
-            log),
+        new SsaInstructionSimplifier(globalInferenceResults, _options,
+            closedWorld, typeRecipeDomain, registry, log),
+        new SsaInstructionSimplifier(globalInferenceResults, _options,
+            closedWorld, typeRecipeDomain, registry, log),
         new SsaTypePropagator(globalInferenceResults,
             closedWorld.commonElements, closedWorld, log),
         // Run a dead code eliminator before LICM because dead
@@ -143,14 +124,8 @@
         new SsaValueRangeAnalyzer(closedWorld, this),
         // Previous optimizations may have generated new
         // opportunities for instruction simplification.
-        new SsaInstructionSimplifier(
-            globalInferenceResults,
-            _options,
-            codegen.rtiSubstitutions,
-            closedWorld,
-            typeRecipeDomain,
-            registry,
-            log),
+        new SsaInstructionSimplifier(globalInferenceResults, _options,
+            closedWorld, typeRecipeDomain, registry, log),
       ];
       phases.forEach(runPhase);
 
@@ -171,14 +146,8 @@
           new SsaGlobalValueNumberer(closedWorld.abstractValueDomain),
           new SsaCodeMotion(closedWorld.abstractValueDomain),
           new SsaValueRangeAnalyzer(closedWorld, this),
-          new SsaInstructionSimplifier(
-              globalInferenceResults,
-              _options,
-              codegen.rtiSubstitutions,
-              closedWorld,
-              typeRecipeDomain,
-              registry,
-              log),
+          new SsaInstructionSimplifier(globalInferenceResults, _options,
+              closedWorld, typeRecipeDomain, registry, log),
           new SsaSimplifyInterceptors(closedWorld, member.enclosingClass),
           new SsaDeadCodeEliminator(closedWorld, this),
         ];
@@ -188,14 +157,8 @@
               closedWorld.commonElements, closedWorld, log),
           // Run the simplifier to remove unneeded type checks inserted by
           // type propagation.
-          new SsaInstructionSimplifier(
-              globalInferenceResults,
-              _options,
-              codegen.rtiSubstitutions,
-              closedWorld,
-              typeRecipeDomain,
-              registry,
-              log),
+          new SsaInstructionSimplifier(globalInferenceResults, _options,
+              closedWorld, typeRecipeDomain, registry, log),
         ];
       }
       phases.forEach(runPhase);
@@ -250,21 +213,14 @@
   final String name = "SsaInstructionSimplifier";
   final GlobalTypeInferenceResults _globalInferenceResults;
   final CompilerOptions _options;
-  final RuntimeTypesSubstitutions _rtiSubstitutions;
   final JClosedWorld _closedWorld;
   final TypeRecipeDomain _typeRecipeDomain;
   final CodegenRegistry _registry;
   final OptimizationTestLog _log;
   HGraph _graph;
 
-  SsaInstructionSimplifier(
-      this._globalInferenceResults,
-      this._options,
-      this._rtiSubstitutions,
-      this._closedWorld,
-      this._typeRecipeDomain,
-      this._registry,
-      this._log);
+  SsaInstructionSimplifier(this._globalInferenceResults, this._options,
+      this._closedWorld, this._typeRecipeDomain, this._registry, this._log);
 
   JCommonElements get commonElements => _closedWorld.commonElements;
 
@@ -1879,16 +1835,7 @@
 
   @override
   HInstruction visitOneShotInterceptor(HOneShotInterceptor node) {
-    return handleInterceptedCall(node);
-  }
-
-  bool needsSubstitutionForTypeVariableAccess(ClassEntity cls) {
-    if (_closedWorld.isUsedAsMixin(cls)) return true;
-
-    return _closedWorld.classHierarchy.anyStrictSubclassOf(cls,
-        (ClassEntity subclass) {
-      return !_rtiSubstitutions.isTrivialSubstitution(subclass, cls);
-    });
+    throw StateError('Should not see HOneShotInterceptor in simplifier: $node');
   }
 
   @override
diff --git a/pkg/compiler/lib/src/ssa/variable_allocator.dart b/pkg/compiler/lib/src/ssa/variable_allocator.dart
index c279758..a544500 100644
--- a/pkg/compiler/lib/src/ssa/variable_allocator.dart
+++ b/pkg/compiler/lib/src/ssa/variable_allocator.dart
@@ -168,14 +168,22 @@
   int instructionId = 0;
 
   /// The liveIns of basic blocks.
-  final Map<HBasicBlock, LiveEnvironment> liveInstructions;
+  final Map<HBasicBlock, LiveEnvironment> liveInstructions = {};
 
   /// The live intervals of instructions.
-  final Map<HInstruction, LiveInterval> liveIntervals;
+  final Map<HInstruction, LiveInterval> liveIntervals = {};
 
-  SsaLiveIntervalBuilder(this.generateAtUseSite, this.controlFlowOperators)
-      : liveInstructions = new Map<HBasicBlock, LiveEnvironment>(),
-        liveIntervals = new Map<HInstruction, LiveInterval>();
+  /// Controlling conditions for control-flow operators. Control-flow operators,
+  /// e.g. `c ? a : b`, have a condition input `c` from the HIf node
+  /// at the top of the control flow diamond as well as the HPhi inputs for `a`
+  /// and `b` at the bottom of the diamond.
+  final Map<HInstruction, HInstruction> _phiToCondition = {};
+
+  SsaLiveIntervalBuilder(this.generateAtUseSite, this.controlFlowOperators) {
+    for (HIf ifNode in controlFlowOperators) {
+      _phiToCondition[ifNode.joinBlock.phis.first] = ifNode.condition;
+    }
+  }
 
   @override
   void visitGraph(HGraph graph) {
@@ -187,6 +195,12 @@
 
   void markInputsAsLiveInEnvironment(
       HInstruction instruction, LiveEnvironment environment) {
+    if (instruction is HPhi) {
+      HInstruction condition = _phiToCondition[instruction];
+      if (condition != null) {
+        markAsLiveInEnvironment(condition, environment);
+      }
+    }
     for (int i = 0, len = instruction.inputs.length; i < len; i++) {
       markAsLiveInEnvironment(instruction.inputs[i], environment);
     }
@@ -257,21 +271,7 @@
 
   @override
   void visitBasicBlock(HBasicBlock block) {
-    LiveEnvironment environment =
-        new LiveEnvironment(liveIntervals, instructionId);
-
-    // If the control flow instruction in this block will actually be
-    // inlined in the codegen in the join block, we need to make
-    // whatever is used by that control flow instruction as live in
-    // the join block.
-    if (controlFlowOperators.contains(block.last)) {
-      HIf ifInstruction = block.last;
-      HBasicBlock joinBlock = ifInstruction.joinBlock;
-      if (generateAtUseSite.contains(joinBlock.phis.first)) {
-        markInputsAsLiveInEnvironment(
-            ifInstruction, liveInstructions[joinBlock]);
-      }
-    }
+    LiveEnvironment environment = LiveEnvironment(liveIntervals, instructionId);
 
     // Add to the environment the liveIn of its successor, as well as
     // the inputs of the phis of the successor that flow from this block.
diff --git a/pkg/compiler/lib/src/universe/class_hierarchy.dart b/pkg/compiler/lib/src/universe/class_hierarchy.dart
index 49a899e..d4a17ee 100644
--- a/pkg/compiler/lib/src/universe/class_hierarchy.dart
+++ b/pkg/compiler/lib/src/universe/class_hierarchy.dart
@@ -83,6 +83,10 @@
   /// _not_ including [cls].
   Iterable<ClassEntity> strictSubtypesOf(ClassEntity cls);
 
+  /// Returns an iterable over all the classes that implement [cls], including
+  /// [cls] itself.
+  Iterable<ClassEntity> allSubtypesOf(ClassEntity cls);
+
   /// Returns the number of live classes that implement [cls] _not_
   /// including [cls] itself.
   int strictSubtypeCount(ClassEntity cls);
@@ -320,6 +324,16 @@
   }
 
   @override
+  Iterable<ClassEntity> allSubtypesOf(ClassEntity cls) {
+    ClassSet classSet = _classSets[cls];
+    if (classSet == null) {
+      return const <ClassEntity>[];
+    } else {
+      return classSet.subtypesByMask(ClassHierarchyNode.ALL);
+    }
+  }
+
+  @override
   int strictSubtypeCount(ClassEntity cls) {
     ClassSet classSet = _classSets[cls];
     if (classSet == null) return 0;
diff --git a/pkg/compiler/lib/src/universe/codegen_world_builder.dart b/pkg/compiler/lib/src/universe/codegen_world_builder.dart
index 8b34788..b63141d 100644
--- a/pkg/compiler/lib/src/universe/codegen_world_builder.dart
+++ b/pkg/compiler/lib/src/universe/codegen_world_builder.dart
@@ -14,6 +14,7 @@
 import '../js_backend/interceptor_data.dart' show OneShotInterceptorData;
 import '../js_backend/native_data.dart' show NativeBasicData;
 import '../js_model/elements.dart';
+import '../universe/class_hierarchy.dart';
 import '../util/enumset.dart';
 import '../util/util.dart';
 import '../world.dart';
@@ -677,6 +678,9 @@
   AnnotationsData get annotationsData => _closedWorld.annotationsData;
 
   @override
+  ClassHierarchy get classHierarchy => _closedWorld.classHierarchy;
+
+  @override
   void forEachStaticField(void Function(FieldEntity) f) {
     bool failure = false;
     _liveMemberUsage.forEach((MemberEntity member, MemberUsage usage) {
diff --git a/pkg/compiler/lib/src/universe/feature.dart b/pkg/compiler/lib/src/universe/feature.dart
index 7ea60b7..f907c36 100644
--- a/pkg/compiler/lib/src/universe/feature.dart
+++ b/pkg/compiler/lib/src/universe/feature.dart
@@ -237,7 +237,7 @@
   static const String tag = 'generic-instantiation';
 
   /// The static type of the instantiated expression.
-  final DartType functionType;
+  final FunctionType functionType;
 
   /// The type arguments of the instantiation.
   final List<DartType> typeArguments;
diff --git a/pkg/compiler/lib/src/world.dart b/pkg/compiler/lib/src/world.dart
index 68effb3..e1f8a31 100644
--- a/pkg/compiler/lib/src/world.dart
+++ b/pkg/compiler/lib/src/world.dart
@@ -249,6 +249,8 @@
 
 /// A [BuiltWorld] is an immutable result of a [WorldBuilder].
 abstract class BuiltWorld {
+  ClassHierarchy get classHierarchy;
+
   /// Calls [f] for each live generic method.
   void forEachGenericMethod(void Function(FunctionEntity) f);
 
@@ -308,6 +310,8 @@
   InterceptorData get interceptorData;
   KElementEnvironment get elementEnvironment;
   KCommonElements get commonElements;
+
+  @override
   ClassHierarchy get classHierarchy;
 
   /// Returns `true` if [cls] is implemented by an instantiated class.
diff --git a/pkg/compiler/pubspec.yaml b/pkg/compiler/pubspec.yaml
index 0f826c1..1073c93 100644
--- a/pkg/compiler/pubspec.yaml
+++ b/pkg/compiler/pubspec.yaml
@@ -31,6 +31,7 @@
 dev_dependencies:
   # Published packages - repo version ensured via dependency_overrides
   args: any
+  dart_style: any
   http: any
   js:
     path: ../js
diff --git a/pkg/compiler/test/analyses/analysis_helper.dart b/pkg/compiler/test/analyses/analysis_helper.dart
index fb096c3..43fb4db 100644
--- a/pkg/compiler/test/analyses/analysis_helper.dart
+++ b/pkg/compiler/test/analyses/analysis_helper.dart
@@ -11,9 +11,6 @@
 import 'package:async_helper/async_helper.dart';
 import 'package:compiler/src/common.dart';
 import 'package:compiler/src/compiler.dart';
-import 'package:compiler/src/diagnostics/diagnostic_listener.dart';
-import 'package:compiler/src/diagnostics/messages.dart';
-import 'package:compiler/src/diagnostics/source_span.dart';
 import 'package:compiler/src/ir/constants.dart';
 import 'package:compiler/src/ir/scope.dart';
 import 'package:compiler/src/ir/static_type.dart';
diff --git a/pkg/compiler/test/analyses/analyze_test.dart b/pkg/compiler/test/analyses/analyze_test.dart
index b0f6832..affe1b1 100644
--- a/pkg/compiler/test/analyses/analyze_test.dart
+++ b/pkg/compiler/test/analyses/analyze_test.dart
@@ -4,11 +4,16 @@
 
 // @dart = 2.7
 
+import 'dart:io' show exitCode;
+
 import "package:testing/src/run_tests.dart" as testing show main;
 
-main() {
+main() async {
   // This method is async, but keeps a port open to prevent the VM from exiting
   // prematurely.
-  return testing.main(
+  await testing.main(
       <String>["--config=pkg/compiler/testing.json", "--verbose", "analyze"]);
+  if (exitCode != 0) {
+    throw "Exit-code was $exitCode!";
+  }
 }
diff --git a/pkg/compiler/test/analyses/api_allowed.json b/pkg/compiler/test/analyses/api_allowed.json
index 241f168..cbee4e6 100644
--- a/pkg/compiler/test/analyses/api_allowed.json
+++ b/pkg/compiler/test/analyses/api_allowed.json
@@ -172,15 +172,19 @@
     "Dynamic invocation of 'toLowerCase'.": 1
   },
   "org-dartlang-sdk:///lib/_http/http_impl.dart": {
+    "Dynamic access of 'headers'.": 1,
+    "Dynamic invocation of 'forEach'.": 1,
+    "Dynamic access of 'connectionInfo'.": 4,
+    "Dynamic access of 'localPort'.": 1,
+    "Dynamic access of 'remoteAddress'.": 2,
+    "Dynamic access of 'address'.": 3,
+    "Dynamic access of 'remotePort'.": 2,
     "Dynamic access of 'message'.": 3,
     "Dynamic invocation of 'call'.": 1,
     "Dynamic invocation of 'destroy'.": 2,
     "Dynamic invocation of 'setOption'.": 1,
-    "Dynamic access of 'address'.": 2,
     "Dynamic access of 'host'.": 2,
     "Dynamic access of 'port'.": 2,
-    "Dynamic access of 'remoteAddress'.": 1,
-    "Dynamic access of 'remotePort'.": 1,
     "Dynamic invocation of 'dart._http::_toJSON'.": 3,
     "Dynamic invocation of 'listen'.": 1,
     "Dynamic invocation of 'close'.": 1
diff --git a/pkg/compiler/test/analyses/dart2js_allowed.json b/pkg/compiler/test/analyses/dart2js_allowed.json
index 10ea069..3fb0668 100644
--- a/pkg/compiler/test/analyses/dart2js_allowed.json
+++ b/pkg/compiler/test/analyses/dart2js_allowed.json
@@ -45,8 +45,7 @@
   },
   "pkg/compiler/lib/src/deferred_load.dart": {
     "Dynamic access of 'memberContext'.": 1,
-    "Dynamic access of 'name'.": 1,
-    "Dynamic invocation of '[]='.": 1
+    "Dynamic access of 'name'.": 1
   },
   "pkg/compiler/lib/src/inferrer/typemasks/container_type_mask.dart": {
     "Dynamic access of 'isNullable'.": 2,
@@ -197,6 +196,9 @@
     "Dynamic invocation of '[]='.": 1,
     "Dynamic invocation of 'add'.": 1
   },
+  "pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_merger.dart": {
+    "Dynamic invocation of '[]='.": 1
+  },
   "pkg/js_ast/lib/src/builder.dart": {
     "Dynamic invocation of 'call'.": 2
   },
diff --git a/pkg/compiler/test/closure/closure_test.dart b/pkg/compiler/test/closure/closure_test.dart
index 231025d..78c02dc 100644
--- a/pkg/compiler/test/closure/closure_test.dart
+++ b/pkg/compiler/test/closure/closure_test.dart
@@ -11,7 +11,6 @@
 import 'package:compiler/src/closure.dart';
 import 'package:compiler/src/common.dart';
 import 'package:compiler/src/compiler.dart';
-import 'package:compiler/src/diagnostics/diagnostic_listener.dart';
 import 'package:compiler/src/elements/entities.dart';
 import 'package:compiler/src/js_model/element_map.dart';
 import 'package:compiler/src/js_model/js_world.dart';
diff --git a/pkg/compiler/test/codegen/codegen_test_helper.dart b/pkg/compiler/test/codegen/codegen_test_helper.dart
index f28f670..e4f9c73 100644
--- a/pkg/compiler/test/codegen/codegen_test_helper.dart
+++ b/pkg/compiler/test/codegen/codegen_test_helper.dart
@@ -33,7 +33,7 @@
       shards: 2,
       directory: 'data',
       skip: skip,
-      options: [Flags.soundNullSafety]);
+      options: [Flags.soundNullSafety, '--enable-experiment=triple-shift']);
 }
 
 runTests2(List<String> args, [int shardIndex]) {
diff --git a/pkg/compiler/test/codegen/constant_folding_test.dart b/pkg/compiler/test/codegen/constant_folding_test.dart
index 06d09ad..a3471c3 100644
--- a/pkg/compiler/test/codegen/constant_folding_test.dart
+++ b/pkg/compiler/test/codegen/constant_folding_test.dart
@@ -65,16 +65,16 @@
         NEGATIVE_NUMBER_FOLDING, 'main', new RegExp(r"print\(1\)"));
     await compile(NULL_EQUALS_FOLDING, entry: 'foo', check: (String generated) {
       RegExp regexp = new RegExp(r'a == null');
-      Expect.isTrue(regexp.hasMatch(generated));
+      Expect.isTrue(regexp.hasMatch(generated), 'No match found for ${regexp}');
 
       regexp = new RegExp(r'null == b');
-      Expect.isTrue(regexp.hasMatch(generated));
+      Expect.isTrue(regexp.hasMatch(generated), 'No match found for ${regexp}');
 
       regexp = new RegExp(r'4 === c');
-      Expect.isTrue(regexp.hasMatch(generated));
+      Expect.isTrue(regexp.hasMatch(generated), 'No match found for ${regexp}');
 
       regexp = new RegExp('"foo" === d');
-      Expect.isTrue(regexp.hasMatch(generated));
+      Expect.isTrue(regexp.hasMatch(generated), 'No match found for ${regexp}');
     });
     await compileAndMatch(LIST_LENGTH_FOLDING, 'foo', new RegExp(r"return 3"));
     await compileAndMatch(LIST_INDEX_FOLDING, 'foo', new RegExp(r"return 1"));
diff --git a/pkg/compiler/test/codegen/data/shift_right_unsigned.dart b/pkg/compiler/test/codegen/data/shift_right_unsigned.dart
new file mode 100644
index 0000000..23043cf
--- /dev/null
+++ b/pkg/compiler/test/codegen/data/shift_right_unsigned.dart
@@ -0,0 +1,117 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+//@dart=2.13
+
+/*member: main:ignore*/
+void main() {
+  for (var a in [false, true]) {
+    sink = cannotRecognize(a ? 10 : C());
+    sink = unspecialized(a ? -1 : 1);
+    sink = otherPositive2(a);
+    sink = shiftBySix(a);
+    sink = shiftByMasked(a, 9);
+    sink = shiftByMasked(a, -9);
+  }
+
+  sink = cannotConstantFold();
+  sink = constantFoldPositive();
+  sink = constantFoldNegative();
+  test6();
+}
+
+Object? sink;
+
+@pragma('dart2js:noInline')
+/*spec.member: cannotRecognize:function(thing) {
+  return H._asInt(J.$shru$n(thing, 1));
+}*/
+/*prod.member: cannotRecognize:function(thing) {
+  return J.$shru$n(thing, 1);
+}*/
+int cannotRecognize(dynamic thing) {
+  return thing >>> 1;
+}
+
+@pragma('dart2js:noInline')
+/*member: cannotConstantFold:function() {
+  return C.JSInt_methods.$shru(1, -1);
+}*/
+int cannotConstantFold() {
+  var a = 1;
+  return a >>> -1;
+}
+
+@pragma('dart2js:noInline')
+/*member: constantFoldPositive:function() {
+  return 25;
+}*/
+int constantFoldPositive() {
+  var a = 100;
+  return a >>> 2;
+}
+
+@pragma('dart2js:noInline')
+/*member: constantFoldNegative:function() {
+  return 3;
+}*/
+int constantFoldNegative() {
+  var a = -1;
+  return a >>> 30;
+}
+
+@pragma('dart2js:noInline')
+/*member: unspecialized:function(a) {
+  return C.JSInt_methods.$shru(1, a);
+}*/
+int unspecialized(int a) {
+  return 1 >>> a;
+}
+
+@pragma('dart2js:noInline')
+/*member: otherPositive2:function(param) {
+  return C.JSInt_methods._shruOtherPositive$1(1, param ? 1 : 2);
+}*/
+int otherPositive2(bool param) {
+  var a = param ? 1 : 2;
+  return 1 >>> a;
+}
+
+@pragma('dart2js:noInline')
+/*member: shiftBySix:function(param) {
+  return (param ? 4294967295 : -1) >>> 6;
+}*/
+int shiftBySix(bool param) {
+  var a = param ? 0xFFFFFFFF : -1;
+  return a >>> 6;
+}
+
+@pragma('dart2js:noInline')
+/*member: shiftByMasked:function(param1, shift) {
+  var a = param1 ? 4294967295 : 0;
+  return a >>> (shift & 31);
+}*/
+int shiftByMasked(bool param1, int shift) {
+  var a = param1 ? 0xFFFFFFFF : 0;
+  return a >>> (shift & 31);
+}
+
+@pragma('dart2js:noInline')
+/*member: otherPositive6:function(a, b) {
+  return C.JSInt_methods._shruOtherPositive$1(a, b);
+}*/
+int otherPositive6(int a, int b) {
+  return a >>> b;
+}
+
+void test6() {
+  sink = otherPositive6(1, 3);
+  sink = otherPositive6(0, 4);
+  sink = otherPositive6(-1, 2);
+}
+
+class C {
+  /*member: C.>>>:ignore*/
+  C operator >>>(int i) => this;
+}
diff --git a/pkg/compiler/test/codegen/expect_annotations_test.dart b/pkg/compiler/test/codegen/expect_annotations_test.dart
index a3df294..5587f3f 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/types.dart';
 import 'package:compiler/src/world.dart' show JClosedWorld;
 import '../inference/type_mask_test_helper.dart';
 import '../helpers/memory_compiler.dart';
diff --git a/pkg/compiler/test/codegen/shift_right_unsigned_test.dart b/pkg/compiler/test/codegen/shift_right_unsigned_test.dart
new file mode 100644
index 0000000..d4d6d2c
--- /dev/null
+++ b/pkg/compiler/test/codegen/shift_right_unsigned_test.dart
@@ -0,0 +1,155 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart = 2.11
+
+library shru_test;
+
+import 'dart:async';
+import 'package:async_helper/async_helper.dart';
+import '../helpers/compiler_helper.dart';
+
+const COMMON = r"""
+int g1 = 0, g2 = 0;
+int sink1 = 0, sink2 = 0;
+
+main() {
+  for (int i = 0; i < 0x100000000; i = i + (i >> 4) + 1) {
+    g1 = g2 = i;
+    sink1 = callFoo(i, 1 - i, i);
+    sink2 = callFoo(2 - i, i, 3 - i);
+  }
+}
+""";
+
+const tests = [
+  r"""
+// constant-fold positive
+int foo(int param) {
+  int a = 100;
+  int b = 2;
+  return a >>> b;
+  // present: 'return 25;'
+}
+""",
+
+  r"""
+// constant-fold negative
+int foo(int param) {
+  int a = -1;
+  int b = 30;
+  return a >>> b;
+  // present: 'return 3;'
+}
+  """,
+
+  r"""
+// base case
+int foo(int value, int shift) {
+  return value >>> shift;
+  // Default code pattern:
+  // present: 'return C.JSInt_methods.$shru(value, shift);'
+}
+int callFoo(int a, int b, int c) => foo(a, b);
+""",
+
+  r"""
+// shift by zero
+int foo(int param) {
+  return param >>> 0;
+  // present: 'return param >>> 0;'
+}
+  """,
+
+  r"""
+// shift by one
+int foo(int param) {
+  return param >>> 1;
+  // present: 'return param >>> 1;'
+}
+""",
+
+  r"""
+// shift masked into safe range
+int foo(int value, int shift) {
+  return value >>> (shift & 31);
+  // present: 'return value >>> (shift & 31);'
+}
+int callFoo(int a, int b, int c) => foo(a, b);
+""",
+
+  r"""
+// idempotent shift by zero
+int foo(int param) {
+  return param >>> 0 >>> 0 >>> 0;
+  // present: 'return param >>> 0;'
+}
+""",
+
+  r"""
+// idempotent shift by zero #2
+int foo(int param) {
+  return (param & 15) >>> 0;
+  // present: 'return param & 15;'
+}
+  """,
+
+// TODO(sra): shift-shift reduction.
+//  r"""
+//// shift-shift-reduction
+//int foo(int param) {
+//  return param >>> 1 >>> 2;
+//  // present: 'return param >>> 3'
+//}
+//""",
+
+  r"""
+// mask-shift to shift-mask reduction
+int foo(int param) {
+  return (param & 0xF0) >>> 4;
+  // present: 'return param >>> 4 & 15'
+}
+""",
+
+  r"""
+// mask-shift to shift-mask reduction enabling mask reduction
+int foo(int param) {
+  return (param & 0x7FFFFFFF) >>> 31;
+  // present: 'return 0;'
+}
+""",
+];
+
+main() {
+  runTests() async {
+    Future check(String test) {
+      String program = COMMON + '\n\n' + test;
+      if (!test.contains('callFoo')) {
+        program += 'int callFoo(int a, int b, int c) => foo(a);\n';
+      }
+      return compile(program,
+          entry: 'main',
+          methodName: 'foo',
+          disableTypeInference: false,
+          enableTripleShift: true,
+          soundNullSafety: true,
+          check: checkerForAbsentPresent(test));
+    }
+
+    for (final test in tests) {
+      String name = 'unnamed';
+      if (test.startsWith('//')) {
+        final comment = test.split('\n').first.replaceFirst('//', '').trim();
+        if (comment.isNotEmpty) name = comment;
+      }
+      print('-- $name');
+      await check(test);
+    }
+  }
+
+  asyncTest(() async {
+    print('--test from kernel------------------------------------------------');
+    await runTests();
+  });
+}
diff --git a/pkg/compiler/test/deferred/closures_test.dart b/pkg/compiler/test/deferred/closures_test.dart
index 5969125..c672c81 100644
--- a/pkg/compiler/test/deferred/closures_test.dart
+++ b/pkg/compiler/test/deferred/closures_test.dart
@@ -11,7 +11,6 @@
 import 'package:expect/expect.dart';
 
 import '../helpers/memory_compiler.dart';
-import '../helpers/output_collector.dart';
 
 void main() {
   asyncTest(() async {
diff --git a/pkg/compiler/test/deferred/constant_emission_test_helper.dart b/pkg/compiler/test/deferred/constant_emission_test_helper.dart
index ce54b1b..d8fc00a 100644
--- a/pkg/compiler/test/deferred/constant_emission_test_helper.dart
+++ b/pkg/compiler/test/deferred/constant_emission_test_helper.dart
@@ -7,7 +7,6 @@
 // Test that the additional runtime type support is output to the right
 // Files when using deferred loading.
 
-import 'package:compiler/compiler_new.dart';
 import 'package:compiler/src/compiler.dart';
 import 'package:compiler/src/constants/values.dart';
 import 'package:compiler/src/deferred_load.dart';
@@ -17,7 +16,6 @@
 import 'package:compiler/src/util/util.dart';
 import 'package:expect/expect.dart';
 import '../helpers/memory_compiler.dart';
-import '../helpers/output_collector.dart';
 import '../helpers/program_lookup.dart';
 
 class OutputUnitDescriptor {
diff --git a/pkg/compiler/test/deferred/emit_type_checks_test.dart b/pkg/compiler/test/deferred/emit_type_checks_test.dart
index 38150fc..d4184ad8 100644
--- a/pkg/compiler/test/deferred/emit_type_checks_test.dart
+++ b/pkg/compiler/test/deferred/emit_type_checks_test.dart
@@ -13,7 +13,6 @@
 import 'package:compiler/src/js_model/js_strategy.dart';
 import 'package:expect/expect.dart';
 import '../helpers/memory_compiler.dart';
-import '../helpers/output_collector.dart';
 
 void main() {
   runTest() async {
diff --git a/pkg/compiler/test/deferred/load_graph_segmentation_test.dart b/pkg/compiler/test/deferred/load_graph_segmentation_test.dart
index 3dc7942..823899f 100644
--- a/pkg/compiler/test/deferred/load_graph_segmentation_test.dart
+++ b/pkg/compiler/test/deferred/load_graph_segmentation_test.dart
@@ -11,9 +11,20 @@
 import 'package:async_helper/async_helper.dart';
 import 'package:compiler/src/compiler.dart';
 import 'package:compiler/src/deferred_load.dart';
+import 'package:compiler/src/js_emitter/startup_emitter/fragment_merger.dart';
 import 'package:expect/expect.dart';
 import '../helpers/memory_compiler.dart';
 
+List<OutputUnit> collectOutputUnits(List<FinalizedFragment> fragments) {
+  List<OutputUnit> outputUnits = [];
+  for (var fragment in fragments) {
+    for (var codeFragment in fragment.codeFragments) {
+      outputUnits.addAll(codeFragment.outputUnits);
+    }
+  }
+  return outputUnits;
+}
+
 void main() {
   asyncTest(() async {
     CompilationResult result =
@@ -59,12 +70,12 @@
     // InputElement is native, so it should be in the mainOutputUnit.
     Expect.equals(mainOutputUnit, outputUnitForClass(inputElement));
 
-    var hunksToLoad = closedWorld.outputUnitData.hunksToLoad;
-
-    var hunksLib1 = hunksToLoad["lib1"];
-    var hunksLib2 = hunksToLoad["lib2"];
-    var hunksLib4_1 = hunksToLoad["lib4_1"];
-    var hunksLib4_2 = hunksToLoad["lib4_2"];
+    var hunksToLoad =
+        backendStrategy.emitterTask.emitter.finalizedFragmentsToLoad;
+    var hunksLib1 = collectOutputUnits(hunksToLoad["lib1"]);
+    var hunksLib2 = collectOutputUnits(hunksToLoad["lib2"]);
+    var hunksLib4_1 = collectOutputUnits(hunksToLoad["lib4_1"]);
+    var hunksLib4_2 = collectOutputUnits(hunksToLoad["lib4_2"]);
     Expect.listEquals([ou_lib1_lib2, ou_lib1], hunksLib1);
     Expect.listEquals([ou_lib1_lib2, ou_lib2], hunksLib2);
     Expect.listEquals([ou_lib4_1], hunksLib4_1);
diff --git a/pkg/compiler/test/deferred/load_mapping_test.dart b/pkg/compiler/test/deferred/load_mapping_test.dart
index c158dc4..ffb7b84 100644
--- a/pkg/compiler/test/deferred/load_mapping_test.dart
+++ b/pkg/compiler/test/deferred/load_mapping_test.dart
@@ -4,27 +4,24 @@
 
 // @dart = 2.7
 
+import 'dart:convert';
 import 'package:expect/expect.dart';
 import 'package:async_helper/async_helper.dart';
 import 'package:compiler/compiler_new.dart';
-import 'package:compiler/src/world.dart';
-import '../helpers/memory_source_file_helper.dart';
 import '../helpers/memory_compiler.dart';
 
 void testLoadMap() async {
   var collector = new OutputCollector();
-  CompilationResult result = await runCompiler(
+  await runCompiler(
       memorySourceFiles: MEMORY_SOURCE_FILES,
       options: ['--deferred-map=deferred_map.json'],
       outputProvider: collector);
-  CompilerImpl compiler = result.compiler;
-  JClosedWorld closedWorld = compiler.backendClosedWorldForTesting;
   // Ensure a mapping file is output.
-  Expect.isNotNull(
-      collector.getOutput("deferred_map.json", OutputType.deferredMap));
+  var deferredMap =
+      collector.getOutput("deferred_map.json", OutputType.deferredMap);
+  Expect.isNotNull(deferredMap);
+  var mapping = jsonDecode(deferredMap);
 
-  Map mapping = closedWorld.outputUnitData
-      .computeDeferredMap(compiler.options, closedWorld.elementEnvironment);
   // Test structure of mapping.
   Expect.equals("<unnamed>", mapping["main.dart"]["name"]);
   Expect.equals(2, mapping["main.dart"]["imports"]["lib1"].length);
@@ -50,7 +47,9 @@
   // result we expect to have an 6 output files:
   //  * one for code that is only use by an individual deferred import, and
   //  * an extra one for the intersection of lib1 and lib2.
-  var expected = ['10000', '01000', '00100', '00010', '00001', '01100'];
+  var expected = ['10000', '01000', '00100', '00010', '00001', '00110'];
+  expected.sort();
+  actual.sort();
   Expect.listEquals(expected, actual);
 }
 
diff --git a/pkg/compiler/test/deferred_loading/data/components/libA.dart b/pkg/compiler/test/deferred_loading/data/components/libA.dart
new file mode 100644
index 0000000..156d3fc
--- /dev/null
+++ b/pkg/compiler/test/deferred_loading/data/components/libA.dart
@@ -0,0 +1,8 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/*member: component:member_unit=1{libA}*/
+String component() {
+  return 'libA';
+}
diff --git a/pkg/compiler/test/deferred_loading/data/components/libB.dart b/pkg/compiler/test/deferred_loading/data/components/libB.dart
new file mode 100644
index 0000000..87b10d5
--- /dev/null
+++ b/pkg/compiler/test/deferred_loading/data/components/libB.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "libBCDE.dart";
+
+/*member: component:member_unit=2{libB}*/
+String component() {
+  return componentBCDE();
+}
diff --git a/pkg/compiler/test/deferred_loading/data/components/libBCDE.dart b/pkg/compiler/test/deferred_loading/data/components/libBCDE.dart
new file mode 100644
index 0000000..77a74fe
--- /dev/null
+++ b/pkg/compiler/test/deferred_loading/data/components/libBCDE.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@pragma('dart2js:noInline')
+/*member: componentBCDE:member_unit=3{libB, libC, libD, libE}*/
+String componentBCDE() {
+  return 'libBCDE';
+}
diff --git a/pkg/compiler/test/deferred_loading/data/components/libC.dart b/pkg/compiler/test/deferred_loading/data/components/libC.dart
new file mode 100644
index 0000000..d13a2f5
--- /dev/null
+++ b/pkg/compiler/test/deferred_loading/data/components/libC.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "libBCDE.dart";
+
+/*member: component:member_unit=4{libC}*/
+String component() {
+  return componentBCDE();
+}
diff --git a/pkg/compiler/test/deferred_loading/data/components/libD.dart b/pkg/compiler/test/deferred_loading/data/components/libD.dart
new file mode 100644
index 0000000..c20123e
--- /dev/null
+++ b/pkg/compiler/test/deferred_loading/data/components/libD.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "libBCDE.dart";
+
+/*member: component:member_unit=5{libD}*/
+String component() {
+  return componentBCDE();
+}
diff --git a/pkg/compiler/test/deferred_loading/data/components/libE.dart b/pkg/compiler/test/deferred_loading/data/components/libE.dart
new file mode 100644
index 0000000..fd8e3c2
--- /dev/null
+++ b/pkg/compiler/test/deferred_loading/data/components/libE.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "libBCDE.dart";
+
+/*member: component:member_unit=6{libE}*/
+String component() {
+  return componentBCDE();
+}
diff --git a/pkg/compiler/test/deferred_loading/data/components/main.dart b/pkg/compiler/test/deferred_loading/data/components/main.dart
new file mode 100644
index 0000000..e918bf6
--- /dev/null
+++ b/pkg/compiler/test/deferred_loading/data/components/main.dart
@@ -0,0 +1,69 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/*spec.library: 
+ output_units=[
+  f1: {units: [1{libA}], usedBy: [], needs: []},
+  f2: {units: [3{libB, libC, libD, libE}], usedBy: [], needs: []},
+  f3: {units: [2{libB}], usedBy: [], needs: []},
+  f4: {units: [4{libC}], usedBy: [], needs: []},
+  f5: {units: [5{libD}], usedBy: [], needs: []},
+  f6: {units: [6{libE}], usedBy: [], needs: []}],
+ steps=[
+  libA=(f1),
+  libB=(f2, f3),
+  libC=(f2, f4),
+  libD=(f2, f5),
+  libE=(f2, f6)]
+*/
+
+/*two-frag.library: 
+ output_units=[
+  f1: {units: [1{libA}], usedBy: [], needs: []},
+  f2: {units: [3{libB, libC, libD, libE}, 6{libE}], usedBy: [], needs: [3]},
+  f3: {units: [5{libD}, 4{libC}, 2{libB}], usedBy: [2], needs: []}],
+ steps=[
+  libA=(f1),
+  libB=(f2, f3),
+  libC=(f2, f3),
+  libD=(f2, f3),
+  libE=(f2)]
+*/
+
+/*three-frag.library: 
+ output_units=[
+  f1: {units: [1{libA}], usedBy: [], needs: []},
+  f2: {units: [3{libB, libC, libD, libE}], usedBy: [], needs: [3, 4]},
+  f3: {units: [4{libC}, 2{libB}], usedBy: [2], needs: []},
+  f4: {units: [6{libE}, 5{libD}], usedBy: [2], needs: []}],
+ steps=[
+  libA=(f1),
+  libB=(f2, f3),
+  libC=(f2, f3),
+  libD=(f2, f4),
+  libE=(f2, f4)]
+*/
+
+// @dart = 2.7
+
+import 'libA.dart' deferred as libA;
+import 'libB.dart' deferred as libB;
+import 'libC.dart' deferred as libC;
+import 'libD.dart' deferred as libD;
+import 'libE.dart' deferred as libE;
+
+/*member: main:member_unit=main{}*/
+main() async {
+  await libA.loadLibrary();
+  await libB.loadLibrary();
+  await libC.loadLibrary();
+  await libD.loadLibrary();
+  await libE.loadLibrary();
+
+  print(libA.component());
+  print(libB.component());
+  print(libC.component());
+  print(libD.component());
+  print(libE.component());
+}
diff --git a/pkg/compiler/test/deferred_loading/data/deferred_overlapping/main.dart b/pkg/compiler/test/deferred_loading/data/deferred_overlapping/main.dart
index d50cc23..154ad59 100644
--- a/pkg/compiler/test/deferred_loading/data/deferred_overlapping/main.dart
+++ b/pkg/compiler/test/deferred_loading/data/deferred_overlapping/main.dart
@@ -2,11 +2,21 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-/*library: 
+/*spec.library: 
  output_units=[
-  f1: {units: [1{lib1, lib2}], usedBy: [2, 3], needs: []},
-  f2: {units: [2{lib1}], usedBy: [], needs: [1]},
-  f3: {units: [3{lib2}], usedBy: [], needs: [1]}],
+  f1: {units: [1{lib1, lib2}], usedBy: [], needs: []},
+  f2: {units: [2{lib1}], usedBy: [], needs: []},
+  f3: {units: [3{lib2}], usedBy: [], needs: []}],
+ steps=[
+  lib1=(f1, f2),
+  lib2=(f1, f3)]
+*/
+
+/*two-frag|three-frag.library: 
+ output_units=[
+  f1: {units: [1{lib1, lib2}], usedBy: [], needs: [2, 3]},
+  f2: {units: [2{lib1}], usedBy: [1], needs: []},
+  f3: {units: [3{lib2}], usedBy: [1], needs: []}],
  steps=[
   lib1=(f1, f2),
   lib2=(f1, f3)]
@@ -21,9 +31,9 @@
 /*member: main:member_unit=main{}*/
 void main() {
   lib1.loadLibrary().then(/*closure_unit=main{}*/ (_) {
-    new lib1.C1();
+    print(new lib1.C1());
     lib2.loadLibrary().then(/*closure_unit=main{}*/ (_) {
-      new lib2.C2();
+      print(new lib2.C2());
     });
   });
 }
diff --git a/pkg/compiler/test/deferred_loading/data/dont_inline_deferred_constants/main.dart b/pkg/compiler/test/deferred_loading/data/dont_inline_deferred_constants/main.dart
index d65299a..db1d7a6 100644
--- a/pkg/compiler/test/deferred_loading/data/dont_inline_deferred_constants/main.dart
+++ b/pkg/compiler/test/deferred_loading/data/dont_inline_deferred_constants/main.dart
@@ -2,11 +2,21 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-/*spec|three-frag.library: 
+/*spec.library: 
  output_units=[
-  f1: {units: [2{lib1, lib2}], usedBy: [2, 3], needs: []},
-  f2: {units: [1{lib1}], usedBy: [], needs: [1]},
-  f3: {units: [3{lib2}], usedBy: [], needs: [1]}],
+  f1: {units: [2{lib1, lib2}], usedBy: [], needs: []},
+  f2: {units: [1{lib1}], usedBy: [], needs: []},
+  f3: {units: [3{lib2}], usedBy: [], needs: []}],
+ steps=[
+  lib1=(f1, f2),
+  lib2=(f1, f3)]
+*/
+
+/*three-frag.library: 
+ output_units=[
+  f1: {units: [2{lib1, lib2}], usedBy: [], needs: [2, 3]},
+  f2: {units: [1{lib1}], usedBy: [1], needs: []},
+  f3: {units: [3{lib2}], usedBy: [1], needs: []}],
  steps=[
   lib1=(f1, f2),
   lib2=(f1, f3)]
@@ -14,8 +24,8 @@
 
 /*two-frag.library: 
  output_units=[
-  f1: {units: [2{lib1, lib2}, 3{lib2}], usedBy: [2], needs: []},
-  f2: {units: [1{lib1}], usedBy: [], needs: [1]}],
+  f1: {units: [2{lib1, lib2}, 3{lib2}], usedBy: [], needs: [2]},
+  f2: {units: [1{lib1}], usedBy: [1], needs: []}],
  steps=[
   lib1=(f1, f2),
   lib2=(f1)]
diff --git a/pkg/compiler/test/deferred_loading/data/instantiation1/main.dart b/pkg/compiler/test/deferred_loading/data/instantiation1/main.dart
index ce14794..4642e97 100644
--- a/pkg/compiler/test/deferred_loading/data/instantiation1/main.dart
+++ b/pkg/compiler/test/deferred_loading/data/instantiation1/main.dart
@@ -2,11 +2,21 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-/*library: 
+/*spec.library: 
  output_units=[
-  f1: {units: [2{b, c}], usedBy: [2, 3], needs: []},
-  f2: {units: [1{b}], usedBy: [], needs: [1]},
-  f3: {units: [3{c}], usedBy: [], needs: [1]}],
+  f1: {units: [2{b, c}], usedBy: [], needs: []},
+  f2: {units: [1{b}], usedBy: [], needs: []},
+  f3: {units: [3{c}], usedBy: [], needs: []}],
+ steps=[
+  b=(f1, f2),
+  c=(f1, f3)]
+*/
+
+/*two-frag|three-frag.library: 
+ output_units=[
+  f1: {units: [2{b, c}], usedBy: [], needs: [2, 3]},
+  f2: {units: [1{b}], usedBy: [1], needs: []},
+  f3: {units: [3{c}], usedBy: [1], needs: []}],
  steps=[
   b=(f1, f2),
   c=(f1, f3)]
diff --git a/pkg/compiler/test/deferred_loading/data/instantiation2/main.dart b/pkg/compiler/test/deferred_loading/data/instantiation2/main.dart
index 0aba5e2..4f5bd68 100644
--- a/pkg/compiler/test/deferred_loading/data/instantiation2/main.dart
+++ b/pkg/compiler/test/deferred_loading/data/instantiation2/main.dart
@@ -2,11 +2,21 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-/*library: 
+/*spec.library: 
  output_units=[
-  f1: {units: [1{b, c}], usedBy: [2, 3], needs: []},
-  f2: {units: [2{b}], usedBy: [], needs: [1]},
-  f3: {units: [3{c}], usedBy: [], needs: [1]}],
+  f1: {units: [1{b, c}], usedBy: [], needs: []},
+  f2: {units: [2{b}], usedBy: [], needs: []},
+  f3: {units: [3{c}], usedBy: [], needs: []}],
+ steps=[
+  b=(f1, f2),
+  c=(f1, f3)]
+*/
+
+/*two-frag|three-frag.library: 
+ output_units=[
+  f1: {units: [1{b, c}], usedBy: [], needs: [2, 3]},
+  f2: {units: [2{b}], usedBy: [1], needs: []},
+  f3: {units: [3{c}], usedBy: [1], needs: []}],
  steps=[
   b=(f1, f2),
   c=(f1, f3)]
diff --git a/pkg/compiler/test/deferred_loading/data/instantiation4/main.dart b/pkg/compiler/test/deferred_loading/data/instantiation4/main.dart
index 1629521..f972fc5 100644
--- a/pkg/compiler/test/deferred_loading/data/instantiation4/main.dart
+++ b/pkg/compiler/test/deferred_loading/data/instantiation4/main.dart
@@ -2,11 +2,21 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-/*library: 
+/*spec.library: 
  output_units=[
-  f1: {units: [2{b, c}], usedBy: [2, 3], needs: []},
-  f2: {units: [1{b}], usedBy: [], needs: [1]},
-  f3: {units: [3{c}], usedBy: [], needs: [1]}],
+  f1: {units: [2{b, c}], usedBy: [], needs: []},
+  f2: {units: [1{b}], usedBy: [], needs: []},
+  f3: {units: [3{c}], usedBy: [], needs: []}],
+ steps=[
+  b=(f1, f2),
+  c=(f1, f3)]
+*/
+
+/*two-frag|three-frag.library: 
+ output_units=[
+  f1: {units: [2{b, c}], usedBy: [], needs: [2, 3]},
+  f2: {units: [1{b}], usedBy: [1], needs: []},
+  f3: {units: [3{c}], usedBy: [1], needs: []}],
  steps=[
   b=(f1, f2),
   c=(f1, f3)]
diff --git a/pkg/compiler/test/deferred_loading/data/instantiation5/main.dart b/pkg/compiler/test/deferred_loading/data/instantiation5/main.dart
index 768282f..f9dd67d 100644
--- a/pkg/compiler/test/deferred_loading/data/instantiation5/main.dart
+++ b/pkg/compiler/test/deferred_loading/data/instantiation5/main.dart
@@ -2,11 +2,21 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-/*library: 
+/*spec.library: 
  output_units=[
-  f1: {units: [1{b, c}], usedBy: [2, 3], needs: []},
-  f2: {units: [2{b}], usedBy: [], needs: [1]},
-  f3: {units: [3{c}], usedBy: [], needs: [1]}],
+  f1: {units: [1{b, c}], usedBy: [], needs: []},
+  f2: {units: [2{b}], usedBy: [], needs: []},
+  f3: {units: [3{c}], usedBy: [], needs: []}],
+ steps=[
+  b=(f1, f2),
+  c=(f1, f3)]
+*/
+
+/*two-frag|three-frag.library: 
+ output_units=[
+  f1: {units: [1{b, c}], usedBy: [], needs: [2, 3]},
+  f2: {units: [2{b}], usedBy: [1], needs: []},
+  f3: {units: [3{c}], usedBy: [1], needs: []}],
  steps=[
   b=(f1, f2),
   c=(f1, f3)]
diff --git a/pkg/compiler/test/deferred_loading/data/lazy_types/lib.dart b/pkg/compiler/test/deferred_loading/data/lazy_types/lib.dart
index 120b83c..22064c8 100644
--- a/pkg/compiler/test/deferred_loading/data/lazy_types/lib.dart
+++ b/pkg/compiler/test/deferred_loading/data/lazy_types/lib.dart
@@ -4,35 +4,30 @@
 
 // @dart = 2.7
 
-/*spec|three-frag.class: Foo:
+/*class: Foo:
  class_unit=1{libB},
  type_unit=3{libA, libB, libC}
 */
-/*two-frag.class: Foo:
- class_unit=1{libB, libA},
- type_unit=3{libA, libB, libC}
-*/
 class Foo {
-  /*spec|three-frag.member: Foo.x:member_unit=1{libB}*/
-  /*two-frag.member: Foo.x:member_unit=1{libB, libA}*/
+  /*member: Foo.x:member_unit=1{libB}*/
   int x;
-  /*spec|three-frag.member: Foo.:member_unit=1{libB}*/
-  /*two-frag.member: Foo.:member_unit=1{libB, libA}*/
+  /*member: Foo.:member_unit=1{libB}*/
   Foo() {
     x = DateTime.now().millisecond;
   }
-  /*spec|three-frag.member: Foo.method:member_unit=1{libB}*/
-  /*two-frag.member: Foo.method:member_unit=1{libB, libA}*/
+  /*member: Foo.method:member_unit=1{libB}*/
+  @pragma('dart2js:noInline')
   int method() => x;
 }
 
 /*member: isFoo:member_unit=3{libA, libB, libC}*/
+@pragma('dart2js:noInline')
 bool isFoo(o) {
   return o is Foo;
 }
 
-/*spec|three-frag.member: callFooMethod:member_unit=1{libB}*/
-/*two-frag.member: callFooMethod:member_unit=1{libB, libA}*/
+/*member: callFooMethod:member_unit=1{libB}*/
+@pragma('dart2js:noInline')
 int callFooMethod() {
   return Foo().method();
 }
@@ -41,6 +36,7 @@
 typedef int FunFunFoo(FunFoo b, int c);
 
 /*member: isFunFunFoo:member_unit=3{libA, libB, libC}*/
+@pragma('dart2js:noInline')
 bool isFunFunFoo(o) {
   return o is FunFunFoo;
 }
@@ -64,18 +60,15 @@
 /*member: Coo.:member_unit=2{libC}*/
 class Coo<T> {}
 
-/*spec|three-frag.class: Doo:
+/*class: Doo:
  class_unit=2{libC},
  type_unit=5{libB, libC}
 */
-/*two-frag.class: Doo:
- class_unit=2{libC},
- type_unit=5{libB, libC, libA}
-*/
 /*member: Doo.:member_unit=2{libC}*/
 class Doo<T> extends Coo<T> with Boo<T> {}
 
 /*member: createDooFunFunFoo:member_unit=2{libC}*/
+@pragma('dart2js:noInline')
 createDooFunFunFoo() => Doo<FunFunFoo>();
 
 /*class: B:
@@ -132,6 +125,7 @@
 class D3 = D2 with D1;
 
 /*member: isMega:member_unit=6{libA}*/
+@pragma('dart2js:noInline')
 bool isMega(o) {
   return o is B2 || o is C3 || o is D3;
 }
diff --git a/pkg/compiler/test/deferred_loading/data/lazy_types/libb.dart b/pkg/compiler/test/deferred_loading/data/lazy_types/libb.dart
index 7c98f96..20c2423 100644
--- a/pkg/compiler/test/deferred_loading/data/lazy_types/libb.dart
+++ b/pkg/compiler/test/deferred_loading/data/lazy_types/libb.dart
@@ -6,18 +6,14 @@
 
 import 'lib.dart' as lib;
 
-/*spec|three-frag.member: callFooMethod:member_unit=1{libB}*/
-/*two-frag.member: callFooMethod:member_unit=1{libB, libA}*/
+/*member: callFooMethod:member_unit=1{libB}*/
 int callFooMethod() => lib.callFooMethod();
 
-/*spec|three-frag.member: isFoo:member_unit=1{libB}*/
-/*two-frag.member: isFoo:member_unit=1{libB, libA}*/
+/*member: isFoo:member_unit=1{libB}*/
 bool isFoo(o) => lib.isFoo(o);
 
-/*spec|three-frag.member: isFunFunFoo:member_unit=1{libB}*/
-/*two-frag.member: isFunFunFoo:member_unit=1{libB, libA}*/
+/*member: isFunFunFoo:member_unit=1{libB}*/
 bool isFunFunFoo(o) => lib.isFunFunFoo(o);
 
-/*spec|three-frag.member: isDooFunFunFoo:member_unit=1{libB}*/
-/*two-frag.member: isDooFunFunFoo:member_unit=1{libB, libA}*/
+/*member: isDooFunFunFoo:member_unit=1{libB}*/
 bool isDooFunFunFoo(o) => o is lib.Doo<lib.FunFunFoo>;
diff --git a/pkg/compiler/test/deferred_loading/data/lazy_types/main.dart b/pkg/compiler/test/deferred_loading/data/lazy_types/main.dart
index 6e80197..ce78d8a 100644
--- a/pkg/compiler/test/deferred_loading/data/lazy_types/main.dart
+++ b/pkg/compiler/test/deferred_loading/data/lazy_types/main.dart
@@ -4,23 +4,21 @@
 
 /*spec.library: 
  output_units=[
-  f1: {units: [3{libA, libB, libC}], usedBy: [2, 4], needs: []},
-  f2: {units: [4{libA, libC}], usedBy: [3, 6], needs: [1, 4]},
-  f3: {units: [6{libA}], usedBy: [], needs: [2]},
-  f4: {units: [5{libB, libC}], usedBy: [5, 2], needs: [1]},
-  f5: {units: [1{libB}], usedBy: [], needs: [4]},
-  f6: {units: [2{libC}], usedBy: [], needs: [2]}],
+  f1: {units: [3{libA, libB, libC}], usedBy: [], needs: []},
+  f2: {units: [6{libA}], usedBy: [], needs: []},
+  f3: {units: [1{libB}], usedBy: [], needs: []},
+  f4: {units: [2{libC}], usedBy: [], needs: []}],
  steps=[
-  libA=(f1, f2, f3),
-  libB=(f1, f4, f5),
-  libC=(f1, f4, f2, f6)]
+  libA=(f1, f2),
+  libB=(f1, f3),
+  libC=(f1, f4)]
 */
 
 /*two-frag.library: 
  output_units=[
-  f1: {units: [3{libA, libB, libC}], usedBy: [2], needs: []},
-  f2: {units: [5{libB, libC, libA}, 4{libA, libC}, 2{libC}], usedBy: [3], needs: [1]},
-  f3: {units: [1{libB, libA}, 6{libA}], usedBy: [], needs: [2]}],
+  f1: {units: [3{libA, libB, libC}], usedBy: [], needs: [2]},
+  f2: {units: [5{libB, libC}, 4{libA, libC}, 2{libC}], usedBy: [1], needs: [3]},
+  f3: {units: [1{libB}, 6{libA}], usedBy: [2], needs: []}],
  steps=[
   libA=(f1, f2, f3),
   libB=(f1, f2, f3),
@@ -29,10 +27,10 @@
 
 /*three-frag.library: 
  output_units=[
-  f1: {units: [3{libA, libB, libC}, 5{libB, libC}, 4{libA, libC}], usedBy: [3, 2, 4], needs: []},
-  f2: {units: [6{libA}], usedBy: [], needs: [1]},
-  f3: {units: [1{libB}], usedBy: [], needs: [1]},
-  f4: {units: [2{libC}], usedBy: [], needs: [1]}],
+  f1: {units: [3{libA, libB, libC}, 5{libB, libC}, 4{libA, libC}], usedBy: [], needs: [4, 3, 2]},
+  f2: {units: [6{libA}], usedBy: [1], needs: []},
+  f3: {units: [1{libB}], usedBy: [1], needs: []},
+  f4: {units: [2{libC}], usedBy: [1], needs: []}],
  steps=[
   libA=(f1, f2),
   libB=(f1, f3),
@@ -45,7 +43,7 @@
 import 'libb.dart' deferred as libB;
 import 'libc.dart' deferred as libC;
 
-/*spec|three-frag.member: foo:
+/*member: foo:
  constants=[
   FunctionConstant(callFooMethod)=1{libB},
   FunctionConstant(createB2)=2{libC},
@@ -62,23 +60,6 @@
   FunctionConstant(isMega)=6{libA}],
  member_unit=main{}
 */
-/*two-frag.member: foo:
- constants=[
-  FunctionConstant(callFooMethod)=1{libB, libA},
-  FunctionConstant(createB2)=2{libC},
-  FunctionConstant(createC3)=2{libC},
-  FunctionConstant(createD3)=2{libC},
-  FunctionConstant(createDooFunFunFoo)=2{libC},
-  FunctionConstant(isDooFunFunFoo)=1{libB, libA},
-  FunctionConstant(isFoo)=1{libB, libA},
-  FunctionConstant(isFoo)=2{libC},
-  FunctionConstant(isFoo)=6{libA},
-  FunctionConstant(isFunFunFoo)=1{libB, libA},
-  FunctionConstant(isFunFunFoo)=2{libC},
-  FunctionConstant(isFunFunFoo)=6{libA},
-  FunctionConstant(isMega)=6{libA}],
- member_unit=main{}
-*/
 void foo() async {
   await libA.loadLibrary();
   await libB.loadLibrary();
diff --git a/pkg/compiler/test/deferred_loading/data/many_parts/libB.dart b/pkg/compiler/test/deferred_loading/data/many_parts/libB.dart
index 64e287e..7f86fc1 100644
--- a/pkg/compiler/test/deferred_loading/data/many_parts/libB.dart
+++ b/pkg/compiler/test/deferred_loading/data/many_parts/libB.dart
@@ -35,13 +35,11 @@
 f_010_11(Set<String> u, int b) => v(u, '01011', b);
 
 @pragma('dart2js:noInline')
-/*spec|three-frag.member: f_011_01:member_unit=8{b1, b3, b4}*/
-/*two-frag.member: f_011_01:member_unit=8{b1, b3, b4, b2, b5}*/
+/*member: f_011_01:member_unit=8{b1, b3, b4}*/
 f_011_01(Set<String> u, int b) => v(u, '01101', b);
 
 @pragma('dart2js:noInline')
-/*spec|two-frag.member: f_011_11:member_unit=9{b1, b2, b3, b4}*/
-/*three-frag.member: f_011_11:member_unit=9{b1, b2, b3, b4, b5}*/
+/*member: f_011_11:member_unit=9{b1, b2, b3, b4}*/
 f_011_11(Set<String> u, int b) => v(u, '01111', b);
 
 @pragma('dart2js:noInline')
@@ -105,8 +103,7 @@
 f_110_10(Set<String> u, int b) => v(u, '11010', b);
 
 @pragma('dart2js:noInline')
-/*spec.member: f_111_10:member_unit=24{b2, b3, b4, b5}*/
-/*two-frag|three-frag.member: f_111_10:member_unit=24{b2, b3, b4, b5, b1}*/
+/*member: f_111_10:member_unit=24{b2, b3, b4, b5}*/
 f_111_10(Set<String> u, int b) => v(u, '11110', b);
 
 @pragma('dart2js:noInline')
@@ -114,8 +111,7 @@
 f_001_00(Set<String> u, int b) => v(u, '00100', b);
 
 @pragma('dart2js:noInline')
-/*spec|two-frag.member: f_011_00:member_unit=26{b3, b4}*/
-/*three-frag.member: f_011_00:member_unit=26{b3, b4, b2, b5, b1}*/
+/*member: f_011_00:member_unit=26{b3, b4}*/
 f_011_00(Set<String> u, int b) => v(u, '01100', b);
 
 @pragma('dart2js:noInline')
diff --git a/pkg/compiler/test/deferred_loading/data/many_parts/main.dart b/pkg/compiler/test/deferred_loading/data/many_parts/main.dart
index 6f86ab9..6cd9224 100644
--- a/pkg/compiler/test/deferred_loading/data/many_parts/main.dart
+++ b/pkg/compiler/test/deferred_loading/data/many_parts/main.dart
@@ -4,37 +4,37 @@
 
 /*spec.library: 
  output_units=[
-  f10: {units: [7{b1, b2, b4}], usedBy: [11, 29], needs: [9, 8]},
-  f11: {units: [5{b1, b2, b3}], usedBy: [12, 21, 26], needs: [10, 8]},
-  f12: {units: [10{b1, b5}], usedBy: [13, 31], needs: [11, 21]},
-  f13: {units: [6{b1, b4}], usedBy: [14, 30], needs: [12, 22]},
-  f14: {units: [4{b1, b3}], usedBy: [15, 28], needs: [13, 23]},
-  f15: {units: [3{b1, b2}], usedBy: [16, 24], needs: [14, 23]},
-  f16: {units: [2{b1}], usedBy: [], needs: [15]},
-  f17: {units: [24{b2, b3, b4, b5}], usedBy: [3, 2], needs: [1]},
-  f18: {units: [23{b2, b4, b5}], usedBy: [19, 20], needs: [5, 25]},
-  f19: {units: [22{b2, b3, b5}], usedBy: [20, 6], needs: [18, 25]},
-  f1: {units: [1{b1, b2, b3, b4, b5}], usedBy: [2, 17], needs: []},
-  f20: {units: [20{b2, b3, b4}], usedBy: [9, 7, 6], needs: [19, 18]},
-  f21: {units: [21{b2, b5}], usedBy: [22, 12], needs: [11, 26]},
-  f22: {units: [19{b2, b4}], usedBy: [23, 13], needs: [21, 27]},
-  f23: {units: [18{b2, b3}], usedBy: [15, 14], needs: [22, 27]},
-  f24: {units: [17{b2}], usedBy: [], needs: [15]},
-  f25: {units: [28{b3, b4, b5}], usedBy: [19, 18], needs: [5, 4]},
-  f26: {units: [27{b3, b5}], usedBy: [27, 21], needs: [11, 29]},
-  f27: {units: [26{b3, b4}], usedBy: [23, 22], needs: [26, 29]},
-  f28: {units: [25{b3}], usedBy: [], needs: [14]},
-  f29: {units: [30{b4, b5}], usedBy: [27, 26], needs: [10, 9]},
-  f2: {units: [16{b1, b3, b4, b5}], usedBy: [3, 4], needs: [1, 17]},
-  f30: {units: [29{b4}], usedBy: [], needs: [13]},
-  f31: {units: [31{b5}], usedBy: [], needs: [12]},
-  f3: {units: [15{b1, b2, b4, b5}], usedBy: [4, 5], needs: [2, 17]},
-  f4: {units: [13{b1, b2, b3, b5}], usedBy: [5, 25], needs: [3, 2]},
-  f5: {units: [9{b1, b2, b3, b4}], usedBy: [6, 18, 25], needs: [4, 3]},
-  f6: {units: [14{b1, b4, b5}], usedBy: [7, 8], needs: [5, 20, 19]},
-  f7: {units: [12{b1, b3, b5}], usedBy: [8, 9], needs: [6, 20]},
-  f8: {units: [8{b1, b3, b4}], usedBy: [9, 11, 10], needs: [7, 6]},
-  f9: {units: [11{b1, b2, b5}], usedBy: [10, 29], needs: [8, 20, 7]}],
+  f10: {units: [7{b1, b2, b4}], usedBy: [], needs: []},
+  f11: {units: [5{b1, b2, b3}], usedBy: [], needs: []},
+  f12: {units: [10{b1, b5}], usedBy: [], needs: []},
+  f13: {units: [6{b1, b4}], usedBy: [], needs: []},
+  f14: {units: [4{b1, b3}], usedBy: [], needs: []},
+  f15: {units: [3{b1, b2}], usedBy: [], needs: []},
+  f16: {units: [2{b1}], usedBy: [], needs: []},
+  f17: {units: [24{b2, b3, b4, b5}], usedBy: [], needs: []},
+  f18: {units: [23{b2, b4, b5}], usedBy: [], needs: []},
+  f19: {units: [22{b2, b3, b5}], usedBy: [], needs: []},
+  f1: {units: [1{b1, b2, b3, b4, b5}], usedBy: [], needs: []},
+  f20: {units: [20{b2, b3, b4}], usedBy: [], needs: []},
+  f21: {units: [21{b2, b5}], usedBy: [], needs: []},
+  f22: {units: [19{b2, b4}], usedBy: [], needs: []},
+  f23: {units: [18{b2, b3}], usedBy: [], needs: []},
+  f24: {units: [17{b2}], usedBy: [], needs: []},
+  f25: {units: [28{b3, b4, b5}], usedBy: [], needs: []},
+  f26: {units: [27{b3, b5}], usedBy: [], needs: []},
+  f27: {units: [26{b3, b4}], usedBy: [], needs: []},
+  f28: {units: [25{b3}], usedBy: [], needs: []},
+  f29: {units: [30{b4, b5}], usedBy: [], needs: []},
+  f2: {units: [16{b1, b3, b4, b5}], usedBy: [], needs: []},
+  f30: {units: [29{b4}], usedBy: [], needs: []},
+  f31: {units: [31{b5}], usedBy: [], needs: []},
+  f3: {units: [15{b1, b2, b4, b5}], usedBy: [], needs: []},
+  f4: {units: [13{b1, b2, b3, b5}], usedBy: [], needs: []},
+  f5: {units: [9{b1, b2, b3, b4}], usedBy: [], needs: []},
+  f6: {units: [14{b1, b4, b5}], usedBy: [], needs: []},
+  f7: {units: [12{b1, b3, b5}], usedBy: [], needs: []},
+  f8: {units: [8{b1, b3, b4}], usedBy: [], needs: []},
+  f9: {units: [11{b1, b2, b5}], usedBy: [], needs: []}],
  steps=[
   b1=(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16),
   b2=(f1, f17, f3, f4, f5, f18, f19, f20, f9, f10, f11, f21, f22, f23, f15, f24),
@@ -45,10 +45,10 @@
 
 /*three-frag.library: 
  output_units=[
-  f1: {units: [1{b1, b2, b3, b4, b5}], usedBy: [2], needs: []},
-  f2: {units: [24{b2, b3, b4, b5, b1}, 16{b1, b3, b4, b5}, 15{b1, b2, b4, b5}, 13{b1, b2, b3, b5}], usedBy: [3], needs: [1]},
-  f3: {units: [9{b1, b2, b3, b4, b5}, 28{b3, b4, b5}, 23{b2, b4, b5}, 22{b2, b3, b5}, 20{b2, b3, b4}, 14{b1, b4, b5}, 12{b1, b3, b5}, 8{b1, b3, b4}, 11{b1, b2, b5}, 7{b1, b2, b4}, 5{b1, b2, b3}, 30{b4, b5}, 27{b3, b5}], usedBy: [4], needs: [2]},
-  f4: {units: [26{b3, b4, b2, b5, b1}, 21{b2, b5}, 19{b2, b4}, 18{b2, b3}, 10{b1, b5}, 6{b1, b4}, 4{b1, b3}, 3{b1, b2}, 31{b5}, 29{b4}, 25{b3}, 17{b2}, 2{b1}], usedBy: [], needs: [3]}],
+  f1: {units: [1{b1, b2, b3, b4, b5}], usedBy: [], needs: [3, 2]},
+  f2: {units: [24{b2, b3, b4, b5}, 16{b1, b3, b4, b5}, 15{b1, b2, b4, b5}, 13{b1, b2, b3, b5}], usedBy: [1], needs: [3]},
+  f3: {units: [9{b1, b2, b3, b4}, 28{b3, b4, b5}, 23{b2, b4, b5}, 22{b2, b3, b5}, 20{b2, b3, b4}, 14{b1, b4, b5}, 12{b1, b3, b5}, 8{b1, b3, b4}, 11{b1, b2, b5}, 7{b1, b2, b4}, 5{b1, b2, b3}, 30{b4, b5}, 27{b3, b5}], usedBy: [1, 2], needs: [4]},
+  f4: {units: [26{b3, b4}, 21{b2, b5}, 19{b2, b4}, 18{b2, b3}, 10{b1, b5}, 6{b1, b4}, 4{b1, b3}, 3{b1, b2}, 31{b5}, 29{b4}, 25{b3}, 17{b2}, 2{b1}], usedBy: [3], needs: []}],
  steps=[
   b1=(f1, f2, f3, f4),
   b2=(f1, f2, f3, f4),
@@ -59,9 +59,9 @@
 
 /*two-frag.library: 
  output_units=[
-  f1: {units: [1{b1, b2, b3, b4, b5}], usedBy: [2], needs: []},
-  f2: {units: [24{b2, b3, b4, b5, b1}, 16{b1, b3, b4, b5}, 15{b1, b2, b4, b5}, 13{b1, b2, b3, b5}, 9{b1, b2, b3, b4}, 28{b3, b4, b5}, 23{b2, b4, b5}, 22{b2, b3, b5}, 20{b2, b3, b4}, 14{b1, b4, b5}, 12{b1, b3, b5}], usedBy: [3], needs: [1]},
-  f3: {units: [8{b1, b3, b4, b2, b5}, 11{b1, b2, b5}, 7{b1, b2, b4}, 5{b1, b2, b3}, 30{b4, b5}, 27{b3, b5}, 26{b3, b4}, 21{b2, b5}, 19{b2, b4}, 18{b2, b3}, 10{b1, b5}, 6{b1, b4}, 4{b1, b3}, 3{b1, b2}, 31{b5}, 29{b4}, 25{b3}, 17{b2}, 2{b1}], usedBy: [], needs: [2]}],
+  f1: {units: [1{b1, b2, b3, b4, b5}], usedBy: [], needs: [2]},
+  f2: {units: [24{b2, b3, b4, b5}, 16{b1, b3, b4, b5}, 15{b1, b2, b4, b5}, 13{b1, b2, b3, b5}, 9{b1, b2, b3, b4}, 28{b3, b4, b5}, 23{b2, b4, b5}, 22{b2, b3, b5}, 20{b2, b3, b4}, 14{b1, b4, b5}, 12{b1, b3, b5}], usedBy: [1], needs: [3]},
+  f3: {units: [8{b1, b3, b4}, 11{b1, b2, b5}, 7{b1, b2, b4}, 5{b1, b2, b3}, 30{b4, b5}, 27{b3, b5}, 26{b3, b4}, 21{b2, b5}, 19{b2, b4}, 18{b2, b3}, 10{b1, b5}, 6{b1, b4}, 4{b1, b3}, 3{b1, b2}, 31{b5}, 29{b4}, 25{b3}, 17{b2}, 2{b1}], usedBy: [2], needs: []}],
  steps=[
   b1=(f1, f2, f3),
   b2=(f1, f2, f3),
diff --git a/pkg/compiler/test/deferred_loading/data/shadowed_types/lib_shared.dart b/pkg/compiler/test/deferred_loading/data/shadowed_types/lib_shared.dart
new file mode 100644
index 0000000..5b20db1
--- /dev/null
+++ b/pkg/compiler/test/deferred_loading/data/shadowed_types/lib_shared.dart
@@ -0,0 +1,45 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/*class: A:
+ class_unit=1{libb},
+ type_unit=2{libb, liba}
+*/
+/*member: A.:member_unit=1{libb}*/
+class A {}
+
+/*class: B:
+ class_unit=main{},
+ type_unit=main{}
+*/
+/*member: B.:member_unit=main{}*/
+class B {}
+
+/*class: C_Parent:
+ class_unit=1{libb},
+ type_unit=main{}
+*/
+/*member: C_Parent.:member_unit=1{libb}*/
+class C_Parent {}
+
+/*class: D:
+ class_unit=1{libb},
+ type_unit=2{libb, liba}
+*/
+/*member: D.:member_unit=1{libb}*/
+class D {}
+
+/*class: E:
+ class_unit=1{libb},
+ type_unit=1{libb}
+*/
+/*member: E.:member_unit=1{libb}*/
+class E extends D {}
+
+/*class: F:
+ class_unit=1{libb},
+ type_unit=1{libb}
+*/
+/*member: F.:member_unit=1{libb}*/
+class F {}
diff --git a/pkg/compiler/test/deferred_loading/data/shadowed_types/liba.dart b/pkg/compiler/test/deferred_loading/data/shadowed_types/liba.dart
new file mode 100644
index 0000000..4ea6fd2
--- /dev/null
+++ b/pkg/compiler/test/deferred_loading/data/shadowed_types/liba.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'lib_shared.dart';
+
+@pragma('dart2js:noInline')
+/*member: isA:member_unit=3{liba}*/
+isA(foo) {
+  return foo is A;
+}
+
+@pragma('dart2js:noInline')
+/*member: isD:member_unit=3{liba}*/
+isD(foo) {
+  return foo is D;
+}
diff --git a/pkg/compiler/test/deferred_loading/data/shadowed_types/libb.dart b/pkg/compiler/test/deferred_loading/data/shadowed_types/libb.dart
new file mode 100644
index 0000000..a5a125c
--- /dev/null
+++ b/pkg/compiler/test/deferred_loading/data/shadowed_types/libb.dart
@@ -0,0 +1,43 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'lib_shared.dart';
+
+@pragma('dart2js:noInline')
+/*member: createA:member_unit=1{libb}*/
+createA() {
+  return A();
+}
+
+@pragma('dart2js:noInline')
+/*member: isB:member_unit=1{libb}*/
+isB(foo) {
+  return foo is B;
+}
+
+/*class: C:
+ class_unit=1{libb},
+ type_unit=main{}
+*/
+/*member: C.:member_unit=1{libb}*/
+class C extends C_Parent {}
+
+@pragma('dart2js:noInline')
+/*member: createC:member_unit=1{libb}*/
+createC() {
+  return C();
+}
+
+@pragma('dart2js:noInline')
+/*member: createE:member_unit=1{libb}*/
+createE() {
+  return E();
+}
+
+@pragma('dart2js:noInline')
+/*member: isFWithUnused:member_unit=1{libb}*/
+isFWithUnused(foo) {
+  var unused = F();
+  return foo is F;
+}
diff --git a/pkg/compiler/test/deferred_loading/data/shadowed_types/main.dart b/pkg/compiler/test/deferred_loading/data/shadowed_types/main.dart
new file mode 100644
index 0000000..753bc7f
--- /dev/null
+++ b/pkg/compiler/test/deferred_loading/data/shadowed_types/main.dart
@@ -0,0 +1,31 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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: 
+ output_units=[
+  f1: {units: [3{liba}], usedBy: [], needs: []},
+  f2: {units: [1{libb}], usedBy: [], needs: []}],
+ steps=[
+  liba=(f1),
+  libb=(f2)]
+*/
+
+import 'liba.dart' deferred as liba;
+import 'libb.dart' deferred as libb;
+import 'lib_shared.dart';
+
+/*member: main:member_unit=main{}*/
+main() async {
+  var f = /*closure_unit=main{}*/ () => libb.C();
+  print(f is C_Parent Function());
+  await liba.loadLibrary();
+  await libb.loadLibrary();
+
+  print(liba.isA(libb.createA()));
+  print(libb.createA());
+  print(libb.createC());
+  print(libb.isB(B()));
+  print(liba.isD(libb.createE()));
+  print(libb.isFWithUnused(null as dynamic));
+}
diff --git a/pkg/compiler/test/deferred_loading/data/static_separate/main.dart b/pkg/compiler/test/deferred_loading/data/static_separate/main.dart
index 9c8dd2f..a4f5f5a 100644
--- a/pkg/compiler/test/deferred_loading/data/static_separate/main.dart
+++ b/pkg/compiler/test/deferred_loading/data/static_separate/main.dart
@@ -2,11 +2,21 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-/*library: 
+/*spec.library: 
  output_units=[
-  f1: {units: [2{lib1, lib2}], usedBy: [2, 3], needs: []},
-  f2: {units: [1{lib1}], usedBy: [], needs: [1]},
-  f3: {units: [3{lib2}], usedBy: [], needs: [1]}],
+  f1: {units: [2{lib1, lib2}], usedBy: [], needs: []},
+  f2: {units: [1{lib1}], usedBy: [], needs: []},
+  f3: {units: [3{lib2}], usedBy: [], needs: []}],
+ steps=[
+  lib1=(f1, f2),
+  lib2=(f1, f3)]
+*/
+
+/*two-frag|three-frag.library: 
+ output_units=[
+  f1: {units: [2{lib1, lib2}], usedBy: [], needs: [2, 3]},
+  f2: {units: [1{lib1}], usedBy: [1], needs: []},
+  f3: {units: [3{lib2}], usedBy: [1], needs: []}],
  steps=[
   lib1=(f1, f2),
   lib2=(f1, f3)]
diff --git a/pkg/compiler/test/deferred_loading/data/type_arguments/main.dart b/pkg/compiler/test/deferred_loading/data/type_arguments/main.dart
index 42fed69..9433a91 100644
--- a/pkg/compiler/test/deferred_loading/data/type_arguments/main.dart
+++ b/pkg/compiler/test/deferred_loading/data/type_arguments/main.dart
@@ -4,12 +4,11 @@
 
 /*library: 
  output_units=[
-  f1: {units: [3{lib1, lib3}], usedBy: [2, 3], needs: []},
-  f2: {units: [1{lib1}], usedBy: [], needs: [1]},
-  f3: {units: [2{lib3}], usedBy: [], needs: [1]}],
+  f1: {units: [1{lib1}], usedBy: [], needs: []},
+  f2: {units: [2{lib3}], usedBy: [], needs: []}],
  steps=[
-  lib1=(f1, f2),
-  lib3=(f1, f3)]
+  lib1=(f1),
+  lib3=(f2)]
 */
 
 // @dart = 2.7
diff --git a/pkg/compiler/test/deferred_loading/deferred_loading_test.dart b/pkg/compiler/test/deferred_loading/deferred_loading_test.dart
index e64d305..dcd98df 100644
--- a/pkg/compiler/test/deferred_loading/deferred_loading_test.dart
+++ b/pkg/compiler/test/deferred_loading/deferred_loading_test.dart
@@ -15,7 +15,6 @@
 import 'package:compiler/src/ir/util.dart';
 import 'package:compiler/src/js_model/element_map.dart';
 import 'package:compiler/src/js_model/js_world.dart';
-import 'package:compiler/src/js_emitter/model.dart';
 import 'package:compiler/src/js_emitter/startup_emitter/fragment_merger.dart';
 import 'package:compiler/src/kernel/kernel_strategy.dart';
 import 'package:expect/expect.dart';
@@ -87,23 +86,18 @@
 }
 
 Map<String, List<PreFragment>> buildPreFragmentMap(
-    Map<String, List<Fragment>> loadMap,
+    Map<String, List<FinalizedFragment>> fragmentsToLoad,
     List<PreFragment> preDeferredFragments) {
-  Map<DeferredFragment, PreFragment> fragmentMap = {};
+  Map<FinalizedFragment, PreFragment> fragmentMap = {};
   for (var preFragment in preDeferredFragments) {
-    for (var fragment in preFragment.fragments) {
-      assert(!fragmentMap.containsKey(fragment));
-      fragmentMap[fragment] = preFragment;
-    }
+    fragmentMap[preFragment.finalizedFragment] = preFragment;
   }
-
   Map<String, List<PreFragment>> preFragmentMap = {};
-  loadMap.forEach((loadId, fragments) {
-    Set<PreFragment> preFragments = {};
+  fragmentsToLoad.forEach((loadId, fragments) {
+    List<PreFragment> preFragments = [];
     for (var fragment in fragments) {
       preFragments.add(fragmentMap[fragment]);
     }
-    assert(!preFragmentMap.containsKey(loadId));
     preFragmentMap[loadId] = preFragments.toList();
   });
   return preFragmentMap;
@@ -160,11 +154,14 @@
     ir.Library node = frontendStrategy.elementMap.getLibraryNode(library);
     List<PreFragment> preDeferredFragments = compiler
         .backendStrategy.emitterTask.emitter.preDeferredFragmentsForTesting;
-    Program program =
-        compiler.backendStrategy.emitterTask.emitter.programForTesting;
+    Map<String, List<FinalizedFragment>> fragmentsToLoad =
+        compiler.backendStrategy.emitterTask.emitter.finalizedFragmentsToLoad;
+    Set<OutputUnit> omittedOutputUnits =
+        compiler.backendStrategy.emitterTask.emitter.omittedOutputUnits;
     Map<String, List<PreFragment>> preFragmentMap =
-        buildPreFragmentMap(program.loadMap, preDeferredFragments);
-    PreFragmentsIrComputer(compiler.reporter, actualMap, preFragmentMap)
+        buildPreFragmentMap(fragmentsToLoad, preDeferredFragments);
+    PreFragmentsIrComputer(
+            compiler.reporter, actualMap, preFragmentMap, omittedOutputUnits)
         .computeForLibrary(node);
   }
 
@@ -175,9 +172,13 @@
 
 class PreFragmentsIrComputer extends IrDataExtractor<Features> {
   final Map<String, List<PreFragment>> _preFragmentMap;
+  final Set<OutputUnit> _omittedOutputUnits;
 
-  PreFragmentsIrComputer(DiagnosticReporter reporter,
-      Map<Id, ActualData<Features>> actualMap, this._preFragmentMap)
+  PreFragmentsIrComputer(
+      DiagnosticReporter reporter,
+      Map<Id, ActualData<Features>> actualMap,
+      this._preFragmentMap,
+      this._omittedOutputUnits)
       : super(reporter, actualMap);
 
   @override
@@ -208,21 +209,28 @@
       List<OutputUnit> supplied = [];
       List<int> usedBy = [];
       for (var dependent in preFragment.successors) {
-        assert(preFragmentIndices.containsKey(dependent));
-        usedBy.add(preFragmentIndices[dependent]);
+        if (preFragmentIndices.containsKey(dependent)) {
+          usedBy.add(preFragmentIndices[dependent]);
+        }
       }
 
       for (var dependency in preFragment.predecessors) {
-        assert(preFragmentIndices.containsKey(dependency));
-        needs.add(preFragmentIndices[dependency]);
+        if (preFragmentIndices.containsKey(dependency)) {
+          needs.add(preFragmentIndices[dependency]);
+        }
       }
 
-      for (var fragment in preFragment.fragments) {
-        supplied.add(fragment.outputUnit);
+      for (var emittedOutputUnit in preFragment.emittedOutputUnits) {
+        var outputUnit = emittedOutputUnit.outputUnit;
+        if (!_omittedOutputUnits.contains(outputUnit)) {
+          supplied.add(outputUnit);
+        }
       }
-      var suppliedString = '[${supplied.map(outputUnitString).join(', ')}]';
-      features.addElement(Tags.outputUnits,
-          'f$i: {units: $suppliedString, usedBy: $usedBy, needs: $needs}');
+      if (supplied.isNotEmpty) {
+        var suppliedString = '[${supplied.map(outputUnitString).join(', ')}]';
+        features.addElement(Tags.outputUnits,
+            'f$i: {units: $suppliedString, usedBy: $usedBy, needs: $needs}');
+      }
     }
 
     return features;
diff --git a/pkg/compiler/test/equivalence/id_testing_test.dart b/pkg/compiler/test/equivalence/id_testing_test.dart
index ff453fe..5789c7c 100644
--- a/pkg/compiler/test/equivalence/id_testing_test.dart
+++ b/pkg/compiler/test/equivalence/id_testing_test.dart
@@ -5,7 +5,6 @@
 // @dart = 2.7
 
 import 'dart:io';
-import 'package:_fe_analyzer_shared/src/testing/id_testing.dart';
 import 'package:async_helper/async_helper.dart';
 import 'package:compiler/src/compiler.dart';
 import 'package:compiler/src/diagnostics/diagnostic_listener.dart';
diff --git a/pkg/compiler/test/helpers/compiler_helper.dart b/pkg/compiler/test/helpers/compiler_helper.dart
index a2ebf41..514b1ca 100644
--- a/pkg/compiler/test/helpers/compiler_helper.dart
+++ b/pkg/compiler/test/helpers/compiler_helper.dart
@@ -7,7 +7,6 @@
 library compiler_helper;
 
 import 'dart:async';
-import 'dart:io';
 import 'package:compiler/compiler_new.dart';
 import 'package:compiler/src/commandline_options.dart';
 import 'package:compiler/src/common_elements.dart';
@@ -18,7 +17,6 @@
 import 'package:expect/expect.dart';
 import 'package:_fe_analyzer_shared/src/util/link.dart' show Link;
 import 'memory_compiler.dart';
-import 'output_collector.dart';
 
 export 'package:compiler/src/diagnostics/messages.dart';
 export 'package:compiler/src/diagnostics/source_span.dart';
@@ -46,6 +44,7 @@
     bool disableInlining: true,
     bool disableTypeInference: true,
     bool omitImplicitChecks: true,
+    bool enableTripleShift: false, // TODO(30890): remove.
     bool enableVariance: false,
     void check(String generatedEntry),
     bool returnAll: false,
@@ -67,6 +66,9 @@
   if (disableInlining) {
     options.add(Flags.disableInlining);
   }
+  if (enableTripleShift) {
+    options.add('${Flags.enableLanguageExperiments}=triple-shift');
+  }
   if (enableVariance) {
     options.add('${Flags.enableLanguageExperiments}=variance');
   }
diff --git a/pkg/compiler/test/helpers/d8_helper.dart b/pkg/compiler/test/helpers/d8_helper.dart
index dae47ad..d02ff9e 100644
--- a/pkg/compiler/test/helpers/d8_helper.dart
+++ b/pkg/compiler/test/helpers/d8_helper.dart
@@ -11,7 +11,6 @@
 import 'dart:async';
 import 'dart:io';
 
-import 'package:compiler/compiler_new.dart';
 import 'package:compiler/src/common.dart';
 import 'package:compiler/src/dart2js.dart' as dart2js;
 import 'package:_fe_analyzer_shared/src/util/filenames.dart';
diff --git a/pkg/compiler/test/helpers/ir_types.dart b/pkg/compiler/test/helpers/ir_types.dart
index 2be57b7..b9745e5 100644
--- a/pkg/compiler/test/helpers/ir_types.dart
+++ b/pkg/compiler/test/helpers/ir_types.dart
@@ -98,6 +98,12 @@
   }
 
   @override
+  void visitExtensionType(ir.ExtensionType node, StringBuffer sb) {
+    sb.write(node.extension.name);
+    _writeTypeArguments(node.typeArguments, sb);
+  }
+
+  @override
   void visitFutureOrType(ir.FutureOrType node, StringBuffer sb) {
     sb.write('FutureOr<');
     writeType(node.typeArgument, sb);
diff --git a/pkg/compiler/test/inference/data/non_null.dart b/pkg/compiler/test/inference/data/non_null.dart
index d93cd29..96ee27e 100644
--- a/pkg/compiler/test/inference/data/non_null.dart
+++ b/pkg/compiler/test/inference/data/non_null.dart
@@ -46,8 +46,7 @@
   return new Class2(). /*invoke: [exact=Class2]*/ method();
 }
 
-// TODO(johnniwinther): We should infer that the returned value cannot be null.
-/*member: nonNullLocal:[null|exact=JSUInt31]*/
+/*member: nonNullLocal:[exact=JSUInt31]*/
 nonNullLocal() {
   var local = null;
   return local ??= 42;
diff --git a/pkg/compiler/test/inference/data/postfix.dart b/pkg/compiler/test/inference/data/postfix.dart
index 8059eac..67cf94f 100644
--- a/pkg/compiler/test/inference/data/postfix.dart
+++ b/pkg/compiler/test/inference/data/postfix.dart
@@ -26,7 +26,7 @@
   if (local == null) {
     local = 0;
   }
-  return local /*invoke: [null|exact=JSUInt31]*/ ++;
+  return local /*invoke: [exact=JSUInt31]*/ ++;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -39,7 +39,7 @@
   if (local == null) {
     local = 0;
   }
-  return local /*invoke: [null|exact=JSUInt31]*/ --;
+  return local /*invoke: [exact=JSUInt31]*/ --;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/pkg/compiler/test/inference/data/prefix.dart b/pkg/compiler/test/inference/data/prefix.dart
index bb1cfb1..a7302fc 100644
--- a/pkg/compiler/test/inference/data/prefix.dart
+++ b/pkg/compiler/test/inference/data/prefix.dart
@@ -26,7 +26,7 @@
   if (local == null) {
     local = 0;
   }
-  return /*invoke: [null|exact=JSUInt31]*/ ++local;
+  return /*invoke: [exact=JSUInt31]*/ ++local;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -39,7 +39,7 @@
   if (local == null) {
     local = 0;
   }
-  return /*invoke: [null|exact=JSUInt31]*/ --local;
+  return /*invoke: [exact=JSUInt31]*/ --local;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/pkg/compiler/test/inference/data/shift_right_unsigned.dart b/pkg/compiler/test/inference/data/shift_right_unsigned.dart
new file mode 100644
index 0000000..3518692
--- /dev/null
+++ b/pkg/compiler/test/inference/data/shift_right_unsigned.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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.13
+
+/*member: main:[null]*/
+main() {
+  g1 = -1;
+  g1 = 2;
+  test1();
+  test2();
+  test3();
+  test4();
+}
+
+/*member: g1:[subclass=JSInt]*/
+int g1 = 0;
+
+/*member: test1:[exact=JSUInt31]*/
+test1() {
+  int a = 1234;
+  int b = 2;
+  return a /*invoke: [exact=JSUInt31]*/>>> b;
+}
+
+/*member: test2:[subclass=JSUInt32]*/
+test2() {
+  return g1 /*invoke: [subclass=JSInt]*/>>> g1;
+}
+
+/*member: test3:[subclass=JSUInt32]*/
+test3() {
+  return g1 /*invoke: [subclass=JSInt]*/>>> 1;
+}
+
+/*member: test4:[exact=JSUInt31]*/
+test4() {
+  return 10 /*invoke: [exact=JSUInt31]*/>>> g1;
+}
diff --git a/pkg/compiler/test/inference/inference_test_helper.dart b/pkg/compiler/test/inference/inference_test_helper.dart
index d049559..b51b0e6 100644
--- a/pkg/compiler/test/inference/inference_test_helper.dart
+++ b/pkg/compiler/test/inference/inference_test_helper.dart
@@ -32,7 +32,7 @@
     await checkTests(dataDir, const TypeMaskDataComputer(),
         forUserLibrariesOnly: true,
         args: args,
-        options: [stopAfterTypeInference],
+        options: [stopAfterTypeInference, '--enable-experiment=triple-shift'],
         testedConfigs: allInternalConfigs,
         skip: skip,
         shardIndex: shardIndex ?? 0,
@@ -146,11 +146,23 @@
         node is ir.FunctionDeclaration) {
       ClosureRepresentationInfo info = _closureDataLookup.getClosureInfo(node);
       return getMemberValue(info.callMethod);
-    } else if (node is ir.MethodInvocation) {
+    } else if (node is ir.MethodInvocation ||
+        node is ir.InstanceInvocation ||
+        node is ir.InstanceGetterInvocation ||
+        node is ir.DynamicInvocation ||
+        node is ir.FunctionInvocation ||
+        node is ir.EqualsNull ||
+        node is ir.EqualsCall) {
       return getTypeMaskValue(result.typeOfReceiver(node));
-    } else if (node is ir.PropertyGet) {
+    } else if (node is ir.PropertyGet ||
+        node is ir.InstanceGet ||
+        node is ir.DynamicGet ||
+        node is ir.InstanceTearOff ||
+        node is ir.FunctionTearOff) {
       return getTypeMaskValue(result.typeOfReceiver(node));
-    } else if (node is ir.PropertySet) {
+    } else if (node is ir.PropertySet ||
+        node is ir.InstanceSet ||
+        node is ir.DynamicSet) {
       return getTypeMaskValue(result.typeOfReceiver(node));
     } else if (node is ir.ForInStatement) {
       if (id.kind == IdKind.iterator) {
diff --git a/pkg/compiler/test/jumps/jump_test.dart b/pkg/compiler/test/jumps/jump_test.dart
index b848bd7..e483cba 100644
--- a/pkg/compiler/test/jumps/jump_test.dart
+++ b/pkg/compiler/test/jumps/jump_test.dart
@@ -8,7 +8,6 @@
 import 'package:async_helper/async_helper.dart';
 import 'package:compiler/src/common.dart';
 import 'package:compiler/src/compiler.dart';
-import 'package:compiler/src/diagnostics/diagnostic_listener.dart';
 import 'package:compiler/src/elements/entities.dart';
 import 'package:compiler/src/elements/jumps.dart';
 import 'package:compiler/src/js_model/element_map.dart';
diff --git a/pkg/compiler/test/kernel/data/list_generate_2.dart.expect b/pkg/compiler/test/kernel/data/list_generate_2.dart.expect
index e2a2196..51e385e 100644
--- a/pkg/compiler/test/kernel/data/list_generate_2.dart.expect
+++ b/pkg/compiler/test/kernel/data/list_generate_2.dart.expect
@@ -13,7 +13,7 @@
         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.{_in::JSArray::[]=}{Invariant,BoundsSafe}(i, i.{core::num::+}(1){(core::num*) →* core::int*});
         }
       } =>_list);
     }
diff --git a/pkg/compiler/test/kernel/data/list_generate_3.dart.expect b/pkg/compiler/test/kernel/data/list_generate_3.dart.expect
index 05df05d..9a50e1e 100644
--- a/pkg/compiler/test/kernel/data/list_generate_3.dart.expect
+++ b/pkg/compiler/test/kernel/data/list_generate_3.dart.expect
@@ -34,9 +34,9 @@
   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);
+  if(i.{core::int::isEven}{core::bool*})
+    return i.{core::num::+}(1){(core::num*) →* core::int*};
+  return i.{core::num::-}(1){(core::num*) →* core::int*};
 });
 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);
diff --git a/pkg/compiler/test/model/cfe_constant_test.dart b/pkg/compiler/test/model/cfe_constant_test.dart
index 4ae3771..d9dfbf0 100644
--- a/pkg/compiler/test/model/cfe_constant_test.dart
+++ b/pkg/compiler/test/model/cfe_constant_test.dart
@@ -5,7 +5,6 @@
 // @dart = 2.7
 
 import 'dart:io';
-import 'package:_fe_analyzer_shared/src/testing/id_testing.dart';
 import 'package:async_helper/async_helper.dart';
 import 'package:compiler/src/compiler.dart';
 import 'package:compiler/src/diagnostics/diagnostic_listener.dart';
diff --git a/pkg/compiler/test/optimization/data/shift_right_unsigned.dart b/pkg/compiler/test/optimization/data/shift_right_unsigned.dart
new file mode 100644
index 0000000..6a8aaf3
--- /dev/null
+++ b/pkg/compiler/test/optimization/data/shift_right_unsigned.dart
@@ -0,0 +1,53 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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() {
+  shru1(1, 1);
+  shru1(2, 2);
+  shru1(-1, -1);
+
+  shruOtherInferredPositive(1, 1);
+  shruOtherInferredPositive(99, 99);
+  shruOtherInferredPositive(-1, 2);
+
+  shruSix(1);
+  shruSix(-1);
+
+  shruMaskedCount(1, 1);
+  shruMaskedCount(999, 999);
+  shruMaskedCount(-1, -2);
+
+  shruMaskedCount2(1, 1);
+  shruMaskedCount2(999, 999);
+  shruMaskedCount2(-1, -2);
+}
+
+@pragma('dart2js:noInline')
+shru1(a, b) {
+  return a >>> b;
+}
+
+@pragma('dart2js:noInline')
+/*member: shruOtherInferredPositive:Specializer=[ShiftRightUnsigned._shruOtherPositive]*/
+shruOtherInferredPositive(a, b) {
+  return a >>> b;
+}
+
+@pragma('dart2js:noInline')
+/*member: shruSix:Specializer=[ShiftRightUnsigned]*/
+shruSix(int a) {
+  return a >>> 6;
+}
+
+@pragma('dart2js:noInline')
+/*member: shruMaskedCount:Specializer=[BitAnd,ShiftRightUnsigned]*/
+shruMaskedCount(int a, int b) {
+  return a >>> (b & 31);
+}
+
+@pragma('dart2js:noInline')
+/*member: shruMaskedCount2:Specializer=[BitAnd,ShiftRightUnsigned._shruOtherPositive]*/
+shruMaskedCount2(int a, int b) {
+  return a >>> (b & 127);
+}
diff --git a/pkg/compiler/test/optimization/optimization_test.dart b/pkg/compiler/test/optimization/optimization_test.dart
index b5f2987..baf38d0 100644
--- a/pkg/compiler/test/optimization/optimization_test.dart
+++ b/pkg/compiler/test/optimization/optimization_test.dart
@@ -27,7 +27,8 @@
     Directory dataDir = new Directory.fromUri(Platform.script.resolve('data'));
     bool strict = args.contains('-s');
     await checkTests(dataDir, new OptimizationDataComputer(strict: strict),
-        options: [Flags.disableInlining], args: args);
+        options: [Flags.disableInlining, '--enable-experiment=triple-shift'],
+        args: args);
   });
 }
 
diff --git a/pkg/compiler/test/rti/data/instantiation1.dart b/pkg/compiler/test/rti/data/instantiation1.dart
index 8fbd5f3..c838bbe 100644
--- a/pkg/compiler/test/rti/data/instantiation1.dart
+++ b/pkg/compiler/test/rti/data/instantiation1.dart
@@ -10,7 +10,7 @@
 
 typedef int F<R>(R a);
 
-/*spec.class: B:explicit=[int* Function(B.S*)*],indirect,needsArgs*/
+/*spec.class: B:explicit=[int* Function(B.S*)*],implicit=[B.S],indirect,needsArgs*/
 class B<S> {
   F<S> c;
 
diff --git a/pkg/compiler/test/rti/data/instantiation2.dart b/pkg/compiler/test/rti/data/instantiation2.dart
index dbb5db8..934152a 100644
--- a/pkg/compiler/test/rti/data/instantiation2.dart
+++ b/pkg/compiler/test/rti/data/instantiation2.dart
@@ -9,8 +9,8 @@
 
 typedef bool F<R>(R a);
 
-/*spec.class: B:explicit=[bool* Function(B.S*)*],indirect,needsArgs*/
-/*prod.class: B:indirect,needsArgs*/
+/*spec.class: B:explicit=[bool* Function(B.S*)*],implicit=[B.S],indirect,needsArgs*/
+/*prod.class: B:implicit=[B.S],indirect,needsArgs*/
 class B<S> {
   F<S> c;
 
diff --git a/pkg/compiler/test/rti/data/instantiation3.dart b/pkg/compiler/test/rti/data/instantiation3.dart
index 96e7c7a..f852f9f 100644
--- a/pkg/compiler/test/rti/data/instantiation3.dart
+++ b/pkg/compiler/test/rti/data/instantiation3.dart
@@ -10,7 +10,7 @@
 
 typedef int F<R>(R a);
 
-/*spec.class: B:direct,explicit=[int* Function(B.S*)*],needsArgs*/
+/*spec.class: B:direct,explicit=[int* Function(B.S*)*],implicit=[B.S],needsArgs*/
 class B<S> {
   F<S> c;
 
diff --git a/pkg/compiler/test/rti/data/instantiation4.dart b/pkg/compiler/test/rti/data/instantiation4.dart
index 7ec0433..be3b975 100644
--- a/pkg/compiler/test/rti/data/instantiation4.dart
+++ b/pkg/compiler/test/rti/data/instantiation4.dart
@@ -9,8 +9,8 @@
 
 typedef bool F<R>(R a);
 
-/*spec.class: B:direct,explicit=[bool* Function(B.S*)*],needsArgs*/
-/*prod.class: B:indirect,needsArgs*/
+/*spec.class: B:direct,explicit=[bool* Function(B.S*)*],implicit=[B.S],needsArgs*/
+/*prod.class: B:implicit=[B.S],indirect,needsArgs*/
 class B<S> {
   F<S> c;
 
diff --git a/pkg/compiler/test/rti/data/instantiation5.dart b/pkg/compiler/test/rti/data/instantiation5.dart
index 80063c5..525be33 100644
--- a/pkg/compiler/test/rti/data/instantiation5.dart
+++ b/pkg/compiler/test/rti/data/instantiation5.dart
@@ -10,7 +10,7 @@
 
 typedef int F<R>(R a);
 
-/*spec.member: method:indirect,needsArgs*/
+/*spec.member: method:implicit=[method.S],indirect,needsArgs*/
 method<S>() {
   F<S> c;
 
diff --git a/pkg/compiler/test/rti/data/instantiation6.dart b/pkg/compiler/test/rti/data/instantiation6.dart
index fdfa1d2..e596af2 100644
--- a/pkg/compiler/test/rti/data/instantiation6.dart
+++ b/pkg/compiler/test/rti/data/instantiation6.dart
@@ -9,7 +9,7 @@
 
 typedef bool F<R>(R a);
 
-/*member: method:indirect,needsArgs*/
+/*member: method:implicit=[method.S],indirect,needsArgs*/
 method<S>() {
   F<S> c;
 
diff --git a/pkg/compiler/test/rti/data/instantiation7.dart b/pkg/compiler/test/rti/data/instantiation7.dart
index fda2e4a..a47924b 100644
--- a/pkg/compiler/test/rti/data/instantiation7.dart
+++ b/pkg/compiler/test/rti/data/instantiation7.dart
@@ -20,7 +20,7 @@
 typedef int F2<R, P>(R a, P b, P c);
 typedef int F3<R, P, Q>(R a, P b, Q c);
 
-/*spec.member: method:indirect,needsArgs*/
+/*spec.member: method:implicit=[method.X,method.Y,method.Z],indirect,needsArgs*/
 method<X, Y, Z>() {
   F1<X> c1;
   F2<X, Y> c2;
diff --git a/pkg/compiler/test/rti/data/local_function_signatures_generic.dart b/pkg/compiler/test/rti/data/local_function_signatures_generic.dart
index dc86b33..7956fe4 100644
--- a/pkg/compiler/test/rti/data/local_function_signatures_generic.dart
+++ b/pkg/compiler/test/rti/data/local_function_signatures_generic.dart
@@ -89,8 +89,8 @@
 }
 
 method12() {
-  /*spec.direct,explicit=[local.T*],needsArgs,needsInst=[<dynamic>,<num*>,<num*>],needsSignature*/
-  /*prod.needsArgs,needsInst=[<dynamic>,<num*>,<num*>],needsSignature*/num local<T>(num n, T t) => null;
+  /*spec.direct,explicit=[local.T*],needsArgs,needsSignature*/
+  /*prod.needsArgs,needsSignature*/num local<T>(num n, T t) => null;
   return local;
 }
 
diff --git a/pkg/compiler/test/rti/data/map_to_set.dart b/pkg/compiler/test/rti/data/map_to_set.dart
index 90e9586..0555c1e 100644
--- a/pkg/compiler/test/rti/data/map_to_set.dart
+++ b/pkg/compiler/test/rti/data/map_to_set.dart
@@ -7,7 +7,7 @@
 /*prod.class: global#Map:deps=[Class],needsArgs*/
 /*spec.class: global#Map:deps=[Class],explicit=[Map,Map<Object?,Object?>],indirect,needsArgs*/
 
-/*prod.class: global#LinkedHashMap:deps=[Map],needsArgs*/
+/*prod.class: global#LinkedHashMap:deps=[Map],implicit=[LinkedHashMap.K],needsArgs*/
 /*spec.class: global#LinkedHashMap:deps=[Map],direct,explicit=[LinkedHashMap<LinkedHashMap.K,LinkedHashMap.V>],implicit=[LinkedHashMap.K,LinkedHashMap.V],needsArgs*/
 
 /*prod.class: global#JsLinkedHashMap:deps=[LinkedHashMap],implicit=[JsLinkedHashMap.K],needsArgs*/
diff --git a/pkg/compiler/test/rti/data/method_signatures_generic.dart b/pkg/compiler/test/rti/data/method_signatures_generic.dart
index b3866f8..0d2c352 100644
--- a/pkg/compiler/test/rti/data/method_signatures_generic.dart
+++ b/pkg/compiler/test/rti/data/method_signatures_generic.dart
@@ -28,7 +28,7 @@
 }
 
 class Class4 {
-  /*spec.member: Class4.method6:direct,explicit=[method6.T*],needsArgs,needsInst=[<num*>,<num*>,<num*>,<num*>]*/
+  /*spec.member: Class4.method6:direct,explicit=[method6.T*],needsArgs*/
   num method6<T>(num n, T t) => null;
 }
 
@@ -38,7 +38,7 @@
 /*member: method8:*/
 T method8<T>(num n) => null;
 
-/*spec.member: method9:direct,explicit=[method9.T*],needsArgs,needsInst=[<num*>,<num*>,<num*>,<num*>]*/
+/*spec.member: method9:direct,explicit=[method9.T*],needsArgs*/
 num method9<T>(num n, T t) => null;
 
 @pragma('dart2js:noInline')
diff --git a/pkg/compiler/test/rti/emission/event_callback.dart b/pkg/compiler/test/rti/emission/event_callback.dart
index e6b2bc2..5e77e38 100644
--- a/pkg/compiler/test/rti/emission/event_callback.dart
+++ b/pkg/compiler/test/rti/emission/event_callback.dart
@@ -8,8 +8,10 @@
 
 /*spec.class: global#Event:checkedInstance,checkedTypeArgument,checks=[$isEvent],instance,typeArgument*/
 /*prod.class: global#Event:checkedTypeArgument,checks=[$isEvent],instance,typeArgument*/
-/*class: global#MouseEvent:checks=[$isMouseEvent],instance,typeArgument*/
-/*class: global#KeyboardEvent:checks=[$isKeyboardEvent],instance,typeArgument*/
+/*spec.class: global#MouseEvent:checkedInstance,checks=[$isMouseEvent],instance,typeArgument*/
+/*prod.class: global#MouseEvent:checks=[$isMouseEvent],instance,typeArgument*/
+/*spec.class: global#KeyboardEvent:checkedInstance,checks=[$isKeyboardEvent],instance,typeArgument*/
+/*prod.class: global#KeyboardEvent:checks=[$isKeyboardEvent],instance,typeArgument*/
 
 void main() {
   print('InputElement');
diff --git a/pkg/compiler/test/rti/rti_need_test_helper.dart b/pkg/compiler/test/rti/rti_need_test_helper.dart
index 4170976..4206006 100644
--- a/pkg/compiler/test/rti/rti_need_test_helper.dart
+++ b/pkg/compiler/test/rti/rti_need_test_helper.dart
@@ -160,12 +160,11 @@
             features.addElement(Tags.selectors, selector);
           }
         });
-        rtiNeedBuilder.instantiationsNeedingTypeArgumentsForTesting?.forEach(
-            (GenericInstantiation instantiation, Set<Entity> targets) {
-          if (targets.contains(entity)) {
-            features.addElement(
-                Tags.instantiationsNeedTypeArguments, instantiation.shortText);
-          }
+        rtiNeedBuilder
+            .instantiatedEntitiesNeedingTypeArgumentsForTesting[entity]
+            ?.forEach((GenericInstantiation instantiation) {
+          features.addElement(
+              Tags.instantiationsNeedTypeArguments, instantiation.shortText);
         });
       }
 
diff --git a/pkg/compiler/test/serialization/on_disk_split_test.dart b/pkg/compiler/test/serialization/on_disk_split_test.dart
index 00ce798..22cedb1 100644
--- a/pkg/compiler/test/serialization/on_disk_split_test.dart
+++ b/pkg/compiler/test/serialization/on_disk_split_test.dart
@@ -17,17 +17,19 @@
     Uri dillUri = dir.uri.resolve('out.dill');
     Uri outUri = dir.uri.resolve('out.js');
     var commonArgs = [
-      Flags.writeData,
       Flags.verbose,
       '--libraries-spec=$sdkLibrariesSpecificationUri',
     ];
     await internalMain([
           'samples-dev/swarm/swarm.dart',
+          Flags.writeClosedWorld,
           '--out=${dillUri}',
         ] +
         commonArgs);
     await internalMain([
           '${dillUri}',
+          Flags.readClosedWorld,
+          Flags.writeData,
           '--out=${outUri}',
         ] +
         commonArgs);
diff --git a/pkg/compiler/test/serialization/serialization_test_helper.dart b/pkg/compiler/test/serialization/serialization_test_helper.dart
index b429960..b7b771c 100644
--- a/pkg/compiler/test/serialization/serialization_test_helper.dart
+++ b/pkg/compiler/test/serialization/serialization_test_helper.dart
@@ -184,7 +184,8 @@
 GlobalTypeInferenceResults cloneInferenceResults(Compiler compiler,
     GlobalTypeInferenceResults results, SerializationStrategy strategy) {
   List<int> irData = strategy.unpackAndSerializeComponent(results);
-
+  List<int> closedWorldData =
+      strategy.serializeClosedWorld(results.closedWorld);
   List<int> worldData = strategy.serializeGlobalTypeInferenceResults(results);
   print('data size: ${worldData.length}');
 
@@ -196,6 +197,7 @@
           compiler.environment,
           compiler.abstractValueStrategy,
           newComponent,
+          closedWorldData,
           worldData);
   List<int> newWorldData =
       strategy.serializeGlobalTypeInferenceResults(newResults);
diff --git a/pkg/compiler/test/sourcemaps/helpers/sourcemap_helper.dart b/pkg/compiler/test/sourcemaps/helpers/sourcemap_helper.dart
index f5e0509..cc8df9a 100644
--- a/pkg/compiler/test/sourcemaps/helpers/sourcemap_helper.dart
+++ b/pkg/compiler/test/sourcemaps/helpers/sourcemap_helper.dart
@@ -22,7 +22,6 @@
 import 'package:compiler/src/js_model/js_strategy.dart';
 import 'package:compiler/src/source_file_provider.dart';
 import '../../helpers/memory_compiler.dart';
-import '../../helpers/output_collector.dart';
 
 class SourceFileSink implements OutputSink {
   final String filename;
diff --git a/pkg/compiler/test/sourcemaps/stacktrace/extension_method.dart b/pkg/compiler/test/sourcemaps/stacktrace/extension_method.dart
index 0f6432d..5c8302a 100644
--- a/pkg/compiler/test/sourcemaps/stacktrace/extension_method.dart
+++ b/pkg/compiler/test/sourcemaps/stacktrace/extension_method.dart
@@ -1,7 +1,8 @@
+// @dart = 2.7
+
 class MyClass {
   MyClass();
 
-// @dart = 2.7
   @pragma('dart2js:noInline')
   set internalSetter(int v) {
     /*7:MyClass.internalSetter*/ throw "error";
diff --git a/pkg/compiler/test/sourcemaps/stacktrace_test.dart b/pkg/compiler/test/sourcemaps/stacktrace_test.dart
index 6785cc0..7468227 100644
--- a/pkg/compiler/test/sourcemaps/stacktrace_test.dart
+++ b/pkg/compiler/test/sourcemaps/stacktrace_test.dart
@@ -9,7 +9,6 @@
 
 import 'package:args/args.dart';
 import 'package:async_helper/async_helper.dart';
-import 'package:compiler/compiler_new.dart';
 import 'package:compiler/src/commandline_options.dart';
 import 'package:compiler/src/dart2js.dart' as entry;
 
diff --git a/pkg/compiler/test/sourcemaps/stepping_test.dart b/pkg/compiler/test/sourcemaps/stepping_test.dart
index 28712e6..c6a0504 100644
--- a/pkg/compiler/test/sourcemaps/stepping_test.dart
+++ b/pkg/compiler/test/sourcemaps/stepping_test.dart
@@ -10,7 +10,6 @@
 import 'package:_fe_analyzer_shared/src/testing/annotated_code_helper.dart';
 import 'package:args/args.dart';
 import 'package:async_helper/async_helper.dart';
-import 'package:compiler/compiler_new.dart';
 import 'package:compiler/src/commandline_options.dart';
 import 'package:compiler/src/dart2js.dart' as entry;
 import 'package:expect/expect.dart';
diff --git a/pkg/compiler/test/static_type/data/effectively_final_access.dart b/pkg/compiler/test/static_type/data/effectively_final_access.dart
new file mode 100644
index 0000000..352b77c
--- /dev/null
+++ b/pkg/compiler/test/static_type/data/effectively_final_access.dart
@@ -0,0 +1,56 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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
+
+main() {
+  effectivelyFinalFunctionTyped();
+  effectivelyFinalGenericFunctionTyped(null);
+  effectivelyFinalDynamicallyTyped();
+  effectivelyFinalPartiallyTyped();
+}
+
+effectivelyFinalFunctionTyped() {
+  Function f = (int i) => /*spec.int*/ i;
+  /*spec.int Function(int)*/ f
+      . /*spec.invoke: [int Function(int)]->int*/ call(0);
+  (/*spec.int Function(int)*/ f.call)
+      /*spec.invoke: [int Function(int)]->int*/ (0);
+}
+
+effectivelyFinalGenericFunctionTyped(T Function<T>(T) g) {
+  Function f = /*spec.T Function<T extends Object>(T)*/ g;
+  /*spec.T Function<T extends Object>(T)*/ f
+      . /*spec.invoke: [T Function<T extends Object>(T)]->int*/ call<int>(0);
+  (/*spec.T Function<T extends Object>(T)*/ f.call)
+      .
+      /*spec.invoke: [T Function<T extends Object>(T)]->int*/
+      call<int>(0);
+}
+
+effectivelyFinalDynamicallyTyped() {
+  dynamic list = <int>[0];
+  /*spec.List<int>*/ list.first /*spec.invoke: [int]->int*/ + 0;
+  /*spec.List<int>*/ list /*spec.[List<int>]->int*/
+          [0] /*spec.invoke: [int]->int*/ +
+      0;
+  (/*spec.List<int>*/ list.contains)
+      /*spec.invoke: [bool Function(Object)]->bool*/ (0);
+  /*spec.List<int>*/ list
+      /*spec.update: [List<int>]->void*/ /*spec.[List<int>]->int*/
+      [0] /*spec.invoke: [int]->int*/ ++;
+}
+
+effectivelyFinalPartiallyTyped() {
+  List list = <int>[0];
+  /*spec.List<int>*/ list.first /*spec.invoke: [int]->int*/ + 0;
+  /*spec.List<int>*/ list /*spec.[List<int>]->int*/
+          [0] /*spec.invoke: [int]->int*/ +
+      0;
+  (/*spec.List<int>*/ list.contains)
+      /*spec.invoke: [bool Function(Object)]->bool*/ (0);
+  /*spec.List<int>*/ list
+      /*spec.update: [List<int>]->void*/ /*spec.[List<int>]->int*/
+      [0] /*spec.invoke: [int]->int*/ ++;
+}
diff --git a/pkg/compiler/test/static_type/static_type_test.dart b/pkg/compiler/test/static_type/static_type_test.dart
index 220b990..fca7c8a 100644
--- a/pkg/compiler/test/static_type/static_type_test.dart
+++ b/pkg/compiler/test/static_type/static_type_test.dart
@@ -89,6 +89,29 @@
     } else if (node is ir.MethodInvocation) {
       return '[${typeToText(node.receiver.accept(staticTypeCache))}]->'
           '${typeToText(node.accept(staticTypeCache))}';
+    } else if (node is ir.InstanceInvocation) {
+      return '[${typeToText(node.receiver.accept(staticTypeCache))}]->'
+          '${typeToText(node.accept(staticTypeCache))}';
+    } else if (node is ir.InstanceGetterInvocation) {
+      return '[${typeToText(node.receiver.accept(staticTypeCache))}]->'
+          '${typeToText(node.accept(staticTypeCache))}';
+    } else if (node is ir.DynamicInvocation) {
+      return '[${typeToText(node.receiver.accept(staticTypeCache))}]->'
+          '${typeToText(node.accept(staticTypeCache))}';
+    } else if (node is ir.FunctionInvocation) {
+      return '[${typeToText(node.receiver.accept(staticTypeCache))}]->'
+          '${typeToText(node.accept(staticTypeCache))}';
+    } else if (node is ir.LocalFunctionInvocation) {
+      return '[${typeToText(node.variable.type)}]->'
+          '${typeToText(node.accept(staticTypeCache))}';
+    } else if (node is ir.EqualsCall) {
+      return '[${typeToText(node.left.accept(staticTypeCache))}]->'
+          '${typeToText(node.accept(staticTypeCache))}';
+    } else if (node is ir.EqualsNull) {
+      // TODO(johnniwinther): Remove this after the new method invocation has
+      // landed stably. This is only included to make the transition a no-op.
+      return '[${typeToText(node.expression.accept(staticTypeCache))}]->'
+          '${typeToText(node.accept(staticTypeCache))}';
     }
     return null;
   }
diff --git a/pkg/compiler/test/static_type/type_promotion_data/equals.dart b/pkg/compiler/test/static_type/type_promotion_data/equals.dart
index cd6ec3c..2438e4d 100644
--- a/pkg/compiler/test/static_type/type_promotion_data/equals.dart
+++ b/pkg/compiler/test/static_type/type_promotion_data/equals.dart
@@ -53,7 +53,7 @@
     if (
         /*{e1:[{true:Iterable<dynamic>,false:Set<dynamic>,Map<dynamic,dynamic>}|Set<dynamic>,Map<dynamic,dynamic>,Iterable<dynamic>]}*/
         e1 is List !=
-            /*{e1:[{true:Iterable<dynamic>,false:Set<dynamic>,Map<dynamic,dynamic>}|Set<dynamic>,Map<dynamic,dynamic>,Iterable<dynamic>]}*/
+            /*{e1:[{true:Iterable<dynamic>,false:Set<dynamic>,Map<dynamic,dynamic>}|Iterable<dynamic>,Set<dynamic>,Map<dynamic,dynamic>]}*/
             e2 is List) {
       return
           /*{e1:[{true:Iterable<dynamic>,false:Set<dynamic>,Map<dynamic,dynamic>}|Iterable<dynamic>,Set<dynamic>,Map<dynamic,dynamic>]}*/
diff --git a/pkg/compiler/test/tool/graph_isomorphizer/golden/less_simple/lib1.dart b/pkg/compiler/test/tool/graph_isomorphizer/golden/less_simple/lib1.dart
new file mode 100644
index 0000000..5f3aa4b
--- /dev/null
+++ b/pkg/compiler/test/tool/graph_isomorphizer/golden/less_simple/lib1.dart
@@ -0,0 +1,11 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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 was autogenerated by the pkg/compiler/tool/graph_isomorphizer.dart.
+import 'lib_100_0.dart' deferred as b1;
+
+entryLib1() async {
+  await b1.loadLibrary();
+  b1.g_100_0();
+}
diff --git a/pkg/compiler/test/tool/graph_isomorphizer/golden/less_simple/lib2.dart b/pkg/compiler/test/tool/graph_isomorphizer/golden/less_simple/lib2.dart
new file mode 100644
index 0000000..20313e2
--- /dev/null
+++ b/pkg/compiler/test/tool/graph_isomorphizer/golden/less_simple/lib2.dart
@@ -0,0 +1,11 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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 was autogenerated by the pkg/compiler/tool/graph_isomorphizer.dart.
+import 'lib_010_0.dart' deferred as b2;
+
+entryLib2() async {
+  await b2.loadLibrary();
+  b2.g_010_0();
+}
diff --git a/pkg/compiler/test/tool/graph_isomorphizer/golden/less_simple/lib3.dart b/pkg/compiler/test/tool/graph_isomorphizer/golden/less_simple/lib3.dart
new file mode 100644
index 0000000..feeeeff
--- /dev/null
+++ b/pkg/compiler/test/tool/graph_isomorphizer/golden/less_simple/lib3.dart
@@ -0,0 +1,11 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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 was autogenerated by the pkg/compiler/tool/graph_isomorphizer.dart.
+import 'lib_001_0.dart' deferred as b3;
+
+entryLib3() async {
+  await b3.loadLibrary();
+  b3.g_001_0();
+}
diff --git a/pkg/compiler/test/tool/graph_isomorphizer/golden/less_simple/lib4.dart b/pkg/compiler/test/tool/graph_isomorphizer/golden/less_simple/lib4.dart
new file mode 100644
index 0000000..fbbe564
--- /dev/null
+++ b/pkg/compiler/test/tool/graph_isomorphizer/golden/less_simple/lib4.dart
@@ -0,0 +1,11 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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 was autogenerated by the pkg/compiler/tool/graph_isomorphizer.dart.
+import 'lib_000_1.dart' deferred as b4;
+
+entryLib4() async {
+  await b4.loadLibrary();
+  b4.g_000_1();
+}
diff --git a/pkg/compiler/test/tool/graph_isomorphizer/golden/less_simple/libImport.dart b/pkg/compiler/test/tool/graph_isomorphizer/golden/less_simple/libImport.dart
new file mode 100644
index 0000000..4a2d52a
--- /dev/null
+++ b/pkg/compiler/test/tool/graph_isomorphizer/golden/less_simple/libImport.dart
@@ -0,0 +1,878 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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 was autogenerated by the pkg/compiler/tool/graph_isomorphizer.dart.
+import "package:expect/expect.dart";
+
+void v(Set<String> u, String name, int bit) {
+  Expect.isTrue(u.add(name));
+  Expect.equals(name[bit], '1');
+}
+
+class C_100_0 {
+  const C_100_0();
+}
+
+class M_100_0 {}
+
+class T_100_0 {}
+
+const C_100_0 iC_100_0 = const C_100_0();
+closureC_100_0(foo) =>
+    (C_100_0 unused) => iC_100_0.toString() == foo.toString();
+
+class C_110_0 {
+  const C_110_0();
+}
+
+class M_110_0 {}
+
+class T_110_0 {}
+
+const C_110_0 iC_110_0 = const C_110_0();
+closureC_110_0(foo) =>
+    (C_110_0 unused) => iC_110_0.toString() == foo.toString();
+
+class C_101_1 {
+  const C_101_1();
+}
+
+class M_101_1 {}
+
+class T_101_1 {}
+
+const C_101_1 iC_101_1 = const C_101_1();
+closureC_101_1(foo) =>
+    (C_101_1 unused) => iC_101_1.toString() == foo.toString();
+
+class C_111_1 {
+  const C_111_1();
+}
+
+class M_111_1 {}
+
+class T_111_1 {}
+
+const C_111_1 iC_111_1 = const C_111_1();
+closureC_111_1(foo) =>
+    (C_111_1 unused) => iC_111_1.toString() == foo.toString();
+
+class C_010_0 {
+  const C_010_0();
+}
+
+class M_010_0 {}
+
+class T_010_0 {}
+
+const C_010_0 iC_010_0 = const C_010_0();
+closureC_010_0(foo) =>
+    (C_010_0 unused) => iC_010_0.toString() == foo.toString();
+
+class C_010_1 {
+  const C_010_1();
+}
+
+class M_010_1 {}
+
+class T_010_1 {}
+
+const C_010_1 iC_010_1 = const C_010_1();
+closureC_010_1(foo) =>
+    (C_010_1 unused) => iC_010_1.toString() == foo.toString();
+
+class C_011_1 {
+  const C_011_1();
+}
+
+class M_011_1 {}
+
+class T_011_1 {}
+
+const C_011_1 iC_011_1 = const C_011_1();
+closureC_011_1(foo) =>
+    (C_011_1 unused) => iC_011_1.toString() == foo.toString();
+
+class C_001_0 {
+  const C_001_0();
+}
+
+class M_001_0 {}
+
+class T_001_0 {}
+
+const C_001_0 iC_001_0 = const C_001_0();
+closureC_001_0(foo) =>
+    (C_001_0 unused) => iC_001_0.toString() == foo.toString();
+
+class C_000_1 {
+  const C_000_1();
+}
+
+class M_000_1 {}
+
+class T_000_1 {}
+
+const C_000_1 iC_000_1 = const C_000_1();
+closureC_000_1(foo) =>
+    (C_000_1 unused) => iC_000_1.toString() == foo.toString();
+
+class C_110_0_class_1 extends C_100_0
+    with M_100_0, M_110_0, M_101_1, M_111_1, M_010_0, M_010_1, M_011_1
+    implements C_110_0, C_101_1, C_111_1, C_010_0, C_010_1, C_011_1 {
+  const C_110_0_class_1();
+}
+
+const C_110_0_class_1 iC_110_0_class_1 = const C_110_0_class_1();
+closureC_110_0_class_1(foo) =>
+    (C_110_0_class_1 unused) => iC_110_0_class_1.toString() == foo.toString();
+
+class T_110_0_type__1 extends T_100_0
+    with M_100_0, M_110_0, M_101_1, M_111_1, M_010_0, M_010_1, M_011_1
+    implements T_110_0, T_101_1, T_111_1, T_010_0, T_010_1, T_011_1 {}
+
+class C_110_0_class_2 extends C_110_0
+    with M_100_0, M_110_0, M_101_1, M_111_1, M_010_0, M_010_1, M_011_1
+    implements C_100_0, C_101_1, C_111_1, C_010_0, C_010_1, C_011_1 {
+  const C_110_0_class_2();
+}
+
+const C_110_0_class_2 iC_110_0_class_2 = const C_110_0_class_2();
+closureC_110_0_class_2(foo) =>
+    (C_110_0_class_2 unused) => iC_110_0_class_2.toString() == foo.toString();
+
+class T_110_0_type__2 extends T_110_0
+    with M_100_0, M_110_0, M_101_1, M_111_1, M_010_0, M_010_1, M_011_1
+    implements T_100_0, T_101_1, T_111_1, T_010_0, T_010_1, T_011_1 {}
+
+class C_110_0_class_3 extends C_101_1
+    with M_100_0, M_110_0, M_101_1, M_111_1, M_010_0, M_010_1, M_011_1
+    implements C_100_0, C_110_0, C_111_1, C_010_0, C_010_1, C_011_1 {
+  const C_110_0_class_3();
+}
+
+const C_110_0_class_3 iC_110_0_class_3 = const C_110_0_class_3();
+closureC_110_0_class_3(foo) =>
+    (C_110_0_class_3 unused) => iC_110_0_class_3.toString() == foo.toString();
+
+class T_110_0_type__3 extends T_101_1
+    with M_100_0, M_110_0, M_101_1, M_111_1, M_010_0, M_010_1, M_011_1
+    implements T_100_0, T_110_0, T_111_1, T_010_0, T_010_1, T_011_1 {}
+
+class C_110_0_class_4 extends C_111_1
+    with M_100_0, M_110_0, M_101_1, M_111_1, M_010_0, M_010_1, M_011_1
+    implements C_100_0, C_110_0, C_101_1, C_010_0, C_010_1, C_011_1 {
+  const C_110_0_class_4();
+}
+
+const C_110_0_class_4 iC_110_0_class_4 = const C_110_0_class_4();
+closureC_110_0_class_4(foo) =>
+    (C_110_0_class_4 unused) => iC_110_0_class_4.toString() == foo.toString();
+
+class T_110_0_type__4 extends T_111_1
+    with M_100_0, M_110_0, M_101_1, M_111_1, M_010_0, M_010_1, M_011_1
+    implements T_100_0, T_110_0, T_101_1, T_010_0, T_010_1, T_011_1 {}
+
+class C_110_0_class_5 extends C_010_0
+    with M_100_0, M_110_0, M_101_1, M_111_1, M_010_0, M_010_1, M_011_1
+    implements C_100_0, C_110_0, C_101_1, C_111_1, C_010_1, C_011_1 {
+  const C_110_0_class_5();
+}
+
+const C_110_0_class_5 iC_110_0_class_5 = const C_110_0_class_5();
+closureC_110_0_class_5(foo) =>
+    (C_110_0_class_5 unused) => iC_110_0_class_5.toString() == foo.toString();
+
+class T_110_0_type__5 extends T_010_0
+    with M_100_0, M_110_0, M_101_1, M_111_1, M_010_0, M_010_1, M_011_1
+    implements T_100_0, T_110_0, T_101_1, T_111_1, T_010_1, T_011_1 {}
+
+class C_110_0_class_6 extends C_010_1
+    with M_100_0, M_110_0, M_101_1, M_111_1, M_010_0, M_010_1, M_011_1
+    implements C_100_0, C_110_0, C_101_1, C_111_1, C_010_0, C_011_1 {
+  const C_110_0_class_6();
+}
+
+const C_110_0_class_6 iC_110_0_class_6 = const C_110_0_class_6();
+closureC_110_0_class_6(foo) =>
+    (C_110_0_class_6 unused) => iC_110_0_class_6.toString() == foo.toString();
+
+class T_110_0_type__6 extends T_010_1
+    with M_100_0, M_110_0, M_101_1, M_111_1, M_010_0, M_010_1, M_011_1
+    implements T_100_0, T_110_0, T_101_1, T_111_1, T_010_0, T_011_1 {}
+
+class C_110_0_class_7 extends C_011_1
+    with M_100_0, M_110_0, M_101_1, M_111_1, M_010_0, M_010_1, M_011_1
+    implements C_100_0, C_110_0, C_101_1, C_111_1, C_010_0, C_010_1 {
+  const C_110_0_class_7();
+}
+
+const C_110_0_class_7 iC_110_0_class_7 = const C_110_0_class_7();
+closureC_110_0_class_7(foo) =>
+    (C_110_0_class_7 unused) => iC_110_0_class_7.toString() == foo.toString();
+
+class T_110_0_type__7 extends T_011_1
+    with M_100_0, M_110_0, M_101_1, M_111_1, M_010_0, M_010_1, M_011_1
+    implements T_100_0, T_110_0, T_101_1, T_111_1, T_010_0, T_010_1 {}
+
+class C_101_1_class_1 extends C_100_0
+    with M_100_0, M_110_0, M_101_1, M_111_1, M_001_0, M_000_1
+    implements C_110_0, C_101_1, C_111_1, C_001_0, C_000_1 {
+  const C_101_1_class_1();
+}
+
+const C_101_1_class_1 iC_101_1_class_1 = const C_101_1_class_1();
+closureC_101_1_class_1(foo) =>
+    (C_101_1_class_1 unused) => iC_101_1_class_1.toString() == foo.toString();
+
+class T_101_1_type__1 extends T_100_0
+    with M_100_0, M_110_0, M_101_1, M_111_1, M_001_0, M_000_1
+    implements T_110_0, T_101_1, T_111_1, T_001_0, T_000_1 {}
+
+class C_101_1_class_2 extends C_110_0
+    with M_100_0, M_110_0, M_101_1, M_111_1, M_001_0, M_000_1
+    implements C_100_0, C_101_1, C_111_1, C_001_0, C_000_1 {
+  const C_101_1_class_2();
+}
+
+const C_101_1_class_2 iC_101_1_class_2 = const C_101_1_class_2();
+closureC_101_1_class_2(foo) =>
+    (C_101_1_class_2 unused) => iC_101_1_class_2.toString() == foo.toString();
+
+class T_101_1_type__2 extends T_110_0
+    with M_100_0, M_110_0, M_101_1, M_111_1, M_001_0, M_000_1
+    implements T_100_0, T_101_1, T_111_1, T_001_0, T_000_1 {}
+
+class C_101_1_class_3 extends C_101_1
+    with M_100_0, M_110_0, M_101_1, M_111_1, M_001_0, M_000_1
+    implements C_100_0, C_110_0, C_111_1, C_001_0, C_000_1 {
+  const C_101_1_class_3();
+}
+
+const C_101_1_class_3 iC_101_1_class_3 = const C_101_1_class_3();
+closureC_101_1_class_3(foo) =>
+    (C_101_1_class_3 unused) => iC_101_1_class_3.toString() == foo.toString();
+
+class T_101_1_type__3 extends T_101_1
+    with M_100_0, M_110_0, M_101_1, M_111_1, M_001_0, M_000_1
+    implements T_100_0, T_110_0, T_111_1, T_001_0, T_000_1 {}
+
+class C_101_1_class_4 extends C_111_1
+    with M_100_0, M_110_0, M_101_1, M_111_1, M_001_0, M_000_1
+    implements C_100_0, C_110_0, C_101_1, C_001_0, C_000_1 {
+  const C_101_1_class_4();
+}
+
+const C_101_1_class_4 iC_101_1_class_4 = const C_101_1_class_4();
+closureC_101_1_class_4(foo) =>
+    (C_101_1_class_4 unused) => iC_101_1_class_4.toString() == foo.toString();
+
+class T_101_1_type__4 extends T_111_1
+    with M_100_0, M_110_0, M_101_1, M_111_1, M_001_0, M_000_1
+    implements T_100_0, T_110_0, T_101_1, T_001_0, T_000_1 {}
+
+class C_101_1_class_5 extends C_001_0
+    with M_100_0, M_110_0, M_101_1, M_111_1, M_001_0, M_000_1
+    implements C_100_0, C_110_0, C_101_1, C_111_1, C_000_1 {
+  const C_101_1_class_5();
+}
+
+const C_101_1_class_5 iC_101_1_class_5 = const C_101_1_class_5();
+closureC_101_1_class_5(foo) =>
+    (C_101_1_class_5 unused) => iC_101_1_class_5.toString() == foo.toString();
+
+class T_101_1_type__5 extends T_001_0
+    with M_100_0, M_110_0, M_101_1, M_111_1, M_001_0, M_000_1
+    implements T_100_0, T_110_0, T_101_1, T_111_1, T_000_1 {}
+
+class C_101_1_class_6 extends C_000_1
+    with M_100_0, M_110_0, M_101_1, M_111_1, M_001_0, M_000_1
+    implements C_100_0, C_110_0, C_101_1, C_111_1, C_001_0 {
+  const C_101_1_class_6();
+}
+
+const C_101_1_class_6 iC_101_1_class_6 = const C_101_1_class_6();
+closureC_101_1_class_6(foo) =>
+    (C_101_1_class_6 unused) => iC_101_1_class_6.toString() == foo.toString();
+
+class T_101_1_type__6 extends T_000_1
+    with M_100_0, M_110_0, M_101_1, M_111_1, M_001_0, M_000_1
+    implements T_100_0, T_110_0, T_101_1, T_111_1, T_001_0 {}
+
+class C_111_1_class_1 extends C_100_0
+    with
+        M_100_0,
+        M_110_0,
+        M_101_1,
+        M_111_1,
+        M_010_0,
+        M_010_1,
+        M_011_1,
+        M_001_0,
+        M_000_1
+    implements
+        C_110_0,
+        C_101_1,
+        C_111_1,
+        C_010_0,
+        C_010_1,
+        C_011_1,
+        C_001_0,
+        C_000_1 {
+  const C_111_1_class_1();
+}
+
+const C_111_1_class_1 iC_111_1_class_1 = const C_111_1_class_1();
+closureC_111_1_class_1(foo) =>
+    (C_111_1_class_1 unused) => iC_111_1_class_1.toString() == foo.toString();
+
+class T_111_1_type__1 extends T_100_0
+    with
+        M_100_0,
+        M_110_0,
+        M_101_1,
+        M_111_1,
+        M_010_0,
+        M_010_1,
+        M_011_1,
+        M_001_0,
+        M_000_1
+    implements
+        T_110_0,
+        T_101_1,
+        T_111_1,
+        T_010_0,
+        T_010_1,
+        T_011_1,
+        T_001_0,
+        T_000_1 {}
+
+class C_111_1_class_2 extends C_110_0
+    with
+        M_100_0,
+        M_110_0,
+        M_101_1,
+        M_111_1,
+        M_010_0,
+        M_010_1,
+        M_011_1,
+        M_001_0,
+        M_000_1
+    implements
+        C_100_0,
+        C_101_1,
+        C_111_1,
+        C_010_0,
+        C_010_1,
+        C_011_1,
+        C_001_0,
+        C_000_1 {
+  const C_111_1_class_2();
+}
+
+const C_111_1_class_2 iC_111_1_class_2 = const C_111_1_class_2();
+closureC_111_1_class_2(foo) =>
+    (C_111_1_class_2 unused) => iC_111_1_class_2.toString() == foo.toString();
+
+class T_111_1_type__2 extends T_110_0
+    with
+        M_100_0,
+        M_110_0,
+        M_101_1,
+        M_111_1,
+        M_010_0,
+        M_010_1,
+        M_011_1,
+        M_001_0,
+        M_000_1
+    implements
+        T_100_0,
+        T_101_1,
+        T_111_1,
+        T_010_0,
+        T_010_1,
+        T_011_1,
+        T_001_0,
+        T_000_1 {}
+
+class C_111_1_class_3 extends C_101_1
+    with
+        M_100_0,
+        M_110_0,
+        M_101_1,
+        M_111_1,
+        M_010_0,
+        M_010_1,
+        M_011_1,
+        M_001_0,
+        M_000_1
+    implements
+        C_100_0,
+        C_110_0,
+        C_111_1,
+        C_010_0,
+        C_010_1,
+        C_011_1,
+        C_001_0,
+        C_000_1 {
+  const C_111_1_class_3();
+}
+
+const C_111_1_class_3 iC_111_1_class_3 = const C_111_1_class_3();
+closureC_111_1_class_3(foo) =>
+    (C_111_1_class_3 unused) => iC_111_1_class_3.toString() == foo.toString();
+
+class T_111_1_type__3 extends T_101_1
+    with
+        M_100_0,
+        M_110_0,
+        M_101_1,
+        M_111_1,
+        M_010_0,
+        M_010_1,
+        M_011_1,
+        M_001_0,
+        M_000_1
+    implements
+        T_100_0,
+        T_110_0,
+        T_111_1,
+        T_010_0,
+        T_010_1,
+        T_011_1,
+        T_001_0,
+        T_000_1 {}
+
+class C_111_1_class_4 extends C_111_1
+    with
+        M_100_0,
+        M_110_0,
+        M_101_1,
+        M_111_1,
+        M_010_0,
+        M_010_1,
+        M_011_1,
+        M_001_0,
+        M_000_1
+    implements
+        C_100_0,
+        C_110_0,
+        C_101_1,
+        C_010_0,
+        C_010_1,
+        C_011_1,
+        C_001_0,
+        C_000_1 {
+  const C_111_1_class_4();
+}
+
+const C_111_1_class_4 iC_111_1_class_4 = const C_111_1_class_4();
+closureC_111_1_class_4(foo) =>
+    (C_111_1_class_4 unused) => iC_111_1_class_4.toString() == foo.toString();
+
+class T_111_1_type__4 extends T_111_1
+    with
+        M_100_0,
+        M_110_0,
+        M_101_1,
+        M_111_1,
+        M_010_0,
+        M_010_1,
+        M_011_1,
+        M_001_0,
+        M_000_1
+    implements
+        T_100_0,
+        T_110_0,
+        T_101_1,
+        T_010_0,
+        T_010_1,
+        T_011_1,
+        T_001_0,
+        T_000_1 {}
+
+class C_111_1_class_5 extends C_010_0
+    with
+        M_100_0,
+        M_110_0,
+        M_101_1,
+        M_111_1,
+        M_010_0,
+        M_010_1,
+        M_011_1,
+        M_001_0,
+        M_000_1
+    implements
+        C_100_0,
+        C_110_0,
+        C_101_1,
+        C_111_1,
+        C_010_1,
+        C_011_1,
+        C_001_0,
+        C_000_1 {
+  const C_111_1_class_5();
+}
+
+const C_111_1_class_5 iC_111_1_class_5 = const C_111_1_class_5();
+closureC_111_1_class_5(foo) =>
+    (C_111_1_class_5 unused) => iC_111_1_class_5.toString() == foo.toString();
+
+class T_111_1_type__5 extends T_010_0
+    with
+        M_100_0,
+        M_110_0,
+        M_101_1,
+        M_111_1,
+        M_010_0,
+        M_010_1,
+        M_011_1,
+        M_001_0,
+        M_000_1
+    implements
+        T_100_0,
+        T_110_0,
+        T_101_1,
+        T_111_1,
+        T_010_1,
+        T_011_1,
+        T_001_0,
+        T_000_1 {}
+
+class C_111_1_class_6 extends C_010_1
+    with
+        M_100_0,
+        M_110_0,
+        M_101_1,
+        M_111_1,
+        M_010_0,
+        M_010_1,
+        M_011_1,
+        M_001_0,
+        M_000_1
+    implements
+        C_100_0,
+        C_110_0,
+        C_101_1,
+        C_111_1,
+        C_010_0,
+        C_011_1,
+        C_001_0,
+        C_000_1 {
+  const C_111_1_class_6();
+}
+
+const C_111_1_class_6 iC_111_1_class_6 = const C_111_1_class_6();
+closureC_111_1_class_6(foo) =>
+    (C_111_1_class_6 unused) => iC_111_1_class_6.toString() == foo.toString();
+
+class T_111_1_type__6 extends T_010_1
+    with
+        M_100_0,
+        M_110_0,
+        M_101_1,
+        M_111_1,
+        M_010_0,
+        M_010_1,
+        M_011_1,
+        M_001_0,
+        M_000_1
+    implements
+        T_100_0,
+        T_110_0,
+        T_101_1,
+        T_111_1,
+        T_010_0,
+        T_011_1,
+        T_001_0,
+        T_000_1 {}
+
+class C_111_1_class_7 extends C_011_1
+    with
+        M_100_0,
+        M_110_0,
+        M_101_1,
+        M_111_1,
+        M_010_0,
+        M_010_1,
+        M_011_1,
+        M_001_0,
+        M_000_1
+    implements
+        C_100_0,
+        C_110_0,
+        C_101_1,
+        C_111_1,
+        C_010_0,
+        C_010_1,
+        C_001_0,
+        C_000_1 {
+  const C_111_1_class_7();
+}
+
+const C_111_1_class_7 iC_111_1_class_7 = const C_111_1_class_7();
+closureC_111_1_class_7(foo) =>
+    (C_111_1_class_7 unused) => iC_111_1_class_7.toString() == foo.toString();
+
+class T_111_1_type__7 extends T_011_1
+    with
+        M_100_0,
+        M_110_0,
+        M_101_1,
+        M_111_1,
+        M_010_0,
+        M_010_1,
+        M_011_1,
+        M_001_0,
+        M_000_1
+    implements
+        T_100_0,
+        T_110_0,
+        T_101_1,
+        T_111_1,
+        T_010_0,
+        T_010_1,
+        T_001_0,
+        T_000_1 {}
+
+class C_111_1_class_8 extends C_001_0
+    with
+        M_100_0,
+        M_110_0,
+        M_101_1,
+        M_111_1,
+        M_010_0,
+        M_010_1,
+        M_011_1,
+        M_001_0,
+        M_000_1
+    implements
+        C_100_0,
+        C_110_0,
+        C_101_1,
+        C_111_1,
+        C_010_0,
+        C_010_1,
+        C_011_1,
+        C_000_1 {
+  const C_111_1_class_8();
+}
+
+const C_111_1_class_8 iC_111_1_class_8 = const C_111_1_class_8();
+closureC_111_1_class_8(foo) =>
+    (C_111_1_class_8 unused) => iC_111_1_class_8.toString() == foo.toString();
+
+class T_111_1_type__8 extends T_001_0
+    with
+        M_100_0,
+        M_110_0,
+        M_101_1,
+        M_111_1,
+        M_010_0,
+        M_010_1,
+        M_011_1,
+        M_001_0,
+        M_000_1
+    implements
+        T_100_0,
+        T_110_0,
+        T_101_1,
+        T_111_1,
+        T_010_0,
+        T_010_1,
+        T_011_1,
+        T_000_1 {}
+
+class C_111_1_class_9 extends C_000_1
+    with
+        M_100_0,
+        M_110_0,
+        M_101_1,
+        M_111_1,
+        M_010_0,
+        M_010_1,
+        M_011_1,
+        M_001_0,
+        M_000_1
+    implements
+        C_100_0,
+        C_110_0,
+        C_101_1,
+        C_111_1,
+        C_010_0,
+        C_010_1,
+        C_011_1,
+        C_001_0 {
+  const C_111_1_class_9();
+}
+
+const C_111_1_class_9 iC_111_1_class_9 = const C_111_1_class_9();
+closureC_111_1_class_9(foo) =>
+    (C_111_1_class_9 unused) => iC_111_1_class_9.toString() == foo.toString();
+
+class T_111_1_type__9 extends T_000_1
+    with
+        M_100_0,
+        M_110_0,
+        M_101_1,
+        M_111_1,
+        M_010_0,
+        M_010_1,
+        M_011_1,
+        M_001_0,
+        M_000_1
+    implements
+        T_100_0,
+        T_110_0,
+        T_101_1,
+        T_111_1,
+        T_010_0,
+        T_010_1,
+        T_011_1,
+        T_001_0 {}
+
+class C_010_1_class_1 extends C_010_0
+    with M_010_0, M_010_1, M_011_1, M_000_1
+    implements C_010_1, C_011_1, C_000_1 {
+  const C_010_1_class_1();
+}
+
+const C_010_1_class_1 iC_010_1_class_1 = const C_010_1_class_1();
+closureC_010_1_class_1(foo) =>
+    (C_010_1_class_1 unused) => iC_010_1_class_1.toString() == foo.toString();
+
+class T_010_1_type__1 extends T_010_0
+    with M_010_0, M_010_1, M_011_1, M_000_1
+    implements T_010_1, T_011_1, T_000_1 {}
+
+class C_010_1_class_2 extends C_010_1
+    with M_010_0, M_010_1, M_011_1, M_000_1
+    implements C_010_0, C_011_1, C_000_1 {
+  const C_010_1_class_2();
+}
+
+const C_010_1_class_2 iC_010_1_class_2 = const C_010_1_class_2();
+closureC_010_1_class_2(foo) =>
+    (C_010_1_class_2 unused) => iC_010_1_class_2.toString() == foo.toString();
+
+class T_010_1_type__2 extends T_010_1
+    with M_010_0, M_010_1, M_011_1, M_000_1
+    implements T_010_0, T_011_1, T_000_1 {}
+
+class C_010_1_class_3 extends C_011_1
+    with M_010_0, M_010_1, M_011_1, M_000_1
+    implements C_010_0, C_010_1, C_000_1 {
+  const C_010_1_class_3();
+}
+
+const C_010_1_class_3 iC_010_1_class_3 = const C_010_1_class_3();
+closureC_010_1_class_3(foo) =>
+    (C_010_1_class_3 unused) => iC_010_1_class_3.toString() == foo.toString();
+
+class T_010_1_type__3 extends T_011_1
+    with M_010_0, M_010_1, M_011_1, M_000_1
+    implements T_010_0, T_010_1, T_000_1 {}
+
+class C_010_1_class_4 extends C_000_1
+    with M_010_0, M_010_1, M_011_1, M_000_1
+    implements C_010_0, C_010_1, C_011_1 {
+  const C_010_1_class_4();
+}
+
+const C_010_1_class_4 iC_010_1_class_4 = const C_010_1_class_4();
+closureC_010_1_class_4(foo) =>
+    (C_010_1_class_4 unused) => iC_010_1_class_4.toString() == foo.toString();
+
+class T_010_1_type__4 extends T_000_1
+    with M_010_0, M_010_1, M_011_1, M_000_1
+    implements T_010_0, T_010_1, T_011_1 {}
+
+class C_011_1_class_1 extends C_010_0
+    with M_010_0, M_010_1, M_011_1, M_001_0, M_000_1
+    implements C_010_1, C_011_1, C_001_0, C_000_1 {
+  const C_011_1_class_1();
+}
+
+const C_011_1_class_1 iC_011_1_class_1 = const C_011_1_class_1();
+closureC_011_1_class_1(foo) =>
+    (C_011_1_class_1 unused) => iC_011_1_class_1.toString() == foo.toString();
+
+class T_011_1_type__1 extends T_010_0
+    with M_010_0, M_010_1, M_011_1, M_001_0, M_000_1
+    implements T_010_1, T_011_1, T_001_0, T_000_1 {}
+
+class C_011_1_class_2 extends C_010_1
+    with M_010_0, M_010_1, M_011_1, M_001_0, M_000_1
+    implements C_010_0, C_011_1, C_001_0, C_000_1 {
+  const C_011_1_class_2();
+}
+
+const C_011_1_class_2 iC_011_1_class_2 = const C_011_1_class_2();
+closureC_011_1_class_2(foo) =>
+    (C_011_1_class_2 unused) => iC_011_1_class_2.toString() == foo.toString();
+
+class T_011_1_type__2 extends T_010_1
+    with M_010_0, M_010_1, M_011_1, M_001_0, M_000_1
+    implements T_010_0, T_011_1, T_001_0, T_000_1 {}
+
+class C_011_1_class_3 extends C_011_1
+    with M_010_0, M_010_1, M_011_1, M_001_0, M_000_1
+    implements C_010_0, C_010_1, C_001_0, C_000_1 {
+  const C_011_1_class_3();
+}
+
+const C_011_1_class_3 iC_011_1_class_3 = const C_011_1_class_3();
+closureC_011_1_class_3(foo) =>
+    (C_011_1_class_3 unused) => iC_011_1_class_3.toString() == foo.toString();
+
+class T_011_1_type__3 extends T_011_1
+    with M_010_0, M_010_1, M_011_1, M_001_0, M_000_1
+    implements T_010_0, T_010_1, T_001_0, T_000_1 {}
+
+class C_011_1_class_4 extends C_001_0
+    with M_010_0, M_010_1, M_011_1, M_001_0, M_000_1
+    implements C_010_0, C_010_1, C_011_1, C_000_1 {
+  const C_011_1_class_4();
+}
+
+const C_011_1_class_4 iC_011_1_class_4 = const C_011_1_class_4();
+closureC_011_1_class_4(foo) =>
+    (C_011_1_class_4 unused) => iC_011_1_class_4.toString() == foo.toString();
+
+class T_011_1_type__4 extends T_001_0
+    with M_010_0, M_010_1, M_011_1, M_001_0, M_000_1
+    implements T_010_0, T_010_1, T_011_1, T_000_1 {}
+
+class C_011_1_class_5 extends C_000_1
+    with M_010_0, M_010_1, M_011_1, M_001_0, M_000_1
+    implements C_010_0, C_010_1, C_011_1, C_001_0 {
+  const C_011_1_class_5();
+}
+
+const C_011_1_class_5 iC_011_1_class_5 = const C_011_1_class_5();
+closureC_011_1_class_5(foo) =>
+    (C_011_1_class_5 unused) => iC_011_1_class_5.toString() == foo.toString();
+
+class T_011_1_type__5 extends T_000_1
+    with M_010_0, M_010_1, M_011_1, M_001_0, M_000_1
+    implements T_010_0, T_010_1, T_011_1, T_001_0 {}
+
+@pragma('dart2js:noInline')
+f_100_0(Set<String> u, int b) => v(u, '1000', b);
+@pragma('dart2js:noInline')
+f_110_0(Set<String> u, int b) => v(u, '1100', b);
+@pragma('dart2js:noInline')
+f_101_1(Set<String> u, int b) => v(u, '1011', b);
+@pragma('dart2js:noInline')
+f_111_1(Set<String> u, int b) => v(u, '1111', b);
+@pragma('dart2js:noInline')
+f_010_0(Set<String> u, int b) => v(u, '0100', b);
+@pragma('dart2js:noInline')
+f_010_1(Set<String> u, int b) => v(u, '0101', b);
+@pragma('dart2js:noInline')
+f_011_1(Set<String> u, int b) => v(u, '0111', b);
+@pragma('dart2js:noInline')
+f_001_0(Set<String> u, int b) => v(u, '0010', b);
+@pragma('dart2js:noInline')
+f_000_1(Set<String> u, int b) => v(u, '0001', b);
diff --git a/pkg/compiler/test/tool/graph_isomorphizer/golden/less_simple/lib_000_1.dart b/pkg/compiler/test/tool/graph_isomorphizer/golden/less_simple/lib_000_1.dart
new file mode 100644
index 0000000..c67496e
--- /dev/null
+++ b/pkg/compiler/test/tool/graph_isomorphizer/golden/less_simple/lib_000_1.dart
@@ -0,0 +1,229 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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 was autogenerated by the pkg/compiler/tool/graph_isomorphizer.dart.
+import "package:expect/expect.dart";
+
+import 'libImport.dart';
+
+@pragma('dart2js:noInline')
+typeTest(dynamic t) {
+  if (t is T_000_1) {
+    return true;
+  }
+  if (t is T_101_1_type__1) {
+    return true;
+  }
+  if (t is T_101_1_type__2) {
+    return true;
+  }
+  if (t is T_101_1_type__3) {
+    return true;
+  }
+  if (t is T_101_1_type__4) {
+    return true;
+  }
+  if (t is T_101_1_type__5) {
+    return true;
+  }
+  if (t is T_101_1_type__6) {
+    return true;
+  }
+  if (t is T_111_1_type__1) {
+    return true;
+  }
+  if (t is T_111_1_type__2) {
+    return true;
+  }
+  if (t is T_111_1_type__3) {
+    return true;
+  }
+  if (t is T_111_1_type__4) {
+    return true;
+  }
+  if (t is T_111_1_type__5) {
+    return true;
+  }
+  if (t is T_111_1_type__6) {
+    return true;
+  }
+  if (t is T_111_1_type__7) {
+    return true;
+  }
+  if (t is T_111_1_type__8) {
+    return true;
+  }
+  if (t is T_111_1_type__9) {
+    return true;
+  }
+  if (t is T_010_1_type__1) {
+    return true;
+  }
+  if (t is T_010_1_type__2) {
+    return true;
+  }
+  if (t is T_010_1_type__3) {
+    return true;
+  }
+  if (t is T_010_1_type__4) {
+    return true;
+  }
+  if (t is T_011_1_type__1) {
+    return true;
+  }
+  if (t is T_011_1_type__2) {
+    return true;
+  }
+  if (t is T_011_1_type__3) {
+    return true;
+  }
+  if (t is T_011_1_type__4) {
+    return true;
+  }
+  if (t is T_011_1_type__5) {
+    return true;
+  }
+  return false;
+}
+
+@pragma('dart2js:noInline')
+g_000_1() {
+  // C_***_1;
+  Expect.isFalse(typeTest(C_000_1()));
+  Expect.isFalse(typeTest(C_101_1_class_1()));
+  Expect.isFalse(typeTest(C_101_1_class_2()));
+  Expect.isFalse(typeTest(C_101_1_class_3()));
+  Expect.isFalse(typeTest(C_101_1_class_4()));
+  Expect.isFalse(typeTest(C_101_1_class_5()));
+  Expect.isFalse(typeTest(C_101_1_class_6()));
+  Expect.isFalse(typeTest(C_111_1_class_1()));
+  Expect.isFalse(typeTest(C_111_1_class_2()));
+  Expect.isFalse(typeTest(C_111_1_class_3()));
+  Expect.isFalse(typeTest(C_111_1_class_4()));
+  Expect.isFalse(typeTest(C_111_1_class_5()));
+  Expect.isFalse(typeTest(C_111_1_class_6()));
+  Expect.isFalse(typeTest(C_111_1_class_7()));
+  Expect.isFalse(typeTest(C_111_1_class_8()));
+  Expect.isFalse(typeTest(C_111_1_class_9()));
+  Expect.isFalse(typeTest(C_010_1_class_1()));
+  Expect.isFalse(typeTest(C_010_1_class_2()));
+  Expect.isFalse(typeTest(C_010_1_class_3()));
+  Expect.isFalse(typeTest(C_010_1_class_4()));
+  Expect.isFalse(typeTest(C_011_1_class_1()));
+  Expect.isFalse(typeTest(C_011_1_class_2()));
+  Expect.isFalse(typeTest(C_011_1_class_3()));
+  Expect.isFalse(typeTest(C_011_1_class_4()));
+  Expect.isFalse(typeTest(C_011_1_class_5()));
+
+  Expect.isTrue(closureC_000_1(C_000_1())(C_000_1()));
+  Expect.isTrue(closureC_101_1_class_1(C_101_1_class_1())(C_101_1_class_1()));
+  Expect.isTrue(closureC_101_1_class_2(C_101_1_class_2())(C_101_1_class_2()));
+  Expect.isTrue(closureC_101_1_class_3(C_101_1_class_3())(C_101_1_class_3()));
+  Expect.isTrue(closureC_101_1_class_4(C_101_1_class_4())(C_101_1_class_4()));
+  Expect.isTrue(closureC_101_1_class_5(C_101_1_class_5())(C_101_1_class_5()));
+  Expect.isTrue(closureC_101_1_class_6(C_101_1_class_6())(C_101_1_class_6()));
+  Expect.isTrue(closureC_111_1_class_1(C_111_1_class_1())(C_111_1_class_1()));
+  Expect.isTrue(closureC_111_1_class_2(C_111_1_class_2())(C_111_1_class_2()));
+  Expect.isTrue(closureC_111_1_class_3(C_111_1_class_3())(C_111_1_class_3()));
+  Expect.isTrue(closureC_111_1_class_4(C_111_1_class_4())(C_111_1_class_4()));
+  Expect.isTrue(closureC_111_1_class_5(C_111_1_class_5())(C_111_1_class_5()));
+  Expect.isTrue(closureC_111_1_class_6(C_111_1_class_6())(C_111_1_class_6()));
+  Expect.isTrue(closureC_111_1_class_7(C_111_1_class_7())(C_111_1_class_7()));
+  Expect.isTrue(closureC_111_1_class_8(C_111_1_class_8())(C_111_1_class_8()));
+  Expect.isTrue(closureC_111_1_class_9(C_111_1_class_9())(C_111_1_class_9()));
+  Expect.isTrue(closureC_010_1_class_1(C_010_1_class_1())(C_010_1_class_1()));
+  Expect.isTrue(closureC_010_1_class_2(C_010_1_class_2())(C_010_1_class_2()));
+  Expect.isTrue(closureC_010_1_class_3(C_010_1_class_3())(C_010_1_class_3()));
+  Expect.isTrue(closureC_010_1_class_4(C_010_1_class_4())(C_010_1_class_4()));
+  Expect.isTrue(closureC_011_1_class_1(C_011_1_class_1())(C_011_1_class_1()));
+  Expect.isTrue(closureC_011_1_class_2(C_011_1_class_2())(C_011_1_class_2()));
+  Expect.isTrue(closureC_011_1_class_3(C_011_1_class_3())(C_011_1_class_3()));
+  Expect.isTrue(closureC_011_1_class_4(C_011_1_class_4())(C_011_1_class_4()));
+  Expect.isTrue(closureC_011_1_class_5(C_011_1_class_5())(C_011_1_class_5()));
+
+  Expect.equals(
+      closureC_000_1(C_000_1()).runtimeType.toString(), '(C_000_1) => bool');
+  Expect.equals(
+      closureC_101_1_class_1(C_101_1_class_1()).runtimeType.toString(),
+      '(C_101_1_class_1) => bool');
+  Expect.equals(
+      closureC_101_1_class_2(C_101_1_class_2()).runtimeType.toString(),
+      '(C_101_1_class_2) => bool');
+  Expect.equals(
+      closureC_101_1_class_3(C_101_1_class_3()).runtimeType.toString(),
+      '(C_101_1_class_3) => bool');
+  Expect.equals(
+      closureC_101_1_class_4(C_101_1_class_4()).runtimeType.toString(),
+      '(C_101_1_class_4) => bool');
+  Expect.equals(
+      closureC_101_1_class_5(C_101_1_class_5()).runtimeType.toString(),
+      '(C_101_1_class_5) => bool');
+  Expect.equals(
+      closureC_101_1_class_6(C_101_1_class_6()).runtimeType.toString(),
+      '(C_101_1_class_6) => bool');
+  Expect.equals(
+      closureC_111_1_class_1(C_111_1_class_1()).runtimeType.toString(),
+      '(C_111_1_class_1) => bool');
+  Expect.equals(
+      closureC_111_1_class_2(C_111_1_class_2()).runtimeType.toString(),
+      '(C_111_1_class_2) => bool');
+  Expect.equals(
+      closureC_111_1_class_3(C_111_1_class_3()).runtimeType.toString(),
+      '(C_111_1_class_3) => bool');
+  Expect.equals(
+      closureC_111_1_class_4(C_111_1_class_4()).runtimeType.toString(),
+      '(C_111_1_class_4) => bool');
+  Expect.equals(
+      closureC_111_1_class_5(C_111_1_class_5()).runtimeType.toString(),
+      '(C_111_1_class_5) => bool');
+  Expect.equals(
+      closureC_111_1_class_6(C_111_1_class_6()).runtimeType.toString(),
+      '(C_111_1_class_6) => bool');
+  Expect.equals(
+      closureC_111_1_class_7(C_111_1_class_7()).runtimeType.toString(),
+      '(C_111_1_class_7) => bool');
+  Expect.equals(
+      closureC_111_1_class_8(C_111_1_class_8()).runtimeType.toString(),
+      '(C_111_1_class_8) => bool');
+  Expect.equals(
+      closureC_111_1_class_9(C_111_1_class_9()).runtimeType.toString(),
+      '(C_111_1_class_9) => bool');
+  Expect.equals(
+      closureC_010_1_class_1(C_010_1_class_1()).runtimeType.toString(),
+      '(C_010_1_class_1) => bool');
+  Expect.equals(
+      closureC_010_1_class_2(C_010_1_class_2()).runtimeType.toString(),
+      '(C_010_1_class_2) => bool');
+  Expect.equals(
+      closureC_010_1_class_3(C_010_1_class_3()).runtimeType.toString(),
+      '(C_010_1_class_3) => bool');
+  Expect.equals(
+      closureC_010_1_class_4(C_010_1_class_4()).runtimeType.toString(),
+      '(C_010_1_class_4) => bool');
+  Expect.equals(
+      closureC_011_1_class_1(C_011_1_class_1()).runtimeType.toString(),
+      '(C_011_1_class_1) => bool');
+  Expect.equals(
+      closureC_011_1_class_2(C_011_1_class_2()).runtimeType.toString(),
+      '(C_011_1_class_2) => bool');
+  Expect.equals(
+      closureC_011_1_class_3(C_011_1_class_3()).runtimeType.toString(),
+      '(C_011_1_class_3) => bool');
+  Expect.equals(
+      closureC_011_1_class_4(C_011_1_class_4()).runtimeType.toString(),
+      '(C_011_1_class_4) => bool');
+  Expect.equals(
+      closureC_011_1_class_5(C_011_1_class_5()).runtimeType.toString(),
+      '(C_011_1_class_5) => bool');
+
+  Set<String> uniques = {};
+
+  // f_***_1;
+  f_000_1(uniques, 3);
+  f_010_1(uniques, 3);
+  f_011_1(uniques, 3);
+  f_101_1(uniques, 3);
+  f_111_1(uniques, 3);
+  Expect.equals(5, uniques.length);
+}
diff --git a/pkg/compiler/test/tool/graph_isomorphizer/golden/less_simple/lib_001_0.dart b/pkg/compiler/test/tool/graph_isomorphizer/golden/less_simple/lib_001_0.dart
new file mode 100644
index 0000000..93b13b2
--- /dev/null
+++ b/pkg/compiler/test/tool/graph_isomorphizer/golden/less_simple/lib_001_0.dart
@@ -0,0 +1,196 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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 was autogenerated by the pkg/compiler/tool/graph_isomorphizer.dart.
+import "package:expect/expect.dart";
+
+import 'libImport.dart';
+
+@pragma('dart2js:noInline')
+typeTest(dynamic t) {
+  if (t is T_001_0) {
+    return true;
+  }
+  if (t is T_101_1_type__1) {
+    return true;
+  }
+  if (t is T_101_1_type__2) {
+    return true;
+  }
+  if (t is T_101_1_type__3) {
+    return true;
+  }
+  if (t is T_101_1_type__4) {
+    return true;
+  }
+  if (t is T_101_1_type__5) {
+    return true;
+  }
+  if (t is T_101_1_type__6) {
+    return true;
+  }
+  if (t is T_111_1_type__1) {
+    return true;
+  }
+  if (t is T_111_1_type__2) {
+    return true;
+  }
+  if (t is T_111_1_type__3) {
+    return true;
+  }
+  if (t is T_111_1_type__4) {
+    return true;
+  }
+  if (t is T_111_1_type__5) {
+    return true;
+  }
+  if (t is T_111_1_type__6) {
+    return true;
+  }
+  if (t is T_111_1_type__7) {
+    return true;
+  }
+  if (t is T_111_1_type__8) {
+    return true;
+  }
+  if (t is T_111_1_type__9) {
+    return true;
+  }
+  if (t is T_011_1_type__1) {
+    return true;
+  }
+  if (t is T_011_1_type__2) {
+    return true;
+  }
+  if (t is T_011_1_type__3) {
+    return true;
+  }
+  if (t is T_011_1_type__4) {
+    return true;
+  }
+  if (t is T_011_1_type__5) {
+    return true;
+  }
+  return false;
+}
+
+@pragma('dart2js:noInline')
+g_001_0() {
+  // C_**1_*;
+  Expect.isFalse(typeTest(C_001_0()));
+  Expect.isFalse(typeTest(C_101_1_class_1()));
+  Expect.isFalse(typeTest(C_101_1_class_2()));
+  Expect.isFalse(typeTest(C_101_1_class_3()));
+  Expect.isFalse(typeTest(C_101_1_class_4()));
+  Expect.isFalse(typeTest(C_101_1_class_5()));
+  Expect.isFalse(typeTest(C_101_1_class_6()));
+  Expect.isFalse(typeTest(C_111_1_class_1()));
+  Expect.isFalse(typeTest(C_111_1_class_2()));
+  Expect.isFalse(typeTest(C_111_1_class_3()));
+  Expect.isFalse(typeTest(C_111_1_class_4()));
+  Expect.isFalse(typeTest(C_111_1_class_5()));
+  Expect.isFalse(typeTest(C_111_1_class_6()));
+  Expect.isFalse(typeTest(C_111_1_class_7()));
+  Expect.isFalse(typeTest(C_111_1_class_8()));
+  Expect.isFalse(typeTest(C_111_1_class_9()));
+  Expect.isFalse(typeTest(C_011_1_class_1()));
+  Expect.isFalse(typeTest(C_011_1_class_2()));
+  Expect.isFalse(typeTest(C_011_1_class_3()));
+  Expect.isFalse(typeTest(C_011_1_class_4()));
+  Expect.isFalse(typeTest(C_011_1_class_5()));
+
+  Expect.isTrue(closureC_001_0(C_001_0())(C_001_0()));
+  Expect.isTrue(closureC_101_1_class_1(C_101_1_class_1())(C_101_1_class_1()));
+  Expect.isTrue(closureC_101_1_class_2(C_101_1_class_2())(C_101_1_class_2()));
+  Expect.isTrue(closureC_101_1_class_3(C_101_1_class_3())(C_101_1_class_3()));
+  Expect.isTrue(closureC_101_1_class_4(C_101_1_class_4())(C_101_1_class_4()));
+  Expect.isTrue(closureC_101_1_class_5(C_101_1_class_5())(C_101_1_class_5()));
+  Expect.isTrue(closureC_101_1_class_6(C_101_1_class_6())(C_101_1_class_6()));
+  Expect.isTrue(closureC_111_1_class_1(C_111_1_class_1())(C_111_1_class_1()));
+  Expect.isTrue(closureC_111_1_class_2(C_111_1_class_2())(C_111_1_class_2()));
+  Expect.isTrue(closureC_111_1_class_3(C_111_1_class_3())(C_111_1_class_3()));
+  Expect.isTrue(closureC_111_1_class_4(C_111_1_class_4())(C_111_1_class_4()));
+  Expect.isTrue(closureC_111_1_class_5(C_111_1_class_5())(C_111_1_class_5()));
+  Expect.isTrue(closureC_111_1_class_6(C_111_1_class_6())(C_111_1_class_6()));
+  Expect.isTrue(closureC_111_1_class_7(C_111_1_class_7())(C_111_1_class_7()));
+  Expect.isTrue(closureC_111_1_class_8(C_111_1_class_8())(C_111_1_class_8()));
+  Expect.isTrue(closureC_111_1_class_9(C_111_1_class_9())(C_111_1_class_9()));
+  Expect.isTrue(closureC_011_1_class_1(C_011_1_class_1())(C_011_1_class_1()));
+  Expect.isTrue(closureC_011_1_class_2(C_011_1_class_2())(C_011_1_class_2()));
+  Expect.isTrue(closureC_011_1_class_3(C_011_1_class_3())(C_011_1_class_3()));
+  Expect.isTrue(closureC_011_1_class_4(C_011_1_class_4())(C_011_1_class_4()));
+  Expect.isTrue(closureC_011_1_class_5(C_011_1_class_5())(C_011_1_class_5()));
+
+  Expect.equals(
+      closureC_001_0(C_001_0()).runtimeType.toString(), '(C_001_0) => bool');
+  Expect.equals(
+      closureC_101_1_class_1(C_101_1_class_1()).runtimeType.toString(),
+      '(C_101_1_class_1) => bool');
+  Expect.equals(
+      closureC_101_1_class_2(C_101_1_class_2()).runtimeType.toString(),
+      '(C_101_1_class_2) => bool');
+  Expect.equals(
+      closureC_101_1_class_3(C_101_1_class_3()).runtimeType.toString(),
+      '(C_101_1_class_3) => bool');
+  Expect.equals(
+      closureC_101_1_class_4(C_101_1_class_4()).runtimeType.toString(),
+      '(C_101_1_class_4) => bool');
+  Expect.equals(
+      closureC_101_1_class_5(C_101_1_class_5()).runtimeType.toString(),
+      '(C_101_1_class_5) => bool');
+  Expect.equals(
+      closureC_101_1_class_6(C_101_1_class_6()).runtimeType.toString(),
+      '(C_101_1_class_6) => bool');
+  Expect.equals(
+      closureC_111_1_class_1(C_111_1_class_1()).runtimeType.toString(),
+      '(C_111_1_class_1) => bool');
+  Expect.equals(
+      closureC_111_1_class_2(C_111_1_class_2()).runtimeType.toString(),
+      '(C_111_1_class_2) => bool');
+  Expect.equals(
+      closureC_111_1_class_3(C_111_1_class_3()).runtimeType.toString(),
+      '(C_111_1_class_3) => bool');
+  Expect.equals(
+      closureC_111_1_class_4(C_111_1_class_4()).runtimeType.toString(),
+      '(C_111_1_class_4) => bool');
+  Expect.equals(
+      closureC_111_1_class_5(C_111_1_class_5()).runtimeType.toString(),
+      '(C_111_1_class_5) => bool');
+  Expect.equals(
+      closureC_111_1_class_6(C_111_1_class_6()).runtimeType.toString(),
+      '(C_111_1_class_6) => bool');
+  Expect.equals(
+      closureC_111_1_class_7(C_111_1_class_7()).runtimeType.toString(),
+      '(C_111_1_class_7) => bool');
+  Expect.equals(
+      closureC_111_1_class_8(C_111_1_class_8()).runtimeType.toString(),
+      '(C_111_1_class_8) => bool');
+  Expect.equals(
+      closureC_111_1_class_9(C_111_1_class_9()).runtimeType.toString(),
+      '(C_111_1_class_9) => bool');
+  Expect.equals(
+      closureC_011_1_class_1(C_011_1_class_1()).runtimeType.toString(),
+      '(C_011_1_class_1) => bool');
+  Expect.equals(
+      closureC_011_1_class_2(C_011_1_class_2()).runtimeType.toString(),
+      '(C_011_1_class_2) => bool');
+  Expect.equals(
+      closureC_011_1_class_3(C_011_1_class_3()).runtimeType.toString(),
+      '(C_011_1_class_3) => bool');
+  Expect.equals(
+      closureC_011_1_class_4(C_011_1_class_4()).runtimeType.toString(),
+      '(C_011_1_class_4) => bool');
+  Expect.equals(
+      closureC_011_1_class_5(C_011_1_class_5()).runtimeType.toString(),
+      '(C_011_1_class_5) => bool');
+
+  Set<String> uniques = {};
+
+  // f_**1_*;
+  f_001_0(uniques, 2);
+  f_011_1(uniques, 2);
+  f_101_1(uniques, 2);
+  f_111_1(uniques, 2);
+  Expect.equals(4, uniques.length);
+}
diff --git a/pkg/compiler/test/tool/graph_isomorphizer/golden/less_simple/lib_010_0.dart b/pkg/compiler/test/tool/graph_isomorphizer/golden/less_simple/lib_010_0.dart
new file mode 100644
index 0000000..600809f
--- /dev/null
+++ b/pkg/compiler/test/tool/graph_isomorphizer/golden/less_simple/lib_010_0.dart
@@ -0,0 +1,251 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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 was autogenerated by the pkg/compiler/tool/graph_isomorphizer.dart.
+import "package:expect/expect.dart";
+
+import 'libImport.dart';
+
+@pragma('dart2js:noInline')
+typeTest(dynamic t) {
+  if (t is T_010_0) {
+    return true;
+  }
+  if (t is T_010_1) {
+    return true;
+  }
+  if (t is T_011_1) {
+    return true;
+  }
+  if (t is T_110_0_type__1) {
+    return true;
+  }
+  if (t is T_110_0_type__2) {
+    return true;
+  }
+  if (t is T_110_0_type__3) {
+    return true;
+  }
+  if (t is T_110_0_type__4) {
+    return true;
+  }
+  if (t is T_110_0_type__5) {
+    return true;
+  }
+  if (t is T_110_0_type__6) {
+    return true;
+  }
+  if (t is T_110_0_type__7) {
+    return true;
+  }
+  if (t is T_111_1_type__1) {
+    return true;
+  }
+  if (t is T_111_1_type__2) {
+    return true;
+  }
+  if (t is T_111_1_type__3) {
+    return true;
+  }
+  if (t is T_111_1_type__4) {
+    return true;
+  }
+  if (t is T_111_1_type__5) {
+    return true;
+  }
+  if (t is T_111_1_type__6) {
+    return true;
+  }
+  if (t is T_111_1_type__7) {
+    return true;
+  }
+  if (t is T_111_1_type__8) {
+    return true;
+  }
+  if (t is T_111_1_type__9) {
+    return true;
+  }
+  if (t is T_010_1_type__1) {
+    return true;
+  }
+  if (t is T_010_1_type__2) {
+    return true;
+  }
+  if (t is T_010_1_type__3) {
+    return true;
+  }
+  if (t is T_010_1_type__4) {
+    return true;
+  }
+  if (t is T_011_1_type__1) {
+    return true;
+  }
+  if (t is T_011_1_type__2) {
+    return true;
+  }
+  if (t is T_011_1_type__3) {
+    return true;
+  }
+  if (t is T_011_1_type__4) {
+    return true;
+  }
+  if (t is T_011_1_type__5) {
+    return true;
+  }
+  return false;
+}
+
+@pragma('dart2js:noInline')
+g_010_0() {
+  // C_*1*_*;
+  Expect.isFalse(typeTest(C_010_0()));
+  Expect.isFalse(typeTest(C_010_1()));
+  Expect.isFalse(typeTest(C_011_1()));
+  Expect.isFalse(typeTest(C_110_0_class_1()));
+  Expect.isFalse(typeTest(C_110_0_class_2()));
+  Expect.isFalse(typeTest(C_110_0_class_3()));
+  Expect.isFalse(typeTest(C_110_0_class_4()));
+  Expect.isFalse(typeTest(C_110_0_class_5()));
+  Expect.isFalse(typeTest(C_110_0_class_6()));
+  Expect.isFalse(typeTest(C_110_0_class_7()));
+  Expect.isFalse(typeTest(C_111_1_class_1()));
+  Expect.isFalse(typeTest(C_111_1_class_2()));
+  Expect.isFalse(typeTest(C_111_1_class_3()));
+  Expect.isFalse(typeTest(C_111_1_class_4()));
+  Expect.isFalse(typeTest(C_111_1_class_5()));
+  Expect.isFalse(typeTest(C_111_1_class_6()));
+  Expect.isFalse(typeTest(C_111_1_class_7()));
+  Expect.isFalse(typeTest(C_111_1_class_8()));
+  Expect.isFalse(typeTest(C_111_1_class_9()));
+  Expect.isFalse(typeTest(C_010_1_class_1()));
+  Expect.isFalse(typeTest(C_010_1_class_2()));
+  Expect.isFalse(typeTest(C_010_1_class_3()));
+  Expect.isFalse(typeTest(C_010_1_class_4()));
+  Expect.isFalse(typeTest(C_011_1_class_1()));
+  Expect.isFalse(typeTest(C_011_1_class_2()));
+  Expect.isFalse(typeTest(C_011_1_class_3()));
+  Expect.isFalse(typeTest(C_011_1_class_4()));
+  Expect.isFalse(typeTest(C_011_1_class_5()));
+
+  Expect.isTrue(closureC_010_0(C_010_0())(C_010_0()));
+  Expect.isTrue(closureC_010_1(C_010_1())(C_010_1()));
+  Expect.isTrue(closureC_011_1(C_011_1())(C_011_1()));
+  Expect.isTrue(closureC_110_0_class_1(C_110_0_class_1())(C_110_0_class_1()));
+  Expect.isTrue(closureC_110_0_class_2(C_110_0_class_2())(C_110_0_class_2()));
+  Expect.isTrue(closureC_110_0_class_3(C_110_0_class_3())(C_110_0_class_3()));
+  Expect.isTrue(closureC_110_0_class_4(C_110_0_class_4())(C_110_0_class_4()));
+  Expect.isTrue(closureC_110_0_class_5(C_110_0_class_5())(C_110_0_class_5()));
+  Expect.isTrue(closureC_110_0_class_6(C_110_0_class_6())(C_110_0_class_6()));
+  Expect.isTrue(closureC_110_0_class_7(C_110_0_class_7())(C_110_0_class_7()));
+  Expect.isTrue(closureC_111_1_class_1(C_111_1_class_1())(C_111_1_class_1()));
+  Expect.isTrue(closureC_111_1_class_2(C_111_1_class_2())(C_111_1_class_2()));
+  Expect.isTrue(closureC_111_1_class_3(C_111_1_class_3())(C_111_1_class_3()));
+  Expect.isTrue(closureC_111_1_class_4(C_111_1_class_4())(C_111_1_class_4()));
+  Expect.isTrue(closureC_111_1_class_5(C_111_1_class_5())(C_111_1_class_5()));
+  Expect.isTrue(closureC_111_1_class_6(C_111_1_class_6())(C_111_1_class_6()));
+  Expect.isTrue(closureC_111_1_class_7(C_111_1_class_7())(C_111_1_class_7()));
+  Expect.isTrue(closureC_111_1_class_8(C_111_1_class_8())(C_111_1_class_8()));
+  Expect.isTrue(closureC_111_1_class_9(C_111_1_class_9())(C_111_1_class_9()));
+  Expect.isTrue(closureC_010_1_class_1(C_010_1_class_1())(C_010_1_class_1()));
+  Expect.isTrue(closureC_010_1_class_2(C_010_1_class_2())(C_010_1_class_2()));
+  Expect.isTrue(closureC_010_1_class_3(C_010_1_class_3())(C_010_1_class_3()));
+  Expect.isTrue(closureC_010_1_class_4(C_010_1_class_4())(C_010_1_class_4()));
+  Expect.isTrue(closureC_011_1_class_1(C_011_1_class_1())(C_011_1_class_1()));
+  Expect.isTrue(closureC_011_1_class_2(C_011_1_class_2())(C_011_1_class_2()));
+  Expect.isTrue(closureC_011_1_class_3(C_011_1_class_3())(C_011_1_class_3()));
+  Expect.isTrue(closureC_011_1_class_4(C_011_1_class_4())(C_011_1_class_4()));
+  Expect.isTrue(closureC_011_1_class_5(C_011_1_class_5())(C_011_1_class_5()));
+
+  Expect.equals(
+      closureC_010_0(C_010_0()).runtimeType.toString(), '(C_010_0) => bool');
+  Expect.equals(
+      closureC_010_1(C_010_1()).runtimeType.toString(), '(C_010_1) => bool');
+  Expect.equals(
+      closureC_011_1(C_011_1()).runtimeType.toString(), '(C_011_1) => bool');
+  Expect.equals(
+      closureC_110_0_class_1(C_110_0_class_1()).runtimeType.toString(),
+      '(C_110_0_class_1) => bool');
+  Expect.equals(
+      closureC_110_0_class_2(C_110_0_class_2()).runtimeType.toString(),
+      '(C_110_0_class_2) => bool');
+  Expect.equals(
+      closureC_110_0_class_3(C_110_0_class_3()).runtimeType.toString(),
+      '(C_110_0_class_3) => bool');
+  Expect.equals(
+      closureC_110_0_class_4(C_110_0_class_4()).runtimeType.toString(),
+      '(C_110_0_class_4) => bool');
+  Expect.equals(
+      closureC_110_0_class_5(C_110_0_class_5()).runtimeType.toString(),
+      '(C_110_0_class_5) => bool');
+  Expect.equals(
+      closureC_110_0_class_6(C_110_0_class_6()).runtimeType.toString(),
+      '(C_110_0_class_6) => bool');
+  Expect.equals(
+      closureC_110_0_class_7(C_110_0_class_7()).runtimeType.toString(),
+      '(C_110_0_class_7) => bool');
+  Expect.equals(
+      closureC_111_1_class_1(C_111_1_class_1()).runtimeType.toString(),
+      '(C_111_1_class_1) => bool');
+  Expect.equals(
+      closureC_111_1_class_2(C_111_1_class_2()).runtimeType.toString(),
+      '(C_111_1_class_2) => bool');
+  Expect.equals(
+      closureC_111_1_class_3(C_111_1_class_3()).runtimeType.toString(),
+      '(C_111_1_class_3) => bool');
+  Expect.equals(
+      closureC_111_1_class_4(C_111_1_class_4()).runtimeType.toString(),
+      '(C_111_1_class_4) => bool');
+  Expect.equals(
+      closureC_111_1_class_5(C_111_1_class_5()).runtimeType.toString(),
+      '(C_111_1_class_5) => bool');
+  Expect.equals(
+      closureC_111_1_class_6(C_111_1_class_6()).runtimeType.toString(),
+      '(C_111_1_class_6) => bool');
+  Expect.equals(
+      closureC_111_1_class_7(C_111_1_class_7()).runtimeType.toString(),
+      '(C_111_1_class_7) => bool');
+  Expect.equals(
+      closureC_111_1_class_8(C_111_1_class_8()).runtimeType.toString(),
+      '(C_111_1_class_8) => bool');
+  Expect.equals(
+      closureC_111_1_class_9(C_111_1_class_9()).runtimeType.toString(),
+      '(C_111_1_class_9) => bool');
+  Expect.equals(
+      closureC_010_1_class_1(C_010_1_class_1()).runtimeType.toString(),
+      '(C_010_1_class_1) => bool');
+  Expect.equals(
+      closureC_010_1_class_2(C_010_1_class_2()).runtimeType.toString(),
+      '(C_010_1_class_2) => bool');
+  Expect.equals(
+      closureC_010_1_class_3(C_010_1_class_3()).runtimeType.toString(),
+      '(C_010_1_class_3) => bool');
+  Expect.equals(
+      closureC_010_1_class_4(C_010_1_class_4()).runtimeType.toString(),
+      '(C_010_1_class_4) => bool');
+  Expect.equals(
+      closureC_011_1_class_1(C_011_1_class_1()).runtimeType.toString(),
+      '(C_011_1_class_1) => bool');
+  Expect.equals(
+      closureC_011_1_class_2(C_011_1_class_2()).runtimeType.toString(),
+      '(C_011_1_class_2) => bool');
+  Expect.equals(
+      closureC_011_1_class_3(C_011_1_class_3()).runtimeType.toString(),
+      '(C_011_1_class_3) => bool');
+  Expect.equals(
+      closureC_011_1_class_4(C_011_1_class_4()).runtimeType.toString(),
+      '(C_011_1_class_4) => bool');
+  Expect.equals(
+      closureC_011_1_class_5(C_011_1_class_5()).runtimeType.toString(),
+      '(C_011_1_class_5) => bool');
+
+  Set<String> uniques = {};
+
+  // f_*1*_*;
+  f_010_0(uniques, 1);
+  f_010_1(uniques, 1);
+  f_011_1(uniques, 1);
+  f_110_0(uniques, 1);
+  f_111_1(uniques, 1);
+  Expect.equals(5, uniques.length);
+}
diff --git a/pkg/compiler/test/tool/graph_isomorphizer/golden/less_simple/lib_100_0.dart b/pkg/compiler/test/tool/graph_isomorphizer/golden/less_simple/lib_100_0.dart
new file mode 100644
index 0000000..bbf23b8
--- /dev/null
+++ b/pkg/compiler/test/tool/graph_isomorphizer/golden/less_simple/lib_100_0.dart
@@ -0,0 +1,233 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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 was autogenerated by the pkg/compiler/tool/graph_isomorphizer.dart.
+import "package:expect/expect.dart";
+
+import 'libImport.dart';
+
+@pragma('dart2js:noInline')
+typeTest(dynamic t) {
+  if (t is T_100_0) {
+    return true;
+  }
+  if (t is T_110_0) {
+    return true;
+  }
+  if (t is T_101_1) {
+    return true;
+  }
+  if (t is T_111_1) {
+    return true;
+  }
+  if (t is T_110_0_type__1) {
+    return true;
+  }
+  if (t is T_110_0_type__2) {
+    return true;
+  }
+  if (t is T_110_0_type__3) {
+    return true;
+  }
+  if (t is T_110_0_type__4) {
+    return true;
+  }
+  if (t is T_110_0_type__5) {
+    return true;
+  }
+  if (t is T_110_0_type__6) {
+    return true;
+  }
+  if (t is T_110_0_type__7) {
+    return true;
+  }
+  if (t is T_101_1_type__1) {
+    return true;
+  }
+  if (t is T_101_1_type__2) {
+    return true;
+  }
+  if (t is T_101_1_type__3) {
+    return true;
+  }
+  if (t is T_101_1_type__4) {
+    return true;
+  }
+  if (t is T_101_1_type__5) {
+    return true;
+  }
+  if (t is T_101_1_type__6) {
+    return true;
+  }
+  if (t is T_111_1_type__1) {
+    return true;
+  }
+  if (t is T_111_1_type__2) {
+    return true;
+  }
+  if (t is T_111_1_type__3) {
+    return true;
+  }
+  if (t is T_111_1_type__4) {
+    return true;
+  }
+  if (t is T_111_1_type__5) {
+    return true;
+  }
+  if (t is T_111_1_type__6) {
+    return true;
+  }
+  if (t is T_111_1_type__7) {
+    return true;
+  }
+  if (t is T_111_1_type__8) {
+    return true;
+  }
+  if (t is T_111_1_type__9) {
+    return true;
+  }
+  return false;
+}
+
+@pragma('dart2js:noInline')
+g_100_0() {
+  // C_1**_*;
+  Expect.isFalse(typeTest(C_100_0()));
+  Expect.isFalse(typeTest(C_110_0()));
+  Expect.isFalse(typeTest(C_101_1()));
+  Expect.isFalse(typeTest(C_111_1()));
+  Expect.isFalse(typeTest(C_110_0_class_1()));
+  Expect.isFalse(typeTest(C_110_0_class_2()));
+  Expect.isFalse(typeTest(C_110_0_class_3()));
+  Expect.isFalse(typeTest(C_110_0_class_4()));
+  Expect.isFalse(typeTest(C_110_0_class_5()));
+  Expect.isFalse(typeTest(C_110_0_class_6()));
+  Expect.isFalse(typeTest(C_110_0_class_7()));
+  Expect.isFalse(typeTest(C_101_1_class_1()));
+  Expect.isFalse(typeTest(C_101_1_class_2()));
+  Expect.isFalse(typeTest(C_101_1_class_3()));
+  Expect.isFalse(typeTest(C_101_1_class_4()));
+  Expect.isFalse(typeTest(C_101_1_class_5()));
+  Expect.isFalse(typeTest(C_101_1_class_6()));
+  Expect.isFalse(typeTest(C_111_1_class_1()));
+  Expect.isFalse(typeTest(C_111_1_class_2()));
+  Expect.isFalse(typeTest(C_111_1_class_3()));
+  Expect.isFalse(typeTest(C_111_1_class_4()));
+  Expect.isFalse(typeTest(C_111_1_class_5()));
+  Expect.isFalse(typeTest(C_111_1_class_6()));
+  Expect.isFalse(typeTest(C_111_1_class_7()));
+  Expect.isFalse(typeTest(C_111_1_class_8()));
+  Expect.isFalse(typeTest(C_111_1_class_9()));
+
+  Expect.isTrue(closureC_100_0(C_100_0())(C_100_0()));
+  Expect.isTrue(closureC_110_0(C_110_0())(C_110_0()));
+  Expect.isTrue(closureC_101_1(C_101_1())(C_101_1()));
+  Expect.isTrue(closureC_111_1(C_111_1())(C_111_1()));
+  Expect.isTrue(closureC_110_0_class_1(C_110_0_class_1())(C_110_0_class_1()));
+  Expect.isTrue(closureC_110_0_class_2(C_110_0_class_2())(C_110_0_class_2()));
+  Expect.isTrue(closureC_110_0_class_3(C_110_0_class_3())(C_110_0_class_3()));
+  Expect.isTrue(closureC_110_0_class_4(C_110_0_class_4())(C_110_0_class_4()));
+  Expect.isTrue(closureC_110_0_class_5(C_110_0_class_5())(C_110_0_class_5()));
+  Expect.isTrue(closureC_110_0_class_6(C_110_0_class_6())(C_110_0_class_6()));
+  Expect.isTrue(closureC_110_0_class_7(C_110_0_class_7())(C_110_0_class_7()));
+  Expect.isTrue(closureC_101_1_class_1(C_101_1_class_1())(C_101_1_class_1()));
+  Expect.isTrue(closureC_101_1_class_2(C_101_1_class_2())(C_101_1_class_2()));
+  Expect.isTrue(closureC_101_1_class_3(C_101_1_class_3())(C_101_1_class_3()));
+  Expect.isTrue(closureC_101_1_class_4(C_101_1_class_4())(C_101_1_class_4()));
+  Expect.isTrue(closureC_101_1_class_5(C_101_1_class_5())(C_101_1_class_5()));
+  Expect.isTrue(closureC_101_1_class_6(C_101_1_class_6())(C_101_1_class_6()));
+  Expect.isTrue(closureC_111_1_class_1(C_111_1_class_1())(C_111_1_class_1()));
+  Expect.isTrue(closureC_111_1_class_2(C_111_1_class_2())(C_111_1_class_2()));
+  Expect.isTrue(closureC_111_1_class_3(C_111_1_class_3())(C_111_1_class_3()));
+  Expect.isTrue(closureC_111_1_class_4(C_111_1_class_4())(C_111_1_class_4()));
+  Expect.isTrue(closureC_111_1_class_5(C_111_1_class_5())(C_111_1_class_5()));
+  Expect.isTrue(closureC_111_1_class_6(C_111_1_class_6())(C_111_1_class_6()));
+  Expect.isTrue(closureC_111_1_class_7(C_111_1_class_7())(C_111_1_class_7()));
+  Expect.isTrue(closureC_111_1_class_8(C_111_1_class_8())(C_111_1_class_8()));
+  Expect.isTrue(closureC_111_1_class_9(C_111_1_class_9())(C_111_1_class_9()));
+
+  Expect.equals(
+      closureC_100_0(C_100_0()).runtimeType.toString(), '(C_100_0) => bool');
+  Expect.equals(
+      closureC_110_0(C_110_0()).runtimeType.toString(), '(C_110_0) => bool');
+  Expect.equals(
+      closureC_101_1(C_101_1()).runtimeType.toString(), '(C_101_1) => bool');
+  Expect.equals(
+      closureC_111_1(C_111_1()).runtimeType.toString(), '(C_111_1) => bool');
+  Expect.equals(
+      closureC_110_0_class_1(C_110_0_class_1()).runtimeType.toString(),
+      '(C_110_0_class_1) => bool');
+  Expect.equals(
+      closureC_110_0_class_2(C_110_0_class_2()).runtimeType.toString(),
+      '(C_110_0_class_2) => bool');
+  Expect.equals(
+      closureC_110_0_class_3(C_110_0_class_3()).runtimeType.toString(),
+      '(C_110_0_class_3) => bool');
+  Expect.equals(
+      closureC_110_0_class_4(C_110_0_class_4()).runtimeType.toString(),
+      '(C_110_0_class_4) => bool');
+  Expect.equals(
+      closureC_110_0_class_5(C_110_0_class_5()).runtimeType.toString(),
+      '(C_110_0_class_5) => bool');
+  Expect.equals(
+      closureC_110_0_class_6(C_110_0_class_6()).runtimeType.toString(),
+      '(C_110_0_class_6) => bool');
+  Expect.equals(
+      closureC_110_0_class_7(C_110_0_class_7()).runtimeType.toString(),
+      '(C_110_0_class_7) => bool');
+  Expect.equals(
+      closureC_101_1_class_1(C_101_1_class_1()).runtimeType.toString(),
+      '(C_101_1_class_1) => bool');
+  Expect.equals(
+      closureC_101_1_class_2(C_101_1_class_2()).runtimeType.toString(),
+      '(C_101_1_class_2) => bool');
+  Expect.equals(
+      closureC_101_1_class_3(C_101_1_class_3()).runtimeType.toString(),
+      '(C_101_1_class_3) => bool');
+  Expect.equals(
+      closureC_101_1_class_4(C_101_1_class_4()).runtimeType.toString(),
+      '(C_101_1_class_4) => bool');
+  Expect.equals(
+      closureC_101_1_class_5(C_101_1_class_5()).runtimeType.toString(),
+      '(C_101_1_class_5) => bool');
+  Expect.equals(
+      closureC_101_1_class_6(C_101_1_class_6()).runtimeType.toString(),
+      '(C_101_1_class_6) => bool');
+  Expect.equals(
+      closureC_111_1_class_1(C_111_1_class_1()).runtimeType.toString(),
+      '(C_111_1_class_1) => bool');
+  Expect.equals(
+      closureC_111_1_class_2(C_111_1_class_2()).runtimeType.toString(),
+      '(C_111_1_class_2) => bool');
+  Expect.equals(
+      closureC_111_1_class_3(C_111_1_class_3()).runtimeType.toString(),
+      '(C_111_1_class_3) => bool');
+  Expect.equals(
+      closureC_111_1_class_4(C_111_1_class_4()).runtimeType.toString(),
+      '(C_111_1_class_4) => bool');
+  Expect.equals(
+      closureC_111_1_class_5(C_111_1_class_5()).runtimeType.toString(),
+      '(C_111_1_class_5) => bool');
+  Expect.equals(
+      closureC_111_1_class_6(C_111_1_class_6()).runtimeType.toString(),
+      '(C_111_1_class_6) => bool');
+  Expect.equals(
+      closureC_111_1_class_7(C_111_1_class_7()).runtimeType.toString(),
+      '(C_111_1_class_7) => bool');
+  Expect.equals(
+      closureC_111_1_class_8(C_111_1_class_8()).runtimeType.toString(),
+      '(C_111_1_class_8) => bool');
+  Expect.equals(
+      closureC_111_1_class_9(C_111_1_class_9()).runtimeType.toString(),
+      '(C_111_1_class_9) => bool');
+
+  Set<String> uniques = {};
+
+  // f_1**_*;
+  f_100_0(uniques, 0);
+  f_101_1(uniques, 0);
+  f_110_0(uniques, 0);
+  f_111_1(uniques, 0);
+  Expect.equals(4, uniques.length);
+}
diff --git a/pkg/compiler/test/tool/graph_isomorphizer/golden/less_simple/main.dart b/pkg/compiler/test/tool/graph_isomorphizer/golden/less_simple/main.dart
new file mode 100644
index 0000000..5f1c08c
--- /dev/null
+++ b/pkg/compiler/test/tool/graph_isomorphizer/golden/less_simple/main.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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 was autogenerated by the pkg/compiler/tool/graph_isomorphizer.dart.
+import 'lib1.dart';
+import 'lib2.dart';
+import 'lib3.dart';
+import 'lib4.dart';
+
+main() {
+  entryLib1();
+  entryLib2();
+  entryLib3();
+  entryLib4();
+}
diff --git a/pkg/compiler/test/tool/graph_isomorphizer/golden/simple/lib1.dart b/pkg/compiler/test/tool/graph_isomorphizer/golden/simple/lib1.dart
new file mode 100644
index 0000000..d91a48b
--- /dev/null
+++ b/pkg/compiler/test/tool/graph_isomorphizer/golden/simple/lib1.dart
@@ -0,0 +1,11 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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 was autogenerated by the pkg/compiler/tool/graph_isomorphizer.dart.
+import 'lib_100.dart' deferred as b1;
+
+entryLib1() async {
+  await b1.loadLibrary();
+  b1.g_100();
+}
diff --git a/pkg/compiler/test/tool/graph_isomorphizer/golden/simple/lib2.dart b/pkg/compiler/test/tool/graph_isomorphizer/golden/simple/lib2.dart
new file mode 100644
index 0000000..7960202
--- /dev/null
+++ b/pkg/compiler/test/tool/graph_isomorphizer/golden/simple/lib2.dart
@@ -0,0 +1,11 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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 was autogenerated by the pkg/compiler/tool/graph_isomorphizer.dart.
+import 'lib_010.dart' deferred as b2;
+
+entryLib2() async {
+  await b2.loadLibrary();
+  b2.g_010();
+}
diff --git a/pkg/compiler/test/tool/graph_isomorphizer/golden/simple/lib3.dart b/pkg/compiler/test/tool/graph_isomorphizer/golden/simple/lib3.dart
new file mode 100644
index 0000000..e62cd54
--- /dev/null
+++ b/pkg/compiler/test/tool/graph_isomorphizer/golden/simple/lib3.dart
@@ -0,0 +1,11 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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 was autogenerated by the pkg/compiler/tool/graph_isomorphizer.dart.
+import 'lib_001.dart' deferred as b3;
+
+entryLib3() async {
+  await b3.loadLibrary();
+  b3.g_001();
+}
diff --git a/pkg/compiler/test/tool/graph_isomorphizer/golden/simple/libImport.dart b/pkg/compiler/test/tool/graph_isomorphizer/golden/simple/libImport.dart
new file mode 100644
index 0000000..27f453d
--- /dev/null
+++ b/pkg/compiler/test/tool/graph_isomorphizer/golden/simple/libImport.dart
@@ -0,0 +1,272 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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 was autogenerated by the pkg/compiler/tool/graph_isomorphizer.dart.
+import "package:expect/expect.dart";
+
+void v(Set<String> u, String name, int bit) {
+  Expect.isTrue(u.add(name));
+  Expect.equals(name[bit], '1');
+}
+
+class C_100 {
+  const C_100();
+}
+
+class M_100 {}
+
+class T_100 {}
+
+const C_100 iC_100 = const C_100();
+closureC_100(foo) => (C_100 unused) => iC_100.toString() == foo.toString();
+
+class C_101 {
+  const C_101();
+}
+
+class M_101 {}
+
+class T_101 {}
+
+const C_101 iC_101 = const C_101();
+closureC_101(foo) => (C_101 unused) => iC_101.toString() == foo.toString();
+
+class C_111 {
+  const C_111();
+}
+
+class M_111 {}
+
+class T_111 {}
+
+const C_111 iC_111 = const C_111();
+closureC_111(foo) => (C_111 unused) => iC_111.toString() == foo.toString();
+
+class C_010 {
+  const C_010();
+}
+
+class M_010 {}
+
+class T_010 {}
+
+const C_010 iC_010 = const C_010();
+closureC_010(foo) => (C_010 unused) => iC_010.toString() == foo.toString();
+
+class C_011 {
+  const C_011();
+}
+
+class M_011 {}
+
+class T_011 {}
+
+const C_011 iC_011 = const C_011();
+closureC_011(foo) => (C_011 unused) => iC_011.toString() == foo.toString();
+
+class C_001 {
+  const C_001();
+}
+
+class M_001 {}
+
+class T_001 {}
+
+const C_001 iC_001 = const C_001();
+closureC_001(foo) => (C_001 unused) => iC_001.toString() == foo.toString();
+
+class C_101_class_1 extends C_100
+    with M_100, M_101, M_111, M_001
+    implements C_101, C_111, C_001 {
+  const C_101_class_1();
+}
+
+const C_101_class_1 iC_101_class_1 = const C_101_class_1();
+closureC_101_class_1(foo) =>
+    (C_101_class_1 unused) => iC_101_class_1.toString() == foo.toString();
+
+class T_101_type__1 extends T_100
+    with M_100, M_101, M_111, M_001
+    implements T_101, T_111, T_001 {}
+
+class C_101_class_2 extends C_101
+    with M_100, M_101, M_111, M_001
+    implements C_100, C_111, C_001 {
+  const C_101_class_2();
+}
+
+const C_101_class_2 iC_101_class_2 = const C_101_class_2();
+closureC_101_class_2(foo) =>
+    (C_101_class_2 unused) => iC_101_class_2.toString() == foo.toString();
+
+class T_101_type__2 extends T_101
+    with M_100, M_101, M_111, M_001
+    implements T_100, T_111, T_001 {}
+
+class C_101_class_3 extends C_111
+    with M_100, M_101, M_111, M_001
+    implements C_100, C_101, C_001 {
+  const C_101_class_3();
+}
+
+const C_101_class_3 iC_101_class_3 = const C_101_class_3();
+closureC_101_class_3(foo) =>
+    (C_101_class_3 unused) => iC_101_class_3.toString() == foo.toString();
+
+class T_101_type__3 extends T_111
+    with M_100, M_101, M_111, M_001
+    implements T_100, T_101, T_001 {}
+
+class C_101_class_4 extends C_001
+    with M_100, M_101, M_111, M_001
+    implements C_100, C_101, C_111 {
+  const C_101_class_4();
+}
+
+const C_101_class_4 iC_101_class_4 = const C_101_class_4();
+closureC_101_class_4(foo) =>
+    (C_101_class_4 unused) => iC_101_class_4.toString() == foo.toString();
+
+class T_101_type__4 extends T_001
+    with M_100, M_101, M_111, M_001
+    implements T_100, T_101, T_111 {}
+
+class C_111_class_1 extends C_100
+    with M_100, M_101, M_111, M_010, M_011, M_001
+    implements C_101, C_111, C_010, C_011, C_001 {
+  const C_111_class_1();
+}
+
+const C_111_class_1 iC_111_class_1 = const C_111_class_1();
+closureC_111_class_1(foo) =>
+    (C_111_class_1 unused) => iC_111_class_1.toString() == foo.toString();
+
+class T_111_type__1 extends T_100
+    with M_100, M_101, M_111, M_010, M_011, M_001
+    implements T_101, T_111, T_010, T_011, T_001 {}
+
+class C_111_class_2 extends C_101
+    with M_100, M_101, M_111, M_010, M_011, M_001
+    implements C_100, C_111, C_010, C_011, C_001 {
+  const C_111_class_2();
+}
+
+const C_111_class_2 iC_111_class_2 = const C_111_class_2();
+closureC_111_class_2(foo) =>
+    (C_111_class_2 unused) => iC_111_class_2.toString() == foo.toString();
+
+class T_111_type__2 extends T_101
+    with M_100, M_101, M_111, M_010, M_011, M_001
+    implements T_100, T_111, T_010, T_011, T_001 {}
+
+class C_111_class_3 extends C_111
+    with M_100, M_101, M_111, M_010, M_011, M_001
+    implements C_100, C_101, C_010, C_011, C_001 {
+  const C_111_class_3();
+}
+
+const C_111_class_3 iC_111_class_3 = const C_111_class_3();
+closureC_111_class_3(foo) =>
+    (C_111_class_3 unused) => iC_111_class_3.toString() == foo.toString();
+
+class T_111_type__3 extends T_111
+    with M_100, M_101, M_111, M_010, M_011, M_001
+    implements T_100, T_101, T_010, T_011, T_001 {}
+
+class C_111_class_4 extends C_010
+    with M_100, M_101, M_111, M_010, M_011, M_001
+    implements C_100, C_101, C_111, C_011, C_001 {
+  const C_111_class_4();
+}
+
+const C_111_class_4 iC_111_class_4 = const C_111_class_4();
+closureC_111_class_4(foo) =>
+    (C_111_class_4 unused) => iC_111_class_4.toString() == foo.toString();
+
+class T_111_type__4 extends T_010
+    with M_100, M_101, M_111, M_010, M_011, M_001
+    implements T_100, T_101, T_111, T_011, T_001 {}
+
+class C_111_class_5 extends C_011
+    with M_100, M_101, M_111, M_010, M_011, M_001
+    implements C_100, C_101, C_111, C_010, C_001 {
+  const C_111_class_5();
+}
+
+const C_111_class_5 iC_111_class_5 = const C_111_class_5();
+closureC_111_class_5(foo) =>
+    (C_111_class_5 unused) => iC_111_class_5.toString() == foo.toString();
+
+class T_111_type__5 extends T_011
+    with M_100, M_101, M_111, M_010, M_011, M_001
+    implements T_100, T_101, T_111, T_010, T_001 {}
+
+class C_111_class_6 extends C_001
+    with M_100, M_101, M_111, M_010, M_011, M_001
+    implements C_100, C_101, C_111, C_010, C_011 {
+  const C_111_class_6();
+}
+
+const C_111_class_6 iC_111_class_6 = const C_111_class_6();
+closureC_111_class_6(foo) =>
+    (C_111_class_6 unused) => iC_111_class_6.toString() == foo.toString();
+
+class T_111_type__6 extends T_001
+    with M_100, M_101, M_111, M_010, M_011, M_001
+    implements T_100, T_101, T_111, T_010, T_011 {}
+
+class C_011_class_1 extends C_010
+    with M_010, M_011, M_001
+    implements C_011, C_001 {
+  const C_011_class_1();
+}
+
+const C_011_class_1 iC_011_class_1 = const C_011_class_1();
+closureC_011_class_1(foo) =>
+    (C_011_class_1 unused) => iC_011_class_1.toString() == foo.toString();
+
+class T_011_type__1 extends T_010
+    with M_010, M_011, M_001
+    implements T_011, T_001 {}
+
+class C_011_class_2 extends C_011
+    with M_010, M_011, M_001
+    implements C_010, C_001 {
+  const C_011_class_2();
+}
+
+const C_011_class_2 iC_011_class_2 = const C_011_class_2();
+closureC_011_class_2(foo) =>
+    (C_011_class_2 unused) => iC_011_class_2.toString() == foo.toString();
+
+class T_011_type__2 extends T_011
+    with M_010, M_011, M_001
+    implements T_010, T_001 {}
+
+class C_011_class_3 extends C_001
+    with M_010, M_011, M_001
+    implements C_010, C_011 {
+  const C_011_class_3();
+}
+
+const C_011_class_3 iC_011_class_3 = const C_011_class_3();
+closureC_011_class_3(foo) =>
+    (C_011_class_3 unused) => iC_011_class_3.toString() == foo.toString();
+
+class T_011_type__3 extends T_001
+    with M_010, M_011, M_001
+    implements T_010, T_011 {}
+
+@pragma('dart2js:noInline')
+f_100(Set<String> u, int b) => v(u, '100', b);
+@pragma('dart2js:noInline')
+f_101(Set<String> u, int b) => v(u, '101', b);
+@pragma('dart2js:noInline')
+f_111(Set<String> u, int b) => v(u, '111', b);
+@pragma('dart2js:noInline')
+f_010(Set<String> u, int b) => v(u, '010', b);
+@pragma('dart2js:noInline')
+f_011(Set<String> u, int b) => v(u, '011', b);
+@pragma('dart2js:noInline')
+f_001(Set<String> u, int b) => v(u, '001', b);
diff --git a/pkg/compiler/test/tool/graph_isomorphizer/golden/simple/lib_001.dart b/pkg/compiler/test/tool/graph_isomorphizer/golden/simple/lib_001.dart
new file mode 100644
index 0000000..c8be5f5
--- /dev/null
+++ b/pkg/compiler/test/tool/graph_isomorphizer/golden/simple/lib_001.dart
@@ -0,0 +1,127 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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 was autogenerated by the pkg/compiler/tool/graph_isomorphizer.dart.
+import "package:expect/expect.dart";
+
+import 'libImport.dart';
+
+@pragma('dart2js:noInline')
+typeTest(dynamic t) {
+  if (t is T_001) {
+    return true;
+  }
+  if (t is T_101_type__1) {
+    return true;
+  }
+  if (t is T_101_type__2) {
+    return true;
+  }
+  if (t is T_101_type__3) {
+    return true;
+  }
+  if (t is T_101_type__4) {
+    return true;
+  }
+  if (t is T_111_type__1) {
+    return true;
+  }
+  if (t is T_111_type__2) {
+    return true;
+  }
+  if (t is T_111_type__3) {
+    return true;
+  }
+  if (t is T_111_type__4) {
+    return true;
+  }
+  if (t is T_111_type__5) {
+    return true;
+  }
+  if (t is T_111_type__6) {
+    return true;
+  }
+  if (t is T_011_type__1) {
+    return true;
+  }
+  if (t is T_011_type__2) {
+    return true;
+  }
+  if (t is T_011_type__3) {
+    return true;
+  }
+  return false;
+}
+
+@pragma('dart2js:noInline')
+g_001() {
+  // C_**1;
+  Expect.isFalse(typeTest(C_001()));
+  Expect.isFalse(typeTest(C_101_class_1()));
+  Expect.isFalse(typeTest(C_101_class_2()));
+  Expect.isFalse(typeTest(C_101_class_3()));
+  Expect.isFalse(typeTest(C_101_class_4()));
+  Expect.isFalse(typeTest(C_111_class_1()));
+  Expect.isFalse(typeTest(C_111_class_2()));
+  Expect.isFalse(typeTest(C_111_class_3()));
+  Expect.isFalse(typeTest(C_111_class_4()));
+  Expect.isFalse(typeTest(C_111_class_5()));
+  Expect.isFalse(typeTest(C_111_class_6()));
+  Expect.isFalse(typeTest(C_011_class_1()));
+  Expect.isFalse(typeTest(C_011_class_2()));
+  Expect.isFalse(typeTest(C_011_class_3()));
+
+  Expect.isTrue(closureC_001(C_001())(C_001()));
+  Expect.isTrue(closureC_101_class_1(C_101_class_1())(C_101_class_1()));
+  Expect.isTrue(closureC_101_class_2(C_101_class_2())(C_101_class_2()));
+  Expect.isTrue(closureC_101_class_3(C_101_class_3())(C_101_class_3()));
+  Expect.isTrue(closureC_101_class_4(C_101_class_4())(C_101_class_4()));
+  Expect.isTrue(closureC_111_class_1(C_111_class_1())(C_111_class_1()));
+  Expect.isTrue(closureC_111_class_2(C_111_class_2())(C_111_class_2()));
+  Expect.isTrue(closureC_111_class_3(C_111_class_3())(C_111_class_3()));
+  Expect.isTrue(closureC_111_class_4(C_111_class_4())(C_111_class_4()));
+  Expect.isTrue(closureC_111_class_5(C_111_class_5())(C_111_class_5()));
+  Expect.isTrue(closureC_111_class_6(C_111_class_6())(C_111_class_6()));
+  Expect.isTrue(closureC_011_class_1(C_011_class_1())(C_011_class_1()));
+  Expect.isTrue(closureC_011_class_2(C_011_class_2())(C_011_class_2()));
+  Expect.isTrue(closureC_011_class_3(C_011_class_3())(C_011_class_3()));
+
+  Expect.equals(
+      closureC_001(C_001()).runtimeType.toString(), '(C_001) => bool');
+  Expect.equals(closureC_101_class_1(C_101_class_1()).runtimeType.toString(),
+      '(C_101_class_1) => bool');
+  Expect.equals(closureC_101_class_2(C_101_class_2()).runtimeType.toString(),
+      '(C_101_class_2) => bool');
+  Expect.equals(closureC_101_class_3(C_101_class_3()).runtimeType.toString(),
+      '(C_101_class_3) => bool');
+  Expect.equals(closureC_101_class_4(C_101_class_4()).runtimeType.toString(),
+      '(C_101_class_4) => bool');
+  Expect.equals(closureC_111_class_1(C_111_class_1()).runtimeType.toString(),
+      '(C_111_class_1) => bool');
+  Expect.equals(closureC_111_class_2(C_111_class_2()).runtimeType.toString(),
+      '(C_111_class_2) => bool');
+  Expect.equals(closureC_111_class_3(C_111_class_3()).runtimeType.toString(),
+      '(C_111_class_3) => bool');
+  Expect.equals(closureC_111_class_4(C_111_class_4()).runtimeType.toString(),
+      '(C_111_class_4) => bool');
+  Expect.equals(closureC_111_class_5(C_111_class_5()).runtimeType.toString(),
+      '(C_111_class_5) => bool');
+  Expect.equals(closureC_111_class_6(C_111_class_6()).runtimeType.toString(),
+      '(C_111_class_6) => bool');
+  Expect.equals(closureC_011_class_1(C_011_class_1()).runtimeType.toString(),
+      '(C_011_class_1) => bool');
+  Expect.equals(closureC_011_class_2(C_011_class_2()).runtimeType.toString(),
+      '(C_011_class_2) => bool');
+  Expect.equals(closureC_011_class_3(C_011_class_3()).runtimeType.toString(),
+      '(C_011_class_3) => bool');
+
+  Set<String> uniques = {};
+
+  // f_**1;
+  f_001(uniques, 2);
+  f_011(uniques, 2);
+  f_101(uniques, 2);
+  f_111(uniques, 2);
+  Expect.equals(4, uniques.length);
+}
diff --git a/pkg/compiler/test/tool/graph_isomorphizer/golden/simple/lib_010.dart b/pkg/compiler/test/tool/graph_isomorphizer/golden/simple/lib_010.dart
new file mode 100644
index 0000000..6827fe3
--- /dev/null
+++ b/pkg/compiler/test/tool/graph_isomorphizer/golden/simple/lib_010.dart
@@ -0,0 +1,105 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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 was autogenerated by the pkg/compiler/tool/graph_isomorphizer.dart.
+import "package:expect/expect.dart";
+
+import 'libImport.dart';
+
+@pragma('dart2js:noInline')
+typeTest(dynamic t) {
+  if (t is T_010) {
+    return true;
+  }
+  if (t is T_011) {
+    return true;
+  }
+  if (t is T_111_type__1) {
+    return true;
+  }
+  if (t is T_111_type__2) {
+    return true;
+  }
+  if (t is T_111_type__3) {
+    return true;
+  }
+  if (t is T_111_type__4) {
+    return true;
+  }
+  if (t is T_111_type__5) {
+    return true;
+  }
+  if (t is T_111_type__6) {
+    return true;
+  }
+  if (t is T_011_type__1) {
+    return true;
+  }
+  if (t is T_011_type__2) {
+    return true;
+  }
+  if (t is T_011_type__3) {
+    return true;
+  }
+  return false;
+}
+
+@pragma('dart2js:noInline')
+g_010() {
+  // C_*1*;
+  Expect.isFalse(typeTest(C_010()));
+  Expect.isFalse(typeTest(C_011()));
+  Expect.isFalse(typeTest(C_111_class_1()));
+  Expect.isFalse(typeTest(C_111_class_2()));
+  Expect.isFalse(typeTest(C_111_class_3()));
+  Expect.isFalse(typeTest(C_111_class_4()));
+  Expect.isFalse(typeTest(C_111_class_5()));
+  Expect.isFalse(typeTest(C_111_class_6()));
+  Expect.isFalse(typeTest(C_011_class_1()));
+  Expect.isFalse(typeTest(C_011_class_2()));
+  Expect.isFalse(typeTest(C_011_class_3()));
+
+  Expect.isTrue(closureC_010(C_010())(C_010()));
+  Expect.isTrue(closureC_011(C_011())(C_011()));
+  Expect.isTrue(closureC_111_class_1(C_111_class_1())(C_111_class_1()));
+  Expect.isTrue(closureC_111_class_2(C_111_class_2())(C_111_class_2()));
+  Expect.isTrue(closureC_111_class_3(C_111_class_3())(C_111_class_3()));
+  Expect.isTrue(closureC_111_class_4(C_111_class_4())(C_111_class_4()));
+  Expect.isTrue(closureC_111_class_5(C_111_class_5())(C_111_class_5()));
+  Expect.isTrue(closureC_111_class_6(C_111_class_6())(C_111_class_6()));
+  Expect.isTrue(closureC_011_class_1(C_011_class_1())(C_011_class_1()));
+  Expect.isTrue(closureC_011_class_2(C_011_class_2())(C_011_class_2()));
+  Expect.isTrue(closureC_011_class_3(C_011_class_3())(C_011_class_3()));
+
+  Expect.equals(
+      closureC_010(C_010()).runtimeType.toString(), '(C_010) => bool');
+  Expect.equals(
+      closureC_011(C_011()).runtimeType.toString(), '(C_011) => bool');
+  Expect.equals(closureC_111_class_1(C_111_class_1()).runtimeType.toString(),
+      '(C_111_class_1) => bool');
+  Expect.equals(closureC_111_class_2(C_111_class_2()).runtimeType.toString(),
+      '(C_111_class_2) => bool');
+  Expect.equals(closureC_111_class_3(C_111_class_3()).runtimeType.toString(),
+      '(C_111_class_3) => bool');
+  Expect.equals(closureC_111_class_4(C_111_class_4()).runtimeType.toString(),
+      '(C_111_class_4) => bool');
+  Expect.equals(closureC_111_class_5(C_111_class_5()).runtimeType.toString(),
+      '(C_111_class_5) => bool');
+  Expect.equals(closureC_111_class_6(C_111_class_6()).runtimeType.toString(),
+      '(C_111_class_6) => bool');
+  Expect.equals(closureC_011_class_1(C_011_class_1()).runtimeType.toString(),
+      '(C_011_class_1) => bool');
+  Expect.equals(closureC_011_class_2(C_011_class_2()).runtimeType.toString(),
+      '(C_011_class_2) => bool');
+  Expect.equals(closureC_011_class_3(C_011_class_3()).runtimeType.toString(),
+      '(C_011_class_3) => bool');
+
+  Set<String> uniques = {};
+
+  // f_*1*;
+  f_010(uniques, 1);
+  f_011(uniques, 1);
+  f_111(uniques, 1);
+  Expect.equals(3, uniques.length);
+}
diff --git a/pkg/compiler/test/tool/graph_isomorphizer/golden/simple/lib_100.dart b/pkg/compiler/test/tool/graph_isomorphizer/golden/simple/lib_100.dart
new file mode 100644
index 0000000..5f96ca1
--- /dev/null
+++ b/pkg/compiler/test/tool/graph_isomorphizer/golden/simple/lib_100.dart
@@ -0,0 +1,119 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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 was autogenerated by the pkg/compiler/tool/graph_isomorphizer.dart.
+import "package:expect/expect.dart";
+
+import 'libImport.dart';
+
+@pragma('dart2js:noInline')
+typeTest(dynamic t) {
+  if (t is T_100) {
+    return true;
+  }
+  if (t is T_101) {
+    return true;
+  }
+  if (t is T_111) {
+    return true;
+  }
+  if (t is T_101_type__1) {
+    return true;
+  }
+  if (t is T_101_type__2) {
+    return true;
+  }
+  if (t is T_101_type__3) {
+    return true;
+  }
+  if (t is T_101_type__4) {
+    return true;
+  }
+  if (t is T_111_type__1) {
+    return true;
+  }
+  if (t is T_111_type__2) {
+    return true;
+  }
+  if (t is T_111_type__3) {
+    return true;
+  }
+  if (t is T_111_type__4) {
+    return true;
+  }
+  if (t is T_111_type__5) {
+    return true;
+  }
+  if (t is T_111_type__6) {
+    return true;
+  }
+  return false;
+}
+
+@pragma('dart2js:noInline')
+g_100() {
+  // C_1**;
+  Expect.isFalse(typeTest(C_100()));
+  Expect.isFalse(typeTest(C_101()));
+  Expect.isFalse(typeTest(C_111()));
+  Expect.isFalse(typeTest(C_101_class_1()));
+  Expect.isFalse(typeTest(C_101_class_2()));
+  Expect.isFalse(typeTest(C_101_class_3()));
+  Expect.isFalse(typeTest(C_101_class_4()));
+  Expect.isFalse(typeTest(C_111_class_1()));
+  Expect.isFalse(typeTest(C_111_class_2()));
+  Expect.isFalse(typeTest(C_111_class_3()));
+  Expect.isFalse(typeTest(C_111_class_4()));
+  Expect.isFalse(typeTest(C_111_class_5()));
+  Expect.isFalse(typeTest(C_111_class_6()));
+
+  Expect.isTrue(closureC_100(C_100())(C_100()));
+  Expect.isTrue(closureC_101(C_101())(C_101()));
+  Expect.isTrue(closureC_111(C_111())(C_111()));
+  Expect.isTrue(closureC_101_class_1(C_101_class_1())(C_101_class_1()));
+  Expect.isTrue(closureC_101_class_2(C_101_class_2())(C_101_class_2()));
+  Expect.isTrue(closureC_101_class_3(C_101_class_3())(C_101_class_3()));
+  Expect.isTrue(closureC_101_class_4(C_101_class_4())(C_101_class_4()));
+  Expect.isTrue(closureC_111_class_1(C_111_class_1())(C_111_class_1()));
+  Expect.isTrue(closureC_111_class_2(C_111_class_2())(C_111_class_2()));
+  Expect.isTrue(closureC_111_class_3(C_111_class_3())(C_111_class_3()));
+  Expect.isTrue(closureC_111_class_4(C_111_class_4())(C_111_class_4()));
+  Expect.isTrue(closureC_111_class_5(C_111_class_5())(C_111_class_5()));
+  Expect.isTrue(closureC_111_class_6(C_111_class_6())(C_111_class_6()));
+
+  Expect.equals(
+      closureC_100(C_100()).runtimeType.toString(), '(C_100) => bool');
+  Expect.equals(
+      closureC_101(C_101()).runtimeType.toString(), '(C_101) => bool');
+  Expect.equals(
+      closureC_111(C_111()).runtimeType.toString(), '(C_111) => bool');
+  Expect.equals(closureC_101_class_1(C_101_class_1()).runtimeType.toString(),
+      '(C_101_class_1) => bool');
+  Expect.equals(closureC_101_class_2(C_101_class_2()).runtimeType.toString(),
+      '(C_101_class_2) => bool');
+  Expect.equals(closureC_101_class_3(C_101_class_3()).runtimeType.toString(),
+      '(C_101_class_3) => bool');
+  Expect.equals(closureC_101_class_4(C_101_class_4()).runtimeType.toString(),
+      '(C_101_class_4) => bool');
+  Expect.equals(closureC_111_class_1(C_111_class_1()).runtimeType.toString(),
+      '(C_111_class_1) => bool');
+  Expect.equals(closureC_111_class_2(C_111_class_2()).runtimeType.toString(),
+      '(C_111_class_2) => bool');
+  Expect.equals(closureC_111_class_3(C_111_class_3()).runtimeType.toString(),
+      '(C_111_class_3) => bool');
+  Expect.equals(closureC_111_class_4(C_111_class_4()).runtimeType.toString(),
+      '(C_111_class_4) => bool');
+  Expect.equals(closureC_111_class_5(C_111_class_5()).runtimeType.toString(),
+      '(C_111_class_5) => bool');
+  Expect.equals(closureC_111_class_6(C_111_class_6()).runtimeType.toString(),
+      '(C_111_class_6) => bool');
+
+  Set<String> uniques = {};
+
+  // f_1**;
+  f_100(uniques, 0);
+  f_101(uniques, 0);
+  f_111(uniques, 0);
+  Expect.equals(3, uniques.length);
+}
diff --git a/pkg/compiler/test/tool/graph_isomorphizer/golden/simple/main.dart b/pkg/compiler/test/tool/graph_isomorphizer/golden/simple/main.dart
new file mode 100644
index 0000000..afcad53
--- /dev/null
+++ b/pkg/compiler/test/tool/graph_isomorphizer/golden/simple/main.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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 was autogenerated by the pkg/compiler/tool/graph_isomorphizer.dart.
+import 'lib1.dart';
+import 'lib2.dart';
+import 'lib3.dart';
+
+main() {
+  entryLib1();
+  entryLib2();
+  entryLib3();
+}
diff --git a/pkg/compiler/test/tool/graph_isomorphizer/graph_isomorphizer_test.dart b/pkg/compiler/test/tool/graph_isomorphizer/graph_isomorphizer_test.dart
new file mode 100644
index 0000000..228adcd
--- /dev/null
+++ b/pkg/compiler/test/tool/graph_isomorphizer/graph_isomorphizer_test.dart
@@ -0,0 +1,132 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart = 2.
+
+import 'dart:io';
+
+import 'package:expect/expect.dart';
+import 'package:compiler/compiler_new.dart';
+import 'package:dart_style/dart_style.dart' show DartFormatter;
+import '../../helpers/memory_compiler.dart';
+import '../../../tool/graph_isomorphizer.dart';
+
+/// Only generate goldens from the root sdk directory.
+const String goldenDirectory =
+    'pkg/compiler/test/tool/graph_isomorphizer/golden';
+
+/// A map of folder name to graph file lines. When adding new tests, its
+/// probably best to get the ordering of these lines from the compiler.
+const Map<String, List<String>> testCases = {
+  'simple': ['100', '010', '001', '101', '011', '111'],
+  'less_simple': [
+    '1000',
+    '0100',
+    '0010',
+    '0001',
+    '1100',
+    '0101',
+    '1011',
+    '0111',
+    '1111'
+  ]
+};
+
+void unorderedListEquals(List<String> expected, List<String> actual) {
+  var sortedExpected = expected.toList();
+  var sortedActual = actual.toList();
+  sortedExpected.sort();
+  sortedActual.sort();
+  Expect.listEquals(sortedExpected, sortedActual);
+}
+
+void verifyGeneratedFile(
+    String filename, StringBuffer contents, Map<String, String> expectations) {
+  Expect.stringEquals(
+      DartFormatter().format(contents.toString()), expectations[filename]);
+}
+
+GraphIsomorphizer generateFiles(List<String> graphFileLines,
+    {String outDirectory: '.'}) {
+  Map<int, List<List<int>>> names = {};
+  int maxBit = namesFromGraphFileLines(graphFileLines, names);
+  var graphIsomorphizer =
+      GraphIsomorphizer(names, maxBit, outDirectory: outDirectory);
+  graphIsomorphizer.generateFiles();
+  return graphIsomorphizer;
+}
+
+/// Tests isomorphicity of the code generated by the GraphIsomorphizer.
+void verifyGraphFileLines(
+    List<String> graphFileLines, Map<String, String> expectations) async {
+  // Generate files.
+  var graphIsomorphizer = generateFiles(graphFileLines);
+
+  // Verify generated files.
+  verifyGeneratedFile(graphIsomorphizer.mainFilename,
+      graphIsomorphizer.mainBuffer, expectations);
+  verifyGeneratedFile(graphIsomorphizer.rootImportFilename,
+      graphIsomorphizer.rootImportBuffer, expectations);
+  graphIsomorphizer.entryLibBuffers.forEach((filename, contents) {
+    verifyGeneratedFile(filename, contents, expectations);
+  });
+  graphIsomorphizer.mixerLibBuffers.forEach((filename, contents) {
+    verifyGeneratedFile(filename, contents, expectations);
+  });
+
+  // Compile generated code and dump deferred graph shape.
+  var collector = new OutputCollector();
+  await runCompiler(
+      memorySourceFiles: expectations,
+      options: ['--dump-deferred-graph=deferred_graph.txt'],
+      outputProvider: collector);
+  var actual =
+      collector.getOutput("deferred_graph.txt", OutputType.debug).split('\n');
+
+  // Confirm new graph is isomorphic.
+  unorderedListEquals(graphFileLines, actual);
+}
+
+void generateGoldens() {
+  testCases.forEach((name, test) {
+    var graphIsomorphizer =
+        generateFiles(test, outDirectory: goldenDirectory + '/' + name);
+    graphIsomorphizer.writeFiles();
+  });
+}
+
+String getFilename(String path) {
+  var lastSlash = path.lastIndexOf('/');
+  return path.substring(lastSlash + 1, path.length);
+}
+
+void verifyGoldens() {
+  testCases.forEach((name, test) {
+    Map<String, String> expectations = {};
+    var golden = Directory(goldenDirectory + '/' + name);
+    var files = golden.listSync();
+    for (var file in files) {
+      assert(file is File);
+      var contents = (file as File).readAsStringSync();
+      var filename = getFilename(file.path);
+      expectations[filename] = contents;
+    }
+    verifyGraphFileLines(test, expectations);
+  });
+}
+
+void main(List<String> args) {
+  bool generate = false;
+  for (var arg in args) {
+    if (arg == '-g') {
+      generate = true;
+    }
+  }
+
+  if (generate) {
+    generateGoldens();
+  } else {
+    verifyGoldens();
+  }
+}
diff --git a/pkg/compiler/tool/graph_isomorphizer.dart b/pkg/compiler/tool/graph_isomorphizer.dart
new file mode 100644
index 0000000..49894bd
--- /dev/null
+++ b/pkg/compiler/tool/graph_isomorphizer.dart
@@ -0,0 +1,500 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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 tool builds a program with a deferred graph isomorphic to the provided
+/// graph, or generates permutations of bits and the associated files to
+/// generate complex deferred graphs.
+
+/// For example, if 5 bits are permuted, we end up with files like:
+///   lib1.dart
+///   lib2.dart
+///   lib3.dart
+///   lib4.dart
+///   lib5.dart
+///   libB.dart
+///   lib_000_01.dart
+///   lib_000_10.dart
+///   lib_001_00.dart
+///   lib_010_00.dart
+///   lib_100_00.dart
+///   main.dart
+///
+/// Where
+///   main.dart contains main().
+///   libX.dart contains the actual deferred import of the file with the bit at
+///     the X position starting from the left, ie lib1 imports lib_100_00, lib2
+///     imports lib_010_00, etc.
+///   libImport.dart is the 'top of the diamond' which contains all of the code.
+///   lib_XXX_XX.dart invokes all of the functions in libImport which have a
+///     1 bit at that position, ie lib_100_00 invokes all code in libImport with
+///     a first bit of 1, f100_00, f110_00, etc.
+///
+/// Note: There are restrictions to what we can generate. Specifically, certain
+/// OutputUnits can never be empty, namely we will always generate one file for
+/// each entryLib, and because of our dependency on expect, we will always have
+/// a file representing the intersection of all import entities. So, for example
+/// with three bits, each of 100, 010, 001 and 111 must be present in the graph
+/// file, but 110, 101, and 011 are optional.
+
+// TODO(joshualitt): This is a good start for a fuzzer. There is still work to
+// do:
+// * Emit some classes as const and some not
+// * Randomize what we emit as we walk the graph so it is more sparse.
+
+import 'dart:io';
+import 'dart:math';
+import 'package:dart_style/dart_style.dart' show DartFormatter;
+
+typedef NameFunc = String Function(List<int>, int);
+
+/// A simple constant pass through function for bit strings that don't need
+/// special printing, ie stops.
+String passThroughNameFunc(List<int> l, int i) => l[i].toString();
+
+/// Generates all permutations of bits recursively.
+void generatePermutedNames(
+    Map<int, List<List<int>>> names, int maxBit, List<int> bits, int bit) {
+  if (bit == maxBit) {
+    for (int i = 0; i < bits.length; i++) {
+      if (bits[i] == 1) {
+        names.putIfAbsent(i, () => []);
+        names[i].add(List.from(bits));
+      }
+    }
+    return;
+  }
+  generatePermutedNames(names, maxBit, bits, bit + 1);
+  bits[bit] = 1;
+  generatePermutedNames(names, maxBit, bits, bit + 1);
+  bits[bit] = 0;
+}
+
+/// A helper function to generate names from lists of strings of bits.
+int namesFromGraphFileLines(
+    List<String> lines, Map<int, List<List<int>>> names) {
+  int maxBit = 0;
+  for (var line in lines) {
+    List<int> name = [];
+    // Each line should have the same length.
+    assert(maxBit == 0 || maxBit == line.length);
+    maxBit = max(maxBit, line.length);
+    for (int i = 0; i < line.length; i++) {
+      var bit = line[i];
+      if (bit == '1') {
+        name.add(1);
+        (names[i] ??= []).add(name);
+      } else {
+        name.add(0);
+      }
+    }
+  }
+  return maxBit;
+}
+
+/// Parses names from a graph file dumped from dart2js and returns the max bit.
+int namesFromGraphFile(String graphFile, Map<int, List<List<int>>> names) {
+  var lines = File(graphFile).readAsLinesSync();
+  return namesFromGraphFileLines(lines, names);
+}
+
+class ImportData {
+  String import;
+  String entryPoint;
+
+  ImportData(this.import, this.entryPoint);
+}
+
+class GraphIsomorphizer {
+  /// The output directory, only relevant if files are written out.
+  final String outDirectory;
+
+  /// Various buffers for the files the GraphIsomorphizer generates.
+  StringBuffer rootImportBuffer = StringBuffer();
+  StringBuffer mainBuffer = StringBuffer();
+  Map<String, StringBuffer> mixerLibBuffers = {};
+  Map<String, StringBuffer> entryLibBuffers = {};
+
+  /// A map of bit positions to lists of bit lists.
+  final Map<int, List<List<int>>> names;
+
+  /// A map of bit positions to lists of class names.
+  final Map<int, List<String>> classNames = {};
+  final Map<int, List<String>> mixerClassNames = {};
+
+  /// A map of bit positions to lists of mixin names.
+  final Map<int, List<String>> mixinNames = {};
+
+  /// A map of bit positions to lists of class names used only as types.
+  final Map<int, List<String>> typeNames = {};
+  final Map<int, List<String>> mixerTypeNames = {};
+  final Map<int, List<String>> closureNames = {};
+
+  /// We will permute bits up until the maximum bit.
+  int maxBit = 0;
+
+  /// The 'top of the diamond' import file containing all code.
+  final String rootImportFilename = 'libImport.dart';
+
+  /// The main filename.
+  final String mainFilename = 'main.dart';
+
+  /// A bool to omit the comment block.
+  final bool skipCopyright;
+
+  GraphIsomorphizer(this.names, this.maxBit,
+      {this.outDirectory: '.', this.skipCopyright: false});
+
+  void noInlineDecorator(StringBuffer out) {
+    out.write("@pragma('dart2js:noInline')\n");
+  }
+
+  void importExpect(StringBuffer out) {
+    out.write('import "package:expect/expect.dart";\n\n');
+  }
+
+  void newline(StringBuffer out) {
+    out.write('\n');
+  }
+
+  /// Generates the header for a file.
+  void generateHeader(StringBuffer out) {
+    if (!skipCopyright) {
+      out.write("""
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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 was autogenerated by the pkg/compiler/tool/graph_isomorphizer.dart.
+""");
+    }
+  }
+
+  /// Generates the root import, where classes, types, mixins, and closures
+  /// live.
+  void generateRootImport(StringBuffer out) {
+    generateHeader(out);
+    importExpect(out);
+
+    // We verify that each function in libImport is invoked only once from each
+    // mixerLib and that only the correct functions are called, ie for lib_001,
+    // only functions with XX1 are invoked.
+    out.write('void v(Set<String> u, String name, int bit) {\n' +
+        '  Expect.isTrue(u.add(name));\n' +
+        "  Expect.equals(name[bit], '1');\n" +
+        '}\n\n');
+
+    // Sort the names to ensure they are in a canonical order.
+    var nameKeys = names.keys.toList();
+    nameKeys.sort();
+
+    // Generate the 'base' classes, mixins, and types which will be combined to
+    // generate hierarchies. Also generate a const instance per class and a closure
+    // to invoke.
+    Set<String> uniques = {};
+    for (var bitPosition in nameKeys) {
+      var bitsList = names[bitPosition];
+      for (var bits in bitsList) {
+        var name = generateBitString(bits);
+        if (!uniques.add(name)) continue;
+        String className = 'C$name';
+        String mixinName = 'M$name';
+        String typeName = 'T$name';
+        (classNames[bitPosition] ??= []).add(className);
+        (mixinNames[bitPosition] ??= []).add(mixinName);
+        (typeNames[bitPosition] ??= []).add(typeName);
+        (mixerClassNames[bitPosition] ??= []).add(className);
+        (mixerTypeNames[bitPosition] ??= []).add(typeName);
+        out.write('class $className { const $className(); }\n');
+        out.write('class $mixinName {}\n');
+        out.write('class $typeName {}\n');
+        out.write('const $className i$className = const $className();\n');
+        out.write('closure$className(foo) => ($className unused) ');
+        out.write('=> i$className.toString() == foo.toString();\n');
+      }
+    }
+
+    // Generate combined classes and types, as well as const instances and
+    // closures.
+    newline(out);
+    uniques = {};
+    for (var bitPosition in nameKeys) {
+      var bitsList = names[bitPosition];
+      for (var bits in bitsList) {
+        var name = generateBitString(bits);
+        var bitCount = bits.reduce((a, b) => a + b);
+        var baseName = 'C$name';
+        if (!uniques.add(baseName)) continue;
+        if (bitCount > 1) {
+          List<String> classes = [];
+          List<String> mixins = [];
+          List<String> types = [];
+          for (int i = 0; i < bits.length; i++) {
+            if (bits[i] == 1) {
+              classes.addAll(classNames[i]);
+              mixins.addAll(mixinNames[i]);
+              types.addAll(typeNames[i]);
+            }
+          }
+          String mixinString = mixins.join(', ');
+          int count = 1;
+          assert(classes.length == types.length);
+          for (int i = 0; i < classes.length; i++) {
+            var cls = classes[i];
+            var type = types[i];
+            List<String> classImpls = [];
+            List<String> typeImpls = [];
+            if (i > 0) {
+              classImpls.addAll(classes.sublist(0, i));
+              typeImpls.addAll(types.sublist(0, i));
+            }
+            if (i < classes.length - 1) {
+              classImpls.addAll(classes.sublist(i + 1));
+              typeImpls.addAll(types.sublist(i + 1));
+            }
+            var classImplementsString = classImpls.join(', ');
+            String className = '${baseName}_class_${count}';
+            out.write('class $className extends $cls with $mixinString ');
+            out.write(
+                'implements $classImplementsString { const $className(); }\n');
+            out.write('const $className i$className = const $className();\n');
+            out.write('closure$className(foo) => ($className unused) ');
+            out.write('=> i$className.toString() == foo.toString();\n');
+
+            var typeImplementsString = typeImpls.join(', ');
+            String typeName = 'T${name}_type__${count}';
+            out.write('class $typeName extends $type with $mixinString ');
+            out.write('implements $typeImplementsString {}\n');
+            for (int i = 0; i < bits.length; i++) {
+              if (bits[i] == 1) {
+                mixerClassNames[i].add(className);
+                mixerTypeNames[i].add(typeName);
+              }
+            }
+            count++;
+          }
+        }
+      }
+    }
+
+    // Generate functions.
+    newline(out);
+    uniques = {};
+    for (var name in nameKeys) {
+      var bitsList = names[name];
+      for (var bits in bitsList) {
+        var name = generateBitString(bits);
+        if (uniques.add(name)) {
+          noInlineDecorator(out);
+          var stringBits = generateBitString(bits, withStops: false);
+          out.write(
+              "f$name(Set<String> u, int b) => v(u, '$stringBits', b);\n");
+        }
+      }
+    }
+  }
+
+  /// Generates a mixerLib which will be loaded as a deferred library from an entryLib.
+  void generateMixerLib(
+      String name, StringBuffer out, String import, List<int> bits, int bit) {
+    generateHeader(out);
+    importExpect(out);
+    out.write("import '$import';\n\n");
+
+    // create type test.
+    noInlineDecorator(out);
+    out.write('typeTest(dynamic t) {\n');
+    for (var type in mixerTypeNames[bit]) {
+      out.write('  if (t is $type) { return true; }\n');
+    }
+    out.write('  return false;\n');
+    out.write('}\n\n');
+
+    noInlineDecorator(out);
+    out.write('g$name() {\n');
+    out.write('  // C${generateCommentName(bits, bit)};\n');
+
+    // Construct new instances of each class and pass them to the typeTest
+    for (var cls in mixerClassNames[bit]) {
+      out.write('  Expect.isFalse(typeTest($cls()));\n');
+    }
+    newline(out);
+
+    // Invoke the test closure for each class.
+    for (var cls in mixerClassNames[bit]) {
+      out.write('  Expect.isTrue(closure$cls($cls())($cls()));\n');
+    }
+    newline(out);
+
+    // Verify the runtimeTypes of the closures haven't been mangled.
+    for (var cls in mixerClassNames[bit]) {
+      out.write('  Expect.equals(closure$cls($cls()).runtimeType.toString(), ');
+      out.write("'($cls) => bool');\n");
+    }
+    newline(out);
+
+    // Collect the names so we can sort them and put them in a canonical order.
+    int count = 0;
+    List<String> namesBits = [];
+    names[bit].forEach((nameBits) {
+      var nameString = generateBitString(nameBits);
+      namesBits.add(nameString);
+      count++;
+    });
+
+    out.write('  Set<String> uniques = {};\n\n'
+        '  // f${generateCommentName(bits, bit)};\n');
+
+    namesBits.sort();
+    for (var name in namesBits) {
+      out.write('  f$name(uniques, $bit);\n');
+    }
+
+    // We expect 'count' unique strings added to be added to 'uniques'.
+    out.write("  Expect.equals($count, uniques.length);\n"
+        '}\n');
+  }
+
+  /// Generates a string of bits, with optional parameters to control how the
+  /// bits print.
+  String generateBitString(List<int> bits,
+      {NameFunc f: passThroughNameFunc, bool withStops: true}) {
+    int stop = 0;
+    StringBuffer sb = StringBuffer();
+    for (int i = 0; i < bits.length; i++) {
+      if (stop++ % 3 == 0 && withStops) {
+        sb.write('_');
+      }
+      sb.write(f(bits, i));
+    }
+    return sb.toString();
+  }
+
+  /// Generates a pretty bit string for use in comments.
+  String generateCommentName(List<int> bits, int fixBit) {
+    return generateBitString(bits,
+        f: (List<int> bits, int bit) => bit == fixBit ? '1' : '*');
+  }
+
+  /// Generates an entryLib file.
+  void generateEntryLib(StringBuffer out, String mainName, String funcName,
+      String import, int bit) {
+    generateHeader(out);
+    var name = 'b$bit';
+    out.write("import '$import' deferred as $name;\n\n"
+        '$mainName async {\n'
+        '  await $name.loadLibrary();\n'
+        '  $name.g$funcName();\n'
+        '}\n');
+  }
+
+  /// Generates entry and mixer libs for the supplied names.
+  List<ImportData> generateEntryAndMixerLibs() {
+    // Generates each lib_XXX.dart and the associated entryLib file.
+    List<ImportData> importData = [];
+    for (int i = 1; i <= maxBit; i++) {
+      // Generate the bit list representing this library. ie a list of all
+      // 0s with a single 1 bit flipped.
+      int oneBit = i - 1;
+      List<int> bits = [];
+      for (int j = 0; j < maxBit; j++) bits.add(j == oneBit ? 1 : 0);
+
+      // Generate the mixerLib for this entryLib.
+      var name = generateBitString(bits);
+      var mixerLibBuffer = StringBuffer();
+      var mixerLibName = "lib$name.dart";
+      generateMixerLib(name, mixerLibBuffer, rootImportFilename, bits, oneBit);
+      mixerLibBuffers[mixerLibName] = mixerLibBuffer;
+
+      // Generate the entryLib for this mixerLib.
+      var entryLibName = 'lib$i.dart';
+      var entryFuncName = 'entryLib$i()';
+      var entryLibBuffer = StringBuffer();
+      generateEntryLib(entryLibBuffer, entryFuncName, name, mixerLibName, i);
+      entryLibBuffers[entryLibName] = entryLibBuffer;
+
+      // Stash the entry point in entryLib for later reference in the main file.
+      importData.add(ImportData(entryLibName, entryFuncName));
+    }
+    return importData;
+  }
+
+  /// Generates the main file.
+  void generateMain(StringBuffer out, List<ImportData> importData) {
+    generateHeader(mainBuffer);
+    for (var data in importData) {
+      out.write("import '${data.import}';\n");
+    }
+    out.write('\n'
+        'main() {\n');
+    for (var data in importData) {
+      out.write('  ${data.entryPoint};\n');
+    }
+    out.write('}\n');
+  }
+
+  /// Generates all files into buffers.
+  void generateFiles() {
+    generateRootImport(rootImportBuffer);
+    var importData = generateEntryAndMixerLibs();
+    generateMain(mainBuffer, importData);
+  }
+
+  /// Helper to dump contents to file.
+  void writeToFile(String filename, StringBuffer contents) {
+    var file = File(this.outDirectory + '/' + filename);
+    file.createSync(recursive: true);
+    var sink = file.openWrite();
+    sink.write(DartFormatter().format(contents.toString()));
+    sink.close();
+  }
+
+  /// Writes all buffers to files.
+  void writeFiles() {
+    mixerLibBuffers.forEach(writeToFile);
+    entryLibBuffers.forEach(writeToFile);
+    writeToFile(rootImportFilename, rootImportBuffer);
+    writeToFile(mainFilename, mainBuffer);
+  }
+
+  /// Generate and write files.
+  void run() {
+    generateFiles();
+    writeFiles();
+  }
+}
+
+/// Creates a GraphIsomorphizer based on the provided args.
+GraphIsomorphizer createGraphIsomorphizer(List<String> args) {
+  int maxBit = 0;
+  String graphFile = '';
+  String outDirectory = '.';
+
+  for (var arg in args) {
+    if (arg.startsWith('--max-bit')) {
+      maxBit = int.parse(arg.substring('--max-bit='.length));
+    }
+    if (arg.startsWith('--graph-file')) {
+      graphFile = arg.substring('--graph-file='.length);
+    }
+    if (arg.startsWith('--out-dir')) {
+      outDirectory = arg.substring('--out-dir='.length);
+    }
+  }
+
+  // If we don't have a graphFile, then we generate all permutations of bits up
+  // to maxBit.
+  Map<int, List<List<int>>> names = {};
+  if (graphFile.isEmpty) {
+    List<int> bits = List.filled(maxBit, 0);
+    generatePermutedNames(names, maxBit, bits, 0);
+  } else {
+    maxBit = namesFromGraphFile(graphFile, names);
+  }
+  return GraphIsomorphizer(names, maxBit, outDirectory: outDirectory);
+}
+
+void main(List<String> args) {
+  var graphIsomorphizer = createGraphIsomorphizer(args);
+  graphIsomorphizer.run();
+}
diff --git a/pkg/compiler/tool/modular_test_suite.dart b/pkg/compiler/tool/modular_test_suite.dart
index 0aa6ebe..780c182 100644
--- a/pkg/compiler/tool/modular_test_suite.dart
+++ b/pkg/compiler/tool/modular_test_suite.dart
@@ -54,7 +54,7 @@
         new IOPipeline([
           SourceToDillStep(),
           ComputeClosedWorldStep(),
-          GlobalAnalysisStep(),
+          LegacyGlobalAnalysisStep(),
           LegacyDart2jsCodegenStep(codeId0),
           LegacyDart2jsCodegenStep(codeId1),
           LegacyDart2jsEmissionStep(),
@@ -312,6 +312,8 @@
       for (String flag in flags) '--enable-experiment=$flag',
       '${Flags.readClosedWorld}=${toUri(module, closedWorldId)}',
       '${Flags.writeData}=${toUri(module, globalDataId)}',
+      // TODO(joshualitt): delete this flag after google3 roll
+      '${Flags.noClosedWorldInData}',
     ];
     var result =
         await _runProcess(Platform.resolvedExecutable, args, root.toFilePath());
@@ -425,6 +427,50 @@
   }
 }
 
+// TODO(joshualitt): delete after google3 roll.
+class LegacyGlobalAnalysisStep 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");
+  }
+}
+
 // 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.
diff --git a/pkg/dart_internal/lib/extract_type_arguments.dart b/pkg/dart_internal/lib/extract_type_arguments.dart
index 4275e70..6a02827 100644
--- a/pkg/dart_internal/lib/extract_type_arguments.dart
+++ b/pkg/dart_internal/lib/extract_type_arguments.dart
@@ -9,7 +9,6 @@
 //
 // Only this exact special file is allowed to import "dart:_internal" without
 // causing a compile error.
-// ignore: import_internal_library
 import 'dart:_internal' as internal;
 
 /// Given an [Iterable], invokes [extract], passing the [iterable]'s type
diff --git a/pkg/dartdev/README.md b/pkg/dartdev/README.md
index ef1c6c9..eaee08f 100644
--- a/pkg/dartdev/README.md
+++ b/pkg/dartdev/README.md
@@ -9,8 +9,8 @@
 -h, --help                 Print this usage information.
 -v, --verbose              Show additional command output.
     --version              Print the Dart SDK version.
-    --enable-analytics     Enable anonymous analytics.
-    --disable-analytics    Disable anonymous analytics.
+    --enable-analytics     Enable analytics.
+    --disable-analytics    Disable analytics.
 
 Available commands:
   analyze   Analyze the project's Dart code.
diff --git a/pkg/dartdev/lib/dartdev.dart b/pkg/dartdev/lib/dartdev.dart
index a8f9780..b72fbba 100644
--- a/pkg/dartdev/lib/dartdev.dart
+++ b/pkg/dartdev/lib/dartdev.dart
@@ -79,9 +79,9 @@
     argParser.addFlag('version',
         negatable: false, help: 'Print the Dart SDK version.');
     argParser.addFlag('enable-analytics',
-        negatable: false, help: 'Enable anonymous analytics.');
+        negatable: false, help: 'Enable analytics.');
     argParser.addFlag('disable-analytics',
-        negatable: false, help: 'Disable anonymous analytics.');
+        negatable: false, help: 'Disable analytics.');
 
     argParser.addFlag('diagnostics',
         negatable: false, help: 'Show tool diagnostic output.', hide: !verbose);
@@ -89,7 +89,7 @@
     argParser.addFlag(
       'analytics',
       negatable: true,
-      help: 'Disable anonymous analytics for this `dart *` run',
+      help: 'Disable analytics for this `dart *` run',
       hide: true,
     );
 
@@ -152,7 +152,7 @@
     } else if (topLevelResults['enable-analytics']) {
       analytics.enabled = true;
 
-      // Alert the user again that anonymous data will be collected.
+      // Alert the user again that data will be collected.
       print(analyticsNoticeOnFirstRunMessage);
       return 0;
     }
diff --git a/pkg/dartdev/lib/src/analysis_server.dart b/pkg/dartdev/lib/src/analysis_server.dart
index 0f616f8..2908f51 100644
--- a/pkg/dartdev/lib/src/analysis_server.dart
+++ b/pkg/dartdev/lib/src/analysis_server.dart
@@ -16,10 +16,10 @@
 
 /// A class to provide an API wrapper around an analysis server process.
 class AnalysisServer {
-  AnalysisServer(this.sdkPath, this.directory);
+  AnalysisServer(this.sdkPath, this.analysisRoot);
 
   final Directory sdkPath;
-  final Directory directory;
+  final FileSystemEntity analysisRoot;
 
   Process _process;
 
@@ -98,8 +98,8 @@
     //
     // The call to absolute.resolveSymbolicLinksSync() canonicalizes the path to
     // be passed to the analysis server.
-    var dirPath = trimEnd(
-      directory.absolute.resolveSymbolicLinksSync(),
+    var analysisRootPath = trimEnd(
+      analysisRoot.absolute.resolveSymbolicLinksSync(),
       path.context.separator,
     );
 
@@ -115,7 +115,7 @@
 
     // ignore: unawaited_futures
     _sendCommand('analysis.setAnalysisRoots', params: <String, dynamic>{
-      'included': [dirPath],
+      'included': [analysisRootPath],
       'excluded': <String>[]
     });
   }
@@ -251,6 +251,10 @@
 
   String get correction => json['correction'] as String;
 
+  int get endColumn => json['location']['endColumn'] as int;
+
+  int get endLine => json['location']['endLine'] as int;
+
   String get file => json['location']['file'] as String;
 
   int get startLine => json['location']['startLine'] as int;
@@ -307,11 +311,19 @@
 
   int get column => json['location']['startColumn'] as int;
 
+  int get endColumn => json['location']['endColumn'] as int;
+
+  int get endLine => json['location']['endLine'] as int;
+
   String get filePath => json['location']['file'] as String;
 
+  int get length => json['location']['length'] as int;
+
   int get line => json['location']['startLine'] as int;
 
   String get message => json['message'] as String;
+
+  int get offset => json['location']['offset'] as int;
 }
 
 class FileAnalysisErrors {
diff --git a/pkg/dartdev/lib/src/analytics.dart b/pkg/dartdev/lib/src/analytics.dart
index c9b1edf..e5e10de 100644
--- a/pkg/dartdev/lib/src/analytics.dart
+++ b/pkg/dartdev/lib/src/analytics.dart
@@ -14,11 +14,11 @@
 
 const String analyticsNoticeOnFirstRunMessage = '''
   ╔════════════════════════════════════════════════════════════════════════════╗
-  ║ The Dart tool uses Google Analytics to anonymously report feature usage    ║
-  ║ statistics and to send basic crash reports. This data is used to help      ║
-  ║ improve the Dart platform and tools over time.                             ║
+  ║ The Dart tool uses Google Analytics to report feature usage 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 analytics, run:                          ║
+  ║ To disable reporting of analytics, run:                                    ║
   ║                                                                            ║
   ║   dart --disable-analytics                                                 ║
   ║                                                                            ║
@@ -26,7 +26,7 @@
 ''';
 const String analyticsDisabledNoticeMessage = '''
   ╔════════════════════════════════════════════════════════════════════════════╗
-  ║ Anonymous analytics reporting disabled. In order to enable it, run:        ║
+  ║ Analytics reporting disabled. In order to enable it, run:                  ║
   ║                                                                            ║
   ║   dart --enable-analytics                                                  ║
   ║                                                                            ║
diff --git a/pkg/dartdev/lib/src/commands/analyze.dart b/pkg/dartdev/lib/src/commands/analyze.dart
index cbb4270..3292669 100644
--- a/pkg/dartdev/lib/src/commands/analyze.dart
+++ b/pkg/dartdev/lib/src/commands/analyze.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'dart:async';
+import 'dart:convert';
 import 'dart:io' as io;
 
 import 'package:cli_util/cli_logging.dart';
@@ -35,7 +36,7 @@
   static final int _return = '\r'.codeUnitAt(0);
 
   AnalyzeCommand({bool verbose = false})
-      : super(cmdName, "Analyze the project's Dart code.") {
+      : super(cmdName, 'Analyze Dart code in a directory.') {
     argParser
       ..addFlag('fatal-infos',
           help: 'Treat info level issues as fatal.', negatable: false)
@@ -47,12 +48,13 @@
         'format',
         valueHelp: 'value',
         help: 'Specifies the format to display errors.',
-        allowed: ['default', 'machine'],
+        allowed: ['default', 'json', '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.',
+          'json': 'A machine readable output in a JSON format.',
           '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 '
@@ -68,28 +70,40 @@
   @override
   FutureOr<int> run() async {
     if (argResults.rest.length > 1) {
-      usageException('Only one directory is expected.');
+      usageException('Only one directory or file is expected.');
     }
 
-    // find directory from argResults.rest
-    var dir = argResults.rest.isEmpty
-        ? io.Directory.current
-        : io.Directory(argResults.rest.single);
-    if (!dir.existsSync()) {
-      usageException("Directory doesn't exist: ${dir.path}");
+    // find target from argResults.rest
+    io.FileSystemEntity target;
+    io.Directory relativeToDir;
+    if (argResults.rest.isEmpty) {
+      target = io.Directory.current;
+      relativeToDir = target;
+    } else {
+      var targetPath = argResults.rest.single;
+      if (io.Directory(targetPath).existsSync()) {
+        target = io.Directory(targetPath);
+        relativeToDir = target;
+      } else if (io.File(targetPath).existsSync()) {
+        target = io.File(targetPath);
+        relativeToDir = target.parent;
+      } else {
+        usageException("Directory or file doesn't exist: $targetPath");
+      }
     }
 
     final List<AnalysisError> errors = <AnalysisError>[];
 
     final machineFormat = argResults['format'] == 'machine';
+    final jsonFormat = argResults['format'] == 'json';
 
     var progress = machineFormat
         ? null
-        : log.progress('Analyzing ${path.basename(dir.path)}');
+        : log.progress('Analyzing ${path.basename(target.path)}');
 
     final AnalysisServer server = AnalysisServer(
       io.Directory(sdk.sdkPath),
-      dir,
+      target,
     );
 
     server.onErrors.listen((FileAnalysisErrors fileErrors) {
@@ -127,8 +141,11 @@
 
     if (machineFormat) {
       emitMachineFormat(log, errors);
+    } else if (jsonFormat) {
+      emitJsonFormat(log, errors);
     } else {
-      emitDefaultFormat(log, errors, relativeToDir: dir, verbose: verbose);
+      emitDefaultFormat(log, errors,
+          relativeToDir: relativeToDir, verbose: verbose);
     }
 
     bool hasErrors = false;
@@ -180,7 +197,7 @@
       if (error.isError) {
         severity = ansi.error(severity);
       }
-      var filePath = _relativePath(error.file, relativeToDir?.path);
+      var filePath = _relativePath(error.file, relativeToDir);
       var codeRef = error.code;
       // If we're in verbose mode, write any error urls instead of error codes.
       if (error.url != null && verbose) {
@@ -207,7 +224,7 @@
 
       // Add any context messages as bullet list items.
       for (var message in error.contextMessages) {
-        var contextPath = _relativePath(error.file, relativeToDir?.path);
+        var contextPath = _relativePath(error.file, relativeToDir);
         var messageSentenceFragment = trimEnd(message.message, '.');
 
         log.stdout('$_bodyIndent'
@@ -222,8 +239,70 @@
     log.stdout('$errorCount ${pluralize('issue', errorCount)} found.');
   }
 
-  /// Return a relative path if it is a shorter reference than the given path.
-  static String _relativePath(String givenPath, String fromPath) {
+  @visibleForTesting
+  static void emitJsonFormat(Logger log, List<AnalysisError> errors) {
+    Map<String, dynamic> location(
+            String filePath, Map<String, dynamic> range) =>
+        {
+          'file': filePath,
+          'range': range,
+        };
+
+    Map<String, dynamic> position(int offset, int line, int column) => {
+          'offset': offset,
+          'line': line,
+          'column': column,
+        };
+
+    Map<String, dynamic> range(
+            Map<String, dynamic> start, Map<String, dynamic> end) =>
+        {
+          'start': start,
+          'end': end,
+        };
+
+    var diagnostics = <Map<String, dynamic>>[];
+    for (final AnalysisError error in errors) {
+      var contextMessages = [];
+      for (var contextMessage in error.contextMessages) {
+        var startOffset = contextMessage.offset;
+        contextMessages.add({
+          'location': location(
+              contextMessage.filePath,
+              range(
+                  position(
+                      startOffset, contextMessage.line, contextMessage.column),
+                  position(startOffset + contextMessage.length,
+                      contextMessage.endLine, contextMessage.endColumn))),
+          'message': contextMessage.message,
+        });
+      }
+      var startOffset = error.offset;
+      diagnostics.add({
+        'code': error.code,
+        'severity': error.severity,
+        'type': error.type,
+        'location': location(
+            error.file,
+            range(
+                position(startOffset, error.startLine, error.startColumn),
+                position(startOffset + error.length, error.endLine,
+                    error.endColumn))),
+        'problemMessage': error.message,
+        if (error.correction != null) 'correctionMessage': error.correction,
+        if (contextMessages.isNotEmpty) 'contextMessages': contextMessages,
+        if (error.url != null) 'documentation': error.url,
+      });
+    }
+    log.stdout(json.encode({
+      'version': 1,
+      'diagnostics': diagnostics,
+    }));
+  }
+
+  /// Return a relative path if it is a shorter reference than the given dir.
+  static String _relativePath(String givenPath, io.Directory fromDir) {
+    String fromPath = fromDir?.absolute?.resolveSymbolicLinksSync();
     String relative = path.relative(givenPath, from: fromPath);
     return relative.length <= givenPath.length ? relative : givenPath;
   }
diff --git a/pkg/dartdev/lib/src/commands/compile.dart b/pkg/dartdev/lib/src/commands/compile.dart
index 2e6da52..0dea2b7 100644
--- a/pkg/dartdev/lib/src/commands/compile.dart
+++ b/pkg/dartdev/lib/src/commands/compile.dart
@@ -193,14 +193,23 @@
   }
 
   @override
-  String get invocation => '${super.invocation} <dart entry point>';
+  String get invocation {
+    String msg = '${super.invocation} <dart entry point>';
+    if (isJitSnapshot) {
+      msg += ' [<training arguments>]';
+    }
+    return msg;
+  }
+
+  bool get isJitSnapshot => commandName == jitSnapshotCmdName;
 
   @override
   FutureOr<int> run() async {
-    // We expect a single rest argument; the dart entry point.
-    if (argResults.rest.length != 1) {
+    if (argResults.rest.isEmpty) {
       // This throws.
       usageException('Missing Dart entry point.');
+    } else if (!isJitSnapshot && argResults.rest.length > 1) {
+      usageException('Unexpected arguments after Dart entry point.');
     }
 
     final String sourcePath = argResults.rest[0];
@@ -232,6 +241,11 @@
     }
     args.add(path.canonicalize(sourcePath));
 
+    // Add the training arguments.
+    if (argResults.rest.length > 1) {
+      args.addAll(argResults.rest.sublist(1));
+    }
+
     log.stdout('Compiling $sourcePath to $commandName file $outputFile.');
     // TODO(bkonyi): perform compilation in same process.
     final process = await startDartProcess(sdk, args);
diff --git a/pkg/dartdev/lib/src/commands/create.dart b/pkg/dartdev/lib/src/commands/create.dart
index e8aecd4..d387bd4 100644
--- a/pkg/dartdev/lib/src/commands/create.dart
+++ b/pkg/dartdev/lib/src/commands/create.dart
@@ -8,10 +8,11 @@
 import 'dart:math' as math;
 
 import 'package:path/path.dart' as p;
-import 'package:stagehand/stagehand.dart' as stagehand;
 
 import '../core.dart';
 import '../sdk.dart';
+import '../templates.dart';
+import '../utils.dart';
 
 /// A command to create a new project from a set of templates.
 class CreateCommand extends DartdevCommand {
@@ -19,21 +20,11 @@
 
   static String defaultTemplateId = 'console-simple';
 
-  static List<String> legalTemplateIds = [
-    'console-simple',
-    'console-full',
-    'package-simple',
-    'web-simple'
-  ];
-
-  static Iterable<stagehand.Generator> get generators =>
-      legalTemplateIds.map(retrieveTemplateGenerator);
-
-  static stagehand.Generator retrieveTemplateGenerator(String templateId) =>
-      stagehand.getGenerator(templateId);
+  static final List<String> legalTemplateIds =
+      generators.map((generator) => generator.id).toList();
 
   CreateCommand({bool verbose = false})
-      : super(cmdName, 'Create a new project.') {
+      : super(cmdName, 'Create a new Dart project.') {
     argParser.addOption(
       'template',
       allowed: legalTemplateIds,
@@ -76,7 +67,8 @@
     String templateId = argResults['template'];
 
     String dir = argResults.rest.first;
-    var targetDir = io.Directory(dir);
+    var targetDir = io.Directory(dir).absolute;
+    dir = targetDir.path;
     if (targetDir.existsSync() && !argResults['force']) {
       log.stderr(
         "Directory '$dir' already exists "
@@ -85,15 +77,27 @@
       return 73;
     }
 
+    String projectName = p.basename(dir);
+    if (projectName == '.') {
+      projectName = p.basename(io.Directory.current.path);
+    }
+    projectName = normalizeProjectName(projectName);
+
+    if (!isValidPackageName(projectName)) {
+      log.stderr('"$projectName" is not a valid Dart project name.\n\n'
+          'See https://dart.dev/tools/pub/pubspec#name for more information.');
+      return 73;
+    }
+
     log.stdout(
-      'Creating ${log.ansi.emphasized(p.absolute(dir))} '
+      'Creating ${log.ansi.emphasized(projectName)} '
       'using template $templateId...',
     );
     log.stdout('');
 
-    var generator = retrieveTemplateGenerator(templateId);
-    await generator.generate(
-      p.basename(dir),
+    var generator = getGenerator(templateId);
+    generator.generate(
+      projectName,
       DirectoryGeneratorTarget(generator, io.Directory(dir)),
     );
 
@@ -130,11 +134,12 @@
     }
 
     log.stdout('');
-    log.stdout('Created project $dir! In order to get started, type:');
+    log.stdout(
+        'Created project $projectName in ${p.relative(dir)}! In order to get '
+        'started, run the following commands:');
     log.stdout('');
     log.stdout(log.ansi.emphasized('  cd ${p.relative(dir)}'));
-    // TODO(devoncarew): Once we have a 'run' command, print out here how to run
-    // the app.
+    log.stdout(log.ansi.emphasized('  dart run'));
     log.stdout('');
 
     return 0;
@@ -151,7 +156,7 @@
   }
 
   String _availableTemplatesJson() {
-    var items = generators.map((stagehand.Generator generator) {
+    var items = generators.map((Generator generator) {
       var m = {
         'name': generator.id,
         'label': generator.label,
@@ -171,22 +176,24 @@
   }
 }
 
-class DirectoryGeneratorTarget extends stagehand.GeneratorTarget {
-  final stagehand.Generator generator;
+class DirectoryGeneratorTarget extends GeneratorTarget {
+  final Generator generator;
   final io.Directory dir;
 
   DirectoryGeneratorTarget(this.generator, this.dir) {
-    dir.createSync();
+    if (!dir.existsSync()) {
+      dir.createSync();
+    }
   }
 
   @override
-  Future createFile(String path, List<int> contents) async {
+  void createFile(String path, List<int> contents) {
     io.File file = io.File(p.join(dir.path, path));
 
     String name = p.relative(file.path, from: dir.path);
     log.stdout('  $name');
 
-    await file.create(recursive: true);
-    await file.writeAsBytes(contents);
+    file.createSync(recursive: true);
+    file.writeAsBytesSync(contents);
   }
 }
diff --git a/pkg/dartdev/lib/src/commands/run.dart b/pkg/dartdev/lib/src/commands/run.dart
index 45bfd1e..db32bfe 100644
--- a/pkg/dartdev/lib/src/commands/run.dart
+++ b/pkg/dartdev/lib/src/commands/run.dart
@@ -243,13 +243,18 @@
 class _DebuggingSession {
   Future<bool> start(
       String host, String port, bool disableServiceAuthCodes) async {
-    final serviceInfo = await Service.getInfo();
     final ddsSnapshot = (dirname(sdk.dart).endsWith('bin'))
         ? sdk.ddsSnapshot
         : absolute(dirname(sdk.dart), 'gen', 'dds.dart.snapshot');
     if (!Sdk.checkArtifactExists(ddsSnapshot)) {
       return false;
     }
+    ServiceProtocolInfo serviceInfo = await Service.getInfo();
+    // Wait for VM service to publish its connection info.
+    while (serviceInfo.serverUri == null) {
+      await Future.delayed(Duration(milliseconds: 10));
+      serviceInfo = await Service.getInfo();
+    }
     final process = await Process.start(
         sdk.dart,
         [
diff --git a/pkg/dartdev/lib/src/commands/test.dart b/pkg/dartdev/lib/src/commands/test.dart
index b010f54..7261896 100644
--- a/pkg/dartdev/lib/src/commands/test.dart
+++ b/pkg/dartdev/lib/src/commands/test.dart
@@ -17,7 +17,7 @@
 class TestCommand extends DartdevCommand {
   static const String cmdName = 'test';
 
-  TestCommand() : super(cmdName, 'Run tests in this package.');
+  TestCommand() : super(cmdName, 'Run tests for a project.');
 
   // 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
diff --git a/pkg/dartdev/lib/src/templates.dart b/pkg/dartdev/lib/src/templates.dart
new file mode 100644
index 0000000..0b5aa0d
--- /dev/null
+++ b/pkg/dartdev/lib/src/templates.dart
@@ -0,0 +1,195 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:convert' show utf8;
+
+import 'package:meta/meta.dart';
+
+import 'templates/console_full.dart';
+import 'templates/console_simple.dart';
+import 'templates/package_simple.dart';
+import 'templates/server_simple.dart';
+import 'templates/web_simple.dart';
+
+final _substituteRegExp = RegExp(r'__([a-zA-Z]+)__');
+final _nonValidSubstituteRegExp = RegExp('[^a-zA-Z]');
+
+final List<Generator> generators = [
+  ConsoleSimpleGenerator(),
+  ConsoleFullGenerator(),
+  PackageSimpleGenerator(),
+  ServerSimpleGenerator(),
+  WebSimpleGenerator(),
+];
+
+Generator getGenerator(String id) =>
+    generators.firstWhere((g) => g.id == id, orElse: () => null);
+
+/// An abstract class which both defines a template generator and can generate a
+/// user project based on this template.
+abstract class Generator implements Comparable<Generator> {
+  final String id;
+  final String label;
+  final String description;
+  final List<String> categories;
+
+  final List<TemplateFile> files = [];
+  TemplateFile _entrypoint;
+
+  Generator(
+    this.id,
+    this.label,
+    this.description, {
+    this.categories = const [],
+  });
+
+  /// The entrypoint of the application; the main file for the project, which an
+  /// IDE might open after creating the project.
+  TemplateFile get entrypoint => _entrypoint;
+
+  TemplateFile addFile(String path, String contents) {
+    return addTemplateFile(TemplateFile(path, contents));
+  }
+
+  /// Add a new template file.
+  TemplateFile addTemplateFile(TemplateFile file) {
+    files.add(file);
+    return file;
+  }
+
+  /// Return the template file wih the given [path].
+  TemplateFile getFile(String path) =>
+      files.firstWhere((file) => file.path == path, orElse: () => null);
+
+  /// Set the main entrypoint of this template. This is the 'most important'
+  /// file of this template. An IDE might use this information to open this file
+  /// after the user's project is generated.
+  void setEntrypoint(TemplateFile entrypoint) {
+    if (_entrypoint != null) throw StateError('entrypoint already set');
+    if (entrypoint == null) throw StateError('entrypoint is null');
+    _entrypoint = entrypoint;
+  }
+
+  void generate(
+    String projectName,
+    GeneratorTarget target, {
+    Map<String, String> additionalVars,
+  }) {
+    final vars = {
+      'projectName': projectName,
+      'description': description,
+      'year': DateTime.now().year.toString(),
+      'author': '<your name>',
+      if (additionalVars != null) ...additionalVars,
+    };
+
+    for (TemplateFile file in files) {
+      final resultFile = file.runSubstitution(vars);
+      final filePath = resultFile.path;
+      target.createFile(filePath, resultFile.content);
+    }
+  }
+
+  int numFiles() => files.length;
+
+  @override
+  int compareTo(Generator other) =>
+      id.toLowerCase().compareTo(other.id.toLowerCase());
+
+  /// Return some user facing instructions about how to finish installation of
+  /// the template.
+  String getInstallInstructions() => '';
+
+  @override
+  String toString() => '[$id: $description]';
+}
+
+/// An abstract implementation of a [Generator].
+abstract class DefaultGenerator extends Generator {
+  DefaultGenerator(
+    String id,
+    String label,
+    String description, {
+    List<String> categories = const [],
+  }) : super(id, label, description, categories: categories);
+}
+
+/// A target for a [Generator]. This class knows how to create files given a
+/// path for the file (relative to the particular [GeneratorTarget] instance),
+/// and the binary content for the file.
+abstract class GeneratorTarget {
+  /// Create a file at the given path with the given contents.
+  void createFile(String path, List<int> contents);
+}
+
+/// This class represents a file in a generator template. The contents could
+/// either be binary or text. If text, the contents may contain mustache
+/// variables that can be substituted (`__myVar__`).
+class TemplateFile {
+  final String path;
+  final String content;
+
+  TemplateFile(this.path, this.content);
+
+  FileContents runSubstitution(Map<String, String> parameters) {
+    if (path == 'pubspec.yaml' && parameters['author'] == '<your name>') {
+      parameters = Map.from(parameters);
+      parameters['author'] = 'Your Name';
+    }
+
+    final newPath = substituteVars(path, parameters);
+    final newContents = _createContent(parameters);
+
+    return FileContents(newPath, newContents);
+  }
+
+  List<int> _createContent(Map<String, String> vars) {
+    return utf8.encode(substituteVars(content, vars));
+  }
+}
+
+class FileContents {
+  final String path;
+  final List<int> content;
+
+  FileContents(this.path, this.content);
+}
+
+/// Given a `String` [str] with mustache templates, and a [Map] of String key /
+/// value pairs, substitute all instances of `__key__` for `value`. I.e.,
+///
+/// ```
+/// Foo __projectName__ baz.
+/// ```
+///
+/// and
+///
+/// ```
+/// {'projectName': 'bar'}
+/// ```
+///
+/// becomes:
+///
+/// ```
+/// Foo bar baz.
+/// ```
+///
+/// A key value can only be an ASCII string made up of letters: A-Z, a-z.
+/// No whitespace, numbers, or other characters are allowed.
+@visibleForTesting
+String substituteVars(String str, Map<String, String> vars) {
+  if (vars.keys.any((element) => element.contains(_nonValidSubstituteRegExp))) {
+    throw ArgumentError('vars.keys can only contain letters.');
+  }
+
+  return str.replaceAllMapped(_substituteRegExp, (match) {
+    final item = vars[match[1]];
+
+    if (item == null) {
+      return match[0];
+    } else {
+      return item;
+    }
+  });
+}
diff --git a/pkg/dartdev/lib/src/templates/common.dart b/pkg/dartdev/lib/src/templates/common.dart
new file mode 100644
index 0000000..b849fdd
--- /dev/null
+++ b/pkg/dartdev/lib/src/templates/common.dart
@@ -0,0 +1,37 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+final String gitignore = '''
+# Files and directories created by pub.
+.dart_tool/
+.packages
+
+# Conventional directory for build output.
+build/
+''';
+
+final String analysisOptions = '''
+# Defines a default set of lint rules enforced for projects at Google. For
+# details and rationale, see
+# https://github.com/dart-lang/pedantic#enabled-lints.
+
+include: package:pedantic/analysis_options.yaml
+
+# For lint rules and documentation, see http://dart-lang.github.io/linter/lints.
+
+# Uncomment to specify additional rules.
+# linter:
+#   rules:
+#     - camel_case_types
+
+# analyzer:
+#   exclude:
+#     - path/to/excluded/files/**
+''';
+
+final String changelog = '''
+## 1.0.0
+
+- Initial version.
+''';
diff --git a/pkg/dartdev/lib/src/templates/console_full.dart b/pkg/dartdev/lib/src/templates/console_full.dart
new file mode 100644
index 0000000..78e1670
--- /dev/null
+++ b/pkg/dartdev/lib/src/templates/console_full.dart
@@ -0,0 +1,76 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import '../templates.dart';
+import 'common.dart' as common;
+
+/// A generator for a hello world command-line application.
+class ConsoleFullGenerator extends DefaultGenerator {
+  ConsoleFullGenerator()
+      : super('console-full', 'Console Application',
+            'A command-line application sample.',
+            categories: const ['dart', 'console']) {
+    addFile('.gitignore', common.gitignore);
+    addFile('analysis_options.yaml', common.analysisOptions);
+    addFile('CHANGELOG.md', common.changelog);
+    addFile('pubspec.yaml', _pubspec);
+    addFile('README.md', _readme);
+    setEntrypoint(
+      addFile('bin/__projectName__.dart', _mainDart),
+    );
+    addFile('lib/__projectName__.dart', _libDart);
+    addFile('test/__projectName___test.dart', _testDart);
+  }
+
+  @override
+  String getInstallInstructions() => '${super.getInstallInstructions()}\n'
+      'run your app using `dart ${entrypoint.path}`.';
+}
+
+final String _pubspec = '''
+name: __projectName__
+description: A sample command-line application.
+version: 1.0.0
+# homepage: https://www.example.com
+
+environment:
+  sdk: '>=2.12.0 <3.0.0'
+
+# dependencies:
+#   path: ^1.8.0
+
+dev_dependencies:
+  pedantic: ^1.10.0
+  test: ^1.16.0
+''';
+
+final String _readme = '''
+A sample command-line application with an entrypoint in `bin/`, library code
+in `lib/`, and example unit test in `test/`.
+''';
+
+final String _mainDart = r'''
+import 'package:__projectName__/__projectName__.dart' as __projectName__;
+
+void main(List<String> arguments) {
+  print('Hello world: ${__projectName__.calculate()}!');
+}
+''';
+
+final String _libDart = '''
+int calculate() {
+  return 6 * 7;
+}
+''';
+
+final String _testDart = '''
+import 'package:__projectName__/__projectName__.dart';
+import 'package:test/test.dart';
+
+void main() {
+  test('calculate', () {
+    expect(calculate(), 42);
+  });
+}
+''';
diff --git a/pkg/dartdev/lib/src/templates/console_simple.dart b/pkg/dartdev/lib/src/templates/console_simple.dart
new file mode 100644
index 0000000..15384c6
--- /dev/null
+++ b/pkg/dartdev/lib/src/templates/console_simple.dart
@@ -0,0 +1,53 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import '../templates.dart';
+import 'common.dart' as common;
+
+/// A generator for a simple command-line application.
+class ConsoleSimpleGenerator extends DefaultGenerator {
+  ConsoleSimpleGenerator()
+      : super('console-simple', 'Simple Console Application',
+            'A simple command-line application.',
+            categories: const ['dart', 'console']) {
+    addFile('.gitignore', common.gitignore);
+    addFile('analysis_options.yaml', common.analysisOptions);
+    addFile('CHANGELOG.md', common.changelog);
+    addFile('pubspec.yaml', _pubspec);
+    addFile('README.md', _readme);
+    setEntrypoint(
+      addFile('bin/__projectName__.dart', main),
+    );
+  }
+
+  @override
+  String getInstallInstructions() => '${super.getInstallInstructions()}\n'
+      'run your app using `dart ${entrypoint.path}`.';
+}
+
+final String _pubspec = '''
+name: __projectName__
+description: A simple command-line application.
+version: 1.0.0
+# homepage: https://www.example.com
+
+environment:
+  sdk: '>=2.12.0 <3.0.0'
+
+# dependencies:
+#   path: ^1.8.0
+
+dev_dependencies:
+  pedantic: ^1.10.0
+''';
+
+final String _readme = '''
+A simple command-line application.
+''';
+
+final String main = '''
+void main(List<String> arguments) {
+  print('Hello world!');
+}
+''';
diff --git a/pkg/dartdev/lib/src/templates/package_simple.dart b/pkg/dartdev/lib/src/templates/package_simple.dart
new file mode 100644
index 0000000..7d013fa
--- /dev/null
+++ b/pkg/dartdev/lib/src/templates/package_simple.dart
@@ -0,0 +1,130 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import '../templates.dart';
+import 'common.dart' as common;
+
+/// A generator for a simple command-line application.
+class PackageSimpleGenerator extends DefaultGenerator {
+  PackageSimpleGenerator()
+      : super('package-simple', 'Dart Package',
+            'A starting point for Dart libraries or applications.',
+            categories: const ['dart']) {
+    addFile('.gitignore', _gitignore);
+    addFile('analysis_options.yaml', common.analysisOptions);
+    addFile('CHANGELOG.md', common.changelog);
+    addFile('pubspec.yaml', _pubspec);
+    addFile('README.md', _readme);
+    addFile('example/__projectName___example.dart', _exampleDart);
+    setEntrypoint(
+      addFile('lib/__projectName__.dart', _libDart),
+    );
+    addFile('lib/src/__projectName___base.dart', _libSrcDart);
+    addFile('test/__projectName___test.dart', _testDart);
+  }
+
+  @override
+  String getInstallInstructions() => '${super.getInstallInstructions()}\n'
+      'run your app using `dart ${entrypoint.path}`.';
+}
+
+final String _gitignore = '''
+# Files and directories created by pub.
+.dart_tool/
+.packages
+
+# Conventional directory for build outputs.
+build/
+
+# Omit committing pubspec.lock for library packages; see
+# https://dart.dev/guides/libraries/private-files#pubspeclock.
+pubspec.lock
+''';
+
+final String _pubspec = '''
+name: __projectName__
+description: A starting point for Dart libraries or applications.
+version: 1.0.0
+# homepage: https://www.example.com
+
+environment:
+  sdk: '>=2.12.0 <3.0.0'
+
+# dependencies:
+#   path: ^1.8.0
+
+dev_dependencies:
+  pedantic: ^1.10.0
+  test: ^1.16.0
+''';
+
+final String _readme = '''
+A library for Dart developers.
+
+## Usage
+
+A simple usage example:
+
+```dart
+import 'package:__projectName__/__projectName__.dart';
+
+main() {
+  var awesome = new Awesome();
+}
+```
+
+## Features and bugs
+
+Please file feature requests and bugs at the [issue tracker][tracker].
+
+[tracker]: http://example.com/issues/replaceme
+''';
+
+final String _exampleDart = r'''
+import 'package:__projectName__/__projectName__.dart';
+
+void main() {
+  var awesome = Awesome();
+  print('awesome: ${awesome.isAwesome}');
+}
+''';
+
+final String _libDart = '''
+/// Support for doing something awesome.
+///
+/// More dartdocs go here.
+library __projectName__;
+
+export 'src/__projectName___base.dart';
+
+// TODO: Export any libraries intended for clients of this package.
+''';
+
+final String _libSrcDart = '''
+// TODO: Put public facing types in this file.
+
+/// Checks if you are awesome. Spoiler: you are.
+class Awesome {
+  bool get isAwesome => true;
+}
+''';
+
+final String _testDart = '''
+import 'package:__projectName__/__projectName__.dart';
+import 'package:test/test.dart';
+
+void main() {
+  group('A group of tests', () {
+    final awesome = Awesome();
+
+    setUp(() {
+      // Additional setup goes here.
+    });
+
+    test('First Test', () {
+      expect(awesome.isAwesome, isTrue);
+    });
+  });
+}
+''';
diff --git a/pkg/dartdev/lib/src/templates/server_simple.dart b/pkg/dartdev/lib/src/templates/server_simple.dart
new file mode 100644
index 0000000..6688f23
--- /dev/null
+++ b/pkg/dartdev/lib/src/templates/server_simple.dart
@@ -0,0 +1,85 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import '../templates.dart';
+import 'common.dart' as common;
+
+/// A generator for a server app built on `package:shelf`.
+class ServerSimpleGenerator extends DefaultGenerator {
+  ServerSimpleGenerator()
+      : super('server-simple', 'Web Server',
+            'A web server built using package:shelf.',
+            categories: const ['dart', 'server']) {
+    addFile('.gitignore', common.gitignore);
+    addFile('analysis_options.yaml', common.analysisOptions);
+    addFile('CHANGELOG.md', common.changelog);
+    addFile('pubspec.yaml', _pubspec);
+    addFile('README.md', _readme);
+    setEntrypoint(
+      addFile('bin/server.dart', _main),
+    );
+  }
+
+  @override
+  String getInstallInstructions() => '${super.getInstallInstructions()}\n'
+      'run your app using `dart ${entrypoint.path}`.';
+}
+
+final String _pubspec = '''
+name: __projectName__
+description: A web server built using the shelf package.
+version: 1.0.0
+# homepage: https://www.example.com
+
+environment:
+  sdk: ">=2.12.0 <3.0.0"
+
+dependencies:
+  args: ^2.0.0
+  shelf: ^1.1.0
+
+dev_dependencies:
+  pedantic: ^1.10.0
+''';
+
+final String _readme = '''
+A web server built using [Shelf](https://pub.dev/packages/shelf).
+''';
+
+final String _main = r'''
+import 'dart:io';
+
+import 'package:args/args.dart';
+import 'package:shelf/shelf.dart' as shelf;
+import 'package:shelf/shelf_io.dart' as io;
+
+// For Google Cloud Run, set _hostname to '0.0.0.0'.
+const _hostname = 'localhost';
+
+void main(List<String> args) async {
+  var parser = ArgParser()..addOption('port', abbr: 'p');
+  var result = parser.parse(args);
+
+  // For Google Cloud Run, we respect the PORT environment variable
+  var portStr = result['port'] ?? Platform.environment['PORT'] ?? '8080';
+  var port = int.tryParse(portStr);
+
+  if (port == null) {
+    stdout.writeln('Could not parse port value "$portStr" into a number.');
+    // 64: command line usage error
+    exitCode = 64;
+    return;
+  }
+
+  var handler = const shelf.Pipeline()
+      .addMiddleware(shelf.logRequests())
+      .addHandler(_echoRequest);
+
+  var server = await io.serve(handler, _hostname, port);
+  print('Serving at http://${server.address.host}:${server.port}');
+}
+
+shelf.Response _echoRequest(shelf.Request request) =>
+    shelf.Response.ok('Request for "${request.url}"');
+''';
diff --git a/pkg/dartdev/lib/src/templates/web_simple.dart b/pkg/dartdev/lib/src/templates/web_simple.dart
new file mode 100644
index 0000000..12ed1ce
--- /dev/null
+++ b/pkg/dartdev/lib/src/templates/web_simple.dart
@@ -0,0 +1,94 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import '../templates.dart';
+import 'common.dart' as common;
+
+/// A generator for a uber-simple web application.
+class WebSimpleGenerator extends DefaultGenerator {
+  WebSimpleGenerator()
+      : super('web-simple', 'Bare-bones Web App',
+            'A web app that uses only core Dart libraries.',
+            categories: const ['dart', 'web']) {
+    addFile('.gitignore', common.gitignore);
+    addFile('analysis_options.yaml', common.analysisOptions);
+    addFile('CHANGELOG.md', common.changelog);
+    addFile('pubspec.yaml', _pubspec);
+    addFile('README.md', _readme);
+    addFile('web/index.html', _index);
+    setEntrypoint(
+      addFile('web/main.dart', _main),
+    );
+    addFile('web/styles.css', _styles);
+  }
+}
+
+final String _pubspec = '''
+name: __projectName__
+description: An absolute bare-bones web app.
+version: 1.0.0
+# homepage: https://www.example.com
+
+environment:
+  sdk: '>=2.12.0 <3.0.0'
+
+# dependencies:
+#   path: ^1.7.0
+
+dev_dependencies:
+  build_runner: ^1.10.0
+  build_web_compilers: ^2.11.0
+  pedantic: ^1.9.0
+''';
+
+final String _readme = '''
+An absolute bare-bones web app.
+''';
+
+final String _index = '''
+<!DOCTYPE html>
+
+<html>
+<head>
+    <meta charset="utf-8">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <meta name="scaffolded-by" content="https://github.com/dart-lang/sdk">
+    <title>__projectName__</title>
+    <link rel="stylesheet" href="styles.css">
+    <script defer src="main.dart.js"></script>
+</head>
+
+<body>
+
+  <div id="output"></div>
+
+</body>
+</html>
+''';
+
+final String _main = '''
+import 'dart:html';
+
+void main() {
+  querySelector('#output')?.text = 'Your Dart app is running.';
+}
+''';
+
+final String _styles = '''
+@import url(https://fonts.googleapis.com/css?family=Roboto);
+
+html, body {
+  width: 100%;
+  height: 100%;
+  margin: 0;
+  padding: 0;
+  font-family: 'Roboto', sans-serif;
+}
+
+#output {
+  padding: 20px;
+  text-align: center;
+}
+''';
diff --git a/pkg/dartdev/lib/src/utils.dart b/pkg/dartdev/lib/src/utils.dart
index c168bf4..c5aa257 100644
--- a/pkg/dartdev/lib/src/utils.dart
+++ b/pkg/dartdev/lib/src/utils.dart
@@ -79,3 +79,98 @@
   }
   return buffer.toString();
 }
+
+// A valid Dart identifier that can be used for a package, i.e. no
+// capital letters.
+// https://dart.dev/guides/language/language-tour#important-concepts
+final RegExp _identifierRegExp = RegExp('[a-z_][a-z0-9_]*');
+
+// non-contextual dart keywords.
+// https://dart.dev/guides/language/language-tour#keywords
+const Set<String> _keywords = <String>{
+  'abstract',
+  'as',
+  'assert',
+  'async',
+  'await',
+  'break',
+  'case',
+  'catch',
+  'class',
+  'const',
+  'continue',
+  'covariant',
+  'default',
+  'deferred',
+  'do',
+  'dynamic',
+  'else',
+  'enum',
+  'export',
+  'extends',
+  'extension',
+  'external',
+  'factory',
+  'false',
+  'final',
+  'finally',
+  'for',
+  'function',
+  'get',
+  'hide',
+  'if',
+  'implements',
+  'import',
+  'in',
+  'inout',
+  'interface',
+  'is',
+  'late',
+  'library',
+  'mixin',
+  'native',
+  'new',
+  'null',
+  'of',
+  'on',
+  'operator',
+  'out',
+  'part',
+  'patch',
+  'required',
+  'rethrow',
+  'return',
+  'set',
+  'show',
+  'source',
+  'static',
+  'super',
+  'switch',
+  'sync',
+  'this',
+  'throw',
+  'true',
+  'try',
+  'typedef',
+  'var',
+  'void',
+  'while',
+  'with',
+  'yield',
+};
+
+/// Whether [name] is a valid Pub package.
+bool isValidPackageName(String name) {
+  final Match match = _identifierRegExp.matchAsPrefix(name);
+  return match != null && match.end == name.length && !_keywords.contains(name);
+}
+
+/// Convert a directory name into a reasonably legal pub package name.
+String normalizeProjectName(String name) {
+  name = name.replaceAll('-', '_').replaceAll(' ', '_');
+  // Strip any extension (like .dart).
+  if (name.contains('.')) {
+    name = name.substring(0, name.indexOf('.'));
+  }
+  return name;
+}
diff --git a/pkg/dartdev/pubspec.yaml b/pkg/dartdev/pubspec.yaml
index 5acc161..20071f4 100644
--- a/pkg/dartdev/pubspec.yaml
+++ b/pkg/dartdev/pubspec.yaml
@@ -27,7 +27,6 @@
   path: ^1.0.0
   pedantic: ^1.9.0
   pub: any
-  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 a160888..304fc6a 100644
--- a/pkg/dartdev/test/analytics_test.dart
+++ b/pkg/dartdev/test/analytics_test.dart
@@ -45,7 +45,7 @@
     var result = p.runSync(['--disable-analytics']);
     expect(result.stdout, contains('''
   ╔════════════════════════════════════════════════════════════════════════════╗
-  ║ Anonymous analytics reporting disabled. In order to enable it, run:        ║
+  ║ Analytics reporting disabled. In order to enable it, run:                  ║
   ║                                                                            ║
   ║   dart --enable-analytics                                                  ║
   ║                                                                            ║
@@ -55,11 +55,11 @@
     result = p.runSync(['--enable-analytics']);
     expect(result.stdout, contains('''
   ╔════════════════════════════════════════════════════════════════════════════╗
-  ║ The Dart tool uses Google Analytics to anonymously report feature usage    ║
-  ║ statistics and to send basic crash reports. This data is used to help      ║
-  ║ improve the Dart platform and tools over time.                             ║
+  ║ The Dart tool uses Google Analytics to report feature usage 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 analytics, run:                          ║
+  ║ To disable reporting of analytics, run:                                    ║
   ║                                                                            ║
   ║   dart --disable-analytics                                                 ║
   ║                                                                            ║
diff --git a/pkg/dartdev/test/commands/analyze_test.dart b/pkg/dartdev/test/commands/analyze_test.dart
index 6d0709d..8017a0c 100644
--- a/pkg/dartdev/test/commands/analyze_test.dart
+++ b/pkg/dartdev/test/commands/analyze_test.dart
@@ -14,7 +14,7 @@
   group('analyze', defineAnalyze, timeout: longTimeout);
 }
 
-const String _analyzeDescriptionText = "Analyze the project's Dart code.";
+const String _analyzeDescriptionText = 'Analyze Dart code in a directory.';
 
 const String _analyzeUsageText =
     'Usage: dart analyze [arguments] [<directory>]';
@@ -78,7 +78,7 @@
 
     expect(result.exitCode, 64);
     expect(result.stdout, isEmpty);
-    expect(result.stderr, contains('Only one directory is expected.'));
+    expect(result.stderr, contains('Only one directory or file is expected.'));
     expect(result.stderr, contains(_analyzeUsageText));
   });
 
@@ -88,7 +88,8 @@
 
     expect(result.exitCode, 64);
     expect(result.stdout, isEmpty);
-    expect(result.stderr, contains("Directory doesn't exist: /no/such/dir1/"));
+    expect(result.stderr,
+        contains("Directory or file doesn't exist: /no/such/dir1/"));
     expect(result.stderr, contains(_analyzeUsageText));
   });
 
@@ -102,34 +103,59 @@
     expect(result.stdout, contains('No issues found!'));
   });
 
-  test('no errors', () {
-    p = project(mainSrc: 'int get foo => 1;\n');
-    var result = p.runSync(['analyze', p.dirPath]);
+  group('single directory', () {
+    test('no errors', () {
+      p = project(mainSrc: 'int get foo => 1;\n');
+      var result = p.runSync(['analyze', p.dirPath]);
 
-    expect(result.exitCode, 0);
-    expect(result.stderr, isEmpty);
-    expect(result.stdout, contains('No issues found!'));
+      expect(result.exitCode, 0);
+      expect(result.stderr, isEmpty);
+      expect(result.stdout, contains('No issues found!'));
+    });
+
+    test('one error', () {
+      p = project(mainSrc: "int get foo => 'str';\n");
+      var result = p.runSync(['analyze', p.dirPath]);
+
+      expect(result.exitCode, 3);
+      expect(result.stderr, isEmpty);
+      expect(result.stdout, contains('A value of type '));
+      expect(result.stdout, contains('lib/main.dart:1:16 '));
+      expect(result.stdout, contains('return_of_invalid_type'));
+      expect(result.stdout, contains('1 issue found.'));
+    });
+
+    test('two errors', () {
+      p = project(mainSrc: "int get foo => 'str';\nint get bar => 'str';\n");
+      var result = p.runSync(['analyze', p.dirPath]);
+
+      expect(result.exitCode, 3);
+      expect(result.stderr, isEmpty);
+      expect(result.stdout, contains('2 issues found.'));
+    });
   });
 
-  test('one error', () {
-    p = project(mainSrc: "int get foo => 'str';\n");
-    var result = p.runSync(['analyze', p.dirPath]);
+  group('single file', () {
+    test('no errors', () {
+      p = project(mainSrc: 'int get foo => 1;\n');
+      var result = p.runSync(['analyze', p.mainPath]);
 
-    expect(result.exitCode, 3);
-    expect(result.stderr, isEmpty);
-    expect(result.stdout, contains('A value of type '));
-    expect(result.stdout, contains('lib/main.dart:1:16 '));
-    expect(result.stdout, contains('return_of_invalid_type'));
-    expect(result.stdout, contains('1 issue found.'));
-  });
+      expect(result.exitCode, 0);
+      expect(result.stderr, isEmpty);
+      expect(result.stdout, contains('No issues found!'));
+    });
 
-  test('two errors', () {
-    p = project(mainSrc: "int get foo => 'str';\nint get bar => 'str';\n");
-    var result = p.runSync(['analyze', p.dirPath]);
+    test('one error', () {
+      p = project(mainSrc: "int get foo => 'str';\n");
+      var result = p.runSync(['analyze', p.mainPath]);
 
-    expect(result.exitCode, 3);
-    expect(result.stderr, isEmpty);
-    expect(result.stdout, contains('2 issues found.'));
+      expect(result.exitCode, 3);
+      expect(result.stderr, isEmpty);
+      expect(result.stdout, contains('A value of type '));
+      expect(result.stdout, contains('main.dart:1:16 '));
+      expect(result.stdout, contains('return_of_invalid_type'));
+      expect(result.stdout, contains('1 issue found.'));
+    });
   });
 
   test('warning --fatal-warnings', () {
@@ -195,7 +221,7 @@
     expect(result.exitCode, 3);
     expect(result.stderr, isEmpty);
     var stdout = result.stdout;
-    expect(stdout, contains("The declaration of 'one' is on line 3"));
+    expect(stdout, contains("The declaration of 'one' is here"));
     expect(
         stdout, contains('Try moving the declaration to before the first use'));
     expect(stdout, contains('https://dart.dev'));
@@ -208,6 +234,8 @@
       'type': 'TODO',
       'code': 'dead_code',
       'location': {
+        'endLine': 16,
+        'endColumn': 12,
         'file': 'lib/test.dart',
         'offset': 362,
         'length': 72,
@@ -217,6 +245,37 @@
       'message': 'Foo bar baz.',
       'hasFix': false,
     };
+    final fullDiagnosticJson = {
+      'severity': 'ERROR',
+      'type': 'COMPILE_TIME_ERROR',
+      'location': {
+        'file': 'lib/test.dart',
+        'offset': 19,
+        'length': 1,
+        'startLine': 2,
+        'startColumn': 9
+      },
+      'message':
+          "Local variable 's' can't be referenced before it is declared.",
+      'correction':
+          "Try moving the declaration to before the first use, or renaming the local variable so that it doesn't hide a name from an enclosing scope.",
+      'code': 'referenced_before_declaration',
+      'url':
+          'https:://dart.dev/tools/diagnostic-messages#referenced_before_declaration',
+      'contextMessages': [
+        {
+          'message': "The declaration of 's' is on line 3.",
+          'location': {
+            'file': 'lib/test.dart',
+            'offset': 29,
+            'length': 1,
+            'startLine': 3,
+            'startColumn': 7
+          }
+        }
+      ],
+      'hasFix': false
+    };
 
     test('default', () {
       final logger = TestLogger(false);
@@ -232,6 +291,49 @@
       expect(stdout, contains('dead_code'));
     });
 
+    group('json', () {
+      test('short', () {
+        final logger = TestLogger(false);
+        final errors = [AnalysisError(sampleInfoJson)];
+
+        AnalyzeCommand.emitJsonFormat(logger, errors);
+
+        expect(logger.stderrBuffer, isEmpty);
+        final stdout = logger.stdoutBuffer.toString().trim();
+        expect(
+            stdout,
+            '{"version":1,"diagnostics":[{"code":"dead_code","severity":"INFO",'
+            '"type":"TODO","location":{"file":"lib/test.dart","range":{'
+            '"start":{"offset":362,"line":15,"column":4},"end":{"offset":434,'
+            '"line":16,"column":12}}},"problemMessage":"Foo bar baz."}]}');
+      });
+      test('full', () {
+        final logger = TestLogger(false);
+        final errors = [AnalysisError(fullDiagnosticJson)];
+
+        AnalyzeCommand.emitJsonFormat(logger, errors);
+
+        expect(logger.stderrBuffer, isEmpty);
+        final stdout = logger.stdoutBuffer.toString().trim();
+        expect(
+            stdout,
+            '{"version":1,"diagnostics":[{'
+            '"code":"referenced_before_declaration","severity":"ERROR",'
+            '"type":"COMPILE_TIME_ERROR","location":{"file":"lib/test.dart",'
+            '"range":{"start":{"offset":19,"line":2,"column":9},"end":{'
+            '"offset":20,"line":null,"column":null}}},"problemMessage":'
+            '"Local variable \'s\' can\'t be referenced before it is declared.",'
+            '"correctionMessage":"Try moving the declaration to before the'
+            ' first use, or renaming the local variable so that it doesn\'t hide'
+            ' a name from an enclosing scope.","contextMessages":[{"location":{'
+            '"file":"lib/test.dart","range":{"start":{"offset":29,"line":3,'
+            '"column":7},"end":{"offset":30,"line":null,"column":null}}},'
+            '"message":"The declaration of \'s\' is on line 3."}],'
+            '"documentation":'
+            '"https:://dart.dev/tools/diagnostic-messages#referenced_before_declaration"}]}');
+      });
+    });
+
     test('machine', () {
       final logger = TestLogger(false);
       final errors = [AnalysisError(sampleInfoJson)];
diff --git a/pkg/dartdev/test/commands/compile_test.dart b/pkg/dartdev/test/commands/compile_test.dart
index 17cc1a8..6b47a28 100644
--- a/pkg/dartdev/test/commands/compile_test.dart
+++ b/pkg/dartdev/test/commands/compile_test.dart
@@ -213,7 +213,6 @@
 
     // Ensure the -D and --define arguments were processed correctly.
     final contents = file.readAsStringSync();
-    print(contents);
     expect(contents.contains('1: bar'), true);
     expect(contents.contains('2: foo'), true);
   });
@@ -665,6 +664,34 @@
     expect(result.exitCode, 0);
   });
 
+  test('Compile kernel with invalid trailing argument', () {
+    final p = project(mainSrc: '''void main() {}''');
+    final inFile = path.canonicalize(path.join(p.dirPath, p.relativeFilePath));
+    final outFile = path.canonicalize(path.join(p.dirPath, 'mydill'));
+
+    var result = p.runSync(
+      [
+        'compile',
+        'kernel',
+        '--verbosity=warning',
+        '-o',
+        outFile,
+        inFile,
+        'invalid-arg',
+      ],
+    );
+
+    expect(result.stdout, isEmpty);
+    expect(
+      result.stderr,
+      predicate(
+        (o) => '$o'.contains('Unexpected arguments after Dart entry point.'),
+      ),
+    );
+    expect(result.exitCode, 64);
+    expect(File(outFile).existsSync(), false, reason: 'File found: $outFile');
+  });
+
   test('Compile kernel with sound null safety', () {
     final p = project(mainSrc: '''void main() {}''');
     final inFile = path.canonicalize(path.join(p.dirPath, p.relativeFilePath));
@@ -835,6 +862,30 @@
         reason: 'File not found: $outFile');
   });
 
+  test('Compile JIT snapshot with training args', () {
+    final p =
+        project(mainSrc: '''void main(List<String> args) => print(args);''');
+    final inFile = path.canonicalize(path.join(p.dirPath, p.relativeFilePath));
+    final outFile = path.canonicalize(path.join(p.dirPath, 'myjit'));
+
+    var result = p.runSync(
+      [
+        'compile',
+        'jit-snapshot',
+        '-o',
+        outFile,
+        inFile,
+        'foo',
+      ],
+    );
+
+    expect(result.stdout, predicate((o) => '$o'.contains('[foo]')));
+    expect(result.stderr, isEmpty);
+    expect(result.exitCode, 0);
+    expect(File(outFile).existsSync(), true,
+        reason: 'File not found: $outFile');
+  });
+
   test('Compile JIT snapshot without info', () {
     final p = project(mainSrc: '''void main() {}''');
     final inFile = path.canonicalize(path.join(p.dirPath, p.relativeFilePath));
diff --git a/pkg/dartdev/test/commands/create_integration_test.dart b/pkg/dartdev/test/commands/create_integration_test.dart
new file mode 100644
index 0000000..8bc1066
--- /dev/null
+++ b/pkg/dartdev/test/commands/create_integration_test.dart
@@ -0,0 +1,54 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. 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:dartdev/src/commands/create.dart';
+import 'package:test/test.dart';
+
+import '../utils.dart';
+
+void main() {
+  group('create integration', defineCreateTests, timeout: longTimeout);
+}
+
+void defineCreateTests() {
+  TestProject p;
+
+  setUp(() => p = null);
+
+  tearDown(() => p?.dispose());
+
+  // Create tests for each template.
+  for (String templateId in CreateCommand.legalTemplateIds) {
+    test(templateId, () {
+      p = project();
+
+      ProcessResult createResult = p.runSync([
+        'create',
+        '--force',
+        '--template',
+        templateId,
+        'template_project',
+      ]);
+      expect(createResult.exitCode, 0, reason: createResult.stderr);
+
+      // Validate that the project analyzes cleanly.
+      // TODO: Should we use --fatal-infos here?
+      ProcessResult analyzeResult =
+          p.runSync(['analyze'], workingDir: p.dir.path);
+      expect(analyzeResult.exitCode, 0, reason: analyzeResult.stdout);
+
+      // Validate that the code is well formatted.
+      ProcessResult formatResult = p.runSync([
+        'format',
+        '--output',
+        'none',
+        '--set-exit-if-changed',
+        'template_project',
+      ]);
+      expect(formatResult.exitCode, 0, reason: formatResult.stdout);
+    });
+  }
+}
diff --git a/pkg/dartdev/test/commands/create_test.dart b/pkg/dartdev/test/commands/create_test.dart
index 7f5c846..86b2d48 100644
--- a/pkg/dartdev/test/commands/create_test.dart
+++ b/pkg/dartdev/test/commands/create_test.dart
@@ -6,6 +6,7 @@
 import 'dart:io';
 
 import 'package:dartdev/src/commands/create.dart';
+import 'package:dartdev/src/templates.dart' as templates;
 import 'package:path/path.dart' as path;
 import 'package:test/test.dart';
 
@@ -64,6 +65,42 @@
     expect(result.exitCode, 73);
   });
 
+  test('create project in current directory', () {
+    p = project();
+    final projectDir = Directory('foo')..createSync();
+    final result = p.runSync(
+      ['create', '--force', '.'],
+      workingDir: projectDir.path,
+    );
+    expect(result.stderr, isEmpty);
+    expect(result.stdout, contains('Created project foo in .!'));
+    expect(result.exitCode, 0);
+  });
+
+  test('create project with normalized package name', () {
+    p = project();
+    final result = p.runSync(['create', 'requires-normalization']);
+    expect(result.stderr, isEmpty);
+    expect(
+        result.stdout,
+        contains(
+            'Created project requires_normalization in requires-normalization!'));
+    expect(result.exitCode, 0);
+  });
+
+  test('create project with an invalid package name', () {
+    p = project();
+    final result = p.runSync(['create', 'bad-package^name']);
+    expect(
+      result.stderr,
+      contains(
+        '"bad_package^name" is not a valid Dart project name.\n\n'
+        'See https://dart.dev/tools/pub/pubspec#name for more information.',
+      ),
+    );
+    expect(result.exitCode, 73);
+  });
+
   test('bad template id', () {
     p = project();
 
@@ -76,17 +113,20 @@
   for (String templateId in CreateCommand.legalTemplateIds) {
     test('create $templateId', () {
       p = project();
-
-      ProcessResult result = p
-          .runSync(['create', '--force', '--template', templateId, p.dir.path]);
+      const projectName = 'template_project';
+      ProcessResult result = p.runSync([
+        'create',
+        '--force',
+        '--no-pub',
+        '--template',
+        templateId,
+        projectName,
+      ]);
       expect(result.exitCode, 0);
 
-      String projectName = path.basename(p.dir.path);
-
-      String entry =
-          CreateCommand.retrieveTemplateGenerator(templateId).entrypoint.path;
+      String entry = templates.getGenerator(templateId).entrypoint.path;
       entry = entry.replaceAll('__projectName__', projectName);
-      File entryFile = File(path.join(p.dir.path, entry));
+      File entryFile = File(path.join(p.dir.path, projectName, entry));
 
       expect(entryFile.existsSync(), true,
           reason: 'File not found: ${entryFile.path}');
diff --git a/pkg/dartdev/test/commands/migrate_test.dart b/pkg/dartdev/test/commands/migrate_test.dart
index 681d550..500d587 100644
--- a/pkg/dartdev/test/commands/migrate_test.dart
+++ b/pkg/dartdev/test/commands/migrate_test.dart
@@ -25,8 +25,8 @@
 
     expect(result.exitCode, 0);
     expect(result.stderr, isEmpty);
-    expect(result.stdout,
-        contains('Perform a null safety migration on a project or package.'));
+    expect(
+        result.stdout, contains('Perform null safety migration on a project.'));
     expect(result.stdout,
         contains('Usage: dart migrate [arguments] [project or directory]'));
   });
diff --git a/pkg/dartdev/test/commands/test_test.dart b/pkg/dartdev/test/commands/test_test.dart
index 1a85ad1..b493403 100644
--- a/pkg/dartdev/test/commands/test_test.dart
+++ b/pkg/dartdev/test/commands/test_test.dart
@@ -41,7 +41,7 @@
     final result = p.runSync(['help', 'test']);
 
     expect(result.exitCode, 0);
-    expect(result.stdout, contains(' tests in this package'));
+    expect(result.stdout, contains(' tests for a project'));
     expect(result.stderr, isEmpty);
   });
 
@@ -64,7 +64,7 @@
     expect(resultHelp.stdout, '''
 No pubspec.yaml file found - run this command in your project folder.
 
-Run tests in this package.
+Run tests for a project.
 
 Usage: dart test [arguments]
 
diff --git a/pkg/dartdev/test/templates_test.dart b/pkg/dartdev/test/templates_test.dart
new file mode 100644
index 0000000..3b466c9
--- /dev/null
+++ b/pkg/dartdev/test/templates_test.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:dartdev/src/templates.dart';
+import 'package:test/test.dart';
+
+void main() {
+  group('templates', () {
+    group('substituteVars', () {
+      test('simple', () {
+        _expect('foo __bar__ baz', {'bar': 'baz'}, 'foo baz baz');
+      });
+
+      test('nosub', () {
+        _expect('foo __bar__ baz', {'aaa': 'bbb'}, 'foo __bar__ baz');
+      });
+
+      test('matching input', () {
+        _expect('foo __bar__ baz', {'bar': '__baz__', 'baz': 'foo'},
+            'foo __baz__ baz');
+      });
+
+      test('vars must be alpha + numeric', () {
+        expect(() => substituteVars('str', {'with space': 'noop'}),
+            throwsArgumentError);
+        expect(() => substituteVars('str', {'with!symbols': 'noop'}),
+            throwsArgumentError);
+        expect(() => substituteVars('str', {'with1numbers': 'noop'}),
+            throwsArgumentError);
+        expect(() => substituteVars('str', {'with_under': 'noop'}),
+            throwsArgumentError);
+      });
+    });
+  });
+}
+
+void _expect(String original, Map<String, String> vars, String result) {
+  expect(substituteVars(original, vars), result);
+}
diff --git a/pkg/dartdev/test/utils.dart b/pkg/dartdev/test/utils.dart
index 117aec2..5a64ced 100644
--- a/pkg/dartdev/test/utils.dart
+++ b/pkg/dartdev/test/utils.dart
@@ -7,7 +7,6 @@
 
 import 'package:path/path.dart' as path;
 import 'package:pub_semver/pub_semver.dart';
-
 import 'package:test/test.dart';
 
 /// A long [Timeout] is provided for tests that start a process on
@@ -38,6 +37,8 @@
 
   String get dirPath => dir.path;
 
+  String get mainPath => path.join(dirPath, relativeFilePath);
+
   final String name;
 
   String get relativeFilePath => 'lib/main.dart';
@@ -52,7 +53,7 @@
       this.name = _defaultProjectName,
       this.logAnalytics = false,
       this.sdkConstraint}) {
-    dir = Directory.systemTemp.createTempSync(name);
+    dir = Directory.systemTemp.createTempSync('a');
     file('pubspec.yaml', '''
 name: $name
 environment:
diff --git a/pkg/dds/CHANGELOG.md b/pkg/dds/CHANGELOG.md
index 62904a1..e374a78 100644
--- a/pkg/dds/CHANGELOG.md
+++ b/pkg/dds/CHANGELOG.md
@@ -1,3 +1,6 @@
+# 1.7.6
+- Update dependencies.
+
 # 1.7.5
 - Add 30 second keep alive period for SSE connections.
 
diff --git a/pkg/dds/bin/dds.dart b/pkg/dds/bin/dds.dart
index 3ac9a09..9937d26 100644
--- a/pkg/dds/bin/dds.dart
+++ b/pkg/dds/bin/dds.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.10
+
 import 'dart:io';
 
 import 'package:dds/dds.dart';
diff --git a/pkg/dds/example/example.dart b/pkg/dds/example/example.dart
index 883c678..561dca9 100644
--- a/pkg/dds/example/example.dart
+++ b/pkg/dds/example/example.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.10
+
 import 'package:dds/dds.dart';
 import 'package:vm_service/vm_service_io.dart';
 
diff --git a/pkg/dds/lib/dds.dart b/pkg/dds/lib/dds.dart
index a9024dd..f7c7a05 100644
--- a/pkg/dds/lib/dds.dart
+++ b/pkg/dds/lib/dds.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.10
+
 /// A library used to spawn the Dart Developer Service, used to communicate
 /// with a Dart VM Service instance.
 library dds;
diff --git a/pkg/dds/lib/src/binary_compatible_peer.dart b/pkg/dds/lib/src/binary_compatible_peer.dart
index b701f5e..2e1af84 100644
--- a/pkg/dds/lib/src/binary_compatible_peer.dart
+++ b/pkg/dds/lib/src/binary_compatible_peer.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.10
+
 import 'dart:async';
 import 'dart:convert';
 import 'dart:typed_data';
diff --git a/pkg/dds/lib/src/client.dart b/pkg/dds/lib/src/client.dart
index 0c854c3..f81bd25 100644
--- a/pkg/dds/lib/src/client.dart
+++ b/pkg/dds/lib/src/client.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.10
+
 import 'dart:async';
 
 import 'package:json_rpc_2/json_rpc_2.dart' as json_rpc;
diff --git a/pkg/dds/lib/src/client_manager.dart b/pkg/dds/lib/src/client_manager.dart
index b168978..c911c51 100644
--- a/pkg/dds/lib/src/client_manager.dart
+++ b/pkg/dds/lib/src/client_manager.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.10
+
 import 'package:json_rpc_2/json_rpc_2.dart' as json_rpc;
 
 import 'client.dart';
diff --git a/pkg/dds/lib/src/constants.dart b/pkg/dds/lib/src/constants.dart
index c6450d5..2466390 100644
--- a/pkg/dds/lib/src/constants.dart
+++ b/pkg/dds/lib/src/constants.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.10
+
 abstract class RPCResponses {
   static const success = <String, dynamic>{
     'type': 'Success',
diff --git a/pkg/dds/lib/src/dds_impl.dart b/pkg/dds/lib/src/dds_impl.dart
index 6daaedd..db355fb 100644
--- a/pkg/dds/lib/src/dds_impl.dart
+++ b/pkg/dds/lib/src/dds_impl.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.10
+
 import 'dart:async';
 import 'dart:convert';
 import 'dart:io';
diff --git a/pkg/dds/lib/src/expression_evaluator.dart b/pkg/dds/lib/src/expression_evaluator.dart
index bb69bb5..59bbe36 100644
--- a/pkg/dds/lib/src/expression_evaluator.dart
+++ b/pkg/dds/lib/src/expression_evaluator.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.10
+
 import 'package:json_rpc_2/json_rpc_2.dart' as json_rpc;
 
 import 'client.dart';
diff --git a/pkg/dds/lib/src/isolate_manager.dart b/pkg/dds/lib/src/isolate_manager.dart
index 2714021..a5139d5 100644
--- a/pkg/dds/lib/src/isolate_manager.dart
+++ b/pkg/dds/lib/src/isolate_manager.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.10
+
 import 'package:json_rpc_2/json_rpc_2.dart' as json_rpc;
 
 import 'client.dart';
diff --git a/pkg/dds/lib/src/logging_repository.dart b/pkg/dds/lib/src/logging_repository.dart
index f87fdaa..0b31ca6 100644
--- a/pkg/dds/lib/src/logging_repository.dart
+++ b/pkg/dds/lib/src/logging_repository.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.10
+
 import 'dart:math';
 
 import 'package:json_rpc_2/json_rpc_2.dart' as json_rpc;
diff --git a/pkg/dds/lib/src/named_lookup.dart b/pkg/dds/lib/src/named_lookup.dart
index 603bbc0..8515411 100644
--- a/pkg/dds/lib/src/named_lookup.dart
+++ b/pkg/dds/lib/src/named_lookup.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.10
+
 // Originally pulled from dart:_vmservice.
 
 import 'dart:collection';
diff --git a/pkg/dds/lib/src/rpc_error_codes.dart b/pkg/dds/lib/src/rpc_error_codes.dart
index 93c514e..895c07c 100644
--- a/pkg/dds/lib/src/rpc_error_codes.dart
+++ b/pkg/dds/lib/src/rpc_error_codes.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.10
+
 import 'package:json_rpc_2/json_rpc_2.dart' as json_rpc;
 
 abstract class RpcErrorCodes {
diff --git a/pkg/dds/lib/src/stream_manager.dart b/pkg/dds/lib/src/stream_manager.dart
index 28c7f28..26bc6d7 100644
--- a/pkg/dds/lib/src/stream_manager.dart
+++ b/pkg/dds/lib/src/stream_manager.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.10
+
 import 'dart:typed_data';
 
 import 'package:json_rpc_2/json_rpc_2.dart' as json_rpc;
diff --git a/pkg/dds/lib/vm_service_extensions.dart b/pkg/dds/lib/vm_service_extensions.dart
index 8373b87..0b6aaf4 100644
--- a/pkg/dds/lib/vm_service_extensions.dart
+++ b/pkg/dds/lib/vm_service_extensions.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.10
+
 import 'dart:async';
 import 'dart:collection';
 
diff --git a/pkg/dds/pubspec.yaml b/pkg/dds/pubspec.yaml
index 469fc0e..221e3df 100644
--- a/pkg/dds/pubspec.yaml
+++ b/pkg/dds/pubspec.yaml
@@ -3,27 +3,27 @@
   A library used to spawn the Dart Developer Service, used to communicate with
   a Dart VM Service instance.
 
-version: 1.7.5
+version: 1.7.6
 
 homepage: https://github.com/dart-lang/sdk/tree/master/pkg/dds
 
 environment:
-  sdk: '>=2.6.0 <3.0.0'
+  sdk: '>=2.12.0 <3.0.0'
 
 dependencies:
   async: ^2.4.1
   json_rpc_2: ^2.2.0
   meta: ^1.1.8
   pedantic: ^1.7.0
-  shelf: ^0.7.5
-  shelf_proxy: ^0.1.0+7
-  shelf_web_socket: ^0.2.3
+  shelf: ^1.0.0
+  shelf_proxy: ^1.0.0
+  shelf_web_socket: ^1.0.0
   sse: ^3.7.0
   stream_channel: ^2.0.0
   vm_service: ^6.0.1-nullsafety.0
-  web_socket_channel: ^1.1.0
+  web_socket_channel: ^2.0.0
 
 dev_dependencies:
-  shelf_static: ^0.2.8
+  shelf_static: ^1.0.0
   test: ^1.0.0
-  webdriver: ^2.1.2
+  webdriver: ^3.0.0
diff --git a/pkg/dds/test/auth_codes_test.dart b/pkg/dds/test/auth_codes_test.dart
index 653ff41..fa8cd44 100644
--- a/pkg/dds/test/auth_codes_test.dart
+++ b/pkg/dds/test/auth_codes_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.
 
+// @dart=2.10
+
 import 'dart:convert';
 import 'dart:io';
 
diff --git a/pkg/dds/test/common/fakes.dart b/pkg/dds/test/common/fakes.dart
index 7e11f9d..663cdd0 100644
--- a/pkg/dds/test/common/fakes.dart
+++ b/pkg/dds/test/common/fakes.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.10
+
 import 'dart:async';
 
 import 'package:json_rpc_2/json_rpc_2.dart' as json_rpc;
diff --git a/pkg/dds/test/common/test_helper.dart b/pkg/dds/test/common/test_helper.dart
index cda9ce2..7cdb204 100644
--- a/pkg/dds/test/common/test_helper.dart
+++ b/pkg/dds/test/common/test_helper.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.10
+
 import 'dart:convert';
 import 'dart:io';
 
diff --git a/pkg/dds/test/external_compilation_service_script.dart b/pkg/dds/test/external_compilation_service_script.dart
index b01ed60..00c9208 100644
--- a/pkg/dds/test/external_compilation_service_script.dart
+++ b/pkg/dds/test/external_compilation_service_script.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.10
+
 import 'dart:developer';
 
 main() {
diff --git a/pkg/dds/test/external_compilation_service_test.dart b/pkg/dds/test/external_compilation_service_test.dart
index 92e5ac8..f31b9c0 100644
--- a/pkg/dds/test/external_compilation_service_test.dart
+++ b/pkg/dds/test/external_compilation_service_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.
 
+// @dart=2.10
+
 import 'dart:io';
 
 import 'package:dds/dds.dart';
diff --git a/pkg/dds/test/get_stream_history_script.dart b/pkg/dds/test/get_stream_history_script.dart
index 68dafec..1f8b820 100644
--- a/pkg/dds/test/get_stream_history_script.dart
+++ b/pkg/dds/test/get_stream_history_script.dart
@@ -1,3 +1,5 @@
+// @dart = 2.10
+
 import 'dart:developer';
 
 void main() {
diff --git a/pkg/dds/test/get_stream_history_test.dart b/pkg/dds/test/get_stream_history_test.dart
index c2ae8f9..6631d24 100644
--- a/pkg/dds/test/get_stream_history_test.dart
+++ b/pkg/dds/test/get_stream_history_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.
 
+// @dart=2.10
+
 import 'dart:io';
 
 import 'package:dds/dds.dart';
diff --git a/pkg/dds/test/handles_client_disconnect_state_error_test.dart b/pkg/dds/test/handles_client_disconnect_state_error_test.dart
index 87d027c..974814a 100644
--- a/pkg/dds/test/handles_client_disconnect_state_error_test.dart
+++ b/pkg/dds/test/handles_client_disconnect_state_error_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.
 
+// @dart=2.10
+
 import 'dart:async';
 
 import 'package:dds/dds.dart';
diff --git a/pkg/dds/test/handles_connection_closed_before_full_header.dart b/pkg/dds/test/handles_connection_closed_before_full_header.dart
index 80f1744..7be1043 100644
--- a/pkg/dds/test/handles_connection_closed_before_full_header.dart
+++ b/pkg/dds/test/handles_connection_closed_before_full_header.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.10
+
 import 'dart:async';
 import 'dart:io';
 
diff --git a/pkg/dds/test/on_event_with_history_script.dart b/pkg/dds/test/on_event_with_history_script.dart
index 3f27df0..e35decc 100644
--- a/pkg/dds/test/on_event_with_history_script.dart
+++ b/pkg/dds/test/on_event_with_history_script.dart
@@ -1,3 +1,5 @@
+// @dart=2.10
+
 import 'dart:developer';
 
 void main() {
diff --git a/pkg/dds/test/on_event_with_history_test.dart b/pkg/dds/test/on_event_with_history_test.dart
index 55e04b9..42f25a1 100644
--- a/pkg/dds/test/on_event_with_history_test.dart
+++ b/pkg/dds/test/on_event_with_history_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.
 
+// @dart=2.10
+
 import 'dart:async';
 import 'dart:io';
 
diff --git a/pkg/dds/test/smoke.dart b/pkg/dds/test/smoke.dart
index f4c4774..f1f92a2 100644
--- a/pkg/dds/test/smoke.dart
+++ b/pkg/dds/test/smoke.dart
@@ -1,3 +1,5 @@
+// @dart=2.10
+
 void main() {
   print('Hello world!');
 }
diff --git a/pkg/dds/test/smoke_test.dart b/pkg/dds/test/smoke_test.dart
index 983a2da..2f59ef0 100644
--- a/pkg/dds/test/smoke_test.dart
+++ b/pkg/dds/test/smoke_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.
 
+// @dart=2.10
+
 import 'dart:convert';
 import 'dart:io';
 
diff --git a/pkg/dds/test/sse_smoke_test.dart b/pkg/dds/test/sse_smoke_test.dart
index 9d4a9a6..2b5e696 100644
--- a/pkg/dds/test/sse_smoke_test.dart
+++ b/pkg/dds/test/sse_smoke_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.
 
+// @dart=2.10
+
 import 'dart:async';
 import 'dart:convert';
 import 'dart:io';
diff --git a/pkg/dds/test/uri_test.dart b/pkg/dds/test/uri_test.dart
index 8c7e64e..dad20f3 100644
--- a/pkg/dds/test/uri_test.dart
+++ b/pkg/dds/test/uri_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.
 
+// @dart=2.10
+
 import 'dart:io';
 
 import 'package:dds/dds.dart';
diff --git a/pkg/dds/test/web/sse_smoke_driver.dart b/pkg/dds/test/web/sse_smoke_driver.dart
index 4f0ab25..f8769f5 100644
--- a/pkg/dds/test/web/sse_smoke_driver.dart
+++ b/pkg/dds/test/web/sse_smoke_driver.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.10
+
 // This file must be compiled for changes to be picked up.
 //
 // Run the following command from the root of this package if this file is
diff --git a/pkg/dev_compiler/analysis_options.yaml b/pkg/dev_compiler/analysis_options.yaml
index 6a33ce2..4c72ad8 100644
--- a/pkg/dev_compiler/analysis_options.yaml
+++ b/pkg/dev_compiler/analysis_options.yaml
@@ -1,4 +1,4 @@
-include: package:pedantic/analysis_options.1.9.0.yaml
+include: package:pedantic/analysis_options.1.11.0.yaml
 
 analyzer:
   strong-mode:
diff --git a/pkg/dev_compiler/bin/dartdevc.dart b/pkg/dev_compiler/bin/dartdevc.dart
index 87da5bb..4d8d197 100755
--- a/pkg/dev_compiler/bin/dartdevc.dart
+++ b/pkg/dev_compiler/bin/dartdevc.dart
@@ -32,20 +32,8 @@
   } else if (parsedArgs.isBatch) {
     await runBatch(parsedArgs);
   } else if (parsedArgs.isExpressionCompiler) {
-    if (sendPort != null) {
-      var receivePort = ReceivePort();
-      sendPort.send(receivePort.sendPort);
-      var worker = await ExpressionCompilerWorker.createFromArgs(
-          parsedArgs.rest,
-          requestStream: receivePort.cast<Map<String, dynamic>>(),
-          sendResponse: sendPort.send);
-      await worker.start();
-      receivePort.close();
-    } else {
-      var worker =
-          await ExpressionCompilerWorker.createFromArgs(parsedArgs.rest);
-      await worker.start();
-    }
+    await ExpressionCompilerWorker.createAndStart(parsedArgs.rest,
+        sendPort: sendPort);
   } else {
     var result = await compile(parsedArgs);
     exitCode = result.exitCode;
diff --git a/pkg/dev_compiler/lib/src/compiler/js_names.dart b/pkg/dev_compiler/lib/src/compiler/js_names.dart
index 81e3899..3295e0c 100644
--- a/pkg/dev_compiler/lib/src/compiler/js_names.dart
+++ b/pkg/dev_compiler/lib/src/compiler/js_names.dart
@@ -246,11 +246,11 @@
       // If collisions become common we need a better search.
       // TODO(jmesserly): what's the most readable scheme here? Maybe 1-letter
       // names in some cases?
-      candidate = name == 'function' ? 'func' : '${name}\$';
+      candidate = name == 'function' ? 'func' : '$name\$';
       for (var i = 0;
           scopes.any((scope) => scope.used.contains(candidate));
           i++) {
-        candidate = '${name}\$$i';
+        candidate = '$name\$$i';
       }
     }
     return candidate;
diff --git a/pkg/dev_compiler/lib/src/compiler/module_builder.dart b/pkg/dev_compiler/lib/src/compiler/module_builder.dart
index 847185d..922b17f 100644
--- a/pkg/dev_compiler/lib/src/compiler/module_builder.dart
+++ b/pkg/dev_compiler/lib/src/compiler/module_builder.dart
@@ -96,6 +96,30 @@
   }
 }
 
+/// Transforms an ES6 [function] into a given module [format].
+///
+/// If the format is [ModuleFormat.es6] this will return [function] unchanged.
+///
+/// Because JS ASTs are immutable the resulting function will share as much
+/// structure as possible with the original. The transformation is a shallow one
+/// that affects the [ImportDeclaration]s from [items].
+///
+/// Returns a new function that combines all statements from tranformed imports
+/// from [items] and the body of the [function].
+Fun transformFunctionModuleFormat(
+    List<ModuleItem> items, Fun function, ModuleFormat format) {
+  switch (format) {
+    case ModuleFormat.ddc:
+      // Legacy format always generates output compatible with single file mode.
+      return DdcModuleBuilder().buildFunctionWithImports(items, function);
+    case ModuleFormat.amd:
+      return AmdModuleBuilder().buildFunctionWithImports(items, function);
+    default:
+      throw UnsupportedError(
+          'Incremental build does not support $format module format');
+  }
+}
+
 /// Base class for compiling ES6 modules into various ES5 module patterns.
 ///
 /// This is a helper class for utilities and state that is shared by several
@@ -107,11 +131,16 @@
   final statements = <Statement>[];
 
   /// Collect [imports], [exports] and [statements] from the ES6 [module].
+  void visitProgram(Program module) {
+    visitModuleItems(module.body);
+  }
+
+  /// Collect [imports], [exports] and [statements] from the ES6 [items].
   ///
   /// For exports, this will also add their body to [statements] in the
   /// appropriate position.
-  void visitProgram(Program module) {
-    for (var item in module.body) {
+  void visitModuleItems(List<ModuleItem> items) {
+    for (var item in items) {
       if (item is ImportDeclaration) {
         visitImportDeclaration(item);
       } else if (item is ExportDeclaration) {
@@ -137,60 +166,124 @@
   void visitStatement(Statement node) {
     statements.add(node);
   }
+
+  void clear() {
+    imports.clear();
+    exports.clear();
+    statements.clear();
+  }
 }
 
 /// Generates modules for with our DDC `dart_library.js` loading mechanism.
 // TODO(jmesserly): remove this and replace with something that interoperates.
 class DdcModuleBuilder extends _ModuleBuilder {
-  Program build(Program module) {
-    // Collect imports/exports/statements.
-    visitProgram(module);
+  /// Build a module variable definition for [import].
+  ///
+  /// Used to load modules referenced in the expression during expression
+  /// evaluation.
+  static Statement buildLoadModule(
+          Identifier moduleVar, ImportDeclaration import) =>
+      js.statement(
+          'const # = dart_library.import(#);', [moduleVar, import.from]);
 
-    // Build import parameters.
-    var exportsVar = TemporaryId('exports');
-    var parameters = <TemporaryId>[exportsVar];
-    var importNames = <Expression>[];
-    var importStatements = <Statement>[];
-    for (var import in imports) {
-      importNames.add(import.from);
-      // TODO(jmesserly): we could use destructuring here.
-      var moduleVar =
-          TemporaryId(pathToJSIdentifier(import.from.valueWithoutQuotes));
-      parameters.add(moduleVar);
-      for (var importName in import.namedImports) {
-        assert(!importName
-            .isStar); // import * not supported in ddc format modules.
-        var asName = importName.asName ?? importName.name;
-        var fromName = importName.name.name;
-        // Load non-SDK modules on demand (i.e., deferred).
-        if (import.from.valueWithoutQuotes != dartSdkModule) {
-          importStatements.add(js.statement(
-              'let # = dart_library.defer(#, #, function (mod, lib) {'
-              '  # = mod;'
-              '  # = lib;'
-              '});',
-              [asName, moduleVar, js.string(fromName), moduleVar, asName]));
-        } else {
-          importStatements.add(js.statement(
-              'const # = #.#', [asName, moduleVar, importName.name.name]));
-        }
+  /// Build library variable definitions for all libraries from [import].
+  static List<Statement> buildImports(
+      Identifier moduleVar, ImportDeclaration import, bool deferModules) {
+    var items = <Statement>[];
+
+    for (var importName in import.namedImports) {
+      // import * is not emitted by the compiler, so we don't handle it here.
+      assert(!importName.isStar);
+      var asName = importName.asName ?? importName.name;
+      var fromName = importName.name.name;
+      // Load non-SDK modules on demand (i.e., deferred).
+      if (deferModules && import.from.valueWithoutQuotes != dartSdkModule) {
+        items.add(js.statement(
+            'let # = dart_library.defer(#, #, function (mod, lib) {'
+            '  # = mod;'
+            '  # = lib;'
+            '});',
+            [asName, moduleVar, js.string(fromName), moduleVar, asName]));
+      } else {
+        items.add(js.statement('const # = #.#', [asName, moduleVar, fromName]));
       }
     }
-    statements.insertAll(0, importStatements);
+    return items;
+  }
+
+  /// Build statements for [exports].
+  static List<Statement> buildExports(
+      Identifier exportsVar, List<ExportDeclaration> exports) {
+    var items = <Statement>[];
 
     if (exports.isNotEmpty) {
-      statements.add(js.comment('Exports:'));
+      items.add(js.comment('Exports:'));
       // TODO(jmesserly): make these immutable in JS?
       for (var export in exports) {
         var names = export.exportedNames;
         assert(names != null); // export * not supported in ddc modules.
         for (var name in names) {
           var alias = name.asName ?? name.name;
-          statements.add(
+          items.add(
               js.statement('#.# = #;', [exportsVar, alias.name, name.name]));
         }
       }
     }
+    return items;
+  }
+
+  /// Build function body with all necessary imports included.
+  ///
+  /// Used for the top level synthetic function generated during expression
+  /// compilation, in order to include all the context needed for evaluation
+  /// inside it.
+  ///
+  /// Returns a new function that combines all statements from tranformed
+  /// imports from [items] and the body of the [function].
+  Fun buildFunctionWithImports(List<ModuleItem> items, Fun function) {
+    clear();
+    visitModuleItems(items);
+
+    var moduleImports = _collectModuleImports(imports);
+    var importStatements = <Statement>[];
+
+    for (var p in moduleImports) {
+      var moduleVar = p.key;
+      var import = p.value;
+      importStatements.add(buildLoadModule(moduleVar, import));
+      importStatements.addAll(buildImports(moduleVar, import, false));
+    }
+
+    return Fun(
+      function.params,
+      Block([...importStatements, ...statements, ...function.body.statements]),
+    );
+  }
+
+  Program build(Program module) {
+    // Collect imports/exports/statements.
+    visitProgram(module);
+
+    var exportsVar = TemporaryId('exports');
+    var parameters = <Identifier>[exportsVar];
+    var importNames = <Expression>[];
+
+    var moduleImports = _collectModuleImports(imports);
+    var importStatements = <Statement>[];
+
+    for (var p in moduleImports) {
+      var moduleVar = p.key;
+      var import = p.value;
+      importNames.add(import.from);
+      parameters.add(moduleVar);
+      importStatements.addAll(buildImports(moduleVar, import, true));
+    }
+
+    // Prepend import statetements.
+    statements.insertAll(0, importStatements);
+
+    // Append export statements.
+    statements.addAll(buildExports(exportsVar, exports));
 
     var resultModule = NamedFunction(
         loadFunctionIdentifier(module.name),
@@ -260,31 +353,32 @@
 class AmdModuleBuilder extends _ModuleBuilder {
   AmdModuleBuilder();
 
-  Program build(Program module) {
-    var importStatements = <Statement>[];
+  /// Build a module variable definition for [import].
+  ///
+  /// Used to load modules referenced in the expression during expression
+  /// evaluation.
+  static Statement buildLoadModule(
+          Identifier moduleVar, ImportDeclaration import) =>
+      js.statement('const # = require(#);', [moduleVar, import.from]);
 
-    // Collect imports/exports/statements.
-    visitProgram(module);
+  /// Build library variable definitions for all libraries from [import].
+  static List<Statement> buildImports(
+      Identifier moduleVar, ImportDeclaration import) {
+    var items = <Statement>[];
 
-    var dependencies = <LiteralString>[];
-    var fnParams = <Parameter>[];
-    for (var import in imports) {
-      // TODO(jmesserly): we could use destructuring once Atom supports it.
-      var moduleVar =
-          TemporaryId(pathToJSIdentifier(import.from.valueWithoutQuotes));
-      fnParams.add(moduleVar);
-      dependencies.add(import.from);
-
-      // TODO(jmesserly): optimize for the common case of a single import.
-      for (var importName in import.namedImports) {
-        // import * is not emitted by the compiler, so we don't handle it here.
-        assert(!importName.isStar);
-        var asName = importName.asName ?? importName.name;
-        importStatements.add(js.statement(
-            'const # = #.#', [asName, moduleVar, importName.name.name]));
-      }
+    for (var importName in import.namedImports) {
+      // import * is not emitted by the compiler, so we don't handle it here.
+      assert(!importName.isStar);
+      var asName = importName.asName ?? importName.name;
+      items.add(js.statement(
+          'const # = #.#', [asName, moduleVar, importName.name.name]));
     }
-    statements.insertAll(0, importStatements);
+    return items;
+  }
+
+  /// Build statements for [exports].
+  static List<Statement> buildExports(List<ExportDeclaration> exports) {
+    var items = <Statement>[];
 
     if (exports.isNotEmpty) {
       var exportedProps = <Property>[];
@@ -297,9 +391,63 @@
           exportedProps.add(Property(js.string(alias.name), name.name));
         }
       }
-      statements.add(js.comment('Exports:'));
-      statements.add(Return(ObjectInitializer(exportedProps, multiline: true)));
+      items.add(js.comment('Exports:'));
+      items.add(Return(ObjectInitializer(exportedProps, multiline: true)));
     }
+    return items;
+  }
+
+  /// Build function body with all necessary imports included.
+  ///
+  /// Used for the top level synthetic function generated during expression
+  /// compilation, in order to include all the context needed for evaluation
+  /// inside it.
+  ///
+  /// Returns a new function that combines all statements from tranformed
+  /// imports from [items] and the body of the [function].
+  Fun buildFunctionWithImports(List<ModuleItem> items, Fun function) {
+    clear();
+    visitModuleItems(items);
+
+    var moduleImports = _collectModuleImports(imports);
+    var importStatements = <Statement>[];
+
+    for (var p in moduleImports) {
+      var moduleVar = p.key;
+      var import = p.value;
+      importStatements.add(buildLoadModule(moduleVar, import));
+      importStatements.addAll(buildImports(moduleVar, import));
+    }
+
+    return Fun(
+      function.params,
+      Block([...importStatements, ...statements, ...function.body.statements]),
+    );
+  }
+
+  Program build(Program module) {
+    // Collect imports/exports/statements.
+    visitProgram(module);
+
+    var moduleImports = _collectModuleImports(imports);
+    var importStatements = <Statement>[];
+    var fnParams = <Identifier>[];
+    var dependencies = <LiteralString>[];
+
+    for (var p in moduleImports) {
+      var moduleVar = p.key;
+      var import = p.value;
+      fnParams.add(moduleVar);
+      dependencies.add(import.from);
+      importStatements.addAll(buildImports(moduleVar, import));
+    }
+
+    // Prepend import statetements.
+    statements.insertAll(0, importStatements);
+
+    // Append export statements.
+    statements.addAll(buildExports(exports));
+
     var resultModule = NamedFunction(
         loadFunctionIdentifier(module.name),
         js.fun("function(#) { 'use strict'; #; }", [fnParams, statements]),
@@ -350,3 +498,17 @@
 
 // Replacement string for path separators (i.e., '/', '\', '..').
 final encodedSeparator = '__';
+
+/// Group libraries from [imports] by modules.
+List<MapEntry<Identifier, ImportDeclaration>> _collectModuleImports(
+    List<ImportDeclaration> imports) {
+  var result = <MapEntry<Identifier, ImportDeclaration>>[];
+  for (var import in imports) {
+    // TODO(jmesserly): we could use destructuring once Atom supports it.
+    var moduleVar =
+        TemporaryId(pathToJSIdentifier(import.from.valueWithoutQuotes));
+
+    result.add(MapEntry<Identifier, ImportDeclaration>(moduleVar, import));
+  }
+  return result;
+}
diff --git a/pkg/dev_compiler/lib/src/compiler/module_containers.dart b/pkg/dev_compiler/lib/src/compiler/module_containers.dart
index 2e03a63..0040d60 100644
--- a/pkg/dev_compiler/lib/src/compiler/module_containers.dart
+++ b/pkg/dev_compiler/lib/src/compiler/module_containers.dart
@@ -8,6 +8,9 @@
 import '../js_ast/js_ast.dart' as js_ast;
 import '../js_ast/js_ast.dart' show js;
 
+/// Defines how to emit a value of a table
+typedef _emitValue<K> = js_ast.Expression Function(K, ModuleItemData);
+
 /// Represents a top-level property hoisted to a top-level object.
 class ModuleItemData {
   /// The container that holds this module item in the emitted JS.
@@ -39,34 +42,39 @@
   /// Name of the container in the emitted JS.
   String name;
 
-  /// Indicates if this table is being used in an incremental context (such as
-  /// during expression evaluation).
-  ///
-  /// Set by `emitFunctionIncremental` in kernel/compiler.dart.
-  bool incrementalMode = false;
-
   /// Refers to the latest container if this container is sharded.
   js_ast.Identifier containerId;
 
-  /// Refers to the aggregated entrypoint into this container.
-  ///
-  /// Should only be accessed during expression evaluation since lookups are
-  /// deoptimized in V8..
-  js_ast.Identifier aggregatedContainerId;
-
   final Map<K, ModuleItemData> moduleItems = {};
 
+  /// Incremental mode used for expression compilation
+  bool _incrementalMode = false;
+
+  /// Items accessed during incremental mode
+  final Set<K> incrementalModuleItems = {};
+
+  /// Indicates if this table is being used in an incremental context.
+  ///
+  /// Used during expression evaluation.
+  /// Set by `emitFunctionIncremental` in kernel/compiler.dart.
+  bool get incrementalMode => _incrementalMode;
+
+  /// Sets the container to incremental mode.
+  ///
+  /// Used during expression evaluating so only referenced items
+  /// will be emitted in a generated function.
+  ///
+  /// Note: the container cannot revert to non-incremental mode.
+  void setIncrementalMode() {
+    incrementalModuleItems.clear();
+    _incrementalMode = true;
+  }
+
   /// Holds keys that will not be emitted when calling [emit].
   final Set<K> _noEmit = {};
 
-  /// Creates a container with a name, ID, and incremental ID used for
-  /// expression evaluation.
-  ///
-  /// If [aggregatedId] is null, the container is not sharded, so the
-  /// containerId is safe to use during eval.
-  ModuleItemContainer._(
-      this.name, this.containerId, js_ast.Identifier aggregatedId)
-      : aggregatedContainerId = aggregatedId ?? containerId;
+  /// Creates a container with a name, ID
+  ModuleItemContainer._(this.name, this.containerId);
 
   /// Creates an automatically sharding container backed by JS Objects.
   factory ModuleItemContainer.asObject(String name,
@@ -107,15 +115,17 @@
     _noEmit.add(key);
   }
 
+  void setEmitIfIncremental(K key) {
+    if (incrementalMode) {
+      incrementalModuleItems.add(key);
+    }
+  }
+
   /// Emit the container declaration/initializer, using multiple statements if
   /// necessary.
-  List<js_ast.Statement> emit();
-
-  /// Emit the container declaration/initializer incrementally.
   ///
-  /// Used during expression evaluation. Appends all newly added types to the
-  /// aggregated container.
-  List<js_ast.Statement> emitIncremental();
+  /// Uses [emitValue] to emit the values in the table.
+  List<js_ast.Statement> emit({_emitValue<K> emitValue});
 }
 
 /// Associates a [K] with a container-unique JS key and arbitrary JS value.
@@ -142,8 +152,7 @@
   String Function(K) keyToString;
 
   ModuleItemObjectContainer(String name, this.keyToString)
-      : super._(
-            name, js_ast.TemporaryId(name), js_ast.Identifier('${name}\$Eval'));
+      : super._(name, js_ast.TemporaryId(name));
 
   @override
   void operator []=(K key, js_ast.Expression value) {
@@ -170,53 +179,33 @@
 
   @override
   js_ast.Expression access(K key) {
-    var id = incrementalMode ? aggregatedContainerId : moduleItems[key].id;
+    var id = moduleItems[key].id;
     return js.call('#.#', [id, moduleItems[key].jsKey]);
   }
 
   @override
-  List<js_ast.Statement> emit() {
+  List<js_ast.Statement> emit({_emitValue<K> emitValue}) {
     var containersToProperties = <js_ast.Identifier, List<js_ast.Property>>{};
     moduleItems.forEach((k, v) {
-      if (_noEmit.contains(k)) return;
+      if (!incrementalMode && _noEmit.contains(k)) return;
+      if (incrementalMode && !incrementalModuleItems.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));
+      containersToProperties[v.id].add(js_ast.Property(
+          v.jsKey, emitValue == null ? v.jsValue : emitValue(k, v)));
     });
 
-    // Emit a self-reference for the next container so V8 does not optimize it
-    // away. Required for expression evaluation.
-    if (containersToProperties[containerId] == null) {
-      containersToProperties[containerId] = [
-        js_ast.Property(
-            js_ast.LiteralString('_'), js.call('() => #', [containerId]))
-      ];
-    }
+    if (containersToProperties.isEmpty) return [];
+
     var statements = <js_ast.Statement>[];
-    var aggregatedContainers = <js_ast.Expression>[];
     containersToProperties.forEach((containerId, properties) {
       var containerObject = js_ast.ObjectInitializer(properties,
           multiline: properties.length > 1);
       statements.add(js.statement('var # = #', [containerId, containerObject]));
-      aggregatedContainers.add(js.call('#', [containerId]));
     });
-    // Create an aggregated access point over all containers for eval.
-    statements.add(js.statement('var # = Object.assign({_ : () => #}, #)',
-        [aggregatedContainerId, aggregatedContainerId, aggregatedContainers]));
-    return statements;
-  }
 
-  /// Appends all newly added types to the most recent container.
-  @override
-  List<js_ast.Statement> emitIncremental() {
-    assert(incrementalMode);
-    var statements = <js_ast.Statement>[];
-    moduleItems.forEach((k, v) {
-      if (_noEmit.contains(k)) return;
-      statements.add(js
-          .statement('#[#] = #', [aggregatedContainerId, v.jsKey, v.jsValue]));
-    });
     return statements;
   }
 }
@@ -232,7 +221,7 @@
 /// ```
 class ModuleItemArrayContainer<K> extends ModuleItemContainer<K> {
   ModuleItemArrayContainer(String name)
-      : super._(name, js_ast.TemporaryId(name), null);
+      : super._(name, js_ast.TemporaryId(name));
 
   @override
   void operator []=(K key, js_ast.Expression value) {
@@ -246,23 +235,26 @@
 
   @override
   js_ast.Expression access(K key) {
-    var id = incrementalMode ? aggregatedContainerId : containerId;
+    var id = containerId;
     return js.call('#[#]', [id, moduleItems[key].jsKey]);
   }
 
   @override
-  List<js_ast.Statement> emit() {
+  List<js_ast.Statement> emit({_emitValue<K> emitValue}) {
     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;
+      if (!incrementalMode && _noEmit.contains(k)) return;
+      if (incrementalMode && !incrementalModuleItems.contains(k)) return;
       valueSet.add(v.jsValue);
       properties[int.parse((v.jsKey as js_ast.LiteralNumber).value)] =
-          v.jsValue;
+          emitValue == null ? v.jsValue : emitValue(k, v);
     });
 
+    if (valueSet.isEmpty) return [];
+
     if (valueSet.length == 1 && moduleItems.length > 1) {
       return [
         js.statement('var # = Array(#).fill(#)', [
@@ -281,16 +273,4 @@
       ])
     ];
   }
-
-  @override
-  List<js_ast.Statement> emitIncremental() {
-    assert(incrementalMode);
-    var statements = <js_ast.Statement>[];
-    moduleItems.forEach((k, v) {
-      if (_noEmit.contains(k)) return;
-      statements.add(js
-          .statement('#[#] = #', [aggregatedContainerId, v.jsKey, v.jsValue]));
-    });
-    return statements;
-  }
 }
diff --git a/pkg/dev_compiler/lib/src/compiler/shared_compiler.dart b/pkg/dev_compiler/lib/src/compiler/shared_compiler.dart
index 363ff0b..d83b346 100644
--- a/pkg/dev_compiler/lib/src/compiler/shared_compiler.dart
+++ b/pkg/dev_compiler/lib/src/compiler/shared_compiler.dart
@@ -30,6 +30,9 @@
   final _symbolContainer = ModuleItemContainer<js_ast.Identifier>.asObject('S',
       keyToString: (js_ast.Identifier i) => '${i.name}');
 
+  ModuleItemContainer<js_ast.Identifier> get symbolContainer =>
+      _symbolContainer;
+
   /// Extension member symbols for adding Dart members to JS types.
   ///
   /// These are added to the [extensionSymbolsModule]; see that field for more
@@ -43,6 +46,47 @@
   /// Imported libraries, and the temporaries used to refer to them.
   final _imports = <Library, js_ast.TemporaryId>{};
 
+  /// Incremental mode for expression compilation.
+  ///
+  /// If set to true, triggers emitting tall used ypes, symbols, libraries,
+  /// constants, urs inside the generated function.
+  bool _incrementalMode = false;
+
+  @protected
+  bool get incrementalMode => _incrementalMode;
+
+  /// Set incremental mode for one expression compilation.
+  ///
+  /// Sets all tables and internal structures to incremental mode so
+  /// only referenced items will be emitted in a generated function.
+  ///
+  /// Note: the compiler cannot revert to non-incremental mode.
+  @protected
+  void setIncrementalMode() {
+    incrementalModules.clear();
+    _privateNames.clear();
+    symbolContainer.setIncrementalMode();
+    _incrementalMode = true;
+  }
+
+  /// Modules and libraries accessed during compilation in incremental mode.
+  @protected
+  final Map<String, Set<String>> incrementalModules = {};
+
+  @protected
+  void setEmitIfIncrementalLibrary(Library library) {
+    if (incrementalMode && library != null) {
+      setEmitIfIncremental(libraryToModule(library), jsLibraryName(library));
+    }
+  }
+
+  @protected
+  void setEmitIfIncremental(String module, String library) {
+    if (incrementalMode && library != null) {
+      incrementalModules.putIfAbsent(module, () => {}).add(library);
+    }
+  }
+
   /// The identifier used to reference DDC's core "dart:_runtime" library from
   /// generated JS code, typically called "dart" e.g. `dart.dcall`.
   js_ast.Identifier runtimeModule;
@@ -220,8 +264,10 @@
   ///     dart.asInt(<expr>)
   ///
   @protected
-  js_ast.Expression runtimeCall(String code, [List<Object> args]) =>
-      js.call('#.$code', <Object>[runtimeModule, ...?args]);
+  js_ast.Expression runtimeCall(String code, [List<Object> args]) {
+    setEmitIfIncremental(libraryToModule(coreLibrary), runtimeModule.name);
+    return js.call('#.$code', <Object>[runtimeModule, ...?args]);
+  }
 
   /// Calls [runtimeCall] and uses `toStatement()` to convert the resulting
   /// expression into a statement.
@@ -276,7 +322,13 @@
     }
 
     var privateNames = _privateNames.putIfAbsent(library, () => HashMap());
-    return privateNames.putIfAbsent(name, initPrivateNameSymbol);
+    var symbolId = privateNames.putIfAbsent(name, initPrivateNameSymbol);
+
+    setEmitIfIncrementalLibrary(library);
+    setEmitIfIncremental(libraryToModule(coreLibrary), runtimeModule.name);
+    _symbolContainer.setEmitIfIncremental(symbolId);
+
+    return symbolId;
   }
 
   /// Emits a private name JS Symbol for [memberName] unique to a Dart
@@ -445,7 +497,6 @@
           .statement('var # = Object.create(#.library)', [id, runtimeModule]));
       exports.add(js_ast.NameSpecifier(id));
     }
-
     items.add(js_ast.ExportDeclaration(js_ast.ExportClause(exports)));
 
     if (isBuildingSdk) {
@@ -469,6 +520,8 @@
 
   /// Returns the canonical name to refer to the Dart library.
   js_ast.Identifier emitLibraryName(Library library) {
+    setEmitIfIncrementalLibrary(library);
+
     // Avoid adding the dart:_runtime to _imports when our runtime unit tests
     // import it explicitly. It will always be implicitly imported.
     if (isSdkInternalRuntime(library)) return runtimeModule;
@@ -479,12 +532,10 @@
             library, () => js_ast.TemporaryId(jsLibraryName(library)));
   }
 
-  /// Emits imports and extension methods into [items].
+  /// Emits imports into [items].
   @protected
-  void emitImportsAndExtensionSymbols(List<js_ast.ModuleItem> items,
-      {bool forceExtensionSymbols = false}) {
+  void emitImports(List<js_ast.ModuleItem> items) {
     var modules = <String, List<Library>>{};
-
     for (var import in _imports.keys) {
       modules.putIfAbsent(libraryToModule(import), () => []).add(import);
     }
@@ -493,33 +544,57 @@
     if (!_libraries.containsKey(coreLibrary)) {
       coreModuleName = libraryToModule(coreLibrary);
     }
+
     modules.forEach((module, libraries) {
-      // Generate import directives.
-      //
-      // Our import variables are temps and can get renamed. Since our renaming
-      // is integrated into js_ast, it is aware of this possibility and will
-      // generate an "as" if needed. For example:
-      //
-      //     import {foo} from 'foo';         // if no rename needed
-      //     import {foo as foo$} from 'foo'; // if rename was needed
-      //
-      var imports = libraries.map((library) {
-        var alias = jsLibraryAlias(library);
-        if (alias != null) {
-          var aliasId = js_ast.TemporaryId(alias);
-          return js_ast.NameSpecifier(aliasId, asName: _imports[library]);
+      if (!incrementalMode || incrementalModules.containsKey(module)) {
+        var usedLibraries = incrementalModules[module];
+
+        // Generate import directives.
+        //
+        // Our import variables are temps and can get renamed. Since our renaming
+        // is integrated into js_ast, it is aware of this possibility and will
+        // generate an "as" if needed. For example:
+        //
+        //     import {foo} from 'foo';         // if no rename needed
+        //     import {foo as foo$} from 'foo'; // if rename was needed
+        //
+        var imports = <js_ast.NameSpecifier>[];
+        for (var library in libraries) {
+          if (!incrementalMode ||
+              usedLibraries.contains(jsLibraryName(library))) {
+            var alias = jsLibraryAlias(library);
+            if (alias != null) {
+              var aliasId = js_ast.TemporaryId(alias);
+              imports.add(
+                  js_ast.NameSpecifier(aliasId, asName: _imports[library]));
+            } else {
+              imports.add(js_ast.NameSpecifier(_imports[library]));
+            }
+          }
         }
-        return js_ast.NameSpecifier(_imports[library]);
-      }).toList();
-      if (module == coreModuleName) {
-        imports.add(js_ast.NameSpecifier(runtimeModule));
-        imports.add(js_ast.NameSpecifier(extensionSymbolsModule));
+
+        if (module == coreModuleName) {
+          if (!incrementalMode || usedLibraries.contains(runtimeModule.name)) {
+            imports.add(js_ast.NameSpecifier(runtimeModule));
+          }
+          if (!incrementalMode ||
+              usedLibraries.contains(extensionSymbolsModule.name)) {
+            imports.add(js_ast.NameSpecifier(extensionSymbolsModule));
+          }
+        }
+
+        if (!incrementalMode || imports.isNotEmpty) {
+          items.add(js_ast.ImportDeclaration(
+              namedImports: imports, from: js.string(module, "'")));
+        }
       }
-
-      items.add(js_ast.ImportDeclaration(
-          namedImports: imports, from: js.string(module, "'")));
     });
+  }
 
+  /// Emits extension methods into [items].
+  @protected
+  void emitExtensionSymbols(List<js_ast.ModuleItem> items,
+      {bool forceExtensionSymbols = false}) {
     // Initialize extension symbols
     _extensionSymbols.forEach((name, id) {
       js_ast.Expression value =
@@ -530,16 +605,84 @@
         value = js.call(
             '# || (# = Symbol(#))', [value, value, js.string('dartx.$name')]);
       }
-      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]));
+      // Emit hoisted extension symbols that are marked as noEmit in regular as
+      // well as incremental mode (if needed) since they are going to be
+      // referenced as such in the generated expression.
+      if (!incrementalMode ||
+          _symbolContainer.incrementalModuleItems.contains(id)) {
+        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]));
+        }
+      }
+      if (_symbolContainer.incrementalModuleItems.contains(id)) {
+        setEmitIfIncremental(
+            libraryToModule(coreLibrary), extensionSymbolsModule.name);
       }
       _symbolContainer[id] = value;
     });
   }
 
+  /// Emits exports as imports into [items].
+  ///
+  /// Use information from exports to re-define library variables referenced
+  /// inside compiled expressions in incremental mode. That matches importing
+  /// a current module into the symbol used to represent the library during
+  /// original compilation in [ProgramCompiler.emitModule].
+  ///
+  /// Example of exports emitted to JavaScript during emitModule:
+  ///
+  /// ```
+  /// dart.trackLibraries("web/main", { ... });
+  /// // Exports:
+  /// return {
+  ///  web__main: main
+  /// };
+  /// ```
+  ///
+  /// The transformation to imports during expression compilation converts the
+  /// exports above to:
+  ///
+  /// ```
+  /// const web__main = require('web/main');
+  /// const main = web__main.web__main;
+  /// ```
+  ///
+  /// Where the compiled expression references `main`.
+  @protected
+  void emitExportsAsImports(List<js_ast.ModuleItem> items, Library current) {
+    var exports = <js_ast.NameSpecifier>[];
+    assert(incrementalMode);
+    assert(!isBuildingSdk);
+
+    var module = libraryToModule(current);
+    var usedLibraries = incrementalModules[module] ?? {};
+
+    if (usedLibraries.isNotEmpty) {
+      _libraries.forEach((library, libraryId) {
+        if (usedLibraries.contains(jsLibraryName(library))) {
+          var alias = jsLibraryAlias(library);
+          var aliasId = alias == null ? libraryId : js_ast.TemporaryId(alias);
+          var asName = alias == null ? null : libraryId;
+          exports.add(js_ast.NameSpecifier(aliasId, asName: asName));
+        }
+      });
+
+      items.add(js_ast.ImportDeclaration(
+          namedImports: exports, from: js.string(module, "'")));
+    }
+  }
+
+  /// Emits imports and extension methods into [items].
+  @protected
+  void emitImportsAndExtensionSymbols(List<js_ast.ModuleItem> items,
+      {bool forceExtensionSymbols = false}) {
+    emitImports(items);
+    emitExtensionSymbols(items, forceExtensionSymbols: forceExtensionSymbols);
+  }
+
   void _emitDebuggerExtensionInfo(String name) {
     var properties = <js_ast.Property>[];
     var parts = <js_ast.Property>[];
@@ -568,27 +711,26 @@
   ///
   /// A symbol lookup on an id marked no emit omits the symbol accessor.
   js_ast.Expression getSymbol(js_ast.Identifier id) {
+    _symbolContainer.setEmitIfIncremental(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) {
+    _symbolContainer.setEmitIfIncremental(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;
+    _symbolContainer.setEmitIfIncremental(id);
     if (!containerizeSymbols) {
       _symbolContainer.setNoEmit(id);
     }
     return _symbolContainer[id];
   }
 
-  void setSymbolContainerIncrementalMode(bool setting) {
-    _symbolContainer.incrementalMode = setting;
-  }
-
   /// Finishes the module created by [startModule], by combining the preable
   /// [items] with the [moduleItems] that have been emitted.
   ///
@@ -646,7 +788,9 @@
       _extensionSymbols[name] = id;
       addSymbol(id, id);
     }
-    return _extensionSymbols[name];
+    var symbolId = _extensionSymbols[name];
+    _symbolContainer.setEmitIfIncremental(symbolId);
+    return symbolId;
   }
 
   /// 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 42a4511..0e0077a 100644
--- a/pkg/dev_compiler/lib/src/js_ast/builder.dart
+++ b/pkg/dev_compiler/lib/src/js_ast/builder.dart
@@ -7,6 +7,7 @@
 // ignore_for_file: slash_for_doc_comments, unnecessary_new
 // ignore_for_file: always_declare_return_types, prefer_single_quotes
 // ignore_for_file: prefer_collection_literals, omit_local_variable_types
+// ignore_for_file: unnecessary_brace_in_string_interps
 
 // Utilities for building JS ASTs at runtime.  Contains a builder class
 // and a parser that parses part of the language.
diff --git a/pkg/dev_compiler/lib/src/js_ast/printer.dart b/pkg/dev_compiler/lib/src/js_ast/printer.dart
index 9fabc56..c6d7581 100644
--- a/pkg/dev_compiler/lib/src/js_ast/printer.dart
+++ b/pkg/dev_compiler/lib/src/js_ast/printer.dart
@@ -7,7 +7,7 @@
 // ignore_for_file: slash_for_doc_comments, unnecessary_const
 // ignore_for_file: always_declare_return_types, prefer_single_quotes
 // ignore_for_file: prefer_collection_literals, omit_local_variable_types
-// ignore_for_file: prefer_generic_function_type_aliases, prefer_final_fields
+// ignore_for_file: prefer_final_fields
 // ignore_for_file: use_function_type_syntax_for_parameters
 
 part of js_ast;
diff --git a/pkg/dev_compiler/lib/src/kernel/command.dart b/pkg/dev_compiler/lib/src/kernel/command.dart
index 9a30699..8ddd4dc 100644
--- a/pkg/dev_compiler/lib/src/kernel/command.dart
+++ b/pkg/dev_compiler/lib/src/kernel/command.dart
@@ -16,7 +16,6 @@
 import 'package:kernel/class_hierarchy.dart';
 import 'package:kernel/core_types.dart';
 import 'package:kernel/kernel.dart';
-import 'package:kernel/ast.dart' show NonNullableByDefaultCompiledMode;
 import 'package:kernel/target/targets.dart';
 import 'package:kernel/text/ast_to_text.dart' as kernel show Printer;
 import 'package:path/path.dart' as p;
diff --git a/pkg/dev_compiler/lib/src/kernel/compiler.dart b/pkg/dev_compiler/lib/src/kernel/compiler.dart
index b1341b9..dcec2b1 100644
--- a/pkg/dev_compiler/lib/src/kernel/compiler.dart
+++ b/pkg/dev_compiler/lib/src/kernel/compiler.dart
@@ -26,7 +26,7 @@
 import '../compiler/shared_command.dart' show SharedCompilerOptions;
 import '../compiler/shared_compiler.dart';
 import '../js_ast/js_ast.dart' as js_ast;
-import '../js_ast/js_ast.dart' show js;
+import '../js_ast/js_ast.dart' show ModuleItem, js;
 import '../js_ast/source_map_printer.dart' show NodeEnd, NodeSpan, HoverComment;
 import 'constants.dart';
 import 'js_interop.dart';
@@ -77,7 +77,7 @@
   final _constLazyAccessors = <js_ast.Method>[];
 
   /// Container for holding the results of lazily-evaluated constants.
-  final _constTableCache = ModuleItemContainer<String>.asArray('C');
+  var _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.
@@ -221,7 +221,7 @@
   final constAliasCache = HashMap<Constant, js_ast.Expression>();
 
   /// Maps uri strings in asserts and elsewhere to hoisted identifiers.
-  final _uriContainer = ModuleItemContainer<String>.asArray('I');
+  var _uriContainer = ModuleItemContainer<String>.asArray('I');
 
   final Class _jsArrayClass;
   final Class _privateSymbolClass;
@@ -242,6 +242,8 @@
 
   final NullableInference _nullableInference;
 
+  bool _moduleEmitted = false;
+
   factory ProgramCompiler(
       Component component,
       ClassHierarchy hierarchy,
@@ -320,8 +322,10 @@
   InterfaceType get internalSymbolType =>
       _coreTypes.legacyRawType(_coreTypes.internalSymbolClass);
 
+  /// Module can be emitted only once, and the compiler can be reused after
+  /// only in incremental mode, for expression compilation only.
   js_ast.Program emitModule(Component component) {
-    if (moduleItems.isNotEmpty) {
+    if (_moduleEmitted) {
       throw StateError('Can only call emitModule once.');
     }
     _component = component;
@@ -443,7 +447,12 @@
     // Emit the hoisted type table cache variables
     items.addAll(_typeTable.dischargeBoundTypes());
 
-    return finishModule(items, _options.moduleName);
+    var module = finishModule(items, _options.moduleName);
+
+    // Mark as finished for incremental mode, so it is safe to
+    // switch to the incremental mode for expression compilation.
+    _moduleEmitted = true;
+    return module;
   }
 
   @override
@@ -2276,7 +2285,7 @@
   ///
   /// For user-defined operators the following names are allowed:
   ///
-  ///     <, >, <=, >=, ==, -, +, /, ~/, *, %, |, ^, &, <<, >>, []=, [], ~
+  ///     <, >, <=, >=, ==, -, +, /, ~/, *, %, |, ^, &, <<, >>, >>>, []=, [], ~
   ///
   /// They generate code like:
   ///
@@ -2530,8 +2539,14 @@
     return libraryJSName != null ? '$libraryJSName.$jsName' : jsName;
   }
 
+  String _emitJsNameWithoutGlobal(NamedNode n) {
+    if (!usesJSInterop(n)) return null;
+    setEmitIfIncrementalLibrary(getLibrary(n));
+    return _jsNameWithoutGlobal(n);
+  }
+
   js_ast.PropertyAccess _emitJSInterop(NamedNode n) {
-    var jsName = _jsNameWithoutGlobal(n);
+    var jsName = _emitJsNameWithoutGlobal(n);
     if (jsName == null) return null;
     return _emitJSInteropForGlobal(jsName);
   }
@@ -2731,6 +2746,10 @@
       _emitInterfaceType(type);
 
   @override
+  js_ast.Expression visitExtensionType(ExtensionType type) =>
+      type.onType.accept(this);
+
+  @override
   js_ast.Expression visitFutureOrType(FutureOrType type) =>
       _normalizeFutureOr(type);
 
@@ -2762,7 +2781,7 @@
       typeRep = runtimeCall(
           'anonymousJSType(#)', [js.escapedString(getLocalClassName(c))]);
     } else {
-      var jsName = _jsNameWithoutGlobal(c);
+      var jsName = _emitJsNameWithoutGlobal(c);
       if (jsName != null) {
         typeRep = runtimeCall('lazyJSType(() => #, #)',
             [_emitJSInteropForGlobal(jsName), js.escapedString(jsName)]);
@@ -3072,6 +3091,30 @@
   js_ast.Expression visitTypedefType(TypedefType type) =>
       visitFunctionType(type.unalias as FunctionType);
 
+  /// Set incremental mode for expression compilation.
+  ///
+  /// Called for each expression compilation to set the intremental mode
+  /// and clear referenced items.
+  ///
+  /// The compiler cannot revert to non-incremental mode, and requires the
+  /// original module to be already emitted by the same compiler instance.
+  @override
+  void setIncrementalMode() {
+    if (!_moduleEmitted) {
+      throw StateError(
+          'Cannot run in incremental mode before module completion');
+    }
+    super.setIncrementalMode();
+
+    _constTableCache = ModuleItemContainer<String>.asArray('C');
+    _constLazyAccessors.clear();
+    constAliasCache.clear();
+
+    _uriContainer = ModuleItemContainer<String>.asArray('I');
+
+    _typeTable.typeContainer.setIncrementalMode();
+  }
+
   /// Emits function after initial compilation.
   ///
   /// Emits function from kernel [functionNode] with name [name] in the context
@@ -3079,68 +3122,67 @@
   /// finished. For example, this happens in expression compilation during
   /// expression evaluation initiated by the user from the IDE and coordinated
   /// by the debugger.
-  js_ast.Fun emitFunctionIncremental(
-      Library library, Class cls, FunctionNode functionNode, String name) {
-    // setup context
+  /// Triggers incremental mode, which only emits symbols, types, constants,
+  /// libraries, and uris referenced in the expression compilation result.
+  js_ast.Fun emitFunctionIncremental(List<ModuleItem> items, Library library,
+      Class cls, FunctionNode functionNode, String name) {
+    // Setup context.
     _currentLibrary = library;
     _staticTypeContext.enterLibrary(_currentLibrary);
     _currentClass = cls;
 
+    // Keep all symbols in containers.
+    containerizeSymbols = true;
+
+    // Set all tables to incremental mode, so we can only emit elements that
+    // were referenced the compiled code for the expression.
+    setIncrementalMode();
+
     // 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
+    // variables from the current scope, and should already be checked in the
     // original code.
     _checkParameters = false;
 
-    // Set module item containers to incremental mode.
-    setSymbolContainerIncrementalMode(true);
-    _typeTable.typeContainer.incrementalMode = true;
-    _constTableCache.incrementalMode = true;
-
-    // Emit function with additional information, such as types that are used
-    // in the expression.
+    // Emit function while recoding elements accessed from tables.
     var fun = _emitFunction(functionNode, name);
 
-    var types = _typeTable.dischargeBoundTypes();
-    var constants = _dischargeConstTable();
+    var extensionSymbols = <js_ast.Statement>[];
+    emitExtensionSymbols(extensionSymbols);
 
-    var body = js_ast.Block([...?types, ...?constants, ...fun.body.statements]);
+    // Add all elements from tables accessed in the function
+    var body = js_ast.Block([
+      ...extensionSymbols,
+      ..._typeTable.dischargeBoundTypes(),
+      ...symbolContainer.emit(),
+      ..._emitConstTable(),
+      ..._uriContainer.emit(),
+      ...fun.body.statements
+    ]);
+
+    // Import all necessary libraries, including libraries accessed from the
+    // current module and libraries accessed from the type table.
+    for (var library in _typeTable.incrementalLibraries()) {
+      setEmitIfIncrementalLibrary(library);
+    }
+    emitImports(items);
+    emitExportsAsImports(items, _currentLibrary);
+
     return js_ast.Fun(fun.params, body);
   }
 
-  /// Emit all collected const symbols
-  ///
-  /// This is similar to how constants are emitted during
-  /// initial compilation in emitModule
-  ///
-  /// TODO: unify the code with emitModule.
-  List<js_ast.Statement> _dischargeConstTable() {
-    var items = <js_ast.Statement>[];
-
+  List<js_ast.Statement> _emitConstTable() {
+    var constTable = <js_ast.Statement>[];
     if (_constLazyAccessors.isNotEmpty) {
-      var constTableBody = runtimeStatement(
-          'defineLazy(#, { # }, false)', [_constTable, _constLazyAccessors]);
-      items.add(constTableBody);
-      _constLazyAccessors.clear();
-    }
+      constTable
+          .add(js.statement('const # = Object.create(null);', [_constTable]));
 
-    _copyAndFlattenBlocks(items, moduleItems);
-    moduleItems.clear();
-    return items;
-  }
+      constTable.add(runtimeStatement(
+          'defineLazy(#, { # }, false)', [_constTable, _constLazyAccessors]));
 
-  /// Flattens blocks in [items] to a single list.
-  ///
-  /// This will not flatten blocks that are marked as being scopes.
-  void _copyAndFlattenBlocks(
-      List<js_ast.Statement> result, Iterable<js_ast.ModuleItem> items) {
-    for (var item in items) {
-      if (item is js_ast.Block && !item.isScope) {
-        _copyAndFlattenBlocks(result, item.statements);
-      } else {
-        result.add(item as js_ast.Statement);
-      }
+      constTable.addAll(_constTableCache.emit());
     }
+    return constTable;
   }
 
   js_ast.Fun _emitFunction(FunctionNode f, String name) {
@@ -3729,6 +3771,7 @@
     if (!_uriContainer.contains(uri)) {
       _uriContainer[uri] = js_ast.LiteralString('"$uri"');
     }
+    _uriContainer.setEmitIfIncremental(uri);
     return _uriContainer.access(uri);
   }
 
@@ -4369,19 +4412,19 @@
 
   @override
   js_ast.Expression visitDynamicGet(DynamicGet node) {
-    return _emitPropertyGet(node.receiver, null, node.name.name);
+    return _emitPropertyGet(node.receiver, null, node.name.text);
   }
 
   @override
   js_ast.Expression visitInstanceGet(InstanceGet node) {
     return _emitPropertyGet(
-        node.receiver, node.interfaceTarget, node.name.name);
+        node.receiver, node.interfaceTarget, node.name.text);
   }
 
   @override
   js_ast.Expression visitInstanceTearOff(InstanceTearOff node) {
     return _emitPropertyGet(
-        node.receiver, node.interfaceTarget, node.name.name);
+        node.receiver, node.interfaceTarget, node.name.text);
   }
 
   @override
@@ -4554,6 +4597,13 @@
   }
 
   @override
+  js_ast.Expression visitInstanceGetterInvocation(
+      InstanceGetterInvocation node) {
+    return _emitMethodCall(
+        node.receiver, node.interfaceTarget, node.arguments, node);
+  }
+
+  @override
   js_ast.Expression visitLocalFunctionInvocation(LocalFunctionInvocation node) {
     return _emitMethodCall(
         VariableGet(node.variable)..fileOffset = node.fileOffset,
@@ -4565,13 +4615,13 @@
   @override
   js_ast.Expression visitEqualsCall(EqualsCall node) {
     return _emitEqualityOperator(node.left, node.interfaceTarget, node.right,
-        negated: node.isNot);
+        negated: false);
   }
 
   @override
   js_ast.Expression visitEqualsNull(EqualsNull node) {
     return _emitCoreIdenticalCall([node.expression, NullLiteral()],
-        negated: node.isNot);
+        negated: false);
   }
 
   @override
@@ -4591,12 +4641,10 @@
     /// 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') {
+      Expression receiver;
+      if (receiver != null && node.name.text == '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 &&
             !receiver.variable.isLate) {
@@ -4997,6 +5045,12 @@
             }
             return _emitOperatorCall(left, target, op, [right]);
 
+          case '>>>':
+            if (_asIntInRange(right, 0, 31) != null) {
+              return binary('# >>> #');
+            }
+            return _emitOperatorCall(left, target, op, [right]);
+
           default:
             // TODO(vsm): When do Dart ops not map to JS?
             return binary('# $op #');
@@ -5560,6 +5614,13 @@
       return _emitEqualityOperator(operand.receiver, operand.interfaceTarget,
           operand.arguments.positional[0],
           negated: true);
+    } else if (operand is EqualsCall) {
+      return _emitEqualityOperator(
+          operand.left, operand.interfaceTarget, operand.right,
+          negated: true);
+    } else if (operand is EqualsNull) {
+      return _emitCoreIdenticalCall([operand.expression, NullLiteral()],
+          negated: true);
     } else if (operand is StaticInvocation &&
         operand.target == _coreTypes.identicalProcedure) {
       return _emitCoreIdenticalCall(operand.arguments.positional,
diff --git a/pkg/dev_compiler/lib/src/kernel/expression_compiler.dart b/pkg/dev_compiler/lib/src/kernel/expression_compiler.dart
index a4c69bd..03c94f7 100644
--- a/pkg/dev_compiler/lib/src/kernel/expression_compiler.dart
+++ b/pkg/dev_compiler/lib/src/kernel/expression_compiler.dart
@@ -13,8 +13,9 @@
     show Code, Message, PlainAndColorizedString;
 
 import 'package:dev_compiler/dev_compiler.dart';
+import 'package:dev_compiler/src/compiler/js_names.dart' as js_ast;
+import 'package:dev_compiler/src/compiler/module_builder.dart';
 import 'package:dev_compiler/src/js_ast/js_ast.dart' as js_ast;
-import 'package:dev_compiler/src/kernel/compiler.dart';
 
 import 'package:front_end/src/api_unstable/ddc.dart';
 
@@ -31,8 +32,6 @@
         Member,
         Node,
         Procedure,
-        PropertyGet,
-        PropertySet,
         RedirectingFactoryConstructor,
         TreeNode,
         TypeParameter,
@@ -114,7 +113,7 @@
   }
 
   DartScope build() {
-    if (_offset == null || _library == null || _member == null) return null;
+    if (_offset == null || _library == null) return null;
 
     return DartScope(_library, _cls, _member, _definitions, _typeParameters);
   }
@@ -127,7 +126,10 @@
   @override
   void visitLibrary(Library library) {
     _library = library;
-    _offset = _component.getOffset(_library.fileUri, _line, _column);
+    _offset = 0;
+    if (_line > 0) {
+      _offset = _component.getOffset(_library.fileUri, _line, _column);
+    }
 
     // Exit early if the evaluation offset is not found.
     // Note: the complete scope is not found in this case,
@@ -261,53 +263,6 @@
   }
 }
 
-/// 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> with VisitorVoidMixin {
-  final Map<String, Library> privateFields = {};
-
-  @override
-  void defaultNode(Node node) {
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitFieldReference(Field node) {
-    if (node.name.isPrivate && !node.isStatic) {
-      privateFields[node.name.text] = node.enclosingLibrary;
-    }
-  }
-
-  @override
-  void visitField(Field node) {
-    if (node.name.isPrivate && !node.isStatic) {
-      privateFields[node.name.text] = node.enclosingLibrary;
-    }
-  }
-
-  @override
-  void visitPropertyGet(PropertyGet node) {
-    var member = node.interfaceTarget;
-    if (node.name.isPrivate && member != null && member.isInstanceMember) {
-      privateFields[node.name.text] = node.interfaceTarget?.enclosingLibrary;
-    }
-  }
-
-  @override
-  void visitPropertySet(PropertySet node) {
-    var member = node.interfaceTarget;
-    if (node.name.isPrivate && member != null && member.isInstanceMember) {
-      privateFields[node.name.text] = node.interfaceTarget?.enclosingLibrary;
-    }
-  }
-}
-
 class ExpressionCompiler {
   static final String debugProcedureName = '\$dartEval';
 
@@ -317,6 +272,7 @@
   final IncrementalCompiler _compiler;
   final ProgramCompiler _kernel2jsCompiler;
   final Component _component;
+  final ModuleFormat _moduleFormat;
 
   DiagnosticMessageHandler onDiagnostic;
 
@@ -328,6 +284,7 @@
 
   ExpressionCompiler(
     this._options,
+    this._moduleFormat,
     this.errors,
     this._compiler,
     this._kernel2jsCompiler,
@@ -494,81 +451,27 @@
 
     // TODO: make this code clear and assumptions enforceable
     // https://github.com/dart-lang/sdk/issues/43273
-    //
-    // We assume here that ExpressionCompiler is always created using
-    // onDisgnostic method that adds to the error list that is passed
-    // to the same invocation of the ExpressionCompiler constructor.
-    // We only use the error list once - below, to detect if the frontend
-    // compilation of the expression has failed.
     if (errors.isNotEmpty) {
       return null;
     }
 
-    var jsFun = _kernel2jsCompiler.emitFunctionIncremental(
+    var imports = <js_ast.ModuleItem>[];
+    var jsFun = _kernel2jsCompiler.emitFunctionIncremental(imports,
         scope.library, scope.cls, procedure.function, '$debugProcedureName');
 
     _log('Generated JavaScript for expression');
 
-    var jsFunModified = _addSymbolDefinitions(procedure, jsFun, scope);
-
-    _log('Added symbol definitions to JavaScript');
-
     // print JS ast to string for evaluation
-
     var context = js_ast.SimpleJavaScriptPrintingContext();
     var opts =
         js_ast.JavaScriptPrintingOptions(allowKeywordsInProperties: true);
 
-    jsFunModified.accept(js_ast.Printer(opts, context));
-    _log('Performed JavaScript adjustments for expression');
+    var tree = transformFunctionModuleFormat(imports, jsFun, _moduleFormat);
+    tree.accept(
+        js_ast.Printer(opts, context, localNamer: js_ast.TemporaryNamer(tree)));
+
+    _log('Added imports and renamed variables for expression');
 
     return context.getText();
   }
-
-  /// 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) {
-    // get private fields accessed by the evaluated expression
-    var fieldsCollector = PrivateFieldsVisitor();
-    procedure.accept(fieldsCollector);
-    var privateFields = fieldsCollector.privateFields;
-
-    // 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([
-      // re-create private field accessors
-      ...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 private symbol definition
-  ///
-  /// example:
-  /// let _f = dart.privateName(main, "_f");
-  js_ast.Statement _createPrivateField(String field, String library) {
-    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 9956b4f..0052d2d 100644
--- a/pkg/dev_compiler/lib/src/kernel/expression_compiler_worker.dart
+++ b/pkg/dev_compiler/lib/src/kernel/expression_compiler_worker.dart
@@ -7,9 +7,11 @@
 import 'dart:async';
 import 'dart:convert';
 import 'dart:io';
+import 'dart:isolate';
 
 import 'package:args/args.dart';
 import 'package:build_integration/file_system/multi_root.dart';
+import 'package:dev_compiler/dev_compiler.dart';
 import 'package:front_end/src/api_prototype/file_system.dart';
 import 'package:front_end/src/api_unstable/ddc.dart';
 import 'package:kernel/ast.dart' show Component, Library;
@@ -22,11 +24,7 @@
 import 'package:vm/http_filesystem.dart';
 
 import '../compiler/js_names.dart';
-import '../compiler/shared_command.dart';
 import 'command.dart';
-import 'compiler.dart';
-import 'expression_compiler.dart';
-import 'target.dart';
 
 /// The service that handles expression compilation requests from
 /// the debugger.
@@ -52,7 +50,7 @@
 ///
 ///    - debugger creates an isolate using dartdevc's main method with
 ///      '--experimental-expression-compiler' flag and passes a send port
-///      to dartdevc for sending responces from the service to the debugger.
+///      to dartdevc for sending responses from the service to the debugger.
 ///
 ///    - dartdevc creates a new send port to receive requests on, and sends
 ///      it back to the debugger, for sending requests to the service.
@@ -82,16 +80,60 @@
 
   final ProcessedOptions _processedOptions;
   final CompilerOptions _compilerOptions;
+  final ModuleFormat _moduleFormat;
   final Component _sdkComponent;
 
   ExpressionCompilerWorker._(
     this._processedOptions,
     this._compilerOptions,
+    this._moduleFormat,
     this._sdkComponent,
     this.requestStream,
     this.sendResponse,
   );
 
+  /// Create expression compiler worker from [args] and start it.
+  ///
+  /// If [sendPort] is provided, creates a `receivePort` and sends it to
+  /// the consumer to establish communication. Otherwise, uses stdin/stdout
+  /// for communication with the consumer.
+  ///
+  /// Details:
+  ///
+  /// Consumer uses (`consumerSendPort`, `consumerReceivePort`) pair to
+  /// send requests and receive responses:
+  ///
+  /// `consumerReceivePort.sendport` = [sendPort]
+  /// `consumerSendPort = receivePort.sendport`
+  ///
+  /// Worker uses the opposite ports connected to the consumer ports -
+  /// (`receivePort`, [sendPort]) to receive requests and send responses.
+  ///
+  /// The worker stops on start failure or after the consumer closes its
+  /// receive port corresponding to [sendPort].
+  static Future<void> createAndStart(List<String> args,
+      {SendPort sendPort}) async {
+    if (sendPort != null) {
+      var receivePort = ReceivePort();
+      sendPort.send(receivePort.sendPort);
+      try {
+        var worker = await createFromArgs(args,
+            requestStream: receivePort.cast<Map<String, dynamic>>(),
+            sendResponse: sendPort.send);
+        await worker.start();
+      } catch (e, s) {
+        sendPort
+            .send({'exception': '$e', 'stackTrace': '$s', 'succeeded': false});
+        rethrow;
+      } finally {
+        receivePort.close();
+      }
+    } else {
+      var worker = await createFromArgs(args);
+      await worker.start();
+    }
+  }
+
   static Future<ExpressionCompilerWorker> createFromArgs(
     List<String> args, {
     Stream<Map<String, dynamic>> requestStream,
@@ -120,6 +162,9 @@
         parseExperimentalArguments(
             parsedArgs['enable-experiment'] as List<String>),
         onError: (e) => throw e);
+
+    var moduleFormat = parseModuleFormat(parsedArgs['module-format'] as String);
+
     return create(
       librariesSpecificationUri:
           _argToUri(parsedArgs['libraries-file'] as String),
@@ -131,6 +176,7 @@
       sdkRoot: _argToUri(parsedArgs['sdk-root'] as String),
       trackWidgetCreation: parsedArgs['track-widget-creation'] as bool,
       soundNullSafety: parsedArgs['sound-null-safety'] as bool,
+      moduleFormat: moduleFormat,
       verbose: parsedArgs['verbose'] as bool,
       requestStream: requestStream,
       sendResponse: sendResponse,
@@ -152,6 +198,7 @@
     Uri sdkRoot,
     bool trackWidgetCreation = false,
     bool soundNullSafety = false,
+    ModuleFormat moduleFormat = ModuleFormat.amd,
     bool verbose = false,
     Stream<Map<String, dynamic>> requestStream, // Defaults to read from stdin
     void Function(Map<String, dynamic>)
@@ -184,8 +231,11 @@
       return processedOptions.loadSdkSummary(null);
     });
 
+    if (sdkComponent == null) {
+      throw Exception('Could not load SDK component: $sdkSummary');
+    }
     return ExpressionCompilerWorker._(processedOptions, compilerOptions,
-        sdkComponent, requestStream, sendResponse)
+        moduleFormat, sdkComponent, requestStream, sendResponse)
       .._updateCache(sdkComponent, dartSdkModule, true);
   }
 
@@ -309,6 +359,7 @@
           sourceMap: true,
           summarizeApi: false,
           moduleName: moduleName,
+          soundNullSafety: _compilerOptions.nnbdMode == NnbdMode.Strong,
           // 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
@@ -342,6 +393,7 @@
 
     var expressionCompiler = ExpressionCompiler(
       _compilerOptions,
+      _moduleFormat,
       errors,
       incrementalCompiler,
       kernel2jsCompiler,
@@ -673,6 +725,7 @@
   ..addOption('sdk-root')
   ..addOption('asset-server-address')
   ..addOption('asset-server-port')
+  ..addOption('module-format', defaultsTo: 'amd')
   ..addFlag('track-widget-creation', defaultsTo: false)
   ..addFlag('sound-null-safety', defaultsTo: false)
   ..addFlag('verbose', defaultsTo: false);
diff --git a/pkg/dev_compiler/lib/src/kernel/kernel_helpers.dart b/pkg/dev_compiler/lib/src/kernel/kernel_helpers.dart
index 78dadd1..0c4e313 100644
--- a/pkg/dev_compiler/lib/src/kernel/kernel_helpers.dart
+++ b/pkg/dev_compiler/lib/src/kernel/kernel_helpers.dart
@@ -53,7 +53,7 @@
   if (n is Class) return n.name;
   if (n is Typedef) return n.name;
   if (n is Field) return n.name.text;
-  return n.canonicalName?.name;
+  return n.reference.canonicalName?.name;
 }
 
 /// Given an annotated [node] and a [test] function, returns the first matching
@@ -135,6 +135,7 @@
     case '&':
     case '>>':
     case '<<':
+    case '>>>':
     case '+':
     case 'unary-':
     case '-':
diff --git a/pkg/dev_compiler/lib/src/kernel/nullable_inference.dart b/pkg/dev_compiler/lib/src/kernel/nullable_inference.dart
index b930366..07fa7d4 100644
--- a/pkg/dev_compiler/lib/src/kernel/nullable_inference.dart
+++ b/pkg/dev_compiler/lib/src/kernel/nullable_inference.dart
@@ -145,6 +145,11 @@
           node.interfaceTarget, node.name.text, node, node.receiver);
 
   @override
+  bool visitInstanceGetterInvocation(InstanceGetterInvocation node) =>
+      _invocationIsNullable(
+          node.interfaceTarget, node.name.text, node, node.receiver);
+
+  @override
   bool visitDynamicInvocation(DynamicInvocation node) =>
       _invocationIsNullable(null, node.name.text, node, node.receiver);
 
diff --git a/pkg/dev_compiler/lib/src/kernel/property_model.dart b/pkg/dev_compiler/lib/src/kernel/property_model.dart
index 5e403c2..fc403b3 100644
--- a/pkg/dev_compiler/lib/src/kernel/property_model.dart
+++ b/pkg/dev_compiler/lib/src/kernel/property_model.dart
@@ -46,20 +46,35 @@
   /// Private classes that can be extended outside of this library.
   ///
   /// Normally private classes cannot be accessed outside this library, however,
-  /// this can happen if they are extended by a public class, for example:
+  /// this can happen if they are extended by a public class or exposed by a
+  /// public typedef, for example:
   ///
   ///     class _A { int x = 42; }
   ///     class _B { int x = 42; }
+  ///     class _C { int x = 42; }
   ///
-  ///     // _A is now effectively public for the purpose of overrides.
-  ///     class C extends _A {}
+  ///     // _A and _B are now effectively public for the purpose of overrides.
+  ///     class D extends _A {}
+  ///     typedef E = _B;
   ///
-  /// The class _A must treat is "x" as virtual, however _B does not.
+  /// The classes _A and _B must treat is "x" as virtual, however _C does not.
   final _extensiblePrivateClasses = HashSet<Class>();
 
   _LibraryVirtualFieldModel.build(Library library) {
     var allClasses = library.classes;
 
+    for (var typedef in library.typedefs) {
+      // Ignore private typedefs.
+      if (typedef.name.startsWith('_')) continue;
+
+      var type = typedef.type;
+      if (type is InterfaceType && type.classNode.name.startsWith('_')) {
+        // Public typedefs of private classes expose those classes for
+        // extension.
+        _extensiblePrivateClasses.add(type.classNode);
+      }
+    }
+
     // The set of public types is our initial extensible type set.
     // From there, visit all immediate private types in this library, and so on
     // from those private types, marking them as extensible.
diff --git a/pkg/dev_compiler/lib/src/kernel/target.dart b/pkg/dev_compiler/lib/src/kernel/target.dart
index ffc64a4..1f8d5f6 100644
--- a/pkg/dev_compiler/lib/src/kernel/target.dart
+++ b/pkg/dev_compiler/lib/src/kernel/target.dart
@@ -440,6 +440,12 @@
   }
 
   @override
+  void visitInstanceGetterInvocation(InstanceGetterInvocation node) {
+    _checkTarget(node.receiver, node.interfaceTarget);
+    super.visitInstanceGetterInvocation(node);
+  }
+
+  @override
   void visitInstanceTearOff(InstanceTearOff node) {
     _checkTearoff(node.interfaceTarget);
     super.visitInstanceTearOff(node);
diff --git a/pkg/dev_compiler/lib/src/kernel/type_table.dart b/pkg/dev_compiler/lib/src/kernel/type_table.dart
index 57b23f0..15cbd31 100644
--- a/pkg/dev_compiler/lib/src/kernel/type_table.dart
+++ b/pkg/dev_compiler/lib/src/kernel/type_table.dart
@@ -9,7 +9,8 @@
 import 'package:kernel/kernel.dart';
 
 import '../compiler/js_names.dart' as js_ast;
-import '../compiler/module_containers.dart' show ModuleItemContainer;
+import '../compiler/module_containers.dart'
+    show ModuleItemContainer, ModuleItemData;
 import '../js_ast/js_ast.dart' as js_ast;
 import '../js_ast/js_ast.dart' show js;
 import 'kernel_helpers.dart';
@@ -119,16 +120,26 @@
   bool _isNamed(DartType type) =>
       typeContainer.contains(type) || _unboundTypeIds.containsKey(type);
 
+  Set<Library> incrementalLibraries() {
+    var libraries = <Library>{};
+    for (var t in typeContainer.incrementalModuleItems) {
+      if (t is InterfaceType) {
+        libraries.add(t.classNode.enclosingLibrary);
+      }
+    }
+    return libraries;
+  }
+
   /// 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]]);
+    js_ast.Expression emitValue(DartType t, ModuleItemData data) {
+      var access = js.call('#.#', [data.id, data.jsKey]);
+      return js.call('() => ((# = #.constFn(#))())',
+          [access, _runtimeModule, data.jsValue]);
     }
-    var boundTypes = typeContainer.incrementalMode
-        ? typeContainer.emitIncremental()
-        : typeContainer.emit();
+
+    var boundTypes = typeContainer.emit(emitValue: emitValue);
     // Bound types should only be emitted once (even across multiple evals).
     for (var t in typeContainer.keys) {
       typeContainer.setNoEmit(t);
@@ -172,6 +183,7 @@
     if (!typeContainer.contains(type)) {
       typeContainer[type] = typeRep;
     }
+    typeContainer.setEmitIfIncremental(type);
     return _unboundTypeIds[type] ?? typeContainer.access(type);
   }
 
diff --git a/pkg/dev_compiler/pubspec.yaml b/pkg/dev_compiler/pubspec.yaml
index 2a4517c..a3a70e5 100644
--- a/pkg/dev_compiler/pubspec.yaml
+++ b/pkg/dev_compiler/pubspec.yaml
@@ -28,6 +28,7 @@
     path: ../vm
 
 dev_dependencies:
+  browser_launcher: ^0.1.9
   expect:
     path: ../expect
   js:
@@ -35,10 +36,12 @@
   modular_test:
     path: ../modular_test
   package_config: any
-  pedantic: ^1.8.0
+  pedantic: ^1.11.0
   sourcemap_testing:
     path: ../sourcemap_testing
   stack_trace: any
   test: any
   testing:
     path: ../testing
+  webkit_inspection_protocol: ^0.7.4
+
diff --git a/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_shared.dart b/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_shared.dart
new file mode 100644
index 0000000..9ae2415
--- /dev/null
+++ b/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_shared.dart
@@ -0,0 +1,966 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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 dev_compiler.test.expression_compiler;
+
+import 'package:test/test.dart';
+import 'expression_compiler_e2e_suite.dart';
+
+const simpleClassSource = '''
+extension NumberParsing on String {
+  int parseInt() {
+    return int.parse(this) + 1;
+  }
+}
+
+class C {
+  static int staticField = 1;
+  static int _staticField = 2;
+  static int _unusedStaticField = 3;
+  int field;
+  int _field;
+  int _unusedField = 4;
+
+  C(this.field, this._field) {
+    int y = 1;
+    // Breakpoint: constructorBP
+    var nop;
+  }
+
+  int methodFieldAccess(int x) {
+    // Breakpoint: methodBP
+    var inScope = 1;
+    {
+      var innerInScope = global + staticField + field;
+      // Breakpoint: innerScopeBP
+      var innerNotInScope = 2;
+    }
+    var notInScope = 3;
+    return x + _field + _staticField;
+  }
+
+  Future<int> asyncMethod(int x) async {
+    return x + _field + _staticField;
+  }
+}
+
+int global = 42;
+
+main() {
+  int x = 15;
+  var c = C(5, 6);
+  // Breakpoint: globalFunctionBP
+  c.methodFieldAccess(10);
+}
+''';
+
+void runSharedTests(SetupCompilerOptions setup, TestDriver driver) {
+  group('Expression compiler scope collection tests', () {
+    var source = simpleClassSource;
+
+    setUpAll(() async {
+      await driver.initSource(setup, source);
+    });
+
+    tearDownAll(() async {
+      await driver.cleanupTest();
+    });
+
+    test('local in scope', () async {
+      await driver.check(
+          breakpointId: 'innerScopeBP',
+          expression: 'inScope',
+          expectedResult: '1');
+    });
+
+    test('local in inner scope', () async {
+      await driver.check(
+          breakpointId: 'innerScopeBP',
+          expression: 'innerInScope',
+          expectedResult: '48');
+    });
+
+    test('global in scope', () async {
+      await driver.check(
+          breakpointId: 'innerScopeBP',
+          expression: 'global',
+          expectedResult: '42');
+    });
+
+    test('static field in scope', () async {
+      await driver.check(
+          breakpointId: 'innerScopeBP',
+          expression: 'staticField',
+          expectedResult: '1');
+    });
+
+    test('field in scope', () async {
+      await driver.check(
+          breakpointId: 'innerScopeBP',
+          expression: 'field',
+          expectedResult: '5');
+    });
+
+    test('parameter in scope', () async {
+      await driver.check(
+          breakpointId: 'innerScopeBP', expression: 'x', expectedResult: '10');
+    });
+
+    test('local not in scope', () async {
+      await driver.check(
+          breakpointId: 'innerScopeBP',
+          expression: 'notInScope',
+          expectedError: "Error: The getter 'notInScope' isn't defined for the"
+              " class 'C'.");
+    });
+
+    test('local not in inner scope', () async {
+      await driver.check(
+          breakpointId: 'innerScopeBP',
+          expression: 'innerNotInScope',
+          expectedError:
+              "Error: The getter 'innerNotInScope' isn't defined for the"
+              " class 'C'.");
+    });
+  });
+
+  group('Expression compiler extension symbols tests', () {
+    var source = '''
+        main() {
+          List<int> list = [];
+          list.add(0);
+          // Breakpoint: bp
+        }
+        ''';
+
+    setUpAll(() async {
+      await driver.initSource(setup, source);
+    });
+
+    tearDownAll(() async {
+      await driver.cleanupTest();
+    });
+
+    test('extension symbol used only in expression compilation', () async {
+      await driver.check(
+          breakpointId: 'bp', expression: 'list.first', expectedResult: '0');
+    });
+
+    test('extension symbol used in original compilation', () async {
+      await driver.check(
+          breakpointId: 'bp',
+          expression: '() { list.add(1); return list.last; }()',
+          expectedResult: '1');
+    });
+  });
+
+  group('Expression compiler tests in extension method:', () {
+    var source = '''
+        extension NumberParsing on String {
+          int parseInt() {
+            var ret = int.parse(this);
+            // Breakpoint: bp
+            return ret;
+          }
+        }
+        main() => "1234".parseInt();
+      ''';
+
+    setUpAll(() async {
+      await driver.initSource(setup, source);
+    });
+
+    tearDownAll(() {
+      driver.cleanupTest();
+    });
+
+    test('compilation error', () async {
+      await driver.check(
+          breakpointId: 'bp',
+          expression: 'typo',
+          expectedError: "Error: Getter not found: 'typo'");
+    });
+
+    test('local (trimmed scope)', () async {
+      await driver.check(
+          breakpointId: 'bp', expression: 'ret', expectedResult: '1234');
+    });
+
+    test('this (full scope)', () async {
+      // Note: this currently fails due to
+      // - incremental compiler not mapping 'this' from user input to '#this'
+      // - incremental compiler not allowing #this as a parameter name
+      await driver.check(
+          breakpointId: 'bp',
+          expression: 'this',
+          expectedError: "Error: Expected identifier, but got 'this'");
+    });
+  });
+
+  group('Expression compiler tests in static function:', () {
+    var source = '''
+        int foo(int x, {int y: 0}) {
+          int z = 3;
+          // Breakpoint: bp
+          return x + y + z;
+        }
+
+        main() => foo(1, y: 2);
+        ''';
+
+    setUpAll(() async {
+      await driver.initSource(setup, source);
+    });
+
+    tearDownAll(() {
+      driver.cleanupTest();
+    });
+
+    test('compilation error', () async {
+      await driver.check(
+          breakpointId: 'bp',
+          expression: 'typo',
+          expectedError: "Getter not found: \'typo\'");
+    });
+
+    test('local', () async {
+      await driver.check(
+          breakpointId: 'bp', expression: 'x', expectedResult: '1');
+    });
+
+    test('formal', () async {
+      await driver.check(
+          breakpointId: 'bp', expression: 'y', expectedResult: '2');
+    });
+
+    test('named formal', () async {
+      await driver.check(
+          breakpointId: 'bp', expression: 'z', expectedResult: '3');
+    });
+
+    test('function', () async {
+      await driver
+          .check(breakpointId: 'bp', expression: 'main', expectedResult: '''
+              function main() {
+                return test.foo(1, {y: 2});
+              }''');
+    });
+  });
+
+  group('Expression compiler tests in method:', () {
+    var source = simpleClassSource;
+
+    setUpAll(() async {
+      await driver.initSource(setup, source);
+    });
+
+    tearDownAll(() {
+      driver.cleanupTest();
+    });
+
+    test('compilation error', () async {
+      await driver.check(
+          breakpointId: 'methodBP',
+          expression: 'typo',
+          expectedError: "The getter 'typo' isn't defined for the class 'C'");
+    });
+
+    test('local', () async {
+      await driver.check(
+          breakpointId: 'methodBP', expression: 'x', expectedResult: '10');
+    });
+
+    test('this', () async {
+      await driver.check(
+          breakpointId: 'methodBP',
+          expression: 'this',
+          expectedResult:
+              'test.C.new {Symbol(_unusedField): 4, Symbol(C.field): 5,'
+              ' Symbol(_field): 6}');
+    });
+
+    test('expression using locals', () async {
+      await driver.check(
+          breakpointId: 'methodBP', expression: 'x + 1', expectedResult: '11');
+    });
+
+    test('expression using static fields', () async {
+      await driver.check(
+          breakpointId: 'methodBP',
+          expression: 'x + staticField',
+          expectedResult: '11');
+    });
+
+    test('expression using private static fields', () async {
+      await driver.check(
+          breakpointId: 'methodBP',
+          expression: 'x + _staticField',
+          expectedResult: '12');
+    });
+
+    test('expression using fields', () async {
+      await driver.check(
+          breakpointId: 'methodBP',
+          expression: 'x + field',
+          expectedResult: '15');
+    });
+
+    test('expression using private fields', () async {
+      await driver.check(
+          breakpointId: 'methodBP',
+          expression: 'x + _field',
+          expectedResult: '16');
+    });
+
+    test('expression using globals', () async {
+      await driver.check(
+          breakpointId: 'methodBP',
+          expression: 'x + global',
+          expectedResult: '52');
+    });
+
+    test('expression using fields not referred to in the original  code',
+        () async {
+      await driver.check(
+          breakpointId: 'methodBP',
+          expression: '_unusedField + _unusedStaticField',
+          expectedResult: '7');
+    });
+
+    test('private field modification', () async {
+      await driver.check(
+          breakpointId: 'methodBP',
+          expression: '_field = 2',
+          expectedResult: '2');
+    });
+
+    test('field modification', () async {
+      await driver.check(
+          breakpointId: 'methodBP',
+          expression: 'field = 3',
+          expectedResult: '3');
+    });
+
+    test('private static field modification', () async {
+      await driver.check(
+          breakpointId: 'methodBP',
+          expression: '_staticField = 4',
+          expectedResult: '4');
+    });
+
+    test('static field modification', () async {
+      await driver.check(
+          breakpointId: 'methodBP',
+          expression: 'staticField = 5',
+          expectedResult: '5');
+    });
+  });
+
+  group('Expression compiler tests in global function:', () {
+    var source = simpleClassSource;
+
+    setUpAll(() async {
+      await driver.initSource(setup, source);
+    });
+
+    tearDownAll(() {
+      driver.cleanupTest();
+    });
+
+    test('compilation error', () async {
+      await driver.check(
+          breakpointId: 'globalFunctionBP',
+          expression: 'typo',
+          expectedError: "Getter not found: 'typo'.");
+    });
+
+    test('local with primitive type', () async {
+      await driver.check(
+          breakpointId: 'globalFunctionBP',
+          expression: 'x',
+          expectedResult: '15');
+    });
+
+    test('local object', () async {
+      await driver.check(
+          breakpointId: 'globalFunctionBP',
+          expression: 'c',
+          expectedResult:
+              'test.C.new {Symbol(_unusedField): 4, Symbol(C.field): 5, '
+              'Symbol(_field): 6}');
+    });
+
+    test('create new object', () async {
+      await driver.check(
+          breakpointId: 'globalFunctionBP',
+          expression: 'C(3, 4)',
+          expectedResult:
+              'test.C.new {Symbol(_unusedField): 4, Symbol(C.field): 3, '
+              'Symbol(_field): 4}');
+    });
+
+    test('access field of new object', () async {
+      await driver.check(
+          breakpointId: 'globalFunctionBP',
+          expression: 'C(3, 4)._field',
+          expectedResult: '4');
+    });
+
+    test('access static field', () async {
+      await driver.check(
+          breakpointId: 'globalFunctionBP',
+          expression: 'C.staticField',
+          expectedResult: '1');
+    });
+
+    test('expression using private static fields', () async {
+      await driver.check(
+          breakpointId: 'globalFunctionBP',
+          expression: 'C._staticField',
+          expectedError: "Error: Getter not found: '_staticField'.");
+    });
+
+    test('access field', () async {
+      await driver.check(
+          breakpointId: 'globalFunctionBP',
+          expression: 'c.field',
+          expectedResult: '5');
+    });
+
+    test('access private field', () async {
+      await driver.check(
+          breakpointId: 'globalFunctionBP',
+          expression: 'c._field',
+          expectedResult: '6');
+    });
+
+    test('method call', () async {
+      await driver.check(
+          breakpointId: 'globalFunctionBP',
+          expression: 'c.methodFieldAccess(2)',
+          expectedResult: '10');
+    });
+
+    test('async method call', () async {
+      await driver.check(
+          breakpointId: 'globalFunctionBP',
+          expression: 'c.asyncMethod(2)',
+          expectedResult: '_Future.new {Symbol(_state): 1, '
+              'Symbol(_resultOrListeners): null, '
+              'Symbol(_zone): _RootZone {}');
+    });
+
+    test('extension method call', () async {
+      await driver.check(
+          breakpointId: 'globalFunctionBP',
+          expression: '"1234".parseInt()',
+          expectedResult: '1235');
+    });
+
+    test('private field modification', () async {
+      await driver.check(
+          breakpointId: 'globalFunctionBP',
+          expression: 'c._field = 10',
+          expectedResult: '10');
+    });
+
+    test('field modification', () async {
+      await driver.check(
+          breakpointId: 'globalFunctionBP',
+          expression: 'c._field = 11',
+          expectedResult: '11');
+    });
+
+    test('private static field modification', () async {
+      await driver.check(
+          breakpointId: 'globalFunctionBP',
+          expression: 'C._staticField = 2',
+          expectedError: "Setter not found: '_staticField'.");
+    });
+
+    test('static field modification', () async {
+      await driver.check(
+          breakpointId: 'globalFunctionBP',
+          expression: 'C.staticField = 20',
+          expectedResult: '20');
+    });
+
+    test('call global function from core library', () async {
+      await driver.check(
+          breakpointId: 'globalFunctionBP',
+          expression: 'identical(1, 1)',
+          expectedResult: 'true');
+    });
+  });
+
+  group('Expression compiler tests in constructor:', () {
+    var source = simpleClassSource;
+
+    setUpAll(() async {
+      await driver.initSource(setup, source);
+    });
+
+    tearDownAll(() {
+      driver.cleanupTest();
+    });
+
+    test('compilation error', () async {
+      await driver.check(
+          breakpointId: 'constructorBP',
+          expression: 'typo',
+          expectedError: "The getter 'typo' isn't defined for the class 'C'");
+    });
+
+    test('local', () async {
+      await driver.check(
+          breakpointId: 'constructorBP', expression: 'y', expectedResult: '1');
+    });
+
+    test('this', () async {
+      await driver.check(
+          breakpointId: 'constructorBP',
+          expression: 'this',
+          expectedResult:
+              'test.C.new {Symbol(_unusedField): 4, Symbol(C.field): 5,'
+              ' Symbol(_field): 6}');
+    });
+
+    test('expression using locals', () async {
+      await driver.check(
+          breakpointId: 'constructorBP',
+          expression: 'y + 1',
+          expectedResult: '2');
+    });
+
+    test('expression using static fields', () async {
+      await driver.check(
+          breakpointId: 'constructorBP',
+          expression: 'y + staticField',
+          expectedResult: '2');
+    });
+
+    test('expression using private static fields', () async {
+      await driver.check(
+          breakpointId: 'constructorBP',
+          expression: 'y + _staticField',
+          expectedResult: '3');
+    });
+
+    test('expression using fields', () async {
+      await driver.check(
+          breakpointId: 'constructorBP',
+          expression: 'y + field',
+          expectedResult: '6');
+    });
+
+    test('expression using private fields', () async {
+      await driver.check(
+          breakpointId: 'constructorBP',
+          expression: 'y + _field',
+          expectedResult: '7');
+    });
+
+    test('expression using globals', () async {
+      await driver.check(
+          breakpointId: 'constructorBP',
+          expression: 'y + global',
+          expectedResult: '43');
+    });
+
+    test('method call', () async {
+      await driver.check(
+          breakpointId: 'constructorBP',
+          expression: 'methodFieldAccess(2)',
+          expectedResult: '10');
+    });
+
+    test('async method call', () async {
+      await driver.check(
+          breakpointId: 'constructorBP',
+          expression: 'asyncMethod(2)',
+          expectedResult: '_Future.new {Symbol(_state): 1, '
+              'Symbol(_resultOrListeners): null, '
+              'Symbol(_zone): _RootZone {}');
+    });
+
+    test('extension method call', () async {
+      await driver.check(
+          breakpointId: 'constructorBP',
+          expression: '"1234".parseInt()',
+          expectedResult: '1235');
+    });
+
+    test('private field modification', () async {
+      await driver.check(
+          breakpointId: 'constructorBP',
+          expression: '_field = 2',
+          expectedResult: '2');
+    });
+
+    test('field modification', () async {
+      await driver.check(
+          breakpointId: 'constructorBP',
+          expression: 'field = 2',
+          expectedResult: '2');
+    });
+
+    test('private static field modification', () async {
+      await driver.check(
+          breakpointId: 'constructorBP',
+          expression: '_staticField = 2',
+          expectedResult: '2');
+    });
+
+    test('static field modification', () async {
+      await driver.check(
+          breakpointId: 'constructorBP',
+          expression: 'staticField = 2',
+          expectedResult: '2');
+    });
+  });
+
+  group('Expression compiler tests in async method:', () {
+    var source = '''
+        class C {
+          static int staticField = 1;
+          static int _staticField = 2;
+          int _field;
+          int field;
+
+          C(this.field, this._field);
+          Future<int> asyncMethod(int x) async {
+            // Breakpoint: bp
+            return x + global + _field + field + staticField + _staticField;
+          }
+        }
+
+        Future<int> entrypoint() async {
+          var c = C(5, 7);
+          // Breakpoint: bp1
+          return await c.asyncMethod(1);
+        }
+
+        int global = 42;
+        void main() async {
+          await entrypoint();
+        }
+        ''';
+
+    setUpAll(() async {
+      await driver.initSource(setup, source);
+    });
+
+    tearDownAll(() {
+      driver.cleanupTest();
+    });
+
+    test('compilation error', () async {
+      await driver.check(
+          breakpointId: 'bp',
+          expression: 'typo',
+          expectedError: "The getter 'typo' isn't defined for the class 'C'");
+    });
+
+    test('local', () async {
+      await driver.check(
+          breakpointId: 'bp', expression: 'x', expectedResult: '1');
+    });
+
+    test('this', () async {
+      await driver.check(
+          breakpointId: 'bp',
+          expression: 'this',
+          expectedResult: 'test.C.new {Symbol(C.field): 5, Symbol(_field): 7}');
+    });
+
+    test('awaited method call', () async {
+      await driver.check(
+          breakpointId: 'bp1',
+          expression: 'c.asyncMethod(1)',
+          expectedResult: '_Future.new {Symbol(_state): 1, '
+              'Symbol(_resultOrListeners): null, '
+              'Symbol(_zone): _RootZone {}');
+    }, skip: "'await' is not yet supported in expression evaluation.");
+
+    test('awaited method call', () async {
+      await driver.check(
+          breakpointId: 'bp1',
+          expression: 'await c.asyncMethod(1)',
+          expectedResult: '58');
+    }, skip: "'await' is not yet supported in expression evaluation.");
+  });
+
+  group('Expression compiler tests in closures:', () {
+    var source = '''
+        void globalFunction() {
+        int x = 15;
+
+        var outerClosure = (int y) {
+          var closureCaptureInner = (int z) {
+            // Breakpoint: bp
+            var temp = x + y + z;
+            return;
+          };
+          closureCaptureInner(0);
+        };
+
+        outerClosure(3);
+        return;
+      }
+
+      main() => globalFunction();
+      ''';
+
+    setUpAll(() async {
+      await driver.initSource(setup, source);
+    });
+
+    tearDownAll(() {
+      driver.cleanupTest();
+    });
+
+    test('compilation error', () async {
+      await driver.check(
+          breakpointId: 'bp',
+          expression: 'typo',
+          expectedError: "Getter not found: 'typo'.");
+    });
+
+    test('expression using captured variables', () async {
+      await driver.check(
+          breakpointId: 'bp', expression: r"'$y+$z'", expectedResult: '3+0');
+    });
+
+    test('expression using uncaptured variables', () async {
+      await driver.check(
+          breakpointId: 'bp',
+          expression: r"'$x+$y+$z'",
+          expectedResult: '15+3+0');
+    });
+  });
+
+  group('Expression compiler tests in method with no type use:', () {
+    var source = '''
+        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;
+        }
+
+        String baz(String t) {
+          return t;
+        }
+
+        String main() {
+          var k = Key('t');
+          MyClass c = MyClass(0);
+          int p = 1;
+          const t = 1;
+
+          // Breakpoint: bp
+          return '\$c, \$k, \$t';
+        }
+        ''';
+
+    setUpAll(() async {
+      await driver.initSource(setup, source);
+    });
+
+    tearDownAll(() {
+      driver.cleanupTest();
+    });
+
+    test('call function not using type', () async {
+      await driver.check(
+          breakpointId: 'bp', expression: 'bar(p)', expectedResult: '1');
+    });
+
+    test('call function using type', () async {
+      await driver.check(
+          breakpointId: 'bp', expression: "baz('\$p')", expectedResult: '1');
+    });
+
+    test('evaluate new const expression', () async {
+      await driver.check(
+          breakpointId: 'bp',
+          expression: 'const MyClass(1)',
+          expectedResult: 'MyClass {Symbol(MyClass._t): 1}');
+    });
+
+    test('evaluate optimized const expression', () async {
+      await driver.check(
+          breakpointId: 'bp', expression: 't', expectedResult: '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(
+          breakpointId: 'bp',
+          expression: "Key('t')",
+          expectedResult: 'test.ValueKey.new {Symbol(ValueKey.value): t}');
+    });
+
+    test('evaluate const factory constructor call', () async {
+      await driver.check(
+          breakpointId: 'bp',
+          expression: "const Key('t')",
+          expectedResult: 'ValueKey {Symbol(ValueKey.value): t}');
+    });
+  });
+
+  group('Expression compiler tests in simple loops:', () {
+    var source = '''
+        void globalFunction() {
+          int x = 15;
+          for(int i = 0; i < 10; i++) {
+            // Breakpoint: bp
+            var calculation = '\$i+\$x';
+          };
+        }
+
+        main() => globalFunction();
+        ''';
+
+    setUpAll(() async {
+      await driver.initSource(setup, source);
+    });
+
+    tearDownAll(() {
+      driver.cleanupTest();
+    });
+
+    test('expression using local', () async {
+      await driver.check(
+          breakpointId: 'bp', expression: 'x', expectedResult: '15');
+    });
+
+    test('expression using loop variable', () async {
+      await driver.check(
+          breakpointId: 'bp', expression: 'i', expectedResult: '0');
+    });
+  });
+
+  group('Expression compiler tests in conditional:', () {
+    var source = '''
+        int globalFunction(int x) {
+          if (x == 1) {
+            int y = 3;
+            // Breakpoint: thenBP
+            var calculation = '\$y+\$x';
+          } else {
+            int z = 4;
+            // Breakpoint: elseBP
+            var calculation = '\$z+\$x';
+          }
+          // Breakpoint: postBP
+          return 0;
+        }
+
+        void main() {
+          globalFunction(1);
+          globalFunction(2);
+        }
+        ''';
+
+    setUpAll(() async {
+      await driver.initSource(setup, source);
+    });
+
+    tearDownAll(() {
+      driver.cleanupTest();
+    });
+
+    test('(then) expression using local', () async {
+      await driver.check(
+          breakpointId: 'thenBP', expression: 'y', expectedResult: '3');
+    });
+
+    test('(then) expression using local out of scope', () async {
+      await driver.check(
+          breakpointId: 'thenBP',
+          expression: 'z',
+          expectedError: "Error: Getter not found: 'z'");
+    });
+
+    test('(else) expression using local', () async {
+      await driver.check(
+          breakpointId: 'elseBP', expression: 'z', expectedResult: '4');
+    });
+
+    test('(else) expression using local out of scope', () async {
+      await driver.check(
+          breakpointId: 'elseBP',
+          expression: 'y',
+          expectedError: "Error: Getter not found: 'y'");
+    });
+
+    test('(post) expression using local', () async {
+      await driver.check(
+          breakpointId: 'postBP', expression: 'x', expectedResult: '1');
+    });
+
+    test('(post) expression using local out of scope', () async {
+      await driver.check(
+          breakpointId: 'postBP',
+          expression: 'z',
+          expectedError: "Error: Getter not found: 'z'");
+    });
+
+    test('(post) expression using local out of scope', () async {
+      await driver.check(
+          breakpointId: 'postBP',
+          expression: 'y',
+          expectedError: "Error: Getter not found: 'y'");
+    });
+  });
+
+  group('Expression compiler tests in iterator loops:', () {
+    var source = '''
+        int globalFunction() {
+          var l = <String>['1', '2', '3'];
+
+          for (var e in l) {
+            // Breakpoint: bp
+            var calculation = '\$e';
+          };
+          return 0;
+        }
+
+        main() => globalFunction();
+        ''';
+
+    setUpAll(() async {
+      await driver.initSource(setup, source);
+    });
+
+    tearDownAll(() {
+      driver.cleanupTest();
+    });
+
+    test('expression loop variable', () async {
+      await driver.check(
+          breakpointId: 'bp', expression: 'e', expectedResult: '1');
+    });
+  });
+}
diff --git a/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_sound_test.dart b/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_sound_test.dart
new file mode 100644
index 0000000..f67ae6a9
--- /dev/null
+++ b/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_sound_test.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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 dev_compiler.test.expression_compiler;
+
+import 'package:test/test.dart';
+import 'expression_compiler_e2e_shared.dart';
+import 'expression_compiler_e2e_suite.dart';
+
+void main() async {
+  var driver = await TestDriver.init();
+  var setup = SetupCompilerOptions(soundNullSafety: true);
+
+  group('(Sound null safety)', () {
+    tearDownAll(() {
+      driver.finish();
+    });
+
+    runSharedTests(setup, driver);
+  });
+}
diff --git a/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_suite.dart b/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_suite.dart
new file mode 100644
index 0000000..1dceafe
--- /dev/null
+++ b/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_suite.dart
@@ -0,0 +1,609 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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 dev_compiler.test.expression_compiler;
+
+import 'dart:async';
+import 'dart:convert';
+import 'dart:io' show Directory, File, Platform;
+
+import 'package:browser_launcher/browser_launcher.dart' as browser;
+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:dev_compiler/src/kernel/module_metadata.dart';
+import 'package:front_end/src/api_unstable/ddc.dart' as fe;
+import 'package:front_end/src/compute_platform_binaries_location.dart' as fe;
+import 'package:front_end/src/fasta/incremental_serializer.dart' as fe;
+import 'package:kernel/ast.dart' show Component, Library;
+import 'package:kernel/target/targets.dart';
+import 'package:path/path.dart' as p;
+import 'package:source_maps/parser.dart' as source_maps;
+import 'package:source_maps/source_maps.dart' as source_maps;
+import 'package:test/test.dart';
+import 'package:webkit_inspection_protocol/webkit_inspection_protocol.dart'
+    as wip;
+
+class DevelopmentIncrementalCompiler extends fe.IncrementalCompiler {
+  Uri entryPoint;
+
+  DevelopmentIncrementalCompiler(fe.CompilerOptions options, this.entryPoint,
+      [Uri initializeFrom,
+      bool outlineOnly,
+      fe.IncrementalSerializer incrementalSerializer])
+      : super(
+            fe.CompilerContext(
+                fe.ProcessedOptions(options: options, inputs: [entryPoint])),
+            initializeFrom,
+            outlineOnly,
+            incrementalSerializer);
+
+  DevelopmentIncrementalCompiler.fromComponent(fe.CompilerOptions options,
+      this.entryPoint, Component componentToInitializeFrom,
+      [bool outlineOnly, fe.IncrementalSerializer incrementalSerializer])
+      : super.fromComponent(
+            fe.CompilerContext(
+                fe.ProcessedOptions(options: options, inputs: [entryPoint])),
+            componentToInitializeFrom,
+            outlineOnly,
+            incrementalSerializer);
+}
+
+class SetupCompilerOptions {
+  static final sdkRoot = fe.computePlatformBinariesLocation();
+  static final sdkUnsoundSummaryPath =
+      p.join(sdkRoot.toFilePath(), 'ddc_sdk.dill');
+  static final sdkSoundSummaryPath =
+      p.join(sdkRoot.toFilePath(), 'ddc_outline_sound.dill');
+  static final librariesSpecificationUri =
+      p.join(p.dirname(p.dirname(getSdkPath())), 'libraries.json');
+  static final String dartUnsoundComment = '// @dart = 2.9';
+  static final String dartSoundComment = '//';
+
+  final String dartLangComment;
+  final List<String> errors = [];
+  final List<String> diagnosticMessages = [];
+  final ModuleFormat moduleFormat;
+  final fe.CompilerOptions options;
+  final bool soundNullSafety;
+
+  static fe.CompilerOptions _getOptions(bool soundNullSafety) {
+    var options = fe.CompilerOptions()
+      ..verbose = false // set to true for debugging
+      ..sdkRoot = sdkRoot
+      ..target = DevCompilerTarget(TargetFlags())
+      ..librariesSpecificationUri = p.toUri('sdk/lib/libraries.json')
+      ..omitPlatform = true
+      ..sdkSummary =
+          p.toUri(soundNullSafety ? sdkSoundSummaryPath : sdkUnsoundSummaryPath)
+      ..environmentDefines = const {}
+      ..nnbdMode = soundNullSafety ? fe.NnbdMode.Strong : fe.NnbdMode.Weak;
+    return options;
+  }
+
+  SetupCompilerOptions(
+      {this.soundNullSafety = true, this.moduleFormat = ModuleFormat.amd})
+      : options = _getOptions(soundNullSafety),
+        dartLangComment =
+            soundNullSafety ? dartSoundComment : dartUnsoundComment {
+    options.onDiagnostic = (fe.DiagnosticMessage m) {
+      diagnosticMessages.addAll(m.plainTextFormatted);
+      if (m.severity == fe.Severity.error) {
+        errors.addAll(m.plainTextFormatted);
+      }
+    };
+  }
+}
+
+class TestCompilationResult {
+  final String result;
+  final bool isSuccess;
+
+  TestCompilationResult(this.result, this.isSuccess);
+}
+
+class TestCompiler {
+  final SetupCompilerOptions setup;
+  Component component;
+  ExpressionCompiler evaluator;
+  ModuleMetadata metadata;
+  source_maps.SingleMapping sourceMap;
+
+  TestCompiler(this.setup);
+
+  Future<TestCompiler> init({Uri input, Uri output, Uri packages}) async {
+    // Initialize the incremental compiler and module component.
+    // TODO: extend this for multi-module compilations by storing separate
+    // compilers/components/names per module.
+    setup.options.packagesFileUri = packages;
+    var compiler = DevelopmentIncrementalCompiler(setup.options, input);
+    component = await compiler.computeDelta();
+    component.computeCanonicalNames();
+
+    // Initialize DDC.
+    var moduleName = '${p.basenameWithoutExtension(output.toFilePath())}';
+
+    var classHierarchy = compiler.getClassHierarchy();
+    var compilerOptions = SharedCompilerOptions(
+        replCompile: true,
+        moduleName: moduleName,
+        soundNullSafety: setup.soundNullSafety);
+    var coreTypes = compiler.getCoreTypes();
+
+    final importToSummary = Map<Library, Component>.identity();
+    final summaryToModule = Map<Component, String>.identity();
+    for (var lib in component.libraries) {
+      importToSummary[lib] = component;
+    }
+    summaryToModule[component] = moduleName;
+
+    var kernel2jsCompiler = ProgramCompiler(component, classHierarchy,
+        compilerOptions, importToSummary, summaryToModule,
+        coreTypes: coreTypes);
+    var module = kernel2jsCompiler.emitModule(component);
+
+    // Perform a full compile, writing the compiled JS + sourcemap.
+    var code = jsProgramToCode(
+      module,
+      setup.moduleFormat,
+      inlineSourceMap: true,
+      buildSourceMap: true,
+      emitDebugMetadata: true,
+      jsUrl: '$output',
+      mapUrl: '$output.map',
+      component: component,
+    );
+    metadata = code.metadata;
+    sourceMap = source_maps.SingleMapping.fromJson(code.sourceMap);
+    var codeBytes = utf8.encode(code.code);
+    var sourceMapBytes = utf8.encode(json.encode(code.sourceMap));
+
+    File('${output.toFilePath()}').writeAsBytesSync(codeBytes);
+    File('${output.toFilePath()}.map').writeAsBytesSync(sourceMapBytes);
+
+    // Save the expression evaluator for future evaluations.
+    evaluator = ExpressionCompiler(
+      setup.options,
+      setup.moduleFormat,
+      setup.errors,
+      compiler,
+      kernel2jsCompiler,
+      component,
+    );
+
+    if (setup.errors.isNotEmpty) {
+      throw Exception('Compilation failed with: ${setup.errors}');
+    }
+    setup.diagnosticMessages.clear();
+
+    return this;
+  }
+
+  Future<TestCompilationResult> compileExpression(
+      {Uri input,
+      int line,
+      int column,
+      Map<String, String> scope,
+      String expression}) async {
+    var libraryUri = metadataForLibraryUri(input);
+    var jsExpression = await evaluator.compileExpressionToJs(
+        libraryUri.importUri, line, column, scope, expression);
+    if (setup.errors.isNotEmpty) {
+      jsExpression = setup.errors.toString().replaceAll(
+          RegExp(
+              r'org-dartlang-debug:synthetic_debug_expression:[0-9]*:[0-9]*:'),
+          '');
+
+      return TestCompilationResult(jsExpression, false);
+    }
+
+    return TestCompilationResult(jsExpression, true);
+  }
+
+  LibraryMetadata metadataForLibraryUri(Uri libraryUri) =>
+      metadata.libraries.entries
+          .firstWhere((entry) => entry.value.fileUri == '$libraryUri')
+          .value;
+}
+
+class TestDriver {
+  SetupCompilerOptions setup;
+  String source;
+  Directory chromeDir;
+  Directory testDir;
+  String moduleFormatString;
+  Uri htmlBootstrapper;
+  Uri input;
+  Uri output;
+  Uri packagesFile;
+  browser.Chrome chrome;
+  wip.WipDebugger debugger;
+  wip.WipConnection connection;
+  TestCompiler compiler;
+
+  TestDriver._();
+
+  static Future<TestDriver> init() async {
+    var driver = TestDriver._();
+    await driver.initChrome();
+    return driver;
+  }
+
+  /// Initializes a Chrome browser instance, tab connection, and debugger.
+  ///
+  /// Should be called once after creating TestDriver.
+  Future<void> initChrome() async {
+    // Create a temporary directory for holding Chrome tests.
+    var systemTempDir = Directory.systemTemp;
+    chromeDir = await systemTempDir.createTemp('ddc_eval_test_anchor');
+
+    // Start Chrome on an empty page with a single empty tab.
+    chrome = await browser.Chrome.startWithDebugPort(['about:blank'],
+        userDataDir: chromeDir.uri.toFilePath(), headless: true);
+
+    // Connect to the first 'normal' tab.
+    var tab = await chrome.chromeConnection
+        .getTab((tab) => !tab.isBackgroundPage && !tab.isChromeExtension);
+    connection = await tab.connect();
+    debugger = connection.debugger;
+  }
+
+  /// Must be called when testing a new Dart program.
+  ///
+  /// Depends on SDK artifacts (such as the sound and unsound dart_sdk.js
+  /// files) generated from the 'dartdevc_test' target.
+  Future<void> initSource(SetupCompilerOptions setup, String source) async {
+    // Perform setup sanity checks.
+    var summaryPath = setup.options.sdkSummary.toFilePath();
+    if (!File(summaryPath).existsSync()) {
+      throw StateError('Unable to find SDK summary at path: $summaryPath.');
+    }
+
+    // Prepend Dart nullability comment.
+    source = '${setup.dartLangComment}\n\n$source';
+    this.setup = setup;
+    this.source = source;
+    testDir = await chromeDir.createTemp('ddc_eval_test');
+    var buildDir = p.dirname(p.dirname(p.dirname(Platform.resolvedExecutable)));
+    var scriptPath = Platform.script.normalizePath().toFilePath();
+    var ddcPath = p.dirname(p.dirname(p.dirname(scriptPath)));
+    output = testDir.uri.resolve('test.js');
+    input = testDir.uri.resolve('test.dart');
+    File(input.toFilePath())
+      ..createSync()
+      ..writeAsStringSync(source);
+
+    packagesFile = testDir.uri.resolve('package_config.json');
+    File(packagesFile.toFilePath())
+      ..createSync()
+      ..writeAsStringSync('''
+      {
+        "configVersion": 2,
+        "packages": [
+          {
+            "name": "eval_test",
+            "rootUri": "./",
+            "packageUri": "./"
+          }
+        ]
+      }
+      ''');
+
+    // Initialize DDC and the incremental compiler, then perform a full compile.
+    compiler = await TestCompiler(setup)
+        .init(input: input, output: output, packages: packagesFile);
+
+    htmlBootstrapper = testDir.uri.resolve('bootstrapper.html');
+    var bootstrapFile = File(htmlBootstrapper.toFilePath())..createSync();
+    var moduleName = compiler.metadata.name;
+    var mainLibraryName = compiler.metadataForLibraryUri(input).name;
+
+    switch (setup.moduleFormat) {
+      case ModuleFormat.ddc:
+        moduleFormatString = 'ddc';
+        var dartSdkPath = escaped(p.join(
+            buildDir,
+            'gen',
+            'utils',
+            'dartdevc',
+            setup.soundNullSafety ? 'sound' : 'kernel',
+            'legacy',
+            'dart_sdk.js'));
+        var dartLibraryPath =
+            escaped(p.join(ddcPath, 'lib', 'js', 'legacy', 'dart_library.js'));
+        var outputPath = escaped(output.toFilePath());
+        bootstrapFile.writeAsStringSync('''
+<script src='$dartLibraryPath'></script>
+<script src='$dartSdkPath'></script>
+<script src='$outputPath'></script>
+<script>
+  'use strict';
+  var sound = ${setup.soundNullSafety};
+  var sdk = dart_library.import('dart_sdk');
+
+  if (!sound) {
+    sdk.dart.weakNullSafetyWarnings(false);
+    sdk.dart.weakNullSafetyErrors(false);
+  }
+  sdk.dart.nonNullAsserts(true);
+  sdk.dart.nativeNonNullAsserts(true);
+  sdk._debugger.registerDevtoolsFormatter();
+  dart_library.start('$moduleName', '$mainLibraryName');
+</script>
+''');
+        break;
+      case ModuleFormat.amd:
+        moduleFormatString = 'amd';
+        var dartSdkPath = escaped(p.join(buildDir, 'gen', 'utils', 'dartdevc',
+            setup.soundNullSafety ? 'sound' : 'kernel', 'amd', 'dart_sdk'));
+        var requirePath = escaped(p.join(buildDir, 'dart-sdk', 'lib',
+            'dev_compiler', 'kernel', 'amd', 'require.js'));
+        var outputPath = escaped(p.withoutExtension(output.toFilePath()));
+        bootstrapFile.writeAsStringSync('''
+<script src='$requirePath'></script>
+<script>
+  require.config({
+    paths: {
+        'dart_sdk': '$dartSdkPath',
+        '$moduleName': '$outputPath'
+    },
+    waitSeconds: 15
+  });
+  var sound = ${setup.soundNullSafety};
+
+  require(['dart_sdk', '$moduleName'],
+        function(sdk, app) {
+    'use strict';
+
+    if (!sound) {
+    sdk.dart.weakNullSafetyWarnings(false);
+    sdk.dart.weakNullSafetyErrors(false);
+    }
+    sdk.dart.nonNullAsserts(true);
+    sdk.dart.nativeNonNullAsserts(true);
+    sdk._debugger.registerDevtoolsFormatter();
+    app.$mainLibraryName.main([]);
+  });
+</script>
+''');
+
+        break;
+      default:
+        throw Exception(
+            'Unsupported module format for SDK evaluation tests: ${setup.moduleFormat}');
+    }
+
+    await debugger.enable();
+
+    // Pause as soon as the test file loads but before it executes.
+    var urlRegex = '.*${libraryUriToJsIdentifier(output)}.*';
+    await debugger.sendCommand('Debugger.setBreakpointByUrl', params: {
+      'urlRegex': urlRegex,
+      'lineNumber': 0,
+    });
+  }
+
+  void finish() async {
+    await chrome?.close();
+    // Chrome takes a while to free its claim on chromeDir, so wait a bit.
+    await Future.delayed(const Duration(milliseconds: 500));
+    chromeDir?.deleteSync(recursive: true);
+  }
+
+  Future<void> cleanupTest() async {
+    setup.diagnosticMessages.clear();
+    setup.errors.clear();
+    await debugger.disable();
+  }
+
+  Future<void> check(
+      {String breakpointId,
+      String expression,
+      String expectedError,
+      String expectedResult}) async {
+    assert(expectedError == null || expectedResult == null,
+        'Cannot expect both an error and result.');
+
+    // The next two pause events will correspond to:
+    // 1) the initial preemptive breakpoint and
+    // 2) the breakpoint at the specified ID
+    final pauseController = StreamController<wip.DebuggerPausedEvent>();
+    var pauseSub = debugger.onPaused.listen(pauseController.add);
+
+    final scriptController = StreamController<wip.ScriptParsedEvent>();
+    var scriptSub = debugger.onScriptParsed.listen((event) {
+      if ('${event.script.url}' == '$output') {
+        scriptController.add(event);
+      }
+    });
+
+    // Navigate from the empty page and immediately pause on the preemptive
+    // breakpoint.
+    await connection.page.navigate('$htmlBootstrapper');
+
+    // Poll until the script is found, or timeout after a few seconds.
+    var script = (await scriptController.stream.first.timeout(
+            const Duration(seconds: 5),
+            onTimeout: () => throw Exception(
+                'Unable to find JS script corresponding to test file $output in ${debugger.scripts}.')))
+        .script;
+    await scriptSub.cancel();
+    await scriptController.close();
+
+    // Breakpoint at the first WIP location mapped from its Dart line.
+    var dartLine = _findBreakpointLine(breakpointId);
+    var location = await _jsLocationFromDartLine(script, dartLine);
+    var bp = await debugger.setBreakpoint(location);
+
+    // Continue to the next breakpoint, ignoring the first pause event since it
+    // corresponds to the preemptive URI breakpoint made prior to page
+    // navigation.
+    await debugger.resume();
+    final event = await pauseController.stream
+        .skip(1)
+        .timeout(const Duration(seconds: 5),
+            onTimeout: (event) => throw Exception(
+                'Unable to find JS preemptive pause event in $output.'))
+        .first
+        .timeout(const Duration(seconds: 5),
+            onTimeout: () => throw Exception(
+                'Unable to find JS pause event corresponding to line ($dartLine -> $location) in $output.'));
+    await pauseSub.cancel();
+    await pauseController.close();
+
+    // Retrieve the call frame and its scope variables.
+    var frame = event.getCallFrames().first;
+    var scope = await _collectScopeVariables(frame);
+
+    // Perform an incremental compile.
+    var result = await compiler.compileExpression(
+        input: input,
+        line: dartLine,
+        column: 1,
+        scope: scope,
+        expression: expression);
+
+    if (expectedError != null) {
+      expect(
+          result,
+          const TypeMatcher<TestCompilationResult>()
+              .having((_) => result.result, 'result', _matches(expectedError)));
+      setup.diagnosticMessages.clear();
+      setup.errors.clear();
+      return;
+    }
+
+    if (!result.isSuccess) {
+      throw Exception(
+          'Unexpected expression evaluation failure:\n${result.result}');
+    }
+
+    var evalResult = await debugger.evaluateOnCallFrame(
+        frame.callFrameId, result.result,
+        returnByValue: false);
+
+    await debugger.removeBreakpoint(bp.breakpointId);
+    var value = await stringifyRemoteObject(evalResult);
+
+    expect(
+        result,
+        const TypeMatcher<TestCompilationResult>()
+            .having((_) => '$value', 'result', _matches(expectedResult)));
+  }
+
+  /// Generate simple string representation of a RemoteObject that closely
+  /// resembles Chrome's console output.
+  ///
+  /// Examples:
+  /// Class: t.C.new {Symbol(C.field): 5, Symbol(_field): 7}
+  /// Function: function main() {
+  ///             return test.foo(1, {y: 2});
+  ///           }
+  Future<String> stringifyRemoteObject(wip.RemoteObject obj) async {
+    String str;
+    switch (obj.type) {
+      case 'function':
+        str = obj.description;
+        break;
+      case 'object':
+        if (obj.subtype == 'null') {
+          return 'null';
+        }
+        var properties =
+            await connection.runtime.getProperties(obj, ownProperties: true);
+        var filteredProps = <String, String>{};
+        for (var prop in properties) {
+          if (prop.value != null && prop.name != '__proto__') {
+            filteredProps[prop.name] = await stringifyRemoteObject(prop.value);
+          }
+        }
+        str = '${obj.description} $filteredProps';
+        break;
+      default:
+        str = '${obj.value}';
+        break;
+    }
+    return str;
+  }
+
+  /// Collects local JS variables visible at a breakpoint during evaluation.
+  ///
+  /// Adapted from webdev/dwds/lib/src/services/expression_evaluator.dart.
+  Future<Map<String, String>> _collectScopeVariables(
+      wip.WipCallFrame frame) async {
+    var jsScope = <String, String>{};
+
+    for (var scope in filterScopes(frame)) {
+      var response = await connection.runtime
+          .getProperties(scope.object, ownProperties: true);
+      for (var prop in response) {
+        var propKey = '${prop.name}';
+        var propValue = '${prop.value.value}';
+        jsScope[propKey] = propValue == 'null' ? propKey : propValue;
+      }
+    }
+    return jsScope;
+  }
+
+  /// Used for matching error text emitted during expression evaluation.
+  Matcher _matches(String text) {
+    var unindented = RegExp.escape(text).replaceAll(RegExp('[ ]+'), '[ ]*');
+    return matches(RegExp(unindented, multiLine: true));
+  }
+
+  /// Finds the line number in [source] matching [breakpointId].
+  ///
+  /// A breakpoint ID is found by looking for a line that ends with a comment
+  /// of exactly this form: `// Breakpoint: <id>`.
+  ///
+  /// Throws if it can't find the matching line.
+  ///
+  /// Adapted from webdev/blob/master/dwds/test/fixtures/context.dart.
+  int _findBreakpointLine(String breakpointId) {
+    var lines = LineSplitter.split(source).toList();
+    var lineNumber =
+        lines.indexWhere((l) => l.endsWith('// Breakpoint: $breakpointId'));
+    if (lineNumber == -1) {
+      throw StateError(
+          'Unable to find breakpoint in $input with id: $breakpointId');
+    }
+    return lineNumber + 1;
+  }
+
+  /// Finds the corresponding JS WipLocation for a given line in Dart.
+  Future<wip.WipLocation> _jsLocationFromDartLine(
+      wip.WipScript script, int dartLine) async {
+    var inputSourceUrl = input.pathSegments.last;
+    for (var lineEntry in compiler.sourceMap.lines) {
+      for (var entry in lineEntry.entries) {
+        if (entry.sourceUrlId != null &&
+            entry.sourceLine == dartLine &&
+            compiler.sourceMap.urls[entry.sourceUrlId] == inputSourceUrl) {
+          return wip.WipLocation.fromValues(script.scriptId, lineEntry.line);
+        }
+      }
+    }
+    throw StateError(
+        'Unable to extract WIP Location from ${script.url} for Dart line $dartLine.');
+  }
+}
+
+/// Filters the provided frame scopes to those that are pertinent for Dart
+/// debugging.
+///
+/// Copied from webdev/dwds/lib/src/debugging/dart_scope.dart.
+List<wip.WipScope> filterScopes(wip.WipCallFrame frame) {
+  var scopes = frame.getScopeChain().toList();
+  // Remove outer scopes up to and including the Dart SDK.
+  while (
+      scopes.isNotEmpty && !(scopes.last.name?.startsWith('load__') ?? false)) {
+    scopes.removeLast();
+  }
+  if (scopes.isNotEmpty) scopes.removeLast();
+  return scopes;
+}
+
+String escaped(String path) => path.replaceAll('\\', '\\\\');
diff --git a/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_unsound_test.dart b/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_unsound_test.dart
new file mode 100644
index 0000000..7ac4ce7
--- /dev/null
+++ b/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_unsound_test.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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 dev_compiler.test.expression_compiler;
+
+import 'package:test/test.dart';
+import 'expression_compiler_e2e_shared.dart';
+import 'expression_compiler_e2e_suite.dart';
+
+void main() async {
+  var driver = await TestDriver.init();
+  var setup = SetupCompilerOptions(soundNullSafety: false);
+
+  group('(Unsound null safety)', () {
+    tearDownAll(() {
+      driver.finish();
+    });
+
+    runSharedTests(setup, driver);
+  });
+}
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 b335acd..17e60eb 100644
--- a/pkg/dev_compiler/test/expression_compiler/expression_compiler_test.dart
+++ b/pkg/dev_compiler/test/expression_compiler/expression_compiler_test.dart
@@ -8,7 +8,9 @@
 
 import 'package:cli_util/cli_util.dart';
 import 'package:dev_compiler/dev_compiler.dart';
+import 'package:dev_compiler/src/compiler/js_names.dart';
 import 'package:dev_compiler/src/compiler/module_builder.dart';
+import 'package:dev_compiler/src/js_ast/js_ast.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/incremental_serializer.dart';
@@ -16,6 +18,7 @@
 import 'package:kernel/target/targets.dart';
 import 'package:path/path.dart' as p;
 import 'package:test/test.dart';
+import 'package:vm/transformations/type_flow/utils.dart';
 
 // TODO(annagrin): Replace javascript matching in tests below with evaluating
 // the javascript and checking the result.
@@ -74,8 +77,11 @@
   final List<String> errors = [];
   final CompilerOptions options;
   final String dartLangComment;
+  final ModuleFormat moduleFormat;
+  final bool soundNullSafety;
 
-  SetupCompilerOptions(bool soundNullSafety)
+  SetupCompilerOptions(
+      {this.soundNullSafety = true, this.moduleFormat = ModuleFormat.amd})
       : options = getOptions(soundNullSafety),
         dartLangComment =
             soundNullSafety ? dartSoundComment : dartUnsoundComment {
@@ -83,6 +89,17 @@
       errors.addAll(m.plainTextFormatted);
     };
   }
+
+  String get loadModule {
+    switch (moduleFormat) {
+      case ModuleFormat.amd:
+        return 'require';
+      case ModuleFormat.ddc:
+        return 'dart_library.import';
+      default:
+        throw UnsupportedError('Module format: $moduleFormat');
+    }
+  }
 }
 
 /// Convenience class describing JavaScript module
@@ -116,7 +133,7 @@
 
   @override
   String toString() =>
-      'Name: $name, File: $file, Package: $package, path: $path';
+      'Name: \$name, File: \$file, Package: \$package, path: \$path';
 }
 
 class TestCompilationResult {
@@ -145,8 +162,13 @@
     component.computeCanonicalNames();
 
     // initialize ddc
+    var moduleName = 'foo.dart';
     var classHierarchy = compiler.getClassHierarchy();
-    var compilerOptions = SharedCompilerOptions(replCompile: true);
+    var compilerOptions = SharedCompilerOptions(
+        replCompile: true,
+        moduleName: moduleName,
+        soundNullSafety: setup.soundNullSafety,
+        moduleFormats: [setup.moduleFormat]);
     var coreTypes = compiler.getCoreTypes();
 
     final importToSummary = Map<Library, Component>.identity();
@@ -154,16 +176,28 @@
     for (var lib in component.libraries) {
       importToSummary[lib] = component;
     }
-    summaryToModule[component] = 'foo.dart';
+    summaryToModule[component] = moduleName;
 
     var kernel2jsCompiler = ProgramCompiler(component, classHierarchy,
         compilerOptions, importToSummary, summaryToModule,
         coreTypes: coreTypes);
-    kernel2jsCompiler.emitModule(component);
+    var moduleTree = kernel2jsCompiler.emitModule(component);
+
+    {
+      var opts = JavaScriptPrintingOptions(
+          allowKeywordsInProperties: true, allowSingleLineIfStatements: true);
+      var printer = SimpleJavaScriptPrintingContext();
+
+      var tree = transformModuleFormat(setup.moduleFormat, moduleTree);
+      tree.accept(Printer(opts, printer, localNamer: TemporaryNamer(tree)));
+      var printed = printer.getText();
+      debugPrint(printed);
+    }
 
     // create expression compiler
     var evaluator = ExpressionCompiler(
       setup.options,
+      setup.moduleFormat,
       setup.errors,
       compiler,
       kernel2jsCompiler,
@@ -240,7 +274,7 @@
     tempDir.delete(recursive: true);
   }
 
-  void check(
+  Future<void> check(
       {Map<String, String> scope,
       String expression,
       String expectedError,
@@ -289,1080 +323,197 @@
 }
 
 void main() {
-  group('Unsound null safety:', () {
-    var options = SetupCompilerOptions(false);
+  for (var moduleFormat in [ModuleFormat.amd, ModuleFormat.ddc]) {
+    group('Module format: $moduleFormat', () {
+      group('Unsound null safety:', () {
+        var options = SetupCompilerOptions(
+            soundNullSafety: false, moduleFormat: moduleFormat);
 
-    group('Expression compiler scope collection tests', () {
-      var source = '''
-        ${options.dartLangComment}
-
-        class C {
-          C(int this.field);
-
-          int methodFieldAccess(int x) {
-            var inScope = 1;
-            {
-              var innerInScope = global + staticField + field;
-              /* evaluation placeholder */
-              print(innerInScope);
-              var innerNotInScope = 2;
-            }
-            var notInScope = 3;
+        group('Expression compiler import tests', () {
+          var source = '''
+          ${options.dartLangComment}
+          import 'dart:io' show Directory;
+          import 'dart:io' as p;
+          import 'dart:convert' as p;
+          
+          main() {
+            print(Directory.systemTemp);
+            print(p.Directory.systemTemp);
+            print(p.utf.decoder);
           }
 
-          static int staticField = 0;
-          int field;
-        }
-
-        int global = 42;
-        main() => 0;
-        ''';
-
-      TestDriver driver;
-
-      setUp(() {
-        driver = TestDriver(options, source);
-      });
-
-      tearDown(() {
-        driver.delete();
-      });
-
-      test('local in scope', () async {
-        await driver.check(
-            scope: <String, String>{'inScope': '1', 'innerInScope': '0'},
-            expression: 'inScope',
-            expectedResult: '''
-            (function(inScope, innerInScope) {
-              return inScope;
-            }.bind(this)(
-              1,
-              0
-            ))
-            ''');
-      });
-
-      test('local in inner scope', () async {
-        await driver.check(
-            scope: <String, String>{'inScope': '1', 'innerInScope': '0'},
-            expression: 'innerInScope',
-            expectedResult: '''
-            (function(inScope, innerInScope) {
-              return innerInScope;
-            }.bind(this)(
-              1,
-              0
-            ))
-            ''');
-      });
-
-      test('global in scope', () async {
-        await driver.check(
-            scope: <String, String>{'inScope': '1', 'innerInScope': '0'},
-            expression: 'global',
-            expectedResult: '''
-            (function(inScope, innerInScope) {
-              return foo.global;
-            }.bind(this)(
-              1,
-              0
-            ))
-            ''');
-      });
-
-      test('static field in scope', () async {
-        await driver.check(
-            scope: <String, String>{'inScope': '1', 'innerInScope': '0'},
-            expression: 'staticField',
-            expectedResult: '''
-            (function(inScope, innerInScope) {
-              return foo.C.staticField;
-            }.bind(this)(
-              1,
-              0
-            ))
-            ''');
-      });
-
-      test('field in scope', () async {
-        await driver.check(
-            scope: <String, String>{'inScope': '1', 'innerInScope': '0'},
-            expression: 'field',
-            expectedResult: '''
-            (function(inScope, innerInScope) {
-              return this.field;
-            }.bind(this)(
-              1,
-              0
-            ))
-            ''');
-      });
-
-      test('local not in scope', () async {
-        await driver.check(
-            scope: <String, String>{'inScope': '1', 'innerInScope': '0'},
-            expression: 'notInScope',
-            expectedError:
-                "Error: The getter 'notInScope' isn't defined for the class 'C'.");
-      });
-
-      test('local not in inner scope', () async {
-        await driver.check(
-            scope: <String, String>{'inScope': '1', 'innerInScope': '0'},
-            expression: 'innerNotInScope',
-            expectedError:
-                "Error: The getter 'innerNotInScope' isn't defined for the class 'C'.");
-      });
-    });
-
-    group('Expression compiler tests in extension method:', () {
-      var source = '''
-        ${options.dartLangComment}
-        extension NumberParsing on String {
-          int parseInt() {
-            var ret = int.parse(this);
+          void foo() {
             /* evaluation placeholder */
-            return ret;
           }
-        }
-        main() => 0;
-      ''';
+          ''';
 
-      TestDriver driver;
+          TestDriver driver;
 
-      setUp(() {
-        driver = TestDriver(options, source);
-      });
+          setUp(() {
+            driver = TestDriver(options, source);
+          });
 
-      tearDown(() {
-        driver.delete();
-      });
+          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;
+          test('expression referencing unnamed import', () async {
+            await driver.check(
+                scope: <String, String>{},
+                expression: 'Directory.systemTemp',
+                expectedResult: '''
+            (function() {
+              const dart_sdk = ${options.loadModule}(\'dart_sdk\');
+              const io = dart_sdk.io;
+              return io.Directory.systemTemp;
             }(
-              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:', () {
-      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;
+          test('expression referencing named import', () async {
+            await driver.check(
+                scope: <String, String>{},
+                expression: 'p.Directory.systemTemp',
+                expectedResult: '''
+            (function() {
+              const dart_sdk = ${options.loadModule}(\'dart_sdk\');
+              const io = dart_sdk.io;
+              return io.Directory.systemTemp;
             }(
-              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;
+          test(
+              'expression referencing another library with the same named import',
+              () async {
+            await driver.check(
+                scope: <String, String>{},
+                expression: 'p.utf8.decoder',
+                expectedResult: '''
+            (function() {
+              const dart_sdk = ${options.loadModule}(\'dart_sdk\');
+              const convert = dart_sdk.convert;
+              return convert.utf8.decoder;
             }(
-              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
-            ))
-            ''');
-      });
+        group('Expression compiler extension symbols tests', () {
+          var source = '''
+          ${options.dartLangComment}
 
-      test('function', () async {
-        await driver.check(
-            scope: <String, String>{'x': '1', 'y': '2', 'z': '3'},
-            expression: 'main',
-            expectedResult: '''
-            (function(x, y, z) {
-              T\$Eval.VoidTodynamic = () => (T\$Eval.VoidTodynamic = dart.constFn(dart.fnType(dart.dynamic, [])))();
-              return dart.fn(foo.main, T\$Eval.VoidTodynamic());
-            }(
-              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) {
+          main() {
+            List<int> list = {};
+            list.add(0);
             /* evaluation placeholder */
-            return x + _field + _staticField;
+          }
+          ''';
+
+          TestDriver driver;
+
+          setUp(() {
+            driver = TestDriver(options, source);
+          });
+
+          tearDown(() {
+            driver.delete();
+          });
+
+          test('extension symbol used in original compilation', () async {
+            await driver.check(
+                scope: <String, String>{'list': 'list'},
+                expression: 'list.add(1)',
+                expectedResult: '''
+            (function(list) {
+              const dart_sdk = ${options.loadModule}('dart_sdk');
+              const dartx = dart_sdk.dartx;
+              var \$add = dartx.add;
+              var S = {\$add: dartx.add};
+              return list[\$add](1);
+            }(
+              list
+            ))
+            ''');
+          });
+
+          test('extension symbol used only in expression compilation',
+              () async {
+            await driver.check(
+                scope: <String, String>{'list': 'list'},
+                expression: 'list.first',
+                expectedResult: '''
+            (function(list) {
+              const dart_sdk = ${options.loadModule}('dart_sdk');
+              const dartx = dart_sdk.dartx;
+              var S = {\$first: dartx.first};
+              return list[S.\$first];
+            }(
+              list
+            ))
+            ''');
+          });
+        });
+
+        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;
           }
 
-          Future<int> asyncMethod(int x) async {
-            return x;
-          }
-        }
+          main() => 0;
+          ''';
 
-        main() => 0;
-        ''';
+          TestDriver driver;
+          setUp(() {
+            driver = TestDriver(options, source);
+          });
 
-      TestDriver driver;
+          tearDown(() {
+            driver.delete();
+          });
 
-      setUp(() {
-        driver = TestDriver(options, source);
-      });
+          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'.");
+          });
 
-      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: '''
+          test('expression using uncaptured variables', () async {
+            await driver.check(
+                scope: <String, String>{
+                  'x': '1',
+                  'c': 'null',
+                  'y': '3',
+                  'z': '0'
+                },
+                expression: "'\$x+\$y+\$z'",
+                expectedResult: '''
             (function(x, c, y, z) {
+              const dart_sdk = ${options.loadModule}('dart_sdk');
+              const dart = dart_sdk.dart;
               return dart.str(x) + "+" + dart.str(y) + "+" + dart.str(z);
             }(
               1,
@@ -1371,14 +522,21 @@
               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: '''
+          test('expression using captured variables', () async {
+            await driver.check(
+                scope: <String, String>{
+                  'x': '1',
+                  'c': 'null',
+                  'y': '3',
+                  'z': '0'
+                },
+                expression: "'\$y+\$z'",
+                expectedResult: '''
             (function(x, c, y, z) {
+              const dart_sdk = ${options.loadModule}('dart_sdk');
+              const dart = dart_sdk.dart;
               return dart.str(y) + "+" + dart.str(z);
             }(
               1,
@@ -1387,779 +545,173 @@
               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 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) {
-              T\$Eval.StringL = () => (T\$Eval.StringL = dart.constFn(dart.legacy(core.String)))();
-              return foo.baz(T\$Eval.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) {
-              return dart.const({
-                __proto__: foo.MyClass.prototype,
-                [_t]: 1
-              });
-            }(
-              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) {
-              return dart.const({
-                __proto__: foo.ValueKey.prototype,
-                [value]: "t"
-                });
-            }(
-              1
-            ))
-            ''');
-      });
-    });
-
-    group('Expression compiler tests in constructor:', () {
-      var source = '''
-        ${options.dartLangComment}
-        extension NumberParsing on String {
-          int parseInt() {
-            return int.parse(this);
+        group(
+            'Expression compiler tests for interactions with module containers:',
+            () {
+          var source = '''
+          ${options.dartLangComment}
+          class A {
+            const A();
           }
-        }
-
-        int global = 42;
-
-        class C {
-          C(int this.field, int this._field) {
-            int x = 1;
+          class B {
+            const B();
+          }
+          void foo() {
+            const a = A();
+            var check = a is int;
             /* evaluation placeholder */
-            print(this.field);
+            return;
           }
 
-          static int staticField = 0;
-          static int _staticField = 1;
+          void main() => foo();
+          ''';
 
-          int _field;
-          int field;
+          TestDriver driver;
+          setUp(() {
+            driver = TestDriver(options, source);
+          });
 
-          int methodFieldAccess(int t) {
-            return t + _field + _staticField;
-          }
+          tearDown(() {
+            driver.delete();
+          });
 
-          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 simple 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'");
-      });
-    });
-
-    group('Expression compiler tests for interactions with module containers:',
-        () {
-      var source = '''
-        ${options.dartLangComment}
-        class A {
-          const A();
-        }
-        class B {
-          const B();
-        }
-        void foo() {
-          const a = A();
-          var check = a is int;
-          /* evaluation placeholder */
-          return;
-        }
-        
-        void main() => foo();
-        ''';
-
-      TestDriver driver;
-      setUp(() {
-        driver = TestDriver(options, source);
-      });
-
-      tearDown(() {
-        driver.delete();
-      });
-
-      test('evaluation that non-destructively appends to the type container',
-          () async {
-        await driver.check(
-            scope: <String, String>{'a': 'null', 'check': 'null'},
-            expression: 'a is String',
-            expectedResult: '''
+          test(
+              'evaluation that non-destructively appends to the type container',
+              () async {
+            await driver.check(
+                scope: <String, String>{'a': 'null', 'check': 'null'},
+                expression: 'a is String',
+                expectedResult: '''
             (function(a, check) {
-              T\$Eval.StringL = () => (T\$Eval.StringL = dart.constFn(dart.legacy(core.String)))();
-              return T\$Eval.StringL().is(a);
+              const dart_sdk = ${options.loadModule}('dart_sdk');
+              const core = dart_sdk.core;
+              const dart = dart_sdk.dart;
+              var T = {
+                StringL: () => (T.StringL = dart.constFn(dart.legacy(core.String)))()
+              };
+              return T.StringL().is(a);
             }(
               null,
               null
             ))
             ''');
-      });
+          });
 
-      test('evaluation that reuses the type container', () async {
-        await driver.check(
-            scope: <String, String>{'a': 'null', 'check': 'null'},
-            expression: 'a is int',
-            expectedResult: '''
+          test('evaluation that reuses the type container', () async {
+            await driver.check(
+                scope: <String, String>{'a': 'null', 'check': 'null'},
+                expression: 'a is int',
+                expectedResult: '''
             (function(a, check) {
-              return T\$Eval.intL().is(a);
+              const dart_sdk = ${options.loadModule}('dart_sdk');
+              const core = dart_sdk.core;
+              const dart = dart_sdk.dart;
+              var T = {
+                intL: () => (T.intL = dart.constFn(dart.legacy(core.int)))()
+              };
+              return T.intL().is(a);
             }(
               null,
               null
             ))
             ''');
-      });
+          });
 
-      test(
-          'evaluation that non-destructively appends to the constant container',
-          () async {
-        await driver.check(
-            scope: <String, String>{'a': 'null', 'check': 'null'},
-            expression: 'const B()',
-            expectedResult: '''
+          test(
+              'evaluation that non-destructively appends to the constant container',
+              () async {
+            await driver.check(
+                scope: <String, String>{'a': 'null', 'check': 'null'},
+                expression: 'const B()',
+                expectedResult: '''
             (function(a, check) {
-              return dart.const({
-                __proto__: foo.B.prototype
-              });
+             const dart_sdk = ${options.loadModule}('dart_sdk');
+              const dart = dart_sdk.dart;
+              const foo\$46dart = ${options.loadModule}('foo.dart');
+              const foo = foo\$46dart.foo;
+              const CT = Object.create(null);
+              dart.defineLazy(CT, {
+                get C0() {
+                  return C[0] = dart.const({
+                    __proto__: foo.B.prototype
+                  });
+                }
+              }, false);
+              var C = [void 0];
+              return C[0] || CT.C0;
             }(
               null,
               null
             ))
             ''');
-      });
+          });
 
-      test(
-          'evaluation that reuses the constant container and canonicalizes properly',
-          () async {
-        await driver.check(
-            scope: <String, String>{'a': 'null', 'check': 'null'},
-            expression: 'a == const A()',
-            expectedResult: '''
+          test(
+              'evaluation that reuses the constant container and canonicalizes properly',
+              () async {
+            await driver.check(
+                scope: <String, String>{'a': 'null', 'check': 'null'},
+                expression: 'a == const A()',
+                expectedResult: '''
             (function(a, check) {
-              return dart.equals(a, dart.const({
-                __proto__: foo.A.prototype
-              }));
+              const dart_sdk = ${options.loadModule}('dart_sdk');
+              const dart = dart_sdk.dart;
+              const foo\$46dart = ${options.loadModule}('foo.dart');
+              const foo = foo\$46dart.foo;
+              const CT = Object.create(null);
+              dart.defineLazy(CT, {
+                get C0() {
+                  return C[0] = dart.const({
+                    __proto__: foo.A.prototype
+                  });
+                }
+              }, false);
+              var C = [void 0];
+              return dart.equals(a, C[0] || CT.C0);
             }(
               null,
               null
             ))
             ''');
-      });
-    });
+          });
+        });
 
-    group('Expression compiler tests in generic method:', () {
-      var source = '''
-        ${options.dartLangComment}
-        class A {
-          void generic<TType, KType>(TType a, KType b) {
-            /* evaluation placeholder */
-            print(a);
-            print(b);
+        group('Expression compiler tests in generic method:', () {
+          var source = '''
+          ${options.dartLangComment}
+          class A {
+            void generic<TType, KType>(TType a, KType b) {
+              /* evaluation placeholder */
+              print(a);
+              print(b);
+            }
           }
-        }
 
-        void main() => generic<int, String>(0, 'hi');
-        ''';
+          void main() => generic<int, String>(0, 'hi');
+          ''';
 
-      TestDriver driver;
-      setUp(() {
-        driver = TestDriver(options, source);
-      });
+          TestDriver driver;
+          setUp(() {
+            driver = TestDriver(options, source);
+          });
 
-      tearDown(() {
-        driver.delete();
-      });
+          tearDown(() {
+            driver.delete();
+          });
 
-      test('evaluate formals', () async {
-        await driver.check(
-            scope: <String, String>{
-              'TType': 'TType',
-              'KType': 'KType',
-              'a': 'a',
-              'b': 'b'
-            },
-            expression: 'a',
-            expectedResult: '''
+          test('evaluate formals', () async {
+            await driver.check(
+                scope: <String, String>{
+                  'TType': 'TType',
+                  'KType': 'KType',
+                  'a': 'a',
+                  'b': 'b'
+                },
+                expression: 'a',
+                expectedResult: '''
             (function(TType, KType, a, b) {
                 return a;
             }.bind(this)(
@@ -2169,19 +721,21 @@
               b
             ))
             ''');
-      });
+          });
 
-      test('evaluate type parameters', () async {
-        await driver.check(
-            scope: <String, String>{
-              'TType': 'TType',
-              'KType': 'KType',
-              'a': 'a',
-              'b': 'b'
-            },
-            expression: 'TType',
-            expectedResult: '''
+          test('evaluate type parameters', () async {
+            await driver.check(
+                scope: <String, String>{
+                  'TType': 'TType',
+                  'KType': 'KType',
+                  'a': 'a',
+                  'b': 'b'
+                },
+                expression: 'TType',
+                expectedResult: '''
             (function(TType, KType, a, b) {
+              const dart_sdk = ${options.loadModule}('dart_sdk');
+              const dart = dart_sdk.dart;
               return dart.wrapType(dart.legacy(TType));
             }.bind(this)(
               TType,
@@ -2190,1084 +744,249 @@
               b
             ))
             ''');
-      });
-    });
-  });
+          });
+        });
 
-  group('Sound null safety:', () {
-    var options = SetupCompilerOptions(true);
-
-    group('Expression compiler scope collection tests', () {
-      var source = '''
-        ${options.dartLangComment}
-
-        class C {
-          C(int this.field);
-
-          int methodFieldAccess(int x) {
-            var inScope = 1;
-            {
-              var innerInScope = global + staticField + field;
-              /* evaluation placeholder */
-              print(innerInScope);
-              var innerNotInScope = 2;
-            }
-            var notInScope = 3;
-          }
-
-          static int staticField = 0;
-          int field;
-        }
-
-        int global = 42;
-        main() => 0;
-        ''';
-
-      TestDriver driver;
-
-      setUp(() {
-        driver = TestDriver(options, source);
-      });
-
-      tearDown(() {
-        driver.delete();
-      });
-
-      test('local in scope', () async {
-        await driver.check(
-            scope: <String, String>{'inScope': '1', 'innerInScope': '0'},
-            expression: 'inScope',
-            expectedResult: '''
-            (function(inScope, innerInScope) {
-              return inScope;
-            }.bind(this)(
-              1,
-              0
-            ))
-            ''');
-      });
-
-      test('local in inner scope', () async {
-        await driver.check(
-            scope: <String, String>{'inScope': '1', 'innerInScope': '0'},
-            expression: 'innerInScope',
-            expectedResult: '''
-            (function(inScope, innerInScope) {
-              return innerInScope;
-            }.bind(this)(
-              1,
-              0
-            ))
-            ''');
-      });
-
-      test('global in scope', () async {
-        await driver.check(
-            scope: <String, String>{'inScope': '1', 'innerInScope': '0'},
-            expression: 'global',
-            expectedResult: '''
-            (function(inScope, innerInScope) {
-              return foo.global;
-            }.bind(this)(
-              1,
-              0
-            ))
-            ''');
-      });
-
-      test('static field in scope', () async {
-        await driver.check(
-            scope: <String, String>{'inScope': '1', 'innerInScope': '0'},
-            expression: 'staticField',
-            expectedResult: '''
-            (function(inScope, innerInScope) {
-              return foo.C.staticField;
-            }.bind(this)(
-              1,
-              0
-            ))
-            ''');
-      });
-
-      test('field in scope', () async {
-        await driver.check(
-            scope: <String, String>{'inScope': '1', 'innerInScope': '0'},
-            expression: 'field',
-            expectedResult: '''
-            (function(inScope, innerInScope) {
-              return this.field;
-            }.bind(this)(
-              1,
-              0
-            ))
-            ''');
-      });
-
-      test('local not in scope', () async {
-        await driver.check(
-            scope: <String, String>{'inScope': '1', 'innerInScope': '0'},
-            expression: 'notInScope',
-            expectedError:
-                "Error: The getter 'notInScope' isn't defined for the class 'C'.");
-      });
-
-      test('local not in inner scope', () async {
-        await driver.check(
-            scope: <String, String>{'inScope': '1', 'innerInScope': '0'},
-            expression: 'innerNotInScope',
-            expectedError:
-                "Error: The getter 'innerNotInScope' isn't defined for the class 'C'.");
-      });
-    });
-
-    group('Expression compiler tests in extension method:', () {
-      var source = '''
-        ${options.dartLangComment}
-        extension NumberParsing on String {
-          int parseInt() {
-            var ret = int.parse(this);
+        group('Expression compiler tests using extension symbols', () {
+          var source = '''
+          ${options.dartLangComment}
+          void bar() {
             /* evaluation placeholder */
-            return ret;
           }
-        }
-        main() => 0;
-      ''';
 
-      TestDriver driver;
+          void main() => bar();
+          ''';
 
-      setUp(() {
-        driver = TestDriver(options, source);
-      });
+          TestDriver driver;
+          setUp(() {
+            driver = TestDriver(options, source);
+          });
 
-      tearDown(() {
-        driver.delete();
-      });
+          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;
+          test('map access', () async {
+            await driver.check(
+                scope: <String, String>{'inScope': '1', 'innerInScope': '0'},
+                expression:
+                    '(Map<String, String> params) { return params["index"]; }({})',
+                expectedResult: '''
+            (function() {
+              const dart_sdk = ${options.loadModule}('dart_sdk');
+              const core = dart_sdk.core;
+              const _js_helper = dart_sdk._js_helper;
+              const dart = dart_sdk.dart;
+              const dartx = dart_sdk.dartx;
+              var T = {
+                StringL: () => (T.StringL = dart.constFn(dart.legacy(core.String)))(),
+                MapOfStringL\$StringL: () => (T.MapOfStringL\$StringL = dart.constFn(core.Map\$(T.StringL(), T.StringL())))(),
+                MapLOfStringL\$StringL: () => (T.MapLOfStringL\$StringL = dart.constFn(dart.legacy(T.MapOfStringL\$StringL())))(),
+                MapLOfStringL\$StringLToStringL: () => (T.MapLOfStringL\$StringLToStringL = dart.constFn(dart.fnType(T.StringL(), [T.MapLOfStringL\$StringL()])))(),
+                IdentityMapOfStringL\$StringL: () => (T.IdentityMapOfStringL\$StringL = dart.constFn(_js_helper.IdentityMap\$(T.StringL(), T.StringL())))()
+              };
+              var S = {\$_get: dartx._get};
+              return dart.fn(params => params[S.\$_get]("index"), T.MapLOfStringL\$StringLToStringL())(new (T.IdentityMapOfStringL\$StringL()).new());
             }(
-              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:', () {
-      var source = '''
-        ${options.dartLangComment}
-        int foo(int x, {int y}) {
-          int z = 0;
-          /* evaluation placeholder */
-          return x + y + z;
-        }
+  for (var moduleFormat in [ModuleFormat.amd, ModuleFormat.ddc]) {
+    group('Module format: $moduleFormat', () {
+      group('Sound null safety:', () {
+        var options = SetupCompilerOptions(soundNullSafety: true);
 
-        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) {
-              T\$Eval.VoidTodynamic = () => (T\$Eval.VoidTodynamic = dart.constFn(dart.fnType(dart.dynamic, [])))();
-              return dart.fn(foo.main, T\$Eval.VoidTodynamic());
-            }(
-              1,
-              2,
-              3
-            ))
-            ''');
-      });
-    });
-
-    group('Expression compiler tests in method:', () {
-      var source = '''
-        ${options.dartLangComment}
-        extension NumberParsing on String {
-          int parseInt() {
-            return int.parse(this);
+        group('Expression compiler import tests', () {
+          var source = '''
+          ${options.dartLangComment}
+          import 'dart:io' show Directory;
+          import 'dart:io' as p;
+          import 'dart:convert' as p;
+          
+          main() {
+            print(Directory.systemTemp);
+            print(p.Directory.systemTemp);
+            print(p.utf.decoder);
           }
-        }
 
-        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) {
+          void foo() {
             /* evaluation placeholder */
-            return x + _field + _staticField;
           }
+          ''';
 
-          Future<int> asyncMethod(int x) async {
-            return x;
-          }
-        }
+          TestDriver driver;
 
-        main() => 0;
-        ''';
+          setUp(() {
+            driver = TestDriver(options, source);
+          });
 
-      TestDriver driver;
+          tearDown(() {
+            driver.delete();
+          });
 
-      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('expression referencing unnamed import', () async {
+            await driver.check(
+                scope: <String, String>{},
+                expression: 'Directory.systemTemp',
+                expectedResult: '''
+            (function() {
+              const dart_sdk = ${options.loadModule}(\'dart_sdk\');
+              const io = dart_sdk.io;
+              return io.Directory.systemTemp;
+            }(
+              
             ))
             ''');
-      });
+          });
 
-      test('this', () async {
-        await driver.check(
-            scope: <String, String>{'x': '1'},
-            expression: 'this',
-            expectedResult: '''
-            (function(x) {
-              return this;
-            }.bind(this)(
-              1
+          test('expression referencing named import', () async {
+            await driver.check(
+                scope: <String, String>{},
+                expression: 'p.Directory.systemTemp',
+                expectedResult: '''
+            (function() {
+              const dart_sdk = ${options.loadModule}(\'dart_sdk\');
+              const io = dart_sdk.io;
+              return io.Directory.systemTemp;
+            }(
+              
             ))
             ''');
-      });
+          });
 
-      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 referencing another library with the same named import',
+              () async {
+            await driver.check(
+                scope: <String, String>{},
+                expression: 'p.utf8.decoder',
+                expectedResult: '''
+            (function() {
+              const dart_sdk = ${options.loadModule}(\'dart_sdk\');
+              const convert = dart_sdk.convert;
+              return convert.utf8.decoder;
+            }(
+              
             ))
             ''');
-      });
+          });
+        });
 
-      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) {
+        group('Expression compiler extension symbols tests', () {
+          var source = '''
+          ${options.dartLangComment}
+    
+          main() {
+            List<int> list = {};
+            list.add(0);
             /* evaluation placeholder */
-            return x;
+          }
+          ''';
+
+          TestDriver driver;
+
+          setUp(() {
+            driver = TestDriver(options, source);
+          });
+
+          tearDown(() {
+            driver.delete();
+          });
+
+          test('extension symbol used in original compilation', () async {
+            await driver.check(
+                scope: <String, String>{'list': 'list'},
+                expression: 'list.add(1)',
+                expectedResult: '''
+            (function(list) {
+              const dart_sdk = ${options.loadModule}('dart_sdk');
+              const dartx = dart_sdk.dartx;
+              var \$add = dartx.add;
+              var S = {\$add: dartx.add};
+              return list[\$add](1);
+            }(
+              list
+            ))
+            ''');
+          });
+
+          test('extension symbol used only in expression compilation',
+              () async {
+            await driver.check(
+                scope: <String, String>{'list': 'list'},
+                expression: 'list.first',
+                expectedResult: '''
+            (function(list) {
+              const dart_sdk = ${options.loadModule}('dart_sdk');
+              const dartx = dart_sdk.dartx;
+              var S = {\$first: dartx.first};
+              return list[S.\$first];
+            }(
+              list
+            ))
+            ''');
+          });
+        });
+
+        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;
           }
 
-          Future<int> asyncMethod(int x) async {
-            return x;
-          }
-        }
+          main() => 0;
+          ''';
 
-        main() => 0;
-        ''';
+          TestDriver driver;
+          setUp(() {
+            driver = TestDriver(options, source);
+          });
 
-      TestDriver driver;
-      setUp(() {
-        driver = TestDriver(options, source);
-      });
+          tearDown(() {
+            driver.delete();
+          });
 
-      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('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: '''
+          test('expression using uncaptured variables', () async {
+            await driver.check(
+                scope: <String, String>{
+                  'x': '1',
+                  'c': 'null',
+                  'y': '3',
+                  'z': '0'
+                },
+                expression: "'\$x+\$y+\$z'",
+                expectedResult: '''
             (function(x, c, y, z) {
+              const dart_sdk = ${options.loadModule}('dart_sdk');
+              const dart = dart_sdk.dart;
               return dart.str(x) + "+" + dart.str(y) + "+" + dart.str(z);
             }(
               1,
@@ -3276,14 +995,21 @@
               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: '''
+          test('expression using captured variables', () async {
+            await driver.check(
+                scope: <String, String>{
+                  'x': '1',
+                  'c': 'null',
+                  'y': '3',
+                  'z': '0'
+                },
+                expression: "'\$y+\$z'",
+                expectedResult: '''
             (function(x, c, y, z) {
+              const dart_sdk = ${options.loadModule}('dart_sdk');
+              const dart = dart_sdk.dart;
               return dart.str(y) + "+" + dart.str(z);
             }(
               1,
@@ -3292,682 +1018,42 @@
               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) {
-              return dart.const({
-                __proto__: foo.MyClass.prototype,
-                [_t]: 1
-              });
-            }(
-              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) {
-              return dart.const({
-                __proto__: foo.ValueKey.prototype,
-                [value]: "t"
-                });
-            }(
-              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);
+        group('Expression compiler tests in generic method:', () {
+          var source = '''
+          ${options.dartLangComment}
+          class A {
+            void generic<TType, KType>(TType a, KType b) {
+              /* evaluation placeholder */
+              print(a);
+              print(b);
+            }
           }
 
-          static int staticField = 0;
-          static int _staticField = 1;
+          void main() => generic<int, String>(0, 'hi');
+          ''';
 
-          int _field;
-          int field;
+          TestDriver driver;
+          setUp(() {
+            driver = TestDriver(options, source);
+          });
 
-          int methodFieldAccess(int t) {
-            return t + _field + _staticField;
-          }
+          tearDown(() {
+            driver.delete();
+          });
 
-          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'");
-      });
-    });
-
-    group('Expression compiler tests in generic method:', () {
-      var source = '''
-        ${options.dartLangComment}
-        class A {
-          void generic<TType, KType>(TType a, KType b) {
-            /* evaluation placeholder */
-            print(a);
-            print(b);
-          }
-        }
-
-        void main() => generic<int, String>(0, 'hi');
-        ''';
-
-      TestDriver driver;
-      setUp(() {
-        driver = TestDriver(options, source);
-      });
-
-      tearDown(() {
-        driver.delete();
-      });
-
-      test('evaluate formals', () async {
-        await driver.check(
-            scope: <String, String>{
-              'TType': 'TType',
-              'KType': 'KType',
-              'a': 'a',
-              'b': 'b'
-            },
-            expression: 'a',
-            expectedResult: '''
+          test('evaluate formals', () async {
+            await driver.check(
+                scope: <String, String>{
+                  'TType': 'TType',
+                  'KType': 'KType',
+                  'a': 'a',
+                  'b': 'b'
+                },
+                expression: 'a',
+                expectedResult: '''
             (function(TType, KType, a, b) {
                 return a;
             }.bind(this)(
@@ -3977,19 +1063,21 @@
               b
             ))
             ''');
-      });
+          });
 
-      test('evaluate type parameters', () async {
-        await driver.check(
-            scope: <String, String>{
-              'TType': 'TType',
-              'KType': 'KType',
-              'a': 'a',
-              'b': 'b'
-            },
-            expression: 'TType',
-            expectedResult: '''
+          test('evaluate type parameters', () async {
+            await driver.check(
+                scope: <String, String>{
+                  'TType': 'TType',
+                  'KType': 'KType',
+                  'a': 'a',
+                  'b': 'b'
+                },
+                expression: 'TType',
+                expectedResult: '''
             (function(TType, KType, a, b) {
+              const dart_sdk = ${options.loadModule}('dart_sdk');
+              const dart = dart_sdk.dart;
               return dart.wrapType(TType);
             }.bind(this)(
               TType,
@@ -3998,7 +1086,55 @@
               b
             ))
             ''');
+          });
+        });
+
+        group('Expression compiler tests using extension symbols', () {
+          var source = '''
+          ${options.dartLangComment}
+          void bar() {
+            /* evaluation placeholder */ 
+          }
+
+          void main() => bar();
+          ''';
+
+          TestDriver driver;
+          setUp(() {
+            driver = TestDriver(options, source);
+          });
+
+          tearDown(() {
+            driver.delete();
+          });
+
+          test('map access', () async {
+            await driver.check(
+                scope: <String, String>{'inScope': '1', 'innerInScope': '0'},
+                expression:
+                    '(Map<String, String> params) { return params["index"]; }({})',
+                expectedResult: '''
+            (function() {
+              const dart_sdk = ${options.loadModule}('dart_sdk');
+              const core = dart_sdk.core;
+              const _js_helper = dart_sdk._js_helper;
+              const dart = dart_sdk.dart;
+              const dartx = dart_sdk.dartx;
+              var T = {
+                StringN: () => (T.StringN = dart.constFn(dart.nullable(core.String)))(),
+                MapOfString\$String: () => (T.MapOfString\$String = dart.constFn(core.Map\$(core.String, core.String)))(),
+                MapOfString\$StringToStringN: () => (T.MapOfString\$StringToStringN = dart.constFn(dart.fnType(T.StringN(), [T.MapOfString\$String()])))(),
+                IdentityMapOfString\$String: () => (T.IdentityMapOfString\$String = dart.constFn(_js_helper.IdentityMap\$(core.String, core.String)))()
+              };
+              var S = {\$_get: dartx._get};
+              return dart.fn(params => params[S.\$_get]("index"), T.MapOfString\$StringToStringN())(new (T.IdentityMapOfString\$String()).new());
+            }(
+              
+            ))
+            ''');
+          });
+        });
       });
     });
-  });
+  }
 }
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 e964f5f..e5fa0e0 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
@@ -7,6 +7,7 @@
 import 'dart:async';
 import 'dart:convert';
 import 'dart:io' show Directory, File, Platform, Process, stderr, stdout;
+import 'dart:isolate';
 
 import 'package:build_integration/file_system/multi_root.dart';
 import 'package:front_end/src/api_prototype/standard_file_system.dart';
@@ -47,8 +48,10 @@
   final Directory rootDirectory;
   final String outputDir = 'out';
   final bool soundNullSafety;
+  final String moduleFormat;
 
-  TestProjectConfiguration(this.rootDirectory, this.soundNullSafety);
+  TestProjectConfiguration(
+      this.rootDirectory, this.soundNullSafety, this.moduleFormat);
 
   ModuleConfiguration get mainModule => ModuleConfiguration(
       root: root,
@@ -210,486 +213,535 @@
 }
 
 void main() async {
-  for (var soundNullSafety in [true, false]) {
-    group('${soundNullSafety ? "sound" : "unsound"} null safety -', () {
-      for (var summarySupport in [true, false]) {
-        group('${summarySupport ? "" : "no "}debugger summary support -', () {
-          group('expression compiler worker', () {
-            ExpressionCompilerWorker worker;
-            Future workerDone;
-            StreamController<Map<String, dynamic>> requestController;
-            StreamController<Map<String, dynamic>> responseController;
+  for (var moduleFormat in ['amd', 'ddc']) {
+    group('$moduleFormat module format -', () {
+      for (var soundNullSafety in [true, false]) {
+        group('${soundNullSafety ? "sound" : "unsound"} null safety -', () {
+          group('expression compiler worker on startup', () {
             Directory tempDir;
-            TestProjectConfiguration config;
-            List inputs;
-
-            setUpAll(() async {
-              tempDir = Directory.systemTemp.createTempSync('foo bar');
-              config = TestProjectConfiguration(tempDir, soundNullSafety);
-
-              // simulate webdev
-              config.createTestProject();
-              var kernelGenerator = DDCKernelGenerator(config);
-              await kernelGenerator.generate();
-
-              inputs = [
-                {
-                  'path': config.mainModule.fullDillPath.path,
-                  if (summarySupport)
-                    'summaryPath': config.mainModule.summaryDillPath.path,
-                  'moduleName': config.mainModule.moduleName
-                },
-                {
-                  'path': config.testModule.fullDillPath.path,
-                  if (summarySupport)
-                    'summaryPath': config.testModule.summaryDillPath.path,
-                  'moduleName': config.testModule.moduleName
-                },
-                {
-                  'path': config.testModule2.fullDillPath.path,
-                  if (summarySupport)
-                    'summaryPath': config.testModule2.summaryDillPath.path,
-                  'moduleName': config.testModule2.moduleName
-                },
-                {
-                  'path': config.testModule3.fullDillPath.path,
-                  if (summarySupport)
-                    'summaryPath': config.testModule3.summaryDillPath.path,
-                  'moduleName': config.testModule3.moduleName
-                },
-              ];
-            });
-
-            tearDownAll(() async {
-              tempDir.deleteSync(recursive: true);
-            });
+            ReceivePort receivePort;
 
             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,
-                // We should be able to load everything from dill and not require
-                // source parsing. Webdev and google3 integration currently rely on
-                // that. Make the test fail on source reading by not providing a
-                // packages file.
-                packagesFile: null,
-                sdkSummary: config.sdkSummaryPath,
-                fileSystem: fileSystem,
-                requestStream: requestController.stream,
-                sendResponse: responseController.add,
-                soundNullSafety: soundNullSafety,
-                verbose: verbose,
-              );
-              workerDone = worker.start();
+              tempDir = Directory.systemTemp.createTempSync('foo bar');
+              receivePort = ReceivePort();
             });
 
             tearDown(() async {
-              unawaited(requestController.close());
-              await workerDone;
-              unawaited(responseController.close());
+              tempDir.deleteSync(recursive: true);
+              receivePort.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',
-              });
-
+            test('reports failure to consumer', () async {
               expect(
-                  responseController.stream,
+                  receivePort,
                   emitsInOrder([
+                    equals(isA<SendPort>()),
                     equals({
-                      'succeeded': true,
-                    }),
-                    equals({
-                      'succeeded': true,
-                      'errors': isEmpty,
-                      'warnings': isEmpty,
-                      'infos': 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.testModule.moduleName,
-              });
-
-              expect(
-                  responseController.stream,
-                  emitsInOrder([
-                    equals({
-                      'succeeded': true,
-                    }),
-                    equals({
-                      'succeeded': true,
-                      'errors': isEmpty,
-                      'warnings': isEmpty,
-                      'infos': 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': 9,
-                '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,
-                      'infos': isEmpty,
-                      'compiledProcedure': contains('return count;'),
-                    })
-                  ]));
-            });
-
-            test(
-                'can load dependencies and compile expressions in main (extension method)',
-                () async {
-              requestController.add({
-                'command': 'UpdateDeps',
-                'inputs': inputs,
-              });
-
-              requestController.add({
-                'command': 'CompileExpression',
-                'expression': 'ret',
-                'line': 19,
-                'column': 1,
-                'jsModules': {},
-                'jsScope': {'ret': 'ret'},
-                'libraryUri': config.mainModule.libraryUri,
-                'moduleName': config.mainModule.moduleName,
-              });
-
-              expect(
-                  responseController.stream,
-                  emitsInOrder([
-                    equals({
-                      'succeeded': true,
-                    }),
-                    equals({
-                      'succeeded': true,
-                      'errors': isEmpty,
-                      'warnings': isEmpty,
-                      'infos': isEmpty,
-                      'compiledProcedure': contains('return ret;'),
-                    })
-                  ]));
-            });
-
-            test(
-                'can load dependencies and compile transitive expressions in main',
-                () async {
-              requestController.add({
-                'command': 'UpdateDeps',
-                'inputs': inputs,
-              });
-
-              requestController.add({
-                'command': 'CompileExpression',
-                'expression': 'B().c().getNumber()',
-                'line': 9,
-                'column': 1,
-                'jsModules': {},
-                'jsScope': {},
-                'libraryUri': config.mainModule.libraryUri,
-                'moduleName': config.mainModule.moduleName,
-              });
-
-              expect(
-                  responseController.stream,
-                  emitsInOrder([
-                    equals({
-                      'succeeded': true,
-                    }),
-                    equals({
-                      'succeeded': true,
-                      'errors': isEmpty,
-                      'warnings': isEmpty,
-                      'infos': isEmpty,
-                      'compiledProcedure': contains(
-                          'return new test_library.B.new().c().getNumber()'),
-                    })
-                  ]));
-            });
-
-            test('can compile series of expressions in various libraries',
-                () async {
-              requestController.add({
-                'command': 'UpdateDeps',
-                'inputs': inputs,
-              });
-
-              requestController.add({
-                'command': 'CompileExpression',
-                'expression': 'B().c().getNumber()',
-                'line': 8,
-                'column': 1,
-                'jsModules': {},
-                'jsScope': {},
-                'libraryUri': config.mainModule.libraryUri,
-                'moduleName': config.mainModule.moduleName,
-              });
-
-              requestController.add({
-                'command': 'CompileExpression',
-                'expression': 'formal',
-                'line': 5,
-                'column': 1,
-                'jsModules': {},
-                'jsScope': {'formal': 'formal'},
-                'libraryUri': config.testModule.libraryUri,
-                'moduleName': config.testModule.moduleName,
-              });
-
-              requestController.add({
-                'command': 'CompileExpression',
-                'expression': 'formal',
-                'line': 3,
-                'column': 1,
-                'jsModules': {},
-                'jsScope': {'formal': 'formal'},
-                'libraryUri': config.testModule2.libraryUri,
-                'moduleName': config.testModule2.moduleName,
-              });
-
-              requestController.add({
-                'command': 'CompileExpression',
-                'expression': 'formal',
-                'line': 3,
-                'column': 1,
-                'jsModules': {},
-                'jsScope': {'formal': 'formal'},
-                'libraryUri': config.testModule3.libraryUri,
-                'moduleName': config.testModule3.moduleName,
-              });
-
-              requestController.add({
-                'command': 'CompileExpression',
-                'expression': 'B().printNumber()',
-                'line': 9,
-                'column': 1,
-                'jsModules': {},
-                'jsScope': {},
-                'libraryUri': config.mainModule.libraryUri,
-                'moduleName': config.mainModule.moduleName,
-              });
-
-              expect(
-                  responseController.stream,
-                  emitsInOrder([
-                    equals({
-                      'succeeded': true,
-                    }),
-                    equals({
-                      'succeeded': true,
-                      'errors': isEmpty,
-                      'warnings': isEmpty,
-                      'infos': isEmpty,
-                      'compiledProcedure':
-                          contains('new test_library.B.new().c().getNumber()'),
-                    }),
-                    equals({
-                      'succeeded': true,
-                      'errors': isEmpty,
-                      'warnings': isEmpty,
-                      'infos': isEmpty,
-                      'compiledProcedure': contains('return formal;'),
-                    }),
-                    equals({
-                      'succeeded': true,
-                      'errors': isEmpty,
-                      'warnings': isEmpty,
-                      'infos': isEmpty,
-                      'compiledProcedure': contains('return formal;'),
-                    }),
-                    equals({
-                      'succeeded': true,
-                      'errors': isEmpty,
-                      'warnings': isEmpty,
-                      'infos': isEmpty,
-                      'compiledProcedure': contains('return formal;'),
-                    }),
-                    equals({
-                      'succeeded': true,
-                      'errors': isEmpty,
-                      'warnings': isEmpty,
-                      'infos': isEmpty,
-                      'compiledProcedure':
-                          contains('test_library.B.new().printNumber()'),
-                    })
-                  ]));
-            });
-
-            test('can compile after dependency update', () async {
-              requestController.add({
-                'command': 'UpdateDeps',
-                'inputs': inputs,
-              });
-
-              requestController.add({
-                'command': 'CompileExpression',
-                'expression': 'B().c().getNumber()',
-                'line': 8,
-                'column': 1,
-                'jsModules': {},
-                'jsScope': {},
-                'libraryUri': config.mainModule.libraryUri,
-                'moduleName': config.mainModule.moduleName,
-              });
-
-              requestController.add({
-                'command': 'CompileExpression',
-                'expression': 'formal',
-                'line': 5,
-                'column': 1,
-                'jsModules': {},
-                'jsScope': {'formal': 'formal'},
-                'libraryUri': config.testModule.libraryUri,
-                'moduleName': config.testModule.moduleName,
-              });
-
-              requestController.add({
-                'command': 'CompileExpression',
-                'expression': 'B().printNumber()',
-                'line': 9,
-                'column': 1,
-                'jsModules': {},
-                'jsScope': {},
-                'libraryUri': config.mainModule.libraryUri,
-                'moduleName': config.mainModule.moduleName,
-              });
-
-              requestController.add({
-                'command': 'UpdateDeps',
-                'inputs': inputs,
-              });
-
-              requestController.add({
-                'command': 'CompileExpression',
-                'expression': 'B().c().getNumber()',
-                'line': 8,
-                'column': 1,
-                'jsModules': {},
-                'jsScope': {},
-                'libraryUri': config.mainModule.libraryUri,
-                'moduleName': config.mainModule.moduleName,
-              });
-
-              requestController.add({
-                'command': 'CompileExpression',
-                'expression': 'formal',
-                'line': 3,
-                'column': 1,
-                'jsModules': {},
-                'jsScope': {'formal': 'formal'},
-                'libraryUri': config.testModule3.libraryUri,
-                'moduleName': config.testModule3.moduleName,
-              });
-
-              expect(
-                  responseController.stream,
-                  emitsInOrder([
-                    equals({
-                      'succeeded': true,
-                    }),
-                    equals({
-                      'succeeded': true,
-                      'errors': isEmpty,
-                      'warnings': isEmpty,
-                      'infos': isEmpty,
-                      'compiledProcedure':
-                          contains('new test_library.B.new().c().getNumber()'),
-                    }),
-                    equals({
-                      'succeeded': true,
-                      'errors': isEmpty,
-                      'warnings': isEmpty,
-                      'infos': isEmpty,
-                      'compiledProcedure': contains('return formal;'),
-                    }),
-                    equals({
-                      'succeeded': true,
-                      'errors': isEmpty,
-                      'warnings': isEmpty,
-                      'infos': isEmpty,
-                      'compiledProcedure':
-                          contains('test_library.B.new().printNumber()'),
-                    }),
-                    equals({
-                      'succeeded': true,
-                    }),
-                    equals({
-                      'succeeded': true,
-                      'errors': isEmpty,
-                      'warnings': isEmpty,
-                      'infos': isEmpty,
-                      'compiledProcedure':
-                          contains('new test_library.B.new().c().getNumber()'),
-                    }),
-                    equals({
-                      'succeeded': true,
-                      'errors': isEmpty,
-                      'warnings': isEmpty,
-                      'infos': isEmpty,
-                      'compiledProcedure': contains('return formal;'),
+                      'succeeded': false,
+                      'stackTrace': isNotNull,
+                      'exception': contains('Could not load SDK component'),
                     }),
                   ]));
+
+              try {
+                var badPath = 'file:///path/does/not/exist';
+                await ExpressionCompilerWorker.createAndStart(
+                  [
+                    '--libraries-file',
+                    badPath,
+                    '--dart-sdk-summary',
+                    badPath,
+                    '--module-format',
+                    moduleFormat,
+                    soundNullSafety
+                        ? '--sound-null-safety'
+                        : '--no-sound-null-safety',
+                    if (verbose) '--verbose',
+                  ],
+                  sendPort: receivePort.sendPort,
+                );
+              } catch (e) {
+                throwsA(contains('Could not load SDK component'));
+              }
             });
           });
+
+          for (var summarySupport in [true, false]) {
+            group('${summarySupport ? "" : "no "}debugger summary support -',
+                () {
+              group('expression compiler worker', () {
+                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, soundNullSafety, moduleFormat);
+
+                  // simulate webdev
+                  config.createTestProject();
+                  var kernelGenerator = DDCKernelGenerator(config);
+                  await kernelGenerator.generate();
+
+                  inputs = [
+                    {
+                      'path': config.mainModule.fullDillPath.path,
+                      if (summarySupport)
+                        'summaryPath': config.mainModule.summaryDillPath.path,
+                      'moduleName': config.mainModule.moduleName
+                    },
+                    {
+                      'path': config.testModule.fullDillPath.path,
+                      if (summarySupport)
+                        'summaryPath': config.testModule.summaryDillPath.path,
+                      'moduleName': config.testModule.moduleName
+                    },
+                    {
+                      'path': config.testModule2.fullDillPath.path,
+                      if (summarySupport)
+                        'summaryPath': config.testModule2.summaryDillPath.path,
+                      'moduleName': config.testModule2.moduleName
+                    },
+                    {
+                      'path': config.testModule3.fullDillPath.path,
+                      if (summarySupport)
+                        'summaryPath': config.testModule3.summaryDillPath.path,
+                      'moduleName': config.testModule3.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,
+                    // We should be able to load everything from dill and not
+                    // require source parsing. Webdev and google3 integration
+                    // currently rely on that. Make the test fail on source
+                    // reading by not providing a packages file.
+                    packagesFile: null,
+                    sdkSummary: config.sdkSummaryPath,
+                    fileSystem: fileSystem,
+                    requestStream: requestController.stream,
+                    sendResponse: responseController.add,
+                    soundNullSafety: soundNullSafety,
+                    verbose: verbose,
+                  );
+                  workerDone = worker.start();
+                });
+
+                tearDown(() async {
+                  unawaited(requestController.close());
+                  await workerDone;
+                  unawaited(responseController.close());
+                });
+
+                test('can 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,
+                          'infos': isEmpty,
+                          'compiledProcedure': contains('return other;'),
+                        })
+                      ]));
+                }, skip: 'Evaluating expressions in SDK is not supported yet');
+
+                test('can 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.testModule.moduleName,
+                  });
+
+                  expect(
+                      responseController.stream,
+                      emitsInOrder([
+                        equals({
+                          'succeeded': true,
+                        }),
+                        equals({
+                          'succeeded': true,
+                          'errors': isEmpty,
+                          'warnings': isEmpty,
+                          'infos': isEmpty,
+                          'compiledProcedure': contains('return formal;'),
+                        })
+                      ]));
+                });
+
+                test('can compile expressions in main', () async {
+                  requestController.add({
+                    'command': 'UpdateDeps',
+                    'inputs': inputs,
+                  });
+
+                  requestController.add({
+                    'command': 'CompileExpression',
+                    'expression': 'count',
+                    'line': 9,
+                    '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,
+                          'infos': isEmpty,
+                          'compiledProcedure': contains('return count;'),
+                        })
+                      ]));
+                });
+
+                test('can compile expressions in main (extension method)',
+                    () async {
+                  requestController.add({
+                    'command': 'UpdateDeps',
+                    'inputs': inputs,
+                  });
+
+                  requestController.add({
+                    'command': 'CompileExpression',
+                    'expression': 'ret',
+                    'line': 19,
+                    'column': 1,
+                    'jsModules': {},
+                    'jsScope': {'ret': 'ret'},
+                    'libraryUri': config.mainModule.libraryUri,
+                    'moduleName': config.mainModule.moduleName,
+                  });
+
+                  expect(
+                      responseController.stream,
+                      emitsInOrder([
+                        equals({
+                          'succeeded': true,
+                        }),
+                        equals({
+                          'succeeded': true,
+                          'errors': isEmpty,
+                          'warnings': isEmpty,
+                          'infos': isEmpty,
+                          'compiledProcedure': contains('return ret;'),
+                        })
+                      ]));
+                });
+
+                test('can compile transitive expressions in main', () async {
+                  requestController.add({
+                    'command': 'UpdateDeps',
+                    'inputs': inputs,
+                  });
+
+                  requestController.add({
+                    'command': 'CompileExpression',
+                    'expression': 'B().c().getNumber()',
+                    'line': 9,
+                    'column': 1,
+                    'jsModules': {},
+                    'jsScope': {},
+                    'libraryUri': config.mainModule.libraryUri,
+                    'moduleName': config.mainModule.moduleName,
+                  });
+
+                  expect(
+                      responseController.stream,
+                      emitsInOrder([
+                        equals({
+                          'succeeded': true,
+                        }),
+                        equals({
+                          'succeeded': true,
+                          'errors': isEmpty,
+                          'warnings': isEmpty,
+                          'infos': isEmpty,
+                          'compiledProcedure': contains(
+                              'new test_library.B.new().c().getNumber()'),
+                        })
+                      ]));
+                });
+
+                test('can compile series of expressions in various libraries',
+                    () async {
+                  requestController.add({
+                    'command': 'UpdateDeps',
+                    'inputs': inputs,
+                  });
+
+                  requestController.add({
+                    'command': 'CompileExpression',
+                    'expression': 'B().c().getNumber()',
+                    'line': 8,
+                    'column': 1,
+                    'jsModules': {},
+                    'jsScope': {},
+                    'libraryUri': config.mainModule.libraryUri,
+                    'moduleName': config.mainModule.moduleName,
+                  });
+
+                  requestController.add({
+                    'command': 'CompileExpression',
+                    'expression': 'formal',
+                    'line': 5,
+                    'column': 1,
+                    'jsModules': {},
+                    'jsScope': {'formal': 'formal'},
+                    'libraryUri': config.testModule.libraryUri,
+                    'moduleName': config.testModule.moduleName,
+                  });
+
+                  requestController.add({
+                    'command': 'CompileExpression',
+                    'expression': 'formal',
+                    'line': 3,
+                    'column': 1,
+                    'jsModules': {},
+                    'jsScope': {'formal': 'formal'},
+                    'libraryUri': config.testModule2.libraryUri,
+                    'moduleName': config.testModule2.moduleName,
+                  });
+
+                  requestController.add({
+                    'command': 'CompileExpression',
+                    'expression': 'formal',
+                    'line': 3,
+                    'column': 1,
+                    'jsModules': {},
+                    'jsScope': {'formal': 'formal'},
+                    'libraryUri': config.testModule3.libraryUri,
+                    'moduleName': config.testModule3.moduleName,
+                  });
+
+                  requestController.add({
+                    'command': 'CompileExpression',
+                    'expression': 'B().printNumber()',
+                    'line': 9,
+                    'column': 1,
+                    'jsModules': {},
+                    'jsScope': {},
+                    'libraryUri': config.mainModule.libraryUri,
+                    'moduleName': config.mainModule.moduleName,
+                  });
+
+                  expect(
+                      responseController.stream,
+                      emitsInOrder([
+                        equals({
+                          'succeeded': true,
+                        }),
+                        equals({
+                          'succeeded': true,
+                          'errors': isEmpty,
+                          'warnings': isEmpty,
+                          'infos': isEmpty,
+                          'compiledProcedure': contains(
+                              'new test_library.B.new().c().getNumber()'),
+                        }),
+                        equals({
+                          'succeeded': true,
+                          'errors': isEmpty,
+                          'warnings': isEmpty,
+                          'infos': isEmpty,
+                          'compiledProcedure': contains('return formal;'),
+                        }),
+                        equals({
+                          'succeeded': true,
+                          'errors': isEmpty,
+                          'warnings': isEmpty,
+                          'infos': isEmpty,
+                          'compiledProcedure': contains('return formal;'),
+                        }),
+                        equals({
+                          'succeeded': true,
+                          'errors': isEmpty,
+                          'warnings': isEmpty,
+                          'infos': isEmpty,
+                          'compiledProcedure': contains('return formal;'),
+                        }),
+                        equals({
+                          'succeeded': true,
+                          'errors': isEmpty,
+                          'warnings': isEmpty,
+                          'infos': isEmpty,
+                          'compiledProcedure':
+                              contains('test_library.B.new().printNumber()'),
+                        })
+                      ]));
+                });
+
+                test('can compile after dependency update', () async {
+                  requestController.add({
+                    'command': 'UpdateDeps',
+                    'inputs': inputs,
+                  });
+
+                  requestController.add({
+                    'command': 'CompileExpression',
+                    'expression': 'B().c().getNumber()',
+                    'line': 8,
+                    'column': 1,
+                    'jsModules': {},
+                    'jsScope': {},
+                    'libraryUri': config.mainModule.libraryUri,
+                    'moduleName': config.mainModule.moduleName,
+                  });
+
+                  requestController.add({
+                    'command': 'CompileExpression',
+                    'expression': 'formal',
+                    'line': 5,
+                    'column': 1,
+                    'jsModules': {},
+                    'jsScope': {'formal': 'formal'},
+                    'libraryUri': config.testModule.libraryUri,
+                    'moduleName': config.testModule.moduleName,
+                  });
+
+                  requestController.add({
+                    'command': 'CompileExpression',
+                    'expression': 'B().printNumber()',
+                    'line': 9,
+                    'column': 1,
+                    'jsModules': {},
+                    'jsScope': {},
+                    'libraryUri': config.mainModule.libraryUri,
+                    'moduleName': config.mainModule.moduleName,
+                  });
+
+                  requestController.add({
+                    'command': 'UpdateDeps',
+                    'inputs': inputs,
+                  });
+
+                  requestController.add({
+                    'command': 'CompileExpression',
+                    'expression': 'B().c().getNumber()',
+                    'line': 8,
+                    'column': 1,
+                    'jsModules': {},
+                    'jsScope': {},
+                    'libraryUri': config.mainModule.libraryUri,
+                    'moduleName': config.mainModule.moduleName,
+                  });
+
+                  requestController.add({
+                    'command': 'CompileExpression',
+                    'expression': 'formal',
+                    'line': 3,
+                    'column': 1,
+                    'jsModules': {},
+                    'jsScope': {'formal': 'formal'},
+                    'libraryUri': config.testModule3.libraryUri,
+                    'moduleName': config.testModule3.moduleName,
+                  });
+
+                  expect(
+                      responseController.stream,
+                      emitsInOrder([
+                        equals({
+                          'succeeded': true,
+                        }),
+                        equals({
+                          'succeeded': true,
+                          'errors': isEmpty,
+                          'warnings': isEmpty,
+                          'infos': isEmpty,
+                          'compiledProcedure': contains(
+                              'new test_library.B.new().c().getNumber()'),
+                        }),
+                        equals({
+                          'succeeded': true,
+                          'errors': isEmpty,
+                          'warnings': isEmpty,
+                          'infos': isEmpty,
+                          'compiledProcedure': contains('return formal;'),
+                        }),
+                        equals({
+                          'succeeded': true,
+                          'errors': isEmpty,
+                          'warnings': isEmpty,
+                          'infos': isEmpty,
+                          'compiledProcedure':
+                              contains('test_library.B.new().printNumber()'),
+                        }),
+                        equals({
+                          'succeeded': true,
+                        }),
+                        equals({
+                          'succeeded': true,
+                          'errors': isEmpty,
+                          'warnings': isEmpty,
+                          'infos': isEmpty,
+                          'compiledProcedure': contains(
+                              'new test_library.B.new().c().getNumber()'),
+                        }),
+                        equals({
+                          'succeeded': true,
+                          'errors': isEmpty,
+                          'warnings': isEmpty,
+                          'infos': isEmpty,
+                          'compiledProcedure': contains('return formal;'),
+                        }),
+                      ]));
+                });
+              });
+            });
+          }
         });
       }
     });
@@ -708,7 +760,7 @@
     var dartdevc =
         p.join(p.dirname(dart), 'snapshots', 'dartdevc.dart.snapshot');
 
-    Directory.fromUri(config.outputPath)..createSync();
+    Directory.fromUri(config.outputPath).createSync();
 
     // generate test_library3.full.dill
     var args = [
@@ -727,7 +779,10 @@
       'org-dartlang-app',
       '--packages',
       config.packagesPath.path,
-      config.soundNullSafety ? '--sound-null-safety' : '--no-sound-null-safety'
+      if (config.soundNullSafety) '--sound-null-safety',
+      if (!config.soundNullSafety) '--no-sound-null-safety',
+      '--modules',
+      '${config.moduleFormat}',
     ];
 
     var exitCode = await runProcess(dart, args, config.rootPath);
@@ -753,6 +808,9 @@
       '--packages',
       config.packagesPath.path,
       if (config.soundNullSafety) '--sound-null-safety',
+      if (!config.soundNullSafety) '--no-sound-null-safety',
+      '--modules',
+      '${config.moduleFormat}',
     ];
 
     exitCode = await runProcess(dart, args, config.rootPath);
@@ -780,6 +838,9 @@
       '--packages',
       config.packagesPath.path,
       if (config.soundNullSafety) '--sound-null-safety',
+      if (!config.soundNullSafety) '--no-sound-null-safety',
+      '--modules',
+      '${config.moduleFormat}',
     ];
 
     exitCode = await runProcess(dart, args, config.rootPath);
@@ -809,6 +870,9 @@
       '--packages',
       config.packagesPath.toFilePath(),
       if (config.soundNullSafety) '--sound-null-safety',
+      if (!config.soundNullSafety) '--no-sound-null-safety',
+      '--modules',
+      '${config.moduleFormat}',
     ];
 
     return await runProcess(dart, args, config.rootPath);
diff --git a/pkg/dev_compiler/test/expression_compiler/scope_offset_test.dart b/pkg/dev_compiler/test/expression_compiler/scope_offset_test.dart
index 413ae5e..933dce6 100644
--- a/pkg/dev_compiler/test/expression_compiler/scope_offset_test.dart
+++ b/pkg/dev_compiler/test/expression_compiler/scope_offset_test.dart
@@ -81,7 +81,7 @@
                 member.isForwardingStub ||
                 member.stubKind == ProcedureStubKind.ConcreteMixinStub
             : (member is Field)
-                ? member.name.name.contains(redirectingName)
+                ? member.name.text.contains(redirectingName)
                 : false;
 
     if (!noBreakPointPossible) {
diff --git a/pkg/dev_compiler/test/modular_suite.dart b/pkg/dev_compiler/test/modular_suite.dart
index 79181e5..c93b5cb 100644
--- a/pkg/dev_compiler/test/modular_suite.dart
+++ b/pkg/dev_compiler/test/modular_suite.dart
@@ -48,7 +48,7 @@
 String _packageConfigEntry(String name, Uri root,
     {Uri packageRoot, LanguageVersion version}) {
   var fields = [
-    '"name": "${name}"',
+    '"name": "$name"',
     '"rootUri": "$root"',
     if (packageRoot != null) '"packageUri": "$packageRoot"',
     if (version != null) '"languageVersion": "$version"'
diff --git a/pkg/dev_compiler/test/modular_suite_nnbd.dart b/pkg/dev_compiler/test/modular_suite_nnbd.dart
index aaf92a3..29bd656 100644
--- a/pkg/dev_compiler/test/modular_suite_nnbd.dart
+++ b/pkg/dev_compiler/test/modular_suite_nnbd.dart
@@ -48,7 +48,7 @@
 String _packageConfigEntry(String name, Uri root,
     {Uri packageRoot, LanguageVersion version}) {
   var fields = [
-    '"name": "${name}"',
+    '"name": "$name"',
     '"rootUri": "$root"',
     if (packageRoot != null) '"packageUri": "$packageRoot"',
     if (version != null) '"languageVersion": "$version"'
diff --git a/pkg/dev_compiler/test/sourcemap/stacktrace_testfiles/throw_in_try_catch.dart b/pkg/dev_compiler/test/sourcemap/stacktrace_testfiles/throw_in_try_catch.dart
index 3c2bd99..359b523 100644
--- a/pkg/dev_compiler/test/sourcemap/stacktrace_testfiles/throw_in_try_catch.dart
+++ b/pkg/dev_compiler/test/sourcemap/stacktrace_testfiles/throw_in_try_catch.dart
@@ -13,6 +13,6 @@
     /*2:test*/ throw '>ExceptionMarker<';
     // ignore: UNUSED_CATCH_CLAUSE
   } on Error catch (e) {
-    // ignore: EMPTY_CATCHES
+    // Ignored.
   }
 }
diff --git a/pkg/expect/lib/expect.dart b/pkg/expect/lib/expect.dart
index 47ada71..e6cf6e5 100644
--- a/pkg/expect/lib/expect.dart
+++ b/pkg/expect/lib/expect.dart
@@ -451,6 +451,17 @@
     }
   }
 
+  /// Checks that [haystack] contains one of the given substrings [needles].
+  ///
+  /// For example, this succeeds:
+  ///
+  ///     Expect.containsOneOf(["a", "h"], "abcdefg");
+  static void containsOneOf(Iterable<String> needles, String haystack) {
+    if (!needles.any((s) => haystack.contains(s))) {
+      _fail("None of the strings '$needles' found within '$haystack'");
+    }
+  }
+
   /// Checks that [actual] contains a given list of [substrings] in order.
   ///
   /// For example, this succeeds:
diff --git a/pkg/front_end/lib/src/api_prototype/compiler_options.dart b/pkg/front_end/lib/src/api_prototype/compiler_options.dart
index 99c4fc7..a9154dd 100644
--- a/pkg/front_end/lib/src/api_prototype/compiler_options.dart
+++ b/pkg/front_end/lib/src/api_prototype/compiler_options.dart
@@ -31,7 +31,8 @@
     show
         getExperimentEnabledVersionInLibrary,
         isExperimentEnabled,
-        isExperimentEnabledInLibrary;
+        isExperimentEnabledInLibrary,
+        isExperimentEnabledInLibraryByVersion;
 
 import 'file_system.dart' show FileSystem;
 
@@ -299,6 +300,17 @@
             experimentReleasedVersionForTesting);
   }
 
+  bool isExperimentEnabledInLibraryByVersion(
+      ExperimentalFlag flag, Uri importUri, Version version) {
+    return flags.isExperimentEnabledInLibraryByVersion(flag, importUri, version,
+        explicitExperimentalFlags: explicitExperimentalFlags,
+        defaultExperimentFlagsForTesting: defaultExperimentFlagsForTesting,
+        allowedExperimentalFlags: allowedExperimentalFlagsForTesting,
+        experimentEnabledVersionForTesting: experimentEnabledVersionForTesting,
+        experimentReleasedVersionForTesting:
+            experimentReleasedVersionForTesting);
+  }
+
   bool equivalent(CompilerOptions other,
       {bool ignoreOnDiagnostic: true,
       bool ignoreVerbose: true,
diff --git a/pkg/front_end/lib/src/api_prototype/experimental_flags.dart b/pkg/front_end/lib/src/api_prototype/experimental_flags.dart
index 088b517..bd9a076 100644
--- a/pkg/front_end/lib/src/api_prototype/experimental_flags.dart
+++ b/pkg/front_end/lib/src/api_prototype/experimental_flags.dart
@@ -182,3 +182,71 @@
   assert(version != null, "No version for enabling $flag in $canonicalUri.");
   return version;
 }
+
+bool isExperimentEnabledInLibraryByVersion(
+    ExperimentalFlag flag, Uri canonicalUri, Version version,
+    {Map<ExperimentalFlag, bool> defaultExperimentFlagsForTesting,
+    Map<ExperimentalFlag, bool> explicitExperimentalFlags,
+    AllowedExperimentalFlags allowedExperimentalFlags,
+    Map<ExperimentalFlag, Version> experimentEnabledVersionForTesting,
+    Map<ExperimentalFlag, Version> experimentReleasedVersionForTesting}) {
+  assert(defaultExperimentalFlags.containsKey(flag),
+      "No default value for $flag.");
+  assert(expiredExperimentalFlags.containsKey(flag),
+      "No expired value for $flag.");
+  if (expiredExperimentalFlags[flag]) {
+    return defaultExperimentalFlags[flag];
+  }
+
+  bool enabledByDefault;
+  if (defaultExperimentFlagsForTesting != null) {
+    enabledByDefault = defaultExperimentFlagsForTesting[flag];
+  }
+  enabledByDefault ??= defaultExperimentalFlags[flag];
+
+  bool enabledExplicitly = explicitExperimentalFlags[flag] ?? false;
+
+  allowedExperimentalFlags ??= defaultAllowedExperimentalFlags;
+
+  Set<ExperimentalFlag> allowedFlags;
+  bool enabledByAllowed = false;
+  if (canonicalUri.scheme == 'dart') {
+    allowedFlags = allowedExperimentalFlags.forSdkLibrary(canonicalUri.path);
+  } else if (canonicalUri.scheme == 'package') {
+    int index = canonicalUri.path.indexOf('/');
+    String packageName;
+    if (index >= 0) {
+      packageName = canonicalUri.path.substring(0, index);
+    } else {
+      packageName = canonicalUri.path;
+    }
+    allowedFlags = allowedExperimentalFlags.forPackage(packageName);
+  }
+  if (allowedFlags != null) {
+    enabledByAllowed = allowedFlags.contains(flag);
+  }
+
+  if (enabledByDefault || enabledExplicitly || enabledByAllowed) {
+    // The feature is enabled depending on the library language version.
+    Version enabledVersion;
+    if (!enabledByDefault || enabledExplicitly || enabledByAllowed) {
+      // If the feature is not enabled by default or is enabled by the allowed
+      // list, use the experiment release version.
+      if (experimentReleasedVersionForTesting != null) {
+        enabledVersion = experimentReleasedVersionForTesting[flag];
+      }
+      enabledVersion ??= experimentReleasedVersion[flag];
+    } else {
+      // If the feature is enabled by default and is not enabled by the allowed
+      // list use the enabled version.
+      if (experimentEnabledVersionForTesting != null) {
+        enabledVersion = experimentEnabledVersionForTesting[flag];
+      }
+      enabledVersion ??= experimentEnabledVersion[flag];
+    }
+    return version >= enabledVersion;
+  } else {
+    // The feature is not enabled, regardless of library language version.
+    return false;
+  }
+}
diff --git a/pkg/front_end/lib/src/api_prototype/experimental_flags_generated.dart b/pkg/front_end/lib/src/api_prototype/experimental_flags_generated.dart
index e7d11dc..f774c07 100644
--- a/pkg/front_end/lib/src/api_prototype/experimental_flags_generated.dart
+++ b/pkg/front_end/lib/src/api_prototype/experimental_flags_generated.dart
@@ -87,7 +87,7 @@
   ExperimentalFlag.extensionTypes: false,
   ExperimentalFlag.genericMetadata: false,
   ExperimentalFlag.nonNullable: true,
-  ExperimentalFlag.nonfunctionTypeAliases: false,
+  ExperimentalFlag.nonfunctionTypeAliases: true,
   ExperimentalFlag.setLiterals: true,
   ExperimentalFlag.spreadCollections: true,
   ExperimentalFlag.tripleShift: false,
diff --git a/pkg/front_end/lib/src/api_prototype/language_version.dart b/pkg/front_end/lib/src/api_prototype/language_version.dart
index 84b27fd..bc5d353 100644
--- a/pkg/front_end/lib/src/api_prototype/language_version.dart
+++ b/pkg/front_end/lib/src/api_prototype/language_version.dart
@@ -147,9 +147,10 @@
   if (SourceLibraryBuilder.isOptOutTest(uri)) return true;
   VersionAndPackageUri versionAndLibraryUri =
       await languageVersionForUri(uri, options);
-  return (versionAndLibraryUri.version <
-      options.getExperimentEnabledVersionInLibrary(
-          ExperimentalFlag.nonNullable, versionAndLibraryUri.packageUri));
+  return !options.isExperimentEnabledInLibraryByVersion(
+      ExperimentalFlag.nonNullable,
+      versionAndLibraryUri.packageUri,
+      versionAndLibraryUri.version);
 }
 
 class VersionAndPackageUri {
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 d4ef9bf..4d44607 100644
--- a/pkg/front_end/lib/src/api_unstable/bazel_worker.dart
+++ b/pkg/front_end/lib/src/api_unstable/bazel_worker.dart
@@ -16,9 +16,6 @@
 
 import 'package:kernel/target/targets.dart' show Target;
 
-import '../api_prototype/compiler_options.dart'
-    show CompilerOptions, parseExperimentalFlags;
-
 import '../api_prototype/experimental_flags.dart' show ExperimentalFlag;
 
 import '../api_prototype/file_system.dart' show FileSystem;
diff --git a/pkg/front_end/lib/src/api_unstable/vm.dart b/pkg/front_end/lib/src/api_unstable/vm.dart
index 5fe07cd..bf01283 100644
--- a/pkg/front_end/lib/src/api_unstable/vm.dart
+++ b/pkg/front_end/lib/src/api_unstable/vm.dart
@@ -52,6 +52,7 @@
         LocatedMessage,
         messageFfiExceptionalReturnNull,
         messageFfiExpectedConstant,
+        messageFfiPackedAnnotationAlignment,
         noLength,
         templateFfiDartTypeMismatch,
         templateFfiEmptyStruct,
@@ -64,7 +65,10 @@
         templateFfiFieldNoAnnotation,
         templateFfiFieldNull,
         templateFfiNotStatic,
+        templateFfiPackedAnnotation,
+        templateFfiPackedNestingNonPacked,
         templateFfiSizeAnnotation,
+        templateFfiSizeAnnotationDimensions,
         templateFfiStructGeneric,
         templateFfiTypeInvalid,
         templateFfiTypeMismatch;
diff --git a/pkg/front_end/lib/src/base/processed_options.dart b/pkg/front_end/lib/src/base/processed_options.dart
index 1ea8dc4..04951b8 100644
--- a/pkg/front_end/lib/src/base/processed_options.dart
+++ b/pkg/front_end/lib/src/base/processed_options.dart
@@ -401,6 +401,11 @@
     return _raw.getExperimentEnabledVersionInLibrary(flag, importUri);
   }
 
+  bool isExperimentEnabledInLibraryByVersion(
+      flags.ExperimentalFlag flag, Uri importUri, Version version) {
+    return _raw.isExperimentEnabledInLibraryByVersion(flag, importUri, version);
+  }
+
   Component _validateNullSafetyMode(Component component) {
     if (component.mode == NonNullableByDefaultCompiledMode.Invalid) {
       throw new FormatException(
diff --git a/pkg/front_end/lib/src/fasta/builder/class_builder.dart b/pkg/front_end/lib/src/fasta/builder/class_builder.dart
index c4c4e5c..8d2d698 100644
--- a/pkg/front_end/lib/src/fasta/builder/class_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/class_builder.dart
@@ -361,7 +361,14 @@
     }
 
     MetadataBuilder.buildAnnotations(
-        isPatch ? origin.cls : cls, metadata, library, this, null);
+        isPatch ? origin.cls : cls, metadata, library, this, null, fileUri);
+    if (typeVariables != null) {
+      for (int i = 0; i < typeVariables.length; i++) {
+        typeVariables[i].buildOutlineExpressions(
+            library, this, null, coreTypes, delayedActionPerformers);
+      }
+    }
+
     constructors.forEach(build);
     scope.forEach(build);
   }
@@ -675,7 +682,10 @@
       TypeAliasBuilder aliasBuilder; // Non-null if a type alias is use.
       if (decl is TypeAliasBuilder) {
         aliasBuilder = decl;
-        decl = aliasBuilder.unaliasDeclaration(superClassType.arguments);
+        decl = aliasBuilder.unaliasDeclaration(superClassType.arguments,
+            isUsedAsClass: true,
+            usedAsClassCharOffset: supertypeBuilder.charOffset,
+            usedAsClassFileUri: superClassType.fileUri);
       }
       // TODO(eernst): Should gather 'restricted supertype' checks in one place,
       // e.g., dynamic/int/String/Null and more are checked elsewhere.
@@ -701,7 +711,10 @@
         TypeAliasBuilder aliasBuilder; // Non-null if a type alias is used.
         if (typeDeclaration is TypeAliasBuilder) {
           aliasBuilder = typeDeclaration;
-          decl = aliasBuilder.unaliasDeclaration(type.arguments);
+          decl = aliasBuilder.unaliasDeclaration(type.arguments,
+              isUsedAsClass: true,
+              usedAsClassCharOffset: type.charOffset,
+              usedAsClassFileUri: type.fileUri);
         } else {
           decl = typeDeclaration;
         }
@@ -1142,7 +1155,10 @@
           if (builder is ClassBuilder) return builder;
           if (builder is TypeAliasBuilder) {
             TypeDeclarationBuilder declarationBuilder =
-                builder.unaliasDeclaration(supertype.arguments);
+                builder.unaliasDeclaration(supertype.arguments,
+                    isUsedAsClass: true,
+                    usedAsClassCharOffset: supertype.charOffset,
+                    usedAsClassFileUri: supertype.fileUri);
             if (declarationBuilder is ClassBuilder) return declarationBuilder;
           }
         }
diff --git a/pkg/front_end/lib/src/fasta/builder/extension_builder.dart b/pkg/front_end/lib/src/fasta/builder/extension_builder.dart
index b953844..d7978bd 100644
--- a/pkg/front_end/lib/src/fasta/builder/extension_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/extension_builder.dart
@@ -9,7 +9,6 @@
 
 import '../fasta_codes.dart'
     show templateInternalProblemNotFoundIn, templateTypeArgumentMismatch;
-import '../kernel/internal_ast.dart';
 import '../scope.dart';
 import '../source/source_library_builder.dart';
 import '../problems.dart';
@@ -206,20 +205,4 @@
 
   @override
   String get debugName => "ExtensionBuilder";
-
-  @override
-  void buildOutlineExpressions(LibraryBuilder library, CoreTypes coreTypes,
-      List<DelayedActionPerformer> delayedActionPerformers) {
-    void build(String ignore, Builder declaration) {
-      MemberBuilder member = declaration;
-      member.buildOutlineExpressions(
-          library, coreTypes, delayedActionPerformers);
-    }
-
-    // TODO(johnniwinther): Handle annotations on the extension declaration.
-    //MetadataBuilder.buildAnnotations(
-    //    isPatch ? origin.extension : extension,
-    //    metadata, library, this, null);
-    scope.forEach(build);
-  }
 }
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 1e93f43..fd05495 100644
--- a/pkg/front_end/lib/src/fasta/builder/field_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/field_builder.dart
@@ -389,7 +389,7 @@
     ClassBuilder classBuilder = isClassMember ? parent : null;
     for (Annotatable annotatable in _fieldEncoding.annotatables) {
       MetadataBuilder.buildAnnotations(
-          annotatable, metadata, library, classBuilder, this);
+          annotatable, metadata, library, classBuilder, this, fileUri);
     }
 
     // For modular compilation we need to include initializers of all const
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 8477784..15880c6 100644
--- a/pkg/front_end/lib/src/fasta/builder/function_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/function_builder.dart
@@ -41,6 +41,7 @@
 
 import 'builder.dart';
 import 'class_builder.dart';
+import 'declaration_builder.dart';
 import 'extension_builder.dart';
 import 'formal_parameter_builder.dart';
 import 'library_builder.dart';
@@ -506,8 +507,20 @@
   void buildOutlineExpressions(LibraryBuilder library, CoreTypes coreTypes,
       List<DelayedActionPerformer> delayedActionPerformers) {
     if (!_hasBuiltOutlineExpressions) {
+      DeclarationBuilder classOrExtensionBuilder =
+          isClassMember || isExtensionMember ? parent : null;
       MetadataBuilder.buildAnnotations(
-          member, metadata, library, isClassMember ? parent : null, this);
+          member, metadata, library, classOrExtensionBuilder, this, fileUri);
+      if (typeVariables != null) {
+        for (int i = 0; i < typeVariables.length; i++) {
+          typeVariables[i].buildOutlineExpressions(
+              library,
+              classOrExtensionBuilder,
+              this,
+              coreTypes,
+              delayedActionPerformers);
+        }
+      }
 
       if (formals != null) {
         // For const constructors we need to include default parameter values
diff --git a/pkg/front_end/lib/src/fasta/builder/library_builder.dart b/pkg/front_end/lib/src/fasta/builder/library_builder.dart
index f318572..74355bf 100644
--- a/pkg/front_end/lib/src/fasta/builder/library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/library_builder.dart
@@ -8,7 +8,7 @@
 
 import 'package:_fe_analyzer_shared/src/messages/severity.dart' show Severity;
 
-import 'package:kernel/ast.dart' show Library, Nullability, Version;
+import 'package:kernel/ast.dart' show Library, Nullability;
 
 import '../combinator.dart' show Combinator;
 
@@ -55,23 +55,6 @@
 
   bool mayImplementRestrictedTypes;
 
-  /// Set the language version to a specific non-null [version].
-  ///
-  /// If the language version has previously been explicitly set set (i.e. with
-  /// [explicit] set to true), any subsequent call (explicit or not) should be
-  /// ignored.
-  /// Multiple calls with [explicit] set to false should be allowed though.
-  ///
-  /// The main idea is that the .packages file specifies a default language
-  /// version, but that the library can have source code that specifies another
-  /// one which should be supported, but specifying several in code should not
-  /// change anything.
-  ///
-  /// [offset] and [length] refers to the offset and length of the source code
-  /// specifying the language version.
-  void setLanguageVersion(Version version,
-      {int offset: 0, int length, bool explicit});
-
   bool get isPart;
 
   Loader get loader;
@@ -224,27 +207,6 @@
   @override
   bool get isSynthetic => false;
 
-  /// Set the language version to a specific non-null major and minor version.
-  ///
-  /// If [version] is null (and no other version has been explicitly set) a
-  /// problem is issued.
-  ///
-  /// If the language version has previously been explicitly set set (i.e. with
-  /// [explicit] set to true), any subsequent call (explicit or not) should be
-  /// ignored.
-  /// Multiple calls with [explicit] set to false should be allowed though.
-  ///
-  /// The main idea is that the .packages file specifies a default language
-  /// version, but that the library can have source code that specifies another
-  /// one which should be supported, but specifying several in code should not
-  /// change anything.
-  ///
-  /// [offset] and [length] refers to the offset and length of the source code
-  /// specifying the language version.
-  @override
-  void setLanguageVersion(Version version,
-      {int offset: 0, int length, bool explicit});
-
   @override
   Builder get parent => null;
 
diff --git a/pkg/front_end/lib/src/fasta/builder/metadata_builder.dart b/pkg/front_end/lib/src/fasta/builder/metadata_builder.dart
index 910119c..00998c8 100644
--- a/pkg/front_end/lib/src/fasta/builder/metadata_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/metadata_builder.dart
@@ -8,7 +8,7 @@
 
 import 'package:_fe_analyzer_shared/src/scanner/scanner.dart' show Token;
 
-import 'package:kernel/ast.dart' show Annotatable, Class, Library;
+import 'package:kernel/ast.dart';
 
 import '../kernel/body_builder.dart' show BodyBuilder;
 
@@ -16,7 +16,7 @@
 
 import '../scope.dart' show Scope;
 
-import 'class_builder.dart';
+import 'declaration_builder.dart';
 import 'member_builder.dart';
 
 class MetadataBuilder {
@@ -30,16 +30,19 @@
       Annotatable parent,
       List<MetadataBuilder> metadata,
       SourceLibraryBuilder library,
-      ClassBuilder classBuilder,
-      MemberBuilder member) {
+      DeclarationBuilder classOrExtensionBuilder,
+      MemberBuilder member,
+      Uri fileUri) {
     if (metadata == null) return;
-    Uri fileUri = member?.fileUri ?? classBuilder?.fileUri ?? library.fileUri;
-    Scope scope = parent is Library || parent is Class || classBuilder == null
+    Scope scope = parent is Library ||
+            parent is Class ||
+            parent is Extension ||
+            classOrExtensionBuilder == null
         ? library.scope
-        : classBuilder.scope;
+        : classOrExtensionBuilder.scope;
     BodyBuilder bodyBuilder = library.loader
         .createBodyBuilderForOutlineExpression(
-            library, classBuilder, member, scope, fileUri);
+            library, classOrExtensionBuilder, member, scope, fileUri);
     for (int i = 0; i < metadata.length; ++i) {
       MetadataBuilder annotationBuilder = metadata[i];
       parent.addAnnotation(
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 c0e9971..31a334d 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
@@ -6,8 +6,6 @@
 
 library fasta.named_type_builder;
 
-import 'package:_fe_analyzer_shared/src/messages/severity.dart' show Severity;
-
 import 'package:kernel/ast.dart';
 
 import '../fasta_codes.dart'
@@ -23,6 +21,8 @@
         templateExtendingRestricted,
         templateNotAType,
         templateSupertypeIsIllegal,
+        templateSupertypeIsIllegalAliased,
+        templateSupertypeIsNullableAliased,
         templateSupertypeIsTypeVariable,
         templateTypeArgumentMismatch,
         templateTypeArgumentsOnTypeVariable,
@@ -30,9 +30,6 @@
 
 import '../identifiers.dart' show Identifier, QualifiedName, flattenName;
 
-import '../messages.dart'
-    show noLength, templateSupertypeIsIllegal, templateSupertypeIsTypeVariable;
-
 import '../problems.dart' show unhandled;
 
 import '../scope.dart';
@@ -182,7 +179,7 @@
   String get debugName => "NamedTypeBuilder";
 
   StringBuffer printOn(StringBuffer buffer) {
-    buffer.write(name);
+    buffer.write(flattenName(name, charOffset, fileUri));
     if (arguments?.isEmpty ?? true) return buffer;
     buffer.write("<");
     bool first = true;
@@ -206,29 +203,39 @@
         context: context);
   }
 
-  Supertype handleInvalidSupertype(LibraryBuilder library, int charOffset,
-      Uri fileUri, TypeAliasBuilder aliasBuilder) {
+  Supertype handleInvalidSupertype(
+      LibraryBuilder library, int charOffset, Uri fileUri) {
     Template<Message Function(String name)> template =
         declaration.isTypeVariable
             ? templateSupertypeIsTypeVariable
             : templateSupertypeIsIllegal;
-    if (aliasBuilder != null) {
-      library.addProblem(
-          template.withArguments(flattenName(name, charOffset, fileUri)),
-          charOffset,
-          noLength,
-          fileUri,
-          context: [
-            messageTypedefCause.withLocation(
-                aliasBuilder.fileUri, aliasBuilder.charOffset, noLength),
-          ]);
-    } else {
-      library.addProblem(
-          template.withArguments(flattenName(name, charOffset, fileUri)),
-          charOffset,
-          noLength,
-          fileUri);
-    }
+    library.addProblem(template.withArguments(fullNameForErrors), charOffset,
+        noLength, fileUri);
+    return null;
+  }
+
+  Supertype handleInvalidAliasedSupertype(
+      LibraryBuilder library,
+      int charOffset,
+      Uri fileUri,
+      TypeAliasBuilder aliasBuilder,
+      DartType type) {
+    Template<Message Function(String name, DartType type, bool)> template =
+        declaration.isTypeVariable
+            ? templateSupertypeIsTypeVariable
+            : (type != null && type.nullability == Nullability.nullable
+                ? templateSupertypeIsNullableAliased
+                : templateSupertypeIsIllegalAliased);
+    library.addProblem(
+        template.withArguments(
+            fullNameForErrors, type, library.isNonNullableByDefault),
+        charOffset,
+        noLength,
+        fileUri,
+        context: [
+          messageTypedefCause.withLocation(
+              aliasBuilder.fileUri, aliasBuilder.charOffset, noLength),
+        ]);
     return null;
   }
 
@@ -249,14 +256,28 @@
       }
     }
 
-    return declaration.buildType(
-        library, nullabilityBuilder, arguments, notInstanceContext);
+    if (library is SourceLibraryBuilder) {
+      int uncheckedTypedefTypeCount = library.uncheckedTypedefTypes.length;
+      DartType builtType = declaration.buildType(
+          library, nullabilityBuilder, arguments, notInstanceContext);
+      // Set locations for new unchecked TypedefTypes for error reporting.
+      for (int i = uncheckedTypedefTypeCount;
+          i < library.uncheckedTypedefTypes.length;
+          ++i) {
+        library.uncheckedTypedefTypes[i]
+          ..fileUri ??= fileUri
+          ..offset ??= charOffset;
+      }
+      return builtType;
+    } else {
+      return declaration.buildType(
+          library, nullabilityBuilder, arguments, notInstanceContext);
+    }
   }
 
   Supertype buildSupertype(
       LibraryBuilder library, int charOffset, Uri fileUri) {
     TypeDeclarationBuilder declaration = this.declaration;
-    TypeAliasBuilder aliasBuilder; // Non-null if a type alias is used.
     if (declaration is ClassBuilder) {
       if (declaration.isNullClass && !library.mayImplementRestrictedTypes) {
         library.addProblem(
@@ -267,10 +288,10 @@
       }
       return declaration.buildSupertype(library, arguments);
     } else if (declaration is TypeAliasBuilder) {
-      aliasBuilder = declaration;
+      TypeAliasBuilder aliasBuilder = declaration;
       DartType type =
           declaration.buildType(library, library.nonNullableBuilder, arguments);
-      if (type is InterfaceType) {
+      if (type is InterfaceType && type.nullability != Nullability.nullable) {
         return new Supertype(type.classNode, type.typeArguments);
       } else if (type is NullType) {
         // Even though Null is disallowed as a supertype, ClassHierarchyBuilder
@@ -314,9 +335,9 @@
             unaliasedDeclaration.name == "FutureOr");
         return new Supertype((unaliasedDeclaration as ClassBuilder).cls,
             <DartType>[type.typeArgument]);
-      } else {
-        // Do nothing: handleInvalidSuper below will handle the erroneous case.
       }
+      return handleInvalidAliasedSupertype(
+          library, charOffset, fileUri, aliasBuilder, type);
     } else if (declaration is InvalidTypeDeclarationBuilder) {
       library.addProblem(
           declaration.message.messageObject,
@@ -326,22 +347,23 @@
           severity: Severity.error);
       return null;
     }
-    return handleInvalidSupertype(library, charOffset, fileUri, aliasBuilder);
+    return handleInvalidSupertype(library, charOffset, fileUri);
   }
 
   Supertype buildMixedInType(
       LibraryBuilder library, int charOffset, Uri fileUri) {
     TypeDeclarationBuilder declaration = this.declaration;
-    TypeAliasBuilder aliasBuilder; // Non-null if a type alias is used.
     if (declaration is ClassBuilder) {
       return declaration.buildMixedInType(library, arguments);
     } else if (declaration is TypeAliasBuilder) {
-      aliasBuilder = declaration;
+      TypeAliasBuilder aliasBuilder = declaration;
       DartType type =
           declaration.buildType(library, library.nonNullableBuilder, arguments);
-      if (type is InterfaceType) {
+      if (type is InterfaceType && type.nullability != Nullability.nullable) {
         return new Supertype(type.classNode, type.typeArguments);
       }
+      return handleInvalidAliasedSupertype(
+          library, charOffset, fileUri, aliasBuilder, type);
     } else if (declaration is InvalidTypeDeclarationBuilder) {
       library.addProblem(
           declaration.message.messageObject,
@@ -351,7 +373,7 @@
           severity: Severity.error);
       return null;
     }
-    return handleInvalidSupertype(library, charOffset, fileUri, aliasBuilder);
+    return handleInvalidSupertype(library, charOffset, fileUri);
   }
 
   TypeBuilder subst(Map<TypeVariableBuilder, TypeBuilder> substitution) {
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 ae2dc15..ecc024e 100644
--- a/pkg/front_end/lib/src/fasta/builder/procedure_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/procedure_builder.dart
@@ -8,8 +8,6 @@
 import 'package:front_end/src/fasta/kernel/kernel_api.dart';
 import 'package:kernel/ast.dart';
 
-import 'package:kernel/type_algebra.dart';
-
 import '../kernel/class_hierarchy_builder.dart';
 import '../kernel/forest.dart';
 import '../kernel/internal_ast.dart';
diff --git a/pkg/front_end/lib/src/fasta/builder/type_alias_builder.dart b/pkg/front_end/lib/src/fasta/builder/type_alias_builder.dart
index 2f94d08..871917c 100644
--- a/pkg/front_end/lib/src/fasta/builder/type_alias_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/type_alias_builder.dart
@@ -6,14 +6,8 @@
 
 library fasta.function_type_alias_builder;
 
-import 'package:kernel/ast.dart'
-    show
-        DartType,
-        DynamicType,
-        InvalidType,
-        Nullability,
-        TypeParameter,
-        Typedef;
+import 'package:kernel/ast.dart';
+import 'package:kernel/core_types.dart';
 
 import 'package:kernel/type_algebra.dart' show substitute, uniteNullabilities;
 import 'package:kernel/src/legacy_erasure.dart';
@@ -27,6 +21,8 @@
         messageTypedefTypeVariableNotConstructorCause;
 
 import '../problems.dart' show unhandled;
+import '../source/source_library_builder.dart';
+import '../util/helpers.dart';
 
 import 'class_builder.dart';
 import 'library_builder.dart';
@@ -79,14 +75,14 @@
   /// based on the given [typeArguments]. It expands type aliases repeatedly
   /// until it encounters a builder which is not a [TypeAliasBuilder].
   ///
-  /// If [isInvocation] is false: In this case it is required that
+  /// If [isUsedAsClass] is false: In this case it is required that
   /// `typeArguments.length == typeVariables.length`. The [typeArguments] are
   /// threaded through the expansion if needed, and the resulting declaration
   /// is returned.
   ///
-  /// If [isInvocation] is true: In this case [typeArguments] are ignored, but
-  /// [invocationCharOffset] and [invocationFileUri] must be non-null. If `this`
-  /// type alias expands in one or more steps to a builder which is not a
+  /// If [isUsedAsClass] is true: In this case [typeArguments] are ignored, but
+  /// [usedAsClassCharOffset] and [usedAsClassFileUri] must be non-null. If
+  /// `this` type alias expands in one or more steps to a builder which is not a
   /// [TypeAliasBuilder] nor a [TypeVariableBuilder] then that builder is
   /// returned. If this type alias is cyclic or expands to an invalid type or
   /// a type that does not have a declaration (say, a function type) then `this`
@@ -95,9 +91,9 @@
   /// [TypeVariableBuilder] then the type alias cannot be used in a constructor
   /// invocation. Then an error is emitted and `this` is returned.
   TypeDeclarationBuilder unaliasDeclaration(List<TypeBuilder> typeArguments,
-      {bool isInvocation = false,
-      int invocationCharOffset,
-      Uri invocationFileUri});
+      {bool isUsedAsClass = false,
+      int usedAsClassCharOffset,
+      Uri usedAsClassFileUri});
 
   /// Compute type arguments passed to [ClassBuilder] from unaliasDeclaration.
   /// This method does not check for cycles and may only be called if an
@@ -114,6 +110,9 @@
   /// arguments for passing to the [ClassBuilder] which is the end of the
   /// unaliasing chain.
   List<TypeBuilder> unaliasTypeArguments(List<TypeBuilder> typeArguments);
+
+  void buildOutlineExpressions(LibraryBuilder library, CoreTypes coreTypes,
+      List<DelayedActionPerformer> delayedActionPerformers);
 }
 
 abstract class TypeAliasBuilderImpl extends TypeDeclarationBuilderImpl
@@ -141,6 +140,17 @@
     for (int i = 0; i < typedef.typeParameters.length; i++) {
       substitution[typedef.typeParameters[i]] = arguments[i];
     }
+    // The following adds the built type to the list of unchecked typedef types
+    // of the client library. It is needed because the type is built unaliased,
+    // and at the time of the check it wouldn't be possible to see if the type
+    // arguments to the generic typedef conform to the bounds without preserving
+    // the TypedefType for the delayed check.
+    if (library is SourceLibraryBuilder &&
+        arguments.isNotEmpty &&
+        thisType is! FunctionType) {
+      library.uncheckedTypedefTypes.add(new UncheckedTypedefType(
+          new TypedefType(typedef, nullability, arguments)));
+    }
     return substitute(result, substitution);
   }
 
@@ -186,25 +196,32 @@
   /// based on the given [typeArguments]. It expands type aliases repeatedly
   /// until it encounters a builder which is not a [TypeAliasBuilder].
   ///
-  /// If [isInvocation] is false: In this case it is required that
+  /// The parameter [isUsedAsClass] indicates whether the type alias is being
+  /// used as a class, e.g., as the class in an instance creation, as a
+  /// superinterface, in a redirecting factory constructor, or to invoke a
+  /// static member.
+  ///
+  /// If [isUsedAsClass] is false: In this case it is required that
   /// `typeArguments.length == typeVariables.length`. The [typeArguments] are
   /// threaded through the expansion if needed, and the resulting declaration
   /// is returned.
   ///
-  /// If [isInvocation] is true: In this case [typeArguments] are ignored, but
-  /// [invocationCharOffset] and [invocationFileUri] must be non-null. If `this`
+  /// If [isUsedAsClass] is true: In this case [typeArguments] can be null, but
+  /// [usedAsClassCharOffset] and [usedAsClassFileUri] must be non-null. When
+  /// [typeArguments] is null, the returned [TypeDeclarationBuilder] indicates
+  /// which class the type alias denotes, without type arguments. If `this`
   /// type alias expands in one or more steps to a builder which is not a
   /// [TypeAliasBuilder] nor a [TypeVariableBuilder] then that builder is
   /// returned. If this type alias is cyclic or expands to an invalid type or
   /// a type that does not have a declaration (say, a function type) then `this`
   /// is returned (when the type was invalid: with `thisType` set to
   /// `const InvalidType()`). If `this` type alias expands to a
-  /// [TypeVariableBuilder] then the type alias cannot be used in a constructor
-  /// invocation. Then an error is emitted and `this` is returned.
+  /// [TypeVariableBuilder] then the type alias cannot be used as a class, in
+  /// which case an error is emitted and `this` is returned.
   TypeDeclarationBuilder unaliasDeclaration(List<TypeBuilder> typeArguments,
-      {bool isInvocation = false,
-      int invocationCharOffset,
-      Uri invocationFileUri}) {
+      {bool isUsedAsClass = false,
+      int usedAsClassCharOffset,
+      Uri usedAsClassFileUri}) {
     if (_cachedUnaliasedDeclaration != null) return _cachedUnaliasedDeclaration;
     Set<TypeDeclarationBuilder> builders = {this};
     TypeDeclarationBuilder current = this;
@@ -236,15 +253,39 @@
         // `_cachedUnaliasedDeclaration` because it changes from call to call
         // with type aliases of this kind. Note that every `aliasBuilder.type`
         // up to this point is a [NamedTypeBuilder], because only they can have
-        // a non-null `type`. However, a constructor invocation is not admitted.
-        if (isInvocation) {
-          library.addProblem(messageTypedefTypeVariableNotConstructor,
-              invocationCharOffset, noLength, invocationFileUri,
-              context: [
-                messageTypedefTypeVariableNotConstructorCause.withLocation(
-                    current.fileUri, current.charOffset, noLength),
-              ]);
-          return this;
+        // a non-null `type`. However, this type alias can not be used as a
+        // class.
+        if (isUsedAsClass) {
+          List<TypeBuilder> freshTypeArguments = [
+            if (typeVariables != null)
+              for (TypeVariableBuilder typeVariable in typeVariables)
+                new NamedTypeBuilder.fromTypeDeclarationBuilder(
+                  typeVariable,
+                  library.nonNullableBuilder,
+                  const [],
+                  fileUri,
+                  charOffset,
+                ),
+          ];
+          TypeDeclarationBuilder typeDeclarationBuilder =
+              _unaliasDeclaration(freshTypeArguments);
+          bool found = false;
+          for (TypeBuilder typeBuilder in freshTypeArguments) {
+            if (typeBuilder.declaration == typeDeclarationBuilder) {
+              found = true;
+              break;
+            }
+          }
+          if (found) {
+            library.addProblem(messageTypedefTypeVariableNotConstructor,
+                usedAsClassCharOffset, noLength, usedAsClassFileUri,
+                context: [
+                  messageTypedefTypeVariableNotConstructorCause.withLocation(
+                      current.fileUri, current.charOffset, noLength),
+                ]);
+            return this;
+          }
+          if (typeArguments == null) return typeDeclarationBuilder;
         }
         return _unaliasDeclaration(typeArguments);
       }
diff --git a/pkg/front_end/lib/src/fasta/builder/type_variable_builder.dart b/pkg/front_end/lib/src/fasta/builder/type_variable_builder.dart
index d8d4a27..ba03221 100644
--- a/pkg/front_end/lib/src/fasta/builder/type_variable_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/type_variable_builder.dart
@@ -8,17 +8,21 @@
 
 import 'package:kernel/ast.dart'
     show DartType, Nullability, TypeParameter, TypeParameterType;
+import 'package:kernel/core_types.dart';
 
 import '../fasta_codes.dart'
     show
-        templateCycleInTypeVariables,
         templateInternalProblemUnfinishedTypeVariable,
         templateTypeArgumentsOnTypeVariable;
 
-import '../source/source_library_builder.dart' show SourceLibraryBuilder;
+import '../source/source_library_builder.dart';
+import '../util/helpers.dart';
 
 import 'class_builder.dart';
+import 'declaration_builder.dart';
 import 'library_builder.dart';
+import 'member_builder.dart';
+import 'metadata_builder.dart';
 import 'named_type_builder.dart';
 import 'nullability_builder.dart';
 import 'type_builder.dart';
@@ -35,13 +39,16 @@
 
   final bool isExtensionTypeParameter;
 
-  TypeVariableBuilder(
-      String name, SourceLibraryBuilder compilationUnit, int charOffset,
-      {this.bound, this.isExtensionTypeParameter: false, int variableVariance})
+  TypeVariableBuilder(String name, SourceLibraryBuilder compilationUnit,
+      int charOffset, Uri fileUri,
+      {this.bound,
+      this.isExtensionTypeParameter: false,
+      int variableVariance,
+      List<MetadataBuilder> metadata})
       : actualParameter = new TypeParameter(name, null)
           ..fileOffset = charOffset
           ..variance = variableVariance,
-        super(null, 0, name, compilationUnit, charOffset);
+        super(metadata, 0, name, compilationUnit, charOffset, fileUri);
 
   TypeVariableBuilder.fromKernel(
       TypeParameter parameter, LibraryBuilder compilationUnit)
@@ -108,12 +115,12 @@
     DartType type = buildTypesWithBuiltArguments(library, nullability, null);
     if (needsPostUpdate) {
       if (library is SourceLibraryBuilder) {
-        library.pendingNullabilities.add(type);
+        library.registerPendingNullability(fileUri, charOffset, type);
       } else {
         library.addProblem(
             templateInternalProblemUnfinishedTypeVariable.withArguments(
                 name, library?.importUri),
-            parameter.fileOffset,
+            charOffset,
             name.length,
             fileUri);
       }
@@ -158,74 +165,6 @@
             : dynamicType.build(library));
   }
 
-  /// Assigns nullabilities to types in [pendingNullabilities].
-  ///
-  /// It's a helper function to assign the nullabilities to type-parameter types
-  /// after the corresponding type parameters have their bounds set or changed.
-  /// The function takes into account that some of the types in the input list
-  /// may be bounds to some of the type parameters of other types from the input
-  /// list.
-  static void finishNullabilities(LibraryBuilder libraryBuilder,
-      List<TypeParameterType> pendingNullabilities) {
-    // The bounds of type parameters may be type-parameter types of other
-    // parameters from the same declaration.  In this case we need to set the
-    // nullability for them first.  To preserve the ordering, we implement a
-    // depth-first search over the types.  We use the fact that a nullability
-    // of a type parameter type can't ever be 'nullable' if computed from the
-    // bound. It allows us to use 'nullable' nullability as the marker in the
-    // DFS implementation.
-    Nullability marker = Nullability.nullable;
-    List<TypeParameterType> stack =
-        new List<TypeParameterType>.filled(pendingNullabilities.length, null);
-    int stackTop = 0;
-    for (TypeParameterType type in pendingNullabilities) {
-      type.declaredNullability = null;
-    }
-    for (TypeParameterType type in pendingNullabilities) {
-      if (type.declaredNullability != null) {
-        // Nullability for [type] was already computed on one of the branches
-        // of the depth-first search.  Continue to the next one.
-        continue;
-      }
-      if (type.parameter.bound is TypeParameterType) {
-        TypeParameterType current = type;
-        TypeParameterType next = current.parameter.bound;
-        while (next != null && next.declaredNullability == null) {
-          stack[stackTop++] = current;
-          current.declaredNullability = marker;
-
-          current = next;
-          if (current.parameter.bound is TypeParameterType) {
-            next = current.parameter.bound;
-            if (next.declaredNullability == marker) {
-              next.declaredNullability = Nullability.undetermined;
-              libraryBuilder.addProblem(
-                  templateCycleInTypeVariables.withArguments(
-                      next.parameter.name, current.parameter.name),
-                  next.parameter.fileOffset,
-                  next.parameter.name.length,
-                  next.parameter.location.file);
-              next = null;
-            }
-          } else {
-            next = null;
-          }
-        }
-        current.declaredNullability =
-            TypeParameterType.computeNullabilityFromBound(current.parameter);
-        while (stackTop != 0) {
-          --stackTop;
-          current = stack[stackTop];
-          current.declaredNullability =
-              TypeParameterType.computeNullabilityFromBound(current.parameter);
-        }
-      } else {
-        type.declaredNullability =
-            TypeParameterType.computeNullabilityFromBound(type.parameter);
-      }
-    }
-  }
-
   void applyPatch(covariant TypeVariableBuilder patch) {
     patch.actualOrigin = this;
   }
@@ -234,10 +173,20 @@
     // TODO(dmitryas): Figure out if using [charOffset] here is a good idea.
     // An alternative is to use the offset of the node the cloned type variable
     // is declared on.
-    return new TypeVariableBuilder(name, parent, charOffset,
+    return new TypeVariableBuilder(name, parent, charOffset, fileUri,
         bound: bound.clone(newTypes), variableVariance: variance);
   }
 
+  void buildOutlineExpressions(
+      LibraryBuilder libraryBuilder,
+      DeclarationBuilder classOrExtensionBuilder,
+      MemberBuilder memberBuilder,
+      CoreTypes coreTypes,
+      List<DelayedActionPerformer> delayedActionPerformers) {
+    MetadataBuilder.buildAnnotations(parameter, metadata, libraryBuilder,
+        classOrExtensionBuilder, memberBuilder, fileUri);
+  }
+
   @override
   bool operator ==(Object other) {
     return other is TypeVariableBuilder && parameter == other.parameter;
diff --git a/pkg/front_end/lib/src/fasta/compiler_context.dart b/pkg/front_end/lib/src/fasta/compiler_context.dart
index 913a4e1..67cfc5a 100644
--- a/pkg/front_end/lib/src/fasta/compiler_context.dart
+++ b/pkg/front_end/lib/src/fasta/compiler_context.dart
@@ -24,9 +24,6 @@
 
 import 'command_line_reporting.dart' as command_line_reporting;
 
-import 'fasta_codes.dart'
-    show LocatedMessage, Message, messageInternalProblemMissingContext;
-
 final Object compilerContextKey = new Object();
 
 /// Shared context used throughout the compiler.
diff --git a/pkg/front_end/lib/src/fasta/dill/dill_extension_builder.dart b/pkg/front_end/lib/src/fasta/dill/dill_extension_builder.dart
index ea03898..8da14de 100644
--- a/pkg/front_end/lib/src/fasta/dill/dill_extension_builder.dart
+++ b/pkg/front_end/lib/src/fasta/dill/dill_extension_builder.dart
@@ -4,7 +4,9 @@
 
 // @dart = 2.9
 
+import 'package:front_end/src/fasta/util/helpers.dart';
 import 'package:kernel/ast.dart';
+import 'package:kernel/core_types.dart';
 
 import '../builder/extension_builder.dart';
 import '../builder/library_builder.dart';
@@ -105,4 +107,10 @@
     }
     return _onType;
   }
+
+  @override
+  void buildOutlineExpressions(LibraryBuilder library, CoreTypes coreTypes,
+      List<DelayedActionPerformer> delayedActionPerformers) {
+    // TODO(johnniwinther): Remove the need for this.
+  }
 }
diff --git a/pkg/front_end/lib/src/fasta/dill/dill_library_builder.dart b/pkg/front_end/lib/src/fasta/dill/dill_library_builder.dart
index c3813c3..27e97e4 100644
--- a/pkg/front_end/lib/src/fasta/dill/dill_library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/dill/dill_library_builder.dart
@@ -28,8 +28,7 @@
         StaticGet,
         StringConstant,
         StringLiteral,
-        Typedef,
-        Version;
+        Typedef;
 
 import '../builder/builder.dart';
 import '../builder/class_builder.dart';
@@ -140,10 +139,6 @@
   bool get isNonNullableByDefault => library.isNonNullableByDefault;
 
   @override
-  void setLanguageVersion(Version version,
-      {int offset: 0, int length, bool explicit}) {}
-
-  @override
   Uri get importUri => library.importUri;
 
   @override
diff --git a/pkg/front_end/lib/src/fasta/dill/dill_target.dart b/pkg/front_end/lib/src/fasta/dill/dill_target.dart
index 9901f81..002f35d 100644
--- a/pkg/front_end/lib/src/fasta/dill/dill_target.dart
+++ b/pkg/front_end/lib/src/fasta/dill/dill_target.dart
@@ -17,6 +17,8 @@
 
 import '../problems.dart' show unsupported;
 
+import '../source/source_library_builder.dart' show LanguageVersion;
+
 import '../target_implementation.dart' show TargetImplementation;
 
 import '../ticker.dart' show Ticker;
@@ -66,6 +68,7 @@
       Uri uri,
       Uri fileUri,
       Uri packageUri,
+      LanguageVersion packageLanguageVersion,
       LibraryBuilder origin,
       Library referencesFrom,
       bool referenceIsPartOwner) {
diff --git a/pkg/front_end/lib/src/fasta/dill/dill_type_alias_builder.dart b/pkg/front_end/lib/src/fasta/dill/dill_type_alias_builder.dart
index 9020e68..6b7b54b 100644
--- a/pkg/front_end/lib/src/fasta/dill/dill_type_alias_builder.dart
+++ b/pkg/front_end/lib/src/fasta/dill/dill_type_alias_builder.dart
@@ -6,7 +6,9 @@
 
 library fasta.dill_typedef_builder;
 
+import 'package:front_end/src/fasta/util/helpers.dart';
 import 'package:kernel/ast.dart' show DartType, InvalidType, NullType, Typedef;
+import 'package:kernel/core_types.dart';
 
 import '../builder/library_builder.dart';
 import '../builder/metadata_builder.dart';
@@ -92,4 +94,10 @@
 
   @override
   bool get isNullAlias => typedef.type is NullType;
+
+  @override
+  void buildOutlineExpressions(LibraryBuilder library, CoreTypes coreTypes,
+      List<DelayedActionPerformer> delayedActionPerformers) {
+    // TODO(johnniwinther): Remove the need for this.
+  }
 }
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 127d61d..4e0e710 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
@@ -3639,7 +3639,7 @@
             Message Function(String name, String name2, DartType _type,
                 bool isNonNullableByDefault)>(
         messageTemplate:
-            r"""Type parameters could not be inferred for the mixin '#name' because '#name2' does not implement the mixin's supertype constraint '#type'.""",
+            r"""Type parameters couldn't be inferred for the mixin '#name' because '#name2' does not implement the mixin's supertype constraint '#type'.""",
         withArguments: _withArgumentsMixinInferenceNoMatchingClass);
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
@@ -3663,7 +3663,7 @@
   String type = typeParts.join();
   return new Message(codeMixinInferenceNoMatchingClass,
       message:
-          """Type parameters could not be inferred for the mixin '${name}' because '${name2}' does not implement the mixin's supertype constraint '${type}'.""" +
+          """Type parameters couldn't be inferred for the mixin '${name}' because '${name2}' does not implement the mixin's supertype constraint '${type}'.""" +
               labeler.originMessages,
       arguments: {'name': name, 'name2': name2, 'type': _type});
 }
@@ -4631,6 +4631,78 @@
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Template<
         Message Function(
+            String name, DartType _type, bool isNonNullableByDefault)>
+    templateSupertypeIsIllegalAliased = const Template<
+            Message Function(
+                String name, DartType _type, bool isNonNullableByDefault)>(
+        messageTemplate:
+            r"""The type '#name' which is an alias of '#type' can't be used as supertype.""",
+        withArguments: _withArgumentsSupertypeIsIllegalAliased);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<
+        Message Function(
+            String name, DartType _type, bool isNonNullableByDefault)>
+    codeSupertypeIsIllegalAliased = const Code<
+            Message Function(
+                String name, DartType _type, bool isNonNullableByDefault)>(
+        "SupertypeIsIllegalAliased",
+        analyzerCodes: <String>["EXTENDS_NON_CLASS"]);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsSupertypeIsIllegalAliased(
+    String name, DartType _type, bool isNonNullableByDefault) {
+  if (name.isEmpty) throw 'No name provided';
+  name = demangleMixinApplicationName(name);
+  TypeLabeler labeler = new TypeLabeler(isNonNullableByDefault);
+  List<Object> typeParts = labeler.labelType(_type);
+  String type = typeParts.join();
+  return new Message(codeSupertypeIsIllegalAliased,
+      message:
+          """The type '${name}' which is an alias of '${type}' can't be used as supertype.""" +
+              labeler.originMessages,
+      arguments: {'name': name, 'type': _type});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<
+        Message Function(
+            String name, DartType _type, bool isNonNullableByDefault)>
+    templateSupertypeIsNullableAliased = const Template<
+            Message Function(
+                String name, DartType _type, bool isNonNullableByDefault)>(
+        messageTemplate:
+            r"""The type '#name' which is an alias of '#type' can't be used as supertype because it is nullable.""",
+        withArguments: _withArgumentsSupertypeIsNullableAliased);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<
+        Message Function(
+            String name, DartType _type, bool isNonNullableByDefault)>
+    codeSupertypeIsNullableAliased = const Code<
+            Message Function(
+                String name, DartType _type, bool isNonNullableByDefault)>(
+        "SupertypeIsNullableAliased",
+        analyzerCodes: <String>["EXTENDS_NON_CLASS"]);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsSupertypeIsNullableAliased(
+    String name, DartType _type, bool isNonNullableByDefault) {
+  if (name.isEmpty) throw 'No name provided';
+  name = demangleMixinApplicationName(name);
+  TypeLabeler labeler = new TypeLabeler(isNonNullableByDefault);
+  List<Object> typeParts = labeler.labelType(_type);
+  String type = typeParts.join();
+  return new Message(codeSupertypeIsNullableAliased,
+      message:
+          """The type '${name}' which is an alias of '${type}' can't be used as supertype because it is nullable.""" +
+              labeler.originMessages,
+      arguments: {'name': name, 'type': _type});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<
+        Message Function(
             DartType _type, DartType _type2, bool isNonNullableByDefault)>
     templateSwitchExpressionNotAssignable = const Template<
             Message Function(
@@ -4732,6 +4804,43 @@
 const Template<
         Message Function(
             String name, DartType _type, bool isNonNullableByDefault)>
+    templateUndefinedExtensionGetter = const Template<
+            Message Function(
+                String name, DartType _type, bool isNonNullableByDefault)>(
+        messageTemplate:
+            r"""The getter '#name' isn't defined for the extension '#type'.""",
+        tipTemplate:
+            r"""Try correcting the name to the name of an existing getter, or defining a getter or field named '#name'.""",
+        withArguments: _withArgumentsUndefinedExtensionGetter);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<
+    Message Function(String name, DartType _type,
+        bool isNonNullableByDefault)> codeUndefinedExtensionGetter = const Code<
+    Message Function(String name, DartType _type, bool isNonNullableByDefault)>(
+  "UndefinedExtensionGetter",
+);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsUndefinedExtensionGetter(
+    String name, DartType _type, bool isNonNullableByDefault) {
+  if (name.isEmpty) throw 'No name provided';
+  name = demangleMixinApplicationName(name);
+  TypeLabeler labeler = new TypeLabeler(isNonNullableByDefault);
+  List<Object> typeParts = labeler.labelType(_type);
+  String type = typeParts.join();
+  return new Message(codeUndefinedExtensionGetter,
+      message:
+          """The getter '${name}' isn't defined for the extension '${type}'.""" +
+              labeler.originMessages,
+      tip: """Try correcting the name to the name of an existing getter, or defining a getter or field named '${name}'.""",
+      arguments: {'name': name, 'type': _type});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<
+        Message Function(
+            String name, DartType _type, bool isNonNullableByDefault)>
     templateUndefinedExtensionMethod = const Template<
             Message Function(
                 String name, DartType _type, bool isNonNullableByDefault)>(
@@ -4767,6 +4876,82 @@
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Template<
+        Message Function(
+            String name, DartType _type, bool isNonNullableByDefault)>
+    templateUndefinedExtensionOperator = const Template<
+            Message Function(
+                String name, DartType _type, bool isNonNullableByDefault)>(
+        messageTemplate:
+            r"""The operator '#name' isn't defined for the extension '#type'.""",
+        tipTemplate:
+            r"""Try correcting the operator to an existing operator, or defining a '#name' operator.""",
+        withArguments: _withArgumentsUndefinedExtensionOperator);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<
+        Message Function(
+            String name, DartType _type, bool isNonNullableByDefault)>
+    codeUndefinedExtensionOperator = const Code<
+        Message Function(
+            String name, DartType _type, bool isNonNullableByDefault)>(
+  "UndefinedExtensionOperator",
+);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsUndefinedExtensionOperator(
+    String name, DartType _type, bool isNonNullableByDefault) {
+  if (name.isEmpty) throw 'No name provided';
+  name = demangleMixinApplicationName(name);
+  TypeLabeler labeler = new TypeLabeler(isNonNullableByDefault);
+  List<Object> typeParts = labeler.labelType(_type);
+  String type = typeParts.join();
+  return new Message(codeUndefinedExtensionOperator,
+      message:
+          """The operator '${name}' isn't defined for the extension '${type}'.""" +
+              labeler.originMessages,
+      tip: """Try correcting the operator to an existing operator, or defining a '${name}' operator.""",
+      arguments: {'name': name, 'type': _type});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<
+        Message Function(
+            String name, DartType _type, bool isNonNullableByDefault)>
+    templateUndefinedExtensionSetter = const Template<
+            Message Function(
+                String name, DartType _type, bool isNonNullableByDefault)>(
+        messageTemplate:
+            r"""The setter '#name' isn't defined for the extension '#type'.""",
+        tipTemplate:
+            r"""Try correcting the name to the name of an existing setter, or defining a setter or field named '#name'.""",
+        withArguments: _withArgumentsUndefinedExtensionSetter);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<
+    Message Function(String name, DartType _type,
+        bool isNonNullableByDefault)> codeUndefinedExtensionSetter = const Code<
+    Message Function(String name, DartType _type, bool isNonNullableByDefault)>(
+  "UndefinedExtensionSetter",
+);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsUndefinedExtensionSetter(
+    String name, DartType _type, bool isNonNullableByDefault) {
+  if (name.isEmpty) throw 'No name provided';
+  name = demangleMixinApplicationName(name);
+  TypeLabeler labeler = new TypeLabeler(isNonNullableByDefault);
+  List<Object> typeParts = labeler.labelType(_type);
+  String type = typeParts.join();
+  return new Message(codeUndefinedExtensionSetter,
+      message:
+          """The setter '${name}' isn't defined for the extension '${type}'.""" +
+              labeler.originMessages,
+      tip: """Try correcting the name to the name of an existing setter, or defining a setter or field named '${name}'.""",
+      arguments: {'name': name, 'type': _type});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<
     Message Function(
         String name,
         DartType _type,
diff --git a/pkg/front_end/lib/src/fasta/incremental_compiler.dart b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
index 9965154..a25d4e1 100644
--- a/pkg/front_end/lib/src/fasta/incremental_compiler.dart
+++ b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
@@ -19,8 +19,6 @@
 import 'package:kernel/binary/ast_from_binary.dart'
     show
         BinaryBuilderWithMetadata,
-        CanonicalNameError,
-        CanonicalNameSdkError,
         CompilationModeError,
         InvalidKernelSdkVersionError,
         InvalidKernelVersionError,
@@ -52,6 +50,9 @@
         TreeNode,
         TypeParameter;
 
+import 'package:kernel/canonical_name.dart'
+    show CanonicalNameError, CanonicalNameSdkError;
+
 import 'package:kernel/kernel.dart' as kernel show Combinator;
 
 import 'package:kernel/target/changed_structure_notifier.dart'
@@ -108,14 +109,6 @@
 
 import 'util/textual_outline.dart' show textualOutline;
 
-import 'fasta_codes.dart'
-    show
-        DiagnosticMessageFromJson,
-        templateInitializeFromDillNotSelfContained,
-        templateInitializeFromDillNotSelfContainedNoDump,
-        templateInitializeFromDillUnknownProblem,
-        templateInitializeFromDillUnknownProblemNoDump;
-
 import 'hybrid_file_system.dart' show HybridFileSystem;
 
 import 'kernel/kernel_builder.dart' show ClassHierarchyBuilder;
@@ -126,9 +119,8 @@
 
 import 'library_graph.dart' show LibraryGraph;
 
-import 'messages.dart' show Message;
-
-import 'source/source_library_builder.dart' show SourceLibraryBuilder;
+import 'source/source_library_builder.dart'
+    show ImplicitLanguageVersion, SourceLibraryBuilder;
 
 import 'ticker.dart' show Ticker;
 
@@ -1892,12 +1884,12 @@
         libraryUri,
         debugExprUri,
         /*packageUri*/ null,
+        new ImplicitLanguageVersion(libraryBuilder.library.languageVersion),
         userCode.loader,
         null,
         scope: libraryBuilder.scope.createNestedScope("expression"),
         nameOrigin: libraryBuilder.library,
       );
-      debugLibrary.setLanguageVersion(libraryBuilder.library.languageVersion);
       ticker.logMs("Created debug library");
 
       if (libraryBuilder is DillLibraryBuilder) {
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 06e8346..11692c2 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -1081,6 +1081,7 @@
 
     resolveRedirectingFactoryTargets();
     finishVariableMetadata();
+    libraryBuilder.checkUncheckedTypedefTypes(typeEnvironment);
   }
 
   void checkAsyncReturnType(AsyncMarker asyncModifier, DartType returnType,
@@ -1300,11 +1301,13 @@
   void _unaliasTypeAliasedConstructorInvocations() {
     for (TypeAliasedConstructorInvocationJudgment invocation
         in typeAliasedConstructorInvocations) {
-      DartType unaliasedType = new TypedefType(
-              invocation.typeAliasBuilder.typedef,
-              Nullability.nonNullable,
-              invocation.arguments.types)
-          .unalias;
+      DartType aliasedType = new TypedefType(
+          invocation.typeAliasBuilder.typedef,
+          Nullability.nonNullable,
+          invocation.arguments.types);
+      libraryBuilder.checkBoundsInType(
+          aliasedType, typeEnvironment, uri, invocation.fileOffset);
+      DartType unaliasedType = aliasedType.unalias;
       List<DartType> invocationTypeArguments = null;
       if (unaliasedType is InterfaceType) {
         invocationTypeArguments = unaliasedType.typeArguments;
@@ -1322,11 +1325,13 @@
   void _unaliasTypeAliasedFactoryInvocations() {
     for (TypeAliasedFactoryInvocationJudgment invocation
         in typeAliasedFactoryInvocations) {
-      DartType unaliasedType = new TypedefType(
-              invocation.typeAliasBuilder.typedef,
-              Nullability.nonNullable,
-              invocation.arguments.types)
-          .unalias;
+      DartType aliasedType = new TypedefType(
+          invocation.typeAliasBuilder.typedef,
+          Nullability.nonNullable,
+          invocation.arguments.types);
+      libraryBuilder.checkBoundsInType(
+          aliasedType, typeEnvironment, uri, invocation.fileOffset);
+      DartType unaliasedType = aliasedType.unalias;
       List<DartType> invocationTypeArguments = null;
       if (unaliasedType is InterfaceType) {
         invocationTypeArguments = unaliasedType.typeArguments;
@@ -1401,7 +1406,7 @@
   }
 
   @override
-  List<Expression> finishMetadata(TreeNode parent) {
+  List<Expression> finishMetadata(Annotatable parent) {
     List<Expression> expressions = pop();
     inferAnnotations(parent, expressions);
 
@@ -1412,35 +1417,7 @@
     // used.
     ListLiteral temporaryParent;
 
-    if (parent is Class) {
-      for (Expression expression in expressions) {
-        parent.addAnnotation(expression);
-      }
-    } else if (parent is Library) {
-      for (Expression expression in expressions) {
-        parent.addAnnotation(expression);
-      }
-    } else if (parent is LibraryDependency) {
-      for (Expression expression in expressions) {
-        parent.addAnnotation(expression);
-      }
-    } else if (parent is LibraryPart) {
-      for (Expression expression in expressions) {
-        parent.addAnnotation(expression);
-      }
-    } else if (parent is Member) {
-      for (Expression expression in expressions) {
-        parent.addAnnotation(expression);
-      }
-    } else if (parent is Typedef) {
-      for (Expression expression in expressions) {
-        parent.addAnnotation(expression);
-      }
-    } else if (parent is TypeParameter) {
-      for (Expression expression in expressions) {
-        parent.addAnnotation(expression);
-      }
-    } else if (parent is VariableDeclaration) {
+    if (parent != null) {
       for (Expression expression in expressions) {
         parent.addAnnotation(expression);
       }
@@ -2220,7 +2197,8 @@
       VariableBuilder variableBuilder = declaration;
       if (constantContext != ConstantContext.none &&
           !variableBuilder.isConst &&
-          !member.isConstructor) {
+          !member.isConstructor &&
+          !enableConstFunctionsInLibrary) {
         return new IncompleteErrorGenerator(
             this, token, fasta.messageNotAConstantExpression);
       }
@@ -3470,8 +3448,12 @@
     if (typeVariables != null) {
       for (TypeVariableBuilder builder in typeVariables) {
         if (builder.parameter.annotations.isNotEmpty) {
-          addProblem(fasta.messageAnnotationOnFunctionTypeTypeVariable,
-              builder.charOffset, builder.name.length);
+          if (!libraryBuilder.enableGenericMetadataInLibrary) {
+            addProblem(fasta.messageAnnotationOnFunctionTypeTypeVariable,
+                builder.charOffset, builder.name.length);
+          }
+          // Annotations on function types are not constant evaluated and are
+          // not included in the generated AST so we clear them here.
           builder.parameter.annotations = const <Expression>[];
         }
       }
@@ -4252,7 +4234,8 @@
       {bool isTearOff}) {
     List<TypeParameter> typeParameters = target.function.typeParameters;
     LocatedMessage argMessage = checkArgumentsForFunction(
-        target.function, arguments, fileOffset, typeParameters);
+        target.function, arguments, fileOffset, typeParameters,
+        isExtensionMemberInvocation: true);
     if (argMessage != null) {
       return throwNoSuchMethodError(forest.createNullLiteral(fileOffset),
           target.name.text, arguments, fileOffset,
@@ -4271,19 +4254,32 @@
 
   @override
   LocatedMessage checkArgumentsForFunction(FunctionNode function,
-      Arguments arguments, int offset, List<TypeParameter> typeParameters) {
+      Arguments arguments, int offset, List<TypeParameter> typeParameters,
+      {bool isExtensionMemberInvocation = false}) {
+    int requiredPositionalParameterCountToReport =
+        function.requiredParameterCount;
+    int positionalParameterCountToReport = function.positionalParameters.length;
+    int positionalArgumentCountToReport =
+        forest.argumentsPositional(arguments).length;
+    if (isExtensionMemberInvocation) {
+      // Extension member invocations have additional synthetic parameter for
+      // `this`.
+      --requiredPositionalParameterCountToReport;
+      --positionalParameterCountToReport;
+      --positionalArgumentCountToReport;
+    }
     if (forest.argumentsPositional(arguments).length <
         function.requiredParameterCount) {
       return fasta.templateTooFewArguments
-          .withArguments(function.requiredParameterCount,
-              forest.argumentsPositional(arguments).length)
+          .withArguments(requiredPositionalParameterCountToReport,
+              positionalArgumentCountToReport)
           .withLocation(uri, arguments.fileOffset, noLength);
     }
     if (forest.argumentsPositional(arguments).length >
         function.positionalParameters.length) {
       return fasta.templateTooManyArguments
-          .withArguments(function.positionalParameters.length,
-              forest.argumentsPositional(arguments).length)
+          .withArguments(
+              positionalParameterCountToReport, positionalArgumentCountToReport)
           .withLocation(uri, arguments.fileOffset, noLength);
     }
     List<NamedExpression> named = forest.argumentsNamed(arguments);
@@ -4330,19 +4326,32 @@
 
   @override
   LocatedMessage checkArgumentsForType(
-      FunctionType function, Arguments arguments, int offset) {
+      FunctionType function, Arguments arguments, int offset,
+      {bool isExtensionMemberInvocation = false}) {
+    int requiredPositionalParameterCountToReport =
+        function.requiredParameterCount;
+    int positionalParameterCountToReport = function.positionalParameters.length;
+    int positionalArgumentCountToReport =
+        forest.argumentsPositional(arguments).length;
+    if (isExtensionMemberInvocation) {
+      // Extension member invocations have additional synthetic parameter for
+      // `this`.
+      --requiredPositionalParameterCountToReport;
+      --positionalParameterCountToReport;
+      --positionalArgumentCountToReport;
+    }
     if (forest.argumentsPositional(arguments).length <
         function.requiredParameterCount) {
       return fasta.templateTooFewArguments
-          .withArguments(function.requiredParameterCount,
-              forest.argumentsPositional(arguments).length)
+          .withArguments(requiredPositionalParameterCountToReport,
+              positionalArgumentCountToReport)
           .withLocation(uri, arguments.fileOffset, noLength);
     }
     if (forest.argumentsPositional(arguments).length >
         function.positionalParameters.length) {
       return fasta.templateTooManyArguments
-          .withArguments(function.positionalParameters.length,
-              forest.argumentsPositional(arguments).length)
+          .withArguments(
+              positionalParameterCountToReport, positionalArgumentCountToReport)
           .withLocation(uri, arguments.fileOffset, noLength);
     }
     List<NamedExpression> named = forest.argumentsNamed(arguments);
@@ -4495,7 +4504,8 @@
       List<UnresolvedType> typeArguments,
       int charOffset,
       Constness constness,
-      {bool isTypeArgumentsInForest = false}) {
+      {bool isTypeArgumentsInForest = false,
+      TypeDeclarationBuilder typeAliasBuilder}) {
     if (arguments == null) {
       return buildProblem(fasta.messageMissingArgumentList,
           nameToken.charOffset, nameToken.length);
@@ -4526,9 +4536,9 @@
                 noLength));
       }
       type = aliasBuilder.unaliasDeclaration(null,
-          isInvocation: true,
-          invocationCharOffset: nameToken.charOffset,
-          invocationFileUri: uri);
+          isUsedAsClass: true,
+          usedAsClassCharOffset: nameToken.charOffset,
+          usedAsClassFileUri: uri);
       List<TypeBuilder> typeArgumentBuilders = [];
       if (typeArguments != null) {
         for (UnresolvedType unresolvedType in typeArguments) {
@@ -4616,6 +4626,23 @@
           }
         }
       }
+
+      List<DartType> typeArgumentsToCheck = const <DartType>[];
+      if (typeArgumentBuilders != null && typeArgumentBuilders.isNotEmpty) {
+        typeArgumentsToCheck = new List.filled(
+            typeArgumentBuilders.length, const DynamicType(),
+            growable: false);
+        for (int i = 0; i < typeArgumentsToCheck.length; ++i) {
+          typeArgumentsToCheck[i] =
+              typeArgumentBuilders[i].build(libraryBuilder);
+        }
+      }
+      DartType typeToCheck = new TypedefType(
+          aliasBuilder.typedef, Nullability.nonNullable, typeArgumentsToCheck);
+      libraryBuilder.checkBoundsInType(
+          typeToCheck, typeEnvironment, uri, charOffset,
+          allowSuperBounded: false);
+
       if (type is ClassBuilder) {
         if (typeArguments != null) {
           int numberOfTypeParameters = aliasBuilder.typeVariables?.length ?? 0;
@@ -4705,7 +4732,8 @@
         invocation = buildStaticInvocation(target, arguments,
             constness: constness,
             charOffset: nameToken.charOffset,
-            charLength: nameToken.length);
+            charLength: nameToken.length,
+            typeAliasBuilder: typeAliasBuilder);
 
         if (invocation is StaticInvocation &&
             isRedirectingFactory(target, helper: this)) {
@@ -4741,6 +4769,15 @@
   }
 
   @override
+  void handleConstFactory(Token constKeyword) {
+    debugEvent("ConstFactory");
+    if (!libraryBuilder.enableConstFunctionsInLibrary) {
+      handleRecoverableError(
+          fasta.messageConstFactory, constKeyword, constKeyword);
+    }
+  }
+
+  @override
   void beginIfControlFlow(Token ifToken) {
     // TODO(danrubel): consider removing this when control flow support is added
     // if the ifToken is not needed for error reporting
@@ -5877,8 +5914,8 @@
     debugEvent("beginTypeVariable");
     Identifier name = pop();
     List<Expression> annotations = pop();
-    TypeVariableBuilder variable =
-        new TypeVariableBuilder(name.name, libraryBuilder, name.charOffset);
+    TypeVariableBuilder variable = new TypeVariableBuilder(
+        name.name, libraryBuilder, name.charOffset, uri);
     if (annotations != null) {
       inferAnnotations(variable.parameter, annotations);
       for (Expression annotation in annotations) {
@@ -5922,11 +5959,17 @@
     // Peek to leave type parameters on top of stack.
     List<TypeVariableBuilder> typeVariables = peek();
 
+    List<TypeBuilder> unboundTypes = [];
+    List<TypeVariableBuilder> unboundTypeVariables = [];
     List<TypeBuilder> calculatedBounds = calculateBounds(
         typeVariables,
         libraryBuilder.loader.target.dynamicType,
         libraryBuilder.loader.target.nullType,
-        libraryBuilder.loader.target.objectClassBuilder);
+        libraryBuilder.loader.target.objectClassBuilder,
+        unboundTypes: unboundTypes,
+        unboundTypeVariables: unboundTypeVariables);
+    assert(unboundTypes.isEmpty,
+        "Found a type not bound to a declaration in BodyBuilder.");
     for (int i = 0; i < typeVariables.length; ++i) {
       typeVariables[i].defaultType = calculatedBounds[i];
       typeVariables[i].defaultType.resolveIn(scope, typeVariables[i].charOffset,
@@ -5936,9 +5979,13 @@
           libraryBuilder.loader.target.objectClassBuilder,
           libraryBuilder.loader.target.dynamicType);
     }
-    TypeVariableBuilder.finishNullabilities(
-        libraryBuilder, libraryBuilder.pendingNullabilities);
-    libraryBuilder.pendingNullabilities.clear();
+    for (int i = 0; i < unboundTypeVariables.length; ++i) {
+      unboundTypeVariables[i].finish(
+          libraryBuilder,
+          libraryBuilder.loader.target.objectClassBuilder,
+          libraryBuilder.loader.target.dynamicType);
+    }
+    libraryBuilder.processPendingNullabilities();
   }
 
   @override
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 25e0a70..38ee51c 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
@@ -1374,7 +1374,10 @@
       if (mixin is TypeAliasBuilder) {
         TypeAliasBuilder aliasBuilder = mixin;
         NamedTypeBuilder namedBuilder = mixedInTypeBuilder;
-        mixin = aliasBuilder.unaliasDeclaration(namedBuilder.arguments);
+        mixin = aliasBuilder.unaliasDeclaration(namedBuilder.arguments,
+            isUsedAsClass: true,
+            usedAsClassCharOffset: namedBuilder.charOffset,
+            usedAsClassFileUri: namedBuilder.fileUri);
       }
       if (mixin is ClassBuilder) {
         scope = mixin.scope.computeMixinScope();
diff --git a/pkg/front_end/lib/src/fasta/kernel/collections.dart b/pkg/front_end/lib/src/fasta/kernel/collections.dart
index 9b23f9f..e2fb85b 100644
--- a/pkg/front_end/lib/src/fasta/kernel/collections.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/collections.dart
@@ -12,14 +12,6 @@
 
 import 'package:kernel/type_environment.dart' show StaticTypeContext;
 
-import 'package:kernel/visitor.dart'
-    show
-        ExpressionVisitor,
-        ExpressionVisitor1,
-        Transformer,
-        TreeVisitor,
-        Visitor;
-
 import '../messages.dart'
     show noLength, templateExpectedAfterButGot, templateExpectedButGot;
 
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 a759519..5178dfa 100644
--- a/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
@@ -383,6 +383,7 @@
     transformLibraryPartList(library.parts, library);
     transformTypedefList(library.typedefs, library);
     transformClassList(library.classes, library);
+    transformExtensionList(library.extensions, library);
     transformProcedureList(library.procedures, library);
     transformFieldList(library.fields, library);
 
@@ -432,6 +433,19 @@
   }
 
   @override
+  Extension visitExtension(Extension node, TreeNode removalSentinel) {
+    StaticTypeContext oldStaticTypeContext = _staticTypeContext;
+    _staticTypeContext = new StaticTypeContext.forAnnotations(
+        node.enclosingLibrary, typeEnvironment);
+    constantEvaluator.withNewEnvironment(() {
+      transformAnnotations(node.annotations, node);
+      transformTypeParameterList(node.typeParameters, node);
+    });
+    _staticTypeContext = oldStaticTypeContext;
+    return node;
+  }
+
+  @override
   Procedure visitProcedure(Procedure node, TreeNode removalSentinel) {
     StaticTypeContext oldStaticTypeContext = _staticTypeContext;
     _staticTypeContext = new StaticTypeContext(node, typeEnvironment);
@@ -537,6 +551,21 @@
   }
 
   @override
+  Statement visitFunctionDeclaration(
+      FunctionDeclaration node, TreeNode removalSentinel) {
+    if (enableConstFunctions) {
+      if (node.function != null) {
+        node.function = transform(node.function)..parent = node;
+      }
+      constantEvaluator.env.addVariableValue(
+          node.variable, new IntermediateValue(node.function));
+    } else {
+      return super.visitFunctionDeclaration(node, removalSentinel);
+    }
+    return node;
+  }
+
+  @override
   Statement visitVariableDeclaration(
       VariableDeclaration node, TreeNode removalSentinel) {
     transformAnnotations(node.annotations, node);
@@ -544,7 +573,7 @@
     if (node.initializer != null) {
       if (node.isConst) {
         final Constant constant = evaluateWithContext(node, node.initializer);
-        constantEvaluator.env.updateVariableValue(node, constant);
+        constantEvaluator.env.addVariableValue(node, constant);
         node.initializer = makeConstantExpression(constant, node.initializer)
           ..parent = node;
 
@@ -609,11 +638,9 @@
     Expression left = transform(node.left);
     Expression right = transform(node.right);
     if (_isNull(left)) {
-      return new EqualsNull(right, isNot: node.isNot)
-        ..fileOffset = node.fileOffset;
+      return new EqualsNull(right)..fileOffset = node.fileOffset;
     } else if (_isNull(right)) {
-      return new EqualsNull(left, isNot: node.isNot)
-        ..fileOffset = node.fileOffset;
+      return new EqualsNull(left)..fileOffset = node.fileOffset;
     }
     node.left = left..parent = node;
     node.right = right..parent = node;
@@ -811,7 +838,7 @@
   }
 }
 
-class ConstantEvaluator extends ExpressionVisitor<Constant> {
+class ConstantEvaluator implements ExpressionVisitor<Constant> {
   final ConstantsBackend backend;
   final NumberSemantics numberSemantics;
   ConstantIntFolder intFolder;
@@ -993,7 +1020,14 @@
   Constant execute(Statement statement) {
     StatementConstantEvaluator statementEvaluator =
         new StatementConstantEvaluator(this);
-    return statement.accept(statementEvaluator);
+    ExecutionStatus status = statement.accept(statementEvaluator);
+    if (status is ReturnStatus) {
+      return status.value;
+    } else if (status is AbortStatus) {
+      return status.error;
+    }
+    return createInvalidExpressionConstant(statement,
+        'No valid constant returned from the execution of $statement.');
   }
 
   /// Create an error-constant indicating that an error has been detected during
@@ -1135,7 +1169,10 @@
     } else {
       bool sentinelInserted = false;
       if (nodeCache.containsKey(node)) {
-        if (nodeCache[node] == null) {
+        bool isRecursiveFunctionCall =
+            node is MethodInvocation || node is StaticInvocation;
+        if (nodeCache[node] == null &&
+            !(enableConstFunctions && isRecursiveFunctionCall)) {
           // recursive call
           return createErrorConstant(node, messageConstEvalCircularity);
         }
@@ -1651,14 +1688,14 @@
             // TODO(johnniwinther): This should call [_evaluateSubexpression].
             : _evaluateNullableSubexpression(parameter.initializer);
         if (value is AbortConstant) return value;
-        env.updateVariableValue(parameter, value);
+        env.addVariableValue(parameter, value);
       }
       for (final VariableDeclaration parameter in function.namedParameters) {
         final Constant value = namedArguments[parameter.name] ??
             // TODO(johnniwinther): This should call [_evaluateSubexpression].
             _evaluateNullableSubexpression(parameter.initializer);
         if (value is AbortConstant) return value;
-        env.updateVariableValue(parameter, value);
+        env.addVariableValue(parameter, value);
       }
 
       // Step 2) Run all initializers (including super calls) with environment
@@ -1679,7 +1716,7 @@
           final VariableDeclaration variable = init.variable;
           Constant constant = _evaluateSubexpression(variable.initializer);
           if (constant is AbortConstant) return constant;
-          env.updateVariableValue(variable, constant);
+          env.addVariableValue(variable, constant);
         } else if (init is SuperInitializer) {
           AbortConstant error = checkConstructorConst(init, constructor);
           if (error != null) return error;
@@ -1931,13 +1968,12 @@
       return unevaluated(
           node,
           new EqualsCall(extract(left), extract(right),
-              isNot: node.isNot,
               functionType: node.functionType,
               interfaceTarget: node.interfaceTarget)
             ..fileOffset = node.fileOffset);
     }
 
-    return _handleEquals(node, left, right, isNot: node.isNot);
+    return _handleEquals(node, left, right);
   }
 
   @override
@@ -1946,18 +1982,14 @@
     if (expression is AbortConstant) return expression;
 
     if (shouldBeUnevaluated) {
-      return unevaluated(
-          node,
-          new EqualsNull(extract(expression), isNot: node.isNot)
-            ..fileOffset = node.fileOffset);
+      return unevaluated(node,
+          new EqualsNull(extract(expression))..fileOffset = node.fileOffset);
     }
 
-    return _handleEquals(node, expression, nullConstant, isNot: node.isNot);
+    return _handleEquals(node, expression, nullConstant);
   }
 
-  Constant _handleEquals(Expression node, Constant left, Constant right,
-      {bool isNot}) {
-    assert(isNot != null);
+  Constant _handleEquals(Expression node, Constant left, Constant right) {
     if (left is NullConstant ||
         left is BoolConstant ||
         left is IntConstant ||
@@ -1966,17 +1998,7 @@
         right is NullConstant) {
       // [DoubleConstant] uses [identical] to determine equality, so we need
       // to take the special cases into account.
-      Constant result =
-          doubleSpecialCases(left, right) ?? makeBoolConstant(left == right);
-      if (isNot) {
-        if (result == trueConstant) {
-          result = falseConstant;
-        } else {
-          assert(result == falseConstant);
-          result = trueConstant;
-        }
-      }
-      return result;
+      return doubleSpecialCases(left, right) ?? makeBoolConstant(left == right);
     } else {
       return createErrorConstant(
           node,
@@ -1993,7 +2015,7 @@
     // parsed as `!(a == b)` it is handled implicitly through ==.
     if (arguments.length == 1 && op == '==') {
       final Constant right = arguments[0];
-      return _handleEquals(node, receiver, right, isNot: false);
+      return _handleEquals(node, receiver, right);
     }
 
     // This is a white-listed set of methods we need to support on constants.
@@ -2113,19 +2135,17 @@
   @override
   Constant visitMethodInvocation(MethodInvocation node) {
     // We have no support for generic method invocation at the moment.
-    if (node.arguments.types.isNotEmpty) {
+    if (node.arguments.types.isNotEmpty && !enableConstFunctions) {
       return createInvalidExpressionConstant(node, "generic method invocation");
     }
 
     // We have no support for method invocation with named arguments at the
     // moment.
-    if (node.arguments.named.isNotEmpty) {
+    if (node.arguments.named.isNotEmpty && !enableConstFunctions) {
       return createInvalidExpressionConstant(
           node, "method invocation with named arguments");
     }
 
-    final Constant receiver = _evaluateSubexpression(node.receiver);
-    if (receiver is AbortConstant) return receiver;
     final List<Constant> arguments =
         _evaluatePositionalArguments(node.arguments);
 
@@ -2137,6 +2157,36 @@
     assert(_gotError == null);
     assert(arguments != null);
 
+    final Constant receiver = _evaluateSubexpression(node.receiver);
+    if (receiver is AbortConstant) {
+      return receiver;
+    } else if (enableConstFunctions &&
+        receiver is IntermediateValue &&
+        receiver.value is FunctionNode) {
+      // Evaluate type arguments of the method invoked.
+      List<DartType> types = _evaluateTypeArguments(node, node.arguments);
+      if (types == null && _gotError != null) {
+        AbortConstant error = _gotError;
+        _gotError = null;
+        return error;
+      }
+      assert(_gotError == null);
+      assert(types != null);
+
+      // Evaluate named arguments of the method invoked.
+      final Map<String, Constant> named =
+          _evaluateNamedArguments(node.arguments);
+      if (named == null && _gotError != null) {
+        AbortConstant error = _gotError;
+        _gotError = null;
+        return error;
+      }
+      assert(_gotError == null);
+      assert(named != null);
+
+      return _handleFunctionInvocation(receiver.value, types, arguments, named);
+    }
+
     if (shouldBeUnevaluated) {
       return unevaluated(
           node,
@@ -2381,7 +2431,7 @@
   Constant visitLet(Let node) {
     Constant value = _evaluateSubexpression(node.variable.initializer);
     if (value is AbortConstant) return value;
-    env.updateVariableValue(node.variable, value);
+    env.addVariableValue(node.variable, value);
     return _evaluateSubexpression(node.body);
   }
 
@@ -2394,20 +2444,39 @@
     // TODO(kustermann): The heuristic of allowing all [VariableGet]s on [Let]
     // variables might allow more than it should.
     final VariableDeclaration variable = node.variable;
-    if (variable.parent is Let || _isFormalParameter(variable)) {
-      return env.lookupVariable(node.variable) ??
-          createErrorConstant(
-              node,
-              templateConstEvalNonConstantVariableGet
-                  .withArguments(variable.name));
-    }
-    if (variable.isConst) {
-      return _evaluateSubexpression(variable.initializer);
+    if (enableConstFunctions) {
+      return env.lookupVariable(variable) ??
+          createInvalidExpressionConstant(
+              node, 'Variable get of an unknown value.');
+    } else {
+      if (variable.parent is Let || _isFormalParameter(variable)) {
+        return env.lookupVariable(node.variable) ??
+            createErrorConstant(
+                node,
+                templateConstEvalNonConstantVariableGet
+                    .withArguments(variable.name));
+      }
+      if (variable.isConst) {
+        return _evaluateSubexpression(variable.initializer);
+      }
     }
     return createInvalidExpressionConstant(
         node, 'Variable get of a non-const variable.');
   }
 
+  @override
+  Constant visitVariableSet(VariableSet node) {
+    if (enableConstFunctions) {
+      final VariableDeclaration variable = node.variable;
+      Constant value = _evaluateSubexpression(node.value);
+      if (value is AbortConstant) return value;
+      return env.updateVariableValue(variable, value) ??
+          createInvalidExpressionConstant(
+              node, 'Variable set of an unknown value.');
+    }
+    return defaultExpression(node);
+  }
+
   /// Computes the constant for [expression] defined in the context of [member].
   ///
   /// This compute the constant as seen in the current evaluation mode even when
@@ -2466,7 +2535,7 @@
         return createErrorConstant(
             node,
             templateConstEvalInvalidStaticInvocation
-                .withArguments(target.name.name));
+                .withArguments(target.name.text));
       } else {
         return createInvalidExpressionConstant(
             node, 'No support for ${target.runtimeType} in a static tear-off.');
@@ -2703,7 +2772,8 @@
     } else if (target.isExtensionMember) {
       return createErrorConstant(node, messageConstEvalExtension);
     } else if (enableConstFunctions && target.kind == ProcedureKind.Method) {
-      return _handleStaticInvocation(node, typeArguments, positionals, named);
+      return _handleFunctionInvocation(
+          node.target.function, typeArguments, positionals, named);
     }
 
     String name = target.name.text;
@@ -2713,18 +2783,21 @@
       } else {
         name = '${target.enclosingClass.name}.${name}';
       }
+
+      if (enableConstFunctions) {
+        return _handleFunctionInvocation(
+            node.target.function, typeArguments, positionals, named);
+      }
     }
     return createInvalidExpressionConstant(node, "Invocation of $name");
   }
 
-  Constant _handleStaticInvocation(
-      StaticInvocation node,
+  Constant _handleFunctionInvocation(
+      FunctionNode function,
       List<DartType> typeArguments,
       List<Constant> positionalArguments,
       Map<String, Constant> namedArguments) {
     return withNewEnvironment(() {
-      final FunctionNode function = node.target.function;
-
       // Map arguments from caller to callee.
       for (int i = 0; i < function.typeParameters.length; i++) {
         env.addTypeParameterValue(function.typeParameters[i], typeArguments[i]);
@@ -2736,14 +2809,14 @@
             // TODO(johnniwinther): This should call [_evaluateSubexpression].
             : _evaluateNullableSubexpression(parameter.initializer);
         if (value is AbortConstant) return value;
-        env.updateVariableValue(parameter, value);
+        env.addVariableValue(parameter, value);
       }
       for (final VariableDeclaration parameter in function.namedParameters) {
         final Constant value = namedArguments[parameter.name] ??
             // TODO(johnniwinther): This should call [_evaluateSubexpression].
             _evaluateNullableSubexpression(parameter.initializer);
         if (value is AbortConstant) return value;
-        env.updateVariableValue(parameter, value);
+        env.addVariableValue(parameter, value);
       }
       return execute(function.body);
     });
@@ -3152,7 +3225,11 @@
 
   T withNewEnvironment<T>(T fn()) {
     final EvaluationEnvironment oldEnv = env;
-    env = new EvaluationEnvironment();
+    if (enableConstFunctions) {
+      env = new EvaluationEnvironment.withParent(env);
+    } else {
+      env = new EvaluationEnvironment();
+    }
     T result = fn();
     env = oldEnv;
     return result;
@@ -3204,9 +3281,60 @@
       node = node.parent;
     }
   }
+
+  @override
+  Constant defaultBasicLiteral(BasicLiteral node) => defaultExpression(node);
+
+  @override
+  Constant visitAwaitExpression(AwaitExpression node) =>
+      defaultExpression(node);
+
+  @override
+  Constant visitBlockExpression(BlockExpression node) =>
+      defaultExpression(node);
+
+  @override
+  Constant visitDynamicSet(DynamicSet node) => defaultExpression(node);
+
+  @override
+  Constant visitInstanceGetterInvocation(InstanceGetterInvocation node) =>
+      defaultExpression(node);
+
+  @override
+  Constant visitInstanceSet(InstanceSet node) => defaultExpression(node);
+
+  @override
+  Constant visitLoadLibrary(LoadLibrary node) => defaultExpression(node);
+
+  @override
+  Constant visitPropertySet(PropertySet node) => defaultExpression(node);
+
+  @override
+  Constant visitRethrow(Rethrow node) => defaultExpression(node);
+
+  @override
+  Constant visitStaticSet(StaticSet node) => defaultExpression(node);
+
+  @override
+  Constant visitSuperMethodInvocation(SuperMethodInvocation node) =>
+      defaultExpression(node);
+
+  @override
+  Constant visitSuperPropertyGet(SuperPropertyGet node) =>
+      defaultExpression(node);
+
+  @override
+  Constant visitSuperPropertySet(SuperPropertySet node) =>
+      defaultExpression(node);
+
+  @override
+  Constant visitThisExpression(ThisExpression node) => defaultExpression(node);
+
+  @override
+  Constant visitThrow(Throw node) => defaultExpression(node);
 }
 
-class StatementConstantEvaluator extends StatementVisitor<Constant> {
+class StatementConstantEvaluator extends StatementVisitor<ExecutionStatus> {
   ConstantEvaluator exprEvaluator;
 
   StatementConstantEvaluator(this.exprEvaluator) {
@@ -3219,12 +3347,156 @@
   Constant evaluate(Expression expr) => expr.accept(exprEvaluator);
 
   @override
-  Constant defaultStatement(Statement node) => throw new UnsupportedError(
-      'Statement constant evaluation does not support ${node.runtimeType}.');
+  ExecutionStatus defaultStatement(Statement node) {
+    throw new UnsupportedError(
+        'Statement constant evaluation does not support ${node.runtimeType}.');
+  }
 
   @override
-  Constant visitReturnStatement(ReturnStatement node) =>
-      evaluate(node.expression);
+  ExecutionStatus visitAssertBlock(AssertBlock node) => defaultStatement(node);
+
+  @override
+  ExecutionStatus visitAssertStatement(AssertStatement node) {
+    AbortConstant error = exprEvaluator.checkAssert(node);
+    if (error != null) return new AbortStatus(error);
+    return const ProceedStatus();
+  }
+
+  @override
+  ExecutionStatus visitBlock(Block node) {
+    return exprEvaluator.withNewEnvironment(() {
+      for (Statement statement in node.statements) {
+        final ExecutionStatus status = statement.accept(this);
+        if (status is! ProceedStatus) return status;
+      }
+      return const ProceedStatus();
+    });
+  }
+
+  @override
+  ExecutionStatus visitBreakStatement(BreakStatement node) =>
+      new BreakStatus(node.target);
+
+  @override
+  ExecutionStatus visitContinueSwitchStatement(ContinueSwitchStatement node) =>
+      node.target.body.accept(this);
+
+  @override
+  ExecutionStatus visitDoStatement(DoStatement node) {
+    Constant condition;
+    do {
+      ExecutionStatus status = node.body.accept(this);
+      if (status is! ProceedStatus) return status;
+      condition = evaluate(node.condition);
+    } while (condition is BoolConstant && condition.value);
+
+    if (condition is AbortConstant) {
+      return new AbortStatus(condition);
+    }
+    assert(condition is BoolConstant);
+    return const ProceedStatus();
+  }
+
+  @override
+  ExecutionStatus visitIfStatement(IfStatement node) {
+    Constant condition = evaluate(node.condition);
+    if (condition is AbortConstant) return new AbortStatus(condition);
+    assert(condition is BoolConstant);
+    if ((condition as BoolConstant).value) {
+      return node.then.accept(this);
+    } else if (node.otherwise != null) {
+      return node.otherwise.accept(this);
+    }
+    return const ProceedStatus();
+  }
+
+  @override
+  ExecutionStatus visitForStatement(ForStatement node) {
+    for (VariableDeclaration variable in node.variables) {
+      final ExecutionStatus status = variable.accept(this);
+      if (status is! ProceedStatus) return status;
+    }
+
+    Constant condition =
+        node.condition != null ? evaluate(node.condition) : null;
+    while (node.condition == null || condition is BoolConstant) {
+      if (condition is BoolConstant && !condition.value) break;
+
+      final ExecutionStatus status = node.body.accept(this);
+      if (status is! ProceedStatus) return status;
+
+      for (Expression update in node.updates) {
+        Constant updateConstant = evaluate(update);
+        if (updateConstant is AbortConstant) {
+          return new AbortStatus(updateConstant);
+        }
+      }
+
+      if (node.condition != null) {
+        condition = evaluate(node.condition);
+      }
+    }
+
+    if (condition is AbortConstant) return new AbortStatus(condition);
+    assert(condition is BoolConstant);
+    return const ProceedStatus();
+  }
+
+  @override
+  ExecutionStatus visitExpressionStatement(ExpressionStatement node) {
+    Constant value = evaluate(node.expression);
+    if (value is AbortConstant) return new AbortStatus(value);
+    return const ProceedStatus();
+  }
+
+  @override
+  ExecutionStatus visitLabeledStatement(LabeledStatement node) {
+    final ExecutionStatus status = node.body.accept(this);
+    if (status is BreakStatus && status.target == node) {
+      return const ProceedStatus();
+    }
+    return status;
+  }
+
+  @override
+  ExecutionStatus visitReturnStatement(ReturnStatement node) =>
+      new ReturnStatus(evaluate(node.expression));
+
+  @override
+  ExecutionStatus visitSwitchStatement(SwitchStatement node) {
+    final Constant value = evaluate(node.expression);
+    if (value is AbortConstant) return new AbortStatus(value);
+
+    for (SwitchCase switchCase in node.cases) {
+      if (switchCase.isDefault) return switchCase.body.accept(this);
+      for (Expression expr in switchCase.expressions) {
+        final Constant caseValue = evaluate(expr);
+        if (value == caseValue) return switchCase.body.accept(this);
+      }
+    }
+    return const ProceedStatus();
+  }
+
+  @override
+  ExecutionStatus visitVariableDeclaration(VariableDeclaration node) {
+    Constant value = evaluate(node.initializer);
+    if (value is AbortConstant) return new AbortStatus(value);
+    exprEvaluator.env.addVariableValue(node, value);
+    return const ProceedStatus();
+  }
+
+  @override
+  ExecutionStatus visitWhileStatement(WhileStatement node) {
+    Constant condition = evaluate(node.condition);
+    while (condition is BoolConstant && condition.value) {
+      final ExecutionStatus status = node.body.accept(this);
+      if (status is! ProceedStatus) return status;
+      condition = evaluate(node.condition);
+    }
+    if (condition is AbortConstant) return new AbortStatus(condition);
+    assert(condition is BoolConstant);
+    return const ProceedStatus();
+  }
 }
 
 class ConstantCoverage {
@@ -3298,29 +3570,45 @@
   final Set<VariableDeclaration> _unreadUnevaluatedVariables =
       new Set<VariableDeclaration>();
 
+  EvaluationEnvironment _parent;
+
+  EvaluationEnvironment();
+  EvaluationEnvironment.withParent(this._parent);
+
   /// Whether the current environment is empty.
-  bool get isEmpty => _typeVariables.isEmpty && _variables.isEmpty;
+  bool get isEmpty {
+    // Since we look up variables in enclosing environment, the environment
+    // is not empty if its parent is not empty.
+    if (_parent != null && !_parent.isEmpty) return false;
+    return _typeVariables.isEmpty && _variables.isEmpty;
+  }
 
   void addTypeParameterValue(TypeParameter parameter, DartType value) {
     assert(!_typeVariables.containsKey(parameter));
     _typeVariables[parameter] = value;
   }
 
-  void updateVariableValue(VariableDeclaration variable, Constant value) {
-    if (!_variables.containsKey(variable)) {
-      _variables[variable] = new EvaluationReference(value);
-    } else {
-      _variables[variable].value = value;
-    }
+  void addVariableValue(VariableDeclaration variable, Constant value) {
+    _variables[variable] = new EvaluationReference(value);
     if (value is UnevaluatedConstant) {
       _unreadUnevaluatedVariables.add(variable);
     }
   }
 
+  Constant updateVariableValue(VariableDeclaration variable, Constant value) {
+    if (_variables.containsKey(variable)) {
+      _variables[variable].value = value;
+      return value;
+    }
+    return _parent?.updateVariableValue(variable, value);
+  }
+
   Constant lookupVariable(VariableDeclaration variable) {
     Constant value = _variables[variable]?.value;
     if (value is UnevaluatedConstant) {
       _unreadUnevaluatedVariables.remove(variable);
+    } else if (value == null) {
+      return _parent?.lookupVariable(variable);
     }
     return value;
   }
@@ -3362,6 +3650,34 @@
   EvaluationReference(this.value);
 }
 
+/// Represents a status for statement execution.
+abstract class ExecutionStatus {
+  const ExecutionStatus();
+}
+
+/// Status that the statement completed execution successfully.
+class ProceedStatus extends ExecutionStatus {
+  const ProceedStatus();
+}
+
+/// Status that the statement returned a valid [Constant] value.
+class ReturnStatus extends ExecutionStatus {
+  final Constant value;
+  ReturnStatus(this.value);
+}
+
+/// Status with an exception or error that the statement has thrown.
+class AbortStatus extends ExecutionStatus {
+  final AbortConstant error;
+  AbortStatus(this.error);
+}
+
+/// Status that the statement breaks out of an enclosing [LabeledStatement].
+class BreakStatus extends ExecutionStatus {
+  final LabeledStatement target;
+  BreakStatus(this.target);
+}
+
 /// An intermediate result that is used within the [ConstantEvaluator].
 class IntermediateValue implements Constant {
   dynamic value;
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 4e59fb4..19f3191 100644
--- a/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
@@ -67,18 +67,6 @@
 
 import 'kernel_api.dart' show NameSystem, printNodeOn, printQualifiedNameOn;
 
-import 'kernel_ast_api.dart'
-    show
-        Arguments,
-        DartType,
-        DynamicType,
-        Expression,
-        Initializer,
-        Member,
-        Name,
-        Procedure,
-        VariableDeclaration;
-
 import 'kernel_builder.dart' show LoadLibraryBuilder;
 
 import 'internal_ast.dart';
@@ -3070,12 +3058,13 @@
     Arguments arguments = send.arguments;
 
     TypeDeclarationBuilder declarationBuilder = declaration;
+    TypeAliasBuilder aliasBuilder;
     if (declarationBuilder is TypeAliasBuilder) {
-      TypeAliasBuilder aliasBuilder = declarationBuilder;
+      aliasBuilder = declarationBuilder;
       declarationBuilder = aliasBuilder.unaliasDeclaration(null,
-          isInvocation: true,
-          invocationCharOffset: this.fileOffset,
-          invocationFileUri: _uri);
+          isUsedAsClass: true,
+          usedAsClassCharOffset: this.fileOffset,
+          usedAsClassFileUri: _uri);
     }
     if (declarationBuilder is DeclarationBuilder) {
       DeclarationBuilder declaration = declarationBuilder;
@@ -3097,7 +3086,8 @@
               send.typeArguments,
               token.charOffset,
               Constness.implicit,
-              isTypeArgumentsInForest: send.isTypeArgumentsInForest);
+              isTypeArgumentsInForest: send.isTypeArgumentsInForest,
+              typeAliasBuilder: aliasBuilder);
         }
       } else if (member is AmbiguousBuilder) {
         return _helper.buildProblem(
diff --git a/pkg/front_end/lib/src/fasta/kernel/expression_generator_helper.dart b/pkg/front_end/lib/src/fasta/kernel/expression_generator_helper.dart
index 83bd4ab..2faf2ed 100644
--- a/pkg/front_end/lib/src/fasta/kernel/expression_generator_helper.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/expression_generator_helper.dart
@@ -126,7 +126,8 @@
       List<UnresolvedType> typeArguments,
       int charOffset,
       Constness constness,
-      {bool isTypeArgumentsInForest = false});
+      {bool isTypeArgumentsInForest = false,
+      TypeDeclarationBuilder typeAliasBuilder});
 
   UnresolvedType validateTypeUse(UnresolvedType unresolved,
       {bool nonInstanceAccessIsError, bool allowPotentiallyConstantType});
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 b45a75c..f9c2d18 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
@@ -61,6 +61,12 @@
   }
 
   @override
+  ImplicitFieldType toNonNull() {
+    return unsupported(
+        "toNonNullable", fieldBuilder.charOffset, fieldBuilder.fileUri);
+  }
+
+  @override
   void toTextInternal(AstPrinter printer) {
     printer.write('<implicit-field-type:$fieldBuilder>');
   }
diff --git a/pkg/front_end/lib/src/fasta/kernel/implicit_type_argument.dart b/pkg/front_end/lib/src/fasta/kernel/implicit_type_argument.dart
index c6daddf..3f27451 100644
--- a/pkg/front_end/lib/src/fasta/kernel/implicit_type_argument.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/implicit_type_argument.dart
@@ -49,6 +49,11 @@
   }
 
   @override
+  ImplicitTypeArgument toNonNull() {
+    return unsupported("toNonNullable", -1, null);
+  }
+
+  @override
   bool equals(Object other, Assumptions assumptions) => this == other;
 
   @override
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 be077f9..89fdd5e 100644
--- a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
@@ -94,6 +94,90 @@
   }
 
   @override
+  ExpressionInferenceResult visitDynamicGet(
+      DynamicGet node, DartType typeContext) {
+    return _unhandledExpression(node, typeContext);
+  }
+
+  @override
+  ExpressionInferenceResult visitInstanceGet(
+      InstanceGet node, DartType typeContext) {
+    return _unhandledExpression(node, typeContext);
+  }
+
+  @override
+  ExpressionInferenceResult visitInstanceTearOff(
+      InstanceTearOff node, DartType typeContext) {
+    return _unhandledExpression(node, typeContext);
+  }
+
+  @override
+  ExpressionInferenceResult visitDynamicInvocation(
+      DynamicInvocation node, DartType typeContext) {
+    return _unhandledExpression(node, typeContext);
+  }
+
+  @override
+  ExpressionInferenceResult visitDynamicSet(
+      DynamicSet node, DartType typeContext) {
+    return _unhandledExpression(node, typeContext);
+  }
+
+  @override
+  ExpressionInferenceResult visitEqualsCall(
+      EqualsCall node, DartType typeContext) {
+    return _unhandledExpression(node, typeContext);
+  }
+
+  @override
+  ExpressionInferenceResult visitEqualsNull(
+      EqualsNull node, DartType typeContext) {
+    return _unhandledExpression(node, typeContext);
+  }
+
+  @override
+  ExpressionInferenceResult visitFunctionInvocation(
+      FunctionInvocation node, DartType typeContext) {
+    return _unhandledExpression(node, typeContext);
+  }
+
+  @override
+  ExpressionInferenceResult visitInstanceInvocation(
+      InstanceInvocation node, DartType typeContext) {
+    return _unhandledExpression(node, typeContext);
+  }
+
+  @override
+  ExpressionInferenceResult visitInstanceGetterInvocation(
+      InstanceGetterInvocation node, DartType typeContext) {
+    return _unhandledExpression(node, typeContext);
+  }
+
+  @override
+  ExpressionInferenceResult visitInstanceSet(
+      InstanceSet node, DartType typeContext) {
+    return _unhandledExpression(node, typeContext);
+  }
+
+  @override
+  ExpressionInferenceResult visitLocalFunctionInvocation(
+      LocalFunctionInvocation node, DartType typeContext) {
+    return _unhandledExpression(node, typeContext);
+  }
+
+  @override
+  ExpressionInferenceResult visitStaticTearOff(
+      StaticTearOff node, DartType typeContext) {
+    return _unhandledExpression(node, typeContext);
+  }
+
+  @override
+  ExpressionInferenceResult visitFunctionTearOff(
+      FunctionTearOff node, DartType typeContext) {
+    return _unhandledExpression(node, typeContext);
+  }
+
+  @override
   ExpressionInferenceResult visitFileUriExpression(
       FileUriExpression node, DartType typeContext) {
     return _unhandledExpression(node, typeContext);
@@ -817,7 +901,7 @@
     // This is matched by the call to [forEach_end] in
     // [inferElement], [inferMapEntry] or [inferForInStatement].
     inferrer.flowAnalysis.declare(variable, true);
-    inferrer.flowAnalysis.forEach_bodyBegin(node, variable, variable.type);
+    inferrer.flowAnalysis.forEach_bodyBegin(node);
 
     VariableDeclaration tempVariable =
         new VariableDeclaration(null, type: inferredType, isFinal: true);
@@ -938,8 +1022,11 @@
     }
     // This is matched by the call to [forEach_end] in
     // [inferElement], [inferMapEntry] or [inferForInStatement].
-    inferrer.flowAnalysis.forEach_bodyBegin(node, variable, inferredType);
+    inferrer.flowAnalysis.forEach_bodyBegin(node);
     syntheticAssignment = forInVariable.inferAssignment(inferrer, inferredType);
+    if (syntheticAssignment is VariableSet) {
+      inferrer.flowAnalysis.write(node, variable, inferredType, null);
+    }
     if (expressionEffects != null) {
       StatementInferenceResult result =
           inferrer.inferStatement(expressionEffects);
@@ -1165,7 +1252,7 @@
     //   UP(t0, t1)
     // - Then the inferred type is T.
     DartType originalLhsType = lhsResult.inferredType;
-    DartType nonNullableLhsType = inferrer.computeNonNullable(originalLhsType);
+    DartType nonNullableLhsType = originalLhsType.toNonNull();
     DartType inferredType = inferrer.typeSchemaEnvironment
         .getStandardUpperBound(nonNullableLhsType, rhsResult.inferredType,
             inferrer.library.library);
@@ -1389,8 +1476,14 @@
                 spreadType is! DynamicType &&
                 spreadType is! NullType &&
                 !element.isNullAware) {
+              Expression receiver = element.expression;
               replacement = inferrer.helper.buildProblem(
-                  messageNullableSpreadError, element.expression.fileOffset, 1);
+                  messageNullableSpreadError, receiver.fileOffset, 1,
+                  context: inferrer.getWhyNotPromotedContext(
+                      receiver,
+                      inferrer.flowAnalysis?.whyNotPromoted(receiver)(),
+                      element,
+                      (type) => !type.isPotentiallyNullable));
             }
 
             replacement = inferrer.helper.buildProblem(
@@ -1398,6 +1491,7 @@
                     spreadType, inferrer.isNonNullableByDefault),
                 element.expression.fileOffset,
                 1);
+            _copyNonPromotionReasonToReplacement(element, replacement);
           }
         } else if (spreadTypeBound is InterfaceType) {
           if (!inferrer.isAssignable(inferredTypeArgument, spreadElementType)) {
@@ -1452,8 +1546,15 @@
               spreadType is! DynamicType &&
               spreadType is! NullType &&
               !element.isNullAware) {
+            Expression receiver = element.expression;
             replacement = inferrer.helper.buildProblem(
-                messageNullableSpreadError, element.expression.fileOffset, 1);
+                messageNullableSpreadError, receiver.fileOffset, 1,
+                context: inferrer.getWhyNotPromotedContext(
+                    receiver,
+                    inferrer.flowAnalysis?.whyNotPromoted(receiver)(),
+                    element,
+                    (type) => !type.isPotentiallyNullable));
+            _copyNonPromotionReasonToReplacement(element, replacement);
           }
         }
       }
@@ -1632,6 +1733,17 @@
     }
   }
 
+  void _copyNonPromotionReasonToReplacement(
+      TreeNode oldNode, TreeNode replacement) {
+    if (!identical(oldNode, replacement) &&
+        inferrer.dataForTesting?.flowAnalysisResult != null) {
+      inferrer.dataForTesting.flowAnalysisResult
+              .nonPromotionReasons[replacement] =
+          inferrer
+              .dataForTesting.flowAnalysisResult.nonPromotionReasons[oldNode];
+    }
+  }
+
   void checkElement(
       Expression item,
       Expression parent,
@@ -1872,10 +1984,16 @@
                 spreadType is! DynamicType &&
                 spreadType is! NullType &&
                 !entry.isNullAware) {
-              replacement = new SpreadMapEntry(
-                  inferrer.helper.buildProblem(messageNullableSpreadError,
-                      entry.expression.fileOffset, 1),
-                  false)
+              Expression receiver = entry.expression;
+              Expression problem = inferrer.helper.buildProblem(
+                  messageNullableSpreadError, receiver.fileOffset, 1,
+                  context: inferrer.getWhyNotPromotedContext(
+                      receiver,
+                      inferrer.flowAnalysis?.whyNotPromoted(receiver)(),
+                      entry,
+                      (type) => !type.isPotentiallyNullable));
+              _copyNonPromotionReasonToReplacement(entry, problem);
+              replacement = new SpreadMapEntry(problem, false)
                 ..fileOffset = entry.fileOffset;
             }
 
@@ -1883,13 +2001,19 @@
             // error is reported in checkMapEntry if it's disambiguated as map.
             iterableSpreadType = spreadType;
           } else {
-            replacement = new MapEntry(
-                inferrer.helper.buildProblem(
-                    templateSpreadMapEntryTypeMismatch.withArguments(
-                        spreadType, inferrer.isNonNullableByDefault),
-                    entry.expression.fileOffset,
-                    1),
-                new NullLiteral())
+            Expression receiver = entry.expression;
+            Expression problem = inferrer.helper.buildProblem(
+                templateSpreadMapEntryTypeMismatch.withArguments(
+                    spreadType, inferrer.isNonNullableByDefault),
+                receiver.fileOffset,
+                1,
+                context: inferrer.getWhyNotPromotedContext(
+                    receiver,
+                    inferrer.flowAnalysis?.whyNotPromoted(receiver)(),
+                    entry,
+                    (type) => !type.isPotentiallyNullable));
+            _copyNonPromotionReasonToReplacement(entry, problem);
+            replacement = new MapEntry(problem, new NullLiteral())
               ..fileOffset = entry.fileOffset;
           }
         } else if (spreadTypeBound is InterfaceType) {
@@ -1991,8 +2115,15 @@
               spreadType is! DynamicType &&
               spreadType is! NullType &&
               !entry.isNullAware) {
+            Expression receiver = entry.expression;
             keyError = inferrer.helper.buildProblem(
-                messageNullableSpreadError, entry.expression.fileOffset, 1);
+                messageNullableSpreadError, receiver.fileOffset, 1,
+                context: inferrer.getWhyNotPromotedContext(
+                    receiver,
+                    inferrer.flowAnalysis?.whyNotPromoted(receiver)(),
+                    entry,
+                    (type) => !type.isPotentiallyNullable));
+            _copyNonPromotionReasonToReplacement(entry, keyError);
           }
           if (keyError != null || valueError != null) {
             keyError ??= new NullLiteral();
@@ -2259,7 +2390,8 @@
                   iterableSpreadType, inferrer.isNonNullableByDefault),
               iterableSpreadOffset,
               1),
-          new NullLiteral());
+          new NullLiteral())
+        ..fileOffset = iterableSpreadOffset;
     }
     if (entry is SpreadMapEntry) {
       DartType spreadType = inferredSpreadTypes[entry.expression];
@@ -2596,7 +2728,7 @@
     reportNonNullableInNullAwareWarningIfNeeded(
         operandType, "!", node.operand.fileOffset);
     inferrer.flowAnalysis.nonNullAssert_end(node.operand);
-    DartType nonNullableResultType = inferrer.computeNonNullable(operandType);
+    DartType nonNullableResultType = operandType.toNonNull();
     return inferrer.createNullAwareExpressionInferenceResult(
         nonNullableResultType, node, nullAwareGuards);
   }
@@ -2838,7 +2970,7 @@
         .findInterfaceMember(readType, equalsName, node.fileOffset)
         .member;
 
-    DartType nonNullableReadType = inferrer.computeNonNullable(readType);
+    DartType nonNullableReadType = readType.toNonNull();
     DartType inferredType = inferrer.typeSchemaEnvironment
         .getStandardUpperBound(
             nonNullableReadType, writeType, inferrer.library.library);
@@ -2903,8 +3035,7 @@
         .member;
 
     DartType originalReadType = readType;
-    DartType nonNullableReadType =
-        inferrer.computeNonNullable(originalReadType);
+    DartType nonNullableReadType = originalReadType.toNonNull();
     DartType inferredType = inferrer.typeSchemaEnvironment
         .getStandardUpperBound(nonNullableReadType, writeResult.inferredType,
             inferrer.library.library);
@@ -3282,7 +3413,7 @@
     Expression value = inferrer.ensureAssignableResult(valueType, valueResult);
     inferrer.flowAnalysis.ifNullExpression_end();
 
-    DartType nonNullableReadType = inferrer.computeNonNullable(readType);
+    DartType nonNullableReadType = readType.toNonNull();
     DartType inferredType = inferrer.typeSchemaEnvironment
         .getStandardUpperBound(nonNullableReadType, valueResult.inferredType,
             inferrer.library.library);
@@ -3463,7 +3594,7 @@
     Expression value = inferrer.ensureAssignableResult(valueType, valueResult);
     inferrer.flowAnalysis.ifNullExpression_end();
 
-    DartType nonNullableReadType = inferrer.computeNonNullable(readType);
+    DartType nonNullableReadType = readType.toNonNull();
     DartType inferredType = inferrer.typeSchemaEnvironment
         .getStandardUpperBound(nonNullableReadType, valueResult.inferredType,
             inferrer.library.library);
@@ -3638,7 +3769,7 @@
     Expression value = inferrer.ensureAssignableResult(valueType, valueResult);
     inferrer.flowAnalysis.ifNullExpression_end();
 
-    DartType nonNullableReadType = inferrer.computeNonNullable(readType);
+    DartType nonNullableReadType = readType.toNonNull();
     DartType inferredType = inferrer.typeSchemaEnvironment
         .getStandardUpperBound(nonNullableReadType, valueResult.inferredType,
             inferrer.library.library);
@@ -3747,12 +3878,15 @@
 
     if (inferrer.useNewMethodInvocationEncoding) {
       if (_isNull(right)) {
-        equals = new EqualsNull(left, isNot: isNot)..fileOffset = fileOffset;
+        equals = new EqualsNull(left)..fileOffset = fileOffset;
       } else if (_isNull(left)) {
-        equals = new EqualsNull(rightResult.expression, isNot: isNot)
+        equals = new EqualsNull(rightResult.expression)
           ..fileOffset = fileOffset;
       }
       if (equals != null) {
+        if (isNot) {
+          equals = new Not(equals)..fileOffset = fileOffset;
+        }
         inferrer.flowAnalysis.equalityOp_end(
             equals, rightResult.expression, rightResult.inferredType,
             notEqual: isNot);
@@ -3798,10 +3932,11 @@
         FunctionType functionType =
             inferrer.getFunctionType(equalsTarget, leftType);
         equals = new EqualsCall(left, right,
-            isNot: isNot,
-            functionType: functionType,
-            interfaceTarget: equalsTarget.member)
+            functionType: functionType, interfaceTarget: equalsTarget.member)
           ..fileOffset = fileOffset;
+        if (isNot) {
+          equals = new Not(equals)..fileOffset = fileOffset;
+        }
       } else {
         assert(equalsTarget.isNever);
         FunctionType functionType = new FunctionType([const DynamicType()],
@@ -3812,8 +3947,11 @@
                 instrumented: false)
             .member;
         equals = new EqualsCall(left, right,
-            isNot: isNot, functionType: functionType, interfaceTarget: target)
+            functionType: functionType, interfaceTarget: target)
           ..fileOffset = fileOffset;
+        if (isNot) {
+          equals = new Not(equals)..fileOffset = fileOffset;
+        }
       }
     } else {
       equals = new MethodInvocation(
@@ -4741,7 +4879,10 @@
           read.fileOffset,
           propertyName.text.length,
           context: inferrer.getWhyNotPromotedContext(
-              receiver, inferrer.flowAnalysis?.whyNotPromoted(receiver), read));
+              receiver,
+              inferrer.flowAnalysis?.whyNotPromoted(receiver)(),
+              read,
+              (type) => !type.isPotentiallyNullable));
     }
     return readResult;
   }
@@ -5072,7 +5213,7 @@
         inferrer.createNullAwareGuard(receiverVariable);
     Expression readReceiver = createVariableGet(receiverVariable);
     Expression writeReceiver = createVariableGet(receiverVariable);
-    DartType nonNullReceiverType = inferrer.computeNonNullable(receiverType);
+    DartType nonNullReceiverType = receiverType.toNonNull();
 
     ExpressionInferenceResult readResult = _computePropertyGet(
         node.readOffset,
@@ -5608,7 +5749,7 @@
         inferrer.createNullAwareGuard(receiverVariable);
     Expression readReceiver = createVariableGet(receiverVariable);
     Expression writeReceiver = createVariableGet(receiverVariable);
-    DartType nonNullReceiverType = inferrer.computeNonNullable(receiverType);
+    DartType nonNullReceiverType = receiverType.toNonNull();
 
     ExpressionInferenceResult readResult = _computePropertyGet(node.readOffset,
         readReceiver, nonNullReceiverType, node.name, typeContext,
@@ -5644,7 +5785,7 @@
 
     inferrer.flowAnalysis.ifNullExpression_end();
 
-    DartType nonNullableReadType = inferrer.computeNonNullable(readType);
+    DartType nonNullableReadType = readType.toNonNull();
     DartType inferredType = inferrer.typeSchemaEnvironment
         .getStandardUpperBound(nonNullableReadType, valueResult.inferredType,
             inferrer.library.library);
@@ -5708,7 +5849,7 @@
         node.fileOffset, receiver, receiverType, node.name, typeContext,
         isThisReceiver: node.receiver is ThisExpression);
     inferrer.flowAnalysis.propertyGet(
-        node, node.receiver, node.name.name, readResult.inferredType);
+        node, node.receiver, node.name.text, readResult.inferredType);
     ExpressionInferenceResult expressionInferenceResult =
         inferrer.createNullAwareExpressionInferenceResult(
             readResult.inferredType, readResult.expression, nullAwareGuards);
@@ -6234,7 +6375,7 @@
       inferrer.flowAnalysis.tryFinallyStatement_finallyBegin(
           node.catchBlocks.isNotEmpty ? node : tryBodyWithAssignedInfo);
       finalizerResult = inferrer.inferStatement(node.finallyBlock);
-      inferrer.flowAnalysis.tryFinallyStatement_end(node.finallyBlock);
+      inferrer.flowAnalysis.tryFinallyStatement_end();
     }
     Statement result =
         tryBlockResult.hasChanged ? tryBlockResult.statement : node.tryBlock;
@@ -6571,7 +6712,7 @@
       inferrer.flowAnalysis.thisOrSuper(node, variable.type);
     } else if (inferrer.isNonNullableByDefault) {
       if (node.forNullGuardedAccess) {
-        DartType nonNullableType = inferrer.computeNonNullable(variable.type);
+        DartType nonNullableType = variable.type.toNonNull();
         if (nonNullableType != variable.type) {
           promotedType = nonNullableType;
         }
@@ -6867,97 +7008,6 @@
       }
     }
   }
-
-  @override
-  ExpressionInferenceResult visitDynamicGet(
-      DynamicGet node, DartType typeContext) {
-    // TODO: implement visitDynamicGet
-    throw new UnimplementedError();
-  }
-
-  @override
-  ExpressionInferenceResult visitInstanceGet(
-      InstanceGet node, DartType typeContext) {
-    // TODO: implement visitInstanceGet
-    throw new UnimplementedError();
-  }
-
-  @override
-  ExpressionInferenceResult visitInstanceTearOff(
-      InstanceTearOff node, DartType typeContext) {
-    // TODO: implement visitInstanceTearOff
-    throw new UnimplementedError();
-  }
-
-  @override
-  ExpressionInferenceResult visitDynamicInvocation(
-      DynamicInvocation node, DartType typeContext) {
-    // TODO: implement visitDynamicInvocation
-    throw new UnimplementedError();
-  }
-
-  @override
-  ExpressionInferenceResult visitDynamicSet(
-      DynamicSet node, DartType typeContext) {
-    // TODO: implement visitDynamicSet
-    throw new UnimplementedError();
-  }
-
-  @override
-  ExpressionInferenceResult visitEqualsCall(
-      EqualsCall node, DartType typeContext) {
-    // TODO: implement visitEqualsCall
-    throw new UnimplementedError();
-  }
-
-  @override
-  ExpressionInferenceResult visitEqualsNull(
-      EqualsNull node, DartType typeContext) {
-    // TODO: implement visitEqualsNull
-    throw new UnimplementedError();
-  }
-
-  @override
-  ExpressionInferenceResult visitFunctionInvocation(
-      FunctionInvocation node, DartType typeContext) {
-    // TODO: implement visitFunctionInvocation
-    throw new UnimplementedError();
-  }
-
-  @override
-  ExpressionInferenceResult visitInstanceInvocation(
-      InstanceInvocation node, DartType typeContext) {
-    // TODO: implement visitInstanceInvocation
-    throw new UnimplementedError();
-  }
-
-  @override
-  ExpressionInferenceResult visitInstanceSet(
-      InstanceSet node, DartType typeContext) {
-    // TODO: implement visitInstanceSet
-    throw new UnimplementedError();
-  }
-
-  @override
-  ExpressionInferenceResult visitLocalFunctionInvocation(
-      LocalFunctionInvocation node, DartType typeContext) {
-    // TODO: implement visitLocalFunctionInvocation
-    throw new UnimplementedError();
-  }
-
-  @override
-  ExpressionInferenceResult visitStaticTearOff(
-      StaticTearOff node, DartType typeContext) {
-    // TODO: implement visitStaticTearOff
-    throw new UnimplementedError();
-  }
-
-  @override
-  ExpressionInferenceResult visitFunctionTearOff(
-      FunctionTearOff node, DartType arg) {
-    // TODO: implement visitFunctionTearOff
-    throw new UnimplementedError();
-  }
 }
 
 class ForInResult {
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 06bdd72..35da3d2 100644
--- a/pkg/front_end/lib/src/fasta/kernel/internal_ast.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/internal_ast.dart
@@ -21,13 +21,9 @@
 /// with the same kind of root node.
 
 import 'package:kernel/ast.dart';
-import 'package:kernel/binary/ast_to_binary.dart';
 import 'package:kernel/core_types.dart';
-import 'package:kernel/src/assumptions.dart';
 import 'package:kernel/src/printer.dart';
-import 'package:kernel/src/text_util.dart';
 import 'package:kernel/text/ast_to_text.dart' show Precedence, Printer;
-import 'package:kernel/type_algebra.dart';
 import 'package:kernel/type_environment.dart';
 
 import '../builder/type_alias_builder.dart';
@@ -54,8 +50,6 @@
 
 import 'inference_visitor.dart';
 
-import 'type_labeler.dart';
-
 /// Computes the return type of a (possibly factory) constructor.
 InterfaceType computeConstructorReturnType(
     Member constructor, CoreTypes coreTypes) {
@@ -4232,170 +4226,3 @@
   }
   throw new UnsupportedError("Clone not supported for ${node.runtimeType}.");
 }
-
-class ExtensionType extends DartType {
-  final Reference extensionName;
-
-  @override
-  final Nullability declaredNullability;
-
-  final List<DartType> typeArguments;
-
-  final DartType onType;
-
-  ExtensionType(Extension extensionNode, Nullability declaredNullability,
-      [List<DartType> typeArguments])
-      : this.byReference(extensionNode.reference, declaredNullability,
-            typeArguments ?? _defaultTypeArguments(extensionNode));
-
-  ExtensionType.byReference(
-      this.extensionName, this.declaredNullability, this.typeArguments)
-      : assert(declaredNullability != null),
-        onType = _computeOnType(extensionName, typeArguments);
-
-  Extension get extensionNode => extensionName.asExtension;
-
-  @override
-  Nullability get nullability {
-    return uniteNullabilities(
-        declaredNullability, extensionNode.onType.nullability);
-  }
-
-  static List<DartType> _defaultTypeArguments(Extension extensionNode) {
-    if (extensionNode.typeParameters.length == 0) {
-      // Avoid allocating a list in this very common case.
-      return const <DartType>[];
-    } else {
-      return new List<DartType>.filled(
-          extensionNode.typeParameters.length, const DynamicType());
-    }
-  }
-
-  static DartType _computeOnType(
-      Reference extensionName, List<DartType> typeArguments) {
-    Extension extensionNode = extensionName.asExtension;
-    if (extensionNode.typeParameters.isEmpty) {
-      return extensionNode.onType;
-    } else {
-      assert(extensionNode.typeParameters.length == typeArguments.length);
-      return Substitution.fromPairs(extensionNode.typeParameters, typeArguments)
-          .substituteType(extensionNode.onType);
-    }
-  }
-
-  @override
-  R accept<R>(DartTypeVisitor<R> v) {
-    if (v is Printer) {
-      // TODO(dmitryas): Move this guarded code into Printer.visitExtensionType
-      // when it's available.
-      Printer printer = v as Printer;
-      printer.writeExtensionReferenceFromReference(extensionName);
-      if (typeArguments.isNotEmpty) {
-        printer.writeSymbol('<');
-        printer.writeList(typeArguments, printer.writeType);
-        printer.writeSymbol('>');
-        printer.state = Printer.WORD;
-      }
-      printer.writeNullability(declaredNullability);
-      // The following line is needed to supply the return value and make the
-      // compiler happy. It should go away once ExtensionType is moved to
-      // ast.dart.
-      return null;
-    } else if (v is BinaryPrinter) {
-      // TODO(dmitryas): Remove the following line and implement
-      // BinaryPrinter.visitExtensionType when it's available.
-      return onType.accept(v);
-    } else if (v is TypeLabeler) {
-      // TODO(dmitryas): Move this guarded code into
-      // TypeLabeler.visitExtensionType when it's available.
-      TypeLabeler typeLabeler = v as TypeLabeler;
-      typeLabeler.result.add(typeLabeler.nameForEntity(
-          extensionNode,
-          extensionNode.name,
-          extensionNode.enclosingLibrary.importUri,
-          extensionNode.enclosingLibrary.fileUri));
-      if (typeArguments.isNotEmpty) {
-        typeLabeler.result.add("<");
-        bool first = true;
-        for (DartType typeArg in typeArguments) {
-          if (!first) typeLabeler.result.add(", ");
-          typeArg.accept(typeLabeler);
-          first = false;
-        }
-        typeLabeler.result.add(">");
-      }
-      typeLabeler.addNullability(declaredNullability);
-      // The following line is needed to supply the return value and make the
-      // compiler happy. It should go away once ExtensionType is moved to
-      // ast.dart.
-      return null;
-    }
-    // TODO(dmitryas): Change this to `v.visitExtensionType(this)` when
-    // ExtensionType is moved to ast.dart.
-    return v.defaultDartType(this);
-  }
-
-  @override
-  R accept1<R, A>(DartTypeVisitor1<R, A> v, A arg) {
-    // TODO(dmitryas): Change this to `v.visitExtensionType(this, arg)` when
-    // ExtensionType is moved to ast.dart.
-    return v.defaultDartType(this, arg);
-  }
-
-  @override
-  void visitChildren(Visitor v) {
-    // TODO(dmitryas): Uncomment the following line when ExtensionType is moved
-    // to ast.dart.
-    //extensionNode.acceptReference(v);
-    visitList(typeArguments, v);
-  }
-
-  @override
-  bool equals(Object other, Assumptions assumptions) {
-    if (identical(this, other)) return true;
-    if (other is ExtensionType) {
-      if (nullability != other.nullability) return false;
-      if (extensionName != other.extensionName) return false;
-      if (typeArguments.length != other.typeArguments.length) return false;
-      for (int i = 0; i < typeArguments.length; ++i) {
-        if (!typeArguments[i].equals(other.typeArguments[i], assumptions)) {
-          return false;
-        }
-      }
-      return true;
-    } else {
-      return false;
-    }
-  }
-
-  @override
-  int get hashCode {
-    int hash = 0x3fffffff & extensionName.hashCode;
-    for (int i = 0; i < typeArguments.length; ++i) {
-      hash = 0x3fffffff & (hash * 31 + (hash ^ typeArguments[i].hashCode));
-    }
-    int nullabilityHash = (0x33333333 >> nullability.index) ^ 0x33333333;
-    hash = 0x3fffffff & (hash * 31 + (hash ^ nullabilityHash));
-    return hash;
-  }
-
-  @override
-  ExtensionType withDeclaredNullability(Nullability declaredNullability) {
-    return declaredNullability == this.declaredNullability
-        ? this
-        : new ExtensionType.byReference(
-            extensionName, declaredNullability, typeArguments);
-  }
-
-  @override
-  String toString() {
-    return "ExtensionType(${toStringInternal()})";
-  }
-
-  @override
-  void toTextInternal(AstPrinter printer) {
-    printer.writeExtensionName(extensionName);
-    printer.writeTypeArguments(typeArguments);
-    printer.write(nullabilityToString(declaredNullability));
-  }
-}
diff --git a/pkg/front_end/lib/src/fasta/kernel/invalid_type.dart b/pkg/front_end/lib/src/fasta/kernel/invalid_type.dart
index b66b0ab..3cafb52 100644
--- a/pkg/front_end/lib/src/fasta/kernel/invalid_type.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/invalid_type.dart
@@ -5,12 +5,9 @@
 // @dart = 2.9
 
 import 'package:kernel/ast.dart';
-import 'package:kernel/visitor.dart';
 
 import '../type_inference/type_schema.dart';
 
-import 'internal_ast.dart';
-
 /// Check if [type] contains [InvalidType] as its part.
 ///
 /// The helper function is intended for stopping cascading errors because of
@@ -60,6 +57,15 @@
   }
 
   @override
+  bool visitExtensionType(
+      ExtensionType node, Set<TypedefType> visitedTypedefs) {
+    for (DartType typeArgument in node.typeArguments) {
+      if (typeArgument.accept1(this, visitedTypedefs)) return true;
+    }
+    return false;
+  }
+
+  @override
   bool visitFutureOrType(FutureOrType node, Set<TypedefType> visitedTypedefs) {
     return node.typeArgument.accept1(this, visitedTypedefs);
   }
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 1bebec8..456dc09 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
@@ -9,38 +9,7 @@
 import 'package:front_end/src/api_prototype/experimental_flags.dart';
 import 'package:front_end/src/fasta/dill/dill_library_builder.dart'
     show DillLibraryBuilder;
-import 'package:kernel/ast.dart'
-    show
-        Arguments,
-        CanonicalName,
-        Class,
-        Component,
-        Constructor,
-        DartType,
-        EmptyStatement,
-        Expression,
-        Field,
-        FieldInitializer,
-        FunctionNode,
-        Initializer,
-        InterfaceType,
-        InvalidInitializer,
-        InvalidType,
-        Library,
-        Name,
-        NamedExpression,
-        NonNullableByDefaultCompiledMode,
-        NullLiteral,
-        Procedure,
-        RedirectingInitializer,
-        Reference,
-        Source,
-        SuperInitializer,
-        Supertype,
-        TypeParameter,
-        TypeParameterType,
-        VariableDeclaration,
-        VariableGet;
+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';
@@ -51,7 +20,7 @@
 import 'package:kernel/transformations/value_class.dart' as valueClass;
 import 'package:kernel/type_algebra.dart' show substitute;
 import 'package:kernel/type_environment.dart' show TypeEnvironment;
-import 'package:package_config/package_config.dart';
+import 'package:package_config/package_config.dart' hide LanguageVersion;
 
 import '../../api_prototype/file_system.dart' show FileSystem;
 import '../../base/nnbd_mode.dart';
@@ -102,7 +71,8 @@
 import '../problems.dart' show unhandled;
 import '../scope.dart' show AmbiguousBuilder;
 import '../source/source_class_builder.dart' show SourceClassBuilder;
-import '../source/source_library_builder.dart' show SourceLibraryBuilder;
+import '../source/source_library_builder.dart'
+    show LanguageVersion, SourceLibraryBuilder;
 import '../source/source_loader.dart' show SourceLoader;
 import '../target_implementation.dart' show TargetImplementation;
 import '../uri_translator.dart' show UriTranslator;
@@ -246,6 +216,7 @@
       Uri uri,
       Uri fileUri,
       Uri packageUri,
+      LanguageVersion packageLanguageVersion,
       SourceLibraryBuilder origin,
       Library referencesFrom,
       bool referenceIsPartOwner) {
@@ -295,7 +266,8 @@
         return builder;
       }
     }
-    return new SourceLibraryBuilder(uri, fileUri, packageUri, loader, origin,
+    return new SourceLibraryBuilder(
+        uri, fileUri, packageUri, packageLanguageVersion, loader, origin,
         referencesFrom: referencesFrom,
         referenceIsPartOwner: referenceIsPartOwner);
   }
@@ -675,7 +647,10 @@
     if (supertype is TypeAliasBuilder) {
       TypeAliasBuilder aliasBuilder = supertype;
       NamedTypeBuilder namedBuilder = type;
-      supertype = aliasBuilder.unaliasDeclaration(namedBuilder.arguments);
+      supertype = aliasBuilder.unaliasDeclaration(namedBuilder.arguments,
+          isUsedAsClass: true,
+          usedAsClassCharOffset: namedBuilder.charOffset,
+          usedAsClassFileUri: namedBuilder.fileUri);
     }
     if (supertype is SourceClassBuilder && supertype.isMixinApplication) {
       installForwardingConstructors(supertype);
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 1f87bde..0e2ea27 100644
--- a/pkg/front_end/lib/src/fasta/kernel/late_lowering.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/late_lowering.dart
@@ -106,8 +106,7 @@
           new ConditionalExpression(
               useNewMethodInvocationEncoding
                   ? (new EqualsNull(
-                      new VariableGet(variable)..fileOffset = fileOffset,
-                      isNot: false)
+                      new VariableGet(variable)..fileOffset = fileOffset)
                     ..fileOffset = fileOffset)
                   : new MethodInvocation(
                       new VariableGet(variable)..fileOffset = fileOffset,
@@ -261,8 +260,7 @@
           new ConditionalExpression(
               useNewMethodInvocationEncoding
                   ? (new EqualsNull(
-                      new VariableGet(variable)..fileOffset = fileOffset,
-                      isNot: false)
+                      new VariableGet(variable)..fileOffset = fileOffset)
                     ..fileOffset = fileOffset)
                   : new MethodInvocation(
                       new VariableGet(variable)..fileOffset = fileOffset,
@@ -278,8 +276,7 @@
                       useNewMethodInvocationEncoding
                           ? (new EqualsNull(
                               createVariableRead(needsPromotion: false)
-                                ..fileOffset = fileOffset,
-                              isNot: false)
+                                ..fileOffset = fileOffset)
                             ..fileOffset = fileOffset)
                           : new MethodInvocation(
                               createVariableRead(needsPromotion: false)
@@ -381,8 +378,7 @@
           new ConditionalExpression(
               useNewMethodInvocationEncoding
                   ? (new EqualsNull(
-                      new VariableGet(variable)..fileOffset = fileOffset,
-                      isNot: false)
+                      new VariableGet(variable)..fileOffset = fileOffset)
                     ..fileOffset = fileOffset)
                   : new MethodInvocation(
                       new VariableGet(variable)..fileOffset = fileOffset,
@@ -540,8 +536,7 @@
       //    }
       return new IfStatement(
         useNewMethodInvocationEncoding
-            ? (new EqualsNull(createVariableRead()..fileOffset = fileOffset,
-                isNot: false)
+            ? (new EqualsNull(createVariableRead()..fileOffset = fileOffset)
               ..fileOffset = fileOffset)
             : new MethodInvocation(
                 createVariableRead()..fileOffset = fileOffset,
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 0866c33..d017229 100644
--- a/pkg/front_end/lib/src/fasta/kernel/transform_collections.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/transform_collections.dart
@@ -15,8 +15,6 @@
 import 'package:kernel/type_environment.dart'
     show SubtypeCheckMode, TypeEnvironment;
 
-import 'package:kernel/visitor.dart' show Transformer;
-
 import 'collections.dart'
     show
         ControlFlowElement,
@@ -946,22 +944,22 @@
   Expression _createEqualsNull(Expression expression, {bool notEquals: false}) {
     assert(expression != null);
     assert(expression.fileOffset != TreeNode.noOffset);
+    Expression check;
     if (useNewMethodInvocationEncoding) {
-      return new EqualsNull(expression, isNot: notEquals)
-        ..fileOffset = expression.fileOffset;
+      check = new EqualsNull(expression)..fileOffset = expression.fileOffset;
     } else {
-      Expression check = new MethodInvocation(
+      check = new MethodInvocation(
           expression,
           new Name('=='),
           new Arguments(
               [new NullLiteral()..fileOffset = expression.fileOffset]),
           _objectEquals)
         ..fileOffset = expression.fileOffset;
-      if (notEquals) {
-        check = new Not(check)..fileOffset = expression.fileOffset;
-      }
-      return check;
     }
+    if (notEquals) {
+      check = new Not(check)..fileOffset = expression.fileOffset;
+    }
+    return check;
   }
 
   Expression _createIndexSet(int fileOffset, Expression receiver,
diff --git a/pkg/front_end/lib/src/fasta/kernel/transform_set_literals.dart b/pkg/front_end/lib/src/fasta/kernel/transform_set_literals.dart
index 7195f01..253d4ce 100644
--- a/pkg/front_end/lib/src/fasta/kernel/transform_set_literals.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/transform_set_literals.dart
@@ -14,8 +14,6 @@
 
 import 'package:kernel/type_algebra.dart' show Substitution;
 
-import 'package:kernel/visitor.dart' show Transformer;
-
 import '../source/source_loader.dart' show SourceLoader;
 
 import 'redirecting_factory_body.dart' show RedirectingFactoryBody;
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 ac56037..6e79f8f 100644
--- a/pkg/front_end/lib/src/fasta/kernel/type_algorithms.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/type_algorithms.dart
@@ -4,23 +4,7 @@
 
 // @dart = 2.9
 
-import 'package:kernel/ast.dart'
-    show
-        DartType,
-        DartTypeVisitor,
-        DynamicType,
-        FunctionType,
-        FutureOrType,
-        InterfaceType,
-        InvalidType,
-        NamedType,
-        NeverType,
-        NullType,
-        TypeParameter,
-        TypeParameterType,
-        TypedefType,
-        Variance,
-        VoidType;
+import 'package:kernel/ast.dart';
 
 import 'package:kernel/type_algebra.dart' show containsTypeVariable;
 
@@ -315,8 +299,8 @@
             variance: Variance.invariant);
         if (bound != variable.bound) {
           TypeVariableBuilder newTypeVariableBuilder = variables[i] =
-              new TypeVariableBuilder(
-                  variable.name, variable.parent, variable.charOffset,
+              new TypeVariableBuilder(variable.name, variable.parent,
+                  variable.charOffset, variable.fileUri,
                   bound: bound);
           unboundTypeVariables.add(newTypeVariableBuilder);
           if (functionTypeUpperSubstitution == null) {
@@ -394,7 +378,12 @@
 /// (https://github.com/dart-lang/sdk/blob/master/docs/language/informal/instantiate-to-bound.md)
 /// of the algorithm for details.
 List<TypeBuilder> calculateBounds(List<TypeVariableBuilder> variables,
-    TypeBuilder dynamicType, TypeBuilder bottomType, ClassBuilder objectClass) {
+    TypeBuilder dynamicType, TypeBuilder bottomType, ClassBuilder objectClass,
+    {List<TypeBuilder> unboundTypes,
+    List<TypeVariableBuilder> unboundTypeVariables}) {
+  assert(unboundTypes != null);
+  assert(unboundTypeVariables != null);
+
   List<TypeBuilder> bounds =
       new List<TypeBuilder>.filled(variables.length, null);
 
@@ -415,8 +404,12 @@
     }
     for (int variableIndex in component) {
       TypeVariableBuilder variable = variables[variableIndex];
-      bounds[variableIndex] = substituteRange(bounds[variableIndex],
-          dynamicSubstitution, nullSubstitution, null, null,
+      bounds[variableIndex] = substituteRange(
+          bounds[variableIndex],
+          dynamicSubstitution,
+          nullSubstitution,
+          unboundTypes,
+          unboundTypeVariables,
           variance: variable.variance);
     }
   }
@@ -430,8 +423,8 @@
     nullSubstitution[variables[i]] = bottomType;
     for (int j = 0; j < variables.length; j++) {
       TypeVariableBuilder variable = variables[j];
-      bounds[j] = substituteRange(
-          bounds[j], substitution, nullSubstitution, null, null,
+      bounds[j] = substituteRange(bounds[j], substitution, nullSubstitution,
+          unboundTypes, unboundTypeVariables,
           variance: variable.variance);
     }
   }
@@ -709,6 +702,27 @@
   return issues;
 }
 
+/// Finds raw non-simple types in bounds of type variables in [typeBuilder].
+///
+/// Returns flattened list of triplets.  The first element of the triplet is the
+/// [TypeDeclarationBuilder] for the type variable from [variables] that has raw
+/// generic types with inbound references in its bound.  The second element of
+/// the triplet is the error message.  The third element is the context.
+List<Object> getInboundReferenceIssuesInType(TypeBuilder typeBuilder) {
+  List<FunctionTypeBuilder> genericFunctionTypeBuilders =
+      <FunctionTypeBuilder>[];
+  findUnaliasedGenericFunctionTypes(typeBuilder,
+      result: genericFunctionTypeBuilders);
+  List<Object> issues = <Object>[];
+  for (FunctionTypeBuilder genericFunctionTypeBuilder
+      in genericFunctionTypeBuilders) {
+    List<TypeVariableBuilder> typeVariables =
+        genericFunctionTypeBuilder.typeVariables;
+    issues.addAll(getInboundReferenceIssues(typeVariables));
+  }
+  return issues;
+}
+
 /// Finds raw type paths starting from those in [start] and ending with [end].
 ///
 /// Returns list of found paths.  Each path is represented as a list of
@@ -971,8 +985,38 @@
   }
 }
 
+/// Finds generic function type sub-terms in [type].
+void findUnaliasedGenericFunctionTypes(TypeBuilder type,
+    {List<FunctionTypeBuilder> result}) {
+  assert(result != null);
+  if (type is FunctionTypeBuilder) {
+    if (type.typeVariables != null && type.typeVariables.length > 0) {
+      result.add(type);
+
+      for (TypeVariableBuilder typeVariable in type.typeVariables) {
+        findUnaliasedGenericFunctionTypes(typeVariable.bound, result: result);
+        findUnaliasedGenericFunctionTypes(typeVariable.defaultType,
+            result: result);
+      }
+    }
+    findUnaliasedGenericFunctionTypes(type.returnType, result: result);
+    if (type.formals != null) {
+      for (FormalParameterBuilder formal in type.formals) {
+        findUnaliasedGenericFunctionTypes(formal.type, result: result);
+      }
+    }
+  } else if (type is NamedTypeBuilder) {
+    if (type.arguments != null) {
+      for (TypeBuilder argument in type.arguments) {
+        findUnaliasedGenericFunctionTypes(argument, result: result);
+      }
+    }
+  }
+}
+
+/// Finds generic function type sub-terms in [type] including the aliased ones.
 void findGenericFunctionTypes(TypeBuilder type, {List<TypeBuilder> result}) {
-  result ??= <TypeBuilder>[];
+  assert(result != null);
   if (type is FunctionTypeBuilder) {
     if (type.typeVariables != null && type.typeVariables.length > 0) {
       result.add(type);
@@ -1029,24 +1073,37 @@
     return false;
   }
 
+  @override
   bool visitInvalidType(InvalidType node) => false;
 
+  @override
   bool visitDynamicType(DynamicType node) => false;
 
+  @override
   bool visitVoidType(VoidType node) => false;
 
+  @override
   bool visitNeverType(NeverType node) => false;
 
+  @override
   bool visitNullType(NullType node) => false;
 
+  @override
   bool visitInterfaceType(InterfaceType node) {
     return anyTypeVariables(node.typeArguments);
   }
 
+  @override
+  bool visitExtensionType(ExtensionType node) {
+    return anyTypeVariables(node.typeArguments);
+  }
+
+  @override
   bool visitFutureOrType(FutureOrType node) {
     return node.typeArgument.accept(this);
   }
 
+  @override
   bool visitFunctionType(FunctionType node) {
     if (anyTypeVariables(node.positionalParameters)) return true;
     for (TypeParameter variable in node.typeParameters) {
@@ -1058,8 +1115,10 @@
     return false;
   }
 
+  @override
   bool visitTypeParameterType(TypeParameterType node) => true;
 
+  @override
   bool visitTypedefType(TypedefType node) {
     return anyTypeVariables(node.typeArguments);
   }
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 8735d07..f0e5030 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
@@ -9,26 +9,7 @@
 import 'package:_fe_analyzer_shared/src/parser/parser.dart'
     show FormalParameterKind;
 
-import 'package:kernel/ast.dart'
-    show
-        Class,
-        DartType,
-        DartTypeVisitor,
-        DynamicType,
-        FunctionType,
-        FutureOrType,
-        InterfaceType,
-        InvalidType,
-        Library,
-        NamedType,
-        NeverType,
-        NullType,
-        TreeNode,
-        TypeParameter,
-        TypeParameterType,
-        Typedef,
-        TypedefType,
-        VoidType;
+import 'package:kernel/ast.dart';
 
 import '../builder/class_builder.dart';
 import '../builder/dynamic_type_declaration_builder.dart';
@@ -131,6 +112,11 @@
   }
 
   @override
+  TypeBuilder visitExtensionType(ExtensionType node) {
+    throw "Not implemented";
+  }
+
+  @override
   TypeBuilder visitFutureOrType(FutureOrType node) {
     TypeBuilder argument = node.typeArgument.accept(this);
     return new NamedTypeBuilder(
diff --git a/pkg/front_end/lib/src/fasta/kernel/type_labeler.dart b/pkg/front_end/lib/src/fasta/kernel/type_labeler.dart
index 0b66c6e..e097eca 100644
--- a/pkg/front_end/lib/src/fasta/kernel/type_labeler.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/type_labeler.dart
@@ -6,45 +6,7 @@
 
 import 'dart:convert' show json;
 
-import 'package:kernel/ast.dart'
-    show
-        BoolConstant,
-        Class,
-        Constant,
-        ConstantMapEntry,
-        DartType,
-        DoubleConstant,
-        DynamicType,
-        Field,
-        FunctionType,
-        FutureOrType,
-        InvalidType,
-        InstanceConstant,
-        IntConstant,
-        InterfaceType,
-        Library,
-        ListConstant,
-        MapConstant,
-        NeverType,
-        NullConstant,
-        NullType,
-        Nullability,
-        PartialInstantiationConstant,
-        Procedure,
-        SetConstant,
-        StringConstant,
-        SymbolConstant,
-        TearOffConstant,
-        TreeNode,
-        Typedef,
-        TypedefType,
-        TypeLiteralConstant,
-        TypeParameter,
-        TypeParameterType,
-        UnevaluatedConstant,
-        VoidType;
-
-import 'package:kernel/visitor.dart' show ConstantVisitor, DartTypeVisitor;
+import 'package:kernel/ast.dart';
 
 import '../denylisted_classes.dart' show denylistedCoreClasses;
 
@@ -150,8 +112,8 @@
     result.add(nameForEntity(
         typedefNode,
         typedefNode.name,
-        typedefNode.enclosingLibrary.importUri,
-        typedefNode.enclosingLibrary.fileUri));
+        typedefNode?.enclosingLibrary?.importUri ?? unknownUri,
+        typedefNode?.enclosingLibrary?.fileUri ?? unknownUri));
     if (node.typeArguments.isNotEmpty) {
       result.add("<");
       bool first = true;
@@ -264,8 +226,10 @@
     result.add(nameForEntity(
         classNode,
         classNode.name,
-        classNode.enclosingLibrary.importUri,
-        classNode.enclosingLibrary.fileUri));
+        // TODO(johnniwinther): Ensure enclosing libraries on classes earlier
+        // in the compiler to ensure types in error messages have context.
+        classNode?.enclosingLibrary?.importUri ?? unknownUri,
+        classNode?.enclosingLibrary?.fileUri ?? unknownUri));
     if (node.typeArguments.isNotEmpty) {
       result.add("<");
       bool first = true;
@@ -286,6 +250,25 @@
     addNullability(node.declaredNullability);
   }
 
+  void visitExtensionType(ExtensionType node) {
+    result.add(nameForEntity(
+        node.extension,
+        node.extension.name,
+        node.extension?.enclosingLibrary?.importUri ?? unknownUri,
+        node.extension?.enclosingLibrary?.fileUri ?? unknownUri));
+    if (node.typeArguments.isNotEmpty) {
+      result.add("<");
+      bool first = true;
+      for (DartType typeArg in node.typeArguments) {
+        if (!first) result.add(", ");
+        typeArg.accept(this);
+        first = false;
+      }
+      result.add(">");
+    }
+    addNullability(node.declaredNullability);
+  }
+
   void defaultConstant(Constant node) {}
 
   void visitNullConstant(NullConstant node) {
diff --git a/pkg/front_end/lib/src/fasta/loader.dart b/pkg/front_end/lib/src/fasta/loader.dart
index 0652578..c7d3cbe 100644
--- a/pkg/front_end/lib/src/fasta/loader.dart
+++ b/pkg/front_end/lib/src/fasta/loader.dart
@@ -34,12 +34,21 @@
         noLength,
         SummaryTemplate,
         Template,
+        messageLanguageVersionInvalidInDotPackages,
         messagePlatformPrivateLibraryAccess,
         templateInternalProblemContextSeverity,
+        templateLanguageVersionTooHigh,
         templateSourceBodySummary;
 
 import 'problems.dart' show internalProblem, unhandled;
 
+import 'source/source_library_builder.dart' as src
+    show
+        LanguageVersion,
+        InvalidLanguageVersion,
+        ImplicitLanguageVersion,
+        SourceLibraryBuilder;
+
 import 'target_implementation.dart' show TargetImplementation;
 
 import 'ticker.dart' show Ticker;
@@ -144,9 +153,9 @@
         packageForLanguageVersion =
             target.uriTranslator.packages.packageOf(fileUri);
       }
-      bool hasPackageSpecifiedLanguageVersion = false;
-      Version version;
+      src.LanguageVersion packageLanguageVersion;
       Uri packageUri;
+      Message packageLanguageVersionProblem;
       if (packageForLanguageVersion != null) {
         Uri importUri = origin?.importUri ?? uri;
         if (importUri.scheme != 'dart' &&
@@ -156,24 +165,50 @@
               new Uri(scheme: 'package', path: packageForLanguageVersion.name);
         }
         if (packageForLanguageVersion.languageVersion != null) {
-          hasPackageSpecifiedLanguageVersion = true;
           if (packageForLanguageVersion.languageVersion
-              is! InvalidLanguageVersion) {
-            version = new Version(
+              is InvalidLanguageVersion) {
+            packageLanguageVersionProblem =
+                messageLanguageVersionInvalidInDotPackages;
+            packageLanguageVersion = new src.InvalidLanguageVersion(
+                fileUri, 0, noLength, target.currentSdkVersion, false);
+          } else {
+            Version version = new Version(
                 packageForLanguageVersion.languageVersion.major,
                 packageForLanguageVersion.languageVersion.minor);
+            if (version > target.currentSdkVersion) {
+              packageLanguageVersionProblem =
+                  templateLanguageVersionTooHigh.withArguments(
+                      target.currentSdkVersion.major,
+                      target.currentSdkVersion.minor);
+              packageLanguageVersion = new src.InvalidLanguageVersion(
+                  fileUri, 0, noLength, target.currentSdkVersion, false);
+            } else {
+              packageLanguageVersion = new src.ImplicitLanguageVersion(version);
+            }
           }
         }
       }
-      LibraryBuilder library = target.createLibraryBuilder(uri, fileUri,
-          packageUri, origin, referencesFrom, referenceIsPartOwner);
+      packageLanguageVersion ??=
+          new src.ImplicitLanguageVersion(target.currentSdkVersion);
+
+      LibraryBuilder library = target.createLibraryBuilder(
+          uri,
+          fileUri,
+          packageUri,
+          packageLanguageVersion,
+          origin,
+          referencesFrom,
+          referenceIsPartOwner);
       if (library == null) {
         throw new StateError("createLibraryBuilder for uri $uri, "
             "fileUri $fileUri returned null.");
       }
-      if (hasPackageSpecifiedLanguageVersion) {
-        library.setLanguageVersion(version, explicit: false);
+      if (packageLanguageVersionProblem != null &&
+          library is src.SourceLibraryBuilder) {
+        library.addPostponedProblem(
+            packageLanguageVersionProblem, 0, noLength, library.fileUri);
       }
+
       if (uri.scheme == "dart" && uri.path == "core") {
         coreLibrary = library;
       }
diff --git a/pkg/front_end/lib/src/fasta/problems.dart b/pkg/front_end/lib/src/fasta/problems.dart
index db9552f..cd06b1f 100644
--- a/pkg/front_end/lib/src/fasta/problems.dart
+++ b/pkg/front_end/lib/src/fasta/problems.dart
@@ -45,9 +45,10 @@
 ///
 /// Before printing the message, the string `"Internal error: "` is prepended.
 dynamic internalProblem(Message message, int charOffset, Uri uri) {
-  throw CompilerContext.current.format(
-      message.withLocation(uri, charOffset, noLength),
-      Severity.internalProblem);
+  throw CompilerContext.current
+      .format(message.withLocation(uri, charOffset, noLength),
+          Severity.internalProblem)
+      .plain;
 }
 
 dynamic unimplemented(String what, int charOffset, Uri uri) {
diff --git a/pkg/front_end/lib/src/fasta/source/diet_listener.dart b/pkg/front_end/lib/src/fasta/source/diet_listener.dart
index 2787514..c5664f8 100644
--- a/pkg/front_end/lib/src/fasta/source/diet_listener.dart
+++ b/pkg/front_end/lib/src/fasta/source/diet_listener.dart
@@ -18,17 +18,7 @@
 
 import 'package:_fe_analyzer_shared/src/scanner/token.dart' show Token;
 
-import 'package:kernel/ast.dart'
-    show
-        AsyncMarker,
-        Expression,
-        InterfaceType,
-        Library,
-        LibraryDependency,
-        LibraryPart,
-        TreeNode,
-        TypeParameter,
-        VariableDeclaration;
+import 'package:kernel/ast.dart';
 
 import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
 
@@ -277,12 +267,12 @@
 
     if (equals == null) pop(); // endToken
     Object name = pop();
-    Token metadata = pop();
+    // Metadata is handled in [SourceTypeAliasBuilder.buildOutlineExpressions].
+    pop(); // metadata
     checkEmpty(typedefKeyword.charOffset);
     if (name is ParserRecovery) return;
 
     TypeAliasBuilder typedefBuilder = lookupBuilder(typedefKeyword, null, name);
-    parseMetadata(typedefBuilder, metadata, typedefBuilder.typedef);
     if (typedefBuilder is TypeAliasBuilder) {
       TypeBuilder type = typedefBuilder.type;
       if (type is FunctionTypeBuilder) {
@@ -643,6 +633,11 @@
   }
 
   @override
+  void handleConstFactory(Token constKeyword) {
+    debugEvent("ConstFactory");
+  }
+
+  @override
   void handleNativeFunctionBody(Token nativeToken, Token semicolon) {
     debugEvent("NativeFunctionBody");
   }
@@ -1111,7 +1106,7 @@
   /// If the [metadata] is not `null`, return the parsed metadata [Expression]s.
   /// Otherwise, return `null`.
   List<Expression> parseMetadata(
-      ModifierBuilder builder, Token metadata, TreeNode parent) {
+      ModifierBuilder builder, Token metadata, Annotatable parent) {
     if (metadata != null) {
       StackListenerImpl listener = createListener(builder, memberScope,
           isDeclarationInstanceMember: false);
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 990f491..6e7b86a 100644
--- a/pkg/front_end/lib/src/fasta/source/outline_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/outline_builder.dart
@@ -575,8 +575,10 @@
     List<MetadataBuilder> metadata = pop();
     checkEmpty(beginToken.charOffset);
     if (name is ParserRecovery) {
-      libraryBuilder.endNestedDeclaration(
-          TypeParameterScopeKind.classDeclaration, "<syntax-error>");
+      libraryBuilder
+          .endNestedDeclaration(
+              TypeParameterScopeKind.classDeclaration, "<syntax-error>")
+          .resolveTypes(typeVariables, libraryBuilder);
       return;
     }
 
@@ -659,8 +661,10 @@
     List<MetadataBuilder> metadata = pop(NullValue.Metadata);
     checkEmpty(mixinToken.charOffset);
     if (name is ParserRecovery) {
-      libraryBuilder.endNestedDeclaration(
-          TypeParameterScopeKind.mixinDeclaration, "<syntax-error>");
+      libraryBuilder
+          .endNestedDeclaration(
+              TypeParameterScopeKind.mixinDeclaration, "<syntax-error>")
+          .resolveTypes(typeVariables, libraryBuilder);
       return;
     }
     int startOffset =
@@ -1255,8 +1259,10 @@
     List<MetadataBuilder> metadata = pop();
     checkEmpty(beginToken.charOffset);
     if (name is ParserRecovery || mixinApplication is ParserRecovery) {
-      libraryBuilder.endNestedDeclaration(
-          TypeParameterScopeKind.namedMixinApplication, "<syntax-error>");
+      libraryBuilder
+          .endNestedDeclaration(
+              TypeParameterScopeKind.namedMixinApplication, "<syntax-error>")
+          .resolveTypes(typeVariables, libraryBuilder);
       return;
     }
 
@@ -1608,6 +1614,7 @@
         typeVariables,
         formals,
         libraryBuilder.nullableBuilderIfTrue(questionMark != null),
+        uri,
         functionToken.charOffset));
   }
 
@@ -1621,8 +1628,13 @@
     if (!libraryBuilder.isNonNullableByDefault) {
       reportErrorIfNullableType(question);
     }
-    push(libraryBuilder.addFunctionType(returnType, typeVariables, formals,
-        libraryBuilder.nullableBuilderIfTrue(question != null), formalsOffset));
+    push(libraryBuilder.addFunctionType(
+        returnType,
+        typeVariables,
+        formals,
+        libraryBuilder.nullableBuilderIfTrue(question != null),
+        uri,
+        formalsOffset));
   }
 
   @override
@@ -1644,8 +1656,10 @@
       // `library.addFunctionType`.
       if (name is ParserRecovery) {
         pop(); // Metadata.
-        libraryBuilder.endNestedDeclaration(
-            TypeParameterScopeKind.typedef, "<syntax-error>");
+        libraryBuilder
+            .endNestedDeclaration(
+                TypeParameterScopeKind.typedef, "<syntax-error>")
+            .resolveTypes(typeVariables, libraryBuilder);
         return;
       }
       libraryBuilder.beginNestedDeclaration(
@@ -1653,7 +1667,7 @@
           hasMembers: false);
       // TODO(dmitryas): Make sure that RHS of typedefs can't have '?'.
       aliasedType = libraryBuilder.addFunctionType(returnType, null, formals,
-          const NullabilityBuilder.omitted(), charOffset);
+          const NullabilityBuilder.omitted(), uri, charOffset);
     } else {
       Object type = pop();
       typeVariables = pop();
@@ -1661,8 +1675,10 @@
       name = pop();
       if (name is ParserRecovery) {
         pop(); // Metadata.
-        libraryBuilder.endNestedDeclaration(
-            TypeParameterScopeKind.functionType, "<syntax-error>");
+        libraryBuilder
+            .endNestedDeclaration(
+                TypeParameterScopeKind.functionType, "<syntax-error>")
+            .resolveTypes(typeVariables, libraryBuilder);
         return;
       }
       if (type is FunctionTypeBuilder &&
@@ -1833,13 +1849,12 @@
     debugEvent("beginTypeVariable");
     int charOffset = pop();
     Object name = pop();
-    // TODO(paulberry): type variable metadata should not be ignored.  See
-    // dartbug.com/28981.
-    /* List<MetadataBuilder<TypeBuilder>> metadata = */ pop();
+    List<MetadataBuilder> metadata = pop();
     if (name is ParserRecovery) {
       push(name);
     } else {
-      push(libraryBuilder.addTypeVariable(name, null, charOffset));
+      push(libraryBuilder.addTypeVariable(
+          metadata, name, null, charOffset, uri));
     }
   }
 
@@ -2030,6 +2045,14 @@
   }
 
   @override
+  void handleConstFactory(Token constKeyword) {
+    debugEvent("ConstFactory");
+    if (!libraryBuilder.enableConstFunctionsInLibrary) {
+      handleRecoverableError(messageConstFactory, constKeyword, constKeyword);
+    }
+  }
+
+  @override
   void endFieldInitializer(Token assignmentOperator, Token token) {
     debugEvent("FieldInitializer");
     Token beforeLast = assignmentOperator.next;
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 3017856..bf02502 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
@@ -589,8 +589,11 @@
       if (declarationBuilder is TypeAliasBuilder) {
         TypeAliasBuilder aliasBuilder = declarationBuilder;
         NamedTypeBuilder namedBuilder = supertype;
-        declarationBuilder =
-            aliasBuilder.unaliasDeclaration(namedBuilder.arguments);
+        declarationBuilder = aliasBuilder.unaliasDeclaration(
+            namedBuilder.arguments,
+            isUsedAsClass: true,
+            usedAsClassCharOffset: namedBuilder.charOffset,
+            usedAsClassFileUri: namedBuilder.fileUri);
         result[declarationBuilder] = aliasBuilder;
       } else {
         result[declarationBuilder] = null;
@@ -606,8 +609,11 @@
         if (declarationBuilder is TypeAliasBuilder) {
           TypeAliasBuilder aliasBuilder = declarationBuilder;
           NamedTypeBuilder namedBuilder = interface;
-          declarationBuilder =
-              aliasBuilder.unaliasDeclaration(namedBuilder.arguments);
+          declarationBuilder = aliasBuilder.unaliasDeclaration(
+              namedBuilder.arguments,
+              isUsedAsClass: true,
+              usedAsClassCharOffset: namedBuilder.charOffset,
+              usedAsClassFileUri: namedBuilder.fileUri);
           result[declarationBuilder] = aliasBuilder;
         } else {
           result[declarationBuilder] = null;
@@ -621,8 +627,11 @@
       if (declarationBuilder is TypeAliasBuilder) {
         TypeAliasBuilder aliasBuilder = declarationBuilder;
         NamedTypeBuilder namedBuilder = mixedInTypeBuilder;
-        declarationBuilder =
-            aliasBuilder.unaliasDeclaration(namedBuilder.arguments);
+        declarationBuilder = aliasBuilder.unaliasDeclaration(
+            namedBuilder.arguments,
+            isUsedAsClass: true,
+            usedAsClassCharOffset: namedBuilder.charOffset,
+            usedAsClassFileUri: namedBuilder.fileUri);
         result[declarationBuilder] = aliasBuilder;
       } else {
         result[declarationBuilder] = null;
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 a8d620c..264a65f 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
@@ -5,6 +5,7 @@
 // @dart = 2.9
 
 import 'package:kernel/ast.dart';
+import 'package:kernel/core_types.dart';
 import 'package:kernel/type_environment.dart';
 
 import '../../base/common.dart';
@@ -31,6 +32,8 @@
 
 import '../scope.dart';
 
+import '../util/helpers.dart';
+
 import 'source_library_builder.dart';
 
 const String extensionThisName = '#this';
@@ -258,4 +261,25 @@
       }
     });
   }
+
+  @override
+  void buildOutlineExpressions(LibraryBuilder library, CoreTypes coreTypes,
+      List<DelayedActionPerformer> delayedActionPerformers) {
+    MetadataBuilder.buildAnnotations(isPatch ? origin.extension : extension,
+        metadata, library, this, null, fileUri);
+    if (typeParameters != null) {
+      for (int i = 0; i < typeParameters.length; i++) {
+        typeParameters[i].buildOutlineExpressions(
+            library, this, null, coreTypes, delayedActionPerformers);
+      }
+    }
+
+    void build(String ignore, Builder declaration) {
+      MemberBuilder member = declaration;
+      member.buildOutlineExpressions(
+          library, coreTypes, delayedActionPerformers);
+    }
+
+    scope.forEach(build);
+  }
 }
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 e409ff0..097bde3 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
@@ -8,8 +8,6 @@
 
 import 'dart:convert' show jsonEncode;
 
-import 'package:_fe_analyzer_shared/src/messages/severity.dart' show Severity;
-
 import 'package:_fe_analyzer_shared/src/scanner/token.dart' show Token;
 
 import 'package:_fe_analyzer_shared/src/util/resolve_relative_uri.dart'
@@ -98,6 +96,7 @@
         calculateBounds,
         computeTypeVariableBuilderVariance,
         findGenericFunctionTypes,
+        getInboundReferenceIssuesInType,
         getNonSimplicityIssuesForDeclaration,
         getNonSimplicityIssuesForTypeVariables,
         pendingVariance;
@@ -190,6 +189,9 @@
   final List<TypeVariableBuilder> boundlessTypeVariables =
       <TypeVariableBuilder>[];
 
+  final List<UncheckedTypedefType> uncheckedTypedefTypes =
+      <UncheckedTypedefType>[];
+
   // A list of alternating forwarders and the procedures they were generated
   // for.  Note that it may not include a forwarder-origin pair in cases when
   // the former does not need to be updated after the body of the latter was
@@ -205,7 +207,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 = <TypeParameterType>[];
+  final List<PendingNullability> _pendingNullabilities = <PendingNullability>[];
 
   // 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
@@ -230,6 +232,17 @@
 
   List<FieldBuilder> _implicitlyTypedFields;
 
+  /// The language version of this library as defined by the language version
+  /// of the package it belongs to, if present, or the current language version
+  /// otherwise.
+  ///
+  /// This language version we be used as the language version for the library
+  /// if the library does not contain an explicit @dart= annotation.
+  final LanguageVersion packageLanguageVersion;
+
+  /// The actual language version of this library. This is initially the
+  /// [packageLanguageVersion] but will be updated if the library contains
+  /// an explicit @dart= language version annotation.
   LanguageVersion _languageVersion;
 
   bool postponedProblemsIssued = false;
@@ -246,6 +259,7 @@
       SourceLoader loader,
       Uri fileUri,
       Uri packageUri,
+      LanguageVersion packageLanguageVersion,
       Scope scope,
       SourceLibraryBuilder actualOrigin,
       Library library,
@@ -256,6 +270,7 @@
             loader,
             fileUri,
             packageUri,
+            packageLanguageVersion,
             new TypeParameterScopeBuilder.library(),
             scope ?? new Scope.top(),
             actualOrigin,
@@ -267,13 +282,14 @@
       this.loader,
       this.fileUri,
       this._packageUri,
+      this.packageLanguageVersion,
       this.libraryDeclaration,
       this.importScope,
       this.actualOrigin,
       this.library,
       this._nameOrigin,
       this.referencesFrom)
-      : _languageVersion = new ImplicitLanguageVersion(library.languageVersion),
+      : _languageVersion = packageLanguageVersion,
         currentTypeParameterScopeBuilder = libraryDeclaration,
         referencesFromIndexed =
             referencesFrom == null ? null : new IndexedLibrary(referencesFrom),
@@ -302,17 +318,21 @@
   bool _enableExtensionTypesInLibrary;
 
   bool get enableConstFunctionsInLibrary => _enableConstFunctionsInLibrary ??=
-      loader.target.isExperimentEnabledInLibrary(
-          ExperimentalFlag.constFunctions, _packageUri ?? importUri);
+      loader.target.isExperimentEnabledInLibraryByVersion(
+          ExperimentalFlag.constFunctions,
+          _packageUri ?? importUri,
+          languageVersion.version);
 
-  bool get enableVarianceInLibrary =>
-      _enableVarianceInLibrary ??= loader.target.isExperimentEnabledInLibrary(
-          ExperimentalFlag.variance, _packageUri ?? importUri);
+  bool get enableVarianceInLibrary => _enableVarianceInLibrary ??= loader.target
+      .isExperimentEnabledInLibraryByVersion(ExperimentalFlag.variance,
+          _packageUri ?? importUri, languageVersion.version);
 
   bool get enableNonfunctionTypeAliasesInLibrary =>
       _enableNonfunctionTypeAliasesInLibrary ??= loader.target
-          .isExperimentEnabledInLibrary(ExperimentalFlag.nonfunctionTypeAliases,
-              _packageUri ?? importUri);
+          .isExperimentEnabledInLibraryByVersion(
+              ExperimentalFlag.nonfunctionTypeAliases,
+              _packageUri ?? importUri,
+              languageVersion.version);
 
   /// Returns `true` if the 'non-nullable' experiment is enabled for this
   /// library.
@@ -330,46 +350,54 @@
               ExperimentalFlag.nonNullable, _packageUri ?? importUri);
 
   bool get enableTripleShiftInLibrary => _enableTripleShiftInLibrary ??=
-      loader.target.isExperimentEnabledInLibrary(
-          ExperimentalFlag.tripleShift, _packageUri ?? importUri);
+      loader.target.isExperimentEnabledInLibraryByVersion(
+          ExperimentalFlag.tripleShift,
+          _packageUri ?? importUri,
+          languageVersion.version);
 
   bool get enableExtensionMethodsInLibrary =>
       _enableExtensionMethodsInLibrary ??= loader.target
-          .isExperimentEnabledInLibrary(
-              ExperimentalFlag.extensionMethods, _packageUri ?? importUri);
+          .isExperimentEnabledInLibraryByVersion(
+              ExperimentalFlag.extensionMethods,
+              _packageUri ?? importUri,
+              languageVersion.version);
 
   bool get enableGenericMetadataInLibrary => _enableGenericMetadataInLibrary ??=
-      loader.target.isExperimentEnabledInLibrary(
-          ExperimentalFlag.genericMetadata, _packageUri ?? importUri);
+      loader.target.isExperimentEnabledInLibraryByVersion(
+          ExperimentalFlag.genericMetadata,
+          _packageUri ?? importUri,
+          languageVersion.version);
 
   bool get enableExtensionTypesInLibrary => _enableExtensionTypesInLibrary ??=
-      loader.target.isExperimentEnabledInLibrary(
-          ExperimentalFlag.extensionTypes, _packageUri ?? importUri);
+      loader.target.isExperimentEnabledInLibraryByVersion(
+          ExperimentalFlag.extensionTypes,
+          _packageUri ?? importUri,
+          languageVersion.version);
 
-  void updateLibraryNNBDSettings() {
+  void _updateLibraryNNBDSettings() {
     library.isNonNullableByDefault = isNonNullableByDefault;
-    if (enableNonNullableInLibrary) {
-      switch (loader.nnbdMode) {
-        case NnbdMode.Weak:
-          library.nonNullableByDefaultCompiledMode =
-              NonNullableByDefaultCompiledMode.Weak;
-          break;
-        case NnbdMode.Strong:
-          library.nonNullableByDefaultCompiledMode =
-              NonNullableByDefaultCompiledMode.Strong;
-          break;
-        case NnbdMode.Agnostic:
-          library.nonNullableByDefaultCompiledMode =
-              NonNullableByDefaultCompiledMode.Agnostic;
-          break;
-      }
-    } else {
-      library.nonNullableByDefaultCompiledMode =
-          NonNullableByDefaultCompiledMode.Weak;
+    switch (loader.nnbdMode) {
+      case NnbdMode.Weak:
+        library.nonNullableByDefaultCompiledMode =
+            NonNullableByDefaultCompiledMode.Weak;
+        break;
+      case NnbdMode.Strong:
+        library.nonNullableByDefaultCompiledMode =
+            NonNullableByDefaultCompiledMode.Strong;
+        break;
+      case NnbdMode.Agnostic:
+        library.nonNullableByDefaultCompiledMode =
+            NonNullableByDefaultCompiledMode.Agnostic;
+        break;
     }
   }
 
-  SourceLibraryBuilder(Uri uri, Uri fileUri, Uri packageUri, Loader loader,
+  SourceLibraryBuilder(
+      Uri uri,
+      Uri fileUri,
+      Uri packageUri,
+      LanguageVersion packageLanguageVersion,
+      Loader loader,
       SourceLibraryBuilder actualOrigin,
       {Scope scope,
       Library target,
@@ -380,6 +408,7 @@
             loader,
             fileUri,
             packageUri,
+            packageLanguageVersion,
             scope,
             actualOrigin,
             target ??
@@ -389,7 +418,7 @@
                         reference: referenceIsPartOwner == true
                             ? null
                             : referencesFrom?.reference)
-                  ..setLanguageVersion(loader.target.currentSdkVersion)),
+                  ..setLanguageVersion(packageLanguageVersion.version)),
             nameOrigin,
             referencesFrom,
             referenceIsPartOwner);
@@ -424,7 +453,7 @@
   bool _ensureIsNonNullableByDefault() {
     if (_isNonNullableByDefault == null) {
       _isNonNullableByDefault = _computeIsNonNullableByDefault();
-      updateLibraryNNBDSettings();
+      _updateLibraryNNBDSettings();
     }
     return _isNonNullableByDefault;
   }
@@ -457,9 +486,17 @@
     'vm/dart_2/', // in runtime/tests
   ];
 
-  LanguageVersion get languageVersion => _languageVersion;
+  LanguageVersion get languageVersion {
+    assert(
+        _languageVersion.isFinal,
+        "Attempting to read the language version of ${this} before has been "
+        "finalized.");
+    return _languageVersion;
+  }
 
   void markLanguageVersionFinal() {
+    _languageVersion.isFinal = true;
+    _ensureIsNonNullableByDefault();
     if (!isNonNullableByDefault &&
         (loader.nnbdMode == NnbdMode.Strong ||
             loader.nnbdMode == NnbdMode.Agnostic)) {
@@ -475,32 +512,29 @@
           NonNullableByDefaultCompiledMode.Invalid;
       loader.hasInvalidNnbdModeLibrary = true;
     }
-    _languageVersion.isFinal = true;
-    _ensureIsNonNullableByDefault();
   }
 
-  @override
-  void setLanguageVersion(Version version,
-      {int offset: 0, int length: noLength, bool explicit: false}) {
-    assert(!_languageVersion.isFinal);
-    if (languageVersion.isExplicit) return;
-
-    if (version == null) {
-      addPostponedProblem(
-          messageLanguageVersionInvalidInDotPackages, offset, length, fileUri);
-      if (_languageVersion is ImplicitLanguageVersion) {
-        // If the package set an OK version, but the file set an invalid version
-        // we want to use the package version.
-        _languageVersion = new InvalidLanguageVersion(
-            fileUri, offset, length, explicit, loader.target.currentSdkVersion);
-        library.setLanguageVersion(_languageVersion.version);
-      }
+  /// Set the language version to an explicit major and minor version.
+  ///
+  /// The default language version specified by the .packages file is passed
+  /// to the constructor, but the library can have source code that specifies
+  /// another one which should be supported.
+  ///
+  /// Only the first registered language version is used.
+  ///
+  /// [offset] and [length] refers to the offset and length of the source code
+  /// specifying the language version.
+  void registerExplicitLanguageVersion(Version version,
+      {int offset: 0, int length: noLength}) {
+    if (_languageVersion.isExplicit) {
+      // If more than once language version exists we use the first.
       return;
     }
+    assert(!_languageVersion.isFinal);
 
-    // If trying to set a language version that is higher than the current sdk
-    // version it's an error.
     if (version > loader.target.currentSdkVersion) {
+      // If trying to set a language version that is higher than the current sdk
+      // version it's an error.
       addPostponedProblem(
           templateLanguageVersionTooHigh.withArguments(
               loader.target.currentSdkVersion.major,
@@ -508,19 +542,15 @@
           offset,
           length,
           fileUri);
-      if (_languageVersion is ImplicitLanguageVersion) {
-        // If the package set an OK version, but the file set an invalid version
-        // we want to use the package version.
-        _languageVersion = new InvalidLanguageVersion(
-            fileUri, offset, length, explicit, loader.target.currentSdkVersion);
-        library.setLanguageVersion(_languageVersion.version);
-      }
-      return;
+      // If the package set an OK version, but the file set an invalid version
+      // we want to use the package version.
+      _languageVersion = new InvalidLanguageVersion(
+          fileUri, offset, length, packageLanguageVersion.version, true);
+    } else {
+      _languageVersion = new LanguageVersion(version, fileUri, offset, length);
     }
-
-    _languageVersion =
-        new LanguageVersion(version, fileUri, offset, length, explicit);
-    library.setLanguageVersion(version);
+    library.setLanguageVersion(_languageVersion.version);
+    _languageVersion.isFinal = true;
   }
 
   ConstructorReferenceBuilder addConstructorReference(Object name,
@@ -2527,10 +2557,21 @@
       List<TypeVariableBuilder> typeVariables,
       List<FormalParameterBuilder> formals,
       NullabilityBuilder nullabilityBuilder,
+      Uri fileUri,
       int charOffset) {
     FunctionTypeBuilder builder = new FunctionTypeBuilder(returnType,
         typeVariables, formals, nullabilityBuilder, fileUri, charOffset);
     checkTypeVariables(typeVariables, null);
+    if (typeVariables != null) {
+      for (TypeVariableBuilder builder in typeVariables) {
+        if (builder.metadata != null) {
+          if (!enableGenericMetadataInLibrary) {
+            addProblem(messageAnnotationOnFunctionTypeTypeVariable,
+                builder.charOffset, builder.name.length, builder.fileUri);
+          }
+        }
+      }
+    }
     // Nested declaration began in `OutlineBuilder.beginFunctionType` or
     // `OutlineBuilder.beginFunctionTypedFormalParameter`.
     endNestedDeclaration(TypeParameterScopeKind.functionType, "#function_type")
@@ -2557,17 +2598,19 @@
     return formal;
   }
 
-  TypeVariableBuilder addTypeVariable(
-      String name, TypeBuilder bound, int charOffset) {
-    TypeVariableBuilder builder =
-        new TypeVariableBuilder(name, this, charOffset, bound: bound);
+  TypeVariableBuilder addTypeVariable(List<MetadataBuilder> metadata,
+      String name, TypeBuilder bound, int charOffset, Uri fileUri) {
+    TypeVariableBuilder builder = new TypeVariableBuilder(
+        name, this, charOffset, fileUri,
+        bound: bound, metadata: metadata);
     boundlessTypeVariables.add(builder);
     return builder;
   }
 
   @override
   void buildOutlineExpressions() {
-    MetadataBuilder.buildAnnotations(library, metadata, this, null, null);
+    MetadataBuilder.buildAnnotations(
+        library, metadata, this, null, null, fileUri);
   }
 
   /// Builds the core AST structures for [declaration] needed for the outline.
@@ -2867,7 +2910,7 @@
     List<TypeVariableBuilder> copy = <TypeVariableBuilder>[];
     for (TypeVariableBuilder variable in original) {
       TypeVariableBuilder newVariable = new TypeVariableBuilder(
-          variable.name, this, variable.charOffset,
+          variable.name, this, variable.charOffset, variable.fileUri,
           bound: variable.bound?.clone(newTypes),
           isExtensionTypeParameter: isExtensionTypeParameter,
           variableVariance:
@@ -2891,22 +2934,95 @@
     }
     boundlessTypeVariables.clear();
 
-    TypeVariableBuilder.finishNullabilities(this, pendingNullabilities);
-    pendingNullabilities.clear();
+    processPendingNullabilities();
 
     return count;
   }
 
+  /// Assigns nullabilities to types in [_pendingNullabilities].
+  ///
+  /// It's a helper function to assign the nullabilities to type-parameter types
+  /// after the corresponding type parameters have their bounds set or changed.
+  /// The function takes into account that some of the types in the input list
+  /// may be bounds to some of the type parameters of other types from the input
+  /// list.
+  void processPendingNullabilities() {
+    // The bounds of type parameters may be type-parameter types of other
+    // parameters from the same declaration.  In this case we need to set the
+    // nullability for them first.  To preserve the ordering, we implement a
+    // depth-first search over the types.  We use the fact that a nullability
+    // of a type parameter type can't ever be 'nullable' if computed from the
+    // bound. It allows us to use 'nullable' nullability as the marker in the
+    // DFS implementation.
+    Nullability marker = Nullability.nullable;
+    List<TypeParameterType> stack =
+        new List<TypeParameterType>.filled(_pendingNullabilities.length, null);
+    int stackTop = 0;
+    for (PendingNullability pendingNullability in _pendingNullabilities) {
+      pendingNullability.type.declaredNullability = null;
+    }
+    for (PendingNullability pendingNullability in _pendingNullabilities) {
+      TypeParameterType type = pendingNullability.type;
+      if (type.declaredNullability != null) {
+        // Nullability for [type] was already computed on one of the branches
+        // of the depth-first search.  Continue to the next one.
+        continue;
+      }
+      if (type.parameter.bound is TypeParameterType) {
+        TypeParameterType current = type;
+        TypeParameterType next = current.parameter.bound;
+        while (next != null && next.declaredNullability == null) {
+          stack[stackTop++] = current;
+          current.declaredNullability = marker;
+
+          current = next;
+          if (current.parameter.bound is TypeParameterType) {
+            next = current.parameter.bound;
+            if (next.declaredNullability == marker) {
+              next.declaredNullability = Nullability.undetermined;
+              current.parameter.bound = const InvalidType();
+              current.parameter.defaultType = const InvalidType();
+              addProblem(
+                  templateCycleInTypeVariables.withArguments(
+                      next.parameter.name, current.parameter.name),
+                  pendingNullability.charOffset,
+                  next.parameter.name.length,
+                  pendingNullability.fileUri);
+              next = null;
+            }
+          } else {
+            next = null;
+          }
+        }
+        current.declaredNullability =
+            TypeParameterType.computeNullabilityFromBound(current.parameter);
+        while (stackTop != 0) {
+          --stackTop;
+          current = stack[stackTop];
+          current.declaredNullability =
+              TypeParameterType.computeNullabilityFromBound(current.parameter);
+        }
+      } else {
+        type.declaredNullability =
+            TypeParameterType.computeNullabilityFromBound(type.parameter);
+      }
+    }
+    _pendingNullabilities.clear();
+  }
+
   int computeVariances() {
     int count = 0;
     for (Builder declaration in libraryDeclaration.members.values) {
-      if (declaration is TypeAliasBuilder &&
-          declaration.typeVariablesCount > 0) {
-        for (TypeVariableBuilder typeParameter in declaration.typeVariables) {
-          typeParameter.variance = computeTypeVariableBuilderVariance(
-              typeParameter, declaration.type, this);
-          ++count;
+      while (declaration != null) {
+        if (declaration is TypeAliasBuilder &&
+            declaration.typeVariablesCount > 0) {
+          for (TypeVariableBuilder typeParameter in declaration.typeVariables) {
+            typeParameter.variance = computeTypeVariableBuilderVariance(
+                typeParameter, declaration.type, this);
+            ++count;
+          }
         }
+        declaration = declaration.next;
       }
     }
     return count;
@@ -2937,11 +3053,20 @@
         }
 
         if (!haveErroneousBounds) {
+          List<TypeBuilder> unboundTypes = [];
+          List<TypeVariableBuilder> unboundTypeVariables = [];
           List<TypeBuilder> calculatedBounds = calculateBounds(
               variables,
               dynamicType,
               isNonNullableByDefault ? bottomType : nullType,
-              objectClass);
+              objectClass,
+              unboundTypes: unboundTypes,
+              unboundTypeVariables: unboundTypeVariables);
+          for (TypeBuilder unboundType in unboundTypes) {
+            currentTypeParameterScopeBuilder
+                .addType(new UnresolvedType(unboundType, -1, null));
+          }
+          boundlessTypeVariables.addAll(unboundTypeVariables);
           for (int i = 0; i < variables.length; ++i) {
             variables[i].defaultType = calculatedBounds[i];
           }
@@ -2981,6 +3106,7 @@
               inErrorRecovery: issues.isNotEmpty);
 
           declaration.constructors.forEach((String name, Builder member) {
+            List<FormalParameterBuilder> formals;
             if (member is ProcedureBuilder) {
               assert(member.isFactory,
                   "Unexpected constructor member (${member.runtimeType}).");
@@ -2988,9 +3114,18 @@
                   // Type variables are inherited from the class so if the class
                   // has issues, so does the factory constructors.
                   inErrorRecovery: issues.isNotEmpty);
+              formals = member.formals;
             } else {
               assert(member is ConstructorBuilder,
                   "Unexpected constructor member (${member.runtimeType}).");
+              formals = (member as ConstructorBuilder).formals;
+            }
+            if (formals != null && formals.isNotEmpty) {
+              for (FormalParameterBuilder formal in formals) {
+                List<Object> issues =
+                    getInboundReferenceIssuesInType(formal.type);
+                reportIssues(issues);
+              }
             }
           });
         }
@@ -2998,23 +3133,46 @@
           if (member is ProcedureBuilder) {
             List<Object> issues =
                 getNonSimplicityIssuesForTypeVariables(member.typeVariables);
+            if (member.formals != null && member.formals.isNotEmpty) {
+              for (FormalParameterBuilder formal in member.formals) {
+                issues.addAll(getInboundReferenceIssuesInType(formal.type));
+              }
+            }
+            if (member.returnType != null) {
+              issues.addAll(getInboundReferenceIssuesInType(member.returnType));
+            }
             reportIssues(issues);
             count += computeDefaultTypesForVariables(member.typeVariables,
                 inErrorRecovery: issues.isNotEmpty);
           } else {
             assert(member is FieldBuilder,
                 "Unexpected class member $member (${member.runtimeType}).");
+            TypeBuilder fieldType = (member as FieldBuilder).type;
+            if (fieldType != null) {
+              List<Object> issues = getInboundReferenceIssuesInType(fieldType);
+              reportIssues(issues);
+            }
           }
         });
       } else if (declaration is TypeAliasBuilder) {
         List<Object> issues = getNonSimplicityIssuesForDeclaration(declaration,
             performErrorRecovery: true);
+        issues.addAll(getInboundReferenceIssuesInType(declaration.type));
         reportIssues(issues);
         count += computeDefaultTypesForVariables(declaration.typeVariables,
             inErrorRecovery: issues.isNotEmpty);
       } else if (declaration is FunctionBuilder) {
         List<Object> issues =
             getNonSimplicityIssuesForTypeVariables(declaration.typeVariables);
+        if (declaration.formals != null && declaration.formals.isNotEmpty) {
+          for (FormalParameterBuilder formal in declaration.formals) {
+            issues.addAll(getInboundReferenceIssuesInType(formal.type));
+          }
+        }
+        if (declaration.returnType != null) {
+          issues
+              .addAll(getInboundReferenceIssuesInType(declaration.returnType));
+        }
         reportIssues(issues);
         count += computeDefaultTypesForVariables(declaration.typeVariables,
             inErrorRecovery: issues.isNotEmpty);
@@ -3031,6 +3189,14 @@
           if (member is ProcedureBuilder) {
             List<Object> issues =
                 getNonSimplicityIssuesForTypeVariables(member.typeVariables);
+            if (member.formals != null && member.formals.isNotEmpty) {
+              for (FormalParameterBuilder formal in member.formals) {
+                issues.addAll(getInboundReferenceIssuesInType(formal.type));
+              }
+            }
+            if (member.returnType != null) {
+              issues.addAll(getInboundReferenceIssuesInType(member.returnType));
+            }
             reportIssues(issues);
             count += computeDefaultTypesForVariables(member.typeVariables,
                 inErrorRecovery: issues.isNotEmpty);
@@ -3039,16 +3205,34 @@
                 "Unexpected extension member $member (${member.runtimeType}).");
           }
         });
+      } else if (declaration is FieldBuilder) {
+        if (declaration.type != null) {
+          List<Object> issues =
+              getInboundReferenceIssuesInType(declaration.type);
+          reportIssues(issues);
+        }
       } else {
         assert(
-            declaration is FieldBuilder ||
-                declaration is PrefixBuilder ||
+            declaration is PrefixBuilder ||
                 declaration is DynamicTypeDeclarationBuilder ||
                 declaration is NeverTypeDeclarationBuilder,
             "Unexpected top level member $declaration "
             "(${declaration.runtimeType}).");
       }
     }
+    for (Builder declaration in libraryDeclaration.setters.values) {
+      assert(
+          declaration is ProcedureBuilder,
+          "Expected setter to be a ProcedureBuilder, "
+          "but got '${declaration.runtimeType}'");
+      if (declaration is ProcedureBuilder &&
+          declaration.formals != null &&
+          declaration.formals.isNotEmpty) {
+        for (FormalParameterBuilder formal in declaration.formals) {
+          reportIssues(getInboundReferenceIssuesInType(formal.type));
+        }
+      }
+    }
 
     return count;
   }
@@ -3655,6 +3839,41 @@
         targetName: name.text);
   }
 
+  void checkBoundsInFunctionInvocation(
+      TypeEnvironment typeEnvironment,
+      ClassHierarchy hierarchy,
+      TypeInferrerImpl typeInferrer,
+      FunctionType functionType,
+      String localName,
+      Arguments arguments,
+      Uri fileUri,
+      int offset) {
+    if (arguments.types.isEmpty) return;
+
+    List<TypeParameter> functionTypeParameters = functionType.typeParameters;
+    // The error is to be reported elsewhere.
+    if (functionTypeParameters.length != arguments.types.length) return;
+    final DartType bottomType = isNonNullableByDefault
+        ? const NeverType.nonNullable()
+        : const NullType();
+    List<TypeArgumentIssue> issues = findTypeArgumentIssuesForInvocation(
+        functionTypeParameters,
+        arguments.types,
+        typeEnvironment,
+        isNonNullableByDefault
+            ? SubtypeCheckMode.withNullabilities
+            : SubtypeCheckMode.ignoringNullabilities,
+        bottomType,
+        isNonNullableByDefault: library.isNonNullableByDefault,
+        areGenericArgumentsAllowed: enableGenericMetadataInLibrary);
+    reportTypeArgumentIssues(issues, fileUri, offset,
+        typeArgumentsInfo: getTypeArgumentsInfo(arguments),
+        // TODO(johnniwinther): Special-case messaging on function type
+        //  invocation to avoid reference to 'call' and use the function type
+        //  instead.
+        targetName: localName ?? 'call');
+  }
+
   void checkTypesInOutline(TypeEnvironment typeEnvironment) {
     Iterator<Builder> iterator = this.iterator;
     while (iterator.moveNext()) {
@@ -3685,6 +3904,7 @@
       }
     }
     inferredTypes.clear();
+    checkUncheckedTypedefTypes(typeEnvironment);
   }
 
   void registerImplicitlyTypedField(FieldBuilder fieldBuilder) {
@@ -3730,6 +3950,27 @@
           referencesFromIndexed.lookupIndexedClass(name);
     }
   }
+
+  void registerPendingNullability(
+      Uri fileUri, int charOffset, TypeParameterType type) {
+    _pendingNullabilities
+        .add(new PendingNullability(fileUri, charOffset, type));
+  }
+
+  /// Performs delayed bounds checks on [TypedefType]s for the library
+  ///
+  /// As [TypedefType]s are built, they are eagerly unaliased, making it
+  /// impossible to perform the bounds checks on them at the time when the
+  /// checks can be done. To perform the checks, [TypedefType]s are added to
+  /// [uncheckedTypedefTypes] as they are built.  This method performs the
+  /// checks and clears the list of the types for the delayed check.
+  void checkUncheckedTypedefTypes(TypeEnvironment typeEnvironment) {
+    for (UncheckedTypedefType uncheckedTypedefType in uncheckedTypedefTypes) {
+      checkBoundsInType(uncheckedTypedefType.typeToCheck, typeEnvironment,
+          uncheckedTypedefType.fileUri, uncheckedTypedefType.offset);
+    }
+    uncheckedTypedefTypes.clear();
+  }
 }
 
 // The kind of type parameter scope built by a [TypeParameterScopeBuilder]
@@ -4032,11 +4273,11 @@
   final Uri fileUri;
   final int charOffset;
   final int charCount;
-  final bool isExplicit;
   bool isFinal = false;
 
-  LanguageVersion(this.version, this.fileUri, this.charOffset, this.charCount,
-      this.isExplicit);
+  LanguageVersion(this.version, this.fileUri, this.charOffset, this.charCount);
+
+  bool get isExplicit => true;
 
   bool get valid => true;
 
@@ -4059,12 +4300,12 @@
   final Uri fileUri;
   final int charOffset;
   final int charCount;
-  final bool isExplicit;
   final Version version;
+  final bool isExplicit;
   bool isFinal = false;
 
   InvalidLanguageVersion(this.fileUri, this.charOffset, this.charCount,
-      this.isExplicit, this.version);
+      this.version, this.isExplicit);
 
   @override
   bool get valid => false;
@@ -4188,3 +4429,22 @@
     }
   }
 }
+
+class PendingNullability {
+  final Uri fileUri;
+  final int charOffset;
+  final TypeParameterType type;
+
+  PendingNullability(this.fileUri, this.charOffset, this.type);
+}
+
+class UncheckedTypedefType {
+  final TypedefType typeToCheck;
+
+  // TODO(dmitryas): Make these fields nullable when the library is opted-in to
+  // NNBD.
+  int offset;
+  Uri fileUri;
+
+  UncheckedTypedefType(this.typeToCheck);
+}
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 1405152..29a3626 100644
--- a/pkg/front_end/lib/src/fasta/source/source_loader.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_loader.dart
@@ -25,7 +25,6 @@
         ScannerResult,
         Token,
         scan;
-import 'package:front_end/src/api_prototype/experimental_flags.dart';
 
 import 'package:kernel/ast.dart'
     show
@@ -59,6 +58,7 @@
 
 import 'package:package_config/package_config.dart';
 
+import '../../api_prototype/experimental_flags.dart';
 import '../../api_prototype/file_system.dart';
 
 import '../../base/common.dart';
@@ -71,6 +71,7 @@
 
 import '../builder/builder.dart';
 import '../builder/class_builder.dart';
+import '../builder/dynamic_type_declaration_builder.dart';
 import '../builder/enum_builder.dart';
 import '../builder/extension_builder.dart';
 import '../builder/field_builder.dart';
@@ -78,6 +79,8 @@
 import '../builder/library_builder.dart';
 import '../builder/member_builder.dart';
 import '../builder/named_type_builder.dart';
+import '../builder/never_type_declaration_builder.dart';
+import '../builder/prefix_builder.dart';
 import '../builder/procedure_builder.dart';
 import '../builder/type_alias_builder.dart';
 import '../builder/type_builder.dart';
@@ -202,24 +205,24 @@
 
   Future<Token> tokenize(SourceLibraryBuilder library,
       {bool suppressLexicalErrors: false}) async {
-    Uri uri = library.fileUri;
+    Uri fileUri = library.fileUri;
 
     // Lookup the file URI in the cache.
-    List<int> bytes = sourceBytes[uri];
+    List<int> bytes = sourceBytes[fileUri];
 
     if (bytes == null) {
       // Error recovery.
-      if (uri.scheme == untranslatableUriScheme) {
+      if (fileUri.scheme == untranslatableUriScheme) {
         Message message =
             templateUntranslatableUri.withArguments(library.importUri);
         library.addProblemAtAccessors(message);
         bytes = synthesizeSourceForMissingFile(library.importUri, null);
-      } else if (!uri.hasScheme) {
+      } else if (!fileUri.hasScheme) {
         return internalProblem(
-            templateInternalProblemUriMissingScheme.withArguments(uri),
+            templateInternalProblemUriMissingScheme.withArguments(fileUri),
             -1,
             library.importUri);
-      } else if (uri.scheme == SourceLibraryBuilder.MALFORMED_URI_SCHEME) {
+      } else if (fileUri.scheme == SourceLibraryBuilder.MALFORMED_URI_SCHEME) {
         library.addProblemAtAccessors(messageExpectedUri);
         bytes = synthesizeSourceForMissingFile(library.importUri, null);
       }
@@ -227,7 +230,7 @@
         Uint8List zeroTerminatedBytes = new Uint8List(bytes.length + 1);
         zeroTerminatedBytes.setRange(0, bytes.length, bytes);
         bytes = zeroTerminatedBytes;
-        sourceBytes[uri] = bytes;
+        sourceBytes[fileUri] = bytes;
       }
     }
 
@@ -236,30 +239,44 @@
       // system.
       List<int> rawBytes;
       try {
-        rawBytes = await fileSystem.entityForUri(uri).readAsBytes();
+        rawBytes = await fileSystem.entityForUri(fileUri).readAsBytes();
       } on FileSystemException catch (e) {
-        Message message = templateCantReadFile.withArguments(uri, e.message);
+        Message message =
+            templateCantReadFile.withArguments(fileUri, e.message);
         library.addProblemAtAccessors(message);
         rawBytes = synthesizeSourceForMissingFile(library.importUri, message);
       }
       Uint8List zeroTerminatedBytes = new Uint8List(rawBytes.length + 1);
       zeroTerminatedBytes.setRange(0, rawBytes.length, rawBytes);
       bytes = zeroTerminatedBytes;
-      sourceBytes[uri] = bytes;
+      sourceBytes[fileUri] = bytes;
       byteCount += rawBytes.length;
     }
 
     ScannerResult result = scan(bytes,
         includeComments: includeComments,
         configuration: new ScannerConfiguration(
-            enableTripleShift: library.enableTripleShiftInLibrary,
-            enableExtensionMethods: library.enableExtensionMethodsInLibrary,
-            enableNonNullable: library.enableNonNullableInLibrary),
+            enableTripleShift: target.isExperimentEnabledInLibraryByVersion(
+                ExperimentalFlag.tripleShift,
+                library.importUri,
+                library.packageLanguageVersion.version),
+            enableExtensionMethods:
+                target.isExperimentEnabledInLibraryByVersion(
+                    ExperimentalFlag.extensionMethods,
+                    library.importUri,
+                    library.packageLanguageVersion.version),
+            enableNonNullable: target.isExperimentEnabledInLibraryByVersion(
+                    ExperimentalFlag.nonNullable,
+                    library.importUri,
+                    library.packageLanguageVersion.version) &&
+                !SourceLibraryBuilder.isOptOutTest(library.importUri)),
         languageVersionChanged:
             (Scanner scanner, LanguageVersionToken version) {
       if (!suppressLexicalErrors) {
-        library.setLanguageVersion(new Version(version.major, version.minor),
-            offset: version.offset, length: version.length, explicit: true);
+        library.registerExplicitLanguageVersion(
+            new Version(version.major, version.minor),
+            offset: version.offset,
+            length: version.length);
       }
       scanner.configuration = new ScannerConfiguration(
           enableTripleShift: library.enableTripleShiftInLibrary,
@@ -292,7 +309,7 @@
       if (!suppressLexicalErrors) {
         ErrorToken error = token;
         library.addProblem(error.assertionMessage, offsetForToken(token),
-            lengthForToken(token), uri);
+            lengthForToken(token), fileUri);
       }
       token = token.next;
     }
@@ -904,7 +921,10 @@
         if (builder is TypeAliasBuilder) {
           TypeAliasBuilder aliasBuilder = builder;
           NamedTypeBuilder namedBuilder = mixedInTypeBuilder;
-          builder = aliasBuilder.unaliasDeclaration(namedBuilder.arguments);
+          builder = aliasBuilder.unaliasDeclaration(namedBuilder.arguments,
+              isUsedAsClass: true,
+              usedAsClassCharOffset: namedBuilder.charOffset,
+              usedAsClassFileUri: namedBuilder.fileUri);
           if (builder is! ClassBuilder) {
             cls.addProblem(
                 templateIllegalMixin.withArguments(builder.fullNameForErrors),
@@ -1153,6 +1173,16 @@
           } else if (declaration is MemberBuilder) {
             declaration.buildOutlineExpressions(
                 library, coreTypes, delayedActionPerformers);
+          } else if (declaration is TypeAliasBuilder) {
+            declaration.buildOutlineExpressions(
+                library, coreTypes, delayedActionPerformers);
+          } else {
+            assert(
+                declaration is PrefixBuilder ||
+                    declaration is DynamicTypeDeclarationBuilder ||
+                    declaration is NeverTypeDeclarationBuilder,
+                "Unexpected builder in library: ${declaration} "
+                "(${declaration.runtimeType}");
           }
         }
       }
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 b84b276..3057286 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
@@ -17,6 +17,8 @@
         VariableDeclaration,
         getAsTypeArguments;
 
+import 'package:kernel/core_types.dart';
+
 import 'package:kernel/type_algebra.dart'
     show FreshTypeParameters, getFreshTypeParameters;
 
@@ -39,6 +41,8 @@
 import '../builder/type_declaration_builder.dart';
 import '../builder/type_variable_builder.dart';
 
+import '../util/helpers.dart';
+
 import 'source_library_builder.dart' show SourceLibraryBuilder;
 
 class SourceTypeAliasBuilder extends TypeAliasBuilderImpl {
@@ -191,7 +195,8 @@
         // otherwise it's a compiled library loaded from a dill file, and the
         // bounds should have been assigned.
         SourceLibraryBuilder parentLibrary = parent;
-        parentLibrary.pendingNullabilities.add(asTypeArguments[i]);
+        parentLibrary.registerPendingNullability(_typeVariables[i].fileUri,
+            _typeVariables[i].charOffset, asTypeArguments[i]);
       }
     }
     return result;
@@ -241,6 +246,20 @@
     library.checkBoundsInTypeParameters(
         typeEnvironment, typedef.typeParameters, fileUri);
     library.checkBoundsInType(
-        typedef.type, typeEnvironment, fileUri, type?.charOffset ?? charOffset);
+        typedef.type, typeEnvironment, fileUri, type?.charOffset ?? charOffset,
+        allowSuperBounded: false);
+  }
+
+  @override
+  void buildOutlineExpressions(LibraryBuilder library, CoreTypes coreTypes,
+      List<DelayedActionPerformer> delayedActionPerformers) {
+    MetadataBuilder.buildAnnotations(
+        typedef, metadata, library, null, null, fileUri);
+    if (typeVariables != null) {
+      for (int i = 0; i < typeVariables.length; i++) {
+        typeVariables[i].buildOutlineExpressions(
+            library, null, null, coreTypes, delayedActionPerformers);
+      }
+    }
   }
 }
diff --git a/pkg/front_end/lib/src/fasta/source/stack_listener_impl.dart b/pkg/front_end/lib/src/fasta/source/stack_listener_impl.dart
index 83721d7..12c8559 100644
--- a/pkg/front_end/lib/src/fasta/source/stack_listener_impl.dart
+++ b/pkg/front_end/lib/src/fasta/source/stack_listener_impl.dart
@@ -6,8 +6,6 @@
 
 library fasta.stack_listener_impl;
 
-import 'package:_fe_analyzer_shared/src/messages/codes.dart' show Message;
-
 import 'package:_fe_analyzer_shared/src/parser/parser.dart' show Parser;
 
 import 'package:_fe_analyzer_shared/src/parser/stack_listener.dart';
@@ -15,8 +13,7 @@
 import 'package:_fe_analyzer_shared/src/scanner/scanner.dart' show Token;
 import 'package:front_end/src/api_prototype/experimental_flags.dart';
 
-import 'package:kernel/ast.dart'
-    show AsyncMarker, Expression, FunctionNode, TreeNode;
+import 'package:kernel/ast.dart';
 
 import '../fasta_codes.dart';
 
@@ -64,7 +61,7 @@
 
   // TODO(ahe): This doesn't belong here. Only implemented by body_builder.dart
   // and ast_builder.dart.
-  List<Expression> finishMetadata(TreeNode parent) {
+  List<Expression> finishMetadata(Annotatable parent) {
     return problems.unsupported("finishMetadata", -1, uri);
   }
 
diff --git a/pkg/front_end/lib/src/fasta/target_implementation.dart b/pkg/front_end/lib/src/fasta/target_implementation.dart
index 8acd6b8..2b29da2 100644
--- a/pkg/front_end/lib/src/fasta/target_implementation.dart
+++ b/pkg/front_end/lib/src/fasta/target_implementation.dart
@@ -17,6 +17,7 @@
 import 'builder/class_builder.dart';
 import 'builder/library_builder.dart';
 import 'builder/member_builder.dart';
+import 'source/source_library_builder.dart' show LanguageVersion;
 
 import 'compiler_context.dart' show CompilerContext;
 
@@ -66,6 +67,12 @@
     return _options.getExperimentEnabledVersionInLibrary(flag, importUri);
   }
 
+  bool isExperimentEnabledInLibraryByVersion(
+      ExperimentalFlag flag, Uri importUri, Version version) {
+    return _options.isExperimentEnabledInLibraryByVersion(
+        flag, importUri, version);
+  }
+
   /// Returns `true` if the [flag] is enabled by default.
   bool isExperimentEnabledByDefault(ExperimentalFlag flag) {
     return _options.isExperimentEnabledByDefault(flag);
@@ -100,10 +107,15 @@
   /// For libraries with a 'package:' [importUri], the package path must match
   /// the path in the [importUri]. For libraries with a 'dart:' [importUri] the
   /// [packageUri] must be `null`.
+  ///
+  /// [packageLanguageVersion] is the language version defined by the package
+  /// which the library belongs to, or the current sdk version if the library
+  /// doesn't belong to a package.
   LibraryBuilder createLibraryBuilder(
       Uri uri,
       Uri fileUri,
       Uri packageUri,
+      LanguageVersion packageLanguageVersion,
       covariant LibraryBuilder origin,
       Library referencesFrom,
       bool referenceIsPartOwner);
diff --git a/pkg/front_end/lib/src/fasta/type_inference/inference_helper.dart b/pkg/front_end/lib/src/fasta/type_inference/inference_helper.dart
index 24f2850..572feea 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/inference_helper.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/inference_helper.dart
@@ -21,7 +21,8 @@
       {List<LocatedMessage> context, bool suppressMessage});
 
   LocatedMessage checkArgumentsForType(
-      FunctionType function, Arguments arguments, int offset);
+      FunctionType function, Arguments arguments, int offset,
+      {bool isExtensionMemberInvocation = false});
 
   void addProblem(Message message, int charOffset, int length,
       {List<LocatedMessage> context, bool wasHandled});
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_constraint_gatherer.dart b/pkg/front_end/lib/src/fasta/type_inference/type_constraint_gatherer.dart
index 569d058..7e7f6cd 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_constraint_gatherer.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_constraint_gatherer.dart
@@ -12,8 +12,6 @@
 
 import 'package:kernel/type_environment.dart';
 
-import 'type_schema.dart' show UnknownType;
-
 import '../names.dart' show callName;
 
 import 'type_schema.dart';
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart b/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart
index 2e20f55..4a87e32 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart
@@ -18,9 +18,7 @@
         InterfaceType,
         Member,
         NamedType,
-        NeverType,
         NullType,
-        Nullability,
         Statement,
         TreeNode,
         TypeParameter,
@@ -310,19 +308,7 @@
 
   @override
   DartType promoteToNonNull(DartType type) {
-    if (type is TypeParameterType &&
-        type.declaredNullability != Nullability.nullable) {
-      DartType bound =
-          type.bound.withDeclaredNullability(Nullability.nonNullable);
-      if (bound != type.bound) {
-        return new TypeParameterType(
-            type.parameter, type.declaredNullability, bound);
-      }
-      return type;
-    } else if (type is NullType) {
-      return const NeverType.nonNullable();
-    }
-    return type.withDeclaredNullability(Nullability.nonNullable);
+    return type.toNonNull();
   }
 
   @override
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 d70f4c1..15606b8 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
@@ -41,12 +41,6 @@
 
 import '../fasta_codes.dart';
 
-import '../kernel/internal_ast.dart'
-    show
-        VariableDeclarationImpl,
-        getExplicitTypeArguments,
-        getExtensionTypeParameterCount;
-
 import '../kernel/inference_visitor.dart';
 
 import '../kernel/invalid_type.dart';
@@ -270,17 +264,6 @@
     return type.withDeclaredNullability(library.nullable);
   }
 
-  DartType computeNonNullable(DartType type) {
-    if (type is NullType) {
-      return isNonNullableByDefault ? const NeverType.nonNullable() : type;
-    }
-    if (type is TypeParameterType && type.promotedBound != null) {
-      return new TypeParameterType(type.parameter, Nullability.nonNullable,
-          computeNonNullable(type.promotedBound));
-    }
-    return type.withDeclaredNullability(library.nonNullable);
-  }
-
   Expression createReachabilityError(
       int fileOffset, Message errorMessage, Message warningMessage) {
     if (library.loader.target.context.options.warnOnReachabilityCheck &&
@@ -305,16 +288,19 @@
 
   /// Computes a list of context messages explaining why [receiver] was not
   /// promoted, to be used when reporting an error for a larger expression
-  /// containing [receiver].  [expression] is the containing expression.
-  List<LocatedMessage> getWhyNotPromotedContext(Expression receiver,
-      Map<DartType, NonPromotionReason> whyNotPromoted, Expression expression) {
+  /// containing [receiver].  [node] is the containing tree node.
+  List<LocatedMessage> getWhyNotPromotedContext(
+      Expression receiver,
+      Map<DartType, NonPromotionReason> whyNotPromoted,
+      TreeNode node,
+      bool Function(DartType) typeFilter) {
     List<LocatedMessage> context;
     if (whyNotPromoted != null && whyNotPromoted.isNotEmpty) {
       _WhyNotPromotedVisitor whyNotPromotedVisitor =
           new _WhyNotPromotedVisitor(this, receiver);
       for (core.MapEntry<DartType, NonPromotionReason> entry
           in whyNotPromoted.entries) {
-        if (entry.key.isPotentiallyNullable) continue;
+        if (!typeFilter(entry.key)) continue;
         LocatedMessage message = entry.value.accept(whyNotPromotedVisitor);
         if (dataForTesting != null) {
           String nonPromotionReasonText = entry.value.shortName;
@@ -331,7 +317,7 @@
           if (args.isNotEmpty) {
             nonPromotionReasonText += '(${args.join(', ')})';
           }
-          dataForTesting.flowAnalysisResult.nonPromotionReasons[expression] =
+          dataForTesting.flowAnalysisResult.nonPromotionReasons[node] =
               nonPromotionReasonText;
         }
         // Note: this will always pick the first viable reason (only).  I
@@ -626,10 +612,14 @@
                 expression,
                 expressionType,
                 contextType,
-                nullabilityErrorTemplate.withArguments(
-                    expressionType,
-                    declaredContextType ?? contextType,
-                    isNonNullableByDefault));
+                nullabilityErrorTemplate.withArguments(expressionType,
+                    declaredContextType ?? contextType, isNonNullableByDefault),
+                context: getWhyNotPromotedContext(
+                    expression,
+                    flowAnalysis?.whyNotPromoted(expression)(),
+                    expression,
+                    (type) => typeSchemaEnvironment.isSubtypeOf(type,
+                        contextType, SubtypeCheckMode.withNullabilities)));
           }
         } else {
           result = _wrapUnassignableExpression(
@@ -704,7 +694,8 @@
   }
 
   Expression _wrapUnassignableExpression(Expression expression,
-      DartType expressionType, DartType contextType, Message message) {
+      DartType expressionType, DartType contextType, Message message,
+      {List<LocatedMessage> context}) {
     Expression errorNode = new AsExpression(
         expression,
         // TODO(ahe): The outline phase doesn't correctly remove invalid
@@ -719,7 +710,8 @@
       ..fileOffset = expression.fileOffset;
     if (contextType is! InvalidType && expressionType is! InvalidType) {
       errorNode = helper.wrapInProblem(
-          errorNode, message, errorNode.fileOffset, noLength);
+          errorNode, message, errorNode.fileOffset, noLength,
+          context: context);
     }
     return errorNode;
   }
@@ -738,8 +730,7 @@
     Expression nullCheck;
     // TODO(johnniwinther): Avoid null-check for non-nullable expressions.
     if (useNewMethodInvocationEncoding) {
-      nullCheck = new EqualsNull(new VariableGet(t)..fileOffset = fileOffset,
-          isNot: false)
+      nullCheck = new EqualsNull(new VariableGet(t)..fileOffset = fileOffset)
         ..fileOffset = fileOffset;
     } else {
       nullCheck = new MethodInvocation(
@@ -884,30 +875,46 @@
   ObjectAccessTarget _findDirectExtensionMember(
       ExtensionType receiverType, Name name, int fileOffset,
       {ObjectAccessTarget defaultTarget}) {
-    Member targetMethod;
+    Member targetMember;
     Member targetTearoff;
+    ProcedureKind targetKind;
     for (ExtensionMemberDescriptor descriptor
-        in receiverType.extensionNode.members) {
+        in receiverType.extension.members) {
       if (descriptor.name == name) {
         switch (descriptor.kind) {
           case ExtensionMemberKind.Method:
-            targetMethod = descriptor.member.asMember;
+            targetMember = descriptor.member.asMember;
+            targetTearoff ??= targetMember;
+            targetKind = ProcedureKind.Method;
             break;
           case ExtensionMemberKind.TearOff:
             targetTearoff = descriptor.member.asMember;
             break;
+          case ExtensionMemberKind.Getter:
+            targetMember = descriptor.member.asMember;
+            targetTearoff = null;
+            targetKind = ProcedureKind.Getter;
+            break;
+          case ExtensionMemberKind.Setter:
+            targetMember = descriptor.member.asMember;
+            targetTearoff = null;
+            targetKind = ProcedureKind.Setter;
+            break;
+          case ExtensionMemberKind.Operator:
+            targetMember = descriptor.member.asMember;
+            targetTearoff = null;
+            targetKind = ProcedureKind.Operator;
+            break;
           default:
-            unhandled("${descriptor.kind}", "findInterfaceMember", fileOffset,
-                library.fileUri);
+            unhandled("${descriptor.kind}", "_findDirectExtensionMember",
+                fileOffset, library.fileUri);
         }
       }
     }
-    if (targetMethod != null) {
+    if (targetMember != null) {
+      assert(targetKind != null);
       return new ObjectAccessTarget.extensionMember(
-          targetMethod,
-          targetTearoff ?? targetMethod,
-          ProcedureKind.Method,
-          receiverType.typeArguments);
+          targetMember, targetTearoff, targetKind, receiverType.typeArguments);
     } else {
       return defaultTarget;
     }
@@ -1174,8 +1181,8 @@
         // invalid.
         target = _findExtensionMember(
             isNonNullableByDefault
-                ? computeNonNullable(receiverType)
-                : computeNonNullable(receiverBound),
+                ? receiverType.toNonNull()
+                : receiverBound.toNonNull(),
             classNode,
             name,
             fileOffset,
@@ -2034,7 +2041,8 @@
       bool isConst: false,
       bool isImplicitExtensionMember: false,
       bool isImplicitCall: false,
-      Member staticTarget}) {
+      Member staticTarget,
+      bool isExtensionMemberInvocation = false}) {
     int extensionTypeParameterCount = getExtensionTypeParameterCount(arguments);
     if (extensionTypeParameterCount != 0) {
       return _inferGenericExtensionMethodInvocation(extensionTypeParameterCount,
@@ -2055,7 +2063,8 @@
         isConst: isConst,
         isImplicitExtensionMember: isImplicitExtensionMember,
         isImplicitCall: isImplicitCall,
-        staticTarget: staticTarget);
+        staticTarget: staticTarget,
+        isExtensionMemberInvocation: isExtensionMemberInvocation);
   }
 
   InvocationInferenceResult _inferGenericExtensionMethodInvocation(
@@ -2090,7 +2099,8 @@
         receiverType: receiverType,
         isImplicitExtensionMember: isImplicitExtensionMember,
         isImplicitCall: isImplicitCall,
-        staticTarget: staticTarget);
+        staticTarget: staticTarget,
+        isExtensionMemberInvocation: true);
     Substitution extensionSubstitution = Substitution.fromPairs(
         extensionFunctionType.typeParameters, extensionArguments.types);
 
@@ -2147,7 +2157,8 @@
       bool isConst: false,
       bool isImplicitExtensionMember: false,
       bool isImplicitCall,
-      Member staticTarget}) {
+      Member staticTarget,
+      bool isExtensionMemberInvocation: false}) {
     List<TypeParameter> calleeTypeParameters = calleeType.typeParameters;
     if (calleeTypeParameters.isNotEmpty) {
       // It's possible that one of the callee type parameters might match a type
@@ -2367,8 +2378,9 @@
     List<DartType> positionalArgumentTypes = [];
     List<NamedType> namedArgumentTypes = [];
     if (typeChecksNeeded && !identical(calleeType, unknownFunction)) {
-      LocatedMessage argMessage =
-          helper.checkArgumentsForType(calleeType, arguments, offset);
+      LocatedMessage argMessage = helper.checkArgumentsForType(
+          calleeType, arguments, offset,
+          isExtensionMemberInvocation: isExtensionMemberInvocation);
       if (argMessage != null) {
         return new WrapInProblemInferenceResult(
             const InvalidType(),
@@ -2814,7 +2826,10 @@
         //     void Function() get call => () {};
         //   }
         List<LocatedMessage> context = getWhyNotPromotedContext(
-            receiver, flowAnalysis?.whyNotPromoted(receiver), staticInvocation);
+            receiver,
+            flowAnalysis?.whyNotPromoted(receiver)(),
+            staticInvocation,
+            (type) => !type.isPotentiallyNullable);
         result = wrapExpressionInferenceResultInProblem(
             result,
             templateNullableExpressionCallError.withArguments(
@@ -2833,7 +2848,8 @@
           hoistedExpressions: hoistedExpressions,
           receiverType: receiverType,
           isImplicitExtensionMember: true,
-          isImplicitCall: isImplicitCall);
+          isImplicitCall: isImplicitCall,
+          isExtensionMemberInvocation: true);
       if (!isTopLevel) {
         library.checkBoundsInStaticInvocation(staticInvocation,
             typeSchemaEnvironment, helper.uri, getTypeArgumentsInfo(arguments));
@@ -2842,7 +2858,10 @@
       Expression replacement = result.applyResult(staticInvocation);
       if (!isTopLevel && target.isNullable) {
         List<LocatedMessage> context = getWhyNotPromotedContext(
-            receiver, flowAnalysis?.whyNotPromoted(receiver), staticInvocation);
+            receiver,
+            flowAnalysis?.whyNotPromoted(receiver)(),
+            staticInvocation,
+            (type) => !type.isPotentiallyNullable);
         if (isImplicitCall) {
           // Handles cases like:
           //   int? i;
@@ -2899,6 +2918,7 @@
         receiverType: receiverType,
         isImplicitCall: isImplicitCall);
     Expression expression;
+    String localName;
     if (useNewMethodInvocationEncoding) {
       DartType inferredFunctionType = result.functionType;
       if (result.isInapplicable) {
@@ -2910,9 +2930,11 @@
           ..fileOffset = fileOffset;
       } else if (receiver is VariableGet) {
         VariableDeclaration variable = receiver.variable;
-        if (variable.parent is FunctionDeclaration) {
-          assert(inferredFunctionType != unknownFunction,
+        TreeNode parent = variable.parent;
+        if (parent is FunctionDeclaration) {
+          assert(!identical(inferredFunctionType, unknownFunction),
               "Unknown function type for local function invocation.");
+          localName = variable.name;
           expression = new LocalFunctionInvocation(variable, arguments,
               functionType: inferredFunctionType)
             ..fileOffset = receiver.fileOffset;
@@ -2931,13 +2953,29 @@
               : inferredFunctionType)
         ..fileOffset = fileOffset;
     } else {
+      if (receiver is VariableGet) {
+        VariableDeclaration variable = receiver.variable;
+        TreeNode parent = variable.parent;
+        if (parent is FunctionDeclaration) {
+          // This is a local function invocation. Use the name in bounds
+          // checking below.
+          localName = variable.name;
+        }
+      }
       expression = new MethodInvocation(receiver, callName, arguments)
         ..fileOffset = fileOffset;
     }
+
+    _checkBoundsInFunctionInvocation(
+        declaredFunctionType, localName, arguments, fileOffset);
+
     Expression replacement = result.applyResult(expression);
     if (!isTopLevel && target.isNullableCallFunction) {
       List<LocatedMessage> context = getWhyNotPromotedContext(
-          receiver, flowAnalysis?.whyNotPromoted(receiver), expression);
+          receiver,
+          flowAnalysis?.whyNotPromoted(receiver)(),
+          expression,
+          (type) => !type.isPotentiallyNullable);
       if (isImplicitCall) {
         // Handles cases like:
         //   void Function()? f;
@@ -3109,7 +3147,10 @@
     replacement = result.applyResult(replacement);
     if (!isTopLevel && target.isNullable) {
       List<LocatedMessage> context = getWhyNotPromotedContext(
-          receiver, flowAnalysis?.whyNotPromoted(receiver), expression);
+          receiver,
+          flowAnalysis?.whyNotPromoted(receiver)(),
+          expression,
+          (type) => !type.isPotentiallyNullable);
       if (isImplicitCall) {
         // Handles cases like:
         //   C? c;
@@ -3266,8 +3307,11 @@
       //   class C {
       //     void Function() get foo => () {};
       //   }
-      List<LocatedMessage> context = getWhyNotPromotedContext(receiver,
-          flowAnalysis?.whyNotPromoted(receiver), invocationResult.expression);
+      List<LocatedMessage> context = getWhyNotPromotedContext(
+          receiver,
+          flowAnalysis?.whyNotPromoted(receiver)(),
+          invocationResult.expression,
+          (type) => !type.isPotentiallyNullable);
       invocationResult = wrapExpressionInferenceResultInProblem(
           invocationResult,
           templateNullableExpressionCallError.withArguments(
@@ -3290,24 +3334,38 @@
               ..fileOffset = nullAwareAction.fileOffset);
       } else if (nullAwareAction is InstanceInvocation &&
           nullAwareAction.receiver == originalPropertyGet) {
+        // TODO(johnniwinther): Remove this when [MethodInvocation] is no longer
+        // used and [originalPropertyGet] can be an [InstanceGet].
+        InstanceGet instanceGet = originalPropertyGet;
         invocationResult = new ExpressionInferenceResult(
             invocationResult.inferredType,
-            new MethodInvocation(originalReceiver, originalName,
-                nullAwareAction.arguments, originalTarget)
+            new InstanceGetterInvocation(instanceGet.kind, originalReceiver,
+                originalName, nullAwareAction.arguments,
+                interfaceTarget: originalTarget,
+                functionType: nullAwareAction.functionType)
               ..fileOffset = nullAwareAction.fileOffset);
       } else if (nullAwareAction is DynamicInvocation &&
           nullAwareAction.receiver == originalPropertyGet) {
+        // TODO(johnniwinther): Remove this when [MethodInvocation] is no longer
+        // used and [originalPropertyGet] can be an [InstanceGet].
+        InstanceGet instanceGet = originalPropertyGet;
         invocationResult = new ExpressionInferenceResult(
             invocationResult.inferredType,
-            new MethodInvocation(originalReceiver, originalName,
-                nullAwareAction.arguments, originalTarget)
+            new InstanceGetterInvocation(instanceGet.kind, originalReceiver,
+                originalName, nullAwareAction.arguments,
+                interfaceTarget: originalTarget, functionType: null)
               ..fileOffset = nullAwareAction.fileOffset);
       } else if (nullAwareAction is FunctionInvocation &&
           nullAwareAction.receiver == originalPropertyGet) {
+        // TODO(johnniwinther): Remove this when [MethodInvocation] is no longer
+        // used and [originalPropertyGet] can be an [InstanceGet].
+        InstanceGet instanceGet = originalPropertyGet;
         invocationResult = new ExpressionInferenceResult(
             invocationResult.inferredType,
-            new MethodInvocation(originalReceiver, originalName,
-                nullAwareAction.arguments, originalTarget)
+            new InstanceGetterInvocation(instanceGet.kind, originalReceiver,
+                originalName, nullAwareAction.arguments,
+                interfaceTarget: originalTarget,
+                functionType: nullAwareAction.functionType)
               ..fileOffset = nullAwareAction.fileOffset);
       }
     }
@@ -3371,12 +3429,12 @@
       receiver = _hoist(receiver, receiverType, hoistedExpressions);
     }
 
-    Map<DartType, NonPromotionReason> whyNotPromotedInfo;
+    Map<DartType, NonPromotionReason> Function() whyNotPromoted;
     if (!isTopLevel && target.isNullable) {
       // We won't report the error until later (after we have an
       // invocationResult), but we need to gather "why not promoted" info now,
       // before we tell flow analysis about the property get.
-      whyNotPromotedInfo = flowAnalysis?.whyNotPromoted(receiver);
+      whyNotPromoted = flowAnalysis?.whyNotPromoted(receiver);
     }
 
     Name originalName = field.name;
@@ -3402,13 +3460,13 @@
           kind, originalReceiver, originalName,
           resultType: calleeType, interfaceTarget: originalTarget)
         ..fileOffset = fileOffset;
-      flowAnalysis.propertyGet(
-          originalPropertyGet, originalReceiver, originalName.name, calleeType);
     } else {
       originalPropertyGet =
           new PropertyGet(originalReceiver, originalName, originalTarget)
             ..fileOffset = fileOffset;
     }
+    flowAnalysis.propertyGet(
+        originalPropertyGet, originalReceiver, originalName.text, calleeType);
     Expression propertyGet = originalPropertyGet;
     if (receiver is! ThisExpression &&
         calleeType is! DynamicType &&
@@ -3461,7 +3519,10 @@
       // TODO(paulberry): would it be better to report NullableMethodCallError
       // in this scenario?
       List<LocatedMessage> context = getWhyNotPromotedContext(
-          receiver, whyNotPromotedInfo, invocationResult.expression);
+          receiver,
+          whyNotPromoted(),
+          invocationResult.expression,
+          (type) => !type.isPotentiallyNullable);
       invocationResult = wrapExpressionInferenceResultInProblem(
           invocationResult,
           templateNullableExpressionCallError.withArguments(
@@ -3636,11 +3697,9 @@
       Arguments arguments,
       int fileOffset) {
     // If [arguments] were inferred, check them.
-    // TODO(dmitryas): Figure out why [library] is sometimes null? Answer:
-    // because top level inference never got a library. This has changed so
-    // we always have a library. Should we still skip this for top level
-    // inference?
     if (!isTopLevel) {
+      // We only perform checks in full inference.
+
       // [actualReceiverType], [interfaceTarget], and [actualMethodName] below
       // are for a workaround for the cases like the following:
       //
@@ -3674,6 +3733,23 @@
     }
   }
 
+  void _checkBoundsInFunctionInvocation(FunctionType functionType,
+      String localName, Arguments arguments, int fileOffset) {
+    // If [arguments] were inferred, check them.
+    if (!isTopLevel) {
+      // We only perform checks in full inference.
+      library.checkBoundsInFunctionInvocation(
+          typeSchemaEnvironment,
+          classHierarchy,
+          this,
+          functionType,
+          localName,
+          arguments,
+          helper.uri,
+          fileOffset);
+    }
+  }
+
   bool isSpecialCasedBinaryOperatorForReceiverType(
       ObjectAccessTarget target, DartType receiverType) {
     return (target.isInstanceMember ||
@@ -4134,13 +4210,19 @@
       return engine.forest
           .createPropertyGet(fileOffset, receiver, propertyName);
     } else {
+      Template<Message Function(String, DartType, bool)> templateMissing;
+      if (receiverType is ExtensionType) {
+        templateMissing = templateUndefinedExtensionGetter;
+      } else {
+        templateMissing = templateUndefinedGetter;
+      }
       return _reportMissingOrAmbiguousMember(
           fileOffset,
           propertyName.text.length,
           receiverType,
           propertyName,
           extensionAccessCandidates,
-          templateUndefinedGetter,
+          templateMissing,
           templateAmbiguousExtensionProperty);
     }
   }
@@ -4155,13 +4237,19 @@
           fileOffset, receiver, propertyName, value,
           forEffect: forEffect);
     } else {
+      Template<Message Function(String, DartType, bool)> templateMissing;
+      if (receiverType is ExtensionType) {
+        templateMissing = templateUndefinedExtensionSetter;
+      } else {
+        templateMissing = templateUndefinedSetter;
+      }
       return _reportMissingOrAmbiguousMember(
           fileOffset,
           propertyName.text.length,
           receiverType,
           propertyName,
           extensionAccessCandidates,
-          templateUndefinedSetter,
+          templateMissing,
           templateAmbiguousExtensionProperty);
     }
   }
@@ -4172,13 +4260,19 @@
     if (isTopLevel) {
       return engine.forest.createIndexGet(fileOffset, receiver, index);
     } else {
+      Template<Message Function(String, DartType, bool)> templateMissing;
+      if (receiverType is ExtensionType) {
+        templateMissing = templateUndefinedExtensionOperator;
+      } else {
+        templateMissing = templateUndefinedOperator;
+      }
       return _reportMissingOrAmbiguousMember(
           fileOffset,
           noLength,
           receiverType,
           indexGetName,
           extensionAccessCandidates,
-          templateUndefinedOperator,
+          templateMissing,
           templateAmbiguousExtensionOperator);
     }
   }
@@ -4192,13 +4286,19 @@
       return engine.forest.createIndexSet(fileOffset, receiver, index, value,
           forEffect: forEffect);
     } else {
+      Template<Message Function(String, DartType, bool)> templateMissing;
+      if (receiverType is ExtensionType) {
+        templateMissing = templateUndefinedExtensionOperator;
+      } else {
+        templateMissing = templateUndefinedOperator;
+      }
       return _reportMissingOrAmbiguousMember(
           fileOffset,
           noLength,
           receiverType,
           indexSetName,
           extensionAccessCandidates,
-          templateUndefinedOperator,
+          templateMissing,
           templateAmbiguousExtensionOperator);
     }
   }
@@ -4211,13 +4311,19 @@
       return engine.forest.createMethodInvocation(fileOffset, left, binaryName,
           engine.forest.createArguments(fileOffset, <Expression>[right]));
     } else {
+      Template<Message Function(String, DartType, bool)> templateMissing;
+      if (leftType is ExtensionType) {
+        templateMissing = templateUndefinedExtensionOperator;
+      } else {
+        templateMissing = templateUndefinedOperator;
+      }
       return _reportMissingOrAmbiguousMember(
           fileOffset,
           binaryName.text.length,
           leftType,
           binaryName,
           extensionAccessCandidates,
-          templateUndefinedOperator,
+          templateMissing,
           templateAmbiguousExtensionOperator);
     }
   }
@@ -4229,13 +4335,19 @@
       return new UnaryExpression(unaryName, expression)
         ..fileOffset = fileOffset;
     } else {
+      Template<Message Function(String, DartType, bool)> templateMissing;
+      if (expressionType is ExtensionType) {
+        templateMissing = templateUndefinedExtensionOperator;
+      } else {
+        templateMissing = templateUndefinedOperator;
+      }
       return _reportMissingOrAmbiguousMember(
           fileOffset,
           unaryName == unaryMinusName ? 1 : unaryName.text.length,
           expressionType,
           unaryName,
           extensionAccessCandidates,
-          templateUndefinedOperator,
+          templateMissing,
           templateAmbiguousExtensionOperator);
     }
   }
@@ -4246,7 +4358,7 @@
   Expression createEqualsNull(
       int fileOffset, Expression left, Member equalsMember) {
     if (useNewMethodInvocationEncoding) {
-      return new EqualsNull(left, isNot: false)..fileOffset = fileOffset;
+      return new EqualsNull(left)..fileOffset = fileOffset;
     } else {
       return new MethodInvocation(
           left,
@@ -5018,8 +5130,8 @@
 
 class _WhyNotPromotedVisitor
     implements
-        NonPromotionReasonVisitor<LocatedMessage, Node, Expression,
-            VariableDeclaration, DartType> {
+        NonPromotionReasonVisitor<LocatedMessage, Node, VariableDeclaration,
+            DartType> {
   final TypeInferrerImpl inferrer;
 
   final Expression receiver;
@@ -5032,23 +5144,15 @@
 
   @override
   LocatedMessage visitDemoteViaExplicitWrite(
-      DemoteViaExplicitWrite<VariableDeclaration, Expression> reason) {
+      DemoteViaExplicitWrite<VariableDeclaration> reason) {
+    TreeNode node = reason.node as TreeNode;
     if (inferrer.dataForTesting != null) {
       inferrer.dataForTesting.flowAnalysisResult
-          .nonPromotionReasonTargets[reason.writeExpression] = reason.shortName;
+          .nonPromotionReasonTargets[node] = reason.shortName;
     }
-    int offset = reason.writeExpression.fileOffset;
+    int offset = node.fileOffset;
     return templateVariableCouldBeNullDueToWrite
-        .withArguments(reason.variable.name)
-        .withLocation(inferrer.helper.uri, offset, noLength);
-  }
-
-  @override
-  LocatedMessage visitDemoteViaForEachVariableWrite(
-      DemoteViaForEachVariableWrite<VariableDeclaration, Node> reason) {
-    int offset = (reason.node as TreeNode).fileOffset;
-    return templateVariableCouldBeNullDueToWrite
-        .withArguments(reason.variable.name)
+        .withArguments(reason.variable.name, reason.documentationLink)
         .withLocation(inferrer.helper.uri, offset, noLength);
   }
 
@@ -5071,7 +5175,7 @@
       propertyReference = member;
       propertyType = reason.staticType;
       return templateFieldNotPromoted
-          .withArguments(reason.propertyName)
+          .withArguments(reason.propertyName, reason.documentationLink)
           .withLocation(member.fileUri, member.fileOffset, noLength);
     } else {
       return null;
@@ -5080,6 +5184,8 @@
 
   @override
   LocatedMessage visitThisNotPromoted(ThisNotPromoted reason) {
-    return messageThisNotPromoted.withoutLocation();
+    return templateThisNotPromoted
+        .withArguments(reason.documentationLink)
+        .withoutLocation();
   }
 }
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_schema.dart b/pkg/front_end/lib/src/fasta/type_inference/type_schema.dart
index 883df40..cce226f 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_schema.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_schema.dart
@@ -95,6 +95,9 @@
   UnknownType withDeclaredNullability(Nullability nullability) => this;
 
   @override
+  UnknownType toNonNull() => this;
+
+  @override
   void toTextInternal(AstPrinter printer) {
     printer.write('?');
   }
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_schema_environment.dart b/pkg/front_end/lib/src/fasta/type_inference/type_schema_environment.dart
index 172476b..bc3f745 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_schema_environment.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_schema_environment.dart
@@ -17,8 +17,6 @@
 import 'package:kernel/src/hierarchy_based_type_environment.dart'
     show HierarchyBasedTypeEnvironment;
 
-import '../kernel/internal_ast.dart' show ExtensionType;
-
 import 'standard_bounds.dart' show TypeSchemaStandardBounds;
 
 import 'type_constraint_gatherer.dart' show TypeConstraintGatherer;
@@ -373,7 +371,7 @@
       if (coreTypes.isTop(supertype)) {
         return const IsSubtypeOf.always();
       } else if (supertype is ExtensionType &&
-          subtype.extensionNode == supertype.extensionNode) {
+          subtype.extension == supertype.extension) {
         assert(subtype.typeArguments.length == supertype.typeArguments.length);
         IsSubtypeOf result = const IsSubtypeOf.always();
         for (int i = 0; i < subtype.typeArguments.length; ++i) {
@@ -399,7 +397,7 @@
       if (coreTypes.isBottom(subtype)) {
         return const IsSubtypeOf.always();
       } else if (subtype is ExtensionType &&
-          subtype.extensionNode == unwrappedSupertype.extensionNode) {
+          subtype.extension == unwrappedSupertype.extension) {
         assert(subtype.typeArguments.length ==
             unwrappedSupertype.typeArguments.length);
         IsSubtypeOf result = const IsSubtypeOf.always();
diff --git a/pkg/front_end/lib/src/fasta/uri_translator.dart b/pkg/front_end/lib/src/fasta/uri_translator.dart
index 55222b2..cf294d2 100644
--- a/pkg/front_end/lib/src/fasta/uri_translator.dart
+++ b/pkg/front_end/lib/src/fasta/uri_translator.dart
@@ -6,8 +6,6 @@
 
 library fasta.uri_translator;
 
-import 'package:_fe_analyzer_shared/src/messages/severity.dart' show Severity;
-
 import 'package:package_config/package_config.dart';
 
 import '../base/libraries_specification.dart' show TargetLibrariesSpecification;
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 cc76576..fe06b76 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
@@ -1970,6 +1970,13 @@
     seen(data);
   }
 
+  void handleConstFactory(Token constKeyword) {
+    DirectParserASTContentConstFactoryHandle data =
+        new DirectParserASTContentConstFactoryHandle(DirectParserASTType.HANDLE,
+            constKeyword: constKeyword);
+    seen(data);
+  }
+
   void beginForControlFlow(Token awaitToken, Token forToken) {
     DirectParserASTContentForControlFlowBegin data =
         new DirectParserASTContentForControlFlowBegin(DirectParserASTType.BEGIN,
@@ -5814,6 +5821,18 @@
       };
 }
 
+class DirectParserASTContentConstFactoryHandle extends DirectParserASTContent {
+  final Token constKeyword;
+
+  DirectParserASTContentConstFactoryHandle(DirectParserASTType type,
+      {this.constKeyword})
+      : super("ConstFactory", type);
+
+  Map<String, Object> get deprecatedArguments => {
+        "constKeyword": constKeyword,
+      };
+}
+
 class DirectParserASTContentForControlFlowBegin extends DirectParserASTContent {
   final Token awaitToken;
   final Token forToken;
diff --git a/pkg/front_end/lib/src/testing/id_extractor.dart b/pkg/front_end/lib/src/testing/id_extractor.dart
index ebee200..eb7832a 100644
--- a/pkg/front_end/lib/src/testing/id_extractor.dart
+++ b/pkg/front_end/lib/src/testing/id_extractor.dart
@@ -200,9 +200,9 @@
   }
 
   _visitInvocation(Expression node, Name name) {
-    if (name.name == '[]') {
+    if (name.text == '[]') {
       computeForNode(node, computeDefaultNodeId(node));
-    } else if (name.name == '[]=') {
+    } else if (name.text == '[]=') {
       computeForNode(node, createUpdateId(node));
     } else {
       if (node.fileOffset != TreeNode.noOffset) {
@@ -221,7 +221,7 @@
       // This is an invocation of a named local function.
       computeForNode(node, createInvokeId(node.receiver));
       node.arguments.accept(this);
-    } else if (node.name.name == '==' &&
+    } else if (node.name.text == '==' &&
         receiver is VariableGet &&
         receiver.variable.name == null) {
       // This is a desugared `?.`.
@@ -273,6 +273,12 @@
   }
 
   @override
+  visitInstanceGetterInvocation(InstanceGetterInvocation node) {
+    _visitInvocation(node, node.name);
+    super.visitInstanceGetterInvocation(node);
+  }
+
+  @override
   visitLoadLibrary(LoadLibrary node) {
     computeForNode(node, createInvokeId(node));
   }
@@ -630,4 +636,10 @@
     computeForNode(node, computeDefaultNodeId(node));
     return super.visitLogicalExpression(node);
   }
+
+  @override
+  visitInvalidExpression(InvalidExpression node) {
+    computeForNode(node, computeDefaultNodeId(node));
+    return super.visitInvalidExpression(node);
+  }
 }
diff --git a/pkg/front_end/lib/src/testing/id_testing_utils.dart b/pkg/front_end/lib/src/testing/id_testing_utils.dart
index 94c3bfd..68cbf92 100644
--- a/pkg/front_end/lib/src/testing/id_testing_utils.dart
+++ b/pkg/front_end/lib/src/testing/id_testing_utils.dart
@@ -570,6 +570,16 @@
     }
     sb.write(nullabilityToText(node.nullability, typeRepresentation));
   }
+
+  void visitExtensionType(ExtensionType node) {
+    sb.write(node.extension.name);
+    if (node.typeArguments.isNotEmpty) {
+      sb.write('<');
+      visitList(node.typeArguments);
+      sb.write('>');
+    }
+    sb.write(nullabilityToText(node.declaredNullability, typeRepresentation));
+  }
 }
 
 /// Returns `true` if [type] is `Object` from `dart:core`.
diff --git a/pkg/front_end/messages.status b/pkg/front_end/messages.status
index 9c120af..17b04d6 100644
--- a/pkg/front_end/messages.status
+++ b/pkg/front_end/messages.status
@@ -329,7 +329,11 @@
 FfiFieldNoAnnotation/analyzerCode: Fail
 FfiFieldNull/analyzerCode: Fail
 FfiNotStatic/analyzerCode: Fail
+FfiPackedAnnotation/analyzerCode: Fail
+FfiPackedAnnotationAlignment/analyzerCode: Fail
+FfiPackedNestingNonPacked/analyzerCode: Fail
 FfiSizeAnnotation/analyzerCode: Fail
+FfiSizeAnnotationDimensions/analyzerCode: Fail
 FfiStructAnnotation/analyzerCode: Fail
 FfiStructGeneric/analyzerCode: Fail
 FfiTypeInvalid/analyzerCode: Fail
@@ -741,6 +745,8 @@
 SupertypeIsFunction/analyzerCode: Fail
 SupertypeIsFunction/example: Fail
 SupertypeIsIllegal/example: Fail
+SupertypeIsIllegalAliased/example: Fail
+SupertypeIsNullableAliased/example: Fail
 SupertypeIsTypeVariable/example: Fail
 SwitchCaseFallThrough/example: Fail
 SwitchExpressionNotSubtype/analyzerCode: Fail
@@ -772,8 +778,15 @@
 TypedefNullableType/analyzerCode: Fail
 TypedefTypeVariableNotConstructor/analyzerCode: Fail # Feature not yet enabled by default.
 TypedefTypeVariableNotConstructor/example: Fail # Feature not yet enabled by default.
+UndefinedExtensionGetter/analyzerCode: Fail
+UndefinedExtensionGetter/example: Fail
 UndefinedExtensionMethod/analyzerCode: Fail
 UndefinedExtensionMethod/example: Fail
+UndefinedExtensionOperator/analyzerCode: Fail
+UndefinedExtensionOperator/example: Fail
+UndefinedExtensionSetter/analyzerCode: Fail
+UndefinedExtensionSetter/example: Fail
+UnexpectedModifierInNonNnbd/part_wrapped_script: Fail # Test requires @dart= annotation
 UnexpectedToken/part_wrapped_script1: Fail
 UnexpectedToken/script1: Fail
 UnmatchedToken/part_wrapped_script1: Fail
diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml
index 36d6bcc..05f2d16 100644
--- a/pkg/front_end/messages.yaml
+++ b/pkg/front_end/messages.yaml
@@ -214,7 +214,7 @@
   analyzerCode: NOT_CONSTANT_EXPRESSION
 
 ConstEvalUnevaluated:
-  template: "Could not evaluate constant expression."
+  template: "Couldn't evaluate constant expression."
 
 NotConstantExpression:
   template: "#string is not a constant expression."
@@ -1248,6 +1248,54 @@
   script:
     - "import 'b.dart' d as b;"
 
+LiteralWithClassAndNew:
+  template: "A #string literal can't be prefixed by 'new #lexeme'."
+  tip: "Try removing 'new' and '#lexeme'"
+  analyzerCode: ParserErrorCode.LITERAL_WITH_CLASS_AND_NEW
+  index: 115
+  script:
+    - "var x = new Map{};"
+    - "var x = new Set{};"
+    - "var x = new List[];"
+    - "var x = new Map{1: 2};"
+    - "var x = new Set{1};"
+    - "var x = new List[1];"
+
+LiteralWithClass:
+  template: "A #string literal can't be prefixed by '#lexeme'."
+  tip: "Try removing '#lexeme'"
+  analyzerCode: ParserErrorCode.LITERAL_WITH_CLASS
+  index: 116
+  script:
+    - "var x = Map{};"
+    - "var x = Set{};"
+    - "var x = List<String>[];"
+    - "var x = Map{1: 2};"
+    - "var x = Set{1};"
+    - "var x = List<int>[1];"
+    - "var x = const Map{};"
+    - "var x = const Set{};"
+    - "var x = const List[];"
+    - "var x = const Map{1: 2};"
+    - "var x = const Set{1};"
+    - "var x = const List[1];"
+
+LiteralWithNew:
+  template: "A literal can't be prefixed by 'new'."
+  tip: "Try removing 'new'"
+  analyzerCode: ParserErrorCode.LITERAL_WITH_NEW
+  index: 117
+  script:
+    - "var x = new <String, String>{};"
+    - "var x = new <String>{};"
+    - "var x = new {};"
+    - "var x = new [];"
+    - "var x = new <String, String>{'a': 'b'};"
+    - "var x = new <String>{'a'};"
+    - "var x = new {'a': 'b'};"
+    - "var x = new {'a'};"
+    - "var x = new ['a'];"
+
 UnmatchedToken:
   template: "Can't find '#string' to match '#lexeme'."
   analyzerCode: EXPECTED_TOKEN
@@ -2904,6 +2952,14 @@
   template: "The type '#name' can't be used as supertype."
   analyzerCode: EXTENDS_NON_CLASS
 
+SupertypeIsIllegalAliased:
+  template: "The type '#name' which is an alias of '#type' can't be used as supertype."
+  analyzerCode: EXTENDS_NON_CLASS
+
+SupertypeIsNullableAliased:
+  template: "The type '#name' which is an alias of '#type' can't be used as supertype because it is nullable."
+  analyzerCode: EXTENDS_NON_CLASS
+
 SupertypeIsTypeVariable:
   template: "The type variable '#name' can't be used as supertype."
   analyzerCode: EXTENDS_NON_CLASS
@@ -3232,7 +3288,7 @@
   tip: "Try specifying the file explicitly with the --packages option."
 
 PackageNotFound:
-  template: "Could not resolve the package '#name' in '#uri'."
+  template: "Couldn't resolve the package '#name' in '#uri'."
 
 InvalidPackageUri:
   template: "Invalid package URI '#uri':\n  #string."
@@ -3491,10 +3547,22 @@
       c + 0;
     }
 
+UndefinedExtensionGetter:
+  template: "The getter '#name' isn't defined for the extension '#type'."
+  tip: "Try correcting the name to the name of an existing getter, or defining a getter or field named '#name'."
+
+UndefinedExtensionSetter:
+  template: "The setter '#name' isn't defined for the extension '#type'."
+  tip: "Try correcting the name to the name of an existing setter, or defining a setter or field named '#name'."
+
 UndefinedExtensionMethod:
   template: "The method '#name' isn't defined for the extension '#type'."
   tip: "Try correcting the name to the name of an existing method, or defining a method name '#name'."
 
+UndefinedExtensionOperator:
+  template: "The operator '#name' isn't defined for the extension '#type'."
+  tip: "Try correcting the operator to an existing operator, or defining a '#name' operator."
+
 AmbiguousExtensionMethod:
   template: "The method '#name' is defined in multiple extensions for '#type' and neither is more specific."
   tip: "Try using an explicit extension application of the wanted extension or hiding unwanted extensions from scope."
@@ -3610,7 +3678,7 @@
   analyzerCode: AMBIGUOUS_SUPERTYPES
 
 MixinInferenceNoMatchingClass:
-  template: "Type parameters could not be inferred for the mixin '#name' because '#name2' does not implement the mixin's supertype constraint '#type'."
+  template: "Type parameters couldn't be inferred for the mixin '#name' because '#name2' does not implement the mixin's supertype constraint '#type'."
   analyzerCode: MIXIN_INFERENCE_NO_POSSIBLE_SUBSTITUTION
 
 ImplicitCallOfNonMethod:
@@ -4253,7 +4321,7 @@
 
 FfiNotStatic:
   # Used by dart:ffi
-  template: "#name expects a static function as parameter. dart:ffi only supports calling static Dart functions from native code."
+  template: "#name expects a static function as parameter. dart:ffi only supports calling static Dart functions from native code. Closures and tear-offs are not supported because they can capture context."
   external: test/ffi_test.dart
 
 FfiFieldInitializer:
@@ -4267,11 +4335,31 @@
   template: "Class '#name' cannot be extended or implemented."
   external: test/ffi_test.dart
 
+FfiPackedAnnotation:
+  # Used by dart:ffi
+  template: "Struct '#name' must have at most one 'Packed' annotation."
+  external: test/ffi_test.dart
+
+FfiPackedAnnotationAlignment:
+  # Used by dart:ffi
+  template: "Only packing to 1, 2, 4, 8, and 16 bytes is supported."
+  external: test/ffi_test.dart
+
+FfiPackedNestingNonPacked:
+  # Used by dart:ffi
+  template: "Nesting the non-packed or less tightly packed struct '#name' in a packed struct '#name2' is not supported."
+  external: test/ffi_test.dart
+
 FfiSizeAnnotation:
   # Used by dart:ffi
   template: "Field '#name' must have exactly one 'Array' annotation."
   external: test/ffi_test.dart
 
+FfiSizeAnnotationDimensions:
+  # Used by dart:ffi
+  template: "Field '#name' must have an 'Array' annotation that matches the dimensions."
+  external: test/ffi_test.dart
+
 FfiStructGeneric:
   # Used by dart:ffi
   template: "Struct '#name' should not be generic."
@@ -4567,14 +4655,16 @@
   analyzerCode: ParserErrorCode.MULTIPLE_VARIANCE_MODIFIERS
 
 VariableCouldBeNullDueToWrite:
-  template: "Variable '#name' could be null due to an intervening write."
-  tip: "Try null checking the variable after the write."
+  template: "Variable '#name' could not be promoted due to an assignment."
+  tip: "Try null checking the variable after the assignment.  See #string"
 
 FieldNotPromoted:
-  template: "'#name' refers to a property so it could not be promoted."
+  template: "'#name' refers to a property so it couldn't be promoted."
+  tip: "See #string"
 
 ThisNotPromoted:
   template: "'this' can't be promoted."
+  tip: "See #string"
 
 NullablePropertyAccessError:
   template: "Property '#name' cannot be accessed on '#type' because it is potentially null."
@@ -4941,8 +5031,9 @@
   template: "The modifier '#lexeme' is only available in null safe libraries."
   exampleAllowMoreCodes: true
   analyzerCode: UNEXPECTED_TOKEN
-  script:
-    - "late int x;"
+  script: |
+    // @dart=2.9
+    late int x;
 
 CompilingWithSoundNullSafety:
   template: "Compiling with sound null safety"
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_45251.dart b/pkg/front_end/parser_testcases/error_recovery/issue_45251.dart
new file mode 100644
index 0000000..24d670e
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_45251.dart
@@ -0,0 +1,28 @@
+class F {
+  /* notice the braces at the end instead of parenthesis! */
+  final Map<String, Undefined> foo1 = Map<String, List<int>>{};
+
+  // variation #1: OK.
+  final Map<String, Undefined> foo2 = <String, List<int>>{};
+
+  // variation #2: Bad.
+  final Map<String, Undefined> foo3 = Map{};
+
+  // variation #3: OK.
+  final Map<String, Undefined> foo4 = Map<String, List<int>>();
+
+  // variation #4: OK.
+  final Map<String, Undefined> foo5 = Map();
+
+  // variation #5: Bad.
+  final Map<String, Undefined> foo6 = Map<String, List<int>>{"a": null};
+
+  // variation #6: Bad.
+  final Map<String, Undefined> foo7 = Map{"a": null};
+
+  // variation #7: OK.
+  final Map<String, Undefined> foo8 = <String, List<int>>{"a": null};
+
+  // variation #8: OK.
+  final Map<String, Undefined> foo9 = {"a": null};
+}
\ No newline at end of file
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_45251.dart.expect b/pkg/front_end/parser_testcases/error_recovery/issue_45251.dart.expect
new file mode 100644
index 0000000..702b63b
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_45251.dart.expect
@@ -0,0 +1,305 @@
+Problems reported:
+
+parser/error_recovery/issue_45251:3:39: A map literal can't be prefixed by 'Map'.
+  final Map<String, Undefined> foo1 = Map<String, List<int>>{};
+                                      ^^^
+
+parser/error_recovery/issue_45251:9:39: A map literal can't be prefixed by 'Map'.
+  final Map<String, Undefined> foo3 = Map{};
+                                      ^^^
+
+parser/error_recovery/issue_45251:18:39: A map literal can't be prefixed by 'Map'.
+  final Map<String, Undefined> foo6 = Map<String, List<int>>{"a": null};
+                                      ^^^
+
+parser/error_recovery/issue_45251:21:39: A map literal can't be prefixed by 'Map'.
+  final Map<String, Undefined> foo7 = Map{"a": null};
+                                      ^^^
+
+beginCompilationUnit(class)
+  beginMetadataStar(class)
+  endMetadataStar(0)
+  beginClassOrNamedMixinApplicationPrelude(class)
+    handleIdentifier(F, classOrMixinDeclaration)
+    handleNoTypeVariables({)
+    beginClassDeclaration(class, null, F)
+      handleNoType(F)
+      handleClassExtends(null, 1)
+      handleClassNoWithClause()
+      handleClassOrMixinImplements(null, 0)
+      handleClassHeader(class, class, null)
+      beginClassOrMixinBody(DeclarationKind.Class, {)
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields({)
+            handleIdentifier(Map, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(String, typeReference)
+              handleNoTypeArguments(,)
+              handleType(String, null)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(2, <, >)
+            handleType(Map, null)
+            handleIdentifier(foo1, fieldDeclaration)
+            beginFieldInitializer(=)
+              handleRecoverableError(Message[LiteralWithClass, A map literal can't be prefixed by 'Map'., Try removing 'Map', {string: map, lexeme: Map}], Map, Map)
+              beginTypeArguments(<)
+                handleIdentifier(String, typeReference)
+                handleNoTypeArguments(,)
+                handleType(String, null)
+                handleIdentifier(List, typeReference)
+                beginTypeArguments(<)
+                  handleIdentifier(int, typeReference)
+                  handleNoTypeArguments(>)
+                  handleType(int, null)
+                endTypeArguments(1, <, >)
+                handleType(List, null)
+              endTypeArguments(2, <, >)
+              handleLiteralSetOrMap(0, {, null, }, false)
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields(;)
+            handleIdentifier(Map, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(String, typeReference)
+              handleNoTypeArguments(,)
+              handleType(String, null)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(2, <, >)
+            handleType(Map, null)
+            handleIdentifier(foo2, fieldDeclaration)
+            beginFieldInitializer(=)
+              beginTypeArguments(<)
+                handleIdentifier(String, typeReference)
+                handleNoTypeArguments(,)
+                handleType(String, null)
+                handleIdentifier(List, typeReference)
+                beginTypeArguments(<)
+                  handleIdentifier(int, typeReference)
+                  handleNoTypeArguments(>)
+                  handleType(int, null)
+                endTypeArguments(1, <, >)
+                handleType(List, null)
+              endTypeArguments(2, <, >)
+              handleLiteralSetOrMap(0, {, null, }, false)
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields(;)
+            handleIdentifier(Map, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(String, typeReference)
+              handleNoTypeArguments(,)
+              handleType(String, null)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(2, <, >)
+            handleType(Map, null)
+            handleIdentifier(foo3, fieldDeclaration)
+            beginFieldInitializer(=)
+              handleRecoverableError(Message[LiteralWithClass, A map literal can't be prefixed by 'Map'., Try removing 'Map', {string: map, lexeme: Map}], Map, Map)
+              handleNoTypeArguments({)
+              handleLiteralSetOrMap(0, {, null, }, false)
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields(;)
+            handleIdentifier(Map, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(String, typeReference)
+              handleNoTypeArguments(,)
+              handleType(String, null)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(2, <, >)
+            handleType(Map, null)
+            handleIdentifier(foo4, fieldDeclaration)
+            beginFieldInitializer(=)
+              handleIdentifier(Map, expression)
+              beginTypeArguments(<)
+                handleIdentifier(String, typeReference)
+                handleNoTypeArguments(,)
+                handleType(String, null)
+                handleIdentifier(List, typeReference)
+                beginTypeArguments(<)
+                  handleIdentifier(int, typeReference)
+                  handleNoTypeArguments(>)
+                  handleType(int, null)
+                endTypeArguments(1, <, >)
+                handleType(List, null)
+              endTypeArguments(2, <, >)
+              beginArguments(()
+              endArguments(0, (, ))
+              handleSend(Map, ;)
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields(;)
+            handleIdentifier(Map, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(String, typeReference)
+              handleNoTypeArguments(,)
+              handleType(String, null)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(2, <, >)
+            handleType(Map, null)
+            handleIdentifier(foo5, fieldDeclaration)
+            beginFieldInitializer(=)
+              handleIdentifier(Map, expression)
+              handleNoTypeArguments(()
+              beginArguments(()
+              endArguments(0, (, ))
+              handleSend(Map, ;)
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields(;)
+            handleIdentifier(Map, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(String, typeReference)
+              handleNoTypeArguments(,)
+              handleType(String, null)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(2, <, >)
+            handleType(Map, null)
+            handleIdentifier(foo6, fieldDeclaration)
+            beginFieldInitializer(=)
+              handleRecoverableError(Message[LiteralWithClass, A map literal can't be prefixed by 'Map'., Try removing 'Map', {string: map, lexeme: Map}], Map, Map)
+              beginTypeArguments(<)
+                handleIdentifier(String, typeReference)
+                handleNoTypeArguments(,)
+                handleType(String, null)
+                handleIdentifier(List, typeReference)
+                beginTypeArguments(<)
+                  handleIdentifier(int, typeReference)
+                  handleNoTypeArguments(>)
+                  handleType(int, null)
+                endTypeArguments(1, <, >)
+                handleType(List, null)
+              endTypeArguments(2, <, >)
+              beginLiteralString("a")
+              endLiteralString(0, :)
+              handleLiteralNull(null)
+              handleLiteralMapEntry(:, })
+              handleLiteralSetOrMap(1, {, null, }, false)
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields(;)
+            handleIdentifier(Map, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(String, typeReference)
+              handleNoTypeArguments(,)
+              handleType(String, null)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(2, <, >)
+            handleType(Map, null)
+            handleIdentifier(foo7, fieldDeclaration)
+            beginFieldInitializer(=)
+              handleRecoverableError(Message[LiteralWithClass, A map literal can't be prefixed by 'Map'., Try removing 'Map', {string: map, lexeme: Map}], Map, Map)
+              handleNoTypeArguments({)
+              beginLiteralString("a")
+              endLiteralString(0, :)
+              handleLiteralNull(null)
+              handleLiteralMapEntry(:, })
+              handleLiteralSetOrMap(1, {, null, }, false)
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields(;)
+            handleIdentifier(Map, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(String, typeReference)
+              handleNoTypeArguments(,)
+              handleType(String, null)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(2, <, >)
+            handleType(Map, null)
+            handleIdentifier(foo8, fieldDeclaration)
+            beginFieldInitializer(=)
+              beginTypeArguments(<)
+                handleIdentifier(String, typeReference)
+                handleNoTypeArguments(,)
+                handleType(String, null)
+                handleIdentifier(List, typeReference)
+                beginTypeArguments(<)
+                  handleIdentifier(int, typeReference)
+                  handleNoTypeArguments(>)
+                  handleType(int, null)
+                endTypeArguments(1, <, >)
+                handleType(List, null)
+              endTypeArguments(2, <, >)
+              beginLiteralString("a")
+              endLiteralString(0, :)
+              handleLiteralNull(null)
+              handleLiteralMapEntry(:, })
+              handleLiteralSetOrMap(1, {, null, }, false)
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields(;)
+            handleIdentifier(Map, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(String, typeReference)
+              handleNoTypeArguments(,)
+              handleType(String, null)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(2, <, >)
+            handleType(Map, null)
+            handleIdentifier(foo9, fieldDeclaration)
+            beginFieldInitializer(=)
+              handleNoTypeArguments({)
+              beginLiteralString("a")
+              endLiteralString(0, :)
+              handleLiteralNull(null)
+              handleLiteralMapEntry(:, })
+              handleLiteralSetOrMap(1, {, null, }, false)
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+      endClassOrMixinBody(DeclarationKind.Class, 9, {, })
+    endClassDeclaration(class, })
+  endTopLevelDeclaration()
+endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_45251.dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/issue_45251.dart.intertwined.expect
new file mode 100644
index 0000000..8e981b1
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_45251.dart.intertwined.expect
@@ -0,0 +1,488 @@
+parseUnit(class)
+  skipErrorTokens(class)
+  listener: beginCompilationUnit(class)
+  syntheticPreviousToken(class)
+  parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+    parseMetadataStar()
+      listener: beginMetadataStar(class)
+      listener: endMetadataStar(0)
+    parseTopLevelKeywordDeclaration(, class, Instance of 'DirectiveContext')
+      parseClassDeclarationModifiers(, class)
+      parseClassOrNamedMixinApplication(null, class)
+        listener: beginClassOrNamedMixinApplicationPrelude(class)
+        ensureIdentifier(class, classOrMixinDeclaration)
+          listener: handleIdentifier(F, classOrMixinDeclaration)
+        listener: handleNoTypeVariables({)
+        listener: beginClassDeclaration(class, null, F)
+        parseClass(F, class, class, F)
+          parseClassHeaderOpt(F, class, class)
+            parseClassExtendsOpt(F)
+              listener: handleNoType(F)
+              listener: handleClassExtends(null, 1)
+            parseWithClauseOpt(F)
+              listener: handleClassNoWithClause()
+            parseClassOrMixinImplementsOpt(F)
+              listener: handleClassOrMixinImplements(null, 0)
+            listener: handleClassHeader(class, class, null)
+          parseClassOrMixinOrExtensionBody(F, DeclarationKind.Class, F)
+            listener: beginClassOrMixinBody(DeclarationKind.Class, {)
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl({, DeclarationKind.Class, F)
+              parseMetadataStar({)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields({, null, null, null, null, null, final, final, Instance of 'ComplexTypeInfo', foo1, DeclarationKind.Class, F, false)
+                listener: beginFields({)
+                ensureIdentifier(final, typeReference)
+                  listener: handleIdentifier(Map, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(String, typeReference)
+                listener: handleNoTypeArguments(,)
+                listener: handleType(String, null)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(2, <, >)
+                listener: handleType(Map, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo1, fieldDeclaration)
+                parseFieldInitializerOpt(foo1, foo1, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseSendOrFunctionLiteral(=, expression)
+                            parseSend(=, expression)
+                              reportRecoverableError(Map, Message[LiteralWithClass, A map literal can't be prefixed by 'Map'., Try removing 'Map', {string: map, lexeme: Map}])
+                                listener: handleRecoverableError(Message[LiteralWithClass, A map literal can't be prefixed by 'Map'., Try removing 'Map', {string: map, lexeme: Map}], Map, Map)
+                              parsePrimary(Map, expression)
+                                parseLiteralListSetMapOrFunction(Map, null)
+                                  listener: beginTypeArguments(<)
+                                  listener: handleIdentifier(String, typeReference)
+                                  listener: handleNoTypeArguments(,)
+                                  listener: handleType(String, null)
+                                  listener: handleIdentifier(List, typeReference)
+                                  listener: beginTypeArguments(<)
+                                  listener: handleIdentifier(int, typeReference)
+                                  listener: handleNoTypeArguments(>)
+                                  listener: handleType(int, null)
+                                  listener: endTypeArguments(1, <, >)
+                                  listener: handleType(List, null)
+                                  listener: endTypeArguments(2, <, >)
+                                  parseLiteralSetOrMapSuffix(>, null)
+                                    listener: handleLiteralSetOrMap(0, {, null, }, false)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, F)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, final, final, Instance of 'ComplexTypeInfo', foo2, DeclarationKind.Class, F, false)
+                listener: beginFields(;)
+                ensureIdentifier(final, typeReference)
+                  listener: handleIdentifier(Map, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(String, typeReference)
+                listener: handleNoTypeArguments(,)
+                listener: handleType(String, null)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(2, <, >)
+                listener: handleType(Map, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo2, fieldDeclaration)
+                parseFieldInitializerOpt(foo2, foo2, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseLiteralListSetMapOrFunction(=, null)
+                            listener: beginTypeArguments(<)
+                            listener: handleIdentifier(String, typeReference)
+                            listener: handleNoTypeArguments(,)
+                            listener: handleType(String, null)
+                            listener: handleIdentifier(List, typeReference)
+                            listener: beginTypeArguments(<)
+                            listener: handleIdentifier(int, typeReference)
+                            listener: handleNoTypeArguments(>)
+                            listener: handleType(int, null)
+                            listener: endTypeArguments(1, <, >)
+                            listener: handleType(List, null)
+                            listener: endTypeArguments(2, <, >)
+                            parseLiteralSetOrMapSuffix(>, null)
+                              listener: handleLiteralSetOrMap(0, {, null, }, false)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, F)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, final, final, Instance of 'ComplexTypeInfo', foo3, DeclarationKind.Class, F, false)
+                listener: beginFields(;)
+                ensureIdentifier(final, typeReference)
+                  listener: handleIdentifier(Map, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(String, typeReference)
+                listener: handleNoTypeArguments(,)
+                listener: handleType(String, null)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(2, <, >)
+                listener: handleType(Map, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo3, fieldDeclaration)
+                parseFieldInitializerOpt(foo3, foo3, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseSendOrFunctionLiteral(=, expression)
+                            parseSend(=, expression)
+                              reportRecoverableError(Map, Message[LiteralWithClass, A map literal can't be prefixed by 'Map'., Try removing 'Map', {string: map, lexeme: Map}])
+                                listener: handleRecoverableError(Message[LiteralWithClass, A map literal can't be prefixed by 'Map'., Try removing 'Map', {string: map, lexeme: Map}], Map, Map)
+                              parsePrimary(Map, expression)
+                                listener: handleNoTypeArguments({)
+                                parseLiteralSetOrMapSuffix(Map, null)
+                                  listener: handleLiteralSetOrMap(0, {, null, }, false)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, F)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, final, final, Instance of 'ComplexTypeInfo', foo4, DeclarationKind.Class, F, false)
+                listener: beginFields(;)
+                ensureIdentifier(final, typeReference)
+                  listener: handleIdentifier(Map, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(String, typeReference)
+                listener: handleNoTypeArguments(,)
+                listener: handleType(String, null)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(2, <, >)
+                listener: handleType(Map, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo4, fieldDeclaration)
+                parseFieldInitializerOpt(foo4, foo4, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseSendOrFunctionLiteral(=, expression)
+                            looksLikeFunctionBody(;)
+                            parseSend(=, expression)
+                              ensureIdentifier(=, expression)
+                                listener: handleIdentifier(Map, expression)
+                              listener: beginTypeArguments(<)
+                              listener: handleIdentifier(String, typeReference)
+                              listener: handleNoTypeArguments(,)
+                              listener: handleType(String, null)
+                              listener: handleIdentifier(List, typeReference)
+                              listener: beginTypeArguments(<)
+                              listener: handleIdentifier(int, typeReference)
+                              listener: handleNoTypeArguments(>)
+                              listener: handleType(int, null)
+                              listener: endTypeArguments(1, <, >)
+                              listener: handleType(List, null)
+                              listener: endTypeArguments(2, <, >)
+                              parseArgumentsOpt(>)
+                                parseArguments(>)
+                                  parseArgumentsRest(()
+                                    listener: beginArguments(()
+                                    listener: endArguments(0, (, ))
+                              listener: handleSend(Map, ;)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, F)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, final, final, Instance of 'ComplexTypeInfo', foo5, DeclarationKind.Class, F, false)
+                listener: beginFields(;)
+                ensureIdentifier(final, typeReference)
+                  listener: handleIdentifier(Map, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(String, typeReference)
+                listener: handleNoTypeArguments(,)
+                listener: handleType(String, null)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(2, <, >)
+                listener: handleType(Map, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo5, fieldDeclaration)
+                parseFieldInitializerOpt(foo5, foo5, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseSendOrFunctionLiteral(=, expression)
+                            looksLikeFunctionBody(;)
+                            parseSend(=, expression)
+                              ensureIdentifier(=, expression)
+                                listener: handleIdentifier(Map, expression)
+                              listener: handleNoTypeArguments(()
+                              parseArgumentsOpt(Map)
+                                parseArguments(Map)
+                                  parseArgumentsRest(()
+                                    listener: beginArguments(()
+                                    listener: endArguments(0, (, ))
+                              listener: handleSend(Map, ;)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, F)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, final, final, Instance of 'ComplexTypeInfo', foo6, DeclarationKind.Class, F, false)
+                listener: beginFields(;)
+                ensureIdentifier(final, typeReference)
+                  listener: handleIdentifier(Map, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(String, typeReference)
+                listener: handleNoTypeArguments(,)
+                listener: handleType(String, null)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(2, <, >)
+                listener: handleType(Map, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo6, fieldDeclaration)
+                parseFieldInitializerOpt(foo6, foo6, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseSendOrFunctionLiteral(=, expression)
+                            parseSend(=, expression)
+                              reportRecoverableError(Map, Message[LiteralWithClass, A map literal can't be prefixed by 'Map'., Try removing 'Map', {string: map, lexeme: Map}])
+                                listener: handleRecoverableError(Message[LiteralWithClass, A map literal can't be prefixed by 'Map'., Try removing 'Map', {string: map, lexeme: Map}], Map, Map)
+                              parsePrimary(Map, expression)
+                                parseLiteralListSetMapOrFunction(Map, null)
+                                  listener: beginTypeArguments(<)
+                                  listener: handleIdentifier(String, typeReference)
+                                  listener: handleNoTypeArguments(,)
+                                  listener: handleType(String, null)
+                                  listener: handleIdentifier(List, typeReference)
+                                  listener: beginTypeArguments(<)
+                                  listener: handleIdentifier(int, typeReference)
+                                  listener: handleNoTypeArguments(>)
+                                  listener: handleType(int, null)
+                                  listener: endTypeArguments(1, <, >)
+                                  listener: handleType(List, null)
+                                  listener: endTypeArguments(2, <, >)
+                                  parseLiteralSetOrMapSuffix(>, null)
+                                    parseExpression({)
+                                      parsePrecedenceExpression({, 1, true)
+                                        parseUnaryExpression({, true)
+                                          parsePrimary({, expression)
+                                            parseLiteralString({)
+                                              parseSingleLiteralString({)
+                                                listener: beginLiteralString("a")
+                                                listener: endLiteralString(0, :)
+                                    parseExpression(:)
+                                      parsePrecedenceExpression(:, 1, true)
+                                        parseUnaryExpression(:, true)
+                                          parsePrimary(:, expression)
+                                            parseLiteralNull(:)
+                                              listener: handleLiteralNull(null)
+                                    listener: handleLiteralMapEntry(:, })
+                                    listener: handleLiteralSetOrMap(1, {, null, }, false)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, F)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, final, final, Instance of 'ComplexTypeInfo', foo7, DeclarationKind.Class, F, false)
+                listener: beginFields(;)
+                ensureIdentifier(final, typeReference)
+                  listener: handleIdentifier(Map, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(String, typeReference)
+                listener: handleNoTypeArguments(,)
+                listener: handleType(String, null)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(2, <, >)
+                listener: handleType(Map, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo7, fieldDeclaration)
+                parseFieldInitializerOpt(foo7, foo7, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseSendOrFunctionLiteral(=, expression)
+                            parseSend(=, expression)
+                              reportRecoverableError(Map, Message[LiteralWithClass, A map literal can't be prefixed by 'Map'., Try removing 'Map', {string: map, lexeme: Map}])
+                                listener: handleRecoverableError(Message[LiteralWithClass, A map literal can't be prefixed by 'Map'., Try removing 'Map', {string: map, lexeme: Map}], Map, Map)
+                              parsePrimary(Map, expression)
+                                listener: handleNoTypeArguments({)
+                                parseLiteralSetOrMapSuffix(Map, null)
+                                  parseExpression({)
+                                    parsePrecedenceExpression({, 1, true)
+                                      parseUnaryExpression({, true)
+                                        parsePrimary({, expression)
+                                          parseLiteralString({)
+                                            parseSingleLiteralString({)
+                                              listener: beginLiteralString("a")
+                                              listener: endLiteralString(0, :)
+                                  parseExpression(:)
+                                    parsePrecedenceExpression(:, 1, true)
+                                      parseUnaryExpression(:, true)
+                                        parsePrimary(:, expression)
+                                          parseLiteralNull(:)
+                                            listener: handleLiteralNull(null)
+                                  listener: handleLiteralMapEntry(:, })
+                                  listener: handleLiteralSetOrMap(1, {, null, }, false)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, F)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, final, final, Instance of 'ComplexTypeInfo', foo8, DeclarationKind.Class, F, false)
+                listener: beginFields(;)
+                ensureIdentifier(final, typeReference)
+                  listener: handleIdentifier(Map, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(String, typeReference)
+                listener: handleNoTypeArguments(,)
+                listener: handleType(String, null)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(2, <, >)
+                listener: handleType(Map, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo8, fieldDeclaration)
+                parseFieldInitializerOpt(foo8, foo8, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseLiteralListSetMapOrFunction(=, null)
+                            listener: beginTypeArguments(<)
+                            listener: handleIdentifier(String, typeReference)
+                            listener: handleNoTypeArguments(,)
+                            listener: handleType(String, null)
+                            listener: handleIdentifier(List, typeReference)
+                            listener: beginTypeArguments(<)
+                            listener: handleIdentifier(int, typeReference)
+                            listener: handleNoTypeArguments(>)
+                            listener: handleType(int, null)
+                            listener: endTypeArguments(1, <, >)
+                            listener: handleType(List, null)
+                            listener: endTypeArguments(2, <, >)
+                            parseLiteralSetOrMapSuffix(>, null)
+                              parseExpression({)
+                                parsePrecedenceExpression({, 1, true)
+                                  parseUnaryExpression({, true)
+                                    parsePrimary({, expression)
+                                      parseLiteralString({)
+                                        parseSingleLiteralString({)
+                                          listener: beginLiteralString("a")
+                                          listener: endLiteralString(0, :)
+                              parseExpression(:)
+                                parsePrecedenceExpression(:, 1, true)
+                                  parseUnaryExpression(:, true)
+                                    parsePrimary(:, expression)
+                                      parseLiteralNull(:)
+                                        listener: handleLiteralNull(null)
+                              listener: handleLiteralMapEntry(:, })
+                              listener: handleLiteralSetOrMap(1, {, null, }, false)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, F)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, final, final, Instance of 'ComplexTypeInfo', foo9, DeclarationKind.Class, F, false)
+                listener: beginFields(;)
+                ensureIdentifier(final, typeReference)
+                  listener: handleIdentifier(Map, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(String, typeReference)
+                listener: handleNoTypeArguments(,)
+                listener: handleType(String, null)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(2, <, >)
+                listener: handleType(Map, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo9, fieldDeclaration)
+                parseFieldInitializerOpt(foo9, foo9, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          listener: handleNoTypeArguments({)
+                          parseLiteralSetOrMapSuffix(=, null)
+                            parseExpression({)
+                              parsePrecedenceExpression({, 1, true)
+                                parseUnaryExpression({, true)
+                                  parsePrimary({, expression)
+                                    parseLiteralString({)
+                                      parseSingleLiteralString({)
+                                        listener: beginLiteralString("a")
+                                        listener: endLiteralString(0, :)
+                            parseExpression(:)
+                              parsePrecedenceExpression(:, 1, true)
+                                parseUnaryExpression(:, true)
+                                  parsePrimary(:, expression)
+                                    parseLiteralNull(:)
+                                      listener: handleLiteralNull(null)
+                            listener: handleLiteralMapEntry(:, })
+                            listener: handleLiteralSetOrMap(1, {, null, }, false)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, })
+            listener: endClassOrMixinBody(DeclarationKind.Class, 9, {, })
+          listener: endClassDeclaration(class, })
+  listener: endTopLevelDeclaration()
+  reportAllErrorTokens(class)
+  listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_45251.dart.parser.expect b/pkg/front_end/parser_testcases/error_recovery/issue_45251.dart.parser.expect
new file mode 100644
index 0000000..682cbcb
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_45251.dart.parser.expect
@@ -0,0 +1,59 @@
+NOTICE: Stream was rewritten by parser!
+
+class F {
+
+final Map<String, Undefined> foo1 = Map<String, List<int>>{};
+
+
+final Map<String, Undefined> foo2 = <String, List<int>>{};
+
+
+final Map<String, Undefined> foo3 = Map{};
+
+
+final Map<String, Undefined> foo4 = Map<String, List<int>>();
+
+
+final Map<String, Undefined> foo5 = Map();
+
+
+final Map<String, Undefined> foo6 = Map<String, List<int>>{"a": null};
+
+
+final Map<String, Undefined> foo7 = Map{"a": null};
+
+
+final Map<String, Undefined> foo8 = <String, List<int>>{"a": null};
+
+
+final Map<String, Undefined> foo9 = {"a": null};
+}
+
+class[KeywordToken] F[StringToken] {[BeginToken]
+
+final[KeywordToken] Map[StringToken]<[BeginToken]String[StringToken],[SimpleToken] Undefined[StringToken]>[SimpleToken] foo1[StringToken] =[SimpleToken] Map[StringToken]<[BeginToken]String[StringToken],[SimpleToken] List[StringToken]<[BeginToken]int[StringToken]>[SimpleToken]>[SimpleToken]{[BeginToken]}[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Map[StringToken]<[BeginToken]String[StringToken],[SimpleToken] Undefined[StringToken]>[SimpleToken] foo2[StringToken] =[SimpleToken] <[BeginToken]String[StringToken],[SimpleToken] List[StringToken]<[BeginToken]int[StringToken]>[SimpleToken]>[SimpleToken]{[BeginToken]}[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Map[StringToken]<[BeginToken]String[StringToken],[SimpleToken] Undefined[StringToken]>[SimpleToken] foo3[StringToken] =[SimpleToken] Map[StringToken]{[BeginToken]}[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Map[StringToken]<[BeginToken]String[StringToken],[SimpleToken] Undefined[StringToken]>[SimpleToken] foo4[StringToken] =[SimpleToken] Map[StringToken]<[BeginToken]String[StringToken],[SimpleToken] List[StringToken]<[BeginToken]int[StringToken]>[SimpleToken]>[SimpleToken]([BeginToken])[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Map[StringToken]<[BeginToken]String[StringToken],[SimpleToken] Undefined[StringToken]>[SimpleToken] foo5[StringToken] =[SimpleToken] Map[StringToken]([BeginToken])[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Map[StringToken]<[BeginToken]String[StringToken],[SimpleToken] Undefined[StringToken]>[SimpleToken] foo6[StringToken] =[SimpleToken] Map[StringToken]<[BeginToken]String[StringToken],[SimpleToken] List[StringToken]<[BeginToken]int[StringToken]>[SimpleToken]>[SimpleToken]{[BeginToken]"a"[StringToken]:[SimpleToken] null[KeywordToken]}[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Map[StringToken]<[BeginToken]String[StringToken],[SimpleToken] Undefined[StringToken]>[SimpleToken] foo7[StringToken] =[SimpleToken] Map[StringToken]{[BeginToken]"a"[StringToken]:[SimpleToken] null[KeywordToken]}[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Map[StringToken]<[BeginToken]String[StringToken],[SimpleToken] Undefined[StringToken]>[SimpleToken] foo8[StringToken] =[SimpleToken] <[BeginToken]String[StringToken],[SimpleToken] List[StringToken]<[BeginToken]int[StringToken]>[SimpleToken]>[SimpleToken]{[BeginToken]"a"[StringToken]:[SimpleToken] null[KeywordToken]}[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Map[StringToken]<[BeginToken]String[StringToken],[SimpleToken] Undefined[StringToken]>[SimpleToken] foo9[StringToken] =[SimpleToken] {[BeginToken]"a"[StringToken]:[SimpleToken] null[KeywordToken]}[SimpleToken];[SimpleToken]
+}[SimpleToken][SimpleToken]
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_45251.dart.scanner.expect b/pkg/front_end/parser_testcases/error_recovery/issue_45251.dart.scanner.expect
new file mode 100644
index 0000000..44dc9e8
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_45251.dart.scanner.expect
@@ -0,0 +1,57 @@
+class F {
+
+final Map<String, Undefined> foo1 = Map<String, List<int>>{};
+
+
+final Map<String, Undefined> foo2 = <String, List<int>>{};
+
+
+final Map<String, Undefined> foo3 = Map{};
+
+
+final Map<String, Undefined> foo4 = Map<String, List<int>>();
+
+
+final Map<String, Undefined> foo5 = Map();
+
+
+final Map<String, Undefined> foo6 = Map<String, List<int>>{"a": null};
+
+
+final Map<String, Undefined> foo7 = Map{"a": null};
+
+
+final Map<String, Undefined> foo8 = <String, List<int>>{"a": null};
+
+
+final Map<String, Undefined> foo9 = {"a": null};
+}
+
+class[KeywordToken] F[StringToken] {[BeginToken]
+
+final[KeywordToken] Map[StringToken]<[BeginToken]String[StringToken],[SimpleToken] Undefined[StringToken]>[SimpleToken] foo1[StringToken] =[SimpleToken] Map[StringToken]<[BeginToken]String[StringToken],[SimpleToken] List[StringToken]<[BeginToken]int[StringToken]>>[SimpleToken]{[BeginToken]}[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Map[StringToken]<[BeginToken]String[StringToken],[SimpleToken] Undefined[StringToken]>[SimpleToken] foo2[StringToken] =[SimpleToken] <[BeginToken]String[StringToken],[SimpleToken] List[StringToken]<[BeginToken]int[StringToken]>>[SimpleToken]{[BeginToken]}[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Map[StringToken]<[BeginToken]String[StringToken],[SimpleToken] Undefined[StringToken]>[SimpleToken] foo3[StringToken] =[SimpleToken] Map[StringToken]{[BeginToken]}[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Map[StringToken]<[BeginToken]String[StringToken],[SimpleToken] Undefined[StringToken]>[SimpleToken] foo4[StringToken] =[SimpleToken] Map[StringToken]<[BeginToken]String[StringToken],[SimpleToken] List[StringToken]<[BeginToken]int[StringToken]>>[SimpleToken]([BeginToken])[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Map[StringToken]<[BeginToken]String[StringToken],[SimpleToken] Undefined[StringToken]>[SimpleToken] foo5[StringToken] =[SimpleToken] Map[StringToken]([BeginToken])[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Map[StringToken]<[BeginToken]String[StringToken],[SimpleToken] Undefined[StringToken]>[SimpleToken] foo6[StringToken] =[SimpleToken] Map[StringToken]<[BeginToken]String[StringToken],[SimpleToken] List[StringToken]<[BeginToken]int[StringToken]>>[SimpleToken]{[BeginToken]"a"[StringToken]:[SimpleToken] null[KeywordToken]}[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Map[StringToken]<[BeginToken]String[StringToken],[SimpleToken] Undefined[StringToken]>[SimpleToken] foo7[StringToken] =[SimpleToken] Map[StringToken]{[BeginToken]"a"[StringToken]:[SimpleToken] null[KeywordToken]}[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Map[StringToken]<[BeginToken]String[StringToken],[SimpleToken] Undefined[StringToken]>[SimpleToken] foo8[StringToken] =[SimpleToken] <[BeginToken]String[StringToken],[SimpleToken] List[StringToken]<[BeginToken]int[StringToken]>>[SimpleToken]{[BeginToken]"a"[StringToken]:[SimpleToken] null[KeywordToken]}[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Map[StringToken]<[BeginToken]String[StringToken],[SimpleToken] Undefined[StringToken]>[SimpleToken] foo9[StringToken] =[SimpleToken] {[BeginToken]"a"[StringToken]:[SimpleToken] null[KeywordToken]}[SimpleToken];[SimpleToken]
+}[SimpleToken][SimpleToken]
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_45251_const.dart b/pkg/front_end/parser_testcases/error_recovery/issue_45251_const.dart
new file mode 100644
index 0000000..51c5929
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_45251_const.dart
@@ -0,0 +1,28 @@
+class F {
+  /* notice the braces at the end instead of parenthesis! */
+  final Map<String, Undefined> foo1 = const Map<String, List<int>>{};
+
+  // variation #1: OK.
+  final Map<String, Undefined> foo2 = const <String, List<int>>{};
+
+  // variation #2: Bad.
+  final Map<String, Undefined> foo3 = const Map{};
+
+  // variation #3: OK.
+  final Map<String, Undefined> foo4 = const Map<String, List<int>>();
+
+  // variation #4: OK.
+  final Map<String, Undefined> foo5 = const Map();
+
+  // variation #5: Bad.
+  final Map<String, Undefined> foo6 = const Map<String, List<int>>{"a": null};
+
+  // variation #6: Bad.
+  final Map<String, Undefined> foo7 = const Map{"a": null};
+
+  // variation #7: OK.
+  final Map<String, Undefined> foo8 = const <String, List<int>>{"a": null};
+
+  // variation #8: OK.
+  final Map<String, Undefined> foo9 = const {"a": null};
+}
\ No newline at end of file
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_45251_const.dart.expect b/pkg/front_end/parser_testcases/error_recovery/issue_45251_const.dart.expect
new file mode 100644
index 0000000..0291006
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_45251_const.dart.expect
@@ -0,0 +1,327 @@
+Problems reported:
+
+parser/error_recovery/issue_45251_const:3:45: A map literal can't be prefixed by 'Map'.
+  final Map<String, Undefined> foo1 = const Map<String, List<int>>{};
+                                            ^^^
+
+parser/error_recovery/issue_45251_const:9:45: A map literal can't be prefixed by 'Map'.
+  final Map<String, Undefined> foo3 = const Map{};
+                                            ^^^
+
+parser/error_recovery/issue_45251_const:18:45: A map literal can't be prefixed by 'Map'.
+  final Map<String, Undefined> foo6 = const Map<String, List<int>>{"a": null};
+                                            ^^^
+
+parser/error_recovery/issue_45251_const:21:45: A map literal can't be prefixed by 'Map'.
+  final Map<String, Undefined> foo7 = const Map{"a": null};
+                                            ^^^
+
+beginCompilationUnit(class)
+  beginMetadataStar(class)
+  endMetadataStar(0)
+  beginClassOrNamedMixinApplicationPrelude(class)
+    handleIdentifier(F, classOrMixinDeclaration)
+    handleNoTypeVariables({)
+    beginClassDeclaration(class, null, F)
+      handleNoType(F)
+      handleClassExtends(null, 1)
+      handleClassNoWithClause()
+      handleClassOrMixinImplements(null, 0)
+      handleClassHeader(class, class, null)
+      beginClassOrMixinBody(DeclarationKind.Class, {)
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields({)
+            handleIdentifier(Map, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(String, typeReference)
+              handleNoTypeArguments(,)
+              handleType(String, null)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(2, <, >)
+            handleType(Map, null)
+            handleIdentifier(foo1, fieldDeclaration)
+            beginFieldInitializer(=)
+              handleRecoverableError(Message[LiteralWithClass, A map literal can't be prefixed by 'Map'., Try removing 'Map', {string: map, lexeme: Map}], Map, Map)
+              beginConstLiteral(<)
+                beginTypeArguments(<)
+                  handleIdentifier(String, typeReference)
+                  handleNoTypeArguments(,)
+                  handleType(String, null)
+                  handleIdentifier(List, typeReference)
+                  beginTypeArguments(<)
+                    handleIdentifier(int, typeReference)
+                    handleNoTypeArguments(>)
+                    handleType(int, null)
+                  endTypeArguments(1, <, >)
+                  handleType(List, null)
+                endTypeArguments(2, <, >)
+                handleLiteralSetOrMap(0, {, const, }, false)
+              endConstLiteral(;)
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields(;)
+            handleIdentifier(Map, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(String, typeReference)
+              handleNoTypeArguments(,)
+              handleType(String, null)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(2, <, >)
+            handleType(Map, null)
+            handleIdentifier(foo2, fieldDeclaration)
+            beginFieldInitializer(=)
+              beginConstLiteral(<)
+                beginTypeArguments(<)
+                  handleIdentifier(String, typeReference)
+                  handleNoTypeArguments(,)
+                  handleType(String, null)
+                  handleIdentifier(List, typeReference)
+                  beginTypeArguments(<)
+                    handleIdentifier(int, typeReference)
+                    handleNoTypeArguments(>)
+                    handleType(int, null)
+                  endTypeArguments(1, <, >)
+                  handleType(List, null)
+                endTypeArguments(2, <, >)
+                handleLiteralSetOrMap(0, {, const, }, false)
+              endConstLiteral(;)
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields(;)
+            handleIdentifier(Map, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(String, typeReference)
+              handleNoTypeArguments(,)
+              handleType(String, null)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(2, <, >)
+            handleType(Map, null)
+            handleIdentifier(foo3, fieldDeclaration)
+            beginFieldInitializer(=)
+              handleRecoverableError(Message[LiteralWithClass, A map literal can't be prefixed by 'Map'., Try removing 'Map', {string: map, lexeme: Map}], Map, Map)
+              beginConstLiteral({)
+                handleNoTypeArguments({)
+                handleLiteralSetOrMap(0, {, const, }, false)
+              endConstLiteral(;)
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields(;)
+            handleIdentifier(Map, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(String, typeReference)
+              handleNoTypeArguments(,)
+              handleType(String, null)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(2, <, >)
+            handleType(Map, null)
+            handleIdentifier(foo4, fieldDeclaration)
+            beginFieldInitializer(=)
+              beginConstExpression(const)
+                handleIdentifier(Map, constructorReference)
+                beginConstructorReference(Map)
+                  beginTypeArguments(<)
+                    handleIdentifier(String, typeReference)
+                    handleNoTypeArguments(,)
+                    handleType(String, null)
+                    handleIdentifier(List, typeReference)
+                    beginTypeArguments(<)
+                      handleIdentifier(int, typeReference)
+                      handleNoTypeArguments(>)
+                      handleType(int, null)
+                    endTypeArguments(1, <, >)
+                    handleType(List, null)
+                  endTypeArguments(2, <, >)
+                  handleNoConstructorReferenceContinuationAfterTypeArguments(()
+                endConstructorReference(Map, null, ()
+                beginArguments(()
+                endArguments(0, (, ))
+              endConstExpression(const)
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields(;)
+            handleIdentifier(Map, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(String, typeReference)
+              handleNoTypeArguments(,)
+              handleType(String, null)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(2, <, >)
+            handleType(Map, null)
+            handleIdentifier(foo5, fieldDeclaration)
+            beginFieldInitializer(=)
+              beginConstExpression(const)
+                handleIdentifier(Map, constructorReference)
+                beginConstructorReference(Map)
+                  handleNoTypeArguments(()
+                  handleNoConstructorReferenceContinuationAfterTypeArguments(()
+                endConstructorReference(Map, null, ()
+                beginArguments(()
+                endArguments(0, (, ))
+              endConstExpression(const)
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields(;)
+            handleIdentifier(Map, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(String, typeReference)
+              handleNoTypeArguments(,)
+              handleType(String, null)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(2, <, >)
+            handleType(Map, null)
+            handleIdentifier(foo6, fieldDeclaration)
+            beginFieldInitializer(=)
+              handleRecoverableError(Message[LiteralWithClass, A map literal can't be prefixed by 'Map'., Try removing 'Map', {string: map, lexeme: Map}], Map, Map)
+              beginConstLiteral(<)
+                beginTypeArguments(<)
+                  handleIdentifier(String, typeReference)
+                  handleNoTypeArguments(,)
+                  handleType(String, null)
+                  handleIdentifier(List, typeReference)
+                  beginTypeArguments(<)
+                    handleIdentifier(int, typeReference)
+                    handleNoTypeArguments(>)
+                    handleType(int, null)
+                  endTypeArguments(1, <, >)
+                  handleType(List, null)
+                endTypeArguments(2, <, >)
+                beginLiteralString("a")
+                endLiteralString(0, :)
+                handleLiteralNull(null)
+                handleLiteralMapEntry(:, })
+                handleLiteralSetOrMap(1, {, const, }, false)
+              endConstLiteral(;)
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields(;)
+            handleIdentifier(Map, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(String, typeReference)
+              handleNoTypeArguments(,)
+              handleType(String, null)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(2, <, >)
+            handleType(Map, null)
+            handleIdentifier(foo7, fieldDeclaration)
+            beginFieldInitializer(=)
+              handleRecoverableError(Message[LiteralWithClass, A map literal can't be prefixed by 'Map'., Try removing 'Map', {string: map, lexeme: Map}], Map, Map)
+              beginConstLiteral({)
+                handleNoTypeArguments({)
+                beginLiteralString("a")
+                endLiteralString(0, :)
+                handleLiteralNull(null)
+                handleLiteralMapEntry(:, })
+                handleLiteralSetOrMap(1, {, const, }, false)
+              endConstLiteral(;)
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields(;)
+            handleIdentifier(Map, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(String, typeReference)
+              handleNoTypeArguments(,)
+              handleType(String, null)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(2, <, >)
+            handleType(Map, null)
+            handleIdentifier(foo8, fieldDeclaration)
+            beginFieldInitializer(=)
+              beginConstLiteral(<)
+                beginTypeArguments(<)
+                  handleIdentifier(String, typeReference)
+                  handleNoTypeArguments(,)
+                  handleType(String, null)
+                  handleIdentifier(List, typeReference)
+                  beginTypeArguments(<)
+                    handleIdentifier(int, typeReference)
+                    handleNoTypeArguments(>)
+                    handleType(int, null)
+                  endTypeArguments(1, <, >)
+                  handleType(List, null)
+                endTypeArguments(2, <, >)
+                beginLiteralString("a")
+                endLiteralString(0, :)
+                handleLiteralNull(null)
+                handleLiteralMapEntry(:, })
+                handleLiteralSetOrMap(1, {, const, }, false)
+              endConstLiteral(;)
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields(;)
+            handleIdentifier(Map, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(String, typeReference)
+              handleNoTypeArguments(,)
+              handleType(String, null)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(2, <, >)
+            handleType(Map, null)
+            handleIdentifier(foo9, fieldDeclaration)
+            beginFieldInitializer(=)
+              beginConstLiteral({)
+                handleNoTypeArguments({)
+                beginLiteralString("a")
+                endLiteralString(0, :)
+                handleLiteralNull(null)
+                handleLiteralMapEntry(:, })
+                handleLiteralSetOrMap(1, {, const, }, false)
+              endConstLiteral(;)
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+      endClassOrMixinBody(DeclarationKind.Class, 9, {, })
+    endClassDeclaration(class, })
+  endTopLevelDeclaration()
+endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_45251_const.dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/issue_45251_const.dart.intertwined.expect
new file mode 100644
index 0000000..3d2e81d
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_45251_const.dart.intertwined.expect
@@ -0,0 +1,503 @@
+parseUnit(class)
+  skipErrorTokens(class)
+  listener: beginCompilationUnit(class)
+  syntheticPreviousToken(class)
+  parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+    parseMetadataStar()
+      listener: beginMetadataStar(class)
+      listener: endMetadataStar(0)
+    parseTopLevelKeywordDeclaration(, class, Instance of 'DirectiveContext')
+      parseClassDeclarationModifiers(, class)
+      parseClassOrNamedMixinApplication(null, class)
+        listener: beginClassOrNamedMixinApplicationPrelude(class)
+        ensureIdentifier(class, classOrMixinDeclaration)
+          listener: handleIdentifier(F, classOrMixinDeclaration)
+        listener: handleNoTypeVariables({)
+        listener: beginClassDeclaration(class, null, F)
+        parseClass(F, class, class, F)
+          parseClassHeaderOpt(F, class, class)
+            parseClassExtendsOpt(F)
+              listener: handleNoType(F)
+              listener: handleClassExtends(null, 1)
+            parseWithClauseOpt(F)
+              listener: handleClassNoWithClause()
+            parseClassOrMixinImplementsOpt(F)
+              listener: handleClassOrMixinImplements(null, 0)
+            listener: handleClassHeader(class, class, null)
+          parseClassOrMixinOrExtensionBody(F, DeclarationKind.Class, F)
+            listener: beginClassOrMixinBody(DeclarationKind.Class, {)
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl({, DeclarationKind.Class, F)
+              parseMetadataStar({)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields({, null, null, null, null, null, final, final, Instance of 'ComplexTypeInfo', foo1, DeclarationKind.Class, F, false)
+                listener: beginFields({)
+                ensureIdentifier(final, typeReference)
+                  listener: handleIdentifier(Map, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(String, typeReference)
+                listener: handleNoTypeArguments(,)
+                listener: handleType(String, null)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(2, <, >)
+                listener: handleType(Map, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo1, fieldDeclaration)
+                parseFieldInitializerOpt(foo1, foo1, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseConstExpression(=)
+                            reportRecoverableError(Map, Message[LiteralWithClass, A map literal can't be prefixed by 'Map'., Try removing 'Map', {string: map, lexeme: Map}])
+                              listener: handleRecoverableError(Message[LiteralWithClass, A map literal can't be prefixed by 'Map'., Try removing 'Map', {string: map, lexeme: Map}], Map, Map)
+                            listener: beginConstLiteral(<)
+                            parseLiteralListSetMapOrFunction(Map, const)
+                              listener: beginTypeArguments(<)
+                              listener: handleIdentifier(String, typeReference)
+                              listener: handleNoTypeArguments(,)
+                              listener: handleType(String, null)
+                              listener: handleIdentifier(List, typeReference)
+                              listener: beginTypeArguments(<)
+                              listener: handleIdentifier(int, typeReference)
+                              listener: handleNoTypeArguments(>)
+                              listener: handleType(int, null)
+                              listener: endTypeArguments(1, <, >)
+                              listener: handleType(List, null)
+                              listener: endTypeArguments(2, <, >)
+                              parseLiteralSetOrMapSuffix(>, const)
+                                listener: handleLiteralSetOrMap(0, {, const, }, false)
+                            listener: endConstLiteral(;)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, F)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, final, final, Instance of 'ComplexTypeInfo', foo2, DeclarationKind.Class, F, false)
+                listener: beginFields(;)
+                ensureIdentifier(final, typeReference)
+                  listener: handleIdentifier(Map, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(String, typeReference)
+                listener: handleNoTypeArguments(,)
+                listener: handleType(String, null)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(2, <, >)
+                listener: handleType(Map, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo2, fieldDeclaration)
+                parseFieldInitializerOpt(foo2, foo2, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseConstExpression(=)
+                            listener: beginConstLiteral(<)
+                            parseLiteralListSetMapOrFunction(const, const)
+                              listener: beginTypeArguments(<)
+                              listener: handleIdentifier(String, typeReference)
+                              listener: handleNoTypeArguments(,)
+                              listener: handleType(String, null)
+                              listener: handleIdentifier(List, typeReference)
+                              listener: beginTypeArguments(<)
+                              listener: handleIdentifier(int, typeReference)
+                              listener: handleNoTypeArguments(>)
+                              listener: handleType(int, null)
+                              listener: endTypeArguments(1, <, >)
+                              listener: handleType(List, null)
+                              listener: endTypeArguments(2, <, >)
+                              parseLiteralSetOrMapSuffix(>, const)
+                                listener: handleLiteralSetOrMap(0, {, const, }, false)
+                            listener: endConstLiteral(;)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, F)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, final, final, Instance of 'ComplexTypeInfo', foo3, DeclarationKind.Class, F, false)
+                listener: beginFields(;)
+                ensureIdentifier(final, typeReference)
+                  listener: handleIdentifier(Map, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(String, typeReference)
+                listener: handleNoTypeArguments(,)
+                listener: handleType(String, null)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(2, <, >)
+                listener: handleType(Map, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo3, fieldDeclaration)
+                parseFieldInitializerOpt(foo3, foo3, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseConstExpression(=)
+                            reportRecoverableError(Map, Message[LiteralWithClass, A map literal can't be prefixed by 'Map'., Try removing 'Map', {string: map, lexeme: Map}])
+                              listener: handleRecoverableError(Message[LiteralWithClass, A map literal can't be prefixed by 'Map'., Try removing 'Map', {string: map, lexeme: Map}], Map, Map)
+                            listener: beginConstLiteral({)
+                            listener: handleNoTypeArguments({)
+                            parseLiteralSetOrMapSuffix(Map, const)
+                              listener: handleLiteralSetOrMap(0, {, const, }, false)
+                            listener: endConstLiteral(;)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, F)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, final, final, Instance of 'ComplexTypeInfo', foo4, DeclarationKind.Class, F, false)
+                listener: beginFields(;)
+                ensureIdentifier(final, typeReference)
+                  listener: handleIdentifier(Map, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(String, typeReference)
+                listener: handleNoTypeArguments(,)
+                listener: handleType(String, null)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(2, <, >)
+                listener: handleType(Map, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo4, fieldDeclaration)
+                parseFieldInitializerOpt(foo4, foo4, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseConstExpression(=)
+                            listener: beginConstExpression(const)
+                            parseConstructorReference(const, Instance of 'ComplexTypeParamOrArgInfo')
+                              ensureIdentifier(const, constructorReference)
+                                listener: handleIdentifier(Map, constructorReference)
+                              listener: beginConstructorReference(Map)
+                              parseQualifiedRestOpt(Map, constructorReferenceContinuation)
+                              listener: beginTypeArguments(<)
+                              listener: handleIdentifier(String, typeReference)
+                              listener: handleNoTypeArguments(,)
+                              listener: handleType(String, null)
+                              listener: handleIdentifier(List, typeReference)
+                              listener: beginTypeArguments(<)
+                              listener: handleIdentifier(int, typeReference)
+                              listener: handleNoTypeArguments(>)
+                              listener: handleType(int, null)
+                              listener: endTypeArguments(1, <, >)
+                              listener: handleType(List, null)
+                              listener: endTypeArguments(2, <, >)
+                              listener: handleNoConstructorReferenceContinuationAfterTypeArguments(()
+                              listener: endConstructorReference(Map, null, ()
+                            parseConstructorInvocationArguments(>)
+                              parseArgumentsRest(()
+                                listener: beginArguments(()
+                                listener: endArguments(0, (, ))
+                            listener: endConstExpression(const)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, F)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, final, final, Instance of 'ComplexTypeInfo', foo5, DeclarationKind.Class, F, false)
+                listener: beginFields(;)
+                ensureIdentifier(final, typeReference)
+                  listener: handleIdentifier(Map, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(String, typeReference)
+                listener: handleNoTypeArguments(,)
+                listener: handleType(String, null)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(2, <, >)
+                listener: handleType(Map, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo5, fieldDeclaration)
+                parseFieldInitializerOpt(foo5, foo5, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseConstExpression(=)
+                            listener: beginConstExpression(const)
+                            parseConstructorReference(const, Instance of 'NoTypeParamOrArg')
+                              ensureIdentifier(const, constructorReference)
+                                listener: handleIdentifier(Map, constructorReference)
+                              listener: beginConstructorReference(Map)
+                              parseQualifiedRestOpt(Map, constructorReferenceContinuation)
+                              listener: handleNoTypeArguments(()
+                              listener: handleNoConstructorReferenceContinuationAfterTypeArguments(()
+                              listener: endConstructorReference(Map, null, ()
+                            parseConstructorInvocationArguments(Map)
+                              parseArgumentsRest(()
+                                listener: beginArguments(()
+                                listener: endArguments(0, (, ))
+                            listener: endConstExpression(const)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, F)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, final, final, Instance of 'ComplexTypeInfo', foo6, DeclarationKind.Class, F, false)
+                listener: beginFields(;)
+                ensureIdentifier(final, typeReference)
+                  listener: handleIdentifier(Map, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(String, typeReference)
+                listener: handleNoTypeArguments(,)
+                listener: handleType(String, null)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(2, <, >)
+                listener: handleType(Map, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo6, fieldDeclaration)
+                parseFieldInitializerOpt(foo6, foo6, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseConstExpression(=)
+                            reportRecoverableError(Map, Message[LiteralWithClass, A map literal can't be prefixed by 'Map'., Try removing 'Map', {string: map, lexeme: Map}])
+                              listener: handleRecoverableError(Message[LiteralWithClass, A map literal can't be prefixed by 'Map'., Try removing 'Map', {string: map, lexeme: Map}], Map, Map)
+                            listener: beginConstLiteral(<)
+                            parseLiteralListSetMapOrFunction(Map, const)
+                              listener: beginTypeArguments(<)
+                              listener: handleIdentifier(String, typeReference)
+                              listener: handleNoTypeArguments(,)
+                              listener: handleType(String, null)
+                              listener: handleIdentifier(List, typeReference)
+                              listener: beginTypeArguments(<)
+                              listener: handleIdentifier(int, typeReference)
+                              listener: handleNoTypeArguments(>)
+                              listener: handleType(int, null)
+                              listener: endTypeArguments(1, <, >)
+                              listener: handleType(List, null)
+                              listener: endTypeArguments(2, <, >)
+                              parseLiteralSetOrMapSuffix(>, const)
+                                parseExpression({)
+                                  parsePrecedenceExpression({, 1, true)
+                                    parseUnaryExpression({, true)
+                                      parsePrimary({, expression)
+                                        parseLiteralString({)
+                                          parseSingleLiteralString({)
+                                            listener: beginLiteralString("a")
+                                            listener: endLiteralString(0, :)
+                                parseExpression(:)
+                                  parsePrecedenceExpression(:, 1, true)
+                                    parseUnaryExpression(:, true)
+                                      parsePrimary(:, expression)
+                                        parseLiteralNull(:)
+                                          listener: handleLiteralNull(null)
+                                listener: handleLiteralMapEntry(:, })
+                                listener: handleLiteralSetOrMap(1, {, const, }, false)
+                            listener: endConstLiteral(;)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, F)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, final, final, Instance of 'ComplexTypeInfo', foo7, DeclarationKind.Class, F, false)
+                listener: beginFields(;)
+                ensureIdentifier(final, typeReference)
+                  listener: handleIdentifier(Map, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(String, typeReference)
+                listener: handleNoTypeArguments(,)
+                listener: handleType(String, null)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(2, <, >)
+                listener: handleType(Map, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo7, fieldDeclaration)
+                parseFieldInitializerOpt(foo7, foo7, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseConstExpression(=)
+                            reportRecoverableError(Map, Message[LiteralWithClass, A map literal can't be prefixed by 'Map'., Try removing 'Map', {string: map, lexeme: Map}])
+                              listener: handleRecoverableError(Message[LiteralWithClass, A map literal can't be prefixed by 'Map'., Try removing 'Map', {string: map, lexeme: Map}], Map, Map)
+                            listener: beginConstLiteral({)
+                            listener: handleNoTypeArguments({)
+                            parseLiteralSetOrMapSuffix(Map, const)
+                              parseExpression({)
+                                parsePrecedenceExpression({, 1, true)
+                                  parseUnaryExpression({, true)
+                                    parsePrimary({, expression)
+                                      parseLiteralString({)
+                                        parseSingleLiteralString({)
+                                          listener: beginLiteralString("a")
+                                          listener: endLiteralString(0, :)
+                              parseExpression(:)
+                                parsePrecedenceExpression(:, 1, true)
+                                  parseUnaryExpression(:, true)
+                                    parsePrimary(:, expression)
+                                      parseLiteralNull(:)
+                                        listener: handleLiteralNull(null)
+                              listener: handleLiteralMapEntry(:, })
+                              listener: handleLiteralSetOrMap(1, {, const, }, false)
+                            listener: endConstLiteral(;)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, F)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, final, final, Instance of 'ComplexTypeInfo', foo8, DeclarationKind.Class, F, false)
+                listener: beginFields(;)
+                ensureIdentifier(final, typeReference)
+                  listener: handleIdentifier(Map, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(String, typeReference)
+                listener: handleNoTypeArguments(,)
+                listener: handleType(String, null)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(2, <, >)
+                listener: handleType(Map, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo8, fieldDeclaration)
+                parseFieldInitializerOpt(foo8, foo8, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseConstExpression(=)
+                            listener: beginConstLiteral(<)
+                            parseLiteralListSetMapOrFunction(const, const)
+                              listener: beginTypeArguments(<)
+                              listener: handleIdentifier(String, typeReference)
+                              listener: handleNoTypeArguments(,)
+                              listener: handleType(String, null)
+                              listener: handleIdentifier(List, typeReference)
+                              listener: beginTypeArguments(<)
+                              listener: handleIdentifier(int, typeReference)
+                              listener: handleNoTypeArguments(>)
+                              listener: handleType(int, null)
+                              listener: endTypeArguments(1, <, >)
+                              listener: handleType(List, null)
+                              listener: endTypeArguments(2, <, >)
+                              parseLiteralSetOrMapSuffix(>, const)
+                                parseExpression({)
+                                  parsePrecedenceExpression({, 1, true)
+                                    parseUnaryExpression({, true)
+                                      parsePrimary({, expression)
+                                        parseLiteralString({)
+                                          parseSingleLiteralString({)
+                                            listener: beginLiteralString("a")
+                                            listener: endLiteralString(0, :)
+                                parseExpression(:)
+                                  parsePrecedenceExpression(:, 1, true)
+                                    parseUnaryExpression(:, true)
+                                      parsePrimary(:, expression)
+                                        parseLiteralNull(:)
+                                          listener: handleLiteralNull(null)
+                                listener: handleLiteralMapEntry(:, })
+                                listener: handleLiteralSetOrMap(1, {, const, }, false)
+                            listener: endConstLiteral(;)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, F)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, final, final, Instance of 'ComplexTypeInfo', foo9, DeclarationKind.Class, F, false)
+                listener: beginFields(;)
+                ensureIdentifier(final, typeReference)
+                  listener: handleIdentifier(Map, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(String, typeReference)
+                listener: handleNoTypeArguments(,)
+                listener: handleType(String, null)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(2, <, >)
+                listener: handleType(Map, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo9, fieldDeclaration)
+                parseFieldInitializerOpt(foo9, foo9, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseConstExpression(=)
+                            listener: beginConstLiteral({)
+                            listener: handleNoTypeArguments({)
+                            parseLiteralSetOrMapSuffix(const, const)
+                              parseExpression({)
+                                parsePrecedenceExpression({, 1, true)
+                                  parseUnaryExpression({, true)
+                                    parsePrimary({, expression)
+                                      parseLiteralString({)
+                                        parseSingleLiteralString({)
+                                          listener: beginLiteralString("a")
+                                          listener: endLiteralString(0, :)
+                              parseExpression(:)
+                                parsePrecedenceExpression(:, 1, true)
+                                  parseUnaryExpression(:, true)
+                                    parsePrimary(:, expression)
+                                      parseLiteralNull(:)
+                                        listener: handleLiteralNull(null)
+                              listener: handleLiteralMapEntry(:, })
+                              listener: handleLiteralSetOrMap(1, {, const, }, false)
+                            listener: endConstLiteral(;)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, })
+            listener: endClassOrMixinBody(DeclarationKind.Class, 9, {, })
+          listener: endClassDeclaration(class, })
+  listener: endTopLevelDeclaration()
+  reportAllErrorTokens(class)
+  listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_45251_const.dart.parser.expect b/pkg/front_end/parser_testcases/error_recovery/issue_45251_const.dart.parser.expect
new file mode 100644
index 0000000..a66770f
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_45251_const.dart.parser.expect
@@ -0,0 +1,59 @@
+NOTICE: Stream was rewritten by parser!
+
+class F {
+
+final Map<String, Undefined> foo1 = const Map<String, List<int>>{};
+
+
+final Map<String, Undefined> foo2 = const <String, List<int>>{};
+
+
+final Map<String, Undefined> foo3 = const Map{};
+
+
+final Map<String, Undefined> foo4 = const Map<String, List<int>>();
+
+
+final Map<String, Undefined> foo5 = const Map();
+
+
+final Map<String, Undefined> foo6 = const Map<String, List<int>>{"a": null};
+
+
+final Map<String, Undefined> foo7 = const Map{"a": null};
+
+
+final Map<String, Undefined> foo8 = const <String, List<int>>{"a": null};
+
+
+final Map<String, Undefined> foo9 = const {"a": null};
+}
+
+class[KeywordToken] F[StringToken] {[BeginToken]
+
+final[KeywordToken] Map[StringToken]<[BeginToken]String[StringToken],[SimpleToken] Undefined[StringToken]>[SimpleToken] foo1[StringToken] =[SimpleToken] const[KeywordToken] Map[StringToken]<[BeginToken]String[StringToken],[SimpleToken] List[StringToken]<[BeginToken]int[StringToken]>[SimpleToken]>[SimpleToken]{[BeginToken]}[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Map[StringToken]<[BeginToken]String[StringToken],[SimpleToken] Undefined[StringToken]>[SimpleToken] foo2[StringToken] =[SimpleToken] const[KeywordToken] <[BeginToken]String[StringToken],[SimpleToken] List[StringToken]<[BeginToken]int[StringToken]>[SimpleToken]>[SimpleToken]{[BeginToken]}[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Map[StringToken]<[BeginToken]String[StringToken],[SimpleToken] Undefined[StringToken]>[SimpleToken] foo3[StringToken] =[SimpleToken] const[KeywordToken] Map[StringToken]{[BeginToken]}[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Map[StringToken]<[BeginToken]String[StringToken],[SimpleToken] Undefined[StringToken]>[SimpleToken] foo4[StringToken] =[SimpleToken] const[KeywordToken] Map[StringToken]<[BeginToken]String[StringToken],[SimpleToken] List[StringToken]<[BeginToken]int[StringToken]>[SimpleToken]>[SimpleToken]([BeginToken])[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Map[StringToken]<[BeginToken]String[StringToken],[SimpleToken] Undefined[StringToken]>[SimpleToken] foo5[StringToken] =[SimpleToken] const[KeywordToken] Map[StringToken]([BeginToken])[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Map[StringToken]<[BeginToken]String[StringToken],[SimpleToken] Undefined[StringToken]>[SimpleToken] foo6[StringToken] =[SimpleToken] const[KeywordToken] Map[StringToken]<[BeginToken]String[StringToken],[SimpleToken] List[StringToken]<[BeginToken]int[StringToken]>[SimpleToken]>[SimpleToken]{[BeginToken]"a"[StringToken]:[SimpleToken] null[KeywordToken]}[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Map[StringToken]<[BeginToken]String[StringToken],[SimpleToken] Undefined[StringToken]>[SimpleToken] foo7[StringToken] =[SimpleToken] const[KeywordToken] Map[StringToken]{[BeginToken]"a"[StringToken]:[SimpleToken] null[KeywordToken]}[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Map[StringToken]<[BeginToken]String[StringToken],[SimpleToken] Undefined[StringToken]>[SimpleToken] foo8[StringToken] =[SimpleToken] const[KeywordToken] <[BeginToken]String[StringToken],[SimpleToken] List[StringToken]<[BeginToken]int[StringToken]>[SimpleToken]>[SimpleToken]{[BeginToken]"a"[StringToken]:[SimpleToken] null[KeywordToken]}[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Map[StringToken]<[BeginToken]String[StringToken],[SimpleToken] Undefined[StringToken]>[SimpleToken] foo9[StringToken] =[SimpleToken] const[KeywordToken] {[BeginToken]"a"[StringToken]:[SimpleToken] null[KeywordToken]}[SimpleToken];[SimpleToken]
+}[SimpleToken][SimpleToken]
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_45251_const.dart.scanner.expect b/pkg/front_end/parser_testcases/error_recovery/issue_45251_const.dart.scanner.expect
new file mode 100644
index 0000000..a45fa22
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_45251_const.dart.scanner.expect
@@ -0,0 +1,57 @@
+class F {
+
+final Map<String, Undefined> foo1 = const Map<String, List<int>>{};
+
+
+final Map<String, Undefined> foo2 = const <String, List<int>>{};
+
+
+final Map<String, Undefined> foo3 = const Map{};
+
+
+final Map<String, Undefined> foo4 = const Map<String, List<int>>();
+
+
+final Map<String, Undefined> foo5 = const Map();
+
+
+final Map<String, Undefined> foo6 = const Map<String, List<int>>{"a": null};
+
+
+final Map<String, Undefined> foo7 = const Map{"a": null};
+
+
+final Map<String, Undefined> foo8 = const <String, List<int>>{"a": null};
+
+
+final Map<String, Undefined> foo9 = const {"a": null};
+}
+
+class[KeywordToken] F[StringToken] {[BeginToken]
+
+final[KeywordToken] Map[StringToken]<[BeginToken]String[StringToken],[SimpleToken] Undefined[StringToken]>[SimpleToken] foo1[StringToken] =[SimpleToken] const[KeywordToken] Map[StringToken]<[BeginToken]String[StringToken],[SimpleToken] List[StringToken]<[BeginToken]int[StringToken]>>[SimpleToken]{[BeginToken]}[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Map[StringToken]<[BeginToken]String[StringToken],[SimpleToken] Undefined[StringToken]>[SimpleToken] foo2[StringToken] =[SimpleToken] const[KeywordToken] <[BeginToken]String[StringToken],[SimpleToken] List[StringToken]<[BeginToken]int[StringToken]>>[SimpleToken]{[BeginToken]}[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Map[StringToken]<[BeginToken]String[StringToken],[SimpleToken] Undefined[StringToken]>[SimpleToken] foo3[StringToken] =[SimpleToken] const[KeywordToken] Map[StringToken]{[BeginToken]}[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Map[StringToken]<[BeginToken]String[StringToken],[SimpleToken] Undefined[StringToken]>[SimpleToken] foo4[StringToken] =[SimpleToken] const[KeywordToken] Map[StringToken]<[BeginToken]String[StringToken],[SimpleToken] List[StringToken]<[BeginToken]int[StringToken]>>[SimpleToken]([BeginToken])[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Map[StringToken]<[BeginToken]String[StringToken],[SimpleToken] Undefined[StringToken]>[SimpleToken] foo5[StringToken] =[SimpleToken] const[KeywordToken] Map[StringToken]([BeginToken])[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Map[StringToken]<[BeginToken]String[StringToken],[SimpleToken] Undefined[StringToken]>[SimpleToken] foo6[StringToken] =[SimpleToken] const[KeywordToken] Map[StringToken]<[BeginToken]String[StringToken],[SimpleToken] List[StringToken]<[BeginToken]int[StringToken]>>[SimpleToken]{[BeginToken]"a"[StringToken]:[SimpleToken] null[KeywordToken]}[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Map[StringToken]<[BeginToken]String[StringToken],[SimpleToken] Undefined[StringToken]>[SimpleToken] foo7[StringToken] =[SimpleToken] const[KeywordToken] Map[StringToken]{[BeginToken]"a"[StringToken]:[SimpleToken] null[KeywordToken]}[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Map[StringToken]<[BeginToken]String[StringToken],[SimpleToken] Undefined[StringToken]>[SimpleToken] foo8[StringToken] =[SimpleToken] const[KeywordToken] <[BeginToken]String[StringToken],[SimpleToken] List[StringToken]<[BeginToken]int[StringToken]>>[SimpleToken]{[BeginToken]"a"[StringToken]:[SimpleToken] null[KeywordToken]}[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Map[StringToken]<[BeginToken]String[StringToken],[SimpleToken] Undefined[StringToken]>[SimpleToken] foo9[StringToken] =[SimpleToken] const[KeywordToken] {[BeginToken]"a"[StringToken]:[SimpleToken] null[KeywordToken]}[SimpleToken];[SimpleToken]
+}[SimpleToken][SimpleToken]
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_45251_list.dart b/pkg/front_end/parser_testcases/error_recovery/issue_45251_list.dart
new file mode 100644
index 0000000..b74b6d0
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_45251_list.dart
@@ -0,0 +1,28 @@
+class F {
+  /* notice the bracket at the end instead of parenthesis! */
+  final List<Undefined> foo1 = List<List<int>>[];
+
+  // variation #1: OK.
+  final List<Undefined> foo2 = <List<int>>[];
+
+  // variation #2: Bad.
+  final List<Undefined> foo3 = List[];
+
+  // variation #3: OK.
+  final List<Undefined> foo4 = List<List<int>>();
+
+  // variation #4: OK.
+  final List<Undefined> foo5 = List();
+
+  // variation #5: Bad.
+  final List<Undefined> foo6 = List<List<int>>[null];
+
+  // variation #6: This is actually just an indexed expression.
+  final List<Undefined> foo7 = List[null];
+
+  // variation #7: OK.
+  final List<Undefined> foo8 = <List<int>>[null];
+
+  // variation #8: OK.
+  final List<Undefined> foo9 = [null];
+}
\ No newline at end of file
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_45251_list.dart.expect b/pkg/front_end/parser_testcases/error_recovery/issue_45251_list.dart.expect
new file mode 100644
index 0000000..f5c21fa
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_45251_list.dart.expect
@@ -0,0 +1,249 @@
+Problems reported:
+
+parser/error_recovery/issue_45251_list:3:32: A list literal can't be prefixed by 'List'.
+  final List<Undefined> foo1 = List<List<int>>[];
+                               ^^^^
+
+parser/error_recovery/issue_45251_list:9:32: A list literal can't be prefixed by 'List'.
+  final List<Undefined> foo3 = List[];
+                               ^^^^
+
+parser/error_recovery/issue_45251_list:18:32: A list literal can't be prefixed by 'List'.
+  final List<Undefined> foo6 = List<List<int>>[null];
+                               ^^^^
+
+beginCompilationUnit(class)
+  beginMetadataStar(class)
+  endMetadataStar(0)
+  beginClassOrNamedMixinApplicationPrelude(class)
+    handleIdentifier(F, classOrMixinDeclaration)
+    handleNoTypeVariables({)
+    beginClassDeclaration(class, null, F)
+      handleNoType(F)
+      handleClassExtends(null, 1)
+      handleClassNoWithClause()
+      handleClassOrMixinImplements(null, 0)
+      handleClassHeader(class, class, null)
+      beginClassOrMixinBody(DeclarationKind.Class, {)
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields({)
+            handleIdentifier(List, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(1, <, >)
+            handleType(List, null)
+            handleIdentifier(foo1, fieldDeclaration)
+            beginFieldInitializer(=)
+              handleRecoverableError(Message[LiteralWithClass, A list literal can't be prefixed by 'List'., Try removing 'List', {string: list, lexeme: List}], List, List)
+              beginTypeArguments(<)
+                handleIdentifier(List, typeReference)
+                beginTypeArguments(<)
+                  handleIdentifier(int, typeReference)
+                  handleNoTypeArguments(>)
+                  handleType(int, null)
+                endTypeArguments(1, <, >)
+                handleType(List, null)
+              endTypeArguments(1, <, >)
+              handleLiteralList(0, [, null, ])
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields(;)
+            handleIdentifier(List, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(1, <, >)
+            handleType(List, null)
+            handleIdentifier(foo2, fieldDeclaration)
+            beginFieldInitializer(=)
+              beginTypeArguments(<)
+                handleIdentifier(List, typeReference)
+                beginTypeArguments(<)
+                  handleIdentifier(int, typeReference)
+                  handleNoTypeArguments(>)
+                  handleType(int, null)
+                endTypeArguments(1, <, >)
+                handleType(List, null)
+              endTypeArguments(1, <, >)
+              handleLiteralList(0, [, null, ])
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields(;)
+            handleIdentifier(List, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(1, <, >)
+            handleType(List, null)
+            handleIdentifier(foo3, fieldDeclaration)
+            beginFieldInitializer(=)
+              handleRecoverableError(Message[LiteralWithClass, A list literal can't be prefixed by 'List'., Try removing 'List', {string: list, lexeme: List}], List, List)
+              handleNoTypeArguments([])
+              handleLiteralList(0, [, null, ])
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields(;)
+            handleIdentifier(List, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(1, <, >)
+            handleType(List, null)
+            handleIdentifier(foo4, fieldDeclaration)
+            beginFieldInitializer(=)
+              handleIdentifier(List, expression)
+              beginTypeArguments(<)
+                handleIdentifier(List, typeReference)
+                beginTypeArguments(<)
+                  handleIdentifier(int, typeReference)
+                  handleNoTypeArguments(>)
+                  handleType(int, null)
+                endTypeArguments(1, <, >)
+                handleType(List, null)
+              endTypeArguments(1, <, >)
+              beginArguments(()
+              endArguments(0, (, ))
+              handleSend(List, ;)
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields(;)
+            handleIdentifier(List, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(1, <, >)
+            handleType(List, null)
+            handleIdentifier(foo5, fieldDeclaration)
+            beginFieldInitializer(=)
+              handleIdentifier(List, expression)
+              handleNoTypeArguments(()
+              beginArguments(()
+              endArguments(0, (, ))
+              handleSend(List, ;)
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields(;)
+            handleIdentifier(List, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(1, <, >)
+            handleType(List, null)
+            handleIdentifier(foo6, fieldDeclaration)
+            beginFieldInitializer(=)
+              handleRecoverableError(Message[LiteralWithClass, A list literal can't be prefixed by 'List'., Try removing 'List', {string: list, lexeme: List}], List, List)
+              beginTypeArguments(<)
+                handleIdentifier(List, typeReference)
+                beginTypeArguments(<)
+                  handleIdentifier(int, typeReference)
+                  handleNoTypeArguments(>)
+                  handleType(int, null)
+                endTypeArguments(1, <, >)
+                handleType(List, null)
+              endTypeArguments(1, <, >)
+              handleLiteralNull(null)
+              handleLiteralList(1, [, null, ])
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields(;)
+            handleIdentifier(List, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(1, <, >)
+            handleType(List, null)
+            handleIdentifier(foo7, fieldDeclaration)
+            beginFieldInitializer(=)
+              handleIdentifier(List, expression)
+              handleNoTypeArguments([)
+              handleNoArguments([)
+              handleSend(List, [)
+              handleLiteralNull(null)
+              handleIndexedExpression(null, [, ])
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields(;)
+            handleIdentifier(List, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(1, <, >)
+            handleType(List, null)
+            handleIdentifier(foo8, fieldDeclaration)
+            beginFieldInitializer(=)
+              beginTypeArguments(<)
+                handleIdentifier(List, typeReference)
+                beginTypeArguments(<)
+                  handleIdentifier(int, typeReference)
+                  handleNoTypeArguments(>)
+                  handleType(int, null)
+                endTypeArguments(1, <, >)
+                handleType(List, null)
+              endTypeArguments(1, <, >)
+              handleLiteralNull(null)
+              handleLiteralList(1, [, null, ])
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields(;)
+            handleIdentifier(List, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(1, <, >)
+            handleType(List, null)
+            handleIdentifier(foo9, fieldDeclaration)
+            beginFieldInitializer(=)
+              handleNoTypeArguments([)
+              handleLiteralNull(null)
+              handleLiteralList(1, [, null, ])
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+      endClassOrMixinBody(DeclarationKind.Class, 9, {, })
+    endClassDeclaration(class, })
+  endTopLevelDeclaration()
+endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_45251_list.dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/issue_45251_list.dart.intertwined.expect
new file mode 100644
index 0000000..a073268
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_45251_list.dart.intertwined.expect
@@ -0,0 +1,412 @@
+parseUnit(class)
+  skipErrorTokens(class)
+  listener: beginCompilationUnit(class)
+  syntheticPreviousToken(class)
+  parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+    parseMetadataStar()
+      listener: beginMetadataStar(class)
+      listener: endMetadataStar(0)
+    parseTopLevelKeywordDeclaration(, class, Instance of 'DirectiveContext')
+      parseClassDeclarationModifiers(, class)
+      parseClassOrNamedMixinApplication(null, class)
+        listener: beginClassOrNamedMixinApplicationPrelude(class)
+        ensureIdentifier(class, classOrMixinDeclaration)
+          listener: handleIdentifier(F, classOrMixinDeclaration)
+        listener: handleNoTypeVariables({)
+        listener: beginClassDeclaration(class, null, F)
+        parseClass(F, class, class, F)
+          parseClassHeaderOpt(F, class, class)
+            parseClassExtendsOpt(F)
+              listener: handleNoType(F)
+              listener: handleClassExtends(null, 1)
+            parseWithClauseOpt(F)
+              listener: handleClassNoWithClause()
+            parseClassOrMixinImplementsOpt(F)
+              listener: handleClassOrMixinImplements(null, 0)
+            listener: handleClassHeader(class, class, null)
+          parseClassOrMixinOrExtensionBody(F, DeclarationKind.Class, F)
+            listener: beginClassOrMixinBody(DeclarationKind.Class, {)
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl({, DeclarationKind.Class, F)
+              parseMetadataStar({)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields({, null, null, null, null, null, final, final, Instance of 'SimpleTypeWith1Argument', foo1, DeclarationKind.Class, F, false)
+                listener: beginFields({)
+                listener: handleIdentifier(List, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(1, <, >)
+                listener: handleType(List, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo1, fieldDeclaration)
+                parseFieldInitializerOpt(foo1, foo1, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseSendOrFunctionLiteral(=, expression)
+                            parseSend(=, expression)
+                              reportRecoverableError(List, Message[LiteralWithClass, A list literal can't be prefixed by 'List'., Try removing 'List', {string: list, lexeme: List}])
+                                listener: handleRecoverableError(Message[LiteralWithClass, A list literal can't be prefixed by 'List'., Try removing 'List', {string: list, lexeme: List}], List, List)
+                              parsePrimary(List, expression)
+                                parseLiteralListSetMapOrFunction(List, null)
+                                  listener: beginTypeArguments(<)
+                                  listener: handleIdentifier(List, typeReference)
+                                  listener: beginTypeArguments(<)
+                                  listener: handleIdentifier(int, typeReference)
+                                  listener: handleNoTypeArguments(>)
+                                  listener: handleType(int, null)
+                                  listener: endTypeArguments(1, <, >)
+                                  listener: handleType(List, null)
+                                  listener: endTypeArguments(1, <, >)
+                                  parseLiteralListSuffix(>, null)
+                                    rewriteSquareBrackets(>)
+                                      link([, ])
+                                      rewriter()
+                                    listener: handleLiteralList(0, [, null, ])
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, F)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, final, final, Instance of 'SimpleTypeWith1Argument', foo2, DeclarationKind.Class, F, false)
+                listener: beginFields(;)
+                listener: handleIdentifier(List, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(1, <, >)
+                listener: handleType(List, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo2, fieldDeclaration)
+                parseFieldInitializerOpt(foo2, foo2, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseLiteralListSetMapOrFunction(=, null)
+                            listener: beginTypeArguments(<)
+                            listener: handleIdentifier(List, typeReference)
+                            listener: beginTypeArguments(<)
+                            listener: handleIdentifier(int, typeReference)
+                            listener: handleNoTypeArguments(>)
+                            listener: handleType(int, null)
+                            listener: endTypeArguments(1, <, >)
+                            listener: handleType(List, null)
+                            listener: endTypeArguments(1, <, >)
+                            parseLiteralListSuffix(>, null)
+                              rewriteSquareBrackets(>)
+                                link([, ])
+                                rewriter()
+                              listener: handleLiteralList(0, [, null, ])
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, F)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, final, final, Instance of 'SimpleTypeWith1Argument', foo3, DeclarationKind.Class, F, false)
+                listener: beginFields(;)
+                listener: handleIdentifier(List, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(1, <, >)
+                listener: handleType(List, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo3, fieldDeclaration)
+                parseFieldInitializerOpt(foo3, foo3, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseSendOrFunctionLiteral(=, expression)
+                            parseSend(=, expression)
+                              reportRecoverableError(List, Message[LiteralWithClass, A list literal can't be prefixed by 'List'., Try removing 'List', {string: list, lexeme: List}])
+                                listener: handleRecoverableError(Message[LiteralWithClass, A list literal can't be prefixed by 'List'., Try removing 'List', {string: list, lexeme: List}], List, List)
+                              parsePrimary(List, expression)
+                                listener: handleNoTypeArguments([])
+                                parseLiteralListSuffix(List, null)
+                                  rewriteSquareBrackets(List)
+                                    link([, ])
+                                    rewriter()
+                                  listener: handleLiteralList(0, [, null, ])
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, F)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, final, final, Instance of 'SimpleTypeWith1Argument', foo4, DeclarationKind.Class, F, false)
+                listener: beginFields(;)
+                listener: handleIdentifier(List, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(1, <, >)
+                listener: handleType(List, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo4, fieldDeclaration)
+                parseFieldInitializerOpt(foo4, foo4, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseSendOrFunctionLiteral(=, expression)
+                            looksLikeFunctionBody(;)
+                            parseSend(=, expression)
+                              ensureIdentifier(=, expression)
+                                listener: handleIdentifier(List, expression)
+                              listener: beginTypeArguments(<)
+                              listener: handleIdentifier(List, typeReference)
+                              listener: beginTypeArguments(<)
+                              listener: handleIdentifier(int, typeReference)
+                              listener: handleNoTypeArguments(>)
+                              listener: handleType(int, null)
+                              listener: endTypeArguments(1, <, >)
+                              listener: handleType(List, null)
+                              listener: endTypeArguments(1, <, >)
+                              parseArgumentsOpt(>)
+                                parseArguments(>)
+                                  parseArgumentsRest(()
+                                    listener: beginArguments(()
+                                    listener: endArguments(0, (, ))
+                              listener: handleSend(List, ;)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, F)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, final, final, Instance of 'SimpleTypeWith1Argument', foo5, DeclarationKind.Class, F, false)
+                listener: beginFields(;)
+                listener: handleIdentifier(List, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(1, <, >)
+                listener: handleType(List, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo5, fieldDeclaration)
+                parseFieldInitializerOpt(foo5, foo5, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseSendOrFunctionLiteral(=, expression)
+                            looksLikeFunctionBody(;)
+                            parseSend(=, expression)
+                              ensureIdentifier(=, expression)
+                                listener: handleIdentifier(List, expression)
+                              listener: handleNoTypeArguments(()
+                              parseArgumentsOpt(List)
+                                parseArguments(List)
+                                  parseArgumentsRest(()
+                                    listener: beginArguments(()
+                                    listener: endArguments(0, (, ))
+                              listener: handleSend(List, ;)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, F)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, final, final, Instance of 'SimpleTypeWith1Argument', foo6, DeclarationKind.Class, F, false)
+                listener: beginFields(;)
+                listener: handleIdentifier(List, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(1, <, >)
+                listener: handleType(List, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo6, fieldDeclaration)
+                parseFieldInitializerOpt(foo6, foo6, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseSendOrFunctionLiteral(=, expression)
+                            parseSend(=, expression)
+                              reportRecoverableError(List, Message[LiteralWithClass, A list literal can't be prefixed by 'List'., Try removing 'List', {string: list, lexeme: List}])
+                                listener: handleRecoverableError(Message[LiteralWithClass, A list literal can't be prefixed by 'List'., Try removing 'List', {string: list, lexeme: List}], List, List)
+                              parsePrimary(List, expression)
+                                parseLiteralListSetMapOrFunction(List, null)
+                                  listener: beginTypeArguments(<)
+                                  listener: handleIdentifier(List, typeReference)
+                                  listener: beginTypeArguments(<)
+                                  listener: handleIdentifier(int, typeReference)
+                                  listener: handleNoTypeArguments(>)
+                                  listener: handleType(int, null)
+                                  listener: endTypeArguments(1, <, >)
+                                  listener: handleType(List, null)
+                                  listener: endTypeArguments(1, <, >)
+                                  parseLiteralListSuffix(>, null)
+                                    parseExpression([)
+                                      parsePrecedenceExpression([, 1, true)
+                                        parseUnaryExpression([, true)
+                                          parsePrimary([, expression)
+                                            parseLiteralNull([)
+                                              listener: handleLiteralNull(null)
+                                    listener: handleLiteralList(1, [, null, ])
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, F)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, final, final, Instance of 'SimpleTypeWith1Argument', foo7, DeclarationKind.Class, F, false)
+                listener: beginFields(;)
+                listener: handleIdentifier(List, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(1, <, >)
+                listener: handleType(List, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo7, fieldDeclaration)
+                parseFieldInitializerOpt(foo7, foo7, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseSendOrFunctionLiteral(=, expression)
+                            parseSend(=, expression)
+                              ensureIdentifier(=, expression)
+                                listener: handleIdentifier(List, expression)
+                              listener: handleNoTypeArguments([)
+                              parseArgumentsOpt(List)
+                                listener: handleNoArguments([)
+                              listener: handleSend(List, [)
+                      parseArgumentOrIndexStar(List, Instance of 'NoTypeParamOrArg', false)
+                        parseExpression([)
+                          parsePrecedenceExpression([, 1, true)
+                            parseUnaryExpression([, true)
+                              parsePrimary([, expression)
+                                parseLiteralNull([)
+                                  listener: handleLiteralNull(null)
+                        listener: handleIndexedExpression(null, [, ])
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, F)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, final, final, Instance of 'SimpleTypeWith1Argument', foo8, DeclarationKind.Class, F, false)
+                listener: beginFields(;)
+                listener: handleIdentifier(List, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(1, <, >)
+                listener: handleType(List, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo8, fieldDeclaration)
+                parseFieldInitializerOpt(foo8, foo8, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseLiteralListSetMapOrFunction(=, null)
+                            listener: beginTypeArguments(<)
+                            listener: handleIdentifier(List, typeReference)
+                            listener: beginTypeArguments(<)
+                            listener: handleIdentifier(int, typeReference)
+                            listener: handleNoTypeArguments(>)
+                            listener: handleType(int, null)
+                            listener: endTypeArguments(1, <, >)
+                            listener: handleType(List, null)
+                            listener: endTypeArguments(1, <, >)
+                            parseLiteralListSuffix(>, null)
+                              parseExpression([)
+                                parsePrecedenceExpression([, 1, true)
+                                  parseUnaryExpression([, true)
+                                    parsePrimary([, expression)
+                                      parseLiteralNull([)
+                                        listener: handleLiteralNull(null)
+                              listener: handleLiteralList(1, [, null, ])
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, F)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, final, final, Instance of 'SimpleTypeWith1Argument', foo9, DeclarationKind.Class, F, false)
+                listener: beginFields(;)
+                listener: handleIdentifier(List, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(1, <, >)
+                listener: handleType(List, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo9, fieldDeclaration)
+                parseFieldInitializerOpt(foo9, foo9, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          listener: handleNoTypeArguments([)
+                          parseLiteralListSuffix(=, null)
+                            parseExpression([)
+                              parsePrecedenceExpression([, 1, true)
+                                parseUnaryExpression([, true)
+                                  parsePrimary([, expression)
+                                    parseLiteralNull([)
+                                      listener: handleLiteralNull(null)
+                            listener: handleLiteralList(1, [, null, ])
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, })
+            listener: endClassOrMixinBody(DeclarationKind.Class, 9, {, })
+          listener: endClassDeclaration(class, })
+  listener: endTopLevelDeclaration()
+  reportAllErrorTokens(class)
+  listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_45251_list.dart.parser.expect b/pkg/front_end/parser_testcases/error_recovery/issue_45251_list.dart.parser.expect
new file mode 100644
index 0000000..71b1cfe
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_45251_list.dart.parser.expect
@@ -0,0 +1,59 @@
+NOTICE: Stream was rewritten by parser!
+
+class F {
+
+final List<Undefined> foo1 = List<List<int>>[];
+
+
+final List<Undefined> foo2 = <List<int>>[];
+
+
+final List<Undefined> foo3 = List[];
+
+
+final List<Undefined> foo4 = List<List<int>>();
+
+
+final List<Undefined> foo5 = List();
+
+
+final List<Undefined> foo6 = List<List<int>>[null];
+
+
+final List<Undefined> foo7 = List[null];
+
+
+final List<Undefined> foo8 = <List<int>>[null];
+
+
+final List<Undefined> foo9 = [null];
+}
+
+class[KeywordToken] F[StringToken] {[BeginToken]
+
+final[KeywordToken] List[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo1[StringToken] =[SimpleToken] List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]int[StringToken]>[SimpleToken]>[SimpleToken][[BeginToken]][SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] List[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo2[StringToken] =[SimpleToken] <[BeginToken]List[StringToken]<[BeginToken]int[StringToken]>[SimpleToken]>[SimpleToken][[BeginToken]][SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] List[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo3[StringToken] =[SimpleToken] List[StringToken][[BeginToken]][SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] List[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo4[StringToken] =[SimpleToken] List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]int[StringToken]>[SimpleToken]>[SimpleToken]([BeginToken])[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] List[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo5[StringToken] =[SimpleToken] List[StringToken]([BeginToken])[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] List[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo6[StringToken] =[SimpleToken] List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]int[StringToken]>[SimpleToken]>[SimpleToken][[BeginToken]null[KeywordToken]][SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] List[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo7[StringToken] =[SimpleToken] List[StringToken][[BeginToken]null[KeywordToken]][SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] List[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo8[StringToken] =[SimpleToken] <[BeginToken]List[StringToken]<[BeginToken]int[StringToken]>[SimpleToken]>[SimpleToken][[BeginToken]null[KeywordToken]][SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] List[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo9[StringToken] =[SimpleToken] [[BeginToken]null[KeywordToken]][SimpleToken];[SimpleToken]
+}[SimpleToken][SimpleToken]
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_45251_list.dart.scanner.expect b/pkg/front_end/parser_testcases/error_recovery/issue_45251_list.dart.scanner.expect
new file mode 100644
index 0000000..895b318
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_45251_list.dart.scanner.expect
@@ -0,0 +1,57 @@
+class F {
+
+final List<Undefined> foo1 = List<List<int>>[];
+
+
+final List<Undefined> foo2 = <List<int>>[];
+
+
+final List<Undefined> foo3 = List[];
+
+
+final List<Undefined> foo4 = List<List<int>>();
+
+
+final List<Undefined> foo5 = List();
+
+
+final List<Undefined> foo6 = List<List<int>>[null];
+
+
+final List<Undefined> foo7 = List[null];
+
+
+final List<Undefined> foo8 = <List<int>>[null];
+
+
+final List<Undefined> foo9 = [null];
+}
+
+class[KeywordToken] F[StringToken] {[BeginToken]
+
+final[KeywordToken] List[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo1[StringToken] =[SimpleToken] List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]int[StringToken]>>[SimpleToken][][SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] List[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo2[StringToken] =[SimpleToken] <[BeginToken]List[StringToken]<[BeginToken]int[StringToken]>>[SimpleToken][][SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] List[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo3[StringToken] =[SimpleToken] List[StringToken][][SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] List[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo4[StringToken] =[SimpleToken] List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]int[StringToken]>>[SimpleToken]([BeginToken])[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] List[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo5[StringToken] =[SimpleToken] List[StringToken]([BeginToken])[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] List[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo6[StringToken] =[SimpleToken] List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]int[StringToken]>>[SimpleToken][[BeginToken]null[KeywordToken]][SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] List[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo7[StringToken] =[SimpleToken] List[StringToken][[BeginToken]null[KeywordToken]][SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] List[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo8[StringToken] =[SimpleToken] <[BeginToken]List[StringToken]<[BeginToken]int[StringToken]>>[SimpleToken][[BeginToken]null[KeywordToken]][SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] List[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo9[StringToken] =[SimpleToken] [[BeginToken]null[KeywordToken]][SimpleToken];[SimpleToken]
+}[SimpleToken][SimpleToken]
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_45251_list_const.dart b/pkg/front_end/parser_testcases/error_recovery/issue_45251_list_const.dart
new file mode 100644
index 0000000..43d659c
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_45251_list_const.dart
@@ -0,0 +1,29 @@
+class F {
+  /* notice the bracket at the end instead of parenthesis! */
+  final List<Undefined> foo1 = const List<List<int>>[];
+
+  // variation #1: OK.
+  final List<Undefined> foo2 = const <List<int>>[];
+
+  // variation #2: Bad.
+  final List<Undefined> foo3 = const List[];
+
+  // variation #3: OK.
+  final List<Undefined> foo4 = const List<List<int>>();
+
+  // variation #4: OK.
+  final List<Undefined> foo5 = const List();
+
+  // variation #5: Bad.
+  final List<Undefined> foo6 = const List<List<int>>[null];
+
+  // variation #6: const makes it bad. Without const it would be an indexed
+  // expression; We should probably recover as `const [null]`.
+  final List<Undefined> foo7 = const List[null];
+
+  // variation #7: OK.
+  final List<Undefined> foo8 = const <List<int>>[null];
+
+  // variation #8: OK.
+  final List<Undefined> foo9 = const [null];
+}
\ No newline at end of file
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_45251_list_const.dart.expect b/pkg/front_end/parser_testcases/error_recovery/issue_45251_list_const.dart.expect
new file mode 100644
index 0000000..0f278c9
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_45251_list_const.dart.expect
@@ -0,0 +1,273 @@
+Problems reported:
+
+parser/error_recovery/issue_45251_list_const:3:38: A list literal can't be prefixed by 'List'.
+  final List<Undefined> foo1 = const List<List<int>>[];
+                                     ^^^^
+
+parser/error_recovery/issue_45251_list_const:9:38: A list literal can't be prefixed by 'List'.
+  final List<Undefined> foo3 = const List[];
+                                     ^^^^
+
+parser/error_recovery/issue_45251_list_const:18:38: A list literal can't be prefixed by 'List'.
+  final List<Undefined> foo6 = const List<List<int>>[null];
+                                     ^^^^
+
+parser/error_recovery/issue_45251_list_const:22:38: A list literal can't be prefixed by 'List'.
+  final List<Undefined> foo7 = const List[null];
+                                     ^^^^
+
+beginCompilationUnit(class)
+  beginMetadataStar(class)
+  endMetadataStar(0)
+  beginClassOrNamedMixinApplicationPrelude(class)
+    handleIdentifier(F, classOrMixinDeclaration)
+    handleNoTypeVariables({)
+    beginClassDeclaration(class, null, F)
+      handleNoType(F)
+      handleClassExtends(null, 1)
+      handleClassNoWithClause()
+      handleClassOrMixinImplements(null, 0)
+      handleClassHeader(class, class, null)
+      beginClassOrMixinBody(DeclarationKind.Class, {)
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields({)
+            handleIdentifier(List, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(1, <, >)
+            handleType(List, null)
+            handleIdentifier(foo1, fieldDeclaration)
+            beginFieldInitializer(=)
+              handleRecoverableError(Message[LiteralWithClass, A list literal can't be prefixed by 'List'., Try removing 'List', {string: list, lexeme: List}], List, List)
+              beginConstLiteral(<)
+                beginTypeArguments(<)
+                  handleIdentifier(List, typeReference)
+                  beginTypeArguments(<)
+                    handleIdentifier(int, typeReference)
+                    handleNoTypeArguments(>)
+                    handleType(int, null)
+                  endTypeArguments(1, <, >)
+                  handleType(List, null)
+                endTypeArguments(1, <, >)
+                handleLiteralList(0, [, const, ])
+              endConstLiteral(;)
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields(;)
+            handleIdentifier(List, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(1, <, >)
+            handleType(List, null)
+            handleIdentifier(foo2, fieldDeclaration)
+            beginFieldInitializer(=)
+              beginConstLiteral(<)
+                beginTypeArguments(<)
+                  handleIdentifier(List, typeReference)
+                  beginTypeArguments(<)
+                    handleIdentifier(int, typeReference)
+                    handleNoTypeArguments(>)
+                    handleType(int, null)
+                  endTypeArguments(1, <, >)
+                  handleType(List, null)
+                endTypeArguments(1, <, >)
+                handleLiteralList(0, [, const, ])
+              endConstLiteral(;)
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields(;)
+            handleIdentifier(List, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(1, <, >)
+            handleType(List, null)
+            handleIdentifier(foo3, fieldDeclaration)
+            beginFieldInitializer(=)
+              handleRecoverableError(Message[LiteralWithClass, A list literal can't be prefixed by 'List'., Try removing 'List', {string: list, lexeme: List}], List, List)
+              beginConstLiteral([])
+                handleNoTypeArguments([])
+                handleLiteralList(0, [, const, ])
+              endConstLiteral(;)
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields(;)
+            handleIdentifier(List, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(1, <, >)
+            handleType(List, null)
+            handleIdentifier(foo4, fieldDeclaration)
+            beginFieldInitializer(=)
+              beginConstExpression(const)
+                handleIdentifier(List, constructorReference)
+                beginConstructorReference(List)
+                  beginTypeArguments(<)
+                    handleIdentifier(List, typeReference)
+                    beginTypeArguments(<)
+                      handleIdentifier(int, typeReference)
+                      handleNoTypeArguments(>)
+                      handleType(int, null)
+                    endTypeArguments(1, <, >)
+                    handleType(List, null)
+                  endTypeArguments(1, <, >)
+                  handleNoConstructorReferenceContinuationAfterTypeArguments(()
+                endConstructorReference(List, null, ()
+                beginArguments(()
+                endArguments(0, (, ))
+              endConstExpression(const)
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields(;)
+            handleIdentifier(List, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(1, <, >)
+            handleType(List, null)
+            handleIdentifier(foo5, fieldDeclaration)
+            beginFieldInitializer(=)
+              beginConstExpression(const)
+                handleIdentifier(List, constructorReference)
+                beginConstructorReference(List)
+                  handleNoTypeArguments(()
+                  handleNoConstructorReferenceContinuationAfterTypeArguments(()
+                endConstructorReference(List, null, ()
+                beginArguments(()
+                endArguments(0, (, ))
+              endConstExpression(const)
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields(;)
+            handleIdentifier(List, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(1, <, >)
+            handleType(List, null)
+            handleIdentifier(foo6, fieldDeclaration)
+            beginFieldInitializer(=)
+              handleRecoverableError(Message[LiteralWithClass, A list literal can't be prefixed by 'List'., Try removing 'List', {string: list, lexeme: List}], List, List)
+              beginConstLiteral(<)
+                beginTypeArguments(<)
+                  handleIdentifier(List, typeReference)
+                  beginTypeArguments(<)
+                    handleIdentifier(int, typeReference)
+                    handleNoTypeArguments(>)
+                    handleType(int, null)
+                  endTypeArguments(1, <, >)
+                  handleType(List, null)
+                endTypeArguments(1, <, >)
+                handleLiteralNull(null)
+                handleLiteralList(1, [, const, ])
+              endConstLiteral(;)
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields(;)
+            handleIdentifier(List, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(1, <, >)
+            handleType(List, null)
+            handleIdentifier(foo7, fieldDeclaration)
+            beginFieldInitializer(=)
+              handleRecoverableError(Message[LiteralWithClass, A list literal can't be prefixed by 'List'., Try removing 'List', {string: list, lexeme: List}], List, List)
+              beginConstLiteral([)
+                handleNoTypeArguments([)
+                handleLiteralNull(null)
+                handleLiteralList(1, [, const, ])
+              endConstLiteral(;)
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields(;)
+            handleIdentifier(List, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(1, <, >)
+            handleType(List, null)
+            handleIdentifier(foo8, fieldDeclaration)
+            beginFieldInitializer(=)
+              beginConstLiteral(<)
+                beginTypeArguments(<)
+                  handleIdentifier(List, typeReference)
+                  beginTypeArguments(<)
+                    handleIdentifier(int, typeReference)
+                    handleNoTypeArguments(>)
+                    handleType(int, null)
+                  endTypeArguments(1, <, >)
+                  handleType(List, null)
+                endTypeArguments(1, <, >)
+                handleLiteralNull(null)
+                handleLiteralList(1, [, const, ])
+              endConstLiteral(;)
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields(;)
+            handleIdentifier(List, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(1, <, >)
+            handleType(List, null)
+            handleIdentifier(foo9, fieldDeclaration)
+            beginFieldInitializer(=)
+              beginConstLiteral([)
+                handleNoTypeArguments([)
+                handleLiteralNull(null)
+                handleLiteralList(1, [, const, ])
+              endConstLiteral(;)
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+      endClassOrMixinBody(DeclarationKind.Class, 9, {, })
+    endClassDeclaration(class, })
+  endTopLevelDeclaration()
+endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_45251_list_const.dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/issue_45251_list_const.dart.intertwined.expect
new file mode 100644
index 0000000..84d3ed8
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_45251_list_const.dart.intertwined.expect
@@ -0,0 +1,425 @@
+parseUnit(class)
+  skipErrorTokens(class)
+  listener: beginCompilationUnit(class)
+  syntheticPreviousToken(class)
+  parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+    parseMetadataStar()
+      listener: beginMetadataStar(class)
+      listener: endMetadataStar(0)
+    parseTopLevelKeywordDeclaration(, class, Instance of 'DirectiveContext')
+      parseClassDeclarationModifiers(, class)
+      parseClassOrNamedMixinApplication(null, class)
+        listener: beginClassOrNamedMixinApplicationPrelude(class)
+        ensureIdentifier(class, classOrMixinDeclaration)
+          listener: handleIdentifier(F, classOrMixinDeclaration)
+        listener: handleNoTypeVariables({)
+        listener: beginClassDeclaration(class, null, F)
+        parseClass(F, class, class, F)
+          parseClassHeaderOpt(F, class, class)
+            parseClassExtendsOpt(F)
+              listener: handleNoType(F)
+              listener: handleClassExtends(null, 1)
+            parseWithClauseOpt(F)
+              listener: handleClassNoWithClause()
+            parseClassOrMixinImplementsOpt(F)
+              listener: handleClassOrMixinImplements(null, 0)
+            listener: handleClassHeader(class, class, null)
+          parseClassOrMixinOrExtensionBody(F, DeclarationKind.Class, F)
+            listener: beginClassOrMixinBody(DeclarationKind.Class, {)
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl({, DeclarationKind.Class, F)
+              parseMetadataStar({)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields({, null, null, null, null, null, final, final, Instance of 'SimpleTypeWith1Argument', foo1, DeclarationKind.Class, F, false)
+                listener: beginFields({)
+                listener: handleIdentifier(List, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(1, <, >)
+                listener: handleType(List, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo1, fieldDeclaration)
+                parseFieldInitializerOpt(foo1, foo1, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseConstExpression(=)
+                            reportRecoverableError(List, Message[LiteralWithClass, A list literal can't be prefixed by 'List'., Try removing 'List', {string: list, lexeme: List}])
+                              listener: handleRecoverableError(Message[LiteralWithClass, A list literal can't be prefixed by 'List'., Try removing 'List', {string: list, lexeme: List}], List, List)
+                            listener: beginConstLiteral(<)
+                            parseLiteralListSetMapOrFunction(List, const)
+                              listener: beginTypeArguments(<)
+                              listener: handleIdentifier(List, typeReference)
+                              listener: beginTypeArguments(<)
+                              listener: handleIdentifier(int, typeReference)
+                              listener: handleNoTypeArguments(>)
+                              listener: handleType(int, null)
+                              listener: endTypeArguments(1, <, >)
+                              listener: handleType(List, null)
+                              listener: endTypeArguments(1, <, >)
+                              parseLiteralListSuffix(>, const)
+                                rewriteSquareBrackets(>)
+                                  link([, ])
+                                  rewriter()
+                                listener: handleLiteralList(0, [, const, ])
+                            listener: endConstLiteral(;)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, F)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, final, final, Instance of 'SimpleTypeWith1Argument', foo2, DeclarationKind.Class, F, false)
+                listener: beginFields(;)
+                listener: handleIdentifier(List, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(1, <, >)
+                listener: handleType(List, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo2, fieldDeclaration)
+                parseFieldInitializerOpt(foo2, foo2, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseConstExpression(=)
+                            listener: beginConstLiteral(<)
+                            parseLiteralListSetMapOrFunction(const, const)
+                              listener: beginTypeArguments(<)
+                              listener: handleIdentifier(List, typeReference)
+                              listener: beginTypeArguments(<)
+                              listener: handleIdentifier(int, typeReference)
+                              listener: handleNoTypeArguments(>)
+                              listener: handleType(int, null)
+                              listener: endTypeArguments(1, <, >)
+                              listener: handleType(List, null)
+                              listener: endTypeArguments(1, <, >)
+                              parseLiteralListSuffix(>, const)
+                                rewriteSquareBrackets(>)
+                                  link([, ])
+                                  rewriter()
+                                listener: handleLiteralList(0, [, const, ])
+                            listener: endConstLiteral(;)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, F)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, final, final, Instance of 'SimpleTypeWith1Argument', foo3, DeclarationKind.Class, F, false)
+                listener: beginFields(;)
+                listener: handleIdentifier(List, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(1, <, >)
+                listener: handleType(List, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo3, fieldDeclaration)
+                parseFieldInitializerOpt(foo3, foo3, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseConstExpression(=)
+                            reportRecoverableError(List, Message[LiteralWithClass, A list literal can't be prefixed by 'List'., Try removing 'List', {string: list, lexeme: List}])
+                              listener: handleRecoverableError(Message[LiteralWithClass, A list literal can't be prefixed by 'List'., Try removing 'List', {string: list, lexeme: List}], List, List)
+                            listener: beginConstLiteral([])
+                            listener: handleNoTypeArguments([])
+                            parseLiteralListSuffix(List, const)
+                              rewriteSquareBrackets(List)
+                                link([, ])
+                                rewriter()
+                              listener: handleLiteralList(0, [, const, ])
+                            listener: endConstLiteral(;)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, F)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, final, final, Instance of 'SimpleTypeWith1Argument', foo4, DeclarationKind.Class, F, false)
+                listener: beginFields(;)
+                listener: handleIdentifier(List, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(1, <, >)
+                listener: handleType(List, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo4, fieldDeclaration)
+                parseFieldInitializerOpt(foo4, foo4, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseConstExpression(=)
+                            listener: beginConstExpression(const)
+                            parseConstructorReference(const, Instance of 'ComplexTypeParamOrArgInfo')
+                              ensureIdentifier(const, constructorReference)
+                                listener: handleIdentifier(List, constructorReference)
+                              listener: beginConstructorReference(List)
+                              parseQualifiedRestOpt(List, constructorReferenceContinuation)
+                              listener: beginTypeArguments(<)
+                              listener: handleIdentifier(List, typeReference)
+                              listener: beginTypeArguments(<)
+                              listener: handleIdentifier(int, typeReference)
+                              listener: handleNoTypeArguments(>)
+                              listener: handleType(int, null)
+                              listener: endTypeArguments(1, <, >)
+                              listener: handleType(List, null)
+                              listener: endTypeArguments(1, <, >)
+                              listener: handleNoConstructorReferenceContinuationAfterTypeArguments(()
+                              listener: endConstructorReference(List, null, ()
+                            parseConstructorInvocationArguments(>)
+                              parseArgumentsRest(()
+                                listener: beginArguments(()
+                                listener: endArguments(0, (, ))
+                            listener: endConstExpression(const)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, F)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, final, final, Instance of 'SimpleTypeWith1Argument', foo5, DeclarationKind.Class, F, false)
+                listener: beginFields(;)
+                listener: handleIdentifier(List, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(1, <, >)
+                listener: handleType(List, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo5, fieldDeclaration)
+                parseFieldInitializerOpt(foo5, foo5, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseConstExpression(=)
+                            listener: beginConstExpression(const)
+                            parseConstructorReference(const, Instance of 'NoTypeParamOrArg')
+                              ensureIdentifier(const, constructorReference)
+                                listener: handleIdentifier(List, constructorReference)
+                              listener: beginConstructorReference(List)
+                              parseQualifiedRestOpt(List, constructorReferenceContinuation)
+                              listener: handleNoTypeArguments(()
+                              listener: handleNoConstructorReferenceContinuationAfterTypeArguments(()
+                              listener: endConstructorReference(List, null, ()
+                            parseConstructorInvocationArguments(List)
+                              parseArgumentsRest(()
+                                listener: beginArguments(()
+                                listener: endArguments(0, (, ))
+                            listener: endConstExpression(const)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, F)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, final, final, Instance of 'SimpleTypeWith1Argument', foo6, DeclarationKind.Class, F, false)
+                listener: beginFields(;)
+                listener: handleIdentifier(List, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(1, <, >)
+                listener: handleType(List, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo6, fieldDeclaration)
+                parseFieldInitializerOpt(foo6, foo6, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseConstExpression(=)
+                            reportRecoverableError(List, Message[LiteralWithClass, A list literal can't be prefixed by 'List'., Try removing 'List', {string: list, lexeme: List}])
+                              listener: handleRecoverableError(Message[LiteralWithClass, A list literal can't be prefixed by 'List'., Try removing 'List', {string: list, lexeme: List}], List, List)
+                            listener: beginConstLiteral(<)
+                            parseLiteralListSetMapOrFunction(List, const)
+                              listener: beginTypeArguments(<)
+                              listener: handleIdentifier(List, typeReference)
+                              listener: beginTypeArguments(<)
+                              listener: handleIdentifier(int, typeReference)
+                              listener: handleNoTypeArguments(>)
+                              listener: handleType(int, null)
+                              listener: endTypeArguments(1, <, >)
+                              listener: handleType(List, null)
+                              listener: endTypeArguments(1, <, >)
+                              parseLiteralListSuffix(>, const)
+                                parseExpression([)
+                                  parsePrecedenceExpression([, 1, true)
+                                    parseUnaryExpression([, true)
+                                      parsePrimary([, expression)
+                                        parseLiteralNull([)
+                                          listener: handleLiteralNull(null)
+                                listener: handleLiteralList(1, [, const, ])
+                            listener: endConstLiteral(;)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, F)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, final, final, Instance of 'SimpleTypeWith1Argument', foo7, DeclarationKind.Class, F, false)
+                listener: beginFields(;)
+                listener: handleIdentifier(List, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(1, <, >)
+                listener: handleType(List, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo7, fieldDeclaration)
+                parseFieldInitializerOpt(foo7, foo7, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseConstExpression(=)
+                            reportRecoverableError(List, Message[LiteralWithClass, A list literal can't be prefixed by 'List'., Try removing 'List', {string: list, lexeme: List}])
+                              listener: handleRecoverableError(Message[LiteralWithClass, A list literal can't be prefixed by 'List'., Try removing 'List', {string: list, lexeme: List}], List, List)
+                            listener: beginConstLiteral([)
+                            listener: handleNoTypeArguments([)
+                            parseLiteralListSuffix(List, const)
+                              parseExpression([)
+                                parsePrecedenceExpression([, 1, true)
+                                  parseUnaryExpression([, true)
+                                    parsePrimary([, expression)
+                                      parseLiteralNull([)
+                                        listener: handleLiteralNull(null)
+                              listener: handleLiteralList(1, [, const, ])
+                            listener: endConstLiteral(;)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, F)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, final, final, Instance of 'SimpleTypeWith1Argument', foo8, DeclarationKind.Class, F, false)
+                listener: beginFields(;)
+                listener: handleIdentifier(List, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(1, <, >)
+                listener: handleType(List, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo8, fieldDeclaration)
+                parseFieldInitializerOpt(foo8, foo8, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseConstExpression(=)
+                            listener: beginConstLiteral(<)
+                            parseLiteralListSetMapOrFunction(const, const)
+                              listener: beginTypeArguments(<)
+                              listener: handleIdentifier(List, typeReference)
+                              listener: beginTypeArguments(<)
+                              listener: handleIdentifier(int, typeReference)
+                              listener: handleNoTypeArguments(>)
+                              listener: handleType(int, null)
+                              listener: endTypeArguments(1, <, >)
+                              listener: handleType(List, null)
+                              listener: endTypeArguments(1, <, >)
+                              parseLiteralListSuffix(>, const)
+                                parseExpression([)
+                                  parsePrecedenceExpression([, 1, true)
+                                    parseUnaryExpression([, true)
+                                      parsePrimary([, expression)
+                                        parseLiteralNull([)
+                                          listener: handleLiteralNull(null)
+                                listener: handleLiteralList(1, [, const, ])
+                            listener: endConstLiteral(;)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, F)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, final, final, Instance of 'SimpleTypeWith1Argument', foo9, DeclarationKind.Class, F, false)
+                listener: beginFields(;)
+                listener: handleIdentifier(List, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(1, <, >)
+                listener: handleType(List, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo9, fieldDeclaration)
+                parseFieldInitializerOpt(foo9, foo9, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseConstExpression(=)
+                            listener: beginConstLiteral([)
+                            listener: handleNoTypeArguments([)
+                            parseLiteralListSuffix(const, const)
+                              parseExpression([)
+                                parsePrecedenceExpression([, 1, true)
+                                  parseUnaryExpression([, true)
+                                    parsePrimary([, expression)
+                                      parseLiteralNull([)
+                                        listener: handleLiteralNull(null)
+                              listener: handleLiteralList(1, [, const, ])
+                            listener: endConstLiteral(;)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, })
+            listener: endClassOrMixinBody(DeclarationKind.Class, 9, {, })
+          listener: endClassDeclaration(class, })
+  listener: endTopLevelDeclaration()
+  reportAllErrorTokens(class)
+  listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_45251_list_const.dart.parser.expect b/pkg/front_end/parser_testcases/error_recovery/issue_45251_list_const.dart.parser.expect
new file mode 100644
index 0000000..bbe5abb
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_45251_list_const.dart.parser.expect
@@ -0,0 +1,61 @@
+NOTICE: Stream was rewritten by parser!
+
+class F {
+
+final List<Undefined> foo1 = const List<List<int>>[];
+
+
+final List<Undefined> foo2 = const <List<int>>[];
+
+
+final List<Undefined> foo3 = const List[];
+
+
+final List<Undefined> foo4 = const List<List<int>>();
+
+
+final List<Undefined> foo5 = const List();
+
+
+final List<Undefined> foo6 = const List<List<int>>[null];
+
+
+
+final List<Undefined> foo7 = const List[null];
+
+
+final List<Undefined> foo8 = const <List<int>>[null];
+
+
+final List<Undefined> foo9 = const [null];
+}
+
+class[KeywordToken] F[StringToken] {[BeginToken]
+
+final[KeywordToken] List[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo1[StringToken] =[SimpleToken] const[KeywordToken] List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]int[StringToken]>[SimpleToken]>[SimpleToken][[BeginToken]][SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] List[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo2[StringToken] =[SimpleToken] const[KeywordToken] <[BeginToken]List[StringToken]<[BeginToken]int[StringToken]>[SimpleToken]>[SimpleToken][[BeginToken]][SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] List[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo3[StringToken] =[SimpleToken] const[KeywordToken] List[StringToken][[BeginToken]][SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] List[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo4[StringToken] =[SimpleToken] const[KeywordToken] List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]int[StringToken]>[SimpleToken]>[SimpleToken]([BeginToken])[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] List[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo5[StringToken] =[SimpleToken] const[KeywordToken] List[StringToken]([BeginToken])[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] List[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo6[StringToken] =[SimpleToken] const[KeywordToken] List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]int[StringToken]>[SimpleToken]>[SimpleToken][[BeginToken]null[KeywordToken]][SimpleToken];[SimpleToken]
+
+
+
+final[KeywordToken] List[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo7[StringToken] =[SimpleToken] const[KeywordToken] List[StringToken][[BeginToken]null[KeywordToken]][SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] List[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo8[StringToken] =[SimpleToken] const[KeywordToken] <[BeginToken]List[StringToken]<[BeginToken]int[StringToken]>[SimpleToken]>[SimpleToken][[BeginToken]null[KeywordToken]][SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] List[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo9[StringToken] =[SimpleToken] const[KeywordToken] [[BeginToken]null[KeywordToken]][SimpleToken];[SimpleToken]
+}[SimpleToken][SimpleToken]
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_45251_list_const.dart.scanner.expect b/pkg/front_end/parser_testcases/error_recovery/issue_45251_list_const.dart.scanner.expect
new file mode 100644
index 0000000..12dac96
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_45251_list_const.dart.scanner.expect
@@ -0,0 +1,59 @@
+class F {
+
+final List<Undefined> foo1 = const List<List<int>>[];
+
+
+final List<Undefined> foo2 = const <List<int>>[];
+
+
+final List<Undefined> foo3 = const List[];
+
+
+final List<Undefined> foo4 = const List<List<int>>();
+
+
+final List<Undefined> foo5 = const List();
+
+
+final List<Undefined> foo6 = const List<List<int>>[null];
+
+
+
+final List<Undefined> foo7 = const List[null];
+
+
+final List<Undefined> foo8 = const <List<int>>[null];
+
+
+final List<Undefined> foo9 = const [null];
+}
+
+class[KeywordToken] F[StringToken] {[BeginToken]
+
+final[KeywordToken] List[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo1[StringToken] =[SimpleToken] const[KeywordToken] List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]int[StringToken]>>[SimpleToken][][SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] List[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo2[StringToken] =[SimpleToken] const[KeywordToken] <[BeginToken]List[StringToken]<[BeginToken]int[StringToken]>>[SimpleToken][][SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] List[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo3[StringToken] =[SimpleToken] const[KeywordToken] List[StringToken][][SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] List[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo4[StringToken] =[SimpleToken] const[KeywordToken] List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]int[StringToken]>>[SimpleToken]([BeginToken])[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] List[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo5[StringToken] =[SimpleToken] const[KeywordToken] List[StringToken]([BeginToken])[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] List[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo6[StringToken] =[SimpleToken] const[KeywordToken] List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]int[StringToken]>>[SimpleToken][[BeginToken]null[KeywordToken]][SimpleToken];[SimpleToken]
+
+
+
+final[KeywordToken] List[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo7[StringToken] =[SimpleToken] const[KeywordToken] List[StringToken][[BeginToken]null[KeywordToken]][SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] List[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo8[StringToken] =[SimpleToken] const[KeywordToken] <[BeginToken]List[StringToken]<[BeginToken]int[StringToken]>>[SimpleToken][[BeginToken]null[KeywordToken]][SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] List[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo9[StringToken] =[SimpleToken] const[KeywordToken] [[BeginToken]null[KeywordToken]][SimpleToken];[SimpleToken]
+}[SimpleToken][SimpleToken]
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_45251_list_new.dart b/pkg/front_end/parser_testcases/error_recovery/issue_45251_list_new.dart
new file mode 100644
index 0000000..d05a529
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_45251_list_new.dart
@@ -0,0 +1,29 @@
+class F {
+  /* notice the bracket at the end instead of parenthesis! */
+  final List<Undefined> foo1 = new List<List<int>>[];
+
+  // variation #1: new makes it bad.
+  final List<Undefined> foo2 = new <List<int>>[];
+
+  // variation #2: Bad.
+  final List<Undefined> foo3 = new List[];
+
+  // variation #3: OK.
+  final List<Undefined> foo4 = new List<List<int>>();
+
+  // variation #4: OK.
+  final List<Undefined> foo5 = new List();
+
+  // variation #5: Bad.
+  final List<Undefined> foo6 = new List<List<int>>[null];
+
+  // variation #6: new makes it bad. Without new it would be an indexed
+  // expression; We should probably recover as `[null]`.
+  final List<Undefined> foo7 = new List[null];
+
+  // variation #7: new makes it bad.
+  final List<Undefined> foo8 = new <List<int>>[null];
+
+  // variation #8: new makes it bad.
+  final List<Undefined> foo9 = new [null];
+}
\ No newline at end of file
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_45251_list_new.dart.expect b/pkg/front_end/parser_testcases/error_recovery/issue_45251_list_new.dart.expect
new file mode 100644
index 0000000..447db69
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_45251_list_new.dart.expect
@@ -0,0 +1,274 @@
+Problems reported:
+
+parser/error_recovery/issue_45251_list_new:3:32: A list literal can't be prefixed by 'new List'.
+  final List<Undefined> foo1 = new List<List<int>>[];
+                               ^^^^^^^^
+
+parser/error_recovery/issue_45251_list_new:6:32: A literal can't be prefixed by 'new'.
+  final List<Undefined> foo2 = new <List<int>>[];
+                               ^^^
+
+parser/error_recovery/issue_45251_list_new:9:32: A list literal can't be prefixed by 'new List'.
+  final List<Undefined> foo3 = new List[];
+                               ^^^^^^^^
+
+parser/error_recovery/issue_45251_list_new:18:32: A list literal can't be prefixed by 'new List'.
+  final List<Undefined> foo6 = new List<List<int>>[null];
+                               ^^^^^^^^
+
+parser/error_recovery/issue_45251_list_new:22:32: A list literal can't be prefixed by 'new List'.
+  final List<Undefined> foo7 = new List[null];
+                               ^^^^^^^^
+
+parser/error_recovery/issue_45251_list_new:25:32: A literal can't be prefixed by 'new'.
+  final List<Undefined> foo8 = new <List<int>>[null];
+                               ^^^
+
+parser/error_recovery/issue_45251_list_new:28:32: A literal can't be prefixed by 'new'.
+  final List<Undefined> foo9 = new [null];
+                               ^^^
+
+beginCompilationUnit(class)
+  beginMetadataStar(class)
+  endMetadataStar(0)
+  beginClassOrNamedMixinApplicationPrelude(class)
+    handleIdentifier(F, classOrMixinDeclaration)
+    handleNoTypeVariables({)
+    beginClassDeclaration(class, null, F)
+      handleNoType(F)
+      handleClassExtends(null, 1)
+      handleClassNoWithClause()
+      handleClassOrMixinImplements(null, 0)
+      handleClassHeader(class, class, null)
+      beginClassOrMixinBody(DeclarationKind.Class, {)
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields({)
+            handleIdentifier(List, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(1, <, >)
+            handleType(List, null)
+            handleIdentifier(foo1, fieldDeclaration)
+            beginFieldInitializer(=)
+              handleRecoverableError(Message[LiteralWithClassAndNew, A list literal can't be prefixed by 'new List'., Try removing 'new' and 'List', {string: list, lexeme: List}], new, List)
+              beginTypeArguments(<)
+                handleIdentifier(List, typeReference)
+                beginTypeArguments(<)
+                  handleIdentifier(int, typeReference)
+                  handleNoTypeArguments(>)
+                  handleType(int, null)
+                endTypeArguments(1, <, >)
+                handleType(List, null)
+              endTypeArguments(1, <, >)
+              handleLiteralList(0, [, null, ])
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields(;)
+            handleIdentifier(List, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(1, <, >)
+            handleType(List, null)
+            handleIdentifier(foo2, fieldDeclaration)
+            beginFieldInitializer(=)
+              handleRecoverableError(LiteralWithNew, new, new)
+              beginTypeArguments(<)
+                handleIdentifier(List, typeReference)
+                beginTypeArguments(<)
+                  handleIdentifier(int, typeReference)
+                  handleNoTypeArguments(>)
+                  handleType(int, null)
+                endTypeArguments(1, <, >)
+                handleType(List, null)
+              endTypeArguments(1, <, >)
+              handleLiteralList(0, [, null, ])
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields(;)
+            handleIdentifier(List, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(1, <, >)
+            handleType(List, null)
+            handleIdentifier(foo3, fieldDeclaration)
+            beginFieldInitializer(=)
+              handleRecoverableError(Message[LiteralWithClassAndNew, A list literal can't be prefixed by 'new List'., Try removing 'new' and 'List', {string: list, lexeme: List}], new, List)
+              handleNoTypeArguments([])
+              handleLiteralList(0, [, null, ])
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields(;)
+            handleIdentifier(List, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(1, <, >)
+            handleType(List, null)
+            handleIdentifier(foo4, fieldDeclaration)
+            beginFieldInitializer(=)
+              beginNewExpression(new)
+                handleIdentifier(List, constructorReference)
+                beginConstructorReference(List)
+                  beginTypeArguments(<)
+                    handleIdentifier(List, typeReference)
+                    beginTypeArguments(<)
+                      handleIdentifier(int, typeReference)
+                      handleNoTypeArguments(>)
+                      handleType(int, null)
+                    endTypeArguments(1, <, >)
+                    handleType(List, null)
+                  endTypeArguments(1, <, >)
+                  handleNoConstructorReferenceContinuationAfterTypeArguments(()
+                endConstructorReference(List, null, ()
+                beginArguments(()
+                endArguments(0, (, ))
+              endNewExpression(new)
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields(;)
+            handleIdentifier(List, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(1, <, >)
+            handleType(List, null)
+            handleIdentifier(foo5, fieldDeclaration)
+            beginFieldInitializer(=)
+              beginNewExpression(new)
+                handleIdentifier(List, constructorReference)
+                beginConstructorReference(List)
+                  handleNoTypeArguments(()
+                  handleNoConstructorReferenceContinuationAfterTypeArguments(()
+                endConstructorReference(List, null, ()
+                beginArguments(()
+                endArguments(0, (, ))
+              endNewExpression(new)
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields(;)
+            handleIdentifier(List, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(1, <, >)
+            handleType(List, null)
+            handleIdentifier(foo6, fieldDeclaration)
+            beginFieldInitializer(=)
+              handleRecoverableError(Message[LiteralWithClassAndNew, A list literal can't be prefixed by 'new List'., Try removing 'new' and 'List', {string: list, lexeme: List}], new, List)
+              beginTypeArguments(<)
+                handleIdentifier(List, typeReference)
+                beginTypeArguments(<)
+                  handleIdentifier(int, typeReference)
+                  handleNoTypeArguments(>)
+                  handleType(int, null)
+                endTypeArguments(1, <, >)
+                handleType(List, null)
+              endTypeArguments(1, <, >)
+              handleLiteralNull(null)
+              handleLiteralList(1, [, null, ])
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields(;)
+            handleIdentifier(List, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(1, <, >)
+            handleType(List, null)
+            handleIdentifier(foo7, fieldDeclaration)
+            beginFieldInitializer(=)
+              handleRecoverableError(Message[LiteralWithClassAndNew, A list literal can't be prefixed by 'new List'., Try removing 'new' and 'List', {string: list, lexeme: List}], new, List)
+              handleNoTypeArguments([)
+              handleLiteralNull(null)
+              handleLiteralList(1, [, null, ])
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields(;)
+            handleIdentifier(List, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(1, <, >)
+            handleType(List, null)
+            handleIdentifier(foo8, fieldDeclaration)
+            beginFieldInitializer(=)
+              handleRecoverableError(LiteralWithNew, new, new)
+              beginTypeArguments(<)
+                handleIdentifier(List, typeReference)
+                beginTypeArguments(<)
+                  handleIdentifier(int, typeReference)
+                  handleNoTypeArguments(>)
+                  handleType(int, null)
+                endTypeArguments(1, <, >)
+                handleType(List, null)
+              endTypeArguments(1, <, >)
+              handleLiteralNull(null)
+              handleLiteralList(1, [, null, ])
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields(;)
+            handleIdentifier(List, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(1, <, >)
+            handleType(List, null)
+            handleIdentifier(foo9, fieldDeclaration)
+            beginFieldInitializer(=)
+              handleRecoverableError(LiteralWithNew, new, new)
+              handleNoTypeArguments([)
+              handleLiteralNull(null)
+              handleLiteralList(1, [, null, ])
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+      endClassOrMixinBody(DeclarationKind.Class, 9, {, })
+    endClassDeclaration(class, })
+  endTopLevelDeclaration()
+endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_45251_list_new.dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/issue_45251_list_new.dart.intertwined.expect
new file mode 100644
index 0000000..9dd8aca
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_45251_list_new.dart.intertwined.expect
@@ -0,0 +1,420 @@
+parseUnit(class)
+  skipErrorTokens(class)
+  listener: beginCompilationUnit(class)
+  syntheticPreviousToken(class)
+  parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+    parseMetadataStar()
+      listener: beginMetadataStar(class)
+      listener: endMetadataStar(0)
+    parseTopLevelKeywordDeclaration(, class, Instance of 'DirectiveContext')
+      parseClassDeclarationModifiers(, class)
+      parseClassOrNamedMixinApplication(null, class)
+        listener: beginClassOrNamedMixinApplicationPrelude(class)
+        ensureIdentifier(class, classOrMixinDeclaration)
+          listener: handleIdentifier(F, classOrMixinDeclaration)
+        listener: handleNoTypeVariables({)
+        listener: beginClassDeclaration(class, null, F)
+        parseClass(F, class, class, F)
+          parseClassHeaderOpt(F, class, class)
+            parseClassExtendsOpt(F)
+              listener: handleNoType(F)
+              listener: handleClassExtends(null, 1)
+            parseWithClauseOpt(F)
+              listener: handleClassNoWithClause()
+            parseClassOrMixinImplementsOpt(F)
+              listener: handleClassOrMixinImplements(null, 0)
+            listener: handleClassHeader(class, class, null)
+          parseClassOrMixinOrExtensionBody(F, DeclarationKind.Class, F)
+            listener: beginClassOrMixinBody(DeclarationKind.Class, {)
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl({, DeclarationKind.Class, F)
+              parseMetadataStar({)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields({, null, null, null, null, null, final, final, Instance of 'SimpleTypeWith1Argument', foo1, DeclarationKind.Class, F, false)
+                listener: beginFields({)
+                listener: handleIdentifier(List, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(1, <, >)
+                listener: handleType(List, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo1, fieldDeclaration)
+                parseFieldInitializerOpt(foo1, foo1, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseNewExpression(=)
+                            listener: handleRecoverableError(Message[LiteralWithClassAndNew, A list literal can't be prefixed by 'new List'., Try removing 'new' and 'List', {string: list, lexeme: List}], new, List)
+                            parsePrimary(List, expression)
+                              parseLiteralListSetMapOrFunction(List, null)
+                                listener: beginTypeArguments(<)
+                                listener: handleIdentifier(List, typeReference)
+                                listener: beginTypeArguments(<)
+                                listener: handleIdentifier(int, typeReference)
+                                listener: handleNoTypeArguments(>)
+                                listener: handleType(int, null)
+                                listener: endTypeArguments(1, <, >)
+                                listener: handleType(List, null)
+                                listener: endTypeArguments(1, <, >)
+                                parseLiteralListSuffix(>, null)
+                                  rewriteSquareBrackets(>)
+                                    link([, ])
+                                    rewriter()
+                                  listener: handleLiteralList(0, [, null, ])
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, F)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, final, final, Instance of 'SimpleTypeWith1Argument', foo2, DeclarationKind.Class, F, false)
+                listener: beginFields(;)
+                listener: handleIdentifier(List, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(1, <, >)
+                listener: handleType(List, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo2, fieldDeclaration)
+                parseFieldInitializerOpt(foo2, foo2, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseNewExpression(=)
+                            reportRecoverableError(new, LiteralWithNew)
+                              listener: handleRecoverableError(LiteralWithNew, new, new)
+                            parsePrimary(new, expression)
+                              parseLiteralListSetMapOrFunction(new, null)
+                                listener: beginTypeArguments(<)
+                                listener: handleIdentifier(List, typeReference)
+                                listener: beginTypeArguments(<)
+                                listener: handleIdentifier(int, typeReference)
+                                listener: handleNoTypeArguments(>)
+                                listener: handleType(int, null)
+                                listener: endTypeArguments(1, <, >)
+                                listener: handleType(List, null)
+                                listener: endTypeArguments(1, <, >)
+                                parseLiteralListSuffix(>, null)
+                                  rewriteSquareBrackets(>)
+                                    link([, ])
+                                    rewriter()
+                                  listener: handleLiteralList(0, [, null, ])
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, F)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, final, final, Instance of 'SimpleTypeWith1Argument', foo3, DeclarationKind.Class, F, false)
+                listener: beginFields(;)
+                listener: handleIdentifier(List, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(1, <, >)
+                listener: handleType(List, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo3, fieldDeclaration)
+                parseFieldInitializerOpt(foo3, foo3, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseNewExpression(=)
+                            listener: handleRecoverableError(Message[LiteralWithClassAndNew, A list literal can't be prefixed by 'new List'., Try removing 'new' and 'List', {string: list, lexeme: List}], new, List)
+                            parsePrimary(List, expression)
+                              listener: handleNoTypeArguments([])
+                              parseLiteralListSuffix(List, null)
+                                rewriteSquareBrackets(List)
+                                  link([, ])
+                                  rewriter()
+                                listener: handleLiteralList(0, [, null, ])
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, F)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, final, final, Instance of 'SimpleTypeWith1Argument', foo4, DeclarationKind.Class, F, false)
+                listener: beginFields(;)
+                listener: handleIdentifier(List, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(1, <, >)
+                listener: handleType(List, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo4, fieldDeclaration)
+                parseFieldInitializerOpt(foo4, foo4, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseNewExpression(=)
+                            listener: beginNewExpression(new)
+                            parseConstructorReference(new, Instance of 'ComplexTypeParamOrArgInfo')
+                              ensureIdentifier(new, constructorReference)
+                                listener: handleIdentifier(List, constructorReference)
+                              listener: beginConstructorReference(List)
+                              parseQualifiedRestOpt(List, constructorReferenceContinuation)
+                              listener: beginTypeArguments(<)
+                              listener: handleIdentifier(List, typeReference)
+                              listener: beginTypeArguments(<)
+                              listener: handleIdentifier(int, typeReference)
+                              listener: handleNoTypeArguments(>)
+                              listener: handleType(int, null)
+                              listener: endTypeArguments(1, <, >)
+                              listener: handleType(List, null)
+                              listener: endTypeArguments(1, <, >)
+                              listener: handleNoConstructorReferenceContinuationAfterTypeArguments(()
+                              listener: endConstructorReference(List, null, ()
+                            parseConstructorInvocationArguments(>)
+                              parseArgumentsRest(()
+                                listener: beginArguments(()
+                                listener: endArguments(0, (, ))
+                            listener: endNewExpression(new)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, F)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, final, final, Instance of 'SimpleTypeWith1Argument', foo5, DeclarationKind.Class, F, false)
+                listener: beginFields(;)
+                listener: handleIdentifier(List, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(1, <, >)
+                listener: handleType(List, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo5, fieldDeclaration)
+                parseFieldInitializerOpt(foo5, foo5, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseNewExpression(=)
+                            listener: beginNewExpression(new)
+                            parseConstructorReference(new, Instance of 'NoTypeParamOrArg')
+                              ensureIdentifier(new, constructorReference)
+                                listener: handleIdentifier(List, constructorReference)
+                              listener: beginConstructorReference(List)
+                              parseQualifiedRestOpt(List, constructorReferenceContinuation)
+                              listener: handleNoTypeArguments(()
+                              listener: handleNoConstructorReferenceContinuationAfterTypeArguments(()
+                              listener: endConstructorReference(List, null, ()
+                            parseConstructorInvocationArguments(List)
+                              parseArgumentsRest(()
+                                listener: beginArguments(()
+                                listener: endArguments(0, (, ))
+                            listener: endNewExpression(new)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, F)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, final, final, Instance of 'SimpleTypeWith1Argument', foo6, DeclarationKind.Class, F, false)
+                listener: beginFields(;)
+                listener: handleIdentifier(List, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(1, <, >)
+                listener: handleType(List, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo6, fieldDeclaration)
+                parseFieldInitializerOpt(foo6, foo6, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseNewExpression(=)
+                            listener: handleRecoverableError(Message[LiteralWithClassAndNew, A list literal can't be prefixed by 'new List'., Try removing 'new' and 'List', {string: list, lexeme: List}], new, List)
+                            parsePrimary(List, expression)
+                              parseLiteralListSetMapOrFunction(List, null)
+                                listener: beginTypeArguments(<)
+                                listener: handleIdentifier(List, typeReference)
+                                listener: beginTypeArguments(<)
+                                listener: handleIdentifier(int, typeReference)
+                                listener: handleNoTypeArguments(>)
+                                listener: handleType(int, null)
+                                listener: endTypeArguments(1, <, >)
+                                listener: handleType(List, null)
+                                listener: endTypeArguments(1, <, >)
+                                parseLiteralListSuffix(>, null)
+                                  parseExpression([)
+                                    parsePrecedenceExpression([, 1, true)
+                                      parseUnaryExpression([, true)
+                                        parsePrimary([, expression)
+                                          parseLiteralNull([)
+                                            listener: handleLiteralNull(null)
+                                  listener: handleLiteralList(1, [, null, ])
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, F)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, final, final, Instance of 'SimpleTypeWith1Argument', foo7, DeclarationKind.Class, F, false)
+                listener: beginFields(;)
+                listener: handleIdentifier(List, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(1, <, >)
+                listener: handleType(List, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo7, fieldDeclaration)
+                parseFieldInitializerOpt(foo7, foo7, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseNewExpression(=)
+                            listener: handleRecoverableError(Message[LiteralWithClassAndNew, A list literal can't be prefixed by 'new List'., Try removing 'new' and 'List', {string: list, lexeme: List}], new, List)
+                            parsePrimary(List, expression)
+                              listener: handleNoTypeArguments([)
+                              parseLiteralListSuffix(List, null)
+                                parseExpression([)
+                                  parsePrecedenceExpression([, 1, true)
+                                    parseUnaryExpression([, true)
+                                      parsePrimary([, expression)
+                                        parseLiteralNull([)
+                                          listener: handleLiteralNull(null)
+                                listener: handleLiteralList(1, [, null, ])
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, F)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, final, final, Instance of 'SimpleTypeWith1Argument', foo8, DeclarationKind.Class, F, false)
+                listener: beginFields(;)
+                listener: handleIdentifier(List, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(1, <, >)
+                listener: handleType(List, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo8, fieldDeclaration)
+                parseFieldInitializerOpt(foo8, foo8, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseNewExpression(=)
+                            reportRecoverableError(new, LiteralWithNew)
+                              listener: handleRecoverableError(LiteralWithNew, new, new)
+                            parsePrimary(new, expression)
+                              parseLiteralListSetMapOrFunction(new, null)
+                                listener: beginTypeArguments(<)
+                                listener: handleIdentifier(List, typeReference)
+                                listener: beginTypeArguments(<)
+                                listener: handleIdentifier(int, typeReference)
+                                listener: handleNoTypeArguments(>)
+                                listener: handleType(int, null)
+                                listener: endTypeArguments(1, <, >)
+                                listener: handleType(List, null)
+                                listener: endTypeArguments(1, <, >)
+                                parseLiteralListSuffix(>, null)
+                                  parseExpression([)
+                                    parsePrecedenceExpression([, 1, true)
+                                      parseUnaryExpression([, true)
+                                        parsePrimary([, expression)
+                                          parseLiteralNull([)
+                                            listener: handleLiteralNull(null)
+                                  listener: handleLiteralList(1, [, null, ])
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, F)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, final, final, Instance of 'SimpleTypeWith1Argument', foo9, DeclarationKind.Class, F, false)
+                listener: beginFields(;)
+                listener: handleIdentifier(List, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(1, <, >)
+                listener: handleType(List, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo9, fieldDeclaration)
+                parseFieldInitializerOpt(foo9, foo9, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseNewExpression(=)
+                            reportRecoverableError(new, LiteralWithNew)
+                              listener: handleRecoverableError(LiteralWithNew, new, new)
+                            parsePrimary(new, expression)
+                              listener: handleNoTypeArguments([)
+                              parseLiteralListSuffix(new, null)
+                                parseExpression([)
+                                  parsePrecedenceExpression([, 1, true)
+                                    parseUnaryExpression([, true)
+                                      parsePrimary([, expression)
+                                        parseLiteralNull([)
+                                          listener: handleLiteralNull(null)
+                                listener: handleLiteralList(1, [, null, ])
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, })
+            listener: endClassOrMixinBody(DeclarationKind.Class, 9, {, })
+          listener: endClassDeclaration(class, })
+  listener: endTopLevelDeclaration()
+  reportAllErrorTokens(class)
+  listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_45251_list_new.dart.parser.expect b/pkg/front_end/parser_testcases/error_recovery/issue_45251_list_new.dart.parser.expect
new file mode 100644
index 0000000..4d592a3
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_45251_list_new.dart.parser.expect
@@ -0,0 +1,61 @@
+NOTICE: Stream was rewritten by parser!
+
+class F {
+
+final List<Undefined> foo1 = new List<List<int>>[];
+
+
+final List<Undefined> foo2 = new <List<int>>[];
+
+
+final List<Undefined> foo3 = new List[];
+
+
+final List<Undefined> foo4 = new List<List<int>>();
+
+
+final List<Undefined> foo5 = new List();
+
+
+final List<Undefined> foo6 = new List<List<int>>[null];
+
+
+
+final List<Undefined> foo7 = new List[null];
+
+
+final List<Undefined> foo8 = new <List<int>>[null];
+
+
+final List<Undefined> foo9 = new [null];
+}
+
+class[KeywordToken] F[StringToken] {[BeginToken]
+
+final[KeywordToken] List[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo1[StringToken] =[SimpleToken] new[KeywordToken] List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]int[StringToken]>[SimpleToken]>[SimpleToken][[BeginToken]][SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] List[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo2[StringToken] =[SimpleToken] new[KeywordToken] <[BeginToken]List[StringToken]<[BeginToken]int[StringToken]>[SimpleToken]>[SimpleToken][[BeginToken]][SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] List[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo3[StringToken] =[SimpleToken] new[KeywordToken] List[StringToken][[BeginToken]][SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] List[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo4[StringToken] =[SimpleToken] new[KeywordToken] List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]int[StringToken]>[SimpleToken]>[SimpleToken]([BeginToken])[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] List[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo5[StringToken] =[SimpleToken] new[KeywordToken] List[StringToken]([BeginToken])[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] List[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo6[StringToken] =[SimpleToken] new[KeywordToken] List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]int[StringToken]>[SimpleToken]>[SimpleToken][[BeginToken]null[KeywordToken]][SimpleToken];[SimpleToken]
+
+
+
+final[KeywordToken] List[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo7[StringToken] =[SimpleToken] new[KeywordToken] List[StringToken][[BeginToken]null[KeywordToken]][SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] List[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo8[StringToken] =[SimpleToken] new[KeywordToken] <[BeginToken]List[StringToken]<[BeginToken]int[StringToken]>[SimpleToken]>[SimpleToken][[BeginToken]null[KeywordToken]][SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] List[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo9[StringToken] =[SimpleToken] new[KeywordToken] [[BeginToken]null[KeywordToken]][SimpleToken];[SimpleToken]
+}[SimpleToken][SimpleToken]
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_45251_list_new.dart.scanner.expect b/pkg/front_end/parser_testcases/error_recovery/issue_45251_list_new.dart.scanner.expect
new file mode 100644
index 0000000..9905387
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_45251_list_new.dart.scanner.expect
@@ -0,0 +1,59 @@
+class F {
+
+final List<Undefined> foo1 = new List<List<int>>[];
+
+
+final List<Undefined> foo2 = new <List<int>>[];
+
+
+final List<Undefined> foo3 = new List[];
+
+
+final List<Undefined> foo4 = new List<List<int>>();
+
+
+final List<Undefined> foo5 = new List();
+
+
+final List<Undefined> foo6 = new List<List<int>>[null];
+
+
+
+final List<Undefined> foo7 = new List[null];
+
+
+final List<Undefined> foo8 = new <List<int>>[null];
+
+
+final List<Undefined> foo9 = new [null];
+}
+
+class[KeywordToken] F[StringToken] {[BeginToken]
+
+final[KeywordToken] List[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo1[StringToken] =[SimpleToken] new[KeywordToken] List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]int[StringToken]>>[SimpleToken][][SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] List[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo2[StringToken] =[SimpleToken] new[KeywordToken] <[BeginToken]List[StringToken]<[BeginToken]int[StringToken]>>[SimpleToken][][SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] List[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo3[StringToken] =[SimpleToken] new[KeywordToken] List[StringToken][][SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] List[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo4[StringToken] =[SimpleToken] new[KeywordToken] List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]int[StringToken]>>[SimpleToken]([BeginToken])[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] List[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo5[StringToken] =[SimpleToken] new[KeywordToken] List[StringToken]([BeginToken])[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] List[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo6[StringToken] =[SimpleToken] new[KeywordToken] List[StringToken]<[BeginToken]List[StringToken]<[BeginToken]int[StringToken]>>[SimpleToken][[BeginToken]null[KeywordToken]][SimpleToken];[SimpleToken]
+
+
+
+final[KeywordToken] List[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo7[StringToken] =[SimpleToken] new[KeywordToken] List[StringToken][[BeginToken]null[KeywordToken]][SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] List[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo8[StringToken] =[SimpleToken] new[KeywordToken] <[BeginToken]List[StringToken]<[BeginToken]int[StringToken]>>[SimpleToken][[BeginToken]null[KeywordToken]][SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] List[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo9[StringToken] =[SimpleToken] new[KeywordToken] [[BeginToken]null[KeywordToken]][SimpleToken];[SimpleToken]
+}[SimpleToken][SimpleToken]
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_45251_new.dart b/pkg/front_end/parser_testcases/error_recovery/issue_45251_new.dart
new file mode 100644
index 0000000..7ce5659
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_45251_new.dart
@@ -0,0 +1,28 @@
+class F {
+  /* notice the braces at the end instead of parenthesis! */
+  final Map<String, Undefined> foo1 = new Map<String, List<int>>{};
+
+  // variation #1: new makes it bad.
+  final Map<String, Undefined> foo2 = new <String, List<int>>{};
+
+  // variation #2: Bad.
+  final Map<String, Undefined> foo3 = new Map{};
+
+  // variation #3: OK.
+  final Map<String, Undefined> foo4 = new Map<String, List<int>>();
+
+  // variation #4: OK.
+  final Map<String, Undefined> foo5 = new Map();
+
+  // variation #5: Bad.
+  final Map<String, Undefined> foo6 = new Map<String, List<int>>{"a": null};
+
+  // variation #6: Bad.
+  final Map<String, Undefined> foo7 = new Map{"a": null};
+
+  // variation #7: OK.
+  final Map<String, Undefined> foo8 = new <String, List<int>>{"a": null};
+
+  // variation #8: new makes it bad.
+  final Map<String, Undefined> foo9 = new {"a": null};
+}
\ No newline at end of file
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_45251_new.dart.expect b/pkg/front_end/parser_testcases/error_recovery/issue_45251_new.dart.expect
new file mode 100644
index 0000000..c1b095d
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_45251_new.dart.expect
@@ -0,0 +1,328 @@
+Problems reported:
+
+parser/error_recovery/issue_45251_new:3:39: A map literal can't be prefixed by 'new Map'.
+  final Map<String, Undefined> foo1 = new Map<String, List<int>>{};
+                                      ^^^^^^^
+
+parser/error_recovery/issue_45251_new:6:39: A literal can't be prefixed by 'new'.
+  final Map<String, Undefined> foo2 = new <String, List<int>>{};
+                                      ^^^
+
+parser/error_recovery/issue_45251_new:9:39: A map literal can't be prefixed by 'new Map'.
+  final Map<String, Undefined> foo3 = new Map{};
+                                      ^^^^^^^
+
+parser/error_recovery/issue_45251_new:18:39: A map literal can't be prefixed by 'new Map'.
+  final Map<String, Undefined> foo6 = new Map<String, List<int>>{"a": null};
+                                      ^^^^^^^
+
+parser/error_recovery/issue_45251_new:21:39: A map literal can't be prefixed by 'new Map'.
+  final Map<String, Undefined> foo7 = new Map{"a": null};
+                                      ^^^^^^^
+
+parser/error_recovery/issue_45251_new:24:39: A literal can't be prefixed by 'new'.
+  final Map<String, Undefined> foo8 = new <String, List<int>>{"a": null};
+                                      ^^^
+
+parser/error_recovery/issue_45251_new:27:39: A literal can't be prefixed by 'new'.
+  final Map<String, Undefined> foo9 = new {"a": null};
+                                      ^^^
+
+beginCompilationUnit(class)
+  beginMetadataStar(class)
+  endMetadataStar(0)
+  beginClassOrNamedMixinApplicationPrelude(class)
+    handleIdentifier(F, classOrMixinDeclaration)
+    handleNoTypeVariables({)
+    beginClassDeclaration(class, null, F)
+      handleNoType(F)
+      handleClassExtends(null, 1)
+      handleClassNoWithClause()
+      handleClassOrMixinImplements(null, 0)
+      handleClassHeader(class, class, null)
+      beginClassOrMixinBody(DeclarationKind.Class, {)
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields({)
+            handleIdentifier(Map, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(String, typeReference)
+              handleNoTypeArguments(,)
+              handleType(String, null)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(2, <, >)
+            handleType(Map, null)
+            handleIdentifier(foo1, fieldDeclaration)
+            beginFieldInitializer(=)
+              handleRecoverableError(Message[LiteralWithClassAndNew, A map literal can't be prefixed by 'new Map'., Try removing 'new' and 'Map', {string: map, lexeme: Map}], new, Map)
+              beginTypeArguments(<)
+                handleIdentifier(String, typeReference)
+                handleNoTypeArguments(,)
+                handleType(String, null)
+                handleIdentifier(List, typeReference)
+                beginTypeArguments(<)
+                  handleIdentifier(int, typeReference)
+                  handleNoTypeArguments(>)
+                  handleType(int, null)
+                endTypeArguments(1, <, >)
+                handleType(List, null)
+              endTypeArguments(2, <, >)
+              handleLiteralSetOrMap(0, {, null, }, false)
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields(;)
+            handleIdentifier(Map, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(String, typeReference)
+              handleNoTypeArguments(,)
+              handleType(String, null)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(2, <, >)
+            handleType(Map, null)
+            handleIdentifier(foo2, fieldDeclaration)
+            beginFieldInitializer(=)
+              handleRecoverableError(LiteralWithNew, new, new)
+              beginTypeArguments(<)
+                handleIdentifier(String, typeReference)
+                handleNoTypeArguments(,)
+                handleType(String, null)
+                handleIdentifier(List, typeReference)
+                beginTypeArguments(<)
+                  handleIdentifier(int, typeReference)
+                  handleNoTypeArguments(>)
+                  handleType(int, null)
+                endTypeArguments(1, <, >)
+                handleType(List, null)
+              endTypeArguments(2, <, >)
+              handleLiteralSetOrMap(0, {, null, }, false)
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields(;)
+            handleIdentifier(Map, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(String, typeReference)
+              handleNoTypeArguments(,)
+              handleType(String, null)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(2, <, >)
+            handleType(Map, null)
+            handleIdentifier(foo3, fieldDeclaration)
+            beginFieldInitializer(=)
+              handleRecoverableError(Message[LiteralWithClassAndNew, A map literal can't be prefixed by 'new Map'., Try removing 'new' and 'Map', {string: map, lexeme: Map}], new, Map)
+              handleNoTypeArguments({)
+              handleLiteralSetOrMap(0, {, null, }, false)
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields(;)
+            handleIdentifier(Map, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(String, typeReference)
+              handleNoTypeArguments(,)
+              handleType(String, null)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(2, <, >)
+            handleType(Map, null)
+            handleIdentifier(foo4, fieldDeclaration)
+            beginFieldInitializer(=)
+              beginNewExpression(new)
+                handleIdentifier(Map, constructorReference)
+                beginConstructorReference(Map)
+                  beginTypeArguments(<)
+                    handleIdentifier(String, typeReference)
+                    handleNoTypeArguments(,)
+                    handleType(String, null)
+                    handleIdentifier(List, typeReference)
+                    beginTypeArguments(<)
+                      handleIdentifier(int, typeReference)
+                      handleNoTypeArguments(>)
+                      handleType(int, null)
+                    endTypeArguments(1, <, >)
+                    handleType(List, null)
+                  endTypeArguments(2, <, >)
+                  handleNoConstructorReferenceContinuationAfterTypeArguments(()
+                endConstructorReference(Map, null, ()
+                beginArguments(()
+                endArguments(0, (, ))
+              endNewExpression(new)
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields(;)
+            handleIdentifier(Map, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(String, typeReference)
+              handleNoTypeArguments(,)
+              handleType(String, null)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(2, <, >)
+            handleType(Map, null)
+            handleIdentifier(foo5, fieldDeclaration)
+            beginFieldInitializer(=)
+              beginNewExpression(new)
+                handleIdentifier(Map, constructorReference)
+                beginConstructorReference(Map)
+                  handleNoTypeArguments(()
+                  handleNoConstructorReferenceContinuationAfterTypeArguments(()
+                endConstructorReference(Map, null, ()
+                beginArguments(()
+                endArguments(0, (, ))
+              endNewExpression(new)
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields(;)
+            handleIdentifier(Map, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(String, typeReference)
+              handleNoTypeArguments(,)
+              handleType(String, null)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(2, <, >)
+            handleType(Map, null)
+            handleIdentifier(foo6, fieldDeclaration)
+            beginFieldInitializer(=)
+              handleRecoverableError(Message[LiteralWithClassAndNew, A map literal can't be prefixed by 'new Map'., Try removing 'new' and 'Map', {string: map, lexeme: Map}], new, Map)
+              beginTypeArguments(<)
+                handleIdentifier(String, typeReference)
+                handleNoTypeArguments(,)
+                handleType(String, null)
+                handleIdentifier(List, typeReference)
+                beginTypeArguments(<)
+                  handleIdentifier(int, typeReference)
+                  handleNoTypeArguments(>)
+                  handleType(int, null)
+                endTypeArguments(1, <, >)
+                handleType(List, null)
+              endTypeArguments(2, <, >)
+              beginLiteralString("a")
+              endLiteralString(0, :)
+              handleLiteralNull(null)
+              handleLiteralMapEntry(:, })
+              handleLiteralSetOrMap(1, {, null, }, false)
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields(;)
+            handleIdentifier(Map, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(String, typeReference)
+              handleNoTypeArguments(,)
+              handleType(String, null)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(2, <, >)
+            handleType(Map, null)
+            handleIdentifier(foo7, fieldDeclaration)
+            beginFieldInitializer(=)
+              handleRecoverableError(Message[LiteralWithClassAndNew, A map literal can't be prefixed by 'new Map'., Try removing 'new' and 'Map', {string: map, lexeme: Map}], new, Map)
+              handleNoTypeArguments({)
+              beginLiteralString("a")
+              endLiteralString(0, :)
+              handleLiteralNull(null)
+              handleLiteralMapEntry(:, })
+              handleLiteralSetOrMap(1, {, null, }, false)
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields(;)
+            handleIdentifier(Map, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(String, typeReference)
+              handleNoTypeArguments(,)
+              handleType(String, null)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(2, <, >)
+            handleType(Map, null)
+            handleIdentifier(foo8, fieldDeclaration)
+            beginFieldInitializer(=)
+              handleRecoverableError(LiteralWithNew, new, new)
+              beginTypeArguments(<)
+                handleIdentifier(String, typeReference)
+                handleNoTypeArguments(,)
+                handleType(String, null)
+                handleIdentifier(List, typeReference)
+                beginTypeArguments(<)
+                  handleIdentifier(int, typeReference)
+                  handleNoTypeArguments(>)
+                  handleType(int, null)
+                endTypeArguments(1, <, >)
+                handleType(List, null)
+              endTypeArguments(2, <, >)
+              beginLiteralString("a")
+              endLiteralString(0, :)
+              handleLiteralNull(null)
+              handleLiteralMapEntry(:, })
+              handleLiteralSetOrMap(1, {, null, }, false)
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields(;)
+            handleIdentifier(Map, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(String, typeReference)
+              handleNoTypeArguments(,)
+              handleType(String, null)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(2, <, >)
+            handleType(Map, null)
+            handleIdentifier(foo9, fieldDeclaration)
+            beginFieldInitializer(=)
+              handleRecoverableError(LiteralWithNew, new, new)
+              handleNoTypeArguments({)
+              beginLiteralString("a")
+              endLiteralString(0, :)
+              handleLiteralNull(null)
+              handleLiteralMapEntry(:, })
+              handleLiteralSetOrMap(1, {, null, }, false)
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+      endClassOrMixinBody(DeclarationKind.Class, 9, {, })
+    endClassDeclaration(class, })
+  endTopLevelDeclaration()
+endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_45251_new.dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/issue_45251_new.dart.intertwined.expect
new file mode 100644
index 0000000..d3039be
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_45251_new.dart.intertwined.expect
@@ -0,0 +1,498 @@
+parseUnit(class)
+  skipErrorTokens(class)
+  listener: beginCompilationUnit(class)
+  syntheticPreviousToken(class)
+  parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+    parseMetadataStar()
+      listener: beginMetadataStar(class)
+      listener: endMetadataStar(0)
+    parseTopLevelKeywordDeclaration(, class, Instance of 'DirectiveContext')
+      parseClassDeclarationModifiers(, class)
+      parseClassOrNamedMixinApplication(null, class)
+        listener: beginClassOrNamedMixinApplicationPrelude(class)
+        ensureIdentifier(class, classOrMixinDeclaration)
+          listener: handleIdentifier(F, classOrMixinDeclaration)
+        listener: handleNoTypeVariables({)
+        listener: beginClassDeclaration(class, null, F)
+        parseClass(F, class, class, F)
+          parseClassHeaderOpt(F, class, class)
+            parseClassExtendsOpt(F)
+              listener: handleNoType(F)
+              listener: handleClassExtends(null, 1)
+            parseWithClauseOpt(F)
+              listener: handleClassNoWithClause()
+            parseClassOrMixinImplementsOpt(F)
+              listener: handleClassOrMixinImplements(null, 0)
+            listener: handleClassHeader(class, class, null)
+          parseClassOrMixinOrExtensionBody(F, DeclarationKind.Class, F)
+            listener: beginClassOrMixinBody(DeclarationKind.Class, {)
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl({, DeclarationKind.Class, F)
+              parseMetadataStar({)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields({, null, null, null, null, null, final, final, Instance of 'ComplexTypeInfo', foo1, DeclarationKind.Class, F, false)
+                listener: beginFields({)
+                ensureIdentifier(final, typeReference)
+                  listener: handleIdentifier(Map, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(String, typeReference)
+                listener: handleNoTypeArguments(,)
+                listener: handleType(String, null)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(2, <, >)
+                listener: handleType(Map, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo1, fieldDeclaration)
+                parseFieldInitializerOpt(foo1, foo1, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseNewExpression(=)
+                            listener: handleRecoverableError(Message[LiteralWithClassAndNew, A map literal can't be prefixed by 'new Map'., Try removing 'new' and 'Map', {string: map, lexeme: Map}], new, Map)
+                            parsePrimary(Map, expression)
+                              parseLiteralListSetMapOrFunction(Map, null)
+                                listener: beginTypeArguments(<)
+                                listener: handleIdentifier(String, typeReference)
+                                listener: handleNoTypeArguments(,)
+                                listener: handleType(String, null)
+                                listener: handleIdentifier(List, typeReference)
+                                listener: beginTypeArguments(<)
+                                listener: handleIdentifier(int, typeReference)
+                                listener: handleNoTypeArguments(>)
+                                listener: handleType(int, null)
+                                listener: endTypeArguments(1, <, >)
+                                listener: handleType(List, null)
+                                listener: endTypeArguments(2, <, >)
+                                parseLiteralSetOrMapSuffix(>, null)
+                                  listener: handleLiteralSetOrMap(0, {, null, }, false)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, F)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, final, final, Instance of 'ComplexTypeInfo', foo2, DeclarationKind.Class, F, false)
+                listener: beginFields(;)
+                ensureIdentifier(final, typeReference)
+                  listener: handleIdentifier(Map, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(String, typeReference)
+                listener: handleNoTypeArguments(,)
+                listener: handleType(String, null)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(2, <, >)
+                listener: handleType(Map, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo2, fieldDeclaration)
+                parseFieldInitializerOpt(foo2, foo2, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseNewExpression(=)
+                            reportRecoverableError(new, LiteralWithNew)
+                              listener: handleRecoverableError(LiteralWithNew, new, new)
+                            parsePrimary(new, expression)
+                              parseLiteralListSetMapOrFunction(new, null)
+                                listener: beginTypeArguments(<)
+                                listener: handleIdentifier(String, typeReference)
+                                listener: handleNoTypeArguments(,)
+                                listener: handleType(String, null)
+                                listener: handleIdentifier(List, typeReference)
+                                listener: beginTypeArguments(<)
+                                listener: handleIdentifier(int, typeReference)
+                                listener: handleNoTypeArguments(>)
+                                listener: handleType(int, null)
+                                listener: endTypeArguments(1, <, >)
+                                listener: handleType(List, null)
+                                listener: endTypeArguments(2, <, >)
+                                parseLiteralSetOrMapSuffix(>, null)
+                                  listener: handleLiteralSetOrMap(0, {, null, }, false)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, F)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, final, final, Instance of 'ComplexTypeInfo', foo3, DeclarationKind.Class, F, false)
+                listener: beginFields(;)
+                ensureIdentifier(final, typeReference)
+                  listener: handleIdentifier(Map, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(String, typeReference)
+                listener: handleNoTypeArguments(,)
+                listener: handleType(String, null)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(2, <, >)
+                listener: handleType(Map, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo3, fieldDeclaration)
+                parseFieldInitializerOpt(foo3, foo3, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseNewExpression(=)
+                            listener: handleRecoverableError(Message[LiteralWithClassAndNew, A map literal can't be prefixed by 'new Map'., Try removing 'new' and 'Map', {string: map, lexeme: Map}], new, Map)
+                            parsePrimary(Map, expression)
+                              listener: handleNoTypeArguments({)
+                              parseLiteralSetOrMapSuffix(Map, null)
+                                listener: handleLiteralSetOrMap(0, {, null, }, false)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, F)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, final, final, Instance of 'ComplexTypeInfo', foo4, DeclarationKind.Class, F, false)
+                listener: beginFields(;)
+                ensureIdentifier(final, typeReference)
+                  listener: handleIdentifier(Map, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(String, typeReference)
+                listener: handleNoTypeArguments(,)
+                listener: handleType(String, null)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(2, <, >)
+                listener: handleType(Map, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo4, fieldDeclaration)
+                parseFieldInitializerOpt(foo4, foo4, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseNewExpression(=)
+                            listener: beginNewExpression(new)
+                            parseConstructorReference(new, Instance of 'ComplexTypeParamOrArgInfo')
+                              ensureIdentifier(new, constructorReference)
+                                listener: handleIdentifier(Map, constructorReference)
+                              listener: beginConstructorReference(Map)
+                              parseQualifiedRestOpt(Map, constructorReferenceContinuation)
+                              listener: beginTypeArguments(<)
+                              listener: handleIdentifier(String, typeReference)
+                              listener: handleNoTypeArguments(,)
+                              listener: handleType(String, null)
+                              listener: handleIdentifier(List, typeReference)
+                              listener: beginTypeArguments(<)
+                              listener: handleIdentifier(int, typeReference)
+                              listener: handleNoTypeArguments(>)
+                              listener: handleType(int, null)
+                              listener: endTypeArguments(1, <, >)
+                              listener: handleType(List, null)
+                              listener: endTypeArguments(2, <, >)
+                              listener: handleNoConstructorReferenceContinuationAfterTypeArguments(()
+                              listener: endConstructorReference(Map, null, ()
+                            parseConstructorInvocationArguments(>)
+                              parseArgumentsRest(()
+                                listener: beginArguments(()
+                                listener: endArguments(0, (, ))
+                            listener: endNewExpression(new)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, F)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, final, final, Instance of 'ComplexTypeInfo', foo5, DeclarationKind.Class, F, false)
+                listener: beginFields(;)
+                ensureIdentifier(final, typeReference)
+                  listener: handleIdentifier(Map, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(String, typeReference)
+                listener: handleNoTypeArguments(,)
+                listener: handleType(String, null)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(2, <, >)
+                listener: handleType(Map, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo5, fieldDeclaration)
+                parseFieldInitializerOpt(foo5, foo5, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseNewExpression(=)
+                            listener: beginNewExpression(new)
+                            parseConstructorReference(new, Instance of 'NoTypeParamOrArg')
+                              ensureIdentifier(new, constructorReference)
+                                listener: handleIdentifier(Map, constructorReference)
+                              listener: beginConstructorReference(Map)
+                              parseQualifiedRestOpt(Map, constructorReferenceContinuation)
+                              listener: handleNoTypeArguments(()
+                              listener: handleNoConstructorReferenceContinuationAfterTypeArguments(()
+                              listener: endConstructorReference(Map, null, ()
+                            parseConstructorInvocationArguments(Map)
+                              parseArgumentsRest(()
+                                listener: beginArguments(()
+                                listener: endArguments(0, (, ))
+                            listener: endNewExpression(new)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, F)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, final, final, Instance of 'ComplexTypeInfo', foo6, DeclarationKind.Class, F, false)
+                listener: beginFields(;)
+                ensureIdentifier(final, typeReference)
+                  listener: handleIdentifier(Map, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(String, typeReference)
+                listener: handleNoTypeArguments(,)
+                listener: handleType(String, null)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(2, <, >)
+                listener: handleType(Map, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo6, fieldDeclaration)
+                parseFieldInitializerOpt(foo6, foo6, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseNewExpression(=)
+                            listener: handleRecoverableError(Message[LiteralWithClassAndNew, A map literal can't be prefixed by 'new Map'., Try removing 'new' and 'Map', {string: map, lexeme: Map}], new, Map)
+                            parsePrimary(Map, expression)
+                              parseLiteralListSetMapOrFunction(Map, null)
+                                listener: beginTypeArguments(<)
+                                listener: handleIdentifier(String, typeReference)
+                                listener: handleNoTypeArguments(,)
+                                listener: handleType(String, null)
+                                listener: handleIdentifier(List, typeReference)
+                                listener: beginTypeArguments(<)
+                                listener: handleIdentifier(int, typeReference)
+                                listener: handleNoTypeArguments(>)
+                                listener: handleType(int, null)
+                                listener: endTypeArguments(1, <, >)
+                                listener: handleType(List, null)
+                                listener: endTypeArguments(2, <, >)
+                                parseLiteralSetOrMapSuffix(>, null)
+                                  parseExpression({)
+                                    parsePrecedenceExpression({, 1, true)
+                                      parseUnaryExpression({, true)
+                                        parsePrimary({, expression)
+                                          parseLiteralString({)
+                                            parseSingleLiteralString({)
+                                              listener: beginLiteralString("a")
+                                              listener: endLiteralString(0, :)
+                                  parseExpression(:)
+                                    parsePrecedenceExpression(:, 1, true)
+                                      parseUnaryExpression(:, true)
+                                        parsePrimary(:, expression)
+                                          parseLiteralNull(:)
+                                            listener: handleLiteralNull(null)
+                                  listener: handleLiteralMapEntry(:, })
+                                  listener: handleLiteralSetOrMap(1, {, null, }, false)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, F)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, final, final, Instance of 'ComplexTypeInfo', foo7, DeclarationKind.Class, F, false)
+                listener: beginFields(;)
+                ensureIdentifier(final, typeReference)
+                  listener: handleIdentifier(Map, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(String, typeReference)
+                listener: handleNoTypeArguments(,)
+                listener: handleType(String, null)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(2, <, >)
+                listener: handleType(Map, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo7, fieldDeclaration)
+                parseFieldInitializerOpt(foo7, foo7, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseNewExpression(=)
+                            listener: handleRecoverableError(Message[LiteralWithClassAndNew, A map literal can't be prefixed by 'new Map'., Try removing 'new' and 'Map', {string: map, lexeme: Map}], new, Map)
+                            parsePrimary(Map, expression)
+                              listener: handleNoTypeArguments({)
+                              parseLiteralSetOrMapSuffix(Map, null)
+                                parseExpression({)
+                                  parsePrecedenceExpression({, 1, true)
+                                    parseUnaryExpression({, true)
+                                      parsePrimary({, expression)
+                                        parseLiteralString({)
+                                          parseSingleLiteralString({)
+                                            listener: beginLiteralString("a")
+                                            listener: endLiteralString(0, :)
+                                parseExpression(:)
+                                  parsePrecedenceExpression(:, 1, true)
+                                    parseUnaryExpression(:, true)
+                                      parsePrimary(:, expression)
+                                        parseLiteralNull(:)
+                                          listener: handleLiteralNull(null)
+                                listener: handleLiteralMapEntry(:, })
+                                listener: handleLiteralSetOrMap(1, {, null, }, false)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, F)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, final, final, Instance of 'ComplexTypeInfo', foo8, DeclarationKind.Class, F, false)
+                listener: beginFields(;)
+                ensureIdentifier(final, typeReference)
+                  listener: handleIdentifier(Map, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(String, typeReference)
+                listener: handleNoTypeArguments(,)
+                listener: handleType(String, null)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(2, <, >)
+                listener: handleType(Map, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo8, fieldDeclaration)
+                parseFieldInitializerOpt(foo8, foo8, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseNewExpression(=)
+                            reportRecoverableError(new, LiteralWithNew)
+                              listener: handleRecoverableError(LiteralWithNew, new, new)
+                            parsePrimary(new, expression)
+                              parseLiteralListSetMapOrFunction(new, null)
+                                listener: beginTypeArguments(<)
+                                listener: handleIdentifier(String, typeReference)
+                                listener: handleNoTypeArguments(,)
+                                listener: handleType(String, null)
+                                listener: handleIdentifier(List, typeReference)
+                                listener: beginTypeArguments(<)
+                                listener: handleIdentifier(int, typeReference)
+                                listener: handleNoTypeArguments(>)
+                                listener: handleType(int, null)
+                                listener: endTypeArguments(1, <, >)
+                                listener: handleType(List, null)
+                                listener: endTypeArguments(2, <, >)
+                                parseLiteralSetOrMapSuffix(>, null)
+                                  parseExpression({)
+                                    parsePrecedenceExpression({, 1, true)
+                                      parseUnaryExpression({, true)
+                                        parsePrimary({, expression)
+                                          parseLiteralString({)
+                                            parseSingleLiteralString({)
+                                              listener: beginLiteralString("a")
+                                              listener: endLiteralString(0, :)
+                                  parseExpression(:)
+                                    parsePrecedenceExpression(:, 1, true)
+                                      parseUnaryExpression(:, true)
+                                        parsePrimary(:, expression)
+                                          parseLiteralNull(:)
+                                            listener: handleLiteralNull(null)
+                                  listener: handleLiteralMapEntry(:, })
+                                  listener: handleLiteralSetOrMap(1, {, null, }, false)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, F)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, final, final, Instance of 'ComplexTypeInfo', foo9, DeclarationKind.Class, F, false)
+                listener: beginFields(;)
+                ensureIdentifier(final, typeReference)
+                  listener: handleIdentifier(Map, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(String, typeReference)
+                listener: handleNoTypeArguments(,)
+                listener: handleType(String, null)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(2, <, >)
+                listener: handleType(Map, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo9, fieldDeclaration)
+                parseFieldInitializerOpt(foo9, foo9, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseNewExpression(=)
+                            reportRecoverableError(new, LiteralWithNew)
+                              listener: handleRecoverableError(LiteralWithNew, new, new)
+                            parsePrimary(new, expression)
+                              listener: handleNoTypeArguments({)
+                              parseLiteralSetOrMapSuffix(new, null)
+                                parseExpression({)
+                                  parsePrecedenceExpression({, 1, true)
+                                    parseUnaryExpression({, true)
+                                      parsePrimary({, expression)
+                                        parseLiteralString({)
+                                          parseSingleLiteralString({)
+                                            listener: beginLiteralString("a")
+                                            listener: endLiteralString(0, :)
+                                parseExpression(:)
+                                  parsePrecedenceExpression(:, 1, true)
+                                    parseUnaryExpression(:, true)
+                                      parsePrimary(:, expression)
+                                        parseLiteralNull(:)
+                                          listener: handleLiteralNull(null)
+                                listener: handleLiteralMapEntry(:, })
+                                listener: handleLiteralSetOrMap(1, {, null, }, false)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, })
+            listener: endClassOrMixinBody(DeclarationKind.Class, 9, {, })
+          listener: endClassDeclaration(class, })
+  listener: endTopLevelDeclaration()
+  reportAllErrorTokens(class)
+  listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_45251_new.dart.parser.expect b/pkg/front_end/parser_testcases/error_recovery/issue_45251_new.dart.parser.expect
new file mode 100644
index 0000000..298d0ec
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_45251_new.dart.parser.expect
@@ -0,0 +1,59 @@
+NOTICE: Stream was rewritten by parser!
+
+class F {
+
+final Map<String, Undefined> foo1 = new Map<String, List<int>>{};
+
+
+final Map<String, Undefined> foo2 = new <String, List<int>>{};
+
+
+final Map<String, Undefined> foo3 = new Map{};
+
+
+final Map<String, Undefined> foo4 = new Map<String, List<int>>();
+
+
+final Map<String, Undefined> foo5 = new Map();
+
+
+final Map<String, Undefined> foo6 = new Map<String, List<int>>{"a": null};
+
+
+final Map<String, Undefined> foo7 = new Map{"a": null};
+
+
+final Map<String, Undefined> foo8 = new <String, List<int>>{"a": null};
+
+
+final Map<String, Undefined> foo9 = new {"a": null};
+}
+
+class[KeywordToken] F[StringToken] {[BeginToken]
+
+final[KeywordToken] Map[StringToken]<[BeginToken]String[StringToken],[SimpleToken] Undefined[StringToken]>[SimpleToken] foo1[StringToken] =[SimpleToken] new[KeywordToken] Map[StringToken]<[BeginToken]String[StringToken],[SimpleToken] List[StringToken]<[BeginToken]int[StringToken]>[SimpleToken]>[SimpleToken]{[BeginToken]}[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Map[StringToken]<[BeginToken]String[StringToken],[SimpleToken] Undefined[StringToken]>[SimpleToken] foo2[StringToken] =[SimpleToken] new[KeywordToken] <[BeginToken]String[StringToken],[SimpleToken] List[StringToken]<[BeginToken]int[StringToken]>[SimpleToken]>[SimpleToken]{[BeginToken]}[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Map[StringToken]<[BeginToken]String[StringToken],[SimpleToken] Undefined[StringToken]>[SimpleToken] foo3[StringToken] =[SimpleToken] new[KeywordToken] Map[StringToken]{[BeginToken]}[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Map[StringToken]<[BeginToken]String[StringToken],[SimpleToken] Undefined[StringToken]>[SimpleToken] foo4[StringToken] =[SimpleToken] new[KeywordToken] Map[StringToken]<[BeginToken]String[StringToken],[SimpleToken] List[StringToken]<[BeginToken]int[StringToken]>[SimpleToken]>[SimpleToken]([BeginToken])[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Map[StringToken]<[BeginToken]String[StringToken],[SimpleToken] Undefined[StringToken]>[SimpleToken] foo5[StringToken] =[SimpleToken] new[KeywordToken] Map[StringToken]([BeginToken])[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Map[StringToken]<[BeginToken]String[StringToken],[SimpleToken] Undefined[StringToken]>[SimpleToken] foo6[StringToken] =[SimpleToken] new[KeywordToken] Map[StringToken]<[BeginToken]String[StringToken],[SimpleToken] List[StringToken]<[BeginToken]int[StringToken]>[SimpleToken]>[SimpleToken]{[BeginToken]"a"[StringToken]:[SimpleToken] null[KeywordToken]}[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Map[StringToken]<[BeginToken]String[StringToken],[SimpleToken] Undefined[StringToken]>[SimpleToken] foo7[StringToken] =[SimpleToken] new[KeywordToken] Map[StringToken]{[BeginToken]"a"[StringToken]:[SimpleToken] null[KeywordToken]}[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Map[StringToken]<[BeginToken]String[StringToken],[SimpleToken] Undefined[StringToken]>[SimpleToken] foo8[StringToken] =[SimpleToken] new[KeywordToken] <[BeginToken]String[StringToken],[SimpleToken] List[StringToken]<[BeginToken]int[StringToken]>[SimpleToken]>[SimpleToken]{[BeginToken]"a"[StringToken]:[SimpleToken] null[KeywordToken]}[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Map[StringToken]<[BeginToken]String[StringToken],[SimpleToken] Undefined[StringToken]>[SimpleToken] foo9[StringToken] =[SimpleToken] new[KeywordToken] {[BeginToken]"a"[StringToken]:[SimpleToken] null[KeywordToken]}[SimpleToken];[SimpleToken]
+}[SimpleToken][SimpleToken]
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_45251_new.dart.scanner.expect b/pkg/front_end/parser_testcases/error_recovery/issue_45251_new.dart.scanner.expect
new file mode 100644
index 0000000..f04fbe0
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_45251_new.dart.scanner.expect
@@ -0,0 +1,57 @@
+class F {
+
+final Map<String, Undefined> foo1 = new Map<String, List<int>>{};
+
+
+final Map<String, Undefined> foo2 = new <String, List<int>>{};
+
+
+final Map<String, Undefined> foo3 = new Map{};
+
+
+final Map<String, Undefined> foo4 = new Map<String, List<int>>();
+
+
+final Map<String, Undefined> foo5 = new Map();
+
+
+final Map<String, Undefined> foo6 = new Map<String, List<int>>{"a": null};
+
+
+final Map<String, Undefined> foo7 = new Map{"a": null};
+
+
+final Map<String, Undefined> foo8 = new <String, List<int>>{"a": null};
+
+
+final Map<String, Undefined> foo9 = new {"a": null};
+}
+
+class[KeywordToken] F[StringToken] {[BeginToken]
+
+final[KeywordToken] Map[StringToken]<[BeginToken]String[StringToken],[SimpleToken] Undefined[StringToken]>[SimpleToken] foo1[StringToken] =[SimpleToken] new[KeywordToken] Map[StringToken]<[BeginToken]String[StringToken],[SimpleToken] List[StringToken]<[BeginToken]int[StringToken]>>[SimpleToken]{[BeginToken]}[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Map[StringToken]<[BeginToken]String[StringToken],[SimpleToken] Undefined[StringToken]>[SimpleToken] foo2[StringToken] =[SimpleToken] new[KeywordToken] <[BeginToken]String[StringToken],[SimpleToken] List[StringToken]<[BeginToken]int[StringToken]>>[SimpleToken]{[BeginToken]}[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Map[StringToken]<[BeginToken]String[StringToken],[SimpleToken] Undefined[StringToken]>[SimpleToken] foo3[StringToken] =[SimpleToken] new[KeywordToken] Map[StringToken]{[BeginToken]}[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Map[StringToken]<[BeginToken]String[StringToken],[SimpleToken] Undefined[StringToken]>[SimpleToken] foo4[StringToken] =[SimpleToken] new[KeywordToken] Map[StringToken]<[BeginToken]String[StringToken],[SimpleToken] List[StringToken]<[BeginToken]int[StringToken]>>[SimpleToken]([BeginToken])[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Map[StringToken]<[BeginToken]String[StringToken],[SimpleToken] Undefined[StringToken]>[SimpleToken] foo5[StringToken] =[SimpleToken] new[KeywordToken] Map[StringToken]([BeginToken])[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Map[StringToken]<[BeginToken]String[StringToken],[SimpleToken] Undefined[StringToken]>[SimpleToken] foo6[StringToken] =[SimpleToken] new[KeywordToken] Map[StringToken]<[BeginToken]String[StringToken],[SimpleToken] List[StringToken]<[BeginToken]int[StringToken]>>[SimpleToken]{[BeginToken]"a"[StringToken]:[SimpleToken] null[KeywordToken]}[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Map[StringToken]<[BeginToken]String[StringToken],[SimpleToken] Undefined[StringToken]>[SimpleToken] foo7[StringToken] =[SimpleToken] new[KeywordToken] Map[StringToken]{[BeginToken]"a"[StringToken]:[SimpleToken] null[KeywordToken]}[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Map[StringToken]<[BeginToken]String[StringToken],[SimpleToken] Undefined[StringToken]>[SimpleToken] foo8[StringToken] =[SimpleToken] new[KeywordToken] <[BeginToken]String[StringToken],[SimpleToken] List[StringToken]<[BeginToken]int[StringToken]>>[SimpleToken]{[BeginToken]"a"[StringToken]:[SimpleToken] null[KeywordToken]}[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Map[StringToken]<[BeginToken]String[StringToken],[SimpleToken] Undefined[StringToken]>[SimpleToken] foo9[StringToken] =[SimpleToken] new[KeywordToken] {[BeginToken]"a"[StringToken]:[SimpleToken] null[KeywordToken]}[SimpleToken];[SimpleToken]
+}[SimpleToken][SimpleToken]
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_45251_set.dart b/pkg/front_end/parser_testcases/error_recovery/issue_45251_set.dart
new file mode 100644
index 0000000..2824c09
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_45251_set.dart
@@ -0,0 +1,28 @@
+class F {
+  /* notice the braces at the end instead of parenthesis! */
+  final Set<Undefined> foo1 = Set<List<int>>{};
+
+  // variation #1: OK.
+  final Set<Undefined> foo2 = <List<int>>{};
+
+  // variation #2: Bad.
+  final Set<Undefined> foo3 = Set{};
+
+  // variation #3: OK.
+  final Set<Undefined> foo4 = Set<List<int>>();
+
+  // variation #4: OK.
+  final Set<Undefined> foo5 = Set();
+
+  // variation #5: Bad.
+  final Set<Undefined> foo6 = Set<List<int>>{null};
+
+  // variation #6: Bad.
+  final Set<Undefined> foo7 = Set{null};
+
+  // variation #7: OK.
+  final Set<Undefined> foo8 = <List<int>>{null};
+
+  // variation #8: OK.
+  final Set<Undefined> foo9 = {null};
+}
\ No newline at end of file
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_45251_set.dart.expect b/pkg/front_end/parser_testcases/error_recovery/issue_45251_set.dart.expect
new file mode 100644
index 0000000..e1d57ca
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_45251_set.dart.expect
@@ -0,0 +1,251 @@
+Problems reported:
+
+parser/error_recovery/issue_45251_set:3:31: A set literal can't be prefixed by 'Set'.
+  final Set<Undefined> foo1 = Set<List<int>>{};
+                              ^^^
+
+parser/error_recovery/issue_45251_set:9:31: A set literal can't be prefixed by 'Set'.
+  final Set<Undefined> foo3 = Set{};
+                              ^^^
+
+parser/error_recovery/issue_45251_set:18:31: A set literal can't be prefixed by 'Set'.
+  final Set<Undefined> foo6 = Set<List<int>>{null};
+                              ^^^
+
+parser/error_recovery/issue_45251_set:21:31: A set literal can't be prefixed by 'Set'.
+  final Set<Undefined> foo7 = Set{null};
+                              ^^^
+
+beginCompilationUnit(class)
+  beginMetadataStar(class)
+  endMetadataStar(0)
+  beginClassOrNamedMixinApplicationPrelude(class)
+    handleIdentifier(F, classOrMixinDeclaration)
+    handleNoTypeVariables({)
+    beginClassDeclaration(class, null, F)
+      handleNoType(F)
+      handleClassExtends(null, 1)
+      handleClassNoWithClause()
+      handleClassOrMixinImplements(null, 0)
+      handleClassHeader(class, class, null)
+      beginClassOrMixinBody(DeclarationKind.Class, {)
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields({)
+            handleIdentifier(Set, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(1, <, >)
+            handleType(Set, null)
+            handleIdentifier(foo1, fieldDeclaration)
+            beginFieldInitializer(=)
+              handleRecoverableError(Message[LiteralWithClass, A set literal can't be prefixed by 'Set'., Try removing 'Set', {string: set, lexeme: Set}], Set, Set)
+              beginTypeArguments(<)
+                handleIdentifier(List, typeReference)
+                beginTypeArguments(<)
+                  handleIdentifier(int, typeReference)
+                  handleNoTypeArguments(>)
+                  handleType(int, null)
+                endTypeArguments(1, <, >)
+                handleType(List, null)
+              endTypeArguments(1, <, >)
+              handleLiteralSetOrMap(0, {, null, }, false)
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields(;)
+            handleIdentifier(Set, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(1, <, >)
+            handleType(Set, null)
+            handleIdentifier(foo2, fieldDeclaration)
+            beginFieldInitializer(=)
+              beginTypeArguments(<)
+                handleIdentifier(List, typeReference)
+                beginTypeArguments(<)
+                  handleIdentifier(int, typeReference)
+                  handleNoTypeArguments(>)
+                  handleType(int, null)
+                endTypeArguments(1, <, >)
+                handleType(List, null)
+              endTypeArguments(1, <, >)
+              handleLiteralSetOrMap(0, {, null, }, false)
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields(;)
+            handleIdentifier(Set, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(1, <, >)
+            handleType(Set, null)
+            handleIdentifier(foo3, fieldDeclaration)
+            beginFieldInitializer(=)
+              handleRecoverableError(Message[LiteralWithClass, A set literal can't be prefixed by 'Set'., Try removing 'Set', {string: set, lexeme: Set}], Set, Set)
+              handleNoTypeArguments({)
+              handleLiteralSetOrMap(0, {, null, }, false)
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields(;)
+            handleIdentifier(Set, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(1, <, >)
+            handleType(Set, null)
+            handleIdentifier(foo4, fieldDeclaration)
+            beginFieldInitializer(=)
+              handleIdentifier(Set, expression)
+              beginTypeArguments(<)
+                handleIdentifier(List, typeReference)
+                beginTypeArguments(<)
+                  handleIdentifier(int, typeReference)
+                  handleNoTypeArguments(>)
+                  handleType(int, null)
+                endTypeArguments(1, <, >)
+                handleType(List, null)
+              endTypeArguments(1, <, >)
+              beginArguments(()
+              endArguments(0, (, ))
+              handleSend(Set, ;)
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields(;)
+            handleIdentifier(Set, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(1, <, >)
+            handleType(Set, null)
+            handleIdentifier(foo5, fieldDeclaration)
+            beginFieldInitializer(=)
+              handleIdentifier(Set, expression)
+              handleNoTypeArguments(()
+              beginArguments(()
+              endArguments(0, (, ))
+              handleSend(Set, ;)
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields(;)
+            handleIdentifier(Set, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(1, <, >)
+            handleType(Set, null)
+            handleIdentifier(foo6, fieldDeclaration)
+            beginFieldInitializer(=)
+              handleRecoverableError(Message[LiteralWithClass, A set literal can't be prefixed by 'Set'., Try removing 'Set', {string: set, lexeme: Set}], Set, Set)
+              beginTypeArguments(<)
+                handleIdentifier(List, typeReference)
+                beginTypeArguments(<)
+                  handleIdentifier(int, typeReference)
+                  handleNoTypeArguments(>)
+                  handleType(int, null)
+                endTypeArguments(1, <, >)
+                handleType(List, null)
+              endTypeArguments(1, <, >)
+              handleLiteralNull(null)
+              handleLiteralSetOrMap(1, {, null, }, true)
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields(;)
+            handleIdentifier(Set, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(1, <, >)
+            handleType(Set, null)
+            handleIdentifier(foo7, fieldDeclaration)
+            beginFieldInitializer(=)
+              handleRecoverableError(Message[LiteralWithClass, A set literal can't be prefixed by 'Set'., Try removing 'Set', {string: set, lexeme: Set}], Set, Set)
+              handleNoTypeArguments({)
+              handleLiteralNull(null)
+              handleLiteralSetOrMap(1, {, null, }, true)
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields(;)
+            handleIdentifier(Set, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(1, <, >)
+            handleType(Set, null)
+            handleIdentifier(foo8, fieldDeclaration)
+            beginFieldInitializer(=)
+              beginTypeArguments(<)
+                handleIdentifier(List, typeReference)
+                beginTypeArguments(<)
+                  handleIdentifier(int, typeReference)
+                  handleNoTypeArguments(>)
+                  handleType(int, null)
+                endTypeArguments(1, <, >)
+                handleType(List, null)
+              endTypeArguments(1, <, >)
+              handleLiteralNull(null)
+              handleLiteralSetOrMap(1, {, null, }, true)
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields(;)
+            handleIdentifier(Set, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(1, <, >)
+            handleType(Set, null)
+            handleIdentifier(foo9, fieldDeclaration)
+            beginFieldInitializer(=)
+              handleNoTypeArguments({)
+              handleLiteralNull(null)
+              handleLiteralSetOrMap(1, {, null, }, true)
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+      endClassOrMixinBody(DeclarationKind.Class, 9, {, })
+    endClassDeclaration(class, })
+  endTopLevelDeclaration()
+endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_45251_set.dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/issue_45251_set.dart.intertwined.expect
new file mode 100644
index 0000000..9fad6f6
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_45251_set.dart.intertwined.expect
@@ -0,0 +1,401 @@
+parseUnit(class)
+  skipErrorTokens(class)
+  listener: beginCompilationUnit(class)
+  syntheticPreviousToken(class)
+  parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+    parseMetadataStar()
+      listener: beginMetadataStar(class)
+      listener: endMetadataStar(0)
+    parseTopLevelKeywordDeclaration(, class, Instance of 'DirectiveContext')
+      parseClassDeclarationModifiers(, class)
+      parseClassOrNamedMixinApplication(null, class)
+        listener: beginClassOrNamedMixinApplicationPrelude(class)
+        ensureIdentifier(class, classOrMixinDeclaration)
+          listener: handleIdentifier(F, classOrMixinDeclaration)
+        listener: handleNoTypeVariables({)
+        listener: beginClassDeclaration(class, null, F)
+        parseClass(F, class, class, F)
+          parseClassHeaderOpt(F, class, class)
+            parseClassExtendsOpt(F)
+              listener: handleNoType(F)
+              listener: handleClassExtends(null, 1)
+            parseWithClauseOpt(F)
+              listener: handleClassNoWithClause()
+            parseClassOrMixinImplementsOpt(F)
+              listener: handleClassOrMixinImplements(null, 0)
+            listener: handleClassHeader(class, class, null)
+          parseClassOrMixinOrExtensionBody(F, DeclarationKind.Class, F)
+            listener: beginClassOrMixinBody(DeclarationKind.Class, {)
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl({, DeclarationKind.Class, F)
+              parseMetadataStar({)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields({, null, null, null, null, null, final, final, Instance of 'SimpleTypeWith1Argument', foo1, DeclarationKind.Class, F, false)
+                listener: beginFields({)
+                listener: handleIdentifier(Set, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(1, <, >)
+                listener: handleType(Set, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo1, fieldDeclaration)
+                parseFieldInitializerOpt(foo1, foo1, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseSendOrFunctionLiteral(=, expression)
+                            parseSend(=, expression)
+                              reportRecoverableError(Set, Message[LiteralWithClass, A set literal can't be prefixed by 'Set'., Try removing 'Set', {string: set, lexeme: Set}])
+                                listener: handleRecoverableError(Message[LiteralWithClass, A set literal can't be prefixed by 'Set'., Try removing 'Set', {string: set, lexeme: Set}], Set, Set)
+                              parsePrimary(Set, expression)
+                                parseLiteralListSetMapOrFunction(Set, null)
+                                  listener: beginTypeArguments(<)
+                                  listener: handleIdentifier(List, typeReference)
+                                  listener: beginTypeArguments(<)
+                                  listener: handleIdentifier(int, typeReference)
+                                  listener: handleNoTypeArguments(>)
+                                  listener: handleType(int, null)
+                                  listener: endTypeArguments(1, <, >)
+                                  listener: handleType(List, null)
+                                  listener: endTypeArguments(1, <, >)
+                                  parseLiteralSetOrMapSuffix(>, null)
+                                    listener: handleLiteralSetOrMap(0, {, null, }, false)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, F)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, final, final, Instance of 'SimpleTypeWith1Argument', foo2, DeclarationKind.Class, F, false)
+                listener: beginFields(;)
+                listener: handleIdentifier(Set, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(1, <, >)
+                listener: handleType(Set, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo2, fieldDeclaration)
+                parseFieldInitializerOpt(foo2, foo2, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseLiteralListSetMapOrFunction(=, null)
+                            listener: beginTypeArguments(<)
+                            listener: handleIdentifier(List, typeReference)
+                            listener: beginTypeArguments(<)
+                            listener: handleIdentifier(int, typeReference)
+                            listener: handleNoTypeArguments(>)
+                            listener: handleType(int, null)
+                            listener: endTypeArguments(1, <, >)
+                            listener: handleType(List, null)
+                            listener: endTypeArguments(1, <, >)
+                            parseLiteralSetOrMapSuffix(>, null)
+                              listener: handleLiteralSetOrMap(0, {, null, }, false)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, F)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, final, final, Instance of 'SimpleTypeWith1Argument', foo3, DeclarationKind.Class, F, false)
+                listener: beginFields(;)
+                listener: handleIdentifier(Set, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(1, <, >)
+                listener: handleType(Set, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo3, fieldDeclaration)
+                parseFieldInitializerOpt(foo3, foo3, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseSendOrFunctionLiteral(=, expression)
+                            parseSend(=, expression)
+                              reportRecoverableError(Set, Message[LiteralWithClass, A set literal can't be prefixed by 'Set'., Try removing 'Set', {string: set, lexeme: Set}])
+                                listener: handleRecoverableError(Message[LiteralWithClass, A set literal can't be prefixed by 'Set'., Try removing 'Set', {string: set, lexeme: Set}], Set, Set)
+                              parsePrimary(Set, expression)
+                                listener: handleNoTypeArguments({)
+                                parseLiteralSetOrMapSuffix(Set, null)
+                                  listener: handleLiteralSetOrMap(0, {, null, }, false)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, F)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, final, final, Instance of 'SimpleTypeWith1Argument', foo4, DeclarationKind.Class, F, false)
+                listener: beginFields(;)
+                listener: handleIdentifier(Set, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(1, <, >)
+                listener: handleType(Set, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo4, fieldDeclaration)
+                parseFieldInitializerOpt(foo4, foo4, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseSendOrFunctionLiteral(=, expression)
+                            looksLikeFunctionBody(;)
+                            parseSend(=, expression)
+                              ensureIdentifier(=, expression)
+                                listener: handleIdentifier(Set, expression)
+                              listener: beginTypeArguments(<)
+                              listener: handleIdentifier(List, typeReference)
+                              listener: beginTypeArguments(<)
+                              listener: handleIdentifier(int, typeReference)
+                              listener: handleNoTypeArguments(>)
+                              listener: handleType(int, null)
+                              listener: endTypeArguments(1, <, >)
+                              listener: handleType(List, null)
+                              listener: endTypeArguments(1, <, >)
+                              parseArgumentsOpt(>)
+                                parseArguments(>)
+                                  parseArgumentsRest(()
+                                    listener: beginArguments(()
+                                    listener: endArguments(0, (, ))
+                              listener: handleSend(Set, ;)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, F)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, final, final, Instance of 'SimpleTypeWith1Argument', foo5, DeclarationKind.Class, F, false)
+                listener: beginFields(;)
+                listener: handleIdentifier(Set, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(1, <, >)
+                listener: handleType(Set, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo5, fieldDeclaration)
+                parseFieldInitializerOpt(foo5, foo5, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseSendOrFunctionLiteral(=, expression)
+                            looksLikeFunctionBody(;)
+                            parseSend(=, expression)
+                              ensureIdentifier(=, expression)
+                                listener: handleIdentifier(Set, expression)
+                              listener: handleNoTypeArguments(()
+                              parseArgumentsOpt(Set)
+                                parseArguments(Set)
+                                  parseArgumentsRest(()
+                                    listener: beginArguments(()
+                                    listener: endArguments(0, (, ))
+                              listener: handleSend(Set, ;)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, F)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, final, final, Instance of 'SimpleTypeWith1Argument', foo6, DeclarationKind.Class, F, false)
+                listener: beginFields(;)
+                listener: handleIdentifier(Set, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(1, <, >)
+                listener: handleType(Set, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo6, fieldDeclaration)
+                parseFieldInitializerOpt(foo6, foo6, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseSendOrFunctionLiteral(=, expression)
+                            parseSend(=, expression)
+                              reportRecoverableError(Set, Message[LiteralWithClass, A set literal can't be prefixed by 'Set'., Try removing 'Set', {string: set, lexeme: Set}])
+                                listener: handleRecoverableError(Message[LiteralWithClass, A set literal can't be prefixed by 'Set'., Try removing 'Set', {string: set, lexeme: Set}], Set, Set)
+                              parsePrimary(Set, expression)
+                                parseLiteralListSetMapOrFunction(Set, null)
+                                  listener: beginTypeArguments(<)
+                                  listener: handleIdentifier(List, typeReference)
+                                  listener: beginTypeArguments(<)
+                                  listener: handleIdentifier(int, typeReference)
+                                  listener: handleNoTypeArguments(>)
+                                  listener: handleType(int, null)
+                                  listener: endTypeArguments(1, <, >)
+                                  listener: handleType(List, null)
+                                  listener: endTypeArguments(1, <, >)
+                                  parseLiteralSetOrMapSuffix(>, null)
+                                    parseExpression({)
+                                      parsePrecedenceExpression({, 1, true)
+                                        parseUnaryExpression({, true)
+                                          parsePrimary({, expression)
+                                            parseLiteralNull({)
+                                              listener: handleLiteralNull(null)
+                                    listener: handleLiteralSetOrMap(1, {, null, }, true)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, F)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, final, final, Instance of 'SimpleTypeWith1Argument', foo7, DeclarationKind.Class, F, false)
+                listener: beginFields(;)
+                listener: handleIdentifier(Set, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(1, <, >)
+                listener: handleType(Set, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo7, fieldDeclaration)
+                parseFieldInitializerOpt(foo7, foo7, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseSendOrFunctionLiteral(=, expression)
+                            parseSend(=, expression)
+                              reportRecoverableError(Set, Message[LiteralWithClass, A set literal can't be prefixed by 'Set'., Try removing 'Set', {string: set, lexeme: Set}])
+                                listener: handleRecoverableError(Message[LiteralWithClass, A set literal can't be prefixed by 'Set'., Try removing 'Set', {string: set, lexeme: Set}], Set, Set)
+                              parsePrimary(Set, expression)
+                                listener: handleNoTypeArguments({)
+                                parseLiteralSetOrMapSuffix(Set, null)
+                                  parseExpression({)
+                                    parsePrecedenceExpression({, 1, true)
+                                      parseUnaryExpression({, true)
+                                        parsePrimary({, expression)
+                                          parseLiteralNull({)
+                                            listener: handleLiteralNull(null)
+                                  listener: handleLiteralSetOrMap(1, {, null, }, true)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, F)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, final, final, Instance of 'SimpleTypeWith1Argument', foo8, DeclarationKind.Class, F, false)
+                listener: beginFields(;)
+                listener: handleIdentifier(Set, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(1, <, >)
+                listener: handleType(Set, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo8, fieldDeclaration)
+                parseFieldInitializerOpt(foo8, foo8, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseLiteralListSetMapOrFunction(=, null)
+                            listener: beginTypeArguments(<)
+                            listener: handleIdentifier(List, typeReference)
+                            listener: beginTypeArguments(<)
+                            listener: handleIdentifier(int, typeReference)
+                            listener: handleNoTypeArguments(>)
+                            listener: handleType(int, null)
+                            listener: endTypeArguments(1, <, >)
+                            listener: handleType(List, null)
+                            listener: endTypeArguments(1, <, >)
+                            parseLiteralSetOrMapSuffix(>, null)
+                              parseExpression({)
+                                parsePrecedenceExpression({, 1, true)
+                                  parseUnaryExpression({, true)
+                                    parsePrimary({, expression)
+                                      parseLiteralNull({)
+                                        listener: handleLiteralNull(null)
+                              listener: handleLiteralSetOrMap(1, {, null, }, true)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, F)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, final, final, Instance of 'SimpleTypeWith1Argument', foo9, DeclarationKind.Class, F, false)
+                listener: beginFields(;)
+                listener: handleIdentifier(Set, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(1, <, >)
+                listener: handleType(Set, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo9, fieldDeclaration)
+                parseFieldInitializerOpt(foo9, foo9, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          listener: handleNoTypeArguments({)
+                          parseLiteralSetOrMapSuffix(=, null)
+                            parseExpression({)
+                              parsePrecedenceExpression({, 1, true)
+                                parseUnaryExpression({, true)
+                                  parsePrimary({, expression)
+                                    parseLiteralNull({)
+                                      listener: handleLiteralNull(null)
+                            listener: handleLiteralSetOrMap(1, {, null, }, true)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, })
+            listener: endClassOrMixinBody(DeclarationKind.Class, 9, {, })
+          listener: endClassDeclaration(class, })
+  listener: endTopLevelDeclaration()
+  reportAllErrorTokens(class)
+  listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_45251_set.dart.parser.expect b/pkg/front_end/parser_testcases/error_recovery/issue_45251_set.dart.parser.expect
new file mode 100644
index 0000000..a8976df
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_45251_set.dart.parser.expect
@@ -0,0 +1,59 @@
+NOTICE: Stream was rewritten by parser!
+
+class F {
+
+final Set<Undefined> foo1 = Set<List<int>>{};
+
+
+final Set<Undefined> foo2 = <List<int>>{};
+
+
+final Set<Undefined> foo3 = Set{};
+
+
+final Set<Undefined> foo4 = Set<List<int>>();
+
+
+final Set<Undefined> foo5 = Set();
+
+
+final Set<Undefined> foo6 = Set<List<int>>{null};
+
+
+final Set<Undefined> foo7 = Set{null};
+
+
+final Set<Undefined> foo8 = <List<int>>{null};
+
+
+final Set<Undefined> foo9 = {null};
+}
+
+class[KeywordToken] F[StringToken] {[BeginToken]
+
+final[KeywordToken] Set[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo1[StringToken] =[SimpleToken] Set[StringToken]<[BeginToken]List[StringToken]<[BeginToken]int[StringToken]>[SimpleToken]>[SimpleToken]{[BeginToken]}[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Set[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo2[StringToken] =[SimpleToken] <[BeginToken]List[StringToken]<[BeginToken]int[StringToken]>[SimpleToken]>[SimpleToken]{[BeginToken]}[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Set[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo3[StringToken] =[SimpleToken] Set[StringToken]{[BeginToken]}[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Set[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo4[StringToken] =[SimpleToken] Set[StringToken]<[BeginToken]List[StringToken]<[BeginToken]int[StringToken]>[SimpleToken]>[SimpleToken]([BeginToken])[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Set[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo5[StringToken] =[SimpleToken] Set[StringToken]([BeginToken])[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Set[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo6[StringToken] =[SimpleToken] Set[StringToken]<[BeginToken]List[StringToken]<[BeginToken]int[StringToken]>[SimpleToken]>[SimpleToken]{[BeginToken]null[KeywordToken]}[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Set[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo7[StringToken] =[SimpleToken] Set[StringToken]{[BeginToken]null[KeywordToken]}[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Set[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo8[StringToken] =[SimpleToken] <[BeginToken]List[StringToken]<[BeginToken]int[StringToken]>[SimpleToken]>[SimpleToken]{[BeginToken]null[KeywordToken]}[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Set[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo9[StringToken] =[SimpleToken] {[BeginToken]null[KeywordToken]}[SimpleToken];[SimpleToken]
+}[SimpleToken][SimpleToken]
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_45251_set.dart.scanner.expect b/pkg/front_end/parser_testcases/error_recovery/issue_45251_set.dart.scanner.expect
new file mode 100644
index 0000000..aac5540
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_45251_set.dart.scanner.expect
@@ -0,0 +1,57 @@
+class F {
+
+final Set<Undefined> foo1 = Set<List<int>>{};
+
+
+final Set<Undefined> foo2 = <List<int>>{};
+
+
+final Set<Undefined> foo3 = Set{};
+
+
+final Set<Undefined> foo4 = Set<List<int>>();
+
+
+final Set<Undefined> foo5 = Set();
+
+
+final Set<Undefined> foo6 = Set<List<int>>{null};
+
+
+final Set<Undefined> foo7 = Set{null};
+
+
+final Set<Undefined> foo8 = <List<int>>{null};
+
+
+final Set<Undefined> foo9 = {null};
+}
+
+class[KeywordToken] F[StringToken] {[BeginToken]
+
+final[KeywordToken] Set[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo1[StringToken] =[SimpleToken] Set[StringToken]<[BeginToken]List[StringToken]<[BeginToken]int[StringToken]>>[SimpleToken]{[BeginToken]}[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Set[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo2[StringToken] =[SimpleToken] <[BeginToken]List[StringToken]<[BeginToken]int[StringToken]>>[SimpleToken]{[BeginToken]}[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Set[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo3[StringToken] =[SimpleToken] Set[StringToken]{[BeginToken]}[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Set[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo4[StringToken] =[SimpleToken] Set[StringToken]<[BeginToken]List[StringToken]<[BeginToken]int[StringToken]>>[SimpleToken]([BeginToken])[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Set[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo5[StringToken] =[SimpleToken] Set[StringToken]([BeginToken])[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Set[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo6[StringToken] =[SimpleToken] Set[StringToken]<[BeginToken]List[StringToken]<[BeginToken]int[StringToken]>>[SimpleToken]{[BeginToken]null[KeywordToken]}[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Set[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo7[StringToken] =[SimpleToken] Set[StringToken]{[BeginToken]null[KeywordToken]}[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Set[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo8[StringToken] =[SimpleToken] <[BeginToken]List[StringToken]<[BeginToken]int[StringToken]>>[SimpleToken]{[BeginToken]null[KeywordToken]}[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Set[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo9[StringToken] =[SimpleToken] {[BeginToken]null[KeywordToken]}[SimpleToken];[SimpleToken]
+}[SimpleToken][SimpleToken]
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_45251_set_const.dart b/pkg/front_end/parser_testcases/error_recovery/issue_45251_set_const.dart
new file mode 100644
index 0000000..58f00b2
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_45251_set_const.dart
@@ -0,0 +1,28 @@
+class F {
+  /* notice the braces at the end instead of parenthesis! */
+  final Set<Undefined> foo1 = const Set<List<int>>{};
+
+  // variation #1: OK.
+  final Set<Undefined> foo2 = const <List<int>>{};
+
+  // variation #2: Bad.
+  final Set<Undefined> foo3 = const Set{};
+
+  // variation #3: OK.
+  final Set<Undefined> foo4 = const Set<List<int>>();
+
+  // variation #4: OK.
+  final Set<Undefined> foo5 = const Set();
+
+  // variation #5: Bad.
+  final Set<Undefined> foo6 = const Set<List<int>>{null};
+
+  // variation #6: Bad.
+  final Set<Undefined> foo7 = const Set{null};
+
+  // variation #7: OK.
+  final Set<Undefined> foo8 = const <List<int>>{null};
+
+  // variation #8: OK.
+  final Set<Undefined> foo9 = const {null};
+}
\ No newline at end of file
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_45251_set_const.dart.expect b/pkg/front_end/parser_testcases/error_recovery/issue_45251_set_const.dart.expect
new file mode 100644
index 0000000..7d01b7d5
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_45251_set_const.dart.expect
@@ -0,0 +1,273 @@
+Problems reported:
+
+parser/error_recovery/issue_45251_set_const:3:37: A set literal can't be prefixed by 'Set'.
+  final Set<Undefined> foo1 = const Set<List<int>>{};
+                                    ^^^
+
+parser/error_recovery/issue_45251_set_const:9:37: A set literal can't be prefixed by 'Set'.
+  final Set<Undefined> foo3 = const Set{};
+                                    ^^^
+
+parser/error_recovery/issue_45251_set_const:18:37: A set literal can't be prefixed by 'Set'.
+  final Set<Undefined> foo6 = const Set<List<int>>{null};
+                                    ^^^
+
+parser/error_recovery/issue_45251_set_const:21:37: A set literal can't be prefixed by 'Set'.
+  final Set<Undefined> foo7 = const Set{null};
+                                    ^^^
+
+beginCompilationUnit(class)
+  beginMetadataStar(class)
+  endMetadataStar(0)
+  beginClassOrNamedMixinApplicationPrelude(class)
+    handleIdentifier(F, classOrMixinDeclaration)
+    handleNoTypeVariables({)
+    beginClassDeclaration(class, null, F)
+      handleNoType(F)
+      handleClassExtends(null, 1)
+      handleClassNoWithClause()
+      handleClassOrMixinImplements(null, 0)
+      handleClassHeader(class, class, null)
+      beginClassOrMixinBody(DeclarationKind.Class, {)
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields({)
+            handleIdentifier(Set, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(1, <, >)
+            handleType(Set, null)
+            handleIdentifier(foo1, fieldDeclaration)
+            beginFieldInitializer(=)
+              handleRecoverableError(Message[LiteralWithClass, A set literal can't be prefixed by 'Set'., Try removing 'Set', {string: set, lexeme: Set}], Set, Set)
+              beginConstLiteral(<)
+                beginTypeArguments(<)
+                  handleIdentifier(List, typeReference)
+                  beginTypeArguments(<)
+                    handleIdentifier(int, typeReference)
+                    handleNoTypeArguments(>)
+                    handleType(int, null)
+                  endTypeArguments(1, <, >)
+                  handleType(List, null)
+                endTypeArguments(1, <, >)
+                handleLiteralSetOrMap(0, {, const, }, false)
+              endConstLiteral(;)
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields(;)
+            handleIdentifier(Set, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(1, <, >)
+            handleType(Set, null)
+            handleIdentifier(foo2, fieldDeclaration)
+            beginFieldInitializer(=)
+              beginConstLiteral(<)
+                beginTypeArguments(<)
+                  handleIdentifier(List, typeReference)
+                  beginTypeArguments(<)
+                    handleIdentifier(int, typeReference)
+                    handleNoTypeArguments(>)
+                    handleType(int, null)
+                  endTypeArguments(1, <, >)
+                  handleType(List, null)
+                endTypeArguments(1, <, >)
+                handleLiteralSetOrMap(0, {, const, }, false)
+              endConstLiteral(;)
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields(;)
+            handleIdentifier(Set, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(1, <, >)
+            handleType(Set, null)
+            handleIdentifier(foo3, fieldDeclaration)
+            beginFieldInitializer(=)
+              handleRecoverableError(Message[LiteralWithClass, A set literal can't be prefixed by 'Set'., Try removing 'Set', {string: set, lexeme: Set}], Set, Set)
+              beginConstLiteral({)
+                handleNoTypeArguments({)
+                handleLiteralSetOrMap(0, {, const, }, false)
+              endConstLiteral(;)
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields(;)
+            handleIdentifier(Set, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(1, <, >)
+            handleType(Set, null)
+            handleIdentifier(foo4, fieldDeclaration)
+            beginFieldInitializer(=)
+              beginConstExpression(const)
+                handleIdentifier(Set, constructorReference)
+                beginConstructorReference(Set)
+                  beginTypeArguments(<)
+                    handleIdentifier(List, typeReference)
+                    beginTypeArguments(<)
+                      handleIdentifier(int, typeReference)
+                      handleNoTypeArguments(>)
+                      handleType(int, null)
+                    endTypeArguments(1, <, >)
+                    handleType(List, null)
+                  endTypeArguments(1, <, >)
+                  handleNoConstructorReferenceContinuationAfterTypeArguments(()
+                endConstructorReference(Set, null, ()
+                beginArguments(()
+                endArguments(0, (, ))
+              endConstExpression(const)
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields(;)
+            handleIdentifier(Set, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(1, <, >)
+            handleType(Set, null)
+            handleIdentifier(foo5, fieldDeclaration)
+            beginFieldInitializer(=)
+              beginConstExpression(const)
+                handleIdentifier(Set, constructorReference)
+                beginConstructorReference(Set)
+                  handleNoTypeArguments(()
+                  handleNoConstructorReferenceContinuationAfterTypeArguments(()
+                endConstructorReference(Set, null, ()
+                beginArguments(()
+                endArguments(0, (, ))
+              endConstExpression(const)
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields(;)
+            handleIdentifier(Set, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(1, <, >)
+            handleType(Set, null)
+            handleIdentifier(foo6, fieldDeclaration)
+            beginFieldInitializer(=)
+              handleRecoverableError(Message[LiteralWithClass, A set literal can't be prefixed by 'Set'., Try removing 'Set', {string: set, lexeme: Set}], Set, Set)
+              beginConstLiteral(<)
+                beginTypeArguments(<)
+                  handleIdentifier(List, typeReference)
+                  beginTypeArguments(<)
+                    handleIdentifier(int, typeReference)
+                    handleNoTypeArguments(>)
+                    handleType(int, null)
+                  endTypeArguments(1, <, >)
+                  handleType(List, null)
+                endTypeArguments(1, <, >)
+                handleLiteralNull(null)
+                handleLiteralSetOrMap(1, {, const, }, true)
+              endConstLiteral(;)
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields(;)
+            handleIdentifier(Set, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(1, <, >)
+            handleType(Set, null)
+            handleIdentifier(foo7, fieldDeclaration)
+            beginFieldInitializer(=)
+              handleRecoverableError(Message[LiteralWithClass, A set literal can't be prefixed by 'Set'., Try removing 'Set', {string: set, lexeme: Set}], Set, Set)
+              beginConstLiteral({)
+                handleNoTypeArguments({)
+                handleLiteralNull(null)
+                handleLiteralSetOrMap(1, {, const, }, true)
+              endConstLiteral(;)
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields(;)
+            handleIdentifier(Set, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(1, <, >)
+            handleType(Set, null)
+            handleIdentifier(foo8, fieldDeclaration)
+            beginFieldInitializer(=)
+              beginConstLiteral(<)
+                beginTypeArguments(<)
+                  handleIdentifier(List, typeReference)
+                  beginTypeArguments(<)
+                    handleIdentifier(int, typeReference)
+                    handleNoTypeArguments(>)
+                    handleType(int, null)
+                  endTypeArguments(1, <, >)
+                  handleType(List, null)
+                endTypeArguments(1, <, >)
+                handleLiteralNull(null)
+                handleLiteralSetOrMap(1, {, const, }, true)
+              endConstLiteral(;)
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields(;)
+            handleIdentifier(Set, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(1, <, >)
+            handleType(Set, null)
+            handleIdentifier(foo9, fieldDeclaration)
+            beginFieldInitializer(=)
+              beginConstLiteral({)
+                handleNoTypeArguments({)
+                handleLiteralNull(null)
+                handleLiteralSetOrMap(1, {, const, }, true)
+              endConstLiteral(;)
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+      endClassOrMixinBody(DeclarationKind.Class, 9, {, })
+    endClassDeclaration(class, })
+  endTopLevelDeclaration()
+endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_45251_set_const.dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/issue_45251_set_const.dart.intertwined.expect
new file mode 100644
index 0000000..7f9a6a5
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_45251_set_const.dart.intertwined.expect
@@ -0,0 +1,416 @@
+parseUnit(class)
+  skipErrorTokens(class)
+  listener: beginCompilationUnit(class)
+  syntheticPreviousToken(class)
+  parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+    parseMetadataStar()
+      listener: beginMetadataStar(class)
+      listener: endMetadataStar(0)
+    parseTopLevelKeywordDeclaration(, class, Instance of 'DirectiveContext')
+      parseClassDeclarationModifiers(, class)
+      parseClassOrNamedMixinApplication(null, class)
+        listener: beginClassOrNamedMixinApplicationPrelude(class)
+        ensureIdentifier(class, classOrMixinDeclaration)
+          listener: handleIdentifier(F, classOrMixinDeclaration)
+        listener: handleNoTypeVariables({)
+        listener: beginClassDeclaration(class, null, F)
+        parseClass(F, class, class, F)
+          parseClassHeaderOpt(F, class, class)
+            parseClassExtendsOpt(F)
+              listener: handleNoType(F)
+              listener: handleClassExtends(null, 1)
+            parseWithClauseOpt(F)
+              listener: handleClassNoWithClause()
+            parseClassOrMixinImplementsOpt(F)
+              listener: handleClassOrMixinImplements(null, 0)
+            listener: handleClassHeader(class, class, null)
+          parseClassOrMixinOrExtensionBody(F, DeclarationKind.Class, F)
+            listener: beginClassOrMixinBody(DeclarationKind.Class, {)
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl({, DeclarationKind.Class, F)
+              parseMetadataStar({)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields({, null, null, null, null, null, final, final, Instance of 'SimpleTypeWith1Argument', foo1, DeclarationKind.Class, F, false)
+                listener: beginFields({)
+                listener: handleIdentifier(Set, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(1, <, >)
+                listener: handleType(Set, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo1, fieldDeclaration)
+                parseFieldInitializerOpt(foo1, foo1, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseConstExpression(=)
+                            reportRecoverableError(Set, Message[LiteralWithClass, A set literal can't be prefixed by 'Set'., Try removing 'Set', {string: set, lexeme: Set}])
+                              listener: handleRecoverableError(Message[LiteralWithClass, A set literal can't be prefixed by 'Set'., Try removing 'Set', {string: set, lexeme: Set}], Set, Set)
+                            listener: beginConstLiteral(<)
+                            parseLiteralListSetMapOrFunction(Set, const)
+                              listener: beginTypeArguments(<)
+                              listener: handleIdentifier(List, typeReference)
+                              listener: beginTypeArguments(<)
+                              listener: handleIdentifier(int, typeReference)
+                              listener: handleNoTypeArguments(>)
+                              listener: handleType(int, null)
+                              listener: endTypeArguments(1, <, >)
+                              listener: handleType(List, null)
+                              listener: endTypeArguments(1, <, >)
+                              parseLiteralSetOrMapSuffix(>, const)
+                                listener: handleLiteralSetOrMap(0, {, const, }, false)
+                            listener: endConstLiteral(;)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, F)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, final, final, Instance of 'SimpleTypeWith1Argument', foo2, DeclarationKind.Class, F, false)
+                listener: beginFields(;)
+                listener: handleIdentifier(Set, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(1, <, >)
+                listener: handleType(Set, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo2, fieldDeclaration)
+                parseFieldInitializerOpt(foo2, foo2, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseConstExpression(=)
+                            listener: beginConstLiteral(<)
+                            parseLiteralListSetMapOrFunction(const, const)
+                              listener: beginTypeArguments(<)
+                              listener: handleIdentifier(List, typeReference)
+                              listener: beginTypeArguments(<)
+                              listener: handleIdentifier(int, typeReference)
+                              listener: handleNoTypeArguments(>)
+                              listener: handleType(int, null)
+                              listener: endTypeArguments(1, <, >)
+                              listener: handleType(List, null)
+                              listener: endTypeArguments(1, <, >)
+                              parseLiteralSetOrMapSuffix(>, const)
+                                listener: handleLiteralSetOrMap(0, {, const, }, false)
+                            listener: endConstLiteral(;)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, F)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, final, final, Instance of 'SimpleTypeWith1Argument', foo3, DeclarationKind.Class, F, false)
+                listener: beginFields(;)
+                listener: handleIdentifier(Set, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(1, <, >)
+                listener: handleType(Set, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo3, fieldDeclaration)
+                parseFieldInitializerOpt(foo3, foo3, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseConstExpression(=)
+                            reportRecoverableError(Set, Message[LiteralWithClass, A set literal can't be prefixed by 'Set'., Try removing 'Set', {string: set, lexeme: Set}])
+                              listener: handleRecoverableError(Message[LiteralWithClass, A set literal can't be prefixed by 'Set'., Try removing 'Set', {string: set, lexeme: Set}], Set, Set)
+                            listener: beginConstLiteral({)
+                            listener: handleNoTypeArguments({)
+                            parseLiteralSetOrMapSuffix(Set, const)
+                              listener: handleLiteralSetOrMap(0, {, const, }, false)
+                            listener: endConstLiteral(;)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, F)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, final, final, Instance of 'SimpleTypeWith1Argument', foo4, DeclarationKind.Class, F, false)
+                listener: beginFields(;)
+                listener: handleIdentifier(Set, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(1, <, >)
+                listener: handleType(Set, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo4, fieldDeclaration)
+                parseFieldInitializerOpt(foo4, foo4, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseConstExpression(=)
+                            listener: beginConstExpression(const)
+                            parseConstructorReference(const, Instance of 'ComplexTypeParamOrArgInfo')
+                              ensureIdentifier(const, constructorReference)
+                                listener: handleIdentifier(Set, constructorReference)
+                              listener: beginConstructorReference(Set)
+                              parseQualifiedRestOpt(Set, constructorReferenceContinuation)
+                              listener: beginTypeArguments(<)
+                              listener: handleIdentifier(List, typeReference)
+                              listener: beginTypeArguments(<)
+                              listener: handleIdentifier(int, typeReference)
+                              listener: handleNoTypeArguments(>)
+                              listener: handleType(int, null)
+                              listener: endTypeArguments(1, <, >)
+                              listener: handleType(List, null)
+                              listener: endTypeArguments(1, <, >)
+                              listener: handleNoConstructorReferenceContinuationAfterTypeArguments(()
+                              listener: endConstructorReference(Set, null, ()
+                            parseConstructorInvocationArguments(>)
+                              parseArgumentsRest(()
+                                listener: beginArguments(()
+                                listener: endArguments(0, (, ))
+                            listener: endConstExpression(const)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, F)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, final, final, Instance of 'SimpleTypeWith1Argument', foo5, DeclarationKind.Class, F, false)
+                listener: beginFields(;)
+                listener: handleIdentifier(Set, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(1, <, >)
+                listener: handleType(Set, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo5, fieldDeclaration)
+                parseFieldInitializerOpt(foo5, foo5, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseConstExpression(=)
+                            listener: beginConstExpression(const)
+                            parseConstructorReference(const, Instance of 'NoTypeParamOrArg')
+                              ensureIdentifier(const, constructorReference)
+                                listener: handleIdentifier(Set, constructorReference)
+                              listener: beginConstructorReference(Set)
+                              parseQualifiedRestOpt(Set, constructorReferenceContinuation)
+                              listener: handleNoTypeArguments(()
+                              listener: handleNoConstructorReferenceContinuationAfterTypeArguments(()
+                              listener: endConstructorReference(Set, null, ()
+                            parseConstructorInvocationArguments(Set)
+                              parseArgumentsRest(()
+                                listener: beginArguments(()
+                                listener: endArguments(0, (, ))
+                            listener: endConstExpression(const)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, F)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, final, final, Instance of 'SimpleTypeWith1Argument', foo6, DeclarationKind.Class, F, false)
+                listener: beginFields(;)
+                listener: handleIdentifier(Set, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(1, <, >)
+                listener: handleType(Set, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo6, fieldDeclaration)
+                parseFieldInitializerOpt(foo6, foo6, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseConstExpression(=)
+                            reportRecoverableError(Set, Message[LiteralWithClass, A set literal can't be prefixed by 'Set'., Try removing 'Set', {string: set, lexeme: Set}])
+                              listener: handleRecoverableError(Message[LiteralWithClass, A set literal can't be prefixed by 'Set'., Try removing 'Set', {string: set, lexeme: Set}], Set, Set)
+                            listener: beginConstLiteral(<)
+                            parseLiteralListSetMapOrFunction(Set, const)
+                              listener: beginTypeArguments(<)
+                              listener: handleIdentifier(List, typeReference)
+                              listener: beginTypeArguments(<)
+                              listener: handleIdentifier(int, typeReference)
+                              listener: handleNoTypeArguments(>)
+                              listener: handleType(int, null)
+                              listener: endTypeArguments(1, <, >)
+                              listener: handleType(List, null)
+                              listener: endTypeArguments(1, <, >)
+                              parseLiteralSetOrMapSuffix(>, const)
+                                parseExpression({)
+                                  parsePrecedenceExpression({, 1, true)
+                                    parseUnaryExpression({, true)
+                                      parsePrimary({, expression)
+                                        parseLiteralNull({)
+                                          listener: handleLiteralNull(null)
+                                listener: handleLiteralSetOrMap(1, {, const, }, true)
+                            listener: endConstLiteral(;)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, F)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, final, final, Instance of 'SimpleTypeWith1Argument', foo7, DeclarationKind.Class, F, false)
+                listener: beginFields(;)
+                listener: handleIdentifier(Set, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(1, <, >)
+                listener: handleType(Set, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo7, fieldDeclaration)
+                parseFieldInitializerOpt(foo7, foo7, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseConstExpression(=)
+                            reportRecoverableError(Set, Message[LiteralWithClass, A set literal can't be prefixed by 'Set'., Try removing 'Set', {string: set, lexeme: Set}])
+                              listener: handleRecoverableError(Message[LiteralWithClass, A set literal can't be prefixed by 'Set'., Try removing 'Set', {string: set, lexeme: Set}], Set, Set)
+                            listener: beginConstLiteral({)
+                            listener: handleNoTypeArguments({)
+                            parseLiteralSetOrMapSuffix(Set, const)
+                              parseExpression({)
+                                parsePrecedenceExpression({, 1, true)
+                                  parseUnaryExpression({, true)
+                                    parsePrimary({, expression)
+                                      parseLiteralNull({)
+                                        listener: handleLiteralNull(null)
+                              listener: handleLiteralSetOrMap(1, {, const, }, true)
+                            listener: endConstLiteral(;)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, F)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, final, final, Instance of 'SimpleTypeWith1Argument', foo8, DeclarationKind.Class, F, false)
+                listener: beginFields(;)
+                listener: handleIdentifier(Set, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(1, <, >)
+                listener: handleType(Set, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo8, fieldDeclaration)
+                parseFieldInitializerOpt(foo8, foo8, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseConstExpression(=)
+                            listener: beginConstLiteral(<)
+                            parseLiteralListSetMapOrFunction(const, const)
+                              listener: beginTypeArguments(<)
+                              listener: handleIdentifier(List, typeReference)
+                              listener: beginTypeArguments(<)
+                              listener: handleIdentifier(int, typeReference)
+                              listener: handleNoTypeArguments(>)
+                              listener: handleType(int, null)
+                              listener: endTypeArguments(1, <, >)
+                              listener: handleType(List, null)
+                              listener: endTypeArguments(1, <, >)
+                              parseLiteralSetOrMapSuffix(>, const)
+                                parseExpression({)
+                                  parsePrecedenceExpression({, 1, true)
+                                    parseUnaryExpression({, true)
+                                      parsePrimary({, expression)
+                                        parseLiteralNull({)
+                                          listener: handleLiteralNull(null)
+                                listener: handleLiteralSetOrMap(1, {, const, }, true)
+                            listener: endConstLiteral(;)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, F)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, final, final, Instance of 'SimpleTypeWith1Argument', foo9, DeclarationKind.Class, F, false)
+                listener: beginFields(;)
+                listener: handleIdentifier(Set, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(1, <, >)
+                listener: handleType(Set, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo9, fieldDeclaration)
+                parseFieldInitializerOpt(foo9, foo9, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseConstExpression(=)
+                            listener: beginConstLiteral({)
+                            listener: handleNoTypeArguments({)
+                            parseLiteralSetOrMapSuffix(const, const)
+                              parseExpression({)
+                                parsePrecedenceExpression({, 1, true)
+                                  parseUnaryExpression({, true)
+                                    parsePrimary({, expression)
+                                      parseLiteralNull({)
+                                        listener: handleLiteralNull(null)
+                              listener: handleLiteralSetOrMap(1, {, const, }, true)
+                            listener: endConstLiteral(;)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, })
+            listener: endClassOrMixinBody(DeclarationKind.Class, 9, {, })
+          listener: endClassDeclaration(class, })
+  listener: endTopLevelDeclaration()
+  reportAllErrorTokens(class)
+  listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_45251_set_const.dart.parser.expect b/pkg/front_end/parser_testcases/error_recovery/issue_45251_set_const.dart.parser.expect
new file mode 100644
index 0000000..2cbb213
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_45251_set_const.dart.parser.expect
@@ -0,0 +1,59 @@
+NOTICE: Stream was rewritten by parser!
+
+class F {
+
+final Set<Undefined> foo1 = const Set<List<int>>{};
+
+
+final Set<Undefined> foo2 = const <List<int>>{};
+
+
+final Set<Undefined> foo3 = const Set{};
+
+
+final Set<Undefined> foo4 = const Set<List<int>>();
+
+
+final Set<Undefined> foo5 = const Set();
+
+
+final Set<Undefined> foo6 = const Set<List<int>>{null};
+
+
+final Set<Undefined> foo7 = const Set{null};
+
+
+final Set<Undefined> foo8 = const <List<int>>{null};
+
+
+final Set<Undefined> foo9 = const {null};
+}
+
+class[KeywordToken] F[StringToken] {[BeginToken]
+
+final[KeywordToken] Set[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo1[StringToken] =[SimpleToken] const[KeywordToken] Set[StringToken]<[BeginToken]List[StringToken]<[BeginToken]int[StringToken]>[SimpleToken]>[SimpleToken]{[BeginToken]}[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Set[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo2[StringToken] =[SimpleToken] const[KeywordToken] <[BeginToken]List[StringToken]<[BeginToken]int[StringToken]>[SimpleToken]>[SimpleToken]{[BeginToken]}[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Set[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo3[StringToken] =[SimpleToken] const[KeywordToken] Set[StringToken]{[BeginToken]}[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Set[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo4[StringToken] =[SimpleToken] const[KeywordToken] Set[StringToken]<[BeginToken]List[StringToken]<[BeginToken]int[StringToken]>[SimpleToken]>[SimpleToken]([BeginToken])[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Set[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo5[StringToken] =[SimpleToken] const[KeywordToken] Set[StringToken]([BeginToken])[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Set[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo6[StringToken] =[SimpleToken] const[KeywordToken] Set[StringToken]<[BeginToken]List[StringToken]<[BeginToken]int[StringToken]>[SimpleToken]>[SimpleToken]{[BeginToken]null[KeywordToken]}[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Set[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo7[StringToken] =[SimpleToken] const[KeywordToken] Set[StringToken]{[BeginToken]null[KeywordToken]}[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Set[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo8[StringToken] =[SimpleToken] const[KeywordToken] <[BeginToken]List[StringToken]<[BeginToken]int[StringToken]>[SimpleToken]>[SimpleToken]{[BeginToken]null[KeywordToken]}[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Set[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo9[StringToken] =[SimpleToken] const[KeywordToken] {[BeginToken]null[KeywordToken]}[SimpleToken];[SimpleToken]
+}[SimpleToken][SimpleToken]
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_45251_set_const.dart.scanner.expect b/pkg/front_end/parser_testcases/error_recovery/issue_45251_set_const.dart.scanner.expect
new file mode 100644
index 0000000..4f0046a
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_45251_set_const.dart.scanner.expect
@@ -0,0 +1,57 @@
+class F {
+
+final Set<Undefined> foo1 = const Set<List<int>>{};
+
+
+final Set<Undefined> foo2 = const <List<int>>{};
+
+
+final Set<Undefined> foo3 = const Set{};
+
+
+final Set<Undefined> foo4 = const Set<List<int>>();
+
+
+final Set<Undefined> foo5 = const Set();
+
+
+final Set<Undefined> foo6 = const Set<List<int>>{null};
+
+
+final Set<Undefined> foo7 = const Set{null};
+
+
+final Set<Undefined> foo8 = const <List<int>>{null};
+
+
+final Set<Undefined> foo9 = const {null};
+}
+
+class[KeywordToken] F[StringToken] {[BeginToken]
+
+final[KeywordToken] Set[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo1[StringToken] =[SimpleToken] const[KeywordToken] Set[StringToken]<[BeginToken]List[StringToken]<[BeginToken]int[StringToken]>>[SimpleToken]{[BeginToken]}[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Set[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo2[StringToken] =[SimpleToken] const[KeywordToken] <[BeginToken]List[StringToken]<[BeginToken]int[StringToken]>>[SimpleToken]{[BeginToken]}[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Set[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo3[StringToken] =[SimpleToken] const[KeywordToken] Set[StringToken]{[BeginToken]}[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Set[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo4[StringToken] =[SimpleToken] const[KeywordToken] Set[StringToken]<[BeginToken]List[StringToken]<[BeginToken]int[StringToken]>>[SimpleToken]([BeginToken])[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Set[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo5[StringToken] =[SimpleToken] const[KeywordToken] Set[StringToken]([BeginToken])[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Set[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo6[StringToken] =[SimpleToken] const[KeywordToken] Set[StringToken]<[BeginToken]List[StringToken]<[BeginToken]int[StringToken]>>[SimpleToken]{[BeginToken]null[KeywordToken]}[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Set[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo7[StringToken] =[SimpleToken] const[KeywordToken] Set[StringToken]{[BeginToken]null[KeywordToken]}[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Set[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo8[StringToken] =[SimpleToken] const[KeywordToken] <[BeginToken]List[StringToken]<[BeginToken]int[StringToken]>>[SimpleToken]{[BeginToken]null[KeywordToken]}[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Set[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo9[StringToken] =[SimpleToken] const[KeywordToken] {[BeginToken]null[KeywordToken]}[SimpleToken];[SimpleToken]
+}[SimpleToken][SimpleToken]
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_45251_set_new.dart b/pkg/front_end/parser_testcases/error_recovery/issue_45251_set_new.dart
new file mode 100644
index 0000000..a949b83
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_45251_set_new.dart
@@ -0,0 +1,28 @@
+class F {
+  /* notice the braces at the end instead of parenthesis! */
+  final Set<Undefined> foo1 = new Set<List<int>>{};
+
+  // variation #1: new makes it bad.
+  final Set<Undefined> foo2 = new <List<int>>{};
+
+  // variation #2: Bad.
+  final Set<Undefined> foo3 = new Set{};
+
+  // variation #3: OK.
+  final Set<Undefined> foo4 = new Set<List<int>>();
+
+  // variation #4: OK.
+  final Set<Undefined> foo5 = new Set();
+
+  // variation #5: Bad.
+  final Set<Undefined> foo6 = new Set<List<int>>{null};
+
+  // variation #6: Bad.
+  final Set<Undefined> foo7 = new Set{null};
+
+  // variation #7: new makes it bad.
+  final Set<Undefined> foo8 = new <List<int>>{null};
+
+  // variation #8: new makes it bad.
+  final Set<Undefined> foo9 = new {null};
+}
\ No newline at end of file
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_45251_set_new.dart.expect b/pkg/front_end/parser_testcases/error_recovery/issue_45251_set_new.dart.expect
new file mode 100644
index 0000000..1df0d1b
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_45251_set_new.dart.expect
@@ -0,0 +1,274 @@
+Problems reported:
+
+parser/error_recovery/issue_45251_set_new:3:31: A set literal can't be prefixed by 'new Set'.
+  final Set<Undefined> foo1 = new Set<List<int>>{};
+                              ^^^^^^^
+
+parser/error_recovery/issue_45251_set_new:6:31: A literal can't be prefixed by 'new'.
+  final Set<Undefined> foo2 = new <List<int>>{};
+                              ^^^
+
+parser/error_recovery/issue_45251_set_new:9:31: A set literal can't be prefixed by 'new Set'.
+  final Set<Undefined> foo3 = new Set{};
+                              ^^^^^^^
+
+parser/error_recovery/issue_45251_set_new:18:31: A set literal can't be prefixed by 'new Set'.
+  final Set<Undefined> foo6 = new Set<List<int>>{null};
+                              ^^^^^^^
+
+parser/error_recovery/issue_45251_set_new:21:31: A set literal can't be prefixed by 'new Set'.
+  final Set<Undefined> foo7 = new Set{null};
+                              ^^^^^^^
+
+parser/error_recovery/issue_45251_set_new:24:31: A literal can't be prefixed by 'new'.
+  final Set<Undefined> foo8 = new <List<int>>{null};
+                              ^^^
+
+parser/error_recovery/issue_45251_set_new:27:31: A literal can't be prefixed by 'new'.
+  final Set<Undefined> foo9 = new {null};
+                              ^^^
+
+beginCompilationUnit(class)
+  beginMetadataStar(class)
+  endMetadataStar(0)
+  beginClassOrNamedMixinApplicationPrelude(class)
+    handleIdentifier(F, classOrMixinDeclaration)
+    handleNoTypeVariables({)
+    beginClassDeclaration(class, null, F)
+      handleNoType(F)
+      handleClassExtends(null, 1)
+      handleClassNoWithClause()
+      handleClassOrMixinImplements(null, 0)
+      handleClassHeader(class, class, null)
+      beginClassOrMixinBody(DeclarationKind.Class, {)
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields({)
+            handleIdentifier(Set, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(1, <, >)
+            handleType(Set, null)
+            handleIdentifier(foo1, fieldDeclaration)
+            beginFieldInitializer(=)
+              handleRecoverableError(Message[LiteralWithClassAndNew, A set literal can't be prefixed by 'new Set'., Try removing 'new' and 'Set', {string: set, lexeme: Set}], new, Set)
+              beginTypeArguments(<)
+                handleIdentifier(List, typeReference)
+                beginTypeArguments(<)
+                  handleIdentifier(int, typeReference)
+                  handleNoTypeArguments(>)
+                  handleType(int, null)
+                endTypeArguments(1, <, >)
+                handleType(List, null)
+              endTypeArguments(1, <, >)
+              handleLiteralSetOrMap(0, {, null, }, false)
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields(;)
+            handleIdentifier(Set, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(1, <, >)
+            handleType(Set, null)
+            handleIdentifier(foo2, fieldDeclaration)
+            beginFieldInitializer(=)
+              handleRecoverableError(LiteralWithNew, new, new)
+              beginTypeArguments(<)
+                handleIdentifier(List, typeReference)
+                beginTypeArguments(<)
+                  handleIdentifier(int, typeReference)
+                  handleNoTypeArguments(>)
+                  handleType(int, null)
+                endTypeArguments(1, <, >)
+                handleType(List, null)
+              endTypeArguments(1, <, >)
+              handleLiteralSetOrMap(0, {, null, }, false)
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields(;)
+            handleIdentifier(Set, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(1, <, >)
+            handleType(Set, null)
+            handleIdentifier(foo3, fieldDeclaration)
+            beginFieldInitializer(=)
+              handleRecoverableError(Message[LiteralWithClassAndNew, A set literal can't be prefixed by 'new Set'., Try removing 'new' and 'Set', {string: set, lexeme: Set}], new, Set)
+              handleNoTypeArguments({)
+              handleLiteralSetOrMap(0, {, null, }, false)
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields(;)
+            handleIdentifier(Set, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(1, <, >)
+            handleType(Set, null)
+            handleIdentifier(foo4, fieldDeclaration)
+            beginFieldInitializer(=)
+              beginNewExpression(new)
+                handleIdentifier(Set, constructorReference)
+                beginConstructorReference(Set)
+                  beginTypeArguments(<)
+                    handleIdentifier(List, typeReference)
+                    beginTypeArguments(<)
+                      handleIdentifier(int, typeReference)
+                      handleNoTypeArguments(>)
+                      handleType(int, null)
+                    endTypeArguments(1, <, >)
+                    handleType(List, null)
+                  endTypeArguments(1, <, >)
+                  handleNoConstructorReferenceContinuationAfterTypeArguments(()
+                endConstructorReference(Set, null, ()
+                beginArguments(()
+                endArguments(0, (, ))
+              endNewExpression(new)
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields(;)
+            handleIdentifier(Set, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(1, <, >)
+            handleType(Set, null)
+            handleIdentifier(foo5, fieldDeclaration)
+            beginFieldInitializer(=)
+              beginNewExpression(new)
+                handleIdentifier(Set, constructorReference)
+                beginConstructorReference(Set)
+                  handleNoTypeArguments(()
+                  handleNoConstructorReferenceContinuationAfterTypeArguments(()
+                endConstructorReference(Set, null, ()
+                beginArguments(()
+                endArguments(0, (, ))
+              endNewExpression(new)
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields(;)
+            handleIdentifier(Set, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(1, <, >)
+            handleType(Set, null)
+            handleIdentifier(foo6, fieldDeclaration)
+            beginFieldInitializer(=)
+              handleRecoverableError(Message[LiteralWithClassAndNew, A set literal can't be prefixed by 'new Set'., Try removing 'new' and 'Set', {string: set, lexeme: Set}], new, Set)
+              beginTypeArguments(<)
+                handleIdentifier(List, typeReference)
+                beginTypeArguments(<)
+                  handleIdentifier(int, typeReference)
+                  handleNoTypeArguments(>)
+                  handleType(int, null)
+                endTypeArguments(1, <, >)
+                handleType(List, null)
+              endTypeArguments(1, <, >)
+              handleLiteralNull(null)
+              handleLiteralSetOrMap(1, {, null, }, true)
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields(;)
+            handleIdentifier(Set, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(1, <, >)
+            handleType(Set, null)
+            handleIdentifier(foo7, fieldDeclaration)
+            beginFieldInitializer(=)
+              handleRecoverableError(Message[LiteralWithClassAndNew, A set literal can't be prefixed by 'new Set'., Try removing 'new' and 'Set', {string: set, lexeme: Set}], new, Set)
+              handleNoTypeArguments({)
+              handleLiteralNull(null)
+              handleLiteralSetOrMap(1, {, null, }, true)
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields(;)
+            handleIdentifier(Set, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(1, <, >)
+            handleType(Set, null)
+            handleIdentifier(foo8, fieldDeclaration)
+            beginFieldInitializer(=)
+              handleRecoverableError(LiteralWithNew, new, new)
+              beginTypeArguments(<)
+                handleIdentifier(List, typeReference)
+                beginTypeArguments(<)
+                  handleIdentifier(int, typeReference)
+                  handleNoTypeArguments(>)
+                  handleType(int, null)
+                endTypeArguments(1, <, >)
+                handleType(List, null)
+              endTypeArguments(1, <, >)
+              handleLiteralNull(null)
+              handleLiteralSetOrMap(1, {, null, }, true)
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+        beginMetadataStar(final)
+        endMetadataStar(0)
+        beginMember()
+          beginFields(;)
+            handleIdentifier(Set, typeReference)
+            beginTypeArguments(<)
+              handleIdentifier(Undefined, typeReference)
+              handleNoTypeArguments(>)
+              handleType(Undefined, null)
+            endTypeArguments(1, <, >)
+            handleType(Set, null)
+            handleIdentifier(foo9, fieldDeclaration)
+            beginFieldInitializer(=)
+              handleRecoverableError(LiteralWithNew, new, new)
+              handleNoTypeArguments({)
+              handleLiteralNull(null)
+              handleLiteralSetOrMap(1, {, null, }, true)
+            endFieldInitializer(=, ;)
+          endClassFields(null, null, null, null, null, final, 1, final, ;)
+        endMember()
+      endClassOrMixinBody(DeclarationKind.Class, 9, {, })
+    endClassDeclaration(class, })
+  endTopLevelDeclaration()
+endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_45251_set_new.dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/issue_45251_set_new.dart.intertwined.expect
new file mode 100644
index 0000000..49f1043
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_45251_set_new.dart.intertwined.expect
@@ -0,0 +1,411 @@
+parseUnit(class)
+  skipErrorTokens(class)
+  listener: beginCompilationUnit(class)
+  syntheticPreviousToken(class)
+  parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+    parseMetadataStar()
+      listener: beginMetadataStar(class)
+      listener: endMetadataStar(0)
+    parseTopLevelKeywordDeclaration(, class, Instance of 'DirectiveContext')
+      parseClassDeclarationModifiers(, class)
+      parseClassOrNamedMixinApplication(null, class)
+        listener: beginClassOrNamedMixinApplicationPrelude(class)
+        ensureIdentifier(class, classOrMixinDeclaration)
+          listener: handleIdentifier(F, classOrMixinDeclaration)
+        listener: handleNoTypeVariables({)
+        listener: beginClassDeclaration(class, null, F)
+        parseClass(F, class, class, F)
+          parseClassHeaderOpt(F, class, class)
+            parseClassExtendsOpt(F)
+              listener: handleNoType(F)
+              listener: handleClassExtends(null, 1)
+            parseWithClauseOpt(F)
+              listener: handleClassNoWithClause()
+            parseClassOrMixinImplementsOpt(F)
+              listener: handleClassOrMixinImplements(null, 0)
+            listener: handleClassHeader(class, class, null)
+          parseClassOrMixinOrExtensionBody(F, DeclarationKind.Class, F)
+            listener: beginClassOrMixinBody(DeclarationKind.Class, {)
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl({, DeclarationKind.Class, F)
+              parseMetadataStar({)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields({, null, null, null, null, null, final, final, Instance of 'SimpleTypeWith1Argument', foo1, DeclarationKind.Class, F, false)
+                listener: beginFields({)
+                listener: handleIdentifier(Set, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(1, <, >)
+                listener: handleType(Set, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo1, fieldDeclaration)
+                parseFieldInitializerOpt(foo1, foo1, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseNewExpression(=)
+                            listener: handleRecoverableError(Message[LiteralWithClassAndNew, A set literal can't be prefixed by 'new Set'., Try removing 'new' and 'Set', {string: set, lexeme: Set}], new, Set)
+                            parsePrimary(Set, expression)
+                              parseLiteralListSetMapOrFunction(Set, null)
+                                listener: beginTypeArguments(<)
+                                listener: handleIdentifier(List, typeReference)
+                                listener: beginTypeArguments(<)
+                                listener: handleIdentifier(int, typeReference)
+                                listener: handleNoTypeArguments(>)
+                                listener: handleType(int, null)
+                                listener: endTypeArguments(1, <, >)
+                                listener: handleType(List, null)
+                                listener: endTypeArguments(1, <, >)
+                                parseLiteralSetOrMapSuffix(>, null)
+                                  listener: handleLiteralSetOrMap(0, {, null, }, false)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, F)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, final, final, Instance of 'SimpleTypeWith1Argument', foo2, DeclarationKind.Class, F, false)
+                listener: beginFields(;)
+                listener: handleIdentifier(Set, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(1, <, >)
+                listener: handleType(Set, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo2, fieldDeclaration)
+                parseFieldInitializerOpt(foo2, foo2, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseNewExpression(=)
+                            reportRecoverableError(new, LiteralWithNew)
+                              listener: handleRecoverableError(LiteralWithNew, new, new)
+                            parsePrimary(new, expression)
+                              parseLiteralListSetMapOrFunction(new, null)
+                                listener: beginTypeArguments(<)
+                                listener: handleIdentifier(List, typeReference)
+                                listener: beginTypeArguments(<)
+                                listener: handleIdentifier(int, typeReference)
+                                listener: handleNoTypeArguments(>)
+                                listener: handleType(int, null)
+                                listener: endTypeArguments(1, <, >)
+                                listener: handleType(List, null)
+                                listener: endTypeArguments(1, <, >)
+                                parseLiteralSetOrMapSuffix(>, null)
+                                  listener: handleLiteralSetOrMap(0, {, null, }, false)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, F)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, final, final, Instance of 'SimpleTypeWith1Argument', foo3, DeclarationKind.Class, F, false)
+                listener: beginFields(;)
+                listener: handleIdentifier(Set, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(1, <, >)
+                listener: handleType(Set, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo3, fieldDeclaration)
+                parseFieldInitializerOpt(foo3, foo3, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseNewExpression(=)
+                            listener: handleRecoverableError(Message[LiteralWithClassAndNew, A set literal can't be prefixed by 'new Set'., Try removing 'new' and 'Set', {string: set, lexeme: Set}], new, Set)
+                            parsePrimary(Set, expression)
+                              listener: handleNoTypeArguments({)
+                              parseLiteralSetOrMapSuffix(Set, null)
+                                listener: handleLiteralSetOrMap(0, {, null, }, false)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, F)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, final, final, Instance of 'SimpleTypeWith1Argument', foo4, DeclarationKind.Class, F, false)
+                listener: beginFields(;)
+                listener: handleIdentifier(Set, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(1, <, >)
+                listener: handleType(Set, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo4, fieldDeclaration)
+                parseFieldInitializerOpt(foo4, foo4, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseNewExpression(=)
+                            listener: beginNewExpression(new)
+                            parseConstructorReference(new, Instance of 'ComplexTypeParamOrArgInfo')
+                              ensureIdentifier(new, constructorReference)
+                                listener: handleIdentifier(Set, constructorReference)
+                              listener: beginConstructorReference(Set)
+                              parseQualifiedRestOpt(Set, constructorReferenceContinuation)
+                              listener: beginTypeArguments(<)
+                              listener: handleIdentifier(List, typeReference)
+                              listener: beginTypeArguments(<)
+                              listener: handleIdentifier(int, typeReference)
+                              listener: handleNoTypeArguments(>)
+                              listener: handleType(int, null)
+                              listener: endTypeArguments(1, <, >)
+                              listener: handleType(List, null)
+                              listener: endTypeArguments(1, <, >)
+                              listener: handleNoConstructorReferenceContinuationAfterTypeArguments(()
+                              listener: endConstructorReference(Set, null, ()
+                            parseConstructorInvocationArguments(>)
+                              parseArgumentsRest(()
+                                listener: beginArguments(()
+                                listener: endArguments(0, (, ))
+                            listener: endNewExpression(new)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, F)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, final, final, Instance of 'SimpleTypeWith1Argument', foo5, DeclarationKind.Class, F, false)
+                listener: beginFields(;)
+                listener: handleIdentifier(Set, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(1, <, >)
+                listener: handleType(Set, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo5, fieldDeclaration)
+                parseFieldInitializerOpt(foo5, foo5, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseNewExpression(=)
+                            listener: beginNewExpression(new)
+                            parseConstructorReference(new, Instance of 'NoTypeParamOrArg')
+                              ensureIdentifier(new, constructorReference)
+                                listener: handleIdentifier(Set, constructorReference)
+                              listener: beginConstructorReference(Set)
+                              parseQualifiedRestOpt(Set, constructorReferenceContinuation)
+                              listener: handleNoTypeArguments(()
+                              listener: handleNoConstructorReferenceContinuationAfterTypeArguments(()
+                              listener: endConstructorReference(Set, null, ()
+                            parseConstructorInvocationArguments(Set)
+                              parseArgumentsRest(()
+                                listener: beginArguments(()
+                                listener: endArguments(0, (, ))
+                            listener: endNewExpression(new)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, F)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, final, final, Instance of 'SimpleTypeWith1Argument', foo6, DeclarationKind.Class, F, false)
+                listener: beginFields(;)
+                listener: handleIdentifier(Set, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(1, <, >)
+                listener: handleType(Set, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo6, fieldDeclaration)
+                parseFieldInitializerOpt(foo6, foo6, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseNewExpression(=)
+                            listener: handleRecoverableError(Message[LiteralWithClassAndNew, A set literal can't be prefixed by 'new Set'., Try removing 'new' and 'Set', {string: set, lexeme: Set}], new, Set)
+                            parsePrimary(Set, expression)
+                              parseLiteralListSetMapOrFunction(Set, null)
+                                listener: beginTypeArguments(<)
+                                listener: handleIdentifier(List, typeReference)
+                                listener: beginTypeArguments(<)
+                                listener: handleIdentifier(int, typeReference)
+                                listener: handleNoTypeArguments(>)
+                                listener: handleType(int, null)
+                                listener: endTypeArguments(1, <, >)
+                                listener: handleType(List, null)
+                                listener: endTypeArguments(1, <, >)
+                                parseLiteralSetOrMapSuffix(>, null)
+                                  parseExpression({)
+                                    parsePrecedenceExpression({, 1, true)
+                                      parseUnaryExpression({, true)
+                                        parsePrimary({, expression)
+                                          parseLiteralNull({)
+                                            listener: handleLiteralNull(null)
+                                  listener: handleLiteralSetOrMap(1, {, null, }, true)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, F)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, final, final, Instance of 'SimpleTypeWith1Argument', foo7, DeclarationKind.Class, F, false)
+                listener: beginFields(;)
+                listener: handleIdentifier(Set, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(1, <, >)
+                listener: handleType(Set, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo7, fieldDeclaration)
+                parseFieldInitializerOpt(foo7, foo7, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseNewExpression(=)
+                            listener: handleRecoverableError(Message[LiteralWithClassAndNew, A set literal can't be prefixed by 'new Set'., Try removing 'new' and 'Set', {string: set, lexeme: Set}], new, Set)
+                            parsePrimary(Set, expression)
+                              listener: handleNoTypeArguments({)
+                              parseLiteralSetOrMapSuffix(Set, null)
+                                parseExpression({)
+                                  parsePrecedenceExpression({, 1, true)
+                                    parseUnaryExpression({, true)
+                                      parsePrimary({, expression)
+                                        parseLiteralNull({)
+                                          listener: handleLiteralNull(null)
+                                listener: handleLiteralSetOrMap(1, {, null, }, true)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, F)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, final, final, Instance of 'SimpleTypeWith1Argument', foo8, DeclarationKind.Class, F, false)
+                listener: beginFields(;)
+                listener: handleIdentifier(Set, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(1, <, >)
+                listener: handleType(Set, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo8, fieldDeclaration)
+                parseFieldInitializerOpt(foo8, foo8, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseNewExpression(=)
+                            reportRecoverableError(new, LiteralWithNew)
+                              listener: handleRecoverableError(LiteralWithNew, new, new)
+                            parsePrimary(new, expression)
+                              parseLiteralListSetMapOrFunction(new, null)
+                                listener: beginTypeArguments(<)
+                                listener: handleIdentifier(List, typeReference)
+                                listener: beginTypeArguments(<)
+                                listener: handleIdentifier(int, typeReference)
+                                listener: handleNoTypeArguments(>)
+                                listener: handleType(int, null)
+                                listener: endTypeArguments(1, <, >)
+                                listener: handleType(List, null)
+                                listener: endTypeArguments(1, <, >)
+                                parseLiteralSetOrMapSuffix(>, null)
+                                  parseExpression({)
+                                    parsePrecedenceExpression({, 1, true)
+                                      parseUnaryExpression({, true)
+                                        parsePrimary({, expression)
+                                          parseLiteralNull({)
+                                            listener: handleLiteralNull(null)
+                                  listener: handleLiteralSetOrMap(1, {, null, }, true)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, final)
+            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, F)
+              parseMetadataStar(;)
+                listener: beginMetadataStar(final)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              parseFields(;, null, null, null, null, null, final, final, Instance of 'SimpleTypeWith1Argument', foo9, DeclarationKind.Class, F, false)
+                listener: beginFields(;)
+                listener: handleIdentifier(Set, typeReference)
+                listener: beginTypeArguments(<)
+                listener: handleIdentifier(Undefined, typeReference)
+                listener: handleNoTypeArguments(>)
+                listener: handleType(Undefined, null)
+                listener: endTypeArguments(1, <, >)
+                listener: handleType(Set, null)
+                ensureIdentifierPotentiallyRecovered(>, fieldDeclaration, false)
+                  listener: handleIdentifier(foo9, fieldDeclaration)
+                parseFieldInitializerOpt(foo9, foo9, null, null, null, final, DeclarationKind.Class, F)
+                  listener: beginFieldInitializer(=)
+                  parseExpression(=)
+                    parsePrecedenceExpression(=, 1, true)
+                      parseUnaryExpression(=, true)
+                        parsePrimary(=, expression)
+                          parseNewExpression(=)
+                            reportRecoverableError(new, LiteralWithNew)
+                              listener: handleRecoverableError(LiteralWithNew, new, new)
+                            parsePrimary(new, expression)
+                              listener: handleNoTypeArguments({)
+                              parseLiteralSetOrMapSuffix(new, null)
+                                parseExpression({)
+                                  parsePrecedenceExpression({, 1, true)
+                                    parseUnaryExpression({, true)
+                                      parsePrimary({, expression)
+                                        parseLiteralNull({)
+                                          listener: handleLiteralNull(null)
+                                listener: handleLiteralSetOrMap(1, {, null, }, true)
+                  listener: endFieldInitializer(=, ;)
+                listener: endClassFields(null, null, null, null, null, final, 1, final, ;)
+              listener: endMember()
+            notEofOrValue(}, })
+            listener: endClassOrMixinBody(DeclarationKind.Class, 9, {, })
+          listener: endClassDeclaration(class, })
+  listener: endTopLevelDeclaration()
+  reportAllErrorTokens(class)
+  listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_45251_set_new.dart.parser.expect b/pkg/front_end/parser_testcases/error_recovery/issue_45251_set_new.dart.parser.expect
new file mode 100644
index 0000000..2f51b76
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_45251_set_new.dart.parser.expect
@@ -0,0 +1,59 @@
+NOTICE: Stream was rewritten by parser!
+
+class F {
+
+final Set<Undefined> foo1 = new Set<List<int>>{};
+
+
+final Set<Undefined> foo2 = new <List<int>>{};
+
+
+final Set<Undefined> foo3 = new Set{};
+
+
+final Set<Undefined> foo4 = new Set<List<int>>();
+
+
+final Set<Undefined> foo5 = new Set();
+
+
+final Set<Undefined> foo6 = new Set<List<int>>{null};
+
+
+final Set<Undefined> foo7 = new Set{null};
+
+
+final Set<Undefined> foo8 = new <List<int>>{null};
+
+
+final Set<Undefined> foo9 = new {null};
+}
+
+class[KeywordToken] F[StringToken] {[BeginToken]
+
+final[KeywordToken] Set[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo1[StringToken] =[SimpleToken] new[KeywordToken] Set[StringToken]<[BeginToken]List[StringToken]<[BeginToken]int[StringToken]>[SimpleToken]>[SimpleToken]{[BeginToken]}[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Set[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo2[StringToken] =[SimpleToken] new[KeywordToken] <[BeginToken]List[StringToken]<[BeginToken]int[StringToken]>[SimpleToken]>[SimpleToken]{[BeginToken]}[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Set[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo3[StringToken] =[SimpleToken] new[KeywordToken] Set[StringToken]{[BeginToken]}[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Set[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo4[StringToken] =[SimpleToken] new[KeywordToken] Set[StringToken]<[BeginToken]List[StringToken]<[BeginToken]int[StringToken]>[SimpleToken]>[SimpleToken]([BeginToken])[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Set[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo5[StringToken] =[SimpleToken] new[KeywordToken] Set[StringToken]([BeginToken])[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Set[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo6[StringToken] =[SimpleToken] new[KeywordToken] Set[StringToken]<[BeginToken]List[StringToken]<[BeginToken]int[StringToken]>[SimpleToken]>[SimpleToken]{[BeginToken]null[KeywordToken]}[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Set[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo7[StringToken] =[SimpleToken] new[KeywordToken] Set[StringToken]{[BeginToken]null[KeywordToken]}[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Set[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo8[StringToken] =[SimpleToken] new[KeywordToken] <[BeginToken]List[StringToken]<[BeginToken]int[StringToken]>[SimpleToken]>[SimpleToken]{[BeginToken]null[KeywordToken]}[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Set[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo9[StringToken] =[SimpleToken] new[KeywordToken] {[BeginToken]null[KeywordToken]}[SimpleToken];[SimpleToken]
+}[SimpleToken][SimpleToken]
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_45251_set_new.dart.scanner.expect b/pkg/front_end/parser_testcases/error_recovery/issue_45251_set_new.dart.scanner.expect
new file mode 100644
index 0000000..a92bb6a
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_45251_set_new.dart.scanner.expect
@@ -0,0 +1,57 @@
+class F {
+
+final Set<Undefined> foo1 = new Set<List<int>>{};
+
+
+final Set<Undefined> foo2 = new <List<int>>{};
+
+
+final Set<Undefined> foo3 = new Set{};
+
+
+final Set<Undefined> foo4 = new Set<List<int>>();
+
+
+final Set<Undefined> foo5 = new Set();
+
+
+final Set<Undefined> foo6 = new Set<List<int>>{null};
+
+
+final Set<Undefined> foo7 = new Set{null};
+
+
+final Set<Undefined> foo8 = new <List<int>>{null};
+
+
+final Set<Undefined> foo9 = new {null};
+}
+
+class[KeywordToken] F[StringToken] {[BeginToken]
+
+final[KeywordToken] Set[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo1[StringToken] =[SimpleToken] new[KeywordToken] Set[StringToken]<[BeginToken]List[StringToken]<[BeginToken]int[StringToken]>>[SimpleToken]{[BeginToken]}[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Set[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo2[StringToken] =[SimpleToken] new[KeywordToken] <[BeginToken]List[StringToken]<[BeginToken]int[StringToken]>>[SimpleToken]{[BeginToken]}[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Set[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo3[StringToken] =[SimpleToken] new[KeywordToken] Set[StringToken]{[BeginToken]}[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Set[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo4[StringToken] =[SimpleToken] new[KeywordToken] Set[StringToken]<[BeginToken]List[StringToken]<[BeginToken]int[StringToken]>>[SimpleToken]([BeginToken])[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Set[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo5[StringToken] =[SimpleToken] new[KeywordToken] Set[StringToken]([BeginToken])[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Set[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo6[StringToken] =[SimpleToken] new[KeywordToken] Set[StringToken]<[BeginToken]List[StringToken]<[BeginToken]int[StringToken]>>[SimpleToken]{[BeginToken]null[KeywordToken]}[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Set[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo7[StringToken] =[SimpleToken] new[KeywordToken] Set[StringToken]{[BeginToken]null[KeywordToken]}[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Set[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo8[StringToken] =[SimpleToken] new[KeywordToken] <[BeginToken]List[StringToken]<[BeginToken]int[StringToken]>>[SimpleToken]{[BeginToken]null[KeywordToken]}[SimpleToken];[SimpleToken]
+
+
+final[KeywordToken] Set[StringToken]<[BeginToken]Undefined[StringToken]>[SimpleToken] foo9[StringToken] =[SimpleToken] new[KeywordToken] {[BeginToken]null[KeywordToken]}[SimpleToken];[SimpleToken]
+}[SimpleToken][SimpleToken]
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_45327.crash_dart b/pkg/front_end/parser_testcases/error_recovery/issue_45327.crash_dart
new file mode 100644
index 0000000..fb50083
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_45327.crash_dart
@@ -0,0 +1,3 @@
+main() {
+  if (n is int or
+}
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_45327.crash_dart.expect b/pkg/front_end/parser_testcases/error_recovery/issue_45327.crash_dart.expect
new file mode 100644
index 0000000..6c4db58
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_45327.crash_dart.expect
@@ -0,0 +1,49 @@
+Problems reported:
+
+parser/error_recovery/issue_45327.crash:2:16: Expected ';' after this.
+  if (n is int or
+               ^^
+
+parser/error_recovery/issue_45327.crash:2:6: Can't find ')' to match '('.
+  if (n is int or
+     ^
+
+beginCompilationUnit(main)
+  beginMetadataStar(main)
+  endMetadataStar(0)
+  beginTopLevelMember(main)
+    beginTopLevelMethod(UnmatchedToken((), null)
+      handleNoType(UnmatchedToken(())
+      handleIdentifier(main, topLevelFunctionDeclaration)
+      handleNoTypeVariables(()
+      beginFormalParameters((, MemberKind.TopLevelMethod)
+      endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+      handleAsyncModifier(null, null)
+      beginBlockFunctionBody({)
+        beginIfStatement(if)
+          handleIdentifier(n, expression)
+          handleNoTypeArguments(is)
+          handleNoArguments(is)
+          handleSend(n, is)
+          beginIsOperatorType(is)
+            handleIdentifier(int, typeReference)
+            handleNoTypeArguments(or)
+            handleType(int, null)
+          endIsOperatorType(is)
+          handleIsOperator(is, null)
+          handleParenthesizedCondition(()
+          beginThenStatement(or)
+            handleIdentifier(or, expression)
+            handleNoTypeArguments(})
+            handleNoArguments(})
+            handleSend(or, })
+            handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], or, or)
+            handleExpressionStatement(;)
+          endThenStatement(;)
+        endIfStatement(if, null)
+      endBlockFunctionBody(1, {, })
+    endTopLevelMethod(main, null, })
+  endTopLevelDeclaration()
+  handleErrorToken(UnmatchedToken(())
+  handleRecoverableError(Message[UnmatchedToken, Can't find ')' to match '('., null, {string: ), lexeme: (}], UnmatchedToken((), UnmatchedToken(())
+endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_45327.crash_dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/issue_45327.crash_dart.intertwined.expect
new file mode 100644
index 0000000..841133c
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_45327.crash_dart.intertwined.expect
@@ -0,0 +1,101 @@
+parseUnit(UnmatchedToken(())
+  skipErrorTokens(UnmatchedToken(())
+  listener: beginCompilationUnit(main)
+  syntheticPreviousToken(main)
+  parseTopLevelDeclarationImpl(UnmatchedToken((), Instance of 'DirectiveContext')
+    parseMetadataStar(UnmatchedToken(())
+      listener: beginMetadataStar(main)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(UnmatchedToken(())
+      listener: beginTopLevelMember(main)
+      isReservedKeyword(()
+      parseTopLevelMethod(UnmatchedToken((), null, UnmatchedToken((), Instance of 'NoType', null, main, false)
+        listener: beginTopLevelMethod(UnmatchedToken((), null)
+        listener: handleNoType(UnmatchedToken(())
+        ensureIdentifierPotentiallyRecovered(UnmatchedToken((), topLevelFunctionDeclaration, false)
+          listener: handleIdentifier(main, topLevelFunctionDeclaration)
+        parseMethodTypeVar(main)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(main, main, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(main, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+        parseAsyncModifierOpt())
+          listener: handleAsyncModifier(null, null)
+          inPlainSync()
+        parseFunctionBody(), false, false)
+          listener: beginBlockFunctionBody({)
+          notEofOrValue(}, if)
+          parseStatement({)
+            parseStatementX({)
+              parseIfStatement({)
+                listener: beginIfStatement(if)
+                ensureParenthesizedCondition(if)
+                  parseExpressionInParenthesisRest(()
+                    parseExpression(()
+                      parsePrecedenceExpression((, 1, true)
+                        parseUnaryExpression((, true)
+                          parsePrimary((, expression)
+                            parseSendOrFunctionLiteral((, expression)
+                              parseSend((, expression)
+                                ensureIdentifier((, expression)
+                                  listener: handleIdentifier(n, expression)
+                                listener: handleNoTypeArguments(is)
+                                parseArgumentsOpt(n)
+                                  listener: handleNoArguments(is)
+                                listener: handleSend(n, is)
+                        parseIsOperatorRest(n)
+                          listener: beginIsOperatorType(is)
+                          computeTypeAfterIsOrAs(is)
+                          listener: handleIdentifier(int, typeReference)
+                          listener: handleNoTypeArguments(or)
+                          listener: handleType(int, null)
+                          listener: endIsOperatorType(is)
+                          listener: handleIsOperator(is, null)
+                          skipChainedAsIsOperators(int)
+                        rewriter()
+                        parsePrecedenceExpression(||, 6, true)
+                          parseUnaryExpression(||, true)
+                            parsePrimary(||, expression)
+                              parseSend(||, expression)
+                                ensureIdentifier(||, expression)
+                                  reportRecoverableErrorWithToken(), Instance of 'Template<(Token) => Message>')
+                                  rewriter()
+                                parseArgumentsOpt()
+                    ensureCloseParen(int, ()
+                      rewriter()
+                  listener: handleParenthesizedCondition(()
+                listener: beginThenStatement(or)
+                parseStatement())
+                  parseStatementX())
+                    parseExpressionStatementOrDeclarationAfterModifiers(), ), null, null, null, false)
+                      looksLikeLocalFunction(or)
+                      parseExpressionStatement())
+                        parseExpression())
+                          parsePrecedenceExpression(), 1, true)
+                            parseUnaryExpression(), true)
+                              parsePrimary(), expression)
+                                parseSendOrFunctionLiteral(), expression)
+                                  parseSend(), expression)
+                                    ensureIdentifier(), expression)
+                                      listener: handleIdentifier(or, expression)
+                                    listener: handleNoTypeArguments(})
+                                    parseArgumentsOpt(or)
+                                      listener: handleNoArguments(})
+                                    listener: handleSend(or, })
+                        ensureSemicolon(or)
+                          reportRecoverableError(or, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], or, or)
+                          rewriter()
+                        listener: handleExpressionStatement(;)
+                listener: endThenStatement(;)
+                listener: endIfStatement(if, null)
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(1, {, })
+        listener: endTopLevelMethod(main, null, })
+  listener: endTopLevelDeclaration()
+  reportAllErrorTokens(UnmatchedToken(())
+    listener: handleErrorToken(UnmatchedToken(())
+    listener: handleRecoverableError(Message[UnmatchedToken, Can't find ')' to match '('., null, {string: ), lexeme: (}], UnmatchedToken((), UnmatchedToken(())
+  listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_45327.crash_dart.parser.expect b/pkg/front_end/parser_testcases/error_recovery/issue_45327.crash_dart.parser.expect
new file mode 100644
index 0000000..2e09cb4
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_45327.crash_dart.parser.expect
@@ -0,0 +1,11 @@
+NOTICE: Stream was rewritten by parser!
+
+main() {
+if (n is int )or
+;}
+
+
+[UnmatchedToken]main[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]n[StringToken] is[KeywordToken] int[StringToken] )[SyntheticToken]or[StringToken]
+;[SyntheticToken]}[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_45327.crash_dart.scanner.expect b/pkg/front_end/parser_testcases/error_recovery/issue_45327.crash_dart.scanner.expect
new file mode 100644
index 0000000..321f988
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_45327.crash_dart.scanner.expect
@@ -0,0 +1,9 @@
+main() {
+if (n is int or
+)}
+
+
+[UnmatchedToken]main[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]n[StringToken] is[KeywordToken] int[StringToken] or[StringToken]
+)[SyntheticToken]}[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_45327_prime_1.crash_dart b/pkg/front_end/parser_testcases/error_recovery/issue_45327_prime_1.crash_dart
new file mode 100644
index 0000000..2afc4b5
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_45327_prime_1.crash_dart
@@ -0,0 +1,5 @@
+class Foo<T> {
+  foo(Object? key) {
+    if (key is! T or
+  }
+}
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_45327_prime_1.crash_dart.expect b/pkg/front_end/parser_testcases/error_recovery/issue_45327_prime_1.crash_dart.expect
new file mode 100644
index 0000000..a9b75e9
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_45327_prime_1.crash_dart.expect
@@ -0,0 +1,82 @@
+Problems reported:
+
+parser/error_recovery/issue_45327_prime_1.crash:3:19: Expected ';' after this.
+    if (key is! T or
+                  ^^
+
+parser/error_recovery/issue_45327_prime_1.crash:3:8: Can't find ')' to match '('.
+    if (key is! T or
+       ^
+
+beginCompilationUnit(class)
+  beginMetadataStar(class)
+  endMetadataStar(0)
+  beginClassOrNamedMixinApplicationPrelude(class)
+    handleIdentifier(Foo, classOrMixinDeclaration)
+    beginTypeVariables(<)
+      beginMetadataStar(T)
+      endMetadataStar(0)
+      handleIdentifier(T, typeVariableDeclaration)
+      beginTypeVariable(T)
+        handleTypeVariablesDefined(T, 1)
+        handleNoType(T)
+      endTypeVariable(>, 0, null, null)
+    endTypeVariables(<, >)
+    beginClassDeclaration(class, null, Foo)
+      handleNoType(>)
+      handleClassExtends(null, 1)
+      handleClassNoWithClause()
+      handleClassOrMixinImplements(null, 0)
+      handleClassHeader(class, class, null)
+      beginClassOrMixinBody(DeclarationKind.Class, {)
+        beginMetadataStar(foo)
+        endMetadataStar(0)
+        beginMember()
+          beginMethod(null, null, null, null, null, foo)
+            handleNoType({)
+            handleIdentifier(foo, methodDeclaration)
+            handleNoTypeVariables(()
+            beginFormalParameters((, MemberKind.NonStaticMethod)
+              beginMetadataStar(Object)
+              endMetadataStar(0)
+              beginFormalParameter(Object, MemberKind.NonStaticMethod, null, null, null)
+                handleIdentifier(Object, typeReference)
+                handleNoTypeArguments(?)
+                handleType(Object, ?)
+                handleIdentifier(key, formalParameterDeclaration)
+                handleFormalParameterWithoutValue())
+              endFormalParameter(null, null, key, null, null, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+            endFormalParameters(1, (, ), MemberKind.NonStaticMethod)
+            handleNoInitializers()
+            handleAsyncModifier(null, null)
+            beginBlockFunctionBody({)
+              beginIfStatement(if)
+                handleIdentifier(key, expression)
+                handleNoTypeArguments(is)
+                handleNoArguments(is)
+                handleSend(key, is)
+                beginIsOperatorType(is)
+                  handleIdentifier(T, typeReference)
+                  handleNoTypeArguments(or)
+                  handleType(T, null)
+                endIsOperatorType(is)
+                handleIsOperator(is, !)
+                handleParenthesizedCondition(()
+                beginThenStatement(or)
+                  handleIdentifier(or, expression)
+                  handleNoTypeArguments(})
+                  handleNoArguments(})
+                  handleSend(or, })
+                  handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], or, or)
+                  handleExpressionStatement(;)
+                endThenStatement(;)
+              endIfStatement(if, null)
+            endBlockFunctionBody(1, {, })
+          endClassMethod(null, foo, (, null, })
+        endMember()
+      endClassOrMixinBody(DeclarationKind.Class, 1, {, })
+    endClassDeclaration(class, })
+  endTopLevelDeclaration()
+  handleErrorToken(UnmatchedToken(())
+  handleRecoverableError(Message[UnmatchedToken, Can't find ')' to match '('., null, {string: ), lexeme: (}], UnmatchedToken((), UnmatchedToken(())
+endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_45327_prime_1.crash_dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/issue_45327_prime_1.crash_dart.intertwined.expect
new file mode 100644
index 0000000..d794537
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_45327_prime_1.crash_dart.intertwined.expect
@@ -0,0 +1,153 @@
+parseUnit(UnmatchedToken(())
+  skipErrorTokens(UnmatchedToken(())
+  listener: beginCompilationUnit(class)
+  syntheticPreviousToken(class)
+  parseTopLevelDeclarationImpl(UnmatchedToken((), Instance of 'DirectiveContext')
+    parseMetadataStar(UnmatchedToken(())
+      listener: beginMetadataStar(class)
+      listener: endMetadataStar(0)
+    parseTopLevelKeywordDeclaration(UnmatchedToken((), class, Instance of 'DirectiveContext')
+      parseClassDeclarationModifiers(UnmatchedToken((), class)
+      parseClassOrNamedMixinApplication(null, class)
+        listener: beginClassOrNamedMixinApplicationPrelude(class)
+        ensureIdentifier(class, classOrMixinDeclaration)
+          listener: handleIdentifier(Foo, classOrMixinDeclaration)
+        listener: beginTypeVariables(<)
+        listener: beginMetadataStar(T)
+        listener: endMetadataStar(0)
+        listener: handleIdentifier(T, typeVariableDeclaration)
+        listener: beginTypeVariable(T)
+        listener: handleTypeVariablesDefined(T, 1)
+        listener: handleNoType(T)
+        listener: endTypeVariable(>, 0, null, null)
+        listener: endTypeVariables(<, >)
+        listener: beginClassDeclaration(class, null, Foo)
+        parseClass(>, class, class, Foo)
+          parseClassHeaderOpt(>, class, class)
+            parseClassExtendsOpt(>)
+              listener: handleNoType(>)
+              listener: handleClassExtends(null, 1)
+            parseWithClauseOpt(>)
+              listener: handleClassNoWithClause()
+            parseClassOrMixinImplementsOpt(>)
+              listener: handleClassOrMixinImplements(null, 0)
+            listener: handleClassHeader(class, class, null)
+          parseClassOrMixinOrExtensionBody(>, DeclarationKind.Class, Foo)
+            listener: beginClassOrMixinBody(DeclarationKind.Class, {)
+            notEofOrValue(}, foo)
+            parseClassOrMixinOrExtensionMemberImpl({, DeclarationKind.Class, Foo)
+              parseMetadataStar({)
+                listener: beginMetadataStar(foo)
+                listener: endMetadataStar(0)
+              listener: beginMember()
+              isReservedKeyword(()
+              parseMethod({, null, null, null, null, null, null, {, Instance of 'NoType', null, foo, DeclarationKind.Class, Foo, false)
+                listener: beginMethod(null, null, null, null, null, foo)
+                listener: handleNoType({)
+                ensureIdentifierPotentiallyRecovered({, methodDeclaration, false)
+                  listener: handleIdentifier(foo, methodDeclaration)
+                parseQualifiedRestOpt(foo, methodDeclarationContinuation)
+                parseMethodTypeVar(foo)
+                  listener: handleNoTypeVariables(()
+                parseGetterOrFormalParameters(foo, foo, false, MemberKind.NonStaticMethod)
+                  parseFormalParameters(foo, MemberKind.NonStaticMethod)
+                    parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                      listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                      parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+                        parseMetadataStar(()
+                          listener: beginMetadataStar(Object)
+                          listener: endMetadataStar(0)
+                        listener: beginFormalParameter(Object, MemberKind.NonStaticMethod, null, null, null)
+                        listener: handleIdentifier(Object, typeReference)
+                        listener: handleNoTypeArguments(?)
+                        listener: handleType(Object, ?)
+                        ensureIdentifier(?, formalParameterDeclaration)
+                          listener: handleIdentifier(key, formalParameterDeclaration)
+                        listener: handleFormalParameterWithoutValue())
+                        listener: endFormalParameter(null, null, key, null, null, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+                      listener: endFormalParameters(1, (, ), MemberKind.NonStaticMethod)
+                parseInitializersOpt())
+                  listener: handleNoInitializers()
+                parseAsyncModifierOpt())
+                  listener: handleAsyncModifier(null, null)
+                  inPlainSync()
+                inPlainSync()
+                parseFunctionBody(), false, true)
+                  listener: beginBlockFunctionBody({)
+                  notEofOrValue(}, if)
+                  parseStatement({)
+                    parseStatementX({)
+                      parseIfStatement({)
+                        listener: beginIfStatement(if)
+                        ensureParenthesizedCondition(if)
+                          parseExpressionInParenthesisRest(()
+                            parseExpression(()
+                              parsePrecedenceExpression((, 1, true)
+                                parseUnaryExpression((, true)
+                                  parsePrimary((, expression)
+                                    parseSendOrFunctionLiteral((, expression)
+                                      parseSend((, expression)
+                                        ensureIdentifier((, expression)
+                                          listener: handleIdentifier(key, expression)
+                                        listener: handleNoTypeArguments(is)
+                                        parseArgumentsOpt(key)
+                                          listener: handleNoArguments(is)
+                                        listener: handleSend(key, is)
+                                parseIsOperatorRest(key)
+                                  listener: beginIsOperatorType(is)
+                                  computeTypeAfterIsOrAs(!)
+                                  listener: handleIdentifier(T, typeReference)
+                                  listener: handleNoTypeArguments(or)
+                                  listener: handleType(T, null)
+                                  listener: endIsOperatorType(is)
+                                  listener: handleIsOperator(is, !)
+                                  skipChainedAsIsOperators(T)
+                                rewriter()
+                                parsePrecedenceExpression(||, 6, true)
+                                  parseUnaryExpression(||, true)
+                                    parsePrimary(||, expression)
+                                      parseSend(||, expression)
+                                        ensureIdentifier(||, expression)
+                                          reportRecoverableErrorWithToken(), Instance of 'Template<(Token) => Message>')
+                                          rewriter()
+                                        parseArgumentsOpt()
+                            ensureCloseParen(T, ()
+                              rewriter()
+                          listener: handleParenthesizedCondition(()
+                        listener: beginThenStatement(or)
+                        parseStatement())
+                          parseStatementX())
+                            parseExpressionStatementOrDeclarationAfterModifiers(), ), null, null, null, false)
+                              looksLikeLocalFunction(or)
+                              parseExpressionStatement())
+                                parseExpression())
+                                  parsePrecedenceExpression(), 1, true)
+                                    parseUnaryExpression(), true)
+                                      parsePrimary(), expression)
+                                        parseSendOrFunctionLiteral(), expression)
+                                          parseSend(), expression)
+                                            ensureIdentifier(), expression)
+                                              listener: handleIdentifier(or, expression)
+                                            listener: handleNoTypeArguments(})
+                                            parseArgumentsOpt(or)
+                                              listener: handleNoArguments(})
+                                            listener: handleSend(or, })
+                                ensureSemicolon(or)
+                                  reportRecoverableError(or, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], or, or)
+                                  rewriter()
+                                listener: handleExpressionStatement(;)
+                        listener: endThenStatement(;)
+                        listener: endIfStatement(if, null)
+                  notEofOrValue(}, })
+                  listener: endBlockFunctionBody(1, {, })
+                listener: endClassMethod(null, foo, (, null, })
+              listener: endMember()
+            notEofOrValue(}, })
+            listener: endClassOrMixinBody(DeclarationKind.Class, 1, {, })
+          listener: endClassDeclaration(class, })
+  listener: endTopLevelDeclaration()
+  reportAllErrorTokens(UnmatchedToken(())
+    listener: handleErrorToken(UnmatchedToken(())
+    listener: handleRecoverableError(Message[UnmatchedToken, Can't find ')' to match '('., null, {string: ), lexeme: (}], UnmatchedToken((), UnmatchedToken(())
+  listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_45327_prime_1.crash_dart.parser.expect b/pkg/front_end/parser_testcases/error_recovery/issue_45327_prime_1.crash_dart.parser.expect
new file mode 100644
index 0000000..8515a43
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_45327_prime_1.crash_dart.parser.expect
@@ -0,0 +1,15 @@
+NOTICE: Stream was rewritten by parser!
+
+class Foo<T> {
+foo(Object? key) {
+if (key is! T )or
+;}
+}
+
+
+[UnmatchedToken]class[KeywordToken] Foo[StringToken]<[BeginToken]T[StringToken]>[SimpleToken] {[BeginToken]
+foo[StringToken]([BeginToken]Object[StringToken]?[SimpleToken] key[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]key[StringToken] is[KeywordToken]![SimpleToken] T[StringToken] )[SyntheticToken]or[StringToken]
+;[SyntheticToken]}[SimpleToken]
+}[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_45327_prime_1.crash_dart.scanner.expect b/pkg/front_end/parser_testcases/error_recovery/issue_45327_prime_1.crash_dart.scanner.expect
new file mode 100644
index 0000000..b7836d3
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_45327_prime_1.crash_dart.scanner.expect
@@ -0,0 +1,13 @@
+class Foo<T> {
+foo(Object? key) {
+if (key is! T or
+)}
+}
+
+
+[UnmatchedToken]class[KeywordToken] Foo[StringToken]<[BeginToken]T[StringToken]>[SimpleToken] {[BeginToken]
+foo[StringToken]([BeginToken]Object[StringToken]?[SimpleToken] key[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]key[StringToken] is[KeywordToken]![SimpleToken] T[StringToken] or[StringToken]
+)[SyntheticToken]}[SimpleToken]
+}[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/parser_testcases/general/issue_45120.dart b/pkg/front_end/parser_testcases/general/issue_45120.dart
new file mode 100644
index 0000000..bd3974e
--- /dev/null
+++ b/pkg/front_end/parser_testcases/general/issue_45120.dart
@@ -0,0 +1,7 @@
+@A<int>(0)
+typedef F<@A<int>(0) T> = int Function<@A<int>(0) X>(@A<int>(0) int);
+
+void main() {
+  @A<int>(0)
+  void Function<@A<int>(0) X>(@A<int>(0) int y)? f = null;
+}
diff --git a/pkg/front_end/parser_testcases/general/issue_45120.dart.expect b/pkg/front_end/parser_testcases/general/issue_45120.dart.expect
new file mode 100644
index 0000000..1effedc
--- /dev/null
+++ b/pkg/front_end/parser_testcases/general/issue_45120.dart.expect
@@ -0,0 +1,167 @@
+beginCompilationUnit(@)
+  beginMetadataStar(@)
+    beginMetadata(@)
+      handleIdentifier(A, metadataReference)
+      beginTypeArguments(<)
+        handleIdentifier(int, typeReference)
+        handleNoTypeArguments(>)
+        handleType(int, null)
+      endTypeArguments(1, <, >)
+      beginArguments(()
+        handleLiteralInt(0)
+      endArguments(1, (, ))
+    endMetadata(@, null, typedef)
+  endMetadataStar(1)
+  beginUncategorizedTopLevelDeclaration(typedef)
+    beginFunctionTypeAlias(typedef)
+      handleIdentifier(F, typedefDeclaration)
+      beginTypeVariables(<)
+        beginMetadataStar(@)
+          beginMetadata(@)
+            handleIdentifier(A, metadataReference)
+            beginTypeArguments(<)
+              handleIdentifier(int, typeReference)
+              handleNoTypeArguments(>)
+              handleType(int, null)
+            endTypeArguments(1, <, >)
+            beginArguments(()
+              handleLiteralInt(0)
+            endArguments(1, (, ))
+          endMetadata(@, null, T)
+        endMetadataStar(1)
+        handleIdentifier(T, typeVariableDeclaration)
+        beginTypeVariable(T)
+          handleTypeVariablesDefined(T, 1)
+          handleNoType(T)
+        endTypeVariable(>, 0, null, null)
+      endTypeVariables(<, >)
+      beginFunctionType(int)
+        beginTypeVariables(<)
+          beginMetadataStar(@)
+            beginMetadata(@)
+              handleIdentifier(A, metadataReference)
+              beginTypeArguments(<)
+                handleIdentifier(int, typeReference)
+                handleNoTypeArguments(>)
+                handleType(int, null)
+              endTypeArguments(1, <, >)
+              beginArguments(()
+                handleLiteralInt(0)
+              endArguments(1, (, ))
+            endMetadata(@, null, X)
+          endMetadataStar(1)
+          handleIdentifier(X, typeVariableDeclaration)
+          beginTypeVariable(X)
+            handleTypeVariablesDefined(X, 1)
+            handleNoType(X)
+          endTypeVariable(>, 0, null, null)
+        endTypeVariables(<, >)
+        handleIdentifier(int, typeReference)
+        handleNoTypeArguments(Function)
+        handleType(int, null)
+        beginFormalParameters((, MemberKind.GeneralizedFunctionType)
+          beginMetadataStar(@)
+            beginMetadata(@)
+              handleIdentifier(A, metadataReference)
+              beginTypeArguments(<)
+                handleIdentifier(int, typeReference)
+                handleNoTypeArguments(>)
+                handleType(int, null)
+              endTypeArguments(1, <, >)
+              beginArguments(()
+                handleLiteralInt(0)
+              endArguments(1, (, ))
+            endMetadata(@, null, int)
+          endMetadataStar(1)
+          beginFormalParameter(int, MemberKind.GeneralizedFunctionType, null, null, null)
+            handleIdentifier(int, typeReference)
+            handleNoTypeArguments())
+            handleType(int, null)
+            handleNoName())
+            handleFormalParameterWithoutValue())
+          endFormalParameter(null, null, ), null, null, FormalParameterKind.mandatory, MemberKind.GeneralizedFunctionType)
+        endFormalParameters(1, (, ), MemberKind.GeneralizedFunctionType)
+      endFunctionType(Function, null)
+    endFunctionTypeAlias(typedef, =, ;)
+  endTopLevelDeclaration(void)
+  beginMetadataStar(void)
+  endMetadataStar(0)
+  beginTopLevelMember(void)
+    beginTopLevelMethod(;, null)
+      handleVoidKeyword(void)
+      handleIdentifier(main, topLevelFunctionDeclaration)
+      handleNoTypeVariables(()
+      beginFormalParameters((, MemberKind.TopLevelMethod)
+      endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+      handleAsyncModifier(null, null)
+      beginBlockFunctionBody({)
+        beginMetadataStar(@)
+          beginMetadata(@)
+            handleIdentifier(A, metadataReference)
+            beginTypeArguments(<)
+              handleIdentifier(int, typeReference)
+              handleNoTypeArguments(>)
+              handleType(int, null)
+            endTypeArguments(1, <, >)
+            beginArguments(()
+              handleLiteralInt(0)
+            endArguments(1, (, ))
+          endMetadata(@, null, void)
+        endMetadataStar(1)
+        beginFunctionType(void)
+          beginTypeVariables(<)
+            beginMetadataStar(@)
+              beginMetadata(@)
+                handleIdentifier(A, metadataReference)
+                beginTypeArguments(<)
+                  handleIdentifier(int, typeReference)
+                  handleNoTypeArguments(>)
+                  handleType(int, null)
+                endTypeArguments(1, <, >)
+                beginArguments(()
+                  handleLiteralInt(0)
+                endArguments(1, (, ))
+              endMetadata(@, null, X)
+            endMetadataStar(1)
+            handleIdentifier(X, typeVariableDeclaration)
+            beginTypeVariable(X)
+              handleTypeVariablesDefined(X, 1)
+              handleNoType(X)
+            endTypeVariable(>, 0, null, null)
+          endTypeVariables(<, >)
+          handleVoidKeyword(void)
+          beginFormalParameters((, MemberKind.GeneralizedFunctionType)
+            beginMetadataStar(@)
+              beginMetadata(@)
+                handleIdentifier(A, metadataReference)
+                beginTypeArguments(<)
+                  handleIdentifier(int, typeReference)
+                  handleNoTypeArguments(>)
+                  handleType(int, null)
+                endTypeArguments(1, <, >)
+                beginArguments(()
+                  handleLiteralInt(0)
+                endArguments(1, (, ))
+              endMetadata(@, null, int)
+            endMetadataStar(1)
+            beginFormalParameter(int, MemberKind.GeneralizedFunctionType, null, null, null)
+              handleIdentifier(int, typeReference)
+              handleNoTypeArguments(y)
+              handleType(int, null)
+              handleIdentifier(y, formalParameterDeclaration)
+              handleFormalParameterWithoutValue())
+            endFormalParameter(null, null, y, null, null, FormalParameterKind.mandatory, MemberKind.GeneralizedFunctionType)
+          endFormalParameters(1, (, ), MemberKind.GeneralizedFunctionType)
+        endFunctionType(Function, ?)
+        beginVariablesDeclaration(f, null, null)
+          handleIdentifier(f, localVariableDeclaration)
+          beginInitializedIdentifier(f)
+            beginVariableInitializer(=)
+              handleLiteralNull(null)
+            endVariableInitializer(=)
+          endInitializedIdentifier(f)
+        endVariablesDeclaration(1, ;)
+      endBlockFunctionBody(1, {, })
+    endTopLevelMethod(void, null, })
+  endTopLevelDeclaration()
+endCompilationUnit(2, )
diff --git a/pkg/front_end/parser_testcases/general/issue_45120.dart.intertwined.expect b/pkg/front_end/parser_testcases/general/issue_45120.dart.intertwined.expect
new file mode 100644
index 0000000..63f2c9a
--- /dev/null
+++ b/pkg/front_end/parser_testcases/general/issue_45120.dart.intertwined.expect
@@ -0,0 +1,301 @@
+parseUnit(@)
+  skipErrorTokens(@)
+  listener: beginCompilationUnit(@)
+  syntheticPreviousToken(@)
+  parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+    parseMetadataStar()
+      listener: beginMetadataStar(@)
+      parseMetadata()
+        listener: beginMetadata(@)
+        ensureIdentifier(@, metadataReference)
+          listener: handleIdentifier(A, metadataReference)
+        parseQualifiedRestOpt(A, metadataContinuation)
+        listener: beginTypeArguments(<)
+        listener: handleIdentifier(int, typeReference)
+        listener: handleNoTypeArguments(>)
+        listener: handleType(int, null)
+        listener: endTypeArguments(1, <, >)
+        parseArgumentsOpt(>)
+          parseArguments(>)
+            parseArgumentsRest(()
+              listener: beginArguments(()
+              parseExpression(()
+                parsePrecedenceExpression((, 1, true)
+                  parseUnaryExpression((, true)
+                    parsePrimary((, expression)
+                      parseLiteralInt(()
+                        listener: handleLiteralInt(0)
+              listener: endArguments(1, (, ))
+        listener: endMetadata(@, null, typedef)
+      listener: endMetadataStar(1)
+    parseTopLevelKeywordDeclaration(), typedef, Instance of 'DirectiveContext')
+      parseTopLevelKeywordModifiers(), typedef)
+      parseTypedef(typedef)
+        listener: beginUncategorizedTopLevelDeclaration(typedef)
+        listener: beginFunctionTypeAlias(typedef)
+        ensureIdentifierPotentiallyRecovered(typedef, typedefDeclaration, true)
+          listener: handleIdentifier(F, typedefDeclaration)
+        listener: beginTypeVariables(<)
+        parseMetadataStar(<)
+          listener: beginMetadataStar(@)
+          parseMetadata(<)
+            listener: beginMetadata(@)
+            ensureIdentifier(@, metadataReference)
+              listener: handleIdentifier(A, metadataReference)
+            parseQualifiedRestOpt(A, metadataContinuation)
+            listener: beginTypeArguments(<)
+            listener: handleIdentifier(int, typeReference)
+            listener: handleNoTypeArguments(>)
+            listener: handleType(int, null)
+            listener: endTypeArguments(1, <, >)
+            parseArgumentsOpt(>)
+              parseArguments(>)
+                parseArgumentsRest(()
+                  listener: beginArguments(()
+                  parseExpression(()
+                    parsePrecedenceExpression((, 1, true)
+                      parseUnaryExpression((, true)
+                        parsePrimary((, expression)
+                          parseLiteralInt(()
+                            listener: handleLiteralInt(0)
+                  listener: endArguments(1, (, ))
+            listener: endMetadata(@, null, T)
+          listener: endMetadataStar(1)
+        ensureIdentifier(), typeVariableDeclaration)
+          listener: handleIdentifier(T, typeVariableDeclaration)
+        listener: beginTypeVariable(T)
+        listener: handleTypeVariablesDefined(T, 1)
+        listener: handleNoType(T)
+        listener: endTypeVariable(>, 0, null, null)
+        listener: endTypeVariables(<, >)
+        listener: beginFunctionType(int)
+        listener: beginTypeVariables(<)
+        parseMetadataStar(<)
+          listener: beginMetadataStar(@)
+          parseMetadata(<)
+            listener: beginMetadata(@)
+            ensureIdentifier(@, metadataReference)
+              listener: handleIdentifier(A, metadataReference)
+            parseQualifiedRestOpt(A, metadataContinuation)
+            listener: beginTypeArguments(<)
+            listener: handleIdentifier(int, typeReference)
+            listener: handleNoTypeArguments(>)
+            listener: handleType(int, null)
+            listener: endTypeArguments(1, <, >)
+            parseArgumentsOpt(>)
+              parseArguments(>)
+                parseArgumentsRest(()
+                  listener: beginArguments(()
+                  parseExpression(()
+                    parsePrecedenceExpression((, 1, true)
+                      parseUnaryExpression((, true)
+                        parsePrimary((, expression)
+                          parseLiteralInt(()
+                            listener: handleLiteralInt(0)
+                  listener: endArguments(1, (, ))
+            listener: endMetadata(@, null, X)
+          listener: endMetadataStar(1)
+        ensureIdentifier(), typeVariableDeclaration)
+          listener: handleIdentifier(X, typeVariableDeclaration)
+        listener: beginTypeVariable(X)
+        listener: handleTypeVariablesDefined(X, 1)
+        listener: handleNoType(X)
+        listener: endTypeVariable(>, 0, null, null)
+        listener: endTypeVariables(<, >)
+        ensureIdentifier(=, typeReference)
+          listener: handleIdentifier(int, typeReference)
+        listener: handleNoTypeArguments(Function)
+        listener: handleType(int, null)
+        parseFormalParametersRequiredOpt(>, MemberKind.GeneralizedFunctionType)
+          parseFormalParametersRest((, MemberKind.GeneralizedFunctionType)
+            listener: beginFormalParameters((, MemberKind.GeneralizedFunctionType)
+            parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.GeneralizedFunctionType)
+              parseMetadataStar(()
+                listener: beginMetadataStar(@)
+                parseMetadata(()
+                  listener: beginMetadata(@)
+                  ensureIdentifier(@, metadataReference)
+                    listener: handleIdentifier(A, metadataReference)
+                  parseQualifiedRestOpt(A, metadataContinuation)
+                  listener: beginTypeArguments(<)
+                  listener: handleIdentifier(int, typeReference)
+                  listener: handleNoTypeArguments(>)
+                  listener: handleType(int, null)
+                  listener: endTypeArguments(1, <, >)
+                  parseArgumentsOpt(>)
+                    parseArguments(>)
+                      parseArgumentsRest(()
+                        listener: beginArguments(()
+                        parseExpression(()
+                          parsePrecedenceExpression((, 1, true)
+                            parseUnaryExpression((, true)
+                              parsePrimary((, expression)
+                                parseLiteralInt(()
+                                  listener: handleLiteralInt(0)
+                        listener: endArguments(1, (, ))
+                  listener: endMetadata(@, null, int)
+                listener: endMetadataStar(1)
+              listener: beginFormalParameter(int, MemberKind.GeneralizedFunctionType, null, null, null)
+              listener: handleIdentifier(int, typeReference)
+              listener: handleNoTypeArguments())
+              listener: handleType(int, null)
+              listener: handleNoName())
+              listener: handleFormalParameterWithoutValue())
+              listener: endFormalParameter(null, null, ), null, null, FormalParameterKind.mandatory, MemberKind.GeneralizedFunctionType)
+            listener: endFormalParameters(1, (, ), MemberKind.GeneralizedFunctionType)
+        listener: endFunctionType(Function, null)
+        ensureSemicolon())
+        listener: endFunctionTypeAlias(typedef, =, ;)
+  listener: endTopLevelDeclaration(void)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(void)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl(;)
+      listener: beginTopLevelMember(void)
+      parseTopLevelMethod(;, null, ;, Instance of 'VoidType', null, main, false)
+        listener: beginTopLevelMethod(;, null)
+        listener: handleVoidKeyword(void)
+        ensureIdentifierPotentiallyRecovered(void, topLevelFunctionDeclaration, false)
+          listener: handleIdentifier(main, topLevelFunctionDeclaration)
+        parseMethodTypeVar(main)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(main, main, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(main, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+        parseAsyncModifierOpt())
+          listener: handleAsyncModifier(null, null)
+          inPlainSync()
+        parseFunctionBody(), false, false)
+          listener: beginBlockFunctionBody({)
+          notEofOrValue(}, @)
+          parseStatement({)
+            parseStatementX({)
+              parseExpressionStatementOrDeclaration({, false)
+                parseMetadataStar({)
+                  listener: beginMetadataStar(@)
+                  parseMetadata({)
+                    listener: beginMetadata(@)
+                    ensureIdentifier(@, metadataReference)
+                      listener: handleIdentifier(A, metadataReference)
+                    parseQualifiedRestOpt(A, metadataContinuation)
+                    listener: beginTypeArguments(<)
+                    listener: handleIdentifier(int, typeReference)
+                    listener: handleNoTypeArguments(>)
+                    listener: handleType(int, null)
+                    listener: endTypeArguments(1, <, >)
+                    parseArgumentsOpt(>)
+                      parseArguments(>)
+                        parseArgumentsRest(()
+                          listener: beginArguments(()
+                          parseExpression(()
+                            parsePrecedenceExpression((, 1, true)
+                              parseUnaryExpression((, true)
+                                parsePrimary((, expression)
+                                  parseLiteralInt(()
+                                    listener: handleLiteralInt(0)
+                          listener: endArguments(1, (, ))
+                    listener: endMetadata(@, null, void)
+                  listener: endMetadataStar(1)
+                parseExpressionStatementOrDeclarationAfterModifiers(), {, null, null, null, false)
+                  looksLikeLocalFunction(f)
+                  listener: beginFunctionType(void)
+                  listener: beginTypeVariables(<)
+                  parseMetadataStar(<)
+                    listener: beginMetadataStar(@)
+                    parseMetadata(<)
+                      listener: beginMetadata(@)
+                      ensureIdentifier(@, metadataReference)
+                        listener: handleIdentifier(A, metadataReference)
+                      parseQualifiedRestOpt(A, metadataContinuation)
+                      listener: beginTypeArguments(<)
+                      listener: handleIdentifier(int, typeReference)
+                      listener: handleNoTypeArguments(>)
+                      listener: handleType(int, null)
+                      listener: endTypeArguments(1, <, >)
+                      parseArgumentsOpt(>)
+                        parseArguments(>)
+                          parseArgumentsRest(()
+                            listener: beginArguments(()
+                            parseExpression(()
+                              parsePrecedenceExpression((, 1, true)
+                                parseUnaryExpression((, true)
+                                  parsePrimary((, expression)
+                                    parseLiteralInt(()
+                                      listener: handleLiteralInt(0)
+                            listener: endArguments(1, (, ))
+                      listener: endMetadata(@, null, X)
+                    listener: endMetadataStar(1)
+                  ensureIdentifier(), typeVariableDeclaration)
+                    listener: handleIdentifier(X, typeVariableDeclaration)
+                  listener: beginTypeVariable(X)
+                  listener: handleTypeVariablesDefined(X, 1)
+                  listener: handleNoType(X)
+                  listener: endTypeVariable(>, 0, null, null)
+                  listener: endTypeVariables(<, >)
+                  listener: handleVoidKeyword(void)
+                  parseFormalParametersRequiredOpt(>, MemberKind.GeneralizedFunctionType)
+                    parseFormalParametersRest((, MemberKind.GeneralizedFunctionType)
+                      listener: beginFormalParameters((, MemberKind.GeneralizedFunctionType)
+                      parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.GeneralizedFunctionType)
+                        parseMetadataStar(()
+                          listener: beginMetadataStar(@)
+                          parseMetadata(()
+                            listener: beginMetadata(@)
+                            ensureIdentifier(@, metadataReference)
+                              listener: handleIdentifier(A, metadataReference)
+                            parseQualifiedRestOpt(A, metadataContinuation)
+                            listener: beginTypeArguments(<)
+                            listener: handleIdentifier(int, typeReference)
+                            listener: handleNoTypeArguments(>)
+                            listener: handleType(int, null)
+                            listener: endTypeArguments(1, <, >)
+                            parseArgumentsOpt(>)
+                              parseArguments(>)
+                                parseArgumentsRest(()
+                                  listener: beginArguments(()
+                                  parseExpression(()
+                                    parsePrecedenceExpression((, 1, true)
+                                      parseUnaryExpression((, true)
+                                        parsePrimary((, expression)
+                                          parseLiteralInt(()
+                                            listener: handleLiteralInt(0)
+                                  listener: endArguments(1, (, ))
+                            listener: endMetadata(@, null, int)
+                          listener: endMetadataStar(1)
+                        listener: beginFormalParameter(int, MemberKind.GeneralizedFunctionType, null, null, null)
+                        listener: handleIdentifier(int, typeReference)
+                        listener: handleNoTypeArguments(y)
+                        listener: handleType(int, null)
+                        ensureIdentifier(int, formalParameterDeclaration)
+                          listener: handleIdentifier(y, formalParameterDeclaration)
+                        listener: handleFormalParameterWithoutValue())
+                        listener: endFormalParameter(null, null, y, null, null, FormalParameterKind.mandatory, MemberKind.GeneralizedFunctionType)
+                      listener: endFormalParameters(1, (, ), MemberKind.GeneralizedFunctionType)
+                  listener: endFunctionType(Function, ?)
+                  listener: beginVariablesDeclaration(f, null, null)
+                  parseVariablesDeclarationRest(?, true)
+                    parseOptionallyInitializedIdentifier(?)
+                      ensureIdentifier(?, localVariableDeclaration)
+                        listener: handleIdentifier(f, localVariableDeclaration)
+                      listener: beginInitializedIdentifier(f)
+                      parseVariableInitializerOpt(f)
+                        listener: beginVariableInitializer(=)
+                        parseExpression(=)
+                          parsePrecedenceExpression(=, 1, true)
+                            parseUnaryExpression(=, true)
+                              parsePrimary(=, expression)
+                                parseLiteralNull(=)
+                                  listener: handleLiteralNull(null)
+                        listener: endVariableInitializer(=)
+                      listener: endInitializedIdentifier(f)
+                    ensureSemicolon(null)
+                    listener: endVariablesDeclaration(1, ;)
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(1, {, })
+        listener: endTopLevelMethod(void, null, })
+  listener: endTopLevelDeclaration()
+  reportAllErrorTokens(@)
+  listener: endCompilationUnit(2, )
diff --git a/pkg/front_end/parser_testcases/general/issue_45120.dart.parser.expect b/pkg/front_end/parser_testcases/general/issue_45120.dart.parser.expect
new file mode 100644
index 0000000..954f749
--- /dev/null
+++ b/pkg/front_end/parser_testcases/general/issue_45120.dart.parser.expect
@@ -0,0 +1,17 @@
+@A<int>(0)
+typedef F<@A<int>(0) T> = int Function<@A<int>(0) X>(@A<int>(0) int);
+
+void main() {
+@A<int>(0)
+void Function<@A<int>(0) X>(@A<int>(0) int y)? f = null;
+}
+
+
+@[SimpleToken]A[StringToken]<[BeginToken]int[StringToken]>[SimpleToken]([BeginToken]0[StringToken])[SimpleToken]
+typedef[KeywordToken] F[StringToken]<[BeginToken]@[SimpleToken]A[StringToken]<[BeginToken]int[StringToken]>[SimpleToken]([BeginToken]0[StringToken])[SimpleToken] T[StringToken]>[SimpleToken] =[SimpleToken] int[StringToken] Function[KeywordToken]<[BeginToken]@[SimpleToken]A[StringToken]<[BeginToken]int[StringToken]>[SimpleToken]([BeginToken]0[StringToken])[SimpleToken] X[StringToken]>[SimpleToken]([BeginToken]@[SimpleToken]A[StringToken]<[BeginToken]int[StringToken]>[SimpleToken]([BeginToken]0[StringToken])[SimpleToken] int[StringToken])[SimpleToken];[SimpleToken]
+
+void[KeywordToken] main[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
+@[SimpleToken]A[StringToken]<[BeginToken]int[StringToken]>[SimpleToken]([BeginToken]0[StringToken])[SimpleToken]
+void[KeywordToken] Function[KeywordToken]<[BeginToken]@[SimpleToken]A[StringToken]<[BeginToken]int[StringToken]>[SimpleToken]([BeginToken]0[StringToken])[SimpleToken] X[StringToken]>[SimpleToken]([BeginToken]@[SimpleToken]A[StringToken]<[BeginToken]int[StringToken]>[SimpleToken]([BeginToken]0[StringToken])[SimpleToken] int[StringToken] y[StringToken])[SimpleToken]?[SimpleToken] f[StringToken] =[SimpleToken] null[KeywordToken];[SimpleToken]
+}[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/parser_testcases/general/issue_45120.dart.scanner.expect b/pkg/front_end/parser_testcases/general/issue_45120.dart.scanner.expect
new file mode 100644
index 0000000..954f749
--- /dev/null
+++ b/pkg/front_end/parser_testcases/general/issue_45120.dart.scanner.expect
@@ -0,0 +1,17 @@
+@A<int>(0)
+typedef F<@A<int>(0) T> = int Function<@A<int>(0) X>(@A<int>(0) int);
+
+void main() {
+@A<int>(0)
+void Function<@A<int>(0) X>(@A<int>(0) int y)? f = null;
+}
+
+
+@[SimpleToken]A[StringToken]<[BeginToken]int[StringToken]>[SimpleToken]([BeginToken]0[StringToken])[SimpleToken]
+typedef[KeywordToken] F[StringToken]<[BeginToken]@[SimpleToken]A[StringToken]<[BeginToken]int[StringToken]>[SimpleToken]([BeginToken]0[StringToken])[SimpleToken] T[StringToken]>[SimpleToken] =[SimpleToken] int[StringToken] Function[KeywordToken]<[BeginToken]@[SimpleToken]A[StringToken]<[BeginToken]int[StringToken]>[SimpleToken]([BeginToken]0[StringToken])[SimpleToken] X[StringToken]>[SimpleToken]([BeginToken]@[SimpleToken]A[StringToken]<[BeginToken]int[StringToken]>[SimpleToken]([BeginToken]0[StringToken])[SimpleToken] int[StringToken])[SimpleToken];[SimpleToken]
+
+void[KeywordToken] main[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
+@[SimpleToken]A[StringToken]<[BeginToken]int[StringToken]>[SimpleToken]([BeginToken]0[StringToken])[SimpleToken]
+void[KeywordToken] Function[KeywordToken]<[BeginToken]@[SimpleToken]A[StringToken]<[BeginToken]int[StringToken]>[SimpleToken]([BeginToken]0[StringToken])[SimpleToken] X[StringToken]>[SimpleToken]([BeginToken]@[SimpleToken]A[StringToken]<[BeginToken]int[StringToken]>[SimpleToken]([BeginToken]0[StringToken])[SimpleToken] int[StringToken] y[StringToken])[SimpleToken]?[SimpleToken] f[StringToken] =[SimpleToken] null[KeywordToken];[SimpleToken]
+}[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/parser_testcases/general/metadata.dart b/pkg/front_end/parser_testcases/general/metadata.dart
new file mode 100644
index 0000000..53003ad
--- /dev/null
+++ b/pkg/front_end/parser_testcases/general/metadata.dart
@@ -0,0 +1,40 @@
+// These 10 should be OK.
+@abstract
+@foo.abstract
+@foo.bar.abstract
+@foo("hello")
+@foo.abstract("hello")
+@foo.bar.abstract("hello")
+@foo<int>("hello")
+@foo<int>.abstract("hello")
+@foo.bar<int>("hello")
+@foo.bar<int>.abstract("hello")
+class X {}
+
+// They should also be OK in various places for instance:
+typedef F<@abstract T> = int Function<@abstract X>(@abstract int);
+typedef F<@foo.abstract T> = int Function<@foo.abstract X>(@foo.abstract int);
+typedef F<@foo.bar.abstract T> = int Function<@foo.bar.abstract X>(@foo.bar.abstract int);
+typedef F<@foo("hello") T> = int Function<@foo("hello") X>(@foo("hello") int);
+typedef F<@foo.abstract("hello") T> = int Function<@foo.abstract("hello") X>(@foo.abstract("hello") int);
+typedef F<@foo.bar.abstract("hello") T> = int Function<@foo.bar.abstract("hello") X>(@foo.bar.abstract("hello") int);
+typedef F<@foo<int>("hello") T> = int Function<@foo<int>("hello") X>(@foo<int>("hello") int);
+typedef F<@foo<int>.abstract("hello") T> = int Function<@foo<int>.abstract("hello") X>(@foo<int>.abstract("hello") int);
+typedef F<@foo.bar<int>("hello") T> = int Function<@foo.bar<int>("hello") X>(@foo.bar<int>("hello") int);
+typedef F<@foo.bar<int>.abstract("hello") T> = int Function<@foo.bar<int>.abstract("hello") X>(@foo.bar<int>.abstract("hello") int);
+
+// These 9 should fail because they start with a built in which is an
+// identifier but not a typeIdentifier.
+// We don't necessarily expect that parser to give the error though, the further
+// pipeline will give an error because there's no class, variable etc with that
+// name.
+@abstract.abstract
+@abstract.bar.abstract
+@abstract("hello")
+@abstract.abstract("hello")
+@abstract.bar.abstract("hello")
+@abstract<int>("hello")
+@abstract<int>.abstract("hello")
+@abstract.bar<int>("hello")
+@abstract.bar<int>.abstract("hello")
+class Y {}
\ No newline at end of file
diff --git a/pkg/front_end/parser_testcases/general/metadata.dart.expect b/pkg/front_end/parser_testcases/general/metadata.dart.expect
new file mode 100644
index 0000000..d342b49
--- /dev/null
+++ b/pkg/front_end/parser_testcases/general/metadata.dart.expect
@@ -0,0 +1,952 @@
+beginCompilationUnit(@)
+  beginMetadataStar(@)
+    beginMetadata(@)
+      handleIdentifier(abstract, metadataReference)
+      handleNoTypeArguments(@)
+      handleNoArguments(@)
+    endMetadata(@, null, @)
+    beginMetadata(@)
+      handleIdentifier(foo, metadataReference)
+      handleIdentifier(abstract, metadataContinuation)
+      handleQualified(.)
+      handleNoTypeArguments(@)
+      handleNoArguments(@)
+    endMetadata(@, null, @)
+    beginMetadata(@)
+      handleIdentifier(foo, metadataReference)
+      handleIdentifier(bar, metadataContinuation)
+      handleQualified(.)
+      handleNoTypeArguments(.)
+      handleIdentifier(abstract, metadataContinuationAfterTypeArguments)
+      handleNoArguments(@)
+    endMetadata(@, ., @)
+    beginMetadata(@)
+      handleIdentifier(foo, metadataReference)
+      handleNoTypeArguments(()
+      beginArguments(()
+        beginLiteralString("hello")
+        endLiteralString(0, ))
+      endArguments(1, (, ))
+    endMetadata(@, null, @)
+    beginMetadata(@)
+      handleIdentifier(foo, metadataReference)
+      handleIdentifier(abstract, metadataContinuation)
+      handleQualified(.)
+      handleNoTypeArguments(()
+      beginArguments(()
+        beginLiteralString("hello")
+        endLiteralString(0, ))
+      endArguments(1, (, ))
+    endMetadata(@, null, @)
+    beginMetadata(@)
+      handleIdentifier(foo, metadataReference)
+      handleIdentifier(bar, metadataContinuation)
+      handleQualified(.)
+      handleNoTypeArguments(.)
+      handleIdentifier(abstract, metadataContinuationAfterTypeArguments)
+      beginArguments(()
+        beginLiteralString("hello")
+        endLiteralString(0, ))
+      endArguments(1, (, ))
+    endMetadata(@, ., @)
+    beginMetadata(@)
+      handleIdentifier(foo, metadataReference)
+      beginTypeArguments(<)
+        handleIdentifier(int, typeReference)
+        handleNoTypeArguments(>)
+        handleType(int, null)
+      endTypeArguments(1, <, >)
+      beginArguments(()
+        beginLiteralString("hello")
+        endLiteralString(0, ))
+      endArguments(1, (, ))
+    endMetadata(@, null, @)
+    beginMetadata(@)
+      handleIdentifier(foo, metadataReference)
+      beginTypeArguments(<)
+        handleIdentifier(int, typeReference)
+        handleNoTypeArguments(>)
+        handleType(int, null)
+      endTypeArguments(1, <, >)
+      handleIdentifier(abstract, metadataContinuationAfterTypeArguments)
+      beginArguments(()
+        beginLiteralString("hello")
+        endLiteralString(0, ))
+      endArguments(1, (, ))
+    endMetadata(@, ., @)
+    beginMetadata(@)
+      handleIdentifier(foo, metadataReference)
+      handleIdentifier(bar, metadataContinuation)
+      handleQualified(.)
+      beginTypeArguments(<)
+        handleIdentifier(int, typeReference)
+        handleNoTypeArguments(>)
+        handleType(int, null)
+      endTypeArguments(1, <, >)
+      beginArguments(()
+        beginLiteralString("hello")
+        endLiteralString(0, ))
+      endArguments(1, (, ))
+    endMetadata(@, null, @)
+    beginMetadata(@)
+      handleIdentifier(foo, metadataReference)
+      handleIdentifier(bar, metadataContinuation)
+      handleQualified(.)
+      beginTypeArguments(<)
+        handleIdentifier(int, typeReference)
+        handleNoTypeArguments(>)
+        handleType(int, null)
+      endTypeArguments(1, <, >)
+      handleIdentifier(abstract, metadataContinuationAfterTypeArguments)
+      beginArguments(()
+        beginLiteralString("hello")
+        endLiteralString(0, ))
+      endArguments(1, (, ))
+    endMetadata(@, ., class)
+  endMetadataStar(10)
+  beginClassOrNamedMixinApplicationPrelude(class)
+    handleIdentifier(X, classOrMixinDeclaration)
+    handleNoTypeVariables({)
+    beginClassDeclaration(class, null, X)
+      handleNoType(X)
+      handleClassExtends(null, 1)
+      handleClassNoWithClause()
+      handleClassOrMixinImplements(null, 0)
+      handleClassHeader(class, class, null)
+      beginClassOrMixinBody(DeclarationKind.Class, {)
+      endClassOrMixinBody(DeclarationKind.Class, 0, {, })
+    endClassDeclaration(class, })
+  endTopLevelDeclaration(typedef)
+  beginMetadataStar(typedef)
+  endMetadataStar(0)
+  beginUncategorizedTopLevelDeclaration(typedef)
+    beginFunctionTypeAlias(typedef)
+      handleIdentifier(F, typedefDeclaration)
+      beginTypeVariables(<)
+        beginMetadataStar(@)
+          beginMetadata(@)
+            handleIdentifier(abstract, metadataReference)
+            handleNoTypeArguments(T)
+            handleNoArguments(T)
+          endMetadata(@, null, T)
+        endMetadataStar(1)
+        handleIdentifier(T, typeVariableDeclaration)
+        beginTypeVariable(T)
+          handleTypeVariablesDefined(T, 1)
+          handleNoType(T)
+        endTypeVariable(>, 0, null, null)
+      endTypeVariables(<, >)
+      beginFunctionType(int)
+        beginTypeVariables(<)
+          beginMetadataStar(@)
+            beginMetadata(@)
+              handleIdentifier(abstract, metadataReference)
+              handleNoTypeArguments(X)
+              handleNoArguments(X)
+            endMetadata(@, null, X)
+          endMetadataStar(1)
+          handleIdentifier(X, typeVariableDeclaration)
+          beginTypeVariable(X)
+            handleTypeVariablesDefined(X, 1)
+            handleNoType(X)
+          endTypeVariable(>, 0, null, null)
+        endTypeVariables(<, >)
+        handleIdentifier(int, typeReference)
+        handleNoTypeArguments(Function)
+        handleType(int, null)
+        beginFormalParameters((, MemberKind.GeneralizedFunctionType)
+          beginMetadataStar(@)
+            beginMetadata(@)
+              handleIdentifier(abstract, metadataReference)
+              handleNoTypeArguments(int)
+              handleNoArguments(int)
+            endMetadata(@, null, int)
+          endMetadataStar(1)
+          beginFormalParameter(int, MemberKind.GeneralizedFunctionType, null, null, null)
+            handleIdentifier(int, typeReference)
+            handleNoTypeArguments())
+            handleType(int, null)
+            handleNoName())
+            handleFormalParameterWithoutValue())
+          endFormalParameter(null, null, ), null, null, FormalParameterKind.mandatory, MemberKind.GeneralizedFunctionType)
+        endFormalParameters(1, (, ), MemberKind.GeneralizedFunctionType)
+      endFunctionType(Function, null)
+    endFunctionTypeAlias(typedef, =, ;)
+  endTopLevelDeclaration(typedef)
+  beginMetadataStar(typedef)
+  endMetadataStar(0)
+  beginUncategorizedTopLevelDeclaration(typedef)
+    beginFunctionTypeAlias(typedef)
+      handleIdentifier(F, typedefDeclaration)
+      beginTypeVariables(<)
+        beginMetadataStar(@)
+          beginMetadata(@)
+            handleIdentifier(foo, metadataReference)
+            handleIdentifier(abstract, metadataContinuation)
+            handleQualified(.)
+            handleNoTypeArguments(T)
+            handleNoArguments(T)
+          endMetadata(@, null, T)
+        endMetadataStar(1)
+        handleIdentifier(T, typeVariableDeclaration)
+        beginTypeVariable(T)
+          handleTypeVariablesDefined(T, 1)
+          handleNoType(T)
+        endTypeVariable(>, 0, null, null)
+      endTypeVariables(<, >)
+      beginFunctionType(int)
+        beginTypeVariables(<)
+          beginMetadataStar(@)
+            beginMetadata(@)
+              handleIdentifier(foo, metadataReference)
+              handleIdentifier(abstract, metadataContinuation)
+              handleQualified(.)
+              handleNoTypeArguments(X)
+              handleNoArguments(X)
+            endMetadata(@, null, X)
+          endMetadataStar(1)
+          handleIdentifier(X, typeVariableDeclaration)
+          beginTypeVariable(X)
+            handleTypeVariablesDefined(X, 1)
+            handleNoType(X)
+          endTypeVariable(>, 0, null, null)
+        endTypeVariables(<, >)
+        handleIdentifier(int, typeReference)
+        handleNoTypeArguments(Function)
+        handleType(int, null)
+        beginFormalParameters((, MemberKind.GeneralizedFunctionType)
+          beginMetadataStar(@)
+            beginMetadata(@)
+              handleIdentifier(foo, metadataReference)
+              handleIdentifier(abstract, metadataContinuation)
+              handleQualified(.)
+              handleNoTypeArguments(int)
+              handleNoArguments(int)
+            endMetadata(@, null, int)
+          endMetadataStar(1)
+          beginFormalParameter(int, MemberKind.GeneralizedFunctionType, null, null, null)
+            handleIdentifier(int, typeReference)
+            handleNoTypeArguments())
+            handleType(int, null)
+            handleNoName())
+            handleFormalParameterWithoutValue())
+          endFormalParameter(null, null, ), null, null, FormalParameterKind.mandatory, MemberKind.GeneralizedFunctionType)
+        endFormalParameters(1, (, ), MemberKind.GeneralizedFunctionType)
+      endFunctionType(Function, null)
+    endFunctionTypeAlias(typedef, =, ;)
+  endTopLevelDeclaration(typedef)
+  beginMetadataStar(typedef)
+  endMetadataStar(0)
+  beginUncategorizedTopLevelDeclaration(typedef)
+    beginFunctionTypeAlias(typedef)
+      handleIdentifier(F, typedefDeclaration)
+      beginTypeVariables(<)
+        beginMetadataStar(@)
+          beginMetadata(@)
+            handleIdentifier(foo, metadataReference)
+            handleIdentifier(bar, metadataContinuation)
+            handleQualified(.)
+            handleNoTypeArguments(.)
+            handleIdentifier(abstract, metadataContinuationAfterTypeArguments)
+            handleNoArguments(T)
+          endMetadata(@, ., T)
+        endMetadataStar(1)
+        handleIdentifier(T, typeVariableDeclaration)
+        beginTypeVariable(T)
+          handleTypeVariablesDefined(T, 1)
+          handleNoType(T)
+        endTypeVariable(>, 0, null, null)
+      endTypeVariables(<, >)
+      beginFunctionType(int)
+        beginTypeVariables(<)
+          beginMetadataStar(@)
+            beginMetadata(@)
+              handleIdentifier(foo, metadataReference)
+              handleIdentifier(bar, metadataContinuation)
+              handleQualified(.)
+              handleNoTypeArguments(.)
+              handleIdentifier(abstract, metadataContinuationAfterTypeArguments)
+              handleNoArguments(X)
+            endMetadata(@, ., X)
+          endMetadataStar(1)
+          handleIdentifier(X, typeVariableDeclaration)
+          beginTypeVariable(X)
+            handleTypeVariablesDefined(X, 1)
+            handleNoType(X)
+          endTypeVariable(>, 0, null, null)
+        endTypeVariables(<, >)
+        handleIdentifier(int, typeReference)
+        handleNoTypeArguments(Function)
+        handleType(int, null)
+        beginFormalParameters((, MemberKind.GeneralizedFunctionType)
+          beginMetadataStar(@)
+            beginMetadata(@)
+              handleIdentifier(foo, metadataReference)
+              handleIdentifier(bar, metadataContinuation)
+              handleQualified(.)
+              handleNoTypeArguments(.)
+              handleIdentifier(abstract, metadataContinuationAfterTypeArguments)
+              handleNoArguments(int)
+            endMetadata(@, ., int)
+          endMetadataStar(1)
+          beginFormalParameter(int, MemberKind.GeneralizedFunctionType, null, null, null)
+            handleIdentifier(int, typeReference)
+            handleNoTypeArguments())
+            handleType(int, null)
+            handleNoName())
+            handleFormalParameterWithoutValue())
+          endFormalParameter(null, null, ), null, null, FormalParameterKind.mandatory, MemberKind.GeneralizedFunctionType)
+        endFormalParameters(1, (, ), MemberKind.GeneralizedFunctionType)
+      endFunctionType(Function, null)
+    endFunctionTypeAlias(typedef, =, ;)
+  endTopLevelDeclaration(typedef)
+  beginMetadataStar(typedef)
+  endMetadataStar(0)
+  beginUncategorizedTopLevelDeclaration(typedef)
+    beginFunctionTypeAlias(typedef)
+      handleIdentifier(F, typedefDeclaration)
+      beginTypeVariables(<)
+        beginMetadataStar(@)
+          beginMetadata(@)
+            handleIdentifier(foo, metadataReference)
+            handleNoTypeArguments(()
+            beginArguments(()
+              beginLiteralString("hello")
+              endLiteralString(0, ))
+            endArguments(1, (, ))
+          endMetadata(@, null, T)
+        endMetadataStar(1)
+        handleIdentifier(T, typeVariableDeclaration)
+        beginTypeVariable(T)
+          handleTypeVariablesDefined(T, 1)
+          handleNoType(T)
+        endTypeVariable(>, 0, null, null)
+      endTypeVariables(<, >)
+      beginFunctionType(int)
+        beginTypeVariables(<)
+          beginMetadataStar(@)
+            beginMetadata(@)
+              handleIdentifier(foo, metadataReference)
+              handleNoTypeArguments(()
+              beginArguments(()
+                beginLiteralString("hello")
+                endLiteralString(0, ))
+              endArguments(1, (, ))
+            endMetadata(@, null, X)
+          endMetadataStar(1)
+          handleIdentifier(X, typeVariableDeclaration)
+          beginTypeVariable(X)
+            handleTypeVariablesDefined(X, 1)
+            handleNoType(X)
+          endTypeVariable(>, 0, null, null)
+        endTypeVariables(<, >)
+        handleIdentifier(int, typeReference)
+        handleNoTypeArguments(Function)
+        handleType(int, null)
+        beginFormalParameters((, MemberKind.GeneralizedFunctionType)
+          beginMetadataStar(@)
+            beginMetadata(@)
+              handleIdentifier(foo, metadataReference)
+              handleNoTypeArguments(()
+              beginArguments(()
+                beginLiteralString("hello")
+                endLiteralString(0, ))
+              endArguments(1, (, ))
+            endMetadata(@, null, int)
+          endMetadataStar(1)
+          beginFormalParameter(int, MemberKind.GeneralizedFunctionType, null, null, null)
+            handleIdentifier(int, typeReference)
+            handleNoTypeArguments())
+            handleType(int, null)
+            handleNoName())
+            handleFormalParameterWithoutValue())
+          endFormalParameter(null, null, ), null, null, FormalParameterKind.mandatory, MemberKind.GeneralizedFunctionType)
+        endFormalParameters(1, (, ), MemberKind.GeneralizedFunctionType)
+      endFunctionType(Function, null)
+    endFunctionTypeAlias(typedef, =, ;)
+  endTopLevelDeclaration(typedef)
+  beginMetadataStar(typedef)
+  endMetadataStar(0)
+  beginUncategorizedTopLevelDeclaration(typedef)
+    beginFunctionTypeAlias(typedef)
+      handleIdentifier(F, typedefDeclaration)
+      beginTypeVariables(<)
+        beginMetadataStar(@)
+          beginMetadata(@)
+            handleIdentifier(foo, metadataReference)
+            handleIdentifier(abstract, metadataContinuation)
+            handleQualified(.)
+            handleNoTypeArguments(()
+            beginArguments(()
+              beginLiteralString("hello")
+              endLiteralString(0, ))
+            endArguments(1, (, ))
+          endMetadata(@, null, T)
+        endMetadataStar(1)
+        handleIdentifier(T, typeVariableDeclaration)
+        beginTypeVariable(T)
+          handleTypeVariablesDefined(T, 1)
+          handleNoType(T)
+        endTypeVariable(>, 0, null, null)
+      endTypeVariables(<, >)
+      beginFunctionType(int)
+        beginTypeVariables(<)
+          beginMetadataStar(@)
+            beginMetadata(@)
+              handleIdentifier(foo, metadataReference)
+              handleIdentifier(abstract, metadataContinuation)
+              handleQualified(.)
+              handleNoTypeArguments(()
+              beginArguments(()
+                beginLiteralString("hello")
+                endLiteralString(0, ))
+              endArguments(1, (, ))
+            endMetadata(@, null, X)
+          endMetadataStar(1)
+          handleIdentifier(X, typeVariableDeclaration)
+          beginTypeVariable(X)
+            handleTypeVariablesDefined(X, 1)
+            handleNoType(X)
+          endTypeVariable(>, 0, null, null)
+        endTypeVariables(<, >)
+        handleIdentifier(int, typeReference)
+        handleNoTypeArguments(Function)
+        handleType(int, null)
+        beginFormalParameters((, MemberKind.GeneralizedFunctionType)
+          beginMetadataStar(@)
+            beginMetadata(@)
+              handleIdentifier(foo, metadataReference)
+              handleIdentifier(abstract, metadataContinuation)
+              handleQualified(.)
+              handleNoTypeArguments(()
+              beginArguments(()
+                beginLiteralString("hello")
+                endLiteralString(0, ))
+              endArguments(1, (, ))
+            endMetadata(@, null, int)
+          endMetadataStar(1)
+          beginFormalParameter(int, MemberKind.GeneralizedFunctionType, null, null, null)
+            handleIdentifier(int, typeReference)
+            handleNoTypeArguments())
+            handleType(int, null)
+            handleNoName())
+            handleFormalParameterWithoutValue())
+          endFormalParameter(null, null, ), null, null, FormalParameterKind.mandatory, MemberKind.GeneralizedFunctionType)
+        endFormalParameters(1, (, ), MemberKind.GeneralizedFunctionType)
+      endFunctionType(Function, null)
+    endFunctionTypeAlias(typedef, =, ;)
+  endTopLevelDeclaration(typedef)
+  beginMetadataStar(typedef)
+  endMetadataStar(0)
+  beginUncategorizedTopLevelDeclaration(typedef)
+    beginFunctionTypeAlias(typedef)
+      handleIdentifier(F, typedefDeclaration)
+      beginTypeVariables(<)
+        beginMetadataStar(@)
+          beginMetadata(@)
+            handleIdentifier(foo, metadataReference)
+            handleIdentifier(bar, metadataContinuation)
+            handleQualified(.)
+            handleNoTypeArguments(.)
+            handleIdentifier(abstract, metadataContinuationAfterTypeArguments)
+            beginArguments(()
+              beginLiteralString("hello")
+              endLiteralString(0, ))
+            endArguments(1, (, ))
+          endMetadata(@, ., T)
+        endMetadataStar(1)
+        handleIdentifier(T, typeVariableDeclaration)
+        beginTypeVariable(T)
+          handleTypeVariablesDefined(T, 1)
+          handleNoType(T)
+        endTypeVariable(>, 0, null, null)
+      endTypeVariables(<, >)
+      beginFunctionType(int)
+        beginTypeVariables(<)
+          beginMetadataStar(@)
+            beginMetadata(@)
+              handleIdentifier(foo, metadataReference)
+              handleIdentifier(bar, metadataContinuation)
+              handleQualified(.)
+              handleNoTypeArguments(.)
+              handleIdentifier(abstract, metadataContinuationAfterTypeArguments)
+              beginArguments(()
+                beginLiteralString("hello")
+                endLiteralString(0, ))
+              endArguments(1, (, ))
+            endMetadata(@, ., X)
+          endMetadataStar(1)
+          handleIdentifier(X, typeVariableDeclaration)
+          beginTypeVariable(X)
+            handleTypeVariablesDefined(X, 1)
+            handleNoType(X)
+          endTypeVariable(>, 0, null, null)
+        endTypeVariables(<, >)
+        handleIdentifier(int, typeReference)
+        handleNoTypeArguments(Function)
+        handleType(int, null)
+        beginFormalParameters((, MemberKind.GeneralizedFunctionType)
+          beginMetadataStar(@)
+            beginMetadata(@)
+              handleIdentifier(foo, metadataReference)
+              handleIdentifier(bar, metadataContinuation)
+              handleQualified(.)
+              handleNoTypeArguments(.)
+              handleIdentifier(abstract, metadataContinuationAfterTypeArguments)
+              beginArguments(()
+                beginLiteralString("hello")
+                endLiteralString(0, ))
+              endArguments(1, (, ))
+            endMetadata(@, ., int)
+          endMetadataStar(1)
+          beginFormalParameter(int, MemberKind.GeneralizedFunctionType, null, null, null)
+            handleIdentifier(int, typeReference)
+            handleNoTypeArguments())
+            handleType(int, null)
+            handleNoName())
+            handleFormalParameterWithoutValue())
+          endFormalParameter(null, null, ), null, null, FormalParameterKind.mandatory, MemberKind.GeneralizedFunctionType)
+        endFormalParameters(1, (, ), MemberKind.GeneralizedFunctionType)
+      endFunctionType(Function, null)
+    endFunctionTypeAlias(typedef, =, ;)
+  endTopLevelDeclaration(typedef)
+  beginMetadataStar(typedef)
+  endMetadataStar(0)
+  beginUncategorizedTopLevelDeclaration(typedef)
+    beginFunctionTypeAlias(typedef)
+      handleIdentifier(F, typedefDeclaration)
+      beginTypeVariables(<)
+        beginMetadataStar(@)
+          beginMetadata(@)
+            handleIdentifier(foo, metadataReference)
+            beginTypeArguments(<)
+              handleIdentifier(int, typeReference)
+              handleNoTypeArguments(>)
+              handleType(int, null)
+            endTypeArguments(1, <, >)
+            beginArguments(()
+              beginLiteralString("hello")
+              endLiteralString(0, ))
+            endArguments(1, (, ))
+          endMetadata(@, null, T)
+        endMetadataStar(1)
+        handleIdentifier(T, typeVariableDeclaration)
+        beginTypeVariable(T)
+          handleTypeVariablesDefined(T, 1)
+          handleNoType(T)
+        endTypeVariable(>, 0, null, null)
+      endTypeVariables(<, >)
+      beginFunctionType(int)
+        beginTypeVariables(<)
+          beginMetadataStar(@)
+            beginMetadata(@)
+              handleIdentifier(foo, metadataReference)
+              beginTypeArguments(<)
+                handleIdentifier(int, typeReference)
+                handleNoTypeArguments(>)
+                handleType(int, null)
+              endTypeArguments(1, <, >)
+              beginArguments(()
+                beginLiteralString("hello")
+                endLiteralString(0, ))
+              endArguments(1, (, ))
+            endMetadata(@, null, X)
+          endMetadataStar(1)
+          handleIdentifier(X, typeVariableDeclaration)
+          beginTypeVariable(X)
+            handleTypeVariablesDefined(X, 1)
+            handleNoType(X)
+          endTypeVariable(>, 0, null, null)
+        endTypeVariables(<, >)
+        handleIdentifier(int, typeReference)
+        handleNoTypeArguments(Function)
+        handleType(int, null)
+        beginFormalParameters((, MemberKind.GeneralizedFunctionType)
+          beginMetadataStar(@)
+            beginMetadata(@)
+              handleIdentifier(foo, metadataReference)
+              beginTypeArguments(<)
+                handleIdentifier(int, typeReference)
+                handleNoTypeArguments(>)
+                handleType(int, null)
+              endTypeArguments(1, <, >)
+              beginArguments(()
+                beginLiteralString("hello")
+                endLiteralString(0, ))
+              endArguments(1, (, ))
+            endMetadata(@, null, int)
+          endMetadataStar(1)
+          beginFormalParameter(int, MemberKind.GeneralizedFunctionType, null, null, null)
+            handleIdentifier(int, typeReference)
+            handleNoTypeArguments())
+            handleType(int, null)
+            handleNoName())
+            handleFormalParameterWithoutValue())
+          endFormalParameter(null, null, ), null, null, FormalParameterKind.mandatory, MemberKind.GeneralizedFunctionType)
+        endFormalParameters(1, (, ), MemberKind.GeneralizedFunctionType)
+      endFunctionType(Function, null)
+    endFunctionTypeAlias(typedef, =, ;)
+  endTopLevelDeclaration(typedef)
+  beginMetadataStar(typedef)
+  endMetadataStar(0)
+  beginUncategorizedTopLevelDeclaration(typedef)
+    beginFunctionTypeAlias(typedef)
+      handleIdentifier(F, typedefDeclaration)
+      beginTypeVariables(<)
+        beginMetadataStar(@)
+          beginMetadata(@)
+            handleIdentifier(foo, metadataReference)
+            beginTypeArguments(<)
+              handleIdentifier(int, typeReference)
+              handleNoTypeArguments(>)
+              handleType(int, null)
+            endTypeArguments(1, <, >)
+            handleIdentifier(abstract, metadataContinuationAfterTypeArguments)
+            beginArguments(()
+              beginLiteralString("hello")
+              endLiteralString(0, ))
+            endArguments(1, (, ))
+          endMetadata(@, ., T)
+        endMetadataStar(1)
+        handleIdentifier(T, typeVariableDeclaration)
+        beginTypeVariable(T)
+          handleTypeVariablesDefined(T, 1)
+          handleNoType(T)
+        endTypeVariable(>, 0, null, null)
+      endTypeVariables(<, >)
+      beginFunctionType(int)
+        beginTypeVariables(<)
+          beginMetadataStar(@)
+            beginMetadata(@)
+              handleIdentifier(foo, metadataReference)
+              beginTypeArguments(<)
+                handleIdentifier(int, typeReference)
+                handleNoTypeArguments(>)
+                handleType(int, null)
+              endTypeArguments(1, <, >)
+              handleIdentifier(abstract, metadataContinuationAfterTypeArguments)
+              beginArguments(()
+                beginLiteralString("hello")
+                endLiteralString(0, ))
+              endArguments(1, (, ))
+            endMetadata(@, ., X)
+          endMetadataStar(1)
+          handleIdentifier(X, typeVariableDeclaration)
+          beginTypeVariable(X)
+            handleTypeVariablesDefined(X, 1)
+            handleNoType(X)
+          endTypeVariable(>, 0, null, null)
+        endTypeVariables(<, >)
+        handleIdentifier(int, typeReference)
+        handleNoTypeArguments(Function)
+        handleType(int, null)
+        beginFormalParameters((, MemberKind.GeneralizedFunctionType)
+          beginMetadataStar(@)
+            beginMetadata(@)
+              handleIdentifier(foo, metadataReference)
+              beginTypeArguments(<)
+                handleIdentifier(int, typeReference)
+                handleNoTypeArguments(>)
+                handleType(int, null)
+              endTypeArguments(1, <, >)
+              handleIdentifier(abstract, metadataContinuationAfterTypeArguments)
+              beginArguments(()
+                beginLiteralString("hello")
+                endLiteralString(0, ))
+              endArguments(1, (, ))
+            endMetadata(@, ., int)
+          endMetadataStar(1)
+          beginFormalParameter(int, MemberKind.GeneralizedFunctionType, null, null, null)
+            handleIdentifier(int, typeReference)
+            handleNoTypeArguments())
+            handleType(int, null)
+            handleNoName())
+            handleFormalParameterWithoutValue())
+          endFormalParameter(null, null, ), null, null, FormalParameterKind.mandatory, MemberKind.GeneralizedFunctionType)
+        endFormalParameters(1, (, ), MemberKind.GeneralizedFunctionType)
+      endFunctionType(Function, null)
+    endFunctionTypeAlias(typedef, =, ;)
+  endTopLevelDeclaration(typedef)
+  beginMetadataStar(typedef)
+  endMetadataStar(0)
+  beginUncategorizedTopLevelDeclaration(typedef)
+    beginFunctionTypeAlias(typedef)
+      handleIdentifier(F, typedefDeclaration)
+      beginTypeVariables(<)
+        beginMetadataStar(@)
+          beginMetadata(@)
+            handleIdentifier(foo, metadataReference)
+            handleIdentifier(bar, metadataContinuation)
+            handleQualified(.)
+            beginTypeArguments(<)
+              handleIdentifier(int, typeReference)
+              handleNoTypeArguments(>)
+              handleType(int, null)
+            endTypeArguments(1, <, >)
+            beginArguments(()
+              beginLiteralString("hello")
+              endLiteralString(0, ))
+            endArguments(1, (, ))
+          endMetadata(@, null, T)
+        endMetadataStar(1)
+        handleIdentifier(T, typeVariableDeclaration)
+        beginTypeVariable(T)
+          handleTypeVariablesDefined(T, 1)
+          handleNoType(T)
+        endTypeVariable(>, 0, null, null)
+      endTypeVariables(<, >)
+      beginFunctionType(int)
+        beginTypeVariables(<)
+          beginMetadataStar(@)
+            beginMetadata(@)
+              handleIdentifier(foo, metadataReference)
+              handleIdentifier(bar, metadataContinuation)
+              handleQualified(.)
+              beginTypeArguments(<)
+                handleIdentifier(int, typeReference)
+                handleNoTypeArguments(>)
+                handleType(int, null)
+              endTypeArguments(1, <, >)
+              beginArguments(()
+                beginLiteralString("hello")
+                endLiteralString(0, ))
+              endArguments(1, (, ))
+            endMetadata(@, null, X)
+          endMetadataStar(1)
+          handleIdentifier(X, typeVariableDeclaration)
+          beginTypeVariable(X)
+            handleTypeVariablesDefined(X, 1)
+            handleNoType(X)
+          endTypeVariable(>, 0, null, null)
+        endTypeVariables(<, >)
+        handleIdentifier(int, typeReference)
+        handleNoTypeArguments(Function)
+        handleType(int, null)
+        beginFormalParameters((, MemberKind.GeneralizedFunctionType)
+          beginMetadataStar(@)
+            beginMetadata(@)
+              handleIdentifier(foo, metadataReference)
+              handleIdentifier(bar, metadataContinuation)
+              handleQualified(.)
+              beginTypeArguments(<)
+                handleIdentifier(int, typeReference)
+                handleNoTypeArguments(>)
+                handleType(int, null)
+              endTypeArguments(1, <, >)
+              beginArguments(()
+                beginLiteralString("hello")
+                endLiteralString(0, ))
+              endArguments(1, (, ))
+            endMetadata(@, null, int)
+          endMetadataStar(1)
+          beginFormalParameter(int, MemberKind.GeneralizedFunctionType, null, null, null)
+            handleIdentifier(int, typeReference)
+            handleNoTypeArguments())
+            handleType(int, null)
+            handleNoName())
+            handleFormalParameterWithoutValue())
+          endFormalParameter(null, null, ), null, null, FormalParameterKind.mandatory, MemberKind.GeneralizedFunctionType)
+        endFormalParameters(1, (, ), MemberKind.GeneralizedFunctionType)
+      endFunctionType(Function, null)
+    endFunctionTypeAlias(typedef, =, ;)
+  endTopLevelDeclaration(typedef)
+  beginMetadataStar(typedef)
+  endMetadataStar(0)
+  beginUncategorizedTopLevelDeclaration(typedef)
+    beginFunctionTypeAlias(typedef)
+      handleIdentifier(F, typedefDeclaration)
+      beginTypeVariables(<)
+        beginMetadataStar(@)
+          beginMetadata(@)
+            handleIdentifier(foo, metadataReference)
+            handleIdentifier(bar, metadataContinuation)
+            handleQualified(.)
+            beginTypeArguments(<)
+              handleIdentifier(int, typeReference)
+              handleNoTypeArguments(>)
+              handleType(int, null)
+            endTypeArguments(1, <, >)
+            handleIdentifier(abstract, metadataContinuationAfterTypeArguments)
+            beginArguments(()
+              beginLiteralString("hello")
+              endLiteralString(0, ))
+            endArguments(1, (, ))
+          endMetadata(@, ., T)
+        endMetadataStar(1)
+        handleIdentifier(T, typeVariableDeclaration)
+        beginTypeVariable(T)
+          handleTypeVariablesDefined(T, 1)
+          handleNoType(T)
+        endTypeVariable(>, 0, null, null)
+      endTypeVariables(<, >)
+      beginFunctionType(int)
+        beginTypeVariables(<)
+          beginMetadataStar(@)
+            beginMetadata(@)
+              handleIdentifier(foo, metadataReference)
+              handleIdentifier(bar, metadataContinuation)
+              handleQualified(.)
+              beginTypeArguments(<)
+                handleIdentifier(int, typeReference)
+                handleNoTypeArguments(>)
+                handleType(int, null)
+              endTypeArguments(1, <, >)
+              handleIdentifier(abstract, metadataContinuationAfterTypeArguments)
+              beginArguments(()
+                beginLiteralString("hello")
+                endLiteralString(0, ))
+              endArguments(1, (, ))
+            endMetadata(@, ., X)
+          endMetadataStar(1)
+          handleIdentifier(X, typeVariableDeclaration)
+          beginTypeVariable(X)
+            handleTypeVariablesDefined(X, 1)
+            handleNoType(X)
+          endTypeVariable(>, 0, null, null)
+        endTypeVariables(<, >)
+        handleIdentifier(int, typeReference)
+        handleNoTypeArguments(Function)
+        handleType(int, null)
+        beginFormalParameters((, MemberKind.GeneralizedFunctionType)
+          beginMetadataStar(@)
+            beginMetadata(@)
+              handleIdentifier(foo, metadataReference)
+              handleIdentifier(bar, metadataContinuation)
+              handleQualified(.)
+              beginTypeArguments(<)
+                handleIdentifier(int, typeReference)
+                handleNoTypeArguments(>)
+                handleType(int, null)
+              endTypeArguments(1, <, >)
+              handleIdentifier(abstract, metadataContinuationAfterTypeArguments)
+              beginArguments(()
+                beginLiteralString("hello")
+                endLiteralString(0, ))
+              endArguments(1, (, ))
+            endMetadata(@, ., int)
+          endMetadataStar(1)
+          beginFormalParameter(int, MemberKind.GeneralizedFunctionType, null, null, null)
+            handleIdentifier(int, typeReference)
+            handleNoTypeArguments())
+            handleType(int, null)
+            handleNoName())
+            handleFormalParameterWithoutValue())
+          endFormalParameter(null, null, ), null, null, FormalParameterKind.mandatory, MemberKind.GeneralizedFunctionType)
+        endFormalParameters(1, (, ), MemberKind.GeneralizedFunctionType)
+      endFunctionType(Function, null)
+    endFunctionTypeAlias(typedef, =, ;)
+  endTopLevelDeclaration(@)
+  beginMetadataStar(@)
+    beginMetadata(@)
+      handleIdentifier(abstract, metadataReference)
+      handleIdentifier(abstract, metadataContinuation)
+      handleQualified(.)
+      handleNoTypeArguments(@)
+      handleNoArguments(@)
+    endMetadata(@, null, @)
+    beginMetadata(@)
+      handleIdentifier(abstract, metadataReference)
+      handleIdentifier(bar, metadataContinuation)
+      handleQualified(.)
+      handleNoTypeArguments(.)
+      handleIdentifier(abstract, metadataContinuationAfterTypeArguments)
+      handleNoArguments(@)
+    endMetadata(@, ., @)
+    beginMetadata(@)
+      handleIdentifier(abstract, metadataReference)
+      handleNoTypeArguments(()
+      beginArguments(()
+        beginLiteralString("hello")
+        endLiteralString(0, ))
+      endArguments(1, (, ))
+    endMetadata(@, null, @)
+    beginMetadata(@)
+      handleIdentifier(abstract, metadataReference)
+      handleIdentifier(abstract, metadataContinuation)
+      handleQualified(.)
+      handleNoTypeArguments(()
+      beginArguments(()
+        beginLiteralString("hello")
+        endLiteralString(0, ))
+      endArguments(1, (, ))
+    endMetadata(@, null, @)
+    beginMetadata(@)
+      handleIdentifier(abstract, metadataReference)
+      handleIdentifier(bar, metadataContinuation)
+      handleQualified(.)
+      handleNoTypeArguments(.)
+      handleIdentifier(abstract, metadataContinuationAfterTypeArguments)
+      beginArguments(()
+        beginLiteralString("hello")
+        endLiteralString(0, ))
+      endArguments(1, (, ))
+    endMetadata(@, ., @)
+    beginMetadata(@)
+      handleIdentifier(abstract, metadataReference)
+      beginTypeArguments(<)
+        handleIdentifier(int, typeReference)
+        handleNoTypeArguments(>)
+        handleType(int, null)
+      endTypeArguments(1, <, >)
+      beginArguments(()
+        beginLiteralString("hello")
+        endLiteralString(0, ))
+      endArguments(1, (, ))
+    endMetadata(@, null, @)
+    beginMetadata(@)
+      handleIdentifier(abstract, metadataReference)
+      beginTypeArguments(<)
+        handleIdentifier(int, typeReference)
+        handleNoTypeArguments(>)
+        handleType(int, null)
+      endTypeArguments(1, <, >)
+      handleIdentifier(abstract, metadataContinuationAfterTypeArguments)
+      beginArguments(()
+        beginLiteralString("hello")
+        endLiteralString(0, ))
+      endArguments(1, (, ))
+    endMetadata(@, ., @)
+    beginMetadata(@)
+      handleIdentifier(abstract, metadataReference)
+      handleIdentifier(bar, metadataContinuation)
+      handleQualified(.)
+      beginTypeArguments(<)
+        handleIdentifier(int, typeReference)
+        handleNoTypeArguments(>)
+        handleType(int, null)
+      endTypeArguments(1, <, >)
+      beginArguments(()
+        beginLiteralString("hello")
+        endLiteralString(0, ))
+      endArguments(1, (, ))
+    endMetadata(@, null, @)
+    beginMetadata(@)
+      handleIdentifier(abstract, metadataReference)
+      handleIdentifier(bar, metadataContinuation)
+      handleQualified(.)
+      beginTypeArguments(<)
+        handleIdentifier(int, typeReference)
+        handleNoTypeArguments(>)
+        handleType(int, null)
+      endTypeArguments(1, <, >)
+      handleIdentifier(abstract, metadataContinuationAfterTypeArguments)
+      beginArguments(()
+        beginLiteralString("hello")
+        endLiteralString(0, ))
+      endArguments(1, (, ))
+    endMetadata(@, ., class)
+  endMetadataStar(9)
+  beginClassOrNamedMixinApplicationPrelude(class)
+    handleIdentifier(Y, classOrMixinDeclaration)
+    handleNoTypeVariables({)
+    beginClassDeclaration(class, null, Y)
+      handleNoType(Y)
+      handleClassExtends(null, 1)
+      handleClassNoWithClause()
+      handleClassOrMixinImplements(null, 0)
+      handleClassHeader(class, class, null)
+      beginClassOrMixinBody(DeclarationKind.Class, {)
+      endClassOrMixinBody(DeclarationKind.Class, 0, {, })
+    endClassDeclaration(class, })
+  endTopLevelDeclaration()
+endCompilationUnit(12, )
diff --git a/pkg/front_end/parser_testcases/general/metadata.dart.intertwined.expect b/pkg/front_end/parser_testcases/general/metadata.dart.intertwined.expect
new file mode 100644
index 0000000..9a0530c
--- /dev/null
+++ b/pkg/front_end/parser_testcases/general/metadata.dart.intertwined.expect
@@ -0,0 +1,1741 @@
+parseUnit(@)
+  skipErrorTokens(@)
+  listener: beginCompilationUnit(@)
+  syntheticPreviousToken(@)
+  parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+    parseMetadataStar()
+      listener: beginMetadataStar(@)
+      parseMetadata()
+        listener: beginMetadata(@)
+        ensureIdentifier(@, metadataReference)
+          inPlainSync()
+          listener: handleIdentifier(abstract, metadataReference)
+        parseQualifiedRestOpt(abstract, metadataContinuation)
+        listener: handleNoTypeArguments(@)
+        parseArgumentsOpt(abstract)
+          listener: handleNoArguments(@)
+        listener: endMetadata(@, null, @)
+      parseMetadata(abstract)
+        listener: beginMetadata(@)
+        ensureIdentifier(@, metadataReference)
+          listener: handleIdentifier(foo, metadataReference)
+        parseQualifiedRestOpt(foo, metadataContinuation)
+          parseQualifiedRest(foo, metadataContinuation)
+            ensureIdentifier(., metadataContinuation)
+              inPlainSync()
+              listener: handleIdentifier(abstract, metadataContinuation)
+            listener: handleQualified(.)
+        listener: handleNoTypeArguments(@)
+        parseArgumentsOpt(abstract)
+          listener: handleNoArguments(@)
+        listener: endMetadata(@, null, @)
+      parseMetadata(abstract)
+        listener: beginMetadata(@)
+        ensureIdentifier(@, metadataReference)
+          listener: handleIdentifier(foo, metadataReference)
+        parseQualifiedRestOpt(foo, metadataContinuation)
+          parseQualifiedRest(foo, metadataContinuation)
+            ensureIdentifier(., metadataContinuation)
+              listener: handleIdentifier(bar, metadataContinuation)
+            listener: handleQualified(.)
+        listener: handleNoTypeArguments(.)
+        ensureIdentifier(., metadataContinuationAfterTypeArguments)
+          inPlainSync()
+          listener: handleIdentifier(abstract, metadataContinuationAfterTypeArguments)
+        parseArgumentsOpt(abstract)
+          listener: handleNoArguments(@)
+        listener: endMetadata(@, ., @)
+      parseMetadata(abstract)
+        listener: beginMetadata(@)
+        ensureIdentifier(@, metadataReference)
+          listener: handleIdentifier(foo, metadataReference)
+        parseQualifiedRestOpt(foo, metadataContinuation)
+        listener: handleNoTypeArguments(()
+        parseArgumentsOpt(foo)
+          parseArguments(foo)
+            parseArgumentsRest(()
+              listener: beginArguments(()
+              parseExpression(()
+                parsePrecedenceExpression((, 1, true)
+                  parseUnaryExpression((, true)
+                    parsePrimary((, expression)
+                      parseLiteralString(()
+                        parseSingleLiteralString(()
+                          listener: beginLiteralString("hello")
+                          listener: endLiteralString(0, ))
+              listener: endArguments(1, (, ))
+        listener: endMetadata(@, null, @)
+      parseMetadata())
+        listener: beginMetadata(@)
+        ensureIdentifier(@, metadataReference)
+          listener: handleIdentifier(foo, metadataReference)
+        parseQualifiedRestOpt(foo, metadataContinuation)
+          parseQualifiedRest(foo, metadataContinuation)
+            ensureIdentifier(., metadataContinuation)
+              inPlainSync()
+              listener: handleIdentifier(abstract, metadataContinuation)
+            listener: handleQualified(.)
+        listener: handleNoTypeArguments(()
+        parseArgumentsOpt(abstract)
+          parseArguments(abstract)
+            parseArgumentsRest(()
+              listener: beginArguments(()
+              parseExpression(()
+                parsePrecedenceExpression((, 1, true)
+                  parseUnaryExpression((, true)
+                    parsePrimary((, expression)
+                      parseLiteralString(()
+                        parseSingleLiteralString(()
+                          listener: beginLiteralString("hello")
+                          listener: endLiteralString(0, ))
+              listener: endArguments(1, (, ))
+        listener: endMetadata(@, null, @)
+      parseMetadata())
+        listener: beginMetadata(@)
+        ensureIdentifier(@, metadataReference)
+          listener: handleIdentifier(foo, metadataReference)
+        parseQualifiedRestOpt(foo, metadataContinuation)
+          parseQualifiedRest(foo, metadataContinuation)
+            ensureIdentifier(., metadataContinuation)
+              listener: handleIdentifier(bar, metadataContinuation)
+            listener: handleQualified(.)
+        listener: handleNoTypeArguments(.)
+        ensureIdentifier(., metadataContinuationAfterTypeArguments)
+          inPlainSync()
+          listener: handleIdentifier(abstract, metadataContinuationAfterTypeArguments)
+        parseArgumentsOpt(abstract)
+          parseArguments(abstract)
+            parseArgumentsRest(()
+              listener: beginArguments(()
+              parseExpression(()
+                parsePrecedenceExpression((, 1, true)
+                  parseUnaryExpression((, true)
+                    parsePrimary((, expression)
+                      parseLiteralString(()
+                        parseSingleLiteralString(()
+                          listener: beginLiteralString("hello")
+                          listener: endLiteralString(0, ))
+              listener: endArguments(1, (, ))
+        listener: endMetadata(@, ., @)
+      parseMetadata())
+        listener: beginMetadata(@)
+        ensureIdentifier(@, metadataReference)
+          listener: handleIdentifier(foo, metadataReference)
+        parseQualifiedRestOpt(foo, metadataContinuation)
+        listener: beginTypeArguments(<)
+        listener: handleIdentifier(int, typeReference)
+        listener: handleNoTypeArguments(>)
+        listener: handleType(int, null)
+        listener: endTypeArguments(1, <, >)
+        parseArgumentsOpt(>)
+          parseArguments(>)
+            parseArgumentsRest(()
+              listener: beginArguments(()
+              parseExpression(()
+                parsePrecedenceExpression((, 1, true)
+                  parseUnaryExpression((, true)
+                    parsePrimary((, expression)
+                      parseLiteralString(()
+                        parseSingleLiteralString(()
+                          listener: beginLiteralString("hello")
+                          listener: endLiteralString(0, ))
+              listener: endArguments(1, (, ))
+        listener: endMetadata(@, null, @)
+      parseMetadata())
+        listener: beginMetadata(@)
+        ensureIdentifier(@, metadataReference)
+          listener: handleIdentifier(foo, metadataReference)
+        parseQualifiedRestOpt(foo, metadataContinuation)
+        listener: beginTypeArguments(<)
+        listener: handleIdentifier(int, typeReference)
+        listener: handleNoTypeArguments(>)
+        listener: handleType(int, null)
+        listener: endTypeArguments(1, <, >)
+        ensureIdentifier(., metadataContinuationAfterTypeArguments)
+          inPlainSync()
+          listener: handleIdentifier(abstract, metadataContinuationAfterTypeArguments)
+        parseArgumentsOpt(abstract)
+          parseArguments(abstract)
+            parseArgumentsRest(()
+              listener: beginArguments(()
+              parseExpression(()
+                parsePrecedenceExpression((, 1, true)
+                  parseUnaryExpression((, true)
+                    parsePrimary((, expression)
+                      parseLiteralString(()
+                        parseSingleLiteralString(()
+                          listener: beginLiteralString("hello")
+                          listener: endLiteralString(0, ))
+              listener: endArguments(1, (, ))
+        listener: endMetadata(@, ., @)
+      parseMetadata())
+        listener: beginMetadata(@)
+        ensureIdentifier(@, metadataReference)
+          listener: handleIdentifier(foo, metadataReference)
+        parseQualifiedRestOpt(foo, metadataContinuation)
+          parseQualifiedRest(foo, metadataContinuation)
+            ensureIdentifier(., metadataContinuation)
+              listener: handleIdentifier(bar, metadataContinuation)
+            listener: handleQualified(.)
+        listener: beginTypeArguments(<)
+        listener: handleIdentifier(int, typeReference)
+        listener: handleNoTypeArguments(>)
+        listener: handleType(int, null)
+        listener: endTypeArguments(1, <, >)
+        parseArgumentsOpt(>)
+          parseArguments(>)
+            parseArgumentsRest(()
+              listener: beginArguments(()
+              parseExpression(()
+                parsePrecedenceExpression((, 1, true)
+                  parseUnaryExpression((, true)
+                    parsePrimary((, expression)
+                      parseLiteralString(()
+                        parseSingleLiteralString(()
+                          listener: beginLiteralString("hello")
+                          listener: endLiteralString(0, ))
+              listener: endArguments(1, (, ))
+        listener: endMetadata(@, null, @)
+      parseMetadata())
+        listener: beginMetadata(@)
+        ensureIdentifier(@, metadataReference)
+          listener: handleIdentifier(foo, metadataReference)
+        parseQualifiedRestOpt(foo, metadataContinuation)
+          parseQualifiedRest(foo, metadataContinuation)
+            ensureIdentifier(., metadataContinuation)
+              listener: handleIdentifier(bar, metadataContinuation)
+            listener: handleQualified(.)
+        listener: beginTypeArguments(<)
+        listener: handleIdentifier(int, typeReference)
+        listener: handleNoTypeArguments(>)
+        listener: handleType(int, null)
+        listener: endTypeArguments(1, <, >)
+        ensureIdentifier(., metadataContinuationAfterTypeArguments)
+          inPlainSync()
+          listener: handleIdentifier(abstract, metadataContinuationAfterTypeArguments)
+        parseArgumentsOpt(abstract)
+          parseArguments(abstract)
+            parseArgumentsRest(()
+              listener: beginArguments(()
+              parseExpression(()
+                parsePrecedenceExpression((, 1, true)
+                  parseUnaryExpression((, true)
+                    parsePrimary((, expression)
+                      parseLiteralString(()
+                        parseSingleLiteralString(()
+                          listener: beginLiteralString("hello")
+                          listener: endLiteralString(0, ))
+              listener: endArguments(1, (, ))
+        listener: endMetadata(@, ., class)
+      listener: endMetadataStar(10)
+    parseTopLevelKeywordDeclaration(), class, Instance of 'DirectiveContext')
+      parseClassDeclarationModifiers(), class)
+      parseClassOrNamedMixinApplication(null, class)
+        listener: beginClassOrNamedMixinApplicationPrelude(class)
+        ensureIdentifier(class, classOrMixinDeclaration)
+          listener: handleIdentifier(X, classOrMixinDeclaration)
+        listener: handleNoTypeVariables({)
+        listener: beginClassDeclaration(class, null, X)
+        parseClass(X, class, class, X)
+          parseClassHeaderOpt(X, class, class)
+            parseClassExtendsOpt(X)
+              listener: handleNoType(X)
+              listener: handleClassExtends(null, 1)
+            parseWithClauseOpt(X)
+              listener: handleClassNoWithClause()
+            parseClassOrMixinImplementsOpt(X)
+              listener: handleClassOrMixinImplements(null, 0)
+            listener: handleClassHeader(class, class, null)
+          parseClassOrMixinOrExtensionBody(X, DeclarationKind.Class, X)
+            listener: beginClassOrMixinBody(DeclarationKind.Class, {)
+            notEofOrValue(}, })
+            listener: endClassOrMixinBody(DeclarationKind.Class, 0, {, })
+          listener: endClassDeclaration(class, })
+  listener: endTopLevelDeclaration(typedef)
+  parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+    parseMetadataStar(})
+      listener: beginMetadataStar(typedef)
+      listener: endMetadataStar(0)
+    parseTopLevelKeywordDeclaration(}, typedef, Instance of 'DirectiveContext')
+      parseTopLevelKeywordModifiers(}, typedef)
+      parseTypedef(typedef)
+        listener: beginUncategorizedTopLevelDeclaration(typedef)
+        listener: beginFunctionTypeAlias(typedef)
+        ensureIdentifierPotentiallyRecovered(typedef, typedefDeclaration, true)
+          listener: handleIdentifier(F, typedefDeclaration)
+        listener: beginTypeVariables(<)
+        parseMetadataStar(<)
+          listener: beginMetadataStar(@)
+          parseMetadata(<)
+            listener: beginMetadata(@)
+            ensureIdentifier(@, metadataReference)
+              inPlainSync()
+              listener: handleIdentifier(abstract, metadataReference)
+            parseQualifiedRestOpt(abstract, metadataContinuation)
+            listener: handleNoTypeArguments(T)
+            parseArgumentsOpt(abstract)
+              listener: handleNoArguments(T)
+            listener: endMetadata(@, null, T)
+          listener: endMetadataStar(1)
+        ensureIdentifier(abstract, typeVariableDeclaration)
+          listener: handleIdentifier(T, typeVariableDeclaration)
+        listener: beginTypeVariable(T)
+        listener: handleTypeVariablesDefined(T, 1)
+        listener: handleNoType(T)
+        listener: endTypeVariable(>, 0, null, null)
+        listener: endTypeVariables(<, >)
+        listener: beginFunctionType(int)
+        listener: beginTypeVariables(<)
+        parseMetadataStar(<)
+          listener: beginMetadataStar(@)
+          parseMetadata(<)
+            listener: beginMetadata(@)
+            ensureIdentifier(@, metadataReference)
+              inPlainSync()
+              listener: handleIdentifier(abstract, metadataReference)
+            parseQualifiedRestOpt(abstract, metadataContinuation)
+            listener: handleNoTypeArguments(X)
+            parseArgumentsOpt(abstract)
+              listener: handleNoArguments(X)
+            listener: endMetadata(@, null, X)
+          listener: endMetadataStar(1)
+        ensureIdentifier(abstract, typeVariableDeclaration)
+          listener: handleIdentifier(X, typeVariableDeclaration)
+        listener: beginTypeVariable(X)
+        listener: handleTypeVariablesDefined(X, 1)
+        listener: handleNoType(X)
+        listener: endTypeVariable(>, 0, null, null)
+        listener: endTypeVariables(<, >)
+        ensureIdentifier(=, typeReference)
+          listener: handleIdentifier(int, typeReference)
+        listener: handleNoTypeArguments(Function)
+        listener: handleType(int, null)
+        parseFormalParametersRequiredOpt(>, MemberKind.GeneralizedFunctionType)
+          parseFormalParametersRest((, MemberKind.GeneralizedFunctionType)
+            listener: beginFormalParameters((, MemberKind.GeneralizedFunctionType)
+            parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.GeneralizedFunctionType)
+              parseMetadataStar(()
+                listener: beginMetadataStar(@)
+                parseMetadata(()
+                  listener: beginMetadata(@)
+                  ensureIdentifier(@, metadataReference)
+                    inPlainSync()
+                    listener: handleIdentifier(abstract, metadataReference)
+                  parseQualifiedRestOpt(abstract, metadataContinuation)
+                  listener: handleNoTypeArguments(int)
+                  parseArgumentsOpt(abstract)
+                    listener: handleNoArguments(int)
+                  listener: endMetadata(@, null, int)
+                listener: endMetadataStar(1)
+              listener: beginFormalParameter(int, MemberKind.GeneralizedFunctionType, null, null, null)
+              listener: handleIdentifier(int, typeReference)
+              listener: handleNoTypeArguments())
+              listener: handleType(int, null)
+              listener: handleNoName())
+              listener: handleFormalParameterWithoutValue())
+              listener: endFormalParameter(null, null, ), null, null, FormalParameterKind.mandatory, MemberKind.GeneralizedFunctionType)
+            listener: endFormalParameters(1, (, ), MemberKind.GeneralizedFunctionType)
+        listener: endFunctionType(Function, null)
+        ensureSemicolon())
+        listener: endFunctionTypeAlias(typedef, =, ;)
+  listener: endTopLevelDeclaration(typedef)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(typedef)
+      listener: endMetadataStar(0)
+    parseTopLevelKeywordDeclaration(;, typedef, Instance of 'DirectiveContext')
+      parseTopLevelKeywordModifiers(;, typedef)
+      parseTypedef(typedef)
+        listener: beginUncategorizedTopLevelDeclaration(typedef)
+        listener: beginFunctionTypeAlias(typedef)
+        ensureIdentifierPotentiallyRecovered(typedef, typedefDeclaration, true)
+          listener: handleIdentifier(F, typedefDeclaration)
+        listener: beginTypeVariables(<)
+        parseMetadataStar(<)
+          listener: beginMetadataStar(@)
+          parseMetadata(<)
+            listener: beginMetadata(@)
+            ensureIdentifier(@, metadataReference)
+              listener: handleIdentifier(foo, metadataReference)
+            parseQualifiedRestOpt(foo, metadataContinuation)
+              parseQualifiedRest(foo, metadataContinuation)
+                ensureIdentifier(., metadataContinuation)
+                  inPlainSync()
+                  listener: handleIdentifier(abstract, metadataContinuation)
+                listener: handleQualified(.)
+            listener: handleNoTypeArguments(T)
+            parseArgumentsOpt(abstract)
+              listener: handleNoArguments(T)
+            listener: endMetadata(@, null, T)
+          listener: endMetadataStar(1)
+        ensureIdentifier(abstract, typeVariableDeclaration)
+          listener: handleIdentifier(T, typeVariableDeclaration)
+        listener: beginTypeVariable(T)
+        listener: handleTypeVariablesDefined(T, 1)
+        listener: handleNoType(T)
+        listener: endTypeVariable(>, 0, null, null)
+        listener: endTypeVariables(<, >)
+        listener: beginFunctionType(int)
+        listener: beginTypeVariables(<)
+        parseMetadataStar(<)
+          listener: beginMetadataStar(@)
+          parseMetadata(<)
+            listener: beginMetadata(@)
+            ensureIdentifier(@, metadataReference)
+              listener: handleIdentifier(foo, metadataReference)
+            parseQualifiedRestOpt(foo, metadataContinuation)
+              parseQualifiedRest(foo, metadataContinuation)
+                ensureIdentifier(., metadataContinuation)
+                  inPlainSync()
+                  listener: handleIdentifier(abstract, metadataContinuation)
+                listener: handleQualified(.)
+            listener: handleNoTypeArguments(X)
+            parseArgumentsOpt(abstract)
+              listener: handleNoArguments(X)
+            listener: endMetadata(@, null, X)
+          listener: endMetadataStar(1)
+        ensureIdentifier(abstract, typeVariableDeclaration)
+          listener: handleIdentifier(X, typeVariableDeclaration)
+        listener: beginTypeVariable(X)
+        listener: handleTypeVariablesDefined(X, 1)
+        listener: handleNoType(X)
+        listener: endTypeVariable(>, 0, null, null)
+        listener: endTypeVariables(<, >)
+        ensureIdentifier(=, typeReference)
+          listener: handleIdentifier(int, typeReference)
+        listener: handleNoTypeArguments(Function)
+        listener: handleType(int, null)
+        parseFormalParametersRequiredOpt(>, MemberKind.GeneralizedFunctionType)
+          parseFormalParametersRest((, MemberKind.GeneralizedFunctionType)
+            listener: beginFormalParameters((, MemberKind.GeneralizedFunctionType)
+            parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.GeneralizedFunctionType)
+              parseMetadataStar(()
+                listener: beginMetadataStar(@)
+                parseMetadata(()
+                  listener: beginMetadata(@)
+                  ensureIdentifier(@, metadataReference)
+                    listener: handleIdentifier(foo, metadataReference)
+                  parseQualifiedRestOpt(foo, metadataContinuation)
+                    parseQualifiedRest(foo, metadataContinuation)
+                      ensureIdentifier(., metadataContinuation)
+                        inPlainSync()
+                        listener: handleIdentifier(abstract, metadataContinuation)
+                      listener: handleQualified(.)
+                  listener: handleNoTypeArguments(int)
+                  parseArgumentsOpt(abstract)
+                    listener: handleNoArguments(int)
+                  listener: endMetadata(@, null, int)
+                listener: endMetadataStar(1)
+              listener: beginFormalParameter(int, MemberKind.GeneralizedFunctionType, null, null, null)
+              listener: handleIdentifier(int, typeReference)
+              listener: handleNoTypeArguments())
+              listener: handleType(int, null)
+              listener: handleNoName())
+              listener: handleFormalParameterWithoutValue())
+              listener: endFormalParameter(null, null, ), null, null, FormalParameterKind.mandatory, MemberKind.GeneralizedFunctionType)
+            listener: endFormalParameters(1, (, ), MemberKind.GeneralizedFunctionType)
+        listener: endFunctionType(Function, null)
+        ensureSemicolon())
+        listener: endFunctionTypeAlias(typedef, =, ;)
+  listener: endTopLevelDeclaration(typedef)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(typedef)
+      listener: endMetadataStar(0)
+    parseTopLevelKeywordDeclaration(;, typedef, Instance of 'DirectiveContext')
+      parseTopLevelKeywordModifiers(;, typedef)
+      parseTypedef(typedef)
+        listener: beginUncategorizedTopLevelDeclaration(typedef)
+        listener: beginFunctionTypeAlias(typedef)
+        ensureIdentifierPotentiallyRecovered(typedef, typedefDeclaration, true)
+          listener: handleIdentifier(F, typedefDeclaration)
+        listener: beginTypeVariables(<)
+        parseMetadataStar(<)
+          listener: beginMetadataStar(@)
+          parseMetadata(<)
+            listener: beginMetadata(@)
+            ensureIdentifier(@, metadataReference)
+              listener: handleIdentifier(foo, metadataReference)
+            parseQualifiedRestOpt(foo, metadataContinuation)
+              parseQualifiedRest(foo, metadataContinuation)
+                ensureIdentifier(., metadataContinuation)
+                  listener: handleIdentifier(bar, metadataContinuation)
+                listener: handleQualified(.)
+            listener: handleNoTypeArguments(.)
+            ensureIdentifier(., metadataContinuationAfterTypeArguments)
+              inPlainSync()
+              listener: handleIdentifier(abstract, metadataContinuationAfterTypeArguments)
+            parseArgumentsOpt(abstract)
+              listener: handleNoArguments(T)
+            listener: endMetadata(@, ., T)
+          listener: endMetadataStar(1)
+        ensureIdentifier(abstract, typeVariableDeclaration)
+          listener: handleIdentifier(T, typeVariableDeclaration)
+        listener: beginTypeVariable(T)
+        listener: handleTypeVariablesDefined(T, 1)
+        listener: handleNoType(T)
+        listener: endTypeVariable(>, 0, null, null)
+        listener: endTypeVariables(<, >)
+        listener: beginFunctionType(int)
+        listener: beginTypeVariables(<)
+        parseMetadataStar(<)
+          listener: beginMetadataStar(@)
+          parseMetadata(<)
+            listener: beginMetadata(@)
+            ensureIdentifier(@, metadataReference)
+              listener: handleIdentifier(foo, metadataReference)
+            parseQualifiedRestOpt(foo, metadataContinuation)
+              parseQualifiedRest(foo, metadataContinuation)
+                ensureIdentifier(., metadataContinuation)
+                  listener: handleIdentifier(bar, metadataContinuation)
+                listener: handleQualified(.)
+            listener: handleNoTypeArguments(.)
+            ensureIdentifier(., metadataContinuationAfterTypeArguments)
+              inPlainSync()
+              listener: handleIdentifier(abstract, metadataContinuationAfterTypeArguments)
+            parseArgumentsOpt(abstract)
+              listener: handleNoArguments(X)
+            listener: endMetadata(@, ., X)
+          listener: endMetadataStar(1)
+        ensureIdentifier(abstract, typeVariableDeclaration)
+          listener: handleIdentifier(X, typeVariableDeclaration)
+        listener: beginTypeVariable(X)
+        listener: handleTypeVariablesDefined(X, 1)
+        listener: handleNoType(X)
+        listener: endTypeVariable(>, 0, null, null)
+        listener: endTypeVariables(<, >)
+        ensureIdentifier(=, typeReference)
+          listener: handleIdentifier(int, typeReference)
+        listener: handleNoTypeArguments(Function)
+        listener: handleType(int, null)
+        parseFormalParametersRequiredOpt(>, MemberKind.GeneralizedFunctionType)
+          parseFormalParametersRest((, MemberKind.GeneralizedFunctionType)
+            listener: beginFormalParameters((, MemberKind.GeneralizedFunctionType)
+            parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.GeneralizedFunctionType)
+              parseMetadataStar(()
+                listener: beginMetadataStar(@)
+                parseMetadata(()
+                  listener: beginMetadata(@)
+                  ensureIdentifier(@, metadataReference)
+                    listener: handleIdentifier(foo, metadataReference)
+                  parseQualifiedRestOpt(foo, metadataContinuation)
+                    parseQualifiedRest(foo, metadataContinuation)
+                      ensureIdentifier(., metadataContinuation)
+                        listener: handleIdentifier(bar, metadataContinuation)
+                      listener: handleQualified(.)
+                  listener: handleNoTypeArguments(.)
+                  ensureIdentifier(., metadataContinuationAfterTypeArguments)
+                    inPlainSync()
+                    listener: handleIdentifier(abstract, metadataContinuationAfterTypeArguments)
+                  parseArgumentsOpt(abstract)
+                    listener: handleNoArguments(int)
+                  listener: endMetadata(@, ., int)
+                listener: endMetadataStar(1)
+              listener: beginFormalParameter(int, MemberKind.GeneralizedFunctionType, null, null, null)
+              listener: handleIdentifier(int, typeReference)
+              listener: handleNoTypeArguments())
+              listener: handleType(int, null)
+              listener: handleNoName())
+              listener: handleFormalParameterWithoutValue())
+              listener: endFormalParameter(null, null, ), null, null, FormalParameterKind.mandatory, MemberKind.GeneralizedFunctionType)
+            listener: endFormalParameters(1, (, ), MemberKind.GeneralizedFunctionType)
+        listener: endFunctionType(Function, null)
+        ensureSemicolon())
+        listener: endFunctionTypeAlias(typedef, =, ;)
+  listener: endTopLevelDeclaration(typedef)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(typedef)
+      listener: endMetadataStar(0)
+    parseTopLevelKeywordDeclaration(;, typedef, Instance of 'DirectiveContext')
+      parseTopLevelKeywordModifiers(;, typedef)
+      parseTypedef(typedef)
+        listener: beginUncategorizedTopLevelDeclaration(typedef)
+        listener: beginFunctionTypeAlias(typedef)
+        ensureIdentifierPotentiallyRecovered(typedef, typedefDeclaration, true)
+          listener: handleIdentifier(F, typedefDeclaration)
+        listener: beginTypeVariables(<)
+        parseMetadataStar(<)
+          listener: beginMetadataStar(@)
+          parseMetadata(<)
+            listener: beginMetadata(@)
+            ensureIdentifier(@, metadataReference)
+              listener: handleIdentifier(foo, metadataReference)
+            parseQualifiedRestOpt(foo, metadataContinuation)
+            listener: handleNoTypeArguments(()
+            parseArgumentsOpt(foo)
+              parseArguments(foo)
+                parseArgumentsRest(()
+                  listener: beginArguments(()
+                  parseExpression(()
+                    parsePrecedenceExpression((, 1, true)
+                      parseUnaryExpression((, true)
+                        parsePrimary((, expression)
+                          parseLiteralString(()
+                            parseSingleLiteralString(()
+                              listener: beginLiteralString("hello")
+                              listener: endLiteralString(0, ))
+                  listener: endArguments(1, (, ))
+            listener: endMetadata(@, null, T)
+          listener: endMetadataStar(1)
+        ensureIdentifier(), typeVariableDeclaration)
+          listener: handleIdentifier(T, typeVariableDeclaration)
+        listener: beginTypeVariable(T)
+        listener: handleTypeVariablesDefined(T, 1)
+        listener: handleNoType(T)
+        listener: endTypeVariable(>, 0, null, null)
+        listener: endTypeVariables(<, >)
+        listener: beginFunctionType(int)
+        listener: beginTypeVariables(<)
+        parseMetadataStar(<)
+          listener: beginMetadataStar(@)
+          parseMetadata(<)
+            listener: beginMetadata(@)
+            ensureIdentifier(@, metadataReference)
+              listener: handleIdentifier(foo, metadataReference)
+            parseQualifiedRestOpt(foo, metadataContinuation)
+            listener: handleNoTypeArguments(()
+            parseArgumentsOpt(foo)
+              parseArguments(foo)
+                parseArgumentsRest(()
+                  listener: beginArguments(()
+                  parseExpression(()
+                    parsePrecedenceExpression((, 1, true)
+                      parseUnaryExpression((, true)
+                        parsePrimary((, expression)
+                          parseLiteralString(()
+                            parseSingleLiteralString(()
+                              listener: beginLiteralString("hello")
+                              listener: endLiteralString(0, ))
+                  listener: endArguments(1, (, ))
+            listener: endMetadata(@, null, X)
+          listener: endMetadataStar(1)
+        ensureIdentifier(), typeVariableDeclaration)
+          listener: handleIdentifier(X, typeVariableDeclaration)
+        listener: beginTypeVariable(X)
+        listener: handleTypeVariablesDefined(X, 1)
+        listener: handleNoType(X)
+        listener: endTypeVariable(>, 0, null, null)
+        listener: endTypeVariables(<, >)
+        ensureIdentifier(=, typeReference)
+          listener: handleIdentifier(int, typeReference)
+        listener: handleNoTypeArguments(Function)
+        listener: handleType(int, null)
+        parseFormalParametersRequiredOpt(>, MemberKind.GeneralizedFunctionType)
+          parseFormalParametersRest((, MemberKind.GeneralizedFunctionType)
+            listener: beginFormalParameters((, MemberKind.GeneralizedFunctionType)
+            parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.GeneralizedFunctionType)
+              parseMetadataStar(()
+                listener: beginMetadataStar(@)
+                parseMetadata(()
+                  listener: beginMetadata(@)
+                  ensureIdentifier(@, metadataReference)
+                    listener: handleIdentifier(foo, metadataReference)
+                  parseQualifiedRestOpt(foo, metadataContinuation)
+                  listener: handleNoTypeArguments(()
+                  parseArgumentsOpt(foo)
+                    parseArguments(foo)
+                      parseArgumentsRest(()
+                        listener: beginArguments(()
+                        parseExpression(()
+                          parsePrecedenceExpression((, 1, true)
+                            parseUnaryExpression((, true)
+                              parsePrimary((, expression)
+                                parseLiteralString(()
+                                  parseSingleLiteralString(()
+                                    listener: beginLiteralString("hello")
+                                    listener: endLiteralString(0, ))
+                        listener: endArguments(1, (, ))
+                  listener: endMetadata(@, null, int)
+                listener: endMetadataStar(1)
+              listener: beginFormalParameter(int, MemberKind.GeneralizedFunctionType, null, null, null)
+              listener: handleIdentifier(int, typeReference)
+              listener: handleNoTypeArguments())
+              listener: handleType(int, null)
+              listener: handleNoName())
+              listener: handleFormalParameterWithoutValue())
+              listener: endFormalParameter(null, null, ), null, null, FormalParameterKind.mandatory, MemberKind.GeneralizedFunctionType)
+            listener: endFormalParameters(1, (, ), MemberKind.GeneralizedFunctionType)
+        listener: endFunctionType(Function, null)
+        ensureSemicolon())
+        listener: endFunctionTypeAlias(typedef, =, ;)
+  listener: endTopLevelDeclaration(typedef)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(typedef)
+      listener: endMetadataStar(0)
+    parseTopLevelKeywordDeclaration(;, typedef, Instance of 'DirectiveContext')
+      parseTopLevelKeywordModifiers(;, typedef)
+      parseTypedef(typedef)
+        listener: beginUncategorizedTopLevelDeclaration(typedef)
+        listener: beginFunctionTypeAlias(typedef)
+        ensureIdentifierPotentiallyRecovered(typedef, typedefDeclaration, true)
+          listener: handleIdentifier(F, typedefDeclaration)
+        listener: beginTypeVariables(<)
+        parseMetadataStar(<)
+          listener: beginMetadataStar(@)
+          parseMetadata(<)
+            listener: beginMetadata(@)
+            ensureIdentifier(@, metadataReference)
+              listener: handleIdentifier(foo, metadataReference)
+            parseQualifiedRestOpt(foo, metadataContinuation)
+              parseQualifiedRest(foo, metadataContinuation)
+                ensureIdentifier(., metadataContinuation)
+                  inPlainSync()
+                  listener: handleIdentifier(abstract, metadataContinuation)
+                listener: handleQualified(.)
+            listener: handleNoTypeArguments(()
+            parseArgumentsOpt(abstract)
+              parseArguments(abstract)
+                parseArgumentsRest(()
+                  listener: beginArguments(()
+                  parseExpression(()
+                    parsePrecedenceExpression((, 1, true)
+                      parseUnaryExpression((, true)
+                        parsePrimary((, expression)
+                          parseLiteralString(()
+                            parseSingleLiteralString(()
+                              listener: beginLiteralString("hello")
+                              listener: endLiteralString(0, ))
+                  listener: endArguments(1, (, ))
+            listener: endMetadata(@, null, T)
+          listener: endMetadataStar(1)
+        ensureIdentifier(), typeVariableDeclaration)
+          listener: handleIdentifier(T, typeVariableDeclaration)
+        listener: beginTypeVariable(T)
+        listener: handleTypeVariablesDefined(T, 1)
+        listener: handleNoType(T)
+        listener: endTypeVariable(>, 0, null, null)
+        listener: endTypeVariables(<, >)
+        listener: beginFunctionType(int)
+        listener: beginTypeVariables(<)
+        parseMetadataStar(<)
+          listener: beginMetadataStar(@)
+          parseMetadata(<)
+            listener: beginMetadata(@)
+            ensureIdentifier(@, metadataReference)
+              listener: handleIdentifier(foo, metadataReference)
+            parseQualifiedRestOpt(foo, metadataContinuation)
+              parseQualifiedRest(foo, metadataContinuation)
+                ensureIdentifier(., metadataContinuation)
+                  inPlainSync()
+                  listener: handleIdentifier(abstract, metadataContinuation)
+                listener: handleQualified(.)
+            listener: handleNoTypeArguments(()
+            parseArgumentsOpt(abstract)
+              parseArguments(abstract)
+                parseArgumentsRest(()
+                  listener: beginArguments(()
+                  parseExpression(()
+                    parsePrecedenceExpression((, 1, true)
+                      parseUnaryExpression((, true)
+                        parsePrimary((, expression)
+                          parseLiteralString(()
+                            parseSingleLiteralString(()
+                              listener: beginLiteralString("hello")
+                              listener: endLiteralString(0, ))
+                  listener: endArguments(1, (, ))
+            listener: endMetadata(@, null, X)
+          listener: endMetadataStar(1)
+        ensureIdentifier(), typeVariableDeclaration)
+          listener: handleIdentifier(X, typeVariableDeclaration)
+        listener: beginTypeVariable(X)
+        listener: handleTypeVariablesDefined(X, 1)
+        listener: handleNoType(X)
+        listener: endTypeVariable(>, 0, null, null)
+        listener: endTypeVariables(<, >)
+        ensureIdentifier(=, typeReference)
+          listener: handleIdentifier(int, typeReference)
+        listener: handleNoTypeArguments(Function)
+        listener: handleType(int, null)
+        parseFormalParametersRequiredOpt(>, MemberKind.GeneralizedFunctionType)
+          parseFormalParametersRest((, MemberKind.GeneralizedFunctionType)
+            listener: beginFormalParameters((, MemberKind.GeneralizedFunctionType)
+            parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.GeneralizedFunctionType)
+              parseMetadataStar(()
+                listener: beginMetadataStar(@)
+                parseMetadata(()
+                  listener: beginMetadata(@)
+                  ensureIdentifier(@, metadataReference)
+                    listener: handleIdentifier(foo, metadataReference)
+                  parseQualifiedRestOpt(foo, metadataContinuation)
+                    parseQualifiedRest(foo, metadataContinuation)
+                      ensureIdentifier(., metadataContinuation)
+                        inPlainSync()
+                        listener: handleIdentifier(abstract, metadataContinuation)
+                      listener: handleQualified(.)
+                  listener: handleNoTypeArguments(()
+                  parseArgumentsOpt(abstract)
+                    parseArguments(abstract)
+                      parseArgumentsRest(()
+                        listener: beginArguments(()
+                        parseExpression(()
+                          parsePrecedenceExpression((, 1, true)
+                            parseUnaryExpression((, true)
+                              parsePrimary((, expression)
+                                parseLiteralString(()
+                                  parseSingleLiteralString(()
+                                    listener: beginLiteralString("hello")
+                                    listener: endLiteralString(0, ))
+                        listener: endArguments(1, (, ))
+                  listener: endMetadata(@, null, int)
+                listener: endMetadataStar(1)
+              listener: beginFormalParameter(int, MemberKind.GeneralizedFunctionType, null, null, null)
+              listener: handleIdentifier(int, typeReference)
+              listener: handleNoTypeArguments())
+              listener: handleType(int, null)
+              listener: handleNoName())
+              listener: handleFormalParameterWithoutValue())
+              listener: endFormalParameter(null, null, ), null, null, FormalParameterKind.mandatory, MemberKind.GeneralizedFunctionType)
+            listener: endFormalParameters(1, (, ), MemberKind.GeneralizedFunctionType)
+        listener: endFunctionType(Function, null)
+        ensureSemicolon())
+        listener: endFunctionTypeAlias(typedef, =, ;)
+  listener: endTopLevelDeclaration(typedef)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(typedef)
+      listener: endMetadataStar(0)
+    parseTopLevelKeywordDeclaration(;, typedef, Instance of 'DirectiveContext')
+      parseTopLevelKeywordModifiers(;, typedef)
+      parseTypedef(typedef)
+        listener: beginUncategorizedTopLevelDeclaration(typedef)
+        listener: beginFunctionTypeAlias(typedef)
+        ensureIdentifierPotentiallyRecovered(typedef, typedefDeclaration, true)
+          listener: handleIdentifier(F, typedefDeclaration)
+        listener: beginTypeVariables(<)
+        parseMetadataStar(<)
+          listener: beginMetadataStar(@)
+          parseMetadata(<)
+            listener: beginMetadata(@)
+            ensureIdentifier(@, metadataReference)
+              listener: handleIdentifier(foo, metadataReference)
+            parseQualifiedRestOpt(foo, metadataContinuation)
+              parseQualifiedRest(foo, metadataContinuation)
+                ensureIdentifier(., metadataContinuation)
+                  listener: handleIdentifier(bar, metadataContinuation)
+                listener: handleQualified(.)
+            listener: handleNoTypeArguments(.)
+            ensureIdentifier(., metadataContinuationAfterTypeArguments)
+              inPlainSync()
+              listener: handleIdentifier(abstract, metadataContinuationAfterTypeArguments)
+            parseArgumentsOpt(abstract)
+              parseArguments(abstract)
+                parseArgumentsRest(()
+                  listener: beginArguments(()
+                  parseExpression(()
+                    parsePrecedenceExpression((, 1, true)
+                      parseUnaryExpression((, true)
+                        parsePrimary((, expression)
+                          parseLiteralString(()
+                            parseSingleLiteralString(()
+                              listener: beginLiteralString("hello")
+                              listener: endLiteralString(0, ))
+                  listener: endArguments(1, (, ))
+            listener: endMetadata(@, ., T)
+          listener: endMetadataStar(1)
+        ensureIdentifier(), typeVariableDeclaration)
+          listener: handleIdentifier(T, typeVariableDeclaration)
+        listener: beginTypeVariable(T)
+        listener: handleTypeVariablesDefined(T, 1)
+        listener: handleNoType(T)
+        listener: endTypeVariable(>, 0, null, null)
+        listener: endTypeVariables(<, >)
+        listener: beginFunctionType(int)
+        listener: beginTypeVariables(<)
+        parseMetadataStar(<)
+          listener: beginMetadataStar(@)
+          parseMetadata(<)
+            listener: beginMetadata(@)
+            ensureIdentifier(@, metadataReference)
+              listener: handleIdentifier(foo, metadataReference)
+            parseQualifiedRestOpt(foo, metadataContinuation)
+              parseQualifiedRest(foo, metadataContinuation)
+                ensureIdentifier(., metadataContinuation)
+                  listener: handleIdentifier(bar, metadataContinuation)
+                listener: handleQualified(.)
+            listener: handleNoTypeArguments(.)
+            ensureIdentifier(., metadataContinuationAfterTypeArguments)
+              inPlainSync()
+              listener: handleIdentifier(abstract, metadataContinuationAfterTypeArguments)
+            parseArgumentsOpt(abstract)
+              parseArguments(abstract)
+                parseArgumentsRest(()
+                  listener: beginArguments(()
+                  parseExpression(()
+                    parsePrecedenceExpression((, 1, true)
+                      parseUnaryExpression((, true)
+                        parsePrimary((, expression)
+                          parseLiteralString(()
+                            parseSingleLiteralString(()
+                              listener: beginLiteralString("hello")
+                              listener: endLiteralString(0, ))
+                  listener: endArguments(1, (, ))
+            listener: endMetadata(@, ., X)
+          listener: endMetadataStar(1)
+        ensureIdentifier(), typeVariableDeclaration)
+          listener: handleIdentifier(X, typeVariableDeclaration)
+        listener: beginTypeVariable(X)
+        listener: handleTypeVariablesDefined(X, 1)
+        listener: handleNoType(X)
+        listener: endTypeVariable(>, 0, null, null)
+        listener: endTypeVariables(<, >)
+        ensureIdentifier(=, typeReference)
+          listener: handleIdentifier(int, typeReference)
+        listener: handleNoTypeArguments(Function)
+        listener: handleType(int, null)
+        parseFormalParametersRequiredOpt(>, MemberKind.GeneralizedFunctionType)
+          parseFormalParametersRest((, MemberKind.GeneralizedFunctionType)
+            listener: beginFormalParameters((, MemberKind.GeneralizedFunctionType)
+            parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.GeneralizedFunctionType)
+              parseMetadataStar(()
+                listener: beginMetadataStar(@)
+                parseMetadata(()
+                  listener: beginMetadata(@)
+                  ensureIdentifier(@, metadataReference)
+                    listener: handleIdentifier(foo, metadataReference)
+                  parseQualifiedRestOpt(foo, metadataContinuation)
+                    parseQualifiedRest(foo, metadataContinuation)
+                      ensureIdentifier(., metadataContinuation)
+                        listener: handleIdentifier(bar, metadataContinuation)
+                      listener: handleQualified(.)
+                  listener: handleNoTypeArguments(.)
+                  ensureIdentifier(., metadataContinuationAfterTypeArguments)
+                    inPlainSync()
+                    listener: handleIdentifier(abstract, metadataContinuationAfterTypeArguments)
+                  parseArgumentsOpt(abstract)
+                    parseArguments(abstract)
+                      parseArgumentsRest(()
+                        listener: beginArguments(()
+                        parseExpression(()
+                          parsePrecedenceExpression((, 1, true)
+                            parseUnaryExpression((, true)
+                              parsePrimary((, expression)
+                                parseLiteralString(()
+                                  parseSingleLiteralString(()
+                                    listener: beginLiteralString("hello")
+                                    listener: endLiteralString(0, ))
+                        listener: endArguments(1, (, ))
+                  listener: endMetadata(@, ., int)
+                listener: endMetadataStar(1)
+              listener: beginFormalParameter(int, MemberKind.GeneralizedFunctionType, null, null, null)
+              listener: handleIdentifier(int, typeReference)
+              listener: handleNoTypeArguments())
+              listener: handleType(int, null)
+              listener: handleNoName())
+              listener: handleFormalParameterWithoutValue())
+              listener: endFormalParameter(null, null, ), null, null, FormalParameterKind.mandatory, MemberKind.GeneralizedFunctionType)
+            listener: endFormalParameters(1, (, ), MemberKind.GeneralizedFunctionType)
+        listener: endFunctionType(Function, null)
+        ensureSemicolon())
+        listener: endFunctionTypeAlias(typedef, =, ;)
+  listener: endTopLevelDeclaration(typedef)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(typedef)
+      listener: endMetadataStar(0)
+    parseTopLevelKeywordDeclaration(;, typedef, Instance of 'DirectiveContext')
+      parseTopLevelKeywordModifiers(;, typedef)
+      parseTypedef(typedef)
+        listener: beginUncategorizedTopLevelDeclaration(typedef)
+        listener: beginFunctionTypeAlias(typedef)
+        ensureIdentifierPotentiallyRecovered(typedef, typedefDeclaration, true)
+          listener: handleIdentifier(F, typedefDeclaration)
+        listener: beginTypeVariables(<)
+        parseMetadataStar(<)
+          listener: beginMetadataStar(@)
+          parseMetadata(<)
+            listener: beginMetadata(@)
+            ensureIdentifier(@, metadataReference)
+              listener: handleIdentifier(foo, metadataReference)
+            parseQualifiedRestOpt(foo, metadataContinuation)
+            listener: beginTypeArguments(<)
+            listener: handleIdentifier(int, typeReference)
+            listener: handleNoTypeArguments(>)
+            listener: handleType(int, null)
+            listener: endTypeArguments(1, <, >)
+            parseArgumentsOpt(>)
+              parseArguments(>)
+                parseArgumentsRest(()
+                  listener: beginArguments(()
+                  parseExpression(()
+                    parsePrecedenceExpression((, 1, true)
+                      parseUnaryExpression((, true)
+                        parsePrimary((, expression)
+                          parseLiteralString(()
+                            parseSingleLiteralString(()
+                              listener: beginLiteralString("hello")
+                              listener: endLiteralString(0, ))
+                  listener: endArguments(1, (, ))
+            listener: endMetadata(@, null, T)
+          listener: endMetadataStar(1)
+        ensureIdentifier(), typeVariableDeclaration)
+          listener: handleIdentifier(T, typeVariableDeclaration)
+        listener: beginTypeVariable(T)
+        listener: handleTypeVariablesDefined(T, 1)
+        listener: handleNoType(T)
+        listener: endTypeVariable(>, 0, null, null)
+        listener: endTypeVariables(<, >)
+        listener: beginFunctionType(int)
+        listener: beginTypeVariables(<)
+        parseMetadataStar(<)
+          listener: beginMetadataStar(@)
+          parseMetadata(<)
+            listener: beginMetadata(@)
+            ensureIdentifier(@, metadataReference)
+              listener: handleIdentifier(foo, metadataReference)
+            parseQualifiedRestOpt(foo, metadataContinuation)
+            listener: beginTypeArguments(<)
+            listener: handleIdentifier(int, typeReference)
+            listener: handleNoTypeArguments(>)
+            listener: handleType(int, null)
+            listener: endTypeArguments(1, <, >)
+            parseArgumentsOpt(>)
+              parseArguments(>)
+                parseArgumentsRest(()
+                  listener: beginArguments(()
+                  parseExpression(()
+                    parsePrecedenceExpression((, 1, true)
+                      parseUnaryExpression((, true)
+                        parsePrimary((, expression)
+                          parseLiteralString(()
+                            parseSingleLiteralString(()
+                              listener: beginLiteralString("hello")
+                              listener: endLiteralString(0, ))
+                  listener: endArguments(1, (, ))
+            listener: endMetadata(@, null, X)
+          listener: endMetadataStar(1)
+        ensureIdentifier(), typeVariableDeclaration)
+          listener: handleIdentifier(X, typeVariableDeclaration)
+        listener: beginTypeVariable(X)
+        listener: handleTypeVariablesDefined(X, 1)
+        listener: handleNoType(X)
+        listener: endTypeVariable(>, 0, null, null)
+        listener: endTypeVariables(<, >)
+        ensureIdentifier(=, typeReference)
+          listener: handleIdentifier(int, typeReference)
+        listener: handleNoTypeArguments(Function)
+        listener: handleType(int, null)
+        parseFormalParametersRequiredOpt(>, MemberKind.GeneralizedFunctionType)
+          parseFormalParametersRest((, MemberKind.GeneralizedFunctionType)
+            listener: beginFormalParameters((, MemberKind.GeneralizedFunctionType)
+            parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.GeneralizedFunctionType)
+              parseMetadataStar(()
+                listener: beginMetadataStar(@)
+                parseMetadata(()
+                  listener: beginMetadata(@)
+                  ensureIdentifier(@, metadataReference)
+                    listener: handleIdentifier(foo, metadataReference)
+                  parseQualifiedRestOpt(foo, metadataContinuation)
+                  listener: beginTypeArguments(<)
+                  listener: handleIdentifier(int, typeReference)
+                  listener: handleNoTypeArguments(>)
+                  listener: handleType(int, null)
+                  listener: endTypeArguments(1, <, >)
+                  parseArgumentsOpt(>)
+                    parseArguments(>)
+                      parseArgumentsRest(()
+                        listener: beginArguments(()
+                        parseExpression(()
+                          parsePrecedenceExpression((, 1, true)
+                            parseUnaryExpression((, true)
+                              parsePrimary((, expression)
+                                parseLiteralString(()
+                                  parseSingleLiteralString(()
+                                    listener: beginLiteralString("hello")
+                                    listener: endLiteralString(0, ))
+                        listener: endArguments(1, (, ))
+                  listener: endMetadata(@, null, int)
+                listener: endMetadataStar(1)
+              listener: beginFormalParameter(int, MemberKind.GeneralizedFunctionType, null, null, null)
+              listener: handleIdentifier(int, typeReference)
+              listener: handleNoTypeArguments())
+              listener: handleType(int, null)
+              listener: handleNoName())
+              listener: handleFormalParameterWithoutValue())
+              listener: endFormalParameter(null, null, ), null, null, FormalParameterKind.mandatory, MemberKind.GeneralizedFunctionType)
+            listener: endFormalParameters(1, (, ), MemberKind.GeneralizedFunctionType)
+        listener: endFunctionType(Function, null)
+        ensureSemicolon())
+        listener: endFunctionTypeAlias(typedef, =, ;)
+  listener: endTopLevelDeclaration(typedef)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(typedef)
+      listener: endMetadataStar(0)
+    parseTopLevelKeywordDeclaration(;, typedef, Instance of 'DirectiveContext')
+      parseTopLevelKeywordModifiers(;, typedef)
+      parseTypedef(typedef)
+        listener: beginUncategorizedTopLevelDeclaration(typedef)
+        listener: beginFunctionTypeAlias(typedef)
+        ensureIdentifierPotentiallyRecovered(typedef, typedefDeclaration, true)
+          listener: handleIdentifier(F, typedefDeclaration)
+        listener: beginTypeVariables(<)
+        parseMetadataStar(<)
+          listener: beginMetadataStar(@)
+          parseMetadata(<)
+            listener: beginMetadata(@)
+            ensureIdentifier(@, metadataReference)
+              listener: handleIdentifier(foo, metadataReference)
+            parseQualifiedRestOpt(foo, metadataContinuation)
+            listener: beginTypeArguments(<)
+            listener: handleIdentifier(int, typeReference)
+            listener: handleNoTypeArguments(>)
+            listener: handleType(int, null)
+            listener: endTypeArguments(1, <, >)
+            ensureIdentifier(., metadataContinuationAfterTypeArguments)
+              inPlainSync()
+              listener: handleIdentifier(abstract, metadataContinuationAfterTypeArguments)
+            parseArgumentsOpt(abstract)
+              parseArguments(abstract)
+                parseArgumentsRest(()
+                  listener: beginArguments(()
+                  parseExpression(()
+                    parsePrecedenceExpression((, 1, true)
+                      parseUnaryExpression((, true)
+                        parsePrimary((, expression)
+                          parseLiteralString(()
+                            parseSingleLiteralString(()
+                              listener: beginLiteralString("hello")
+                              listener: endLiteralString(0, ))
+                  listener: endArguments(1, (, ))
+            listener: endMetadata(@, ., T)
+          listener: endMetadataStar(1)
+        ensureIdentifier(), typeVariableDeclaration)
+          listener: handleIdentifier(T, typeVariableDeclaration)
+        listener: beginTypeVariable(T)
+        listener: handleTypeVariablesDefined(T, 1)
+        listener: handleNoType(T)
+        listener: endTypeVariable(>, 0, null, null)
+        listener: endTypeVariables(<, >)
+        listener: beginFunctionType(int)
+        listener: beginTypeVariables(<)
+        parseMetadataStar(<)
+          listener: beginMetadataStar(@)
+          parseMetadata(<)
+            listener: beginMetadata(@)
+            ensureIdentifier(@, metadataReference)
+              listener: handleIdentifier(foo, metadataReference)
+            parseQualifiedRestOpt(foo, metadataContinuation)
+            listener: beginTypeArguments(<)
+            listener: handleIdentifier(int, typeReference)
+            listener: handleNoTypeArguments(>)
+            listener: handleType(int, null)
+            listener: endTypeArguments(1, <, >)
+            ensureIdentifier(., metadataContinuationAfterTypeArguments)
+              inPlainSync()
+              listener: handleIdentifier(abstract, metadataContinuationAfterTypeArguments)
+            parseArgumentsOpt(abstract)
+              parseArguments(abstract)
+                parseArgumentsRest(()
+                  listener: beginArguments(()
+                  parseExpression(()
+                    parsePrecedenceExpression((, 1, true)
+                      parseUnaryExpression((, true)
+                        parsePrimary((, expression)
+                          parseLiteralString(()
+                            parseSingleLiteralString(()
+                              listener: beginLiteralString("hello")
+                              listener: endLiteralString(0, ))
+                  listener: endArguments(1, (, ))
+            listener: endMetadata(@, ., X)
+          listener: endMetadataStar(1)
+        ensureIdentifier(), typeVariableDeclaration)
+          listener: handleIdentifier(X, typeVariableDeclaration)
+        listener: beginTypeVariable(X)
+        listener: handleTypeVariablesDefined(X, 1)
+        listener: handleNoType(X)
+        listener: endTypeVariable(>, 0, null, null)
+        listener: endTypeVariables(<, >)
+        ensureIdentifier(=, typeReference)
+          listener: handleIdentifier(int, typeReference)
+        listener: handleNoTypeArguments(Function)
+        listener: handleType(int, null)
+        parseFormalParametersRequiredOpt(>, MemberKind.GeneralizedFunctionType)
+          parseFormalParametersRest((, MemberKind.GeneralizedFunctionType)
+            listener: beginFormalParameters((, MemberKind.GeneralizedFunctionType)
+            parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.GeneralizedFunctionType)
+              parseMetadataStar(()
+                listener: beginMetadataStar(@)
+                parseMetadata(()
+                  listener: beginMetadata(@)
+                  ensureIdentifier(@, metadataReference)
+                    listener: handleIdentifier(foo, metadataReference)
+                  parseQualifiedRestOpt(foo, metadataContinuation)
+                  listener: beginTypeArguments(<)
+                  listener: handleIdentifier(int, typeReference)
+                  listener: handleNoTypeArguments(>)
+                  listener: handleType(int, null)
+                  listener: endTypeArguments(1, <, >)
+                  ensureIdentifier(., metadataContinuationAfterTypeArguments)
+                    inPlainSync()
+                    listener: handleIdentifier(abstract, metadataContinuationAfterTypeArguments)
+                  parseArgumentsOpt(abstract)
+                    parseArguments(abstract)
+                      parseArgumentsRest(()
+                        listener: beginArguments(()
+                        parseExpression(()
+                          parsePrecedenceExpression((, 1, true)
+                            parseUnaryExpression((, true)
+                              parsePrimary((, expression)
+                                parseLiteralString(()
+                                  parseSingleLiteralString(()
+                                    listener: beginLiteralString("hello")
+                                    listener: endLiteralString(0, ))
+                        listener: endArguments(1, (, ))
+                  listener: endMetadata(@, ., int)
+                listener: endMetadataStar(1)
+              listener: beginFormalParameter(int, MemberKind.GeneralizedFunctionType, null, null, null)
+              listener: handleIdentifier(int, typeReference)
+              listener: handleNoTypeArguments())
+              listener: handleType(int, null)
+              listener: handleNoName())
+              listener: handleFormalParameterWithoutValue())
+              listener: endFormalParameter(null, null, ), null, null, FormalParameterKind.mandatory, MemberKind.GeneralizedFunctionType)
+            listener: endFormalParameters(1, (, ), MemberKind.GeneralizedFunctionType)
+        listener: endFunctionType(Function, null)
+        ensureSemicolon())
+        listener: endFunctionTypeAlias(typedef, =, ;)
+  listener: endTopLevelDeclaration(typedef)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(typedef)
+      listener: endMetadataStar(0)
+    parseTopLevelKeywordDeclaration(;, typedef, Instance of 'DirectiveContext')
+      parseTopLevelKeywordModifiers(;, typedef)
+      parseTypedef(typedef)
+        listener: beginUncategorizedTopLevelDeclaration(typedef)
+        listener: beginFunctionTypeAlias(typedef)
+        ensureIdentifierPotentiallyRecovered(typedef, typedefDeclaration, true)
+          listener: handleIdentifier(F, typedefDeclaration)
+        listener: beginTypeVariables(<)
+        parseMetadataStar(<)
+          listener: beginMetadataStar(@)
+          parseMetadata(<)
+            listener: beginMetadata(@)
+            ensureIdentifier(@, metadataReference)
+              listener: handleIdentifier(foo, metadataReference)
+            parseQualifiedRestOpt(foo, metadataContinuation)
+              parseQualifiedRest(foo, metadataContinuation)
+                ensureIdentifier(., metadataContinuation)
+                  listener: handleIdentifier(bar, metadataContinuation)
+                listener: handleQualified(.)
+            listener: beginTypeArguments(<)
+            listener: handleIdentifier(int, typeReference)
+            listener: handleNoTypeArguments(>)
+            listener: handleType(int, null)
+            listener: endTypeArguments(1, <, >)
+            parseArgumentsOpt(>)
+              parseArguments(>)
+                parseArgumentsRest(()
+                  listener: beginArguments(()
+                  parseExpression(()
+                    parsePrecedenceExpression((, 1, true)
+                      parseUnaryExpression((, true)
+                        parsePrimary((, expression)
+                          parseLiteralString(()
+                            parseSingleLiteralString(()
+                              listener: beginLiteralString("hello")
+                              listener: endLiteralString(0, ))
+                  listener: endArguments(1, (, ))
+            listener: endMetadata(@, null, T)
+          listener: endMetadataStar(1)
+        ensureIdentifier(), typeVariableDeclaration)
+          listener: handleIdentifier(T, typeVariableDeclaration)
+        listener: beginTypeVariable(T)
+        listener: handleTypeVariablesDefined(T, 1)
+        listener: handleNoType(T)
+        listener: endTypeVariable(>, 0, null, null)
+        listener: endTypeVariables(<, >)
+        listener: beginFunctionType(int)
+        listener: beginTypeVariables(<)
+        parseMetadataStar(<)
+          listener: beginMetadataStar(@)
+          parseMetadata(<)
+            listener: beginMetadata(@)
+            ensureIdentifier(@, metadataReference)
+              listener: handleIdentifier(foo, metadataReference)
+            parseQualifiedRestOpt(foo, metadataContinuation)
+              parseQualifiedRest(foo, metadataContinuation)
+                ensureIdentifier(., metadataContinuation)
+                  listener: handleIdentifier(bar, metadataContinuation)
+                listener: handleQualified(.)
+            listener: beginTypeArguments(<)
+            listener: handleIdentifier(int, typeReference)
+            listener: handleNoTypeArguments(>)
+            listener: handleType(int, null)
+            listener: endTypeArguments(1, <, >)
+            parseArgumentsOpt(>)
+              parseArguments(>)
+                parseArgumentsRest(()
+                  listener: beginArguments(()
+                  parseExpression(()
+                    parsePrecedenceExpression((, 1, true)
+                      parseUnaryExpression((, true)
+                        parsePrimary((, expression)
+                          parseLiteralString(()
+                            parseSingleLiteralString(()
+                              listener: beginLiteralString("hello")
+                              listener: endLiteralString(0, ))
+                  listener: endArguments(1, (, ))
+            listener: endMetadata(@, null, X)
+          listener: endMetadataStar(1)
+        ensureIdentifier(), typeVariableDeclaration)
+          listener: handleIdentifier(X, typeVariableDeclaration)
+        listener: beginTypeVariable(X)
+        listener: handleTypeVariablesDefined(X, 1)
+        listener: handleNoType(X)
+        listener: endTypeVariable(>, 0, null, null)
+        listener: endTypeVariables(<, >)
+        ensureIdentifier(=, typeReference)
+          listener: handleIdentifier(int, typeReference)
+        listener: handleNoTypeArguments(Function)
+        listener: handleType(int, null)
+        parseFormalParametersRequiredOpt(>, MemberKind.GeneralizedFunctionType)
+          parseFormalParametersRest((, MemberKind.GeneralizedFunctionType)
+            listener: beginFormalParameters((, MemberKind.GeneralizedFunctionType)
+            parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.GeneralizedFunctionType)
+              parseMetadataStar(()
+                listener: beginMetadataStar(@)
+                parseMetadata(()
+                  listener: beginMetadata(@)
+                  ensureIdentifier(@, metadataReference)
+                    listener: handleIdentifier(foo, metadataReference)
+                  parseQualifiedRestOpt(foo, metadataContinuation)
+                    parseQualifiedRest(foo, metadataContinuation)
+                      ensureIdentifier(., metadataContinuation)
+                        listener: handleIdentifier(bar, metadataContinuation)
+                      listener: handleQualified(.)
+                  listener: beginTypeArguments(<)
+                  listener: handleIdentifier(int, typeReference)
+                  listener: handleNoTypeArguments(>)
+                  listener: handleType(int, null)
+                  listener: endTypeArguments(1, <, >)
+                  parseArgumentsOpt(>)
+                    parseArguments(>)
+                      parseArgumentsRest(()
+                        listener: beginArguments(()
+                        parseExpression(()
+                          parsePrecedenceExpression((, 1, true)
+                            parseUnaryExpression((, true)
+                              parsePrimary((, expression)
+                                parseLiteralString(()
+                                  parseSingleLiteralString(()
+                                    listener: beginLiteralString("hello")
+                                    listener: endLiteralString(0, ))
+                        listener: endArguments(1, (, ))
+                  listener: endMetadata(@, null, int)
+                listener: endMetadataStar(1)
+              listener: beginFormalParameter(int, MemberKind.GeneralizedFunctionType, null, null, null)
+              listener: handleIdentifier(int, typeReference)
+              listener: handleNoTypeArguments())
+              listener: handleType(int, null)
+              listener: handleNoName())
+              listener: handleFormalParameterWithoutValue())
+              listener: endFormalParameter(null, null, ), null, null, FormalParameterKind.mandatory, MemberKind.GeneralizedFunctionType)
+            listener: endFormalParameters(1, (, ), MemberKind.GeneralizedFunctionType)
+        listener: endFunctionType(Function, null)
+        ensureSemicolon())
+        listener: endFunctionTypeAlias(typedef, =, ;)
+  listener: endTopLevelDeclaration(typedef)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(typedef)
+      listener: endMetadataStar(0)
+    parseTopLevelKeywordDeclaration(;, typedef, Instance of 'DirectiveContext')
+      parseTopLevelKeywordModifiers(;, typedef)
+      parseTypedef(typedef)
+        listener: beginUncategorizedTopLevelDeclaration(typedef)
+        listener: beginFunctionTypeAlias(typedef)
+        ensureIdentifierPotentiallyRecovered(typedef, typedefDeclaration, true)
+          listener: handleIdentifier(F, typedefDeclaration)
+        listener: beginTypeVariables(<)
+        parseMetadataStar(<)
+          listener: beginMetadataStar(@)
+          parseMetadata(<)
+            listener: beginMetadata(@)
+            ensureIdentifier(@, metadataReference)
+              listener: handleIdentifier(foo, metadataReference)
+            parseQualifiedRestOpt(foo, metadataContinuation)
+              parseQualifiedRest(foo, metadataContinuation)
+                ensureIdentifier(., metadataContinuation)
+                  listener: handleIdentifier(bar, metadataContinuation)
+                listener: handleQualified(.)
+            listener: beginTypeArguments(<)
+            listener: handleIdentifier(int, typeReference)
+            listener: handleNoTypeArguments(>)
+            listener: handleType(int, null)
+            listener: endTypeArguments(1, <, >)
+            ensureIdentifier(., metadataContinuationAfterTypeArguments)
+              inPlainSync()
+              listener: handleIdentifier(abstract, metadataContinuationAfterTypeArguments)
+            parseArgumentsOpt(abstract)
+              parseArguments(abstract)
+                parseArgumentsRest(()
+                  listener: beginArguments(()
+                  parseExpression(()
+                    parsePrecedenceExpression((, 1, true)
+                      parseUnaryExpression((, true)
+                        parsePrimary((, expression)
+                          parseLiteralString(()
+                            parseSingleLiteralString(()
+                              listener: beginLiteralString("hello")
+                              listener: endLiteralString(0, ))
+                  listener: endArguments(1, (, ))
+            listener: endMetadata(@, ., T)
+          listener: endMetadataStar(1)
+        ensureIdentifier(), typeVariableDeclaration)
+          listener: handleIdentifier(T, typeVariableDeclaration)
+        listener: beginTypeVariable(T)
+        listener: handleTypeVariablesDefined(T, 1)
+        listener: handleNoType(T)
+        listener: endTypeVariable(>, 0, null, null)
+        listener: endTypeVariables(<, >)
+        listener: beginFunctionType(int)
+        listener: beginTypeVariables(<)
+        parseMetadataStar(<)
+          listener: beginMetadataStar(@)
+          parseMetadata(<)
+            listener: beginMetadata(@)
+            ensureIdentifier(@, metadataReference)
+              listener: handleIdentifier(foo, metadataReference)
+            parseQualifiedRestOpt(foo, metadataContinuation)
+              parseQualifiedRest(foo, metadataContinuation)
+                ensureIdentifier(., metadataContinuation)
+                  listener: handleIdentifier(bar, metadataContinuation)
+                listener: handleQualified(.)
+            listener: beginTypeArguments(<)
+            listener: handleIdentifier(int, typeReference)
+            listener: handleNoTypeArguments(>)
+            listener: handleType(int, null)
+            listener: endTypeArguments(1, <, >)
+            ensureIdentifier(., metadataContinuationAfterTypeArguments)
+              inPlainSync()
+              listener: handleIdentifier(abstract, metadataContinuationAfterTypeArguments)
+            parseArgumentsOpt(abstract)
+              parseArguments(abstract)
+                parseArgumentsRest(()
+                  listener: beginArguments(()
+                  parseExpression(()
+                    parsePrecedenceExpression((, 1, true)
+                      parseUnaryExpression((, true)
+                        parsePrimary((, expression)
+                          parseLiteralString(()
+                            parseSingleLiteralString(()
+                              listener: beginLiteralString("hello")
+                              listener: endLiteralString(0, ))
+                  listener: endArguments(1, (, ))
+            listener: endMetadata(@, ., X)
+          listener: endMetadataStar(1)
+        ensureIdentifier(), typeVariableDeclaration)
+          listener: handleIdentifier(X, typeVariableDeclaration)
+        listener: beginTypeVariable(X)
+        listener: handleTypeVariablesDefined(X, 1)
+        listener: handleNoType(X)
+        listener: endTypeVariable(>, 0, null, null)
+        listener: endTypeVariables(<, >)
+        ensureIdentifier(=, typeReference)
+          listener: handleIdentifier(int, typeReference)
+        listener: handleNoTypeArguments(Function)
+        listener: handleType(int, null)
+        parseFormalParametersRequiredOpt(>, MemberKind.GeneralizedFunctionType)
+          parseFormalParametersRest((, MemberKind.GeneralizedFunctionType)
+            listener: beginFormalParameters((, MemberKind.GeneralizedFunctionType)
+            parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.GeneralizedFunctionType)
+              parseMetadataStar(()
+                listener: beginMetadataStar(@)
+                parseMetadata(()
+                  listener: beginMetadata(@)
+                  ensureIdentifier(@, metadataReference)
+                    listener: handleIdentifier(foo, metadataReference)
+                  parseQualifiedRestOpt(foo, metadataContinuation)
+                    parseQualifiedRest(foo, metadataContinuation)
+                      ensureIdentifier(., metadataContinuation)
+                        listener: handleIdentifier(bar, metadataContinuation)
+                      listener: handleQualified(.)
+                  listener: beginTypeArguments(<)
+                  listener: handleIdentifier(int, typeReference)
+                  listener: handleNoTypeArguments(>)
+                  listener: handleType(int, null)
+                  listener: endTypeArguments(1, <, >)
+                  ensureIdentifier(., metadataContinuationAfterTypeArguments)
+                    inPlainSync()
+                    listener: handleIdentifier(abstract, metadataContinuationAfterTypeArguments)
+                  parseArgumentsOpt(abstract)
+                    parseArguments(abstract)
+                      parseArgumentsRest(()
+                        listener: beginArguments(()
+                        parseExpression(()
+                          parsePrecedenceExpression((, 1, true)
+                            parseUnaryExpression((, true)
+                              parsePrimary((, expression)
+                                parseLiteralString(()
+                                  parseSingleLiteralString(()
+                                    listener: beginLiteralString("hello")
+                                    listener: endLiteralString(0, ))
+                        listener: endArguments(1, (, ))
+                  listener: endMetadata(@, ., int)
+                listener: endMetadataStar(1)
+              listener: beginFormalParameter(int, MemberKind.GeneralizedFunctionType, null, null, null)
+              listener: handleIdentifier(int, typeReference)
+              listener: handleNoTypeArguments())
+              listener: handleType(int, null)
+              listener: handleNoName())
+              listener: handleFormalParameterWithoutValue())
+              listener: endFormalParameter(null, null, ), null, null, FormalParameterKind.mandatory, MemberKind.GeneralizedFunctionType)
+            listener: endFormalParameters(1, (, ), MemberKind.GeneralizedFunctionType)
+        listener: endFunctionType(Function, null)
+        ensureSemicolon())
+        listener: endFunctionTypeAlias(typedef, =, ;)
+  listener: endTopLevelDeclaration(@)
+  parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+    parseMetadataStar(;)
+      listener: beginMetadataStar(@)
+      parseMetadata(;)
+        listener: beginMetadata(@)
+        ensureIdentifier(@, metadataReference)
+          inPlainSync()
+          listener: handleIdentifier(abstract, metadataReference)
+        parseQualifiedRestOpt(abstract, metadataContinuation)
+          parseQualifiedRest(abstract, metadataContinuation)
+            ensureIdentifier(., metadataContinuation)
+              inPlainSync()
+              listener: handleIdentifier(abstract, metadataContinuation)
+            listener: handleQualified(.)
+        listener: handleNoTypeArguments(@)
+        parseArgumentsOpt(abstract)
+          listener: handleNoArguments(@)
+        listener: endMetadata(@, null, @)
+      parseMetadata(abstract)
+        listener: beginMetadata(@)
+        ensureIdentifier(@, metadataReference)
+          inPlainSync()
+          listener: handleIdentifier(abstract, metadataReference)
+        parseQualifiedRestOpt(abstract, metadataContinuation)
+          parseQualifiedRest(abstract, metadataContinuation)
+            ensureIdentifier(., metadataContinuation)
+              listener: handleIdentifier(bar, metadataContinuation)
+            listener: handleQualified(.)
+        listener: handleNoTypeArguments(.)
+        ensureIdentifier(., metadataContinuationAfterTypeArguments)
+          inPlainSync()
+          listener: handleIdentifier(abstract, metadataContinuationAfterTypeArguments)
+        parseArgumentsOpt(abstract)
+          listener: handleNoArguments(@)
+        listener: endMetadata(@, ., @)
+      parseMetadata(abstract)
+        listener: beginMetadata(@)
+        ensureIdentifier(@, metadataReference)
+          inPlainSync()
+          listener: handleIdentifier(abstract, metadataReference)
+        parseQualifiedRestOpt(abstract, metadataContinuation)
+        listener: handleNoTypeArguments(()
+        parseArgumentsOpt(abstract)
+          parseArguments(abstract)
+            parseArgumentsRest(()
+              listener: beginArguments(()
+              parseExpression(()
+                parsePrecedenceExpression((, 1, true)
+                  parseUnaryExpression((, true)
+                    parsePrimary((, expression)
+                      parseLiteralString(()
+                        parseSingleLiteralString(()
+                          listener: beginLiteralString("hello")
+                          listener: endLiteralString(0, ))
+              listener: endArguments(1, (, ))
+        listener: endMetadata(@, null, @)
+      parseMetadata())
+        listener: beginMetadata(@)
+        ensureIdentifier(@, metadataReference)
+          inPlainSync()
+          listener: handleIdentifier(abstract, metadataReference)
+        parseQualifiedRestOpt(abstract, metadataContinuation)
+          parseQualifiedRest(abstract, metadataContinuation)
+            ensureIdentifier(., metadataContinuation)
+              inPlainSync()
+              listener: handleIdentifier(abstract, metadataContinuation)
+            listener: handleQualified(.)
+        listener: handleNoTypeArguments(()
+        parseArgumentsOpt(abstract)
+          parseArguments(abstract)
+            parseArgumentsRest(()
+              listener: beginArguments(()
+              parseExpression(()
+                parsePrecedenceExpression((, 1, true)
+                  parseUnaryExpression((, true)
+                    parsePrimary((, expression)
+                      parseLiteralString(()
+                        parseSingleLiteralString(()
+                          listener: beginLiteralString("hello")
+                          listener: endLiteralString(0, ))
+              listener: endArguments(1, (, ))
+        listener: endMetadata(@, null, @)
+      parseMetadata())
+        listener: beginMetadata(@)
+        ensureIdentifier(@, metadataReference)
+          inPlainSync()
+          listener: handleIdentifier(abstract, metadataReference)
+        parseQualifiedRestOpt(abstract, metadataContinuation)
+          parseQualifiedRest(abstract, metadataContinuation)
+            ensureIdentifier(., metadataContinuation)
+              listener: handleIdentifier(bar, metadataContinuation)
+            listener: handleQualified(.)
+        listener: handleNoTypeArguments(.)
+        ensureIdentifier(., metadataContinuationAfterTypeArguments)
+          inPlainSync()
+          listener: handleIdentifier(abstract, metadataContinuationAfterTypeArguments)
+        parseArgumentsOpt(abstract)
+          parseArguments(abstract)
+            parseArgumentsRest(()
+              listener: beginArguments(()
+              parseExpression(()
+                parsePrecedenceExpression((, 1, true)
+                  parseUnaryExpression((, true)
+                    parsePrimary((, expression)
+                      parseLiteralString(()
+                        parseSingleLiteralString(()
+                          listener: beginLiteralString("hello")
+                          listener: endLiteralString(0, ))
+              listener: endArguments(1, (, ))
+        listener: endMetadata(@, ., @)
+      parseMetadata())
+        listener: beginMetadata(@)
+        ensureIdentifier(@, metadataReference)
+          inPlainSync()
+          listener: handleIdentifier(abstract, metadataReference)
+        parseQualifiedRestOpt(abstract, metadataContinuation)
+        listener: beginTypeArguments(<)
+        listener: handleIdentifier(int, typeReference)
+        listener: handleNoTypeArguments(>)
+        listener: handleType(int, null)
+        listener: endTypeArguments(1, <, >)
+        parseArgumentsOpt(>)
+          parseArguments(>)
+            parseArgumentsRest(()
+              listener: beginArguments(()
+              parseExpression(()
+                parsePrecedenceExpression((, 1, true)
+                  parseUnaryExpression((, true)
+                    parsePrimary((, expression)
+                      parseLiteralString(()
+                        parseSingleLiteralString(()
+                          listener: beginLiteralString("hello")
+                          listener: endLiteralString(0, ))
+              listener: endArguments(1, (, ))
+        listener: endMetadata(@, null, @)
+      parseMetadata())
+        listener: beginMetadata(@)
+        ensureIdentifier(@, metadataReference)
+          inPlainSync()
+          listener: handleIdentifier(abstract, metadataReference)
+        parseQualifiedRestOpt(abstract, metadataContinuation)
+        listener: beginTypeArguments(<)
+        listener: handleIdentifier(int, typeReference)
+        listener: handleNoTypeArguments(>)
+        listener: handleType(int, null)
+        listener: endTypeArguments(1, <, >)
+        ensureIdentifier(., metadataContinuationAfterTypeArguments)
+          inPlainSync()
+          listener: handleIdentifier(abstract, metadataContinuationAfterTypeArguments)
+        parseArgumentsOpt(abstract)
+          parseArguments(abstract)
+            parseArgumentsRest(()
+              listener: beginArguments(()
+              parseExpression(()
+                parsePrecedenceExpression((, 1, true)
+                  parseUnaryExpression((, true)
+                    parsePrimary((, expression)
+                      parseLiteralString(()
+                        parseSingleLiteralString(()
+                          listener: beginLiteralString("hello")
+                          listener: endLiteralString(0, ))
+              listener: endArguments(1, (, ))
+        listener: endMetadata(@, ., @)
+      parseMetadata())
+        listener: beginMetadata(@)
+        ensureIdentifier(@, metadataReference)
+          inPlainSync()
+          listener: handleIdentifier(abstract, metadataReference)
+        parseQualifiedRestOpt(abstract, metadataContinuation)
+          parseQualifiedRest(abstract, metadataContinuation)
+            ensureIdentifier(., metadataContinuation)
+              listener: handleIdentifier(bar, metadataContinuation)
+            listener: handleQualified(.)
+        listener: beginTypeArguments(<)
+        listener: handleIdentifier(int, typeReference)
+        listener: handleNoTypeArguments(>)
+        listener: handleType(int, null)
+        listener: endTypeArguments(1, <, >)
+        parseArgumentsOpt(>)
+          parseArguments(>)
+            parseArgumentsRest(()
+              listener: beginArguments(()
+              parseExpression(()
+                parsePrecedenceExpression((, 1, true)
+                  parseUnaryExpression((, true)
+                    parsePrimary((, expression)
+                      parseLiteralString(()
+                        parseSingleLiteralString(()
+                          listener: beginLiteralString("hello")
+                          listener: endLiteralString(0, ))
+              listener: endArguments(1, (, ))
+        listener: endMetadata(@, null, @)
+      parseMetadata())
+        listener: beginMetadata(@)
+        ensureIdentifier(@, metadataReference)
+          inPlainSync()
+          listener: handleIdentifier(abstract, metadataReference)
+        parseQualifiedRestOpt(abstract, metadataContinuation)
+          parseQualifiedRest(abstract, metadataContinuation)
+            ensureIdentifier(., metadataContinuation)
+              listener: handleIdentifier(bar, metadataContinuation)
+            listener: handleQualified(.)
+        listener: beginTypeArguments(<)
+        listener: handleIdentifier(int, typeReference)
+        listener: handleNoTypeArguments(>)
+        listener: handleType(int, null)
+        listener: endTypeArguments(1, <, >)
+        ensureIdentifier(., metadataContinuationAfterTypeArguments)
+          inPlainSync()
+          listener: handleIdentifier(abstract, metadataContinuationAfterTypeArguments)
+        parseArgumentsOpt(abstract)
+          parseArguments(abstract)
+            parseArgumentsRest(()
+              listener: beginArguments(()
+              parseExpression(()
+                parsePrecedenceExpression((, 1, true)
+                  parseUnaryExpression((, true)
+                    parsePrimary((, expression)
+                      parseLiteralString(()
+                        parseSingleLiteralString(()
+                          listener: beginLiteralString("hello")
+                          listener: endLiteralString(0, ))
+              listener: endArguments(1, (, ))
+        listener: endMetadata(@, ., class)
+      listener: endMetadataStar(9)
+    parseTopLevelKeywordDeclaration(), class, Instance of 'DirectiveContext')
+      parseClassDeclarationModifiers(), class)
+      parseClassOrNamedMixinApplication(null, class)
+        listener: beginClassOrNamedMixinApplicationPrelude(class)
+        ensureIdentifier(class, classOrMixinDeclaration)
+          listener: handleIdentifier(Y, classOrMixinDeclaration)
+        listener: handleNoTypeVariables({)
+        listener: beginClassDeclaration(class, null, Y)
+        parseClass(Y, class, class, Y)
+          parseClassHeaderOpt(Y, class, class)
+            parseClassExtendsOpt(Y)
+              listener: handleNoType(Y)
+              listener: handleClassExtends(null, 1)
+            parseWithClauseOpt(Y)
+              listener: handleClassNoWithClause()
+            parseClassOrMixinImplementsOpt(Y)
+              listener: handleClassOrMixinImplements(null, 0)
+            listener: handleClassHeader(class, class, null)
+          parseClassOrMixinOrExtensionBody(Y, DeclarationKind.Class, Y)
+            listener: beginClassOrMixinBody(DeclarationKind.Class, {)
+            notEofOrValue(}, })
+            listener: endClassOrMixinBody(DeclarationKind.Class, 0, {, })
+          listener: endClassDeclaration(class, })
+  listener: endTopLevelDeclaration()
+  reportAllErrorTokens(@)
+  listener: endCompilationUnit(12, )
diff --git a/pkg/front_end/parser_testcases/general/metadata.dart.parser.expect b/pkg/front_end/parser_testcases/general/metadata.dart.parser.expect
new file mode 100644
index 0000000..fb0a8af
--- /dev/null
+++ b/pkg/front_end/parser_testcases/general/metadata.dart.parser.expect
@@ -0,0 +1,79 @@
+@abstract
+@foo.abstract
+@foo.bar.abstract
+@foo("hello")
+@foo.abstract("hello")
+@foo.bar.abstract("hello")
+@foo<int>("hello")
+@foo<int>.abstract("hello")
+@foo.bar<int>("hello")
+@foo.bar<int>.abstract("hello")
+class X {}
+
+
+typedef F<@abstract T> = int Function<@abstract X>(@abstract int);
+typedef F<@foo.abstract T> = int Function<@foo.abstract X>(@foo.abstract int);
+typedef F<@foo.bar.abstract T> = int Function<@foo.bar.abstract X>(@foo.bar.abstract int);
+typedef F<@foo("hello") T> = int Function<@foo("hello") X>(@foo("hello") int);
+typedef F<@foo.abstract("hello") T> = int Function<@foo.abstract("hello") X>(@foo.abstract("hello") int);
+typedef F<@foo.bar.abstract("hello") T> = int Function<@foo.bar.abstract("hello") X>(@foo.bar.abstract("hello") int);
+typedef F<@foo<int>("hello") T> = int Function<@foo<int>("hello") X>(@foo<int>("hello") int);
+typedef F<@foo<int>.abstract("hello") T> = int Function<@foo<int>.abstract("hello") X>(@foo<int>.abstract("hello") int);
+typedef F<@foo.bar<int>("hello") T> = int Function<@foo.bar<int>("hello") X>(@foo.bar<int>("hello") int);
+typedef F<@foo.bar<int>.abstract("hello") T> = int Function<@foo.bar<int>.abstract("hello") X>(@foo.bar<int>.abstract("hello") int);
+
+
+
+
+
+
+@abstract.abstract
+@abstract.bar.abstract
+@abstract("hello")
+@abstract.abstract("hello")
+@abstract.bar.abstract("hello")
+@abstract<int>("hello")
+@abstract<int>.abstract("hello")
+@abstract.bar<int>("hello")
+@abstract.bar<int>.abstract("hello")
+class Y {}
+
+@[SimpleToken]abstract[KeywordToken]
+@[SimpleToken]foo[StringToken].[SimpleToken]abstract[KeywordToken]
+@[SimpleToken]foo[StringToken].[SimpleToken]bar[StringToken].[SimpleToken]abstract[KeywordToken]
+@[SimpleToken]foo[StringToken]([BeginToken]"hello"[StringToken])[SimpleToken]
+@[SimpleToken]foo[StringToken].[SimpleToken]abstract[KeywordToken]([BeginToken]"hello"[StringToken])[SimpleToken]
+@[SimpleToken]foo[StringToken].[SimpleToken]bar[StringToken].[SimpleToken]abstract[KeywordToken]([BeginToken]"hello"[StringToken])[SimpleToken]
+@[SimpleToken]foo[StringToken]<[BeginToken]int[StringToken]>[SimpleToken]([BeginToken]"hello"[StringToken])[SimpleToken]
+@[SimpleToken]foo[StringToken]<[BeginToken]int[StringToken]>[SimpleToken].[SimpleToken]abstract[KeywordToken]([BeginToken]"hello"[StringToken])[SimpleToken]
+@[SimpleToken]foo[StringToken].[SimpleToken]bar[StringToken]<[BeginToken]int[StringToken]>[SimpleToken]([BeginToken]"hello"[StringToken])[SimpleToken]
+@[SimpleToken]foo[StringToken].[SimpleToken]bar[StringToken]<[BeginToken]int[StringToken]>[SimpleToken].[SimpleToken]abstract[KeywordToken]([BeginToken]"hello"[StringToken])[SimpleToken]
+class[KeywordToken] X[StringToken] {[BeginToken]}[SimpleToken]
+
+
+typedef[KeywordToken] F[StringToken]<[BeginToken]@[SimpleToken]abstract[KeywordToken] T[StringToken]>[SimpleToken] =[SimpleToken] int[StringToken] Function[KeywordToken]<[BeginToken]@[SimpleToken]abstract[KeywordToken] X[StringToken]>[SimpleToken]([BeginToken]@[SimpleToken]abstract[KeywordToken] int[StringToken])[SimpleToken];[SimpleToken]
+typedef[KeywordToken] F[StringToken]<[BeginToken]@[SimpleToken]foo[StringToken].[SimpleToken]abstract[KeywordToken] T[StringToken]>[SimpleToken] =[SimpleToken] int[StringToken] Function[KeywordToken]<[BeginToken]@[SimpleToken]foo[StringToken].[SimpleToken]abstract[KeywordToken] X[StringToken]>[SimpleToken]([BeginToken]@[SimpleToken]foo[StringToken].[SimpleToken]abstract[KeywordToken] int[StringToken])[SimpleToken];[SimpleToken]
+typedef[KeywordToken] F[StringToken]<[BeginToken]@[SimpleToken]foo[StringToken].[SimpleToken]bar[StringToken].[SimpleToken]abstract[KeywordToken] T[StringToken]>[SimpleToken] =[SimpleToken] int[StringToken] Function[KeywordToken]<[BeginToken]@[SimpleToken]foo[StringToken].[SimpleToken]bar[StringToken].[SimpleToken]abstract[KeywordToken] X[StringToken]>[SimpleToken]([BeginToken]@[SimpleToken]foo[StringToken].[SimpleToken]bar[StringToken].[SimpleToken]abstract[KeywordToken] int[StringToken])[SimpleToken];[SimpleToken]
+typedef[KeywordToken] F[StringToken]<[BeginToken]@[SimpleToken]foo[StringToken]([BeginToken]"hello"[StringToken])[SimpleToken] T[StringToken]>[SimpleToken] =[SimpleToken] int[StringToken] Function[KeywordToken]<[BeginToken]@[SimpleToken]foo[StringToken]([BeginToken]"hello"[StringToken])[SimpleToken] X[StringToken]>[SimpleToken]([BeginToken]@[SimpleToken]foo[StringToken]([BeginToken]"hello"[StringToken])[SimpleToken] int[StringToken])[SimpleToken];[SimpleToken]
+typedef[KeywordToken] F[StringToken]<[BeginToken]@[SimpleToken]foo[StringToken].[SimpleToken]abstract[KeywordToken]([BeginToken]"hello"[StringToken])[SimpleToken] T[StringToken]>[SimpleToken] =[SimpleToken] int[StringToken] Function[KeywordToken]<[BeginToken]@[SimpleToken]foo[StringToken].[SimpleToken]abstract[KeywordToken]([BeginToken]"hello"[StringToken])[SimpleToken] X[StringToken]>[SimpleToken]([BeginToken]@[SimpleToken]foo[StringToken].[SimpleToken]abstract[KeywordToken]([BeginToken]"hello"[StringToken])[SimpleToken] int[StringToken])[SimpleToken];[SimpleToken]
+typedef[KeywordToken] F[StringToken]<[BeginToken]@[SimpleToken]foo[StringToken].[SimpleToken]bar[StringToken].[SimpleToken]abstract[KeywordToken]([BeginToken]"hello"[StringToken])[SimpleToken] T[StringToken]>[SimpleToken] =[SimpleToken] int[StringToken] Function[KeywordToken]<[BeginToken]@[SimpleToken]foo[StringToken].[SimpleToken]bar[StringToken].[SimpleToken]abstract[KeywordToken]([BeginToken]"hello"[StringToken])[SimpleToken] X[StringToken]>[SimpleToken]([BeginToken]@[SimpleToken]foo[StringToken].[SimpleToken]bar[StringToken].[SimpleToken]abstract[KeywordToken]([BeginToken]"hello"[StringToken])[SimpleToken] int[StringToken])[SimpleToken];[SimpleToken]
+typedef[KeywordToken] F[StringToken]<[BeginToken]@[SimpleToken]foo[StringToken]<[BeginToken]int[StringToken]>[SimpleToken]([BeginToken]"hello"[StringToken])[SimpleToken] T[StringToken]>[SimpleToken] =[SimpleToken] int[StringToken] Function[KeywordToken]<[BeginToken]@[SimpleToken]foo[StringToken]<[BeginToken]int[StringToken]>[SimpleToken]([BeginToken]"hello"[StringToken])[SimpleToken] X[StringToken]>[SimpleToken]([BeginToken]@[SimpleToken]foo[StringToken]<[BeginToken]int[StringToken]>[SimpleToken]([BeginToken]"hello"[StringToken])[SimpleToken] int[StringToken])[SimpleToken];[SimpleToken]
+typedef[KeywordToken] F[StringToken]<[BeginToken]@[SimpleToken]foo[StringToken]<[BeginToken]int[StringToken]>[SimpleToken].[SimpleToken]abstract[KeywordToken]([BeginToken]"hello"[StringToken])[SimpleToken] T[StringToken]>[SimpleToken] =[SimpleToken] int[StringToken] Function[KeywordToken]<[BeginToken]@[SimpleToken]foo[StringToken]<[BeginToken]int[StringToken]>[SimpleToken].[SimpleToken]abstract[KeywordToken]([BeginToken]"hello"[StringToken])[SimpleToken] X[StringToken]>[SimpleToken]([BeginToken]@[SimpleToken]foo[StringToken]<[BeginToken]int[StringToken]>[SimpleToken].[SimpleToken]abstract[KeywordToken]([BeginToken]"hello"[StringToken])[SimpleToken] int[StringToken])[SimpleToken];[SimpleToken]
+typedef[KeywordToken] F[StringToken]<[BeginToken]@[SimpleToken]foo[StringToken].[SimpleToken]bar[StringToken]<[BeginToken]int[StringToken]>[SimpleToken]([BeginToken]"hello"[StringToken])[SimpleToken] T[StringToken]>[SimpleToken] =[SimpleToken] int[StringToken] Function[KeywordToken]<[BeginToken]@[SimpleToken]foo[StringToken].[SimpleToken]bar[StringToken]<[BeginToken]int[StringToken]>[SimpleToken]([BeginToken]"hello"[StringToken])[SimpleToken] X[StringToken]>[SimpleToken]([BeginToken]@[SimpleToken]foo[StringToken].[SimpleToken]bar[StringToken]<[BeginToken]int[StringToken]>[SimpleToken]([BeginToken]"hello"[StringToken])[SimpleToken] int[StringToken])[SimpleToken];[SimpleToken]
+typedef[KeywordToken] F[StringToken]<[BeginToken]@[SimpleToken]foo[StringToken].[SimpleToken]bar[StringToken]<[BeginToken]int[StringToken]>[SimpleToken].[SimpleToken]abstract[KeywordToken]([BeginToken]"hello"[StringToken])[SimpleToken] T[StringToken]>[SimpleToken] =[SimpleToken] int[StringToken] Function[KeywordToken]<[BeginToken]@[SimpleToken]foo[StringToken].[SimpleToken]bar[StringToken]<[BeginToken]int[StringToken]>[SimpleToken].[SimpleToken]abstract[KeywordToken]([BeginToken]"hello"[StringToken])[SimpleToken] X[StringToken]>[SimpleToken]([BeginToken]@[SimpleToken]foo[StringToken].[SimpleToken]bar[StringToken]<[BeginToken]int[StringToken]>[SimpleToken].[SimpleToken]abstract[KeywordToken]([BeginToken]"hello"[StringToken])[SimpleToken] int[StringToken])[SimpleToken];[SimpleToken]
+
+
+
+
+
+
+@[SimpleToken]abstract[KeywordToken].[SimpleToken]abstract[KeywordToken]
+@[SimpleToken]abstract[KeywordToken].[SimpleToken]bar[StringToken].[SimpleToken]abstract[KeywordToken]
+@[SimpleToken]abstract[KeywordToken]([BeginToken]"hello"[StringToken])[SimpleToken]
+@[SimpleToken]abstract[KeywordToken].[SimpleToken]abstract[KeywordToken]([BeginToken]"hello"[StringToken])[SimpleToken]
+@[SimpleToken]abstract[KeywordToken].[SimpleToken]bar[StringToken].[SimpleToken]abstract[KeywordToken]([BeginToken]"hello"[StringToken])[SimpleToken]
+@[SimpleToken]abstract[KeywordToken]<[BeginToken]int[StringToken]>[SimpleToken]([BeginToken]"hello"[StringToken])[SimpleToken]
+@[SimpleToken]abstract[KeywordToken]<[BeginToken]int[StringToken]>[SimpleToken].[SimpleToken]abstract[KeywordToken]([BeginToken]"hello"[StringToken])[SimpleToken]
+@[SimpleToken]abstract[KeywordToken].[SimpleToken]bar[StringToken]<[BeginToken]int[StringToken]>[SimpleToken]([BeginToken]"hello"[StringToken])[SimpleToken]
+@[SimpleToken]abstract[KeywordToken].[SimpleToken]bar[StringToken]<[BeginToken]int[StringToken]>[SimpleToken].[SimpleToken]abstract[KeywordToken]([BeginToken]"hello"[StringToken])[SimpleToken]
+class[KeywordToken] Y[StringToken] {[BeginToken]}[SimpleToken][SimpleToken]
diff --git a/pkg/front_end/parser_testcases/general/metadata.dart.scanner.expect b/pkg/front_end/parser_testcases/general/metadata.dart.scanner.expect
new file mode 100644
index 0000000..fb0a8af
--- /dev/null
+++ b/pkg/front_end/parser_testcases/general/metadata.dart.scanner.expect
@@ -0,0 +1,79 @@
+@abstract
+@foo.abstract
+@foo.bar.abstract
+@foo("hello")
+@foo.abstract("hello")
+@foo.bar.abstract("hello")
+@foo<int>("hello")
+@foo<int>.abstract("hello")
+@foo.bar<int>("hello")
+@foo.bar<int>.abstract("hello")
+class X {}
+
+
+typedef F<@abstract T> = int Function<@abstract X>(@abstract int);
+typedef F<@foo.abstract T> = int Function<@foo.abstract X>(@foo.abstract int);
+typedef F<@foo.bar.abstract T> = int Function<@foo.bar.abstract X>(@foo.bar.abstract int);
+typedef F<@foo("hello") T> = int Function<@foo("hello") X>(@foo("hello") int);
+typedef F<@foo.abstract("hello") T> = int Function<@foo.abstract("hello") X>(@foo.abstract("hello") int);
+typedef F<@foo.bar.abstract("hello") T> = int Function<@foo.bar.abstract("hello") X>(@foo.bar.abstract("hello") int);
+typedef F<@foo<int>("hello") T> = int Function<@foo<int>("hello") X>(@foo<int>("hello") int);
+typedef F<@foo<int>.abstract("hello") T> = int Function<@foo<int>.abstract("hello") X>(@foo<int>.abstract("hello") int);
+typedef F<@foo.bar<int>("hello") T> = int Function<@foo.bar<int>("hello") X>(@foo.bar<int>("hello") int);
+typedef F<@foo.bar<int>.abstract("hello") T> = int Function<@foo.bar<int>.abstract("hello") X>(@foo.bar<int>.abstract("hello") int);
+
+
+
+
+
+
+@abstract.abstract
+@abstract.bar.abstract
+@abstract("hello")
+@abstract.abstract("hello")
+@abstract.bar.abstract("hello")
+@abstract<int>("hello")
+@abstract<int>.abstract("hello")
+@abstract.bar<int>("hello")
+@abstract.bar<int>.abstract("hello")
+class Y {}
+
+@[SimpleToken]abstract[KeywordToken]
+@[SimpleToken]foo[StringToken].[SimpleToken]abstract[KeywordToken]
+@[SimpleToken]foo[StringToken].[SimpleToken]bar[StringToken].[SimpleToken]abstract[KeywordToken]
+@[SimpleToken]foo[StringToken]([BeginToken]"hello"[StringToken])[SimpleToken]
+@[SimpleToken]foo[StringToken].[SimpleToken]abstract[KeywordToken]([BeginToken]"hello"[StringToken])[SimpleToken]
+@[SimpleToken]foo[StringToken].[SimpleToken]bar[StringToken].[SimpleToken]abstract[KeywordToken]([BeginToken]"hello"[StringToken])[SimpleToken]
+@[SimpleToken]foo[StringToken]<[BeginToken]int[StringToken]>[SimpleToken]([BeginToken]"hello"[StringToken])[SimpleToken]
+@[SimpleToken]foo[StringToken]<[BeginToken]int[StringToken]>[SimpleToken].[SimpleToken]abstract[KeywordToken]([BeginToken]"hello"[StringToken])[SimpleToken]
+@[SimpleToken]foo[StringToken].[SimpleToken]bar[StringToken]<[BeginToken]int[StringToken]>[SimpleToken]([BeginToken]"hello"[StringToken])[SimpleToken]
+@[SimpleToken]foo[StringToken].[SimpleToken]bar[StringToken]<[BeginToken]int[StringToken]>[SimpleToken].[SimpleToken]abstract[KeywordToken]([BeginToken]"hello"[StringToken])[SimpleToken]
+class[KeywordToken] X[StringToken] {[BeginToken]}[SimpleToken]
+
+
+typedef[KeywordToken] F[StringToken]<[BeginToken]@[SimpleToken]abstract[KeywordToken] T[StringToken]>[SimpleToken] =[SimpleToken] int[StringToken] Function[KeywordToken]<[BeginToken]@[SimpleToken]abstract[KeywordToken] X[StringToken]>[SimpleToken]([BeginToken]@[SimpleToken]abstract[KeywordToken] int[StringToken])[SimpleToken];[SimpleToken]
+typedef[KeywordToken] F[StringToken]<[BeginToken]@[SimpleToken]foo[StringToken].[SimpleToken]abstract[KeywordToken] T[StringToken]>[SimpleToken] =[SimpleToken] int[StringToken] Function[KeywordToken]<[BeginToken]@[SimpleToken]foo[StringToken].[SimpleToken]abstract[KeywordToken] X[StringToken]>[SimpleToken]([BeginToken]@[SimpleToken]foo[StringToken].[SimpleToken]abstract[KeywordToken] int[StringToken])[SimpleToken];[SimpleToken]
+typedef[KeywordToken] F[StringToken]<[BeginToken]@[SimpleToken]foo[StringToken].[SimpleToken]bar[StringToken].[SimpleToken]abstract[KeywordToken] T[StringToken]>[SimpleToken] =[SimpleToken] int[StringToken] Function[KeywordToken]<[BeginToken]@[SimpleToken]foo[StringToken].[SimpleToken]bar[StringToken].[SimpleToken]abstract[KeywordToken] X[StringToken]>[SimpleToken]([BeginToken]@[SimpleToken]foo[StringToken].[SimpleToken]bar[StringToken].[SimpleToken]abstract[KeywordToken] int[StringToken])[SimpleToken];[SimpleToken]
+typedef[KeywordToken] F[StringToken]<[BeginToken]@[SimpleToken]foo[StringToken]([BeginToken]"hello"[StringToken])[SimpleToken] T[StringToken]>[SimpleToken] =[SimpleToken] int[StringToken] Function[KeywordToken]<[BeginToken]@[SimpleToken]foo[StringToken]([BeginToken]"hello"[StringToken])[SimpleToken] X[StringToken]>[SimpleToken]([BeginToken]@[SimpleToken]foo[StringToken]([BeginToken]"hello"[StringToken])[SimpleToken] int[StringToken])[SimpleToken];[SimpleToken]
+typedef[KeywordToken] F[StringToken]<[BeginToken]@[SimpleToken]foo[StringToken].[SimpleToken]abstract[KeywordToken]([BeginToken]"hello"[StringToken])[SimpleToken] T[StringToken]>[SimpleToken] =[SimpleToken] int[StringToken] Function[KeywordToken]<[BeginToken]@[SimpleToken]foo[StringToken].[SimpleToken]abstract[KeywordToken]([BeginToken]"hello"[StringToken])[SimpleToken] X[StringToken]>[SimpleToken]([BeginToken]@[SimpleToken]foo[StringToken].[SimpleToken]abstract[KeywordToken]([BeginToken]"hello"[StringToken])[SimpleToken] int[StringToken])[SimpleToken];[SimpleToken]
+typedef[KeywordToken] F[StringToken]<[BeginToken]@[SimpleToken]foo[StringToken].[SimpleToken]bar[StringToken].[SimpleToken]abstract[KeywordToken]([BeginToken]"hello"[StringToken])[SimpleToken] T[StringToken]>[SimpleToken] =[SimpleToken] int[StringToken] Function[KeywordToken]<[BeginToken]@[SimpleToken]foo[StringToken].[SimpleToken]bar[StringToken].[SimpleToken]abstract[KeywordToken]([BeginToken]"hello"[StringToken])[SimpleToken] X[StringToken]>[SimpleToken]([BeginToken]@[SimpleToken]foo[StringToken].[SimpleToken]bar[StringToken].[SimpleToken]abstract[KeywordToken]([BeginToken]"hello"[StringToken])[SimpleToken] int[StringToken])[SimpleToken];[SimpleToken]
+typedef[KeywordToken] F[StringToken]<[BeginToken]@[SimpleToken]foo[StringToken]<[BeginToken]int[StringToken]>[SimpleToken]([BeginToken]"hello"[StringToken])[SimpleToken] T[StringToken]>[SimpleToken] =[SimpleToken] int[StringToken] Function[KeywordToken]<[BeginToken]@[SimpleToken]foo[StringToken]<[BeginToken]int[StringToken]>[SimpleToken]([BeginToken]"hello"[StringToken])[SimpleToken] X[StringToken]>[SimpleToken]([BeginToken]@[SimpleToken]foo[StringToken]<[BeginToken]int[StringToken]>[SimpleToken]([BeginToken]"hello"[StringToken])[SimpleToken] int[StringToken])[SimpleToken];[SimpleToken]
+typedef[KeywordToken] F[StringToken]<[BeginToken]@[SimpleToken]foo[StringToken]<[BeginToken]int[StringToken]>[SimpleToken].[SimpleToken]abstract[KeywordToken]([BeginToken]"hello"[StringToken])[SimpleToken] T[StringToken]>[SimpleToken] =[SimpleToken] int[StringToken] Function[KeywordToken]<[BeginToken]@[SimpleToken]foo[StringToken]<[BeginToken]int[StringToken]>[SimpleToken].[SimpleToken]abstract[KeywordToken]([BeginToken]"hello"[StringToken])[SimpleToken] X[StringToken]>[SimpleToken]([BeginToken]@[SimpleToken]foo[StringToken]<[BeginToken]int[StringToken]>[SimpleToken].[SimpleToken]abstract[KeywordToken]([BeginToken]"hello"[StringToken])[SimpleToken] int[StringToken])[SimpleToken];[SimpleToken]
+typedef[KeywordToken] F[StringToken]<[BeginToken]@[SimpleToken]foo[StringToken].[SimpleToken]bar[StringToken]<[BeginToken]int[StringToken]>[SimpleToken]([BeginToken]"hello"[StringToken])[SimpleToken] T[StringToken]>[SimpleToken] =[SimpleToken] int[StringToken] Function[KeywordToken]<[BeginToken]@[SimpleToken]foo[StringToken].[SimpleToken]bar[StringToken]<[BeginToken]int[StringToken]>[SimpleToken]([BeginToken]"hello"[StringToken])[SimpleToken] X[StringToken]>[SimpleToken]([BeginToken]@[SimpleToken]foo[StringToken].[SimpleToken]bar[StringToken]<[BeginToken]int[StringToken]>[SimpleToken]([BeginToken]"hello"[StringToken])[SimpleToken] int[StringToken])[SimpleToken];[SimpleToken]
+typedef[KeywordToken] F[StringToken]<[BeginToken]@[SimpleToken]foo[StringToken].[SimpleToken]bar[StringToken]<[BeginToken]int[StringToken]>[SimpleToken].[SimpleToken]abstract[KeywordToken]([BeginToken]"hello"[StringToken])[SimpleToken] T[StringToken]>[SimpleToken] =[SimpleToken] int[StringToken] Function[KeywordToken]<[BeginToken]@[SimpleToken]foo[StringToken].[SimpleToken]bar[StringToken]<[BeginToken]int[StringToken]>[SimpleToken].[SimpleToken]abstract[KeywordToken]([BeginToken]"hello"[StringToken])[SimpleToken] X[StringToken]>[SimpleToken]([BeginToken]@[SimpleToken]foo[StringToken].[SimpleToken]bar[StringToken]<[BeginToken]int[StringToken]>[SimpleToken].[SimpleToken]abstract[KeywordToken]([BeginToken]"hello"[StringToken])[SimpleToken] int[StringToken])[SimpleToken];[SimpleToken]
+
+
+
+
+
+
+@[SimpleToken]abstract[KeywordToken].[SimpleToken]abstract[KeywordToken]
+@[SimpleToken]abstract[KeywordToken].[SimpleToken]bar[StringToken].[SimpleToken]abstract[KeywordToken]
+@[SimpleToken]abstract[KeywordToken]([BeginToken]"hello"[StringToken])[SimpleToken]
+@[SimpleToken]abstract[KeywordToken].[SimpleToken]abstract[KeywordToken]([BeginToken]"hello"[StringToken])[SimpleToken]
+@[SimpleToken]abstract[KeywordToken].[SimpleToken]bar[StringToken].[SimpleToken]abstract[KeywordToken]([BeginToken]"hello"[StringToken])[SimpleToken]
+@[SimpleToken]abstract[KeywordToken]<[BeginToken]int[StringToken]>[SimpleToken]([BeginToken]"hello"[StringToken])[SimpleToken]
+@[SimpleToken]abstract[KeywordToken]<[BeginToken]int[StringToken]>[SimpleToken].[SimpleToken]abstract[KeywordToken]([BeginToken]"hello"[StringToken])[SimpleToken]
+@[SimpleToken]abstract[KeywordToken].[SimpleToken]bar[StringToken]<[BeginToken]int[StringToken]>[SimpleToken]([BeginToken]"hello"[StringToken])[SimpleToken]
+@[SimpleToken]abstract[KeywordToken].[SimpleToken]bar[StringToken]<[BeginToken]int[StringToken]>[SimpleToken].[SimpleToken]abstract[KeywordToken]([BeginToken]"hello"[StringToken])[SimpleToken]
+class[KeywordToken] Y[StringToken] {[BeginToken]}[SimpleToken][SimpleToken]
diff --git a/pkg/front_end/test/enable_non_nullable/enable_non_nullable_test.dart b/pkg/front_end/test/enable_non_nullable/enable_non_nullable_test.dart
index 85cce5b..d95cf75 100644
--- a/pkg/front_end/test/enable_non_nullable/enable_non_nullable_test.dart
+++ b/pkg/front_end/test/enable_non_nullable/enable_non_nullable_test.dart
@@ -107,6 +107,7 @@
 
   bool hadDiagnostic = false;
   options.onDiagnostic = (DiagnosticMessage message) {
+    print(message.plainTextFormatted);
     hadDiagnostic = true;
   };
 
diff --git a/pkg/front_end/test/explicit_creation_git_test.dart b/pkg/front_end/test/explicit_creation_git_test.dart
index a0378d2..9229e49 100644
--- a/pkg/front_end/test/explicit_creation_git_test.dart
+++ b/pkg/front_end/test/explicit_creation_git_test.dart
@@ -237,7 +237,8 @@
       List<UnresolvedType> typeArguments,
       int charOffset,
       Constness constness,
-      {bool isTypeArgumentsInForest = false}) {
+      {bool isTypeArgumentsInForest = false,
+      TypeDeclarationBuilder typeAliasBuilder}) {
     Token maybeNewOrConst = nameToken.previous;
     bool doReport = true;
     if (maybeNewOrConst is KeywordToken) {
diff --git a/pkg/front_end/test/fasta/analyze_git_test.dart b/pkg/front_end/test/fasta/analyze_git_test.dart
index 044385e..684f469 100644
--- a/pkg/front_end/test/fasta/analyze_git_test.dart
+++ b/pkg/front_end/test/fasta/analyze_git_test.dart
@@ -4,13 +4,18 @@
 
 // @dart = 2.9
 
+import 'dart:io' show exitCode;
+
 import "package:testing/src/run_tests.dart" as testing show main;
 
-main() {
+main() async {
   // This method is async, but keeps a port open to prevent the VM from exiting
   // prematurely.
   // Note: if you change this file, also change
   // pkg/compiler/test/analyses/analyze_test.dart
-  return testing.main(
+  await testing.main(
       <String>["--config=pkg/front_end/testing.json", "--verbose", "analyze"]);
+  if (exitCode != 0) {
+    throw "Exit-code was $exitCode!";
+  }
 }
diff --git a/pkg/front_end/test/fasta/analyze_src_with_lints_git_test.dart b/pkg/front_end/test/fasta/analyze_src_with_lints_git_test.dart
index 652d6b7..aba5e28 100644
--- a/pkg/front_end/test/fasta/analyze_src_with_lints_git_test.dart
+++ b/pkg/front_end/test/fasta/analyze_src_with_lints_git_test.dart
@@ -4,12 +4,17 @@
 
 // @dart = 2.9
 
+import 'dart:io' show exitCode;
+
 import "package:testing/src/run_tests.dart" as testing show main;
 
 main() async {
-  return await testing.main(<String>[
+  await testing.main(<String>[
     "--config=pkg/front_end/testing_with_lints.json",
     "--verbose",
     "analyze"
   ]);
+  if (exitCode != 0) {
+    throw "Exit-code was $exitCode!";
+  }
 }
diff --git a/pkg/front_end/test/fasta/generator_to_string_test.dart b/pkg/front_end/test/fasta/generator_to_string_test.dart
index 88b6146..c1d32eb 100644
--- a/pkg/front_end/test/fasta/generator_to_string_test.dart
+++ b/pkg/front_end/test/fasta/generator_to_string_test.dart
@@ -27,7 +27,8 @@
         TypeParameter,
         VariableDeclaration,
         VariableGet,
-        VoidType;
+        VoidType,
+        defaultLanguageVersion;
 
 import 'package:kernel/target/targets.dart' show NoneTarget, TargetFlags;
 
@@ -53,7 +54,7 @@
 import 'package:front_end/src/fasta/kernel/body_builder.dart' show BodyBuilder;
 
 import 'package:front_end/src/fasta/source/source_library_builder.dart'
-    show SourceLibraryBuilder;
+    show ImplicitLanguageVersion, SourceLibraryBuilder;
 
 void check(String expected, Generator generator) {
   Expect.stringEquals(expected, "$generator");
@@ -74,6 +75,7 @@
         uri,
         uri,
         /*packageUri*/ null,
+        new ImplicitLanguageVersion(defaultLanguageVersion),
         new KernelTarget(
                 null,
                 false,
diff --git a/pkg/front_end/test/fasta/testing/suite.dart b/pkg/front_end/test/fasta/testing/suite.dart
index 3b69a38..0da4649 100644
--- a/pkg/front_end/test/fasta/testing/suite.dart
+++ b/pkg/front_end/test/fasta/testing/suite.dart
@@ -159,6 +159,10 @@
         StdioProcess;
 
 import 'package:vm/target/vm.dart' show VmTarget;
+import 'package:vm/transformations/type_flow/transformer.dart' as type_flow;
+import 'package:vm/transformations/pragma.dart' as type_flow;
+
+import '../../testing_utils.dart' show checkEnvironment;
 
 import '../../utils/kernel_chain.dart'
     show
@@ -233,6 +237,11 @@
 const String overwriteCurrentSdkVersion = '--overwrite-current-sdk-version=';
 const String noVerifyCmd = '--no-verify';
 
+final ExpectationSet staticExpectationSet =
+    new ExpectationSet.fromJsonList(jsonDecode(EXPECTATIONS));
+final Expectation semiFuzzFailure = staticExpectationSet["SemiFuzzFailure"];
+final Expectation semiFuzzCrash = staticExpectationSet["SemiFuzzCrash"];
+
 /// Options used for all tests within a given folder.
 ///
 /// This is used for instance for defining target, mode, and experiment specific
@@ -312,10 +321,6 @@
   final bool semiFuzz;
   final bool verify;
   final bool soundNullSafety;
-  final Map<Component, KernelTarget> componentToTarget =
-      <Component, KernelTarget>{};
-  final Map<Component, List<Iterable<String>>> componentToDiagnostics =
-      <Component, List<Iterable<String>>>{};
   final Uri platformBinaries;
   final Map<UriConfiguration, UriTranslator> _uriTranslators = {};
   final Map<Uri, FolderOptions> _folderOptions = {};
@@ -332,8 +337,7 @@
   bool get canBeFixWithUpdateExpectations => true;
 
   @override
-  final ExpectationSet expectationSet =
-      new ExpectationSet.fromJsonList(jsonDecode(EXPECTATIONS));
+  final ExpectationSet expectationSet = staticExpectationSet;
 
   Map<Uri, Component> _platforms = {};
 
@@ -378,13 +382,11 @@
       steps.add(new MatchExpectation(
           fullCompile ? "$fullPrefix.expect" : "$outlinePrefix.expect",
           serializeFirst: false,
-          isLastMatchStep: updateExpectations));
-      if (!updateExpectations) {
-        steps.add(new MatchExpectation(
-            fullCompile ? "$fullPrefix.expect" : "$outlinePrefix.expect",
-            serializeFirst: true,
-            isLastMatchStep: true));
-      }
+          isLastMatchStep: false));
+      steps.add(new MatchExpectation(
+          fullCompile ? "$fullPrefix.expect" : "$outlinePrefix.expect",
+          serializeFirst: true,
+          isLastMatchStep: true));
     }
     steps.add(const TypeCheck());
     steps.add(const EnsureNoErrors());
@@ -393,6 +395,7 @@
     }
     if (fullCompile) {
       steps.add(const Transform());
+      steps.add(const Verify(true));
       steps.add(const StressConstantEvaluatorStep());
       if (!ignoreExpectations) {
         steps.add(new MatchExpectation("$fullPrefix.transformed.expect",
@@ -405,11 +408,17 @@
       steps.add(const EnsureNoErrors());
       if (!skipVm) {
         steps.add(const WriteDill());
-        steps.add(const Run());
       }
       if (semiFuzz) {
         steps.add(const FuzzCompiles());
       }
+
+      // Notice: The below steps will run async, i.e. the next test will run
+      // intertwined with this/these step(s). That for instance means that they
+      // should not touch any ASTs!
+      if (!skipVm) {
+        steps.add(const Run());
+      }
     }
   }
 
@@ -678,18 +687,27 @@
 
   Expectation get verificationError => expectationSet["VerificationError"];
 
-  Future<Component> loadPlatform(Target target, NnbdMode nnbdMode) async {
+  Uri _getPlatformUri(Target target, NnbdMode nnbdMode) {
     String fileName = computePlatformDillName(
         target,
         nnbdMode,
         () => throw new UnsupportedError(
             "No platform dill for target '${target.name}' with $nnbdMode."));
-    Uri uri = platformBinaries.resolve(fileName);
+    return platformBinaries.resolve(fileName);
+  }
+
+  Future<Component> loadPlatform(Target target, NnbdMode nnbdMode) async {
+    Uri uri = _getPlatformUri(target, nnbdMode);
     return _platforms.putIfAbsent(uri, () {
       return loadComponentFromBytes(new File.fromUri(uri).readAsBytesSync());
     });
   }
 
+  void clearPlatformCache(Target target, NnbdMode nnbdMode) async {
+    Uri uri = _getPlatformUri(target, nnbdMode);
+    _platforms.remove(uri);
+  }
+
   @override
   Result processTestResult(
       TestDescription description, Result result, bool last) {
@@ -706,16 +724,59 @@
   @override
   Set<Expectation> processExpectedOutcomes(
       Set<Expectation> outcomes, TestDescription description) {
-    if (skipVm && outcomes.length == 1 && outcomes.single == runtimeError) {
-      return new Set<Expectation>.from([Expectation.Pass]);
-    } else {
-      return outcomes;
+    // Remove outcomes related to phases not currently in effect.
+
+    Set<Expectation> result;
+
+    // If skipping VM we can't get a runtime error.
+    if (skipVm && outcomes.contains(runtimeError)) {
+      result ??= new Set.from(outcomes);
+      result.remove(runtimeError);
     }
+
+    // If not semi-fuzzing we can't get semi-fuzz errors.
+    if (!semiFuzz &&
+        (outcomes.contains(semiFuzzFailure) ||
+            outcomes.contains(semiFuzzCrash))) {
+      result ??= new Set.from(outcomes);
+      result.remove(semiFuzzFailure);
+      result.remove(semiFuzzCrash);
+    }
+
+    // Fast-path: no changes made.
+    if (result == null) return outcomes;
+
+    // Changes made: No expectations left. This happens when all expected
+    // outcomes are removed above.
+    // We have to put in the implicit assumption that it will pass then.
+    if (result.isEmpty) return {Expectation.Pass};
+
+    // Changes made with at least one expectation left. That's out result!
+    return result;
   }
 
   static Future<FastaContext> create(
       Chain suite, Map<String, String> environment) async {
-    Uri vm = Uri.base.resolveUri(new Uri.file(Platform.resolvedExecutable));
+    const Set<String> knownEnvironmentKeys = {
+      "enableExtensionMethods",
+      "enableNonNullable",
+      "soundNullSafety",
+      "onlyCrashes",
+      "ignoreExpectations",
+      UPDATE_EXPECTATIONS,
+      UPDATE_COMMENTS,
+      "skipVm",
+      "semiFuzz",
+      "verify",
+      KERNEL_TEXT_SERIALIZATION,
+      "platformBinaries",
+      ENABLE_FULL_COMPILE,
+    };
+    checkEnvironment(environment, knownEnvironmentKeys);
+
+    String resolvedExecutable = Platform.environment['resolvedExecutable'] ??
+        Platform.resolvedExecutable;
+    Uri vm = Uri.base.resolveUri(new Uri.file(resolvedExecutable));
     Map<ExperimentalFlag, bool> experimentalFlags = <ExperimentalFlag, bool>{};
 
     void addForcedExperimentalFlag(String name, ExperimentalFlag flag) {
@@ -768,10 +829,9 @@
 
   String get name => "run";
 
+  /// WARNING: Every subsequent step in this test will run async as well!
   bool get isAsync => true;
 
-  bool get isRuntime => true;
-
   Future<Result<ComponentResult>> run(
       ComponentResult result, FastaContext context) async {
     FolderOptions folderOptions =
@@ -812,11 +872,11 @@
         }
         return new Result<ComponentResult>(
             result, runResult.outcome, runResult.error);
+      case "aot":
       case "none":
-      case "noneWithJs":
       case "dart2js":
       case "dartdevc":
-        // TODO(johnniwinther): Support running dart2js and/or dartdevc.
+        // TODO(johnniwinther): Support running vm aot, dart2js and/or dartdevc.
         return pass(result);
       default:
         throw new ArgumentError(
@@ -1160,7 +1220,7 @@
         userLibraries.length != result.userLibraries.length) {
       return new Result<ComponentResult>(
           result,
-          context.expectationSet["SemiFuzzFailure"],
+          semiFuzzFailure,
           "Got a different amount of user libraries on first compile "
           "compared to 'original' compilation:\n\n"
           "This compile:\n"
@@ -1185,7 +1245,7 @@
               originalErrors.map((error) => error.join('\n')).join('\n\n');
           return new Result<ComponentResult>(
               result,
-              context.expectationSet["SemiFuzzFailure"],
+              semiFuzzFailure,
               "Expected these errors:\n${errorsString}\n\n"
               "but didn't get any after invalidating $importUri");
         } else {
@@ -1194,7 +1254,7 @@
               .join('\n\n');
           return new Result<ComponentResult>(
               result,
-              context.expectationSet["SemiFuzzFailure"],
+              semiFuzzFailure,
               "Unexpected errors:\n${errorsString}\n\n"
               "after invalidating $importUri");
         }
@@ -1206,7 +1266,7 @@
           newUserLibraries.length != userLibraries.length) {
         return new Result<ComponentResult>(
             result,
-            context.expectationSet["SemiFuzzFailure"],
+            semiFuzzFailure,
             "Got a different amount of user libraries on recompile "
             "compared to 'original' compilation after having invalidated "
             "$importUri.\n\n"
@@ -1275,8 +1335,18 @@
         continue;
       }
       Uint8List orgData = fs.data[uri];
-      FuzzAstVisitorSorter fuzzAstVisitorSorter =
-          new FuzzAstVisitorSorter(orgData, builder.isNonNullableByDefault);
+      FuzzAstVisitorSorter fuzzAstVisitorSorter;
+      try {
+        fuzzAstVisitorSorter =
+            new FuzzAstVisitorSorter(orgData, builder.isNonNullableByDefault);
+      } on FormatException catch (e, st) {
+        // UTF-16-LE formatted test crashes `utf8.decode(bytes)` --- catch that
+        return new Result<ComponentResult>(
+            result,
+            semiFuzzCrash,
+            "$e\n\n"
+            "$st");
+      }
 
       // Sort ascending and then compile. Then sort descending and try again.
       for (void Function() sorter in [
@@ -1297,7 +1367,7 @@
         } catch (e, st) {
           return new Result<ComponentResult>(
               result,
-              context.expectationSet["SemiFuzzCrash"],
+              semiFuzzCrash,
               "Crashed with '$e' after reordering '$uri' to\n\n"
               "$sb\n\n"
               "$st");
@@ -1317,7 +1387,7 @@
                 originalErrors.map((error) => error.join('\n')).join('\n\n');
             return new Result<ComponentResult>(
                 result,
-                context.expectationSet["SemiFuzzFailure"],
+                semiFuzzFailure,
                 "Expected these errors:\n${errorsString}\n\n"
                 "but didn't get any after reordering $uri "
                 "to have this content:\n\n"
@@ -1325,7 +1395,7 @@
           } else {
             return new Result<ComponentResult>(
                 result,
-                context.expectationSet["SemiFuzzFailure"],
+                semiFuzzFailure,
                 "Unexpected errors:\n${errorsString}\n\n"
                 "after reordering $uri to have this content:\n\n"
                 "$sb");
@@ -1648,12 +1718,12 @@
     case "vm":
       target = new TestVmTarget(targetFlags);
       break;
+    case "aot":
+      target = new TestVmAotTarget(targetFlags);
+      break;
     case "none":
       target = new NoneTarget(targetFlags);
       break;
-    case "noneWithJs":
-      target = new NoneWithJsTarget(targetFlags);
-      break;
     case "dart2js":
       target = new TestDart2jsTarget('dart2js', targetFlags);
       break;
@@ -1781,10 +1851,6 @@
       await instrumentation.loadExpectations(description.uri);
       sourceTarget.loader.instrumentation = instrumentation;
       Component p = await sourceTarget.buildOutlines();
-      context.componentToTarget.clear();
-      context.componentToTarget[p] = sourceTarget;
-      context.componentToDiagnostics.clear();
-      context.componentToDiagnostics[p] = compilationSetup.errors;
       Set<Uri> userLibraries =
           createUserLibrariesImportUriSet(p, sourceTarget.uriTranslator);
       if (fullCompile) {
@@ -1799,7 +1865,7 @@
           } else {
             return new Result<ComponentResult>(
                 new ComponentResult(description, p, userLibraries,
-                    compilationSetup.options, sourceTarget),
+                    compilationSetup, sourceTarget),
                 context.expectationSet["InstrumentationMismatch"],
                 instrumentation.problemsAsString,
                 autoFixCommand: '${UPDATE_COMMENTS}=true',
@@ -1807,8 +1873,8 @@
           }
         }
       }
-      return pass(new ComponentResult(description, p, userLibraries,
-          compilationSetup.options, sourceTarget));
+      return pass(new ComponentResult(
+          description, p, userLibraries, compilationSetup, sourceTarget));
     });
   }
 
@@ -1850,8 +1916,7 @@
       ComponentResult result, FastaContext context) async {
     return await CompilerContext.runWithOptions(result.options, (_) async {
       Component component = result.component;
-      KernelTarget sourceTarget = context.componentToTarget[component];
-      context.componentToTarget.remove(component);
+      KernelTarget sourceTarget = result.sourceTarget;
       Target backendTarget = sourceTarget.backendTarget;
       if (backendTarget is TestTarget) {
         backendTarget.performModularTransformations = true;
@@ -1872,7 +1937,18 @@
             context.expectationSet["TransformVerificationError"],
             errors.join('\n'));
       }
-      return pass(result);
+      if (backendTarget is TestTarget &&
+          backendTarget.hasGlobalTransformation) {
+        component =
+            backendTarget.performGlobalTransformations(sourceTarget, component);
+        // Clear the currently cached platform since the global transformation
+        // might have modified it.
+        context.clearPlatformCache(
+            backendTarget, result.compilationSetup.options.nnbdMode);
+      }
+
+      return pass(new ComponentResult(result.description, component,
+          result.userLibraries, result.compilationSetup, sourceTarget));
     });
   }
 }
@@ -1973,12 +2049,34 @@
           logger: logger);
     }
   }
+
+  bool get hasGlobalTransformation => false;
+
+  Component performGlobalTransformations(
+          KernelTarget kernelTarget, Component component) =>
+      component;
 }
 
 class TestVmTarget extends VmTarget with TestTarget {
   TestVmTarget(TargetFlags flags) : super(flags);
 }
 
+class TestVmAotTarget extends TestVmTarget {
+  TestVmAotTarget(TargetFlags flags) : super(flags);
+
+  @override
+  bool get hasGlobalTransformation => true;
+
+  @override
+  Component performGlobalTransformations(
+      KernelTarget kernelTarget, Component component) {
+    return type_flow.transformComponent(
+        this, kernelTarget.loader.coreTypes, component,
+        matcher: new type_flow.ConstantPragmaAnnotationParser(
+            kernelTarget.loader.coreTypes));
+  }
+}
+
 class EnsureNoErrors
     extends Step<ComponentResult, ComponentResult, FastaContext> {
   const EnsureNoErrors();
@@ -1987,8 +2085,7 @@
 
   Future<Result<ComponentResult>> run(
       ComponentResult result, FastaContext context) async {
-    List<Iterable<String>> errors =
-        context.componentToDiagnostics[result.component];
+    List<Iterable<String>> errors = result.compilationSetup.errors;
     return errors.isEmpty
         ? pass(result)
         : fail(
@@ -2009,7 +2106,7 @@
     Component component = result.component;
     Uri uri =
         component.uriToSource.keys.firstWhere((uri) => uri?.scheme == "file");
-    KernelTarget target = context.componentToTarget[component];
+    KernelTarget target = result.sourceTarget;
     ClassHierarchyBuilder hierarchy = target.loader.builderHierarchy;
     StringBuffer sb = new StringBuffer();
     for (ClassHierarchyNode node in hierarchy.nodes.values) {
@@ -2039,14 +2136,6 @@
   }
 }
 
-class NoneWithJsTarget extends NoneTarget {
-  NoneWithJsTarget(TargetFlags flags) : super(flags);
-
-  @override
-  ConstantsBackend constantsBackend(CoreTypes coreTypes) =>
-      const NoneConstantsBackendWithJs(supportsUnevaluatedConstants: true);
-}
-
 class NoneConstantsBackendWithJs extends NoneConstantsBackend {
   const NoneConstantsBackendWithJs({bool supportsUnevaluatedConstants})
       : super(supportsUnevaluatedConstants: supportsUnevaluatedConstants);
diff --git a/pkg/front_end/test/fasta/text_serialization1_suite.dart b/pkg/front_end/test/fasta/text_serialization1_suite.dart
deleted file mode 100644
index bccfbcd..0000000
--- a/pkg/front_end/test/fasta/text_serialization1_suite.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.md file.
-
-// @dart = 2.9
-
-import 'text_serialization_tester.dart';
-
-main(List<String> arguments) {
-  internalMain(arguments: arguments, shards: shardCount, shard: 0);
-}
diff --git a/pkg/front_end/test/fasta/text_serialization2_suite.dart b/pkg/front_end/test/fasta/text_serialization2_suite.dart
deleted file mode 100644
index 8b5b2ca..0000000
--- a/pkg/front_end/test/fasta/text_serialization2_suite.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.md file.
-
-// @dart = 2.9
-
-import 'text_serialization_tester.dart';
-
-main(List<String> arguments) {
-  internalMain(arguments: arguments, shards: shardCount, shard: 1);
-}
diff --git a/pkg/front_end/test/fasta/text_serialization3_suite.dart b/pkg/front_end/test/fasta/text_serialization3_suite.dart
deleted file mode 100644
index 682d486..0000000
--- a/pkg/front_end/test/fasta/text_serialization3_suite.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.md file.
-
-// @dart = 2.9
-
-import 'text_serialization_tester.dart';
-
-main(List<String> arguments) {
-  internalMain(arguments: arguments, shards: shardCount, shard: 2);
-}
diff --git a/pkg/front_end/test/fasta/text_serialization4_suite.dart b/pkg/front_end/test/fasta/text_serialization4_suite.dart
deleted file mode 100644
index c6043fc..0000000
--- a/pkg/front_end/test/fasta/text_serialization4_suite.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.md file.
-
-// @dart = 2.9
-
-import 'text_serialization_tester.dart';
-
-main(List<String> arguments) {
-  internalMain(arguments: arguments, shards: shardCount, shard: 3);
-}
diff --git a/pkg/front_end/test/fasta/text_serialization_suite.dart b/pkg/front_end/test/fasta/text_serialization_suite.dart
new file mode 100644
index 0000000..a7018eb
--- /dev/null
+++ b/pkg/front_end/test/fasta/text_serialization_suite.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE.md file.
+
+// @dart = 2.9
+
+library fasta.test.text_serialization_test;
+
+import 'testing/suite.dart';
+
+Future<FastaContext> createContext(
+    Chain suite, Map<String, String> environment) {
+  environment[ENABLE_FULL_COMPILE] = "";
+  environment[KERNEL_TEXT_SERIALIZATION] = "";
+  return FastaContext.create(suite, environment);
+}
+
+main(List<String> arguments) {
+  internalMain(arguments: arguments);
+}
+
+internalMain(
+    {List<String> arguments = const [], int shards = 1, int shard = 0}) {
+  runMe(arguments, createContext,
+      configurationPath: "../../testing.json", shards: shards, shard: shard);
+}
diff --git a/pkg/front_end/test/fasta/text_serialization_tester.dart b/pkg/front_end/test/fasta/text_serialization_tester.dart
deleted file mode 100644
index 25c4081..0000000
--- a/pkg/front_end/test/fasta/text_serialization_tester.dart
+++ /dev/null
@@ -1,33 +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.md file.
-
-// @dart = 2.9
-
-library fasta.test.text_serialization_test;
-
-import 'dart:io' show Platform;
-
-import 'testing/suite.dart';
-
-const int shardCount = 4;
-
-Future<FastaContext> createContext(
-    Chain suite, Map<String, String> environment) {
-  environment[ENABLE_FULL_COMPILE] = "";
-  environment[KERNEL_TEXT_SERIALIZATION] = "";
-  return FastaContext.create(suite, environment);
-}
-
-main(List<String> arguments) {
-  internalMain(arguments: arguments);
-}
-
-internalMain(
-    {List<String> arguments = const [], int shards = 1, int shard = 0}) {
-  runMe(arguments, createContext,
-      configurationPath: "../../testing.json",
-      me: Platform.script.resolve('text_serialization_tester.dart'),
-      shards: shards,
-      shard: shard);
-}
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 6ceb6c7..67cfacc 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
@@ -383,13 +383,9 @@
     parseTestLibrary("");
 
     checkLowerBound(
-        type1: "Object",
-        type2: "FutureOr<Null>",
-        lowerBound: "FutureOr<Never>");
+        type1: "Object", type2: "FutureOr<Null>", lowerBound: "Never");
     checkLowerBound(
-        type1: "FutureOr<Null>",
-        type2: "Object",
-        lowerBound: "FutureOr<Never>");
+        type1: "FutureOr<Null>", type2: "Object", lowerBound: "Never");
 
     // FutureOr<dynamic> is top.
     checkLowerBound(
@@ -1329,6 +1325,59 @@
         type2: "T",
         upperBound: "List<Object?>",
         typeParameters: "T extends List<T>, U extends List<Never>");
+    checkUpperBound(
+        type1: "T",
+        type2: "T",
+        upperBound: "T",
+        typeParameters: "T extends Object?");
+
+    // These cases are observed through `a ?? b`. Here the resulting type
+    // is `UP(NonNull(a),b)`, if `b` is `null`, is `NonNull(a)?`.
+
+    // We have
+    //
+    //     NonNull(T extends Object?) = T & Object
+    //
+    // resulting in
+    //
+    //     (T & Object)? = T? & Object
+    //
+    checkUpperBound(
+        type1: "T",
+        type2: "Null",
+        upperBound: "T? & Object",
+        typeParameters: "T extends Object?",
+        nonNull1: true);
+
+    // We have
+    //
+    //     NonNull(T extends bool?) = T & bool
+    //
+    // resulting in
+    //
+    //     (T & bool)? = T? & bool
+    //
+    checkUpperBound(
+        type1: "T",
+        type2: "Null",
+        upperBound: "T? & bool",
+        typeParameters: "T extends bool?",
+        nonNull1: true);
+
+    // We have
+    //
+    //     NonNull(T extends bool) = T
+    //
+    // resulting in
+    //
+    //     (T)? = T?
+    //
+    checkUpperBound(
+        type1: "T",
+        type2: "Null",
+        upperBound: "T?",
+        typeParameters: "T extends bool",
+        nonNull1: true);
   }
 
   void test_upper_bound_unknown() {
@@ -1521,16 +1570,29 @@
   }
 
   void checkUpperBound(
-      {String type1, String type2, String upperBound, String typeParameters}) {
+      {String type1,
+      String type2,
+      String upperBound,
+      String typeParameters,
+      bool nonNull1: false,
+      bool nonNull2: false}) {
     assert(type1 != null);
     assert(type2 != null);
     assert(upperBound != null);
 
     typeParserEnvironment.withTypeParameters(typeParameters,
         (List<TypeParameter> typeParameterNodes) {
+      DartType dartType1 = parseType(type1);
+      DartType dartType2 = parseType(type2);
+      if (nonNull1) {
+        dartType1 = dartType1.toNonNull();
+      }
+      if (nonNull2) {
+        dartType2 = dartType2.toNonNull();
+      }
       expect(
           typeSchemaEnvironment.getStandardUpperBound(
-              parseType(type1), parseType(type2), testLibrary),
+              dartType1, dartType2, testLibrary),
           parseType(upperBound));
     });
   }
diff --git a/pkg/front_end/test/lint_test.status b/pkg/front_end/test/lint_test.status
index 691adfa..4b2a34a 100644
--- a/pkg/front_end/test/lint_test.status
+++ b/pkg/front_end/test/lint_test.status
@@ -15,7 +15,6 @@
 front_end/lib/src/api_prototype/incremental_kernel_generator/Exports: Fail
 front_end/lib/src/api_prototype/language_version/Exports: Fail
 front_end/lib/src/api_prototype/terminal_color_support/Exports: Fail
-front_end/lib/src/api_unstable/bazel_worker/ImportsTwice: Fail
 front_end/lib/src/fasta/fasta_codes/Exports: Fail
 front_end/lib/src/fasta/incremental_compiler/ImportsTwice: Fail
 front_end/lib/src/fasta/kernel/body_builder/ImportsTwice: Fail
@@ -37,7 +36,6 @@
 front_end/lib/src/fasta/source/scope_listener/Exports: Fail
 front_end/lib/src/fasta/source/source_class_builder/ImportsTwice: Fail
 front_end/lib/src/fasta/source/value_kinds/ImportsTwice: Fail
-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
diff --git a/pkg/front_end/test/parser_test_listener.dart b/pkg/front_end/test/parser_test_listener.dart
index fca16c8..8ffa24f 100644
--- a/pkg/front_end/test/parser_test_listener.dart
+++ b/pkg/front_end/test/parser_test_listener.dart
@@ -1765,6 +1765,11 @@
     doPrint('endConstExpression(' '$token)');
   }
 
+  void handleConstFactory(Token constKeyword) {
+    seen(constKeyword);
+    doPrint('handleConstFactory(' '$constKeyword)');
+  }
+
   void beginForControlFlow(Token? awaitToken, Token forToken) {
     seen(awaitToken);
     seen(forToken);
diff --git a/pkg/front_end/test/spell_checking_list_code.txt b/pkg/front_end/test/spell_checking_list_code.txt
index ba25ffb..cce4737 100644
--- a/pkg/front_end/test/spell_checking_list_code.txt
+++ b/pkg/front_end/test/spell_checking_list_code.txt
@@ -251,6 +251,7 @@
 corrected
 corrections
 cosmetic
+costly
 counters
 covariances
 coverage
@@ -311,6 +312,7 @@
 deserializes
 deserializing
 design
+designation
 despite
 destination
 destinations
@@ -351,6 +353,7 @@
 dst
 dummy
 dupdate
+dyn
 e
 easy
 ecma
@@ -410,6 +413,7 @@
 faced
 factor
 factored
+fairly
 fangorn
 fasta
 favored
@@ -692,6 +696,7 @@
 merely
 meta
 metadata's
+metadatum
 method10a
 method10b
 method1a
@@ -804,6 +809,7 @@
 orders
 ordinal
 org
+orphancy
 orphans
 ors
 os
@@ -876,6 +882,7 @@
 preexisted
 preexisting
 preorder
+presented
 presubmit
 prev
 prime
@@ -886,6 +893,7 @@
 producers
 product
 progresses
+promo
 proof
 prop
 propose
@@ -994,6 +1002,7 @@
 replicated
 repo
 repositories
+repurposed
 requirement
 res
 residue
@@ -1374,6 +1383,7 @@
 wn
 worthwhile
 worthy
+woven
 writeln
 wrongfully
 wrt
diff --git a/pkg/front_end/test/spell_checking_list_common.txt b/pkg/front_end/test/spell_checking_list_common.txt
index 9a5012d..912054f 100644
--- a/pkg/front_end/test/spell_checking_list_common.txt
+++ b/pkg/front_end/test/spell_checking_list_common.txt
@@ -857,6 +857,9 @@
 digit
 digits
 dill
+dimension
+dimensional
+dimensions
 dir
 direct
 direction
@@ -2025,6 +2028,7 @@
 odds
 of
 off
+offs
 offset
 offsets
 often
@@ -2110,6 +2114,8 @@
 package
 packaged
 packages
+packed
+packing
 pad
 padded
 padding
@@ -3039,6 +3045,7 @@
 thumb
 thunk
 thus
+tightly
 time
 timeline
 times
@@ -3148,6 +3155,7 @@
 unbind
 uncertain
 unchanged
+unchecked
 unclaimed
 unclear
 undeclared
diff --git a/pkg/front_end/test/spell_checking_list_tests.txt b/pkg/front_end/test/spell_checking_list_tests.txt
index 59a96f5..17ee5f0 100644
--- a/pkg/front_end/test/spell_checking_list_tests.txt
+++ b/pkg/front_end/test/spell_checking_list_tests.txt
@@ -19,8 +19,10 @@
 aaa
 abc
 abcompile
+adapter
 adaptor
 adopted
+advantages
 albeit
 allocations
 allowlist
@@ -33,6 +35,7 @@
 annoying
 anon
 aoo
+aot
 approval
 approximation
 arbitrarily
@@ -54,6 +57,12 @@
 bail
 bailing
 bailout
+bar1a
+bar1b
+bar2a
+bar2b
+bar3a
+bar3b
 barbar
 bash
 bat
@@ -98,6 +107,7 @@
 c59cdee365b94ce066344840f9e3412d642019b
 ca
 cafebabe
+calloc
 camel
 capitalized
 causal
@@ -142,6 +152,7 @@
 complement
 completers
 complicated
+concurrently
 confidence
 confident
 confirm
@@ -169,6 +180,8 @@
 cursor
 cuts
 cx
+d1a
+d1b
 dacoharkes
 dadd
 daemon
@@ -226,6 +239,7 @@
 doo
 downstream
 draw
+dsemi
 dumping
 dumps
 dupe
@@ -335,6 +349,7 @@
 gave
 gc
 gcd
+gesture
 getter1c
 getter1d
 getter1e
@@ -365,6 +380,7 @@
 i'm
 ia
 ideal
+identification
 idle
 ikg
 illustrate
@@ -504,10 +520,13 @@
 modelled
 month
 moo
+mouse
 mul
 mx
 mxn
 mysdk
+n1a
+n1b
 naively
 naturally
 negatable
@@ -522,6 +541,7 @@
 ob
 obool
 observable
+offers
 oh
 okay
 ol
@@ -567,6 +587,8 @@
 prematurely
 press
 pretends
+processes
+processors
 producer
 profile
 profiler
@@ -670,6 +692,7 @@
 signalled
 sigwinch
 slight
+sliver
 smoke
 snull
 somehow
@@ -736,9 +759,11 @@
 timings
 tinv
 told
+touch
 tpt
 transitively
 translators
+transparent
 triangle
 triggers
 trimming
diff --git a/pkg/front_end/test/testing_utils.dart b/pkg/front_end/test/testing_utils.dart
index 6781673..502ac99 100644
--- a/pkg/front_end/test/testing_utils.dart
+++ b/pkg/front_end/test/testing_utils.dart
@@ -43,7 +43,9 @@
   Set<String> environmentKeys = environment.keys.toSet();
   environmentKeys.removeAll(knownEnvironmentKeys);
   if (environmentKeys.isNotEmpty) {
-    throw "Unknown environment(s) given: ${environmentKeys.toList()}.\n"
-        "Knows about ${knownEnvironmentKeys.toList()}";
+    throw "Unknown environment(s) given:"
+        "\n - ${environmentKeys.join("\n- ")}\n"
+        "Knows about these environment(s):"
+        "\n - ${knownEnvironmentKeys.join("\n - ")}";
   }
 }
diff --git a/pkg/front_end/test/unit_test_suites_impl.dart b/pkg/front_end/test/unit_test_suites_impl.dart
index 70a67b3..c67f5b3 100644
--- a/pkg/front_end/test/unit_test_suites_impl.dart
+++ b/pkg/front_end/test/unit_test_suites_impl.dart
@@ -23,7 +23,7 @@
 import 'fasta/messages_suite.dart' as messages show createContext;
 import 'fasta/outline_suite.dart' as outline show createContext;
 import 'fasta/strong_suite.dart' as strong show createContext;
-import 'fasta/text_serialization_tester.dart' as text_serialization
+import 'fasta/text_serialization_suite.dart' as text_serialization
     show createContext;
 import 'fasta/textual_outline_suite.dart' as textual_outline show createContext;
 import 'fasta/weak_suite.dart' as weak show createContext;
@@ -349,7 +349,7 @@
     "fasta/text_serialization",
     text_serialization.createContext,
     "../../testing.json",
-    path: "fasta/text_serialization_tester.dart",
+    path: "fasta/text_serialization_suite.dart",
     shardCount: 10,
   ),
   const Suite(
diff --git a/pkg/front_end/test/utils/kernel_chain.dart b/pkg/front_end/test/utils/kernel_chain.dart
index 5afe941..f3d539c 100644
--- a/pkg/front_end/test/utils/kernel_chain.dart
+++ b/pkg/front_end/test/utils/kernel_chain.dart
@@ -61,6 +61,8 @@
         Step,
         TestDescription;
 
+import '../fasta/testing/suite.dart' show CompilationSetup;
+
 final Uri platformBinariesLocation = computePlatformBinariesLocation();
 
 abstract class MatchContext implements ChainContext {
@@ -82,7 +84,9 @@
       expectationSet["ExpectationFileMissing"];
 
   Future<Result<O>> match<O>(String suffix, String actual, Uri uri, O output,
-      {Expectation onMismatch}) async {
+      {Expectation onMismatch, bool overwriteUpdateExpectationsWith}) async {
+    bool updateExpectations =
+        overwriteUpdateExpectationsWith ?? this.updateExpectations;
     actual = actual.trim();
     if (actual.isNotEmpty) {
       actual += "\n";
@@ -241,8 +245,7 @@
 
     StringBuffer buffer = new StringBuffer();
 
-    List<Iterable<String>> errors =
-        (context as dynamic).componentToDiagnostics[component];
+    List<Iterable<String>> errors = result.compilationSetup.errors;
     Set<String> reportedErrors = <String>{};
     for (Iterable<String> message in errors) {
       reportedErrors.add(message.join('\n'));
@@ -337,7 +340,8 @@
     return context.match<ComponentResult>(suffix, actual, uri, result,
         onMismatch: serializeFirst
             ? context.expectationFileMismatchSerialized
-            : context.expectationFileMismatch);
+            : context.expectationFileMismatch,
+        overwriteUpdateExpectationsWith: serializeFirst ? false : null);
   }
 }
 
@@ -420,8 +424,13 @@
     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.compilationSetup,
+        result.sourceTarget,
+        uri);
     try {
       new BinaryPrinter(sink).writeComponentFile(component);
     } catch (e, s) {
@@ -517,12 +526,12 @@
   final Component component;
   final Set<Uri> userLibraries;
   final Uri outputUri;
-  final ProcessedOptions options;
+  final CompilationSetup compilationSetup;
   final KernelTarget sourceTarget;
   final List<String> extraConstantStrings = [];
 
   ComponentResult(this.description, this.component, this.userLibraries,
-      this.options, this.sourceTarget,
+      this.compilationSetup, this.sourceTarget,
       [this.outputUri]);
 
   bool isUserLibrary(Library library) {
@@ -532,4 +541,6 @@
   bool isUserLibraryImportUri(Uri importUri) {
     return userLibraries.contains(importUri);
   }
+
+  ProcessedOptions get options => compilationSetup.options;
 }
diff --git a/pkg/front_end/test/weekly_tester.dart b/pkg/front_end/test/weekly_tester.dart
new file mode 100644
index 0000000..ba30452
--- /dev/null
+++ b/pkg/front_end/test/weekly_tester.dart
@@ -0,0 +1,134 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// 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.
+
+import 'dart:async' show Future;
+import 'dart:convert' show LineSplitter, utf8;
+import 'dart:io' show File, Platform, Process, exitCode;
+
+main(List<String> args) async {
+  // General idea: Launch - in separate processes - whatever we want to run
+  // concurrently, capturing the stdout and stderr, printing it with some
+  // prepended identification.
+  // When all runs are done, fail if any fails.
+  // Later we might be able to move it to the "testRunner"-system, if that
+  // offers any advantages.
+
+  print("NOTE: This machine has ${Platform.numberOfProcessors} processors!"
+      "\n\n");
+
+  List<WrappedProcess> startedProcesses = [];
+  {
+    // Very slow: Leak-test.
+    Uri leakTester =
+        Platform.script.resolve("flutter_gallery_leak_tester.dart");
+    if (!new File.fromUri(leakTester).existsSync()) {
+      exitCode = 1;
+      print("Couldn't find $leakTester");
+    } else {
+      // The tools/bots/flutter/compile_flutter.sh script passes `--path`
+      // --- we'll just pass everything along.
+      startedProcesses
+          .add(await run([leakTester.toString(), ...args], "leak test"));
+    }
+  }
+  {
+    // Slow: Leak-test with alternative invalidation.
+    Uri leakTester =
+        Platform.script.resolve("flutter_gallery_leak_tester.dart");
+    if (!new File.fromUri(leakTester).existsSync()) {
+      exitCode = 1;
+      print("Couldn't find $leakTester");
+    } else {
+      // Note that the leak test run above will start checking out flutter
+      // gallery (etc) and that it has to finish before starting this.
+      // We therefore wait for the observatory line being printed before
+      // starting. Wait at most 10 minutes though.
+
+      // ignore: unawaited_futures
+      () async {
+        for (int i = 0; i < 10 * 60; i++) {
+          if (observatoryLines.isNotEmpty) break;
+          await Future.delayed(new Duration(seconds: 1));
+        }
+
+        // The tools/bots/flutter/compile_flutter.sh script passes `--path`
+        // --- we'll just pass everything along.
+        startedProcesses.add(await run(
+            [leakTester.toString(), ...args, "--alternativeInvalidation"],
+            "leak test alternative invalidation"));
+      }();
+    }
+  }
+
+  {
+    // Weak suite with fuzzing.
+    Uri weakSuite = Platform.script.resolve("fasta/weak_suite.dart");
+    if (!new File.fromUri(weakSuite).existsSync()) {
+      exitCode = 1;
+      print("Couldn't find $weakSuite");
+    } else {
+      startedProcesses.add(
+          await run([weakSuite.toString(), "-DsemiFuzz=true"], "weak suite"));
+    }
+  }
+
+  {
+    // Strong suite with fuzzing.
+    Uri strongSuite = Platform.script.resolve("fasta/strong_suite.dart");
+    if (!new File.fromUri(strongSuite).existsSync()) {
+      exitCode = 1;
+      print("Couldn't find $strongSuite");
+    } else {
+      startedProcesses.add(await run(
+          [strongSuite.toString(), "-DsemiFuzz=true"], "strong suite"));
+    }
+  }
+
+  // Wait for everything to finish.
+  List<int> exitCodes =
+      await Future.wait(startedProcesses.map((e) => e.process.exitCode));
+  if (exitCodes.where((e) => e != 0).isNotEmpty) {
+    // At least one failed.
+    exitCode = 1;
+    for (WrappedProcess p in startedProcesses) {
+      int pExitCode = await p.process.exitCode;
+      if (pExitCode != 0) {
+        print("${p.id} failed with exist-code $pExitCode");
+      }
+    }
+  }
+}
+
+List<String> observatoryLines = [];
+
+Future<WrappedProcess> run(List<String> args, String id) async {
+  Process process = await Process.start(
+      Platform.resolvedExecutable, ["--enable-asserts", ...args]);
+  process.stderr
+      .transform(utf8.decoder)
+      .transform(new LineSplitter())
+      .listen((line) {
+    print("$id stderr> $line");
+    if (line.contains("Observatory listening on")) {
+      observatoryLines.add(line);
+    }
+  });
+  process.stdout
+      .transform(utf8.decoder)
+      .transform(new LineSplitter())
+      .listen((line) {
+    print("$id stdout> $line");
+    if (line.contains("Observatory listening on")) {
+      observatoryLines.add(line);
+    }
+  });
+  return new WrappedProcess(process, id);
+}
+
+class WrappedProcess {
+  final Process process;
+  final String id;
+
+  WrappedProcess(this.process, this.id);
+}
diff --git a/pkg/front_end/testcases/aot/enum_from_lib_used_as_type/main.dart b/pkg/front_end/testcases/aot/enum_from_lib_used_as_type/main.dart
new file mode 100644
index 0000000..d2ee09c
--- /dev/null
+++ b/pkg/front_end/testcases/aot/enum_from_lib_used_as_type/main.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. 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';
+
+main() {
+  List list = [];
+  if (list.isNotEmpty) {
+    new Class().method(null as dynamic);
+  }
+}
diff --git a/pkg/front_end/testcases/aot/enum_from_lib_used_as_type/main.dart.strong.expect b/pkg/front_end/testcases/aot/enum_from_lib_used_as_type/main.dart.strong.expect
new file mode 100644
index 0000000..09282c5
--- /dev/null
+++ b/pkg/front_end/testcases/aot/enum_from_lib_used_as_type/main.dart.strong.expect
@@ -0,0 +1,49 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "main_lib.dart" as mai;
+
+import "org-dartlang-testcase:///main_lib.dart";
+
+static method main() → dynamic {
+  core::List<dynamic> list = <dynamic>[];
+  if(list.{core::Iterable::isNotEmpty}) {
+    new mai::Class::•().{mai::Class::method}((null as{ForNonNullableByDefault} dynamic) as{TypeError,ForDynamic,ForNonNullableByDefault} mai::Enum);
+  }
+}
+
+library /*isNonNullableByDefault*/;
+import self as mai;
+import "dart:core" as core;
+
+class Enum extends core::Object /*isEnum*/  {
+  final field core::int index;
+  final field core::String _name;
+  static const field core::List<mai::Enum> values = #C4;
+  static const field mai::Enum a = #C3;
+  const constructor •(core::int index, core::String _name) → mai::Enum
+    : mai::Enum::index = index, mai::Enum::_name = _name, super core::Object::•()
+    ;
+  method toString() → core::String
+    return this.{mai::Enum::_name};
+}
+class Class extends core::Object {
+  synthetic constructor •() → mai::Class
+    : super core::Object::•()
+    ;
+  method method(mai::Enum e) → core::int
+    return e.{mai::Enum::index};
+}
+
+constants  {
+  #C1 = 0
+  #C2 = "Enum.a"
+  #C3 = mai::Enum {index:#C1, _name:#C2}
+  #C4 = <mai::Enum>[#C3]
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///main_lib.dart:
+- Enum. (from org-dartlang-testcase:///main_lib.dart:5:6)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/aot/enum_from_lib_used_as_type/main.dart.strong.transformed.expect b/pkg/front_end/testcases/aot/enum_from_lib_used_as_type/main.dart.strong.transformed.expect
new file mode 100644
index 0000000..24d6d3b
--- /dev/null
+++ b/pkg/front_end/testcases/aot/enum_from_lib_used_as_type/main.dart.strong.transformed.expect
@@ -0,0 +1,32 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "main_lib.dart" as mai;
+import "dart:_internal" as _in;
+
+import "org-dartlang-testcase:///main_lib.dart";
+
+static method main() → dynamic {
+  core::List<dynamic> list = core::_GrowableList::•<dynamic>(0);
+  if(list.{core::Iterable::isNotEmpty}) {
+    let dynamic #t1 = new mai::Class::•() in let dynamic #t2 = _in::unsafeCast<dynamic>(null) as{TypeError,ForDynamic,ForNonNullableByDefault} mai::Enum in throw "Attempt to execute code removed by Dart AOT compiler (TFA)";
+  }
+}
+
+library /*isNonNullableByDefault*/;
+import self as mai;
+import "dart:core" as core;
+
+abstract class Enum extends core::Object {
+}
+class Class extends core::Object {
+  synthetic constructor •() → mai::Class
+    : super core::Object::•()
+    ;
+}
+
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///main_lib.dart:
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/aot/enum_from_lib_used_as_type/main.dart.textual_outline.expect b/pkg/front_end/testcases/aot/enum_from_lib_used_as_type/main.dart.textual_outline.expect
new file mode 100644
index 0000000..82be6bb
--- /dev/null
+++ b/pkg/front_end/testcases/aot/enum_from_lib_used_as_type/main.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+import 'main_lib.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/aot/enum_from_lib_used_as_type/main.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/aot/enum_from_lib_used_as_type/main.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..82be6bb
--- /dev/null
+++ b/pkg/front_end/testcases/aot/enum_from_lib_used_as_type/main.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+import 'main_lib.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/aot/enum_from_lib_used_as_type/main.dart.weak.expect b/pkg/front_end/testcases/aot/enum_from_lib_used_as_type/main.dart.weak.expect
new file mode 100644
index 0000000..d3516e5
--- /dev/null
+++ b/pkg/front_end/testcases/aot/enum_from_lib_used_as_type/main.dart.weak.expect
@@ -0,0 +1,49 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "main_lib.dart" as mai;
+
+import "org-dartlang-testcase:///main_lib.dart";
+
+static method main() → dynamic {
+  core::List<dynamic> list = <dynamic>[];
+  if(list.{core::Iterable::isNotEmpty}) {
+    new mai::Class::•().{mai::Class::method}((null as{ForNonNullableByDefault} dynamic) as{TypeError,ForDynamic,ForNonNullableByDefault} mai::Enum);
+  }
+}
+
+library /*isNonNullableByDefault*/;
+import self as mai;
+import "dart:core" as core;
+
+class Enum extends core::Object /*isEnum*/  {
+  final field core::int index;
+  final field core::String _name;
+  static const field core::List<mai::Enum> values = #C4;
+  static const field mai::Enum a = #C3;
+  const constructor •(core::int index, core::String _name) → mai::Enum
+    : mai::Enum::index = index, mai::Enum::_name = _name, super core::Object::•()
+    ;
+  method toString() → core::String
+    return this.{mai::Enum::_name};
+}
+class Class extends core::Object {
+  synthetic constructor •() → mai::Class
+    : super core::Object::•()
+    ;
+  method method(mai::Enum e) → core::int
+    return e.{mai::Enum::index};
+}
+
+constants  {
+  #C1 = 0
+  #C2 = "Enum.a"
+  #C3 = mai::Enum {index:#C1, _name:#C2}
+  #C4 = <mai::Enum*>[#C3]
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///main_lib.dart:
+- Enum. (from org-dartlang-testcase:///main_lib.dart:5:6)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/aot/enum_from_lib_used_as_type/main.dart.weak.outline.expect b/pkg/front_end/testcases/aot/enum_from_lib_used_as_type/main.dart.weak.outline.expect
new file mode 100644
index 0000000..5574f01
--- /dev/null
+++ b/pkg/front_end/testcases/aot/enum_from_lib_used_as_type/main.dart.weak.outline.expect
@@ -0,0 +1,42 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+
+import "org-dartlang-testcase:///main_lib.dart";
+
+static method main() → dynamic
+  ;
+
+library /*isNonNullableByDefault*/;
+import self as self2;
+import "dart:core" as core;
+
+class Enum extends core::Object /*isEnum*/  {
+  final field core::int index;
+  final field core::String _name;
+  static const field core::List<self2::Enum> values = #C4;
+  static const field self2::Enum a = #C3;
+  const constructor •(core::int index, core::String _name) → self2::Enum
+    : self2::Enum::index = index, self2::Enum::_name = _name, super core::Object::•()
+    ;
+  method toString() → core::String
+    return this.{self2::Enum::_name};
+}
+class Class extends core::Object {
+  synthetic constructor •() → self2::Class
+    ;
+  method method(self2::Enum e) → core::int
+    ;
+}
+
+constants  {
+  #C1 = 0
+  #C2 = "Enum.a"
+  #C3 = self2::Enum {index:#C1, _name:#C2}
+  #C4 = <self2::Enum*>[#C3]
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///main_lib.dart:
+- Enum. (from org-dartlang-testcase:///main_lib.dart:5:6)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/aot/enum_from_lib_used_as_type/main.dart.weak.transformed.expect b/pkg/front_end/testcases/aot/enum_from_lib_used_as_type/main.dart.weak.transformed.expect
new file mode 100644
index 0000000..040adbc
--- /dev/null
+++ b/pkg/front_end/testcases/aot/enum_from_lib_used_as_type/main.dart.weak.transformed.expect
@@ -0,0 +1,35 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "main_lib.dart" as mai;
+import "dart:_internal" as _in;
+
+import "org-dartlang-testcase:///main_lib.dart";
+
+static method main() → dynamic {
+  core::List<dynamic> list = core::_GrowableList::•<dynamic>(0);
+  if(list.{core::Iterable::isNotEmpty}) {
+    new mai::Class::•().{mai::Class::method}(_in::unsafeCast<mai::Enum>(_in::unsafeCast<dynamic>(null)));
+  }
+}
+
+library /*isNonNullableByDefault*/;
+import self as mai;
+import "dart:core" as core;
+
+abstract class Enum extends core::Object {
+  abstract get /*isLegacy*/ index() → core::int;
+}
+class Class extends core::Object {
+  synthetic constructor •() → mai::Class
+    : super core::Object::•()
+    ;
+  method method(mai::Enum e) → core::int
+    return e.{mai::Enum::index};
+}
+
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///main_lib.dart:
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/aot/enum_from_lib_used_as_type/main_lib.dart b/pkg/front_end/testcases/aot/enum_from_lib_used_as_type/main_lib.dart
new file mode 100644
index 0000000..e5600e4
--- /dev/null
+++ b/pkg/front_end/testcases/aot/enum_from_lib_used_as_type/main_lib.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+enum Enum { a }
+
+class Class {
+  int method(Enum e) => e.index;
+}
diff --git a/pkg/front_end/testcases/aot/enum_from_lib_used_as_type/test.options b/pkg/front_end/testcases/aot/enum_from_lib_used_as_type/test.options
new file mode 100644
index 0000000..bfe6dc8
--- /dev/null
+++ b/pkg/front_end/testcases/aot/enum_from_lib_used_as_type/test.options
@@ -0,0 +1 @@
+main_lib.dart
\ No newline at end of file
diff --git a/pkg/front_end/testcases/aot/folder.options b/pkg/front_end/testcases/aot/folder.options
new file mode 100644
index 0000000..a8a8650
--- /dev/null
+++ b/pkg/front_end/testcases/aot/folder.options
@@ -0,0 +1 @@
+--target=aot
\ No newline at end of file
diff --git a/pkg/front_end/testcases/aot/tree_shake/main.dart b/pkg/front_end/testcases/aot/tree_shake/main.dart
new file mode 100644
index 0000000..8958414
--- /dev/null
+++ b/pkg/front_end/testcases/aot/tree_shake/main.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. 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';
+
+enum UnusedEnum { a, b }
+enum UsedEnum {
+  unusedValue,
+  usedValue,
+}
+
+usedMethod(UnusedInterface c) {
+  c.usedInterfaceField = c.usedInterfaceField;
+}
+
+unusedMethod() {}
+
+class UnusedInterface {
+  int? usedInterfaceField;
+
+  UnusedInterface(this.usedInterfaceField);
+}
+
+class UsedClass implements UnusedInterface {
+  int? unusedField;
+  int? usedField;
+  int? usedInterfaceField;
+}
+
+class UnusedClass {}
+
+main() {
+  usedMethod(new UsedClass()..usedField);
+  UsedEnum.usedValue;
+  List<UnusedEnum> list = [];
+  if (list.isNotEmpty) {
+    new ConstClass().method(null as dynamic);
+  }
+}
diff --git a/pkg/front_end/testcases/aot/tree_shake/main.dart.strong.expect b/pkg/front_end/testcases/aot/tree_shake/main.dart.strong.expect
new file mode 100644
index 0000000..57eb8a2
--- /dev/null
+++ b/pkg/front_end/testcases/aot/tree_shake/main.dart.strong.expect
@@ -0,0 +1,116 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "main_lib.dart" as mai;
+
+import "org-dartlang-testcase:///main_lib.dart";
+
+class UnusedEnum extends core::Object /*isEnum*/  {
+  final field core::int index;
+  final field core::String _name;
+  static const field core::List<self::UnusedEnum> values = #C7;
+  static const field self::UnusedEnum a = #C3;
+  static const field self::UnusedEnum b = #C6;
+  const constructor •(core::int index, core::String _name) → self::UnusedEnum
+    : self::UnusedEnum::index = index, self::UnusedEnum::_name = _name, super core::Object::•()
+    ;
+  method toString() → core::String
+    return this.{self::UnusedEnum::_name};
+}
+class UsedEnum extends core::Object /*isEnum*/  {
+  final field core::int index;
+  final field core::String _name;
+  static const field core::List<self::UsedEnum> values = #C12;
+  static const field self::UsedEnum unusedValue = #C9;
+  static const field self::UsedEnum usedValue = #C11;
+  const constructor •(core::int index, core::String _name) → self::UsedEnum
+    : self::UsedEnum::index = index, self::UsedEnum::_name = _name, super core::Object::•()
+    ;
+  method toString() → core::String
+    return this.{self::UsedEnum::_name};
+}
+class UnusedInterface extends core::Object {
+  field core::int? usedInterfaceField;
+  constructor •(core::int? usedInterfaceField) → self::UnusedInterface
+    : self::UnusedInterface::usedInterfaceField = usedInterfaceField, super core::Object::•()
+    ;
+}
+class UsedClass extends core::Object implements self::UnusedInterface {
+  field core::int? unusedField = null;
+  field core::int? usedField = null;
+  field core::int? usedInterfaceField = null;
+  synthetic constructor •() → self::UsedClass
+    : super core::Object::•()
+    ;
+}
+class UnusedClass extends core::Object {
+  synthetic constructor •() → self::UnusedClass
+    : super core::Object::•()
+    ;
+}
+static method usedMethod(self::UnusedInterface c) → dynamic {
+  c.{self::UnusedInterface::usedInterfaceField} = c.{self::UnusedInterface::usedInterfaceField};
+}
+static method unusedMethod() → dynamic {}
+static method main() → dynamic {
+  self::usedMethod(let final self::UsedClass #t1 = new self::UsedClass::•() in block {
+    #t1.{self::UsedClass::usedField};
+  } =>#t1);
+  #C11;
+  core::List<self::UnusedEnum> list = <self::UnusedEnum>[];
+  if(list.{core::Iterable::isNotEmpty}) {
+    new mai::ConstClass::•().{mai::ConstClass::method}((null as{ForNonNullableByDefault} dynamic) as{TypeError,ForDynamic,ForNonNullableByDefault} mai::ConstEnum);
+  }
+}
+
+library /*isNonNullableByDefault*/;
+import self as mai;
+import "dart:core" as core;
+
+class ConstEnum extends core::Object /*isEnum*/  {
+  final field core::int index;
+  final field core::String _name;
+  static const field core::List<mai::ConstEnum> values = #C15;
+  static const field mai::ConstEnum value = #C14;
+  const constructor •(core::int index, core::String _name) → mai::ConstEnum
+    : mai::ConstEnum::index = index, mai::ConstEnum::_name = _name, super core::Object::•()
+    ;
+  method toString() → core::String
+    return this.{mai::ConstEnum::_name};
+}
+class ConstClass extends core::Object {
+  synthetic constructor •() → mai::ConstClass
+    : super core::Object::•()
+    ;
+  method method(mai::ConstEnum e) → core::int
+    return e.{mai::ConstEnum::index};
+}
+
+constants  {
+  #C1 = 0
+  #C2 = "UnusedEnum.a"
+  #C3 = self::UnusedEnum {index:#C1, _name:#C2}
+  #C4 = 1
+  #C5 = "UnusedEnum.b"
+  #C6 = self::UnusedEnum {index:#C4, _name:#C5}
+  #C7 = <self::UnusedEnum>[#C3, #C6]
+  #C8 = "UsedEnum.unusedValue"
+  #C9 = self::UsedEnum {index:#C1, _name:#C8}
+  #C10 = "UsedEnum.usedValue"
+  #C11 = self::UsedEnum {index:#C4, _name:#C10}
+  #C12 = <self::UsedEnum>[#C9, #C11]
+  #C13 = "ConstEnum.value"
+  #C14 = mai::ConstEnum {index:#C1, _name:#C13}
+  #C15 = <mai::ConstEnum>[#C14]
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///main_lib.dart:
+- ConstEnum. (from org-dartlang-testcase:///main_lib.dart:5:6)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
+
+org-dartlang-testcase:///main.dart:
+- UnusedEnum. (from org-dartlang-testcase:///main.dart:7:6)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
+- UsedEnum. (from org-dartlang-testcase:///main.dart:8:6)
diff --git a/pkg/front_end/testcases/aot/tree_shake/main.dart.strong.transformed.expect b/pkg/front_end/testcases/aot/tree_shake/main.dart.strong.transformed.expect
new file mode 100644
index 0000000..23b7ce8
--- /dev/null
+++ b/pkg/front_end/testcases/aot/tree_shake/main.dart.strong.transformed.expect
@@ -0,0 +1,66 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "main_lib.dart" as mai;
+import "dart:_internal" as _in;
+
+import "org-dartlang-testcase:///main_lib.dart";
+
+abstract class UnusedEnum extends core::Object {
+}
+class UsedEnum extends core::Object /*isEnum*/  {
+  final field core::int index;
+  final field core::String _name;
+  method toString() → core::String
+    return this.{self::UsedEnum::_name};
+}
+abstract class UnusedInterface extends core::Object {
+  abstract get /*isLegacy*/ usedInterfaceField() → core::int?;
+  abstract set /*isLegacy*/ usedInterfaceField(core::int? value) → void;
+}
+class UsedClass extends core::Object implements self::UnusedInterface {
+  field core::int? usedField = null;
+  field core::int? usedInterfaceField = null;
+  synthetic constructor •() → self::UsedClass
+    : super core::Object::•()
+    ;
+}
+static method usedMethod(self::UnusedInterface c) → dynamic {
+  c.{self::UnusedInterface::usedInterfaceField} = c.{self::UnusedInterface::usedInterfaceField};
+}
+static method main() → dynamic {
+  self::usedMethod(let final self::UsedClass #t1 = new self::UsedClass::•() in block {
+    #t1.{self::UsedClass::usedField};
+  } =>#t1);
+  #C3;
+  core::List<self::UnusedEnum> list = core::_GrowableList::•<self::UnusedEnum>(0);
+  if(list.{core::Iterable::isNotEmpty}) {
+    let dynamic #t2 = new mai::ConstClass::•() in let dynamic #t3 = _in::unsafeCast<dynamic>(null) as{TypeError,ForDynamic,ForNonNullableByDefault} mai::ConstEnum in throw "Attempt to execute code removed by Dart AOT compiler (TFA)";
+  }
+}
+
+library /*isNonNullableByDefault*/;
+import self as mai;
+import "dart:core" as core;
+
+abstract class ConstEnum extends core::Object {
+}
+class ConstClass extends core::Object {
+  synthetic constructor •() → mai::ConstClass
+    : super core::Object::•()
+    ;
+}
+
+constants  {
+  #C1 = 1
+  #C2 = "UsedEnum.usedValue"
+  #C3 = self::UsedEnum {index:#C1, _name:#C2}
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///main_lib.dart:
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
+
+org-dartlang-testcase:///main.dart:
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/aot/tree_shake/main.dart.textual_outline.expect b/pkg/front_end/testcases/aot/tree_shake/main.dart.textual_outline.expect
new file mode 100644
index 0000000..97f788b
--- /dev/null
+++ b/pkg/front_end/testcases/aot/tree_shake/main.dart.textual_outline.expect
@@ -0,0 +1,24 @@
+import 'main_lib.dart';
+
+enum UnusedEnum { a, b }
+enum UsedEnum {
+  unusedValue,
+  usedValue,
+}
+usedMethod(UnusedInterface c) {}
+unusedMethod() {}
+
+class UnusedInterface {
+  int? usedInterfaceField;
+  UnusedInterface(this.usedInterfaceField);
+}
+
+class UsedClass implements UnusedInterface {
+  int? unusedField;
+  int? usedField;
+  int? usedInterfaceField;
+}
+
+class UnusedClass {}
+
+main() {}
diff --git a/pkg/front_end/testcases/aot/tree_shake/main.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/aot/tree_shake/main.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a10c6f3
--- /dev/null
+++ b/pkg/front_end/testcases/aot/tree_shake/main.dart.textual_outline_modelled.expect
@@ -0,0 +1,23 @@
+import 'main_lib.dart';
+
+class UnusedClass {}
+
+class UnusedInterface {
+  UnusedInterface(this.usedInterfaceField);
+  int? usedInterfaceField;
+}
+
+class UsedClass implements UnusedInterface {
+  int? unusedField;
+  int? usedField;
+  int? usedInterfaceField;
+}
+
+enum UnusedEnum { a, b }
+enum UsedEnum {
+  unusedValue,
+  usedValue,
+}
+main() {}
+unusedMethod() {}
+usedMethod(UnusedInterface c) {}
diff --git a/pkg/front_end/testcases/aot/tree_shake/main.dart.weak.expect b/pkg/front_end/testcases/aot/tree_shake/main.dart.weak.expect
new file mode 100644
index 0000000..55eeff3
--- /dev/null
+++ b/pkg/front_end/testcases/aot/tree_shake/main.dart.weak.expect
@@ -0,0 +1,116 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "main_lib.dart" as mai;
+
+import "org-dartlang-testcase:///main_lib.dart";
+
+class UnusedEnum extends core::Object /*isEnum*/  {
+  final field core::int index;
+  final field core::String _name;
+  static const field core::List<self::UnusedEnum> values = #C7;
+  static const field self::UnusedEnum a = #C3;
+  static const field self::UnusedEnum b = #C6;
+  const constructor •(core::int index, core::String _name) → self::UnusedEnum
+    : self::UnusedEnum::index = index, self::UnusedEnum::_name = _name, super core::Object::•()
+    ;
+  method toString() → core::String
+    return this.{self::UnusedEnum::_name};
+}
+class UsedEnum extends core::Object /*isEnum*/  {
+  final field core::int index;
+  final field core::String _name;
+  static const field core::List<self::UsedEnum> values = #C12;
+  static const field self::UsedEnum unusedValue = #C9;
+  static const field self::UsedEnum usedValue = #C11;
+  const constructor •(core::int index, core::String _name) → self::UsedEnum
+    : self::UsedEnum::index = index, self::UsedEnum::_name = _name, super core::Object::•()
+    ;
+  method toString() → core::String
+    return this.{self::UsedEnum::_name};
+}
+class UnusedInterface extends core::Object {
+  field core::int? usedInterfaceField;
+  constructor •(core::int? usedInterfaceField) → self::UnusedInterface
+    : self::UnusedInterface::usedInterfaceField = usedInterfaceField, super core::Object::•()
+    ;
+}
+class UsedClass extends core::Object implements self::UnusedInterface {
+  field core::int? unusedField = null;
+  field core::int? usedField = null;
+  field core::int? usedInterfaceField = null;
+  synthetic constructor •() → self::UsedClass
+    : super core::Object::•()
+    ;
+}
+class UnusedClass extends core::Object {
+  synthetic constructor •() → self::UnusedClass
+    : super core::Object::•()
+    ;
+}
+static method usedMethod(self::UnusedInterface c) → dynamic {
+  c.{self::UnusedInterface::usedInterfaceField} = c.{self::UnusedInterface::usedInterfaceField};
+}
+static method unusedMethod() → dynamic {}
+static method main() → dynamic {
+  self::usedMethod(let final self::UsedClass #t1 = new self::UsedClass::•() in block {
+    #t1.{self::UsedClass::usedField};
+  } =>#t1);
+  #C11;
+  core::List<self::UnusedEnum> list = <self::UnusedEnum>[];
+  if(list.{core::Iterable::isNotEmpty}) {
+    new mai::ConstClass::•().{mai::ConstClass::method}((null as{ForNonNullableByDefault} dynamic) as{TypeError,ForDynamic,ForNonNullableByDefault} mai::ConstEnum);
+  }
+}
+
+library /*isNonNullableByDefault*/;
+import self as mai;
+import "dart:core" as core;
+
+class ConstEnum extends core::Object /*isEnum*/  {
+  final field core::int index;
+  final field core::String _name;
+  static const field core::List<mai::ConstEnum> values = #C15;
+  static const field mai::ConstEnum value = #C14;
+  const constructor •(core::int index, core::String _name) → mai::ConstEnum
+    : mai::ConstEnum::index = index, mai::ConstEnum::_name = _name, super core::Object::•()
+    ;
+  method toString() → core::String
+    return this.{mai::ConstEnum::_name};
+}
+class ConstClass extends core::Object {
+  synthetic constructor •() → mai::ConstClass
+    : super core::Object::•()
+    ;
+  method method(mai::ConstEnum e) → core::int
+    return e.{mai::ConstEnum::index};
+}
+
+constants  {
+  #C1 = 0
+  #C2 = "UnusedEnum.a"
+  #C3 = self::UnusedEnum {index:#C1, _name:#C2}
+  #C4 = 1
+  #C5 = "UnusedEnum.b"
+  #C6 = self::UnusedEnum {index:#C4, _name:#C5}
+  #C7 = <self::UnusedEnum*>[#C3, #C6]
+  #C8 = "UsedEnum.unusedValue"
+  #C9 = self::UsedEnum {index:#C1, _name:#C8}
+  #C10 = "UsedEnum.usedValue"
+  #C11 = self::UsedEnum {index:#C4, _name:#C10}
+  #C12 = <self::UsedEnum*>[#C9, #C11]
+  #C13 = "ConstEnum.value"
+  #C14 = mai::ConstEnum {index:#C1, _name:#C13}
+  #C15 = <mai::ConstEnum*>[#C14]
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///main_lib.dart:
+- ConstEnum. (from org-dartlang-testcase:///main_lib.dart:5:6)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
+
+org-dartlang-testcase:///main.dart:
+- UnusedEnum. (from org-dartlang-testcase:///main.dart:7:6)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
+- UsedEnum. (from org-dartlang-testcase:///main.dart:8:6)
diff --git a/pkg/front_end/testcases/aot/tree_shake/main.dart.weak.outline.expect b/pkg/front_end/testcases/aot/tree_shake/main.dart.weak.outline.expect
new file mode 100644
index 0000000..43c42d9
--- /dev/null
+++ b/pkg/front_end/testcases/aot/tree_shake/main.dart.weak.outline.expect
@@ -0,0 +1,96 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///main_lib.dart";
+
+class UnusedEnum extends core::Object /*isEnum*/  {
+  final field core::int index;
+  final field core::String _name;
+  static const field core::List<self::UnusedEnum> values = const <self::UnusedEnum>[self::UnusedEnum::a, self::UnusedEnum::b];
+  static const field self::UnusedEnum a = const self::UnusedEnum::•(0, "UnusedEnum.a");
+  static const field self::UnusedEnum b = const self::UnusedEnum::•(1, "UnusedEnum.b");
+  const constructor •(core::int index, core::String _name) → self::UnusedEnum
+    : self::UnusedEnum::index = index, self::UnusedEnum::_name = _name, super core::Object::•()
+    ;
+  method toString() → core::String
+    return this.{self::UnusedEnum::_name};
+}
+class UsedEnum extends core::Object /*isEnum*/  {
+  final field core::int index;
+  final field core::String _name;
+  static const field core::List<self::UsedEnum> values = const <self::UsedEnum>[self::UsedEnum::unusedValue, self::UsedEnum::usedValue];
+  static const field self::UsedEnum unusedValue = const self::UsedEnum::•(0, "UsedEnum.unusedValue");
+  static const field self::UsedEnum usedValue = const self::UsedEnum::•(1, "UsedEnum.usedValue");
+  const constructor •(core::int index, core::String _name) → self::UsedEnum
+    : self::UsedEnum::index = index, self::UsedEnum::_name = _name, super core::Object::•()
+    ;
+  method toString() → core::String
+    return this.{self::UsedEnum::_name};
+}
+class UnusedInterface extends core::Object {
+  field core::int? usedInterfaceField;
+  constructor •(core::int? usedInterfaceField) → self::UnusedInterface
+    ;
+}
+class UsedClass extends core::Object implements self::UnusedInterface {
+  field core::int? unusedField;
+  field core::int? usedField;
+  field core::int? usedInterfaceField;
+  synthetic constructor •() → self::UsedClass
+    ;
+}
+class UnusedClass extends core::Object {
+  synthetic constructor •() → self::UnusedClass
+    ;
+}
+static method usedMethod(self::UnusedInterface c) → dynamic
+  ;
+static method unusedMethod() → dynamic
+  ;
+static method main() → dynamic
+  ;
+
+library /*isNonNullableByDefault*/;
+import self as self2;
+import "dart:core" as core;
+
+class ConstEnum extends core::Object /*isEnum*/  {
+  final field core::int index;
+  final field core::String _name;
+  static const field core::List<self2::ConstEnum> values = #C4;
+  static const field self2::ConstEnum value = #C3;
+  const constructor •(core::int index, core::String _name) → self2::ConstEnum
+    : self2::ConstEnum::index = index, self2::ConstEnum::_name = _name, super core::Object::•()
+    ;
+  method toString() → core::String
+    return this.{self2::ConstEnum::_name};
+}
+class ConstClass extends core::Object {
+  synthetic constructor •() → self2::ConstClass
+    ;
+  method method(self2::ConstEnum e) → core::int
+    ;
+}
+
+constants  {
+  #C1 = 0
+  #C2 = "ConstEnum.value"
+  #C3 = self2::ConstEnum {index:#C1, _name:#C2}
+  #C4 = <self2::ConstEnum*>[#C3]
+}
+
+Extra constant evaluation status:
+Evaluated: ListLiteral @ org-dartlang-testcase:///main.dart:7:6 -> ListConstant(const <UnusedEnum*>[const UnusedEnum{UnusedEnum.index: 0, UnusedEnum._name: "UnusedEnum.a"}, const UnusedEnum{UnusedEnum.index: 1, UnusedEnum._name: "UnusedEnum.b"}])
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///main.dart:7:19 -> InstanceConstant(const UnusedEnum{UnusedEnum.index: 0, UnusedEnum._name: "UnusedEnum.a"})
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///main.dart:7:22 -> InstanceConstant(const UnusedEnum{UnusedEnum.index: 1, UnusedEnum._name: "UnusedEnum.b"})
+Evaluated: ListLiteral @ org-dartlang-testcase:///main.dart:8:6 -> ListConstant(const <UsedEnum*>[const UsedEnum{UsedEnum.index: 0, UsedEnum._name: "UsedEnum.unusedValue"}, const UsedEnum{UsedEnum.index: 1, UsedEnum._name: "UsedEnum.usedValue"}])
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///main.dart:9:3 -> InstanceConstant(const UsedEnum{UsedEnum.index: 0, UsedEnum._name: "UsedEnum.unusedValue"})
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///main.dart:10:3 -> InstanceConstant(const UsedEnum{UsedEnum.index: 1, UsedEnum._name: "UsedEnum.usedValue"})
+Extra constant evaluation: evaluated: 18, effectively constant: 6
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///main_lib.dart:
+- ConstEnum. (from org-dartlang-testcase:///main_lib.dart:5:6)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/aot/tree_shake/main.dart.weak.transformed.expect b/pkg/front_end/testcases/aot/tree_shake/main.dart.weak.transformed.expect
new file mode 100644
index 0000000..80c0d6a
--- /dev/null
+++ b/pkg/front_end/testcases/aot/tree_shake/main.dart.weak.transformed.expect
@@ -0,0 +1,69 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "main_lib.dart" as mai;
+import "dart:_internal" as _in;
+
+import "org-dartlang-testcase:///main_lib.dart";
+
+abstract class UnusedEnum extends core::Object {
+}
+class UsedEnum extends core::Object /*isEnum*/  {
+  final field core::int index;
+  final field core::String _name;
+  method toString() → core::String
+    return this.{self::UsedEnum::_name};
+}
+abstract class UnusedInterface extends core::Object {
+  abstract get /*isLegacy*/ usedInterfaceField() → core::int?;
+  abstract set /*isLegacy*/ usedInterfaceField(core::int? value) → void;
+}
+class UsedClass extends core::Object implements self::UnusedInterface {
+  field core::int? usedField = null;
+  field core::int? usedInterfaceField = null;
+  synthetic constructor •() → self::UsedClass
+    : super core::Object::•()
+    ;
+}
+static method usedMethod(self::UnusedInterface c) → dynamic {
+  c.{self::UnusedInterface::usedInterfaceField} = c.{self::UnusedInterface::usedInterfaceField};
+}
+static method main() → dynamic {
+  self::usedMethod(let final self::UsedClass #t1 = new self::UsedClass::•() in block {
+    #t1.{self::UsedClass::usedField};
+  } =>#t1);
+  #C3;
+  core::List<self::UnusedEnum> list = core::_GrowableList::•<self::UnusedEnum>(0);
+  if(list.{core::Iterable::isNotEmpty}) {
+    new mai::ConstClass::•().{mai::ConstClass::method}(_in::unsafeCast<mai::ConstEnum>(_in::unsafeCast<dynamic>(null)));
+  }
+}
+
+library /*isNonNullableByDefault*/;
+import self as mai;
+import "dart:core" as core;
+
+abstract class ConstEnum extends core::Object {
+  abstract get /*isLegacy*/ index() → core::int;
+}
+class ConstClass extends core::Object {
+  synthetic constructor •() → mai::ConstClass
+    : super core::Object::•()
+    ;
+  method method(mai::ConstEnum e) → core::int
+    return e.{mai::ConstEnum::index};
+}
+
+constants  {
+  #C1 = 1
+  #C2 = "UsedEnum.usedValue"
+  #C3 = self::UsedEnum {index:#C1, _name:#C2}
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///main_lib.dart:
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
+
+org-dartlang-testcase:///main.dart:
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/aot/tree_shake/main_lib.dart b/pkg/front_end/testcases/aot/tree_shake/main_lib.dart
new file mode 100644
index 0000000..bc873dc
--- /dev/null
+++ b/pkg/front_end/testcases/aot/tree_shake/main_lib.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+enum ConstEnum { value }
+
+class ConstClass {
+  int method(ConstEnum e) => e.index;
+}
diff --git a/pkg/front_end/testcases/aot/tree_shake/test.options b/pkg/front_end/testcases/aot/tree_shake/test.options
new file mode 100644
index 0000000..bfe6dc8
--- /dev/null
+++ b/pkg/front_end/testcases/aot/tree_shake/test.options
@@ -0,0 +1 @@
+main_lib.dart
\ No newline at end of file
diff --git a/pkg/front_end/testcases/aot/tree_shake_field_from_lib/main.dart b/pkg/front_end/testcases/aot/tree_shake_field_from_lib/main.dart
new file mode 100644
index 0000000..53ab22e
--- /dev/null
+++ b/pkg/front_end/testcases/aot/tree_shake_field_from_lib/main.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. 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';
+
+class Class implements Interface {
+  int? field1;
+  int? field2;
+  int? field3;
+}
+
+void method(Interface i) {
+  i.field2 = i.field1;
+  i.field3 = i.field3;
+}
+
+main() {
+  method(new Class());
+}
diff --git a/pkg/front_end/testcases/aot/tree_shake_field_from_lib/main.dart.strong.expect b/pkg/front_end/testcases/aot/tree_shake_field_from_lib/main.dart.strong.expect
new file mode 100644
index 0000000..fce2045
--- /dev/null
+++ b/pkg/front_end/testcases/aot/tree_shake_field_from_lib/main.dart.strong.expect
@@ -0,0 +1,35 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "main_lib.dart" as mai;
+
+import "org-dartlang-testcase:///main_lib.dart";
+
+class Class extends core::Object implements mai::Interface {
+  field core::int? field1 = null;
+  field core::int? field2 = null;
+  field core::int? field3 = null;
+  synthetic constructor •() → self::Class
+    : super core::Object::•()
+    ;
+}
+static method method(mai::Interface i) → void {
+  i.{mai::Interface::field2} = i.{mai::Interface::field1};
+  i.{mai::Interface::field3} = i.{mai::Interface::field3};
+}
+static method main() → dynamic {
+  self::method(new self::Class::•());
+}
+
+library /*isNonNullableByDefault*/;
+import self as mai;
+import "dart:core" as core;
+
+class Interface extends core::Object {
+  field core::int? field1 = null;
+  field core::int? field2 = null;
+  field core::int? field3 = null;
+  synthetic constructor •() → mai::Interface
+    : super core::Object::•()
+    ;
+}
diff --git a/pkg/front_end/testcases/aot/tree_shake_field_from_lib/main.dart.strong.transformed.expect b/pkg/front_end/testcases/aot/tree_shake_field_from_lib/main.dart.strong.transformed.expect
new file mode 100644
index 0000000..9a18bdf
--- /dev/null
+++ b/pkg/front_end/testcases/aot/tree_shake_field_from_lib/main.dart.strong.transformed.expect
@@ -0,0 +1,33 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "main_lib.dart" as mai;
+
+import "org-dartlang-testcase:///main_lib.dart";
+
+class Class extends core::Object implements mai::Interface {
+  field core::int? field1 = null;
+  field core::int? field3 = null;
+  synthetic constructor •() → self::Class
+    : super core::Object::•()
+    ;
+  set /*isLegacy*/ field2(core::int? value) → void;
+}
+static method method(mai::Interface i) → void {
+  i.{mai::Interface::field2} = i.{mai::Interface::field1};
+  i.{mai::Interface::field3} = i.{mai::Interface::field3};
+}
+static method main() → dynamic {
+  self::method(new self::Class::•());
+}
+
+library /*isNonNullableByDefault*/;
+import self as mai;
+import "dart:core" as core;
+
+abstract class Interface extends core::Object {
+  abstract get /*isLegacy*/ field1() → core::int?;
+  abstract set /*isLegacy*/ field2(core::int? value) → void;
+  abstract get /*isLegacy*/ field3() → core::int?;
+  abstract set /*isLegacy*/ field3(core::int? value) → void;
+}
diff --git a/pkg/front_end/testcases/aot/tree_shake_field_from_lib/main.dart.textual_outline.expect b/pkg/front_end/testcases/aot/tree_shake_field_from_lib/main.dart.textual_outline.expect
new file mode 100644
index 0000000..433a1aa
--- /dev/null
+++ b/pkg/front_end/testcases/aot/tree_shake_field_from_lib/main.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+import 'main_lib.dart';
+
+class Class implements Interface {
+  int? field1;
+  int? field2;
+  int? field3;
+}
+
+void method(Interface i) {}
+main() {}
diff --git a/pkg/front_end/testcases/aot/tree_shake_field_from_lib/main.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/aot/tree_shake_field_from_lib/main.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..60b9b0d
--- /dev/null
+++ b/pkg/front_end/testcases/aot/tree_shake_field_from_lib/main.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+import 'main_lib.dart';
+
+class Class implements Interface {
+  int? field1;
+  int? field2;
+  int? field3;
+}
+
+main() {}
+void method(Interface i) {}
diff --git a/pkg/front_end/testcases/aot/tree_shake_field_from_lib/main.dart.weak.expect b/pkg/front_end/testcases/aot/tree_shake_field_from_lib/main.dart.weak.expect
new file mode 100644
index 0000000..fce2045
--- /dev/null
+++ b/pkg/front_end/testcases/aot/tree_shake_field_from_lib/main.dart.weak.expect
@@ -0,0 +1,35 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "main_lib.dart" as mai;
+
+import "org-dartlang-testcase:///main_lib.dart";
+
+class Class extends core::Object implements mai::Interface {
+  field core::int? field1 = null;
+  field core::int? field2 = null;
+  field core::int? field3 = null;
+  synthetic constructor •() → self::Class
+    : super core::Object::•()
+    ;
+}
+static method method(mai::Interface i) → void {
+  i.{mai::Interface::field2} = i.{mai::Interface::field1};
+  i.{mai::Interface::field3} = i.{mai::Interface::field3};
+}
+static method main() → dynamic {
+  self::method(new self::Class::•());
+}
+
+library /*isNonNullableByDefault*/;
+import self as mai;
+import "dart:core" as core;
+
+class Interface extends core::Object {
+  field core::int? field1 = null;
+  field core::int? field2 = null;
+  field core::int? field3 = null;
+  synthetic constructor •() → mai::Interface
+    : super core::Object::•()
+    ;
+}
diff --git a/pkg/front_end/testcases/aot/tree_shake_field_from_lib/main.dart.weak.outline.expect b/pkg/front_end/testcases/aot/tree_shake_field_from_lib/main.dart.weak.outline.expect
new file mode 100644
index 0000000..7018a21
--- /dev/null
+++ b/pkg/front_end/testcases/aot/tree_shake_field_from_lib/main.dart.weak.outline.expect
@@ -0,0 +1,30 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "main_lib.dart" as mai;
+
+import "org-dartlang-testcase:///main_lib.dart";
+
+class Class extends core::Object implements mai::Interface {
+  field core::int? field1;
+  field core::int? field2;
+  field core::int? field3;
+  synthetic constructor •() → self::Class
+    ;
+}
+static method method(mai::Interface i) → void
+  ;
+static method main() → dynamic
+  ;
+
+library /*isNonNullableByDefault*/;
+import self as mai;
+import "dart:core" as core;
+
+class Interface extends core::Object {
+  field core::int? field1;
+  field core::int? field2;
+  field core::int? field3;
+  synthetic constructor •() → mai::Interface
+    ;
+}
diff --git a/pkg/front_end/testcases/aot/tree_shake_field_from_lib/main.dart.weak.transformed.expect b/pkg/front_end/testcases/aot/tree_shake_field_from_lib/main.dart.weak.transformed.expect
new file mode 100644
index 0000000..9a18bdf
--- /dev/null
+++ b/pkg/front_end/testcases/aot/tree_shake_field_from_lib/main.dart.weak.transformed.expect
@@ -0,0 +1,33 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "main_lib.dart" as mai;
+
+import "org-dartlang-testcase:///main_lib.dart";
+
+class Class extends core::Object implements mai::Interface {
+  field core::int? field1 = null;
+  field core::int? field3 = null;
+  synthetic constructor •() → self::Class
+    : super core::Object::•()
+    ;
+  set /*isLegacy*/ field2(core::int? value) → void;
+}
+static method method(mai::Interface i) → void {
+  i.{mai::Interface::field2} = i.{mai::Interface::field1};
+  i.{mai::Interface::field3} = i.{mai::Interface::field3};
+}
+static method main() → dynamic {
+  self::method(new self::Class::•());
+}
+
+library /*isNonNullableByDefault*/;
+import self as mai;
+import "dart:core" as core;
+
+abstract class Interface extends core::Object {
+  abstract get /*isLegacy*/ field1() → core::int?;
+  abstract set /*isLegacy*/ field2(core::int? value) → void;
+  abstract get /*isLegacy*/ field3() → core::int?;
+  abstract set /*isLegacy*/ field3(core::int? value) → void;
+}
diff --git a/pkg/front_end/testcases/aot/tree_shake_field_from_lib/main_lib.dart b/pkg/front_end/testcases/aot/tree_shake_field_from_lib/main_lib.dart
new file mode 100644
index 0000000..190ab1a
--- /dev/null
+++ b/pkg/front_end/testcases/aot/tree_shake_field_from_lib/main_lib.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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 Interface {
+  int? field1;
+  int? field2;
+  int? field3;
+}
diff --git a/pkg/front_end/testcases/aot/tree_shake_field_from_lib/test.options b/pkg/front_end/testcases/aot/tree_shake_field_from_lib/test.options
new file mode 100644
index 0000000..bfe6dc8
--- /dev/null
+++ b/pkg/front_end/testcases/aot/tree_shake_field_from_lib/test.options
@@ -0,0 +1 @@
+main_lib.dart
\ No newline at end of file
diff --git a/pkg/front_end/testcases/const_functions/const_functions_assert_statements.dart b/pkg/front_end/testcases/const_functions/const_functions_assert_statements.dart
new file mode 100644
index 0000000..de66c5b
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_assert_statements.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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 assert statements with const functions.
+
+import "package:expect/expect.dart";
+
+const var1 = fn();
+int fn() {
+  int x = 0;
+  assert(x == 0, "fail");
+  return x;
+}
+
+void main() {
+  Expect.equals(var1, 0);
+}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_assert_statements.dart.strong.expect b/pkg/front_end/testcases/const_functions/const_functions_assert_statements.dart.strong.expect
new file mode 100644
index 0000000..8fa0afb
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_assert_statements.dart.strong.expect
@@ -0,0 +1,20 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "package:expect/expect.dart" as exp;
+
+import "package:expect/expect.dart";
+
+static const field core::int var1 = #C1;
+static method fn() → core::int {
+  core::int x = 0;
+  assert(x.{core::num::==}(0), "fail");
+  return x;
+}
+static method main() → void {
+  exp::Expect::equals(#C1, 0);
+}
+
+constants  {
+  #C1 = 0
+}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_assert_statements.dart.strong.transformed.expect b/pkg/front_end/testcases/const_functions/const_functions_assert_statements.dart.strong.transformed.expect
new file mode 100644
index 0000000..8fa0afb
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_assert_statements.dart.strong.transformed.expect
@@ -0,0 +1,20 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "package:expect/expect.dart" as exp;
+
+import "package:expect/expect.dart";
+
+static const field core::int var1 = #C1;
+static method fn() → core::int {
+  core::int x = 0;
+  assert(x.{core::num::==}(0), "fail");
+  return x;
+}
+static method main() → void {
+  exp::Expect::equals(#C1, 0);
+}
+
+constants  {
+  #C1 = 0
+}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_assert_statements.dart.textual_outline.expect b/pkg/front_end/testcases/const_functions/const_functions_assert_statements.dart.textual_outline.expect
new file mode 100644
index 0000000..574b595
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_assert_statements.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+import "package:expect/expect.dart";
+
+const var1 = fn();
+int fn() {}
+void main() {}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_assert_statements.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/const_functions/const_functions_assert_statements.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..574b595
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_assert_statements.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+import "package:expect/expect.dart";
+
+const var1 = fn();
+int fn() {}
+void main() {}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_assert_statements.dart.weak.expect b/pkg/front_end/testcases/const_functions/const_functions_assert_statements.dart.weak.expect
new file mode 100644
index 0000000..8fa0afb
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_assert_statements.dart.weak.expect
@@ -0,0 +1,20 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "package:expect/expect.dart" as exp;
+
+import "package:expect/expect.dart";
+
+static const field core::int var1 = #C1;
+static method fn() → core::int {
+  core::int x = 0;
+  assert(x.{core::num::==}(0), "fail");
+  return x;
+}
+static method main() → void {
+  exp::Expect::equals(#C1, 0);
+}
+
+constants  {
+  #C1 = 0
+}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_assert_statements.dart.weak.outline.expect b/pkg/front_end/testcases/const_functions/const_functions_assert_statements.dart.weak.outline.expect
new file mode 100644
index 0000000..786a90f
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_assert_statements.dart.weak.outline.expect
@@ -0,0 +1,11 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+import "package:expect/expect.dart";
+
+static const field core::int var1 = self::fn();
+static method fn() → core::int
+  ;
+static method main() → void
+  ;
diff --git a/pkg/front_end/testcases/const_functions/const_functions_assert_statements.dart.weak.transformed.expect b/pkg/front_end/testcases/const_functions/const_functions_assert_statements.dart.weak.transformed.expect
new file mode 100644
index 0000000..8fa0afb
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_assert_statements.dart.weak.transformed.expect
@@ -0,0 +1,20 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "package:expect/expect.dart" as exp;
+
+import "package:expect/expect.dart";
+
+static const field core::int var1 = #C1;
+static method fn() → core::int {
+  core::int x = 0;
+  assert(x.{core::num::==}(0), "fail");
+  return x;
+}
+static method main() → void {
+  exp::Expect::equals(#C1, 0);
+}
+
+constants  {
+  #C1 = 0
+}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_block.dart b/pkg/front_end/testcases/const_functions/const_functions_block.dart
new file mode 100644
index 0000000..067a7c4
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_block.dart
@@ -0,0 +1,43 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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 blocks and scope with const functions.
+
+import "package:expect/expect.dart";
+
+void blockTest() {
+  int x() => 1;
+  const i = x();
+  Expect.equals(i, 1);
+  {
+    int x() => 2;
+    const y = x();
+    Expect.equals(y, 2);
+    {
+      int x() => 3;
+      const y = x();
+      Expect.equals(y, 3);
+    }
+  }
+  const z = x();
+  Expect.equals(z, 1);
+}
+
+void blockTest1() {
+  int x() {
+    int z = 3;
+    {
+      int z = 4;
+    }
+    return z;
+  }
+
+  const i = x();
+  Expect.equals(i, 3);
+}
+
+void main() {
+  blockTest();
+  blockTest1();
+}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_block.dart.strong.expect b/pkg/front_end/testcases/const_functions/const_functions_block.dart.strong.expect
new file mode 100644
index 0000000..ee6a074
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_block.dart.strong.expect
@@ -0,0 +1,43 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "package:expect/expect.dart" as exp;
+
+import "package:expect/expect.dart";
+
+static method blockTest() → void {
+  function x() → core::int
+    return 1;
+  exp::Expect::equals(#C1, 1);
+  {
+    function x() → core::int
+      return 2;
+    exp::Expect::equals(#C2, 2);
+    {
+      function x() → core::int
+        return 3;
+      exp::Expect::equals(#C3, 3);
+    }
+  }
+  exp::Expect::equals(#C1, 1);
+}
+static method blockTest1() → void {
+  function x() → core::int {
+    core::int z = 3;
+    {
+      core::int z = 4;
+    }
+    return z;
+  }
+  exp::Expect::equals(#C3, 3);
+}
+static method main() → void {
+  self::blockTest();
+  self::blockTest1();
+}
+
+constants  {
+  #C1 = 1
+  #C2 = 2
+  #C3 = 3
+}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_block.dart.strong.transformed.expect b/pkg/front_end/testcases/const_functions/const_functions_block.dart.strong.transformed.expect
new file mode 100644
index 0000000..ee6a074
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_block.dart.strong.transformed.expect
@@ -0,0 +1,43 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "package:expect/expect.dart" as exp;
+
+import "package:expect/expect.dart";
+
+static method blockTest() → void {
+  function x() → core::int
+    return 1;
+  exp::Expect::equals(#C1, 1);
+  {
+    function x() → core::int
+      return 2;
+    exp::Expect::equals(#C2, 2);
+    {
+      function x() → core::int
+        return 3;
+      exp::Expect::equals(#C3, 3);
+    }
+  }
+  exp::Expect::equals(#C1, 1);
+}
+static method blockTest1() → void {
+  function x() → core::int {
+    core::int z = 3;
+    {
+      core::int z = 4;
+    }
+    return z;
+  }
+  exp::Expect::equals(#C3, 3);
+}
+static method main() → void {
+  self::blockTest();
+  self::blockTest1();
+}
+
+constants  {
+  #C1 = 1
+  #C2 = 2
+  #C3 = 3
+}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_block.dart.textual_outline.expect b/pkg/front_end/testcases/const_functions/const_functions_block.dart.textual_outline.expect
new file mode 100644
index 0000000..af17fc7
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_block.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+import "package:expect/expect.dart";
+
+void blockTest() {}
+void blockTest1() {}
+void main() {}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_block.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/const_functions/const_functions_block.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..af17fc7
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_block.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+import "package:expect/expect.dart";
+
+void blockTest() {}
+void blockTest1() {}
+void main() {}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_block.dart.weak.expect b/pkg/front_end/testcases/const_functions/const_functions_block.dart.weak.expect
new file mode 100644
index 0000000..ee6a074
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_block.dart.weak.expect
@@ -0,0 +1,43 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "package:expect/expect.dart" as exp;
+
+import "package:expect/expect.dart";
+
+static method blockTest() → void {
+  function x() → core::int
+    return 1;
+  exp::Expect::equals(#C1, 1);
+  {
+    function x() → core::int
+      return 2;
+    exp::Expect::equals(#C2, 2);
+    {
+      function x() → core::int
+        return 3;
+      exp::Expect::equals(#C3, 3);
+    }
+  }
+  exp::Expect::equals(#C1, 1);
+}
+static method blockTest1() → void {
+  function x() → core::int {
+    core::int z = 3;
+    {
+      core::int z = 4;
+    }
+    return z;
+  }
+  exp::Expect::equals(#C3, 3);
+}
+static method main() → void {
+  self::blockTest();
+  self::blockTest1();
+}
+
+constants  {
+  #C1 = 1
+  #C2 = 2
+  #C3 = 3
+}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_block.dart.weak.outline.expect b/pkg/front_end/testcases/const_functions/const_functions_block.dart.weak.outline.expect
new file mode 100644
index 0000000..0e98e4e
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_block.dart.weak.outline.expect
@@ -0,0 +1,11 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+
+import "package:expect/expect.dart";
+
+static method blockTest() → void
+  ;
+static method blockTest1() → void
+  ;
+static method main() → void
+  ;
diff --git a/pkg/front_end/testcases/const_functions/const_functions_block.dart.weak.transformed.expect b/pkg/front_end/testcases/const_functions/const_functions_block.dart.weak.transformed.expect
new file mode 100644
index 0000000..ee6a074
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_block.dart.weak.transformed.expect
@@ -0,0 +1,43 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "package:expect/expect.dart" as exp;
+
+import "package:expect/expect.dart";
+
+static method blockTest() → void {
+  function x() → core::int
+    return 1;
+  exp::Expect::equals(#C1, 1);
+  {
+    function x() → core::int
+      return 2;
+    exp::Expect::equals(#C2, 2);
+    {
+      function x() → core::int
+        return 3;
+      exp::Expect::equals(#C3, 3);
+    }
+  }
+  exp::Expect::equals(#C1, 1);
+}
+static method blockTest1() → void {
+  function x() → core::int {
+    core::int z = 3;
+    {
+      core::int z = 4;
+    }
+    return z;
+  }
+  exp::Expect::equals(#C3, 3);
+}
+static method main() → void {
+  self::blockTest();
+  self::blockTest1();
+}
+
+constants  {
+  #C1 = 1
+  #C2 = 2
+  #C3 = 3
+}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_const_factory.dart b/pkg/front_end/testcases/const_functions/const_functions_const_factory.dart
new file mode 100644
index 0000000..08f2b76
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_const_factory.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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 const factories with const functions.
+
+import "package:expect/expect.dart";
+
+const printConst = MessageType.parse("print");
+
+class MessageType {
+  static const print = MessageType._('print');
+
+  static const skip = MessageType._('skip');
+
+  final String name;
+
+  const factory MessageType.parse(String name) {
+    if (name == 'print') {
+      return MessageType.print;
+    }
+    return MessageType.skip;
+  }
+
+  const MessageType._(this.name);
+}
+
+void main() {
+  Expect.equals(printConst, MessageType.print);
+}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_const_factory.dart.strong.expect b/pkg/front_end/testcases/const_functions/const_functions_const_factory.dart.strong.expect
new file mode 100644
index 0000000..c9674e9
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_const_factory.dart.strong.expect
@@ -0,0 +1,38 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "package:expect/expect.dart" as exp;
+
+import "package:expect/expect.dart";
+
+class MessageType extends core::Object /*hasConstConstructor*/  {
+  static const field self::MessageType print = #C2;
+  static const field self::MessageType skip = #C4;
+  final field core::String name;
+  const constructor _(core::String name) → self::MessageType
+    : self::MessageType::name = name, super core::Object::•()
+    ;
+  static factory parse(core::String name) → self::MessageType {
+    if(name.{core::String::==}("print")) {
+      return #C2;
+    }
+    return #C4;
+  }
+}
+static const field self::MessageType printConst = #C2;
+static method main() → void {
+  exp::Expect::equals(#C2, #C2);
+}
+
+constants  {
+  #C1 = "print"
+  #C2 = self::MessageType {name:#C1}
+  #C3 = "skip"
+  #C4 = self::MessageType {name:#C3}
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///const_functions_const_factory.dart:
+- MessageType._ (from org-dartlang-testcase:///const_functions_const_factory.dart:25:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/const_functions/const_functions_const_factory.dart.strong.transformed.expect b/pkg/front_end/testcases/const_functions/const_functions_const_factory.dart.strong.transformed.expect
new file mode 100644
index 0000000..c9674e9
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_const_factory.dart.strong.transformed.expect
@@ -0,0 +1,38 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "package:expect/expect.dart" as exp;
+
+import "package:expect/expect.dart";
+
+class MessageType extends core::Object /*hasConstConstructor*/  {
+  static const field self::MessageType print = #C2;
+  static const field self::MessageType skip = #C4;
+  final field core::String name;
+  const constructor _(core::String name) → self::MessageType
+    : self::MessageType::name = name, super core::Object::•()
+    ;
+  static factory parse(core::String name) → self::MessageType {
+    if(name.{core::String::==}("print")) {
+      return #C2;
+    }
+    return #C4;
+  }
+}
+static const field self::MessageType printConst = #C2;
+static method main() → void {
+  exp::Expect::equals(#C2, #C2);
+}
+
+constants  {
+  #C1 = "print"
+  #C2 = self::MessageType {name:#C1}
+  #C3 = "skip"
+  #C4 = self::MessageType {name:#C3}
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///const_functions_const_factory.dart:
+- MessageType._ (from org-dartlang-testcase:///const_functions_const_factory.dart:25:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/const_functions/const_functions_const_factory.dart.textual_outline.expect b/pkg/front_end/testcases/const_functions/const_functions_const_factory.dart.textual_outline.expect
new file mode 100644
index 0000000..5caeeca
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_const_factory.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+import "package:expect/expect.dart";
+const printConst = MessageType.parse("print");
+class MessageType {
+  static const print = MessageType._('print');
+  static const skip = MessageType._('skip');
+  final String name;
+  const factory MessageType.parse(String name) {}
+  const MessageType._(this.name);
+}
+void main() {}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_const_factory.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/const_functions/const_functions_const_factory.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..cb1859d
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_const_factory.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+import "package:expect/expect.dart";
+
+class MessageType {
+  const MessageType._(this.name);
+  const factory MessageType.parse(String name) {}
+  final String name;
+  static const print = MessageType._('print');
+  static const skip = MessageType._('skip');
+}
+
+const printConst = MessageType.parse("print");
+void main() {}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_const_factory.dart.weak.expect b/pkg/front_end/testcases/const_functions/const_functions_const_factory.dart.weak.expect
new file mode 100644
index 0000000..c9674e9
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_const_factory.dart.weak.expect
@@ -0,0 +1,38 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "package:expect/expect.dart" as exp;
+
+import "package:expect/expect.dart";
+
+class MessageType extends core::Object /*hasConstConstructor*/  {
+  static const field self::MessageType print = #C2;
+  static const field self::MessageType skip = #C4;
+  final field core::String name;
+  const constructor _(core::String name) → self::MessageType
+    : self::MessageType::name = name, super core::Object::•()
+    ;
+  static factory parse(core::String name) → self::MessageType {
+    if(name.{core::String::==}("print")) {
+      return #C2;
+    }
+    return #C4;
+  }
+}
+static const field self::MessageType printConst = #C2;
+static method main() → void {
+  exp::Expect::equals(#C2, #C2);
+}
+
+constants  {
+  #C1 = "print"
+  #C2 = self::MessageType {name:#C1}
+  #C3 = "skip"
+  #C4 = self::MessageType {name:#C3}
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///const_functions_const_factory.dart:
+- MessageType._ (from org-dartlang-testcase:///const_functions_const_factory.dart:25:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/const_functions/const_functions_const_factory.dart.weak.outline.expect b/pkg/front_end/testcases/const_functions/const_functions_const_factory.dart.weak.outline.expect
new file mode 100644
index 0000000..fe4b863
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_const_factory.dart.weak.outline.expect
@@ -0,0 +1,25 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+import "package:expect/expect.dart";
+
+class MessageType extends core::Object /*hasConstConstructor*/  {
+  static const field self::MessageType print = const self::MessageType::_("print");
+  static const field self::MessageType skip = const self::MessageType::_("skip");
+  final field core::String name;
+  const constructor _(core::String name) → self::MessageType
+    : self::MessageType::name = name, super core::Object::•()
+    ;
+  static const factory parse(core::String name) → self::MessageType
+    ;
+}
+static const field self::MessageType printConst = const self::MessageType::parse("print");
+static method main() → void
+  ;
+
+
+Extra constant evaluation status:
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///const_functions_const_factory.dart:12:36 -> InstanceConstant(const MessageType{MessageType.name: "print"})
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///const_functions_const_factory.dart:14:35 -> InstanceConstant(const MessageType{MessageType.name: "skip"})
+Extra constant evaluation: evaluated: 4, effectively constant: 2
diff --git a/pkg/front_end/testcases/const_functions/const_functions_const_factory.dart.weak.transformed.expect b/pkg/front_end/testcases/const_functions/const_functions_const_factory.dart.weak.transformed.expect
new file mode 100644
index 0000000..c9674e9
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_const_factory.dart.weak.transformed.expect
@@ -0,0 +1,38 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "package:expect/expect.dart" as exp;
+
+import "package:expect/expect.dart";
+
+class MessageType extends core::Object /*hasConstConstructor*/  {
+  static const field self::MessageType print = #C2;
+  static const field self::MessageType skip = #C4;
+  final field core::String name;
+  const constructor _(core::String name) → self::MessageType
+    : self::MessageType::name = name, super core::Object::•()
+    ;
+  static factory parse(core::String name) → self::MessageType {
+    if(name.{core::String::==}("print")) {
+      return #C2;
+    }
+    return #C4;
+  }
+}
+static const field self::MessageType printConst = #C2;
+static method main() → void {
+  exp::Expect::equals(#C2, #C2);
+}
+
+constants  {
+  #C1 = "print"
+  #C2 = self::MessageType {name:#C1}
+  #C3 = "skip"
+  #C4 = self::MessageType {name:#C3}
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///const_functions_const_factory.dart:
+- MessageType._ (from org-dartlang-testcase:///const_functions_const_factory.dart:25:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/const_functions/const_functions_do_statements.dart b/pkg/front_end/testcases/const_functions/const_functions_do_statements.dart
new file mode 100644
index 0000000..f7f45b1
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_do_statements.dart
@@ -0,0 +1,46 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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 do-while statements for const functions.
+
+import "package:expect/expect.dart";
+
+const var1 = fn();
+int fn() {
+  int x = 0;
+  do {
+    x++;
+  } while (x < 2);
+  return x;
+}
+
+const var2 = fn2(2);
+const var3 = fn2(10);
+int fn2(int a) {
+  int x = 0, b = 0;
+  do {
+    if (x > 5) break;
+    x += a;
+    b++;
+  } while (b < 2);
+  return x;
+}
+
+const var4 = fn3();
+int fn3() {
+  int x = 0, b = 0;
+  do {
+    x += 1;
+    if (x % 2 == 1) continue;
+    b += x;
+  } while (x < 5);
+  return b;
+}
+
+void main() {
+  Expect.equals(var1, 2);
+  Expect.equals(var2, 4);
+  Expect.equals(var3, 10);
+  Expect.equals(var4, 6);
+}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_do_statements.dart.strong.expect b/pkg/front_end/testcases/const_functions/const_functions_do_statements.dart.strong.expect
new file mode 100644
index 0000000..1737f7b
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_do_statements.dart.strong.expect
@@ -0,0 +1,59 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "package:expect/expect.dart" as exp;
+
+import "package:expect/expect.dart";
+
+static const field core::int var1 = #C1;
+static const field core::int var2 = #C2;
+static const field core::int var3 = #C3;
+static const field core::int var4 = #C4;
+static method fn() → core::int {
+  core::int x = 0;
+  do {
+    x = x.{core::num::+}(1);
+  }
+  while (x.{core::num::<}(2))
+  return x;
+}
+static method fn2(core::int a) → core::int {
+  core::int x = 0;
+  core::int b = 0;
+  #L1:
+  do {
+    if(x.{core::num::>}(5))
+      break #L1;
+    x = x.{core::num::+}(a);
+    b = b.{core::num::+}(1);
+  }
+  while (b.{core::num::<}(2))
+  return x;
+}
+static method fn3() → core::int {
+  core::int x = 0;
+  core::int b = 0;
+  do
+    #L2:
+    {
+      x = x.{core::num::+}(1);
+      if(x.{core::num::%}(2).{core::num::==}(1))
+        break #L2;
+      b = b.{core::num::+}(x);
+    }
+  while (x.{core::num::<}(5))
+  return b;
+}
+static method main() → void {
+  exp::Expect::equals(#C1, 2);
+  exp::Expect::equals(#C2, 4);
+  exp::Expect::equals(#C3, 10);
+  exp::Expect::equals(#C4, 6);
+}
+
+constants  {
+  #C1 = 2
+  #C2 = 4
+  #C3 = 10
+  #C4 = 6
+}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_do_statements.dart.strong.transformed.expect b/pkg/front_end/testcases/const_functions/const_functions_do_statements.dart.strong.transformed.expect
new file mode 100644
index 0000000..1737f7b
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_do_statements.dart.strong.transformed.expect
@@ -0,0 +1,59 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "package:expect/expect.dart" as exp;
+
+import "package:expect/expect.dart";
+
+static const field core::int var1 = #C1;
+static const field core::int var2 = #C2;
+static const field core::int var3 = #C3;
+static const field core::int var4 = #C4;
+static method fn() → core::int {
+  core::int x = 0;
+  do {
+    x = x.{core::num::+}(1);
+  }
+  while (x.{core::num::<}(2))
+  return x;
+}
+static method fn2(core::int a) → core::int {
+  core::int x = 0;
+  core::int b = 0;
+  #L1:
+  do {
+    if(x.{core::num::>}(5))
+      break #L1;
+    x = x.{core::num::+}(a);
+    b = b.{core::num::+}(1);
+  }
+  while (b.{core::num::<}(2))
+  return x;
+}
+static method fn3() → core::int {
+  core::int x = 0;
+  core::int b = 0;
+  do
+    #L2:
+    {
+      x = x.{core::num::+}(1);
+      if(x.{core::num::%}(2).{core::num::==}(1))
+        break #L2;
+      b = b.{core::num::+}(x);
+    }
+  while (x.{core::num::<}(5))
+  return b;
+}
+static method main() → void {
+  exp::Expect::equals(#C1, 2);
+  exp::Expect::equals(#C2, 4);
+  exp::Expect::equals(#C3, 10);
+  exp::Expect::equals(#C4, 6);
+}
+
+constants  {
+  #C1 = 2
+  #C2 = 4
+  #C3 = 10
+  #C4 = 6
+}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_do_statements.dart.textual_outline.expect b/pkg/front_end/testcases/const_functions/const_functions_do_statements.dart.textual_outline.expect
new file mode 100644
index 0000000..4f0d977
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_do_statements.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+import "package:expect/expect.dart";
+
+const var1 = fn();
+int fn() {}
+const var2 = fn2(2);
+const var3 = fn2(10);
+int fn2(int a) {}
+const var4 = fn3();
+int fn3() {}
+void main() {}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_do_statements.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/const_functions/const_functions_do_statements.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..155303b
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_do_statements.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+import "package:expect/expect.dart";
+
+const var1 = fn();
+const var2 = fn2(2);
+const var3 = fn2(10);
+const var4 = fn3();
+int fn() {}
+int fn2(int a) {}
+int fn3() {}
+void main() {}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_do_statements.dart.weak.expect b/pkg/front_end/testcases/const_functions/const_functions_do_statements.dart.weak.expect
new file mode 100644
index 0000000..1737f7b
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_do_statements.dart.weak.expect
@@ -0,0 +1,59 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "package:expect/expect.dart" as exp;
+
+import "package:expect/expect.dart";
+
+static const field core::int var1 = #C1;
+static const field core::int var2 = #C2;
+static const field core::int var3 = #C3;
+static const field core::int var4 = #C4;
+static method fn() → core::int {
+  core::int x = 0;
+  do {
+    x = x.{core::num::+}(1);
+  }
+  while (x.{core::num::<}(2))
+  return x;
+}
+static method fn2(core::int a) → core::int {
+  core::int x = 0;
+  core::int b = 0;
+  #L1:
+  do {
+    if(x.{core::num::>}(5))
+      break #L1;
+    x = x.{core::num::+}(a);
+    b = b.{core::num::+}(1);
+  }
+  while (b.{core::num::<}(2))
+  return x;
+}
+static method fn3() → core::int {
+  core::int x = 0;
+  core::int b = 0;
+  do
+    #L2:
+    {
+      x = x.{core::num::+}(1);
+      if(x.{core::num::%}(2).{core::num::==}(1))
+        break #L2;
+      b = b.{core::num::+}(x);
+    }
+  while (x.{core::num::<}(5))
+  return b;
+}
+static method main() → void {
+  exp::Expect::equals(#C1, 2);
+  exp::Expect::equals(#C2, 4);
+  exp::Expect::equals(#C3, 10);
+  exp::Expect::equals(#C4, 6);
+}
+
+constants  {
+  #C1 = 2
+  #C2 = 4
+  #C3 = 10
+  #C4 = 6
+}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_do_statements.dart.weak.outline.expect b/pkg/front_end/testcases/const_functions/const_functions_do_statements.dart.weak.outline.expect
new file mode 100644
index 0000000..3c2ca31
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_do_statements.dart.weak.outline.expect
@@ -0,0 +1,18 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+import "package:expect/expect.dart";
+
+static const field core::int var1 = self::fn();
+static const field core::int var2 = self::fn2(2);
+static const field core::int var3 = self::fn2(10);
+static const field core::int var4 = self::fn3();
+static method fn() → core::int
+  ;
+static method fn2(core::int a) → core::int
+  ;
+static method fn3() → core::int
+  ;
+static method main() → void
+  ;
diff --git a/pkg/front_end/testcases/const_functions/const_functions_do_statements.dart.weak.transformed.expect b/pkg/front_end/testcases/const_functions/const_functions_do_statements.dart.weak.transformed.expect
new file mode 100644
index 0000000..1737f7b
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_do_statements.dart.weak.transformed.expect
@@ -0,0 +1,59 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "package:expect/expect.dart" as exp;
+
+import "package:expect/expect.dart";
+
+static const field core::int var1 = #C1;
+static const field core::int var2 = #C2;
+static const field core::int var3 = #C3;
+static const field core::int var4 = #C4;
+static method fn() → core::int {
+  core::int x = 0;
+  do {
+    x = x.{core::num::+}(1);
+  }
+  while (x.{core::num::<}(2))
+  return x;
+}
+static method fn2(core::int a) → core::int {
+  core::int x = 0;
+  core::int b = 0;
+  #L1:
+  do {
+    if(x.{core::num::>}(5))
+      break #L1;
+    x = x.{core::num::+}(a);
+    b = b.{core::num::+}(1);
+  }
+  while (b.{core::num::<}(2))
+  return x;
+}
+static method fn3() → core::int {
+  core::int x = 0;
+  core::int b = 0;
+  do
+    #L2:
+    {
+      x = x.{core::num::+}(1);
+      if(x.{core::num::%}(2).{core::num::==}(1))
+        break #L2;
+      b = b.{core::num::+}(x);
+    }
+  while (x.{core::num::<}(5))
+  return b;
+}
+static method main() → void {
+  exp::Expect::equals(#C1, 2);
+  exp::Expect::equals(#C2, 4);
+  exp::Expect::equals(#C3, 10);
+  exp::Expect::equals(#C4, 6);
+}
+
+constants  {
+  #C1 = 2
+  #C2 = 4
+  #C3 = 10
+  #C4 = 6
+}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_for_statements.dart b/pkg/front_end/testcases/const_functions/const_functions_for_statements.dart
new file mode 100644
index 0000000..6b365ed
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_for_statements.dart
@@ -0,0 +1,92 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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 for statements for const functions.
+
+import "package:expect/expect.dart";
+
+const var1 = fn(2);
+const var2 = fn(3);
+int fn(int a) {
+  int b = a;
+  for (int i = 0; i < 2; i++) {
+    b += a;
+  }
+  return b;
+}
+
+const var3 = fn1(2);
+const var4 = fn1(3);
+int fn1(int a) {
+  int b = a;
+  for (int i = 0;; i++) {
+    b *= 3;
+    if (b > 10) return b;
+  }
+}
+
+const var5 = fn2();
+int fn2() {
+  for (int i = 0, j = 2;; i += 2, j += 1) {
+    if (i + j > 10) {
+      return i + j;
+    }
+  }
+}
+
+const var6 = fnContinue();
+int fnContinue() {
+  int a = 0;
+  for (int i = 0; i < 5; i++) {
+    if (i % 2 == 1) continue;
+    a += i;
+  }
+  return a;
+}
+
+const var7 = fnBreak(2);
+const var8 = fnBreak(3);
+int fnBreak(int a) {
+  int b = a;
+  for (int i = 0; i < 2; i++) {
+    if (b == 2) break;
+    b += a;
+  }
+  return b;
+}
+
+const var9 = fnNestedFor();
+int fnNestedFor() {
+  int a = 0;
+  for (;;) {
+    for (;;) {
+      break;
+    }
+    return 1;
+  }
+}
+
+const var10 = fnBreakLabel();
+int fnBreakLabel() {
+  foo:
+  for (;;) {
+    for (;;) {
+      break foo;
+    }
+  }
+  return 3;
+}
+
+void main() {
+  Expect.equals(var1, 6);
+  Expect.equals(var2, 9);
+  Expect.equals(var3, 18);
+  Expect.equals(var4, 27);
+  Expect.equals(var5, 11);
+  Expect.equals(var6, 6);
+  Expect.equals(var7, 2);
+  Expect.equals(var8, 9);
+  Expect.equals(var9, 1);
+  Expect.equals(var10, 3);
+}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_for_statements.dart.strong.expect b/pkg/front_end/testcases/const_functions/const_functions_for_statements.dart.strong.expect
new file mode 100644
index 0000000..b8210ed
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_for_statements.dart.strong.expect
@@ -0,0 +1,102 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "package:expect/expect.dart" as exp;
+
+import "package:expect/expect.dart";
+
+static const field core::int var1 = #C1;
+static const field core::int var2 = #C2;
+static const field core::int var3 = #C3;
+static const field core::int var4 = #C4;
+static const field core::int var5 = #C5;
+static const field core::int var6 = #C1;
+static const field core::int var7 = #C6;
+static const field core::int var8 = #C2;
+static const field core::int var9 = #C7;
+static const field core::int var10 = #C8;
+static method fn(core::int a) → core::int {
+  core::int b = a;
+  for (core::int i = 0; i.{core::num::<}(2); i = i.{core::num::+}(1)) {
+    b = b.{core::num::+}(a);
+  }
+  return b;
+}
+static method fn1(core::int a) → core::int {
+  core::int b = a;
+  for (core::int i = 0; ; i = i.{core::num::+}(1)) {
+    b = b.{core::num::*}(3);
+    if(b.{core::num::>}(10))
+      return b;
+  }
+}
+static method fn2() → core::int {
+  for (core::int i = 0, core::int j = 2; ; i = i.{core::num::+}(2), j = j.{core::num::+}(1)) {
+    if(i.{core::num::+}(j).{core::num::>}(10)) {
+      return i.{core::num::+}(j);
+    }
+  }
+}
+static method fnContinue() → core::int {
+  core::int a = 0;
+  for (core::int i = 0; i.{core::num::<}(5); i = i.{core::num::+}(1))
+    #L1:
+    {
+      if(i.{core::num::%}(2).{core::num::==}(1))
+        break #L1;
+      a = a.{core::num::+}(i);
+    }
+  return a;
+}
+static method fnBreak(core::int a) → core::int {
+  core::int b = a;
+  #L2:
+  for (core::int i = 0; i.{core::num::<}(2); i = i.{core::num::+}(1)) {
+    if(b.{core::num::==}(2))
+      break #L2;
+    b = b.{core::num::+}(a);
+  }
+  return b;
+}
+static method fnNestedFor() → core::int {
+  core::int a = 0;
+  for (; ; ) {
+    #L3:
+    for (; ; ) {
+      break #L3;
+    }
+    return 1;
+  }
+}
+static method fnBreakLabel() → core::int {
+  #L4:
+  for (; ; ) {
+    for (; ; ) {
+      break #L4;
+    }
+  }
+  return 3;
+}
+static method main() → void {
+  exp::Expect::equals(#C1, 6);
+  exp::Expect::equals(#C2, 9);
+  exp::Expect::equals(#C3, 18);
+  exp::Expect::equals(#C4, 27);
+  exp::Expect::equals(#C5, 11);
+  exp::Expect::equals(#C1, 6);
+  exp::Expect::equals(#C6, 2);
+  exp::Expect::equals(#C2, 9);
+  exp::Expect::equals(#C7, 1);
+  exp::Expect::equals(#C8, 3);
+}
+
+constants  {
+  #C1 = 6
+  #C2 = 9
+  #C3 = 18
+  #C4 = 27
+  #C5 = 11
+  #C6 = 2
+  #C7 = 1
+  #C8 = 3
+}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_for_statements.dart.strong.transformed.expect b/pkg/front_end/testcases/const_functions/const_functions_for_statements.dart.strong.transformed.expect
new file mode 100644
index 0000000..b8210ed
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_for_statements.dart.strong.transformed.expect
@@ -0,0 +1,102 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "package:expect/expect.dart" as exp;
+
+import "package:expect/expect.dart";
+
+static const field core::int var1 = #C1;
+static const field core::int var2 = #C2;
+static const field core::int var3 = #C3;
+static const field core::int var4 = #C4;
+static const field core::int var5 = #C5;
+static const field core::int var6 = #C1;
+static const field core::int var7 = #C6;
+static const field core::int var8 = #C2;
+static const field core::int var9 = #C7;
+static const field core::int var10 = #C8;
+static method fn(core::int a) → core::int {
+  core::int b = a;
+  for (core::int i = 0; i.{core::num::<}(2); i = i.{core::num::+}(1)) {
+    b = b.{core::num::+}(a);
+  }
+  return b;
+}
+static method fn1(core::int a) → core::int {
+  core::int b = a;
+  for (core::int i = 0; ; i = i.{core::num::+}(1)) {
+    b = b.{core::num::*}(3);
+    if(b.{core::num::>}(10))
+      return b;
+  }
+}
+static method fn2() → core::int {
+  for (core::int i = 0, core::int j = 2; ; i = i.{core::num::+}(2), j = j.{core::num::+}(1)) {
+    if(i.{core::num::+}(j).{core::num::>}(10)) {
+      return i.{core::num::+}(j);
+    }
+  }
+}
+static method fnContinue() → core::int {
+  core::int a = 0;
+  for (core::int i = 0; i.{core::num::<}(5); i = i.{core::num::+}(1))
+    #L1:
+    {
+      if(i.{core::num::%}(2).{core::num::==}(1))
+        break #L1;
+      a = a.{core::num::+}(i);
+    }
+  return a;
+}
+static method fnBreak(core::int a) → core::int {
+  core::int b = a;
+  #L2:
+  for (core::int i = 0; i.{core::num::<}(2); i = i.{core::num::+}(1)) {
+    if(b.{core::num::==}(2))
+      break #L2;
+    b = b.{core::num::+}(a);
+  }
+  return b;
+}
+static method fnNestedFor() → core::int {
+  core::int a = 0;
+  for (; ; ) {
+    #L3:
+    for (; ; ) {
+      break #L3;
+    }
+    return 1;
+  }
+}
+static method fnBreakLabel() → core::int {
+  #L4:
+  for (; ; ) {
+    for (; ; ) {
+      break #L4;
+    }
+  }
+  return 3;
+}
+static method main() → void {
+  exp::Expect::equals(#C1, 6);
+  exp::Expect::equals(#C2, 9);
+  exp::Expect::equals(#C3, 18);
+  exp::Expect::equals(#C4, 27);
+  exp::Expect::equals(#C5, 11);
+  exp::Expect::equals(#C1, 6);
+  exp::Expect::equals(#C6, 2);
+  exp::Expect::equals(#C2, 9);
+  exp::Expect::equals(#C7, 1);
+  exp::Expect::equals(#C8, 3);
+}
+
+constants  {
+  #C1 = 6
+  #C2 = 9
+  #C3 = 18
+  #C4 = 27
+  #C5 = 11
+  #C6 = 2
+  #C7 = 1
+  #C8 = 3
+}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_for_statements.dart.textual_outline.expect b/pkg/front_end/testcases/const_functions/const_functions_for_statements.dart.textual_outline.expect
new file mode 100644
index 0000000..7c59b2e
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_for_statements.dart.textual_outline.expect
@@ -0,0 +1,20 @@
+import "package:expect/expect.dart";
+
+const var1 = fn(2);
+const var2 = fn(3);
+int fn(int a) {}
+const var3 = fn1(2);
+const var4 = fn1(3);
+int fn1(int a) {}
+const var5 = fn2();
+int fn2() {}
+const var6 = fnContinue();
+int fnContinue() {}
+const var7 = fnBreak(2);
+const var8 = fnBreak(3);
+int fnBreak(int a) {}
+const var9 = fnNestedFor();
+int fnNestedFor() {}
+const var10 = fnBreakLabel();
+int fnBreakLabel() {}
+void main() {}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_for_statements.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/const_functions/const_functions_for_statements.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8aa5055
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_for_statements.dart.textual_outline_modelled.expect
@@ -0,0 +1,20 @@
+import "package:expect/expect.dart";
+
+const var1 = fn(2);
+const var10 = fnBreakLabel();
+const var2 = fn(3);
+const var3 = fn1(2);
+const var4 = fn1(3);
+const var5 = fn2();
+const var6 = fnContinue();
+const var7 = fnBreak(2);
+const var8 = fnBreak(3);
+const var9 = fnNestedFor();
+int fn(int a) {}
+int fn1(int a) {}
+int fn2() {}
+int fnBreak(int a) {}
+int fnBreakLabel() {}
+int fnContinue() {}
+int fnNestedFor() {}
+void main() {}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_for_statements.dart.weak.expect b/pkg/front_end/testcases/const_functions/const_functions_for_statements.dart.weak.expect
new file mode 100644
index 0000000..b8210ed
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_for_statements.dart.weak.expect
@@ -0,0 +1,102 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "package:expect/expect.dart" as exp;
+
+import "package:expect/expect.dart";
+
+static const field core::int var1 = #C1;
+static const field core::int var2 = #C2;
+static const field core::int var3 = #C3;
+static const field core::int var4 = #C4;
+static const field core::int var5 = #C5;
+static const field core::int var6 = #C1;
+static const field core::int var7 = #C6;
+static const field core::int var8 = #C2;
+static const field core::int var9 = #C7;
+static const field core::int var10 = #C8;
+static method fn(core::int a) → core::int {
+  core::int b = a;
+  for (core::int i = 0; i.{core::num::<}(2); i = i.{core::num::+}(1)) {
+    b = b.{core::num::+}(a);
+  }
+  return b;
+}
+static method fn1(core::int a) → core::int {
+  core::int b = a;
+  for (core::int i = 0; ; i = i.{core::num::+}(1)) {
+    b = b.{core::num::*}(3);
+    if(b.{core::num::>}(10))
+      return b;
+  }
+}
+static method fn2() → core::int {
+  for (core::int i = 0, core::int j = 2; ; i = i.{core::num::+}(2), j = j.{core::num::+}(1)) {
+    if(i.{core::num::+}(j).{core::num::>}(10)) {
+      return i.{core::num::+}(j);
+    }
+  }
+}
+static method fnContinue() → core::int {
+  core::int a = 0;
+  for (core::int i = 0; i.{core::num::<}(5); i = i.{core::num::+}(1))
+    #L1:
+    {
+      if(i.{core::num::%}(2).{core::num::==}(1))
+        break #L1;
+      a = a.{core::num::+}(i);
+    }
+  return a;
+}
+static method fnBreak(core::int a) → core::int {
+  core::int b = a;
+  #L2:
+  for (core::int i = 0; i.{core::num::<}(2); i = i.{core::num::+}(1)) {
+    if(b.{core::num::==}(2))
+      break #L2;
+    b = b.{core::num::+}(a);
+  }
+  return b;
+}
+static method fnNestedFor() → core::int {
+  core::int a = 0;
+  for (; ; ) {
+    #L3:
+    for (; ; ) {
+      break #L3;
+    }
+    return 1;
+  }
+}
+static method fnBreakLabel() → core::int {
+  #L4:
+  for (; ; ) {
+    for (; ; ) {
+      break #L4;
+    }
+  }
+  return 3;
+}
+static method main() → void {
+  exp::Expect::equals(#C1, 6);
+  exp::Expect::equals(#C2, 9);
+  exp::Expect::equals(#C3, 18);
+  exp::Expect::equals(#C4, 27);
+  exp::Expect::equals(#C5, 11);
+  exp::Expect::equals(#C1, 6);
+  exp::Expect::equals(#C6, 2);
+  exp::Expect::equals(#C2, 9);
+  exp::Expect::equals(#C7, 1);
+  exp::Expect::equals(#C8, 3);
+}
+
+constants  {
+  #C1 = 6
+  #C2 = 9
+  #C3 = 18
+  #C4 = 27
+  #C5 = 11
+  #C6 = 2
+  #C7 = 1
+  #C8 = 3
+}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_for_statements.dart.weak.outline.expect b/pkg/front_end/testcases/const_functions/const_functions_for_statements.dart.weak.outline.expect
new file mode 100644
index 0000000..b9034e2
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_for_statements.dart.weak.outline.expect
@@ -0,0 +1,32 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+import "package:expect/expect.dart";
+
+static const field core::int var1 = self::fn(2);
+static const field core::int var2 = self::fn(3);
+static const field core::int var3 = self::fn1(2);
+static const field core::int var4 = self::fn1(3);
+static const field core::int var5 = self::fn2();
+static const field core::int var6 = self::fnContinue();
+static const field core::int var7 = self::fnBreak(2);
+static const field core::int var8 = self::fnBreak(3);
+static const field core::int var9 = self::fnNestedFor();
+static const field core::int var10 = self::fnBreakLabel();
+static method fn(core::int a) → core::int
+  ;
+static method fn1(core::int a) → core::int
+  ;
+static method fn2() → core::int
+  ;
+static method fnContinue() → core::int
+  ;
+static method fnBreak(core::int a) → core::int
+  ;
+static method fnNestedFor() → core::int
+  ;
+static method fnBreakLabel() → core::int
+  ;
+static method main() → void
+  ;
diff --git a/pkg/front_end/testcases/const_functions/const_functions_for_statements.dart.weak.transformed.expect b/pkg/front_end/testcases/const_functions/const_functions_for_statements.dart.weak.transformed.expect
new file mode 100644
index 0000000..b8210ed
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_for_statements.dart.weak.transformed.expect
@@ -0,0 +1,102 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "package:expect/expect.dart" as exp;
+
+import "package:expect/expect.dart";
+
+static const field core::int var1 = #C1;
+static const field core::int var2 = #C2;
+static const field core::int var3 = #C3;
+static const field core::int var4 = #C4;
+static const field core::int var5 = #C5;
+static const field core::int var6 = #C1;
+static const field core::int var7 = #C6;
+static const field core::int var8 = #C2;
+static const field core::int var9 = #C7;
+static const field core::int var10 = #C8;
+static method fn(core::int a) → core::int {
+  core::int b = a;
+  for (core::int i = 0; i.{core::num::<}(2); i = i.{core::num::+}(1)) {
+    b = b.{core::num::+}(a);
+  }
+  return b;
+}
+static method fn1(core::int a) → core::int {
+  core::int b = a;
+  for (core::int i = 0; ; i = i.{core::num::+}(1)) {
+    b = b.{core::num::*}(3);
+    if(b.{core::num::>}(10))
+      return b;
+  }
+}
+static method fn2() → core::int {
+  for (core::int i = 0, core::int j = 2; ; i = i.{core::num::+}(2), j = j.{core::num::+}(1)) {
+    if(i.{core::num::+}(j).{core::num::>}(10)) {
+      return i.{core::num::+}(j);
+    }
+  }
+}
+static method fnContinue() → core::int {
+  core::int a = 0;
+  for (core::int i = 0; i.{core::num::<}(5); i = i.{core::num::+}(1))
+    #L1:
+    {
+      if(i.{core::num::%}(2).{core::num::==}(1))
+        break #L1;
+      a = a.{core::num::+}(i);
+    }
+  return a;
+}
+static method fnBreak(core::int a) → core::int {
+  core::int b = a;
+  #L2:
+  for (core::int i = 0; i.{core::num::<}(2); i = i.{core::num::+}(1)) {
+    if(b.{core::num::==}(2))
+      break #L2;
+    b = b.{core::num::+}(a);
+  }
+  return b;
+}
+static method fnNestedFor() → core::int {
+  core::int a = 0;
+  for (; ; ) {
+    #L3:
+    for (; ; ) {
+      break #L3;
+    }
+    return 1;
+  }
+}
+static method fnBreakLabel() → core::int {
+  #L4:
+  for (; ; ) {
+    for (; ; ) {
+      break #L4;
+    }
+  }
+  return 3;
+}
+static method main() → void {
+  exp::Expect::equals(#C1, 6);
+  exp::Expect::equals(#C2, 9);
+  exp::Expect::equals(#C3, 18);
+  exp::Expect::equals(#C4, 27);
+  exp::Expect::equals(#C5, 11);
+  exp::Expect::equals(#C1, 6);
+  exp::Expect::equals(#C6, 2);
+  exp::Expect::equals(#C2, 9);
+  exp::Expect::equals(#C7, 1);
+  exp::Expect::equals(#C8, 3);
+}
+
+constants  {
+  #C1 = 6
+  #C2 = 9
+  #C3 = 18
+  #C4 = 27
+  #C5 = 11
+  #C6 = 2
+  #C7 = 1
+  #C8 = 3
+}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_if_statements.dart b/pkg/front_end/testcases/const_functions/const_functions_if_statements.dart
new file mode 100644
index 0000000..a4118a3
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_if_statements.dart
@@ -0,0 +1,75 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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 if statements for const functions.
+
+import "package:expect/expect.dart";
+
+const var1 = ifTest(1);
+const var2 = ifTest(2);
+const var3 = ifTest(3);
+int ifTest(int a) {
+  if (a == 1) {
+    return 100;
+  } else if (a == 2) {
+    return 200;
+  } else {
+    return 300;
+  }
+}
+
+const one = 1;
+const var4 = ifTest2(1);
+const var5 = ifTest2(2);
+int ifTest2(int a) {
+  if (a == one) {
+    return 100;
+  } else {
+    return 200;
+  }
+}
+
+const var6 = ifTest3(1);
+const var6_1 = ifTest3(2);
+const var6_2 = ifTest3(0);
+int ifTest3(int a) {
+  if (a > 0) {
+    if (a == 1) return 100;
+    return 200;
+  }
+  return 300;
+}
+
+const var7 = ifTest4(1);
+int ifTest4(int a) {
+  int b = a;
+  if (a == 1) {
+    b += a;
+    if (a % 2 == 1) {
+      b += a;
+    }
+  } else if (a == 2) {
+    b -= a;
+  }
+
+  return b;
+}
+
+const var8 = ifTest5();
+int ifTest5() {
+  var x = 10;
+  if (true) var x = 20;
+  return x;
+}
+
+void main() {
+  Expect.equals(var1, 100);
+  Expect.equals(var2, 200);
+  Expect.equals(var3, 300);
+  Expect.equals(var4, 100);
+  Expect.equals(var5, 200);
+  Expect.equals(var6, 100);
+  Expect.equals(var7, 3);
+  Expect.equals(var8, 10);
+}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_if_statements.dart.strong.expect b/pkg/front_end/testcases/const_functions/const_functions_if_statements.dart.strong.expect
new file mode 100644
index 0000000..8d0f813
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_if_statements.dart.strong.expect
@@ -0,0 +1,86 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "package:expect/expect.dart" as exp;
+
+import "package:expect/expect.dart";
+
+static const field core::int var1 = #C1;
+static const field core::int var2 = #C2;
+static const field core::int var3 = #C3;
+static const field core::int one = #C4;
+static const field core::int var4 = #C1;
+static const field core::int var5 = #C2;
+static const field core::int var6 = #C1;
+static const field core::int var6_1 = #C2;
+static const field core::int var6_2 = #C3;
+static const field core::int var7 = #C5;
+static const field core::int var8 = #C6;
+static method ifTest(core::int a) → core::int {
+  if(a.{core::num::==}(1)) {
+    return 100;
+  }
+  else
+    if(a.{core::num::==}(2)) {
+      return 200;
+    }
+    else {
+      return 300;
+    }
+}
+static method ifTest2(core::int a) → core::int {
+  if(a.{core::num::==}(#C4)) {
+    return 100;
+  }
+  else {
+    return 200;
+  }
+}
+static method ifTest3(core::int a) → core::int {
+  if(a.{core::num::>}(0)) {
+    if(a.{core::num::==}(1))
+      return 100;
+    return 200;
+  }
+  return 300;
+}
+static method ifTest4(core::int a) → core::int {
+  core::int b = a;
+  if(a.{core::num::==}(1)) {
+    b = b.{core::num::+}(a);
+    if(a.{core::num::%}(2).{core::num::==}(1)) {
+      b = b.{core::num::+}(a);
+    }
+  }
+  else
+    if(a.{core::num::==}(2)) {
+      b = b.{core::num::-}(a);
+    }
+  return b;
+}
+static method ifTest5() → core::int {
+  core::int x = 10;
+  if(true) {
+    core::int x = 20;
+  }
+  return x;
+}
+static method main() → void {
+  exp::Expect::equals(#C1, 100);
+  exp::Expect::equals(#C2, 200);
+  exp::Expect::equals(#C3, 300);
+  exp::Expect::equals(#C1, 100);
+  exp::Expect::equals(#C2, 200);
+  exp::Expect::equals(#C1, 100);
+  exp::Expect::equals(#C5, 3);
+  exp::Expect::equals(#C6, 10);
+}
+
+constants  {
+  #C1 = 100
+  #C2 = 200
+  #C3 = 300
+  #C4 = 1
+  #C5 = 3
+  #C6 = 10
+}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_if_statements.dart.strong.transformed.expect b/pkg/front_end/testcases/const_functions/const_functions_if_statements.dart.strong.transformed.expect
new file mode 100644
index 0000000..8d0f813
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_if_statements.dart.strong.transformed.expect
@@ -0,0 +1,86 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "package:expect/expect.dart" as exp;
+
+import "package:expect/expect.dart";
+
+static const field core::int var1 = #C1;
+static const field core::int var2 = #C2;
+static const field core::int var3 = #C3;
+static const field core::int one = #C4;
+static const field core::int var4 = #C1;
+static const field core::int var5 = #C2;
+static const field core::int var6 = #C1;
+static const field core::int var6_1 = #C2;
+static const field core::int var6_2 = #C3;
+static const field core::int var7 = #C5;
+static const field core::int var8 = #C6;
+static method ifTest(core::int a) → core::int {
+  if(a.{core::num::==}(1)) {
+    return 100;
+  }
+  else
+    if(a.{core::num::==}(2)) {
+      return 200;
+    }
+    else {
+      return 300;
+    }
+}
+static method ifTest2(core::int a) → core::int {
+  if(a.{core::num::==}(#C4)) {
+    return 100;
+  }
+  else {
+    return 200;
+  }
+}
+static method ifTest3(core::int a) → core::int {
+  if(a.{core::num::>}(0)) {
+    if(a.{core::num::==}(1))
+      return 100;
+    return 200;
+  }
+  return 300;
+}
+static method ifTest4(core::int a) → core::int {
+  core::int b = a;
+  if(a.{core::num::==}(1)) {
+    b = b.{core::num::+}(a);
+    if(a.{core::num::%}(2).{core::num::==}(1)) {
+      b = b.{core::num::+}(a);
+    }
+  }
+  else
+    if(a.{core::num::==}(2)) {
+      b = b.{core::num::-}(a);
+    }
+  return b;
+}
+static method ifTest5() → core::int {
+  core::int x = 10;
+  if(true) {
+    core::int x = 20;
+  }
+  return x;
+}
+static method main() → void {
+  exp::Expect::equals(#C1, 100);
+  exp::Expect::equals(#C2, 200);
+  exp::Expect::equals(#C3, 300);
+  exp::Expect::equals(#C1, 100);
+  exp::Expect::equals(#C2, 200);
+  exp::Expect::equals(#C1, 100);
+  exp::Expect::equals(#C5, 3);
+  exp::Expect::equals(#C6, 10);
+}
+
+constants  {
+  #C1 = 100
+  #C2 = 200
+  #C3 = 300
+  #C4 = 1
+  #C5 = 3
+  #C6 = 10
+}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_if_statements.dart.textual_outline.expect b/pkg/front_end/testcases/const_functions/const_functions_if_statements.dart.textual_outline.expect
new file mode 100644
index 0000000..0af1a72
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_if_statements.dart.textual_outline.expect
@@ -0,0 +1,19 @@
+import "package:expect/expect.dart";
+
+const var1 = ifTest(1);
+const var2 = ifTest(2);
+const var3 = ifTest(3);
+int ifTest(int a) {}
+const one = 1;
+const var4 = ifTest2(1);
+const var5 = ifTest2(2);
+int ifTest2(int a) {}
+const var6 = ifTest3(1);
+const var6_1 = ifTest3(2);
+const var6_2 = ifTest3(0);
+int ifTest3(int a) {}
+const var7 = ifTest4(1);
+int ifTest4(int a) {}
+const var8 = ifTest5();
+int ifTest5() {}
+void main() {}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_if_statements.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/const_functions/const_functions_if_statements.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5f5b560
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_if_statements.dart.textual_outline_modelled.expect
@@ -0,0 +1,19 @@
+import "package:expect/expect.dart";
+
+const one = 1;
+const var1 = ifTest(1);
+const var2 = ifTest(2);
+const var3 = ifTest(3);
+const var4 = ifTest2(1);
+const var5 = ifTest2(2);
+const var6 = ifTest3(1);
+const var6_1 = ifTest3(2);
+const var6_2 = ifTest3(0);
+const var7 = ifTest4(1);
+const var8 = ifTest5();
+int ifTest(int a) {}
+int ifTest2(int a) {}
+int ifTest3(int a) {}
+int ifTest4(int a) {}
+int ifTest5() {}
+void main() {}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_if_statements.dart.weak.expect b/pkg/front_end/testcases/const_functions/const_functions_if_statements.dart.weak.expect
new file mode 100644
index 0000000..8d0f813
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_if_statements.dart.weak.expect
@@ -0,0 +1,86 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "package:expect/expect.dart" as exp;
+
+import "package:expect/expect.dart";
+
+static const field core::int var1 = #C1;
+static const field core::int var2 = #C2;
+static const field core::int var3 = #C3;
+static const field core::int one = #C4;
+static const field core::int var4 = #C1;
+static const field core::int var5 = #C2;
+static const field core::int var6 = #C1;
+static const field core::int var6_1 = #C2;
+static const field core::int var6_2 = #C3;
+static const field core::int var7 = #C5;
+static const field core::int var8 = #C6;
+static method ifTest(core::int a) → core::int {
+  if(a.{core::num::==}(1)) {
+    return 100;
+  }
+  else
+    if(a.{core::num::==}(2)) {
+      return 200;
+    }
+    else {
+      return 300;
+    }
+}
+static method ifTest2(core::int a) → core::int {
+  if(a.{core::num::==}(#C4)) {
+    return 100;
+  }
+  else {
+    return 200;
+  }
+}
+static method ifTest3(core::int a) → core::int {
+  if(a.{core::num::>}(0)) {
+    if(a.{core::num::==}(1))
+      return 100;
+    return 200;
+  }
+  return 300;
+}
+static method ifTest4(core::int a) → core::int {
+  core::int b = a;
+  if(a.{core::num::==}(1)) {
+    b = b.{core::num::+}(a);
+    if(a.{core::num::%}(2).{core::num::==}(1)) {
+      b = b.{core::num::+}(a);
+    }
+  }
+  else
+    if(a.{core::num::==}(2)) {
+      b = b.{core::num::-}(a);
+    }
+  return b;
+}
+static method ifTest5() → core::int {
+  core::int x = 10;
+  if(true) {
+    core::int x = 20;
+  }
+  return x;
+}
+static method main() → void {
+  exp::Expect::equals(#C1, 100);
+  exp::Expect::equals(#C2, 200);
+  exp::Expect::equals(#C3, 300);
+  exp::Expect::equals(#C1, 100);
+  exp::Expect::equals(#C2, 200);
+  exp::Expect::equals(#C1, 100);
+  exp::Expect::equals(#C5, 3);
+  exp::Expect::equals(#C6, 10);
+}
+
+constants  {
+  #C1 = 100
+  #C2 = 200
+  #C3 = 300
+  #C4 = 1
+  #C5 = 3
+  #C6 = 10
+}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_if_statements.dart.weak.outline.expect b/pkg/front_end/testcases/const_functions/const_functions_if_statements.dart.weak.outline.expect
new file mode 100644
index 0000000..ee08b4b
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_if_statements.dart.weak.outline.expect
@@ -0,0 +1,29 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+import "package:expect/expect.dart";
+
+static const field core::int var1 = self::ifTest(1);
+static const field core::int var2 = self::ifTest(2);
+static const field core::int var3 = self::ifTest(3);
+static const field core::int one = 1;
+static const field core::int var4 = self::ifTest2(1);
+static const field core::int var5 = self::ifTest2(2);
+static const field core::int var6 = self::ifTest3(1);
+static const field core::int var6_1 = self::ifTest3(2);
+static const field core::int var6_2 = self::ifTest3(0);
+static const field core::int var7 = self::ifTest4(1);
+static const field core::int var8 = self::ifTest5();
+static method ifTest(core::int a) → core::int
+  ;
+static method ifTest2(core::int a) → core::int
+  ;
+static method ifTest3(core::int a) → core::int
+  ;
+static method ifTest4(core::int a) → core::int
+  ;
+static method ifTest5() → core::int
+  ;
+static method main() → void
+  ;
diff --git a/pkg/front_end/testcases/const_functions/const_functions_if_statements.dart.weak.transformed.expect b/pkg/front_end/testcases/const_functions/const_functions_if_statements.dart.weak.transformed.expect
new file mode 100644
index 0000000..8d0f813
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_if_statements.dart.weak.transformed.expect
@@ -0,0 +1,86 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "package:expect/expect.dart" as exp;
+
+import "package:expect/expect.dart";
+
+static const field core::int var1 = #C1;
+static const field core::int var2 = #C2;
+static const field core::int var3 = #C3;
+static const field core::int one = #C4;
+static const field core::int var4 = #C1;
+static const field core::int var5 = #C2;
+static const field core::int var6 = #C1;
+static const field core::int var6_1 = #C2;
+static const field core::int var6_2 = #C3;
+static const field core::int var7 = #C5;
+static const field core::int var8 = #C6;
+static method ifTest(core::int a) → core::int {
+  if(a.{core::num::==}(1)) {
+    return 100;
+  }
+  else
+    if(a.{core::num::==}(2)) {
+      return 200;
+    }
+    else {
+      return 300;
+    }
+}
+static method ifTest2(core::int a) → core::int {
+  if(a.{core::num::==}(#C4)) {
+    return 100;
+  }
+  else {
+    return 200;
+  }
+}
+static method ifTest3(core::int a) → core::int {
+  if(a.{core::num::>}(0)) {
+    if(a.{core::num::==}(1))
+      return 100;
+    return 200;
+  }
+  return 300;
+}
+static method ifTest4(core::int a) → core::int {
+  core::int b = a;
+  if(a.{core::num::==}(1)) {
+    b = b.{core::num::+}(a);
+    if(a.{core::num::%}(2).{core::num::==}(1)) {
+      b = b.{core::num::+}(a);
+    }
+  }
+  else
+    if(a.{core::num::==}(2)) {
+      b = b.{core::num::-}(a);
+    }
+  return b;
+}
+static method ifTest5() → core::int {
+  core::int x = 10;
+  if(true) {
+    core::int x = 20;
+  }
+  return x;
+}
+static method main() → void {
+  exp::Expect::equals(#C1, 100);
+  exp::Expect::equals(#C2, 200);
+  exp::Expect::equals(#C3, 300);
+  exp::Expect::equals(#C1, 100);
+  exp::Expect::equals(#C2, 200);
+  exp::Expect::equals(#C1, 100);
+  exp::Expect::equals(#C5, 3);
+  exp::Expect::equals(#C6, 10);
+}
+
+constants  {
+  #C1 = 100
+  #C2 = 200
+  #C3 = 300
+  #C4 = 1
+  #C5 = 3
+  #C6 = 10
+}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_local_functions.dart b/pkg/front_end/testcases/const_functions/const_functions_local_functions.dart
new file mode 100644
index 0000000..b8aa152
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_local_functions.dart
@@ -0,0 +1,73 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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 local function usage, some having references to other constant values.
+
+import "package:expect/expect.dart";
+
+int function1() {
+  int add(int a, int b) => a + b;
+  const value = add(10, 2);
+  return value;
+}
+
+const constTwo = 2;
+int function2() {
+  int addTwo(int a) {
+    int b = a + constTwo;
+    return b;
+  }
+
+  const value = addTwo(2);
+  return value;
+}
+
+int function3() {
+  int addTwoReturn(int a) => a + constTwo;
+  const value = addTwoReturn(3);
+  return value;
+}
+
+int function4() {
+  const localTwo = 2;
+  int addTwo(int a) => a + localTwo;
+  const value = addTwo(20);
+  return value;
+}
+
+int function5() {
+  T typeFn<T>(T a) => a;
+  const value = typeFn(3);
+  return value;
+}
+
+int function6() {
+  int optionalFn([int a = 0]) => a;
+  const value = optionalFn(1);
+  return value;
+}
+
+int function7() {
+  int namedFn({int a = 0}) => a;
+  const value = namedFn(a: 2);
+  return value;
+}
+
+int function8() {
+  int add(int a, int b) => a + b;
+  const value = add(1, 1);
+  const value1 = add(2, 3);
+  return value + value1;
+}
+
+void main() {
+  Expect.equals(function1(), 12);
+  Expect.equals(function2(), 4);
+  Expect.equals(function3(), 5);
+  Expect.equals(function4(), 22);
+  Expect.equals(function5(), 3);
+  Expect.equals(function6(), 1);
+  Expect.equals(function7(), 2);
+  Expect.equals(function8(), 7);
+}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_local_functions.dart.strong.expect b/pkg/front_end/testcases/const_functions/const_functions_local_functions.dart.strong.expect
new file mode 100644
index 0000000..cd90a2e
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_local_functions.dart.strong.expect
@@ -0,0 +1,71 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "package:expect/expect.dart" as exp;
+
+import "package:expect/expect.dart";
+
+static const field core::int constTwo = #C1;
+static method function1() → core::int {
+  function add(core::int a, core::int b) → core::int
+    return a.{core::num::+}(b);
+  return #C2;
+}
+static method function2() → core::int {
+  function addTwo(core::int a) → core::int {
+    core::int b = a.{core::num::+}(#C1);
+    return b;
+  }
+  return #C3;
+}
+static method function3() → core::int {
+  function addTwoReturn(core::int a) → core::int
+    return a.{core::num::+}(#C1);
+  return #C4;
+}
+static method function4() → core::int {
+  function addTwo(core::int a) → core::int
+    return a.{core::num::+}(#C1);
+  return #C5;
+}
+static method function5() → core::int {
+  function typeFn<T extends core::Object? = dynamic>(T% a) → T%
+    return a;
+  return #C6;
+}
+static method function6() → core::int {
+  function optionalFn([core::int a = #C7]) → core::int
+    return a;
+  return #C8;
+}
+static method function7() → core::int {
+  function namedFn({core::int a = #C7}) → core::int
+    return a;
+  return #C1;
+}
+static method function8() → core::int {
+  function add(core::int a, core::int b) → core::int
+    return a.{core::num::+}(b);
+  return (#C1).{core::num::+}(#C4);
+}
+static method main() → void {
+  exp::Expect::equals(self::function1(), 12);
+  exp::Expect::equals(self::function2(), 4);
+  exp::Expect::equals(self::function3(), 5);
+  exp::Expect::equals(self::function4(), 22);
+  exp::Expect::equals(self::function5(), 3);
+  exp::Expect::equals(self::function6(), 1);
+  exp::Expect::equals(self::function7(), 2);
+  exp::Expect::equals(self::function8(), 7);
+}
+
+constants  {
+  #C1 = 2
+  #C2 = 12
+  #C3 = 4
+  #C4 = 5
+  #C5 = 22
+  #C6 = 3
+  #C7 = 0
+  #C8 = 1
+}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_local_functions.dart.strong.transformed.expect b/pkg/front_end/testcases/const_functions/const_functions_local_functions.dart.strong.transformed.expect
new file mode 100644
index 0000000..2dc0292
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_local_functions.dart.strong.transformed.expect
@@ -0,0 +1,75 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "package:expect/expect.dart" as exp;
+
+import "package:expect/expect.dart";
+
+static const field core::int constTwo = #C1;
+static method function1() → core::int {
+  function add(core::int a, core::int b) → core::int
+    return a.{core::num::+}(b);
+  return #C2;
+}
+static method function2() → core::int {
+  function addTwo(core::int a) → core::int {
+    core::int b = a.{core::num::+}(#C1);
+    return b;
+  }
+  return #C3;
+}
+static method function3() → core::int {
+  function addTwoReturn(core::int a) → core::int
+    return a.{core::num::+}(#C1);
+  return #C4;
+}
+static method function4() → core::int {
+  function addTwo(core::int a) → core::int
+    return a.{core::num::+}(#C1);
+  return #C5;
+}
+static method function5() → core::int {
+  function typeFn<T extends core::Object? = dynamic>(T% a) → T%
+    return a;
+  return #C6;
+}
+static method function6() → core::int {
+  function optionalFn([core::int a = #C7]) → core::int
+    return a;
+  return #C8;
+}
+static method function7() → core::int {
+  function namedFn({core::int a = #C7}) → core::int
+    return a;
+  return #C1;
+}
+static method function8() → core::int {
+  function add(core::int a, core::int b) → core::int
+    return a.{core::num::+}(b);
+  return (#C1).{core::num::+}(#C4);
+}
+static method main() → void {
+  exp::Expect::equals(self::function1(), 12);
+  exp::Expect::equals(self::function2(), 4);
+  exp::Expect::equals(self::function3(), 5);
+  exp::Expect::equals(self::function4(), 22);
+  exp::Expect::equals(self::function5(), 3);
+  exp::Expect::equals(self::function6(), 1);
+  exp::Expect::equals(self::function7(), 2);
+  exp::Expect::equals(self::function8(), 7);
+}
+
+constants  {
+  #C1 = 2
+  #C2 = 12
+  #C3 = 4
+  #C4 = 5
+  #C5 = 22
+  #C6 = 3
+  #C7 = 0
+  #C8 = 1
+}
+
+Extra constant evaluation status:
+Evaluated: MethodInvocation @ org-dartlang-testcase:///const_functions_local_functions.dart:61:16 -> IntConstant(7)
+Extra constant evaluation: evaluated: 33, effectively constant: 1
diff --git a/pkg/front_end/testcases/const_functions/const_functions_local_functions.dart.textual_outline.expect b/pkg/front_end/testcases/const_functions/const_functions_local_functions.dart.textual_outline.expect
new file mode 100644
index 0000000..6b92e59
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_local_functions.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+import "package:expect/expect.dart";
+
+int function1() {}
+const constTwo = 2;
+int function2() {}
+int function3() {}
+int function4() {}
+int function5() {}
+int function6() {}
+int function7() {}
+int function8() {}
+void main() {}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_local_functions.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/const_functions/const_functions_local_functions.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..06caca3
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_local_functions.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+import "package:expect/expect.dart";
+
+const constTwo = 2;
+int function1() {}
+int function2() {}
+int function3() {}
+int function4() {}
+int function5() {}
+int function6() {}
+int function7() {}
+int function8() {}
+void main() {}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_local_functions.dart.weak.expect b/pkg/front_end/testcases/const_functions/const_functions_local_functions.dart.weak.expect
new file mode 100644
index 0000000..cd90a2e
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_local_functions.dart.weak.expect
@@ -0,0 +1,71 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "package:expect/expect.dart" as exp;
+
+import "package:expect/expect.dart";
+
+static const field core::int constTwo = #C1;
+static method function1() → core::int {
+  function add(core::int a, core::int b) → core::int
+    return a.{core::num::+}(b);
+  return #C2;
+}
+static method function2() → core::int {
+  function addTwo(core::int a) → core::int {
+    core::int b = a.{core::num::+}(#C1);
+    return b;
+  }
+  return #C3;
+}
+static method function3() → core::int {
+  function addTwoReturn(core::int a) → core::int
+    return a.{core::num::+}(#C1);
+  return #C4;
+}
+static method function4() → core::int {
+  function addTwo(core::int a) → core::int
+    return a.{core::num::+}(#C1);
+  return #C5;
+}
+static method function5() → core::int {
+  function typeFn<T extends core::Object? = dynamic>(T% a) → T%
+    return a;
+  return #C6;
+}
+static method function6() → core::int {
+  function optionalFn([core::int a = #C7]) → core::int
+    return a;
+  return #C8;
+}
+static method function7() → core::int {
+  function namedFn({core::int a = #C7}) → core::int
+    return a;
+  return #C1;
+}
+static method function8() → core::int {
+  function add(core::int a, core::int b) → core::int
+    return a.{core::num::+}(b);
+  return (#C1).{core::num::+}(#C4);
+}
+static method main() → void {
+  exp::Expect::equals(self::function1(), 12);
+  exp::Expect::equals(self::function2(), 4);
+  exp::Expect::equals(self::function3(), 5);
+  exp::Expect::equals(self::function4(), 22);
+  exp::Expect::equals(self::function5(), 3);
+  exp::Expect::equals(self::function6(), 1);
+  exp::Expect::equals(self::function7(), 2);
+  exp::Expect::equals(self::function8(), 7);
+}
+
+constants  {
+  #C1 = 2
+  #C2 = 12
+  #C3 = 4
+  #C4 = 5
+  #C5 = 22
+  #C6 = 3
+  #C7 = 0
+  #C8 = 1
+}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_local_functions.dart.weak.outline.expect b/pkg/front_end/testcases/const_functions/const_functions_local_functions.dart.weak.outline.expect
new file mode 100644
index 0000000..2d98dcf2
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_local_functions.dart.weak.outline.expect
@@ -0,0 +1,25 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+import "package:expect/expect.dart";
+
+static const field core::int constTwo = 2;
+static method function1() → core::int
+  ;
+static method function2() → core::int
+  ;
+static method function3() → core::int
+  ;
+static method function4() → core::int
+  ;
+static method function5() → core::int
+  ;
+static method function6() → core::int
+  ;
+static method function7() → core::int
+  ;
+static method function8() → core::int
+  ;
+static method main() → void
+  ;
diff --git a/pkg/front_end/testcases/const_functions/const_functions_local_functions.dart.weak.transformed.expect b/pkg/front_end/testcases/const_functions/const_functions_local_functions.dart.weak.transformed.expect
new file mode 100644
index 0000000..2dc0292
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_local_functions.dart.weak.transformed.expect
@@ -0,0 +1,75 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "package:expect/expect.dart" as exp;
+
+import "package:expect/expect.dart";
+
+static const field core::int constTwo = #C1;
+static method function1() → core::int {
+  function add(core::int a, core::int b) → core::int
+    return a.{core::num::+}(b);
+  return #C2;
+}
+static method function2() → core::int {
+  function addTwo(core::int a) → core::int {
+    core::int b = a.{core::num::+}(#C1);
+    return b;
+  }
+  return #C3;
+}
+static method function3() → core::int {
+  function addTwoReturn(core::int a) → core::int
+    return a.{core::num::+}(#C1);
+  return #C4;
+}
+static method function4() → core::int {
+  function addTwo(core::int a) → core::int
+    return a.{core::num::+}(#C1);
+  return #C5;
+}
+static method function5() → core::int {
+  function typeFn<T extends core::Object? = dynamic>(T% a) → T%
+    return a;
+  return #C6;
+}
+static method function6() → core::int {
+  function optionalFn([core::int a = #C7]) → core::int
+    return a;
+  return #C8;
+}
+static method function7() → core::int {
+  function namedFn({core::int a = #C7}) → core::int
+    return a;
+  return #C1;
+}
+static method function8() → core::int {
+  function add(core::int a, core::int b) → core::int
+    return a.{core::num::+}(b);
+  return (#C1).{core::num::+}(#C4);
+}
+static method main() → void {
+  exp::Expect::equals(self::function1(), 12);
+  exp::Expect::equals(self::function2(), 4);
+  exp::Expect::equals(self::function3(), 5);
+  exp::Expect::equals(self::function4(), 22);
+  exp::Expect::equals(self::function5(), 3);
+  exp::Expect::equals(self::function6(), 1);
+  exp::Expect::equals(self::function7(), 2);
+  exp::Expect::equals(self::function8(), 7);
+}
+
+constants  {
+  #C1 = 2
+  #C2 = 12
+  #C3 = 4
+  #C4 = 5
+  #C5 = 22
+  #C6 = 3
+  #C7 = 0
+  #C8 = 1
+}
+
+Extra constant evaluation status:
+Evaluated: MethodInvocation @ org-dartlang-testcase:///const_functions_local_functions.dart:61:16 -> IntConstant(7)
+Extra constant evaluation: evaluated: 33, effectively constant: 1
diff --git a/pkg/front_end/testcases/const_functions/const_functions_recursion.dart b/pkg/front_end/testcases/const_functions/const_functions_recursion.dart
new file mode 100644
index 0000000..73f16fa
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_recursion.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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 recursive function calls for const functions.
+
+import "package:expect/expect.dart";
+
+const b = fn(4);
+int fn(int a) {
+  if (a == 1) return 1;
+  return a * fn(a - 1);
+}
+
+int localTest() {
+  int fnLocal(int a) {
+    if (a == 1) return 1;
+    return a * fnLocal(a - 1);
+  }
+
+  const c = fnLocal(4);
+  return c;
+}
+
+void main() {
+  Expect.equals(b, 24);
+  Expect.equals(localTest(), 24);
+}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_recursion.dart.strong.expect b/pkg/front_end/testcases/const_functions/const_functions_recursion.dart.strong.expect
new file mode 100644
index 0000000..c53d3dc
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_recursion.dart.strong.expect
@@ -0,0 +1,29 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "package:expect/expect.dart" as exp;
+
+import "package:expect/expect.dart";
+
+static const field core::int b = #C1;
+static method fn(core::int a) → core::int {
+  if(a.{core::num::==}(1))
+    return 1;
+  return a.{core::num::*}(self::fn(a.{core::num::-}(1)));
+}
+static method localTest() → core::int {
+  function fnLocal(core::int a) → core::int {
+    if(a.{core::num::==}(1))
+      return 1;
+    return a.{core::num::*}(fnLocal.call(a.{core::num::-}(1)));
+  }
+  return #C1;
+}
+static method main() → void {
+  exp::Expect::equals(#C1, 24);
+  exp::Expect::equals(self::localTest(), 24);
+}
+
+constants  {
+  #C1 = 24
+}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_recursion.dart.strong.transformed.expect b/pkg/front_end/testcases/const_functions/const_functions_recursion.dart.strong.transformed.expect
new file mode 100644
index 0000000..c53d3dc
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_recursion.dart.strong.transformed.expect
@@ -0,0 +1,29 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "package:expect/expect.dart" as exp;
+
+import "package:expect/expect.dart";
+
+static const field core::int b = #C1;
+static method fn(core::int a) → core::int {
+  if(a.{core::num::==}(1))
+    return 1;
+  return a.{core::num::*}(self::fn(a.{core::num::-}(1)));
+}
+static method localTest() → core::int {
+  function fnLocal(core::int a) → core::int {
+    if(a.{core::num::==}(1))
+      return 1;
+    return a.{core::num::*}(fnLocal.call(a.{core::num::-}(1)));
+  }
+  return #C1;
+}
+static method main() → void {
+  exp::Expect::equals(#C1, 24);
+  exp::Expect::equals(self::localTest(), 24);
+}
+
+constants  {
+  #C1 = 24
+}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_recursion.dart.textual_outline.expect b/pkg/front_end/testcases/const_functions/const_functions_recursion.dart.textual_outline.expect
new file mode 100644
index 0000000..e73f951
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_recursion.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+import "package:expect/expect.dart";
+
+const b = fn(4);
+int fn(int a) {}
+int localTest() {}
+void main() {}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_recursion.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/const_functions/const_functions_recursion.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e73f951
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_recursion.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+import "package:expect/expect.dart";
+
+const b = fn(4);
+int fn(int a) {}
+int localTest() {}
+void main() {}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_recursion.dart.weak.expect b/pkg/front_end/testcases/const_functions/const_functions_recursion.dart.weak.expect
new file mode 100644
index 0000000..c53d3dc
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_recursion.dart.weak.expect
@@ -0,0 +1,29 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "package:expect/expect.dart" as exp;
+
+import "package:expect/expect.dart";
+
+static const field core::int b = #C1;
+static method fn(core::int a) → core::int {
+  if(a.{core::num::==}(1))
+    return 1;
+  return a.{core::num::*}(self::fn(a.{core::num::-}(1)));
+}
+static method localTest() → core::int {
+  function fnLocal(core::int a) → core::int {
+    if(a.{core::num::==}(1))
+      return 1;
+    return a.{core::num::*}(fnLocal.call(a.{core::num::-}(1)));
+  }
+  return #C1;
+}
+static method main() → void {
+  exp::Expect::equals(#C1, 24);
+  exp::Expect::equals(self::localTest(), 24);
+}
+
+constants  {
+  #C1 = 24
+}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_recursion.dart.weak.outline.expect b/pkg/front_end/testcases/const_functions/const_functions_recursion.dart.weak.outline.expect
new file mode 100644
index 0000000..e25beae
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_recursion.dart.weak.outline.expect
@@ -0,0 +1,13 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+import "package:expect/expect.dart";
+
+static const field core::int b = self::fn(4);
+static method fn(core::int a) → core::int
+  ;
+static method localTest() → core::int
+  ;
+static method main() → void
+  ;
diff --git a/pkg/front_end/testcases/const_functions/const_functions_recursion.dart.weak.transformed.expect b/pkg/front_end/testcases/const_functions/const_functions_recursion.dart.weak.transformed.expect
new file mode 100644
index 0000000..c53d3dc
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_recursion.dart.weak.transformed.expect
@@ -0,0 +1,29 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "package:expect/expect.dart" as exp;
+
+import "package:expect/expect.dart";
+
+static const field core::int b = #C1;
+static method fn(core::int a) → core::int {
+  if(a.{core::num::==}(1))
+    return 1;
+  return a.{core::num::*}(self::fn(a.{core::num::-}(1)));
+}
+static method localTest() → core::int {
+  function fnLocal(core::int a) → core::int {
+    if(a.{core::num::==}(1))
+      return 1;
+    return a.{core::num::*}(fnLocal.call(a.{core::num::-}(1)));
+  }
+  return #C1;
+}
+static method main() → void {
+  exp::Expect::equals(#C1, 24);
+  exp::Expect::equals(self::localTest(), 24);
+}
+
+constants  {
+  #C1 = 24
+}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_simple_invocations.dart b/pkg/front_end/testcases/const_functions/const_functions_simple_invocations.dart
index d77e883..78ad9d9 100644
--- a/pkg/front_end/testcases/const_functions/const_functions_simple_invocations.dart
+++ b/pkg/front_end/testcases/const_functions/const_functions_simple_invocations.dart
@@ -35,6 +35,10 @@
 const doubleResult = doubleFn(2.2, 2);
 double doubleFn(double a, double b) => a * b;
 
+const multi = multiFn(1);
+const multi2 = multiFn(2);
+int multiFn(int a) => a + 1;
+
 void main() {
   Expect.equals(binary, 1);
   Expect.equals(optional, 2);
@@ -47,4 +51,6 @@
   Expect.equals(negative, -2);
   Expect.equals(boolean, true);
   Expect.equals(doubleResult, 4.4);
+  Expect.equals(multi, 2);
+  Expect.equals(multi2, 3);
 }
diff --git a/pkg/front_end/testcases/const_functions/const_functions_simple_invocations.dart.strong.expect b/pkg/front_end/testcases/const_functions/const_functions_simple_invocations.dart.strong.expect
index 977caaa..0d13bf0 100644
--- a/pkg/front_end/testcases/const_functions/const_functions_simple_invocations.dart.strong.expect
+++ b/pkg/front_end/testcases/const_functions/const_functions_simple_invocations.dart.strong.expect
@@ -16,6 +16,8 @@
 static const field core::int negative = #C9;
 static const field core::bool boolean = #C8;
 static const field core::double doubleResult = #C10;
+static const field core::int multi = #C2;
+static const field core::int multi2 = #C3;
 static method binaryFn(core::int a, core::int b) → core::int
   return a.{core::num::-}(b);
 static method optionalFn(core::int c, [core::int d = #C11]) → core::int
@@ -34,6 +36,8 @@
   return a || b;
 static method doubleFn(core::double a, core::double b) → core::double
   return a.{core::double::*}(b);
+static method multiFn(core::int a) → core::int
+  return a.{core::num::+}(1);
 static method main() → void {
   exp::Expect::equals(#C1, 1);
   exp::Expect::equals(#C2, 2);
@@ -46,6 +50,8 @@
   exp::Expect::equals(#C9, 2.{core::int::unary-}());
   exp::Expect::equals(#C8, true);
   exp::Expect::equals(#C10, 4.4);
+  exp::Expect::equals(#C2, 2);
+  exp::Expect::equals(#C3, 3);
 }
 
 constants  {
diff --git a/pkg/front_end/testcases/const_functions/const_functions_simple_invocations.dart.strong.transformed.expect b/pkg/front_end/testcases/const_functions/const_functions_simple_invocations.dart.strong.transformed.expect
index 920ec7f..de39112 100644
--- a/pkg/front_end/testcases/const_functions/const_functions_simple_invocations.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/const_functions/const_functions_simple_invocations.dart.strong.transformed.expect
@@ -16,6 +16,8 @@
 static const field core::int negative = #C9;
 static const field core::bool boolean = #C8;
 static const field core::double doubleResult = #C10;
+static const field core::int multi = #C2;
+static const field core::int multi2 = #C3;
 static method binaryFn(core::int a, core::int b) → core::int
   return a.{core::num::-}(b);
 static method optionalFn(core::int c, [core::int d = #C11]) → core::int
@@ -34,6 +36,8 @@
   return a || b;
 static method doubleFn(core::double a, core::double b) → core::double
   return a.{core::double::*}(b);
+static method multiFn(core::int a) → core::int
+  return a.{core::num::+}(1);
 static method main() → void {
   exp::Expect::equals(#C1, 1);
   exp::Expect::equals(#C2, 2);
@@ -46,6 +50,8 @@
   exp::Expect::equals(#C9, 2.{core::int::unary-}());
   exp::Expect::equals(#C8, true);
   exp::Expect::equals(#C10, 4.4);
+  exp::Expect::equals(#C2, 2);
+  exp::Expect::equals(#C3, 3);
 }
 
 constants  {
@@ -63,5 +69,5 @@
 }
 
 Extra constant evaluation status:
-Evaluated: MethodInvocation @ org-dartlang-testcase:///const_functions_simple_invocations.dart:47:27 -> IntConstant(-2)
-Extra constant evaluation: evaluated: 35, effectively constant: 1
+Evaluated: MethodInvocation @ org-dartlang-testcase:///const_functions_simple_invocations.dart:51:27 -> IntConstant(-2)
+Extra constant evaluation: evaluated: 39, effectively constant: 1
diff --git a/pkg/front_end/testcases/const_functions/const_functions_simple_invocations.dart.textual_outline.expect b/pkg/front_end/testcases/const_functions/const_functions_simple_invocations.dart.textual_outline.expect
index 13bdbb5..81a6fa3 100644
--- a/pkg/front_end/testcases/const_functions/const_functions_simple_invocations.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/const_functions/const_functions_simple_invocations.dart.textual_outline.expect
@@ -20,4 +20,7 @@
 bool boolFn(bool a, bool b) => a || b;
 const doubleResult = doubleFn(2.2, 2);
 double doubleFn(double a, double b) => a * b;
+const multi = multiFn(1);
+const multi2 = multiFn(2);
+int multiFn(int a) => a + 1;
 void main() {}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_simple_invocations.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/const_functions/const_functions_simple_invocations.dart.textual_outline_modelled.expect
index a3e7b8c..6428837 100644
--- a/pkg/front_end/testcases/const_functions/const_functions_simple_invocations.dart.textual_outline_modelled.expect
+++ b/pkg/front_end/testcases/const_functions/const_functions_simple_invocations.dart.textual_outline_modelled.expect
@@ -8,6 +8,8 @@
 const boolean = boolFn(true, false);
 const doubleResult = doubleFn(2.2, 2);
 const eq = equalFn(2, 2);
+const multi = multiFn(1);
+const multi2 = multiFn(2);
 const named = namedFn(2, f: 2);
 const named1 = namedFn(2);
 const negative = unary(2);
@@ -17,6 +19,7 @@
 const type = typeFn(6);
 double doubleFn(double a, double b) => a * b;
 int binaryFn(int a, int b) => a - b;
+int multiFn(int a) => a + 1;
 int namedFn(int e, {int f = 3}) => e + f;
 int optionalFn(int c, [int d = 0]) => c + d;
 int unary(int a) => -a;
diff --git a/pkg/front_end/testcases/const_functions/const_functions_simple_invocations.dart.weak.expect b/pkg/front_end/testcases/const_functions/const_functions_simple_invocations.dart.weak.expect
index 977caaa..0d13bf0 100644
--- a/pkg/front_end/testcases/const_functions/const_functions_simple_invocations.dart.weak.expect
+++ b/pkg/front_end/testcases/const_functions/const_functions_simple_invocations.dart.weak.expect
@@ -16,6 +16,8 @@
 static const field core::int negative = #C9;
 static const field core::bool boolean = #C8;
 static const field core::double doubleResult = #C10;
+static const field core::int multi = #C2;
+static const field core::int multi2 = #C3;
 static method binaryFn(core::int a, core::int b) → core::int
   return a.{core::num::-}(b);
 static method optionalFn(core::int c, [core::int d = #C11]) → core::int
@@ -34,6 +36,8 @@
   return a || b;
 static method doubleFn(core::double a, core::double b) → core::double
   return a.{core::double::*}(b);
+static method multiFn(core::int a) → core::int
+  return a.{core::num::+}(1);
 static method main() → void {
   exp::Expect::equals(#C1, 1);
   exp::Expect::equals(#C2, 2);
@@ -46,6 +50,8 @@
   exp::Expect::equals(#C9, 2.{core::int::unary-}());
   exp::Expect::equals(#C8, true);
   exp::Expect::equals(#C10, 4.4);
+  exp::Expect::equals(#C2, 2);
+  exp::Expect::equals(#C3, 3);
 }
 
 constants  {
diff --git a/pkg/front_end/testcases/const_functions/const_functions_simple_invocations.dart.weak.outline.expect b/pkg/front_end/testcases/const_functions/const_functions_simple_invocations.dart.weak.outline.expect
index f3f61d3..d5201b0 100644
--- a/pkg/front_end/testcases/const_functions/const_functions_simple_invocations.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/const_functions/const_functions_simple_invocations.dart.weak.outline.expect
@@ -15,6 +15,8 @@
 static const field core::int negative = self::unary(2);
 static const field core::bool boolean = self::boolFn(true, false);
 static const field core::double doubleResult = self::doubleFn(2.2, 2.0);
+static const field core::int multi = self::multiFn(1);
+static const field core::int multi2 = self::multiFn(2);
 static method binaryFn(core::int a, core::int b) → core::int
   ;
 static method optionalFn(core::int c, [core::int d]) → core::int
@@ -33,5 +35,7 @@
   ;
 static method doubleFn(core::double a, core::double b) → core::double
   ;
+static method multiFn(core::int a) → core::int
+  ;
 static method main() → void
   ;
diff --git a/pkg/front_end/testcases/const_functions/const_functions_simple_invocations.dart.weak.transformed.expect b/pkg/front_end/testcases/const_functions/const_functions_simple_invocations.dart.weak.transformed.expect
index 920ec7f..de39112 100644
--- a/pkg/front_end/testcases/const_functions/const_functions_simple_invocations.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/const_functions/const_functions_simple_invocations.dart.weak.transformed.expect
@@ -16,6 +16,8 @@
 static const field core::int negative = #C9;
 static const field core::bool boolean = #C8;
 static const field core::double doubleResult = #C10;
+static const field core::int multi = #C2;
+static const field core::int multi2 = #C3;
 static method binaryFn(core::int a, core::int b) → core::int
   return a.{core::num::-}(b);
 static method optionalFn(core::int c, [core::int d = #C11]) → core::int
@@ -34,6 +36,8 @@
   return a || b;
 static method doubleFn(core::double a, core::double b) → core::double
   return a.{core::double::*}(b);
+static method multiFn(core::int a) → core::int
+  return a.{core::num::+}(1);
 static method main() → void {
   exp::Expect::equals(#C1, 1);
   exp::Expect::equals(#C2, 2);
@@ -46,6 +50,8 @@
   exp::Expect::equals(#C9, 2.{core::int::unary-}());
   exp::Expect::equals(#C8, true);
   exp::Expect::equals(#C10, 4.4);
+  exp::Expect::equals(#C2, 2);
+  exp::Expect::equals(#C3, 3);
 }
 
 constants  {
@@ -63,5 +69,5 @@
 }
 
 Extra constant evaluation status:
-Evaluated: MethodInvocation @ org-dartlang-testcase:///const_functions_simple_invocations.dart:47:27 -> IntConstant(-2)
-Extra constant evaluation: evaluated: 35, effectively constant: 1
+Evaluated: MethodInvocation @ org-dartlang-testcase:///const_functions_simple_invocations.dart:51:27 -> IntConstant(-2)
+Extra constant evaluation: evaluated: 39, effectively constant: 1
diff --git a/pkg/front_end/testcases/const_functions/const_functions_switch_statements.dart b/pkg/front_end/testcases/const_functions/const_functions_switch_statements.dart
new file mode 100644
index 0000000..c192041
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_switch_statements.dart
@@ -0,0 +1,65 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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 switch statements for const functions.
+
+import "package:expect/expect.dart";
+
+const var1 = basicSwitch(1);
+const var2 = basicSwitch(2);
+int basicSwitch(int x) {
+  switch (x) {
+    case 1:
+      return 100;
+    default:
+      x++;
+      break;
+  }
+  return x;
+}
+
+const var3 = multipleCaseSwitch(1);
+const var4 = multipleCaseSwitch(2);
+const var5 = multipleCaseSwitch(3);
+int multipleCaseSwitch(int x) {
+  switch (x) {
+    case 1:
+    case 2:
+      return 100;
+    default:
+      break;
+  }
+  return 0;
+}
+
+const var6 = continueLabelSwitch(1);
+const var7 = continueLabelSwitch(2);
+const var8 = continueLabelSwitch(3);
+const var9 = continueLabelSwitch(4);
+int continueLabelSwitch(int x) {
+  switch (x) {
+    label1:
+    case 1:
+      x = x + 100;
+      continue label3;
+    case 2:
+      continue label1;
+    label3:
+    case 3:
+      return x + 3;
+  }
+  return 0;
+}
+
+void main() {
+  Expect.equals(var1, 100);
+  Expect.equals(var2, 3);
+  Expect.equals(var3, 100);
+  Expect.equals(var4, 100);
+  Expect.equals(var5, 0);
+  Expect.equals(var6, 104);
+  Expect.equals(var7, 105);
+  Expect.equals(var8, 6);
+  Expect.equals(var9, 0);
+}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_switch_statements.dart.strong.expect b/pkg/front_end/testcases/const_functions/const_functions_switch_statements.dart.strong.expect
new file mode 100644
index 0000000..76efdb8
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_switch_statements.dart.strong.expect
@@ -0,0 +1,93 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "package:expect/expect.dart" as exp;
+
+import "package:expect/expect.dart";
+
+static const field core::int var1 = #C1;
+static const field core::int var2 = #C2;
+static const field core::int var3 = #C1;
+static const field core::int var4 = #C1;
+static const field core::int var5 = #C3;
+static const field core::int var6 = #C4;
+static const field core::int var7 = #C5;
+static const field core::int var8 = #C6;
+static const field core::int var9 = #C3;
+static method basicSwitch(core::int x) → core::int {
+  #L1:
+  switch(x) {
+    #L2:
+    case #C7:
+      {
+        return 100;
+      }
+    #L3:
+    default:
+      {
+        x = x.{core::num::+}(1);
+        break #L1;
+      }
+  }
+  return x;
+}
+static method multipleCaseSwitch(core::int x) → core::int {
+  #L4:
+  switch(x) {
+    #L5:
+    case #C7:
+    case #C8:
+      {
+        return 100;
+      }
+    #L6:
+    default:
+      {
+        break #L4;
+      }
+  }
+  return 0;
+}
+static method continueLabelSwitch(core::int x) → core::int {
+  switch(x) {
+    #L7:
+    case #C7:
+      {
+        x = x.{core::num::+}(100);
+        continue #L8;
+      }
+    #L9:
+    case #C8:
+      {
+        continue #L7;
+      }
+    #L8:
+    case #C2:
+      {
+        return x.{core::num::+}(3);
+      }
+  }
+  return 0;
+}
+static method main() → void {
+  exp::Expect::equals(#C1, 100);
+  exp::Expect::equals(#C2, 3);
+  exp::Expect::equals(#C1, 100);
+  exp::Expect::equals(#C1, 100);
+  exp::Expect::equals(#C3, 0);
+  exp::Expect::equals(#C4, 104);
+  exp::Expect::equals(#C5, 105);
+  exp::Expect::equals(#C6, 6);
+  exp::Expect::equals(#C3, 0);
+}
+
+constants  {
+  #C1 = 100
+  #C2 = 3
+  #C3 = 0
+  #C4 = 104
+  #C5 = 105
+  #C6 = 6
+  #C7 = 1
+  #C8 = 2
+}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_switch_statements.dart.strong.transformed.expect b/pkg/front_end/testcases/const_functions/const_functions_switch_statements.dart.strong.transformed.expect
new file mode 100644
index 0000000..76efdb8
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_switch_statements.dart.strong.transformed.expect
@@ -0,0 +1,93 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "package:expect/expect.dart" as exp;
+
+import "package:expect/expect.dart";
+
+static const field core::int var1 = #C1;
+static const field core::int var2 = #C2;
+static const field core::int var3 = #C1;
+static const field core::int var4 = #C1;
+static const field core::int var5 = #C3;
+static const field core::int var6 = #C4;
+static const field core::int var7 = #C5;
+static const field core::int var8 = #C6;
+static const field core::int var9 = #C3;
+static method basicSwitch(core::int x) → core::int {
+  #L1:
+  switch(x) {
+    #L2:
+    case #C7:
+      {
+        return 100;
+      }
+    #L3:
+    default:
+      {
+        x = x.{core::num::+}(1);
+        break #L1;
+      }
+  }
+  return x;
+}
+static method multipleCaseSwitch(core::int x) → core::int {
+  #L4:
+  switch(x) {
+    #L5:
+    case #C7:
+    case #C8:
+      {
+        return 100;
+      }
+    #L6:
+    default:
+      {
+        break #L4;
+      }
+  }
+  return 0;
+}
+static method continueLabelSwitch(core::int x) → core::int {
+  switch(x) {
+    #L7:
+    case #C7:
+      {
+        x = x.{core::num::+}(100);
+        continue #L8;
+      }
+    #L9:
+    case #C8:
+      {
+        continue #L7;
+      }
+    #L8:
+    case #C2:
+      {
+        return x.{core::num::+}(3);
+      }
+  }
+  return 0;
+}
+static method main() → void {
+  exp::Expect::equals(#C1, 100);
+  exp::Expect::equals(#C2, 3);
+  exp::Expect::equals(#C1, 100);
+  exp::Expect::equals(#C1, 100);
+  exp::Expect::equals(#C3, 0);
+  exp::Expect::equals(#C4, 104);
+  exp::Expect::equals(#C5, 105);
+  exp::Expect::equals(#C6, 6);
+  exp::Expect::equals(#C3, 0);
+}
+
+constants  {
+  #C1 = 100
+  #C2 = 3
+  #C3 = 0
+  #C4 = 104
+  #C5 = 105
+  #C6 = 6
+  #C7 = 1
+  #C8 = 2
+}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_switch_statements.dart.textual_outline.expect b/pkg/front_end/testcases/const_functions/const_functions_switch_statements.dart.textual_outline.expect
new file mode 100644
index 0000000..5d539a6
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_switch_statements.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+import "package:expect/expect.dart";
+
+const var1 = basicSwitch(1);
+const var2 = basicSwitch(2);
+int basicSwitch(int x) {}
+const var3 = multipleCaseSwitch(1);
+const var4 = multipleCaseSwitch(2);
+const var5 = multipleCaseSwitch(3);
+int multipleCaseSwitch(int x) {}
+const var6 = continueLabelSwitch(1);
+const var7 = continueLabelSwitch(2);
+const var8 = continueLabelSwitch(3);
+const var9 = continueLabelSwitch(4);
+int continueLabelSwitch(int x) {}
+void main() {}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_switch_statements.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/const_functions/const_functions_switch_statements.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f57dab8
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_switch_statements.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+import "package:expect/expect.dart";
+
+const var1 = basicSwitch(1);
+const var2 = basicSwitch(2);
+const var3 = multipleCaseSwitch(1);
+const var4 = multipleCaseSwitch(2);
+const var5 = multipleCaseSwitch(3);
+const var6 = continueLabelSwitch(1);
+const var7 = continueLabelSwitch(2);
+const var8 = continueLabelSwitch(3);
+const var9 = continueLabelSwitch(4);
+int basicSwitch(int x) {}
+int continueLabelSwitch(int x) {}
+int multipleCaseSwitch(int x) {}
+void main() {}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_switch_statements.dart.weak.expect b/pkg/front_end/testcases/const_functions/const_functions_switch_statements.dart.weak.expect
new file mode 100644
index 0000000..76efdb8
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_switch_statements.dart.weak.expect
@@ -0,0 +1,93 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "package:expect/expect.dart" as exp;
+
+import "package:expect/expect.dart";
+
+static const field core::int var1 = #C1;
+static const field core::int var2 = #C2;
+static const field core::int var3 = #C1;
+static const field core::int var4 = #C1;
+static const field core::int var5 = #C3;
+static const field core::int var6 = #C4;
+static const field core::int var7 = #C5;
+static const field core::int var8 = #C6;
+static const field core::int var9 = #C3;
+static method basicSwitch(core::int x) → core::int {
+  #L1:
+  switch(x) {
+    #L2:
+    case #C7:
+      {
+        return 100;
+      }
+    #L3:
+    default:
+      {
+        x = x.{core::num::+}(1);
+        break #L1;
+      }
+  }
+  return x;
+}
+static method multipleCaseSwitch(core::int x) → core::int {
+  #L4:
+  switch(x) {
+    #L5:
+    case #C7:
+    case #C8:
+      {
+        return 100;
+      }
+    #L6:
+    default:
+      {
+        break #L4;
+      }
+  }
+  return 0;
+}
+static method continueLabelSwitch(core::int x) → core::int {
+  switch(x) {
+    #L7:
+    case #C7:
+      {
+        x = x.{core::num::+}(100);
+        continue #L8;
+      }
+    #L9:
+    case #C8:
+      {
+        continue #L7;
+      }
+    #L8:
+    case #C2:
+      {
+        return x.{core::num::+}(3);
+      }
+  }
+  return 0;
+}
+static method main() → void {
+  exp::Expect::equals(#C1, 100);
+  exp::Expect::equals(#C2, 3);
+  exp::Expect::equals(#C1, 100);
+  exp::Expect::equals(#C1, 100);
+  exp::Expect::equals(#C3, 0);
+  exp::Expect::equals(#C4, 104);
+  exp::Expect::equals(#C5, 105);
+  exp::Expect::equals(#C6, 6);
+  exp::Expect::equals(#C3, 0);
+}
+
+constants  {
+  #C1 = 100
+  #C2 = 3
+  #C3 = 0
+  #C4 = 104
+  #C5 = 105
+  #C6 = 6
+  #C7 = 1
+  #C8 = 2
+}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_switch_statements.dart.weak.outline.expect b/pkg/front_end/testcases/const_functions/const_functions_switch_statements.dart.weak.outline.expect
new file mode 100644
index 0000000..b7050bd
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_switch_statements.dart.weak.outline.expect
@@ -0,0 +1,23 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+import "package:expect/expect.dart";
+
+static const field core::int var1 = self::basicSwitch(1);
+static const field core::int var2 = self::basicSwitch(2);
+static const field core::int var3 = self::multipleCaseSwitch(1);
+static const field core::int var4 = self::multipleCaseSwitch(2);
+static const field core::int var5 = self::multipleCaseSwitch(3);
+static const field core::int var6 = self::continueLabelSwitch(1);
+static const field core::int var7 = self::continueLabelSwitch(2);
+static const field core::int var8 = self::continueLabelSwitch(3);
+static const field core::int var9 = self::continueLabelSwitch(4);
+static method basicSwitch(core::int x) → core::int
+  ;
+static method multipleCaseSwitch(core::int x) → core::int
+  ;
+static method continueLabelSwitch(core::int x) → core::int
+  ;
+static method main() → void
+  ;
diff --git a/pkg/front_end/testcases/const_functions/const_functions_switch_statements.dart.weak.transformed.expect b/pkg/front_end/testcases/const_functions/const_functions_switch_statements.dart.weak.transformed.expect
new file mode 100644
index 0000000..76efdb8
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_switch_statements.dart.weak.transformed.expect
@@ -0,0 +1,93 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "package:expect/expect.dart" as exp;
+
+import "package:expect/expect.dart";
+
+static const field core::int var1 = #C1;
+static const field core::int var2 = #C2;
+static const field core::int var3 = #C1;
+static const field core::int var4 = #C1;
+static const field core::int var5 = #C3;
+static const field core::int var6 = #C4;
+static const field core::int var7 = #C5;
+static const field core::int var8 = #C6;
+static const field core::int var9 = #C3;
+static method basicSwitch(core::int x) → core::int {
+  #L1:
+  switch(x) {
+    #L2:
+    case #C7:
+      {
+        return 100;
+      }
+    #L3:
+    default:
+      {
+        x = x.{core::num::+}(1);
+        break #L1;
+      }
+  }
+  return x;
+}
+static method multipleCaseSwitch(core::int x) → core::int {
+  #L4:
+  switch(x) {
+    #L5:
+    case #C7:
+    case #C8:
+      {
+        return 100;
+      }
+    #L6:
+    default:
+      {
+        break #L4;
+      }
+  }
+  return 0;
+}
+static method continueLabelSwitch(core::int x) → core::int {
+  switch(x) {
+    #L7:
+    case #C7:
+      {
+        x = x.{core::num::+}(100);
+        continue #L8;
+      }
+    #L9:
+    case #C8:
+      {
+        continue #L7;
+      }
+    #L8:
+    case #C2:
+      {
+        return x.{core::num::+}(3);
+      }
+  }
+  return 0;
+}
+static method main() → void {
+  exp::Expect::equals(#C1, 100);
+  exp::Expect::equals(#C2, 3);
+  exp::Expect::equals(#C1, 100);
+  exp::Expect::equals(#C1, 100);
+  exp::Expect::equals(#C3, 0);
+  exp::Expect::equals(#C4, 104);
+  exp::Expect::equals(#C5, 105);
+  exp::Expect::equals(#C6, 6);
+  exp::Expect::equals(#C3, 0);
+}
+
+constants  {
+  #C1 = 100
+  #C2 = 3
+  #C3 = 0
+  #C4 = 104
+  #C5 = 105
+  #C6 = 6
+  #C7 = 1
+  #C8 = 2
+}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_variable_assignments.dart b/pkg/front_end/testcases/const_functions/const_functions_variable_assignments.dart
new file mode 100644
index 0000000..537caea
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_variable_assignments.dart
@@ -0,0 +1,42 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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 variable assignments for const functions.
+
+import "package:expect/expect.dart";
+
+const var1 = varAssignmentTest(1);
+int varAssignmentTest(int a) {
+  int x = 4;
+  {
+    x = 3;
+  }
+  return x;
+}
+
+int function() {
+  int varAssignmentTest2() {
+    int x = 2;
+    x += 1;
+    return x;
+  }
+
+  const var2 = varAssignmentTest2();
+  return var2;
+}
+
+const var3 = varAssignmentTest3(1);
+const var4 = varAssignmentTest3(2);
+int varAssignmentTest3(int a) {
+  int x = 4;
+  x = a + 1;
+  return x;
+}
+
+void main() {
+  Expect.equals(var1, 3);
+  Expect.equals(function(), 3);
+  Expect.equals(var3, 2);
+  Expect.equals(var4, 3);
+}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_variable_assignments.dart.strong.expect b/pkg/front_end/testcases/const_functions/const_functions_variable_assignments.dart.strong.expect
new file mode 100644
index 0000000..7107ba3
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_variable_assignments.dart.strong.expect
@@ -0,0 +1,41 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "package:expect/expect.dart" as exp;
+
+import "package:expect/expect.dart";
+
+static const field core::int var1 = #C1;
+static const field core::int var3 = #C2;
+static const field core::int var4 = #C1;
+static method varAssignmentTest(core::int a) → core::int {
+  core::int x = 4;
+  {
+    x = 3;
+  }
+  return x;
+}
+static method function() → core::int {
+  function varAssignmentTest2() → core::int {
+    core::int x = 2;
+    x = x.{core::num::+}(1);
+    return x;
+  }
+  return #C1;
+}
+static method varAssignmentTest3(core::int a) → core::int {
+  core::int x = 4;
+  x = a.{core::num::+}(1);
+  return x;
+}
+static method main() → void {
+  exp::Expect::equals(#C1, 3);
+  exp::Expect::equals(self::function(), 3);
+  exp::Expect::equals(#C2, 2);
+  exp::Expect::equals(#C1, 3);
+}
+
+constants  {
+  #C1 = 3
+  #C2 = 2
+}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_variable_assignments.dart.strong.transformed.expect b/pkg/front_end/testcases/const_functions/const_functions_variable_assignments.dart.strong.transformed.expect
new file mode 100644
index 0000000..7107ba3
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_variable_assignments.dart.strong.transformed.expect
@@ -0,0 +1,41 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "package:expect/expect.dart" as exp;
+
+import "package:expect/expect.dart";
+
+static const field core::int var1 = #C1;
+static const field core::int var3 = #C2;
+static const field core::int var4 = #C1;
+static method varAssignmentTest(core::int a) → core::int {
+  core::int x = 4;
+  {
+    x = 3;
+  }
+  return x;
+}
+static method function() → core::int {
+  function varAssignmentTest2() → core::int {
+    core::int x = 2;
+    x = x.{core::num::+}(1);
+    return x;
+  }
+  return #C1;
+}
+static method varAssignmentTest3(core::int a) → core::int {
+  core::int x = 4;
+  x = a.{core::num::+}(1);
+  return x;
+}
+static method main() → void {
+  exp::Expect::equals(#C1, 3);
+  exp::Expect::equals(self::function(), 3);
+  exp::Expect::equals(#C2, 2);
+  exp::Expect::equals(#C1, 3);
+}
+
+constants  {
+  #C1 = 3
+  #C2 = 2
+}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_variable_assignments.dart.textual_outline.expect b/pkg/front_end/testcases/const_functions/const_functions_variable_assignments.dart.textual_outline.expect
new file mode 100644
index 0000000..0db1b6d
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_variable_assignments.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+import "package:expect/expect.dart";
+
+const var1 = varAssignmentTest(1);
+int varAssignmentTest(int a) {}
+int function() {}
+const var3 = varAssignmentTest3(1);
+const var4 = varAssignmentTest3(2);
+int varAssignmentTest3(int a) {}
+void main() {}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_variable_assignments.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/const_functions/const_functions_variable_assignments.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..87b42cc
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_variable_assignments.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+import "package:expect/expect.dart";
+
+const var1 = varAssignmentTest(1);
+const var3 = varAssignmentTest3(1);
+const var4 = varAssignmentTest3(2);
+int function() {}
+int varAssignmentTest(int a) {}
+int varAssignmentTest3(int a) {}
+void main() {}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_variable_assignments.dart.weak.expect b/pkg/front_end/testcases/const_functions/const_functions_variable_assignments.dart.weak.expect
new file mode 100644
index 0000000..7107ba3
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_variable_assignments.dart.weak.expect
@@ -0,0 +1,41 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "package:expect/expect.dart" as exp;
+
+import "package:expect/expect.dart";
+
+static const field core::int var1 = #C1;
+static const field core::int var3 = #C2;
+static const field core::int var4 = #C1;
+static method varAssignmentTest(core::int a) → core::int {
+  core::int x = 4;
+  {
+    x = 3;
+  }
+  return x;
+}
+static method function() → core::int {
+  function varAssignmentTest2() → core::int {
+    core::int x = 2;
+    x = x.{core::num::+}(1);
+    return x;
+  }
+  return #C1;
+}
+static method varAssignmentTest3(core::int a) → core::int {
+  core::int x = 4;
+  x = a.{core::num::+}(1);
+  return x;
+}
+static method main() → void {
+  exp::Expect::equals(#C1, 3);
+  exp::Expect::equals(self::function(), 3);
+  exp::Expect::equals(#C2, 2);
+  exp::Expect::equals(#C1, 3);
+}
+
+constants  {
+  #C1 = 3
+  #C2 = 2
+}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_variable_assignments.dart.weak.outline.expect b/pkg/front_end/testcases/const_functions/const_functions_variable_assignments.dart.weak.outline.expect
new file mode 100644
index 0000000..911659e
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_variable_assignments.dart.weak.outline.expect
@@ -0,0 +1,17 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+import "package:expect/expect.dart";
+
+static const field core::int var1 = self::varAssignmentTest(1);
+static const field core::int var3 = self::varAssignmentTest3(1);
+static const field core::int var4 = self::varAssignmentTest3(2);
+static method varAssignmentTest(core::int a) → core::int
+  ;
+static method function() → core::int
+  ;
+static method varAssignmentTest3(core::int a) → core::int
+  ;
+static method main() → void
+  ;
diff --git a/pkg/front_end/testcases/const_functions/const_functions_variable_assignments.dart.weak.transformed.expect b/pkg/front_end/testcases/const_functions/const_functions_variable_assignments.dart.weak.transformed.expect
new file mode 100644
index 0000000..7107ba3
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_variable_assignments.dart.weak.transformed.expect
@@ -0,0 +1,41 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "package:expect/expect.dart" as exp;
+
+import "package:expect/expect.dart";
+
+static const field core::int var1 = #C1;
+static const field core::int var3 = #C2;
+static const field core::int var4 = #C1;
+static method varAssignmentTest(core::int a) → core::int {
+  core::int x = 4;
+  {
+    x = 3;
+  }
+  return x;
+}
+static method function() → core::int {
+  function varAssignmentTest2() → core::int {
+    core::int x = 2;
+    x = x.{core::num::+}(1);
+    return x;
+  }
+  return #C1;
+}
+static method varAssignmentTest3(core::int a) → core::int {
+  core::int x = 4;
+  x = a.{core::num::+}(1);
+  return x;
+}
+static method main() → void {
+  exp::Expect::equals(#C1, 3);
+  exp::Expect::equals(self::function(), 3);
+  exp::Expect::equals(#C2, 2);
+  exp::Expect::equals(#C1, 3);
+}
+
+constants  {
+  #C1 = 3
+  #C2 = 2
+}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_variable_declarations.dart b/pkg/front_end/testcases/const_functions/const_functions_variable_declarations.dart
new file mode 100644
index 0000000..7c1c573
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_variable_declarations.dart
@@ -0,0 +1,49 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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 creating new local variables within const functions.
+
+import "package:expect/expect.dart";
+
+const var1 = function1(1, 2);
+const var1_1 = function1(2, 2);
+int function1(int a, int b) {
+  var x = 1 + a + b;
+  return x;
+}
+
+const var2 = function2();
+String function2() {
+  dynamic x = "string";
+  return x;
+}
+
+const var3 = function3();
+int function3() {
+  var first = 2;
+  var second = 2 + first;
+  return 2 + second;
+}
+
+const var4 = function4();
+int function4() {
+  var first = 2;
+  var second = 0;
+  return first + second;
+}
+
+const var5 = function5();
+int function5() {
+  const constant = -2;
+  return constant;
+}
+
+void main() {
+  Expect.equals(var1, 4);
+  Expect.equals(var1_1, 5);
+  Expect.equals(var2, "string");
+  Expect.equals(var3, 6);
+  Expect.equals(var4, 2);
+  Expect.equals(var5, -2);
+}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_variable_declarations.dart.strong.expect b/pkg/front_end/testcases/const_functions/const_functions_variable_declarations.dart.strong.expect
new file mode 100644
index 0000000..425972a
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_variable_declarations.dart.strong.expect
@@ -0,0 +1,51 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "package:expect/expect.dart" as exp;
+
+import "package:expect/expect.dart";
+
+static const field core::int var1 = #C1;
+static const field core::int var1_1 = #C2;
+static const field core::String var2 = #C3;
+static const field core::int var3 = #C4;
+static const field core::int var4 = #C5;
+static const field core::int var5 = #C6;
+static method function1(core::int a, core::int b) → core::int {
+  core::int x = 1.{core::num::+}(a).{core::num::+}(b);
+  return x;
+}
+static method function2() → core::String {
+  dynamic x = "string";
+  return x as{TypeError,ForDynamic,ForNonNullableByDefault} core::String;
+}
+static method function3() → core::int {
+  core::int first = 2;
+  core::int second = 2.{core::num::+}(first);
+  return 2.{core::num::+}(second);
+}
+static method function4() → core::int {
+  core::int first = 2;
+  core::int second = 0;
+  return first.{core::num::+}(second);
+}
+static method function5() → core::int {
+  return #C6;
+}
+static method main() → void {
+  exp::Expect::equals(#C1, 4);
+  exp::Expect::equals(#C2, 5);
+  exp::Expect::equals(#C3, "string");
+  exp::Expect::equals(#C4, 6);
+  exp::Expect::equals(#C5, 2);
+  exp::Expect::equals(#C6, 2.{core::int::unary-}());
+}
+
+constants  {
+  #C1 = 4
+  #C2 = 5
+  #C3 = "string"
+  #C4 = 6
+  #C5 = 2
+  #C6 = -2
+}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_variable_declarations.dart.strong.transformed.expect b/pkg/front_end/testcases/const_functions/const_functions_variable_declarations.dart.strong.transformed.expect
new file mode 100644
index 0000000..9ea2e2a
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_variable_declarations.dart.strong.transformed.expect
@@ -0,0 +1,55 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "package:expect/expect.dart" as exp;
+
+import "package:expect/expect.dart";
+
+static const field core::int var1 = #C1;
+static const field core::int var1_1 = #C2;
+static const field core::String var2 = #C3;
+static const field core::int var3 = #C4;
+static const field core::int var4 = #C5;
+static const field core::int var5 = #C6;
+static method function1(core::int a, core::int b) → core::int {
+  core::int x = 1.{core::num::+}(a).{core::num::+}(b);
+  return x;
+}
+static method function2() → core::String {
+  dynamic x = "string";
+  return x as{TypeError,ForDynamic,ForNonNullableByDefault} core::String;
+}
+static method function3() → core::int {
+  core::int first = 2;
+  core::int second = 2.{core::num::+}(first);
+  return 2.{core::num::+}(second);
+}
+static method function4() → core::int {
+  core::int first = 2;
+  core::int second = 0;
+  return first.{core::num::+}(second);
+}
+static method function5() → core::int {
+  return #C6;
+}
+static method main() → void {
+  exp::Expect::equals(#C1, 4);
+  exp::Expect::equals(#C2, 5);
+  exp::Expect::equals(#C3, "string");
+  exp::Expect::equals(#C4, 6);
+  exp::Expect::equals(#C5, 2);
+  exp::Expect::equals(#C6, 2.{core::int::unary-}());
+}
+
+constants  {
+  #C1 = 4
+  #C2 = 5
+  #C3 = "string"
+  #C4 = 6
+  #C5 = 2
+  #C6 = -2
+}
+
+Extra constant evaluation status:
+Evaluated: MethodInvocation @ org-dartlang-testcase:///const_functions_variable_declarations.dart:48:23 -> IntConstant(-2)
+Extra constant evaluation: evaluated: 21, effectively constant: 1
diff --git a/pkg/front_end/testcases/const_functions/const_functions_variable_declarations.dart.textual_outline.expect b/pkg/front_end/testcases/const_functions/const_functions_variable_declarations.dart.textual_outline.expect
new file mode 100644
index 0000000..1b140e3
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_variable_declarations.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+import "package:expect/expect.dart";
+
+const var1 = function1(1, 2);
+const var1_1 = function1(2, 2);
+int function1(int a, int b) {}
+const var2 = function2();
+String function2() {}
+const var3 = function3();
+int function3() {}
+const var4 = function4();
+int function4() {}
+const var5 = function5();
+int function5() {}
+void main() {}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_variable_declarations.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/const_functions/const_functions_variable_declarations.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..7dcb573
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_variable_declarations.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+import "package:expect/expect.dart";
+
+String function2() {}
+const var1 = function1(1, 2);
+const var1_1 = function1(2, 2);
+const var2 = function2();
+const var3 = function3();
+const var4 = function4();
+const var5 = function5();
+int function1(int a, int b) {}
+int function3() {}
+int function4() {}
+int function5() {}
+void main() {}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_variable_declarations.dart.weak.expect b/pkg/front_end/testcases/const_functions/const_functions_variable_declarations.dart.weak.expect
new file mode 100644
index 0000000..425972a
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_variable_declarations.dart.weak.expect
@@ -0,0 +1,51 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "package:expect/expect.dart" as exp;
+
+import "package:expect/expect.dart";
+
+static const field core::int var1 = #C1;
+static const field core::int var1_1 = #C2;
+static const field core::String var2 = #C3;
+static const field core::int var3 = #C4;
+static const field core::int var4 = #C5;
+static const field core::int var5 = #C6;
+static method function1(core::int a, core::int b) → core::int {
+  core::int x = 1.{core::num::+}(a).{core::num::+}(b);
+  return x;
+}
+static method function2() → core::String {
+  dynamic x = "string";
+  return x as{TypeError,ForDynamic,ForNonNullableByDefault} core::String;
+}
+static method function3() → core::int {
+  core::int first = 2;
+  core::int second = 2.{core::num::+}(first);
+  return 2.{core::num::+}(second);
+}
+static method function4() → core::int {
+  core::int first = 2;
+  core::int second = 0;
+  return first.{core::num::+}(second);
+}
+static method function5() → core::int {
+  return #C6;
+}
+static method main() → void {
+  exp::Expect::equals(#C1, 4);
+  exp::Expect::equals(#C2, 5);
+  exp::Expect::equals(#C3, "string");
+  exp::Expect::equals(#C4, 6);
+  exp::Expect::equals(#C5, 2);
+  exp::Expect::equals(#C6, 2.{core::int::unary-}());
+}
+
+constants  {
+  #C1 = 4
+  #C2 = 5
+  #C3 = "string"
+  #C4 = 6
+  #C5 = 2
+  #C6 = -2
+}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_variable_declarations.dart.weak.outline.expect b/pkg/front_end/testcases/const_functions/const_functions_variable_declarations.dart.weak.outline.expect
new file mode 100644
index 0000000..f119780
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_variable_declarations.dart.weak.outline.expect
@@ -0,0 +1,24 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+import "package:expect/expect.dart";
+
+static const field core::int var1 = self::function1(1, 2);
+static const field core::int var1_1 = self::function1(2, 2);
+static const field core::String var2 = self::function2();
+static const field core::int var3 = self::function3();
+static const field core::int var4 = self::function4();
+static const field core::int var5 = self::function5();
+static method function1(core::int a, core::int b) → core::int
+  ;
+static method function2() → core::String
+  ;
+static method function3() → core::int
+  ;
+static method function4() → core::int
+  ;
+static method function5() → core::int
+  ;
+static method main() → void
+  ;
diff --git a/pkg/front_end/testcases/const_functions/const_functions_variable_declarations.dart.weak.transformed.expect b/pkg/front_end/testcases/const_functions/const_functions_variable_declarations.dart.weak.transformed.expect
new file mode 100644
index 0000000..9ea2e2a
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_variable_declarations.dart.weak.transformed.expect
@@ -0,0 +1,55 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "package:expect/expect.dart" as exp;
+
+import "package:expect/expect.dart";
+
+static const field core::int var1 = #C1;
+static const field core::int var1_1 = #C2;
+static const field core::String var2 = #C3;
+static const field core::int var3 = #C4;
+static const field core::int var4 = #C5;
+static const field core::int var5 = #C6;
+static method function1(core::int a, core::int b) → core::int {
+  core::int x = 1.{core::num::+}(a).{core::num::+}(b);
+  return x;
+}
+static method function2() → core::String {
+  dynamic x = "string";
+  return x as{TypeError,ForDynamic,ForNonNullableByDefault} core::String;
+}
+static method function3() → core::int {
+  core::int first = 2;
+  core::int second = 2.{core::num::+}(first);
+  return 2.{core::num::+}(second);
+}
+static method function4() → core::int {
+  core::int first = 2;
+  core::int second = 0;
+  return first.{core::num::+}(second);
+}
+static method function5() → core::int {
+  return #C6;
+}
+static method main() → void {
+  exp::Expect::equals(#C1, 4);
+  exp::Expect::equals(#C2, 5);
+  exp::Expect::equals(#C3, "string");
+  exp::Expect::equals(#C4, 6);
+  exp::Expect::equals(#C5, 2);
+  exp::Expect::equals(#C6, 2.{core::int::unary-}());
+}
+
+constants  {
+  #C1 = 4
+  #C2 = 5
+  #C3 = "string"
+  #C4 = 6
+  #C5 = 2
+  #C6 = -2
+}
+
+Extra constant evaluation status:
+Evaluated: MethodInvocation @ org-dartlang-testcase:///const_functions_variable_declarations.dart:48:23 -> IntConstant(-2)
+Extra constant evaluation: evaluated: 21, effectively constant: 1
diff --git a/pkg/front_end/testcases/const_functions/const_functions_while_statements.dart b/pkg/front_end/testcases/const_functions/const_functions_while_statements.dart
new file mode 100644
index 0000000..5730e6e
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_while_statements.dart
@@ -0,0 +1,91 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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 while statements for const functions.
+
+import "package:expect/expect.dart";
+
+const var1 = fn(2);
+const var2 = fn(3);
+int fn(int a) {
+  int b = a;
+  int i = 0;
+  while (i < 2) {
+    b += a;
+    i++;
+  }
+  return b;
+}
+
+const var3 = fn1(2);
+const var4 = fn1(3);
+int fn1(int a) {
+  int b = a;
+  while (true) {
+    b *= 3;
+    if (b > 10) return b;
+  }
+}
+
+const var5 = fnContinue();
+int fnContinue() {
+  int a = 0;
+  int i = 0;
+  while (i < 5) {
+    if (i % 2 == 1) {
+      i++;
+      continue;
+    }
+    a += i;
+    i++;
+  }
+  return a;
+}
+
+const var6 = fnBreak(2);
+const var7 = fnBreak(3);
+int fnBreak(int a) {
+  int b = a;
+  int i = 0;
+  while (i < 2) {
+    if (b == 2) break;
+    b += a;
+    i++;
+  }
+  return b;
+}
+
+const var8 = fnNestedWhile();
+int fnNestedWhile() {
+  int a = 0;
+  while (true) {
+    while (true) {
+      break;
+    }
+    return 1;
+  }
+}
+
+const var9 = fnBreakLabel();
+int fnBreakLabel() {
+  foo:
+  while (true) {
+    while (true) {
+      break foo;
+    }
+  }
+  return 3;
+}
+
+void main() {
+  Expect.equals(var1, 6);
+  Expect.equals(var2, 9);
+  Expect.equals(var3, 18);
+  Expect.equals(var4, 27);
+  Expect.equals(var5, 6);
+  Expect.equals(var6, 2);
+  Expect.equals(var7, 9);
+  Expect.equals(var8, 1);
+  Expect.equals(var9, 3);
+}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_while_statements.dart.strong.expect b/pkg/front_end/testcases/const_functions/const_functions_while_statements.dart.strong.expect
new file mode 100644
index 0000000..00d3c60
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_while_statements.dart.strong.expect
@@ -0,0 +1,100 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "package:expect/expect.dart" as exp;
+
+import "package:expect/expect.dart";
+
+static const field core::int var1 = #C1;
+static const field core::int var2 = #C2;
+static const field core::int var3 = #C3;
+static const field core::int var4 = #C4;
+static const field core::int var5 = #C1;
+static const field core::int var6 = #C5;
+static const field core::int var7 = #C2;
+static const field core::int var8 = #C6;
+static const field core::int var9 = #C7;
+static method fn(core::int a) → core::int {
+  core::int b = a;
+  core::int i = 0;
+  while (i.{core::num::<}(2)) {
+    b = b.{core::num::+}(a);
+    i = i.{core::num::+}(1);
+  }
+  return b;
+}
+static method fn1(core::int a) → core::int {
+  core::int b = a;
+  while (true) {
+    b = b.{core::num::*}(3);
+    if(b.{core::num::>}(10))
+      return b;
+  }
+}
+static method fnContinue() → core::int {
+  core::int a = 0;
+  core::int i = 0;
+  while (i.{core::num::<}(5))
+    #L1:
+    {
+      if(i.{core::num::%}(2).{core::num::==}(1)) {
+        i = i.{core::num::+}(1);
+        break #L1;
+      }
+      a = a.{core::num::+}(i);
+      i = i.{core::num::+}(1);
+    }
+  return a;
+}
+static method fnBreak(core::int a) → core::int {
+  core::int b = a;
+  core::int i = 0;
+  #L2:
+  while (i.{core::num::<}(2)) {
+    if(b.{core::num::==}(2))
+      break #L2;
+    b = b.{core::num::+}(a);
+    i = i.{core::num::+}(1);
+  }
+  return b;
+}
+static method fnNestedWhile() → core::int {
+  core::int a = 0;
+  while (true) {
+    #L3:
+    while (true) {
+      break #L3;
+    }
+    return 1;
+  }
+}
+static method fnBreakLabel() → core::int {
+  #L4:
+  while (true) {
+    while (true) {
+      break #L4;
+    }
+  }
+  return 3;
+}
+static method main() → void {
+  exp::Expect::equals(#C1, 6);
+  exp::Expect::equals(#C2, 9);
+  exp::Expect::equals(#C3, 18);
+  exp::Expect::equals(#C4, 27);
+  exp::Expect::equals(#C1, 6);
+  exp::Expect::equals(#C5, 2);
+  exp::Expect::equals(#C2, 9);
+  exp::Expect::equals(#C6, 1);
+  exp::Expect::equals(#C7, 3);
+}
+
+constants  {
+  #C1 = 6
+  #C2 = 9
+  #C3 = 18
+  #C4 = 27
+  #C5 = 2
+  #C6 = 1
+  #C7 = 3
+}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_while_statements.dart.strong.transformed.expect b/pkg/front_end/testcases/const_functions/const_functions_while_statements.dart.strong.transformed.expect
new file mode 100644
index 0000000..00d3c60
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_while_statements.dart.strong.transformed.expect
@@ -0,0 +1,100 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "package:expect/expect.dart" as exp;
+
+import "package:expect/expect.dart";
+
+static const field core::int var1 = #C1;
+static const field core::int var2 = #C2;
+static const field core::int var3 = #C3;
+static const field core::int var4 = #C4;
+static const field core::int var5 = #C1;
+static const field core::int var6 = #C5;
+static const field core::int var7 = #C2;
+static const field core::int var8 = #C6;
+static const field core::int var9 = #C7;
+static method fn(core::int a) → core::int {
+  core::int b = a;
+  core::int i = 0;
+  while (i.{core::num::<}(2)) {
+    b = b.{core::num::+}(a);
+    i = i.{core::num::+}(1);
+  }
+  return b;
+}
+static method fn1(core::int a) → core::int {
+  core::int b = a;
+  while (true) {
+    b = b.{core::num::*}(3);
+    if(b.{core::num::>}(10))
+      return b;
+  }
+}
+static method fnContinue() → core::int {
+  core::int a = 0;
+  core::int i = 0;
+  while (i.{core::num::<}(5))
+    #L1:
+    {
+      if(i.{core::num::%}(2).{core::num::==}(1)) {
+        i = i.{core::num::+}(1);
+        break #L1;
+      }
+      a = a.{core::num::+}(i);
+      i = i.{core::num::+}(1);
+    }
+  return a;
+}
+static method fnBreak(core::int a) → core::int {
+  core::int b = a;
+  core::int i = 0;
+  #L2:
+  while (i.{core::num::<}(2)) {
+    if(b.{core::num::==}(2))
+      break #L2;
+    b = b.{core::num::+}(a);
+    i = i.{core::num::+}(1);
+  }
+  return b;
+}
+static method fnNestedWhile() → core::int {
+  core::int a = 0;
+  while (true) {
+    #L3:
+    while (true) {
+      break #L3;
+    }
+    return 1;
+  }
+}
+static method fnBreakLabel() → core::int {
+  #L4:
+  while (true) {
+    while (true) {
+      break #L4;
+    }
+  }
+  return 3;
+}
+static method main() → void {
+  exp::Expect::equals(#C1, 6);
+  exp::Expect::equals(#C2, 9);
+  exp::Expect::equals(#C3, 18);
+  exp::Expect::equals(#C4, 27);
+  exp::Expect::equals(#C1, 6);
+  exp::Expect::equals(#C5, 2);
+  exp::Expect::equals(#C2, 9);
+  exp::Expect::equals(#C6, 1);
+  exp::Expect::equals(#C7, 3);
+}
+
+constants  {
+  #C1 = 6
+  #C2 = 9
+  #C3 = 18
+  #C4 = 27
+  #C5 = 2
+  #C6 = 1
+  #C7 = 3
+}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_while_statements.dart.textual_outline.expect b/pkg/front_end/testcases/const_functions/const_functions_while_statements.dart.textual_outline.expect
new file mode 100644
index 0000000..d7a2e9b
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_while_statements.dart.textual_outline.expect
@@ -0,0 +1,18 @@
+import "package:expect/expect.dart";
+
+const var1 = fn(2);
+const var2 = fn(3);
+int fn(int a) {}
+const var3 = fn1(2);
+const var4 = fn1(3);
+int fn1(int a) {}
+const var5 = fnContinue();
+int fnContinue() {}
+const var6 = fnBreak(2);
+const var7 = fnBreak(3);
+int fnBreak(int a) {}
+const var8 = fnNestedWhile();
+int fnNestedWhile() {}
+const var9 = fnBreakLabel();
+int fnBreakLabel() {}
+void main() {}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_while_statements.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/const_functions/const_functions_while_statements.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8134c04
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_while_statements.dart.textual_outline_modelled.expect
@@ -0,0 +1,18 @@
+import "package:expect/expect.dart";
+
+const var1 = fn(2);
+const var2 = fn(3);
+const var3 = fn1(2);
+const var4 = fn1(3);
+const var5 = fnContinue();
+const var6 = fnBreak(2);
+const var7 = fnBreak(3);
+const var8 = fnNestedWhile();
+const var9 = fnBreakLabel();
+int fn(int a) {}
+int fn1(int a) {}
+int fnBreak(int a) {}
+int fnBreakLabel() {}
+int fnContinue() {}
+int fnNestedWhile() {}
+void main() {}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_while_statements.dart.weak.expect b/pkg/front_end/testcases/const_functions/const_functions_while_statements.dart.weak.expect
new file mode 100644
index 0000000..00d3c60
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_while_statements.dart.weak.expect
@@ -0,0 +1,100 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "package:expect/expect.dart" as exp;
+
+import "package:expect/expect.dart";
+
+static const field core::int var1 = #C1;
+static const field core::int var2 = #C2;
+static const field core::int var3 = #C3;
+static const field core::int var4 = #C4;
+static const field core::int var5 = #C1;
+static const field core::int var6 = #C5;
+static const field core::int var7 = #C2;
+static const field core::int var8 = #C6;
+static const field core::int var9 = #C7;
+static method fn(core::int a) → core::int {
+  core::int b = a;
+  core::int i = 0;
+  while (i.{core::num::<}(2)) {
+    b = b.{core::num::+}(a);
+    i = i.{core::num::+}(1);
+  }
+  return b;
+}
+static method fn1(core::int a) → core::int {
+  core::int b = a;
+  while (true) {
+    b = b.{core::num::*}(3);
+    if(b.{core::num::>}(10))
+      return b;
+  }
+}
+static method fnContinue() → core::int {
+  core::int a = 0;
+  core::int i = 0;
+  while (i.{core::num::<}(5))
+    #L1:
+    {
+      if(i.{core::num::%}(2).{core::num::==}(1)) {
+        i = i.{core::num::+}(1);
+        break #L1;
+      }
+      a = a.{core::num::+}(i);
+      i = i.{core::num::+}(1);
+    }
+  return a;
+}
+static method fnBreak(core::int a) → core::int {
+  core::int b = a;
+  core::int i = 0;
+  #L2:
+  while (i.{core::num::<}(2)) {
+    if(b.{core::num::==}(2))
+      break #L2;
+    b = b.{core::num::+}(a);
+    i = i.{core::num::+}(1);
+  }
+  return b;
+}
+static method fnNestedWhile() → core::int {
+  core::int a = 0;
+  while (true) {
+    #L3:
+    while (true) {
+      break #L3;
+    }
+    return 1;
+  }
+}
+static method fnBreakLabel() → core::int {
+  #L4:
+  while (true) {
+    while (true) {
+      break #L4;
+    }
+  }
+  return 3;
+}
+static method main() → void {
+  exp::Expect::equals(#C1, 6);
+  exp::Expect::equals(#C2, 9);
+  exp::Expect::equals(#C3, 18);
+  exp::Expect::equals(#C4, 27);
+  exp::Expect::equals(#C1, 6);
+  exp::Expect::equals(#C5, 2);
+  exp::Expect::equals(#C2, 9);
+  exp::Expect::equals(#C6, 1);
+  exp::Expect::equals(#C7, 3);
+}
+
+constants  {
+  #C1 = 6
+  #C2 = 9
+  #C3 = 18
+  #C4 = 27
+  #C5 = 2
+  #C6 = 1
+  #C7 = 3
+}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_while_statements.dart.weak.outline.expect b/pkg/front_end/testcases/const_functions/const_functions_while_statements.dart.weak.outline.expect
new file mode 100644
index 0000000..8d8170d
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_while_statements.dart.weak.outline.expect
@@ -0,0 +1,29 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+import "package:expect/expect.dart";
+
+static const field core::int var1 = self::fn(2);
+static const field core::int var2 = self::fn(3);
+static const field core::int var3 = self::fn1(2);
+static const field core::int var4 = self::fn1(3);
+static const field core::int var5 = self::fnContinue();
+static const field core::int var6 = self::fnBreak(2);
+static const field core::int var7 = self::fnBreak(3);
+static const field core::int var8 = self::fnNestedWhile();
+static const field core::int var9 = self::fnBreakLabel();
+static method fn(core::int a) → core::int
+  ;
+static method fn1(core::int a) → core::int
+  ;
+static method fnContinue() → core::int
+  ;
+static method fnBreak(core::int a) → core::int
+  ;
+static method fnNestedWhile() → core::int
+  ;
+static method fnBreakLabel() → core::int
+  ;
+static method main() → void
+  ;
diff --git a/pkg/front_end/testcases/const_functions/const_functions_while_statements.dart.weak.transformed.expect b/pkg/front_end/testcases/const_functions/const_functions_while_statements.dart.weak.transformed.expect
new file mode 100644
index 0000000..00d3c60
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_while_statements.dart.weak.transformed.expect
@@ -0,0 +1,100 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "package:expect/expect.dart" as exp;
+
+import "package:expect/expect.dart";
+
+static const field core::int var1 = #C1;
+static const field core::int var2 = #C2;
+static const field core::int var3 = #C3;
+static const field core::int var4 = #C4;
+static const field core::int var5 = #C1;
+static const field core::int var6 = #C5;
+static const field core::int var7 = #C2;
+static const field core::int var8 = #C6;
+static const field core::int var9 = #C7;
+static method fn(core::int a) → core::int {
+  core::int b = a;
+  core::int i = 0;
+  while (i.{core::num::<}(2)) {
+    b = b.{core::num::+}(a);
+    i = i.{core::num::+}(1);
+  }
+  return b;
+}
+static method fn1(core::int a) → core::int {
+  core::int b = a;
+  while (true) {
+    b = b.{core::num::*}(3);
+    if(b.{core::num::>}(10))
+      return b;
+  }
+}
+static method fnContinue() → core::int {
+  core::int a = 0;
+  core::int i = 0;
+  while (i.{core::num::<}(5))
+    #L1:
+    {
+      if(i.{core::num::%}(2).{core::num::==}(1)) {
+        i = i.{core::num::+}(1);
+        break #L1;
+      }
+      a = a.{core::num::+}(i);
+      i = i.{core::num::+}(1);
+    }
+  return a;
+}
+static method fnBreak(core::int a) → core::int {
+  core::int b = a;
+  core::int i = 0;
+  #L2:
+  while (i.{core::num::<}(2)) {
+    if(b.{core::num::==}(2))
+      break #L2;
+    b = b.{core::num::+}(a);
+    i = i.{core::num::+}(1);
+  }
+  return b;
+}
+static method fnNestedWhile() → core::int {
+  core::int a = 0;
+  while (true) {
+    #L3:
+    while (true) {
+      break #L3;
+    }
+    return 1;
+  }
+}
+static method fnBreakLabel() → core::int {
+  #L4:
+  while (true) {
+    while (true) {
+      break #L4;
+    }
+  }
+  return 3;
+}
+static method main() → void {
+  exp::Expect::equals(#C1, 6);
+  exp::Expect::equals(#C2, 9);
+  exp::Expect::equals(#C3, 18);
+  exp::Expect::equals(#C4, 27);
+  exp::Expect::equals(#C1, 6);
+  exp::Expect::equals(#C5, 2);
+  exp::Expect::equals(#C2, 9);
+  exp::Expect::equals(#C6, 1);
+  exp::Expect::equals(#C7, 3);
+}
+
+constants  {
+  #C1 = 6
+  #C2 = 9
+  #C3 = 18
+  #C4 = 27
+  #C5 = 2
+  #C6 = 1
+  #C7 = 3
+}
diff --git a/pkg/front_end/testcases/dart2js/instance_getter_invocation.dart b/pkg/front_end/testcases/dart2js/instance_getter_invocation.dart
new file mode 100644
index 0000000..1ef505e
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/instance_getter_invocation.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+T id<T>(T t) => t;
+
+class Class {
+  S Function<S>(S) get idFunction => id;
+  dynamic get dynFunction => id;
+}
+
+main() {
+  Class c = new Class();
+  c.idFunction(0);
+  c.idFunction<int>(0);
+  c.dynFunction(0);
+}
diff --git a/pkg/front_end/testcases/dart2js/instance_getter_invocation.dart.strong.expect b/pkg/front_end/testcases/dart2js/instance_getter_invocation.dart.strong.expect
new file mode 100644
index 0000000..e29a84e
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/instance_getter_invocation.dart.strong.expect
@@ -0,0 +1,25 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  synthetic constructor •() → self::Class
+    : super core::Object::•()
+    ;
+  get idFunction() → <S extends core::Object? = dynamic>(S%) → S%
+    return #C1;
+  get dynFunction() → dynamic
+    return #C1;
+}
+static method id<T extends core::Object? = dynamic>(self::id::T% t) → self::id::T%
+  return t;
+static method main() → dynamic {
+  self::Class c = new self::Class::•();
+  let final self::Class #t1 = c in let final core::int #t2 = 0 in #t1.{self::Class::idFunction}<core::int>(#t2){(core::int) → core::int};
+  let final self::Class #t3 = c in let final core::int #t4 = 0 in #t3.{self::Class::idFunction}<core::int>(#t4){(core::int) → core::int};
+  let final self::Class #t5 = c in let final core::int #t6 = 0 in #t5.{self::Class::dynFunction}(#t6);
+}
+
+constants  {
+  #C1 = tearoff self::id
+}
diff --git a/pkg/front_end/testcases/dart2js/instance_getter_invocation.dart.strong.transformed.expect b/pkg/front_end/testcases/dart2js/instance_getter_invocation.dart.strong.transformed.expect
new file mode 100644
index 0000000..6a431a4
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/instance_getter_invocation.dart.strong.transformed.expect
@@ -0,0 +1,31 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  synthetic constructor •() → self::Class
+    : super core::Object::•()
+    ;
+  get idFunction() → <S extends core::Object? = dynamic>(S%) → S%
+    return #C1;
+  get dynFunction() → dynamic
+    return #C1;
+}
+static method id<T extends core::Object? = dynamic>(self::id::T% t) → self::id::T%
+  return t;
+static method main() → dynamic {
+  self::Class c = new self::Class::•();
+  let final self::Class #t1 = c in let final core::int #t2 = 0 in #t1.{self::Class::idFunction}<core::int>(#t2){(core::int) → core::int};
+  let final self::Class #t3 = c in let final core::int #t4 = 0 in #t3.{self::Class::idFunction}<core::int>(#t4){(core::int) → core::int};
+  let final self::Class #t5 = c in let final core::int #t6 = 0 in #t5.{self::Class::dynFunction}(#t6);
+}
+
+constants  {
+  #C1 = tearoff self::id
+}
+
+Extra constant evaluation status:
+Evaluated: VariableGet @ org-dartlang-testcase:///instance_getter_invocation.dart:14:16 -> DoubleConstant(0.0)
+Evaluated: VariableGet @ org-dartlang-testcase:///instance_getter_invocation.dart:15:21 -> DoubleConstant(0.0)
+Evaluated: VariableGet @ org-dartlang-testcase:///instance_getter_invocation.dart:16:17 -> DoubleConstant(0.0)
+Extra constant evaluation: evaluated: 20, effectively constant: 3
diff --git a/pkg/front_end/testcases/dart2js/instance_getter_invocation.dart.textual_outline.expect b/pkg/front_end/testcases/dart2js/instance_getter_invocation.dart.textual_outline.expect
new file mode 100644
index 0000000..9cd1271
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/instance_getter_invocation.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+T id<T>(T t) => t;
+
+class Class {
+  S Function<S>(S) get idFunction => id;
+  dynamic get dynFunction => id;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/dart2js/instance_getter_invocation.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/dart2js/instance_getter_invocation.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9cd1271
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/instance_getter_invocation.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+T id<T>(T t) => t;
+
+class Class {
+  S Function<S>(S) get idFunction => id;
+  dynamic get dynFunction => id;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/dart2js/instance_getter_invocation.dart.weak.expect b/pkg/front_end/testcases/dart2js/instance_getter_invocation.dart.weak.expect
new file mode 100644
index 0000000..e29a84e
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/instance_getter_invocation.dart.weak.expect
@@ -0,0 +1,25 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  synthetic constructor •() → self::Class
+    : super core::Object::•()
+    ;
+  get idFunction() → <S extends core::Object? = dynamic>(S%) → S%
+    return #C1;
+  get dynFunction() → dynamic
+    return #C1;
+}
+static method id<T extends core::Object? = dynamic>(self::id::T% t) → self::id::T%
+  return t;
+static method main() → dynamic {
+  self::Class c = new self::Class::•();
+  let final self::Class #t1 = c in let final core::int #t2 = 0 in #t1.{self::Class::idFunction}<core::int>(#t2){(core::int) → core::int};
+  let final self::Class #t3 = c in let final core::int #t4 = 0 in #t3.{self::Class::idFunction}<core::int>(#t4){(core::int) → core::int};
+  let final self::Class #t5 = c in let final core::int #t6 = 0 in #t5.{self::Class::dynFunction}(#t6);
+}
+
+constants  {
+  #C1 = tearoff self::id
+}
diff --git a/pkg/front_end/testcases/dart2js/instance_getter_invocation.dart.weak.outline.expect b/pkg/front_end/testcases/dart2js/instance_getter_invocation.dart.weak.outline.expect
new file mode 100644
index 0000000..85f75fa
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/instance_getter_invocation.dart.weak.outline.expect
@@ -0,0 +1,16 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  synthetic constructor •() → self::Class
+    ;
+  get idFunction() → <S extends core::Object? = dynamic>(S%) → S%
+    ;
+  get dynFunction() → dynamic
+    ;
+}
+static method id<T extends core::Object? = dynamic>(self::id::T% t) → self::id::T%
+  ;
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/dart2js/instance_getter_invocation.dart.weak.transformed.expect b/pkg/front_end/testcases/dart2js/instance_getter_invocation.dart.weak.transformed.expect
new file mode 100644
index 0000000..6a431a4
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/instance_getter_invocation.dart.weak.transformed.expect
@@ -0,0 +1,31 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  synthetic constructor •() → self::Class
+    : super core::Object::•()
+    ;
+  get idFunction() → <S extends core::Object? = dynamic>(S%) → S%
+    return #C1;
+  get dynFunction() → dynamic
+    return #C1;
+}
+static method id<T extends core::Object? = dynamic>(self::id::T% t) → self::id::T%
+  return t;
+static method main() → dynamic {
+  self::Class c = new self::Class::•();
+  let final self::Class #t1 = c in let final core::int #t2 = 0 in #t1.{self::Class::idFunction}<core::int>(#t2){(core::int) → core::int};
+  let final self::Class #t3 = c in let final core::int #t4 = 0 in #t3.{self::Class::idFunction}<core::int>(#t4){(core::int) → core::int};
+  let final self::Class #t5 = c in let final core::int #t6 = 0 in #t5.{self::Class::dynFunction}(#t6);
+}
+
+constants  {
+  #C1 = tearoff self::id
+}
+
+Extra constant evaluation status:
+Evaluated: VariableGet @ org-dartlang-testcase:///instance_getter_invocation.dart:14:16 -> DoubleConstant(0.0)
+Evaluated: VariableGet @ org-dartlang-testcase:///instance_getter_invocation.dart:15:21 -> DoubleConstant(0.0)
+Evaluated: VariableGet @ org-dartlang-testcase:///instance_getter_invocation.dart:16:17 -> DoubleConstant(0.0)
+Extra constant evaluation: evaluated: 20, effectively constant: 3
diff --git a/pkg/front_end/testcases/dart2js/late_fields.dart b/pkg/front_end/testcases/dart2js/late_fields.dart
new file mode 100644
index 0000000..ea3012b
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/late_fields.dart
@@ -0,0 +1,41 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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() {
+  testUninitializedNonFinalInstanceField();
+  testUninitializedFinalInstanceField();
+  testInitializedNonFinalInstanceField();
+  testInitializedFinalInstanceField();
+}
+
+class C {
+  late int a;
+  late final int b;
+  late int c = -1;
+  late final int d = -1;
+}
+
+var c = C();
+
+void testUninitializedNonFinalInstanceField() {
+  print(c.a);
+  c.a = 42;
+  print(c.a);
+}
+
+void testUninitializedFinalInstanceField() {
+  print(c.b);
+  c.b = 42;
+  print(c.b);
+}
+
+void testInitializedNonFinalInstanceField() {
+  print(c.c);
+  c.c = 42;
+  print(c.c);
+}
+
+void testInitializedFinalInstanceField() {
+  print(c.d);
+}
diff --git a/pkg/front_end/testcases/dart2js/late_fields.dart.strong.expect b/pkg/front_end/testcases/dart2js/late_fields.dart.strong.expect
new file mode 100644
index 0000000..cf590d6
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/late_fields.dart.strong.expect
@@ -0,0 +1,56 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:_internal" as _in;
+
+class C extends core::Object {
+  field core::int? _#C#a = null;
+  field core::int? _#C#b = null;
+  field core::int? _#C#c = null;
+  field core::int? _#C#d = null;
+  synthetic constructor •() → self::C
+    : super core::Object::•()
+    ;
+  get a() → core::int
+    return let final core::int? #t1 = this.{self::C::_#C#a} in #t1 == null ?{core::int} throw new _in::LateError::fieldNI("a") : #t1{core::int};
+  set a(core::int #t2) → void
+    this.{self::C::_#C#a} = #t2;
+  get b() → core::int
+    return let final core::int? #t3 = this.{self::C::_#C#b} in #t3 == null ?{core::int} throw new _in::LateError::fieldNI("b") : #t3{core::int};
+  set b(core::int #t4) → void
+    if(this.{self::C::_#C#b} == null)
+      this.{self::C::_#C#b} = #t4;
+    else
+      throw new _in::LateError::fieldAI("b");
+  get c() → core::int
+    return let final core::int? #t5 = this.{self::C::_#C#c} in #t5 == null ?{core::int} this.{self::C::_#C#c} = 1.{core::int::unary-}(){() → core::int} : #t5{core::int};
+  set c(core::int #t6) → void
+    this.{self::C::_#C#c} = #t6;
+  get d() → core::int
+    return let final core::int? #t7 = this.{self::C::_#C#d} in #t7 == null ?{core::int} let final core::int #t8 = 1.{core::int::unary-}(){() → core::int} in this.{self::C::_#C#d} == null ?{core::int} this.{self::C::_#C#d} = #t8 : throw new _in::LateError::fieldADI("d") : #t7{core::int};
+}
+static field self::C c = new self::C::•();
+static method main() → void {
+  self::testUninitializedNonFinalInstanceField();
+  self::testUninitializedFinalInstanceField();
+  self::testInitializedNonFinalInstanceField();
+  self::testInitializedFinalInstanceField();
+}
+static method testUninitializedNonFinalInstanceField() → void {
+  core::print(self::c.{self::C::a}{core::int});
+  self::c.{self::C::a} = 42;
+  core::print(self::c.{self::C::a}{core::int});
+}
+static method testUninitializedFinalInstanceField() → void {
+  core::print(self::c.{self::C::b}{core::int});
+  self::c.{self::C::b} = 42;
+  core::print(self::c.{self::C::b}{core::int});
+}
+static method testInitializedNonFinalInstanceField() → void {
+  core::print(self::c.{self::C::c}{core::int});
+  self::c.{self::C::c} = 42;
+  core::print(self::c.{self::C::c}{core::int});
+}
+static method testInitializedFinalInstanceField() → void {
+  core::print(self::c.{self::C::d}{core::int});
+}
diff --git a/pkg/front_end/testcases/dart2js/late_fields.dart.strong.transformed.expect b/pkg/front_end/testcases/dart2js/late_fields.dart.strong.transformed.expect
new file mode 100644
index 0000000..9b256e1
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/late_fields.dart.strong.transformed.expect
@@ -0,0 +1,63 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:_internal" as _in;
+
+class C extends core::Object {
+  field core::int? _#C#a = null;
+  field core::int? _#C#b = null;
+  field core::int? _#C#c = null;
+  field core::int? _#C#d = null;
+  synthetic constructor •() → self::C
+    : super core::Object::•()
+    ;
+  get a() → core::int
+    return let final core::int? #t1 = this.{self::C::_#C#a} in #t1 == null ?{core::int} throw new _in::LateError::fieldNI("a") : #t1{core::int};
+  set a(core::int #t2) → void
+    this.{self::C::_#C#a} = #t2;
+  get b() → core::int
+    return let final core::int? #t3 = this.{self::C::_#C#b} in #t3 == null ?{core::int} throw new _in::LateError::fieldNI("b") : #t3{core::int};
+  set b(core::int #t4) → void
+    if(this.{self::C::_#C#b} == null)
+      this.{self::C::_#C#b} = #t4;
+    else
+      throw new _in::LateError::fieldAI("b");
+  get c() → core::int
+    return let final core::int? #t5 = this.{self::C::_#C#c} in #t5 == null ?{core::int} this.{self::C::_#C#c} = 1.{core::int::unary-}(){() → core::int} : #t5{core::int};
+  set c(core::int #t6) → void
+    this.{self::C::_#C#c} = #t6;
+  get d() → core::int
+    return let final core::int? #t7 = this.{self::C::_#C#d} in #t7 == null ?{core::int} let final core::int #t8 = 1.{core::int::unary-}(){() → core::int} in this.{self::C::_#C#d} == null ?{core::int} this.{self::C::_#C#d} = #t8 : throw new _in::LateError::fieldADI("d") : #t7{core::int};
+}
+static field self::C c = new self::C::•();
+static method main() → void {
+  self::testUninitializedNonFinalInstanceField();
+  self::testUninitializedFinalInstanceField();
+  self::testInitializedNonFinalInstanceField();
+  self::testInitializedFinalInstanceField();
+}
+static method testUninitializedNonFinalInstanceField() → void {
+  core::print(self::c.{self::C::a}{core::int});
+  self::c.{self::C::a} = 42;
+  core::print(self::c.{self::C::a}{core::int});
+}
+static method testUninitializedFinalInstanceField() → void {
+  core::print(self::c.{self::C::b}{core::int});
+  self::c.{self::C::b} = 42;
+  core::print(self::c.{self::C::b}{core::int});
+}
+static method testInitializedNonFinalInstanceField() → void {
+  core::print(self::c.{self::C::c}{core::int});
+  self::c.{self::C::c} = 42;
+  core::print(self::c.{self::C::c}{core::int});
+}
+static method testInitializedFinalInstanceField() → void {
+  core::print(self::c.{self::C::d}{core::int});
+}
+
+
+Extra constant evaluation status:
+Evaluated: InstanceInvocation @ org-dartlang-testcase:///late_fields.dart:15:16 -> DoubleConstant(-1.0)
+Evaluated: InstanceInvocation @ org-dartlang-testcase:///late_fields.dart:16:22 -> DoubleConstant(-1.0)
+Evaluated: VariableGet @ org-dartlang-testcase:///late_fields.dart:16:18 -> DoubleConstant(-1.0)
+Extra constant evaluation: evaluated: 92, effectively constant: 3
diff --git a/pkg/front_end/testcases/dart2js/late_fields.dart.textual_outline.expect b/pkg/front_end/testcases/dart2js/late_fields.dart.textual_outline.expect
new file mode 100644
index 0000000..7f4885f
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/late_fields.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+void main() {}
+
+class C {
+  late int a;
+  late final int b;
+  late int c = -1;
+  late final int d = -1;
+}
+
+var c = C();
+void testUninitializedNonFinalInstanceField() {}
+void testUninitializedFinalInstanceField() {}
+void testInitializedNonFinalInstanceField() {}
+void testInitializedFinalInstanceField() {}
diff --git a/pkg/front_end/testcases/dart2js/late_fields.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/dart2js/late_fields.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..79b904b
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/late_fields.dart.textual_outline_modelled.expect
@@ -0,0 +1,24 @@
+class C {
+  ---- unknown chunk starts ----
+late
+---- unknown chunk ends ----
+  int a;
+  ---- unknown chunk starts ----
+late
+---- unknown chunk ends ----
+  final int b;
+  ---- unknown chunk starts ----
+late
+---- unknown chunk ends ----
+  int c = -1;
+  ---- unknown chunk starts ----
+late
+---- unknown chunk ends ----
+  final int d = -1;
+}
+var c = C();
+void main() {}
+void testInitializedFinalInstanceField() {}
+void testInitializedNonFinalInstanceField() {}
+void testUninitializedFinalInstanceField() {}
+void testUninitializedNonFinalInstanceField() {}
diff --git a/pkg/front_end/testcases/dart2js/late_fields.dart.weak.expect b/pkg/front_end/testcases/dart2js/late_fields.dart.weak.expect
new file mode 100644
index 0000000..9b589dc
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/late_fields.dart.weak.expect
@@ -0,0 +1,56 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:_internal" as _in;
+
+class C extends core::Object {
+  field core::int? _#C#a = _in::createSentinel<core::int>();
+  field core::int? _#C#b = _in::createSentinel<core::int>();
+  field core::int? _#C#c = _in::createSentinel<core::int>();
+  field core::int? _#C#d = _in::createSentinel<core::int>();
+  synthetic constructor •() → self::C
+    : super core::Object::•()
+    ;
+  get a() → core::int
+    return let final core::int? #t1 = this.{self::C::_#C#a} in _in::isSentinel(#t1) ?{core::int} throw new _in::LateError::fieldNI("a") : #t1{core::int};
+  set a(core::int #t2) → void
+    this.{self::C::_#C#a} = #t2;
+  get b() → core::int
+    return let final core::int? #t3 = this.{self::C::_#C#b} in _in::isSentinel(#t3) ?{core::int} throw new _in::LateError::fieldNI("b") : #t3{core::int};
+  set b(core::int #t4) → void
+    if(_in::isSentinel(this.{self::C::_#C#b}))
+      this.{self::C::_#C#b} = #t4;
+    else
+      throw new _in::LateError::fieldAI("b");
+  get c() → core::int
+    return let final core::int? #t5 = this.{self::C::_#C#c} in _in::isSentinel(#t5) ?{core::int} this.{self::C::_#C#c} = 1.{core::int::unary-}(){() → core::int} : #t5{core::int};
+  set c(core::int #t6) → void
+    this.{self::C::_#C#c} = #t6;
+  get d() → core::int
+    return let final core::int #t7 = this.{self::C::_#C#d} in _in::isSentinel(#t7) ?{core::int} let final core::int #t8 = 1.{core::int::unary-}(){() → core::int} in _in::isSentinel(this.{self::C::_#C#d}) ?{core::int} this.{self::C::_#C#d} = #t8 : throw new _in::LateError::fieldADI("d") : #t7;
+}
+static field self::C c = new self::C::•();
+static method main() → void {
+  self::testUninitializedNonFinalInstanceField();
+  self::testUninitializedFinalInstanceField();
+  self::testInitializedNonFinalInstanceField();
+  self::testInitializedFinalInstanceField();
+}
+static method testUninitializedNonFinalInstanceField() → void {
+  core::print(self::c.{self::C::a}{core::int});
+  self::c.{self::C::a} = 42;
+  core::print(self::c.{self::C::a}{core::int});
+}
+static method testUninitializedFinalInstanceField() → void {
+  core::print(self::c.{self::C::b}{core::int});
+  self::c.{self::C::b} = 42;
+  core::print(self::c.{self::C::b}{core::int});
+}
+static method testInitializedNonFinalInstanceField() → void {
+  core::print(self::c.{self::C::c}{core::int});
+  self::c.{self::C::c} = 42;
+  core::print(self::c.{self::C::c}{core::int});
+}
+static method testInitializedFinalInstanceField() → void {
+  core::print(self::c.{self::C::d}{core::int});
+}
diff --git a/pkg/front_end/testcases/dart2js/late_fields.dart.weak.outline.expect b/pkg/front_end/testcases/dart2js/late_fields.dart.weak.outline.expect
new file mode 100644
index 0000000..09228574
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/late_fields.dart.weak.outline.expect
@@ -0,0 +1,30 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  field core::int? _#C#a;
+  field core::int? _#C#b;
+  field core::int? _#C#c;
+  field core::int? _#C#d;
+  synthetic constructor •() → self::C
+    ;
+  get a() → core::int;
+  set a(core::int #t1) → void;
+  get b() → core::int;
+  set b(core::int #t2) → void;
+  get c() → core::int;
+  set c(core::int #t3) → void;
+  get d() → core::int;
+}
+static field self::C c;
+static method main() → void
+  ;
+static method testUninitializedNonFinalInstanceField() → void
+  ;
+static method testUninitializedFinalInstanceField() → void
+  ;
+static method testInitializedNonFinalInstanceField() → void
+  ;
+static method testInitializedFinalInstanceField() → void
+  ;
diff --git a/pkg/front_end/testcases/dart2js/late_fields.dart.weak.transformed.expect b/pkg/front_end/testcases/dart2js/late_fields.dart.weak.transformed.expect
new file mode 100644
index 0000000..46bb69b
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/late_fields.dart.weak.transformed.expect
@@ -0,0 +1,63 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:_internal" as _in;
+
+class C extends core::Object {
+  field core::int? _#C#a = _in::createSentinel<core::int>();
+  field core::int? _#C#b = _in::createSentinel<core::int>();
+  field core::int? _#C#c = _in::createSentinel<core::int>();
+  field core::int? _#C#d = _in::createSentinel<core::int>();
+  synthetic constructor •() → self::C
+    : super core::Object::•()
+    ;
+  get a() → core::int
+    return let final core::int? #t1 = this.{self::C::_#C#a} in _in::isSentinel(#t1) ?{core::int} throw new _in::LateError::fieldNI("a") : #t1{core::int};
+  set a(core::int #t2) → void
+    this.{self::C::_#C#a} = #t2;
+  get b() → core::int
+    return let final core::int? #t3 = this.{self::C::_#C#b} in _in::isSentinel(#t3) ?{core::int} throw new _in::LateError::fieldNI("b") : #t3{core::int};
+  set b(core::int #t4) → void
+    if(_in::isSentinel(this.{self::C::_#C#b}))
+      this.{self::C::_#C#b} = #t4;
+    else
+      throw new _in::LateError::fieldAI("b");
+  get c() → core::int
+    return let final core::int? #t5 = this.{self::C::_#C#c} in _in::isSentinel(#t5) ?{core::int} this.{self::C::_#C#c} = 1.{core::int::unary-}(){() → core::int} : #t5{core::int};
+  set c(core::int #t6) → void
+    this.{self::C::_#C#c} = #t6;
+  get d() → core::int
+    return let final core::int #t7 = this.{self::C::_#C#d} in _in::isSentinel(#t7) ?{core::int} let final core::int #t8 = 1.{core::int::unary-}(){() → core::int} in _in::isSentinel(this.{self::C::_#C#d}) ?{core::int} this.{self::C::_#C#d} = #t8 : throw new _in::LateError::fieldADI("d") : #t7;
+}
+static field self::C c = new self::C::•();
+static method main() → void {
+  self::testUninitializedNonFinalInstanceField();
+  self::testUninitializedFinalInstanceField();
+  self::testInitializedNonFinalInstanceField();
+  self::testInitializedFinalInstanceField();
+}
+static method testUninitializedNonFinalInstanceField() → void {
+  core::print(self::c.{self::C::a}{core::int});
+  self::c.{self::C::a} = 42;
+  core::print(self::c.{self::C::a}{core::int});
+}
+static method testUninitializedFinalInstanceField() → void {
+  core::print(self::c.{self::C::b}{core::int});
+  self::c.{self::C::b} = 42;
+  core::print(self::c.{self::C::b}{core::int});
+}
+static method testInitializedNonFinalInstanceField() → void {
+  core::print(self::c.{self::C::c}{core::int});
+  self::c.{self::C::c} = 42;
+  core::print(self::c.{self::C::c}{core::int});
+}
+static method testInitializedFinalInstanceField() → void {
+  core::print(self::c.{self::C::d}{core::int});
+}
+
+
+Extra constant evaluation status:
+Evaluated: InstanceInvocation @ org-dartlang-testcase:///late_fields.dart:15:16 -> DoubleConstant(-1.0)
+Evaluated: InstanceInvocation @ org-dartlang-testcase:///late_fields.dart:16:22 -> DoubleConstant(-1.0)
+Evaluated: VariableGet @ org-dartlang-testcase:///late_fields.dart:16:18 -> DoubleConstant(-1.0)
+Extra constant evaluation: evaluated: 96, effectively constant: 3
diff --git a/pkg/front_end/testcases/dart2js/late_locals.dart b/pkg/front_end/testcases/dart2js/late_locals.dart
new file mode 100644
index 0000000..8065042
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/late_locals.dart
@@ -0,0 +1,70 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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() {
+  testNullableUninitializedNonFinalLocal();
+  testNonNullableUninitializedNonFinalLocal();
+  testNullableUninitializedFinalLocal();
+  testNonNullableUninitializedFinalLocal();
+  testNullableInitializedNonFinalLocal();
+  testNonNullableInitializedNonFinalLocal();
+  testNullableInitializedFinalLocal();
+  testNonNullableInitializedFinalLocal();
+}
+
+void testNullableUninitializedNonFinalLocal() {
+  late int? x;
+  x = 42;
+  print(x);
+}
+
+void testNonNullableUninitializedNonFinalLocal() {
+  late int x;
+  x = 42;
+  print(x);
+}
+
+void testNullableUninitializedFinalLocal() {
+  late final int? x;
+  x = 42;
+  print(x);
+}
+
+void testNonNullableUninitializedFinalLocal() {
+  late final int x;
+  x = 42;
+  print(x);
+}
+
+void testNullableInitializedNonFinalLocal() {
+  late int? x = -1;
+  print(x);
+  x = 42;
+  print(x);
+
+  late int? y = null;
+  print(y);
+  y = 42;
+  print(y);
+}
+
+void testNonNullableInitializedNonFinalLocal() {
+  late int x = -1;
+  print(x);
+  x = 42;
+  print(x);
+}
+
+void testNullableInitializedFinalLocal() {
+  late final int? x = -1;
+  print(x);
+
+  late final int? y = null;
+  print(y);
+}
+
+void testNonNullableInitializedFinalLocal() {
+  late final int x = -1;
+  print(x);
+}
diff --git a/pkg/front_end/testcases/dart2js/late_locals.dart.strong.expect b/pkg/front_end/testcases/dart2js/late_locals.dart.strong.expect
new file mode 100644
index 0000000..fe43261
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/late_locals.dart.strong.expect
@@ -0,0 +1,101 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:_internal" as _in;
+
+static method main() → void {
+  self::testNullableUninitializedNonFinalLocal();
+  self::testNonNullableUninitializedNonFinalLocal();
+  self::testNullableUninitializedFinalLocal();
+  self::testNonNullableUninitializedFinalLocal();
+  self::testNullableInitializedNonFinalLocal();
+  self::testNonNullableInitializedNonFinalLocal();
+  self::testNullableInitializedFinalLocal();
+  self::testNonNullableInitializedFinalLocal();
+}
+static method testNullableUninitializedNonFinalLocal() → void {
+  lowered core::int? #x = _in::createSentinel<core::int?>();
+  function #x#get() → core::int?
+    return let final core::int? #t1 = #x in _in::isSentinel(#t1) ?{core::int?} throw new _in::LateError::localNI("x") : #t1{core::int?};
+  function #x#set(core::int? #t2) → dynamic
+    return #x = #t2;
+  #x#set(42){(core::int?) → dynamic};
+  core::print(#x#get(){() → core::int?});
+}
+static method testNonNullableUninitializedNonFinalLocal() → void {
+  lowered core::int? #x;
+  function #x#get() → core::int
+    return let final core::int? #t3 = #x in #t3 == null ?{core::int} throw new _in::LateError::localNI("x") : #t3{core::int};
+  function #x#set(core::int #t4) → dynamic
+    return #x = #t4;
+  #x#set(42){(core::int) → dynamic};
+  core::print(#x#get(){() → core::int});
+}
+static method testNullableUninitializedFinalLocal() → void {
+  lowered final core::int? #x = _in::createSentinel<core::int?>();
+  function #x#get() → core::int?
+    return let final core::int? #t5 = #x in _in::isSentinel(#t5) ?{core::int?} throw new _in::LateError::localNI("x") : #t5{core::int?};
+  function #x#set(core::int? #t6) → dynamic
+    if(_in::isSentinel(#x))
+      return #x = #t6;
+    else
+      throw new _in::LateError::localAI("x");
+  #x#set(42){(core::int?) → dynamic};
+  core::print(#x#get(){() → core::int?});
+}
+static method testNonNullableUninitializedFinalLocal() → void {
+  lowered final core::int? #x;
+  function #x#get() → core::int
+    return let final core::int? #t7 = #x in #t7 == null ?{core::int} throw new _in::LateError::localNI("x") : #t7{core::int};
+  function #x#set(core::int #t8) → dynamic
+    if(#x == null)
+      return #x = #t8;
+    else
+      throw new _in::LateError::localAI("x");
+  #x#set(42){(core::int) → dynamic};
+  core::print(#x#get(){() → core::int});
+}
+static method testNullableInitializedNonFinalLocal() → void {
+  lowered core::int? #x = _in::createSentinel<core::int?>();
+  function #x#get() → core::int?
+    return let final core::int? #t9 = #x in _in::isSentinel(#t9) ?{core::int?} #x = 1.{core::int::unary-}(){() → core::int} : #t9{core::int?};
+  function #x#set(core::int? #t10) → dynamic
+    return #x = #t10;
+  core::print(#x#get(){() → core::int?});
+  #x#set(42){(core::int?) → dynamic};
+  core::print(#x#get(){() → core::int?});
+  lowered core::int? #y = _in::createSentinel<core::int?>();
+  function #y#get() → core::int?
+    return let final core::int? #t11 = #y in _in::isSentinel(#t11) ?{core::int?} #y = null : #t11{core::int?};
+  function #y#set(core::int? #t12) → dynamic
+    return #y = #t12;
+  core::print(#y#get(){() → core::int?});
+  #y#set(42){(core::int?) → dynamic};
+  core::print(#y#get(){() → core::int?});
+}
+static method testNonNullableInitializedNonFinalLocal() → void {
+  lowered core::int? #x;
+  function #x#get() → core::int
+    return let final core::int? #t13 = #x in #t13 == null ?{core::int} #x = 1.{core::int::unary-}(){() → core::int} : #t13{core::int};
+  function #x#set(core::int #t14) → dynamic
+    return #x = #t14;
+  core::print(#x#get(){() → core::int});
+  #x#set(42){(core::int) → dynamic};
+  core::print(#x#get(){() → core::int});
+}
+static method testNullableInitializedFinalLocal() → void {
+  lowered final core::int? #x = _in::createSentinel<core::int?>();
+  function #x#get() → core::int?
+    return let final core::int? #t15 = #x in _in::isSentinel(#t15) ?{core::int?} let final core::int? #t16 = 1.{core::int::unary-}(){() → core::int} in _in::isSentinel(#x) ?{core::int?} #x = #t16 : throw new _in::LateError::localADI("x") : #t15;
+  core::print(#x#get(){() → core::int?});
+  lowered final core::int? #y = _in::createSentinel<core::int?>();
+  function #y#get() → core::int?
+    return let final core::int? #t17 = #y in _in::isSentinel(#t17) ?{core::int?} let final core::int? #t18 = null in _in::isSentinel(#y) ?{core::int?} #y = #t18 : throw new _in::LateError::localADI("y") : #t17;
+  core::print(#y#get(){() → core::int?});
+}
+static method testNonNullableInitializedFinalLocal() → void {
+  lowered final core::int? #x;
+  function #x#get() → core::int
+    return let final core::int? #t19 = #x in #t19 == null ?{core::int} let final core::int #t20 = 1.{core::int::unary-}(){() → core::int} in #x == null ?{core::int} #x = #t20 : throw new _in::LateError::localADI("x") : #t19{core::int};
+  core::print(#x#get(){() → core::int});
+}
diff --git a/pkg/front_end/testcases/dart2js/late_locals.dart.strong.transformed.expect b/pkg/front_end/testcases/dart2js/late_locals.dart.strong.transformed.expect
new file mode 100644
index 0000000..ac86677
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/late_locals.dart.strong.transformed.expect
@@ -0,0 +1,112 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:_internal" as _in;
+
+static method main() → void {
+  self::testNullableUninitializedNonFinalLocal();
+  self::testNonNullableUninitializedNonFinalLocal();
+  self::testNullableUninitializedFinalLocal();
+  self::testNonNullableUninitializedFinalLocal();
+  self::testNullableInitializedNonFinalLocal();
+  self::testNonNullableInitializedNonFinalLocal();
+  self::testNullableInitializedFinalLocal();
+  self::testNonNullableInitializedFinalLocal();
+}
+static method testNullableUninitializedNonFinalLocal() → void {
+  lowered core::int? #x = _in::createSentinel<core::int?>();
+  function #x#get() → core::int?
+    return let final core::int? #t1 = #x in _in::isSentinel(#t1) ?{core::int?} throw new _in::LateError::localNI("x") : #t1{core::int?};
+  function #x#set(core::int? #t2) → dynamic
+    return #x = #t2;
+  #x#set(42){(core::int?) → dynamic};
+  core::print(#x#get(){() → core::int?});
+}
+static method testNonNullableUninitializedNonFinalLocal() → void {
+  lowered core::int? #x;
+  function #x#get() → core::int
+    return let final core::int? #t3 = #x in #t3 == null ?{core::int} throw new _in::LateError::localNI("x") : #t3{core::int};
+  function #x#set(core::int #t4) → dynamic
+    return #x = #t4;
+  #x#set(42){(core::int) → dynamic};
+  core::print(#x#get(){() → core::int});
+}
+static method testNullableUninitializedFinalLocal() → void {
+  lowered final core::int? #x = _in::createSentinel<core::int?>();
+  function #x#get() → core::int?
+    return let final core::int? #t5 = #x in _in::isSentinel(#t5) ?{core::int?} throw new _in::LateError::localNI("x") : #t5{core::int?};
+  function #x#set(core::int? #t6) → dynamic
+    if(_in::isSentinel(#x))
+      return #x = #t6;
+    else
+      throw new _in::LateError::localAI("x");
+  #x#set(42){(core::int?) → dynamic};
+  core::print(#x#get(){() → core::int?});
+}
+static method testNonNullableUninitializedFinalLocal() → void {
+  lowered final core::int? #x;
+  function #x#get() → core::int
+    return let final core::int? #t7 = #x in #t7 == null ?{core::int} throw new _in::LateError::localNI("x") : #t7{core::int};
+  function #x#set(core::int #t8) → dynamic
+    if(#x == null)
+      return #x = #t8;
+    else
+      throw new _in::LateError::localAI("x");
+  #x#set(42){(core::int) → dynamic};
+  core::print(#x#get(){() → core::int});
+}
+static method testNullableInitializedNonFinalLocal() → void {
+  lowered core::int? #x = _in::createSentinel<core::int?>();
+  function #x#get() → core::int?
+    return let final core::int? #t9 = #x in _in::isSentinel(#t9) ?{core::int?} #x = 1.{core::int::unary-}(){() → core::int} : #t9{core::int?};
+  function #x#set(core::int? #t10) → dynamic
+    return #x = #t10;
+  core::print(#x#get(){() → core::int?});
+  #x#set(42){(core::int?) → dynamic};
+  core::print(#x#get(){() → core::int?});
+  lowered core::int? #y = _in::createSentinel<core::int?>();
+  function #y#get() → core::int?
+    return let final core::int? #t11 = #y in _in::isSentinel(#t11) ?{core::int?} #y = null : #t11{core::int?};
+  function #y#set(core::int? #t12) → dynamic
+    return #y = #t12;
+  core::print(#y#get(){() → core::int?});
+  #y#set(42){(core::int?) → dynamic};
+  core::print(#y#get(){() → core::int?});
+}
+static method testNonNullableInitializedNonFinalLocal() → void {
+  lowered core::int? #x;
+  function #x#get() → core::int
+    return let final core::int? #t13 = #x in #t13 == null ?{core::int} #x = 1.{core::int::unary-}(){() → core::int} : #t13{core::int};
+  function #x#set(core::int #t14) → dynamic
+    return #x = #t14;
+  core::print(#x#get(){() → core::int});
+  #x#set(42){(core::int) → dynamic};
+  core::print(#x#get(){() → core::int});
+}
+static method testNullableInitializedFinalLocal() → void {
+  lowered final core::int? #x = _in::createSentinel<core::int?>();
+  function #x#get() → core::int?
+    return let final core::int? #t15 = #x in _in::isSentinel(#t15) ?{core::int?} let final core::int? #t16 = 1.{core::int::unary-}(){() → core::int} in _in::isSentinel(#x) ?{core::int?} #x = #t16 : throw new _in::LateError::localADI("x") : #t15;
+  core::print(#x#get(){() → core::int?});
+  lowered final core::int? #y = _in::createSentinel<core::int?>();
+  function #y#get() → core::int?
+    return let final core::int? #t17 = #y in _in::isSentinel(#t17) ?{core::int?} let final core::int? #t18 = null in _in::isSentinel(#y) ?{core::int?} #y = #t18 : throw new _in::LateError::localADI("y") : #t17;
+  core::print(#y#get(){() → core::int?});
+}
+static method testNonNullableInitializedFinalLocal() → void {
+  lowered final core::int? #x;
+  function #x#get() → core::int
+    return let final core::int? #t19 = #x in #t19 == null ?{core::int} let final core::int #t20 = 1.{core::int::unary-}(){() → core::int} in #x == null ?{core::int} #x = #t20 : throw new _in::LateError::localADI("x") : #t19{core::int};
+  core::print(#x#get(){() → core::int});
+}
+
+
+Extra constant evaluation status:
+Evaluated: InstanceInvocation @ org-dartlang-testcase:///late_locals.dart:41:17 -> DoubleConstant(-1.0)
+Evaluated: InstanceInvocation @ org-dartlang-testcase:///late_locals.dart:53:16 -> DoubleConstant(-1.0)
+Evaluated: InstanceInvocation @ org-dartlang-testcase:///late_locals.dart:60:23 -> DoubleConstant(-1.0)
+Evaluated: VariableGet @ org-dartlang-testcase:///late_locals.dart:60:19 -> DoubleConstant(-1.0)
+Evaluated: VariableGet @ org-dartlang-testcase:///late_locals.dart:63:19 -> NullConstant(null)
+Evaluated: InstanceInvocation @ org-dartlang-testcase:///late_locals.dart:68:22 -> DoubleConstant(-1.0)
+Evaluated: VariableGet @ org-dartlang-testcase:///late_locals.dart:68:18 -> DoubleConstant(-1.0)
+Extra constant evaluation: evaluated: 168, effectively constant: 7
diff --git a/pkg/front_end/testcases/dart2js/late_locals.dart.textual_outline.expect b/pkg/front_end/testcases/dart2js/late_locals.dart.textual_outline.expect
new file mode 100644
index 0000000..c13d4ba
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/late_locals.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+void main() {}
+void testNullableUninitializedNonFinalLocal() {}
+void testNonNullableUninitializedNonFinalLocal() {}
+void testNullableUninitializedFinalLocal() {}
+void testNonNullableUninitializedFinalLocal() {}
+void testNullableInitializedNonFinalLocal() {}
+void testNonNullableInitializedNonFinalLocal() {}
+void testNullableInitializedFinalLocal() {}
+void testNonNullableInitializedFinalLocal() {}
diff --git a/pkg/front_end/testcases/dart2js/late_locals.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/dart2js/late_locals.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6760814
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/late_locals.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+void main() {}
+void testNonNullableInitializedFinalLocal() {}
+void testNonNullableInitializedNonFinalLocal() {}
+void testNonNullableUninitializedFinalLocal() {}
+void testNonNullableUninitializedNonFinalLocal() {}
+void testNullableInitializedFinalLocal() {}
+void testNullableInitializedNonFinalLocal() {}
+void testNullableUninitializedFinalLocal() {}
+void testNullableUninitializedNonFinalLocal() {}
diff --git a/pkg/front_end/testcases/dart2js/late_locals.dart.weak.expect b/pkg/front_end/testcases/dart2js/late_locals.dart.weak.expect
new file mode 100644
index 0000000..26979f0
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/late_locals.dart.weak.expect
@@ -0,0 +1,101 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:_internal" as _in;
+
+static method main() → void {
+  self::testNullableUninitializedNonFinalLocal();
+  self::testNonNullableUninitializedNonFinalLocal();
+  self::testNullableUninitializedFinalLocal();
+  self::testNonNullableUninitializedFinalLocal();
+  self::testNullableInitializedNonFinalLocal();
+  self::testNonNullableInitializedNonFinalLocal();
+  self::testNullableInitializedFinalLocal();
+  self::testNonNullableInitializedFinalLocal();
+}
+static method testNullableUninitializedNonFinalLocal() → void {
+  lowered core::int? #x = _in::createSentinel<core::int?>();
+  function #x#get() → core::int?
+    return let final core::int? #t1 = #x in _in::isSentinel(#t1) ?{core::int?} throw new _in::LateError::localNI("x") : #t1{core::int?};
+  function #x#set(core::int? #t2) → dynamic
+    return #x = #t2;
+  #x#set(42){(core::int?) → dynamic};
+  core::print(#x#get(){() → core::int?});
+}
+static method testNonNullableUninitializedNonFinalLocal() → void {
+  lowered core::int? #x = _in::createSentinel<core::int>();
+  function #x#get() → core::int
+    return let final core::int? #t3 = #x in _in::isSentinel(#t3) ?{core::int} throw new _in::LateError::localNI("x") : #t3{core::int};
+  function #x#set(core::int #t4) → dynamic
+    return #x = #t4;
+  #x#set(42){(core::int) → dynamic};
+  core::print(#x#get(){() → core::int});
+}
+static method testNullableUninitializedFinalLocal() → void {
+  lowered final core::int? #x = _in::createSentinel<core::int?>();
+  function #x#get() → core::int?
+    return let final core::int? #t5 = #x in _in::isSentinel(#t5) ?{core::int?} throw new _in::LateError::localNI("x") : #t5{core::int?};
+  function #x#set(core::int? #t6) → dynamic
+    if(_in::isSentinel(#x))
+      return #x = #t6;
+    else
+      throw new _in::LateError::localAI("x");
+  #x#set(42){(core::int?) → dynamic};
+  core::print(#x#get(){() → core::int?});
+}
+static method testNonNullableUninitializedFinalLocal() → void {
+  lowered final core::int? #x = _in::createSentinel<core::int>();
+  function #x#get() → core::int
+    return let final core::int? #t7 = #x in _in::isSentinel(#t7) ?{core::int} throw new _in::LateError::localNI("x") : #t7{core::int};
+  function #x#set(core::int #t8) → dynamic
+    if(_in::isSentinel(#x))
+      return #x = #t8;
+    else
+      throw new _in::LateError::localAI("x");
+  #x#set(42){(core::int) → dynamic};
+  core::print(#x#get(){() → core::int});
+}
+static method testNullableInitializedNonFinalLocal() → void {
+  lowered core::int? #x = _in::createSentinel<core::int?>();
+  function #x#get() → core::int?
+    return let final core::int? #t9 = #x in _in::isSentinel(#t9) ?{core::int?} #x = 1.{core::int::unary-}(){() → core::int} : #t9{core::int?};
+  function #x#set(core::int? #t10) → dynamic
+    return #x = #t10;
+  core::print(#x#get(){() → core::int?});
+  #x#set(42){(core::int?) → dynamic};
+  core::print(#x#get(){() → core::int?});
+  lowered core::int? #y = _in::createSentinel<core::int?>();
+  function #y#get() → core::int?
+    return let final core::int? #t11 = #y in _in::isSentinel(#t11) ?{core::int?} #y = null : #t11{core::int?};
+  function #y#set(core::int? #t12) → dynamic
+    return #y = #t12;
+  core::print(#y#get(){() → core::int?});
+  #y#set(42){(core::int?) → dynamic};
+  core::print(#y#get(){() → core::int?});
+}
+static method testNonNullableInitializedNonFinalLocal() → void {
+  lowered core::int? #x = _in::createSentinel<core::int>();
+  function #x#get() → core::int
+    return let final core::int? #t13 = #x in _in::isSentinel(#t13) ?{core::int} #x = 1.{core::int::unary-}(){() → core::int} : #t13{core::int};
+  function #x#set(core::int #t14) → dynamic
+    return #x = #t14;
+  core::print(#x#get(){() → core::int});
+  #x#set(42){(core::int) → dynamic};
+  core::print(#x#get(){() → core::int});
+}
+static method testNullableInitializedFinalLocal() → void {
+  lowered final core::int? #x = _in::createSentinel<core::int?>();
+  function #x#get() → core::int?
+    return let final core::int? #t15 = #x in _in::isSentinel(#t15) ?{core::int?} let final core::int? #t16 = 1.{core::int::unary-}(){() → core::int} in _in::isSentinel(#x) ?{core::int?} #x = #t16 : throw new _in::LateError::localADI("x") : #t15;
+  core::print(#x#get(){() → core::int?});
+  lowered final core::int? #y = _in::createSentinel<core::int?>();
+  function #y#get() → core::int?
+    return let final core::int? #t17 = #y in _in::isSentinel(#t17) ?{core::int?} let final core::int? #t18 = null in _in::isSentinel(#y) ?{core::int?} #y = #t18 : throw new _in::LateError::localADI("y") : #t17;
+  core::print(#y#get(){() → core::int?});
+}
+static method testNonNullableInitializedFinalLocal() → void {
+  lowered final core::int? #x = _in::createSentinel<core::int>();
+  function #x#get() → core::int
+    return let final core::int #t19 = #x in _in::isSentinel(#t19) ?{core::int} let final core::int #t20 = 1.{core::int::unary-}(){() → core::int} in _in::isSentinel(#x) ?{core::int} #x = #t20 : throw new _in::LateError::localADI("x") : #t19;
+  core::print(#x#get(){() → core::int});
+}
diff --git a/pkg/front_end/testcases/dart2js/late_locals.dart.weak.outline.expect b/pkg/front_end/testcases/dart2js/late_locals.dart.weak.outline.expect
new file mode 100644
index 0000000..99217cb
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/late_locals.dart.weak.outline.expect
@@ -0,0 +1,21 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+
+static method main() → void
+  ;
+static method testNullableUninitializedNonFinalLocal() → void
+  ;
+static method testNonNullableUninitializedNonFinalLocal() → void
+  ;
+static method testNullableUninitializedFinalLocal() → void
+  ;
+static method testNonNullableUninitializedFinalLocal() → void
+  ;
+static method testNullableInitializedNonFinalLocal() → void
+  ;
+static method testNonNullableInitializedNonFinalLocal() → void
+  ;
+static method testNullableInitializedFinalLocal() → void
+  ;
+static method testNonNullableInitializedFinalLocal() → void
+  ;
diff --git a/pkg/front_end/testcases/dart2js/late_locals.dart.weak.transformed.expect b/pkg/front_end/testcases/dart2js/late_locals.dart.weak.transformed.expect
new file mode 100644
index 0000000..640d4d4
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/late_locals.dart.weak.transformed.expect
@@ -0,0 +1,112 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:_internal" as _in;
+
+static method main() → void {
+  self::testNullableUninitializedNonFinalLocal();
+  self::testNonNullableUninitializedNonFinalLocal();
+  self::testNullableUninitializedFinalLocal();
+  self::testNonNullableUninitializedFinalLocal();
+  self::testNullableInitializedNonFinalLocal();
+  self::testNonNullableInitializedNonFinalLocal();
+  self::testNullableInitializedFinalLocal();
+  self::testNonNullableInitializedFinalLocal();
+}
+static method testNullableUninitializedNonFinalLocal() → void {
+  lowered core::int? #x = _in::createSentinel<core::int?>();
+  function #x#get() → core::int?
+    return let final core::int? #t1 = #x in _in::isSentinel(#t1) ?{core::int?} throw new _in::LateError::localNI("x") : #t1{core::int?};
+  function #x#set(core::int? #t2) → dynamic
+    return #x = #t2;
+  #x#set(42){(core::int?) → dynamic};
+  core::print(#x#get(){() → core::int?});
+}
+static method testNonNullableUninitializedNonFinalLocal() → void {
+  lowered core::int? #x = _in::createSentinel<core::int>();
+  function #x#get() → core::int
+    return let final core::int? #t3 = #x in _in::isSentinel(#t3) ?{core::int} throw new _in::LateError::localNI("x") : #t3{core::int};
+  function #x#set(core::int #t4) → dynamic
+    return #x = #t4;
+  #x#set(42){(core::int) → dynamic};
+  core::print(#x#get(){() → core::int});
+}
+static method testNullableUninitializedFinalLocal() → void {
+  lowered final core::int? #x = _in::createSentinel<core::int?>();
+  function #x#get() → core::int?
+    return let final core::int? #t5 = #x in _in::isSentinel(#t5) ?{core::int?} throw new _in::LateError::localNI("x") : #t5{core::int?};
+  function #x#set(core::int? #t6) → dynamic
+    if(_in::isSentinel(#x))
+      return #x = #t6;
+    else
+      throw new _in::LateError::localAI("x");
+  #x#set(42){(core::int?) → dynamic};
+  core::print(#x#get(){() → core::int?});
+}
+static method testNonNullableUninitializedFinalLocal() → void {
+  lowered final core::int? #x = _in::createSentinel<core::int>();
+  function #x#get() → core::int
+    return let final core::int? #t7 = #x in _in::isSentinel(#t7) ?{core::int} throw new _in::LateError::localNI("x") : #t7{core::int};
+  function #x#set(core::int #t8) → dynamic
+    if(_in::isSentinel(#x))
+      return #x = #t8;
+    else
+      throw new _in::LateError::localAI("x");
+  #x#set(42){(core::int) → dynamic};
+  core::print(#x#get(){() → core::int});
+}
+static method testNullableInitializedNonFinalLocal() → void {
+  lowered core::int? #x = _in::createSentinel<core::int?>();
+  function #x#get() → core::int?
+    return let final core::int? #t9 = #x in _in::isSentinel(#t9) ?{core::int?} #x = 1.{core::int::unary-}(){() → core::int} : #t9{core::int?};
+  function #x#set(core::int? #t10) → dynamic
+    return #x = #t10;
+  core::print(#x#get(){() → core::int?});
+  #x#set(42){(core::int?) → dynamic};
+  core::print(#x#get(){() → core::int?});
+  lowered core::int? #y = _in::createSentinel<core::int?>();
+  function #y#get() → core::int?
+    return let final core::int? #t11 = #y in _in::isSentinel(#t11) ?{core::int?} #y = null : #t11{core::int?};
+  function #y#set(core::int? #t12) → dynamic
+    return #y = #t12;
+  core::print(#y#get(){() → core::int?});
+  #y#set(42){(core::int?) → dynamic};
+  core::print(#y#get(){() → core::int?});
+}
+static method testNonNullableInitializedNonFinalLocal() → void {
+  lowered core::int? #x = _in::createSentinel<core::int>();
+  function #x#get() → core::int
+    return let final core::int? #t13 = #x in _in::isSentinel(#t13) ?{core::int} #x = 1.{core::int::unary-}(){() → core::int} : #t13{core::int};
+  function #x#set(core::int #t14) → dynamic
+    return #x = #t14;
+  core::print(#x#get(){() → core::int});
+  #x#set(42){(core::int) → dynamic};
+  core::print(#x#get(){() → core::int});
+}
+static method testNullableInitializedFinalLocal() → void {
+  lowered final core::int? #x = _in::createSentinel<core::int?>();
+  function #x#get() → core::int?
+    return let final core::int? #t15 = #x in _in::isSentinel(#t15) ?{core::int?} let final core::int? #t16 = 1.{core::int::unary-}(){() → core::int} in _in::isSentinel(#x) ?{core::int?} #x = #t16 : throw new _in::LateError::localADI("x") : #t15;
+  core::print(#x#get(){() → core::int?});
+  lowered final core::int? #y = _in::createSentinel<core::int?>();
+  function #y#get() → core::int?
+    return let final core::int? #t17 = #y in _in::isSentinel(#t17) ?{core::int?} let final core::int? #t18 = null in _in::isSentinel(#y) ?{core::int?} #y = #t18 : throw new _in::LateError::localADI("y") : #t17;
+  core::print(#y#get(){() → core::int?});
+}
+static method testNonNullableInitializedFinalLocal() → void {
+  lowered final core::int? #x = _in::createSentinel<core::int>();
+  function #x#get() → core::int
+    return let final core::int #t19 = #x in _in::isSentinel(#t19) ?{core::int} let final core::int #t20 = 1.{core::int::unary-}(){() → core::int} in _in::isSentinel(#x) ?{core::int} #x = #t20 : throw new _in::LateError::localADI("x") : #t19;
+  core::print(#x#get(){() → core::int});
+}
+
+
+Extra constant evaluation status:
+Evaluated: InstanceInvocation @ org-dartlang-testcase:///late_locals.dart:41:17 -> DoubleConstant(-1.0)
+Evaluated: InstanceInvocation @ org-dartlang-testcase:///late_locals.dart:53:16 -> DoubleConstant(-1.0)
+Evaluated: InstanceInvocation @ org-dartlang-testcase:///late_locals.dart:60:23 -> DoubleConstant(-1.0)
+Evaluated: VariableGet @ org-dartlang-testcase:///late_locals.dart:60:19 -> DoubleConstant(-1.0)
+Evaluated: VariableGet @ org-dartlang-testcase:///late_locals.dart:63:19 -> NullConstant(null)
+Evaluated: InstanceInvocation @ org-dartlang-testcase:///late_locals.dart:68:22 -> DoubleConstant(-1.0)
+Evaluated: VariableGet @ org-dartlang-testcase:///late_locals.dart:68:18 -> DoubleConstant(-1.0)
+Extra constant evaluation: evaluated: 172, effectively constant: 7
diff --git a/pkg/front_end/testcases/dart2js/late_statics.dart b/pkg/front_end/testcases/dart2js/late_statics.dart
new file mode 100644
index 0000000..1030ef4
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/late_statics.dart
@@ -0,0 +1,39 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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() {
+  testUninitializedNonFinalStaticField();
+  testUninitializedFinalStaticField();
+  testInitializedNonFinalStaticField();
+  testInitializedFinalStaticField();
+}
+
+class Statics {
+  static late int a;
+  static late final int b;
+  static late int c = -1;
+  static late final int d = -1;
+}
+
+void testUninitializedNonFinalStaticField() {
+  print(Statics.a);
+  Statics.a = 42;
+  print(Statics.a);
+}
+
+void testUninitializedFinalStaticField() {
+  print(Statics.b);
+  Statics.b = 42;
+  print(Statics.b);
+}
+
+void testInitializedNonFinalStaticField() {
+  print(Statics.c);
+  Statics.c = 42;
+  print(Statics.c);
+}
+
+void testInitializedFinalStaticField() {
+  print(Statics.d);
+}
diff --git a/pkg/front_end/testcases/dart2js/late_statics.dart.strong.expect b/pkg/front_end/testcases/dart2js/late_statics.dart.strong.expect
new file mode 100644
index 0000000..f41ebf9
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/late_statics.dart.strong.expect
@@ -0,0 +1,55 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:_internal" as _in;
+
+class Statics extends core::Object {
+  static field core::int? _#a = null;
+  static field core::int? _#b = null;
+  static field core::int? _#c = null;
+  static field core::int? _#d = null;
+  synthetic constructor •() → self::Statics
+    : super core::Object::•()
+    ;
+  static get a() → core::int
+    return let final core::int? #t1 = self::Statics::_#a in #t1 == null ?{core::int} throw new _in::LateError::fieldNI("a") : #t1{core::int};
+  static set a(core::int #t2) → void
+    self::Statics::_#a = #t2;
+  static get b() → core::int
+    return let final core::int? #t3 = self::Statics::_#b in #t3 == null ?{core::int} throw new _in::LateError::fieldNI("b") : #t3{core::int};
+  static set b(core::int #t4) → void
+    if(self::Statics::_#b == null)
+      self::Statics::_#b = #t4;
+    else
+      throw new _in::LateError::fieldAI("b");
+  static get c() → core::int
+    return let final core::int? #t5 = self::Statics::_#c in #t5 == null ?{core::int} self::Statics::_#c = 1.{core::int::unary-}(){() → core::int} : #t5{core::int};
+  static set c(core::int #t6) → void
+    self::Statics::_#c = #t6;
+  static get d() → core::int
+    return let final core::int? #t7 = self::Statics::_#d in #t7 == null ?{core::int} let final core::int #t8 = 1.{core::int::unary-}(){() → core::int} in self::Statics::_#d == null ?{core::int} self::Statics::_#d = #t8 : throw new _in::LateError::fieldADI("d") : #t7{core::int};
+}
+static method main() → void {
+  self::testUninitializedNonFinalStaticField();
+  self::testUninitializedFinalStaticField();
+  self::testInitializedNonFinalStaticField();
+  self::testInitializedFinalStaticField();
+}
+static method testUninitializedNonFinalStaticField() → void {
+  core::print(self::Statics::a);
+  self::Statics::a = 42;
+  core::print(self::Statics::a);
+}
+static method testUninitializedFinalStaticField() → void {
+  core::print(self::Statics::b);
+  self::Statics::b = 42;
+  core::print(self::Statics::b);
+}
+static method testInitializedNonFinalStaticField() → void {
+  core::print(self::Statics::c);
+  self::Statics::c = 42;
+  core::print(self::Statics::c);
+}
+static method testInitializedFinalStaticField() → void {
+  core::print(self::Statics::d);
+}
diff --git a/pkg/front_end/testcases/dart2js/late_statics.dart.strong.transformed.expect b/pkg/front_end/testcases/dart2js/late_statics.dart.strong.transformed.expect
new file mode 100644
index 0000000..1a4e13b
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/late_statics.dart.strong.transformed.expect
@@ -0,0 +1,62 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:_internal" as _in;
+
+class Statics extends core::Object {
+  static field core::int? _#a = null;
+  static field core::int? _#b = null;
+  static field core::int? _#c = null;
+  static field core::int? _#d = null;
+  synthetic constructor •() → self::Statics
+    : super core::Object::•()
+    ;
+  static get a() → core::int
+    return let final core::int? #t1 = self::Statics::_#a in #t1 == null ?{core::int} throw new _in::LateError::fieldNI("a") : #t1{core::int};
+  static set a(core::int #t2) → void
+    self::Statics::_#a = #t2;
+  static get b() → core::int
+    return let final core::int? #t3 = self::Statics::_#b in #t3 == null ?{core::int} throw new _in::LateError::fieldNI("b") : #t3{core::int};
+  static set b(core::int #t4) → void
+    if(self::Statics::_#b == null)
+      self::Statics::_#b = #t4;
+    else
+      throw new _in::LateError::fieldAI("b");
+  static get c() → core::int
+    return let final core::int? #t5 = self::Statics::_#c in #t5 == null ?{core::int} self::Statics::_#c = 1.{core::int::unary-}(){() → core::int} : #t5{core::int};
+  static set c(core::int #t6) → void
+    self::Statics::_#c = #t6;
+  static get d() → core::int
+    return let final core::int? #t7 = self::Statics::_#d in #t7 == null ?{core::int} let final core::int #t8 = 1.{core::int::unary-}(){() → core::int} in self::Statics::_#d == null ?{core::int} self::Statics::_#d = #t8 : throw new _in::LateError::fieldADI("d") : #t7{core::int};
+}
+static method main() → void {
+  self::testUninitializedNonFinalStaticField();
+  self::testUninitializedFinalStaticField();
+  self::testInitializedNonFinalStaticField();
+  self::testInitializedFinalStaticField();
+}
+static method testUninitializedNonFinalStaticField() → void {
+  core::print(self::Statics::a);
+  self::Statics::a = 42;
+  core::print(self::Statics::a);
+}
+static method testUninitializedFinalStaticField() → void {
+  core::print(self::Statics::b);
+  self::Statics::b = 42;
+  core::print(self::Statics::b);
+}
+static method testInitializedNonFinalStaticField() → void {
+  core::print(self::Statics::c);
+  self::Statics::c = 42;
+  core::print(self::Statics::c);
+}
+static method testInitializedFinalStaticField() → void {
+  core::print(self::Statics::d);
+}
+
+
+Extra constant evaluation status:
+Evaluated: InstanceInvocation @ org-dartlang-testcase:///late_statics.dart:15:23 -> DoubleConstant(-1.0)
+Evaluated: InstanceInvocation @ org-dartlang-testcase:///late_statics.dart:16:29 -> DoubleConstant(-1.0)
+Evaluated: VariableGet @ org-dartlang-testcase:///late_statics.dart:16:25 -> DoubleConstant(-1.0)
+Extra constant evaluation: evaluated: 70, effectively constant: 3
diff --git a/pkg/front_end/testcases/dart2js/late_statics.dart.textual_outline.expect b/pkg/front_end/testcases/dart2js/late_statics.dart.textual_outline.expect
new file mode 100644
index 0000000..c9f0b3d
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/late_statics.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+void main() {}
+class Statics {
+  static late int ;
+  a;
+  static late ;
+  final int b;
+  static late int ;
+  c = -1;
+  static late ;
+  final int d = -1;
+}
+void testUninitializedNonFinalStaticField() {}
+void testUninitializedFinalStaticField() {}
+void testInitializedNonFinalStaticField() {}
+void testInitializedFinalStaticField() {}
diff --git a/pkg/front_end/testcases/dart2js/late_statics.dart.weak.expect b/pkg/front_end/testcases/dart2js/late_statics.dart.weak.expect
new file mode 100644
index 0000000..fb7425e
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/late_statics.dart.weak.expect
@@ -0,0 +1,55 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:_internal" as _in;
+
+class Statics extends core::Object {
+  static field core::int? _#a = _in::createSentinel<core::int>();
+  static field core::int? _#b = _in::createSentinel<core::int>();
+  static field core::int? _#c = _in::createSentinel<core::int>();
+  static field core::int? _#d = _in::createSentinel<core::int>();
+  synthetic constructor •() → self::Statics
+    : super core::Object::•()
+    ;
+  static get a() → core::int
+    return let final core::int? #t1 = self::Statics::_#a in _in::isSentinel(#t1) ?{core::int} throw new _in::LateError::fieldNI("a") : #t1{core::int};
+  static set a(core::int #t2) → void
+    self::Statics::_#a = #t2;
+  static get b() → core::int
+    return let final core::int? #t3 = self::Statics::_#b in _in::isSentinel(#t3) ?{core::int} throw new _in::LateError::fieldNI("b") : #t3{core::int};
+  static set b(core::int #t4) → void
+    if(_in::isSentinel(self::Statics::_#b))
+      self::Statics::_#b = #t4;
+    else
+      throw new _in::LateError::fieldAI("b");
+  static get c() → core::int
+    return let final core::int? #t5 = self::Statics::_#c in _in::isSentinel(#t5) ?{core::int} self::Statics::_#c = 1.{core::int::unary-}(){() → core::int} : #t5{core::int};
+  static set c(core::int #t6) → void
+    self::Statics::_#c = #t6;
+  static get d() → core::int
+    return let final core::int #t7 = self::Statics::_#d in _in::isSentinel(#t7) ?{core::int} let final core::int #t8 = 1.{core::int::unary-}(){() → core::int} in _in::isSentinel(self::Statics::_#d) ?{core::int} self::Statics::_#d = #t8 : throw new _in::LateError::fieldADI("d") : #t7;
+}
+static method main() → void {
+  self::testUninitializedNonFinalStaticField();
+  self::testUninitializedFinalStaticField();
+  self::testInitializedNonFinalStaticField();
+  self::testInitializedFinalStaticField();
+}
+static method testUninitializedNonFinalStaticField() → void {
+  core::print(self::Statics::a);
+  self::Statics::a = 42;
+  core::print(self::Statics::a);
+}
+static method testUninitializedFinalStaticField() → void {
+  core::print(self::Statics::b);
+  self::Statics::b = 42;
+  core::print(self::Statics::b);
+}
+static method testInitializedNonFinalStaticField() → void {
+  core::print(self::Statics::c);
+  self::Statics::c = 42;
+  core::print(self::Statics::c);
+}
+static method testInitializedFinalStaticField() → void {
+  core::print(self::Statics::d);
+}
diff --git a/pkg/front_end/testcases/dart2js/late_statics.dart.weak.outline.expect b/pkg/front_end/testcases/dart2js/late_statics.dart.weak.outline.expect
new file mode 100644
index 0000000..7f9136d
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/late_statics.dart.weak.outline.expect
@@ -0,0 +1,29 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class Statics extends core::Object {
+  static field core::int? _#a;
+  static field core::int? _#b;
+  static field core::int? _#c;
+  static field core::int? _#d;
+  synthetic constructor •() → self::Statics
+    ;
+  static get a() → core::int;
+  static set a(core::int #t1) → void;
+  static get b() → core::int;
+  static set b(core::int #t2) → void;
+  static get c() → core::int;
+  static set c(core::int #t3) → void;
+  static get d() → core::int;
+}
+static method main() → void
+  ;
+static method testUninitializedNonFinalStaticField() → void
+  ;
+static method testUninitializedFinalStaticField() → void
+  ;
+static method testInitializedNonFinalStaticField() → void
+  ;
+static method testInitializedFinalStaticField() → void
+  ;
diff --git a/pkg/front_end/testcases/dart2js/late_statics.dart.weak.transformed.expect b/pkg/front_end/testcases/dart2js/late_statics.dart.weak.transformed.expect
new file mode 100644
index 0000000..68a4534
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/late_statics.dart.weak.transformed.expect
@@ -0,0 +1,62 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:_internal" as _in;
+
+class Statics extends core::Object {
+  static field core::int? _#a = _in::createSentinel<core::int>();
+  static field core::int? _#b = _in::createSentinel<core::int>();
+  static field core::int? _#c = _in::createSentinel<core::int>();
+  static field core::int? _#d = _in::createSentinel<core::int>();
+  synthetic constructor •() → self::Statics
+    : super core::Object::•()
+    ;
+  static get a() → core::int
+    return let final core::int? #t1 = self::Statics::_#a in _in::isSentinel(#t1) ?{core::int} throw new _in::LateError::fieldNI("a") : #t1{core::int};
+  static set a(core::int #t2) → void
+    self::Statics::_#a = #t2;
+  static get b() → core::int
+    return let final core::int? #t3 = self::Statics::_#b in _in::isSentinel(#t3) ?{core::int} throw new _in::LateError::fieldNI("b") : #t3{core::int};
+  static set b(core::int #t4) → void
+    if(_in::isSentinel(self::Statics::_#b))
+      self::Statics::_#b = #t4;
+    else
+      throw new _in::LateError::fieldAI("b");
+  static get c() → core::int
+    return let final core::int? #t5 = self::Statics::_#c in _in::isSentinel(#t5) ?{core::int} self::Statics::_#c = 1.{core::int::unary-}(){() → core::int} : #t5{core::int};
+  static set c(core::int #t6) → void
+    self::Statics::_#c = #t6;
+  static get d() → core::int
+    return let final core::int #t7 = self::Statics::_#d in _in::isSentinel(#t7) ?{core::int} let final core::int #t8 = 1.{core::int::unary-}(){() → core::int} in _in::isSentinel(self::Statics::_#d) ?{core::int} self::Statics::_#d = #t8 : throw new _in::LateError::fieldADI("d") : #t7;
+}
+static method main() → void {
+  self::testUninitializedNonFinalStaticField();
+  self::testUninitializedFinalStaticField();
+  self::testInitializedNonFinalStaticField();
+  self::testInitializedFinalStaticField();
+}
+static method testUninitializedNonFinalStaticField() → void {
+  core::print(self::Statics::a);
+  self::Statics::a = 42;
+  core::print(self::Statics::a);
+}
+static method testUninitializedFinalStaticField() → void {
+  core::print(self::Statics::b);
+  self::Statics::b = 42;
+  core::print(self::Statics::b);
+}
+static method testInitializedNonFinalStaticField() → void {
+  core::print(self::Statics::c);
+  self::Statics::c = 42;
+  core::print(self::Statics::c);
+}
+static method testInitializedFinalStaticField() → void {
+  core::print(self::Statics::d);
+}
+
+
+Extra constant evaluation status:
+Evaluated: InstanceInvocation @ org-dartlang-testcase:///late_statics.dart:15:23 -> DoubleConstant(-1.0)
+Evaluated: InstanceInvocation @ org-dartlang-testcase:///late_statics.dart:16:29 -> DoubleConstant(-1.0)
+Evaluated: VariableGet @ org-dartlang-testcase:///late_statics.dart:16:25 -> DoubleConstant(-1.0)
+Extra constant evaluation: evaluated: 74, effectively constant: 3
diff --git a/pkg/front_end/testcases/dart2js/list_generate.dart.strong.expect b/pkg/front_end/testcases/dart2js/list_generate.dart.strong.expect
index c9e4703..1d7d6ef 100644
--- a/pkg/front_end/testcases/dart2js/list_generate.dart.strong.expect
+++ b/pkg/front_end/testcases/dart2js/list_generate.dart.strong.expect
@@ -3,5 +3,5 @@
 import "dart:core" as core;
 
 static method main() → dynamic {
-  core::List::generate<core::int>(10, (core::int i) → core::int => i.{core::num::*}(2));
+  core::List::generate<core::int>(10, (core::int i) → core::int => i.{core::num::*}(2){(core::num) → core::int});
 }
diff --git a/pkg/front_end/testcases/dart2js/list_generate.dart.strong.transformed.expect b/pkg/front_end/testcases/dart2js/list_generate.dart.strong.transformed.expect
index a118ecb..c99286d 100644
--- a/pkg/front_end/testcases/dart2js/list_generate.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/dart2js/list_generate.dart.strong.transformed.expect
@@ -8,7 +8,7 @@
     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.{core::num::*}(2));
+      _list.{_in::JSArray::[]=}{Invariant,BoundsSafe}(i, i.{core::num::*}(2){(core::num) → core::int});
     }
   } =>_list;
 }
diff --git a/pkg/front_end/testcases/dart2js/list_generate.dart.weak.expect b/pkg/front_end/testcases/dart2js/list_generate.dart.weak.expect
index c9e4703..1d7d6ef 100644
--- a/pkg/front_end/testcases/dart2js/list_generate.dart.weak.expect
+++ b/pkg/front_end/testcases/dart2js/list_generate.dart.weak.expect
@@ -3,5 +3,5 @@
 import "dart:core" as core;
 
 static method main() → dynamic {
-  core::List::generate<core::int>(10, (core::int i) → core::int => i.{core::num::*}(2));
+  core::List::generate<core::int>(10, (core::int i) → core::int => i.{core::num::*}(2){(core::num) → core::int});
 }
diff --git a/pkg/front_end/testcases/dart2js/list_generate.dart.weak.transformed.expect b/pkg/front_end/testcases/dart2js/list_generate.dart.weak.transformed.expect
index a118ecb..c99286d 100644
--- a/pkg/front_end/testcases/dart2js/list_generate.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/dart2js/list_generate.dart.weak.transformed.expect
@@ -8,7 +8,7 @@
     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.{core::num::*}(2));
+      _list.{_in::JSArray::[]=}{Invariant,BoundsSafe}(i, i.{core::num::*}(2){(core::num) → core::int});
     }
   } =>_list;
 }
diff --git a/pkg/front_end/testcases/dart2js/list_generate_local_function_invocation.dart b/pkg/front_end/testcases/dart2js/list_generate_local_function_invocation.dart
new file mode 100644
index 0000000..a2fd1da
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/list_generate_local_function_invocation.dart
@@ -0,0 +1,8 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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() {
+  int localFunction(int i) => i * 2;
+  new List<int>.generate(10, (i) => localFunction(i));
+}
diff --git a/pkg/front_end/testcases/dart2js/list_generate_local_function_invocation.dart.strong.expect b/pkg/front_end/testcases/dart2js/list_generate_local_function_invocation.dart.strong.expect
new file mode 100644
index 0000000..fa4652c
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/list_generate_local_function_invocation.dart.strong.expect
@@ -0,0 +1,9 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  function localFunction(core::int i) → core::int
+    return i.{core::num::*}(2){(core::num) → core::int};
+  core::List::generate<core::int>(10, (core::int i) → core::int => localFunction(i){(core::int) → core::int});
+}
diff --git a/pkg/front_end/testcases/dart2js/list_generate_local_function_invocation.dart.strong.transformed.expect b/pkg/front_end/testcases/dart2js/list_generate_local_function_invocation.dart.strong.transformed.expect
new file mode 100644
index 0000000..e8cb15b
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/list_generate_local_function_invocation.dart.strong.transformed.expect
@@ -0,0 +1,16 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:_interceptors" as _in;
+
+static method main() → dynamic {
+  function localFunction(core::int i) → core::int
+    return i.{core::num::*}(2){(core::num) → core::int};
+  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, localFunction(i){(core::int) → core::int});
+    }
+  } =>_list;
+}
diff --git a/pkg/front_end/testcases/dart2js/list_generate_local_function_invocation.dart.textual_outline.expect b/pkg/front_end/testcases/dart2js/list_generate_local_function_invocation.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/list_generate_local_function_invocation.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/dart2js/list_generate_local_function_invocation.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/dart2js/list_generate_local_function_invocation.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/list_generate_local_function_invocation.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/dart2js/list_generate_local_function_invocation.dart.weak.expect b/pkg/front_end/testcases/dart2js/list_generate_local_function_invocation.dart.weak.expect
new file mode 100644
index 0000000..fa4652c
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/list_generate_local_function_invocation.dart.weak.expect
@@ -0,0 +1,9 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  function localFunction(core::int i) → core::int
+    return i.{core::num::*}(2){(core::num) → core::int};
+  core::List::generate<core::int>(10, (core::int i) → core::int => localFunction(i){(core::int) → core::int});
+}
diff --git a/pkg/front_end/testcases/dart2js/list_generate_local_function_invocation.dart.weak.outline.expect b/pkg/front_end/testcases/dart2js/list_generate_local_function_invocation.dart.weak.outline.expect
new file mode 100644
index 0000000..e2cba6b
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/list_generate_local_function_invocation.dart.weak.outline.expect
@@ -0,0 +1,5 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/dart2js/list_generate_local_function_invocation.dart.weak.transformed.expect b/pkg/front_end/testcases/dart2js/list_generate_local_function_invocation.dart.weak.transformed.expect
new file mode 100644
index 0000000..e8cb15b
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/list_generate_local_function_invocation.dart.weak.transformed.expect
@@ -0,0 +1,16 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:_interceptors" as _in;
+
+static method main() → dynamic {
+  function localFunction(core::int i) → core::int
+    return i.{core::num::*}(2){(core::num) → core::int};
+  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, localFunction(i){(core::int) → core::int});
+    }
+  } =>_list;
+}
diff --git a/pkg/front_end/testcases/dartdevc/instance_getter_invocation.dart b/pkg/front_end/testcases/dartdevc/instance_getter_invocation.dart
new file mode 100644
index 0000000..1ef505e
--- /dev/null
+++ b/pkg/front_end/testcases/dartdevc/instance_getter_invocation.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+T id<T>(T t) => t;
+
+class Class {
+  S Function<S>(S) get idFunction => id;
+  dynamic get dynFunction => id;
+}
+
+main() {
+  Class c = new Class();
+  c.idFunction(0);
+  c.idFunction<int>(0);
+  c.dynFunction(0);
+}
diff --git a/pkg/front_end/testcases/dartdevc/instance_getter_invocation.dart.strong.expect b/pkg/front_end/testcases/dartdevc/instance_getter_invocation.dart.strong.expect
new file mode 100644
index 0000000..e29a84e
--- /dev/null
+++ b/pkg/front_end/testcases/dartdevc/instance_getter_invocation.dart.strong.expect
@@ -0,0 +1,25 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  synthetic constructor •() → self::Class
+    : super core::Object::•()
+    ;
+  get idFunction() → <S extends core::Object? = dynamic>(S%) → S%
+    return #C1;
+  get dynFunction() → dynamic
+    return #C1;
+}
+static method id<T extends core::Object? = dynamic>(self::id::T% t) → self::id::T%
+  return t;
+static method main() → dynamic {
+  self::Class c = new self::Class::•();
+  let final self::Class #t1 = c in let final core::int #t2 = 0 in #t1.{self::Class::idFunction}<core::int>(#t2){(core::int) → core::int};
+  let final self::Class #t3 = c in let final core::int #t4 = 0 in #t3.{self::Class::idFunction}<core::int>(#t4){(core::int) → core::int};
+  let final self::Class #t5 = c in let final core::int #t6 = 0 in #t5.{self::Class::dynFunction}(#t6);
+}
+
+constants  {
+  #C1 = tearoff self::id
+}
diff --git a/pkg/front_end/testcases/dartdevc/instance_getter_invocation.dart.strong.transformed.expect b/pkg/front_end/testcases/dartdevc/instance_getter_invocation.dart.strong.transformed.expect
new file mode 100644
index 0000000..6a431a4
--- /dev/null
+++ b/pkg/front_end/testcases/dartdevc/instance_getter_invocation.dart.strong.transformed.expect
@@ -0,0 +1,31 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  synthetic constructor •() → self::Class
+    : super core::Object::•()
+    ;
+  get idFunction() → <S extends core::Object? = dynamic>(S%) → S%
+    return #C1;
+  get dynFunction() → dynamic
+    return #C1;
+}
+static method id<T extends core::Object? = dynamic>(self::id::T% t) → self::id::T%
+  return t;
+static method main() → dynamic {
+  self::Class c = new self::Class::•();
+  let final self::Class #t1 = c in let final core::int #t2 = 0 in #t1.{self::Class::idFunction}<core::int>(#t2){(core::int) → core::int};
+  let final self::Class #t3 = c in let final core::int #t4 = 0 in #t3.{self::Class::idFunction}<core::int>(#t4){(core::int) → core::int};
+  let final self::Class #t5 = c in let final core::int #t6 = 0 in #t5.{self::Class::dynFunction}(#t6);
+}
+
+constants  {
+  #C1 = tearoff self::id
+}
+
+Extra constant evaluation status:
+Evaluated: VariableGet @ org-dartlang-testcase:///instance_getter_invocation.dart:14:16 -> DoubleConstant(0.0)
+Evaluated: VariableGet @ org-dartlang-testcase:///instance_getter_invocation.dart:15:21 -> DoubleConstant(0.0)
+Evaluated: VariableGet @ org-dartlang-testcase:///instance_getter_invocation.dart:16:17 -> DoubleConstant(0.0)
+Extra constant evaluation: evaluated: 20, effectively constant: 3
diff --git a/pkg/front_end/testcases/dartdevc/instance_getter_invocation.dart.textual_outline.expect b/pkg/front_end/testcases/dartdevc/instance_getter_invocation.dart.textual_outline.expect
new file mode 100644
index 0000000..9cd1271
--- /dev/null
+++ b/pkg/front_end/testcases/dartdevc/instance_getter_invocation.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+T id<T>(T t) => t;
+
+class Class {
+  S Function<S>(S) get idFunction => id;
+  dynamic get dynFunction => id;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/dartdevc/instance_getter_invocation.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/dartdevc/instance_getter_invocation.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9cd1271
--- /dev/null
+++ b/pkg/front_end/testcases/dartdevc/instance_getter_invocation.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+T id<T>(T t) => t;
+
+class Class {
+  S Function<S>(S) get idFunction => id;
+  dynamic get dynFunction => id;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/dartdevc/instance_getter_invocation.dart.weak.expect b/pkg/front_end/testcases/dartdevc/instance_getter_invocation.dart.weak.expect
new file mode 100644
index 0000000..e29a84e
--- /dev/null
+++ b/pkg/front_end/testcases/dartdevc/instance_getter_invocation.dart.weak.expect
@@ -0,0 +1,25 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  synthetic constructor •() → self::Class
+    : super core::Object::•()
+    ;
+  get idFunction() → <S extends core::Object? = dynamic>(S%) → S%
+    return #C1;
+  get dynFunction() → dynamic
+    return #C1;
+}
+static method id<T extends core::Object? = dynamic>(self::id::T% t) → self::id::T%
+  return t;
+static method main() → dynamic {
+  self::Class c = new self::Class::•();
+  let final self::Class #t1 = c in let final core::int #t2 = 0 in #t1.{self::Class::idFunction}<core::int>(#t2){(core::int) → core::int};
+  let final self::Class #t3 = c in let final core::int #t4 = 0 in #t3.{self::Class::idFunction}<core::int>(#t4){(core::int) → core::int};
+  let final self::Class #t5 = c in let final core::int #t6 = 0 in #t5.{self::Class::dynFunction}(#t6);
+}
+
+constants  {
+  #C1 = tearoff self::id
+}
diff --git a/pkg/front_end/testcases/dartdevc/instance_getter_invocation.dart.weak.outline.expect b/pkg/front_end/testcases/dartdevc/instance_getter_invocation.dart.weak.outline.expect
new file mode 100644
index 0000000..85f75fa
--- /dev/null
+++ b/pkg/front_end/testcases/dartdevc/instance_getter_invocation.dart.weak.outline.expect
@@ -0,0 +1,16 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  synthetic constructor •() → self::Class
+    ;
+  get idFunction() → <S extends core::Object? = dynamic>(S%) → S%
+    ;
+  get dynFunction() → dynamic
+    ;
+}
+static method id<T extends core::Object? = dynamic>(self::id::T% t) → self::id::T%
+  ;
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/dartdevc/instance_getter_invocation.dart.weak.transformed.expect b/pkg/front_end/testcases/dartdevc/instance_getter_invocation.dart.weak.transformed.expect
new file mode 100644
index 0000000..6a431a4
--- /dev/null
+++ b/pkg/front_end/testcases/dartdevc/instance_getter_invocation.dart.weak.transformed.expect
@@ -0,0 +1,31 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  synthetic constructor •() → self::Class
+    : super core::Object::•()
+    ;
+  get idFunction() → <S extends core::Object? = dynamic>(S%) → S%
+    return #C1;
+  get dynFunction() → dynamic
+    return #C1;
+}
+static method id<T extends core::Object? = dynamic>(self::id::T% t) → self::id::T%
+  return t;
+static method main() → dynamic {
+  self::Class c = new self::Class::•();
+  let final self::Class #t1 = c in let final core::int #t2 = 0 in #t1.{self::Class::idFunction}<core::int>(#t2){(core::int) → core::int};
+  let final self::Class #t3 = c in let final core::int #t4 = 0 in #t3.{self::Class::idFunction}<core::int>(#t4){(core::int) → core::int};
+  let final self::Class #t5 = c in let final core::int #t6 = 0 in #t5.{self::Class::dynFunction}(#t6);
+}
+
+constants  {
+  #C1 = tearoff self::id
+}
+
+Extra constant evaluation status:
+Evaluated: VariableGet @ org-dartlang-testcase:///instance_getter_invocation.dart:14:16 -> DoubleConstant(0.0)
+Evaluated: VariableGet @ org-dartlang-testcase:///instance_getter_invocation.dart:15:21 -> DoubleConstant(0.0)
+Evaluated: VariableGet @ org-dartlang-testcase:///instance_getter_invocation.dart:16:17 -> DoubleConstant(0.0)
+Extra constant evaluation: evaluated: 20, effectively constant: 3
diff --git a/pkg/front_end/testcases/extension_types/simple_getter_resolution.dart b/pkg/front_end/testcases/extension_types/simple_getter_resolution.dart
new file mode 100644
index 0000000..114ac6f
--- /dev/null
+++ b/pkg/front_end/testcases/extension_types/simple_getter_resolution.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class A {
+  int get foo => 42;
+}
+
+extension E on A {
+  double get bar => 3.14;
+}
+
+test(A a, E e) {
+  a.foo; // Ok.
+  a.bar; // Ok.
+  e.foo; // Error.
+  e.bar; // Ok.
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/extension_types/simple_getter_resolution.dart.strong.expect b/pkg/front_end/testcases/extension_types/simple_getter_resolution.dart.strong.expect
new file mode 100644
index 0000000..8c6d2ea
--- /dev/null
+++ b/pkg/front_end/testcases/extension_types/simple_getter_resolution.dart.strong.expect
@@ -0,0 +1,34 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/extension_types/simple_getter_resolution.dart:16:5: Error: The getter 'foo' isn't defined for the extension 'E'.
+// Try correcting the name to the name of an existing getter, or defining a getter or field named 'foo'.
+//   e.foo; // Error.
+//     ^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+  get foo() → core::int
+    return 42;
+}
+extension E on self::A {
+  get bar = self::E|get#bar;
+}
+static method E|get#bar(lowered final self::A #this) → core::double
+  return 3.14;
+static method test(self::A a, self::E e) → dynamic {
+  a.{self::A::foo};
+  self::E|get#bar(a);
+  invalid-expression "pkg/front_end/testcases/extension_types/simple_getter_resolution.dart:16:5: Error: The getter 'foo' isn't defined for the extension 'E'.
+Try correcting the name to the name of an existing getter, or defining a getter or field named 'foo'.
+  e.foo; // Error.
+    ^^^";
+  self::E|get#bar(e);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/extension_types/simple_getter_resolution.dart.strong.transformed.expect b/pkg/front_end/testcases/extension_types/simple_getter_resolution.dart.strong.transformed.expect
new file mode 100644
index 0000000..8c6d2ea
--- /dev/null
+++ b/pkg/front_end/testcases/extension_types/simple_getter_resolution.dart.strong.transformed.expect
@@ -0,0 +1,34 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/extension_types/simple_getter_resolution.dart:16:5: Error: The getter 'foo' isn't defined for the extension 'E'.
+// Try correcting the name to the name of an existing getter, or defining a getter or field named 'foo'.
+//   e.foo; // Error.
+//     ^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+  get foo() → core::int
+    return 42;
+}
+extension E on self::A {
+  get bar = self::E|get#bar;
+}
+static method E|get#bar(lowered final self::A #this) → core::double
+  return 3.14;
+static method test(self::A a, self::E e) → dynamic {
+  a.{self::A::foo};
+  self::E|get#bar(a);
+  invalid-expression "pkg/front_end/testcases/extension_types/simple_getter_resolution.dart:16:5: Error: The getter 'foo' isn't defined for the extension 'E'.
+Try correcting the name to the name of an existing getter, or defining a getter or field named 'foo'.
+  e.foo; // Error.
+    ^^^";
+  self::E|get#bar(e);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/extension_types/simple_getter_resolution.dart.textual_outline.expect b/pkg/front_end/testcases/extension_types/simple_getter_resolution.dart.textual_outline.expect
new file mode 100644
index 0000000..587163f
--- /dev/null
+++ b/pkg/front_end/testcases/extension_types/simple_getter_resolution.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+class A {
+  int get foo => 42;
+}
+
+extension E on A {
+  double get bar => 3.14;
+}
+
+test(A a, E e) {}
+main() {}
diff --git a/pkg/front_end/testcases/extension_types/simple_getter_resolution.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extension_types/simple_getter_resolution.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8d51c64
--- /dev/null
+++ b/pkg/front_end/testcases/extension_types/simple_getter_resolution.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+class A {
+  int get foo => 42;
+}
+
+extension E on A {
+  double get bar => 3.14;
+}
+
+main() {}
+test(A a, E e) {}
diff --git a/pkg/front_end/testcases/extension_types/simple_getter_resolution.dart.weak.expect b/pkg/front_end/testcases/extension_types/simple_getter_resolution.dart.weak.expect
new file mode 100644
index 0000000..8c6d2ea
--- /dev/null
+++ b/pkg/front_end/testcases/extension_types/simple_getter_resolution.dart.weak.expect
@@ -0,0 +1,34 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/extension_types/simple_getter_resolution.dart:16:5: Error: The getter 'foo' isn't defined for the extension 'E'.
+// Try correcting the name to the name of an existing getter, or defining a getter or field named 'foo'.
+//   e.foo; // Error.
+//     ^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+  get foo() → core::int
+    return 42;
+}
+extension E on self::A {
+  get bar = self::E|get#bar;
+}
+static method E|get#bar(lowered final self::A #this) → core::double
+  return 3.14;
+static method test(self::A a, self::E e) → dynamic {
+  a.{self::A::foo};
+  self::E|get#bar(a);
+  invalid-expression "pkg/front_end/testcases/extension_types/simple_getter_resolution.dart:16:5: Error: The getter 'foo' isn't defined for the extension 'E'.
+Try correcting the name to the name of an existing getter, or defining a getter or field named 'foo'.
+  e.foo; // Error.
+    ^^^";
+  self::E|get#bar(e);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/extension_types/simple_getter_resolution.dart.weak.outline.expect b/pkg/front_end/testcases/extension_types/simple_getter_resolution.dart.weak.outline.expect
new file mode 100644
index 0000000..08cef61
--- /dev/null
+++ b/pkg/front_end/testcases/extension_types/simple_getter_resolution.dart.weak.outline.expect
@@ -0,0 +1,19 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    ;
+  get foo() → core::int
+    ;
+}
+extension E on self::A {
+  get bar = self::E|get#bar;
+}
+static method E|get#bar(lowered final self::A #this) → core::double
+  ;
+static method test(self::A a, self::E e) → dynamic
+  ;
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/extension_types/simple_getter_resolution.dart.weak.transformed.expect b/pkg/front_end/testcases/extension_types/simple_getter_resolution.dart.weak.transformed.expect
new file mode 100644
index 0000000..8c6d2ea
--- /dev/null
+++ b/pkg/front_end/testcases/extension_types/simple_getter_resolution.dart.weak.transformed.expect
@@ -0,0 +1,34 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/extension_types/simple_getter_resolution.dart:16:5: Error: The getter 'foo' isn't defined for the extension 'E'.
+// Try correcting the name to the name of an existing getter, or defining a getter or field named 'foo'.
+//   e.foo; // Error.
+//     ^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+  get foo() → core::int
+    return 42;
+}
+extension E on self::A {
+  get bar = self::E|get#bar;
+}
+static method E|get#bar(lowered final self::A #this) → core::double
+  return 3.14;
+static method test(self::A a, self::E e) → dynamic {
+  a.{self::A::foo};
+  self::E|get#bar(a);
+  invalid-expression "pkg/front_end/testcases/extension_types/simple_getter_resolution.dart:16:5: Error: The getter 'foo' isn't defined for the extension 'E'.
+Try correcting the name to the name of an existing getter, or defining a getter or field named 'foo'.
+  e.foo; // Error.
+    ^^^";
+  self::E|get#bar(e);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/extension_types/simple_operator_resolution.dart b/pkg/front_end/testcases/extension_types/simple_operator_resolution.dart
new file mode 100644
index 0000000..7f1f10b
--- /dev/null
+++ b/pkg/front_end/testcases/extension_types/simple_operator_resolution.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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 {
+  dynamic operator*(dynamic other) => 42;
+  dynamic operator[](int index) => 42;
+  void operator[]=(int index, dynamic value) {}
+  dynamic operator-() => 42;
+}
+
+extension E on A {
+  dynamic operator+(dynamic other) => 42;
+}
+
+test(A a, E e) {
+  a * "foobar"; // Ok.
+  a[0]; // Ok.
+  a[0] = "foobar"; // Ok.
+  -a; // Ok.
+  a + "foobar"; // Ok.
+
+  e * "foobar"; // Error.
+  e[0]; // Error.
+  e[0] = "foobar"; // Error.
+  -e; // Error.
+  e + "foobar"; // Ok.
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/extension_types/simple_operator_resolution.dart.strong.expect b/pkg/front_end/testcases/extension_types/simple_operator_resolution.dart.strong.expect
new file mode 100644
index 0000000..80d58c8
--- /dev/null
+++ b/pkg/front_end/testcases/extension_types/simple_operator_resolution.dart.strong.expect
@@ -0,0 +1,69 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/extension_types/simple_operator_resolution.dart:23:5: Error: The operator '*' isn't defined for the extension 'E'.
+// Try correcting the operator to an existing operator, or defining a '*' operator.
+//   e * "foobar"; // Error.
+//     ^
+//
+// pkg/front_end/testcases/extension_types/simple_operator_resolution.dart:24:4: Error: The operator '[]' isn't defined for the extension 'E'.
+// Try correcting the operator to an existing operator, or defining a '[]' operator.
+//   e[0]; // Error.
+//    ^
+//
+// pkg/front_end/testcases/extension_types/simple_operator_resolution.dart:25:4: Error: The operator '[]=' isn't defined for the extension 'E'.
+// Try correcting the operator to an existing operator, or defining a '[]=' operator.
+//   e[0] = "foobar"; // Error.
+//    ^
+//
+// pkg/front_end/testcases/extension_types/simple_operator_resolution.dart:26:3: Error: The operator 'unary-' isn't defined for the extension 'E'.
+// Try correcting the operator to an existing operator, or defining a 'unary-' operator.
+//   -e; // Error.
+//   ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+  operator *(dynamic other) → dynamic
+    return 42;
+  operator [](core::int index) → dynamic
+    return 42;
+  operator []=(core::int index, dynamic value) → void {}
+  operator unary-() → dynamic
+    return 42;
+}
+extension E on self::A {
+  operator + = self::E|+;
+}
+static method E|+(lowered final self::A #this, dynamic other) → dynamic
+  return 42;
+static method test(self::A a, self::E e) → dynamic {
+  a.{self::A::*}("foobar");
+  a.{self::A::[]}(0);
+  a.{self::A::[]=}(0, "foobar");
+  a.{self::A::unary-}();
+  self::E|+(a, "foobar");
+  invalid-expression "pkg/front_end/testcases/extension_types/simple_operator_resolution.dart:23:5: Error: The operator '*' isn't defined for the extension 'E'.
+Try correcting the operator to an existing operator, or defining a '*' operator.
+  e * \"foobar\"; // Error.
+    ^";
+  invalid-expression "pkg/front_end/testcases/extension_types/simple_operator_resolution.dart:24:4: Error: The operator '[]' isn't defined for the extension 'E'.
+Try correcting the operator to an existing operator, or defining a '[]' operator.
+  e[0]; // Error.
+   ^";
+  invalid-expression "pkg/front_end/testcases/extension_types/simple_operator_resolution.dart:25:4: Error: The operator '[]=' isn't defined for the extension 'E'.
+Try correcting the operator to an existing operator, or defining a '[]=' operator.
+  e[0] = \"foobar\"; // Error.
+   ^";
+  invalid-expression "pkg/front_end/testcases/extension_types/simple_operator_resolution.dart:26:3: Error: The operator 'unary-' isn't defined for the extension 'E'.
+Try correcting the operator to an existing operator, or defining a 'unary-' operator.
+  -e; // Error.
+  ^";
+  self::E|+(e, "foobar");
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/extension_types/simple_operator_resolution.dart.strong.transformed.expect b/pkg/front_end/testcases/extension_types/simple_operator_resolution.dart.strong.transformed.expect
new file mode 100644
index 0000000..80d58c8
--- /dev/null
+++ b/pkg/front_end/testcases/extension_types/simple_operator_resolution.dart.strong.transformed.expect
@@ -0,0 +1,69 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/extension_types/simple_operator_resolution.dart:23:5: Error: The operator '*' isn't defined for the extension 'E'.
+// Try correcting the operator to an existing operator, or defining a '*' operator.
+//   e * "foobar"; // Error.
+//     ^
+//
+// pkg/front_end/testcases/extension_types/simple_operator_resolution.dart:24:4: Error: The operator '[]' isn't defined for the extension 'E'.
+// Try correcting the operator to an existing operator, or defining a '[]' operator.
+//   e[0]; // Error.
+//    ^
+//
+// pkg/front_end/testcases/extension_types/simple_operator_resolution.dart:25:4: Error: The operator '[]=' isn't defined for the extension 'E'.
+// Try correcting the operator to an existing operator, or defining a '[]=' operator.
+//   e[0] = "foobar"; // Error.
+//    ^
+//
+// pkg/front_end/testcases/extension_types/simple_operator_resolution.dart:26:3: Error: The operator 'unary-' isn't defined for the extension 'E'.
+// Try correcting the operator to an existing operator, or defining a 'unary-' operator.
+//   -e; // Error.
+//   ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+  operator *(dynamic other) → dynamic
+    return 42;
+  operator [](core::int index) → dynamic
+    return 42;
+  operator []=(core::int index, dynamic value) → void {}
+  operator unary-() → dynamic
+    return 42;
+}
+extension E on self::A {
+  operator + = self::E|+;
+}
+static method E|+(lowered final self::A #this, dynamic other) → dynamic
+  return 42;
+static method test(self::A a, self::E e) → dynamic {
+  a.{self::A::*}("foobar");
+  a.{self::A::[]}(0);
+  a.{self::A::[]=}(0, "foobar");
+  a.{self::A::unary-}();
+  self::E|+(a, "foobar");
+  invalid-expression "pkg/front_end/testcases/extension_types/simple_operator_resolution.dart:23:5: Error: The operator '*' isn't defined for the extension 'E'.
+Try correcting the operator to an existing operator, or defining a '*' operator.
+  e * \"foobar\"; // Error.
+    ^";
+  invalid-expression "pkg/front_end/testcases/extension_types/simple_operator_resolution.dart:24:4: Error: The operator '[]' isn't defined for the extension 'E'.
+Try correcting the operator to an existing operator, or defining a '[]' operator.
+  e[0]; // Error.
+   ^";
+  invalid-expression "pkg/front_end/testcases/extension_types/simple_operator_resolution.dart:25:4: Error: The operator '[]=' isn't defined for the extension 'E'.
+Try correcting the operator to an existing operator, or defining a '[]=' operator.
+  e[0] = \"foobar\"; // Error.
+   ^";
+  invalid-expression "pkg/front_end/testcases/extension_types/simple_operator_resolution.dart:26:3: Error: The operator 'unary-' isn't defined for the extension 'E'.
+Try correcting the operator to an existing operator, or defining a 'unary-' operator.
+  -e; // Error.
+  ^";
+  self::E|+(e, "foobar");
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/extension_types/simple_operator_resolution.dart.textual_outline.expect b/pkg/front_end/testcases/extension_types/simple_operator_resolution.dart.textual_outline.expect
new file mode 100644
index 0000000..b773643
--- /dev/null
+++ b/pkg/front_end/testcases/extension_types/simple_operator_resolution.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+class A {
+  dynamic operator *(dynamic other) => 42;
+  dynamic operator [](int index) => 42;
+  void operator []=(int index, dynamic value) {}
+  dynamic operator -() => 42;
+}
+
+extension E on A {
+  dynamic operator +(dynamic other) => 42;
+}
+
+test(A a, E e) {}
+main() {}
diff --git a/pkg/front_end/testcases/extension_types/simple_operator_resolution.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extension_types/simple_operator_resolution.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3cbb6bf
--- /dev/null
+++ b/pkg/front_end/testcases/extension_types/simple_operator_resolution.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+class A {
+  dynamic operator *(dynamic other) => 42;
+  dynamic operator -() => 42;
+  dynamic operator [](int index) => 42;
+  void operator []=(int index, dynamic value) {}
+}
+
+extension E on A {
+  dynamic operator +(dynamic other) => 42;
+}
+
+main() {}
+test(A a, E e) {}
diff --git a/pkg/front_end/testcases/extension_types/simple_operator_resolution.dart.weak.expect b/pkg/front_end/testcases/extension_types/simple_operator_resolution.dart.weak.expect
new file mode 100644
index 0000000..80d58c8
--- /dev/null
+++ b/pkg/front_end/testcases/extension_types/simple_operator_resolution.dart.weak.expect
@@ -0,0 +1,69 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/extension_types/simple_operator_resolution.dart:23:5: Error: The operator '*' isn't defined for the extension 'E'.
+// Try correcting the operator to an existing operator, or defining a '*' operator.
+//   e * "foobar"; // Error.
+//     ^
+//
+// pkg/front_end/testcases/extension_types/simple_operator_resolution.dart:24:4: Error: The operator '[]' isn't defined for the extension 'E'.
+// Try correcting the operator to an existing operator, or defining a '[]' operator.
+//   e[0]; // Error.
+//    ^
+//
+// pkg/front_end/testcases/extension_types/simple_operator_resolution.dart:25:4: Error: The operator '[]=' isn't defined for the extension 'E'.
+// Try correcting the operator to an existing operator, or defining a '[]=' operator.
+//   e[0] = "foobar"; // Error.
+//    ^
+//
+// pkg/front_end/testcases/extension_types/simple_operator_resolution.dart:26:3: Error: The operator 'unary-' isn't defined for the extension 'E'.
+// Try correcting the operator to an existing operator, or defining a 'unary-' operator.
+//   -e; // Error.
+//   ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+  operator *(dynamic other) → dynamic
+    return 42;
+  operator [](core::int index) → dynamic
+    return 42;
+  operator []=(core::int index, dynamic value) → void {}
+  operator unary-() → dynamic
+    return 42;
+}
+extension E on self::A {
+  operator + = self::E|+;
+}
+static method E|+(lowered final self::A #this, dynamic other) → dynamic
+  return 42;
+static method test(self::A a, self::E e) → dynamic {
+  a.{self::A::*}("foobar");
+  a.{self::A::[]}(0);
+  a.{self::A::[]=}(0, "foobar");
+  a.{self::A::unary-}();
+  self::E|+(a, "foobar");
+  invalid-expression "pkg/front_end/testcases/extension_types/simple_operator_resolution.dart:23:5: Error: The operator '*' isn't defined for the extension 'E'.
+Try correcting the operator to an existing operator, or defining a '*' operator.
+  e * \"foobar\"; // Error.
+    ^";
+  invalid-expression "pkg/front_end/testcases/extension_types/simple_operator_resolution.dart:24:4: Error: The operator '[]' isn't defined for the extension 'E'.
+Try correcting the operator to an existing operator, or defining a '[]' operator.
+  e[0]; // Error.
+   ^";
+  invalid-expression "pkg/front_end/testcases/extension_types/simple_operator_resolution.dart:25:4: Error: The operator '[]=' isn't defined for the extension 'E'.
+Try correcting the operator to an existing operator, or defining a '[]=' operator.
+  e[0] = \"foobar\"; // Error.
+   ^";
+  invalid-expression "pkg/front_end/testcases/extension_types/simple_operator_resolution.dart:26:3: Error: The operator 'unary-' isn't defined for the extension 'E'.
+Try correcting the operator to an existing operator, or defining a 'unary-' operator.
+  -e; // Error.
+  ^";
+  self::E|+(e, "foobar");
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/extension_types/simple_operator_resolution.dart.weak.outline.expect b/pkg/front_end/testcases/extension_types/simple_operator_resolution.dart.weak.outline.expect
new file mode 100644
index 0000000..af29517
--- /dev/null
+++ b/pkg/front_end/testcases/extension_types/simple_operator_resolution.dart.weak.outline.expect
@@ -0,0 +1,25 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    ;
+  operator *(dynamic other) → dynamic
+    ;
+  operator [](core::int index) → dynamic
+    ;
+  operator []=(core::int index, dynamic value) → void
+    ;
+  operator unary-() → dynamic
+    ;
+}
+extension E on self::A {
+  operator + = self::E|+;
+}
+static method E|+(lowered final self::A #this, dynamic other) → dynamic
+  ;
+static method test(self::A a, self::E e) → dynamic
+  ;
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/extension_types/simple_operator_resolution.dart.weak.transformed.expect b/pkg/front_end/testcases/extension_types/simple_operator_resolution.dart.weak.transformed.expect
new file mode 100644
index 0000000..80d58c8
--- /dev/null
+++ b/pkg/front_end/testcases/extension_types/simple_operator_resolution.dart.weak.transformed.expect
@@ -0,0 +1,69 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/extension_types/simple_operator_resolution.dart:23:5: Error: The operator '*' isn't defined for the extension 'E'.
+// Try correcting the operator to an existing operator, or defining a '*' operator.
+//   e * "foobar"; // Error.
+//     ^
+//
+// pkg/front_end/testcases/extension_types/simple_operator_resolution.dart:24:4: Error: The operator '[]' isn't defined for the extension 'E'.
+// Try correcting the operator to an existing operator, or defining a '[]' operator.
+//   e[0]; // Error.
+//    ^
+//
+// pkg/front_end/testcases/extension_types/simple_operator_resolution.dart:25:4: Error: The operator '[]=' isn't defined for the extension 'E'.
+// Try correcting the operator to an existing operator, or defining a '[]=' operator.
+//   e[0] = "foobar"; // Error.
+//    ^
+//
+// pkg/front_end/testcases/extension_types/simple_operator_resolution.dart:26:3: Error: The operator 'unary-' isn't defined for the extension 'E'.
+// Try correcting the operator to an existing operator, or defining a 'unary-' operator.
+//   -e; // Error.
+//   ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+  operator *(dynamic other) → dynamic
+    return 42;
+  operator [](core::int index) → dynamic
+    return 42;
+  operator []=(core::int index, dynamic value) → void {}
+  operator unary-() → dynamic
+    return 42;
+}
+extension E on self::A {
+  operator + = self::E|+;
+}
+static method E|+(lowered final self::A #this, dynamic other) → dynamic
+  return 42;
+static method test(self::A a, self::E e) → dynamic {
+  a.{self::A::*}("foobar");
+  a.{self::A::[]}(0);
+  a.{self::A::[]=}(0, "foobar");
+  a.{self::A::unary-}();
+  self::E|+(a, "foobar");
+  invalid-expression "pkg/front_end/testcases/extension_types/simple_operator_resolution.dart:23:5: Error: The operator '*' isn't defined for the extension 'E'.
+Try correcting the operator to an existing operator, or defining a '*' operator.
+  e * \"foobar\"; // Error.
+    ^";
+  invalid-expression "pkg/front_end/testcases/extension_types/simple_operator_resolution.dart:24:4: Error: The operator '[]' isn't defined for the extension 'E'.
+Try correcting the operator to an existing operator, or defining a '[]' operator.
+  e[0]; // Error.
+   ^";
+  invalid-expression "pkg/front_end/testcases/extension_types/simple_operator_resolution.dart:25:4: Error: The operator '[]=' isn't defined for the extension 'E'.
+Try correcting the operator to an existing operator, or defining a '[]=' operator.
+  e[0] = \"foobar\"; // Error.
+   ^";
+  invalid-expression "pkg/front_end/testcases/extension_types/simple_operator_resolution.dart:26:3: Error: The operator 'unary-' isn't defined for the extension 'E'.
+Try correcting the operator to an existing operator, or defining a 'unary-' operator.
+  -e; // Error.
+  ^";
+  self::E|+(e, "foobar");
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/extension_types/simple_setter_resolution.dart b/pkg/front_end/testcases/extension_types/simple_setter_resolution.dart
new file mode 100644
index 0000000..20f43d6
--- /dev/null
+++ b/pkg/front_end/testcases/extension_types/simple_setter_resolution.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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 {
+  void set foo(int value) {}
+}
+
+extension E on A {
+  void set bar(int value) {}
+}
+
+test(A a, E e) {
+  a.foo = 42; // Ok.
+  a.bar = 42; // Ok.
+  e.foo = 42; // Error.
+  e.bar = 42; // Ok.
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/extension_types/simple_setter_resolution.dart.strong.expect b/pkg/front_end/testcases/extension_types/simple_setter_resolution.dart.strong.expect
new file mode 100644
index 0000000..c7f4354
--- /dev/null
+++ b/pkg/front_end/testcases/extension_types/simple_setter_resolution.dart.strong.expect
@@ -0,0 +1,32 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/extension_types/simple_setter_resolution.dart:16:5: Error: The setter 'foo' isn't defined for the extension 'E'.
+// Try correcting the name to the name of an existing setter, or defining a setter or field named 'foo'.
+//   e.foo = 42; // Error.
+//     ^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+  set foo(core::int value) → void {}
+}
+extension E on self::A {
+  set bar = self::E|set#bar;
+}
+static method E|set#bar(lowered final self::A #this, core::int value) → void {}
+static method test(self::A a, self::E e) → dynamic {
+  a.{self::A::foo} = 42;
+  self::E|set#bar(a, 42);
+  invalid-expression "pkg/front_end/testcases/extension_types/simple_setter_resolution.dart:16:5: Error: The setter 'foo' isn't defined for the extension 'E'.
+Try correcting the name to the name of an existing setter, or defining a setter or field named 'foo'.
+  e.foo = 42; // Error.
+    ^^^";
+  self::E|set#bar(e, 42);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/extension_types/simple_setter_resolution.dart.strong.transformed.expect b/pkg/front_end/testcases/extension_types/simple_setter_resolution.dart.strong.transformed.expect
new file mode 100644
index 0000000..c7f4354
--- /dev/null
+++ b/pkg/front_end/testcases/extension_types/simple_setter_resolution.dart.strong.transformed.expect
@@ -0,0 +1,32 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/extension_types/simple_setter_resolution.dart:16:5: Error: The setter 'foo' isn't defined for the extension 'E'.
+// Try correcting the name to the name of an existing setter, or defining a setter or field named 'foo'.
+//   e.foo = 42; // Error.
+//     ^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+  set foo(core::int value) → void {}
+}
+extension E on self::A {
+  set bar = self::E|set#bar;
+}
+static method E|set#bar(lowered final self::A #this, core::int value) → void {}
+static method test(self::A a, self::E e) → dynamic {
+  a.{self::A::foo} = 42;
+  self::E|set#bar(a, 42);
+  invalid-expression "pkg/front_end/testcases/extension_types/simple_setter_resolution.dart:16:5: Error: The setter 'foo' isn't defined for the extension 'E'.
+Try correcting the name to the name of an existing setter, or defining a setter or field named 'foo'.
+  e.foo = 42; // Error.
+    ^^^";
+  self::E|set#bar(e, 42);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/extension_types/simple_setter_resolution.dart.textual_outline.expect b/pkg/front_end/testcases/extension_types/simple_setter_resolution.dart.textual_outline.expect
new file mode 100644
index 0000000..d7b5425
--- /dev/null
+++ b/pkg/front_end/testcases/extension_types/simple_setter_resolution.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+class A {
+  void set foo(int value) {}
+}
+
+extension E on A {
+  void set bar(int value) {}
+}
+
+test(A a, E e) {}
+main() {}
diff --git a/pkg/front_end/testcases/extension_types/simple_setter_resolution.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extension_types/simple_setter_resolution.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..74b9e08
--- /dev/null
+++ b/pkg/front_end/testcases/extension_types/simple_setter_resolution.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+class A {
+  void set foo(int value) {}
+}
+
+extension E on A {
+  void set bar(int value) {}
+}
+
+main() {}
+test(A a, E e) {}
diff --git a/pkg/front_end/testcases/extension_types/simple_setter_resolution.dart.weak.expect b/pkg/front_end/testcases/extension_types/simple_setter_resolution.dart.weak.expect
new file mode 100644
index 0000000..c7f4354
--- /dev/null
+++ b/pkg/front_end/testcases/extension_types/simple_setter_resolution.dart.weak.expect
@@ -0,0 +1,32 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/extension_types/simple_setter_resolution.dart:16:5: Error: The setter 'foo' isn't defined for the extension 'E'.
+// Try correcting the name to the name of an existing setter, or defining a setter or field named 'foo'.
+//   e.foo = 42; // Error.
+//     ^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+  set foo(core::int value) → void {}
+}
+extension E on self::A {
+  set bar = self::E|set#bar;
+}
+static method E|set#bar(lowered final self::A #this, core::int value) → void {}
+static method test(self::A a, self::E e) → dynamic {
+  a.{self::A::foo} = 42;
+  self::E|set#bar(a, 42);
+  invalid-expression "pkg/front_end/testcases/extension_types/simple_setter_resolution.dart:16:5: Error: The setter 'foo' isn't defined for the extension 'E'.
+Try correcting the name to the name of an existing setter, or defining a setter or field named 'foo'.
+  e.foo = 42; // Error.
+    ^^^";
+  self::E|set#bar(e, 42);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/extension_types/simple_setter_resolution.dart.weak.outline.expect b/pkg/front_end/testcases/extension_types/simple_setter_resolution.dart.weak.outline.expect
new file mode 100644
index 0000000..05a6bb6
--- /dev/null
+++ b/pkg/front_end/testcases/extension_types/simple_setter_resolution.dart.weak.outline.expect
@@ -0,0 +1,19 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    ;
+  set foo(core::int value) → void
+    ;
+}
+extension E on self::A {
+  set bar = self::E|set#bar;
+}
+static method E|set#bar(lowered final self::A #this, core::int value) → void
+  ;
+static method test(self::A a, self::E e) → dynamic
+  ;
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/extension_types/simple_setter_resolution.dart.weak.transformed.expect b/pkg/front_end/testcases/extension_types/simple_setter_resolution.dart.weak.transformed.expect
new file mode 100644
index 0000000..c7f4354
--- /dev/null
+++ b/pkg/front_end/testcases/extension_types/simple_setter_resolution.dart.weak.transformed.expect
@@ -0,0 +1,32 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/extension_types/simple_setter_resolution.dart:16:5: Error: The setter 'foo' isn't defined for the extension 'E'.
+// Try correcting the name to the name of an existing setter, or defining a setter or field named 'foo'.
+//   e.foo = 42; // Error.
+//     ^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+  set foo(core::int value) → void {}
+}
+extension E on self::A {
+  set bar = self::E|set#bar;
+}
+static method E|set#bar(lowered final self::A #this, core::int value) → void {}
+static method test(self::A a, self::E e) → dynamic {
+  a.{self::A::foo} = 42;
+  self::E|set#bar(a, 42);
+  invalid-expression "pkg/front_end/testcases/extension_types/simple_setter_resolution.dart:16:5: Error: The setter 'foo' isn't defined for the extension 'E'.
+Try correcting the name to the name of an existing setter, or defining a setter or field named 'foo'.
+  e.foo = 42; // Error.
+    ^^^";
+  self::E|set#bar(e, 42);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/extensions/invalid_explicit_access.dart.weak.expect b/pkg/front_end/testcases/extensions/invalid_explicit_access.dart.weak.expect
index 8c0ab7a..3dfc9a6 100644
--- a/pkg/front_end/testcases/extensions/invalid_explicit_access.dart.weak.expect
+++ b/pkg/front_end/testcases/extensions/invalid_explicit_access.dart.weak.expect
@@ -34,14 +34,14 @@
 //   Extension(c1).foo();
 //                 ^^^
 //
-// pkg/front_end/testcases/extensions/invalid_explicit_access.dart:32:17: Error: Too few positional arguments: 2 required, 1 given.
+// pkg/front_end/testcases/extensions/invalid_explicit_access.dart:32:17: Error: Too few positional arguments: 1 required, 0 given.
 //   Extension(c1).method();
 //                 ^
 // pkg/front_end/testcases/extensions/invalid_explicit_access.dart:8:3: Context: Found this candidate, but the arguments don't match.
 //   method(a) {}
 //   ^^^^^^^^^^^^^...
 //
-// pkg/front_end/testcases/extensions/invalid_explicit_access.dart:36:17: Error: Too many positional arguments: 2 allowed, but 3 found.
+// pkg/front_end/testcases/extensions/invalid_explicit_access.dart:36:17: Error: Too many positional arguments: 1 allowed, but 2 found.
 // Try removing the extra positional arguments.
 //   Extension(c1).method(1, 2);
 //                 ^
@@ -49,7 +49,7 @@
 //   method(a) {}
 //   ^^^^^^^^^^^^^...
 //
-// pkg/front_end/testcases/extensions/invalid_explicit_access.dart:37:17: Error: Too few positional arguments: 2 required, 1 given.
+// pkg/front_end/testcases/extensions/invalid_explicit_access.dart:37:17: Error: Too few positional arguments: 1 required, 0 given.
 //   Extension(c1).method(a: 1);
 //                 ^
 // pkg/front_end/testcases/extensions/invalid_explicit_access.dart:8:3: Context: Found this candidate, but the arguments don't match.
@@ -199,14 +199,14 @@
   invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:31:17: Error: Method not found: 'foo'.
   Extension(c1).foo();
                 ^^^";
-  invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:32:17: Error: Too few positional arguments: 2 required, 1 given.
+  invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:32:17: Error: Too few positional arguments: 1 required, 0 given.
   Extension(c1).method();
                 ^";
-  invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:36:17: Error: Too many positional arguments: 2 allowed, but 3 found.
+  invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:36:17: Error: Too many positional arguments: 1 allowed, but 2 found.
 Try removing the extra positional arguments.
   Extension(c1).method(1, 2);
                 ^";
-  invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:37:17: Error: Too few positional arguments: 2 required, 1 given.
+  invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:37:17: Error: Too few positional arguments: 1 required, 0 given.
   Extension(c1).method(a: 1);
                 ^";
   invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:38:27: Error: No named parameter with the name 'a'.
diff --git a/pkg/front_end/testcases/extensions/invalid_explicit_access.dart.weak.transformed.expect b/pkg/front_end/testcases/extensions/invalid_explicit_access.dart.weak.transformed.expect
index 8c0ab7a..3dfc9a6 100644
--- a/pkg/front_end/testcases/extensions/invalid_explicit_access.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/extensions/invalid_explicit_access.dart.weak.transformed.expect
@@ -34,14 +34,14 @@
 //   Extension(c1).foo();
 //                 ^^^
 //
-// pkg/front_end/testcases/extensions/invalid_explicit_access.dart:32:17: Error: Too few positional arguments: 2 required, 1 given.
+// pkg/front_end/testcases/extensions/invalid_explicit_access.dart:32:17: Error: Too few positional arguments: 1 required, 0 given.
 //   Extension(c1).method();
 //                 ^
 // pkg/front_end/testcases/extensions/invalid_explicit_access.dart:8:3: Context: Found this candidate, but the arguments don't match.
 //   method(a) {}
 //   ^^^^^^^^^^^^^...
 //
-// pkg/front_end/testcases/extensions/invalid_explicit_access.dart:36:17: Error: Too many positional arguments: 2 allowed, but 3 found.
+// pkg/front_end/testcases/extensions/invalid_explicit_access.dart:36:17: Error: Too many positional arguments: 1 allowed, but 2 found.
 // Try removing the extra positional arguments.
 //   Extension(c1).method(1, 2);
 //                 ^
@@ -49,7 +49,7 @@
 //   method(a) {}
 //   ^^^^^^^^^^^^^...
 //
-// pkg/front_end/testcases/extensions/invalid_explicit_access.dart:37:17: Error: Too few positional arguments: 2 required, 1 given.
+// pkg/front_end/testcases/extensions/invalid_explicit_access.dart:37:17: Error: Too few positional arguments: 1 required, 0 given.
 //   Extension(c1).method(a: 1);
 //                 ^
 // pkg/front_end/testcases/extensions/invalid_explicit_access.dart:8:3: Context: Found this candidate, but the arguments don't match.
@@ -199,14 +199,14 @@
   invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:31:17: Error: Method not found: 'foo'.
   Extension(c1).foo();
                 ^^^";
-  invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:32:17: Error: Too few positional arguments: 2 required, 1 given.
+  invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:32:17: Error: Too few positional arguments: 1 required, 0 given.
   Extension(c1).method();
                 ^";
-  invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:36:17: Error: Too many positional arguments: 2 allowed, but 3 found.
+  invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:36:17: Error: Too many positional arguments: 1 allowed, but 2 found.
 Try removing the extra positional arguments.
   Extension(c1).method(1, 2);
                 ^";
-  invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:37:17: Error: Too few positional arguments: 2 required, 1 given.
+  invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:37:17: Error: Too few positional arguments: 1 required, 0 given.
   Extension(c1).method(a: 1);
                 ^";
   invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:38:27: Error: No named parameter with the name 'a'.
diff --git a/pkg/front_end/testcases/general/annotation_top.dart.weak.outline.expect b/pkg/front_end/testcases/general/annotation_top.dart.weak.outline.expect
index a3676d1..f0fe7fb 100644
--- a/pkg/front_end/testcases/general/annotation_top.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/general/annotation_top.dart.weak.outline.expect
@@ -4,7 +4,11 @@
 import self as self;
 import "dart:core" as core;
 
+@self::a
+@self::A::•(2)
 typedef F1 = () →* void;
+@self::a
+@self::A::•(3)
 typedef F2 = () →* void;
 class A extends core::Object /*hasConstConstructor*/  {
   const constructor •(core::int* value) → self::A*
@@ -53,6 +57,10 @@
 Extra constant evaluation status:
 Evaluated: StaticGet @ org-dartlang-testcase:///annotation_top.dart:5:2 -> InstanceConstant(const Object{})
 Evaluated: ConstructorInvocation @ org-dartlang-testcase:///annotation_top.dart:6:2 -> InstanceConstant(const A{})
+Evaluated: StaticGet @ org-dartlang-testcase:///annotation_top.dart:19:2 -> InstanceConstant(const Object{})
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///annotation_top.dart:20:2 -> InstanceConstant(const A{})
+Evaluated: StaticGet @ org-dartlang-testcase:///annotation_top.dart:23:2 -> InstanceConstant(const Object{})
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///annotation_top.dart:24:2 -> InstanceConstant(const A{})
 Evaluated: StaticGet @ org-dartlang-testcase:///annotation_top.dart:15:2 -> InstanceConstant(const Object{})
 Evaluated: ConstructorInvocation @ org-dartlang-testcase:///annotation_top.dart:16:2 -> InstanceConstant(const A{})
 Evaluated: StaticGet @ org-dartlang-testcase:///annotation_top.dart:31:2 -> InstanceConstant(const Object{})
@@ -62,4 +70,4 @@
 Evaluated: ConstructorInvocation @ org-dartlang-testcase:///annotation_top.dart:28:2 -> InstanceConstant(const A{})
 Evaluated: StaticGet @ org-dartlang-testcase:///annotation_top.dart:27:2 -> InstanceConstant(const Object{})
 Evaluated: ConstructorInvocation @ org-dartlang-testcase:///annotation_top.dart:28:2 -> InstanceConstant(const A{})
-Extra constant evaluation: evaluated: 11, effectively constant: 11
+Extra constant evaluation: evaluated: 15, effectively constant: 15
diff --git a/pkg/front_end/testcases/general/constants/js_semantics/folder.options b/pkg/front_end/testcases/general/constants/js_semantics/folder.options
index 674c362..7a017fa 100644
--- a/pkg/front_end/testcases/general/constants/js_semantics/folder.options
+++ b/pkg/front_end/testcases/general/constants/js_semantics/folder.options
@@ -1,2 +1,2 @@
 --enable-experiment=triple-shift
---target=noneWithJs
\ No newline at end of file
+--target=dart2js
\ No newline at end of file
diff --git a/pkg/front_end/testcases/general/constants/js_semantics/issue45376.dart b/pkg/front_end/testcases/general/constants/js_semantics/issue45376.dart
new file mode 100644
index 0000000..81c2ce24
--- /dev/null
+++ b/pkg/front_end/testcases/general/constants/js_semantics/issue45376.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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 MyClass {
+  final int a;
+  final int b;
+  const MyClass(i1, i2) : a = (i1 >>> i2), b = (i1 >>> i2);
+}
+
+test() {
+  const MyClass c1 = MyClass(1.0, 1);
+}
+
+main() {}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/general/constants/js_semantics/issue45376.dart.textual_outline.expect b/pkg/front_end/testcases/general/constants/js_semantics/issue45376.dart.textual_outline.expect
new file mode 100644
index 0000000..3e39af0
--- /dev/null
+++ b/pkg/front_end/testcases/general/constants/js_semantics/issue45376.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+class MyClass {
+  final int a;
+  final int b;
+  const MyClass(i1, i2)
+      : a = (i1 >>> i2),
+        b = (i1 >>> i2);
+}
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/general/constants/js_semantics/issue45376.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/constants/js_semantics/issue45376.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..827c2fb
--- /dev/null
+++ b/pkg/front_end/testcases/general/constants/js_semantics/issue45376.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+class MyClass {
+  const MyClass(i1, i2)
+      : a = (i1 >>> i2),
+        b = (i1 >>> i2);
+  final int a;
+  final int b;
+}
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general/constants/js_semantics/issue45376.dart.weak.expect b/pkg/front_end/testcases/general/constants/js_semantics/issue45376.dart.weak.expect
new file mode 100644
index 0000000..bdbea12
--- /dev/null
+++ b/pkg/front_end/testcases/general/constants/js_semantics/issue45376.dart.weak.expect
@@ -0,0 +1,20 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class MyClass extends core::Object /*hasConstConstructor*/  {
+  final field core::int a;
+  final field core::int b;
+  const constructor •(dynamic i1, dynamic i2) → self::MyClass
+    : self::MyClass::a = i1{dynamic}.>>>(i2) as{TypeError,ForDynamic,ForNonNullableByDefault} core::int, self::MyClass::b = i1{dynamic}.>>>(i2) as{TypeError,ForDynamic,ForNonNullableByDefault} core::int, super core::Object::•()
+    ;
+}
+static method test() → dynamic {}
+static method main() → dynamic {}
+
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///issue45376.dart:
+- MyClass. (from org-dartlang-testcase:///issue45376.dart:8:9)
+- Object. (from org-dartlang-sdk:///lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/general/constants/js_semantics/issue45376.dart.weak.outline.expect b/pkg/front_end/testcases/general/constants/js_semantics/issue45376.dart.weak.outline.expect
new file mode 100644
index 0000000..dcdb486
--- /dev/null
+++ b/pkg/front_end/testcases/general/constants/js_semantics/issue45376.dart.weak.outline.expect
@@ -0,0 +1,15 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class MyClass extends core::Object /*hasConstConstructor*/  {
+  final field core::int a;
+  final field core::int b;
+  const constructor •(dynamic i1, dynamic i2) → self::MyClass
+    : self::MyClass::a = i1{dynamic}.>>>(i2) as{TypeError,ForDynamic,ForNonNullableByDefault} core::int, self::MyClass::b = i1{dynamic}.>>>(i2) as{TypeError,ForDynamic,ForNonNullableByDefault} core::int, super core::Object::•()
+    ;
+}
+static method test() → dynamic
+  ;
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/general/constants/js_semantics/issue45376.dart.weak.transformed.expect b/pkg/front_end/testcases/general/constants/js_semantics/issue45376.dart.weak.transformed.expect
new file mode 100644
index 0000000..bdbea12
--- /dev/null
+++ b/pkg/front_end/testcases/general/constants/js_semantics/issue45376.dart.weak.transformed.expect
@@ -0,0 +1,20 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class MyClass extends core::Object /*hasConstConstructor*/  {
+  final field core::int a;
+  final field core::int b;
+  const constructor •(dynamic i1, dynamic i2) → self::MyClass
+    : self::MyClass::a = i1{dynamic}.>>>(i2) as{TypeError,ForDynamic,ForNonNullableByDefault} core::int, self::MyClass::b = i1{dynamic}.>>>(i2) as{TypeError,ForDynamic,ForNonNullableByDefault} core::int, super core::Object::•()
+    ;
+}
+static method test() → dynamic {}
+static method main() → dynamic {}
+
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///issue45376.dart:
+- MyClass. (from org-dartlang-testcase:///issue45376.dart:8:9)
+- Object. (from org-dartlang-sdk:///lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart b/pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart
index cc1f967..04a3d28 100644
--- a/pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart
+++ b/pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart
@@ -1,7 +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.
-// @dart=2.9
+
 const int shiftNegative1 = 2 << -1;
 const int shiftNegative2 = 2 >>> -1;
 const int shiftNegative3 = 2 >> -1;
@@ -23,7 +23,6 @@
 const int binaryXor = 63 ^ 21;
 const int binaryShift1 = 21 << 1;
 
-// These aren't currently defined on int :(.
 const int binaryShift2 = 84 >>> 1;
 const int binaryShift3 = 21 >>> 64;
 
@@ -36,7 +35,8 @@
 
 const int doubleTruncateDiv = 84.2 ~/ 2;
 const int doubleTruncateDivZero = 84.2 ~/ 0;
-const int doubleTruncateDivNull = 84.2 ~/ null;
+const dynamic nil = null;
+const int doubleTruncateDivNull = 84.2 ~/ nil;
 const double doubleNan = 0/0;
 const int doubleTruncateDivNaN = 84.2 ~/ doubleNan;
 
diff --git a/pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart.textual_outline.expect b/pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart.textual_outline.expect
index 4be3a27..4a2cf37 100644
--- a/pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart.textual_outline.expect
@@ -1,4 +1,3 @@
-// @dart = 2.9
 const int shiftNegative1 = 2 << -1;
 const int shiftNegative2 = 2 >>> -1;
 const int shiftNegative3 = 2 >> -1;
@@ -28,7 +27,8 @@
 const bool binaryGreater = 42 > 42;
 const int doubleTruncateDiv = 84.2 ~/ 2;
 const int doubleTruncateDivZero = 84.2 ~/ 0;
-const int doubleTruncateDivNull = 84.2 ~/ null;
+const dynamic nil = null;
+const int doubleTruncateDivNull = 84.2 ~/ nil;
 const double doubleNan = 0/0;
 const int doubleTruncateDivNaN = 84.2 ~/ doubleNan;
 const int bigNumber = 0x8000000000000000;
diff --git a/pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart.weak.expect b/pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart.weak.expect
index bb1a380..e2269a8 100644
--- a/pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart.weak.expect
+++ b/pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart.weak.expect
@@ -1,4 +1,4 @@
-library;
+library /*isNonNullableByDefault*/;
 //
 // Problems in library:
 //
@@ -61,24 +61,24 @@
 // const int intdivZero = 2 ~/ 0;
 //           ^
 //
-// pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart:38:40: Error: Constant evaluation error:
+// pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart:37:40: Error: Constant evaluation error:
 // const int doubleTruncateDivZero = 84.2 ~/ 0;
 //                                        ^
-// pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart:38:40: Context: Binary operator '~/' on '84.2' requires non-zero divisor, but divisor was '0'.
+// pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart:37:40: Context: Binary operator '~/' on '84.2' requires non-zero divisor, but divisor was '0'.
 // const int doubleTruncateDivZero = 84.2 ~/ 0;
 //                                        ^
-// pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart:38:11: Context: While analyzing:
+// pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart:37:11: Context: While analyzing:
 // const int doubleTruncateDivZero = 84.2 ~/ 0;
 //           ^
 //
 // pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart:39:40: Error: Constant evaluation error:
-// const int doubleTruncateDivNull = 84.2 ~/ null;
+// const int doubleTruncateDivNull = 84.2 ~/ nil;
 //                                        ^
 // pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart:39:40: Context: Binary operator '~/' on '84.2' requires operand of type 'num', but was of type 'Null'.
-// const int doubleTruncateDivNull = 84.2 ~/ null;
+// const int doubleTruncateDivNull = 84.2 ~/ nil;
 //                                        ^
 // pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart:39:11: Context: While analyzing:
-// const int doubleTruncateDivNull = 84.2 ~/ null;
+// const int doubleTruncateDivNull = 84.2 ~/ nil;
 //           ^
 //
 // pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart:41:39: Error: Constant evaluation error:
@@ -94,43 +94,44 @@
 import self as self;
 import "dart:core" as core;
 
-static const field core::int* shiftNegative1 = invalid-expression "Binary operator '<<' on '2.0' requires non-negative operand, but was '-1.0'.";
-static const field core::int* shiftNegative2 = invalid-expression "Binary operator '>>>' on '2.0' requires non-negative operand, but was '-1.0'.";
-static const field core::int* shiftNegative3 = invalid-expression "Binary operator '>>' on '2.0' requires non-negative operand, but was '-1.0'.";
-static const field core::int* modZero = invalid-expression "Binary operator '%' on '2.0' requires non-zero divisor, but divisor was '0'.";
-static const field core::int* divZero = invalid-expression "pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart:9:23: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+static const field core::int shiftNegative1 = invalid-expression "Binary operator '<<' on '2.0' requires non-negative operand, but was '-1.0'.";
+static const field core::int shiftNegative2 = invalid-expression "Binary operator '>>>' on '2.0' requires non-negative operand, but was '-1.0'.";
+static const field core::int shiftNegative3 = invalid-expression "Binary operator '>>' on '2.0' requires non-negative operand, but was '-1.0'.";
+static const field core::int modZero = invalid-expression "Binary operator '%' on '2.0' requires non-zero divisor, but divisor was '0'.";
+static const field core::int divZero = invalid-expression "pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart:9:23: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
 const int divZero = 2 / 0;
                       ^";
-static const field core::int* intdivZero = invalid-expression "Binary operator '~/' on '2.0' requires non-zero divisor, but divisor was '0'.";
-static const field core::int* unaryMinus = #C1;
-static const field core::int* unaryTilde = #C2;
-static const field core::int* unaryPlus = invalid-expression "pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart:13:23: Error: This couldn't be parsed.
+static const field core::int intdivZero = invalid-expression "Binary operator '~/' on '2.0' requires non-zero divisor, but divisor was '0'.";
+static const field core::int unaryMinus = #C1;
+static const field core::int unaryTilde = #C2;
+static const field core::int unaryPlus = invalid-expression "pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart:13:23: Error: This couldn't be parsed.
 const int unaryPlus = +2;
                       ^";
-static const field core::int* binaryPlus = #C3;
-static const field core::int* binaryMinus = #C3;
-static const field core::int* binaryTimes = #C3;
-static const field core::double* binaryDiv = #C3;
-static const field core::int* binaryTildeDiv = #C3;
-static const field core::int* binaryMod = #C3;
-static const field core::int* binaryOr = #C3;
-static const field core::int* binaryAnd = #C3;
-static const field core::int* binaryXor = #C3;
-static const field core::int* binaryShift1 = #C3;
-static const field core::int* binaryShift2 = #C3;
-static const field core::int* binaryShift3 = #C4;
-static const field core::int* binaryShift4 = #C3;
-static const field core::int* binaryShift5 = #C5;
-static const field core::bool* binaryLess = #C6;
-static const field core::bool* binaryLessEqual = #C7;
-static const field core::bool* binaryGreaterEqual = #C7;
-static const field core::bool* binaryGreater = #C6;
-static const field core::int* doubleTruncateDiv = #C3;
-static const field core::int* doubleTruncateDivZero = invalid-expression "Binary operator '~/' on '84.2' requires non-zero divisor, but divisor was '0'.";
-static const field core::int* doubleTruncateDivNull = invalid-expression "Binary operator '~/' on '84.2' requires operand of type 'num', but was of type 'Null'.";
-static const field core::double* doubleNan = #C8;
-static const field core::int* doubleTruncateDivNaN = invalid-expression "Binary operator '84.2 ~/ NaN' results is Infinity or NaN.";
-static const field core::int* bigNumber = #C9;
+static const field core::int binaryPlus = #C3;
+static const field core::int binaryMinus = #C3;
+static const field core::int binaryTimes = #C3;
+static const field core::double binaryDiv = #C3;
+static const field core::int binaryTildeDiv = #C3;
+static const field core::int binaryMod = #C3;
+static const field core::int binaryOr = #C3;
+static const field core::int binaryAnd = #C3;
+static const field core::int binaryXor = #C3;
+static const field core::int binaryShift1 = #C3;
+static const field core::int binaryShift2 = #C3;
+static const field core::int binaryShift3 = #C4;
+static const field core::int binaryShift4 = #C3;
+static const field core::int binaryShift5 = #C5;
+static const field core::bool binaryLess = #C6;
+static const field core::bool binaryLessEqual = #C7;
+static const field core::bool binaryGreaterEqual = #C7;
+static const field core::bool binaryGreater = #C6;
+static const field core::int doubleTruncateDiv = #C3;
+static const field core::int doubleTruncateDivZero = invalid-expression "Binary operator '~/' on '84.2' requires non-zero divisor, but divisor was '0'.";
+static const field dynamic nil = #C8;
+static const field core::int doubleTruncateDivNull = invalid-expression "Binary operator '~/' on '84.2' requires operand of type 'num', but was of type 'Null'.";
+static const field core::double doubleNan = #C9;
+static const field core::int doubleTruncateDivNaN = invalid-expression "Binary operator '84.2 ~/ NaN' results is Infinity or NaN.";
+static const field core::int bigNumber = #C10;
 static method main() → dynamic {}
 
 constants  {
@@ -141,6 +142,7 @@
   #C5 = 4294967295.0
   #C6 = false
   #C7 = true
-  #C8 = NaN
-  #C9 = 9223372036854776000.0
+  #C8 = null
+  #C9 = NaN
+  #C10 = 9223372036854776000.0
 }
diff --git a/pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart.weak.outline.expect b/pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart.weak.outline.expect
index 3efcc8e..2aa115c 100644
--- a/pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart.weak.outline.expect
@@ -1,4 +1,4 @@
-library;
+library /*isNonNullableByDefault*/;
 //
 // Problems in library:
 //
@@ -14,43 +14,44 @@
 import self as self;
 import "dart:core" as core;
 
-static const field core::int* shiftNegative1 = 2.{core::int::<<}(1.{core::int::unary-}(){() →* core::int*}){(core::int*) →* core::int*};
-static const field core::int* shiftNegative2 = 2.{core::int::>>>}(1.{core::int::unary-}(){() →* core::int*}){(core::int*) →* core::int*};
-static const field core::int* shiftNegative3 = 2.{core::int::>>}(1.{core::int::unary-}(){() →* core::int*}){(core::int*) →* core::int*};
-static const field core::int* modZero = 2.{core::num::%}(0){(core::num*) →* core::int*};
-static const field core::int* divZero = let final Never* #t1 = invalid-expression "pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart:9:23: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+static const field core::int shiftNegative1 = 2.{core::int::<<}(1.{core::int::unary-}(){() → core::int}){(core::int) → core::int};
+static const field core::int shiftNegative2 = 2.{core::int::>>>}(1.{core::int::unary-}(){() → core::int}){(core::int) → core::int};
+static const field core::int shiftNegative3 = 2.{core::int::>>}(1.{core::int::unary-}(){() → core::int}){(core::int) → core::int};
+static const field core::int modZero = 2.{core::num::%}(0){(core::num) → core::int};
+static const field core::int divZero = let final Never #t1 = invalid-expression "pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart:9:23: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
 const int divZero = 2 / 0;
-                      ^" in 2.{core::num::/}(0){(core::num*) →* core::double*} as{TypeError} core::int*;
-static const field core::int* intdivZero = 2.{core::num::~/}(0){(core::num*) →* core::int*};
-static const field core::int* unaryMinus = 2.{core::int::unary-}(){() →* core::int*};
-static const field core::int* unaryTilde = 2.{core::int::~}(){() →* core::int*};
-static const field core::int* unaryPlus = invalid-expression "pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart:13:23: Error: This couldn't be parsed.
+                      ^" in 2.{core::num::/}(0){(core::num) → core::double} as{TypeError,ForNonNullableByDefault} core::int;
+static const field core::int intdivZero = 2.{core::num::~/}(0){(core::num) → core::int};
+static const field core::int unaryMinus = 2.{core::int::unary-}(){() → core::int};
+static const field core::int unaryTilde = 2.{core::int::~}(){() → core::int};
+static const field core::int unaryPlus = invalid-expression "pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart:13:23: Error: This couldn't be parsed.
 const int unaryPlus = +2;
-                      ^"{dynamic}.+(2) as{TypeError,ForDynamic} core::int*;
-static const field core::int* binaryPlus = 40.{core::num::+}(2){(core::num*) →* core::int*};
-static const field core::int* binaryMinus = 44.{core::num::-}(2){(core::num*) →* core::int*};
-static const field core::int* binaryTimes = 21.{core::num::*}(2){(core::num*) →* core::int*};
-static const field core::double* binaryDiv = 84.{core::num::/}(2){(core::num*) →* core::double*};
-static const field core::int* binaryTildeDiv = 84.{core::num::~/}(2){(core::num*) →* core::int*};
-static const field core::int* binaryMod = 85.{core::num::%}(43){(core::num*) →* core::int*};
-static const field core::int* binaryOr = 32.{core::int::|}(10){(core::int*) →* core::int*};
-static const field core::int* binaryAnd = 63.{core::int::&}(106){(core::int*) →* core::int*};
-static const field core::int* binaryXor = 63.{core::int::^}(21){(core::int*) →* core::int*};
-static const field core::int* binaryShift1 = 21.{core::int::<<}(1){(core::int*) →* core::int*};
-static const field core::int* binaryShift2 = 84.{core::int::>>>}(1){(core::int*) →* core::int*};
-static const field core::int* binaryShift3 = 21.{core::int::>>>}(64){(core::int*) →* core::int*};
-static const field core::int* binaryShift4 = 84.{core::int::>>}(1){(core::int*) →* core::int*};
-static const field core::int* binaryShift5 = 1.{core::int::unary-}(){() →* core::int*}.{core::int::>>}(1){(core::int*) →* core::int*};
-static const field core::bool* binaryLess = 42.{core::num::<}(42){(core::num*) →* core::bool*};
-static const field core::bool* binaryLessEqual = 42.{core::num::<=}(42){(core::num*) →* core::bool*};
-static const field core::bool* binaryGreaterEqual = 42.{core::num::>=}(42){(core::num*) →* core::bool*};
-static const field core::bool* binaryGreater = 42.{core::num::>}(42){(core::num*) →* core::bool*};
-static const field core::int* doubleTruncateDiv = 84.2.{core::double::~/}(2){(core::num*) →* core::int*};
-static const field core::int* doubleTruncateDivZero = 84.2.{core::double::~/}(0){(core::num*) →* core::int*};
-static const field core::int* doubleTruncateDivNull = 84.2.{core::double::~/}(null){(core::num*) →* core::int*};
-static const field core::double* doubleNan = 0.{core::num::/}(0){(core::num*) →* core::double*};
-static const field core::int* doubleTruncateDivNaN = 84.2.{core::double::~/}(self::doubleNan){(core::num*) →* core::int*};
-static const field core::int* bigNumber = -9223372036854775808;
+                      ^"{dynamic}.+(2) as{TypeError,ForDynamic,ForNonNullableByDefault} core::int;
+static const field core::int binaryPlus = 40.{core::num::+}(2){(core::num) → core::int};
+static const field core::int binaryMinus = 44.{core::num::-}(2){(core::num) → core::int};
+static const field core::int binaryTimes = 21.{core::num::*}(2){(core::num) → core::int};
+static const field core::double binaryDiv = 84.{core::num::/}(2){(core::num) → core::double};
+static const field core::int binaryTildeDiv = 84.{core::num::~/}(2){(core::num) → core::int};
+static const field core::int binaryMod = 85.{core::num::%}(43){(core::num) → core::int};
+static const field core::int binaryOr = 32.{core::int::|}(10){(core::int) → core::int};
+static const field core::int binaryAnd = 63.{core::int::&}(106){(core::int) → core::int};
+static const field core::int binaryXor = 63.{core::int::^}(21){(core::int) → core::int};
+static const field core::int binaryShift1 = 21.{core::int::<<}(1){(core::int) → core::int};
+static const field core::int binaryShift2 = 84.{core::int::>>>}(1){(core::int) → core::int};
+static const field core::int binaryShift3 = 21.{core::int::>>>}(64){(core::int) → core::int};
+static const field core::int binaryShift4 = 84.{core::int::>>}(1){(core::int) → core::int};
+static const field core::int binaryShift5 = 1.{core::int::unary-}(){() → core::int}.{core::int::>>}(1){(core::int) → core::int};
+static const field core::bool binaryLess = 42.{core::num::<}(42){(core::num) → core::bool};
+static const field core::bool binaryLessEqual = 42.{core::num::<=}(42){(core::num) → core::bool};
+static const field core::bool binaryGreaterEqual = 42.{core::num::>=}(42){(core::num) → core::bool};
+static const field core::bool binaryGreater = 42.{core::num::>}(42){(core::num) → core::bool};
+static const field core::int doubleTruncateDiv = 84.2.{core::double::~/}(2){(core::num) → core::int};
+static const field core::int doubleTruncateDivZero = 84.2.{core::double::~/}(0){(core::num) → core::int};
+static const field dynamic nil = null;
+static const field core::int doubleTruncateDivNull = 84.2.{core::double::~/}(self::nil as{TypeError,ForDynamic,ForNonNullableByDefault} core::num){(core::num) → core::int};
+static const field core::double doubleNan = 0.{core::num::/}(0){(core::num) → core::double};
+static const field core::int doubleTruncateDivNaN = 84.2.{core::double::~/}(self::doubleNan){(core::num) → core::int};
+static const field core::int bigNumber = -9223372036854775808;
 static method main() → dynamic
   ;
 
@@ -72,15 +73,16 @@
 Evaluated: InstanceInvocation @ org-dartlang-testcase:///number_folds.dart:22:26 -> DoubleConstant(42.0)
 Evaluated: InstanceInvocation @ org-dartlang-testcase:///number_folds.dart:23:26 -> DoubleConstant(42.0)
 Evaluated: InstanceInvocation @ org-dartlang-testcase:///number_folds.dart:24:29 -> DoubleConstant(42.0)
-Evaluated: InstanceInvocation @ org-dartlang-testcase:///number_folds.dart:27:29 -> DoubleConstant(42.0)
-Evaluated: InstanceInvocation @ org-dartlang-testcase:///number_folds.dart:28:29 -> DoubleConstant(0.0)
-Evaluated: InstanceInvocation @ org-dartlang-testcase:///number_folds.dart:30:29 -> DoubleConstant(42.0)
-Evaluated: InstanceInvocation @ org-dartlang-testcase:///number_folds.dart:31:29 -> DoubleConstant(4294967295.0)
-Evaluated: InstanceInvocation @ org-dartlang-testcase:///number_folds.dart:32:28 -> BoolConstant(false)
-Evaluated: InstanceInvocation @ org-dartlang-testcase:///number_folds.dart:33:33 -> BoolConstant(true)
-Evaluated: InstanceInvocation @ org-dartlang-testcase:///number_folds.dart:34:36 -> BoolConstant(true)
-Evaluated: InstanceInvocation @ org-dartlang-testcase:///number_folds.dart:35:31 -> BoolConstant(false)
-Evaluated: InstanceInvocation @ org-dartlang-testcase:///number_folds.dart:37:36 -> DoubleConstant(42.0)
+Evaluated: InstanceInvocation @ org-dartlang-testcase:///number_folds.dart:26:29 -> DoubleConstant(42.0)
+Evaluated: InstanceInvocation @ org-dartlang-testcase:///number_folds.dart:27:29 -> DoubleConstant(0.0)
+Evaluated: InstanceInvocation @ org-dartlang-testcase:///number_folds.dart:29:29 -> DoubleConstant(42.0)
+Evaluated: InstanceInvocation @ org-dartlang-testcase:///number_folds.dart:30:29 -> DoubleConstant(4294967295.0)
+Evaluated: InstanceInvocation @ org-dartlang-testcase:///number_folds.dart:31:28 -> BoolConstant(false)
+Evaluated: InstanceInvocation @ org-dartlang-testcase:///number_folds.dart:32:33 -> BoolConstant(true)
+Evaluated: InstanceInvocation @ org-dartlang-testcase:///number_folds.dart:33:36 -> BoolConstant(true)
+Evaluated: InstanceInvocation @ org-dartlang-testcase:///number_folds.dart:34:31 -> BoolConstant(false)
+Evaluated: InstanceInvocation @ org-dartlang-testcase:///number_folds.dart:36:36 -> DoubleConstant(42.0)
+Evaluated: AsExpression @ org-dartlang-testcase:///number_folds.dart:39:43 -> NullConstant(null)
 Evaluated: InstanceInvocation @ org-dartlang-testcase:///number_folds.dart:40:27 -> DoubleConstant(NaN)
 Evaluated: StaticGet @ org-dartlang-testcase:///number_folds.dart:41:42 -> DoubleConstant(NaN)
-Extra constant evaluation: evaluated: 39, effectively constant: 27
+Extra constant evaluation: evaluated: 40, effectively constant: 28
diff --git a/pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart.weak.transformed.expect b/pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart.weak.transformed.expect
index bb1a380..e2269a8 100644
--- a/pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart.weak.transformed.expect
@@ -1,4 +1,4 @@
-library;
+library /*isNonNullableByDefault*/;
 //
 // Problems in library:
 //
@@ -61,24 +61,24 @@
 // const int intdivZero = 2 ~/ 0;
 //           ^
 //
-// pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart:38:40: Error: Constant evaluation error:
+// pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart:37:40: Error: Constant evaluation error:
 // const int doubleTruncateDivZero = 84.2 ~/ 0;
 //                                        ^
-// pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart:38:40: Context: Binary operator '~/' on '84.2' requires non-zero divisor, but divisor was '0'.
+// pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart:37:40: Context: Binary operator '~/' on '84.2' requires non-zero divisor, but divisor was '0'.
 // const int doubleTruncateDivZero = 84.2 ~/ 0;
 //                                        ^
-// pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart:38:11: Context: While analyzing:
+// pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart:37:11: Context: While analyzing:
 // const int doubleTruncateDivZero = 84.2 ~/ 0;
 //           ^
 //
 // pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart:39:40: Error: Constant evaluation error:
-// const int doubleTruncateDivNull = 84.2 ~/ null;
+// const int doubleTruncateDivNull = 84.2 ~/ nil;
 //                                        ^
 // pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart:39:40: Context: Binary operator '~/' on '84.2' requires operand of type 'num', but was of type 'Null'.
-// const int doubleTruncateDivNull = 84.2 ~/ null;
+// const int doubleTruncateDivNull = 84.2 ~/ nil;
 //                                        ^
 // pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart:39:11: Context: While analyzing:
-// const int doubleTruncateDivNull = 84.2 ~/ null;
+// const int doubleTruncateDivNull = 84.2 ~/ nil;
 //           ^
 //
 // pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart:41:39: Error: Constant evaluation error:
@@ -94,43 +94,44 @@
 import self as self;
 import "dart:core" as core;
 
-static const field core::int* shiftNegative1 = invalid-expression "Binary operator '<<' on '2.0' requires non-negative operand, but was '-1.0'.";
-static const field core::int* shiftNegative2 = invalid-expression "Binary operator '>>>' on '2.0' requires non-negative operand, but was '-1.0'.";
-static const field core::int* shiftNegative3 = invalid-expression "Binary operator '>>' on '2.0' requires non-negative operand, but was '-1.0'.";
-static const field core::int* modZero = invalid-expression "Binary operator '%' on '2.0' requires non-zero divisor, but divisor was '0'.";
-static const field core::int* divZero = invalid-expression "pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart:9:23: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+static const field core::int shiftNegative1 = invalid-expression "Binary operator '<<' on '2.0' requires non-negative operand, but was '-1.0'.";
+static const field core::int shiftNegative2 = invalid-expression "Binary operator '>>>' on '2.0' requires non-negative operand, but was '-1.0'.";
+static const field core::int shiftNegative3 = invalid-expression "Binary operator '>>' on '2.0' requires non-negative operand, but was '-1.0'.";
+static const field core::int modZero = invalid-expression "Binary operator '%' on '2.0' requires non-zero divisor, but divisor was '0'.";
+static const field core::int divZero = invalid-expression "pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart:9:23: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
 const int divZero = 2 / 0;
                       ^";
-static const field core::int* intdivZero = invalid-expression "Binary operator '~/' on '2.0' requires non-zero divisor, but divisor was '0'.";
-static const field core::int* unaryMinus = #C1;
-static const field core::int* unaryTilde = #C2;
-static const field core::int* unaryPlus = invalid-expression "pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart:13:23: Error: This couldn't be parsed.
+static const field core::int intdivZero = invalid-expression "Binary operator '~/' on '2.0' requires non-zero divisor, but divisor was '0'.";
+static const field core::int unaryMinus = #C1;
+static const field core::int unaryTilde = #C2;
+static const field core::int unaryPlus = invalid-expression "pkg/front_end/testcases/general/constants/js_semantics/number_folds.dart:13:23: Error: This couldn't be parsed.
 const int unaryPlus = +2;
                       ^";
-static const field core::int* binaryPlus = #C3;
-static const field core::int* binaryMinus = #C3;
-static const field core::int* binaryTimes = #C3;
-static const field core::double* binaryDiv = #C3;
-static const field core::int* binaryTildeDiv = #C3;
-static const field core::int* binaryMod = #C3;
-static const field core::int* binaryOr = #C3;
-static const field core::int* binaryAnd = #C3;
-static const field core::int* binaryXor = #C3;
-static const field core::int* binaryShift1 = #C3;
-static const field core::int* binaryShift2 = #C3;
-static const field core::int* binaryShift3 = #C4;
-static const field core::int* binaryShift4 = #C3;
-static const field core::int* binaryShift5 = #C5;
-static const field core::bool* binaryLess = #C6;
-static const field core::bool* binaryLessEqual = #C7;
-static const field core::bool* binaryGreaterEqual = #C7;
-static const field core::bool* binaryGreater = #C6;
-static const field core::int* doubleTruncateDiv = #C3;
-static const field core::int* doubleTruncateDivZero = invalid-expression "Binary operator '~/' on '84.2' requires non-zero divisor, but divisor was '0'.";
-static const field core::int* doubleTruncateDivNull = invalid-expression "Binary operator '~/' on '84.2' requires operand of type 'num', but was of type 'Null'.";
-static const field core::double* doubleNan = #C8;
-static const field core::int* doubleTruncateDivNaN = invalid-expression "Binary operator '84.2 ~/ NaN' results is Infinity or NaN.";
-static const field core::int* bigNumber = #C9;
+static const field core::int binaryPlus = #C3;
+static const field core::int binaryMinus = #C3;
+static const field core::int binaryTimes = #C3;
+static const field core::double binaryDiv = #C3;
+static const field core::int binaryTildeDiv = #C3;
+static const field core::int binaryMod = #C3;
+static const field core::int binaryOr = #C3;
+static const field core::int binaryAnd = #C3;
+static const field core::int binaryXor = #C3;
+static const field core::int binaryShift1 = #C3;
+static const field core::int binaryShift2 = #C3;
+static const field core::int binaryShift3 = #C4;
+static const field core::int binaryShift4 = #C3;
+static const field core::int binaryShift5 = #C5;
+static const field core::bool binaryLess = #C6;
+static const field core::bool binaryLessEqual = #C7;
+static const field core::bool binaryGreaterEqual = #C7;
+static const field core::bool binaryGreater = #C6;
+static const field core::int doubleTruncateDiv = #C3;
+static const field core::int doubleTruncateDivZero = invalid-expression "Binary operator '~/' on '84.2' requires non-zero divisor, but divisor was '0'.";
+static const field dynamic nil = #C8;
+static const field core::int doubleTruncateDivNull = invalid-expression "Binary operator '~/' on '84.2' requires operand of type 'num', but was of type 'Null'.";
+static const field core::double doubleNan = #C9;
+static const field core::int doubleTruncateDivNaN = invalid-expression "Binary operator '84.2 ~/ NaN' results is Infinity or NaN.";
+static const field core::int bigNumber = #C10;
 static method main() → dynamic {}
 
 constants  {
@@ -141,6 +142,7 @@
   #C5 = 4294967295.0
   #C6 = false
   #C7 = true
-  #C8 = NaN
-  #C9 = 9223372036854776000.0
+  #C8 = null
+  #C9 = NaN
+  #C10 = 9223372036854776000.0
 }
diff --git a/pkg/front_end/testcases/general/constants/js_semantics/number_folds_opt_out.dart b/pkg/front_end/testcases/general/constants/js_semantics/number_folds_opt_out.dart
new file mode 100644
index 0000000..90f02de
--- /dev/null
+++ b/pkg/front_end/testcases/general/constants/js_semantics/number_folds_opt_out.dart
@@ -0,0 +1,44 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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
+
+const int shiftNegative1 = 2 << -1;
+const int shiftNegative3 = 2 >> -1;
+const int modZero = 2 % 0;
+const int divZero = 2 / 0;
+const int intdivZero = 2 ~/ 0;
+const int unaryMinus = -2;
+const int unaryTilde = ~2;
+const int unaryPlus = +2;
+
+const int binaryPlus = 40 + 2;
+const int binaryMinus = 44 - 2;
+const int binaryTimes = 21 * 2;
+const double binaryDiv = 84 / 2;
+const int binaryTildeDiv = 84~/ 2;
+const int binaryMod = 85 % 43;
+const int binaryOr = 32 | 10;
+const int binaryAnd = 63 & 106;
+const int binaryXor = 63 ^ 21;
+const int binaryShift1 = 21 << 1;
+
+const int binaryShift4 = 84 >> 1;
+const int binaryShift5 = -1 >> 1;
+const bool binaryLess = 42 < 42;
+const bool binaryLessEqual = 42 <= 42;
+const bool binaryGreaterEqual = 42 >= 42;
+const bool binaryGreater = 42 > 42;
+
+const int doubleTruncateDiv = 84.2 ~/ 2;
+const int doubleTruncateDivZero = 84.2 ~/ 0;
+const int doubleTruncateDivNull = 84.2 ~/ null;
+const double doubleNan = 0/0;
+const int doubleTruncateDivNaN = 84.2 ~/ doubleNan;
+
+const int bigNumber = 0x8000000000000000;
+
+main() {
+
+}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/general/constants/js_semantics/number_folds_opt_out.dart.textual_outline.expect b/pkg/front_end/testcases/general/constants/js_semantics/number_folds_opt_out.dart.textual_outline.expect
new file mode 100644
index 0000000..7f22f68
--- /dev/null
+++ b/pkg/front_end/testcases/general/constants/js_semantics/number_folds_opt_out.dart.textual_outline.expect
@@ -0,0 +1,32 @@
+// @dart = 2.9
+const int shiftNegative1 = 2 << -1;
+const int shiftNegative3 = 2 >> -1;
+const int modZero = 2 % 0;
+const int divZero = 2 / 0;
+const int intdivZero = 2 ~/ 0;
+const int unaryMinus = -2;
+const int unaryTilde = ~2;
+const int unaryPlus = +2;
+const int binaryPlus = 40 + 2;
+const int binaryMinus = 44 - 2;
+const int binaryTimes = 21 * 2;
+const double binaryDiv = 84 / 2;
+const int binaryTildeDiv = 84~/ 2;
+const int binaryMod = 85 % 43;
+const int binaryOr = 32 | 10;
+const int binaryAnd = 63 & 106;
+const int binaryXor = 63 ^ 21;
+const int binaryShift1 = 21 << 1;
+const int binaryShift4 = 84 >> 1;
+const int binaryShift5 = -1 >> 1;
+const bool binaryLess = 42 < 42;
+const bool binaryLessEqual = 42 <= 42;
+const bool binaryGreaterEqual = 42 >= 42;
+const bool binaryGreater = 42 > 42;
+const int doubleTruncateDiv = 84.2 ~/ 2;
+const int doubleTruncateDivZero = 84.2 ~/ 0;
+const int doubleTruncateDivNull = 84.2 ~/ null;
+const double doubleNan = 0/0;
+const int doubleTruncateDivNaN = 84.2 ~/ doubleNan;
+const int bigNumber = 0x8000000000000000;
+main() {}
diff --git a/pkg/front_end/testcases/general/constants/js_semantics/number_folds_opt_out.dart.weak.expect b/pkg/front_end/testcases/general/constants/js_semantics/number_folds_opt_out.dart.weak.expect
new file mode 100644
index 0000000..220b700
--- /dev/null
+++ b/pkg/front_end/testcases/general/constants/js_semantics/number_folds_opt_out.dart.weak.expect
@@ -0,0 +1,132 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/constants/js_semantics/number_folds_opt_out.dart:14:23: Error: '+' is not a prefix operator.
+// Try removing '+'.
+// const int unaryPlus = +2;
+//                       ^
+//
+// pkg/front_end/testcases/general/constants/js_semantics/number_folds_opt_out.dart:10:23: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+// const int divZero = 2 / 0;
+//                       ^
+//
+// pkg/front_end/testcases/general/constants/js_semantics/number_folds_opt_out.dart:7:30: Error: Constant evaluation error:
+// const int shiftNegative1 = 2 << -1;
+//                              ^
+// pkg/front_end/testcases/general/constants/js_semantics/number_folds_opt_out.dart:7:30: Context: Binary operator '<<' on '2.0' requires non-negative operand, but was '-1.0'.
+// const int shiftNegative1 = 2 << -1;
+//                              ^
+// pkg/front_end/testcases/general/constants/js_semantics/number_folds_opt_out.dart:7:11: Context: While analyzing:
+// const int shiftNegative1 = 2 << -1;
+//           ^
+//
+// pkg/front_end/testcases/general/constants/js_semantics/number_folds_opt_out.dart:8:30: Error: Constant evaluation error:
+// const int shiftNegative3 = 2 >> -1;
+//                              ^
+// pkg/front_end/testcases/general/constants/js_semantics/number_folds_opt_out.dart:8:30: Context: Binary operator '>>' on '2.0' requires non-negative operand, but was '-1.0'.
+// const int shiftNegative3 = 2 >> -1;
+//                              ^
+// pkg/front_end/testcases/general/constants/js_semantics/number_folds_opt_out.dart:8:11: Context: While analyzing:
+// const int shiftNegative3 = 2 >> -1;
+//           ^
+//
+// pkg/front_end/testcases/general/constants/js_semantics/number_folds_opt_out.dart:9:23: Error: Constant evaluation error:
+// const int modZero = 2 % 0;
+//                       ^
+// pkg/front_end/testcases/general/constants/js_semantics/number_folds_opt_out.dart:9:23: Context: Binary operator '%' on '2.0' requires non-zero divisor, but divisor was '0'.
+// const int modZero = 2 % 0;
+//                       ^
+// pkg/front_end/testcases/general/constants/js_semantics/number_folds_opt_out.dart:9:11: Context: While analyzing:
+// const int modZero = 2 % 0;
+//           ^
+//
+// pkg/front_end/testcases/general/constants/js_semantics/number_folds_opt_out.dart:11:26: Error: Constant evaluation error:
+// const int intdivZero = 2 ~/ 0;
+//                          ^
+// pkg/front_end/testcases/general/constants/js_semantics/number_folds_opt_out.dart:11:26: Context: Binary operator '~/' on '2.0' requires non-zero divisor, but divisor was '0'.
+// const int intdivZero = 2 ~/ 0;
+//                          ^
+// pkg/front_end/testcases/general/constants/js_semantics/number_folds_opt_out.dart:11:11: Context: While analyzing:
+// const int intdivZero = 2 ~/ 0;
+//           ^
+//
+// pkg/front_end/testcases/general/constants/js_semantics/number_folds_opt_out.dart:35:40: Error: Constant evaluation error:
+// const int doubleTruncateDivZero = 84.2 ~/ 0;
+//                                        ^
+// pkg/front_end/testcases/general/constants/js_semantics/number_folds_opt_out.dart:35:40: Context: Binary operator '~/' on '84.2' requires non-zero divisor, but divisor was '0'.
+// const int doubleTruncateDivZero = 84.2 ~/ 0;
+//                                        ^
+// pkg/front_end/testcases/general/constants/js_semantics/number_folds_opt_out.dart:35:11: Context: While analyzing:
+// const int doubleTruncateDivZero = 84.2 ~/ 0;
+//           ^
+//
+// pkg/front_end/testcases/general/constants/js_semantics/number_folds_opt_out.dart:36:40: Error: Constant evaluation error:
+// const int doubleTruncateDivNull = 84.2 ~/ null;
+//                                        ^
+// pkg/front_end/testcases/general/constants/js_semantics/number_folds_opt_out.dart:36:40: Context: Binary operator '~/' on '84.2' requires operand of type 'num', but was of type 'Null'.
+// const int doubleTruncateDivNull = 84.2 ~/ null;
+//                                        ^
+// pkg/front_end/testcases/general/constants/js_semantics/number_folds_opt_out.dart:36:11: Context: While analyzing:
+// const int doubleTruncateDivNull = 84.2 ~/ null;
+//           ^
+//
+// pkg/front_end/testcases/general/constants/js_semantics/number_folds_opt_out.dart:38:39: Error: Constant evaluation error:
+// const int doubleTruncateDivNaN = 84.2 ~/ doubleNan;
+//                                       ^
+// pkg/front_end/testcases/general/constants/js_semantics/number_folds_opt_out.dart:38:39: Context: Binary operator '84.2 ~/ NaN' results is Infinity or NaN.
+// const int doubleTruncateDivNaN = 84.2 ~/ doubleNan;
+//                                       ^
+// pkg/front_end/testcases/general/constants/js_semantics/number_folds_opt_out.dart:38:11: Context: While analyzing:
+// const int doubleTruncateDivNaN = 84.2 ~/ doubleNan;
+//           ^
+//
+import self as self;
+import "dart:core" as core;
+
+static const field core::int* shiftNegative1 = invalid-expression "Binary operator '<<' on '2.0' requires non-negative operand, but was '-1.0'.";
+static const field core::int* shiftNegative3 = invalid-expression "Binary operator '>>' on '2.0' requires non-negative operand, but was '-1.0'.";
+static const field core::int* modZero = invalid-expression "Binary operator '%' on '2.0' requires non-zero divisor, but divisor was '0'.";
+static const field core::int* divZero = invalid-expression "pkg/front_end/testcases/general/constants/js_semantics/number_folds_opt_out.dart:10:23: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+const int divZero = 2 / 0;
+                      ^";
+static const field core::int* intdivZero = invalid-expression "Binary operator '~/' on '2.0' requires non-zero divisor, but divisor was '0'.";
+static const field core::int* unaryMinus = #C1;
+static const field core::int* unaryTilde = #C2;
+static const field core::int* unaryPlus = invalid-expression "pkg/front_end/testcases/general/constants/js_semantics/number_folds_opt_out.dart:14:23: Error: This couldn't be parsed.
+const int unaryPlus = +2;
+                      ^";
+static const field core::int* binaryPlus = #C3;
+static const field core::int* binaryMinus = #C3;
+static const field core::int* binaryTimes = #C3;
+static const field core::double* binaryDiv = #C3;
+static const field core::int* binaryTildeDiv = #C3;
+static const field core::int* binaryMod = #C3;
+static const field core::int* binaryOr = #C3;
+static const field core::int* binaryAnd = #C3;
+static const field core::int* binaryXor = #C3;
+static const field core::int* binaryShift1 = #C3;
+static const field core::int* binaryShift4 = #C3;
+static const field core::int* binaryShift5 = #C4;
+static const field core::bool* binaryLess = #C5;
+static const field core::bool* binaryLessEqual = #C6;
+static const field core::bool* binaryGreaterEqual = #C6;
+static const field core::bool* binaryGreater = #C5;
+static const field core::int* doubleTruncateDiv = #C3;
+static const field core::int* doubleTruncateDivZero = invalid-expression "Binary operator '~/' on '84.2' requires non-zero divisor, but divisor was '0'.";
+static const field core::int* doubleTruncateDivNull = invalid-expression "Binary operator '~/' on '84.2' requires operand of type 'num', but was of type 'Null'.";
+static const field core::double* doubleNan = #C7;
+static const field core::int* doubleTruncateDivNaN = invalid-expression "Binary operator '84.2 ~/ NaN' results is Infinity or NaN.";
+static const field core::int* bigNumber = #C8;
+static method main() → dynamic {}
+
+constants  {
+  #C1 = -2.0
+  #C2 = 4294967293.0
+  #C3 = 42.0
+  #C4 = 4294967295.0
+  #C5 = false
+  #C6 = true
+  #C7 = NaN
+  #C8 = 9223372036854776000.0
+}
diff --git a/pkg/front_end/testcases/general/constants/js_semantics/number_folds_opt_out.dart.weak.outline.expect b/pkg/front_end/testcases/general/constants/js_semantics/number_folds_opt_out.dart.weak.outline.expect
new file mode 100644
index 0000000..92d8300
--- /dev/null
+++ b/pkg/front_end/testcases/general/constants/js_semantics/number_folds_opt_out.dart.weak.outline.expect
@@ -0,0 +1,80 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/constants/js_semantics/number_folds_opt_out.dart:14:23: Error: '+' is not a prefix operator.
+// Try removing '+'.
+// const int unaryPlus = +2;
+//                       ^
+//
+// pkg/front_end/testcases/general/constants/js_semantics/number_folds_opt_out.dart:10:23: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+// const int divZero = 2 / 0;
+//                       ^
+//
+import self as self;
+import "dart:core" as core;
+
+static const field core::int* shiftNegative1 = 2.{core::int::<<}(1.{core::int::unary-}(){() →* core::int*}){(core::int*) →* core::int*};
+static const field core::int* shiftNegative3 = 2.{core::int::>>}(1.{core::int::unary-}(){() →* core::int*}){(core::int*) →* core::int*};
+static const field core::int* modZero = 2.{core::num::%}(0){(core::num*) →* core::int*};
+static const field core::int* divZero = let final Never* #t1 = invalid-expression "pkg/front_end/testcases/general/constants/js_semantics/number_folds_opt_out.dart:10:23: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+const int divZero = 2 / 0;
+                      ^" in 2.{core::num::/}(0){(core::num*) →* core::double*} as{TypeError} core::int*;
+static const field core::int* intdivZero = 2.{core::num::~/}(0){(core::num*) →* core::int*};
+static const field core::int* unaryMinus = 2.{core::int::unary-}(){() →* core::int*};
+static const field core::int* unaryTilde = 2.{core::int::~}(){() →* core::int*};
+static const field core::int* unaryPlus = invalid-expression "pkg/front_end/testcases/general/constants/js_semantics/number_folds_opt_out.dart:14:23: Error: This couldn't be parsed.
+const int unaryPlus = +2;
+                      ^"{dynamic}.+(2) as{TypeError,ForDynamic} core::int*;
+static const field core::int* binaryPlus = 40.{core::num::+}(2){(core::num*) →* core::int*};
+static const field core::int* binaryMinus = 44.{core::num::-}(2){(core::num*) →* core::int*};
+static const field core::int* binaryTimes = 21.{core::num::*}(2){(core::num*) →* core::int*};
+static const field core::double* binaryDiv = 84.{core::num::/}(2){(core::num*) →* core::double*};
+static const field core::int* binaryTildeDiv = 84.{core::num::~/}(2){(core::num*) →* core::int*};
+static const field core::int* binaryMod = 85.{core::num::%}(43){(core::num*) →* core::int*};
+static const field core::int* binaryOr = 32.{core::int::|}(10){(core::int*) →* core::int*};
+static const field core::int* binaryAnd = 63.{core::int::&}(106){(core::int*) →* core::int*};
+static const field core::int* binaryXor = 63.{core::int::^}(21){(core::int*) →* core::int*};
+static const field core::int* binaryShift1 = 21.{core::int::<<}(1){(core::int*) →* core::int*};
+static const field core::int* binaryShift4 = 84.{core::int::>>}(1){(core::int*) →* core::int*};
+static const field core::int* binaryShift5 = 1.{core::int::unary-}(){() →* core::int*}.{core::int::>>}(1){(core::int*) →* core::int*};
+static const field core::bool* binaryLess = 42.{core::num::<}(42){(core::num*) →* core::bool*};
+static const field core::bool* binaryLessEqual = 42.{core::num::<=}(42){(core::num*) →* core::bool*};
+static const field core::bool* binaryGreaterEqual = 42.{core::num::>=}(42){(core::num*) →* core::bool*};
+static const field core::bool* binaryGreater = 42.{core::num::>}(42){(core::num*) →* core::bool*};
+static const field core::int* doubleTruncateDiv = 84.2.{core::double::~/}(2){(core::num*) →* core::int*};
+static const field core::int* doubleTruncateDivZero = 84.2.{core::double::~/}(0){(core::num*) →* core::int*};
+static const field core::int* doubleTruncateDivNull = 84.2.{core::double::~/}(null){(core::num*) →* core::int*};
+static const field core::double* doubleNan = 0.{core::num::/}(0){(core::num*) →* core::double*};
+static const field core::int* doubleTruncateDivNaN = 84.2.{core::double::~/}(self::doubleNan){(core::num*) →* core::int*};
+static const field core::int* bigNumber = -9223372036854775808;
+static method main() → dynamic
+  ;
+
+
+Extra constant evaluation status:
+Evaluated: InstanceInvocation @ org-dartlang-testcase:///number_folds_opt_out.dart:7:33 -> DoubleConstant(-1.0)
+Evaluated: InstanceInvocation @ org-dartlang-testcase:///number_folds_opt_out.dart:8:33 -> DoubleConstant(-1.0)
+Evaluated: InstanceInvocation @ org-dartlang-testcase:///number_folds_opt_out.dart:10:23 -> DoubleConstant(Infinity)
+Evaluated: InstanceInvocation @ org-dartlang-testcase:///number_folds_opt_out.dart:12:24 -> DoubleConstant(-2.0)
+Evaluated: InstanceInvocation @ org-dartlang-testcase:///number_folds_opt_out.dart:13:24 -> DoubleConstant(4294967293.0)
+Evaluated: InstanceInvocation @ org-dartlang-testcase:///number_folds_opt_out.dart:16:27 -> DoubleConstant(42.0)
+Evaluated: InstanceInvocation @ org-dartlang-testcase:///number_folds_opt_out.dart:17:28 -> DoubleConstant(42.0)
+Evaluated: InstanceInvocation @ org-dartlang-testcase:///number_folds_opt_out.dart:18:28 -> DoubleConstant(42.0)
+Evaluated: InstanceInvocation @ org-dartlang-testcase:///number_folds_opt_out.dart:19:29 -> DoubleConstant(42.0)
+Evaluated: InstanceInvocation @ org-dartlang-testcase:///number_folds_opt_out.dart:20:30 -> DoubleConstant(42.0)
+Evaluated: InstanceInvocation @ org-dartlang-testcase:///number_folds_opt_out.dart:21:26 -> DoubleConstant(42.0)
+Evaluated: InstanceInvocation @ org-dartlang-testcase:///number_folds_opt_out.dart:22:25 -> DoubleConstant(42.0)
+Evaluated: InstanceInvocation @ org-dartlang-testcase:///number_folds_opt_out.dart:23:26 -> DoubleConstant(42.0)
+Evaluated: InstanceInvocation @ org-dartlang-testcase:///number_folds_opt_out.dart:24:26 -> DoubleConstant(42.0)
+Evaluated: InstanceInvocation @ org-dartlang-testcase:///number_folds_opt_out.dart:25:29 -> DoubleConstant(42.0)
+Evaluated: InstanceInvocation @ org-dartlang-testcase:///number_folds_opt_out.dart:27:29 -> DoubleConstant(42.0)
+Evaluated: InstanceInvocation @ org-dartlang-testcase:///number_folds_opt_out.dart:28:29 -> DoubleConstant(4294967295.0)
+Evaluated: InstanceInvocation @ org-dartlang-testcase:///number_folds_opt_out.dart:29:28 -> BoolConstant(false)
+Evaluated: InstanceInvocation @ org-dartlang-testcase:///number_folds_opt_out.dart:30:33 -> BoolConstant(true)
+Evaluated: InstanceInvocation @ org-dartlang-testcase:///number_folds_opt_out.dart:31:36 -> BoolConstant(true)
+Evaluated: InstanceInvocation @ org-dartlang-testcase:///number_folds_opt_out.dart:32:31 -> BoolConstant(false)
+Evaluated: InstanceInvocation @ org-dartlang-testcase:///number_folds_opt_out.dart:34:36 -> DoubleConstant(42.0)
+Evaluated: InstanceInvocation @ org-dartlang-testcase:///number_folds_opt_out.dart:37:27 -> DoubleConstant(NaN)
+Evaluated: StaticGet @ org-dartlang-testcase:///number_folds_opt_out.dart:38:42 -> DoubleConstant(NaN)
+Extra constant evaluation: evaluated: 35, effectively constant: 24
diff --git a/pkg/front_end/testcases/general/constants/js_semantics/number_folds_opt_out.dart.weak.transformed.expect b/pkg/front_end/testcases/general/constants/js_semantics/number_folds_opt_out.dart.weak.transformed.expect
new file mode 100644
index 0000000..220b700
--- /dev/null
+++ b/pkg/front_end/testcases/general/constants/js_semantics/number_folds_opt_out.dart.weak.transformed.expect
@@ -0,0 +1,132 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/constants/js_semantics/number_folds_opt_out.dart:14:23: Error: '+' is not a prefix operator.
+// Try removing '+'.
+// const int unaryPlus = +2;
+//                       ^
+//
+// pkg/front_end/testcases/general/constants/js_semantics/number_folds_opt_out.dart:10:23: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+// const int divZero = 2 / 0;
+//                       ^
+//
+// pkg/front_end/testcases/general/constants/js_semantics/number_folds_opt_out.dart:7:30: Error: Constant evaluation error:
+// const int shiftNegative1 = 2 << -1;
+//                              ^
+// pkg/front_end/testcases/general/constants/js_semantics/number_folds_opt_out.dart:7:30: Context: Binary operator '<<' on '2.0' requires non-negative operand, but was '-1.0'.
+// const int shiftNegative1 = 2 << -1;
+//                              ^
+// pkg/front_end/testcases/general/constants/js_semantics/number_folds_opt_out.dart:7:11: Context: While analyzing:
+// const int shiftNegative1 = 2 << -1;
+//           ^
+//
+// pkg/front_end/testcases/general/constants/js_semantics/number_folds_opt_out.dart:8:30: Error: Constant evaluation error:
+// const int shiftNegative3 = 2 >> -1;
+//                              ^
+// pkg/front_end/testcases/general/constants/js_semantics/number_folds_opt_out.dart:8:30: Context: Binary operator '>>' on '2.0' requires non-negative operand, but was '-1.0'.
+// const int shiftNegative3 = 2 >> -1;
+//                              ^
+// pkg/front_end/testcases/general/constants/js_semantics/number_folds_opt_out.dart:8:11: Context: While analyzing:
+// const int shiftNegative3 = 2 >> -1;
+//           ^
+//
+// pkg/front_end/testcases/general/constants/js_semantics/number_folds_opt_out.dart:9:23: Error: Constant evaluation error:
+// const int modZero = 2 % 0;
+//                       ^
+// pkg/front_end/testcases/general/constants/js_semantics/number_folds_opt_out.dart:9:23: Context: Binary operator '%' on '2.0' requires non-zero divisor, but divisor was '0'.
+// const int modZero = 2 % 0;
+//                       ^
+// pkg/front_end/testcases/general/constants/js_semantics/number_folds_opt_out.dart:9:11: Context: While analyzing:
+// const int modZero = 2 % 0;
+//           ^
+//
+// pkg/front_end/testcases/general/constants/js_semantics/number_folds_opt_out.dart:11:26: Error: Constant evaluation error:
+// const int intdivZero = 2 ~/ 0;
+//                          ^
+// pkg/front_end/testcases/general/constants/js_semantics/number_folds_opt_out.dart:11:26: Context: Binary operator '~/' on '2.0' requires non-zero divisor, but divisor was '0'.
+// const int intdivZero = 2 ~/ 0;
+//                          ^
+// pkg/front_end/testcases/general/constants/js_semantics/number_folds_opt_out.dart:11:11: Context: While analyzing:
+// const int intdivZero = 2 ~/ 0;
+//           ^
+//
+// pkg/front_end/testcases/general/constants/js_semantics/number_folds_opt_out.dart:35:40: Error: Constant evaluation error:
+// const int doubleTruncateDivZero = 84.2 ~/ 0;
+//                                        ^
+// pkg/front_end/testcases/general/constants/js_semantics/number_folds_opt_out.dart:35:40: Context: Binary operator '~/' on '84.2' requires non-zero divisor, but divisor was '0'.
+// const int doubleTruncateDivZero = 84.2 ~/ 0;
+//                                        ^
+// pkg/front_end/testcases/general/constants/js_semantics/number_folds_opt_out.dart:35:11: Context: While analyzing:
+// const int doubleTruncateDivZero = 84.2 ~/ 0;
+//           ^
+//
+// pkg/front_end/testcases/general/constants/js_semantics/number_folds_opt_out.dart:36:40: Error: Constant evaluation error:
+// const int doubleTruncateDivNull = 84.2 ~/ null;
+//                                        ^
+// pkg/front_end/testcases/general/constants/js_semantics/number_folds_opt_out.dart:36:40: Context: Binary operator '~/' on '84.2' requires operand of type 'num', but was of type 'Null'.
+// const int doubleTruncateDivNull = 84.2 ~/ null;
+//                                        ^
+// pkg/front_end/testcases/general/constants/js_semantics/number_folds_opt_out.dart:36:11: Context: While analyzing:
+// const int doubleTruncateDivNull = 84.2 ~/ null;
+//           ^
+//
+// pkg/front_end/testcases/general/constants/js_semantics/number_folds_opt_out.dart:38:39: Error: Constant evaluation error:
+// const int doubleTruncateDivNaN = 84.2 ~/ doubleNan;
+//                                       ^
+// pkg/front_end/testcases/general/constants/js_semantics/number_folds_opt_out.dart:38:39: Context: Binary operator '84.2 ~/ NaN' results is Infinity or NaN.
+// const int doubleTruncateDivNaN = 84.2 ~/ doubleNan;
+//                                       ^
+// pkg/front_end/testcases/general/constants/js_semantics/number_folds_opt_out.dart:38:11: Context: While analyzing:
+// const int doubleTruncateDivNaN = 84.2 ~/ doubleNan;
+//           ^
+//
+import self as self;
+import "dart:core" as core;
+
+static const field core::int* shiftNegative1 = invalid-expression "Binary operator '<<' on '2.0' requires non-negative operand, but was '-1.0'.";
+static const field core::int* shiftNegative3 = invalid-expression "Binary operator '>>' on '2.0' requires non-negative operand, but was '-1.0'.";
+static const field core::int* modZero = invalid-expression "Binary operator '%' on '2.0' requires non-zero divisor, but divisor was '0'.";
+static const field core::int* divZero = invalid-expression "pkg/front_end/testcases/general/constants/js_semantics/number_folds_opt_out.dart:10:23: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+const int divZero = 2 / 0;
+                      ^";
+static const field core::int* intdivZero = invalid-expression "Binary operator '~/' on '2.0' requires non-zero divisor, but divisor was '0'.";
+static const field core::int* unaryMinus = #C1;
+static const field core::int* unaryTilde = #C2;
+static const field core::int* unaryPlus = invalid-expression "pkg/front_end/testcases/general/constants/js_semantics/number_folds_opt_out.dart:14:23: Error: This couldn't be parsed.
+const int unaryPlus = +2;
+                      ^";
+static const field core::int* binaryPlus = #C3;
+static const field core::int* binaryMinus = #C3;
+static const field core::int* binaryTimes = #C3;
+static const field core::double* binaryDiv = #C3;
+static const field core::int* binaryTildeDiv = #C3;
+static const field core::int* binaryMod = #C3;
+static const field core::int* binaryOr = #C3;
+static const field core::int* binaryAnd = #C3;
+static const field core::int* binaryXor = #C3;
+static const field core::int* binaryShift1 = #C3;
+static const field core::int* binaryShift4 = #C3;
+static const field core::int* binaryShift5 = #C4;
+static const field core::bool* binaryLess = #C5;
+static const field core::bool* binaryLessEqual = #C6;
+static const field core::bool* binaryGreaterEqual = #C6;
+static const field core::bool* binaryGreater = #C5;
+static const field core::int* doubleTruncateDiv = #C3;
+static const field core::int* doubleTruncateDivZero = invalid-expression "Binary operator '~/' on '84.2' requires non-zero divisor, but divisor was '0'.";
+static const field core::int* doubleTruncateDivNull = invalid-expression "Binary operator '~/' on '84.2' requires operand of type 'num', but was of type 'Null'.";
+static const field core::double* doubleNan = #C7;
+static const field core::int* doubleTruncateDivNaN = invalid-expression "Binary operator '84.2 ~/ NaN' results is Infinity or NaN.";
+static const field core::int* bigNumber = #C8;
+static method main() → dynamic {}
+
+constants  {
+  #C1 = -2.0
+  #C2 = 4294967293.0
+  #C3 = 42.0
+  #C4 = 4294967295.0
+  #C5 = false
+  #C6 = true
+  #C7 = NaN
+  #C8 = 9223372036854776000.0
+}
diff --git a/pkg/front_end/testcases/general/constants/js_semantics/on_double.dart b/pkg/front_end/testcases/general/constants/js_semantics/on_double.dart
new file mode 100644
index 0000000..d4598da
--- /dev/null
+++ b/pkg/front_end/testcases/general/constants/js_semantics/on_double.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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 dynamic a = 1.0;
+const dynamic b = 1.5;
+
+const dynamic c0 = a >> 1;
+const dynamic c1 = b >> 1;
+const dynamic c2 = a >>> 1;
+const dynamic c3 = b >>> 1;
+
+const dynamic d0 = 1 >> a;
+const dynamic d1 = 1 >> b;
+const dynamic d2 = 1 >>> a;
+const dynamic d3 = 1 >>> b;
+
+class Class {
+  final int a;
+
+  const Class.doubleShift(i1, i2) : a = (i1 >> i2);
+  const Class.tripleShift(i1, i2) : a = (i1 >>> i2);
+}
+
+main() {
+  const Class c1 = Class.doubleShift(a, 1);
+  const Class c2 = Class.doubleShift(b, 1);
+  const Class c3 = Class.tripleShift(a, 1);
+  const Class c4 = Class.tripleShift(b, 1);
+
+  const Class d1 = Class.doubleShift(1, a);
+  const Class d2 = Class.doubleShift(1, b);
+  const Class d3 = Class.tripleShift(1, a);
+  const Class d4 = Class.tripleShift(1, b);
+
+  const Class e1 = Class.doubleShift(1.0, 1);
+  const Class e2 = Class.doubleShift(1.5, 1);
+  const Class e3 = Class.tripleShift(1.0, 1);
+  const Class e4 = Class.tripleShift(1.5, 1);
+}
diff --git a/pkg/front_end/testcases/general/constants/js_semantics/on_double.dart.textual_outline.expect b/pkg/front_end/testcases/general/constants/js_semantics/on_double.dart.textual_outline.expect
new file mode 100644
index 0000000..186b763
--- /dev/null
+++ b/pkg/front_end/testcases/general/constants/js_semantics/on_double.dart.textual_outline.expect
@@ -0,0 +1,18 @@
+const dynamic a = 1.0;
+const dynamic b = 1.5;
+const dynamic c0 = a >> 1;
+const dynamic c1 = b >> 1;
+const dynamic c2 = a >>> 1;
+const dynamic c3 = b >>> 1;
+const dynamic d0 = 1 >> a;
+const dynamic d1 = 1 >> b;
+const dynamic d2 = 1 >>> a;
+const dynamic d3 = 1 >>> b;
+
+class Class {
+  final int a;
+  const Class.doubleShift(i1, i2) : a = (i1 >> i2);
+  const Class.tripleShift(i1, i2) : a = (i1 >>> i2);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/constants/js_semantics/on_double.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/constants/js_semantics/on_double.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6fc8f42
--- /dev/null
+++ b/pkg/front_end/testcases/general/constants/js_semantics/on_double.dart.textual_outline_modelled.expect
@@ -0,0 +1,17 @@
+class Class {
+  const Class.doubleShift(i1, i2) : a = (i1 >> i2);
+  const Class.tripleShift(i1, i2) : a = (i1 >>> i2);
+  final int a;
+}
+
+const dynamic a = 1.0;
+const dynamic b = 1.5;
+const dynamic c0 = a >> 1;
+const dynamic c1 = b >> 1;
+const dynamic c2 = a >>> 1;
+const dynamic c3 = b >>> 1;
+const dynamic d0 = 1 >> a;
+const dynamic d1 = 1 >> b;
+const dynamic d2 = 1 >>> a;
+const dynamic d3 = 1 >>> b;
+main() {}
diff --git a/pkg/front_end/testcases/general/constants/js_semantics/on_double.dart.weak.expect b/pkg/front_end/testcases/general/constants/js_semantics/on_double.dart.weak.expect
new file mode 100644
index 0000000..2573a35
--- /dev/null
+++ b/pkg/front_end/testcases/general/constants/js_semantics/on_double.dart.weak.expect
@@ -0,0 +1,147 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/constants/js_semantics/on_double.dart:27:26: Error: Constant evaluation error:
+//   const Class c2 = Class.doubleShift(b, 1);
+//                          ^
+// pkg/front_end/testcases/general/constants/js_semantics/on_double.dart:21:45: Context: Binary operator '>>' on '1.5' requires operand of type 'int', but was of type 'double'.
+//   const Class.doubleShift(i1, i2) : a = (i1 >> i2);
+//                                             ^
+// pkg/front_end/testcases/general/constants/js_semantics/on_double.dart:27:15: Context: While analyzing:
+//   const Class c2 = Class.doubleShift(b, 1);
+//               ^
+//
+// pkg/front_end/testcases/general/constants/js_semantics/on_double.dart:29:26: Error: Constant evaluation error:
+//   const Class c4 = Class.tripleShift(b, 1);
+//                          ^
+// pkg/front_end/testcases/general/constants/js_semantics/on_double.dart:22:45: Context: Binary operator '>>>' on '1.5' requires operand of type 'int', but was of type 'double'.
+//   const Class.tripleShift(i1, i2) : a = (i1 >>> i2);
+//                                             ^
+// pkg/front_end/testcases/general/constants/js_semantics/on_double.dart:29:15: Context: While analyzing:
+//   const Class c4 = Class.tripleShift(b, 1);
+//               ^
+//
+// pkg/front_end/testcases/general/constants/js_semantics/on_double.dart:32:26: Error: Constant evaluation error:
+//   const Class d2 = Class.doubleShift(1, b);
+//                          ^
+// pkg/front_end/testcases/general/constants/js_semantics/on_double.dart:21:45: Context: Binary operator '>>' on '1.5' requires operand of type 'int', but was of type 'double'.
+//   const Class.doubleShift(i1, i2) : a = (i1 >> i2);
+//                                             ^
+// pkg/front_end/testcases/general/constants/js_semantics/on_double.dart:32:15: Context: While analyzing:
+//   const Class d2 = Class.doubleShift(1, b);
+//               ^
+//
+// pkg/front_end/testcases/general/constants/js_semantics/on_double.dart:34:26: Error: Constant evaluation error:
+//   const Class d4 = Class.tripleShift(1, b);
+//                          ^
+// pkg/front_end/testcases/general/constants/js_semantics/on_double.dart:22:45: Context: Binary operator '>>>' on '1.5' requires operand of type 'int', but was of type 'double'.
+//   const Class.tripleShift(i1, i2) : a = (i1 >>> i2);
+//                                             ^
+// pkg/front_end/testcases/general/constants/js_semantics/on_double.dart:34:15: Context: While analyzing:
+//   const Class d4 = Class.tripleShift(1, b);
+//               ^
+//
+// pkg/front_end/testcases/general/constants/js_semantics/on_double.dart:37:26: Error: Constant evaluation error:
+//   const Class e2 = Class.doubleShift(1.5, 1);
+//                          ^
+// pkg/front_end/testcases/general/constants/js_semantics/on_double.dart:21:45: Context: Binary operator '>>' on '1.5' requires operand of type 'int', but was of type 'double'.
+//   const Class.doubleShift(i1, i2) : a = (i1 >> i2);
+//                                             ^
+// pkg/front_end/testcases/general/constants/js_semantics/on_double.dart:37:15: Context: While analyzing:
+//   const Class e2 = Class.doubleShift(1.5, 1);
+//               ^
+//
+// pkg/front_end/testcases/general/constants/js_semantics/on_double.dart:39:26: Error: Constant evaluation error:
+//   const Class e4 = Class.tripleShift(1.5, 1);
+//                          ^
+// pkg/front_end/testcases/general/constants/js_semantics/on_double.dart:22:45: Context: Binary operator '>>>' on '1.5' requires operand of type 'int', but was of type 'double'.
+//   const Class.tripleShift(i1, i2) : a = (i1 >>> i2);
+//                                             ^
+// pkg/front_end/testcases/general/constants/js_semantics/on_double.dart:39:15: Context: While analyzing:
+//   const Class e4 = Class.tripleShift(1.5, 1);
+//               ^
+//
+// pkg/front_end/testcases/general/constants/js_semantics/on_double.dart:9:22: Error: Constant evaluation error:
+// const dynamic c1 = b >> 1;
+//                      ^
+// pkg/front_end/testcases/general/constants/js_semantics/on_double.dart:9:22: Context: Binary operator '>>' on '1.5' requires operand of type 'int', but was of type 'double'.
+// const dynamic c1 = b >> 1;
+//                      ^
+// pkg/front_end/testcases/general/constants/js_semantics/on_double.dart:9:15: Context: While analyzing:
+// const dynamic c1 = b >> 1;
+//               ^
+//
+// pkg/front_end/testcases/general/constants/js_semantics/on_double.dart:11:22: Error: Constant evaluation error:
+// const dynamic c3 = b >>> 1;
+//                      ^
+// pkg/front_end/testcases/general/constants/js_semantics/on_double.dart:11:22: Context: Binary operator '>>>' on '1.5' requires operand of type 'int', but was of type 'double'.
+// const dynamic c3 = b >>> 1;
+//                      ^
+// pkg/front_end/testcases/general/constants/js_semantics/on_double.dart:11:15: Context: While analyzing:
+// const dynamic c3 = b >>> 1;
+//               ^
+//
+// pkg/front_end/testcases/general/constants/js_semantics/on_double.dart:14:22: Error: Constant evaluation error:
+// const dynamic d1 = 1 >> b;
+//                      ^
+// pkg/front_end/testcases/general/constants/js_semantics/on_double.dart:14:25: Context: Expected constant '1.5' to be of type 'int', but was of type 'double'.
+// const dynamic d1 = 1 >> b;
+//                         ^
+// pkg/front_end/testcases/general/constants/js_semantics/on_double.dart:14:15: Context: While analyzing:
+// const dynamic d1 = 1 >> b;
+//               ^
+//
+// pkg/front_end/testcases/general/constants/js_semantics/on_double.dart:16:22: Error: Constant evaluation error:
+// const dynamic d3 = 1 >>> b;
+//                      ^
+// pkg/front_end/testcases/general/constants/js_semantics/on_double.dart:16:26: Context: Expected constant '1.5' to be of type 'int', but was of type 'double'.
+// const dynamic d3 = 1 >>> b;
+//                          ^
+// pkg/front_end/testcases/general/constants/js_semantics/on_double.dart:16:15: Context: While analyzing:
+// const dynamic d3 = 1 >>> b;
+//               ^
+//
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object /*hasConstConstructor*/  {
+  final field core::int a;
+  const constructor doubleShift(dynamic i1, dynamic i2) → self::Class
+    : self::Class::a = i1{dynamic}.>>(i2) as{TypeError,ForDynamic,ForNonNullableByDefault} core::int, super core::Object::•()
+    ;
+  const constructor tripleShift(dynamic i1, dynamic i2) → self::Class
+    : self::Class::a = i1{dynamic}.>>>(i2) as{TypeError,ForDynamic,ForNonNullableByDefault} core::int, super core::Object::•()
+    ;
+}
+static const field dynamic a = #C1;
+static const field dynamic b = #C2;
+static const field dynamic c0 = #C3;
+static const field dynamic c1 = invalid-expression "Binary operator '>>' on '1.5' requires operand of type 'int', but was of type 'double'.";
+static const field dynamic c2 = #C3;
+static const field dynamic c3 = invalid-expression "Binary operator '>>>' on '1.5' requires operand of type 'int', but was of type 'double'.";
+static const field dynamic d0 = #C3;
+static const field dynamic d1 = invalid-expression "Expected constant '1.5' to be of type 'int', but was of type 'double'.";
+static const field dynamic d2 = #C3;
+static const field dynamic d3 = invalid-expression "Expected constant '1.5' to be of type 'int', but was of type 'double'.";
+static method main() → dynamic {
+  const self::Class c2 = invalid-expression "Binary operator '>>' on '1.5' requires operand of type 'int', but was of type 'double'.";
+  const self::Class c4 = invalid-expression "Binary operator '>>>' on '1.5' requires operand of type 'int', but was of type 'double'.";
+  const self::Class d2 = invalid-expression "Binary operator '>>' on '1.5' requires operand of type 'int', but was of type 'double'.";
+  const self::Class d4 = invalid-expression "Binary operator '>>>' on '1.5' requires operand of type 'int', but was of type 'double'.";
+  const self::Class e2 = invalid-expression "Binary operator '>>' on '1.5' requires operand of type 'int', but was of type 'double'.";
+  const self::Class e4 = invalid-expression "Binary operator '>>>' on '1.5' requires operand of type 'int', but was of type 'double'.";
+}
+
+constants  {
+  #C1 = 1.0
+  #C2 = 1.5
+  #C3 = 0.0
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///on_double.dart:
+- Class.doubleShift (from org-dartlang-testcase:///on_double.dart:21:9)
+- Object. (from org-dartlang-sdk:///lib/core/object.dart:25:9)
+- Class.tripleShift (from org-dartlang-testcase:///on_double.dart:22:9)
diff --git a/pkg/front_end/testcases/general/constants/js_semantics/on_double.dart.weak.outline.expect b/pkg/front_end/testcases/general/constants/js_semantics/on_double.dart.weak.outline.expect
new file mode 100644
index 0000000..c94c041
--- /dev/null
+++ b/pkg/front_end/testcases/general/constants/js_semantics/on_double.dart.weak.outline.expect
@@ -0,0 +1,37 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object /*hasConstConstructor*/  {
+  final field core::int a;
+  const constructor doubleShift(dynamic i1, dynamic i2) → self::Class
+    : self::Class::a = i1{dynamic}.>>(i2) as{TypeError,ForDynamic,ForNonNullableByDefault} core::int, super core::Object::•()
+    ;
+  const constructor tripleShift(dynamic i1, dynamic i2) → self::Class
+    : self::Class::a = i1{dynamic}.>>>(i2) as{TypeError,ForDynamic,ForNonNullableByDefault} core::int, super core::Object::•()
+    ;
+}
+static const field dynamic a = 1.0;
+static const field dynamic b = 1.5;
+static const field dynamic c0 = self::a{dynamic}.>>(1);
+static const field dynamic c1 = self::b{dynamic}.>>(1);
+static const field dynamic c2 = self::a{dynamic}.>>>(1);
+static const field dynamic c3 = self::b{dynamic}.>>>(1);
+static const field dynamic d0 = 1.{core::int::>>}(self::a as{TypeError,ForDynamic,ForNonNullableByDefault} core::int){(core::int) → core::int};
+static const field dynamic d1 = 1.{core::int::>>}(self::b as{TypeError,ForDynamic,ForNonNullableByDefault} core::int){(core::int) → core::int};
+static const field dynamic d2 = 1.{core::int::>>>}(self::a as{TypeError,ForDynamic,ForNonNullableByDefault} core::int){(core::int) → core::int};
+static const field dynamic d3 = 1.{core::int::>>>}(self::b as{TypeError,ForDynamic,ForNonNullableByDefault} core::int){(core::int) → core::int};
+static method main() → dynamic
+  ;
+
+
+Extra constant evaluation status:
+Evaluated: DynamicInvocation @ org-dartlang-testcase:///on_double.dart:8:22 -> DoubleConstant(0.0)
+Evaluated: StaticGet @ org-dartlang-testcase:///on_double.dart:9:20 -> DoubleConstant(1.5)
+Evaluated: DynamicInvocation @ org-dartlang-testcase:///on_double.dart:10:22 -> DoubleConstant(0.0)
+Evaluated: StaticGet @ org-dartlang-testcase:///on_double.dart:11:20 -> DoubleConstant(1.5)
+Evaluated: InstanceInvocation @ org-dartlang-testcase:///on_double.dart:13:22 -> DoubleConstant(0.0)
+Evaluated: StaticGet @ org-dartlang-testcase:///on_double.dart:14:25 -> DoubleConstant(1.5)
+Evaluated: InstanceInvocation @ org-dartlang-testcase:///on_double.dart:15:22 -> DoubleConstant(0.0)
+Evaluated: StaticGet @ org-dartlang-testcase:///on_double.dart:16:26 -> DoubleConstant(1.5)
+Extra constant evaluation: evaluated: 22, effectively constant: 8
diff --git a/pkg/front_end/testcases/general/constants/js_semantics/on_double.dart.weak.transformed.expect b/pkg/front_end/testcases/general/constants/js_semantics/on_double.dart.weak.transformed.expect
new file mode 100644
index 0000000..2573a35
--- /dev/null
+++ b/pkg/front_end/testcases/general/constants/js_semantics/on_double.dart.weak.transformed.expect
@@ -0,0 +1,147 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/constants/js_semantics/on_double.dart:27:26: Error: Constant evaluation error:
+//   const Class c2 = Class.doubleShift(b, 1);
+//                          ^
+// pkg/front_end/testcases/general/constants/js_semantics/on_double.dart:21:45: Context: Binary operator '>>' on '1.5' requires operand of type 'int', but was of type 'double'.
+//   const Class.doubleShift(i1, i2) : a = (i1 >> i2);
+//                                             ^
+// pkg/front_end/testcases/general/constants/js_semantics/on_double.dart:27:15: Context: While analyzing:
+//   const Class c2 = Class.doubleShift(b, 1);
+//               ^
+//
+// pkg/front_end/testcases/general/constants/js_semantics/on_double.dart:29:26: Error: Constant evaluation error:
+//   const Class c4 = Class.tripleShift(b, 1);
+//                          ^
+// pkg/front_end/testcases/general/constants/js_semantics/on_double.dart:22:45: Context: Binary operator '>>>' on '1.5' requires operand of type 'int', but was of type 'double'.
+//   const Class.tripleShift(i1, i2) : a = (i1 >>> i2);
+//                                             ^
+// pkg/front_end/testcases/general/constants/js_semantics/on_double.dart:29:15: Context: While analyzing:
+//   const Class c4 = Class.tripleShift(b, 1);
+//               ^
+//
+// pkg/front_end/testcases/general/constants/js_semantics/on_double.dart:32:26: Error: Constant evaluation error:
+//   const Class d2 = Class.doubleShift(1, b);
+//                          ^
+// pkg/front_end/testcases/general/constants/js_semantics/on_double.dart:21:45: Context: Binary operator '>>' on '1.5' requires operand of type 'int', but was of type 'double'.
+//   const Class.doubleShift(i1, i2) : a = (i1 >> i2);
+//                                             ^
+// pkg/front_end/testcases/general/constants/js_semantics/on_double.dart:32:15: Context: While analyzing:
+//   const Class d2 = Class.doubleShift(1, b);
+//               ^
+//
+// pkg/front_end/testcases/general/constants/js_semantics/on_double.dart:34:26: Error: Constant evaluation error:
+//   const Class d4 = Class.tripleShift(1, b);
+//                          ^
+// pkg/front_end/testcases/general/constants/js_semantics/on_double.dart:22:45: Context: Binary operator '>>>' on '1.5' requires operand of type 'int', but was of type 'double'.
+//   const Class.tripleShift(i1, i2) : a = (i1 >>> i2);
+//                                             ^
+// pkg/front_end/testcases/general/constants/js_semantics/on_double.dart:34:15: Context: While analyzing:
+//   const Class d4 = Class.tripleShift(1, b);
+//               ^
+//
+// pkg/front_end/testcases/general/constants/js_semantics/on_double.dart:37:26: Error: Constant evaluation error:
+//   const Class e2 = Class.doubleShift(1.5, 1);
+//                          ^
+// pkg/front_end/testcases/general/constants/js_semantics/on_double.dart:21:45: Context: Binary operator '>>' on '1.5' requires operand of type 'int', but was of type 'double'.
+//   const Class.doubleShift(i1, i2) : a = (i1 >> i2);
+//                                             ^
+// pkg/front_end/testcases/general/constants/js_semantics/on_double.dart:37:15: Context: While analyzing:
+//   const Class e2 = Class.doubleShift(1.5, 1);
+//               ^
+//
+// pkg/front_end/testcases/general/constants/js_semantics/on_double.dart:39:26: Error: Constant evaluation error:
+//   const Class e4 = Class.tripleShift(1.5, 1);
+//                          ^
+// pkg/front_end/testcases/general/constants/js_semantics/on_double.dart:22:45: Context: Binary operator '>>>' on '1.5' requires operand of type 'int', but was of type 'double'.
+//   const Class.tripleShift(i1, i2) : a = (i1 >>> i2);
+//                                             ^
+// pkg/front_end/testcases/general/constants/js_semantics/on_double.dart:39:15: Context: While analyzing:
+//   const Class e4 = Class.tripleShift(1.5, 1);
+//               ^
+//
+// pkg/front_end/testcases/general/constants/js_semantics/on_double.dart:9:22: Error: Constant evaluation error:
+// const dynamic c1 = b >> 1;
+//                      ^
+// pkg/front_end/testcases/general/constants/js_semantics/on_double.dart:9:22: Context: Binary operator '>>' on '1.5' requires operand of type 'int', but was of type 'double'.
+// const dynamic c1 = b >> 1;
+//                      ^
+// pkg/front_end/testcases/general/constants/js_semantics/on_double.dart:9:15: Context: While analyzing:
+// const dynamic c1 = b >> 1;
+//               ^
+//
+// pkg/front_end/testcases/general/constants/js_semantics/on_double.dart:11:22: Error: Constant evaluation error:
+// const dynamic c3 = b >>> 1;
+//                      ^
+// pkg/front_end/testcases/general/constants/js_semantics/on_double.dart:11:22: Context: Binary operator '>>>' on '1.5' requires operand of type 'int', but was of type 'double'.
+// const dynamic c3 = b >>> 1;
+//                      ^
+// pkg/front_end/testcases/general/constants/js_semantics/on_double.dart:11:15: Context: While analyzing:
+// const dynamic c3 = b >>> 1;
+//               ^
+//
+// pkg/front_end/testcases/general/constants/js_semantics/on_double.dart:14:22: Error: Constant evaluation error:
+// const dynamic d1 = 1 >> b;
+//                      ^
+// pkg/front_end/testcases/general/constants/js_semantics/on_double.dart:14:25: Context: Expected constant '1.5' to be of type 'int', but was of type 'double'.
+// const dynamic d1 = 1 >> b;
+//                         ^
+// pkg/front_end/testcases/general/constants/js_semantics/on_double.dart:14:15: Context: While analyzing:
+// const dynamic d1 = 1 >> b;
+//               ^
+//
+// pkg/front_end/testcases/general/constants/js_semantics/on_double.dart:16:22: Error: Constant evaluation error:
+// const dynamic d3 = 1 >>> b;
+//                      ^
+// pkg/front_end/testcases/general/constants/js_semantics/on_double.dart:16:26: Context: Expected constant '1.5' to be of type 'int', but was of type 'double'.
+// const dynamic d3 = 1 >>> b;
+//                          ^
+// pkg/front_end/testcases/general/constants/js_semantics/on_double.dart:16:15: Context: While analyzing:
+// const dynamic d3 = 1 >>> b;
+//               ^
+//
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object /*hasConstConstructor*/  {
+  final field core::int a;
+  const constructor doubleShift(dynamic i1, dynamic i2) → self::Class
+    : self::Class::a = i1{dynamic}.>>(i2) as{TypeError,ForDynamic,ForNonNullableByDefault} core::int, super core::Object::•()
+    ;
+  const constructor tripleShift(dynamic i1, dynamic i2) → self::Class
+    : self::Class::a = i1{dynamic}.>>>(i2) as{TypeError,ForDynamic,ForNonNullableByDefault} core::int, super core::Object::•()
+    ;
+}
+static const field dynamic a = #C1;
+static const field dynamic b = #C2;
+static const field dynamic c0 = #C3;
+static const field dynamic c1 = invalid-expression "Binary operator '>>' on '1.5' requires operand of type 'int', but was of type 'double'.";
+static const field dynamic c2 = #C3;
+static const field dynamic c3 = invalid-expression "Binary operator '>>>' on '1.5' requires operand of type 'int', but was of type 'double'.";
+static const field dynamic d0 = #C3;
+static const field dynamic d1 = invalid-expression "Expected constant '1.5' to be of type 'int', but was of type 'double'.";
+static const field dynamic d2 = #C3;
+static const field dynamic d3 = invalid-expression "Expected constant '1.5' to be of type 'int', but was of type 'double'.";
+static method main() → dynamic {
+  const self::Class c2 = invalid-expression "Binary operator '>>' on '1.5' requires operand of type 'int', but was of type 'double'.";
+  const self::Class c4 = invalid-expression "Binary operator '>>>' on '1.5' requires operand of type 'int', but was of type 'double'.";
+  const self::Class d2 = invalid-expression "Binary operator '>>' on '1.5' requires operand of type 'int', but was of type 'double'.";
+  const self::Class d4 = invalid-expression "Binary operator '>>>' on '1.5' requires operand of type 'int', but was of type 'double'.";
+  const self::Class e2 = invalid-expression "Binary operator '>>' on '1.5' requires operand of type 'int', but was of type 'double'.";
+  const self::Class e4 = invalid-expression "Binary operator '>>>' on '1.5' requires operand of type 'int', but was of type 'double'.";
+}
+
+constants  {
+  #C1 = 1.0
+  #C2 = 1.5
+  #C3 = 0.0
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///on_double.dart:
+- Class.doubleShift (from org-dartlang-testcase:///on_double.dart:21:9)
+- Object. (from org-dartlang-sdk:///lib/core/object.dart:25:9)
+- Class.tripleShift (from org-dartlang-testcase:///on_double.dart:22:9)
diff --git a/pkg/front_end/testcases/general/constants/number_folds.dart b/pkg/front_end/testcases/general/constants/number_folds.dart
index a905108..1a45579 100644
--- a/pkg/front_end/testcases/general/constants/number_folds.dart
+++ b/pkg/front_end/testcases/general/constants/number_folds.dart
@@ -1,7 +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.
-// @dart=2.9
+
 const int shiftNegative1 = 2 << -1;
 const int shiftNegative2 = 2 >>> -1;
 const int shiftNegative3 = 2 >> -1;
@@ -23,7 +23,6 @@
 const int binaryXor = 63 ^ 21;
 const int binaryShift1 = 21 << 1;
 
-// These aren't currently defined on int :(.
 const int binaryShift2 = 84 >>> 1;
 const int binaryShift3 = 21 >>> 64;
 
@@ -35,7 +34,8 @@
 
 const int doubleTruncateDiv = 84.2 ~/ 2;
 const int doubleTruncateDivZero = 84.2 ~/ 0;
-const int doubleTruncateDivNull = 84.2 ~/ null;
+const dynamic nil = null;
+const int doubleTruncateDivNull = 84.2 ~/ nil;
 const double doubleNan = 0/0;
 const int doubleTruncateDivNaN = 84.2 ~/ doubleNan;
 
diff --git a/pkg/front_end/testcases/general/constants/number_folds.dart.textual_outline.expect b/pkg/front_end/testcases/general/constants/number_folds.dart.textual_outline.expect
index 2491b0a..025ab90 100644
--- a/pkg/front_end/testcases/general/constants/number_folds.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/general/constants/number_folds.dart.textual_outline.expect
@@ -1,4 +1,3 @@
-// @dart = 2.9
 const int shiftNegative1 = 2 << -1;
 const int shiftNegative2 = 2 >>> -1;
 const int shiftNegative3 = 2 >> -1;
@@ -27,7 +26,8 @@
 const bool binaryGreater = 42 > 42;
 const int doubleTruncateDiv = 84.2 ~/ 2;
 const int doubleTruncateDivZero = 84.2 ~/ 0;
-const int doubleTruncateDivNull = 84.2 ~/ null;
+const dynamic nil = null;
+const int doubleTruncateDivNull = 84.2 ~/ nil;
 const double doubleNan = 0/0;
 const int doubleTruncateDivNaN = 84.2 ~/ doubleNan;
 main() {}
diff --git a/pkg/front_end/testcases/general/constants/number_folds.dart.weak.expect b/pkg/front_end/testcases/general/constants/number_folds.dart.weak.expect
index dc5a80f..6de8923 100644
--- a/pkg/front_end/testcases/general/constants/number_folds.dart.weak.expect
+++ b/pkg/front_end/testcases/general/constants/number_folds.dart.weak.expect
@@ -1,4 +1,4 @@
-library;
+library /*isNonNullableByDefault*/;
 //
 // Problems in library:
 //
@@ -61,24 +61,24 @@
 // const int intdivZero = 2 ~/ 0;
 //           ^
 //
-// pkg/front_end/testcases/general/constants/number_folds.dart:37:40: Error: Constant evaluation error:
+// pkg/front_end/testcases/general/constants/number_folds.dart:36:40: Error: Constant evaluation error:
 // const int doubleTruncateDivZero = 84.2 ~/ 0;
 //                                        ^
-// pkg/front_end/testcases/general/constants/number_folds.dart:37:40: Context: Binary operator '~/' on '84.2' requires non-zero divisor, but divisor was '0'.
+// pkg/front_end/testcases/general/constants/number_folds.dart:36:40: Context: Binary operator '~/' on '84.2' requires non-zero divisor, but divisor was '0'.
 // const int doubleTruncateDivZero = 84.2 ~/ 0;
 //                                        ^
-// pkg/front_end/testcases/general/constants/number_folds.dart:37:11: Context: While analyzing:
+// pkg/front_end/testcases/general/constants/number_folds.dart:36:11: Context: While analyzing:
 // const int doubleTruncateDivZero = 84.2 ~/ 0;
 //           ^
 //
 // pkg/front_end/testcases/general/constants/number_folds.dart:38:40: Error: Constant evaluation error:
-// const int doubleTruncateDivNull = 84.2 ~/ null;
+// const int doubleTruncateDivNull = 84.2 ~/ nil;
 //                                        ^
 // pkg/front_end/testcases/general/constants/number_folds.dart:38:40: Context: Binary operator '~/' on '84.2' requires operand of type 'num', but was of type 'Null'.
-// const int doubleTruncateDivNull = 84.2 ~/ null;
+// const int doubleTruncateDivNull = 84.2 ~/ nil;
 //                                        ^
 // pkg/front_end/testcases/general/constants/number_folds.dart:38:11: Context: While analyzing:
-// const int doubleTruncateDivNull = 84.2 ~/ null;
+// const int doubleTruncateDivNull = 84.2 ~/ nil;
 //           ^
 //
 // pkg/front_end/testcases/general/constants/number_folds.dart:40:39: Error: Constant evaluation error:
@@ -94,41 +94,42 @@
 import self as self;
 import "dart:core" as core;
 
-static const field core::int* shiftNegative1 = invalid-expression "Binary operator '<<' on '2' requires non-negative operand, but was '-1'.";
-static const field core::int* shiftNegative2 = invalid-expression "Binary operator '>>>' on '2' requires non-negative operand, but was '-1'.";
-static const field core::int* shiftNegative3 = invalid-expression "Binary operator '>>' on '2' requires non-negative operand, but was '-1'.";
-static const field core::int* modZero = invalid-expression "Binary operator '%' on '2' requires non-zero divisor, but divisor was '0'.";
-static const field core::int* divZero = invalid-expression "pkg/front_end/testcases/general/constants/number_folds.dart:9:23: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+static const field core::int shiftNegative1 = invalid-expression "Binary operator '<<' on '2' requires non-negative operand, but was '-1'.";
+static const field core::int shiftNegative2 = invalid-expression "Binary operator '>>>' on '2' requires non-negative operand, but was '-1'.";
+static const field core::int shiftNegative3 = invalid-expression "Binary operator '>>' on '2' requires non-negative operand, but was '-1'.";
+static const field core::int modZero = invalid-expression "Binary operator '%' on '2' requires non-zero divisor, but divisor was '0'.";
+static const field core::int divZero = invalid-expression "pkg/front_end/testcases/general/constants/number_folds.dart:9:23: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
 const int divZero = 2 / 0;
                       ^";
-static const field core::int* intdivZero = invalid-expression "Binary operator '~/' on '2' requires non-zero divisor, but divisor was '0'.";
-static const field core::int* unaryMinus = #C1;
-static const field core::int* unaryTilde = #C2;
-static const field core::int* unaryPlus = invalid-expression "pkg/front_end/testcases/general/constants/number_folds.dart:13:23: Error: This couldn't be parsed.
+static const field core::int intdivZero = invalid-expression "Binary operator '~/' on '2' requires non-zero divisor, but divisor was '0'.";
+static const field core::int unaryMinus = #C1;
+static const field core::int unaryTilde = #C2;
+static const field core::int unaryPlus = invalid-expression "pkg/front_end/testcases/general/constants/number_folds.dart:13:23: Error: This couldn't be parsed.
 const int unaryPlus = +2;
                       ^";
-static const field core::int* binaryPlus = #C3;
-static const field core::int* binaryMinus = #C3;
-static const field core::int* binaryTimes = #C3;
-static const field core::double* binaryDiv = #C4;
-static const field core::int* binaryTildeDiv = #C3;
-static const field core::int* binaryMod = #C3;
-static const field core::int* binaryOr = #C3;
-static const field core::int* binaryAnd = #C3;
-static const field core::int* binaryXor = #C3;
-static const field core::int* binaryShift1 = #C3;
-static const field core::int* binaryShift2 = #C3;
-static const field core::int* binaryShift3 = #C5;
-static const field core::int* binaryShift4 = #C3;
-static const field core::bool* binaryLess = #C6;
-static const field core::bool* binaryLessEqual = #C7;
-static const field core::bool* binaryGreaterEqual = #C7;
-static const field core::bool* binaryGreater = #C6;
-static const field core::int* doubleTruncateDiv = #C3;
-static const field core::int* doubleTruncateDivZero = invalid-expression "Binary operator '~/' on '84.2' requires non-zero divisor, but divisor was '0'.";
-static const field core::int* doubleTruncateDivNull = invalid-expression "Binary operator '~/' on '84.2' requires operand of type 'num', but was of type 'Null'.";
-static const field core::double* doubleNan = #C8;
-static const field core::int* doubleTruncateDivNaN = invalid-expression "Binary operator '84.2 ~/ NaN' results is Infinity or NaN.";
+static const field core::int binaryPlus = #C3;
+static const field core::int binaryMinus = #C3;
+static const field core::int binaryTimes = #C3;
+static const field core::double binaryDiv = #C4;
+static const field core::int binaryTildeDiv = #C3;
+static const field core::int binaryMod = #C3;
+static const field core::int binaryOr = #C3;
+static const field core::int binaryAnd = #C3;
+static const field core::int binaryXor = #C3;
+static const field core::int binaryShift1 = #C3;
+static const field core::int binaryShift2 = #C3;
+static const field core::int binaryShift3 = #C5;
+static const field core::int binaryShift4 = #C3;
+static const field core::bool binaryLess = #C6;
+static const field core::bool binaryLessEqual = #C7;
+static const field core::bool binaryGreaterEqual = #C7;
+static const field core::bool binaryGreater = #C6;
+static const field core::int doubleTruncateDiv = #C3;
+static const field core::int doubleTruncateDivZero = invalid-expression "Binary operator '~/' on '84.2' requires non-zero divisor, but divisor was '0'.";
+static const field dynamic nil = #C8;
+static const field core::int doubleTruncateDivNull = invalid-expression "Binary operator '~/' on '84.2' requires operand of type 'num', but was of type 'Null'.";
+static const field core::double doubleNan = #C9;
+static const field core::int doubleTruncateDivNaN = invalid-expression "Binary operator '84.2 ~/ NaN' results is Infinity or NaN.";
 static method main() → dynamic {}
 
 constants  {
@@ -139,5 +140,6 @@
   #C5 = 0
   #C6 = false
   #C7 = true
-  #C8 = NaN
+  #C8 = null
+  #C9 = NaN
 }
diff --git a/pkg/front_end/testcases/general/constants/number_folds.dart.weak.outline.expect b/pkg/front_end/testcases/general/constants/number_folds.dart.weak.outline.expect
index 844245f..83af03a 100644
--- a/pkg/front_end/testcases/general/constants/number_folds.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/general/constants/number_folds.dart.weak.outline.expect
@@ -1,4 +1,4 @@
-library;
+library /*isNonNullableByDefault*/;
 //
 // Problems in library:
 //
@@ -14,41 +14,42 @@
 import self as self;
 import "dart:core" as core;
 
-static const field core::int* shiftNegative1 = 2.{core::int::<<}(1.{core::int::unary-}());
-static const field core::int* shiftNegative2 = 2.{core::int::>>>}(1.{core::int::unary-}());
-static const field core::int* shiftNegative3 = 2.{core::int::>>}(1.{core::int::unary-}());
-static const field core::int* modZero = 2.{core::num::%}(0);
-static const field core::int* divZero = let final Never* #t1 = invalid-expression "pkg/front_end/testcases/general/constants/number_folds.dart:9:23: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+static const field core::int shiftNegative1 = 2.{core::int::<<}(1.{core::int::unary-}());
+static const field core::int shiftNegative2 = 2.{core::int::>>>}(1.{core::int::unary-}());
+static const field core::int shiftNegative3 = 2.{core::int::>>}(1.{core::int::unary-}());
+static const field core::int modZero = 2.{core::num::%}(0);
+static const field core::int divZero = let final Never #t1 = invalid-expression "pkg/front_end/testcases/general/constants/number_folds.dart:9:23: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
 const int divZero = 2 / 0;
-                      ^" in 2.{core::num::/}(0) as{TypeError} core::int*;
-static const field core::int* intdivZero = 2.{core::num::~/}(0);
-static const field core::int* unaryMinus = 2.{core::int::unary-}();
-static const field core::int* unaryTilde = 2.{core::int::~}();
-static const field core::int* unaryPlus = invalid-expression "pkg/front_end/testcases/general/constants/number_folds.dart:13:23: Error: This couldn't be parsed.
+                      ^" in 2.{core::num::/}(0) as{TypeError,ForNonNullableByDefault} core::int;
+static const field core::int intdivZero = 2.{core::num::~/}(0);
+static const field core::int unaryMinus = 2.{core::int::unary-}();
+static const field core::int unaryTilde = 2.{core::int::~}();
+static const field core::int unaryPlus = invalid-expression "pkg/front_end/testcases/general/constants/number_folds.dart:13:23: Error: This couldn't be parsed.
 const int unaryPlus = +2;
-                      ^".+(2) as{TypeError,ForDynamic} core::int*;
-static const field core::int* binaryPlus = 40.{core::num::+}(2);
-static const field core::int* binaryMinus = 44.{core::num::-}(2);
-static const field core::int* binaryTimes = 21.{core::num::*}(2);
-static const field core::double* binaryDiv = 84.{core::num::/}(2);
-static const field core::int* binaryTildeDiv = 84.{core::num::~/}(2);
-static const field core::int* binaryMod = 85.{core::num::%}(43);
-static const field core::int* binaryOr = 32.{core::int::|}(10);
-static const field core::int* binaryAnd = 63.{core::int::&}(106);
-static const field core::int* binaryXor = 63.{core::int::^}(21);
-static const field core::int* binaryShift1 = 21.{core::int::<<}(1);
-static const field core::int* binaryShift2 = 84.{core::int::>>>}(1);
-static const field core::int* binaryShift3 = 21.{core::int::>>>}(64);
-static const field core::int* binaryShift4 = 84.{core::int::>>}(1);
-static const field core::bool* binaryLess = 42.{core::num::<}(42);
-static const field core::bool* binaryLessEqual = 42.{core::num::<=}(42);
-static const field core::bool* binaryGreaterEqual = 42.{core::num::>=}(42);
-static const field core::bool* binaryGreater = 42.{core::num::>}(42);
-static const field core::int* doubleTruncateDiv = 84.2.{core::double::~/}(2);
-static const field core::int* doubleTruncateDivZero = 84.2.{core::double::~/}(0);
-static const field core::int* doubleTruncateDivNull = 84.2.{core::double::~/}(null);
-static const field core::double* doubleNan = 0.{core::num::/}(0);
-static const field core::int* doubleTruncateDivNaN = 84.2.{core::double::~/}(self::doubleNan);
+                      ^".+(2) as{TypeError,ForDynamic,ForNonNullableByDefault} core::int;
+static const field core::int binaryPlus = 40.{core::num::+}(2);
+static const field core::int binaryMinus = 44.{core::num::-}(2);
+static const field core::int binaryTimes = 21.{core::num::*}(2);
+static const field core::double binaryDiv = 84.{core::num::/}(2);
+static const field core::int binaryTildeDiv = 84.{core::num::~/}(2);
+static const field core::int binaryMod = 85.{core::num::%}(43);
+static const field core::int binaryOr = 32.{core::int::|}(10);
+static const field core::int binaryAnd = 63.{core::int::&}(106);
+static const field core::int binaryXor = 63.{core::int::^}(21);
+static const field core::int binaryShift1 = 21.{core::int::<<}(1);
+static const field core::int binaryShift2 = 84.{core::int::>>>}(1);
+static const field core::int binaryShift3 = 21.{core::int::>>>}(64);
+static const field core::int binaryShift4 = 84.{core::int::>>}(1);
+static const field core::bool binaryLess = 42.{core::num::<}(42);
+static const field core::bool binaryLessEqual = 42.{core::num::<=}(42);
+static const field core::bool binaryGreaterEqual = 42.{core::num::>=}(42);
+static const field core::bool binaryGreater = 42.{core::num::>}(42);
+static const field core::int doubleTruncateDiv = 84.2.{core::double::~/}(2);
+static const field core::int doubleTruncateDivZero = 84.2.{core::double::~/}(0);
+static const field dynamic nil = null;
+static const field core::int doubleTruncateDivNull = 84.2.{core::double::~/}(self::nil as{TypeError,ForDynamic,ForNonNullableByDefault} core::num);
+static const field core::double doubleNan = 0.{core::num::/}(0);
+static const field core::int doubleTruncateDivNaN = 84.2.{core::double::~/}(self::doubleNan);
 static method main() → dynamic
   ;
 
@@ -70,14 +71,15 @@
 Evaluated: MethodInvocation @ org-dartlang-testcase:///number_folds.dart:22:26 -> IntConstant(42)
 Evaluated: MethodInvocation @ org-dartlang-testcase:///number_folds.dart:23:26 -> IntConstant(42)
 Evaluated: MethodInvocation @ org-dartlang-testcase:///number_folds.dart:24:29 -> IntConstant(42)
-Evaluated: MethodInvocation @ org-dartlang-testcase:///number_folds.dart:27:29 -> IntConstant(42)
-Evaluated: MethodInvocation @ org-dartlang-testcase:///number_folds.dart:28:29 -> IntConstant(0)
-Evaluated: MethodInvocation @ org-dartlang-testcase:///number_folds.dart:30:29 -> IntConstant(42)
-Evaluated: MethodInvocation @ org-dartlang-testcase:///number_folds.dart:31:28 -> BoolConstant(false)
-Evaluated: MethodInvocation @ org-dartlang-testcase:///number_folds.dart:32:33 -> BoolConstant(true)
-Evaluated: MethodInvocation @ org-dartlang-testcase:///number_folds.dart:33:36 -> BoolConstant(true)
-Evaluated: MethodInvocation @ org-dartlang-testcase:///number_folds.dart:34:31 -> BoolConstant(false)
-Evaluated: MethodInvocation @ org-dartlang-testcase:///number_folds.dart:36:36 -> IntConstant(42)
+Evaluated: MethodInvocation @ org-dartlang-testcase:///number_folds.dart:26:29 -> IntConstant(42)
+Evaluated: MethodInvocation @ org-dartlang-testcase:///number_folds.dart:27:29 -> IntConstant(0)
+Evaluated: MethodInvocation @ org-dartlang-testcase:///number_folds.dart:29:29 -> IntConstant(42)
+Evaluated: MethodInvocation @ org-dartlang-testcase:///number_folds.dart:30:28 -> BoolConstant(false)
+Evaluated: MethodInvocation @ org-dartlang-testcase:///number_folds.dart:31:33 -> BoolConstant(true)
+Evaluated: MethodInvocation @ org-dartlang-testcase:///number_folds.dart:32:36 -> BoolConstant(true)
+Evaluated: MethodInvocation @ org-dartlang-testcase:///number_folds.dart:33:31 -> BoolConstant(false)
+Evaluated: MethodInvocation @ org-dartlang-testcase:///number_folds.dart:35:36 -> IntConstant(42)
+Evaluated: AsExpression @ org-dartlang-testcase:///number_folds.dart:38:43 -> NullConstant(null)
 Evaluated: MethodInvocation @ org-dartlang-testcase:///number_folds.dart:39:27 -> DoubleConstant(NaN)
 Evaluated: StaticGet @ org-dartlang-testcase:///number_folds.dart:40:42 -> DoubleConstant(NaN)
-Extra constant evaluation: evaluated: 38, effectively constant: 26
+Extra constant evaluation: evaluated: 39, effectively constant: 27
diff --git a/pkg/front_end/testcases/general/constants/number_folds.dart.weak.transformed.expect b/pkg/front_end/testcases/general/constants/number_folds.dart.weak.transformed.expect
index dc5a80f..6de8923 100644
--- a/pkg/front_end/testcases/general/constants/number_folds.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general/constants/number_folds.dart.weak.transformed.expect
@@ -1,4 +1,4 @@
-library;
+library /*isNonNullableByDefault*/;
 //
 // Problems in library:
 //
@@ -61,24 +61,24 @@
 // const int intdivZero = 2 ~/ 0;
 //           ^
 //
-// pkg/front_end/testcases/general/constants/number_folds.dart:37:40: Error: Constant evaluation error:
+// pkg/front_end/testcases/general/constants/number_folds.dart:36:40: Error: Constant evaluation error:
 // const int doubleTruncateDivZero = 84.2 ~/ 0;
 //                                        ^
-// pkg/front_end/testcases/general/constants/number_folds.dart:37:40: Context: Binary operator '~/' on '84.2' requires non-zero divisor, but divisor was '0'.
+// pkg/front_end/testcases/general/constants/number_folds.dart:36:40: Context: Binary operator '~/' on '84.2' requires non-zero divisor, but divisor was '0'.
 // const int doubleTruncateDivZero = 84.2 ~/ 0;
 //                                        ^
-// pkg/front_end/testcases/general/constants/number_folds.dart:37:11: Context: While analyzing:
+// pkg/front_end/testcases/general/constants/number_folds.dart:36:11: Context: While analyzing:
 // const int doubleTruncateDivZero = 84.2 ~/ 0;
 //           ^
 //
 // pkg/front_end/testcases/general/constants/number_folds.dart:38:40: Error: Constant evaluation error:
-// const int doubleTruncateDivNull = 84.2 ~/ null;
+// const int doubleTruncateDivNull = 84.2 ~/ nil;
 //                                        ^
 // pkg/front_end/testcases/general/constants/number_folds.dart:38:40: Context: Binary operator '~/' on '84.2' requires operand of type 'num', but was of type 'Null'.
-// const int doubleTruncateDivNull = 84.2 ~/ null;
+// const int doubleTruncateDivNull = 84.2 ~/ nil;
 //                                        ^
 // pkg/front_end/testcases/general/constants/number_folds.dart:38:11: Context: While analyzing:
-// const int doubleTruncateDivNull = 84.2 ~/ null;
+// const int doubleTruncateDivNull = 84.2 ~/ nil;
 //           ^
 //
 // pkg/front_end/testcases/general/constants/number_folds.dart:40:39: Error: Constant evaluation error:
@@ -94,41 +94,42 @@
 import self as self;
 import "dart:core" as core;
 
-static const field core::int* shiftNegative1 = invalid-expression "Binary operator '<<' on '2' requires non-negative operand, but was '-1'.";
-static const field core::int* shiftNegative2 = invalid-expression "Binary operator '>>>' on '2' requires non-negative operand, but was '-1'.";
-static const field core::int* shiftNegative3 = invalid-expression "Binary operator '>>' on '2' requires non-negative operand, but was '-1'.";
-static const field core::int* modZero = invalid-expression "Binary operator '%' on '2' requires non-zero divisor, but divisor was '0'.";
-static const field core::int* divZero = invalid-expression "pkg/front_end/testcases/general/constants/number_folds.dart:9:23: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+static const field core::int shiftNegative1 = invalid-expression "Binary operator '<<' on '2' requires non-negative operand, but was '-1'.";
+static const field core::int shiftNegative2 = invalid-expression "Binary operator '>>>' on '2' requires non-negative operand, but was '-1'.";
+static const field core::int shiftNegative3 = invalid-expression "Binary operator '>>' on '2' requires non-negative operand, but was '-1'.";
+static const field core::int modZero = invalid-expression "Binary operator '%' on '2' requires non-zero divisor, but divisor was '0'.";
+static const field core::int divZero = invalid-expression "pkg/front_end/testcases/general/constants/number_folds.dart:9:23: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
 const int divZero = 2 / 0;
                       ^";
-static const field core::int* intdivZero = invalid-expression "Binary operator '~/' on '2' requires non-zero divisor, but divisor was '0'.";
-static const field core::int* unaryMinus = #C1;
-static const field core::int* unaryTilde = #C2;
-static const field core::int* unaryPlus = invalid-expression "pkg/front_end/testcases/general/constants/number_folds.dart:13:23: Error: This couldn't be parsed.
+static const field core::int intdivZero = invalid-expression "Binary operator '~/' on '2' requires non-zero divisor, but divisor was '0'.";
+static const field core::int unaryMinus = #C1;
+static const field core::int unaryTilde = #C2;
+static const field core::int unaryPlus = invalid-expression "pkg/front_end/testcases/general/constants/number_folds.dart:13:23: Error: This couldn't be parsed.
 const int unaryPlus = +2;
                       ^";
-static const field core::int* binaryPlus = #C3;
-static const field core::int* binaryMinus = #C3;
-static const field core::int* binaryTimes = #C3;
-static const field core::double* binaryDiv = #C4;
-static const field core::int* binaryTildeDiv = #C3;
-static const field core::int* binaryMod = #C3;
-static const field core::int* binaryOr = #C3;
-static const field core::int* binaryAnd = #C3;
-static const field core::int* binaryXor = #C3;
-static const field core::int* binaryShift1 = #C3;
-static const field core::int* binaryShift2 = #C3;
-static const field core::int* binaryShift3 = #C5;
-static const field core::int* binaryShift4 = #C3;
-static const field core::bool* binaryLess = #C6;
-static const field core::bool* binaryLessEqual = #C7;
-static const field core::bool* binaryGreaterEqual = #C7;
-static const field core::bool* binaryGreater = #C6;
-static const field core::int* doubleTruncateDiv = #C3;
-static const field core::int* doubleTruncateDivZero = invalid-expression "Binary operator '~/' on '84.2' requires non-zero divisor, but divisor was '0'.";
-static const field core::int* doubleTruncateDivNull = invalid-expression "Binary operator '~/' on '84.2' requires operand of type 'num', but was of type 'Null'.";
-static const field core::double* doubleNan = #C8;
-static const field core::int* doubleTruncateDivNaN = invalid-expression "Binary operator '84.2 ~/ NaN' results is Infinity or NaN.";
+static const field core::int binaryPlus = #C3;
+static const field core::int binaryMinus = #C3;
+static const field core::int binaryTimes = #C3;
+static const field core::double binaryDiv = #C4;
+static const field core::int binaryTildeDiv = #C3;
+static const field core::int binaryMod = #C3;
+static const field core::int binaryOr = #C3;
+static const field core::int binaryAnd = #C3;
+static const field core::int binaryXor = #C3;
+static const field core::int binaryShift1 = #C3;
+static const field core::int binaryShift2 = #C3;
+static const field core::int binaryShift3 = #C5;
+static const field core::int binaryShift4 = #C3;
+static const field core::bool binaryLess = #C6;
+static const field core::bool binaryLessEqual = #C7;
+static const field core::bool binaryGreaterEqual = #C7;
+static const field core::bool binaryGreater = #C6;
+static const field core::int doubleTruncateDiv = #C3;
+static const field core::int doubleTruncateDivZero = invalid-expression "Binary operator '~/' on '84.2' requires non-zero divisor, but divisor was '0'.";
+static const field dynamic nil = #C8;
+static const field core::int doubleTruncateDivNull = invalid-expression "Binary operator '~/' on '84.2' requires operand of type 'num', but was of type 'Null'.";
+static const field core::double doubleNan = #C9;
+static const field core::int doubleTruncateDivNaN = invalid-expression "Binary operator '84.2 ~/ NaN' results is Infinity or NaN.";
 static method main() → dynamic {}
 
 constants  {
@@ -139,5 +140,6 @@
   #C5 = 0
   #C6 = false
   #C7 = true
-  #C8 = NaN
+  #C8 = null
+  #C9 = NaN
 }
diff --git a/pkg/front_end/testcases/general/constants/number_folds_opt_out.dart b/pkg/front_end/testcases/general/constants/number_folds_opt_out.dart
new file mode 100644
index 0000000..0ad98da
--- /dev/null
+++ b/pkg/front_end/testcases/general/constants/number_folds_opt_out.dart
@@ -0,0 +1,41 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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
+
+const int shiftNegative1 = 2 << -1;
+const int shiftNegative3 = 2 >> -1;
+const int modZero = 2 % 0;
+const int divZero = 2 / 0;
+const int intdivZero = 2 ~/ 0;
+const int unaryMinus = -2;
+const int unaryTilde = ~2;
+const int unaryPlus = +2;
+
+const int binaryPlus = 40 + 2;
+const int binaryMinus = 44 - 2;
+const int binaryTimes = 21 * 2;
+const double binaryDiv = 84 / 2;
+const int binaryTildeDiv = 84~/ 2;
+const int binaryMod = 85 % 43;
+const int binaryOr = 32 | 10;
+const int binaryAnd = 63 & 106;
+const int binaryXor = 63 ^ 21;
+const int binaryShift1 = 21 << 1;
+
+const int binaryShift4 = 84 >> 1;
+const bool binaryLess = 42 < 42;
+const bool binaryLessEqual = 42 <= 42;
+const bool binaryGreaterEqual = 42 >= 42;
+const bool binaryGreater = 42 > 42;
+
+const int doubleTruncateDiv = 84.2 ~/ 2;
+const int doubleTruncateDivZero = 84.2 ~/ 0;
+const int doubleTruncateDivNull = 84.2 ~/ null;
+const double doubleNan = 0/0;
+const int doubleTruncateDivNaN = 84.2 ~/ doubleNan;
+
+main() {
+
+}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/general/constants/number_folds_opt_out.dart.textual_outline.expect b/pkg/front_end/testcases/general/constants/number_folds_opt_out.dart.textual_outline.expect
new file mode 100644
index 0000000..128603c
--- /dev/null
+++ b/pkg/front_end/testcases/general/constants/number_folds_opt_out.dart.textual_outline.expect
@@ -0,0 +1,30 @@
+// @dart = 2.9
+const int shiftNegative1 = 2 << -1;
+const int shiftNegative3 = 2 >> -1;
+const int modZero = 2 % 0;
+const int divZero = 2 / 0;
+const int intdivZero = 2 ~/ 0;
+const int unaryMinus = -2;
+const int unaryTilde = ~2;
+const int unaryPlus = +2;
+const int binaryPlus = 40 + 2;
+const int binaryMinus = 44 - 2;
+const int binaryTimes = 21 * 2;
+const double binaryDiv = 84 / 2;
+const int binaryTildeDiv = 84~/ 2;
+const int binaryMod = 85 % 43;
+const int binaryOr = 32 | 10;
+const int binaryAnd = 63 & 106;
+const int binaryXor = 63 ^ 21;
+const int binaryShift1 = 21 << 1;
+const int binaryShift4 = 84 >> 1;
+const bool binaryLess = 42 < 42;
+const bool binaryLessEqual = 42 <= 42;
+const bool binaryGreaterEqual = 42 >= 42;
+const bool binaryGreater = 42 > 42;
+const int doubleTruncateDiv = 84.2 ~/ 2;
+const int doubleTruncateDivZero = 84.2 ~/ 0;
+const int doubleTruncateDivNull = 84.2 ~/ null;
+const double doubleNan = 0/0;
+const int doubleTruncateDivNaN = 84.2 ~/ doubleNan;
+main() {}
diff --git a/pkg/front_end/testcases/general/constants/number_folds_opt_out.dart.weak.expect b/pkg/front_end/testcases/general/constants/number_folds_opt_out.dart.weak.expect
new file mode 100644
index 0000000..44bc90e
--- /dev/null
+++ b/pkg/front_end/testcases/general/constants/number_folds_opt_out.dart.weak.expect
@@ -0,0 +1,129 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/constants/number_folds_opt_out.dart:14:23: Error: '+' is not a prefix operator.
+// Try removing '+'.
+// const int unaryPlus = +2;
+//                       ^
+//
+// pkg/front_end/testcases/general/constants/number_folds_opt_out.dart:10:23: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+// const int divZero = 2 / 0;
+//                       ^
+//
+// pkg/front_end/testcases/general/constants/number_folds_opt_out.dart:7:30: Error: Constant evaluation error:
+// const int shiftNegative1 = 2 << -1;
+//                              ^
+// pkg/front_end/testcases/general/constants/number_folds_opt_out.dart:7:30: Context: Binary operator '<<' on '2' requires non-negative operand, but was '-1'.
+// const int shiftNegative1 = 2 << -1;
+//                              ^
+// pkg/front_end/testcases/general/constants/number_folds_opt_out.dart:7:11: Context: While analyzing:
+// const int shiftNegative1 = 2 << -1;
+//           ^
+//
+// pkg/front_end/testcases/general/constants/number_folds_opt_out.dart:8:30: Error: Constant evaluation error:
+// const int shiftNegative3 = 2 >> -1;
+//                              ^
+// pkg/front_end/testcases/general/constants/number_folds_opt_out.dart:8:30: Context: Binary operator '>>' on '2' requires non-negative operand, but was '-1'.
+// const int shiftNegative3 = 2 >> -1;
+//                              ^
+// pkg/front_end/testcases/general/constants/number_folds_opt_out.dart:8:11: Context: While analyzing:
+// const int shiftNegative3 = 2 >> -1;
+//           ^
+//
+// pkg/front_end/testcases/general/constants/number_folds_opt_out.dart:9:23: Error: Constant evaluation error:
+// const int modZero = 2 % 0;
+//                       ^
+// pkg/front_end/testcases/general/constants/number_folds_opt_out.dart:9:23: Context: Binary operator '%' on '2' requires non-zero divisor, but divisor was '0'.
+// const int modZero = 2 % 0;
+//                       ^
+// pkg/front_end/testcases/general/constants/number_folds_opt_out.dart:9:11: Context: While analyzing:
+// const int modZero = 2 % 0;
+//           ^
+//
+// pkg/front_end/testcases/general/constants/number_folds_opt_out.dart:11:26: Error: Constant evaluation error:
+// const int intdivZero = 2 ~/ 0;
+//                          ^
+// pkg/front_end/testcases/general/constants/number_folds_opt_out.dart:11:26: Context: Binary operator '~/' on '2' requires non-zero divisor, but divisor was '0'.
+// const int intdivZero = 2 ~/ 0;
+//                          ^
+// pkg/front_end/testcases/general/constants/number_folds_opt_out.dart:11:11: Context: While analyzing:
+// const int intdivZero = 2 ~/ 0;
+//           ^
+//
+// pkg/front_end/testcases/general/constants/number_folds_opt_out.dart:34:40: Error: Constant evaluation error:
+// const int doubleTruncateDivZero = 84.2 ~/ 0;
+//                                        ^
+// pkg/front_end/testcases/general/constants/number_folds_opt_out.dart:34:40: Context: Binary operator '~/' on '84.2' requires non-zero divisor, but divisor was '0'.
+// const int doubleTruncateDivZero = 84.2 ~/ 0;
+//                                        ^
+// pkg/front_end/testcases/general/constants/number_folds_opt_out.dart:34:11: Context: While analyzing:
+// const int doubleTruncateDivZero = 84.2 ~/ 0;
+//           ^
+//
+// pkg/front_end/testcases/general/constants/number_folds_opt_out.dart:35:40: Error: Constant evaluation error:
+// const int doubleTruncateDivNull = 84.2 ~/ null;
+//                                        ^
+// pkg/front_end/testcases/general/constants/number_folds_opt_out.dart:35:40: Context: Binary operator '~/' on '84.2' requires operand of type 'num', but was of type 'Null'.
+// const int doubleTruncateDivNull = 84.2 ~/ null;
+//                                        ^
+// pkg/front_end/testcases/general/constants/number_folds_opt_out.dart:35:11: Context: While analyzing:
+// const int doubleTruncateDivNull = 84.2 ~/ null;
+//           ^
+//
+// pkg/front_end/testcases/general/constants/number_folds_opt_out.dart:37:39: Error: Constant evaluation error:
+// const int doubleTruncateDivNaN = 84.2 ~/ doubleNan;
+//                                       ^
+// pkg/front_end/testcases/general/constants/number_folds_opt_out.dart:37:39: Context: Binary operator '84.2 ~/ NaN' results is Infinity or NaN.
+// const int doubleTruncateDivNaN = 84.2 ~/ doubleNan;
+//                                       ^
+// pkg/front_end/testcases/general/constants/number_folds_opt_out.dart:37:11: Context: While analyzing:
+// const int doubleTruncateDivNaN = 84.2 ~/ doubleNan;
+//           ^
+//
+import self as self;
+import "dart:core" as core;
+
+static const field core::int* shiftNegative1 = invalid-expression "Binary operator '<<' on '2' requires non-negative operand, but was '-1'.";
+static const field core::int* shiftNegative3 = invalid-expression "Binary operator '>>' on '2' requires non-negative operand, but was '-1'.";
+static const field core::int* modZero = invalid-expression "Binary operator '%' on '2' requires non-zero divisor, but divisor was '0'.";
+static const field core::int* divZero = invalid-expression "pkg/front_end/testcases/general/constants/number_folds_opt_out.dart:10:23: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+const int divZero = 2 / 0;
+                      ^";
+static const field core::int* intdivZero = invalid-expression "Binary operator '~/' on '2' requires non-zero divisor, but divisor was '0'.";
+static const field core::int* unaryMinus = #C1;
+static const field core::int* unaryTilde = #C2;
+static const field core::int* unaryPlus = invalid-expression "pkg/front_end/testcases/general/constants/number_folds_opt_out.dart:14:23: Error: This couldn't be parsed.
+const int unaryPlus = +2;
+                      ^";
+static const field core::int* binaryPlus = #C3;
+static const field core::int* binaryMinus = #C3;
+static const field core::int* binaryTimes = #C3;
+static const field core::double* binaryDiv = #C4;
+static const field core::int* binaryTildeDiv = #C3;
+static const field core::int* binaryMod = #C3;
+static const field core::int* binaryOr = #C3;
+static const field core::int* binaryAnd = #C3;
+static const field core::int* binaryXor = #C3;
+static const field core::int* binaryShift1 = #C3;
+static const field core::int* binaryShift4 = #C3;
+static const field core::bool* binaryLess = #C5;
+static const field core::bool* binaryLessEqual = #C6;
+static const field core::bool* binaryGreaterEqual = #C6;
+static const field core::bool* binaryGreater = #C5;
+static const field core::int* doubleTruncateDiv = #C3;
+static const field core::int* doubleTruncateDivZero = invalid-expression "Binary operator '~/' on '84.2' requires non-zero divisor, but divisor was '0'.";
+static const field core::int* doubleTruncateDivNull = invalid-expression "Binary operator '~/' on '84.2' requires operand of type 'num', but was of type 'Null'.";
+static const field core::double* doubleNan = #C7;
+static const field core::int* doubleTruncateDivNaN = invalid-expression "Binary operator '84.2 ~/ NaN' results is Infinity or NaN.";
+static method main() → dynamic {}
+
+constants  {
+  #C1 = -2
+  #C2 = -3
+  #C3 = 42
+  #C4 = 42.0
+  #C5 = false
+  #C6 = true
+  #C7 = NaN
+}
diff --git a/pkg/front_end/testcases/general/constants/number_folds_opt_out.dart.weak.outline.expect b/pkg/front_end/testcases/general/constants/number_folds_opt_out.dart.weak.outline.expect
new file mode 100644
index 0000000..df84569
--- /dev/null
+++ b/pkg/front_end/testcases/general/constants/number_folds_opt_out.dart.weak.outline.expect
@@ -0,0 +1,77 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/constants/number_folds_opt_out.dart:14:23: Error: '+' is not a prefix operator.
+// Try removing '+'.
+// const int unaryPlus = +2;
+//                       ^
+//
+// pkg/front_end/testcases/general/constants/number_folds_opt_out.dart:10:23: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+// const int divZero = 2 / 0;
+//                       ^
+//
+import self as self;
+import "dart:core" as core;
+
+static const field core::int* shiftNegative1 = 2.{core::int::<<}(1.{core::int::unary-}());
+static const field core::int* shiftNegative3 = 2.{core::int::>>}(1.{core::int::unary-}());
+static const field core::int* modZero = 2.{core::num::%}(0);
+static const field core::int* divZero = let final Never* #t1 = invalid-expression "pkg/front_end/testcases/general/constants/number_folds_opt_out.dart:10:23: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+const int divZero = 2 / 0;
+                      ^" in 2.{core::num::/}(0) as{TypeError} core::int*;
+static const field core::int* intdivZero = 2.{core::num::~/}(0);
+static const field core::int* unaryMinus = 2.{core::int::unary-}();
+static const field core::int* unaryTilde = 2.{core::int::~}();
+static const field core::int* unaryPlus = invalid-expression "pkg/front_end/testcases/general/constants/number_folds_opt_out.dart:14:23: Error: This couldn't be parsed.
+const int unaryPlus = +2;
+                      ^".+(2) as{TypeError,ForDynamic} core::int*;
+static const field core::int* binaryPlus = 40.{core::num::+}(2);
+static const field core::int* binaryMinus = 44.{core::num::-}(2);
+static const field core::int* binaryTimes = 21.{core::num::*}(2);
+static const field core::double* binaryDiv = 84.{core::num::/}(2);
+static const field core::int* binaryTildeDiv = 84.{core::num::~/}(2);
+static const field core::int* binaryMod = 85.{core::num::%}(43);
+static const field core::int* binaryOr = 32.{core::int::|}(10);
+static const field core::int* binaryAnd = 63.{core::int::&}(106);
+static const field core::int* binaryXor = 63.{core::int::^}(21);
+static const field core::int* binaryShift1 = 21.{core::int::<<}(1);
+static const field core::int* binaryShift4 = 84.{core::int::>>}(1);
+static const field core::bool* binaryLess = 42.{core::num::<}(42);
+static const field core::bool* binaryLessEqual = 42.{core::num::<=}(42);
+static const field core::bool* binaryGreaterEqual = 42.{core::num::>=}(42);
+static const field core::bool* binaryGreater = 42.{core::num::>}(42);
+static const field core::int* doubleTruncateDiv = 84.2.{core::double::~/}(2);
+static const field core::int* doubleTruncateDivZero = 84.2.{core::double::~/}(0);
+static const field core::int* doubleTruncateDivNull = 84.2.{core::double::~/}(null);
+static const field core::double* doubleNan = 0.{core::num::/}(0);
+static const field core::int* doubleTruncateDivNaN = 84.2.{core::double::~/}(self::doubleNan);
+static method main() → dynamic
+  ;
+
+
+Extra constant evaluation status:
+Evaluated: MethodInvocation @ org-dartlang-testcase:///number_folds_opt_out.dart:7:33 -> IntConstant(-1)
+Evaluated: MethodInvocation @ org-dartlang-testcase:///number_folds_opt_out.dart:8:33 -> IntConstant(-1)
+Evaluated: MethodInvocation @ org-dartlang-testcase:///number_folds_opt_out.dart:10:23 -> DoubleConstant(Infinity)
+Evaluated: MethodInvocation @ org-dartlang-testcase:///number_folds_opt_out.dart:12:24 -> IntConstant(-2)
+Evaluated: MethodInvocation @ org-dartlang-testcase:///number_folds_opt_out.dart:13:24 -> IntConstant(-3)
+Evaluated: MethodInvocation @ org-dartlang-testcase:///number_folds_opt_out.dart:16:27 -> IntConstant(42)
+Evaluated: MethodInvocation @ org-dartlang-testcase:///number_folds_opt_out.dart:17:28 -> IntConstant(42)
+Evaluated: MethodInvocation @ org-dartlang-testcase:///number_folds_opt_out.dart:18:28 -> IntConstant(42)
+Evaluated: MethodInvocation @ org-dartlang-testcase:///number_folds_opt_out.dart:19:29 -> DoubleConstant(42.0)
+Evaluated: MethodInvocation @ org-dartlang-testcase:///number_folds_opt_out.dart:20:30 -> IntConstant(42)
+Evaluated: MethodInvocation @ org-dartlang-testcase:///number_folds_opt_out.dart:21:26 -> IntConstant(42)
+Evaluated: MethodInvocation @ org-dartlang-testcase:///number_folds_opt_out.dart:22:25 -> IntConstant(42)
+Evaluated: MethodInvocation @ org-dartlang-testcase:///number_folds_opt_out.dart:23:26 -> IntConstant(42)
+Evaluated: MethodInvocation @ org-dartlang-testcase:///number_folds_opt_out.dart:24:26 -> IntConstant(42)
+Evaluated: MethodInvocation @ org-dartlang-testcase:///number_folds_opt_out.dart:25:29 -> IntConstant(42)
+Evaluated: MethodInvocation @ org-dartlang-testcase:///number_folds_opt_out.dart:27:29 -> IntConstant(42)
+Evaluated: MethodInvocation @ org-dartlang-testcase:///number_folds_opt_out.dart:28:28 -> BoolConstant(false)
+Evaluated: MethodInvocation @ org-dartlang-testcase:///number_folds_opt_out.dart:29:33 -> BoolConstant(true)
+Evaluated: MethodInvocation @ org-dartlang-testcase:///number_folds_opt_out.dart:30:36 -> BoolConstant(true)
+Evaluated: MethodInvocation @ org-dartlang-testcase:///number_folds_opt_out.dart:31:31 -> BoolConstant(false)
+Evaluated: MethodInvocation @ org-dartlang-testcase:///number_folds_opt_out.dart:33:36 -> IntConstant(42)
+Evaluated: MethodInvocation @ org-dartlang-testcase:///number_folds_opt_out.dart:36:27 -> DoubleConstant(NaN)
+Evaluated: StaticGet @ org-dartlang-testcase:///number_folds_opt_out.dart:37:42 -> DoubleConstant(NaN)
+Extra constant evaluation: evaluated: 34, effectively constant: 23
diff --git a/pkg/front_end/testcases/general/constants/number_folds_opt_out.dart.weak.transformed.expect b/pkg/front_end/testcases/general/constants/number_folds_opt_out.dart.weak.transformed.expect
new file mode 100644
index 0000000..44bc90e
--- /dev/null
+++ b/pkg/front_end/testcases/general/constants/number_folds_opt_out.dart.weak.transformed.expect
@@ -0,0 +1,129 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/constants/number_folds_opt_out.dart:14:23: Error: '+' is not a prefix operator.
+// Try removing '+'.
+// const int unaryPlus = +2;
+//                       ^
+//
+// pkg/front_end/testcases/general/constants/number_folds_opt_out.dart:10:23: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+// const int divZero = 2 / 0;
+//                       ^
+//
+// pkg/front_end/testcases/general/constants/number_folds_opt_out.dart:7:30: Error: Constant evaluation error:
+// const int shiftNegative1 = 2 << -1;
+//                              ^
+// pkg/front_end/testcases/general/constants/number_folds_opt_out.dart:7:30: Context: Binary operator '<<' on '2' requires non-negative operand, but was '-1'.
+// const int shiftNegative1 = 2 << -1;
+//                              ^
+// pkg/front_end/testcases/general/constants/number_folds_opt_out.dart:7:11: Context: While analyzing:
+// const int shiftNegative1 = 2 << -1;
+//           ^
+//
+// pkg/front_end/testcases/general/constants/number_folds_opt_out.dart:8:30: Error: Constant evaluation error:
+// const int shiftNegative3 = 2 >> -1;
+//                              ^
+// pkg/front_end/testcases/general/constants/number_folds_opt_out.dart:8:30: Context: Binary operator '>>' on '2' requires non-negative operand, but was '-1'.
+// const int shiftNegative3 = 2 >> -1;
+//                              ^
+// pkg/front_end/testcases/general/constants/number_folds_opt_out.dart:8:11: Context: While analyzing:
+// const int shiftNegative3 = 2 >> -1;
+//           ^
+//
+// pkg/front_end/testcases/general/constants/number_folds_opt_out.dart:9:23: Error: Constant evaluation error:
+// const int modZero = 2 % 0;
+//                       ^
+// pkg/front_end/testcases/general/constants/number_folds_opt_out.dart:9:23: Context: Binary operator '%' on '2' requires non-zero divisor, but divisor was '0'.
+// const int modZero = 2 % 0;
+//                       ^
+// pkg/front_end/testcases/general/constants/number_folds_opt_out.dart:9:11: Context: While analyzing:
+// const int modZero = 2 % 0;
+//           ^
+//
+// pkg/front_end/testcases/general/constants/number_folds_opt_out.dart:11:26: Error: Constant evaluation error:
+// const int intdivZero = 2 ~/ 0;
+//                          ^
+// pkg/front_end/testcases/general/constants/number_folds_opt_out.dart:11:26: Context: Binary operator '~/' on '2' requires non-zero divisor, but divisor was '0'.
+// const int intdivZero = 2 ~/ 0;
+//                          ^
+// pkg/front_end/testcases/general/constants/number_folds_opt_out.dart:11:11: Context: While analyzing:
+// const int intdivZero = 2 ~/ 0;
+//           ^
+//
+// pkg/front_end/testcases/general/constants/number_folds_opt_out.dart:34:40: Error: Constant evaluation error:
+// const int doubleTruncateDivZero = 84.2 ~/ 0;
+//                                        ^
+// pkg/front_end/testcases/general/constants/number_folds_opt_out.dart:34:40: Context: Binary operator '~/' on '84.2' requires non-zero divisor, but divisor was '0'.
+// const int doubleTruncateDivZero = 84.2 ~/ 0;
+//                                        ^
+// pkg/front_end/testcases/general/constants/number_folds_opt_out.dart:34:11: Context: While analyzing:
+// const int doubleTruncateDivZero = 84.2 ~/ 0;
+//           ^
+//
+// pkg/front_end/testcases/general/constants/number_folds_opt_out.dart:35:40: Error: Constant evaluation error:
+// const int doubleTruncateDivNull = 84.2 ~/ null;
+//                                        ^
+// pkg/front_end/testcases/general/constants/number_folds_opt_out.dart:35:40: Context: Binary operator '~/' on '84.2' requires operand of type 'num', but was of type 'Null'.
+// const int doubleTruncateDivNull = 84.2 ~/ null;
+//                                        ^
+// pkg/front_end/testcases/general/constants/number_folds_opt_out.dart:35:11: Context: While analyzing:
+// const int doubleTruncateDivNull = 84.2 ~/ null;
+//           ^
+//
+// pkg/front_end/testcases/general/constants/number_folds_opt_out.dart:37:39: Error: Constant evaluation error:
+// const int doubleTruncateDivNaN = 84.2 ~/ doubleNan;
+//                                       ^
+// pkg/front_end/testcases/general/constants/number_folds_opt_out.dart:37:39: Context: Binary operator '84.2 ~/ NaN' results is Infinity or NaN.
+// const int doubleTruncateDivNaN = 84.2 ~/ doubleNan;
+//                                       ^
+// pkg/front_end/testcases/general/constants/number_folds_opt_out.dart:37:11: Context: While analyzing:
+// const int doubleTruncateDivNaN = 84.2 ~/ doubleNan;
+//           ^
+//
+import self as self;
+import "dart:core" as core;
+
+static const field core::int* shiftNegative1 = invalid-expression "Binary operator '<<' on '2' requires non-negative operand, but was '-1'.";
+static const field core::int* shiftNegative3 = invalid-expression "Binary operator '>>' on '2' requires non-negative operand, but was '-1'.";
+static const field core::int* modZero = invalid-expression "Binary operator '%' on '2' requires non-zero divisor, but divisor was '0'.";
+static const field core::int* divZero = invalid-expression "pkg/front_end/testcases/general/constants/number_folds_opt_out.dart:10:23: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+const int divZero = 2 / 0;
+                      ^";
+static const field core::int* intdivZero = invalid-expression "Binary operator '~/' on '2' requires non-zero divisor, but divisor was '0'.";
+static const field core::int* unaryMinus = #C1;
+static const field core::int* unaryTilde = #C2;
+static const field core::int* unaryPlus = invalid-expression "pkg/front_end/testcases/general/constants/number_folds_opt_out.dart:14:23: Error: This couldn't be parsed.
+const int unaryPlus = +2;
+                      ^";
+static const field core::int* binaryPlus = #C3;
+static const field core::int* binaryMinus = #C3;
+static const field core::int* binaryTimes = #C3;
+static const field core::double* binaryDiv = #C4;
+static const field core::int* binaryTildeDiv = #C3;
+static const field core::int* binaryMod = #C3;
+static const field core::int* binaryOr = #C3;
+static const field core::int* binaryAnd = #C3;
+static const field core::int* binaryXor = #C3;
+static const field core::int* binaryShift1 = #C3;
+static const field core::int* binaryShift4 = #C3;
+static const field core::bool* binaryLess = #C5;
+static const field core::bool* binaryLessEqual = #C6;
+static const field core::bool* binaryGreaterEqual = #C6;
+static const field core::bool* binaryGreater = #C5;
+static const field core::int* doubleTruncateDiv = #C3;
+static const field core::int* doubleTruncateDivZero = invalid-expression "Binary operator '~/' on '84.2' requires non-zero divisor, but divisor was '0'.";
+static const field core::int* doubleTruncateDivNull = invalid-expression "Binary operator '~/' on '84.2' requires operand of type 'num', but was of type 'Null'.";
+static const field core::double* doubleNan = #C7;
+static const field core::int* doubleTruncateDivNaN = invalid-expression "Binary operator '84.2 ~/ NaN' results is Infinity or NaN.";
+static method main() → dynamic {}
+
+constants  {
+  #C1 = -2
+  #C2 = -3
+  #C3 = 42
+  #C4 = 42.0
+  #C5 = false
+  #C6 = true
+  #C7 = NaN
+}
diff --git a/pkg/front_end/testcases/general/crashes/crash_01/main.dart b/pkg/front_end/testcases/general/crashes/crash_01/main.dart
new file mode 100644
index 0000000..6258ba8
--- /dev/null
+++ b/pkg/front_end/testcases/general/crashes/crash_01/main.dart
@@ -0,0 +1,12 @@
+import 'main_lib.dart';
+
+class SliverConstraints {}
+
+abstract class RenderSliver extends RenderObject {
+  SliverConstraints get constraints => super.constraints as SliverConstraints;
+}
+
+abstract class RenderSliverSingleBoxAdapter extends RenderSliver
+    with RenderObjectWithChildMixin {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/crashes/crash_01/main.dart.textual_outline.expect b/pkg/front_end/testcases/general/crashes/crash_01/main.dart.textual_outline.expect
new file mode 100644
index 0000000..6258ba8
--- /dev/null
+++ b/pkg/front_end/testcases/general/crashes/crash_01/main.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+import 'main_lib.dart';
+
+class SliverConstraints {}
+
+abstract class RenderSliver extends RenderObject {
+  SliverConstraints get constraints => super.constraints as SliverConstraints;
+}
+
+abstract class RenderSliverSingleBoxAdapter extends RenderSliver
+    with RenderObjectWithChildMixin {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/crashes/crash_01/main.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/crashes/crash_01/main.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..cb9802c
--- /dev/null
+++ b/pkg/front_end/testcases/general/crashes/crash_01/main.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+import 'main_lib.dart';
+
+abstract class RenderSliver extends RenderObject {
+  SliverConstraints get constraints => super.constraints as SliverConstraints;
+}
+
+abstract class RenderSliverSingleBoxAdapter extends RenderSliver
+    with RenderObjectWithChildMixin {}
+
+class SliverConstraints {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/crashes/crash_01/main.dart.weak.expect b/pkg/front_end/testcases/general/crashes/crash_01/main.dart.weak.expect
new file mode 100644
index 0000000..ffd4dfe
--- /dev/null
+++ b/pkg/front_end/testcases/general/crashes/crash_01/main.dart.weak.expect
@@ -0,0 +1,59 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "main_lib.dart" as mai;
+
+import "org-dartlang-testcase:///main_lib.dart";
+
+class SliverConstraints extends core::Object {
+  synthetic constructor •() → self::SliverConstraints
+    : super core::Object::•()
+    ;
+}
+abstract class RenderSliver extends mai::RenderObject {
+  synthetic constructor •() → self::RenderSliver
+    : super mai::RenderObject::•()
+    ;
+  get constraints() → self::SliverConstraints
+    return super.{mai::RenderObject::constraints} as{ForNonNullableByDefault} self::SliverConstraints;
+}
+abstract class _RenderSliverSingleBoxAdapter&RenderSliver&RenderObjectWithChildMixin = self::RenderSliver with mai::RenderObjectWithChildMixin /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_RenderSliverSingleBoxAdapter&RenderSliver&RenderObjectWithChildMixin
+    : super self::RenderSliver::•()
+    ;
+  abstract member-signature get constraints() → invalid-type; -> self::RenderSliver::constraints
+}
+abstract class RenderSliverSingleBoxAdapter extends self::_RenderSliverSingleBoxAdapter&RenderSliver&RenderObjectWithChildMixin {
+  synthetic constructor •() → self::RenderSliverSingleBoxAdapter
+    : super self::_RenderSliverSingleBoxAdapter&RenderSliver&RenderObjectWithChildMixin::•()
+    ;
+}
+static method main() → dynamic {}
+
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/crashes/crash_01/main_lib.dart:2:3: Error: Type 'Constraints' not found.
+//   Constraints get constraints {}
+//   ^^^^^^^^^^^
+//
+// pkg/front_end/testcases/general/crashes/crash_01/main_lib.dart:2:19: Error: A non-null value must be returned since the return type 'invalid-type' doesn't allow null.
+//   Constraints get constraints {}
+//                   ^
+//
+import self as mai;
+import "dart:core" as core;
+
+abstract class RenderObject extends core::Object {
+  synthetic constructor •() → mai::RenderObject
+    : super core::Object::•()
+    ;
+  get constraints() → invalid-type {
+    return let final Never #t1 = invalid-expression "pkg/front_end/testcases/general/crashes/crash_01/main_lib.dart:2:19: Error: A non-null value must be returned since the return type 'invalid-type' doesn't allow null.
+  Constraints get constraints {}
+                  ^" in null;
+  }
+}
+abstract class RenderObjectWithChildMixin extends mai::RenderObject /*isMixinDeclaration*/  {
+}
diff --git a/pkg/front_end/testcases/general/crashes/crash_01/main.dart.weak.outline.expect b/pkg/front_end/testcases/general/crashes/crash_01/main.dart.weak.outline.expect
new file mode 100644
index 0000000..8c1c6ff
--- /dev/null
+++ b/pkg/front_end/testcases/general/crashes/crash_01/main.dart.weak.outline.expect
@@ -0,0 +1,49 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "main_lib.dart" as mai;
+
+import "org-dartlang-testcase:///main_lib.dart";
+
+class SliverConstraints extends core::Object {
+  synthetic constructor •() → self::SliverConstraints
+    ;
+}
+abstract class RenderSliver extends mai::RenderObject {
+  synthetic constructor •() → self::RenderSliver
+    ;
+  get constraints() → self::SliverConstraints
+    ;
+}
+abstract class _RenderSliverSingleBoxAdapter&RenderSliver&RenderObjectWithChildMixin = self::RenderSliver with mai::RenderObjectWithChildMixin /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_RenderSliverSingleBoxAdapter&RenderSliver&RenderObjectWithChildMixin
+    : super self::RenderSliver::•()
+    ;
+  abstract member-signature get constraints() → invalid-type; -> self::RenderSliver::constraints
+}
+abstract class RenderSliverSingleBoxAdapter extends self::_RenderSliverSingleBoxAdapter&RenderSliver&RenderObjectWithChildMixin {
+  synthetic constructor •() → self::RenderSliverSingleBoxAdapter
+    ;
+}
+static method main() → dynamic
+  ;
+
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/crashes/crash_01/main_lib.dart:2:3: Error: Type 'Constraints' not found.
+//   Constraints get constraints {}
+//   ^^^^^^^^^^^
+//
+import self as mai;
+import "dart:core" as core;
+
+abstract class RenderObject extends core::Object {
+  synthetic constructor •() → mai::RenderObject
+    ;
+  get constraints() → invalid-type
+    ;
+}
+abstract class RenderObjectWithChildMixin extends mai::RenderObject /*isMixinDeclaration*/  {
+}
diff --git a/pkg/front_end/testcases/general/crashes/crash_01/main.dart.weak.transformed.expect b/pkg/front_end/testcases/general/crashes/crash_01/main.dart.weak.transformed.expect
new file mode 100644
index 0000000..2825858
--- /dev/null
+++ b/pkg/front_end/testcases/general/crashes/crash_01/main.dart.weak.transformed.expect
@@ -0,0 +1,59 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "main_lib.dart" as mai;
+
+import "org-dartlang-testcase:///main_lib.dart";
+
+class SliverConstraints extends core::Object {
+  synthetic constructor •() → self::SliverConstraints
+    : super core::Object::•()
+    ;
+}
+abstract class RenderSliver extends mai::RenderObject {
+  synthetic constructor •() → self::RenderSliver
+    : super mai::RenderObject::•()
+    ;
+  get constraints() → self::SliverConstraints
+    return super.{mai::RenderObject::constraints};
+}
+abstract class _RenderSliverSingleBoxAdapter&RenderSliver&RenderObjectWithChildMixin extends self::RenderSliver implements mai::RenderObjectWithChildMixin /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_RenderSliverSingleBoxAdapter&RenderSliver&RenderObjectWithChildMixin
+    : super self::RenderSliver::•()
+    ;
+  abstract member-signature get constraints() → invalid-type; -> self::RenderSliver::constraints
+}
+abstract class RenderSliverSingleBoxAdapter extends self::_RenderSliverSingleBoxAdapter&RenderSliver&RenderObjectWithChildMixin {
+  synthetic constructor •() → self::RenderSliverSingleBoxAdapter
+    : super self::_RenderSliverSingleBoxAdapter&RenderSliver&RenderObjectWithChildMixin::•()
+    ;
+}
+static method main() → dynamic {}
+
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/crashes/crash_01/main_lib.dart:2:3: Error: Type 'Constraints' not found.
+//   Constraints get constraints {}
+//   ^^^^^^^^^^^
+//
+// pkg/front_end/testcases/general/crashes/crash_01/main_lib.dart:2:19: Error: A non-null value must be returned since the return type 'invalid-type' doesn't allow null.
+//   Constraints get constraints {}
+//                   ^
+//
+import self as mai;
+import "dart:core" as core;
+
+abstract class RenderObject extends core::Object {
+  synthetic constructor •() → mai::RenderObject
+    : super core::Object::•()
+    ;
+  get constraints() → invalid-type {
+    return let final Never #t1 = invalid-expression "pkg/front_end/testcases/general/crashes/crash_01/main_lib.dart:2:19: Error: A non-null value must be returned since the return type 'invalid-type' doesn't allow null.
+  Constraints get constraints {}
+                  ^" in null;
+  }
+}
+abstract class RenderObjectWithChildMixin extends mai::RenderObject /*isMixinDeclaration*/  {
+}
diff --git a/pkg/front_end/testcases/general/crashes/crash_01/main_lib.dart b/pkg/front_end/testcases/general/crashes/crash_01/main_lib.dart
new file mode 100644
index 0000000..f31f8b6
--- /dev/null
+++ b/pkg/front_end/testcases/general/crashes/crash_01/main_lib.dart
@@ -0,0 +1,5 @@
+abstract class RenderObject {
+  Constraints get constraints {}
+}
+
+mixin RenderObjectWithChildMixin on RenderObject {}
diff --git a/pkg/front_end/testcases/general/crashes/crash_02/main.dart b/pkg/front_end/testcases/general/crashes/crash_02/main.dart
new file mode 100644
index 0000000..3023c50
--- /dev/null
+++ b/pkg/front_end/testcases/general/crashes/crash_02/main.dart
@@ -0,0 +1,9 @@
+mixin A on D, E {}
+
+class B extends C with A {}
+
+class C {}
+
+class D {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/crashes/crash_02/main.dart.textual_outline.expect b/pkg/front_end/testcases/general/crashes/crash_02/main.dart.textual_outline.expect
new file mode 100644
index 0000000..3023c50
--- /dev/null
+++ b/pkg/front_end/testcases/general/crashes/crash_02/main.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+mixin A on D, E {}
+
+class B extends C with A {}
+
+class C {}
+
+class D {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/crashes/crash_02/main.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/crashes/crash_02/main.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2dd7a40c
--- /dev/null
+++ b/pkg/front_end/testcases/general/crashes/crash_02/main.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+class B extends C with A {}
+
+class C {}
+
+class D {}
+
+main() {}
+mixin A on D, E {}
diff --git a/pkg/front_end/testcases/general/crashes/crash_03/main.dart b/pkg/front_end/testcases/general/crashes/crash_03/main.dart
new file mode 100644
index 0000000..02f0f7c
--- /dev/null
+++ b/pkg/front_end/testcases/general/crashes/crash_03/main.dart
@@ -0,0 +1,12 @@
+import 'main_lib.dart';
+
+class Offset {}
+
+class PlatformViewRenderBox extends RenderBox with _PlatformViewGestureMixin {}
+
+mixin _PlatformViewGestureMixin on RenderBox implements MouseTrackerAnnotation {
+  bool hitTestSelf(Offset position) =>
+      _hitTestBehavior != PlatformViewHitTestBehavior.transparent;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/crashes/crash_03/main.dart.textual_outline.expect b/pkg/front_end/testcases/general/crashes/crash_03/main.dart.textual_outline.expect
new file mode 100644
index 0000000..c81eca3
--- /dev/null
+++ b/pkg/front_end/testcases/general/crashes/crash_03/main.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+import 'main_lib.dart';
+
+class Offset {}
+
+class PlatformViewRenderBox extends RenderBox with _PlatformViewGestureMixin {}
+
+mixin _PlatformViewGestureMixin on RenderBox implements MouseTrackerAnnotation {
+  bool hitTestSelf(Offset position) =>
+      _hitTestBehavior != PlatformViewHitTestBehavior.transparent;
+}
+main() {}
diff --git a/pkg/front_end/testcases/general/crashes/crash_03/main.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/crashes/crash_03/main.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5260853
--- /dev/null
+++ b/pkg/front_end/testcases/general/crashes/crash_03/main.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+import 'main_lib.dart';
+
+class Offset {}
+
+class PlatformViewRenderBox extends RenderBox with _PlatformViewGestureMixin {}
+
+main() {}
+mixin _PlatformViewGestureMixin on RenderBox implements MouseTrackerAnnotation {
+  bool hitTestSelf(Offset position) =>
+      _hitTestBehavior != PlatformViewHitTestBehavior.transparent;
+}
diff --git a/pkg/front_end/testcases/general/crashes/crash_03/main.dart.weak.expect b/pkg/front_end/testcases/general/crashes/crash_03/main.dart.weak.expect
new file mode 100644
index 0000000..02e0ecc
--- /dev/null
+++ b/pkg/front_end/testcases/general/crashes/crash_03/main.dart.weak.expect
@@ -0,0 +1,79 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/crashes/crash_03/main.dart:7:57: Error: Type 'MouseTrackerAnnotation' not found.
+// mixin _PlatformViewGestureMixin on RenderBox implements MouseTrackerAnnotation {
+//                                                         ^^^^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/general/crashes/crash_03/main.dart:9:7: Error: The getter '_hitTestBehavior' isn't defined for the class '_PlatformViewGestureMixin'.
+//  - '_PlatformViewGestureMixin' is from 'pkg/front_end/testcases/general/crashes/crash_03/main.dart'.
+// Try correcting the name to the name of an existing getter, or defining a getter or field named '_hitTestBehavior'.
+//       _hitTestBehavior != PlatformViewHitTestBehavior.transparent;
+//       ^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/general/crashes/crash_03/main.dart:9:27: Error: The getter 'PlatformViewHitTestBehavior' isn't defined for the class '_PlatformViewGestureMixin'.
+//  - '_PlatformViewGestureMixin' is from 'pkg/front_end/testcases/general/crashes/crash_03/main.dart'.
+// Try correcting the name to the name of an existing getter, or defining a getter or field named 'PlatformViewHitTestBehavior'.
+//       _hitTestBehavior != PlatformViewHitTestBehavior.transparent;
+//                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+import "main_lib.dart" as mai;
+
+import "org-dartlang-testcase:///main_lib.dart";
+
+class Offset extends core::Object {
+  synthetic constructor •() → self::Offset
+    : super core::Object::•()
+    ;
+}
+abstract class _PlatformViewRenderBox&RenderBox&_PlatformViewGestureMixin = mai::RenderBox with self::_PlatformViewGestureMixin /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_PlatformViewRenderBox&RenderBox&_PlatformViewGestureMixin
+    : super mai::RenderBox::•()
+    ;
+  mixin-super-stub method hitTestSelf(self::Offset position) → core::bool
+    return super.{self::_PlatformViewGestureMixin::hitTestSelf}(position);
+}
+class PlatformViewRenderBox extends self::_PlatformViewRenderBox&RenderBox&_PlatformViewGestureMixin {
+  synthetic constructor •() → self::PlatformViewRenderBox
+    : super self::_PlatformViewRenderBox&RenderBox&_PlatformViewGestureMixin::•()
+    ;
+}
+abstract class _PlatformViewGestureMixin extends mai::RenderBox /*isMixinDeclaration*/  {
+  method hitTestSelf(self::Offset position) → core::bool
+    return !invalid-expression "pkg/front_end/testcases/general/crashes/crash_03/main.dart:9:7: Error: The getter '_hitTestBehavior' isn't defined for the class '_PlatformViewGestureMixin'.
+ - '_PlatformViewGestureMixin' is from 'pkg/front_end/testcases/general/crashes/crash_03/main.dart'.
+Try correcting the name to the name of an existing getter, or defining a getter or field named '_hitTestBehavior'.
+      _hitTestBehavior != PlatformViewHitTestBehavior.transparent;
+      ^^^^^^^^^^^^^^^^".{core::Object::==}(invalid-expression "pkg/front_end/testcases/general/crashes/crash_03/main.dart:9:27: Error: The getter 'PlatformViewHitTestBehavior' isn't defined for the class '_PlatformViewGestureMixin'.
+ - '_PlatformViewGestureMixin' is from 'pkg/front_end/testcases/general/crashes/crash_03/main.dart'.
+Try correcting the name to the name of an existing getter, or defining a getter or field named 'PlatformViewHitTestBehavior'.
+      _hitTestBehavior != PlatformViewHitTestBehavior.transparent;
+                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^".transparent);
+}
+static method main() → dynamic {}
+
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/crashes/crash_03/main_lib.dart:2:20: Error: Type 'Offset' not found.
+//   bool hitTestSelf(Offset position) => false;
+//                    ^^^^^^
+//
+// pkg/front_end/testcases/general/crashes/crash_03/main_lib.dart:2:20: Error: 'Offset' isn't a type.
+//   bool hitTestSelf(Offset position) => false;
+//                    ^^^^^^
+//
+import self as mai;
+import "dart:core" as core;
+
+abstract class RenderBox extends core::Object {
+  synthetic constructor •() → mai::RenderBox
+    : super core::Object::•()
+    ;
+  method hitTestSelf(invalid-type position) → core::bool
+    return false;
+}
diff --git a/pkg/front_end/testcases/general/crashes/crash_03/main.dart.weak.outline.expect b/pkg/front_end/testcases/general/crashes/crash_03/main.dart.weak.outline.expect
new file mode 100644
index 0000000..6af4997
--- /dev/null
+++ b/pkg/front_end/testcases/general/crashes/crash_03/main.dart.weak.outline.expect
@@ -0,0 +1,53 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/crashes/crash_03/main.dart:7:57: Error: Type 'MouseTrackerAnnotation' not found.
+// mixin _PlatformViewGestureMixin on RenderBox implements MouseTrackerAnnotation {
+//                                                         ^^^^^^^^^^^^^^^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+import "main_lib.dart" as mai;
+
+import "org-dartlang-testcase:///main_lib.dart";
+
+class Offset extends core::Object {
+  synthetic constructor •() → self::Offset
+    ;
+}
+abstract class _PlatformViewRenderBox&RenderBox&_PlatformViewGestureMixin = mai::RenderBox with self::_PlatformViewGestureMixin /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_PlatformViewRenderBox&RenderBox&_PlatformViewGestureMixin
+    : super mai::RenderBox::•()
+    ;
+  mixin-super-stub method hitTestSelf(self::Offset position) → core::bool
+    return super.{self::_PlatformViewGestureMixin::hitTestSelf}(position);
+}
+class PlatformViewRenderBox extends self::_PlatformViewRenderBox&RenderBox&_PlatformViewGestureMixin {
+  synthetic constructor •() → self::PlatformViewRenderBox
+    ;
+}
+abstract class _PlatformViewGestureMixin extends mai::RenderBox /*isMixinDeclaration*/  {
+  method hitTestSelf(self::Offset position) → core::bool
+    ;
+}
+static method main() → dynamic
+  ;
+
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/crashes/crash_03/main_lib.dart:2:20: Error: Type 'Offset' not found.
+//   bool hitTestSelf(Offset position) => false;
+//                    ^^^^^^
+//
+import self as mai;
+import "dart:core" as core;
+
+abstract class RenderBox extends core::Object {
+  synthetic constructor •() → mai::RenderBox
+    ;
+  method hitTestSelf(invalid-type position) → core::bool
+    ;
+}
diff --git a/pkg/front_end/testcases/general/crashes/crash_03/main.dart.weak.transformed.expect b/pkg/front_end/testcases/general/crashes/crash_03/main.dart.weak.transformed.expect
new file mode 100644
index 0000000..e933f73
--- /dev/null
+++ b/pkg/front_end/testcases/general/crashes/crash_03/main.dart.weak.transformed.expect
@@ -0,0 +1,87 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/crashes/crash_03/main.dart:7:57: Error: Type 'MouseTrackerAnnotation' not found.
+// mixin _PlatformViewGestureMixin on RenderBox implements MouseTrackerAnnotation {
+//                                                         ^^^^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/general/crashes/crash_03/main.dart:9:7: Error: The getter '_hitTestBehavior' isn't defined for the class '_PlatformViewGestureMixin'.
+//  - '_PlatformViewGestureMixin' is from 'pkg/front_end/testcases/general/crashes/crash_03/main.dart'.
+// Try correcting the name to the name of an existing getter, or defining a getter or field named '_hitTestBehavior'.
+//       _hitTestBehavior != PlatformViewHitTestBehavior.transparent;
+//       ^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/general/crashes/crash_03/main.dart:9:27: Error: The getter 'PlatformViewHitTestBehavior' isn't defined for the class '_PlatformViewGestureMixin'.
+//  - '_PlatformViewGestureMixin' is from 'pkg/front_end/testcases/general/crashes/crash_03/main.dart'.
+// Try correcting the name to the name of an existing getter, or defining a getter or field named 'PlatformViewHitTestBehavior'.
+//       _hitTestBehavior != PlatformViewHitTestBehavior.transparent;
+//                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+import "main_lib.dart" as mai;
+
+import "org-dartlang-testcase:///main_lib.dart";
+
+class Offset extends core::Object {
+  synthetic constructor •() → self::Offset
+    : super core::Object::•()
+    ;
+}
+abstract class _PlatformViewRenderBox&RenderBox&_PlatformViewGestureMixin extends mai::RenderBox implements self::_PlatformViewGestureMixin /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_PlatformViewRenderBox&RenderBox&_PlatformViewGestureMixin
+    : super mai::RenderBox::•()
+    ;
+  method hitTestSelf(self::Offset position) → core::bool
+    return !invalid-expression "pkg/front_end/testcases/general/crashes/crash_03/main.dart:9:7: Error: The getter '_hitTestBehavior' isn't defined for the class '_PlatformViewGestureMixin'.
+ - '_PlatformViewGestureMixin' is from 'pkg/front_end/testcases/general/crashes/crash_03/main.dart'.
+Try correcting the name to the name of an existing getter, or defining a getter or field named '_hitTestBehavior'.
+      _hitTestBehavior != PlatformViewHitTestBehavior.transparent;
+      ^^^^^^^^^^^^^^^^".{core::Object::==}(invalid-expression "pkg/front_end/testcases/general/crashes/crash_03/main.dart:9:27: Error: The getter 'PlatformViewHitTestBehavior' isn't defined for the class '_PlatformViewGestureMixin'.
+ - '_PlatformViewGestureMixin' is from 'pkg/front_end/testcases/general/crashes/crash_03/main.dart'.
+Try correcting the name to the name of an existing getter, or defining a getter or field named 'PlatformViewHitTestBehavior'.
+      _hitTestBehavior != PlatformViewHitTestBehavior.transparent;
+                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^".transparent);
+}
+class PlatformViewRenderBox extends self::_PlatformViewRenderBox&RenderBox&_PlatformViewGestureMixin {
+  synthetic constructor •() → self::PlatformViewRenderBox
+    : super self::_PlatformViewRenderBox&RenderBox&_PlatformViewGestureMixin::•()
+    ;
+}
+abstract class _PlatformViewGestureMixin extends mai::RenderBox /*isMixinDeclaration*/  {
+  method hitTestSelf(self::Offset position) → core::bool
+    return !invalid-expression "pkg/front_end/testcases/general/crashes/crash_03/main.dart:9:7: Error: The getter '_hitTestBehavior' isn't defined for the class '_PlatformViewGestureMixin'.
+ - '_PlatformViewGestureMixin' is from 'pkg/front_end/testcases/general/crashes/crash_03/main.dart'.
+Try correcting the name to the name of an existing getter, or defining a getter or field named '_hitTestBehavior'.
+      _hitTestBehavior != PlatformViewHitTestBehavior.transparent;
+      ^^^^^^^^^^^^^^^^".{core::Object::==}(invalid-expression "pkg/front_end/testcases/general/crashes/crash_03/main.dart:9:27: Error: The getter 'PlatformViewHitTestBehavior' isn't defined for the class '_PlatformViewGestureMixin'.
+ - '_PlatformViewGestureMixin' is from 'pkg/front_end/testcases/general/crashes/crash_03/main.dart'.
+Try correcting the name to the name of an existing getter, or defining a getter or field named 'PlatformViewHitTestBehavior'.
+      _hitTestBehavior != PlatformViewHitTestBehavior.transparent;
+                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^".transparent);
+}
+static method main() → dynamic {}
+
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/crashes/crash_03/main_lib.dart:2:20: Error: Type 'Offset' not found.
+//   bool hitTestSelf(Offset position) => false;
+//                    ^^^^^^
+//
+// pkg/front_end/testcases/general/crashes/crash_03/main_lib.dart:2:20: Error: 'Offset' isn't a type.
+//   bool hitTestSelf(Offset position) => false;
+//                    ^^^^^^
+//
+import self as mai;
+import "dart:core" as core;
+
+abstract class RenderBox extends core::Object {
+  synthetic constructor •() → mai::RenderBox
+    : super core::Object::•()
+    ;
+  method hitTestSelf(invalid-type position) → core::bool
+    return false;
+}
diff --git a/pkg/front_end/testcases/general/crashes/crash_03/main_lib.dart b/pkg/front_end/testcases/general/crashes/crash_03/main_lib.dart
new file mode 100644
index 0000000..0c393f3
--- /dev/null
+++ b/pkg/front_end/testcases/general/crashes/crash_03/main_lib.dart
@@ -0,0 +1,3 @@
+abstract class RenderBox {
+  bool hitTestSelf(Offset position) => false;
+}
diff --git a/pkg/front_end/testcases/general/crashes/crash_04/main.dart b/pkg/front_end/testcases/general/crashes/crash_04/main.dart
new file mode 100644
index 0000000..bb75d98
--- /dev/null
+++ b/pkg/front_end/testcases/general/crashes/crash_04/main.dart
@@ -0,0 +1,5 @@
+mixin A<T extends C> on D {}
+
+class B extends D with A {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/crashes/crash_04/main.dart.textual_outline.expect b/pkg/front_end/testcases/general/crashes/crash_04/main.dart.textual_outline.expect
new file mode 100644
index 0000000..bb75d98
--- /dev/null
+++ b/pkg/front_end/testcases/general/crashes/crash_04/main.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+mixin A<T extends C> on D {}
+
+class B extends D with A {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/crashes/crash_04/main.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/crashes/crash_04/main.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..46ccd7b
--- /dev/null
+++ b/pkg/front_end/testcases/general/crashes/crash_04/main.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+class B extends D with A {}
+
+main() {}
+mixin A<T extends C> on D {}
diff --git a/pkg/front_end/testcases/general/crashes/crash_05/main.dart b/pkg/front_end/testcases/general/crashes/crash_05/main.dart
new file mode 100644
index 0000000..56c1217
--- /dev/null
+++ b/pkg/front_end/testcases/general/crashes/crash_05/main.dart
@@ -0,0 +1,12 @@
+import 'main_lib.dart';
+
+class SliverHitTestEntry {}
+
+abstract class RenderSliver {
+  void handleEvent(PointerEvent event, SliverHitTestEntry entry) {}
+}
+
+abstract class RenderSliverSingleBoxAdapter extends RenderSliver
+    with RenderObjectWithChildMixin<RenderBox>, RenderSliverHelpers {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/crashes/crash_05/main.dart.textual_outline.expect b/pkg/front_end/testcases/general/crashes/crash_05/main.dart.textual_outline.expect
new file mode 100644
index 0000000..56c1217
--- /dev/null
+++ b/pkg/front_end/testcases/general/crashes/crash_05/main.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+import 'main_lib.dart';
+
+class SliverHitTestEntry {}
+
+abstract class RenderSliver {
+  void handleEvent(PointerEvent event, SliverHitTestEntry entry) {}
+}
+
+abstract class RenderSliverSingleBoxAdapter extends RenderSliver
+    with RenderObjectWithChildMixin<RenderBox>, RenderSliverHelpers {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/crashes/crash_05/main.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/crashes/crash_05/main.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f19ec08
--- /dev/null
+++ b/pkg/front_end/testcases/general/crashes/crash_05/main.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+import 'main_lib.dart';
+
+abstract class RenderSliver {
+  void handleEvent(PointerEvent event, SliverHitTestEntry entry) {}
+}
+
+abstract class RenderSliverSingleBoxAdapter extends RenderSliver
+    with RenderObjectWithChildMixin<RenderBox>, RenderSliverHelpers {}
+
+class SliverHitTestEntry {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/crashes/crash_05/main.dart.weak.expect b/pkg/front_end/testcases/general/crashes/crash_05/main.dart.weak.expect
new file mode 100644
index 0000000..cd6f676
--- /dev/null
+++ b/pkg/front_end/testcases/general/crashes/crash_05/main.dart.weak.expect
@@ -0,0 +1,98 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/crashes/crash_05/main.dart:6:20: Error: Type 'PointerEvent' not found.
+//   void handleEvent(PointerEvent event, SliverHitTestEntry entry) {}
+//                    ^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/general/crashes/crash_05/main.dart:10:37: Error: Type 'RenderBox' not found.
+//     with RenderObjectWithChildMixin<RenderBox>, RenderSliverHelpers {}
+//                                     ^^^^^^^^^
+//
+// pkg/front_end/testcases/general/crashes/crash_05/main.dart:10:49: Error: Type 'RenderSliverHelpers' not found.
+//     with RenderObjectWithChildMixin<RenderBox>, RenderSliverHelpers {}
+//                                                 ^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/general/crashes/crash_05/main.dart:9:16: Error: The type 'RenderSliverHelpers' can't be mixed in.
+// abstract class RenderSliverSingleBoxAdapter extends RenderSliver
+//                ^
+//
+// pkg/front_end/testcases/general/crashes/crash_05/main.dart:9:16: Error: 'RenderSliver' doesn't implement 'RenderObject' so it can't be used with 'RenderObjectWithChildMixin<invalid-type>'.
+//  - 'RenderSliver' is from 'pkg/front_end/testcases/general/crashes/crash_05/main.dart'.
+//  - 'RenderObject' is from 'pkg/front_end/testcases/general/crashes/crash_05/main_lib.dart'.
+//  - 'RenderObjectWithChildMixin' is from 'pkg/front_end/testcases/general/crashes/crash_05/main_lib.dart'.
+// abstract class RenderSliverSingleBoxAdapter extends RenderSliver
+//                ^
+//
+// pkg/front_end/testcases/general/crashes/crash_05/main.dart:6:20: Error: 'PointerEvent' isn't a type.
+//   void handleEvent(PointerEvent event, SliverHitTestEntry entry) {}
+//                    ^^^^^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+import "main_lib.dart" as mai;
+
+import "org-dartlang-testcase:///main_lib.dart";
+
+class SliverHitTestEntry extends core::Object {
+  synthetic constructor •() → self::SliverHitTestEntry
+    : super core::Object::•()
+    ;
+}
+abstract class RenderSliver extends core::Object {
+  synthetic constructor •() → self::RenderSliver
+    : super core::Object::•()
+    ;
+  method handleEvent(invalid-type event, self::SliverHitTestEntry entry) → void {}
+}
+abstract class _RenderSliverSingleBoxAdapter&RenderSliver&RenderObjectWithChildMixin = self::RenderSliver with mai::RenderObjectWithChildMixin<invalid-type> /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_RenderSliverSingleBoxAdapter&RenderSliver&RenderObjectWithChildMixin
+    : super self::RenderSliver::•()
+    ;
+  forwarding-stub method handleEvent(invalid-type event, covariant invalid-type entry) → void
+    return super.{self::RenderSliver::handleEvent}(event, entry);
+}
+abstract class _RenderSliverSingleBoxAdapter&RenderSliver&RenderObjectWithChildMixin&RenderSliverHelpers extends self::_RenderSliverSingleBoxAdapter&RenderSliver&RenderObjectWithChildMixin /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_RenderSliverSingleBoxAdapter&RenderSliver&RenderObjectWithChildMixin&RenderSliverHelpers
+    : super self::_RenderSliverSingleBoxAdapter&RenderSliver&RenderObjectWithChildMixin::•()
+    ;
+}
+abstract class RenderSliverSingleBoxAdapter extends self::_RenderSliverSingleBoxAdapter&RenderSliver&RenderObjectWithChildMixin&RenderSliverHelpers {
+  synthetic constructor •() → self::RenderSliverSingleBoxAdapter
+    : super self::_RenderSliverSingleBoxAdapter&RenderSliver&RenderObjectWithChildMixin&RenderSliverHelpers::•()
+    ;
+}
+static method main() → dynamic {}
+
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/crashes/crash_05/main_lib.dart:2:20: Error: Type 'PointerEvent' not found.
+//   void handleEvent(PointerEvent event, covariant HitTestEntry entry) {}
+//                    ^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/general/crashes/crash_05/main_lib.dart:2:50: Error: Type 'HitTestEntry' not found.
+//   void handleEvent(PointerEvent event, covariant HitTestEntry entry) {}
+//                                                  ^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/general/crashes/crash_05/main_lib.dart:2:20: Error: 'PointerEvent' isn't a type.
+//   void handleEvent(PointerEvent event, covariant HitTestEntry entry) {}
+//                    ^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/general/crashes/crash_05/main_lib.dart:2:50: Error: 'HitTestEntry' isn't a type.
+//   void handleEvent(PointerEvent event, covariant HitTestEntry entry) {}
+//                                                  ^^^^^^^^^^^^
+//
+import self as mai;
+import "dart:core" as core;
+
+abstract class RenderObject extends core::Object {
+  synthetic constructor •() → mai::RenderObject
+    : super core::Object::•()
+    ;
+  method handleEvent(invalid-type event, covariant invalid-type entry) → void {}
+}
+abstract class RenderObjectWithChildMixin<ChildType extends mai::RenderObject = mai::RenderObject> extends mai::RenderObject /*isMixinDeclaration*/  {
+}
diff --git a/pkg/front_end/testcases/general/crashes/crash_05/main.dart.weak.outline.expect b/pkg/front_end/testcases/general/crashes/crash_05/main.dart.weak.outline.expect
new file mode 100644
index 0000000..db57999
--- /dev/null
+++ b/pkg/front_end/testcases/general/crashes/crash_05/main.dart.weak.outline.expect
@@ -0,0 +1,85 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/crashes/crash_05/main.dart:6:20: Error: Type 'PointerEvent' not found.
+//   void handleEvent(PointerEvent event, SliverHitTestEntry entry) {}
+//                    ^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/general/crashes/crash_05/main.dart:10:37: Error: Type 'RenderBox' not found.
+//     with RenderObjectWithChildMixin<RenderBox>, RenderSliverHelpers {}
+//                                     ^^^^^^^^^
+//
+// pkg/front_end/testcases/general/crashes/crash_05/main.dart:10:49: Error: Type 'RenderSliverHelpers' not found.
+//     with RenderObjectWithChildMixin<RenderBox>, RenderSliverHelpers {}
+//                                                 ^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/general/crashes/crash_05/main.dart:9:16: Error: The type 'RenderSliverHelpers' can't be mixed in.
+// abstract class RenderSliverSingleBoxAdapter extends RenderSliver
+//                ^
+//
+// pkg/front_end/testcases/general/crashes/crash_05/main.dart:9:16: Error: 'RenderSliver' doesn't implement 'RenderObject' so it can't be used with 'RenderObjectWithChildMixin<invalid-type>'.
+//  - 'RenderSliver' is from 'pkg/front_end/testcases/general/crashes/crash_05/main.dart'.
+//  - 'RenderObject' is from 'pkg/front_end/testcases/general/crashes/crash_05/main_lib.dart'.
+//  - 'RenderObjectWithChildMixin' is from 'pkg/front_end/testcases/general/crashes/crash_05/main_lib.dart'.
+// abstract class RenderSliverSingleBoxAdapter extends RenderSliver
+//                ^
+//
+import self as self;
+import "dart:core" as core;
+import "main_lib.dart" as mai;
+
+import "org-dartlang-testcase:///main_lib.dart";
+
+class SliverHitTestEntry extends core::Object {
+  synthetic constructor •() → self::SliverHitTestEntry
+    ;
+}
+abstract class RenderSliver extends core::Object {
+  synthetic constructor •() → self::RenderSliver
+    ;
+  method handleEvent(invalid-type event, self::SliverHitTestEntry entry) → void
+    ;
+}
+abstract class _RenderSliverSingleBoxAdapter&RenderSliver&RenderObjectWithChildMixin = self::RenderSliver with mai::RenderObjectWithChildMixin<invalid-type> /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_RenderSliverSingleBoxAdapter&RenderSliver&RenderObjectWithChildMixin
+    : super self::RenderSliver::•()
+    ;
+  forwarding-stub method handleEvent(invalid-type event, covariant invalid-type entry) → void
+    return super.{self::RenderSliver::handleEvent}(event, entry);
+}
+abstract class _RenderSliverSingleBoxAdapter&RenderSliver&RenderObjectWithChildMixin&RenderSliverHelpers extends self::_RenderSliverSingleBoxAdapter&RenderSliver&RenderObjectWithChildMixin /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_RenderSliverSingleBoxAdapter&RenderSliver&RenderObjectWithChildMixin&RenderSliverHelpers
+    : super self::_RenderSliverSingleBoxAdapter&RenderSliver&RenderObjectWithChildMixin::•()
+    ;
+}
+abstract class RenderSliverSingleBoxAdapter extends self::_RenderSliverSingleBoxAdapter&RenderSliver&RenderObjectWithChildMixin&RenderSliverHelpers {
+  synthetic constructor •() → self::RenderSliverSingleBoxAdapter
+    ;
+}
+static method main() → dynamic
+  ;
+
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/crashes/crash_05/main_lib.dart:2:20: Error: Type 'PointerEvent' not found.
+//   void handleEvent(PointerEvent event, covariant HitTestEntry entry) {}
+//                    ^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/general/crashes/crash_05/main_lib.dart:2:50: Error: Type 'HitTestEntry' not found.
+//   void handleEvent(PointerEvent event, covariant HitTestEntry entry) {}
+//                                                  ^^^^^^^^^^^^
+//
+import self as mai;
+import "dart:core" as core;
+
+abstract class RenderObject extends core::Object {
+  synthetic constructor •() → mai::RenderObject
+    ;
+  method handleEvent(invalid-type event, covariant invalid-type entry) → void
+    ;
+}
+abstract class RenderObjectWithChildMixin<ChildType extends mai::RenderObject = mai::RenderObject> extends mai::RenderObject /*isMixinDeclaration*/  {
+}
diff --git a/pkg/front_end/testcases/general/crashes/crash_05/main.dart.weak.transformed.expect b/pkg/front_end/testcases/general/crashes/crash_05/main.dart.weak.transformed.expect
new file mode 100644
index 0000000..6019bb4
--- /dev/null
+++ b/pkg/front_end/testcases/general/crashes/crash_05/main.dart.weak.transformed.expect
@@ -0,0 +1,98 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/crashes/crash_05/main.dart:6:20: Error: Type 'PointerEvent' not found.
+//   void handleEvent(PointerEvent event, SliverHitTestEntry entry) {}
+//                    ^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/general/crashes/crash_05/main.dart:10:37: Error: Type 'RenderBox' not found.
+//     with RenderObjectWithChildMixin<RenderBox>, RenderSliverHelpers {}
+//                                     ^^^^^^^^^
+//
+// pkg/front_end/testcases/general/crashes/crash_05/main.dart:10:49: Error: Type 'RenderSliverHelpers' not found.
+//     with RenderObjectWithChildMixin<RenderBox>, RenderSliverHelpers {}
+//                                                 ^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/general/crashes/crash_05/main.dart:9:16: Error: The type 'RenderSliverHelpers' can't be mixed in.
+// abstract class RenderSliverSingleBoxAdapter extends RenderSliver
+//                ^
+//
+// pkg/front_end/testcases/general/crashes/crash_05/main.dart:9:16: Error: 'RenderSliver' doesn't implement 'RenderObject' so it can't be used with 'RenderObjectWithChildMixin<invalid-type>'.
+//  - 'RenderSliver' is from 'pkg/front_end/testcases/general/crashes/crash_05/main.dart'.
+//  - 'RenderObject' is from 'pkg/front_end/testcases/general/crashes/crash_05/main_lib.dart'.
+//  - 'RenderObjectWithChildMixin' is from 'pkg/front_end/testcases/general/crashes/crash_05/main_lib.dart'.
+// abstract class RenderSliverSingleBoxAdapter extends RenderSliver
+//                ^
+//
+// pkg/front_end/testcases/general/crashes/crash_05/main.dart:6:20: Error: 'PointerEvent' isn't a type.
+//   void handleEvent(PointerEvent event, SliverHitTestEntry entry) {}
+//                    ^^^^^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+import "main_lib.dart" as mai;
+
+import "org-dartlang-testcase:///main_lib.dart";
+
+class SliverHitTestEntry extends core::Object {
+  synthetic constructor •() → self::SliverHitTestEntry
+    : super core::Object::•()
+    ;
+}
+abstract class RenderSliver extends core::Object {
+  synthetic constructor •() → self::RenderSliver
+    : super core::Object::•()
+    ;
+  method handleEvent(invalid-type event, self::SliverHitTestEntry entry) → void {}
+}
+abstract class _RenderSliverSingleBoxAdapter&RenderSliver&RenderObjectWithChildMixin extends self::RenderSliver implements mai::RenderObjectWithChildMixin<invalid-type> /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_RenderSliverSingleBoxAdapter&RenderSliver&RenderObjectWithChildMixin
+    : super self::RenderSliver::•()
+    ;
+  forwarding-stub method handleEvent(invalid-type event, covariant invalid-type entry) → void
+    return super.{self::RenderSliver::handleEvent}(event, entry);
+}
+abstract class _RenderSliverSingleBoxAdapter&RenderSliver&RenderObjectWithChildMixin&RenderSliverHelpers extends self::_RenderSliverSingleBoxAdapter&RenderSliver&RenderObjectWithChildMixin /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_RenderSliverSingleBoxAdapter&RenderSliver&RenderObjectWithChildMixin&RenderSliverHelpers
+    : super self::_RenderSliverSingleBoxAdapter&RenderSliver&RenderObjectWithChildMixin::•()
+    ;
+}
+abstract class RenderSliverSingleBoxAdapter extends self::_RenderSliverSingleBoxAdapter&RenderSliver&RenderObjectWithChildMixin&RenderSliverHelpers {
+  synthetic constructor •() → self::RenderSliverSingleBoxAdapter
+    : super self::_RenderSliverSingleBoxAdapter&RenderSliver&RenderObjectWithChildMixin&RenderSliverHelpers::•()
+    ;
+}
+static method main() → dynamic {}
+
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/crashes/crash_05/main_lib.dart:2:20: Error: Type 'PointerEvent' not found.
+//   void handleEvent(PointerEvent event, covariant HitTestEntry entry) {}
+//                    ^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/general/crashes/crash_05/main_lib.dart:2:50: Error: Type 'HitTestEntry' not found.
+//   void handleEvent(PointerEvent event, covariant HitTestEntry entry) {}
+//                                                  ^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/general/crashes/crash_05/main_lib.dart:2:20: Error: 'PointerEvent' isn't a type.
+//   void handleEvent(PointerEvent event, covariant HitTestEntry entry) {}
+//                    ^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/general/crashes/crash_05/main_lib.dart:2:50: Error: 'HitTestEntry' isn't a type.
+//   void handleEvent(PointerEvent event, covariant HitTestEntry entry) {}
+//                                                  ^^^^^^^^^^^^
+//
+import self as mai;
+import "dart:core" as core;
+
+abstract class RenderObject extends core::Object {
+  synthetic constructor •() → mai::RenderObject
+    : super core::Object::•()
+    ;
+  method handleEvent(invalid-type event, covariant invalid-type entry) → void {}
+}
+abstract class RenderObjectWithChildMixin<ChildType extends mai::RenderObject = mai::RenderObject> extends mai::RenderObject /*isMixinDeclaration*/  {
+}
diff --git a/pkg/front_end/testcases/general/crashes/crash_05/main_lib.dart b/pkg/front_end/testcases/general/crashes/crash_05/main_lib.dart
new file mode 100644
index 0000000..46763cf
--- /dev/null
+++ b/pkg/front_end/testcases/general/crashes/crash_05/main_lib.dart
@@ -0,0 +1,6 @@
+abstract class RenderObject {
+  void handleEvent(PointerEvent event, covariant HitTestEntry entry) {}
+}
+
+mixin RenderObjectWithChildMixin<ChildType extends RenderObject>
+    on RenderObject {}
diff --git a/pkg/front_end/testcases/general/duplicate_typedef.dart b/pkg/front_end/testcases/general/duplicate_typedef.dart
new file mode 100644
index 0000000..3c409c7
--- /dev/null
+++ b/pkg/front_end/testcases/general/duplicate_typedef.dart
@@ -0,0 +1,11 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+typedef F = void Function();
+typedef F = void Function();
+
+typedef G<T> = void Function(T);
+typedef G<T> = void Function(T);
+
+main() {}
diff --git a/pkg/front_end/testcases/general/duplicate_typedef.dart.textual_outline.expect b/pkg/front_end/testcases/general/duplicate_typedef.dart.textual_outline.expect
new file mode 100644
index 0000000..6552461
--- /dev/null
+++ b/pkg/front_end/testcases/general/duplicate_typedef.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+typedef F = void Function();
+typedef F = void Function();
+typedef G<T> = void Function(T);
+typedef G<T> = void Function(T);
+main() {}
diff --git a/pkg/front_end/testcases/general/duplicate_typedef.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/duplicate_typedef.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..916f4b4
--- /dev/null
+++ b/pkg/front_end/testcases/general/duplicate_typedef.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+main() {}
+typedef F = void Function();
+typedef F = void Function();
+typedef G<T> = void Function(T);
+typedef G<T> = void Function(T);
diff --git a/pkg/front_end/testcases/general/duplicate_typedef.dart.weak.expect b/pkg/front_end/testcases/general/duplicate_typedef.dart.weak.expect
new file mode 100644
index 0000000..6428f44
--- /dev/null
+++ b/pkg/front_end/testcases/general/duplicate_typedef.dart.weak.expect
@@ -0,0 +1,24 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/duplicate_typedef.dart:6:9: Error: 'F' is already declared in this scope.
+// typedef F = void Function();
+//         ^
+// pkg/front_end/testcases/general/duplicate_typedef.dart:5:9: Context: Previous declaration of 'F'.
+// typedef F = void Function();
+//         ^
+//
+// pkg/front_end/testcases/general/duplicate_typedef.dart:9:9: Error: 'G' is already declared in this scope.
+// typedef G<T> = void Function(T);
+//         ^
+// pkg/front_end/testcases/general/duplicate_typedef.dart:8:9: Context: Previous declaration of 'G'.
+// typedef G<T> = void Function(T);
+//         ^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef F = () → void;
+typedef G<contravariant T extends core::Object? = dynamic> = (T%) → void;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general/duplicate_typedef.dart.weak.outline.expect b/pkg/front_end/testcases/general/duplicate_typedef.dart.weak.outline.expect
new file mode 100644
index 0000000..1247e17
--- /dev/null
+++ b/pkg/front_end/testcases/general/duplicate_typedef.dart.weak.outline.expect
@@ -0,0 +1,25 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/duplicate_typedef.dart:6:9: Error: 'F' is already declared in this scope.
+// typedef F = void Function();
+//         ^
+// pkg/front_end/testcases/general/duplicate_typedef.dart:5:9: Context: Previous declaration of 'F'.
+// typedef F = void Function();
+//         ^
+//
+// pkg/front_end/testcases/general/duplicate_typedef.dart:9:9: Error: 'G' is already declared in this scope.
+// typedef G<T> = void Function(T);
+//         ^
+// pkg/front_end/testcases/general/duplicate_typedef.dart:8:9: Context: Previous declaration of 'G'.
+// typedef G<T> = void Function(T);
+//         ^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef F = () → void;
+typedef G<contravariant T extends core::Object? = dynamic> = (T%) → void;
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/general/duplicate_typedef.dart.weak.transformed.expect b/pkg/front_end/testcases/general/duplicate_typedef.dart.weak.transformed.expect
new file mode 100644
index 0000000..6428f44
--- /dev/null
+++ b/pkg/front_end/testcases/general/duplicate_typedef.dart.weak.transformed.expect
@@ -0,0 +1,24 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/duplicate_typedef.dart:6:9: Error: 'F' is already declared in this scope.
+// typedef F = void Function();
+//         ^
+// pkg/front_end/testcases/general/duplicate_typedef.dart:5:9: Context: Previous declaration of 'F'.
+// typedef F = void Function();
+//         ^
+//
+// pkg/front_end/testcases/general/duplicate_typedef.dart:9:9: Error: 'G' is already declared in this scope.
+// typedef G<T> = void Function(T);
+//         ^
+// pkg/front_end/testcases/general/duplicate_typedef.dart:8:9: Context: Previous declaration of 'G'.
+// typedef G<T> = void Function(T);
+//         ^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef F = () → void;
+typedef G<contravariant T extends core::Object? = dynamic> = (T%) → void;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general/duplicated_bad_prefix.dart b/pkg/front_end/testcases/general/duplicated_bad_prefix.dart
index bd5afe3..06ff79b 100644
--- a/pkg/front_end/testcases/general/duplicated_bad_prefix.dart
+++ b/pkg/front_end/testcases/general/duplicated_bad_prefix.dart
@@ -1,7 +1,9 @@
 // Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
+
 // @dart=2.9
+
 import 'duplicated_bad_prefix_lib1.dart' as dupe;
 import 'duplicated_bad_prefix_lib2.dart' as dupe;
 
diff --git a/pkg/front_end/testcases/general/duplicated_bad_prefix.dart.weak.expect b/pkg/front_end/testcases/general/duplicated_bad_prefix.dart.weak.expect
index 44ea56a..c5b39f8 100644
--- a/pkg/front_end/testcases/general/duplicated_bad_prefix.dart.weak.expect
+++ b/pkg/front_end/testcases/general/duplicated_bad_prefix.dart.weak.expect
@@ -2,22 +2,22 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/general/duplicated_bad_prefix.dart:10:7: Error: 'Dupe' is already declared in this scope.
+// pkg/front_end/testcases/general/duplicated_bad_prefix.dart:12:7: Error: 'Dupe' is already declared in this scope.
 // class Dupe {}
 //       ^^^^
-// pkg/front_end/testcases/general/duplicated_bad_prefix.dart:8:7: Context: Previous declaration of 'Dupe'.
+// pkg/front_end/testcases/general/duplicated_bad_prefix.dart:10:7: Context: Previous declaration of 'Dupe'.
 // class Dupe {}
 //       ^^^^
 //
-// pkg/front_end/testcases/general/duplicated_bad_prefix.dart:13:3: Error: Type 'Dupe.a' not found.
+// pkg/front_end/testcases/general/duplicated_bad_prefix.dart:15:3: Error: Type 'Dupe.a' not found.
 //   Dupe.a b;
 //   ^^^^^^
 //
-// pkg/front_end/testcases/general/duplicated_bad_prefix.dart:6:45: Error: 'C' is imported from both 'pkg/front_end/testcases/general/duplicated_bad_prefix_lib1.dart' and 'pkg/front_end/testcases/general/duplicated_bad_prefix_lib2.dart'.
+// pkg/front_end/testcases/general/duplicated_bad_prefix.dart:8:45: Error: 'C' is imported from both 'pkg/front_end/testcases/general/duplicated_bad_prefix_lib1.dart' and 'pkg/front_end/testcases/general/duplicated_bad_prefix_lib2.dart'.
 // import 'duplicated_bad_prefix_lib2.dart' as dupe;
 //                                             ^
 //
-// pkg/front_end/testcases/general/duplicated_bad_prefix.dart:13:3: Error: 'Dupe.a' isn't a type.
+// pkg/front_end/testcases/general/duplicated_bad_prefix.dart:15:3: Error: 'Dupe.a' isn't a type.
 //   Dupe.a b;
 //   ^^^^^^
 //
diff --git a/pkg/front_end/testcases/general/duplicated_bad_prefix.dart.weak.outline.expect b/pkg/front_end/testcases/general/duplicated_bad_prefix.dart.weak.outline.expect
index 4f7744f..5531431 100644
--- a/pkg/front_end/testcases/general/duplicated_bad_prefix.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/general/duplicated_bad_prefix.dart.weak.outline.expect
@@ -2,18 +2,18 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/general/duplicated_bad_prefix.dart:10:7: Error: 'Dupe' is already declared in this scope.
+// pkg/front_end/testcases/general/duplicated_bad_prefix.dart:12:7: Error: 'Dupe' is already declared in this scope.
 // class Dupe {}
 //       ^^^^
-// pkg/front_end/testcases/general/duplicated_bad_prefix.dart:8:7: Context: Previous declaration of 'Dupe'.
+// pkg/front_end/testcases/general/duplicated_bad_prefix.dart:10:7: Context: Previous declaration of 'Dupe'.
 // class Dupe {}
 //       ^^^^
 //
-// pkg/front_end/testcases/general/duplicated_bad_prefix.dart:13:3: Error: Type 'Dupe.a' not found.
+// pkg/front_end/testcases/general/duplicated_bad_prefix.dart:15:3: Error: Type 'Dupe.a' not found.
 //   Dupe.a b;
 //   ^^^^^^
 //
-// pkg/front_end/testcases/general/duplicated_bad_prefix.dart:6:45: Error: 'C' is imported from both 'pkg/front_end/testcases/general/duplicated_bad_prefix_lib1.dart' and 'pkg/front_end/testcases/general/duplicated_bad_prefix_lib2.dart'.
+// pkg/front_end/testcases/general/duplicated_bad_prefix.dart:8:45: Error: 'C' is imported from both 'pkg/front_end/testcases/general/duplicated_bad_prefix_lib1.dart' and 'pkg/front_end/testcases/general/duplicated_bad_prefix_lib2.dart'.
 // import 'duplicated_bad_prefix_lib2.dart' as dupe;
 //                                             ^
 //
diff --git a/pkg/front_end/testcases/general/duplicated_bad_prefix.dart.weak.transformed.expect b/pkg/front_end/testcases/general/duplicated_bad_prefix.dart.weak.transformed.expect
index 44ea56a..c5b39f8 100644
--- a/pkg/front_end/testcases/general/duplicated_bad_prefix.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general/duplicated_bad_prefix.dart.weak.transformed.expect
@@ -2,22 +2,22 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/general/duplicated_bad_prefix.dart:10:7: Error: 'Dupe' is already declared in this scope.
+// pkg/front_end/testcases/general/duplicated_bad_prefix.dart:12:7: Error: 'Dupe' is already declared in this scope.
 // class Dupe {}
 //       ^^^^
-// pkg/front_end/testcases/general/duplicated_bad_prefix.dart:8:7: Context: Previous declaration of 'Dupe'.
+// pkg/front_end/testcases/general/duplicated_bad_prefix.dart:10:7: Context: Previous declaration of 'Dupe'.
 // class Dupe {}
 //       ^^^^
 //
-// pkg/front_end/testcases/general/duplicated_bad_prefix.dart:13:3: Error: Type 'Dupe.a' not found.
+// pkg/front_end/testcases/general/duplicated_bad_prefix.dart:15:3: Error: Type 'Dupe.a' not found.
 //   Dupe.a b;
 //   ^^^^^^
 //
-// pkg/front_end/testcases/general/duplicated_bad_prefix.dart:6:45: Error: 'C' is imported from both 'pkg/front_end/testcases/general/duplicated_bad_prefix_lib1.dart' and 'pkg/front_end/testcases/general/duplicated_bad_prefix_lib2.dart'.
+// pkg/front_end/testcases/general/duplicated_bad_prefix.dart:8:45: Error: 'C' is imported from both 'pkg/front_end/testcases/general/duplicated_bad_prefix_lib1.dart' and 'pkg/front_end/testcases/general/duplicated_bad_prefix_lib2.dart'.
 // import 'duplicated_bad_prefix_lib2.dart' as dupe;
 //                                             ^
 //
-// pkg/front_end/testcases/general/duplicated_bad_prefix.dart:13:3: Error: 'Dupe.a' isn't a type.
+// pkg/front_end/testcases/general/duplicated_bad_prefix.dart:15:3: Error: 'Dupe.a' isn't a type.
 //   Dupe.a b;
 //   ^^^^^^
 //
diff --git a/pkg/front_end/testcases/general/extension_annotation.dart b/pkg/front_end/testcases/general/extension_annotation.dart
new file mode 100644
index 0000000..5e32514
--- /dev/null
+++ b/pkg/front_end/testcases/general/extension_annotation.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class A {
+  const A();
+}
+
+@A()
+extension Extension on int {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/extension_annotation.dart.textual_outline.expect b/pkg/front_end/testcases/general/extension_annotation.dart.textual_outline.expect
new file mode 100644
index 0000000..35443c8
--- /dev/null
+++ b/pkg/front_end/testcases/general/extension_annotation.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+class A {
+  const A();
+}
+
+@A()
+extension Extension on int {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/extension_annotation.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/extension_annotation.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..35443c8
--- /dev/null
+++ b/pkg/front_end/testcases/general/extension_annotation.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+class A {
+  const A();
+}
+
+@A()
+extension Extension on int {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/extension_annotation.dart.weak.expect b/pkg/front_end/testcases/general/extension_annotation.dart.weak.expect
new file mode 100644
index 0000000..d44af16
--- /dev/null
+++ b/pkg/front_end/testcases/general/extension_annotation.dart.weak.expect
@@ -0,0 +1,23 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object /*hasConstConstructor*/  {
+  const constructor •() → self::A
+    : super core::Object::•()
+    ;
+}
+@#C1
+extension Extension on core::int {
+}
+static method main() → dynamic {}
+
+constants  {
+  #C1 = self::A {}
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///extension_annotation.dart:
+- A. (from org-dartlang-testcase:///extension_annotation.dart:6:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/general/extension_annotation.dart.weak.outline.expect b/pkg/front_end/testcases/general/extension_annotation.dart.weak.outline.expect
new file mode 100644
index 0000000..3a68e58
--- /dev/null
+++ b/pkg/front_end/testcases/general/extension_annotation.dart.weak.outline.expect
@@ -0,0 +1,14 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object /*hasConstConstructor*/  {
+  const constructor •() → self::A
+    : super core::Object::•()
+    ;
+}
+@self::A::•()
+extension Extension on core::int {
+}
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/general/extension_annotation.dart.weak.transformed.expect b/pkg/front_end/testcases/general/extension_annotation.dart.weak.transformed.expect
new file mode 100644
index 0000000..d44af16
--- /dev/null
+++ b/pkg/front_end/testcases/general/extension_annotation.dart.weak.transformed.expect
@@ -0,0 +1,23 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object /*hasConstConstructor*/  {
+  const constructor •() → self::A
+    : super core::Object::•()
+    ;
+}
+@#C1
+extension Extension on core::int {
+}
+static method main() → dynamic {}
+
+constants  {
+  #C1 = self::A {}
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///extension_annotation.dart:
+- A. (from org-dartlang-testcase:///extension_annotation.dart:6:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/general/ffi_sample.dart.weak.transformed.expect b/pkg/front_end/testcases/general/ffi_sample.dart.weak.transformed.expect
index eefcad1..4e3bcdc 100644
--- a/pkg/front_end/testcases/general/ffi_sample.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general/ffi_sample.dart.weak.transformed.expect
@@ -6,9 +6,9 @@
 import "dart:ffi";
 import "package:ffi/ffi.dart";
 
-@#C6
+@#C7
 class Coordinate extends ffi::Struct {
-  static final field core::int* #sizeOf = (#C9).{core::List::[]}(ffi::_abi());
+  static final field core::int* #sizeOf = (#C10).{core::List::[]}(ffi::_abi());
   @#C12
   constructor #fromTypedDataBase(dynamic #pointer) → dynamic
     : super ffi::Struct::_fromPointer(#pointer)
@@ -51,14 +51,14 @@
   #C2 = TypeLiteralConstant(ffi::Double)
   #C3 = TypeLiteralConstant(ffi::Pointer<ffi::NativeType>)
   #C4 = <core::Type>[#C2, #C2, #C3]
-  #C5 = ffi::_FfiStructLayout {fieldTypes:#C4}
-  #C6 = core::pragma {name:#C1, options:#C5}
-  #C7 = 24
-  #C8 = 20
-  #C9 = <core::int*>[#C7, #C8, #C7]
-  #C10 = "vm:entry-point"
-  #C11 = null
-  #C12 = core::pragma {name:#C10, options:#C11}
+  #C5 = null
+  #C6 = ffi::_FfiStructLayout {fieldTypes:#C4, packing:#C5}
+  #C7 = core::pragma {name:#C1, options:#C6}
+  #C8 = 24
+  #C9 = 20
+  #C10 = <core::int*>[#C8, #C9, #C8]
+  #C11 = "vm:entry-point"
+  #C12 = core::pragma {name:#C11, options:#C5}
   #C13 = 0
   #C14 = <core::int*>[#C13, #C13, #C13]
   #C15 = 8
diff --git a/pkg/front_end/testcases/general/function_invocation_bounds.dart b/pkg/front_end/testcases/general/function_invocation_bounds.dart
new file mode 100644
index 0000000..5e01a3a
--- /dev/null
+++ b/pkg/front_end/testcases/general/function_invocation_bounds.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+typedef T G<T>(T t);
+
+test() {
+  T local<T extends num>(T t) => t;
+  local("");
+  local<String>(throw '');
+  local(0);
+  local<int>(throw '');
+  local<int, String>(throw '');
+  var f = local;
+  f("");
+  f<String>(throw '');
+  f(0);
+  f<int>(throw '');
+  f<int, String>(throw '');
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/function_invocation_bounds.dart.textual_outline.expect b/pkg/front_end/testcases/general/function_invocation_bounds.dart.textual_outline.expect
new file mode 100644
index 0000000..4eb293e
--- /dev/null
+++ b/pkg/front_end/testcases/general/function_invocation_bounds.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+typedef T G<T>(T t);
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/general/function_invocation_bounds.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/function_invocation_bounds.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6ff567c
--- /dev/null
+++ b/pkg/front_end/testcases/general/function_invocation_bounds.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+main() {}
+test() {}
+typedef T G<T>(T t);
diff --git a/pkg/front_end/testcases/general/function_invocation_bounds.dart.weak.expect b/pkg/front_end/testcases/general/function_invocation_bounds.dart.weak.expect
new file mode 100644
index 0000000..ea6f457
--- /dev/null
+++ b/pkg/front_end/testcases/general/function_invocation_bounds.dart.weak.expect
@@ -0,0 +1,56 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/function_invocation_bounds.dart:9:8: Error: Inferred type argument 'String' doesn't conform to the bound 'num' of the type variable 'T' on 'local'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//   local("");
+//        ^
+//
+// pkg/front_end/testcases/general/function_invocation_bounds.dart:10:8: Error: Type argument 'String' doesn't conform to the bound 'num' of the type variable 'T' on 'local'.
+// Try changing type arguments so that they conform to the bounds.
+//   local<String>(throw '');
+//        ^
+//
+// pkg/front_end/testcases/general/function_invocation_bounds.dart:13:8: Error: Expected 1 type arguments.
+//   local<int, String>(throw '');
+//        ^
+//
+// pkg/front_end/testcases/general/function_invocation_bounds.dart:15:4: Error: Inferred type argument 'String' doesn't conform to the bound 'num' of the type variable 'T' on 'call'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//   f("");
+//    ^
+//
+// pkg/front_end/testcases/general/function_invocation_bounds.dart:16:4: Error: Type argument 'String' doesn't conform to the bound 'num' of the type variable 'T' on 'call'.
+// Try changing type arguments so that they conform to the bounds.
+//   f<String>(throw '');
+//    ^
+//
+// pkg/front_end/testcases/general/function_invocation_bounds.dart:19:4: Error: Expected 1 type arguments.
+//   f<int, String>(throw '');
+//    ^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef G<invariant T extends core::Object? = dynamic> = (T%) → T%;
+static method test() → dynamic {
+  function local<T extends core::num = core::num>(T t) → T
+    return t;
+  local.call<core::String>("");
+  local.call<core::String>(throw "");
+  local.call<core::int>(0);
+  local.call<core::int>(throw "");
+  let final Never #t1 = invalid-expression "pkg/front_end/testcases/general/function_invocation_bounds.dart:13:8: Error: Expected 1 type arguments.
+  local<int, String>(throw '');
+       ^" in local.call<core::int, core::String>(throw "");
+  <T extends core::num = core::num>(T) → T f = local;
+  f.call<core::String>("");
+  f.call<core::String>(throw "");
+  f.call<core::int>(0);
+  f.call<core::int>(throw "");
+  let final Never #t2 = invalid-expression "pkg/front_end/testcases/general/function_invocation_bounds.dart:19:4: Error: Expected 1 type arguments.
+  f<int, String>(throw '');
+   ^" in f.call<core::int, core::String>(throw "");
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general/function_invocation_bounds.dart.weak.outline.expect b/pkg/front_end/testcases/general/function_invocation_bounds.dart.weak.outline.expect
new file mode 100644
index 0000000..b663e0a
--- /dev/null
+++ b/pkg/front_end/testcases/general/function_invocation_bounds.dart.weak.outline.expect
@@ -0,0 +1,9 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+typedef G<invariant T extends core::Object? = dynamic> = (T%) → T%;
+static method test() → dynamic
+  ;
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/general/function_invocation_bounds.dart.weak.transformed.expect b/pkg/front_end/testcases/general/function_invocation_bounds.dart.weak.transformed.expect
new file mode 100644
index 0000000..f71e3b1
--- /dev/null
+++ b/pkg/front_end/testcases/general/function_invocation_bounds.dart.weak.transformed.expect
@@ -0,0 +1,51 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/function_invocation_bounds.dart:18:3: Error: 'F' isn't a type.
+//   F g = local;
+//   ^
+//
+// pkg/front_end/testcases/general/function_invocation_bounds.dart:9:8: Error: Inferred type argument 'String' doesn't conform to the bound 'num' of the type variable 'T' on 'local'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//   local("");
+//        ^
+//
+// pkg/front_end/testcases/general/function_invocation_bounds.dart:10:8: Error: Type argument 'String' doesn't conform to the bound 'num' of the type variable 'T' on 'local'.
+// Try changing type arguments so that they conform to the bounds.
+//   local<String>(throw '');
+//        ^
+//
+// pkg/front_end/testcases/general/function_invocation_bounds.dart:14:4: Error: Inferred type argument 'String' doesn't conform to the bound 'num' of the type variable 'T' on 'call'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//   f("");
+//    ^
+//
+// pkg/front_end/testcases/general/function_invocation_bounds.dart:15:4: Error: Type argument 'String' doesn't conform to the bound 'num' of the type variable 'T' on 'call'.
+// Try changing type arguments so that they conform to the bounds.
+//   f<String>(throw '');
+//    ^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef G<invariant T extends core::Object? = dynamic> = (T%) → T%;
+static method test() → dynamic {
+  function local<T extends core::num = core::num>(T t) → T
+    return t;
+  local.call<core::String>("");
+  local.call<core::String>(throw "");
+  local.call<core::int>(0);
+  local.call<core::int>(throw "");
+  <T extends core::num = core::num>(T) → T f = local;
+  f.call<core::String>("");
+  f.call<core::String>(throw "");
+  f.call<core::int>(0);
+  f.call<core::int>(throw "");
+  invalid-type g = local;
+  g.call("");
+  g.call<core::String>(throw "");
+  g.call(0);
+  g.call<core::int>(throw "");
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general/function_type_parameter.dart b/pkg/front_end/testcases/general/function_type_parameter.dart
new file mode 100644
index 0000000..a9cb3ee
--- /dev/null
+++ b/pkg/front_end/testcases/general/function_type_parameter.dart
@@ -0,0 +1,25 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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();
+}
+
+void Function<@A() T>(T)? f;
+
+typedef F = void Function<@A() T>(T);
+
+typedef void G<@A() T>(T t);
+
+void method1<@A() T>(T t) {}
+
+void method2(void Function<@A() T>(T) f) {}
+
+class Class<T extends void Function<@A() S>(S)> {}
+
+main() {
+  void local<@A() T>(T t) {}
+
+  void Function<@A() T>(T)? f;
+}
diff --git a/pkg/front_end/testcases/general/function_type_parameter.dart.textual_outline.expect b/pkg/front_end/testcases/general/function_type_parameter.dart.textual_outline.expect
new file mode 100644
index 0000000..31291f6
--- /dev/null
+++ b/pkg/front_end/testcases/general/function_type_parameter.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+class A {
+  const A();
+}
+
+void Function<@A() T>(T)? f;
+typedef F = void Function<@A() T>(T);
+typedef void G<@A() T>(T t);
+void method1<@A() T>(T t) {}
+void method2(void Function<@A() T>(T) f) {}
+
+class Class<T extends void Function<@A() S>(S)> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/function_type_parameter.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/function_type_parameter.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e028d49
--- /dev/null
+++ b/pkg/front_end/testcases/general/function_type_parameter.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+class A {
+  const A();
+}
+
+class Class<T extends void Function<@A() S>(S)> {}
+
+main() {}
+typedef F = void Function<@A() T>(T);
+typedef void G<@A() T>(T t);
+void Function<@A() T>(T)? f;
+void method1<@A() T>(T t) {}
+void method2(void Function<@A() T>(T) f) {}
diff --git a/pkg/front_end/testcases/general/function_type_parameter.dart.weak.expect b/pkg/front_end/testcases/general/function_type_parameter.dart.weak.expect
new file mode 100644
index 0000000..35519c9
--- /dev/null
+++ b/pkg/front_end/testcases/general/function_type_parameter.dart.weak.expect
@@ -0,0 +1,60 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/function_type_parameter.dart:9:20: Error: A type variable on a function type can't have annotations.
+// void Function<@A() T>(T)? f;
+//                    ^
+//
+// pkg/front_end/testcases/general/function_type_parameter.dart:11:32: Error: A type variable on a function type can't have annotations.
+// typedef F = void Function<@A() T>(T);
+//                                ^
+//
+// pkg/front_end/testcases/general/function_type_parameter.dart:17:33: Error: A type variable on a function type can't have annotations.
+// void method2(void Function<@A() T>(T) f) {}
+//                                 ^
+//
+// pkg/front_end/testcases/general/function_type_parameter.dart:19:42: Error: A type variable on a function type can't have annotations.
+// class Class<T extends void Function<@A() S>(S)> {}
+//                                          ^
+//
+// pkg/front_end/testcases/general/function_type_parameter.dart:19:13: Error: Type variables can't have generic function types in their bounds.
+// class Class<T extends void Function<@A() S>(S)> {}
+//             ^
+//
+// pkg/front_end/testcases/general/function_type_parameter.dart:24:22: Error: A type variable on a function type can't have annotations.
+//   void Function<@A() T>(T)? f;
+//                      ^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef F = <T extends core::Object? = dynamic>(T%) → void;
+typedef G<@#C1 contravariant T extends core::Object? = dynamic> = (T%) → void;
+class A extends core::Object /*hasConstConstructor*/  {
+  const constructor •() → self::A
+    : super core::Object::•()
+    ;
+}
+class Class<T extends <S extends core::Object? = dynamic>(S%) → void = dynamic> extends core::Object {
+  synthetic constructor •() → self::Class<self::Class::T>
+    : super core::Object::•()
+    ;
+}
+static field <T extends core::Object? = dynamic>(T%) →? void f;
+static method method1<@#C1 T extends core::Object? = dynamic>(self::method1::T% t) → void {}
+static method method2(<T extends core::Object? = dynamic>(T%) → void f) → void {}
+static method main() → dynamic {
+  function local<@#C1 T extends core::Object? = dynamic>(T% t) → void {}
+  <T extends core::Object? = dynamic>(T%) →? void f;
+}
+
+constants  {
+  #C1 = self::A {}
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///function_type_parameter.dart:
+- A. (from org-dartlang-testcase:///function_type_parameter.dart:6:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/general/function_type_parameter.dart.weak.outline.expect b/pkg/front_end/testcases/general/function_type_parameter.dart.weak.outline.expect
new file mode 100644
index 0000000..0ce97a7
--- /dev/null
+++ b/pkg/front_end/testcases/general/function_type_parameter.dart.weak.outline.expect
@@ -0,0 +1,51 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/function_type_parameter.dart:9:20: Error: A type variable on a function type can't have annotations.
+// void Function<@A() T>(T)? f;
+//                    ^
+//
+// pkg/front_end/testcases/general/function_type_parameter.dart:11:32: Error: A type variable on a function type can't have annotations.
+// typedef F = void Function<@A() T>(T);
+//                                ^
+//
+// pkg/front_end/testcases/general/function_type_parameter.dart:17:33: Error: A type variable on a function type can't have annotations.
+// void method2(void Function<@A() T>(T) f) {}
+//                                 ^
+//
+// pkg/front_end/testcases/general/function_type_parameter.dart:19:42: Error: A type variable on a function type can't have annotations.
+// class Class<T extends void Function<@A() S>(S)> {}
+//                                          ^
+//
+// pkg/front_end/testcases/general/function_type_parameter.dart:19:13: Error: Type variables can't have generic function types in their bounds.
+// class Class<T extends void Function<@A() S>(S)> {}
+//             ^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef F = <T extends core::Object? = dynamic>(T%) → void;
+typedef G<@self::A::•() contravariant T extends core::Object? = dynamic> = (T%) → void;
+class A extends core::Object /*hasConstConstructor*/  {
+  const constructor •() → self::A
+    : super core::Object::•()
+    ;
+}
+class Class<T extends <S extends core::Object? = dynamic>(S%) → void = dynamic> extends core::Object {
+  synthetic constructor •() → self::Class<self::Class::T>
+    ;
+}
+static field <T extends core::Object? = dynamic>(T%) →? void f;
+static method method1<@self::A::•() T extends core::Object? = dynamic>(self::method1::T% t) → void
+  ;
+static method method2(<T extends core::Object? = dynamic>(T%) → void f) → void
+  ;
+static method main() → dynamic
+  ;
+
+
+Extra constant evaluation status:
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///function_type_parameter.dart:13:17 -> InstanceConstant(const A{})
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///function_type_parameter.dart:15:15 -> InstanceConstant(const A{})
+Extra constant evaluation: evaluated: 2, effectively constant: 2
diff --git a/pkg/front_end/testcases/general/function_type_parameter.dart.weak.transformed.expect b/pkg/front_end/testcases/general/function_type_parameter.dart.weak.transformed.expect
new file mode 100644
index 0000000..35519c9
--- /dev/null
+++ b/pkg/front_end/testcases/general/function_type_parameter.dart.weak.transformed.expect
@@ -0,0 +1,60 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/function_type_parameter.dart:9:20: Error: A type variable on a function type can't have annotations.
+// void Function<@A() T>(T)? f;
+//                    ^
+//
+// pkg/front_end/testcases/general/function_type_parameter.dart:11:32: Error: A type variable on a function type can't have annotations.
+// typedef F = void Function<@A() T>(T);
+//                                ^
+//
+// pkg/front_end/testcases/general/function_type_parameter.dart:17:33: Error: A type variable on a function type can't have annotations.
+// void method2(void Function<@A() T>(T) f) {}
+//                                 ^
+//
+// pkg/front_end/testcases/general/function_type_parameter.dart:19:42: Error: A type variable on a function type can't have annotations.
+// class Class<T extends void Function<@A() S>(S)> {}
+//                                          ^
+//
+// pkg/front_end/testcases/general/function_type_parameter.dart:19:13: Error: Type variables can't have generic function types in their bounds.
+// class Class<T extends void Function<@A() S>(S)> {}
+//             ^
+//
+// pkg/front_end/testcases/general/function_type_parameter.dart:24:22: Error: A type variable on a function type can't have annotations.
+//   void Function<@A() T>(T)? f;
+//                      ^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef F = <T extends core::Object? = dynamic>(T%) → void;
+typedef G<@#C1 contravariant T extends core::Object? = dynamic> = (T%) → void;
+class A extends core::Object /*hasConstConstructor*/  {
+  const constructor •() → self::A
+    : super core::Object::•()
+    ;
+}
+class Class<T extends <S extends core::Object? = dynamic>(S%) → void = dynamic> extends core::Object {
+  synthetic constructor •() → self::Class<self::Class::T>
+    : super core::Object::•()
+    ;
+}
+static field <T extends core::Object? = dynamic>(T%) →? void f;
+static method method1<@#C1 T extends core::Object? = dynamic>(self::method1::T% t) → void {}
+static method method2(<T extends core::Object? = dynamic>(T%) → void f) → void {}
+static method main() → dynamic {
+  function local<@#C1 T extends core::Object? = dynamic>(T% t) → void {}
+  <T extends core::Object? = dynamic>(T%) →? void f;
+}
+
+constants  {
+  #C1 = self::A {}
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///function_type_parameter.dart:
+- A. (from org-dartlang-testcase:///function_type_parameter.dart:6:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/general/generic_typedef_in_generic_class.dart b/pkg/front_end/testcases/general/generic_typedef_in_generic_class.dart
new file mode 100644
index 0000000..366c73b7
--- /dev/null
+++ b/pkg/front_end/testcases/general/generic_typedef_in_generic_class.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+typedef F = T Function<T, S>(T, S);
+
+class Class<A> {
+  method() {
+    const G = F;
+    print(F);
+    print(G);
+  }
+}
+
+main() {
+  new Class<int>().method();
+}
diff --git a/pkg/front_end/testcases/general/generic_typedef_in_generic_class.dart.textual_outline.expect b/pkg/front_end/testcases/general/generic_typedef_in_generic_class.dart.textual_outline.expect
new file mode 100644
index 0000000..244f23d
--- /dev/null
+++ b/pkg/front_end/testcases/general/generic_typedef_in_generic_class.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+typedef F = T Function<T, S>(T, S);
+
+class Class<A> {
+  method() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/generic_typedef_in_generic_class.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/generic_typedef_in_generic_class.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bb25297
--- /dev/null
+++ b/pkg/front_end/testcases/general/generic_typedef_in_generic_class.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+class Class<A> {
+  method() {}
+}
+
+main() {}
+typedef F = T Function<T, S>(T, S);
diff --git a/pkg/front_end/testcases/general/generic_typedef_in_generic_class.dart.weak.expect b/pkg/front_end/testcases/general/generic_typedef_in_generic_class.dart.weak.expect
new file mode 100644
index 0000000..542c883
--- /dev/null
+++ b/pkg/front_end/testcases/general/generic_typedef_in_generic_class.dart.weak.expect
@@ -0,0 +1,21 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+typedef F = <T extends core::Object? = dynamic, S extends core::Object? = dynamic>(T%, S%) → T%;
+class Class<A extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::Class<self::Class::A%>
+    : super core::Object::•()
+    ;
+  method method() → dynamic {
+    core::print(#C1);
+    core::print(#C1);
+  }
+}
+static method main() → dynamic {
+  new self::Class::•<core::int>().{self::Class::method}();
+}
+
+constants  {
+  #C1 = TypeLiteralConstant(<T extends core::Object? = dynamic, S extends core::Object? = dynamic>(T*, S*) →* T*)
+}
diff --git a/pkg/front_end/testcases/general/generic_typedef_in_generic_class.dart.weak.outline.expect b/pkg/front_end/testcases/general/generic_typedef_in_generic_class.dart.weak.outline.expect
new file mode 100644
index 0000000..6a9b7fb
--- /dev/null
+++ b/pkg/front_end/testcases/general/generic_typedef_in_generic_class.dart.weak.outline.expect
@@ -0,0 +1,13 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+typedef F = <T extends core::Object? = dynamic, S extends core::Object? = dynamic>(T%, S%) → T%;
+class Class<A extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::Class<self::Class::A%>
+    ;
+  method method() → dynamic
+    ;
+}
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/general/generic_typedef_in_generic_class.dart.weak.transformed.expect b/pkg/front_end/testcases/general/generic_typedef_in_generic_class.dart.weak.transformed.expect
new file mode 100644
index 0000000..542c883
--- /dev/null
+++ b/pkg/front_end/testcases/general/generic_typedef_in_generic_class.dart.weak.transformed.expect
@@ -0,0 +1,21 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+typedef F = <T extends core::Object? = dynamic, S extends core::Object? = dynamic>(T%, S%) → T%;
+class Class<A extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::Class<self::Class::A%>
+    : super core::Object::•()
+    ;
+  method method() → dynamic {
+    core::print(#C1);
+    core::print(#C1);
+  }
+}
+static method main() → dynamic {
+  new self::Class::•<core::int>().{self::Class::method}();
+}
+
+constants  {
+  #C1 = TypeLiteralConstant(<T extends core::Object? = dynamic, S extends core::Object? = dynamic>(T*, S*) →* T*)
+}
diff --git a/pkg/front_end/testcases/general/issue42435.dart b/pkg/front_end/testcases/general/issue42435.dart
new file mode 100644
index 0000000..f49f068
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue42435.dart
@@ -0,0 +1,32 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class A<X extends A<X>> {}
+
+typedef F = Function<Y extends A>();
+
+class B {
+  B(Function<Z extends A>() a);
+  factory B.foo(Function<Z extends A>() a) => new B(a);
+  foo2(Function<Z extends A>() a) {}
+  Function<Z extends A>() foo3() => throw 42;
+  Function<Z extends A>() get foo4 => throw 42;
+  void set foo5(Function<Z extends A>() a) {}
+  Function<Z extends A>() foo6 = (() => throw 42)();
+}
+
+bar2(Function<Z extends A>() a) {}
+Function<Z extends A>() bar3() => throw 42;
+Function<Z extends A>() get bar4 => throw 42;
+void set bar5(Function<Z extends A>() a) {}
+Function<Z extends A>() bar6 = (() => throw 42)();
+
+extension E on int {
+  baz2(Function<Z extends A>() a) {}
+  Function<Z extends A>() baz3() => throw 42;
+  Function<Z extends A>() get baz4 => throw 42;
+  void set baz5(Function<Z extends A>() a) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/issue42435.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue42435.dart.textual_outline.expect
new file mode 100644
index 0000000..2e81748
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue42435.dart.textual_outline.expect
@@ -0,0 +1,28 @@
+class A<X extends A<X>> {}
+
+typedef F = Function<Y extends A>();
+
+class B {
+  B(Function<Z extends A>() a);
+  factory B.foo(Function<Z extends A>() a) => new B(a);
+  foo2(Function<Z extends A>() a) {}
+  Function<Z extends A>() foo3() => throw 42;
+  Function<Z extends A>() get foo4 => throw 42;
+  void set foo5(Function<Z extends A>() a) {}
+  Function<Z extends A>() foo6 = (() => throw 42)();
+}
+
+bar2(Function<Z extends A>() a) {}
+Function<Z extends A>() bar3() => throw 42;
+Function<Z extends A>() get bar4 => throw 42;
+void set bar5(Function<Z extends A>() a) {}
+Function<Z extends A>() bar6 = (() => throw 42)();
+
+extension E on int {
+  baz2(Function<Z extends A>() a) {}
+  Function<Z extends A>() baz3() => throw 42;
+  Function<Z extends A>() get baz4 => throw 42;
+  void set baz5(Function<Z extends A>() a) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/issue42435.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue42435.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c61aa8e
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue42435.dart.textual_outline_modelled.expect
@@ -0,0 +1,27 @@
+Function<Z extends A>() bar3() => throw 42;
+Function<Z extends A>() bar6 = (() => throw 42)();
+Function<Z extends A>() get bar4 => throw 42;
+bar2(Function<Z extends A>() a) {}
+
+class A<X extends A<X>> {}
+
+class B {
+  B(Function<Z extends A>() a);
+  Function<Z extends A>() foo3() => throw 42;
+  Function<Z extends A>() foo6 = (() => throw 42)();
+  Function<Z extends A>() get foo4 => throw 42;
+  factory B.foo(Function<Z extends A>() a) => new B(a);
+  foo2(Function<Z extends A>() a) {}
+  void set foo5(Function<Z extends A>() a) {}
+}
+
+extension E on int {
+  Function<Z extends A>() baz3() => throw 42;
+  Function<Z extends A>() get baz4 => throw 42;
+  baz2(Function<Z extends A>() a) {}
+  void set baz5(Function<Z extends A>() a) {}
+}
+
+main() {}
+typedef F = Function<Y extends A>();
+void set bar5(Function<Z extends A>() a) {}
diff --git a/pkg/front_end/testcases/general/issue42435.dart.weak.expect b/pkg/front_end/testcases/general/issue42435.dart.weak.expect
new file mode 100644
index 0000000..4c809d0
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue42435.dart.weak.expect
@@ -0,0 +1,190 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/issue42435.dart:7:22: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+// typedef F = Function<Y extends A>();
+//                      ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+//         ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:10:14: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+//   B(Function<Z extends A>() a);
+//              ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+//         ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:11:26: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+//   factory B.foo(Function<Z extends A>() a) => new B(a);
+//                          ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+//         ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:12:17: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+//   foo2(Function<Z extends A>() a) {}
+//                 ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+//         ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:13:12: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+//   Function<Z extends A>() foo3() => throw 42;
+//            ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+//         ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:14:12: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+//   Function<Z extends A>() get foo4 => throw 42;
+//            ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+//         ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:16:12: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+//   Function<Z extends A>() foo6 = (() => throw 42)();
+//            ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+//         ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:15:26: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+//   void set foo5(Function<Z extends A>() a) {}
+//                          ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+//         ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:19:15: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+// bar2(Function<Z extends A>() a) {}
+//               ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+//         ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:20:10: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+// Function<Z extends A>() bar3() => throw 42;
+//          ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+//         ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:21:10: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+// Function<Z extends A>() get bar4 => throw 42;
+//          ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+//         ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:23:10: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+// Function<Z extends A>() bar6 = (() => throw 42)();
+//          ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+//         ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:26:17: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+//   baz2(Function<Z extends A>() a) {}
+//                 ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+//         ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:27:12: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+//   Function<Z extends A>() baz3() => throw 42;
+//            ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+//         ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:28:12: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+//   Function<Z extends A>() get baz4 => throw 42;
+//            ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+//         ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:29:26: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+//   void set baz5(Function<Z extends A>() a) {}
+//                          ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+//         ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:22:24: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+// void set bar5(Function<Z extends A>() a) {}
+//                        ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+//         ^
+//
+import self as self;
+import "dart:core" as core;
+import "dart:_internal" as _in;
+
+typedef F = <Y extends self::A<self::A<dynamic>> = dynamic>() → dynamic;
+class A<X extends self::A<self::A::X> = self::A<dynamic>> extends core::Object {
+  synthetic constructor •() → self::A<self::A::X>
+    : super core::Object::•()
+    ;
+}
+class B extends core::Object {
+  field <Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic foo6 = let final Never #t1 = (() → Never => throw 42).call() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
+  constructor •(<Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic a) → self::B
+    : super core::Object::•()
+    ;
+  static factory foo(<Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic a) → self::B
+    return new self::B::•(a);
+  method foo2(<Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic a) → dynamic {}
+  method foo3() → <Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic
+    return throw 42;
+  get foo4() → <Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic
+    return throw 42;
+  set foo5(<Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic a) → void {}
+}
+extension E on core::int {
+  method baz2 = self::E|baz2;
+  tearoff baz2 = self::E|get#baz2;
+  method baz3 = self::E|baz3;
+  tearoff baz3 = self::E|get#baz3;
+  get baz4 = self::E|get#baz4;
+  set baz5 = self::E|set#baz5;
+}
+static field <Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic bar6 = let final Never #t2 = (() → Never => throw 42).call() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
+static method bar2(<Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic a) → dynamic {}
+static method bar3() → <Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic
+  return throw 42;
+static get bar4() → <Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic
+  return throw 42;
+static set bar5(<Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic a) → void {}
+static method E|baz2(lowered final core::int #this, <Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic a) → dynamic {}
+static method E|get#baz2(lowered final core::int #this) → (<Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic) → dynamic
+  return (<Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic a) → dynamic => self::E|baz2(#this, a);
+static method E|baz3(lowered final core::int #this) → <Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic
+  return throw 42;
+static method E|get#baz3(lowered final core::int #this) → () → <Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic
+  return () → <Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic => self::E|baz3(#this);
+static method E|get#baz4(lowered final core::int #this) → <Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic
+  return throw 42;
+static method E|set#baz5(lowered final core::int #this, <Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic a) → void {}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general/issue42435.dart.weak.outline.expect b/pkg/front_end/testcases/general/issue42435.dart.weak.outline.expect
new file mode 100644
index 0000000..90c287f
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue42435.dart.weak.outline.expect
@@ -0,0 +1,194 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/issue42435.dart:7:22: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+// typedef F = Function<Y extends A>();
+//                      ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+//         ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:10:14: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+//   B(Function<Z extends A>() a);
+//              ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+//         ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:11:26: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+//   factory B.foo(Function<Z extends A>() a) => new B(a);
+//                          ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+//         ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:12:17: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+//   foo2(Function<Z extends A>() a) {}
+//                 ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+//         ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:13:12: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+//   Function<Z extends A>() foo3() => throw 42;
+//            ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+//         ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:14:12: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+//   Function<Z extends A>() get foo4 => throw 42;
+//            ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+//         ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:16:12: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+//   Function<Z extends A>() foo6 = (() => throw 42)();
+//            ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+//         ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:15:26: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+//   void set foo5(Function<Z extends A>() a) {}
+//                          ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+//         ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:19:15: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+// bar2(Function<Z extends A>() a) {}
+//               ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+//         ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:20:10: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+// Function<Z extends A>() bar3() => throw 42;
+//          ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+//         ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:21:10: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+// Function<Z extends A>() get bar4 => throw 42;
+//          ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+//         ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:23:10: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+// Function<Z extends A>() bar6 = (() => throw 42)();
+//          ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+//         ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:26:17: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+//   baz2(Function<Z extends A>() a) {}
+//                 ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+//         ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:27:12: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+//   Function<Z extends A>() baz3() => throw 42;
+//            ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+//         ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:28:12: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+//   Function<Z extends A>() get baz4 => throw 42;
+//            ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+//         ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:29:26: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+//   void set baz5(Function<Z extends A>() a) {}
+//                          ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+//         ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:22:24: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+// void set bar5(Function<Z extends A>() a) {}
+//                        ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+//         ^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef F = <Y extends self::A<self::A<dynamic>> = dynamic>() → dynamic;
+class A<X extends self::A<self::A::X> = self::A<dynamic>> extends core::Object {
+  synthetic constructor •() → self::A<self::A::X>
+    ;
+}
+class B extends core::Object {
+  field <Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic foo6;
+  constructor •(<Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic a) → self::B
+    ;
+  static factory foo(<Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic a) → self::B
+    ;
+  method foo2(<Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic a) → dynamic
+    ;
+  method foo3() → <Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic
+    ;
+  get foo4() → <Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic
+    ;
+  set foo5(<Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic a) → void
+    ;
+}
+extension E on core::int {
+  method baz2 = self::E|baz2;
+  tearoff baz2 = self::E|get#baz2;
+  method baz3 = self::E|baz3;
+  tearoff baz3 = self::E|get#baz3;
+  get baz4 = self::E|get#baz4;
+  set baz5 = self::E|set#baz5;
+}
+static field <Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic bar6;
+static method bar2(<Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic a) → dynamic
+  ;
+static method bar3() → <Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic
+  ;
+static get bar4() → <Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic
+  ;
+static set bar5(<Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic a) → void
+  ;
+static method E|baz2(lowered final core::int #this, <Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic a) → dynamic
+  ;
+static method E|get#baz2(lowered final core::int #this) → (<Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic) → dynamic
+  return (<Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic a) → dynamic => self::E|baz2(#this, a);
+static method E|baz3(lowered final core::int #this) → <Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic
+  ;
+static method E|get#baz3(lowered final core::int #this) → () → <Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic
+  return () → <Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic => self::E|baz3(#this);
+static method E|get#baz4(lowered final core::int #this) → <Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic
+  ;
+static method E|set#baz5(lowered final core::int #this, <Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic a) → void
+  ;
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/general/issue42435.dart.weak.transformed.expect b/pkg/front_end/testcases/general/issue42435.dart.weak.transformed.expect
new file mode 100644
index 0000000..4c809d0
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue42435.dart.weak.transformed.expect
@@ -0,0 +1,190 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/issue42435.dart:7:22: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+// typedef F = Function<Y extends A>();
+//                      ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+//         ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:10:14: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+//   B(Function<Z extends A>() a);
+//              ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+//         ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:11:26: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+//   factory B.foo(Function<Z extends A>() a) => new B(a);
+//                          ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+//         ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:12:17: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+//   foo2(Function<Z extends A>() a) {}
+//                 ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+//         ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:13:12: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+//   Function<Z extends A>() foo3() => throw 42;
+//            ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+//         ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:14:12: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+//   Function<Z extends A>() get foo4 => throw 42;
+//            ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+//         ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:16:12: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+//   Function<Z extends A>() foo6 = (() => throw 42)();
+//            ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+//         ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:15:26: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+//   void set foo5(Function<Z extends A>() a) {}
+//                          ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+//         ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:19:15: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+// bar2(Function<Z extends A>() a) {}
+//               ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+//         ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:20:10: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+// Function<Z extends A>() bar3() => throw 42;
+//          ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+//         ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:21:10: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+// Function<Z extends A>() get bar4 => throw 42;
+//          ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+//         ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:23:10: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+// Function<Z extends A>() bar6 = (() => throw 42)();
+//          ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+//         ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:26:17: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+//   baz2(Function<Z extends A>() a) {}
+//                 ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+//         ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:27:12: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+//   Function<Z extends A>() baz3() => throw 42;
+//            ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+//         ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:28:12: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+//   Function<Z extends A>() get baz4 => throw 42;
+//            ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+//         ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:29:26: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+//   void set baz5(Function<Z extends A>() a) {}
+//                          ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+//         ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:22:24: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+// void set bar5(Function<Z extends A>() a) {}
+//                        ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+//         ^
+//
+import self as self;
+import "dart:core" as core;
+import "dart:_internal" as _in;
+
+typedef F = <Y extends self::A<self::A<dynamic>> = dynamic>() → dynamic;
+class A<X extends self::A<self::A::X> = self::A<dynamic>> extends core::Object {
+  synthetic constructor •() → self::A<self::A::X>
+    : super core::Object::•()
+    ;
+}
+class B extends core::Object {
+  field <Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic foo6 = let final Never #t1 = (() → Never => throw 42).call() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
+  constructor •(<Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic a) → self::B
+    : super core::Object::•()
+    ;
+  static factory foo(<Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic a) → self::B
+    return new self::B::•(a);
+  method foo2(<Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic a) → dynamic {}
+  method foo3() → <Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic
+    return throw 42;
+  get foo4() → <Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic
+    return throw 42;
+  set foo5(<Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic a) → void {}
+}
+extension E on core::int {
+  method baz2 = self::E|baz2;
+  tearoff baz2 = self::E|get#baz2;
+  method baz3 = self::E|baz3;
+  tearoff baz3 = self::E|get#baz3;
+  get baz4 = self::E|get#baz4;
+  set baz5 = self::E|set#baz5;
+}
+static field <Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic bar6 = let final Never #t2 = (() → Never => throw 42).call() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
+static method bar2(<Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic a) → dynamic {}
+static method bar3() → <Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic
+  return throw 42;
+static get bar4() → <Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic
+  return throw 42;
+static set bar5(<Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic a) → void {}
+static method E|baz2(lowered final core::int #this, <Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic a) → dynamic {}
+static method E|get#baz2(lowered final core::int #this) → (<Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic) → dynamic
+  return (<Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic a) → dynamic => self::E|baz2(#this, a);
+static method E|baz3(lowered final core::int #this) → <Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic
+  return throw 42;
+static method E|get#baz3(lowered final core::int #this) → () → <Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic
+  return () → <Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic => self::E|baz3(#this);
+static method E|get#baz4(lowered final core::int #this) → <Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic
+  return throw 42;
+static method E|set#baz5(lowered final core::int #this, <Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic a) → void {}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general/issue42435_2.dart b/pkg/front_end/testcases/general/issue42435_2.dart
new file mode 100644
index 0000000..cc13212
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue42435_2.dart
@@ -0,0 +1,5 @@
+class A<X extends A<X>> {}
+
+typedef AAlias = Function<X extends A>();
+
+main() {}
diff --git a/pkg/front_end/testcases/general/issue42435_2.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue42435_2.dart.textual_outline.expect
new file mode 100644
index 0000000..3230d3d
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue42435_2.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+class A<X extends A<X>> {}
+
+typedef AAlias = Function<X extends A>();
+main() {}
diff --git a/pkg/front_end/testcases/general/issue42435_2.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue42435_2.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ce0d405
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue42435_2.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+class A<X extends A<X>> {}
+
+main() {}
+typedef AAlias = Function<X extends A>();
diff --git a/pkg/front_end/testcases/general/issue42435_2.dart.weak.expect b/pkg/front_end/testcases/general/issue42435_2.dart.weak.expect
new file mode 100644
index 0000000..aa9fc93
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue42435_2.dart.weak.expect
@@ -0,0 +1,22 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/issue42435_2.dart:3:27: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+// typedef AAlias = Function<X extends A>();
+//                           ^
+// pkg/front_end/testcases/general/issue42435_2.dart:1:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+//         ^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef AAlias = <X extends self::A<self::A<dynamic>> = dynamic>() → dynamic;
+class A<X extends self::A<self::A::X> = self::A<dynamic>> extends core::Object {
+  synthetic constructor •() → self::A<self::A::X>
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general/issue42435_2.dart.weak.outline.expect b/pkg/front_end/testcases/general/issue42435_2.dart.weak.outline.expect
new file mode 100644
index 0000000..b808ee98
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue42435_2.dart.weak.outline.expect
@@ -0,0 +1,22 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/issue42435_2.dart:3:27: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+// typedef AAlias = Function<X extends A>();
+//                           ^
+// pkg/front_end/testcases/general/issue42435_2.dart:1:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+//         ^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef AAlias = <X extends self::A<self::A<dynamic>> = dynamic>() → dynamic;
+class A<X extends self::A<self::A::X> = self::A<dynamic>> extends core::Object {
+  synthetic constructor •() → self::A<self::A::X>
+    ;
+}
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/general/issue42435_2.dart.weak.transformed.expect b/pkg/front_end/testcases/general/issue42435_2.dart.weak.transformed.expect
new file mode 100644
index 0000000..aa9fc93
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue42435_2.dart.weak.transformed.expect
@@ -0,0 +1,22 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/issue42435_2.dart:3:27: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+// typedef AAlias = Function<X extends A>();
+//                           ^
+// pkg/front_end/testcases/general/issue42435_2.dart:1:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+//         ^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef AAlias = <X extends self::A<self::A<dynamic>> = dynamic>() → dynamic;
+class A<X extends self::A<self::A::X> = self::A<dynamic>> extends core::Object {
+  synthetic constructor •() → self::A<self::A::X>
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general/issue45204.dart b/pkg/front_end/testcases/general/issue45204.dart
new file mode 100644
index 0000000..ee754db
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue45204.dart
@@ -0,0 +1,44 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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 S on int {
+  void test(int x) {}
+}
+
+extension S2<X> on int {
+  void test2(int x) {}
+  void test3<Y>(Y y) {}
+}
+
+foo() {
+  3.test();
+  4.test(5, 6);
+  5.test<int>(6);
+
+  3.test2();
+  4.test2(5, 6);
+  5.test2<int>(6);
+
+  3.test3();
+  4.test3(5, 6);
+  5.test3<int>(6);
+  6.test3<int, int>(7);
+  7.test3<int, int, int>(8);
+
+  S(3).test();
+  S(4).test(5, 6);
+  S(5).test<int>(6);
+
+  S2(3).test2();
+  S2(4).test2(5, 6);
+  S2(5).test2<int>(6);
+
+  S2(3).test3();
+  S2(4).test3(5, 6);
+  S2(5).test3<int>(6);
+  S2(6).test3<int, int>(7);
+  S2(7).test3<int, int, int>(8);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/issue45204.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue45204.dart.textual_outline.expect
new file mode 100644
index 0000000..1eac4b0
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue45204.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+extension S on int {
+  void test(int x) {}
+}
+
+extension S2<X> on int {
+  void test2(int x) {}
+  void test3<Y>(Y y) {}
+}
+
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/general/issue45204.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue45204.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1eac4b0
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue45204.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+extension S on int {
+  void test(int x) {}
+}
+
+extension S2<X> on int {
+  void test2(int x) {}
+  void test3<Y>(Y y) {}
+}
+
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/general/issue45204.dart.weak.expect b/pkg/front_end/testcases/general/issue45204.dart.weak.expect
new file mode 100644
index 0000000..6488985
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue45204.dart.weak.expect
@@ -0,0 +1,213 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/issue45204.dart:29:8: Error: Too few positional arguments: 1 required, 0 given.
+//   S(3).test();
+//        ^
+// pkg/front_end/testcases/general/issue45204.dart:6:8: Context: Found this candidate, but the arguments don't match.
+//   void test(int x) {}
+//        ^^^^^^
+//
+// pkg/front_end/testcases/general/issue45204.dart:30:8: Error: Too many positional arguments: 1 allowed, but 2 found.
+// Try removing the extra positional arguments.
+//   S(4).test(5, 6);
+//        ^
+// pkg/front_end/testcases/general/issue45204.dart:6:8: Context: Found this candidate, but the arguments don't match.
+//   void test(int x) {}
+//        ^^^^^^
+//
+// pkg/front_end/testcases/general/issue45204.dart:31:8: Error: Expected 0 type arguments.
+//   S(5).test<int>(6);
+//        ^
+// pkg/front_end/testcases/general/issue45204.dart:6:8: Context: Found this candidate, but the arguments don't match.
+//   void test(int x) {}
+//        ^^^^^^
+//
+// pkg/front_end/testcases/general/issue45204.dart:33:9: Error: Too few positional arguments: 1 required, 0 given.
+//   S2(3).test2();
+//         ^
+// pkg/front_end/testcases/general/issue45204.dart:10:8: Context: Found this candidate, but the arguments don't match.
+//   void test2(int x) {}
+//        ^^^^^^^^
+//
+// pkg/front_end/testcases/general/issue45204.dart:34:9: Error: Too many positional arguments: 1 allowed, but 2 found.
+// Try removing the extra positional arguments.
+//   S2(4).test2(5, 6);
+//         ^
+// pkg/front_end/testcases/general/issue45204.dart:10:8: Context: Found this candidate, but the arguments don't match.
+//   void test2(int x) {}
+//        ^^^^^^^^
+//
+// pkg/front_end/testcases/general/issue45204.dart:35:9: Error: Expected 1 type arguments.
+//   S2(5).test2<int>(6);
+//         ^
+// pkg/front_end/testcases/general/issue45204.dart:10:8: Context: Found this candidate, but the arguments don't match.
+//   void test2(int x) {}
+//        ^^^^^^^^
+//
+// pkg/front_end/testcases/general/issue45204.dart:37:9: Error: Too few positional arguments: 1 required, 0 given.
+//   S2(3).test3();
+//         ^
+// pkg/front_end/testcases/general/issue45204.dart:11:8: Context: Found this candidate, but the arguments don't match.
+//   void test3<Y>(Y y) {}
+//        ^^^^^^^^
+//
+// pkg/front_end/testcases/general/issue45204.dart:38:9: Error: Too many positional arguments: 1 allowed, but 2 found.
+// Try removing the extra positional arguments.
+//   S2(4).test3(5, 6);
+//         ^
+// pkg/front_end/testcases/general/issue45204.dart:11:8: Context: Found this candidate, but the arguments don't match.
+//   void test3<Y>(Y y) {}
+//        ^^^^^^^^
+//
+// pkg/front_end/testcases/general/issue45204.dart:40:9: Error: Expected 2 type arguments.
+//   S2(6).test3<int, int>(7);
+//         ^
+// pkg/front_end/testcases/general/issue45204.dart:11:8: Context: Found this candidate, but the arguments don't match.
+//   void test3<Y>(Y y) {}
+//        ^^^^^^^^
+//
+// pkg/front_end/testcases/general/issue45204.dart:41:9: Error: Expected 2 type arguments.
+//   S2(7).test3<int, int, int>(8);
+//         ^
+// pkg/front_end/testcases/general/issue45204.dart:11:8: Context: Found this candidate, but the arguments don't match.
+//   void test3<Y>(Y y) {}
+//        ^^^^^^^^
+//
+// pkg/front_end/testcases/general/issue45204.dart:15:9: Error: Too few positional arguments: 1 required, 0 given.
+//   3.test();
+//         ^
+//
+// pkg/front_end/testcases/general/issue45204.dart:16:9: Error: Too many positional arguments: 1 allowed, but 2 found.
+// Try removing the extra positional arguments.
+//   4.test(5, 6);
+//         ^
+//
+// pkg/front_end/testcases/general/issue45204.dart:17:5: Error: Expected 0 type arguments.
+//   5.test<int>(6);
+//     ^
+//
+// pkg/front_end/testcases/general/issue45204.dart:19:10: Error: Too few positional arguments: 1 required, 0 given.
+//   3.test2();
+//          ^
+//
+// pkg/front_end/testcases/general/issue45204.dart:20:10: Error: Too many positional arguments: 1 allowed, but 2 found.
+// Try removing the extra positional arguments.
+//   4.test2(5, 6);
+//          ^
+//
+// pkg/front_end/testcases/general/issue45204.dart:21:5: Error: Expected 0 type arguments.
+//   5.test2<int>(6);
+//     ^
+//
+// pkg/front_end/testcases/general/issue45204.dart:23:10: Error: Too few positional arguments: 1 required, 0 given.
+//   3.test3();
+//          ^
+//
+// pkg/front_end/testcases/general/issue45204.dart:24:10: Error: Too many positional arguments: 1 allowed, but 2 found.
+// Try removing the extra positional arguments.
+//   4.test3(5, 6);
+//          ^
+//
+// pkg/front_end/testcases/general/issue45204.dart:26:5: Error: Expected 1 type arguments.
+//   6.test3<int, int>(7);
+//     ^
+//
+// pkg/front_end/testcases/general/issue45204.dart:27:5: Error: Expected 1 type arguments.
+//   7.test3<int, int, int>(8);
+//     ^
+//
+import self as self;
+import "dart:core" as core;
+
+extension S on core::int {
+  method test = self::S|test;
+  tearoff test = self::S|get#test;
+}
+extension S2<X extends core::Object? = dynamic> on core::int {
+  method test2 = self::S2|test2;
+  tearoff test2 = self::S2|get#test2;
+  method test3 = self::S2|test3;
+  tearoff test3 = self::S2|get#test3;
+}
+static method S|test(lowered final core::int #this, core::int x) → void {}
+static method S|get#test(lowered final core::int #this) → (core::int) → void
+  return (core::int x) → void => self::S|test(#this, x);
+static method S2|test2<X extends core::Object? = dynamic>(lowered final core::int #this, core::int x) → void {}
+static method S2|get#test2<X extends core::Object? = dynamic>(lowered final core::int #this) → (core::int) → void
+  return (core::int x) → void => self::S2|test2<self::S2|get#test2::X%>(#this, x);
+static method S2|test3<X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(lowered final core::int #this, self::S2|test3::Y% y) → void {}
+static method S2|get#test3<X extends core::Object? = dynamic>(lowered final core::int #this) → <Y extends core::Object? = dynamic>(Y%) → void
+  return <Y extends core::Object? = dynamic>(Y% y) → void => self::S2|test3<self::S2|get#test3::X%, Y%>(#this, y);
+static method foo() → dynamic {
+  let final Never #t1 = invalid-expression "pkg/front_end/testcases/general/issue45204.dart:15:9: Error: Too few positional arguments: 1 required, 0 given.
+  3.test();
+        ^" in self::S|test(3);
+  let final Never #t2 = invalid-expression "pkg/front_end/testcases/general/issue45204.dart:16:9: Error: Too many positional arguments: 1 allowed, but 2 found.
+Try removing the extra positional arguments.
+  4.test(5, 6);
+        ^" in self::S|test(4, 5, 6);
+  let final Never #t3 = invalid-expression "pkg/front_end/testcases/general/issue45204.dart:17:5: Error: Expected 0 type arguments.
+  5.test<int>(6);
+    ^" in self::S|test<core::int>(5, 6);
+  let final Never #t4 = invalid-expression "pkg/front_end/testcases/general/issue45204.dart:19:10: Error: Too few positional arguments: 1 required, 0 given.
+  3.test2();
+         ^" in self::S2|test2<dynamic>(3);
+  let final Never #t5 = invalid-expression "pkg/front_end/testcases/general/issue45204.dart:20:10: Error: Too many positional arguments: 1 allowed, but 2 found.
+Try removing the extra positional arguments.
+  4.test2(5, 6);
+         ^" in self::S2|test2<dynamic>(4, 5, 6);
+  let final Never #t6 = invalid-expression "pkg/front_end/testcases/general/issue45204.dart:21:5: Error: Expected 0 type arguments.
+  5.test2<int>(6);
+    ^" in self::S2|test2<dynamic, core::int>(5, 6);
+  let final Never #t7 = invalid-expression "pkg/front_end/testcases/general/issue45204.dart:23:10: Error: Too few positional arguments: 1 required, 0 given.
+  3.test3();
+         ^" in self::S2|test3<dynamic, dynamic>(3);
+  let final Never #t8 = invalid-expression "pkg/front_end/testcases/general/issue45204.dart:24:10: Error: Too many positional arguments: 1 allowed, but 2 found.
+Try removing the extra positional arguments.
+  4.test3(5, 6);
+         ^" in self::S2|test3<dynamic, core::int>(4, 5, 6);
+  self::S2|test3<dynamic, core::int>(5, 6);
+  let final Never #t9 = invalid-expression "pkg/front_end/testcases/general/issue45204.dart:26:5: Error: Expected 1 type arguments.
+  6.test3<int, int>(7);
+    ^" in self::S2|test3<dynamic, core::int, core::int>(6, 7);
+  let final Never #t10 = invalid-expression "pkg/front_end/testcases/general/issue45204.dart:27:5: Error: Expected 1 type arguments.
+  7.test3<int, int, int>(8);
+    ^" in self::S2|test3<dynamic, core::int, core::int, core::int>(7, 8);
+  invalid-expression "pkg/front_end/testcases/general/issue45204.dart:29:8: Error: Too few positional arguments: 1 required, 0 given.
+  S(3).test();
+       ^";
+  invalid-expression "pkg/front_end/testcases/general/issue45204.dart:30:8: Error: Too many positional arguments: 1 allowed, but 2 found.
+Try removing the extra positional arguments.
+  S(4).test(5, 6);
+       ^";
+  invalid-expression "pkg/front_end/testcases/general/issue45204.dart:31:8: Error: Expected 0 type arguments.
+  S(5).test<int>(6);
+       ^";
+  invalid-expression "pkg/front_end/testcases/general/issue45204.dart:33:9: Error: Too few positional arguments: 1 required, 0 given.
+  S2(3).test2();
+        ^";
+  invalid-expression "pkg/front_end/testcases/general/issue45204.dart:34:9: Error: Too many positional arguments: 1 allowed, but 2 found.
+Try removing the extra positional arguments.
+  S2(4).test2(5, 6);
+        ^";
+  invalid-expression "pkg/front_end/testcases/general/issue45204.dart:35:9: Error: Expected 1 type arguments.
+  S2(5).test2<int>(6);
+        ^";
+  invalid-expression "pkg/front_end/testcases/general/issue45204.dart:37:9: Error: Too few positional arguments: 1 required, 0 given.
+  S2(3).test3();
+        ^";
+  invalid-expression "pkg/front_end/testcases/general/issue45204.dart:38:9: Error: Too many positional arguments: 1 allowed, but 2 found.
+Try removing the extra positional arguments.
+  S2(4).test3(5, 6);
+        ^";
+  self::S2|test3<dynamic, core::int>(5, 6);
+  invalid-expression "pkg/front_end/testcases/general/issue45204.dart:40:9: Error: Expected 2 type arguments.
+  S2(6).test3<int, int>(7);
+        ^";
+  invalid-expression "pkg/front_end/testcases/general/issue45204.dart:41:9: Error: Expected 2 type arguments.
+  S2(7).test3<int, int, int>(8);
+        ^";
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general/issue45204.dart.weak.outline.expect b/pkg/front_end/testcases/general/issue45204.dart.weak.outline.expect
new file mode 100644
index 0000000..2c95328
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue45204.dart.weak.outline.expect
@@ -0,0 +1,30 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+extension S on core::int {
+  method test = self::S|test;
+  tearoff test = self::S|get#test;
+}
+extension S2<X extends core::Object? = dynamic> on core::int {
+  method test2 = self::S2|test2;
+  tearoff test2 = self::S2|get#test2;
+  method test3 = self::S2|test3;
+  tearoff test3 = self::S2|get#test3;
+}
+static method S|test(lowered final core::int #this, core::int x) → void
+  ;
+static method S|get#test(lowered final core::int #this) → (core::int) → void
+  return (core::int x) → void => self::S|test(#this, x);
+static method S2|test2<X extends core::Object? = dynamic>(lowered final core::int #this, core::int x) → void
+  ;
+static method S2|get#test2<X extends core::Object? = dynamic>(lowered final core::int #this) → (core::int) → void
+  return (core::int x) → void => self::S2|test2<self::S2|get#test2::X%>(#this, x);
+static method S2|test3<X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(lowered final core::int #this, self::S2|test3::Y% y) → void
+  ;
+static method S2|get#test3<X extends core::Object? = dynamic>(lowered final core::int #this) → <Y extends core::Object? = dynamic>(Y%) → void
+  return <Y extends core::Object? = dynamic>(Y% y) → void => self::S2|test3<self::S2|get#test3::X%, Y%>(#this, y);
+static method foo() → dynamic
+  ;
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/general/issue45330.dart b/pkg/front_end/testcases/general/issue45330.dart
new file mode 100644
index 0000000..95ebfd0
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue45330.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for 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 'issue45330_lib.dart';
+
+void genericMethod<T>() {}
+
+testInMain() {
+  genericMethod<void Function<T extends T>()>();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/issue45330.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue45330.dart.textual_outline.expect
new file mode 100644
index 0000000..23719be
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue45330.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+part 'issue45330_lib.dart';
+
+void genericMethod<T>() {}
+testInMain() {}
+main() {}
diff --git a/pkg/front_end/testcases/general/issue45330.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue45330.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..eb6bf12
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue45330.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+part 'issue45330_lib.dart';
+
+main() {}
+testInMain() {}
+void genericMethod<T>() {}
diff --git a/pkg/front_end/testcases/general/issue45330.dart.weak.expect b/pkg/front_end/testcases/general/issue45330.dart.weak.expect
new file mode 100644
index 0000000..c315320
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue45330.dart.weak.expect
@@ -0,0 +1,36 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/issue45330.dart:10:31: Error: Type 'T' is a bound of itself via 'T'.
+// Try breaking the cycle by removing at least on of the 'extends' clauses in the cycle.
+//   genericMethod<void Function<T extends T>()>();
+//                               ^
+//
+// pkg/front_end/testcases/general/issue45330.dart:10:3: Error: A generic function type can't be used as a type argument.
+// Try using a non-generic function type.
+//   genericMethod<void Function<T extends T>()>();
+//   ^
+//
+// pkg/front_end/testcases/general/issue45330_lib.dart:35:31: Error: Type 'T' is a bound of itself via 'T'.
+// Try breaking the cycle by removing at least on of the 'extends' clauses in the cycle.
+//   genericMethod<void Function<T extends T>()>();
+//                               ^
+//
+// pkg/front_end/testcases/general/issue45330_lib.dart:35:3: Error: A generic function type can't be used as a type argument.
+// Try using a non-generic function type.
+//   genericMethod<void Function<T extends T>()>();
+//   ^
+//
+import self as self;
+import "dart:core" as core;
+
+part issue45330_lib.dart;
+static method genericMethod<T extends core::Object? = dynamic>() → void {}
+static method testInMain() → dynamic {
+  self::genericMethod<<T extends invalid-type = invalid-type>() → void>();
+}
+static method main() → dynamic {}
+static method /* from org-dartlang-testcase:///issue45330_lib.dart */ testInPart() → dynamic {
+  self::genericMethod<<T extends invalid-type = invalid-type>() → void>();
+}
diff --git a/pkg/front_end/testcases/general/issue45330.dart.weak.outline.expect b/pkg/front_end/testcases/general/issue45330.dart.weak.outline.expect
new file mode 100644
index 0000000..fc3746d
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue45330.dart.weak.outline.expect
@@ -0,0 +1,13 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+part issue45330_lib.dart;
+static method genericMethod<T extends core::Object? = dynamic>() → void
+  ;
+static method testInMain() → dynamic
+  ;
+static method main() → dynamic
+  ;
+static method /* from org-dartlang-testcase:///issue45330_lib.dart */ testInPart() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/general/issue45330.dart.weak.transformed.expect b/pkg/front_end/testcases/general/issue45330.dart.weak.transformed.expect
new file mode 100644
index 0000000..c315320
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue45330.dart.weak.transformed.expect
@@ -0,0 +1,36 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/issue45330.dart:10:31: Error: Type 'T' is a bound of itself via 'T'.
+// Try breaking the cycle by removing at least on of the 'extends' clauses in the cycle.
+//   genericMethod<void Function<T extends T>()>();
+//                               ^
+//
+// pkg/front_end/testcases/general/issue45330.dart:10:3: Error: A generic function type can't be used as a type argument.
+// Try using a non-generic function type.
+//   genericMethod<void Function<T extends T>()>();
+//   ^
+//
+// pkg/front_end/testcases/general/issue45330_lib.dart:35:31: Error: Type 'T' is a bound of itself via 'T'.
+// Try breaking the cycle by removing at least on of the 'extends' clauses in the cycle.
+//   genericMethod<void Function<T extends T>()>();
+//                               ^
+//
+// pkg/front_end/testcases/general/issue45330_lib.dart:35:3: Error: A generic function type can't be used as a type argument.
+// Try using a non-generic function type.
+//   genericMethod<void Function<T extends T>()>();
+//   ^
+//
+import self as self;
+import "dart:core" as core;
+
+part issue45330_lib.dart;
+static method genericMethod<T extends core::Object? = dynamic>() → void {}
+static method testInMain() → dynamic {
+  self::genericMethod<<T extends invalid-type = invalid-type>() → void>();
+}
+static method main() → dynamic {}
+static method /* from org-dartlang-testcase:///issue45330_lib.dart */ testInPart() → dynamic {
+  self::genericMethod<<T extends invalid-type = invalid-type>() → void>();
+}
diff --git a/pkg/front_end/testcases/general/issue45330_lib.dart b/pkg/front_end/testcases/general/issue45330_lib.dart
new file mode 100644
index 0000000..1772937
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue45330_lib.dart
@@ -0,0 +1,36 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Long comment to increase error offset.
+// Long comment to increase error offset.
+// Long comment to increase error offset.
+// Long comment to increase error offset.
+// Long comment to increase error offset.
+// Long comment to increase error offset.
+// Long comment to increase error offset.
+// Long comment to increase error offset.
+// Long comment to increase error offset.
+// Long comment to increase error offset.
+// Long comment to increase error offset.
+// Long comment to increase error offset.
+// Long comment to increase error offset.
+// Long comment to increase error offset.
+// Long comment to increase error offset.
+// Long comment to increase error offset.
+// Long comment to increase error offset.
+// Long comment to increase error offset.
+// Long comment to increase error offset.
+// Long comment to increase error offset.
+// Long comment to increase error offset.
+// Long comment to increase error offset.
+// Long comment to increase error offset.
+// Long comment to increase error offset.
+// Long comment to increase error offset.
+// Long comment to increase error offset.
+
+part of 'issue45330.dart';
+
+testInPart() {
+  genericMethod<void Function<T extends T>()>();
+}
diff --git a/pkg/front_end/testcases/general/issue45490.dart b/pkg/front_end/testcases/general/issue45490.dart
new file mode 100644
index 0000000..dee548d
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue45490.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class A<X> {}
+
+class test<X extends A> = A<X extends A<X>>;
+
+main() {}
diff --git a/pkg/front_end/testcases/general/issue45490.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue45490.dart.textual_outline.expect
new file mode 100644
index 0000000..cf841d6
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue45490.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+class A<X> {}
+class test<X extends A> = A<X extends A<X>>with;
+main() {}
diff --git a/pkg/front_end/testcases/general/issue45490.dart.weak.expect b/pkg/front_end/testcases/general/issue45490.dart.weak.expect
new file mode 100644
index 0000000..4ebc700
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue45490.dart.weak.expect
@@ -0,0 +1,21 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/issue45490.dart:7:29: Error: Expected '>' after this.
+// class test<X extends A> = A<X extends A<X>>;
+//                             ^
+//
+// pkg/front_end/testcases/general/issue45490.dart:7:44: Error: Expected 'with' before this.
+// class test<X extends A> = A<X extends A<X>>;
+//                                            ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A<X extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::A<self::A::X%>
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general/issue45490.dart.weak.outline.expect b/pkg/front_end/testcases/general/issue45490.dart.weak.outline.expect
new file mode 100644
index 0000000..349a6cb
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue45490.dart.weak.outline.expect
@@ -0,0 +1,21 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/issue45490.dart:7:29: Error: Expected '>' after this.
+// class test<X extends A> = A<X extends A<X>>;
+//                             ^
+//
+// pkg/front_end/testcases/general/issue45490.dart:7:44: Error: Expected 'with' before this.
+// class test<X extends A> = A<X extends A<X>>;
+//                                            ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A<X extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::A<self::A::X%>
+    ;
+}
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/general/issue45490.dart.weak.transformed.expect b/pkg/front_end/testcases/general/issue45490.dart.weak.transformed.expect
new file mode 100644
index 0000000..4ebc700
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue45490.dart.weak.transformed.expect
@@ -0,0 +1,21 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/issue45490.dart:7:29: Error: Expected '>' after this.
+// class test<X extends A> = A<X extends A<X>>;
+//                             ^
+//
+// pkg/front_end/testcases/general/issue45490.dart:7:44: Error: Expected 'with' before this.
+// class test<X extends A> = A<X extends A<X>>;
+//                                            ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A<X extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::A<self::A::X%>
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general/nsm_covariance.dart b/pkg/front_end/testcases/general/nsm_covariance.dart
index d579d47..15b27f7 100644
--- a/pkg/front_end/testcases/general/nsm_covariance.dart
+++ b/pkg/front_end/testcases/general/nsm_covariance.dart
@@ -1,7 +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
+
 import 'nsm_covariance_lib.dart';
 
 abstract class D1 implements A<int>, B {}
diff --git a/pkg/front_end/testcases/general/nsm_covariance.dart.weak.outline.expect b/pkg/front_end/testcases/general/nsm_covariance.dart.weak.outline.expect
index b434cfe..0376936 100644
--- a/pkg/front_end/testcases/general/nsm_covariance.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/general/nsm_covariance.dart.weak.outline.expect
@@ -219,44 +219,44 @@
 
 
 Extra constant evaluation status:
-Evaluated: StaticGet @ org-dartlang-testcase:///nsm_covariance.dart:12:4 -> InstanceConstant(const _Override{})
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///nsm_covariance.dart:11:7 -> SymbolConstant(#_method1)
-Evaluated: ListLiteral @ org-dartlang-testcase:///nsm_covariance.dart:11:7 -> ListConstant(const <Type*>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///nsm_covariance.dart:11:7 -> InstanceConstant(const _ImmutableMap<Symbol*, dynamic>{_ImmutableMap._kvPairs: const <dynamic>[]})
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///nsm_covariance.dart:11:7 -> SymbolConstant(#_method2)
-Evaluated: ListLiteral @ org-dartlang-testcase:///nsm_covariance.dart:11:7 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-testcase:///nsm_covariance.dart:11:7 -> ListConstant(const <dynamic>[])
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///nsm_covariance.dart:11:7 -> SymbolConstant(#a)
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///nsm_covariance.dart:11:7 -> SymbolConstant(#b)
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///nsm_covariance.dart:11:7 -> SymbolConstant(#c)
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///nsm_covariance.dart:11:7 -> SymbolConstant(#d)
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///nsm_covariance.dart:11:7 -> SymbolConstant(#_method3)
-Evaluated: ListLiteral @ org-dartlang-testcase:///nsm_covariance.dart:11:7 -> ListConstant(const <Type*>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///nsm_covariance.dart:11:7 -> InstanceConstant(const _ImmutableMap<Symbol*, dynamic>{_ImmutableMap._kvPairs: const <dynamic>[]})
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///nsm_covariance.dart:11:7 -> SymbolConstant(#_method4)
-Evaluated: ListLiteral @ org-dartlang-testcase:///nsm_covariance.dart:11:7 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-testcase:///nsm_covariance.dart:11:7 -> ListConstant(const <dynamic>[])
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///nsm_covariance.dart:11:7 -> SymbolConstant(#a)
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///nsm_covariance.dart:11:7 -> SymbolConstant(#b)
-Evaluated: StaticGet @ org-dartlang-testcase:///nsm_covariance.dart:17:4 -> InstanceConstant(const _Override{})
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///nsm_covariance.dart:16:7 -> SymbolConstant(#_method1)
-Evaluated: ListLiteral @ org-dartlang-testcase:///nsm_covariance.dart:16:7 -> ListConstant(const <Type*>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///nsm_covariance.dart:16:7 -> InstanceConstant(const _ImmutableMap<Symbol*, dynamic>{_ImmutableMap._kvPairs: const <dynamic>[]})
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///nsm_covariance.dart:16:7 -> SymbolConstant(#_method2)
-Evaluated: ListLiteral @ org-dartlang-testcase:///nsm_covariance.dart:16:7 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-testcase:///nsm_covariance.dart:16:7 -> ListConstant(const <dynamic>[])
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///nsm_covariance.dart:16:7 -> SymbolConstant(#a)
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///nsm_covariance.dart:16:7 -> SymbolConstant(#b)
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///nsm_covariance.dart:16:7 -> SymbolConstant(#c)
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///nsm_covariance.dart:16:7 -> SymbolConstant(#d)
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///nsm_covariance.dart:16:7 -> SymbolConstant(#_method3)
-Evaluated: ListLiteral @ org-dartlang-testcase:///nsm_covariance.dart:16:7 -> ListConstant(const <Type*>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///nsm_covariance.dart:16:7 -> InstanceConstant(const _ImmutableMap<Symbol*, dynamic>{_ImmutableMap._kvPairs: const <dynamic>[]})
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///nsm_covariance.dart:16:7 -> SymbolConstant(#_method4)
-Evaluated: ListLiteral @ org-dartlang-testcase:///nsm_covariance.dart:16:7 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-testcase:///nsm_covariance.dart:16:7 -> ListConstant(const <dynamic>[])
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///nsm_covariance.dart:16:7 -> SymbolConstant(#a)
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///nsm_covariance.dart:16:7 -> SymbolConstant(#b)
+Evaluated: StaticGet @ org-dartlang-testcase:///nsm_covariance.dart:14:4 -> InstanceConstant(const _Override{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///nsm_covariance.dart:13:7 -> SymbolConstant(#_method1)
+Evaluated: ListLiteral @ org-dartlang-testcase:///nsm_covariance.dart:13:7 -> ListConstant(const <Type*>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///nsm_covariance.dart:13:7 -> InstanceConstant(const _ImmutableMap<Symbol*, dynamic>{_ImmutableMap._kvPairs: const <dynamic>[]})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///nsm_covariance.dart:13:7 -> SymbolConstant(#_method2)
+Evaluated: ListLiteral @ org-dartlang-testcase:///nsm_covariance.dart:13:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///nsm_covariance.dart:13:7 -> ListConstant(const <dynamic>[])
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///nsm_covariance.dart:13:7 -> SymbolConstant(#a)
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///nsm_covariance.dart:13:7 -> SymbolConstant(#b)
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///nsm_covariance.dart:13:7 -> SymbolConstant(#c)
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///nsm_covariance.dart:13:7 -> SymbolConstant(#d)
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///nsm_covariance.dart:13:7 -> SymbolConstant(#_method3)
+Evaluated: ListLiteral @ org-dartlang-testcase:///nsm_covariance.dart:13:7 -> ListConstant(const <Type*>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///nsm_covariance.dart:13:7 -> InstanceConstant(const _ImmutableMap<Symbol*, dynamic>{_ImmutableMap._kvPairs: const <dynamic>[]})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///nsm_covariance.dart:13:7 -> SymbolConstant(#_method4)
+Evaluated: ListLiteral @ org-dartlang-testcase:///nsm_covariance.dart:13:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///nsm_covariance.dart:13:7 -> ListConstant(const <dynamic>[])
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///nsm_covariance.dart:13:7 -> SymbolConstant(#a)
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///nsm_covariance.dart:13:7 -> SymbolConstant(#b)
+Evaluated: StaticGet @ org-dartlang-testcase:///nsm_covariance.dart:19:4 -> InstanceConstant(const _Override{})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///nsm_covariance.dart:18:7 -> SymbolConstant(#_method1)
+Evaluated: ListLiteral @ org-dartlang-testcase:///nsm_covariance.dart:18:7 -> ListConstant(const <Type*>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///nsm_covariance.dart:18:7 -> InstanceConstant(const _ImmutableMap<Symbol*, dynamic>{_ImmutableMap._kvPairs: const <dynamic>[]})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///nsm_covariance.dart:18:7 -> SymbolConstant(#_method2)
+Evaluated: ListLiteral @ org-dartlang-testcase:///nsm_covariance.dart:18:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///nsm_covariance.dart:18:7 -> ListConstant(const <dynamic>[])
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///nsm_covariance.dart:18:7 -> SymbolConstant(#a)
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///nsm_covariance.dart:18:7 -> SymbolConstant(#b)
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///nsm_covariance.dart:18:7 -> SymbolConstant(#c)
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///nsm_covariance.dart:18:7 -> SymbolConstant(#d)
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///nsm_covariance.dart:18:7 -> SymbolConstant(#_method3)
+Evaluated: ListLiteral @ org-dartlang-testcase:///nsm_covariance.dart:18:7 -> ListConstant(const <Type*>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///nsm_covariance.dart:18:7 -> InstanceConstant(const _ImmutableMap<Symbol*, dynamic>{_ImmutableMap._kvPairs: const <dynamic>[]})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///nsm_covariance.dart:18:7 -> SymbolConstant(#_method4)
+Evaluated: ListLiteral @ org-dartlang-testcase:///nsm_covariance.dart:18:7 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///nsm_covariance.dart:18:7 -> ListConstant(const <dynamic>[])
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///nsm_covariance.dart:18:7 -> SymbolConstant(#a)
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///nsm_covariance.dart:18:7 -> SymbolConstant(#b)
 Evaluated: StaticGet @ org-dartlang-testcase:///nsm_covariance_lib.dart:24:4 -> InstanceConstant(const _Override{})
 Evaluated: SymbolLiteral @ org-dartlang-testcase:///nsm_covariance_lib.dart:23:7 -> SymbolConstant(#_method1)
 Evaluated: ListLiteral @ org-dartlang-testcase:///nsm_covariance_lib.dart:23:7 -> ListConstant(const <Type*>[])
diff --git a/pkg/front_end/testcases/general/null_check_type_variable_type.dart b/pkg/front_end/testcases/general/null_check_type_variable_type.dart
new file mode 100644
index 0000000..30f0312
--- /dev/null
+++ b/pkg/front_end/testcases/general/null_check_type_variable_type.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for 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 Element {}
+
+class Class<E extends Element?> {
+  E? element;
+
+  Class(this.element);
+
+  void setElement(E? element) {
+    if (this.element != element) {
+      this.element = element;
+      Set<Element> elements = new Set<Element>();
+      if (element != null) {
+        elements.add(element);
+      }
+      if (this.element != null) {
+        elements.add(this.element!);
+      }
+    }
+  }
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/null_check_type_variable_type.dart.textual_outline.expect b/pkg/front_end/testcases/general/null_check_type_variable_type.dart.textual_outline.expect
new file mode 100644
index 0000000..e380d41
--- /dev/null
+++ b/pkg/front_end/testcases/general/null_check_type_variable_type.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+class Element {}
+
+class Class<E extends Element?> {
+  E? element;
+  Class(this.element);
+  void setElement(E? element) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/null_check_type_variable_type.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/null_check_type_variable_type.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c1b9d90
--- /dev/null
+++ b/pkg/front_end/testcases/general/null_check_type_variable_type.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+class Class<E extends Element?> {
+  Class(this.element);
+  E? element;
+  void setElement(E? element) {}
+}
+
+class Element {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/null_check_type_variable_type.dart.weak.expect b/pkg/front_end/testcases/general/null_check_type_variable_type.dart.weak.expect
new file mode 100644
index 0000000..6972fb1
--- /dev/null
+++ b/pkg/front_end/testcases/general/null_check_type_variable_type.dart.weak.expect
@@ -0,0 +1,29 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:collection" as col;
+
+class Element extends core::Object {
+  synthetic constructor •() → self::Element
+    : super core::Object::•()
+    ;
+}
+class Class<E extends self::Element? = self::Element?> extends core::Object {
+  generic-covariant-impl field self::Class::E? element;
+  constructor •(self::Class::E? element) → self::Class<self::Class::E%>
+    : self::Class::element = element, super core::Object::•()
+    ;
+  method setElement(generic-covariant-impl self::Class::E? element) → void {
+    if(!this.{self::Class::element}.{core::Object::==}(element)) {
+      this.{self::Class::element} = element;
+      core::Set<self::Element> elements = col::LinkedHashSet::•<self::Element>();
+      if(!element.{core::Object::==}(null)) {
+        elements.{core::Set::add}(element{self::Class::E% & self::Element /* '%' & '!' = '!' */});
+      }
+      if(!this.{self::Class::element}.{core::Object::==}(null)) {
+        elements.{core::Set::add}(this.{self::Class::element}!);
+      }
+    }
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general/null_check_type_variable_type.dart.weak.outline.expect b/pkg/front_end/testcases/general/null_check_type_variable_type.dart.weak.outline.expect
new file mode 100644
index 0000000..199055c
--- /dev/null
+++ b/pkg/front_end/testcases/general/null_check_type_variable_type.dart.weak.outline.expect
@@ -0,0 +1,17 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class Element extends core::Object {
+  synthetic constructor •() → self::Element
+    ;
+}
+class Class<E extends self::Element? = self::Element?> extends core::Object {
+  generic-covariant-impl field self::Class::E? element;
+  constructor •(self::Class::E? element) → self::Class<self::Class::E%>
+    ;
+  method setElement(generic-covariant-impl self::Class::E? element) → void
+    ;
+}
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/general/null_check_type_variable_type.dart.weak.transformed.expect b/pkg/front_end/testcases/general/null_check_type_variable_type.dart.weak.transformed.expect
new file mode 100644
index 0000000..6405a73
--- /dev/null
+++ b/pkg/front_end/testcases/general/null_check_type_variable_type.dart.weak.transformed.expect
@@ -0,0 +1,29 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:collection" as col;
+
+class Element extends core::Object {
+  synthetic constructor •() → self::Element
+    : super core::Object::•()
+    ;
+}
+class Class<E extends self::Element? = self::Element?> extends core::Object {
+  generic-covariant-impl field self::Class::E? element;
+  constructor •(self::Class::E? element) → self::Class<self::Class::E%>
+    : self::Class::element = element, super core::Object::•()
+    ;
+  method setElement(generic-covariant-impl self::Class::E? element) → void {
+    if(!this.{self::Class::element}.{core::Object::==}(element)) {
+      this.{self::Class::element} = element;
+      core::Set<self::Element> elements = new col::_CompactLinkedHashSet::•<self::Element>();
+      if(!element.{core::Object::==}(null)) {
+        elements.{core::Set::add}(element{self::Class::E% & self::Element /* '%' & '!' = '!' */});
+      }
+      if(!this.{self::Class::element}.{core::Object::==}(null)) {
+        elements.{core::Set::add}(this.{self::Class::element}!);
+      }
+    }
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general/qualified.dart.weak.expect b/pkg/front_end/testcases/general/qualified.dart.weak.expect
index a51969d..b829051 100644
--- a/pkg/front_end/testcases/general/qualified.dart.weak.expect
+++ b/pkg/front_end/testcases/general/qualified.dart.weak.expect
@@ -17,7 +17,7 @@
 //   lib.Missing method() {}
 //   ^^^^^^^^^^^
 //
-// pkg/front_end/testcases/general/qualified.dart:18:7: Error: The type 'lib.VoidFunction' can't be used as supertype.
+// pkg/front_end/testcases/general/qualified.dart:18:7: Error: The type 'lib.VoidFunction' which is an alias of 'void Function()' can't be used as supertype.
 // class IllegalSupertype extends lib.VoidFunction {}
 //       ^
 // pkg/front_end/testcases/general/qualified_lib.dart:27:9: Context: The issue arises via this type alias.
diff --git a/pkg/front_end/testcases/general/qualified.dart.weak.outline.expect b/pkg/front_end/testcases/general/qualified.dart.weak.outline.expect
index fcf8ecc..2102d04 100644
--- a/pkg/front_end/testcases/general/qualified.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/general/qualified.dart.weak.outline.expect
@@ -17,7 +17,7 @@
 //   lib.Missing method() {}
 //   ^^^^^^^^^^^
 //
-// pkg/front_end/testcases/general/qualified.dart:18:7: Error: The type 'lib.VoidFunction' can't be used as supertype.
+// pkg/front_end/testcases/general/qualified.dart:18:7: Error: The type 'lib.VoidFunction' which is an alias of 'void Function()' can't be used as supertype.
 // class IllegalSupertype extends lib.VoidFunction {}
 //       ^
 // pkg/front_end/testcases/general/qualified_lib.dart:27:9: Context: The issue arises via this type alias.
diff --git a/pkg/front_end/testcases/general/qualified.dart.weak.transformed.expect b/pkg/front_end/testcases/general/qualified.dart.weak.transformed.expect
index 25de173..003ca00 100644
--- a/pkg/front_end/testcases/general/qualified.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general/qualified.dart.weak.transformed.expect
@@ -17,7 +17,7 @@
 //   lib.Missing method() {}
 //   ^^^^^^^^^^^
 //
-// pkg/front_end/testcases/general/qualified.dart:18:7: Error: The type 'lib.VoidFunction' can't be used as supertype.
+// pkg/front_end/testcases/general/qualified.dart:18:7: Error: The type 'lib.VoidFunction' which is an alias of 'void Function()' can't be used as supertype.
 // class IllegalSupertype extends lib.VoidFunction {}
 //       ^
 // pkg/front_end/testcases/general/qualified_lib.dart:27:9: Context: The issue arises via this type alias.
diff --git a/pkg/front_end/testcases/general/type_variable_annotations.dart b/pkg/front_end/testcases/general/type_variable_annotations.dart
new file mode 100644
index 0000000..0f9233b
--- /dev/null
+++ b/pkg/front_end/testcases/general/type_variable_annotations.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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();
+}
+
+void method<@A() T>() {}
+
+typedef F<@A() T> = void Function(T);
+
+class Class<@A() T> {
+  void method<@A() T>() {
+    void local<@A() T>() {}
+  }
+}
+
+extension Extension<@A() T> on T {
+  void method<@A() T>() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/type_variable_annotations.dart.textual_outline.expect b/pkg/front_end/testcases/general/type_variable_annotations.dart.textual_outline.expect
new file mode 100644
index 0000000..dd1805b
--- /dev/null
+++ b/pkg/front_end/testcases/general/type_variable_annotations.dart.textual_outline.expect
@@ -0,0 +1,16 @@
+class A {
+  const A();
+}
+
+void method<@A() T>() {}
+typedef F<@A() T> = void Function(T);
+
+class Class<@A() T> {
+  void method<@A() T>() {}
+}
+
+extension Extension<@A() T> on T {
+  void method<@A() T>() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/type_variable_annotations.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/type_variable_annotations.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a640304
--- /dev/null
+++ b/pkg/front_end/testcases/general/type_variable_annotations.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+class A {
+  const A();
+}
+
+class Class<@A() T> {
+  void method<@A() T>() {}
+}
+
+extension Extension<@A() T> on T {
+  void method<@A() T>() {}
+}
+
+main() {}
+typedef F<@A() T> = void Function(T);
+void method<@A() T>() {}
diff --git a/pkg/front_end/testcases/general/type_variable_annotations.dart.weak.expect b/pkg/front_end/testcases/general/type_variable_annotations.dart.weak.expect
new file mode 100644
index 0000000..21c0f72
--- /dev/null
+++ b/pkg/front_end/testcases/general/type_variable_annotations.dart.weak.expect
@@ -0,0 +1,37 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+typedef F<@#C1 contravariant T extends core::Object? = dynamic> = (T%) → void;
+class A extends core::Object /*hasConstConstructor*/  {
+  const constructor •() → self::A
+    : super core::Object::•()
+    ;
+}
+class Class<@#C1 T extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::Class<self::Class::T%>
+    : super core::Object::•()
+    ;
+  method method<@#C1 T extends core::Object? = dynamic>() → void {
+    function local<@#C1 T extends core::Object? = dynamic>() → void {}
+  }
+}
+extension Extension<@#C1 T extends core::Object? = dynamic> on T% {
+  method method = self::Extension|method;
+  tearoff method = self::Extension|get#method;
+}
+static method method<@#C1 T extends core::Object? = dynamic>() → void {}
+static method Extension|method<#T extends core::Object? = dynamic, @#C1 T extends core::Object? = dynamic>(lowered final self::Extension|method::#T% #this) → void {}
+static method Extension|get#method<#T extends core::Object? = dynamic>(lowered final self::Extension|get#method::#T% #this) → <T extends core::Object? = dynamic>() → void
+  return <T extends core::Object? = dynamic>() → void => self::Extension|method<self::Extension|get#method::#T%, T%>(#this);
+static method main() → dynamic {}
+
+constants  {
+  #C1 = self::A {}
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///type_variable_annotations.dart:
+- A. (from org-dartlang-testcase:///type_variable_annotations.dart:6:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/general/type_variable_annotations.dart.weak.outline.expect b/pkg/front_end/testcases/general/type_variable_annotations.dart.weak.outline.expect
new file mode 100644
index 0000000..503996e
--- /dev/null
+++ b/pkg/front_end/testcases/general/type_variable_annotations.dart.weak.outline.expect
@@ -0,0 +1,38 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+typedef F<@self::A::•() contravariant T extends core::Object? = dynamic> = (T%) → void;
+class A extends core::Object /*hasConstConstructor*/  {
+  const constructor •() → self::A
+    : super core::Object::•()
+    ;
+}
+class Class<@self::A::•() T extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::Class<self::Class::T%>
+    ;
+  method method<@self::A::•() T extends core::Object? = dynamic>() → void
+    ;
+}
+extension Extension<@self::A::•() T extends core::Object? = dynamic> on T% {
+  method method = self::Extension|method;
+  tearoff method = self::Extension|get#method;
+}
+static method method<@self::A::•() T extends core::Object? = dynamic>() → void
+  ;
+static method Extension|method<#T extends core::Object? = dynamic, @self::A::•() T extends core::Object? = dynamic>(lowered final self::Extension|method::#T% #this) → void
+  ;
+static method Extension|get#method<#T extends core::Object? = dynamic>(lowered final self::Extension|get#method::#T% #this) → <T extends core::Object? = dynamic>() → void
+  return <T extends core::Object? = dynamic>() → void => self::Extension|method<self::Extension|get#method::#T%, T%>(#this);
+static method main() → dynamic
+  ;
+
+
+Extra constant evaluation status:
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///type_variable_annotations.dart:11:12 -> InstanceConstant(const A{})
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///type_variable_annotations.dart:13:14 -> InstanceConstant(const A{})
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///type_variable_annotations.dart:14:16 -> InstanceConstant(const A{})
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///type_variable_annotations.dart:19:22 -> InstanceConstant(const A{})
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///type_variable_annotations.dart:9:14 -> InstanceConstant(const A{})
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///type_variable_annotations.dart:20:16 -> InstanceConstant(const A{})
+Extra constant evaluation: evaluated: 9, effectively constant: 6
diff --git a/pkg/front_end/testcases/general/type_variable_annotations.dart.weak.transformed.expect b/pkg/front_end/testcases/general/type_variable_annotations.dart.weak.transformed.expect
new file mode 100644
index 0000000..21c0f72
--- /dev/null
+++ b/pkg/front_end/testcases/general/type_variable_annotations.dart.weak.transformed.expect
@@ -0,0 +1,37 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+typedef F<@#C1 contravariant T extends core::Object? = dynamic> = (T%) → void;
+class A extends core::Object /*hasConstConstructor*/  {
+  const constructor •() → self::A
+    : super core::Object::•()
+    ;
+}
+class Class<@#C1 T extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::Class<self::Class::T%>
+    : super core::Object::•()
+    ;
+  method method<@#C1 T extends core::Object? = dynamic>() → void {
+    function local<@#C1 T extends core::Object? = dynamic>() → void {}
+  }
+}
+extension Extension<@#C1 T extends core::Object? = dynamic> on T% {
+  method method = self::Extension|method;
+  tearoff method = self::Extension|get#method;
+}
+static method method<@#C1 T extends core::Object? = dynamic>() → void {}
+static method Extension|method<#T extends core::Object? = dynamic, @#C1 T extends core::Object? = dynamic>(lowered final self::Extension|method::#T% #this) → void {}
+static method Extension|get#method<#T extends core::Object? = dynamic>(lowered final self::Extension|get#method::#T% #this) → <T extends core::Object? = dynamic>() → void
+  return <T extends core::Object? = dynamic>() → void => self::Extension|method<self::Extension|get#method::#T%, T%>(#this);
+static method main() → dynamic {}
+
+constants  {
+  #C1 = self::A {}
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///type_variable_annotations.dart:
+- A. (from org-dartlang-testcase:///type_variable_annotations.dart:6:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/general/typedef_annotation.dart b/pkg/front_end/testcases/general/typedef_annotation.dart
new file mode 100644
index 0000000..fe8f57d
--- /dev/null
+++ b/pkg/front_end/testcases/general/typedef_annotation.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class A {
+  const A();
+}
+
+@A()
+typedef F = void Function();
+
+@A()
+typedef void G();
+
+main() {}
diff --git a/pkg/front_end/testcases/general/typedef_annotation.dart.textual_outline.expect b/pkg/front_end/testcases/general/typedef_annotation.dart.textual_outline.expect
new file mode 100644
index 0000000..796a732
--- /dev/null
+++ b/pkg/front_end/testcases/general/typedef_annotation.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+class A {
+  const A();
+}
+
+@A()
+typedef F = void Function();
+@A()
+typedef void G();
+main() {}
diff --git a/pkg/front_end/testcases/general/typedef_annotation.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/typedef_annotation.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a4408c3
--- /dev/null
+++ b/pkg/front_end/testcases/general/typedef_annotation.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+class A {
+  const A();
+}
+
+main() {}
+@A()
+typedef F = void Function();
+@A()
+typedef void G();
diff --git a/pkg/front_end/testcases/general/typedef_annotation.dart.weak.expect b/pkg/front_end/testcases/general/typedef_annotation.dart.weak.expect
new file mode 100644
index 0000000..3c94843
--- /dev/null
+++ b/pkg/front_end/testcases/general/typedef_annotation.dart.weak.expect
@@ -0,0 +1,24 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+@#C1
+typedef F = () → void;
+@#C1
+typedef G = () → void;
+class A extends core::Object /*hasConstConstructor*/  {
+  const constructor •() → self::A
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {}
+
+constants  {
+  #C1 = self::A {}
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///typedef_annotation.dart:
+- A. (from org-dartlang-testcase:///typedef_annotation.dart:6:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/general/typedef_annotation.dart.weak.outline.expect b/pkg/front_end/testcases/general/typedef_annotation.dart.weak.outline.expect
new file mode 100644
index 0000000..280c14f
--- /dev/null
+++ b/pkg/front_end/testcases/general/typedef_annotation.dart.weak.outline.expect
@@ -0,0 +1,21 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+@self::A::•()
+typedef F = () → void;
+@self::A::•()
+typedef G = () → void;
+class A extends core::Object /*hasConstConstructor*/  {
+  const constructor •() → self::A
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic
+  ;
+
+
+Extra constant evaluation status:
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///typedef_annotation.dart:9:2 -> InstanceConstant(const A{})
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///typedef_annotation.dart:12:2 -> InstanceConstant(const A{})
+Extra constant evaluation: evaluated: 2, effectively constant: 2
diff --git a/pkg/front_end/testcases/general/typedef_annotation.dart.weak.transformed.expect b/pkg/front_end/testcases/general/typedef_annotation.dart.weak.transformed.expect
new file mode 100644
index 0000000..3c94843
--- /dev/null
+++ b/pkg/front_end/testcases/general/typedef_annotation.dart.weak.transformed.expect
@@ -0,0 +1,24 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+@#C1
+typedef F = () → void;
+@#C1
+typedef G = () → void;
+class A extends core::Object /*hasConstConstructor*/  {
+  const constructor •() → self::A
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {}
+
+constants  {
+  #C1 = self::A {}
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///typedef_annotation.dart:
+- A. (from org-dartlang-testcase:///typedef_annotation.dart:6:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart b/pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart
new file mode 100644
index 0000000..afca06a
--- /dev/null
+++ b/pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class A<T> {
+  const A(o);
+}
+
+void Function<@A<int>() T>(T)? f;
+
+// TODO(johnniwinther): Report errors on annotations here.
+typedef F = void Function<@A<bool>() T>(T);
+
+typedef void G<@A<dynamic>() T>(T t);
+
+void method1<@A<String>() T>(T t) {}
+
+void method2(void Function<@A<num>() T>(T) f) {}
+
+// TODO(johnniwinther): Report errors on annotations here.
+class Class<T extends void Function<@A<void>() S>(S)> {}
+
+main() {
+  void local<@A<double>() T>(T t) {}
+
+  void Function<@A<int>() T>(T)? f;
+}
diff --git a/pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart.strong.expect b/pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart.strong.expect
new file mode 100644
index 0000000..6ab9190
--- /dev/null
+++ b/pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart.strong.expect
@@ -0,0 +1,74 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart:14:27: Error: Too few positional arguments: 1 required, 0 given.
+// typedef void G<@A<dynamic>() T>(T t);
+//                           ^
+// pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart:6:9: Context: Found this candidate, but the arguments don't match.
+//   const A(o);
+//         ^
+//
+// pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart:16:24: Error: Too few positional arguments: 1 required, 0 given.
+// void method1<@A<String>() T>(T t) {}
+//                        ^
+// pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart:6:9: Context: Found this candidate, but the arguments don't match.
+//   const A(o);
+//         ^
+//
+// pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart:9:22: Error: Too few positional arguments: 1 required, 0 given.
+// void Function<@A<int>() T>(T)? f;
+//                      ^
+// pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart:6:9: Context: Found this candidate, but the arguments don't match.
+//   const A(o);
+//         ^
+//
+// pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart:18:35: Error: Too few positional arguments: 1 required, 0 given.
+// void method2(void Function<@A<num>() T>(T) f) {}
+//                                   ^
+// pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart:6:9: Context: Found this candidate, but the arguments don't match.
+//   const A(o);
+//         ^
+//
+// pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart:24:24: Error: Too few positional arguments: 1 required, 0 given.
+//   void local<@A<double>() T>(T t) {}
+//                        ^
+// pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart:6:9: Context: Found this candidate, but the arguments don't match.
+//   const A(o);
+//         ^
+//
+// pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart:26:24: Error: Too few positional arguments: 1 required, 0 given.
+//   void Function<@A<int>() T>(T)? f;
+//                        ^
+// pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart:6:9: Context: Found this candidate, but the arguments don't match.
+//   const A(o);
+//         ^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef F = <T extends core::Object? = dynamic>(T%) → void;
+typedef G<@invalid-expression "pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart:14:27: Error: Too few positional arguments: 1 required, 0 given.
+typedef void G<@A<dynamic>() T>(T t);
+                          ^" contravariant T extends core::Object? = dynamic> = (T%) → void;
+class A<T extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/  {
+  const constructor •(dynamic o) → self::A<self::A::T%>
+    : super core::Object::•()
+    ;
+}
+class Class<T extends <S extends core::Object? = dynamic>(S%) → void = <S extends core::Object? = dynamic>(S%) → void> extends core::Object {
+  synthetic constructor •() → self::Class<self::Class::T>
+    : super core::Object::•()
+    ;
+}
+static field <T extends core::Object? = dynamic>(T%) →? void f;
+static method method1<@invalid-expression "pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart:16:24: Error: Too few positional arguments: 1 required, 0 given.
+void method1<@A<String>() T>(T t) {}
+                       ^" T extends core::Object? = dynamic>(self::method1::T% t) → void {}
+static method method2(<T extends core::Object? = dynamic>(T%) → void f) → void {}
+static method main() → dynamic {
+  function local<@invalid-expression "pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart:24:24: Error: Too few positional arguments: 1 required, 0 given.
+  void local<@A<double>() T>(T t) {}
+                       ^" T extends core::Object? = dynamic>(T% t) → void {}
+  <T extends core::Object? = dynamic>(T%) →? void f;
+}
diff --git a/pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart.strong.transformed.expect b/pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart.strong.transformed.expect
new file mode 100644
index 0000000..6ab9190
--- /dev/null
+++ b/pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart.strong.transformed.expect
@@ -0,0 +1,74 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart:14:27: Error: Too few positional arguments: 1 required, 0 given.
+// typedef void G<@A<dynamic>() T>(T t);
+//                           ^
+// pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart:6:9: Context: Found this candidate, but the arguments don't match.
+//   const A(o);
+//         ^
+//
+// pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart:16:24: Error: Too few positional arguments: 1 required, 0 given.
+// void method1<@A<String>() T>(T t) {}
+//                        ^
+// pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart:6:9: Context: Found this candidate, but the arguments don't match.
+//   const A(o);
+//         ^
+//
+// pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart:9:22: Error: Too few positional arguments: 1 required, 0 given.
+// void Function<@A<int>() T>(T)? f;
+//                      ^
+// pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart:6:9: Context: Found this candidate, but the arguments don't match.
+//   const A(o);
+//         ^
+//
+// pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart:18:35: Error: Too few positional arguments: 1 required, 0 given.
+// void method2(void Function<@A<num>() T>(T) f) {}
+//                                   ^
+// pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart:6:9: Context: Found this candidate, but the arguments don't match.
+//   const A(o);
+//         ^
+//
+// pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart:24:24: Error: Too few positional arguments: 1 required, 0 given.
+//   void local<@A<double>() T>(T t) {}
+//                        ^
+// pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart:6:9: Context: Found this candidate, but the arguments don't match.
+//   const A(o);
+//         ^
+//
+// pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart:26:24: Error: Too few positional arguments: 1 required, 0 given.
+//   void Function<@A<int>() T>(T)? f;
+//                        ^
+// pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart:6:9: Context: Found this candidate, but the arguments don't match.
+//   const A(o);
+//         ^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef F = <T extends core::Object? = dynamic>(T%) → void;
+typedef G<@invalid-expression "pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart:14:27: Error: Too few positional arguments: 1 required, 0 given.
+typedef void G<@A<dynamic>() T>(T t);
+                          ^" contravariant T extends core::Object? = dynamic> = (T%) → void;
+class A<T extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/  {
+  const constructor •(dynamic o) → self::A<self::A::T%>
+    : super core::Object::•()
+    ;
+}
+class Class<T extends <S extends core::Object? = dynamic>(S%) → void = <S extends core::Object? = dynamic>(S%) → void> extends core::Object {
+  synthetic constructor •() → self::Class<self::Class::T>
+    : super core::Object::•()
+    ;
+}
+static field <T extends core::Object? = dynamic>(T%) →? void f;
+static method method1<@invalid-expression "pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart:16:24: Error: Too few positional arguments: 1 required, 0 given.
+void method1<@A<String>() T>(T t) {}
+                       ^" T extends core::Object? = dynamic>(self::method1::T% t) → void {}
+static method method2(<T extends core::Object? = dynamic>(T%) → void f) → void {}
+static method main() → dynamic {
+  function local<@invalid-expression "pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart:24:24: Error: Too few positional arguments: 1 required, 0 given.
+  void local<@A<double>() T>(T t) {}
+                       ^" T extends core::Object? = dynamic>(T% t) → void {}
+  <T extends core::Object? = dynamic>(T%) →? void f;
+}
diff --git a/pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart.textual_outline.expect b/pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart.textual_outline.expect
new file mode 100644
index 0000000..63866c4
--- /dev/null
+++ b/pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+class A<T> {
+  const A(o);
+}
+
+void Function<@A<int>() T>(T)? f;
+typedef F = void Function<@A<bool>() T>(T);
+typedef void G<@A<dynamic>() T>(T t);
+void method1<@A<String>() T>(T t) {}
+void method2(void Function<@A<num>() T>(T) f) {}
+
+class Class<T extends void Function<@A<void>() S>(S)> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..7b92378
--- /dev/null
+++ b/pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+class A<T> {
+  const A(o);
+}
+
+class Class<T extends void Function<@A<void>() S>(S)> {}
+
+main() {}
+typedef F = void Function<@A<bool>() T>(T);
+typedef void G<@A<dynamic>() T>(T t);
+void Function<@A<int>() T>(T)? f;
+void method1<@A<String>() T>(T t) {}
+void method2(void Function<@A<num>() T>(T) f) {}
diff --git a/pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart.weak.expect b/pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart.weak.expect
new file mode 100644
index 0000000..6ab9190
--- /dev/null
+++ b/pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart.weak.expect
@@ -0,0 +1,74 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart:14:27: Error: Too few positional arguments: 1 required, 0 given.
+// typedef void G<@A<dynamic>() T>(T t);
+//                           ^
+// pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart:6:9: Context: Found this candidate, but the arguments don't match.
+//   const A(o);
+//         ^
+//
+// pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart:16:24: Error: Too few positional arguments: 1 required, 0 given.
+// void method1<@A<String>() T>(T t) {}
+//                        ^
+// pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart:6:9: Context: Found this candidate, but the arguments don't match.
+//   const A(o);
+//         ^
+//
+// pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart:9:22: Error: Too few positional arguments: 1 required, 0 given.
+// void Function<@A<int>() T>(T)? f;
+//                      ^
+// pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart:6:9: Context: Found this candidate, but the arguments don't match.
+//   const A(o);
+//         ^
+//
+// pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart:18:35: Error: Too few positional arguments: 1 required, 0 given.
+// void method2(void Function<@A<num>() T>(T) f) {}
+//                                   ^
+// pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart:6:9: Context: Found this candidate, but the arguments don't match.
+//   const A(o);
+//         ^
+//
+// pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart:24:24: Error: Too few positional arguments: 1 required, 0 given.
+//   void local<@A<double>() T>(T t) {}
+//                        ^
+// pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart:6:9: Context: Found this candidate, but the arguments don't match.
+//   const A(o);
+//         ^
+//
+// pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart:26:24: Error: Too few positional arguments: 1 required, 0 given.
+//   void Function<@A<int>() T>(T)? f;
+//                        ^
+// pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart:6:9: Context: Found this candidate, but the arguments don't match.
+//   const A(o);
+//         ^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef F = <T extends core::Object? = dynamic>(T%) → void;
+typedef G<@invalid-expression "pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart:14:27: Error: Too few positional arguments: 1 required, 0 given.
+typedef void G<@A<dynamic>() T>(T t);
+                          ^" contravariant T extends core::Object? = dynamic> = (T%) → void;
+class A<T extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/  {
+  const constructor •(dynamic o) → self::A<self::A::T%>
+    : super core::Object::•()
+    ;
+}
+class Class<T extends <S extends core::Object? = dynamic>(S%) → void = <S extends core::Object? = dynamic>(S%) → void> extends core::Object {
+  synthetic constructor •() → self::Class<self::Class::T>
+    : super core::Object::•()
+    ;
+}
+static field <T extends core::Object? = dynamic>(T%) →? void f;
+static method method1<@invalid-expression "pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart:16:24: Error: Too few positional arguments: 1 required, 0 given.
+void method1<@A<String>() T>(T t) {}
+                       ^" T extends core::Object? = dynamic>(self::method1::T% t) → void {}
+static method method2(<T extends core::Object? = dynamic>(T%) → void f) → void {}
+static method main() → dynamic {
+  function local<@invalid-expression "pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart:24:24: Error: Too few positional arguments: 1 required, 0 given.
+  void local<@A<double>() T>(T t) {}
+                       ^" T extends core::Object? = dynamic>(T% t) → void {}
+  <T extends core::Object? = dynamic>(T%) →? void f;
+}
diff --git a/pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart.weak.outline.expect b/pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart.weak.outline.expect
new file mode 100644
index 0000000..edc7f22
--- /dev/null
+++ b/pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart.weak.outline.expect
@@ -0,0 +1,43 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart:14:27: Error: Too few positional arguments: 1 required, 0 given.
+// typedef void G<@A<dynamic>() T>(T t);
+//                           ^
+// pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart:6:9: Context: Found this candidate, but the arguments don't match.
+//   const A(o);
+//         ^
+//
+// pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart:16:24: Error: Too few positional arguments: 1 required, 0 given.
+// void method1<@A<String>() T>(T t) {}
+//                        ^
+// pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart:6:9: Context: Found this candidate, but the arguments don't match.
+//   const A(o);
+//         ^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef F = <T extends core::Object? = dynamic>(T%) → void;
+typedef G<@invalid-expression "pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart:14:27: Error: Too few positional arguments: 1 required, 0 given.
+typedef void G<@A<dynamic>() T>(T t);
+                          ^" contravariant T extends core::Object? = dynamic> = (T%) → void;
+class A<T extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/  {
+  const constructor •(dynamic o) → self::A<self::A::T%>
+    : super core::Object::•()
+    ;
+}
+class Class<T extends <S extends core::Object? = dynamic>(S%) → void = <S extends core::Object? = dynamic>(S%) → void> extends core::Object {
+  synthetic constructor •() → self::Class<self::Class::T>
+    ;
+}
+static field <T extends core::Object? = dynamic>(T%) →? void f;
+static method method1<@invalid-expression "pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart:16:24: Error: Too few positional arguments: 1 required, 0 given.
+void method1<@A<String>() T>(T t) {}
+                       ^" T extends core::Object? = dynamic>(self::method1::T% t) → void
+  ;
+static method method2(<T extends core::Object? = dynamic>(T%) → void f) → void
+  ;
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart.weak.transformed.expect b/pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart.weak.transformed.expect
new file mode 100644
index 0000000..6ab9190
--- /dev/null
+++ b/pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart.weak.transformed.expect
@@ -0,0 +1,74 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart:14:27: Error: Too few positional arguments: 1 required, 0 given.
+// typedef void G<@A<dynamic>() T>(T t);
+//                           ^
+// pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart:6:9: Context: Found this candidate, but the arguments don't match.
+//   const A(o);
+//         ^
+//
+// pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart:16:24: Error: Too few positional arguments: 1 required, 0 given.
+// void method1<@A<String>() T>(T t) {}
+//                        ^
+// pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart:6:9: Context: Found this candidate, but the arguments don't match.
+//   const A(o);
+//         ^
+//
+// pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart:9:22: Error: Too few positional arguments: 1 required, 0 given.
+// void Function<@A<int>() T>(T)? f;
+//                      ^
+// pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart:6:9: Context: Found this candidate, but the arguments don't match.
+//   const A(o);
+//         ^
+//
+// pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart:18:35: Error: Too few positional arguments: 1 required, 0 given.
+// void method2(void Function<@A<num>() T>(T) f) {}
+//                                   ^
+// pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart:6:9: Context: Found this candidate, but the arguments don't match.
+//   const A(o);
+//         ^
+//
+// pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart:24:24: Error: Too few positional arguments: 1 required, 0 given.
+//   void local<@A<double>() T>(T t) {}
+//                        ^
+// pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart:6:9: Context: Found this candidate, but the arguments don't match.
+//   const A(o);
+//         ^
+//
+// pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart:26:24: Error: Too few positional arguments: 1 required, 0 given.
+//   void Function<@A<int>() T>(T)? f;
+//                        ^
+// pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart:6:9: Context: Found this candidate, but the arguments don't match.
+//   const A(o);
+//         ^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef F = <T extends core::Object? = dynamic>(T%) → void;
+typedef G<@invalid-expression "pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart:14:27: Error: Too few positional arguments: 1 required, 0 given.
+typedef void G<@A<dynamic>() T>(T t);
+                          ^" contravariant T extends core::Object? = dynamic> = (T%) → void;
+class A<T extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/  {
+  const constructor •(dynamic o) → self::A<self::A::T%>
+    : super core::Object::•()
+    ;
+}
+class Class<T extends <S extends core::Object? = dynamic>(S%) → void = <S extends core::Object? = dynamic>(S%) → void> extends core::Object {
+  synthetic constructor •() → self::Class<self::Class::T>
+    : super core::Object::•()
+    ;
+}
+static field <T extends core::Object? = dynamic>(T%) →? void f;
+static method method1<@invalid-expression "pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart:16:24: Error: Too few positional arguments: 1 required, 0 given.
+void method1<@A<String>() T>(T t) {}
+                       ^" T extends core::Object? = dynamic>(self::method1::T% t) → void {}
+static method method2(<T extends core::Object? = dynamic>(T%) → void f) → void {}
+static method main() → dynamic {
+  function local<@invalid-expression "pkg/front_end/testcases/generic_metadata/erroneous_function_type_parameter.dart:24:24: Error: Too few positional arguments: 1 required, 0 given.
+  void local<@A<double>() T>(T t) {}
+                       ^" T extends core::Object? = dynamic>(T% t) → void {}
+  <T extends core::Object? = dynamic>(T%) →? void f;
+}
diff --git a/pkg/front_end/testcases/generic_metadata/from_dill/main.dart b/pkg/front_end/testcases/generic_metadata/from_dill/main.dart
new file mode 100644
index 0000000..6ac6d2c
--- /dev/null
+++ b/pkg/front_end/testcases/generic_metadata/from_dill/main.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. 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';
+
+main() {
+  C1 c1 = C1();
+  C1 c2 = C1<T Function<T>(T)>();
+
+  C2 c3 = C2();
+  C2 c4 = C2<void Function<int>()>();
+
+  C3 c5 = C3();
+  C3 c6 = C3<T Function<T>()>();
+
+  C4 c7 = C4();
+  C4 c8 = C4<void Function<T>(T)>();
+
+  C5 c9 = C5();
+  C5 c10 = C5<T Function<T extends S Function<S>(S)>(T)>();
+
+  C6 c11 = C6();
+  C6 c12 = C6<
+      T Function<T, S>(T, S, V Function<V extends S, U>(T, U, V, Map<S, U>))>();
+}
diff --git a/pkg/front_end/testcases/generic_metadata/from_dill/main.dart.strong.expect b/pkg/front_end/testcases/generic_metadata/from_dill/main.dart.strong.expect
new file mode 100644
index 0000000..92b41bb
--- /dev/null
+++ b/pkg/front_end/testcases/generic_metadata/from_dill/main.dart.strong.expect
@@ -0,0 +1,81 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "main_lib.dart" as mai;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///main_lib.dart";
+
+static method main() → dynamic {
+  mai::C1<<T extends core::Object? = dynamic>(T%) → T%> c1 = new mai::C1::•<<T extends core::Object? = dynamic>(T%) → T%>();
+  mai::C1<<T extends core::Object? = dynamic>(T%) → T%> c2 = new mai::C1::•<<T extends core::Object? = dynamic>(T%) → T%>();
+  mai::C2<<T extends core::Object? = dynamic>() → void> c3 = new mai::C2::•<<T extends core::Object? = dynamic>() → void>();
+  mai::C2<<T extends core::Object? = dynamic>() → void> c4 = new mai::C2::•<<int extends core::Object? = dynamic>() → void>();
+  mai::C3<<T extends core::Object? = dynamic>() → T%> c5 = new mai::C3::•<<T extends core::Object? = dynamic>() → T%>();
+  mai::C3<<T extends core::Object? = dynamic>() → T%> c6 = new mai::C3::•<<T extends core::Object? = dynamic>() → T%>();
+  mai::C4<<T extends core::Object? = dynamic>(T%) → void> c7 = new mai::C4::•<<T extends core::Object? = dynamic>(T%) → void>();
+  mai::C4<<T extends core::Object? = dynamic>(T%) → void> c8 = new mai::C4::•<<T extends core::Object? = dynamic>(T%) → void>();
+  mai::C5<<T extends <S extends core::Object? = dynamic>(S%) → S% = dynamic>(T) → T> c9 = new mai::C5::•<<T extends <S extends core::Object? = dynamic>(S%) → S% = dynamic>(T) → T>();
+  mai::C5<<T extends <S extends core::Object? = dynamic>(S%) → S% = dynamic>(T) → T> c10 = new mai::C5::•<<T extends <S extends core::Object? = dynamic>(S%) → S% = <S extends core::Object? = dynamic>(S%) → S%>(T) → T>();
+  mai::C6<<T extends core::Object? = dynamic, S extends core::Object? = dynamic>(T%, S%, <V extends S% = dynamic, U extends core::Object? = dynamic>(T%, U%, V%, core::Map<S%, U%>) → V%) → T%> c11 = new mai::C6::•<<T extends core::Object? = dynamic, S extends core::Object? = dynamic>(T%, S%, <V extends S% = dynamic, U extends core::Object? = dynamic>(T%, U%, V%, core::Map<S%, U%>) → V%) → T%>();
+  mai::C6<<T extends core::Object? = dynamic, S extends core::Object? = dynamic>(T%, S%, <V extends S% = dynamic, U extends core::Object? = dynamic>(T%, U%, V%, core::Map<S%, U%>) → V%) → T%> c12 = new mai::C6::•<<T extends core::Object? = dynamic, S extends core::Object? = dynamic>(T%, S%, <V extends S% = S%, U extends core::Object? = dynamic>(T%, U%, V%, core::Map<S%, U%>) → V%) → T%>();
+}
+
+library /*isNonNullableByDefault*/;
+import self as mai;
+import "dart:core" as core;
+
+typedef exp1 = <T extends core::Object? = dynamic>(T%) → T%;
+typedef exp2 = <T extends core::Object? = dynamic>() → void;
+typedef exp3 = <T extends core::Object? = dynamic>() → T%;
+typedef exp4 = <T extends core::Object? = dynamic>(T%) → void;
+typedef exp5 = <T extends <S extends core::Object? = dynamic>(S%) → S% = dynamic>(T) → T;
+typedef exp6 = <T extends core::Object? = dynamic, S extends core::Object? = dynamic>(T%, S%, <V extends S% = dynamic, U extends core::Object? = dynamic>(T%, U%, V%, core::Map<S%, U%>) → V%) → T%;
+class C1<X extends <T extends core::Object? = dynamic>(T%) → T% = <T extends core::Object? = dynamic>(T%) → T%> extends core::Object {
+  constructor •() → mai::C1<mai::C1::X>
+    : super core::Object::•() {
+    mai::expect(#C1, mai::C1::X);
+  }
+}
+class C2<X extends <T extends core::Object? = dynamic>() → void = <T extends core::Object? = dynamic>() → void> extends core::Object {
+  constructor •() → mai::C2<mai::C2::X>
+    : super core::Object::•() {
+    mai::expect(#C2, mai::C2::X);
+  }
+}
+class C3<X extends <T extends core::Object? = dynamic>() → T% = <T extends core::Object? = dynamic>() → T%> extends core::Object {
+  constructor •() → mai::C3<mai::C3::X>
+    : super core::Object::•() {
+    mai::expect(#C3, mai::C3::X);
+  }
+}
+class C4<X extends <T extends core::Object? = dynamic>(T%) → void = <T extends core::Object? = dynamic>(T%) → void> extends core::Object {
+  constructor •() → mai::C4<mai::C4::X>
+    : super core::Object::•() {
+    mai::expect(#C4, mai::C4::X);
+  }
+}
+class C5<X extends <T extends <S extends core::Object? = dynamic>(S%) → S% = dynamic>(T) → T = <T extends <S extends core::Object? = dynamic>(S%) → S% = dynamic>(T) → T> extends core::Object {
+  constructor •() → mai::C5<mai::C5::X>
+    : super core::Object::•() {
+    mai::expect(#C5, mai::C5::X);
+  }
+}
+class C6<X extends <T extends core::Object? = dynamic, S extends core::Object? = dynamic>(T%, S%, <V extends S% = dynamic, U extends core::Object? = dynamic>(T%, U%, V%, core::Map<S%, U%>) → V%) → T% = <T extends core::Object? = dynamic, S extends core::Object? = dynamic>(T%, S%, <V extends S% = dynamic, U extends core::Object? = dynamic>(T%, U%, V%, core::Map<S%, U%>) → V%) → T%> extends core::Object {
+  constructor •() → mai::C6<mai::C6::X>
+    : super core::Object::•() {
+    mai::expect(#C6, mai::C6::X);
+  }
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+  if(!expected.{core::Object::==}(actual))
+    throw "Expected ${expected}, actual ${actual}";
+}
+
+constants  {
+  #C1 = TypeLiteralConstant(<T extends core::Object? = dynamic>(T%) → T%)
+  #C2 = TypeLiteralConstant(<T extends core::Object? = dynamic>() → void)
+  #C3 = TypeLiteralConstant(<T extends core::Object? = dynamic>() → T%)
+  #C4 = TypeLiteralConstant(<T extends core::Object? = dynamic>(T%) → void)
+  #C5 = TypeLiteralConstant(<T extends <S extends core::Object? = dynamic>(S%) → S% = dynamic>(T) → T)
+  #C6 = TypeLiteralConstant(<T extends core::Object? = dynamic, S extends core::Object? = dynamic>(T%, S%, <V extends S% = dynamic, U extends core::Object? = dynamic>(T%, U%, V%, core::Map<S%, U%>) → V%) → T%)
+}
diff --git a/pkg/front_end/testcases/generic_metadata/from_dill/main.dart.strong.transformed.expect b/pkg/front_end/testcases/generic_metadata/from_dill/main.dart.strong.transformed.expect
new file mode 100644
index 0000000..92b41bb
--- /dev/null
+++ b/pkg/front_end/testcases/generic_metadata/from_dill/main.dart.strong.transformed.expect
@@ -0,0 +1,81 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "main_lib.dart" as mai;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///main_lib.dart";
+
+static method main() → dynamic {
+  mai::C1<<T extends core::Object? = dynamic>(T%) → T%> c1 = new mai::C1::•<<T extends core::Object? = dynamic>(T%) → T%>();
+  mai::C1<<T extends core::Object? = dynamic>(T%) → T%> c2 = new mai::C1::•<<T extends core::Object? = dynamic>(T%) → T%>();
+  mai::C2<<T extends core::Object? = dynamic>() → void> c3 = new mai::C2::•<<T extends core::Object? = dynamic>() → void>();
+  mai::C2<<T extends core::Object? = dynamic>() → void> c4 = new mai::C2::•<<int extends core::Object? = dynamic>() → void>();
+  mai::C3<<T extends core::Object? = dynamic>() → T%> c5 = new mai::C3::•<<T extends core::Object? = dynamic>() → T%>();
+  mai::C3<<T extends core::Object? = dynamic>() → T%> c6 = new mai::C3::•<<T extends core::Object? = dynamic>() → T%>();
+  mai::C4<<T extends core::Object? = dynamic>(T%) → void> c7 = new mai::C4::•<<T extends core::Object? = dynamic>(T%) → void>();
+  mai::C4<<T extends core::Object? = dynamic>(T%) → void> c8 = new mai::C4::•<<T extends core::Object? = dynamic>(T%) → void>();
+  mai::C5<<T extends <S extends core::Object? = dynamic>(S%) → S% = dynamic>(T) → T> c9 = new mai::C5::•<<T extends <S extends core::Object? = dynamic>(S%) → S% = dynamic>(T) → T>();
+  mai::C5<<T extends <S extends core::Object? = dynamic>(S%) → S% = dynamic>(T) → T> c10 = new mai::C5::•<<T extends <S extends core::Object? = dynamic>(S%) → S% = <S extends core::Object? = dynamic>(S%) → S%>(T) → T>();
+  mai::C6<<T extends core::Object? = dynamic, S extends core::Object? = dynamic>(T%, S%, <V extends S% = dynamic, U extends core::Object? = dynamic>(T%, U%, V%, core::Map<S%, U%>) → V%) → T%> c11 = new mai::C6::•<<T extends core::Object? = dynamic, S extends core::Object? = dynamic>(T%, S%, <V extends S% = dynamic, U extends core::Object? = dynamic>(T%, U%, V%, core::Map<S%, U%>) → V%) → T%>();
+  mai::C6<<T extends core::Object? = dynamic, S extends core::Object? = dynamic>(T%, S%, <V extends S% = dynamic, U extends core::Object? = dynamic>(T%, U%, V%, core::Map<S%, U%>) → V%) → T%> c12 = new mai::C6::•<<T extends core::Object? = dynamic, S extends core::Object? = dynamic>(T%, S%, <V extends S% = S%, U extends core::Object? = dynamic>(T%, U%, V%, core::Map<S%, U%>) → V%) → T%>();
+}
+
+library /*isNonNullableByDefault*/;
+import self as mai;
+import "dart:core" as core;
+
+typedef exp1 = <T extends core::Object? = dynamic>(T%) → T%;
+typedef exp2 = <T extends core::Object? = dynamic>() → void;
+typedef exp3 = <T extends core::Object? = dynamic>() → T%;
+typedef exp4 = <T extends core::Object? = dynamic>(T%) → void;
+typedef exp5 = <T extends <S extends core::Object? = dynamic>(S%) → S% = dynamic>(T) → T;
+typedef exp6 = <T extends core::Object? = dynamic, S extends core::Object? = dynamic>(T%, S%, <V extends S% = dynamic, U extends core::Object? = dynamic>(T%, U%, V%, core::Map<S%, U%>) → V%) → T%;
+class C1<X extends <T extends core::Object? = dynamic>(T%) → T% = <T extends core::Object? = dynamic>(T%) → T%> extends core::Object {
+  constructor •() → mai::C1<mai::C1::X>
+    : super core::Object::•() {
+    mai::expect(#C1, mai::C1::X);
+  }
+}
+class C2<X extends <T extends core::Object? = dynamic>() → void = <T extends core::Object? = dynamic>() → void> extends core::Object {
+  constructor •() → mai::C2<mai::C2::X>
+    : super core::Object::•() {
+    mai::expect(#C2, mai::C2::X);
+  }
+}
+class C3<X extends <T extends core::Object? = dynamic>() → T% = <T extends core::Object? = dynamic>() → T%> extends core::Object {
+  constructor •() → mai::C3<mai::C3::X>
+    : super core::Object::•() {
+    mai::expect(#C3, mai::C3::X);
+  }
+}
+class C4<X extends <T extends core::Object? = dynamic>(T%) → void = <T extends core::Object? = dynamic>(T%) → void> extends core::Object {
+  constructor •() → mai::C4<mai::C4::X>
+    : super core::Object::•() {
+    mai::expect(#C4, mai::C4::X);
+  }
+}
+class C5<X extends <T extends <S extends core::Object? = dynamic>(S%) → S% = dynamic>(T) → T = <T extends <S extends core::Object? = dynamic>(S%) → S% = dynamic>(T) → T> extends core::Object {
+  constructor •() → mai::C5<mai::C5::X>
+    : super core::Object::•() {
+    mai::expect(#C5, mai::C5::X);
+  }
+}
+class C6<X extends <T extends core::Object? = dynamic, S extends core::Object? = dynamic>(T%, S%, <V extends S% = dynamic, U extends core::Object? = dynamic>(T%, U%, V%, core::Map<S%, U%>) → V%) → T% = <T extends core::Object? = dynamic, S extends core::Object? = dynamic>(T%, S%, <V extends S% = dynamic, U extends core::Object? = dynamic>(T%, U%, V%, core::Map<S%, U%>) → V%) → T%> extends core::Object {
+  constructor •() → mai::C6<mai::C6::X>
+    : super core::Object::•() {
+    mai::expect(#C6, mai::C6::X);
+  }
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+  if(!expected.{core::Object::==}(actual))
+    throw "Expected ${expected}, actual ${actual}";
+}
+
+constants  {
+  #C1 = TypeLiteralConstant(<T extends core::Object? = dynamic>(T%) → T%)
+  #C2 = TypeLiteralConstant(<T extends core::Object? = dynamic>() → void)
+  #C3 = TypeLiteralConstant(<T extends core::Object? = dynamic>() → T%)
+  #C4 = TypeLiteralConstant(<T extends core::Object? = dynamic>(T%) → void)
+  #C5 = TypeLiteralConstant(<T extends <S extends core::Object? = dynamic>(S%) → S% = dynamic>(T) → T)
+  #C6 = TypeLiteralConstant(<T extends core::Object? = dynamic, S extends core::Object? = dynamic>(T%, S%, <V extends S% = dynamic, U extends core::Object? = dynamic>(T%, U%, V%, core::Map<S%, U%>) → V%) → T%)
+}
diff --git a/pkg/front_end/testcases/generic_metadata/from_dill/main.dart.textual_outline.expect b/pkg/front_end/testcases/generic_metadata/from_dill/main.dart.textual_outline.expect
new file mode 100644
index 0000000..82be6bb
--- /dev/null
+++ b/pkg/front_end/testcases/generic_metadata/from_dill/main.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+import 'main_lib.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/generic_metadata/from_dill/main.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/generic_metadata/from_dill/main.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..82be6bb
--- /dev/null
+++ b/pkg/front_end/testcases/generic_metadata/from_dill/main.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+import 'main_lib.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/generic_metadata/from_dill/main.dart.weak.expect b/pkg/front_end/testcases/generic_metadata/from_dill/main.dart.weak.expect
new file mode 100644
index 0000000..e1e7067
--- /dev/null
+++ b/pkg/front_end/testcases/generic_metadata/from_dill/main.dart.weak.expect
@@ -0,0 +1,81 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "main_lib.dart" as mai;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///main_lib.dart";
+
+static method main() → dynamic {
+  mai::C1<<T extends core::Object? = dynamic>(T%) → T%> c1 = new mai::C1::•<<T extends core::Object? = dynamic>(T%) → T%>();
+  mai::C1<<T extends core::Object? = dynamic>(T%) → T%> c2 = new mai::C1::•<<T extends core::Object? = dynamic>(T%) → T%>();
+  mai::C2<<T extends core::Object? = dynamic>() → void> c3 = new mai::C2::•<<T extends core::Object? = dynamic>() → void>();
+  mai::C2<<T extends core::Object? = dynamic>() → void> c4 = new mai::C2::•<<int extends core::Object? = dynamic>() → void>();
+  mai::C3<<T extends core::Object? = dynamic>() → T%> c5 = new mai::C3::•<<T extends core::Object? = dynamic>() → T%>();
+  mai::C3<<T extends core::Object? = dynamic>() → T%> c6 = new mai::C3::•<<T extends core::Object? = dynamic>() → T%>();
+  mai::C4<<T extends core::Object? = dynamic>(T%) → void> c7 = new mai::C4::•<<T extends core::Object? = dynamic>(T%) → void>();
+  mai::C4<<T extends core::Object? = dynamic>(T%) → void> c8 = new mai::C4::•<<T extends core::Object? = dynamic>(T%) → void>();
+  mai::C5<<T extends <S extends core::Object? = dynamic>(S%) → S% = dynamic>(T) → T> c9 = new mai::C5::•<<T extends <S extends core::Object? = dynamic>(S%) → S% = dynamic>(T) → T>();
+  mai::C5<<T extends <S extends core::Object? = dynamic>(S%) → S% = dynamic>(T) → T> c10 = new mai::C5::•<<T extends <S extends core::Object? = dynamic>(S%) → S% = <S extends core::Object? = dynamic>(S%) → S%>(T) → T>();
+  mai::C6<<T extends core::Object? = dynamic, S extends core::Object? = dynamic>(T%, S%, <V extends S% = dynamic, U extends core::Object? = dynamic>(T%, U%, V%, core::Map<S%, U%>) → V%) → T%> c11 = new mai::C6::•<<T extends core::Object? = dynamic, S extends core::Object? = dynamic>(T%, S%, <V extends S% = dynamic, U extends core::Object? = dynamic>(T%, U%, V%, core::Map<S%, U%>) → V%) → T%>();
+  mai::C6<<T extends core::Object? = dynamic, S extends core::Object? = dynamic>(T%, S%, <V extends S% = dynamic, U extends core::Object? = dynamic>(T%, U%, V%, core::Map<S%, U%>) → V%) → T%> c12 = new mai::C6::•<<T extends core::Object? = dynamic, S extends core::Object? = dynamic>(T%, S%, <V extends S% = S%, U extends core::Object? = dynamic>(T%, U%, V%, core::Map<S%, U%>) → V%) → T%>();
+}
+
+library /*isNonNullableByDefault*/;
+import self as mai;
+import "dart:core" as core;
+
+typedef exp1 = <T extends core::Object? = dynamic>(T%) → T%;
+typedef exp2 = <T extends core::Object? = dynamic>() → void;
+typedef exp3 = <T extends core::Object? = dynamic>() → T%;
+typedef exp4 = <T extends core::Object? = dynamic>(T%) → void;
+typedef exp5 = <T extends <S extends core::Object? = dynamic>(S%) → S% = dynamic>(T) → T;
+typedef exp6 = <T extends core::Object? = dynamic, S extends core::Object? = dynamic>(T%, S%, <V extends S% = dynamic, U extends core::Object? = dynamic>(T%, U%, V%, core::Map<S%, U%>) → V%) → T%;
+class C1<X extends <T extends core::Object? = dynamic>(T%) → T% = <T extends core::Object? = dynamic>(T%) → T%> extends core::Object {
+  constructor •() → mai::C1<mai::C1::X>
+    : super core::Object::•() {
+    mai::expect(#C1, mai::C1::X);
+  }
+}
+class C2<X extends <T extends core::Object? = dynamic>() → void = <T extends core::Object? = dynamic>() → void> extends core::Object {
+  constructor •() → mai::C2<mai::C2::X>
+    : super core::Object::•() {
+    mai::expect(#C2, mai::C2::X);
+  }
+}
+class C3<X extends <T extends core::Object? = dynamic>() → T% = <T extends core::Object? = dynamic>() → T%> extends core::Object {
+  constructor •() → mai::C3<mai::C3::X>
+    : super core::Object::•() {
+    mai::expect(#C3, mai::C3::X);
+  }
+}
+class C4<X extends <T extends core::Object? = dynamic>(T%) → void = <T extends core::Object? = dynamic>(T%) → void> extends core::Object {
+  constructor •() → mai::C4<mai::C4::X>
+    : super core::Object::•() {
+    mai::expect(#C4, mai::C4::X);
+  }
+}
+class C5<X extends <T extends <S extends core::Object? = dynamic>(S%) → S% = dynamic>(T) → T = <T extends <S extends core::Object? = dynamic>(S%) → S% = dynamic>(T) → T> extends core::Object {
+  constructor •() → mai::C5<mai::C5::X>
+    : super core::Object::•() {
+    mai::expect(#C5, mai::C5::X);
+  }
+}
+class C6<X extends <T extends core::Object? = dynamic, S extends core::Object? = dynamic>(T%, S%, <V extends S% = dynamic, U extends core::Object? = dynamic>(T%, U%, V%, core::Map<S%, U%>) → V%) → T% = <T extends core::Object? = dynamic, S extends core::Object? = dynamic>(T%, S%, <V extends S% = dynamic, U extends core::Object? = dynamic>(T%, U%, V%, core::Map<S%, U%>) → V%) → T%> extends core::Object {
+  constructor •() → mai::C6<mai::C6::X>
+    : super core::Object::•() {
+    mai::expect(#C6, mai::C6::X);
+  }
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+  if(!expected.{core::Object::==}(actual))
+    throw "Expected ${expected}, actual ${actual}";
+}
+
+constants  {
+  #C1 = TypeLiteralConstant(<T extends core::Object? = dynamic>(T*) →* T*)
+  #C2 = TypeLiteralConstant(<T extends core::Object? = dynamic>() →* void)
+  #C3 = TypeLiteralConstant(<T extends core::Object? = dynamic>() →* T*)
+  #C4 = TypeLiteralConstant(<T extends core::Object? = dynamic>(T*) →* void)
+  #C5 = TypeLiteralConstant(<T extends <S extends core::Object? = dynamic>(S*) →* S* = <S extends core::Object? = dynamic>(S*) →* S*>(T*) →* T*)
+  #C6 = TypeLiteralConstant(<T extends core::Object? = dynamic, S extends core::Object? = dynamic>(T*, S*, <V extends S* = S*, U extends core::Object? = dynamic>(T*, U*, V*, core::Map<S*, U*>*) →* V*) →* T*)
+}
diff --git a/pkg/front_end/testcases/generic_metadata/from_dill/main.dart.weak.outline.expect b/pkg/front_end/testcases/generic_metadata/from_dill/main.dart.weak.outline.expect
new file mode 100644
index 0000000..b9ccc27
--- /dev/null
+++ b/pkg/front_end/testcases/generic_metadata/from_dill/main.dart.weak.outline.expect
@@ -0,0 +1,44 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+
+import "org-dartlang-testcase:///main_lib.dart";
+
+static method main() → dynamic
+  ;
+
+library /*isNonNullableByDefault*/;
+import self as self2;
+import "dart:core" as core;
+
+typedef exp1 = <T extends core::Object? = dynamic>(T%) → T%;
+typedef exp2 = <T extends core::Object? = dynamic>() → void;
+typedef exp3 = <T extends core::Object? = dynamic>() → T%;
+typedef exp4 = <T extends core::Object? = dynamic>(T%) → void;
+typedef exp5 = <T extends <S extends core::Object? = dynamic>(S%) → S% = dynamic>(T) → T;
+typedef exp6 = <T extends core::Object? = dynamic, S extends core::Object? = dynamic>(T%, S%, <V extends S% = dynamic, U extends core::Object? = dynamic>(T%, U%, V%, core::Map<S%, U%>) → V%) → T%;
+class C1<X extends <T extends core::Object? = dynamic>(T%) → T% = <T extends core::Object? = dynamic>(T%) → T%> extends core::Object {
+  constructor •() → self2::C1<self2::C1::X>
+    ;
+}
+class C2<X extends <T extends core::Object? = dynamic>() → void = <T extends core::Object? = dynamic>() → void> extends core::Object {
+  constructor •() → self2::C2<self2::C2::X>
+    ;
+}
+class C3<X extends <T extends core::Object? = dynamic>() → T% = <T extends core::Object? = dynamic>() → T%> extends core::Object {
+  constructor •() → self2::C3<self2::C3::X>
+    ;
+}
+class C4<X extends <T extends core::Object? = dynamic>(T%) → void = <T extends core::Object? = dynamic>(T%) → void> extends core::Object {
+  constructor •() → self2::C4<self2::C4::X>
+    ;
+}
+class C5<X extends <T extends <S extends core::Object? = dynamic>(S%) → S% = dynamic>(T) → T = <T extends <S extends core::Object? = dynamic>(S%) → S% = dynamic>(T) → T> extends core::Object {
+  constructor •() → self2::C5<self2::C5::X>
+    ;
+}
+class C6<X extends <T extends core::Object? = dynamic, S extends core::Object? = dynamic>(T%, S%, <V extends S% = dynamic, U extends core::Object? = dynamic>(T%, U%, V%, core::Map<S%, U%>) → V%) → T% = <T extends core::Object? = dynamic, S extends core::Object? = dynamic>(T%, S%, <V extends S% = dynamic, U extends core::Object? = dynamic>(T%, U%, V%, core::Map<S%, U%>) → V%) → T%> extends core::Object {
+  constructor •() → self2::C6<self2::C6::X>
+    ;
+}
+static method expect(dynamic expected, dynamic actual) → dynamic
+  ;
diff --git a/pkg/front_end/testcases/generic_metadata/from_dill/main.dart.weak.transformed.expect b/pkg/front_end/testcases/generic_metadata/from_dill/main.dart.weak.transformed.expect
new file mode 100644
index 0000000..e1e7067
--- /dev/null
+++ b/pkg/front_end/testcases/generic_metadata/from_dill/main.dart.weak.transformed.expect
@@ -0,0 +1,81 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "main_lib.dart" as mai;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///main_lib.dart";
+
+static method main() → dynamic {
+  mai::C1<<T extends core::Object? = dynamic>(T%) → T%> c1 = new mai::C1::•<<T extends core::Object? = dynamic>(T%) → T%>();
+  mai::C1<<T extends core::Object? = dynamic>(T%) → T%> c2 = new mai::C1::•<<T extends core::Object? = dynamic>(T%) → T%>();
+  mai::C2<<T extends core::Object? = dynamic>() → void> c3 = new mai::C2::•<<T extends core::Object? = dynamic>() → void>();
+  mai::C2<<T extends core::Object? = dynamic>() → void> c4 = new mai::C2::•<<int extends core::Object? = dynamic>() → void>();
+  mai::C3<<T extends core::Object? = dynamic>() → T%> c5 = new mai::C3::•<<T extends core::Object? = dynamic>() → T%>();
+  mai::C3<<T extends core::Object? = dynamic>() → T%> c6 = new mai::C3::•<<T extends core::Object? = dynamic>() → T%>();
+  mai::C4<<T extends core::Object? = dynamic>(T%) → void> c7 = new mai::C4::•<<T extends core::Object? = dynamic>(T%) → void>();
+  mai::C4<<T extends core::Object? = dynamic>(T%) → void> c8 = new mai::C4::•<<T extends core::Object? = dynamic>(T%) → void>();
+  mai::C5<<T extends <S extends core::Object? = dynamic>(S%) → S% = dynamic>(T) → T> c9 = new mai::C5::•<<T extends <S extends core::Object? = dynamic>(S%) → S% = dynamic>(T) → T>();
+  mai::C5<<T extends <S extends core::Object? = dynamic>(S%) → S% = dynamic>(T) → T> c10 = new mai::C5::•<<T extends <S extends core::Object? = dynamic>(S%) → S% = <S extends core::Object? = dynamic>(S%) → S%>(T) → T>();
+  mai::C6<<T extends core::Object? = dynamic, S extends core::Object? = dynamic>(T%, S%, <V extends S% = dynamic, U extends core::Object? = dynamic>(T%, U%, V%, core::Map<S%, U%>) → V%) → T%> c11 = new mai::C6::•<<T extends core::Object? = dynamic, S extends core::Object? = dynamic>(T%, S%, <V extends S% = dynamic, U extends core::Object? = dynamic>(T%, U%, V%, core::Map<S%, U%>) → V%) → T%>();
+  mai::C6<<T extends core::Object? = dynamic, S extends core::Object? = dynamic>(T%, S%, <V extends S% = dynamic, U extends core::Object? = dynamic>(T%, U%, V%, core::Map<S%, U%>) → V%) → T%> c12 = new mai::C6::•<<T extends core::Object? = dynamic, S extends core::Object? = dynamic>(T%, S%, <V extends S% = S%, U extends core::Object? = dynamic>(T%, U%, V%, core::Map<S%, U%>) → V%) → T%>();
+}
+
+library /*isNonNullableByDefault*/;
+import self as mai;
+import "dart:core" as core;
+
+typedef exp1 = <T extends core::Object? = dynamic>(T%) → T%;
+typedef exp2 = <T extends core::Object? = dynamic>() → void;
+typedef exp3 = <T extends core::Object? = dynamic>() → T%;
+typedef exp4 = <T extends core::Object? = dynamic>(T%) → void;
+typedef exp5 = <T extends <S extends core::Object? = dynamic>(S%) → S% = dynamic>(T) → T;
+typedef exp6 = <T extends core::Object? = dynamic, S extends core::Object? = dynamic>(T%, S%, <V extends S% = dynamic, U extends core::Object? = dynamic>(T%, U%, V%, core::Map<S%, U%>) → V%) → T%;
+class C1<X extends <T extends core::Object? = dynamic>(T%) → T% = <T extends core::Object? = dynamic>(T%) → T%> extends core::Object {
+  constructor •() → mai::C1<mai::C1::X>
+    : super core::Object::•() {
+    mai::expect(#C1, mai::C1::X);
+  }
+}
+class C2<X extends <T extends core::Object? = dynamic>() → void = <T extends core::Object? = dynamic>() → void> extends core::Object {
+  constructor •() → mai::C2<mai::C2::X>
+    : super core::Object::•() {
+    mai::expect(#C2, mai::C2::X);
+  }
+}
+class C3<X extends <T extends core::Object? = dynamic>() → T% = <T extends core::Object? = dynamic>() → T%> extends core::Object {
+  constructor •() → mai::C3<mai::C3::X>
+    : super core::Object::•() {
+    mai::expect(#C3, mai::C3::X);
+  }
+}
+class C4<X extends <T extends core::Object? = dynamic>(T%) → void = <T extends core::Object? = dynamic>(T%) → void> extends core::Object {
+  constructor •() → mai::C4<mai::C4::X>
+    : super core::Object::•() {
+    mai::expect(#C4, mai::C4::X);
+  }
+}
+class C5<X extends <T extends <S extends core::Object? = dynamic>(S%) → S% = dynamic>(T) → T = <T extends <S extends core::Object? = dynamic>(S%) → S% = dynamic>(T) → T> extends core::Object {
+  constructor •() → mai::C5<mai::C5::X>
+    : super core::Object::•() {
+    mai::expect(#C5, mai::C5::X);
+  }
+}
+class C6<X extends <T extends core::Object? = dynamic, S extends core::Object? = dynamic>(T%, S%, <V extends S% = dynamic, U extends core::Object? = dynamic>(T%, U%, V%, core::Map<S%, U%>) → V%) → T% = <T extends core::Object? = dynamic, S extends core::Object? = dynamic>(T%, S%, <V extends S% = dynamic, U extends core::Object? = dynamic>(T%, U%, V%, core::Map<S%, U%>) → V%) → T%> extends core::Object {
+  constructor •() → mai::C6<mai::C6::X>
+    : super core::Object::•() {
+    mai::expect(#C6, mai::C6::X);
+  }
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+  if(!expected.{core::Object::==}(actual))
+    throw "Expected ${expected}, actual ${actual}";
+}
+
+constants  {
+  #C1 = TypeLiteralConstant(<T extends core::Object? = dynamic>(T*) →* T*)
+  #C2 = TypeLiteralConstant(<T extends core::Object? = dynamic>() →* void)
+  #C3 = TypeLiteralConstant(<T extends core::Object? = dynamic>() →* T*)
+  #C4 = TypeLiteralConstant(<T extends core::Object? = dynamic>(T*) →* void)
+  #C5 = TypeLiteralConstant(<T extends <S extends core::Object? = dynamic>(S*) →* S* = <S extends core::Object? = dynamic>(S*) →* S*>(T*) →* T*)
+  #C6 = TypeLiteralConstant(<T extends core::Object? = dynamic, S extends core::Object? = dynamic>(T*, S*, <V extends S* = S*, U extends core::Object? = dynamic>(T*, U*, V*, core::Map<S*, U*>*) →* V*) →* T*)
+}
diff --git a/pkg/front_end/testcases/generic_metadata/from_dill/main_lib.dart b/pkg/front_end/testcases/generic_metadata/from_dill/main_lib.dart
new file mode 100644
index 0000000..5a1661c
--- /dev/null
+++ b/pkg/front_end/testcases/generic_metadata/from_dill/main_lib.dart
@@ -0,0 +1,53 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+typedef exp1 = T Function<T>(T);
+typedef exp2 = void Function<T>();
+typedef exp3 = T Function<T>();
+typedef exp4 = void Function<T>(T);
+typedef exp5 = T Function<T extends S Function<S>(S)>(T);
+typedef exp6 = T Function<T, S>(
+    T, S, V Function<V extends S, U>(T, U, V, Map<S, U>));
+
+class C1<X extends T Function<T>(T)> {
+  C1() {
+    expect(exp1, X);
+  }
+}
+
+class C2<X extends void Function<T>()> {
+  C2() {
+    expect(exp2, X);
+  }
+}
+
+class C3<X extends T Function<T>()> {
+  C3() {
+    expect(exp3, X);
+  }
+}
+
+class C4<X extends void Function<T>(T)> {
+  C4() {
+    expect(exp4, X);
+  }
+}
+
+class C5<X extends T Function<T extends S Function<S>(S)>(T)> {
+  C5() {
+    expect(exp5, X);
+  }
+}
+
+class C6<
+    X extends T Function<T, S>(
+        T, S, V Function<V extends S, U>(T, U, V, Map<S, U>))> {
+  C6() {
+    expect(exp6, X);
+  }
+}
+
+expect(expected, actual) {
+  if (expected != actual) throw 'Expected $expected, actual $actual';
+}
diff --git a/pkg/front_end/testcases/generic_metadata/from_dill/test.options b/pkg/front_end/testcases/generic_metadata/from_dill/test.options
new file mode 100644
index 0000000..bfe6dc8
--- /dev/null
+++ b/pkg/front_end/testcases/generic_metadata/from_dill/test.options
@@ -0,0 +1 @@
+main_lib.dart
\ No newline at end of file
diff --git a/pkg/front_end/testcases/generic_metadata/function_type_parameter.dart b/pkg/front_end/testcases/generic_metadata/function_type_parameter.dart
new file mode 100644
index 0000000..551ae01
--- /dev/null
+++ b/pkg/front_end/testcases/generic_metadata/function_type_parameter.dart
@@ -0,0 +1,25 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class A<T> {
+  const A();
+}
+
+void Function<@A<int>() T>(T)? f;
+
+typedef F = void Function<@A<bool>() T>(T);
+
+typedef void G<@A<dynamic>() T>(T t);
+
+void method1<@A<String>() T>(T t) {}
+
+void method2(void Function<@A<num>() T>(T) f) {}
+
+class Class<T extends void Function<@A<void>() S>(S)> {}
+
+main() {
+  void local<@A<double>() T>(T t) {}
+
+  void Function<@A<int>() T>(T)? f;
+}
diff --git a/pkg/front_end/testcases/generic_metadata/function_type_parameter.dart.strong.expect b/pkg/front_end/testcases/generic_metadata/function_type_parameter.dart.strong.expect
new file mode 100644
index 0000000..493cc77
--- /dev/null
+++ b/pkg/front_end/testcases/generic_metadata/function_type_parameter.dart.strong.expect
@@ -0,0 +1,35 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+typedef F = <T extends core::Object? = dynamic>(T%) → void;
+typedef G<@#C1 contravariant T extends core::Object? = dynamic> = (T%) → void;
+class A<T extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/  {
+  const constructor •() → self::A<self::A::T%>
+    : super core::Object::•()
+    ;
+}
+class Class<T extends <S extends core::Object? = dynamic>(S%) → void = <S extends core::Object? = dynamic>(S%) → void> extends core::Object {
+  synthetic constructor •() → self::Class<self::Class::T>
+    : super core::Object::•()
+    ;
+}
+static field <T extends core::Object? = dynamic>(T%) →? void f;
+static method method1<@#C2 T extends core::Object? = dynamic>(self::method1::T% t) → void {}
+static method method2(<T extends core::Object? = dynamic>(T%) → void f) → void {}
+static method main() → dynamic {
+  function local<@#C3 T extends core::Object? = dynamic>(T% t) → void {}
+  <T extends core::Object? = dynamic>(T%) →? void f;
+}
+
+constants  {
+  #C1 = self::A<dynamic> {}
+  #C2 = self::A<core::String> {}
+  #C3 = self::A<core::double> {}
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///function_type_parameter.dart:
+- A. (from org-dartlang-testcase:///function_type_parameter.dart:6:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/generic_metadata/function_type_parameter.dart.strong.transformed.expect b/pkg/front_end/testcases/generic_metadata/function_type_parameter.dart.strong.transformed.expect
new file mode 100644
index 0000000..493cc77
--- /dev/null
+++ b/pkg/front_end/testcases/generic_metadata/function_type_parameter.dart.strong.transformed.expect
@@ -0,0 +1,35 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+typedef F = <T extends core::Object? = dynamic>(T%) → void;
+typedef G<@#C1 contravariant T extends core::Object? = dynamic> = (T%) → void;
+class A<T extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/  {
+  const constructor •() → self::A<self::A::T%>
+    : super core::Object::•()
+    ;
+}
+class Class<T extends <S extends core::Object? = dynamic>(S%) → void = <S extends core::Object? = dynamic>(S%) → void> extends core::Object {
+  synthetic constructor •() → self::Class<self::Class::T>
+    : super core::Object::•()
+    ;
+}
+static field <T extends core::Object? = dynamic>(T%) →? void f;
+static method method1<@#C2 T extends core::Object? = dynamic>(self::method1::T% t) → void {}
+static method method2(<T extends core::Object? = dynamic>(T%) → void f) → void {}
+static method main() → dynamic {
+  function local<@#C3 T extends core::Object? = dynamic>(T% t) → void {}
+  <T extends core::Object? = dynamic>(T%) →? void f;
+}
+
+constants  {
+  #C1 = self::A<dynamic> {}
+  #C2 = self::A<core::String> {}
+  #C3 = self::A<core::double> {}
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///function_type_parameter.dart:
+- A. (from org-dartlang-testcase:///function_type_parameter.dart:6:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/generic_metadata/function_type_parameter.dart.textual_outline.expect b/pkg/front_end/testcases/generic_metadata/function_type_parameter.dart.textual_outline.expect
new file mode 100644
index 0000000..e9838db
--- /dev/null
+++ b/pkg/front_end/testcases/generic_metadata/function_type_parameter.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+class A<T> {
+  const A();
+}
+
+void Function<@A<int>() T>(T)? f;
+typedef F = void Function<@A<bool>() T>(T);
+typedef void G<@A<dynamic>() T>(T t);
+void method1<@A<String>() T>(T t) {}
+void method2(void Function<@A<num>() T>(T) f) {}
+
+class Class<T extends void Function<@A<void>() S>(S)> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/generic_metadata/function_type_parameter.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/generic_metadata/function_type_parameter.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..32b733c
--- /dev/null
+++ b/pkg/front_end/testcases/generic_metadata/function_type_parameter.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+class A<T> {
+  const A();
+}
+
+class Class<T extends void Function<@A<void>() S>(S)> {}
+
+main() {}
+typedef F = void Function<@A<bool>() T>(T);
+typedef void G<@A<dynamic>() T>(T t);
+void Function<@A<int>() T>(T)? f;
+void method1<@A<String>() T>(T t) {}
+void method2(void Function<@A<num>() T>(T) f) {}
diff --git a/pkg/front_end/testcases/generic_metadata/function_type_parameter.dart.weak.expect b/pkg/front_end/testcases/generic_metadata/function_type_parameter.dart.weak.expect
new file mode 100644
index 0000000..c1ead73
--- /dev/null
+++ b/pkg/front_end/testcases/generic_metadata/function_type_parameter.dart.weak.expect
@@ -0,0 +1,35 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+typedef F = <T extends core::Object? = dynamic>(T%) → void;
+typedef G<@#C1 contravariant T extends core::Object? = dynamic> = (T%) → void;
+class A<T extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/  {
+  const constructor •() → self::A<self::A::T%>
+    : super core::Object::•()
+    ;
+}
+class Class<T extends <S extends core::Object? = dynamic>(S%) → void = <S extends core::Object? = dynamic>(S%) → void> extends core::Object {
+  synthetic constructor •() → self::Class<self::Class::T>
+    : super core::Object::•()
+    ;
+}
+static field <T extends core::Object? = dynamic>(T%) →? void f;
+static method method1<@#C2 T extends core::Object? = dynamic>(self::method1::T% t) → void {}
+static method method2(<T extends core::Object? = dynamic>(T%) → void f) → void {}
+static method main() → dynamic {
+  function local<@#C3 T extends core::Object? = dynamic>(T% t) → void {}
+  <T extends core::Object? = dynamic>(T%) →? void f;
+}
+
+constants  {
+  #C1 = self::A<dynamic> {}
+  #C2 = self::A<core::String*> {}
+  #C3 = self::A<core::double*> {}
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///function_type_parameter.dart:
+- A. (from org-dartlang-testcase:///function_type_parameter.dart:6:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/generic_metadata/function_type_parameter.dart.weak.outline.expect b/pkg/front_end/testcases/generic_metadata/function_type_parameter.dart.weak.outline.expect
new file mode 100644
index 0000000..778e91b
--- /dev/null
+++ b/pkg/front_end/testcases/generic_metadata/function_type_parameter.dart.weak.outline.expect
@@ -0,0 +1,28 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+typedef F = <T extends core::Object? = dynamic>(T%) → void;
+typedef G<@self::A::•<dynamic>() contravariant T extends core::Object? = dynamic> = (T%) → void;
+class A<T extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/  {
+  const constructor •() → self::A<self::A::T%>
+    : super core::Object::•()
+    ;
+}
+class Class<T extends <S extends core::Object? = dynamic>(S%) → void = <S extends core::Object? = dynamic>(S%) → void> extends core::Object {
+  synthetic constructor •() → self::Class<self::Class::T>
+    ;
+}
+static field <T extends core::Object? = dynamic>(T%) →? void f;
+static method method1<@self::A::•<core::String>() T extends core::Object? = dynamic>(self::method1::T% t) → void
+  ;
+static method method2(<T extends core::Object? = dynamic>(T%) → void f) → void
+  ;
+static method main() → dynamic
+  ;
+
+
+Extra constant evaluation status:
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///function_type_parameter.dart:13:17 -> InstanceConstant(const A<dynamic>{})
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///function_type_parameter.dart:15:15 -> InstanceConstant(const A<String*>{})
+Extra constant evaluation: evaluated: 2, effectively constant: 2
diff --git a/pkg/front_end/testcases/generic_metadata/function_type_parameter.dart.weak.transformed.expect b/pkg/front_end/testcases/generic_metadata/function_type_parameter.dart.weak.transformed.expect
new file mode 100644
index 0000000..c1ead73
--- /dev/null
+++ b/pkg/front_end/testcases/generic_metadata/function_type_parameter.dart.weak.transformed.expect
@@ -0,0 +1,35 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+typedef F = <T extends core::Object? = dynamic>(T%) → void;
+typedef G<@#C1 contravariant T extends core::Object? = dynamic> = (T%) → void;
+class A<T extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/  {
+  const constructor •() → self::A<self::A::T%>
+    : super core::Object::•()
+    ;
+}
+class Class<T extends <S extends core::Object? = dynamic>(S%) → void = <S extends core::Object? = dynamic>(S%) → void> extends core::Object {
+  synthetic constructor •() → self::Class<self::Class::T>
+    : super core::Object::•()
+    ;
+}
+static field <T extends core::Object? = dynamic>(T%) →? void f;
+static method method1<@#C2 T extends core::Object? = dynamic>(self::method1::T% t) → void {}
+static method method2(<T extends core::Object? = dynamic>(T%) → void f) → void {}
+static method main() → dynamic {
+  function local<@#C3 T extends core::Object? = dynamic>(T% t) → void {}
+  <T extends core::Object? = dynamic>(T%) →? void f;
+}
+
+constants  {
+  #C1 = self::A<dynamic> {}
+  #C2 = self::A<core::String*> {}
+  #C3 = self::A<core::double*> {}
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///function_type_parameter.dart:
+- A. (from org-dartlang-testcase:///function_type_parameter.dart:6:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/generic_metadata/generic_metadata.dart.textual_outline.expect b/pkg/front_end/testcases/generic_metadata/generic_metadata.dart.textual_outline.expect
index e109be7..0224cb7 100644
--- a/pkg/front_end/testcases/generic_metadata/generic_metadata.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/generic_metadata/generic_metadata.dart.textual_outline.expect
@@ -1,15 +1,19 @@
 class A<T> {
   const A();
 }
+
 class B<S, T> {
   const B();
 }
+
 class C<T extends num> {
   const C();
 }
+
 class D<S extends num, T extends S> {
   const D();
 }
+
 @A<int, num>()
 @B<int>()
 @C<String>()
diff --git a/pkg/front_end/testcases/generic_metadata/generic_metadata.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/generic_metadata/generic_metadata.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d5e1444
--- /dev/null
+++ b/pkg/front_end/testcases/generic_metadata/generic_metadata.dart.textual_outline_modelled.expect
@@ -0,0 +1,32 @@
+class A<T> {
+  const A();
+}
+
+class B<S, T> {
+  const B();
+}
+
+class C<T extends num> {
+  const C();
+}
+
+class D<S extends num, T extends S> {
+  const D();
+}
+
+@A()
+@A<int>()
+@B()
+@B<int, String>()
+@C()
+@C<num>()
+@C<int>()
+@D()
+@D<num, num>()
+@D<num, int>()
+main() {}
+@A<int, num>()
+@B<int>()
+@C<String>()
+@D<int, num>()
+test() {}
diff --git a/pkg/front_end/testcases/generic_metadata/issue45330.dart b/pkg/front_end/testcases/generic_metadata/issue45330.dart
new file mode 100644
index 0000000..95ebfd0
--- /dev/null
+++ b/pkg/front_end/testcases/generic_metadata/issue45330.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for 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 'issue45330_lib.dart';
+
+void genericMethod<T>() {}
+
+testInMain() {
+  genericMethod<void Function<T extends T>()>();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/generic_metadata/issue45330.dart.strong.expect b/pkg/front_end/testcases/generic_metadata/issue45330.dart.strong.expect
new file mode 100644
index 0000000..bf8ebf6
--- /dev/null
+++ b/pkg/front_end/testcases/generic_metadata/issue45330.dart.strong.expect
@@ -0,0 +1,26 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/generic_metadata/issue45330.dart:10:31: Error: Type 'T' is a bound of itself via 'T'.
+// Try breaking the cycle by removing at least on of the 'extends' clauses in the cycle.
+//   genericMethod<void Function<T extends T>()>();
+//                               ^
+//
+// pkg/front_end/testcases/generic_metadata/issue45330_lib.dart:35:31: Error: Type 'T' is a bound of itself via 'T'.
+// Try breaking the cycle by removing at least on of the 'extends' clauses in the cycle.
+//   genericMethod<void Function<T extends T>()>();
+//                               ^
+//
+import self as self;
+import "dart:core" as core;
+
+part issue45330_lib.dart;
+static method genericMethod<T extends core::Object? = dynamic>() → void {}
+static method testInMain() → dynamic {
+  self::genericMethod<<T extends invalid-type = invalid-type>() → void>();
+}
+static method main() → dynamic {}
+static method /* from org-dartlang-testcase:///issue45330_lib.dart */ testInPart() → dynamic {
+  self::genericMethod<<T extends invalid-type = invalid-type>() → void>();
+}
diff --git a/pkg/front_end/testcases/generic_metadata/issue45330.dart.strong.transformed.expect b/pkg/front_end/testcases/generic_metadata/issue45330.dart.strong.transformed.expect
new file mode 100644
index 0000000..bf8ebf6
--- /dev/null
+++ b/pkg/front_end/testcases/generic_metadata/issue45330.dart.strong.transformed.expect
@@ -0,0 +1,26 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/generic_metadata/issue45330.dart:10:31: Error: Type 'T' is a bound of itself via 'T'.
+// Try breaking the cycle by removing at least on of the 'extends' clauses in the cycle.
+//   genericMethod<void Function<T extends T>()>();
+//                               ^
+//
+// pkg/front_end/testcases/generic_metadata/issue45330_lib.dart:35:31: Error: Type 'T' is a bound of itself via 'T'.
+// Try breaking the cycle by removing at least on of the 'extends' clauses in the cycle.
+//   genericMethod<void Function<T extends T>()>();
+//                               ^
+//
+import self as self;
+import "dart:core" as core;
+
+part issue45330_lib.dart;
+static method genericMethod<T extends core::Object? = dynamic>() → void {}
+static method testInMain() → dynamic {
+  self::genericMethod<<T extends invalid-type = invalid-type>() → void>();
+}
+static method main() → dynamic {}
+static method /* from org-dartlang-testcase:///issue45330_lib.dart */ testInPart() → dynamic {
+  self::genericMethod<<T extends invalid-type = invalid-type>() → void>();
+}
diff --git a/pkg/front_end/testcases/generic_metadata/issue45330.dart.textual_outline.expect b/pkg/front_end/testcases/generic_metadata/issue45330.dart.textual_outline.expect
new file mode 100644
index 0000000..23719be
--- /dev/null
+++ b/pkg/front_end/testcases/generic_metadata/issue45330.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+part 'issue45330_lib.dart';
+
+void genericMethod<T>() {}
+testInMain() {}
+main() {}
diff --git a/pkg/front_end/testcases/generic_metadata/issue45330.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/generic_metadata/issue45330.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..eb6bf12
--- /dev/null
+++ b/pkg/front_end/testcases/generic_metadata/issue45330.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+part 'issue45330_lib.dart';
+
+main() {}
+testInMain() {}
+void genericMethod<T>() {}
diff --git a/pkg/front_end/testcases/generic_metadata/issue45330.dart.weak.expect b/pkg/front_end/testcases/generic_metadata/issue45330.dart.weak.expect
new file mode 100644
index 0000000..bf8ebf6
--- /dev/null
+++ b/pkg/front_end/testcases/generic_metadata/issue45330.dart.weak.expect
@@ -0,0 +1,26 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/generic_metadata/issue45330.dart:10:31: Error: Type 'T' is a bound of itself via 'T'.
+// Try breaking the cycle by removing at least on of the 'extends' clauses in the cycle.
+//   genericMethod<void Function<T extends T>()>();
+//                               ^
+//
+// pkg/front_end/testcases/generic_metadata/issue45330_lib.dart:35:31: Error: Type 'T' is a bound of itself via 'T'.
+// Try breaking the cycle by removing at least on of the 'extends' clauses in the cycle.
+//   genericMethod<void Function<T extends T>()>();
+//                               ^
+//
+import self as self;
+import "dart:core" as core;
+
+part issue45330_lib.dart;
+static method genericMethod<T extends core::Object? = dynamic>() → void {}
+static method testInMain() → dynamic {
+  self::genericMethod<<T extends invalid-type = invalid-type>() → void>();
+}
+static method main() → dynamic {}
+static method /* from org-dartlang-testcase:///issue45330_lib.dart */ testInPart() → dynamic {
+  self::genericMethod<<T extends invalid-type = invalid-type>() → void>();
+}
diff --git a/pkg/front_end/testcases/generic_metadata/issue45330.dart.weak.outline.expect b/pkg/front_end/testcases/generic_metadata/issue45330.dart.weak.outline.expect
new file mode 100644
index 0000000..fc3746d
--- /dev/null
+++ b/pkg/front_end/testcases/generic_metadata/issue45330.dart.weak.outline.expect
@@ -0,0 +1,13 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+part issue45330_lib.dart;
+static method genericMethod<T extends core::Object? = dynamic>() → void
+  ;
+static method testInMain() → dynamic
+  ;
+static method main() → dynamic
+  ;
+static method /* from org-dartlang-testcase:///issue45330_lib.dart */ testInPart() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/generic_metadata/issue45330.dart.weak.transformed.expect b/pkg/front_end/testcases/generic_metadata/issue45330.dart.weak.transformed.expect
new file mode 100644
index 0000000..bf8ebf6
--- /dev/null
+++ b/pkg/front_end/testcases/generic_metadata/issue45330.dart.weak.transformed.expect
@@ -0,0 +1,26 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/generic_metadata/issue45330.dart:10:31: Error: Type 'T' is a bound of itself via 'T'.
+// Try breaking the cycle by removing at least on of the 'extends' clauses in the cycle.
+//   genericMethod<void Function<T extends T>()>();
+//                               ^
+//
+// pkg/front_end/testcases/generic_metadata/issue45330_lib.dart:35:31: Error: Type 'T' is a bound of itself via 'T'.
+// Try breaking the cycle by removing at least on of the 'extends' clauses in the cycle.
+//   genericMethod<void Function<T extends T>()>();
+//                               ^
+//
+import self as self;
+import "dart:core" as core;
+
+part issue45330_lib.dart;
+static method genericMethod<T extends core::Object? = dynamic>() → void {}
+static method testInMain() → dynamic {
+  self::genericMethod<<T extends invalid-type = invalid-type>() → void>();
+}
+static method main() → dynamic {}
+static method /* from org-dartlang-testcase:///issue45330_lib.dart */ testInPart() → dynamic {
+  self::genericMethod<<T extends invalid-type = invalid-type>() → void>();
+}
diff --git a/pkg/front_end/testcases/generic_metadata/issue45330_lib.dart b/pkg/front_end/testcases/generic_metadata/issue45330_lib.dart
new file mode 100644
index 0000000..1772937
--- /dev/null
+++ b/pkg/front_end/testcases/generic_metadata/issue45330_lib.dart
@@ -0,0 +1,36 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Long comment to increase error offset.
+// Long comment to increase error offset.
+// Long comment to increase error offset.
+// Long comment to increase error offset.
+// Long comment to increase error offset.
+// Long comment to increase error offset.
+// Long comment to increase error offset.
+// Long comment to increase error offset.
+// Long comment to increase error offset.
+// Long comment to increase error offset.
+// Long comment to increase error offset.
+// Long comment to increase error offset.
+// Long comment to increase error offset.
+// Long comment to increase error offset.
+// Long comment to increase error offset.
+// Long comment to increase error offset.
+// Long comment to increase error offset.
+// Long comment to increase error offset.
+// Long comment to increase error offset.
+// Long comment to increase error offset.
+// Long comment to increase error offset.
+// Long comment to increase error offset.
+// Long comment to increase error offset.
+// Long comment to increase error offset.
+// Long comment to increase error offset.
+// Long comment to increase error offset.
+
+part of 'issue45330.dart';
+
+testInPart() {
+  genericMethod<void Function<T extends T>()>();
+}
diff --git a/pkg/front_end/testcases/generic_metadata/type_parameters_in_default_types.dart b/pkg/front_end/testcases/generic_metadata/type_parameters_in_default_types.dart
new file mode 100644
index 0000000..70b0804
--- /dev/null
+++ b/pkg/front_end/testcases/generic_metadata/type_parameters_in_default_types.dart
@@ -0,0 +1,7 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+foo<X extends Function<Y extends X>()>() {}
+
+main() {}
diff --git a/pkg/front_end/testcases/generic_metadata/type_parameters_in_default_types.dart.strong.expect b/pkg/front_end/testcases/generic_metadata/type_parameters_in_default_types.dart.strong.expect
new file mode 100644
index 0000000..52d8793
--- /dev/null
+++ b/pkg/front_end/testcases/generic_metadata/type_parameters_in_default_types.dart.strong.expect
@@ -0,0 +1,5 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+
+static method foo<X extends <Y extends self::foo::X = dynamic>() → dynamic = <Y extends dynamic = dynamic>() → dynamic>() → dynamic {}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/generic_metadata/type_parameters_in_default_types.dart.strong.transformed.expect b/pkg/front_end/testcases/generic_metadata/type_parameters_in_default_types.dart.strong.transformed.expect
new file mode 100644
index 0000000..52d8793
--- /dev/null
+++ b/pkg/front_end/testcases/generic_metadata/type_parameters_in_default_types.dart.strong.transformed.expect
@@ -0,0 +1,5 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+
+static method foo<X extends <Y extends self::foo::X = dynamic>() → dynamic = <Y extends dynamic = dynamic>() → dynamic>() → dynamic {}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/generic_metadata/type_parameters_in_default_types.dart.textual_outline.expect b/pkg/front_end/testcases/generic_metadata/type_parameters_in_default_types.dart.textual_outline.expect
new file mode 100644
index 0000000..e6c43cd
--- /dev/null
+++ b/pkg/front_end/testcases/generic_metadata/type_parameters_in_default_types.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+foo<X extends Function<Y extends X>()>() {}
+main() {}
diff --git a/pkg/front_end/testcases/generic_metadata/type_parameters_in_default_types.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/generic_metadata/type_parameters_in_default_types.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e6c43cd
--- /dev/null
+++ b/pkg/front_end/testcases/generic_metadata/type_parameters_in_default_types.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+foo<X extends Function<Y extends X>()>() {}
+main() {}
diff --git a/pkg/front_end/testcases/generic_metadata/type_parameters_in_default_types.dart.weak.expect b/pkg/front_end/testcases/generic_metadata/type_parameters_in_default_types.dart.weak.expect
new file mode 100644
index 0000000..52d8793
--- /dev/null
+++ b/pkg/front_end/testcases/generic_metadata/type_parameters_in_default_types.dart.weak.expect
@@ -0,0 +1,5 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+
+static method foo<X extends <Y extends self::foo::X = dynamic>() → dynamic = <Y extends dynamic = dynamic>() → dynamic>() → dynamic {}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/generic_metadata/type_parameters_in_default_types.dart.weak.outline.expect b/pkg/front_end/testcases/generic_metadata/type_parameters_in_default_types.dart.weak.outline.expect
new file mode 100644
index 0000000..3b0732a
--- /dev/null
+++ b/pkg/front_end/testcases/generic_metadata/type_parameters_in_default_types.dart.weak.outline.expect
@@ -0,0 +1,7 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+
+static method foo<X extends <Y extends self::foo::X = dynamic>() → dynamic = <Y extends dynamic = dynamic>() → dynamic>() → dynamic
+  ;
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/generic_metadata/type_parameters_in_default_types.dart.weak.transformed.expect b/pkg/front_end/testcases/generic_metadata/type_parameters_in_default_types.dart.weak.transformed.expect
new file mode 100644
index 0000000..52d8793
--- /dev/null
+++ b/pkg/front_end/testcases/generic_metadata/type_parameters_in_default_types.dart.weak.transformed.expect
@@ -0,0 +1,5 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+
+static method foo<X extends <Y extends self::foo::X = dynamic>() → dynamic = <Y extends dynamic = dynamic>() → dynamic>() → dynamic {}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/implicit_getter_calls/getter_call.dart.weak.expect b/pkg/front_end/testcases/implicit_getter_calls/getter_call.dart.weak.expect
index b452cdb..2b4c9cc 100644
--- a/pkg/front_end/testcases/implicit_getter_calls/getter_call.dart.weak.expect
+++ b/pkg/front_end/testcases/implicit_getter_calls/getter_call.dart.weak.expect
@@ -153,25 +153,25 @@
 }
 static method callGetter(self::Class* c) → dynamic {
   self::expect(0, c.{self::Class::getter1a}());
-  self::expect(0, c.{self::Class::getter1b}());
-  self::expect(42.{core::int::unary-}(){() →* core::int*}, let final self::Class* #t31 = c in let final core::int* #t32 = self::read(42) in #t31.{self::Class::getter2}(#t32));
-  self::expect(11.{core::int::unary-}(){() →* core::int*}, let final self::Class* #t33 = c in let final core::int* #t34 = self::read(12) in let final core::int* #t35 = self::read(23) in #t33.{self::Class::getter3}(#t34, #t35));
-  self::expect(12, let final self::Class* #t36 = c in let final core::int* #t37 = self::read(12) in #t36.{self::Class::getter4}(#t37));
-  self::expect(11.{core::int::unary-}(){() →* core::int*}, let final self::Class* #t38 = c in let final core::int* #t39 = self::read(12) in let final core::int* #t40 = self::read(23) in #t38.{self::Class::getter4}(#t39, #t40));
-  self::expect(0, c.{self::Class::getter5}());
-  self::expect(12, let final self::Class* #t41 = c in let final core::int* #t42 = self::read(12) in #t41.{self::Class::getter5}(#t42));
-  self::expect(11.{core::int::unary-}(){() →* core::int*}, let final self::Class* #t43 = c in let final core::int* #t44 = self::read(12) in let final core::int* #t45 = self::read(23) in #t43.{self::Class::getter5}(#t44, #t45));
-  self::expect(12, let final self::Class* #t46 = c in let final core::int* #t47 = self::read(12) in #t46.{self::Class::getter6}(#t47));
-  self::expect(11.{core::int::unary-}(){() →* core::int*}, let final self::Class* #t48 = c in let final core::int* #t49 = self::read(12) in let final core::int* #t50 = self::read(23) in #t48.{self::Class::getter6}(#t49, b: #t50));
-  self::expect(0, c.{self::Class::getter7}());
-  self::expect(12, let final self::Class* #t51 = c in let final core::int* #t52 = self::read(12) in #t51.{self::Class::getter7}(a: #t52));
-  self::expect(23.{core::int::unary-}(){() →* core::int*}, let final self::Class* #t53 = c in let final core::int* #t54 = self::read(23) in #t53.{self::Class::getter7}(b: #t54));
-  self::expect(11.{core::int::unary-}(){() →* core::int*}, let final self::Class* #t55 = c in let final core::int* #t56 = self::read(12) in let final core::int* #t57 = self::read(23) in #t55.{self::Class::getter7}(a: #t56, b: #t57));
-  self::expect(11.{core::int::unary-}(){() →* core::int*}, let final self::Class* #t58 = c in let final core::int* #t59 = self::read(23) in let final core::int* #t60 = self::read(12) in #t58.{self::Class::getter7}(b: #t59, a: #t60));
+  self::expect(0, c.{self::Class::getter1b}(){() →* core::int*});
+  self::expect(42.{core::int::unary-}(){() →* core::int*}, let final self::Class* #t31 = c in let final core::int* #t32 = self::read(42) in #t31.{self::Class::getter2}(#t32){(core::int*) →* core::int*});
+  self::expect(11.{core::int::unary-}(){() →* core::int*}, let final self::Class* #t33 = c in let final core::int* #t34 = self::read(12) in let final core::int* #t35 = self::read(23) in #t33.{self::Class::getter3}(#t34, #t35){(core::int*, core::int*) →* core::int*});
+  self::expect(12, let final self::Class* #t36 = c in let final core::int* #t37 = self::read(12) in #t36.{self::Class::getter4}(#t37){(core::int*, [core::int*]) →* core::int*});
+  self::expect(11.{core::int::unary-}(){() →* core::int*}, let final self::Class* #t38 = c in let final core::int* #t39 = self::read(12) in let final core::int* #t40 = self::read(23) in #t38.{self::Class::getter4}(#t39, #t40){(core::int*, [core::int*]) →* core::int*});
+  self::expect(0, c.{self::Class::getter5}(){([core::int*, core::int*]) →* core::int*});
+  self::expect(12, let final self::Class* #t41 = c in let final core::int* #t42 = self::read(12) in #t41.{self::Class::getter5}(#t42){([core::int*, core::int*]) →* core::int*});
+  self::expect(11.{core::int::unary-}(){() →* core::int*}, let final self::Class* #t43 = c in let final core::int* #t44 = self::read(12) in let final core::int* #t45 = self::read(23) in #t43.{self::Class::getter5}(#t44, #t45){([core::int*, core::int*]) →* core::int*});
+  self::expect(12, let final self::Class* #t46 = c in let final core::int* #t47 = self::read(12) in #t46.{self::Class::getter6}(#t47){(core::int*, {b: core::int*}) →* core::int*});
+  self::expect(11.{core::int::unary-}(){() →* core::int*}, let final self::Class* #t48 = c in let final core::int* #t49 = self::read(12) in let final core::int* #t50 = self::read(23) in #t48.{self::Class::getter6}(#t49, b: #t50){(core::int*, {b: core::int*}) →* core::int*});
+  self::expect(0, c.{self::Class::getter7}(){({a: core::int*, b: core::int*}) →* core::int*});
+  self::expect(12, let final self::Class* #t51 = c in let final core::int* #t52 = self::read(12) in #t51.{self::Class::getter7}(a: #t52){({a: core::int*, b: core::int*}) →* core::int*});
+  self::expect(23.{core::int::unary-}(){() →* core::int*}, let final self::Class* #t53 = c in let final core::int* #t54 = self::read(23) in #t53.{self::Class::getter7}(b: #t54){({a: core::int*, b: core::int*}) →* core::int*});
+  self::expect(11.{core::int::unary-}(){() →* core::int*}, let final self::Class* #t55 = c in let final core::int* #t56 = self::read(12) in let final core::int* #t57 = self::read(23) in #t55.{self::Class::getter7}(a: #t56, b: #t57){({a: core::int*, b: core::int*}) →* core::int*});
+  self::expect(11.{core::int::unary-}(){() →* core::int*}, let final self::Class* #t58 = c in let final core::int* #t59 = self::read(23) in let final core::int* #t60 = self::read(12) in #t58.{self::Class::getter7}(b: #t59, a: #t60){({a: core::int*, b: core::int*}) →* core::int*});
 }
 static method expect(dynamic expected, dynamic actual) → dynamic {
   self::enableRead = true;
-  if(expected !={core::Object::==}{(core::Object*) →* core::bool*} actual)
+  if(!(expected =={core::Object::==}{(core::Object*) →* core::bool*} actual))
     throw "Expected ${expected}, ${actual}";
 }
 
diff --git a/pkg/front_end/testcases/implicit_getter_calls/getter_call.dart.weak.transformed.expect b/pkg/front_end/testcases/implicit_getter_calls/getter_call.dart.weak.transformed.expect
index 7462ff3..3c6b74a 100644
--- a/pkg/front_end/testcases/implicit_getter_calls/getter_call.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/implicit_getter_calls/getter_call.dart.weak.transformed.expect
@@ -153,25 +153,25 @@
 }
 static method callGetter(self::Class* c) → dynamic {
   self::expect(0, c.{self::Class::getter1a}());
-  self::expect(0, c.{self::Class::getter1b}());
-  self::expect(42.{core::int::unary-}(){() →* core::int*}, let final self::Class* #t31 = c in let final core::int* #t32 = self::read(42) in #t31.{self::Class::getter2}(#t32));
-  self::expect(11.{core::int::unary-}(){() →* core::int*}, let final self::Class* #t33 = c in let final core::int* #t34 = self::read(12) in let final core::int* #t35 = self::read(23) in #t33.{self::Class::getter3}(#t34, #t35));
-  self::expect(12, let final self::Class* #t36 = c in let final core::int* #t37 = self::read(12) in #t36.{self::Class::getter4}(#t37));
-  self::expect(11.{core::int::unary-}(){() →* core::int*}, let final self::Class* #t38 = c in let final core::int* #t39 = self::read(12) in let final core::int* #t40 = self::read(23) in #t38.{self::Class::getter4}(#t39, #t40));
-  self::expect(0, c.{self::Class::getter5}());
-  self::expect(12, let final self::Class* #t41 = c in let final core::int* #t42 = self::read(12) in #t41.{self::Class::getter5}(#t42));
-  self::expect(11.{core::int::unary-}(){() →* core::int*}, let final self::Class* #t43 = c in let final core::int* #t44 = self::read(12) in let final core::int* #t45 = self::read(23) in #t43.{self::Class::getter5}(#t44, #t45));
-  self::expect(12, let final self::Class* #t46 = c in let final core::int* #t47 = self::read(12) in #t46.{self::Class::getter6}(#t47));
-  self::expect(11.{core::int::unary-}(){() →* core::int*}, let final self::Class* #t48 = c in let final core::int* #t49 = self::read(12) in let final core::int* #t50 = self::read(23) in #t48.{self::Class::getter6}(#t49, b: #t50));
-  self::expect(0, c.{self::Class::getter7}());
-  self::expect(12, let final self::Class* #t51 = c in let final core::int* #t52 = self::read(12) in #t51.{self::Class::getter7}(a: #t52));
-  self::expect(23.{core::int::unary-}(){() →* core::int*}, let final self::Class* #t53 = c in let final core::int* #t54 = self::read(23) in #t53.{self::Class::getter7}(b: #t54));
-  self::expect(11.{core::int::unary-}(){() →* core::int*}, let final self::Class* #t55 = c in let final core::int* #t56 = self::read(12) in let final core::int* #t57 = self::read(23) in #t55.{self::Class::getter7}(a: #t56, b: #t57));
-  self::expect(11.{core::int::unary-}(){() →* core::int*}, let final self::Class* #t58 = c in let final core::int* #t59 = self::read(23) in let final core::int* #t60 = self::read(12) in #t58.{self::Class::getter7}(b: #t59, a: #t60));
+  self::expect(0, c.{self::Class::getter1b}(){() →* core::int*});
+  self::expect(42.{core::int::unary-}(){() →* core::int*}, let final self::Class* #t31 = c in let final core::int* #t32 = self::read(42) in #t31.{self::Class::getter2}(#t32){(core::int*) →* core::int*});
+  self::expect(11.{core::int::unary-}(){() →* core::int*}, let final self::Class* #t33 = c in let final core::int* #t34 = self::read(12) in let final core::int* #t35 = self::read(23) in #t33.{self::Class::getter3}(#t34, #t35){(core::int*, core::int*) →* core::int*});
+  self::expect(12, let final self::Class* #t36 = c in let final core::int* #t37 = self::read(12) in #t36.{self::Class::getter4}(#t37){(core::int*, [core::int*]) →* core::int*});
+  self::expect(11.{core::int::unary-}(){() →* core::int*}, let final self::Class* #t38 = c in let final core::int* #t39 = self::read(12) in let final core::int* #t40 = self::read(23) in #t38.{self::Class::getter4}(#t39, #t40){(core::int*, [core::int*]) →* core::int*});
+  self::expect(0, c.{self::Class::getter5}(){([core::int*, core::int*]) →* core::int*});
+  self::expect(12, let final self::Class* #t41 = c in let final core::int* #t42 = self::read(12) in #t41.{self::Class::getter5}(#t42){([core::int*, core::int*]) →* core::int*});
+  self::expect(11.{core::int::unary-}(){() →* core::int*}, let final self::Class* #t43 = c in let final core::int* #t44 = self::read(12) in let final core::int* #t45 = self::read(23) in #t43.{self::Class::getter5}(#t44, #t45){([core::int*, core::int*]) →* core::int*});
+  self::expect(12, let final self::Class* #t46 = c in let final core::int* #t47 = self::read(12) in #t46.{self::Class::getter6}(#t47){(core::int*, {b: core::int*}) →* core::int*});
+  self::expect(11.{core::int::unary-}(){() →* core::int*}, let final self::Class* #t48 = c in let final core::int* #t49 = self::read(12) in let final core::int* #t50 = self::read(23) in #t48.{self::Class::getter6}(#t49, b: #t50){(core::int*, {b: core::int*}) →* core::int*});
+  self::expect(0, c.{self::Class::getter7}(){({a: core::int*, b: core::int*}) →* core::int*});
+  self::expect(12, let final self::Class* #t51 = c in let final core::int* #t52 = self::read(12) in #t51.{self::Class::getter7}(a: #t52){({a: core::int*, b: core::int*}) →* core::int*});
+  self::expect(23.{core::int::unary-}(){() →* core::int*}, let final self::Class* #t53 = c in let final core::int* #t54 = self::read(23) in #t53.{self::Class::getter7}(b: #t54){({a: core::int*, b: core::int*}) →* core::int*});
+  self::expect(11.{core::int::unary-}(){() →* core::int*}, let final self::Class* #t55 = c in let final core::int* #t56 = self::read(12) in let final core::int* #t57 = self::read(23) in #t55.{self::Class::getter7}(a: #t56, b: #t57){({a: core::int*, b: core::int*}) →* core::int*});
+  self::expect(11.{core::int::unary-}(){() →* core::int*}, let final self::Class* #t58 = c in let final core::int* #t59 = self::read(23) in let final core::int* #t60 = self::read(12) in #t58.{self::Class::getter7}(b: #t59, a: #t60){({a: core::int*, b: core::int*}) →* core::int*});
 }
 static method expect(dynamic expected, dynamic actual) → dynamic {
   self::enableRead = true;
-  if(expected !={core::Object::==}{(core::Object*) →* core::bool*} actual)
+  if(!(expected =={core::Object::==}{(core::Object*) →* core::bool*} actual))
     throw "Expected ${expected}, ${actual}";
 }
 
@@ -204,4 +204,4 @@
 Evaluated: InstanceInvocation @ org-dartlang-testcase:///getter_call.dart:160:10 -> IntConstant(-23)
 Evaluated: InstanceInvocation @ org-dartlang-testcase:///getter_call.dart:161:10 -> IntConstant(-11)
 Evaluated: InstanceInvocation @ org-dartlang-testcase:///getter_call.dart:162:10 -> IntConstant(-11)
-Extra constant evaluation: evaluated: 321, effectively constant: 17
+Extra constant evaluation: evaluated: 322, effectively constant: 17
diff --git a/pkg/front_end/testcases/incremental/changing_modules_2.yaml.world.1.expect b/pkg/front_end/testcases/incremental/changing_modules_2.yaml.world.1.expect
index ad8a087..41e48cc 100644
--- a/pkg/front_end/testcases/incremental/changing_modules_2.yaml.world.1.expect
+++ b/pkg/front_end/testcases/incremental/changing_modules_2.yaml.world.1.expect
@@ -6,8 +6,8 @@
 }
 library from "package:foo/foo.dart" as foo {
 additionalExports = (a::example,
-  a::example,
-  a::a)
+  a::a,
+  a::example)
 
   export "package:example/a.dart";
 
diff --git a/pkg/front_end/testcases/incremental/changing_modules_2.yaml.world.2.expect b/pkg/front_end/testcases/incremental/changing_modules_2.yaml.world.2.expect
index ad8a087..41e48cc 100644
--- a/pkg/front_end/testcases/incremental/changing_modules_2.yaml.world.2.expect
+++ b/pkg/front_end/testcases/incremental/changing_modules_2.yaml.world.2.expect
@@ -6,8 +6,8 @@
 }
 library from "package:foo/foo.dart" as foo {
 additionalExports = (a::example,
-  a::example,
-  a::a)
+  a::a,
+  a::example)
 
   export "package:example/a.dart";
 
diff --git a/pkg/front_end/testcases/incremental/crash_01.yaml b/pkg/front_end/testcases/incremental/crash_01.yaml
new file mode 100644
index 0000000..d8c9c08
--- /dev/null
+++ b/pkg/front_end/testcases/incremental/crash_01.yaml
@@ -0,0 +1,33 @@
+# 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: app/main.dart
+    sources:
+      .dart_tool/package_config.json: |
+        {
+          "configVersion": 2,
+          "packages": [
+            {
+              "name": "flutter",
+              "rootUri": "../flutter",
+              "languageVersion": "2.12"
+            }
+          ]
+        }
+      app/main.dart: |
+        import "package:flutter/src/cupertino/interface_level.dart";
+      flutter/src/widgets/framework.dart: |
+        abstract class Widget {}
+        abstract class ProxyWidget extends Widget {}
+        abstract class InheritedWidget extends ProxyWidget {}
+      flutter/src/cupertino/interface_level.dart: |
+        import '../widgets/framework.dart';
+        class CupertinoUserInterfaceLevel extends InheritedWidget {}
+    expectedLibraryCount: 3
diff --git a/pkg/front_end/testcases/incremental/crash_01.yaml.world.1.expect b/pkg/front_end/testcases/incremental/crash_01.yaml.world.1.expect
new file mode 100644
index 0000000..137fbff
--- /dev/null
+++ b/pkg/front_end/testcases/incremental/crash_01.yaml.world.1.expect
@@ -0,0 +1,34 @@
+main = <No Member>;
+library from "org-dartlang-test:///app/main.dart" as main {
+
+  import "package:flutter/src/cupertino/interface_level.dart";
+
+}
+library from "package:flutter/src/cupertino/interface_level.dart" as int {
+
+  import "package:flutter/src/widgets/framework.dart";
+
+  class CupertinoUserInterfaceLevel extends fra::InheritedWidget {
+    synthetic constructor •() → int::CupertinoUserInterfaceLevel
+      : super fra::InheritedWidget::•()
+      ;
+  }
+}
+library from "package:flutter/src/widgets/framework.dart" as fra {
+
+  abstract class Widget extends dart.core::Object {
+    synthetic constructor •() → fra::Widget
+      : super dart.core::Object::•()
+      ;
+  }
+  abstract class ProxyWidget extends fra::Widget {
+    synthetic constructor •() → fra::ProxyWidget
+      : super fra::Widget::•()
+      ;
+  }
+  abstract class InheritedWidget extends fra::ProxyWidget {
+    synthetic constructor •() → fra::InheritedWidget
+      : super fra::ProxyWidget::•()
+      ;
+  }
+}
diff --git a/pkg/front_end/testcases/incremental/crash_02.yaml b/pkg/front_end/testcases/incremental/crash_02.yaml
new file mode 100644
index 0000000..7a10c94
--- /dev/null
+++ b/pkg/front_end/testcases/incremental/crash_02.yaml
@@ -0,0 +1,31 @@
+# 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: app/main.dart
+    sources:
+      .dart_tool/package_config.json: |
+        {
+          "configVersion": 2,
+          "packages": [
+            {
+              "name": "flutter",
+              "rootUri": "../flutter",
+              "languageVersion": "2.12"
+            }
+          ]
+        }
+      app/main.dart: |
+        import "package:flutter/src/widgets/framework.dart";
+      flutter/src/widgets/framework.dart: |
+        import "package:flutter/src/widgets/widget_inspector.dart";
+        abstract class Widget {}
+      flutter/src/widgets/widget_inspector.dart: |
+        abstract class _HasCreationLocation {}
+    expectedLibraryCount: 3
diff --git a/pkg/front_end/testcases/incremental/crash_02.yaml.world.1.expect b/pkg/front_end/testcases/incremental/crash_02.yaml.world.1.expect
new file mode 100644
index 0000000..a577623
--- /dev/null
+++ b/pkg/front_end/testcases/incremental/crash_02.yaml.world.1.expect
@@ -0,0 +1,24 @@
+main = <No Member>;
+library from "org-dartlang-test:///app/main.dart" as main {
+
+  import "package:flutter/src/widgets/framework.dart";
+
+}
+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 {
+    synthetic constructor •() → fra::Widget
+      : super dart.core::Object::•()
+      ;
+  }
+}
+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::•()
+      ;
+  }
+}
diff --git a/pkg/front_end/testcases/incremental/crash_03.yaml b/pkg/front_end/testcases/incremental/crash_03.yaml
new file mode 100644
index 0000000..4d1be72
--- /dev/null
+++ b/pkg/front_end/testcases/incremental/crash_03.yaml
@@ -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.md file.
+
+# Reproduce a crash.
+
+type: newworld
+trackWidgetCreation: true
+target: DDC # basically needed for widget creation to be run
+worlds:
+  - entry: app/main.dart
+    sources:
+      .dart_tool/package_config.json: |
+        {
+          "configVersion": 2,
+          "packages": [
+            {
+              "name": "flutter",
+              "rootUri": "../flutter",
+              "languageVersion": "2.12"
+            }
+          ]
+        }
+      app/main.dart: |
+        import "package:flutter/src/widgets/framework.dart";
+      flutter/src/widgets/framework.dart: |
+        abstract class Widget {}
+    expectedLibraryCount: 2
diff --git a/pkg/front_end/testcases/incremental/crash_03.yaml.world.1.expect b/pkg/front_end/testcases/incremental/crash_03.yaml.world.1.expect
new file mode 100644
index 0000000..510e30c
--- /dev/null
+++ b/pkg/front_end/testcases/incremental/crash_03.yaml.world.1.expect
@@ -0,0 +1,14 @@
+main = <No Member>;
+library from "org-dartlang-test:///app/main.dart" as main {
+
+  import "package:flutter/src/widgets/framework.dart";
+
+}
+library from "package:flutter/src/widgets/framework.dart" as fra {
+
+  abstract class Widget extends dart.core::Object {
+    synthetic constructor •() → fra::Widget
+      : super dart.core::Object::•()
+      ;
+  }
+}
diff --git a/pkg/front_end/testcases/incremental/crash_04.yaml b/pkg/front_end/testcases/incremental/crash_04.yaml
new file mode 100644
index 0000000..7a10c94
--- /dev/null
+++ b/pkg/front_end/testcases/incremental/crash_04.yaml
@@ -0,0 +1,31 @@
+# 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: app/main.dart
+    sources:
+      .dart_tool/package_config.json: |
+        {
+          "configVersion": 2,
+          "packages": [
+            {
+              "name": "flutter",
+              "rootUri": "../flutter",
+              "languageVersion": "2.12"
+            }
+          ]
+        }
+      app/main.dart: |
+        import "package:flutter/src/widgets/framework.dart";
+      flutter/src/widgets/framework.dart: |
+        import "package:flutter/src/widgets/widget_inspector.dart";
+        abstract class Widget {}
+      flutter/src/widgets/widget_inspector.dart: |
+        abstract class _HasCreationLocation {}
+    expectedLibraryCount: 3
diff --git a/pkg/front_end/testcases/incremental/crash_04.yaml.world.1.expect b/pkg/front_end/testcases/incremental/crash_04.yaml.world.1.expect
new file mode 100644
index 0000000..a577623
--- /dev/null
+++ b/pkg/front_end/testcases/incremental/crash_04.yaml.world.1.expect
@@ -0,0 +1,24 @@
+main = <No Member>;
+library from "org-dartlang-test:///app/main.dart" as main {
+
+  import "package:flutter/src/widgets/framework.dart";
+
+}
+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 {
+    synthetic constructor •() → fra::Widget
+      : super dart.core::Object::•()
+      ;
+  }
+}
+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::•()
+      ;
+  }
+}
diff --git a/pkg/front_end/testcases/incremental/ffi_01.yaml.world.1.expect b/pkg/front_end/testcases/incremental/ffi_01.yaml.world.1.expect
index b112423..5946f0f 100644
--- a/pkg/front_end/testcases/incremental/ffi_01.yaml.world.1.expect
+++ b/pkg/front_end/testcases/incremental/ffi_01.yaml.world.1.expect
@@ -3,9 +3,9 @@
 
   import "dart:ffi";
 
-  @#C6
+  @#C7
   class Coordinate extends dart.ffi::Struct {
-    static final field dart.core::int* #sizeOf = (#C9).{dart.core::List::[]}(dart.ffi::_abi());
+    static final field dart.core::int* #sizeOf = (#C10).{dart.core::List::[]}(dart.ffi::_abi());
     @#C12
     constructor #fromTypedDataBase(dynamic #pointer) → dynamic
       : super dart.ffi::Struct::_fromPointer(#pointer)
@@ -54,14 +54,14 @@
   #C2 = TypeLiteralConstant(dart.ffi::Double)
   #C3 = TypeLiteralConstant(dart.ffi::Pointer<dart.ffi::NativeType>)
   #C4 = <dart.core::Type>[#C2, #C2, #C3]
-  #C5 = dart.ffi::_FfiStructLayout {fieldTypes:#C4}
-  #C6 = dart.core::pragma {name:#C1, options:#C5}
-  #C7 = 24
-  #C8 = 20
-  #C9 = <dart.core::int*>[#C7, #C8, #C7]
-  #C10 = "vm:entry-point"
-  #C11 = null
-  #C12 = dart.core::pragma {name:#C10, options:#C11}
+  #C5 = null
+  #C6 = dart.ffi::_FfiStructLayout {fieldTypes:#C4, packing:#C5}
+  #C7 = dart.core::pragma {name:#C1, options:#C6}
+  #C8 = 24
+  #C9 = 20
+  #C10 = <dart.core::int*>[#C8, #C9, #C8]
+  #C11 = "vm:entry-point"
+  #C12 = dart.core::pragma {name:#C11, options:#C5}
   #C13 = 0
   #C14 = <dart.core::int*>[#C13, #C13, #C13]
   #C15 = 8
diff --git a/pkg/front_end/testcases/incremental/ffi_01.yaml.world.2.expect b/pkg/front_end/testcases/incremental/ffi_01.yaml.world.2.expect
index 406e797..7095982 100644
--- a/pkg/front_end/testcases/incremental/ffi_01.yaml.world.2.expect
+++ b/pkg/front_end/testcases/incremental/ffi_01.yaml.world.2.expect
@@ -3,9 +3,9 @@
 
   import "dart:ffi";
 
-  @#C6
+  @#C7
   class Coordinate extends dart.ffi::Struct {
-    static final field dart.core::int* #sizeOf = (#C9).{dart.core::List::[]}(dart.ffi::_abi());
+    static final field dart.core::int* #sizeOf = (#C10).{dart.core::List::[]}(dart.ffi::_abi());
     @#C12
     constructor #fromTypedDataBase(dynamic #pointer) → dynamic
       : super dart.ffi::Struct::_fromPointer(#pointer)
@@ -58,14 +58,14 @@
   #C2 = TypeLiteralConstant(dart.ffi::Double)
   #C3 = TypeLiteralConstant(dart.ffi::Pointer<dart.ffi::NativeType>)
   #C4 = <dart.core::Type>[#C2, #C2, #C3]
-  #C5 = dart.ffi::_FfiStructLayout {fieldTypes:#C4}
-  #C6 = dart.core::pragma {name:#C1, options:#C5}
-  #C7 = 24
-  #C8 = 20
-  #C9 = <dart.core::int*>[#C7, #C8, #C7]
-  #C10 = "vm:entry-point"
-  #C11 = null
-  #C12 = dart.core::pragma {name:#C10, options:#C11}
+  #C5 = null
+  #C6 = dart.ffi::_FfiStructLayout {fieldTypes:#C4, packing:#C5}
+  #C7 = dart.core::pragma {name:#C1, options:#C6}
+  #C8 = 24
+  #C9 = 20
+  #C10 = <dart.core::int*>[#C8, #C9, #C8]
+  #C11 = "vm:entry-point"
+  #C12 = dart.core::pragma {name:#C11, options:#C5}
   #C13 = 0
   #C14 = <dart.core::int*>[#C13, #C13, #C13]
   #C15 = 8
diff --git a/pkg/front_end/testcases/incremental/ffi_02.yaml.world.1.expect b/pkg/front_end/testcases/incremental/ffi_02.yaml.world.1.expect
index 29633d6..1bd3802 100644
--- a/pkg/front_end/testcases/incremental/ffi_02.yaml.world.1.expect
+++ b/pkg/front_end/testcases/incremental/ffi_02.yaml.world.1.expect
@@ -3,9 +3,9 @@
 
   import "dart:ffi";
 
-  @#C6
+  @#C7
   class Coordinate extends dart.ffi::Struct {
-    static final field dart.core::int* #sizeOf = (#C9).{dart.core::List::[]}(dart.ffi::_abi());
+    static final field dart.core::int* #sizeOf = (#C10).{dart.core::List::[]}(dart.ffi::_abi());
     @#C12
     constructor #fromTypedDataBase(dynamic #pointer) → dynamic
       : super dart.ffi::Struct::_fromPointer(#pointer)
@@ -55,14 +55,14 @@
   #C2 = TypeLiteralConstant(dart.ffi::Double)
   #C3 = TypeLiteralConstant(dart.ffi::Pointer<dart.ffi::NativeType>)
   #C4 = <dart.core::Type>[#C2, #C2, #C3]
-  #C5 = dart.ffi::_FfiStructLayout {fieldTypes:#C4}
-  #C6 = dart.core::pragma {name:#C1, options:#C5}
-  #C7 = 24
-  #C8 = 20
-  #C9 = <dart.core::int*>[#C7, #C8, #C7]
-  #C10 = "vm:entry-point"
-  #C11 = null
-  #C12 = dart.core::pragma {name:#C10, options:#C11}
+  #C5 = null
+  #C6 = dart.ffi::_FfiStructLayout {fieldTypes:#C4, packing:#C5}
+  #C7 = dart.core::pragma {name:#C1, options:#C6}
+  #C8 = 24
+  #C9 = 20
+  #C10 = <dart.core::int*>[#C8, #C9, #C8]
+  #C11 = "vm:entry-point"
+  #C12 = dart.core::pragma {name:#C11, options:#C5}
   #C13 = 0
   #C14 = <dart.core::int*>[#C13, #C13, #C13]
   #C15 = 8
diff --git a/pkg/front_end/testcases/incremental/mixin_inferrer_error.yaml.world.1.expect b/pkg/front_end/testcases/incremental/mixin_inferrer_error.yaml.world.1.expect
index c8038bf..09119c7 100644
--- a/pkg/front_end/testcases/incremental/mixin_inferrer_error.yaml.world.1.expect
+++ b/pkg/front_end/testcases/incremental/mixin_inferrer_error.yaml.world.1.expect
@@ -10,7 +10,7 @@
 // class C extends Object with M {}
 //       ^
 //
-// org-dartlang-test:///main.dart:3:7: Error: Type parameters could not be inferred for the mixin 'M' because 'Object' does not implement the mixin's supertype constraint 'A<T>'.
+// org-dartlang-test:///main.dart:3:7: Error: Type parameters couldn't be inferred for the mixin 'M' because 'Object' does not implement the mixin's supertype constraint 'A<T>'.
 //  - 'A' is from 'org-dartlang-test:///main.dart'.
 // class C extends Object with M {}
 //       ^
diff --git a/pkg/front_end/testcases/incremental/no_outline_change_35.yaml.world.1.expect b/pkg/front_end/testcases/incremental/no_outline_change_35.yaml.world.1.expect
index b112423..5946f0f 100644
--- a/pkg/front_end/testcases/incremental/no_outline_change_35.yaml.world.1.expect
+++ b/pkg/front_end/testcases/incremental/no_outline_change_35.yaml.world.1.expect
@@ -3,9 +3,9 @@
 
   import "dart:ffi";
 
-  @#C6
+  @#C7
   class Coordinate extends dart.ffi::Struct {
-    static final field dart.core::int* #sizeOf = (#C9).{dart.core::List::[]}(dart.ffi::_abi());
+    static final field dart.core::int* #sizeOf = (#C10).{dart.core::List::[]}(dart.ffi::_abi());
     @#C12
     constructor #fromTypedDataBase(dynamic #pointer) → dynamic
       : super dart.ffi::Struct::_fromPointer(#pointer)
@@ -54,14 +54,14 @@
   #C2 = TypeLiteralConstant(dart.ffi::Double)
   #C3 = TypeLiteralConstant(dart.ffi::Pointer<dart.ffi::NativeType>)
   #C4 = <dart.core::Type>[#C2, #C2, #C3]
-  #C5 = dart.ffi::_FfiStructLayout {fieldTypes:#C4}
-  #C6 = dart.core::pragma {name:#C1, options:#C5}
-  #C7 = 24
-  #C8 = 20
-  #C9 = <dart.core::int*>[#C7, #C8, #C7]
-  #C10 = "vm:entry-point"
-  #C11 = null
-  #C12 = dart.core::pragma {name:#C10, options:#C11}
+  #C5 = null
+  #C6 = dart.ffi::_FfiStructLayout {fieldTypes:#C4, packing:#C5}
+  #C7 = dart.core::pragma {name:#C1, options:#C6}
+  #C8 = 24
+  #C9 = 20
+  #C10 = <dart.core::int*>[#C8, #C9, #C8]
+  #C11 = "vm:entry-point"
+  #C12 = dart.core::pragma {name:#C11, options:#C5}
   #C13 = 0
   #C14 = <dart.core::int*>[#C13, #C13, #C13]
   #C15 = 8
diff --git a/pkg/front_end/testcases/incremental/no_outline_change_35.yaml.world.2.expect b/pkg/front_end/testcases/incremental/no_outline_change_35.yaml.world.2.expect
index 5a4e426..9d3a106 100644
--- a/pkg/front_end/testcases/incremental/no_outline_change_35.yaml.world.2.expect
+++ b/pkg/front_end/testcases/incremental/no_outline_change_35.yaml.world.2.expect
@@ -3,9 +3,9 @@
 
   import "dart:ffi";
 
-  @#C6
+  @#C7
   class Coordinate extends dart.ffi::Struct {
-    static final field dart.core::int* #sizeOf = (#C9).{dart.core::List::[]}(dart.ffi::_abi());
+    static final field dart.core::int* #sizeOf = (#C10).{dart.core::List::[]}(dart.ffi::_abi());
     @#C12
     constructor #fromTypedDataBase(dynamic #pointer) → dynamic
       : super dart.ffi::Struct::_fromPointer(#pointer)
@@ -55,14 +55,14 @@
   #C2 = TypeLiteralConstant(dart.ffi::Double)
   #C3 = TypeLiteralConstant(dart.ffi::Pointer<dart.ffi::NativeType>)
   #C4 = <dart.core::Type>[#C2, #C2, #C3]
-  #C5 = dart.ffi::_FfiStructLayout {fieldTypes:#C4}
-  #C6 = dart.core::pragma {name:#C1, options:#C5}
-  #C7 = 24
-  #C8 = 20
-  #C9 = <dart.core::int*>[#C7, #C8, #C7]
-  #C10 = "vm:entry-point"
-  #C11 = null
-  #C12 = dart.core::pragma {name:#C10, options:#C11}
+  #C5 = null
+  #C6 = dart.ffi::_FfiStructLayout {fieldTypes:#C4, packing:#C5}
+  #C7 = dart.core::pragma {name:#C1, options:#C6}
+  #C8 = 24
+  #C9 = 20
+  #C10 = <dart.core::int*>[#C8, #C9, #C8]
+  #C11 = "vm:entry-point"
+  #C12 = dart.core::pragma {name:#C11, options:#C5}
   #C13 = 0
   #C14 = <dart.core::int*>[#C13, #C13, #C13]
   #C15 = 8
diff --git a/pkg/front_end/testcases/incremental/no_outline_change_35.yaml.world.3.expect b/pkg/front_end/testcases/incremental/no_outline_change_35.yaml.world.3.expect
index 3d3c99a..9094ac3 100644
--- a/pkg/front_end/testcases/incremental/no_outline_change_35.yaml.world.3.expect
+++ b/pkg/front_end/testcases/incremental/no_outline_change_35.yaml.world.3.expect
@@ -3,9 +3,9 @@
 
   import "dart:ffi";
 
-  @#C6
+  @#C7
   class Coordinate extends dart.ffi::Struct {
-    static final field dart.core::int* #sizeOf = (#C9).{dart.core::List::[]}(dart.ffi::_abi());
+    static final field dart.core::int* #sizeOf = (#C10).{dart.core::List::[]}(dart.ffi::_abi());
     @#C12
     constructor #fromTypedDataBase(dynamic #pointer) → dynamic
       : super dart.ffi::Struct::_fromPointer(#pointer)
@@ -56,14 +56,14 @@
   #C2 = TypeLiteralConstant(dart.ffi::Double)
   #C3 = TypeLiteralConstant(dart.ffi::Pointer<dart.ffi::NativeType>)
   #C4 = <dart.core::Type>[#C2, #C2, #C3]
-  #C5 = dart.ffi::_FfiStructLayout {fieldTypes:#C4}
-  #C6 = dart.core::pragma {name:#C1, options:#C5}
-  #C7 = 24
-  #C8 = 20
-  #C9 = <dart.core::int*>[#C7, #C8, #C7]
-  #C10 = "vm:entry-point"
-  #C11 = null
-  #C12 = dart.core::pragma {name:#C10, options:#C11}
+  #C5 = null
+  #C6 = dart.ffi::_FfiStructLayout {fieldTypes:#C4, packing:#C5}
+  #C7 = dart.core::pragma {name:#C1, options:#C6}
+  #C8 = 24
+  #C9 = 20
+  #C10 = <dart.core::int*>[#C8, #C9, #C8]
+  #C11 = "vm:entry-point"
+  #C12 = dart.core::pragma {name:#C11, options:#C5}
   #C13 = 0
   #C14 = <dart.core::int*>[#C13, #C13, #C13]
   #C15 = 8
diff --git a/pkg/front_end/testcases/incremental/no_outline_change_43.yaml.world.1.expect b/pkg/front_end/testcases/incremental/no_outline_change_43.yaml.world.1.expect
index cc2970c..83a60c98 100644
--- a/pkg/front_end/testcases/incremental/no_outline_change_43.yaml.world.1.expect
+++ b/pkg/front_end/testcases/incremental/no_outline_change_43.yaml.world.1.expect
@@ -10,8 +10,8 @@
 }
 library from "org-dartlang-test:///libExporter.dart" as lib2 {
 additionalExports = (lib::libField,
-  lib::libField,
-  lib::requireStuffFromLibExporter)
+  lib::requireStuffFromLibExporter,
+  lib::libField)
 
   export "org-dartlang-test:///lib.dart";
 
diff --git a/pkg/front_end/testcases/incremental/no_outline_change_43.yaml.world.2.expect b/pkg/front_end/testcases/incremental/no_outline_change_43.yaml.world.2.expect
index cc2970c..83a60c98 100644
--- a/pkg/front_end/testcases/incremental/no_outline_change_43.yaml.world.2.expect
+++ b/pkg/front_end/testcases/incremental/no_outline_change_43.yaml.world.2.expect
@@ -10,8 +10,8 @@
 }
 library from "org-dartlang-test:///libExporter.dart" as lib2 {
 additionalExports = (lib::libField,
-  lib::libField,
-  lib::requireStuffFromLibExporter)
+  lib::requireStuffFromLibExporter,
+  lib::libField)
 
   export "org-dartlang-test:///lib.dart";
 
diff --git a/pkg/front_end/testcases/incremental/no_outline_change_43.yaml.world.3.expect b/pkg/front_end/testcases/incremental/no_outline_change_43.yaml.world.3.expect
index cc2970c..83a60c98 100644
--- a/pkg/front_end/testcases/incremental/no_outline_change_43.yaml.world.3.expect
+++ b/pkg/front_end/testcases/incremental/no_outline_change_43.yaml.world.3.expect
@@ -10,8 +10,8 @@
 }
 library from "org-dartlang-test:///libExporter.dart" as lib2 {
 additionalExports = (lib::libField,
-  lib::libField,
-  lib::requireStuffFromLibExporter)
+  lib::requireStuffFromLibExporter,
+  lib::libField)
 
   export "org-dartlang-test:///lib.dart";
 
diff --git a/pkg/front_end/testcases/incremental/no_outline_change_43.yaml.world.4.expect b/pkg/front_end/testcases/incremental/no_outline_change_43.yaml.world.4.expect
index cc2970c..83a60c98 100644
--- a/pkg/front_end/testcases/incremental/no_outline_change_43.yaml.world.4.expect
+++ b/pkg/front_end/testcases/incremental/no_outline_change_43.yaml.world.4.expect
@@ -10,8 +10,8 @@
 }
 library from "org-dartlang-test:///libExporter.dart" as lib2 {
 additionalExports = (lib::libField,
-  lib::libField,
-  lib::requireStuffFromLibExporter)
+  lib::requireStuffFromLibExporter,
+  lib::libField)
 
   export "org-dartlang-test:///lib.dart";
 
diff --git a/pkg/front_end/testcases/incremental/no_outline_change_46.yaml b/pkg/front_end/testcases/incremental/no_outline_change_46.yaml
new file mode 100644
index 0000000..6f8b85b
--- /dev/null
+++ b/pkg/front_end/testcases/incremental/no_outline_change_46.yaml
@@ -0,0 +1,27 @@
+# Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+# 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
+target: VM
+worlds:
+  - entry: main.dart
+    experiments: alternative-invalidation-strategy,non-nullable
+    sources:
+      main.dart: |
+        class Foo {
+          external int x;
+        }
+    expectedLibraryCount: 1
+
+  - entry: main.dart
+    experiments: alternative-invalidation-strategy,non-nullable
+    worldType: updated
+    expectInitializeFromDill: false
+    invalidate:
+      - main.dart
+    expectedLibraryCount: 1
+    expectsRebuildBodiesOnly: true
+
diff --git a/pkg/front_end/testcases/incremental/no_outline_change_46.yaml.world.1.expect b/pkg/front_end/testcases/incremental/no_outline_change_46.yaml.world.1.expect
new file mode 100644
index 0000000..35a5f4d
--- /dev/null
+++ b/pkg/front_end/testcases/incremental/no_outline_change_46.yaml.world.1.expect
@@ -0,0 +1,11 @@
+main = <No Member>;
+library from "org-dartlang-test:///main.dart" as main {
+
+  class Foo extends dart.core::Object {
+    synthetic constructor •() → main::Foo
+      : super dart.core::Object::•()
+      ;
+    external get x() → dart.core::int;
+    external set x(dart.core::int #externalFieldValue) → void;
+  }
+}
diff --git a/pkg/front_end/testcases/incremental/no_outline_change_46.yaml.world.2.expect b/pkg/front_end/testcases/incremental/no_outline_change_46.yaml.world.2.expect
new file mode 100644
index 0000000..35a5f4d
--- /dev/null
+++ b/pkg/front_end/testcases/incremental/no_outline_change_46.yaml.world.2.expect
@@ -0,0 +1,11 @@
+main = <No Member>;
+library from "org-dartlang-test:///main.dart" as main {
+
+  class Foo extends dart.core::Object {
+    synthetic constructor •() → main::Foo
+      : super dart.core::Object::•()
+      ;
+    external get x() → dart.core::int;
+    external set x(dart.core::int #externalFieldValue) → void;
+  }
+}
diff --git a/pkg/front_end/testcases/incremental/remove_language_version.yaml b/pkg/front_end/testcases/incremental/remove_language_version.yaml
new file mode 100644
index 0000000..fc000e4
--- /dev/null
+++ b/pkg/front_end/testcases/incremental/remove_language_version.yaml
@@ -0,0 +1,34 @@
+# Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE.md file.
+
+# Compile a library with an explicit language version that prohibits use of
+# null safety syntax. Remove the explicit language version annotation in
+# the update to check the version isn't copied over from the original
+# library.
+
+type: newworld
+worlds:
+  - entry: main.dart
+    experiments: non-nullable
+    errors: true
+    warnings: false
+    sources:
+      main.dart: |
+        // @dart=2.9
+        main() {
+          int? i;
+        }
+    expectedLibraryCount: 1
+  - entry: main.dart
+    experiments: non-nullable
+    invalidate:
+      - main.dart
+    errors: false
+    warnings: false
+    sources:
+      main.dart: |
+        main() {
+          int? i;
+        }
+    expectedLibraryCount: 1
\ No newline at end of file
diff --git a/pkg/front_end/testcases/incremental/remove_language_version.yaml.world.1.expect b/pkg/front_end/testcases/incremental/remove_language_version.yaml.world.1.expect
new file mode 100644
index 0000000..033ad48
--- /dev/null
+++ b/pkg/front_end/testcases/incremental/remove_language_version.yaml.world.1.expect
@@ -0,0 +1,18 @@
+main = main::main;
+library from "org-dartlang-test:///main.dart" as main {
+//
+// Problems in library:
+//
+// org-dartlang-test:///main.dart:3:6: Error: Null safety features are disabled for this library.
+// Try removing the `@dart=` annotation or setting the language version to 2.10 or higher.
+//   int? i;
+//      ^
+// org-dartlang-test:///main.dart:1:1: Context: This is the annotation that opts out this library from null safety features.
+// // @dart=2.9
+// ^^^^^^^^^^^^
+//
+
+  static method main() → dynamic {
+    dart.core::int? i;
+  }
+}
diff --git a/pkg/front_end/testcases/incremental/remove_language_version.yaml.world.2.expect b/pkg/front_end/testcases/incremental/remove_language_version.yaml.world.2.expect
new file mode 100644
index 0000000..c699ac4
--- /dev/null
+++ b/pkg/front_end/testcases/incremental/remove_language_version.yaml.world.2.expect
@@ -0,0 +1,7 @@
+main = main::main;
+library from "org-dartlang-test:///main.dart" as main {
+
+  static method main() → dynamic {
+    dart.core::int? i;
+  }
+}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable.dart b/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable.dart
index 97e6015..5937e4a 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable.dart
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable.dart
@@ -9,14 +9,14 @@
   const Foo(List<String> l);
 }
 
-class C<@Foo(const []) T> {}
+class C<@Foo(/*@typeArgs=String**/ const []) T> {}
 
-typedef void F<@Foo(const []) T>();
+typedef void F<@Foo(/*@typeArgs=String**/ const []) T>();
 
-void f<@Foo(const []) T>() {}
+void f<@Foo(/*@typeArgs=String**/ const []) T>() {}
 
 class D {
-  void m<@Foo(const []) T>() {}
+  void m<@Foo(/*@typeArgs=String**/ const []) T>() {}
 }
 
 main() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable.dart.weak.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable.dart.weak.expect
index 33fedb6..60436b4 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable.dart.weak.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable.dart.weak.expect
@@ -2,7 +2,7 @@
 import self as self;
 import "dart:core" as core;
 
-typedef F<unrelated T extends core::Object* = dynamic> = () →* void;
+typedef F<@#C1 unrelated T extends core::Object* = dynamic> = () →* void;
 class Foo extends core::Object /*hasConstConstructor*/  {
   const constructor •(core::List<core::String*>* l) → self::Foo*
     : super core::Object::•()
@@ -18,7 +18,7 @@
   abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
   abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
 }
-class C<T extends core::Object* = dynamic> extends core::Object {
+class C<@#C1 T extends core::Object* = dynamic> extends core::Object {
   synthetic constructor •() → self::C<self::C::T*>*
     : super core::Object::•()
     ;
@@ -37,7 +37,7 @@
   synthetic constructor •() → self::D*
     : super core::Object::•()
     ;
-  method m<T extends core::Object* = dynamic>() → void {}
+  method m<@#C1 T extends core::Object* = dynamic>() → 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
@@ -49,5 +49,15 @@
   abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
   abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
 }
-static method f<T extends core::Object* = dynamic>() → void {}
+static method f<@#C1 T extends core::Object* = dynamic>() → void {}
 static method main() → dynamic {}
+
+constants  {
+  #C1 = self::Foo {}
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///downwards_inference_annotations_type_variable.dart:
+- Foo. (from org-dartlang-testcase:///downwards_inference_annotations_type_variable.dart:9:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable.dart.weak.outline.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable.dart.weak.outline.expect
index 801fd15..c523b74 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable.dart.weak.outline.expect
@@ -2,7 +2,7 @@
 import self as self;
 import "dart:core" as core;
 
-typedef F<unrelated T extends core::Object* = dynamic> = () →* void;
+typedef F<@self::Foo::•(const <core::String*>[]) unrelated T extends core::Object* = dynamic> = () →* void;
 class Foo extends core::Object /*hasConstConstructor*/  {
   const constructor •(core::List<core::String*>* l) → self::Foo*
     : super core::Object::•()
@@ -18,7 +18,7 @@
   abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
   abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
 }
-class C<T extends core::Object* = dynamic> extends core::Object {
+class C<@self::Foo::•(const <core::String*>[]) T extends core::Object* = dynamic> extends core::Object {
   synthetic constructor •() → self::C<self::C::T*>*
     ;
   abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
@@ -35,7 +35,7 @@
 class D extends core::Object {
   synthetic constructor •() → self::D*
     ;
-  method m<T extends core::Object* = dynamic>() → void
+  method m<@self::Foo::•(const <core::String*>[]) T extends core::Object* = dynamic>() → 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
@@ -48,7 +48,15 @@
   abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
   abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
 }
-static method f<T extends core::Object* = dynamic>() → void
+static method f<@self::Foo::•(const <core::String*>[]) T extends core::Object* = dynamic>() → void
   ;
 static method main() → dynamic
   ;
+
+
+Extra constant evaluation status:
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///downwards_inference_annotations_type_variable.dart:14:17 -> InstanceConstant(const Foo{})
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///downwards_inference_annotations_type_variable.dart:12:10 -> InstanceConstant(const Foo{})
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///downwards_inference_annotations_type_variable.dart:19:11 -> InstanceConstant(const Foo{})
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///downwards_inference_annotations_type_variable.dart:16:9 -> InstanceConstant(const Foo{})
+Extra constant evaluation: evaluated: 4, effectively constant: 4
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable.dart.weak.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable.dart.weak.transformed.expect
index 33fedb6..60436b4 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable.dart.weak.transformed.expect
@@ -2,7 +2,7 @@
 import self as self;
 import "dart:core" as core;
 
-typedef F<unrelated T extends core::Object* = dynamic> = () →* void;
+typedef F<@#C1 unrelated T extends core::Object* = dynamic> = () →* void;
 class Foo extends core::Object /*hasConstConstructor*/  {
   const constructor •(core::List<core::String*>* l) → self::Foo*
     : super core::Object::•()
@@ -18,7 +18,7 @@
   abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
   abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
 }
-class C<T extends core::Object* = dynamic> extends core::Object {
+class C<@#C1 T extends core::Object* = dynamic> extends core::Object {
   synthetic constructor •() → self::C<self::C::T*>*
     : super core::Object::•()
     ;
@@ -37,7 +37,7 @@
   synthetic constructor •() → self::D*
     : super core::Object::•()
     ;
-  method m<T extends core::Object* = dynamic>() → void {}
+  method m<@#C1 T extends core::Object* = dynamic>() → 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
@@ -49,5 +49,15 @@
   abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
   abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
 }
-static method f<T extends core::Object* = dynamic>() → void {}
+static method f<@#C1 T extends core::Object* = dynamic>() → void {}
 static method main() → dynamic {}
+
+constants  {
+  #C1 = self::Foo {}
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///downwards_inference_annotations_type_variable.dart:
+- Foo. (from org-dartlang-testcase:///downwards_inference_annotations_type_variable.dart:9:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_typedef.dart.weak.outline.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_typedef.dart.weak.outline.expect
index 7d68ee4..a88013f 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_annotations_typedef.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_typedef.dart.weak.outline.expect
@@ -2,6 +2,7 @@
 import self as self;
 import "dart:core" as core;
 
+@self::Foo::•(const <core::String*>[])
 typedef F = () →* void;
 class Foo extends core::Object /*hasConstConstructor*/  {
   const constructor •(core::List<core::String*>* l) → self::Foo*
@@ -20,3 +21,8 @@
 }
 static method main() → dynamic
   ;
+
+
+Extra constant evaluation status:
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///downwards_inference_annotations_typedef.dart:12:2 -> InstanceConstant(const Foo{})
+Extra constant evaluation: evaluated: 1, effectively constant: 1
diff --git a/pkg/front_end/testcases/nnbd/assignability.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/assignability.dart.strong.transformed.expect
index 35a2bad..1511c7e 100644
--- a/pkg/front_end/testcases/nnbd/assignability.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/assignability.dart.strong.transformed.expect
@@ -1324,466 +1324,466 @@
   functionVar = let final Never #t104 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:200:17: Error: A value of type 'Function?' can't be assigned to a variable of type 'Function' because 'Function?' is nullable and 'Function' isn't.
  - 'Function' is from 'dart:core'.
   functionVar = functionNullableArg;
-                ^" in let core::Function? #t105 = functionNullableArg in #t105.==(null) ?{core::Function} #t105 as{TypeError,ForNonNullableByDefault} core::Function : #t105{core::Function};
-  functionVar = let final Never #t106 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:201:17: Error: A value of type 'void Function()?' can't be assigned to a variable of type 'Function' because 'void Function()?' is nullable and 'Function' isn't.
+                ^" in functionNullableArg as{TypeError,ForNonNullableByDefault} core::Function;
+  functionVar = let final Never #t105 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:201:17: Error: A value of type 'void Function()?' can't be assigned to a variable of type 'Function' because 'void Function()?' is nullable and 'Function' isn't.
  - 'Function' is from 'dart:core'.
   functionVar = toVoidNullableArg;
-                ^" in let () →? void #t107 = toVoidNullableArg in #t107.==(null) ?{core::Function} #t107 as{TypeError,ForNonNullableByDefault} core::Function : #t107{core::Function};
-  functionVar = let final Never #t108 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:202:17: Error: Can't tear off method 'call' from a potentially null value.
+                ^" in toVoidNullableArg as{TypeError,ForNonNullableByDefault} core::Function;
+  functionVar = let final Never #t106 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:202:17: Error: Can't tear off method 'call' from a potentially null value.
   functionVar = tearoffableNullableArg;
                 ^" in tearoffableNullableArg as{TypeError} core::Function;
-  functionVar = let final Never #t109 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:203:17: Error: A value of type 'XnonNull' can't be assigned to a variable of type 'Function'.
+  functionVar = let final Never #t107 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:203:17: Error: A value of type 'XnonNull' can't be assigned to a variable of type 'Function'.
  - 'Function' is from 'dart:core'.
   functionVar = xNonNullArg;
                 ^" in xNonNullArg as{TypeError,ForNonNullableByDefault} core::Function;
-  functionVar = let final Never #t110 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:204:17: Error: A value of type 'XnonNull?' can't be assigned to a variable of type 'Function'.
+  functionVar = let final Never #t108 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:204:17: Error: A value of type 'XnonNull?' can't be assigned to a variable of type 'Function'.
  - 'Function' is from 'dart:core'.
   functionVar = xNonNullNullableArg;
                 ^" in xNonNullNullableArg as{TypeError,ForNonNullableByDefault} core::Function;
-  functionVar = let final Never #t111 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:205:17: Error: A value of type 'XpotentiallyNull' can't be assigned to a variable of type 'Function'.
+  functionVar = let final Never #t109 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:205:17: Error: A value of type 'XpotentiallyNull' can't be assigned to a variable of type 'Function'.
  - 'Function' is from 'dart:core'.
   functionVar = xPotentiallyNullArg;
                 ^" in xPotentiallyNullArg as{TypeError,ForNonNullableByDefault} core::Function;
-  functionVar = let final Never #t112 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:206:17: Error: A value of type 'XpotentiallyNull?' can't be assigned to a variable of type 'Function'.
+  functionVar = let final Never #t110 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:206:17: Error: A value of type 'XpotentiallyNull?' can't be assigned to a variable of type 'Function'.
  - 'Function' is from 'dart:core'.
   functionVar = xPotentiallyNullNullableArg;
                 ^" in xPotentiallyNullNullableArg as{TypeError,ForNonNullableByDefault} core::Function;
-  functionVar = let final Never #t113 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:207:17: Error: A value of type 'YnonNull' can't be assigned to a variable of type 'Function'.
+  functionVar = let final Never #t111 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:207:17: Error: A value of type 'YnonNull' can't be assigned to a variable of type 'Function'.
  - 'Function' is from 'dart:core'.
   functionVar = yNonNullArg;
                 ^" in yNonNullArg as{TypeError,ForNonNullableByDefault} core::Function;
-  functionVar = let final Never #t114 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:208:17: Error: A value of type 'YnonNull?' can't be assigned to a variable of type 'Function'.
+  functionVar = let final Never #t112 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:208:17: Error: A value of type 'YnonNull?' can't be assigned to a variable of type 'Function'.
  - 'Function' is from 'dart:core'.
   functionVar = yNonNullNullableArg;
                 ^" in yNonNullNullableArg as{TypeError,ForNonNullableByDefault} core::Function;
-  functionVar = let final Never #t115 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:209:17: Error: A value of type 'YpotentiallyNull' can't be assigned to a variable of type 'Function'.
+  functionVar = let final Never #t113 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:209:17: Error: A value of type 'YpotentiallyNull' can't be assigned to a variable of type 'Function'.
  - 'Function' is from 'dart:core'.
   functionVar = yPotentiallyNullArg;
                 ^" in yPotentiallyNullArg as{TypeError,ForNonNullableByDefault} core::Function;
-  functionVar = let final Never #t116 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:210:17: Error: A value of type 'YpotentiallyNull?' can't be assigned to a variable of type 'Function'.
+  functionVar = let final Never #t114 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:210:17: Error: A value of type 'YpotentiallyNull?' can't be assigned to a variable of type 'Function'.
  - 'Function' is from 'dart:core'.
   functionVar = yPotentiallyNullNullableArg;
                 ^" in yPotentiallyNullNullableArg as{TypeError,ForNonNullableByDefault} core::Function;
-  () → void toVoidVar = let final Never #t117 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:212:31: Error: A value of type 'Object' can't be assigned to a variable of type 'void Function()'.
+  () → void toVoidVar = let final Never #t115 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:212:31: Error: A value of type 'Object' can't be assigned to a variable of type 'void Function()'.
  - 'Object' is from 'dart:core'.
   void Function() toVoidVar = objectArg;
                               ^" in objectArg as{TypeError,ForNonNullableByDefault} () → void;
-  toVoidVar = let final Never #t118 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:213:15: Error: A value of type 'Object?' can't be assigned to a variable of type 'void Function()'.
+  toVoidVar = let final Never #t116 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:213:15: Error: A value of type 'Object?' can't be assigned to a variable of type 'void Function()'.
  - 'Object' is from 'dart:core'.
   toVoidVar = objectNullableArg;
               ^" in objectNullableArg as{TypeError,ForNonNullableByDefault} () → void;
-  toVoidVar = let final Never #t119 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:214:15: Error: A value of type 'num' can't be assigned to a variable of type 'void Function()'.
+  toVoidVar = let final Never #t117 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:214:15: Error: A value of type 'num' can't be assigned to a variable of type 'void Function()'.
   toVoidVar = numArg;
               ^" in numArg as{TypeError,ForNonNullableByDefault} () → void;
-  toVoidVar = let final Never #t120 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:215:15: Error: A value of type 'num?' can't be assigned to a variable of type 'void Function()'.
+  toVoidVar = let final Never #t118 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:215:15: Error: A value of type 'num?' can't be assigned to a variable of type 'void Function()'.
   toVoidVar = numNullableArg;
               ^" in numNullableArg as{TypeError,ForNonNullableByDefault} () → void;
-  toVoidVar = let final Never #t121 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:216:15: Error: A value of type 'int' can't be assigned to a variable of type 'void Function()'.
+  toVoidVar = let final Never #t119 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:216:15: Error: A value of type 'int' can't be assigned to a variable of type 'void Function()'.
   toVoidVar = intArg;
               ^" in intArg as{TypeError,ForNonNullableByDefault} () → void;
-  toVoidVar = let final Never #t122 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:217:15: Error: A value of type 'int?' can't be assigned to a variable of type 'void Function()'.
+  toVoidVar = let final Never #t120 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:217:15: Error: A value of type 'int?' can't be assigned to a variable of type 'void Function()'.
   toVoidVar = intNullableArg;
               ^" in intNullableArg as{TypeError,ForNonNullableByDefault} () → void;
-  toVoidVar = let final Never #t123 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:218:15: Error: A value of type 'double' can't be assigned to a variable of type 'void Function()'.
+  toVoidVar = let final Never #t121 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:218:15: Error: A value of type 'double' can't be assigned to a variable of type 'void Function()'.
   toVoidVar = doubleArg;
               ^" in doubleArg as{TypeError,ForNonNullableByDefault} () → void;
-  toVoidVar = let final Never #t124 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:219:15: Error: A value of type 'double?' can't be assigned to a variable of type 'void Function()'.
+  toVoidVar = let final Never #t122 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:219:15: Error: A value of type 'double?' can't be assigned to a variable of type 'void Function()'.
   toVoidVar = doubleNullableArg;
               ^" in doubleNullableArg as{TypeError,ForNonNullableByDefault} () → void;
-  toVoidVar = let final Never #t125 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:220:15: Error: A value of type 'Function' can't be assigned to a variable of type 'void Function()'.
+  toVoidVar = let final Never #t123 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:220:15: Error: A value of type 'Function' can't be assigned to a variable of type 'void Function()'.
  - 'Function' is from 'dart:core'.
   toVoidVar = functionArg;
               ^" in functionArg as{TypeError,ForNonNullableByDefault} () → void;
-  toVoidVar = let final Never #t126 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:221:15: Error: A value of type 'Function?' can't be assigned to a variable of type 'void Function()'.
+  toVoidVar = let final Never #t124 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:221:15: Error: A value of type 'Function?' can't be assigned to a variable of type 'void Function()'.
  - 'Function' is from 'dart:core'.
   toVoidVar = functionNullableArg;
               ^" in functionNullableArg as{TypeError,ForNonNullableByDefault} () → void;
-  toVoidVar = let final Never #t127 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:222:15: Error: A value of type 'void Function()?' can't be assigned to a variable of type 'void Function()' because 'void Function()?' is nullable and 'void Function()' isn't.
+  toVoidVar = let final Never #t125 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:222:15: Error: A value of type 'void Function()?' can't be assigned to a variable of type 'void Function()' because 'void Function()?' is nullable and 'void Function()' isn't.
   toVoidVar = toVoidNullableArg;
-              ^" in let () →? void #t128 = toVoidNullableArg in #t128.==(null) ?{() → void} #t128 as{TypeError,ForNonNullableByDefault} () → void : #t128{() → void};
-  toVoidVar = let final Never #t129 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:223:15: Error: Can't tear off method 'call' from a potentially null value.
+              ^" in let () →? void #t126 = toVoidNullableArg in #t126.==(null) ?{() → void} #t126 as{TypeError,ForNonNullableByDefault} () → void : #t126{() → void};
+  toVoidVar = let final Never #t127 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:223:15: Error: Can't tear off method 'call' from a potentially null value.
   toVoidVar = tearoffableNullableArg;
               ^" in tearoffableNullableArg as{TypeError} () → void;
-  toVoidVar = let final Never #t130 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:224:15: Error: A value of type 'XnonNull' can't be assigned to a variable of type 'void Function()'.
+  toVoidVar = let final Never #t128 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:224:15: Error: A value of type 'XnonNull' can't be assigned to a variable of type 'void Function()'.
   toVoidVar = xNonNullArg;
               ^" in xNonNullArg as{TypeError,ForNonNullableByDefault} () → void;
-  toVoidVar = let final Never #t131 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:225:15: Error: A value of type 'XnonNull?' can't be assigned to a variable of type 'void Function()'.
+  toVoidVar = let final Never #t129 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:225:15: Error: A value of type 'XnonNull?' can't be assigned to a variable of type 'void Function()'.
   toVoidVar = xNonNullNullableArg;
               ^" in xNonNullNullableArg as{TypeError,ForNonNullableByDefault} () → void;
-  toVoidVar = let final Never #t132 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:226:15: Error: A value of type 'XpotentiallyNull' can't be assigned to a variable of type 'void Function()'.
+  toVoidVar = let final Never #t130 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:226:15: Error: A value of type 'XpotentiallyNull' can't be assigned to a variable of type 'void Function()'.
   toVoidVar = xPotentiallyNullArg;
               ^" in xPotentiallyNullArg as{TypeError,ForNonNullableByDefault} () → void;
-  toVoidVar = let final Never #t133 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:227:15: Error: A value of type 'XpotentiallyNull?' can't be assigned to a variable of type 'void Function()'.
+  toVoidVar = let final Never #t131 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:227:15: Error: A value of type 'XpotentiallyNull?' can't be assigned to a variable of type 'void Function()'.
   toVoidVar = xPotentiallyNullNullableArg;
               ^" in xPotentiallyNullNullableArg as{TypeError,ForNonNullableByDefault} () → void;
-  toVoidVar = let final Never #t134 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:228:15: Error: A value of type 'YnonNull' can't be assigned to a variable of type 'void Function()'.
+  toVoidVar = let final Never #t132 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:228:15: Error: A value of type 'YnonNull' can't be assigned to a variable of type 'void Function()'.
   toVoidVar = yNonNullArg;
               ^" in yNonNullArg as{TypeError,ForNonNullableByDefault} () → void;
-  toVoidVar = let final Never #t135 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:229:15: Error: A value of type 'YnonNull?' can't be assigned to a variable of type 'void Function()'.
+  toVoidVar = let final Never #t133 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:229:15: Error: A value of type 'YnonNull?' can't be assigned to a variable of type 'void Function()'.
   toVoidVar = yNonNullNullableArg;
               ^" in yNonNullNullableArg as{TypeError,ForNonNullableByDefault} () → void;
-  toVoidVar = let final Never #t136 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:230:15: Error: A value of type 'YpotentiallyNull' can't be assigned to a variable of type 'void Function()'.
+  toVoidVar = let final Never #t134 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:230:15: Error: A value of type 'YpotentiallyNull' can't be assigned to a variable of type 'void Function()'.
   toVoidVar = yPotentiallyNullArg;
               ^" in yPotentiallyNullArg as{TypeError,ForNonNullableByDefault} () → void;
-  toVoidVar = let final Never #t137 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:231:15: Error: A value of type 'YpotentiallyNull?' can't be assigned to a variable of type 'void Function()'.
+  toVoidVar = let final Never #t135 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:231:15: Error: A value of type 'YpotentiallyNull?' can't be assigned to a variable of type 'void Function()'.
   toVoidVar = yPotentiallyNullNullableArg;
               ^" in yPotentiallyNullNullableArg as{TypeError,ForNonNullableByDefault} () → void;
-  self::Tearoffable tearoffableVar = let final Never #t138 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:233:32: Error: A value of type 'Object' can't be assigned to a variable of type 'Tearoffable'.
+  self::Tearoffable tearoffableVar = let final Never #t136 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:233:32: Error: A value of type 'Object' can't be assigned to a variable of type 'Tearoffable'.
  - 'Object' is from 'dart:core'.
  - 'Tearoffable' is from 'pkg/front_end/testcases/nnbd/assignability.dart'.
   Tearoffable tearoffableVar = objectArg;
                                ^" in objectArg as{TypeError,ForNonNullableByDefault} self::Tearoffable;
-  tearoffableVar = let final Never #t139 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:234:20: Error: A value of type 'Object?' can't be assigned to a variable of type 'Tearoffable'.
+  tearoffableVar = let final Never #t137 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:234:20: Error: A value of type 'Object?' can't be assigned to a variable of type 'Tearoffable'.
  - 'Object' is from 'dart:core'.
  - 'Tearoffable' is from 'pkg/front_end/testcases/nnbd/assignability.dart'.
   tearoffableVar = objectNullableArg;
                    ^" in objectNullableArg as{TypeError,ForNonNullableByDefault} self::Tearoffable;
-  tearoffableVar = let final Never #t140 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:235:20: Error: A value of type 'num' can't be assigned to a variable of type 'Tearoffable'.
+  tearoffableVar = let final Never #t138 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:235:20: Error: A value of type 'num' can't be assigned to a variable of type 'Tearoffable'.
  - 'Tearoffable' is from 'pkg/front_end/testcases/nnbd/assignability.dart'.
   tearoffableVar = numArg;
                    ^" in numArg as{TypeError,ForNonNullableByDefault} self::Tearoffable;
-  tearoffableVar = let final Never #t141 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:236:20: Error: A value of type 'num?' can't be assigned to a variable of type 'Tearoffable'.
+  tearoffableVar = let final Never #t139 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:236:20: Error: A value of type 'num?' can't be assigned to a variable of type 'Tearoffable'.
  - 'Tearoffable' is from 'pkg/front_end/testcases/nnbd/assignability.dart'.
   tearoffableVar = numNullableArg;
                    ^" in numNullableArg as{TypeError,ForNonNullableByDefault} self::Tearoffable;
-  tearoffableVar = let final Never #t142 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:237:20: Error: A value of type 'int' can't be assigned to a variable of type 'Tearoffable'.
+  tearoffableVar = let final Never #t140 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:237:20: Error: A value of type 'int' can't be assigned to a variable of type 'Tearoffable'.
  - 'Tearoffable' is from 'pkg/front_end/testcases/nnbd/assignability.dart'.
   tearoffableVar = intArg;
                    ^" in intArg as{TypeError,ForNonNullableByDefault} self::Tearoffable;
-  tearoffableVar = let final Never #t143 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:238:20: Error: A value of type 'int?' can't be assigned to a variable of type 'Tearoffable'.
+  tearoffableVar = let final Never #t141 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:238:20: Error: A value of type 'int?' can't be assigned to a variable of type 'Tearoffable'.
  - 'Tearoffable' is from 'pkg/front_end/testcases/nnbd/assignability.dart'.
   tearoffableVar = intNullableArg;
                    ^" in intNullableArg as{TypeError,ForNonNullableByDefault} self::Tearoffable;
-  tearoffableVar = let final Never #t144 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:239:20: Error: A value of type 'double' can't be assigned to a variable of type 'Tearoffable'.
+  tearoffableVar = let final Never #t142 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:239:20: Error: A value of type 'double' can't be assigned to a variable of type 'Tearoffable'.
  - 'Tearoffable' is from 'pkg/front_end/testcases/nnbd/assignability.dart'.
   tearoffableVar = doubleArg;
                    ^" in doubleArg as{TypeError,ForNonNullableByDefault} self::Tearoffable;
-  tearoffableVar = let final Never #t145 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:240:20: Error: A value of type 'double?' can't be assigned to a variable of type 'Tearoffable'.
+  tearoffableVar = let final Never #t143 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:240:20: Error: A value of type 'double?' can't be assigned to a variable of type 'Tearoffable'.
  - 'Tearoffable' is from 'pkg/front_end/testcases/nnbd/assignability.dart'.
   tearoffableVar = doubleNullableArg;
                    ^" in doubleNullableArg as{TypeError,ForNonNullableByDefault} self::Tearoffable;
-  tearoffableVar = let final Never #t146 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:241:20: Error: A value of type 'Function' can't be assigned to a variable of type 'Tearoffable'.
+  tearoffableVar = let final Never #t144 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:241:20: Error: A value of type 'Function' can't be assigned to a variable of type 'Tearoffable'.
  - 'Function' is from 'dart:core'.
  - 'Tearoffable' is from 'pkg/front_end/testcases/nnbd/assignability.dart'.
   tearoffableVar = functionArg;
                    ^" in functionArg as{TypeError,ForNonNullableByDefault} self::Tearoffable;
-  tearoffableVar = let final Never #t147 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:242:20: Error: A value of type 'Function?' can't be assigned to a variable of type 'Tearoffable'.
+  tearoffableVar = let final Never #t145 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:242:20: Error: A value of type 'Function?' can't be assigned to a variable of type 'Tearoffable'.
  - 'Function' is from 'dart:core'.
  - 'Tearoffable' is from 'pkg/front_end/testcases/nnbd/assignability.dart'.
   tearoffableVar = functionNullableArg;
                    ^" in functionNullableArg as{TypeError,ForNonNullableByDefault} self::Tearoffable;
-  tearoffableVar = let final Never #t148 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:243:20: Error: A value of type 'void Function()' can't be assigned to a variable of type 'Tearoffable'.
+  tearoffableVar = let final Never #t146 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:243:20: Error: A value of type 'void Function()' can't be assigned to a variable of type 'Tearoffable'.
  - 'Tearoffable' is from 'pkg/front_end/testcases/nnbd/assignability.dart'.
   tearoffableVar = toVoidArg;
                    ^" in toVoidArg as{TypeError,ForNonNullableByDefault} self::Tearoffable;
-  tearoffableVar = let final Never #t149 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:244:20: Error: A value of type 'void Function()?' can't be assigned to a variable of type 'Tearoffable'.
+  tearoffableVar = let final Never #t147 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:244:20: Error: A value of type 'void Function()?' can't be assigned to a variable of type 'Tearoffable'.
  - 'Tearoffable' is from 'pkg/front_end/testcases/nnbd/assignability.dart'.
   tearoffableVar = toVoidNullableArg;
                    ^" in toVoidNullableArg as{TypeError,ForNonNullableByDefault} self::Tearoffable;
-  tearoffableVar = let final Never #t150 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:245:20: Error: A value of type 'Tearoffable?' can't be assigned to a variable of type 'Tearoffable' because 'Tearoffable?' is nullable and 'Tearoffable' isn't.
+  tearoffableVar = let final Never #t148 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:245:20: Error: A value of type 'Tearoffable?' can't be assigned to a variable of type 'Tearoffable' because 'Tearoffable?' is nullable and 'Tearoffable' isn't.
  - 'Tearoffable' is from 'pkg/front_end/testcases/nnbd/assignability.dart'.
   tearoffableVar = tearoffableNullableArg;
-                   ^" in let self::Tearoffable? #t151 = tearoffableNullableArg in #t151.==(null) ?{self::Tearoffable} #t151 as{TypeError,ForNonNullableByDefault} self::Tearoffable : #t151{self::Tearoffable};
-  tearoffableVar = let final Never #t152 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:246:20: Error: A value of type 'XnonNull' can't be assigned to a variable of type 'Tearoffable'.
+                   ^" in let self::Tearoffable? #t149 = tearoffableNullableArg in #t149.==(null) ?{self::Tearoffable} #t149 as{TypeError,ForNonNullableByDefault} self::Tearoffable : #t149{self::Tearoffable};
+  tearoffableVar = let final Never #t150 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:246:20: Error: A value of type 'XnonNull' can't be assigned to a variable of type 'Tearoffable'.
  - 'Tearoffable' is from 'pkg/front_end/testcases/nnbd/assignability.dart'.
   tearoffableVar = xNonNullArg;
                    ^" in xNonNullArg as{TypeError,ForNonNullableByDefault} self::Tearoffable;
-  tearoffableVar = let final Never #t153 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:247:20: Error: A value of type 'XnonNull?' can't be assigned to a variable of type 'Tearoffable'.
+  tearoffableVar = let final Never #t151 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:247:20: Error: A value of type 'XnonNull?' can't be assigned to a variable of type 'Tearoffable'.
  - 'Tearoffable' is from 'pkg/front_end/testcases/nnbd/assignability.dart'.
   tearoffableVar = xNonNullNullableArg;
                    ^" in xNonNullNullableArg as{TypeError,ForNonNullableByDefault} self::Tearoffable;
-  tearoffableVar = let final Never #t154 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:248:20: Error: A value of type 'XpotentiallyNull' can't be assigned to a variable of type 'Tearoffable'.
+  tearoffableVar = let final Never #t152 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:248:20: Error: A value of type 'XpotentiallyNull' can't be assigned to a variable of type 'Tearoffable'.
  - 'Tearoffable' is from 'pkg/front_end/testcases/nnbd/assignability.dart'.
   tearoffableVar = xPotentiallyNullArg;
                    ^" in xPotentiallyNullArg as{TypeError,ForNonNullableByDefault} self::Tearoffable;
-  tearoffableVar = let final Never #t155 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:249:20: Error: A value of type 'XpotentiallyNull?' can't be assigned to a variable of type 'Tearoffable'.
+  tearoffableVar = let final Never #t153 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:249:20: Error: A value of type 'XpotentiallyNull?' can't be assigned to a variable of type 'Tearoffable'.
  - 'Tearoffable' is from 'pkg/front_end/testcases/nnbd/assignability.dart'.
   tearoffableVar = xPotentiallyNullNullableArg;
                    ^" in xPotentiallyNullNullableArg as{TypeError,ForNonNullableByDefault} self::Tearoffable;
-  tearoffableVar = let final Never #t156 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:250:20: Error: A value of type 'YnonNull' can't be assigned to a variable of type 'Tearoffable'.
+  tearoffableVar = let final Never #t154 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:250:20: Error: A value of type 'YnonNull' can't be assigned to a variable of type 'Tearoffable'.
  - 'Tearoffable' is from 'pkg/front_end/testcases/nnbd/assignability.dart'.
   tearoffableVar = yNonNullArg;
                    ^" in yNonNullArg as{TypeError,ForNonNullableByDefault} self::Tearoffable;
-  tearoffableVar = let final Never #t157 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:251:20: Error: A value of type 'YnonNull?' can't be assigned to a variable of type 'Tearoffable'.
+  tearoffableVar = let final Never #t155 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:251:20: Error: A value of type 'YnonNull?' can't be assigned to a variable of type 'Tearoffable'.
  - 'Tearoffable' is from 'pkg/front_end/testcases/nnbd/assignability.dart'.
   tearoffableVar = yNonNullNullableArg;
                    ^" in yNonNullNullableArg as{TypeError,ForNonNullableByDefault} self::Tearoffable;
-  tearoffableVar = let final Never #t158 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:252:20: Error: A value of type 'YpotentiallyNull' can't be assigned to a variable of type 'Tearoffable'.
+  tearoffableVar = let final Never #t156 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:252:20: Error: A value of type 'YpotentiallyNull' can't be assigned to a variable of type 'Tearoffable'.
  - 'Tearoffable' is from 'pkg/front_end/testcases/nnbd/assignability.dart'.
   tearoffableVar = yPotentiallyNullArg;
                    ^" in yPotentiallyNullArg as{TypeError,ForNonNullableByDefault} self::Tearoffable;
-  tearoffableVar = let final Never #t159 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:253:20: Error: A value of type 'YpotentiallyNull?' can't be assigned to a variable of type 'Tearoffable'.
+  tearoffableVar = let final Never #t157 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:253:20: Error: A value of type 'YpotentiallyNull?' can't be assigned to a variable of type 'Tearoffable'.
  - 'Tearoffable' is from 'pkg/front_end/testcases/nnbd/assignability.dart'.
   tearoffableVar = yPotentiallyNullNullableArg;
                    ^" in yPotentiallyNullNullableArg as{TypeError,ForNonNullableByDefault} self::Tearoffable;
-  self::error::XnonNull xNonNullVar = let final Never #t160 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:255:26: Error: A value of type 'Object' can't be assigned to a variable of type 'XnonNull'.
+  self::error::XnonNull xNonNullVar = let final Never #t158 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:255:26: Error: A value of type 'Object' can't be assigned to a variable of type 'XnonNull'.
  - 'Object' is from 'dart:core'.
   XnonNull xNonNullVar = objectArg;
                          ^" in objectArg as{TypeError,ForNonNullableByDefault} Never;
-  xNonNullVar = let final Never #t161 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:256:17: Error: A value of type 'Object?' can't be assigned to a variable of type 'XnonNull'.
+  xNonNullVar = let final Never #t159 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:256:17: Error: A value of type 'Object?' can't be assigned to a variable of type 'XnonNull'.
  - 'Object' is from 'dart:core'.
   xNonNullVar = objectNullableArg;
                 ^" in objectNullableArg as{TypeError,ForNonNullableByDefault} Never;
-  xNonNullVar = let final Never #t162 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:257:17: Error: A value of type 'num' can't be assigned to a variable of type 'XnonNull'.
+  xNonNullVar = let final Never #t160 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:257:17: Error: A value of type 'num' can't be assigned to a variable of type 'XnonNull'.
   xNonNullVar = numArg;
                 ^" in numArg as{TypeError,ForNonNullableByDefault} Never;
-  xNonNullVar = let final Never #t163 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:258:17: Error: A value of type 'num?' can't be assigned to a variable of type 'XnonNull'.
+  xNonNullVar = let final Never #t161 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:258:17: Error: A value of type 'num?' can't be assigned to a variable of type 'XnonNull'.
   xNonNullVar = numNullableArg;
                 ^" in numNullableArg as{TypeError,ForNonNullableByDefault} Never;
-  xNonNullVar = let final Never #t164 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:259:17: Error: A value of type 'int' can't be assigned to a variable of type 'XnonNull'.
+  xNonNullVar = let final Never #t162 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:259:17: Error: A value of type 'int' can't be assigned to a variable of type 'XnonNull'.
   xNonNullVar = intArg;
                 ^" in intArg as{TypeError,ForNonNullableByDefault} Never;
-  xNonNullVar = let final Never #t165 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:260:17: Error: A value of type 'int?' can't be assigned to a variable of type 'XnonNull'.
+  xNonNullVar = let final Never #t163 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:260:17: Error: A value of type 'int?' can't be assigned to a variable of type 'XnonNull'.
   xNonNullVar = intNullableArg;
                 ^" in intNullableArg as{TypeError,ForNonNullableByDefault} Never;
-  xNonNullVar = let final Never #t166 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:261:17: Error: A value of type 'double' can't be assigned to a variable of type 'XnonNull'.
+  xNonNullVar = let final Never #t164 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:261:17: Error: A value of type 'double' can't be assigned to a variable of type 'XnonNull'.
   xNonNullVar = doubleArg;
                 ^" in doubleArg as{TypeError,ForNonNullableByDefault} Never;
-  xNonNullVar = let final Never #t167 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:262:17: Error: A value of type 'double?' can't be assigned to a variable of type 'XnonNull'.
+  xNonNullVar = let final Never #t165 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:262:17: Error: A value of type 'double?' can't be assigned to a variable of type 'XnonNull'.
   xNonNullVar = doubleNullableArg;
                 ^" in doubleNullableArg as{TypeError,ForNonNullableByDefault} Never;
-  xNonNullVar = let final Never #t168 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:263:17: Error: A value of type 'Function' can't be assigned to a variable of type 'XnonNull'.
+  xNonNullVar = let final Never #t166 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:263:17: Error: A value of type 'Function' can't be assigned to a variable of type 'XnonNull'.
  - 'Function' is from 'dart:core'.
   xNonNullVar = functionArg;
                 ^" in functionArg as{TypeError,ForNonNullableByDefault} Never;
-  xNonNullVar = let final Never #t169 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:264:17: Error: A value of type 'Function?' can't be assigned to a variable of type 'XnonNull'.
+  xNonNullVar = let final Never #t167 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:264:17: Error: A value of type 'Function?' can't be assigned to a variable of type 'XnonNull'.
  - 'Function' is from 'dart:core'.
   xNonNullVar = functionNullableArg;
                 ^" in functionNullableArg as{TypeError,ForNonNullableByDefault} Never;
-  xNonNullVar = let final Never #t170 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:265:17: Error: A value of type 'void Function()' can't be assigned to a variable of type 'XnonNull'.
+  xNonNullVar = let final Never #t168 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:265:17: Error: A value of type 'void Function()' can't be assigned to a variable of type 'XnonNull'.
   xNonNullVar = toVoidArg;
                 ^" in toVoidArg as{TypeError,ForNonNullableByDefault} Never;
-  xNonNullVar = let final Never #t171 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:266:17: Error: A value of type 'void Function()?' can't be assigned to a variable of type 'XnonNull'.
+  xNonNullVar = let final Never #t169 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:266:17: Error: A value of type 'void Function()?' can't be assigned to a variable of type 'XnonNull'.
   xNonNullVar = toVoidNullableArg;
                 ^" in toVoidNullableArg as{TypeError,ForNonNullableByDefault} Never;
-  xNonNullVar = let final Never #t172 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:267:17: Error: A value of type 'Tearoffable' can't be assigned to a variable of type 'XnonNull'.
+  xNonNullVar = let final Never #t170 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:267:17: Error: A value of type 'Tearoffable' can't be assigned to a variable of type 'XnonNull'.
  - 'Tearoffable' is from 'pkg/front_end/testcases/nnbd/assignability.dart'.
   xNonNullVar = tearoffableArg;
                 ^" in tearoffableArg as{TypeError,ForNonNullableByDefault} Never;
-  xNonNullVar = let final Never #t173 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:268:17: Error: A value of type 'Tearoffable?' can't be assigned to a variable of type 'XnonNull'.
+  xNonNullVar = let final Never #t171 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:268:17: Error: A value of type 'Tearoffable?' can't be assigned to a variable of type 'XnonNull'.
  - 'Tearoffable' is from 'pkg/front_end/testcases/nnbd/assignability.dart'.
   xNonNullVar = tearoffableNullableArg;
                 ^" in tearoffableNullableArg as{TypeError,ForNonNullableByDefault} Never;
-  xNonNullVar = let final Never #t174 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:269:17: Error: A value of type 'XnonNull?' can't be assigned to a variable of type 'XnonNull' because 'XnonNull?' is nullable and 'XnonNull' isn't.
+  xNonNullVar = let final Never #t172 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:269:17: Error: A value of type 'XnonNull?' can't be assigned to a variable of type 'XnonNull' because 'XnonNull?' is nullable and 'XnonNull' isn't.
   xNonNullVar = xNonNullNullableArg;
                 ^" in xNonNullNullableArg as{TypeError,ForNonNullableByDefault} Never;
-  xNonNullVar = let final Never #t175 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:270:17: Error: A value of type 'XpotentiallyNull' can't be assigned to a variable of type 'XnonNull'.
+  xNonNullVar = let final Never #t173 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:270:17: Error: A value of type 'XpotentiallyNull' can't be assigned to a variable of type 'XnonNull'.
   xNonNullVar = xPotentiallyNullArg;
                 ^" in xPotentiallyNullArg as{TypeError,ForNonNullableByDefault} Never;
-  xNonNullVar = let final Never #t176 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:271:17: Error: A value of type 'XpotentiallyNull?' can't be assigned to a variable of type 'XnonNull'.
+  xNonNullVar = let final Never #t174 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:271:17: Error: A value of type 'XpotentiallyNull?' can't be assigned to a variable of type 'XnonNull'.
   xNonNullVar = xPotentiallyNullNullableArg;
                 ^" in xPotentiallyNullNullableArg as{TypeError,ForNonNullableByDefault} Never;
-  xNonNullVar = let final Never #t177 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:272:17: Error: A value of type 'YnonNull?' can't be assigned to a variable of type 'XnonNull' because 'YnonNull?' is nullable and 'XnonNull' isn't.
+  xNonNullVar = let final Never #t175 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:272:17: Error: A value of type 'YnonNull?' can't be assigned to a variable of type 'XnonNull' because 'YnonNull?' is nullable and 'XnonNull' isn't.
   xNonNullVar = yNonNullNullableArg;
                 ^" in yNonNullNullableArg as{TypeError,ForNonNullableByDefault} Never;
-  xNonNullVar = let final Never #t178 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:273:17: Error: A value of type 'YpotentiallyNull' can't be assigned to a variable of type 'XnonNull'.
+  xNonNullVar = let final Never #t176 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:273:17: Error: A value of type 'YpotentiallyNull' can't be assigned to a variable of type 'XnonNull'.
   xNonNullVar = yPotentiallyNullArg;
                 ^" in yPotentiallyNullArg as{TypeError,ForNonNullableByDefault} Never;
-  xNonNullVar = let final Never #t179 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:274:17: Error: A value of type 'YpotentiallyNull?' can't be assigned to a variable of type 'XnonNull'.
+  xNonNullVar = let final Never #t177 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:274:17: Error: A value of type 'YpotentiallyNull?' can't be assigned to a variable of type 'XnonNull'.
   xNonNullVar = yPotentiallyNullNullableArg;
                 ^" in yPotentiallyNullNullableArg as{TypeError,ForNonNullableByDefault} Never;
-  self::error::XpotentiallyNull% xPotentiallyNullVar = let final Never #t180 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:276:42: Error: A value of type 'Object' can't be assigned to a variable of type 'XpotentiallyNull'.
+  self::error::XpotentiallyNull% xPotentiallyNullVar = let final Never #t178 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:276:42: Error: A value of type 'Object' can't be assigned to a variable of type 'XpotentiallyNull'.
  - 'Object' is from 'dart:core'.
   XpotentiallyNull xPotentiallyNullVar = objectArg;
                                          ^" in objectArg as{TypeError,ForNonNullableByDefault} Never;
-  xPotentiallyNullVar = let final Never #t181 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:277:25: Error: A value of type 'Object?' can't be assigned to a variable of type 'XpotentiallyNull'.
+  xPotentiallyNullVar = let final Never #t179 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:277:25: Error: A value of type 'Object?' can't be assigned to a variable of type 'XpotentiallyNull'.
  - 'Object' is from 'dart:core'.
   xPotentiallyNullVar = objectNullableArg;
                         ^" in objectNullableArg as{TypeError,ForNonNullableByDefault} Never;
-  xPotentiallyNullVar = let final Never #t182 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:278:25: Error: A value of type 'num' can't be assigned to a variable of type 'XpotentiallyNull'.
+  xPotentiallyNullVar = let final Never #t180 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:278:25: Error: A value of type 'num' can't be assigned to a variable of type 'XpotentiallyNull'.
   xPotentiallyNullVar = numArg;
                         ^" in numArg as{TypeError,ForNonNullableByDefault} Never;
-  xPotentiallyNullVar = let final Never #t183 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:279:25: Error: A value of type 'num?' can't be assigned to a variable of type 'XpotentiallyNull'.
+  xPotentiallyNullVar = let final Never #t181 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:279:25: Error: A value of type 'num?' can't be assigned to a variable of type 'XpotentiallyNull'.
   xPotentiallyNullVar = numNullableArg;
                         ^" in numNullableArg as{TypeError,ForNonNullableByDefault} Never;
-  xPotentiallyNullVar = let final Never #t184 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:280:25: Error: A value of type 'int' can't be assigned to a variable of type 'XpotentiallyNull'.
+  xPotentiallyNullVar = let final Never #t182 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:280:25: Error: A value of type 'int' can't be assigned to a variable of type 'XpotentiallyNull'.
   xPotentiallyNullVar = intArg;
                         ^" in intArg as{TypeError,ForNonNullableByDefault} Never;
-  xPotentiallyNullVar = let final Never #t185 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:281:25: Error: A value of type 'int?' can't be assigned to a variable of type 'XpotentiallyNull'.
+  xPotentiallyNullVar = let final Never #t183 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:281:25: Error: A value of type 'int?' can't be assigned to a variable of type 'XpotentiallyNull'.
   xPotentiallyNullVar = intNullableArg;
                         ^" in intNullableArg as{TypeError,ForNonNullableByDefault} Never;
-  xPotentiallyNullVar = let final Never #t186 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:282:25: Error: A value of type 'double' can't be assigned to a variable of type 'XpotentiallyNull'.
+  xPotentiallyNullVar = let final Never #t184 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:282:25: Error: A value of type 'double' can't be assigned to a variable of type 'XpotentiallyNull'.
   xPotentiallyNullVar = doubleArg;
                         ^" in doubleArg as{TypeError,ForNonNullableByDefault} Never;
-  xPotentiallyNullVar = let final Never #t187 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:283:25: Error: A value of type 'double?' can't be assigned to a variable of type 'XpotentiallyNull'.
+  xPotentiallyNullVar = let final Never #t185 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:283:25: Error: A value of type 'double?' can't be assigned to a variable of type 'XpotentiallyNull'.
   xPotentiallyNullVar = doubleNullableArg;
                         ^" in doubleNullableArg as{TypeError,ForNonNullableByDefault} Never;
-  xPotentiallyNullVar = let final Never #t188 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:284:25: Error: A value of type 'Function' can't be assigned to a variable of type 'XpotentiallyNull'.
+  xPotentiallyNullVar = let final Never #t186 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:284:25: Error: A value of type 'Function' can't be assigned to a variable of type 'XpotentiallyNull'.
  - 'Function' is from 'dart:core'.
   xPotentiallyNullVar = functionArg;
                         ^" in functionArg as{TypeError,ForNonNullableByDefault} Never;
-  xPotentiallyNullVar = let final Never #t189 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:285:25: Error: A value of type 'Function?' can't be assigned to a variable of type 'XpotentiallyNull'.
+  xPotentiallyNullVar = let final Never #t187 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:285:25: Error: A value of type 'Function?' can't be assigned to a variable of type 'XpotentiallyNull'.
  - 'Function' is from 'dart:core'.
   xPotentiallyNullVar = functionNullableArg;
                         ^" in functionNullableArg as{TypeError,ForNonNullableByDefault} Never;
-  xPotentiallyNullVar = let final Never #t190 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:286:25: Error: A value of type 'void Function()' can't be assigned to a variable of type 'XpotentiallyNull'.
+  xPotentiallyNullVar = let final Never #t188 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:286:25: Error: A value of type 'void Function()' can't be assigned to a variable of type 'XpotentiallyNull'.
   xPotentiallyNullVar = toVoidArg;
                         ^" in toVoidArg as{TypeError,ForNonNullableByDefault} Never;
-  xPotentiallyNullVar = let final Never #t191 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:287:25: Error: A value of type 'void Function()?' can't be assigned to a variable of type 'XpotentiallyNull'.
+  xPotentiallyNullVar = let final Never #t189 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:287:25: Error: A value of type 'void Function()?' can't be assigned to a variable of type 'XpotentiallyNull'.
   xPotentiallyNullVar = toVoidNullableArg;
                         ^" in toVoidNullableArg as{TypeError,ForNonNullableByDefault} Never;
-  xPotentiallyNullVar = let final Never #t192 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:288:25: Error: A value of type 'Tearoffable' can't be assigned to a variable of type 'XpotentiallyNull'.
+  xPotentiallyNullVar = let final Never #t190 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:288:25: Error: A value of type 'Tearoffable' can't be assigned to a variable of type 'XpotentiallyNull'.
  - 'Tearoffable' is from 'pkg/front_end/testcases/nnbd/assignability.dart'.
   xPotentiallyNullVar = tearoffableArg;
                         ^" in tearoffableArg as{TypeError,ForNonNullableByDefault} Never;
-  xPotentiallyNullVar = let final Never #t193 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:289:25: Error: A value of type 'Tearoffable?' can't be assigned to a variable of type 'XpotentiallyNull'.
+  xPotentiallyNullVar = let final Never #t191 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:289:25: Error: A value of type 'Tearoffable?' can't be assigned to a variable of type 'XpotentiallyNull'.
  - 'Tearoffable' is from 'pkg/front_end/testcases/nnbd/assignability.dart'.
   xPotentiallyNullVar = tearoffableNullableArg;
                         ^" in tearoffableNullableArg as{TypeError,ForNonNullableByDefault} Never;
-  xPotentiallyNullVar = let final Never #t194 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:290:25: Error: A value of type 'XnonNull' can't be assigned to a variable of type 'XpotentiallyNull'.
+  xPotentiallyNullVar = let final Never #t192 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:290:25: Error: A value of type 'XnonNull' can't be assigned to a variable of type 'XpotentiallyNull'.
   xPotentiallyNullVar = xNonNullArg;
                         ^" in xNonNullArg as{TypeError,ForNonNullableByDefault} Never;
-  xPotentiallyNullVar = let final Never #t195 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:291:25: Error: A value of type 'XnonNull?' can't be assigned to a variable of type 'XpotentiallyNull'.
+  xPotentiallyNullVar = let final Never #t193 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:291:25: Error: A value of type 'XnonNull?' can't be assigned to a variable of type 'XpotentiallyNull'.
   xPotentiallyNullVar = xNonNullNullableArg;
                         ^" in xNonNullNullableArg as{TypeError,ForNonNullableByDefault} Never;
-  xPotentiallyNullVar = let final Never #t196 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:292:25: Error: A value of type 'XpotentiallyNull?' can't be assigned to a variable of type 'XpotentiallyNull' because 'XpotentiallyNull?' is nullable and 'XpotentiallyNull' isn't.
+  xPotentiallyNullVar = let final Never #t194 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:292:25: Error: A value of type 'XpotentiallyNull?' can't be assigned to a variable of type 'XpotentiallyNull' because 'XpotentiallyNull?' is nullable and 'XpotentiallyNull' isn't.
   xPotentiallyNullVar = xPotentiallyNullNullableArg;
                         ^" in xPotentiallyNullNullableArg as{TypeError,ForNonNullableByDefault} Never;
-  xPotentiallyNullVar = let final Never #t197 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:293:25: Error: A value of type 'YnonNull' can't be assigned to a variable of type 'XpotentiallyNull'.
+  xPotentiallyNullVar = let final Never #t195 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:293:25: Error: A value of type 'YnonNull' can't be assigned to a variable of type 'XpotentiallyNull'.
   xPotentiallyNullVar = yNonNullArg;
                         ^" in yNonNullArg as{TypeError,ForNonNullableByDefault} Never;
-  xPotentiallyNullVar = let final Never #t198 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:294:25: Error: A value of type 'YnonNull?' can't be assigned to a variable of type 'XpotentiallyNull'.
+  xPotentiallyNullVar = let final Never #t196 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:294:25: Error: A value of type 'YnonNull?' can't be assigned to a variable of type 'XpotentiallyNull'.
   xPotentiallyNullVar = yNonNullNullableArg;
                         ^" in yNonNullNullableArg as{TypeError,ForNonNullableByDefault} Never;
-  xPotentiallyNullVar = let final Never #t199 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:295:25: Error: A value of type 'YpotentiallyNull?' can't be assigned to a variable of type 'XpotentiallyNull' because 'YpotentiallyNull?' is nullable and 'XpotentiallyNull' isn't.
+  xPotentiallyNullVar = let final Never #t197 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:295:25: Error: A value of type 'YpotentiallyNull?' can't be assigned to a variable of type 'XpotentiallyNull' because 'YpotentiallyNull?' is nullable and 'XpotentiallyNull' isn't.
   xPotentiallyNullVar = yPotentiallyNullNullableArg;
                         ^" in yPotentiallyNullNullableArg as{TypeError,ForNonNullableByDefault} Never;
-  self::error::YnonNull yNonNullVar = let final Never #t200 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:297:26: Error: A value of type 'Object' can't be assigned to a variable of type 'YnonNull'.
+  self::error::YnonNull yNonNullVar = let final Never #t198 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:297:26: Error: A value of type 'Object' can't be assigned to a variable of type 'YnonNull'.
  - 'Object' is from 'dart:core'.
   YnonNull yNonNullVar = objectArg;
                          ^" in objectArg as{TypeError,ForNonNullableByDefault} Never;
-  yNonNullVar = let final Never #t201 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:298:17: Error: A value of type 'Object?' can't be assigned to a variable of type 'YnonNull'.
+  yNonNullVar = let final Never #t199 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:298:17: Error: A value of type 'Object?' can't be assigned to a variable of type 'YnonNull'.
  - 'Object' is from 'dart:core'.
   yNonNullVar = objectNullableArg;
                 ^" in objectNullableArg as{TypeError,ForNonNullableByDefault} Never;
-  yNonNullVar = let final Never #t202 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:299:17: Error: A value of type 'num' can't be assigned to a variable of type 'YnonNull'.
+  yNonNullVar = let final Never #t200 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:299:17: Error: A value of type 'num' can't be assigned to a variable of type 'YnonNull'.
   yNonNullVar = numArg;
                 ^" in numArg as{TypeError,ForNonNullableByDefault} Never;
-  yNonNullVar = let final Never #t203 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:300:17: Error: A value of type 'num?' can't be assigned to a variable of type 'YnonNull'.
+  yNonNullVar = let final Never #t201 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:300:17: Error: A value of type 'num?' can't be assigned to a variable of type 'YnonNull'.
   yNonNullVar = numNullableArg;
                 ^" in numNullableArg as{TypeError,ForNonNullableByDefault} Never;
-  yNonNullVar = let final Never #t204 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:301:17: Error: A value of type 'int' can't be assigned to a variable of type 'YnonNull'.
+  yNonNullVar = let final Never #t202 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:301:17: Error: A value of type 'int' can't be assigned to a variable of type 'YnonNull'.
   yNonNullVar = intArg;
                 ^" in intArg as{TypeError,ForNonNullableByDefault} Never;
-  yNonNullVar = let final Never #t205 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:302:17: Error: A value of type 'int?' can't be assigned to a variable of type 'YnonNull'.
+  yNonNullVar = let final Never #t203 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:302:17: Error: A value of type 'int?' can't be assigned to a variable of type 'YnonNull'.
   yNonNullVar = intNullableArg;
                 ^" in intNullableArg as{TypeError,ForNonNullableByDefault} Never;
-  yNonNullVar = let final Never #t206 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:303:17: Error: A value of type 'double' can't be assigned to a variable of type 'YnonNull'.
+  yNonNullVar = let final Never #t204 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:303:17: Error: A value of type 'double' can't be assigned to a variable of type 'YnonNull'.
   yNonNullVar = doubleArg;
                 ^" in doubleArg as{TypeError,ForNonNullableByDefault} Never;
-  yNonNullVar = let final Never #t207 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:304:17: Error: A value of type 'double?' can't be assigned to a variable of type 'YnonNull'.
+  yNonNullVar = let final Never #t205 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:304:17: Error: A value of type 'double?' can't be assigned to a variable of type 'YnonNull'.
   yNonNullVar = doubleNullableArg;
                 ^" in doubleNullableArg as{TypeError,ForNonNullableByDefault} Never;
-  yNonNullVar = let final Never #t208 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:305:17: Error: A value of type 'Function' can't be assigned to a variable of type 'YnonNull'.
+  yNonNullVar = let final Never #t206 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:305:17: Error: A value of type 'Function' can't be assigned to a variable of type 'YnonNull'.
  - 'Function' is from 'dart:core'.
   yNonNullVar = functionArg;
                 ^" in functionArg as{TypeError,ForNonNullableByDefault} Never;
-  yNonNullVar = let final Never #t209 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:306:17: Error: A value of type 'Function?' can't be assigned to a variable of type 'YnonNull'.
+  yNonNullVar = let final Never #t207 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:306:17: Error: A value of type 'Function?' can't be assigned to a variable of type 'YnonNull'.
  - 'Function' is from 'dart:core'.
   yNonNullVar = functionNullableArg;
                 ^" in functionNullableArg as{TypeError,ForNonNullableByDefault} Never;
-  yNonNullVar = let final Never #t210 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:307:17: Error: A value of type 'void Function()' can't be assigned to a variable of type 'YnonNull'.
+  yNonNullVar = let final Never #t208 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:307:17: Error: A value of type 'void Function()' can't be assigned to a variable of type 'YnonNull'.
   yNonNullVar = toVoidArg;
                 ^" in toVoidArg as{TypeError,ForNonNullableByDefault} Never;
-  yNonNullVar = let final Never #t211 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:308:17: Error: A value of type 'void Function()?' can't be assigned to a variable of type 'YnonNull'.
+  yNonNullVar = let final Never #t209 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:308:17: Error: A value of type 'void Function()?' can't be assigned to a variable of type 'YnonNull'.
   yNonNullVar = toVoidNullableArg;
                 ^" in toVoidNullableArg as{TypeError,ForNonNullableByDefault} Never;
-  yNonNullVar = let final Never #t212 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:309:17: Error: A value of type 'Tearoffable' can't be assigned to a variable of type 'YnonNull'.
+  yNonNullVar = let final Never #t210 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:309:17: Error: A value of type 'Tearoffable' can't be assigned to a variable of type 'YnonNull'.
  - 'Tearoffable' is from 'pkg/front_end/testcases/nnbd/assignability.dart'.
   yNonNullVar = tearoffableArg;
                 ^" in tearoffableArg as{TypeError,ForNonNullableByDefault} Never;
-  yNonNullVar = let final Never #t213 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:310:17: Error: A value of type 'Tearoffable?' can't be assigned to a variable of type 'YnonNull'.
+  yNonNullVar = let final Never #t211 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:310:17: Error: A value of type 'Tearoffable?' can't be assigned to a variable of type 'YnonNull'.
  - 'Tearoffable' is from 'pkg/front_end/testcases/nnbd/assignability.dart'.
   yNonNullVar = tearoffableNullableArg;
                 ^" in tearoffableNullableArg as{TypeError,ForNonNullableByDefault} Never;
-  yNonNullVar = let final Never #t214 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:311:17: Error: A value of type 'XnonNull' can't be assigned to a variable of type 'YnonNull'.
+  yNonNullVar = let final Never #t212 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:311:17: Error: A value of type 'XnonNull' can't be assigned to a variable of type 'YnonNull'.
   yNonNullVar = xNonNullArg;
                 ^" in xNonNullArg as{TypeError,ForNonNullableByDefault} Never;
-  yNonNullVar = let final Never #t215 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:312:17: Error: A value of type 'XnonNull?' can't be assigned to a variable of type 'YnonNull'.
+  yNonNullVar = let final Never #t213 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:312:17: Error: A value of type 'XnonNull?' can't be assigned to a variable of type 'YnonNull'.
   yNonNullVar = xNonNullNullableArg;
                 ^" in xNonNullNullableArg as{TypeError,ForNonNullableByDefault} Never;
-  yNonNullVar = let final Never #t216 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:313:17: Error: A value of type 'XpotentiallyNull' can't be assigned to a variable of type 'YnonNull'.
+  yNonNullVar = let final Never #t214 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:313:17: Error: A value of type 'XpotentiallyNull' can't be assigned to a variable of type 'YnonNull'.
   yNonNullVar = xPotentiallyNullArg;
                 ^" in xPotentiallyNullArg as{TypeError,ForNonNullableByDefault} Never;
-  yNonNullVar = let final Never #t217 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:314:17: Error: A value of type 'XpotentiallyNull?' can't be assigned to a variable of type 'YnonNull'.
+  yNonNullVar = let final Never #t215 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:314:17: Error: A value of type 'XpotentiallyNull?' can't be assigned to a variable of type 'YnonNull'.
   yNonNullVar = xPotentiallyNullNullableArg;
                 ^" in xPotentiallyNullNullableArg as{TypeError,ForNonNullableByDefault} Never;
-  yNonNullVar = let final Never #t218 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:315:17: Error: A value of type 'YnonNull?' can't be assigned to a variable of type 'YnonNull' because 'YnonNull?' is nullable and 'YnonNull' isn't.
+  yNonNullVar = let final Never #t216 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:315:17: Error: A value of type 'YnonNull?' can't be assigned to a variable of type 'YnonNull' because 'YnonNull?' is nullable and 'YnonNull' isn't.
   yNonNullVar = yNonNullNullableArg;
                 ^" in yNonNullNullableArg as{TypeError,ForNonNullableByDefault} Never;
-  yNonNullVar = let final Never #t219 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:316:17: Error: A value of type 'YpotentiallyNull' can't be assigned to a variable of type 'YnonNull'.
+  yNonNullVar = let final Never #t217 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:316:17: Error: A value of type 'YpotentiallyNull' can't be assigned to a variable of type 'YnonNull'.
   yNonNullVar = yPotentiallyNullArg;
                 ^" in yPotentiallyNullArg as{TypeError,ForNonNullableByDefault} Never;
-  yNonNullVar = let final Never #t220 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:317:17: Error: A value of type 'YpotentiallyNull?' can't be assigned to a variable of type 'YnonNull'.
+  yNonNullVar = let final Never #t218 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:317:17: Error: A value of type 'YpotentiallyNull?' can't be assigned to a variable of type 'YnonNull'.
   yNonNullVar = yPotentiallyNullNullableArg;
                 ^" in yPotentiallyNullNullableArg as{TypeError,ForNonNullableByDefault} Never;
-  self::error::YpotentiallyNull% yPotentiallyNullVar = let final Never #t221 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:319:42: Error: A value of type 'Object' can't be assigned to a variable of type 'YpotentiallyNull'.
+  self::error::YpotentiallyNull% yPotentiallyNullVar = let final Never #t219 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:319:42: Error: A value of type 'Object' can't be assigned to a variable of type 'YpotentiallyNull'.
  - 'Object' is from 'dart:core'.
   YpotentiallyNull yPotentiallyNullVar = objectArg;
                                          ^" in objectArg as{TypeError,ForNonNullableByDefault} Never;
-  yPotentiallyNullVar = let final Never #t222 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:320:25: Error: A value of type 'Object?' can't be assigned to a variable of type 'YpotentiallyNull'.
+  yPotentiallyNullVar = let final Never #t220 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:320:25: Error: A value of type 'Object?' can't be assigned to a variable of type 'YpotentiallyNull'.
  - 'Object' is from 'dart:core'.
   yPotentiallyNullVar = objectNullableArg;
                         ^" in objectNullableArg as{TypeError,ForNonNullableByDefault} Never;
-  yPotentiallyNullVar = let final Never #t223 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:321:25: Error: A value of type 'num' can't be assigned to a variable of type 'YpotentiallyNull'.
+  yPotentiallyNullVar = let final Never #t221 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:321:25: Error: A value of type 'num' can't be assigned to a variable of type 'YpotentiallyNull'.
   yPotentiallyNullVar = numArg;
                         ^" in numArg as{TypeError,ForNonNullableByDefault} Never;
-  yPotentiallyNullVar = let final Never #t224 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:322:25: Error: A value of type 'num?' can't be assigned to a variable of type 'YpotentiallyNull'.
+  yPotentiallyNullVar = let final Never #t222 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:322:25: Error: A value of type 'num?' can't be assigned to a variable of type 'YpotentiallyNull'.
   yPotentiallyNullVar = numNullableArg;
                         ^" in numNullableArg as{TypeError,ForNonNullableByDefault} Never;
-  yPotentiallyNullVar = let final Never #t225 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:323:25: Error: A value of type 'int' can't be assigned to a variable of type 'YpotentiallyNull'.
+  yPotentiallyNullVar = let final Never #t223 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:323:25: Error: A value of type 'int' can't be assigned to a variable of type 'YpotentiallyNull'.
   yPotentiallyNullVar = intArg;
                         ^" in intArg as{TypeError,ForNonNullableByDefault} Never;
-  yPotentiallyNullVar = let final Never #t226 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:324:25: Error: A value of type 'int?' can't be assigned to a variable of type 'YpotentiallyNull'.
+  yPotentiallyNullVar = let final Never #t224 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:324:25: Error: A value of type 'int?' can't be assigned to a variable of type 'YpotentiallyNull'.
   yPotentiallyNullVar = intNullableArg;
                         ^" in intNullableArg as{TypeError,ForNonNullableByDefault} Never;
-  yPotentiallyNullVar = let final Never #t227 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:325:25: Error: A value of type 'double' can't be assigned to a variable of type 'YpotentiallyNull'.
+  yPotentiallyNullVar = let final Never #t225 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:325:25: Error: A value of type 'double' can't be assigned to a variable of type 'YpotentiallyNull'.
   yPotentiallyNullVar = doubleArg;
                         ^" in doubleArg as{TypeError,ForNonNullableByDefault} Never;
-  yPotentiallyNullVar = let final Never #t228 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:326:25: Error: A value of type 'double?' can't be assigned to a variable of type 'YpotentiallyNull'.
+  yPotentiallyNullVar = let final Never #t226 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:326:25: Error: A value of type 'double?' can't be assigned to a variable of type 'YpotentiallyNull'.
   yPotentiallyNullVar = doubleNullableArg;
                         ^" in doubleNullableArg as{TypeError,ForNonNullableByDefault} Never;
-  yPotentiallyNullVar = let final Never #t229 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:327:25: Error: A value of type 'Function' can't be assigned to a variable of type 'YpotentiallyNull'.
+  yPotentiallyNullVar = let final Never #t227 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:327:25: Error: A value of type 'Function' can't be assigned to a variable of type 'YpotentiallyNull'.
  - 'Function' is from 'dart:core'.
   yPotentiallyNullVar = functionArg;
                         ^" in functionArg as{TypeError,ForNonNullableByDefault} Never;
-  yPotentiallyNullVar = let final Never #t230 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:328:25: Error: A value of type 'Function?' can't be assigned to a variable of type 'YpotentiallyNull'.
+  yPotentiallyNullVar = let final Never #t228 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:328:25: Error: A value of type 'Function?' can't be assigned to a variable of type 'YpotentiallyNull'.
  - 'Function' is from 'dart:core'.
   yPotentiallyNullVar = functionNullableArg;
                         ^" in functionNullableArg as{TypeError,ForNonNullableByDefault} Never;
-  yPotentiallyNullVar = let final Never #t231 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:329:25: Error: A value of type 'void Function()' can't be assigned to a variable of type 'YpotentiallyNull'.
+  yPotentiallyNullVar = let final Never #t229 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:329:25: Error: A value of type 'void Function()' can't be assigned to a variable of type 'YpotentiallyNull'.
   yPotentiallyNullVar = toVoidArg;
                         ^" in toVoidArg as{TypeError,ForNonNullableByDefault} Never;
-  yPotentiallyNullVar = let final Never #t232 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:330:25: Error: A value of type 'void Function()?' can't be assigned to a variable of type 'YpotentiallyNull'.
+  yPotentiallyNullVar = let final Never #t230 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:330:25: Error: A value of type 'void Function()?' can't be assigned to a variable of type 'YpotentiallyNull'.
   yPotentiallyNullVar = toVoidNullableArg;
                         ^" in toVoidNullableArg as{TypeError,ForNonNullableByDefault} Never;
-  yPotentiallyNullVar = let final Never #t233 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:331:25: Error: A value of type 'Tearoffable' can't be assigned to a variable of type 'YpotentiallyNull'.
+  yPotentiallyNullVar = let final Never #t231 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:331:25: Error: A value of type 'Tearoffable' can't be assigned to a variable of type 'YpotentiallyNull'.
  - 'Tearoffable' is from 'pkg/front_end/testcases/nnbd/assignability.dart'.
   yPotentiallyNullVar = tearoffableArg;
                         ^" in tearoffableArg as{TypeError,ForNonNullableByDefault} Never;
-  yPotentiallyNullVar = let final Never #t234 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:332:25: Error: A value of type 'Tearoffable?' can't be assigned to a variable of type 'YpotentiallyNull'.
+  yPotentiallyNullVar = let final Never #t232 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:332:25: Error: A value of type 'Tearoffable?' can't be assigned to a variable of type 'YpotentiallyNull'.
  - 'Tearoffable' is from 'pkg/front_end/testcases/nnbd/assignability.dart'.
   yPotentiallyNullVar = tearoffableNullableArg;
                         ^" in tearoffableNullableArg as{TypeError,ForNonNullableByDefault} Never;
-  yPotentiallyNullVar = let final Never #t235 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:333:25: Error: A value of type 'XnonNull' can't be assigned to a variable of type 'YpotentiallyNull'.
+  yPotentiallyNullVar = let final Never #t233 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:333:25: Error: A value of type 'XnonNull' can't be assigned to a variable of type 'YpotentiallyNull'.
   yPotentiallyNullVar = xNonNullArg;
                         ^" in xNonNullArg as{TypeError,ForNonNullableByDefault} Never;
-  yPotentiallyNullVar = let final Never #t236 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:334:25: Error: A value of type 'XnonNull?' can't be assigned to a variable of type 'YpotentiallyNull'.
+  yPotentiallyNullVar = let final Never #t234 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:334:25: Error: A value of type 'XnonNull?' can't be assigned to a variable of type 'YpotentiallyNull'.
   yPotentiallyNullVar = xNonNullNullableArg;
                         ^" in xNonNullNullableArg as{TypeError,ForNonNullableByDefault} Never;
-  yPotentiallyNullVar = let final Never #t237 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:335:25: Error: A value of type 'XpotentiallyNull' can't be assigned to a variable of type 'YpotentiallyNull'.
+  yPotentiallyNullVar = let final Never #t235 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:335:25: Error: A value of type 'XpotentiallyNull' can't be assigned to a variable of type 'YpotentiallyNull'.
   yPotentiallyNullVar = xPotentiallyNullArg;
                         ^" in xPotentiallyNullArg as{TypeError,ForNonNullableByDefault} Never;
-  yPotentiallyNullVar = let final Never #t238 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:336:25: Error: A value of type 'XpotentiallyNull?' can't be assigned to a variable of type 'YpotentiallyNull'.
+  yPotentiallyNullVar = let final Never #t236 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:336:25: Error: A value of type 'XpotentiallyNull?' can't be assigned to a variable of type 'YpotentiallyNull'.
   yPotentiallyNullVar = xPotentiallyNullNullableArg;
                         ^" in xPotentiallyNullNullableArg as{TypeError,ForNonNullableByDefault} Never;
-  yPotentiallyNullVar = let final Never #t239 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:337:25: Error: A value of type 'YnonNull' can't be assigned to a variable of type 'YpotentiallyNull'.
+  yPotentiallyNullVar = let final Never #t237 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:337:25: Error: A value of type 'YnonNull' can't be assigned to a variable of type 'YpotentiallyNull'.
   yPotentiallyNullVar = yNonNullArg;
                         ^" in yNonNullArg as{TypeError,ForNonNullableByDefault} Never;
-  yPotentiallyNullVar = let final Never #t240 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:338:25: Error: A value of type 'YnonNull?' can't be assigned to a variable of type 'YpotentiallyNull'.
+  yPotentiallyNullVar = let final Never #t238 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:338:25: Error: A value of type 'YnonNull?' can't be assigned to a variable of type 'YpotentiallyNull'.
   yPotentiallyNullVar = yNonNullNullableArg;
                         ^" in yNonNullNullableArg as{TypeError,ForNonNullableByDefault} Never;
-  yPotentiallyNullVar = let final Never #t241 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:339:25: Error: A value of type 'YpotentiallyNull?' can't be assigned to a variable of type 'YpotentiallyNull' because 'YpotentiallyNull?' is nullable and 'YpotentiallyNull' isn't.
+  yPotentiallyNullVar = let final Never #t239 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:339:25: Error: A value of type 'YpotentiallyNull?' can't be assigned to a variable of type 'YpotentiallyNull' because 'YpotentiallyNull?' is nullable and 'YpotentiallyNull' isn't.
   yPotentiallyNullVar = yPotentiallyNullNullableArg;
                         ^" in yPotentiallyNullNullableArg as{TypeError,ForNonNullableByDefault} Never;
 }
diff --git a/pkg/front_end/testcases/nnbd/assignability.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/assignability.dart.weak.transformed.expect
index 945c6ab..74dd324 100644
--- a/pkg/front_end/testcases/nnbd/assignability.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/assignability.dart.weak.transformed.expect
@@ -1324,11 +1324,11 @@
   functionVar = let final Never #t85 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:200:17: Error: A value of type 'Function?' can't be assigned to a variable of type 'Function' because 'Function?' is nullable and 'Function' isn't.
  - 'Function' is from 'dart:core'.
   functionVar = functionNullableArg;
-                ^" in functionNullableArg;
+                ^" in functionNullableArg as{TypeError,ForNonNullableByDefault} core::Function;
   functionVar = let final Never #t86 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:201:17: Error: A value of type 'void Function()?' can't be assigned to a variable of type 'Function' because 'void Function()?' is nullable and 'Function' isn't.
  - 'Function' is from 'dart:core'.
   functionVar = toVoidNullableArg;
-                ^" in toVoidNullableArg;
+                ^" in toVoidNullableArg as{TypeError,ForNonNullableByDefault} core::Function;
   functionVar = let final Never #t87 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:202:17: Error: Can't tear off method 'call' from a potentially null value.
   functionVar = tearoffableNullableArg;
                 ^" in tearoffableNullableArg as{TypeError} core::Function;
diff --git a/pkg/front_end/testcases/nnbd/ffi_sample.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/ffi_sample.dart.strong.transformed.expect
index e039c5f..ff9d534 100644
--- a/pkg/front_end/testcases/nnbd/ffi_sample.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/ffi_sample.dart.strong.transformed.expect
@@ -6,9 +6,9 @@
 import "dart:ffi";
 import "package:ffi/ffi.dart";
 
-@#C6
+@#C7
 class Coordinate extends ffi::Struct {
-  static final field core::int* #sizeOf = (#C9).{core::List::[]}(ffi::_abi())/*isLegacy*/;
+  static final field core::int* #sizeOf = (#C10).{core::List::[]}(ffi::_abi())/*isLegacy*/;
   @#C12
   constructor #fromTypedDataBase(dynamic #pointer) → dynamic
     : super ffi::Struct::_fromPointer(#pointer)
@@ -44,14 +44,14 @@
   #C2 = TypeLiteralConstant(ffi::Double)
   #C3 = TypeLiteralConstant(ffi::Pointer<ffi::NativeType>)
   #C4 = <core::Type>[#C2, #C2, #C3]
-  #C5 = ffi::_FfiStructLayout {fieldTypes:#C4}
-  #C6 = core::pragma {name:#C1, options:#C5}
-  #C7 = 24
-  #C8 = 20
-  #C9 = <core::int*>[#C7, #C8, #C7]
-  #C10 = "vm:entry-point"
-  #C11 = null
-  #C12 = core::pragma {name:#C10, options:#C11}
+  #C5 = null
+  #C6 = ffi::_FfiStructLayout {fieldTypes:#C4, packing:#C5}
+  #C7 = core::pragma {name:#C1, options:#C6}
+  #C8 = 24
+  #C9 = 20
+  #C10 = <core::int*>[#C8, #C9, #C8]
+  #C11 = "vm:entry-point"
+  #C12 = core::pragma {name:#C11, options:#C5}
   #C13 = ffi::Double {}
   #C14 = 0
   #C15 = <core::int*>[#C14, #C14, #C14]
diff --git a/pkg/front_end/testcases/nnbd/ffi_sample.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/ffi_sample.dart.weak.transformed.expect
index e039c5f..ff9d534 100644
--- a/pkg/front_end/testcases/nnbd/ffi_sample.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/ffi_sample.dart.weak.transformed.expect
@@ -6,9 +6,9 @@
 import "dart:ffi";
 import "package:ffi/ffi.dart";
 
-@#C6
+@#C7
 class Coordinate extends ffi::Struct {
-  static final field core::int* #sizeOf = (#C9).{core::List::[]}(ffi::_abi())/*isLegacy*/;
+  static final field core::int* #sizeOf = (#C10).{core::List::[]}(ffi::_abi())/*isLegacy*/;
   @#C12
   constructor #fromTypedDataBase(dynamic #pointer) → dynamic
     : super ffi::Struct::_fromPointer(#pointer)
@@ -44,14 +44,14 @@
   #C2 = TypeLiteralConstant(ffi::Double)
   #C3 = TypeLiteralConstant(ffi::Pointer<ffi::NativeType>)
   #C4 = <core::Type>[#C2, #C2, #C3]
-  #C5 = ffi::_FfiStructLayout {fieldTypes:#C4}
-  #C6 = core::pragma {name:#C1, options:#C5}
-  #C7 = 24
-  #C8 = 20
-  #C9 = <core::int*>[#C7, #C8, #C7]
-  #C10 = "vm:entry-point"
-  #C11 = null
-  #C12 = core::pragma {name:#C10, options:#C11}
+  #C5 = null
+  #C6 = ffi::_FfiStructLayout {fieldTypes:#C4, packing:#C5}
+  #C7 = core::pragma {name:#C1, options:#C6}
+  #C8 = 24
+  #C9 = 20
+  #C10 = <core::int*>[#C8, #C9, #C8]
+  #C11 = "vm:entry-point"
+  #C12 = core::pragma {name:#C11, options:#C5}
   #C13 = ffi::Double {}
   #C14 = 0
   #C15 = <core::int*>[#C14, #C14, #C14]
diff --git a/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.strong.expect b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.strong.expect
index fa7c510..d997209 100644
--- a/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.strong.expect
@@ -9,19 +9,20 @@
   synthetic constructor •() → self::StructInlineArray
     : super ffi::Struct::•()
     ;
-  @#C2
+  @#C3
   external get a0() → ffi::Array<ffi::Uint8>;
-  @#C2
+  @#C3
   external set a0(ffi::Array<ffi::Uint8> #externalFieldValue) → void;
 }
 static method main() → dynamic {}
 
 constants  {
   #C1 = 8
-  #C2 = ffi::_ArraySize<ffi::NativeType> {dimension1:#C1}
+  #C2 = null
+  #C3 = ffi::_ArraySize<ffi::NativeType> {dimension1:#C1, dimension2:#C2, dimension3:#C2, dimension4:#C2, dimension5:#C2, dimensions:#C2}
 }
 
 
 Constructor coverage from constants:
 org-dartlang-testcase:///ffi_struct_inline_array.dart:
-- _ArraySize. (from org-dartlang-sdk:///sdk/lib/_internal/vm/lib/ffi_patch.dart:133:9)
+- _ArraySize. (from org-dartlang-sdk:///sdk/lib/ffi/ffi.dart:134:9)
diff --git a/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.strong.transformed.expect
index 77d29d6..62cdedc 100644
--- a/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.strong.transformed.expect
@@ -8,9 +8,9 @@
 import "dart:ffi";
 import "package:ffi/ffi.dart";
 
-@#C7
+@#C8
 class StructInlineArray extends ffi::Struct {
-  static final field core::int* #sizeOf = (#C8).{core::List::[]}(ffi::_abi())/*isLegacy*/;
+  static final field core::int* #sizeOf = (#C9).{core::List::[]}(ffi::_abi())/*isLegacy*/;
   synthetic constructor •() → self::StructInlineArray
     : super ffi::Struct::•()
     ;
@@ -20,13 +20,13 @@
     ;
   @#C12
   get a0() → ffi::Array<ffi::Uint8>
-    return new ffi::Array::_<ffi::Array<ffi::Uint8>>( block {
+    return new ffi::Array::_<ffi::Uint8>( block {
       core::Object #typedDataBase = this.{ffi::Struct::_addressOf};
       core::int #offset = (#C14).{core::List::[]}(ffi::_abi());
-    } =>#typedDataBase is ffi::Pointer<dynamic> ?{core::Object} ffi::_fromAddress<ffi::Uint8>(#typedDataBase.{ffi::Pointer::address}.{core::num::+}(#offset)) : let typ::TypedData #typedData = _in::unsafeCast<typ::TypedData>(#typedDataBase) in #typedData.{typ::TypedData::buffer}.{typ::ByteBuffer::asUint8List}(#typedData.{typ::TypedData::offsetInBytes}.{core::num::+}(#offset), (#C8).{core::List::[]}(ffi::_abi())), #C3);
+    } =>#typedDataBase is ffi::Pointer<dynamic> ?{core::Object} ffi::_fromAddress<ffi::Uint8>(#typedDataBase.{ffi::Pointer::address}.{core::num::+}(#offset)) : let typ::TypedData #typedData = _in::unsafeCast<typ::TypedData>(#typedDataBase) in #typedData.{typ::TypedData::buffer}.{typ::ByteBuffer::asUint8List}(#typedData.{typ::TypedData::offsetInBytes}.{core::num::+}(#offset), (#C9).{core::List::[]}(ffi::_abi())), #C3, #C15);
   @#C12
   set a0(ffi::Array<ffi::Uint8> #externalFieldValue) → void
-    return ffi::_memCopy(this.{ffi::Struct::_addressOf}, (#C14).{core::List::[]}(ffi::_abi()), #externalFieldValue.{ffi::Array::_typedDataBase}, #C13, (#C8).{core::List::[]}(ffi::_abi()));
+    return ffi::_memCopy(this.{ffi::Struct::_addressOf}, (#C14).{core::List::[]}(ffi::_abi()), #externalFieldValue.{ffi::Array::_typedDataBase}, #C13, (#C9).{core::List::[]}(ffi::_abi()));
 }
 static method main() → dynamic {}
 
@@ -36,18 +36,19 @@
   #C3 = 8
   #C4 = ffi::_FfiInlineArray {elementType:#C2, length:#C3}
   #C5 = <core::Type>[#C4]
-  #C6 = ffi::_FfiStructLayout {fieldTypes:#C5}
-  #C7 = core::pragma {name:#C1, options:#C6}
-  #C8 = <core::int*>[#C3, #C3, #C3]
-  #C9 = "vm:entry-point"
-  #C10 = null
-  #C11 = core::pragma {name:#C9, options:#C10}
-  #C12 = ffi::_ArraySize<ffi::NativeType> {dimension1:#C3}
+  #C6 = null
+  #C7 = ffi::_FfiStructLayout {fieldTypes:#C5, packing:#C6}
+  #C8 = core::pragma {name:#C1, options:#C7}
+  #C9 = <core::int*>[#C3, #C3, #C3]
+  #C10 = "vm:entry-point"
+  #C11 = core::pragma {name:#C10, options:#C6}
+  #C12 = ffi::_ArraySize<ffi::NativeType> {dimension1:#C3, dimension2:#C6, dimension3:#C6, dimension4:#C6, dimension5:#C6, dimensions:#C6}
   #C13 = 0
   #C14 = <core::int*>[#C13, #C13, #C13]
+  #C15 = <core::int*>[]
 }
 
 
 Constructor coverage from constants:
 org-dartlang-testcase:///ffi_struct_inline_array.dart:
-- _ArraySize. (from org-dartlang-sdk:///sdk/lib/_internal/vm/lib/ffi_patch.dart:133:9)
+- _ArraySize. (from org-dartlang-sdk:///sdk/lib/ffi/ffi.dart:134:9)
diff --git a/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.weak.expect b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.weak.expect
index 5125b89..f04b75d 100644
--- a/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.weak.expect
@@ -9,19 +9,20 @@
   synthetic constructor •() → self::StructInlineArray
     : super ffi::Struct::•()
     ;
-  @#C2
+  @#C3
   external get a0() → ffi::Array<ffi::Uint8>;
-  @#C2
+  @#C3
   external set a0(ffi::Array<ffi::Uint8> #externalFieldValue) → void;
 }
 static method main() → dynamic {}
 
 constants  {
   #C1 = 8
-  #C2 = ffi::_ArraySize<ffi::NativeType*> {dimension1:#C1}
+  #C2 = null
+  #C3 = ffi::_ArraySize<ffi::NativeType*> {dimension1:#C1, dimension2:#C2, dimension3:#C2, dimension4:#C2, dimension5:#C2, dimensions:#C2}
 }
 
 
 Constructor coverage from constants:
 org-dartlang-testcase:///ffi_struct_inline_array.dart:
-- _ArraySize. (from org-dartlang-sdk:///sdk/lib/_internal/vm/lib/ffi_patch.dart:133:9)
+- _ArraySize. (from org-dartlang-sdk:///sdk/lib/ffi/ffi.dart:134:9)
diff --git a/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.weak.outline.expect b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.weak.outline.expect
index 75350ad..209ea1d 100644
--- a/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.weak.outline.expect
@@ -18,6 +18,6 @@
 
 
 Extra constant evaluation status:
-Evaluated: ConstructorInvocation @ org-dartlang-testcase:///ffi_struct_inline_array.dart:10:4 -> InstanceConstant(const _ArraySize<NativeType*>{_ArraySize.dimension1: 8})
-Evaluated: ConstructorInvocation @ org-dartlang-testcase:///ffi_struct_inline_array.dart:10:4 -> InstanceConstant(const _ArraySize<NativeType*>{_ArraySize.dimension1: 8})
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///ffi_struct_inline_array.dart:10:4 -> InstanceConstant(const _ArraySize<NativeType*>{_ArraySize.dimension1: 8, _ArraySize.dimension2: null, _ArraySize.dimension3: null, _ArraySize.dimension4: null, _ArraySize.dimension5: null, _ArraySize.dimensions: null})
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///ffi_struct_inline_array.dart:10:4 -> InstanceConstant(const _ArraySize<NativeType*>{_ArraySize.dimension1: 8, _ArraySize.dimension2: null, _ArraySize.dimension3: null, _ArraySize.dimension4: null, _ArraySize.dimension5: null, _ArraySize.dimensions: null})
 Extra constant evaluation: evaluated: 2, effectively constant: 2
diff --git a/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.weak.transformed.expect
index bd41225..85a31bd 100644
--- a/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.weak.transformed.expect
@@ -8,9 +8,9 @@
 import "dart:ffi";
 import "package:ffi/ffi.dart";
 
-@#C7
+@#C8
 class StructInlineArray extends ffi::Struct {
-  static final field core::int* #sizeOf = (#C8).{core::List::[]}(ffi::_abi())/*isLegacy*/;
+  static final field core::int* #sizeOf = (#C9).{core::List::[]}(ffi::_abi())/*isLegacy*/;
   synthetic constructor •() → self::StructInlineArray
     : super ffi::Struct::•()
     ;
@@ -20,13 +20,13 @@
     ;
   @#C12
   get a0() → ffi::Array<ffi::Uint8>
-    return new ffi::Array::_<ffi::Array<ffi::Uint8>>( block {
+    return new ffi::Array::_<ffi::Uint8>( block {
       core::Object #typedDataBase = this.{ffi::Struct::_addressOf};
       core::int #offset = (#C14).{core::List::[]}(ffi::_abi());
-    } =>#typedDataBase is ffi::Pointer<dynamic> ?{core::Object} ffi::_fromAddress<ffi::Uint8>(#typedDataBase.{ffi::Pointer::address}.{core::num::+}(#offset)) : let typ::TypedData #typedData = _in::unsafeCast<typ::TypedData>(#typedDataBase) in #typedData.{typ::TypedData::buffer}.{typ::ByteBuffer::asUint8List}(#typedData.{typ::TypedData::offsetInBytes}.{core::num::+}(#offset), (#C8).{core::List::[]}(ffi::_abi())), #C3);
+    } =>#typedDataBase is ffi::Pointer<dynamic> ?{core::Object} ffi::_fromAddress<ffi::Uint8>(#typedDataBase.{ffi::Pointer::address}.{core::num::+}(#offset)) : let typ::TypedData #typedData = _in::unsafeCast<typ::TypedData>(#typedDataBase) in #typedData.{typ::TypedData::buffer}.{typ::ByteBuffer::asUint8List}(#typedData.{typ::TypedData::offsetInBytes}.{core::num::+}(#offset), (#C9).{core::List::[]}(ffi::_abi())), #C3, #C15);
   @#C12
   set a0(ffi::Array<ffi::Uint8> #externalFieldValue) → void
-    return ffi::_memCopy(this.{ffi::Struct::_addressOf}, (#C14).{core::List::[]}(ffi::_abi()), #externalFieldValue.{ffi::Array::_typedDataBase}, #C13, (#C8).{core::List::[]}(ffi::_abi()));
+    return ffi::_memCopy(this.{ffi::Struct::_addressOf}, (#C14).{core::List::[]}(ffi::_abi()), #externalFieldValue.{ffi::Array::_typedDataBase}, #C13, (#C9).{core::List::[]}(ffi::_abi()));
 }
 static method main() → dynamic {}
 
@@ -36,18 +36,19 @@
   #C3 = 8
   #C4 = ffi::_FfiInlineArray {elementType:#C2, length:#C3}
   #C5 = <core::Type>[#C4]
-  #C6 = ffi::_FfiStructLayout {fieldTypes:#C5}
-  #C7 = core::pragma {name:#C1, options:#C6}
-  #C8 = <core::int*>[#C3, #C3, #C3]
-  #C9 = "vm:entry-point"
-  #C10 = null
-  #C11 = core::pragma {name:#C9, options:#C10}
-  #C12 = ffi::_ArraySize<ffi::NativeType*> {dimension1:#C3}
+  #C6 = null
+  #C7 = ffi::_FfiStructLayout {fieldTypes:#C5, packing:#C6}
+  #C8 = core::pragma {name:#C1, options:#C7}
+  #C9 = <core::int*>[#C3, #C3, #C3]
+  #C10 = "vm:entry-point"
+  #C11 = core::pragma {name:#C10, options:#C6}
+  #C12 = ffi::_ArraySize<ffi::NativeType*> {dimension1:#C3, dimension2:#C6, dimension3:#C6, dimension4:#C6, dimension5:#C6, dimensions:#C6}
   #C13 = 0
   #C14 = <core::int*>[#C13, #C13, #C13]
+  #C15 = <core::int*>[]
 }
 
 
 Constructor coverage from constants:
 org-dartlang-testcase:///ffi_struct_inline_array.dart:
-- _ArraySize. (from org-dartlang-sdk:///sdk/lib/_internal/vm/lib/ffi_patch.dart:133:9)
+- _ArraySize. (from org-dartlang-sdk:///sdk/lib/ffi/ffi.dart:134:9)
diff --git a/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart
new file mode 100644
index 0000000..08618c8
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. 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 "package:ffi/ffi.dart";
+
+class StructInlineArrayMultiDimensional extends Struct {
+  @Array(2, 2, 2)
+  external Array<Array<Array<Uint8>>> a0;
+}
+
+main() {
+  final pointer = calloc<StructInlineArrayMultiDimensional>();
+  final struct = pointer.ref;
+  final array = struct.a0;
+  final subArray = array[0];
+  array[1] = subArray;
+  calloc.free(pointer);
+}
diff --git a/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.strong.expect b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.strong.expect
new file mode 100644
index 0000000..391f4bc
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.strong.expect
@@ -0,0 +1,36 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:ffi" as ffi;
+
+import "dart:ffi";
+import "package:ffi/ffi.dart";
+
+class StructInlineArrayMultiDimensional extends ffi::Struct {
+  synthetic constructor •() → self::StructInlineArrayMultiDimensional
+    : super ffi::Struct::•()
+    ;
+  @#C3
+  external get a0() → ffi::Array<ffi::Array<ffi::Array<ffi::Uint8>>>;
+  @#C3
+  external set a0(ffi::Array<ffi::Array<ffi::Array<ffi::Uint8>>> #externalFieldValue) → void;
+}
+static method main() → dynamic {
+  final ffi::Pointer<self::StructInlineArrayMultiDimensional> pointer = ffi::AllocatorAlloc|call<self::StructInlineArrayMultiDimensional>(#C4);
+  final self::StructInlineArrayMultiDimensional struct = ffi::StructPointer|get#ref<self::StructInlineArrayMultiDimensional>(pointer);
+  final ffi::Array<ffi::Array<ffi::Array<ffi::Uint8>>> array = struct.{self::StructInlineArrayMultiDimensional::a0};
+  final ffi::Array<ffi::Array<ffi::Uint8>> subArray = ffi::ArrayArray|[]<ffi::Array<ffi::Uint8>>(array, 0);
+  ffi::ArrayArray|[]=<ffi::Array<ffi::Uint8>>(array, 1, subArray);
+  (#C4).{ffi::Allocator::free}(pointer);
+}
+
+constants  {
+  #C1 = 2
+  #C2 = null
+  #C3 = ffi::_ArraySize<ffi::NativeType> {dimension1:#C1, dimension2:#C1, dimension3:#C1, dimension4:#C2, dimension5:#C2, dimensions:#C2}
+  #C4 = all::_CallocAllocator {}
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///ffi_struct_inline_array_multi_dimensional.dart:
+- _ArraySize. (from org-dartlang-sdk:///sdk/lib/ffi/ffi.dart:134:9)
diff --git a/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.strong.transformed.expect
new file mode 100644
index 0000000..f190d80
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.strong.transformed.expect
@@ -0,0 +1,86 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:ffi" as ffi;
+import "dart:typed_data" as typ;
+import "dart:_internal" as _in;
+
+import "dart:ffi";
+import "package:ffi/ffi.dart";
+
+@#C8
+class StructInlineArrayMultiDimensional extends ffi::Struct {
+  static final field core::int* #sizeOf = (#C9).{core::List::[]}(ffi::_abi())/*isLegacy*/;
+  synthetic constructor •() → self::StructInlineArrayMultiDimensional
+    : super ffi::Struct::•()
+    ;
+  @#C11
+  constructor #fromTypedDataBase(dynamic #pointer) → dynamic
+    : super ffi::Struct::_fromPointer(#pointer)
+    ;
+  @#C13
+  get a0() → ffi::Array<ffi::Array<ffi::Array<ffi::Uint8>>>
+    return new ffi::Array::_<ffi::Array<ffi::Array<ffi::Uint8>>>( block {
+      core::Object #typedDataBase = this.{ffi::Struct::_addressOf};
+      core::int #offset = (#C15).{core::List::[]}(ffi::_abi());
+    } =>#typedDataBase is ffi::Pointer<dynamic> ?{core::Object} ffi::_fromAddress<ffi::Array<ffi::Array<ffi::Uint8>>>(#typedDataBase.{ffi::Pointer::address}.{core::num::+}(#offset)) : let typ::TypedData #typedData = _in::unsafeCast<typ::TypedData>(#typedDataBase) in #typedData.{typ::TypedData::buffer}.{typ::ByteBuffer::asUint8List}(#typedData.{typ::TypedData::offsetInBytes}.{core::num::+}(#offset), (#C9).{core::List::[]}(ffi::_abi())), #C12, #C16);
+  @#C13
+  set a0(ffi::Array<ffi::Array<ffi::Array<ffi::Uint8>>> #externalFieldValue) → void
+    return ffi::_memCopy(this.{ffi::Struct::_addressOf}, (#C15).{core::List::[]}(ffi::_abi()), #externalFieldValue.{ffi::Array::_typedDataBase}, #C14, (#C9).{core::List::[]}(ffi::_abi()));
+}
+static method main() → dynamic {
+  final ffi::Pointer<self::StructInlineArrayMultiDimensional> pointer = (#C17).{ffi::Allocator::allocate}<self::StructInlineArrayMultiDimensional>(self::StructInlineArrayMultiDimensional::#sizeOf);
+  final self::StructInlineArrayMultiDimensional struct = new self::StructInlineArrayMultiDimensional::#fromTypedDataBase(pointer!);
+  final ffi::Array<ffi::Array<ffi::Array<ffi::Uint8>>> array = struct.{self::StructInlineArrayMultiDimensional::a0};
+  final ffi::Array<ffi::Array<ffi::Uint8>> subArray = block {
+    ffi::Array<dynamic> #array = array!;
+    core::int #index = 0!;
+    #array.{ffi::Array::_checkIndex}(#index);
+    core::int #singleElementSize = #C18;
+    core::int #elementSize = #singleElementSize.{core::num::*}(#array.{ffi::Array::_nestedDimensionsFlattened});
+    core::int #offset = #elementSize.{core::num::*}(#index);
+  } =>new ffi::Array::_<ffi::Array<ffi::Uint8>>( block {
+    core::Object #typedDataBase = #array.{ffi::Array::_typedDataBase};
+    core::int #offset = #offset;
+  } =>#typedDataBase is ffi::Pointer<dynamic> ?{core::Object} ffi::_fromAddress<ffi::Array<ffi::Uint8>>(#typedDataBase.{ffi::Pointer::address}.{core::num::+}(#offset)) : let typ::TypedData #typedData = _in::unsafeCast<typ::TypedData>(#typedDataBase) in #typedData.{typ::TypedData::buffer}.{typ::ByteBuffer::asUint8List}(#typedData.{typ::TypedData::offsetInBytes}.{core::num::+}(#offset), #elementSize), #array.{ffi::Array::_nestedDimensionsFirst}, #array.{ffi::Array::_nestedDimensionsRest});
+  block {
+    ffi::Array<dynamic> #array = array!;
+    core::int #index = 1!;
+    #array.{ffi::Array::_checkIndex}(#index);
+    core::int #singleElementSize = #C18;
+    core::int #elementSize = #singleElementSize.{core::num::*}(#array.{ffi::Array::_nestedDimensionsFlattened});
+    core::int #offset = #elementSize.{core::num::*}(#index);
+  } =>ffi::_memCopy(#array.{ffi::Array::_typedDataBase}, #offset, subArray.{ffi::Array::_typedDataBase}, #C14, #elementSize);
+  (#C17).{ffi::Allocator::free}(pointer);
+}
+
+constants  {
+  #C1 = "vm:ffi:struct-fields"
+  #C2 = TypeLiteralConstant(ffi::Uint8)
+  #C3 = 8
+  #C4 = ffi::_FfiInlineArray {elementType:#C2, length:#C3}
+  #C5 = <core::Type>[#C4]
+  #C6 = null
+  #C7 = ffi::_FfiStructLayout {fieldTypes:#C5, packing:#C6}
+  #C8 = core::pragma {name:#C1, options:#C7}
+  #C9 = <core::int*>[#C3, #C3, #C3]
+  #C10 = "vm:entry-point"
+  #C11 = core::pragma {name:#C10, options:#C6}
+  #C12 = 2
+  #C13 = ffi::_ArraySize<ffi::NativeType> {dimension1:#C12, dimension2:#C12, dimension3:#C12, dimension4:#C6, dimension5:#C6, dimensions:#C6}
+  #C14 = 0
+  #C15 = <core::int*>[#C14, #C14, #C14]
+  #C16 = <core::int*>[#C12, #C12]
+  #C17 = all::_CallocAllocator {}
+  #C18 = 1
+}
+
+Extra constant evaluation status:
+Evaluated: NullCheck @ org-dartlang-testcase:///ffi_struct_inline_array_multi_dimensional.dart:18:25 -> IntConstant(0)
+Evaluated: NullCheck @ org-dartlang-testcase:///ffi_struct_inline_array_multi_dimensional.dart:19:8 -> IntConstant(1)
+Extra constant evaluation: evaluated: 110, effectively constant: 2
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///ffi_struct_inline_array_multi_dimensional.dart:
+- _ArraySize. (from org-dartlang-sdk:///sdk/lib/ffi/ffi.dart:134:9)
diff --git a/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.textual_outline.expect
new file mode 100644
index 0000000..677a6db
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+import 'dart:ffi';
+import "package:ffi/ffi.dart";
+
+class StructInlineArrayMultiDimensional extends Struct {
+  @Array(2, 2, 2)
+  external Array<Array<Array<Uint8>>> a0;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b7c36aa
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+import "package:ffi/ffi.dart";
+import 'dart:ffi';
+
+class StructInlineArrayMultiDimensional extends Struct {
+  @Array(2, 2, 2)
+  external Array<Array<Array<Uint8>>> a0;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.weak.expect b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.weak.expect
new file mode 100644
index 0000000..32510af
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.weak.expect
@@ -0,0 +1,36 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:ffi" as ffi;
+
+import "dart:ffi";
+import "package:ffi/ffi.dart";
+
+class StructInlineArrayMultiDimensional extends ffi::Struct {
+  synthetic constructor •() → self::StructInlineArrayMultiDimensional
+    : super ffi::Struct::•()
+    ;
+  @#C3
+  external get a0() → ffi::Array<ffi::Array<ffi::Array<ffi::Uint8>>>;
+  @#C3
+  external set a0(ffi::Array<ffi::Array<ffi::Array<ffi::Uint8>>> #externalFieldValue) → void;
+}
+static method main() → dynamic {
+  final ffi::Pointer<self::StructInlineArrayMultiDimensional> pointer = ffi::AllocatorAlloc|call<self::StructInlineArrayMultiDimensional>(#C4);
+  final self::StructInlineArrayMultiDimensional struct = ffi::StructPointer|get#ref<self::StructInlineArrayMultiDimensional>(pointer);
+  final ffi::Array<ffi::Array<ffi::Array<ffi::Uint8>>> array = struct.{self::StructInlineArrayMultiDimensional::a0};
+  final ffi::Array<ffi::Array<ffi::Uint8>> subArray = ffi::ArrayArray|[]<ffi::Array<ffi::Uint8>>(array, 0);
+  ffi::ArrayArray|[]=<ffi::Array<ffi::Uint8>>(array, 1, subArray);
+  (#C4).{ffi::Allocator::free}(pointer);
+}
+
+constants  {
+  #C1 = 2
+  #C2 = null
+  #C3 = ffi::_ArraySize<ffi::NativeType*> {dimension1:#C1, dimension2:#C1, dimension3:#C1, dimension4:#C2, dimension5:#C2, dimensions:#C2}
+  #C4 = all::_CallocAllocator {}
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///ffi_struct_inline_array_multi_dimensional.dart:
+- _ArraySize. (from org-dartlang-sdk:///sdk/lib/ffi/ffi.dart:134:9)
diff --git a/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.weak.outline.expect b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.weak.outline.expect
new file mode 100644
index 0000000..4cd5816
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.weak.outline.expect
@@ -0,0 +1,23 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:ffi" as ffi;
+
+import "dart:ffi";
+import "package:ffi/ffi.dart";
+
+class StructInlineArrayMultiDimensional extends ffi::Struct {
+  synthetic constructor •() → self::StructInlineArrayMultiDimensional
+    ;
+  @ffi::_ArraySize::•<ffi::NativeType>(2, 2, 2)
+  external get a0() → ffi::Array<ffi::Array<ffi::Array<ffi::Uint8>>>;
+  @ffi::_ArraySize::•<ffi::NativeType>(2, 2, 2)
+  external set a0(ffi::Array<ffi::Array<ffi::Array<ffi::Uint8>>> #externalFieldValue) → void;
+}
+static method main() → dynamic
+  ;
+
+
+Extra constant evaluation status:
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///ffi_struct_inline_array_multi_dimensional.dart:10:4 -> InstanceConstant(const _ArraySize<NativeType*>{_ArraySize.dimension1: 2, _ArraySize.dimension2: 2, _ArraySize.dimension3: 2, _ArraySize.dimension4: null, _ArraySize.dimension5: null, _ArraySize.dimensions: null})
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///ffi_struct_inline_array_multi_dimensional.dart:10:4 -> InstanceConstant(const _ArraySize<NativeType*>{_ArraySize.dimension1: 2, _ArraySize.dimension2: 2, _ArraySize.dimension3: 2, _ArraySize.dimension4: null, _ArraySize.dimension5: null, _ArraySize.dimensions: null})
+Extra constant evaluation: evaluated: 2, effectively constant: 2
diff --git a/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.weak.transformed.expect
new file mode 100644
index 0000000..abf15e4
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.weak.transformed.expect
@@ -0,0 +1,86 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:ffi" as ffi;
+import "dart:typed_data" as typ;
+import "dart:_internal" as _in;
+
+import "dart:ffi";
+import "package:ffi/ffi.dart";
+
+@#C8
+class StructInlineArrayMultiDimensional extends ffi::Struct {
+  static final field core::int* #sizeOf = (#C9).{core::List::[]}(ffi::_abi())/*isLegacy*/;
+  synthetic constructor •() → self::StructInlineArrayMultiDimensional
+    : super ffi::Struct::•()
+    ;
+  @#C11
+  constructor #fromTypedDataBase(dynamic #pointer) → dynamic
+    : super ffi::Struct::_fromPointer(#pointer)
+    ;
+  @#C13
+  get a0() → ffi::Array<ffi::Array<ffi::Array<ffi::Uint8>>>
+    return new ffi::Array::_<ffi::Array<ffi::Array<ffi::Uint8>>>( block {
+      core::Object #typedDataBase = this.{ffi::Struct::_addressOf};
+      core::int #offset = (#C15).{core::List::[]}(ffi::_abi());
+    } =>#typedDataBase is ffi::Pointer<dynamic> ?{core::Object} ffi::_fromAddress<ffi::Array<ffi::Array<ffi::Uint8>>>(#typedDataBase.{ffi::Pointer::address}.{core::num::+}(#offset)) : let typ::TypedData #typedData = _in::unsafeCast<typ::TypedData>(#typedDataBase) in #typedData.{typ::TypedData::buffer}.{typ::ByteBuffer::asUint8List}(#typedData.{typ::TypedData::offsetInBytes}.{core::num::+}(#offset), (#C9).{core::List::[]}(ffi::_abi())), #C12, #C16);
+  @#C13
+  set a0(ffi::Array<ffi::Array<ffi::Array<ffi::Uint8>>> #externalFieldValue) → void
+    return ffi::_memCopy(this.{ffi::Struct::_addressOf}, (#C15).{core::List::[]}(ffi::_abi()), #externalFieldValue.{ffi::Array::_typedDataBase}, #C14, (#C9).{core::List::[]}(ffi::_abi()));
+}
+static method main() → dynamic {
+  final ffi::Pointer<self::StructInlineArrayMultiDimensional> pointer = (#C17).{ffi::Allocator::allocate}<self::StructInlineArrayMultiDimensional>(self::StructInlineArrayMultiDimensional::#sizeOf);
+  final self::StructInlineArrayMultiDimensional struct = new self::StructInlineArrayMultiDimensional::#fromTypedDataBase(pointer!);
+  final ffi::Array<ffi::Array<ffi::Array<ffi::Uint8>>> array = struct.{self::StructInlineArrayMultiDimensional::a0};
+  final ffi::Array<ffi::Array<ffi::Uint8>> subArray = block {
+    ffi::Array<dynamic> #array = array!;
+    core::int #index = 0!;
+    #array.{ffi::Array::_checkIndex}(#index);
+    core::int #singleElementSize = #C18;
+    core::int #elementSize = #singleElementSize.{core::num::*}(#array.{ffi::Array::_nestedDimensionsFlattened});
+    core::int #offset = #elementSize.{core::num::*}(#index);
+  } =>new ffi::Array::_<ffi::Array<ffi::Uint8>>( block {
+    core::Object #typedDataBase = #array.{ffi::Array::_typedDataBase};
+    core::int #offset = #offset;
+  } =>#typedDataBase is ffi::Pointer<dynamic> ?{core::Object} ffi::_fromAddress<ffi::Array<ffi::Uint8>>(#typedDataBase.{ffi::Pointer::address}.{core::num::+}(#offset)) : let typ::TypedData #typedData = _in::unsafeCast<typ::TypedData>(#typedDataBase) in #typedData.{typ::TypedData::buffer}.{typ::ByteBuffer::asUint8List}(#typedData.{typ::TypedData::offsetInBytes}.{core::num::+}(#offset), #elementSize), #array.{ffi::Array::_nestedDimensionsFirst}, #array.{ffi::Array::_nestedDimensionsRest});
+  block {
+    ffi::Array<dynamic> #array = array!;
+    core::int #index = 1!;
+    #array.{ffi::Array::_checkIndex}(#index);
+    core::int #singleElementSize = #C18;
+    core::int #elementSize = #singleElementSize.{core::num::*}(#array.{ffi::Array::_nestedDimensionsFlattened});
+    core::int #offset = #elementSize.{core::num::*}(#index);
+  } =>ffi::_memCopy(#array.{ffi::Array::_typedDataBase}, #offset, subArray.{ffi::Array::_typedDataBase}, #C14, #elementSize);
+  (#C17).{ffi::Allocator::free}(pointer);
+}
+
+constants  {
+  #C1 = "vm:ffi:struct-fields"
+  #C2 = TypeLiteralConstant(ffi::Uint8)
+  #C3 = 8
+  #C4 = ffi::_FfiInlineArray {elementType:#C2, length:#C3}
+  #C5 = <core::Type>[#C4]
+  #C6 = null
+  #C7 = ffi::_FfiStructLayout {fieldTypes:#C5, packing:#C6}
+  #C8 = core::pragma {name:#C1, options:#C7}
+  #C9 = <core::int*>[#C3, #C3, #C3]
+  #C10 = "vm:entry-point"
+  #C11 = core::pragma {name:#C10, options:#C6}
+  #C12 = 2
+  #C13 = ffi::_ArraySize<ffi::NativeType*> {dimension1:#C12, dimension2:#C12, dimension3:#C12, dimension4:#C6, dimension5:#C6, dimensions:#C6}
+  #C14 = 0
+  #C15 = <core::int*>[#C14, #C14, #C14]
+  #C16 = <core::int*>[#C12, #C12]
+  #C17 = all::_CallocAllocator {}
+  #C18 = 1
+}
+
+Extra constant evaluation status:
+Evaluated: NullCheck @ org-dartlang-testcase:///ffi_struct_inline_array_multi_dimensional.dart:18:25 -> IntConstant(0)
+Evaluated: NullCheck @ org-dartlang-testcase:///ffi_struct_inline_array_multi_dimensional.dart:19:8 -> IntConstant(1)
+Extra constant evaluation: evaluated: 110, effectively constant: 2
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///ffi_struct_inline_array_multi_dimensional.dart:
+- _ArraySize. (from org-dartlang-sdk:///sdk/lib/ffi/ffi.dart:134:9)
diff --git a/pkg/front_end/testcases/nnbd/issue43278.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue43278.dart.strong.expect
index d15a9c9..3bfcc52 100644
--- a/pkg/front_end/testcases/nnbd/issue43278.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/issue43278.dart.strong.expect
@@ -19,15 +19,8 @@
 //   b.fooExtension ??= x; // Error.
 //     ^^^^^^^^^^^^
 //
-// pkg/front_end/testcases/nnbd/issue43278.dart:29:5: Error: The getter 'fooExtension' isn't defined for the class 'B?'.
-//  - 'B' is from 'pkg/front_end/testcases/nnbd/issue43278.dart'.
-// Try correcting the name to the name of an existing getter, or defining a getter or field named 'fooExtension'.
-//   t.fooExtension ??= x; // Error.
-//     ^^^^^^^^^^^^
-//
-// pkg/front_end/testcases/nnbd/issue43278.dart:29:5: Error: The setter 'fooExtension' isn't defined for the class 'B?'.
-//  - 'B' is from 'pkg/front_end/testcases/nnbd/issue43278.dart'.
-// Try correcting the name to the name of an existing setter, or defining a setter or field named 'fooExtension'.
+// pkg/front_end/testcases/nnbd/issue43278.dart:29:5: Error: Property 'fooExtension' cannot be accessed on 'T' because it is potentially null.
+// Try accessing using ?. instead.
 //   t.fooExtension ??= x; // Error.
 //     ^^^^^^^^^^^^
 //
@@ -86,15 +79,13 @@
 Try accessing using ?. instead.
   b.fooExtension ??= x; // Error.
     ^^^^^^^^^^^^" in self::Extension|set#fooExtension(#t10, x) : null;
-  let final self::testExtension::T% #t13 = t in invalid-expression "pkg/front_end/testcases/nnbd/issue43278.dart:29:5: Error: The getter 'fooExtension' isn't defined for the class 'B?'.
- - 'B' is from 'pkg/front_end/testcases/nnbd/issue43278.dart'.
-Try correcting the name to the name of an existing getter, or defining a getter or field named 'fooExtension'.
+  let final self::testExtension::T% #t13 = t in (let final Never #t14 = invalid-expression "pkg/front_end/testcases/nnbd/issue43278.dart:29:5: Error: Property 'fooExtension' cannot be accessed on 'T' because it is potentially null.
+Try accessing using ?. instead.
   t.fooExtension ??= x; // Error.
-    ^^^^^^^^^^^^".{core::Object::==}(null) ?{dynamic} invalid-expression "pkg/front_end/testcases/nnbd/issue43278.dart:29:5: Error: The setter 'fooExtension' isn't defined for the class 'B?'.
- - 'B' is from 'pkg/front_end/testcases/nnbd/issue43278.dart'.
-Try correcting the name to the name of an existing setter, or defining a setter or field named 'fooExtension'.
+    ^^^^^^^^^^^^" in self::Extension|get#fooExtension(#t13)).{core::num::==}(null) ?{core::int} let final Never #t15 = invalid-expression "pkg/front_end/testcases/nnbd/issue43278.dart:29:5: Error: Property 'fooExtension' cannot be accessed on 'T' because it is potentially null.
+Try accessing using ?. instead.
   t.fooExtension ??= x; // Error.
-    ^^^^^^^^^^^^" : null;
-  let final self::B? #t14 = b in #t14.{core::Object::==}(null) ?{core::int?} null : let final self::B #t15 = self::Extension|get#barExtension(#t14{self::B}) in self::Extension|get#fooExtension(#t15).{core::num::==}(null) ?{core::int} self::Extension|set#fooExtension(#t15, x) : null;
+    ^^^^^^^^^^^^" in self::Extension|set#fooExtension(#t13, x) : null;
+  let final self::B? #t16 = b in #t16.{core::Object::==}(null) ?{core::int?} null : let final self::B #t17 = self::Extension|get#barExtension(#t16{self::B}) in self::Extension|get#fooExtension(#t17).{core::num::==}(null) ?{core::int} self::Extension|set#fooExtension(#t17, x) : null;
 }
 static method main() → dynamic {}
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 d15a9c9..3bfcc52 100644
--- a/pkg/front_end/testcases/nnbd/issue43278.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue43278.dart.strong.transformed.expect
@@ -19,15 +19,8 @@
 //   b.fooExtension ??= x; // Error.
 //     ^^^^^^^^^^^^
 //
-// pkg/front_end/testcases/nnbd/issue43278.dart:29:5: Error: The getter 'fooExtension' isn't defined for the class 'B?'.
-//  - 'B' is from 'pkg/front_end/testcases/nnbd/issue43278.dart'.
-// Try correcting the name to the name of an existing getter, or defining a getter or field named 'fooExtension'.
-//   t.fooExtension ??= x; // Error.
-//     ^^^^^^^^^^^^
-//
-// pkg/front_end/testcases/nnbd/issue43278.dart:29:5: Error: The setter 'fooExtension' isn't defined for the class 'B?'.
-//  - 'B' is from 'pkg/front_end/testcases/nnbd/issue43278.dart'.
-// Try correcting the name to the name of an existing setter, or defining a setter or field named 'fooExtension'.
+// pkg/front_end/testcases/nnbd/issue43278.dart:29:5: Error: Property 'fooExtension' cannot be accessed on 'T' because it is potentially null.
+// Try accessing using ?. instead.
 //   t.fooExtension ??= x; // Error.
 //     ^^^^^^^^^^^^
 //
@@ -86,15 +79,13 @@
 Try accessing using ?. instead.
   b.fooExtension ??= x; // Error.
     ^^^^^^^^^^^^" in self::Extension|set#fooExtension(#t10, x) : null;
-  let final self::testExtension::T% #t13 = t in invalid-expression "pkg/front_end/testcases/nnbd/issue43278.dart:29:5: Error: The getter 'fooExtension' isn't defined for the class 'B?'.
- - 'B' is from 'pkg/front_end/testcases/nnbd/issue43278.dart'.
-Try correcting the name to the name of an existing getter, or defining a getter or field named 'fooExtension'.
+  let final self::testExtension::T% #t13 = t in (let final Never #t14 = invalid-expression "pkg/front_end/testcases/nnbd/issue43278.dart:29:5: Error: Property 'fooExtension' cannot be accessed on 'T' because it is potentially null.
+Try accessing using ?. instead.
   t.fooExtension ??= x; // Error.
-    ^^^^^^^^^^^^".{core::Object::==}(null) ?{dynamic} invalid-expression "pkg/front_end/testcases/nnbd/issue43278.dart:29:5: Error: The setter 'fooExtension' isn't defined for the class 'B?'.
- - 'B' is from 'pkg/front_end/testcases/nnbd/issue43278.dart'.
-Try correcting the name to the name of an existing setter, or defining a setter or field named 'fooExtension'.
+    ^^^^^^^^^^^^" in self::Extension|get#fooExtension(#t13)).{core::num::==}(null) ?{core::int} let final Never #t15 = invalid-expression "pkg/front_end/testcases/nnbd/issue43278.dart:29:5: Error: Property 'fooExtension' cannot be accessed on 'T' because it is potentially null.
+Try accessing using ?. instead.
   t.fooExtension ??= x; // Error.
-    ^^^^^^^^^^^^" : null;
-  let final self::B? #t14 = b in #t14.{core::Object::==}(null) ?{core::int?} null : let final self::B #t15 = self::Extension|get#barExtension(#t14{self::B}) in self::Extension|get#fooExtension(#t15).{core::num::==}(null) ?{core::int} self::Extension|set#fooExtension(#t15, x) : null;
+    ^^^^^^^^^^^^" in self::Extension|set#fooExtension(#t13, x) : null;
+  let final self::B? #t16 = b in #t16.{core::Object::==}(null) ?{core::int?} null : let final self::B #t17 = self::Extension|get#barExtension(#t16{self::B}) in self::Extension|get#fooExtension(#t17).{core::num::==}(null) ?{core::int} self::Extension|set#fooExtension(#t17, x) : null;
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue43278.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue43278.dart.weak.expect
index d15a9c9..3bfcc52 100644
--- a/pkg/front_end/testcases/nnbd/issue43278.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/issue43278.dart.weak.expect
@@ -19,15 +19,8 @@
 //   b.fooExtension ??= x; // Error.
 //     ^^^^^^^^^^^^
 //
-// pkg/front_end/testcases/nnbd/issue43278.dart:29:5: Error: The getter 'fooExtension' isn't defined for the class 'B?'.
-//  - 'B' is from 'pkg/front_end/testcases/nnbd/issue43278.dart'.
-// Try correcting the name to the name of an existing getter, or defining a getter or field named 'fooExtension'.
-//   t.fooExtension ??= x; // Error.
-//     ^^^^^^^^^^^^
-//
-// pkg/front_end/testcases/nnbd/issue43278.dart:29:5: Error: The setter 'fooExtension' isn't defined for the class 'B?'.
-//  - 'B' is from 'pkg/front_end/testcases/nnbd/issue43278.dart'.
-// Try correcting the name to the name of an existing setter, or defining a setter or field named 'fooExtension'.
+// pkg/front_end/testcases/nnbd/issue43278.dart:29:5: Error: Property 'fooExtension' cannot be accessed on 'T' because it is potentially null.
+// Try accessing using ?. instead.
 //   t.fooExtension ??= x; // Error.
 //     ^^^^^^^^^^^^
 //
@@ -86,15 +79,13 @@
 Try accessing using ?. instead.
   b.fooExtension ??= x; // Error.
     ^^^^^^^^^^^^" in self::Extension|set#fooExtension(#t10, x) : null;
-  let final self::testExtension::T% #t13 = t in invalid-expression "pkg/front_end/testcases/nnbd/issue43278.dart:29:5: Error: The getter 'fooExtension' isn't defined for the class 'B?'.
- - 'B' is from 'pkg/front_end/testcases/nnbd/issue43278.dart'.
-Try correcting the name to the name of an existing getter, or defining a getter or field named 'fooExtension'.
+  let final self::testExtension::T% #t13 = t in (let final Never #t14 = invalid-expression "pkg/front_end/testcases/nnbd/issue43278.dart:29:5: Error: Property 'fooExtension' cannot be accessed on 'T' because it is potentially null.
+Try accessing using ?. instead.
   t.fooExtension ??= x; // Error.
-    ^^^^^^^^^^^^".{core::Object::==}(null) ?{dynamic} invalid-expression "pkg/front_end/testcases/nnbd/issue43278.dart:29:5: Error: The setter 'fooExtension' isn't defined for the class 'B?'.
- - 'B' is from 'pkg/front_end/testcases/nnbd/issue43278.dart'.
-Try correcting the name to the name of an existing setter, or defining a setter or field named 'fooExtension'.
+    ^^^^^^^^^^^^" in self::Extension|get#fooExtension(#t13)).{core::num::==}(null) ?{core::int} let final Never #t15 = invalid-expression "pkg/front_end/testcases/nnbd/issue43278.dart:29:5: Error: Property 'fooExtension' cannot be accessed on 'T' because it is potentially null.
+Try accessing using ?. instead.
   t.fooExtension ??= x; // Error.
-    ^^^^^^^^^^^^" : null;
-  let final self::B? #t14 = b in #t14.{core::Object::==}(null) ?{core::int?} null : let final self::B #t15 = self::Extension|get#barExtension(#t14{self::B}) in self::Extension|get#fooExtension(#t15).{core::num::==}(null) ?{core::int} self::Extension|set#fooExtension(#t15, x) : null;
+    ^^^^^^^^^^^^" in self::Extension|set#fooExtension(#t13, x) : null;
+  let final self::B? #t16 = b in #t16.{core::Object::==}(null) ?{core::int?} null : let final self::B #t17 = self::Extension|get#barExtension(#t16{self::B}) in self::Extension|get#fooExtension(#t17).{core::num::==}(null) ?{core::int} self::Extension|set#fooExtension(#t17, x) : null;
 }
 static method main() → dynamic {}
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 d15a9c9..3bfcc52 100644
--- a/pkg/front_end/testcases/nnbd/issue43278.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue43278.dart.weak.transformed.expect
@@ -19,15 +19,8 @@
 //   b.fooExtension ??= x; // Error.
 //     ^^^^^^^^^^^^
 //
-// pkg/front_end/testcases/nnbd/issue43278.dart:29:5: Error: The getter 'fooExtension' isn't defined for the class 'B?'.
-//  - 'B' is from 'pkg/front_end/testcases/nnbd/issue43278.dart'.
-// Try correcting the name to the name of an existing getter, or defining a getter or field named 'fooExtension'.
-//   t.fooExtension ??= x; // Error.
-//     ^^^^^^^^^^^^
-//
-// pkg/front_end/testcases/nnbd/issue43278.dart:29:5: Error: The setter 'fooExtension' isn't defined for the class 'B?'.
-//  - 'B' is from 'pkg/front_end/testcases/nnbd/issue43278.dart'.
-// Try correcting the name to the name of an existing setter, or defining a setter or field named 'fooExtension'.
+// pkg/front_end/testcases/nnbd/issue43278.dart:29:5: Error: Property 'fooExtension' cannot be accessed on 'T' because it is potentially null.
+// Try accessing using ?. instead.
 //   t.fooExtension ??= x; // Error.
 //     ^^^^^^^^^^^^
 //
@@ -86,15 +79,13 @@
 Try accessing using ?. instead.
   b.fooExtension ??= x; // Error.
     ^^^^^^^^^^^^" in self::Extension|set#fooExtension(#t10, x) : null;
-  let final self::testExtension::T% #t13 = t in invalid-expression "pkg/front_end/testcases/nnbd/issue43278.dart:29:5: Error: The getter 'fooExtension' isn't defined for the class 'B?'.
- - 'B' is from 'pkg/front_end/testcases/nnbd/issue43278.dart'.
-Try correcting the name to the name of an existing getter, or defining a getter or field named 'fooExtension'.
+  let final self::testExtension::T% #t13 = t in (let final Never #t14 = invalid-expression "pkg/front_end/testcases/nnbd/issue43278.dart:29:5: Error: Property 'fooExtension' cannot be accessed on 'T' because it is potentially null.
+Try accessing using ?. instead.
   t.fooExtension ??= x; // Error.
-    ^^^^^^^^^^^^".{core::Object::==}(null) ?{dynamic} invalid-expression "pkg/front_end/testcases/nnbd/issue43278.dart:29:5: Error: The setter 'fooExtension' isn't defined for the class 'B?'.
- - 'B' is from 'pkg/front_end/testcases/nnbd/issue43278.dart'.
-Try correcting the name to the name of an existing setter, or defining a setter or field named 'fooExtension'.
+    ^^^^^^^^^^^^" in self::Extension|get#fooExtension(#t13)).{core::num::==}(null) ?{core::int} let final Never #t15 = invalid-expression "pkg/front_end/testcases/nnbd/issue43278.dart:29:5: Error: Property 'fooExtension' cannot be accessed on 'T' because it is potentially null.
+Try accessing using ?. instead.
   t.fooExtension ??= x; // Error.
-    ^^^^^^^^^^^^" : null;
-  let final self::B? #t14 = b in #t14.{core::Object::==}(null) ?{core::int?} null : let final self::B #t15 = self::Extension|get#barExtension(#t14{self::B}) in self::Extension|get#fooExtension(#t15).{core::num::==}(null) ?{core::int} self::Extension|set#fooExtension(#t15, x) : null;
+    ^^^^^^^^^^^^" in self::Extension|set#fooExtension(#t13, x) : null;
+  let final self::B? #t16 = b in #t16.{core::Object::==}(null) ?{core::int?} null : let final self::B #t17 = self::Extension|get#barExtension(#t16{self::B}) in self::Extension|get#fooExtension(#t17).{core::num::==}(null) ?{core::int} self::Extension|set#fooExtension(#t17, x) : null;
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd_mixed/export_from_opt_out_lib1.dart b/pkg/front_end/testcases/nnbd_mixed/export_from_opt_out_lib1.dart
index 1943b6e..c904869 100644
--- a/pkg/front_end/testcases/nnbd_mixed/export_from_opt_out_lib1.dart
+++ b/pkg/front_end/testcases/nnbd_mixed/export_from_opt_out_lib1.dart
@@ -2,6 +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.5
+// @dart=2.9
 
 class LegacyClass1 {}
diff --git a/pkg/front_end/testcases/nnbd_mixed/export_from_opt_out_lib2.dart b/pkg/front_end/testcases/nnbd_mixed/export_from_opt_out_lib2.dart
index 1723c1f..c68b9f9 100644
--- a/pkg/front_end/testcases/nnbd_mixed/export_from_opt_out_lib2.dart
+++ b/pkg/front_end/testcases/nnbd_mixed/export_from_opt_out_lib2.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.
 
-// @dart=2.5
+// @dart=2.9
 
 class LegacyClass3 {}
 
diff --git a/pkg/front_end/testcases/nnbd_mixed/export_from_opt_out_lib3.dart b/pkg/front_end/testcases/nnbd_mixed/export_from_opt_out_lib3.dart
index 148a845..6dbe951 100644
--- a/pkg/front_end/testcases/nnbd_mixed/export_from_opt_out_lib3.dart
+++ b/pkg/front_end/testcases/nnbd_mixed/export_from_opt_out_lib3.dart
@@ -2,16 +2,14 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart=2.5
+// @dart=2.9
 
 export 'export_from_opt_out_lib5.dart';
 
-class LegacyClass2 {
-}
+class LegacyClass2 {}
 
 legacyMethod1() {}
 
-extension LegacyExtension on String {
-}
+extension LegacyExtension on String {}
 
-typedef LegacyTypedef = void Function();
\ No newline at end of file
+typedef LegacyTypedef = void Function();
diff --git a/pkg/front_end/testcases/nnbd_mixed/export_from_opt_out_lib4.dart b/pkg/front_end/testcases/nnbd_mixed/export_from_opt_out_lib4.dart
index 5a7261a..612326d 100644
--- a/pkg/front_end/testcases/nnbd_mixed/export_from_opt_out_lib4.dart
+++ b/pkg/front_end/testcases/nnbd_mixed/export_from_opt_out_lib4.dart
@@ -2,6 +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.5
+// @dart=2.9
 
 export 'export_from_opt_out_lib5.dart';
diff --git a/pkg/front_end/testcases/none/equals.dart.strong.expect b/pkg/front_end/testcases/none/equals.dart.strong.expect
index 905a90a..3c8e61d 100644
--- a/pkg/front_end/testcases/none/equals.dart.strong.expect
+++ b/pkg/front_end/testcases/none/equals.dart.strong.expect
@@ -129,347 +129,347 @@
 static method test<T1 extends core::Function = core::Function, T2 extends (core::int) → core::int = (core::int) → core::int>(core::Object o, core::Object nonNullableObject, core::Object? nullableObject, self::Class<core::String> nonNullableClass, self::Class<core::String>? nullableClass, dynamic dyn, Never never, Never? nullableNever, Null nullTypedValue, core::Function nonNullableFunction, core::Function? nullableFunction, (core::int) → core::int nonNullableFunctionType, (core::int) →? core::int nullableFunctionType, self::test::T1 nonNullableTypeVariable1, self::test::T1? nullableTypeVariable1, self::test::T2 nonNullableTypeVariable2, self::test::T2? nullableTypeVariable2) → dynamic {
   core::print("EqualsNull (literal null)");
   null == null;
-  null != null;
+  !(null == null);
   nonNullableObject == null;
-  nonNullableObject != null;
+  !(nonNullableObject == null);
   nonNullableObject == null;
-  nonNullableObject != null;
+  !(nonNullableObject == null);
   nullableObject == null;
-  nullableObject != null;
+  !(nullableObject == null);
   nullableObject == null;
-  nullableObject != null;
+  !(nullableObject == null);
   nullableClass == null;
-  nullableClass != null;
+  !(nullableClass == null);
   nullableClass == null;
-  nullableClass != null;
+  !(nullableClass == null);
   nonNullableClass == null;
-  nonNullableClass != null;
+  !(nonNullableClass == null);
   nonNullableClass == null;
-  nonNullableClass != null;
+  !(nonNullableClass == null);
   dyn == null;
-  dyn != null;
+  !(dyn == null);
   dyn == null;
-  dyn != null;
+  !(dyn == null);
   never == null;
-  never != null;
+  !(never == null);
   never == null;
-  never != null;
+  !(never == null);
   nullableNever == null;
-  nullableNever != null;
+  !(nullableNever == null);
   nullableNever == null;
-  nullableNever != null;
+  !(nullableNever == null);
   nullTypedValue == null;
-  nullTypedValue != null;
+  !(nullTypedValue == null);
   nullTypedValue == null;
-  nullTypedValue != null;
+  !(nullTypedValue == null);
   nonNullableFunction == null;
-  nonNullableFunction != null;
+  !(nonNullableFunction == null);
   nonNullableFunction == null;
-  nonNullableFunction != null;
+  !(nonNullableFunction == null);
   nullableFunction == null;
-  nullableFunction != null;
+  !(nullableFunction == null);
   nullableFunction == null;
-  nullableFunction != null;
+  !(nullableFunction == null);
   nonNullableFunctionType == null;
-  nonNullableFunctionType != null;
+  !(nonNullableFunctionType == null);
   nonNullableFunctionType == null;
-  nonNullableFunctionType != null;
+  !(nonNullableFunctionType == null);
   nullableFunctionType == null;
-  nullableFunctionType != null;
+  !(nullableFunctionType == null);
   nullableFunctionType == null;
-  nullableFunctionType != null;
+  !(nullableFunctionType == null);
   nonNullableTypeVariable1 == null;
-  nonNullableTypeVariable1 != null;
+  !(nonNullableTypeVariable1 == null);
   nonNullableTypeVariable1 == null;
-  nonNullableTypeVariable1 != null;
+  !(nonNullableTypeVariable1 == null);
   nullableTypeVariable1 == null;
-  nullableTypeVariable1 != null;
+  !(nullableTypeVariable1 == null);
   nullableTypeVariable1 == null;
-  nullableTypeVariable1 != null;
+  !(nullableTypeVariable1 == null);
   nonNullableTypeVariable2 == null;
-  nonNullableTypeVariable2 != null;
+  !(nonNullableTypeVariable2 == null);
   nonNullableTypeVariable2 == null;
-  nonNullableTypeVariable2 != null;
+  !(nonNullableTypeVariable2 == null);
   nullableTypeVariable2 == null;
-  nullableTypeVariable2 != null;
+  !(nullableTypeVariable2 == null);
   nullableTypeVariable2 == null;
-  nullableTypeVariable2 != null;
+  !(nullableTypeVariable2 == null);
   (let final Never #t1 = invalid-expression "pkg/front_end/testcases/none/equals.dart:115:26: Error: Too few positional arguments: 1 required, 0 given.
   nonNullableClass.method() == null;
                          ^" in nonNullableClass.{self::Class::method}{<inapplicable>}.(){() → invalid-type}) == null;
-  (let final Never #t2 = invalid-expression "pkg/front_end/testcases/none/equals.dart:116:26: Error: Too few positional arguments: 1 required, 0 given.
+  !((let final Never #t2 = invalid-expression "pkg/front_end/testcases/none/equals.dart:116:26: Error: Too few positional arguments: 1 required, 0 given.
   nonNullableClass.method() != null;
-                         ^" in nonNullableClass.{self::Class::method}{<inapplicable>}.(){() → invalid-type}) != null;
+                         ^" in nonNullableClass.{self::Class::method}{<inapplicable>}.(){() → invalid-type}) == null);
   (let final Never #t3 = invalid-expression "pkg/front_end/testcases/none/equals.dart:117:34: Error: Too few positional arguments: 1 required, 0 given.
   null == nonNullableClass.method();
                                  ^" in nonNullableClass.{self::Class::method}{<inapplicable>}.(){() → invalid-type}) == null;
-  (let final Never #t4 = invalid-expression "pkg/front_end/testcases/none/equals.dart:118:34: Error: Too few positional arguments: 1 required, 0 given.
+  !((let final Never #t4 = invalid-expression "pkg/front_end/testcases/none/equals.dart:118:34: Error: Too few positional arguments: 1 required, 0 given.
   null != nonNullableClass.method();
-                                 ^" in nonNullableClass.{self::Class::method}{<inapplicable>}.(){() → invalid-type}) != null;
+                                 ^" in nonNullableClass.{self::Class::method}{<inapplicable>}.(){() → invalid-type}) == null);
   core::print("EqualsNull (constant null)");
   (#C1) == null;
-  (#C1) != null;
+  !((#C1) == null);
   nonNullableObject == null;
-  nonNullableObject != null;
+  !(nonNullableObject == null);
   nonNullableObject == null;
-  nonNullableObject != null;
+  !(nonNullableObject == null);
   nullableObject == null;
-  nullableObject != null;
+  !(nullableObject == null);
   nullableObject == null;
-  nullableObject != null;
+  !(nullableObject == null);
   nonNullableClass =={self::Class::==}{(self::Class<core::String>) → core::bool} (let final Never #t5 = invalid-expression "pkg/front_end/testcases/none/equals.dart:134:23: Error: The argument type 'Object?' can't be assigned to the parameter type 'Class<String>?'.
  - 'Object' is from 'dart:core'.
  - 'Class' is from 'pkg/front_end/testcases/none/equals.dart'.
   nonNullableClass == nullValue;
                       ^" in (#C1) as{TypeError,ForNonNullableByDefault} self::Class<core::String>?);
-  nonNullableClass !={self::Class::==}{(self::Class<core::String>) → core::bool} (let final Never #t6 = invalid-expression "pkg/front_end/testcases/none/equals.dart:135:23: Error: The argument type 'Object?' can't be assigned to the parameter type 'Class<String>?'.
+  !(nonNullableClass =={self::Class::==}{(self::Class<core::String>) → core::bool} (let final Never #t6 = invalid-expression "pkg/front_end/testcases/none/equals.dart:135:23: Error: The argument type 'Object?' can't be assigned to the parameter type 'Class<String>?'.
  - 'Object' is from 'dart:core'.
  - 'Class' is from 'pkg/front_end/testcases/none/equals.dart'.
   nonNullableClass != nullValue;
-                      ^" in (#C1) as{TypeError,ForNonNullableByDefault} self::Class<core::String>?);
+                      ^" in (#C1) as{TypeError,ForNonNullableByDefault} self::Class<core::String>?));
   nonNullableClass == null;
-  nonNullableClass != null;
+  !(nonNullableClass == null);
   nullableClass =={self::Class::==}{(self::Class<core::String>) → core::bool} (let final Never #t7 = invalid-expression "pkg/front_end/testcases/none/equals.dart:139:20: Error: The argument type 'Object?' can't be assigned to the parameter type 'Class<String>?'.
  - 'Object' is from 'dart:core'.
  - 'Class' is from 'pkg/front_end/testcases/none/equals.dart'.
   nullableClass == nullValue;
                    ^" in (#C1) as{TypeError,ForNonNullableByDefault} self::Class<core::String>?);
-  nullableClass !={self::Class::==}{(self::Class<core::String>) → core::bool} (let final Never #t8 = invalid-expression "pkg/front_end/testcases/none/equals.dart:140:20: Error: The argument type 'Object?' can't be assigned to the parameter type 'Class<String>?'.
+  !(nullableClass =={self::Class::==}{(self::Class<core::String>) → core::bool} (let final Never #t8 = invalid-expression "pkg/front_end/testcases/none/equals.dart:140:20: Error: The argument type 'Object?' can't be assigned to the parameter type 'Class<String>?'.
  - 'Object' is from 'dart:core'.
  - 'Class' is from 'pkg/front_end/testcases/none/equals.dart'.
   nullableClass != nullValue;
-                   ^" in (#C1) as{TypeError,ForNonNullableByDefault} self::Class<core::String>?);
+                   ^" in (#C1) as{TypeError,ForNonNullableByDefault} self::Class<core::String>?));
   nullableClass == null;
-  nullableClass != null;
+  !(nullableClass == null);
   dyn == null;
-  dyn != null;
+  !(dyn == null);
   dyn == null;
-  dyn != null;
+  !(dyn == null);
   never == null;
-  never != null;
+  !(never == null);
   never == null;
-  never != null;
+  !(never == null);
   nullableNever == null;
-  nullableNever != null;
+  !(nullableNever == null);
   nullableNever == null;
-  nullableNever != null;
+  !(nullableNever == null);
   nullTypedValue == null;
-  nullTypedValue != null;
+  !(nullTypedValue == null);
   nullTypedValue == null;
-  nullTypedValue != null;
+  !(nullTypedValue == null);
   nonNullableFunction == null;
-  nonNullableFunction != null;
+  !(nonNullableFunction == null);
   nonNullableFunction == null;
-  nonNullableFunction != null;
+  !(nonNullableFunction == null);
   nullableFunction == null;
-  nullableFunction != null;
+  !(nullableFunction == null);
   nullableFunction == null;
-  nullableFunction != null;
+  !(nullableFunction == null);
   nonNullableFunctionType == null;
-  nonNullableFunctionType != null;
+  !(nonNullableFunctionType == null);
   nonNullableFunctionType == null;
-  nonNullableFunctionType != null;
+  !(nonNullableFunctionType == null);
   nullableFunctionType == null;
-  nullableFunctionType != null;
+  !(nullableFunctionType == null);
   nullableFunctionType == null;
-  nullableFunctionType != null;
+  !(nullableFunctionType == null);
   nonNullableTypeVariable1 == null;
-  nonNullableTypeVariable1 != null;
+  !(nonNullableTypeVariable1 == null);
   nonNullableTypeVariable1 == null;
-  nonNullableTypeVariable1 != null;
+  !(nonNullableTypeVariable1 == null);
   nullableTypeVariable1 == null;
-  nullableTypeVariable1 != null;
+  !(nullableTypeVariable1 == null);
   nullableTypeVariable1 == null;
-  nullableTypeVariable1 != null;
+  !(nullableTypeVariable1 == null);
   nonNullableTypeVariable2 == null;
-  nonNullableTypeVariable2 != null;
+  !(nonNullableTypeVariable2 == null);
   nonNullableTypeVariable2 == null;
-  nonNullableTypeVariable2 != null;
+  !(nonNullableTypeVariable2 == null);
   nullableTypeVariable2 == null;
-  nullableTypeVariable2 != null;
+  !(nullableTypeVariable2 == null);
   nullableTypeVariable2 == null;
-  nullableTypeVariable2 != null;
+  !(nullableTypeVariable2 == null);
   (let final Never #t9 = invalid-expression "pkg/front_end/testcases/none/equals.dart:204:26: Error: Too few positional arguments: 1 required, 0 given.
   nonNullableClass.method() == nullValue;
                          ^" in nonNullableClass.{self::Class::method}{<inapplicable>}.(){() → invalid-type}) == null;
-  (let final Never #t10 = invalid-expression "pkg/front_end/testcases/none/equals.dart:205:26: Error: Too few positional arguments: 1 required, 0 given.
+  !((let final Never #t10 = invalid-expression "pkg/front_end/testcases/none/equals.dart:205:26: Error: Too few positional arguments: 1 required, 0 given.
   nonNullableClass.method() != nullValue;
-                         ^" in nonNullableClass.{self::Class::method}{<inapplicable>}.(){() → invalid-type}) != null;
+                         ^" in nonNullableClass.{self::Class::method}{<inapplicable>}.(){() → invalid-type}) == null);
   (let final Never #t11 = invalid-expression "pkg/front_end/testcases/none/equals.dart:206:39: Error: Too few positional arguments: 1 required, 0 given.
   nullValue == nonNullableClass.method();
                                       ^" in nonNullableClass.{self::Class::method}{<inapplicable>}.(){() → invalid-type}) == null;
-  (let final Never #t12 = invalid-expression "pkg/front_end/testcases/none/equals.dart:207:39: Error: Too few positional arguments: 1 required, 0 given.
+  !((let final Never #t12 = invalid-expression "pkg/front_end/testcases/none/equals.dart:207:39: Error: Too few positional arguments: 1 required, 0 given.
   nullValue != nonNullableClass.method();
-                                      ^" in nonNullableClass.{self::Class::method}{<inapplicable>}.(){() → invalid-type}) != null;
+                                      ^" in nonNullableClass.{self::Class::method}{<inapplicable>}.(){() → invalid-type}) == null);
   core::print("EqualsCall");
   nonNullableObject =={core::Object::==}{(core::Object) → core::bool} nullTypedValue;
-  nonNullableObject !={core::Object::==}{(core::Object) → core::bool} nullTypedValue;
+  !(nonNullableObject =={core::Object::==}{(core::Object) → core::bool} nullTypedValue);
   nullTypedValue =={core::Object::==}{(core::Object) → core::bool} nonNullableObject;
-  nullTypedValue !={core::Object::==}{(core::Object) → core::bool} nonNullableObject;
+  !(nullTypedValue =={core::Object::==}{(core::Object) → core::bool} nonNullableObject);
   nonNullableObject =={core::Object::==}{(core::Object) → core::bool} o;
-  nonNullableObject !={core::Object::==}{(core::Object) → core::bool} o;
+  !(nonNullableObject =={core::Object::==}{(core::Object) → core::bool} o);
   o =={core::Object::==}{(core::Object) → core::bool} nonNullableObject;
-  o !={core::Object::==}{(core::Object) → core::bool} nonNullableObject;
+  !(o =={core::Object::==}{(core::Object) → core::bool} nonNullableObject);
   nullableObject =={core::Object::==}{(core::Object) → core::bool} nullTypedValue;
-  nullableObject !={core::Object::==}{(core::Object) → core::bool} nullTypedValue;
+  !(nullableObject =={core::Object::==}{(core::Object) → core::bool} nullTypedValue);
   nullTypedValue =={core::Object::==}{(core::Object) → core::bool} nullableObject;
-  nullTypedValue !={core::Object::==}{(core::Object) → core::bool} nullableObject;
+  !(nullTypedValue =={core::Object::==}{(core::Object) → core::bool} nullableObject);
   nullableObject =={core::Object::==}{(core::Object) → core::bool} o;
-  nullableObject !={core::Object::==}{(core::Object) → core::bool} o;
+  !(nullableObject =={core::Object::==}{(core::Object) → core::bool} o);
   o =={core::Object::==}{(core::Object) → core::bool} nullableObject;
-  o !={core::Object::==}{(core::Object) → core::bool} nullableObject;
+  !(o =={core::Object::==}{(core::Object) → core::bool} nullableObject);
   nonNullableClass =={self::Class::==}{(self::Class<core::String>) → core::bool} nullTypedValue;
-  nonNullableClass !={self::Class::==}{(self::Class<core::String>) → core::bool} nullTypedValue;
+  !(nonNullableClass =={self::Class::==}{(self::Class<core::String>) → core::bool} nullTypedValue);
   nullTypedValue =={core::Object::==}{(core::Object) → core::bool} nonNullableClass;
-  nullTypedValue !={core::Object::==}{(core::Object) → core::bool} nonNullableClass;
+  !(nullTypedValue =={core::Object::==}{(core::Object) → core::bool} nonNullableClass);
   nonNullableClass =={self::Class::==}{(self::Class<core::String>) → core::bool} (let final Never #t13 = invalid-expression "pkg/front_end/testcases/none/equals.dart:233:23: Error: The argument type 'Object' can't be assigned to the parameter type 'Class<String>?'.
  - 'Object' is from 'dart:core'.
  - 'Class' is from 'pkg/front_end/testcases/none/equals.dart'.
   nonNullableClass == o;
                       ^" in o as{TypeError,ForNonNullableByDefault} self::Class<core::String>?);
-  nonNullableClass !={self::Class::==}{(self::Class<core::String>) → core::bool} (let final Never #t14 = invalid-expression "pkg/front_end/testcases/none/equals.dart:234:23: Error: The argument type 'Object' can't be assigned to the parameter type 'Class<String>?'.
+  !(nonNullableClass =={self::Class::==}{(self::Class<core::String>) → core::bool} (let final Never #t14 = invalid-expression "pkg/front_end/testcases/none/equals.dart:234:23: Error: The argument type 'Object' can't be assigned to the parameter type 'Class<String>?'.
  - 'Object' is from 'dart:core'.
  - 'Class' is from 'pkg/front_end/testcases/none/equals.dart'.
   nonNullableClass != o;
-                      ^" in o as{TypeError,ForNonNullableByDefault} self::Class<core::String>?);
+                      ^" in o as{TypeError,ForNonNullableByDefault} self::Class<core::String>?));
   o =={core::Object::==}{(core::Object) → core::bool} nonNullableClass;
-  o !={core::Object::==}{(core::Object) → core::bool} nonNullableClass;
+  !(o =={core::Object::==}{(core::Object) → core::bool} nonNullableClass);
   nullableClass =={self::Class::==}{(self::Class<core::String>) → core::bool} nullTypedValue;
-  nullableClass !={self::Class::==}{(self::Class<core::String>) → core::bool} nullTypedValue;
+  !(nullableClass =={self::Class::==}{(self::Class<core::String>) → core::bool} nullTypedValue);
   nullTypedValue =={core::Object::==}{(core::Object) → core::bool} nullableClass;
-  nullTypedValue !={core::Object::==}{(core::Object) → core::bool} nullableClass;
+  !(nullTypedValue =={core::Object::==}{(core::Object) → core::bool} nullableClass);
   nullableClass =={self::Class::==}{(self::Class<core::String>) → core::bool} (let final Never #t15 = invalid-expression "pkg/front_end/testcases/none/equals.dart:242:20: Error: The argument type 'Object' can't be assigned to the parameter type 'Class<String>?'.
  - 'Object' is from 'dart:core'.
  - 'Class' is from 'pkg/front_end/testcases/none/equals.dart'.
   nullableClass == o;
                    ^" in o as{TypeError,ForNonNullableByDefault} self::Class<core::String>?);
-  nullableClass !={self::Class::==}{(self::Class<core::String>) → core::bool} (let final Never #t16 = invalid-expression "pkg/front_end/testcases/none/equals.dart:243:20: Error: The argument type 'Object' can't be assigned to the parameter type 'Class<String>?'.
+  !(nullableClass =={self::Class::==}{(self::Class<core::String>) → core::bool} (let final Never #t16 = invalid-expression "pkg/front_end/testcases/none/equals.dart:243:20: Error: The argument type 'Object' can't be assigned to the parameter type 'Class<String>?'.
  - 'Object' is from 'dart:core'.
  - 'Class' is from 'pkg/front_end/testcases/none/equals.dart'.
   nullableClass != o;
-                   ^" in o as{TypeError,ForNonNullableByDefault} self::Class<core::String>?);
+                   ^" in o as{TypeError,ForNonNullableByDefault} self::Class<core::String>?));
   o =={core::Object::==}{(core::Object) → core::bool} nullableClass;
-  o !={core::Object::==}{(core::Object) → core::bool} nullableClass;
+  !(o =={core::Object::==}{(core::Object) → core::bool} nullableClass);
   dyn =={core::Object::==}{(core::Object) → core::bool} nullTypedValue;
-  dyn !={core::Object::==}{(core::Object) → core::bool} nullTypedValue;
+  !(dyn =={core::Object::==}{(core::Object) → core::bool} nullTypedValue);
   nullTypedValue =={core::Object::==}{(core::Object) → core::bool} dyn;
-  nullTypedValue !={core::Object::==}{(core::Object) → core::bool} dyn;
+  !(nullTypedValue =={core::Object::==}{(core::Object) → core::bool} dyn);
   dyn =={core::Object::==}{(core::Object) → core::bool} o;
-  dyn !={core::Object::==}{(core::Object) → core::bool} o;
+  !(dyn =={core::Object::==}{(core::Object) → core::bool} o);
   o =={core::Object::==}{(core::Object) → core::bool} dyn;
-  o !={core::Object::==}{(core::Object) → core::bool} dyn;
+  !(o =={core::Object::==}{(core::Object) → core::bool} dyn);
   never =={core::Object::==}{(dynamic) → Never} nullTypedValue;
-  never !={core::Object::==}{(dynamic) → Never} nullTypedValue;
+  !(never =={core::Object::==}{(dynamic) → Never} nullTypedValue);
   nullTypedValue =={core::Object::==}{(core::Object) → core::bool} never;
-  nullTypedValue !={core::Object::==}{(core::Object) → core::bool} never;
+  !(nullTypedValue =={core::Object::==}{(core::Object) → core::bool} never);
   never =={core::Object::==}{(dynamic) → Never} o;
-  never !={core::Object::==}{(dynamic) → Never} o;
+  !(never =={core::Object::==}{(dynamic) → Never} o);
   o =={core::Object::==}{(core::Object) → core::bool} never;
-  o !={core::Object::==}{(core::Object) → core::bool} never;
+  !(o =={core::Object::==}{(core::Object) → core::bool} never);
   nullableNever =={core::Object::==}{(core::Object) → core::bool} nullTypedValue;
-  nullableNever !={core::Object::==}{(core::Object) → core::bool} nullTypedValue;
+  !(nullableNever =={core::Object::==}{(core::Object) → core::bool} nullTypedValue);
   nullTypedValue =={core::Object::==}{(core::Object) → core::bool} nullableNever;
-  nullTypedValue !={core::Object::==}{(core::Object) → core::bool} nullableNever;
+  !(nullTypedValue =={core::Object::==}{(core::Object) → core::bool} nullableNever);
   nullableNever =={core::Object::==}{(core::Object) → core::bool} o;
-  nullableNever !={core::Object::==}{(core::Object) → core::bool} o;
+  !(nullableNever =={core::Object::==}{(core::Object) → core::bool} o);
   o =={core::Object::==}{(core::Object) → core::bool} nullableNever;
-  o !={core::Object::==}{(core::Object) → core::bool} nullableNever;
+  !(o =={core::Object::==}{(core::Object) → core::bool} nullableNever);
   nullTypedValue =={core::Object::==}{(core::Object) → core::bool} nullTypedValue;
-  nullTypedValue !={core::Object::==}{(core::Object) → core::bool} nullTypedValue;
+  !(nullTypedValue =={core::Object::==}{(core::Object) → core::bool} nullTypedValue);
   nullTypedValue =={core::Object::==}{(core::Object) → core::bool} nullTypedValue;
-  nullTypedValue !={core::Object::==}{(core::Object) → core::bool} nullTypedValue;
+  !(nullTypedValue =={core::Object::==}{(core::Object) → core::bool} nullTypedValue);
   nullTypedValue =={core::Object::==}{(core::Object) → core::bool} o;
-  nullTypedValue !={core::Object::==}{(core::Object) → core::bool} o;
+  !(nullTypedValue =={core::Object::==}{(core::Object) → core::bool} o);
   o =={core::Object::==}{(core::Object) → core::bool} nullTypedValue;
-  o !={core::Object::==}{(core::Object) → core::bool} nullTypedValue;
+  !(o =={core::Object::==}{(core::Object) → core::bool} nullTypedValue);
   nonNullableFunction =={core::Function::==}{(core::Object) → core::bool} nullTypedValue;
-  nonNullableFunction !={core::Function::==}{(core::Object) → core::bool} nullTypedValue;
+  !(nonNullableFunction =={core::Function::==}{(core::Object) → core::bool} nullTypedValue);
   nullTypedValue =={core::Object::==}{(core::Object) → core::bool} nonNullableFunction;
-  nullTypedValue !={core::Object::==}{(core::Object) → core::bool} nonNullableFunction;
+  !(nullTypedValue =={core::Object::==}{(core::Object) → core::bool} nonNullableFunction);
   nonNullableFunction =={core::Function::==}{(core::Object) → core::bool} o;
-  nonNullableFunction !={core::Function::==}{(core::Object) → core::bool} o;
+  !(nonNullableFunction =={core::Function::==}{(core::Object) → core::bool} o);
   o =={core::Object::==}{(core::Object) → core::bool} nonNullableFunction;
-  o !={core::Object::==}{(core::Object) → core::bool} nonNullableFunction;
+  !(o =={core::Object::==}{(core::Object) → core::bool} nonNullableFunction);
   nullableFunction =={core::Function::==}{(core::Object) → core::bool} nullTypedValue;
-  nullableFunction !={core::Function::==}{(core::Object) → core::bool} nullTypedValue;
+  !(nullableFunction =={core::Function::==}{(core::Object) → core::bool} nullTypedValue);
   nullTypedValue =={core::Object::==}{(core::Object) → core::bool} nullableFunction;
-  nullTypedValue !={core::Object::==}{(core::Object) → core::bool} nullableFunction;
+  !(nullTypedValue =={core::Object::==}{(core::Object) → core::bool} nullableFunction);
   nullableFunction =={core::Function::==}{(core::Object) → core::bool} o;
-  nullableFunction !={core::Function::==}{(core::Object) → core::bool} o;
+  !(nullableFunction =={core::Function::==}{(core::Object) → core::bool} o);
   o =={core::Object::==}{(core::Object) → core::bool} nullableFunction;
-  o !={core::Object::==}{(core::Object) → core::bool} nullableFunction;
+  !(o =={core::Object::==}{(core::Object) → core::bool} nullableFunction);
   nonNullableFunctionType =={core::Object::==}{(core::Object) → core::bool} nullTypedValue;
-  nonNullableFunctionType !={core::Object::==}{(core::Object) → core::bool} nullTypedValue;
+  !(nonNullableFunctionType =={core::Object::==}{(core::Object) → core::bool} nullTypedValue);
   nullTypedValue =={core::Object::==}{(core::Object) → core::bool} nonNullableFunctionType;
-  nullTypedValue !={core::Object::==}{(core::Object) → core::bool} nonNullableFunctionType;
+  !(nullTypedValue =={core::Object::==}{(core::Object) → core::bool} nonNullableFunctionType);
   nonNullableFunctionType =={core::Object::==}{(core::Object) → core::bool} o;
-  nonNullableFunctionType !={core::Object::==}{(core::Object) → core::bool} o;
+  !(nonNullableFunctionType =={core::Object::==}{(core::Object) → core::bool} o);
   o =={core::Object::==}{(core::Object) → core::bool} nonNullableFunctionType;
-  o !={core::Object::==}{(core::Object) → core::bool} nonNullableFunctionType;
+  !(o =={core::Object::==}{(core::Object) → core::bool} nonNullableFunctionType);
   nullableFunctionType =={core::Object::==}{(core::Object) → core::bool} nullTypedValue;
-  nullableFunctionType !={core::Object::==}{(core::Object) → core::bool} nullTypedValue;
+  !(nullableFunctionType =={core::Object::==}{(core::Object) → core::bool} nullTypedValue);
   nullTypedValue =={core::Object::==}{(core::Object) → core::bool} nullableFunctionType;
-  nullTypedValue !={core::Object::==}{(core::Object) → core::bool} nullableFunctionType;
+  !(nullTypedValue =={core::Object::==}{(core::Object) → core::bool} nullableFunctionType);
   nullableFunctionType =={core::Object::==}{(core::Object) → core::bool} o;
-  nullableFunctionType !={core::Object::==}{(core::Object) → core::bool} o;
+  !(nullableFunctionType =={core::Object::==}{(core::Object) → core::bool} o);
   o =={core::Object::==}{(core::Object) → core::bool} nullableFunctionType;
-  o !={core::Object::==}{(core::Object) → core::bool} nullableFunctionType;
+  !(o =={core::Object::==}{(core::Object) → core::bool} nullableFunctionType);
   nonNullableTypeVariable1 =={core::Function::==}{(core::Object) → core::bool} nullTypedValue;
-  nonNullableTypeVariable1 !={core::Function::==}{(core::Object) → core::bool} nullTypedValue;
+  !(nonNullableTypeVariable1 =={core::Function::==}{(core::Object) → core::bool} nullTypedValue);
   nullTypedValue =={core::Object::==}{(core::Object) → core::bool} nonNullableTypeVariable1;
-  nullTypedValue !={core::Object::==}{(core::Object) → core::bool} nonNullableTypeVariable1;
+  !(nullTypedValue =={core::Object::==}{(core::Object) → core::bool} nonNullableTypeVariable1);
   nonNullableTypeVariable1 =={core::Function::==}{(core::Object) → core::bool} o;
-  nonNullableTypeVariable1 !={core::Function::==}{(core::Object) → core::bool} o;
+  !(nonNullableTypeVariable1 =={core::Function::==}{(core::Object) → core::bool} o);
   o =={core::Object::==}{(core::Object) → core::bool} nonNullableTypeVariable1;
-  o !={core::Object::==}{(core::Object) → core::bool} nonNullableTypeVariable1;
+  !(o =={core::Object::==}{(core::Object) → core::bool} nonNullableTypeVariable1);
   nullableTypeVariable1 =={core::Function::==}{(core::Object) → core::bool} nullTypedValue;
-  nullableTypeVariable1 !={core::Function::==}{(core::Object) → core::bool} nullTypedValue;
+  !(nullableTypeVariable1 =={core::Function::==}{(core::Object) → core::bool} nullTypedValue);
   nullTypedValue =={core::Object::==}{(core::Object) → core::bool} nullableTypeVariable1;
-  nullTypedValue !={core::Object::==}{(core::Object) → core::bool} nullableTypeVariable1;
+  !(nullTypedValue =={core::Object::==}{(core::Object) → core::bool} nullableTypeVariable1);
   nullableTypeVariable1 =={core::Function::==}{(core::Object) → core::bool} o;
-  nullableTypeVariable1 !={core::Function::==}{(core::Object) → core::bool} o;
+  !(nullableTypeVariable1 =={core::Function::==}{(core::Object) → core::bool} o);
   o =={core::Object::==}{(core::Object) → core::bool} nullableTypeVariable1;
-  o !={core::Object::==}{(core::Object) → core::bool} nullableTypeVariable1;
+  !(o =={core::Object::==}{(core::Object) → core::bool} nullableTypeVariable1);
   nonNullableTypeVariable2 =={core::Object::==}{(core::Object) → core::bool} nullTypedValue;
-  nonNullableTypeVariable2 !={core::Object::==}{(core::Object) → core::bool} nullTypedValue;
+  !(nonNullableTypeVariable2 =={core::Object::==}{(core::Object) → core::bool} nullTypedValue);
   nullTypedValue =={core::Object::==}{(core::Object) → core::bool} nonNullableTypeVariable2;
-  nullTypedValue !={core::Object::==}{(core::Object) → core::bool} nonNullableTypeVariable2;
+  !(nullTypedValue =={core::Object::==}{(core::Object) → core::bool} nonNullableTypeVariable2);
   nonNullableTypeVariable2 =={core::Object::==}{(core::Object) → core::bool} o;
-  nonNullableTypeVariable2 !={core::Object::==}{(core::Object) → core::bool} o;
+  !(nonNullableTypeVariable2 =={core::Object::==}{(core::Object) → core::bool} o);
   o =={core::Object::==}{(core::Object) → core::bool} nonNullableTypeVariable2;
-  o !={core::Object::==}{(core::Object) → core::bool} nonNullableTypeVariable2;
+  !(o =={core::Object::==}{(core::Object) → core::bool} nonNullableTypeVariable2);
   nullableTypeVariable2 =={core::Object::==}{(core::Object) → core::bool} nullTypedValue;
-  nullableTypeVariable2 !={core::Object::==}{(core::Object) → core::bool} nullTypedValue;
+  !(nullableTypeVariable2 =={core::Object::==}{(core::Object) → core::bool} nullTypedValue);
   nullTypedValue =={core::Object::==}{(core::Object) → core::bool} nullableTypeVariable2;
-  nullTypedValue !={core::Object::==}{(core::Object) → core::bool} nullableTypeVariable2;
+  !(nullTypedValue =={core::Object::==}{(core::Object) → core::bool} nullableTypeVariable2);
   nullableTypeVariable2 =={core::Object::==}{(core::Object) → core::bool} o;
-  nullableTypeVariable2 !={core::Object::==}{(core::Object) → core::bool} o;
+  !(nullableTypeVariable2 =={core::Object::==}{(core::Object) → core::bool} o);
   o =={core::Object::==}{(core::Object) → core::bool} nullableTypeVariable2;
-  o !={core::Object::==}{(core::Object) → core::bool} nullableTypeVariable2;
+  !(o =={core::Object::==}{(core::Object) → core::bool} nullableTypeVariable2);
   (let final Never #t17 = invalid-expression "pkg/front_end/testcases/none/equals.dart:355:26: Error: Too few positional arguments: 1 required, 0 given.
   nonNullableClass.method() == nullTypedValue;
                          ^" in nonNullableClass.{self::Class::method}{<inapplicable>}.(){() → invalid-type}) =={core::Object::==}{(core::Object) → core::bool} nullTypedValue;
-  (let final Never #t18 = invalid-expression "pkg/front_end/testcases/none/equals.dart:356:26: Error: Too few positional arguments: 1 required, 0 given.
+  !((let final Never #t18 = invalid-expression "pkg/front_end/testcases/none/equals.dart:356:26: Error: Too few positional arguments: 1 required, 0 given.
   nonNullableClass.method() != nullTypedValue;
-                         ^" in nonNullableClass.{self::Class::method}{<inapplicable>}.(){() → invalid-type}) !={core::Object::==}{(core::Object) → core::bool} nullTypedValue;
+                         ^" in nonNullableClass.{self::Class::method}{<inapplicable>}.(){() → invalid-type}) =={core::Object::==}{(core::Object) → core::bool} nullTypedValue);
   nullTypedValue =={core::Object::==}{(core::Object) → core::bool} (let final Never #t19 = invalid-expression "pkg/front_end/testcases/none/equals.dart:357:44: Error: Too few positional arguments: 1 required, 0 given.
   nullTypedValue == nonNullableClass.method();
                                            ^" in nonNullableClass.{self::Class::method}{<inapplicable>}.(){() → invalid-type});
-  nullTypedValue !={core::Object::==}{(core::Object) → core::bool} (let final Never #t20 = invalid-expression "pkg/front_end/testcases/none/equals.dart:358:44: Error: Too few positional arguments: 1 required, 0 given.
+  !(nullTypedValue =={core::Object::==}{(core::Object) → core::bool} (let final Never #t20 = invalid-expression "pkg/front_end/testcases/none/equals.dart:358:44: Error: Too few positional arguments: 1 required, 0 given.
   nullTypedValue != nonNullableClass.method();
-                                           ^" in nonNullableClass.{self::Class::method}{<inapplicable>}.(){() → invalid-type});
+                                           ^" in nonNullableClass.{self::Class::method}{<inapplicable>}.(){() → invalid-type}));
   (let final Never #t21 = invalid-expression "pkg/front_end/testcases/none/equals.dart:359:26: Error: Too few positional arguments: 1 required, 0 given.
   nonNullableClass.method() == o;
                          ^" in nonNullableClass.{self::Class::method}{<inapplicable>}.(){() → invalid-type}) =={core::Object::==}{(core::Object) → core::bool} o;
-  (let final Never #t22 = invalid-expression "pkg/front_end/testcases/none/equals.dart:360:26: Error: Too few positional arguments: 1 required, 0 given.
+  !((let final Never #t22 = invalid-expression "pkg/front_end/testcases/none/equals.dart:360:26: Error: Too few positional arguments: 1 required, 0 given.
   nonNullableClass.method() != o;
-                         ^" in nonNullableClass.{self::Class::method}{<inapplicable>}.(){() → invalid-type}) !={core::Object::==}{(core::Object) → core::bool} o;
+                         ^" in nonNullableClass.{self::Class::method}{<inapplicable>}.(){() → invalid-type}) =={core::Object::==}{(core::Object) → core::bool} o);
   o =={core::Object::==}{(core::Object) → core::bool} (let final Never #t23 = invalid-expression "pkg/front_end/testcases/none/equals.dart:361:31: Error: Too few positional arguments: 1 required, 0 given.
   o == nonNullableClass.method();
                               ^" in nonNullableClass.{self::Class::method}{<inapplicable>}.(){() → invalid-type});
-  o !={core::Object::==}{(core::Object) → core::bool} (let final Never #t24 = invalid-expression "pkg/front_end/testcases/none/equals.dart:362:31: Error: Too few positional arguments: 1 required, 0 given.
+  !(o =={core::Object::==}{(core::Object) → core::bool} (let final Never #t24 = invalid-expression "pkg/front_end/testcases/none/equals.dart:362:31: Error: Too few positional arguments: 1 required, 0 given.
   o != nonNullableClass.method();
-                              ^" in nonNullableClass.{self::Class::method}{<inapplicable>}.(){() → invalid-type});
+                              ^" in nonNullableClass.{self::Class::method}{<inapplicable>}.(){() → invalid-type}));
 }
 static method nullEqualsIndexGet(core::Map<core::int, core::String> map) → dynamic {
   map.{core::Map::[]}(0){(core::Object?) → core::String?} == null;
diff --git a/pkg/front_end/testcases/none/equals.dart.weak.expect b/pkg/front_end/testcases/none/equals.dart.weak.expect
index 538a152..622fa6c8 100644
--- a/pkg/front_end/testcases/none/equals.dart.weak.expect
+++ b/pkg/front_end/testcases/none/equals.dart.weak.expect
@@ -130,347 +130,347 @@
 static method test<T1 extends core::Function = core::Function, T2 extends (core::int) → core::int = (core::int) → core::int>(core::Object o, core::Object nonNullableObject, core::Object? nullableObject, self::Class<core::String> nonNullableClass, self::Class<core::String>? nullableClass, dynamic dyn, Never never, Never? nullableNever, Null nullTypedValue, core::Function nonNullableFunction, core::Function? nullableFunction, (core::int) → core::int nonNullableFunctionType, (core::int) →? core::int nullableFunctionType, self::test::T1 nonNullableTypeVariable1, self::test::T1? nullableTypeVariable1, self::test::T2 nonNullableTypeVariable2, self::test::T2? nullableTypeVariable2) → dynamic {
   core::print("EqualsNull (literal null)");
   null == null;
-  null != null;
+  !(null == null);
   nonNullableObject == null;
-  nonNullableObject != null;
+  !(nonNullableObject == null);
   nonNullableObject == null;
-  nonNullableObject != null;
+  !(nonNullableObject == null);
   nullableObject == null;
-  nullableObject != null;
+  !(nullableObject == null);
   nullableObject == null;
-  nullableObject != null;
+  !(nullableObject == null);
   nullableClass == null;
-  nullableClass != null;
+  !(nullableClass == null);
   nullableClass == null;
-  nullableClass != null;
+  !(nullableClass == null);
   nonNullableClass == null;
-  nonNullableClass != null;
+  !(nonNullableClass == null);
   nonNullableClass == null;
-  nonNullableClass != null;
+  !(nonNullableClass == null);
   dyn == null;
-  dyn != null;
+  !(dyn == null);
   dyn == null;
-  dyn != null;
+  !(dyn == null);
   (let final Never #t1 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")) == null;
-  (let final Never #t2 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")) != null;
+  !((let final Never #t2 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")) == null);
   (let final Never #t3 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")) == null;
-  (let final Never #t4 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")) != null;
+  !((let final Never #t4 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")) == null);
   nullableNever == null;
-  nullableNever != null;
+  !(nullableNever == null);
   nullableNever == null;
-  nullableNever != null;
+  !(nullableNever == null);
   nullTypedValue == null;
-  nullTypedValue != null;
+  !(nullTypedValue == null);
   nullTypedValue == null;
-  nullTypedValue != null;
+  !(nullTypedValue == null);
   nonNullableFunction == null;
-  nonNullableFunction != null;
+  !(nonNullableFunction == null);
   nonNullableFunction == null;
-  nonNullableFunction != null;
+  !(nonNullableFunction == null);
   nullableFunction == null;
-  nullableFunction != null;
+  !(nullableFunction == null);
   nullableFunction == null;
-  nullableFunction != null;
+  !(nullableFunction == null);
   nonNullableFunctionType == null;
-  nonNullableFunctionType != null;
+  !(nonNullableFunctionType == null);
   nonNullableFunctionType == null;
-  nonNullableFunctionType != null;
+  !(nonNullableFunctionType == null);
   nullableFunctionType == null;
-  nullableFunctionType != null;
+  !(nullableFunctionType == null);
   nullableFunctionType == null;
-  nullableFunctionType != null;
+  !(nullableFunctionType == null);
   nonNullableTypeVariable1 == null;
-  nonNullableTypeVariable1 != null;
+  !(nonNullableTypeVariable1 == null);
   nonNullableTypeVariable1 == null;
-  nonNullableTypeVariable1 != null;
+  !(nonNullableTypeVariable1 == null);
   nullableTypeVariable1 == null;
-  nullableTypeVariable1 != null;
+  !(nullableTypeVariable1 == null);
   nullableTypeVariable1 == null;
-  nullableTypeVariable1 != null;
+  !(nullableTypeVariable1 == null);
   nonNullableTypeVariable2 == null;
-  nonNullableTypeVariable2 != null;
+  !(nonNullableTypeVariable2 == null);
   nonNullableTypeVariable2 == null;
-  nonNullableTypeVariable2 != null;
+  !(nonNullableTypeVariable2 == null);
   nullableTypeVariable2 == null;
-  nullableTypeVariable2 != null;
+  !(nullableTypeVariable2 == null);
   nullableTypeVariable2 == null;
-  nullableTypeVariable2 != null;
+  !(nullableTypeVariable2 == null);
   (let final Never #t5 = invalid-expression "pkg/front_end/testcases/none/equals.dart:115:26: Error: Too few positional arguments: 1 required, 0 given.
   nonNullableClass.method() == null;
                          ^" in nonNullableClass.{self::Class::method}{<inapplicable>}.(){() → invalid-type}) == null;
-  (let final Never #t6 = invalid-expression "pkg/front_end/testcases/none/equals.dart:116:26: Error: Too few positional arguments: 1 required, 0 given.
+  !((let final Never #t6 = invalid-expression "pkg/front_end/testcases/none/equals.dart:116:26: Error: Too few positional arguments: 1 required, 0 given.
   nonNullableClass.method() != null;
-                         ^" in nonNullableClass.{self::Class::method}{<inapplicable>}.(){() → invalid-type}) != null;
+                         ^" in nonNullableClass.{self::Class::method}{<inapplicable>}.(){() → invalid-type}) == null);
   (let final Never #t7 = invalid-expression "pkg/front_end/testcases/none/equals.dart:117:34: Error: Too few positional arguments: 1 required, 0 given.
   null == nonNullableClass.method();
                                  ^" in nonNullableClass.{self::Class::method}{<inapplicable>}.(){() → invalid-type}) == null;
-  (let final Never #t8 = invalid-expression "pkg/front_end/testcases/none/equals.dart:118:34: Error: Too few positional arguments: 1 required, 0 given.
+  !((let final Never #t8 = invalid-expression "pkg/front_end/testcases/none/equals.dart:118:34: Error: Too few positional arguments: 1 required, 0 given.
   null != nonNullableClass.method();
-                                 ^" in nonNullableClass.{self::Class::method}{<inapplicable>}.(){() → invalid-type}) != null;
+                                 ^" in nonNullableClass.{self::Class::method}{<inapplicable>}.(){() → invalid-type}) == null);
   core::print("EqualsNull (constant null)");
   (#C1) == null;
-  (#C1) != null;
+  !((#C1) == null);
   nonNullableObject == null;
-  nonNullableObject != null;
+  !(nonNullableObject == null);
   nonNullableObject == null;
-  nonNullableObject != null;
+  !(nonNullableObject == null);
   nullableObject == null;
-  nullableObject != null;
+  !(nullableObject == null);
   nullableObject == null;
-  nullableObject != null;
+  !(nullableObject == null);
   nonNullableClass =={self::Class::==}{(self::Class<core::String>) → core::bool} (let final Never #t9 = invalid-expression "pkg/front_end/testcases/none/equals.dart:134:23: Error: The argument type 'Object?' can't be assigned to the parameter type 'Class<String>?'.
  - 'Object' is from 'dart:core'.
  - 'Class' is from 'pkg/front_end/testcases/none/equals.dart'.
   nonNullableClass == nullValue;
                       ^" in (#C1) as{TypeError,ForNonNullableByDefault} self::Class<core::String>?);
-  nonNullableClass !={self::Class::==}{(self::Class<core::String>) → core::bool} (let final Never #t10 = invalid-expression "pkg/front_end/testcases/none/equals.dart:135:23: Error: The argument type 'Object?' can't be assigned to the parameter type 'Class<String>?'.
+  !(nonNullableClass =={self::Class::==}{(self::Class<core::String>) → core::bool} (let final Never #t10 = invalid-expression "pkg/front_end/testcases/none/equals.dart:135:23: Error: The argument type 'Object?' can't be assigned to the parameter type 'Class<String>?'.
  - 'Object' is from 'dart:core'.
  - 'Class' is from 'pkg/front_end/testcases/none/equals.dart'.
   nonNullableClass != nullValue;
-                      ^" in (#C1) as{TypeError,ForNonNullableByDefault} self::Class<core::String>?);
+                      ^" in (#C1) as{TypeError,ForNonNullableByDefault} self::Class<core::String>?));
   nonNullableClass == null;
-  nonNullableClass != null;
+  !(nonNullableClass == null);
   nullableClass =={self::Class::==}{(self::Class<core::String>) → core::bool} (let final Never #t11 = invalid-expression "pkg/front_end/testcases/none/equals.dart:139:20: Error: The argument type 'Object?' can't be assigned to the parameter type 'Class<String>?'.
  - 'Object' is from 'dart:core'.
  - 'Class' is from 'pkg/front_end/testcases/none/equals.dart'.
   nullableClass == nullValue;
                    ^" in (#C1) as{TypeError,ForNonNullableByDefault} self::Class<core::String>?);
-  nullableClass !={self::Class::==}{(self::Class<core::String>) → core::bool} (let final Never #t12 = invalid-expression "pkg/front_end/testcases/none/equals.dart:140:20: Error: The argument type 'Object?' can't be assigned to the parameter type 'Class<String>?'.
+  !(nullableClass =={self::Class::==}{(self::Class<core::String>) → core::bool} (let final Never #t12 = invalid-expression "pkg/front_end/testcases/none/equals.dart:140:20: Error: The argument type 'Object?' can't be assigned to the parameter type 'Class<String>?'.
  - 'Object' is from 'dart:core'.
  - 'Class' is from 'pkg/front_end/testcases/none/equals.dart'.
   nullableClass != nullValue;
-                   ^" in (#C1) as{TypeError,ForNonNullableByDefault} self::Class<core::String>?);
+                   ^" in (#C1) as{TypeError,ForNonNullableByDefault} self::Class<core::String>?));
   nullableClass == null;
-  nullableClass != null;
+  !(nullableClass == null);
   dyn == null;
-  dyn != null;
+  !(dyn == null);
   dyn == null;
-  dyn != null;
+  !(dyn == null);
   let final Never #t13 = (let final Never #t14 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")) == null in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
-  let final Never #t15 = (let final Never #t16 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")) != null in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
+  let final Never #t15 = !((let final Never #t16 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")) == null) in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
   (let final Never #t17 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")) == null;
-  (let final Never #t18 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")) != null;
+  !((let final Never #t18 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")) == null);
   nullableNever == null;
-  nullableNever != null;
+  !(nullableNever == null);
   nullableNever == null;
-  nullableNever != null;
+  !(nullableNever == null);
   nullTypedValue == null;
-  nullTypedValue != null;
+  !(nullTypedValue == null);
   nullTypedValue == null;
-  nullTypedValue != null;
+  !(nullTypedValue == null);
   nonNullableFunction == null;
-  nonNullableFunction != null;
+  !(nonNullableFunction == null);
   nonNullableFunction == null;
-  nonNullableFunction != null;
+  !(nonNullableFunction == null);
   nullableFunction == null;
-  nullableFunction != null;
+  !(nullableFunction == null);
   nullableFunction == null;
-  nullableFunction != null;
+  !(nullableFunction == null);
   nonNullableFunctionType == null;
-  nonNullableFunctionType != null;
+  !(nonNullableFunctionType == null);
   nonNullableFunctionType == null;
-  nonNullableFunctionType != null;
+  !(nonNullableFunctionType == null);
   nullableFunctionType == null;
-  nullableFunctionType != null;
+  !(nullableFunctionType == null);
   nullableFunctionType == null;
-  nullableFunctionType != null;
+  !(nullableFunctionType == null);
   nonNullableTypeVariable1 == null;
-  nonNullableTypeVariable1 != null;
+  !(nonNullableTypeVariable1 == null);
   nonNullableTypeVariable1 == null;
-  nonNullableTypeVariable1 != null;
+  !(nonNullableTypeVariable1 == null);
   nullableTypeVariable1 == null;
-  nullableTypeVariable1 != null;
+  !(nullableTypeVariable1 == null);
   nullableTypeVariable1 == null;
-  nullableTypeVariable1 != null;
+  !(nullableTypeVariable1 == null);
   nonNullableTypeVariable2 == null;
-  nonNullableTypeVariable2 != null;
+  !(nonNullableTypeVariable2 == null);
   nonNullableTypeVariable2 == null;
-  nonNullableTypeVariable2 != null;
+  !(nonNullableTypeVariable2 == null);
   nullableTypeVariable2 == null;
-  nullableTypeVariable2 != null;
+  !(nullableTypeVariable2 == null);
   nullableTypeVariable2 == null;
-  nullableTypeVariable2 != null;
+  !(nullableTypeVariable2 == null);
   (let final Never #t19 = invalid-expression "pkg/front_end/testcases/none/equals.dart:204:26: Error: Too few positional arguments: 1 required, 0 given.
   nonNullableClass.method() == nullValue;
                          ^" in nonNullableClass.{self::Class::method}{<inapplicable>}.(){() → invalid-type}) == null;
-  (let final Never #t20 = invalid-expression "pkg/front_end/testcases/none/equals.dart:205:26: Error: Too few positional arguments: 1 required, 0 given.
+  !((let final Never #t20 = invalid-expression "pkg/front_end/testcases/none/equals.dart:205:26: Error: Too few positional arguments: 1 required, 0 given.
   nonNullableClass.method() != nullValue;
-                         ^" in nonNullableClass.{self::Class::method}{<inapplicable>}.(){() → invalid-type}) != null;
+                         ^" in nonNullableClass.{self::Class::method}{<inapplicable>}.(){() → invalid-type}) == null);
   (let final Never #t21 = invalid-expression "pkg/front_end/testcases/none/equals.dart:206:39: Error: Too few positional arguments: 1 required, 0 given.
   nullValue == nonNullableClass.method();
                                       ^" in nonNullableClass.{self::Class::method}{<inapplicable>}.(){() → invalid-type}) == null;
-  (let final Never #t22 = invalid-expression "pkg/front_end/testcases/none/equals.dart:207:39: Error: Too few positional arguments: 1 required, 0 given.
+  !((let final Never #t22 = invalid-expression "pkg/front_end/testcases/none/equals.dart:207:39: Error: Too few positional arguments: 1 required, 0 given.
   nullValue != nonNullableClass.method();
-                                      ^" in nonNullableClass.{self::Class::method}{<inapplicable>}.(){() → invalid-type}) != null;
+                                      ^" in nonNullableClass.{self::Class::method}{<inapplicable>}.(){() → invalid-type}) == null);
   core::print("EqualsCall");
   nonNullableObject =={core::Object::==}{(core::Object) → core::bool} nullTypedValue;
-  nonNullableObject !={core::Object::==}{(core::Object) → core::bool} nullTypedValue;
+  !(nonNullableObject =={core::Object::==}{(core::Object) → core::bool} nullTypedValue);
   nullTypedValue =={core::Object::==}{(core::Object) → core::bool} nonNullableObject;
-  nullTypedValue !={core::Object::==}{(core::Object) → core::bool} nonNullableObject;
+  !(nullTypedValue =={core::Object::==}{(core::Object) → core::bool} nonNullableObject);
   nonNullableObject =={core::Object::==}{(core::Object) → core::bool} o;
-  nonNullableObject !={core::Object::==}{(core::Object) → core::bool} o;
+  !(nonNullableObject =={core::Object::==}{(core::Object) → core::bool} o);
   o =={core::Object::==}{(core::Object) → core::bool} nonNullableObject;
-  o !={core::Object::==}{(core::Object) → core::bool} nonNullableObject;
+  !(o =={core::Object::==}{(core::Object) → core::bool} nonNullableObject);
   nullableObject =={core::Object::==}{(core::Object) → core::bool} nullTypedValue;
-  nullableObject !={core::Object::==}{(core::Object) → core::bool} nullTypedValue;
+  !(nullableObject =={core::Object::==}{(core::Object) → core::bool} nullTypedValue);
   nullTypedValue =={core::Object::==}{(core::Object) → core::bool} nullableObject;
-  nullTypedValue !={core::Object::==}{(core::Object) → core::bool} nullableObject;
+  !(nullTypedValue =={core::Object::==}{(core::Object) → core::bool} nullableObject);
   nullableObject =={core::Object::==}{(core::Object) → core::bool} o;
-  nullableObject !={core::Object::==}{(core::Object) → core::bool} o;
+  !(nullableObject =={core::Object::==}{(core::Object) → core::bool} o);
   o =={core::Object::==}{(core::Object) → core::bool} nullableObject;
-  o !={core::Object::==}{(core::Object) → core::bool} nullableObject;
+  !(o =={core::Object::==}{(core::Object) → core::bool} nullableObject);
   nonNullableClass =={self::Class::==}{(self::Class<core::String>) → core::bool} nullTypedValue;
-  nonNullableClass !={self::Class::==}{(self::Class<core::String>) → core::bool} nullTypedValue;
+  !(nonNullableClass =={self::Class::==}{(self::Class<core::String>) → core::bool} nullTypedValue);
   nullTypedValue =={core::Object::==}{(core::Object) → core::bool} nonNullableClass;
-  nullTypedValue !={core::Object::==}{(core::Object) → core::bool} nonNullableClass;
+  !(nullTypedValue =={core::Object::==}{(core::Object) → core::bool} nonNullableClass);
   nonNullableClass =={self::Class::==}{(self::Class<core::String>) → core::bool} (let final Never #t23 = invalid-expression "pkg/front_end/testcases/none/equals.dart:233:23: Error: The argument type 'Object' can't be assigned to the parameter type 'Class<String>?'.
  - 'Object' is from 'dart:core'.
  - 'Class' is from 'pkg/front_end/testcases/none/equals.dart'.
   nonNullableClass == o;
                       ^" in o as{TypeError,ForNonNullableByDefault} self::Class<core::String>?);
-  nonNullableClass !={self::Class::==}{(self::Class<core::String>) → core::bool} (let final Never #t24 = invalid-expression "pkg/front_end/testcases/none/equals.dart:234:23: Error: The argument type 'Object' can't be assigned to the parameter type 'Class<String>?'.
+  !(nonNullableClass =={self::Class::==}{(self::Class<core::String>) → core::bool} (let final Never #t24 = invalid-expression "pkg/front_end/testcases/none/equals.dart:234:23: Error: The argument type 'Object' can't be assigned to the parameter type 'Class<String>?'.
  - 'Object' is from 'dart:core'.
  - 'Class' is from 'pkg/front_end/testcases/none/equals.dart'.
   nonNullableClass != o;
-                      ^" in o as{TypeError,ForNonNullableByDefault} self::Class<core::String>?);
+                      ^" in o as{TypeError,ForNonNullableByDefault} self::Class<core::String>?));
   o =={core::Object::==}{(core::Object) → core::bool} nonNullableClass;
-  o !={core::Object::==}{(core::Object) → core::bool} nonNullableClass;
+  !(o =={core::Object::==}{(core::Object) → core::bool} nonNullableClass);
   nullableClass =={self::Class::==}{(self::Class<core::String>) → core::bool} nullTypedValue;
-  nullableClass !={self::Class::==}{(self::Class<core::String>) → core::bool} nullTypedValue;
+  !(nullableClass =={self::Class::==}{(self::Class<core::String>) → core::bool} nullTypedValue);
   nullTypedValue =={core::Object::==}{(core::Object) → core::bool} nullableClass;
-  nullTypedValue !={core::Object::==}{(core::Object) → core::bool} nullableClass;
+  !(nullTypedValue =={core::Object::==}{(core::Object) → core::bool} nullableClass);
   nullableClass =={self::Class::==}{(self::Class<core::String>) → core::bool} (let final Never #t25 = invalid-expression "pkg/front_end/testcases/none/equals.dart:242:20: Error: The argument type 'Object' can't be assigned to the parameter type 'Class<String>?'.
  - 'Object' is from 'dart:core'.
  - 'Class' is from 'pkg/front_end/testcases/none/equals.dart'.
   nullableClass == o;
                    ^" in o as{TypeError,ForNonNullableByDefault} self::Class<core::String>?);
-  nullableClass !={self::Class::==}{(self::Class<core::String>) → core::bool} (let final Never #t26 = invalid-expression "pkg/front_end/testcases/none/equals.dart:243:20: Error: The argument type 'Object' can't be assigned to the parameter type 'Class<String>?'.
+  !(nullableClass =={self::Class::==}{(self::Class<core::String>) → core::bool} (let final Never #t26 = invalid-expression "pkg/front_end/testcases/none/equals.dart:243:20: Error: The argument type 'Object' can't be assigned to the parameter type 'Class<String>?'.
  - 'Object' is from 'dart:core'.
  - 'Class' is from 'pkg/front_end/testcases/none/equals.dart'.
   nullableClass != o;
-                   ^" in o as{TypeError,ForNonNullableByDefault} self::Class<core::String>?);
+                   ^" in o as{TypeError,ForNonNullableByDefault} self::Class<core::String>?));
   o =={core::Object::==}{(core::Object) → core::bool} nullableClass;
-  o !={core::Object::==}{(core::Object) → core::bool} nullableClass;
+  !(o =={core::Object::==}{(core::Object) → core::bool} nullableClass);
   dyn =={core::Object::==}{(core::Object) → core::bool} nullTypedValue;
-  dyn !={core::Object::==}{(core::Object) → core::bool} nullTypedValue;
+  !(dyn =={core::Object::==}{(core::Object) → core::bool} nullTypedValue);
   nullTypedValue =={core::Object::==}{(core::Object) → core::bool} dyn;
-  nullTypedValue !={core::Object::==}{(core::Object) → core::bool} dyn;
+  !(nullTypedValue =={core::Object::==}{(core::Object) → core::bool} dyn);
   dyn =={core::Object::==}{(core::Object) → core::bool} o;
-  dyn !={core::Object::==}{(core::Object) → core::bool} o;
+  !(dyn =={core::Object::==}{(core::Object) → core::bool} o);
   o =={core::Object::==}{(core::Object) → core::bool} dyn;
-  o !={core::Object::==}{(core::Object) → core::bool} dyn;
+  !(o =={core::Object::==}{(core::Object) → core::bool} dyn);
   let final Never #t27 = (let final Never #t28 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")) =={core::Object::==}{(dynamic) → Never} nullTypedValue in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
-  let final Never #t29 = (let final Never #t30 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")) !={core::Object::==}{(dynamic) → Never} nullTypedValue in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
+  let final Never #t29 = !((let final Never #t30 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")) =={core::Object::==}{(dynamic) → Never} nullTypedValue) in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
   nullTypedValue =={core::Object::==}{(core::Object) → core::bool} (let final Never #t31 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
-  nullTypedValue !={core::Object::==}{(core::Object) → core::bool} (let final Never #t32 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
+  !(nullTypedValue =={core::Object::==}{(core::Object) → core::bool} (let final Never #t32 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")));
   let final Never #t33 = (let final Never #t34 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")) =={core::Object::==}{(dynamic) → Never} o in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
-  let final Never #t35 = (let final Never #t36 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")) !={core::Object::==}{(dynamic) → Never} o in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
+  let final Never #t35 = !((let final Never #t36 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")) =={core::Object::==}{(dynamic) → Never} o) in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
   o =={core::Object::==}{(core::Object) → core::bool} (let final Never #t37 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
-  o !={core::Object::==}{(core::Object) → core::bool} (let final Never #t38 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."));
+  !(o =={core::Object::==}{(core::Object) → core::bool} (let final Never #t38 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")));
   nullableNever =={core::Object::==}{(core::Object) → core::bool} nullTypedValue;
-  nullableNever !={core::Object::==}{(core::Object) → core::bool} nullTypedValue;
+  !(nullableNever =={core::Object::==}{(core::Object) → core::bool} nullTypedValue);
   nullTypedValue =={core::Object::==}{(core::Object) → core::bool} nullableNever;
-  nullTypedValue !={core::Object::==}{(core::Object) → core::bool} nullableNever;
+  !(nullTypedValue =={core::Object::==}{(core::Object) → core::bool} nullableNever);
   nullableNever =={core::Object::==}{(core::Object) → core::bool} o;
-  nullableNever !={core::Object::==}{(core::Object) → core::bool} o;
+  !(nullableNever =={core::Object::==}{(core::Object) → core::bool} o);
   o =={core::Object::==}{(core::Object) → core::bool} nullableNever;
-  o !={core::Object::==}{(core::Object) → core::bool} nullableNever;
+  !(o =={core::Object::==}{(core::Object) → core::bool} nullableNever);
   nullTypedValue =={core::Object::==}{(core::Object) → core::bool} nullTypedValue;
-  nullTypedValue !={core::Object::==}{(core::Object) → core::bool} nullTypedValue;
+  !(nullTypedValue =={core::Object::==}{(core::Object) → core::bool} nullTypedValue);
   nullTypedValue =={core::Object::==}{(core::Object) → core::bool} nullTypedValue;
-  nullTypedValue !={core::Object::==}{(core::Object) → core::bool} nullTypedValue;
+  !(nullTypedValue =={core::Object::==}{(core::Object) → core::bool} nullTypedValue);
   nullTypedValue =={core::Object::==}{(core::Object) → core::bool} o;
-  nullTypedValue !={core::Object::==}{(core::Object) → core::bool} o;
+  !(nullTypedValue =={core::Object::==}{(core::Object) → core::bool} o);
   o =={core::Object::==}{(core::Object) → core::bool} nullTypedValue;
-  o !={core::Object::==}{(core::Object) → core::bool} nullTypedValue;
+  !(o =={core::Object::==}{(core::Object) → core::bool} nullTypedValue);
   nonNullableFunction =={core::Function::==}{(core::Object) → core::bool} nullTypedValue;
-  nonNullableFunction !={core::Function::==}{(core::Object) → core::bool} nullTypedValue;
+  !(nonNullableFunction =={core::Function::==}{(core::Object) → core::bool} nullTypedValue);
   nullTypedValue =={core::Object::==}{(core::Object) → core::bool} nonNullableFunction;
-  nullTypedValue !={core::Object::==}{(core::Object) → core::bool} nonNullableFunction;
+  !(nullTypedValue =={core::Object::==}{(core::Object) → core::bool} nonNullableFunction);
   nonNullableFunction =={core::Function::==}{(core::Object) → core::bool} o;
-  nonNullableFunction !={core::Function::==}{(core::Object) → core::bool} o;
+  !(nonNullableFunction =={core::Function::==}{(core::Object) → core::bool} o);
   o =={core::Object::==}{(core::Object) → core::bool} nonNullableFunction;
-  o !={core::Object::==}{(core::Object) → core::bool} nonNullableFunction;
+  !(o =={core::Object::==}{(core::Object) → core::bool} nonNullableFunction);
   nullableFunction =={core::Function::==}{(core::Object) → core::bool} nullTypedValue;
-  nullableFunction !={core::Function::==}{(core::Object) → core::bool} nullTypedValue;
+  !(nullableFunction =={core::Function::==}{(core::Object) → core::bool} nullTypedValue);
   nullTypedValue =={core::Object::==}{(core::Object) → core::bool} nullableFunction;
-  nullTypedValue !={core::Object::==}{(core::Object) → core::bool} nullableFunction;
+  !(nullTypedValue =={core::Object::==}{(core::Object) → core::bool} nullableFunction);
   nullableFunction =={core::Function::==}{(core::Object) → core::bool} o;
-  nullableFunction !={core::Function::==}{(core::Object) → core::bool} o;
+  !(nullableFunction =={core::Function::==}{(core::Object) → core::bool} o);
   o =={core::Object::==}{(core::Object) → core::bool} nullableFunction;
-  o !={core::Object::==}{(core::Object) → core::bool} nullableFunction;
+  !(o =={core::Object::==}{(core::Object) → core::bool} nullableFunction);
   nonNullableFunctionType =={core::Object::==}{(core::Object) → core::bool} nullTypedValue;
-  nonNullableFunctionType !={core::Object::==}{(core::Object) → core::bool} nullTypedValue;
+  !(nonNullableFunctionType =={core::Object::==}{(core::Object) → core::bool} nullTypedValue);
   nullTypedValue =={core::Object::==}{(core::Object) → core::bool} nonNullableFunctionType;
-  nullTypedValue !={core::Object::==}{(core::Object) → core::bool} nonNullableFunctionType;
+  !(nullTypedValue =={core::Object::==}{(core::Object) → core::bool} nonNullableFunctionType);
   nonNullableFunctionType =={core::Object::==}{(core::Object) → core::bool} o;
-  nonNullableFunctionType !={core::Object::==}{(core::Object) → core::bool} o;
+  !(nonNullableFunctionType =={core::Object::==}{(core::Object) → core::bool} o);
   o =={core::Object::==}{(core::Object) → core::bool} nonNullableFunctionType;
-  o !={core::Object::==}{(core::Object) → core::bool} nonNullableFunctionType;
+  !(o =={core::Object::==}{(core::Object) → core::bool} nonNullableFunctionType);
   nullableFunctionType =={core::Object::==}{(core::Object) → core::bool} nullTypedValue;
-  nullableFunctionType !={core::Object::==}{(core::Object) → core::bool} nullTypedValue;
+  !(nullableFunctionType =={core::Object::==}{(core::Object) → core::bool} nullTypedValue);
   nullTypedValue =={core::Object::==}{(core::Object) → core::bool} nullableFunctionType;
-  nullTypedValue !={core::Object::==}{(core::Object) → core::bool} nullableFunctionType;
+  !(nullTypedValue =={core::Object::==}{(core::Object) → core::bool} nullableFunctionType);
   nullableFunctionType =={core::Object::==}{(core::Object) → core::bool} o;
-  nullableFunctionType !={core::Object::==}{(core::Object) → core::bool} o;
+  !(nullableFunctionType =={core::Object::==}{(core::Object) → core::bool} o);
   o =={core::Object::==}{(core::Object) → core::bool} nullableFunctionType;
-  o !={core::Object::==}{(core::Object) → core::bool} nullableFunctionType;
+  !(o =={core::Object::==}{(core::Object) → core::bool} nullableFunctionType);
   nonNullableTypeVariable1 =={core::Function::==}{(core::Object) → core::bool} nullTypedValue;
-  nonNullableTypeVariable1 !={core::Function::==}{(core::Object) → core::bool} nullTypedValue;
+  !(nonNullableTypeVariable1 =={core::Function::==}{(core::Object) → core::bool} nullTypedValue);
   nullTypedValue =={core::Object::==}{(core::Object) → core::bool} nonNullableTypeVariable1;
-  nullTypedValue !={core::Object::==}{(core::Object) → core::bool} nonNullableTypeVariable1;
+  !(nullTypedValue =={core::Object::==}{(core::Object) → core::bool} nonNullableTypeVariable1);
   nonNullableTypeVariable1 =={core::Function::==}{(core::Object) → core::bool} o;
-  nonNullableTypeVariable1 !={core::Function::==}{(core::Object) → core::bool} o;
+  !(nonNullableTypeVariable1 =={core::Function::==}{(core::Object) → core::bool} o);
   o =={core::Object::==}{(core::Object) → core::bool} nonNullableTypeVariable1;
-  o !={core::Object::==}{(core::Object) → core::bool} nonNullableTypeVariable1;
+  !(o =={core::Object::==}{(core::Object) → core::bool} nonNullableTypeVariable1);
   nullableTypeVariable1 =={core::Function::==}{(core::Object) → core::bool} nullTypedValue;
-  nullableTypeVariable1 !={core::Function::==}{(core::Object) → core::bool} nullTypedValue;
+  !(nullableTypeVariable1 =={core::Function::==}{(core::Object) → core::bool} nullTypedValue);
   nullTypedValue =={core::Object::==}{(core::Object) → core::bool} nullableTypeVariable1;
-  nullTypedValue !={core::Object::==}{(core::Object) → core::bool} nullableTypeVariable1;
+  !(nullTypedValue =={core::Object::==}{(core::Object) → core::bool} nullableTypeVariable1);
   nullableTypeVariable1 =={core::Function::==}{(core::Object) → core::bool} o;
-  nullableTypeVariable1 !={core::Function::==}{(core::Object) → core::bool} o;
+  !(nullableTypeVariable1 =={core::Function::==}{(core::Object) → core::bool} o);
   o =={core::Object::==}{(core::Object) → core::bool} nullableTypeVariable1;
-  o !={core::Object::==}{(core::Object) → core::bool} nullableTypeVariable1;
+  !(o =={core::Object::==}{(core::Object) → core::bool} nullableTypeVariable1);
   nonNullableTypeVariable2 =={core::Object::==}{(core::Object) → core::bool} nullTypedValue;
-  nonNullableTypeVariable2 !={core::Object::==}{(core::Object) → core::bool} nullTypedValue;
+  !(nonNullableTypeVariable2 =={core::Object::==}{(core::Object) → core::bool} nullTypedValue);
   nullTypedValue =={core::Object::==}{(core::Object) → core::bool} nonNullableTypeVariable2;
-  nullTypedValue !={core::Object::==}{(core::Object) → core::bool} nonNullableTypeVariable2;
+  !(nullTypedValue =={core::Object::==}{(core::Object) → core::bool} nonNullableTypeVariable2);
   nonNullableTypeVariable2 =={core::Object::==}{(core::Object) → core::bool} o;
-  nonNullableTypeVariable2 !={core::Object::==}{(core::Object) → core::bool} o;
+  !(nonNullableTypeVariable2 =={core::Object::==}{(core::Object) → core::bool} o);
   o =={core::Object::==}{(core::Object) → core::bool} nonNullableTypeVariable2;
-  o !={core::Object::==}{(core::Object) → core::bool} nonNullableTypeVariable2;
+  !(o =={core::Object::==}{(core::Object) → core::bool} nonNullableTypeVariable2);
   nullableTypeVariable2 =={core::Object::==}{(core::Object) → core::bool} nullTypedValue;
-  nullableTypeVariable2 !={core::Object::==}{(core::Object) → core::bool} nullTypedValue;
+  !(nullableTypeVariable2 =={core::Object::==}{(core::Object) → core::bool} nullTypedValue);
   nullTypedValue =={core::Object::==}{(core::Object) → core::bool} nullableTypeVariable2;
-  nullTypedValue !={core::Object::==}{(core::Object) → core::bool} nullableTypeVariable2;
+  !(nullTypedValue =={core::Object::==}{(core::Object) → core::bool} nullableTypeVariable2);
   nullableTypeVariable2 =={core::Object::==}{(core::Object) → core::bool} o;
-  nullableTypeVariable2 !={core::Object::==}{(core::Object) → core::bool} o;
+  !(nullableTypeVariable2 =={core::Object::==}{(core::Object) → core::bool} o);
   o =={core::Object::==}{(core::Object) → core::bool} nullableTypeVariable2;
-  o !={core::Object::==}{(core::Object) → core::bool} nullableTypeVariable2;
+  !(o =={core::Object::==}{(core::Object) → core::bool} nullableTypeVariable2);
   (let final Never #t39 = invalid-expression "pkg/front_end/testcases/none/equals.dart:355:26: Error: Too few positional arguments: 1 required, 0 given.
   nonNullableClass.method() == nullTypedValue;
                          ^" in nonNullableClass.{self::Class::method}{<inapplicable>}.(){() → invalid-type}) =={core::Object::==}{(core::Object) → core::bool} nullTypedValue;
-  (let final Never #t40 = invalid-expression "pkg/front_end/testcases/none/equals.dart:356:26: Error: Too few positional arguments: 1 required, 0 given.
+  !((let final Never #t40 = invalid-expression "pkg/front_end/testcases/none/equals.dart:356:26: Error: Too few positional arguments: 1 required, 0 given.
   nonNullableClass.method() != nullTypedValue;
-                         ^" in nonNullableClass.{self::Class::method}{<inapplicable>}.(){() → invalid-type}) !={core::Object::==}{(core::Object) → core::bool} nullTypedValue;
+                         ^" in nonNullableClass.{self::Class::method}{<inapplicable>}.(){() → invalid-type}) =={core::Object::==}{(core::Object) → core::bool} nullTypedValue);
   nullTypedValue =={core::Object::==}{(core::Object) → core::bool} (let final Never #t41 = invalid-expression "pkg/front_end/testcases/none/equals.dart:357:44: Error: Too few positional arguments: 1 required, 0 given.
   nullTypedValue == nonNullableClass.method();
                                            ^" in nonNullableClass.{self::Class::method}{<inapplicable>}.(){() → invalid-type});
-  nullTypedValue !={core::Object::==}{(core::Object) → core::bool} (let final Never #t42 = invalid-expression "pkg/front_end/testcases/none/equals.dart:358:44: Error: Too few positional arguments: 1 required, 0 given.
+  !(nullTypedValue =={core::Object::==}{(core::Object) → core::bool} (let final Never #t42 = invalid-expression "pkg/front_end/testcases/none/equals.dart:358:44: Error: Too few positional arguments: 1 required, 0 given.
   nullTypedValue != nonNullableClass.method();
-                                           ^" in nonNullableClass.{self::Class::method}{<inapplicable>}.(){() → invalid-type});
+                                           ^" in nonNullableClass.{self::Class::method}{<inapplicable>}.(){() → invalid-type}));
   (let final Never #t43 = invalid-expression "pkg/front_end/testcases/none/equals.dart:359:26: Error: Too few positional arguments: 1 required, 0 given.
   nonNullableClass.method() == o;
                          ^" in nonNullableClass.{self::Class::method}{<inapplicable>}.(){() → invalid-type}) =={core::Object::==}{(core::Object) → core::bool} o;
-  (let final Never #t44 = invalid-expression "pkg/front_end/testcases/none/equals.dart:360:26: Error: Too few positional arguments: 1 required, 0 given.
+  !((let final Never #t44 = invalid-expression "pkg/front_end/testcases/none/equals.dart:360:26: Error: Too few positional arguments: 1 required, 0 given.
   nonNullableClass.method() != o;
-                         ^" in nonNullableClass.{self::Class::method}{<inapplicable>}.(){() → invalid-type}) !={core::Object::==}{(core::Object) → core::bool} o;
+                         ^" in nonNullableClass.{self::Class::method}{<inapplicable>}.(){() → invalid-type}) =={core::Object::==}{(core::Object) → core::bool} o);
   o =={core::Object::==}{(core::Object) → core::bool} (let final Never #t45 = invalid-expression "pkg/front_end/testcases/none/equals.dart:361:31: Error: Too few positional arguments: 1 required, 0 given.
   o == nonNullableClass.method();
                               ^" in nonNullableClass.{self::Class::method}{<inapplicable>}.(){() → invalid-type});
-  o !={core::Object::==}{(core::Object) → core::bool} (let final Never #t46 = invalid-expression "pkg/front_end/testcases/none/equals.dart:362:31: Error: Too few positional arguments: 1 required, 0 given.
+  !(o =={core::Object::==}{(core::Object) → core::bool} (let final Never #t46 = invalid-expression "pkg/front_end/testcases/none/equals.dart:362:31: Error: Too few positional arguments: 1 required, 0 given.
   o != nonNullableClass.method();
-                              ^" in nonNullableClass.{self::Class::method}{<inapplicable>}.(){() → invalid-type});
+                              ^" in nonNullableClass.{self::Class::method}{<inapplicable>}.(){() → invalid-type}));
 }
 static method nullEqualsIndexGet(core::Map<core::int, core::String> map) → dynamic {
   map.{core::Map::[]}(0){(core::Object?) → core::String?} == null;
diff --git a/pkg/front_end/testcases/none/mixin_covariant.dart.strong.expect b/pkg/front_end/testcases/none/mixin_covariant.dart.strong.expect
index be28553..81796a7 100644
--- a/pkg/front_end/testcases/none/mixin_covariant.dart.strong.expect
+++ b/pkg/front_end/testcases/none/mixin_covariant.dart.strong.expect
@@ -65,7 +65,7 @@
   self::expect("Mixin", m.{self::Mixin::method4}(0, 1){(core::int, core::int) → core::String});
 }
 static method expect(dynamic expected, dynamic actual) → void {
-  if(expected !={core::Object::==}{(core::Object) → core::bool} actual)
+  if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual))
     throw "Expected ${expected}, actual ${actual}";
 }
 static method throws(() → void f) → void {
diff --git a/pkg/front_end/testcases/none/mixin_covariant.dart.strong.transformed.expect b/pkg/front_end/testcases/none/mixin_covariant.dart.strong.transformed.expect
index be28553..81796a7 100644
--- a/pkg/front_end/testcases/none/mixin_covariant.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/none/mixin_covariant.dart.strong.transformed.expect
@@ -65,7 +65,7 @@
   self::expect("Mixin", m.{self::Mixin::method4}(0, 1){(core::int, core::int) → core::String});
 }
 static method expect(dynamic expected, dynamic actual) → void {
-  if(expected !={core::Object::==}{(core::Object) → core::bool} actual)
+  if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual))
     throw "Expected ${expected}, actual ${actual}";
 }
 static method throws(() → void f) → void {
diff --git a/pkg/front_end/testcases/none/mixin_covariant.dart.weak.expect b/pkg/front_end/testcases/none/mixin_covariant.dart.weak.expect
index be28553..81796a7 100644
--- a/pkg/front_end/testcases/none/mixin_covariant.dart.weak.expect
+++ b/pkg/front_end/testcases/none/mixin_covariant.dart.weak.expect
@@ -65,7 +65,7 @@
   self::expect("Mixin", m.{self::Mixin::method4}(0, 1){(core::int, core::int) → core::String});
 }
 static method expect(dynamic expected, dynamic actual) → void {
-  if(expected !={core::Object::==}{(core::Object) → core::bool} actual)
+  if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual))
     throw "Expected ${expected}, actual ${actual}";
 }
 static method throws(() → void f) → void {
diff --git a/pkg/front_end/testcases/none/mixin_covariant.dart.weak.transformed.expect b/pkg/front_end/testcases/none/mixin_covariant.dart.weak.transformed.expect
index be28553..81796a7 100644
--- a/pkg/front_end/testcases/none/mixin_covariant.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/none/mixin_covariant.dart.weak.transformed.expect
@@ -65,7 +65,7 @@
   self::expect("Mixin", m.{self::Mixin::method4}(0, 1){(core::int, core::int) → core::String});
 }
 static method expect(dynamic expected, dynamic actual) → void {
-  if(expected !={core::Object::==}{(core::Object) → core::bool} actual)
+  if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual))
     throw "Expected ${expected}, actual ${actual}";
 }
 static method throws(() → void f) → void {
diff --git a/pkg/front_end/testcases/none/new_method_invocation_encodings.dart.strong.expect b/pkg/front_end/testcases/none/new_method_invocation_encodings.dart.strong.expect
index 6bbacdb..a213a54 100644
--- a/pkg/front_end/testcases/none/new_method_invocation_encodings.dart.strong.expect
+++ b/pkg/front_end/testcases/none/new_method_invocation_encodings.dart.strong.expect
@@ -46,10 +46,10 @@
   function local() → Null {}
   local(){() → Null};
   c =={core::Object::==}{(core::Object) → core::bool} d;
-  c !={core::Object::==}{(core::Object) → core::bool} d;
+  !(c =={core::Object::==}{(core::Object) → core::bool} d);
   c == null;
-  c != null;
+  !(c == null);
   d == null;
-  d != null;
+  !(d == null);
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/none/new_method_invocation_encodings.dart.strong.transformed.expect b/pkg/front_end/testcases/none/new_method_invocation_encodings.dart.strong.transformed.expect
index 6bbacdb..a213a54 100644
--- a/pkg/front_end/testcases/none/new_method_invocation_encodings.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/none/new_method_invocation_encodings.dart.strong.transformed.expect
@@ -46,10 +46,10 @@
   function local() → Null {}
   local(){() → Null};
   c =={core::Object::==}{(core::Object) → core::bool} d;
-  c !={core::Object::==}{(core::Object) → core::bool} d;
+  !(c =={core::Object::==}{(core::Object) → core::bool} d);
   c == null;
-  c != null;
+  !(c == null);
   d == null;
-  d != null;
+  !(d == null);
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/none/new_method_invocation_encodings.dart.weak.expect b/pkg/front_end/testcases/none/new_method_invocation_encodings.dart.weak.expect
index 6bbacdb..a213a54 100644
--- a/pkg/front_end/testcases/none/new_method_invocation_encodings.dart.weak.expect
+++ b/pkg/front_end/testcases/none/new_method_invocation_encodings.dart.weak.expect
@@ -46,10 +46,10 @@
   function local() → Null {}
   local(){() → Null};
   c =={core::Object::==}{(core::Object) → core::bool} d;
-  c !={core::Object::==}{(core::Object) → core::bool} d;
+  !(c =={core::Object::==}{(core::Object) → core::bool} d);
   c == null;
-  c != null;
+  !(c == null);
   d == null;
-  d != null;
+  !(d == null);
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/none/new_method_invocation_encodings.dart.weak.transformed.expect b/pkg/front_end/testcases/none/new_method_invocation_encodings.dart.weak.transformed.expect
index 6bbacdb..a213a54 100644
--- a/pkg/front_end/testcases/none/new_method_invocation_encodings.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/none/new_method_invocation_encodings.dart.weak.transformed.expect
@@ -46,10 +46,10 @@
   function local() → Null {}
   local(){() → Null};
   c =={core::Object::==}{(core::Object) → core::bool} d;
-  c !={core::Object::==}{(core::Object) → core::bool} d;
+  !(c =={core::Object::==}{(core::Object) → core::bool} d);
   c == null;
-  c != null;
+  !(c == null);
   d == null;
-  d != null;
+  !(d == null);
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart
new file mode 100644
index 0000000..84f5324
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart
@@ -0,0 +1,38 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class A<T> {}
+
+typedef B<X extends A<X>> = A<X>;
+
+foo() {
+  B<A<int>> x1;
+  A<B<A<int>>> x2;
+}
+
+B<A<int>> bar1a() => throw 42;
+A<B<A<int>>> bar1b() => throw 42;
+
+bar2a(B<A<int>> x) => throw 42;
+bar2b(A<B<A<int>>> x) => throw 42;
+
+bar3a<X extends B<A<int>>>() => throw 42;
+bar3b<X extends A<B<A<int>>>>() => throw 42;
+
+class Bar1<X extends B<A<int>>> {
+  B<A<int>> barBar11() => throw 42;
+  barBar12(B<A<int>> x) => throw 42;
+  barBar13<X extends B<A<int>>>() => throw 42;
+}
+
+class Bar2<X extends A<B<A<int>>>> {
+  A<B<A<int>>> barBar21() => throw 42;
+  barBar22(A<B<A<int>>> x) => throw 42;
+  barBar23<X extends A<B<A<int>>>>() => throw 42;
+}
+
+typedef Baz1 = B<A<int>>;
+typedef Baz2 = A<B<A<int>>>;
+
+main() {}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart.strong.expect b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart.strong.expect
new file mode 100644
index 0000000..7506643
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart.strong.expect
@@ -0,0 +1,216 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:20:17: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+// bar3a<X extends B<A<int>>>() => throw 42;
+//                 ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:21:19: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+// bar3b<X extends A<B<A<int>>>>() => throw 42;
+//                   ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:23:22: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+// class Bar1<X extends B<A<int>>> {
+//                      ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:26:22: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+//   barBar13<X extends B<A<int>>>() => throw 42;
+//                      ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:29:24: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+// class Bar2<X extends A<B<A<int>>>> {
+//                        ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:32:24: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+//   barBar23<X extends A<B<A<int>>>>() => throw 42;
+//                        ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:14:1: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+// B<A<int>> bar1a() => throw 42;
+// ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:15:3: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+// A<B<A<int>>> bar1b() => throw 42;
+//   ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:17:7: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+// bar2a(B<A<int>> x) => throw 42;
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:18:9: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+// bar2b(A<B<A<int>>> x) => throw 42;
+//         ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:24:3: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+//   B<A<int>> barBar11() => throw 42;
+//   ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:25:12: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+//   barBar12(B<A<int>> x) => throw 42;
+//            ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:30:5: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+//   A<B<A<int>>> barBar21() => throw 42;
+//     ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:31:14: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+//   barBar22(A<B<A<int>>> x) => throw 42;
+//              ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:35:16: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+// typedef Baz1 = B<A<int>>;
+//                ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:36:18: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+// typedef Baz2 = A<B<A<int>>>;
+//                  ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:10:3: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+//   B<A<int>> x1;
+//   ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:11:5: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+//   A<B<A<int>>> x2;
+//     ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef B<X extends self::A<X> = self::A<dynamic>> = self::A<X>;
+typedef Baz1 = self::A<self::A<core::int>>;
+typedef Baz2 = self::A<self::A<self::A<core::int>>>;
+class A<T extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::A<self::A::T%>
+    : super core::Object::•()
+    ;
+}
+class Bar1<X extends self::A<self::A<core::int>> = self::A<self::A<core::int>>> extends core::Object {
+  synthetic constructor •() → self::Bar1<self::Bar1::X>
+    : super core::Object::•()
+    ;
+  method barBar11() → self::A<self::A<core::int>>
+    return throw 42;
+  method barBar12(self::A<self::A<core::int>> x) → dynamic
+    return throw 42;
+  method barBar13<X extends self::A<self::A<core::int>> = self::A<self::A<core::int>>>() → dynamic
+    return throw 42;
+}
+class Bar2<X extends self::A<self::A<self::A<core::int>>> = self::A<self::A<self::A<core::int>>>> extends core::Object {
+  synthetic constructor •() → self::Bar2<self::Bar2::X>
+    : super core::Object::•()
+    ;
+  method barBar21() → self::A<self::A<self::A<core::int>>>
+    return throw 42;
+  method barBar22(self::A<self::A<self::A<core::int>>> x) → dynamic
+    return throw 42;
+  method barBar23<X extends self::A<self::A<self::A<core::int>>> = self::A<self::A<self::A<core::int>>>>() → dynamic
+    return throw 42;
+}
+static method foo() → dynamic {
+  self::A<self::A<core::int>> x1;
+  self::A<self::A<self::A<core::int>>> x2;
+}
+static method bar1a() → self::A<self::A<core::int>>
+  return throw 42;
+static method bar1b() → self::A<self::A<self::A<core::int>>>
+  return throw 42;
+static method bar2a(self::A<self::A<core::int>> x) → dynamic
+  return throw 42;
+static method bar2b(self::A<self::A<self::A<core::int>>> x) → dynamic
+  return throw 42;
+static method bar3a<X extends self::A<self::A<core::int>> = self::A<self::A<core::int>>>() → dynamic
+  return throw 42;
+static method bar3b<X extends self::A<self::A<self::A<core::int>>> = self::A<self::A<self::A<core::int>>>>() → dynamic
+  return throw 42;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart.strong.transformed.expect b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart.strong.transformed.expect
new file mode 100644
index 0000000..7506643
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart.strong.transformed.expect
@@ -0,0 +1,216 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:20:17: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+// bar3a<X extends B<A<int>>>() => throw 42;
+//                 ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:21:19: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+// bar3b<X extends A<B<A<int>>>>() => throw 42;
+//                   ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:23:22: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+// class Bar1<X extends B<A<int>>> {
+//                      ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:26:22: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+//   barBar13<X extends B<A<int>>>() => throw 42;
+//                      ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:29:24: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+// class Bar2<X extends A<B<A<int>>>> {
+//                        ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:32:24: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+//   barBar23<X extends A<B<A<int>>>>() => throw 42;
+//                        ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:14:1: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+// B<A<int>> bar1a() => throw 42;
+// ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:15:3: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+// A<B<A<int>>> bar1b() => throw 42;
+//   ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:17:7: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+// bar2a(B<A<int>> x) => throw 42;
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:18:9: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+// bar2b(A<B<A<int>>> x) => throw 42;
+//         ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:24:3: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+//   B<A<int>> barBar11() => throw 42;
+//   ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:25:12: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+//   barBar12(B<A<int>> x) => throw 42;
+//            ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:30:5: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+//   A<B<A<int>>> barBar21() => throw 42;
+//     ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:31:14: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+//   barBar22(A<B<A<int>>> x) => throw 42;
+//              ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:35:16: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+// typedef Baz1 = B<A<int>>;
+//                ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:36:18: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+// typedef Baz2 = A<B<A<int>>>;
+//                  ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:10:3: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+//   B<A<int>> x1;
+//   ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:11:5: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+//   A<B<A<int>>> x2;
+//     ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef B<X extends self::A<X> = self::A<dynamic>> = self::A<X>;
+typedef Baz1 = self::A<self::A<core::int>>;
+typedef Baz2 = self::A<self::A<self::A<core::int>>>;
+class A<T extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::A<self::A::T%>
+    : super core::Object::•()
+    ;
+}
+class Bar1<X extends self::A<self::A<core::int>> = self::A<self::A<core::int>>> extends core::Object {
+  synthetic constructor •() → self::Bar1<self::Bar1::X>
+    : super core::Object::•()
+    ;
+  method barBar11() → self::A<self::A<core::int>>
+    return throw 42;
+  method barBar12(self::A<self::A<core::int>> x) → dynamic
+    return throw 42;
+  method barBar13<X extends self::A<self::A<core::int>> = self::A<self::A<core::int>>>() → dynamic
+    return throw 42;
+}
+class Bar2<X extends self::A<self::A<self::A<core::int>>> = self::A<self::A<self::A<core::int>>>> extends core::Object {
+  synthetic constructor •() → self::Bar2<self::Bar2::X>
+    : super core::Object::•()
+    ;
+  method barBar21() → self::A<self::A<self::A<core::int>>>
+    return throw 42;
+  method barBar22(self::A<self::A<self::A<core::int>>> x) → dynamic
+    return throw 42;
+  method barBar23<X extends self::A<self::A<self::A<core::int>>> = self::A<self::A<self::A<core::int>>>>() → dynamic
+    return throw 42;
+}
+static method foo() → dynamic {
+  self::A<self::A<core::int>> x1;
+  self::A<self::A<self::A<core::int>>> x2;
+}
+static method bar1a() → self::A<self::A<core::int>>
+  return throw 42;
+static method bar1b() → self::A<self::A<self::A<core::int>>>
+  return throw 42;
+static method bar2a(self::A<self::A<core::int>> x) → dynamic
+  return throw 42;
+static method bar2b(self::A<self::A<self::A<core::int>>> x) → dynamic
+  return throw 42;
+static method bar3a<X extends self::A<self::A<core::int>> = self::A<self::A<core::int>>>() → dynamic
+  return throw 42;
+static method bar3b<X extends self::A<self::A<self::A<core::int>>> = self::A<self::A<self::A<core::int>>>>() → dynamic
+  return throw 42;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart.textual_outline.expect b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart.textual_outline.expect
new file mode 100644
index 0000000..1e1227f
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart.textual_outline.expect
@@ -0,0 +1,26 @@
+class A<T> {}
+
+typedef B<X extends A<X>> = A<X>;
+foo() {}
+B<A<int>> bar1a() => throw 42;
+A<B<A<int>>> bar1b() => throw 42;
+bar2a(B<A<int>> x) => throw 42;
+bar2b(A<B<A<int>>> x) => throw 42;
+bar3a<X extends B<A<int>>>() => throw 42;
+bar3b<X extends A<B<A<int>>>>() => throw 42;
+
+class Bar1<X extends B<A<int>>> {
+  B<A<int>> barBar11() => throw 42;
+  barBar12(B<A<int>> x) => throw 42;
+  barBar13<X extends B<A<int>>>() => throw 42;
+}
+
+class Bar2<X extends A<B<A<int>>>> {
+  A<B<A<int>>> barBar21() => throw 42;
+  barBar22(A<B<A<int>>> x) => throw 42;
+  barBar23<X extends A<B<A<int>>>>() => throw 42;
+}
+
+typedef Baz1 = B<A<int>>;
+typedef Baz2 = A<B<A<int>>>;
+main() {}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b492b9f
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart.textual_outline_modelled.expect
@@ -0,0 +1,26 @@
+A<B<A<int>>> bar1b() => throw 42;
+B<A<int>> bar1a() => throw 42;
+bar2a(B<A<int>> x) => throw 42;
+bar2b(A<B<A<int>>> x) => throw 42;
+bar3a<X extends B<A<int>>>() => throw 42;
+bar3b<X extends A<B<A<int>>>>() => throw 42;
+
+class A<T> {}
+
+class Bar1<X extends B<A<int>>> {
+  B<A<int>> barBar11() => throw 42;
+  barBar12(B<A<int>> x) => throw 42;
+  barBar13<X extends B<A<int>>>() => throw 42;
+}
+
+class Bar2<X extends A<B<A<int>>>> {
+  A<B<A<int>>> barBar21() => throw 42;
+  barBar22(A<B<A<int>>> x) => throw 42;
+  barBar23<X extends A<B<A<int>>>>() => throw 42;
+}
+
+foo() {}
+main() {}
+typedef B<X extends A<X>> = A<X>;
+typedef Baz1 = B<A<int>>;
+typedef Baz2 = A<B<A<int>>>;
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart.weak.expect b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart.weak.expect
new file mode 100644
index 0000000..7506643
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart.weak.expect
@@ -0,0 +1,216 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:20:17: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+// bar3a<X extends B<A<int>>>() => throw 42;
+//                 ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:21:19: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+// bar3b<X extends A<B<A<int>>>>() => throw 42;
+//                   ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:23:22: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+// class Bar1<X extends B<A<int>>> {
+//                      ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:26:22: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+//   barBar13<X extends B<A<int>>>() => throw 42;
+//                      ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:29:24: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+// class Bar2<X extends A<B<A<int>>>> {
+//                        ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:32:24: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+//   barBar23<X extends A<B<A<int>>>>() => throw 42;
+//                        ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:14:1: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+// B<A<int>> bar1a() => throw 42;
+// ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:15:3: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+// A<B<A<int>>> bar1b() => throw 42;
+//   ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:17:7: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+// bar2a(B<A<int>> x) => throw 42;
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:18:9: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+// bar2b(A<B<A<int>>> x) => throw 42;
+//         ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:24:3: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+//   B<A<int>> barBar11() => throw 42;
+//   ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:25:12: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+//   barBar12(B<A<int>> x) => throw 42;
+//            ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:30:5: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+//   A<B<A<int>>> barBar21() => throw 42;
+//     ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:31:14: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+//   barBar22(A<B<A<int>>> x) => throw 42;
+//              ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:35:16: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+// typedef Baz1 = B<A<int>>;
+//                ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:36:18: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+// typedef Baz2 = A<B<A<int>>>;
+//                  ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:10:3: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+//   B<A<int>> x1;
+//   ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:11:5: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+//   A<B<A<int>>> x2;
+//     ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef B<X extends self::A<X> = self::A<dynamic>> = self::A<X>;
+typedef Baz1 = self::A<self::A<core::int>>;
+typedef Baz2 = self::A<self::A<self::A<core::int>>>;
+class A<T extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::A<self::A::T%>
+    : super core::Object::•()
+    ;
+}
+class Bar1<X extends self::A<self::A<core::int>> = self::A<self::A<core::int>>> extends core::Object {
+  synthetic constructor •() → self::Bar1<self::Bar1::X>
+    : super core::Object::•()
+    ;
+  method barBar11() → self::A<self::A<core::int>>
+    return throw 42;
+  method barBar12(self::A<self::A<core::int>> x) → dynamic
+    return throw 42;
+  method barBar13<X extends self::A<self::A<core::int>> = self::A<self::A<core::int>>>() → dynamic
+    return throw 42;
+}
+class Bar2<X extends self::A<self::A<self::A<core::int>>> = self::A<self::A<self::A<core::int>>>> extends core::Object {
+  synthetic constructor •() → self::Bar2<self::Bar2::X>
+    : super core::Object::•()
+    ;
+  method barBar21() → self::A<self::A<self::A<core::int>>>
+    return throw 42;
+  method barBar22(self::A<self::A<self::A<core::int>>> x) → dynamic
+    return throw 42;
+  method barBar23<X extends self::A<self::A<self::A<core::int>>> = self::A<self::A<self::A<core::int>>>>() → dynamic
+    return throw 42;
+}
+static method foo() → dynamic {
+  self::A<self::A<core::int>> x1;
+  self::A<self::A<self::A<core::int>>> x2;
+}
+static method bar1a() → self::A<self::A<core::int>>
+  return throw 42;
+static method bar1b() → self::A<self::A<self::A<core::int>>>
+  return throw 42;
+static method bar2a(self::A<self::A<core::int>> x) → dynamic
+  return throw 42;
+static method bar2b(self::A<self::A<self::A<core::int>>> x) → dynamic
+  return throw 42;
+static method bar3a<X extends self::A<self::A<core::int>> = self::A<self::A<core::int>>>() → dynamic
+  return throw 42;
+static method bar3b<X extends self::A<self::A<self::A<core::int>>> = self::A<self::A<self::A<core::int>>>>() → dynamic
+  return throw 42;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart.weak.outline.expect b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart.weak.outline.expect
new file mode 100644
index 0000000..e66dde1
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart.weak.outline.expect
@@ -0,0 +1,194 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:20:17: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+// bar3a<X extends B<A<int>>>() => throw 42;
+//                 ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:21:19: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+// bar3b<X extends A<B<A<int>>>>() => throw 42;
+//                   ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:23:22: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+// class Bar1<X extends B<A<int>>> {
+//                      ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:26:22: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+//   barBar13<X extends B<A<int>>>() => throw 42;
+//                      ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:29:24: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+// class Bar2<X extends A<B<A<int>>>> {
+//                        ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:32:24: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+//   barBar23<X extends A<B<A<int>>>>() => throw 42;
+//                        ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:14:1: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+// B<A<int>> bar1a() => throw 42;
+// ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:15:3: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+// A<B<A<int>>> bar1b() => throw 42;
+//   ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:17:7: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+// bar2a(B<A<int>> x) => throw 42;
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:18:9: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+// bar2b(A<B<A<int>>> x) => throw 42;
+//         ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:24:3: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+//   B<A<int>> barBar11() => throw 42;
+//   ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:25:12: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+//   barBar12(B<A<int>> x) => throw 42;
+//            ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:30:5: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+//   A<B<A<int>>> barBar21() => throw 42;
+//     ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:31:14: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+//   barBar22(A<B<A<int>>> x) => throw 42;
+//              ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:35:16: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+// typedef Baz1 = B<A<int>>;
+//                ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:36:18: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+// typedef Baz2 = A<B<A<int>>>;
+//                  ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef B<X extends self::A<X> = self::A<dynamic>> = self::A<X>;
+typedef Baz1 = self::A<self::A<core::int>>;
+typedef Baz2 = self::A<self::A<self::A<core::int>>>;
+class A<T extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::A<self::A::T%>
+    ;
+}
+class Bar1<X extends self::A<self::A<core::int>> = self::A<self::A<core::int>>> extends core::Object {
+  synthetic constructor •() → self::Bar1<self::Bar1::X>
+    ;
+  method barBar11() → self::A<self::A<core::int>>
+    ;
+  method barBar12(self::A<self::A<core::int>> x) → dynamic
+    ;
+  method barBar13<X extends self::A<self::A<core::int>> = self::A<self::A<core::int>>>() → dynamic
+    ;
+}
+class Bar2<X extends self::A<self::A<self::A<core::int>>> = self::A<self::A<self::A<core::int>>>> extends core::Object {
+  synthetic constructor •() → self::Bar2<self::Bar2::X>
+    ;
+  method barBar21() → self::A<self::A<self::A<core::int>>>
+    ;
+  method barBar22(self::A<self::A<self::A<core::int>>> x) → dynamic
+    ;
+  method barBar23<X extends self::A<self::A<self::A<core::int>>> = self::A<self::A<self::A<core::int>>>>() → dynamic
+    ;
+}
+static method foo() → dynamic
+  ;
+static method bar1a() → self::A<self::A<core::int>>
+  ;
+static method bar1b() → self::A<self::A<self::A<core::int>>>
+  ;
+static method bar2a(self::A<self::A<core::int>> x) → dynamic
+  ;
+static method bar2b(self::A<self::A<self::A<core::int>>> x) → dynamic
+  ;
+static method bar3a<X extends self::A<self::A<core::int>> = self::A<self::A<core::int>>>() → dynamic
+  ;
+static method bar3b<X extends self::A<self::A<self::A<core::int>>> = self::A<self::A<self::A<core::int>>>>() → dynamic
+  ;
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart.weak.transformed.expect b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart.weak.transformed.expect
new file mode 100644
index 0000000..7506643
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart.weak.transformed.expect
@@ -0,0 +1,216 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:20:17: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+// bar3a<X extends B<A<int>>>() => throw 42;
+//                 ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:21:19: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+// bar3b<X extends A<B<A<int>>>>() => throw 42;
+//                   ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:23:22: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+// class Bar1<X extends B<A<int>>> {
+//                      ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:26:22: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+//   barBar13<X extends B<A<int>>>() => throw 42;
+//                      ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:29:24: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+// class Bar2<X extends A<B<A<int>>>> {
+//                        ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:32:24: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+//   barBar23<X extends A<B<A<int>>>>() => throw 42;
+//                        ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:14:1: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+// B<A<int>> bar1a() => throw 42;
+// ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:15:3: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+// A<B<A<int>>> bar1b() => throw 42;
+//   ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:17:7: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+// bar2a(B<A<int>> x) => throw 42;
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:18:9: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+// bar2b(A<B<A<int>>> x) => throw 42;
+//         ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:24:3: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+//   B<A<int>> barBar11() => throw 42;
+//   ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:25:12: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+//   barBar12(B<A<int>> x) => throw 42;
+//            ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:30:5: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+//   A<B<A<int>>> barBar21() => throw 42;
+//     ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:31:14: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+//   barBar22(A<B<A<int>>> x) => throw 42;
+//              ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:35:16: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+// typedef Baz1 = B<A<int>>;
+//                ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:36:18: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+// typedef Baz2 = A<B<A<int>>>;
+//                  ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:10:3: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+//   B<A<int>> x1;
+//   ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:11:5: Error: Type argument 'A<int>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'B'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+//   A<B<A<int>>> x2;
+//     ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends A<X>> = A<X>;
+//           ^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef B<X extends self::A<X> = self::A<dynamic>> = self::A<X>;
+typedef Baz1 = self::A<self::A<core::int>>;
+typedef Baz2 = self::A<self::A<self::A<core::int>>>;
+class A<T extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::A<self::A::T%>
+    : super core::Object::•()
+    ;
+}
+class Bar1<X extends self::A<self::A<core::int>> = self::A<self::A<core::int>>> extends core::Object {
+  synthetic constructor •() → self::Bar1<self::Bar1::X>
+    : super core::Object::•()
+    ;
+  method barBar11() → self::A<self::A<core::int>>
+    return throw 42;
+  method barBar12(self::A<self::A<core::int>> x) → dynamic
+    return throw 42;
+  method barBar13<X extends self::A<self::A<core::int>> = self::A<self::A<core::int>>>() → dynamic
+    return throw 42;
+}
+class Bar2<X extends self::A<self::A<self::A<core::int>>> = self::A<self::A<self::A<core::int>>>> extends core::Object {
+  synthetic constructor •() → self::Bar2<self::Bar2::X>
+    : super core::Object::•()
+    ;
+  method barBar21() → self::A<self::A<self::A<core::int>>>
+    return throw 42;
+  method barBar22(self::A<self::A<self::A<core::int>>> x) → dynamic
+    return throw 42;
+  method barBar23<X extends self::A<self::A<self::A<core::int>>> = self::A<self::A<self::A<core::int>>>>() → dynamic
+    return throw 42;
+}
+static method foo() → dynamic {
+  self::A<self::A<core::int>> x1;
+  self::A<self::A<self::A<core::int>>> x2;
+}
+static method bar1a() → self::A<self::A<core::int>>
+  return throw 42;
+static method bar1b() → self::A<self::A<self::A<core::int>>>
+  return throw 42;
+static method bar2a(self::A<self::A<core::int>> x) → dynamic
+  return throw 42;
+static method bar2b(self::A<self::A<self::A<core::int>>> x) → dynamic
+  return throw 42;
+static method bar3a<X extends self::A<self::A<core::int>> = self::A<self::A<core::int>>>() → dynamic
+  return throw 42;
+static method bar3b<X extends self::A<self::A<self::A<core::int>>> = self::A<self::A<self::A<core::int>>>>() → dynamic
+  return throw 42;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_in_typedef.dart b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_in_typedef.dart
new file mode 100644
index 0000000..1317c74
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_in_typedef.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+foo() {
+  A<String> a;
+}
+
+typedef A<X extends int> = B<String>;
+typedef B<X extends int> = C<String>;
+typedef C<X extends int> = X;
+
+main() {}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_in_typedef.dart.strong.expect b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_in_typedef.dart.strong.expect
new file mode 100644
index 0000000..2b7816b
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_in_typedef.dart.strong.expect
@@ -0,0 +1,38 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_in_typedef.dart:10:28: Error: Type argument 'String' doesn't conform to the bound 'int' of the type variable 'X' on 'C'.
+// Try changing type arguments so that they conform to the bounds.
+// typedef B<X extends int> = C<String>;
+//                            ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_in_typedef.dart:11:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef C<X extends int> = X;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_in_typedef.dart:9:28: Error: Type argument 'String' doesn't conform to the bound 'int' of the type variable 'X' on 'B'.
+// Try changing type arguments so that they conform to the bounds.
+// typedef A<X extends int> = B<String>;
+//                            ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_in_typedef.dart:10:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends int> = C<String>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_in_typedef.dart:6:3: Error: Type argument 'String' doesn't conform to the bound 'int' of the type variable 'X' on 'A'.
+// Try changing type arguments so that they conform to the bounds.
+//   A<String> a;
+//   ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_in_typedef.dart:9:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef A<X extends int> = B<String>;
+//           ^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef A<unrelated X extends core::int = core::int> = core::String;
+typedef B<unrelated X extends core::int = core::int> = core::String;
+typedef C<X extends core::int = core::int> = X;
+static method foo() → dynamic {
+  core::String a;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_in_typedef.dart.strong.transformed.expect b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_in_typedef.dart.strong.transformed.expect
new file mode 100644
index 0000000..2b7816b
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_in_typedef.dart.strong.transformed.expect
@@ -0,0 +1,38 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_in_typedef.dart:10:28: Error: Type argument 'String' doesn't conform to the bound 'int' of the type variable 'X' on 'C'.
+// Try changing type arguments so that they conform to the bounds.
+// typedef B<X extends int> = C<String>;
+//                            ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_in_typedef.dart:11:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef C<X extends int> = X;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_in_typedef.dart:9:28: Error: Type argument 'String' doesn't conform to the bound 'int' of the type variable 'X' on 'B'.
+// Try changing type arguments so that they conform to the bounds.
+// typedef A<X extends int> = B<String>;
+//                            ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_in_typedef.dart:10:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends int> = C<String>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_in_typedef.dart:6:3: Error: Type argument 'String' doesn't conform to the bound 'int' of the type variable 'X' on 'A'.
+// Try changing type arguments so that they conform to the bounds.
+//   A<String> a;
+//   ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_in_typedef.dart:9:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef A<X extends int> = B<String>;
+//           ^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef A<unrelated X extends core::int = core::int> = core::String;
+typedef B<unrelated X extends core::int = core::int> = core::String;
+typedef C<X extends core::int = core::int> = X;
+static method foo() → dynamic {
+  core::String a;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_in_typedef.dart.textual_outline.expect b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_in_typedef.dart.textual_outline.expect
new file mode 100644
index 0000000..ebe8a0b
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_in_typedef.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+foo() {}
+typedef A<X extends int> = B<String>;
+typedef B<X extends int> = C<String>;
+typedef C<X extends int> = X;
+main() {}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_in_typedef.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_in_typedef.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5455c3c
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_in_typedef.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+foo() {}
+main() {}
+typedef A<X extends int> = B<String>;
+typedef B<X extends int> = C<String>;
+typedef C<X extends int> = X;
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_in_typedef.dart.weak.expect b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_in_typedef.dart.weak.expect
new file mode 100644
index 0000000..2b7816b
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_in_typedef.dart.weak.expect
@@ -0,0 +1,38 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_in_typedef.dart:10:28: Error: Type argument 'String' doesn't conform to the bound 'int' of the type variable 'X' on 'C'.
+// Try changing type arguments so that they conform to the bounds.
+// typedef B<X extends int> = C<String>;
+//                            ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_in_typedef.dart:11:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef C<X extends int> = X;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_in_typedef.dart:9:28: Error: Type argument 'String' doesn't conform to the bound 'int' of the type variable 'X' on 'B'.
+// Try changing type arguments so that they conform to the bounds.
+// typedef A<X extends int> = B<String>;
+//                            ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_in_typedef.dart:10:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends int> = C<String>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_in_typedef.dart:6:3: Error: Type argument 'String' doesn't conform to the bound 'int' of the type variable 'X' on 'A'.
+// Try changing type arguments so that they conform to the bounds.
+//   A<String> a;
+//   ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_in_typedef.dart:9:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef A<X extends int> = B<String>;
+//           ^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef A<unrelated X extends core::int = core::int> = core::String;
+typedef B<unrelated X extends core::int = core::int> = core::String;
+typedef C<X extends core::int = core::int> = X;
+static method foo() → dynamic {
+  core::String a;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_in_typedef.dart.weak.outline.expect b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_in_typedef.dart.weak.outline.expect
new file mode 100644
index 0000000..0649b07
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_in_typedef.dart.weak.outline.expect
@@ -0,0 +1,30 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_in_typedef.dart:10:28: Error: Type argument 'String' doesn't conform to the bound 'int' of the type variable 'X' on 'C'.
+// Try changing type arguments so that they conform to the bounds.
+// typedef B<X extends int> = C<String>;
+//                            ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_in_typedef.dart:11:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef C<X extends int> = X;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_in_typedef.dart:9:28: Error: Type argument 'String' doesn't conform to the bound 'int' of the type variable 'X' on 'B'.
+// Try changing type arguments so that they conform to the bounds.
+// typedef A<X extends int> = B<String>;
+//                            ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_in_typedef.dart:10:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends int> = C<String>;
+//           ^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef A<unrelated X extends core::int = core::int> = core::String;
+typedef B<unrelated X extends core::int = core::int> = core::String;
+typedef C<X extends core::int = core::int> = X;
+static method foo() → dynamic
+  ;
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_in_typedef.dart.weak.transformed.expect b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_in_typedef.dart.weak.transformed.expect
new file mode 100644
index 0000000..2b7816b
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_in_typedef.dart.weak.transformed.expect
@@ -0,0 +1,38 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_in_typedef.dart:10:28: Error: Type argument 'String' doesn't conform to the bound 'int' of the type variable 'X' on 'C'.
+// Try changing type arguments so that they conform to the bounds.
+// typedef B<X extends int> = C<String>;
+//                            ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_in_typedef.dart:11:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef C<X extends int> = X;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_in_typedef.dart:9:28: Error: Type argument 'String' doesn't conform to the bound 'int' of the type variable 'X' on 'B'.
+// Try changing type arguments so that they conform to the bounds.
+// typedef A<X extends int> = B<String>;
+//                            ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_in_typedef.dart:10:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends int> = C<String>;
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_in_typedef.dart:6:3: Error: Type argument 'String' doesn't conform to the bound 'int' of the type variable 'X' on 'A'.
+// Try changing type arguments so that they conform to the bounds.
+//   A<String> a;
+//   ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_in_typedef.dart:9:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef A<X extends int> = B<String>;
+//           ^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef A<unrelated X extends core::int = core::int> = core::String;
+typedef B<unrelated X extends core::int = core::int> = core::String;
+typedef C<X extends core::int = core::int> = X;
+static method foo() → dynamic {
+  core::String a;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_no_bodies_lib.dart b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_no_bodies_lib.dart
new file mode 100644
index 0000000..e08489b
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_no_bodies_lib.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for 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 {}
+
+typedef B<X extends String> = A;
+
+class C<Y extends B<int>> {}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_no_bodies_main.dart b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_no_bodies_main.dart
new file mode 100644
index 0000000..0123a2a
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_no_bodies_main.dart
@@ -0,0 +1,7 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import './aliased_checks_no_bodies_lib.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_no_bodies_main.dart.strong.expect b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_no_bodies_main.dart.strong.expect
new file mode 100644
index 0000000..381925d
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_no_bodies_main.dart.strong.expect
@@ -0,0 +1,33 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+
+import "org-dartlang-testcase:///aliased_checks_no_bodies_lib.dart";
+
+static method main() → dynamic {}
+
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_no_bodies_lib.dart:9:19: Error: Type argument 'int' doesn't conform to the bound 'String' of the type variable 'X' on 'B'.
+// Try changing type arguments so that they conform to the bounds.
+// class C<Y extends B<int>> {}
+//                   ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_no_bodies_lib.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends String> = A;
+//           ^
+//
+import self as self2;
+import "dart:core" as core;
+
+typedef B<unrelated X extends core::String = core::String> = self2::A;
+class A extends core::Object {
+  synthetic constructor •() → self2::A
+    : super core::Object::•()
+    ;
+}
+class C<Y extends self2::A = self2::A> extends core::Object {
+  synthetic constructor •() → self2::C<self2::C::Y>
+    : super core::Object::•()
+    ;
+}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_no_bodies_main.dart.strong.transformed.expect b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_no_bodies_main.dart.strong.transformed.expect
new file mode 100644
index 0000000..381925d
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_no_bodies_main.dart.strong.transformed.expect
@@ -0,0 +1,33 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+
+import "org-dartlang-testcase:///aliased_checks_no_bodies_lib.dart";
+
+static method main() → dynamic {}
+
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_no_bodies_lib.dart:9:19: Error: Type argument 'int' doesn't conform to the bound 'String' of the type variable 'X' on 'B'.
+// Try changing type arguments so that they conform to the bounds.
+// class C<Y extends B<int>> {}
+//                   ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_no_bodies_lib.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends String> = A;
+//           ^
+//
+import self as self2;
+import "dart:core" as core;
+
+typedef B<unrelated X extends core::String = core::String> = self2::A;
+class A extends core::Object {
+  synthetic constructor •() → self2::A
+    : super core::Object::•()
+    ;
+}
+class C<Y extends self2::A = self2::A> extends core::Object {
+  synthetic constructor •() → self2::C<self2::C::Y>
+    : super core::Object::•()
+    ;
+}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_no_bodies_main.dart.textual_outline.expect b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_no_bodies_main.dart.textual_outline.expect
new file mode 100644
index 0000000..ac7da8d
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_no_bodies_main.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+import './aliased_checks_no_bodies_lib.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_no_bodies_main.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_no_bodies_main.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ac7da8d
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_no_bodies_main.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+import './aliased_checks_no_bodies_lib.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_no_bodies_main.dart.weak.expect b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_no_bodies_main.dart.weak.expect
new file mode 100644
index 0000000..381925d
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_no_bodies_main.dart.weak.expect
@@ -0,0 +1,33 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+
+import "org-dartlang-testcase:///aliased_checks_no_bodies_lib.dart";
+
+static method main() → dynamic {}
+
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_no_bodies_lib.dart:9:19: Error: Type argument 'int' doesn't conform to the bound 'String' of the type variable 'X' on 'B'.
+// Try changing type arguments so that they conform to the bounds.
+// class C<Y extends B<int>> {}
+//                   ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_no_bodies_lib.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends String> = A;
+//           ^
+//
+import self as self2;
+import "dart:core" as core;
+
+typedef B<unrelated X extends core::String = core::String> = self2::A;
+class A extends core::Object {
+  synthetic constructor •() → self2::A
+    : super core::Object::•()
+    ;
+}
+class C<Y extends self2::A = self2::A> extends core::Object {
+  synthetic constructor •() → self2::C<self2::C::Y>
+    : super core::Object::•()
+    ;
+}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_no_bodies_main.dart.weak.outline.expect b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_no_bodies_main.dart.weak.outline.expect
new file mode 100644
index 0000000..ecbd101
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_no_bodies_main.dart.weak.outline.expect
@@ -0,0 +1,32 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+
+import "org-dartlang-testcase:///aliased_checks_no_bodies_lib.dart";
+
+static method main() → dynamic
+  ;
+
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_no_bodies_lib.dart:9:19: Error: Type argument 'int' doesn't conform to the bound 'String' of the type variable 'X' on 'B'.
+// Try changing type arguments so that they conform to the bounds.
+// class C<Y extends B<int>> {}
+//                   ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_no_bodies_lib.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends String> = A;
+//           ^
+//
+import self as self2;
+import "dart:core" as core;
+
+typedef B<unrelated X extends core::String = core::String> = self2::A;
+class A extends core::Object {
+  synthetic constructor •() → self2::A
+    ;
+}
+class C<Y extends self2::A = self2::A> extends core::Object {
+  synthetic constructor •() → self2::C<self2::C::Y>
+    ;
+}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_no_bodies_main.dart.weak.transformed.expect b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_no_bodies_main.dart.weak.transformed.expect
new file mode 100644
index 0000000..381925d
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_no_bodies_main.dart.weak.transformed.expect
@@ -0,0 +1,33 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+
+import "org-dartlang-testcase:///aliased_checks_no_bodies_lib.dart";
+
+static method main() → dynamic {}
+
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_no_bodies_lib.dart:9:19: Error: Type argument 'int' doesn't conform to the bound 'String' of the type variable 'X' on 'B'.
+// Try changing type arguments so that they conform to the bounds.
+// class C<Y extends B<int>> {}
+//                   ^
+// pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_no_bodies_lib.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends String> = A;
+//           ^
+//
+import self as self2;
+import "dart:core" as core;
+
+typedef B<unrelated X extends core::String = core::String> = self2::A;
+class A extends core::Object {
+  synthetic constructor •() → self2::A
+    : super core::Object::•()
+    ;
+}
+class C<Y extends self2::A = self2::A> extends core::Object {
+  synthetic constructor •() → self2::C<self2::C::Y>
+    : super core::Object::•()
+    ;
+}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart.strong.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart.strong.expect
index 8de447c..fb500ca 100644
--- a/pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart.strong.expect
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart.strong.expect
@@ -2,7 +2,7 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart:13:42: Error: The value 'null' can't be assigned to a variable of type 'FutureOr<A>' because 'FutureOr<A>' is not nullable.
+// pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart:13:42: Error: The value 'null' can't be assigned to a variable of type 'FutureOr<A Function()>' because 'FutureOr<A Function()>' is not nullable.
 //  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue41501_lib.dart'.
 //   FutureOr<AAlias> foLegacyNonNullable = null; // error
 //                                          ^
@@ -21,11 +21,11 @@
 typedef AAliasNonNullable = opt::A;
 typedef AAliasNullable = opt::A?;
 static method test() → dynamic {
-  FutureOr<opt::A>foLegacyNonNullable = let final Never #t1 = invalid-expression "pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart:13:42: Error: The value 'null' can't be assigned to a variable of type 'FutureOr<A>' because 'FutureOr<A>' is not nullable.
+  FutureOr<() → opt::A*>foLegacyNonNullable = let final Never #t1 = invalid-expression "pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart:13:42: Error: The value 'null' can't be assigned to a variable of type 'FutureOr<A Function()>' because 'FutureOr<A Function()>' is not nullable.
  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue41501_lib.dart'.
   FutureOr<AAlias> foLegacyNonNullable = null; // error
-                                         ^" in null as{TypeError,ForNonNullableByDefault} FutureOr<opt::A>;
-  FutureOr<opt::A?>foLegacyNullable = null;
+                                         ^" in null as{TypeError,ForNonNullableByDefault} FutureOr<() → opt::A*>;
+  FutureOr<() →? opt::A*>foLegacyNullable = null;
   FutureOr<opt::A>foNonNullable = let final Never #t2 = invalid-expression "pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart:15:47: Error: The value 'null' can't be assigned to a variable of type 'FutureOr<A>' because 'FutureOr<A>' is not nullable.
  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue41501_lib.dart'.
   FutureOr<AAliasNonNullable> foNonNullable = null; // error
@@ -50,7 +50,7 @@
 import "dart:async";
 import "org-dartlang-testcase:///issue41501.dart";
 
-typedef AAlias = opt::A*;
+typedef AAlias = () →* opt::A*;
 class A extends core::Object {
   synthetic constructor •() → opt::A*
     : super core::Object::•()
@@ -67,7 +67,7 @@
   abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
 }
 static method test() → dynamic {
-  FutureOr<opt::A*>* foLegacy = null;
+  FutureOr<() →* opt::A*>* foLegacy = null;
   FutureOr<opt::A*>* foNonNullable = null;
   FutureOr<opt::A*>* foNullable = null;
 }
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart.strong.transformed.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart.strong.transformed.expect
index a59394b..af7457b 100644
--- a/pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart.strong.transformed.expect
@@ -2,7 +2,7 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart:13:42: Error: The value 'null' can't be assigned to a variable of type 'FutureOr<A>' because 'FutureOr<A>' is not nullable.
+// pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart:13:42: Error: The value 'null' can't be assigned to a variable of type 'FutureOr<A Function()>' because 'FutureOr<A Function()>' is not nullable.
 //  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue41501_lib.dart'.
 //   FutureOr<AAlias> foLegacyNonNullable = null; // error
 //                                          ^
@@ -21,11 +21,11 @@
 typedef AAliasNonNullable = opt::A;
 typedef AAliasNullable = opt::A?;
 static method test() → dynamic {
-  FutureOr<opt::A>foLegacyNonNullable = let final Never #t1 = invalid-expression "pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart:13:42: Error: The value 'null' can't be assigned to a variable of type 'FutureOr<A>' because 'FutureOr<A>' is not nullable.
+  FutureOr<() → opt::A*>foLegacyNonNullable = let final Never #t1 = invalid-expression "pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart:13:42: Error: The value 'null' can't be assigned to a variable of type 'FutureOr<A Function()>' because 'FutureOr<A Function()>' is not nullable.
  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue41501_lib.dart'.
   FutureOr<AAlias> foLegacyNonNullable = null; // error
-                                         ^" in let Null #t2 = null in #t2.==(null) ?{FutureOr<opt::A>} #t2 as{TypeError,ForNonNullableByDefault} FutureOr<opt::A> : #t2{FutureOr<opt::A>};
-  FutureOr<opt::A?>foLegacyNullable = null;
+                                         ^" in let Null #t2 = null in #t2.==(null) ?{FutureOr<() → opt::A*>} #t2 as{TypeError,ForNonNullableByDefault} FutureOr<() → opt::A*> : #t2{FutureOr<() → opt::A*>};
+  FutureOr<() →? opt::A*>foLegacyNullable = null;
   FutureOr<opt::A>foNonNullable = let final Never #t3 = invalid-expression "pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart:15:47: Error: The value 'null' can't be assigned to a variable of type 'FutureOr<A>' because 'FutureOr<A>' is not nullable.
  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue41501_lib.dart'.
   FutureOr<AAliasNonNullable> foNonNullable = null; // error
@@ -50,7 +50,7 @@
 import "dart:async";
 import "org-dartlang-testcase:///issue41501.dart";
 
-typedef AAlias = opt::A*;
+typedef AAlias = () →* opt::A*;
 class A extends core::Object {
   synthetic constructor •() → opt::A*
     : super core::Object::•()
@@ -67,7 +67,7 @@
   abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
 }
 static method test() → dynamic {
-  FutureOr<opt::A*>* foLegacy = null;
+  FutureOr<() →* opt::A*>* foLegacy = null;
   FutureOr<opt::A*>* foNonNullable = null;
   FutureOr<opt::A*>* foNullable = null;
 }
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart.textual_outline.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart.textual_outline.expect
index 6c19416..c1f1ec1 100644
--- a/pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart.textual_outline.expect
@@ -1,5 +1,6 @@
 import 'dart:async';
 import 'issue41501_lib.dart';
+
 typedef AAliasNonNullable = A;
 typedef AAliasNullable = A?;
 test() {}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ed74116
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+import 'dart:async';
+import 'issue41501_lib.dart';
+
+main() {}
+test() {}
+typedef AAliasNonNullable = A;
+typedef AAliasNullable = A?;
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart.weak.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart.weak.expect
index c86c3be..a709e0b 100644
--- a/pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart.weak.expect
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart.weak.expect
@@ -2,7 +2,7 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart:13:42: Error: The value 'null' can't be assigned to a variable of type 'FutureOr<A>' because 'FutureOr<A>' is not nullable.
+// pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart:13:42: Error: The value 'null' can't be assigned to a variable of type 'FutureOr<A Function()>' because 'FutureOr<A Function()>' is not nullable.
 //  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue41501_lib.dart'.
 //   FutureOr<AAlias> foLegacyNonNullable = null; // error
 //                                          ^
@@ -21,11 +21,11 @@
 typedef AAliasNonNullable = opt::A;
 typedef AAliasNullable = opt::A?;
 static method test() → dynamic {
-  FutureOr<opt::A>foLegacyNonNullable = let final Never #t1 = invalid-expression "pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart:13:42: Error: The value 'null' can't be assigned to a variable of type 'FutureOr<A>' because 'FutureOr<A>' is not nullable.
+  FutureOr<() → opt::A*>foLegacyNonNullable = let final Never #t1 = invalid-expression "pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart:13:42: Error: The value 'null' can't be assigned to a variable of type 'FutureOr<A Function()>' because 'FutureOr<A Function()>' is not nullable.
  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue41501_lib.dart'.
   FutureOr<AAlias> foLegacyNonNullable = null; // error
-                                         ^" in null as{TypeError,ForNonNullableByDefault} FutureOr<opt::A>;
-  FutureOr<opt::A?>foLegacyNullable = null;
+                                         ^" in null as{TypeError,ForNonNullableByDefault} FutureOr<() → opt::A*>;
+  FutureOr<() →? opt::A*>foLegacyNullable = null;
   FutureOr<opt::A>foNonNullable = let final Never #t2 = invalid-expression "pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart:15:47: Error: The value 'null' can't be assigned to a variable of type 'FutureOr<A>' because 'FutureOr<A>' is not nullable.
  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue41501_lib.dart'.
   FutureOr<AAliasNonNullable> foNonNullable = null; // error
@@ -43,7 +43,7 @@
 import "dart:async";
 import "org-dartlang-testcase:///issue41501.dart";
 
-typedef AAlias = opt::A*;
+typedef AAlias = () →* opt::A*;
 class A extends core::Object {
   synthetic constructor •() → opt::A*
     : super core::Object::•()
@@ -60,7 +60,7 @@
   abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
 }
 static method test() → dynamic {
-  FutureOr<opt::A*>* foLegacy = null;
+  FutureOr<() →* opt::A*>* foLegacy = null;
   FutureOr<opt::A*>* foNonNullable = null;
   FutureOr<opt::A*>* foNullable = null;
 }
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart.weak.outline.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart.weak.outline.expect
index 1b2a115..da69458 100644
--- a/pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart.weak.outline.expect
@@ -19,7 +19,7 @@
 import "dart:async";
 import "org-dartlang-testcase:///issue41501.dart";
 
-typedef AAlias = opt::A*;
+typedef AAlias = () →* opt::A*;
 class A extends core::Object {
   synthetic constructor •() → opt::A*
     ;
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart.weak.transformed.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart.weak.transformed.expect
index b82561c..a75d478 100644
--- a/pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart.weak.transformed.expect
@@ -2,7 +2,7 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart:13:42: Error: The value 'null' can't be assigned to a variable of type 'FutureOr<A>' because 'FutureOr<A>' is not nullable.
+// pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart:13:42: Error: The value 'null' can't be assigned to a variable of type 'FutureOr<A Function()>' because 'FutureOr<A Function()>' is not nullable.
 //  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue41501_lib.dart'.
 //   FutureOr<AAlias> foLegacyNonNullable = null; // error
 //                                          ^
@@ -21,11 +21,11 @@
 typedef AAliasNonNullable = opt::A;
 typedef AAliasNullable = opt::A?;
 static method test() → dynamic {
-  FutureOr<opt::A>foLegacyNonNullable = let final Never #t1 = invalid-expression "pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart:13:42: Error: The value 'null' can't be assigned to a variable of type 'FutureOr<A>' because 'FutureOr<A>' is not nullable.
+  FutureOr<() → opt::A*>foLegacyNonNullable = let final Never #t1 = invalid-expression "pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart:13:42: Error: The value 'null' can't be assigned to a variable of type 'FutureOr<A Function()>' because 'FutureOr<A Function()>' is not nullable.
  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue41501_lib.dart'.
   FutureOr<AAlias> foLegacyNonNullable = null; // error
                                          ^" in null;
-  FutureOr<opt::A?>foLegacyNullable = null;
+  FutureOr<() →? opt::A*>foLegacyNullable = null;
   FutureOr<opt::A>foNonNullable = let final Never #t2 = invalid-expression "pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart:15:47: Error: The value 'null' can't be assigned to a variable of type 'FutureOr<A>' because 'FutureOr<A>' is not nullable.
  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue41501_lib.dart'.
   FutureOr<AAliasNonNullable> foNonNullable = null; // error
@@ -43,7 +43,7 @@
 import "dart:async";
 import "org-dartlang-testcase:///issue41501.dart";
 
-typedef AAlias = opt::A*;
+typedef AAlias = () →* opt::A*;
 class A extends core::Object {
   synthetic constructor •() → opt::A*
     : super core::Object::•()
@@ -60,7 +60,7 @@
   abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
 }
 static method test() → dynamic {
-  FutureOr<opt::A*>* foLegacy = null;
+  FutureOr<() →* opt::A*>* foLegacy = null;
   FutureOr<opt::A*>* foNonNullable = null;
   FutureOr<opt::A*>* foNullable = null;
 }
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue41501_lib.dart b/pkg/front_end/testcases/nonfunction_type_aliases/issue41501_lib.dart
index 09e20d1..e026cd9 100644
--- a/pkg/front_end/testcases/nonfunction_type_aliases/issue41501_lib.dart
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue41501_lib.dart
@@ -11,11 +11,10 @@
 
 class A {}
 
-typedef AAlias = A;
+typedef AAlias = A Function();
 
 test() {
   FutureOr<AAlias> foLegacy = null; // ok
   FutureOr<AAliasNonNullable> foNonNullable = null; // ok
   FutureOr<AAliasNullable> foNullable = null; // ok
 }
-
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue42446.dart.textual_outline.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue42446.dart.textual_outline.expect
index 611ce04..68bc621 100644
--- a/pkg/front_end/testcases/nonfunction_type_aliases/issue42446.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue42446.dart.textual_outline.expect
@@ -1,8 +1,11 @@
 class A<X extends A<X>> {}
+
 typedef B<X extends A<X>> = A<X>;
+
 class A2<X extends A2<X>> {
   factory A2() => throw 42;
 }
+
 typedef B2<X extends A2<X>> = A2<X>;
 foo() {}
 main() {}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue42446.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue42446.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..cfc9006
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue42446.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+class A<X extends A<X>> {}
+
+class A2<X extends A2<X>> {
+  factory A2() => throw 42;
+}
+
+foo() {}
+main() {}
+typedef B<X extends A<X>> = A<X>;
+typedef B2<X extends A2<X>> = A2<X>;
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue45051.dart.textual_outline.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue45051.dart.textual_outline.expect
index 08b1c6f..bbd084e 100644
--- a/pkg/front_end/testcases/nonfunction_type_aliases/issue45051.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue45051.dart.textual_outline.expect
@@ -2,9 +2,12 @@
   factory A() = BAlias;
   factory A.named() = BAlias.named;
 }
+
 typedef BAlias = B;
+
 class B implements A {
   B();
   B.named();
 }
+
 main() {}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue45051.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue45051.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c41fa7b
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue45051.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+class A {
+  factory A() = BAlias;
+  factory A.named() = BAlias.named;
+}
+
+class B implements A {
+  B();
+  B.named();
+}
+
+main() {}
+typedef BAlias = B;
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart b/pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart
new file mode 100644
index 0000000..ed569dc
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart
@@ -0,0 +1,52 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+Type? _capturedTypeArgument;
+
+X captureTypeArgument<X>() {
+  _capturedTypeArgument = X;
+  print("X: $X");
+  throw "Error";
+}
+
+class A<X extends A<X>> {}
+typedef C<X extends A<X>> = A<X>;
+
+void topLevel1<X extends A<X>>(A<X> Function() g) => g();
+
+void topLevel2<X extends C<X>>(C<X> Function() g) => g();
+
+class Class {
+  void instance1<X extends A<X>>(A<X> Function() g) => g();
+
+  void instance2<X extends C<X>>(C<X> Function() g) => g();
+
+  void test() {
+    void local1<X extends A<X>>(A<X> Function() g) => g();
+    void local2<X extends C<X>>(C<X> Function() g) => g();
+
+    var f1 = local1;
+    var f2 = local2;
+
+    new A();
+    new C();
+    f1(() => captureTypeArgument());
+    f2(() => captureTypeArgument());
+    local1(() => captureTypeArgument());
+    local2(() => captureTypeArgument());
+    topLevel1(() => captureTypeArgument());
+    topLevel2(() => captureTypeArgument());
+    instance1(() => captureTypeArgument());
+    instance2(() => captureTypeArgument());
+  }
+}
+
+class Subclass extends Class {
+  void test() {
+    super.instance1(() => captureTypeArgument());
+    super.instance2(() => captureTypeArgument());
+  }
+}
+
+main() {}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart.strong.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart.strong.expect
new file mode 100644
index 0000000..15fe25b
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart.strong.expect
@@ -0,0 +1,160 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:32:9: Error: Inferred type argument 'A<Object?>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'A'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart'.
+//  - 'Object' is from 'dart:core'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//     new A();
+//         ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:13:9: Context: This is the type variable whose bound isn't conformed to.
+// class A<X extends A<X>> {}
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:33:9: Error: Inferred type argument 'A<Object?>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'A'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart'.
+//  - 'Object' is from 'dart:core'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//     new C();
+//         ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:13:9: Context: This is the type variable whose bound isn't conformed to.
+// class A<X extends A<X>> {}
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:34:7: Error: Inferred type argument 'Object?' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'call'.
+//  - 'Object' is from 'dart:core'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//     f1(() => captureTypeArgument());
+//       ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:35:7: Error: Inferred type argument 'Object?' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'call'.
+//  - 'Object' is from 'dart:core'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//     f2(() => captureTypeArgument());
+//       ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:36:11: Error: Inferred type argument 'Object?' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'local1'.
+//  - 'Object' is from 'dart:core'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//     local1(() => captureTypeArgument());
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:37:11: Error: Inferred type argument 'Object?' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'local2'.
+//  - 'Object' is from 'dart:core'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//     local2(() => captureTypeArgument());
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:38:5: Error: Inferred type argument 'Object?' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'topLevel1'.
+//  - 'Object' is from 'dart:core'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//     topLevel1(() => captureTypeArgument());
+//     ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:16:16: Context: This is the type variable whose bound isn't conformed to.
+// void topLevel1<X extends A<X>>(A<X> Function() g) => g();
+//                ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:39:5: Error: Inferred type argument 'Object?' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'topLevel2'.
+//  - 'Object' is from 'dart:core'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//     topLevel2(() => captureTypeArgument());
+//     ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:18:16: Context: This is the type variable whose bound isn't conformed to.
+// void topLevel2<X extends C<X>>(C<X> Function() g) => g();
+//                ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:40:5: Error: Inferred type argument 'Object?' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'Class.instance1'.
+//  - 'Object' is from 'dart:core'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart'.
+//  - 'Class' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//     instance1(() => captureTypeArgument());
+//     ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:41:5: Error: Inferred type argument 'Object?' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'Class.instance2'.
+//  - 'Object' is from 'dart:core'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart'.
+//  - 'Class' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//     instance2(() => captureTypeArgument());
+//     ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:47:11: Error: Inferred type argument 'Object?' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'Subclass.instance1'.
+//  - 'Object' is from 'dart:core'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart'.
+//  - 'Subclass' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//     super.instance1(() => captureTypeArgument());
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:48:11: Error: Inferred type argument 'Object?' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'Subclass.instance2'.
+//  - 'Object' is from 'dart:core'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart'.
+//  - 'Subclass' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//     super.instance2(() => captureTypeArgument());
+//           ^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef C<X extends self::A<X> = self::A<dynamic>> = self::A<X>;
+class A<X extends self::A<self::A::X> = self::A<dynamic>> extends core::Object {
+  synthetic constructor •() → self::A<self::A::X>
+    : super core::Object::•()
+    ;
+}
+class Class extends core::Object {
+  synthetic constructor •() → self::Class
+    : super core::Object::•()
+    ;
+  method instance1<X extends self::A<self::Class::instance1::X> = self::A<dynamic>>(() → self::A<self::Class::instance1::X> g) → void
+    return g.call();
+  method instance2<X extends self::A<self::Class::instance2::X> = self::A<dynamic>>(() → self::A<self::Class::instance2::X> g) → void
+    return g.call();
+  method test() → void {
+    function local1<X extends self::A<X> = self::A<dynamic>>(() → self::A<X> g) → void
+      return g.call();
+    function local2<X extends self::A<X> = self::A<dynamic>>(() → self::A<X> g) → void
+      return g.call();
+    <X extends self::A<X> = self::A<dynamic>>(() → self::A<X>) → void f1 = local1;
+    <X extends self::A<X> = self::A<dynamic>>(() → self::A<X>) → void f2 = local2;
+    new self::A::•<self::A<core::Object?>>();
+    new self::A::•<self::A<core::Object?>>();
+    f1.call<core::Object?>(() → self::A<core::Object?> => self::captureTypeArgument<self::A<core::Object?>>());
+    f2.call<core::Object?>(() → self::A<core::Object?> => self::captureTypeArgument<self::A<core::Object?>>());
+    local1.call<core::Object?>(() → self::A<core::Object?> => self::captureTypeArgument<self::A<core::Object?>>());
+    local2.call<core::Object?>(() → self::A<core::Object?> => self::captureTypeArgument<self::A<core::Object?>>());
+    self::topLevel1<core::Object?>(() → self::A<core::Object?> => self::captureTypeArgument<self::A<core::Object?>>());
+    self::topLevel2<core::Object?>(() → self::A<core::Object?> => self::captureTypeArgument<self::A<core::Object?>>());
+    this.{self::Class::instance1}<core::Object?>(() → self::A<core::Object?> => self::captureTypeArgument<self::A<core::Object?>>());
+    this.{self::Class::instance2}<core::Object?>(() → self::A<core::Object?> => self::captureTypeArgument<self::A<core::Object?>>());
+  }
+}
+class Subclass extends self::Class {
+  synthetic constructor •() → self::Subclass
+    : super self::Class::•()
+    ;
+  method test() → void {
+    super.{self::Class::instance1}<core::Object?>(() → self::A<core::Object?> => self::captureTypeArgument<self::A<core::Object?>>());
+    super.{self::Class::instance2}<core::Object?>(() → self::A<core::Object?> => self::captureTypeArgument<self::A<core::Object?>>());
+  }
+}
+static field core::Type? _capturedTypeArgument;
+static method captureTypeArgument<X extends core::Object? = dynamic>() → self::captureTypeArgument::X% {
+  self::_capturedTypeArgument = self::captureTypeArgument::X%;
+  core::print("X: ${self::captureTypeArgument::X%}");
+  throw "Error";
+}
+static method topLevel1<X extends self::A<self::topLevel1::X> = self::A<dynamic>>(() → self::A<self::topLevel1::X> g) → void
+  return g.call();
+static method topLevel2<X extends self::A<self::topLevel2::X> = self::A<dynamic>>(() → self::A<self::topLevel2::X> g) → void
+  return g.call();
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart.strong.transformed.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart.strong.transformed.expect
new file mode 100644
index 0000000..15fe25b
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart.strong.transformed.expect
@@ -0,0 +1,160 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:32:9: Error: Inferred type argument 'A<Object?>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'A'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart'.
+//  - 'Object' is from 'dart:core'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//     new A();
+//         ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:13:9: Context: This is the type variable whose bound isn't conformed to.
+// class A<X extends A<X>> {}
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:33:9: Error: Inferred type argument 'A<Object?>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'A'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart'.
+//  - 'Object' is from 'dart:core'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//     new C();
+//         ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:13:9: Context: This is the type variable whose bound isn't conformed to.
+// class A<X extends A<X>> {}
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:34:7: Error: Inferred type argument 'Object?' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'call'.
+//  - 'Object' is from 'dart:core'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//     f1(() => captureTypeArgument());
+//       ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:35:7: Error: Inferred type argument 'Object?' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'call'.
+//  - 'Object' is from 'dart:core'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//     f2(() => captureTypeArgument());
+//       ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:36:11: Error: Inferred type argument 'Object?' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'local1'.
+//  - 'Object' is from 'dart:core'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//     local1(() => captureTypeArgument());
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:37:11: Error: Inferred type argument 'Object?' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'local2'.
+//  - 'Object' is from 'dart:core'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//     local2(() => captureTypeArgument());
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:38:5: Error: Inferred type argument 'Object?' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'topLevel1'.
+//  - 'Object' is from 'dart:core'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//     topLevel1(() => captureTypeArgument());
+//     ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:16:16: Context: This is the type variable whose bound isn't conformed to.
+// void topLevel1<X extends A<X>>(A<X> Function() g) => g();
+//                ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:39:5: Error: Inferred type argument 'Object?' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'topLevel2'.
+//  - 'Object' is from 'dart:core'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//     topLevel2(() => captureTypeArgument());
+//     ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:18:16: Context: This is the type variable whose bound isn't conformed to.
+// void topLevel2<X extends C<X>>(C<X> Function() g) => g();
+//                ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:40:5: Error: Inferred type argument 'Object?' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'Class.instance1'.
+//  - 'Object' is from 'dart:core'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart'.
+//  - 'Class' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//     instance1(() => captureTypeArgument());
+//     ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:41:5: Error: Inferred type argument 'Object?' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'Class.instance2'.
+//  - 'Object' is from 'dart:core'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart'.
+//  - 'Class' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//     instance2(() => captureTypeArgument());
+//     ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:47:11: Error: Inferred type argument 'Object?' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'Subclass.instance1'.
+//  - 'Object' is from 'dart:core'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart'.
+//  - 'Subclass' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//     super.instance1(() => captureTypeArgument());
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:48:11: Error: Inferred type argument 'Object?' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'Subclass.instance2'.
+//  - 'Object' is from 'dart:core'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart'.
+//  - 'Subclass' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//     super.instance2(() => captureTypeArgument());
+//           ^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef C<X extends self::A<X> = self::A<dynamic>> = self::A<X>;
+class A<X extends self::A<self::A::X> = self::A<dynamic>> extends core::Object {
+  synthetic constructor •() → self::A<self::A::X>
+    : super core::Object::•()
+    ;
+}
+class Class extends core::Object {
+  synthetic constructor •() → self::Class
+    : super core::Object::•()
+    ;
+  method instance1<X extends self::A<self::Class::instance1::X> = self::A<dynamic>>(() → self::A<self::Class::instance1::X> g) → void
+    return g.call();
+  method instance2<X extends self::A<self::Class::instance2::X> = self::A<dynamic>>(() → self::A<self::Class::instance2::X> g) → void
+    return g.call();
+  method test() → void {
+    function local1<X extends self::A<X> = self::A<dynamic>>(() → self::A<X> g) → void
+      return g.call();
+    function local2<X extends self::A<X> = self::A<dynamic>>(() → self::A<X> g) → void
+      return g.call();
+    <X extends self::A<X> = self::A<dynamic>>(() → self::A<X>) → void f1 = local1;
+    <X extends self::A<X> = self::A<dynamic>>(() → self::A<X>) → void f2 = local2;
+    new self::A::•<self::A<core::Object?>>();
+    new self::A::•<self::A<core::Object?>>();
+    f1.call<core::Object?>(() → self::A<core::Object?> => self::captureTypeArgument<self::A<core::Object?>>());
+    f2.call<core::Object?>(() → self::A<core::Object?> => self::captureTypeArgument<self::A<core::Object?>>());
+    local1.call<core::Object?>(() → self::A<core::Object?> => self::captureTypeArgument<self::A<core::Object?>>());
+    local2.call<core::Object?>(() → self::A<core::Object?> => self::captureTypeArgument<self::A<core::Object?>>());
+    self::topLevel1<core::Object?>(() → self::A<core::Object?> => self::captureTypeArgument<self::A<core::Object?>>());
+    self::topLevel2<core::Object?>(() → self::A<core::Object?> => self::captureTypeArgument<self::A<core::Object?>>());
+    this.{self::Class::instance1}<core::Object?>(() → self::A<core::Object?> => self::captureTypeArgument<self::A<core::Object?>>());
+    this.{self::Class::instance2}<core::Object?>(() → self::A<core::Object?> => self::captureTypeArgument<self::A<core::Object?>>());
+  }
+}
+class Subclass extends self::Class {
+  synthetic constructor •() → self::Subclass
+    : super self::Class::•()
+    ;
+  method test() → void {
+    super.{self::Class::instance1}<core::Object?>(() → self::A<core::Object?> => self::captureTypeArgument<self::A<core::Object?>>());
+    super.{self::Class::instance2}<core::Object?>(() → self::A<core::Object?> => self::captureTypeArgument<self::A<core::Object?>>());
+  }
+}
+static field core::Type? _capturedTypeArgument;
+static method captureTypeArgument<X extends core::Object? = dynamic>() → self::captureTypeArgument::X% {
+  self::_capturedTypeArgument = self::captureTypeArgument::X%;
+  core::print("X: ${self::captureTypeArgument::X%}");
+  throw "Error";
+}
+static method topLevel1<X extends self::A<self::topLevel1::X> = self::A<dynamic>>(() → self::A<self::topLevel1::X> g) → void
+  return g.call();
+static method topLevel2<X extends self::A<self::topLevel2::X> = self::A<dynamic>>(() → self::A<self::topLevel2::X> g) → void
+  return g.call();
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart.textual_outline.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart.textual_outline.expect
new file mode 100644
index 0000000..4172321
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart.textual_outline.expect
@@ -0,0 +1,20 @@
+Type? _capturedTypeArgument;
+X captureTypeArgument<X>() {}
+
+class A<X extends A<X>> {}
+
+typedef C<X extends A<X>> = A<X>;
+void topLevel1<X extends A<X>>(A<X> Function() g) => g();
+void topLevel2<X extends C<X>>(C<X> Function() g) => g();
+
+class Class {
+  void instance1<X extends A<X>>(A<X> Function() g) => g();
+  void instance2<X extends C<X>>(C<X> Function() g) => g();
+  void test() {}
+}
+
+class Subclass extends Class {
+  void test() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0f69476
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart.textual_outline_modelled.expect
@@ -0,0 +1,19 @@
+Type? _capturedTypeArgument;
+X captureTypeArgument<X>() {}
+
+class A<X extends A<X>> {}
+
+class Class {
+  void instance1<X extends A<X>>(A<X> Function() g) => g();
+  void instance2<X extends C<X>>(C<X> Function() g) => g();
+  void test() {}
+}
+
+class Subclass extends Class {
+  void test() {}
+}
+
+main() {}
+typedef C<X extends A<X>> = A<X>;
+void topLevel1<X extends A<X>>(A<X> Function() g) => g();
+void topLevel2<X extends C<X>>(C<X> Function() g) => g();
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart.weak.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart.weak.expect
new file mode 100644
index 0000000..15fe25b
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart.weak.expect
@@ -0,0 +1,160 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:32:9: Error: Inferred type argument 'A<Object?>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'A'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart'.
+//  - 'Object' is from 'dart:core'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//     new A();
+//         ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:13:9: Context: This is the type variable whose bound isn't conformed to.
+// class A<X extends A<X>> {}
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:33:9: Error: Inferred type argument 'A<Object?>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'A'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart'.
+//  - 'Object' is from 'dart:core'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//     new C();
+//         ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:13:9: Context: This is the type variable whose bound isn't conformed to.
+// class A<X extends A<X>> {}
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:34:7: Error: Inferred type argument 'Object?' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'call'.
+//  - 'Object' is from 'dart:core'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//     f1(() => captureTypeArgument());
+//       ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:35:7: Error: Inferred type argument 'Object?' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'call'.
+//  - 'Object' is from 'dart:core'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//     f2(() => captureTypeArgument());
+//       ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:36:11: Error: Inferred type argument 'Object?' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'local1'.
+//  - 'Object' is from 'dart:core'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//     local1(() => captureTypeArgument());
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:37:11: Error: Inferred type argument 'Object?' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'local2'.
+//  - 'Object' is from 'dart:core'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//     local2(() => captureTypeArgument());
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:38:5: Error: Inferred type argument 'Object?' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'topLevel1'.
+//  - 'Object' is from 'dart:core'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//     topLevel1(() => captureTypeArgument());
+//     ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:16:16: Context: This is the type variable whose bound isn't conformed to.
+// void topLevel1<X extends A<X>>(A<X> Function() g) => g();
+//                ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:39:5: Error: Inferred type argument 'Object?' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'topLevel2'.
+//  - 'Object' is from 'dart:core'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//     topLevel2(() => captureTypeArgument());
+//     ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:18:16: Context: This is the type variable whose bound isn't conformed to.
+// void topLevel2<X extends C<X>>(C<X> Function() g) => g();
+//                ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:40:5: Error: Inferred type argument 'Object?' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'Class.instance1'.
+//  - 'Object' is from 'dart:core'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart'.
+//  - 'Class' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//     instance1(() => captureTypeArgument());
+//     ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:41:5: Error: Inferred type argument 'Object?' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'Class.instance2'.
+//  - 'Object' is from 'dart:core'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart'.
+//  - 'Class' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//     instance2(() => captureTypeArgument());
+//     ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:47:11: Error: Inferred type argument 'Object?' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'Subclass.instance1'.
+//  - 'Object' is from 'dart:core'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart'.
+//  - 'Subclass' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//     super.instance1(() => captureTypeArgument());
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:48:11: Error: Inferred type argument 'Object?' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'Subclass.instance2'.
+//  - 'Object' is from 'dart:core'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart'.
+//  - 'Subclass' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//     super.instance2(() => captureTypeArgument());
+//           ^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef C<X extends self::A<X> = self::A<dynamic>> = self::A<X>;
+class A<X extends self::A<self::A::X> = self::A<dynamic>> extends core::Object {
+  synthetic constructor •() → self::A<self::A::X>
+    : super core::Object::•()
+    ;
+}
+class Class extends core::Object {
+  synthetic constructor •() → self::Class
+    : super core::Object::•()
+    ;
+  method instance1<X extends self::A<self::Class::instance1::X> = self::A<dynamic>>(() → self::A<self::Class::instance1::X> g) → void
+    return g.call();
+  method instance2<X extends self::A<self::Class::instance2::X> = self::A<dynamic>>(() → self::A<self::Class::instance2::X> g) → void
+    return g.call();
+  method test() → void {
+    function local1<X extends self::A<X> = self::A<dynamic>>(() → self::A<X> g) → void
+      return g.call();
+    function local2<X extends self::A<X> = self::A<dynamic>>(() → self::A<X> g) → void
+      return g.call();
+    <X extends self::A<X> = self::A<dynamic>>(() → self::A<X>) → void f1 = local1;
+    <X extends self::A<X> = self::A<dynamic>>(() → self::A<X>) → void f2 = local2;
+    new self::A::•<self::A<core::Object?>>();
+    new self::A::•<self::A<core::Object?>>();
+    f1.call<core::Object?>(() → self::A<core::Object?> => self::captureTypeArgument<self::A<core::Object?>>());
+    f2.call<core::Object?>(() → self::A<core::Object?> => self::captureTypeArgument<self::A<core::Object?>>());
+    local1.call<core::Object?>(() → self::A<core::Object?> => self::captureTypeArgument<self::A<core::Object?>>());
+    local2.call<core::Object?>(() → self::A<core::Object?> => self::captureTypeArgument<self::A<core::Object?>>());
+    self::topLevel1<core::Object?>(() → self::A<core::Object?> => self::captureTypeArgument<self::A<core::Object?>>());
+    self::topLevel2<core::Object?>(() → self::A<core::Object?> => self::captureTypeArgument<self::A<core::Object?>>());
+    this.{self::Class::instance1}<core::Object?>(() → self::A<core::Object?> => self::captureTypeArgument<self::A<core::Object?>>());
+    this.{self::Class::instance2}<core::Object?>(() → self::A<core::Object?> => self::captureTypeArgument<self::A<core::Object?>>());
+  }
+}
+class Subclass extends self::Class {
+  synthetic constructor •() → self::Subclass
+    : super self::Class::•()
+    ;
+  method test() → void {
+    super.{self::Class::instance1}<core::Object?>(() → self::A<core::Object?> => self::captureTypeArgument<self::A<core::Object?>>());
+    super.{self::Class::instance2}<core::Object?>(() → self::A<core::Object?> => self::captureTypeArgument<self::A<core::Object?>>());
+  }
+}
+static field core::Type? _capturedTypeArgument;
+static method captureTypeArgument<X extends core::Object? = dynamic>() → self::captureTypeArgument::X% {
+  self::_capturedTypeArgument = self::captureTypeArgument::X%;
+  core::print("X: ${self::captureTypeArgument::X%}");
+  throw "Error";
+}
+static method topLevel1<X extends self::A<self::topLevel1::X> = self::A<dynamic>>(() → self::A<self::topLevel1::X> g) → void
+  return g.call();
+static method topLevel2<X extends self::A<self::topLevel2::X> = self::A<dynamic>>(() → self::A<self::topLevel2::X> g) → void
+  return g.call();
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart.weak.outline.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart.weak.outline.expect
new file mode 100644
index 0000000..a1218a1
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart.weak.outline.expect
@@ -0,0 +1,34 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+typedef C<X extends self::A<X> = self::A<dynamic>> = self::A<X>;
+class A<X extends self::A<self::A::X> = self::A<dynamic>> extends core::Object {
+  synthetic constructor •() → self::A<self::A::X>
+    ;
+}
+class Class extends core::Object {
+  synthetic constructor •() → self::Class
+    ;
+  method instance1<X extends self::A<self::Class::instance1::X> = self::A<dynamic>>(() → self::A<self::Class::instance1::X> g) → void
+    ;
+  method instance2<X extends self::A<self::Class::instance2::X> = self::A<dynamic>>(() → self::A<self::Class::instance2::X> g) → void
+    ;
+  method test() → void
+    ;
+}
+class Subclass extends self::Class {
+  synthetic constructor •() → self::Subclass
+    ;
+  method test() → void
+    ;
+}
+static field core::Type? _capturedTypeArgument;
+static method captureTypeArgument<X extends core::Object? = dynamic>() → self::captureTypeArgument::X%
+  ;
+static method topLevel1<X extends self::A<self::topLevel1::X> = self::A<dynamic>>(() → self::A<self::topLevel1::X> g) → void
+  ;
+static method topLevel2<X extends self::A<self::topLevel2::X> = self::A<dynamic>>(() → self::A<self::topLevel2::X> g) → void
+  ;
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart.weak.transformed.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart.weak.transformed.expect
new file mode 100644
index 0000000..15fe25b
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart.weak.transformed.expect
@@ -0,0 +1,160 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:32:9: Error: Inferred type argument 'A<Object?>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'A'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart'.
+//  - 'Object' is from 'dart:core'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//     new A();
+//         ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:13:9: Context: This is the type variable whose bound isn't conformed to.
+// class A<X extends A<X>> {}
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:33:9: Error: Inferred type argument 'A<Object?>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'A'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart'.
+//  - 'Object' is from 'dart:core'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//     new C();
+//         ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:13:9: Context: This is the type variable whose bound isn't conformed to.
+// class A<X extends A<X>> {}
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:34:7: Error: Inferred type argument 'Object?' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'call'.
+//  - 'Object' is from 'dart:core'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//     f1(() => captureTypeArgument());
+//       ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:35:7: Error: Inferred type argument 'Object?' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'call'.
+//  - 'Object' is from 'dart:core'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//     f2(() => captureTypeArgument());
+//       ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:36:11: Error: Inferred type argument 'Object?' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'local1'.
+//  - 'Object' is from 'dart:core'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//     local1(() => captureTypeArgument());
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:37:11: Error: Inferred type argument 'Object?' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'local2'.
+//  - 'Object' is from 'dart:core'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//     local2(() => captureTypeArgument());
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:38:5: Error: Inferred type argument 'Object?' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'topLevel1'.
+//  - 'Object' is from 'dart:core'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//     topLevel1(() => captureTypeArgument());
+//     ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:16:16: Context: This is the type variable whose bound isn't conformed to.
+// void topLevel1<X extends A<X>>(A<X> Function() g) => g();
+//                ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:39:5: Error: Inferred type argument 'Object?' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'topLevel2'.
+//  - 'Object' is from 'dart:core'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//     topLevel2(() => captureTypeArgument());
+//     ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:18:16: Context: This is the type variable whose bound isn't conformed to.
+// void topLevel2<X extends C<X>>(C<X> Function() g) => g();
+//                ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:40:5: Error: Inferred type argument 'Object?' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'Class.instance1'.
+//  - 'Object' is from 'dart:core'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart'.
+//  - 'Class' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//     instance1(() => captureTypeArgument());
+//     ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:41:5: Error: Inferred type argument 'Object?' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'Class.instance2'.
+//  - 'Object' is from 'dart:core'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart'.
+//  - 'Class' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//     instance2(() => captureTypeArgument());
+//     ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:47:11: Error: Inferred type argument 'Object?' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'Subclass.instance1'.
+//  - 'Object' is from 'dart:core'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart'.
+//  - 'Subclass' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//     super.instance1(() => captureTypeArgument());
+//           ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart:48:11: Error: Inferred type argument 'Object?' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'Subclass.instance2'.
+//  - 'Object' is from 'dart:core'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart'.
+//  - 'Subclass' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45464.dart'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//     super.instance2(() => captureTypeArgument());
+//           ^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef C<X extends self::A<X> = self::A<dynamic>> = self::A<X>;
+class A<X extends self::A<self::A::X> = self::A<dynamic>> extends core::Object {
+  synthetic constructor •() → self::A<self::A::X>
+    : super core::Object::•()
+    ;
+}
+class Class extends core::Object {
+  synthetic constructor •() → self::Class
+    : super core::Object::•()
+    ;
+  method instance1<X extends self::A<self::Class::instance1::X> = self::A<dynamic>>(() → self::A<self::Class::instance1::X> g) → void
+    return g.call();
+  method instance2<X extends self::A<self::Class::instance2::X> = self::A<dynamic>>(() → self::A<self::Class::instance2::X> g) → void
+    return g.call();
+  method test() → void {
+    function local1<X extends self::A<X> = self::A<dynamic>>(() → self::A<X> g) → void
+      return g.call();
+    function local2<X extends self::A<X> = self::A<dynamic>>(() → self::A<X> g) → void
+      return g.call();
+    <X extends self::A<X> = self::A<dynamic>>(() → self::A<X>) → void f1 = local1;
+    <X extends self::A<X> = self::A<dynamic>>(() → self::A<X>) → void f2 = local2;
+    new self::A::•<self::A<core::Object?>>();
+    new self::A::•<self::A<core::Object?>>();
+    f1.call<core::Object?>(() → self::A<core::Object?> => self::captureTypeArgument<self::A<core::Object?>>());
+    f2.call<core::Object?>(() → self::A<core::Object?> => self::captureTypeArgument<self::A<core::Object?>>());
+    local1.call<core::Object?>(() → self::A<core::Object?> => self::captureTypeArgument<self::A<core::Object?>>());
+    local2.call<core::Object?>(() → self::A<core::Object?> => self::captureTypeArgument<self::A<core::Object?>>());
+    self::topLevel1<core::Object?>(() → self::A<core::Object?> => self::captureTypeArgument<self::A<core::Object?>>());
+    self::topLevel2<core::Object?>(() → self::A<core::Object?> => self::captureTypeArgument<self::A<core::Object?>>());
+    this.{self::Class::instance1}<core::Object?>(() → self::A<core::Object?> => self::captureTypeArgument<self::A<core::Object?>>());
+    this.{self::Class::instance2}<core::Object?>(() → self::A<core::Object?> => self::captureTypeArgument<self::A<core::Object?>>());
+  }
+}
+class Subclass extends self::Class {
+  synthetic constructor •() → self::Subclass
+    : super self::Class::•()
+    ;
+  method test() → void {
+    super.{self::Class::instance1}<core::Object?>(() → self::A<core::Object?> => self::captureTypeArgument<self::A<core::Object?>>());
+    super.{self::Class::instance2}<core::Object?>(() → self::A<core::Object?> => self::captureTypeArgument<self::A<core::Object?>>());
+  }
+}
+static field core::Type? _capturedTypeArgument;
+static method captureTypeArgument<X extends core::Object? = dynamic>() → self::captureTypeArgument::X% {
+  self::_capturedTypeArgument = self::captureTypeArgument::X%;
+  core::print("X: ${self::captureTypeArgument::X%}");
+  throw "Error";
+}
+static method topLevel1<X extends self::A<self::topLevel1::X> = self::A<dynamic>>(() → self::A<self::topLevel1::X> g) → void
+  return g.call();
+static method topLevel2<X extends self::A<self::topLevel2::X> = self::A<dynamic>>(() → self::A<self::topLevel2::X> g) → void
+  return g.call();
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart b/pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart
new file mode 100644
index 0000000..1a3a438
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class A<X extends A<X>> {}
+
+typedef AAlias<X> = A;
+
+void main() {}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart.strong.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart.strong.expect
new file mode 100644
index 0000000..e43a323
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart.strong.expect
@@ -0,0 +1,23 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart:7:21: Error: Inferred type argument 'A<dynamic>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'A'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+// typedef AAlias<X> = A;
+//                     ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart:5:9: Context: This is the type variable whose bound isn't conformed to.
+// class A<X extends A<X>> {}
+//         ^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef AAlias<unrelated X extends core::Object? = dynamic> = self::A<self::A<dynamic>>;
+class A<X extends self::A<self::A::X> = self::A<dynamic>> extends core::Object {
+  synthetic constructor •() → self::A<self::A::X>
+    : super core::Object::•()
+    ;
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart.strong.transformed.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart.strong.transformed.expect
new file mode 100644
index 0000000..e43a323
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart.strong.transformed.expect
@@ -0,0 +1,23 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart:7:21: Error: Inferred type argument 'A<dynamic>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'A'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+// typedef AAlias<X> = A;
+//                     ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart:5:9: Context: This is the type variable whose bound isn't conformed to.
+// class A<X extends A<X>> {}
+//         ^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef AAlias<unrelated X extends core::Object? = dynamic> = self::A<self::A<dynamic>>;
+class A<X extends self::A<self::A::X> = self::A<dynamic>> extends core::Object {
+  synthetic constructor •() → self::A<self::A::X>
+    : super core::Object::•()
+    ;
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart.textual_outline.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart.textual_outline.expect
new file mode 100644
index 0000000..d25a92a
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+class A<X extends A<X>> {}
+
+typedef AAlias<X> = A;
+void main() {}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d25a92a
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+class A<X extends A<X>> {}
+
+typedef AAlias<X> = A;
+void main() {}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart.weak.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart.weak.expect
new file mode 100644
index 0000000..e43a323
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart.weak.expect
@@ -0,0 +1,23 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart:7:21: Error: Inferred type argument 'A<dynamic>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'A'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+// typedef AAlias<X> = A;
+//                     ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart:5:9: Context: This is the type variable whose bound isn't conformed to.
+// class A<X extends A<X>> {}
+//         ^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef AAlias<unrelated X extends core::Object? = dynamic> = self::A<self::A<dynamic>>;
+class A<X extends self::A<self::A::X> = self::A<dynamic>> extends core::Object {
+  synthetic constructor •() → self::A<self::A::X>
+    : super core::Object::•()
+    ;
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart.weak.outline.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart.weak.outline.expect
new file mode 100644
index 0000000..19040d1
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart.weak.outline.expect
@@ -0,0 +1,23 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart:7:21: Error: Inferred type argument 'A<dynamic>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'A'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+// typedef AAlias<X> = A;
+//                     ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart:5:9: Context: This is the type variable whose bound isn't conformed to.
+// class A<X extends A<X>> {}
+//         ^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef AAlias<unrelated X extends core::Object? = dynamic> = self::A<self::A<dynamic>>;
+class A<X extends self::A<self::A::X> = self::A<dynamic>> extends core::Object {
+  synthetic constructor •() → self::A<self::A::X>
+    ;
+}
+static method main() → void
+  ;
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart.weak.transformed.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart.weak.transformed.expect
new file mode 100644
index 0000000..e43a323
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart.weak.transformed.expect
@@ -0,0 +1,23 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart:7:21: Error: Inferred type argument 'A<dynamic>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'A'.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+// typedef AAlias<X> = A;
+//                     ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart:5:9: Context: This is the type variable whose bound isn't conformed to.
+// class A<X extends A<X>> {}
+//         ^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef AAlias<unrelated X extends core::Object? = dynamic> = self::A<self::A<dynamic>>;
+class A<X extends self::A<self::A::X> = self::A<dynamic>> extends core::Object {
+  synthetic constructor •() → self::A<self::A::X>
+    : super core::Object::•()
+    ;
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue45519.dart b/pkg/front_end/testcases/nonfunction_type_aliases/issue45519.dart
new file mode 100644
index 0000000..9a5768c
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue45519.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class C<X> {}
+typedef G<X> = X Function(X);
+typedef A<X extends G<C<X>>> = C<X>;
+
+test() {
+  A a = throw 42; // Error.
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue45519.dart.strong.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue45519.dart.strong.expect
new file mode 100644
index 0000000..20cf2a0a
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue45519.dart.strong.expect
@@ -0,0 +1,31 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519.dart:10:3: Error: Inferred type argument 'C<dynamic> Function(C<dynamic>)' doesn't conform to the bound 'C<X> Function(C<X>)' of the type variable 'X' on 'A'.
+//  - 'C' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45519.dart'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//   A a = throw 42; // Error.
+//   ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef A<X extends G<C<X>>> = C<X>;
+//           ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519.dart:10:3: Context: If you want 'A<C<dynamic> Function(C<dynamic>)>' to be a super-bounded type, note that the inverted type 'A<G<C<Never>>>' must then satisfy its bounds, which it does not.
+//  - 'C' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45519.dart'.
+//   A a = throw 42; // Error.
+//   ^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef G<invariant X extends core::Object? = dynamic> = (X%) → X%;
+typedef A<X extends (self::C<X>) → self::C<X> = (self::C<dynamic>) → self::C<dynamic>> = self::C<X>;
+class C<X extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::C<self::C::X%>
+    : super core::Object::•()
+    ;
+}
+static method test() → dynamic {
+  self::C<(self::C<dynamic>) → self::C<dynamic>> a = throw 42;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue45519.dart.strong.transformed.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue45519.dart.strong.transformed.expect
new file mode 100644
index 0000000..20cf2a0a
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue45519.dart.strong.transformed.expect
@@ -0,0 +1,31 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519.dart:10:3: Error: Inferred type argument 'C<dynamic> Function(C<dynamic>)' doesn't conform to the bound 'C<X> Function(C<X>)' of the type variable 'X' on 'A'.
+//  - 'C' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45519.dart'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//   A a = throw 42; // Error.
+//   ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef A<X extends G<C<X>>> = C<X>;
+//           ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519.dart:10:3: Context: If you want 'A<C<dynamic> Function(C<dynamic>)>' to be a super-bounded type, note that the inverted type 'A<G<C<Never>>>' must then satisfy its bounds, which it does not.
+//  - 'C' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45519.dart'.
+//   A a = throw 42; // Error.
+//   ^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef G<invariant X extends core::Object? = dynamic> = (X%) → X%;
+typedef A<X extends (self::C<X>) → self::C<X> = (self::C<dynamic>) → self::C<dynamic>> = self::C<X>;
+class C<X extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::C<self::C::X%>
+    : super core::Object::•()
+    ;
+}
+static method test() → dynamic {
+  self::C<(self::C<dynamic>) → self::C<dynamic>> a = throw 42;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue45519.dart.textual_outline.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue45519.dart.textual_outline.expect
new file mode 100644
index 0000000..a5f4a20
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue45519.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class C<X> {}
+
+typedef G<X> = X Function(X);
+typedef A<X extends G<C<X>>> = C<X>;
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue45519.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue45519.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..edec24e
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue45519.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+class C<X> {}
+
+main() {}
+test() {}
+typedef A<X extends G<C<X>>> = C<X>;
+typedef G<X> = X Function(X);
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue45519.dart.weak.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue45519.dart.weak.expect
new file mode 100644
index 0000000..20cf2a0a
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue45519.dart.weak.expect
@@ -0,0 +1,31 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519.dart:10:3: Error: Inferred type argument 'C<dynamic> Function(C<dynamic>)' doesn't conform to the bound 'C<X> Function(C<X>)' of the type variable 'X' on 'A'.
+//  - 'C' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45519.dart'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//   A a = throw 42; // Error.
+//   ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef A<X extends G<C<X>>> = C<X>;
+//           ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519.dart:10:3: Context: If you want 'A<C<dynamic> Function(C<dynamic>)>' to be a super-bounded type, note that the inverted type 'A<G<C<Never>>>' must then satisfy its bounds, which it does not.
+//  - 'C' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45519.dart'.
+//   A a = throw 42; // Error.
+//   ^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef G<invariant X extends core::Object? = dynamic> = (X%) → X%;
+typedef A<X extends (self::C<X>) → self::C<X> = (self::C<dynamic>) → self::C<dynamic>> = self::C<X>;
+class C<X extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::C<self::C::X%>
+    : super core::Object::•()
+    ;
+}
+static method test() → dynamic {
+  self::C<(self::C<dynamic>) → self::C<dynamic>> a = throw 42;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue45519.dart.weak.outline.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue45519.dart.weak.outline.expect
new file mode 100644
index 0000000..2c7e28a
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue45519.dart.weak.outline.expect
@@ -0,0 +1,14 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+typedef G<invariant X extends core::Object? = dynamic> = (X%) → X%;
+typedef A<X extends (self::C<X>) → self::C<X> = (self::C<dynamic>) → self::C<dynamic>> = self::C<X>;
+class C<X extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::C<self::C::X%>
+    ;
+}
+static method test() → dynamic
+  ;
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue45519.dart.weak.transformed.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue45519.dart.weak.transformed.expect
new file mode 100644
index 0000000..20cf2a0a
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue45519.dart.weak.transformed.expect
@@ -0,0 +1,31 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519.dart:10:3: Error: Inferred type argument 'C<dynamic> Function(C<dynamic>)' doesn't conform to the bound 'C<X> Function(C<X>)' of the type variable 'X' on 'A'.
+//  - 'C' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45519.dart'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//   A a = throw 42; // Error.
+//   ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519.dart:7:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef A<X extends G<C<X>>> = C<X>;
+//           ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519.dart:10:3: Context: If you want 'A<C<dynamic> Function(C<dynamic>)>' to be a super-bounded type, note that the inverted type 'A<G<C<Never>>>' must then satisfy its bounds, which it does not.
+//  - 'C' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45519.dart'.
+//   A a = throw 42; // Error.
+//   ^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef G<invariant X extends core::Object? = dynamic> = (X%) → X%;
+typedef A<X extends (self::C<X>) → self::C<X> = (self::C<dynamic>) → self::C<dynamic>> = self::C<X>;
+class C<X extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::C<self::C::X%>
+    : super core::Object::•()
+    ;
+}
+static method test() → dynamic {
+  self::C<(self::C<dynamic>) → self::C<dynamic>> a = throw 42;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart b/pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart
new file mode 100644
index 0000000..de364ca
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class C<X> {
+  factory C() => new C.foo();
+  C.foo() {}
+  factory C.bar() = C;
+}
+class D<X> {
+  D();
+  factory D.foo() => new D();
+  factory D.bar() = D;
+}
+typedef G<X> = X Function(X);
+typedef A<X extends G<C<X>>> = C<X>;
+typedef B<X extends G<D<X>>> = D<X>;
+
+test() {
+  A(); // Error.
+  A.foo(); // Error.
+  A.bar(); // Error.
+  B(); // Error.
+  B.foo(); // Error.
+  B.bar(); // Error.
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart.strong.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart.strong.expect
new file mode 100644
index 0000000..2e82e80
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart.strong.expect
@@ -0,0 +1,128 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:21:5: Error: Type argument 'C<Object?> Function(C<Never>)' doesn't conform to the bound 'C<X> Function(C<X>)' of the type variable 'X' on 'A'.
+//  - 'C' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart'.
+//  - 'Object' is from 'dart:core'.
+// Try changing type arguments so that they conform to the bounds.
+//   A.foo(); // Error.
+//     ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:16:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef A<X extends G<C<X>>> = C<X>;
+//           ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:21:5: Context: If you want 'A<C<Object?> Function(C<Never>)>' to be a super-bounded type, note that the inverted type 'A<G<C<Never>>>' must then satisfy its bounds, which it does not.
+//  - 'C' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart'.
+//  - 'Object' is from 'dart:core'.
+//   A.foo(); // Error.
+//     ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:23:3: Error: Type argument 'D<Object?> Function(D<Never>)' doesn't conform to the bound 'D<X> Function(D<X>)' of the type variable 'X' on 'B'.
+//  - 'D' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart'.
+//  - 'Object' is from 'dart:core'.
+// Try changing type arguments so that they conform to the bounds.
+//   B(); // Error.
+//   ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:17:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends G<D<X>>> = D<X>;
+//           ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:23:3: Context: If you want 'B<D<Object?> Function(D<Never>)>' to be a super-bounded type, note that the inverted type 'B<G<D<Never>>>' must then satisfy its bounds, which it does not.
+//  - 'D' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart'.
+//  - 'Object' is from 'dart:core'.
+//   B(); // Error.
+//   ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:20:3: Error: Type argument 'C<Object?> Function(C<Never>)' doesn't conform to the bound 'C<X> Function(C<X>)' of the type variable 'X' on 'A'.
+//  - 'C' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart'.
+//  - 'Object' is from 'dart:core'.
+// Try changing type arguments so that they conform to the bounds.
+//   A(); // Error.
+//   ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:16:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef A<X extends G<C<X>>> = C<X>;
+//           ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:20:3: Context: If you want 'A<C<Object?> Function(C<Never>)>' to be a super-bounded type, note that the inverted type 'A<G<C<Never>>>' must then satisfy its bounds, which it does not.
+//  - 'C' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart'.
+//  - 'Object' is from 'dart:core'.
+//   A(); // Error.
+//   ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:22:5: Error: Type argument 'C<Object?> Function(C<Never>)' doesn't conform to the bound 'C<X> Function(C<X>)' of the type variable 'X' on 'A'.
+//  - 'C' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart'.
+//  - 'Object' is from 'dart:core'.
+// Try changing type arguments so that they conform to the bounds.
+//   A.bar(); // Error.
+//     ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:16:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef A<X extends G<C<X>>> = C<X>;
+//           ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:22:5: Context: If you want 'A<C<Object?> Function(C<Never>)>' to be a super-bounded type, note that the inverted type 'A<G<C<Never>>>' must then satisfy its bounds, which it does not.
+//  - 'C' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart'.
+//  - 'Object' is from 'dart:core'.
+//   A.bar(); // Error.
+//     ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:24:5: Error: Type argument 'D<Object?> Function(D<Never>)' doesn't conform to the bound 'D<X> Function(D<X>)' of the type variable 'X' on 'B'.
+//  - 'D' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart'.
+//  - 'Object' is from 'dart:core'.
+// Try changing type arguments so that they conform to the bounds.
+//   B.foo(); // Error.
+//     ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:17:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends G<D<X>>> = D<X>;
+//           ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:24:5: Context: If you want 'B<D<Object?> Function(D<Never>)>' to be a super-bounded type, note that the inverted type 'B<G<D<Never>>>' must then satisfy its bounds, which it does not.
+//  - 'D' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart'.
+//  - 'Object' is from 'dart:core'.
+//   B.foo(); // Error.
+//     ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:25:5: Error: Type argument 'D<Object?> Function(D<Never>)' doesn't conform to the bound 'D<X> Function(D<X>)' of the type variable 'X' on 'B'.
+//  - 'D' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart'.
+//  - 'Object' is from 'dart:core'.
+// Try changing type arguments so that they conform to the bounds.
+//   B.bar(); // Error.
+//     ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:17:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends G<D<X>>> = D<X>;
+//           ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:25:5: Context: If you want 'B<D<Object?> Function(D<Never>)>' to be a super-bounded type, note that the inverted type 'B<G<D<Never>>>' must then satisfy its bounds, which it does not.
+//  - 'D' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart'.
+//  - 'Object' is from 'dart:core'.
+//   B.bar(); // Error.
+//     ^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef G<invariant X extends core::Object? = dynamic> = (X%) → X%;
+typedef A<X extends (self::C<X>) → self::C<X> = (self::C<dynamic>) → self::C<dynamic>> = self::C<X>;
+typedef B<X extends (self::D<X>) → self::D<X> = (self::D<dynamic>) → self::D<dynamic>> = self::D<X>;
+class C<X extends core::Object? = dynamic> extends core::Object {
+  static final field dynamic _redirecting# = <dynamic>[self::C::bar]/*isLegacy*/;
+  constructor foo() → self::C<self::C::X%>
+    : super core::Object::•() {}
+  static factory •<X extends core::Object? = dynamic>() → self::C<self::C::•::X%>
+    return new self::C::foo<self::C::•::X%>();
+  static factory bar<X extends core::Object? = dynamic>() → self::C<self::C::bar::X%>
+    let dynamic #redirecting_factory = self::C::• in let self::C::bar::X% #typeArg0 = null in invalid-expression;
+}
+class D<X extends core::Object? = dynamic> extends core::Object {
+  static final field dynamic _redirecting# = <dynamic>[self::D::bar]/*isLegacy*/;
+  constructor •() → self::D<self::D::X%>
+    : super core::Object::•()
+    ;
+  static factory foo<X extends core::Object? = dynamic>() → self::D<self::D::foo::X%>
+    return new self::D::•<self::D::foo::X%>();
+  static factory bar<X extends core::Object? = dynamic>() → self::D<self::D::bar::X%>
+    let dynamic #redirecting_factory = self::D::• in let self::D::bar::X% #typeArg0 = null in invalid-expression;
+}
+static method test() → dynamic {
+  self::C::•<(self::C<Never>) → self::C<core::Object?>>();
+  new self::C::foo<(self::C<Never>) → self::C<core::Object?>>();
+  self::C::•<(self::C<Never>) → self::C<core::Object?>>();
+  new self::D::•<(self::D<Never>) → self::D<core::Object?>>();
+  self::D::foo<(self::D<Never>) → self::D<core::Object?>>();
+  new self::D::•<(self::D<Never>) → self::D<core::Object?>>();
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart.strong.transformed.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart.strong.transformed.expect
new file mode 100644
index 0000000..e2f8dde
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart.strong.transformed.expect
@@ -0,0 +1,128 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:21:5: Error: Type argument 'C<Object?> Function(C<Never>)' doesn't conform to the bound 'C<X> Function(C<X>)' of the type variable 'X' on 'A'.
+//  - 'C' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart'.
+//  - 'Object' is from 'dart:core'.
+// Try changing type arguments so that they conform to the bounds.
+//   A.foo(); // Error.
+//     ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:16:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef A<X extends G<C<X>>> = C<X>;
+//           ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:21:5: Context: If you want 'A<C<Object?> Function(C<Never>)>' to be a super-bounded type, note that the inverted type 'A<G<C<Never>>>' must then satisfy its bounds, which it does not.
+//  - 'C' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart'.
+//  - 'Object' is from 'dart:core'.
+//   A.foo(); // Error.
+//     ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:23:3: Error: Type argument 'D<Object?> Function(D<Never>)' doesn't conform to the bound 'D<X> Function(D<X>)' of the type variable 'X' on 'B'.
+//  - 'D' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart'.
+//  - 'Object' is from 'dart:core'.
+// Try changing type arguments so that they conform to the bounds.
+//   B(); // Error.
+//   ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:17:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends G<D<X>>> = D<X>;
+//           ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:23:3: Context: If you want 'B<D<Object?> Function(D<Never>)>' to be a super-bounded type, note that the inverted type 'B<G<D<Never>>>' must then satisfy its bounds, which it does not.
+//  - 'D' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart'.
+//  - 'Object' is from 'dart:core'.
+//   B(); // Error.
+//   ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:20:3: Error: Type argument 'C<Object?> Function(C<Never>)' doesn't conform to the bound 'C<X> Function(C<X>)' of the type variable 'X' on 'A'.
+//  - 'C' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart'.
+//  - 'Object' is from 'dart:core'.
+// Try changing type arguments so that they conform to the bounds.
+//   A(); // Error.
+//   ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:16:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef A<X extends G<C<X>>> = C<X>;
+//           ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:20:3: Context: If you want 'A<C<Object?> Function(C<Never>)>' to be a super-bounded type, note that the inverted type 'A<G<C<Never>>>' must then satisfy its bounds, which it does not.
+//  - 'C' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart'.
+//  - 'Object' is from 'dart:core'.
+//   A(); // Error.
+//   ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:22:5: Error: Type argument 'C<Object?> Function(C<Never>)' doesn't conform to the bound 'C<X> Function(C<X>)' of the type variable 'X' on 'A'.
+//  - 'C' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart'.
+//  - 'Object' is from 'dart:core'.
+// Try changing type arguments so that they conform to the bounds.
+//   A.bar(); // Error.
+//     ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:16:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef A<X extends G<C<X>>> = C<X>;
+//           ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:22:5: Context: If you want 'A<C<Object?> Function(C<Never>)>' to be a super-bounded type, note that the inverted type 'A<G<C<Never>>>' must then satisfy its bounds, which it does not.
+//  - 'C' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart'.
+//  - 'Object' is from 'dart:core'.
+//   A.bar(); // Error.
+//     ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:24:5: Error: Type argument 'D<Object?> Function(D<Never>)' doesn't conform to the bound 'D<X> Function(D<X>)' of the type variable 'X' on 'B'.
+//  - 'D' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart'.
+//  - 'Object' is from 'dart:core'.
+// Try changing type arguments so that they conform to the bounds.
+//   B.foo(); // Error.
+//     ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:17:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends G<D<X>>> = D<X>;
+//           ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:24:5: Context: If you want 'B<D<Object?> Function(D<Never>)>' to be a super-bounded type, note that the inverted type 'B<G<D<Never>>>' must then satisfy its bounds, which it does not.
+//  - 'D' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart'.
+//  - 'Object' is from 'dart:core'.
+//   B.foo(); // Error.
+//     ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:25:5: Error: Type argument 'D<Object?> Function(D<Never>)' doesn't conform to the bound 'D<X> Function(D<X>)' of the type variable 'X' on 'B'.
+//  - 'D' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart'.
+//  - 'Object' is from 'dart:core'.
+// Try changing type arguments so that they conform to the bounds.
+//   B.bar(); // Error.
+//     ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:17:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends G<D<X>>> = D<X>;
+//           ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:25:5: Context: If you want 'B<D<Object?> Function(D<Never>)>' to be a super-bounded type, note that the inverted type 'B<G<D<Never>>>' must then satisfy its bounds, which it does not.
+//  - 'D' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart'.
+//  - 'Object' is from 'dart:core'.
+//   B.bar(); // Error.
+//     ^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef G<invariant X extends core::Object? = dynamic> = (X%) → X%;
+typedef A<X extends (self::C<X>) → self::C<X> = (self::C<dynamic>) → self::C<dynamic>> = self::C<X>;
+typedef B<X extends (self::D<X>) → self::D<X> = (self::D<dynamic>) → self::D<dynamic>> = self::D<X>;
+class C<X extends core::Object? = dynamic> extends core::Object {
+  static final field dynamic _redirecting# = <dynamic>[self::C::bar]/*isLegacy*/;
+  constructor foo() → self::C<self::C::X%>
+    : super core::Object::•() {}
+  static factory •<X extends core::Object? = dynamic>() → self::C<self::C::•::X%>
+    return new self::C::foo<self::C::•::X%>();
+  static factory bar<X extends core::Object? = dynamic>() → self::C<self::C::bar::X%>
+    let <X extends core::Object? = dynamic>() → self::C<X%> #redirecting_factory = self::C::• in let self::C::bar::X% #typeArg0 = null in invalid-expression;
+}
+class D<X extends core::Object? = dynamic> extends core::Object {
+  static final field dynamic _redirecting# = <dynamic>[self::D::bar]/*isLegacy*/;
+  constructor •() → self::D<self::D::X%>
+    : super core::Object::•()
+    ;
+  static factory foo<X extends core::Object? = dynamic>() → self::D<self::D::foo::X%>
+    return new self::D::•<self::D::foo::X%>();
+  static factory bar<X extends core::Object? = dynamic>() → self::D<self::D::bar::X%>
+    let Never #redirecting_factory = self::D::• in let self::D::bar::X% #typeArg0 = null in invalid-expression;
+}
+static method test() → dynamic {
+  self::C::•<(self::C<Never>) → self::C<core::Object?>>();
+  new self::C::foo<(self::C<Never>) → self::C<core::Object?>>();
+  self::C::•<(self::C<Never>) → self::C<core::Object?>>();
+  new self::D::•<(self::D<Never>) → self::D<core::Object?>>();
+  self::D::foo<(self::D<Never>) → self::D<core::Object?>>();
+  new self::D::•<(self::D<Never>) → self::D<core::Object?>>();
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart.textual_outline.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart.textual_outline.expect
new file mode 100644
index 0000000..acb7e9b
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart.textual_outline.expect
@@ -0,0 +1,17 @@
+class C<X> {
+  factory C() => new C.foo();
+  C.foo() {}
+  factory C.bar() = C;
+}
+
+class D<X> {
+  D();
+  factory D.foo() => new D();
+  factory D.bar() = D;
+}
+
+typedef G<X> = X Function(X);
+typedef A<X extends G<C<X>>> = C<X>;
+typedef B<X extends G<D<X>>> = D<X>;
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e83da8e
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart.textual_outline_modelled.expect
@@ -0,0 +1,17 @@
+class C<X> {
+  C.foo() {}
+  factory C() => new C.foo();
+  factory C.bar() = C;
+}
+
+class D<X> {
+  D();
+  factory D.bar() = D;
+  factory D.foo() => new D();
+}
+
+main() {}
+test() {}
+typedef A<X extends G<C<X>>> = C<X>;
+typedef B<X extends G<D<X>>> = D<X>;
+typedef G<X> = X Function(X);
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart.weak.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart.weak.expect
new file mode 100644
index 0000000..2e82e80
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart.weak.expect
@@ -0,0 +1,128 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:21:5: Error: Type argument 'C<Object?> Function(C<Never>)' doesn't conform to the bound 'C<X> Function(C<X>)' of the type variable 'X' on 'A'.
+//  - 'C' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart'.
+//  - 'Object' is from 'dart:core'.
+// Try changing type arguments so that they conform to the bounds.
+//   A.foo(); // Error.
+//     ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:16:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef A<X extends G<C<X>>> = C<X>;
+//           ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:21:5: Context: If you want 'A<C<Object?> Function(C<Never>)>' to be a super-bounded type, note that the inverted type 'A<G<C<Never>>>' must then satisfy its bounds, which it does not.
+//  - 'C' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart'.
+//  - 'Object' is from 'dart:core'.
+//   A.foo(); // Error.
+//     ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:23:3: Error: Type argument 'D<Object?> Function(D<Never>)' doesn't conform to the bound 'D<X> Function(D<X>)' of the type variable 'X' on 'B'.
+//  - 'D' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart'.
+//  - 'Object' is from 'dart:core'.
+// Try changing type arguments so that they conform to the bounds.
+//   B(); // Error.
+//   ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:17:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends G<D<X>>> = D<X>;
+//           ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:23:3: Context: If you want 'B<D<Object?> Function(D<Never>)>' to be a super-bounded type, note that the inverted type 'B<G<D<Never>>>' must then satisfy its bounds, which it does not.
+//  - 'D' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart'.
+//  - 'Object' is from 'dart:core'.
+//   B(); // Error.
+//   ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:20:3: Error: Type argument 'C<Object?> Function(C<Never>)' doesn't conform to the bound 'C<X> Function(C<X>)' of the type variable 'X' on 'A'.
+//  - 'C' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart'.
+//  - 'Object' is from 'dart:core'.
+// Try changing type arguments so that they conform to the bounds.
+//   A(); // Error.
+//   ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:16:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef A<X extends G<C<X>>> = C<X>;
+//           ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:20:3: Context: If you want 'A<C<Object?> Function(C<Never>)>' to be a super-bounded type, note that the inverted type 'A<G<C<Never>>>' must then satisfy its bounds, which it does not.
+//  - 'C' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart'.
+//  - 'Object' is from 'dart:core'.
+//   A(); // Error.
+//   ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:22:5: Error: Type argument 'C<Object?> Function(C<Never>)' doesn't conform to the bound 'C<X> Function(C<X>)' of the type variable 'X' on 'A'.
+//  - 'C' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart'.
+//  - 'Object' is from 'dart:core'.
+// Try changing type arguments so that they conform to the bounds.
+//   A.bar(); // Error.
+//     ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:16:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef A<X extends G<C<X>>> = C<X>;
+//           ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:22:5: Context: If you want 'A<C<Object?> Function(C<Never>)>' to be a super-bounded type, note that the inverted type 'A<G<C<Never>>>' must then satisfy its bounds, which it does not.
+//  - 'C' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart'.
+//  - 'Object' is from 'dart:core'.
+//   A.bar(); // Error.
+//     ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:24:5: Error: Type argument 'D<Object?> Function(D<Never>)' doesn't conform to the bound 'D<X> Function(D<X>)' of the type variable 'X' on 'B'.
+//  - 'D' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart'.
+//  - 'Object' is from 'dart:core'.
+// Try changing type arguments so that they conform to the bounds.
+//   B.foo(); // Error.
+//     ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:17:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends G<D<X>>> = D<X>;
+//           ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:24:5: Context: If you want 'B<D<Object?> Function(D<Never>)>' to be a super-bounded type, note that the inverted type 'B<G<D<Never>>>' must then satisfy its bounds, which it does not.
+//  - 'D' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart'.
+//  - 'Object' is from 'dart:core'.
+//   B.foo(); // Error.
+//     ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:25:5: Error: Type argument 'D<Object?> Function(D<Never>)' doesn't conform to the bound 'D<X> Function(D<X>)' of the type variable 'X' on 'B'.
+//  - 'D' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart'.
+//  - 'Object' is from 'dart:core'.
+// Try changing type arguments so that they conform to the bounds.
+//   B.bar(); // Error.
+//     ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:17:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends G<D<X>>> = D<X>;
+//           ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:25:5: Context: If you want 'B<D<Object?> Function(D<Never>)>' to be a super-bounded type, note that the inverted type 'B<G<D<Never>>>' must then satisfy its bounds, which it does not.
+//  - 'D' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart'.
+//  - 'Object' is from 'dart:core'.
+//   B.bar(); // Error.
+//     ^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef G<invariant X extends core::Object? = dynamic> = (X%) → X%;
+typedef A<X extends (self::C<X>) → self::C<X> = (self::C<dynamic>) → self::C<dynamic>> = self::C<X>;
+typedef B<X extends (self::D<X>) → self::D<X> = (self::D<dynamic>) → self::D<dynamic>> = self::D<X>;
+class C<X extends core::Object? = dynamic> extends core::Object {
+  static final field dynamic _redirecting# = <dynamic>[self::C::bar]/*isLegacy*/;
+  constructor foo() → self::C<self::C::X%>
+    : super core::Object::•() {}
+  static factory •<X extends core::Object? = dynamic>() → self::C<self::C::•::X%>
+    return new self::C::foo<self::C::•::X%>();
+  static factory bar<X extends core::Object? = dynamic>() → self::C<self::C::bar::X%>
+    let dynamic #redirecting_factory = self::C::• in let self::C::bar::X% #typeArg0 = null in invalid-expression;
+}
+class D<X extends core::Object? = dynamic> extends core::Object {
+  static final field dynamic _redirecting# = <dynamic>[self::D::bar]/*isLegacy*/;
+  constructor •() → self::D<self::D::X%>
+    : super core::Object::•()
+    ;
+  static factory foo<X extends core::Object? = dynamic>() → self::D<self::D::foo::X%>
+    return new self::D::•<self::D::foo::X%>();
+  static factory bar<X extends core::Object? = dynamic>() → self::D<self::D::bar::X%>
+    let dynamic #redirecting_factory = self::D::• in let self::D::bar::X% #typeArg0 = null in invalid-expression;
+}
+static method test() → dynamic {
+  self::C::•<(self::C<Never>) → self::C<core::Object?>>();
+  new self::C::foo<(self::C<Never>) → self::C<core::Object?>>();
+  self::C::•<(self::C<Never>) → self::C<core::Object?>>();
+  new self::D::•<(self::D<Never>) → self::D<core::Object?>>();
+  self::D::foo<(self::D<Never>) → self::D<core::Object?>>();
+  new self::D::•<(self::D<Never>) → self::D<core::Object?>>();
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart.weak.outline.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart.weak.outline.expect
new file mode 100644
index 0000000..5bcbed2
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart.weak.outline.expect
@@ -0,0 +1,29 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+typedef G<invariant X extends core::Object? = dynamic> = (X%) → X%;
+typedef A<X extends (self::C<X>) → self::C<X> = (self::C<dynamic>) → self::C<dynamic>> = self::C<X>;
+typedef B<X extends (self::D<X>) → self::D<X> = (self::D<dynamic>) → self::D<dynamic>> = self::D<X>;
+class C<X extends core::Object? = dynamic> extends core::Object {
+  static final field dynamic _redirecting# = <dynamic>[self::C::bar]/*isLegacy*/;
+  constructor foo() → self::C<self::C::X%>
+    ;
+  static factory •<X extends core::Object? = dynamic>() → self::C<self::C::•::X%>
+    ;
+  static factory bar<X extends core::Object? = dynamic>() → self::C<self::C::bar::X%>
+    let dynamic #redirecting_factory = self::C::• in let self::C::bar::X% #typeArg0 = null in invalid-expression;
+}
+class D<X extends core::Object? = dynamic> extends core::Object {
+  static final field dynamic _redirecting# = <dynamic>[self::D::bar]/*isLegacy*/;
+  constructor •() → self::D<self::D::X%>
+    ;
+  static factory foo<X extends core::Object? = dynamic>() → self::D<self::D::foo::X%>
+    ;
+  static factory bar<X extends core::Object? = dynamic>() → self::D<self::D::bar::X%>
+    let dynamic #redirecting_factory = self::D::• in let self::D::bar::X% #typeArg0 = null in invalid-expression;
+}
+static method test() → dynamic
+  ;
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart.weak.transformed.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart.weak.transformed.expect
new file mode 100644
index 0000000..e2f8dde
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart.weak.transformed.expect
@@ -0,0 +1,128 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:21:5: Error: Type argument 'C<Object?> Function(C<Never>)' doesn't conform to the bound 'C<X> Function(C<X>)' of the type variable 'X' on 'A'.
+//  - 'C' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart'.
+//  - 'Object' is from 'dart:core'.
+// Try changing type arguments so that they conform to the bounds.
+//   A.foo(); // Error.
+//     ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:16:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef A<X extends G<C<X>>> = C<X>;
+//           ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:21:5: Context: If you want 'A<C<Object?> Function(C<Never>)>' to be a super-bounded type, note that the inverted type 'A<G<C<Never>>>' must then satisfy its bounds, which it does not.
+//  - 'C' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart'.
+//  - 'Object' is from 'dart:core'.
+//   A.foo(); // Error.
+//     ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:23:3: Error: Type argument 'D<Object?> Function(D<Never>)' doesn't conform to the bound 'D<X> Function(D<X>)' of the type variable 'X' on 'B'.
+//  - 'D' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart'.
+//  - 'Object' is from 'dart:core'.
+// Try changing type arguments so that they conform to the bounds.
+//   B(); // Error.
+//   ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:17:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends G<D<X>>> = D<X>;
+//           ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:23:3: Context: If you want 'B<D<Object?> Function(D<Never>)>' to be a super-bounded type, note that the inverted type 'B<G<D<Never>>>' must then satisfy its bounds, which it does not.
+//  - 'D' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart'.
+//  - 'Object' is from 'dart:core'.
+//   B(); // Error.
+//   ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:20:3: Error: Type argument 'C<Object?> Function(C<Never>)' doesn't conform to the bound 'C<X> Function(C<X>)' of the type variable 'X' on 'A'.
+//  - 'C' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart'.
+//  - 'Object' is from 'dart:core'.
+// Try changing type arguments so that they conform to the bounds.
+//   A(); // Error.
+//   ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:16:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef A<X extends G<C<X>>> = C<X>;
+//           ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:20:3: Context: If you want 'A<C<Object?> Function(C<Never>)>' to be a super-bounded type, note that the inverted type 'A<G<C<Never>>>' must then satisfy its bounds, which it does not.
+//  - 'C' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart'.
+//  - 'Object' is from 'dart:core'.
+//   A(); // Error.
+//   ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:22:5: Error: Type argument 'C<Object?> Function(C<Never>)' doesn't conform to the bound 'C<X> Function(C<X>)' of the type variable 'X' on 'A'.
+//  - 'C' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart'.
+//  - 'Object' is from 'dart:core'.
+// Try changing type arguments so that they conform to the bounds.
+//   A.bar(); // Error.
+//     ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:16:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef A<X extends G<C<X>>> = C<X>;
+//           ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:22:5: Context: If you want 'A<C<Object?> Function(C<Never>)>' to be a super-bounded type, note that the inverted type 'A<G<C<Never>>>' must then satisfy its bounds, which it does not.
+//  - 'C' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart'.
+//  - 'Object' is from 'dart:core'.
+//   A.bar(); // Error.
+//     ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:24:5: Error: Type argument 'D<Object?> Function(D<Never>)' doesn't conform to the bound 'D<X> Function(D<X>)' of the type variable 'X' on 'B'.
+//  - 'D' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart'.
+//  - 'Object' is from 'dart:core'.
+// Try changing type arguments so that they conform to the bounds.
+//   B.foo(); // Error.
+//     ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:17:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends G<D<X>>> = D<X>;
+//           ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:24:5: Context: If you want 'B<D<Object?> Function(D<Never>)>' to be a super-bounded type, note that the inverted type 'B<G<D<Never>>>' must then satisfy its bounds, which it does not.
+//  - 'D' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart'.
+//  - 'Object' is from 'dart:core'.
+//   B.foo(); // Error.
+//     ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:25:5: Error: Type argument 'D<Object?> Function(D<Never>)' doesn't conform to the bound 'D<X> Function(D<X>)' of the type variable 'X' on 'B'.
+//  - 'D' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart'.
+//  - 'Object' is from 'dart:core'.
+// Try changing type arguments so that they conform to the bounds.
+//   B.bar(); // Error.
+//     ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:17:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef B<X extends G<D<X>>> = D<X>;
+//           ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart:25:5: Context: If you want 'B<D<Object?> Function(D<Never>)>' to be a super-bounded type, note that the inverted type 'B<G<D<Never>>>' must then satisfy its bounds, which it does not.
+//  - 'D' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart'.
+//  - 'Object' is from 'dart:core'.
+//   B.bar(); // Error.
+//     ^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef G<invariant X extends core::Object? = dynamic> = (X%) → X%;
+typedef A<X extends (self::C<X>) → self::C<X> = (self::C<dynamic>) → self::C<dynamic>> = self::C<X>;
+typedef B<X extends (self::D<X>) → self::D<X> = (self::D<dynamic>) → self::D<dynamic>> = self::D<X>;
+class C<X extends core::Object? = dynamic> extends core::Object {
+  static final field dynamic _redirecting# = <dynamic>[self::C::bar]/*isLegacy*/;
+  constructor foo() → self::C<self::C::X%>
+    : super core::Object::•() {}
+  static factory •<X extends core::Object? = dynamic>() → self::C<self::C::•::X%>
+    return new self::C::foo<self::C::•::X%>();
+  static factory bar<X extends core::Object? = dynamic>() → self::C<self::C::bar::X%>
+    let <X extends core::Object? = dynamic>() → self::C<X%> #redirecting_factory = self::C::• in let self::C::bar::X% #typeArg0 = null in invalid-expression;
+}
+class D<X extends core::Object? = dynamic> extends core::Object {
+  static final field dynamic _redirecting# = <dynamic>[self::D::bar]/*isLegacy*/;
+  constructor •() → self::D<self::D::X%>
+    : super core::Object::•()
+    ;
+  static factory foo<X extends core::Object? = dynamic>() → self::D<self::D::foo::X%>
+    return new self::D::•<self::D::foo::X%>();
+  static factory bar<X extends core::Object? = dynamic>() → self::D<self::D::bar::X%>
+    let Never #redirecting_factory = self::D::• in let self::D::bar::X% #typeArg0 = null in invalid-expression;
+}
+static method test() → dynamic {
+  self::C::•<(self::C<Never>) → self::C<core::Object?>>();
+  new self::C::foo<(self::C<Never>) → self::C<core::Object?>>();
+  self::C::•<(self::C<Never>) → self::C<core::Object?>>();
+  new self::D::•<(self::D<Never>) → self::D<core::Object?>>();
+  self::D::foo<(self::D<Never>) → self::D<core::Object?>>();
+  new self::D::•<(self::D<Never>) → self::D<core::Object?>>();
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue_43084/issue_43084.dart b/pkg/front_end/testcases/nonfunction_type_aliases/issue_43084/issue_43084.dart
new file mode 100644
index 0000000..17fef52
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue_43084/issue_43084.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.
+
+// @dart=2.9
+
+import 'issue_43084_lib.dart';
+
+main() {
+  Bar<int> x = new Bar<int>();
+  print(x);
+}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue_43084/issue_43084.dart.strong.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue_43084/issue_43084.dart.strong.expect
new file mode 100644
index 0000000..a8a2594
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue_43084/issue_43084.dart.strong.expect
@@ -0,0 +1,29 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue_43084/issue_43084.dart:5:1: Error: A library can't opt out of null safety by default, when using sound null safety.
+// // @dart=2.9
+// ^^^^^^^^^^^^
+//
+import self as self;
+import "issue_43084_lib.dart" as iss;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///issue_43084_lib.dart";
+
+static method main() → dynamic {
+  iss::Foo<core::int*>* x = new iss::Foo::•<core::int*>();
+  core::print(x);
+}
+
+library /*isNonNullableByDefault*/;
+import self as iss;
+import "dart:core" as core;
+
+typedef Bar<X extends core::Object? = dynamic> = iss::Foo<X%>;
+class Foo<X extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → iss::Foo<iss::Foo::X%>
+    : super core::Object::•()
+    ;
+}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue_43084/issue_43084.dart.strong.transformed.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue_43084/issue_43084.dart.strong.transformed.expect
new file mode 100644
index 0000000..a8a2594
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue_43084/issue_43084.dart.strong.transformed.expect
@@ -0,0 +1,29 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue_43084/issue_43084.dart:5:1: Error: A library can't opt out of null safety by default, when using sound null safety.
+// // @dart=2.9
+// ^^^^^^^^^^^^
+//
+import self as self;
+import "issue_43084_lib.dart" as iss;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///issue_43084_lib.dart";
+
+static method main() → dynamic {
+  iss::Foo<core::int*>* x = new iss::Foo::•<core::int*>();
+  core::print(x);
+}
+
+library /*isNonNullableByDefault*/;
+import self as iss;
+import "dart:core" as core;
+
+typedef Bar<X extends core::Object? = dynamic> = iss::Foo<X%>;
+class Foo<X extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → iss::Foo<iss::Foo::X%>
+    : super core::Object::•()
+    ;
+}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue_43084/issue_43084.dart.textual_outline.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue_43084/issue_43084.dart.textual_outline.expect
new file mode 100644
index 0000000..e51aa89
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue_43084/issue_43084.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+// @dart = 2.9
+import 'issue_43084_lib.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue_43084/issue_43084.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue_43084/issue_43084.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e51aa89
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue_43084/issue_43084.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+// @dart = 2.9
+import 'issue_43084_lib.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue_43084/issue_43084.dart.weak.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue_43084/issue_43084.dart.weak.expect
new file mode 100644
index 0000000..fd22d37
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue_43084/issue_43084.dart.weak.expect
@@ -0,0 +1,22 @@
+library;
+import self as self;
+import "issue_43084_lib.dart" as iss;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///issue_43084_lib.dart";
+
+static method main() → dynamic {
+  iss::Foo<core::int*>* x = new iss::Foo::•<core::int*>();
+  core::print(x);
+}
+
+library /*isNonNullableByDefault*/;
+import self as iss;
+import "dart:core" as core;
+
+typedef Bar<X extends core::Object? = dynamic> = iss::Foo<X%>;
+class Foo<X extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → iss::Foo<iss::Foo::X%>
+    : super core::Object::•()
+    ;
+}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue_43084/issue_43084.dart.weak.outline.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue_43084/issue_43084.dart.weak.outline.expect
new file mode 100644
index 0000000..91de9ad
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue_43084/issue_43084.dart.weak.outline.expect
@@ -0,0 +1,17 @@
+library;
+import self as self;
+
+import "org-dartlang-testcase:///issue_43084_lib.dart";
+
+static method main() → dynamic
+  ;
+
+library /*isNonNullableByDefault*/;
+import self as self2;
+import "dart:core" as core;
+
+typedef Bar<X extends core::Object? = dynamic> = self2::Foo<X%>;
+class Foo<X extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self2::Foo<self2::Foo::X%>
+    ;
+}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue_43084/issue_43084.dart.weak.transformed.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue_43084/issue_43084.dart.weak.transformed.expect
new file mode 100644
index 0000000..fd22d37
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue_43084/issue_43084.dart.weak.transformed.expect
@@ -0,0 +1,22 @@
+library;
+import self as self;
+import "issue_43084_lib.dart" as iss;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///issue_43084_lib.dart";
+
+static method main() → dynamic {
+  iss::Foo<core::int*>* x = new iss::Foo::•<core::int*>();
+  core::print(x);
+}
+
+library /*isNonNullableByDefault*/;
+import self as iss;
+import "dart:core" as core;
+
+typedef Bar<X extends core::Object? = dynamic> = iss::Foo<X%>;
+class Foo<X extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → iss::Foo<iss::Foo::X%>
+    : super core::Object::•()
+    ;
+}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue_43084/issue_43084_lib.dart b/pkg/front_end/testcases/nonfunction_type_aliases/issue_43084/issue_43084_lib.dart
new file mode 100644
index 0000000..75163af
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue_43084/issue_43084_lib.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.
+
+class Foo<X> {
+}
+
+typedef Bar<X> = Foo<X>;
\ No newline at end of file
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases_no_nnbd/issue_43084/test.options b/pkg/front_end/testcases/nonfunction_type_aliases/issue_43084/test.options
similarity index 100%
rename from pkg/front_end/testcases/nonfunction_type_aliases_no_nnbd/issue_43084/test.options
rename to pkg/front_end/testcases/nonfunction_type_aliases/issue_43084/test.options
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart b/pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart
new file mode 100644
index 0000000..30966c9
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart
@@ -0,0 +1,57 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'nullable_supertypes.dart' as prefix;
+
+class A {}
+class B {}
+class C {}
+
+typedef AAlias = A?;
+typedef BAlias = B?;
+typedef CAlias = C?;
+typedef TAlias<T> = T?;
+
+class C1 extends AAlias {}
+
+class C2 implements AAlias {}
+
+class C3 = A with BAlias;
+
+class C4 = A with B implements CAlias;
+
+class C5 extends A with BAlias {}
+
+mixin M1 on AAlias {}
+
+mixin M2 on A, BAlias {}
+
+mixin M3 on A implements BAlias {}
+
+class D1 extends TAlias<A> {}
+
+class D1a extends prefix.TAlias<A> {}
+
+class D1b extends TAlias<prefix.A> {}
+
+class D2 implements TAlias<A> {}
+
+class D3 = A with TAlias<B>;
+
+class D4 = A with B implements TAlias<C>;
+
+class D5 extends A with TAlias<B> {}
+
+mixin N1 on TAlias<A> {}
+
+mixin N1a on prefix.TAlias<A> {}
+
+mixin N1b on TAlias<prefix.A> {}
+
+mixin N2 on A, TAlias<B> {}
+
+mixin N3 on A implements TAlias<B> {}
+
+main() {
+}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart.strong.expect b/pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart.strong.expect
new file mode 100644
index 0000000..1a2fe24
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart.strong.expect
@@ -0,0 +1,383 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:32:18: Error: Can't use a typedef denoting a type variable as a constructor, nor for a static member access.
+// class D1 extends TAlias<A> {}
+//                  ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:16: Context: This is the type variable ultimately denoted.
+// typedef TAlias<T> = T?;
+//                ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:34:19: Error: Can't use a typedef denoting a type variable as a constructor, nor for a static member access.
+// class D1a extends prefix.TAlias<A> {}
+//                   ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:16: Context: This is the type variable ultimately denoted.
+// typedef TAlias<T> = T?;
+//                ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:36:19: Error: Can't use a typedef denoting a type variable as a constructor, nor for a static member access.
+// class D1b extends TAlias<prefix.A> {}
+//                   ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:16: Context: This is the type variable ultimately denoted.
+// typedef TAlias<T> = T?;
+//                ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:38:21: Error: Can't use a typedef denoting a type variable as a constructor, nor for a static member access.
+// class D2 implements TAlias<A> {}
+//                     ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:16: Context: This is the type variable ultimately denoted.
+// typedef TAlias<T> = T?;
+//                ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:40:19: Error: Can't use a typedef denoting a type variable as a constructor, nor for a static member access.
+// class D3 = A with TAlias<B>;
+//                   ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:16: Context: This is the type variable ultimately denoted.
+// typedef TAlias<T> = T?;
+//                ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:40:7: Error: The type 'TAlias' can't be mixed in.
+// class D3 = A with TAlias<B>;
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:9: Context: The issue arises via this type alias.
+// typedef TAlias<T> = T?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:42:32: Error: Can't use a typedef denoting a type variable as a constructor, nor for a static member access.
+// class D4 = A with B implements TAlias<C>;
+//                                ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:16: Context: This is the type variable ultimately denoted.
+// typedef TAlias<T> = T?;
+//                ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:44:25: Error: Can't use a typedef denoting a type variable as a constructor, nor for a static member access.
+// class D5 extends A with TAlias<B> {}
+//                         ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:16: Context: This is the type variable ultimately denoted.
+// typedef TAlias<T> = T?;
+//                ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:44:7: Error: The type 'TAlias' can't be mixed in.
+// class D5 extends A with TAlias<B> {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:9: Context: The issue arises via this type alias.
+// typedef TAlias<T> = T?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:46:13: Error: Can't use a typedef denoting a type variable as a constructor, nor for a static member access.
+// mixin N1 on TAlias<A> {}
+//             ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:16: Context: This is the type variable ultimately denoted.
+// typedef TAlias<T> = T?;
+//                ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:48:14: Error: Can't use a typedef denoting a type variable as a constructor, nor for a static member access.
+// mixin N1a on prefix.TAlias<A> {}
+//              ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:16: Context: This is the type variable ultimately denoted.
+// typedef TAlias<T> = T?;
+//                ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:50:14: Error: Can't use a typedef denoting a type variable as a constructor, nor for a static member access.
+// mixin N1b on TAlias<prefix.A> {}
+//              ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:16: Context: This is the type variable ultimately denoted.
+// typedef TAlias<T> = T?;
+//                ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:52:16: Error: Can't use a typedef denoting a type variable as a constructor, nor for a static member access.
+// mixin N2 on A, TAlias<B> {}
+//                ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:16: Context: This is the type variable ultimately denoted.
+// typedef TAlias<T> = T?;
+//                ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:54:26: Error: Can't use a typedef denoting a type variable as a constructor, nor for a static member access.
+// mixin N3 on A implements TAlias<B> {}
+//                          ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:16: Context: This is the type variable ultimately denoted.
+// typedef TAlias<T> = T?;
+//                ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:16:7: Error: The type 'AAlias' which is an alias of 'A?' can't be used as supertype because it is nullable.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// class C1 extends AAlias {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:11:9: Context: The issue arises via this type alias.
+// typedef AAlias = A?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:18:7: Error: The type 'AAlias' which is an alias of 'A?' can't be used as supertype because it is nullable.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// class C2 implements AAlias {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:11:9: Context: The issue arises via this type alias.
+// typedef AAlias = A?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:20:7: Error: The type 'BAlias' which is an alias of 'B?' can't be used as supertype because it is nullable.
+//  - 'B' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// class C3 = A with BAlias;
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:12:9: Context: The issue arises via this type alias.
+// typedef BAlias = B?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:22:7: Error: The type 'CAlias' which is an alias of 'C?' can't be used as supertype because it is nullable.
+//  - 'C' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// class C4 = A with B implements CAlias;
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:13:9: Context: The issue arises via this type alias.
+// typedef CAlias = C?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:24:7: Error: The type 'BAlias' which is an alias of 'B?' can't be used as supertype because it is nullable.
+//  - 'B' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// class C5 extends A with BAlias {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:12:9: Context: The issue arises via this type alias.
+// typedef BAlias = B?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:26:7: Error: The type 'AAlias' which is an alias of 'A?' can't be used as supertype because it is nullable.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// mixin M1 on AAlias {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:11:9: Context: The issue arises via this type alias.
+// typedef AAlias = A?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:28:7: Error: The type 'BAlias' which is an alias of 'B?' can't be used as supertype because it is nullable.
+//  - 'B' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// mixin M2 on A, BAlias {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:12:9: Context: The issue arises via this type alias.
+// typedef BAlias = B?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:30:7: Error: The type 'BAlias' which is an alias of 'B?' can't be used as supertype because it is nullable.
+//  - 'B' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// mixin M3 on A implements BAlias {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:12:9: Context: The issue arises via this type alias.
+// typedef BAlias = B?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:32:7: Error: The type 'TAlias<A>' which is an alias of 'A?' can't be used as supertype because it is nullable.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// class D1 extends TAlias<A> {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:9: Context: The issue arises via this type alias.
+// typedef TAlias<T> = T?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:34:7: Error: The type 'prefix.TAlias<A>' which is an alias of 'A?' can't be used as supertype because it is nullable.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// class D1a extends prefix.TAlias<A> {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:9: Context: The issue arises via this type alias.
+// typedef TAlias<T> = T?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:36:7: Error: The type 'TAlias<prefix.A>' which is an alias of 'A?' can't be used as supertype because it is nullable.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// class D1b extends TAlias<prefix.A> {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:9: Context: The issue arises via this type alias.
+// typedef TAlias<T> = T?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:38:7: Error: The type 'TAlias<A>' which is an alias of 'A?' can't be used as supertype because it is nullable.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// class D2 implements TAlias<A> {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:9: Context: The issue arises via this type alias.
+// typedef TAlias<T> = T?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:40:7: Error: The type 'TAlias<B>' which is an alias of 'B?' can't be used as supertype because it is nullable.
+//  - 'B' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// class D3 = A with TAlias<B>;
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:9: Context: The issue arises via this type alias.
+// typedef TAlias<T> = T?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:42:7: Error: The type 'TAlias<C>' which is an alias of 'C?' can't be used as supertype because it is nullable.
+//  - 'C' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// class D4 = A with B implements TAlias<C>;
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:9: Context: The issue arises via this type alias.
+// typedef TAlias<T> = T?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:44:7: Error: The type 'TAlias<B>' which is an alias of 'B?' can't be used as supertype because it is nullable.
+//  - 'B' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// class D5 extends A with TAlias<B> {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:9: Context: The issue arises via this type alias.
+// typedef TAlias<T> = T?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:46:7: Error: The type 'TAlias<A>' which is an alias of 'A?' can't be used as supertype because it is nullable.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// mixin N1 on TAlias<A> {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:9: Context: The issue arises via this type alias.
+// typedef TAlias<T> = T?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:48:7: Error: The type 'prefix.TAlias<A>' which is an alias of 'A?' can't be used as supertype because it is nullable.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// mixin N1a on prefix.TAlias<A> {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:9: Context: The issue arises via this type alias.
+// typedef TAlias<T> = T?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:50:7: Error: The type 'TAlias<prefix.A>' which is an alias of 'A?' can't be used as supertype because it is nullable.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// mixin N1b on TAlias<prefix.A> {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:9: Context: The issue arises via this type alias.
+// typedef TAlias<T> = T?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:52:7: Error: The type 'TAlias<B>' which is an alias of 'B?' can't be used as supertype because it is nullable.
+//  - 'B' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// mixin N2 on A, TAlias<B> {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:9: Context: The issue arises via this type alias.
+// typedef TAlias<T> = T?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:54:7: Error: The type 'TAlias<B>' which is an alias of 'B?' can't be used as supertype because it is nullable.
+//  - 'B' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// mixin N3 on A implements TAlias<B> {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:9: Context: The issue arises via this type alias.
+// typedef TAlias<T> = T?;
+//         ^
+//
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///nullable_supertypes.dart" as prefix;
+
+typedef AAlias = self::A?;
+typedef BAlias = self::B?;
+typedef CAlias = self::C?;
+typedef TAlias<T extends core::Object? = dynamic> = T?;
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+}
+class B extends core::Object {
+  synthetic constructor •() → self::B
+    : super core::Object::•()
+    ;
+}
+class C extends core::Object {
+  synthetic constructor •() → self::C
+    : super core::Object::•()
+    ;
+}
+class C1 extends core::Object {
+  synthetic constructor •() → self::C1
+    : super core::Object::•()
+    ;
+}
+class C2 extends core::Object {
+  synthetic constructor •() → self::C2
+    : super core::Object::•()
+    ;
+}
+class C3 extends self::A {
+  synthetic constructor •() → self::C3
+    : super self::A::•()
+    ;
+}
+class C4 = self::A with self::B {
+  synthetic constructor •() → self::C4
+    : super self::A::•()
+    ;
+}
+abstract class _C5&A&BAlias extends self::A /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_C5&A&BAlias
+    : super self::A::•()
+    ;
+}
+class C5 extends self::_C5&A&BAlias {
+  synthetic constructor •() → self::C5
+    : super self::_C5&A&BAlias::•()
+    ;
+}
+abstract class M1 extends core::Object /*isMixinDeclaration*/  {
+}
+abstract class _M2&A&BAlias extends core::Object implements self::A /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_M2&A&BAlias
+    : super core::Object::•()
+    ;
+}
+abstract class M2 extends self::_M2&A&BAlias /*isMixinDeclaration*/  {
+}
+abstract class M3 extends self::A /*isMixinDeclaration*/  {
+}
+class D1 extends core::Object {
+  synthetic constructor •() → self::D1
+    : super core::Object::•()
+    ;
+}
+class D1a extends core::Object {
+  synthetic constructor •() → self::D1a
+    : super core::Object::•()
+    ;
+}
+class D1b extends core::Object {
+  synthetic constructor •() → self::D1b
+    : super core::Object::•()
+    ;
+}
+class D2 extends core::Object {
+  synthetic constructor •() → self::D2
+    : super core::Object::•()
+    ;
+}
+class D3 extends self::A {
+  synthetic constructor •() → self::D3
+    : super self::A::•()
+    ;
+}
+class D4 = self::A with self::B {
+  synthetic constructor •() → self::D4
+    : super self::A::•()
+    ;
+}
+abstract class _D5&A&TAlias extends self::A /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_D5&A&TAlias
+    : super self::A::•()
+    ;
+}
+class D5 extends self::_D5&A&TAlias {
+  synthetic constructor •() → self::D5
+    : super self::_D5&A&TAlias::•()
+    ;
+}
+abstract class N1 extends core::Object /*isMixinDeclaration*/  {
+}
+abstract class N1a extends core::Object /*isMixinDeclaration*/  {
+}
+abstract class N1b extends core::Object /*isMixinDeclaration*/  {
+}
+abstract class _N2&A&TAlias extends core::Object implements self::A /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_N2&A&TAlias
+    : super core::Object::•()
+    ;
+}
+abstract class N2 extends self::_N2&A&TAlias /*isMixinDeclaration*/  {
+}
+abstract class N3 extends self::A /*isMixinDeclaration*/  {
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart.strong.transformed.expect b/pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart.strong.transformed.expect
new file mode 100644
index 0000000..5dac514
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart.strong.transformed.expect
@@ -0,0 +1,383 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:32:18: Error: Can't use a typedef denoting a type variable as a constructor, nor for a static member access.
+// class D1 extends TAlias<A> {}
+//                  ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:16: Context: This is the type variable ultimately denoted.
+// typedef TAlias<T> = T?;
+//                ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:34:19: Error: Can't use a typedef denoting a type variable as a constructor, nor for a static member access.
+// class D1a extends prefix.TAlias<A> {}
+//                   ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:16: Context: This is the type variable ultimately denoted.
+// typedef TAlias<T> = T?;
+//                ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:36:19: Error: Can't use a typedef denoting a type variable as a constructor, nor for a static member access.
+// class D1b extends TAlias<prefix.A> {}
+//                   ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:16: Context: This is the type variable ultimately denoted.
+// typedef TAlias<T> = T?;
+//                ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:38:21: Error: Can't use a typedef denoting a type variable as a constructor, nor for a static member access.
+// class D2 implements TAlias<A> {}
+//                     ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:16: Context: This is the type variable ultimately denoted.
+// typedef TAlias<T> = T?;
+//                ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:40:19: Error: Can't use a typedef denoting a type variable as a constructor, nor for a static member access.
+// class D3 = A with TAlias<B>;
+//                   ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:16: Context: This is the type variable ultimately denoted.
+// typedef TAlias<T> = T?;
+//                ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:40:7: Error: The type 'TAlias' can't be mixed in.
+// class D3 = A with TAlias<B>;
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:9: Context: The issue arises via this type alias.
+// typedef TAlias<T> = T?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:42:32: Error: Can't use a typedef denoting a type variable as a constructor, nor for a static member access.
+// class D4 = A with B implements TAlias<C>;
+//                                ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:16: Context: This is the type variable ultimately denoted.
+// typedef TAlias<T> = T?;
+//                ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:44:25: Error: Can't use a typedef denoting a type variable as a constructor, nor for a static member access.
+// class D5 extends A with TAlias<B> {}
+//                         ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:16: Context: This is the type variable ultimately denoted.
+// typedef TAlias<T> = T?;
+//                ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:44:7: Error: The type 'TAlias' can't be mixed in.
+// class D5 extends A with TAlias<B> {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:9: Context: The issue arises via this type alias.
+// typedef TAlias<T> = T?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:46:13: Error: Can't use a typedef denoting a type variable as a constructor, nor for a static member access.
+// mixin N1 on TAlias<A> {}
+//             ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:16: Context: This is the type variable ultimately denoted.
+// typedef TAlias<T> = T?;
+//                ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:48:14: Error: Can't use a typedef denoting a type variable as a constructor, nor for a static member access.
+// mixin N1a on prefix.TAlias<A> {}
+//              ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:16: Context: This is the type variable ultimately denoted.
+// typedef TAlias<T> = T?;
+//                ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:50:14: Error: Can't use a typedef denoting a type variable as a constructor, nor for a static member access.
+// mixin N1b on TAlias<prefix.A> {}
+//              ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:16: Context: This is the type variable ultimately denoted.
+// typedef TAlias<T> = T?;
+//                ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:52:16: Error: Can't use a typedef denoting a type variable as a constructor, nor for a static member access.
+// mixin N2 on A, TAlias<B> {}
+//                ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:16: Context: This is the type variable ultimately denoted.
+// typedef TAlias<T> = T?;
+//                ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:54:26: Error: Can't use a typedef denoting a type variable as a constructor, nor for a static member access.
+// mixin N3 on A implements TAlias<B> {}
+//                          ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:16: Context: This is the type variable ultimately denoted.
+// typedef TAlias<T> = T?;
+//                ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:16:7: Error: The type 'AAlias' which is an alias of 'A?' can't be used as supertype because it is nullable.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// class C1 extends AAlias {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:11:9: Context: The issue arises via this type alias.
+// typedef AAlias = A?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:18:7: Error: The type 'AAlias' which is an alias of 'A?' can't be used as supertype because it is nullable.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// class C2 implements AAlias {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:11:9: Context: The issue arises via this type alias.
+// typedef AAlias = A?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:20:7: Error: The type 'BAlias' which is an alias of 'B?' can't be used as supertype because it is nullable.
+//  - 'B' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// class C3 = A with BAlias;
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:12:9: Context: The issue arises via this type alias.
+// typedef BAlias = B?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:22:7: Error: The type 'CAlias' which is an alias of 'C?' can't be used as supertype because it is nullable.
+//  - 'C' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// class C4 = A with B implements CAlias;
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:13:9: Context: The issue arises via this type alias.
+// typedef CAlias = C?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:24:7: Error: The type 'BAlias' which is an alias of 'B?' can't be used as supertype because it is nullable.
+//  - 'B' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// class C5 extends A with BAlias {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:12:9: Context: The issue arises via this type alias.
+// typedef BAlias = B?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:26:7: Error: The type 'AAlias' which is an alias of 'A?' can't be used as supertype because it is nullable.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// mixin M1 on AAlias {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:11:9: Context: The issue arises via this type alias.
+// typedef AAlias = A?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:28:7: Error: The type 'BAlias' which is an alias of 'B?' can't be used as supertype because it is nullable.
+//  - 'B' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// mixin M2 on A, BAlias {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:12:9: Context: The issue arises via this type alias.
+// typedef BAlias = B?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:30:7: Error: The type 'BAlias' which is an alias of 'B?' can't be used as supertype because it is nullable.
+//  - 'B' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// mixin M3 on A implements BAlias {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:12:9: Context: The issue arises via this type alias.
+// typedef BAlias = B?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:32:7: Error: The type 'TAlias<A>' which is an alias of 'A?' can't be used as supertype because it is nullable.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// class D1 extends TAlias<A> {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:9: Context: The issue arises via this type alias.
+// typedef TAlias<T> = T?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:34:7: Error: The type 'prefix.TAlias<A>' which is an alias of 'A?' can't be used as supertype because it is nullable.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// class D1a extends prefix.TAlias<A> {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:9: Context: The issue arises via this type alias.
+// typedef TAlias<T> = T?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:36:7: Error: The type 'TAlias<prefix.A>' which is an alias of 'A?' can't be used as supertype because it is nullable.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// class D1b extends TAlias<prefix.A> {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:9: Context: The issue arises via this type alias.
+// typedef TAlias<T> = T?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:38:7: Error: The type 'TAlias<A>' which is an alias of 'A?' can't be used as supertype because it is nullable.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// class D2 implements TAlias<A> {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:9: Context: The issue arises via this type alias.
+// typedef TAlias<T> = T?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:40:7: Error: The type 'TAlias<B>' which is an alias of 'B?' can't be used as supertype because it is nullable.
+//  - 'B' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// class D3 = A with TAlias<B>;
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:9: Context: The issue arises via this type alias.
+// typedef TAlias<T> = T?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:42:7: Error: The type 'TAlias<C>' which is an alias of 'C?' can't be used as supertype because it is nullable.
+//  - 'C' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// class D4 = A with B implements TAlias<C>;
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:9: Context: The issue arises via this type alias.
+// typedef TAlias<T> = T?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:44:7: Error: The type 'TAlias<B>' which is an alias of 'B?' can't be used as supertype because it is nullable.
+//  - 'B' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// class D5 extends A with TAlias<B> {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:9: Context: The issue arises via this type alias.
+// typedef TAlias<T> = T?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:46:7: Error: The type 'TAlias<A>' which is an alias of 'A?' can't be used as supertype because it is nullable.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// mixin N1 on TAlias<A> {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:9: Context: The issue arises via this type alias.
+// typedef TAlias<T> = T?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:48:7: Error: The type 'prefix.TAlias<A>' which is an alias of 'A?' can't be used as supertype because it is nullable.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// mixin N1a on prefix.TAlias<A> {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:9: Context: The issue arises via this type alias.
+// typedef TAlias<T> = T?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:50:7: Error: The type 'TAlias<prefix.A>' which is an alias of 'A?' can't be used as supertype because it is nullable.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// mixin N1b on TAlias<prefix.A> {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:9: Context: The issue arises via this type alias.
+// typedef TAlias<T> = T?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:52:7: Error: The type 'TAlias<B>' which is an alias of 'B?' can't be used as supertype because it is nullable.
+//  - 'B' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// mixin N2 on A, TAlias<B> {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:9: Context: The issue arises via this type alias.
+// typedef TAlias<T> = T?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:54:7: Error: The type 'TAlias<B>' which is an alias of 'B?' can't be used as supertype because it is nullable.
+//  - 'B' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// mixin N3 on A implements TAlias<B> {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:9: Context: The issue arises via this type alias.
+// typedef TAlias<T> = T?;
+//         ^
+//
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///nullable_supertypes.dart" as prefix;
+
+typedef AAlias = self::A?;
+typedef BAlias = self::B?;
+typedef CAlias = self::C?;
+typedef TAlias<T extends core::Object? = dynamic> = T?;
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+}
+class B extends core::Object {
+  synthetic constructor •() → self::B
+    : super core::Object::•()
+    ;
+}
+class C extends core::Object {
+  synthetic constructor •() → self::C
+    : super core::Object::•()
+    ;
+}
+class C1 extends core::Object {
+  synthetic constructor •() → self::C1
+    : super core::Object::•()
+    ;
+}
+class C2 extends core::Object {
+  synthetic constructor •() → self::C2
+    : super core::Object::•()
+    ;
+}
+class C3 extends self::A {
+  synthetic constructor •() → self::C3
+    : super self::A::•()
+    ;
+}
+class C4 extends self::A implements self::B /*isEliminatedMixin*/  {
+  synthetic constructor •() → self::C4
+    : super self::A::•()
+    ;
+}
+abstract class _C5&A&BAlias extends self::A /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_C5&A&BAlias
+    : super self::A::•()
+    ;
+}
+class C5 extends self::_C5&A&BAlias {
+  synthetic constructor •() → self::C5
+    : super self::_C5&A&BAlias::•()
+    ;
+}
+abstract class M1 extends core::Object /*isMixinDeclaration*/  {
+}
+abstract class _M2&A&BAlias extends core::Object implements self::A /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_M2&A&BAlias
+    : super core::Object::•()
+    ;
+}
+abstract class M2 extends self::_M2&A&BAlias /*isMixinDeclaration*/  {
+}
+abstract class M3 extends self::A /*isMixinDeclaration*/  {
+}
+class D1 extends core::Object {
+  synthetic constructor •() → self::D1
+    : super core::Object::•()
+    ;
+}
+class D1a extends core::Object {
+  synthetic constructor •() → self::D1a
+    : super core::Object::•()
+    ;
+}
+class D1b extends core::Object {
+  synthetic constructor •() → self::D1b
+    : super core::Object::•()
+    ;
+}
+class D2 extends core::Object {
+  synthetic constructor •() → self::D2
+    : super core::Object::•()
+    ;
+}
+class D3 extends self::A {
+  synthetic constructor •() → self::D3
+    : super self::A::•()
+    ;
+}
+class D4 extends self::A implements self::B /*isEliminatedMixin*/  {
+  synthetic constructor •() → self::D4
+    : super self::A::•()
+    ;
+}
+abstract class _D5&A&TAlias extends self::A /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_D5&A&TAlias
+    : super self::A::•()
+    ;
+}
+class D5 extends self::_D5&A&TAlias {
+  synthetic constructor •() → self::D5
+    : super self::_D5&A&TAlias::•()
+    ;
+}
+abstract class N1 extends core::Object /*isMixinDeclaration*/  {
+}
+abstract class N1a extends core::Object /*isMixinDeclaration*/  {
+}
+abstract class N1b extends core::Object /*isMixinDeclaration*/  {
+}
+abstract class _N2&A&TAlias extends core::Object implements self::A /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_N2&A&TAlias
+    : super core::Object::•()
+    ;
+}
+abstract class N2 extends self::_N2&A&TAlias /*isMixinDeclaration*/  {
+}
+abstract class N3 extends self::A /*isMixinDeclaration*/  {
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart.textual_outline.expect b/pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart.textual_outline.expect
new file mode 100644
index 0000000..1c0f311
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart.textual_outline.expect
@@ -0,0 +1,45 @@
+import 'nullable_supertypes.dart' as prefix;
+
+class A {}
+
+class B {}
+
+class C {}
+
+typedef AAlias = A?;
+typedef BAlias = B?;
+typedef CAlias = C?;
+typedef TAlias<T> = T?;
+
+class C1 extends AAlias {}
+
+class C2 implements AAlias {}
+
+class C3 = A with BAlias;
+class C4 = A with B implements CAlias;
+
+class C5 extends A with BAlias {}
+
+mixin M1 on AAlias {}
+mixin M2 on A, BAlias {}
+mixin M3 on A implements BAlias {}
+
+class D1 extends TAlias<A> {}
+
+class D1a extends prefix.TAlias<A> {}
+
+class D1b extends TAlias<prefix.A> {}
+
+class D2 implements TAlias<A> {}
+
+class D3 = A with TAlias<B>;
+class D4 = A with B implements TAlias<C>;
+
+class D5 extends A with TAlias<B> {}
+
+mixin N1 on TAlias<A> {}
+mixin N1a on prefix.TAlias<A> {}
+mixin N1b on TAlias<prefix.A> {}
+mixin N2 on A, TAlias<B> {}
+mixin N3 on A implements TAlias<B> {}
+main() {}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..85ec1fa
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart.textual_outline_modelled.expect
@@ -0,0 +1,43 @@
+import 'nullable_supertypes.dart' as prefix;
+
+class A {}
+
+class B {}
+
+class C {}
+
+class C1 extends AAlias {}
+
+class C2 implements AAlias {}
+
+class C3 = A with BAlias;
+class C4 = A with B implements CAlias;
+
+class C5 extends A with BAlias {}
+
+class D1 extends TAlias<A> {}
+
+class D1a extends prefix.TAlias<A> {}
+
+class D1b extends TAlias<prefix.A> {}
+
+class D2 implements TAlias<A> {}
+
+class D3 = A with TAlias<B>;
+class D4 = A with B implements TAlias<C>;
+
+class D5 extends A with TAlias<B> {}
+
+main() {}
+mixin M1 on AAlias {}
+mixin M2 on A, BAlias {}
+mixin M3 on A implements BAlias {}
+mixin N1 on TAlias<A> {}
+mixin N1a on prefix.TAlias<A> {}
+mixin N1b on TAlias<prefix.A> {}
+mixin N2 on A, TAlias<B> {}
+mixin N3 on A implements TAlias<B> {}
+typedef AAlias = A?;
+typedef BAlias = B?;
+typedef CAlias = C?;
+typedef TAlias<T> = T?;
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart.weak.expect b/pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart.weak.expect
new file mode 100644
index 0000000..1a2fe24
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart.weak.expect
@@ -0,0 +1,383 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:32:18: Error: Can't use a typedef denoting a type variable as a constructor, nor for a static member access.
+// class D1 extends TAlias<A> {}
+//                  ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:16: Context: This is the type variable ultimately denoted.
+// typedef TAlias<T> = T?;
+//                ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:34:19: Error: Can't use a typedef denoting a type variable as a constructor, nor for a static member access.
+// class D1a extends prefix.TAlias<A> {}
+//                   ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:16: Context: This is the type variable ultimately denoted.
+// typedef TAlias<T> = T?;
+//                ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:36:19: Error: Can't use a typedef denoting a type variable as a constructor, nor for a static member access.
+// class D1b extends TAlias<prefix.A> {}
+//                   ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:16: Context: This is the type variable ultimately denoted.
+// typedef TAlias<T> = T?;
+//                ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:38:21: Error: Can't use a typedef denoting a type variable as a constructor, nor for a static member access.
+// class D2 implements TAlias<A> {}
+//                     ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:16: Context: This is the type variable ultimately denoted.
+// typedef TAlias<T> = T?;
+//                ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:40:19: Error: Can't use a typedef denoting a type variable as a constructor, nor for a static member access.
+// class D3 = A with TAlias<B>;
+//                   ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:16: Context: This is the type variable ultimately denoted.
+// typedef TAlias<T> = T?;
+//                ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:40:7: Error: The type 'TAlias' can't be mixed in.
+// class D3 = A with TAlias<B>;
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:9: Context: The issue arises via this type alias.
+// typedef TAlias<T> = T?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:42:32: Error: Can't use a typedef denoting a type variable as a constructor, nor for a static member access.
+// class D4 = A with B implements TAlias<C>;
+//                                ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:16: Context: This is the type variable ultimately denoted.
+// typedef TAlias<T> = T?;
+//                ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:44:25: Error: Can't use a typedef denoting a type variable as a constructor, nor for a static member access.
+// class D5 extends A with TAlias<B> {}
+//                         ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:16: Context: This is the type variable ultimately denoted.
+// typedef TAlias<T> = T?;
+//                ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:44:7: Error: The type 'TAlias' can't be mixed in.
+// class D5 extends A with TAlias<B> {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:9: Context: The issue arises via this type alias.
+// typedef TAlias<T> = T?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:46:13: Error: Can't use a typedef denoting a type variable as a constructor, nor for a static member access.
+// mixin N1 on TAlias<A> {}
+//             ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:16: Context: This is the type variable ultimately denoted.
+// typedef TAlias<T> = T?;
+//                ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:48:14: Error: Can't use a typedef denoting a type variable as a constructor, nor for a static member access.
+// mixin N1a on prefix.TAlias<A> {}
+//              ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:16: Context: This is the type variable ultimately denoted.
+// typedef TAlias<T> = T?;
+//                ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:50:14: Error: Can't use a typedef denoting a type variable as a constructor, nor for a static member access.
+// mixin N1b on TAlias<prefix.A> {}
+//              ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:16: Context: This is the type variable ultimately denoted.
+// typedef TAlias<T> = T?;
+//                ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:52:16: Error: Can't use a typedef denoting a type variable as a constructor, nor for a static member access.
+// mixin N2 on A, TAlias<B> {}
+//                ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:16: Context: This is the type variable ultimately denoted.
+// typedef TAlias<T> = T?;
+//                ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:54:26: Error: Can't use a typedef denoting a type variable as a constructor, nor for a static member access.
+// mixin N3 on A implements TAlias<B> {}
+//                          ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:16: Context: This is the type variable ultimately denoted.
+// typedef TAlias<T> = T?;
+//                ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:16:7: Error: The type 'AAlias' which is an alias of 'A?' can't be used as supertype because it is nullable.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// class C1 extends AAlias {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:11:9: Context: The issue arises via this type alias.
+// typedef AAlias = A?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:18:7: Error: The type 'AAlias' which is an alias of 'A?' can't be used as supertype because it is nullable.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// class C2 implements AAlias {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:11:9: Context: The issue arises via this type alias.
+// typedef AAlias = A?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:20:7: Error: The type 'BAlias' which is an alias of 'B?' can't be used as supertype because it is nullable.
+//  - 'B' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// class C3 = A with BAlias;
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:12:9: Context: The issue arises via this type alias.
+// typedef BAlias = B?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:22:7: Error: The type 'CAlias' which is an alias of 'C?' can't be used as supertype because it is nullable.
+//  - 'C' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// class C4 = A with B implements CAlias;
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:13:9: Context: The issue arises via this type alias.
+// typedef CAlias = C?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:24:7: Error: The type 'BAlias' which is an alias of 'B?' can't be used as supertype because it is nullable.
+//  - 'B' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// class C5 extends A with BAlias {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:12:9: Context: The issue arises via this type alias.
+// typedef BAlias = B?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:26:7: Error: The type 'AAlias' which is an alias of 'A?' can't be used as supertype because it is nullable.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// mixin M1 on AAlias {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:11:9: Context: The issue arises via this type alias.
+// typedef AAlias = A?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:28:7: Error: The type 'BAlias' which is an alias of 'B?' can't be used as supertype because it is nullable.
+//  - 'B' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// mixin M2 on A, BAlias {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:12:9: Context: The issue arises via this type alias.
+// typedef BAlias = B?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:30:7: Error: The type 'BAlias' which is an alias of 'B?' can't be used as supertype because it is nullable.
+//  - 'B' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// mixin M3 on A implements BAlias {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:12:9: Context: The issue arises via this type alias.
+// typedef BAlias = B?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:32:7: Error: The type 'TAlias<A>' which is an alias of 'A?' can't be used as supertype because it is nullable.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// class D1 extends TAlias<A> {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:9: Context: The issue arises via this type alias.
+// typedef TAlias<T> = T?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:34:7: Error: The type 'prefix.TAlias<A>' which is an alias of 'A?' can't be used as supertype because it is nullable.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// class D1a extends prefix.TAlias<A> {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:9: Context: The issue arises via this type alias.
+// typedef TAlias<T> = T?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:36:7: Error: The type 'TAlias<prefix.A>' which is an alias of 'A?' can't be used as supertype because it is nullable.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// class D1b extends TAlias<prefix.A> {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:9: Context: The issue arises via this type alias.
+// typedef TAlias<T> = T?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:38:7: Error: The type 'TAlias<A>' which is an alias of 'A?' can't be used as supertype because it is nullable.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// class D2 implements TAlias<A> {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:9: Context: The issue arises via this type alias.
+// typedef TAlias<T> = T?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:40:7: Error: The type 'TAlias<B>' which is an alias of 'B?' can't be used as supertype because it is nullable.
+//  - 'B' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// class D3 = A with TAlias<B>;
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:9: Context: The issue arises via this type alias.
+// typedef TAlias<T> = T?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:42:7: Error: The type 'TAlias<C>' which is an alias of 'C?' can't be used as supertype because it is nullable.
+//  - 'C' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// class D4 = A with B implements TAlias<C>;
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:9: Context: The issue arises via this type alias.
+// typedef TAlias<T> = T?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:44:7: Error: The type 'TAlias<B>' which is an alias of 'B?' can't be used as supertype because it is nullable.
+//  - 'B' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// class D5 extends A with TAlias<B> {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:9: Context: The issue arises via this type alias.
+// typedef TAlias<T> = T?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:46:7: Error: The type 'TAlias<A>' which is an alias of 'A?' can't be used as supertype because it is nullable.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// mixin N1 on TAlias<A> {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:9: Context: The issue arises via this type alias.
+// typedef TAlias<T> = T?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:48:7: Error: The type 'prefix.TAlias<A>' which is an alias of 'A?' can't be used as supertype because it is nullable.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// mixin N1a on prefix.TAlias<A> {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:9: Context: The issue arises via this type alias.
+// typedef TAlias<T> = T?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:50:7: Error: The type 'TAlias<prefix.A>' which is an alias of 'A?' can't be used as supertype because it is nullable.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// mixin N1b on TAlias<prefix.A> {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:9: Context: The issue arises via this type alias.
+// typedef TAlias<T> = T?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:52:7: Error: The type 'TAlias<B>' which is an alias of 'B?' can't be used as supertype because it is nullable.
+//  - 'B' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// mixin N2 on A, TAlias<B> {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:9: Context: The issue arises via this type alias.
+// typedef TAlias<T> = T?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:54:7: Error: The type 'TAlias<B>' which is an alias of 'B?' can't be used as supertype because it is nullable.
+//  - 'B' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// mixin N3 on A implements TAlias<B> {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:9: Context: The issue arises via this type alias.
+// typedef TAlias<T> = T?;
+//         ^
+//
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///nullable_supertypes.dart" as prefix;
+
+typedef AAlias = self::A?;
+typedef BAlias = self::B?;
+typedef CAlias = self::C?;
+typedef TAlias<T extends core::Object? = dynamic> = T?;
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+}
+class B extends core::Object {
+  synthetic constructor •() → self::B
+    : super core::Object::•()
+    ;
+}
+class C extends core::Object {
+  synthetic constructor •() → self::C
+    : super core::Object::•()
+    ;
+}
+class C1 extends core::Object {
+  synthetic constructor •() → self::C1
+    : super core::Object::•()
+    ;
+}
+class C2 extends core::Object {
+  synthetic constructor •() → self::C2
+    : super core::Object::•()
+    ;
+}
+class C3 extends self::A {
+  synthetic constructor •() → self::C3
+    : super self::A::•()
+    ;
+}
+class C4 = self::A with self::B {
+  synthetic constructor •() → self::C4
+    : super self::A::•()
+    ;
+}
+abstract class _C5&A&BAlias extends self::A /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_C5&A&BAlias
+    : super self::A::•()
+    ;
+}
+class C5 extends self::_C5&A&BAlias {
+  synthetic constructor •() → self::C5
+    : super self::_C5&A&BAlias::•()
+    ;
+}
+abstract class M1 extends core::Object /*isMixinDeclaration*/  {
+}
+abstract class _M2&A&BAlias extends core::Object implements self::A /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_M2&A&BAlias
+    : super core::Object::•()
+    ;
+}
+abstract class M2 extends self::_M2&A&BAlias /*isMixinDeclaration*/  {
+}
+abstract class M3 extends self::A /*isMixinDeclaration*/  {
+}
+class D1 extends core::Object {
+  synthetic constructor •() → self::D1
+    : super core::Object::•()
+    ;
+}
+class D1a extends core::Object {
+  synthetic constructor •() → self::D1a
+    : super core::Object::•()
+    ;
+}
+class D1b extends core::Object {
+  synthetic constructor •() → self::D1b
+    : super core::Object::•()
+    ;
+}
+class D2 extends core::Object {
+  synthetic constructor •() → self::D2
+    : super core::Object::•()
+    ;
+}
+class D3 extends self::A {
+  synthetic constructor •() → self::D3
+    : super self::A::•()
+    ;
+}
+class D4 = self::A with self::B {
+  synthetic constructor •() → self::D4
+    : super self::A::•()
+    ;
+}
+abstract class _D5&A&TAlias extends self::A /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_D5&A&TAlias
+    : super self::A::•()
+    ;
+}
+class D5 extends self::_D5&A&TAlias {
+  synthetic constructor •() → self::D5
+    : super self::_D5&A&TAlias::•()
+    ;
+}
+abstract class N1 extends core::Object /*isMixinDeclaration*/  {
+}
+abstract class N1a extends core::Object /*isMixinDeclaration*/  {
+}
+abstract class N1b extends core::Object /*isMixinDeclaration*/  {
+}
+abstract class _N2&A&TAlias extends core::Object implements self::A /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_N2&A&TAlias
+    : super core::Object::•()
+    ;
+}
+abstract class N2 extends self::_N2&A&TAlias /*isMixinDeclaration*/  {
+}
+abstract class N3 extends self::A /*isMixinDeclaration*/  {
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart.weak.outline.expect b/pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart.weak.outline.expect
new file mode 100644
index 0000000..a0cf738
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart.weak.outline.expect
@@ -0,0 +1,371 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:32:18: Error: Can't use a typedef denoting a type variable as a constructor, nor for a static member access.
+// class D1 extends TAlias<A> {}
+//                  ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:16: Context: This is the type variable ultimately denoted.
+// typedef TAlias<T> = T?;
+//                ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:34:19: Error: Can't use a typedef denoting a type variable as a constructor, nor for a static member access.
+// class D1a extends prefix.TAlias<A> {}
+//                   ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:16: Context: This is the type variable ultimately denoted.
+// typedef TAlias<T> = T?;
+//                ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:36:19: Error: Can't use a typedef denoting a type variable as a constructor, nor for a static member access.
+// class D1b extends TAlias<prefix.A> {}
+//                   ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:16: Context: This is the type variable ultimately denoted.
+// typedef TAlias<T> = T?;
+//                ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:38:21: Error: Can't use a typedef denoting a type variable as a constructor, nor for a static member access.
+// class D2 implements TAlias<A> {}
+//                     ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:16: Context: This is the type variable ultimately denoted.
+// typedef TAlias<T> = T?;
+//                ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:40:19: Error: Can't use a typedef denoting a type variable as a constructor, nor for a static member access.
+// class D3 = A with TAlias<B>;
+//                   ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:16: Context: This is the type variable ultimately denoted.
+// typedef TAlias<T> = T?;
+//                ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:40:7: Error: The type 'TAlias' can't be mixed in.
+// class D3 = A with TAlias<B>;
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:9: Context: The issue arises via this type alias.
+// typedef TAlias<T> = T?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:42:32: Error: Can't use a typedef denoting a type variable as a constructor, nor for a static member access.
+// class D4 = A with B implements TAlias<C>;
+//                                ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:16: Context: This is the type variable ultimately denoted.
+// typedef TAlias<T> = T?;
+//                ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:44:25: Error: Can't use a typedef denoting a type variable as a constructor, nor for a static member access.
+// class D5 extends A with TAlias<B> {}
+//                         ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:16: Context: This is the type variable ultimately denoted.
+// typedef TAlias<T> = T?;
+//                ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:44:7: Error: The type 'TAlias' can't be mixed in.
+// class D5 extends A with TAlias<B> {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:9: Context: The issue arises via this type alias.
+// typedef TAlias<T> = T?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:46:13: Error: Can't use a typedef denoting a type variable as a constructor, nor for a static member access.
+// mixin N1 on TAlias<A> {}
+//             ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:16: Context: This is the type variable ultimately denoted.
+// typedef TAlias<T> = T?;
+//                ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:48:14: Error: Can't use a typedef denoting a type variable as a constructor, nor for a static member access.
+// mixin N1a on prefix.TAlias<A> {}
+//              ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:16: Context: This is the type variable ultimately denoted.
+// typedef TAlias<T> = T?;
+//                ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:50:14: Error: Can't use a typedef denoting a type variable as a constructor, nor for a static member access.
+// mixin N1b on TAlias<prefix.A> {}
+//              ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:16: Context: This is the type variable ultimately denoted.
+// typedef TAlias<T> = T?;
+//                ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:52:16: Error: Can't use a typedef denoting a type variable as a constructor, nor for a static member access.
+// mixin N2 on A, TAlias<B> {}
+//                ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:16: Context: This is the type variable ultimately denoted.
+// typedef TAlias<T> = T?;
+//                ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:54:26: Error: Can't use a typedef denoting a type variable as a constructor, nor for a static member access.
+// mixin N3 on A implements TAlias<B> {}
+//                          ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:16: Context: This is the type variable ultimately denoted.
+// typedef TAlias<T> = T?;
+//                ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:16:7: Error: The type 'AAlias' which is an alias of 'A?' can't be used as supertype because it is nullable.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// class C1 extends AAlias {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:11:9: Context: The issue arises via this type alias.
+// typedef AAlias = A?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:18:7: Error: The type 'AAlias' which is an alias of 'A?' can't be used as supertype because it is nullable.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// class C2 implements AAlias {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:11:9: Context: The issue arises via this type alias.
+// typedef AAlias = A?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:20:7: Error: The type 'BAlias' which is an alias of 'B?' can't be used as supertype because it is nullable.
+//  - 'B' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// class C3 = A with BAlias;
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:12:9: Context: The issue arises via this type alias.
+// typedef BAlias = B?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:22:7: Error: The type 'CAlias' which is an alias of 'C?' can't be used as supertype because it is nullable.
+//  - 'C' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// class C4 = A with B implements CAlias;
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:13:9: Context: The issue arises via this type alias.
+// typedef CAlias = C?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:24:7: Error: The type 'BAlias' which is an alias of 'B?' can't be used as supertype because it is nullable.
+//  - 'B' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// class C5 extends A with BAlias {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:12:9: Context: The issue arises via this type alias.
+// typedef BAlias = B?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:26:7: Error: The type 'AAlias' which is an alias of 'A?' can't be used as supertype because it is nullable.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// mixin M1 on AAlias {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:11:9: Context: The issue arises via this type alias.
+// typedef AAlias = A?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:28:7: Error: The type 'BAlias' which is an alias of 'B?' can't be used as supertype because it is nullable.
+//  - 'B' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// mixin M2 on A, BAlias {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:12:9: Context: The issue arises via this type alias.
+// typedef BAlias = B?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:30:7: Error: The type 'BAlias' which is an alias of 'B?' can't be used as supertype because it is nullable.
+//  - 'B' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// mixin M3 on A implements BAlias {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:12:9: Context: The issue arises via this type alias.
+// typedef BAlias = B?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:32:7: Error: The type 'TAlias<A>' which is an alias of 'A?' can't be used as supertype because it is nullable.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// class D1 extends TAlias<A> {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:9: Context: The issue arises via this type alias.
+// typedef TAlias<T> = T?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:34:7: Error: The type 'prefix.TAlias<A>' which is an alias of 'A?' can't be used as supertype because it is nullable.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// class D1a extends prefix.TAlias<A> {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:9: Context: The issue arises via this type alias.
+// typedef TAlias<T> = T?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:36:7: Error: The type 'TAlias<prefix.A>' which is an alias of 'A?' can't be used as supertype because it is nullable.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// class D1b extends TAlias<prefix.A> {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:9: Context: The issue arises via this type alias.
+// typedef TAlias<T> = T?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:38:7: Error: The type 'TAlias<A>' which is an alias of 'A?' can't be used as supertype because it is nullable.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// class D2 implements TAlias<A> {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:9: Context: The issue arises via this type alias.
+// typedef TAlias<T> = T?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:40:7: Error: The type 'TAlias<B>' which is an alias of 'B?' can't be used as supertype because it is nullable.
+//  - 'B' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// class D3 = A with TAlias<B>;
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:9: Context: The issue arises via this type alias.
+// typedef TAlias<T> = T?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:42:7: Error: The type 'TAlias<C>' which is an alias of 'C?' can't be used as supertype because it is nullable.
+//  - 'C' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// class D4 = A with B implements TAlias<C>;
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:9: Context: The issue arises via this type alias.
+// typedef TAlias<T> = T?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:44:7: Error: The type 'TAlias<B>' which is an alias of 'B?' can't be used as supertype because it is nullable.
+//  - 'B' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// class D5 extends A with TAlias<B> {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:9: Context: The issue arises via this type alias.
+// typedef TAlias<T> = T?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:46:7: Error: The type 'TAlias<A>' which is an alias of 'A?' can't be used as supertype because it is nullable.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// mixin N1 on TAlias<A> {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:9: Context: The issue arises via this type alias.
+// typedef TAlias<T> = T?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:48:7: Error: The type 'prefix.TAlias<A>' which is an alias of 'A?' can't be used as supertype because it is nullable.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// mixin N1a on prefix.TAlias<A> {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:9: Context: The issue arises via this type alias.
+// typedef TAlias<T> = T?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:50:7: Error: The type 'TAlias<prefix.A>' which is an alias of 'A?' can't be used as supertype because it is nullable.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// mixin N1b on TAlias<prefix.A> {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:9: Context: The issue arises via this type alias.
+// typedef TAlias<T> = T?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:52:7: Error: The type 'TAlias<B>' which is an alias of 'B?' can't be used as supertype because it is nullable.
+//  - 'B' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// mixin N2 on A, TAlias<B> {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:9: Context: The issue arises via this type alias.
+// typedef TAlias<T> = T?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:54:7: Error: The type 'TAlias<B>' which is an alias of 'B?' can't be used as supertype because it is nullable.
+//  - 'B' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// mixin N3 on A implements TAlias<B> {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:9: Context: The issue arises via this type alias.
+// typedef TAlias<T> = T?;
+//         ^
+//
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///nullable_supertypes.dart" as prefix;
+
+typedef AAlias = self::A?;
+typedef BAlias = self::B?;
+typedef CAlias = self::C?;
+typedef TAlias<T extends core::Object? = dynamic> = T?;
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    ;
+}
+class B extends core::Object {
+  synthetic constructor •() → self::B
+    ;
+}
+class C extends core::Object {
+  synthetic constructor •() → self::C
+    ;
+}
+class C1 extends core::Object {
+  synthetic constructor •() → self::C1
+    ;
+}
+class C2 extends core::Object {
+  synthetic constructor •() → self::C2
+    ;
+}
+class C3 extends self::A {
+  synthetic constructor •() → self::C3
+    : super self::A::•()
+    ;
+}
+class C4 = self::A with self::B {
+  synthetic constructor •() → self::C4
+    : super self::A::•()
+    ;
+}
+abstract class _C5&A&BAlias extends self::A /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_C5&A&BAlias
+    : super self::A::•()
+    ;
+}
+class C5 extends self::_C5&A&BAlias {
+  synthetic constructor •() → self::C5
+    ;
+}
+abstract class M1 extends core::Object /*isMixinDeclaration*/  {
+}
+abstract class _M2&A&BAlias extends core::Object implements self::A /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_M2&A&BAlias
+    ;
+}
+abstract class M2 extends self::_M2&A&BAlias /*isMixinDeclaration*/  {
+}
+abstract class M3 extends self::A /*isMixinDeclaration*/  {
+}
+class D1 extends core::Object {
+  synthetic constructor •() → self::D1
+    ;
+}
+class D1a extends core::Object {
+  synthetic constructor •() → self::D1a
+    ;
+}
+class D1b extends core::Object {
+  synthetic constructor •() → self::D1b
+    ;
+}
+class D2 extends core::Object {
+  synthetic constructor •() → self::D2
+    ;
+}
+class D3 extends self::A {
+  synthetic constructor •() → self::D3
+    : super self::A::•()
+    ;
+}
+class D4 = self::A with self::B {
+  synthetic constructor •() → self::D4
+    : super self::A::•()
+    ;
+}
+abstract class _D5&A&TAlias extends self::A /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_D5&A&TAlias
+    : super self::A::•()
+    ;
+}
+class D5 extends self::_D5&A&TAlias {
+  synthetic constructor •() → self::D5
+    ;
+}
+abstract class N1 extends core::Object /*isMixinDeclaration*/  {
+}
+abstract class N1a extends core::Object /*isMixinDeclaration*/  {
+}
+abstract class N1b extends core::Object /*isMixinDeclaration*/  {
+}
+abstract class _N2&A&TAlias extends core::Object implements self::A /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_N2&A&TAlias
+    ;
+}
+abstract class N2 extends self::_N2&A&TAlias /*isMixinDeclaration*/  {
+}
+abstract class N3 extends self::A /*isMixinDeclaration*/  {
+}
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart.weak.transformed.expect b/pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart.weak.transformed.expect
new file mode 100644
index 0000000..5dac514
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart.weak.transformed.expect
@@ -0,0 +1,383 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:32:18: Error: Can't use a typedef denoting a type variable as a constructor, nor for a static member access.
+// class D1 extends TAlias<A> {}
+//                  ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:16: Context: This is the type variable ultimately denoted.
+// typedef TAlias<T> = T?;
+//                ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:34:19: Error: Can't use a typedef denoting a type variable as a constructor, nor for a static member access.
+// class D1a extends prefix.TAlias<A> {}
+//                   ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:16: Context: This is the type variable ultimately denoted.
+// typedef TAlias<T> = T?;
+//                ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:36:19: Error: Can't use a typedef denoting a type variable as a constructor, nor for a static member access.
+// class D1b extends TAlias<prefix.A> {}
+//                   ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:16: Context: This is the type variable ultimately denoted.
+// typedef TAlias<T> = T?;
+//                ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:38:21: Error: Can't use a typedef denoting a type variable as a constructor, nor for a static member access.
+// class D2 implements TAlias<A> {}
+//                     ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:16: Context: This is the type variable ultimately denoted.
+// typedef TAlias<T> = T?;
+//                ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:40:19: Error: Can't use a typedef denoting a type variable as a constructor, nor for a static member access.
+// class D3 = A with TAlias<B>;
+//                   ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:16: Context: This is the type variable ultimately denoted.
+// typedef TAlias<T> = T?;
+//                ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:40:7: Error: The type 'TAlias' can't be mixed in.
+// class D3 = A with TAlias<B>;
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:9: Context: The issue arises via this type alias.
+// typedef TAlias<T> = T?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:42:32: Error: Can't use a typedef denoting a type variable as a constructor, nor for a static member access.
+// class D4 = A with B implements TAlias<C>;
+//                                ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:16: Context: This is the type variable ultimately denoted.
+// typedef TAlias<T> = T?;
+//                ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:44:25: Error: Can't use a typedef denoting a type variable as a constructor, nor for a static member access.
+// class D5 extends A with TAlias<B> {}
+//                         ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:16: Context: This is the type variable ultimately denoted.
+// typedef TAlias<T> = T?;
+//                ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:44:7: Error: The type 'TAlias' can't be mixed in.
+// class D5 extends A with TAlias<B> {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:9: Context: The issue arises via this type alias.
+// typedef TAlias<T> = T?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:46:13: Error: Can't use a typedef denoting a type variable as a constructor, nor for a static member access.
+// mixin N1 on TAlias<A> {}
+//             ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:16: Context: This is the type variable ultimately denoted.
+// typedef TAlias<T> = T?;
+//                ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:48:14: Error: Can't use a typedef denoting a type variable as a constructor, nor for a static member access.
+// mixin N1a on prefix.TAlias<A> {}
+//              ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:16: Context: This is the type variable ultimately denoted.
+// typedef TAlias<T> = T?;
+//                ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:50:14: Error: Can't use a typedef denoting a type variable as a constructor, nor for a static member access.
+// mixin N1b on TAlias<prefix.A> {}
+//              ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:16: Context: This is the type variable ultimately denoted.
+// typedef TAlias<T> = T?;
+//                ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:52:16: Error: Can't use a typedef denoting a type variable as a constructor, nor for a static member access.
+// mixin N2 on A, TAlias<B> {}
+//                ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:16: Context: This is the type variable ultimately denoted.
+// typedef TAlias<T> = T?;
+//                ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:54:26: Error: Can't use a typedef denoting a type variable as a constructor, nor for a static member access.
+// mixin N3 on A implements TAlias<B> {}
+//                          ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:16: Context: This is the type variable ultimately denoted.
+// typedef TAlias<T> = T?;
+//                ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:16:7: Error: The type 'AAlias' which is an alias of 'A?' can't be used as supertype because it is nullable.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// class C1 extends AAlias {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:11:9: Context: The issue arises via this type alias.
+// typedef AAlias = A?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:18:7: Error: The type 'AAlias' which is an alias of 'A?' can't be used as supertype because it is nullable.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// class C2 implements AAlias {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:11:9: Context: The issue arises via this type alias.
+// typedef AAlias = A?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:20:7: Error: The type 'BAlias' which is an alias of 'B?' can't be used as supertype because it is nullable.
+//  - 'B' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// class C3 = A with BAlias;
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:12:9: Context: The issue arises via this type alias.
+// typedef BAlias = B?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:22:7: Error: The type 'CAlias' which is an alias of 'C?' can't be used as supertype because it is nullable.
+//  - 'C' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// class C4 = A with B implements CAlias;
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:13:9: Context: The issue arises via this type alias.
+// typedef CAlias = C?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:24:7: Error: The type 'BAlias' which is an alias of 'B?' can't be used as supertype because it is nullable.
+//  - 'B' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// class C5 extends A with BAlias {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:12:9: Context: The issue arises via this type alias.
+// typedef BAlias = B?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:26:7: Error: The type 'AAlias' which is an alias of 'A?' can't be used as supertype because it is nullable.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// mixin M1 on AAlias {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:11:9: Context: The issue arises via this type alias.
+// typedef AAlias = A?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:28:7: Error: The type 'BAlias' which is an alias of 'B?' can't be used as supertype because it is nullable.
+//  - 'B' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// mixin M2 on A, BAlias {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:12:9: Context: The issue arises via this type alias.
+// typedef BAlias = B?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:30:7: Error: The type 'BAlias' which is an alias of 'B?' can't be used as supertype because it is nullable.
+//  - 'B' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// mixin M3 on A implements BAlias {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:12:9: Context: The issue arises via this type alias.
+// typedef BAlias = B?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:32:7: Error: The type 'TAlias<A>' which is an alias of 'A?' can't be used as supertype because it is nullable.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// class D1 extends TAlias<A> {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:9: Context: The issue arises via this type alias.
+// typedef TAlias<T> = T?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:34:7: Error: The type 'prefix.TAlias<A>' which is an alias of 'A?' can't be used as supertype because it is nullable.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// class D1a extends prefix.TAlias<A> {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:9: Context: The issue arises via this type alias.
+// typedef TAlias<T> = T?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:36:7: Error: The type 'TAlias<prefix.A>' which is an alias of 'A?' can't be used as supertype because it is nullable.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// class D1b extends TAlias<prefix.A> {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:9: Context: The issue arises via this type alias.
+// typedef TAlias<T> = T?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:38:7: Error: The type 'TAlias<A>' which is an alias of 'A?' can't be used as supertype because it is nullable.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// class D2 implements TAlias<A> {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:9: Context: The issue arises via this type alias.
+// typedef TAlias<T> = T?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:40:7: Error: The type 'TAlias<B>' which is an alias of 'B?' can't be used as supertype because it is nullable.
+//  - 'B' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// class D3 = A with TAlias<B>;
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:9: Context: The issue arises via this type alias.
+// typedef TAlias<T> = T?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:42:7: Error: The type 'TAlias<C>' which is an alias of 'C?' can't be used as supertype because it is nullable.
+//  - 'C' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// class D4 = A with B implements TAlias<C>;
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:9: Context: The issue arises via this type alias.
+// typedef TAlias<T> = T?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:44:7: Error: The type 'TAlias<B>' which is an alias of 'B?' can't be used as supertype because it is nullable.
+//  - 'B' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// class D5 extends A with TAlias<B> {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:9: Context: The issue arises via this type alias.
+// typedef TAlias<T> = T?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:46:7: Error: The type 'TAlias<A>' which is an alias of 'A?' can't be used as supertype because it is nullable.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// mixin N1 on TAlias<A> {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:9: Context: The issue arises via this type alias.
+// typedef TAlias<T> = T?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:48:7: Error: The type 'prefix.TAlias<A>' which is an alias of 'A?' can't be used as supertype because it is nullable.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// mixin N1a on prefix.TAlias<A> {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:9: Context: The issue arises via this type alias.
+// typedef TAlias<T> = T?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:50:7: Error: The type 'TAlias<prefix.A>' which is an alias of 'A?' can't be used as supertype because it is nullable.
+//  - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// mixin N1b on TAlias<prefix.A> {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:9: Context: The issue arises via this type alias.
+// typedef TAlias<T> = T?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:52:7: Error: The type 'TAlias<B>' which is an alias of 'B?' can't be used as supertype because it is nullable.
+//  - 'B' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// mixin N2 on A, TAlias<B> {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:9: Context: The issue arises via this type alias.
+// typedef TAlias<T> = T?;
+//         ^
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:54:7: Error: The type 'TAlias<B>' which is an alias of 'B?' can't be used as supertype because it is nullable.
+//  - 'B' is from 'pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart'.
+// mixin N3 on A implements TAlias<B> {}
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/nullable_supertypes.dart:14:9: Context: The issue arises via this type alias.
+// typedef TAlias<T> = T?;
+//         ^
+//
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///nullable_supertypes.dart" as prefix;
+
+typedef AAlias = self::A?;
+typedef BAlias = self::B?;
+typedef CAlias = self::C?;
+typedef TAlias<T extends core::Object? = dynamic> = T?;
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+}
+class B extends core::Object {
+  synthetic constructor •() → self::B
+    : super core::Object::•()
+    ;
+}
+class C extends core::Object {
+  synthetic constructor •() → self::C
+    : super core::Object::•()
+    ;
+}
+class C1 extends core::Object {
+  synthetic constructor •() → self::C1
+    : super core::Object::•()
+    ;
+}
+class C2 extends core::Object {
+  synthetic constructor •() → self::C2
+    : super core::Object::•()
+    ;
+}
+class C3 extends self::A {
+  synthetic constructor •() → self::C3
+    : super self::A::•()
+    ;
+}
+class C4 extends self::A implements self::B /*isEliminatedMixin*/  {
+  synthetic constructor •() → self::C4
+    : super self::A::•()
+    ;
+}
+abstract class _C5&A&BAlias extends self::A /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_C5&A&BAlias
+    : super self::A::•()
+    ;
+}
+class C5 extends self::_C5&A&BAlias {
+  synthetic constructor •() → self::C5
+    : super self::_C5&A&BAlias::•()
+    ;
+}
+abstract class M1 extends core::Object /*isMixinDeclaration*/  {
+}
+abstract class _M2&A&BAlias extends core::Object implements self::A /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_M2&A&BAlias
+    : super core::Object::•()
+    ;
+}
+abstract class M2 extends self::_M2&A&BAlias /*isMixinDeclaration*/  {
+}
+abstract class M3 extends self::A /*isMixinDeclaration*/  {
+}
+class D1 extends core::Object {
+  synthetic constructor •() → self::D1
+    : super core::Object::•()
+    ;
+}
+class D1a extends core::Object {
+  synthetic constructor •() → self::D1a
+    : super core::Object::•()
+    ;
+}
+class D1b extends core::Object {
+  synthetic constructor •() → self::D1b
+    : super core::Object::•()
+    ;
+}
+class D2 extends core::Object {
+  synthetic constructor •() → self::D2
+    : super core::Object::•()
+    ;
+}
+class D3 extends self::A {
+  synthetic constructor •() → self::D3
+    : super self::A::•()
+    ;
+}
+class D4 extends self::A implements self::B /*isEliminatedMixin*/  {
+  synthetic constructor •() → self::D4
+    : super self::A::•()
+    ;
+}
+abstract class _D5&A&TAlias extends self::A /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_D5&A&TAlias
+    : super self::A::•()
+    ;
+}
+class D5 extends self::_D5&A&TAlias {
+  synthetic constructor •() → self::D5
+    : super self::_D5&A&TAlias::•()
+    ;
+}
+abstract class N1 extends core::Object /*isMixinDeclaration*/  {
+}
+abstract class N1a extends core::Object /*isMixinDeclaration*/  {
+}
+abstract class N1b extends core::Object /*isMixinDeclaration*/  {
+}
+abstract class _N2&A&TAlias extends core::Object implements self::A /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_N2&A&TAlias
+    : super core::Object::•()
+    ;
+}
+abstract class N2 extends self::_N2&A&TAlias /*isMixinDeclaration*/  {
+}
+abstract class N3 extends self::A /*isMixinDeclaration*/  {
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/old_version.dart b/pkg/front_end/testcases/nonfunction_type_aliases/old_version.dart
new file mode 100644
index 0000000..932fe93
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/old_version.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.12
+
+typedef A = int;
+
+void main() {}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/old_version.dart.strong.expect b/pkg/front_end/testcases/nonfunction_type_aliases/old_version.dart.strong.expect
new file mode 100644
index 0000000..104aeb2
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/old_version.dart.strong.expect
@@ -0,0 +1,12 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/old_version.dart:7:11: Error: Can't create typedef from non-function type.
+// typedef A = int;
+//           ^
+//
+import self as self;
+
+typedef A = invalid-type;
+static method main() → void {}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/old_version.dart.strong.transformed.expect b/pkg/front_end/testcases/nonfunction_type_aliases/old_version.dart.strong.transformed.expect
new file mode 100644
index 0000000..104aeb2
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/old_version.dart.strong.transformed.expect
@@ -0,0 +1,12 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/old_version.dart:7:11: Error: Can't create typedef from non-function type.
+// typedef A = int;
+//           ^
+//
+import self as self;
+
+typedef A = invalid-type;
+static method main() → void {}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/old_version.dart.textual_outline.expect b/pkg/front_end/testcases/nonfunction_type_aliases/old_version.dart.textual_outline.expect
new file mode 100644
index 0000000..14f266b
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/old_version.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+// @dart = 2.12
+typedef A = int;
+void main() {}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/old_version.dart.weak.expect b/pkg/front_end/testcases/nonfunction_type_aliases/old_version.dart.weak.expect
new file mode 100644
index 0000000..104aeb2
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/old_version.dart.weak.expect
@@ -0,0 +1,12 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/old_version.dart:7:11: Error: Can't create typedef from non-function type.
+// typedef A = int;
+//           ^
+//
+import self as self;
+
+typedef A = invalid-type;
+static method main() → void {}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/old_version.dart.weak.outline.expect b/pkg/front_end/testcases/nonfunction_type_aliases/old_version.dart.weak.outline.expect
new file mode 100644
index 0000000..2f9bbe5
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/old_version.dart.weak.outline.expect
@@ -0,0 +1,13 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/old_version.dart:7:11: Error: Can't create typedef from non-function type.
+// typedef A = int;
+//           ^
+//
+import self as self;
+
+typedef A = invalid-type;
+static method main() → void
+  ;
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/old_version.dart.weak.transformed.expect b/pkg/front_end/testcases/nonfunction_type_aliases/old_version.dart.weak.transformed.expect
new file mode 100644
index 0000000..104aeb2
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/old_version.dart.weak.transformed.expect
@@ -0,0 +1,12 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/old_version.dart:7:11: Error: Can't create typedef from non-function type.
+// typedef A = int;
+//           ^
+//
+import self as self;
+
+typedef A = invalid-type;
+static method main() → void {}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls.dart b/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls.dart
new file mode 100644
index 0000000..2da162b
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class C<X> {}
+typedef A<X extends num, Y> = C<X>;
+
+foo() {
+  new A<dynamic, String>();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls.dart.strong.expect b/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls.dart.strong.expect
new file mode 100644
index 0000000..0c361f8
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls.dart.strong.expect
@@ -0,0 +1,25 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls.dart:9:7: Error: Type argument 'dynamic' doesn't conform to the bound 'num' of the type variable 'X' on 'A'.
+// Try changing type arguments so that they conform to the bounds.
+//   new A<dynamic, String>();
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls.dart:6:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef A<X extends num, Y> = C<X>;
+//           ^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef A<X extends core::num = core::num, unrelated Y extends core::Object? = dynamic> = self::C<X>;
+class C<X extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::C<self::C::X%>
+    : super core::Object::•()
+    ;
+}
+static method foo() → dynamic {
+  new self::C::•<dynamic>();
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls.dart.strong.transformed.expect b/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls.dart.strong.transformed.expect
new file mode 100644
index 0000000..0c361f8
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls.dart.strong.transformed.expect
@@ -0,0 +1,25 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls.dart:9:7: Error: Type argument 'dynamic' doesn't conform to the bound 'num' of the type variable 'X' on 'A'.
+// Try changing type arguments so that they conform to the bounds.
+//   new A<dynamic, String>();
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls.dart:6:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef A<X extends num, Y> = C<X>;
+//           ^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef A<X extends core::num = core::num, unrelated Y extends core::Object? = dynamic> = self::C<X>;
+class C<X extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::C<self::C::X%>
+    : super core::Object::•()
+    ;
+}
+static method foo() → dynamic {
+  new self::C::•<dynamic>();
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls.dart.textual_outline.expect b/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls.dart.textual_outline.expect
new file mode 100644
index 0000000..048066b
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+class C<X> {}
+
+typedef A<X extends num, Y> = C<X>;
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1121072
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+class C<X> {}
+
+foo() {}
+main() {}
+typedef A<X extends num, Y> = C<X>;
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls.dart.weak.expect b/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls.dart.weak.expect
new file mode 100644
index 0000000..0c361f8
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls.dart.weak.expect
@@ -0,0 +1,25 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls.dart:9:7: Error: Type argument 'dynamic' doesn't conform to the bound 'num' of the type variable 'X' on 'A'.
+// Try changing type arguments so that they conform to the bounds.
+//   new A<dynamic, String>();
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls.dart:6:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef A<X extends num, Y> = C<X>;
+//           ^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef A<X extends core::num = core::num, unrelated Y extends core::Object? = dynamic> = self::C<X>;
+class C<X extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::C<self::C::X%>
+    : super core::Object::•()
+    ;
+}
+static method foo() → dynamic {
+  new self::C::•<dynamic>();
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls.dart.weak.outline.expect b/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls.dart.weak.outline.expect
new file mode 100644
index 0000000..67117f8
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls.dart.weak.outline.expect
@@ -0,0 +1,13 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+typedef A<X extends core::num = core::num, unrelated Y extends core::Object? = dynamic> = self::C<X>;
+class C<X extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::C<self::C::X%>
+    ;
+}
+static method foo() → dynamic
+  ;
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls.dart.weak.transformed.expect b/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls.dart.weak.transformed.expect
new file mode 100644
index 0000000..0c361f8
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls.dart.weak.transformed.expect
@@ -0,0 +1,25 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls.dart:9:7: Error: Type argument 'dynamic' doesn't conform to the bound 'num' of the type variable 'X' on 'A'.
+// Try changing type arguments so that they conform to the bounds.
+//   new A<dynamic, String>();
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls.dart:6:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef A<X extends num, Y> = C<X>;
+//           ^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef A<X extends core::num = core::num, unrelated Y extends core::Object? = dynamic> = self::C<X>;
+class C<X extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::C<self::C::X%>
+    : super core::Object::•()
+    ;
+}
+static method foo() → dynamic {
+  new self::C::•<dynamic>();
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls_with_parts_lib.dart b/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls_with_parts_lib.dart
new file mode 100644
index 0000000..c93b7d9
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls_with_parts_lib.dart
@@ -0,0 +1,7 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for 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 unaliased_bounds_checks_in_constructor_calls_with_parts_lib;
+
+part './unaliased_bounds_checks_in_constructor_calls_with_parts_part_lib.dart';
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls_with_parts_main.dart b/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls_with_parts_main.dart
new file mode 100644
index 0000000..9bf694a
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls_with_parts_main.dart
@@ -0,0 +1,7 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import './unaliased_bounds_checks_in_constructor_calls_with_parts_lib.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls_with_parts_main.dart.strong.expect b/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls_with_parts_main.dart.strong.expect
new file mode 100644
index 0000000..afdc55d
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls_with_parts_main.dart.strong.expect
@@ -0,0 +1,32 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+
+import "org-dartlang-testcase:///unaliased_bounds_checks_in_constructor_calls_with_parts_lib.dart";
+
+static method main() → dynamic {}
+
+library unaliased_bounds_checks_in_constructor_calls_with_parts_lib /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls_with_parts_part_lib.dart:11:7: Error: Type argument 'dynamic' doesn't conform to the bound 'num' of the type variable 'X' on 'A'.
+// Try changing type arguments so that they conform to the bounds.
+//   new A<dynamic, String>();
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls_with_parts_part_lib.dart:8:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef A<X extends num, Y> = C<X>;
+//           ^
+//
+import self as self2;
+import "dart:core" as core;
+
+part ./unaliased_bounds_checks_in_constructor_calls_with_parts_part_lib.dart;
+typedef A<X extends core::num = core::num, unrelated Y extends core::Object? = dynamic> = self2::C<X>;
+class C<X extends core::Object? = dynamic> extends core::Object { // from org-dartlang-testcase:///unaliased_bounds_checks_in_constructor_calls_with_parts_part_lib.dart
+  synthetic constructor •() → self2::C<self2::C::X%>
+    : super core::Object::•()
+    ;
+}
+static method /* from org-dartlang-testcase:///unaliased_bounds_checks_in_constructor_calls_with_parts_part_lib.dart */ foo() → dynamic {
+  new self2::C::•<dynamic>();
+}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls_with_parts_main.dart.strong.transformed.expect b/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls_with_parts_main.dart.strong.transformed.expect
new file mode 100644
index 0000000..afdc55d
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls_with_parts_main.dart.strong.transformed.expect
@@ -0,0 +1,32 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+
+import "org-dartlang-testcase:///unaliased_bounds_checks_in_constructor_calls_with_parts_lib.dart";
+
+static method main() → dynamic {}
+
+library unaliased_bounds_checks_in_constructor_calls_with_parts_lib /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls_with_parts_part_lib.dart:11:7: Error: Type argument 'dynamic' doesn't conform to the bound 'num' of the type variable 'X' on 'A'.
+// Try changing type arguments so that they conform to the bounds.
+//   new A<dynamic, String>();
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls_with_parts_part_lib.dart:8:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef A<X extends num, Y> = C<X>;
+//           ^
+//
+import self as self2;
+import "dart:core" as core;
+
+part ./unaliased_bounds_checks_in_constructor_calls_with_parts_part_lib.dart;
+typedef A<X extends core::num = core::num, unrelated Y extends core::Object? = dynamic> = self2::C<X>;
+class C<X extends core::Object? = dynamic> extends core::Object { // from org-dartlang-testcase:///unaliased_bounds_checks_in_constructor_calls_with_parts_part_lib.dart
+  synthetic constructor •() → self2::C<self2::C::X%>
+    : super core::Object::•()
+    ;
+}
+static method /* from org-dartlang-testcase:///unaliased_bounds_checks_in_constructor_calls_with_parts_part_lib.dart */ foo() → dynamic {
+  new self2::C::•<dynamic>();
+}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls_with_parts_main.dart.textual_outline.expect b/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls_with_parts_main.dart.textual_outline.expect
new file mode 100644
index 0000000..c76bce2
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls_with_parts_main.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+import './unaliased_bounds_checks_in_constructor_calls_with_parts_lib.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls_with_parts_main.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls_with_parts_main.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c76bce2
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls_with_parts_main.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+import './unaliased_bounds_checks_in_constructor_calls_with_parts_lib.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls_with_parts_main.dart.weak.expect b/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls_with_parts_main.dart.weak.expect
new file mode 100644
index 0000000..afdc55d
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls_with_parts_main.dart.weak.expect
@@ -0,0 +1,32 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+
+import "org-dartlang-testcase:///unaliased_bounds_checks_in_constructor_calls_with_parts_lib.dart";
+
+static method main() → dynamic {}
+
+library unaliased_bounds_checks_in_constructor_calls_with_parts_lib /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls_with_parts_part_lib.dart:11:7: Error: Type argument 'dynamic' doesn't conform to the bound 'num' of the type variable 'X' on 'A'.
+// Try changing type arguments so that they conform to the bounds.
+//   new A<dynamic, String>();
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls_with_parts_part_lib.dart:8:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef A<X extends num, Y> = C<X>;
+//           ^
+//
+import self as self2;
+import "dart:core" as core;
+
+part ./unaliased_bounds_checks_in_constructor_calls_with_parts_part_lib.dart;
+typedef A<X extends core::num = core::num, unrelated Y extends core::Object? = dynamic> = self2::C<X>;
+class C<X extends core::Object? = dynamic> extends core::Object { // from org-dartlang-testcase:///unaliased_bounds_checks_in_constructor_calls_with_parts_part_lib.dart
+  synthetic constructor •() → self2::C<self2::C::X%>
+    : super core::Object::•()
+    ;
+}
+static method /* from org-dartlang-testcase:///unaliased_bounds_checks_in_constructor_calls_with_parts_part_lib.dart */ foo() → dynamic {
+  new self2::C::•<dynamic>();
+}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls_with_parts_main.dart.weak.outline.expect b/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls_with_parts_main.dart.weak.outline.expect
new file mode 100644
index 0000000..d3cc16c
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls_with_parts_main.dart.weak.outline.expect
@@ -0,0 +1,20 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+
+import "org-dartlang-testcase:///unaliased_bounds_checks_in_constructor_calls_with_parts_lib.dart";
+
+static method main() → dynamic
+  ;
+
+library unaliased_bounds_checks_in_constructor_calls_with_parts_lib /*isNonNullableByDefault*/;
+import self as self2;
+import "dart:core" as core;
+
+part ./unaliased_bounds_checks_in_constructor_calls_with_parts_part_lib.dart;
+typedef A<X extends core::num = core::num, unrelated Y extends core::Object? = dynamic> = self2::C<X>;
+class C<X extends core::Object? = dynamic> extends core::Object { // from org-dartlang-testcase:///unaliased_bounds_checks_in_constructor_calls_with_parts_part_lib.dart
+  synthetic constructor •() → self2::C<self2::C::X%>
+    ;
+}
+static method /* from org-dartlang-testcase:///unaliased_bounds_checks_in_constructor_calls_with_parts_part_lib.dart */ foo() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls_with_parts_main.dart.weak.transformed.expect b/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls_with_parts_main.dart.weak.transformed.expect
new file mode 100644
index 0000000..afdc55d
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls_with_parts_main.dart.weak.transformed.expect
@@ -0,0 +1,32 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+
+import "org-dartlang-testcase:///unaliased_bounds_checks_in_constructor_calls_with_parts_lib.dart";
+
+static method main() → dynamic {}
+
+library unaliased_bounds_checks_in_constructor_calls_with_parts_lib /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls_with_parts_part_lib.dart:11:7: Error: Type argument 'dynamic' doesn't conform to the bound 'num' of the type variable 'X' on 'A'.
+// Try changing type arguments so that they conform to the bounds.
+//   new A<dynamic, String>();
+//       ^
+// pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls_with_parts_part_lib.dart:8:11: Context: This is the type variable whose bound isn't conformed to.
+// typedef A<X extends num, Y> = C<X>;
+//           ^
+//
+import self as self2;
+import "dart:core" as core;
+
+part ./unaliased_bounds_checks_in_constructor_calls_with_parts_part_lib.dart;
+typedef A<X extends core::num = core::num, unrelated Y extends core::Object? = dynamic> = self2::C<X>;
+class C<X extends core::Object? = dynamic> extends core::Object { // from org-dartlang-testcase:///unaliased_bounds_checks_in_constructor_calls_with_parts_part_lib.dart
+  synthetic constructor •() → self2::C<self2::C::X%>
+    : super core::Object::•()
+    ;
+}
+static method /* from org-dartlang-testcase:///unaliased_bounds_checks_in_constructor_calls_with_parts_part_lib.dart */ foo() → dynamic {
+  new self2::C::•<dynamic>();
+}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls_with_parts_part_lib.dart b/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls_with_parts_part_lib.dart
new file mode 100644
index 0000000..3ccd59b
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls_with_parts_part_lib.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for 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 unaliased_bounds_checks_in_constructor_calls_with_parts_lib;
+
+class C<X> {}
+typedef A<X extends num, Y> = C<X>;
+
+foo() {
+  new A<dynamic, String>();
+}
+
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases_no_nnbd/folder.options b/pkg/front_end/testcases/nonfunction_type_aliases_no_nnbd/folder.options
deleted file mode 100644
index f1e0c43..0000000
--- a/pkg/front_end/testcases/nonfunction_type_aliases_no_nnbd/folder.options
+++ /dev/null
@@ -1 +0,0 @@
---enable-experiment=nonfunction-type-aliases
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases_no_nnbd/issue_43084/issue_43084.dart b/pkg/front_end/testcases/nonfunction_type_aliases_no_nnbd/issue_43084/issue_43084.dart
deleted file mode 100644
index 0e9dfeb..0000000
--- a/pkg/front_end/testcases/nonfunction_type_aliases_no_nnbd/issue_43084/issue_43084.dart
+++ /dev/null
@@ -1,10 +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.
-// @dart=2.9
-import "issue_43084_lib.dart";
-
-main() {
-  Bar<int> x = new Bar<int>();
-  print(x);
-}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases_no_nnbd/issue_43084/issue_43084.dart.textual_outline.expect b/pkg/front_end/testcases/nonfunction_type_aliases_no_nnbd/issue_43084/issue_43084.dart.textual_outline.expect
deleted file mode 100644
index 9591f62..0000000
--- a/pkg/front_end/testcases/nonfunction_type_aliases_no_nnbd/issue_43084/issue_43084.dart.textual_outline.expect
+++ /dev/null
@@ -1,4 +0,0 @@
-// @dart = 2.9
-import "issue_43084_lib.dart";
-
-main() {}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases_no_nnbd/issue_43084/issue_43084.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nonfunction_type_aliases_no_nnbd/issue_43084/issue_43084.dart.textual_outline_modelled.expect
deleted file mode 100644
index 9591f62..0000000
--- a/pkg/front_end/testcases/nonfunction_type_aliases_no_nnbd/issue_43084/issue_43084.dart.textual_outline_modelled.expect
+++ /dev/null
@@ -1,4 +0,0 @@
-// @dart = 2.9
-import "issue_43084_lib.dart";
-
-main() {}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases_no_nnbd/issue_43084/issue_43084.dart.weak.expect b/pkg/front_end/testcases/nonfunction_type_aliases_no_nnbd/issue_43084/issue_43084.dart.weak.expect
deleted file mode 100644
index e216ebf..0000000
--- a/pkg/front_end/testcases/nonfunction_type_aliases_no_nnbd/issue_43084/issue_43084.dart.weak.expect
+++ /dev/null
@@ -1,32 +0,0 @@
-library;
-import self as self;
-import "issue_43084_lib.dart" as iss;
-import "dart:core" as core;
-
-import "org-dartlang-testcase:///issue_43084_lib.dart";
-
-static method main() → dynamic {
-  iss::Foo<core::int*>* x = new iss::Foo::•<core::int*>();
-  core::print(x);
-}
-
-library;
-import self as iss;
-import "dart:core" as core;
-
-typedef Bar<X extends core::Object* = dynamic> = iss::Foo<X*>*;
-class Foo<X extends core::Object* = dynamic> extends core::Object {
-  synthetic constructor •() → iss::Foo<iss::Foo::X*>*
-    : 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
-}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases_no_nnbd/issue_43084/issue_43084.dart.weak.outline.expect b/pkg/front_end/testcases/nonfunction_type_aliases_no_nnbd/issue_43084/issue_43084.dart.weak.outline.expect
deleted file mode 100644
index 796c6b3..0000000
--- a/pkg/front_end/testcases/nonfunction_type_aliases_no_nnbd/issue_43084/issue_43084.dart.weak.outline.expect
+++ /dev/null
@@ -1,27 +0,0 @@
-library;
-import self as self;
-
-import "org-dartlang-testcase:///issue_43084_lib.dart";
-
-static method main() → dynamic
-  ;
-
-library;
-import self as self2;
-import "dart:core" as core;
-
-typedef Bar<X extends core::Object* = dynamic> = self2::Foo<X*>*;
-class Foo<X extends core::Object* = dynamic> extends core::Object {
-  synthetic constructor •() → self2::Foo<self2::Foo::X*>*
-    ;
-  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
-}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases_no_nnbd/issue_43084/issue_43084.dart.weak.transformed.expect b/pkg/front_end/testcases/nonfunction_type_aliases_no_nnbd/issue_43084/issue_43084.dart.weak.transformed.expect
deleted file mode 100644
index e216ebf..0000000
--- a/pkg/front_end/testcases/nonfunction_type_aliases_no_nnbd/issue_43084/issue_43084.dart.weak.transformed.expect
+++ /dev/null
@@ -1,32 +0,0 @@
-library;
-import self as self;
-import "issue_43084_lib.dart" as iss;
-import "dart:core" as core;
-
-import "org-dartlang-testcase:///issue_43084_lib.dart";
-
-static method main() → dynamic {
-  iss::Foo<core::int*>* x = new iss::Foo::•<core::int*>();
-  core::print(x);
-}
-
-library;
-import self as iss;
-import "dart:core" as core;
-
-typedef Bar<X extends core::Object* = dynamic> = iss::Foo<X*>*;
-class Foo<X extends core::Object* = dynamic> extends core::Object {
-  synthetic constructor •() → iss::Foo<iss::Foo::X*>*
-    : 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
-}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases_no_nnbd/issue_43084/issue_43084_lib.dart b/pkg/front_end/testcases/nonfunction_type_aliases_no_nnbd/issue_43084/issue_43084_lib.dart
deleted file mode 100644
index 647ad1d..0000000
--- a/pkg/front_end/testcases/nonfunction_type_aliases_no_nnbd/issue_43084/issue_43084_lib.dart
+++ /dev/null
@@ -1,8 +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.
-// @dart=2.9
-class Foo<X> {
-}
-
-typedef Bar<X> = Foo<X>;
\ No newline at end of file
diff --git a/pkg/front_end/testcases/outline.status b/pkg/front_end/testcases/outline.status
index 63e873f..dc7cac2 100644
--- a/pkg/front_end/testcases/outline.status
+++ b/pkg/front_end/testcases/outline.status
@@ -2,11 +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.md file.
 
+const_functions/const_functions_const_factory: VerificationError
 extension_types/simple: ExpectationFileMismatchSerialized
+extension_types/simple_getter_resolution: ExpectationFileMismatchSerialized
 extension_types/simple_method_resolution: ExpectationFileMismatchSerialized
+extension_types/simple_operator_resolution: ExpectationFileMismatchSerialized
+extension_types/simple_setter_resolution: ExpectationFileMismatchSerialized
 general/abstract_members: TypeCheckError
 general/bug30695: TypeCheckError
 general/covariant_field: TypeCheckError
+general/crashes/crash_02/main: Crash
+general/crashes/crash_04/main: Crash
 general/getter_vs_setter_type: TypeCheckError
 general/infer_field_from_multiple: TypeCheckError
 general/invalid_operator: TypeCheckError
diff --git a/pkg/front_end/testcases/regress/issue_31155.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_31155.dart.textual_outline.expect
index 79e9364..89f0128 100644
--- a/pkg/front_end/testcases/regress/issue_31155.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/regress/issue_31155.dart.textual_outline.expect
@@ -2,8 +2,6 @@
 class A {}
 class B {}
 class C {
-  var f = Map<A, B;
-  operator> (){}
-  ;
+  var f = Map<A, B> {};
 }
 void main() {}
diff --git a/pkg/front_end/testcases/regress/issue_31155.dart.weak.expect b/pkg/front_end/testcases/regress/issue_31155.dart.weak.expect
index 1cad098..2f83d69 100644
--- a/pkg/front_end/testcases/regress/issue_31155.dart.weak.expect
+++ b/pkg/front_end/testcases/regress/issue_31155.dart.weak.expect
@@ -2,33 +2,10 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/regress/issue_31155.dart:11:18: Error: Expected ';' after this.
+// pkg/front_end/testcases/regress/issue_31155.dart:11:11: Error: A map literal can't be prefixed by 'Map'.
+// Try removing 'Map'
 //   var f = Map<A, B> {};
-//                  ^
-//
-// pkg/front_end/testcases/regress/issue_31155.dart:11:19: Error: Operator declarations must be preceded by the keyword 'operator'.
-// Try adding the keyword 'operator'.
-//   var f = Map<A, B> {};
-//                   ^
-//
-// pkg/front_end/testcases/regress/issue_31155.dart:11:19: Error: A method declaration needs an explicit list of parameters.
-// Try adding a parameter list to the method declaration.
-//   var f = Map<A, B> {};
-//                   ^
-//
-// pkg/front_end/testcases/regress/issue_31155.dart:11:19: Error: Operator '>' should have exactly one parameter.
-//   var f = Map<A, B> {};
-//                   ^
-//
-// pkg/front_end/testcases/regress/issue_31155.dart:11:23: Error: Expected a class member, but got ';'.
-//   var f = Map<A, B> {};
-//                       ^
-//
-// pkg/front_end/testcases/regress/issue_31155.dart:11:14: Error: The operator '<' isn't defined for the class 'Type'.
-//  - 'Type' is from 'dart:core'.
-// Try correcting the operator to an existing operator, or defining a '<' operator.
-//   var f = Map<A, B> {};
-//              ^
+//           ^^^
 //
 import self as self;
 import "dart:core" as core;
@@ -64,16 +41,10 @@
   abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
 }
 class C extends core::Object {
-  field dynamic f = invalid-expression "pkg/front_end/testcases/regress/issue_31155.dart:11:14: Error: The operator '<' isn't defined for the class 'Type'.
- - 'Type' is from 'dart:core'.
-Try correcting the operator to an existing operator, or defining a '<' operator.
-  var f = Map<A, B> {};
-             ^";
-  field dynamic B = null;
+  field core::Map<self::A*, self::B*>* f = <self::A*, self::B*>{};
   synthetic constructor •() → self::C*
     : super core::Object::•()
     ;
-  operator >() → dynamic {}
   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
diff --git a/pkg/front_end/testcases/regress/issue_31155.dart.weak.outline.expect b/pkg/front_end/testcases/regress/issue_31155.dart.weak.outline.expect
index 86f986c..2a3e5ef 100644
--- a/pkg/front_end/testcases/regress/issue_31155.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/regress/issue_31155.dart.weak.outline.expect
@@ -2,27 +2,10 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/regress/issue_31155.dart:11:18: Error: Expected ';' after this.
+// pkg/front_end/testcases/regress/issue_31155.dart:11:11: Error: A map literal can't be prefixed by 'Map'.
+// Try removing 'Map'
 //   var f = Map<A, B> {};
-//                  ^
-//
-// pkg/front_end/testcases/regress/issue_31155.dart:11:19: Error: Operator declarations must be preceded by the keyword 'operator'.
-// Try adding the keyword 'operator'.
-//   var f = Map<A, B> {};
-//                   ^
-//
-// pkg/front_end/testcases/regress/issue_31155.dart:11:19: Error: A method declaration needs an explicit list of parameters.
-// Try adding a parameter list to the method declaration.
-//   var f = Map<A, B> {};
-//                   ^
-//
-// pkg/front_end/testcases/regress/issue_31155.dart:11:19: Error: Operator '>' should have exactly one parameter.
-//   var f = Map<A, B> {};
-//                   ^
-//
-// pkg/front_end/testcases/regress/issue_31155.dart:11:23: Error: Expected a class member, but got ';'.
-//   var f = Map<A, B> {};
-//                       ^
+//           ^^^
 //
 import self as self;
 import "dart:core" as core;
@@ -56,12 +39,9 @@
   abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
 }
 class C extends core::Object {
-  field dynamic f;
-  field dynamic B;
+  field core::Map<self::A*, self::B*>* f;
   synthetic constructor •() → self::C*
     ;
-  operator >() → dynamic
-    ;
   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
diff --git a/pkg/front_end/testcases/regress/issue_31155.dart.weak.transformed.expect b/pkg/front_end/testcases/regress/issue_31155.dart.weak.transformed.expect
index 1cad098..2f83d69 100644
--- a/pkg/front_end/testcases/regress/issue_31155.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_31155.dart.weak.transformed.expect
@@ -2,33 +2,10 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/regress/issue_31155.dart:11:18: Error: Expected ';' after this.
+// pkg/front_end/testcases/regress/issue_31155.dart:11:11: Error: A map literal can't be prefixed by 'Map'.
+// Try removing 'Map'
 //   var f = Map<A, B> {};
-//                  ^
-//
-// pkg/front_end/testcases/regress/issue_31155.dart:11:19: Error: Operator declarations must be preceded by the keyword 'operator'.
-// Try adding the keyword 'operator'.
-//   var f = Map<A, B> {};
-//                   ^
-//
-// pkg/front_end/testcases/regress/issue_31155.dart:11:19: Error: A method declaration needs an explicit list of parameters.
-// Try adding a parameter list to the method declaration.
-//   var f = Map<A, B> {};
-//                   ^
-//
-// pkg/front_end/testcases/regress/issue_31155.dart:11:19: Error: Operator '>' should have exactly one parameter.
-//   var f = Map<A, B> {};
-//                   ^
-//
-// pkg/front_end/testcases/regress/issue_31155.dart:11:23: Error: Expected a class member, but got ';'.
-//   var f = Map<A, B> {};
-//                       ^
-//
-// pkg/front_end/testcases/regress/issue_31155.dart:11:14: Error: The operator '<' isn't defined for the class 'Type'.
-//  - 'Type' is from 'dart:core'.
-// Try correcting the operator to an existing operator, or defining a '<' operator.
-//   var f = Map<A, B> {};
-//              ^
+//           ^^^
 //
 import self as self;
 import "dart:core" as core;
@@ -64,16 +41,10 @@
   abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
 }
 class C extends core::Object {
-  field dynamic f = invalid-expression "pkg/front_end/testcases/regress/issue_31155.dart:11:14: Error: The operator '<' isn't defined for the class 'Type'.
- - 'Type' is from 'dart:core'.
-Try correcting the operator to an existing operator, or defining a '<' operator.
-  var f = Map<A, B> {};
-             ^";
-  field dynamic B = null;
+  field core::Map<self::A*, self::B*>* f = <self::A*, self::B*>{};
   synthetic constructor •() → self::C*
     : super core::Object::•()
     ;
-  operator >() → dynamic {}
   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
diff --git a/pkg/front_end/testcases/strong.status b/pkg/front_end/testcases/strong.status
index 757cc84..c0d86e6 100644
--- a/pkg/front_end/testcases/strong.status
+++ b/pkg/front_end/testcases/strong.status
@@ -7,7 +7,10 @@
 # strong-mode enabled.
 
 extension_types/simple: ExpectationFileMismatchSerialized # Expected.
+extension_types/simple_getter_resolution: ExpectationFileMismatchSerialized # Expected.
 extension_types/simple_method_resolution: ExpectationFileMismatchSerialized # Expected.
+extension_types/simple_operator_resolution: ExpectationFileMismatchSerialized # Expected.
+extension_types/simple_setter_resolution: ExpectationFileMismatchSerialized # Expected.
 late_lowering/covariant_late_field: TypeCheckError
 nnbd/covariant_late_field: TypeCheckError
 nnbd/getter_vs_setter_type: TypeCheckError
diff --git a/pkg/front_end/testcases/text_serialization.status b/pkg/front_end/testcases/text_serialization.status
index 3aabae1..55f591f 100644
--- a/pkg/front_end/testcases/text_serialization.status
+++ b/pkg/front_end/testcases/text_serialization.status
@@ -7,7 +7,10 @@
 # Kernel files are produced by compiling Dart code via Fasta.
 
 extension_types/simple: ExpectationFileMismatchSerialized # Expected.
+extension_types/simple_getter_resolution: ExpectationFileMismatchSerialized # Expected.
 extension_types/simple_method_resolution: ExpectationFileMismatchSerialized # Expected.
+extension_types/simple_operator_resolution: ExpectationFileMismatchSerialized # Expected.
+extension_types/simple_setter_resolution: ExpectationFileMismatchSerialized # Expected.
 extensions/call_methods: TypeCheckError
 extensions/extension_setter_error: TypeCheckError
 extensions/instance_access_of_static: RuntimeError
@@ -26,6 +29,8 @@
 general/constructor_initializer_invalid: RuntimeError
 general/covariant_field: TypeCheckError
 general/covariant_generic: RuntimeError
+general/crashes/crash_02/main: Crash
+general/crashes/crash_04/main: Crash
 general/duplicated_declarations: TypeCheckError
 general/duplicated_field_initializer: RuntimeError
 general/error_locations/error_location_01: RuntimeError
@@ -61,6 +66,7 @@
 general/error_recovery/yield_not_in_generator: RuntimeError
 general/expressions: RuntimeError
 general/external_import: RuntimeError
+general/function_invocation_bounds: TypeCheckError
 general/getter_vs_setter_type: TypeCheckError
 general/incomplete_field_formal_parameter: RuntimeError
 general/infer_field_from_multiple: TypeCheckError
@@ -74,6 +80,7 @@
 general/issue41210a: TypeCheckError
 general/issue41210b/issue41210.no_link: TypeCheckError
 general/issue41210b/issue41210: TypeCheckError
+general/issue45204: TypeCheckError
 general/micro: RuntimeError
 general/mixin_application_override: TypeCheckError
 general/mixin_constructors_with_default_values: RuntimeError
diff --git a/pkg/front_end/testcases/textual_outline.status b/pkg/front_end/testcases/textual_outline.status
index 6fef290..6dd5ffb 100644
--- a/pkg/front_end/testcases/textual_outline.status
+++ b/pkg/front_end/testcases/textual_outline.status
@@ -20,7 +20,7 @@
 regress/issue_39091_2: EmptyOutput
 regress/utf_16_le_content.crash: EmptyOutput
 
-
+const_functions/const_functions_const_factory: FormatterCrash
 extensions/extension_constructor: FormatterCrash
 extensions/extension_field_with_type_parameter_usage: FormatterCrash
 extensions/issue38600: FormatterCrash
@@ -31,7 +31,9 @@
 general/bug31124: FormatterCrash
 general/clone_function_type: FormatterCrash
 general/constants/js_semantics/number_folds: FormatterCrash
+general/constants/js_semantics/number_folds_opt_out: FormatterCrash
 general/constants/number_folds: FormatterCrash
+general/constants/number_folds_opt_out: FormatterCrash
 general/constants/various: FormatterCrash
 general/constructor_initializer_invalid: FormatterCrash
 general/duplicated_declarations: FormatterCrash
@@ -57,12 +59,12 @@
 general/invalid_operator: FormatterCrash
 general/issue42997: FormatterCrash
 general/issue43363: FormatterCrash
+general/issue45490: FormatterCrash
 general/many_errors: FormatterCrash
 general/null_safety_invalid_experiment: FormatterCrash
 general/null_safety_invalid_experiment_and_language_version: FormatterCrash
 general/type_parameters_on_void: FormatterCrash
 general/var_as_type_name: FormatterCrash
-generic_metadata/generic_metadata: FormatterCrash
 inference/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr1: FormatterCrash
 inference/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr1: FormatterCrash
 late_lowering/covariant_late_field: FormatterCrash
@@ -125,9 +127,7 @@
 nnbd_mixed/inheritance_from_opt_in: FormatterCrash
 nnbd_mixed/issue41597: FormatterCrash
 nnbd_mixed/null_safety_invalid_language_version: FormatterCrash
-nonfunction_type_aliases/issue41501: FormatterCrash
-nonfunction_type_aliases/issue42446: FormatterCrash
-nonfunction_type_aliases/issue45051: FormatterCrash
+nonfunction_type_aliases/old_version: FormatterCrash
 rasta/bad_redirection: FormatterCrash
 rasta/issue_000032: FormatterCrash
 rasta/issue_000034: FormatterCrash
diff --git a/pkg/front_end/testcases/triple_shift/invalid_operator.dart b/pkg/front_end/testcases/triple_shift/invalid_operator.dart
index 9e33989..97cbba7 100644
--- a/pkg/front_end/testcases/triple_shift/invalid_operator.dart
+++ b/pkg/front_end/testcases/triple_shift/invalid_operator.dart
@@ -1,7 +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.
-// @dart=2.9
+
 class Operators1 {
   operator >>>() => true;
 }
diff --git a/pkg/front_end/testcases/triple_shift/invalid_operator.dart.strong.expect b/pkg/front_end/testcases/triple_shift/invalid_operator.dart.strong.expect
index 4fc7537..86bba08 100644
--- a/pkg/front_end/testcases/triple_shift/invalid_operator.dart.strong.expect
+++ b/pkg/front_end/testcases/triple_shift/invalid_operator.dart.strong.expect
@@ -1,11 +1,7 @@
-library;
+library /*isNonNullableByDefault*/;
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/triple_shift/invalid_operator.dart:4:1: Error: A library can't opt out of null safety by default, when using sound null safety.
-// // @dart=2.9
-// ^^^^^^^^^^^^
-//
 // pkg/front_end/testcases/triple_shift/invalid_operator.dart:6:12: Error: Operator '>>>' should have exactly one parameter.
 //   operator >>>() => true;
 //            ^^^
@@ -39,123 +35,53 @@
 import "dart:core" as core;
 
 class Operators1 extends core::Object {
-  synthetic constructor •() → self::Operators1*
+  synthetic constructor •() → self::Operators1
     : super core::Object::•()
     ;
   operator >>>() → dynamic
     return true;
-  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 Operators2 extends core::Object {
-  synthetic constructor •() → self::Operators2*
+  synthetic constructor •() → self::Operators2
     : super core::Object::•()
     ;
   operator >>>(dynamic a, dynamic b) → dynamic
     return true;
-  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 Operators3 extends core::Object {
-  synthetic constructor •() → self::Operators3*
+  synthetic constructor •() → self::Operators3
     : super core::Object::•()
     ;
   operator >>>([dynamic a = #C1]) → dynamic
     return true;
-  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 Operators4 extends core::Object {
-  synthetic constructor •() → self::Operators4*
+  synthetic constructor •() → self::Operators4
     : super core::Object::•()
     ;
   operator >>>({dynamic a = #C1}) → dynamic
     return true;
-  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 Operators5 extends core::Object {
-  synthetic constructor •() → self::Operators5*
+  synthetic constructor •() → self::Operators5
     : super core::Object::•()
     ;
   operator >>>(dynamic a, [dynamic b = #C1]) → dynamic
     return true;
-  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 Operators6 extends core::Object {
-  synthetic constructor •() → self::Operators6*
+  synthetic constructor •() → self::Operators6
     : super core::Object::•()
     ;
   operator >>>(dynamic a, {dynamic b = #C1}) → dynamic
     return true;
-  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 Operators7 extends core::Object {
-  synthetic constructor •() → self::Operators7*
+  synthetic constructor •() → self::Operators7
     : super core::Object::•()
     ;
-  operator >>><T extends core::Object* = dynamic>(dynamic a) → dynamic
+  operator >>><T extends core::Object? = dynamic>(dynamic a) → dynamic
     return true;
-  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/triple_shift/invalid_operator.dart.strong.transformed.expect b/pkg/front_end/testcases/triple_shift/invalid_operator.dart.strong.transformed.expect
index 4fc7537..86bba08 100644
--- a/pkg/front_end/testcases/triple_shift/invalid_operator.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/triple_shift/invalid_operator.dart.strong.transformed.expect
@@ -1,11 +1,7 @@
-library;
+library /*isNonNullableByDefault*/;
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/triple_shift/invalid_operator.dart:4:1: Error: A library can't opt out of null safety by default, when using sound null safety.
-// // @dart=2.9
-// ^^^^^^^^^^^^
-//
 // pkg/front_end/testcases/triple_shift/invalid_operator.dart:6:12: Error: Operator '>>>' should have exactly one parameter.
 //   operator >>>() => true;
 //            ^^^
@@ -39,123 +35,53 @@
 import "dart:core" as core;
 
 class Operators1 extends core::Object {
-  synthetic constructor •() → self::Operators1*
+  synthetic constructor •() → self::Operators1
     : super core::Object::•()
     ;
   operator >>>() → dynamic
     return true;
-  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 Operators2 extends core::Object {
-  synthetic constructor •() → self::Operators2*
+  synthetic constructor •() → self::Operators2
     : super core::Object::•()
     ;
   operator >>>(dynamic a, dynamic b) → dynamic
     return true;
-  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 Operators3 extends core::Object {
-  synthetic constructor •() → self::Operators3*
+  synthetic constructor •() → self::Operators3
     : super core::Object::•()
     ;
   operator >>>([dynamic a = #C1]) → dynamic
     return true;
-  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 Operators4 extends core::Object {
-  synthetic constructor •() → self::Operators4*
+  synthetic constructor •() → self::Operators4
     : super core::Object::•()
     ;
   operator >>>({dynamic a = #C1}) → dynamic
     return true;
-  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 Operators5 extends core::Object {
-  synthetic constructor •() → self::Operators5*
+  synthetic constructor •() → self::Operators5
     : super core::Object::•()
     ;
   operator >>>(dynamic a, [dynamic b = #C1]) → dynamic
     return true;
-  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 Operators6 extends core::Object {
-  synthetic constructor •() → self::Operators6*
+  synthetic constructor •() → self::Operators6
     : super core::Object::•()
     ;
   operator >>>(dynamic a, {dynamic b = #C1}) → dynamic
     return true;
-  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 Operators7 extends core::Object {
-  synthetic constructor •() → self::Operators7*
+  synthetic constructor •() → self::Operators7
     : super core::Object::•()
     ;
-  operator >>><T extends core::Object* = dynamic>(dynamic a) → dynamic
+  operator >>><T extends core::Object? = dynamic>(dynamic a) → dynamic
     return true;
-  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/triple_shift/invalid_operator.dart.textual_outline.expect b/pkg/front_end/testcases/triple_shift/invalid_operator.dart.textual_outline.expect
index 0c9cae8..a449983 100644
--- a/pkg/front_end/testcases/triple_shift/invalid_operator.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/triple_shift/invalid_operator.dart.textual_outline.expect
@@ -1,4 +1,3 @@
-// @dart = 2.9
 class Operators1 {
   operator >>(){}
   operator>() => true;
diff --git a/pkg/front_end/testcases/triple_shift/invalid_operator.dart.weak.expect b/pkg/front_end/testcases/triple_shift/invalid_operator.dart.weak.expect
index a5258fd..86bba08 100644
--- a/pkg/front_end/testcases/triple_shift/invalid_operator.dart.weak.expect
+++ b/pkg/front_end/testcases/triple_shift/invalid_operator.dart.weak.expect
@@ -1,4 +1,4 @@
-library;
+library /*isNonNullableByDefault*/;
 //
 // Problems in library:
 //
@@ -35,123 +35,53 @@
 import "dart:core" as core;
 
 class Operators1 extends core::Object {
-  synthetic constructor •() → self::Operators1*
+  synthetic constructor •() → self::Operators1
     : super core::Object::•()
     ;
   operator >>>() → dynamic
     return true;
-  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 Operators2 extends core::Object {
-  synthetic constructor •() → self::Operators2*
+  synthetic constructor •() → self::Operators2
     : super core::Object::•()
     ;
   operator >>>(dynamic a, dynamic b) → dynamic
     return true;
-  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 Operators3 extends core::Object {
-  synthetic constructor •() → self::Operators3*
+  synthetic constructor •() → self::Operators3
     : super core::Object::•()
     ;
   operator >>>([dynamic a = #C1]) → dynamic
     return true;
-  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 Operators4 extends core::Object {
-  synthetic constructor •() → self::Operators4*
+  synthetic constructor •() → self::Operators4
     : super core::Object::•()
     ;
   operator >>>({dynamic a = #C1}) → dynamic
     return true;
-  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 Operators5 extends core::Object {
-  synthetic constructor •() → self::Operators5*
+  synthetic constructor •() → self::Operators5
     : super core::Object::•()
     ;
   operator >>>(dynamic a, [dynamic b = #C1]) → dynamic
     return true;
-  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 Operators6 extends core::Object {
-  synthetic constructor •() → self::Operators6*
+  synthetic constructor •() → self::Operators6
     : super core::Object::•()
     ;
   operator >>>(dynamic a, {dynamic b = #C1}) → dynamic
     return true;
-  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 Operators7 extends core::Object {
-  synthetic constructor •() → self::Operators7*
+  synthetic constructor •() → self::Operators7
     : super core::Object::•()
     ;
-  operator >>><T extends core::Object* = dynamic>(dynamic a) → dynamic
+  operator >>><T extends core::Object? = dynamic>(dynamic a) → dynamic
     return true;
-  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/triple_shift/invalid_operator.dart.weak.outline.expect b/pkg/front_end/testcases/triple_shift/invalid_operator.dart.weak.outline.expect
index d2a1d7f..34eccb8 100644
--- a/pkg/front_end/testcases/triple_shift/invalid_operator.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/triple_shift/invalid_operator.dart.weak.outline.expect
@@ -1,4 +1,4 @@
-library;
+library /*isNonNullableByDefault*/;
 //
 // Problems in library:
 //
@@ -35,116 +35,46 @@
 import "dart:core" as core;
 
 class Operators1 extends core::Object {
-  synthetic constructor •() → self::Operators1*
+  synthetic constructor •() → self::Operators1
     ;
   operator >>>() → dynamic
     ;
-  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 Operators2 extends core::Object {
-  synthetic constructor •() → self::Operators2*
+  synthetic constructor •() → self::Operators2
     ;
   operator >>>(dynamic a, dynamic b) → dynamic
     ;
-  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 Operators3 extends core::Object {
-  synthetic constructor •() → self::Operators3*
+  synthetic constructor •() → self::Operators3
     ;
   operator >>>([dynamic a]) → dynamic
     ;
-  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 Operators4 extends core::Object {
-  synthetic constructor •() → self::Operators4*
+  synthetic constructor •() → self::Operators4
     ;
   operator >>>({dynamic a}) → dynamic
     ;
-  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 Operators5 extends core::Object {
-  synthetic constructor •() → self::Operators5*
+  synthetic constructor •() → self::Operators5
     ;
   operator >>>(dynamic a, [dynamic b]) → dynamic
     ;
-  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 Operators6 extends core::Object {
-  synthetic constructor •() → self::Operators6*
+  synthetic constructor •() → self::Operators6
     ;
   operator >>>(dynamic a, {dynamic b}) → dynamic
     ;
-  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 Operators7 extends core::Object {
-  synthetic constructor •() → self::Operators7*
+  synthetic constructor •() → self::Operators7
     ;
-  operator >>><T extends core::Object* = dynamic>(dynamic a) → dynamic
+  operator >>><T extends core::Object? = dynamic>(dynamic a) → dynamic
     ;
-  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/triple_shift/invalid_operator.dart.weak.transformed.expect b/pkg/front_end/testcases/triple_shift/invalid_operator.dart.weak.transformed.expect
index a5258fd..86bba08 100644
--- a/pkg/front_end/testcases/triple_shift/invalid_operator.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/triple_shift/invalid_operator.dart.weak.transformed.expect
@@ -1,4 +1,4 @@
-library;
+library /*isNonNullableByDefault*/;
 //
 // Problems in library:
 //
@@ -35,123 +35,53 @@
 import "dart:core" as core;
 
 class Operators1 extends core::Object {
-  synthetic constructor •() → self::Operators1*
+  synthetic constructor •() → self::Operators1
     : super core::Object::•()
     ;
   operator >>>() → dynamic
     return true;
-  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 Operators2 extends core::Object {
-  synthetic constructor •() → self::Operators2*
+  synthetic constructor •() → self::Operators2
     : super core::Object::•()
     ;
   operator >>>(dynamic a, dynamic b) → dynamic
     return true;
-  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 Operators3 extends core::Object {
-  synthetic constructor •() → self::Operators3*
+  synthetic constructor •() → self::Operators3
     : super core::Object::•()
     ;
   operator >>>([dynamic a = #C1]) → dynamic
     return true;
-  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 Operators4 extends core::Object {
-  synthetic constructor •() → self::Operators4*
+  synthetic constructor •() → self::Operators4
     : super core::Object::•()
     ;
   operator >>>({dynamic a = #C1}) → dynamic
     return true;
-  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 Operators5 extends core::Object {
-  synthetic constructor •() → self::Operators5*
+  synthetic constructor •() → self::Operators5
     : super core::Object::•()
     ;
   operator >>>(dynamic a, [dynamic b = #C1]) → dynamic
     return true;
-  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 Operators6 extends core::Object {
-  synthetic constructor •() → self::Operators6*
+  synthetic constructor •() → self::Operators6
     : super core::Object::•()
     ;
   operator >>>(dynamic a, {dynamic b = #C1}) → dynamic
     return true;
-  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 Operators7 extends core::Object {
-  synthetic constructor •() → self::Operators7*
+  synthetic constructor •() → self::Operators7
     : super core::Object::•()
     ;
-  operator >>><T extends core::Object* = dynamic>(dynamic a) → dynamic
+  operator >>><T extends core::Object? = dynamic>(dynamic a) → dynamic
     return true;
-  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/variance/class_type_parameter_modifier.dart b/pkg/front_end/testcases/variance/class_type_parameter_modifier.dart
index 1aea4d3..71aa5cf 100644
--- a/pkg/front_end/testcases/variance/class_type_parameter_modifier.dart
+++ b/pkg/front_end/testcases/variance/class_type_parameter_modifier.dart
@@ -1,7 +1,7 @@
 // Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-// @dart=2.9
+
 class A<out X, in Y, inout Z> {}
 
 main() {
diff --git a/pkg/front_end/testcases/variance/class_type_parameter_modifier.dart.textual_outline.expect b/pkg/front_end/testcases/variance/class_type_parameter_modifier.dart.textual_outline.expect
index b4adc16..eaa0557 100644
--- a/pkg/front_end/testcases/variance/class_type_parameter_modifier.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/variance/class_type_parameter_modifier.dart.textual_outline.expect
@@ -1,3 +1,2 @@
-// @dart = 2.9
 class A<out X, in Y, inout Z> {}
 main() {}
diff --git a/pkg/front_end/testcases/variance/class_type_parameter_modifier.dart.weak.expect b/pkg/front_end/testcases/variance/class_type_parameter_modifier.dart.weak.expect
index 6d3f0f2..14e8ddf 100644
--- a/pkg/front_end/testcases/variance/class_type_parameter_modifier.dart.weak.expect
+++ b/pkg/front_end/testcases/variance/class_type_parameter_modifier.dart.weak.expect
@@ -1,22 +1,12 @@
-library;
+library /*isNonNullableByDefault*/;
 import self as self;
 import "dart:core" as core;
 
-class A<X extends core::Object* = dynamic, contravariant Y extends core::Object* = dynamic, invariant Z extends core::Object* = dynamic> extends core::Object {
-  synthetic constructor •() → self::A<self::A::X*, self::A::Y*, self::A::Z*>*
+class A<X extends core::Object? = dynamic, contravariant Y extends core::Object? = dynamic, invariant Z extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::A<self::A::X%, self::A::Y%, self::A::Z%>
     : super core::Object::•()
     ;
-  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 {
-  self::A<dynamic, dynamic, dynamic>* a = new self::A::•<dynamic, dynamic, dynamic>();
+  self::A<dynamic, dynamic, dynamic> a = new self::A::•<dynamic, dynamic, dynamic>();
 }
diff --git a/pkg/front_end/testcases/variance/class_type_parameter_modifier.dart.weak.outline.expect b/pkg/front_end/testcases/variance/class_type_parameter_modifier.dart.weak.outline.expect
index 6031980..4f9e525 100644
--- a/pkg/front_end/testcases/variance/class_type_parameter_modifier.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/variance/class_type_parameter_modifier.dart.weak.outline.expect
@@ -1,20 +1,10 @@
-library;
+library /*isNonNullableByDefault*/;
 import self as self;
 import "dart:core" as core;
 
-class A<X extends core::Object* = dynamic, contravariant Y extends core::Object* = dynamic, invariant Z extends core::Object* = dynamic> extends core::Object {
-  synthetic constructor •() → self::A<self::A::X*, self::A::Y*, self::A::Z*>*
+class A<X extends core::Object? = dynamic, contravariant Y extends core::Object? = dynamic, invariant Z extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::A<self::A::X%, self::A::Y%, self::A::Z%>
     ;
-  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/variance/class_type_parameter_modifier.dart.weak.transformed.expect b/pkg/front_end/testcases/variance/class_type_parameter_modifier.dart.weak.transformed.expect
index 6d3f0f2..14e8ddf 100644
--- a/pkg/front_end/testcases/variance/class_type_parameter_modifier.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/variance/class_type_parameter_modifier.dart.weak.transformed.expect
@@ -1,22 +1,12 @@
-library;
+library /*isNonNullableByDefault*/;
 import self as self;
 import "dart:core" as core;
 
-class A<X extends core::Object* = dynamic, contravariant Y extends core::Object* = dynamic, invariant Z extends core::Object* = dynamic> extends core::Object {
-  synthetic constructor •() → self::A<self::A::X*, self::A::Y*, self::A::Z*>*
+class A<X extends core::Object? = dynamic, contravariant Y extends core::Object? = dynamic, invariant Z extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::A<self::A::X%, self::A::Y%, self::A::Z%>
     : super core::Object::•()
     ;
-  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 {
-  self::A<dynamic, dynamic, dynamic>* a = new self::A::•<dynamic, dynamic, dynamic>();
+  self::A<dynamic, dynamic, dynamic> a = new self::A::•<dynamic, dynamic, dynamic>();
 }
diff --git a/pkg/front_end/testcases/variance/generic_covariance_sound_variance.dart b/pkg/front_end/testcases/variance/generic_covariance_sound_variance.dart
index 1d1c133..983db1d 100644
--- a/pkg/front_end/testcases/variance/generic_covariance_sound_variance.dart
+++ b/pkg/front_end/testcases/variance/generic_covariance_sound_variance.dart
@@ -1,16 +1,16 @@
 // Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-// @dart=2.9
+
 typedef ContraFunction<T> = void Function(T);
 typedef InvFunction<T> = T Function(T);
 class Contravariant<in T> {}
 class Invariant<inout T> {}
 
 class A<in T, out U, V> {
-  final void Function(T) field = null;
+  final void Function(T)? field = null;
   void method(T t, void Function(U) u, V v) {}
-  void method2(T x, [T y]) {}
+  void method2(T x, [T? y]) {}
   void set x(T t) {}
   Map<U, Contravariant<V>> get mapContra => new Map<U, Contravariant<V>>();
   Map<U, ContraFunction<V>> get mapContraFn => new Map<U, ContraFunction<V>>();
@@ -19,14 +19,14 @@
 }
 
 class B<inout T> {
-  T x;
+  T? x;
   T method(T x) => x;
   void set y(T x) {}
 }
 
 class C<in T> {
-  final void Function(T) field = null;
-  void method(T x, [T y]) {}
+  final void Function(T)? field = null;
+  void method(T x, [T? y]) {}
   void set x(T t) {}
 }
 
@@ -39,6 +39,7 @@
   E(this.f);
   int method(T x) {
     f(x);
+    return 0;
   }
 }
 
diff --git a/pkg/front_end/testcases/variance/generic_covariance_sound_variance.dart.textual_outline.expect b/pkg/front_end/testcases/variance/generic_covariance_sound_variance.dart.textual_outline.expect
index aa7684d..375b737 100644
--- a/pkg/front_end/testcases/variance/generic_covariance_sound_variance.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/variance/generic_covariance_sound_variance.dart.textual_outline.expect
@@ -1,12 +1,11 @@
-// @dart = 2.9
 typedef ContraFunction<T> = void Function(T);
 typedef InvFunction<T> = T Function(T);
 class Contravariant<in T> {}
 class Invariant<inout T> {}
 class A<in T, out U, V> {
-  final void Function(T) field = null;
+  final void Function(T)? field = null;
   void method(T t, void Function(U) u, V v) {}
-  void method2(T x, [T y]) {}
+  void method2(T x, [T? y]) {}
   void set x(T t) {}
   Map<U, Contravariant<V>> get mapContra => new Map<U, Contravariant<V>>();
   Map<U, ContraFunction<V>> get mapContraFn => new Map<U, ContraFunction<V>>();
@@ -14,13 +13,13 @@
   Map<U, InvFunction<V>> get mapInvFn => new Map<U, InvFunction<V>>();
 }
 class B<inout T> {
-  T x;
+  T? x;
   T method(T x) => x;
   void set y(T x) {}
 }
 class C<in T> {
-  final void Function(T) field = null;
-  void method(T x, [T y]) {}
+  final void Function(T)? field = null;
+  void method(T x, [T? y]) {}
   void set x(T t) {}
 }
 abstract class D<T> {
diff --git a/pkg/front_end/testcases/variance/generic_covariance_sound_variance.dart.weak.expect b/pkg/front_end/testcases/variance/generic_covariance_sound_variance.dart.weak.expect
index 4b64468..fbf4052 100644
--- a/pkg/front_end/testcases/variance/generic_covariance_sound_variance.dart.weak.expect
+++ b/pkg/front_end/testcases/variance/generic_covariance_sound_variance.dart.weak.expect
@@ -1,191 +1,113 @@
-library;
+library /*isNonNullableByDefault*/;
 import self as self;
 import "dart:core" as core;
 
-typedef ContraFunction<contravariant T extends core::Object* = dynamic> = (T*) →* void;
-typedef InvFunction<invariant T extends core::Object* = dynamic> = (T*) →* T*;
-class Contravariant<contravariant T extends core::Object* = dynamic> extends core::Object {
-  synthetic constructor •() → self::Contravariant<self::Contravariant::T*>*
+typedef ContraFunction<contravariant T extends core::Object? = dynamic> = (T%) → void;
+typedef InvFunction<invariant T extends core::Object? = dynamic> = (T%) → T%;
+class Contravariant<contravariant T extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::Contravariant<self::Contravariant::T%>
     : 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 Invariant<invariant T extends core::Object* = dynamic> extends core::Object {
-  synthetic constructor •() → self::Invariant<self::Invariant::T*>*
+class Invariant<invariant T extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::Invariant<self::Invariant::T%>
     : 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 A<contravariant T extends core::Object* = dynamic, U extends core::Object* = dynamic, V extends core::Object* = dynamic> extends core::Object {
-  final field (self::A::T*) →* void field = null;
-  synthetic constructor •() → self::A<self::A::T*, self::A::U*, self::A::V*>*
+class A<contravariant T extends core::Object? = dynamic, U extends core::Object? = dynamic, V extends core::Object? = dynamic> extends core::Object {
+  final field (self::A::T%) →? void field = null;
+  synthetic constructor •() → self::A<self::A::T%, self::A::U%, self::A::V%>
     : super core::Object::•()
     ;
-  method method(self::A::T* t, (self::A::U*) →* void u, generic-covariant-impl self::A::V* v) → void {}
-  method method2(self::A::T* x, [self::A::T* y = #C1]) → void {}
-  set x(self::A::T* t) → void {}
-  get mapContra() → core::Map<self::A::U*, self::Contravariant<self::A::V*>*>*
-    return core::Map::•<self::A::U*, self::Contravariant<self::A::V*>*>();
-  get mapContraFn() → core::Map<self::A::U*, (self::A::V*) →* void>*
-    return core::Map::•<self::A::U*, (self::A::V*) →* void>();
-  get mapInv() → core::Map<self::A::U*, self::Invariant<self::A::V*>*>*
-    return core::Map::•<self::A::U*, self::Invariant<self::A::V*>*>();
-  get mapInvFn() → core::Map<self::A::U*, (self::A::V*) →* self::A::V*>*
-    return core::Map::•<self::A::U*, (self::A::V*) →* self::A::V*>();
-  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
+  method method(self::A::T% t, (self::A::U%) → void u, generic-covariant-impl self::A::V% v) → void {}
+  method method2(self::A::T% x, [self::A::T? y = #C1]) → void {}
+  set x(self::A::T% t) → void {}
+  get mapContra() → core::Map<self::A::U%, self::Contravariant<self::A::V%>>
+    return core::Map::•<self::A::U%, self::Contravariant<self::A::V%>>();
+  get mapContraFn() → core::Map<self::A::U%, (self::A::V%) → void>
+    return core::Map::•<self::A::U%, (self::A::V%) → void>();
+  get mapInv() → core::Map<self::A::U%, self::Invariant<self::A::V%>>
+    return core::Map::•<self::A::U%, self::Invariant<self::A::V%>>();
+  get mapInvFn() → core::Map<self::A::U%, (self::A::V%) → self::A::V%>
+    return core::Map::•<self::A::U%, (self::A::V%) → self::A::V%>();
 }
-class B<invariant T extends core::Object* = dynamic> extends core::Object {
-  field self::B::T* x = null;
-  synthetic constructor •() → self::B<self::B::T*>*
+class B<invariant T extends core::Object? = dynamic> extends core::Object {
+  field self::B::T? x = null;
+  synthetic constructor •() → self::B<self::B::T%>
     : super core::Object::•()
     ;
-  method method(self::B::T* x) → self::B::T*
+  method method(self::B::T% x) → self::B::T%
     return x;
-  set y(self::B::T* x) → void {}
-  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
-  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 get runtimeType() → core::Type*; -> core::Object::runtimeType
+  set y(self::B::T% x) → void {}
 }
-class C<contravariant T extends core::Object* = dynamic> extends core::Object {
-  final field (self::C::T*) →* void field = null;
-  synthetic constructor •() → self::C<self::C::T*>*
+class C<contravariant T extends core::Object? = dynamic> extends core::Object {
+  final field (self::C::T%) →? void field = null;
+  synthetic constructor •() → self::C<self::C::T%>
     : super core::Object::•()
     ;
-  method method(self::C::T* x, [self::C::T* y = #C1]) → void {}
-  set x(self::C::T* t) → 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
+  method method(self::C::T% x, [self::C::T? y = #C1]) → void {}
+  set x(self::C::T% t) → void {}
 }
-abstract class D<T extends core::Object* = dynamic> extends core::Object {
-  synthetic constructor •() → self::D<self::D::T*>*
+abstract class D<T extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::D<self::D::T%>
     : super core::Object::•()
     ;
-  abstract method method(generic-covariant-impl self::D::T* x) → core::int*;
-  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 method method(generic-covariant-impl self::D::T% x) → core::int;
 }
-class E<invariant T extends core::Object* = dynamic> extends core::Object {
-  final field (self::E::T*) →* void f;
-  constructor •((self::E::T*) →* void f) → self::E<self::E::T*>*
+class E<invariant T extends core::Object? = dynamic> extends core::Object {
+  final field (self::E::T%) → void f;
+  constructor •((self::E::T%) → void f) → self::E<self::E::T%>
     : self::E::f = f, super core::Object::•()
     ;
-  method method(self::E::T* x) → core::int* {
-    let final self::E::T* #t1 = x in this.{self::E::f}.call(#t1);
+  method method(self::E::T% x) → core::int {
+    let final self::E::T% #t1 = x in this.{self::E::f}.call(#t1);
+    return 0;
   }
-  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 F<invariant T extends core::Object* = dynamic> extends self::E<self::F::T*> implements self::D<self::F::T*> {
-  constructor •((self::F::T*) →* void f) → self::F<self::F::T*>*
+class F<invariant T extends core::Object? = dynamic> extends self::E<self::F::T%> implements self::D<self::F::T%> {
+  constructor •((self::F::T%) → void f) → self::F<self::F::T%>
     : super self::E::•(f)
     ;
-  forwarding-stub method method(generic-covariant-impl self::F::T* x) → core::int*
+  forwarding-stub method method(generic-covariant-impl self::F::T% x) → core::int
     return super.{self::E::method}(x);
 }
-class NoSuchMethod<invariant T extends core::Object* = dynamic> extends core::Object implements self::B<self::NoSuchMethod::T*> {
-  synthetic constructor •() → self::NoSuchMethod<self::NoSuchMethod::T*>*
+class NoSuchMethod<invariant T extends core::Object? = dynamic> extends core::Object implements self::B<self::NoSuchMethod::T%> {
+  synthetic constructor •() → self::NoSuchMethod<self::NoSuchMethod::T%>
     : super core::Object::•()
     ;
-  method noSuchMethod(core::Invocation* _) → dynamic
+  method noSuchMethod(core::Invocation _) → dynamic
     return 3;
-  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 get runtimeType() → core::Type*; -> core::Object::runtimeType
-  no-such-method-forwarder get x() → self::NoSuchMethod::T*
-    return this.{self::NoSuchMethod::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 1, #C3, #C4, core::Map::unmodifiable<core::Symbol*, dynamic>(#C5))) as{TypeError,ForDynamic} self::NoSuchMethod::T*;
-  no-such-method-forwarder method method(self::NoSuchMethod::T* x) → self::NoSuchMethod::T*
-    return this.{self::NoSuchMethod::noSuchMethod}(new core::_InvocationMirror::_withType(#C6, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[x]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C5))) as{TypeError,ForDynamic} self::NoSuchMethod::T*;
-  no-such-method-forwarder set y(self::NoSuchMethod::T* x) → void
+  no-such-method-forwarder get x() → self::NoSuchMethod::T?
+    return this.{self::NoSuchMethod::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 1, #C3, #C4, core::Map::unmodifiable<core::Symbol*, dynamic>(#C5))) as{TypeError,ForDynamic,ForNonNullableByDefault} self::NoSuchMethod::T?;
+  no-such-method-forwarder method method(self::NoSuchMethod::T% x) → self::NoSuchMethod::T%
+    return this.{self::NoSuchMethod::noSuchMethod}(new core::_InvocationMirror::_withType(#C6, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[x]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C5))) as{TypeError,ForDynamic,ForNonNullableByDefault} self::NoSuchMethod::T%;
+  no-such-method-forwarder set y(self::NoSuchMethod::T% x) → void
     return this.{self::NoSuchMethod::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 2, #C3, core::List::unmodifiable<dynamic>(<dynamic>[x]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C5)));
-  no-such-method-forwarder set x(self::NoSuchMethod::T* value) → void
+  no-such-method-forwarder set x(self::NoSuchMethod::T? value) → void
     return this.{self::NoSuchMethod::noSuchMethod}(new core::_InvocationMirror::_withType(#C8, 2, #C3, core::List::unmodifiable<dynamic>(<dynamic>[value]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C5)));
 }
 static method main() → dynamic {
-  self::A<core::int*, core::num*, core::String*>* a = new self::A::•<core::int*, core::num*, core::String*>();
+  self::A<core::int, core::num, core::String> a = new self::A::•<core::int, core::num, core::String>();
   self::expect(null, a.{self::A::field});
-  a.{self::A::method}(3, (core::num* num) → Null {}, "test");
+  a.{self::A::method}(3, (core::num num) → void {}, "test");
   a.{self::A::method2}(3);
   a.{self::A::x} = 3;
-  core::Map<core::num*, self::Contravariant<core::String*>*>* mapContra = a.{self::A::mapContra} as{TypeError,CovarianceCheck} core::Map<core::num*, self::Contravariant<core::String*>*>*;
-  core::Map<core::num*, (core::String*) →* void>* mapContraFn = a.{self::A::mapContraFn} as{TypeError,CovarianceCheck} core::Map<core::num*, (core::String*) →* void>*;
-  core::Map<core::num*, self::Invariant<core::String*>*>* mapInv = a.{self::A::mapInv} as{TypeError,CovarianceCheck} core::Map<core::num*, self::Invariant<core::String*>*>*;
-  core::Map<core::num*, (core::String*) →* core::String*>* mapInvFn = a.{self::A::mapInvFn} as{TypeError,CovarianceCheck} core::Map<core::num*, (core::String*) →* core::String*>*;
-  self::B<core::int*>* b = new self::B::•<core::int*>();
+  core::Map<core::num, self::Contravariant<core::String>> mapContra = a.{self::A::mapContra} as{TypeError,CovarianceCheck,ForNonNullableByDefault} core::Map<core::num, self::Contravariant<core::String>>;
+  core::Map<core::num, (core::String) → void> mapContraFn = a.{self::A::mapContraFn} as{TypeError,CovarianceCheck,ForNonNullableByDefault} core::Map<core::num, (core::String) → void>;
+  core::Map<core::num, self::Invariant<core::String>> mapInv = a.{self::A::mapInv} as{TypeError,CovarianceCheck,ForNonNullableByDefault} core::Map<core::num, self::Invariant<core::String>>;
+  core::Map<core::num, (core::String) → core::String> mapInvFn = a.{self::A::mapInvFn} as{TypeError,CovarianceCheck,ForNonNullableByDefault} core::Map<core::num, (core::String) → core::String>;
+  self::B<core::int> b = new self::B::•<core::int>();
   b.{self::B::x} = 3;
   self::expect(3, b.{self::B::x});
   self::expect(3, b.{self::B::method}(3));
   b.{self::B::y} = 3;
-  self::C<core::int*>* c = new self::C::•<core::int*>();
+  self::C<core::int> c = new self::C::•<core::int>();
   self::expect(null, c.{self::C::field});
   c.{self::C::method}(3, 2);
   c.{self::C::x} = 3;
-  self::D<core::Object*>* d = new self::F::•<core::String*>((core::String* s) → Null {});
+  self::D<core::Object> d = new self::F::•<core::String>((core::String s) → void {});
   d.{self::D::method}("test");
-  self::NoSuchMethod<core::num*>* nsm = new self::NoSuchMethod::•<core::num*>();
+  self::NoSuchMethod<core::num> nsm = new self::NoSuchMethod::•<core::num>();
   self::expect(3, nsm.{self::B::method}(3));
 }
 static method expect(dynamic expected, dynamic actual) → dynamic {
diff --git a/pkg/front_end/testcases/variance/generic_covariance_sound_variance.dart.weak.outline.expect b/pkg/front_end/testcases/variance/generic_covariance_sound_variance.dart.weak.outline.expect
index 22cd762..1ce38f4 100644
--- a/pkg/front_end/testcases/variance/generic_covariance_sound_variance.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/variance/generic_covariance_sound_variance.dart.weak.outline.expect
@@ -1,163 +1,84 @@
-library;
+library /*isNonNullableByDefault*/;
 import self as self;
 import "dart:core" as core;
 
-typedef ContraFunction<contravariant T extends core::Object* = dynamic> = (T*) →* void;
-typedef InvFunction<invariant T extends core::Object* = dynamic> = (T*) →* T*;
-class Contravariant<contravariant T extends core::Object* = dynamic> extends core::Object {
-  synthetic constructor •() → self::Contravariant<self::Contravariant::T*>*
+typedef ContraFunction<contravariant T extends core::Object? = dynamic> = (T%) → void;
+typedef InvFunction<invariant T extends core::Object? = dynamic> = (T%) → T%;
+class Contravariant<contravariant T extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::Contravariant<self::Contravariant::T%>
     ;
-  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 Invariant<invariant T extends core::Object* = dynamic> extends core::Object {
-  synthetic constructor •() → self::Invariant<self::Invariant::T*>*
+class Invariant<invariant T extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::Invariant<self::Invariant::T%>
     ;
-  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 A<contravariant T extends core::Object* = dynamic, U extends core::Object* = dynamic, V extends core::Object* = dynamic> extends core::Object {
-  final field (self::A::T*) →* void field;
-  synthetic constructor •() → self::A<self::A::T*, self::A::U*, self::A::V*>*
+class A<contravariant T extends core::Object? = dynamic, U extends core::Object? = dynamic, V extends core::Object? = dynamic> extends core::Object {
+  final field (self::A::T%) →? void field;
+  synthetic constructor •() → self::A<self::A::T%, self::A::U%, self::A::V%>
     ;
-  method method(self::A::T* t, (self::A::U*) →* void u, generic-covariant-impl self::A::V* v) → void
+  method method(self::A::T% t, (self::A::U%) → void u, generic-covariant-impl self::A::V% v) → void
     ;
-  method method2(self::A::T* x, [self::A::T* y]) → void
+  method method2(self::A::T% x, [self::A::T? y]) → void
     ;
-  set x(self::A::T* t) → void
+  set x(self::A::T% t) → void
     ;
-  get mapContra() → core::Map<self::A::U*, self::Contravariant<self::A::V*>*>*
+  get mapContra() → core::Map<self::A::U%, self::Contravariant<self::A::V%>>
     ;
-  get mapContraFn() → core::Map<self::A::U*, (self::A::V*) →* void>*
+  get mapContraFn() → core::Map<self::A::U%, (self::A::V%) → void>
     ;
-  get mapInv() → core::Map<self::A::U*, self::Invariant<self::A::V*>*>*
+  get mapInv() → core::Map<self::A::U%, self::Invariant<self::A::V%>>
     ;
-  get mapInvFn() → core::Map<self::A::U*, (self::A::V*) →* self::A::V*>*
+  get mapInvFn() → core::Map<self::A::U%, (self::A::V%) → self::A::V%>
     ;
-  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 B<invariant T extends core::Object* = dynamic> extends core::Object {
-  field self::B::T* x;
-  synthetic constructor •() → self::B<self::B::T*>*
+class B<invariant T extends core::Object? = dynamic> extends core::Object {
+  field self::B::T? x;
+  synthetic constructor •() → self::B<self::B::T%>
     ;
-  method method(self::B::T* x) → self::B::T*
+  method method(self::B::T% x) → self::B::T%
     ;
-  set y(self::B::T* x) → void
+  set y(self::B::T% x) → void
     ;
-  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
-  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 get runtimeType() → core::Type*; -> core::Object::runtimeType
 }
-class C<contravariant T extends core::Object* = dynamic> extends core::Object {
-  final field (self::C::T*) →* void field;
-  synthetic constructor •() → self::C<self::C::T*>*
+class C<contravariant T extends core::Object? = dynamic> extends core::Object {
+  final field (self::C::T%) →? void field;
+  synthetic constructor •() → self::C<self::C::T%>
     ;
-  method method(self::C::T* x, [self::C::T* y]) → void
+  method method(self::C::T% x, [self::C::T? y]) → void
     ;
-  set x(self::C::T* t) → void
+  set x(self::C::T% t) → 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
 }
-abstract class D<T extends core::Object* = dynamic> extends core::Object {
-  synthetic constructor •() → self::D<self::D::T*>*
+abstract class D<T extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::D<self::D::T%>
     ;
-  abstract method method(generic-covariant-impl self::D::T* x) → core::int*;
-  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 method method(generic-covariant-impl self::D::T% x) → core::int;
 }
-class E<invariant T extends core::Object* = dynamic> extends core::Object {
-  final field (self::E::T*) →* void f;
-  constructor •((self::E::T*) →* void f) → self::E<self::E::T*>*
+class E<invariant T extends core::Object? = dynamic> extends core::Object {
+  final field (self::E::T%) → void f;
+  constructor •((self::E::T%) → void f) → self::E<self::E::T%>
     ;
-  method method(self::E::T* x) → core::int*
+  method method(self::E::T% x) → core::int
     ;
-  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 F<invariant T extends core::Object* = dynamic> extends self::E<self::F::T*> implements self::D<self::F::T*> {
-  constructor •((self::F::T*) →* void f) → self::F<self::F::T*>*
+class F<invariant T extends core::Object? = dynamic> extends self::E<self::F::T%> implements self::D<self::F::T%> {
+  constructor •((self::F::T%) → void f) → self::F<self::F::T%>
     ;
-  forwarding-stub method method(generic-covariant-impl self::F::T* x) → core::int*
+  forwarding-stub method method(generic-covariant-impl self::F::T% x) → core::int
     return super.{self::E::method}(x);
 }
-class NoSuchMethod<invariant T extends core::Object* = dynamic> extends core::Object implements self::B<self::NoSuchMethod::T*> {
-  synthetic constructor •() → self::NoSuchMethod<self::NoSuchMethod::T*>*
+class NoSuchMethod<invariant T extends core::Object? = dynamic> extends core::Object implements self::B<self::NoSuchMethod::T%> {
+  synthetic constructor •() → self::NoSuchMethod<self::NoSuchMethod::T%>
     ;
-  method noSuchMethod(core::Invocation* _) → dynamic
+  method noSuchMethod(core::Invocation _) → dynamic
     ;
-  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 get runtimeType() → core::Type*; -> core::Object::runtimeType
-  no-such-method-forwarder get x() → self::NoSuchMethod::T*
-    return this.{self::NoSuchMethod::noSuchMethod}(new core::_InvocationMirror::_withType(#x, 1, const <core::Type*>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))) as{TypeError,ForDynamic} self::NoSuchMethod::T*;
-  no-such-method-forwarder method method(self::NoSuchMethod::T* x) → self::NoSuchMethod::T*
-    return this.{self::NoSuchMethod::noSuchMethod}(new core::_InvocationMirror::_withType(#method, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[x]), core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))) as{TypeError,ForDynamic} self::NoSuchMethod::T*;
-  no-such-method-forwarder set y(self::NoSuchMethod::T* x) → void
+  no-such-method-forwarder get x() → self::NoSuchMethod::T?
+    return this.{self::NoSuchMethod::noSuchMethod}(new core::_InvocationMirror::_withType(#x, 1, const <core::Type*>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))) as{TypeError,ForDynamic,ForNonNullableByDefault} self::NoSuchMethod::T?;
+  no-such-method-forwarder method method(self::NoSuchMethod::T% x) → self::NoSuchMethod::T%
+    return this.{self::NoSuchMethod::noSuchMethod}(new core::_InvocationMirror::_withType(#method, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[x]), core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))) as{TypeError,ForDynamic,ForNonNullableByDefault} self::NoSuchMethod::T%;
+  no-such-method-forwarder set y(self::NoSuchMethod::T% x) → void
     return this.{self::NoSuchMethod::noSuchMethod}(new core::_InvocationMirror::_withType(#y=, 2, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[x]), core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{})));
-  no-such-method-forwarder set x(self::NoSuchMethod::T* value) → void
+  no-such-method-forwarder set x(self::NoSuchMethod::T? value) → void
     return this.{self::NoSuchMethod::noSuchMethod}(new core::_InvocationMirror::_withType(#x=, 2, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[value]), core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{})));
 }
 static method main() → dynamic
@@ -167,17 +88,17 @@
 
 
 Extra constant evaluation status:
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///generic_covariance_sound_variance.dart:22:5 -> SymbolConstant(#x)
-Evaluated: ListLiteral @ org-dartlang-testcase:///generic_covariance_sound_variance.dart:22:5 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-testcase:///generic_covariance_sound_variance.dart:22:5 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///generic_covariance_sound_variance.dart:22:5 -> InstanceConstant(const _ImmutableMap<Symbol*, dynamic>{_ImmutableMap._kvPairs: const <dynamic>[]})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///generic_covariance_sound_variance.dart:22:6 -> SymbolConstant(#x)
+Evaluated: ListLiteral @ org-dartlang-testcase:///generic_covariance_sound_variance.dart:22:6 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-testcase:///generic_covariance_sound_variance.dart:22:6 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///generic_covariance_sound_variance.dart:22:6 -> InstanceConstant(const _ImmutableMap<Symbol*, dynamic>{_ImmutableMap._kvPairs: const <dynamic>[]})
 Evaluated: SymbolLiteral @ org-dartlang-testcase:///generic_covariance_sound_variance.dart:23:5 -> SymbolConstant(#method)
 Evaluated: ListLiteral @ org-dartlang-testcase:///generic_covariance_sound_variance.dart:23:5 -> ListConstant(const <Type*>[])
 Evaluated: MapLiteral @ org-dartlang-testcase:///generic_covariance_sound_variance.dart:23:5 -> InstanceConstant(const _ImmutableMap<Symbol*, dynamic>{_ImmutableMap._kvPairs: const <dynamic>[]})
 Evaluated: SymbolLiteral @ org-dartlang-testcase:///generic_covariance_sound_variance.dart:24:12 -> SymbolConstant(#y=)
 Evaluated: ListLiteral @ org-dartlang-testcase:///generic_covariance_sound_variance.dart:24:12 -> ListConstant(const <Type*>[])
 Evaluated: MapLiteral @ org-dartlang-testcase:///generic_covariance_sound_variance.dart:24:12 -> InstanceConstant(const _ImmutableMap<Symbol*, dynamic>{_ImmutableMap._kvPairs: const <dynamic>[]})
-Evaluated: SymbolLiteral @ org-dartlang-testcase:///generic_covariance_sound_variance.dart:22:5 -> SymbolConstant(#x=)
-Evaluated: ListLiteral @ org-dartlang-testcase:///generic_covariance_sound_variance.dart:22:5 -> ListConstant(const <Type*>[])
-Evaluated: MapLiteral @ org-dartlang-testcase:///generic_covariance_sound_variance.dart:22:5 -> InstanceConstant(const _ImmutableMap<Symbol*, dynamic>{_ImmutableMap._kvPairs: const <dynamic>[]})
+Evaluated: SymbolLiteral @ org-dartlang-testcase:///generic_covariance_sound_variance.dart:22:6 -> SymbolConstant(#x=)
+Evaluated: ListLiteral @ org-dartlang-testcase:///generic_covariance_sound_variance.dart:22:6 -> ListConstant(const <Type*>[])
+Evaluated: MapLiteral @ org-dartlang-testcase:///generic_covariance_sound_variance.dart:22:6 -> InstanceConstant(const _ImmutableMap<Symbol*, dynamic>{_ImmutableMap._kvPairs: const <dynamic>[]})
 Extra constant evaluation: evaluated: 42, effectively constant: 13
diff --git a/pkg/front_end/testcases/variance/generic_covariance_sound_variance.dart.weak.transformed.expect b/pkg/front_end/testcases/variance/generic_covariance_sound_variance.dart.weak.transformed.expect
index 8f2b714..3719b77 100644
--- a/pkg/front_end/testcases/variance/generic_covariance_sound_variance.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/variance/generic_covariance_sound_variance.dart.weak.transformed.expect
@@ -1,191 +1,113 @@
-library;
+library /*isNonNullableByDefault*/;
 import self as self;
 import "dart:core" as core;
 
-typedef ContraFunction<contravariant T extends core::Object* = dynamic> = (T*) →* void;
-typedef InvFunction<invariant T extends core::Object* = dynamic> = (T*) →* T*;
-class Contravariant<contravariant T extends core::Object* = dynamic> extends core::Object {
-  synthetic constructor •() → self::Contravariant<self::Contravariant::T*>*
+typedef ContraFunction<contravariant T extends core::Object? = dynamic> = (T%) → void;
+typedef InvFunction<invariant T extends core::Object? = dynamic> = (T%) → T%;
+class Contravariant<contravariant T extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::Contravariant<self::Contravariant::T%>
     : 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 Invariant<invariant T extends core::Object* = dynamic> extends core::Object {
-  synthetic constructor •() → self::Invariant<self::Invariant::T*>*
+class Invariant<invariant T extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::Invariant<self::Invariant::T%>
     : 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 A<contravariant T extends core::Object* = dynamic, U extends core::Object* = dynamic, V extends core::Object* = dynamic> extends core::Object {
-  final field (self::A::T*) →* void field = null;
-  synthetic constructor •() → self::A<self::A::T*, self::A::U*, self::A::V*>*
+class A<contravariant T extends core::Object? = dynamic, U extends core::Object? = dynamic, V extends core::Object? = dynamic> extends core::Object {
+  final field (self::A::T%) →? void field = null;
+  synthetic constructor •() → self::A<self::A::T%, self::A::U%, self::A::V%>
     : super core::Object::•()
     ;
-  method method(self::A::T* t, (self::A::U*) →* void u, generic-covariant-impl self::A::V* v) → void {}
-  method method2(self::A::T* x, [self::A::T* y = #C1]) → void {}
-  set x(self::A::T* t) → void {}
-  get mapContra() → core::Map<self::A::U*, self::Contravariant<self::A::V*>*>*
-    return core::Map::•<self::A::U*, self::Contravariant<self::A::V*>*>();
-  get mapContraFn() → core::Map<self::A::U*, (self::A::V*) →* void>*
-    return core::Map::•<self::A::U*, (self::A::V*) →* void>();
-  get mapInv() → core::Map<self::A::U*, self::Invariant<self::A::V*>*>*
-    return core::Map::•<self::A::U*, self::Invariant<self::A::V*>*>();
-  get mapInvFn() → core::Map<self::A::U*, (self::A::V*) →* self::A::V*>*
-    return core::Map::•<self::A::U*, (self::A::V*) →* self::A::V*>();
-  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
+  method method(self::A::T% t, (self::A::U%) → void u, generic-covariant-impl self::A::V% v) → void {}
+  method method2(self::A::T% x, [self::A::T? y = #C1]) → void {}
+  set x(self::A::T% t) → void {}
+  get mapContra() → core::Map<self::A::U%, self::Contravariant<self::A::V%>>
+    return core::Map::•<self::A::U%, self::Contravariant<self::A::V%>>();
+  get mapContraFn() → core::Map<self::A::U%, (self::A::V%) → void>
+    return core::Map::•<self::A::U%, (self::A::V%) → void>();
+  get mapInv() → core::Map<self::A::U%, self::Invariant<self::A::V%>>
+    return core::Map::•<self::A::U%, self::Invariant<self::A::V%>>();
+  get mapInvFn() → core::Map<self::A::U%, (self::A::V%) → self::A::V%>
+    return core::Map::•<self::A::U%, (self::A::V%) → self::A::V%>();
 }
-class B<invariant T extends core::Object* = dynamic> extends core::Object {
-  field self::B::T* x = null;
-  synthetic constructor •() → self::B<self::B::T*>*
+class B<invariant T extends core::Object? = dynamic> extends core::Object {
+  field self::B::T? x = null;
+  synthetic constructor •() → self::B<self::B::T%>
     : super core::Object::•()
     ;
-  method method(self::B::T* x) → self::B::T*
+  method method(self::B::T% x) → self::B::T%
     return x;
-  set y(self::B::T* x) → void {}
-  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
-  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 get runtimeType() → core::Type*; -> core::Object::runtimeType
+  set y(self::B::T% x) → void {}
 }
-class C<contravariant T extends core::Object* = dynamic> extends core::Object {
-  final field (self::C::T*) →* void field = null;
-  synthetic constructor •() → self::C<self::C::T*>*
+class C<contravariant T extends core::Object? = dynamic> extends core::Object {
+  final field (self::C::T%) →? void field = null;
+  synthetic constructor •() → self::C<self::C::T%>
     : super core::Object::•()
     ;
-  method method(self::C::T* x, [self::C::T* y = #C1]) → void {}
-  set x(self::C::T* t) → 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
+  method method(self::C::T% x, [self::C::T? y = #C1]) → void {}
+  set x(self::C::T% t) → void {}
 }
-abstract class D<T extends core::Object* = dynamic> extends core::Object {
-  synthetic constructor •() → self::D<self::D::T*>*
+abstract class D<T extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::D<self::D::T%>
     : super core::Object::•()
     ;
-  abstract method method(generic-covariant-impl self::D::T* x) → core::int*;
-  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 method method(generic-covariant-impl self::D::T% x) → core::int;
 }
-class E<invariant T extends core::Object* = dynamic> extends core::Object {
-  final field (self::E::T*) →* void f;
-  constructor •((self::E::T*) →* void f) → self::E<self::E::T*>*
+class E<invariant T extends core::Object? = dynamic> extends core::Object {
+  final field (self::E::T%) → void f;
+  constructor •((self::E::T%) → void f) → self::E<self::E::T%>
     : self::E::f = f, super core::Object::•()
     ;
-  method method(self::E::T* x) → core::int* {
-    let final self::E::T* #t1 = x in this.{self::E::f}.call(#t1);
+  method method(self::E::T% x) → core::int {
+    let final self::E::T% #t1 = x in this.{self::E::f}.call(#t1);
+    return 0;
   }
-  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 F<invariant T extends core::Object* = dynamic> extends self::E<self::F::T*> implements self::D<self::F::T*> {
-  constructor •((self::F::T*) →* void f) → self::F<self::F::T*>*
+class F<invariant T extends core::Object? = dynamic> extends self::E<self::F::T%> implements self::D<self::F::T%> {
+  constructor •((self::F::T%) → void f) → self::F<self::F::T%>
     : super self::E::•(f)
     ;
-  forwarding-stub method method(generic-covariant-impl self::F::T* x) → core::int*
+  forwarding-stub method method(generic-covariant-impl self::F::T% x) → core::int
     return super.{self::E::method}(x);
 }
-class NoSuchMethod<invariant T extends core::Object* = dynamic> extends core::Object implements self::B<self::NoSuchMethod::T*> {
-  synthetic constructor •() → self::NoSuchMethod<self::NoSuchMethod::T*>*
+class NoSuchMethod<invariant T extends core::Object? = dynamic> extends core::Object implements self::B<self::NoSuchMethod::T%> {
+  synthetic constructor •() → self::NoSuchMethod<self::NoSuchMethod::T%>
     : super core::Object::•()
     ;
-  method noSuchMethod(core::Invocation* _) → dynamic
+  method noSuchMethod(core::Invocation _) → dynamic
     return 3;
-  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 get runtimeType() → core::Type*; -> core::Object::runtimeType
-  no-such-method-forwarder get x() → self::NoSuchMethod::T*
-    return this.{self::NoSuchMethod::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 1, #C3, #C4, core::Map::unmodifiable<core::Symbol*, dynamic>(#C5))) as{TypeError,ForDynamic} self::NoSuchMethod::T*;
-  no-such-method-forwarder method method(self::NoSuchMethod::T* x) → self::NoSuchMethod::T*
-    return this.{self::NoSuchMethod::noSuchMethod}(new core::_InvocationMirror::_withType(#C6, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(x)), core::Map::unmodifiable<core::Symbol*, dynamic>(#C5))) as{TypeError,ForDynamic} self::NoSuchMethod::T*;
-  no-such-method-forwarder set y(self::NoSuchMethod::T* x) → void
+  no-such-method-forwarder get x() → self::NoSuchMethod::T?
+    return this.{self::NoSuchMethod::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 1, #C3, #C4, core::Map::unmodifiable<core::Symbol*, dynamic>(#C5))) as{TypeError,ForDynamic,ForNonNullableByDefault} self::NoSuchMethod::T?;
+  no-such-method-forwarder method method(self::NoSuchMethod::T% x) → self::NoSuchMethod::T%
+    return this.{self::NoSuchMethod::noSuchMethod}(new core::_InvocationMirror::_withType(#C6, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(x)), core::Map::unmodifiable<core::Symbol*, dynamic>(#C5))) as{TypeError,ForDynamic,ForNonNullableByDefault} self::NoSuchMethod::T%;
+  no-such-method-forwarder set y(self::NoSuchMethod::T% x) → void
     return this.{self::NoSuchMethod::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 2, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(x)), core::Map::unmodifiable<core::Symbol*, dynamic>(#C5)));
-  no-such-method-forwarder set x(self::NoSuchMethod::T* value) → void
+  no-such-method-forwarder set x(self::NoSuchMethod::T? value) → void
     return this.{self::NoSuchMethod::noSuchMethod}(new core::_InvocationMirror::_withType(#C8, 2, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(value)), core::Map::unmodifiable<core::Symbol*, dynamic>(#C5)));
 }
 static method main() → dynamic {
-  self::A<core::int*, core::num*, core::String*>* a = new self::A::•<core::int*, core::num*, core::String*>();
+  self::A<core::int, core::num, core::String> a = new self::A::•<core::int, core::num, core::String>();
   self::expect(null, a.{self::A::field});
-  a.{self::A::method}(3, (core::num* num) → Null {}, "test");
+  a.{self::A::method}(3, (core::num num) → void {}, "test");
   a.{self::A::method2}(3);
   a.{self::A::x} = 3;
-  core::Map<core::num*, self::Contravariant<core::String*>*>* mapContra = a.{self::A::mapContra} as{TypeError,CovarianceCheck} core::Map<core::num*, self::Contravariant<core::String*>*>*;
-  core::Map<core::num*, (core::String*) →* void>* mapContraFn = a.{self::A::mapContraFn} as{TypeError,CovarianceCheck} core::Map<core::num*, (core::String*) →* void>*;
-  core::Map<core::num*, self::Invariant<core::String*>*>* mapInv = a.{self::A::mapInv} as{TypeError,CovarianceCheck} core::Map<core::num*, self::Invariant<core::String*>*>*;
-  core::Map<core::num*, (core::String*) →* core::String*>* mapInvFn = a.{self::A::mapInvFn} as{TypeError,CovarianceCheck} core::Map<core::num*, (core::String*) →* core::String*>*;
-  self::B<core::int*>* b = new self::B::•<core::int*>();
+  core::Map<core::num, self::Contravariant<core::String>> mapContra = a.{self::A::mapContra} as{TypeError,CovarianceCheck,ForNonNullableByDefault} core::Map<core::num, self::Contravariant<core::String>>;
+  core::Map<core::num, (core::String) → void> mapContraFn = a.{self::A::mapContraFn} as{TypeError,CovarianceCheck,ForNonNullableByDefault} core::Map<core::num, (core::String) → void>;
+  core::Map<core::num, self::Invariant<core::String>> mapInv = a.{self::A::mapInv} as{TypeError,CovarianceCheck,ForNonNullableByDefault} core::Map<core::num, self::Invariant<core::String>>;
+  core::Map<core::num, (core::String) → core::String> mapInvFn = a.{self::A::mapInvFn} as{TypeError,CovarianceCheck,ForNonNullableByDefault} core::Map<core::num, (core::String) → core::String>;
+  self::B<core::int> b = new self::B::•<core::int>();
   b.{self::B::x} = 3;
   self::expect(3, b.{self::B::x});
   self::expect(3, b.{self::B::method}(3));
   b.{self::B::y} = 3;
-  self::C<core::int*>* c = new self::C::•<core::int*>();
+  self::C<core::int> c = new self::C::•<core::int>();
   self::expect(null, c.{self::C::field});
   c.{self::C::method}(3, 2);
   c.{self::C::x} = 3;
-  self::D<core::Object*>* d = new self::F::•<core::String*>((core::String* s) → Null {});
+  self::D<core::Object> d = new self::F::•<core::String>((core::String s) → void {});
   d.{self::D::method}("test");
-  self::NoSuchMethod<core::num*>* nsm = new self::NoSuchMethod::•<core::num*>();
+  self::NoSuchMethod<core::num> nsm = new self::NoSuchMethod::•<core::num>();
   self::expect(3, nsm.{self::B::method}(3));
 }
 static method expect(dynamic expected, dynamic actual) → dynamic {
diff --git a/pkg/front_end/testcases/variance/mixin_type_parameter_modifier.dart b/pkg/front_end/testcases/variance/mixin_type_parameter_modifier.dart
index ec067aa..2aefefb 100644
--- a/pkg/front_end/testcases/variance/mixin_type_parameter_modifier.dart
+++ b/pkg/front_end/testcases/variance/mixin_type_parameter_modifier.dart
@@ -1,7 +1,7 @@
 // Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-// @dart=2.9
+
 class A {}
 
 mixin B<inout X, out Y, in Z> on A {}
diff --git a/pkg/front_end/testcases/variance/mixin_type_parameter_modifier.dart.textual_outline.expect b/pkg/front_end/testcases/variance/mixin_type_parameter_modifier.dart.textual_outline.expect
index a4e2429..dd52422 100644
--- a/pkg/front_end/testcases/variance/mixin_type_parameter_modifier.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/variance/mixin_type_parameter_modifier.dart.textual_outline.expect
@@ -1,4 +1,3 @@
-// @dart = 2.9
 class A {}
 mixin B<inout X, out Y, in Z> on A {}
 main() {}
diff --git a/pkg/front_end/testcases/variance/mixin_type_parameter_modifier.dart.weak.expect b/pkg/front_end/testcases/variance/mixin_type_parameter_modifier.dart.weak.expect
index c1ffa9b..abd3eea 100644
--- a/pkg/front_end/testcases/variance/mixin_type_parameter_modifier.dart.weak.expect
+++ b/pkg/front_end/testcases/variance/mixin_type_parameter_modifier.dart.weak.expect
@@ -1,22 +1,12 @@
-library;
+library /*isNonNullableByDefault*/;
 import self as self;
 import "dart:core" as core;
 
 class A extends core::Object {
-  synthetic constructor •() → self::A*
+  synthetic 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<invariant X extends core::Object* = dynamic, Y extends core::Object* = dynamic, contravariant Z extends core::Object* = dynamic> extends self::A /*isMixinDeclaration*/  {
+abstract class B<invariant X extends core::Object? = dynamic, Y extends core::Object? = dynamic, contravariant Z extends core::Object? = dynamic> extends self::A /*isMixinDeclaration*/  {
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/variance/mixin_type_parameter_modifier.dart.weak.outline.expect b/pkg/front_end/testcases/variance/mixin_type_parameter_modifier.dart.weak.outline.expect
index 65ebf5c..60dc231 100644
--- a/pkg/front_end/testcases/variance/mixin_type_parameter_modifier.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/variance/mixin_type_parameter_modifier.dart.weak.outline.expect
@@ -1,22 +1,12 @@
-library;
+library /*isNonNullableByDefault*/;
 import self as self;
 import "dart:core" as core;
 
 class A extends core::Object {
-  synthetic constructor •() → self::A*
+  synthetic constructor •() → 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
 }
-abstract class B<invariant X extends core::Object* = dynamic, Y extends core::Object* = dynamic, contravariant Z extends core::Object* = dynamic> extends self::A /*isMixinDeclaration*/  {
+abstract class B<invariant X extends core::Object? = dynamic, Y extends core::Object? = dynamic, contravariant Z extends core::Object? = dynamic> extends self::A /*isMixinDeclaration*/  {
 }
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/variance/mixin_type_parameter_modifier.dart.weak.transformed.expect b/pkg/front_end/testcases/variance/mixin_type_parameter_modifier.dart.weak.transformed.expect
index c1ffa9b..abd3eea 100644
--- a/pkg/front_end/testcases/variance/mixin_type_parameter_modifier.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/variance/mixin_type_parameter_modifier.dart.weak.transformed.expect
@@ -1,22 +1,12 @@
-library;
+library /*isNonNullableByDefault*/;
 import self as self;
 import "dart:core" as core;
 
 class A extends core::Object {
-  synthetic constructor •() → self::A*
+  synthetic 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<invariant X extends core::Object* = dynamic, Y extends core::Object* = dynamic, contravariant Z extends core::Object* = dynamic> extends self::A /*isMixinDeclaration*/  {
+abstract class B<invariant X extends core::Object? = dynamic, Y extends core::Object? = dynamic, contravariant Z extends core::Object? = dynamic> extends self::A /*isMixinDeclaration*/  {
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/variance/unconstrained_inference.dart b/pkg/front_end/testcases/variance/unconstrained_inference.dart
index fa68fbe..7f68e00 100644
--- a/pkg/front_end/testcases/variance/unconstrained_inference.dart
+++ b/pkg/front_end/testcases/variance/unconstrained_inference.dart
@@ -1,7 +1,7 @@
 // Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-// @dart=2.9
+
 class Covariant<out T> {}
 class Contravariant<in T> {}
 class Invariant<inout T> {}
diff --git a/pkg/front_end/testcases/variance/unconstrained_inference.dart.textual_outline.expect b/pkg/front_end/testcases/variance/unconstrained_inference.dart.textual_outline.expect
index 8440fa0..0d3c633 100644
--- a/pkg/front_end/testcases/variance/unconstrained_inference.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/variance/unconstrained_inference.dart.textual_outline.expect
@@ -1,4 +1,3 @@
-// @dart = 2.9
 class Covariant<out T> {}
 class Contravariant<in T> {}
 class Invariant<inout T> {}
diff --git a/pkg/front_end/testcases/variance/unconstrained_inference.dart.weak.expect b/pkg/front_end/testcases/variance/unconstrained_inference.dart.weak.expect
index d9a2571..0850650 100644
--- a/pkg/front_end/testcases/variance/unconstrained_inference.dart.weak.expect
+++ b/pkg/front_end/testcases/variance/unconstrained_inference.dart.weak.expect
@@ -1,60 +1,30 @@
-library;
+library /*isNonNullableByDefault*/;
 import self as self;
 import "dart:core" as core;
 
-class Covariant<T extends core::Object* = dynamic> extends core::Object {
-  synthetic constructor •() → self::Covariant<self::Covariant::T*>*
+class Covariant<T extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::Covariant<self::Covariant::T%>
     : 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 Contravariant<contravariant T extends core::Object* = dynamic> extends core::Object {
-  synthetic constructor •() → self::Contravariant<self::Contravariant::T*>*
+class Contravariant<contravariant T extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::Contravariant<self::Contravariant::T%>
     : 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 Invariant<invariant T extends core::Object* = dynamic> extends core::Object {
-  synthetic constructor •() → self::Invariant<self::Invariant::T*>*
+class Invariant<invariant T extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::Invariant<self::Invariant::T%>
     : 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 method covariantListInfer<T extends core::Object* = dynamic>(self::Covariant<core::List<self::covariantListInfer::T*>*>* x) → void {}
-static method contravariantListInfer<T extends core::Object* = dynamic>(self::Contravariant<core::List<self::contravariantListInfer::T*>*>* x) → void {}
-static method invariantListInfer<T extends core::Object* = dynamic>(self::Invariant<core::List<self::invariantListInfer::T*>*>* x) → void {}
+static method covariantListInfer<T extends core::Object? = dynamic>(self::Covariant<core::List<self::covariantListInfer::T%>> x) → void {}
+static method contravariantListInfer<T extends core::Object? = dynamic>(self::Contravariant<core::List<self::contravariantListInfer::T%>> x) → void {}
+static method invariantListInfer<T extends core::Object? = dynamic>(self::Invariant<core::List<self::invariantListInfer::T%>> x) → void {}
 static method main() → dynamic {
-  self::Covariant<dynamic>* cov = new self::Covariant::•<dynamic>();
-  self::covariantListInfer<dynamic>(new self::Covariant::•<core::List<dynamic>*>());
-  self::Contravariant<Null>* contra = new self::Contravariant::•<Null>();
-  self::contravariantListInfer<Null>(new self::Contravariant::•<core::List<Null>*>());
-  self::Invariant<dynamic>* inv = new self::Invariant::•<dynamic>();
-  self::invariantListInfer<Null>(new self::Invariant::•<core::List<Null>*>());
+  self::Covariant<dynamic> cov = new self::Covariant::•<dynamic>();
+  self::covariantListInfer<core::Object?>(new self::Covariant::•<core::List<core::Object?>>());
+  self::Contravariant<Never> contra = new self::Contravariant::•<Never>();
+  self::contravariantListInfer<core::Object?>(new self::Contravariant::•<core::List<core::Object?>>());
+  self::Invariant<dynamic> inv = new self::Invariant::•<dynamic>();
+  self::invariantListInfer<core::Object?>(new self::Invariant::•<core::List<core::Object?>>());
 }
diff --git a/pkg/front_end/testcases/variance/unconstrained_inference.dart.weak.outline.expect b/pkg/front_end/testcases/variance/unconstrained_inference.dart.weak.outline.expect
index 80e78fe..c5c73b9 100644
--- a/pkg/front_end/testcases/variance/unconstrained_inference.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/variance/unconstrained_inference.dart.weak.outline.expect
@@ -1,54 +1,24 @@
-library;
+library /*isNonNullableByDefault*/;
 import self as self;
 import "dart:core" as core;
 
-class Covariant<T extends core::Object* = dynamic> extends core::Object {
-  synthetic constructor •() → self::Covariant<self::Covariant::T*>*
+class Covariant<T extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::Covariant<self::Covariant::T%>
     ;
-  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 Contravariant<contravariant T extends core::Object* = dynamic> extends core::Object {
-  synthetic constructor •() → self::Contravariant<self::Contravariant::T*>*
+class Contravariant<contravariant T extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::Contravariant<self::Contravariant::T%>
     ;
-  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 Invariant<invariant T extends core::Object* = dynamic> extends core::Object {
-  synthetic constructor •() → self::Invariant<self::Invariant::T*>*
+class Invariant<invariant T extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::Invariant<self::Invariant::T%>
     ;
-  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 covariantListInfer<T extends core::Object* = dynamic>(self::Covariant<core::List<self::covariantListInfer::T*>*>* x) → void
+static method covariantListInfer<T extends core::Object? = dynamic>(self::Covariant<core::List<self::covariantListInfer::T%>> x) → void
   ;
-static method contravariantListInfer<T extends core::Object* = dynamic>(self::Contravariant<core::List<self::contravariantListInfer::T*>*>* x) → void
+static method contravariantListInfer<T extends core::Object? = dynamic>(self::Contravariant<core::List<self::contravariantListInfer::T%>> x) → void
   ;
-static method invariantListInfer<T extends core::Object* = dynamic>(self::Invariant<core::List<self::invariantListInfer::T*>*>* x) → void
+static method invariantListInfer<T extends core::Object? = dynamic>(self::Invariant<core::List<self::invariantListInfer::T%>> x) → void
   ;
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/variance/unconstrained_inference.dart.weak.transformed.expect b/pkg/front_end/testcases/variance/unconstrained_inference.dart.weak.transformed.expect
index d9a2571..0850650 100644
--- a/pkg/front_end/testcases/variance/unconstrained_inference.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/variance/unconstrained_inference.dart.weak.transformed.expect
@@ -1,60 +1,30 @@
-library;
+library /*isNonNullableByDefault*/;
 import self as self;
 import "dart:core" as core;
 
-class Covariant<T extends core::Object* = dynamic> extends core::Object {
-  synthetic constructor •() → self::Covariant<self::Covariant::T*>*
+class Covariant<T extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::Covariant<self::Covariant::T%>
     : 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 Contravariant<contravariant T extends core::Object* = dynamic> extends core::Object {
-  synthetic constructor •() → self::Contravariant<self::Contravariant::T*>*
+class Contravariant<contravariant T extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::Contravariant<self::Contravariant::T%>
     : 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 Invariant<invariant T extends core::Object* = dynamic> extends core::Object {
-  synthetic constructor •() → self::Invariant<self::Invariant::T*>*
+class Invariant<invariant T extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::Invariant<self::Invariant::T%>
     : 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 method covariantListInfer<T extends core::Object* = dynamic>(self::Covariant<core::List<self::covariantListInfer::T*>*>* x) → void {}
-static method contravariantListInfer<T extends core::Object* = dynamic>(self::Contravariant<core::List<self::contravariantListInfer::T*>*>* x) → void {}
-static method invariantListInfer<T extends core::Object* = dynamic>(self::Invariant<core::List<self::invariantListInfer::T*>*>* x) → void {}
+static method covariantListInfer<T extends core::Object? = dynamic>(self::Covariant<core::List<self::covariantListInfer::T%>> x) → void {}
+static method contravariantListInfer<T extends core::Object? = dynamic>(self::Contravariant<core::List<self::contravariantListInfer::T%>> x) → void {}
+static method invariantListInfer<T extends core::Object? = dynamic>(self::Invariant<core::List<self::invariantListInfer::T%>> x) → void {}
 static method main() → dynamic {
-  self::Covariant<dynamic>* cov = new self::Covariant::•<dynamic>();
-  self::covariantListInfer<dynamic>(new self::Covariant::•<core::List<dynamic>*>());
-  self::Contravariant<Null>* contra = new self::Contravariant::•<Null>();
-  self::contravariantListInfer<Null>(new self::Contravariant::•<core::List<Null>*>());
-  self::Invariant<dynamic>* inv = new self::Invariant::•<dynamic>();
-  self::invariantListInfer<Null>(new self::Invariant::•<core::List<Null>*>());
+  self::Covariant<dynamic> cov = new self::Covariant::•<dynamic>();
+  self::covariantListInfer<core::Object?>(new self::Covariant::•<core::List<core::Object?>>());
+  self::Contravariant<Never> contra = new self::Contravariant::•<Never>();
+  self::contravariantListInfer<core::Object?>(new self::Contravariant::•<core::List<core::Object?>>());
+  self::Invariant<dynamic> inv = new self::Invariant::•<dynamic>();
+  self::invariantListInfer<core::Object?>(new self::Invariant::•<core::List<core::Object?>>());
 }
diff --git a/pkg/front_end/testcases/weak.status b/pkg/front_end/testcases/weak.status
index 779ddea..d4a488a 100644
--- a/pkg/front_end/testcases/weak.status
+++ b/pkg/front_end/testcases/weak.status
@@ -4,14 +4,17 @@
 
 # Status file for the weak_suite.dart test suite.
 
-# general/platform_invalid_uris/main: SemiFuzzFailure # semi fuzz fails but isn't currently enabled by default.
-# general/error_recovery/issue_39058.crash: SemiFuzzFailure # semi fuzz fails but isn't currently enabled by default.
-# general/error_recovery/issue_39058_prime.crash: SemiFuzzFailure # semi fuzz fails but isn't currently enabled by default.
-# general/error_recovery/issue_39202.crash: SemiFuzzCrash # semi fuzz fails but isn't currently enabled by default.
-# regress/utf_16_le_content.crash: Crash # semi fuzz fails but isn't currently enabled by default.
+general/platform_invalid_uris/main: SemiFuzzFailure
+general/error_recovery/issue_39058_prime.crash: SemiFuzzFailure
+general/error_recovery/issue_39202.crash: SemiFuzzCrash
+general/error_recovery/issue_39058.crash: SemiFuzzFailure
+regress/utf_16_le_content.crash: SemiFuzzCrash
 
 extension_types/simple: ExpectationFileMismatchSerialized # Expected.
+extension_types/simple_getter_resolution: ExpectationFileMismatchSerialized # Expected.
 extension_types/simple_method_resolution: ExpectationFileMismatchSerialized # Expected.
+extension_types/simple_operator_resolution: ExpectationFileMismatchSerialized # Expected.
+extension_types/simple_setter_resolution: ExpectationFileMismatchSerialized # Expected.
 extensions/call_methods: TypeCheckError
 extensions/extension_setter_error: TypeCheckError
 extensions/instance_access_of_static: RuntimeError
@@ -30,6 +33,8 @@
 general/constructor_initializer_invalid: RuntimeError # Fails execution after recovery
 general/covariant_field: TypeCheckError
 general/covariant_generic: RuntimeError
+general/crashes/crash_02/main: Crash
+general/crashes/crash_04/main: Crash
 general/duplicated_declarations: TypeCheckError
 general/duplicated_field_initializer: RuntimeError
 general/error_locations/error_location_01: RuntimeError
@@ -65,6 +70,7 @@
 general/error_recovery/yield_not_in_generator: RuntimeError
 general/expressions: RuntimeError
 general/external_import: RuntimeError # The native extension to import doesn't exist. This is ok.
+general/function_invocation_bounds: TypeCheckError
 general/getter_vs_setter_type: TypeCheckError
 general/incomplete_field_formal_parameter: RuntimeError
 general/infer_field_from_multiple: TypeCheckError
@@ -78,6 +84,7 @@
 general/issue41210a: TypeCheckError
 general/issue41210b/issue41210.no_link: TypeCheckError
 general/issue41210b/issue41210: TypeCheckError
+general/issue45204: TypeCheckError
 general/micro: RuntimeError
 general/mixin_application_override: ExpectationFileMismatch # Too many errors.
 general/mixin_application_override: TypeCheckError
diff --git a/pkg/front_end/testing.json b/pkg/front_end/testing.json
index d3df652..ef56494 100644
--- a/pkg/front_end/testing.json
+++ b/pkg/front_end/testing.json
@@ -113,7 +113,7 @@
     {
       "name": "text_serialization",
       "kind": "Chain",
-      "source": "test/fasta/text_serialization_tester.dart",
+      "source": "test/fasta/text_serialization_suite.dart",
       "path": "testcases/",
       "status": "testcases/text_serialization.status",
       "pattern": [
@@ -134,7 +134,8 @@
       "path": "testcases/",
       "status": "testcases/weak.status",
       "pattern": [
-        "\\.dart$"
+        "\\.dart$",
+        "\\.crash_dart$"
       ],
       "exclude": [
         "/testcases/.*_part[0-9]*\\.dart$",
diff --git a/pkg/front_end/tool/_fasta/bench_maker.dart b/pkg/front_end/tool/_fasta/bench_maker.dart
index 0cc8476..22732a7 100644
--- a/pkg/front_end/tool/_fasta/bench_maker.dart
+++ b/pkg/front_end/tool/_fasta/bench_maker.dart
@@ -345,6 +345,11 @@
     throw "not implemented";
   }
 
+  @override
+  void visitExtensionType(ExtensionType node, StringBuffer sb) {
+    throw "not implemented";
+  }
+
   Map<String, dynamic> toJson() {
     return <String, dynamic>{
       "classes": classes,
diff --git a/pkg/frontend_server/lib/frontend_server.dart b/pkg/frontend_server/lib/frontend_server.dart
index a4208db..2c45796c 100644
--- a/pkg/frontend_server/lib/frontend_server.dart
+++ b/pkg/frontend_server/lib/frontend_server.dart
@@ -10,7 +10,11 @@
 
 import 'package:args/args.dart';
 import 'package:dev_compiler/dev_compiler.dart'
-    show DevCompilerTarget, ExpressionCompiler;
+    show
+        DevCompilerTarget,
+        ExpressionCompiler,
+        parseModuleFormat,
+        ProgramCompiler;
 
 // front_end/src imports below that require lint `ignore_for_file`
 // are a temporary state of things until frontend team builds better api
@@ -605,6 +609,7 @@
       String filename, String fileSystemScheme, String moduleFormat) async {
     var packageConfig = await loadPackageConfigUri(
         _compilerOptions.packagesFileUri ?? File('.packages').absolute.uri);
+    var soundNullSafety = _compilerOptions.nnbdMode == NnbdMode.Strong;
     final Component component = results.component;
     // Compute strongly connected components.
     final strongComponents = StrongComponents(component,
@@ -623,13 +628,14 @@
         component, strongComponents, fileSystemScheme, packageConfig,
         useDebuggerModuleNames: useDebuggerModuleNames,
         emitDebugMetadata: emitDebugMetadata,
-        moduleFormat: moduleFormat);
+        moduleFormat: moduleFormat,
+        soundNullSafety: soundNullSafety);
     final sourceFileSink = sourceFile.openWrite();
     final manifestFileSink = manifestFile.openWrite();
     final sourceMapsFileSink = sourceMapsFile.openWrite();
     final metadataFileSink =
         emitDebugMetadata ? metadataFile.openWrite() : null;
-    await _bundler.compile(
+    final kernel2JsCompilers = await _bundler.compile(
         results.classHierarchy,
         results.coreTypes,
         results.loadedLibraries,
@@ -637,6 +643,7 @@
         manifestFileSink,
         sourceMapsFileSink,
         metadataFileSink);
+    cachedProgramCompilers.addAll(kernel2JsCompilers);
     await Future.wait([
       sourceFileSink.close(),
       manifestFileSink.close(),
@@ -804,6 +811,12 @@
     }
   }
 
+  /// Program compilers per module.
+  ///
+  /// Produced suring initial compilation of the module to JavaScript,
+  /// cached to be used for expression compilation in [compileExpressionToJs].
+  final Map<String, ProgramCompiler> cachedProgramCompilers = {};
+
   @override
   Future<Null> compileExpressionToJs(
       String libraryUri,
@@ -820,7 +833,7 @@
       reportError('JavaScript bundler is null');
       return;
     }
-    if (!_bundler.compilers.containsKey(moduleName)) {
+    if (!cachedProgramCompilers.containsKey(moduleName)) {
       reportError('Cannot find kernel2js compiler for $moduleName.');
       return;
     }
@@ -831,24 +844,25 @@
     _processedOptions.ticker
         .logMs('Compiling expression to JavaScript in $moduleName');
 
-    var kernel2jsCompiler = _bundler.compilers[moduleName];
+    final kernel2jsCompiler = cachedProgramCompilers[moduleName];
     Component component = _generator.lastKnownGoodComponent;
     component.computeCanonicalNames();
 
     _processedOptions.ticker.logMs('Computed component');
 
-    var expressionCompiler = new ExpressionCompiler(
+    final expressionCompiler = new ExpressionCompiler(
       _compilerOptions,
+      parseModuleFormat(_options['dartdevc-module-format'] as String),
       errors,
       _generator.generator,
       kernel2jsCompiler,
       component,
     );
 
-    var procedure = await expressionCompiler.compileExpressionToJs(
+    final procedure = await expressionCompiler.compileExpressionToJs(
         libraryUri, line, column, jsFrameValues, expression);
 
-    var result = errors.length > 0 ? errors[0] : procedure;
+    final result = errors.length > 0 ? errors[0] : procedure;
 
     // TODO(annagrin): kernelBinaryFilename is too specific
     // rename to _outputFileName?
diff --git a/pkg/frontend_server/lib/src/javascript_bundle.dart b/pkg/frontend_server/lib/src/javascript_bundle.dart
index 924c551..9829c57 100644
--- a/pkg/frontend_server/lib/src/javascript_bundle.dart
+++ b/pkg/frontend_server/lib/src/javascript_bundle.dart
@@ -27,9 +27,9 @@
       this._fileSystemScheme, this._packageConfig,
       {this.useDebuggerModuleNames = false,
       this.emitDebugMetadata = false,
+      this.soundNullSafety = false,
       String moduleFormat})
-      : compilers = <String, ProgramCompiler>{},
-        _moduleFormat = parseModuleFormat(moduleFormat ?? 'amd') {
+      : _moduleFormat = parseModuleFormat(moduleFormat ?? 'amd') {
     _summaries = <Component>[];
     _summaryUris = <Uri>[];
     _moduleImportForSummary = <Uri, String>{};
@@ -63,8 +63,8 @@
   final PackageConfig _packageConfig;
   final bool useDebuggerModuleNames;
   final bool emitDebugMetadata;
-  final Map<String, ProgramCompiler> compilers;
   final ModuleFormat _moduleFormat;
+  final bool soundNullSafety;
 
   List<Component> _summaries;
   List<Uri> _summaryUris;
@@ -73,7 +73,7 @@
   Map<Uri, Component> _uriToComponent;
 
   /// Compile each component into a single JavaScript module.
-  Future<void> compile(
+  Future<Map<String, ProgramCompiler>> compile(
       ClassHierarchy classHierarchy,
       CoreTypes coreTypes,
       Set<Library> loadedLibraries,
@@ -86,6 +86,7 @@
     var metadataOffset = 0;
     final manifest = <String, Map<String, List<int>>>{};
     final Set<Uri> visited = <Uri>{};
+    final Map<String, ProgramCompiler> kernel2JsCompilers = {};
 
     final importToSummary = Map<Library, Component>.identity();
     final summaryToModule = Map<Component, String>.identity();
@@ -135,6 +136,7 @@
           summarizeApi: false,
           emitDebugMetadata: emitDebugMetadata,
           moduleName: moduleName,
+          soundNullSafety: soundNullSafety,
         ),
         importToSummary,
         summaryToModule,
@@ -147,9 +149,8 @@
       // so it can map dart symbols to js symbols
       // [issue 40273](https://github.com/dart-lang/sdk/issues/40273)
 
-      // program compiler is used by ExpressionCompiler to evaluate expressions
-      // on demand
-      compilers[moduleName] = compiler;
+      // Save program compiler to reuse for expression evaluation.
+      kernel2JsCompilers[moduleName] = compiler;
 
       final moduleUrl = urlForComponentUri(moduleUri);
       String sourceMapBase;
@@ -198,6 +199,8 @@
       };
     }
     manifestSink.add(utf8.encode(json.encode(manifest)));
+
+    return kernel2JsCompilers;
   }
 }
 
diff --git a/pkg/frontend_server/test/src/javascript_bundle_test.dart b/pkg/frontend_server/test/src/javascript_bundle_test.dart
index 26a7c21..02cd813 100644
--- a/pkg/frontend_server/test/src/javascript_bundle_test.dart
+++ b/pkg/frontend_server/test/src/javascript_bundle_test.dart
@@ -106,8 +106,14 @@
     final metadataSink = _MemorySink();
     final coreTypes = CoreTypes(testComponent);
 
-    await javaScriptBundler.compile(ClassHierarchy(testComponent, coreTypes),
-        coreTypes, {}, codeSink, manifestSink, sourcemapSink, metadataSink);
+    final compilers = await javaScriptBundler.compile(
+        ClassHierarchy(testComponent, coreTypes),
+        coreTypes,
+        {},
+        codeSink,
+        manifestSink,
+        sourcemapSink,
+        metadataSink);
 
     final Map manifest = json.decode(utf8.decode(manifestSink.buffer));
     final String code = utf8.decode(codeSink.buffer);
@@ -122,6 +128,9 @@
 
     // verify source map url is correct.
     expect(code, contains('sourceMappingURL=c.dart.lib.js.map'));
+
+    // verify program compilers are created.
+    expect(compilers.keys, equals([urlForComponentUri(library.importUri)]));
   });
 
   test('converts package: uris into /packages/ uris', () async {
diff --git a/pkg/kernel/binary.md b/pkg/kernel/binary.md
index d4edbf5..b594898 100644
--- a/pkg/kernel/binary.md
+++ b/pkg/kernel/binary.md
@@ -147,7 +147,7 @@
 
 type ComponentFile {
   UInt32 magic = 0x90ABCDEF;
-  UInt32 formatVersion = 56;
+  UInt32 formatVersion = 60;
   Byte[10] shortSdkHash;
   List<String> problemsAsJson; // Described in problems.md.
   Library[] libraries;
@@ -337,6 +337,7 @@
   Byte tag = 115;
   CanonicalNameReference canonicalName;
   StringReference name;
+  List<Expression> annotations;
   UriReference fileUri;
   FileOffset fileOffset;
   List<TypeParameter> typeParameters;
@@ -741,6 +742,19 @@
   MemberReference interfaceTargetOrigin; // May be NullReference.
 }
 
+type InstanceGetterInvocation extends Expression {
+  Byte tag = 89;
+  Byte kind; // Index into InstanceAccessKind above.
+  Byte flags (isInvariant, isBoundsSafe);
+  FileOffset fileOffset;
+  Expression receiver;
+  Name name;
+  Arguments arguments;
+  DartType functionType;
+  MemberReference interfaceTarget;
+  MemberReference interfaceTargetOrigin; // May be NullReference.
+}
+
 type DynamicInvocation extends Expression {
   Byte tag = 124;
   Byte kind; // Index into DynamicAccessKind above.
@@ -789,7 +803,6 @@
   Byte tag = 15;
   FileOffset fileOffset;
   Expression expression;
-  Byte isNot;
 }
 
 type EqualsCall extends Expression {
@@ -797,7 +810,6 @@
   FileOffset fileOffset;
   Expression left;
   Expression right;
-  Byte isNot;
   DartType functionType;
   MemberReference interfaceTarget;
   MemberReference interfaceTargetOrigin; // May be NullReference.
diff --git a/pkg/kernel/lib/ast.dart b/pkg/kernel/lib/ast.dart
index 7e38523..fde2440 100644
--- a/pkg/kernel/lib/ast.dart
+++ b/pkg/kernel/lib/ast.dart
@@ -72,8 +72,8 @@
 import 'visitor.dart';
 export 'visitor.dart';
 
-import 'canonical_name.dart' show CanonicalName;
-export 'canonical_name.dart' show CanonicalName;
+import 'canonical_name.dart' show CanonicalName, Reference;
+export 'canonical_name.dart' show CanonicalName, Reference;
 
 import 'default_language_version.dart' show defaultLanguageVersion;
 export 'default_language_version.dart' show defaultLanguageVersion;
@@ -84,6 +84,7 @@
 import 'type_algebra.dart';
 import 'type_environment.dart';
 import 'src/assumptions.dart';
+import 'src/non_null.dart';
 import 'src/printer.dart';
 import 'src/text_util.dart';
 
@@ -217,8 +218,6 @@
     }
   }
 
-  CanonicalName? get canonicalName => reference.canonicalName;
-
   /// This is an advanced feature.
   ///
   /// See [Component.relink] for a comprehensive description.
@@ -240,116 +239,6 @@
   void addAnnotation(Expression node);
 }
 
-/// Indirection between a reference and its definition.
-///
-/// There is only one reference object per [NamedNode].
-class Reference {
-  CanonicalName? canonicalName;
-
-  NamedNode? _node;
-
-  NamedNode? get node {
-    if (_node == null) {
-      // Either this is an unbound reference or it belongs to a lazy-loaded
-      // (and not yet loaded) class. If it belongs to a lazy-loaded class,
-      // load the class.
-
-      CanonicalName? canonicalNameParent = canonicalName?.parent;
-      while (canonicalNameParent != null) {
-        if (canonicalNameParent.name.startsWith("@")) {
-          break;
-        }
-        canonicalNameParent = canonicalNameParent.parent;
-      }
-      if (canonicalNameParent != null) {
-        NamedNode? parentNamedNode =
-            canonicalNameParent.parent?.reference?._node;
-        if (parentNamedNode is Class) {
-          Class parentClass = parentNamedNode;
-          if (parentClass.lazyBuilder != null) {
-            parentClass.ensureLoaded();
-          }
-        }
-      }
-    }
-    return _node;
-  }
-
-  void set node(NamedNode? node) {
-    _node = node;
-  }
-
-  String toString() {
-    return "Reference to ${toStringInternal()}";
-  }
-
-  String toStringInternal() {
-    if (canonicalName != null) {
-      return '${canonicalName!.toStringInternal()}';
-    }
-    if (node != null) {
-      return node!.toStringInternal();
-    }
-    return 'Unbound reference';
-  }
-
-  Library get asLibrary {
-    if (node == null) {
-      throw '$this is not bound to an AST node. A library was expected';
-    }
-    return node as Library;
-  }
-
-  Class get asClass {
-    if (node == null) {
-      throw '$this is not bound to an AST node. A class was expected';
-    }
-    return node as Class;
-  }
-
-  Member get asMember {
-    if (node == null) {
-      throw '$this is not bound to an AST node. A member was expected';
-    }
-    return node as Member;
-  }
-
-  Field get asField {
-    if (node == null) {
-      throw '$this is not bound to an AST node. A field was expected';
-    }
-    return node as Field;
-  }
-
-  Constructor get asConstructor {
-    if (node == null) {
-      throw '$this is not bound to an AST node. A constructor was expected';
-    }
-    return node as Constructor;
-  }
-
-  Procedure get asProcedure {
-    if (node == null) {
-      throw '$this is not bound to an AST node. A procedure was expected';
-    }
-    return node as Procedure;
-  }
-
-  Typedef get asTypedef {
-    if (node == null) {
-      throw '$this is not bound to an AST node. A typedef was expected';
-    }
-    return node as Typedef;
-  }
-
-  Extension get asExtension {
-    if (node == null) {
-      throw '$this is not bound to an AST node. An extension was expected';
-    }
-    return node as Extension;
-  }
-}
-
 // ------------------------------------------------------------------------
 //                      LIBRARIES and CLASSES
 // ------------------------------------------------------------------------
@@ -546,7 +435,7 @@
   }
 
   void computeCanonicalNames() {
-    CanonicalName canonicalName = this.canonicalName!;
+    CanonicalName canonicalName = this.reference.canonicalName!;
     for (int i = 0; i < typedefs.length; ++i) {
       Typedef typedef_ = typedefs[i];
       canonicalName.getChildFromTypedef(typedef_).bindTo(typedef_.reference);
@@ -689,9 +578,10 @@
 ///     export <url>;
 ///
 /// optionally with metadata and [Combinators].
-class LibraryDependency extends TreeNode {
+class LibraryDependency extends TreeNode implements Annotatable {
   int flags;
 
+  @override
   final List<Expression> annotations;
 
   Reference importedLibraryReference;
@@ -742,6 +632,7 @@
   bool get isImport => !isExport;
   bool get isDeferred => flags & DeferredFlag != 0;
 
+  @override
   void addAnnotation(Expression annotation) {
     annotations.add(annotation..parent = this);
   }
@@ -787,14 +678,17 @@
 ///     part <url>;
 ///
 /// optionally with metadata.
-class LibraryPart extends TreeNode {
+class LibraryPart extends TreeNode implements Annotatable {
+  @override
   final List<Expression> annotations;
+
   final String partUri;
 
   LibraryPart(this.annotations, this.partUri) {
     setParents(annotations, this);
   }
 
+  @override
   void addAnnotation(Expression annotation) {
     annotations.add(annotation..parent = this);
   }
@@ -872,12 +766,14 @@
 }
 
 /// Declaration of a type alias.
-class Typedef extends NamedNode implements FileUriNode {
+class Typedef extends NamedNode implements FileUriNode, Annotatable {
   /// The URI of the source file that contains the declaration of this typedef.
   @override
   Uri? fileUri;
 
+  @override
   List<Expression> annotations = const <Expression>[];
+
   String name;
   final List<TypeParameter> typeParameters;
   // TODO(johnniwinther): Make this non-nullable.
@@ -946,6 +842,7 @@
     }
   }
 
+  @override
   void addAnnotation(Expression node) {
     if (annotations.isEmpty) {
       annotations = <Expression>[];
@@ -1271,7 +1168,7 @@
   }
 
   void computeCanonicalNames() {
-    CanonicalName canonicalName = this.canonicalName!;
+    CanonicalName canonicalName = this.reference.canonicalName!;
     if (!dirty) return;
     for (int i = 0; i < fields.length; ++i) {
       Field member = fields[i];
@@ -1524,7 +1421,7 @@
 ///
 /// The members are converted into top-level procedures and only accessible
 /// by reference in the [Extension] node.
-class Extension extends NamedNode implements FileUriNode {
+class Extension extends NamedNode implements Annotatable, FileUriNode {
   /// Name of the extension.
   ///
   /// If unnamed, the extension will be given a synthesized name by the
@@ -1552,6 +1449,18 @@
   /// by reference through [ExtensionMemberDescriptor].
   final List<ExtensionMemberDescriptor> members;
 
+  @override
+  List<Expression> annotations = const <Expression>[];
+
+  @override
+  void addAnnotation(Expression node) {
+    if (annotations.isEmpty) {
+      annotations = <Expression>[];
+    }
+    annotations.add(node);
+    node.parent = this;
+  }
+
   Extension(
       {required this.name,
       List<TypeParameter>? typeParameters,
@@ -1578,6 +1487,8 @@
   @override
   R accept1<R, A>(TreeVisitor1<R, A> v, A arg) => v.visitExtension(this, arg);
 
+  R acceptReference<R>(Visitor<R> v) => v.visitExtensionReference(this);
+
   @override
   void visitChildren(Visitor v) {
     visitList(typeParameters, v);
@@ -1840,14 +1751,6 @@
 
   Reference get getterReference => super.reference;
 
-  @override
-  @Deprecated(
-      "Use the specific getterCanonicalName/setterCanonicalName instead")
-  CanonicalName? get canonicalName => reference.canonicalName;
-
-  CanonicalName? get getterCanonicalName => getterReference.canonicalName;
-  CanonicalName? get setterCanonicalName => setterReference?.canonicalName;
-
   Field.mutable(Name? name,
       {this.type: const DynamicType(),
       this.initializer,
@@ -4631,7 +4534,7 @@
 
   Reference? interfaceTargetReference;
 
-  SuperPropertySet(Name name, Expression value, Member interfaceTarget)
+  SuperPropertySet(Name name, Expression value, Member? interfaceTarget)
       : this.byReference(
             name, value, getMemberReferenceSetter(interfaceTarget));
 
@@ -5329,6 +5232,169 @@
   }
 }
 
+/// An invocation of an instance getter or field with a statically known
+/// interface target.
+///
+/// This is used only for web backend in order to support invocation of
+/// native properties as functions. This node will be removed when this
+/// invocation style is no longer supported.
+class InstanceGetterInvocation extends InvocationExpression {
+  // Must match serialized bit positions.
+  static const int FlagInvariant = 1 << 0;
+  static const int FlagBoundsSafe = 1 << 1;
+
+  final InstanceAccessKind kind;
+  Expression receiver;
+
+  @override
+  Name name;
+
+  @override
+  Arguments arguments;
+
+  int flags = 0;
+
+  /// The static type of the invocation, or `dynamic` is of the type is unknown.
+  ///
+  /// This includes substituted type parameters from the static receiver type
+  /// and generic type arguments.
+  ///
+  /// For instance
+  ///
+  ///    class A<T> {
+  ///      Map<T, S> Function<S>(S) get map => ...
+  ///      dynamic get dyn => ...
+  ///    }
+  ///    m(A<String> a) {
+  ///      a.map(0); // The function type is `Map<String, int> Function(int)`.
+  ///      a.dyn(0); // The function type is `null`.
+  ///    }
+  ///
+  FunctionType? functionType;
+
+  Reference interfaceTargetReference;
+
+  InstanceGetterInvocation(InstanceAccessKind kind, Expression receiver,
+      Name name, Arguments arguments,
+      {required Member interfaceTarget, required FunctionType? functionType})
+      : this.byReference(kind, receiver, name, arguments,
+            interfaceTargetReference:
+                getNonNullableMemberReferenceGetter(interfaceTarget),
+            functionType: functionType);
+
+  InstanceGetterInvocation.byReference(
+      this.kind, this.receiver, this.name, this.arguments,
+      {required this.interfaceTargetReference, required this.functionType})
+      // ignore: unnecessary_null_comparison
+      : assert(interfaceTargetReference != null),
+        assert(functionType == null || functionType.typeParameters.isEmpty) {
+    receiver.parent = this;
+    arguments.parent = this;
+  }
+
+  Member get interfaceTarget => interfaceTargetReference.asMember;
+
+  void set interfaceTarget(Member target) {
+    interfaceTargetReference = getNonNullableMemberReferenceGetter(target);
+  }
+
+  /// If `true`, this call is known to be safe wrt. parameter covariance checks.
+  ///
+  /// This is for instance the case in code patterns like this
+  ///
+  ///     List<int> list = <int>[];
+  ///     list.add(0);
+  ///
+  /// where the `list` variable is known to hold a value of the same type as
+  /// the static type. In contrast the would not be the case in code patterns
+  /// like this
+  ///
+  ///     List<num> list = <double>[];
+  ///     list.add(0); // Runtime error `int` is not a subtype of `double`.
+  ///
+  bool get isInvariant => flags & FlagInvariant != 0;
+
+  void set isInvariant(bool value) {
+    flags = value ? (flags | FlagInvariant) : (flags & ~FlagInvariant);
+  }
+
+  /// If `true`, this call is known to be safe wrt. parameter covariance checks.
+  ///
+  /// This is for instance the case in code patterns like this
+  ///
+  ///     List list = new List.filled(2, 0);
+  ///     list[1] = 42;
+  ///
+  /// where the `list` is known to have a sufficient length for the update
+  /// in `list[1] = 42`.
+  bool get isBoundsSafe => flags & FlagBoundsSafe != 0;
+
+  void set isBoundsSafe(bool value) {
+    flags = value ? (flags | FlagBoundsSafe) : (flags & ~FlagBoundsSafe);
+  }
+
+  @override
+  DartType getStaticTypeInternal(StaticTypeContext context) =>
+      functionType?.returnType ?? const DynamicType();
+
+  @override
+  R accept<R>(ExpressionVisitor<R> v) => v.visitInstanceGetterInvocation(this);
+
+  @override
+  R accept1<R, A>(ExpressionVisitor1<R, A> v, A arg) =>
+      v.visitInstanceGetterInvocation(this, arg);
+
+  @override
+  void visitChildren(Visitor v) {
+    receiver.accept(v);
+    interfaceTarget.acceptReference(v);
+    name.accept(v);
+    arguments.accept(v);
+  }
+
+  @override
+  void transformChildren(Transformer v) {
+    // ignore: unnecessary_null_comparison
+    if (receiver != null) {
+      receiver = v.transform(receiver);
+      receiver.parent = this;
+    }
+    // ignore: unnecessary_null_comparison
+    if (arguments != null) {
+      arguments = v.transform(arguments);
+      arguments.parent = this;
+    }
+  }
+
+  @override
+  void transformOrRemoveChildren(RemovingTransformer v) {
+    // ignore: unnecessary_null_comparison
+    if (receiver != null) {
+      receiver = v.transform(receiver);
+      receiver.parent = this;
+    }
+    // ignore: unnecessary_null_comparison
+    if (arguments != null) {
+      arguments = v.transform(arguments);
+      arguments.parent = this;
+    }
+  }
+
+  @override
+  String toString() {
+    return "InstanceGetterInvocation($kind, ${toStringInternal()})";
+  }
+
+  @override
+  void toTextInternal(AstPrinter printer) {
+    printer.writeExpression(receiver,
+        minimumPrecedence: astToText.Precedence.PRIMARY);
+    printer.write('.');
+    printer.writeInterfaceMemberName(interfaceTargetReference, name);
+    printer.writeArguments(arguments);
+  }
+}
+
 /// Access kind used by [FunctionInvocation] and [FunctionTearOff].
 enum FunctionAccessKind {
   /// An access to the 'call' method on an expression of static type `Function`.
@@ -5472,7 +5538,6 @@
 /// An invocation of a local function declaration.
 class LocalFunctionInvocation extends InvocationExpression {
   /// The variable declaration for the function declaration.
-  // TODO(johnniwinther): Should this be the `FunctionDeclaration` instead?
   VariableDeclaration variable;
 
   @override
@@ -5499,6 +5564,10 @@
     arguments.parent = this;
   }
 
+  /// The declaration for the invoked local function.
+  FunctionDeclaration get localFunction =>
+      variable.parent as FunctionDeclaration;
+
   @override
   Name get name => Name.callName;
 
@@ -5548,21 +5617,14 @@
   }
 }
 
-/// Nullness test of an expression, that is `e == null` or `e != null`.
+/// Nullness test of an expression, that is `e == null`.
 ///
-/// This is generated for code like `e1 == e2` and `e1 != e2` where `e1` or `e2`
-/// is `null`.
+/// This is generated for code like `e1 == e2` where `e1` or `e2` is `null`.
 class EqualsNull extends Expression {
   /// The expression tested for nullness.
   Expression expression;
 
-  /// If `true` this is an `e != null` test. Otherwise it is an `e == null`
-  /// test.
-  final bool isNot;
-
-  EqualsNull(this.expression, {required this.isNot})
-      // ignore: unnecessary_null_comparison
-      : assert(isNot != null) {
+  EqualsNull(this.expression) {
     expression.parent = this;
   }
 
@@ -5608,18 +5670,14 @@
   @override
   void toTextInternal(AstPrinter printer) {
     printer.writeExpression(expression, minimumPrecedence: precedence);
-    if (isNot) {
-      printer.write(' != null');
-    } else {
-      printer.write(' == null');
-    }
+    printer.write(' == null');
   }
 }
 
-/// A test of equality, that is `e1 == e2` or `e1 != e2`.
+/// A test of equality, that is `e1 == e2`.
 ///
-/// This is generated for code like `e1 == e2` and `e1 != e2` where neither `e1`
-/// nor `e2` is `null`.
+/// This is generated for code like `e1 == e2` where neither `e1` nor `e2` is
+/// `null`.
 class EqualsCall extends Expression {
   Expression left;
   Expression right;
@@ -5639,27 +5697,17 @@
   ///
   FunctionType functionType;
 
-  /// If `true` this is an `e1 != e2` test. Otherwise it is an `e1 == e2` test.
-  final bool isNot;
-
   Reference interfaceTargetReference;
 
   EqualsCall(Expression left, Expression right,
-      {required bool isNot,
-      required FunctionType functionType,
-      required Procedure interfaceTarget})
+      {required FunctionType functionType, required Procedure interfaceTarget})
       : this.byReference(left, right,
-            isNot: isNot,
             functionType: functionType,
             interfaceTargetReference:
                 getNonNullableMemberReferenceGetter(interfaceTarget));
 
   EqualsCall.byReference(this.left, this.right,
-      {required this.isNot,
-      required this.functionType,
-      required this.interfaceTargetReference})
-      // ignore: unnecessary_null_comparison
-      : assert(isNot != null) {
+      {required this.functionType, required this.interfaceTargetReference}) {
     left.parent = this;
     right.parent = this;
   }
@@ -5726,11 +5774,7 @@
   void toTextInternal(AstPrinter printer) {
     int minimumPrecedence = precedence;
     printer.writeExpression(left, minimumPrecedence: minimumPrecedence);
-    if (isNot) {
-      printer.write(' != ');
-    } else {
-      printer.write(' == ');
-    }
+    printer.write(' == ');
     printer.writeExpression(right, minimumPrecedence: minimumPrecedence + 1);
   }
 }
@@ -9820,7 +9864,7 @@
 /// When this occurs as a statement, it must be a direct child of a [Block].
 //
 // DESIGN TODO: Should we remove the 'final' modifier from variables?
-class VariableDeclaration extends Statement {
+class VariableDeclaration extends Statement implements Annotatable {
   /// Offset of the equals sign in the source file it comes from.
   ///
   /// Valid values are from 0 and up, or -1 ([TreeNode.noOffset])
@@ -9832,6 +9876,7 @@
   ///
   /// This defaults to an immutable empty list. Use [addAnnotation] to add
   /// annotations if needed.
+  @override
   List<Expression> annotations = const <Expression>[];
 
   /// For named parameters, this is the name of the parameter. No two named
@@ -10001,6 +10046,7 @@
     annotations = const <Expression>[];
   }
 
+  @override
   void addAnnotation(Expression annotation) {
     if (annotations.isEmpty) {
       annotations = <Expression>[];
@@ -10349,6 +10395,14 @@
   /// `void`, or `bottom`.
   DartType withDeclaredNullability(Nullability declaredNullability);
 
+  /// Creates the type corresponding to this type without null, if possible.
+  ///
+  /// Note that not all types, for instance `dynamic`, have a corresponding
+  /// non-nullable type. For these, the type itself is returned.
+  ///
+  /// This corresponds to the `NonNull` function of the nnbd specification.
+  DartType toNonNull() => computeNonNull(this);
+
   /// Checks if the type is potentially nullable.
   ///
   /// A type is potentially nullable if it's nullable or if its nullability is
@@ -11129,6 +11183,123 @@
   }
 }
 
+class ExtensionType extends DartType {
+  final Reference extensionReference;
+
+  @override
+  final Nullability declaredNullability;
+
+  final List<DartType> typeArguments;
+
+  final DartType onType;
+
+  ExtensionType(Extension extensionNode, Nullability declaredNullability,
+      [List<DartType>? typeArguments])
+      : this.byReference(extensionNode.reference, declaredNullability,
+            typeArguments ?? _defaultTypeArguments(extensionNode));
+
+  ExtensionType.byReference(
+      this.extensionReference, this.declaredNullability, this.typeArguments)
+      // ignore: unnecessary_null_comparison
+      : assert(declaredNullability != null),
+        onType = _computeOnType(extensionReference, typeArguments);
+
+  Extension get extension => extensionReference.asExtension;
+
+  @override
+  Nullability get nullability {
+    return uniteNullabilities(
+        declaredNullability, extension.onType.nullability);
+  }
+
+  static List<DartType> _defaultTypeArguments(Extension extensionNode) {
+    if (extensionNode.typeParameters.length == 0) {
+      // Avoid allocating a list in this very common case.
+      return const <DartType>[];
+    } else {
+      return new List<DartType>.filled(
+          extensionNode.typeParameters.length, const DynamicType());
+    }
+  }
+
+  static DartType _computeOnType(
+      Reference extensionName, List<DartType> typeArguments) {
+    Extension extensionNode = extensionName.asExtension;
+    if (extensionNode.typeParameters.isEmpty) {
+      return extensionNode.onType;
+    } else {
+      assert(extensionNode.typeParameters.length == typeArguments.length);
+      return Substitution.fromPairs(extensionNode.typeParameters, typeArguments)
+          .substituteType(extensionNode.onType);
+    }
+  }
+
+  @override
+  R accept<R>(DartTypeVisitor<R> v) {
+    return v.visitExtensionType(this);
+  }
+
+  @override
+  R accept1<R, A>(DartTypeVisitor1<R, A> v, A arg) {
+    return v.visitExtensionType(this, arg);
+  }
+
+  @override
+  void visitChildren(Visitor v) {
+    extension.acceptReference(v);
+    visitList(typeArguments, v);
+  }
+
+  @override
+  bool equals(Object other, Assumptions? assumptions) {
+    if (identical(this, other)) return true;
+    if (other is ExtensionType) {
+      if (nullability != other.nullability) return false;
+      if (extensionReference != other.extensionReference) return false;
+      if (typeArguments.length != other.typeArguments.length) return false;
+      for (int i = 0; i < typeArguments.length; ++i) {
+        if (!typeArguments[i].equals(other.typeArguments[i], assumptions)) {
+          return false;
+        }
+      }
+      return true;
+    } else {
+      return false;
+    }
+  }
+
+  @override
+  int get hashCode {
+    int hash = 0x3fffffff & extensionReference.hashCode;
+    for (int i = 0; i < typeArguments.length; ++i) {
+      hash = 0x3fffffff & (hash * 31 + (hash ^ typeArguments[i].hashCode));
+    }
+    int nullabilityHash = (0x33333333 >> nullability.index) ^ 0x33333333;
+    hash = 0x3fffffff & (hash * 31 + (hash ^ nullabilityHash));
+    return hash;
+  }
+
+  @override
+  ExtensionType withDeclaredNullability(Nullability declaredNullability) {
+    return declaredNullability == this.declaredNullability
+        ? this
+        : new ExtensionType.byReference(
+            extensionReference, declaredNullability, typeArguments);
+  }
+
+  @override
+  String toString() {
+    return "ExtensionType(${toStringInternal()})";
+  }
+
+  @override
+  void toTextInternal(AstPrinter printer) {
+    printer.writeExtensionName(extensionReference);
+    printer.writeTypeArguments(typeArguments);
+    printer.write(nullabilityToString(declaredNullability));
+  }
+}
+
 /// A named parameter in [FunctionType].
 class NamedType extends Node implements Comparable<NamedType> {
   // Flag used for serialization if [isRequired].
@@ -11415,9 +11586,6 @@
     if (declaredNullability == this.declaredNullability) {
       return this;
     }
-    // TODO(dmitryas): Consider removing the assert.
-    assert(promotedBound == null,
-        "Can't change the nullability attribute of an intersection type.");
     return new TypeParameterType(parameter, declaredNullability, promotedBound);
   }
 
@@ -11769,13 +11937,14 @@
 /// Type parameters declared by a [FunctionType] are orphans and have a `null`
 /// parent pointer.  [TypeParameter] objects should not be shared between
 /// different [FunctionType] objects.
-class TypeParameter extends TreeNode {
+class TypeParameter extends TreeNode implements Annotatable {
   int flags = 0;
 
   /// List of metadata annotations on the type parameter.
   ///
   /// This defaults to an immutable empty list. Use [addAnnotation] to add
   /// annotations if needed.
+  @override
   List<Expression> annotations = const <Expression>[];
 
   String? name; // Cosmetic name.
@@ -11830,6 +11999,7 @@
         : (flags & ~FlagGenericCovariantImpl);
   }
 
+  @override
   void addAnnotation(Expression annotation) {
     if (annotations.isEmpty) {
       annotations = <Expression>[];
@@ -12999,15 +13169,12 @@
 
 /// Returns the canonical name of [member], or throws an exception if the
 /// member has not been assigned a canonical name yet.
-///
-/// Returns `null` if the member is `null`.
-CanonicalName? getCanonicalNameOfMemberGetter(Member? member) {
-  if (member == null) return null;
+CanonicalName getCanonicalNameOfMemberGetter(Member member) {
   CanonicalName? canonicalName;
   if (member is Field) {
-    canonicalName = member.getterCanonicalName;
+    canonicalName = member.getterReference.canonicalName;
   } else {
-    canonicalName = member.canonicalName;
+    canonicalName = member.reference.canonicalName;
   }
   if (canonicalName == null) {
     throw '$member has no canonical name';
@@ -13017,15 +13184,12 @@
 
 /// Returns the canonical name of [member], or throws an exception if the
 /// member has not been assigned a canonical name yet.
-///
-/// Returns `null` if the member is `null`.
-CanonicalName? getCanonicalNameOfMemberSetter(Member? member) {
-  if (member == null) return null;
+CanonicalName getCanonicalNameOfMemberSetter(Member member) {
   CanonicalName? canonicalName;
   if (member is Field) {
-    canonicalName = member.setterCanonicalName;
+    canonicalName = member.setterReference!.canonicalName;
   } else {
-    canonicalName = member.canonicalName;
+    canonicalName = member.reference.canonicalName;
   }
   if (canonicalName == null) {
     throw '$member has no canonical name';
@@ -13035,38 +13199,29 @@
 
 /// Returns the canonical name of [class_], or throws an exception if the
 /// class has not been assigned a canonical name yet.
-///
-/// Returns `null` if the class is `null`.
-CanonicalName? getCanonicalNameOfClass(Class? class_) {
-  if (class_ == null) return null;
-  if (class_.canonicalName == null) {
+CanonicalName getCanonicalNameOfClass(Class class_) {
+  if (class_.reference.canonicalName == null) {
     throw '$class_ has no canonical name';
   }
-  return class_.canonicalName;
+  return class_.reference.canonicalName!;
 }
 
 /// Returns the canonical name of [extension], or throws an exception if the
 /// class has not been assigned a canonical name yet.
-///
-/// Returns `null` if the extension is `null`.
-CanonicalName? getCanonicalNameOfExtension(Extension? extension) {
-  if (extension == null) return null;
-  if (extension.canonicalName == null) {
+CanonicalName getCanonicalNameOfExtension(Extension extension) {
+  if (extension.reference.canonicalName == null) {
     throw '$extension has no canonical name';
   }
-  return extension.canonicalName;
+  return extension.reference.canonicalName!;
 }
 
 /// Returns the canonical name of [library], or throws an exception if the
 /// library has not been assigned a canonical name yet.
-///
-/// Returns `null` if the library is `null`.
-CanonicalName? getCanonicalNameOfLibrary(Library? library) {
-  if (library == null) return null;
-  if (library.canonicalName == null) {
+CanonicalName getCanonicalNameOfLibrary(Library library) {
+  if (library.reference.canonicalName == null) {
     throw '$library has no canonical name';
   }
-  return library.canonicalName;
+  return library.reference.canonicalName!;
 }
 
 /// Murmur-inspired hashing, with a fall-back to Jenkins-inspired hashing when
@@ -13202,14 +13357,11 @@
 
 /// Returns the canonical name of [typedef_], or throws an exception if the
 /// typedef has not been assigned a canonical name yet.
-///
-/// Returns `null` if the typedef is `null`.
-CanonicalName? getCanonicalNameOfTypedef(Typedef? typedef_) {
-  if (typedef_ == null) return null;
-  if (typedef_.canonicalName == null) {
+CanonicalName getCanonicalNameOfTypedef(Typedef typedef_) {
+  if (typedef_.reference.canonicalName == null) {
     throw '$typedef_ has no canonical name';
   }
-  return typedef_.canonicalName;
+  return typedef_.reference.canonicalName!;
 }
 
 /// Annotation describing information which is not part of Dart semantics; in
diff --git a/pkg/kernel/lib/binary/ast_from_binary.dart b/pkg/kernel/lib/binary/ast_from_binary.dart
index 7da0618..2172314 100644
--- a/pkg/kernel/lib/binary/ast_from_binary.dart
+++ b/pkg/kernel/lib/binary/ast_from_binary.dart
@@ -60,20 +60,6 @@
   String toString() => "CompilationModeError[$message]";
 }
 
-class CanonicalNameError {
-  final String message;
-
-  CanonicalNameError(this.message);
-
-  String toString() => 'CanonicalNameError: $message';
-}
-
-class CanonicalNameSdkError extends CanonicalNameError {
-  CanonicalNameSdkError(String message) : super(message);
-
-  String toString() => 'CanonicalNameSdkError: $message';
-}
-
 class _ComponentIndex {
   static const int numberOfFixedFields = 10;
 
@@ -441,8 +427,7 @@
     final int fieldValueCount = readUInt30();
     final Map<Reference, Constant> fieldValues = <Reference, Constant>{};
     for (int i = 0; i < fieldValueCount; i++) {
-      final Reference fieldRef =
-          readNonNullCanonicalNameReference().getReference();
+      final Reference fieldRef = readNonNullCanonicalNameReference().reference;
       final Constant constant = readConstantReference();
       fieldValues[fieldRef] = constant;
     }
@@ -457,8 +442,7 @@
   }
 
   Constant _readTearOffConstant() {
-    final Reference reference =
-        readNonNullCanonicalNameReference().getReference();
+    final Reference reference = readNonNullCanonicalNameReference().reference;
     return new TearOffConstant.byReference(reference);
   }
 
@@ -656,7 +640,7 @@
       }
 
       if (checkCanonicalNames) {
-        _checkCanonicalNameChildren(component.root);
+        component.root.checkCanonicalNameChildren();
       }
       return views;
     });
@@ -706,63 +690,10 @@
     }
 
     if (checkCanonicalNames) {
-      _checkCanonicalNameChildren(component.root);
+      component.root.checkCanonicalNameChildren();
     }
   }
 
-  void _checkCanonicalNameChildren(CanonicalName parent) {
-    Iterable<CanonicalName>? parentChildren = parent.childrenOrNull;
-    if (parentChildren != null) {
-      for (CanonicalName child in parentChildren) {
-        if (child.name != '@methods' &&
-            child.name != '@typedefs' &&
-            child.name != '@fields' &&
-            child.name != '@=fields' &&
-            child.name != '@getters' &&
-            child.name != '@setters' &&
-            child.name != '@factories' &&
-            child.name != '@constructors') {
-          bool checkReferenceNode = true;
-          if (child.reference == null) {
-            // OK for "if private: URI of library" part of "Qualified name"...
-            // TODO(johnniwinther): This wrongfully skips checking of variable
-            // synthesized by the VM transformations. The kind of canonical
-            // name types maybe should be directly available.
-            if (parent.parent != null && child.name.contains(':')) {
-              // OK then.
-              checkReferenceNode = false;
-            } else {
-              throw buildCanonicalNameError(
-                  "Null reference (${child.name}) ($child).", child);
-            }
-          }
-          if (checkReferenceNode) {
-            if (child.reference!.canonicalName != child) {
-              throw new CanonicalNameError(
-                  "Canonical name and reference doesn't agree.");
-            }
-            if (child.reference!.node == null) {
-              throw buildCanonicalNameError(
-                  "Reference is null (${child.name}) ($child).", child);
-            }
-          }
-        }
-        _checkCanonicalNameChildren(child);
-      }
-    }
-  }
-
-  CanonicalNameError buildCanonicalNameError(
-      String message, CanonicalName problemNode) {
-    // Special-case missing sdk entries as that is probably a change to the
-    // platform - that's something we might want to react differently to.
-    String libraryUri = problemNode.nonRootTop?.name ?? "";
-    if (libraryUri.startsWith("dart:")) {
-      return new CanonicalNameSdkError(message);
-    }
-    return new CanonicalNameError(message);
-  }
-
   _ComponentIndex _readComponentIndex(int componentFileSize) {
     int savedByteIndex = _byteOffset;
 
@@ -1059,12 +990,12 @@
 
   Reference? readNullableLibraryReference() {
     CanonicalName? canonicalName = readNullableCanonicalNameReference();
-    return canonicalName?.getReference();
+    return canonicalName?.reference;
   }
 
   Reference readNonNullLibraryReference() {
     CanonicalName? canonicalName = readNullableCanonicalNameReference();
-    if (canonicalName != null) return canonicalName.getReference();
+    if (canonicalName != null) return canonicalName.reference;
     throw 'Expected a library reference to be valid but was `null`.';
   }
 
@@ -1075,7 +1006,7 @@
 
   Reference? readNullableClassReference() {
     CanonicalName? name = readNullableCanonicalNameReference();
-    return name?.getReference();
+    return name?.reference;
   }
 
   Reference readNonNullClassReference() {
@@ -1083,7 +1014,7 @@
     if (name == null) {
       throw 'Expected a class reference to be valid but was `null`.';
     }
-    return name.getReference();
+    return name.reference;
   }
 
   void skipMemberReference() {
@@ -1092,7 +1023,7 @@
 
   Reference? readNullableMemberReference() {
     CanonicalName? name = readNullableCanonicalNameReference();
-    return name?.getReference();
+    return name?.reference;
   }
 
   Reference readNonNullMemberReference() {
@@ -1100,7 +1031,7 @@
     if (name == null) {
       throw 'Expected a member reference to be valid but was `null`.';
     }
-    return name.getReference();
+    return name.reference;
   }
 
   Reference? readNullableInstanceMemberReference() {
@@ -1116,15 +1047,15 @@
   }
 
   Reference? getNullableMemberReferenceFromInt(int index) {
-    return getNullableCanonicalNameReferenceFromInt(index)?.getReference();
+    return getNullableCanonicalNameReferenceFromInt(index)?.reference;
   }
 
   Reference? readNullableTypedefReference() {
-    return readNullableCanonicalNameReference()?.getReference();
+    return readNullableCanonicalNameReference()?.reference;
   }
 
   Reference readNonNullTypedefReference() {
-    return readNonNullCanonicalNameReference().getReference();
+    return readNonNullCanonicalNameReference().reference;
   }
 
   Name readName() {
@@ -1177,7 +1108,7 @@
     int languageVersionMinor = readUInt30();
 
     CanonicalName canonicalName = readNonNullCanonicalNameReference();
-    Reference reference = canonicalName.getReference();
+    Reference reference = canonicalName.reference;
     Library? library = reference.node as Library?;
     if (alwaysCreateNewNamedNodes) {
       library = null;
@@ -1270,7 +1201,7 @@
       library.additionalExports.clear();
       for (int i = 0; i < numExportedReference; i++) {
         CanonicalName exportedName = readNonNullCanonicalNameReference();
-        Reference reference = exportedName.getReference();
+        Reference reference = exportedName.reference;
         library.additionalExports.add(reference);
       }
     }
@@ -1309,7 +1240,7 @@
 
   Typedef readTypedef() {
     CanonicalName canonicalName = readNonNullCanonicalNameReference();
-    Reference reference = canonicalName.getReference();
+    Reference reference = canonicalName.reference;
     Typedef? node = reference.node as Typedef?;
     if (alwaysCreateNewNamedNodes) {
       node = null;
@@ -1357,7 +1288,7 @@
     _byteOffset = savedByteOffset;
 
     CanonicalName canonicalName = readNonNullCanonicalNameReference();
-    Reference reference = canonicalName.getReference();
+    Reference reference = canonicalName.reference;
     Class? node = reference.node as Class?;
     if (alwaysCreateNewNamedNodes) {
       node = null;
@@ -1413,7 +1344,7 @@
     assert(tag == Tag.Extension);
 
     CanonicalName canonicalName = readNonNullCanonicalNameReference();
-    Reference reference = canonicalName.getReference();
+    Reference reference = canonicalName.reference;
     Extension? node = reference.node as Extension?;
     if (alwaysCreateNewNamedNodes) {
       node = null;
@@ -1428,6 +1359,8 @@
       return true;
     }());
 
+    node.annotations = readAnnotationList(node);
+
     Uri? fileUri = readUriReference();
     node.fileOffset = readOffset();
 
@@ -1449,7 +1382,7 @@
       node.members[i] = new ExtensionMemberDescriptor(
           name: name,
           kind: ExtensionMemberKind.values[kind],
-          member: canonicalName.getReference())
+          member: canonicalName.reference)
         ..flags = flags;
     }
     return node;
@@ -1503,9 +1436,9 @@
     int tag = readByte();
     assert(tag == Tag.Field);
     CanonicalName getterCanonicalName = readNonNullCanonicalNameReference();
-    Reference getterReference = getterCanonicalName.getReference();
+    Reference getterReference = getterCanonicalName.reference;
     CanonicalName? setterCanonicalName = readNullableCanonicalNameReference();
-    Reference? setterReference = setterCanonicalName?.getReference();
+    Reference? setterReference = setterCanonicalName?.reference;
     Field? node = getterReference.node as Field?;
     if (alwaysCreateNewNamedNodes) {
       node = null;
@@ -1549,7 +1482,7 @@
     int tag = readByte();
     assert(tag == Tag.Constructor);
     CanonicalName canonicalName = readNonNullCanonicalNameReference();
-    Reference reference = canonicalName.getReference();
+    Reference reference = canonicalName.reference;
     Constructor? node = reference.node as Constructor?;
     if (alwaysCreateNewNamedNodes) {
       node = null;
@@ -1591,7 +1524,7 @@
     int tag = readByte();
     assert(tag == Tag.Procedure);
     CanonicalName canonicalName = readNonNullCanonicalNameReference();
-    Reference reference = canonicalName.getReference();
+    Reference reference = canonicalName.reference;
     Procedure? node = reference.node as Procedure?;
     if (alwaysCreateNewNamedNodes) {
       node = null;
@@ -1650,7 +1583,7 @@
     int tag = readByte();
     assert(tag == Tag.RedirectingFactoryConstructor);
     CanonicalName canonicalName = readNonNullCanonicalNameReference();
-    Reference reference = canonicalName.getReference();
+    Reference reference = canonicalName.reference;
     RedirectingFactoryConstructor? node =
         reference.node as RedirectingFactoryConstructor?;
     if (alwaysCreateNewNamedNodes) {
@@ -1936,6 +1869,8 @@
         return _readMethodInvocation();
       case Tag.InstanceInvocation:
         return _readInstanceInvocation();
+      case Tag.InstanceGetterInvocation:
+        return _readInstanceGetterInvocation();
       case Tag.DynamicInvocation:
         return _readDynamicInvocation();
       case Tag.FunctionInvocation:
@@ -2193,6 +2128,26 @@
       ..flags = flags;
   }
 
+  Expression _readInstanceGetterInvocation() {
+    InstanceAccessKind kind = InstanceAccessKind.values[readByte()];
+    int flags = readByte();
+    int offset = readOffset();
+    Expression receiver = readExpression();
+    Name name = readName();
+    Arguments arguments = readArguments();
+    DartType functionType = readDartType();
+    // `const DynamicType()` is used to encode a missing function type.
+    assert(functionType is FunctionType || functionType is DynamicType,
+        "Unexpected function type $functionType for InstanceGetterInvocation");
+    Reference interfaceTargetReference = readNonNullInstanceMemberReference();
+    return new InstanceGetterInvocation.byReference(
+        kind, receiver, name, arguments,
+        functionType: functionType is FunctionType ? functionType : null,
+        interfaceTargetReference: interfaceTargetReference)
+      ..fileOffset = offset
+      ..flags = flags;
+  }
+
   Expression _readDynamicInvocation() {
     DynamicAccessKind kind = DynamicAccessKind.values[readByte()];
     int offset = readOffset();
@@ -2223,21 +2178,20 @@
   Expression _readLocalFunctionInvocation() {
     int offset = readOffset();
     readUInt30(); // offset of the variable declaration in the binary.
-    return new LocalFunctionInvocation(readVariableReference(), readArguments(),
+    VariableDeclaration variable = readVariableReference();
+    return new LocalFunctionInvocation(variable, readArguments(),
         functionType: readDartType() as FunctionType)
       ..fileOffset = offset;
   }
 
   Expression _readEqualsNull() {
     int offset = readOffset();
-    return new EqualsNull(readExpression(), isNot: readByte() == 1)
-      ..fileOffset = offset;
+    return new EqualsNull(readExpression())..fileOffset = offset;
   }
 
   Expression _readEqualsCall() {
     int offset = readOffset();
     return new EqualsCall.byReference(readExpression(), readExpression(),
-        isNot: readByte() == 1,
         functionType: readDartType() as FunctionType,
         interfaceTargetReference: readNonNullInstanceMemberReference())
       ..fileOffset = offset;
@@ -2343,8 +2297,7 @@
     int fieldValueCount = readUInt30();
     Map<Reference, Expression> fieldValues = <Reference, Expression>{};
     for (int i = 0; i < fieldValueCount; i++) {
-      final Reference fieldRef =
-          readNonNullCanonicalNameReference().getReference();
+      final Reference fieldRef = readNonNullCanonicalNameReference().reference;
       final Expression value = readExpression();
       fieldValues[fieldRef] = value;
     }
@@ -2768,8 +2721,8 @@
     int offset = readOffset();
     VariableDeclaration variable = readVariableDeclaration();
     variableStack.add(variable); // Will be popped by the enclosing scope.
-    FunctionNode function = readFunctionNode();
-    return new FunctionDeclaration(variable, function)..fileOffset = offset;
+    return new FunctionDeclaration(variable, readFunctionNode())
+      ..fileOffset = offset;
   }
 
   void _readSwitchCaseInto(SwitchCase caseNode) {
diff --git a/pkg/kernel/lib/binary/ast_to_binary.dart b/pkg/kernel/lib/binary/ast_to_binary.dart
index f9409b0..33f0f3e 100644
--- a/pkg/kernel/lib/binary/ast_to_binary.dart
+++ b/pkg/kernel/lib/binary/ast_to_binary.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
-
 library kernel.ast_to_binary;
 
 import 'dart:convert';
@@ -20,34 +18,34 @@
 /// A [BinaryPrinter] can be used to write one file and must then be
 /// discarded.
 class BinaryPrinter implements Visitor<void>, BinarySink {
-  VariableIndexer _variableIndexer;
-  LabelIndexer _labelIndexer;
-  SwitchCaseIndexer _switchCaseIndexer;
-  final TypeParameterIndexer _typeParameterIndexer = new TypeParameterIndexer();
+  VariableIndexer? _variableIndexer;
+  LabelIndexer? _labelIndexer;
+  SwitchCaseIndexer? _switchCaseIndexer;
+  TypeParameterIndexer _typeParameterIndexer = new TypeParameterIndexer();
   final StringIndexer stringIndexer;
-  ConstantIndexer _constantIndexer;
+  late ConstantIndexer _constantIndexer;
   final UriIndexer _sourceUriIndexer = new UriIndexer();
   bool _currentlyInNonimplementation = false;
   final List<bool> _sourcesFromRealImplementation = <bool>[];
   final List<bool> _sourcesUsedInLibrary = <bool>[];
   Map<LibraryDependency, int> _libraryDependencyIndex =
       <LibraryDependency, int>{};
-  NonNullableByDefaultCompiledMode compilationMode;
+  NonNullableByDefaultCompiledMode? compilationMode;
 
-  List<_MetadataSubsection> _metadataSubsections;
+  List<_MetadataSubsection>? _metadataSubsections;
 
   final BufferedSink _mainSink;
   final BufferedSink _metadataSink;
   final BytesSink _constantsBytesSink;
-  BufferedSink _constantsSink;
-  BufferedSink _sink;
+  late BufferedSink _constantsSink;
+  late BufferedSink _sink;
   final bool includeSources;
   final bool includeOffsets;
-  final LibraryFilter libraryFilter;
+  final LibraryFilter? libraryFilter;
 
-  List<int> libraryOffsets;
-  List<int> classOffsets;
-  List<int> procedureOffsets;
+  late List<int> libraryOffsets;
+  late List<int> classOffsets;
+  late List<int> procedureOffsets;
   int _binaryOffsetForSourceTable = -1;
   int _binaryOffsetForLinkTable = -1;
   int _binaryOffsetForMetadataPayloads = -1;
@@ -55,10 +53,10 @@
   int _binaryOffsetForStringTable = -1;
   int _binaryOffsetForConstantTable = -1;
 
-  List<CanonicalName> _canonicalNameList;
+  late List<CanonicalName> _canonicalNameList;
   Set<CanonicalName> _knownCanonicalNameNonRootTops = new Set<CanonicalName>();
 
-  Library _currentLibrary;
+  Library? _currentLibrary;
 
   /// Create a printer that writes to the given [sink].
   ///
@@ -66,7 +64,7 @@
   /// one.
   BinaryPrinter(Sink<List<int>> sink,
       {this.libraryFilter,
-      StringIndexer stringIndexer,
+      StringIndexer? stringIndexer,
       this.includeSources = true,
       this.includeOffsets = true})
       : _mainSink = new BufferedSink(sink),
@@ -83,10 +81,9 @@
   }
 
   int _getVariableIndex(VariableDeclaration variable) {
-    _variableIndexer ??= new VariableIndexer();
-    int index = _variableIndexer[variable];
+    int? index = (_variableIndexer ??= new VariableIndexer())[variable];
     assert(index != null, "No index found for ${variable}");
-    return index;
+    return index!;
   }
 
   void writeByte(int byte) {
@@ -132,7 +129,7 @@
     final List<Uint8List> data = <Uint8List>[];
     int totalLength = 0;
     const int minLength = 1 << 16;
-    Uint8List buffer;
+    Uint8List? buffer;
     int index = 0;
 
     // Write the end offsets.
@@ -194,6 +191,8 @@
   }
 
   int writeConstantTableEntry(Constant constant) {
+    TypeParameterIndexer oldTypeParameterIndexer = _typeParameterIndexer;
+    _typeParameterIndexer = new TypeParameterIndexer();
     BufferedSink oldSink = _sink;
     _sink = _constantsSink;
     int initialOffset = _sink.offset;
@@ -241,7 +240,7 @@
       constant.typeArguments.forEach(writeDartType);
       writeUInt30(constant.fieldValues.length);
       constant.fieldValues.forEach((Reference fieldRef, Constant value) {
-        writeNonNullCanonicalNameReference(fieldRef.canonicalName);
+        writeNonNullCanonicalNameReference(fieldRef.canonicalName!);
         writeConstantReference(value);
       });
     } else if (constant is PartialInstantiationConstant) {
@@ -254,7 +253,8 @@
       }
     } else if (constant is TearOffConstant) {
       writeByte(ConstantTag.TearOffConstant);
-      writeNonNullCanonicalNameReference(constant.procedure.canonicalName);
+      writeNonNullCanonicalNameReference(
+          constant.procedure.reference.canonicalName!);
     } else if (constant is TypeLiteralConstant) {
       writeByte(ConstantTag.TypeLiteralConstant);
       writeDartType(constant.type);
@@ -265,6 +265,7 @@
       throw new ArgumentError('Unsupported constant $constant');
     }
     _sink = oldSink;
+    _typeParameterIndexer = oldTypeParameterIndexer;
     return _constantsSink.offset - initialOffset;
   }
 
@@ -273,7 +274,7 @@
   }
 
   // Returns the new active file uri.
-  void writeUriReference(Uri uri) {
+  void writeUriReference(Uri? uri) {
     final int index = _sourceUriIndexer.put(uri);
     writeUInt30(index);
     if (!_currentlyInNonimplementation) {
@@ -478,7 +479,7 @@
     node.accept(this);
   }
 
-  void writeOptionalNode(Node node) {
+  void writeOptionalNode(Node? node) {
     if (node == null) {
       writeByte(Tag.Nothing);
     } else {
@@ -487,7 +488,7 @@
     }
   }
 
-  void writeOptionalFunctionNode(FunctionNode node) {
+  void writeOptionalFunctionNode(FunctionNode? node) {
     if (node == null) {
       writeByte(Tag.Nothing);
     } else {
@@ -505,9 +506,9 @@
     _canonicalNameList = <CanonicalName>[];
     for (int i = 0; i < component.libraries.length; ++i) {
       Library library = component.libraries[i];
-      if (libraryFilter == null || libraryFilter(library)) {
-        _indexLinkTableInternal(library.canonicalName);
-        _knownCanonicalNameNonRootTops.add(library.canonicalName);
+      if (libraryFilter == null || libraryFilter!(library)) {
+        _indexLinkTableInternal(library.reference.canonicalName!);
+        _knownCanonicalNameNonRootTops.add(library.reference.canonicalName!);
       }
     }
   }
@@ -515,7 +516,7 @@
   void _indexLinkTableInternal(CanonicalName node) {
     node.index = _canonicalNameList.length;
     _canonicalNameList.add(node);
-    Iterable<CanonicalName> children = node.childrenOrNull;
+    Iterable<CanonicalName>? children = node.childrenOrNull;
     if (children != null) {
       for (CanonicalName child in children) {
         _indexLinkTableInternal(child);
@@ -527,14 +528,15 @@
   void computeCanonicalNames(Component component) {
     for (int i = 0; i < component.libraries.length; ++i) {
       Library library = component.libraries[i];
-      if (libraryFilter == null || libraryFilter(library)) {
+      if (libraryFilter == null || libraryFilter!(library)) {
         component.computeCanonicalNamesForLibrary(library);
       }
     }
   }
 
   void writeCanonicalNameEntry(CanonicalName node) {
-    CanonicalName parent = node.parent;
+    assert(node.isConsistent, node.getInconsistency());
+    CanonicalName parent = node.parent!;
     if (parent.isRoot) {
       writeUInt30(0);
     } else {
@@ -558,9 +560,9 @@
         _writeNodeMetadataImpl(component, componentOffset);
       }
       libraryOffsets = <int>[];
-      CanonicalName main = getCanonicalNameOfMemberGetter(component.mainMethod);
-      if (main != null) {
-        checkCanonicalName(main);
+      Procedure? mainMethod = component.mainMethod;
+      if (mainMethod != null) {
+        checkCanonicalName(getCanonicalNameOfMemberGetter(mainMethod));
       }
       writeLibraries(component);
       writeUriToSource(component.uriToSource);
@@ -573,7 +575,7 @@
         List<Library> librariesNew = <Library>[];
         for (int i = 0; i < libraries.length; i++) {
           Library library = libraries[i];
-          if (libraryFilter(library)) librariesNew.add(library);
+          if (libraryFilter!(library)) librariesNew.add(library);
         }
         libraries = librariesNew;
       }
@@ -583,7 +585,7 @@
     });
   }
 
-  void writeListOfStrings(List<String> strings) {
+  void writeListOfStrings(List<String>? strings) {
     writeUInt30(strings?.length ?? 0);
     if (strings != null) {
       for (int i = 0; i < strings.length; i++) {
@@ -613,9 +615,9 @@
   }
 
   void _writeNodeMetadataImpl(Node node, int nodeOffset) {
-    for (_MetadataSubsection subsection in _metadataSubsections) {
-      final MetadataRepository<Object> repository = subsection.repository;
-      final Object value = repository.mapping[node];
+    for (_MetadataSubsection subsection in _metadataSubsections!) {
+      final MetadataRepository<Object?> repository = subsection.repository;
+      final Object? value = repository.mapping[node];
       if (value == null) {
         continue;
       }
@@ -641,7 +643,7 @@
 
   @override
   void enterScope(
-      {List<TypeParameter> typeParameters,
+      {List<TypeParameter>? typeParameters,
       bool memberScope: false,
       bool variableScope: false}) {
     if (typeParameters != null) {
@@ -652,17 +654,17 @@
     }
     if (variableScope) {
       _variableIndexer ??= new VariableIndexer();
-      _variableIndexer.pushScope();
+      _variableIndexer!.pushScope();
     }
   }
 
   @override
   void leaveScope(
-      {List<TypeParameter> typeParameters,
+      {List<TypeParameter>? typeParameters,
       bool memberScope: false,
       bool variableScope: false}) {
     if (variableScope) {
-      _variableIndexer.popScope();
+      _variableIndexer!.popScope();
     }
     if (memberScope) {
       _variableIndexer = null;
@@ -687,7 +689,7 @@
     _metadataSubsections
         ?.removeWhere((_MetadataSubsection s) => s.metadataMapping.isEmpty);
 
-    if (_metadataSubsections == null || _metadataSubsections.isEmpty) {
+    if (_metadataSubsections == null || _metadataSubsections!.isEmpty) {
       _binaryOffsetForMetadataMappings = getBufferOffset();
       writeUInt32(0); // Empty section.
       return;
@@ -699,7 +701,7 @@
 
     // RList<MetadataMapping> metadataMappings
     _binaryOffsetForMetadataMappings = getBufferOffset();
-    for (_MetadataSubsection subsection in _metadataSubsections) {
+    for (_MetadataSubsection subsection in _metadataSubsections!) {
       // UInt32 tag
       writeUInt32(stringIndexer.put(subsection.repository.tag));
 
@@ -711,14 +713,14 @@
       }
       writeUInt32(mappingLength ~/ 2);
     }
-    writeUInt32(_metadataSubsections.length);
+    writeUInt32(_metadataSubsections!.length);
   }
 
   /// Write all of some of the libraries of the [component].
   void writeLibraries(Component component) {
     for (int i = 0; i < component.libraries.length; ++i) {
       Library library = component.libraries[i];
-      if (libraryFilter == null || libraryFilter(library)) {
+      if (libraryFilter == null || libraryFilter!(library)) {
         writeLibraryNode(library);
       }
     }
@@ -758,10 +760,11 @@
     assert(_binaryOffsetForConstantTable >= 0);
     writeUInt32(_binaryOffsetForConstantTable);
 
-    CanonicalName main = getCanonicalNameOfMemberGetter(component.mainMethod);
-    if (main == null) {
+    Procedure? mainMethod = component.mainMethod;
+    if (mainMethod == null) {
       writeUInt32(0);
     } else {
+      CanonicalName main = getCanonicalNameOfMemberGetter(mainMethod);
       writeUInt32(main.index + 1);
     }
     assert(component.modeRaw != null, "Component mode not set.");
@@ -782,14 +785,17 @@
 
     int length = _sourceUriIndexer.index.length;
     writeUInt32(length);
-    List<int> index = new List<int>.filled(length, null);
+    List<int> index = new List<int>.filled(
+        length,
+        // Dummy element value.
+        -1);
 
     // Write data.
     int i = 0;
     Uint8List buffer = new Uint8List(1 << 16);
-    for (Uri uri in _sourceUriIndexer.index.keys) {
+    for (Uri? uri in _sourceUriIndexer.index.keys) {
       index[i] = getBufferOffset();
-      Source source = uriToSource[uri];
+      Source? source = uriToSource[uri];
       if (source == null ||
           !(includeSources &&
               _sourcesFromRealImplementation.length > i &&
@@ -804,7 +810,7 @@
       writeByteList(source.source);
 
       {
-        List<int> lineStarts = source.lineStarts;
+        List<int> lineStarts = source.lineStarts!;
         writeUInt30(lineStarts.length);
         int previousLineStart = 0;
         for (int j = 0; j < lineStarts.length; ++j) {
@@ -819,7 +825,7 @@
       outputStringViaBuffer(importUriAsString, buffer);
 
       {
-        Set<Reference> coverage = source.constantCoverageConstructors;
+        Set<Reference>? coverage = source.constantCoverageConstructors;
         if (coverage == null || coverage.isEmpty) {
           writeUInt30(0);
         } else {
@@ -853,7 +859,7 @@
   }
 
   void writeLibraryDependencyReference(LibraryDependency node) {
-    int index = _libraryDependencyIndex[node];
+    int? index = _libraryDependencyIndex[node];
     if (index == null) {
       throw new ArgumentError(
           'Reference to library dependency $node out of scope');
@@ -861,17 +867,18 @@
     writeUInt30(index);
   }
 
-  void writeNullAllowedInstanceMemberReference(Reference reference) {
+  void writeNullAllowedInstanceMemberReference(Reference? reference) {
     writeNullAllowedReference(reference);
     writeNullAllowedReference(
-        getMemberReferenceGetter(reference?.asMember?.memberSignatureOrigin));
+        getMemberReferenceGetter(reference?.asMember.memberSignatureOrigin));
   }
 
-  void writeNullAllowedReference(Reference reference) {
+  void writeNullAllowedReference(Reference? reference) {
     if (reference == null) {
       writeUInt30(0);
     } else {
-      CanonicalName name = reference.canonicalName;
+      assert(reference.isConsistent, reference.getInconsistency());
+      CanonicalName? name = reference.canonicalName;
       if (name == null) {
         throw new ArgumentError('Missing canonical name for $reference');
       }
@@ -883,14 +890,16 @@
   void writeNonNullInstanceMemberReference(Reference reference) {
     writeNonNullReference(reference);
     writeNullAllowedReference(
-        getMemberReferenceGetter(reference.asMember?.memberSignatureOrigin));
+        getMemberReferenceGetter(reference.asMember.memberSignatureOrigin));
   }
 
   void writeNonNullReference(Reference reference) {
+    // ignore: unnecessary_null_comparison
     if (reference == null) {
       throw new ArgumentError('Got null reference');
     } else {
-      CanonicalName name = reference.canonicalName;
+      assert(reference.isConsistent, reference.getInconsistency());
+      CanonicalName? name = reference.canonicalName;
       if (name == null) {
         throw new ArgumentError('Missing canonical name for $reference');
       }
@@ -901,7 +910,7 @@
 
   void checkCanonicalName(CanonicalName node) {
     if (_knownCanonicalNameNonRootTops.contains(node.nonRootTop)) return;
-    if (node == null || node.isRoot) return;
+    if (node.isRoot) return;
     if (node.index >= 0 && node.index < _canonicalNameList.length) {
       CanonicalName claim = _canonicalNameList[node.index];
       if (node == claim) {
@@ -909,12 +918,12 @@
         return;
       }
     }
-    checkCanonicalName(node.parent);
+    checkCanonicalName(node.parent!);
     node.index = _canonicalNameList.length;
     _canonicalNameList.add(node);
   }
 
-  void writeNullAllowedCanonicalNameReference(CanonicalName name) {
+  void writeNullAllowedCanonicalNameReference(CanonicalName? name) {
     if (name == null) {
       writeUInt30(0);
     } else {
@@ -924,6 +933,7 @@
   }
 
   void writeNonNullCanonicalNameReference(CanonicalName name) {
+    // ignore: unnecessary_null_comparison
     if (name == null) {
       throw new ArgumentError(
           'Expected a canonical name to be valid but was `null`.');
@@ -934,11 +944,11 @@
   }
 
   void writeLibraryReference(Library node, {bool allowNull: false}) {
-    if (node.canonicalName == null && !allowNull) {
+    if (node.reference.canonicalName == null && !allowNull) {
       throw new ArgumentError(
           'Expected a library reference to be valid but was `null`.');
     }
-    writeNullAllowedCanonicalNameReference(node.canonicalName);
+    writeNullAllowedCanonicalNameReference(node.reference.canonicalName);
   }
 
   writeOffset(int offset) {
@@ -953,6 +963,7 @@
   }
 
   void writeClassReference(Class class_) {
+    // ignore: unnecessary_null_comparison
     if (class_ == null) {
       throw new ArgumentError(
           'Expected a class reference to be valid but was `null`.');
@@ -968,7 +979,7 @@
     // TODO: Consider a more compressed format for private names within the
     // enclosing library.
     if (node.isPrivate) {
-      writeLibraryReference(node.library);
+      writeLibraryReference(node.library!);
     }
   }
 
@@ -1111,7 +1122,7 @@
 
     enterScope(typeParameters: node.typeParameters, variableScope: true);
     writeNodeList(node.typeParameters);
-    writeNode(node.type);
+    writeNode(node.type!);
 
     enterScope(typeParameters: node.typeParametersOfFunctionType);
     writeNodeList(node.typeParametersOfFunctionType);
@@ -1142,7 +1153,7 @@
 
     if (node.isAnonymousMixin) _currentlyInNonimplementation = true;
 
-    if (node.canonicalName == null) {
+    if (node.reference.canonicalName == null) {
       throw new ArgumentError('Missing canonical name for $node');
     }
     writeByte(Tag.Class);
@@ -1153,7 +1164,7 @@
     writeOffset(node.fileEndOffset);
 
     writeByte(node.flags);
-    writeStringReference(node.name ?? '');
+    writeStringReference(node.name);
 
     enterScope(memberScope: true);
     writeAnnotationList(node.annotations);
@@ -1185,7 +1196,7 @@
 
   @override
   void visitConstructor(Constructor node) {
-    if (node.canonicalName == null) {
+    if (node.reference.canonicalName == null) {
       throw new ArgumentError('Missing canonical name for $node');
     }
     enterScope(memberScope: true);
@@ -1200,12 +1211,12 @@
     writeName(node.name ?? _emptyName);
 
     writeAnnotationList(node.annotations);
-    assert(node.function.typeParameters.isEmpty);
-    writeFunctionNode(node.function);
+    assert(node.function!.typeParameters.isEmpty);
+    writeFunctionNode(node.function!);
     // Parameters are in scope in the initializers.
     _variableIndexer ??= new VariableIndexer();
-    _variableIndexer.restoreScope(node.function.positionalParameters.length +
-        node.function.namedParameters.length);
+    _variableIndexer!.restoreScope(node.function!.positionalParameters.length +
+        node.function!.namedParameters.length);
     writeNodeList(node.initializers);
 
     leaveScope(memberScope: true);
@@ -1226,9 +1237,24 @@
 
     procedureOffsets.add(getBufferOffset());
 
-    if (node.canonicalName == null) {
+    CanonicalName? canonicalName = node.reference.canonicalName;
+    if (canonicalName == null) {
       throw new ArgumentError('Missing canonical name for $node');
     }
+    String? orphancy = node.reference.getOrphancyDescription(node);
+    if (orphancy != null) {
+      throw new ArgumentError(
+          'Trying to serialize orphaned procedure reference.\n'
+          'Orphaned procedure ${node} (${node.runtimeType}:${node.hashCode})\n'
+          '${orphancy}');
+    }
+    orphancy = canonicalName.getOrphancyDescription(node, node.reference);
+    if (orphancy != null) {
+      throw new ArgumentError(
+          'Trying to serialize orphaned procedure canonical name.\n'
+          'Orphaned procedure ${node} (${node.runtimeType}:${node.hashCode})\n'
+          '${orphancy}');
+    }
 
     final bool currentlyInNonimplementationSaved =
         _currentlyInNonimplementation;
@@ -1255,31 +1281,60 @@
     _currentlyInNonimplementation = currentlyInNonimplementationSaved;
     assert(
         (node.concreteForwardingStubTarget != null) ||
-            !(node.isForwardingStub && node.function.body != null),
+            !(node.isForwardingStub && node.function!.body != null),
         "Invalid forwarding stub $node.");
   }
 
   @override
   void visitField(Field node) {
-    if (node.getterCanonicalName == null) {
+    CanonicalName? getterCanonicalName = node.getterReference.canonicalName;
+    if (getterCanonicalName == null) {
       throw new ArgumentError('Missing canonical name for $node');
     }
-    if (node.hasSetter && node.setterCanonicalName == null) {
-      throw new ArgumentError('Missing canonical name for $node');
+    String? getterOrphancy = node.getterReference.getOrphancyDescription(node);
+    if (getterOrphancy != null) {
+      throw new ArgumentError('Trying to serialize orphaned getter reference.\n'
+          '${getterOrphancy}');
+    }
+    getterOrphancy =
+        getterCanonicalName.getOrphancyDescription(node, node.getterReference);
+    if (getterOrphancy != null) {
+      throw new ArgumentError(
+          'Trying to serialize orphaned getter canonical name.\n'
+          '(${node.runtimeType}:${node.hashCode})\n'
+          '${getterOrphancy}');
+    }
+
+    CanonicalName? setterCanonicalName;
+    if (node.hasSetter) {
+      Reference setterReference = node.setterReference!;
+      setterCanonicalName = setterReference.canonicalName;
+      if (setterCanonicalName == null) {
+        throw new ArgumentError('Missing canonical name for $node');
+      }
+      String? setterOrphancy = setterReference.getOrphancyDescription(node);
+      if (setterOrphancy != null) {
+        throw new ArgumentError(
+            'Trying to serialize orphaned setter reference.\n'
+            '${setterOrphancy}');
+      }
+      setterOrphancy =
+          setterCanonicalName.getOrphancyDescription(node, setterReference);
+      if (setterOrphancy != null) {
+        throw new ArgumentError(
+            'Trying to serialize orphaned setter canonical name.\n'
+            '${setterOrphancy}');
+      }
     }
     enterScope(memberScope: true);
     writeByte(Tag.Field);
-    writeNonNullCanonicalNameReference(getCanonicalNameOfMemberGetter(node));
-    if (node.hasSetter) {
-      writeNonNullCanonicalNameReference(getCanonicalNameOfMemberSetter(node));
-    } else {
-      writeNullAllowedReference(null);
-    }
+    writeNonNullCanonicalNameReference(getterCanonicalName);
+    writeNullAllowedCanonicalNameReference(setterCanonicalName);
     writeUriReference(node.fileUri);
     writeOffset(node.fileOffset);
     writeOffset(node.fileEndOffset);
     writeUInt30(node.flags);
-    writeName(node.name);
+    writeName(node.name!);
     writeAnnotationList(node.annotations);
     writeNode(node.type);
     writeOptionalNode(node.initializer);
@@ -1288,7 +1343,7 @@
 
   @override
   void visitRedirectingFactoryConstructor(RedirectingFactoryConstructor node) {
-    if (node.canonicalName == null) {
+    if (node.reference.canonicalName == null) {
       throw new ArgumentError('Missing canonical name for $node');
     }
     writeByte(Tag.RedirectingFactoryConstructor);
@@ -1301,10 +1356,10 @@
     writeOffset(node.fileOffset);
     writeOffset(node.fileEndOffset);
     writeByte(node.flags);
-    writeName(node.name);
+    writeName(node.name!);
 
     writeAnnotationList(node.annotations);
-    writeNonNullReference(node.targetReference);
+    writeNonNullReference(node.targetReference!);
     writeNodeList(node.typeArguments);
     writeNodeList(node.typeParameters);
     writeUInt30(node.positionalParameters.length + node.namedParameters.length);
@@ -1368,9 +1423,9 @@
   void visitFunctionNode(FunctionNode node) {
     writeByte(Tag.FunctionNode);
     enterScope(typeParameters: node.typeParameters, variableScope: true);
-    LabelIndexer oldLabels = _labelIndexer;
+    LabelIndexer? oldLabels = _labelIndexer;
     _labelIndexer = null;
-    SwitchCaseIndexer oldCases = _switchCaseIndexer;
+    SwitchCaseIndexer? oldCases = _switchCaseIndexer;
     _switchCaseIndexer = null;
     // Note: FunctionNode has no tag.
     writeOffset(node.fileOffset);
@@ -1557,7 +1612,6 @@
     writeOffset(node.fileOffset);
     writeNode(node.left);
     writeNode(node.right);
-    writeByte(node.isNot ? 1 : 0);
     writeDartType(node.functionType);
     writeNonNullInstanceMemberReference(node.interfaceTargetReference);
   }
@@ -1567,7 +1621,6 @@
     writeByte(Tag.EqualsNull);
     writeOffset(node.fileOffset);
     writeNode(node.expression);
-    writeByte(node.isNot ? 1 : 0);
   }
 
   @override
@@ -1595,6 +1648,20 @@
   }
 
   @override
+  void visitInstanceGetterInvocation(InstanceGetterInvocation node) {
+    writeByte(Tag.InstanceGetterInvocation);
+    writeByte(node.kind.index);
+    writeByte(node.flags);
+    writeOffset(node.fileOffset);
+    writeNode(node.receiver);
+    writeName(node.name);
+    writeArgumentsNode(node.arguments);
+    // `const DynamicType()` is used to encode a missing function type.
+    writeDartType(node.functionType ?? const DynamicType());
+    writeNonNullInstanceMemberReference(node.interfaceTargetReference);
+  }
+
+  @override
   void visitLocalFunctionInvocation(LocalFunctionInvocation node) {
     writeByte(Tag.LocalFunctionInvocation);
     writeOffset(node.fileOffset);
@@ -1677,7 +1744,6 @@
       case LogicalExpressionOperator.OR:
         return 1;
     }
-    throw new ArgumentError('Not a logical operator: $operator');
   }
 
   @override
@@ -1900,21 +1966,23 @@
   void visitLet(Let node) {
     writeByte(Tag.Let);
     writeOffset(node.fileOffset);
-    _variableIndexer ??= new VariableIndexer();
-    _variableIndexer.pushScope();
+    VariableIndexer variableIndexer =
+        _variableIndexer ??= new VariableIndexer();
+    variableIndexer.pushScope();
     writeVariableDeclaration(node.variable);
     writeNode(node.body);
-    _variableIndexer.popScope();
+    variableIndexer.popScope();
   }
 
   @override
   void visitBlockExpression(BlockExpression node) {
     writeByte(Tag.BlockExpression);
-    _variableIndexer ??= new VariableIndexer();
-    _variableIndexer.pushScope();
+    VariableIndexer variableIndexer =
+        _variableIndexer ??= new VariableIndexer();
+    variableIndexer.pushScope();
     writeNodeList(node.body.statements);
     writeNode(node.value);
-    _variableIndexer.popScope();
+    variableIndexer.popScope();
   }
 
   @override
@@ -1936,7 +2004,7 @@
     writeLibraryDependencyReference(node.import);
   }
 
-  writeStatementOrEmpty(Statement node) {
+  writeStatementOrEmpty(Statement? node) {
     if (node == null) {
       writeByte(Tag.EmptyStatement);
     } else {
@@ -1952,22 +2020,24 @@
 
   @override
   void visitBlock(Block node) {
-    _variableIndexer ??= new VariableIndexer();
-    _variableIndexer.pushScope();
+    VariableIndexer variableIndexer =
+        _variableIndexer ??= new VariableIndexer();
+    variableIndexer.pushScope();
     writeByte(Tag.Block);
     writeOffset(node.fileOffset);
     writeOffset(node.fileEndOffset);
     writeNodeList(node.statements);
-    _variableIndexer.popScope();
+    variableIndexer.popScope();
   }
 
   @override
   void visitAssertBlock(AssertBlock node) {
-    _variableIndexer ??= new VariableIndexer();
-    _variableIndexer.pushScope();
+    VariableIndexer variableIndexer =
+        _variableIndexer ??= new VariableIndexer();
+    variableIndexer.pushScope();
     writeByte(Tag.AssertBlock);
     writeNodeList(node.statements);
-    _variableIndexer.popScope();
+    variableIndexer.popScope();
   }
 
   @override
@@ -1986,13 +2056,11 @@
 
   @override
   void visitLabeledStatement(LabeledStatement node) {
-    if (_labelIndexer == null) {
-      _labelIndexer = new LabelIndexer();
-    }
-    _labelIndexer.enter(node);
+    LabelIndexer labelIndexer = _labelIndexer ??= new LabelIndexer();
+    labelIndexer.enter(node);
     writeByte(Tag.LabeledStatement);
     writeNode(node.body);
-    _labelIndexer.exit();
+    labelIndexer.exit();
   }
 
   @override
@@ -2007,7 +2075,7 @@
   void visitBreakStatement(BreakStatement node) {
     writeByte(Tag.BreakStatement);
     writeOffset(node.fileOffset);
-    writeUInt30(_labelIndexer[node.target]);
+    writeUInt30(_labelIndexer![node.target]!);
   }
 
   @override
@@ -2028,41 +2096,42 @@
 
   @override
   void visitForStatement(ForStatement node) {
-    _variableIndexer ??= new VariableIndexer();
-    _variableIndexer.pushScope();
+    VariableIndexer variableIndexer =
+        _variableIndexer ??= new VariableIndexer();
+    variableIndexer.pushScope();
     writeByte(Tag.ForStatement);
     writeOffset(node.fileOffset);
     writeVariableDeclarationList(node.variables);
     writeOptionalNode(node.condition);
     writeNodeList(node.updates);
     writeNode(node.body);
-    _variableIndexer.popScope();
+    variableIndexer.popScope();
   }
 
   @override
   void visitForInStatement(ForInStatement node) {
-    _variableIndexer ??= new VariableIndexer();
-    _variableIndexer.pushScope();
+    VariableIndexer variableIndexer =
+        _variableIndexer ??= new VariableIndexer();
+    variableIndexer.pushScope();
     writeByte(node.isAsync ? Tag.AsyncForInStatement : Tag.ForInStatement);
     writeOffset(node.fileOffset);
     writeOffset(node.bodyOffset);
     writeVariableDeclaration(node.variable);
     writeNode(node.iterable);
     writeNode(node.body);
-    _variableIndexer.popScope();
+    variableIndexer.popScope();
   }
 
   @override
   void visitSwitchStatement(SwitchStatement node) {
-    if (_switchCaseIndexer == null) {
-      _switchCaseIndexer = new SwitchCaseIndexer();
-    }
-    _switchCaseIndexer.enter(node);
+    SwitchCaseIndexer switchCaseIndexer =
+        _switchCaseIndexer ??= new SwitchCaseIndexer();
+    switchCaseIndexer.enter(node);
     writeByte(Tag.SwitchStatement);
     writeOffset(node.fileOffset);
     writeNode(node.expression);
     writeSwitchCaseNodeList(node.cases);
-    _switchCaseIndexer.exit(node);
+    switchCaseIndexer.exit(node);
   }
 
   @override
@@ -2082,7 +2151,7 @@
   void visitContinueSwitchStatement(ContinueSwitchStatement node) {
     writeByte(Tag.ContinueSwitchStatement);
     writeOffset(node.fileOffset);
-    writeUInt30(_switchCaseIndexer[node.target]);
+    writeUInt30(_switchCaseIndexer![node.target]!);
   }
 
   @override
@@ -2117,14 +2186,15 @@
   @override
   void visitCatch(Catch node) {
     // Note: there is no tag on Catch.
-    _variableIndexer ??= new VariableIndexer();
-    _variableIndexer.pushScope();
+    VariableIndexer variableIndexer =
+        _variableIndexer ??= new VariableIndexer();
+    variableIndexer.pushScope();
     writeOffset(node.fileOffset);
     writeNode(node.guard);
     writeOptionalVariableDeclaration(node.exception);
     writeOptionalVariableDeclaration(node.stackTrace);
     writeNode(node.body);
-    _variableIndexer.popScope();
+    variableIndexer.popScope();
   }
 
   @override
@@ -2162,15 +2232,14 @@
     writeOptionalNode(node.initializer);
     // Declare the variable after its initializer. It is not in scope in its
     // own initializer.
-    _variableIndexer ??= new VariableIndexer();
-    _variableIndexer.declare(node);
+    (_variableIndexer ??= new VariableIndexer()).declare(node);
   }
 
   void writeVariableDeclarationList(List<VariableDeclaration> nodes) {
     writeList(nodes, writeVariableDeclaration);
   }
 
-  void writeOptionalVariableDeclaration(VariableDeclaration node) {
+  void writeOptionalVariableDeclaration(VariableDeclaration? node) {
     if (node == null) {
       writeByte(Tag.Nothing);
     } else {
@@ -2184,7 +2253,7 @@
     writeByte(Tag.FunctionDeclaration);
     writeOffset(node.fileOffset);
     writeVariableDeclaration(node.variable);
-    writeFunctionNode(node.function);
+    writeFunctionNode(node.function!);
   }
 
   @override
@@ -2223,14 +2292,19 @@
   }
 
   @override
+  void visitExtensionType(ExtensionType node) {
+    // TODO(dmitryas): Serialize ExtensionType.
+    node.onType.accept(this);
+  }
+
+  @override
   void visitFutureOrType(FutureOrType node) {
     // TODO(dmitryas): Remove special treatment of FutureOr when the VM supports
     // the new encoding: just write the tag.
-    assert(_knownCanonicalNameNonRootTops != null &&
-        _knownCanonicalNameNonRootTops.isNotEmpty);
+    assert(_knownCanonicalNameNonRootTops.isNotEmpty);
     CanonicalName root = _knownCanonicalNameNonRootTops.first;
     while (!root.isRoot) {
-      root = root.parent;
+      root = root.parent!;
     }
     CanonicalName canonicalNameOfFutureOr =
         root.getChild("dart:async").getChild("FutureOr");
@@ -2246,11 +2320,10 @@
   void visitNullType(NullType node) {
     // TODO(dmitryas): Remove special treatment of Null when the VM supports the
     // new encoding: just write the tag.
-    assert(_knownCanonicalNameNonRootTops != null &&
-        _knownCanonicalNameNonRootTops.isNotEmpty);
+    assert(_knownCanonicalNameNonRootTops.isNotEmpty);
     CanonicalName root = _knownCanonicalNameNonRootTops.first;
     while (!root.isRoot) {
-      root = root.parent;
+      root = root.parent!;
     }
     CanonicalName canonicalNameOfNull =
         root.getChild("dart:core").getChild("Null");
@@ -2268,11 +2341,11 @@
     // requires the nullability byte.
     if (node.typeArguments.isEmpty) {
       writeByte(Tag.SimpleInterfaceType);
-      writeByte(_currentLibrary.nonNullable.index);
+      writeByte(_currentLibrary!.nonNullable.index);
       writeNonNullReference(node.className);
     } else {
       writeByte(Tag.InterfaceType);
-      writeByte(_currentLibrary.nonNullable.index);
+      writeByte(_currentLibrary!.nonNullable.index);
       writeNonNullReference(node.className);
       writeNodeList(node.typeArguments);
     }
@@ -2338,18 +2411,20 @@
       writeByte(node.variance);
     }
     writeStringReference(node.name ?? '');
-    writeNode(node.bound);
+    writeNode(node.bound!);
+    // TODO(johnniwinther): Make this non-optional.
     writeOptionalNode(node.defaultType);
   }
 
   @override
   void visitExtension(Extension node) {
-    if (node.canonicalName == null) {
+    if (node.reference.canonicalName == null) {
       throw new ArgumentError('Missing canonical name for $node');
     }
     writeByte(Tag.Extension);
     writeNonNullCanonicalNameReference(getCanonicalNameOfExtension(node));
-    writeStringReference(node.name ?? '');
+    writeStringReference(node.name);
+    writeAnnotationList(node.annotations);
     writeUriReference(node.fileUri);
     writeOffset(node.fileOffset);
 
@@ -2365,7 +2440,7 @@
       writeName(descriptor.name);
       writeByte(descriptor.kind.index);
       writeByte(descriptor.flags);
-      writeNonNullCanonicalNameReference(descriptor.member.canonicalName);
+      writeNonNullCanonicalNameReference(descriptor.member.canonicalName!);
     }
   }
 
@@ -2461,6 +2536,11 @@
   }
 
   @override
+  void visitExtensionReference(Extension node) {
+    throw new UnsupportedError('serialization of Class references');
+  }
+
+  @override
   void visitConstructorReference(Constructor node) {
     throw new UnsupportedError('serialization of Constructor references');
   }
@@ -2646,30 +2726,28 @@
 typedef bool LibraryFilter(Library _);
 
 class VariableIndexer {
-  Map<VariableDeclaration, int> index;
-  List<int> scopes;
+  Map<VariableDeclaration, int>? index;
+  List<int>? scopes;
   int stackHeight = 0;
 
   void declare(VariableDeclaration node) {
-    index ??= <VariableDeclaration, int>{};
-    index[node] = stackHeight++;
+    (index ??= <VariableDeclaration, int>{})[node] = stackHeight++;
   }
 
   void pushScope() {
-    scopes ??= <int>[];
-    scopes.add(stackHeight);
+    (scopes ??= <int>[]).add(stackHeight);
   }
 
   void popScope() {
-    stackHeight = scopes.removeLast();
+    stackHeight = scopes!.removeLast();
   }
 
   void restoreScope(int numberOfVariables) {
     stackHeight += numberOfVariables;
   }
 
-  int operator [](VariableDeclaration node) {
-    return index == null ? null : index[node];
+  int? operator [](VariableDeclaration node) {
+    return index == null ? null : index![node];
   }
 }
 
@@ -2685,7 +2763,7 @@
     --stackHeight;
   }
 
-  int operator [](LabeledStatement node) => index[node];
+  int? operator [](LabeledStatement node) => index[node];
 }
 
 class SwitchCaseIndexer {
@@ -2702,7 +2780,7 @@
     stackHeight -= node.cases.length;
   }
 
-  int operator [](SwitchCase node) => index[node];
+  int? operator [](SwitchCase node) => index[node];
 }
 
 class ConstantIndexer extends RecursiveResultVisitor {
@@ -2717,7 +2795,7 @@
   ConstantIndexer(this.stringIndexer, this._printer);
 
   int put(Constant constant) {
-    final int oldOffset = offsets[constant];
+    final int? oldOffset = offsets[constant];
     if (oldOffset != null) return oldOffset;
 
     // Traverse DAG in post-order to ensure children have their offsets assigned
@@ -2747,7 +2825,7 @@
     put(node);
   }
 
-  int operator [](Constant node) => offsets[node];
+  int? operator [](Constant node) => offsets[node];
 }
 
 class TypeParameterIndexer {
@@ -2783,7 +2861,7 @@
   }
 
   int put(String string) {
-    int result = index[string];
+    int? result = index[string];
     if (result == null) {
       result = index.length;
       index[string] = result;
@@ -2791,19 +2869,19 @@
     return result;
   }
 
-  int operator [](String string) => index[string];
+  int? operator [](String string) => index[string];
 }
 
 class UriIndexer {
   // Note that the iteration order is important.
-  final Map<Uri, int> index = new Map<Uri, int>();
+  final Map<Uri?, int> index = new Map<Uri?, int>();
 
   UriIndexer() {
     put(null);
   }
 
-  int put(Uri uri) {
-    int result = index[uri];
+  int put(Uri? uri) {
+    int? result = index[uri];
     if (result == null) {
       result = index.length;
       index[uri] = result;
@@ -2823,19 +2901,20 @@
   int flushedLength = 0;
 
   Float64List _doubleBuffer = new Float64List(1);
-  Uint8List _doubleBufferUint8;
+  Uint8List? _doubleBufferUint8;
 
   int get offset => length + flushedLength;
 
   BufferedSink(this._sink);
 
   void addDouble(double d) {
-    _doubleBufferUint8 ??= _doubleBuffer.buffer.asUint8List();
+    Uint8List doubleBufferUint8 =
+        _doubleBufferUint8 ??= _doubleBuffer.buffer.asUint8List();
     _doubleBuffer[0] = d;
-    addByte4(_doubleBufferUint8[0], _doubleBufferUint8[1],
-        _doubleBufferUint8[2], _doubleBufferUint8[3]);
-    addByte4(_doubleBufferUint8[4], _doubleBufferUint8[5],
-        _doubleBufferUint8[6], _doubleBufferUint8[7]);
+    addByte4(doubleBufferUint8[0], doubleBufferUint8[1], doubleBufferUint8[2],
+        doubleBufferUint8[3]);
+    addByte4(doubleBufferUint8[4], doubleBufferUint8[5], doubleBufferUint8[6],
+        doubleBufferUint8[7]);
   }
 
   @pragma("vm:prefer-inline")
@@ -2915,7 +2994,7 @@
 
 /// Non-empty metadata subsection.
 class _MetadataSubsection {
-  final MetadataRepository<Object> repository;
+  final MetadataRepository<Object?> repository;
 
   /// List of (nodeOffset, metadataOffset) pairs.
   /// Gradually filled by the writer as writing progresses, which by
diff --git a/pkg/kernel/lib/binary/tag.dart b/pkg/kernel/lib/binary/tag.dart
index c91a5e6..fca44c6 100644
--- a/pkg/kernel/lib/binary/tag.dart
+++ b/pkg/kernel/lib/binary/tag.dart
@@ -90,6 +90,7 @@
   static const int InstanceGet = 118;
   static const int InstanceSet = 119;
   static const int InstanceInvocation = 120;
+  static const int InstanceGetterInvocation = 89;
   static const int InstanceTearOff = 121;
   static const int DynamicGet = 122;
   static const int DynamicSet = 123;
@@ -124,6 +125,7 @@
 
   // Types
   static const int TypedefType = 87;
+  // 89 is occupied by [InstanceGetterInvocation] (expression).
   static const int InvalidType = 90;
   static const int DynamicType = 91;
   static const int VoidType = 92;
@@ -172,7 +174,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 = 56;
+  static const int BinaryFormatVersion = 60;
 }
 
 abstract class ConstantTag {
diff --git a/pkg/kernel/lib/canonical_name.dart b/pkg/kernel/lib/canonical_name.dart
index af7344e..086aa2a 100644
--- a/pkg/kernel/lib/canonical_name.dart
+++ b/pkg/kernel/lib/canonical_name.dart
@@ -30,9 +30,14 @@
 ///         "@constructors"
 ///         Qualified name
 ///
-///      Field:
+///      Field or the implicit getter of a field:
 ///         Canonical name of enclosing class or library
-///         "@fields"
+///         "@getters"
+///         Qualified name
+///
+///      Implicit setter of a field:
+///         Canonical name of enclosing class or library
+///         "@setters"
 ///         Qualified name
 ///
 ///      Typedef:
@@ -77,7 +82,7 @@
   Map<String, CanonicalName>? _children;
 
   /// The library, class, or member bound to this name.
-  Reference? reference;
+  Reference? _reference;
 
   /// Temporary index used during serialization.
   int index = -1;
@@ -132,11 +137,11 @@
   }
 
   CanonicalName getChildFromField(Field field) {
-    return getChild('@fields').getChildFromQualifiedName(field.name!);
+    return getChild('@getters').getChildFromQualifiedName(field.name!);
   }
 
   CanonicalName getChildFromFieldSetter(Field field) {
-    return getChild('@=fields').getChildFromQualifiedName(field.name!);
+    return getChild('@setters').getChildFromQualifiedName(field.name!);
   }
 
   CanonicalName getChildFromConstructor(Constructor constructor) {
@@ -151,11 +156,11 @@
   }
 
   CanonicalName getChildFromFieldWithName(Name name) {
-    return getChild('@fields').getChildFromQualifiedName(name);
+    return getChild('@getters').getChildFromQualifiedName(name);
   }
 
   CanonicalName getChildFromFieldSetterWithName(Name name) {
-    return getChild('@=fields').getChildFromQualifiedName(name);
+    return getChild('@setters').getChildFromQualifiedName(name);
   }
 
   CanonicalName getChildFromTypedef(Typedef typedef_) {
@@ -200,16 +205,29 @@
     if (target == null) {
       throw '$this cannot be bound to null';
     }
-    if (reference == target) return;
-    if (reference != null) {
-      throw '$this is already bound';
+    if (_reference == target) return;
+    if (_reference != null) {
+      StringBuffer sb = new StringBuffer();
+      sb.write('$this is already bound to ${_reference}');
+      if (_reference?._node != null) {
+        sb.write(' with node ${_reference?._node}'
+            ' (${_reference?._node.runtimeType}'
+            ':${_reference?._node.hashCode})');
+      }
+      sb.write(', trying to bind to ${target}');
+      if (target._node != null) {
+        sb.write(' with node ${target._node}'
+            ' (${target._node.runtimeType}'
+            ':${target._node.hashCode})');
+      }
+      throw sb.toString();
     }
     if (target.canonicalName != null) {
       throw 'Cannot bind $this to ${target.node}, target is already bound to '
           '${target.canonicalName}';
     }
     target.canonicalName = this;
-    this.reference = target;
+    this._reference = target;
   }
 
   void unbind() {
@@ -223,16 +241,16 @@
   }
 
   void _unbindInternal() {
-    if (reference == null) return;
-    assert(reference!.canonicalName == this);
-    if (reference!.node is Class) {
+    if (_reference == null) return;
+    assert(_reference!.canonicalName == this);
+    if (_reference!.node is Class) {
       // TODO(jensj): Get rid of this. This is only needed because pkg:vm does
       // weird stuff in transformations. `unbind` should probably be private.
-      Class c = reference!.asClass;
+      Class c = _reference!.asClass;
       c.ensureLoaded();
     }
-    reference!.canonicalName = null;
-    reference = null;
+    _reference!.canonicalName = null;
+    _reference = null;
   }
 
   void unbindAll() {
@@ -252,8 +270,67 @@
     return "${parent!.toStringInternal()}::$name";
   }
 
-  Reference getReference() {
-    return reference ??= (new Reference()..canonicalName = this);
+  Reference get reference {
+    return _reference ??= (new Reference()..canonicalName = this);
+  }
+
+  void checkCanonicalNameChildren() {
+    CanonicalName parent = this;
+    Iterable<CanonicalName>? parentChildren = parent.childrenOrNull;
+    if (parentChildren != null) {
+      for (CanonicalName child in parentChildren) {
+        if (child.name != '@methods' &&
+            child.name != '@typedefs' &&
+            child.name != '@fields' &&
+            child.name != '@=fields' &&
+            child.name != '@getters' &&
+            child.name != '@setters' &&
+            child.name != '@factories' &&
+            child.name != '@constructors') {
+          bool checkReferenceNode = true;
+          if (child._reference == null) {
+            // OK for "if private: URI of library" part of "Qualified name"...
+            // TODO(johnniwinther): This wrongfully skips checking of variable
+            // synthesized by the VM transformations. The kind of canonical
+            // name types maybe should be directly available.
+            if (parent.parent != null && child.name.contains(':')) {
+              // OK then.
+              checkReferenceNode = false;
+            } else {
+              throw buildCanonicalNameError(
+                  "Null reference (${child.name}) ($child).", child);
+            }
+          }
+          if (checkReferenceNode) {
+            if (child._reference!.canonicalName != child) {
+              throw buildCanonicalNameError(
+                  "Canonical name and reference doesn't agree.", child);
+            }
+            if (child._reference!.node == null) {
+              throw buildCanonicalNameError(
+                  "Reference is null (${child.name}) ($child).", child);
+            }
+          }
+        }
+        child.checkCanonicalNameChildren();
+      }
+    }
+  }
+
+  bool get isConsistent {
+    if (_reference != null && !_reference!.isConsistent) {
+      return false;
+    }
+    return true;
+  }
+
+  String getInconsistency() {
+    StringBuffer sb = new StringBuffer();
+    sb.write('CanonicalName ${this} (${hashCode}):');
+    if (_reference != null) {
+      sb.write(' ${_reference!.getInconsistency()}');
+    }
+    return sb.toString();
   }
 
   static String getProcedureQualifier(Procedure procedure) {
@@ -262,4 +339,252 @@
     if (procedure.isFactory) return '@factories';
     return '@methods';
   }
+
+  /// Returns `true` if [node] is orphaned through its [reference].
+  ///
+  /// A [NamedNode] is orphaned if the canonical name of its reference doesn't
+  /// point back to the node itself. This can occur if the [reference] is
+  /// repurposed for a new [NamedNode]. In this case, the reference will be
+  /// updated to point the new node.
+  ///
+  /// This method assumes that `reference.canonicalName` is this canonical name.
+  bool isOrphaned(NamedNode node, Reference reference) {
+    assert(reference.canonicalName == this);
+    return _reference?._node != node;
+  }
+
+  /// Returns a description of the orphancy, if [node] is orphaned through its
+  /// [reference]. Otherwise `null`.
+  ///
+  /// A [NamedNode] is orphaned if the canonical name of its reference doesn't
+  /// point back to the node itself. This can occur if the [reference] is
+  /// repurposed for a new [NamedNode]. In this case, the reference will be
+  /// updated to point the new node.
+  ///
+  /// This method assumes that `reference.canonicalName` is this canonical name.
+  String? getOrphancyDescription(NamedNode node, Reference reference) {
+    assert(reference.canonicalName == this);
+    if (_reference?._node != node) {
+      return _reference!.getOrphancyDescription(node);
+    }
+    return null;
+  }
+}
+
+/// Indirection between a reference and its definition.
+///
+/// There is only one reference object per [NamedNode].
+class Reference {
+  CanonicalName? canonicalName;
+
+  NamedNode? _node;
+
+  NamedNode? get node {
+    if (_node == null) {
+      // Either this is an unbound reference or it belongs to a lazy-loaded
+      // (and not yet loaded) class. If it belongs to a lazy-loaded class,
+      // load the class.
+
+      CanonicalName? canonicalNameParent = canonicalName?.parent;
+      while (canonicalNameParent != null) {
+        if (canonicalNameParent.name.startsWith("@")) {
+          break;
+        }
+        canonicalNameParent = canonicalNameParent.parent;
+      }
+      if (canonicalNameParent != null) {
+        NamedNode? parentNamedNode =
+            canonicalNameParent.parent?.reference._node;
+        if (parentNamedNode is Class) {
+          Class parentClass = parentNamedNode;
+          if (parentClass.lazyBuilder != null) {
+            parentClass.ensureLoaded();
+          }
+        }
+      }
+    }
+    return _node;
+  }
+
+  void set node(NamedNode? node) {
+    _node = node;
+  }
+
+  String toString() {
+    return "Reference to ${toStringInternal()}";
+  }
+
+  String toStringInternal() {
+    if (canonicalName != null) {
+      return '${canonicalName!.toStringInternal()}';
+    }
+    if (node != null) {
+      return node!.toStringInternal();
+    }
+    return 'Unbound reference';
+  }
+
+  Library get asLibrary {
+    if (node == null) {
+      throw '$this is not bound to an AST node. A library was expected';
+    }
+    return node as Library;
+  }
+
+  Class get asClass {
+    if (node == null) {
+      throw '$this is not bound to an AST node. A class was expected';
+    }
+    return node as Class;
+  }
+
+  Member get asMember {
+    if (node == null) {
+      throw '$this is not bound to an AST node. A member was expected';
+    }
+    return node as Member;
+  }
+
+  Field get asField {
+    if (node == null) {
+      throw '$this is not bound to an AST node. A field was expected';
+    }
+    return node as Field;
+  }
+
+  Constructor get asConstructor {
+    if (node == null) {
+      throw '$this is not bound to an AST node. A constructor was expected';
+    }
+    return node as Constructor;
+  }
+
+  Procedure get asProcedure {
+    if (node == null) {
+      throw '$this is not bound to an AST node. A procedure was expected';
+    }
+    return node as Procedure;
+  }
+
+  Typedef get asTypedef {
+    if (node == null) {
+      throw '$this is not bound to an AST node. A typedef was expected';
+    }
+    return node as Typedef;
+  }
+
+  Extension get asExtension {
+    if (node == null) {
+      throw '$this is not bound to an AST node. An extension was expected';
+    }
+    return node as Extension;
+  }
+
+  bool get isConsistent {
+    NamedNode? node = _node;
+    if (node != null) {
+      if (node.reference != this &&
+          (node is! Field || node.setterReference != this)) {
+        // The reference of a [NamedNode] must point to this reference, or
+        // if the node is a [Field] the setter reference must point to this
+        // reference.
+        return false;
+      }
+    }
+    if (canonicalName != null && canonicalName!._reference != this) {
+      return false;
+    }
+    return true;
+  }
+
+  String getInconsistency() {
+    StringBuffer sb = new StringBuffer();
+    sb.write('Reference ${this} (${hashCode}):');
+    NamedNode? node = _node;
+    if (node != null) {
+      if (node is Field) {
+        if (node.getterReference != this && node.setterReference != this) {
+          sb.write(' _node=${node} (${node.runtimeType}:${node.hashCode})');
+          sb.write(' _node.getterReference='
+              '${node.getterReference} (${node.getterReference.hashCode})');
+          sb.write(' _node.setterReference='
+              '${node.setterReference} (${node.setterReference.hashCode})');
+        }
+      } else {
+        if (node.reference != this) {
+          sb.write(' _node=${node} (${node.runtimeType}:${node.hashCode})');
+          sb.write(' _node.reference='
+              '${node.reference} (${node.reference.hashCode})');
+        }
+      }
+    }
+    if (canonicalName != null && canonicalName!._reference != this) {
+      sb.write(' canonicalName=${canonicalName} (${canonicalName.hashCode})');
+      sb.write(' canonicalName.reference='
+          '${canonicalName!._reference} '
+          '(${canonicalName!._reference.hashCode})');
+    }
+    return sb.toString();
+  }
+
+  /// Returns `true` if [node] is orphaned through this reference.
+  ///
+  /// A [NamedNode] is orphaned if its reference doesn't point back to the node
+  /// itself. This can occur if the [reference] is repurposed for a new
+  /// [NamedNode]. In this case, the reference will be updated to point the new
+  /// node.
+  ///
+  /// This method assumes that this reference is the reference, possibly
+  /// getter or setter reference for a field, of [node].
+  bool isOrphaned(NamedNode node) {
+    return _node != node;
+  }
+
+  /// Returns a description of the orphancy, if [node] is orphaned through this
+  /// reference. Otherwise `null`.
+  ///
+  /// A [NamedNode] is orphaned if its reference doesn't point back to the node
+  /// itself. This can occur if the [reference] is repurposed for a new
+  /// [NamedNode]. In this case, the reference will be updated to point the new
+  /// node.
+  ///
+  /// This method assumes that this reference is the reference, possibly
+  /// getter or setter reference for a field, of [node].
+  String? getOrphancyDescription(NamedNode node) {
+    if (_node != node) {
+      StringBuffer sb = new StringBuffer();
+      sb.write('Orphaned named node ${node} ');
+      sb.write('(${node.runtimeType}:${node.hashCode})\n');
+      sb.write('Linked node ${_node} ');
+      sb.write('(${_node.runtimeType}:');
+      sb.write('${_node.hashCode})');
+      return sb.toString();
+    }
+    return null;
+  }
+}
+
+class CanonicalNameError {
+  final String message;
+
+  CanonicalNameError(this.message);
+
+  String toString() => 'CanonicalNameError: $message';
+}
+
+class CanonicalNameSdkError extends CanonicalNameError {
+  CanonicalNameSdkError(String message) : super(message);
+
+  String toString() => 'CanonicalNameSdkError: $message';
+}
+
+CanonicalNameError buildCanonicalNameError(
+    String message, CanonicalName problemNode) {
+  // Special-case missing sdk entries as that is probably a change to the
+  // platform - that's something we might want to react differently to.
+  String libraryUri = problemNode.nonRootTop?.name ?? "";
+  if (libraryUri.startsWith("dart:")) {
+    return new CanonicalNameSdkError(message);
+  }
+  return new CanonicalNameError(message);
 }
diff --git a/pkg/kernel/lib/clone.dart b/pkg/kernel/lib/clone.dart
index 69d6fd7..3f09922 100644
--- a/pkg/kernel/lib/clone.dart
+++ b/pkg/kernel/lib/clone.dart
@@ -13,7 +13,7 @@
 /// This class does not clone members. For that, use the
 /// [CloneVisitorWithMembers] and setup references properly.
 class CloneVisitorNotMembers implements TreeVisitor<TreeNode> {
-  final Map<VariableDeclaration, VariableDeclaration> variables =
+  final Map<VariableDeclaration, VariableDeclaration> _variables =
       <VariableDeclaration, VariableDeclaration>{};
   final Map<LabeledStatement, LabeledStatement> labels =
       <LabeledStatement, LabeledStatement>{};
@@ -43,6 +43,20 @@
     return map;
   }
 
+  /// Returns the clone of [variable] or `null` if no clone has been created
+  /// for variable.
+  VariableDeclaration? getVariableClone(VariableDeclaration variable) {
+    return _variables[variable];
+  }
+
+  /// Registers [clone] as the clone for [variable].
+  ///
+  /// Returns the [clone].
+  VariableDeclaration setVariableClone(
+      VariableDeclaration variable, VariableDeclaration clone) {
+    return _variables[variable] = clone;
+  }
+
   TreeNode visitLibrary(Library node) {
     throw 'Cloning of libraries is not implemented';
   }
@@ -140,11 +154,11 @@
 
   visitVariableGet(VariableGet node) {
     return new VariableGet(
-        variables[node.variable]!, visitOptionalType(node.promotedType));
+        getVariableClone(node.variable)!, visitOptionalType(node.promotedType));
   }
 
   visitVariableSet(VariableSet node) {
-    return new VariableSet(variables[node.variable]!, clone(node.value));
+    return new VariableSet(getVariableClone(node.variable)!, clone(node.value));
   }
 
   visitPropertyGet(PropertyGet node) {
@@ -454,19 +468,27 @@
   }
 
   visitVariableDeclaration(VariableDeclaration node) {
-    return variables[node] = new VariableDeclaration(node.name,
-        initializer: cloneOptional(node.initializer),
-        type: visitType(node.type))
-      ..annotations = cloneAnnotations && !node.annotations.isEmpty
-          ? node.annotations.map(clone).toList()
-          : const <Expression>[]
-      ..flags = node.flags
-      ..fileEqualsOffset = _cloneFileOffset(node.fileEqualsOffset);
+    return setVariableClone(
+        node,
+        new VariableDeclaration(node.name,
+            initializer: cloneOptional(node.initializer),
+            type: visitType(node.type))
+          ..annotations = cloneAnnotations && !node.annotations.isEmpty
+              ? node.annotations.map(clone).toList()
+              : const <Expression>[]
+          ..flags = node.flags
+          ..fileEqualsOffset = _cloneFileOffset(node.fileEqualsOffset));
   }
 
   visitFunctionDeclaration(FunctionDeclaration node) {
     VariableDeclaration newVariable = clone(node.variable);
-    return new FunctionDeclaration(newVariable, clone(node.function!));
+    // Create the declaration before cloning the body to support recursive
+    // [LocalFunctionInvocation] nodes.
+    FunctionDeclaration declaration =
+        new FunctionDeclaration(newVariable, null);
+    FunctionNode functionNode = clone(node.function!);
+    declaration.function = functionNode..parent = declaration;
+    return declaration;
   }
 
   void prepareTypeParameters(List<TypeParameter> typeParameters) {
@@ -637,14 +659,13 @@
   @override
   TreeNode visitEqualsCall(EqualsCall node) {
     return new EqualsCall.byReference(clone(node.left), clone(node.right),
-        isNot: node.isNot,
         functionType: visitType(node.functionType) as FunctionType,
         interfaceTargetReference: node.interfaceTargetReference);
   }
 
   @override
   TreeNode visitEqualsNull(EqualsNull node) {
-    return new EqualsNull(clone(node.expression), isNot: node.isNot);
+    return new EqualsNull(clone(node.expression));
   }
 
   @override
@@ -671,6 +692,14 @@
   }
 
   @override
+  TreeNode visitInstanceGetterInvocation(InstanceGetterInvocation node) {
+    return new InstanceGetterInvocation.byReference(
+        node.kind, clone(node.receiver), node.name, clone(node.arguments),
+        functionType: visitOptionalType(node.functionType) as FunctionType,
+        interfaceTargetReference: node.interfaceTargetReference);
+  }
+
+  @override
   TreeNode visitInstanceSet(InstanceSet node) {
     return new InstanceSet.byReference(
         node.kind, clone(node.receiver), node.name, clone(node.value),
@@ -688,7 +717,7 @@
   @override
   TreeNode visitLocalFunctionInvocation(LocalFunctionInvocation node) {
     return new LocalFunctionInvocation(
-        variables[node.variable]!, clone(node.arguments),
+        getVariableClone(node.variable)!, clone(node.arguments),
         functionType: visitType(node.functionType) as FunctionType);
   }
 
diff --git a/pkg/kernel/lib/kernel.dart b/pkg/kernel/lib/kernel.dart
index cae6df9..9433890 100644
--- a/pkg/kernel/lib/kernel.dart
+++ b/pkg/kernel/lib/kernel.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
-
 /// Conventions for paths:
 ///
 /// - Use the [Uri] class for paths that may have the `file`, `dart` or
@@ -23,18 +21,19 @@
 
 export 'ast.dart';
 
-Component loadComponentFromBinary(String path, [Component component]) {
+Component loadComponentFromBinary(String path, [Component? component]) {
   List<int> bytes = new File(path).readAsBytesSync();
   return loadComponentFromBytes(bytes, component);
 }
 
-Component loadComponentFromBytes(List<int> bytes, [Component component]) {
+Component loadComponentFromBytes(List<int> bytes, [Component? component]) {
   component ??= new Component();
   new BinaryBuilder(bytes).readComponent(component);
   return component;
 }
 
-Component loadComponentSourceFromBytes(List<int> bytes, [Component component]) {
+Component loadComponentSourceFromBytes(List<int> bytes,
+    [Component? component]) {
   component ??= new Component();
   new BinaryBuilder(bytes).readComponentSource(component);
   return component;
@@ -68,7 +67,7 @@
   return sink.builder.toBytes();
 }
 
-void writeLibraryToText(Library library, {String path}) {
+void writeLibraryToText(Library library, {String? path}) {
   StringBuffer buffer = new StringBuffer();
   new Printer(buffer).writeLibraryFile(library);
   if (path == null) {
@@ -79,7 +78,7 @@
 }
 
 void writeComponentToText(Component component,
-    {String path, bool showOffsets: false, bool showMetadata: false}) {
+    {String? path, bool showOffsets: false, bool showMetadata: false}) {
   StringBuffer buffer = new StringBuffer();
   new Printer(buffer, showOffsets: showOffsets, showMetadata: showMetadata)
       .writeComponentFile(component);
diff --git a/pkg/kernel/lib/src/bounds_checks.dart b/pkg/kernel/lib/src/bounds_checks.dart
index 6505325..a0d9fb8 100644
--- a/pkg/kernel/lib/src/bounds_checks.dart
+++ b/pkg/kernel/lib/src/bounds_checks.dart
@@ -685,6 +685,17 @@
     }
     return createTypedef(node, newNullability, newTypeArguments);
   }
+
+  @override
+  DartType? visitFunctionType(FunctionType node, int variance) {
+    // The variance of the Typedef parameters should be taken into account only
+    // when for the NNBD code.
+    if (node.typedefType != null && isNonNullableByDefault) {
+      return node.typedefType!.accept1(this, variance);
+    } else {
+      return super.visitFunctionType(node, variance);
+    }
+  }
 }
 
 int computeVariance(TypeParameter typeParameter, DartType type,
@@ -739,6 +750,21 @@
   }
 
   @override
+  int visitExtensionType(ExtensionType node,
+      Map<TypeParameter, Map<DartType, int>> computedVariances) {
+    int result = Variance.unrelated;
+    for (int i = 0; i < node.typeArguments.length; ++i) {
+      result = Variance.meet(
+          result,
+          Variance.combine(
+              node.extension.typeParameters[i].variance,
+              computeVariance(typeParameter, node.typeArguments[i],
+                  computedVariances: computedVariances)));
+    }
+    return result;
+  }
+
+  @override
   int visitFutureOrType(FutureOrType node,
       Map<TypeParameter, Map<DartType, int>> computedVariances) {
     return computeVariance(typeParameter, node.typeArgument,
diff --git a/pkg/kernel/lib/src/dart_type_equivalence.dart b/pkg/kernel/lib/src/dart_type_equivalence.dart
index d051caa..08c2009 100644
--- a/pkg/kernel/lib/src/dart_type_equivalence.dart
+++ b/pkg/kernel/lib/src/dart_type_equivalence.dart
@@ -171,6 +171,32 @@
   }
 
   @override
+  bool visitExtensionType(ExtensionType node, DartType other) {
+    // First, check Object*, Object?.
+    if (equateTopTypes && coreTypes.isTop(node)) {
+      return coreTypes.isTop(other);
+    }
+
+    if (other is ExtensionType) {
+      if (!_checkAndRegisterNullabilities(
+          node.declaredNullability, other.declaredNullability)) {
+        return false;
+      }
+      if (node.extension != other.extension) {
+        return false;
+      }
+      assert(node.typeArguments.length == other.typeArguments.length);
+      for (int i = 0; i < node.typeArguments.length; ++i) {
+        if (!node.typeArguments[i].accept1(this, other.typeArguments[i])) {
+          return false;
+        }
+      }
+      return true;
+    }
+    return false;
+  }
+
+  @override
   bool visitFutureOrType(FutureOrType node, DartType other) {
     // First, check FutureOr<dynamic>, FutureOr<Object?>, etc.
     if (equateTopTypes && coreTypes.isTop(node)) {
diff --git a/pkg/kernel/lib/src/future_value_type.dart b/pkg/kernel/lib/src/future_value_type.dart
index ab5067b..773c8e7 100644
--- a/pkg/kernel/lib/src/future_value_type.dart
+++ b/pkg/kernel/lib/src/future_value_type.dart
@@ -94,6 +94,12 @@
   }
 
   @override
+  DartType visitExtensionType(DartType node, CoreTypes coreTypes) {
+    // Otherwise, for all S, futureValueType(S) = Object?.
+    return coreTypes.objectNullableRawType;
+  }
+
+  @override
   DartType visitVoidType(DartType node, CoreTypes coreTypes) {
     // futureValueType(void) = void.
     return node;
diff --git a/pkg/kernel/lib/src/merge_visitor.dart b/pkg/kernel/lib/src/merge_visitor.dart
index bbc745e..b626fa1 100644
--- a/pkg/kernel/lib/src/merge_visitor.dart
+++ b/pkg/kernel/lib/src/merge_visitor.dart
@@ -175,6 +175,41 @@
   }
 
   @override
+  DartType? visitExtensionType(ExtensionType a, DartType b) {
+    if (b is ExtensionType &&
+        a.extension == b.extension &&
+        a.typeArguments.length == b.typeArguments.length) {
+      Nullability? nullability = mergeNullability(a.nullability, b.nullability);
+      if (nullability != null) {
+        return mergeExtensionTypes(a, b, nullability);
+      }
+    }
+    if (b is InvalidType) {
+      return b;
+    }
+    return null;
+  }
+
+  DartType? mergeExtensionTypes(
+      ExtensionType a, ExtensionType b, Nullability nullability) {
+    assert(a.extension == b.extension);
+    assert(a.typeArguments.length == b.typeArguments.length);
+    if (a.typeArguments.isEmpty) {
+      return new ExtensionType(a.extension, nullability);
+    }
+    List<DartType> newTypeArguments =
+        new List<DartType>.filled(a.typeArguments.length, dummyDartType);
+    for (int i = 0; i < a.typeArguments.length; i++) {
+      DartType? newType = a.typeArguments[i].accept1(this, b.typeArguments[i]);
+      if (newType == null) {
+        return null;
+      }
+      newTypeArguments[i] = newType;
+    }
+    return new ExtensionType(a.extension, nullability, newTypeArguments);
+  }
+
+  @override
   DartType? visitFutureOrType(FutureOrType a, DartType b) {
     if (b is FutureOrType) {
       Nullability? nullability = mergeNullability(a.nullability, b.nullability);
diff --git a/pkg/kernel/lib/src/non_null.dart b/pkg/kernel/lib/src/non_null.dart
index 2d908f0..b0e7cd2 100644
--- a/pkg/kernel/lib/src/non_null.dart
+++ b/pkg/kernel/lib/src/non_null.dart
@@ -4,7 +4,7 @@
 
 import '../ast.dart';
 
-/// Returns the type defines as `NonNull(type)` in the nnbd specification.
+/// Returns the type defined as `NonNull(type)` in the nnbd specification.
 DartType computeNonNull(DartType type) {
   return type.accept(const _NonNullVisitor()) ?? type;
 }
@@ -23,10 +23,18 @@
   }
 
   @override
-  DartType? visitDynamicType(DynamicType node) => null;
+  DartType? visitDynamicType(DynamicType node) {
+    // NonNull(dynamic) = dynamic
+    return null;
+  }
 
   @override
   DartType? visitFunctionType(FunctionType node) {
+    // NonNull(T0 Function(...)) = T0 Function(...)
+    //
+    // NonNull(T?) = NonNull(T)
+    //
+    // NonNull(T*) = NonNull(T)
     if (node.declaredNullability == Nullability.nonNullable) {
       return null;
     }
@@ -35,17 +43,65 @@
 
   @override
   DartType? visitFutureOrType(FutureOrType node) {
-    DartType? typeArgument = node.typeArgument.accept(this);
-    if (node.declaredNullability == Nullability.nonNullable &&
-        typeArgument == null) {
+    // NonNull(FutureOr<T>) = FutureOr<T>
+    //
+    // NonNull(T?) = NonNull(T)
+    //
+    // NonNull(T*) = NonNull(T)
+
+    // Note that we should _not_ compute NonNull of the type argument. Consider
+    //
+    //     NonNull(FutureOr<int?>?)
+    //
+    // We have that
+    //
+    //     FutureOr<int?>? = Future<int?>? | int?
+    //
+    // and therefore that
+    //
+    //     NonNull(FutureOr<int?>?) = NonNull(FutureOr<int?>?) | NonNull(int?)
+    //                              = FutureOr<int?> | int
+    //
+    // but that means that while `null` is not a possible value from `int` it
+    // is still a possible value from awaiting the future. Taking NonNull on
+    // the type argument as well as on the `FutureOr`:
+    //
+    //     NonNull(FutureOr<int?>?) = NonNull(FutureOr<NonNull(int?)>?)
+    //                              = FutureOr<int>
+    //
+    // would be wrong since it would compute that the awaited result could not
+    // be `null`.
+
+    if (node.declaredNullability == Nullability.nonNullable) {
       return null;
     }
-    return new FutureOrType(
-        typeArgument ?? node.typeArgument, Nullability.nonNullable);
+    return new FutureOrType(node.typeArgument, Nullability.nonNullable);
   }
 
   @override
   DartType? visitInterfaceType(InterfaceType node) {
+    // NonNull(C<T1, ... , Tn>) = C<T1, ... , Tn> for class C other
+    // than Null (including Object).
+    //
+    // NonNull(Function) = Function
+    //
+    // NonNull(T?) = NonNull(T)
+    //
+    // NonNull(T*) = NonNull(T)
+    if (node.declaredNullability == Nullability.nonNullable) {
+      return null;
+    }
+    return node.withDeclaredNullability(Nullability.nonNullable);
+  }
+
+  @override
+  DartType? visitExtensionType(ExtensionType node) {
+    // NonNull(C<T1, ... , Tn>) = C<T1, ... , Tn> for class C other
+    // than Null (including Object).
+    //
+    // NonNull(T?) = NonNull(T)
+    //
+    // NonNull(T*) = NonNull(T)
     if (node.declaredNullability == Nullability.nonNullable) {
       return null;
     }
@@ -57,6 +113,11 @@
 
   @override
   DartType? visitNeverType(NeverType node) {
+    // NonNull(Never) = Never
+    //
+    // NonNull(T?) = NonNull(T)
+    //
+    // NonNull(T*) = NonNull(T)
     if (node.declaredNullability == Nullability.nonNullable) {
       return null;
     }
@@ -65,15 +126,25 @@
 
   @override
   DartType? visitNullType(NullType node) {
+    // NonNull(Null) = Never
     return const NeverType.nonNullable();
   }
 
   @override
   DartType? visitTypeParameterType(TypeParameterType node) {
+    // NonNull(X) = X & NonNull(B), where B is the bound of X.
+    //
+    // NonNull(X & T) = X & NonNull(T)
+    //
+    // NonNull(T?) = NonNull(T)
+    //
+    // NonNull(T*) = NonNull(T)
     if (node.nullability == Nullability.nonNullable) {
       return null;
     }
     if (node.promotedBound != null) {
+      // NonNull(X & T) = X & NonNull(T)
+
       if (node.promotedBound!.nullability == Nullability.nonNullable) {
         // The promoted bound is already non-nullable so we set the declared
         // nullability to non-nullable.
@@ -100,6 +171,7 @@
             node.parameter, Nullability.undetermined, promotedBound);
       }
     } else {
+      // NonNull(X) = X & NonNull(B), where B is the bound of X.
       if (node.bound.nullability == Nullability.nonNullable) {
         // The bound is already non-nullable so we set the declared nullability
         // to non-nullable.
@@ -126,6 +198,12 @@
 
   @override
   DartType? visitTypedefType(TypedefType node) {
+    // NonNull(C<T1, ... , Tn>) = C<T1, ... , Tn> for class C other
+    // than Null (including Object).
+    //
+    // NonNull(T?) = NonNull(T)
+    //
+    // NonNull(T*) = NonNull(T)
     if (node.declaredNullability == Nullability.nonNullable) {
       return null;
     }
@@ -133,5 +211,8 @@
   }
 
   @override
-  DartType? visitVoidType(VoidType node) => null;
+  DartType? visitVoidType(VoidType node) {
+    // NonNull(void) = void
+    return null;
+  }
 }
diff --git a/pkg/kernel/lib/src/replacement_visitor.dart b/pkg/kernel/lib/src/replacement_visitor.dart
index b3defb8..a3db97a2 100644
--- a/pkg/kernel/lib/src/replacement_visitor.dart
+++ b/pkg/kernel/lib/src/replacement_visitor.dart
@@ -268,5 +268,35 @@
   }
 
   @override
+  DartType? visitExtensionType(ExtensionType node, int variance) {
+    Nullability? newNullability = visitNullability(node);
+    List<DartType>? newTypeArguments = null;
+    for (int i = 0; i < node.typeArguments.length; i++) {
+      DartType? substitution = node.typeArguments[i].accept1(
+          this,
+          Variance.combine(
+              variance, node.extension.typeParameters[i].variance));
+      if (substitution != null) {
+        newTypeArguments ??= node.typeArguments.toList(growable: false);
+        newTypeArguments[i] = substitution;
+      }
+    }
+    return createExtensionType(node, newNullability, newTypeArguments);
+  }
+
+  DartType? createExtensionType(ExtensionType node, Nullability? newNullability,
+      List<DartType>? newTypeArguments) {
+    if (newNullability == null && newTypeArguments == null) {
+      // No nullability or type arguments needed to be substituted.
+      return null;
+    } else {
+      return new ExtensionType(
+          node.extension,
+          newNullability ?? node.nullability,
+          newTypeArguments ?? node.typeArguments);
+    }
+  }
+
+  @override
   DartType? defaultDartType(DartType node, int variance) => null;
 }
diff --git a/pkg/kernel/lib/target/targets.dart b/pkg/kernel/lib/target/targets.dart
index 27f5eba..2f4eba5 100644
--- a/pkg/kernel/lib/target/targets.dart
+++ b/pkg/kernel/lib/target/targets.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
-
 library kernel.target.targets;
 
 import '../ast.dart';
@@ -66,8 +64,8 @@
   'none': (TargetFlags flags) => new NoneTarget(flags),
 };
 
-Target getTarget(String name, TargetFlags flags) {
-  _TargetBuilder builder = targets[name];
+Target? getTarget(String name, TargetFlags flags) {
+  _TargetBuilder? builder = targets[name];
   if (builder == null) return null;
   return builder(flags);
 }
@@ -241,8 +239,8 @@
       CoreTypes coreTypes,
       List<Library> libraries,
       DiagnosticReporter diagnosticReporter,
-      {void logger(String msg),
-      ChangedStructureNotifier changedStructureNotifier}) {}
+      {void Function(String msg)? logger,
+      ChangedStructureNotifier? changedStructureNotifier}) {}
 
   /// Perform target-specific modular transformations on the given libraries.
   void performModularTransformationsOnLibraries(
@@ -265,7 +263,7 @@
   /// procedure.
   void performTransformationsOnProcedure(
       CoreTypes coreTypes, ClassHierarchy hierarchy, Procedure procedure,
-      {void logger(String msg)}) {}
+      {void Function(String msg)? logger}) {}
 
   /// Whether a platform library may define a restricted type, such as `bool`,
   /// `int`, `double`, `num`, and `String`.
@@ -327,9 +325,14 @@
   ///
   /// This is determined by the [enabledLateLowerings] mask.
   bool isLateFieldLoweringEnabled(
-      {bool hasInitializer, bool isFinal, bool isStatic}) {
+      {required bool hasInitializer,
+      required bool isFinal,
+      required bool isStatic}) {
+    // ignore: unnecessary_null_comparison
     assert(hasInitializer != null);
+    // ignore: unnecessary_null_comparison
     assert(isFinal != null);
+    // ignore: unnecessary_null_comparison
     assert(isStatic != null);
     int mask = LateLowering.getFieldLowering(
         hasInitializer: hasInitializer, isFinal: isFinal, isStatic: isStatic);
@@ -341,9 +344,14 @@
   ///
   /// This is determined by the [enabledLateLowerings] mask.
   bool isLateLocalLoweringEnabled(
-      {bool hasInitializer, bool isFinal, bool isPotentiallyNullable}) {
+      {required bool hasInitializer,
+      required bool isFinal,
+      required bool isPotentiallyNullable}) {
+    // ignore: unnecessary_null_comparison
     assert(hasInitializer != null);
+    // ignore: unnecessary_null_comparison
     assert(isFinal != null);
+    // ignore: unnecessary_null_comparison
     assert(isPotentiallyNullable != null);
     int mask = LateLowering.getLocalLowering(
         hasInitializer: hasInitializer,
@@ -399,15 +407,15 @@
 
   String toString() => 'Target($name)';
 
-  Class concreteListLiteralClass(CoreTypes coreTypes) => null;
-  Class concreteConstListLiteralClass(CoreTypes coreTypes) => null;
+  Class? concreteListLiteralClass(CoreTypes coreTypes) => null;
+  Class? concreteConstListLiteralClass(CoreTypes coreTypes) => null;
 
-  Class concreteMapLiteralClass(CoreTypes coreTypes) => null;
-  Class concreteConstMapLiteralClass(CoreTypes coreTypes) => null;
+  Class? concreteMapLiteralClass(CoreTypes coreTypes) => null;
+  Class? concreteConstMapLiteralClass(CoreTypes coreTypes) => null;
 
-  Class concreteIntLiteralClass(CoreTypes coreTypes, int value) => null;
-  Class concreteDoubleLiteralClass(CoreTypes coreTypes, double value) => null;
-  Class concreteStringLiteralClass(CoreTypes coreTypes, String value) => null;
+  Class? concreteIntLiteralClass(CoreTypes coreTypes, int value) => null;
+  Class? concreteDoubleLiteralClass(CoreTypes coreTypes, double value) => null;
+  Class? concreteStringLiteralClass(CoreTypes coreTypes, String value) => null;
 
   ConstantsBackend constantsBackend(CoreTypes coreTypes);
 }
@@ -416,7 +424,7 @@
   @override
   final bool supportsUnevaluatedConstants;
 
-  const NoneConstantsBackend({this.supportsUnevaluatedConstants});
+  const NoneConstantsBackend({required this.supportsUnevaluatedConstants});
 }
 
 class NoneTarget extends Target {
@@ -456,8 +464,8 @@
       Map<String, String> environmentDefines,
       DiagnosticReporter diagnosticReporter,
       ReferenceFromIndex referenceFromIndex,
-      {void logger(String msg),
-      ChangedStructureNotifier changedStructureNotifier}) {}
+      {void Function(String msg)? logger,
+      ChangedStructureNotifier? changedStructureNotifier}) {}
 
   @override
   Expression instantiateInvocation(CoreTypes coreTypes, Expression receiver,
@@ -509,9 +517,14 @@
   static const int all = (1 << 16) - 1;
 
   static int getLocalLowering(
-      {bool hasInitializer, bool isFinal, bool isPotentiallyNullable}) {
+      {required bool hasInitializer,
+      required bool isFinal,
+      required bool isPotentiallyNullable}) {
+    // ignore: unnecessary_null_comparison
     assert(hasInitializer != null);
+    // ignore: unnecessary_null_comparison
     assert(isFinal != null);
+    // ignore: unnecessary_null_comparison
     assert(isPotentiallyNullable != null);
     if (hasInitializer) {
       if (isFinal) {
@@ -545,9 +558,14 @@
   }
 
   static int getFieldLowering(
-      {bool hasInitializer, bool isFinal, bool isStatic}) {
+      {required bool hasInitializer,
+      required bool isFinal,
+      required bool isStatic}) {
+    // ignore: unnecessary_null_comparison
     assert(hasInitializer != null);
+    // ignore: unnecessary_null_comparison
     assert(isFinal != null);
+    // ignore: unnecessary_null_comparison
     assert(isStatic != null);
     if (hasInitializer) {
       if (isFinal) {
diff --git a/pkg/kernel/lib/text/ast_to_text.dart b/pkg/kernel/lib/text/ast_to_text.dart
index f8ffce6..0718f76 100644
--- a/pkg/kernel/lib/text/ast_to_text.dart
+++ b/pkg/kernel/lib/text/ast_to_text.dart
@@ -1016,8 +1016,8 @@
     if (name.name.startsWith('@')) throw 'unexpected @';
 
     String libraryString(CanonicalName lib) {
-      if (lib.reference?.node != null) {
-        return getLibraryReference(lib.reference!.asLibrary);
+      if (lib.reference.node != null) {
+        return getLibraryReference(lib.reference.asLibrary);
       }
       return syntheticNames.nameCanonicalNameAsLibraryPrefix(
           lib.reference, lib);
@@ -1334,6 +1334,7 @@
   }
 
   visitExtension(Extension node) {
+    writeAnnotationList(node.annotations);
     writeIndentation();
     writeWord('extension');
     writeWord(getExtensionName(node));
@@ -1497,15 +1498,24 @@
     writeSymbol('}');
   }
 
+  visitInstanceGetterInvocation(InstanceGetterInvocation node) {
+    writeExpression(node.receiver, Precedence.PRIMARY);
+    writeSymbol('.');
+    writeInterfaceTarget(node.name, node.interfaceTargetReference);
+    _writeInstanceAccessKind(node.kind);
+    writeNode(node.arguments);
+    if (node.functionType != null) {
+      writeSymbol('{');
+      writeType(node.functionType!);
+      writeSymbol('}');
+    }
+  }
+
   visitEqualsCall(EqualsCall node) {
     int precedence = Precedence.EQUALITY;
     writeExpression(node.left, precedence);
     writeSpace();
-    if (node.isNot) {
-      writeSymbol('!=');
-    } else {
-      writeSymbol('==');
-    }
+    writeSymbol('==');
     writeInterfaceTarget(Name.equalsName, node.interfaceTargetReference);
     writeSymbol('{');
     writeType(node.functionType);
@@ -1517,11 +1527,7 @@
   visitEqualsNull(EqualsNull node) {
     writeExpression(node.expression, Precedence.EQUALITY);
     writeSpace();
-    if (node.isNot) {
-      writeSymbol('!=');
-    } else {
-      writeSymbol('==');
-    }
+    writeSymbol('==');
     writeSpace();
     writeSymbol('null');
   }
@@ -2444,6 +2450,17 @@
     writeNullability(node.nullability);
   }
 
+  visitExtensionType(ExtensionType node) {
+    writeExtensionReferenceFromReference(node.extensionReference);
+    if (node.typeArguments.isNotEmpty) {
+      writeSymbol('<');
+      writeList(node.typeArguments, writeType);
+      writeSymbol('>');
+      state = Printer.WORD;
+    }
+    writeNullability(node.declaredNullability);
+  }
+
   visitFutureOrType(FutureOrType node) {
     writeWord('FutureOr');
     writeSymbol('<');
@@ -2739,6 +2756,9 @@
   int visitInstanceInvocation(InstanceInvocation node) => CALLEE;
 
   @override
+  int visitInstanceGetterInvocation(InstanceGetterInvocation node) => CALLEE;
+
+  @override
   int visitDynamicInvocation(DynamicInvocation node) => CALLEE;
 
   @override
diff --git a/pkg/kernel/lib/text/serializer_combinators.dart b/pkg/kernel/lib/text/serializer_combinators.dart
index 3bd9e1d..7179336 100644
--- a/pkg/kernel/lib/text/serializer_combinators.dart
+++ b/pkg/kernel/lib/text/serializer_combinators.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
-
 library kernel.serializer_combinators;
 
 import 'dart:convert' show json;
@@ -13,7 +11,7 @@
 import 'text_serializer.dart' show Tagger;
 
 class DeserializationEnvironment<T extends Node> {
-  final DeserializationEnvironment<T> parent;
+  final DeserializationEnvironment<T>? parent;
 
   final Map<String, T> locals = <String, T>{};
 
@@ -23,7 +21,10 @@
 
   DeserializationEnvironment(this.parent);
 
-  T lookup(String name) => locals[name] ?? parent?.lookup(name);
+  T lookup(String name) =>
+      locals[name] ??
+      parent?.lookup(name) ??
+      (throw StateError("No local '${name}' found in this scope."));
 
   T addBinder(T node, String distinctName) {
     if (lookupDistinctName(node) != null) {
@@ -40,13 +41,13 @@
     binders.clear();
   }
 
-  String lookupDistinctName(T object) {
+  String? lookupDistinctName(T object) {
     return distinctNames[object] ?? parent?.lookupDistinctName(object);
   }
 }
 
 class SerializationEnvironment<T extends Node> {
-  final SerializationEnvironment<T> parent;
+  final SerializationEnvironment<T>? parent;
 
   final Map<T, String> locals = new Map<T, String>.identity();
 
@@ -58,9 +59,12 @@
 
   SerializationEnvironment(this.parent) : nameCount = parent?.nameCount ?? 0;
 
-  String lookup(T node) => locals[node] ?? parent?.lookup(node);
+  String lookup(T node) =>
+      locals[node] ??
+      parent?.lookup(node) ??
+      (throw StateError("No name for ${node} found in this scope."));
 
-  String addBinder(T node, {String nameClue}) {
+  String addBinder(T node, {String? nameClue}) {
     final String separator = "^";
     final int codeOfZero = "0".codeUnitAt(0);
     final int codeOfNine = "9".codeUnitAt(0);
@@ -100,7 +104,7 @@
     binders.clear();
   }
 
-  String lookupDistinctName(T object) {
+  String? lookupDistinctName(T object) {
     return distinctNames[object] ?? parent?.lookupDistinctName(object);
   }
 }
@@ -121,8 +125,8 @@
 abstract class TextSerializer<T> {
   const TextSerializer();
 
-  T readFrom(Iterator<Object> stream, DeserializationState state);
-  void writeTo(StringBuffer buffer, T object, SerializationState state);
+  T readFrom(Iterator<Object?> stream, DeserializationState? state);
+  void writeTo(StringBuffer buffer, T object, SerializationState? state);
 
   /// True if this serializer/deserializer writes/reads nothing.  This is true
   /// for the serializer [Nothing] and also some serializers derived from it.
@@ -132,9 +136,9 @@
 class Nothing extends TextSerializer<void> {
   const Nothing();
 
-  void readFrom(Iterator<Object> stream, DeserializationState _) {}
+  void readFrom(Iterator<Object?> stream, DeserializationState? _) {}
 
-  void writeTo(StringBuffer buffer, void ignored, SerializationState _) {}
+  void writeTo(StringBuffer buffer, void ignored, SerializationState? _) {}
 
   bool get isEmpty => true;
 }
@@ -142,16 +146,17 @@
 class DartString extends TextSerializer<String> {
   const DartString();
 
-  String readFrom(Iterator<Object> stream, DeserializationState _) {
-    if (stream.current is! String) {
-      throw StateError("Expected an atom, found a list: '${stream.current}'.");
+  String readFrom(Iterator<Object?> stream, DeserializationState? _) {
+    Object? current = stream.current;
+    if (current is! String) {
+      throw StateError("Expected an atom, found a list: '${current}'.");
     }
-    String result = json.decode(stream.current);
+    String result = json.decode(current);
     stream.moveNext();
     return result;
   }
 
-  void writeTo(StringBuffer buffer, String object, SerializationState _) {
+  void writeTo(StringBuffer buffer, String object, SerializationState? _) {
     buffer.write(json.encode(object));
   }
 }
@@ -159,16 +164,17 @@
 class DartInt extends TextSerializer<int> {
   const DartInt();
 
-  int readFrom(Iterator<Object> stream, DeserializationState _) {
-    if (stream.current is! String) {
-      throw StateError("Expected an atom, found a list: '${stream.current}'.");
+  int readFrom(Iterator<Object?> stream, DeserializationState? _) {
+    Object? current = stream.current;
+    if (current is! String) {
+      throw StateError("Expected an atom, found a list: '${current}'.");
     }
-    int result = int.parse(stream.current);
+    int result = int.parse(current);
     stream.moveNext();
     return result;
   }
 
-  void writeTo(StringBuffer buffer, int object, SerializationState _) {
+  void writeTo(StringBuffer buffer, int object, SerializationState? _) {
     buffer.write(object);
   }
 }
@@ -176,16 +182,17 @@
 class DartDouble extends TextSerializer<double> {
   const DartDouble();
 
-  double readFrom(Iterator<Object> stream, DeserializationState _) {
-    if (stream.current is! String) {
-      throw StateError("Expected an atom, found a list: '${stream.current}'.");
+  double readFrom(Iterator<Object?> stream, DeserializationState? _) {
+    Object? current = stream.current;
+    if (current is! String) {
+      throw StateError("Expected an atom, found a list: '${current}'.");
     }
-    double result = double.parse(stream.current);
+    double result = double.parse(current);
     stream.moveNext();
     return result;
   }
 
-  void writeTo(StringBuffer buffer, double object, SerializationState _) {
+  void writeTo(StringBuffer buffer, double object, SerializationState? _) {
     buffer.write(object);
   }
 }
@@ -193,23 +200,24 @@
 class DartBool extends TextSerializer<bool> {
   const DartBool();
 
-  bool readFrom(Iterator<Object> stream, DeserializationState _) {
-    if (stream.current is! String) {
-      throw StateError("Expected an atom, found a list: '${stream.current}'.");
+  bool readFrom(Iterator<Object?> stream, DeserializationState? _) {
+    Object? current = stream.current;
+    if (current is! String) {
+      throw StateError("Expected an atom, found a list: '${current}'.");
     }
     bool result;
-    if (stream.current == "true") {
+    if (current == "true") {
       result = true;
-    } else if (stream.current == "false") {
+    } else if (current == "false") {
       result = false;
     } else {
-      throw StateError("Expected 'true' or 'false', found '${stream.current}'");
+      throw StateError("Expected 'true' or 'false', found '${current}'");
     }
     stream.moveNext();
     return result;
   }
 
-  void writeTo(StringBuffer buffer, bool object, SerializationState _) {
+  void writeTo(StringBuffer buffer, bool object, SerializationState? _) {
     buffer.write(object ? 'true' : 'false');
   }
 }
@@ -217,12 +225,12 @@
 class UriSerializer extends TextSerializer<Uri> {
   const UriSerializer();
 
-  Uri readFrom(Iterator<Object> stream, DeserializationState state) {
+  Uri readFrom(Iterator<Object?> stream, DeserializationState? state) {
     String uriAsString = const DartString().readFrom(stream, state);
     return Uri.parse(uriAsString);
   }
 
-  void writeTo(StringBuffer buffer, Uri object, SerializationState state) {
+  void writeTo(StringBuffer buffer, Uri object, SerializationState? state) {
     const DartString().writeTo(buffer, object.toString(), state);
   }
 }
@@ -250,23 +258,24 @@
     _serializers.addAll(tagsAndSerializers.values);
   }
 
-  T readFrom(Iterator<Object> stream, DeserializationState state) {
-    if (stream.current is! Iterator) {
-      throw StateError("Expected list, found atom: '${stream.current}'.");
+  T readFrom(Iterator<Object?> stream, DeserializationState? state) {
+    Object? iterator = stream.current;
+    if (iterator is! Iterator<Object?>) {
+      throw StateError("Expected list, found atom: '${iterator}'.");
     }
-    Iterator nested = stream.current;
-    nested.moveNext();
-    if (nested.current is! String) {
-      throw StateError("Expected atom, found list: '${nested.current}'.");
+    iterator.moveNext();
+    Object? element = iterator.current;
+    if (element is! String) {
+      throw StateError("Expected atom, found list: '${element}'.");
     }
-    String tag = nested.current;
+    String tag = element;
     for (int i = 0; i < _tags.length; ++i) {
       if (_tags[i] == tag) {
-        nested.moveNext();
-        T result = _serializers[i].readFrom(nested, state);
-        if (nested.moveNext()) {
+        iterator.moveNext();
+        T result = _serializers[i].readFrom(iterator, state);
+        if (iterator.moveNext()) {
           throw StateError(
-              "Extra data in tagged '${tag}': '${nested.current}'.");
+              "Extra data in tagged '${tag}': '${iterator.current}'.");
         }
         stream.moveNext();
         return result;
@@ -275,7 +284,7 @@
     throw StateError("Unrecognized tag '${tag}'.");
   }
 
-  void writeTo(StringBuffer buffer, T object, SerializationState state) {
+  void writeTo(StringBuffer buffer, T object, SerializationState? state) {
     String tag = tagger.tag(object);
     for (int i = 0; i < _tags.length; ++i) {
       if (_tags[i] == tag) {
@@ -301,11 +310,11 @@
 
   const Wrapped(this.unwrap, this.wrap, this.contents);
 
-  K readFrom(Iterator<Object> stream, DeserializationState state) {
+  K readFrom(Iterator<Object?> stream, DeserializationState? state) {
     return wrap(contents.readFrom(stream, state));
   }
 
-  void writeTo(StringBuffer buffer, K object, SerializationState state) {
+  void writeTo(StringBuffer buffer, K object, SerializationState? state) {
     contents.writeTo(buffer, unwrap(object), state);
   }
 
@@ -317,11 +326,20 @@
 
   const ScopedUse();
 
-  T readFrom(Iterator<Object> stream, DeserializationState state) {
-    return state.environment.lookup(stringSerializer.readFrom(stream, null));
+  T readFrom(Iterator<Object?> stream, DeserializationState? state) {
+    if (state == null) {
+      throw StateError(
+          "No deserialization state provided for ${runtimeType}.readFrom.");
+    }
+    return state.environment.lookup(stringSerializer.readFrom(stream, null))
+        as T;
   }
 
-  void writeTo(StringBuffer buffer, T object, SerializationState state) {
+  void writeTo(StringBuffer buffer, T object, SerializationState? state) {
+    if (state == null) {
+      throw StateError(
+          "No serialization state provided for ${runtimeType}.writeTo.");
+    }
     stringSerializer.writeTo(buffer, state.environment.lookup(object), null);
   }
 }
@@ -333,13 +351,14 @@
 
   const Tuple2Serializer(this.first, this.second);
 
-  Tuple2<T1, T2> readFrom(Iterator<Object> stream, DeserializationState state) {
+  Tuple2<T1, T2> readFrom(
+      Iterator<Object?> stream, DeserializationState? state) {
     return new Tuple2(
         first.readFrom(stream, state), second.readFrom(stream, state));
   }
 
   void writeTo(
-      StringBuffer buffer, Tuple2<T1, T2> object, SerializationState state) {
+      StringBuffer buffer, Tuple2<T1, T2> object, SerializationState? state) {
     first.writeTo(buffer, object.first, state);
     if (!second.isEmpty) buffer.write(' ');
     second.writeTo(buffer, object.second, state);
@@ -361,13 +380,13 @@
   const Tuple3Serializer(this.first, this.second, this.third);
 
   Tuple3<T1, T2, T3> readFrom(
-      Iterator<Object> stream, DeserializationState state) {
+      Iterator<Object?> stream, DeserializationState? state) {
     return new Tuple3(first.readFrom(stream, state),
         second.readFrom(stream, state), third.readFrom(stream, state));
   }
 
   void writeTo(StringBuffer buffer, Tuple3<T1, T2, T3> object,
-      SerializationState state) {
+      SerializationState? state) {
     first.writeTo(buffer, object.first, state);
     if (!second.isEmpty) buffer.write(' ');
     second.writeTo(buffer, object.second, state);
@@ -394,7 +413,7 @@
   const Tuple4Serializer(this.first, this.second, this.third, this.fourth);
 
   Tuple4<T1, T2, T3, T4> readFrom(
-      Iterator<Object> stream, DeserializationState state) {
+      Iterator<Object?> stream, DeserializationState? state) {
     return new Tuple4(
         first.readFrom(stream, state),
         second.readFrom(stream, state),
@@ -403,7 +422,7 @@
   }
 
   void writeTo(StringBuffer buffer, Tuple4<T1, T2, T3, T4> object,
-      SerializationState state) {
+      SerializationState? state) {
     first.writeTo(buffer, object.first, state);
     if (!second.isEmpty) buffer.write(' ');
     second.writeTo(buffer, object.second, state);
@@ -435,7 +454,7 @@
       this.first, this.second, this.third, this.fourth, this.fifth);
 
   Tuple5<T1, T2, T3, T4, T5> readFrom(
-      Iterator<Object> stream, DeserializationState state) {
+      Iterator<Object?> stream, DeserializationState? state) {
     return new Tuple5(
         first.readFrom(stream, state),
         second.readFrom(stream, state),
@@ -445,7 +464,7 @@
   }
 
   void writeTo(StringBuffer buffer, Tuple5<T1, T2, T3, T4, T5> object,
-      SerializationState state) {
+      SerializationState? state) {
     first.writeTo(buffer, object.first, state);
     if (!second.isEmpty) buffer.write(' ');
     second.writeTo(buffer, object.second, state);
@@ -481,7 +500,7 @@
       this.first, this.second, this.third, this.fourth, this.fifth, this.sixth);
 
   Tuple6<T1, T2, T3, T4, T5, T6> readFrom(
-      Iterator<Object> stream, DeserializationState state) {
+      Iterator<Object?> stream, DeserializationState? state) {
     return new Tuple6(
         first.readFrom(stream, state),
         second.readFrom(stream, state),
@@ -492,7 +511,7 @@
   }
 
   void writeTo(StringBuffer buffer, Tuple6<T1, T2, T3, T4, T5, T6> object,
-      SerializationState state) {
+      SerializationState? state) {
     first.writeTo(buffer, object.first, state);
     if (!second.isEmpty) buffer.write(' ');
     second.writeTo(buffer, object.second, state);
@@ -533,7 +552,7 @@
       this.fifth, this.sixth, this.seventh);
 
   Tuple7<T1, T2, T3, T4, T5, T6, T7> readFrom(
-      Iterator<Object> stream, DeserializationState state) {
+      Iterator<Object?> stream, DeserializationState? state) {
     return new Tuple7(
         first.readFrom(stream, state),
         second.readFrom(stream, state),
@@ -545,7 +564,7 @@
   }
 
   void writeTo(StringBuffer buffer, Tuple7<T1, T2, T3, T4, T5, T6, T7> object,
-      SerializationState state) {
+      SerializationState? state) {
     first.writeTo(buffer, object.first, state);
     if (!second.isEmpty) buffer.write(' ');
     second.writeTo(buffer, object.second, state);
@@ -581,21 +600,21 @@
 
   const ListSerializer(this.elements);
 
-  List<T> readFrom(Iterator<Object> stream, DeserializationState state) {
-    if (stream.current is! Iterator) {
-      throw StateError("Expected a list, found an atom: '${stream.current}'.");
+  List<T> readFrom(Iterator<Object?> stream, DeserializationState? state) {
+    Object? iterator = stream.current;
+    if (iterator is! Iterator<Object?>) {
+      throw StateError("Expected a list, found an atom: '${iterator}'.");
     }
-    Iterator<Object> list = stream.current;
-    list.moveNext();
+    iterator.moveNext();
     List<T> result = [];
-    while (list.current != null) {
-      result.add(elements.readFrom(list, state));
+    while (iterator.current != null) {
+      result.add(elements.readFrom(iterator, state));
     }
     stream.moveNext();
     return result;
   }
 
-  void writeTo(StringBuffer buffer, List<T> object, SerializationState state) {
+  void writeTo(StringBuffer buffer, List<T> object, SerializationState? state) {
     buffer.write('(');
     for (int i = 0; i < object.length; ++i) {
       if (i != 0) buffer.write(' ');
@@ -605,12 +624,12 @@
   }
 }
 
-class Optional<T> extends TextSerializer<T> {
+class Optional<T> extends TextSerializer<T?> {
   final TextSerializer<T> contents;
 
   const Optional(this.contents);
 
-  T readFrom(Iterator<Object> stream, DeserializationState state) {
+  T? readFrom(Iterator<Object?> stream, DeserializationState? state) {
     if (stream.current == '_') {
       stream.moveNext();
       return null;
@@ -618,7 +637,7 @@
     return contents.readFrom(stream, state);
   }
 
-  void writeTo(StringBuffer buffer, T object, SerializationState state) {
+  void writeTo(StringBuffer buffer, T? object, SerializationState? state) {
     if (object == null) {
       buffer.write('_');
     } else {
@@ -639,7 +658,11 @@
       : namedContents = new Tuple2Serializer(const DartString(), contents);
 
   Tuple2<String, T> readFrom(
-      Iterator<Object> stream, DeserializationState state) {
+      Iterator<Object?> stream, DeserializationState? state) {
+    if (state == null) {
+      throw StateError(
+          "No deserialization state provided for ${runtimeType}.readFrom.");
+    }
     Tuple2<String, T> namedObject = namedContents.readFrom(stream, state);
     String name = namedObject.first;
     T object = namedObject.second;
@@ -648,7 +671,11 @@
   }
 
   void writeTo(StringBuffer buffer, Tuple2<String, T> namedObject,
-      SerializationState state) {
+      SerializationState? state) {
+    if (state == null) {
+      throw StateError(
+          "No serialization state provided for ${runtimeType}.writeTo.");
+    }
     String nameClue = namedObject.first;
     T object = namedObject.second;
     String distinctName =
@@ -668,7 +695,11 @@
 
   const Bind(this.pattern, this.term);
 
-  Tuple2<P, T> readFrom(Iterator<Object> stream, DeserializationState state) {
+  Tuple2<P, T> readFrom(Iterator<Object?> stream, DeserializationState? state) {
+    if (state == null) {
+      throw StateError(
+          "No deserialization state provided for ${runtimeType}.readFrom.");
+    }
     DeserializationState bindingState = new DeserializationState(
         new DeserializationEnvironment(state.environment), state.nameRoot);
     P first = pattern.readFrom(stream, bindingState);
@@ -678,7 +709,11 @@
   }
 
   void writeTo(
-      StringBuffer buffer, Tuple2<P, T> tuple, SerializationState state) {
+      StringBuffer buffer, Tuple2<P, T> tuple, SerializationState? state) {
+    if (state == null) {
+      throw StateError(
+          "No serialization state provided for ${runtimeType}.writeTo.");
+    }
     SerializationState bindingState =
         new SerializationState(new SerializationEnvironment(state.environment));
     pattern.writeTo(buffer, tuple.first, bindingState);
@@ -699,7 +734,11 @@
 
   const Rebind(this.pattern1, this.pattern2);
 
-  Tuple2<P, T> readFrom(Iterator<Object> stream, DeserializationState state) {
+  Tuple2<P, T> readFrom(Iterator<Object?> stream, DeserializationState? state) {
+    if (state == null) {
+      throw StateError(
+          "No deserialization state provided for ${runtimeType}.readFrom.");
+    }
     P first = pattern1.readFrom(stream, state);
     DeserializationState closedState = new DeserializationState(
         new DeserializationEnvironment(state.environment)
@@ -712,7 +751,11 @@
   }
 
   void writeTo(
-      StringBuffer buffer, Tuple2<P, T> tuple, SerializationState state) {
+      StringBuffer buffer, Tuple2<P, T> tuple, SerializationState? state) {
+    if (state == null) {
+      throw StateError(
+          "No serialization state provided for ${runtimeType}.writeTo.");
+    }
     pattern1.writeTo(buffer, tuple.first, state);
     SerializationState closedState =
         new SerializationState(new SerializationEnvironment(state.environment)
@@ -731,24 +774,38 @@
 
   const Zip(this.lists, this.zip, this.unzip);
 
-  List<T> readFrom(Iterator<Object> stream, DeserializationState state) {
+  List<T> readFrom(Iterator<Object?> stream, DeserializationState? state) {
     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>.filled(toZip.first.length, null);
-    for (int i = 0; i < zipped.length; ++i) {
-      zipped[i] = zip(firsts[i], seconds[i]);
+    List<T> zipped;
+    if (firsts.isEmpty) {
+      zipped = <T>[];
+    } else {
+      List<T2> seconds = toZip.second;
+      zipped =
+          new List<T>.filled(toZip.first.length, zip(firsts[0], seconds[0]));
+      for (int i = 1; i < zipped.length; ++i) {
+        zipped[i] = zip(firsts[i], seconds[i]);
+      }
     }
     return zipped;
   }
 
-  void writeTo(StringBuffer buffer, List<T> zipped, SerializationState state) {
-    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;
-      seconds[i] = tuple.second;
+  void writeTo(StringBuffer buffer, List<T> zipped, SerializationState? state) {
+    List<T1> firsts;
+    List<T2> seconds;
+    if (zipped.isEmpty) {
+      firsts = <T1>[];
+      seconds = <T2>[];
+    } else {
+      Tuple2<T1, T2> initial = unzip(zipped[0]);
+      firsts = new List<T1>.filled(zipped.length, initial.first);
+      seconds = new List<T2>.filled(zipped.length, initial.second);
+      for (int i = 1; i < zipped.length; ++i) {
+        Tuple2<T1, T2> tuple = unzip(zipped[i]);
+        firsts[i] = tuple.first;
+        seconds[i] = tuple.second;
+      }
     }
     lists.writeTo(buffer, new Tuple2(firsts, seconds), state);
   }
diff --git a/pkg/kernel/lib/text/text_serialization_verifier.dart b/pkg/kernel/lib/text/text_serialization_verifier.dart
index 0298ad7..dab2bc7 100644
--- a/pkg/kernel/lib/text/text_serialization_verifier.dart
+++ b/pkg/kernel/lib/text/text_serialization_verifier.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:convert' show json;
 
 import '../ast.dart';
@@ -14,7 +12,7 @@
 
 import '../text/text_serializer.dart';
 
-const Uri noUri = null;
+const Uri? noUri = null;
 
 const int noOffset = -1;
 
@@ -28,12 +26,12 @@
   /// round-trip serialization failed on or to the closest parent with location.
   final TreeNode context;
 
-  RoundTripStatus(this.node, {TreeNode context})
+  RoundTripStatus(this.node, {required TreeNode context})
       : context = node is TreeNode && node.location != null ? node : context;
 
-  Uri get uri => context?.location?.file;
+  Uri? get uri => context.location?.file;
 
-  int get offset => context?.fileOffset;
+  int get offset => context.fileOffset;
 
   bool get isSuccess;
 
@@ -42,11 +40,11 @@
   String get nameForDebugging;
 
   int compareTo(RoundTripStatus other) {
-    if (node is TreeNode && other.node is TreeNode) {
-      TreeNode thisNode = this.node;
-      TreeNode otherNode = other.node;
-      Uri thisUri = thisNode.location?.file;
-      Uri otherUri = otherNode.location?.file;
+    Node thisNode = this.node;
+    Node otherNode = other.node;
+    if (thisNode is TreeNode && otherNode is TreeNode) {
+      Uri? thisUri = thisNode.location?.file;
+      Uri? otherUri = otherNode.location?.file;
       int thisOffset = thisNode.fileOffset;
       int otherOffset = otherNode.fileOffset;
 
@@ -58,16 +56,20 @@
       } else if (otherUri == null) {
         compareUri = -1;
       } else {
+        // ignore: unnecessary_null_comparison
         assert(thisUri != null && otherUri != null);
         compareUri = thisUri.toString().compareTo(otherUri.toString());
       }
       if (compareUri != 0) return compareUri;
 
       int compareOffset;
+      // ignore: unnecessary_null_comparison
       if (thisOffset == null && otherOffset == null) {
         compareOffset = 0;
+        // ignore: unnecessary_null_comparison
       } else if (thisOffset == null) {
         compareOffset = 1;
+        // ignore: unnecessary_null_comparison
       } else if (otherOffset == null) {
         compareOffset = -1;
       } else {
@@ -99,12 +101,12 @@
     sb.writeln("Status: ${nameForDebugging}");
     sb.writeln("Node type: ${node.runtimeType}");
     sb.writeln("Node: ${json.encode(node.leakingDebugToString())}");
-    if (node is TreeNode) {
-      TreeNode treeNode = node;
+    Node treeNode = node;
+    if (treeNode is TreeNode) {
       if (treeNode.parent != null) {
         sb.writeln("Parent type: ${treeNode.parent.runtimeType}");
         sb.writeln(
-            "Parent: ${json.encode(treeNode.parent.leakingDebugToString())}");
+            "Parent: ${json.encode(treeNode.parent!.leakingDebugToString())}");
       }
     }
   }
@@ -119,7 +121,7 @@
 class RoundTripSuccess extends RoundTripStatus {
   final String serialized;
 
-  RoundTripSuccess(Node node, this.serialized, {TreeNode context})
+  RoundTripSuccess(Node node, this.serialized, {required TreeNode context})
       : super(node, context: context);
 
   @override
@@ -139,7 +141,7 @@
   final String message;
 
   RoundTripInitialSerializationFailure(Node node, this.message,
-      {TreeNode context})
+      {required TreeNode context})
       : super(node, context: context);
 
   @override
@@ -158,7 +160,8 @@
 class RoundTripDeserializationFailure extends RoundTripStatus {
   final String message;
 
-  RoundTripDeserializationFailure(Node node, this.message, {TreeNode context})
+  RoundTripDeserializationFailure(Node node, this.message,
+      {required TreeNode context})
       : super(node, context: context);
 
   @override
@@ -179,7 +182,7 @@
   final String serialized;
 
   RoundTripSecondSerializationFailure(Node node, this.initial, this.serialized,
-      {TreeNode context})
+      {required TreeNode context})
       : super(node, context: context);
 
   @override
@@ -206,7 +209,7 @@
 
   final CanonicalName root;
 
-  TextSerializationVerifier({CanonicalName root})
+  TextSerializationVerifier({CanonicalName? root})
       : root = root ?? new CanonicalName.root() {
     initializeSerializers();
   }
@@ -220,7 +223,7 @@
     makeRoundTrip<Library>(node, librarySerializer);
   }
 
-  T readNode<T extends TreeNode>(
+  T? readNode<T extends TreeNode>(
       T node, String input, TextSerializer<T> serializer) {
     TextIterator stream = new TextIterator(input, 0);
     stream.moveNext();
@@ -240,6 +243,7 @@
           node, "unexpected trailing text",
           context: node));
     }
+    // ignore: unnecessary_null_comparison
     if (result == null) {
       _status.add(new RoundTripDeserializationFailure(
           node, "Deserialization of the following returned null: '${input}'",
@@ -270,7 +274,7 @@
     }
 
     // Do the round trip.
-    T deserialized = readNode(node, initial, serializer);
+    T? deserialized = readNode(node, initial, serializer);
     if (_failures.length != failureCount) {
       return;
     }
diff --git a/pkg/kernel/lib/text/text_serializer.dart b/pkg/kernel/lib/text/text_serializer.dart
index 7e0ad34..86e8127 100644
--- a/pkg/kernel/lib/text/text_serializer.dart
+++ b/pkg/kernel/lib/text/text_serializer.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
-
 library kernel.text_serializer;
 
 import '../ast.dart';
@@ -23,11 +21,11 @@
 }
 
 TextSerializer<Name> publicName =
-    Wrapped((w) => w.text, (u) => Name(u), const DartString());
+    Wrapped<String, Name>((w) => w.text, (u) => Name(u), const DartString());
 
 TextSerializer<Name> privateName = Wrapped<Tuple2<String, CanonicalName>, Name>(
-    (w) => Tuple2(w.text, w.library.canonicalName),
-    (u) => Name.byReference(u.first, u.second.getReference()),
+    (w) => Tuple2(w.text, w.library!.reference.canonicalName!),
+    (u) => Name.byReference(u.first, u.second.reference),
     Tuple2Serializer(DartString(), CanonicalNameSerializer()));
 
 TextSerializer<Name> nameSerializer = new Case(
@@ -86,6 +84,8 @@
   String visitSuperPropertySet(SuperPropertySet _) => "set-super";
   String visitMethodInvocation(MethodInvocation _) => "invoke-method";
   String visitInstanceInvocation(InstanceInvocation _) => "invoke-instance";
+  String visitInstanceGetterInvocation(InstanceGetterInvocation _) =>
+      "invoke-instance-getter";
   String visitDynamicInvocation(DynamicInvocation _) => "invoke-dynamic";
   String visitFunctionInvocation(FunctionInvocation _) => "invoke-function";
   String visitLocalFunctionInvocation(LocalFunctionInvocation _) =>
@@ -130,14 +130,14 @@
 }
 
 const TextSerializer<InvalidExpression> invalidExpressionSerializer =
-    const Wrapped(
+    const Wrapped<String?, InvalidExpression>(
         unwrapInvalidExpression, wrapInvalidExpression, const DartString());
 
-String unwrapInvalidExpression(InvalidExpression expression) {
+String? unwrapInvalidExpression(InvalidExpression expression) {
   return expression.message;
 }
 
-InvalidExpression wrapInvalidExpression(String message) {
+InvalidExpression wrapInvalidExpression(String? message) {
   return new InvalidExpression(message);
 }
 
@@ -370,7 +370,7 @@
 Tuple3<DartType, DartType, List<Expression>> unwrapMapLiteral(
     MapLiteral expression) {
   List<Expression> entries =
-      new List.filled(2 * expression.entries.length, null);
+      new List.filled(2 * expression.entries.length, dummyExpression);
   for (int from = 0, to = 0; from < expression.entries.length; ++from) {
     MapEntry entry = expression.entries[from];
     entries[to++] = entry.key;
@@ -380,7 +380,8 @@
 }
 
 MapLiteral wrapMapLiteral(Tuple3<DartType, DartType, List<Expression>> tuple) {
-  List<MapEntry> entries = new List.filled(tuple.third.length ~/ 2, null);
+  List<MapEntry> entries =
+      new List.filled(tuple.third.length ~/ 2, dummyMapEntry);
   for (int from = 0, to = 0; to < entries.length; ++to) {
     entries[to] = new MapEntry(tuple.third[from++], tuple.third[from++]);
   }
@@ -396,7 +397,8 @@
 
 MapLiteral wrapConstMapLiteral(
     Tuple3<DartType, DartType, List<Expression>> tuple) {
-  List<MapEntry> entries = new List.filled(tuple.third.length ~/ 2, null);
+  List<MapEntry> entries =
+      new List.filled(tuple.third.length ~/ 2, dummyMapEntry);
   for (int from = 0, to = 0; to < entries.length; ++to) {
     entries[to] = new MapEntry(tuple.third[from++], tuple.third[from++]);
   }
@@ -448,19 +450,23 @@
     unwrapInstanceGet,
     wrapInstanceGet,
     new Tuple5Serializer(instanceAccessKindSerializer, expressionSerializer,
-        nameSerializer, const CanonicalNameSerializer(), dartTypeSerializer));
+        nameSerializer, canonicalNameSerializer, dartTypeSerializer));
 
 Tuple5<InstanceAccessKind, Expression, Name, CanonicalName, DartType>
     unwrapInstanceGet(InstanceGet expression) {
-  return new Tuple5(expression.kind, expression.receiver, expression.name,
-      expression.interfaceTargetReference.canonicalName, expression.resultType);
+  return new Tuple5(
+      expression.kind,
+      expression.receiver,
+      expression.name,
+      expression.interfaceTargetReference.canonicalName!,
+      expression.resultType);
 }
 
 InstanceGet wrapInstanceGet(
     Tuple5<InstanceAccessKind, Expression, Name, CanonicalName, DartType>
         tuple) {
   return new InstanceGet.byReference(tuple.first, tuple.second, tuple.third,
-      interfaceTargetReference: tuple.fourth.getReference(),
+      interfaceTargetReference: tuple.fourth.reference,
       resultType: tuple.fifth);
 }
 
@@ -470,12 +476,12 @@
     unwrapInstanceSet,
     wrapInstanceSet,
     new Tuple5Serializer(instanceAccessKindSerializer, expressionSerializer,
-        nameSerializer, expressionSerializer, const CanonicalNameSerializer()));
+        nameSerializer, expressionSerializer, canonicalNameSerializer));
 
 Tuple5<InstanceAccessKind, Expression, Name, Expression, CanonicalName>
     unwrapInstanceSet(InstanceSet expression) {
   return new Tuple5(expression.kind, expression.receiver, expression.name,
-      expression.value, expression.interfaceTargetReference.canonicalName);
+      expression.value, expression.interfaceTargetReference.canonicalName!);
 }
 
 InstanceSet wrapInstanceSet(
@@ -483,7 +489,7 @@
         tuple) {
   return new InstanceSet.byReference(
       tuple.first, tuple.second, tuple.third, tuple.fourth,
-      interfaceTargetReference: tuple.fifth.getReference());
+      interfaceTargetReference: tuple.fifth.reference);
 }
 
 TextSerializer<DynamicGet> dynamicGetSerializer =
@@ -526,19 +532,23 @@
     unwrapInstanceTearOff,
     wrapInstanceTearOff,
     new Tuple5Serializer(instanceAccessKindSerializer, expressionSerializer,
-        nameSerializer, const CanonicalNameSerializer(), dartTypeSerializer));
+        nameSerializer, canonicalNameSerializer, dartTypeSerializer));
 
 Tuple5<InstanceAccessKind, Expression, Name, CanonicalName, DartType>
     unwrapInstanceTearOff(InstanceTearOff expression) {
-  return new Tuple5(expression.kind, expression.receiver, expression.name,
-      expression.interfaceTargetReference.canonicalName, expression.resultType);
+  return new Tuple5(
+      expression.kind,
+      expression.receiver,
+      expression.name,
+      expression.interfaceTargetReference.canonicalName!,
+      expression.resultType);
 }
 
 InstanceTearOff wrapInstanceTearOff(
     Tuple5<InstanceAccessKind, Expression, Name, CanonicalName, DartType>
         tuple) {
   return new InstanceTearOff.byReference(tuple.first, tuple.second, tuple.third,
-      interfaceTargetReference: tuple.fourth.getReference(),
+      interfaceTargetReference: tuple.fourth.reference,
       resultType: tuple.fifth);
 }
 
@@ -624,7 +634,7 @@
         expressionSerializer,
         nameSerializer,
         argumentsSerializer,
-        const CanonicalNameSerializer(),
+        canonicalNameSerializer,
         dartTypeSerializer));
 
 Tuple6<InstanceAccessKind, Expression, Name, Arguments, CanonicalName, DartType>
@@ -634,7 +644,7 @@
       expression.receiver,
       expression.name,
       expression.arguments,
-      expression.interfaceTargetReference.canonicalName,
+      expression.interfaceTargetReference.canonicalName!,
       expression.functionType);
 }
 
@@ -644,8 +654,45 @@
         tuple) {
   return new InstanceInvocation.byReference(
       tuple.first, tuple.second, tuple.third, tuple.fourth,
-      interfaceTargetReference: tuple.fifth.getReference(),
-      functionType: tuple.sixth);
+      interfaceTargetReference: tuple.fifth.reference,
+      functionType: tuple.sixth as FunctionType);
+}
+
+TextSerializer<
+    InstanceGetterInvocation> instanceGetterInvocationSerializer = new Wrapped<
+        Tuple6<InstanceAccessKind, Expression, Name, Arguments, CanonicalName,
+            DartType?>,
+        InstanceGetterInvocation>(
+    unwrapInstanceGetterInvocation,
+    wrapInstanceGetterInvocation,
+    new Tuple6Serializer(
+        instanceAccessKindSerializer,
+        expressionSerializer,
+        nameSerializer,
+        argumentsSerializer,
+        const CanonicalNameSerializer(),
+        Optional(dartTypeSerializer)));
+
+Tuple6<InstanceAccessKind, Expression, Name, Arguments, CanonicalName,
+        DartType?>
+    unwrapInstanceGetterInvocation(InstanceGetterInvocation expression) {
+  return new Tuple6(
+      expression.kind,
+      expression.receiver,
+      expression.name,
+      expression.arguments,
+      expression.interfaceTargetReference.canonicalName!,
+      expression.functionType);
+}
+
+InstanceGetterInvocation wrapInstanceGetterInvocation(
+    Tuple6<InstanceAccessKind, Expression, Name, Arguments, CanonicalName,
+            DartType?>
+        tuple) {
+  return new InstanceGetterInvocation.byReference(
+      tuple.first, tuple.second, tuple.third, tuple.fourth,
+      interfaceTargetReference: tuple.fifth.reference,
+      functionType: tuple.sixth as FunctionType?);
 }
 
 const Map<DynamicAccessKind, String> dynamicAccessKindToName = const {
@@ -707,23 +754,23 @@
     Case(FunctionAccessKindTagger(), convertFlagsMap(functionAccessKindToName));
 
 TextSerializer<FunctionInvocation> functionInvocationSerializer = new Wrapped<
-        Tuple4<FunctionAccessKind, Expression, Arguments, DartType>,
+        Tuple4<FunctionAccessKind, Expression, Arguments, DartType?>,
         FunctionInvocation>(
     unwrapFunctionInvocation,
     wrapFunctionInvocation,
     new Tuple4Serializer(functionAccessKindSerializer, expressionSerializer,
         argumentsSerializer, new Optional(dartTypeSerializer)));
 
-Tuple4<FunctionAccessKind, Expression, Arguments, DartType>
+Tuple4<FunctionAccessKind, Expression, Arguments, DartType?>
     unwrapFunctionInvocation(FunctionInvocation expression) {
   return new Tuple4(expression.kind, expression.receiver, expression.arguments,
       expression.functionType);
 }
 
 FunctionInvocation wrapFunctionInvocation(
-    Tuple4<FunctionAccessKind, Expression, Arguments, DartType> tuple) {
+    Tuple4<FunctionAccessKind, Expression, Arguments, DartType?> tuple) {
   return new FunctionInvocation(tuple.first, tuple.second, tuple.third,
-      functionType: tuple.fourth);
+      functionType: tuple.fourth as FunctionType?);
 }
 
 TextSerializer<LocalFunctionInvocation> localFunctionInvocationSerializer =
@@ -743,47 +790,42 @@
 LocalFunctionInvocation wrapLocalFunctionInvocation(
     Tuple3<VariableDeclaration, Arguments, DartType> tuple) {
   return new LocalFunctionInvocation(tuple.first, tuple.second,
-      functionType: tuple.third);
+      functionType: tuple.third as FunctionType);
 }
 
 TextSerializer<EqualsNull> equalsNullSerializer =
-    new Wrapped<Tuple2<Expression, bool>, EqualsNull>(
-        unwrapEqualsNull,
-        wrapEqualsNull,
-        new Tuple2Serializer(expressionSerializer, const DartBool()));
+    new Wrapped<Expression, EqualsNull>(
+        unwrapEqualsNull, wrapEqualsNull, expressionSerializer);
 
-Tuple2<Expression, bool> unwrapEqualsNull(EqualsNull expression) {
-  return new Tuple2(expression.expression, expression.isNot);
+Expression unwrapEqualsNull(EqualsNull expression) {
+  return expression.expression;
 }
 
-EqualsNull wrapEqualsNull(Tuple2<Expression, bool> tuple) {
-  return new EqualsNull(tuple.first, isNot: tuple.second);
+EqualsNull wrapEqualsNull(Expression expression) {
+  return new EqualsNull(expression);
 }
 
 TextSerializer<EqualsCall> equalsCallSerializer = new Wrapped<
-        Tuple5<Expression, Expression, bool, CanonicalName, DartType>,
-        EqualsCall>(
+        Tuple4<Expression, Expression, CanonicalName, DartType>, EqualsCall>(
     unwrapEqualsCall,
     wrapEqualsCall,
-    new Tuple5Serializer(expressionSerializer, expressionSerializer,
-        const DartBool(), const CanonicalNameSerializer(), dartTypeSerializer));
+    new Tuple4Serializer(expressionSerializer, expressionSerializer,
+        canonicalNameSerializer, dartTypeSerializer));
 
-Tuple5<Expression, Expression, bool, CanonicalName, DartType> unwrapEqualsCall(
+Tuple4<Expression, Expression, CanonicalName, DartType> unwrapEqualsCall(
     EqualsCall expression) {
-  return new Tuple5(
+  return new Tuple4(
       expression.left,
       expression.right,
-      expression.isNot,
-      expression.interfaceTargetReference.canonicalName,
+      expression.interfaceTargetReference.canonicalName!,
       expression.functionType);
 }
 
 EqualsCall wrapEqualsCall(
-    Tuple5<Expression, Expression, bool, CanonicalName, DartType> tuple) {
+    Tuple4<Expression, Expression, CanonicalName, DartType> tuple) {
   return new EqualsCall.byReference(tuple.first, tuple.second,
-      isNot: tuple.third,
-      interfaceTargetReference: tuple.fourth.getReference(),
-      functionType: tuple.fifth);
+      interfaceTargetReference: tuple.third.reference,
+      functionType: tuple.fourth as FunctionType);
 }
 
 TextSerializer<SuperMethodInvocation> superMethodInvocationSerializer =
@@ -799,18 +841,19 @@
   return new SuperMethodInvocation(tuple.first, tuple.second);
 }
 
-TextSerializer<VariableGet> variableGetSerializer = new Wrapped(
-    unwrapVariableGet,
-    wrapVariableGet,
-    new Tuple2Serializer(const ScopedUse<VariableDeclaration>(),
-        new Optional(dartTypeSerializer)));
+TextSerializer<VariableGet> variableGetSerializer =
+    new Wrapped<Tuple2<VariableDeclaration, DartType?>, VariableGet>(
+        unwrapVariableGet,
+        wrapVariableGet,
+        new Tuple2Serializer(const ScopedUse<VariableDeclaration>(),
+            new Optional(dartTypeSerializer)));
 
-Tuple2<VariableDeclaration, DartType> unwrapVariableGet(VariableGet node) {
-  return new Tuple2<VariableDeclaration, DartType>(
+Tuple2<VariableDeclaration, DartType?> unwrapVariableGet(VariableGet node) {
+  return new Tuple2<VariableDeclaration, DartType?>(
       node.variable, node.promotedType);
 }
 
-VariableGet wrapVariableGet(Tuple2<VariableDeclaration, DartType> tuple) {
+VariableGet wrapVariableGet(Tuple2<VariableDeclaration, DartType?> tuple) {
   return new VariableGet(tuple.first, tuple.second);
 }
 
@@ -828,6 +871,9 @@
   return new VariableSet(tuple.first, tuple.second);
 }
 
+const CanonicalNameSerializer canonicalNameSerializer =
+    const CanonicalNameSerializer();
+
 class CanonicalNameSerializer extends TextSerializer<CanonicalName> {
   static const String delimiter = "::";
 
@@ -835,15 +881,20 @@
 
   static void writeName(CanonicalName name, StringBuffer buffer) {
     if (!name.isRoot) {
-      if (!name.parent.isRoot) {
-        writeName(name.parent, buffer);
+      if (!name.parent!.isRoot) {
+        writeName(name.parent!, buffer);
         buffer.write(delimiter);
       }
       buffer.write(name.name);
     }
   }
 
-  CanonicalName readFrom(Iterator<Object> stream, DeserializationState state) {
+  CanonicalName readFrom(
+      Iterator<Object?> stream, DeserializationState? state) {
+    if (state == null) {
+      throw StateError(
+          "No deserialization state provided for ${runtimeType}.readFrom.");
+    }
     String string = const DartString().readFrom(stream, state);
     CanonicalName name = state.nameRoot;
     for (String s in string.split(delimiter)) {
@@ -853,106 +904,101 @@
   }
 
   void writeTo(
-      StringBuffer buffer, CanonicalName name, SerializationState state) {
+      StringBuffer buffer, CanonicalName name, SerializationState? state) {
     StringBuffer sb = new StringBuffer();
     writeName(name, sb);
     const DartString().writeTo(buffer, sb.toString(), state);
   }
 }
 
-const TextSerializer<StaticGet> staticGetSerializer = const Wrapped(
-    unwrapStaticGet, wrapStaticGet, const CanonicalNameSerializer());
+const TextSerializer<StaticGet> staticGetSerializer =
+    const Wrapped(unwrapStaticGet, wrapStaticGet, canonicalNameSerializer);
 
 CanonicalName unwrapStaticGet(StaticGet expression) {
-  return expression.targetReference.canonicalName;
+  return expression.targetReference.canonicalName!;
 }
 
 StaticGet wrapStaticGet(CanonicalName name) {
-  return new StaticGet.byReference(name.getReference());
+  return new StaticGet.byReference(name.reference);
 }
 
 const TextSerializer<StaticTearOff> staticTearOffSerializer = const Wrapped(
-    unwrapStaticTearOff, wrapStaticTearOff, const CanonicalNameSerializer());
+    unwrapStaticTearOff, wrapStaticTearOff, canonicalNameSerializer);
 
 CanonicalName unwrapStaticTearOff(StaticTearOff expression) {
-  return expression.targetReference.canonicalName;
+  return expression.targetReference.canonicalName!;
 }
 
 StaticTearOff wrapStaticTearOff(CanonicalName name) {
-  return new StaticTearOff.byReference(name.getReference());
+  return new StaticTearOff.byReference(name.reference);
 }
 
 TextSerializer<StaticSet> staticSetSerializer = new Wrapped(
     unwrapStaticSet,
     wrapStaticSet,
-    new Tuple2Serializer(
-        const CanonicalNameSerializer(), expressionSerializer));
+    new Tuple2Serializer(canonicalNameSerializer, expressionSerializer));
 
 Tuple2<CanonicalName, Expression> unwrapStaticSet(StaticSet expression) {
-  return new Tuple2(expression.targetReference.canonicalName, expression.value);
+  return new Tuple2(
+      expression.targetReference.canonicalName!, expression.value);
 }
 
 StaticSet wrapStaticSet(Tuple2<CanonicalName, Expression> tuple) {
-  return new StaticSet.byReference(tuple.first.getReference(), tuple.second);
+  return new StaticSet.byReference(tuple.first.reference, tuple.second);
 }
 
 TextSerializer<StaticInvocation> staticInvocationSerializer = new Wrapped(
     unwrapStaticInvocation,
     wrapStaticInvocation,
-    new Tuple2Serializer(const CanonicalNameSerializer(), argumentsSerializer));
+    new Tuple2Serializer(canonicalNameSerializer, argumentsSerializer));
 
 Tuple2<CanonicalName, Arguments> unwrapStaticInvocation(
     StaticInvocation expression) {
   return new Tuple2(
-      expression.targetReference.canonicalName, expression.arguments);
+      expression.targetReference.canonicalName!, expression.arguments);
 }
 
 StaticInvocation wrapStaticInvocation(Tuple2<CanonicalName, Arguments> tuple) {
-  return new StaticInvocation.byReference(
-      tuple.first.getReference(), tuple.second,
+  return new StaticInvocation.byReference(tuple.first.reference, tuple.second,
       isConst: false);
 }
 
 TextSerializer<StaticInvocation> constStaticInvocationSerializer = new Wrapped(
     unwrapStaticInvocation,
     wrapConstStaticInvocation,
-    new Tuple2Serializer(const CanonicalNameSerializer(), argumentsSerializer));
+    new Tuple2Serializer(canonicalNameSerializer, argumentsSerializer));
 
 StaticInvocation wrapConstStaticInvocation(
     Tuple2<CanonicalName, Arguments> tuple) {
-  return new StaticInvocation.byReference(
-      tuple.first.getReference(), tuple.second,
+  return new StaticInvocation.byReference(tuple.first.reference, tuple.second,
       isConst: true);
 }
 
 TextSerializer<ConstructorInvocation> constructorInvocationSerializer =
-    new Wrapped(
-        unwrapConstructorInvocation,
-        wrapConstructorInvocation,
-        new Tuple2Serializer(
-            const CanonicalNameSerializer(), argumentsSerializer));
+    new Wrapped(unwrapConstructorInvocation, wrapConstructorInvocation,
+        new Tuple2Serializer(canonicalNameSerializer, argumentsSerializer));
 
 Tuple2<CanonicalName, Arguments> unwrapConstructorInvocation(
     ConstructorInvocation expression) {
   return new Tuple2(
-      expression.targetReference.canonicalName, expression.arguments);
+      expression.targetReference.canonicalName!, expression.arguments);
 }
 
 ConstructorInvocation wrapConstructorInvocation(
     Tuple2<CanonicalName, Arguments> tuple) {
   return new ConstructorInvocation.byReference(
-      tuple.first.getReference(), tuple.second,
+      tuple.first.reference, tuple.second,
       isConst: false);
 }
 
 TextSerializer<ConstructorInvocation> constConstructorInvocationSerializer =
     new Wrapped(unwrapConstructorInvocation, wrapConstConstructorInvocation,
-        Tuple2Serializer(const CanonicalNameSerializer(), argumentsSerializer));
+        Tuple2Serializer(canonicalNameSerializer, argumentsSerializer));
 
 ConstructorInvocation wrapConstConstructorInvocation(
     Tuple2<CanonicalName, Arguments> tuple) {
   return new ConstructorInvocation.byReference(
-      tuple.first.getReference(), tuple.second,
+      tuple.first.reference, tuple.second,
       isConst: true);
 }
 
@@ -989,9 +1035,9 @@
             ListSerializer(expressionSerializer)));
 
 TextSerializer<BlockExpression> blockExpressionSerializer =
-    Wrapped<Tuple2<List<Statement>, Expression>, BlockExpression>(
+    Wrapped<Tuple2<List<Statement>, Expression?>, BlockExpression>(
         (w) => Tuple2(w.body.statements, w.value),
-        (u) => BlockExpression(Block(u.first), u.second),
+        (u) => BlockExpression(Block(u.first), u.second!),
         const BlockSerializer());
 
 TextSerializer<Instantiation> instantiationSerializer =
@@ -1001,8 +1047,8 @@
         Tuple2Serializer(
             expressionSerializer, ListSerializer(dartTypeSerializer)));
 
-TextSerializer<NullCheck> nullCheckSerializer =
-    Wrapped((nc) => nc.operand, (op) => NullCheck(op), expressionSerializer);
+TextSerializer<NullCheck> nullCheckSerializer = Wrapped<Expression, NullCheck>(
+    (nc) => nc.operand, (op) => NullCheck(op), expressionSerializer);
 
 TextSerializer<FileUriExpression> fileUriExpressionSerializer =
     Wrapped<Tuple2<Expression, Uri>, FileUriExpression>(
@@ -1010,13 +1056,13 @@
         (t) => FileUriExpression(t.first, t.second),
         Tuple2Serializer(expressionSerializer, const UriSerializer()));
 
-TextSerializer<CheckLibraryIsLoaded> checkLibraryIsLoadedSerializer = Wrapped(
-    (clil) => clil.import,
-    (i) => CheckLibraryIsLoaded(i),
-    libraryDependencySerializer);
+TextSerializer<CheckLibraryIsLoaded> checkLibraryIsLoadedSerializer =
+    Wrapped<LibraryDependency, CheckLibraryIsLoaded>((clil) => clil.import,
+        (i) => CheckLibraryIsLoaded(i), libraryDependencySerializer);
 
-TextSerializer<LoadLibrary> loadLibrarySerializer = Wrapped(
-    (ll) => ll.import, (i) => LoadLibrary(i), libraryDependencySerializer);
+TextSerializer<LoadLibrary> loadLibrarySerializer =
+    Wrapped<LibraryDependency, LoadLibrary>(
+        (ll) => ll.import, (i) => LoadLibrary(i), libraryDependencySerializer);
 
 TextSerializer<ConstantExpression> constantExpressionSerializer =
     Wrapped<Tuple2<Constant, DartType>, ConstantExpression>(
@@ -1029,14 +1075,14 @@
             List<Expression>, List<AssertStatement>, List<Expression>>,
         InstanceCreation>(
     (ic) => Tuple6(
-        ic.classReference.canonicalName,
+        ic.classReference.canonicalName!,
         ic.typeArguments,
-        ic.fieldValues.keys.map((r) => r.canonicalName).toList(),
+        ic.fieldValues.keys.map((r) => r.canonicalName!).toList(),
         ic.fieldValues.values.toList(),
         ic.asserts,
         ic.unusedArguments),
     (t) => InstanceCreation(
-        t.first.getReference(),
+        t.first.reference,
         t.second,
         Map.fromIterables(t.third.map((cn) => cn.reference), t.fourth),
         t.fifth,
@@ -1052,6 +1098,9 @@
 Case<Expression> expressionSerializer =
     new Case.uninitialized(const ExpressionTagger());
 
+TextSerializer<Expression?> nullableExpressionSerializer =
+    new Optional(expressionSerializer);
+
 TextSerializer<NamedExpression> namedExpressionSerializer = new Wrapped(
     unwrapNamedExpression,
     wrapNamedExpression,
@@ -1111,11 +1160,11 @@
             convertFlagsMap(variableDeclarationFlagToName))));
 
 TextSerializer<VariableDeclaration> variableDeclarationSerializer =
-    Wrapped<Tuple2<String, VariableDeclaration>, VariableDeclaration>(
+    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>>,
+          new Wrapped<Tuple4<int, DartType, Expression?, List<Expression>>,
                   VariableDeclaration>(
               (w) => Tuple4(w.flags, w.type, w.initializer, w.annotations),
               (u) => u.fourth.fold(
@@ -1130,7 +1179,7 @@
         ));
 
 TextSerializer<TypeParameter> typeParameterSerializer =
-    Wrapped<Tuple2<String, TypeParameter>, TypeParameter>(
+    Wrapped<Tuple2<String?, TypeParameter>, TypeParameter>(
         (p) => Tuple2(p.name, p),
         (t) => t.second..name = t.first,
         Binder(Wrapped((_) => null, (_) => TypeParameter(), const Nothing())));
@@ -1146,20 +1195,20 @@
     zipTypeParameterDefaultType,
     unzipTypeParameterDefaultType);
 
-TypeParameter zipTypeParameterBound(TypeParameter node, DartType bound) {
+TypeParameter zipTypeParameterBound(TypeParameter node, DartType? bound) {
   return node..bound = bound;
 }
 
-Tuple2<TypeParameter, DartType> unzipTypeParameterBound(TypeParameter node) {
+Tuple2<TypeParameter, DartType?> unzipTypeParameterBound(TypeParameter node) {
   return new Tuple2(node, node.bound);
 }
 
 TypeParameter zipTypeParameterDefaultType(
-    TypeParameter node, DartType defaultType) {
+    TypeParameter node, DartType? defaultType) {
   return node..defaultType = defaultType;
 }
 
-Tuple2<TypeParameter, DartType> unzipTypeParameterDefaultType(
+Tuple2<TypeParameter, DartType?> unzipTypeParameterDefaultType(
     TypeParameter node) {
   return new Tuple2(node, node.defaultType);
 }
@@ -1267,23 +1316,24 @@
     Tuple2Serializer(
         new ScopedUse<TypeParameter>(), new Optional(dartTypeSerializer)));
 
-Tuple2<TypeParameter, DartType> unwrapTypeParameterType(
+Tuple2<TypeParameter, DartType?> unwrapTypeParameterType(
     TypeParameterType node) {
   return new Tuple2(node.parameter, node.promotedBound);
 }
 
-TypeParameterType wrapTypeParameterType(Tuple2<TypeParameter, DartType> tuple) {
+TypeParameterType wrapTypeParameterType(
+    Tuple2<TypeParameter, DartType?> tuple) {
   return new TypeParameterType(tuple.first, Nullability.legacy, tuple.second);
 }
 
 TextSerializer<InterfaceType> interfaceTypeSerializer = new Wrapped(
     unwrapInterfaceType,
     wrapInterfaceType,
-    Tuple2Serializer(const CanonicalNameSerializer(),
-        new ListSerializer(dartTypeSerializer)));
+    Tuple2Serializer(
+        canonicalNameSerializer, new ListSerializer(dartTypeSerializer)));
 
 Tuple2<CanonicalName, List<DartType>> unwrapInterfaceType(InterfaceType node) {
-  return new Tuple2(node.className.canonicalName, node.typeArguments);
+  return new Tuple2(node.className.canonicalName!, node.typeArguments);
 }
 
 InterfaceType wrapInterfaceType(Tuple2<CanonicalName, List<DartType>> tuple) {
@@ -1294,11 +1344,11 @@
 TextSerializer<TypedefType> typedefTypeSerializer = new Wrapped(
     unwrapTypedefType,
     wrapTypedefType,
-    Tuple2Serializer(const CanonicalNameSerializer(),
-        new ListSerializer(dartTypeSerializer)));
+    Tuple2Serializer(
+        canonicalNameSerializer, new ListSerializer(dartTypeSerializer)));
 
 Tuple2<CanonicalName, List<DartType>> unwrapTypedefType(TypedefType node) {
-  return new Tuple2(node.typedefReference.canonicalName, node.typeArguments);
+  return new Tuple2(node.typedefReference.canonicalName!, node.typeArguments);
 }
 
 TypedefType wrapTypedefType(Tuple2<CanonicalName, List<DartType>> tuple) {
@@ -1382,14 +1432,15 @@
   return new ExpressionStatement(expression);
 }
 
-TextSerializer<ReturnStatement> returnStatementSerializer = new Wrapped(
-    unwrapReturnStatement, wrapReturnStatement, expressionSerializer);
+TextSerializer<ReturnStatement> returnStatementSerializer =
+    new Wrapped<Expression?, ReturnStatement>(
+        unwrapReturnStatement, wrapReturnStatement, expressionSerializer);
 
-Expression unwrapReturnStatement(ReturnStatement statement) {
+Expression? unwrapReturnStatement(ReturnStatement statement) {
   return statement.expression;
 }
 
-ReturnStatement wrapReturnStatement(Expression expression) {
+ReturnStatement wrapReturnStatement(Expression? expression) {
   return new ReturnStatement(expression);
 }
 
@@ -1410,24 +1461,24 @@
 }
 
 TextSerializer<AssertStatement> assertStatementSerializer =
-    Wrapped<Tuple4<Expression, Expression, int, int>, AssertStatement>(
+    Wrapped<Tuple4<Expression, Expression?, int, int>, AssertStatement>(
         (a) => Tuple4(a.condition, a.message, a.conditionStartOffset,
             a.conditionEndOffset),
         (t) => AssertStatement(t.first,
             message: t.second,
             conditionStartOffset: t.third,
             conditionEndOffset: t.fourth),
-        Tuple4Serializer(expressionSerializer, Optional(expressionSerializer),
+        Tuple4Serializer(expressionSerializer, nullableExpressionSerializer,
             const DartInt(), const DartInt()));
 
 TextSerializer<Block> blockSerializer =
-    Wrapped<Tuple2<List<Statement>, Expression>, Block>(
+    Wrapped<Tuple2<List<Statement>, Expression?>, Block>(
         (w) => Tuple2(w.statements, null),
         (u) => Block(u.first),
         const BlockSerializer());
 
 TextSerializer<AssertBlock> assertBlockSerializer =
-    Wrapped<Tuple2<List<Statement>, Expression>, AssertBlock>(
+    Wrapped<Tuple2<List<Statement>, Expression?>, AssertBlock>(
         (w) => Tuple2(w.statements, null),
         (u) => AssertBlock(u.first),
         const BlockSerializer());
@@ -1446,33 +1497,41 @@
 /// without direct invocations of either [ListSerializer] or [Bind], but with a
 /// certain internal correspondence to how they work.
 class BlockSerializer
-    extends TextSerializer<Tuple2<List<Statement>, Expression>> {
+    extends TextSerializer<Tuple2<List<Statement>, Expression?>> {
   const BlockSerializer();
 
-  Tuple2<List<Statement>, Expression> readFrom(
-      Iterator<Object> stream, DeserializationState state) {
-    if (stream.current is! Iterator) {
-      throw StateError("Expected a list, found an atom: '${stream.current}'.");
+  Tuple2<List<Statement>, Expression?> readFrom(
+      Iterator<Object?> stream, DeserializationState? state) {
+    if (state == null) {
+      throw StateError(
+          "No deserialization state provided for ${runtimeType}.readFrom.");
     }
-    Iterator<Object> list = stream.current;
-    list.moveNext();
+    Object? iterator = stream.current;
+    if (iterator is! Iterator) {
+      throw StateError("Expected a list, found an atom: '${iterator}'.");
+    }
+    iterator.moveNext();
     List<Statement> statements = [];
     DeserializationState currentState = state;
-    while (list.current != null) {
+    while (iterator.current != null) {
       currentState = new DeserializationState(
           new DeserializationEnvironment(currentState.environment),
           currentState.nameRoot);
-      statements.add(statementSerializer.readFrom(list, currentState));
+      statements.add(statementSerializer.readFrom(iterator, currentState));
       currentState.environment.extend();
     }
     stream.moveNext();
-    Expression expression =
-        new Optional(expressionSerializer).readFrom(stream, currentState);
+    Expression? expression =
+        nullableExpressionSerializer.readFrom(stream, currentState);
     return new Tuple2(statements, expression);
   }
 
-  void writeTo(StringBuffer buffer, Tuple2<List<Statement>, Expression> tuple,
-      SerializationState state) {
+  void writeTo(StringBuffer buffer, Tuple2<List<Statement>, Expression?> tuple,
+      SerializationState? state) {
+    if (state == null) {
+      throw StateError(
+          "No serialization state provided for ${runtimeType}.writeTo.");
+    }
     buffer.write('(');
     SerializationState currentState = state;
     for (int i = 0; i < tuple.first.length; ++i) {
@@ -1483,8 +1542,7 @@
       currentState.environment.extend();
     }
     buffer.write(') ');
-    new Optional(expressionSerializer)
-        .writeTo(buffer, tuple.second, currentState);
+    nullableExpressionSerializer.writeTo(buffer, tuple.second, currentState);
   }
 }
 
@@ -1507,13 +1565,13 @@
     Tuple3Serializer(
         expressionSerializer, statementSerializer, statementSerializer));
 
-Tuple3<Expression, Statement, Statement> unwrapIfElseStatement(
+Tuple3<Expression, Statement, Statement?> unwrapIfElseStatement(
     IfStatement node) {
   return new Tuple3(node.condition, node.then, node.otherwise);
 }
 
 IfStatement wrapIfElseStatement(
-    Tuple3<Expression, Statement, Statement> tuple) {
+    Tuple3<Expression, Statement, Statement?> tuple) {
   return new IfStatement(tuple.first, tuple.second, tuple.third);
 }
 
@@ -1552,7 +1610,7 @@
 
 TextSerializer<ForStatement> forStatementSerializer = Wrapped<
         Tuple2<List<VariableDeclaration>,
-            Tuple3<Expression, List<Expression>, Statement>>,
+            Tuple3<Expression?, List<Expression>, Statement>>,
         ForStatement>(
     (w) => Tuple2(w.variables, Tuple3(w.condition, w.updates, w.body)),
     (u) =>
@@ -1633,7 +1691,7 @@
     Wrapped<
             Tuple2<
                 DartType,
-                Tuple2<Tuple2<VariableDeclaration, VariableDeclaration>,
+                Tuple2<Tuple2<VariableDeclaration?, VariableDeclaration?>,
                     Statement>>,
             Catch>(
         (w) =>
@@ -1687,11 +1745,12 @@
 });
 
 TextSerializer<ContinueSwitchStatement> continueSwitchStatementSerializer =
-    Wrapped((w) => w.target, (u) => ContinueSwitchStatement(u), ScopedUse());
+    Wrapped<SwitchCase, ContinueSwitchStatement>(
+        (w) => w.target, (u) => ContinueSwitchStatement(u), ScopedUse());
 
 TextSerializer<FunctionDeclaration> functionDeclarationSerializer =
     Wrapped<Tuple2<VariableDeclaration, FunctionNode>, FunctionDeclaration>(
-        (w) => Tuple2(w.variable, w.function),
+        (w) => Tuple2(w.variable, w.function!),
         (u) => FunctionDeclaration(u.first, u.second),
         Rebind(variableDeclarationSerializer, functionNodeSerializer));
 
@@ -1719,7 +1778,7 @@
 
 // '/**/' comments added to guide formatting.
 
-TextSerializer<Tuple2<FunctionNode, List<Initializer>>> /**/
+TextSerializer<Tuple2<FunctionNode, List<Initializer>?>> /**/
     functionNodeWithInitializersSerializer = Wrapped<
             Tuple2<
                 AsyncMarker,
@@ -1730,8 +1789,8 @@
                             List<VariableDeclaration>,
                             List<VariableDeclaration>,
                             List<VariableDeclaration>>>,
-                    Tuple3<DartType, List<Initializer>, Statement>>>,
-            Tuple2<FunctionNode, List<Initializer>>>(
+                    Tuple3<DartType, List<Initializer>?, Statement?>>>,
+            Tuple2<FunctionNode, List<Initializer>?>>(
         (w) => Tuple2(
             w.first.asyncMarker,
             Tuple2(
@@ -1769,7 +1828,7 @@
                     Optional(statementSerializer)))));
 
 TextSerializer<FunctionNode> functionNodeSerializer =
-    Wrapped<Tuple2<FunctionNode, List<Initializer>>, FunctionNode>(
+    Wrapped<Tuple2<FunctionNode, List<Initializer>?>, FunctionNode>(
         (w) => Tuple2(w, null),
         (u) => u.first,
         functionNodeWithInitializersSerializer);
@@ -1907,24 +1966,24 @@
 }
 
 TextSerializer<Field> mutableFieldSerializer =
-    Wrapped<Tuple4<Name, int, DartType, Expression>, Field>(
-        (w) => Tuple4(w.name, w.flags, w.type, w.initializer),
+    Wrapped<Tuple4<Name, int, DartType, Expression?>, Field>(
+        (w) => Tuple4(w.name!, w.flags, w.type, w.initializer),
         (u) => Field.mutable(u.first, type: u.third, initializer: u.fourth)
           ..flags = u.second,
         Tuple4Serializer(nameSerializer, fieldFlagsSerializer,
-            dartTypeSerializer, Optional(expressionSerializer)));
+            dartTypeSerializer, nullableExpressionSerializer));
 
 TextSerializer<Field> immutableFieldSerializer =
-    Wrapped<Tuple4<Name, int, DartType, Expression>, Field>(
-        (w) => Tuple4(w.name, w.flags, w.type, w.initializer),
+    Wrapped<Tuple4<Name, int, DartType, Expression?>, Field>(
+        (w) => Tuple4(w.name!, w.flags, w.type, w.initializer),
         (u) => Field.immutable(u.first, type: u.third, initializer: u.fourth)
           ..flags = u.second,
         Tuple4Serializer(nameSerializer, fieldFlagsSerializer,
-            dartTypeSerializer, Optional(expressionSerializer)));
+            dartTypeSerializer, nullableExpressionSerializer));
 
 TextSerializer<Procedure> methodSerializer =
     Wrapped<Tuple3<Name, int, FunctionNode>, Procedure>(
-        (w) => Tuple3(w.name, w.flags, w.function),
+        (w) => Tuple3(w.name!, w.flags, w.function!),
         (u) =>
             Procedure(u.first, ProcedureKind.Method, u.third)..flags = u.second,
         Tuple3Serializer(
@@ -1932,7 +1991,7 @@
 
 TextSerializer<Procedure> getterSerializer =
     Wrapped<Tuple3<Name, int, FunctionNode>, Procedure>(
-        (w) => Tuple3(w.name, w.flags, w.function),
+        (w) => Tuple3(w.name!, w.flags, w.function!),
         (u) =>
             Procedure(u.first, ProcedureKind.Getter, u.third)..flags = u.second,
         Tuple3Serializer(
@@ -1940,7 +1999,7 @@
 
 TextSerializer<Procedure> setterSerializer =
     Wrapped<Tuple3<Name, int, FunctionNode>, Procedure>(
-        (w) => Tuple3(w.name, w.flags, w.function),
+        (w) => Tuple3(w.name!, w.flags, w.function!),
         (u) =>
             Procedure(u.first, ProcedureKind.Setter, u.third)..flags = u.second,
         Tuple3Serializer(
@@ -1948,7 +2007,7 @@
 
 TextSerializer<Procedure> operatorSerializer =
     Wrapped<Tuple3<Name, int, FunctionNode>, Procedure>(
-        (w) => Tuple3(w.name, w.flags, w.function),
+        (w) => Tuple3(w.name!, w.flags, w.function!),
         (u) => Procedure(u.first, ProcedureKind.Operator, u.third)
           ..flags = u.second,
         Tuple3Serializer(
@@ -1956,16 +2015,16 @@
 
 TextSerializer<Procedure> factorySerializer =
     Wrapped<Tuple3<Name, int, FunctionNode>, Procedure>(
-        (w) => Tuple3(w.name, w.flags, w.function),
+        (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<
-        Tuple3<Name, int, Tuple2<FunctionNode, List<Initializer>>>,
+        Tuple3<Name, int, Tuple2<FunctionNode, List<Initializer>?>>,
         Constructor>(
-    (w) => Tuple3(w.name, w.flags, Tuple2(w.function, w.initializers)),
+    (w) => Tuple3(w.name!, w.flags, Tuple2(w.function!, w.initializers)),
     (u) =>
         Constructor(u.third.first, name: u.first, initializers: u.third.second)
           ..flags = u.second,
@@ -1984,9 +2043,9 @@
                         List<VariableDeclaration>, List<DartType>>>>,
             RedirectingFactoryConstructor>(
         (w) => Tuple4(
-            w.name,
+            w.name!,
             w.flags,
-            w.targetReference.canonicalName,
+            w.targetReference!.canonicalName!,
             Tuple2(
                 w.typeParameters,
                 Tuple4(
@@ -2095,8 +2154,10 @@
 TextSerializer<Combinator> showSerializer = Wrapped<List<String>, Combinator>(
     (c) => c.names, (ns) => Combinator(true, ns), ListSerializer(DartString()));
 
-TextSerializer<Combinator> hideSerializer = Wrapped((c) => c.names,
-    (ns) => Combinator(false, ns), ListSerializer(DartString()));
+TextSerializer<Combinator> hideSerializer = Wrapped<List<String>, Combinator>(
+    (c) => c.names,
+    (ns) => Combinator(false, ns),
+    ListSerializer(DartString()));
 
 Case<Combinator> showHideSerializer = new Case(ShowHideTagger(), {
   "show": showSerializer,
@@ -2104,12 +2165,12 @@
 });
 
 TextSerializer<LibraryDependency> libraryDependencySerializer = Wrapped<
-        Tuple5<CanonicalName, String, List<Combinator>, int, List<Expression>>,
+        Tuple5<CanonicalName, String?, List<Combinator>, int, List<Expression>>,
         LibraryDependency>(
-    (ld) => Tuple5(ld.importedLibraryReference.canonicalName, ld.name,
+    (ld) => Tuple5(ld.importedLibraryReference.canonicalName!, ld.name,
         ld.combinators, ld.flags, ld.annotations),
     (t) => LibraryDependency.byReference(
-        t.fourth, t.fifth, t.first.getReference(), t.second, t.third),
+        t.fourth, t.fifth, t.first.reference, t.second, t.third),
     Tuple5Serializer(
         CanonicalNameSerializer(),
         Optional(DartString()),
@@ -2174,7 +2235,7 @@
             Zip(
                 Tuple2Serializer(ListSerializer(constantSerializer),
                     ListSerializer(constantSerializer)),
-                (k, v) => ConstantMapEntry(k, v),
+                (Constant k, Constant v) => ConstantMapEntry(k, v),
                 (z) => Tuple2(z.key, z.value))));
 
 TextSerializer<NullConstant> nullConstantSerializer =
@@ -2201,15 +2262,15 @@
         (w) => w.value, (u) => StringConstant(u), DartString());
 
 TextSerializer<SymbolConstant> symbolConstantSerializer =
-    Wrapped<Tuple2<String, CanonicalName>, SymbolConstant>(
+    Wrapped<Tuple2<String, CanonicalName?>, SymbolConstant>(
         (w) => Tuple2(w.name, w.libraryReference?.canonicalName),
-        (u) => SymbolConstant(u.first, u.second?.getReference()),
+        (u) => SymbolConstant(u.first, u.second?.reference),
         Tuple2Serializer(DartString(), Optional(CanonicalNameSerializer())));
 
 TextSerializer<TearOffConstant> tearOffConstantSerializer =
     Wrapped<CanonicalName, TearOffConstant>(
-        (w) => w.procedureReference.canonicalName,
-        (u) => TearOffConstant.byReference(u.getReference()),
+        (w) => w.procedureReference.canonicalName!,
+        (u) => TearOffConstant.byReference(u.reference),
         CanonicalNameSerializer());
 
 TextSerializer<TypeLiteralConstant> typeLiteralConstantSerializer =
@@ -2226,12 +2287,12 @@
                 List<Constant>>,
             InstanceConstant>(
         (w) => Tuple4(
-            w.classReference.canonicalName,
+            w.classReference.canonicalName!,
             w.typeArguments,
-            w.fieldValues.keys.map((r) => r.canonicalName).toList(),
+            w.fieldValues.keys.map((r) => r.canonicalName!).toList(),
             w.fieldValues.values.toList()),
-        (u) => InstanceConstant(u.first.getReference(), u.second,
-            Map.fromIterables(u.third.map((c) => c.getReference()), u.fourth)),
+        (u) => InstanceConstant(u.first.reference, u.second,
+            Map.fromIterables(u.third.map((c) => c.reference), u.fourth)),
         Tuple4Serializer(
             CanonicalNameSerializer(),
             ListSerializer(dartTypeSerializer),
@@ -2263,13 +2324,13 @@
 }
 
 TextSerializer<AssertInitializer> assertInitializerSerializer =
-    Wrapped<Statement, AssertInitializer>(
-        (w) => w.statement, (u) => AssertInitializer(u), statementSerializer);
+    Wrapped<Statement, AssertInitializer>((w) => w.statement,
+        (u) => AssertInitializer(u as AssertStatement), statementSerializer);
 
 TextSerializer<FieldInitializer> fieldInitializerSerializer =
     Wrapped<Tuple2<CanonicalName, Expression>, FieldInitializer>(
-        (w) => Tuple2(w.fieldReference.canonicalName, w.value),
-        (u) => FieldInitializer.byReference(u.first.getReference(), u.second),
+        (w) => Tuple2(w.fieldReference.canonicalName!, w.value),
+        (u) => FieldInitializer.byReference(u.first.reference, u.second),
         Tuple2Serializer(CanonicalNameSerializer(), expressionSerializer));
 
 TextSerializer<InvalidInitializer> invalidInitializerSerializer =
@@ -2282,15 +2343,14 @@
 
 TextSerializer<RedirectingInitializer> redirectingInitializerSerializer =
     Wrapped<Tuple2<CanonicalName, Arguments>, RedirectingInitializer>(
-        (w) => Tuple2(w.targetReference.canonicalName, w.arguments),
-        (u) => RedirectingInitializer.byReference(
-            u.first.getReference(), u.second),
+        (w) => Tuple2(w.targetReference.canonicalName!, w.arguments),
+        (u) => RedirectingInitializer.byReference(u.first.reference, 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),
+        (w) => Tuple2(w.targetReference.canonicalName!, w.arguments),
+        (u) => SuperInitializer.byReference(u.first.reference, u.second),
         Tuple2Serializer(CanonicalNameSerializer(), argumentsSerializer));
 
 Case<Initializer> initializerSerializer =
@@ -2298,8 +2358,8 @@
 
 TextSerializer<Supertype> supertypeSerializer =
     Wrapped<Tuple2<CanonicalName, List<DartType>>, Supertype>(
-        (w) => Tuple2(w.className.canonicalName, w.typeArguments),
-        (u) => Supertype.byReference(u.first.getReference(), u.second),
+        (w) => Tuple2(w.className.canonicalName!, w.typeArguments),
+        (u) => Supertype.byReference(u.first.reference, u.second),
         Tuple2Serializer(
             CanonicalNameSerializer(), ListSerializer(dartTypeSerializer)));
 
@@ -2333,7 +2393,7 @@
             Tuple2<
                 List<TypeParameter>,
                 /* Comment added to guide formatting. */
-                Tuple4<Supertype, Supertype, List<Supertype>, List<Member>>>>,
+                Tuple4<Supertype?, Supertype?, List<Supertype>, List<Member>>>>,
         Class>(
     (w) => Tuple3(
         w.name,
@@ -2374,7 +2434,7 @@
 
 TextSerializer<Typedef> typedefSerializer =
     Wrapped<Tuple2<String, Tuple2<List<TypeParameter>, DartType>>, Typedef>(
-        (w) => Tuple2(w.name, Tuple2(w.typeParameters, w.type)),
+        (w) => Tuple2(w.name, Tuple2(w.typeParameters, w.type!)),
         (u) =>
             Typedef(u.first, u.second.second, typeParameters: u.second.first),
         Tuple2Serializer(
@@ -2427,9 +2487,9 @@
 TextSerializer<ExtensionMemberDescriptor> extensionMemberDescriptorSerializer =
     Wrapped<Tuple4<Name, ExtensionMemberKind, int, CanonicalName>,
             ExtensionMemberDescriptor>(
-        (w) => Tuple4(w.name, w.kind, w.flags, w.member.canonicalName),
+        (w) => Tuple4(w.name, w.kind, w.flags, w.member.canonicalName!),
         (u) => ExtensionMemberDescriptor(
-            name: u.first, kind: u.second, member: u.fourth.getReference())
+            name: u.first, kind: u.second, member: u.fourth.reference)
           ..flags = u.third,
         Tuple4Serializer(
             nameSerializer,
@@ -2492,6 +2552,7 @@
     "set-super": superPropertySetSerializer,
     "invoke-method": methodInvocationSerializer,
     "invoke-instance": instanceInvocationSerializer,
+    "invoke-instance-getter": instanceGetterInvocationSerializer,
     "invoke-dynamic": dynamicInvocationSerializer,
     "invoke-function": functionInvocationSerializer,
     "invoke-local-function": localFunctionInvocationSerializer,
@@ -2601,7 +2662,8 @@
 }
 
 extension MapFromIterable<E> on Iterable<E> {
-  Map<K, V> toMap<K, V>({K Function(E) key, V Function(E) value}) {
+  Map<K, V> toMap<K, V>(
+      {required K Function(E) key, required V Function(E) value}) {
     return {for (E e in this) key(e): value(e)};
   }
 }
diff --git a/pkg/kernel/lib/transformations/track_widget_constructor_locations.dart b/pkg/kernel/lib/transformations/track_widget_constructor_locations.dart
index 2eeb952..2d301ed 100644
--- a/pkg/kernel/lib/transformations/track_widget_constructor_locations.dart
+++ b/pkg/kernel/lib/transformations/track_widget_constructor_locations.dart
@@ -2,12 +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
-
 library kernel.transformations.track_widget_constructor_locations;
 
-import 'package:meta/meta.dart';
-
 import '../ast.dart';
 import '../target/changed_structure_notifier.dart';
 
@@ -36,7 +32,7 @@
       .any((NamedExpression argument) => argument.name == argumentName);
 }
 
-VariableDeclaration _getNamedParameter(
+VariableDeclaration? _getNamedParameter(
   FunctionNode function,
   String parameterName,
 ) {
@@ -128,7 +124,7 @@
   ///
   /// Used to flow the location passed in as an argument to the factory to the
   /// actual constructor call within the factory.
-  Procedure _currentFactory;
+  Procedure? _currentFactory;
 
   WidgetCreatorTracker _tracker;
 
@@ -136,12 +132,12 @@
   ///
   /// The transformation of the call sites is affected by the NNBD opt-in status
   /// of the library.
-  Library _currentLibrary;
+  Library? _currentLibrary;
 
   _WidgetCallSiteTransformer(
-      {@required Class widgetClass,
-      @required Class locationClass,
-      @required WidgetCreatorTracker tracker})
+      {required Class widgetClass,
+      required Class locationClass,
+      required WidgetCreatorTracker tracker})
       : _widgetClass = widgetClass,
         _locationClass = locationClass,
         _tracker = tracker;
@@ -158,8 +154,8 @@
   /// without re-parsing the source code.
   ConstructorInvocation _constructLocation(
     Location location, {
-    String name,
-    ListLiteral parameterLocations,
+    String? name,
+    ListLiteral? parameterLocations,
     bool showFile: true,
   }) {
     final List<NamedExpression> arguments = <NamedExpression>[
@@ -192,7 +188,8 @@
       _currentFactory = null;
       return node;
     }
-    return defaultTreeNode(node);
+    node.transformChildren(this);
+    return node;
   }
 
   bool _isSubclassOfWidget(Class clazz) {
@@ -206,12 +203,12 @@
     if (!target.isFactory) {
       return node;
     }
-    final Class constructedClass = target.enclosingClass;
+    final Class constructedClass = target.enclosingClass!;
     if (!_isSubclassOfWidget(constructedClass)) {
       return node;
     }
 
-    _addLocationArgument(node, target.function, constructedClass,
+    _addLocationArgument(node, target.function!, constructedClass,
         isConst: node.isConst);
     return node;
   }
@@ -237,7 +234,7 @@
       return node;
     }
 
-    _addLocationArgument(node, constructor.function, constructedClass,
+    _addLocationArgument(node, constructor.function!, constructedClass,
         isConst: node.isConst);
     return node;
   }
@@ -249,13 +246,13 @@
     // argument to the factory constructor rather than the location
     if (_currentFactory != null &&
         _tracker._isSubclassOf(
-            constructedClass, _currentFactory.enclosingClass) &&
+            constructedClass, _currentFactory!.enclosingClass!) &&
         // If the constructor invocation is constant we cannot refer to the
         // location parameter of the surrounding factory since it isn't a
         // constant expression.
         !isConst) {
-      final VariableDeclaration creationLocationParameter = _getNamedParameter(
-        _currentFactory.function,
+      final VariableDeclaration? creationLocationParameter = _getNamedParameter(
+        _currentFactory!.function!,
         _creationLocationParameterName,
       );
       if (creationLocationParameter != null) {
@@ -264,7 +261,7 @@
     }
 
     final Arguments arguments = node.arguments;
-    final Location location = node.location;
+    final Location location = node.location!;
     final List<ConstructorInvocation> parameterLocations =
         <ConstructorInvocation>[];
     final List<VariableDeclaration> parameters = function.positionalParameters;
@@ -272,14 +269,14 @@
       final Expression expression = arguments.positional[i];
       final VariableDeclaration parameter = parameters[i];
       parameterLocations.add(_constructLocation(
-        expression.location,
+        expression.location!,
         name: parameter.name,
         showFile: false,
       ));
     }
     for (NamedExpression expression in arguments.named) {
       parameterLocations.add(_constructLocation(
-        expression.location,
+        expression.location!,
         name: expression.name,
         showFile: false,
       ));
@@ -289,7 +286,7 @@
       parameterLocations: new ListLiteral(
         parameterLocations,
         typeArgument:
-            new InterfaceType(_locationClass, _currentLibrary.nonNullable),
+            new InterfaceType(_locationClass, _currentLibrary!.nonNullable),
         isConst: true,
       ),
     );
@@ -299,7 +296,7 @@
     assert(
         _currentLibrary == null,
         "Attempting to enter library '${library.fileUri}' "
-        "without having exited library '${_currentLibrary.fileUri}'.");
+        "without having exited library '${_currentLibrary!.fileUri}'.");
     _currentLibrary = library;
   }
 
@@ -317,24 +314,30 @@
 /// on the base widget class and flowed through the constructors using a named
 /// parameter.
 class WidgetCreatorTracker {
-  Class _widgetClass;
-  Class _locationClass;
+  bool _foundClasses = false;
+  late Class _widgetClass;
+  late Class _locationClass;
 
   /// Marker interface indicating that a private _location field is
   /// available.
-  Class _hasCreationLocationClass;
+  late Class _hasCreationLocationClass;
 
   void _resolveFlutterClasses(Iterable<Library> libraries) {
     // If the Widget or Debug location classes have been updated we need to get
     // the latest version
+    bool foundWidgetClass = false;
+    bool foundHasCreationLocationClass = false;
+    bool foundLocationClass = false;
     for (Library library in libraries) {
       final Uri importUri = library.importUri;
+      // ignore: unnecessary_null_comparison
       if (importUri != null && importUri.scheme == 'package') {
         if (importUri.path == 'flutter/src/widgets/framework.dart' ||
             importUri.path == 'flutter_web/src/widgets/framework.dart') {
           for (Class class_ in library.classes) {
             if (class_.name == 'Widget') {
               _widgetClass = class_;
+              foundWidgetClass = true;
             }
           }
         } else {
@@ -344,14 +347,18 @@
             for (Class class_ in library.classes) {
               if (class_.name == '_HasCreationLocation') {
                 _hasCreationLocationClass = class_;
+                foundHasCreationLocationClass = true;
               } else if (class_.name == '_Location') {
                 _locationClass = class_;
+                foundLocationClass = true;
               }
             }
           }
         }
       }
     }
+    _foundClasses =
+        foundWidgetClass && foundHasCreationLocationClass && foundLocationClass;
   }
 
   /// Modify [clazz] to add a field named [_locationFieldName] that is the
@@ -360,9 +367,9 @@
   /// This method should only be called for classes that implement but do not
   /// extend [Widget].
   void _transformClassImplementingWidget(
-      Class clazz, ChangedStructureNotifier changedStructureNotifier) {
+      Class clazz, ChangedStructureNotifier? changedStructureNotifier) {
     if (clazz.fields
-        .any((Field field) => field.name.text == _locationFieldName)) {
+        .any((Field field) => field.name!.text == _locationFieldName)) {
       // This class has already been transformed. Skip
       return;
     }
@@ -383,7 +390,7 @@
         isFinal: true,
         getterReference: clazz.reference.canonicalName
             ?.getChildFromFieldWithName(fieldName)
-            ?.reference);
+            .reference);
     clazz.addField(locationField);
 
     final Set<Constructor> _handledConstructors =
@@ -394,7 +401,7 @@
         return;
       }
       assert(!_hasNamedParameter(
-        constructor.function,
+        constructor.function!,
         _creationLocationParameterName,
       ));
       final VariableDeclaration variable = new VariableDeclaration(
@@ -402,7 +409,7 @@
           type: new InterfaceType(
               _locationClass, clazz.enclosingLibrary.nullable),
           initializer: new NullLiteral());
-      if (!_maybeAddNamedParameter(constructor.function, variable)) {
+      if (!_maybeAddNamedParameter(constructor.function!, variable)) {
         return;
       }
 
@@ -417,7 +424,7 @@
           }
           _maybeAddCreationLocationArgument(
             initializer.arguments,
-            initializer.target.function,
+            initializer.target.function!,
             new VariableGet(variable),
             _locationClass,
           );
@@ -462,14 +469,14 @@
   /// compilation where the class hierarchy is kept between compiles and thus
   /// has to be kept up to date.
   void transform(Component module, List<Library> libraries,
-      ChangedStructureNotifier changedStructureNotifier) {
+      ChangedStructureNotifier? changedStructureNotifier) {
     if (libraries.isEmpty) {
       return;
     }
 
     _resolveFlutterClasses(module.libraries);
 
-    if (_widgetClass == null) {
+    if (!_foundClasses) {
       // This application doesn't actually use the package:flutter library.
       return;
     }
@@ -508,7 +515,7 @@
   bool _isSubclassOf(Class a, Class b) {
     // TODO(askesc): Cache results.
     // TODO(askesc): Test for subtype rather than subclass.
-    Class current = a;
+    Class? current = a;
     while (current != null) {
       if (current == b) return true;
       current = current.superclass;
@@ -520,7 +527,7 @@
       Set<Library> librariesToBeTransformed,
       Set<Class> transformedClasses,
       Class clazz,
-      ChangedStructureNotifier changedStructureNotifier) {
+      ChangedStructureNotifier? changedStructureNotifier) {
     if (!_isSubclassOfWidget(clazz) ||
         !librariesToBeTransformed.contains(clazz.enclosingLibrary) ||
         !transformedClasses.add(clazz)) {
@@ -533,7 +540,7 @@
       _transformWidgetConstructors(
         librariesToBeTransformed,
         transformedClasses,
-        clazz.superclass,
+        clazz.superclass!,
         changedStructureNotifier,
       );
     }
@@ -541,7 +548,7 @@
     for (Procedure procedure in clazz.procedures) {
       if (procedure.isFactory) {
         _maybeAddNamedParameter(
-          procedure.function,
+          procedure.function!,
           new VariableDeclaration(_creationLocationParameterName,
               type: new InterfaceType(
                   _locationClass, clazz.enclosingLibrary.nullable),
@@ -552,7 +559,7 @@
 
     // Handle the widget class and classes that implement but do not extend the
     // widget class.
-    if (!_isSubclassOfWidget(clazz.superclass)) {
+    if (!_isSubclassOfWidget(clazz.superclass!)) {
       _transformClassImplementingWidget(clazz, changedStructureNotifier);
       return;
     }
@@ -571,12 +578,12 @@
               _locationClass, clazz.enclosingLibrary.nullable),
           initializer: new NullLiteral());
       if (_hasNamedParameter(
-          constructor.function, _creationLocationParameterName)) {
+          constructor.function!, _creationLocationParameterName)) {
         // Constructor was already rewritten.
         // TODO(jacobr): is this case actually hit?
         return;
       }
-      if (!_maybeAddNamedParameter(constructor.function, variable)) {
+      if (!_maybeAddNamedParameter(constructor.function!, variable)) {
         return;
       }
       for (Initializer initializer in constructor.initializers) {
@@ -590,7 +597,7 @@
 
           _maybeAddCreationLocationArgument(
             initializer.arguments,
-            initializer.target.function,
+            initializer.target.function!,
             new VariableGet(variable),
             _locationClass,
           );
@@ -598,7 +605,7 @@
             _isSubclassOfWidget(initializer.target.enclosingClass)) {
           _maybeAddCreationLocationArgument(
             initializer.arguments,
-            initializer.target.function,
+            initializer.target.function!,
             new VariableGet(variable),
             _locationClass,
           );
diff --git a/pkg/kernel/lib/transformations/type_casts_optimizer.dart b/pkg/kernel/lib/transformations/type_casts_optimizer.dart
index 4df790f..3ddbb77 100644
--- a/pkg/kernel/lib/transformations/type_casts_optimizer.dart
+++ b/pkg/kernel/lib/transformations/type_casts_optimizer.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:kernel/ast.dart';
+import 'package:kernel/core_types.dart' show CoreTypes;
 import 'package:kernel/type_environment.dart'
     show StaticTypeContext, SubtypeCheckMode, TypeEnvironment;
 
@@ -51,7 +52,7 @@
 // operand).
 bool isRedundantTypeCast(AsExpression node, DartType operandStaticType,
     TypeEnvironment env, bool nullSafety) {
-  if (!_canBeTransformed(node)) {
+  if (!_canBeTransformed(node, env.coreTypes)) {
     return false;
   }
 
@@ -68,7 +69,7 @@
 // 'Let tmp = [node.operand] in (tmp == null) ? tmp as T : tmp'.
 bool canBeReducedToNullCheckAndCast(AsExpression node,
     DartType operandStaticType, TypeEnvironment env, bool nullSafety) {
-  if (!_canBeTransformed(node)) {
+  if (!_canBeTransformed(node, env.coreTypes)) {
     return false;
   }
 
@@ -83,7 +84,7 @@
   return false;
 }
 
-bool _canBeTransformed(AsExpression node) {
+bool _canBeTransformed(AsExpression node, CoreTypes coreTypes) {
   if (node.isCovarianceCheck) {
     // Keep casts inserted by the front-end to ensure soundness of
     // covariant types.
@@ -91,8 +92,10 @@
   }
 
   final DartType dst = node.type;
-  if (dst is DynamicType || dst is InvalidType) {
-    // Keep casts to dynamic as they have zero overhead but change
+  if (dst is DynamicType ||
+      dst is InvalidType ||
+      (dst is InterfaceType && dst.classNode == coreTypes.functionClass)) {
+    // Keep casts to dynamic and Function as they change
     // the semantics of calls. Also keep invalid types.
     return false;
   }
diff --git a/pkg/kernel/lib/transformations/value_class.dart b/pkg/kernel/lib/transformations/value_class.dart
index 0264e0a..5a5f424 100644
--- a/pkg/kernel/lib/transformations/value_class.dart
+++ b/pkg/kernel/lib/transformations/value_class.dart
@@ -52,7 +52,7 @@
   // V v;
   // (v as dynamic).copyWith() as V
   bool predicate(MethodInvocation node) {
-    return node.name.name == "copyWith" &&
+    return node.name.text == "copyWith" &&
         _isValueClassAsConstruct(node.receiver);
   }
 
diff --git a/pkg/kernel/lib/type_algebra.dart b/pkg/kernel/lib/type_algebra.dart
index 0976e98..ebf18f2 100644
--- a/pkg/kernel/lib/type_algebra.dart
+++ b/pkg/kernel/lib/type_algebra.dart
@@ -675,6 +675,10 @@
     return node.typeArguments.any(visit);
   }
 
+  bool visitExtensionType(ExtensionType node) {
+    return node.typeArguments.any(visit);
+  }
+
   bool visitFutureOrType(FutureOrType node) {
     return visit(node.typeArgument);
   }
@@ -727,6 +731,10 @@
     return node.typeArguments.any(visit);
   }
 
+  bool visitExtensionType(ExtensionType node) {
+    return node.typeArguments.any(visit);
+  }
+
   bool visitFutureOrType(FutureOrType node) {
     return visit(node.typeArgument);
   }
@@ -782,6 +790,10 @@
     return node.typeArguments.any(visit);
   }
 
+  bool visitExtensionType(ExtensionType node) {
+    return node.typeArguments.any(visit);
+  }
+
   bool visitFutureOrType(FutureOrType node) {
     return visit(node.typeArgument);
   }
@@ -881,6 +893,11 @@
   }
 
   @override
+  bool visitExtensionType(ExtensionType node) {
+    return node.typeArguments.isEmpty;
+  }
+
+  @override
   bool visitInvalidType(InvalidType node) {
     throw new UnsupportedError(
         "Unsupported operation: _PrimitiveTypeVerifier(InvalidType).");
@@ -950,6 +967,11 @@
   }
 
   @override
+  DartType visitExtensionType(ExtensionType node, CoreTypes coreTypes) {
+    return node.withDeclaredNullability(Nullability.nonNullable);
+  }
+
+  @override
   DartType visitInvalidType(InvalidType node, CoreTypes coreTypes) => node;
 
   @override
@@ -1163,6 +1185,13 @@
   }
 
   @override
+  bool visitExtensionType(ExtensionType node) {
+    assert(node.declaredNullability != Nullability.undetermined);
+    return node.declaredNullability == Nullability.nullable ||
+        node.declaredNullability == Nullability.legacy;
+  }
+
+  @override
   bool visitInvalidType(InvalidType node) => false;
 
   @override
diff --git a/pkg/kernel/lib/type_checker.dart b/pkg/kernel/lib/type_checker.dart
index a42bdc8..d078850 100644
--- a/pkg/kernel/lib/type_checker.dart
+++ b/pkg/kernel/lib/type_checker.dart
@@ -1156,6 +1156,19 @@
   }
 
   @override
+  DartType visitInstanceGetterInvocation(InstanceGetterInvocation node) {
+    // TODO(johnniwinther): Use embedded static type.
+    Member target = node.interfaceTarget;
+    assert(
+        !(target is Procedure &&
+            environment.isSpecialCasedBinaryOperator(target)),
+        "Unexpected instance getter invocation target: $target");
+    visitExpression(node.receiver);
+    return handleCall(node.arguments, target.getterType,
+        receiver: getReceiverType(node, node.receiver, node.interfaceTarget));
+  }
+
+  @override
   DartType visitInstanceSet(InstanceSet node) {
     DartType value = visitExpression(node.value);
     Substitution receiver =
diff --git a/pkg/kernel/lib/verifier.dart b/pkg/kernel/lib/verifier.dart
index 8cbf77b..4ecf6ce 100644
--- a/pkg/kernel/lib/verifier.dart
+++ b/pkg/kernel/lib/verifier.dart
@@ -459,6 +459,7 @@
   }
 
   visitLet(Let node) {
+    if (_isCompileTimeErrorEncoding(node)) return;
     visitWithLocalScope(node);
   }
 
@@ -921,6 +922,12 @@
   }
 
   @override
+  void visitLet(Let node) {
+    if (_isCompileTimeErrorEncoding(node)) return;
+    super.visitLet(node);
+  }
+
+  @override
   void defaultExpression(Expression node) {
     try {
       node.getStaticType(_staticTypeContext);
@@ -961,3 +968,7 @@
 void checkInitializers(Constructor constructor) {
   // TODO(ahe): I'll add more here in other CLs.
 }
+
+bool _isCompileTimeErrorEncoding(TreeNode? node) {
+  return node is Let && node.variable.initializer is InvalidExpression;
+}
diff --git a/pkg/kernel/lib/visitor.dart b/pkg/kernel/lib/visitor.dart
index ae54219..c40fde0 100644
--- a/pkg/kernel/lib/visitor.dart
+++ b/pkg/kernel/lib/visitor.dart
@@ -35,6 +35,8 @@
   R visitDynamicInvocation(DynamicInvocation node) => defaultExpression(node);
   R visitFunctionInvocation(FunctionInvocation node) => defaultExpression(node);
   R visitInstanceInvocation(InstanceInvocation node) => defaultExpression(node);
+  R visitInstanceGetterInvocation(InstanceGetterInvocation node) =>
+      defaultExpression(node);
   R visitEqualsNull(EqualsNull node) => defaultExpression(node);
   R visitEqualsCall(EqualsCall node) => defaultExpression(node);
   R visitMethodInvocation(MethodInvocation node) => defaultExpression(node);
@@ -207,6 +209,8 @@
   R visitDynamicInvocation(DynamicInvocation node) => defaultExpression(node);
   R visitFunctionInvocation(FunctionInvocation node) => defaultExpression(node);
   R visitInstanceInvocation(InstanceInvocation node) => defaultExpression(node);
+  R visitInstanceGetterInvocation(InstanceGetterInvocation node) =>
+      defaultExpression(node);
   R visitEqualsNull(EqualsNull node) => defaultExpression(node);
   R visitEqualsCall(EqualsCall node) => defaultExpression(node);
   R visitMethodInvocation(MethodInvocation node) => defaultExpression(node);
@@ -363,6 +367,8 @@
       defaultExpression(node, arg);
   R visitInstanceInvocation(InstanceInvocation node, A arg) =>
       defaultExpression(node, arg);
+  R visitInstanceGetterInvocation(InstanceGetterInvocation node, A arg) =>
+      defaultExpression(node, arg);
   R visitEqualsNull(EqualsNull node, A arg) => defaultExpression(node, arg);
   R visitEqualsCall(EqualsCall node, A arg) => defaultExpression(node, arg);
   R visitMethodInvocation(MethodInvocation node, A arg) =>
@@ -523,6 +529,7 @@
   R visitTypedefType(TypedefType node) => defaultDartType(node);
   R visitNeverType(NeverType node) => defaultDartType(node);
   R visitNullType(NullType node) => defaultDartType(node);
+  R visitExtensionType(ExtensionType node) => defaultDartType(node);
 }
 
 abstract class DartTypeVisitor1<R, T> {
@@ -539,6 +546,7 @@
   R visitTypedefType(TypedefType node, T arg) => defaultDartType(node, arg);
   R visitNeverType(NeverType node, T arg) => defaultDartType(node, arg);
   R visitNullType(NullType node, T arg) => defaultDartType(node, arg);
+  R visitExtensionType(ExtensionType node, T arg) => defaultDartType(node, arg);
 }
 
 /// Visitor for [Constant] nodes.
@@ -777,6 +785,7 @@
   R visitTypedefType(TypedefType node) => defaultDartType(node);
   R visitNeverType(NeverType node) => defaultDartType(node);
   R visitNullType(NullType node) => defaultDartType(node);
+  R visitExtensionType(ExtensionType node) => defaultDartType(node);
 
   // Constants
   R defaultConstant(Constant node) => defaultNode(node);
@@ -801,6 +810,8 @@
 
   R visitTypedefReference(Typedef node);
 
+  R visitExtensionReference(Extension node);
+
   // Constant references
   R defaultConstantReference(Constant node);
 
@@ -873,6 +884,13 @@
   }
 
   @override
+  R visitExtensionReference(Extension node) {
+    throw new UnimplementedError(
+        'Unimplemented ${runtimeType}.visitExtensionReference for '
+        '${node} (${node.runtimeType})');
+  }
+
+  @override
   R defaultConstantReference(Constant node) {
     throw new UnimplementedError(
         'Unimplemented ${runtimeType}.defaultConstantReference for '
@@ -900,6 +918,9 @@
   R? visitTypedefReference(Typedef node) => null;
 
   @override
+  R? visitExtensionReference(Extension node) => null;
+
+  @override
   R? defaultConstantReference(Constant node) => null;
 
   @override
@@ -918,6 +939,9 @@
   void visitTypedefReference(Typedef node) {}
 
   @override
+  void visitExtensionReference(Extension node) {}
+
+  @override
   void defaultConstantReference(Constant node) {}
 
   @override
@@ -938,6 +962,9 @@
   R visitTypedefReference(Typedef node) => defaultValue;
 
   @override
+  R visitExtensionReference(Extension node) => defaultValue;
+
+  @override
   R defaultConstantReference(Constant node) => defaultValue;
 
   @override
@@ -1450,6 +1477,8 @@
       defaultExpression(node, arg);
   R visitInstanceInvocation(InstanceInvocation node, T arg) =>
       defaultExpression(node, arg);
+  R visitInstanceGetterInvocation(InstanceGetterInvocation node, T arg) =>
+      defaultExpression(node, arg);
   R visitEqualsNull(EqualsNull node, T arg) => defaultExpression(node, arg);
   R visitEqualsCall(EqualsCall node, T arg) => defaultExpression(node, arg);
   R visitMethodInvocation(MethodInvocation node, T arg) =>
diff --git a/pkg/kernel/pubspec.yaml b/pkg/kernel/pubspec.yaml
index 09b5348..72c0820 100644
--- a/pkg/kernel/pubspec.yaml
+++ b/pkg/kernel/pubspec.yaml
@@ -8,8 +8,6 @@
 environment:
   sdk: '>=2.12.0 <3.0.0'
 dependencies:
-  meta:
-    path: ../meta
 dev_dependencies:
   args: '>=0.13.4 <2.0.0'
   expect:
diff --git a/pkg/kernel/test/convert_field_to_setter_getter.dart b/pkg/kernel/test/convert_field_to_setter_getter.dart
index 8cc17a4..fe37493 100644
--- a/pkg/kernel/test/convert_field_to_setter_getter.dart
+++ b/pkg/kernel/test/convert_field_to_setter_getter.dart
@@ -37,13 +37,15 @@
   List<int> writtenBytesFieldOriginal = serialize(lib1, lib2);
   // Canonical names are now set: Verify that the field is marked as such,
   // canonical-name-wise.
-  if (field.getterCanonicalName.parent.name != "@fields") {
-    throw "Expected @fields parent, but had "
-        "${field.getterCanonicalName.parent.name}";
+  String getterCanonicalName = '${field.getterReference.canonicalName}';
+  if (field.getterReference.canonicalName.parent.name != "@getters") {
+    throw "Expected @getters parent, but had "
+        "${field.getterReference.canonicalName.parent.name}";
   }
-  if (field.setterCanonicalName.parent.name != "@=fields") {
-    throw "Expected @=fields parent, but had "
-        "${field.setterCanonicalName.parent.name}";
+  String setterCanonicalName = '${field.setterReference.canonicalName}';
+  if (field.setterReference.canonicalName.parent.name != "@setters") {
+    throw "Expected @setters parent, but had "
+        "${field.setterReference.canonicalName.parent.name}";
   }
 
   // Replace the field with a setter/getter pair.
@@ -76,13 +78,23 @@
   List<int> writtenBytesGetterSetter = serialize(lib1, lib2);
   // Canonical names are now set: Verify that the getter/setter is marked as
   // such, canonical-name-wise.
-  if (getter.canonicalName.parent.name != "@getters") {
+  if (getter.reference.canonicalName.parent.name != "@getters") {
     throw "Expected @getters parent, but had "
-        "${getter.canonicalName.parent.name}";
+        "${getter.reference.canonicalName.parent.name}";
   }
-  if (setter.canonicalName.parent.name != "@setters") {
+  if ('${getter.reference.canonicalName}' != getterCanonicalName) {
+    throw "Unexpected getter canonical name. "
+        "Expected $getterCanonicalName, "
+        "actual ${getter.reference.canonicalName}.";
+  }
+  if (setter.reference.canonicalName.parent.name != "@setters") {
     throw "Expected @setters parent, but had "
-        "${setter.canonicalName.parent.name}";
+        "${setter.reference.canonicalName.parent.name}";
+  }
+  if ('${setter.reference.canonicalName}' != setterCanonicalName) {
+    throw "Unexpected setter canonical name. "
+        "Expected $setterCanonicalName, "
+        "actual ${setter.reference.canonicalName}.";
   }
 
   // Replace getter/setter with field.
@@ -101,13 +113,15 @@
   List<int> writtenBytesFieldNew = serialize(lib1, lib2);
   // Canonical names are now set: Verify that the field is marked as such,
   // canonical-name-wise.
-  if (fieldReplacement.getterCanonicalName.parent.name != "@fields") {
-    throw "Expected @fields parent, but had "
-        "${fieldReplacement.getterCanonicalName.parent.name}";
+  if (fieldReplacement.getterReference.canonicalName.parent.name !=
+      "@getters") {
+    throw "Expected @getters parent, but had "
+        "${fieldReplacement.getterReference.canonicalName.parent.name}";
   }
-  if (fieldReplacement.setterCanonicalName.parent.name != "@=fields") {
-    throw "Expected @=fields parent, but had "
-        "${fieldReplacement.setterCanonicalName.parent.name}";
+  if (fieldReplacement.setterReference.canonicalName.parent.name !=
+      "@setters") {
+    throw "Expected @setters parent, but had "
+        "${fieldReplacement.setterReference.canonicalName.parent.name}";
   }
 
   // Load the written stuff and ensure it is as expected.
diff --git a/pkg/kernel/test/metadata_test.dart b/pkg/kernel/test/metadata_test.dart
index 653bdaa..ed46532 100644
--- a/pkg/kernel/test/metadata_test.dart
+++ b/pkg/kernel/test/metadata_test.dart
@@ -66,7 +66,8 @@
     expect(metadata, equals(mapping[node]));
     sink.writeByteList(utf8.encode(metadata.string));
     sink.writeStringReference(metadata.string);
-    sink.writeNullAllowedCanonicalNameReference(metadata.member?.canonicalName);
+    sink.writeNullAllowedCanonicalNameReference(
+        metadata.member?.reference?.canonicalName);
     sink.writeDartType(metadata.type);
   }
 
diff --git a/pkg/kernel/test/non_null_test.dart b/pkg/kernel/test/non_null_test.dart
index ef3b433..5a3dca1 100644
--- a/pkg/kernel/test/non_null_test.dart
+++ b/pkg/kernel/test/non_null_test.dart
@@ -29,18 +29,18 @@
   'List<Object*>': 'List<Object*>',
   'List<Object*>?': 'List<Object*>',
   'List<Object*>*': 'List<Object*>',
-  'FutureOr<Null>': 'FutureOr<Never>',
+  'FutureOr<Null>': 'FutureOr<Null>',
   'FutureOr<dynamic>': 'FutureOr<dynamic>',
   'FutureOr<Object>': 'FutureOr<Object>',
   'FutureOr<Object>?': 'FutureOr<Object>',
   'FutureOr<Object>*': 'FutureOr<Object>',
-  'FutureOr<Object?>': 'FutureOr<Object>',
-  'FutureOr<Object?>?': 'FutureOr<Object>',
-  'FutureOr<Object?>*': 'FutureOr<Object>',
-  'FutureOr<Object*>': 'FutureOr<Object>',
-  'FutureOr<Object*>?': 'FutureOr<Object>',
-  'FutureOr<Object*>*': 'FutureOr<Object>',
-  'FutureOr<FutureOr<Object?>>': 'FutureOr<FutureOr<Object>>',
+  'FutureOr<Object?>': 'FutureOr<Object?>',
+  'FutureOr<Object?>?': 'FutureOr<Object?>',
+  'FutureOr<Object?>*': 'FutureOr<Object?>',
+  'FutureOr<Object*>': 'FutureOr<Object*>',
+  'FutureOr<Object*>?': 'FutureOr<Object*>',
+  '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>',
diff --git a/pkg/kernel/test/text_serializer_from_kernel_nodes_test.dart b/pkg/kernel/test/text_serializer_from_kernel_nodes_test.dart
index 0c1c2e4a..df7b9ff 100644
--- a/pkg/kernel/test/text_serializer_from_kernel_nodes_test.dart
+++ b/pkg/kernel/test/text_serializer_from_kernel_nodes_test.dart
@@ -133,7 +133,7 @@
           name: '/* suppose top-level: dynamic field; */ field;',
           node: new ExpressionStatement(new StaticGet(field)),
           expectation: ''
-              '(expr (get-static "package:foo/bar.dart::@fields::field"))',
+              '(expr (get-static "package:foo/bar.dart::@getters::field"))',
           makeSerializationState: () => new SerializationState(null),
           makeDeserializationState: () =>
               new DeserializationState(null, component.root),
@@ -151,7 +151,7 @@
           name: '/* suppose top-level: dynamic field; */ field;',
           node: new ExpressionStatement(new StaticGet(field)),
           expectation: ''
-              '(expr (get-static "package:foo/bar.dart::@fields::field"))',
+              '(expr (get-static "package:foo/bar.dart::@getters::field"))',
           makeSerializationState: () => new SerializationState(null),
           makeDeserializationState: () =>
               new DeserializationState(null, component.root),
@@ -171,7 +171,7 @@
               new ExpressionStatement(new StaticSet(field, new IntLiteral(1))),
           expectation: ''
               '(expr'
-              ' (set-static "package:foo/bar.dart::@=fields::field" (int 1)))',
+              ' (set-static "package:foo/bar.dart::@setters::field" (int 1)))',
           makeSerializationState: () => new SerializationState(null),
           makeDeserializationState: () =>
               new DeserializationState(null, component.root),
diff --git a/pkg/nnbd_migration/lib/migration_cli.dart b/pkg/nnbd_migration/lib/migration_cli.dart
index 5705e9a..9298730 100644
--- a/pkg/nnbd_migration/lib/migration_cli.dart
+++ b/pkg/nnbd_migration/lib/migration_cli.dart
@@ -142,7 +142,7 @@
   static const String cmdName = 'migrate';
 
   static const String cmdDescription =
-      'Perform a null safety migration on a project or package.';
+      'Perform null safety migration on a project.';
 
   static const String migrationGuideLink =
       'See https://dart.dev/go/null-safety-migration for a migration guide.';
@@ -225,7 +225,7 @@
               defaultsTo: false,
               negatable: false,
               help:
-                  'Attempt to perform null safety analysis even if the package has '
+                  'Attempt to perform null safety analysis even if the project has '
                   'analysis errors.',
             )),
     MigrationCliOption(
@@ -428,7 +428,7 @@
   }
 
   void _showUsage(bool isVerbose) {
-    logger.stderr('Usage: $binaryName [options...] [<package directory>]');
+    logger.stderr('Usage: $binaryName [options...] [<project directory>]');
 
     logger.stderr('');
     logger.stderr(createParser(hide: !isVerbose).usage);
diff --git a/pkg/nnbd_migration/lib/nnbd_migration.dart b/pkg/nnbd_migration/lib/nnbd_migration.dart
index a05c09f..6dd3991 100644
--- a/pkg/nnbd_migration/lib/nnbd_migration.dart
+++ b/pkg/nnbd_migration/lib/nnbd_migration.dart
@@ -18,6 +18,11 @@
 
 /// Description of fixes that might be performed by nullability migration.
 class NullabilityFixDescription {
+  /// A `.then((value) => ...)` suffix was added to an expression.
+  static const addThen = NullabilityFixDescription._(
+      appliedMessage: 'Added `.then` to adjust type of Future expression',
+      kind: NullabilityFixKind.addThen);
+
   /// An import was added to the library.
   static const addImport = NullabilityFixDescription._(
       appliedMessage: 'Added import for use in migrated code',
@@ -266,6 +271,7 @@
 
 /// An enumeration of the various kinds of nullability fixes.
 enum NullabilityFixKind {
+  addThen,
   addImport,
   addLate,
   addLateDueToHint,
diff --git a/pkg/nnbd_migration/lib/src/edge_builder.dart b/pkg/nnbd_migration/lib/src/edge_builder.dart
index 850669e..26ad6fe 100644
--- a/pkg/nnbd_migration/lib/src/edge_builder.dart
+++ b/pkg/nnbd_migration/lib/src/edge_builder.dart
@@ -1776,7 +1776,7 @@
       _flowAnalysis.tryFinallyStatement_finallyBegin(
           catchClauses.isNotEmpty ? node : body);
       _dispatch(finallyBlock);
-      _flowAnalysis.tryFinallyStatement_end(finallyBlock);
+      _flowAnalysis.tryFinallyStatement_end();
     }
     return null;
   }
@@ -2762,10 +2762,11 @@
               source: elementType, destination: lhsType, hard: false);
         }
       }
-      _flowAnalysis.forEach_bodyBegin(
-          node,
-          lhsElement is PromotableElement ? lhsElement : null,
-          elementType ?? _makeNullableDynamicType(node));
+      _flowAnalysis.forEach_bodyBegin(node);
+      if (lhsElement is PromotableElement) {
+        _flowAnalysis.write(node, lhsElement,
+            elementType ?? _makeNullableDynamicType(node), null);
+      }
     }
 
     // The condition may fail/iterable may be empty, so the body gets a new
diff --git a/pkg/nnbd_migration/lib/src/edit_plan.dart b/pkg/nnbd_migration/lib/src/edit_plan.dart
index c603225..bc70677 100644
--- a/pkg/nnbd_migration/lib/src/edit_plan.dart
+++ b/pkg/nnbd_migration/lib/src/edit_plan.dart
@@ -282,21 +282,31 @@
   }
 
   /// Creates a new edit plan that consists of executing [innerPlan], and then
+  /// appending the given text with postfix precedence.  This could be used, for
+  /// example, to append a property access or method call.
+  ///
+  /// Optional argument [info] contains information about why the change was
+  /// made.
+  NodeProducingEditPlan addPostfix(NodeProducingEditPlan innerPlan, String text,
+      {AtomicEditInfo info}) {
+    assert(innerPlan.sourceNode is Expression);
+    return surround(innerPlan,
+        suffix: [AtomicEdit.insert(text, info: info)],
+        outerPrecedence: Precedence.postfix,
+        innerPrecedence: Precedence.postfix,
+        associative: true);
+  }
+
+  /// Creates a new edit plan that consists of executing [innerPlan], and then
   /// appending the given postfix [operator].  This could be used, for example,
   /// to add a null check.
   ///
   /// Optional argument [info] contains information about why the change was
   /// made.
   NodeProducingEditPlan addUnaryPostfix(
-      NodeProducingEditPlan innerPlan, TokenType operator,
-      {AtomicEditInfo info}) {
-    assert(innerPlan.sourceNode is Expression);
-    return surround(innerPlan,
-        suffix: [AtomicEdit.insert(operator.lexeme, info: info)],
-        outerPrecedence: Precedence.postfix,
-        innerPrecedence: Precedence.postfix,
-        associative: true);
-  }
+          NodeProducingEditPlan innerPlan, TokenType operator,
+          {AtomicEditInfo info}) =>
+      addPostfix(innerPlan, operator.lexeme, info: info);
 
   /// Creates a new edit plan that consists of executing [innerPlan], and then
   /// prepending the given prefix [operator].
diff --git a/pkg/nnbd_migration/lib/src/fix_aggregator.dart b/pkg/nnbd_migration/lib/src/fix_aggregator.dart
index 6e57d8d..60e779d 100644
--- a/pkg/nnbd_migration/lib/src/fix_aggregator.dart
+++ b/pkg/nnbd_migration/lib/src/fix_aggregator.dart
@@ -18,6 +18,28 @@
 import 'package:nnbd_migration/src/fix_builder.dart';
 import 'package:nnbd_migration/src/utilities/hint_utils.dart';
 
+/// Base class representing a change that might need to be made to an
+/// expression.
+abstract class ExpressionChange {
+  /// The type of the expression after the change is applied.
+  final DartType resultType;
+
+  ExpressionChange(this.resultType);
+
+  /// Description of the change.
+  NullabilityFixDescription get description;
+
+  /// Creates a [NodeProducingEditPlan] that applies the change to [innerPlan].
+  NodeProducingEditPlan applyExpression(FixAggregator aggregator,
+      NodeProducingEditPlan innerPlan, AtomicEditInfo info);
+
+  /// Creates a string that applies the change to the [inner] text string.
+  String applyText(FixAggregator aggregator, String inner);
+
+  /// Describes the change, for use in debugging.
+  String describe();
+}
+
 /// Visitor that combines together the changes produced by [FixBuilder] into a
 /// concrete set of source code edits using the infrastructure of [EditPlan].
 class FixAggregator extends UnifyingAstVisitor<void> {
@@ -195,6 +217,64 @@
   }
 }
 
+/// [ExpressionChange] describing the addition of an `as` cast to an expression.
+class IntroduceAsChange extends ExpressionChange {
+  /// The type being cast to.
+  final DartType type;
+
+  /// Indicates whether this is a downcast.
+  final bool isDowncast;
+
+  IntroduceAsChange(this.type, {@required this.isDowncast}) : super(type);
+
+  @override
+  NullabilityFixDescription get description => isDowncast
+      ? NullabilityFixDescription.downcastExpression
+      : NullabilityFixDescription.otherCastExpression;
+
+  @override
+  NodeProducingEditPlan applyExpression(FixAggregator aggregator,
+          NodeProducingEditPlan innerPlan, AtomicEditInfo info) =>
+      aggregator.planner.addBinaryPostfix(
+          innerPlan, TokenType.AS, aggregator.typeToCode(type),
+          info: info);
+
+  @override
+  String applyText(FixAggregator aggregator, String inner) =>
+      '$inner as ${aggregator.typeToCode(type)}';
+
+  @override
+  String describe() => 'IntroduceAsChange($type)';
+}
+
+/// [ExpressionChange] describing the addition of an `as` cast to an expression
+/// having a Future type.
+class IntroduceThenChange extends ExpressionChange {
+  /// The change that should be made to the value the future completes with.
+  final ExpressionChange innerChange;
+
+  IntroduceThenChange(DartType resultType, this.innerChange)
+      : super(resultType);
+
+  @override
+  NullabilityFixDescription get description =>
+      NullabilityFixDescription.addThen;
+
+  @override
+  NodeProducingEditPlan applyExpression(FixAggregator aggregator,
+          NodeProducingEditPlan innerPlan, AtomicEditInfo info) =>
+      aggregator.planner.addPostfix(innerPlan,
+          '.then((value) => ${innerChange.applyText(aggregator, 'value')})',
+          info: info);
+
+  @override
+  String applyText(FixAggregator aggregator, String inner) =>
+      '$inner.then((value) => ${innerChange.applyText(aggregator, 'value')})';
+
+  @override
+  String describe() => 'IntroduceThenChange($innerChange)';
+}
+
 /// Reasons that a variable declaration is to be made late.
 enum LateAdditionReason {
   /// It was inferred that the associated variable declaration is to be made
@@ -701,69 +781,25 @@
 /// Implementation of [NodeChange] specialized for operating on [Expression]
 /// nodes.
 class NodeChangeForExpression<N extends Expression> extends NodeChange<N> {
-  bool _addsNoValidMigration = false;
+  /// The list of [ExpressionChange] objects that should be applied to the
+  /// expression, in the order they should be applied.
+  final List<ExpressionChange> expressionChanges = [];
 
-  AtomicEditInfo _addNoValidMigrationInfo;
-
-  bool _addsNullCheck = false;
-
-  AtomicEditInfo _addNullCheckInfo;
-
-  HintComment _addNullCheckHint;
-
-  DartType _introducesAsType;
-
-  AtomicEditInfo _introduceAsInfo;
+  /// The list of [AtomicEditInfo] objects corresponding to each change in
+  /// [expressionChanges].
+  final List<AtomicEditInfo> expressionChangeInfos = [];
 
   NodeChangeForExpression() : super._();
 
-  /// Gets the info for any added "no valid migration" comment.
-  AtomicEditInfo get addNoValidMigrationInfo => _addNoValidMigrationInfo;
-
-  /// Gets the info for any added null check.
-  AtomicEditInfo get addNullCheckInfo => _addNullCheckInfo;
-
-  /// Indicates whether [addNoValidMigration] has been called.
-  bool get addsNoValidMigration => _addsNoValidMigration;
-
-  /// Indicates whether [addNullCheck] has been called.
-  bool get addsNullCheck => _addsNullCheck;
-
-  /// Gets the info for any introduced "as" cast
-  AtomicEditInfo get introducesAsInfo => _introduceAsInfo;
-
-  /// Gets the type for any introduced "as" cast, or `null` if no "as" cast is
-  /// being introduced.
-  DartType get introducesAsType => _introducesAsType;
-
   @override
   Iterable<String> get _toStringParts => [
-        if (_addsNoValidMigration) 'addsNoValidMigration',
-        if (_addsNullCheck) 'addsNullCheck',
-        if (_introducesAsType != null) 'introducesAsType'
+        for (var expressionChange in expressionChanges)
+          expressionChange.describe()
       ];
 
-  void addNoValidMigration(AtomicEditInfo info) {
-    assert(!_addsNoValidMigration);
-    _addsNoValidMigration = true;
-    _addNoValidMigrationInfo = info;
-  }
-
-  /// Causes a null check to be added to this expression, with the given [info].
-  void addNullCheck(AtomicEditInfo info, {HintComment hint}) {
-    assert(!_addsNullCheck);
-    _addsNullCheck = true;
-    _addNullCheckInfo = info;
-    _addNullCheckHint = hint;
-  }
-
-  /// Causes a cast to the given [type] to be added to this expression, with
-  /// the given [info].
-  void introduceAs(DartType type, AtomicEditInfo info) {
-    assert(_introducesAsType == null);
-    assert(type != null);
-    _introducesAsType = type;
-    _introduceAsInfo = info;
+  void addExpressionChange(ExpressionChange change, AtomicEditInfo info) {
+    expressionChanges.add(change);
+    expressionChangeInfos.add(info);
   }
 
   @override
@@ -778,25 +814,9 @@
   NodeProducingEditPlan _applyExpression(
       FixAggregator aggregator, NodeProducingEditPlan innerPlan) {
     var plan = innerPlan;
-    if (_addsNullCheck) {
-      var hint = _addNullCheckHint;
-      if (hint != null) {
-        plan = aggregator.planner.acceptNullabilityOrNullCheckHint(plan, hint,
-            info: _addNullCheckInfo);
-      } else {
-        plan = aggregator.planner
-            .addUnaryPostfix(plan, TokenType.BANG, info: _addNullCheckInfo);
-      }
-    }
-    if (_addsNoValidMigration) {
-      plan = aggregator.planner.addCommentPostfix(
-          plan, '/* no valid migration */',
-          info: _addNoValidMigrationInfo, isInformative: true);
-    }
-    if (_introducesAsType != null) {
-      plan = aggregator.planner.addBinaryPostfix(
-          plan, TokenType.AS, aggregator.typeToCode(_introducesAsType),
-          info: _introduceAsInfo);
+    for (int i = 0; i < expressionChanges.length; i++) {
+      plan = expressionChanges[i]
+          .applyExpression(aggregator, plan, expressionChangeInfos[i]);
     }
     return plan;
   }
@@ -1289,6 +1309,60 @@
   }
 }
 
+/// [ExpressionChange] describing the addition of a comment explaining that a
+/// literal `null` could not be migrated.
+class NoValidMigrationChange extends ExpressionChange {
+  NoValidMigrationChange(DartType resultType) : super(resultType);
+
+  @override
+  NullabilityFixDescription get description =>
+      NullabilityFixDescription.noValidMigrationForNull;
+
+  @override
+  NodeProducingEditPlan applyExpression(FixAggregator aggregator,
+          NodeProducingEditPlan innerPlan, AtomicEditInfo info) =>
+      aggregator.planner.addCommentPostfix(
+          innerPlan, '/* no valid migration */',
+          info: info, isInformative: true);
+
+  @override
+  String applyText(FixAggregator aggregator, String inner) =>
+      '$inner /* no valid migration */';
+
+  @override
+  String describe() => 'NoValidMigrationChange';
+}
+
+/// [ExpressionChange] describing the addition of an `!` after an expression.
+class NullCheckChange extends ExpressionChange {
+  /// The hint that is causing this `!` to be added, if any.
+  final HintComment hint;
+
+  NullCheckChange(DartType resultType, {this.hint}) : super(resultType);
+
+  @override
+  NullabilityFixDescription get description =>
+      NullabilityFixDescription.checkExpression;
+
+  @override
+  NodeProducingEditPlan applyExpression(FixAggregator aggregator,
+      NodeProducingEditPlan innerPlan, AtomicEditInfo info) {
+    if (hint != null) {
+      return aggregator.planner
+          .acceptNullabilityOrNullCheckHint(innerPlan, hint, info: info);
+    } else {
+      return aggregator.planner
+          .addUnaryPostfix(innerPlan, TokenType.BANG, info: info);
+    }
+  }
+
+  @override
+  String applyText(FixAggregator aggregator, String inner) => '$inner!';
+
+  @override
+  String describe() => 'NullCheckChange';
+}
+
 /// Visitor that creates an appropriate [NodeChange] object for the node being
 /// visited.
 class _NodeChangeVisitor extends GeneralizingAstVisitor<NodeChange<AstNode>> {
diff --git a/pkg/nnbd_migration/lib/src/fix_builder.dart b/pkg/nnbd_migration/lib/src/fix_builder.dart
index 0f2cd7f..add21a0 100644
--- a/pkg/nnbd_migration/lib/src/fix_builder.dart
+++ b/pkg/nnbd_migration/lib/src/fix_builder.dart
@@ -515,6 +515,12 @@
   @override
   DartType modifyExpressionType(Expression node, DartType type) =>
       _wrapExceptions(node, () => type, () {
+        if (node is NamedExpression) {
+          // Do not attempt to modify named expressions.  We should already have
+          // been called for [node.expression], and we should have made the
+          // necessary modifications then.
+          return type;
+        }
         var parent = node.parent;
         if (parent is AssignmentExpression) {
           if (parent.leftHandSide == node) {
@@ -577,44 +583,62 @@
     _flowAnalysis = flowAnalysis;
   }
 
-  DartType _addCast(
+  DartType _addCastOrNullCheck(
       Expression node, DartType expressionType, DartType contextType) {
-    var isDowncast =
-        _fixBuilder._typeSystem.isSubtypeOf(contextType, expressionType);
     var checks =
         _fixBuilder._variables.expressionChecks(_fixBuilder.source, node);
-    var info = AtomicEditInfo(
-        isDowncast
-            ? NullabilityFixDescription.downcastExpression
-            : NullabilityFixDescription.otherCastExpression,
-        checks != null ? checks.edges : {});
+    var change = _createExpressionChange(node, expressionType, contextType);
+    var info = AtomicEditInfo(change.description, checks?.edges ?? {});
     (_fixBuilder._getChange(node) as NodeChangeForExpression)
-        .introduceAs(contextType, info);
-    _flowAnalysis.asExpression_end(node, contextType);
-    return contextType;
+        .addExpressionChange(change, info);
+    return change.resultType;
   }
 
   DartType _addNullCheck(Expression node, DartType type,
       {AtomicEditInfo info, HintComment hint}) {
+    var change = _createNullCheckChange(node, type, hint: hint);
     var checks =
         _fixBuilder._variables.expressionChecks(_fixBuilder.source, node);
-    bool noValidMigration = node is NullLiteral && hint == null;
-    info ??= checks != null
-        ? AtomicEditInfo(
-            noValidMigration
-                ? NullabilityFixDescription.noValidMigrationForNull
-                : NullabilityFixDescription.checkExpression,
-            checks.edges)
-        : null;
+    info ??= AtomicEditInfo(change.description, checks?.edges ?? {});
     var nodeChangeForExpression =
         _fixBuilder._getChange(node) as NodeChangeForExpression;
-    if (noValidMigration) {
-      nodeChangeForExpression.addNoValidMigration(info);
-    } else {
-      nodeChangeForExpression.addNullCheck(info, hint: hint);
+    nodeChangeForExpression.addExpressionChange(change, info);
+    return change.resultType;
+  }
+
+  ExpressionChange _createExpressionChange(
+      Expression node, DartType expressionType, DartType contextType) {
+    var expressionFutureTypeArgument = _getFutureTypeArgument(expressionType);
+    var contextFutureTypeArgument = _getFutureTypeArgument(contextType);
+    if (expressionFutureTypeArgument != null &&
+        contextFutureTypeArgument != null) {
+      return IntroduceThenChange(
+          contextType,
+          _createExpressionChange(
+              node, expressionFutureTypeArgument, contextFutureTypeArgument));
     }
+    // Either a cast or a null check is needed.  We prefer to do a null
+    // check if we can.
+    var nonNullType = _fixBuilder._typeSystem.promoteToNonNull(expressionType);
+    if (_fixBuilder._typeSystem.isSubtypeOf(nonNullType, contextType)) {
+      return _createNullCheckChange(node, expressionType);
+    } else {
+      if (node != null) {
+        _flowAnalysis.asExpression_end(node, contextType);
+      }
+      return IntroduceAsChange(contextType,
+          isDowncast:
+              _fixBuilder._typeSystem.isSubtypeOf(contextType, expressionType));
+    }
+  }
+
+  ExpressionChange _createNullCheckChange(Expression node, DartType type,
+      {HintComment hint}) {
+    var resultType = _fixBuilder._typeSystem.promoteToNonNull(type as TypeImpl);
     _flowAnalysis.nonNullAssert_end(node);
-    return _fixBuilder._typeSystem.promoteToNonNull(type as TypeImpl);
+    return node is NullLiteral && hint == null
+        ? NoValidMigrationChange(resultType)
+        : NullCheckChange(resultType, hint: hint);
   }
 
   Expression _findNullabilityContextAncestor(Expression node) {
@@ -638,6 +662,16 @@
     return finalType as InterfaceType;
   }
 
+  DartType _getFutureTypeArgument(DartType type) {
+    if (type is InterfaceType && type.isDartAsyncFuture) {
+      var typeArguments = type.typeArguments;
+      if (typeArguments.isNotEmpty) {
+        return typeArguments.first;
+      }
+    }
+    return null;
+  }
+
   DartType _modifyRValueType(Expression node, DartType type,
       {DartType context}) {
     if (node is MethodInvocation) {
@@ -689,14 +723,7 @@
                 .makeNullable(methodInvocationType as TypeImpl);
         return type;
       }
-      // Either a cast or a null check is needed.  We prefer to do a null
-      // check if we can.
-      var nonNullType = _fixBuilder._typeSystem.promoteToNonNull(type);
-      if (_fixBuilder._typeSystem.isSubtypeOf(nonNullType, context)) {
-        return _addNullCheck(node, type);
-      } else {
-        return _addCast(node, type, context);
-      }
+      return _addCastOrNullCheck(node, type, context);
     }
     if (!_fixBuilder._typeSystem.isNullable(type)) return type;
     if (_needsNullCheckDueToStructure(ancestor)) {
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 7852c1d..39c2926 100644
--- a/pkg/nnbd_migration/lib/src/front_end/info_builder.dart
+++ b/pkg/nnbd_migration/lib/src/front_end/info_builder.dart
@@ -262,6 +262,9 @@
         // We don't offer any edits around unmigratable `null`s.  The user has
         // to fix manually.
         break;
+      case NullabilityFixKind.addThen:
+        // We don't offer any edits around addition of `.then` to a future.
+        break;
     }
     return edits;
   }
diff --git a/pkg/nnbd_migration/lib/src/front_end/instrumentation_renderer.dart b/pkg/nnbd_migration/lib/src/front_end/instrumentation_renderer.dart
index 515595f..d2abbfc 100644
--- a/pkg/nnbd_migration/lib/src/front_end/instrumentation_renderer.dart
+++ b/pkg/nnbd_migration/lib/src/front_end/instrumentation_renderer.dart
@@ -20,7 +20,7 @@
 
   // Convert a git hash to 8 chars.
   // '2.8.0-edge.fd992e423ef69ece9f44bd3ac58fa2355b563212'
-  var versionRegExp = RegExp(r'^.*\.([0123456789abcdef]+)$');
+  var versionRegExp = RegExp(r'^.*\.([0-9a-f]+)$');
   var match = versionRegExp.firstMatch(version);
   if (match != null && match.group(1).length == 40) {
     var commit = match.group(1);
diff --git a/pkg/nnbd_migration/lib/src/front_end/migration_summary.dart b/pkg/nnbd_migration/lib/src/front_end/migration_summary.dart
index a551df2..e8e39e1 100644
--- a/pkg/nnbd_migration/lib/src/front_end/migration_summary.dart
+++ b/pkg/nnbd_migration/lib/src/front_end/migration_summary.dart
@@ -60,6 +60,8 @@
 
   String _keyForKind(NullabilityFixKind kind) {
     switch (kind) {
+      case NullabilityFixKind.addThen:
+        return 'addThen';
       case NullabilityFixKind.addImport:
         return 'addImport';
       case NullabilityFixKind.addLate:
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 20e8f55..cf5fc65 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
@@ -277,7 +277,8 @@
         var edit = SourceEdit(offset, configText.length, newText);
         listener.addSourceFileEdit(
             'enable Null Safety language feature',
-            Location(packageConfigFile.path, offset, newText.length, line, 0),
+            Location(
+                packageConfigFile.path, offset, newText.length, line, 0, 0, 0),
             SourceFileEdit(packageConfigFile.path, 0, edits: [edit]));
       }
     } on FormatException catch (e) {
@@ -598,7 +599,7 @@
     var edit = SourceEdit(offset, 0, content);
     listener.addSourceFileEdit(
         'enable Null Safety language feature',
-        Location(path, offset, content.length, line, 0),
+        Location(path, offset, content.length, line, 0, 0, 0),
         SourceFileEdit(path, 0, edits: [edit]));
   }
 
@@ -608,7 +609,7 @@
     var edit = SourceEdit(offset, span.length, content);
     listener.addSourceFileEdit(
         'enable Null Safety language feature',
-        Location(path, offset, content.length, line, 0),
+        Location(path, offset, content.length, line, 0, 0, 0),
         SourceFileEdit(path, 0, edits: [edit]));
   }
 
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 6135b67..411aa65 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
@@ -7708,7 +7708,7 @@
 ''';
 
 String _migration_js;
-// migration_dart md5 is '03afca61a670ed406ad057b159139998'
+// migration_dart md5 is '62f4a5cddf945de898f19cea860ec0b5'
 String _migration_js_base64 = '''
 KGZ1bmN0aW9uIGRhcnRQcm9ncmFtKCl7ZnVuY3Rpb24gY29weVByb3BlcnRpZXMoYSxiKXt2YXIgcz1P
 YmplY3Qua2V5cyhhKQpmb3IodmFyIHI9MDtyPHMubGVuZ3RoO3IrKyl7dmFyIHE9c1tyXQpiW3FdPWFb
@@ -7802,2615 +7802,2641 @@
 YXJ0IixudWxsKSl9cmV0dXJuIG5ldyBILm5IKGEsYixjLGQuQygibkg8MD4iKSl9LApLMTpmdW5jdGlv
 bihhLGIsYyxkKXtpZih0LmQuYihhKSlyZXR1cm4gbmV3IEgueHkoYSxiLGMuQygiQDwwPiIpLktxKGQp
 LkMoInh5PDEsMj4iKSkKcmV0dXJuIG5ldyBILmkxKGEsYixjLkMoIkA8MD4iKS5LcShkKS5DKCJpMTwx
-LDI+IikpfSwKYks6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzPSJjb3VudCIKaWYodC5kLmIoYSkpe1AuTVIo
-YixzLHQuUykKUC5rMShiLHMpCnJldHVybiBuZXcgSC5kNShhLGIsYy5DKCJkNTwwPiIpKX1QLk1SKGIs
-cyx0LlMpClAuazEoYixzKQpyZXR1cm4gbmV3IEguQU0oYSxiLGMuQygiQU08MD4iKSl9LApXcDpmdW5j
-dGlvbigpe3JldHVybiBuZXcgUC5saigiTm8gZWxlbWVudCIpfSwKQW06ZnVuY3Rpb24oKXtyZXR1cm4g
-bmV3IFAubGooIlRvbyBtYW55IGVsZW1lbnRzIil9LAphcjpmdW5jdGlvbigpe3JldHVybiBuZXcgUC5s
-aigiVG9vIGZldyBlbGVtZW50cyIpfSwKQlI6ZnVuY3Rpb24gQlIoKXt9LApFNzpmdW5jdGlvbiBFNyhh
-LGIpe3RoaXMuYT1hCnRoaXMuJHRpPWJ9LApaeTpmdW5jdGlvbiBaeShhLGIpe3RoaXMuYT1hCnRoaXMu
-JHRpPWJ9LApvbDpmdW5jdGlvbiBvbChhLGIpe3RoaXMuYT1hCnRoaXMuJHRpPWJ9LApVcTpmdW5jdGlv
-biBVcSgpe30sCmpWOmZ1bmN0aW9uIGpWKGEsYil7dGhpcy5hPWEKdGhpcy4kdGk9Yn0sCm46ZnVuY3Rp
-b24gbihhKXt0aGlzLmE9YX0sCnIzOmZ1bmN0aW9uIHIzKGEpe3RoaXMuYT1hfSwKcWo6ZnVuY3Rpb24g
-cWooYSl7dGhpcy5hPWF9LApHTTpmdW5jdGlvbiBHTShhLGIpe3RoaXMuYT1hCnRoaXMuJHRpPWJ9LApi
-UTpmdW5jdGlvbiBiUSgpe30sCmFMOmZ1bmN0aW9uIGFMKCl7fSwKbkg6ZnVuY3Rpb24gbkgoYSxiLGMs
-ZCl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLiR0aT1kfSwKYTc6ZnVuY3Rpb24gYTcoYSxi
-LGMpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5jPTAKXy5kPW51bGwKXy4kdGk9Y30sCmkxOmZ1bmN0
-aW9uIGkxKGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLiR0aT1jfSwKeHk6ZnVuY3Rpb24geHko
-YSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuJHRpPWN9LApNSDpmdW5jdGlvbiBNSChhLGIsYyl7
-dmFyIF89dGhpcwpfLmE9bnVsbApfLmI9YQpfLmM9YgpfLiR0aT1jfSwKbEo6ZnVuY3Rpb24gbEooYSxi
-LGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuJHRpPWN9LApVNTpmdW5jdGlvbiBVNShhLGIsYyl7dGhp
-cy5hPWEKdGhpcy5iPWIKdGhpcy4kdGk9Y30sClNPOmZ1bmN0aW9uIFNPKGEsYixjKXt0aGlzLmE9YQp0
-aGlzLmI9Ygp0aGlzLiR0aT1jfSwKQU06ZnVuY3Rpb24gQU0oYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1i
-CnRoaXMuJHRpPWN9LApkNTpmdW5jdGlvbiBkNShhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy4k
-dGk9Y30sClUxOmZ1bmN0aW9uIFUxKGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLiR0aT1jfSwK
-TUI6ZnVuY3Rpb24gTUIoYSl7dGhpcy4kdGk9YX0sCkZ1OmZ1bmN0aW9uIEZ1KGEpe3RoaXMuJHRpPWF9
-LAp1NjpmdW5jdGlvbiB1NihhLGIpe3RoaXMuYT1hCnRoaXMuJHRpPWJ9LApKQjpmdW5jdGlvbiBKQihh
-LGIpe3RoaXMuYT1hCnRoaXMuJHRpPWJ9LApTVTpmdW5jdGlvbiBTVSgpe30sClJlOmZ1bmN0aW9uIFJl
-KCl7fSwKdzI6ZnVuY3Rpb24gdzIoKXt9LAp3djpmdW5jdGlvbiB3dihhKXt0aGlzLmE9YX0sClFDOmZ1
-bmN0aW9uIFFDKCl7fSwKZGM6ZnVuY3Rpb24oKXt0aHJvdyBILmIoUC5MNCgiQ2Fubm90IG1vZGlmeSB1
-bm1vZGlmaWFibGUgTWFwIikpfSwKTlE6ZnVuY3Rpb24oYSl7dmFyIHMscj1ILkpnKGEpCmlmKHIhPW51
-bGwpcmV0dXJuIHIKcz0ibWluaWZpZWQ6IithCnJldHVybiBzfSwKd1Y6ZnVuY3Rpb24oYSxiKXt2YXIg
-cwppZihiIT1udWxsKXtzPWIueAppZihzIT1udWxsKXJldHVybiBzfXJldHVybiB0LmFVLmIoYSl9LApF
-ajpmdW5jdGlvbihhKXt2YXIgcwppZih0eXBlb2YgYT09InN0cmluZyIpcmV0dXJuIGEKaWYodHlwZW9m
-IGE9PSJudW1iZXIiKXtpZihhIT09MClyZXR1cm4iIithfWVsc2UgaWYoITA9PT1hKXJldHVybiJ0cnVl
-IgplbHNlIGlmKCExPT09YSlyZXR1cm4iZmFsc2UiCmVsc2UgaWYoYT09bnVsbClyZXR1cm4ibnVsbCIK
-cz1KLmooYSkKaWYodHlwZW9mIHMhPSJzdHJpbmciKXRocm93IEguYihILnRMKGEpKQpyZXR1cm4gc30s
-CmVROmZ1bmN0aW9uKGEpe3ZhciBzPWEuJGlkZW50aXR5SGFzaAppZihzPT1udWxsKXtzPU1hdGgucmFu
-ZG9tKCkqMHgzZmZmZmZmZnwwCmEuJGlkZW50aXR5SGFzaD1zfXJldHVybiBzfSwKSHA6ZnVuY3Rpb24o
-YSxiKXt2YXIgcyxyLHEscCxvLG4sbT1udWxsCmlmKHR5cGVvZiBhIT0ic3RyaW5nIilILnYoSC50TChh
-KSkKcz0vXlxzKlsrLV0/KCgweFthLWYwLTldKyl8KFxkKyl8KFthLXowLTldKykpXHMqJC9pLmV4ZWMo
-YSkKaWYocz09bnVsbClyZXR1cm4gbQppZigzPj1zLmxlbmd0aClyZXR1cm4gSC5PSChzLDMpCnI9c1sz
-XQppZihiPT1udWxsKXtpZihyIT1udWxsKXJldHVybiBwYXJzZUludChhLDEwKQppZihzWzJdIT1udWxs
-KXJldHVybiBwYXJzZUludChhLDE2KQpyZXR1cm4gbX1pZihiPDJ8fGI+MzYpdGhyb3cgSC5iKFAuVEUo
-YiwyLDM2LCJyYWRpeCIsbSkpCmlmKGI9PT0xMCYmciE9bnVsbClyZXR1cm4gcGFyc2VJbnQoYSwxMCkK
-aWYoYjwxMHx8cj09bnVsbCl7cT1iPD0xMD80NytiOjg2K2IKcD1zWzFdCmZvcihvPXAubGVuZ3RoLG49
-MDtuPG87KytuKWlmKChDLnhCLlcocCxuKXwzMik+cSlyZXR1cm4gbX1yZXR1cm4gcGFyc2VJbnQoYSxi
-KX0sCk06ZnVuY3Rpb24oYSl7cmV0dXJuIEguSDUoYSl9LApINTpmdW5jdGlvbihhKXt2YXIgcyxyLHEK
-aWYoYSBpbnN0YW5jZW9mIFAuTWgpcmV0dXJuIEguZG0oSC56KGEpLG51bGwpCmlmKEouaWEoYSk9PT1D
-Lk9rfHx0LmJKLmIoYSkpe3M9Qy5PNChhKQppZihILkJlKHMpKXJldHVybiBzCnI9YS5jb25zdHJ1Y3Rv
-cgppZih0eXBlb2Ygcj09ImZ1bmN0aW9uIil7cT1yLm5hbWUKaWYodHlwZW9mIHE9PSJzdHJpbmciJiZI
-LkJlKHEpKXJldHVybiBxfX1yZXR1cm4gSC5kbShILnooYSksbnVsbCl9LApCZTpmdW5jdGlvbihhKXt2
-YXIgcz1hIT09Ik9iamVjdCImJmEhPT0iIgpyZXR1cm4gc30sCk0wOmZ1bmN0aW9uKCl7aWYoISFzZWxm
-LmxvY2F0aW9uKXJldHVybiBzZWxmLmxvY2F0aW9uLmhyZWYKcmV0dXJuIG51bGx9LApWSzpmdW5jdGlv
-bihhKXt2YXIgcyxyLHEscCxvPWEubGVuZ3RoCmlmKG88PTUwMClyZXR1cm4gU3RyaW5nLmZyb21DaGFy
-Q29kZS5hcHBseShudWxsLGEpCmZvcihzPSIiLHI9MDtyPG87cj1xKXtxPXIrNTAwCnA9cTxvP3E6bwpz
-Kz1TdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KG51bGwsYS5zbGljZShyLHApKX1yZXR1cm4gc30sCkNx
-OmZ1bmN0aW9uKGEpe3ZhciBzLHIscSxwPUguVk0oW10sdC5hKQpmb3Iocz1hLmxlbmd0aCxyPTA7cjxh
-Lmxlbmd0aDthLmxlbmd0aD09PXN8fCgwLEgubGspKGEpLCsrcil7cT1hW3JdCmlmKCFILm9rKHEpKXRo
-cm93IEguYihILnRMKHEpKQppZihxPD02NTUzNSlDLk5tLmkocCxxKQplbHNlIGlmKHE8PTExMTQxMTEp
-e0MuTm0uaShwLDU1Mjk2KyhDLmpuLndHKHEtNjU1MzYsMTApJjEwMjMpKQpDLk5tLmkocCw1NjMyMCso
-cSYxMDIzKSl9ZWxzZSB0aHJvdyBILmIoSC50TChxKSl9cmV0dXJuIEguVksocCl9LAplVDpmdW5jdGlv
-bihhKXt2YXIgcyxyLHEKZm9yKHM9YS5sZW5ndGgscj0wO3I8czsrK3Ipe3E9YVtyXQppZighSC5vayhx
-KSl0aHJvdyBILmIoSC50TChxKSkKaWYocTwwKXRocm93IEguYihILnRMKHEpKQppZihxPjY1NTM1KXJl
-dHVybiBILkNxKGEpfXJldHVybiBILlZLKGEpfSwKZnc6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzLHIscSxw
-CmlmKGM8PTUwMCYmYj09PTAmJmM9PT1hLmxlbmd0aClyZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZS5h
-cHBseShudWxsLGEpCmZvcihzPWIscj0iIjtzPGM7cz1xKXtxPXMrNTAwCnA9cTxjP3E6YwpyKz1TdHJp
-bmcuZnJvbUNoYXJDb2RlLmFwcGx5KG51bGwsYS5zdWJhcnJheShzLHApKX1yZXR1cm4gcn0sCkx3OmZ1
-bmN0aW9uKGEpe3ZhciBzCmlmKDA8PWEpe2lmKGE8PTY1NTM1KXJldHVybiBTdHJpbmcuZnJvbUNoYXJD
-b2RlKGEpCmlmKGE8PTExMTQxMTEpe3M9YS02NTUzNgpyZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZSgo
-Qy5qbi53RyhzLDEwKXw1NTI5Nik+Pj4wLHMmMTAyM3w1NjMyMCl9fXRocm93IEguYihQLlRFKGEsMCwx
-MTE0MTExLG51bGwsbnVsbCkpfSwKbzI6ZnVuY3Rpb24oYSl7aWYoYS5kYXRlPT09dm9pZCAwKWEuZGF0
-ZT1uZXcgRGF0ZShhLmEpCnJldHVybiBhLmRhdGV9LAp0SjpmdW5jdGlvbihhKXt2YXIgcz1ILm8yKGEp
-LmdldEZ1bGxZZWFyKCkrMApyZXR1cm4gc30sCk5TOmZ1bmN0aW9uKGEpe3ZhciBzPUgubzIoYSkuZ2V0
-TW9udGgoKSsxCnJldHVybiBzfSwKakE6ZnVuY3Rpb24oYSl7dmFyIHM9SC5vMihhKS5nZXREYXRlKCkr
-MApyZXR1cm4gc30sCklYOmZ1bmN0aW9uKGEpe3ZhciBzPUgubzIoYSkuZ2V0SG91cnMoKSswCnJldHVy
-biBzfSwKY2g6ZnVuY3Rpb24oYSl7dmFyIHM9SC5vMihhKS5nZXRNaW51dGVzKCkrMApyZXR1cm4gc30s
-CkpkOmZ1bmN0aW9uKGEpe3ZhciBzPUgubzIoYSkuZ2V0U2Vjb25kcygpKzAKcmV0dXJuIHN9LApvMTpm
-dW5jdGlvbihhKXt2YXIgcz1ILm8yKGEpLmdldE1pbGxpc2Vjb25kcygpKzAKcmV0dXJuIHN9LAp6bzpm
-dW5jdGlvbihhLGIsYyl7dmFyIHMscixxPXt9CnEuYT0wCnM9W10Kcj1bXQpxLmE9Yi5sZW5ndGgKQy5O
-bS5GVihzLGIpCnEuYj0iIgppZihjIT1udWxsJiZjLmEhPT0wKWMuSygwLG5ldyBILkNqKHEscixzKSkK
-IiIrcS5hCnJldHVybiBKLkp5KGEsbmV3IEguTEkoQy5UZSwwLHMsciwwKSl9LApFazpmdW5jdGlvbihh
-LGIsYyl7dmFyIHMscixxLHAKaWYoYiBpbnN0YW5jZW9mIEFycmF5KXM9Yz09bnVsbHx8Yy5hPT09MApl
-bHNlIHM9ITEKaWYocyl7cj1iCnE9ci5sZW5ndGgKaWYocT09PTApe2lmKCEhYS4kMClyZXR1cm4gYS4k
-MCgpfWVsc2UgaWYocT09PTEpe2lmKCEhYS4kMSlyZXR1cm4gYS4kMShyWzBdKX1lbHNlIGlmKHE9PT0y
-KXtpZighIWEuJDIpcmV0dXJuIGEuJDIoclswXSxyWzFdKX1lbHNlIGlmKHE9PT0zKXtpZighIWEuJDMp
-cmV0dXJuIGEuJDMoclswXSxyWzFdLHJbMl0pfWVsc2UgaWYocT09PTQpe2lmKCEhYS4kNClyZXR1cm4g
-YS4kNChyWzBdLHJbMV0sclsyXSxyWzNdKX1lbHNlIGlmKHE9PT01KWlmKCEhYS4kNSlyZXR1cm4gYS4k
-NShyWzBdLHJbMV0sclsyXSxyWzNdLHJbNF0pCnA9YVsiIisiJCIrcV0KaWYocCE9bnVsbClyZXR1cm4g
-cC5hcHBseShhLHIpfXJldHVybiBILmUxKGEsYixjKX0sCmUxOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxy
-LHEscCxvLG4sbSxsLGssaixpPWIgaW5zdGFuY2VvZiBBcnJheT9iOlAuQ0goYiwhMCx0LnopLGg9aS5s
-ZW5ndGgsZz1hLiRSCmlmKGg8ZylyZXR1cm4gSC56byhhLGksYykKcz1hLiRECnI9cz09bnVsbApxPSFy
-P3MoKTpudWxsCnA9Si5pYShhKQpvPXAuJEMKaWYodHlwZW9mIG89PSJzdHJpbmciKW89cFtvXQppZihy
-KXtpZihjIT1udWxsJiZjLmEhPT0wKXJldHVybiBILnpvKGEsaSxjKQppZihoPT09ZylyZXR1cm4gby5h
-cHBseShhLGkpCnJldHVybiBILnpvKGEsaSxjKX1pZihxIGluc3RhbmNlb2YgQXJyYXkpe2lmKGMhPW51
-bGwmJmMuYSE9PTApcmV0dXJuIEguem8oYSxpLGMpCmlmKGg+ZytxLmxlbmd0aClyZXR1cm4gSC56byhh
-LGksbnVsbCkKQy5ObS5GVihpLHEuc2xpY2UoaC1nKSkKcmV0dXJuIG8uYXBwbHkoYSxpKX1lbHNle2lm
-KGg+ZylyZXR1cm4gSC56byhhLGksYykKbj1PYmplY3Qua2V5cyhxKQppZihjPT1udWxsKWZvcihyPW4u
-bGVuZ3RoLG09MDttPG4ubGVuZ3RoO24ubGVuZ3RoPT09cnx8KDAsSC5saykobiksKyttKXtsPXFbSC5o
-KG5bbV0pXQppZihDLk52PT09bClyZXR1cm4gSC56byhhLGksYykKQy5ObS5pKGksbCl9ZWxzZXtmb3Io
-cj1uLmxlbmd0aCxrPTAsbT0wO208bi5sZW5ndGg7bi5sZW5ndGg9PT1yfHwoMCxILmxrKShuKSwrK20p
-e2o9SC5oKG5bbV0pCmlmKGMueDQoaikpeysrawpDLk5tLmkoaSxjLnEoMCxqKSl9ZWxzZXtsPXFbal0K
-aWYoQy5Odj09PWwpcmV0dXJuIEguem8oYSxpLGMpCkMuTm0uaShpLGwpfX1pZihrIT09Yy5hKXJldHVy
-biBILnpvKGEsaSxjKX1yZXR1cm4gby5hcHBseShhLGkpfX0sCnBZOmZ1bmN0aW9uKGEpe3Rocm93IEgu
-YihILnRMKGEpKX0sCk9IOmZ1bmN0aW9uKGEsYil7aWYoYT09bnVsbClKLkhtKGEpCnRocm93IEguYihI
-LkhZKGEsYikpfSwKSFk6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHE9ImluZGV4IgppZighSC5vayhiKSly
-ZXR1cm4gbmV3IFAudSghMCxiLHEsbnVsbCkKcz1ILnVQKEouSG0oYSkpCmlmKCEoYjwwKSl7aWYodHlw
-ZW9mIHMhPT0ibnVtYmVyIilyZXR1cm4gSC5wWShzKQpyPWI+PXN9ZWxzZSByPSEwCmlmKHIpcmV0dXJu
-IFAuQ2YoYixhLHEsbnVsbCxzKQpyZXR1cm4gUC5PNyhiLHEpfSwKYXU6ZnVuY3Rpb24oYSxiLGMpe2lm
-KGE+YylyZXR1cm4gUC5URShhLDAsYywic3RhcnQiLG51bGwpCmlmKGIhPW51bGwpaWYoYjxhfHxiPmMp
-cmV0dXJuIFAuVEUoYixhLGMsImVuZCIsbnVsbCkKcmV0dXJuIG5ldyBQLnUoITAsYiwiZW5kIixudWxs
-KX0sCnRMOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgUC51KCEwLGEsbnVsbCxudWxsKX0sCmI6ZnVuY3Rp
-b24oYSl7dmFyIHMscgppZihhPT1udWxsKWE9bmV3IFAuRigpCnM9bmV3IEVycm9yKCkKcy5kYXJ0RXhj
-ZXB0aW9uPWEKcj1ILngKaWYoImRlZmluZVByb3BlcnR5IiBpbiBPYmplY3Qpe09iamVjdC5kZWZpbmVQ
-cm9wZXJ0eShzLCJtZXNzYWdlIix7Z2V0OnJ9KQpzLm5hbWU9IiJ9ZWxzZSBzLnRvU3RyaW5nPXIKcmV0
-dXJuIHN9LAp4OmZ1bmN0aW9uKCl7cmV0dXJuIEouaih0aGlzLmRhcnRFeGNlcHRpb24pfSwKdjpmdW5j
-dGlvbihhKXt0aHJvdyBILmIoYSl9LApsazpmdW5jdGlvbihhKXt0aHJvdyBILmIoUC5hNChhKSl9LApj
-TTpmdW5jdGlvbihhKXt2YXIgcyxyLHEscCxvLG4KYT1ILmVBKGEucmVwbGFjZShTdHJpbmcoe30pLCIk
-cmVjZWl2ZXIkIikpCnM9YS5tYXRjaCgvXFxcJFthLXpBLVpdK1xcXCQvZykKaWYocz09bnVsbClzPUgu
-Vk0oW10sdC5zKQpyPXMuaW5kZXhPZigiXFwkYXJndW1lbnRzXFwkIikKcT1zLmluZGV4T2YoIlxcJGFy
-Z3VtZW50c0V4cHJcXCQiKQpwPXMuaW5kZXhPZigiXFwkZXhwclxcJCIpCm89cy5pbmRleE9mKCJcXCRt
-ZXRob2RcXCQiKQpuPXMuaW5kZXhPZigiXFwkcmVjZWl2ZXJcXCQiKQpyZXR1cm4gbmV3IEguZjkoYS5y
-ZXBsYWNlKG5ldyBSZWdFeHAoIlxcXFxcXCRhcmd1bWVudHNcXFxcXFwkIiwiZyIpLCIoKD86eHxbXnhd
-KSopIikucmVwbGFjZShuZXcgUmVnRXhwKCJcXFxcXFwkYXJndW1lbnRzRXhwclxcXFxcXCQiLCJnIiks
-IigoPzp4fFteeF0pKikiKS5yZXBsYWNlKG5ldyBSZWdFeHAoIlxcXFxcXCRleHByXFxcXFxcJCIsImci
-KSwiKCg/Onh8W154XSkqKSIpLnJlcGxhY2UobmV3IFJlZ0V4cCgiXFxcXFxcJG1ldGhvZFxcXFxcXCQi
-LCJnIiksIigoPzp4fFteeF0pKikiKS5yZXBsYWNlKG5ldyBSZWdFeHAoIlxcXFxcXCRyZWNlaXZlclxc
-XFxcXCQiLCJnIiksIigoPzp4fFteeF0pKikiKSxyLHEscCxvLG4pfSwKUzc6ZnVuY3Rpb24oYSl7cmV0
-dXJuIGZ1bmN0aW9uKCRleHByJCl7dmFyICRhcmd1bWVudHNFeHByJD0iJGFyZ3VtZW50cyQiCnRyeXsk
-ZXhwciQuJG1ldGhvZCQoJGFyZ3VtZW50c0V4cHIkKX1jYXRjaChzKXtyZXR1cm4gcy5tZXNzYWdlfX0o
-YSl9LApNajpmdW5jdGlvbihhKXtyZXR1cm4gZnVuY3Rpb24oJGV4cHIkKXt0cnl7JGV4cHIkLiRtZXRo
-b2QkfWNhdGNoKHMpe3JldHVybiBzLm1lc3NhZ2V9fShhKX0sCklqOmZ1bmN0aW9uKGEsYil7cmV0dXJu
-IG5ldyBILlcwKGEsYj09bnVsbD9udWxsOmIubWV0aG9kKX0sClQzOmZ1bmN0aW9uKGEsYil7dmFyIHM9
-Yj09bnVsbCxyPXM/bnVsbDpiLm1ldGhvZApyZXR1cm4gbmV3IEguYXooYSxyLHM/bnVsbDpiLnJlY2Vp
-dmVyKX0sClJ1OmZ1bmN0aW9uKGEpe2lmKGE9PW51bGwpcmV0dXJuIG5ldyBILnRlKGEpCmlmKGEgaW5z
-dGFuY2VvZiBILmJxKXJldHVybiBILnRXKGEsYS5hKQppZih0eXBlb2YgYSE9PSJvYmplY3QiKXJldHVy
-biBhCmlmKCJkYXJ0RXhjZXB0aW9uIiBpbiBhKXJldHVybiBILnRXKGEsYS5kYXJ0RXhjZXB0aW9uKQpy
-ZXR1cm4gSC50bChhKX0sCnRXOmZ1bmN0aW9uKGEsYil7aWYodC5yLmIoYikpaWYoYi4kdGhyb3duSnNF
-cnJvcj09bnVsbCliLiR0aHJvd25Kc0Vycm9yPWEKcmV0dXJuIGJ9LAp0bDpmdW5jdGlvbihhKXt2YXIg
-cyxyLHEscCxvLG4sbSxsLGssaixpLGgsZyxmLGU9bnVsbAppZighKCJtZXNzYWdlIiBpbiBhKSlyZXR1
-cm4gYQpzPWEubWVzc2FnZQppZigibnVtYmVyIiBpbiBhJiZ0eXBlb2YgYS5udW1iZXI9PSJudW1iZXIi
-KXtyPWEubnVtYmVyCnE9ciY2NTUzNQppZigoQy5qbi53RyhyLDE2KSY4MTkxKT09PTEwKXN3aXRjaChx
-KXtjYXNlIDQzODpyZXR1cm4gSC50VyhhLEguVDMoSC5FaihzKSsiIChFcnJvciAiK3ErIikiLGUpKQpj
-YXNlIDQ0NTpjYXNlIDUwMDc6cmV0dXJuIEgudFcoYSxILklqKEguRWoocykrIiAoRXJyb3IgIitxKyIp
-IixlKSl9fWlmKGEgaW5zdGFuY2VvZiBUeXBlRXJyb3Ipe3A9JC5TbigpCm89JC5scSgpCm49JC5OOSgp
-Cm09JC5pSSgpCmw9JC5VTigpCms9JC5aaCgpCmo9JC5yTigpCiQuYzMoKQppPSQuSEsoKQpoPSQucjEo
-KQpnPXAucVMocykKaWYoZyE9bnVsbClyZXR1cm4gSC50VyhhLEguVDMoSC5oKHMpLGcpKQplbHNle2c9
-by5xUyhzKQppZihnIT1udWxsKXtnLm1ldGhvZD0iY2FsbCIKcmV0dXJuIEgudFcoYSxILlQzKEguaChz
-KSxnKSl9ZWxzZXtnPW4ucVMocykKaWYoZz09bnVsbCl7Zz1tLnFTKHMpCmlmKGc9PW51bGwpe2c9bC5x
-UyhzKQppZihnPT1udWxsKXtnPWsucVMocykKaWYoZz09bnVsbCl7Zz1qLnFTKHMpCmlmKGc9PW51bGwp
-e2c9bS5xUyhzKQppZihnPT1udWxsKXtnPWkucVMocykKaWYoZz09bnVsbCl7Zz1oLnFTKHMpCmY9ZyE9
-bnVsbH1lbHNlIGY9ITB9ZWxzZSBmPSEwfWVsc2UgZj0hMH1lbHNlIGY9ITB9ZWxzZSBmPSEwfWVsc2Ug
-Zj0hMH1lbHNlIGY9ITAKaWYoZilyZXR1cm4gSC50VyhhLEguSWooSC5oKHMpLGcpKX19cmV0dXJuIEgu
-dFcoYSxuZXcgSC52Vih0eXBlb2Ygcz09InN0cmluZyI/czoiIikpfWlmKGEgaW5zdGFuY2VvZiBSYW5n
-ZUVycm9yKXtpZih0eXBlb2Ygcz09InN0cmluZyImJnMuaW5kZXhPZigiY2FsbCBzdGFjayIpIT09LTEp
-cmV0dXJuIG5ldyBQLktZKCkKcz1mdW5jdGlvbihiKXt0cnl7cmV0dXJuIFN0cmluZyhiKX1jYXRjaChk
-KXt9cmV0dXJuIG51bGx9KGEpCnJldHVybiBILnRXKGEsbmV3IFAudSghMSxlLGUsdHlwZW9mIHM9PSJz
-dHJpbmciP3MucmVwbGFjZSgvXlJhbmdlRXJyb3I6XHMqLywiIik6cykpfWlmKHR5cGVvZiBJbnRlcm5h
-bEVycm9yPT0iZnVuY3Rpb24iJiZhIGluc3RhbmNlb2YgSW50ZXJuYWxFcnJvcilpZih0eXBlb2Ygcz09
-InN0cmluZyImJnM9PT0idG9vIG11Y2ggcmVjdXJzaW9uIilyZXR1cm4gbmV3IFAuS1koKQpyZXR1cm4g
-YX0sCnRzOmZ1bmN0aW9uKGEpe3ZhciBzCmlmKGEgaW5zdGFuY2VvZiBILmJxKXJldHVybiBhLmIKaWYo
-YT09bnVsbClyZXR1cm4gbmV3IEguWE8oYSkKcz1hLiRjYWNoZWRUcmFjZQppZihzIT1udWxsKXJldHVy
-biBzCnJldHVybiBhLiRjYWNoZWRUcmFjZT1uZXcgSC5YTyhhKX0sCkI3OmZ1bmN0aW9uKGEsYil7dmFy
-IHMscixxLHA9YS5sZW5ndGgKZm9yKHM9MDtzPHA7cz1xKXtyPXMrMQpxPXIrMQpiLlk1KDAsYVtzXSxh
-W3JdKX1yZXR1cm4gYn0sCmZ0OmZ1bmN0aW9uKGEsYixjLGQsZSxmKXt0LlkuYShhKQpzd2l0Y2goSC51
-UChiKSl7Y2FzZSAwOnJldHVybiBhLiQwKCkKY2FzZSAxOnJldHVybiBhLiQxKGMpCmNhc2UgMjpyZXR1
-cm4gYS4kMihjLGQpCmNhc2UgMzpyZXR1cm4gYS4kMyhjLGQsZSkKY2FzZSA0OnJldHVybiBhLiQ0KGMs
-ZCxlLGYpfXRocm93IEguYihuZXcgUC5DRCgiVW5zdXBwb3J0ZWQgbnVtYmVyIG9mIGFyZ3VtZW50cyBm
-b3Igd3JhcHBlZCBjbG9zdXJlIikpfSwKdFI6ZnVuY3Rpb24oYSxiKXt2YXIgcwppZihhPT1udWxsKXJl
-dHVybiBudWxsCnM9YS4kaWRlbnRpdHkKaWYoISFzKXJldHVybiBzCnM9ZnVuY3Rpb24oYyxkLGUpe3Jl
-dHVybiBmdW5jdGlvbihmLGcsaCxpKXtyZXR1cm4gZShjLGQsZixnLGgsaSl9fShhLGIsSC5mdCkKYS4k
-aWRlbnRpdHk9cwpyZXR1cm4gc30sCmlBOmZ1bmN0aW9uKGEsYixjLGQsZSxmLGcpe3ZhciBzLHIscSxw
-LG8sbixtLGw9YlswXSxrPWwuJGNhbGxOYW1lLGo9ZT9PYmplY3QuY3JlYXRlKG5ldyBILnp4KCkuY29u
-c3RydWN0b3IucHJvdG90eXBlKTpPYmplY3QuY3JlYXRlKG5ldyBILnJUKG51bGwsbnVsbCxudWxsLCIi
-KS5jb25zdHJ1Y3Rvci5wcm90b3R5cGUpCmouJGluaXRpYWxpemU9ai5jb25zdHJ1Y3RvcgppZihlKXM9
-ZnVuY3Rpb24gc3RhdGljX3RlYXJfb2ZmKCl7dGhpcy4kaW5pdGlhbGl6ZSgpfQplbHNle3I9JC55agpp
-Zih0eXBlb2YgciE9PSJudW1iZXIiKXJldHVybiByLmgoKQokLnlqPXIrMQpyPW5ldyBGdW5jdGlvbigi
-YSxiLGMsZCIrciwidGhpcy4kaW5pdGlhbGl6ZShhLGIsYyxkIityKyIpIikKcz1yfWouY29uc3RydWN0
-b3I9cwpzLnByb3RvdHlwZT1qCmlmKCFlKXtxPUguYngoYSxsLGYpCnEuJHJlZmxlY3Rpb25JbmZvPWR9
-ZWxzZXtqLiRzdGF0aWNfbmFtZT1nCnE9bH1qLiRTPUguaW0oZCxlLGYpCmpba109cQpmb3IocD1xLG89
-MTtvPGIubGVuZ3RoOysrbyl7bj1iW29dCm09bi4kY2FsbE5hbWUKaWYobSE9bnVsbCl7bj1lP246SC5i
-eChhLG4sZikKalttXT1ufWlmKG89PT1jKXtuLiRyZWZsZWN0aW9uSW5mbz1kCnA9bn19ai4kQz1wCmou
-JFI9bC4kUgpqLiREPWwuJEQKcmV0dXJuIHN9LAppbTpmdW5jdGlvbihhLGIsYyl7dmFyIHMKaWYodHlw
-ZW9mIGE9PSJudW1iZXIiKXJldHVybiBmdW5jdGlvbihkLGUpe3JldHVybiBmdW5jdGlvbigpe3JldHVy
-biBkKGUpfX0oSC5CcCxhKQppZih0eXBlb2YgYT09InN0cmluZyIpe2lmKGIpdGhyb3cgSC5iKCJDYW5u
-b3QgY29tcHV0ZSBzaWduYXR1cmUgZm9yIHN0YXRpYyB0ZWFyb2ZmLiIpCnM9Yz9ILlBXOkguVG4KcmV0
-dXJuIGZ1bmN0aW9uKGQsZSl7cmV0dXJuIGZ1bmN0aW9uKCl7cmV0dXJuIGUodGhpcyxkKX19KGEscyl9
-dGhyb3cgSC5iKCJFcnJvciBpbiBmdW5jdGlvblR5cGUgb2YgdGVhcm9mZiIpfSwKdnE6ZnVuY3Rpb24o
-YSxiLGMsZCl7dmFyIHM9SC5EVgpzd2l0Y2goYj8tMTphKXtjYXNlIDA6cmV0dXJuIGZ1bmN0aW9uKGUs
-Zil7cmV0dXJuIGZ1bmN0aW9uKCl7cmV0dXJuIGYodGhpcylbZV0oKX19KGMscykKY2FzZSAxOnJldHVy
-biBmdW5jdGlvbihlLGYpe3JldHVybiBmdW5jdGlvbihnKXtyZXR1cm4gZih0aGlzKVtlXShnKX19KGMs
-cykKY2FzZSAyOnJldHVybiBmdW5jdGlvbihlLGYpe3JldHVybiBmdW5jdGlvbihnLGgpe3JldHVybiBm
-KHRoaXMpW2VdKGcsaCl9fShjLHMpCmNhc2UgMzpyZXR1cm4gZnVuY3Rpb24oZSxmKXtyZXR1cm4gZnVu
-Y3Rpb24oZyxoLGkpe3JldHVybiBmKHRoaXMpW2VdKGcsaCxpKX19KGMscykKY2FzZSA0OnJldHVybiBm
-dW5jdGlvbihlLGYpe3JldHVybiBmdW5jdGlvbihnLGgsaSxqKXtyZXR1cm4gZih0aGlzKVtlXShnLGgs
-aSxqKX19KGMscykKY2FzZSA1OnJldHVybiBmdW5jdGlvbihlLGYpe3JldHVybiBmdW5jdGlvbihnLGgs
-aSxqLGspe3JldHVybiBmKHRoaXMpW2VdKGcsaCxpLGosayl9fShjLHMpCmRlZmF1bHQ6cmV0dXJuIGZ1
-bmN0aW9uKGUsZil7cmV0dXJuIGZ1bmN0aW9uKCl7cmV0dXJuIGUuYXBwbHkoZih0aGlzKSxhcmd1bWVu
-dHMpfX0oZCxzKX19LApieDpmdW5jdGlvbihhLGIsYyl7dmFyIHMscixxLHAsbyxuLG0KaWYoYylyZXR1
-cm4gSC5IZihhLGIpCnM9Yi4kc3R1Yk5hbWUKcj1iLmxlbmd0aApxPWFbc10KcD1iPT1udWxsP3E9PW51
-bGw6Yj09PXEKbz0hcHx8cj49MjcKaWYobylyZXR1cm4gSC52cShyLCFwLHMsYikKaWYocj09PTApe3A9
-JC55agppZih0eXBlb2YgcCE9PSJudW1iZXIiKXJldHVybiBwLmgoKQokLnlqPXArMQpuPSJzZWxmIitw
-CnJldHVybiBuZXcgRnVuY3Rpb24oInJldHVybiBmdW5jdGlvbigpe3ZhciAiK24rIiA9IHRoaXMuIitI
-LkVqKEgub04oKSkrIjtyZXR1cm4gIituKyIuIitILkVqKHMpKyIoKTt9IikoKX1tPSJhYmNkZWZnaGlq
-a2xtbm9wcXJzdHV2d3h5eiIuc3BsaXQoIiIpLnNwbGljZSgwLHIpLmpvaW4oIiwiKQpwPSQueWoKaWYo
-dHlwZW9mIHAhPT0ibnVtYmVyIilyZXR1cm4gcC5oKCkKJC55aj1wKzEKbSs9cApyZXR1cm4gbmV3IEZ1
-bmN0aW9uKCJyZXR1cm4gZnVuY3Rpb24oIittKyIpe3JldHVybiB0aGlzLiIrSC5FaihILm9OKCkpKyIu
-IitILkVqKHMpKyIoIittKyIpO30iKSgpfSwKWjQ6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHM9SC5EVixy
-PUgueVMKc3dpdGNoKGI/LTE6YSl7Y2FzZSAwOnRocm93IEguYihuZXcgSC5FcSgiSW50ZXJjZXB0ZWQg
-ZnVuY3Rpb24gd2l0aCBubyBhcmd1bWVudHMuIikpCmNhc2UgMTpyZXR1cm4gZnVuY3Rpb24oZSxmLGcp
-e3JldHVybiBmdW5jdGlvbigpe3JldHVybiBmKHRoaXMpW2VdKGcodGhpcykpfX0oYyxzLHIpCmNhc2Ug
-MjpyZXR1cm4gZnVuY3Rpb24oZSxmLGcpe3JldHVybiBmdW5jdGlvbihoKXtyZXR1cm4gZih0aGlzKVtl
-XShnKHRoaXMpLGgpfX0oYyxzLHIpCmNhc2UgMzpyZXR1cm4gZnVuY3Rpb24oZSxmLGcpe3JldHVybiBm
-dW5jdGlvbihoLGkpe3JldHVybiBmKHRoaXMpW2VdKGcodGhpcyksaCxpKX19KGMscyxyKQpjYXNlIDQ6
-cmV0dXJuIGZ1bmN0aW9uKGUsZixnKXtyZXR1cm4gZnVuY3Rpb24oaCxpLGope3JldHVybiBmKHRoaXMp
-W2VdKGcodGhpcyksaCxpLGopfX0oYyxzLHIpCmNhc2UgNTpyZXR1cm4gZnVuY3Rpb24oZSxmLGcpe3Jl
-dHVybiBmdW5jdGlvbihoLGksaixrKXtyZXR1cm4gZih0aGlzKVtlXShnKHRoaXMpLGgsaSxqLGspfX0o
-YyxzLHIpCmNhc2UgNjpyZXR1cm4gZnVuY3Rpb24oZSxmLGcpe3JldHVybiBmdW5jdGlvbihoLGksaixr
-LGwpe3JldHVybiBmKHRoaXMpW2VdKGcodGhpcyksaCxpLGosayxsKX19KGMscyxyKQpkZWZhdWx0OnJl
-dHVybiBmdW5jdGlvbihlLGYsZyxoKXtyZXR1cm4gZnVuY3Rpb24oKXtoPVtnKHRoaXMpXQpBcnJheS5w
-cm90b3R5cGUucHVzaC5hcHBseShoLGFyZ3VtZW50cykKcmV0dXJuIGUuYXBwbHkoZih0aGlzKSxoKX19
-KGQscyxyKX19LApIZjpmdW5jdGlvbihhLGIpe3ZhciBzLHIscSxwLG8sbixtPUgub04oKSxsPSQuUDQK
-aWYobD09bnVsbClsPSQuUDQ9SC5FMigicmVjZWl2ZXIiKQpzPWIuJHN0dWJOYW1lCnI9Yi5sZW5ndGgK
-cT1hW3NdCnA9Yj09bnVsbD9xPT1udWxsOmI9PT1xCm89IXB8fHI+PTI4CmlmKG8pcmV0dXJuIEguWjQo
-ciwhcCxzLGIpCmlmKHI9PT0xKXtwPSJyZXR1cm4gZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy4iK0guRWoo
-bSkrIi4iK0guRWoocykrIih0aGlzLiIrbCsiKTsiCm89JC55agppZih0eXBlb2YgbyE9PSJudW1iZXIi
-KXJldHVybiBvLmgoKQokLnlqPW8rMQpyZXR1cm4gbmV3IEZ1bmN0aW9uKHArbysifSIpKCl9bj0iYWJj
-ZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXoiLnNwbGl0KCIiKS5zcGxpY2UoMCxyLTEpLmpvaW4oIiwiKQpw
-PSJyZXR1cm4gZnVuY3Rpb24oIituKyIpe3JldHVybiB0aGlzLiIrSC5FaihtKSsiLiIrSC5FaihzKSsi
-KHRoaXMuIitsKyIsICIrbisiKTsiCm89JC55agppZih0eXBlb2YgbyE9PSJudW1iZXIiKXJldHVybiBv
-LmgoKQokLnlqPW8rMQpyZXR1cm4gbmV3IEZ1bmN0aW9uKHArbysifSIpKCl9LApLcTpmdW5jdGlvbihh
-LGIsYyxkLGUsZixnKXtyZXR1cm4gSC5pQShhLGIsYyxkLCEhZSwhIWYsZyl9LApUbjpmdW5jdGlvbihh
-LGIpe3JldHVybiBILmNFKHYudHlwZVVuaXZlcnNlLEgueihhLmEpLGIpfSwKUFc6ZnVuY3Rpb24oYSxi
-KXtyZXR1cm4gSC5jRSh2LnR5cGVVbml2ZXJzZSxILnooYS5jKSxiKX0sCkRWOmZ1bmN0aW9uKGEpe3Jl
-dHVybiBhLmF9LAp5UzpmdW5jdGlvbihhKXtyZXR1cm4gYS5jfSwKb046ZnVuY3Rpb24oKXt2YXIgcz0k
-Lm1KCnJldHVybiBzPT1udWxsPyQubUo9SC5FMigic2VsZiIpOnN9LApFMjpmdW5jdGlvbihhKXt2YXIg
-cyxyLHEscD1uZXcgSC5yVCgic2VsZiIsInRhcmdldCIsInJlY2VpdmVyIiwibmFtZSIpLG89Si5FcChP
-YmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhwKSx0LlcpCmZvcihzPW8ubGVuZ3RoLHI9MDtyPHM7Kyty
-KXtxPW9bcl0KaWYocFtxXT09PWEpcmV0dXJuIHF9dGhyb3cgSC5iKFAueFkoIkZpZWxkIG5hbWUgIith
-KyIgbm90IGZvdW5kLiIpKX0sCm9UOmZ1bmN0aW9uKGEpe2lmKGE9PW51bGwpSC5mTygiYm9vbGVhbiBl
-eHByZXNzaW9uIG11c3Qgbm90IGJlIG51bGwiKQpyZXR1cm4gYX0sCmZPOmZ1bmN0aW9uKGEpe3Rocm93
-IEguYihuZXcgSC5rWShhKSl9LAphZzpmdW5jdGlvbihhKXt0aHJvdyBILmIobmV3IFAuYyhhKSl9LApZ
-ZzpmdW5jdGlvbihhKXtyZXR1cm4gdi5nZXRJc29sYXRlVGFnKGEpfSwKQm86ZnVuY3Rpb24oYSl7cmV0
-dXJuIEgudihuZXcgSC5uKGEpKX0sCml3OmZ1bmN0aW9uKGEsYixjKXtPYmplY3QuZGVmaW5lUHJvcGVy
-dHkoYSxiLHt2YWx1ZTpjLGVudW1lcmFibGU6ZmFsc2Usd3JpdGFibGU6dHJ1ZSxjb25maWd1cmFibGU6
-dHJ1ZX0pfSwKdzM6ZnVuY3Rpb24oYSl7dmFyIHMscixxLHAsbyxuPUguaCgkLk5GLiQxKGEpKSxtPSQu
-bndbbl0KaWYobSE9bnVsbCl7T2JqZWN0LmRlZmluZVByb3BlcnR5KGEsdi5kaXNwYXRjaFByb3BlcnR5
-TmFtZSx7dmFsdWU6bSxlbnVtZXJhYmxlOmZhbHNlLHdyaXRhYmxlOnRydWUsY29uZmlndXJhYmxlOnRy
-dWV9KQpyZXR1cm4gbS5pfXM9JC52dltuXQppZihzIT1udWxsKXJldHVybiBzCnI9di5pbnRlcmNlcHRv
-cnNCeVRhZ1tuXQppZihyPT1udWxsKXtxPUguaygkLlRYLiQyKGEsbikpCmlmKHEhPW51bGwpe209JC5u
-d1txXQppZihtIT1udWxsKXtPYmplY3QuZGVmaW5lUHJvcGVydHkoYSx2LmRpc3BhdGNoUHJvcGVydHlO
-YW1lLHt2YWx1ZTptLGVudW1lcmFibGU6ZmFsc2Usd3JpdGFibGU6dHJ1ZSxjb25maWd1cmFibGU6dHJ1
-ZX0pCnJldHVybiBtLml9cz0kLnZ2W3FdCmlmKHMhPW51bGwpcmV0dXJuIHMKcj12LmludGVyY2VwdG9y
-c0J5VGFnW3FdCm49cX19aWYocj09bnVsbClyZXR1cm4gbnVsbApzPXIucHJvdG90eXBlCnA9blswXQpp
-ZihwPT09IiEiKXttPUguVmEocykKJC5ud1tuXT1tCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShhLHYuZGlz
-cGF0Y2hQcm9wZXJ0eU5hbWUse3ZhbHVlOm0sZW51bWVyYWJsZTpmYWxzZSx3cml0YWJsZTp0cnVlLGNv
-bmZpZ3VyYWJsZTp0cnVlfSkKcmV0dXJuIG0uaX1pZihwPT09In4iKXskLnZ2W25dPXMKcmV0dXJuIHN9
-aWYocD09PSItIil7bz1ILlZhKHMpCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShPYmplY3QuZ2V0UHJvdG90
-eXBlT2YoYSksdi5kaXNwYXRjaFByb3BlcnR5TmFtZSx7dmFsdWU6byxlbnVtZXJhYmxlOmZhbHNlLHdy
-aXRhYmxlOnRydWUsY29uZmlndXJhYmxlOnRydWV9KQpyZXR1cm4gby5pfWlmKHA9PT0iKyIpcmV0dXJu
-IEguTGMoYSxzKQppZihwPT09IioiKXRocm93IEguYihQLlNZKG4pKQppZih2LmxlYWZUYWdzW25dPT09
-dHJ1ZSl7bz1ILlZhKHMpCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShPYmplY3QuZ2V0UHJvdG90eXBlT2Yo
-YSksdi5kaXNwYXRjaFByb3BlcnR5TmFtZSx7dmFsdWU6byxlbnVtZXJhYmxlOmZhbHNlLHdyaXRhYmxl
-OnRydWUsY29uZmlndXJhYmxlOnRydWV9KQpyZXR1cm4gby5pfWVsc2UgcmV0dXJuIEguTGMoYSxzKX0s
-CkxjOmZ1bmN0aW9uKGEsYil7dmFyIHM9T2JqZWN0LmdldFByb3RvdHlwZU9mKGEpCk9iamVjdC5kZWZp
-bmVQcm9wZXJ0eShzLHYuZGlzcGF0Y2hQcm9wZXJ0eU5hbWUse3ZhbHVlOkouUXUoYixzLG51bGwsbnVs
-bCksZW51bWVyYWJsZTpmYWxzZSx3cml0YWJsZTp0cnVlLGNvbmZpZ3VyYWJsZTp0cnVlfSkKcmV0dXJu
-IGJ9LApWYTpmdW5jdGlvbihhKXtyZXR1cm4gSi5RdShhLCExLG51bGwsISFhLiRpWGopfSwKVkY6ZnVu
-Y3Rpb24oYSxiLGMpe3ZhciBzPWIucHJvdG90eXBlCmlmKHYubGVhZlRhZ3NbYV09PT10cnVlKXJldHVy
-biBILlZhKHMpCmVsc2UgcmV0dXJuIEouUXUocyxjLG51bGwsbnVsbCl9LApYRDpmdW5jdGlvbigpe2lm
-KCEwPT09JC5CdilyZXR1cm4KJC5Cdj0hMApILloxKCl9LApaMTpmdW5jdGlvbigpe3ZhciBzLHIscSxw
-LG8sbixtLGwKJC5udz1PYmplY3QuY3JlYXRlKG51bGwpCiQudnY9T2JqZWN0LmNyZWF0ZShudWxsKQpI
-LmtPKCkKcz12LmludGVyY2VwdG9yc0J5VGFnCnI9T2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMocykK
-aWYodHlwZW9mIHdpbmRvdyE9InVuZGVmaW5lZCIpe3dpbmRvdwpxPWZ1bmN0aW9uKCl7fQpmb3IocD0w
-O3A8ci5sZW5ndGg7KytwKXtvPXJbcF0Kbj0kLng3LiQxKG8pCmlmKG4hPW51bGwpe209SC5WRihvLHNb
-b10sbikKaWYobSE9bnVsbCl7T2JqZWN0LmRlZmluZVByb3BlcnR5KG4sdi5kaXNwYXRjaFByb3BlcnR5
-TmFtZSx7dmFsdWU6bSxlbnVtZXJhYmxlOmZhbHNlLHdyaXRhYmxlOnRydWUsY29uZmlndXJhYmxlOnRy
-dWV9KQpxLnByb3RvdHlwZT1ufX19fWZvcihwPTA7cDxyLmxlbmd0aDsrK3Ape289cltwXQppZigvXltB
-LVphLXpfXS8udGVzdChvKSl7bD1zW29dCnNbIiEiK29dPWwKc1sifiIrb109bApzWyItIitvXT1sCnNb
-IisiK29dPWwKc1siKiIrb109bH19fSwKa086ZnVuY3Rpb24oKXt2YXIgcyxyLHEscCxvLG4sbT1DLllx
-KCkKbT1ILnVkKEMuS1UsSC51ZChDLmZRLEgudWQoQy5pNyxILnVkKEMuaTcsSC51ZChDLnhpLEgudWQo
-Qy5kayxILnVkKEMud2IoQy5PNCksbSkpKSkpKSkKaWYodHlwZW9mIGRhcnROYXRpdmVEaXNwYXRjaEhv
-b2tzVHJhbnNmb3JtZXIhPSJ1bmRlZmluZWQiKXtzPWRhcnROYXRpdmVEaXNwYXRjaEhvb2tzVHJhbnNm
-b3JtZXIKaWYodHlwZW9mIHM9PSJmdW5jdGlvbiIpcz1bc10KaWYocy5jb25zdHJ1Y3Rvcj09QXJyYXkp
-Zm9yKHI9MDtyPHMubGVuZ3RoOysrcil7cT1zW3JdCmlmKHR5cGVvZiBxPT0iZnVuY3Rpb24iKW09cSht
-KXx8bX19cD1tLmdldFRhZwpvPW0uZ2V0VW5rbm93blRhZwpuPW0ucHJvdG90eXBlRm9yVGFnCiQuTkY9
-bmV3IEguZEMocCkKJC5UWD1uZXcgSC53TihvKQokLng3PW5ldyBILlZYKG4pfSwKdWQ6ZnVuY3Rpb24o
-YSxiKXtyZXR1cm4gYShiKXx8Yn0sCnY0OmZ1bmN0aW9uKGEsYixjLGQsZSxmKXt2YXIgcz1iPyJtIjoi
-IixyPWM/IiI6ImkiLHE9ZD8idSI6IiIscD1lPyJzIjoiIixvPWY/ImciOiIiLG49ZnVuY3Rpb24oZyxo
-KXt0cnl7cmV0dXJuIG5ldyBSZWdFeHAoZyxoKX1jYXRjaChtKXtyZXR1cm4gbX19KGEscytyK3ErcCtv
-KQppZihuIGluc3RhbmNlb2YgUmVnRXhwKXJldHVybiBuCnRocm93IEguYihQLnJyKCJJbGxlZ2FsIFJl
-Z0V4cCBwYXR0ZXJuICgiK1N0cmluZyhuKSsiKSIsYSxudWxsKSl9LApTUTpmdW5jdGlvbihhLGIsYyl7
-dmFyIHMKaWYodHlwZW9mIGI9PSJzdHJpbmciKXJldHVybiBhLmluZGV4T2YoYixjKT49MAplbHNlIGlm
-KGIgaW5zdGFuY2VvZiBILlZSKXtzPUMueEIueW4oYSxjKQpyZXR1cm4gYi5iLnRlc3Qocyl9ZWxzZXtz
-PUouRkwoYixDLnhCLnluKGEsYykpCnJldHVybiFzLmdsMChzKX19LApBNDpmdW5jdGlvbihhKXtpZihh
-LmluZGV4T2YoIiQiLDApPj0wKXJldHVybiBhLnJlcGxhY2UoL1wkL2csIiQkJCQiKQpyZXR1cm4gYX0s
-CmVBOmZ1bmN0aW9uKGEpe2lmKC9bW1xde30oKSorPy5cXF4kfF0vLnRlc3QoYSkpcmV0dXJuIGEucmVw
-bGFjZSgvW1tcXXt9KCkqKz8uXFxeJHxdL2csIlxcJCYiKQpyZXR1cm4gYX0sCnlzOmZ1bmN0aW9uKGEs
-YixjKXt2YXIgcz1ILm5NKGEsYixjKQpyZXR1cm4gc30sCm5NOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxy
-LHEscAppZihiPT09IiIpe2lmKGE9PT0iIilyZXR1cm4gYwpzPWEubGVuZ3RoCmZvcihyPWMscT0wO3E8
-czsrK3Epcj1yK2FbcV0rYwpyZXR1cm4gci5jaGFyQ29kZUF0KDApPT0wP3I6cn1wPWEuaW5kZXhPZihi
-LDApCmlmKHA8MClyZXR1cm4gYQppZihhLmxlbmd0aDw1MDB8fGMuaW5kZXhPZigiJCIsMCk+PTApcmV0
-dXJuIGEuc3BsaXQoYikuam9pbihjKQpyZXR1cm4gYS5yZXBsYWNlKG5ldyBSZWdFeHAoSC5lQShiKSwn
-ZycpLEguQTQoYykpfSwKUEQ6ZnVuY3Rpb24gUEQoYSxiKXt0aGlzLmE9YQp0aGlzLiR0aT1ifSwKV1U6
-ZnVuY3Rpb24gV1UoKXt9LApMUDpmdW5jdGlvbiBMUChhLGIsYyxkKXt2YXIgXz10aGlzCl8uYT1hCl8u
-Yj1iCl8uYz1jCl8uJHRpPWR9LApYUjpmdW5jdGlvbiBYUihhLGIpe3RoaXMuYT1hCnRoaXMuJHRpPWJ9
-LApMSTpmdW5jdGlvbiBMSShhLGIsYyxkLGUpe3ZhciBfPXRoaXMKXy5hPWEKXy5jPWIKXy5kPWMKXy5l
-PWQKXy5mPWV9LApDajpmdW5jdGlvbiBDaihhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9
-LApmOTpmdW5jdGlvbiBmOShhLGIsYyxkLGUsZil7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9Ywpf
-LmQ9ZApfLmU9ZQpfLmY9Zn0sClcwOmZ1bmN0aW9uIFcwKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LAph
-ejpmdW5jdGlvbiBheihhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LAp2VjpmdW5jdGlv
-biB2VihhKXt0aGlzLmE9YX0sCnRlOmZ1bmN0aW9uIHRlKGEpe3RoaXMuYT1hfSwKYnE6ZnVuY3Rpb24g
-YnEoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sClhPOmZ1bmN0aW9uIFhPKGEpe3RoaXMuYT1hCnRoaXMu
-Yj1udWxsfSwKVHA6ZnVuY3Rpb24gVHAoKXt9LApsYzpmdW5jdGlvbiBsYygpe30sCnp4OmZ1bmN0aW9u
-IHp4KCl7fSwKclQ6ZnVuY3Rpb24gclQoYSxiLGMsZCl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9
-YwpfLmQ9ZH0sCkVxOmZ1bmN0aW9uIEVxKGEpe3RoaXMuYT1hfSwKa1k6ZnVuY3Rpb24ga1koYSl7dGhp
-cy5hPWF9LAprcjpmdW5jdGlvbiBrcigpe30sCk41OmZ1bmN0aW9uIE41KGEpe3ZhciBfPXRoaXMKXy5h
-PTAKXy5mPV8uZT1fLmQ9Xy5jPV8uYj1udWxsCl8ucj0wCl8uJHRpPWF9LAp2aDpmdW5jdGlvbiB2aChh
-LGIpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5kPV8uYz1udWxsfSwKaTU6ZnVuY3Rpb24gaTUoYSxi
-KXt0aGlzLmE9YQp0aGlzLiR0aT1ifSwKTjY6ZnVuY3Rpb24gTjYoYSxiLGMpe3ZhciBfPXRoaXMKXy5h
-PWEKXy5iPWIKXy5kPV8uYz1udWxsCl8uJHRpPWN9LApkQzpmdW5jdGlvbiBkQyhhKXt0aGlzLmE9YX0s
-CndOOmZ1bmN0aW9uIHdOKGEpe3RoaXMuYT1hfSwKVlg6ZnVuY3Rpb24gVlgoYSl7dGhpcy5hPWF9LApW
-UjpmdW5jdGlvbiBWUihhLGIpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5kPV8uYz1udWxsfSwKRUs6
-ZnVuY3Rpb24gRUsoYSl7dGhpcy5iPWF9LApLVzpmdW5jdGlvbiBLVyhhLGIsYyl7dGhpcy5hPWEKdGhp
-cy5iPWIKdGhpcy5jPWN9LApQYjpmdW5jdGlvbiBQYihhLGIsYyl7dmFyIF89dGhpcwpfLmE9YQpfLmI9
-YgpfLmM9YwpfLmQ9bnVsbH0sCnRROmZ1bmN0aW9uIHRRKGEsYil7dGhpcy5hPWEKdGhpcy5jPWJ9LAp1
-bjpmdW5jdGlvbiB1bihhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LApTZDpmdW5jdGlv
-biBTZChhLGIsYyl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLmQ9bnVsbH0sClhGOmZ1bmN0
-aW9uKGEpe3JldHVybiBhfSwKb2Q6ZnVuY3Rpb24oYSxiLGMpe2lmKGE+Pj4wIT09YXx8YT49Yyl0aHJv
-dyBILmIoSC5IWShiLGEpKX0sCnJNOmZ1bmN0aW9uKGEsYixjKXt2YXIgcwppZighKGE+Pj4wIT09YSkp
-cz1iPj4+MCE9PWJ8fGE+Ynx8Yj5jCmVsc2Ugcz0hMAppZihzKXRocm93IEguYihILmF1KGEsYixjKSkK
-cmV0dXJuIGJ9LApFVDpmdW5jdGlvbiBFVCgpe30sCkxaOmZ1bmN0aW9uIExaKCl7fSwKRGc6ZnVuY3Rp
-b24gRGcoKXt9LApQZzpmdW5jdGlvbiBQZygpe30sCnhqOmZ1bmN0aW9uIHhqKCl7fSwKZEU6ZnVuY3Rp
-b24gZEUoKXt9LApaQTpmdW5jdGlvbiBaQSgpe30sCmRUOmZ1bmN0aW9uIGRUKCl7fSwKUHE6ZnVuY3Rp
-b24gUHEoKXt9LAplRTpmdW5jdGlvbiBlRSgpe30sClY2OmZ1bmN0aW9uIFY2KCl7fSwKUkc6ZnVuY3Rp
-b24gUkcoKXt9LApWUDpmdW5jdGlvbiBWUCgpe30sCldCOmZ1bmN0aW9uIFdCKCl7fSwKWkc6ZnVuY3Rp
-b24gWkcoKXt9LApjejpmdW5jdGlvbihhLGIpe3ZhciBzPWIuYwpyZXR1cm4gcz09bnVsbD9iLmM9SC5C
-KGEsYi56LCEwKTpzfSwKeFo6ZnVuY3Rpb24oYSxiKXt2YXIgcz1iLmMKcmV0dXJuIHM9PW51bGw/Yi5j
-PUguSihhLCJiOCIsW2Iuel0pOnN9LApRMTpmdW5jdGlvbihhKXt2YXIgcz1hLnkKaWYocz09PTZ8fHM9
-PT03fHxzPT09OClyZXR1cm4gSC5RMShhLnopCnJldHVybiBzPT09MTF8fHM9PT0xMn0sCm1EOmZ1bmN0
-aW9uKGEpe3JldHVybiBhLmN5fSwKTjA6ZnVuY3Rpb24oYSl7cmV0dXJuIEguRSh2LnR5cGVVbml2ZXJz
-ZSxhLCExKX0sClBMOmZ1bmN0aW9uKGEsYixhMCxhMSl7dmFyIHMscixxLHAsbyxuLG0sbCxrLGosaSxo
-LGcsZixlLGQsYz1iLnkKc3dpdGNoKGMpe2Nhc2UgNTpjYXNlIDE6Y2FzZSAyOmNhc2UgMzpjYXNlIDQ6
-cmV0dXJuIGIKY2FzZSA2OnM9Yi56CnI9SC5QTChhLHMsYTAsYTEpCmlmKHI9PT1zKXJldHVybiBiCnJl
-dHVybiBILkMoYSxyLCEwKQpjYXNlIDc6cz1iLnoKcj1ILlBMKGEscyxhMCxhMSkKaWYocj09PXMpcmV0
-dXJuIGIKcmV0dXJuIEguQihhLHIsITApCmNhc2UgODpzPWIuegpyPUguUEwoYSxzLGEwLGExKQppZihy
-PT09cylyZXR1cm4gYgpyZXR1cm4gSC5mKGEsciwhMCkKY2FzZSA5OnE9Yi5RCnA9SC5iWihhLHEsYTAs
-YTEpCmlmKHA9PT1xKXJldHVybiBiCnJldHVybiBILkooYSxiLnoscCkKY2FzZSAxMDpvPWIuegpuPUgu
-UEwoYSxvLGEwLGExKQptPWIuUQpsPUguYlooYSxtLGEwLGExKQppZihuPT09byYmbD09PW0pcmV0dXJu
-IGIKcmV0dXJuIEguYShhLG4sbCkKY2FzZSAxMTprPWIuegpqPUguUEwoYSxrLGEwLGExKQppPWIuUQpo
-PUgucVQoYSxpLGEwLGExKQppZihqPT09ayYmaD09PWkpcmV0dXJuIGIKcmV0dXJuIEguZChhLGosaCkK
-Y2FzZSAxMjpnPWIuUQphMSs9Zy5sZW5ndGgKZj1ILmJaKGEsZyxhMCxhMSkKbz1iLnoKbj1ILlBMKGEs
-byxhMCxhMSkKaWYoZj09PWcmJm49PT1vKXJldHVybiBiCnJldHVybiBILkQoYSxuLGYsITApCmNhc2Ug
-MTM6ZT1iLnoKaWYoZTxhMSlyZXR1cm4gYgpkPWEwW2UtYTFdCmlmKGQ9PW51bGwpcmV0dXJuIGIKcmV0
-dXJuIGQKZGVmYXVsdDp0aHJvdyBILmIoUC5oVigiQXR0ZW1wdGVkIHRvIHN1YnN0aXR1dGUgdW5leHBl
-Y3RlZCBSVEkga2luZCAiK2MpKX19LApiWjpmdW5jdGlvbihhLGIsYyxkKXt2YXIgcyxyLHEscCxvPWIu
-bGVuZ3RoLG49W10KZm9yKHM9ITEscj0wO3I8bzsrK3Ipe3E9YltyXQpwPUguUEwoYSxxLGMsZCkKaWYo
-cCE9PXEpcz0hMApuLnB1c2gocCl9cmV0dXJuIHM/bjpifSwKdk86ZnVuY3Rpb24oYSxiLGMsZCl7dmFy
-IHMscixxLHAsbyxuLG09Yi5sZW5ndGgsbD1bXQpmb3Iocz0hMSxyPTA7cjxtO3IrPTMpe3E9YltyXQpw
-PWJbcisxXQpvPWJbcisyXQpuPUguUEwoYSxvLGMsZCkKaWYobiE9PW8pcz0hMApsLnB1c2gocSkKbC5w
-dXNoKHApCmwucHVzaChuKX1yZXR1cm4gcz9sOmJ9LApxVDpmdW5jdGlvbihhLGIsYyxkKXt2YXIgcyxy
-PWIuYSxxPUguYlooYSxyLGMsZCkscD1iLmIsbz1ILmJaKGEscCxjLGQpLG49Yi5jLG09SC52TyhhLG4s
-YyxkKQppZihxPT09ciYmbz09PXAmJm09PT1uKXJldHVybiBiCnM9bmV3IEguRygpCnMuYT1xCnMuYj1v
-CnMuYz1tCnJldHVybiBzfSwKVk06ZnVuY3Rpb24oYSxiKXthW3YuYXJyYXlSdGldPWIKcmV0dXJuIGF9
-LApKUzpmdW5jdGlvbihhKXt2YXIgcz1hLiRTCmlmKHMhPW51bGwpe2lmKHR5cGVvZiBzPT0ibnVtYmVy
-IilyZXR1cm4gSC5CcChzKQpyZXR1cm4gYS4kUygpfXJldHVybiBudWxsfSwKVWU6ZnVuY3Rpb24oYSxi
-KXt2YXIgcwppZihILlExKGIpKWlmKGEgaW5zdGFuY2VvZiBILlRwKXtzPUguSlMoYSkKaWYocyE9bnVs
-bClyZXR1cm4gc31yZXR1cm4gSC56KGEpfSwKejpmdW5jdGlvbihhKXt2YXIgcwppZihhIGluc3RhbmNl
-b2YgUC5NaCl7cz1hLiR0aQpyZXR1cm4gcyE9bnVsbD9zOkguVlUoYSl9aWYoQXJyYXkuaXNBcnJheShh
-KSlyZXR1cm4gSC50NihhKQpyZXR1cm4gSC5WVShKLmlhKGEpKX0sCnQ2OmZ1bmN0aW9uKGEpe3ZhciBz
-PWFbdi5hcnJheVJ0aV0scj10LmIKaWYocz09bnVsbClyZXR1cm4gcgppZihzLmNvbnN0cnVjdG9yIT09
-ci5jb25zdHJ1Y3RvcilyZXR1cm4gcgpyZXR1cm4gc30sCkxoOmZ1bmN0aW9uKGEpe3ZhciBzPWEuJHRp
-CnJldHVybiBzIT1udWxsP3M6SC5WVShhKX0sClZVOmZ1bmN0aW9uKGEpe3ZhciBzPWEuY29uc3RydWN0
-b3Iscj1zLiRjY2FjaGUKaWYociE9bnVsbClyZXR1cm4gcgpyZXR1cm4gSC5yOShhLHMpfSwKcjk6ZnVu
-Y3Rpb24oYSxiKXt2YXIgcz1hIGluc3RhbmNlb2YgSC5UcD9hLl9fcHJvdG9fXy5fX3Byb3RvX18uY29u
-c3RydWN0b3I6YixyPUguYWkodi50eXBlVW5pdmVyc2Uscy5uYW1lKQpiLiRjY2FjaGU9cgpyZXR1cm4g
-cn0sCkJwOmZ1bmN0aW9uKGEpe3ZhciBzLHIscQpILnVQKGEpCnM9di50eXBlcwpyPXNbYV0KaWYodHlw
-ZW9mIHI9PSJzdHJpbmciKXtxPUguRSh2LnR5cGVVbml2ZXJzZSxyLCExKQpzW2FdPXEKcmV0dXJuIHF9
-cmV0dXJuIHJ9LApLeDpmdW5jdGlvbihhKXt2YXIgcyxyLHEscD1hLngKaWYocCE9bnVsbClyZXR1cm4g
-cApzPWEuY3kKcj1zLnJlcGxhY2UoL1wqL2csIiIpCmlmKHI9PT1zKXJldHVybiBhLng9bmV3IEgubFko
-YSkKcT1ILkUodi50eXBlVW5pdmVyc2UsciwhMCkKcD1xLngKcmV0dXJuIGEueD1wPT1udWxsP3EueD1u
-ZXcgSC5sWShxKTpwfSwKSko6ZnVuY3Rpb24oYSl7dmFyIHMscixxPXRoaXMscD10LksKaWYocT09PXAp
-cmV0dXJuIEguUkUocSxhLEgua2UpCmlmKCFILkE4KHEpKWlmKCEocT09PXQuXykpcD1xPT09cAplbHNl
-IHA9ITAKZWxzZSBwPSEwCmlmKHApcmV0dXJuIEguUkUocSxhLEguSXcpCnA9cS55CnM9cD09PTY/cS56
-OnEKaWYocz09PXQuUylyPUgub2sKZWxzZSBpZihzPT09dC5nUnx8cz09PXQuZGkpcj1ILktICmVsc2Ug
-aWYocz09PXQuTilyPUguTU0KZWxzZSByPXM9PT10Lnk/SC5sOm51bGwKaWYociE9bnVsbClyZXR1cm4g
-SC5SRShxLGEscikKaWYocy55PT09OSl7cD1zLnoKaWYocy5RLmV2ZXJ5KEguY2MpKXtxLnI9IiRpIitw
-CnJldHVybiBILlJFKHEsYSxILnQ0KX19ZWxzZSBpZihwPT09NylyZXR1cm4gSC5SRShxLGEsSC5BUSkK
-cmV0dXJuIEguUkUocSxhLEguWU8pfSwKUkU6ZnVuY3Rpb24oYSxiLGMpe2EuYj1jCnJldHVybiBhLmIo
-Yil9LApBdTpmdW5jdGlvbihhKXt2YXIgcyxyLHE9dGhpcwppZighSC5BOChxKSlpZighKHE9PT10Ll8p
-KXM9cT09PXQuSwplbHNlIHM9ITAKZWxzZSBzPSEwCmlmKHMpcj1ILmhuCmVsc2UgaWYocT09PXQuSyly
-PUguVGkKZWxzZSByPUgubDQKcS5hPXIKcmV0dXJuIHEuYShhKX0sClFqOmZ1bmN0aW9uKGEpe3ZhciBz
-LHI9YS55CmlmKCFILkE4KGEpKWlmKCEoYT09PXQuXykpaWYoIShhPT09dC5jRikpaWYociE9PTcpcz1y
-PT09OCYmSC5RaihhLnopfHxhPT09dC5QfHxhPT09dC5UCmVsc2Ugcz0hMAplbHNlIHM9ITAKZWxzZSBz
-PSEwCmVsc2Ugcz0hMApyZXR1cm4gc30sCllPOmZ1bmN0aW9uKGEpe3ZhciBzPXRoaXMKaWYoYT09bnVs
-bClyZXR1cm4gSC5RaihzKQpyZXR1cm4gSC5XZSh2LnR5cGVVbml2ZXJzZSxILlVlKGEscyksbnVsbCxz
-LG51bGwpfSwKQVE6ZnVuY3Rpb24oYSl7aWYoYT09bnVsbClyZXR1cm4hMApyZXR1cm4gdGhpcy56LmIo
-YSl9LAp0NDpmdW5jdGlvbihhKXt2YXIgcyxyPXRoaXMKaWYoYT09bnVsbClyZXR1cm4gSC5RaihyKQpz
-PXIucgppZihhIGluc3RhbmNlb2YgUC5NaClyZXR1cm4hIWFbc10KcmV0dXJuISFKLmlhKGEpW3NdfSwK
-T3o6ZnVuY3Rpb24oYSl7dmFyIHM9dGhpcwppZihhPT1udWxsKXJldHVybiBhCmVsc2UgaWYocy5iKGEp
-KXJldHVybiBhCkgubTQoYSxzKX0sCmw0OmZ1bmN0aW9uKGEpe3ZhciBzPXRoaXMKaWYoYT09bnVsbCly
-ZXR1cm4gYQplbHNlIGlmKHMuYihhKSlyZXR1cm4gYQpILm00KGEscyl9LAptNDpmdW5jdGlvbihhLGIp
-e3Rocm93IEguYihILlpjKEguV0soYSxILlVlKGEsYiksSC5kbShiLG51bGwpKSkpfSwKRGg6ZnVuY3Rp
-b24oYSxiLGMsZCl7dmFyIHM9bnVsbAppZihILldlKHYudHlwZVVuaXZlcnNlLGEscyxiLHMpKXJldHVy
-biBhCnRocm93IEguYihILlpjKCJUaGUgdHlwZSBhcmd1bWVudCAnIitILkVqKEguZG0oYSxzKSkrIicg
-aXMgbm90IGEgc3VidHlwZSBvZiB0aGUgdHlwZSB2YXJpYWJsZSBib3VuZCAnIitILkVqKEguZG0oYixz
-KSkrIicgb2YgdHlwZSB2YXJpYWJsZSAnIitILkVqKGMpKyInIGluICciK0guRWooZCkrIicuIikpfSwK
-V0s6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzPVAucChhKSxyPUguZG0oYj09bnVsbD9ILnooYSk6YixudWxs
-KQpyZXR1cm4gcysiOiB0eXBlICciK0guRWoocikrIicgaXMgbm90IGEgc3VidHlwZSBvZiB0eXBlICci
-K0guRWooYykrIicifSwKWmM6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBILmlNKCJUeXBlRXJyb3I6ICIr
-YSl9LApxOmZ1bmN0aW9uKGEsYil7cmV0dXJuIG5ldyBILmlNKCJUeXBlRXJyb3I6ICIrSC5XSyhhLG51
-bGwsYikpfSwKa2U6ZnVuY3Rpb24oYSl7cmV0dXJuIGEhPW51bGx9LApUaTpmdW5jdGlvbihhKXtyZXR1
-cm4gYX0sCkl3OmZ1bmN0aW9uKGEpe3JldHVybiEwfSwKaG46ZnVuY3Rpb24oYSl7cmV0dXJuIGF9LAps
-OmZ1bmN0aW9uKGEpe3JldHVybiEwPT09YXx8ITE9PT1hfSwKcDg6ZnVuY3Rpb24oYSl7aWYoITA9PT1h
-KXJldHVybiEwCmlmKCExPT09YSlyZXR1cm4hMQp0aHJvdyBILmIoSC5xKGEsImJvb2wiKSl9LAp5ODpm
-dW5jdGlvbihhKXtpZighMD09PWEpcmV0dXJuITAKaWYoITE9PT1hKXJldHVybiExCmlmKGE9PW51bGwp
-cmV0dXJuIGEKdGhyb3cgSC5iKEgucShhLCJib29sIikpfSwKZHA6ZnVuY3Rpb24oYSl7aWYoITA9PT1h
-KXJldHVybiEwCmlmKCExPT09YSlyZXR1cm4hMQppZihhPT1udWxsKXJldHVybiBhCnRocm93IEguYihI
-LnEoYSwiYm9vbD8iKSl9LApGRzpmdW5jdGlvbihhKXtpZih0eXBlb2YgYT09Im51bWJlciIpcmV0dXJu
-IGEKdGhyb3cgSC5iKEgucShhLCJkb3VibGUiKSl9LApHSDpmdW5jdGlvbihhKXtpZih0eXBlb2YgYT09
-Im51bWJlciIpcmV0dXJuIGEKaWYoYT09bnVsbClyZXR1cm4gYQp0aHJvdyBILmIoSC5xKGEsImRvdWJs
-ZSIpKX0sClFrOmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhPT0ibnVtYmVyIilyZXR1cm4gYQppZihhPT1u
-dWxsKXJldHVybiBhCnRocm93IEguYihILnEoYSwiZG91YmxlPyIpKX0sCm9rOmZ1bmN0aW9uKGEpe3Jl
-dHVybiB0eXBlb2YgYT09Im51bWJlciImJk1hdGguZmxvb3IoYSk9PT1hfSwKSVo6ZnVuY3Rpb24oYSl7
-aWYodHlwZW9mIGE9PSJudW1iZXIiJiZNYXRoLmZsb29yKGEpPT09YSlyZXR1cm4gYQp0aHJvdyBILmIo
-SC5xKGEsImludCIpKX0sCnVQOmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhPT0ibnVtYmVyIiYmTWF0aC5m
-bG9vcihhKT09PWEpcmV0dXJuIGEKaWYoYT09bnVsbClyZXR1cm4gYQp0aHJvdyBILmIoSC5xKGEsImlu
-dCIpKX0sClVjOmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhPT0ibnVtYmVyIiYmTWF0aC5mbG9vcihhKT09
-PWEpcmV0dXJuIGEKaWYoYT09bnVsbClyZXR1cm4gYQp0aHJvdyBILmIoSC5xKGEsImludD8iKSl9LApL
-SDpmdW5jdGlvbihhKXtyZXR1cm4gdHlwZW9mIGE9PSJudW1iZXIifSwKejU6ZnVuY3Rpb24oYSl7aWYo
-dHlwZW9mIGE9PSJudW1iZXIiKXJldHVybiBhCnRocm93IEguYihILnEoYSwibnVtIikpfSwKVzE6ZnVu
-Y3Rpb24oYSl7aWYodHlwZW9mIGE9PSJudW1iZXIiKXJldHVybiBhCmlmKGE9PW51bGwpcmV0dXJuIGEK
-dGhyb3cgSC5iKEgucShhLCJudW0iKSl9LApjVTpmdW5jdGlvbihhKXtpZih0eXBlb2YgYT09Im51bWJl
-ciIpcmV0dXJuIGEKaWYoYT09bnVsbClyZXR1cm4gYQp0aHJvdyBILmIoSC5xKGEsIm51bT8iKSl9LApN
-TTpmdW5jdGlvbihhKXtyZXR1cm4gdHlwZW9mIGE9PSJzdHJpbmcifSwKQnQ6ZnVuY3Rpb24oYSl7aWYo
-dHlwZW9mIGE9PSJzdHJpbmciKXJldHVybiBhCnRocm93IEguYihILnEoYSwiU3RyaW5nIikpfSwKaDpm
-dW5jdGlvbihhKXtpZih0eXBlb2YgYT09InN0cmluZyIpcmV0dXJuIGEKaWYoYT09bnVsbClyZXR1cm4g
-YQp0aHJvdyBILmIoSC5xKGEsIlN0cmluZyIpKX0sCms6ZnVuY3Rpb24oYSl7aWYodHlwZW9mIGE9PSJz
-dHJpbmciKXJldHVybiBhCmlmKGE9PW51bGwpcmV0dXJuIGEKdGhyb3cgSC5iKEgucShhLCJTdHJpbmc/
-IikpfSwKaW86ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEKZm9yKHM9IiIscj0iIixxPTA7cTxhLmxlbmd0
-aDsrK3Escj0iLCAiKXMrPUMueEIuaChyLEguZG0oYVtxXSxiKSkKcmV0dXJuIHN9LApiSTpmdW5jdGlv
-bihhNSxhNixhNyl7dmFyIHMscixxLHAsbyxuLG0sbCxrLGosaSxoLGcsZixlLGQsYyxiLGEsYTAsYTEs
-YTIsYTMsYTQ9IiwgIgppZihhNyE9bnVsbCl7cz1hNy5sZW5ndGgKaWYoYTY9PW51bGwpe2E2PUguVk0o
-W10sdC5zKQpyPW51bGx9ZWxzZSByPWE2Lmxlbmd0aApxPWE2Lmxlbmd0aApmb3IocD1zO3A+MDstLXAp
-Qy5ObS5pKGE2LCJUIisocStwKSkKZm9yKG89dC5XLG49dC5fLG09dC5LLGw9IjwiLGs9IiIscD0wO3A8
-czsrK3Asaz1hNCl7bCs9awpqPWE2Lmxlbmd0aAppPWotMS1wCmlmKGk8MClyZXR1cm4gSC5PSChhNixp
-KQpsPUMueEIuaChsLGE2W2ldKQpoPWE3W3BdCmc9aC55CmlmKCEoZz09PTJ8fGc9PT0zfHxnPT09NHx8
-Zz09PTV8fGg9PT1vKSlpZighKGg9PT1uKSlqPWg9PT1tCmVsc2Ugaj0hMAplbHNlIGo9ITAKaWYoIWop
-bCs9Qy54Qi5oKCIgZXh0ZW5kcyAiLEguZG0oaCxhNikpfWwrPSI+In1lbHNle2w9IiIKcj1udWxsfW89
-YTUuegpmPWE1LlEKZT1mLmEKZD1lLmxlbmd0aApjPWYuYgpiPWMubGVuZ3RoCmE9Zi5jCmEwPWEubGVu
-Z3RoCmExPUguZG0obyxhNikKZm9yKGEyPSIiLGEzPSIiLHA9MDtwPGQ7KytwLGEzPWE0KWEyKz1DLnhC
-LmgoYTMsSC5kbShlW3BdLGE2KSkKaWYoYj4wKXthMis9YTMrIlsiCmZvcihhMz0iIixwPTA7cDxiOysr
-cCxhMz1hNClhMis9Qy54Qi5oKGEzLEguZG0oY1twXSxhNikpCmEyKz0iXSJ9aWYoYTA+MCl7YTIrPWEz
-KyJ7Igpmb3IoYTM9IiIscD0wO3A8YTA7cCs9MyxhMz1hNCl7YTIrPWEzCmlmKGFbcCsxXSlhMis9InJl
-cXVpcmVkICIKYTIrPUouYmIoSC5kbShhW3ArMl0sYTYpLCIgIikrYVtwXX1hMis9In0ifWlmKHIhPW51
-bGwpe2E2LnRvU3RyaW5nCmE2Lmxlbmd0aD1yfXJldHVybiBsKyIoIithMisiKSA9PiAiK0guRWooYTEp
-fSwKZG06ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEscCxvLG4sbSxsPWEueQppZihsPT09NSlyZXR1cm4i
-ZXJhc2VkIgppZihsPT09MilyZXR1cm4iZHluYW1pYyIKaWYobD09PTMpcmV0dXJuInZvaWQiCmlmKGw9
-PT0xKXJldHVybiJOZXZlciIKaWYobD09PTQpcmV0dXJuImFueSIKaWYobD09PTYpe3M9SC5kbShhLnos
-YikKcmV0dXJuIHN9aWYobD09PTcpe3I9YS56CnM9SC5kbShyLGIpCnE9ci55CnJldHVybiBKLmJiKHE9
-PT0xMXx8cT09PTEyP0MueEIuaCgiKCIscykrIikiOnMsIj8iKX1pZihsPT09OClyZXR1cm4iRnV0dXJl
-T3I8IitILkVqKEguZG0oYS56LGIpKSsiPiIKaWYobD09PTkpe3A9SC5vMyhhLnopCm89YS5RCnJldHVy
-biBvLmxlbmd0aCE9PTA/cCsoIjwiK0guaW8obyxiKSsiPiIpOnB9aWYobD09PTExKXJldHVybiBILmJJ
-KGEsYixudWxsKQppZihsPT09MTIpcmV0dXJuIEguYkkoYS56LGIsYS5RKQppZihsPT09MTMpe2IudG9T
-dHJpbmcKbj1hLnoKbT1iLmxlbmd0aApuPW0tMS1uCmlmKG48MHx8bj49bSlyZXR1cm4gSC5PSChiLG4p
-CnJldHVybiBiW25dfXJldHVybiI/In0sCm8zOmZ1bmN0aW9uKGEpe3ZhciBzLHI9SC5KZyhhKQppZihy
-IT1udWxsKXJldHVybiByCnM9Im1pbmlmaWVkOiIrYQpyZXR1cm4gc30sClFvOmZ1bmN0aW9uKGEsYil7
-dmFyIHM9YS50UltiXQpmb3IoO3R5cGVvZiBzPT0ic3RyaW5nIjspcz1hLnRSW3NdCnJldHVybiBzfSwK
-YWk6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEscCxvLG49YS5lVCxtPW5bYl0KaWYobT09bnVsbClyZXR1
-cm4gSC5FKGEsYiwhMSkKZWxzZSBpZih0eXBlb2YgbT09Im51bWJlciIpe3M9bQpyPUgubShhLDUsIiMi
-KQpxPVtdCmZvcihwPTA7cDxzOysrcClxLnB1c2gocikKbz1ILkooYSxiLHEpCm5bYl09bwpyZXR1cm4g
-b31lbHNlIHJldHVybiBtfSwKeGI6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gSC5JeChhLnRSLGIpfSwKRkY6
-ZnVuY3Rpb24oYSxiKXtyZXR1cm4gSC5JeChhLmVULGIpfSwKRTpmdW5jdGlvbihhLGIsYyl7dmFyIHMs
-cj1hLmVDLHE9ci5nZXQoYikKaWYocSE9bnVsbClyZXR1cm4gcQpzPUguaShILm8oYSxudWxsLGIsYykp
-CnIuc2V0KGIscykKcmV0dXJuIHN9LApjRTpmdW5jdGlvbihhLGIsYyl7dmFyIHMscixxPWIuY2gKaWYo
-cT09bnVsbClxPWIuY2g9bmV3IE1hcCgpCnM9cS5nZXQoYykKaWYocyE9bnVsbClyZXR1cm4gcwpyPUgu
-aShILm8oYSxiLGMsITApKQpxLnNldChjLHIpCnJldHVybiByfSwKdjU6ZnVuY3Rpb24oYSxiLGMpe3Zh
-ciBzLHIscSxwPWIuY3gKaWYocD09bnVsbClwPWIuY3g9bmV3IE1hcCgpCnM9Yy5jeQpyPXAuZ2V0KHMp
-CmlmKHIhPW51bGwpcmV0dXJuIHIKcT1ILmEoYSxiLGMueT09PTEwP2MuUTpbY10pCnAuc2V0KHMscSkK
-cmV0dXJuIHF9LApCRDpmdW5jdGlvbihhLGIpe2IuYT1ILkF1CmIuYj1ILkpKCnJldHVybiBifSwKbTpm
-dW5jdGlvbihhLGIsYyl7dmFyIHMscixxPWEuZUMuZ2V0KGMpCmlmKHEhPW51bGwpcmV0dXJuIHEKcz1u
-ZXcgSC5KYyhudWxsLG51bGwpCnMueT1iCnMuY3k9YwpyPUguQkQoYSxzKQphLmVDLnNldChjLHIpCnJl
-dHVybiByfSwKQzpmdW5jdGlvbihhLGIsYyl7dmFyIHMscj1iLmN5KyIqIixxPWEuZUMuZ2V0KHIpCmlm
-KHEhPW51bGwpcmV0dXJuIHEKcz1ILlo3KGEsYixyLGMpCmEuZUMuc2V0KHIscykKcmV0dXJuIHN9LApa
-NzpmdW5jdGlvbihhLGIsYyxkKXt2YXIgcyxyLHEKaWYoZCl7cz1iLnkKaWYoIUguQTgoYikpcj1iPT09
-dC5QfHxiPT09dC5UfHxzPT09N3x8cz09PTYKZWxzZSByPSEwCmlmKHIpcmV0dXJuIGJ9cT1uZXcgSC5K
-YyhudWxsLG51bGwpCnEueT02CnEuej1iCnEuY3k9YwpyZXR1cm4gSC5CRChhLHEpfSwKQjpmdW5jdGlv
-bihhLGIsYyl7dmFyIHMscj1iLmN5KyI/IixxPWEuZUMuZ2V0KHIpCmlmKHEhPW51bGwpcmV0dXJuIHEK
-cz1ILmxsKGEsYixyLGMpCmEuZUMuc2V0KHIscykKcmV0dXJuIHN9LApsbDpmdW5jdGlvbihhLGIsYyxk
-KXt2YXIgcyxyLHEscAppZihkKXtzPWIueQppZighSC5BOChiKSlpZighKGI9PT10LlB8fGI9PT10LlQp
-KWlmKHMhPT03KXI9cz09PTgmJkgubFIoYi56KQplbHNlIHI9ITAKZWxzZSByPSEwCmVsc2Ugcj0hMApp
-ZihyKXJldHVybiBiCmVsc2UgaWYocz09PTF8fGI9PT10LmNGKXJldHVybiB0LlAKZWxzZSBpZihzPT09
-Nil7cT1iLnoKaWYocS55PT09OCYmSC5sUihxLnopKXJldHVybiBxCmVsc2UgcmV0dXJuIEguY3ooYSxi
-KX19cD1uZXcgSC5KYyhudWxsLG51bGwpCnAueT03CnAuej1iCnAuY3k9YwpyZXR1cm4gSC5CRChhLHAp
-fSwKZjpmdW5jdGlvbihhLGIsYyl7dmFyIHMscj1iLmN5KyIvIixxPWEuZUMuZ2V0KHIpCmlmKHEhPW51
-bGwpcmV0dXJuIHEKcz1ILmVWKGEsYixyLGMpCmEuZUMuc2V0KHIscykKcmV0dXJuIHN9LAplVjpmdW5j
-dGlvbihhLGIsYyxkKXt2YXIgcyxyLHEKaWYoZCl7cz1iLnkKaWYoIUguQTgoYikpaWYoIShiPT09dC5f
-KSlyPWI9PT10LksKZWxzZSByPSEwCmVsc2Ugcj0hMAppZihyfHxiPT09dC5LKXJldHVybiBiCmVsc2Ug
-aWYocz09PTEpcmV0dXJuIEguSihhLCJiOCIsW2JdKQplbHNlIGlmKGI9PT10LlB8fGI9PT10LlQpcmV0
-dXJuIHQuYkd9cT1uZXcgSC5KYyhudWxsLG51bGwpCnEueT04CnEuej1iCnEuY3k9YwpyZXR1cm4gSC5C
-RChhLHEpfSwKSDpmdW5jdGlvbihhLGIpe3ZhciBzLHIscT0iIitiKyJeIixwPWEuZUMuZ2V0KHEpCmlm
-KHAhPW51bGwpcmV0dXJuIHAKcz1uZXcgSC5KYyhudWxsLG51bGwpCnMueT0xMwpzLno9YgpzLmN5PXEK
-cj1ILkJEKGEscykKYS5lQy5zZXQocSxyKQpyZXR1cm4gcn0sClV4OmZ1bmN0aW9uKGEpe3ZhciBzLHIs
-cSxwPWEubGVuZ3RoCmZvcihzPSIiLHI9IiIscT0wO3E8cDsrK3Escj0iLCIpcys9cithW3FdLmN5CnJl
-dHVybiBzfSwKUzQ6ZnVuY3Rpb24oYSl7dmFyIHMscixxLHAsbyxuLG09YS5sZW5ndGgKZm9yKHM9IiIs
-cj0iIixxPTA7cTxtO3ErPTMscj0iLCIpe3A9YVtxXQpvPWFbcSsxXT8iISI6IjoiCm49YVtxKzJdLmN5
-CnMrPXIrcCtvK259cmV0dXJuIHN9LApKOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyLHEscD1iCmlmKGMu
-bGVuZ3RoIT09MClwKz0iPCIrSC5VeChjKSsiPiIKcz1hLmVDLmdldChwKQppZihzIT1udWxsKXJldHVy
-biBzCnI9bmV3IEguSmMobnVsbCxudWxsKQpyLnk9OQpyLno9YgpyLlE9YwppZihjLmxlbmd0aD4wKXIu
-Yz1jWzBdCnIuY3k9cApxPUguQkQoYSxyKQphLmVDLnNldChwLHEpCnJldHVybiBxfSwKYTpmdW5jdGlv
-bihhLGIsYyl7dmFyIHMscixxLHAsbyxuCmlmKGIueT09PTEwKXtzPWIuegpyPWIuUS5jb25jYXQoYyl9
-ZWxzZXtyPWMKcz1ifXE9cy5jeSsoIjs8IitILlV4KHIpKyI+IikKcD1hLmVDLmdldChxKQppZihwIT1u
-dWxsKXJldHVybiBwCm89bmV3IEguSmMobnVsbCxudWxsKQpvLnk9MTAKby56PXMKby5RPXIKby5jeT1x
-Cm49SC5CRChhLG8pCmEuZUMuc2V0KHEsbikKcmV0dXJuIG59LApkOmZ1bmN0aW9uKGEsYixjKXt2YXIg
-cyxyLHEscCxvLG49Yi5jeSxtPWMuYSxsPW0ubGVuZ3RoLGs9Yy5iLGo9ay5sZW5ndGgsaT1jLmMsaD1p
-Lmxlbmd0aCxnPSIoIitILlV4KG0pCmlmKGo+MCl7cz1sPjA/IiwiOiIiCnI9SC5VeChrKQpnKz1zKyJb
-IityKyJdIn1pZihoPjApe3M9bD4wPyIsIjoiIgpyPUguUzQoaSkKZys9cysieyIrcisifSJ9cT1uKyhn
-KyIpIikKcD1hLmVDLmdldChxKQppZihwIT1udWxsKXJldHVybiBwCm89bmV3IEguSmMobnVsbCxudWxs
-KQpvLnk9MTEKby56PWIKby5RPWMKby5jeT1xCnI9SC5CRChhLG8pCmEuZUMuc2V0KHEscikKcmV0dXJu
-IHJ9LApEOmZ1bmN0aW9uKGEsYixjLGQpe3ZhciBzLHI9Yi5jeSsoIjwiK0guVXgoYykrIj4iKSxxPWEu
-ZUMuZ2V0KHIpCmlmKHEhPW51bGwpcmV0dXJuIHEKcz1ILmh3KGEsYixjLHIsZCkKYS5lQy5zZXQocixz
-KQpyZXR1cm4gc30sCmh3OmZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIHMscixxLHAsbyxuLG0sbAppZihl
-KXtzPWMubGVuZ3RoCnI9bmV3IEFycmF5KHMpCmZvcihxPTAscD0wO3A8czsrK3Ape289Y1twXQppZihv
-Lnk9PT0xKXtyW3BdPW87KytxfX1pZihxPjApe249SC5QTChhLGIsciwwKQptPUguYlooYSxjLHIsMCkK
-cmV0dXJuIEguRChhLG4sbSxjIT09bSl9fWw9bmV3IEguSmMobnVsbCxudWxsKQpsLnk9MTIKbC56PWIK
-bC5RPWMKbC5jeT1kCnJldHVybiBILkJEKGEsbCl9LApvOmZ1bmN0aW9uKGEsYixjLGQpe3JldHVybnt1
-OmEsZTpiLHI6YyxzOltdLHA6MCxuOmR9fSwKaTpmdW5jdGlvbihhKXt2YXIgcyxyLHEscCxvLG4sbSxs
-LGssaixpLGgsZz1hLnIsZj1hLnMKZm9yKHM9Zy5sZW5ndGgscj0wO3I8czspe3E9Zy5jaGFyQ29kZUF0
-KHIpCmlmKHE+PTQ4JiZxPD01NylyPUguQShyKzEscSxnLGYpCmVsc2UgaWYoKCgocXwzMik+Pj4wKS05
-NyY2NTUzNSk8MjZ8fHE9PT05NXx8cT09PTM2KXI9SC50KGEscixnLGYsITEpCmVsc2UgaWYocT09PTQ2
-KXI9SC50KGEscixnLGYsITApCmVsc2V7KytyCnN3aXRjaChxKXtjYXNlIDQ0OmJyZWFrCmNhc2UgNTg6
-Zi5wdXNoKCExKQpicmVhawpjYXNlIDMzOmYucHVzaCghMCkKYnJlYWsKY2FzZSA1OTpmLnB1c2goSC5L
-KGEudSxhLmUsZi5wb3AoKSkpCmJyZWFrCmNhc2UgOTQ6Zi5wdXNoKEguSChhLnUsZi5wb3AoKSkpCmJy
-ZWFrCmNhc2UgMzU6Zi5wdXNoKEgubShhLnUsNSwiIyIpKQpicmVhawpjYXNlIDY0OmYucHVzaChILm0o
-YS51LDIsIkAiKSkKYnJlYWsKY2FzZSAxMjY6Zi5wdXNoKEgubShhLnUsMywifiIpKQpicmVhawpjYXNl
-IDYwOmYucHVzaChhLnApCmEucD1mLmxlbmd0aApicmVhawpjYXNlIDYyOnA9YS51Cm89Zi5zcGxpY2Uo
-YS5wKQpILnIoYS51LGEuZSxvKQphLnA9Zi5wb3AoKQpuPWYucG9wKCkKaWYodHlwZW9mIG49PSJzdHJp
-bmciKWYucHVzaChILkoocCxuLG8pKQplbHNle209SC5LKHAsYS5lLG4pCnN3aXRjaChtLnkpe2Nhc2Ug
-MTE6Zi5wdXNoKEguRChwLG0sbyxhLm4pKQpicmVhawpkZWZhdWx0OmYucHVzaChILmEocCxtLG8pKQpi
-cmVha319YnJlYWsKY2FzZSAzODpILkkoYSxmKQpicmVhawpjYXNlIDQyOmw9YS51CmYucHVzaChILkMo
-bCxILksobCxhLmUsZi5wb3AoKSksYS5uKSkKYnJlYWsKY2FzZSA2MzpsPWEudQpmLnB1c2goSC5CKGws
-SC5LKGwsYS5lLGYucG9wKCkpLGEubikpCmJyZWFrCmNhc2UgNDc6bD1hLnUKZi5wdXNoKEguZihsLEgu
-SyhsLGEuZSxmLnBvcCgpKSxhLm4pKQpicmVhawpjYXNlIDQwOmYucHVzaChhLnApCmEucD1mLmxlbmd0
-aApicmVhawpjYXNlIDQxOnA9YS51Cms9bmV3IEguRygpCmo9cC5zRUEKaT1wLnNFQQpuPWYucG9wKCkK
-aWYodHlwZW9mIG49PSJudW1iZXIiKXN3aXRjaChuKXtjYXNlLTE6aj1mLnBvcCgpCmJyZWFrCmNhc2Ut
-MjppPWYucG9wKCkKYnJlYWsKZGVmYXVsdDpmLnB1c2gobikKYnJlYWt9ZWxzZSBmLnB1c2gobikKbz1m
-LnNwbGljZShhLnApCkgucihhLnUsYS5lLG8pCmEucD1mLnBvcCgpCmsuYT1vCmsuYj1qCmsuYz1pCmYu
-cHVzaChILmQocCxILksocCxhLmUsZi5wb3AoKSksaykpCmJyZWFrCmNhc2UgOTE6Zi5wdXNoKGEucCkK
-YS5wPWYubGVuZ3RoCmJyZWFrCmNhc2UgOTM6bz1mLnNwbGljZShhLnApCkgucihhLnUsYS5lLG8pCmEu
-cD1mLnBvcCgpCmYucHVzaChvKQpmLnB1c2goLTEpCmJyZWFrCmNhc2UgMTIzOmYucHVzaChhLnApCmEu
-cD1mLmxlbmd0aApicmVhawpjYXNlIDEyNTpvPWYuc3BsaWNlKGEucCkKSC55KGEudSxhLmUsbykKYS5w
-PWYucG9wKCkKZi5wdXNoKG8pCmYucHVzaCgtMikKYnJlYWsKZGVmYXVsdDp0aHJvdyJCYWQgY2hhcmFj
-dGVyICIrcX19fWg9Zi5wb3AoKQpyZXR1cm4gSC5LKGEudSxhLmUsaCl9LApBOmZ1bmN0aW9uKGEsYixj
-LGQpe3ZhciBzLHIscT1iLTQ4CmZvcihzPWMubGVuZ3RoO2E8czsrK2Epe3I9Yy5jaGFyQ29kZUF0KGEp
-CmlmKCEocj49NDgmJnI8PTU3KSlicmVhawpxPXEqMTArKHItNDgpfWQucHVzaChxKQpyZXR1cm4gYX0s
-CnQ6ZnVuY3Rpb24oYSxiLGMsZCxlKXt2YXIgcyxyLHEscCxvLG4sbT1iKzEKZm9yKHM9Yy5sZW5ndGg7
-bTxzOysrbSl7cj1jLmNoYXJDb2RlQXQobSkKaWYocj09PTQ2KXtpZihlKWJyZWFrCmU9ITB9ZWxzZXtp
-ZighKCgoKHJ8MzIpPj4+MCktOTcmNjU1MzUpPDI2fHxyPT09OTV8fHI9PT0zNikpcT1yPj00OCYmcjw9
-NTcKZWxzZSBxPSEwCmlmKCFxKWJyZWFrfX1wPWMuc3Vic3RyaW5nKGIsbSkKaWYoZSl7cz1hLnUKbz1h
-LmUKaWYoby55PT09MTApbz1vLnoKbj1ILlFvKHMsby56KVtwXQppZihuPT1udWxsKUgudignTm8gIicr
-cCsnIiBpbiAiJytILm1EKG8pKyciJykKZC5wdXNoKEguY0UocyxvLG4pKX1lbHNlIGQucHVzaChwKQpy
-ZXR1cm4gbX0sCkk6ZnVuY3Rpb24oYSxiKXt2YXIgcz1iLnBvcCgpCmlmKDA9PT1zKXtiLnB1c2goSC5t
-KGEudSwxLCIwJiIpKQpyZXR1cm59aWYoMT09PXMpe2IucHVzaChILm0oYS51LDQsIjEmIikpCnJldHVy
-bn10aHJvdyBILmIoUC5oVigiVW5leHBlY3RlZCBleHRlbmRlZCBvcGVyYXRpb24gIitILkVqKHMpKSl9
-LApLOmZ1bmN0aW9uKGEsYixjKXtpZih0eXBlb2YgYz09InN0cmluZyIpcmV0dXJuIEguSihhLGMsYS5z
-RUEpCmVsc2UgaWYodHlwZW9mIGM9PSJudW1iZXIiKXJldHVybiBILlRWKGEsYixjKQplbHNlIHJldHVy
-biBjfSwKcjpmdW5jdGlvbihhLGIsYyl7dmFyIHMscj1jLmxlbmd0aApmb3Iocz0wO3M8cjsrK3MpY1tz
-XT1ILksoYSxiLGNbc10pfSwKeTpmdW5jdGlvbihhLGIsYyl7dmFyIHMscj1jLmxlbmd0aApmb3Iocz0y
-O3M8cjtzKz0zKWNbc109SC5LKGEsYixjW3NdKX0sClRWOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyLHE9
-Yi55CmlmKHE9PT0xMCl7aWYoYz09PTApcmV0dXJuIGIuegpzPWIuUQpyPXMubGVuZ3RoCmlmKGM8PXIp
-cmV0dXJuIHNbYy0xXQpjLT1yCmI9Yi56CnE9Yi55fWVsc2UgaWYoYz09PTApcmV0dXJuIGIKaWYocSE9
-PTkpdGhyb3cgSC5iKFAuaFYoIkluZGV4ZWQgYmFzZSBtdXN0IGJlIGFuIGludGVyZmFjZSB0eXBlIikp
-CnM9Yi5RCmlmKGM8PXMubGVuZ3RoKXJldHVybiBzW2MtMV0KdGhyb3cgSC5iKFAuaFYoIkJhZCBpbmRl
-eCAiK2MrIiBmb3IgIitiLncoMCkpKX0sCldlOmZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIHMscixxLHAs
-byxuLG0sbCxrLGoKaWYoYj09PWQpcmV0dXJuITAKaWYoIUguQTgoZCkpaWYoIShkPT09dC5fKSlzPWQ9
-PT10LksKZWxzZSBzPSEwCmVsc2Ugcz0hMAppZihzKXJldHVybiEwCnI9Yi55CmlmKHI9PT00KXJldHVy
-biEwCmlmKEguQTgoYikpcmV0dXJuITEKaWYoYi55IT09MSlzPWI9PT10LlB8fGI9PT10LlQKZWxzZSBz
-PSEwCmlmKHMpcmV0dXJuITAKcT1yPT09MTMKaWYocSlpZihILldlKGEsY1tiLnpdLGMsZCxlKSlyZXR1
-cm4hMApwPWQueQppZihyPT09NilyZXR1cm4gSC5XZShhLGIueixjLGQsZSkKaWYocD09PTYpe3M9ZC56
-CnJldHVybiBILldlKGEsYixjLHMsZSl9aWYocj09PTgpe2lmKCFILldlKGEsYi56LGMsZCxlKSlyZXR1
-cm4hMQpyZXR1cm4gSC5XZShhLEgueFooYSxiKSxjLGQsZSl9aWYocj09PTcpe3M9SC5XZShhLGIueixj
-LGQsZSkKcmV0dXJuIHN9aWYocD09PTgpe2lmKEguV2UoYSxiLGMsZC56LGUpKXJldHVybiEwCnJldHVy
-biBILldlKGEsYixjLEgueFooYSxkKSxlKX1pZihwPT09Nyl7cz1ILldlKGEsYixjLGQueixlKQpyZXR1
-cm4gc31pZihxKXJldHVybiExCnM9ciE9PTExCmlmKCghc3x8cj09PTEyKSYmZD09PXQuWSlyZXR1cm4h
-MAppZihwPT09MTIpe2lmKGI9PT10LngpcmV0dXJuITAKaWYociE9PTEyKXJldHVybiExCm89Yi5RCm49
-ZC5RCm09by5sZW5ndGgKaWYobSE9PW4ubGVuZ3RoKXJldHVybiExCmM9Yz09bnVsbD9vOm8uY29uY2F0
-KGMpCmU9ZT09bnVsbD9uOm4uY29uY2F0KGUpCmZvcihsPTA7bDxtOysrbCl7az1vW2xdCmo9bltsXQpp
-ZighSC5XZShhLGssYyxqLGUpfHwhSC5XZShhLGosZSxrLGMpKXJldHVybiExfXJldHVybiBILmJPKGEs
-Yi56LGMsZC56LGUpfWlmKHA9PT0xMSl7aWYoYj09PXQueClyZXR1cm4hMAppZihzKXJldHVybiExCnJl
-dHVybiBILmJPKGEsYixjLGQsZSl9aWYocj09PTkpe2lmKHAhPT05KXJldHVybiExCnJldHVybiBILnBH
-KGEsYixjLGQsZSl9cmV0dXJuITF9LApiTzpmdW5jdGlvbihhMixhMyxhNCxhNSxhNil7dmFyIHMscixx
-LHAsbyxuLG0sbCxrLGosaSxoLGcsZixlLGQsYyxiLGEsYTAsYTEKaWYoIUguV2UoYTIsYTMueixhNCxh
-NS56LGE2KSlyZXR1cm4hMQpzPWEzLlEKcj1hNS5RCnE9cy5hCnA9ci5hCm89cS5sZW5ndGgKbj1wLmxl
-bmd0aAppZihvPm4pcmV0dXJuITEKbT1uLW8KbD1zLmIKaz1yLmIKaj1sLmxlbmd0aAppPWsubGVuZ3Ro
-CmlmKG8rajxuK2kpcmV0dXJuITEKZm9yKGg9MDtoPG87KytoKXtnPXFbaF0KaWYoIUguV2UoYTIscFto
-XSxhNixnLGE0KSlyZXR1cm4hMX1mb3IoaD0wO2g8bTsrK2gpe2c9bFtoXQppZighSC5XZShhMixwW28r
-aF0sYTYsZyxhNCkpcmV0dXJuITF9Zm9yKGg9MDtoPGk7KytoKXtnPWxbbStoXQppZighSC5XZShhMixr
-W2hdLGE2LGcsYTQpKXJldHVybiExfWY9cy5jCmU9ci5jCmQ9Zi5sZW5ndGgKYz1lLmxlbmd0aApmb3Io
-Yj0wLGE9MDthPGM7YSs9Myl7YTA9ZVthXQpmb3IoOyEwOyl7aWYoYj49ZClyZXR1cm4hMQphMT1mW2Jd
-CmIrPTMKaWYoYTA8YTEpcmV0dXJuITEKaWYoYTE8YTApY29udGludWUKZz1mW2ItMV0KaWYoIUguV2Uo
-YTIsZVthKzJdLGE2LGcsYTQpKXJldHVybiExCmJyZWFrfX1yZXR1cm4hMH0sCnBHOmZ1bmN0aW9uKGEs
-YixjLGQsZSl7dmFyIHMscixxLHAsbyxuLG0sbCxrPWIueixqPWQuegppZihrPT09ail7cz1iLlEKcj1k
-LlEKcT1zLmxlbmd0aApmb3IocD0wO3A8cTsrK3Ape289c1twXQpuPXJbcF0KaWYoIUguV2UoYSxvLGMs
-bixlKSlyZXR1cm4hMX1yZXR1cm4hMH1pZihkPT09dC5LKXJldHVybiEwCm09SC5RbyhhLGspCmlmKG09
-PW51bGwpcmV0dXJuITEKbD1tW2pdCmlmKGw9PW51bGwpcmV0dXJuITEKcT1sLmxlbmd0aApyPWQuUQpm
-b3IocD0wO3A8cTsrK3ApaWYoIUguV2UoYSxILmNFKGEsYixsW3BdKSxjLHJbcF0sZSkpcmV0dXJuITEK
-cmV0dXJuITB9LApsUjpmdW5jdGlvbihhKXt2YXIgcyxyPWEueQppZighKGE9PT10LlB8fGE9PT10LlQp
-KWlmKCFILkE4KGEpKWlmKHIhPT03KWlmKCEocj09PTYmJkgubFIoYS56KSkpcz1yPT09OCYmSC5sUihh
-LnopCmVsc2Ugcz0hMAplbHNlIHM9ITAKZWxzZSBzPSEwCmVsc2Ugcz0hMApyZXR1cm4gc30sCmNjOmZ1
-bmN0aW9uKGEpe3ZhciBzCmlmKCFILkE4KGEpKWlmKCEoYT09PXQuXykpcz1hPT09dC5LCmVsc2Ugcz0h
-MAplbHNlIHM9ITAKcmV0dXJuIHN9LApBODpmdW5jdGlvbihhKXt2YXIgcz1hLnkKcmV0dXJuIHM9PT0y
-fHxzPT09M3x8cz09PTR8fHM9PT01fHxhPT09dC5XfSwKSXg6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHE9
-T2JqZWN0LmtleXMoYikscD1xLmxlbmd0aApmb3Iocz0wO3M8cDsrK3Mpe3I9cVtzXQphW3JdPWJbcl19
-fSwKSmM6ZnVuY3Rpb24gSmMoYSxiKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8ueD1fLnI9Xy5jPW51
-bGwKXy55PTAKXy5jeT1fLmN4PV8uY2g9Xy5RPV8uej1udWxsfSwKRzpmdW5jdGlvbiBHKCl7dGhpcy5j
-PXRoaXMuYj10aGlzLmE9bnVsbH0sCmxZOmZ1bmN0aW9uIGxZKGEpe3RoaXMuYT1hfSwKa1M6ZnVuY3Rp
-b24ga1MoKXt9LAppTTpmdW5jdGlvbiBpTShhKXt0aGlzLmE9YX0sClI5OmZ1bmN0aW9uKGEpe3JldHVy
-biB0LncuYihhKXx8dC5CLmIoYSl8fHQuZHouYihhKXx8dC5JLmIoYSl8fHQuQS5iKGEpfHx0Lmc0LmIo
-YSl8fHQuZzIuYihhKX0sCkpnOmZ1bmN0aW9uKGEpe3JldHVybiB2Lm1hbmdsZWRHbG9iYWxOYW1lc1th
-XX19LEo9ewpRdTpmdW5jdGlvbihhLGIsYyxkKXtyZXR1cm57aTphLHA6YixlOmMseDpkfX0sCmtzOmZ1
-bmN0aW9uKGEpe3ZhciBzLHIscSxwLG89YVt2LmRpc3BhdGNoUHJvcGVydHlOYW1lXQppZihvPT1udWxs
-KWlmKCQuQnY9PW51bGwpe0guWEQoKQpvPWFbdi5kaXNwYXRjaFByb3BlcnR5TmFtZV19aWYobyE9bnVs
-bCl7cz1vLnAKaWYoITE9PT1zKXJldHVybiBvLmkKaWYoITA9PT1zKXJldHVybiBhCnI9T2JqZWN0Lmdl
-dFByb3RvdHlwZU9mKGEpCmlmKHM9PT1yKXJldHVybiBvLmkKaWYoby5lPT09cil0aHJvdyBILmIoUC5T
-WSgiUmV0dXJuIGludGVyY2VwdG9yIGZvciAiK0guRWoocyhhLG8pKSkpfXE9YS5jb25zdHJ1Y3Rvcgpw
-PXE9PW51bGw/bnVsbDpxW0ouUlAoKV0KaWYocCE9bnVsbClyZXR1cm4gcApwPUgudzMoYSkKaWYocCE9
-bnVsbClyZXR1cm4gcAppZih0eXBlb2YgYT09ImZ1bmN0aW9uIilyZXR1cm4gQy5ERwpzPU9iamVjdC5n
-ZXRQcm90b3R5cGVPZihhKQppZihzPT1udWxsKXJldHVybiBDLlpRCmlmKHM9PT1PYmplY3QucHJvdG90
-eXBlKXJldHVybiBDLlpRCmlmKHR5cGVvZiBxPT0iZnVuY3Rpb24iKXtPYmplY3QuZGVmaW5lUHJvcGVy
-dHkocSxKLlJQKCkse3ZhbHVlOkMudkIsZW51bWVyYWJsZTpmYWxzZSx3cml0YWJsZTp0cnVlLGNvbmZp
-Z3VyYWJsZTp0cnVlfSkKcmV0dXJuIEMudkJ9cmV0dXJuIEMudkJ9LApSUDpmdW5jdGlvbigpe3ZhciBz
-PSQuem0KcmV0dXJuIHM9PW51bGw/JC56bT12LmdldElzb2xhdGVUYWcoIl8kZGFydF9qcyIpOnN9LApR
-aTpmdW5jdGlvbihhLGIpe2lmKGE8MHx8YT40Mjk0OTY3Mjk1KXRocm93IEguYihQLlRFKGEsMCw0Mjk0
-OTY3Mjk1LCJsZW5ndGgiLG51bGwpKQpyZXR1cm4gSi5weShuZXcgQXJyYXkoYSksYil9LApLaDpmdW5j
-dGlvbihhLGIpe2lmKGE8MCl0aHJvdyBILmIoUC54WSgiTGVuZ3RoIG11c3QgYmUgYSBub24tbmVnYXRp
-dmUgaW50ZWdlcjogIithKSkKcmV0dXJuIEguVk0obmV3IEFycmF5KGEpLGIuQygiamQ8MD4iKSl9LApw
-eTpmdW5jdGlvbihhLGIpe3JldHVybiBKLkVwKEguVk0oYSxiLkMoImpkPDA+IikpLGIpfSwKRXA6ZnVu
-Y3Rpb24oYSxiKXthLmZpeGVkJGxlbmd0aD1BcnJheQpyZXR1cm4gYX0sCnpDOmZ1bmN0aW9uKGEpe2Eu
-Zml4ZWQkbGVuZ3RoPUFycmF5CmEuaW1tdXRhYmxlJGxpc3Q9QXJyYXkKcmV0dXJuIGF9LApHYTpmdW5j
-dGlvbihhKXtpZihhPDI1Nilzd2l0Y2goYSl7Y2FzZSA5OmNhc2UgMTA6Y2FzZSAxMTpjYXNlIDEyOmNh
-c2UgMTM6Y2FzZSAzMjpjYXNlIDEzMzpjYXNlIDE2MDpyZXR1cm4hMApkZWZhdWx0OnJldHVybiExfXN3
-aXRjaChhKXtjYXNlIDU3NjA6Y2FzZSA4MTkyOmNhc2UgODE5MzpjYXNlIDgxOTQ6Y2FzZSA4MTk1OmNh
-c2UgODE5NjpjYXNlIDgxOTc6Y2FzZSA4MTk4OmNhc2UgODE5OTpjYXNlIDgyMDA6Y2FzZSA4MjAxOmNh
-c2UgODIwMjpjYXNlIDgyMzI6Y2FzZSA4MjMzOmNhc2UgODIzOTpjYXNlIDgyODc6Y2FzZSAxMjI4ODpj
-YXNlIDY1Mjc5OnJldHVybiEwCmRlZmF1bHQ6cmV0dXJuITF9fSwKbW06ZnVuY3Rpb24oYSxiKXt2YXIg
-cyxyCmZvcihzPWEubGVuZ3RoO2I8czspe3I9Qy54Qi5XKGEsYikKaWYociE9PTMyJiZyIT09MTMmJiFK
-LkdhKHIpKWJyZWFrOysrYn1yZXR1cm4gYn0sCmMxOmZ1bmN0aW9uKGEsYil7dmFyIHMscgpmb3IoO2I+
-MDtiPXMpe3M9Yi0xCnI9Qy54Qi5PKGEscykKaWYociE9PTMyJiZyIT09MTMmJiFKLkdhKHIpKWJyZWFr
-fXJldHVybiBifSwKVEo6ZnVuY3Rpb24oYSl7aWYodHlwZW9mIGE9PSJudW1iZXIiKXJldHVybiBKLnFJ
-LnByb3RvdHlwZQppZih0eXBlb2YgYT09InN0cmluZyIpcmV0dXJuIEouRHIucHJvdG90eXBlCmlmKGE9
-PW51bGwpcmV0dXJuIGEKaWYoYS5jb25zdHJ1Y3Rvcj09QXJyYXkpcmV0dXJuIEouamQucHJvdG90eXBl
-CmlmKHR5cGVvZiBhIT0ib2JqZWN0Iil7aWYodHlwZW9mIGE9PSJmdW5jdGlvbiIpcmV0dXJuIEouYzUu
-cHJvdG90eXBlCnJldHVybiBhfWlmKGEgaW5zdGFuY2VvZiBQLk1oKXJldHVybiBhCnJldHVybiBKLmtz
-KGEpfSwKVTY6ZnVuY3Rpb24oYSl7aWYodHlwZW9mIGE9PSJzdHJpbmciKXJldHVybiBKLkRyLnByb3Rv
-dHlwZQppZihhPT1udWxsKXJldHVybiBhCmlmKGEuY29uc3RydWN0b3I9PUFycmF5KXJldHVybiBKLmpk
-LnByb3RvdHlwZQppZih0eXBlb2YgYSE9Im9iamVjdCIpe2lmKHR5cGVvZiBhPT0iZnVuY3Rpb24iKXJl
-dHVybiBKLmM1LnByb3RvdHlwZQpyZXR1cm4gYX1pZihhIGluc3RhbmNlb2YgUC5NaClyZXR1cm4gYQpy
-ZXR1cm4gSi5rcyhhKX0sCllFOmZ1bmN0aW9uKGEpe2lmKGE9PW51bGwpcmV0dXJuIGEKaWYodHlwZW9m
-IGEhPSJvYmplY3QiKXtpZih0eXBlb2YgYT09ImZ1bmN0aW9uIilyZXR1cm4gSi5jNS5wcm90b3R5cGUK
-cmV0dXJuIGF9aWYoYSBpbnN0YW5jZW9mIFAuTWgpcmV0dXJuIGEKcmV0dXJuIEoua3MoYSl9LAppYTpm
-dW5jdGlvbihhKXtpZih0eXBlb2YgYT09Im51bWJlciIpe2lmKE1hdGguZmxvb3IoYSk9PWEpcmV0dXJu
-IEouYlUucHJvdG90eXBlCnJldHVybiBKLkZOLnByb3RvdHlwZX1pZih0eXBlb2YgYT09InN0cmluZyIp
-cmV0dXJuIEouRHIucHJvdG90eXBlCmlmKGE9PW51bGwpcmV0dXJuIEoud2UucHJvdG90eXBlCmlmKHR5
-cGVvZiBhPT0iYm9vbGVhbiIpcmV0dXJuIEoueUUucHJvdG90eXBlCmlmKGEuY29uc3RydWN0b3I9PUFy
-cmF5KXJldHVybiBKLmpkLnByb3RvdHlwZQppZih0eXBlb2YgYSE9Im9iamVjdCIpe2lmKHR5cGVvZiBh
-PT0iZnVuY3Rpb24iKXJldHVybiBKLmM1LnByb3RvdHlwZQpyZXR1cm4gYX1pZihhIGluc3RhbmNlb2Yg
-UC5NaClyZXR1cm4gYQpyZXR1cm4gSi5rcyhhKX0sCnJZOmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhPT0i
-c3RyaW5nIilyZXR1cm4gSi5Eci5wcm90b3R5cGUKaWYoYT09bnVsbClyZXR1cm4gYQppZighKGEgaW5z
-dGFuY2VvZiBQLk1oKSlyZXR1cm4gSi5rZC5wcm90b3R5cGUKcmV0dXJuIGF9LAp2ZDpmdW5jdGlvbihh
-KXtpZih0eXBlb2YgYT09Im51bWJlciIpcmV0dXJuIEoucUkucHJvdG90eXBlCmlmKGE9PW51bGwpcmV0
-dXJuIGEKaWYoIShhIGluc3RhbmNlb2YgUC5NaCkpcmV0dXJuIEoua2QucHJvdG90eXBlCnJldHVybiBh
-fSwKdzE6ZnVuY3Rpb24oYSl7aWYoYT09bnVsbClyZXR1cm4gYQppZihhLmNvbnN0cnVjdG9yPT1BcnJh
-eSlyZXR1cm4gSi5qZC5wcm90b3R5cGUKaWYodHlwZW9mIGEhPSJvYmplY3QiKXtpZih0eXBlb2YgYT09
-ImZ1bmN0aW9uIilyZXR1cm4gSi5jNS5wcm90b3R5cGUKcmV0dXJuIGF9aWYoYSBpbnN0YW5jZW9mIFAu
-TWgpcmV0dXJuIGEKcmV0dXJuIEoua3MoYSl9LApBNTpmdW5jdGlvbihhLGIpe3JldHVybiBKLncxKGEp
-LmVSKGEsYil9LApFaDpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIEouWUUoYSkubUsoYSxiLGMpfSwKRWw6
-ZnVuY3Rpb24oYSxiKXtyZXR1cm4gSi53MShhKS5kcihhLGIpfSwKRjc6ZnVuY3Rpb24oYSl7cmV0dXJu
-IEouVTYoYSkuZ29yKGEpfSwKRkw6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gSi5yWShhKS5kZChhLGIpfSwK
-R0E6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gSi53MShhKS5FKGEsYil9LApIbTpmdW5jdGlvbihhKXtyZXR1
-cm4gSi5VNihhKS5nQShhKX0sCklUOmZ1bmN0aW9uKGEpe3JldHVybiBKLncxKGEpLmdtKGEpfSwKSnk6
-ZnVuY3Rpb24oYSxiKXtyZXR1cm4gSi5pYShhKS5lNyhhLGIpfSwKS1Y6ZnVuY3Rpb24oYSxiKXtyZXR1
-cm4gSi5yWShhKS55bihhLGIpfSwKTHQ6ZnVuY3Rpb24oYSl7cmV0dXJuIEouWUUoYSkud2coYSl9LApN
-MTpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIEoudzEoYSkuRTIoYSxiLGMpfSwKTXU6ZnVuY3Rpb24oYSxi
-KXtyZXR1cm4gSi5ZRShhKS5zUChhLGIpfSwKUXo6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gSi5yWShhKS5X
-KGEsYil9LApSTTpmdW5jdGlvbihhLGIpe2lmKGE9PW51bGwpcmV0dXJuIGI9PW51bGwKaWYodHlwZW9m
-IGEhPSJvYmplY3QiKXJldHVybiBiIT1udWxsJiZhPT09YgpyZXR1cm4gSi5pYShhKS5ETihhLGIpfSwK
-Ulg6ZnVuY3Rpb24oYSl7cmV0dXJuIEoudzEoYSkuYnIoYSl9LApUMDpmdW5jdGlvbihhKXtyZXR1cm4g
-Si5yWShhKS5iUyhhKX0sClZ1OmZ1bmN0aW9uKGEpe3JldHVybiBKLnZkKGEpLnpRKGEpfSwKYTY6ZnVu
-Y3Rpb24oYSxiKXtyZXR1cm4gSi5yWShhKS5PKGEsYil9LApiVDpmdW5jdGlvbihhKXtyZXR1cm4gSi5Z
-RShhKS5ENChhKX0sCmJiOmZ1bmN0aW9uKGEsYil7aWYodHlwZW9mIGE9PSJudW1iZXIiJiZ0eXBlb2Yg
-Yj09Im51bWJlciIpcmV0dXJuIGErYgpyZXR1cm4gSi5USihhKS5oKGEsYil9LApjSDpmdW5jdGlvbihh
-KXtyZXR1cm4gSi5yWShhKS5oYyhhKX0sCmRSOmZ1bmN0aW9uKGEpe3JldHVybiBKLllFKGEpLmdQKGEp
-fSwKZFo6ZnVuY3Rpb24oYSxiLGMsZCl7cmV0dXJuIEouWUUoYSkuT24oYSxiLGMsZCl9LApkZzpmdW5j
-dGlvbihhLGIsYyxkKXtyZXR1cm4gSi5yWShhKS5pNyhhLGIsYyxkKX0sCmRoOmZ1bmN0aW9uKGEpe3Jl
-dHVybiBKLllFKGEpLkZGKGEpfSwKZHI6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gSi5ZRShhKS5zYTQoYSxi
-KX0sCmhmOmZ1bmN0aW9uKGEpe3JldHVybiBKLmlhKGEpLmdpTyhhKX0sCmlnOmZ1bmN0aW9uKGEpe3Jl
-dHVybiBKLllFKGEpLmdRZyhhKX0sCmo6ZnVuY3Rpb24oYSl7cmV0dXJuIEouaWEoYSkudyhhKX0sCmw1
-OmZ1bmN0aW9uKGEsYil7cmV0dXJuIEouWUUoYSkuc2hmKGEsYil9LApsZDpmdW5jdGlvbihhLGIsYyl7
-cmV0dXJuIEouclkoYSkuTmooYSxiLGMpfSwKcDQ6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gSi5yWShhKS5U
-YyhhLGIpfSwKcTA6ZnVuY3Rpb24oYSxiLGMpe3JldHVybiBKLnJZKGEpLlFpKGEsYixjKX0sCnFGOmZ1
-bmN0aW9uKGEpe3JldHVybiBKLllFKGEpLmdWbChhKX0sCnRIOmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4g
-Si5ZRShhKS5wayhhLGIsYyl9LAp1OTpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIEoudzEoYSkuWTUoYSxi
-LGMpfSwKdVU6ZnVuY3Rpb24oYSl7cmV0dXJuIEouVTYoYSkuZ2wwKGEpfSwKd2Y6ZnVuY3Rpb24oYSxi
-KXtyZXR1cm4gSi5ZRShhKS5zUk4oYSxiKX0sCng5OmZ1bmN0aW9uKGEsYil7aWYodHlwZW9mIGI9PT0i
-bnVtYmVyIilpZihhLmNvbnN0cnVjdG9yPT1BcnJheXx8dHlwZW9mIGE9PSJzdHJpbmcifHxILndWKGEs
-YVt2LmRpc3BhdGNoUHJvcGVydHlOYW1lXSkpaWYoYj4+PjA9PT1iJiZiPGEubGVuZ3RoKXJldHVybiBh
-W2JdCnJldHVybiBKLlU2KGEpLnEoYSxiKX0sCnpsOmZ1bmN0aW9uKGEsYil7cmV0dXJuIEouVTYoYSku
-dGcoYSxiKX0sCkd2OmZ1bmN0aW9uIEd2KCl7fSwKeUU6ZnVuY3Rpb24geUUoKXt9LAp3ZTpmdW5jdGlv
-biB3ZSgpe30sCk1GOmZ1bmN0aW9uIE1GKCl7fSwKaUM6ZnVuY3Rpb24gaUMoKXt9LAprZDpmdW5jdGlv
-biBrZCgpe30sCmM1OmZ1bmN0aW9uIGM1KCl7fSwKamQ6ZnVuY3Rpb24gamQoYSl7dGhpcy4kdGk9YX0s
-ClBvOmZ1bmN0aW9uIFBvKGEpe3RoaXMuJHRpPWF9LAptMTpmdW5jdGlvbiBtMShhLGIsYyl7dmFyIF89
-dGhpcwpfLmE9YQpfLmI9YgpfLmM9MApfLmQ9bnVsbApfLiR0aT1jfSwKcUk6ZnVuY3Rpb24gcUkoKXt9
-LApiVTpmdW5jdGlvbiBiVSgpe30sCkZOOmZ1bmN0aW9uIEZOKCl7fSwKRHI6ZnVuY3Rpb24gRHIoKXt9
-fSxQPXsKT2o6ZnVuY3Rpb24oKXt2YXIgcyxyLHE9e30KaWYoc2VsZi5zY2hlZHVsZUltbWVkaWF0ZSE9
-bnVsbClyZXR1cm4gUC5FWCgpCmlmKHNlbGYuTXV0YXRpb25PYnNlcnZlciE9bnVsbCYmc2VsZi5kb2N1
-bWVudCE9bnVsbCl7cz1zZWxmLmRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoImRpdiIpCnI9c2VsZi5kb2N1
-bWVudC5jcmVhdGVFbGVtZW50KCJzcGFuIikKcS5hPW51bGwKbmV3IHNlbGYuTXV0YXRpb25PYnNlcnZl
-cihILnRSKG5ldyBQLnRoKHEpLDEpKS5vYnNlcnZlKHMse2NoaWxkTGlzdDp0cnVlfSkKcmV0dXJuIG5l
-dyBQLmhhKHEscyxyKX1lbHNlIGlmKHNlbGYuc2V0SW1tZWRpYXRlIT1udWxsKXJldHVybiBQLnl0KCkK
-cmV0dXJuIFAucVcoKX0sClpWOmZ1bmN0aW9uKGEpe3NlbGYuc2NoZWR1bGVJbW1lZGlhdGUoSC50Uihu
-ZXcgUC5Wcyh0Lk0uYShhKSksMCkpfSwKb0E6ZnVuY3Rpb24oYSl7c2VsZi5zZXRJbW1lZGlhdGUoSC50
-UihuZXcgUC5GdCh0Lk0uYShhKSksMCkpfSwKQno6ZnVuY3Rpb24oYSl7dC5NLmEoYSkKUC5RTigwLGEp
-fSwKUU46ZnVuY3Rpb24oYSxiKXt2YXIgcz1uZXcgUC5XMygpCnMuQ1koYSxiKQpyZXR1cm4gc30sCkZY
-OmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgUC5paChuZXcgUC52cygkLlgzLGEuQygidnM8MD4iKSksYS5D
-KCJpaDwwPiIpKX0sCkRJOmZ1bmN0aW9uKGEsYil7YS4kMigwLG51bGwpCmIuYj0hMApyZXR1cm4gYi5h
-fSwKalE6ZnVuY3Rpb24oYSxiKXtQLkplKGEsYil9LAp5QzpmdW5jdGlvbihhLGIpe2IuYU0oMCxhKX0s
-CmYzOmZ1bmN0aW9uKGEsYil7Yi53MChILlJ1KGEpLEgudHMoYSkpfSwKSmU6ZnVuY3Rpb24oYSxiKXt2
-YXIgcyxyLHE9bmV3IFAuV00oYikscD1uZXcgUC5TWChiKQppZihhIGluc3RhbmNlb2YgUC52cylhLlFk
-KHEscCx0LnopCmVsc2V7cz10LnoKaWYodC5lLmIoYSkpYS5TcShxLHAscykKZWxzZXtyPW5ldyBQLnZz
-KCQuWDMsdC5jKQpyLmE9NApyLmM9YQpyLlFkKHEscCxzKX19fSwKbHo6ZnVuY3Rpb24oYSl7dmFyIHM9
-ZnVuY3Rpb24oYixjKXtyZXR1cm4gZnVuY3Rpb24oZCxlKXt3aGlsZSh0cnVlKXRyeXtiKGQsZSkKYnJl
-YWt9Y2F0Y2gocil7ZT1yCmQ9Y319fShhLDEpCnJldHVybiAkLlgzLkxqKG5ldyBQLkdzKHMpLHQuSCx0
-LlMsdC56KX0sCklHOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgUC5GeShhLDEpfSwKVGg6ZnVuY3Rpb24o
-KXtyZXR1cm4gQy53UX0sClltOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgUC5GeShhLDMpfSwKbDA6ZnVu
-Y3Rpb24oYSxiKXtyZXR1cm4gbmV3IFAucTQoYSxiLkMoInE0PDA+IikpfSwKVGw6ZnVuY3Rpb24oYSxi
-KXt2YXIgcz1ILmNiKGEsImVycm9yIix0LkspCnJldHVybiBuZXcgUC5DdyhzLGI9PW51bGw/UC52MChh
-KTpiKX0sCnYwOmZ1bmN0aW9uKGEpe3ZhciBzCmlmKHQuci5iKGEpKXtzPWEuZ0lJKCkKaWYocyE9bnVs
-bClyZXR1cm4gc31yZXR1cm4gQy5wZH0sCkE5OmZ1bmN0aW9uKGEsYil7dmFyIHMscixxCmZvcihzPXQu
-YztyPWEuYSxyPT09MjspYT1zLmEoYS5jKQppZihyPj00KXtxPWIuYWgoKQpiLmE9YS5hCmIuYz1hLmMK
-UC5IWihiLHEpfWVsc2V7cT10LkYuYShiLmMpCmIuYT0yCmIuYz1hCmEualEocSl9fSwKSFo6ZnVuY3Rp
-b24oYTAsYTEpe3ZhciBzLHIscSxwLG8sbixtLGwsayxqLGksaCxnLGYsZSxkLGM9bnVsbCxiPXt9LGE9
-Yi5hPWEwCmZvcihzPXQubixyPXQuRixxPXQuZTshMDspe3A9e30Kbz1hLmE9PT04CmlmKGExPT1udWxs
-KXtpZihvKXtuPXMuYShhLmMpClAuTDIoYyxjLGEuYixuLmEsbi5iKX1yZXR1cm59cC5hPWExCm09YTEu
-YQpmb3IoYT1hMTttIT1udWxsO2E9bSxtPWwpe2EuYT1udWxsClAuSFooYi5hLGEpCnAuYT1tCmw9bS5h
-fWs9Yi5hCmo9ay5jCnAuYj1vCnAuYz1qCmk9IW8KaWYoaSl7aD1hLmMKaD0oaCYxKSE9PTB8fChoJjE1
-KT09PTh9ZWxzZSBoPSEwCmlmKGgpe2c9YS5iLmIKaWYobyl7aD1rLmI9PT1nCmg9IShofHxoKX1lbHNl
-IGg9ITEKaWYoaCl7cy5hKGopClAuTDIoYyxjLGsuYixqLmEsai5iKQpyZXR1cm59Zj0kLlgzCmlmKGYh
-PT1nKSQuWDM9ZwplbHNlIGY9YwphPWEuYwppZigoYSYxNSk9PT04KW5ldyBQLlJUKHAsYixvKS4kMCgp
-CmVsc2UgaWYoaSl7aWYoKGEmMSkhPT0wKW5ldyBQLnJxKHAsaikuJDAoKX1lbHNlIGlmKChhJjIpIT09
-MCluZXcgUC5SVyhiLHApLiQwKCkKaWYoZiE9bnVsbCkkLlgzPWYKYT1wLmMKaWYocS5iKGEpKXtrPXAu
-YS4kdGkKaz1rLkMoImI4PDI+IikuYihhKXx8IWsuUVsxXS5iKGEpfWVsc2Ugaz0hMQppZihrKXtxLmEo
-YSkKZT1wLmEuYgppZihhIGluc3RhbmNlb2YgUC52cylpZihhLmE+PTQpe2Q9ci5hKGUuYykKZS5jPW51
-bGwKYTE9ZS5OOChkKQplLmE9YS5hCmUuYz1hLmMKYi5hPWEKY29udGludWV9ZWxzZSBQLkE5KGEsZSkK
-ZWxzZSBlLmVjKGEpCnJldHVybn19ZT1wLmEuYgpkPXIuYShlLmMpCmUuYz1udWxsCmExPWUuTjgoZCkK
-YT1wLmIKaz1wLmMKaWYoIWEpe2UuJHRpLmMuYShrKQplLmE9NAplLmM9a31lbHNle3MuYShrKQplLmE9
-OAplLmM9a31iLmE9ZQphPWV9fSwKVkg6ZnVuY3Rpb24oYSxiKXt2YXIgcwppZih0LmFnLmIoYSkpcmV0
-dXJuIGIuTGooYSx0LnosdC5LLHQubCkKcz10LmJJCmlmKHMuYihhKSlyZXR1cm4gcy5hKGEpCnRocm93
-IEguYihQLkwzKGEsIm9uRXJyb3IiLCJFcnJvciBoYW5kbGVyIG11c3QgYWNjZXB0IG9uZSBPYmplY3Qg
-b3Igb25lIE9iamVjdCBhbmQgYSBTdGFja1RyYWNlIGFzIGFyZ3VtZW50cywgYW5kIHJldHVybiBhIHZh
-bGlkIHJlc3VsdCIpKX0sCnB1OmZ1bmN0aW9uKCl7dmFyIHMscgpmb3Iocz0kLlM2O3MhPW51bGw7cz0k
-LlM2KXskLm1nPW51bGwKcj1zLmIKJC5TNj1yCmlmKHI9PW51bGwpJC5rOD1udWxsCnMuYS4kMCgpfX0s
-CmVOOmZ1bmN0aW9uKCl7JC5VRD0hMAp0cnl7UC5wdSgpfWZpbmFsbHl7JC5tZz1udWxsCiQuVUQ9ITEK
-aWYoJC5TNiE9bnVsbCkkLnV0KCkuJDEoUC5VSSgpKX19LAplVzpmdW5jdGlvbihhKXt2YXIgcz1uZXcg
-UC5PTShhKSxyPSQuazgKaWYocj09bnVsbCl7JC5TNj0kLms4PXMKaWYoISQuVUQpJC51dCgpLiQxKFAu
-VUkoKSl9ZWxzZSAkLms4PXIuYj1zfSwKclI6ZnVuY3Rpb24oYSl7dmFyIHMscixxLHA9JC5TNgppZihw
-PT1udWxsKXtQLmVXKGEpCiQubWc9JC5rOApyZXR1cm59cz1uZXcgUC5PTShhKQpyPSQubWcKaWYocj09
-bnVsbCl7cy5iPXAKJC5TNj0kLm1nPXN9ZWxzZXtxPXIuYgpzLmI9cQokLm1nPXIuYj1zCmlmKHE9PW51
-bGwpJC5rOD1zfX0sCnJiOmZ1bmN0aW9uKGEpe3ZhciBzPW51bGwscj0kLlgzCmlmKEMuTlU9PT1yKXtQ
-LlRrKHMscyxDLk5VLGEpCnJldHVybn1QLlRrKHMscyxyLHQuTS5hKHIuR1koYSkpKX0sClF3OmZ1bmN0
-aW9uKGEsYil7SC5jYihhLCJzdHJlYW0iLHQuSykKcmV0dXJuIG5ldyBQLnhJKGIuQygieEk8MD4iKSl9
-LApMMjpmdW5jdGlvbihhLGIsYyxkLGUpe1AuclIobmV3IFAucEsoZCxlKSl9LApUODpmdW5jdGlvbihh
-LGIsYyxkLGUpe3ZhciBzLHI9JC5YMwppZihyPT09YylyZXR1cm4gZC4kMCgpCiQuWDM9YwpzPXIKdHJ5
-e3I9ZC4kMCgpCnJldHVybiByfWZpbmFsbHl7JC5YMz1zfX0sCnl2OmZ1bmN0aW9uKGEsYixjLGQsZSxm
-LGcpe3ZhciBzLHI9JC5YMwppZihyPT09YylyZXR1cm4gZC4kMShlKQokLlgzPWMKcz1yCnRyeXtyPWQu
-JDEoZSkKcmV0dXJuIHJ9ZmluYWxseXskLlgzPXN9fSwKUXg6ZnVuY3Rpb24oYSxiLGMsZCxlLGYsZyxo
-LGkpe3ZhciBzLHI9JC5YMwppZihyPT09YylyZXR1cm4gZC4kMihlLGYpCiQuWDM9YwpzPXIKdHJ5e3I9
-ZC4kMihlLGYpCnJldHVybiByfWZpbmFsbHl7JC5YMz1zfX0sClRrOmZ1bmN0aW9uKGEsYixjLGQpe3Qu
-TS5hKGQpCmlmKEMuTlUhPT1jKWQ9Yy5HWShkKQpQLmVXKGQpfSwKdGg6ZnVuY3Rpb24gdGgoYSl7dGhp
-cy5hPWF9LApoYTpmdW5jdGlvbiBoYShhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LApW
-czpmdW5jdGlvbiBWcyhhKXt0aGlzLmE9YX0sCkZ0OmZ1bmN0aW9uIEZ0KGEpe3RoaXMuYT1hfSwKVzM6
-ZnVuY3Rpb24gVzMoKXt9LAp5SDpmdW5jdGlvbiB5SChhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKaWg6
-ZnVuY3Rpb24gaWgoYSxiKXt0aGlzLmE9YQp0aGlzLmI9ITEKdGhpcy4kdGk9Yn0sCldNOmZ1bmN0aW9u
-IFdNKGEpe3RoaXMuYT1hfSwKU1g6ZnVuY3Rpb24gU1goYSl7dGhpcy5hPWF9LApHczpmdW5jdGlvbiBH
-cyhhKXt0aGlzLmE9YX0sCkZ5OmZ1bmN0aW9uIEZ5KGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApHVjpm
-dW5jdGlvbiBHVihhLGIpe3ZhciBfPXRoaXMKXy5hPWEKXy5kPV8uYz1fLmI9bnVsbApfLiR0aT1ifSwK
-cTQ6ZnVuY3Rpb24gcTQoYSxiKXt0aGlzLmE9YQp0aGlzLiR0aT1ifSwKQ3c6ZnVuY3Rpb24gQ3coYSxi
-KXt0aGlzLmE9YQp0aGlzLmI9Yn0sClBmOmZ1bmN0aW9uIFBmKCl7fSwKWmY6ZnVuY3Rpb24gWmYoYSxi
-KXt0aGlzLmE9YQp0aGlzLiR0aT1ifSwKRmU6ZnVuY3Rpb24gRmUoYSxiLGMsZCxlKXt2YXIgXz10aGlz
-Cl8uYT1udWxsCl8uYj1hCl8uYz1iCl8uZD1jCl8uZT1kCl8uJHRpPWV9LAp2czpmdW5jdGlvbiB2cyhh
-LGIpe3ZhciBfPXRoaXMKXy5hPTAKXy5iPWEKXy5jPW51bGwKXy4kdGk9Yn0sCmRhOmZ1bmN0aW9uIGRh
-KGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApvUTpmdW5jdGlvbiBvUShhLGIpe3RoaXMuYT1hCnRoaXMu
-Yj1ifSwKcFY6ZnVuY3Rpb24gcFYoYSl7dGhpcy5hPWF9LApVNzpmdW5jdGlvbiBVNyhhKXt0aGlzLmE9
-YX0sCnZyOmZ1bmN0aW9uIHZyKGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9Y30sCnJ0OmZ1
-bmN0aW9uIHJ0KGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApLRjpmdW5jdGlvbiBLRihhLGIpe3RoaXMu
-YT1hCnRoaXMuYj1ifSwKWkw6ZnVuY3Rpb24gWkwoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMu
-Yz1jfSwKUlQ6ZnVuY3Rpb24gUlQoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKalo6
-ZnVuY3Rpb24galooYSl7dGhpcy5hPWF9LApycTpmdW5jdGlvbiBycShhLGIpe3RoaXMuYT1hCnRoaXMu
-Yj1ifSwKUlc6ZnVuY3Rpb24gUlcoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCk9NOmZ1bmN0aW9uIE9N
-KGEpe3RoaXMuYT1hCnRoaXMuYj1udWxsfSwKcWg6ZnVuY3Rpb24gcWgoKXt9LApCNTpmdW5jdGlvbiBC
-NShhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKdU86ZnVuY3Rpb24gdU8oYSxiKXt0aGlzLmE9YQp0aGlz
-LmI9Yn0sCk1POmZ1bmN0aW9uIE1PKCl7fSwKa1Q6ZnVuY3Rpb24ga1QoKXt9LAp4STpmdW5jdGlvbiB4
-SShhKXt0aGlzLiR0aT1hfSwKbTA6ZnVuY3Rpb24gbTAoKXt9LApwSzpmdW5jdGlvbiBwSyhhLGIpe3Ro
-aXMuYT1hCnRoaXMuYj1ifSwKSmk6ZnVuY3Rpb24gSmkoKXt9LApWcDpmdW5jdGlvbiBWcChhLGIpe3Ro
-aXMuYT1hCnRoaXMuYj1ifSwKT1I6ZnVuY3Rpb24gT1IoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRo
-aXMuYz1jfSwKRUY6ZnVuY3Rpb24oYSxiLGMpe3JldHVybiBiLkMoIkA8MD4iKS5LcShjKS5DKCJGbzwx
-LDI+IikuYShILkI3KGEsbmV3IEguTjUoYi5DKCJAPDA+IikuS3EoYykuQygiTjU8MSwyPiIpKSkpfSwK
-Rmw6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gbmV3IEguTjUoYS5DKCJAPDA+IikuS3EoYikuQygiTjU8MSwy
-PiIpKX0sCkxzOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgUC5iNihhLkMoImI2PDA+IikpfSwKVDI6ZnVu
-Y3Rpb24oKXt2YXIgcz1PYmplY3QuY3JlYXRlKG51bGwpCnNbIjxub24taWRlbnRpZmllci1rZXk+Il09
-cwpkZWxldGUgc1siPG5vbi1pZGVudGlmaWVyLWtleT4iXQpyZXR1cm4gc30sCnJqOmZ1bmN0aW9uKGEs
-YixjKXt2YXIgcz1uZXcgUC5sbShhLGIsYy5DKCJsbTwwPiIpKQpzLmM9YS5lCnJldHVybiBzfSwKRVA6
-ZnVuY3Rpb24oYSxiLGMpe3ZhciBzLHIKaWYoUC5oQihhKSl7aWYoYj09PSIoIiYmYz09PSIpIilyZXR1
-cm4iKC4uLikiCnJldHVybiBiKyIuLi4iK2N9cz1ILlZNKFtdLHQucykKQy5ObS5pKCQueGcsYSkKdHJ5
-e1AuVnIoYSxzKX1maW5hbGx5e2lmKDA+PSQueGcubGVuZ3RoKXJldHVybiBILk9IKCQueGcsLTEpCiQu
-eGcucG9wKCl9cj1QLnZnKGIsdC51LmEocyksIiwgIikrYwpyZXR1cm4gci5jaGFyQ29kZUF0KDApPT0w
-P3I6cn0sCldFOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyCmlmKFAuaEIoYSkpcmV0dXJuIGIrIi4uLiIr
-YwpzPW5ldyBQLlJuKGIpCkMuTm0uaSgkLnhnLGEpCnRyeXtyPXMKci5hPVAudmcoci5hLGEsIiwgIil9
-ZmluYWxseXtpZigwPj0kLnhnLmxlbmd0aClyZXR1cm4gSC5PSCgkLnhnLC0xKQokLnhnLnBvcCgpfXMu
-YSs9YwpyPXMuYQpyZXR1cm4gci5jaGFyQ29kZUF0KDApPT0wP3I6cn0sCmhCOmZ1bmN0aW9uKGEpe3Zh
-ciBzLHIKZm9yKHM9JC54Zy5sZW5ndGgscj0wO3I8czsrK3IpaWYoYT09PSQueGdbcl0pcmV0dXJuITAK
-cmV0dXJuITF9LApWcjpmdW5jdGlvbihhLGIpe3ZhciBzLHIscSxwLG8sbixtLGw9YS5nbShhKSxrPTAs
-aj0wCndoaWxlKCEwKXtpZighKGs8ODB8fGo8MykpYnJlYWsKaWYoIWwuRigpKXJldHVybgpzPUguRWoo
-bC5nbCgpKQpDLk5tLmkoYixzKQprKz1zLmxlbmd0aCsyOysran1pZighbC5GKCkpe2lmKGo8PTUpcmV0
-dXJuCmlmKDA+PWIubGVuZ3RoKXJldHVybiBILk9IKGIsLTEpCnI9Yi5wb3AoKQppZigwPj1iLmxlbmd0
-aClyZXR1cm4gSC5PSChiLC0xKQpxPWIucG9wKCl9ZWxzZXtwPWwuZ2woKTsrK2oKaWYoIWwuRigpKXtp
-ZihqPD00KXtDLk5tLmkoYixILkVqKHApKQpyZXR1cm59cj1ILkVqKHApCmlmKDA+PWIubGVuZ3RoKXJl
-dHVybiBILk9IKGIsLTEpCnE9Yi5wb3AoKQprKz1yLmxlbmd0aCsyfWVsc2V7bz1sLmdsKCk7KytqCmZv
-cig7bC5GKCk7cD1vLG89bil7bj1sLmdsKCk7KytqCmlmKGo+MTAwKXt3aGlsZSghMCl7aWYoIShrPjc1
-JiZqPjMpKWJyZWFrCmlmKDA+PWIubGVuZ3RoKXJldHVybiBILk9IKGIsLTEpCmstPWIucG9wKCkubGVu
-Z3RoKzI7LS1qfUMuTm0uaShiLCIuLi4iKQpyZXR1cm59fXE9SC5FaihwKQpyPUguRWoobykKays9ci5s
-ZW5ndGgrcS5sZW5ndGgrNH19aWYoaj5iLmxlbmd0aCsyKXtrKz01Cm09Ii4uLiJ9ZWxzZSBtPW51bGwK
-d2hpbGUoITApe2lmKCEoaz44MCYmYi5sZW5ndGg+MykpYnJlYWsKaWYoMD49Yi5sZW5ndGgpcmV0dXJu
-IEguT0goYiwtMSkKay09Yi5wb3AoKS5sZW5ndGgrMgppZihtPT1udWxsKXtrKz01Cm09Ii4uLiJ9fWlm
-KG0hPW51bGwpQy5ObS5pKGIsbSkKQy5ObS5pKGIscSkKQy5ObS5pKGIscil9LAp0TTpmdW5jdGlvbihh
-LGIpe3ZhciBzLHIscT1QLkxzKGIpCmZvcihzPWEubGVuZ3RoLHI9MDtyPGEubGVuZ3RoO2EubGVuZ3Ro
-PT09c3x8KDAsSC5saykoYSksKytyKXEuaSgwLGIuYShhW3JdKSkKcmV0dXJuIHF9LApuTzpmdW5jdGlv
-bihhKXt2YXIgcyxyPXt9CmlmKFAuaEIoYSkpcmV0dXJuInsuLi59IgpzPW5ldyBQLlJuKCIiKQp0cnl7
-Qy5ObS5pKCQueGcsYSkKcy5hKz0ieyIKci5hPSEwCmEuSygwLG5ldyBQLnJhKHIscykpCnMuYSs9In0i
-fWZpbmFsbHl7aWYoMD49JC54Zy5sZW5ndGgpcmV0dXJuIEguT0goJC54ZywtMSkKJC54Zy5wb3AoKX1y
-PXMuYQpyZXR1cm4gci5jaGFyQ29kZUF0KDApPT0wP3I6cn0sCmI2OmZ1bmN0aW9uIGI2KGEpe3ZhciBf
-PXRoaXMKXy5hPTAKXy5mPV8uZT1fLmQ9Xy5jPV8uYj1udWxsCl8ucj0wCl8uJHRpPWF9LApibjpmdW5j
-dGlvbiBibihhKXt0aGlzLmE9YQp0aGlzLmM9dGhpcy5iPW51bGx9LApsbTpmdW5jdGlvbiBsbShhLGIs
-Yyl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmQ9Xy5jPW51bGwKXy4kdGk9Y30sCm1XOmZ1bmN0aW9u
-IG1XKCl7fSwKdXk6ZnVuY3Rpb24gdXkoKXt9LApsRDpmdW5jdGlvbiBsRCgpe30sCmlsOmZ1bmN0aW9u
-IGlsKCl7fSwKcmE6ZnVuY3Rpb24gcmEoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCllrOmZ1bmN0aW9u
-IFlrKCl7fSwKeVE6ZnVuY3Rpb24geVEoYSl7dGhpcy5hPWF9LApLUDpmdW5jdGlvbiBLUCgpe30sClBu
-OmZ1bmN0aW9uIFBuKCl7fSwKR2o6ZnVuY3Rpb24gR2ooYSxiKXt0aGlzLmE9YQp0aGlzLiR0aT1ifSwK
-bGY6ZnVuY3Rpb24gbGYoKXt9LApWajpmdW5jdGlvbiBWaigpe30sClh2OmZ1bmN0aW9uIFh2KCl7fSwK
-blk6ZnVuY3Rpb24gblkoKXt9LApXWTpmdW5jdGlvbiBXWSgpe30sClJVOmZ1bmN0aW9uIFJVKCl7fSwK
-cFI6ZnVuY3Rpb24gcFIoKXt9LApCUzpmdW5jdGlvbihhLGIpe3ZhciBzLHIscSxwCmlmKHR5cGVvZiBh
-IT0ic3RyaW5nIil0aHJvdyBILmIoSC50TChhKSkKcz1udWxsCnRyeXtzPUpTT04ucGFyc2UoYSl9Y2F0
-Y2gocSl7cj1ILlJ1KHEpCnA9UC5ycihTdHJpbmcociksbnVsbCxudWxsKQp0aHJvdyBILmIocCl9cD1Q
-LlFlKHMpCnJldHVybiBwfSwKUWU6ZnVuY3Rpb24oYSl7dmFyIHMKaWYoYT09bnVsbClyZXR1cm4gbnVs
-bAppZih0eXBlb2YgYSE9Im9iamVjdCIpcmV0dXJuIGEKaWYoT2JqZWN0LmdldFByb3RvdHlwZU9mKGEp
-IT09QXJyYXkucHJvdG90eXBlKXJldHVybiBuZXcgUC51dyhhLE9iamVjdC5jcmVhdGUobnVsbCkpCmZv
-cihzPTA7czxhLmxlbmd0aDsrK3MpYVtzXT1QLlFlKGFbc10pCnJldHVybiBhfSwKa3k6ZnVuY3Rpb24o
-YSxiLGMsZCl7dmFyIHMscgppZihiIGluc3RhbmNlb2YgVWludDhBcnJheSl7cz1iCmQ9cy5sZW5ndGgK
-aWYoZC1jPDE1KXJldHVybiBudWxsCnI9UC5DRyhhLHMsYyxkKQppZihyIT1udWxsJiZhKWlmKHIuaW5k
-ZXhPZigiXHVmZmZkIik+PTApcmV0dXJuIG51bGwKcmV0dXJuIHJ9cmV0dXJuIG51bGx9LApDRzpmdW5j
-dGlvbihhLGIsYyxkKXt2YXIgcz1hPyQuSEcoKTokLnJmKCkKaWYocz09bnVsbClyZXR1cm4gbnVsbApp
-ZigwPT09YyYmZD09PWIubGVuZ3RoKXJldHVybiBQLlJiKHMsYikKcmV0dXJuIFAuUmIocyxiLnN1YmFy
-cmF5KGMsUC5qQihjLGQsYi5sZW5ndGgpKSl9LApSYjpmdW5jdGlvbihhLGIpe3ZhciBzLHIKdHJ5e3M9
-YS5kZWNvZGUoYikKcmV0dXJuIHN9Y2F0Y2gocil7SC5SdShyKX1yZXR1cm4gbnVsbH0sCnhNOmZ1bmN0
-aW9uKGEsYixjLGQsZSxmKXtpZihDLmpuLnpZKGYsNCkhPT0wKXRocm93IEguYihQLnJyKCJJbnZhbGlk
-IGJhc2U2NCBwYWRkaW5nLCBwYWRkZWQgbGVuZ3RoIG11c3QgYmUgbXVsdGlwbGUgb2YgZm91ciwgaXMg
-IitmLGEsYykpCmlmKGQrZSE9PWYpdGhyb3cgSC5iKFAucnIoIkludmFsaWQgYmFzZTY0IHBhZGRpbmcs
-ICc9JyBub3QgYXQgdGhlIGVuZCIsYSxiKSkKaWYoZT4yKXRocm93IEguYihQLnJyKCJJbnZhbGlkIGJh
-c2U2NCBwYWRkaW5nLCBtb3JlIHRoYW4gdHdvICc9JyBjaGFyYWN0ZXJzIixhLGIpKX0sCkd5OmZ1bmN0
-aW9uKGEsYixjKXtyZXR1cm4gbmV3IFAuVWQoYSxiKX0sCk5DOmZ1bmN0aW9uKGEpe3JldHVybiBhLkx0
-KCl9LApVZzpmdW5jdGlvbihhLGIpe3JldHVybiBuZXcgUC50dShhLFtdLFAuQ3koKSl9LAp1WDpmdW5j
-dGlvbihhLGIsYyl7dmFyIHMscj1uZXcgUC5SbigiIikscT1QLlVnKHIsYikKcS5pVShhKQpzPXIuYQpy
-ZXR1cm4gcy5jaGFyQ29kZUF0KDApPT0wP3M6c30sCmo0OmZ1bmN0aW9uKGEpe3N3aXRjaChhKXtjYXNl
-IDY1OnJldHVybiJNaXNzaW5nIGV4dGVuc2lvbiBieXRlIgpjYXNlIDY3OnJldHVybiJVbmV4cGVjdGVk
-IGV4dGVuc2lvbiBieXRlIgpjYXNlIDY5OnJldHVybiJJbnZhbGlkIFVURi04IGJ5dGUiCmNhc2UgNzE6
-cmV0dXJuIk92ZXJsb25nIGVuY29kaW5nIgpjYXNlIDczOnJldHVybiJPdXQgb2YgdW5pY29kZSByYW5n
-ZSIKY2FzZSA3NTpyZXR1cm4iRW5jb2RlZCBzdXJyb2dhdGUiCmNhc2UgNzc6cmV0dXJuIlVuZmluaXNo
-ZWQgVVRGLTggb2N0ZXQgc2VxdWVuY2UiCmRlZmF1bHQ6cmV0dXJuIiJ9fSwKank6ZnVuY3Rpb24oYSxi
-LGMpe3ZhciBzLHIscSxwPWMtYixvPW5ldyBVaW50OEFycmF5KHApCmZvcihzPUouVTYoYSkscj0wO3I8
-cDsrK3Ipe3E9cy5xKGEsYityKQppZih0eXBlb2YgcSE9PSJudW1iZXIiKXJldHVybiBxLnpNKCkKaWYo
-KHEmNDI5NDk2NzA0MCk+Pj4wIT09MClxPTI1NQppZihyPj1wKXJldHVybiBILk9IKG8scikKb1tyXT1x
-fXJldHVybiBvfSwKdXc6ZnVuY3Rpb24gdXcoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9bnVs
-bH0sCmk4OmZ1bmN0aW9uIGk4KGEpe3RoaXMuYT1hfSwKeHI6ZnVuY3Rpb24geHIoKXt9LApOejpmdW5j
-dGlvbiBOeigpe30sCkNWOmZ1bmN0aW9uIENWKCl7fSwKVTg6ZnVuY3Rpb24gVTgoKXt9LApVazpmdW5j
-dGlvbiBVaygpe30sCndJOmZ1bmN0aW9uIHdJKCl7fSwKWmk6ZnVuY3Rpb24gWmkoKXt9LApVZDpmdW5j
-dGlvbiBVZChhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKSzg6ZnVuY3Rpb24gSzgoYSxiKXt0aGlzLmE9
-YQp0aGlzLmI9Yn0sCmJ5OmZ1bmN0aW9uIGJ5KCl7fSwKb2o6ZnVuY3Rpb24gb2ooYSl7dGhpcy5iPWF9
-LApNeDpmdW5jdGlvbiBNeChhKXt0aGlzLmE9YX0sClNoOmZ1bmN0aW9uIFNoKCl7fSwKdGk6ZnVuY3Rp
-b24gdGkoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCnR1OmZ1bmN0aW9uIHR1KGEsYixjKXt0aGlzLmM9
-YQp0aGlzLmE9Ygp0aGlzLmI9Y30sCnU1OmZ1bmN0aW9uIHU1KCl7fSwKRTM6ZnVuY3Rpb24gRTMoKXt9
-LApSdzpmdW5jdGlvbiBSdyhhKXt0aGlzLmI9MAp0aGlzLmM9YX0sCkdZOmZ1bmN0aW9uIEdZKGEpe3Ro
-aXMuYT1hfSwKYno6ZnVuY3Rpb24gYnooYSl7dGhpcy5hPWEKdGhpcy5iPTE2CnRoaXMuYz0wfSwKUUE6
-ZnVuY3Rpb24oYSxiKXt2YXIgcz1ILkhwKGEsYikKaWYocyE9bnVsbClyZXR1cm4gcwp0aHJvdyBILmIo
-UC5ycihhLG51bGwsbnVsbCkpfSwKb3M6ZnVuY3Rpb24oYSl7aWYoYSBpbnN0YW5jZW9mIEguVHApcmV0
-dXJuIGEudygwKQpyZXR1cm4iSW5zdGFuY2Ugb2YgJyIrSC5FaihILk0oYSkpKyInIn0sCk84OmZ1bmN0
-aW9uKGEsYixjLGQpe3ZhciBzLHI9Yz9KLktoKGEsZCk6Si5RaShhLGQpCmlmKGEhPT0wJiZiIT1udWxs
-KWZvcihzPTA7czxyLmxlbmd0aDsrK3MpcltzXT1iCnJldHVybiByfSwKQ0g6ZnVuY3Rpb24oYSxiLGMp
-e3ZhciBzLHI9SC5WTShbXSxjLkMoImpkPDA+IikpCmZvcihzPUouSVQoYSk7cy5GKCk7KUMuTm0uaShy
-LGMuYShzLmdsKCkpKQppZihiKXJldHVybiByCnJldHVybiBKLkVwKHIsYyl9LApZMTpmdW5jdGlvbihh
-LGIsYyl7dmFyIHMKaWYoYilyZXR1cm4gUC5ldihhLGMpCnM9Si5FcChQLmV2KGEsYyksYykKcmV0dXJu
-IHN9LApldjpmdW5jdGlvbihhLGIpe3ZhciBzLHIKaWYoQXJyYXkuaXNBcnJheShhKSlyZXR1cm4gSC5W
-TShhLnNsaWNlKDApLGIuQygiamQ8MD4iKSkKcz1ILlZNKFtdLGIuQygiamQ8MD4iKSkKZm9yKHI9Si5J
-VChhKTtyLkYoKTspQy5ObS5pKHMsci5nbCgpKQpyZXR1cm4gc30sCkFGOmZ1bmN0aW9uKGEsYil7cmV0
-dXJuIEouekMoUC5DSChhLCExLGIpKX0sCkhNOmZ1bmN0aW9uKGEsYixjKXtpZih0LmJtLmIoYSkpcmV0
-dXJuIEguZncoYSxiLFAuakIoYixjLGEubGVuZ3RoKSkKcmV0dXJuIFAuYncoYSxiLGMpfSwKT286ZnVu
-Y3Rpb24oYSl7cmV0dXJuIEguTHcoYSl9LApidzpmdW5jdGlvbihhLGIsYyl7dmFyIHMscixxLHAsbz1u
-dWxsCmlmKGI8MCl0aHJvdyBILmIoUC5URShiLDAsYS5sZW5ndGgsbyxvKSkKcz1jPT1udWxsCmlmKCFz
-JiZjPGIpdGhyb3cgSC5iKFAuVEUoYyxiLGEubGVuZ3RoLG8sbykpCnI9bmV3IEguYTcoYSxhLmxlbmd0
-aCxILnooYSkuQygiYTc8bEQuRT4iKSkKZm9yKHE9MDtxPGI7KytxKWlmKCFyLkYoKSl0aHJvdyBILmIo
-UC5URShiLDAscSxvLG8pKQpwPVtdCmlmKHMpZm9yKDtyLkYoKTspcC5wdXNoKHIuZCkKZWxzZSBmb3Io
-cT1iO3E8YzsrK3Epe2lmKCFyLkYoKSl0aHJvdyBILmIoUC5URShjLGIscSxvLG8pKQpwLnB1c2goci5k
-KX1yZXR1cm4gSC5lVChwKX0sCm51OmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgSC5WUihhLEgudjQoYSwh
-MSwhMCwhMSwhMSwhMSkpfSwKdmc6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzPUouSVQoYikKaWYoIXMuRigp
-KXJldHVybiBhCmlmKGMubGVuZ3RoPT09MCl7ZG8gYSs9SC5FaihzLmdsKCkpCndoaWxlKHMuRigpKX1l
-bHNle2ErPUguRWoocy5nbCgpKQpmb3IoO3MuRigpOylhPWErYytILkVqKHMuZ2woKSl9cmV0dXJuIGF9
-LApscjpmdW5jdGlvbihhLGIsYyxkKXtyZXR1cm4gbmV3IFAubXAoYSxiLGMsZCl9LAp1bzpmdW5jdGlv
-bigpe3ZhciBzPUguTTAoKQppZihzIT1udWxsKXJldHVybiBQLmhLKHMpCnRocm93IEguYihQLkw0KCIn
-VXJpLmJhc2UnIGlzIG5vdCBzdXBwb3J0ZWQiKSl9LAplUDpmdW5jdGlvbihhLGIsYyxkKXt2YXIgcyxy
-LHEscCxvLG4sbT0iMDEyMzQ1Njc4OUFCQ0RFRiIKaWYoYz09PUMueE0pe3M9JC56NCgpLmIKaWYodHlw
-ZW9mIGIhPSJzdHJpbmciKUgudihILnRMKGIpKQpzPXMudGVzdChiKX1lbHNlIHM9ITEKaWYocylyZXR1
-cm4gYgpILkxoKGMpLkMoIlVrLlMiKS5hKGIpCnI9Yy5nWkUoKS5XSihiKQpmb3Iocz1yLmxlbmd0aCxx
-PTAscD0iIjtxPHM7KytxKXtvPXJbcV0KaWYobzwxMjgpe249bz4+PjQKaWYobj49OClyZXR1cm4gSC5P
-SChhLG4pCm49KGFbbl0mMTw8KG8mMTUpKSE9PTB9ZWxzZSBuPSExCmlmKG4pcCs9SC5MdyhvKQplbHNl
-IHA9ZCYmbz09PTMyP3ArIisiOnArIiUiK21bbz4+PjQmMTVdK21bbyYxNV19cmV0dXJuIHAuY2hhckNv
-ZGVBdCgwKT09MD9wOnB9LApHcTpmdW5jdGlvbihhKXt2YXIgcz1NYXRoLmFicyhhKSxyPWE8MD8iLSI6
-IiIKaWYocz49MTAwMClyZXR1cm4iIithCmlmKHM+PTEwMClyZXR1cm4gcisiMCIrcwppZihzPj0xMCly
-ZXR1cm4gcisiMDAiK3MKcmV0dXJuIHIrIjAwMCIrc30sClZ4OmZ1bmN0aW9uKGEpe2lmKGE+PTEwMCly
-ZXR1cm4iIithCmlmKGE+PTEwKXJldHVybiIwIithCnJldHVybiIwMCIrYX0sCmgwOmZ1bmN0aW9uKGEp
-e2lmKGE+PTEwKXJldHVybiIiK2EKcmV0dXJuIjAiK2F9LApwOmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBh
-PT0ibnVtYmVyInx8SC5sKGEpfHxudWxsPT1hKXJldHVybiBKLmooYSkKaWYodHlwZW9mIGE9PSJzdHJp
-bmciKXJldHVybiBKU09OLnN0cmluZ2lmeShhKQpyZXR1cm4gUC5vcyhhKX0sCmhWOmZ1bmN0aW9uKGEp
-e3JldHVybiBuZXcgUC5DNihhKX0sCnhZOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgUC51KCExLG51bGws
-bnVsbCxhKX0sCkwzOmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gbmV3IFAudSghMCxhLGIsYyl9LApNUjpm
-dW5jdGlvbihhLGIsYyl7cmV0dXJuIGF9LApPNzpmdW5jdGlvbihhLGIpe3JldHVybiBuZXcgUC5iSihu
-dWxsLG51bGwsITAsYSxiLCJWYWx1ZSBub3QgaW4gcmFuZ2UiKX0sClRFOmZ1bmN0aW9uKGEsYixjLGQs
-ZSl7cmV0dXJuIG5ldyBQLmJKKGIsYywhMCxhLGQsIkludmFsaWQgdmFsdWUiKX0sCndBOmZ1bmN0aW9u
-KGEsYixjLGQpe2lmKGE8Ynx8YT5jKXRocm93IEguYihQLlRFKGEsYixjLGQsbnVsbCkpCnJldHVybiBh
-fSwKakI6ZnVuY3Rpb24oYSxiLGMpe2lmKDA+YXx8YT5jKXRocm93IEguYihQLlRFKGEsMCxjLCJzdGFy
-dCIsbnVsbCkpCmlmKGIhPW51bGwpe2lmKGE+Ynx8Yj5jKXRocm93IEguYihQLlRFKGIsYSxjLCJlbmQi
-LG51bGwpKQpyZXR1cm4gYn1yZXR1cm4gY30sCmsxOmZ1bmN0aW9uKGEsYil7aWYoYTwwKXRocm93IEgu
-YihQLlRFKGEsMCxudWxsLGIsbnVsbCkpCnJldHVybiBhfSwKQ2Y6ZnVuY3Rpb24oYSxiLGMsZCxlKXt2
-YXIgcz1ILnVQKGU9PW51bGw/Si5IbShiKTplKQpyZXR1cm4gbmV3IFAuZVkocywhMCxhLGMsIkluZGV4
-IG91dCBvZiByYW5nZSIpfSwKTDQ6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLnViKGEpfSwKU1k6ZnVu
-Y3Rpb24oYSl7cmV0dXJuIG5ldyBQLmRzKGEpfSwKUFY6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLmxq
-KGEpfSwKYTQ6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLlVWKGEpfSwKcnI6ZnVuY3Rpb24oYSxiLGMp
-e3JldHVybiBuZXcgUC5hRShhLGIsYyl9LApoSzpmdW5jdGlvbihhNSl7dmFyIHMscixxLHAsbyxuLG0s
-bCxrLGosaSxoLGcsZixlLGQsYyxiLGEsYTAsYTEsYTIsYTM9bnVsbCxhND1hNS5sZW5ndGgKaWYoYTQ+
-PTUpe3M9KChKLlF6KGE1LDQpXjU4KSozfEMueEIuVyhhNSwwKV4xMDB8Qy54Qi5XKGE1LDEpXjk3fEMu
-eEIuVyhhNSwyKV4xMTZ8Qy54Qi5XKGE1LDMpXjk3KT4+PjAKaWYocz09PTApcmV0dXJuIFAuS0QoYTQ8
-YTQ/Qy54Qi5OaihhNSwwLGE0KTphNSw1LGEzKS5nbFIoKQplbHNlIGlmKHM9PT0zMilyZXR1cm4gUC5L
-RChDLnhCLk5qKGE1LDUsYTQpLDAsYTMpLmdsUigpfXI9UC5POCg4LDAsITEsdC5TKQpDLk5tLlk1KHIs
-MCwwKQpDLk5tLlk1KHIsMSwtMSkKQy5ObS5ZNShyLDIsLTEpCkMuTm0uWTUociw3LC0xKQpDLk5tLlk1
-KHIsMywwKQpDLk5tLlk1KHIsNCwwKQpDLk5tLlk1KHIsNSxhNCkKQy5ObS5ZNShyLDYsYTQpCmlmKFAu
-VUIoYTUsMCxhNCwwLHIpPj0xNClDLk5tLlk1KHIsNyxhNCkKcT1yWzFdCmlmKHE+PTApaWYoUC5VQihh
-NSwwLHEsMjAscik9PT0yMClyWzddPXEKcD1yWzJdKzEKbz1yWzNdCm49cls0XQptPXJbNV0KbD1yWzZd
-CmlmKGw8bSltPWwKaWYobjxwKW49bQplbHNlIGlmKG48PXEpbj1xKzEKaWYobzxwKW89bgprPXJbN108
-MAppZihrKWlmKHA+cSszKXtqPWEzCms9ITF9ZWxzZXtpPW8+MAppZihpJiZvKzE9PT1uKXtqPWEzCms9
-ITF9ZWxzZXtpZighKG08YTQmJm09PT1uKzImJkoucTAoYTUsIi4uIixuKSkpaD1tPm4rMiYmSi5xMChh
-NSwiLy4uIixtLTMpCmVsc2UgaD0hMAppZihoKXtqPWEzCms9ITF9ZWxzZXtpZihxPT09NClpZihKLnEw
-KGE1LCJmaWxlIiwwKSl7aWYocDw9MCl7aWYoIUMueEIuUWkoYTUsIi8iLG4pKXtnPSJmaWxlOi8vLyIK
-cz0zfWVsc2V7Zz0iZmlsZTovLyIKcz0yfWE1PWcrQy54Qi5OaihhNSxuLGE0KQpxLT0wCmk9cy0wCm0r
-PWkKbCs9aQphND1hNS5sZW5ndGgKcD03Cm89NwpuPTd9ZWxzZSBpZihuPT09bSl7KytsCmY9bSsxCmE1
-PUMueEIuaTcoYTUsbixtLCIvIik7KythNAptPWZ9aj0iZmlsZSJ9ZWxzZSBpZihDLnhCLlFpKGE1LCJo
-dHRwIiwwKSl7aWYoaSYmbyszPT09biYmQy54Qi5RaShhNSwiODAiLG8rMSkpe2wtPTMKZT1uLTMKbS09
-MwphNT1DLnhCLmk3KGE1LG8sbiwiIikKYTQtPTMKbj1lfWo9Imh0dHAifWVsc2Ugaj1hMwplbHNlIGlm
-KHE9PT01JiZKLnEwKGE1LCJodHRwcyIsMCkpe2lmKGkmJm8rND09PW4mJkoucTAoYTUsIjQ0MyIsbysx
-KSl7bC09NAplPW4tNAptLT00CmE1PUouZGcoYTUsbyxuLCIiKQphNC09MwpuPWV9aj0iaHR0cHMifWVs
-c2Ugaj1hMwprPSEwfX19ZWxzZSBqPWEzCmlmKGspe2k9YTUubGVuZ3RoCmlmKGE0PGkpe2E1PUoubGQo
-YTUsMCxhNCkKcS09MApwLT0wCm8tPTAKbi09MAptLT0wCmwtPTB9cmV0dXJuIG5ldyBQLlVmKGE1LHEs
-cCxvLG4sbSxsLGopfWlmKGo9PW51bGwpaWYocT4wKWo9UC5QaShhNSwwLHEpCmVsc2V7aWYocT09PTAp
-e1AuUjMoYTUsMCwiSW52YWxpZCBlbXB0eSBzY2hlbWUiKQpILkJpKHUuZyl9aj0iIn1pZihwPjApe2Q9
-cSszCmM9ZDxwP1AuelIoYTUsZCxwLTEpOiIiCmI9UC5PZShhNSxwLG8sITEpCmk9bysxCmlmKGk8bil7
-YT1ILkhwKEoubGQoYTUsaSxuKSxhMykKYTA9UC53QihhPT1udWxsP0gudihQLnJyKCJJbnZhbGlkIHBv
-cnQiLGE1LGkpKTphLGopfWVsc2UgYTA9YTN9ZWxzZXthMD1hMwpiPWEwCmM9IiJ9YTE9UC5rYShhNSxu
-LG0sYTMsaixiIT1udWxsKQphMj1tPGw/UC5sZShhNSxtKzEsbCxhMyk6YTMKcmV0dXJuIFAuQ2coaixj
-LGIsYTAsYTEsYTIsbDxhND9QLnRHKGE1LGwrMSxhNCk6YTMpfSwKTXQ6ZnVuY3Rpb24oYSl7SC5oKGEp
-CnJldHVybiBQLmt1KGEsMCxhLmxlbmd0aCxDLnhNLCExKX0sCldYOmZ1bmN0aW9uKGEpe3ZhciBzPXQu
-TgpyZXR1cm4gQy5ObS5OMChILlZNKGEuc3BsaXQoIiYiKSx0LnMpLFAuRmwocyxzKSxuZXcgUC5uMShD
-LnhNKSx0LkopfSwKSGg6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzLHIscSxwLG8sbixtPSJJUHY0IGFkZHJl
-c3Mgc2hvdWxkIGNvbnRhaW4gZXhhY3RseSA0IHBhcnRzIixsPSJlYWNoIHBhcnQgbXVzdCBiZSBpbiB0
-aGUgcmFuZ2UgMC4uMjU1IixrPW5ldyBQLmNTKGEpLGo9bmV3IFVpbnQ4QXJyYXkoNCkKZm9yKHM9Yixy
-PXMscT0wO3M8YzsrK3Mpe3A9Qy54Qi5PKGEscykKaWYocCE9PTQ2KXtpZigocF40OCk+OSlrLiQyKCJp
-bnZhbGlkIGNoYXJhY3RlciIscyl9ZWxzZXtpZihxPT09MylrLiQyKG0scykKbz1QLlFBKEMueEIuTmoo
-YSxyLHMpLG51bGwpCmlmKG8+MjU1KWsuJDIobCxyKQpuPXErMQppZihxPj00KXJldHVybiBILk9IKGos
-cSkKaltxXT1vCnI9cysxCnE9bn19aWYocSE9PTMpay4kMihtLGMpCm89UC5RQShDLnhCLk5qKGEscixj
-KSxudWxsKQppZihvPjI1NSlrLiQyKGwscikKaWYocT49NClyZXR1cm4gSC5PSChqLHEpCmpbcV09bwpy
-ZXR1cm4gan0sCmVnOmZ1bmN0aW9uKGEsYixhMCl7dmFyIHMscixxLHAsbyxuLG0sbCxrLGosaSxoLGcs
-ZixlLGQ9bmV3IFAuVkMoYSksYz1uZXcgUC5KVChkLGEpCmlmKGEubGVuZ3RoPDIpZC4kMSgiYWRkcmVz
-cyBpcyB0b28gc2hvcnQiKQpzPUguVk0oW10sdC5hKQpmb3Iocj1iLHE9cixwPSExLG89ITE7cjxhMDsr
-K3Ipe249Qy54Qi5PKGEscikKaWYobj09PTU4KXtpZihyPT09Yil7KytyCmlmKEMueEIuTyhhLHIpIT09
-NTgpZC4kMigiaW52YWxpZCBzdGFydCBjb2xvbi4iLHIpCnE9cn1pZihyPT09cSl7aWYocClkLiQyKCJv
-bmx5IG9uZSB3aWxkY2FyZCBgOjpgIGlzIGFsbG93ZWQiLHIpCkMuTm0uaShzLC0xKQpwPSEwfWVsc2Ug
-Qy5ObS5pKHMsYy4kMihxLHIpKQpxPXIrMX1lbHNlIGlmKG49PT00NilvPSEwfWlmKHMubGVuZ3RoPT09
-MClkLiQxKCJ0b28gZmV3IHBhcnRzIikKbT1xPT09YTAKbD1DLk5tLmdyWihzKQppZihtJiZsIT09LTEp
-ZC4kMigiZXhwZWN0ZWQgYSBwYXJ0IGFmdGVyIGxhc3QgYDpgIixhMCkKaWYoIW0paWYoIW8pQy5ObS5p
-KHMsYy4kMihxLGEwKSkKZWxzZXtrPVAuSGgoYSxxLGEwKQpDLk5tLmkocywoa1swXTw8OHxrWzFdKT4+
-PjApCkMuTm0uaShzLChrWzJdPDw4fGtbM10pPj4+MCl9aWYocCl7aWYocy5sZW5ndGg+NylkLiQxKCJh
-biBhZGRyZXNzIHdpdGggYSB3aWxkY2FyZCBtdXN0IGhhdmUgbGVzcyB0aGFuIDcgcGFydHMiKX1lbHNl
-IGlmKHMubGVuZ3RoIT09OClkLiQxKCJhbiBhZGRyZXNzIHdpdGhvdXQgYSB3aWxkY2FyZCBtdXN0IGNv
-bnRhaW4gZXhhY3RseSA4IHBhcnRzIikKaj1uZXcgVWludDhBcnJheSgxNikKZm9yKGw9cy5sZW5ndGgs
-aT05LWwscj0wLGg9MDtyPGw7KytyKXtnPXNbcl0KaWYoZz09PS0xKWZvcihmPTA7ZjxpOysrZil7aWYo
-aDwwfHxoPj0xNilyZXR1cm4gSC5PSChqLGgpCmpbaF09MAplPWgrMQppZihlPj0xNilyZXR1cm4gSC5P
-SChqLGUpCmpbZV09MApoKz0yfWVsc2V7ZT1DLmpuLndHKGcsOCkKaWYoaDwwfHxoPj0xNilyZXR1cm4g
-SC5PSChqLGgpCmpbaF09ZQplPWgrMQppZihlPj0xNilyZXR1cm4gSC5PSChqLGUpCmpbZV09ZyYyNTUK
-aCs9Mn19cmV0dXJuIGp9LApDZzpmdW5jdGlvbihhLGIsYyxkLGUsZixnKXtyZXR1cm4gbmV3IFAuRG4o
-YSxiLGMsZCxlLGYsZyl9LApLTDpmdW5jdGlvbihhLGIsYyxkLGUsZixnKXt2YXIgcyxyLHEscCxvLG4K
-Zj1mPT1udWxsPyIiOlAuUGkoZiwwLGYubGVuZ3RoKQpnPVAuelIoZywwLGc9PW51bGw/MDpnLmxlbmd0
-aCkKYT1QLk9lKGEsMCxhPT1udWxsPzA6YS5sZW5ndGgsITEpCnM9UC5sZShudWxsLDAsMCxlKQpyPVAu
-dEcobnVsbCwwLDApCmQ9UC53QihkLGYpCnE9Zj09PSJmaWxlIgppZihhPT1udWxsKXA9Zy5sZW5ndGgh
-PT0wfHxkIT1udWxsfHxxCmVsc2UgcD0hMQppZihwKWE9IiIKcD1hPT1udWxsCm89IXAKYj1QLmthKGIs
-MCxiPT1udWxsPzA6Yi5sZW5ndGgsYyxmLG8pCm49Zi5sZW5ndGg9PT0wCmlmKG4mJnAmJiFDLnhCLm4o
-YiwiLyIpKWI9UC53RihiLCFufHxvKQplbHNlIGI9UC54ZShiKQpyZXR1cm4gUC5DZyhmLGcscCYmQy54
-Qi5uKGIsIi8vIik/IiI6YSxkLGIscyxyKX0sCndLOmZ1bmN0aW9uKGEpe2lmKGE9PT0iaHR0cCIpcmV0
-dXJuIDgwCmlmKGE9PT0iaHR0cHMiKXJldHVybiA0NDMKcmV0dXJuIDB9LApOUjpmdW5jdGlvbihhLGIp
-e3ZhciBzLHIscSxwLG8sbgpmb3Iocz1hLmxlbmd0aCxyPTA7cjxzOysrcil7cT1DLnhCLlcoYSxyKQpw
-PUMueEIuVyhiLHIpCm89cV5wCmlmKG8hPT0wKXtpZihvPT09MzIpe249cHxvCmlmKDk3PD1uJiZuPD0x
-MjIpY29udGludWV9cmV0dXJuITF9fXJldHVybiEwfSwKUjM6ZnVuY3Rpb24oYSxiLGMpe3Rocm93IEgu
-YihQLnJyKGMsYSxiKSl9LApYZDpmdW5jdGlvbihhLGIsYyxkKXt2YXIgcyxyLHEscCxvLG4sbSxsLGss
-aixpLGg9bnVsbCxnPWIubGVuZ3RoCmlmKGchPT0wKXtxPTAKd2hpbGUoITApe2lmKCEocTxnKSl7cz0i
-IgpyPTAKYnJlYWt9aWYoQy54Qi5XKGIscSk9PT02NCl7cz1DLnhCLk5qKGIsMCxxKQpyPXErMQpicmVh
-a30rK3F9aWYocjxnJiZDLnhCLlcoYixyKT09PTkxKXtmb3IocD1yLG89LTE7cDxnOysrcCl7bj1DLnhC
-LlcoYixwKQppZihuPT09MzcmJm88MCl7bT1DLnhCLlFpKGIsIjI1IixwKzEpP3ArMjpwCm89cApwPW19
-ZWxzZSBpZihuPT09OTMpYnJlYWt9aWYocD09PWcpdGhyb3cgSC5iKFAucnIoIkludmFsaWQgSVB2NiBo
-b3N0IGVudHJ5LiIsYixyKSkKbD1vPDA/cDpvClAuZWcoYixyKzEsbCk7KytwCmlmKHAhPT1nJiZDLnhC
-LlcoYixwKSE9PTU4KXRocm93IEguYihQLnJyKCJJbnZhbGlkIGVuZCBvZiBhdXRob3JpdHkiLGIscCkp
-fWVsc2UgcD1yCndoaWxlKCEwKXtpZighKHA8Zykpe2s9aApicmVha31pZihDLnhCLlcoYixwKT09PTU4
-KXtqPUMueEIueW4oYixwKzEpCms9ai5sZW5ndGghPT0wP1AuUUEoaixoKTpoCmJyZWFrfSsrcH1pPUMu
-eEIuTmooYixyLHApfWVsc2V7az1oCmk9awpzPSIifXJldHVybiBQLktMKGksaCxILlZNKGMuc3BsaXQo
-Ii8iKSx0LnMpLGssZCxhLHMpfSwKa0U6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyCmZvcihzPUouSVQoYSk7
-cy5GKCk7KXtyPXMuZ2woKQpyLnRvU3RyaW5nCmlmKEguU1EociwiLyIsMCkpe3M9UC5MNCgiSWxsZWdh
-bCBwYXRoIGNoYXJhY3RlciAiK3IpCnRocm93IEguYihzKX19fSwKSE46ZnVuY3Rpb24oYSxiLGMpe3Zh
-ciBzLHIscQpmb3Iocz1KLkE1KGEsYykscz1zLmdtKHMpO3MuRigpOyl7cj1zLmdsKCkKcT1QLm51KCdb
-IiovOjw+P1xcXFx8XScpCnIudG9TdHJpbmcKaWYoSC5TUShyLHEsMCkpe3M9UC5MNCgiSWxsZWdhbCBj
-aGFyYWN0ZXIgaW4gcGF0aDogIityKQp0aHJvdyBILmIocyl9fX0sCnJnOmZ1bmN0aW9uKGEsYil7dmFy
-IHMKaWYoISg2NTw9YSYmYTw9OTApKXM9OTc8PWEmJmE8PTEyMgplbHNlIHM9ITAKaWYocylyZXR1cm4K
-cz1QLkw0KCJJbGxlZ2FsIGRyaXZlIGxldHRlciAiK1AuT28oYSkpCnRocm93IEguYihzKX0sCndCOmZ1
-bmN0aW9uKGEsYil7aWYoYSE9bnVsbCYmYT09PVAud0soYikpcmV0dXJuIG51bGwKcmV0dXJuIGF9LApP
-ZTpmdW5jdGlvbihhLGIsYyxkKXt2YXIgcyxyLHEscCxvLG4KaWYoYT09bnVsbClyZXR1cm4gbnVsbApp
-ZihiPT09YylyZXR1cm4iIgppZihDLnhCLk8oYSxiKT09PTkxKXtzPWMtMQppZihDLnhCLk8oYSxzKSE9
-PTkzKXtQLlIzKGEsYiwiTWlzc2luZyBlbmQgYF1gIHRvIG1hdGNoIGBbYCBpbiBob3N0IikKSC5CaSh1
-LmcpfXI9YisxCnE9UC50byhhLHIscykKaWYocTxzKXtwPXErMQpvPVAuT0EoYSxDLnhCLlFpKGEsIjI1
-IixwKT9xKzM6cCxzLCIlMjUiKX1lbHNlIG89IiIKUC5lZyhhLHIscSkKcmV0dXJuIEMueEIuTmooYSxi
-LHEpLnRvTG93ZXJDYXNlKCkrbysiXSJ9Zm9yKG49YjtuPGM7KytuKWlmKEMueEIuTyhhLG4pPT09NTgp
-e3E9Qy54Qi5YVShhLCIlIixiKQpxPXE+PWImJnE8Yz9xOmMKaWYocTxjKXtwPXErMQpvPVAuT0EoYSxD
-LnhCLlFpKGEsIjI1IixwKT9xKzM6cCxjLCIlMjUiKX1lbHNlIG89IiIKUC5lZyhhLGIscSkKcmV0dXJu
-IlsiK0MueEIuTmooYSxiLHEpK28rIl0ifXJldHVybiBQLk9MKGEsYixjKX0sCnRvOmZ1bmN0aW9uKGEs
-YixjKXt2YXIgcz1DLnhCLlhVKGEsIiUiLGIpCnJldHVybiBzPj1iJiZzPGM/czpjfSwKT0E6ZnVuY3Rp
-b24oYSxiLGMsZCl7dmFyIHMscixxLHAsbyxuLG0sbCxrLGosaT1kIT09IiI/bmV3IFAuUm4oZCk6bnVs
-bApmb3Iocz1iLHI9cyxxPSEwO3M8Yzspe3A9Qy54Qi5PKGEscykKaWYocD09PTM3KXtvPVAucnYoYSxz
-LCEwKQpuPW89PW51bGwKaWYobiYmcSl7cys9Mwpjb250aW51ZX1pZihpPT1udWxsKWk9bmV3IFAuUm4o
-IiIpCm09aS5hKz1DLnhCLk5qKGEscixzKQppZihuKW89Qy54Qi5OaihhLHMscyszKQplbHNlIGlmKG89
-PT0iJSIpe1AuUjMoYSxzLCJab25lSUQgc2hvdWxkIG5vdCBjb250YWluICUgYW55bW9yZSIpCkguQmko
-dS5nKX1pLmE9bStvCnMrPTMKcj1zCnE9ITB9ZWxzZXtpZihwPDEyNyl7bj1wPj4+NAppZihuPj04KXJl
-dHVybiBILk9IKEMuRjMsbikKbj0oQy5GM1tuXSYxPDwocCYxNSkpIT09MH1lbHNlIG49ITEKaWYobil7
-aWYocSYmNjU8PXAmJjkwPj1wKXtpZihpPT1udWxsKWk9bmV3IFAuUm4oIiIpCmlmKHI8cyl7aS5hKz1D
-LnhCLk5qKGEscixzKQpyPXN9cT0hMX0rK3N9ZWxzZXtpZigocCY2NDUxMik9PT01NTI5NiYmcysxPGMp
-e2w9Qy54Qi5PKGEscysxKQppZigobCY2NDUxMik9PT01NjMyMCl7cD0ocCYxMDIzKTw8MTB8bCYxMDIz
-fDY1NTM2Cms9Mn1lbHNlIGs9MX1lbHNlIGs9MQpqPUMueEIuTmooYSxyLHMpCmlmKGk9PW51bGwpe2k9
-bmV3IFAuUm4oIiIpCm49aX1lbHNlIG49aQpuLmErPWoKbi5hKz1QLnpYKHApCnMrPWsKcj1zfX19aWYo
-aT09bnVsbClyZXR1cm4gQy54Qi5OaihhLGIsYykKaWYocjxjKWkuYSs9Qy54Qi5OaihhLHIsYykKbj1p
-LmEKcmV0dXJuIG4uY2hhckNvZGVBdCgwKT09MD9uOm59LApPTDpmdW5jdGlvbihhLGIsYyl7dmFyIHMs
-cixxLHAsbyxuLG0sbCxrLGosaQpmb3Iocz1iLHI9cyxxPW51bGwscD0hMDtzPGM7KXtvPUMueEIuTyhh
-LHMpCmlmKG89PT0zNyl7bj1QLnJ2KGEscywhMCkKbT1uPT1udWxsCmlmKG0mJnApe3MrPTMKY29udGlu
-dWV9aWYocT09bnVsbClxPW5ldyBQLlJuKCIiKQpsPUMueEIuTmooYSxyLHMpCms9cS5hKz0hcD9sLnRv
-TG93ZXJDYXNlKCk6bAppZihtKXtuPUMueEIuTmooYSxzLHMrMykKaj0zfWVsc2UgaWYobj09PSIlIil7
-bj0iJTI1IgpqPTF9ZWxzZSBqPTMKcS5hPWsrbgpzKz1qCnI9cwpwPSEwfWVsc2V7aWYobzwxMjcpe209
-bz4+PjQKaWYobT49OClyZXR1cm4gSC5PSChDLmVhLG0pCm09KEMuZWFbbV0mMTw8KG8mMTUpKSE9PTB9
-ZWxzZSBtPSExCmlmKG0pe2lmKHAmJjY1PD1vJiY5MD49byl7aWYocT09bnVsbClxPW5ldyBQLlJuKCIi
-KQppZihyPHMpe3EuYSs9Qy54Qi5OaihhLHIscykKcj1zfXA9ITF9KytzfWVsc2V7aWYobzw9OTMpe209
-bz4+PjQKaWYobT49OClyZXR1cm4gSC5PSChDLmFrLG0pCm09KEMuYWtbbV0mMTw8KG8mMTUpKSE9PTB9
-ZWxzZSBtPSExCmlmKG0pe1AuUjMoYSxzLCJJbnZhbGlkIGNoYXJhY3RlciIpCkguQmkodS5nKX1lbHNl
-e2lmKChvJjY0NTEyKT09PTU1Mjk2JiZzKzE8Yyl7aT1DLnhCLk8oYSxzKzEpCmlmKChpJjY0NTEyKT09
-PTU2MzIwKXtvPShvJjEwMjMpPDwxMHxpJjEwMjN8NjU1MzYKaj0yfWVsc2Ugaj0xfWVsc2Ugaj0xCmw9
-Qy54Qi5OaihhLHIscykKaWYoIXApbD1sLnRvTG93ZXJDYXNlKCkKaWYocT09bnVsbCl7cT1uZXcgUC5S
-bigiIikKbT1xfWVsc2UgbT1xCm0uYSs9bAptLmErPVAuelgobykKcys9agpyPXN9fX19aWYocT09bnVs
-bClyZXR1cm4gQy54Qi5OaihhLGIsYykKaWYocjxjKXtsPUMueEIuTmooYSxyLGMpCnEuYSs9IXA/bC50
-b0xvd2VyQ2FzZSgpOmx9bT1xLmEKcmV0dXJuIG0uY2hhckNvZGVBdCgwKT09MD9tOm19LApQaTpmdW5j
-dGlvbihhLGIsYyl7dmFyIHMscixxLHAsbz11LmcKaWYoYj09PWMpcmV0dXJuIiIKaWYoIVAuRXQoSi5y
-WShhKS5XKGEsYikpKXtQLlIzKGEsYiwiU2NoZW1lIG5vdCBzdGFydGluZyB3aXRoIGFscGhhYmV0aWMg
-Y2hhcmFjdGVyIikKSC5CaShvKX1mb3Iocz1iLHI9ITE7czxjOysrcyl7cT1DLnhCLlcoYSxzKQppZihx
-PDEyOCl7cD1xPj4+NAppZihwPj04KXJldHVybiBILk9IKEMubUsscCkKcD0oQy5tS1twXSYxPDwocSYx
-NSkpIT09MH1lbHNlIHA9ITEKaWYoIXApe1AuUjMoYSxzLCJJbGxlZ2FsIHNjaGVtZSBjaGFyYWN0ZXIi
-KQpILkJpKG8pfWlmKDY1PD1xJiZxPD05MClyPSEwfWE9Qy54Qi5OaihhLGIsYykKcmV0dXJuIFAuWWEo
-cj9hLnRvTG93ZXJDYXNlKCk6YSl9LApZYTpmdW5jdGlvbihhKXtpZihhPT09Imh0dHAiKXJldHVybiJo
-dHRwIgppZihhPT09ImZpbGUiKXJldHVybiJmaWxlIgppZihhPT09Imh0dHBzIilyZXR1cm4iaHR0cHMi
-CmlmKGE9PT0icGFja2FnZSIpcmV0dXJuInBhY2thZ2UiCnJldHVybiBhfSwKelI6ZnVuY3Rpb24oYSxi
-LGMpe2lmKGE9PW51bGwpcmV0dXJuIiIKcmV0dXJuIFAuUEkoYSxiLGMsQy50bywhMSl9LAprYTpmdW5j
-dGlvbihhLGIsYyxkLGUsZil7dmFyIHMscixxPWU9PT0iZmlsZSIscD1xfHxmCmlmKGE9PW51bGwpe2lm
-KGQ9PW51bGwpcmV0dXJuIHE/Ii8iOiIiCnM9SC50NihkKQpyPW5ldyBILmxKKGQscy5DKCJxVSgxKSIp
-LmEobmV3IFAuUlooKSkscy5DKCJsSjwxLHFVPiIpKS5rKDAsIi8iKX1lbHNlIGlmKGQhPW51bGwpdGhy
-b3cgSC5iKFAueFkoIkJvdGggcGF0aCBhbmQgcGF0aFNlZ21lbnRzIHNwZWNpZmllZCIpKQplbHNlIHI9
-UC5QSShhLGIsYyxDLldkLCEwKQppZihyLmxlbmd0aD09PTApe2lmKHEpcmV0dXJuIi8ifWVsc2UgaWYo
-cCYmIUMueEIubihyLCIvIikpcj0iLyIrcgpyZXR1cm4gUC5KcihyLGUsZil9LApKcjpmdW5jdGlvbihh
-LGIsYyl7dmFyIHM9Yi5sZW5ndGg9PT0wCmlmKHMmJiFjJiYhQy54Qi5uKGEsIi8iKSlyZXR1cm4gUC53
-RihhLCFzfHxjKQpyZXR1cm4gUC54ZShhKX0sCmxlOmZ1bmN0aW9uKGEsYixjLGQpe3ZhciBzLHI9e30K
-aWYoYSE9bnVsbCl7aWYoZCE9bnVsbCl0aHJvdyBILmIoUC54WSgiQm90aCBxdWVyeSBhbmQgcXVlcnlQ
-YXJhbWV0ZXJzIHNwZWNpZmllZCIpKQpyZXR1cm4gUC5QSShhLGIsYyxDLlZDLCEwKX1pZihkPT1udWxs
-KXJldHVybiBudWxsCnM9bmV3IFAuUm4oIiIpCnIuYT0iIgpkLksoMCxuZXcgUC55NShuZXcgUC5NRShy
-LHMpKSkKcj1zLmEKcmV0dXJuIHIuY2hhckNvZGVBdCgwKT09MD9yOnJ9LAp0RzpmdW5jdGlvbihhLGIs
-Yyl7aWYoYT09bnVsbClyZXR1cm4gbnVsbApyZXR1cm4gUC5QSShhLGIsYyxDLlZDLCEwKX0sCnJ2OmZ1
-bmN0aW9uKGEsYixjKXt2YXIgcyxyLHEscCxvLG49YisyCmlmKG4+PWEubGVuZ3RoKXJldHVybiIlIgpz
-PUMueEIuTyhhLGIrMSkKcj1DLnhCLk8oYSxuKQpxPUgub28ocykKcD1ILm9vKHIpCmlmKHE8MHx8cDww
-KXJldHVybiIlIgpvPXEqMTYrcAppZihvPDEyNyl7bj1DLmpuLndHKG8sNCkKaWYobj49OClyZXR1cm4g
-SC5PSChDLkYzLG4pCm49KEMuRjNbbl0mMTw8KG8mMTUpKSE9PTB9ZWxzZSBuPSExCmlmKG4pcmV0dXJu
-IEguTHcoYyYmNjU8PW8mJjkwPj1vPyhvfDMyKT4+PjA6bykKaWYocz49OTd8fHI+PTk3KXJldHVybiBD
-LnhCLk5qKGEsYixiKzMpLnRvVXBwZXJDYXNlKCkKcmV0dXJuIG51bGx9LAp6WDpmdW5jdGlvbihhKXt2
-YXIgcyxyLHEscCxvLG4sbSxsLGs9IjAxMjM0NTY3ODlBQkNERUYiCmlmKGE8MTI4KXtzPW5ldyBVaW50
-OEFycmF5KDMpCnNbMF09MzcKc1sxXT1DLnhCLlcoayxhPj4+NCkKc1syXT1DLnhCLlcoayxhJjE1KX1l
-bHNle2lmKGE+MjA0NylpZihhPjY1NTM1KXtyPTI0MApxPTR9ZWxzZXtyPTIyNApxPTN9ZWxzZXtyPTE5
-MgpxPTJ9cD0zKnEKcz1uZXcgVWludDhBcnJheShwKQpmb3Iobz0wOy0tcSxxPj0wO3I9MTI4KXtuPUMu
-am4uYmYoYSw2KnEpJjYzfHIKaWYobz49cClyZXR1cm4gSC5PSChzLG8pCnNbb109MzcKbT1vKzEKbD1D
-LnhCLlcoayxuPj4+NCkKaWYobT49cClyZXR1cm4gSC5PSChzLG0pCnNbbV09bApsPW8rMgptPUMueEIu
-VyhrLG4mMTUpCmlmKGw+PXApcmV0dXJuIEguT0gocyxsKQpzW2xdPW0Kbys9M319cmV0dXJuIFAuSE0o
-cywwLG51bGwpfSwKUEk6ZnVuY3Rpb24oYSxiLGMsZCxlKXt2YXIgcz1QLlVsKGEsYixjLGQsZSkKcmV0
-dXJuIHM9PW51bGw/Qy54Qi5OaihhLGIsYyk6c30sClVsOmZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIHMs
-cixxLHAsbyxuLG0sbCxrLGo9bnVsbApmb3Iocz0hZSxyPWIscT1yLHA9ajtyPGM7KXtvPUMueEIuTyhh
-LHIpCmlmKG88MTI3KXtuPW8+Pj40CmlmKG4+PTgpcmV0dXJuIEguT0goZCxuKQpuPShkW25dJjE8PChv
-JjE1KSkhPT0wfWVsc2Ugbj0hMQppZihuKSsrcgplbHNle2lmKG89PT0zNyl7bT1QLnJ2KGEsciwhMSkK
-aWYobT09bnVsbCl7cis9Mwpjb250aW51ZX1pZigiJSI9PT1tKXttPSIlMjUiCmw9MX1lbHNlIGw9M31l
-bHNle2lmKHMpaWYobzw9OTMpe249bz4+PjQKaWYobj49OClyZXR1cm4gSC5PSChDLmFrLG4pCm49KEMu
-YWtbbl0mMTw8KG8mMTUpKSE9PTB9ZWxzZSBuPSExCmVsc2Ugbj0hMQppZihuKXtQLlIzKGEsciwiSW52
-YWxpZCBjaGFyYWN0ZXIiKQpILkJpKHUuZykKbD1qCm09bH1lbHNle2lmKChvJjY0NTEyKT09PTU1Mjk2
-KXtuPXIrMQppZihuPGMpe2s9Qy54Qi5PKGEsbikKaWYoKGsmNjQ1MTIpPT09NTYzMjApe289KG8mMTAy
-Myk8PDEwfGsmMTAyM3w2NTUzNgpsPTJ9ZWxzZSBsPTF9ZWxzZSBsPTF9ZWxzZSBsPTEKbT1QLnpYKG8p
-fX1pZihwPT1udWxsKXtwPW5ldyBQLlJuKCIiKQpuPXB9ZWxzZSBuPXAKbi5hKz1DLnhCLk5qKGEscSxy
-KQpuLmErPUguRWoobSkKaWYodHlwZW9mIGwhPT0ibnVtYmVyIilyZXR1cm4gSC5wWShsKQpyKz1sCnE9
-cn19aWYocD09bnVsbClyZXR1cm4gagppZihxPGMpcC5hKz1DLnhCLk5qKGEscSxjKQpzPXAuYQpyZXR1
-cm4gcy5jaGFyQ29kZUF0KDApPT0wP3M6c30sCnlCOmZ1bmN0aW9uKGEpe2lmKEMueEIubihhLCIuIikp
-cmV0dXJuITAKcmV0dXJuIEMueEIuT1koYSwiLy4iKSE9PS0xfSwKeGU6ZnVuY3Rpb24oYSl7dmFyIHMs
-cixxLHAsbyxuLG0KaWYoIVAueUIoYSkpcmV0dXJuIGEKcz1ILlZNKFtdLHQucykKZm9yKHI9YS5zcGxp
-dCgiLyIpLHE9ci5sZW5ndGgscD0hMSxvPTA7bzxxOysrbyl7bj1yW29dCmlmKEouUk0obiwiLi4iKSl7
-bT1zLmxlbmd0aAppZihtIT09MCl7aWYoMD49bSlyZXR1cm4gSC5PSChzLC0xKQpzLnBvcCgpCmlmKHMu
-bGVuZ3RoPT09MClDLk5tLmkocywiIil9cD0hMH1lbHNlIGlmKCIuIj09PW4pcD0hMAplbHNle0MuTm0u
-aShzLG4pCnA9ITF9fWlmKHApQy5ObS5pKHMsIiIpCnJldHVybiBDLk5tLmsocywiLyIpfSwKd0Y6ZnVu
-Y3Rpb24oYSxiKXt2YXIgcyxyLHEscCxvLG4KaWYoIVAueUIoYSkpcmV0dXJuIWI/UC5DMShhKTphCnM9
-SC5WTShbXSx0LnMpCmZvcihyPWEuc3BsaXQoIi8iKSxxPXIubGVuZ3RoLHA9ITEsbz0wO288cTsrK28p
-e249cltvXQppZigiLi4iPT09bilpZihzLmxlbmd0aCE9PTAmJkMuTm0uZ3JaKHMpIT09Ii4uIil7aWYo
-MD49cy5sZW5ndGgpcmV0dXJuIEguT0gocywtMSkKcy5wb3AoKQpwPSEwfWVsc2V7Qy5ObS5pKHMsIi4u
-IikKcD0hMX1lbHNlIGlmKCIuIj09PW4pcD0hMAplbHNle0MuTm0uaShzLG4pCnA9ITF9fXI9cy5sZW5n
-dGgKaWYociE9PTApaWYocj09PTEpe2lmKDA+PXIpcmV0dXJuIEguT0gocywwKQpyPXNbMF0ubGVuZ3Ro
-PT09MH1lbHNlIHI9ITEKZWxzZSByPSEwCmlmKHIpcmV0dXJuIi4vIgppZihwfHxDLk5tLmdyWihzKT09
-PSIuLiIpQy5ObS5pKHMsIiIpCmlmKCFiKXtpZigwPj1zLmxlbmd0aClyZXR1cm4gSC5PSChzLDApCkMu
-Tm0uWTUocywwLFAuQzEoc1swXSkpfXJldHVybiBDLk5tLmsocywiLyIpfSwKQzE6ZnVuY3Rpb24oYSl7
-dmFyIHMscixxLHA9YS5sZW5ndGgKaWYocD49MiYmUC5FdChKLlF6KGEsMCkpKWZvcihzPTE7czxwOysr
-cyl7cj1DLnhCLlcoYSxzKQppZihyPT09NTgpcmV0dXJuIEMueEIuTmooYSwwLHMpKyIlM0EiK0MueEIu
-eW4oYSxzKzEpCmlmKHI8PTEyNyl7cT1yPj4+NAppZihxPj04KXJldHVybiBILk9IKEMubUsscSkKcT0o
-Qy5tS1txXSYxPDwociYxNSkpPT09MH1lbHNlIHE9ITAKaWYocSlicmVha31yZXR1cm4gYX0sCnVqOmZ1
-bmN0aW9uKGEsYil7aWYoYS5oQigicGFja2FnZSIpJiZhLmM9PW51bGwpcmV0dXJuIFAuZkYoYiwwLGIu
-bGVuZ3RoKQpyZXR1cm4tMX0sCm1uOmZ1bmN0aW9uKGEpe3ZhciBzLHIscSxwPWEuZ0ZqKCksbz1KLlU2
-KHApCmlmKG8uZ0EocCk+MCYmSi5IbShvLnEocCwwKSk9PT0yJiZKLmE2KG8ucShwLDApLDEpPT09NTgp
-e1AucmcoSi5hNihvLnEocCwwKSwwKSwhMSkKUC5ITihwLCExLDEpCnM9ITB9ZWxzZXtQLkhOKHAsITEs
-MCkKcz0hMX1yPWEuZ3RUKCkmJiFzPyJcXCI6IiIKaWYoYS5nY2ooKSl7cT1hLmdKZihhKQppZihxLmxl
-bmd0aCE9PTApcj1yKyJcXCIrcSsiXFwifXI9UC52ZyhyLHAsIlxcIikKbz1zJiZvLmdBKHApPT09MT9y
-KyJcXCI6cgpyZXR1cm4gby5jaGFyQ29kZUF0KDApPT0wP286b30sCkloOmZ1bmN0aW9uKGEsYil7dmFy
-IHMscixxCmZvcihzPTAscj0wO3I8MjsrK3Ipe3E9Qy54Qi5XKGEsYityKQppZig0ODw9cSYmcTw9NTcp
-cz1zKjE2K3EtNDgKZWxzZXtxfD0zMgppZig5Nzw9cSYmcTw9MTAyKXM9cyoxNitxLTg3CmVsc2UgdGhy
-b3cgSC5iKFAueFkoIkludmFsaWQgVVJMIGVuY29kaW5nIikpfX1yZXR1cm4gc30sCmt1OmZ1bmN0aW9u
-KGEsYixjLGQsZSl7dmFyIHMscixxLHAsbz1KLnJZKGEpLG49Ygp3aGlsZSghMCl7aWYoIShuPGMpKXtz
-PSEwCmJyZWFrfXI9by5XKGEsbikKaWYocjw9MTI3KWlmKHIhPT0zNylxPWUmJnI9PT00MwplbHNlIHE9
-ITAKZWxzZSBxPSEwCmlmKHEpe3M9ITEKYnJlYWt9KytufWlmKHMpe2lmKEMueE0hPT1kKXE9ITEKZWxz
-ZSBxPSEwCmlmKHEpcmV0dXJuIG8uTmooYSxiLGMpCmVsc2UgcD1uZXcgSC5xaihvLk5qKGEsYixjKSl9
-ZWxzZXtwPUguVk0oW10sdC5hKQpmb3Iobj1iO248YzsrK24pe3I9by5XKGEsbikKaWYocj4xMjcpdGhy
-b3cgSC5iKFAueFkoIklsbGVnYWwgcGVyY2VudCBlbmNvZGluZyBpbiBVUkkiKSkKaWYocj09PTM3KXtp
-ZihuKzM+YS5sZW5ndGgpdGhyb3cgSC5iKFAueFkoIlRydW5jYXRlZCBVUkkiKSkKQy5ObS5pKHAsUC5J
-aChhLG4rMSkpCm4rPTJ9ZWxzZSBpZihlJiZyPT09NDMpQy5ObS5pKHAsMzIpCmVsc2UgQy5ObS5pKHAs
-cil9fXQuTC5hKHApCnJldHVybiBDLm9FLldKKHApfSwKRXQ6ZnVuY3Rpb24oYSl7dmFyIHM9YXwzMgpy
-ZXR1cm4gOTc8PXMmJnM8PTEyMn0sCktEOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyLHEscCxvLG4sbSxs
-LGs9IkludmFsaWQgTUlNRSB0eXBlIixqPUguVk0oW2ItMV0sdC5hKQpmb3Iocz1hLmxlbmd0aCxyPWIs
-cT0tMSxwPW51bGw7cjxzOysrcil7cD1DLnhCLlcoYSxyKQppZihwPT09NDR8fHA9PT01OSlicmVhawpp
-ZihwPT09NDcpe2lmKHE8MCl7cT1yCmNvbnRpbnVlfXRocm93IEguYihQLnJyKGssYSxyKSl9fWlmKHE8
-MCYmcj5iKXRocm93IEguYihQLnJyKGssYSxyKSkKZm9yKDtwIT09NDQ7KXtDLk5tLmkoaixyKTsrK3IK
-Zm9yKG89LTE7cjxzOysrcil7cD1DLnhCLlcoYSxyKQppZihwPT09NjEpe2lmKG88MClvPXJ9ZWxzZSBp
-ZihwPT09NTl8fHA9PT00NClicmVha31pZihvPj0wKUMuTm0uaShqLG8pCmVsc2V7bj1DLk5tLmdyWihq
-KQppZihwIT09NDR8fHIhPT1uKzd8fCFDLnhCLlFpKGEsImJhc2U2NCIsbisxKSl0aHJvdyBILmIoUC5y
-cigiRXhwZWN0aW5nICc9JyIsYSxyKSkKYnJlYWt9fUMuTm0uaShqLHIpCm09cisxCmlmKChqLmxlbmd0
-aCYxKT09PTEpYT1DLmg5LnlyKGEsbSxzKQplbHNle2w9UC5VbChhLG0scyxDLlZDLCEwKQppZihsIT1u
-dWxsKWE9Qy54Qi5pNyhhLG0scyxsKX1yZXR1cm4gbmV3IFAuUEUoYSxqLGMpfSwKS046ZnVuY3Rpb24o
-KXt2YXIgcyxyLHEscCxvLG4sbT0iMDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJj
-ZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXotLl9+ISQmJygpKissOz0iLGw9Ii4iLGs9IjoiLGo9Ii8iLGk9
-Ij8iLGg9IiMiLGc9SC5WTShuZXcgQXJyYXkoMjIpLHQuZ04pCmZvcihzPTA7czwyMjsrK3MpZ1tzXT1u
-ZXcgVWludDhBcnJheSg5NikKcj1uZXcgUC55SShnKQpxPW5ldyBQLmM2KCkKcD1uZXcgUC5xZCgpCm89
-dC5nYwpuPW8uYShyLiQyKDAsMjI1KSkKcS4kMyhuLG0sMSkKcS4kMyhuLGwsMTQpCnEuJDMobixrLDM0
-KQpxLiQzKG4saiwzKQpxLiQzKG4saSwxNzIpCnEuJDMobixoLDIwNSkKbj1vLmEoci4kMigxNCwyMjUp
-KQpxLiQzKG4sbSwxKQpxLiQzKG4sbCwxNSkKcS4kMyhuLGssMzQpCnEuJDMobixqLDIzNCkKcS4kMyhu
-LGksMTcyKQpxLiQzKG4saCwyMDUpCm49by5hKHIuJDIoMTUsMjI1KSkKcS4kMyhuLG0sMSkKcS4kMyhu
-LCIlIiwyMjUpCnEuJDMobixrLDM0KQpxLiQzKG4saiw5KQpxLiQzKG4saSwxNzIpCnEuJDMobixoLDIw
-NSkKbj1vLmEoci4kMigxLDIyNSkpCnEuJDMobixtLDEpCnEuJDMobixrLDM0KQpxLiQzKG4saiwxMCkK
-cS4kMyhuLGksMTcyKQpxLiQzKG4saCwyMDUpCm49by5hKHIuJDIoMiwyMzUpKQpxLiQzKG4sbSwxMzkp
-CnEuJDMobixqLDEzMSkKcS4kMyhuLGwsMTQ2KQpxLiQzKG4saSwxNzIpCnEuJDMobixoLDIwNSkKbj1v
-LmEoci4kMigzLDIzNSkpCnEuJDMobixtLDExKQpxLiQzKG4saiw2OCkKcS4kMyhuLGwsMTgpCnEuJDMo
-bixpLDE3MikKcS4kMyhuLGgsMjA1KQpuPW8uYShyLiQyKDQsMjI5KSkKcS4kMyhuLG0sNSkKcC4kMyhu
-LCJBWiIsMjI5KQpxLiQzKG4saywxMDIpCnEuJDMobiwiQCIsNjgpCnEuJDMobiwiWyIsMjMyKQpxLiQz
-KG4saiwxMzgpCnEuJDMobixpLDE3MikKcS4kMyhuLGgsMjA1KQpuPW8uYShyLiQyKDUsMjI5KSkKcS4k
-MyhuLG0sNSkKcC4kMyhuLCJBWiIsMjI5KQpxLiQzKG4saywxMDIpCnEuJDMobiwiQCIsNjgpCnEuJDMo
-bixqLDEzOCkKcS4kMyhuLGksMTcyKQpxLiQzKG4saCwyMDUpCm49by5hKHIuJDIoNiwyMzEpKQpwLiQz
-KG4sIjE5Iiw3KQpxLiQzKG4sIkAiLDY4KQpxLiQzKG4saiwxMzgpCnEuJDMobixpLDE3MikKcS4kMyhu
-LGgsMjA1KQpuPW8uYShyLiQyKDcsMjMxKSkKcC4kMyhuLCIwOSIsNykKcS4kMyhuLCJAIiw2OCkKcS4k
-MyhuLGosMTM4KQpxLiQzKG4saSwxNzIpCnEuJDMobixoLDIwNSkKcS4kMyhvLmEoci4kMig4LDgpKSwi
-XSIsNSkKbj1vLmEoci4kMig5LDIzNSkpCnEuJDMobixtLDExKQpxLiQzKG4sbCwxNikKcS4kMyhuLGos
-MjM0KQpxLiQzKG4saSwxNzIpCnEuJDMobixoLDIwNSkKbj1vLmEoci4kMigxNiwyMzUpKQpxLiQzKG4s
-bSwxMSkKcS4kMyhuLGwsMTcpCnEuJDMobixqLDIzNCkKcS4kMyhuLGksMTcyKQpxLiQzKG4saCwyMDUp
-Cm49by5hKHIuJDIoMTcsMjM1KSkKcS4kMyhuLG0sMTEpCnEuJDMobixqLDkpCnEuJDMobixpLDE3MikK
-cS4kMyhuLGgsMjA1KQpuPW8uYShyLiQyKDEwLDIzNSkpCnEuJDMobixtLDExKQpxLiQzKG4sbCwxOCkK
-cS4kMyhuLGosMjM0KQpxLiQzKG4saSwxNzIpCnEuJDMobixoLDIwNSkKbj1vLmEoci4kMigxOCwyMzUp
-KQpxLiQzKG4sbSwxMSkKcS4kMyhuLGwsMTkpCnEuJDMobixqLDIzNCkKcS4kMyhuLGksMTcyKQpxLiQz
-KG4saCwyMDUpCm49by5hKHIuJDIoMTksMjM1KSkKcS4kMyhuLG0sMTEpCnEuJDMobixqLDIzNCkKcS4k
-MyhuLGksMTcyKQpxLiQzKG4saCwyMDUpCm49by5hKHIuJDIoMTEsMjM1KSkKcS4kMyhuLG0sMTEpCnEu
-JDMobixqLDEwKQpxLiQzKG4saSwxNzIpCnEuJDMobixoLDIwNSkKbj1vLmEoci4kMigxMiwyMzYpKQpx
-LiQzKG4sbSwxMikKcS4kMyhuLGksMTIpCnEuJDMobixoLDIwNSkKbj1vLmEoci4kMigxMywyMzcpKQpx
-LiQzKG4sbSwxMykKcS4kMyhuLGksMTMpCnAuJDMoby5hKHIuJDIoMjAsMjQ1KSksImF6IiwyMSkKcj1v
-LmEoci4kMigyMSwyNDUpKQpwLiQzKHIsImF6IiwyMSkKcC4kMyhyLCIwOSIsMjEpCnEuJDMociwiKy0u
-IiwyMSkKcmV0dXJuIGd9LApVQjpmdW5jdGlvbihhLGIsYyxkLGUpe3ZhciBzLHIscSxwLG8sbj0kLnZa
-KCkKZm9yKHM9Si5yWShhKSxyPWI7cjxjOysrcil7aWYoZDwwfHxkPj1uLmxlbmd0aClyZXR1cm4gSC5P
-SChuLGQpCnE9bltkXQpwPXMuVyhhLHIpXjk2Cm89cVtwPjk1PzMxOnBdCmQ9byYzMQpDLk5tLlk1KGUs
-bz4+PjUscil9cmV0dXJuIGR9LApSeDpmdW5jdGlvbihhKXtpZihhLmdaYigpJiZhLmM8PTApcmV0dXJu
-IFAuZkYoYS5hLGEuZSxhLmYpCnJldHVybi0xfSwKZkY6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzLHIscQpm
-b3Iocz1iLHI9MDtzPGM7KytzKXtxPUMueEIuTyhhLHMpCmlmKHE9PT00NylyZXR1cm4gciE9PTA/czot
-MQppZihxPT09Mzd8fHE9PT01OClyZXR1cm4tMQpyfD1xXjQ2fXJldHVybi0xfSwKV0Y6ZnVuY3Rpb24g
-V0YoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCmlQOmZ1bmN0aW9uIGlQKGEsYil7dGhpcy5hPWEKdGhp
-cy5iPWJ9LApYUzpmdW5jdGlvbiBYUygpe30sCkM2OmZ1bmN0aW9uIEM2KGEpe3RoaXMuYT1hfSwKRXo6
-ZnVuY3Rpb24gRXooKXt9LApGOmZ1bmN0aW9uIEYoKXt9LAp1OmZ1bmN0aW9uIHUoYSxiLGMsZCl7dmFy
-IF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLmQ9ZH0sCmJKOmZ1bmN0aW9uIGJKKGEsYixjLGQsZSxm
-KXt2YXIgXz10aGlzCl8uZT1hCl8uZj1iCl8uYT1jCl8uYj1kCl8uYz1lCl8uZD1mfSwKZVk6ZnVuY3Rp
-b24gZVkoYSxiLGMsZCxlKXt2YXIgXz10aGlzCl8uZj1hCl8uYT1iCl8uYj1jCl8uYz1kCl8uZD1lfSwK
-bXA6ZnVuY3Rpb24gbXAoYSxiLGMsZCl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLmQ9ZH0s
-CnViOmZ1bmN0aW9uIHViKGEpe3RoaXMuYT1hfSwKZHM6ZnVuY3Rpb24gZHMoYSl7dGhpcy5hPWF9LAps
-ajpmdW5jdGlvbiBsaihhKXt0aGlzLmE9YX0sClVWOmZ1bmN0aW9uIFVWKGEpe3RoaXMuYT1hfSwKazU6
-ZnVuY3Rpb24gazUoKXt9LApLWTpmdW5jdGlvbiBLWSgpe30sCmM6ZnVuY3Rpb24gYyhhKXt0aGlzLmE9
-YX0sCkNEOmZ1bmN0aW9uIENEKGEpe3RoaXMuYT1hfSwKYUU6ZnVuY3Rpb24gYUUoYSxiLGMpe3RoaXMu
-YT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKY1g6ZnVuY3Rpb24gY1goKXt9LApBbjpmdW5jdGlvbiBBbigp
-e30sCk4zOmZ1bmN0aW9uIE4zKGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLiR0aT1jfSwKYzg6
-ZnVuY3Rpb24gYzgoKXt9LApNaDpmdW5jdGlvbiBNaCgpe30sClpkOmZ1bmN0aW9uIFpkKCl7fSwKUm46
-ZnVuY3Rpb24gUm4oYSl7dGhpcy5hPWF9LApuMTpmdW5jdGlvbiBuMShhKXt0aGlzLmE9YX0sCmNTOmZ1
-bmN0aW9uIGNTKGEpe3RoaXMuYT1hfSwKVkM6ZnVuY3Rpb24gVkMoYSl7dGhpcy5hPWF9LApKVDpmdW5j
-dGlvbiBKVChhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKRG46ZnVuY3Rpb24gRG4oYSxiLGMsZCxlLGYs
-Zyl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLmQ9ZApfLmU9ZQpfLmY9ZgpfLnI9ZwpfLlE9
-Xy56PV8ueT1fLng9JH0sClJaOmZ1bmN0aW9uIFJaKCl7fSwKTUU6ZnVuY3Rpb24gTUUoYSxiKXt0aGlz
-LmE9YQp0aGlzLmI9Yn0sCnk1OmZ1bmN0aW9uIHk1KGEpe3RoaXMuYT1hfSwKUEU6ZnVuY3Rpb24gUEUo
-YSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKeUk6ZnVuY3Rpb24geUkoYSl7dGhpcy5h
-PWF9LApjNjpmdW5jdGlvbiBjNigpe30sCnFkOmZ1bmN0aW9uIHFkKCl7fSwKVWY6ZnVuY3Rpb24gVWYo
-YSxiLGMsZCxlLGYsZyxoKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz1jCl8uZD1kCl8uZT1lCl8u
-Zj1mCl8ucj1nCl8ueD1oCl8ueT1udWxsfSwKcWU6ZnVuY3Rpb24gcWUoYSxiLGMsZCxlLGYsZyl7dmFy
-IF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLmQ9ZApfLmU9ZQpfLmY9ZgpfLnI9ZwpfLlE9Xy56PV8u
-eT1fLng9JH0sCmlKOmZ1bmN0aW9uIGlKKCl7fSwKamc6ZnVuY3Rpb24gamcoYSxiKXt0aGlzLmE9YQp0
-aGlzLmI9Yn0sClRhOmZ1bmN0aW9uIFRhKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApCZjpmdW5jdGlv
-biBCZihhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKQXM6ZnVuY3Rpb24gQXMoKXt9LApHRTpmdW5jdGlv
-biBHRShhKXt0aGlzLmE9YX0sCk43OmZ1bmN0aW9uIE43KGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LAp1
-UTpmdW5jdGlvbiB1USgpe30sCmhGOmZ1bmN0aW9uIGhGKCl7fSwKUjQ6ZnVuY3Rpb24oYSxiLGMsZCl7
-dmFyIHMscixxCkgueTgoYikKdC5qLmEoZCkKaWYoSC5vVChiKSl7cz1bY10KQy5ObS5GVihzLGQpCmQ9
-c31yPXQuegpxPVAuQ0goSi5NMShkLFAudzAoKSxyKSwhMCxyKQp0LlkuYShhKQpyZXR1cm4gUC53WShI
-LkVrKGEscSxudWxsKSl9LApEbTpmdW5jdGlvbihhLGIsYyl7dmFyIHMKdHJ5e2lmKE9iamVjdC5pc0V4
-dGVuc2libGUoYSkmJiFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYSxiKSl7T2Jq
-ZWN0LmRlZmluZVByb3BlcnR5KGEsYix7dmFsdWU6Y30pCnJldHVybiEwfX1jYXRjaChzKXtILlJ1KHMp
-fXJldHVybiExfSwKT206ZnVuY3Rpb24oYSxiKXtpZihPYmplY3QucHJvdG90eXBlLmhhc093blByb3Bl
-cnR5LmNhbGwoYSxiKSlyZXR1cm4gYVtiXQpyZXR1cm4gbnVsbH0sCndZOmZ1bmN0aW9uKGEpe2lmKGE9
-PW51bGx8fHR5cGVvZiBhPT0ic3RyaW5nInx8dHlwZW9mIGE9PSJudW1iZXIifHxILmwoYSkpcmV0dXJu
-IGEKaWYoYSBpbnN0YW5jZW9mIFAuRTQpcmV0dXJuIGEuYQppZihILlI5KGEpKXJldHVybiBhCmlmKHQu
-YWsuYihhKSlyZXR1cm4gYQppZihhIGluc3RhbmNlb2YgUC5pUClyZXR1cm4gSC5vMihhKQppZih0Llku
-YihhKSlyZXR1cm4gUC5oRShhLCIkZGFydF9qc0Z1bmN0aW9uIixuZXcgUC5QQygpKQpyZXR1cm4gUC5o
-RShhLCJfJGRhcnRfanNPYmplY3QiLG5ldyBQLm10KCQua0koKSkpfSwKaEU6ZnVuY3Rpb24oYSxiLGMp
-e3ZhciBzPVAuT20oYSxiKQppZihzPT1udWxsKXtzPWMuJDEoYSkKUC5EbShhLGIscyl9cmV0dXJuIHN9
-LApkVTpmdW5jdGlvbihhKXt2YXIgcyxyCmlmKGE9PW51bGx8fHR5cGVvZiBhPT0ic3RyaW5nInx8dHlw
-ZW9mIGE9PSJudW1iZXIifHx0eXBlb2YgYT09ImJvb2xlYW4iKXJldHVybiBhCmVsc2UgaWYoYSBpbnN0
-YW5jZW9mIE9iamVjdCYmSC5SOShhKSlyZXR1cm4gYQplbHNlIGlmKGEgaW5zdGFuY2VvZiBPYmplY3Qm
-JnQuYWsuYihhKSlyZXR1cm4gYQplbHNlIGlmKGEgaW5zdGFuY2VvZiBEYXRlKXtzPUgudVAoYS5nZXRU
-aW1lKCkpCmlmKE1hdGguYWJzKHMpPD04NjRlMTMpcj0hMQplbHNlIHI9ITAKaWYocilILnYoUC54WSgi
-RGF0ZVRpbWUgaXMgb3V0c2lkZSB2YWxpZCByYW5nZTogIitzKSkKSC5jYighMSwiaXNVdGMiLHQueSkK
-cmV0dXJuIG5ldyBQLmlQKHMsITEpfWVsc2UgaWYoYS5jb25zdHJ1Y3Rvcj09PSQua0koKSlyZXR1cm4g
-YS5vCmVsc2UgcmV0dXJuIFAuTkQoYSl9LApORDpmdW5jdGlvbihhKXtpZih0eXBlb2YgYT09ImZ1bmN0
-aW9uIilyZXR1cm4gUC5pUShhLCQudygpLG5ldyBQLlFTKCkpCmlmKGEgaW5zdGFuY2VvZiBBcnJheSly
-ZXR1cm4gUC5pUShhLCQuUjgoKSxuZXcgUC5ucCgpKQpyZXR1cm4gUC5pUShhLCQuUjgoKSxuZXcgUC5V
-dCgpKX0sCmlROmZ1bmN0aW9uKGEsYixjKXt2YXIgcz1QLk9tKGEsYikKaWYocz09bnVsbHx8IShhIGlu
-c3RhbmNlb2YgT2JqZWN0KSl7cz1jLiQxKGEpClAuRG0oYSxiLHMpfXJldHVybiBzfSwKUEM6ZnVuY3Rp
-b24gUEMoKXt9LAptdDpmdW5jdGlvbiBtdChhKXt0aGlzLmE9YX0sClFTOmZ1bmN0aW9uIFFTKCl7fSwK
-bnA6ZnVuY3Rpb24gbnAoKXt9LApVdDpmdW5jdGlvbiBVdCgpe30sCkU0OmZ1bmN0aW9uIEU0KGEpe3Ro
-aXMuYT1hfSwKcjc6ZnVuY3Rpb24gcjcoYSl7dGhpcy5hPWF9LApUejpmdW5jdGlvbiBUeihhLGIpe3Ro
-aXMuYT1hCnRoaXMuJHRpPWJ9LApjbzpmdW5jdGlvbiBjbygpe30sCm5kOmZ1bmN0aW9uIG5kKCl7fSwK
-S2U6ZnVuY3Rpb24gS2UoYSl7dGhpcy5hPWF9LApoaTpmdW5jdGlvbiBoaSgpe319LFc9ewp4MzpmdW5j
-dGlvbigpe3JldHVybiB3aW5kb3d9LApacjpmdW5jdGlvbigpe3JldHVybiBkb2N1bWVudH0sCko2OmZ1
-bmN0aW9uKGEpe3ZhciBzPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoImEiKQppZihhIT1udWxsKUMueG4u
-c0xVKHMsYSkKcmV0dXJuIHN9LApVOTpmdW5jdGlvbihhLGIsYyl7dmFyIHMscj1kb2N1bWVudC5ib2R5
-CnIudG9TdHJpbmcKcz1DLlJZLnI2KHIsYSxiLGMpCnMudG9TdHJpbmcKcj10LmFjCnI9bmV3IEguVTUo
-bmV3IFcuZTcocyksci5DKCJhMihsRC5FKSIpLmEobmV3IFcuQ3YoKSksci5DKCJVNTxsRC5FPiIpKQpy
-ZXR1cm4gdC5oLmEoci5ncjgocikpfSwKclM6ZnVuY3Rpb24oYSl7dmFyIHMscixxPSJlbGVtZW50IHRh
-ZyB1bmF2YWlsYWJsZSIKdHJ5e3M9Si5ZRShhKQppZih0eXBlb2Ygcy5nbnMoYSk9PSJzdHJpbmciKXE9
-cy5nbnMoYSl9Y2F0Y2gocil7SC5SdShyKX1yZXR1cm4gcX0sCkMwOmZ1bmN0aW9uKGEsYil7YT1hK2Im
-NTM2ODcwOTExCmE9YSsoKGEmNTI0Mjg3KTw8MTApJjUzNjg3MDkxMQpyZXR1cm4gYV5hPj4+Nn0sCnJF
-OmZ1bmN0aW9uKGEsYixjLGQpe3ZhciBzPVcuQzAoVy5DMChXLkMwKFcuQzAoMCxhKSxiKSxjKSxkKSxy
-PXMrKChzJjY3MTA4ODYzKTw8MykmNTM2ODcwOTExCnJePXI+Pj4xMQpyZXR1cm4gcisoKHImMTYzODMp
-PDwxNSkmNTM2ODcwOTExfSwKVE46ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHE9YS5jbGFzc0xpc3QKZm9y
-KHM9Yi5sZW5ndGgscj0wO3I8Yi5sZW5ndGg7Yi5sZW5ndGg9PT1zfHwoMCxILmxrKShiKSwrK3IpcS5h
-ZGQoYltyXSl9LApKRTpmdW5jdGlvbihhLGIsYyxkLGUpe3ZhciBzPVcuYUYobmV3IFcudk4oYyksdC5C
-KQppZihzIT1udWxsJiYhMClKLmRaKGEsYixzLCExKQpyZXR1cm4gbmV3IFcueEMoYSxiLHMsITEsZS5D
-KCJ4QzwwPiIpKX0sClR3OmZ1bmN0aW9uKGEpe3ZhciBzPVcuSjYobnVsbCkscj13aW5kb3cubG9jYXRp
-b24Kcz1uZXcgVy5KUShuZXcgVy5tayhzLHIpKQpzLkNZKGEpCnJldHVybiBzfSwKcUQ6ZnVuY3Rpb24o
-YSxiLGMsZCl7dC5oLmEoYSkKSC5oKGIpCkguaChjKQp0LmNyLmEoZCkKcmV0dXJuITB9LApRVzpmdW5j
-dGlvbihhLGIsYyxkKXt2YXIgcyxyLHEKdC5oLmEoYSkKSC5oKGIpCkguaChjKQpzPXQuY3IuYShkKS5h
-CnI9cy5hCkMueG4uc0xVKHIsYykKcT1yLmhvc3RuYW1lCnM9cy5iCmlmKCEocT09cy5ob3N0bmFtZSYm
-ci5wb3J0PT1zLnBvcnQmJnIucHJvdG9jb2w9PXMucHJvdG9jb2wpKWlmKHE9PT0iIilpZihyLnBvcnQ9
-PT0iIil7cz1yLnByb3RvY29sCnM9cz09PSI6Inx8cz09PSIifWVsc2Ugcz0hMQplbHNlIHM9ITEKZWxz
-ZSBzPSEwCnJldHVybiBzfSwKQmw6ZnVuY3Rpb24oKXt2YXIgcz10Lk4scj1QLnRNKEMuUXgscykscT10
-LmQwLmEobmV3IFcuSUEoKSkscD1ILlZNKFsiVEVNUExBVEUiXSx0LnMpCnM9bmV3IFcuY3QocixQLkxz
-KHMpLFAuTHMocyksUC5McyhzKSxudWxsKQpzLkNZKG51bGwsbmV3IEgubEooQy5ReCxxLHQuZmopLHAs
-bnVsbCkKcmV0dXJuIHN9LApxYzpmdW5jdGlvbihhKXt2YXIgcwppZihhPT1udWxsKXJldHVybiBudWxs
-CmlmKCJwb3N0TWVzc2FnZSIgaW4gYSl7cz1XLlAxKGEpCmlmKHQuYVMuYihzKSlyZXR1cm4gcwpyZXR1
-cm4gbnVsbH1lbHNlIHJldHVybiB0LmNoLmEoYSl9LApQMTpmdW5jdGlvbihhKXtpZihhPT09d2luZG93
-KXJldHVybiB0LmNpLmEoYSkKZWxzZSByZXR1cm4gbmV3IFcuZFcoKX0sCmFGOmZ1bmN0aW9uKGEsYil7
-dmFyIHM9JC5YMwppZihzPT09Qy5OVSlyZXR1cm4gYQpyZXR1cm4gcy5QeShhLGIpfSwKcUU6ZnVuY3Rp
-b24gcUUoKXt9LApHaDpmdW5jdGlvbiBHaCgpe30sCmZZOmZ1bmN0aW9uIGZZKCl7fSwKbkI6ZnVuY3Rp
-b24gbkIoKXt9LApBejpmdW5jdGlvbiBBeigpe30sClFQOmZ1bmN0aW9uIFFQKCl7fSwKbng6ZnVuY3Rp
-b24gbngoKXt9LApvSjpmdW5jdGlvbiBvSigpe30sCmlkOmZ1bmN0aW9uIGlkKCl7fSwKUUY6ZnVuY3Rp
-b24gUUYoKXt9LApOaDpmdW5jdGlvbiBOaCgpe30sCmFlOmZ1bmN0aW9uIGFlKCl7fSwKSUI6ZnVuY3Rp
-b24gSUIoKXt9LApuNzpmdW5jdGlvbiBuNygpe30sCnd6OmZ1bmN0aW9uIHd6KGEsYil7dGhpcy5hPWEK
-dGhpcy4kdGk9Yn0sCmN2OmZ1bmN0aW9uIGN2KCl7fSwKQ3Y6ZnVuY3Rpb24gQ3YoKXt9LAplYTpmdW5j
-dGlvbiBlYSgpe30sCkQwOmZ1bmN0aW9uIEQwKCl7fSwKaEg6ZnVuY3Rpb24gaEgoKXt9LApoNDpmdW5j
-dGlvbiBoNCgpe30sCmJyOmZ1bmN0aW9uIGJyKCl7fSwKVmI6ZnVuY3Rpb24gVmIoKXt9LApmSjpmdW5j
-dGlvbiBmSigpe30sCndhOmZ1bmN0aW9uIHdhKCl7fSwKU2c6ZnVuY3Rpb24gU2coKXt9LAp3NzpmdW5j
-dGlvbiB3Nygpe30sCkFqOmZ1bmN0aW9uIEFqKCl7fSwKZTc6ZnVuY3Rpb24gZTcoYSl7dGhpcy5hPWF9
-LAp1SDpmdW5jdGlvbiB1SCgpe30sCkJIOmZ1bmN0aW9uIEJIKCl7fSwKU046ZnVuY3Rpb24gU04oKXt9
-LApldzpmdW5jdGlvbiBldygpe30sCmxwOmZ1bmN0aW9uIGxwKCl7fSwKVGI6ZnVuY3Rpb24gVGIoKXt9
-LApJdjpmdW5jdGlvbiBJdigpe30sCldQOmZ1bmN0aW9uIFdQKCl7fSwKeVk6ZnVuY3Rpb24geVkoKXt9
-LAp3NjpmdW5jdGlvbiB3Nigpe30sCks1OmZ1bmN0aW9uIEs1KCl7fSwKQ206ZnVuY3Rpb24gQ20oKXt9
-LApDUTpmdW5jdGlvbiBDUSgpe30sCnc0OmZ1bmN0aW9uIHc0KCl7fSwKcmg6ZnVuY3Rpb24gcmgoKXt9
-LApjZjpmdW5jdGlvbiBjZigpe30sCmk3OmZ1bmN0aW9uIGk3KGEpe3RoaXMuYT1hfSwKU3k6ZnVuY3Rp
-b24gU3koYSl7dGhpcy5hPWF9LApLUzpmdW5jdGlvbiBLUyhhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwK
-QTM6ZnVuY3Rpb24gQTMoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCkk0OmZ1bmN0aW9uIEk0KGEpe3Ro
-aXMuYT1hfSwKRms6ZnVuY3Rpb24gRmsoYSxiKXt0aGlzLmE9YQp0aGlzLiR0aT1ifSwKUk86ZnVuY3Rp
-b24gUk8oYSxiLGMsZCl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLiR0aT1kfSwKZXU6ZnVu
-Y3Rpb24gZXUoYSxiLGMsZCl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLiR0aT1kfSwKeEM6
-ZnVuY3Rpb24geEMoYSxiLGMsZCxlKXt2YXIgXz10aGlzCl8uYj1hCl8uYz1iCl8uZD1jCl8uZT1kCl8u
-JHRpPWV9LAp2TjpmdW5jdGlvbiB2TihhKXt0aGlzLmE9YX0sCkpROmZ1bmN0aW9uIEpRKGEpe3RoaXMu
-YT1hfSwKR206ZnVuY3Rpb24gR20oKXt9LAp2RDpmdW5jdGlvbiB2RChhKXt0aGlzLmE9YX0sClV2OmZ1
-bmN0aW9uIFV2KGEpe3RoaXMuYT1hfSwKRWc6ZnVuY3Rpb24gRWcoYSxiLGMpe3RoaXMuYT1hCnRoaXMu
-Yj1iCnRoaXMuYz1jfSwKbTY6ZnVuY3Rpb24gbTYoKXt9LApFbzpmdW5jdGlvbiBFbygpe30sCldrOmZ1
-bmN0aW9uIFdrKCl7fSwKY3Q6ZnVuY3Rpb24gY3QoYSxiLGMsZCxlKXt2YXIgXz10aGlzCl8uZT1hCl8u
-YT1iCl8uYj1jCl8uYz1kCl8uZD1lfSwKSUE6ZnVuY3Rpb24gSUEoKXt9LApPdzpmdW5jdGlvbiBPdygp
-e30sClc5OmZ1bmN0aW9uIFc5KGEsYixjKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz0tMQpfLmQ9
-bnVsbApfLiR0aT1jfSwKZFc6ZnVuY3Rpb24gZFcoKXt9LAptazpmdW5jdGlvbiBtayhhLGIpe3RoaXMu
-YT1hCnRoaXMuYj1ifSwKS286ZnVuY3Rpb24gS28oYSl7dGhpcy5hPWEKdGhpcy5iPSExfSwKZm06ZnVu
-Y3Rpb24gZm0oYSl7dGhpcy5hPWF9LApMZTpmdW5jdGlvbiBMZSgpe30sCks3OmZ1bmN0aW9uIEs3KCl7
-fSwKckI6ZnVuY3Rpb24gckIoKXt9LApYVzpmdW5jdGlvbiBYVygpe30sCm9hOmZ1bmN0aW9uIG9hKCl7
-fX0sVT17CmpmOmZ1bmN0aW9uKGEpe3ZhciBzLHIscSxwCmlmKGE9PW51bGwpcz1udWxsCmVsc2V7cz1I
-LlZNKFtdLHQuZDcpCmZvcihyPUouSVQodC5VLmEoYSkpO3IuRigpOyl7cT1yLmdsKCkKcD1KLlU2KHEp
-CnMucHVzaChuZXcgVS5TZShILmgocC5xKHEsImRlc2NyaXB0aW9uIikpLEguaChwLnEocSwiaHJlZiIp
-KSkpfX1yZXR1cm4gc30sCk5kOmZ1bmN0aW9uKGEpe3ZhciBzLHIKaWYoYT09bnVsbClzPW51bGwKZWxz
-ZXtzPUguVk0oW10sdC5hQSkKZm9yKHI9Si5JVCh0LlUuYShhKSk7ci5GKCk7KXMucHVzaChVLk5mKHIu
-Z2woKSkpfXJldHVybiBzfSwKTmY6ZnVuY3Rpb24oYSl7dmFyIHM9Si5VNihhKSxyPUguaChzLnEoYSwi
-ZGVzY3JpcHRpb24iKSkscT1ILlZNKFtdLHQuYUopCmZvcihzPUouSVQodC5VLmEocy5xKGEsImVudHJp
-ZXMiKSkpO3MuRigpOylxLnB1c2goVS5SaihzLmdsKCkpKQpyZXR1cm4gbmV3IFUueUQocixxKX0sClJq
-OmZ1bmN0aW9uKGEpe3ZhciBzLHI9Si5VNihhKSxxPUguaChyLnEoYSwiZGVzY3JpcHRpb24iKSkscD1I
-Lmgoci5xKGEsImZ1bmN0aW9uIikpLG89ci5xKGEsImxpbmsiKQppZihvPT1udWxsKW89bnVsbAplbHNl
-e3M9Si5VNihvKQpvPW5ldyBVLk1sKEguaChzLnEobywiaHJlZiIpKSxILnVQKHMucShvLCJsaW5lIikp
-LEguaChzLnEobywicGF0aCIpKSl9cj10LmZLLmEoci5xKGEsImhpbnRBY3Rpb25zIikpCnI9cj09bnVs
-bD9udWxsOkouTTEocixuZXcgVS5hTigpLHQuYVgpCnI9cj09bnVsbD9udWxsOnIuYnIoMCkKcmV0dXJu
-IG5ldyBVLndiKHEscCxvLHI9PW51bGw/Qy5kbjpyKX0sCmQyOmZ1bmN0aW9uIGQyKGEsYixjLGQsZSxm
-KXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz1jCl8uZD1kCl8uZT1lCl8uZj1mfSwKU2U6ZnVuY3Rp
-b24gU2UoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCk1sOmZ1bmN0aW9uIE1sKGEsYixjKXt0aGlzLmE9
-YQp0aGlzLmI9Ygp0aGlzLmM9Y30sCnlEOmZ1bmN0aW9uIHlEKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9
-LAp3YjpmdW5jdGlvbiB3YihhLGIsYyxkKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz1jCl8uZD1k
-fSwKYU46ZnVuY3Rpb24gYU4oKXt9LApiMDpmdW5jdGlvbiBiMCgpe319LEI9ewp3UjpmdW5jdGlvbigp
-e3JldHVybiBuZXcgQi5xcCgiIiwiIiwiIixDLkR4KX0sCllmOmZ1bmN0aW9uKGEpe3ZhciBzLHIscSxw
-LG8sbixtLGwsaz1ILmgoYS5xKDAsInJlZ2lvbnMiKSksaj1ILmgoYS5xKDAsIm5hdmlnYXRpb25Db250
-ZW50IikpLGk9SC5oKGEucSgwLCJzb3VyY2VDb2RlIikpLGg9UC5GbCh0LlgsdC5kXykKZm9yKHM9dC50
-LmEoYS5xKDAsImVkaXRzIikpLHM9cy5nUHUocykscz1zLmdtKHMpLHI9dC5VLHE9dC5oNDtzLkYoKTsp
-e3A9cy5nbCgpCm89cC5hCm49SC5WTShbXSxxKQpmb3IocD1KLklUKHIuYShwLmIpKTtwLkYoKTspe209
-cC5nbCgpCmw9Si5VNihtKQpuLnB1c2gobmV3IEIuajgoSC51UChsLnEobSwibGluZSIpKSxILmgobC5x
-KG0sImV4cGxhbmF0aW9uIikpLEgudVAobC5xKG0sIm9mZnNldCIpKSkpfWguWTUoMCxvLG4pfXJldHVy
-biBuZXcgQi5xcChrLGosaSxoKX0sCmo4OmZ1bmN0aW9uIGo4KGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9
-Ygp0aGlzLmM9Y30sCnFwOmZ1bmN0aW9uIHFwKGEsYixjLGQpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIK
-Xy5jPWMKXy5kPWR9LApmdjpmdW5jdGlvbiBmdigpe30sCk9TOmZ1bmN0aW9uKGEpe3ZhciBzCmlmKCEo
-YT49NjUmJmE8PTkwKSlzPWE+PTk3JiZhPD0xMjIKZWxzZSBzPSEwCnJldHVybiBzfSwKWXU6ZnVuY3Rp
-b24oYSxiKXt2YXIgcz1hLmxlbmd0aCxyPWIrMgppZihzPHIpcmV0dXJuITEKaWYoIUIuT1MoQy54Qi5P
-KGEsYikpKXJldHVybiExCmlmKEMueEIuTyhhLGIrMSkhPT01OClyZXR1cm4hMQppZihzPT09cilyZXR1
-cm4hMApyZXR1cm4gQy54Qi5PKGEscik9PT00N319LFQ9e21ROmZ1bmN0aW9uIG1RKCl7fX0sTD17Cklx
-OmZ1bmN0aW9uKCl7Qy5CWi5CKGRvY3VtZW50LCJET01Db250ZW50TG9hZGVkIixuZXcgTC5lKCkpCkMu
-b2wuQih3aW5kb3csInBvcHN0YXRlIixuZXcgTC5MKCkpfSwKa3o6ZnVuY3Rpb24oYSl7dmFyIHMscj10
-LmcuYShhLnBhcmVudE5vZGUpLnF1ZXJ5U2VsZWN0b3IoIjpzY29wZSA+IHVsIikscT1yLnN0eWxlLHA9
-IiIrQy5DRC56UShyLm9mZnNldEhlaWdodCkqMisicHgiCnEubWF4SGVpZ2h0PXAKcT1KLnFGKGEpCnA9
-cS4kdGkKcz1wLkMoIn4oMSk/IikuYShuZXcgTC5XeChyLGEpKQp0LlouYShudWxsKQpXLkpFKHEuYSxx
-LmIscywhMSxwLmMpfSwKeVg6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEscCxvLG4sbT0icXVlcnlTZWxl
-Y3RvckFsbCIsbD1kb2N1bWVudC5xdWVyeVNlbGVjdG9yKGEpLGs9dC5nCmwudG9TdHJpbmcKcz10LmgK
-SC5EaChrLHMsIlQiLG0pCnI9dC5SCnE9bmV3IFcud3oobC5xdWVyeVNlbGVjdG9yQWxsKCIubmF2LWxp
-bmsiKSxyKQpxLksocSxuZXcgTC5BTyhiKSkKSC5EaChrLHMsIlQiLG0pCnA9bmV3IFcud3oobC5xdWVy
-eVNlbGVjdG9yQWxsKCIucmVnaW9uIikscikKaWYoIXAuZ2wwKHApKXtvPWwucXVlcnlTZWxlY3Rvcigi
-dGFibGVbZGF0YS1wYXRoXSIpCm8udG9TdHJpbmcKcC5LKHAsbmV3IEwuSG8oby5nZXRBdHRyaWJ1dGUo
-ImRhdGEtIituZXcgVy5TeShuZXcgVy5pNyhvKSkuT1UoInBhdGgiKSkpKX1ILkRoKGsscywiVCIsbSkK
-bj1uZXcgVy53eihsLnF1ZXJ5U2VsZWN0b3JBbGwoIi5hZGQtaGludC1saW5rIikscikKbi5LKG4sbmV3
-IEwuSUMoKSl9LApRNjpmdW5jdGlvbihhLGIsYyl7dmFyIHM9bmV3IFhNTEh0dHBSZXF1ZXN0KCkKQy5E
-dC5lbyhzLCJHRVQiLEwuUTQoYSxiKSwhMCkKcy5zZXRSZXF1ZXN0SGVhZGVyKCJDb250ZW50LVR5cGUi
-LCJhcHBsaWNhdGlvbi9qc29uOyBjaGFyc2V0PVVURi04IikKcmV0dXJuIEwuTFUocyxudWxsLGMuQygi
-MCoiKSl9LAp0eTpmdW5jdGlvbihhLGIpe3ZhciBzPW5ldyBYTUxIdHRwUmVxdWVzdCgpLHI9dC5YCkMu
-RHQuZW8ocywiUE9TVCIsTC5RNChhLFAuRmwocixyKSksITApCnMuc2V0UmVxdWVzdEhlYWRlcigiQ29u
-dGVudC1UeXBlIiwiYXBwbGljYXRpb24vanNvbjsgY2hhcnNldD1VVEYtOCIpCnJldHVybiBMLkxVKHMs
-Yix0LnQpfSwKTFU6ZnVuY3Rpb24oYSxiLGMpe3JldHVybiBMLlRnKGEsYixjLGMuQygiMCoiKSl9LApU
-ZzpmdW5jdGlvbihhLGIsYyxkKXt2YXIgcz0wLHI9UC5GWChkKSxxLHA9MixvLG49W10sbSxsLGssaixp
-LGgsZyxmCnZhciAkYXN5bmMkTFU9UC5seihmdW5jdGlvbihlLGEwKXtpZihlPT09MSl7bz1hMApzPXB9
-d2hpbGUodHJ1ZSlzd2l0Y2gocyl7Y2FzZSAwOmk9bmV3IFAuWmYobmV3IFAudnMoJC5YMyx0LmdWKSx0
-LmJDKQpoPXQuZWIKZz1oLmEobmV3IEwuZkMoaSxhKSkKdC5aLmEobnVsbCkKbD10LmVRClcuSkUoYSwi
-bG9hZCIsZywhMSxsKQpXLkpFKGEsImVycm9yIixoLmEoaS5nWUooKSksITEsbCkKYS5zZW5kKGI9PW51
-bGw/bnVsbDpDLkN0Lk9CKGIsbnVsbCkpCnA9NApzPTcKcmV0dXJuIFAualEoaS5hLCRhc3luYyRMVSkK
-Y2FzZSA3OnA9MgpzPTYKYnJlYWsKY2FzZSA0OnA9MwpmPW8KSC5SdShmKQptPUgudHMoZikKaD1QLlRs
-KCJFcnJvciByZWFjaGluZyBtaWdyYXRpb24gcHJldmlldyBzZXJ2ZXIuIixtKQp0aHJvdyBILmIoaCkK
-cz02CmJyZWFrCmNhc2UgMzpzPTIKYnJlYWsKY2FzZSA2Omo9Qy5DdC5wVygwLGEucmVzcG9uc2VUZXh0
-LG51bGwpCmlmKGEuc3RhdHVzPT09MjAwKXtxPWMuQygiMCoiKS5hKGopCnM9MQpicmVha31lbHNlIHRo
-cm93IEguYihqKQpjYXNlIDE6cmV0dXJuIFAueUMocSxyKQpjYXNlIDI6cmV0dXJuIFAuZjMobyxyKX19
-KQpyZXR1cm4gUC5ESSgkYXN5bmMkTFUscil9LAphSzpmdW5jdGlvbihhKXt2YXIgcz1QLmhLKGEpLmdo
-WSgpLnEoMCwibGluZSIpCnJldHVybiBzPT1udWxsP251bGw6SC5IcChzLG51bGwpfSwKRzY6ZnVuY3Rp
-b24oYSl7dmFyIHM9UC5oSyhhKS5naFkoKS5xKDAsIm9mZnNldCIpCnJldHVybiBzPT1udWxsP251bGw6
-SC5IcChzLG51bGwpfSwKaTY6ZnVuY3Rpb24oYSl7cmV0dXJuIEwublcodC5PLmEoYSkpfSwKblc6ZnVu
-Y3Rpb24oYSl7dmFyIHM9MCxyPVAuRlgodC56KSxxPTEscCxvPVtdLG4sbSxsLGssaixpLGgKdmFyICRh
-c3luYyRpNj1QLmx6KGZ1bmN0aW9uKGIsYyl7aWYoYj09PTEpe3A9YwpzPXF9d2hpbGUodHJ1ZSlzd2l0
-Y2gocyl7Y2FzZSAwOmk9dC5nLmEoVy5xYyhhLmN1cnJlbnRUYXJnZXQpKS5nZXRBdHRyaWJ1dGUoImhy
-ZWYiKQphLnByZXZlbnREZWZhdWx0KCkKcT0zCms9ZG9jdW1lbnQKbj1DLkNELnpRKGsucXVlcnlTZWxl
-Y3RvcigiLmNvbnRlbnQiKS5zY3JvbGxUb3ApCnM9NgpyZXR1cm4gUC5qUShMLnR5KGksbnVsbCksJGFz
-eW5jJGk2KQpjYXNlIDY6cz03CnJldHVybiBQLmpRKEwuRzcod2luZG93LmxvY2F0aW9uLnBhdGhuYW1l
-LG51bGwsbnVsbCwhMSxudWxsKSwkYXN5bmMkaTYpCmNhc2UgNzprPWsucXVlcnlTZWxlY3RvcigiLmNv
-bnRlbnQiKQprLnRvU3RyaW5nCmsuc2Nyb2xsVG9wPUouVnUobikKcT0xCnM9NQpicmVhawpjYXNlIDM6
-cT0yCmg9cAptPUguUnUoaCkKbD1ILnRzKGgpCkwuQzIoIkNvdWxkIG5vdCBhZGQvcmVtb3ZlIGhpbnQi
-LG0sbCkKcz01CmJyZWFrCmNhc2UgMjpzPTEKYnJlYWsKY2FzZSA1OnJldHVybiBQLnlDKG51bGwscikK
-Y2FzZSAxOnJldHVybiBQLmYzKHAscil9fSkKcmV0dXJuIFAuREkoJGFzeW5jJGk2LHIpfSwKQzI6ZnVu
-Y3Rpb24oYSxiLGMpe3ZhciBzLHIscSxwPSJleGNlcHRpb24iLG89InN0YWNrVHJhY2UiLG49dC50LmIo
-YikmJkouUk0oYi5xKDAsInN1Y2Nlc3MiKSwhMSkmJmIueDQocCkmJmIueDQobyksbT1KLmlhKGIpCmlm
-KG4pe3M9SC5oKG0ucShiLHApKQpjPW0ucShiLG8pfWVsc2Ugcz1tLncoYikKbj1kb2N1bWVudApyPW4u
-cXVlcnlTZWxlY3RvcigiLnBvcHVwLXBhbmUiKQpyLnF1ZXJ5U2VsZWN0b3IoImgyIikuaW5uZXJUZXh0
-PWEKci5xdWVyeVNlbGVjdG9yKCJwIikuaW5uZXJUZXh0PXMKci5xdWVyeVNlbGVjdG9yKCJwcmUiKS5p
-bm5lclRleHQ9Si5qKGMpCnE9dC5kZC5hKHIucXVlcnlTZWxlY3RvcigiYS5ib3R0b20iKSk7KHEmJkMu
-eG4pLnNMVShxLFAuWGQoImh0dHBzIiwiZ2l0aHViLmNvbSIsImRhcnQtbGFuZy9zZGsvaXNzdWVzL25l
-dyIsUC5FRihbInRpdGxlIiwiQ3VzdG9tZXItcmVwb3J0ZWQgaXNzdWUgd2l0aCBOTkJEIG1pZ3JhdGlv
-biB0b29sOiAiK2EsImxhYmVscyIsdS5kLCJib2R5IixhKyJcblxuRXJyb3I6ICIrSC5FaihzKSsiXG5c
-blBsZWFzZSBmaWxsIGluIHRoZSBmb2xsb3dpbmc6XG5cbioqTmFtZSBvZiBwYWNrYWdlIGJlaW5nIG1p
-Z3JhdGVkIChpZiBwdWJsaWMpKio6XG4qKldoYXQgSSB3YXMgZG9pbmcgd2hlbiB0aGlzIGlzc3VlIG9j
-Y3VycmVkKio6XG4qKklzIGl0IHBvc3NpYmxlIHRvIHdvcmsgYXJvdW5kIHRoaXMgaXNzdWUqKjpcbioq
-SGFzIHRoaXMgaXNzdWUgaGFwcGVuZWQgYmVmb3JlLCBhbmQgaWYgc28sIGhvdyBvZnRlbioqOlxuKipE
-YXJ0IFNESyB2ZXJzaW9uKio6ICIrSC5FaihuLmdldEVsZW1lbnRCeUlkKCJzZGstdmVyc2lvbiIpLnRl
-eHRDb250ZW50KSsiXG4qKkFkZGl0aW9uYWwgZGV0YWlscyoqOlxuXG5UaGFua3MgZm9yIGZpbGluZyFc
-blxuU3RhY2t0cmFjZTogX2F1dG8gcG9wdWxhdGVkIGJ5IG1pZ3JhdGlvbiBwcmV2aWV3IHRvb2wuX1xu
-XG5gYGBcbiIrSC5FaihjKSsiXG5gYGBcbiJdLHQuWCx0LnopKS5nbkQoKSkKbj1xLnN0eWxlCm4uZGlz
-cGxheT0iaW5pdGlhbCIKbj1yLnN0eWxlCm4uZGlzcGxheT0iaW5pdGlhbCIKbj1hKyI6ICIrSC5Faihi
-KQp3aW5kb3cKaWYodHlwZW9mIGNvbnNvbGUhPSJ1bmRlZmluZWQiKXdpbmRvdy5jb25zb2xlLmVycm9y
-KG4pCndpbmRvdwpuPUguRWooYykKaWYodHlwZW9mIGNvbnNvbGUhPSJ1bmRlZmluZWQiKXdpbmRvdy5j
-b25zb2xlLmVycm9yKG4pfSwKdDI6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEscCxvPXQuZy5hKFcucWMo
-YS5jdXJyZW50VGFyZ2V0KSkKYS5wcmV2ZW50RGVmYXVsdCgpCnM9by5nZXRBdHRyaWJ1dGUoImhyZWYi
-KQpyPUwuVXMocykKcT1MLkc2KHMpCnA9TC5hSyhzKQppZihxIT1udWxsKUwuYWYocixxLHAsYixuZXcg
-TC5uVChyLHEscCkpCmVsc2UgTC5hZihyLG51bGwsbnVsbCxiLG5ldyBMLk5ZKHIpKX0sCkswOmZ1bmN0
-aW9uKGEpe3ZhciBzLHIscSxwPWRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoIi5wb3B1cC1wYW5lIikKcC5x
-dWVyeVNlbGVjdG9yKCJoMiIpLmlubmVyVGV4dD0iRmFpbGVkIHRvIHJlcnVuIGZyb20gc291cmNlcyIK
-cC5xdWVyeVNlbGVjdG9yKCJwIikuaW5uZXJUZXh0PSJTb3VyY2VzIGNvbnRhaW4gc3RhdGljIGFuYWx5
-c2lzIGVycm9yczoiCnM9cC5xdWVyeVNlbGVjdG9yKCJwcmUiKQpyPUouRWwoYSx0LmF3KQpxPUguTGgo
-cikKcy5pbm5lclRleHQ9bmV3IEgubEoocixxLkMoInFVKihsRC5FKSIpLmEobmV3IEwudWUoKSkscS5D
-KCJsSjxsRC5FLHFVKj4iKSkuaygwLCJcbiIpCnE9cC5xdWVyeVNlbGVjdG9yKCJhLmJvdHRvbSIpLnN0
-eWxlCnEuZGlzcGxheT0ibm9uZSIKcz1wLnN0eWxlCnMuZGlzcGxheT0iaW5pdGlhbCJ9LAp2VTpmdW5j
-dGlvbigpe3ZhciBzPWRvY3VtZW50CkguRGgodC5nLHQuaCwiVCIsInF1ZXJ5U2VsZWN0b3JBbGwiKQpz
-PW5ldyBXLnd6KHMucXVlcnlTZWxlY3RvckFsbCgiLmNvZGUiKSx0LlIpCnMuSyhzLG5ldyBMLmVYKCkp
-fSwKaFg6ZnVuY3Rpb24oYSxiLGMpe3JldHVybiBMLll3KGEsYixjKX0sCll3OmZ1bmN0aW9uKGEsYixj
-KXt2YXIgcz0wLHI9UC5GWCh0LnopLHE9MSxwLG89W10sbixtLGwsayxqLGksaCxnCnZhciAkYXN5bmMk
-aFg9UC5seihmdW5jdGlvbihkLGUpe2lmKGQ9PT0xKXtwPWUKcz1xfXdoaWxlKHRydWUpc3dpdGNoKHMp
-e2Nhc2UgMDpxPTMKaj10LlgKcz02CnJldHVybiBQLmpRKEwuUTYoYSxQLkVGKFsicmVnaW9uIiwicmVn
-aW9uIiwib2Zmc2V0IixILkVqKGIpXSxqLGopLHQudCksJGFzeW5jJGhYKQpjYXNlIDY6bj1lCmo9bgpp
-PUouVTYoaikKbT1uZXcgVS5kMihVLmpmKGkucShqLCJlZGl0cyIpKSxILmgoaS5xKGosImV4cGxhbmF0
-aW9uIikpLEgudVAoaS5xKGosImxpbmUiKSksSC5oKGkucShqLCJkaXNwbGF5UGF0aCIpKSxILmgoaS5x
-KGosInVyaVBhdGgiKSksVS5OZChpLnEoaiwidHJhY2VzIikpKQpMLlQxKG0pCkwuRnIoYSxiLGMpCkwu
-eVgoIi5lZGl0LXBhbmVsIC5wYW5lbC1jb250ZW50IiwhMSkKcT0xCnM9NQpicmVhawpjYXNlIDM6cT0y
-Cmc9cApsPUguUnUoZykKaz1ILnRzKGcpCkwuQzIoIkNvdWxkIG5vdCBsb2FkIGVkaXQgZGV0YWlscyIs
-bCxrKQpzPTUKYnJlYWsKY2FzZSAyOnM9MQpicmVhawpjYXNlIDU6cmV0dXJuIFAueUMobnVsbCxyKQpj
-YXNlIDE6cmV0dXJuIFAuZjMocCxyKX19KQpyZXR1cm4gUC5ESSgkYXN5bmMkaFgscil9LApHNzpmdW5j
-dGlvbihhLGIsYyxkLGUpe3JldHVybiBMLkw1KGEsYixjLGQsZSl9LApMNTpmdW5jdGlvbihhLGIsYyxk
-LGUpe3ZhciBzPTAscj1QLkZYKHQuSCkscSxwPTIsbyxuPVtdLG0sbCxrLGosaSxoLGcKdmFyICRhc3lu
-YyRHNz1QLmx6KGZ1bmN0aW9uKGYsYTApe2lmKGY9PT0xKXtvPWEwCnM9cH13aGlsZSh0cnVlKXN3aXRj
-aChzKXtjYXNlIDA6aWYoIUoucDQoYSwiLmRhcnQiKSl7TC5CRShhLEIud1IoKSxkKQpMLkJYKGEsbnVs
-bCkKaWYoZSE9bnVsbCllLiQwKCkKcz0xCmJyZWFrfXA9NAppPXQuWApzPTcKcmV0dXJuIFAualEoTC5R
-NihhLFAuRUYoWyJpbmxpbmUiLCJ0cnVlIl0saSxpKSx0LnQpLCRhc3luYyRHNykKY2FzZSA3Om09YTAK
-TC5CRShhLEIuWWYobSksZCkKTC5mRyhiLGMpCmw9TC5VcyhhKQpMLkJYKGwsYikKaWYoZSE9bnVsbCll
-LiQwKCkKcD0yCnM9NgpicmVhawpjYXNlIDQ6cD0zCmc9bwprPUguUnUoZykKaj1ILnRzKGcpCkwuQzIo
-IkNvdWxkIG5vdCBsb2FkIGRhcnQgZmlsZSAiK2EsayxqKQpzPTYKYnJlYWsKY2FzZSAzOnM9MgpicmVh
-awpjYXNlIDY6Y2FzZSAxOnJldHVybiBQLnlDKHEscikKY2FzZSAyOnJldHVybiBQLmYzKG8scil9fSkK
-cmV0dXJuIFAuREkoJGFzeW5jJEc3LHIpfSwKR2U6ZnVuY3Rpb24oKXt2YXIgcz0wLHI9UC5GWCh0Lnop
-LHE9MSxwLG89W10sbixtLGwsayxqLGksaCxnCnZhciAkYXN5bmMkR2U9UC5seihmdW5jdGlvbihhLGIp
-e2lmKGE9PT0xKXtwPWIKcz1xfXdoaWxlKHRydWUpc3dpdGNoKHMpe2Nhc2UgMDpoPSIvX3ByZXZpZXcv
-bmF2aWdhdGlvblRyZWUuanNvbiIKcT0zCnM9NgpyZXR1cm4gUC5qUShMLlE2KGgsQy5DTSx0LmVFKSwk
-YXN5bmMkR2UpCmNhc2UgNjpuPWIKbT1kb2N1bWVudC5xdWVyeVNlbGVjdG9yKCIubmF2LXRyZWUiKQpK
-Lmw1KG0sIiIpCmo9TC5tSyhuKQokLklSPWoKTC50WChtLGosITApCnE9MQpzPTUKYnJlYWsKY2FzZSAz
-OnE9MgpnPXAKbD1ILlJ1KGcpCms9SC50cyhnKQpMLkMyKCJDb3VsZCBub3QgbG9hZCBuYXZpZ2F0aW9u
-IHRyZWUiLGwsaykKcz01CmJyZWFrCmNhc2UgMjpzPTEKYnJlYWsKY2FzZSA1OnJldHVybiBQLnlDKG51
-bGwscikKY2FzZSAxOnJldHVybiBQLmYzKHAscil9fSkKcmV0dXJuIFAuREkoJGFzeW5jJEdlLHIpfSwK
-cU86ZnVuY3Rpb24oYSl7dmFyIHMscj1hLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLHE9Qy5DRC56USgk
-LmZpKCkub2Zmc2V0SGVpZ2h0KSxwPXdpbmRvdy5pbm5lckhlaWdodCxvPUMuQ0QuelEoJC5EVygpLm9m
-ZnNldEhlaWdodCkKaWYodHlwZW9mIHAhPT0ibnVtYmVyIilyZXR1cm4gcC5ITigpCnM9ci5ib3R0b20K
-cy50b1N0cmluZwppZihzPnAtKG8rMTQpKUouZGgoYSkKZWxzZXtwPXIudG9wCnAudG9TdHJpbmcKaWYo
-cDxxKzE0KUouZGgoYSl9fSwKZkc6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEscCxvCmlmKGEhPW51bGwp
-e3M9ZG9jdW1lbnQKcj1zLmdldEVsZW1lbnRCeUlkKCJvIitILkVqKGEpKQpxPXMucXVlcnlTZWxlY3Rv
-cigiLmxpbmUtIitILkVqKGIpKQppZihyIT1udWxsKXtMLnFPKHIpCkouZFIocikuaSgwLCJ0YXJnZXQi
-KX1lbHNlIGlmKHEhPW51bGwpTC5xTyhxLnBhcmVudEVsZW1lbnQpCmlmKHEhPW51bGwpSi5kUih0Lmcu
-YShxLnBhcmVudE5vZGUpKS5pKDAsImhpZ2hsaWdodCIpfWVsc2V7cz1kb2N1bWVudApwPXQuZwpILkRo
-KHAsdC5oLCJUIiwicXVlcnlTZWxlY3RvckFsbCIpCnM9cy5xdWVyeVNlbGVjdG9yQWxsKCIubGluZS1u
-byIpCm89bmV3IFcud3oocyx0LlIpCmlmKG8uZ0Eobyk9PT0wKXJldHVybgpMLnFPKHAuYShDLnQ1Lmd0
-SChzKSkpfX0sCmFmOmZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIHMscixxPUwuRzYod2luZG93LmxvY2F0
-aW9uLmhyZWYpLHA9TC5hSyh3aW5kb3cubG9jYXRpb24uaHJlZikKaWYocSE9bnVsbCl7cz1kb2N1bWVu
-dC5nZXRFbGVtZW50QnlJZCgibyIrSC5FaihxKSkKaWYocyE9bnVsbClKLmRSKHMpLlIoMCwidGFyZ2V0
-Iil9aWYocCE9bnVsbCl7cj1kb2N1bWVudC5xdWVyeVNlbGVjdG9yKCIubGluZS0iK0guRWoocCkpCmlm
-KHIhPW51bGwpSi5kUihyLnBhcmVudEVsZW1lbnQpLlIoMCwiaGlnaGxpZ2h0Iil9aWYoYT09d2luZG93
-LmxvY2F0aW9uLnBhdGhuYW1lKXtMLmZHKGIsYykKZS4kMCgpfWVsc2UgTC5HNyhhLGIsYyxkLGUpfSwK
-UTQ6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHE9UC5oSyhhKSxwPXQuWApwPVAuRmwocCxwKQpmb3Iocz1x
-LmdoWSgpLHM9cy5nUHUocykscz1zLmdtKHMpO3MuRigpOyl7cj1zLmdsKCkKcC5ZNSgwLHIuYSxyLmIp
-fWZvcihzPWIuZ1B1KGIpLHM9cy5nbShzKTtzLkYoKTspe3I9cy5nbCgpCnAuWTUoMCxyLmEsci5iKX1w
-Llk1KDAsImF1dGhUb2tlbiIsJC5VRSgpKQpyZXR1cm4gcS5ubSgwLHApLmduRCgpfSwKVDE6ZnVuY3Rp
-b24oYSl7dmFyIHMscixxLHAsbyxuLG0sbCxrLGo9JC5oTCgpCkoubDUoaiwiIikKaWYoYT09bnVsbCl7
-cz1kb2N1bWVudC5jcmVhdGVFbGVtZW50KCJwIikKQy5MdC5zYTQocywiU2VlIGRldGFpbHMgYWJvdXQg
-YSBwcm9wb3NlZCBlZGl0LiIpCkMuTHQuc1AocyxILlZNKFsicGxhY2Vob2xkZXIiXSx0LmkpKQpqLmFw
-cGVuZENoaWxkKHMpCkMuTHQuRkYocykKcmV0dXJufXI9YS5kCnE9JC5uVSgpCnA9cS56ZihyKQpvPWEu
-YgpuPWRvY3VtZW50Cm09cS5IUChyLEouVDAobi5xdWVyeVNlbGVjdG9yKCIucm9vdCIpLnRleHRDb250
-ZW50KSkKbD1hLmMKaz1uLmNyZWF0ZUVsZW1lbnQoInAiKQpqLmFwcGVuZENoaWxkKGspCmsuYXBwZW5k
-Q2hpbGQobi5jcmVhdGVUZXh0Tm9kZShILkVqKG8pKyIgYXQgIikpCnE9dC5YCnE9Vy5KNihMLlE0KGEu
-ZSxQLkVGKFsibGluZSIsSi5qKGwpXSxxLHEpKSkKcS5hcHBlbmRDaGlsZChuLmNyZWF0ZVRleHROb2Rl
-KEguRWoobSkrIjoiK0guRWoobCkrIi4iKSkKay5hcHBlbmRDaGlsZChxKQpKLmRoKGspCkwuQ0MoYSxq
-LHApCkwuRnooYSxqKX0sCkxIOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyLHEscCxvLG4sbSxsLGssaixp
-LGgsZyxmLGU9JC55UCgpCkoubDUoZSwiIikKaWYoYi5nQShiKT09PTApe3M9ZG9jdW1lbnQKcj1zLmNy
-ZWF0ZUVsZW1lbnQoInAiKQplLmFwcGVuZENoaWxkKHIpCnIuYXBwZW5kQ2hpbGQocy5jcmVhdGVUZXh0
-Tm9kZSgiTm8gcHJvcG9zZWQgZWRpdHMiKSl9ZWxzZSBmb3IoZT1iLmdQdShiKSxlPWUuZ20oZSkscz10
-LlgscT10LmsscD1xLkMoIn4oMSk/Iiksbz10LloscT1xLmM7ZS5GKCk7KXtuPWUuZ2woKQptPWRvY3Vt
-ZW50CnI9bS5jcmVhdGVFbGVtZW50KCJwIikKbD0kLnlQKCkKbC5hcHBlbmRDaGlsZChyKQpyLmFwcGVu
-ZENoaWxkKG0uY3JlYXRlVGV4dE5vZGUoSC5FaihuLmEpKyI6IikpCms9bS5jcmVhdGVFbGVtZW50KCJ1
-bCIpCmwuYXBwZW5kQ2hpbGQoaykKZm9yKG49Si5JVChuLmIpO24uRigpOyl7bD1uLmdsKCkKaj1tLmNy
-ZWF0ZUVsZW1lbnQoImxpIikKay5hcHBlbmRDaGlsZChqKQpKLmRSKGopLmkoMCwiZWRpdCIpCmk9bS5j
-cmVhdGVFbGVtZW50KCJhIikKai5hcHBlbmRDaGlsZChpKQppLmNsYXNzTGlzdC5hZGQoImVkaXQtbGlu
-ayIpCmg9bC5jCmc9SC5FaihoKQppLnNldEF0dHJpYnV0ZSgiZGF0YS0iK25ldyBXLlN5KG5ldyBXLmk3
-KGkpKS5PVSgib2Zmc2V0IiksZykKZj1sLmEKZz1ILkVqKGYpCmkuc2V0QXR0cmlidXRlKCJkYXRhLSIr
-bmV3IFcuU3kobmV3IFcuaTcoaSkpLk9VKCJsaW5lIiksZykKaS5hcHBlbmRDaGlsZChtLmNyZWF0ZVRl
-eHROb2RlKCJsaW5lICIrSC5FaihmKSkpCmkuc2V0QXR0cmlidXRlKCJocmVmIixMLlE0KHdpbmRvdy5s
-b2NhdGlvbi5wYXRobmFtZSxQLkVGKFsibGluZSIsSC5FaihmKSwib2Zmc2V0IixILkVqKGgpXSxzLHMp
-KSkKZz1wLmEobmV3IEwuRUUoaCxmLGEpKQpvLmEobnVsbCkKVy5KRShpLCJjbGljayIsZywhMSxxKQpq
-LmFwcGVuZENoaWxkKG0uY3JlYXRlVGV4dE5vZGUoIjogIitILkVqKGwuYikpKX19aWYoYylMLlQxKG51
-bGwpfSwKRnI6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzLHIscT13aW5kb3cubG9jYXRpb24scD1QLmhLKChx
-JiZDLkV4KS5nRHIocSkrSC5FaihhKSkKcT10LlgKcT1QLkZsKHEscSkKaWYoYiE9bnVsbClxLlk1KDAs
-Im9mZnNldCIsSC5FaihiKSkKaWYoYyE9bnVsbClxLlk1KDAsImxpbmUiLEguRWooYykpCnEuWTUoMCwi
-YXV0aFRva2VuIiwkLlVFKCkpCnA9cC5ubSgwLHEpCnE9d2luZG93Lmhpc3RvcnkKcz10LnoKcj1wLmdu
-RCgpCnEudG9TdHJpbmcKcS5wdXNoU3RhdGUobmV3IFAuQmYoW10sW10pLlB2KFAuRmwocyxzKSksIiIs
-cil9LApFbjpmdW5jdGlvbihhKXt2YXIgcz1KLmJiKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoIi5yb290
-IikudGV4dENvbnRlbnQsIi8iKQppZihDLnhCLm4oYSxzKSlyZXR1cm4gQy54Qi55bihhLHMubGVuZ3Ro
-KQplbHNlIHJldHVybiBhfSwKT3Q6ZnVuY3Rpb24oYSl7c3dpdGNoKGEucil7Y2FzZSBDLmN3OmJyZWFr
-CmNhc2UgQy5XRDphLnI9Qy5YagpicmVhawpjYXNlIEMuWGo6YS5yPUMuV0QKYnJlYWsKY2FzZSBDLmRj
-OnRocm93IEguYihQLlBWKCJGaWxlICIrSC5FaihhLmMpKyIgc2hvdWxkIG5vdCBoYXZlIGluZGV0ZXJt
-aW5hdGUgbWlncmF0aW9uIHN0YXR1cyIpKX19LAp4bjpmdW5jdGlvbihhLGIpe3ZhciBzLHIscT0iZGlz
-YWJsZWQiLHA9Yi5nTCgpCkwudGEoYSxwKQppZihiLmM9PSQuRDkoKS5pbm5lclRleHQpe3M9YiBpbnN0
-YW5jZW9mIEwuY0QmJiFILm9UKGIueCkKcj1KLllFKGEpCmlmKHMpci5nUChhKS5pKDAscSkKZWxzZSBy
-LmdQKGEpLlIoMCxxKQpMLnRhKCQuYzAoKSxwKX19LAp0YTpmdW5jdGlvbihhLGIpe3ZhciBzLHI9ImNo
-ZWNrX2JveCIscT0idGl0bGUiLHA9Im9wdGVkLW91dCIsbz0ibWlncmF0aW5nIgpzd2l0Y2goYil7Y2Fz
-ZSBDLmN3OmEuaW5uZXJUZXh0PXIKcz1KLllFKGEpCnMuZ1AoYSkuaSgwLCJhbHJlYWR5LW1pZ3JhdGVk
-IikKcy5nUChhKS5pKDAsImRpc2FibGVkIikKYS5zZXRBdHRyaWJ1dGUocSwiQWxyZWFkeSBtaWdyYXRl
-ZCIpCmJyZWFrCmNhc2UgQy5XRDphLmlubmVyVGV4dD1yCnM9Si5ZRShhKQpzLmdQKGEpLlIoMCxwKQpz
-LmdQKGEpLmkoMCxvKQphLnNldEF0dHJpYnV0ZShxLCJNaWdyYXRpbmcgdG8gbnVsbCBzYWZldHkiKQpi
-cmVhawpjYXNlIEMuWGo6YS5pbm5lclRleHQ9ImNoZWNrX2JveF9vdXRsaW5lX2JsYW5rIgpzPUouWUUo
-YSkKcy5nUChhKS5SKDAsbykKcy5nUChhKS5pKDAscCkKYS5zZXRBdHRyaWJ1dGUocSwiT3B0aW5nIG91
-dCBvZiBudWxsIHNhZmV0eSIpCmJyZWFrCmRlZmF1bHQ6YS5pbm5lclRleHQ9ImluZGV0ZXJtaW5hdGVf
-Y2hlY2tfYm94IgpzPUouWUUoYSkKcy5nUChhKS5SKDAsbykKcy5nUChhKS5pKDAscCkKYS5zZXRBdHRy
-aWJ1dGUocSwiTWl4ZWQgc3RhdHVzZXMgb2YgJ21pZ3JhdGluZycgYW5kICdvcHRpbmcgb3V0JyIpCmJy
-ZWFrfX0sCkJYOmZ1bmN0aW9uKGEsYil7dmFyIHMscixxPXt9CnEuYT1hCmE9TC5FbihhKQpxLmE9YQpK
-LmRyKCQuRDkoKSxhKQpzPWRvY3VtZW50CkguRGgodC5nLHQuaCwiVCIsInF1ZXJ5U2VsZWN0b3JBbGwi
-KQpzPW5ldyBXLnd6KHMucXVlcnlTZWxlY3RvckFsbCgiLm5hdi1wYW5lbCAubmF2LWxpbmsiKSx0LlIp
-CnMuSyhzLG5ldyBMLlZTKHEpKQpzPSQuSVIKcj1zPT1udWxsP251bGw6TC5tSChzLHEuYSkKaWYocj09
-bnVsbClKLmRSKCQuYk4oKSkuUigwLCJ2aXNpYmxlIikKZWxzZXtKLmRSKCQuYk4oKSkuaSgwLCJ2aXNp
-YmxlIikKTC50YSgkLmMwKCksci5nTCgpKX19LApBUjpmdW5jdGlvbihhLGIpe3ZhciBzLHIscT1iLmIK
-aWYocSE9bnVsbCl7cz10LmcKcj1zLmEocy5hKGEucGFyZW50Tm9kZSkucGFyZW50Tm9kZSkKTC54bihy
-LnF1ZXJ5U2VsZWN0b3IoIjpzY29wZSA+IC5zdGF0dXMtaWNvbiIpLHEpCkwuQVIocixxKX19LApobDpm
-dW5jdGlvbihhLGIpe3ZhciBzLHIscSxwLG8sbixtPSI6c2NvcGUgPiAuc3RhdHVzLWljb24iCmZvcihz
-PWIuZCxyPXMubGVuZ3RoLHE9dC5nLHA9MDtwPHMubGVuZ3RoO3MubGVuZ3RoPT09cnx8KDAsSC5sayko
-cyksKytwKXtvPXNbcF0Kbj1hLnF1ZXJ5U2VsZWN0b3IoJ1tkYXRhLW5hbWUqPSInK0guRWooby5jKSsn
-Il0nKQppZihvIGluc3RhbmNlb2YgTC52dCl7TC5obChuLG8pCkwueG4obi5xdWVyeVNlbGVjdG9yKG0p
-LGIpfWVsc2UgTC54bihxLmEobi5wYXJlbnROb2RlKS5xdWVyeVNlbGVjdG9yKG0pLG8pfX0sCkJFOmZ1
-bmN0aW9uKGEsYixjKXt2YXIgcz0iLnJlZ2lvbnMiLHI9ZG9jdW1lbnQscT1yLnF1ZXJ5U2VsZWN0b3Io
-cykscD1yLnF1ZXJ5U2VsZWN0b3IoIi5jb2RlIikKSi50SChxLGIuYSwkLktHKCkpCkoudEgocCxiLmIs
-JC5LRygpKQpMLkxIKGEsYi5kLGMpCmlmKGIuYy5sZW5ndGg8MmU1KUwudlUoKQpMLnlYKCIuY29kZSIs
-ITApCkwueVgocywhMCl9LAp0WDpmdW5jdGlvbihhMSxhMixhMyl7dmFyIHMscixxLHAsbyxuLG0sbCxr
-LGosaSxoLGcsZixlLGQsYz0ibWF0ZXJpYWwtaWNvbnMiLGI9InN0YXR1cy1pY29uIixhPWRvY3VtZW50
-LGEwPWEuY3JlYXRlRWxlbWVudCgidWwiKQphMS5hcHBlbmRDaGlsZChhMCkKZm9yKHM9YTIubGVuZ3Ro
-LHI9dC5YLHE9dC5aLHA9MDtwPGEyLmxlbmd0aDthMi5sZW5ndGg9PT1zfHwoMCxILmxrKShhMiksKytw
-KXtvPWEyW3BdCm49YS5jcmVhdGVFbGVtZW50KCJsaSIpCmEwLmFwcGVuZENoaWxkKG4pCmlmKG8gaW5z
-dGFuY2VvZiBMLnZ0KXttPUouWUUobikKbS5nUChuKS5pKDAsImRpciIpCm4uc2V0QXR0cmlidXRlKCJk
-YXRhLSIrbmV3IFcuU3kobmV3IFcuaTcobikpLk9VKCJuYW1lIiksby5jKQpsPWEuY3JlYXRlRWxlbWVu
-dCgic3BhbiIpCm4uYXBwZW5kQ2hpbGQobCkKaz1KLllFKGwpCmsuZ1AobCkuaSgwLCJhcnJvdyIpCmsu
-c2hmKGwsIiYjeDI1QkM7IikKaj1hLmNyZWF0ZUVsZW1lbnQoInNwYW4iKQpKLmRSKGopLmkoMCxjKQpq
-LmlubmVyVGV4dD0iZm9sZGVyX29wZW4iCm4uYXBwZW5kQ2hpbGQoaikKbi5hcHBlbmRDaGlsZChhLmNy
-ZWF0ZVRleHROb2RlKG8uYSkpCkwudFgobixvLmQsITApCmk9YS5jcmVhdGVFbGVtZW50KCJzcGFuIikK
-az1KLllFKGkpCmsuZ1AoaSkuaSgwLGMpCmkuaW5uZXJUZXh0PSJpbmRldGVybWluYXRlX2NoZWNrX2Jv
-eCIKay5nUChpKS5pKDAsYikKTC54bihpLG8pCms9ay5nVmwoaSkKaD1rLiR0aQpnPWguQygifigxKT8i
-KS5hKG5ldyBMLlREKG8sbixpKSkKcS5hKG51bGwpClcuSkUoay5hLGsuYixnLCExLGguYykKbS5tSyhu
-LGksaikKTC5reihsKX1lbHNlIGlmKG8gaW5zdGFuY2VvZiBMLmNEKXtpPWEuY3JlYXRlRWxlbWVudCgi
-c3BhbiIpCm09Si5ZRShpKQptLmdQKGkpLmkoMCxjKQppLmlubmVyVGV4dD0iIgptLmdQKGkpLmkoMCxi
-KQprPUgub1Qoby54KQppZighayltLmdQKGkpLmkoMCwiZGlzYWJsZWQiKQpMLnhuKGksbykKaWYoayl7
-bT1tLmdWbChpKQprPW0uJHRpCmg9ay5DKCJ+KDEpPyIpLmEobmV3IEwuSWYobyxpLG4pKQpxLmEobnVs
-bCkKVy5KRShtLmEsbS5iLGgsITEsay5jKX1uLmFwcGVuZENoaWxkKGkpCm09YS5jcmVhdGVFbGVtZW50
-KCJzcGFuIikKSi5kUihtKS5pKDAsYykKbS5pbm5lclRleHQ9Imluc2VydF9kcml2ZV9maWxlIgpuLmFw
-cGVuZENoaWxkKG0pCmY9YS5jcmVhdGVFbGVtZW50KCJhIikKbi5hcHBlbmRDaGlsZChmKQptPUouWUUo
-ZikKbS5nUChmKS5pKDAsIm5hdi1saW5rIikKZi5zZXRBdHRyaWJ1dGUoImRhdGEtIituZXcgVy5TeShu
-ZXcgVy5pNyhmKSkuT1UoIm5hbWUiKSxvLmMpCmYuc2V0QXR0cmlidXRlKCJocmVmIixMLlE0KG8uZCxQ
-LkZsKHIscikpKQpmLmFwcGVuZENoaWxkKGEuY3JlYXRlVGV4dE5vZGUoby5hKSkKbT1tLmdWbChmKQpr
-PW0uJHRpCmg9ay5DKCJ+KDEpPyIpLmEobmV3IEwudEIoKSkKcS5hKG51bGwpClcuSkUobS5hLG0uYixo
-LCExLGsuYykKZT1vLmUKaWYodHlwZW9mIGUhPT0ibnVtYmVyIilyZXR1cm4gZS5vcygpCmlmKGU+MCl7
-ZD1hLmNyZWF0ZUVsZW1lbnQoInNwYW4iKQpuLmFwcGVuZENoaWxkKGQpCkouZFIoZCkuaSgwLCJlZGl0
-LWNvdW50IikKbT0iIitlKyIgIgppZihlPT09MSlrPSJwcm9wb3NlZCBlZGl0IgplbHNlIGs9InByb3Bv
-c2VkIGVkaXRzIgpkLnNldEF0dHJpYnV0ZSgidGl0bGUiLG0raykKZC5hcHBlbmRDaGlsZChhLmNyZWF0
-ZVRleHROb2RlKEMuam4udyhlKSkpfX19fSwKdXo6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzPWRvY3VtZW50
-LHI9cy5jcmVhdGVFbGVtZW50KCJidXR0b24iKSxxPXQuayxwPXEuQygifigxKT8iKS5hKG5ldyBMLm0y
-KGEsYykpCnQuWi5hKG51bGwpClcuSkUociwiY2xpY2siLHAsITEscS5jKQpyLmFwcGVuZENoaWxkKHMu
-Y3JlYXRlVGV4dE5vZGUoUi5PWChhLmEpKSkKYi5hcHBlbmRDaGlsZChyKX0sCkZ6OmZ1bmN0aW9uKGEs
-Yil7dmFyIHMscixxLHAsbyxuLG0sbCxrLGosaSxoPWEuYQppZihoPT1udWxsKXJldHVybgpzPWRvY3Vt
-ZW50CnI9cy5jcmVhdGVFbGVtZW50KCJwIikKcT1iLmFwcGVuZENoaWxkKHIpCnI9cy5jcmVhdGVFbGVt
-ZW50KCJzcGFuIikKcD10LmkKSi5NdShyLEguVk0oWyJ0eXBlLWRlc2NyaXB0aW9uIl0scCkpCnIuYXBw
-ZW5kQ2hpbGQocy5jcmVhdGVUZXh0Tm9kZSgiQWN0aW9ucyIpKQpxLmFwcGVuZENoaWxkKHIpCnEuYXBw
-ZW5kQ2hpbGQocy5jcmVhdGVUZXh0Tm9kZSgiOiIpKQpvPXMuY3JlYXRlRWxlbWVudCgicCIpCmIuYXBw
-ZW5kQ2hpbGQobykKZm9yKHI9aC5sZW5ndGgsbj10LlEsbT0wO208aC5sZW5ndGg7aC5sZW5ndGg9PT1y
-fHwoMCxILmxrKShoKSwrK20pe2w9aFttXQprPXMuY3JlYXRlRWxlbWVudCgiYSIpCm8uYXBwZW5kQ2hp
-bGQoaykKay5hcHBlbmRDaGlsZChzLmNyZWF0ZVRleHROb2RlKGwuYSkpCmsuc2V0QXR0cmlidXRlKCJo
-cmVmIixsLmIpCmo9bi5hKEguVk0oWyJhZGQtaGludC1saW5rIiwiYmVmb3JlLWFwcGx5IiwiYnV0dG9u
-Il0scCkpCmk9Si5kUihrKQppLlYxKDApCmkuRlYoMCxqKX19LApDQzpmdW5jdGlvbihhNCxhNSxhNil7
-dmFyIHMscixxLHAsbyxuLG0sbCxrLGosaSxoLGcsZixlLGQsYyxiLGEsYTAsYTEsYTIsYTMKZm9yKHM9
-YTQuZixyPXMubGVuZ3RoLHE9dC5pLHA9dC5RLG89MDtvPHMubGVuZ3RoO3MubGVuZ3RoPT09cnx8KDAs
-SC5saykocyksKytvKXtuPXNbb10KbT1kb2N1bWVudApsPW0uY3JlYXRlRWxlbWVudCgicCIpCms9cC5h
-KEguVk0oWyJ0cmFjZSJdLHEpKQpqPUouZFIobCkKai5WMSgwKQpqLkZWKDAsaykKaT1hNS5hcHBlbmRD
-aGlsZChsKQpsPW0uY3JlYXRlRWxlbWVudCgic3BhbiIpCms9cC5hKEguVk0oWyJ0eXBlLWRlc2NyaXB0
-aW9uIl0scSkpCmo9Si5kUihsKQpqLlYxKDApCmouRlYoMCxrKQpsLmFwcGVuZENoaWxkKG0uY3JlYXRl
-VGV4dE5vZGUobi5hKSkKaS5hcHBlbmRDaGlsZChsKQppLmFwcGVuZENoaWxkKG0uY3JlYXRlVGV4dE5v
-ZGUoIjoiKSkKbD1tLmNyZWF0ZUVsZW1lbnQoInVsIikKaz1wLmEoSC5WTShbInRyYWNlIl0scSkpCmo9
-Si5kUihsKQpqLlYxKDApCmouRlYoMCxrKQpoPWkuYXBwZW5kQ2hpbGQobCkKZm9yKGw9bi5iLGs9bC5s
-ZW5ndGgsZz0wO2c8bC5sZW5ndGg7bC5sZW5ndGg9PT1rfHwoMCxILmxrKShsKSwrK2cpe2Y9bFtnXQpl
-PW0uY3JlYXRlRWxlbWVudCgibGkiKQpoLmFwcGVuZENoaWxkKGUpCmQ9bS5jcmVhdGVFbGVtZW50KCJz
-cGFuIikKYz1wLmEoSC5WTShbImZ1bmN0aW9uIl0scSkpCmo9Si5kUihkKQpqLlYxKDApCmouRlYoMCxj
-KQpjPWYuYgpMLmtEKGQsYz09bnVsbD8idW5rbm93biI6YykKZS5hcHBlbmRDaGlsZChkKQpiPWYuYwpp
-ZihiIT1udWxsKXtlLmFwcGVuZENoaWxkKG0uY3JlYXRlVGV4dE5vZGUoIiAoIikpCmE9Yi5iCmEwPW0u
-Y3JlYXRlRWxlbWVudCgiYSIpCmEwLmFwcGVuZENoaWxkKG0uY3JlYXRlVGV4dE5vZGUoSC5FaihiLmMp
-KyI6IitILkVqKGEpKSkKYTAuc2V0QXR0cmlidXRlKCJocmVmIixiLmEpCmEwLmNsYXNzTGlzdC5hZGQo
-Im5hdi1saW5rIikKZS5hcHBlbmRDaGlsZChhMCkKZS5hcHBlbmRDaGlsZChtLmNyZWF0ZVRleHROb2Rl
-KCIpIikpfWUuYXBwZW5kQ2hpbGQobS5jcmVhdGVUZXh0Tm9kZSgiOiAiKSkKZD1mLmEKTC5rRChlLGQ9
-PW51bGw/InVua25vd24iOmQpCmQ9Zi5kCmlmKGQubGVuZ3RoIT09MCl7Yz1tLmNyZWF0ZUVsZW1lbnQo
-InAiKQphMT1wLmEoSC5WTShbImRyYXdlciIsImJlZm9yZS1hcHBseSJdLHEpKQpqPUouZFIoYykKai5W
-MSgwKQpqLkZWKDAsYTEpCmEyPWUuYXBwZW5kQ2hpbGQoYykKZm9yKGM9ZC5sZW5ndGgsYTM9MDthMzxk
-Lmxlbmd0aDtkLmxlbmd0aD09PWN8fCgwLEgubGspKGQpLCsrYTMpTC51eihkW2EzXSxhMixiKX19fX0s
-ClVzOmZ1bmN0aW9uKGEpe3JldHVybiBKLlU2KGEpLnRnKGEsIj8iKT9DLnhCLk5qKGEsMCxDLnhCLk9Z
-KGEsIj8iKSk6YX0sCmtEOmZ1bmN0aW9uKGEsYil7dmFyIHMscixxPUguVk0oYi5zcGxpdCgiLiIpLHQu
-cykscD1DLk5tLmd0SChxKSxvPWRvY3VtZW50CmEuYXBwZW5kQ2hpbGQoby5jcmVhdGVUZXh0Tm9kZShw
-KSkKZm9yKHA9SC5xQyhxLDEsbnVsbCx0Lk4pLHA9bmV3IEguYTcocCxwLmdBKHApLHAuJHRpLkMoImE3
-PGFMLkU+IikpLHM9Si5ZRShhKTtwLkYoKTspe3I9cC5kCnMubnooYSwiYmVmb3JlZW5kIiwiJiM4MjAz
-Oy4iLG51bGwsbnVsbCkKYS5hcHBlbmRDaGlsZChvLmNyZWF0ZVRleHROb2RlKHIpKX19LAptSDpmdW5j
-dGlvbihhLGIpe3ZhciBzLHIscSxwCmZvcihzPWEubGVuZ3RoLHI9MDtyPGEubGVuZ3RoO2EubGVuZ3Ro
-PT09c3x8KDAsSC5saykoYSksKytyKXtxPWFbcl0KaWYocSBpbnN0YW5jZW9mIEwudnQpe3A9TC5tSChx
-LmQsYikKaWYocCE9bnVsbClyZXR1cm4gcH1lbHNlIGlmKHEuYz09YilyZXR1cm4gcX1yZXR1cm4gbnVs
-bH0sCmU6ZnVuY3Rpb24gZSgpe30sClZXOmZ1bmN0aW9uIFZXKGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9
-Ygp0aGlzLmM9Y30sCm9aOmZ1bmN0aW9uIG9aKCl7fSwKanI6ZnVuY3Rpb24ganIoKXt9LApxbDpmdW5j
-dGlvbiBxbCgpe30sCkhpOmZ1bmN0aW9uIEhpKCl7fSwKQlQ6ZnVuY3Rpb24gQlQoKXt9LApQWTpmdW5j
-dGlvbiBQWSgpe30sCnU4OmZ1bmN0aW9uIHU4KCl7fSwKTDpmdW5jdGlvbiBMKCl7fSwKV3g6ZnVuY3Rp
-b24gV3goYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCkFPOmZ1bmN0aW9uIEFPKGEpe3RoaXMuYT1hfSwK
-ZE46ZnVuY3Rpb24gZE4oYSl7dGhpcy5hPWF9LApIbzpmdW5jdGlvbiBIbyhhKXt0aGlzLmE9YX0sCnh6
-OmZ1bmN0aW9uIHh6KGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApJQzpmdW5jdGlvbiBJQygpe30sCmZD
-OmZ1bmN0aW9uIGZDKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApuVDpmdW5jdGlvbiBuVChhLGIsYyl7
-dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LApOWTpmdW5jdGlvbiBOWShhKXt0aGlzLmE9YX0sCnVl
-OmZ1bmN0aW9uIHVlKCl7fSwKZVg6ZnVuY3Rpb24gZVgoKXt9LApFRTpmdW5jdGlvbiBFRShhLGIsYyl7
-dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LApRTDpmdW5jdGlvbiBRTChhLGIpe3RoaXMuYT1hCnRo
-aXMuYj1ifSwKVlM6ZnVuY3Rpb24gVlMoYSl7dGhpcy5hPWF9LApURDpmdW5jdGlvbiBURChhLGIsYyl7
-dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LApJZjpmdW5jdGlvbiBJZihhLGIsYyl7dGhpcy5hPWEK
-dGhpcy5iPWIKdGhpcy5jPWN9LAp0QjpmdW5jdGlvbiB0Qigpe30sCm0yOmZ1bmN0aW9uIG0yKGEsYil7
-dGhpcy5hPWEKdGhpcy5iPWJ9LApYQTpmdW5jdGlvbiBYQSgpe30sClpzOmZ1bmN0aW9uKGEpe3ZhciBz
-LHIscT1KLlU2KGEpCmlmKEwucDIoSC5oKHEucShhLCJ0eXBlIikpKT09PUMuWTIpe3M9SC5oKHEucShh
-LCJuYW1lIikpCnI9SC5oKHEucShhLCJwYXRoIikpCnE9cS5xKGEsInN1YnRyZWUiKQpxPW5ldyBMLnZ0
-KHE9PW51bGw/bnVsbDpMLm1LKHEpLHMscikKcS5MVigpCnJldHVybiBxfWVsc2V7cz1ILmgocS5xKGEs
-Im5hbWUiKSkKcj1ILmgocS5xKGEsInBhdGgiKSkKcmV0dXJuIG5ldyBMLmNEKEguaChxLnEoYSwiaHJl
-ZiIpKSxILnVQKHEucShhLCJlZGl0Q291bnQiKSksSC55OChxLnEoYSwid2FzRXhwbGljaXRseU9wdGVk
-T3V0IikpLEwudkIoSC51UChxLnEoYSwibWlncmF0aW9uU3RhdHVzIikpKSxILnk4KHEucShhLCJtaWdy
-YXRpb25TdGF0dXNDYW5CZUNoYW5nZWQiKSkscyxyKX19LAptSzpmdW5jdGlvbihhKXt2YXIgcyxyPUgu
-Vk0oW10sdC5jUSkKZm9yKHM9Si5JVCh0LlUuYShhKSk7cy5GKCk7KXIucHVzaChMLlpzKHMuZ2woKSkp
-CnJldHVybiByfSwKVkQ6ZnVuY3Rpb24oYSl7dmFyIHMscixxPUguVk0oW10sdC5HKQpmb3Iocz1hLmxl
-bmd0aCxyPTA7cjxhLmxlbmd0aDthLmxlbmd0aD09PXN8fCgwLEgubGspKGEpLCsrcilxLnB1c2goYVty
-XS5MdCgpKQpyZXR1cm4gcX0sCnZCOmZ1bmN0aW9uKGEpe2lmKGE9PW51bGwpcmV0dXJuIG51bGwKaWYo
-YT4+PjAhPT1hfHxhPj00KXJldHVybiBILk9IKEMubDAsYSkKcmV0dXJuIEMubDBbYV19LApwMjpmdW5j
-dGlvbihhKXtzd2l0Y2goYSl7Y2FzZSJkaXJlY3RvcnkiOnJldHVybiBDLlkyCmNhc2UiZmlsZSI6cmV0
-dXJuIEMucmYKZGVmYXVsdDp0aHJvdyBILmIoUC5QVigiVW5yZWNvZ25pemVkIG5hdmlnYXRpb24gdHJl
-ZSBub2RlIHR5cGU6ICIrSC5FaihhKSkpfX0sCnZ0OmZ1bmN0aW9uIHZ0KGEsYixjKXt2YXIgXz10aGlz
-Cl8uZD1hCl8uYT1iCl8uYj1udWxsCl8uYz1jfSwKY0Q6ZnVuY3Rpb24gY0QoYSxiLGMsZCxlLGYsZyl7
-dmFyIF89dGhpcwpfLmQ9YQpfLmU9YgpfLmY9YwpfLnI9ZApfLng9ZQpfLmE9ZgpfLmI9bnVsbApfLmM9
-Z30sCkQ4OmZ1bmN0aW9uIEQ4KCl7fSwKTzk6ZnVuY3Rpb24gTzkoYSl7dGhpcy5iPWF9LApHYjpmdW5j
-dGlvbiBHYihhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKSVY6ZnVuY3Rpb24gSVYoYSxiLGMsZCl7dmFy
-IF89dGhpcwpfLmQ9YQpfLmU9YgpfLmY9YwpfLnI9ZH19LFI9ewpuejpmdW5jdGlvbihhKXt2YXIgcz1I
-LnVQKGEucSgwLCJub2RlSWQiKSkKcmV0dXJuIG5ldyBSLkxMKEMuTm0uSHQoQy5yayxuZXcgUi5NRChh
-KSkscyl9LApPWDpmdW5jdGlvbihhKXtzd2l0Y2goYSl7Y2FzZSBDLkFkOnJldHVybiJBZGQgLyo/Ki8g
-aGludCIKY2FzZSBDLm5lOnJldHVybiJBZGQgLyohKi8gaGludCIKY2FzZSBDLndWOnJldHVybiJSZW1v
-dmUgLyo/Ki8gaGludCIKY2FzZSBDLmZSOnJldHVybiJSZW1vdmUgLyohKi8gaGludCIKY2FzZSBDLm15
-OnJldHVybiJDaGFuZ2UgdG8gLyo/Ki8gaGludCIKY2FzZSBDLnJ4OnJldHVybiJDaGFuZ2UgdG8gLyoh
-Ki8gaGludCJ9cmV0dXJuIG51bGx9LApMTDpmdW5jdGlvbiBMTChhLGIpe3RoaXMuYT1hCnRoaXMuYj1i
-fSwKTUQ6ZnVuY3Rpb24gTUQoYSl7dGhpcy5hPWF9LApINzpmdW5jdGlvbiBINyhhLGIpe3RoaXMuYT1h
-CnRoaXMuYj1ifX0sTT17CllGOmZ1bmN0aW9uKGEsYil7dmFyIHMscixxLHAsbyxuLG0sbApmb3Iocz1i
-Lmxlbmd0aCxyPTE7cjxzOysrcil7aWYoYltyXT09bnVsbHx8YltyLTFdIT1udWxsKWNvbnRpbnVlCmZv
-cig7cz49MTtzPXEpe3E9cy0xCmlmKGJbcV0hPW51bGwpYnJlYWt9cD1uZXcgUC5SbigiIikKbz1hKyIo
-IgpwLmE9bwpuPUgudDYoYikKbT1uLkMoIm5IPDE+IikKbD1uZXcgSC5uSChiLDAscyxtKQpsLkhkKGIs
-MCxzLG4uYykKbT1vK25ldyBILmxKKGwsbS5DKCJxVShhTC5FKSIpLmEobmV3IE0uTm8oKSksbS5DKCJs
-SjxhTC5FLHFVPiIpKS5rKDAsIiwgIikKcC5hPW0KcC5hPW0rKCIpOiBwYXJ0ICIrKHItMSkrIiB3YXMg
-bnVsbCwgYnV0IHBhcnQgIityKyIgd2FzIG5vdC4iKQp0aHJvdyBILmIoUC54WShwLncoMCkpKX19LAps
-STpmdW5jdGlvbiBsSShhKXt0aGlzLmE9YX0sCnE3OmZ1bmN0aW9uIHE3KCl7fSwKTm86ZnVuY3Rpb24g
-Tm8oKXt9fSxYPXsKQ0w6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEscCxvLG49Yi54WihhKQpiLmhLKGEp
-CmlmKG4hPW51bGwpYT1KLktWKGEsbi5sZW5ndGgpCnM9dC5zCnI9SC5WTShbXSxzKQpxPUguVk0oW10s
-cykKcz1hLmxlbmd0aAppZihzIT09MCYmYi5yNChDLnhCLlcoYSwwKSkpe2lmKDA+PXMpcmV0dXJuIEgu
-T0goYSwwKQpDLk5tLmkocSxhWzBdKQpwPTF9ZWxzZXtDLk5tLmkocSwiIikKcD0wfWZvcihvPXA7bzxz
-OysrbylpZihiLnI0KEMueEIuVyhhLG8pKSl7Qy5ObS5pKHIsQy54Qi5OaihhLHAsbykpCkMuTm0uaShx
-LGFbb10pCnA9bysxfWlmKHA8cyl7Qy5ObS5pKHIsQy54Qi55bihhLHApKQpDLk5tLmkocSwiIil9cmV0
-dXJuIG5ldyBYLldEKGIsbixyLHEpfSwKV0Q6ZnVuY3Rpb24gV0QoYSxiLGMsZCl7dmFyIF89dGhpcwpf
-LmE9YQpfLmI9YgpfLmQ9YwpfLmU9ZH0sCkk3OmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgWC5kdihhKX0s
-CmR2OmZ1bmN0aW9uIGR2KGEpe3RoaXMuYT1hfX0sTz17ClJoOmZ1bmN0aW9uKCl7dmFyIHMscj1udWxs
-CmlmKFAudW8oKS5nRmkoKSE9PSJmaWxlIilyZXR1cm4gJC5FYigpCnM9UC51bygpCmlmKCFDLnhCLlRj
-KHMuZ0lpKHMpLCIvIikpcmV0dXJuICQuRWIoKQppZihQLktMKHIsImEvYiIscixyLHIscixyKS50NCgp
-PT09ImFcXGIiKXJldHVybiAkLktrKCkKcmV0dXJuICQuYkQoKX0sCnpMOmZ1bmN0aW9uIHpMKCl7fX0s
-RT17T0Y6ZnVuY3Rpb24gT0YoYSxiLGMpe3RoaXMuZD1hCnRoaXMuZT1iCnRoaXMuZj1jfX0sRj17cnU6
-ZnVuY3Rpb24gcnUoYSxiLGMsZCl7dmFyIF89dGhpcwpfLmQ9YQpfLmU9YgpfLmY9YwpfLnI9ZH19LEQ9
-ewphYjpmdW5jdGlvbigpe3ZhciBzLHIscSxwLG89bnVsbAp0cnl7bz1QLnVvKCl9Y2F0Y2gocyl7aWYo
-dC5nOC5iKEguUnUocykpKXtyPSQuRmYKaWYociE9bnVsbClyZXR1cm4gcgp0aHJvdyBzfWVsc2UgdGhy
-b3cgc31pZihKLlJNKG8sJC5JNikpe3I9JC5GZgpyLnRvU3RyaW5nCnJldHVybiByfSQuSTY9bwppZigk
-LkhrKCk9PSQuRWIoKSlyPSQuRmY9by5aSSgiLiIpLncoMCkKZWxzZXtxPW8udDQoKQpwPXEubGVuZ3Ro
-LTEKcj0kLkZmPXA9PT0wP3E6Qy54Qi5OaihxLDAscCl9ci50b1N0cmluZwpyZXR1cm4gcn19CnZhciB3
-PVtDLEgsSixQLFcsVSxCLFQsTCxSLE0sWCxPLEUsRixEXQpodW5rSGVscGVycy5zZXRGdW5jdGlvbk5h
-bWVzSWZOZWNlc3NhcnkodykKdmFyICQ9e30KSC5GSy5wcm90b3R5cGU9e30KSi5Hdi5wcm90b3R5cGU9
-ewpETjpmdW5jdGlvbihhLGIpe3JldHVybiBhPT09Yn0sCmdpTzpmdW5jdGlvbihhKXtyZXR1cm4gSC5l
-UShhKX0sCnc6ZnVuY3Rpb24oYSl7cmV0dXJuIkluc3RhbmNlIG9mICciK0guRWooSC5NKGEpKSsiJyJ9
-LAplNzpmdW5jdGlvbihhLGIpe3Quby5hKGIpCnRocm93IEguYihQLmxyKGEsYi5nV2EoKSxiLmduZCgp
-LGIuZ1ZtKCkpKX19CkoueUUucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4gU3RyaW5nKGEp
-fSwKZ2lPOmZ1bmN0aW9uKGEpe3JldHVybiBhPzUxOTAxODoyMTgxNTl9LAokaWEyOjF9Ckoud2UucHJv
-dG90eXBlPXsKRE46ZnVuY3Rpb24oYSxiKXtyZXR1cm4gbnVsbD09Yn0sCnc6ZnVuY3Rpb24oYSl7cmV0
-dXJuIm51bGwifSwKZ2lPOmZ1bmN0aW9uKGEpe3JldHVybiAwfSwKZTc6ZnVuY3Rpb24oYSxiKXtyZXR1
-cm4gdGhpcy5TaihhLHQuby5hKGIpKX0sCiRpYzg6MX0KSi5NRi5wcm90b3R5cGU9ewpnaU86ZnVuY3Rp
-b24oYSl7cmV0dXJuIDB9LAp3OmZ1bmN0aW9uKGEpe3JldHVybiBTdHJpbmcoYSl9LAokaXZtOjF9Ckou
-aUMucHJvdG90eXBlPXt9Ckoua2QucHJvdG90eXBlPXt9CkouYzUucHJvdG90eXBlPXsKdzpmdW5jdGlv
-bihhKXt2YXIgcz1hWyQudygpXQppZihzPT1udWxsKXJldHVybiB0aGlzLnQoYSkKcmV0dXJuIkphdmFT
-Y3JpcHQgZnVuY3Rpb24gZm9yICIrSC5FaihKLmoocykpfSwKJGlFSDoxfQpKLmpkLnByb3RvdHlwZT17
-CmRyOmZ1bmN0aW9uKGEsYil7cmV0dXJuIG5ldyBILmpWKGEsSC50NihhKS5DKCJAPDE+IikuS3EoYiku
-QygialY8MSwyPiIpKX0sCmk6ZnVuY3Rpb24oYSxiKXtILnQ2KGEpLmMuYShiKQppZighIWEuZml4ZWQk
-bGVuZ3RoKUgudihQLkw0KCJhZGQiKSkKYS5wdXNoKGIpfSwKVzQ6ZnVuY3Rpb24oYSxiKXt2YXIgcwpp
-ZighIWEuZml4ZWQkbGVuZ3RoKUgudihQLkw0KCJyZW1vdmVBdCIpKQpzPWEubGVuZ3RoCmlmKGI+PXMp
-dGhyb3cgSC5iKFAuTzcoYixudWxsKSkKcmV0dXJuIGEuc3BsaWNlKGIsMSlbMF19LApVRzpmdW5jdGlv
-bihhLGIsYyl7dmFyIHMscgpILnQ2KGEpLkMoImNYPDE+IikuYShjKQppZighIWEuZml4ZWQkbGVuZ3Ro
-KUgudihQLkw0KCJpbnNlcnRBbGwiKSkKUC53QShiLDAsYS5sZW5ndGgsImluZGV4IikKaWYoIXQuZC5i
-KGMpKWM9Si5SWChjKQpzPUouSG0oYykKYS5sZW5ndGg9YS5sZW5ndGgrcwpyPWIrcwp0aGlzLllXKGEs
-cixhLmxlbmd0aCxhLGIpCnRoaXMudmcoYSxiLHIsYyl9LApGVjpmdW5jdGlvbihhLGIpe3ZhciBzCkgu
-dDYoYSkuQygiY1g8MT4iKS5hKGIpCmlmKCEhYS5maXhlZCRsZW5ndGgpSC52KFAuTDQoImFkZEFsbCIp
-KQppZihBcnJheS5pc0FycmF5KGIpKXt0aGlzLktoKGEsYikKcmV0dXJufWZvcihzPUouSVQoYik7cy5G
-KCk7KWEucHVzaChzLmdsKCkpfSwKS2g6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyCnQuYi5hKGIpCnM9Yi5s
-ZW5ndGgKaWYocz09PTApcmV0dXJuCmlmKGE9PT1iKXRocm93IEguYihQLmE0KGEpKQpmb3Iocj0wO3I8
-czsrK3IpYS5wdXNoKGJbcl0pfSwKRTI6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzPUgudDYoYSkKcmV0dXJu
-IG5ldyBILmxKKGEscy5LcShjKS5DKCIxKDIpIikuYShiKSxzLkMoIkA8MT4iKS5LcShjKS5DKCJsSjwx
-LDI+IikpfSwKazpmdW5jdGlvbihhLGIpe3ZhciBzLHI9UC5POChhLmxlbmd0aCwiIiwhMSx0Lk4pCmZv
-cihzPTA7czxhLmxlbmd0aDsrK3MpdGhpcy5ZNShyLHMsSC5FaihhW3NdKSkKcmV0dXJuIHIuam9pbihi
-KX0sCmVSOmZ1bmN0aW9uKGEsYil7cmV0dXJuIEgucUMoYSxiLG51bGwsSC50NihhKS5jKX0sCk4wOmZ1
-bmN0aW9uKGEsYixjLGQpe3ZhciBzLHIscQpkLmEoYikKSC50NihhKS5LcShkKS5DKCIxKDEsMikiKS5h
-KGMpCnM9YS5sZW5ndGgKZm9yKHI9YixxPTA7cTxzOysrcSl7cj1jLiQyKHIsYVtxXSkKaWYoYS5sZW5n
-dGghPT1zKXRocm93IEguYihQLmE0KGEpKX1yZXR1cm4gcn0sCkh0OmZ1bmN0aW9uKGEsYil7dmFyIHMs
-cixxLHAsbwpILnQ2KGEpLkMoImEyKDEpIikuYShiKQpzPWEubGVuZ3RoCmZvcihyPW51bGwscT0hMSxw
-PTA7cDxzOysrcCl7bz1hW3BdCmlmKEgub1QoYi4kMShvKSkpe2lmKHEpdGhyb3cgSC5iKEguQW0oKSkK
-cj1vCnE9ITB9aWYocyE9PWEubGVuZ3RoKXRocm93IEguYihQLmE0KGEpKX1pZihxKXJldHVybiByCnRo
-cm93IEguYihILldwKCkpfSwKRTpmdW5jdGlvbihhLGIpe2lmKGI8MHx8Yj49YS5sZW5ndGgpcmV0dXJu
-IEguT0goYSxiKQpyZXR1cm4gYVtiXX0sCmd0SDpmdW5jdGlvbihhKXtpZihhLmxlbmd0aD4wKXJldHVy
-biBhWzBdCnRocm93IEguYihILldwKCkpfSwKZ3JaOmZ1bmN0aW9uKGEpe3ZhciBzPWEubGVuZ3RoCmlm
-KHM+MClyZXR1cm4gYVtzLTFdCnRocm93IEguYihILldwKCkpfSwKWVc6ZnVuY3Rpb24oYSxiLGMsZCxl
-KXt2YXIgcyxyLHEscCxvCkgudDYoYSkuQygiY1g8MT4iKS5hKGQpCmlmKCEhYS5pbW11dGFibGUkbGlz
-dClILnYoUC5MNCgic2V0UmFuZ2UiKSkKUC5qQihiLGMsYS5sZW5ndGgpCnM9Yy1iCmlmKHM9PT0wKXJl
-dHVybgpQLmsxKGUsInNraXBDb3VudCIpCmlmKHQuai5iKGQpKXtyPWQKcT1lfWVsc2V7cj1KLkE1KGQs
-ZSkudHQoMCwhMSkKcT0wfXA9Si5VNihyKQppZihxK3M+cC5nQShyKSl0aHJvdyBILmIoSC5hcigpKQpp
-ZihxPGIpZm9yKG89cy0xO28+PTA7LS1vKWFbYitvXT1wLnEocixxK28pCmVsc2UgZm9yKG89MDtvPHM7
-KytvKWFbYitvXT1wLnEocixxK28pfSwKdmc6ZnVuY3Rpb24oYSxiLGMsZCl7cmV0dXJuIHRoaXMuWVco
-YSxiLGMsZCwwKX0sClZyOmZ1bmN0aW9uKGEsYil7dmFyIHMscgpILnQ2KGEpLkMoImEyKDEpIikuYShi
-KQpzPWEubGVuZ3RoCmZvcihyPTA7cjxzOysrcil7aWYoSC5vVChiLiQxKGFbcl0pKSlyZXR1cm4hMApp
-ZihhLmxlbmd0aCE9PXMpdGhyb3cgSC5iKFAuYTQoYSkpfXJldHVybiExfSwKdGc6ZnVuY3Rpb24oYSxi
-KXt2YXIgcwpmb3Iocz0wO3M8YS5sZW5ndGg7KytzKWlmKEouUk0oYVtzXSxiKSlyZXR1cm4hMApyZXR1
-cm4hMX0sCmdsMDpmdW5jdGlvbihhKXtyZXR1cm4gYS5sZW5ndGg9PT0wfSwKZ29yOmZ1bmN0aW9uKGEp
-e3JldHVybiBhLmxlbmd0aCE9PTB9LAp3OmZ1bmN0aW9uKGEpe3JldHVybiBQLldFKGEsIlsiLCJdIil9
-LAp0dDpmdW5jdGlvbihhLGIpe3ZhciBzPUguVk0oYS5zbGljZSgwKSxILnQ2KGEpKQpyZXR1cm4gc30s
-CmJyOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLnR0KGEsITApfSwKZ206ZnVuY3Rpb24oYSl7cmV0dXJu
-IG5ldyBKLm0xKGEsYS5sZW5ndGgsSC50NihhKS5DKCJtMTwxPiIpKX0sCmdpTzpmdW5jdGlvbihhKXty
-ZXR1cm4gSC5lUShhKX0sCmdBOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxlbmd0aH0sCnNBOmZ1bmN0aW9u
-KGEsYil7aWYoISFhLmZpeGVkJGxlbmd0aClILnYoUC5MNCgic2V0IGxlbmd0aCIpKQppZihiPDApdGhy
-b3cgSC5iKFAuVEUoYiwwLG51bGwsIm5ld0xlbmd0aCIsbnVsbCkpCmEubGVuZ3RoPWJ9LApxOmZ1bmN0
-aW9uKGEsYil7SC51UChiKQppZihiPj1hLmxlbmd0aHx8YjwwKXRocm93IEguYihILkhZKGEsYikpCnJl
-dHVybiBhW2JdfSwKWTU6ZnVuY3Rpb24oYSxiLGMpe0gudDYoYSkuYy5hKGMpCmlmKCEhYS5pbW11dGFi
-bGUkbGlzdClILnYoUC5MNCgiaW5kZXhlZCBzZXQiKSkKaWYoYj49YS5sZW5ndGh8fGI8MCl0aHJvdyBI
-LmIoSC5IWShhLGIpKQphW2JdPWN9LAokaWJROjEsCiRpY1g6MSwKJGl6TToxfQpKLlBvLnByb3RvdHlw
-ZT17fQpKLm0xLnByb3RvdHlwZT17CmdsOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuZH0sCkY6ZnVuY3Rp
-b24oKXt2YXIgcyxyPXRoaXMscT1yLmEscD1xLmxlbmd0aAppZihyLmIhPT1wKXRocm93IEguYihILmxr
-KHEpKQpzPXIuYwppZihzPj1wKXtyLnNNKG51bGwpCnJldHVybiExfXIuc00ocVtzXSk7KytyLmMKcmV0
-dXJuITB9LApzTTpmdW5jdGlvbihhKXt0aGlzLmQ9dGhpcy4kdGkuQygiMT8iKS5hKGEpfSwKJGlBbjox
-fQpKLnFJLnByb3RvdHlwZT17CnpROmZ1bmN0aW9uKGEpe2lmKGE+MCl7aWYoYSE9PTEvMClyZXR1cm4g
-TWF0aC5yb3VuZChhKX1lbHNlIGlmKGE+LTEvMClyZXR1cm4gMC1NYXRoLnJvdW5kKDAtYSkKdGhyb3cg
-SC5iKFAuTDQoIiIrYSsiLnJvdW5kKCkiKSl9LAp3OmZ1bmN0aW9uKGEpe2lmKGE9PT0wJiYxL2E8MCly
-ZXR1cm4iLTAuMCIKZWxzZSByZXR1cm4iIithfSwKZ2lPOmZ1bmN0aW9uKGEpe3ZhciBzLHIscSxwLG89
-YXwwCmlmKGE9PT1vKXJldHVybiBvJjUzNjg3MDkxMQpzPU1hdGguYWJzKGEpCnI9TWF0aC5sb2cocykv
-MC42OTMxNDcxODA1NTk5NDUzfDAKcT1NYXRoLnBvdygyLHIpCnA9czwxP3MvcTpxL3MKcmV0dXJuKChw
-KjkwMDcxOTkyNTQ3NDA5OTJ8MCkrKHAqMzU0MjI0MzE4MTE3NjUyMXwwKSkqNTk5MTk3K3IqMTI1OSY1
-MzY4NzA5MTF9LAp6WTpmdW5jdGlvbihhLGIpe3ZhciBzPWElYgppZihzPT09MClyZXR1cm4gMAppZihz
-PjApcmV0dXJuIHMKaWYoYjwwKXJldHVybiBzLWIKZWxzZSByZXR1cm4gcytifSwKQlU6ZnVuY3Rpb24o
-YSxiKXtyZXR1cm4oYXwwKT09PWE/YS9ifDA6dGhpcy5ESihhLGIpfSwKREo6ZnVuY3Rpb24oYSxiKXt2
-YXIgcz1hL2IKaWYocz49LTIxNDc0ODM2NDgmJnM8PTIxNDc0ODM2NDcpcmV0dXJuIHN8MAppZihzPjAp
-e2lmKHMhPT0xLzApcmV0dXJuIE1hdGguZmxvb3Iocyl9ZWxzZSBpZihzPi0xLzApcmV0dXJuIE1hdGgu
-Y2VpbChzKQp0aHJvdyBILmIoUC5MNCgiUmVzdWx0IG9mIHRydW5jYXRpbmcgZGl2aXNpb24gaXMgIitI
-LkVqKHMpKyI6ICIrSC5FaihhKSsiIH4vICIrYikpfSwKd0c6ZnVuY3Rpb24oYSxiKXt2YXIgcwppZihh
-PjApcz10aGlzLnAzKGEsYikKZWxzZXtzPWI+MzE/MzE6YgpzPWE+PnM+Pj4wfXJldHVybiBzfSwKYmY6
-ZnVuY3Rpb24oYSxiKXtpZihiPDApdGhyb3cgSC5iKEgudEwoYikpCnJldHVybiB0aGlzLnAzKGEsYil9
-LApwMzpmdW5jdGlvbihhLGIpe3JldHVybiBiPjMxPzA6YT4+PmJ9LAokaUNQOjEsCiRpWlo6MX0KSi5i
-VS5wcm90b3R5cGU9eyRpQjI6MX0KSi5GTi5wcm90b3R5cGU9e30KSi5Eci5wcm90b3R5cGU9ewpPOmZ1
-bmN0aW9uKGEsYil7aWYoYjwwKXRocm93IEguYihILkhZKGEsYikpCmlmKGI+PWEubGVuZ3RoKUgudihI
-LkhZKGEsYikpCnJldHVybiBhLmNoYXJDb2RlQXQoYil9LApXOmZ1bmN0aW9uKGEsYil7aWYoYj49YS5s
-ZW5ndGgpdGhyb3cgSC5iKEguSFkoYSxiKSkKcmV0dXJuIGEuY2hhckNvZGVBdChiKX0sCmRkOmZ1bmN0
-aW9uKGEsYil7cmV0dXJuIG5ldyBILnVuKGIsYSwwKX0sCmg6ZnVuY3Rpb24oYSxiKXtpZih0eXBlb2Yg
-YiE9InN0cmluZyIpdGhyb3cgSC5iKFAuTDMoYixudWxsLG51bGwpKQpyZXR1cm4gYStifSwKVGM6ZnVu
-Y3Rpb24oYSxiKXt2YXIgcz1iLmxlbmd0aCxyPWEubGVuZ3RoCmlmKHM+cilyZXR1cm4hMQpyZXR1cm4g
-Yj09PXRoaXMueW4oYSxyLXMpfSwKaTc6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHM9UC5qQihiLGMsYS5s
-ZW5ndGgpLHI9YS5zdWJzdHJpbmcoMCxiKSxxPWEuc3Vic3RyaW5nKHMpCnJldHVybiByK2QrcX0sClFp
-OmZ1bmN0aW9uKGEsYixjKXt2YXIgcwppZihjPDB8fGM+YS5sZW5ndGgpdGhyb3cgSC5iKFAuVEUoYyww
-LGEubGVuZ3RoLG51bGwsbnVsbCkpCnM9YytiLmxlbmd0aAppZihzPmEubGVuZ3RoKXJldHVybiExCnJl
-dHVybiBiPT09YS5zdWJzdHJpbmcoYyxzKX0sCm46ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5RaShh
-LGIsMCl9LApOajpmdW5jdGlvbihhLGIsYyl7aWYoYz09bnVsbCljPWEubGVuZ3RoCmlmKGI8MCl0aHJv
-dyBILmIoUC5PNyhiLG51bGwpKQppZihiPmMpdGhyb3cgSC5iKFAuTzcoYixudWxsKSkKaWYoYz5hLmxl
-bmd0aCl0aHJvdyBILmIoUC5PNyhjLG51bGwpKQpyZXR1cm4gYS5zdWJzdHJpbmcoYixjKX0sCnluOmZ1
-bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuTmooYSxiLG51bGwpfSwKaGM6ZnVuY3Rpb24oYSl7cmV0dXJu
-IGEudG9Mb3dlckNhc2UoKX0sCmJTOmZ1bmN0aW9uKGEpe3ZhciBzLHIscSxwPWEudHJpbSgpLG89cC5s
-ZW5ndGgKaWYobz09PTApcmV0dXJuIHAKaWYodGhpcy5XKHAsMCk9PT0xMzMpe3M9Si5tbShwLDEpCmlm
-KHM9PT1vKXJldHVybiIifWVsc2Ugcz0wCnI9by0xCnE9dGhpcy5PKHAscik9PT0xMzM/Si5jMShwLHIp
-Om8KaWYocz09PTAmJnE9PT1vKXJldHVybiBwCnJldHVybiBwLnN1YnN0cmluZyhzLHEpfSwKVDpmdW5j
-dGlvbihhLGIpe3ZhciBzLHIKaWYoMD49YilyZXR1cm4iIgppZihiPT09MXx8YS5sZW5ndGg9PT0wKXJl
-dHVybiBhCmlmKGIhPT1iPj4+MCl0aHJvdyBILmIoQy5FcSkKZm9yKHM9YSxyPSIiOyEwOyl7aWYoKGIm
-MSk9PT0xKXI9cytyCmI9Yj4+PjEKaWYoYj09PTApYnJlYWsKcys9c31yZXR1cm4gcn0sClhVOmZ1bmN0
-aW9uKGEsYixjKXt2YXIgcwppZihjPDB8fGM+YS5sZW5ndGgpdGhyb3cgSC5iKFAuVEUoYywwLGEubGVu
-Z3RoLG51bGwsbnVsbCkpCnM9YS5pbmRleE9mKGIsYykKcmV0dXJuIHN9LApPWTpmdW5jdGlvbihhLGIp
-e3JldHVybiB0aGlzLlhVKGEsYiwwKX0sClBrOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyCmlmKGM9PW51
-bGwpYz1hLmxlbmd0aAplbHNlIGlmKGM8MHx8Yz5hLmxlbmd0aCl0aHJvdyBILmIoUC5URShjLDAsYS5s
-ZW5ndGgsbnVsbCxudWxsKSkKcz1iLmxlbmd0aApyPWEubGVuZ3RoCmlmKGMrcz5yKWM9ci1zCnJldHVy
-biBhLmxhc3RJbmRleE9mKGIsYyl9LApjbjpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLlBrKGEsYixu
-dWxsKX0sCklzOmZ1bmN0aW9uKGEsYixjKXt2YXIgcz1hLmxlbmd0aAppZihjPnMpdGhyb3cgSC5iKFAu
-VEUoYywwLHMsbnVsbCxudWxsKSkKcmV0dXJuIEguU1EoYSxiLGMpfSwKdGc6ZnVuY3Rpb24oYSxiKXty
-ZXR1cm4gdGhpcy5JcyhhLGIsMCl9LAp3OmZ1bmN0aW9uKGEpe3JldHVybiBhfSwKZ2lPOmZ1bmN0aW9u
-KGEpe3ZhciBzLHIscQpmb3Iocz1hLmxlbmd0aCxyPTAscT0wO3E8czsrK3Epe3I9cithLmNoYXJDb2Rl
-QXQocSkmNTM2ODcwOTExCnI9cisoKHImNTI0Mjg3KTw8MTApJjUzNjg3MDkxMQpyXj1yPj42fXI9ciso
-KHImNjcxMDg4NjMpPDwzKSY1MzY4NzA5MTEKcl49cj4+MTEKcmV0dXJuIHIrKChyJjE2MzgzKTw8MTUp
-JjUzNjg3MDkxMX0sCmdBOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxlbmd0aH0sCnE6ZnVuY3Rpb24oYSxi
-KXtILnVQKGIpCmlmKGI+PWEubGVuZ3RofHwhMSl0aHJvdyBILmIoSC5IWShhLGIpKQpyZXR1cm4gYVti
-XX0sCiRpdlg6MSwKJGlxVToxfQpILkJSLnByb3RvdHlwZT17CmdtOmZ1bmN0aW9uKGEpe3ZhciBzPUgu
-TGgodGhpcykKcmV0dXJuIG5ldyBILkU3KEouSVQodGhpcy5nT04oKSkscy5DKCJAPDE+IikuS3Eocy5R
-WzFdKS5DKCJFNzwxLDI+IikpfSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIEouSG0odGhpcy5nT04oKSl9
-LApnbDA6ZnVuY3Rpb24oYSl7cmV0dXJuIEoudVUodGhpcy5nT04oKSl9LApnb3I6ZnVuY3Rpb24oYSl7
-cmV0dXJuIEouRjcodGhpcy5nT04oKSl9LAplUjpmdW5jdGlvbihhLGIpe3ZhciBzPUguTGgodGhpcykK
-cmV0dXJuIEguR0ooSi5BNSh0aGlzLmdPTigpLGIpLHMuYyxzLlFbMV0pfSwKRTpmdW5jdGlvbihhLGIp
-e3JldHVybiBILkxoKHRoaXMpLlFbMV0uYShKLkdBKHRoaXMuZ09OKCksYikpfSwKdzpmdW5jdGlvbihh
-KXtyZXR1cm4gSi5qKHRoaXMuZ09OKCkpfX0KSC5FNy5wcm90b3R5cGU9ewpGOmZ1bmN0aW9uKCl7cmV0
-dXJuIHRoaXMuYS5GKCl9LApnbDpmdW5jdGlvbigpe3JldHVybiB0aGlzLiR0aS5RWzFdLmEodGhpcy5h
-LmdsKCkpfSwKJGlBbjoxfQpILlp5LnByb3RvdHlwZT17CmdPTjpmdW5jdGlvbigpe3JldHVybiB0aGlz
-LmF9fQpILm9sLnByb3RvdHlwZT17JGliUToxfQpILlVxLnByb3RvdHlwZT17CnE6ZnVuY3Rpb24oYSxi
-KXtyZXR1cm4gdGhpcy4kdGkuUVsxXS5hKEoueDkodGhpcy5hLEgudVAoYikpKX0sClk1OmZ1bmN0aW9u
-KGEsYixjKXt2YXIgcz10aGlzLiR0aQpKLnU5KHRoaXMuYSxiLHMuYy5hKHMuUVsxXS5hKGMpKSl9LAok
-aWJROjEsCiRpek06MX0KSC5qVi5wcm90b3R5cGU9ewpkcjpmdW5jdGlvbihhLGIpe3JldHVybiBuZXcg
-SC5qVih0aGlzLmEsdGhpcy4kdGkuQygiQDwxPiIpLktxKGIpLkMoImpWPDEsMj4iKSl9LApnT046ZnVu
-Y3Rpb24oKXtyZXR1cm4gdGhpcy5hfX0KSC5uLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7dmFyIHM9
-dGhpcy5hCnJldHVybiBzIT1udWxsPyJMYXRlSW5pdGlhbGl6YXRpb25FcnJvcjogIitzOiJMYXRlSW5p
-dGlhbGl6YXRpb25FcnJvciJ9fQpILnIzLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7dmFyIHM9IlJl
-YWNoYWJpbGl0eUVycm9yOiAiK3RoaXMuYQpyZXR1cm4gc319CkgucWoucHJvdG90eXBlPXsKZ0E6ZnVu
-Y3Rpb24oYSl7cmV0dXJuIHRoaXMuYS5sZW5ndGh9LApxOmZ1bmN0aW9uKGEsYil7cmV0dXJuIEMueEIu
-Tyh0aGlzLmEsSC51UChiKSl9fQpILkdNLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7cmV0dXJuIk51
-bGwgaXMgbm90IGEgdmFsaWQgdmFsdWUgZm9yIHRoZSBwYXJhbWV0ZXIgJyIrdGhpcy5hKyInIG9mIHR5
-cGUgJyIrSC5LeCh0aGlzLiR0aS5jKS53KDApKyInIn19CkguYlEucHJvdG90eXBlPXt9CkguYUwucHJv
-dG90eXBlPXsKZ206ZnVuY3Rpb24oYSl7dmFyIHM9dGhpcwpyZXR1cm4gbmV3IEguYTcocyxzLmdBKHMp
-LEguTGgocykuQygiYTc8YUwuRT4iKSl9LApnbDA6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuZ0EodGhp
-cyk9PT0wfSwKazpmdW5jdGlvbihhLGIpe3ZhciBzLHIscSxwPXRoaXMsbz1wLmdBKHApCmlmKGIubGVu
-Z3RoIT09MCl7aWYobz09PTApcmV0dXJuIiIKcz1ILkVqKHAuRSgwLDApKQppZihvIT09cC5nQShwKSl0
-aHJvdyBILmIoUC5hNChwKSkKZm9yKHI9cyxxPTE7cTxvOysrcSl7cj1yK2IrSC5FaihwLkUoMCxxKSkK
-aWYobyE9PXAuZ0EocCkpdGhyb3cgSC5iKFAuYTQocCkpfXJldHVybiByLmNoYXJDb2RlQXQoMCk9PTA/
-cjpyfWVsc2V7Zm9yKHE9MCxyPSIiO3E8bzsrK3Epe3IrPUguRWoocC5FKDAscSkpCmlmKG8hPT1wLmdB
-KHApKXRocm93IEguYihQLmE0KHApKX1yZXR1cm4gci5jaGFyQ29kZUF0KDApPT0wP3I6cn19LApldjpm
-dW5jdGlvbihhLGIpe3JldHVybiB0aGlzLkdHKDAsSC5MaCh0aGlzKS5DKCJhMihhTC5FKSIpLmEoYikp
-fSwKRTI6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzPUguTGgodGhpcykKcmV0dXJuIG5ldyBILmxKKHRoaXMs
-cy5LcShjKS5DKCIxKGFMLkUpIikuYShiKSxzLkMoIkA8YUwuRT4iKS5LcShjKS5DKCJsSjwxLDI+Iikp
-fSwKZVI6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gSC5xQyh0aGlzLGIsbnVsbCxILkxoKHRoaXMpLkMoImFM
-LkUiKSl9LAp0dDpmdW5jdGlvbihhLGIpe3JldHVybiBQLlkxKHRoaXMsITAsSC5MaCh0aGlzKS5DKCJh
-TC5FIikpfSwKYnI6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMudHQoYSwhMCl9fQpILm5ILnByb3RvdHlw
-ZT17CkhkOmZ1bmN0aW9uKGEsYixjLGQpe3ZhciBzLHI9dGhpcy5iClAuazEociwic3RhcnQiKQpzPXRo
-aXMuYwppZihzIT1udWxsKXtQLmsxKHMsImVuZCIpCmlmKHI+cyl0aHJvdyBILmIoUC5URShyLDAscywi
-c3RhcnQiLG51bGwpKX19LApnVUQ6ZnVuY3Rpb24oKXt2YXIgcz1KLkhtKHRoaXMuYSkscj10aGlzLmMK
-aWYocj09bnVsbHx8cj5zKXJldHVybiBzCnJldHVybiByfSwKZ0FzOmZ1bmN0aW9uKCl7dmFyIHM9Si5I
-bSh0aGlzLmEpLHI9dGhpcy5iCmlmKHI+cylyZXR1cm4gcwpyZXR1cm4gcn0sCmdBOmZ1bmN0aW9uKGEp
-e3ZhciBzLHI9Si5IbSh0aGlzLmEpLHE9dGhpcy5iCmlmKHE+PXIpcmV0dXJuIDAKcz10aGlzLmMKaWYo
-cz09bnVsbHx8cz49cilyZXR1cm4gci1xCmlmKHR5cGVvZiBzIT09Im51bWJlciIpcmV0dXJuIHMuSE4o
-KQpyZXR1cm4gcy1xfSwKRTpmdW5jdGlvbihhLGIpe3ZhciBzPXRoaXMscj1zLmdBcygpK2IKaWYoYjww
-fHxyPj1zLmdVRCgpKXRocm93IEguYihQLkNmKGIscywiaW5kZXgiLG51bGwsbnVsbCkpCnJldHVybiBK
-LkdBKHMuYSxyKX0sCmVSOmZ1bmN0aW9uKGEsYil7dmFyIHMscixxPXRoaXMKUC5rMShiLCJjb3VudCIp
-CnM9cS5iK2IKcj1xLmMKaWYociE9bnVsbCYmcz49cilyZXR1cm4gbmV3IEguTUIocS4kdGkuQygiTUI8
-MT4iKSkKcmV0dXJuIEgucUMocS5hLHMscixxLiR0aS5jKX0sCnR0OmZ1bmN0aW9uKGEsYil7dmFyIHMs
-cixxLHA9dGhpcyxvPXAuYixuPXAuYSxtPUouVTYobiksbD1tLmdBKG4pLGs9cC5jCmlmKGshPW51bGwm
-Jms8bClsPWsKaWYodHlwZW9mIGwhPT0ibnVtYmVyIilyZXR1cm4gbC5ITigpCnM9bC1vCmlmKHM8PTAp
-e249Si5RaSgwLHAuJHRpLmMpCnJldHVybiBufXI9UC5POChzLG0uRShuLG8pLCExLHAuJHRpLmMpCmZv
-cihxPTE7cTxzOysrcSl7Qy5ObS5ZNShyLHEsbS5FKG4sbytxKSkKaWYobS5nQShuKTxsKXRocm93IEgu
-YihQLmE0KHApKX1yZXR1cm4gcn19CkguYTcucHJvdG90eXBlPXsKZ2w6ZnVuY3Rpb24oKXtyZXR1cm4g
-dGhpcy5kfSwKRjpmdW5jdGlvbigpe3ZhciBzLHI9dGhpcyxxPXIuYSxwPUouVTYocSksbz1wLmdBKHEp
-CmlmKHIuYiE9PW8pdGhyb3cgSC5iKFAuYTQocSkpCnM9ci5jCmlmKHM+PW8pe3Iuc0kobnVsbCkKcmV0
-dXJuITF9ci5zSShwLkUocSxzKSk7KytyLmMKcmV0dXJuITB9LApzSTpmdW5jdGlvbihhKXt0aGlzLmQ9
-dGhpcy4kdGkuQygiMT8iKS5hKGEpfSwKJGlBbjoxfQpILmkxLnByb3RvdHlwZT17CmdtOmZ1bmN0aW9u
-KGEpe3ZhciBzPUguTGgodGhpcykKcmV0dXJuIG5ldyBILk1IKEouSVQodGhpcy5hKSx0aGlzLmIscy5D
-KCJAPDE+IikuS3Eocy5RWzFdKS5DKCJNSDwxLDI+IikpfSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIEou
-SG0odGhpcy5hKX0sCmdsMDpmdW5jdGlvbihhKXtyZXR1cm4gSi51VSh0aGlzLmEpfSwKRTpmdW5jdGlv
-bihhLGIpe3JldHVybiB0aGlzLmIuJDEoSi5HQSh0aGlzLmEsYikpfX0KSC54eS5wcm90b3R5cGU9eyRp
-YlE6MX0KSC5NSC5wcm90b3R5cGU9ewpGOmZ1bmN0aW9uKCl7dmFyIHM9dGhpcyxyPXMuYgppZihyLkYo
-KSl7cy5zSShzLmMuJDEoci5nbCgpKSkKcmV0dXJuITB9cy5zSShudWxsKQpyZXR1cm4hMX0sCmdsOmZ1
-bmN0aW9uKCl7cmV0dXJuIHRoaXMuYX0sCnNJOmZ1bmN0aW9uKGEpe3RoaXMuYT10aGlzLiR0aS5DKCIy
-PyIpLmEoYSl9fQpILmxKLnByb3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3JldHVybiBKLkhtKHRoaXMu
-YSl9LApFOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuYi4kMShKLkdBKHRoaXMuYSxiKSl9fQpILlU1
-LnByb3RvdHlwZT17CmdtOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgSC5TTyhKLklUKHRoaXMuYSksdGhp
-cy5iLHRoaXMuJHRpLkMoIlNPPDE+IikpfX0KSC5TTy5wcm90b3R5cGU9ewpGOmZ1bmN0aW9uKCl7dmFy
-IHMscgpmb3Iocz10aGlzLmEscj10aGlzLmI7cy5GKCk7KWlmKEgub1Qoci4kMShzLmdsKCkpKSlyZXR1
-cm4hMApyZXR1cm4hMX0sCmdsOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuYS5nbCgpfX0KSC5BTS5wcm90
-b3R5cGU9ewplUjpmdW5jdGlvbihhLGIpe1AuTVIoYiwiY291bnQiLHQuUykKUC5rMShiLCJjb3VudCIp
-CnJldHVybiBuZXcgSC5BTSh0aGlzLmEsdGhpcy5iK2IsSC5MaCh0aGlzKS5DKCJBTTwxPiIpKX0sCmdt
-OmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgSC5VMShKLklUKHRoaXMuYSksdGhpcy5iLEguTGgodGhpcyku
-QygiVTE8MT4iKSl9fQpILmQ1LnByb3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3ZhciBzPUouSG0odGhp
-cy5hKS10aGlzLmIKaWYocz49MClyZXR1cm4gcwpyZXR1cm4gMH0sCmVSOmZ1bmN0aW9uKGEsYil7UC5N
-UihiLCJjb3VudCIsdC5TKQpQLmsxKGIsImNvdW50IikKcmV0dXJuIG5ldyBILmQ1KHRoaXMuYSx0aGlz
-LmIrYix0aGlzLiR0aSl9LAokaWJROjF9CkguVTEucHJvdG90eXBlPXsKRjpmdW5jdGlvbigpe3ZhciBz
-LHIKZm9yKHM9dGhpcy5hLHI9MDtyPHRoaXMuYjsrK3Ipcy5GKCkKdGhpcy5iPTAKcmV0dXJuIHMuRigp
-fSwKZ2w6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5hLmdsKCl9fQpILk1CLnByb3RvdHlwZT17CmdtOmZ1
-bmN0aW9uKGEpe3JldHVybiBDLkd3fSwKZ2wwOmZ1bmN0aW9uKGEpe3JldHVybiEwfSwKZ0E6ZnVuY3Rp
-b24oYSl7cmV0dXJuIDB9LApFOmZ1bmN0aW9uKGEsYil7dGhyb3cgSC5iKFAuVEUoYiwwLDAsImluZGV4
-IixudWxsKSl9LAplUjpmdW5jdGlvbihhLGIpe1AuazEoYiwiY291bnQiKQpyZXR1cm4gdGhpc319Ckgu
-RnUucHJvdG90eXBlPXsKRjpmdW5jdGlvbigpe3JldHVybiExfSwKZ2w6ZnVuY3Rpb24oKXt0aHJvdyBI
-LmIoSC5XcCgpKX0sCiRpQW46MX0KSC51Ni5wcm90b3R5cGU9ewpnbTpmdW5jdGlvbihhKXtyZXR1cm4g
-bmV3IEguSkIoSi5JVCh0aGlzLmEpLHRoaXMuJHRpLkMoIkpCPDE+IikpfX0KSC5KQi5wcm90b3R5cGU9
-ewpGOmZ1bmN0aW9uKCl7dmFyIHMscgpmb3Iocz10aGlzLmEscj10aGlzLiR0aS5jO3MuRigpOylpZihy
-LmIocy5nbCgpKSlyZXR1cm4hMApyZXR1cm4hMX0sCmdsOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuJHRp
-LmMuYSh0aGlzLmEuZ2woKSl9LAokaUFuOjF9CkguU1UucHJvdG90eXBlPXt9CkguUmUucHJvdG90eXBl
-PXsKWTU6ZnVuY3Rpb24oYSxiLGMpe0guTGgodGhpcykuQygiUmUuRSIpLmEoYykKdGhyb3cgSC5iKFAu
-TDQoIkNhbm5vdCBtb2RpZnkgYW4gdW5tb2RpZmlhYmxlIGxpc3QiKSl9fQpILncyLnByb3RvdHlwZT17
-fQpILnd2LnByb3RvdHlwZT17CmdpTzpmdW5jdGlvbihhKXt2YXIgcz10aGlzLl9oYXNoQ29kZQppZihz
-IT1udWxsKXJldHVybiBzCnM9NjY0NTk3KkouaGYodGhpcy5hKSY1MzY4NzA5MTEKdGhpcy5faGFzaENv
-ZGU9cwpyZXR1cm4gc30sCnc6ZnVuY3Rpb24oYSl7cmV0dXJuJ1N5bWJvbCgiJytILkVqKHRoaXMuYSkr
-JyIpJ30sCkROOmZ1bmN0aW9uKGEsYil7aWYoYj09bnVsbClyZXR1cm4hMQpyZXR1cm4gYiBpbnN0YW5j
-ZW9mIEgud3YmJnRoaXMuYT09Yi5hfSwKJGlHRDoxfQpILlFDLnByb3RvdHlwZT17fQpILlBELnByb3Rv
-dHlwZT17fQpILldVLnByb3RvdHlwZT17CmdsMDpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5nQSh0aGlz
-KT09PTB9LAp3OmZ1bmN0aW9uKGEpe3JldHVybiBQLm5PKHRoaXMpfSwKWTU6ZnVuY3Rpb24oYSxiLGMp
-e3ZhciBzPUguTGgodGhpcykKcy5jLmEoYikKcy5RWzFdLmEoYykKSC5kYygpCkguQmkodS5nKX0sCmdQ
-dTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5xNChhLEguTGgodGhpcykuQygiTjM8MSwyPiIpKX0sCnE0
-OmZ1bmN0aW9uKGEsYil7dmFyIHM9dGhpcwpyZXR1cm4gUC5sMChmdW5jdGlvbigpe3ZhciByPWEKdmFy
-IHE9MCxwPTEsbyxuLG0sbCxrCnJldHVybiBmdW5jdGlvbiAkYXN5bmMkZ1B1KGMsZCl7aWYoYz09PTEp
-e289ZApxPXB9d2hpbGUodHJ1ZSlzd2l0Y2gocSl7Y2FzZSAwOm49cy5ndmMoKSxuPW4uZ20obiksbT1I
-LkxoKHMpLG09bS5DKCJAPDE+IikuS3EobS5RWzFdKS5DKCJOMzwxLDI+IikKY2FzZSAyOmlmKCFuLkYo
-KSl7cT0zCmJyZWFrfWw9bi5nbCgpCms9cy5xKDAsbCkKay50b1N0cmluZwpxPTQKcmV0dXJuIG5ldyBQ
-Lk4zKGwsayxtKQpjYXNlIDQ6cT0yCmJyZWFrCmNhc2UgMzpyZXR1cm4gUC5UaCgpCmNhc2UgMTpyZXR1
-cm4gUC5ZbShvKX19fSxiKX0sCiRpWjA6MX0KSC5MUC5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXty
-ZXR1cm4gdGhpcy5hfSwKeDQ6ZnVuY3Rpb24oYSl7aWYodHlwZW9mIGEhPSJzdHJpbmciKXJldHVybiEx
-CmlmKCJfX3Byb3RvX18iPT09YSlyZXR1cm4hMQpyZXR1cm4gdGhpcy5iLmhhc093blByb3BlcnR5KGEp
-fSwKcTpmdW5jdGlvbihhLGIpe2lmKCF0aGlzLng0KGIpKXJldHVybiBudWxsCnJldHVybiB0aGlzLnFQ
-KGIpfSwKcVA6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYltILmgoYSldfSwKSzpmdW5jdGlvbihhLGIp
-e3ZhciBzLHIscSxwLG89SC5MaCh0aGlzKQpvLkMoIn4oMSwyKSIpLmEoYikKcz10aGlzLmMKZm9yKHI9
-cy5sZW5ndGgsbz1vLlFbMV0scT0wO3E8cjsrK3Epe3A9c1txXQpiLiQyKHAsby5hKHRoaXMucVAocCkp
-KX19LApndmM6ZnVuY3Rpb24oKXtyZXR1cm4gbmV3IEguWFIodGhpcyxILkxoKHRoaXMpLkMoIlhSPDE+
-IikpfX0KSC5YUi5wcm90b3R5cGU9ewpnbTpmdW5jdGlvbihhKXt2YXIgcz10aGlzLmEuYwpyZXR1cm4g
-bmV3IEoubTEocyxzLmxlbmd0aCxILnQ2KHMpLkMoIm0xPDE+IikpfSwKZ0E6ZnVuY3Rpb24oYSl7cmV0
-dXJuIHRoaXMuYS5jLmxlbmd0aH19CkguTEkucHJvdG90eXBlPXsKZ1dhOmZ1bmN0aW9uKCl7dmFyIHM9
-dGhpcy5hCnJldHVybiBzfSwKZ25kOmZ1bmN0aW9uKCl7dmFyIHMscixxLHAsbz10aGlzCmlmKG8uYz09
-PTEpcmV0dXJuIEMuaFUKcz1vLmQKcj1zLmxlbmd0aC1vLmUubGVuZ3RoLW8uZgppZihyPT09MClyZXR1
-cm4gQy5oVQpxPVtdCmZvcihwPTA7cDxyOysrcCl7aWYocD49cy5sZW5ndGgpcmV0dXJuIEguT0gocyxw
-KQpxLnB1c2goc1twXSl9cmV0dXJuIEouekMocSl9LApnVm06ZnVuY3Rpb24oKXt2YXIgcyxyLHEscCxv
-LG4sbSxsLGs9dGhpcwppZihrLmMhPT0wKXJldHVybiBDLldPCnM9ay5lCnI9cy5sZW5ndGgKcT1rLmQK
-cD1xLmxlbmd0aC1yLWsuZgppZihyPT09MClyZXR1cm4gQy5XTwpvPW5ldyBILk41KHQuZW8pCmZvcihu
-PTA7bjxyOysrbil7aWYobj49cy5sZW5ndGgpcmV0dXJuIEguT0gocyxuKQptPXNbbl0KbD1wK24KaWYo
-bDwwfHxsPj1xLmxlbmd0aClyZXR1cm4gSC5PSChxLGwpCm8uWTUoMCxuZXcgSC53dihtKSxxW2xdKX1y
-ZXR1cm4gbmV3IEguUEQobyx0LmdGKX0sCiRpdlE6MX0KSC5Dai5wcm90b3R5cGU9ewokMjpmdW5jdGlv
-bihhLGIpe3ZhciBzCkguaChhKQpzPXRoaXMuYQpzLmI9cy5iKyIkIitILkVqKGEpCkMuTm0uaSh0aGlz
-LmIsYSkKQy5ObS5pKHRoaXMuYyxiKTsrK3MuYX0sCiRTOjEzfQpILmY5LnByb3RvdHlwZT17CnFTOmZ1
-bmN0aW9uKGEpe3ZhciBzLHIscT10aGlzLHA9bmV3IFJlZ0V4cChxLmEpLmV4ZWMoYSkKaWYocD09bnVs
-bClyZXR1cm4gbnVsbApzPU9iamVjdC5jcmVhdGUobnVsbCkKcj1xLmIKaWYociE9PS0xKXMuYXJndW1l
-bnRzPXBbcisxXQpyPXEuYwppZihyIT09LTEpcy5hcmd1bWVudHNFeHByPXBbcisxXQpyPXEuZAppZihy
-IT09LTEpcy5leHByPXBbcisxXQpyPXEuZQppZihyIT09LTEpcy5tZXRob2Q9cFtyKzFdCnI9cS5mCmlm
-KHIhPT0tMSlzLnJlY2VpdmVyPXBbcisxXQpyZXR1cm4gc319CkguVzAucHJvdG90eXBlPXsKdzpmdW5j
-dGlvbihhKXt2YXIgcz10aGlzLmIKaWYocz09bnVsbClyZXR1cm4iTm9TdWNoTWV0aG9kRXJyb3I6ICIr
-SC5Faih0aGlzLmEpCnJldHVybiJOb1N1Y2hNZXRob2RFcnJvcjogbWV0aG9kIG5vdCBmb3VuZDogJyIr
-cysiJyBvbiBudWxsIn19CkguYXoucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXt2YXIgcyxyPXRoaXMs
-cT0iTm9TdWNoTWV0aG9kRXJyb3I6IG1ldGhvZCBub3QgZm91bmQ6ICciLHA9ci5iCmlmKHA9PW51bGwp
-cmV0dXJuIk5vU3VjaE1ldGhvZEVycm9yOiAiK0guRWooci5hKQpzPXIuYwppZihzPT1udWxsKXJldHVy
-biBxK3ArIicgKCIrSC5FaihyLmEpKyIpIgpyZXR1cm4gcStwKyInIG9uICciK3MrIicgKCIrSC5Faihy
-LmEpKyIpIn19CkgudlYucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXt2YXIgcz10aGlzLmEKcmV0dXJu
-IHMubGVuZ3RoPT09MD8iRXJyb3IiOiJFcnJvcjogIitzfX0KSC50ZS5wcm90b3R5cGU9ewp3OmZ1bmN0
-aW9uKGEpe3JldHVybiJUaHJvdyBvZiBudWxsICgnIisodGhpcy5hPT09bnVsbD8ibnVsbCI6InVuZGVm
-aW5lZCIpKyInIGZyb20gSmF2YVNjcmlwdCkifSwKJGlSejoxfQpILmJxLnByb3RvdHlwZT17fQpILlhP
-LnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7dmFyIHMscj10aGlzLmIKaWYociE9bnVsbClyZXR1cm4g
-cgpyPXRoaXMuYQpzPXIhPT1udWxsJiZ0eXBlb2Ygcj09PSJvYmplY3QiP3Iuc3RhY2s6bnVsbApyZXR1
-cm4gdGhpcy5iPXM9PW51bGw/IiI6c30sCiRpR3o6MX0KSC5UcC5wcm90b3R5cGU9ewp3OmZ1bmN0aW9u
-KGEpe3ZhciBzPXRoaXMuY29uc3RydWN0b3Iscj1zPT1udWxsP251bGw6cy5uYW1lCnJldHVybiJDbG9z
-dXJlICciK0guTlEocj09bnVsbD8idW5rbm93biI6cikrIicifSwKJGlFSDoxLApnS3U6ZnVuY3Rpb24o
-KXtyZXR1cm4gdGhpc30sCiRDOiIkMSIsCiRSOjEsCiREOm51bGx9CkgubGMucHJvdG90eXBlPXt9Ckgu
-engucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXt2YXIgcz10aGlzLiRzdGF0aWNfbmFtZQppZihzPT1u
-dWxsKXJldHVybiJDbG9zdXJlIG9mIHVua25vd24gc3RhdGljIG1ldGhvZCIKcmV0dXJuIkNsb3N1cmUg
-JyIrSC5OUShzKSsiJyJ9fQpILnJULnByb3RvdHlwZT17CkROOmZ1bmN0aW9uKGEsYil7dmFyIHM9dGhp
-cwppZihiPT1udWxsKXJldHVybiExCmlmKHM9PT1iKXJldHVybiEwCmlmKCEoYiBpbnN0YW5jZW9mIEgu
-clQpKXJldHVybiExCnJldHVybiBzLmE9PT1iLmEmJnMuYj09PWIuYiYmcy5jPT09Yi5jfSwKZ2lPOmZ1
-bmN0aW9uKGEpe3ZhciBzLHI9dGhpcy5jCmlmKHI9PW51bGwpcz1ILmVRKHRoaXMuYSkKZWxzZSBzPXR5
-cGVvZiByIT09Im9iamVjdCI/Si5oZihyKTpILmVRKHIpCnI9SC5lUSh0aGlzLmIpCmlmKHR5cGVvZiBz
-IT09Im51bWJlciIpcmV0dXJuIHMuWSgpCnJldHVybihzXnIpPj4+MH0sCnc6ZnVuY3Rpb24oYSl7dmFy
-IHM9dGhpcy5jCmlmKHM9PW51bGwpcz10aGlzLmEKcmV0dXJuIkNsb3N1cmUgJyIrSC5Faih0aGlzLmQp
-KyInIG9mICIrKCJJbnN0YW5jZSBvZiAnIitILkVqKEguTShzKSkrIiciKX19CkguRXEucHJvdG90eXBl
-PXsKdzpmdW5jdGlvbihhKXtyZXR1cm4iUnVudGltZUVycm9yOiAiK3RoaXMuYX19Ckgua1kucHJvdG90
-eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4iQXNzZXJ0aW9uIGZhaWxlZDogIitQLnAodGhpcy5hKX19
-Ckgua3IucHJvdG90eXBlPXt9CkguTjUucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRo
-aXMuYX0sCmdsMDpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hPT09MH0sCmd2YzpmdW5jdGlvbigpe3Jl
-dHVybiBuZXcgSC5pNSh0aGlzLEguTGgodGhpcykuQygiaTU8MT4iKSl9LAp4NDpmdW5jdGlvbihhKXt2
-YXIgcyxyCmlmKHR5cGVvZiBhPT0ic3RyaW5nIil7cz10aGlzLmIKaWYocz09bnVsbClyZXR1cm4hMQpy
-ZXR1cm4gdGhpcy5YdShzLGEpfWVsc2V7cj10aGlzLkNYKGEpCnJldHVybiByfX0sCkNYOmZ1bmN0aW9u
-KGEpe3ZhciBzPXRoaXMuZAppZihzPT1udWxsKXJldHVybiExCnJldHVybiB0aGlzLkZoKHRoaXMuQnQo
-cyxKLmhmKGEpJjB4M2ZmZmZmZiksYSk+PTB9LApxOmZ1bmN0aW9uKGEsYil7dmFyIHMscixxLHAsbz10
-aGlzLG49bnVsbAppZih0eXBlb2YgYj09InN0cmluZyIpe3M9by5iCmlmKHM9PW51bGwpcmV0dXJuIG4K
-cj1vLmoyKHMsYikKcT1yPT1udWxsP246ci5iCnJldHVybiBxfWVsc2UgaWYodHlwZW9mIGI9PSJudW1i
-ZXIiJiYoYiYweDNmZmZmZmYpPT09Yil7cD1vLmMKaWYocD09bnVsbClyZXR1cm4gbgpyPW8uajIocCxi
-KQpxPXI9PW51bGw/bjpyLmIKcmV0dXJuIHF9ZWxzZSByZXR1cm4gby5hYShiKX0sCmFhOmZ1bmN0aW9u
-KGEpe3ZhciBzLHIscT10aGlzLmQKaWYocT09bnVsbClyZXR1cm4gbnVsbApzPXRoaXMuQnQocSxKLmhm
-KGEpJjB4M2ZmZmZmZikKcj10aGlzLkZoKHMsYSkKaWYocjwwKXJldHVybiBudWxsCnJldHVybiBzW3Jd
-LmJ9LApZNTpmdW5jdGlvbihhLGIsYyl7dmFyIHMscixxLHAsbyxuLG09dGhpcyxsPUguTGgobSkKbC5j
-LmEoYikKbC5RWzFdLmEoYykKaWYodHlwZW9mIGI9PSJzdHJpbmciKXtzPW0uYgptLkVIKHM9PW51bGw/
-bS5iPW0ueksoKTpzLGIsYyl9ZWxzZSBpZih0eXBlb2YgYj09Im51bWJlciImJihiJjB4M2ZmZmZmZik9
-PT1iKXtyPW0uYwptLkVIKHI9PW51bGw/bS5jPW0ueksoKTpyLGIsYyl9ZWxzZXtxPW0uZAppZihxPT1u
-dWxsKXE9bS5kPW0ueksoKQpwPUouaGYoYikmMHgzZmZmZmZmCm89bS5CdChxLHApCmlmKG89PW51bGwp
-bS5FSShxLHAsW20uSG4oYixjKV0pCmVsc2V7bj1tLkZoKG8sYikKaWYobj49MClvW25dLmI9YwplbHNl
-IG8ucHVzaChtLkhuKGIsYykpfX19LApLOmZ1bmN0aW9uKGEsYil7dmFyIHMscixxPXRoaXMKSC5MaChx
-KS5DKCJ+KDEsMikiKS5hKGIpCnM9cS5lCnI9cS5yCmZvcig7cyE9bnVsbDspe2IuJDIocy5hLHMuYikK
-aWYociE9PXEucil0aHJvdyBILmIoUC5hNChxKSkKcz1zLmN9fSwKRUg6ZnVuY3Rpb24oYSxiLGMpe3Zh
-ciBzLHI9dGhpcyxxPUguTGgocikKcS5jLmEoYikKcS5RWzFdLmEoYykKcz1yLmoyKGEsYikKaWYocz09
-bnVsbClyLkVJKGEsYixyLkhuKGIsYykpCmVsc2Ugcy5iPWN9LAprczpmdW5jdGlvbigpe3RoaXMucj10
-aGlzLnIrMSY2NzEwODg2M30sCkhuOmZ1bmN0aW9uKGEsYil7dmFyIHM9dGhpcyxyPUguTGgocykscT1u
-ZXcgSC52aChyLmMuYShhKSxyLlFbMV0uYShiKSkKaWYocy5lPT1udWxsKXMuZT1zLmY9cQplbHNle3I9
-cy5mCnIudG9TdHJpbmcKcS5kPXIKcy5mPXIuYz1xfSsrcy5hCnMua3MoKQpyZXR1cm4gcX0sCkZoOmZ1
-bmN0aW9uKGEsYil7dmFyIHMscgppZihhPT1udWxsKXJldHVybi0xCnM9YS5sZW5ndGgKZm9yKHI9MDty
-PHM7KytyKWlmKEouUk0oYVtyXS5hLGIpKXJldHVybiByCnJldHVybi0xfSwKdzpmdW5jdGlvbihhKXty
-ZXR1cm4gUC5uTyh0aGlzKX0sCmoyOmZ1bmN0aW9uKGEsYil7cmV0dXJuIGFbYl19LApCdDpmdW5jdGlv
-bihhLGIpe3JldHVybiBhW2JdfSwKRUk6ZnVuY3Rpb24oYSxiLGMpe2FbYl09Y30sCnJuOmZ1bmN0aW9u
-KGEsYil7ZGVsZXRlIGFbYl19LApYdTpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLmoyKGEsYikhPW51
-bGx9LAp6SzpmdW5jdGlvbigpe3ZhciBzPSI8bm9uLWlkZW50aWZpZXIta2V5PiIscj1PYmplY3QuY3Jl
-YXRlKG51bGwpCnRoaXMuRUkocixzLHIpCnRoaXMucm4ocixzKQpyZXR1cm4gcn0sCiRpRm86MX0KSC52
-aC5wcm90b3R5cGU9e30KSC5pNS5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5h
-LmF9LApnbDA6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYS5hPT09MH0sCmdtOmZ1bmN0aW9uKGEpe3Zh
-ciBzPXRoaXMuYSxyPW5ldyBILk42KHMscy5yLHRoaXMuJHRpLkMoIk42PDE+IikpCnIuYz1zLmUKcmV0
-dXJuIHJ9LAp0ZzpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLmEueDQoYil9fQpILk42LnByb3RvdHlw
-ZT17CmdsOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuZH0sCkY6ZnVuY3Rpb24oKXt2YXIgcyxyPXRoaXMs
-cT1yLmEKaWYoci5iIT09cS5yKXRocm93IEguYihQLmE0KHEpKQpzPXIuYwppZihzPT1udWxsKXtyLnNx
-WShudWxsKQpyZXR1cm4hMX1lbHNle3Iuc3FZKHMuYSkKci5jPXMuYwpyZXR1cm4hMH19LApzcVk6ZnVu
-Y3Rpb24oYSl7dGhpcy5kPXRoaXMuJHRpLkMoIjE/IikuYShhKX0sCiRpQW46MX0KSC5kQy5wcm90b3R5
-cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hKGEpfSwKJFM6NH0KSC53Ti5wcm90b3R5cGU9
-ewokMjpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLmEoYSxiKX0sCiRTOjM0fQpILlZYLnByb3RvdHlw
-ZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmEoSC5oKGEpKX0sCiRTOjMyfQpILlZSLnByb3Rv
-dHlwZT17Cnc6ZnVuY3Rpb24oYSl7cmV0dXJuIlJlZ0V4cC8iK3RoaXMuYSsiLyIrdGhpcy5iLmZsYWdz
-fSwKZ0hjOmZ1bmN0aW9uKCl7dmFyIHM9dGhpcyxyPXMuYwppZihyIT1udWxsKXJldHVybiByCnI9cy5i
-CnJldHVybiBzLmM9SC52NChzLmEsci5tdWx0aWxpbmUsIXIuaWdub3JlQ2FzZSxyLnVuaWNvZGUsci5k
-b3RBbGwsITApfSwKZGQ6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gbmV3IEguS1codGhpcyxiLDApfSwKVVo6
-ZnVuY3Rpb24oYSxiKXt2YXIgcyxyPXRoaXMuZ0hjKCkKci5sYXN0SW5kZXg9YgpzPXIuZXhlYyhhKQpp
-ZihzPT1udWxsKXJldHVybiBudWxsCnJldHVybiBuZXcgSC5FSyhzKX0sCiRpdlg6MSwKJGl3TDoxfQpI
-LkVLLnByb3RvdHlwZT17CnE6ZnVuY3Rpb24oYSxiKXt2YXIgcwpILnVQKGIpCnM9dGhpcy5iCmlmKGI+
-PXMubGVuZ3RoKXJldHVybiBILk9IKHMsYikKcmV0dXJuIHNbYl19LAokaU9kOjEsCiRpaWI6MX0KSC5L
-Vy5wcm90b3R5cGU9ewpnbTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IEguUGIodGhpcy5hLHRoaXMuYix0
-aGlzLmMpfX0KSC5QYi5wcm90b3R5cGU9ewpnbDpmdW5jdGlvbigpe3JldHVybiB0aGlzLmR9LApGOmZ1
-bmN0aW9uKCl7dmFyIHMscixxLHAsbyxuLG09dGhpcyxsPW0uYgppZihsPT1udWxsKXJldHVybiExCnM9
-bS5jCnI9bC5sZW5ndGgKaWYoczw9cil7cT1tLmEKcD1xLlVaKGwscykKaWYocCE9bnVsbCl7bS5kPXAK
-cz1wLmIKbz1zLmluZGV4Cm49bytzWzBdLmxlbmd0aAppZihvPT09bil7aWYocS5iLnVuaWNvZGUpe3M9
-bS5jCnE9cysxCmlmKHE8cil7cz1DLnhCLk8obCxzKQppZihzPj01NTI5NiYmczw9NTYzMTkpe3M9Qy54
-Qi5PKGwscSkKcz1zPj01NjMyMCYmczw9NTczNDN9ZWxzZSBzPSExfWVsc2Ugcz0hMX1lbHNlIHM9ITEK
-bj0ocz9uKzE6bikrMX1tLmM9bgpyZXR1cm4hMH19bS5iPW0uZD1udWxsCnJldHVybiExfSwKJGlBbjox
-fQpILnRRLnByb3RvdHlwZT17CnE6ZnVuY3Rpb24oYSxiKXtILnVQKGIpCmlmKGIhPT0wKUgudihQLk83
-KGIsbnVsbCkpCnJldHVybiB0aGlzLmN9LAokaU9kOjF9CkgudW4ucHJvdG90eXBlPXsKZ206ZnVuY3Rp
-b24oYSl7cmV0dXJuIG5ldyBILlNkKHRoaXMuYSx0aGlzLmIsdGhpcy5jKX19CkguU2QucHJvdG90eXBl
-PXsKRjpmdW5jdGlvbigpe3ZhciBzLHIscT10aGlzLHA9cS5jLG89cS5iLG49by5sZW5ndGgsbT1xLmEs
-bD1tLmxlbmd0aAppZihwK24+bCl7cS5kPW51bGwKcmV0dXJuITF9cz1tLmluZGV4T2YobyxwKQppZihz
-PDApe3EuYz1sKzEKcS5kPW51bGwKcmV0dXJuITF9cj1zK24KcS5kPW5ldyBILnRRKHMsbykKcS5jPXI9
-PT1xLmM/cisxOnIKcmV0dXJuITB9LApnbDpmdW5jdGlvbigpe3ZhciBzPXRoaXMuZApzLnRvU3RyaW5n
-CnJldHVybiBzfSwKJGlBbjoxfQpILkVULnByb3RvdHlwZT17JGlFVDoxLCRpQVM6MX0KSC5MWi5wcm90
-b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gYS5sZW5ndGh9LAokaVhqOjF9CkguRGcucHJvdG90
-eXBlPXsKcTpmdW5jdGlvbihhLGIpe0gudVAoYikKSC5vZChiLGEsYS5sZW5ndGgpCnJldHVybiBhW2Jd
-fSwKWTU6ZnVuY3Rpb24oYSxiLGMpe0guR0goYykKSC5vZChiLGEsYS5sZW5ndGgpCmFbYl09Y30sCiRp
-YlE6MSwKJGljWDoxLAokaXpNOjF9CkguUGcucHJvdG90eXBlPXsKWTU6ZnVuY3Rpb24oYSxiLGMpe0gu
-dVAoYykKSC5vZChiLGEsYS5sZW5ndGgpCmFbYl09Y30sCiRpYlE6MSwKJGljWDoxLAokaXpNOjF9Ckgu
-eGoucHJvdG90eXBlPXsKcTpmdW5jdGlvbihhLGIpe0gudVAoYikKSC5vZChiLGEsYS5sZW5ndGgpCnJl
-dHVybiBhW2JdfX0KSC5kRS5wcm90b3R5cGU9ewpxOmZ1bmN0aW9uKGEsYil7SC51UChiKQpILm9kKGIs
-YSxhLmxlbmd0aCkKcmV0dXJuIGFbYl19fQpILlpBLnByb3RvdHlwZT17CnE6ZnVuY3Rpb24oYSxiKXtI
-LnVQKGIpCkgub2QoYixhLGEubGVuZ3RoKQpyZXR1cm4gYVtiXX19CkguZFQucHJvdG90eXBlPXsKcTpm
-dW5jdGlvbihhLGIpe0gudVAoYikKSC5vZChiLGEsYS5sZW5ndGgpCnJldHVybiBhW2JdfX0KSC5QcS5w
+LDI+IikpfSwKYks6ZnVuY3Rpb24oYSxiLGMpe2lmKHQuZC5iKGEpKXtQLmsxKGIsImNvdW50IikKcmV0
+dXJuIG5ldyBILmQ1KGEsYixjLkMoImQ1PDA+IikpfVAuazEoYiwiY291bnQiKQpyZXR1cm4gbmV3IEgu
+QU0oYSxiLGMuQygiQU08MD4iKSl9LApXcDpmdW5jdGlvbigpe3JldHVybiBuZXcgUC5saigiTm8gZWxl
+bWVudCIpfSwKQW06ZnVuY3Rpb24oKXtyZXR1cm4gbmV3IFAubGooIlRvbyBtYW55IGVsZW1lbnRzIil9
+LAphcjpmdW5jdGlvbigpe3JldHVybiBuZXcgUC5saigiVG9vIGZldyBlbGVtZW50cyIpfSwKQlI6ZnVu
+Y3Rpb24gQlIoKXt9LApFNzpmdW5jdGlvbiBFNyhhLGIpe3RoaXMuYT1hCnRoaXMuJHRpPWJ9LApaeTpm
+dW5jdGlvbiBaeShhLGIpe3RoaXMuYT1hCnRoaXMuJHRpPWJ9LApvbDpmdW5jdGlvbiBvbChhLGIpe3Ro
+aXMuYT1hCnRoaXMuJHRpPWJ9LApVcTpmdW5jdGlvbiBVcSgpe30sCmpWOmZ1bmN0aW9uIGpWKGEsYil7
+dGhpcy5hPWEKdGhpcy4kdGk9Yn0sCm46ZnVuY3Rpb24gbihhKXt0aGlzLmE9YX0sCnIzOmZ1bmN0aW9u
+IHIzKGEpe3RoaXMuYT1hfSwKcWo6ZnVuY3Rpb24gcWooYSl7dGhpcy5hPWF9LApHTTpmdW5jdGlvbiBH
+TShhLGIpe3RoaXMuYT1hCnRoaXMuJHRpPWJ9LApiUTpmdW5jdGlvbiBiUSgpe30sCmFMOmZ1bmN0aW9u
+IGFMKCl7fSwKbkg6ZnVuY3Rpb24gbkgoYSxiLGMsZCl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9
+YwpfLiR0aT1kfSwKYTc6ZnVuY3Rpb24gYTcoYSxiLGMpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5j
+PTAKXy5kPW51bGwKXy4kdGk9Y30sCmkxOmZ1bmN0aW9uIGkxKGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9
+Ygp0aGlzLiR0aT1jfSwKeHk6ZnVuY3Rpb24geHkoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMu
+JHRpPWN9LApNSDpmdW5jdGlvbiBNSChhLGIsYyl7dmFyIF89dGhpcwpfLmE9bnVsbApfLmI9YQpfLmM9
+YgpfLiR0aT1jfSwKbEo6ZnVuY3Rpb24gbEooYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuJHRp
+PWN9LApVNTpmdW5jdGlvbiBVNShhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy4kdGk9Y30sClNP
+OmZ1bmN0aW9uIFNPKGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLiR0aT1jfSwKQU06ZnVuY3Rp
+b24gQU0oYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuJHRpPWN9LApkNTpmdW5jdGlvbiBkNShh
+LGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy4kdGk9Y30sClUxOmZ1bmN0aW9uIFUxKGEsYixjKXt0
+aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLiR0aT1jfSwKTUI6ZnVuY3Rpb24gTUIoYSl7dGhpcy4kdGk9YX0s
+CkZ1OmZ1bmN0aW9uIEZ1KGEpe3RoaXMuJHRpPWF9LAp1NjpmdW5jdGlvbiB1NihhLGIpe3RoaXMuYT1h
+CnRoaXMuJHRpPWJ9LApKQjpmdW5jdGlvbiBKQihhLGIpe3RoaXMuYT1hCnRoaXMuJHRpPWJ9LApTVTpm
+dW5jdGlvbiBTVSgpe30sClJlOmZ1bmN0aW9uIFJlKCl7fSwKdzI6ZnVuY3Rpb24gdzIoKXt9LAp3djpm
+dW5jdGlvbiB3dihhKXt0aGlzLmE9YX0sClFDOmZ1bmN0aW9uIFFDKCl7fSwKZGM6ZnVuY3Rpb24oKXt0
+aHJvdyBILmIoUC5MNCgiQ2Fubm90IG1vZGlmeSB1bm1vZGlmaWFibGUgTWFwIikpfSwKTlE6ZnVuY3Rp
+b24oYSl7dmFyIHMscj1ILkpnKGEpCmlmKHIhPW51bGwpcmV0dXJuIHIKcz0ibWluaWZpZWQ6IithCnJl
+dHVybiBzfSwKd1Y6ZnVuY3Rpb24oYSxiKXt2YXIgcwppZihiIT1udWxsKXtzPWIueAppZihzIT1udWxs
+KXJldHVybiBzfXJldHVybiB0LmFVLmIoYSl9LApFajpmdW5jdGlvbihhKXt2YXIgcwppZih0eXBlb2Yg
+YT09InN0cmluZyIpcmV0dXJuIGEKaWYodHlwZW9mIGE9PSJudW1iZXIiKXtpZihhIT09MClyZXR1cm4i
+IithfWVsc2UgaWYoITA9PT1hKXJldHVybiJ0cnVlIgplbHNlIGlmKCExPT09YSlyZXR1cm4iZmFsc2Ui
+CmVsc2UgaWYoYT09bnVsbClyZXR1cm4ibnVsbCIKcz1KLmooYSkKaWYodHlwZW9mIHMhPSJzdHJpbmci
+KXRocm93IEguYihILnRMKGEpKQpyZXR1cm4gc30sCmVROmZ1bmN0aW9uKGEpe3ZhciBzPWEuJGlkZW50
+aXR5SGFzaAppZihzPT1udWxsKXtzPU1hdGgucmFuZG9tKCkqMHgzZmZmZmZmZnwwCmEuJGlkZW50aXR5
+SGFzaD1zfXJldHVybiBzfSwKSHA6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEscCxvLG4sbT1udWxsCmlm
+KHR5cGVvZiBhIT0ic3RyaW5nIilILnYoSC50TChhKSkKcz0vXlxzKlsrLV0/KCgweFthLWYwLTldKyl8
+KFxkKyl8KFthLXowLTldKykpXHMqJC9pLmV4ZWMoYSkKaWYocz09bnVsbClyZXR1cm4gbQppZigzPj1z
+Lmxlbmd0aClyZXR1cm4gSC5PSChzLDMpCnI9c1szXQppZihiPT1udWxsKXtpZihyIT1udWxsKXJldHVy
+biBwYXJzZUludChhLDEwKQppZihzWzJdIT1udWxsKXJldHVybiBwYXJzZUludChhLDE2KQpyZXR1cm4g
+bX1pZihiPDJ8fGI+MzYpdGhyb3cgSC5iKFAuVEUoYiwyLDM2LCJyYWRpeCIsbSkpCmlmKGI9PT0xMCYm
+ciE9bnVsbClyZXR1cm4gcGFyc2VJbnQoYSwxMCkKaWYoYjwxMHx8cj09bnVsbCl7cT1iPD0xMD80Nyti
+Ojg2K2IKcD1zWzFdCmZvcihvPXAubGVuZ3RoLG49MDtuPG87KytuKWlmKChDLnhCLlcocCxuKXwzMik+
+cSlyZXR1cm4gbX1yZXR1cm4gcGFyc2VJbnQoYSxiKX0sCk06ZnVuY3Rpb24oYSl7cmV0dXJuIEguSDUo
+YSl9LApINTpmdW5jdGlvbihhKXt2YXIgcyxyLHEscAppZihhIGluc3RhbmNlb2YgUC5NaClyZXR1cm4g
+SC5kbShILnooYSksbnVsbCkKaWYoSi5pYShhKT09PUMuT2t8fHQuYkouYihhKSl7cz1DLk80KGEpCnI9
+cyE9PSJPYmplY3QiJiZzIT09IiIKaWYocilyZXR1cm4gcwpxPWEuY29uc3RydWN0b3IKaWYodHlwZW9m
+IHE9PSJmdW5jdGlvbiIpe3A9cS5uYW1lCmlmKHR5cGVvZiBwPT0ic3RyaW5nIilyPXAhPT0iT2JqZWN0
+IiYmcCE9PSIiCmVsc2Ugcj0hMQppZihyKXJldHVybiBwfX1yZXR1cm4gSC5kbShILnooYSksbnVsbCl9
+LApNMDpmdW5jdGlvbigpe2lmKCEhc2VsZi5sb2NhdGlvbilyZXR1cm4gc2VsZi5sb2NhdGlvbi5ocmVm
+CnJldHVybiBudWxsfSwKVks6ZnVuY3Rpb24oYSl7dmFyIHMscixxLHAsbz1hLmxlbmd0aAppZihvPD01
+MDApcmV0dXJuIFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkobnVsbCxhKQpmb3Iocz0iIixyPTA7cjxv
+O3I9cSl7cT1yKzUwMApwPXE8bz9xOm8Kcys9U3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShudWxsLGEu
+c2xpY2UocixwKSl9cmV0dXJuIHN9LApDcTpmdW5jdGlvbihhKXt2YXIgcyxyLHEscD1ILlZNKFtdLHQu
+YSkKZm9yKHM9YS5sZW5ndGgscj0wO3I8YS5sZW5ndGg7YS5sZW5ndGg9PT1zfHwoMCxILmxrKShhKSwr
+K3Ipe3E9YVtyXQppZighSC5vayhxKSl0aHJvdyBILmIoSC50TChxKSkKaWYocTw9NjU1MzUpQy5ObS5p
+KHAscSkKZWxzZSBpZihxPD0xMTE0MTExKXtDLk5tLmkocCw1NTI5NisoQy5qbi53RyhxLTY1NTM2LDEw
+KSYxMDIzKSkKQy5ObS5pKHAsNTYzMjArKHEmMTAyMykpfWVsc2UgdGhyb3cgSC5iKEgudEwocSkpfXJl
+dHVybiBILlZLKHApfSwKZVQ6ZnVuY3Rpb24oYSl7dmFyIHMscixxCmZvcihzPWEubGVuZ3RoLHI9MDty
+PHM7KytyKXtxPWFbcl0KaWYoIUgub2socSkpdGhyb3cgSC5iKEgudEwocSkpCmlmKHE8MCl0aHJvdyBI
+LmIoSC50TChxKSkKaWYocT42NTUzNSlyZXR1cm4gSC5DcShhKX1yZXR1cm4gSC5WSyhhKX0sCmZ3OmZ1
+bmN0aW9uKGEsYixjKXt2YXIgcyxyLHEscAppZihjPD01MDAmJmI9PT0wJiZjPT09YS5sZW5ndGgpcmV0
+dXJuIFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkobnVsbCxhKQpmb3Iocz1iLHI9IiI7czxjO3M9cSl7
+cT1zKzUwMApwPXE8Yz9xOmMKcis9U3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShudWxsLGEuc3ViYXJy
+YXkocyxwKSl9cmV0dXJuIHJ9LApMdzpmdW5jdGlvbihhKXt2YXIgcwppZigwPD1hKXtpZihhPD02NTUz
+NSlyZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZShhKQppZihhPD0xMTE0MTExKXtzPWEtNjU1MzYKcmV0
+dXJuIFN0cmluZy5mcm9tQ2hhckNvZGUoKEMuam4ud0cocywxMCl8NTUyOTYpPj4+MCxzJjEwMjN8NTYz
+MjApfX10aHJvdyBILmIoUC5URShhLDAsMTExNDExMSxudWxsLG51bGwpKX0sCm8yOmZ1bmN0aW9uKGEp
+e2lmKGEuZGF0ZT09PXZvaWQgMClhLmRhdGU9bmV3IERhdGUoYS5hKQpyZXR1cm4gYS5kYXRlfSwKdEo6
+ZnVuY3Rpb24oYSl7dmFyIHM9SC5vMihhKS5nZXRGdWxsWWVhcigpKzAKcmV0dXJuIHN9LApOUzpmdW5j
+dGlvbihhKXt2YXIgcz1ILm8yKGEpLmdldE1vbnRoKCkrMQpyZXR1cm4gc30sCmpBOmZ1bmN0aW9uKGEp
+e3ZhciBzPUgubzIoYSkuZ2V0RGF0ZSgpKzAKcmV0dXJuIHN9LApJWDpmdW5jdGlvbihhKXt2YXIgcz1I
+Lm8yKGEpLmdldEhvdXJzKCkrMApyZXR1cm4gc30sCmNoOmZ1bmN0aW9uKGEpe3ZhciBzPUgubzIoYSku
+Z2V0TWludXRlcygpKzAKcmV0dXJuIHN9LApKZDpmdW5jdGlvbihhKXt2YXIgcz1ILm8yKGEpLmdldFNl
+Y29uZHMoKSswCnJldHVybiBzfSwKbzE6ZnVuY3Rpb24oYSl7dmFyIHM9SC5vMihhKS5nZXRNaWxsaXNl
+Y29uZHMoKSswCnJldHVybiBzfSwKem86ZnVuY3Rpb24oYSxiLGMpe3ZhciBzLHIscT17fQpxLmE9MApz
+PVtdCnI9W10KcS5hPWIubGVuZ3RoCkMuTm0uRlYocyxiKQpxLmI9IiIKaWYoYyE9bnVsbCYmYy5hIT09
+MCljLksoMCxuZXcgSC5DaihxLHIscykpCiIiK3EuYQpyZXR1cm4gSi5KeShhLG5ldyBILkxJKEMuVGUs
+MCxzLHIsMCkpfSwKRWs6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzLHIscSxwCmlmKGIgaW5zdGFuY2VvZiBB
+cnJheSlzPWM9PW51bGx8fGMuYT09PTAKZWxzZSBzPSExCmlmKHMpe3I9YgpxPXIubGVuZ3RoCmlmKHE9
+PT0wKXtpZighIWEuJDApcmV0dXJuIGEuJDAoKX1lbHNlIGlmKHE9PT0xKXtpZighIWEuJDEpcmV0dXJu
+IGEuJDEoclswXSl9ZWxzZSBpZihxPT09Mil7aWYoISFhLiQyKXJldHVybiBhLiQyKHJbMF0sclsxXSl9
+ZWxzZSBpZihxPT09Myl7aWYoISFhLiQzKXJldHVybiBhLiQzKHJbMF0sclsxXSxyWzJdKX1lbHNlIGlm
+KHE9PT00KXtpZighIWEuJDQpcmV0dXJuIGEuJDQoclswXSxyWzFdLHJbMl0sclszXSl9ZWxzZSBpZihx
+PT09NSlpZighIWEuJDUpcmV0dXJuIGEuJDUoclswXSxyWzFdLHJbMl0sclszXSxyWzRdKQpwPWFbIiIr
+IiQiK3FdCmlmKHAhPW51bGwpcmV0dXJuIHAuYXBwbHkoYSxyKX1yZXR1cm4gSC5lMShhLGIsYyl9LApl
+MTpmdW5jdGlvbihhLGIsYyl7dmFyIHMscixxLHAsbyxuLG0sbCxrLGosaT1iIGluc3RhbmNlb2YgQXJy
+YXk/YjpQLkNIKGIsITAsdC56KSxoPWkubGVuZ3RoLGc9YS4kUgppZihoPGcpcmV0dXJuIEguem8oYSxp
+LGMpCnM9YS4kRApyPXM9PW51bGwKcT0hcj9zKCk6bnVsbApwPUouaWEoYSkKbz1wLiRDCmlmKHR5cGVv
+ZiBvPT0ic3RyaW5nIilvPXBbb10KaWYocil7aWYoYyE9bnVsbCYmYy5hIT09MClyZXR1cm4gSC56byhh
+LGksYykKaWYoaD09PWcpcmV0dXJuIG8uYXBwbHkoYSxpKQpyZXR1cm4gSC56byhhLGksYyl9aWYocSBp
+bnN0YW5jZW9mIEFycmF5KXtpZihjIT1udWxsJiZjLmEhPT0wKXJldHVybiBILnpvKGEsaSxjKQppZiho
+PmcrcS5sZW5ndGgpcmV0dXJuIEguem8oYSxpLG51bGwpCkMuTm0uRlYoaSxxLnNsaWNlKGgtZykpCnJl
+dHVybiBvLmFwcGx5KGEsaSl9ZWxzZXtpZihoPmcpcmV0dXJuIEguem8oYSxpLGMpCm49T2JqZWN0Lmtl
+eXMocSkKaWYoYz09bnVsbClmb3Iocj1uLmxlbmd0aCxtPTA7bTxuLmxlbmd0aDtuLmxlbmd0aD09PXJ8
+fCgwLEgubGspKG4pLCsrbSl7bD1xW0guaChuW21dKV0KaWYoQy5Odj09PWwpcmV0dXJuIEguem8oYSxp
+LGMpCkMuTm0uaShpLGwpfWVsc2V7Zm9yKHI9bi5sZW5ndGgsaz0wLG09MDttPG4ubGVuZ3RoO24ubGVu
+Z3RoPT09cnx8KDAsSC5saykobiksKyttKXtqPUguaChuW21dKQppZihjLng0KGopKXsrK2sKQy5ObS5p
+KGksYy5xKDAsaikpfWVsc2V7bD1xW2pdCmlmKEMuTnY9PT1sKXJldHVybiBILnpvKGEsaSxjKQpDLk5t
+LmkoaSxsKX19aWYoayE9PWMuYSlyZXR1cm4gSC56byhhLGksYyl9cmV0dXJuIG8uYXBwbHkoYSxpKX19
+LApwWTpmdW5jdGlvbihhKXt0aHJvdyBILmIoSC50TChhKSl9LApPSDpmdW5jdGlvbihhLGIpe2lmKGE9
+PW51bGwpSi5IbShhKQp0aHJvdyBILmIoSC5IWShhLGIpKX0sCkhZOmZ1bmN0aW9uKGEsYil7dmFyIHMs
+cixxPSJpbmRleCIKaWYoIUgub2soYikpcmV0dXJuIG5ldyBQLnUoITAsYixxLG51bGwpCnM9SC51UChK
+LkhtKGEpKQppZighKGI8MCkpe2lmKHR5cGVvZiBzIT09Im51bWJlciIpcmV0dXJuIEgucFkocykKcj1i
+Pj1zfWVsc2Ugcj0hMAppZihyKXJldHVybiBQLkNmKGIsYSxxLG51bGwscykKcmV0dXJuIFAuTzcoYixx
+KX0sCkR1OmZ1bmN0aW9uKGEsYixjKXtpZihhPmMpcmV0dXJuIFAuVEUoYSwwLGMsInN0YXJ0IixudWxs
+KQppZihiIT1udWxsKWlmKGI8YXx8Yj5jKXJldHVybiBQLlRFKGIsYSxjLCJlbmQiLG51bGwpCnJldHVy
+biBuZXcgUC51KCEwLGIsImVuZCIsbnVsbCl9LAp0TDpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFAudSgh
+MCxhLG51bGwsbnVsbCl9LApiOmZ1bmN0aW9uKGEpe3ZhciBzLHIKaWYoYT09bnVsbClhPW5ldyBQLkYo
+KQpzPW5ldyBFcnJvcigpCnMuZGFydEV4Y2VwdGlvbj1hCnI9SC54CmlmKCJkZWZpbmVQcm9wZXJ0eSIg
+aW4gT2JqZWN0KXtPYmplY3QuZGVmaW5lUHJvcGVydHkocywibWVzc2FnZSIse2dldDpyfSkKcy5uYW1l
+PSIifWVsc2Ugcy50b1N0cmluZz1yCnJldHVybiBzfSwKeDpmdW5jdGlvbigpe3JldHVybiBKLmoodGhp
+cy5kYXJ0RXhjZXB0aW9uKX0sCnY6ZnVuY3Rpb24oYSl7dGhyb3cgSC5iKGEpfSwKbGs6ZnVuY3Rpb24o
+YSl7dGhyb3cgSC5iKFAuYTQoYSkpfSwKY006ZnVuY3Rpb24oYSl7dmFyIHMscixxLHAsbyxuCmE9SC5l
+QShhLnJlcGxhY2UoU3RyaW5nKHt9KSwiJHJlY2VpdmVyJCIpKQpzPWEubWF0Y2goL1xcXCRbYS16QS1a
+XStcXFwkL2cpCmlmKHM9PW51bGwpcz1ILlZNKFtdLHQucykKcj1zLmluZGV4T2YoIlxcJGFyZ3VtZW50
+c1xcJCIpCnE9cy5pbmRleE9mKCJcXCRhcmd1bWVudHNFeHByXFwkIikKcD1zLmluZGV4T2YoIlxcJGV4
+cHJcXCQiKQpvPXMuaW5kZXhPZigiXFwkbWV0aG9kXFwkIikKbj1zLmluZGV4T2YoIlxcJHJlY2VpdmVy
+XFwkIikKcmV0dXJuIG5ldyBILmY5KGEucmVwbGFjZShuZXcgUmVnRXhwKCJcXFxcXFwkYXJndW1lbnRz
+XFxcXFxcJCIsImciKSwiKCg/Onh8W154XSkqKSIpLnJlcGxhY2UobmV3IFJlZ0V4cCgiXFxcXFxcJGFy
+Z3VtZW50c0V4cHJcXFxcXFwkIiwiZyIpLCIoKD86eHxbXnhdKSopIikucmVwbGFjZShuZXcgUmVnRXhw
+KCJcXFxcXFwkZXhwclxcXFxcXCQiLCJnIiksIigoPzp4fFteeF0pKikiKS5yZXBsYWNlKG5ldyBSZWdF
+eHAoIlxcXFxcXCRtZXRob2RcXFxcXFwkIiwiZyIpLCIoKD86eHxbXnhdKSopIikucmVwbGFjZShuZXcg
+UmVnRXhwKCJcXFxcXFwkcmVjZWl2ZXJcXFxcXFwkIiwiZyIpLCIoKD86eHxbXnhdKSopIikscixxLHAs
+byxuKX0sClM3OmZ1bmN0aW9uKGEpe3JldHVybiBmdW5jdGlvbigkZXhwciQpe3ZhciAkYXJndW1lbnRz
+RXhwciQ9IiRhcmd1bWVudHMkIgp0cnl7JGV4cHIkLiRtZXRob2QkKCRhcmd1bWVudHNFeHByJCl9Y2F0
+Y2gocyl7cmV0dXJuIHMubWVzc2FnZX19KGEpfSwKTWo6ZnVuY3Rpb24oYSl7cmV0dXJuIGZ1bmN0aW9u
+KCRleHByJCl7dHJ5eyRleHByJC4kbWV0aG9kJH1jYXRjaChzKXtyZXR1cm4gcy5tZXNzYWdlfX0oYSl9
+LApUMzpmdW5jdGlvbihhLGIpe3ZhciBzPWI9PW51bGwscj1zP251bGw6Yi5tZXRob2QKcmV0dXJuIG5l
+dyBILmF6KGEscixzP251bGw6Yi5yZWNlaXZlcil9LApSdTpmdW5jdGlvbihhKXtpZihhPT1udWxsKXJl
+dHVybiBuZXcgSC50ZShhKQppZihhIGluc3RhbmNlb2YgSC5icSlyZXR1cm4gSC50VyhhLGEuYSkKaWYo
+dHlwZW9mIGEhPT0ib2JqZWN0IilyZXR1cm4gYQppZigiZGFydEV4Y2VwdGlvbiIgaW4gYSlyZXR1cm4g
+SC50VyhhLGEuZGFydEV4Y2VwdGlvbikKcmV0dXJuIEgudGwoYSl9LAp0VzpmdW5jdGlvbihhLGIpe2lm
+KHQuci5iKGIpKWlmKGIuJHRocm93bkpzRXJyb3I9PW51bGwpYi4kdGhyb3duSnNFcnJvcj1hCnJldHVy
+biBifSwKdGw6ZnVuY3Rpb24oYSl7dmFyIHMscixxLHAsbyxuLG0sbCxrLGosaSxoLGcsZixlPW51bGwK
+aWYoISgibWVzc2FnZSIgaW4gYSkpcmV0dXJuIGEKcz1hLm1lc3NhZ2UKaWYoIm51bWJlciIgaW4gYSYm
+dHlwZW9mIGEubnVtYmVyPT0ibnVtYmVyIil7cj1hLm51bWJlcgpxPXImNjU1MzUKaWYoKEMuam4ud0co
+ciwxNikmODE5MSk9PT0xMClzd2l0Y2gocSl7Y2FzZSA0Mzg6cmV0dXJuIEgudFcoYSxILlQzKEguRWoo
+cykrIiAoRXJyb3IgIitxKyIpIixlKSkKY2FzZSA0NDU6Y2FzZSA1MDA3OnA9SC5FaihzKSsiIChFcnJv
+ciAiK3ErIikiCnJldHVybiBILnRXKGEsbmV3IEguVzAocCxlKSl9fWlmKGEgaW5zdGFuY2VvZiBUeXBl
+RXJyb3Ipe289JC5TbigpCm49JC5scSgpCm09JC5OOSgpCmw9JC5pSSgpCms9JC5VTigpCmo9JC5aaCgp
+Cmk9JC5yTigpCiQuYzMoKQpoPSQuSEsoKQpnPSQucjEoKQpmPW8ucVMocykKaWYoZiE9bnVsbClyZXR1
+cm4gSC50VyhhLEguVDMoSC5oKHMpLGYpKQplbHNle2Y9bi5xUyhzKQppZihmIT1udWxsKXtmLm1ldGhv
+ZD0iY2FsbCIKcmV0dXJuIEgudFcoYSxILlQzKEguaChzKSxmKSl9ZWxzZXtmPW0ucVMocykKaWYoZj09
+bnVsbCl7Zj1sLnFTKHMpCmlmKGY9PW51bGwpe2Y9ay5xUyhzKQppZihmPT1udWxsKXtmPWoucVMocykK
+aWYoZj09bnVsbCl7Zj1pLnFTKHMpCmlmKGY9PW51bGwpe2Y9bC5xUyhzKQppZihmPT1udWxsKXtmPWgu
+cVMocykKaWYoZj09bnVsbCl7Zj1nLnFTKHMpCnA9ZiE9bnVsbH1lbHNlIHA9ITB9ZWxzZSBwPSEwfWVs
+c2UgcD0hMH1lbHNlIHA9ITB9ZWxzZSBwPSEwfWVsc2UgcD0hMH1lbHNlIHA9ITAKaWYocCl7SC5oKHMp
+CnJldHVybiBILnRXKGEsbmV3IEguVzAocyxmPT1udWxsP2U6Zi5tZXRob2QpKX19fXJldHVybiBILnRX
+KGEsbmV3IEgudlYodHlwZW9mIHM9PSJzdHJpbmciP3M6IiIpKX1pZihhIGluc3RhbmNlb2YgUmFuZ2VF
+cnJvcil7aWYodHlwZW9mIHM9PSJzdHJpbmciJiZzLmluZGV4T2YoImNhbGwgc3RhY2siKSE9PS0xKXJl
+dHVybiBuZXcgUC5LWSgpCnM9ZnVuY3Rpb24oYil7dHJ5e3JldHVybiBTdHJpbmcoYil9Y2F0Y2goZCl7
+fXJldHVybiBudWxsfShhKQpyZXR1cm4gSC50VyhhLG5ldyBQLnUoITEsZSxlLHR5cGVvZiBzPT0ic3Ry
+aW5nIj9zLnJlcGxhY2UoL15SYW5nZUVycm9yOlxzKi8sIiIpOnMpKX1pZih0eXBlb2YgSW50ZXJuYWxF
+cnJvcj09ImZ1bmN0aW9uIiYmYSBpbnN0YW5jZW9mIEludGVybmFsRXJyb3IpaWYodHlwZW9mIHM9PSJz
+dHJpbmciJiZzPT09InRvbyBtdWNoIHJlY3Vyc2lvbiIpcmV0dXJuIG5ldyBQLktZKCkKcmV0dXJuIGF9
+LAp0czpmdW5jdGlvbihhKXt2YXIgcwppZihhIGluc3RhbmNlb2YgSC5icSlyZXR1cm4gYS5iCmlmKGE9
+PW51bGwpcmV0dXJuIG5ldyBILlhPKGEpCnM9YS4kY2FjaGVkVHJhY2UKaWYocyE9bnVsbClyZXR1cm4g
+cwpyZXR1cm4gYS4kY2FjaGVkVHJhY2U9bmV3IEguWE8oYSl9LApCNzpmdW5jdGlvbihhLGIpe3ZhciBz
+LHIscSxwPWEubGVuZ3RoCmZvcihzPTA7czxwO3M9cSl7cj1zKzEKcT1yKzEKYi5ZNSgwLGFbc10sYVty
+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
+eWoKaWYodHlwZW9mIHAhPT0ibnVtYmVyIilyZXR1cm4gcC5oKCkKJC55aj1wKzEKbj0ic2VsZiIrcApw
+PSJyZXR1cm4gZnVuY3Rpb24oKXt2YXIgIituKyIgPSB0aGlzLiIKbz0kLm1KCnJldHVybiBuZXcgRnVu
+Y3Rpb24ocCsobz09bnVsbD8kLm1KPUguRTIoInNlbGYiKTpvKSsiO3JldHVybiAiK24rIi4iK0guRWoo
+cykrIigpO30iKSgpfW09ImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6Ii5zcGxpdCgiIikuc3BsaWNl
+KDAscikuam9pbigiLCIpCnA9JC55agppZih0eXBlb2YgcCE9PSJudW1iZXIiKXJldHVybiBwLmgoKQok
+LnlqPXArMQptKz1wCnA9InJldHVybiBmdW5jdGlvbigiK20rIil7cmV0dXJuIHRoaXMuIgpvPSQubUoK
+cmV0dXJuIG5ldyBGdW5jdGlvbihwKyhvPT1udWxsPyQubUo9SC5FMigic2VsZiIpOm8pKyIuIitILkVq
+KHMpKyIoIittKyIpO30iKSgpfSwKWjQ6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHM9SC5EVixyPUgueVMK
+c3dpdGNoKGI/LTE6YSl7Y2FzZSAwOnRocm93IEguYihuZXcgSC5FcSgiSW50ZXJjZXB0ZWQgZnVuY3Rp
+b24gd2l0aCBubyBhcmd1bWVudHMuIikpCmNhc2UgMTpyZXR1cm4gZnVuY3Rpb24oZSxmLGcpe3JldHVy
+biBmdW5jdGlvbigpe3JldHVybiBmKHRoaXMpW2VdKGcodGhpcykpfX0oYyxzLHIpCmNhc2UgMjpyZXR1
+cm4gZnVuY3Rpb24oZSxmLGcpe3JldHVybiBmdW5jdGlvbihoKXtyZXR1cm4gZih0aGlzKVtlXShnKHRo
+aXMpLGgpfX0oYyxzLHIpCmNhc2UgMzpyZXR1cm4gZnVuY3Rpb24oZSxmLGcpe3JldHVybiBmdW5jdGlv
+bihoLGkpe3JldHVybiBmKHRoaXMpW2VdKGcodGhpcyksaCxpKX19KGMscyxyKQpjYXNlIDQ6cmV0dXJu
+IGZ1bmN0aW9uKGUsZixnKXtyZXR1cm4gZnVuY3Rpb24oaCxpLGope3JldHVybiBmKHRoaXMpW2VdKGco
+dGhpcyksaCxpLGopfX0oYyxzLHIpCmNhc2UgNTpyZXR1cm4gZnVuY3Rpb24oZSxmLGcpe3JldHVybiBm
+dW5jdGlvbihoLGksaixrKXtyZXR1cm4gZih0aGlzKVtlXShnKHRoaXMpLGgsaSxqLGspfX0oYyxzLHIp
+CmNhc2UgNjpyZXR1cm4gZnVuY3Rpb24oZSxmLGcpe3JldHVybiBmdW5jdGlvbihoLGksaixrLGwpe3Jl
+dHVybiBmKHRoaXMpW2VdKGcodGhpcyksaCxpLGosayxsKX19KGMscyxyKQpkZWZhdWx0OnJldHVybiBm
+dW5jdGlvbihlLGYsZyxoKXtyZXR1cm4gZnVuY3Rpb24oKXtoPVtnKHRoaXMpXQpBcnJheS5wcm90b3R5
+cGUucHVzaC5hcHBseShoLGFyZ3VtZW50cykKcmV0dXJuIGUuYXBwbHkoZih0aGlzKSxoKX19KGQscyxy
+KX19LApIZjpmdW5jdGlvbihhLGIpe3ZhciBzLHIscSxwLG8sbixtLGw9JC5tSgppZihsPT1udWxsKWw9
+JC5tSj1ILkUyKCJzZWxmIikKcz0kLlA0CmlmKHM9PW51bGwpcz0kLlA0PUguRTIoInJlY2VpdmVyIikK
+cj1iLiRzdHViTmFtZQpxPWIubGVuZ3RoCnA9YVtyXQpvPWI9PW51bGw/cD09bnVsbDpiPT09cApuPSFv
+fHxxPj0yOAppZihuKXJldHVybiBILlo0KHEsIW8scixiKQppZihxPT09MSl7bz0icmV0dXJuIGZ1bmN0
+aW9uKCl7cmV0dXJuIHRoaXMuIitsKyIuIitILkVqKHIpKyIodGhpcy4iK3MrIik7IgpuPSQueWoKaWYo
+dHlwZW9mIG4hPT0ibnVtYmVyIilyZXR1cm4gbi5oKCkKJC55aj1uKzEKcmV0dXJuIG5ldyBGdW5jdGlv
+bihvK24rIn0iKSgpfW09ImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6Ii5zcGxpdCgiIikuc3BsaWNl
+KDAscS0xKS5qb2luKCIsIikKbz0icmV0dXJuIGZ1bmN0aW9uKCIrbSsiKXtyZXR1cm4gdGhpcy4iK2wr
+Ii4iK0guRWoocikrIih0aGlzLiIrcysiLCAiK20rIik7IgpuPSQueWoKaWYodHlwZW9mIG4hPT0ibnVt
+YmVyIilyZXR1cm4gbi5oKCkKJC55aj1uKzEKcmV0dXJuIG5ldyBGdW5jdGlvbihvK24rIn0iKSgpfSwK
+S3E6ZnVuY3Rpb24oYSxiLGMsZCxlLGYsZyl7cmV0dXJuIEguaUEoYSxiLGMsZCwhIWUsISFmLGcpfSwK
+VG46ZnVuY3Rpb24oYSxiKXtyZXR1cm4gSC5jRSh2LnR5cGVVbml2ZXJzZSxILnooYS5hKSxiKX0sClBX
+OmZ1bmN0aW9uKGEsYil7cmV0dXJuIEguY0Uodi50eXBlVW5pdmVyc2UsSC56KGEuYyksYil9LApEVjpm
+dW5jdGlvbihhKXtyZXR1cm4gYS5hfSwKeVM6ZnVuY3Rpb24oYSl7cmV0dXJuIGEuY30sCkUyOmZ1bmN0
+aW9uKGEpe3ZhciBzLHIscSxwPW5ldyBILnJUKCJzZWxmIiwidGFyZ2V0IiwicmVjZWl2ZXIiLCJuYW1l
+Iiksbz1KLkVwKE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKHApLHQuVykKZm9yKHM9by5sZW5ndGgs
+cj0wO3I8czsrK3Ipe3E9b1tyXQppZihwW3FdPT09YSlyZXR1cm4gcX10aHJvdyBILmIoUC54WSgiRmll
+bGQgbmFtZSAiK2ErIiBub3QgZm91bmQuIikpfSwKb1Q6ZnVuY3Rpb24oYSl7aWYoYT09bnVsbClILmZP
+KCJib29sZWFuIGV4cHJlc3Npb24gbXVzdCBub3QgYmUgbnVsbCIpCnJldHVybiBhfSwKZk86ZnVuY3Rp
+b24oYSl7dGhyb3cgSC5iKG5ldyBILmtZKGEpKX0sCmFnOmZ1bmN0aW9uKGEpe3Rocm93IEguYihuZXcg
+UC5jKGEpKX0sCllnOmZ1bmN0aW9uKGEpe3JldHVybiB2LmdldElzb2xhdGVUYWcoYSl9LApCbzpmdW5j
+dGlvbihhKXtyZXR1cm4gSC52KG5ldyBILm4oYSkpfSwKaXc6ZnVuY3Rpb24oYSxiLGMpe09iamVjdC5k
+ZWZpbmVQcm9wZXJ0eShhLGIse3ZhbHVlOmMsZW51bWVyYWJsZTpmYWxzZSx3cml0YWJsZTp0cnVlLGNv
+bmZpZ3VyYWJsZTp0cnVlfSl9LAp3MzpmdW5jdGlvbihhKXt2YXIgcyxyLHEscCxvLG49SC5oKCQuTkYu
+JDEoYSkpLG09JC5ud1tuXQppZihtIT1udWxsKXtPYmplY3QuZGVmaW5lUHJvcGVydHkoYSx2LmRpc3Bh
+dGNoUHJvcGVydHlOYW1lLHt2YWx1ZTptLGVudW1lcmFibGU6ZmFsc2Usd3JpdGFibGU6dHJ1ZSxjb25m
+aWd1cmFibGU6dHJ1ZX0pCnJldHVybiBtLml9cz0kLnZ2W25dCmlmKHMhPW51bGwpcmV0dXJuIHMKcj12
+LmludGVyY2VwdG9yc0J5VGFnW25dCmlmKHI9PW51bGwpe3E9SC5rKCQuVFguJDIoYSxuKSkKaWYocSE9
+bnVsbCl7bT0kLm53W3FdCmlmKG0hPW51bGwpe09iamVjdC5kZWZpbmVQcm9wZXJ0eShhLHYuZGlzcGF0
+Y2hQcm9wZXJ0eU5hbWUse3ZhbHVlOm0sZW51bWVyYWJsZTpmYWxzZSx3cml0YWJsZTp0cnVlLGNvbmZp
+Z3VyYWJsZTp0cnVlfSkKcmV0dXJuIG0uaX1zPSQudnZbcV0KaWYocyE9bnVsbClyZXR1cm4gcwpyPXYu
+aW50ZXJjZXB0b3JzQnlUYWdbcV0Kbj1xfX1pZihyPT1udWxsKXJldHVybiBudWxsCnM9ci5wcm90b3R5
+cGUKcD1uWzBdCmlmKHA9PT0iISIpe209SC5WYShzKQokLm53W25dPW0KT2JqZWN0LmRlZmluZVByb3Bl
+cnR5KGEsdi5kaXNwYXRjaFByb3BlcnR5TmFtZSx7dmFsdWU6bSxlbnVtZXJhYmxlOmZhbHNlLHdyaXRh
+YmxlOnRydWUsY29uZmlndXJhYmxlOnRydWV9KQpyZXR1cm4gbS5pfWlmKHA9PT0ifiIpeyQudnZbbl09
+cwpyZXR1cm4gc31pZihwPT09Ii0iKXtvPUguVmEocykKT2JqZWN0LmRlZmluZVByb3BlcnR5KE9iamVj
+dC5nZXRQcm90b3R5cGVPZihhKSx2LmRpc3BhdGNoUHJvcGVydHlOYW1lLHt2YWx1ZTpvLGVudW1lcmFi
+bGU6ZmFsc2Usd3JpdGFibGU6dHJ1ZSxjb25maWd1cmFibGU6dHJ1ZX0pCnJldHVybiBvLml9aWYocD09
+PSIrIilyZXR1cm4gSC5MYyhhLHMpCmlmKHA9PT0iKiIpdGhyb3cgSC5iKFAuU1kobikpCmlmKHYubGVh
+ZlRhZ3Nbbl09PT10cnVlKXtvPUguVmEocykKT2JqZWN0LmRlZmluZVByb3BlcnR5KE9iamVjdC5nZXRQ
+cm90b3R5cGVPZihhKSx2LmRpc3BhdGNoUHJvcGVydHlOYW1lLHt2YWx1ZTpvLGVudW1lcmFibGU6ZmFs
+c2Usd3JpdGFibGU6dHJ1ZSxjb25maWd1cmFibGU6dHJ1ZX0pCnJldHVybiBvLml9ZWxzZSByZXR1cm4g
+SC5MYyhhLHMpfSwKTGM6ZnVuY3Rpb24oYSxiKXt2YXIgcz1PYmplY3QuZ2V0UHJvdG90eXBlT2YoYSkK
+T2JqZWN0LmRlZmluZVByb3BlcnR5KHMsdi5kaXNwYXRjaFByb3BlcnR5TmFtZSx7dmFsdWU6Si5RdShi
+LHMsbnVsbCxudWxsKSxlbnVtZXJhYmxlOmZhbHNlLHdyaXRhYmxlOnRydWUsY29uZmlndXJhYmxlOnRy
+dWV9KQpyZXR1cm4gYn0sClZhOmZ1bmN0aW9uKGEpe3JldHVybiBKLlF1KGEsITEsbnVsbCwhIWEuJGlY
+ail9LApWRjpmdW5jdGlvbihhLGIsYyl7dmFyIHM9Yi5wcm90b3R5cGUKaWYodi5sZWFmVGFnc1thXT09
+PXRydWUpcmV0dXJuIEguVmEocykKZWxzZSByZXR1cm4gSi5RdShzLGMsbnVsbCxudWxsKX0sClhEOmZ1
+bmN0aW9uKCl7aWYoITA9PT0kLkJ2KXJldHVybgokLkJ2PSEwCkguWjEoKX0sCloxOmZ1bmN0aW9uKCl7
+dmFyIHMscixxLHAsbyxuLG0sbAokLm53PU9iamVjdC5jcmVhdGUobnVsbCkKJC52dj1PYmplY3QuY3Jl
+YXRlKG51bGwpCkgua08oKQpzPXYuaW50ZXJjZXB0b3JzQnlUYWcKcj1PYmplY3QuZ2V0T3duUHJvcGVy
+dHlOYW1lcyhzKQppZih0eXBlb2Ygd2luZG93IT0idW5kZWZpbmVkIil7d2luZG93CnE9ZnVuY3Rpb24o
+KXt9CmZvcihwPTA7cDxyLmxlbmd0aDsrK3Ape289cltwXQpuPSQueDcuJDEobykKaWYobiE9bnVsbCl7
+bT1ILlZGKG8sc1tvXSxuKQppZihtIT1udWxsKXtPYmplY3QuZGVmaW5lUHJvcGVydHkobix2LmRpc3Bh
+dGNoUHJvcGVydHlOYW1lLHt2YWx1ZTptLGVudW1lcmFibGU6ZmFsc2Usd3JpdGFibGU6dHJ1ZSxjb25m
+aWd1cmFibGU6dHJ1ZX0pCnEucHJvdG90eXBlPW59fX19Zm9yKHA9MDtwPHIubGVuZ3RoOysrcCl7bz1y
+W3BdCmlmKC9eW0EtWmEtel9dLy50ZXN0KG8pKXtsPXNbb10Kc1siISIrb109bApzWyJ+IitvXT1sCnNb
+Ii0iK29dPWwKc1siKyIrb109bApzWyIqIitvXT1sfX19LAprTzpmdW5jdGlvbigpe3ZhciBzLHIscSxw
+LG8sbixtPUMuWXEoKQptPUgudWQoQy5LVSxILnVkKEMuZlEsSC51ZChDLmk3LEgudWQoQy5pNyxILnVk
+KEMueGksSC51ZChDLmRrLEgudWQoQy53YihDLk80KSxtKSkpKSkpKQppZih0eXBlb2YgZGFydE5hdGl2
+ZURpc3BhdGNoSG9va3NUcmFuc2Zvcm1lciE9InVuZGVmaW5lZCIpe3M9ZGFydE5hdGl2ZURpc3BhdGNo
+SG9va3NUcmFuc2Zvcm1lcgppZih0eXBlb2Ygcz09ImZ1bmN0aW9uIilzPVtzXQppZihzLmNvbnN0cnVj
+dG9yPT1BcnJheSlmb3Iocj0wO3I8cy5sZW5ndGg7KytyKXtxPXNbcl0KaWYodHlwZW9mIHE9PSJmdW5j
+dGlvbiIpbT1xKG0pfHxtfX1wPW0uZ2V0VGFnCm89bS5nZXRVbmtub3duVGFnCm49bS5wcm90b3R5cGVG
+b3JUYWcKJC5ORj1uZXcgSC5kQyhwKQokLlRYPW5ldyBILndOKG8pCiQueDc9bmV3IEguVlgobil9LAp1
+ZDpmdW5jdGlvbihhLGIpe3JldHVybiBhKGIpfHxifSwKdjQ6ZnVuY3Rpb24oYSxiLGMsZCxlLGYpe3Zh
+ciBzPWI/Im0iOiIiLHI9Yz8iIjoiaSIscT1kPyJ1IjoiIixwPWU/InMiOiIiLG89Zj8iZyI6IiIsbj1m
+dW5jdGlvbihnLGgpe3RyeXtyZXR1cm4gbmV3IFJlZ0V4cChnLGgpfWNhdGNoKG0pe3JldHVybiBtfX0o
+YSxzK3IrcStwK28pCmlmKG4gaW5zdGFuY2VvZiBSZWdFeHApcmV0dXJuIG4KdGhyb3cgSC5iKFAucnIo
+IklsbGVnYWwgUmVnRXhwIHBhdHRlcm4gKCIrU3RyaW5nKG4pKyIpIixhLG51bGwpKX0sClNROmZ1bmN0
+aW9uKGEsYixjKXt2YXIgcwppZih0eXBlb2YgYj09InN0cmluZyIpcmV0dXJuIGEuaW5kZXhPZihiLGMp
+Pj0wCmVsc2UgaWYoYiBpbnN0YW5jZW9mIEguVlIpe3M9Qy54Qi55bihhLGMpCnJldHVybiBiLmIudGVz
+dChzKX1lbHNle3M9Si5GTChiLEMueEIueW4oYSxjKSkKcmV0dXJuIXMuZ2wwKHMpfX0sCkE0OmZ1bmN0
+aW9uKGEpe2lmKGEuaW5kZXhPZigiJCIsMCk+PTApcmV0dXJuIGEucmVwbGFjZSgvXCQvZywiJCQkJCIp
+CnJldHVybiBhfSwKZUE6ZnVuY3Rpb24oYSl7aWYoL1tbXF17fSgpKis/LlxcXiR8XS8udGVzdChhKSly
+ZXR1cm4gYS5yZXBsYWNlKC9bW1xde30oKSorPy5cXF4kfF0vZywiXFwkJiIpCnJldHVybiBhfSwKeXM6
+ZnVuY3Rpb24oYSxiLGMpe3ZhciBzPUgubk0oYSxiLGMpCnJldHVybiBzfSwKbk06ZnVuY3Rpb24oYSxi
+LGMpe3ZhciBzLHIscSxwCmlmKGI9PT0iIil7aWYoYT09PSIiKXJldHVybiBjCnM9YS5sZW5ndGgKZm9y
+KHI9YyxxPTA7cTxzOysrcSlyPXIrYVtxXStjCnJldHVybiByLmNoYXJDb2RlQXQoMCk9PTA/cjpyfXA9
+YS5pbmRleE9mKGIsMCkKaWYocDwwKXJldHVybiBhCmlmKGEubGVuZ3RoPDUwMHx8Yy5pbmRleE9mKCIk
+IiwwKT49MClyZXR1cm4gYS5zcGxpdChiKS5qb2luKGMpCnJldHVybiBhLnJlcGxhY2UobmV3IFJlZ0V4
+cChILmVBKGIpLCdnJyksSC5BNChjKSl9LApQRDpmdW5jdGlvbiBQRChhLGIpe3RoaXMuYT1hCnRoaXMu
+JHRpPWJ9LApXVTpmdW5jdGlvbiBXVSgpe30sCkxQOmZ1bmN0aW9uIExQKGEsYixjLGQpe3ZhciBfPXRo
+aXMKXy5hPWEKXy5iPWIKXy5jPWMKXy4kdGk9ZH0sClhSOmZ1bmN0aW9uIFhSKGEsYil7dGhpcy5hPWEK
+dGhpcy4kdGk9Yn0sCkxJOmZ1bmN0aW9uIExJKGEsYixjLGQsZSl7dmFyIF89dGhpcwpfLmE9YQpfLmM9
+YgpfLmQ9YwpfLmU9ZApfLmY9ZX0sCkNqOmZ1bmN0aW9uIENqKGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9
+Ygp0aGlzLmM9Y30sCmY5OmZ1bmN0aW9uIGY5KGEsYixjLGQsZSxmKXt2YXIgXz10aGlzCl8uYT1hCl8u
+Yj1iCl8uYz1jCl8uZD1kCl8uZT1lCl8uZj1mfSwKVzA6ZnVuY3Rpb24gVzAoYSxiKXt0aGlzLmE9YQp0
+aGlzLmI9Yn0sCmF6OmZ1bmN0aW9uIGF6KGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9Y30s
+CnZWOmZ1bmN0aW9uIHZWKGEpe3RoaXMuYT1hfSwKdGU6ZnVuY3Rpb24gdGUoYSl7dGhpcy5hPWF9LApi
+cTpmdW5jdGlvbiBicShhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKWE86ZnVuY3Rpb24gWE8oYSl7dGhp
+cy5hPWEKdGhpcy5iPW51bGx9LApUcDpmdW5jdGlvbiBUcCgpe30sCmxjOmZ1bmN0aW9uIGxjKCl7fSwK
+eng6ZnVuY3Rpb24gengoKXt9LApyVDpmdW5jdGlvbiByVChhLGIsYyxkKXt2YXIgXz10aGlzCl8uYT1h
+Cl8uYj1iCl8uYz1jCl8uZD1kfSwKRXE6ZnVuY3Rpb24gRXEoYSl7dGhpcy5hPWF9LAprWTpmdW5jdGlv
+biBrWShhKXt0aGlzLmE9YX0sCmtyOmZ1bmN0aW9uIGtyKCl7fSwKTjU6ZnVuY3Rpb24gTjUoYSl7dmFy
+IF89dGhpcwpfLmE9MApfLmY9Xy5lPV8uZD1fLmM9Xy5iPW51bGwKXy5yPTAKXy4kdGk9YX0sCnZoOmZ1
+bmN0aW9uIHZoKGEsYil7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmQ9Xy5jPW51bGx9LAppNTpmdW5j
+dGlvbiBpNShhLGIpe3RoaXMuYT1hCnRoaXMuJHRpPWJ9LApONjpmdW5jdGlvbiBONihhLGIsYyl7dmFy
+IF89dGhpcwpfLmE9YQpfLmI9YgpfLmQ9Xy5jPW51bGwKXy4kdGk9Y30sCmRDOmZ1bmN0aW9uIGRDKGEp
+e3RoaXMuYT1hfSwKd046ZnVuY3Rpb24gd04oYSl7dGhpcy5hPWF9LApWWDpmdW5jdGlvbiBWWChhKXt0
+aGlzLmE9YX0sClZSOmZ1bmN0aW9uIFZSKGEsYil7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmQ9Xy5j
+PW51bGx9LApFSzpmdW5jdGlvbiBFSyhhKXt0aGlzLmI9YX0sCktXOmZ1bmN0aW9uIEtXKGEsYixjKXt0
+aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9Y30sClBiOmZ1bmN0aW9uIFBiKGEsYixjKXt2YXIgXz10aGlz
+Cl8uYT1hCl8uYj1iCl8uYz1jCl8uZD1udWxsfSwKdFE6ZnVuY3Rpb24gdFEoYSxiKXt0aGlzLmE9YQp0
+aGlzLmM9Yn0sCnVuOmZ1bmN0aW9uIHVuKGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9Y30s
+ClNkOmZ1bmN0aW9uIFNkKGEsYixjKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz1jCl8uZD1udWxs
+fSwKWEY6ZnVuY3Rpb24oYSl7cmV0dXJuIGF9LApvZDpmdW5jdGlvbihhLGIsYyl7aWYoYT4+PjAhPT1h
+fHxhPj1jKXRocm93IEguYihILkhZKGIsYSkpfSwKck06ZnVuY3Rpb24oYSxiLGMpe3ZhciBzCmlmKCEo
+YT4+PjAhPT1hKSlzPWI+Pj4wIT09Ynx8YT5ifHxiPmMKZWxzZSBzPSEwCmlmKHMpdGhyb3cgSC5iKEgu
+RHUoYSxiLGMpKQpyZXR1cm4gYn0sCkVUOmZ1bmN0aW9uIEVUKCl7fSwKTFo6ZnVuY3Rpb24gTFooKXt9
+LApEZzpmdW5jdGlvbiBEZygpe30sClBnOmZ1bmN0aW9uIFBnKCl7fSwKeGo6ZnVuY3Rpb24geGooKXt9
+LApkRTpmdW5jdGlvbiBkRSgpe30sClpBOmZ1bmN0aW9uIFpBKCl7fSwKZFQ6ZnVuY3Rpb24gZFQoKXt9
+LApQcTpmdW5jdGlvbiBQcSgpe30sCmVFOmZ1bmN0aW9uIGVFKCl7fSwKVjY6ZnVuY3Rpb24gVjYoKXt9
+LApSRzpmdW5jdGlvbiBSRygpe30sClZQOmZ1bmN0aW9uIFZQKCl7fSwKV0I6ZnVuY3Rpb24gV0IoKXt9
+LApaRzpmdW5jdGlvbiBaRygpe30sCmN6OmZ1bmN0aW9uKGEsYil7dmFyIHM9Yi5jCnJldHVybiBzPT1u
+dWxsP2IuYz1ILkIoYSxiLnosITApOnN9LAp4WjpmdW5jdGlvbihhLGIpe3ZhciBzPWIuYwpyZXR1cm4g
+cz09bnVsbD9iLmM9SC5KKGEsImI4IixbYi56XSk6c30sClExOmZ1bmN0aW9uKGEpe3ZhciBzPWEueQpp
+ZihzPT09Nnx8cz09PTd8fHM9PT04KXJldHVybiBILlExKGEueikKcmV0dXJuIHM9PT0xMXx8cz09PTEy
+fSwKbUQ6ZnVuY3Rpb24oYSl7cmV0dXJuIGEuY3l9LApOMDpmdW5jdGlvbihhKXtyZXR1cm4gSC5FKHYu
+dHlwZVVuaXZlcnNlLGEsITEpfSwKUEw6ZnVuY3Rpb24oYSxiLGEwLGExKXt2YXIgcyxyLHEscCxvLG4s
+bSxsLGssaixpLGgsZyxmLGUsZCxjPWIueQpzd2l0Y2goYyl7Y2FzZSA1OmNhc2UgMTpjYXNlIDI6Y2Fz
+ZSAzOmNhc2UgNDpyZXR1cm4gYgpjYXNlIDY6cz1iLnoKcj1ILlBMKGEscyxhMCxhMSkKaWYocj09PXMp
+cmV0dXJuIGIKcmV0dXJuIEguQyhhLHIsITApCmNhc2UgNzpzPWIuegpyPUguUEwoYSxzLGEwLGExKQpp
+ZihyPT09cylyZXR1cm4gYgpyZXR1cm4gSC5CKGEsciwhMCkKY2FzZSA4OnM9Yi56CnI9SC5QTChhLHMs
+YTAsYTEpCmlmKHI9PT1zKXJldHVybiBiCnJldHVybiBILmYoYSxyLCEwKQpjYXNlIDk6cT1iLlEKcD1I
+LmJaKGEscSxhMCxhMSkKaWYocD09PXEpcmV0dXJuIGIKcmV0dXJuIEguSihhLGIueixwKQpjYXNlIDEw
+Om89Yi56Cm49SC5QTChhLG8sYTAsYTEpCm09Yi5RCmw9SC5iWihhLG0sYTAsYTEpCmlmKG49PT1vJiZs
+PT09bSlyZXR1cm4gYgpyZXR1cm4gSC5hKGEsbixsKQpjYXNlIDExOms9Yi56Cmo9SC5QTChhLGssYTAs
+YTEpCmk9Yi5RCmg9SC5xVChhLGksYTAsYTEpCmlmKGo9PT1rJiZoPT09aSlyZXR1cm4gYgpyZXR1cm4g
+SC5kKGEsaixoKQpjYXNlIDEyOmc9Yi5RCmExKz1nLmxlbmd0aApmPUguYlooYSxnLGEwLGExKQpvPWIu
+egpuPUguUEwoYSxvLGEwLGExKQppZihmPT09ZyYmbj09PW8pcmV0dXJuIGIKcmV0dXJuIEguRChhLG4s
+ZiwhMCkKY2FzZSAxMzplPWIuegppZihlPGExKXJldHVybiBiCmQ9YTBbZS1hMV0KaWYoZD09bnVsbCly
+ZXR1cm4gYgpyZXR1cm4gZApkZWZhdWx0OnRocm93IEguYihQLmhWKCJBdHRlbXB0ZWQgdG8gc3Vic3Rp
+dHV0ZSB1bmV4cGVjdGVkIFJUSSBraW5kICIrYykpfX0sCmJaOmZ1bmN0aW9uKGEsYixjLGQpe3ZhciBz
+LHIscSxwLG89Yi5sZW5ndGgsbj1bXQpmb3Iocz0hMSxyPTA7cjxvOysrcil7cT1iW3JdCnA9SC5QTChh
+LHEsYyxkKQppZihwIT09cSlzPSEwCm4ucHVzaChwKX1yZXR1cm4gcz9uOmJ9LAp2TzpmdW5jdGlvbihh
+LGIsYyxkKXt2YXIgcyxyLHEscCxvLG4sbT1iLmxlbmd0aCxsPVtdCmZvcihzPSExLHI9MDtyPG07cis9
+Myl7cT1iW3JdCnA9YltyKzFdCm89YltyKzJdCm49SC5QTChhLG8sYyxkKQppZihuIT09bylzPSEwCmwu
+cHVzaChxKQpsLnB1c2gocCkKbC5wdXNoKG4pfXJldHVybiBzP2w6Yn0sCnFUOmZ1bmN0aW9uKGEsYixj
+LGQpe3ZhciBzLHI9Yi5hLHE9SC5iWihhLHIsYyxkKSxwPWIuYixvPUguYlooYSxwLGMsZCksbj1iLmMs
+bT1ILnZPKGEsbixjLGQpCmlmKHE9PT1yJiZvPT09cCYmbT09PW4pcmV0dXJuIGIKcz1uZXcgSC5HKCkK
+cy5hPXEKcy5iPW8Kcy5jPW0KcmV0dXJuIHN9LApWTTpmdW5jdGlvbihhLGIpe2Fbdi5hcnJheVJ0aV09
+YgpyZXR1cm4gYX0sCkpTOmZ1bmN0aW9uKGEpe3ZhciBzPWEuJFMKaWYocyE9bnVsbCl7aWYodHlwZW9m
+IHM9PSJudW1iZXIiKXJldHVybiBILkJwKHMpCnJldHVybiBhLiRTKCl9cmV0dXJuIG51bGx9LApVZTpm
+dW5jdGlvbihhLGIpe3ZhciBzCmlmKEguUTEoYikpaWYoYSBpbnN0YW5jZW9mIEguVHApe3M9SC5KUyhh
+KQppZihzIT1udWxsKXJldHVybiBzfXJldHVybiBILnooYSl9LAp6OmZ1bmN0aW9uKGEpe3ZhciBzCmlm
+KGEgaW5zdGFuY2VvZiBQLk1oKXtzPWEuJHRpCnJldHVybiBzIT1udWxsP3M6SC5WVShhKX1pZihBcnJh
+eS5pc0FycmF5KGEpKXJldHVybiBILnQ2KGEpCnJldHVybiBILlZVKEouaWEoYSkpfSwKdDY6ZnVuY3Rp
+b24oYSl7dmFyIHM9YVt2LmFycmF5UnRpXSxyPXQuYgppZihzPT1udWxsKXJldHVybiByCmlmKHMuY29u
+c3RydWN0b3IhPT1yLmNvbnN0cnVjdG9yKXJldHVybiByCnJldHVybiBzfSwKTGg6ZnVuY3Rpb24oYSl7
+dmFyIHM9YS4kdGkKcmV0dXJuIHMhPW51bGw/czpILlZVKGEpfSwKVlU6ZnVuY3Rpb24oYSl7dmFyIHM9
+YS5jb25zdHJ1Y3RvcixyPXMuJGNjYWNoZQppZihyIT1udWxsKXJldHVybiByCnJldHVybiBILnI5KGEs
+cyl9LApyOTpmdW5jdGlvbihhLGIpe3ZhciBzPWEgaW5zdGFuY2VvZiBILlRwP2EuX19wcm90b19fLl9f
+cHJvdG9fXy5jb25zdHJ1Y3RvcjpiLHI9SC5haSh2LnR5cGVVbml2ZXJzZSxzLm5hbWUpCmIuJGNjYWNo
+ZT1yCnJldHVybiByfSwKQnA6ZnVuY3Rpb24oYSl7dmFyIHMscixxCkgudVAoYSkKcz12LnR5cGVzCnI9
+c1thXQppZih0eXBlb2Ygcj09InN0cmluZyIpe3E9SC5FKHYudHlwZVVuaXZlcnNlLHIsITEpCnNbYV09
+cQpyZXR1cm4gcX1yZXR1cm4gcn0sCkt4OmZ1bmN0aW9uKGEpe3ZhciBzLHIscSxwPWEueAppZihwIT1u
+dWxsKXJldHVybiBwCnM9YS5jeQpyPXMucmVwbGFjZSgvXCovZywiIikKaWYocj09PXMpcmV0dXJuIGEu
+eD1uZXcgSC5sWShhKQpxPUguRSh2LnR5cGVVbml2ZXJzZSxyLCEwKQpwPXEueApyZXR1cm4gYS54PXA9
+PW51bGw/cS54PW5ldyBILmxZKHEpOnB9LApKSjpmdW5jdGlvbihhKXt2YXIgcyxyLHE9dGhpcyxwPXQu
+SwppZihxPT09cClyZXR1cm4gSC5SRShxLGEsSC5rZSkKaWYoIUguQTgocSkpaWYoIShxPT09dC5fKSlw
+PXE9PT1wCmVsc2UgcD0hMAplbHNlIHA9ITAKaWYocClyZXR1cm4gSC5SRShxLGEsSC5JdykKcD1xLnkK
+cz1wPT09Nj9xLno6cQppZihzPT09dC5TKXI9SC5vawplbHNlIGlmKHM9PT10LmdSfHxzPT09dC5kaSly
+PUguS0gKZWxzZSBpZihzPT09dC5OKXI9SC5NTQplbHNlIHI9cz09PXQueT9ILmw6bnVsbAppZihyIT1u
+dWxsKXJldHVybiBILlJFKHEsYSxyKQppZihzLnk9PT05KXtwPXMuegppZihzLlEuZXZlcnkoSC5jYykp
+e3Eucj0iJGkiK3AKcmV0dXJuIEguUkUocSxhLEgudDQpfX1lbHNlIGlmKHA9PT03KXJldHVybiBILlJF
+KHEsYSxILkFRKQpyZXR1cm4gSC5SRShxLGEsSC5ZTyl9LApSRTpmdW5jdGlvbihhLGIsYyl7YS5iPWMK
+cmV0dXJuIGEuYihiKX0sCkF1OmZ1bmN0aW9uKGEpe3ZhciBzLHIscT10aGlzCmlmKCFILkE4KHEpKWlm
+KCEocT09PXQuXykpcz1xPT09dC5LCmVsc2Ugcz0hMAplbHNlIHM9ITAKaWYocylyPUguaG4KZWxzZSBp
+ZihxPT09dC5LKXI9SC5UaQplbHNlIHI9SC5sNApxLmE9cgpyZXR1cm4gcS5hKGEpfSwKUWo6ZnVuY3Rp
+b24oYSl7dmFyIHMscj1hLnkKaWYoIUguQTgoYSkpaWYoIShhPT09dC5fKSlpZighKGE9PT10LmNGKSlp
+ZihyIT09NylzPXI9PT04JiZILlFqKGEueil8fGE9PT10LlB8fGE9PT10LlQKZWxzZSBzPSEwCmVsc2Ug
+cz0hMAplbHNlIHM9ITAKZWxzZSBzPSEwCnJldHVybiBzfSwKWU86ZnVuY3Rpb24oYSl7dmFyIHM9dGhp
+cwppZihhPT1udWxsKXJldHVybiBILlFqKHMpCnJldHVybiBILldlKHYudHlwZVVuaXZlcnNlLEguVWUo
+YSxzKSxudWxsLHMsbnVsbCl9LApBUTpmdW5jdGlvbihhKXtpZihhPT1udWxsKXJldHVybiEwCnJldHVy
+biB0aGlzLnouYihhKX0sCnQ0OmZ1bmN0aW9uKGEpe3ZhciBzLHI9dGhpcwppZihhPT1udWxsKXJldHVy
+biBILlFqKHIpCnM9ci5yCmlmKGEgaW5zdGFuY2VvZiBQLk1oKXJldHVybiEhYVtzXQpyZXR1cm4hIUou
+aWEoYSlbc119LApPejpmdW5jdGlvbihhKXt2YXIgcz10aGlzCmlmKGE9PW51bGwpcmV0dXJuIGEKZWxz
+ZSBpZihzLmIoYSkpcmV0dXJuIGEKSC5tNChhLHMpfSwKbDQ6ZnVuY3Rpb24oYSl7dmFyIHM9dGhpcwpp
+ZihhPT1udWxsKXJldHVybiBhCmVsc2UgaWYocy5iKGEpKXJldHVybiBhCkgubTQoYSxzKX0sCm00OmZ1
+bmN0aW9uKGEsYil7dGhyb3cgSC5iKEguWmMoSC5XSyhhLEguVWUoYSxiKSxILmRtKGIsbnVsbCkpKSl9
+LApEaDpmdW5jdGlvbihhLGIsYyxkKXt2YXIgcz1udWxsCmlmKEguV2Uodi50eXBlVW5pdmVyc2UsYSxz
+LGIscykpcmV0dXJuIGEKdGhyb3cgSC5iKEguWmMoIlRoZSB0eXBlIGFyZ3VtZW50ICciK0guRWooSC5k
+bShhLHMpKSsiJyBpcyBub3QgYSBzdWJ0eXBlIG9mIHRoZSB0eXBlIHZhcmlhYmxlIGJvdW5kICciK0gu
+RWooSC5kbShiLHMpKSsiJyBvZiB0eXBlIHZhcmlhYmxlICciK0guRWooYykrIicgaW4gJyIrSC5Faihk
+KSsiJy4iKSl9LApXSzpmdW5jdGlvbihhLGIsYyl7dmFyIHM9UC5wKGEpLHI9SC5kbShiPT1udWxsP0gu
+eihhKTpiLG51bGwpCnJldHVybiBzKyI6IHR5cGUgJyIrSC5FaihyKSsiJyBpcyBub3QgYSBzdWJ0eXBl
+IG9mIHR5cGUgJyIrSC5FaihjKSsiJyJ9LApaYzpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IEguaU0oIlR5
+cGVFcnJvcjogIithKX0sCnE6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gbmV3IEguaU0oIlR5cGVFcnJvcjog
+IitILldLKGEsbnVsbCxiKSl9LAprZTpmdW5jdGlvbihhKXtyZXR1cm4gYSE9bnVsbH0sClRpOmZ1bmN0
+aW9uKGEpe3JldHVybiBhfSwKSXc6ZnVuY3Rpb24oYSl7cmV0dXJuITB9LApobjpmdW5jdGlvbihhKXty
+ZXR1cm4gYX0sCmw6ZnVuY3Rpb24oYSl7cmV0dXJuITA9PT1hfHwhMT09PWF9LApwODpmdW5jdGlvbihh
+KXtpZighMD09PWEpcmV0dXJuITAKaWYoITE9PT1hKXJldHVybiExCnRocm93IEguYihILnEoYSwiYm9v
+bCIpKX0sCnk4OmZ1bmN0aW9uKGEpe2lmKCEwPT09YSlyZXR1cm4hMAppZighMT09PWEpcmV0dXJuITEK
+aWYoYT09bnVsbClyZXR1cm4gYQp0aHJvdyBILmIoSC5xKGEsImJvb2wiKSl9LApkcDpmdW5jdGlvbihh
+KXtpZighMD09PWEpcmV0dXJuITAKaWYoITE9PT1hKXJldHVybiExCmlmKGE9PW51bGwpcmV0dXJuIGEK
+dGhyb3cgSC5iKEgucShhLCJib29sPyIpKX0sCkZHOmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhPT0ibnVt
+YmVyIilyZXR1cm4gYQp0aHJvdyBILmIoSC5xKGEsImRvdWJsZSIpKX0sCkdIOmZ1bmN0aW9uKGEpe2lm
+KHR5cGVvZiBhPT0ibnVtYmVyIilyZXR1cm4gYQppZihhPT1udWxsKXJldHVybiBhCnRocm93IEguYihI
+LnEoYSwiZG91YmxlIikpfSwKUWs6ZnVuY3Rpb24oYSl7aWYodHlwZW9mIGE9PSJudW1iZXIiKXJldHVy
+biBhCmlmKGE9PW51bGwpcmV0dXJuIGEKdGhyb3cgSC5iKEgucShhLCJkb3VibGU/IikpfSwKb2s6ZnVu
+Y3Rpb24oYSl7cmV0dXJuIHR5cGVvZiBhPT0ibnVtYmVyIiYmTWF0aC5mbG9vcihhKT09PWF9LApJWjpm
+dW5jdGlvbihhKXtpZih0eXBlb2YgYT09Im51bWJlciImJk1hdGguZmxvb3IoYSk9PT1hKXJldHVybiBh
+CnRocm93IEguYihILnEoYSwiaW50IikpfSwKdVA6ZnVuY3Rpb24oYSl7aWYodHlwZW9mIGE9PSJudW1i
+ZXIiJiZNYXRoLmZsb29yKGEpPT09YSlyZXR1cm4gYQppZihhPT1udWxsKXJldHVybiBhCnRocm93IEgu
+YihILnEoYSwiaW50IikpfSwKVWM6ZnVuY3Rpb24oYSl7aWYodHlwZW9mIGE9PSJudW1iZXIiJiZNYXRo
+LmZsb29yKGEpPT09YSlyZXR1cm4gYQppZihhPT1udWxsKXJldHVybiBhCnRocm93IEguYihILnEoYSwi
+aW50PyIpKX0sCktIOmZ1bmN0aW9uKGEpe3JldHVybiB0eXBlb2YgYT09Im51bWJlciJ9LAp6NTpmdW5j
+dGlvbihhKXtpZih0eXBlb2YgYT09Im51bWJlciIpcmV0dXJuIGEKdGhyb3cgSC5iKEgucShhLCJudW0i
+KSl9LApXMTpmdW5jdGlvbihhKXtpZih0eXBlb2YgYT09Im51bWJlciIpcmV0dXJuIGEKaWYoYT09bnVs
+bClyZXR1cm4gYQp0aHJvdyBILmIoSC5xKGEsIm51bSIpKX0sCmNVOmZ1bmN0aW9uKGEpe2lmKHR5cGVv
+ZiBhPT0ibnVtYmVyIilyZXR1cm4gYQppZihhPT1udWxsKXJldHVybiBhCnRocm93IEguYihILnEoYSwi
+bnVtPyIpKX0sCk1NOmZ1bmN0aW9uKGEpe3JldHVybiB0eXBlb2YgYT09InN0cmluZyJ9LApCdDpmdW5j
+dGlvbihhKXtpZih0eXBlb2YgYT09InN0cmluZyIpcmV0dXJuIGEKdGhyb3cgSC5iKEgucShhLCJTdHJp
+bmciKSl9LApoOmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhPT0ic3RyaW5nIilyZXR1cm4gYQppZihhPT1u
+dWxsKXJldHVybiBhCnRocm93IEguYihILnEoYSwiU3RyaW5nIikpfSwKazpmdW5jdGlvbihhKXtpZih0
+eXBlb2YgYT09InN0cmluZyIpcmV0dXJuIGEKaWYoYT09bnVsbClyZXR1cm4gYQp0aHJvdyBILmIoSC5x
+KGEsIlN0cmluZz8iKSl9LAppbzpmdW5jdGlvbihhLGIpe3ZhciBzLHIscQpmb3Iocz0iIixyPSIiLHE9
+MDtxPGEubGVuZ3RoOysrcSxyPSIsICIpcys9Qy54Qi5oKHIsSC5kbShhW3FdLGIpKQpyZXR1cm4gc30s
+CmJJOmZ1bmN0aW9uKGE1LGE2LGE3KXt2YXIgcyxyLHEscCxvLG4sbSxsLGssaixpLGgsZyxmLGUsZCxj
+LGIsYSxhMCxhMSxhMixhMyxhND0iLCAiCmlmKGE3IT1udWxsKXtzPWE3Lmxlbmd0aAppZihhNj09bnVs
+bCl7YTY9SC5WTShbXSx0LnMpCnI9bnVsbH1lbHNlIHI9YTYubGVuZ3RoCnE9YTYubGVuZ3RoCmZvcihw
+PXM7cD4wOy0tcClDLk5tLmkoYTYsIlQiKyhxK3ApKQpmb3Iobz10Llcsbj10Ll8sbT10LkssbD0iPCIs
+az0iIixwPTA7cDxzOysrcCxrPWE0KXtsKz1rCmo9YTYubGVuZ3RoCmk9ai0xLXAKaWYoaTwwKXJldHVy
+biBILk9IKGE2LGkpCmw9Qy54Qi5oKGwsYTZbaV0pCmg9YTdbcF0KZz1oLnkKaWYoIShnPT09Mnx8Zz09
+PTN8fGc9PT00fHxnPT09NXx8aD09PW8pKWlmKCEoaD09PW4pKWo9aD09PW0KZWxzZSBqPSEwCmVsc2Ug
+aj0hMAppZighailsKz1DLnhCLmgoIiBleHRlbmRzICIsSC5kbShoLGE2KSl9bCs9Ij4ifWVsc2V7bD0i
+IgpyPW51bGx9bz1hNS56CmY9YTUuUQplPWYuYQpkPWUubGVuZ3RoCmM9Zi5iCmI9Yy5sZW5ndGgKYT1m
+LmMKYTA9YS5sZW5ndGgKYTE9SC5kbShvLGE2KQpmb3IoYTI9IiIsYTM9IiIscD0wO3A8ZDsrK3AsYTM9
+YTQpYTIrPUMueEIuaChhMyxILmRtKGVbcF0sYTYpKQppZihiPjApe2EyKz1hMysiWyIKZm9yKGEzPSIi
+LHA9MDtwPGI7KytwLGEzPWE0KWEyKz1DLnhCLmgoYTMsSC5kbShjW3BdLGE2KSkKYTIrPSJdIn1pZihh
+MD4wKXthMis9YTMrInsiCmZvcihhMz0iIixwPTA7cDxhMDtwKz0zLGEzPWE0KXthMis9YTMKaWYoYVtw
+KzFdKWEyKz0icmVxdWlyZWQgIgphMis9Si5iYihILmRtKGFbcCsyXSxhNiksIiAiKSthW3BdfWEyKz0i
+fSJ9aWYociE9bnVsbCl7YTYudG9TdHJpbmcKYTYubGVuZ3RoPXJ9cmV0dXJuIGwrIigiK2EyKyIpID0+
+ICIrSC5FaihhMSl9LApkbTpmdW5jdGlvbihhLGIpe3ZhciBzLHIscSxwLG8sbixtLGw9YS55CmlmKGw9
+PT01KXJldHVybiJlcmFzZWQiCmlmKGw9PT0yKXJldHVybiJkeW5hbWljIgppZihsPT09MylyZXR1cm4i
+dm9pZCIKaWYobD09PTEpcmV0dXJuIk5ldmVyIgppZihsPT09NClyZXR1cm4iYW55IgppZihsPT09Nil7
+cz1ILmRtKGEueixiKQpyZXR1cm4gc31pZihsPT09Nyl7cj1hLnoKcz1ILmRtKHIsYikKcT1yLnkKcmV0
+dXJuIEouYmIocT09PTExfHxxPT09MTI/Qy54Qi5oKCIoIixzKSsiKSI6cywiPyIpfWlmKGw9PT04KXJl
+dHVybiJGdXR1cmVPcjwiK0guRWooSC5kbShhLnosYikpKyI+IgppZihsPT09OSl7cD1ILm8zKGEueikK
+bz1hLlEKcmV0dXJuIG8ubGVuZ3RoIT09MD9wKygiPCIrSC5pbyhvLGIpKyI+Iik6cH1pZihsPT09MTEp
+cmV0dXJuIEguYkkoYSxiLG51bGwpCmlmKGw9PT0xMilyZXR1cm4gSC5iSShhLnosYixhLlEpCmlmKGw9
+PT0xMyl7Yi50b1N0cmluZwpuPWEuegptPWIubGVuZ3RoCm49bS0xLW4KaWYobjwwfHxuPj1tKXJldHVy
+biBILk9IKGIsbikKcmV0dXJuIGJbbl19cmV0dXJuIj8ifSwKbzM6ZnVuY3Rpb24oYSl7dmFyIHMscj1I
+LkpnKGEpCmlmKHIhPW51bGwpcmV0dXJuIHIKcz0ibWluaWZpZWQ6IithCnJldHVybiBzfSwKUW86ZnVu
+Y3Rpb24oYSxiKXt2YXIgcz1hLnRSW2JdCmZvcig7dHlwZW9mIHM9PSJzdHJpbmciOylzPWEudFJbc10K
+cmV0dXJuIHN9LAphaTpmdW5jdGlvbihhLGIpe3ZhciBzLHIscSxwLG8sbj1hLmVULG09bltiXQppZiht
+PT1udWxsKXJldHVybiBILkUoYSxiLCExKQplbHNlIGlmKHR5cGVvZiBtPT0ibnVtYmVyIil7cz1tCnI9
+SC5tKGEsNSwiIyIpCnE9W10KZm9yKHA9MDtwPHM7KytwKXEucHVzaChyKQpvPUguSihhLGIscSkKblti
+XT1vCnJldHVybiBvfWVsc2UgcmV0dXJuIG19LAp4YjpmdW5jdGlvbihhLGIpe3JldHVybiBILkl4KGEu
+dFIsYil9LApGRjpmdW5jdGlvbihhLGIpe3JldHVybiBILkl4KGEuZVQsYil9LApFOmZ1bmN0aW9uKGEs
+YixjKXt2YXIgcyxyPWEuZUMscT1yLmdldChiKQppZihxIT1udWxsKXJldHVybiBxCnM9SC5pKEgubyhh
+LG51bGwsYixjKSkKci5zZXQoYixzKQpyZXR1cm4gc30sCmNFOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxy
+LHE9Yi5jaAppZihxPT1udWxsKXE9Yi5jaD1uZXcgTWFwKCkKcz1xLmdldChjKQppZihzIT1udWxsKXJl
+dHVybiBzCnI9SC5pKEgubyhhLGIsYywhMCkpCnEuc2V0KGMscikKcmV0dXJuIHJ9LAp2NTpmdW5jdGlv
+bihhLGIsYyl7dmFyIHMscixxLHA9Yi5jeAppZihwPT1udWxsKXA9Yi5jeD1uZXcgTWFwKCkKcz1jLmN5
+CnI9cC5nZXQocykKaWYociE9bnVsbClyZXR1cm4gcgpxPUguYShhLGIsYy55PT09MTA/Yy5ROltjXSkK
+cC5zZXQocyxxKQpyZXR1cm4gcX0sCkJEOmZ1bmN0aW9uKGEsYil7Yi5hPUguQXUKYi5iPUguSkoKcmV0
+dXJuIGJ9LAptOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyLHE9YS5lQy5nZXQoYykKaWYocSE9bnVsbCly
+ZXR1cm4gcQpzPW5ldyBILkpjKG51bGwsbnVsbCkKcy55PWIKcy5jeT1jCnI9SC5CRChhLHMpCmEuZUMu
+c2V0KGMscikKcmV0dXJuIHJ9LApDOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyPWIuY3krIioiLHE9YS5l
+Qy5nZXQocikKaWYocSE9bnVsbClyZXR1cm4gcQpzPUguWjcoYSxiLHIsYykKYS5lQy5zZXQocixzKQpy
+ZXR1cm4gc30sClo3OmZ1bmN0aW9uKGEsYixjLGQpe3ZhciBzLHIscQppZihkKXtzPWIueQppZighSC5B
+OChiKSlyPWI9PT10LlB8fGI9PT10LlR8fHM9PT03fHxzPT09NgplbHNlIHI9ITAKaWYocilyZXR1cm4g
+Yn1xPW5ldyBILkpjKG51bGwsbnVsbCkKcS55PTYKcS56PWIKcS5jeT1jCnJldHVybiBILkJEKGEscSl9
+LApCOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyPWIuY3krIj8iLHE9YS5lQy5nZXQocikKaWYocSE9bnVs
+bClyZXR1cm4gcQpzPUgubGwoYSxiLHIsYykKYS5lQy5zZXQocixzKQpyZXR1cm4gc30sCmxsOmZ1bmN0
+aW9uKGEsYixjLGQpe3ZhciBzLHIscSxwCmlmKGQpe3M9Yi55CmlmKCFILkE4KGIpKWlmKCEoYj09PXQu
+UHx8Yj09PXQuVCkpaWYocyE9PTcpcj1zPT09OCYmSC5sUihiLnopCmVsc2Ugcj0hMAplbHNlIHI9ITAK
+ZWxzZSByPSEwCmlmKHIpcmV0dXJuIGIKZWxzZSBpZihzPT09MXx8Yj09PXQuY0YpcmV0dXJuIHQuUApl
+bHNlIGlmKHM9PT02KXtxPWIuegppZihxLnk9PT04JiZILmxSKHEueikpcmV0dXJuIHEKZWxzZSByZXR1
+cm4gSC5jeihhLGIpfX1wPW5ldyBILkpjKG51bGwsbnVsbCkKcC55PTcKcC56PWIKcC5jeT1jCnJldHVy
+biBILkJEKGEscCl9LApmOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyPWIuY3krIi8iLHE9YS5lQy5nZXQo
+cikKaWYocSE9bnVsbClyZXR1cm4gcQpzPUguZVYoYSxiLHIsYykKYS5lQy5zZXQocixzKQpyZXR1cm4g
+c30sCmVWOmZ1bmN0aW9uKGEsYixjLGQpe3ZhciBzLHIscQppZihkKXtzPWIueQppZighSC5BOChiKSlp
+ZighKGI9PT10Ll8pKXI9Yj09PXQuSwplbHNlIHI9ITAKZWxzZSByPSEwCmlmKHJ8fGI9PT10LkspcmV0
+dXJuIGIKZWxzZSBpZihzPT09MSlyZXR1cm4gSC5KKGEsImI4IixbYl0pCmVsc2UgaWYoYj09PXQuUHx8
+Yj09PXQuVClyZXR1cm4gdC5iR31xPW5ldyBILkpjKG51bGwsbnVsbCkKcS55PTgKcS56PWIKcS5jeT1j
+CnJldHVybiBILkJEKGEscSl9LApIOmZ1bmN0aW9uKGEsYil7dmFyIHMscixxPSIiK2IrIl4iLHA9YS5l
+Qy5nZXQocSkKaWYocCE9bnVsbClyZXR1cm4gcApzPW5ldyBILkpjKG51bGwsbnVsbCkKcy55PTEzCnMu
+ej1iCnMuY3k9cQpyPUguQkQoYSxzKQphLmVDLnNldChxLHIpCnJldHVybiByfSwKVXg6ZnVuY3Rpb24o
+YSl7dmFyIHMscixxLHA9YS5sZW5ndGgKZm9yKHM9IiIscj0iIixxPTA7cTxwOysrcSxyPSIsIilzKz1y
+K2FbcV0uY3kKcmV0dXJuIHN9LApTNDpmdW5jdGlvbihhKXt2YXIgcyxyLHEscCxvLG4sbT1hLmxlbmd0
+aApmb3Iocz0iIixyPSIiLHE9MDtxPG07cSs9MyxyPSIsIil7cD1hW3FdCm89YVtxKzFdPyIhIjoiOiIK
+bj1hW3ErMl0uY3kKcys9citwK28rbn1yZXR1cm4gc30sCko6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzLHIs
+cSxwPWIKaWYoYy5sZW5ndGghPT0wKXArPSI8IitILlV4KGMpKyI+IgpzPWEuZUMuZ2V0KHApCmlmKHMh
+PW51bGwpcmV0dXJuIHMKcj1uZXcgSC5KYyhudWxsLG51bGwpCnIueT05CnIuej1iCnIuUT1jCmlmKGMu
+bGVuZ3RoPjApci5jPWNbMF0Kci5jeT1wCnE9SC5CRChhLHIpCmEuZUMuc2V0KHAscSkKcmV0dXJuIHF9
+LAphOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyLHEscCxvLG4KaWYoYi55PT09MTApe3M9Yi56CnI9Yi5R
+LmNvbmNhdChjKX1lbHNle3I9YwpzPWJ9cT1zLmN5KygiOzwiK0guVXgocikrIj4iKQpwPWEuZUMuZ2V0
+KHEpCmlmKHAhPW51bGwpcmV0dXJuIHAKbz1uZXcgSC5KYyhudWxsLG51bGwpCm8ueT0xMApvLno9cwpv
+LlE9cgpvLmN5PXEKbj1ILkJEKGEsbykKYS5lQy5zZXQocSxuKQpyZXR1cm4gbn0sCmQ6ZnVuY3Rpb24o
+YSxiLGMpe3ZhciBzLHIscSxwLG8sbj1iLmN5LG09Yy5hLGw9bS5sZW5ndGgsaz1jLmIsaj1rLmxlbmd0
+aCxpPWMuYyxoPWkubGVuZ3RoLGc9IigiK0guVXgobSkKaWYoaj4wKXtzPWw+MD8iLCI6IiIKcj1ILlV4
+KGspCmcrPXMrIlsiK3IrIl0ifWlmKGg+MCl7cz1sPjA/IiwiOiIiCnI9SC5TNChpKQpnKz1zKyJ7Iity
+KyJ9In1xPW4rKGcrIikiKQpwPWEuZUMuZ2V0KHEpCmlmKHAhPW51bGwpcmV0dXJuIHAKbz1uZXcgSC5K
+YyhudWxsLG51bGwpCm8ueT0xMQpvLno9YgpvLlE9YwpvLmN5PXEKcj1ILkJEKGEsbykKYS5lQy5zZXQo
+cSxyKQpyZXR1cm4gcn0sCkQ6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHMscj1iLmN5KygiPCIrSC5VeChj
+KSsiPiIpLHE9YS5lQy5nZXQocikKaWYocSE9bnVsbClyZXR1cm4gcQpzPUguaHcoYSxiLGMscixkKQph
+LmVDLnNldChyLHMpCnJldHVybiBzfSwKaHc6ZnVuY3Rpb24oYSxiLGMsZCxlKXt2YXIgcyxyLHEscCxv
+LG4sbSxsCmlmKGUpe3M9Yy5sZW5ndGgKcj1uZXcgQXJyYXkocykKZm9yKHE9MCxwPTA7cDxzOysrcCl7
+bz1jW3BdCmlmKG8ueT09PTEpe3JbcF09bzsrK3F9fWlmKHE+MCl7bj1ILlBMKGEsYixyLDApCm09SC5i
+WihhLGMsciwwKQpyZXR1cm4gSC5EKGEsbixtLGMhPT1tKX19bD1uZXcgSC5KYyhudWxsLG51bGwpCmwu
+eT0xMgpsLno9YgpsLlE9YwpsLmN5PWQKcmV0dXJuIEguQkQoYSxsKX0sCm86ZnVuY3Rpb24oYSxiLGMs
+ZCl7cmV0dXJue3U6YSxlOmIscjpjLHM6W10scDowLG46ZH19LAppOmZ1bmN0aW9uKGEpe3ZhciBzLHIs
+cSxwLG8sbixtLGwsayxqLGksaCxnPWEucixmPWEucwpmb3Iocz1nLmxlbmd0aCxyPTA7cjxzOyl7cT1n
+LmNoYXJDb2RlQXQocikKaWYocT49NDgmJnE8PTU3KXI9SC5BKHIrMSxxLGcsZikKZWxzZSBpZigoKChx
+fDMyKT4+PjApLTk3JjY1NTM1KTwyNnx8cT09PTk1fHxxPT09MzYpcj1ILnQoYSxyLGcsZiwhMSkKZWxz
+ZSBpZihxPT09NDYpcj1ILnQoYSxyLGcsZiwhMCkKZWxzZXsrK3IKc3dpdGNoKHEpe2Nhc2UgNDQ6YnJl
+YWsKY2FzZSA1ODpmLnB1c2goITEpCmJyZWFrCmNhc2UgMzM6Zi5wdXNoKCEwKQpicmVhawpjYXNlIDU5
+OmYucHVzaChILksoYS51LGEuZSxmLnBvcCgpKSkKYnJlYWsKY2FzZSA5NDpmLnB1c2goSC5IKGEudSxm
+LnBvcCgpKSkKYnJlYWsKY2FzZSAzNTpmLnB1c2goSC5tKGEudSw1LCIjIikpCmJyZWFrCmNhc2UgNjQ6
+Zi5wdXNoKEgubShhLnUsMiwiQCIpKQpicmVhawpjYXNlIDEyNjpmLnB1c2goSC5tKGEudSwzLCJ+Iikp
+CmJyZWFrCmNhc2UgNjA6Zi5wdXNoKGEucCkKYS5wPWYubGVuZ3RoCmJyZWFrCmNhc2UgNjI6cD1hLnUK
+bz1mLnNwbGljZShhLnApCkgucihhLnUsYS5lLG8pCmEucD1mLnBvcCgpCm49Zi5wb3AoKQppZih0eXBl
+b2Ygbj09InN0cmluZyIpZi5wdXNoKEguSihwLG4sbykpCmVsc2V7bT1ILksocCxhLmUsbikKc3dpdGNo
+KG0ueSl7Y2FzZSAxMTpmLnB1c2goSC5EKHAsbSxvLGEubikpCmJyZWFrCmRlZmF1bHQ6Zi5wdXNoKEgu
+YShwLG0sbykpCmJyZWFrfX1icmVhawpjYXNlIDM4OkguSShhLGYpCmJyZWFrCmNhc2UgNDI6bD1hLnUK
+Zi5wdXNoKEguQyhsLEguSyhsLGEuZSxmLnBvcCgpKSxhLm4pKQpicmVhawpjYXNlIDYzOmw9YS51CmYu
+cHVzaChILkIobCxILksobCxhLmUsZi5wb3AoKSksYS5uKSkKYnJlYWsKY2FzZSA0NzpsPWEudQpmLnB1
+c2goSC5mKGwsSC5LKGwsYS5lLGYucG9wKCkpLGEubikpCmJyZWFrCmNhc2UgNDA6Zi5wdXNoKGEucCkK
+YS5wPWYubGVuZ3RoCmJyZWFrCmNhc2UgNDE6cD1hLnUKaz1uZXcgSC5HKCkKaj1wLnNFQQppPXAuc0VB
+Cm49Zi5wb3AoKQppZih0eXBlb2Ygbj09Im51bWJlciIpc3dpdGNoKG4pe2Nhc2UtMTpqPWYucG9wKCkK
+YnJlYWsKY2FzZS0yOmk9Zi5wb3AoKQpicmVhawpkZWZhdWx0OmYucHVzaChuKQpicmVha31lbHNlIGYu
+cHVzaChuKQpvPWYuc3BsaWNlKGEucCkKSC5yKGEudSxhLmUsbykKYS5wPWYucG9wKCkKay5hPW8Kay5i
+PWoKay5jPWkKZi5wdXNoKEguZChwLEguSyhwLGEuZSxmLnBvcCgpKSxrKSkKYnJlYWsKY2FzZSA5MTpm
+LnB1c2goYS5wKQphLnA9Zi5sZW5ndGgKYnJlYWsKY2FzZSA5MzpvPWYuc3BsaWNlKGEucCkKSC5yKGEu
+dSxhLmUsbykKYS5wPWYucG9wKCkKZi5wdXNoKG8pCmYucHVzaCgtMSkKYnJlYWsKY2FzZSAxMjM6Zi5w
+dXNoKGEucCkKYS5wPWYubGVuZ3RoCmJyZWFrCmNhc2UgMTI1Om89Zi5zcGxpY2UoYS5wKQpILnkoYS51
+LGEuZSxvKQphLnA9Zi5wb3AoKQpmLnB1c2gobykKZi5wdXNoKC0yKQpicmVhawpkZWZhdWx0OnRocm93
+IkJhZCBjaGFyYWN0ZXIgIitxfX19aD1mLnBvcCgpCnJldHVybiBILksoYS51LGEuZSxoKX0sCkE6ZnVu
+Y3Rpb24oYSxiLGMsZCl7dmFyIHMscixxPWItNDgKZm9yKHM9Yy5sZW5ndGg7YTxzOysrYSl7cj1jLmNo
+YXJDb2RlQXQoYSkKaWYoIShyPj00OCYmcjw9NTcpKWJyZWFrCnE9cSoxMCsoci00OCl9ZC5wdXNoKHEp
+CnJldHVybiBhfSwKdDpmdW5jdGlvbihhLGIsYyxkLGUpe3ZhciBzLHIscSxwLG8sbixtPWIrMQpmb3Io
+cz1jLmxlbmd0aDttPHM7KyttKXtyPWMuY2hhckNvZGVBdChtKQppZihyPT09NDYpe2lmKGUpYnJlYWsK
+ZT0hMH1lbHNle2lmKCEoKCgocnwzMik+Pj4wKS05NyY2NTUzNSk8MjZ8fHI9PT05NXx8cj09PTM2KSlx
+PXI+PTQ4JiZyPD01NwplbHNlIHE9ITAKaWYoIXEpYnJlYWt9fXA9Yy5zdWJzdHJpbmcoYixtKQppZihl
+KXtzPWEudQpvPWEuZQppZihvLnk9PT0xMClvPW8uegpuPUguUW8ocyxvLnopW3BdCmlmKG49PW51bGwp
+SC52KCdObyAiJytwKyciIGluICInK0gubUQobykrJyInKQpkLnB1c2goSC5jRShzLG8sbikpfWVsc2Ug
+ZC5wdXNoKHApCnJldHVybiBtfSwKSTpmdW5jdGlvbihhLGIpe3ZhciBzPWIucG9wKCkKaWYoMD09PXMp
+e2IucHVzaChILm0oYS51LDEsIjAmIikpCnJldHVybn1pZigxPT09cyl7Yi5wdXNoKEgubShhLnUsNCwi
+MSYiKSkKcmV0dXJufXRocm93IEguYihQLmhWKCJVbmV4cGVjdGVkIGV4dGVuZGVkIG9wZXJhdGlvbiAi
+K0guRWoocykpKX0sCks6ZnVuY3Rpb24oYSxiLGMpe2lmKHR5cGVvZiBjPT0ic3RyaW5nIilyZXR1cm4g
+SC5KKGEsYyxhLnNFQSkKZWxzZSBpZih0eXBlb2YgYz09Im51bWJlciIpcmV0dXJuIEguVFYoYSxiLGMp
+CmVsc2UgcmV0dXJuIGN9LApyOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyPWMubGVuZ3RoCmZvcihzPTA7
+czxyOysrcyljW3NdPUguSyhhLGIsY1tzXSl9LAp5OmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyPWMubGVu
+Z3RoCmZvcihzPTI7czxyO3MrPTMpY1tzXT1ILksoYSxiLGNbc10pfSwKVFY6ZnVuY3Rpb24oYSxiLGMp
+e3ZhciBzLHIscT1iLnkKaWYocT09PTEwKXtpZihjPT09MClyZXR1cm4gYi56CnM9Yi5RCnI9cy5sZW5n
+dGgKaWYoYzw9cilyZXR1cm4gc1tjLTFdCmMtPXIKYj1iLnoKcT1iLnl9ZWxzZSBpZihjPT09MClyZXR1
+cm4gYgppZihxIT09OSl0aHJvdyBILmIoUC5oVigiSW5kZXhlZCBiYXNlIG11c3QgYmUgYW4gaW50ZXJm
+YWNlIHR5cGUiKSkKcz1iLlEKaWYoYzw9cy5sZW5ndGgpcmV0dXJuIHNbYy0xXQp0aHJvdyBILmIoUC5o
+VigiQmFkIGluZGV4ICIrYysiIGZvciAiK2IudygwKSkpfSwKV2U6ZnVuY3Rpb24oYSxiLGMsZCxlKXt2
+YXIgcyxyLHEscCxvLG4sbSxsLGssagppZihiPT09ZClyZXR1cm4hMAppZighSC5BOChkKSlpZighKGQ9
+PT10Ll8pKXM9ZD09PXQuSwplbHNlIHM9ITAKZWxzZSBzPSEwCmlmKHMpcmV0dXJuITAKcj1iLnkKaWYo
+cj09PTQpcmV0dXJuITAKaWYoSC5BOChiKSlyZXR1cm4hMQppZihiLnkhPT0xKXM9Yj09PXQuUHx8Yj09
+PXQuVAplbHNlIHM9ITAKaWYocylyZXR1cm4hMApxPXI9PT0xMwppZihxKWlmKEguV2UoYSxjW2Iuel0s
+YyxkLGUpKXJldHVybiEwCnA9ZC55CmlmKHI9PT02KXJldHVybiBILldlKGEsYi56LGMsZCxlKQppZihw
+PT09Nil7cz1kLnoKcmV0dXJuIEguV2UoYSxiLGMscyxlKX1pZihyPT09OCl7aWYoIUguV2UoYSxiLnos
+YyxkLGUpKXJldHVybiExCnJldHVybiBILldlKGEsSC54WihhLGIpLGMsZCxlKX1pZihyPT09Nyl7cz1I
+LldlKGEsYi56LGMsZCxlKQpyZXR1cm4gc31pZihwPT09OCl7aWYoSC5XZShhLGIsYyxkLnosZSkpcmV0
+dXJuITAKcmV0dXJuIEguV2UoYSxiLGMsSC54WihhLGQpLGUpfWlmKHA9PT03KXtzPUguV2UoYSxiLGMs
+ZC56LGUpCnJldHVybiBzfWlmKHEpcmV0dXJuITEKcz1yIT09MTEKaWYoKCFzfHxyPT09MTIpJiZkPT09
+dC5ZKXJldHVybiEwCmlmKHA9PT0xMil7aWYoYj09PXQueClyZXR1cm4hMAppZihyIT09MTIpcmV0dXJu
+ITEKbz1iLlEKbj1kLlEKbT1vLmxlbmd0aAppZihtIT09bi5sZW5ndGgpcmV0dXJuITEKYz1jPT1udWxs
+P286by5jb25jYXQoYykKZT1lPT1udWxsP246bi5jb25jYXQoZSkKZm9yKGw9MDtsPG07KytsKXtrPW9b
+bF0Kaj1uW2xdCmlmKCFILldlKGEsayxjLGosZSl8fCFILldlKGEsaixlLGssYykpcmV0dXJuITF9cmV0
+dXJuIEguYk8oYSxiLnosYyxkLnosZSl9aWYocD09PTExKXtpZihiPT09dC54KXJldHVybiEwCmlmKHMp
+cmV0dXJuITEKcmV0dXJuIEguYk8oYSxiLGMsZCxlKX1pZihyPT09OSl7aWYocCE9PTkpcmV0dXJuITEK
+cmV0dXJuIEgucEcoYSxiLGMsZCxlKX1yZXR1cm4hMX0sCmJPOmZ1bmN0aW9uKGEyLGEzLGE0LGE1LGE2
+KXt2YXIgcyxyLHEscCxvLG4sbSxsLGssaixpLGgsZyxmLGUsZCxjLGIsYSxhMCxhMQppZighSC5XZShh
+MixhMy56LGE0LGE1LnosYTYpKXJldHVybiExCnM9YTMuUQpyPWE1LlEKcT1zLmEKcD1yLmEKbz1xLmxl
+bmd0aApuPXAubGVuZ3RoCmlmKG8+bilyZXR1cm4hMQptPW4tbwpsPXMuYgprPXIuYgpqPWwubGVuZ3Ro
+Cmk9ay5sZW5ndGgKaWYobytqPG4raSlyZXR1cm4hMQpmb3IoaD0wO2g8bzsrK2gpe2c9cVtoXQppZigh
+SC5XZShhMixwW2hdLGE2LGcsYTQpKXJldHVybiExfWZvcihoPTA7aDxtOysraCl7Zz1sW2hdCmlmKCFI
+LldlKGEyLHBbbytoXSxhNixnLGE0KSlyZXR1cm4hMX1mb3IoaD0wO2g8aTsrK2gpe2c9bFttK2hdCmlm
+KCFILldlKGEyLGtbaF0sYTYsZyxhNCkpcmV0dXJuITF9Zj1zLmMKZT1yLmMKZD1mLmxlbmd0aApjPWUu
+bGVuZ3RoCmZvcihiPTAsYT0wO2E8YzthKz0zKXthMD1lW2FdCmZvcig7ITA7KXtpZihiPj1kKXJldHVy
+biExCmExPWZbYl0KYis9MwppZihhMDxhMSlyZXR1cm4hMQppZihhMTxhMCljb250aW51ZQpnPWZbYi0x
+XQppZighSC5XZShhMixlW2ErMl0sYTYsZyxhNCkpcmV0dXJuITEKYnJlYWt9fXJldHVybiEwfSwKcEc6
+ZnVuY3Rpb24oYSxiLGMsZCxlKXt2YXIgcyxyLHEscCxvLG4sbSxsLGs9Yi56LGo9ZC56CmlmKGs9PT1q
+KXtzPWIuUQpyPWQuUQpxPXMubGVuZ3RoCmZvcihwPTA7cDxxOysrcCl7bz1zW3BdCm49cltwXQppZigh
+SC5XZShhLG8sYyxuLGUpKXJldHVybiExfXJldHVybiEwfWlmKGQ9PT10LkspcmV0dXJuITAKbT1ILlFv
+KGEsaykKaWYobT09bnVsbClyZXR1cm4hMQpsPW1bal0KaWYobD09bnVsbClyZXR1cm4hMQpxPWwubGVu
+Z3RoCnI9ZC5RCmZvcihwPTA7cDxxOysrcClpZighSC5XZShhLEguY0UoYSxiLGxbcF0pLGMscltwXSxl
+KSlyZXR1cm4hMQpyZXR1cm4hMH0sCmxSOmZ1bmN0aW9uKGEpe3ZhciBzLHI9YS55CmlmKCEoYT09PXQu
+UHx8YT09PXQuVCkpaWYoIUguQTgoYSkpaWYociE9PTcpaWYoIShyPT09NiYmSC5sUihhLnopKSlzPXI9
+PT04JiZILmxSKGEueikKZWxzZSBzPSEwCmVsc2Ugcz0hMAplbHNlIHM9ITAKZWxzZSBzPSEwCnJldHVy
+biBzfSwKY2M6ZnVuY3Rpb24oYSl7dmFyIHMKaWYoIUguQTgoYSkpaWYoIShhPT09dC5fKSlzPWE9PT10
+LksKZWxzZSBzPSEwCmVsc2Ugcz0hMApyZXR1cm4gc30sCkE4OmZ1bmN0aW9uKGEpe3ZhciBzPWEueQpy
+ZXR1cm4gcz09PTJ8fHM9PT0zfHxzPT09NHx8cz09PTV8fGE9PT10Lld9LApJeDpmdW5jdGlvbihhLGIp
+e3ZhciBzLHIscT1PYmplY3Qua2V5cyhiKSxwPXEubGVuZ3RoCmZvcihzPTA7czxwOysrcyl7cj1xW3Nd
+CmFbcl09YltyXX19LApKYzpmdW5jdGlvbiBKYyhhLGIpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy54
+PV8ucj1fLmM9bnVsbApfLnk9MApfLmN5PV8uY3g9Xy5jaD1fLlE9Xy56PW51bGx9LApHOmZ1bmN0aW9u
+IEcoKXt0aGlzLmM9dGhpcy5iPXRoaXMuYT1udWxsfSwKbFk6ZnVuY3Rpb24gbFkoYSl7dGhpcy5hPWF9
+LAprUzpmdW5jdGlvbiBrUygpe30sCmlNOmZ1bmN0aW9uIGlNKGEpe3RoaXMuYT1hfSwKUjk6ZnVuY3Rp
+b24oYSl7cmV0dXJuIHQudy5iKGEpfHx0LkIuYihhKXx8dC5kei5iKGEpfHx0LkkuYihhKXx8dC5BLmIo
+YSl8fHQuZzQuYihhKXx8dC5nMi5iKGEpfSwKSmc6ZnVuY3Rpb24oYSl7cmV0dXJuIHYubWFuZ2xlZEds
+b2JhbE5hbWVzW2FdfX0sSj17ClF1OmZ1bmN0aW9uKGEsYixjLGQpe3JldHVybntpOmEscDpiLGU6Yyx4
+OmR9fSwKa3M6ZnVuY3Rpb24oYSl7dmFyIHMscixxLHAsbyxuPWFbdi5kaXNwYXRjaFByb3BlcnR5TmFt
+ZV0KaWYobj09bnVsbClpZigkLkJ2PT1udWxsKXtILlhEKCkKbj1hW3YuZGlzcGF0Y2hQcm9wZXJ0eU5h
+bWVdfWlmKG4hPW51bGwpe3M9bi5wCmlmKCExPT09cylyZXR1cm4gbi5pCmlmKCEwPT09cylyZXR1cm4g
+YQpyPU9iamVjdC5nZXRQcm90b3R5cGVPZihhKQppZihzPT09cilyZXR1cm4gbi5pCmlmKG4uZT09PXIp
+dGhyb3cgSC5iKFAuU1koIlJldHVybiBpbnRlcmNlcHRvciBmb3IgIitILkVqKHMoYSxuKSkpKX1xPWEu
+Y29uc3RydWN0b3IKaWYocT09bnVsbClwPW51bGwKZWxzZXtvPSQuem0KaWYobz09bnVsbClvPSQuem09
+di5nZXRJc29sYXRlVGFnKCJfJGRhcnRfanMiKQpwPXFbb119aWYocCE9bnVsbClyZXR1cm4gcApwPUgu
+dzMoYSkKaWYocCE9bnVsbClyZXR1cm4gcAppZih0eXBlb2YgYT09ImZ1bmN0aW9uIilyZXR1cm4gQy5E
+RwpzPU9iamVjdC5nZXRQcm90b3R5cGVPZihhKQppZihzPT1udWxsKXJldHVybiBDLlpRCmlmKHM9PT1P
+YmplY3QucHJvdG90eXBlKXJldHVybiBDLlpRCmlmKHR5cGVvZiBxPT0iZnVuY3Rpb24iKXtvPSQuem0K
+aWYobz09bnVsbClvPSQuem09di5nZXRJc29sYXRlVGFnKCJfJGRhcnRfanMiKQpPYmplY3QuZGVmaW5l
+UHJvcGVydHkocSxvLHt2YWx1ZTpDLnZCLGVudW1lcmFibGU6ZmFsc2Usd3JpdGFibGU6dHJ1ZSxjb25m
+aWd1cmFibGU6dHJ1ZX0pCnJldHVybiBDLnZCfXJldHVybiBDLnZCfSwKUWk6ZnVuY3Rpb24oYSxiKXtp
+ZihhPDB8fGE+NDI5NDk2NzI5NSl0aHJvdyBILmIoUC5URShhLDAsNDI5NDk2NzI5NSwibGVuZ3RoIixu
+dWxsKSkKcmV0dXJuIEoucHkobmV3IEFycmF5KGEpLGIpfSwKS2g6ZnVuY3Rpb24oYSxiKXtpZihhPDAp
+dGhyb3cgSC5iKFAueFkoIkxlbmd0aCBtdXN0IGJlIGEgbm9uLW5lZ2F0aXZlIGludGVnZXI6ICIrYSkp
+CnJldHVybiBILlZNKG5ldyBBcnJheShhKSxiLkMoImpkPDA+IikpfSwKcHk6ZnVuY3Rpb24oYSxiKXty
+ZXR1cm4gSi5FcChILlZNKGEsYi5DKCJqZDwwPiIpKSxiKX0sCkVwOmZ1bmN0aW9uKGEsYil7YS5maXhl
+ZCRsZW5ndGg9QXJyYXkKcmV0dXJuIGF9LAp6QzpmdW5jdGlvbihhKXthLmZpeGVkJGxlbmd0aD1BcnJh
+eQphLmltbXV0YWJsZSRsaXN0PUFycmF5CnJldHVybiBhfSwKR2E6ZnVuY3Rpb24oYSl7aWYoYTwyNTYp
+c3dpdGNoKGEpe2Nhc2UgOTpjYXNlIDEwOmNhc2UgMTE6Y2FzZSAxMjpjYXNlIDEzOmNhc2UgMzI6Y2Fz
+ZSAxMzM6Y2FzZSAxNjA6cmV0dXJuITAKZGVmYXVsdDpyZXR1cm4hMX1zd2l0Y2goYSl7Y2FzZSA1NzYw
+OmNhc2UgODE5MjpjYXNlIDgxOTM6Y2FzZSA4MTk0OmNhc2UgODE5NTpjYXNlIDgxOTY6Y2FzZSA4MTk3
+OmNhc2UgODE5ODpjYXNlIDgxOTk6Y2FzZSA4MjAwOmNhc2UgODIwMTpjYXNlIDgyMDI6Y2FzZSA4MjMy
+OmNhc2UgODIzMzpjYXNlIDgyMzk6Y2FzZSA4Mjg3OmNhc2UgMTIyODg6Y2FzZSA2NTI3OTpyZXR1cm4h
+MApkZWZhdWx0OnJldHVybiExfX0sCm1tOmZ1bmN0aW9uKGEsYil7dmFyIHMscgpmb3Iocz1hLmxlbmd0
+aDtiPHM7KXtyPUMueEIuVyhhLGIpCmlmKHIhPT0zMiYmciE9PTEzJiYhSi5HYShyKSlicmVhazsrK2J9
+cmV0dXJuIGJ9LApjMTpmdW5jdGlvbihhLGIpe3ZhciBzLHIKZm9yKDtiPjA7Yj1zKXtzPWItMQpyPUMu
+eEIuTyhhLHMpCmlmKHIhPT0zMiYmciE9PTEzJiYhSi5HYShyKSlicmVha31yZXR1cm4gYn0sClRKOmZ1
+bmN0aW9uKGEpe2lmKHR5cGVvZiBhPT0ibnVtYmVyIilyZXR1cm4gSi5xSS5wcm90b3R5cGUKaWYodHlw
+ZW9mIGE9PSJzdHJpbmciKXJldHVybiBKLkRyLnByb3RvdHlwZQppZihhPT1udWxsKXJldHVybiBhCmlm
+KGEuY29uc3RydWN0b3I9PUFycmF5KXJldHVybiBKLmpkLnByb3RvdHlwZQppZih0eXBlb2YgYSE9Im9i
+amVjdCIpe2lmKHR5cGVvZiBhPT0iZnVuY3Rpb24iKXJldHVybiBKLmM1LnByb3RvdHlwZQpyZXR1cm4g
+YX1pZihhIGluc3RhbmNlb2YgUC5NaClyZXR1cm4gYQpyZXR1cm4gSi5rcyhhKX0sClU2OmZ1bmN0aW9u
+KGEpe2lmKHR5cGVvZiBhPT0ic3RyaW5nIilyZXR1cm4gSi5Eci5wcm90b3R5cGUKaWYoYT09bnVsbCly
+ZXR1cm4gYQppZihhLmNvbnN0cnVjdG9yPT1BcnJheSlyZXR1cm4gSi5qZC5wcm90b3R5cGUKaWYodHlw
+ZW9mIGEhPSJvYmplY3QiKXtpZih0eXBlb2YgYT09ImZ1bmN0aW9uIilyZXR1cm4gSi5jNS5wcm90b3R5
+cGUKcmV0dXJuIGF9aWYoYSBpbnN0YW5jZW9mIFAuTWgpcmV0dXJuIGEKcmV0dXJuIEoua3MoYSl9LApZ
+RTpmdW5jdGlvbihhKXtpZihhPT1udWxsKXJldHVybiBhCmlmKHR5cGVvZiBhIT0ib2JqZWN0Iil7aWYo
+dHlwZW9mIGE9PSJmdW5jdGlvbiIpcmV0dXJuIEouYzUucHJvdG90eXBlCnJldHVybiBhfWlmKGEgaW5z
+dGFuY2VvZiBQLk1oKXJldHVybiBhCnJldHVybiBKLmtzKGEpfSwKaWE6ZnVuY3Rpb24oYSl7aWYodHlw
+ZW9mIGE9PSJudW1iZXIiKXtpZihNYXRoLmZsb29yKGEpPT1hKXJldHVybiBKLmJVLnByb3RvdHlwZQpy
+ZXR1cm4gSi5rRC5wcm90b3R5cGV9aWYodHlwZW9mIGE9PSJzdHJpbmciKXJldHVybiBKLkRyLnByb3Rv
+dHlwZQppZihhPT1udWxsKXJldHVybiBKLndlLnByb3RvdHlwZQppZih0eXBlb2YgYT09ImJvb2xlYW4i
+KXJldHVybiBKLnlFLnByb3RvdHlwZQppZihhLmNvbnN0cnVjdG9yPT1BcnJheSlyZXR1cm4gSi5qZC5w
+cm90b3R5cGUKaWYodHlwZW9mIGEhPSJvYmplY3QiKXtpZih0eXBlb2YgYT09ImZ1bmN0aW9uIilyZXR1
+cm4gSi5jNS5wcm90b3R5cGUKcmV0dXJuIGF9aWYoYSBpbnN0YW5jZW9mIFAuTWgpcmV0dXJuIGEKcmV0
+dXJuIEoua3MoYSl9LApyWTpmdW5jdGlvbihhKXtpZih0eXBlb2YgYT09InN0cmluZyIpcmV0dXJuIEou
+RHIucHJvdG90eXBlCmlmKGE9PW51bGwpcmV0dXJuIGEKaWYoIShhIGluc3RhbmNlb2YgUC5NaCkpcmV0
+dXJuIEoua2QucHJvdG90eXBlCnJldHVybiBhfSwKdmQ6ZnVuY3Rpb24oYSl7aWYodHlwZW9mIGE9PSJu
+dW1iZXIiKXJldHVybiBKLnFJLnByb3RvdHlwZQppZihhPT1udWxsKXJldHVybiBhCmlmKCEoYSBpbnN0
+YW5jZW9mIFAuTWgpKXJldHVybiBKLmtkLnByb3RvdHlwZQpyZXR1cm4gYX0sCncxOmZ1bmN0aW9uKGEp
+e2lmKGE9PW51bGwpcmV0dXJuIGEKaWYoYS5jb25zdHJ1Y3Rvcj09QXJyYXkpcmV0dXJuIEouamQucHJv
+dG90eXBlCmlmKHR5cGVvZiBhIT0ib2JqZWN0Iil7aWYodHlwZW9mIGE9PSJmdW5jdGlvbiIpcmV0dXJu
+IEouYzUucHJvdG90eXBlCnJldHVybiBhfWlmKGEgaW5zdGFuY2VvZiBQLk1oKXJldHVybiBhCnJldHVy
+biBKLmtzKGEpfSwKQTU6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gSi53MShhKS5lUihhLGIpfSwKRDE6ZnVu
+Y3Rpb24oYSxiKXtyZXR1cm4gSi5yWShhKS5PWShhLGIpfSwKRWg6ZnVuY3Rpb24oYSxiLGMpe3JldHVy
+biBKLllFKGEpLm1LKGEsYixjKX0sCkVsOmZ1bmN0aW9uKGEsYil7cmV0dXJuIEoudzEoYSkuZHIoYSxi
+KX0sCkY3OmZ1bmN0aW9uKGEpe3JldHVybiBKLlU2KGEpLmdvcihhKX0sCkZMOmZ1bmN0aW9uKGEsYil7
+cmV0dXJuIEouclkoYSkuZGQoYSxiKX0sCkdBOmZ1bmN0aW9uKGEsYil7cmV0dXJuIEoudzEoYSkuRShh
+LGIpfSwKSG06ZnVuY3Rpb24oYSl7cmV0dXJuIEouVTYoYSkuZ0EoYSl9LApJVDpmdW5jdGlvbihhKXty
+ZXR1cm4gSi53MShhKS5nbShhKX0sCkp5OmZ1bmN0aW9uKGEsYil7cmV0dXJuIEouaWEoYSkuZTcoYSxi
+KX0sCktWOmZ1bmN0aW9uKGEsYil7cmV0dXJuIEouclkoYSkueW4oYSxiKX0sCkx0OmZ1bmN0aW9uKGEp
+e3JldHVybiBKLllFKGEpLndnKGEpfSwKTTE6ZnVuY3Rpb24oYSxiLGMpe3JldHVybiBKLncxKGEpLkUy
+KGEsYixjKX0sCk11OmZ1bmN0aW9uKGEsYil7cmV0dXJuIEouWUUoYSkuc1AoYSxiKX0sClF6OmZ1bmN0
+aW9uKGEsYil7cmV0dXJuIEouclkoYSkuVyhhLGIpfSwKUk06ZnVuY3Rpb24oYSxiKXtpZihhPT1udWxs
+KXJldHVybiBiPT1udWxsCmlmKHR5cGVvZiBhIT0ib2JqZWN0IilyZXR1cm4gYiE9bnVsbCYmYT09PWIK
+cmV0dXJuIEouaWEoYSkuRE4oYSxiKX0sClJYOmZ1bmN0aW9uKGEpe3JldHVybiBKLncxKGEpLmJyKGEp
+fSwKVDA6ZnVuY3Rpb24oYSl7cmV0dXJuIEouclkoYSkuYlMoYSl9LApWdTpmdW5jdGlvbihhKXtyZXR1
+cm4gSi52ZChhKS56UShhKX0sCmE2OmZ1bmN0aW9uKGEsYil7cmV0dXJuIEouclkoYSkuTyhhLGIpfSwK
+YXU6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gSi5yWShhKS5uQyhhLGIpfSwKYlQ6ZnVuY3Rpb24oYSl7cmV0
+dXJuIEouWUUoYSkuRDQoYSl9LApiYjpmdW5jdGlvbihhLGIpe2lmKHR5cGVvZiBhPT0ibnVtYmVyIiYm
+dHlwZW9mIGI9PSJudW1iZXIiKXJldHVybiBhK2IKcmV0dXJuIEouVEooYSkuaChhLGIpfSwKY0g6ZnVu
+Y3Rpb24oYSl7cmV0dXJuIEouclkoYSkuaGMoYSl9LApkUjpmdW5jdGlvbihhKXtyZXR1cm4gSi5ZRShh
+KS5nUChhKX0sCmRaOmZ1bmN0aW9uKGEsYixjLGQpe3JldHVybiBKLllFKGEpLk9uKGEsYixjLGQpfSwK
+ZGc6ZnVuY3Rpb24oYSxiLGMsZCl7cmV0dXJuIEouclkoYSkuaTcoYSxiLGMsZCl9LApkaDpmdW5jdGlv
+bihhKXtyZXR1cm4gSi5ZRShhKS5GRihhKX0sCmRyOmZ1bmN0aW9uKGEsYil7cmV0dXJuIEouWUUoYSku
+c2E0KGEsYil9LApoZjpmdW5jdGlvbihhKXtyZXR1cm4gSi5pYShhKS5naU8oYSl9LAppZzpmdW5jdGlv
+bihhKXtyZXR1cm4gSi5ZRShhKS5nUWcoYSl9LApqOmZ1bmN0aW9uKGEpe3JldHVybiBKLmlhKGEpLnco
+YSl9LApsNTpmdW5jdGlvbihhLGIpe3JldHVybiBKLllFKGEpLnNoZihhLGIpfSwKbGQ6ZnVuY3Rpb24o
+YSxiLGMpe3JldHVybiBKLnJZKGEpLk5qKGEsYixjKX0sCnA0OmZ1bmN0aW9uKGEsYil7cmV0dXJuIEou
+clkoYSkuVGMoYSxiKX0sCnEwOmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gSi5yWShhKS5RaShhLGIsYyl9
+LApxRjpmdW5jdGlvbihhKXtyZXR1cm4gSi5ZRShhKS5nVmwoYSl9LAp0SDpmdW5jdGlvbihhLGIsYyl7
+cmV0dXJuIEouWUUoYSkucGsoYSxiLGMpfSwKdTk6ZnVuY3Rpb24oYSxiLGMpe3JldHVybiBKLncxKGEp
+Llk1KGEsYixjKX0sCnVVOmZ1bmN0aW9uKGEpe3JldHVybiBKLlU2KGEpLmdsMChhKX0sCndmOmZ1bmN0
+aW9uKGEsYil7cmV0dXJuIEouWUUoYSkuc1JOKGEsYil9LAp4OTpmdW5jdGlvbihhLGIpe2lmKHR5cGVv
+ZiBiPT09Im51bWJlciIpaWYoYS5jb25zdHJ1Y3Rvcj09QXJyYXl8fHR5cGVvZiBhPT0ic3RyaW5nInx8
+SC53VihhLGFbdi5kaXNwYXRjaFByb3BlcnR5TmFtZV0pKWlmKGI+Pj4wPT09YiYmYjxhLmxlbmd0aCly
+ZXR1cm4gYVtiXQpyZXR1cm4gSi5VNihhKS5xKGEsYil9LAp6bDpmdW5jdGlvbihhLGIpe3JldHVybiBK
+LlU2KGEpLnRnKGEsYil9LApHdjpmdW5jdGlvbiBHdigpe30sCnlFOmZ1bmN0aW9uIHlFKCl7fSwKd2U6
+ZnVuY3Rpb24gd2UoKXt9LApNRjpmdW5jdGlvbiBNRigpe30sCmlDOmZ1bmN0aW9uIGlDKCl7fSwKa2Q6
+ZnVuY3Rpb24ga2QoKXt9LApjNTpmdW5jdGlvbiBjNSgpe30sCmpkOmZ1bmN0aW9uIGpkKGEpe3RoaXMu
+JHRpPWF9LApQbzpmdW5jdGlvbiBQbyhhKXt0aGlzLiR0aT1hfSwKbTE6ZnVuY3Rpb24gbTEoYSxiLGMp
+e3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5jPTAKXy5kPW51bGwKXy4kdGk9Y30sCnFJOmZ1bmN0aW9u
+IHFJKCl7fSwKYlU6ZnVuY3Rpb24gYlUoKXt9LAprRDpmdW5jdGlvbiBrRCgpe30sCkRyOmZ1bmN0aW9u
+IERyKCl7fX0sUD17Ck9qOmZ1bmN0aW9uKCl7dmFyIHMscixxPXt9CmlmKHNlbGYuc2NoZWR1bGVJbW1l
+ZGlhdGUhPW51bGwpcmV0dXJuIFAuRVgoKQppZihzZWxmLk11dGF0aW9uT2JzZXJ2ZXIhPW51bGwmJnNl
+bGYuZG9jdW1lbnQhPW51bGwpe3M9c2VsZi5kb2N1bWVudC5jcmVhdGVFbGVtZW50KCJkaXYiKQpyPXNl
+bGYuZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgic3BhbiIpCnEuYT1udWxsCm5ldyBzZWxmLk11dGF0aW9u
+T2JzZXJ2ZXIoSC50UihuZXcgUC50aChxKSwxKSkub2JzZXJ2ZShzLHtjaGlsZExpc3Q6dHJ1ZX0pCnJl
+dHVybiBuZXcgUC5oYShxLHMscil9ZWxzZSBpZihzZWxmLnNldEltbWVkaWF0ZSE9bnVsbClyZXR1cm4g
+UC55dCgpCnJldHVybiBQLnFXKCl9LApaVjpmdW5jdGlvbihhKXtzZWxmLnNjaGVkdWxlSW1tZWRpYXRl
+KEgudFIobmV3IFAuVnModC5NLmEoYSkpLDApKX0sCm9BOmZ1bmN0aW9uKGEpe3NlbGYuc2V0SW1tZWRp
+YXRlKEgudFIobmV3IFAuRnQodC5NLmEoYSkpLDApKX0sCkJ6OmZ1bmN0aW9uKGEpe3QuTS5hKGEpClAu
+UU4oMCxhKX0sClFOOmZ1bmN0aW9uKGEsYil7dmFyIHM9bmV3IFAuVzMoKQpzLkNZKGEsYikKcmV0dXJu
+IHN9LApGWDpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFAuaWgobmV3IFAudnMoJC5YMyxhLkMoInZzPDA+
+IikpLGEuQygiaWg8MD4iKSl9LApESTpmdW5jdGlvbihhLGIpe2EuJDIoMCxudWxsKQpiLmI9ITAKcmV0
+dXJuIGIuYX0sCmpROmZ1bmN0aW9uKGEsYil7UC5KZShhLGIpfSwKeUM6ZnVuY3Rpb24oYSxiKXtiLmFN
+KDAsYSl9LApmMzpmdW5jdGlvbihhLGIpe2IudzAoSC5SdShhKSxILnRzKGEpKX0sCkplOmZ1bmN0aW9u
+KGEsYil7dmFyIHMscixxPW5ldyBQLldNKGIpLHA9bmV3IFAuU1goYikKaWYoYSBpbnN0YW5jZW9mIFAu
+dnMpYS5RZChxLHAsdC56KQplbHNle3M9dC56CmlmKHQuZS5iKGEpKWEuU3EocSxwLHMpCmVsc2V7cj1u
+ZXcgUC52cygkLlgzLHQuYykKci5hPTQKci5jPWEKci5RZChxLHAscyl9fX0sCmx6OmZ1bmN0aW9uKGEp
+e3ZhciBzPWZ1bmN0aW9uKGIsYyl7cmV0dXJuIGZ1bmN0aW9uKGQsZSl7d2hpbGUodHJ1ZSl0cnl7Yihk
+LGUpCmJyZWFrfWNhdGNoKHIpe2U9cgpkPWN9fX0oYSwxKQpyZXR1cm4gJC5YMy5MaihuZXcgUC5Hcyhz
+KSx0LkgsdC5TLHQueil9LApJRzpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFAuRnkoYSwxKX0sClRoOmZ1
+bmN0aW9uKCl7cmV0dXJuIEMud1F9LApZbTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFAuRnkoYSwzKX0s
+CmwwOmZ1bmN0aW9uKGEsYil7cmV0dXJuIG5ldyBQLnE0KGEsYi5DKCJxNDwwPiIpKX0sClRsOmZ1bmN0
+aW9uKGEsYil7dmFyIHM9SC5jYihhLCJlcnJvciIsdC5LKQpyZXR1cm4gbmV3IFAuQ3cocyxiPT1udWxs
+P1AudjAoYSk6Yil9LAp2MDpmdW5jdGlvbihhKXt2YXIgcwppZih0LnIuYihhKSl7cz1hLmdJSSgpCmlm
+KHMhPW51bGwpcmV0dXJuIHN9cmV0dXJuIEMucGR9LApBOTpmdW5jdGlvbihhLGIpe3ZhciBzLHIscQpm
+b3Iocz10LmM7cj1hLmEscj09PTI7KWE9cy5hKGEuYykKaWYocj49NCl7cT1iLmFoKCkKYi5hPWEuYQpi
+LmM9YS5jClAuSFooYixxKX1lbHNle3E9dC5GLmEoYi5jKQpiLmE9MgpiLmM9YQphLmpRKHEpfX0sCkha
+OmZ1bmN0aW9uKGEwLGExKXt2YXIgcyxyLHEscCxvLG4sbSxsLGssaixpLGgsZyxmLGUsZCxjPW51bGws
+Yj17fSxhPWIuYT1hMApmb3Iocz10Lm4scj10LkYscT10LmU7ITA7KXtwPXt9Cm89YS5hPT09OAppZihh
+MT09bnVsbCl7aWYobyl7bj1zLmEoYS5jKQpQLkwyKGMsYyxhLmIsbi5hLG4uYil9cmV0dXJufXAuYT1h
+MQptPWExLmEKZm9yKGE9YTE7bSE9bnVsbDthPW0sbT1sKXthLmE9bnVsbApQLkhaKGIuYSxhKQpwLmE9
+bQpsPW0uYX1rPWIuYQpqPWsuYwpwLmI9bwpwLmM9agppPSFvCmlmKGkpe2g9YS5jCmg9KGgmMSkhPT0w
+fHwoaCYxNSk9PT04fWVsc2UgaD0hMAppZihoKXtnPWEuYi5iCmlmKG8pe2g9ay5iPT09ZwpoPSEoaHx8
+aCl9ZWxzZSBoPSExCmlmKGgpe3MuYShqKQpQLkwyKGMsYyxrLmIsai5hLGouYikKcmV0dXJufWY9JC5Y
+MwppZihmIT09ZykkLlgzPWcKZWxzZSBmPWMKYT1hLmMKaWYoKGEmMTUpPT09OCluZXcgUC5SVChwLGIs
+bykuJDAoKQplbHNlIGlmKGkpe2lmKChhJjEpIT09MCluZXcgUC5ycShwLGopLiQwKCl9ZWxzZSBpZigo
+YSYyKSE9PTApbmV3IFAuUlcoYixwKS4kMCgpCmlmKGYhPW51bGwpJC5YMz1mCmE9cC5jCmlmKHEuYihh
+KSl7az1wLmEuJHRpCms9ay5DKCJiODwyPiIpLmIoYSl8fCFrLlFbMV0uYihhKX1lbHNlIGs9ITEKaWYo
+ayl7cS5hKGEpCmU9cC5hLmIKaWYoYSBpbnN0YW5jZW9mIFAudnMpaWYoYS5hPj00KXtkPXIuYShlLmMp
+CmUuYz1udWxsCmExPWUuTjgoZCkKZS5hPWEuYQplLmM9YS5jCmIuYT1hCmNvbnRpbnVlfWVsc2UgUC5B
+OShhLGUpCmVsc2UgZS5lYyhhKQpyZXR1cm59fWU9cC5hLmIKZD1yLmEoZS5jKQplLmM9bnVsbAphMT1l
+Lk44KGQpCmE9cC5iCms9cC5jCmlmKCFhKXtlLiR0aS5jLmEoaykKZS5hPTQKZS5jPWt9ZWxzZXtzLmEo
+aykKZS5hPTgKZS5jPWt9Yi5hPWUKYT1lfX0sClZIOmZ1bmN0aW9uKGEsYil7dmFyIHMKaWYodC5hZy5i
+KGEpKXJldHVybiBiLkxqKGEsdC56LHQuSyx0LmwpCnM9dC5iSQppZihzLmIoYSkpcmV0dXJuIHMuYShh
+KQp0aHJvdyBILmIoUC5MMyhhLCJvbkVycm9yIiwiRXJyb3IgaGFuZGxlciBtdXN0IGFjY2VwdCBvbmUg
+T2JqZWN0IG9yIG9uZSBPYmplY3QgYW5kIGEgU3RhY2tUcmFjZSBhcyBhcmd1bWVudHMsIGFuZCByZXR1
+cm4gYSB2YWxpZCByZXN1bHQiKSl9LApwdTpmdW5jdGlvbigpe3ZhciBzLHIKZm9yKHM9JC5TNjtzIT1u
+dWxsO3M9JC5TNil7JC5tZz1udWxsCnI9cy5iCiQuUzY9cgppZihyPT1udWxsKSQuazg9bnVsbApzLmEu
+JDAoKX19LAplTjpmdW5jdGlvbigpeyQuVUQ9ITAKdHJ5e1AucHUoKX1maW5hbGx5eyQubWc9bnVsbAok
+LlVEPSExCmlmKCQuUzYhPW51bGwpJC51dCgpLiQxKFAuVUkoKSl9fSwKZVc6ZnVuY3Rpb24oYSl7dmFy
+IHM9bmV3IFAuT00oYSkscj0kLms4CmlmKHI9PW51bGwpeyQuUzY9JC5rOD1zCmlmKCEkLlVEKSQudXQo
+KS4kMShQLlVJKCkpfWVsc2UgJC5rOD1yLmI9c30sCnJSOmZ1bmN0aW9uKGEpe3ZhciBzLHIscSxwPSQu
+UzYKaWYocD09bnVsbCl7UC5lVyhhKQokLm1nPSQuazgKcmV0dXJufXM9bmV3IFAuT00oYSkKcj0kLm1n
+CmlmKHI9PW51bGwpe3MuYj1wCiQuUzY9JC5tZz1zfWVsc2V7cT1yLmIKcy5iPXEKJC5tZz1yLmI9cwpp
+ZihxPT1udWxsKSQuazg9c319LApyYjpmdW5jdGlvbihhKXt2YXIgcz1udWxsLHI9JC5YMwppZihDLk5V
+PT09cil7UC5UayhzLHMsQy5OVSxhKQpyZXR1cm59UC5UayhzLHMscix0Lk0uYShyLkdZKGEpKSl9LApR
+dzpmdW5jdGlvbihhLGIpe0guY2IoYSwic3RyZWFtIix0LkspCnJldHVybiBuZXcgUC54SShiLkMoInhJ
+PDA+IikpfSwKTDI6ZnVuY3Rpb24oYSxiLGMsZCxlKXtQLnJSKG5ldyBQLnBLKGQsZSkpfSwKVDg6ZnVu
+Y3Rpb24oYSxiLGMsZCxlKXt2YXIgcyxyPSQuWDMKaWYocj09PWMpcmV0dXJuIGQuJDAoKQokLlgzPWMK
+cz1yCnRyeXtyPWQuJDAoKQpyZXR1cm4gcn1maW5hbGx5eyQuWDM9c319LAp5djpmdW5jdGlvbihhLGIs
+YyxkLGUsZixnKXt2YXIgcyxyPSQuWDMKaWYocj09PWMpcmV0dXJuIGQuJDEoZSkKJC5YMz1jCnM9cgp0
+cnl7cj1kLiQxKGUpCnJldHVybiByfWZpbmFsbHl7JC5YMz1zfX0sClF4OmZ1bmN0aW9uKGEsYixjLGQs
+ZSxmLGcsaCxpKXt2YXIgcyxyPSQuWDMKaWYocj09PWMpcmV0dXJuIGQuJDIoZSxmKQokLlgzPWMKcz1y
+CnRyeXtyPWQuJDIoZSxmKQpyZXR1cm4gcn1maW5hbGx5eyQuWDM9c319LApUazpmdW5jdGlvbihhLGIs
+YyxkKXt0Lk0uYShkKQppZihDLk5VIT09YylkPWMuR1koZCkKUC5lVyhkKX0sCnRoOmZ1bmN0aW9uIHRo
+KGEpe3RoaXMuYT1hfSwKaGE6ZnVuY3Rpb24gaGEoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMu
+Yz1jfSwKVnM6ZnVuY3Rpb24gVnMoYSl7dGhpcy5hPWF9LApGdDpmdW5jdGlvbiBGdChhKXt0aGlzLmE9
+YX0sClczOmZ1bmN0aW9uIFczKCl7fSwKeUg6ZnVuY3Rpb24geUgoYSxiKXt0aGlzLmE9YQp0aGlzLmI9
+Yn0sCmloOmZ1bmN0aW9uIGloKGEsYil7dGhpcy5hPWEKdGhpcy5iPSExCnRoaXMuJHRpPWJ9LApXTTpm
+dW5jdGlvbiBXTShhKXt0aGlzLmE9YX0sClNYOmZ1bmN0aW9uIFNYKGEpe3RoaXMuYT1hfSwKR3M6ZnVu
+Y3Rpb24gR3MoYSl7dGhpcy5hPWF9LApGeTpmdW5jdGlvbiBGeShhLGIpe3RoaXMuYT1hCnRoaXMuYj1i
+fSwKR1Y6ZnVuY3Rpb24gR1YoYSxiKXt2YXIgXz10aGlzCl8uYT1hCl8uZD1fLmM9Xy5iPW51bGwKXy4k
+dGk9Yn0sCnE0OmZ1bmN0aW9uIHE0KGEsYil7dGhpcy5hPWEKdGhpcy4kdGk9Yn0sCkN3OmZ1bmN0aW9u
+IEN3KGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApQZjpmdW5jdGlvbiBQZigpe30sClpmOmZ1bmN0aW9u
+IFpmKGEsYil7dGhpcy5hPWEKdGhpcy4kdGk9Yn0sCkZlOmZ1bmN0aW9uIEZlKGEsYixjLGQsZSl7dmFy
+IF89dGhpcwpfLmE9bnVsbApfLmI9YQpfLmM9YgpfLmQ9YwpfLmU9ZApfLiR0aT1lfSwKdnM6ZnVuY3Rp
+b24gdnMoYSxiKXt2YXIgXz10aGlzCl8uYT0wCl8uYj1hCl8uYz1udWxsCl8uJHRpPWJ9LApkYTpmdW5j
+dGlvbiBkYShhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKb1E6ZnVuY3Rpb24gb1EoYSxiKXt0aGlzLmE9
+YQp0aGlzLmI9Yn0sCnBWOmZ1bmN0aW9uIHBWKGEpe3RoaXMuYT1hfSwKVTc6ZnVuY3Rpb24gVTcoYSl7
+dGhpcy5hPWF9LAp2cjpmdW5jdGlvbiB2cihhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9
+LApydDpmdW5jdGlvbiBydChhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKS0Y6ZnVuY3Rpb24gS0YoYSxi
+KXt0aGlzLmE9YQp0aGlzLmI9Yn0sClpMOmZ1bmN0aW9uIFpMKGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9
+Ygp0aGlzLmM9Y30sClJUOmZ1bmN0aW9uIFJUKGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9
+Y30sCmpaOmZ1bmN0aW9uIGpaKGEpe3RoaXMuYT1hfSwKcnE6ZnVuY3Rpb24gcnEoYSxiKXt0aGlzLmE9
+YQp0aGlzLmI9Yn0sClJXOmZ1bmN0aW9uIFJXKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApPTTpmdW5j
+dGlvbiBPTShhKXt0aGlzLmE9YQp0aGlzLmI9bnVsbH0sCnFoOmZ1bmN0aW9uIHFoKCl7fSwKQjU6ZnVu
+Y3Rpb24gQjUoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCnVPOmZ1bmN0aW9uIHVPKGEsYil7dGhpcy5h
+PWEKdGhpcy5iPWJ9LApNTzpmdW5jdGlvbiBNTygpe30sCmtUOmZ1bmN0aW9uIGtUKCl7fSwKeEk6ZnVu
+Y3Rpb24geEkoYSl7dGhpcy4kdGk9YX0sCm0wOmZ1bmN0aW9uIG0wKCl7fSwKcEs6ZnVuY3Rpb24gcEso
+YSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCkppOmZ1bmN0aW9uIEppKCl7fSwKVnA6ZnVuY3Rpb24gVnAo
+YSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCk9SOmZ1bmN0aW9uIE9SKGEsYixjKXt0aGlzLmE9YQp0aGlz
+LmI9Ygp0aGlzLmM9Y30sCkVGOmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gYi5DKCJAPDA+IikuS3EoYyku
+QygiRm88MSwyPiIpLmEoSC5CNyhhLG5ldyBILk41KGIuQygiQDwwPiIpLktxKGMpLkMoIk41PDEsMj4i
+KSkpKX0sCkZsOmZ1bmN0aW9uKGEsYil7cmV0dXJuIG5ldyBILk41KGEuQygiQDwwPiIpLktxKGIpLkMo
+Ik41PDEsMj4iKSl9LApMczpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFAuYjYoYS5DKCJiNjwwPiIpKX0s
+ClQyOmZ1bmN0aW9uKCl7dmFyIHM9T2JqZWN0LmNyZWF0ZShudWxsKQpzWyI8bm9uLWlkZW50aWZpZXIt
+a2V5PiJdPXMKZGVsZXRlIHNbIjxub24taWRlbnRpZmllci1rZXk+Il0KcmV0dXJuIHN9LApyajpmdW5j
+dGlvbihhLGIsYyl7dmFyIHM9bmV3IFAubG0oYSxiLGMuQygibG08MD4iKSkKcy5jPWEuZQpyZXR1cm4g
+c30sCkVQOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyCmlmKFAuaEIoYSkpe2lmKGI9PT0iKCImJmM9PT0i
+KSIpcmV0dXJuIiguLi4pIgpyZXR1cm4gYisiLi4uIitjfXM9SC5WTShbXSx0LnMpCkMuTm0uaSgkLnhn
+LGEpCnRyeXtQLlZyKGEscyl9ZmluYWxseXtpZigwPj0kLnhnLmxlbmd0aClyZXR1cm4gSC5PSCgkLnhn
+LC0xKQokLnhnLnBvcCgpfXI9UC52ZyhiLHQudS5hKHMpLCIsICIpK2MKcmV0dXJuIHIuY2hhckNvZGVB
+dCgwKT09MD9yOnJ9LApXRTpmdW5jdGlvbihhLGIsYyl7dmFyIHMscgppZihQLmhCKGEpKXJldHVybiBi
+KyIuLi4iK2MKcz1uZXcgUC5SbihiKQpDLk5tLmkoJC54ZyxhKQp0cnl7cj1zCnIuYT1QLnZnKHIuYSxh
+LCIsICIpfWZpbmFsbHl7aWYoMD49JC54Zy5sZW5ndGgpcmV0dXJuIEguT0goJC54ZywtMSkKJC54Zy5w
+b3AoKX1zLmErPWMKcj1zLmEKcmV0dXJuIHIuY2hhckNvZGVBdCgwKT09MD9yOnJ9LApoQjpmdW5jdGlv
+bihhKXt2YXIgcyxyCmZvcihzPSQueGcubGVuZ3RoLHI9MDtyPHM7KytyKWlmKGE9PT0kLnhnW3JdKXJl
+dHVybiEwCnJldHVybiExfSwKVnI6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEscCxvLG4sbSxsPWEuZ20o
+YSksaz0wLGo9MAp3aGlsZSghMCl7aWYoIShrPDgwfHxqPDMpKWJyZWFrCmlmKCFsLkYoKSlyZXR1cm4K
+cz1ILkVqKGwuZ2woKSkKQy5ObS5pKGIscykKays9cy5sZW5ndGgrMjsrK2p9aWYoIWwuRigpKXtpZihq
+PD01KXJldHVybgppZigwPj1iLmxlbmd0aClyZXR1cm4gSC5PSChiLC0xKQpyPWIucG9wKCkKaWYoMD49
+Yi5sZW5ndGgpcmV0dXJuIEguT0goYiwtMSkKcT1iLnBvcCgpfWVsc2V7cD1sLmdsKCk7KytqCmlmKCFs
+LkYoKSl7aWYoajw9NCl7Qy5ObS5pKGIsSC5FaihwKSkKcmV0dXJufXI9SC5FaihwKQppZigwPj1iLmxl
+bmd0aClyZXR1cm4gSC5PSChiLC0xKQpxPWIucG9wKCkKays9ci5sZW5ndGgrMn1lbHNle289bC5nbCgp
+Oysragpmb3IoO2wuRigpO3A9byxvPW4pe249bC5nbCgpOysragppZihqPjEwMCl7d2hpbGUoITApe2lm
+KCEoaz43NSYmaj4zKSlicmVhawppZigwPj1iLmxlbmd0aClyZXR1cm4gSC5PSChiLC0xKQprLT1iLnBv
+cCgpLmxlbmd0aCsyOy0tan1DLk5tLmkoYiwiLi4uIikKcmV0dXJufX1xPUguRWoocCkKcj1ILkVqKG8p
+CmsrPXIubGVuZ3RoK3EubGVuZ3RoKzR9fWlmKGo+Yi5sZW5ndGgrMil7ays9NQptPSIuLi4ifWVsc2Ug
+bT1udWxsCndoaWxlKCEwKXtpZighKGs+ODAmJmIubGVuZ3RoPjMpKWJyZWFrCmlmKDA+PWIubGVuZ3Ro
+KXJldHVybiBILk9IKGIsLTEpCmstPWIucG9wKCkubGVuZ3RoKzIKaWYobT09bnVsbCl7ays9NQptPSIu
+Li4ifX1pZihtIT1udWxsKUMuTm0uaShiLG0pCkMuTm0uaShiLHEpCkMuTm0uaShiLHIpfSwKdE06ZnVu
+Y3Rpb24oYSxiKXt2YXIgcyxyLHE9UC5McyhiKQpmb3Iocz1hLmxlbmd0aCxyPTA7cjxhLmxlbmd0aDth
+Lmxlbmd0aD09PXN8fCgwLEgubGspKGEpLCsrcilxLmkoMCxiLmEoYVtyXSkpCnJldHVybiBxfSwKbk86
+ZnVuY3Rpb24oYSl7dmFyIHMscj17fQppZihQLmhCKGEpKXJldHVybiJ7Li4ufSIKcz1uZXcgUC5Sbigi
+IikKdHJ5e0MuTm0uaSgkLnhnLGEpCnMuYSs9InsiCnIuYT0hMAphLksoMCxuZXcgUC5yYShyLHMpKQpz
+LmErPSJ9In1maW5hbGx5e2lmKDA+PSQueGcubGVuZ3RoKXJldHVybiBILk9IKCQueGcsLTEpCiQueGcu
+cG9wKCl9cj1zLmEKcmV0dXJuIHIuY2hhckNvZGVBdCgwKT09MD9yOnJ9LApiNjpmdW5jdGlvbiBiNihh
+KXt2YXIgXz10aGlzCl8uYT0wCl8uZj1fLmU9Xy5kPV8uYz1fLmI9bnVsbApfLnI9MApfLiR0aT1hfSwK
+Ym46ZnVuY3Rpb24gYm4oYSl7dGhpcy5hPWEKdGhpcy5jPXRoaXMuYj1udWxsfSwKbG06ZnVuY3Rpb24g
+bG0oYSxiLGMpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5kPV8uYz1udWxsCl8uJHRpPWN9LAptVzpm
+dW5jdGlvbiBtVygpe30sCnV5OmZ1bmN0aW9uIHV5KCl7fSwKbEQ6ZnVuY3Rpb24gbEQoKXt9LAppbDpm
+dW5jdGlvbiBpbCgpe30sCnJhOmZ1bmN0aW9uIHJhKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApZazpm
+dW5jdGlvbiBZaygpe30sCnlROmZ1bmN0aW9uIHlRKGEpe3RoaXMuYT1hfSwKS1A6ZnVuY3Rpb24gS1Ao
+KXt9LApQbjpmdW5jdGlvbiBQbigpe30sCkdqOmZ1bmN0aW9uIEdqKGEsYil7dGhpcy5hPWEKdGhpcy4k
+dGk9Yn0sCmxmOmZ1bmN0aW9uIGxmKCl7fSwKVmo6ZnVuY3Rpb24gVmooKXt9LApYdjpmdW5jdGlvbiBY
+digpe30sCm5ZOmZ1bmN0aW9uIG5ZKCl7fSwKV1k6ZnVuY3Rpb24gV1koKXt9LApSVTpmdW5jdGlvbiBS
+VSgpe30sCnBSOmZ1bmN0aW9uIHBSKCl7fSwKQlM6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEscAppZih0
+eXBlb2YgYSE9InN0cmluZyIpdGhyb3cgSC5iKEgudEwoYSkpCnM9bnVsbAp0cnl7cz1KU09OLnBhcnNl
+KGEpfWNhdGNoKHEpe3I9SC5SdShxKQpwPVAucnIoU3RyaW5nKHIpLG51bGwsbnVsbCkKdGhyb3cgSC5i
+KHApfXA9UC5RZShzKQpyZXR1cm4gcH0sClFlOmZ1bmN0aW9uKGEpe3ZhciBzCmlmKGE9PW51bGwpcmV0
+dXJuIG51bGwKaWYodHlwZW9mIGEhPSJvYmplY3QiKXJldHVybiBhCmlmKE9iamVjdC5nZXRQcm90b3R5
+cGVPZihhKSE9PUFycmF5LnByb3RvdHlwZSlyZXR1cm4gbmV3IFAudXcoYSxPYmplY3QuY3JlYXRlKG51
+bGwpKQpmb3Iocz0wO3M8YS5sZW5ndGg7KytzKWFbc109UC5RZShhW3NdKQpyZXR1cm4gYX0sCmt5OmZ1
+bmN0aW9uKGEsYixjLGQpe3ZhciBzLHIKaWYoYiBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpe3M9YgpkPXMu
+bGVuZ3RoCmlmKGQtYzwxNSlyZXR1cm4gbnVsbApyPVAuUlAoYSxzLGMsZCkKaWYociE9bnVsbCYmYSlp
+ZihyLmluZGV4T2YoIlx1ZmZmZCIpPj0wKXJldHVybiBudWxsCnJldHVybiByfXJldHVybiBudWxsfSwK
+UlA6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHM9YT8kLkhHKCk6JC5yZigpCmlmKHM9PW51bGwpcmV0dXJu
+IG51bGwKaWYoMD09PWMmJmQ9PT1iLmxlbmd0aClyZXR1cm4gUC5SYihzLGIpCnJldHVybiBQLlJiKHMs
+Yi5zdWJhcnJheShjLFAuakIoYyxkLGIubGVuZ3RoKSkpfSwKUmI6ZnVuY3Rpb24oYSxiKXt2YXIgcyxy
+CnRyeXtzPWEuZGVjb2RlKGIpCnJldHVybiBzfWNhdGNoKHIpe0guUnUocil9cmV0dXJuIG51bGx9LAp4
+TTpmdW5jdGlvbihhLGIsYyxkLGUsZil7aWYoQy5qbi56WShmLDQpIT09MCl0aHJvdyBILmIoUC5ycigi
+SW52YWxpZCBiYXNlNjQgcGFkZGluZywgcGFkZGVkIGxlbmd0aCBtdXN0IGJlIG11bHRpcGxlIG9mIGZv
+dXIsIGlzICIrZixhLGMpKQppZihkK2UhPT1mKXRocm93IEguYihQLnJyKCJJbnZhbGlkIGJhc2U2NCBw
+YWRkaW5nLCAnPScgbm90IGF0IHRoZSBlbmQiLGEsYikpCmlmKGU+Mil0aHJvdyBILmIoUC5ycigiSW52
+YWxpZCBiYXNlNjQgcGFkZGluZywgbW9yZSB0aGFuIHR3byAnPScgY2hhcmFjdGVycyIsYSxiKSl9LApH
+eTpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIG5ldyBQLlVkKGEsYil9LApOQzpmdW5jdGlvbihhKXtyZXR1
+cm4gYS5MdCgpfSwKVWc6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gbmV3IFAudHUoYSxbXSxQLkN5KCkpfSwK
+dVg6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzLHI9bmV3IFAuUm4oIiIpLHE9UC5VZyhyLGIpCnEuaVUoYSkK
+cz1yLmEKcmV0dXJuIHMuY2hhckNvZGVBdCgwKT09MD9zOnN9LApqNDpmdW5jdGlvbihhKXtzd2l0Y2go
+YSl7Y2FzZSA2NTpyZXR1cm4iTWlzc2luZyBleHRlbnNpb24gYnl0ZSIKY2FzZSA2NzpyZXR1cm4iVW5l
+eHBlY3RlZCBleHRlbnNpb24gYnl0ZSIKY2FzZSA2OTpyZXR1cm4iSW52YWxpZCBVVEYtOCBieXRlIgpj
+YXNlIDcxOnJldHVybiJPdmVybG9uZyBlbmNvZGluZyIKY2FzZSA3MzpyZXR1cm4iT3V0IG9mIHVuaWNv
+ZGUgcmFuZ2UiCmNhc2UgNzU6cmV0dXJuIkVuY29kZWQgc3Vycm9nYXRlIgpjYXNlIDc3OnJldHVybiJV
+bmZpbmlzaGVkIFVURi04IG9jdGV0IHNlcXVlbmNlIgpkZWZhdWx0OnJldHVybiIifX0sCmp5OmZ1bmN0
+aW9uKGEsYixjKXt2YXIgcyxyLHEscD1jLWIsbz1uZXcgVWludDhBcnJheShwKQpmb3Iocz1KLlU2KGEp
+LHI9MDtyPHA7KytyKXtxPXMucShhLGIrcikKaWYodHlwZW9mIHEhPT0ibnVtYmVyIilyZXR1cm4gcS56
+TSgpCmlmKChxJjQyOTQ5NjcwNDApPj4+MCE9PTApcT0yNTUKaWYocj49cClyZXR1cm4gSC5PSChvLHIp
+Cm9bcl09cX1yZXR1cm4gb30sCnV3OmZ1bmN0aW9uIHV3KGEsYil7dGhpcy5hPWEKdGhpcy5iPWIKdGhp
+cy5jPW51bGx9LAppODpmdW5jdGlvbiBpOChhKXt0aGlzLmE9YX0sCnhyOmZ1bmN0aW9uIHhyKCl7fSwK
+Tno6ZnVuY3Rpb24gTnooKXt9LApDVjpmdW5jdGlvbiBDVigpe30sClU4OmZ1bmN0aW9uIFU4KCl7fSwK
+VWs6ZnVuY3Rpb24gVWsoKXt9LAp3STpmdW5jdGlvbiB3SSgpe30sClppOmZ1bmN0aW9uIFppKCl7fSwK
+VWQ6ZnVuY3Rpb24gVWQoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCks4OmZ1bmN0aW9uIEs4KGEsYil7
+dGhpcy5hPWEKdGhpcy5iPWJ9LApieTpmdW5jdGlvbiBieSgpe30sCm9qOmZ1bmN0aW9uIG9qKGEpe3Ro
+aXMuYj1hfSwKTXg6ZnVuY3Rpb24gTXgoYSl7dGhpcy5hPWF9LApTaDpmdW5jdGlvbiBTaCgpe30sCnRp
+OmZ1bmN0aW9uIHRpKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LAp0dTpmdW5jdGlvbiB0dShhLGIsYyl7
+dGhpcy5jPWEKdGhpcy5hPWIKdGhpcy5iPWN9LAp1NTpmdW5jdGlvbiB1NSgpe30sCkUzOmZ1bmN0aW9u
+IEUzKCl7fSwKUnc6ZnVuY3Rpb24gUncoYSl7dGhpcy5iPTAKdGhpcy5jPWF9LApHWTpmdW5jdGlvbiBH
+WShhKXt0aGlzLmE9YX0sCmJ6OmZ1bmN0aW9uIGJ6KGEpe3RoaXMuYT1hCnRoaXMuYj0xNgp0aGlzLmM9
+MH0sClFBOmZ1bmN0aW9uKGEsYil7dmFyIHM9SC5IcChhLGIpCmlmKHMhPW51bGwpcmV0dXJuIHMKdGhy
+b3cgSC5iKFAucnIoYSxudWxsLG51bGwpKX0sCm9zOmZ1bmN0aW9uKGEpe2lmKGEgaW5zdGFuY2VvZiBI
+LlRwKXJldHVybiBhLncoMCkKcmV0dXJuIkluc3RhbmNlIG9mICciK0guRWooSC5NKGEpKSsiJyJ9LApP
+ODpmdW5jdGlvbihhLGIsYyxkKXt2YXIgcyxyPWM/Si5LaChhLGQpOkouUWkoYSxkKQppZihhIT09MCYm
+YiE9bnVsbClmb3Iocz0wO3M8ci5sZW5ndGg7KytzKXJbc109YgpyZXR1cm4gcn0sCkNIOmZ1bmN0aW9u
+KGEsYixjKXt2YXIgcyxyPUguVk0oW10sYy5DKCJqZDwwPiIpKQpmb3Iocz1KLklUKGEpO3MuRigpOylD
+Lk5tLmkocixjLmEocy5nbCgpKSkKaWYoYilyZXR1cm4gcgpyZXR1cm4gSi5FcChyLGMpfSwKWTE6ZnVu
+Y3Rpb24oYSxiLGMpe3ZhciBzCmlmKGIpcmV0dXJuIFAuZXYoYSxjKQpzPUouRXAoUC5ldihhLGMpLGMp
+CnJldHVybiBzfSwKZXY6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyCmlmKEFycmF5LmlzQXJyYXkoYSkpcmV0
+dXJuIEguVk0oYS5zbGljZSgwKSxiLkMoImpkPDA+IikpCnM9SC5WTShbXSxiLkMoImpkPDA+IikpCmZv
+cihyPUouSVQoYSk7ci5GKCk7KUMuTm0uaShzLHIuZ2woKSkKcmV0dXJuIHN9LApBRjpmdW5jdGlvbihh
+LGIpe3JldHVybiBKLnpDKFAuQ0goYSwhMSxiKSl9LApITTpmdW5jdGlvbihhLGIsYyl7aWYodC5ibS5i
+KGEpKXJldHVybiBILmZ3KGEsYixQLmpCKGIsYyxhLmxlbmd0aCkpCnJldHVybiBQLmJ3KGEsYixjKX0s
+Ck9vOmZ1bmN0aW9uKGEpe3JldHVybiBILkx3KGEpfSwKYnc6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzLHIs
+cSxwLG89bnVsbAppZihiPDApdGhyb3cgSC5iKFAuVEUoYiwwLGEubGVuZ3RoLG8sbykpCnM9Yz09bnVs
+bAppZighcyYmYzxiKXRocm93IEguYihQLlRFKGMsYixhLmxlbmd0aCxvLG8pKQpyPW5ldyBILmE3KGEs
+YS5sZW5ndGgsSC56KGEpLkMoImE3PGxELkU+IikpCmZvcihxPTA7cTxiOysrcSlpZighci5GKCkpdGhy
+b3cgSC5iKFAuVEUoYiwwLHEsbyxvKSkKcD1bXQppZihzKWZvcig7ci5GKCk7KXAucHVzaChyLmQpCmVs
+c2UgZm9yKHE9YjtxPGM7KytxKXtpZighci5GKCkpdGhyb3cgSC5iKFAuVEUoYyxiLHEsbyxvKSkKcC5w
+dXNoKHIuZCl9cmV0dXJuIEguZVQocCl9LApudTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IEguVlIoYSxI
+LnY0KGEsITEsITAsITEsITEsITEpKX0sCnZnOmZ1bmN0aW9uKGEsYixjKXt2YXIgcz1KLklUKGIpCmlm
+KCFzLkYoKSlyZXR1cm4gYQppZihjLmxlbmd0aD09PTApe2RvIGErPUguRWoocy5nbCgpKQp3aGlsZShz
+LkYoKSl9ZWxzZXthKz1ILkVqKHMuZ2woKSkKZm9yKDtzLkYoKTspYT1hK2MrSC5FaihzLmdsKCkpfXJl
+dHVybiBhfSwKbHI6ZnVuY3Rpb24oYSxiLGMsZCl7cmV0dXJuIG5ldyBQLm1wKGEsYixjLGQpfSwKdW86
+ZnVuY3Rpb24oKXt2YXIgcz1ILk0wKCkKaWYocyE9bnVsbClyZXR1cm4gUC5oSyhzKQp0aHJvdyBILmIo
+UC5MNCgiJ1VyaS5iYXNlJyBpcyBub3Qgc3VwcG9ydGVkIikpfSwKZVA6ZnVuY3Rpb24oYSxiLGMsZCl7
+dmFyIHMscixxLHAsbyxuLG09IjAxMjM0NTY3ODlBQkNERUYiCmlmKGM9PT1DLnhNKXtzPSQuejQoKS5i
+CmlmKHR5cGVvZiBiIT0ic3RyaW5nIilILnYoSC50TChiKSkKcz1zLnRlc3QoYil9ZWxzZSBzPSExCmlm
+KHMpcmV0dXJuIGIKSC5MaChjKS5DKCJVay5TIikuYShiKQpyPWMuZ1pFKCkuV0ooYikKZm9yKHM9ci5s
+ZW5ndGgscT0wLHA9IiI7cTxzOysrcSl7bz1yW3FdCmlmKG88MTI4KXtuPW8+Pj40CmlmKG4+PTgpcmV0
+dXJuIEguT0goYSxuKQpuPShhW25dJjE8PChvJjE1KSkhPT0wfWVsc2Ugbj0hMQppZihuKXArPUguTHco
+bykKZWxzZSBwPWQmJm89PT0zMj9wKyIrIjpwKyIlIittW28+Pj40JjE1XSttW28mMTVdfXJldHVybiBw
+LmNoYXJDb2RlQXQoMCk9PTA/cDpwfSwKR3E6ZnVuY3Rpb24oYSl7dmFyIHM9TWF0aC5hYnMoYSkscj1h
+PDA/Ii0iOiIiCmlmKHM+PTEwMDApcmV0dXJuIiIrYQppZihzPj0xMDApcmV0dXJuIHIrIjAiK3MKaWYo
+cz49MTApcmV0dXJuIHIrIjAwIitzCnJldHVybiByKyIwMDAiK3N9LApWeDpmdW5jdGlvbihhKXtpZihh
+Pj0xMDApcmV0dXJuIiIrYQppZihhPj0xMClyZXR1cm4iMCIrYQpyZXR1cm4iMDAiK2F9LApoMDpmdW5j
+dGlvbihhKXtpZihhPj0xMClyZXR1cm4iIithCnJldHVybiIwIithfSwKcDpmdW5jdGlvbihhKXtpZih0
+eXBlb2YgYT09Im51bWJlciJ8fEgubChhKXx8bnVsbD09YSlyZXR1cm4gSi5qKGEpCmlmKHR5cGVvZiBh
+PT0ic3RyaW5nIilyZXR1cm4gSlNPTi5zdHJpbmdpZnkoYSkKcmV0dXJuIFAub3MoYSl9LApoVjpmdW5j
+dGlvbihhKXtyZXR1cm4gbmV3IFAuQzYoYSl9LAp4WTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFAudSgh
+MSxudWxsLG51bGwsYSl9LApMMzpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIG5ldyBQLnUoITAsYSxiLGMp
+fSwKTzc6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gbmV3IFAuYkoobnVsbCxudWxsLCEwLGEsYiwiVmFsdWUg
+bm90IGluIHJhbmdlIil9LApURTpmdW5jdGlvbihhLGIsYyxkLGUpe3JldHVybiBuZXcgUC5iSihiLGMs
+ITAsYSxkLCJJbnZhbGlkIHZhbHVlIil9LAp3QTpmdW5jdGlvbihhLGIsYyxkKXtpZihhPGJ8fGE+Yyl0
+aHJvdyBILmIoUC5URShhLGIsYyxkLG51bGwpKQpyZXR1cm4gYX0sCmpCOmZ1bmN0aW9uKGEsYixjKXtp
+ZigwPmF8fGE+Yyl0aHJvdyBILmIoUC5URShhLDAsYywic3RhcnQiLG51bGwpKQppZihiIT1udWxsKXtp
+ZihhPmJ8fGI+Yyl0aHJvdyBILmIoUC5URShiLGEsYywiZW5kIixudWxsKSkKcmV0dXJuIGJ9cmV0dXJu
+IGN9LAprMTpmdW5jdGlvbihhLGIpe2lmKGE8MCl0aHJvdyBILmIoUC5URShhLDAsbnVsbCxiLG51bGwp
+KQpyZXR1cm4gYX0sCkNmOmZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIHM9SC51UChlPT1udWxsP0ouSG0o
+Yik6ZSkKcmV0dXJuIG5ldyBQLmVZKHMsITAsYSxjLCJJbmRleCBvdXQgb2YgcmFuZ2UiKX0sCkw0OmZ1
+bmN0aW9uKGEpe3JldHVybiBuZXcgUC51YihhKX0sClNZOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgUC5k
+cyhhKX0sClBWOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgUC5saihhKX0sCmE0OmZ1bmN0aW9uKGEpe3Jl
+dHVybiBuZXcgUC5VVihhKX0sCnJyOmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gbmV3IFAuYUUoYSxiLGMp
+fSwKaEs6ZnVuY3Rpb24oYTUpe3ZhciBzLHIscSxwLG8sbixtLGwsayxqLGksaCxnLGYsZSxkLGMsYixh
+LGEwLGExLGEyLGEzPW51bGwsYTQ9YTUubGVuZ3RoCmlmKGE0Pj01KXtzPSgoSi5ReihhNSw0KV41OCkq
+M3xDLnhCLlcoYTUsMCleMTAwfEMueEIuVyhhNSwxKV45N3xDLnhCLlcoYTUsMileMTE2fEMueEIuVyhh
+NSwzKV45Nyk+Pj4wCmlmKHM9PT0wKXJldHVybiBQLktEKGE0PGE0P0MueEIuTmooYTUsMCxhNCk6YTUs
+NSxhMykuZ2xSKCkKZWxzZSBpZihzPT09MzIpcmV0dXJuIFAuS0QoQy54Qi5OaihhNSw1LGE0KSwwLGEz
+KS5nbFIoKX1yPVAuTzgoOCwwLCExLHQuUykKQy5ObS5ZNShyLDAsMCkKQy5ObS5ZNShyLDEsLTEpCkMu
+Tm0uWTUociwyLC0xKQpDLk5tLlk1KHIsNywtMSkKQy5ObS5ZNShyLDMsMCkKQy5ObS5ZNShyLDQsMCkK
+Qy5ObS5ZNShyLDUsYTQpCkMuTm0uWTUociw2LGE0KQppZihQLlVCKGE1LDAsYTQsMCxyKT49MTQpQy5O
+bS5ZNShyLDcsYTQpCnE9clsxXQppZihxPj0wKWlmKFAuVUIoYTUsMCxxLDIwLHIpPT09MjApcls3XT1x
+CnA9clsyXSsxCm89clszXQpuPXJbNF0KbT1yWzVdCmw9cls2XQppZihsPG0pbT1sCmlmKG48cCluPW0K
+ZWxzZSBpZihuPD1xKW49cSsxCmlmKG88cClvPW4Kaz1yWzddPDAKaWYoaylpZihwPnErMyl7aj1hMwpr
+PSExfWVsc2V7aT1vPjAKaWYoaSYmbysxPT09bil7aj1hMwprPSExfWVsc2V7aWYoIShtPGE0JiZtPT09
+bisyJiZKLnEwKGE1LCIuLiIsbikpKWg9bT5uKzImJkoucTAoYTUsIi8uLiIsbS0zKQplbHNlIGg9ITAK
+aWYoaCl7aj1hMwprPSExfWVsc2V7aWYocT09PTQpaWYoSi5xMChhNSwiZmlsZSIsMCkpe2lmKHA8PTAp
+e2lmKCFDLnhCLlFpKGE1LCIvIixuKSl7Zz0iZmlsZTovLy8iCnM9M31lbHNle2c9ImZpbGU6Ly8iCnM9
+Mn1hNT1nK0MueEIuTmooYTUsbixhNCkKcS09MAppPXMtMAptKz1pCmwrPWkKYTQ9YTUubGVuZ3RoCnA9
+NwpvPTcKbj03fWVsc2UgaWYobj09PW0peysrbApmPW0rMQphNT1DLnhCLmk3KGE1LG4sbSwiLyIpOysr
+YTQKbT1mfWo9ImZpbGUifWVsc2UgaWYoQy54Qi5RaShhNSwiaHR0cCIsMCkpe2lmKGkmJm8rMz09PW4m
+JkMueEIuUWkoYTUsIjgwIixvKzEpKXtsLT0zCmU9bi0zCm0tPTMKYTU9Qy54Qi5pNyhhNSxvLG4sIiIp
+CmE0LT0zCm49ZX1qPSJodHRwIn1lbHNlIGo9YTMKZWxzZSBpZihxPT09NSYmSi5xMChhNSwiaHR0cHMi
+LDApKXtpZihpJiZvKzQ9PT1uJiZKLnEwKGE1LCI0NDMiLG8rMSkpe2wtPTQKZT1uLTQKbS09NAphNT1K
+LmRnKGE1LG8sbiwiIikKYTQtPTMKbj1lfWo9Imh0dHBzIn1lbHNlIGo9YTMKaz0hMH19fWVsc2Ugaj1h
+MwppZihrKXtpPWE1Lmxlbmd0aAppZihhNDxpKXthNT1KLmxkKGE1LDAsYTQpCnEtPTAKcC09MApvLT0w
+Cm4tPTAKbS09MApsLT0wfXJldHVybiBuZXcgUC5VZihhNSxxLHAsbyxuLG0sbCxqKX1pZihqPT1udWxs
+KWlmKHE+MClqPVAuUGkoYTUsMCxxKQplbHNle2lmKHE9PT0wKXtQLlIzKGE1LDAsIkludmFsaWQgZW1w
+dHkgc2NoZW1lIikKSC5CaSh1LmcpfWo9IiJ9aWYocD4wKXtkPXErMwpjPWQ8cD9QLnpSKGE1LGQscC0x
+KToiIgpiPVAuT2UoYTUscCxvLCExKQppPW8rMQppZihpPG4pe2E9SC5IcChKLmxkKGE1LGksbiksYTMp
+CmEwPVAud0IoYT09bnVsbD9ILnYoUC5ycigiSW52YWxpZCBwb3J0IixhNSxpKSk6YSxqKX1lbHNlIGEw
+PWEzfWVsc2V7YTA9YTMKYj1hMApjPSIifWExPVAua2EoYTUsbixtLGEzLGosYiE9bnVsbCkKYTI9bTxs
+P1AubGUoYTUsbSsxLGwsYTMpOmEzCnJldHVybiBQLkNnKGosYyxiLGEwLGExLGEyLGw8YTQ/UC50Ryhh
+NSxsKzEsYTQpOmEzKX0sCk10OmZ1bmN0aW9uKGEpe0guaChhKQpyZXR1cm4gUC5rdShhLDAsYS5sZW5n
+dGgsQy54TSwhMSl9LApXWDpmdW5jdGlvbihhKXt2YXIgcz10Lk4KcmV0dXJuIEMuTm0uTjAoSC5WTShh
+LnNwbGl0KCImIiksdC5zKSxQLkZsKHMscyksbmV3IFAubjEoQy54TSksdC5KKX0sCkhoOmZ1bmN0aW9u
+KGEsYixjKXt2YXIgcyxyLHEscCxvLG4sbT0iSVB2NCBhZGRyZXNzIHNob3VsZCBjb250YWluIGV4YWN0
+bHkgNCBwYXJ0cyIsbD0iZWFjaCBwYXJ0IG11c3QgYmUgaW4gdGhlIHJhbmdlIDAuLjI1NSIsaz1uZXcg
+UC5jUyhhKSxqPW5ldyBVaW50OEFycmF5KDQpCmZvcihzPWIscj1zLHE9MDtzPGM7KytzKXtwPUMueEIu
+TyhhLHMpCmlmKHAhPT00Nil7aWYoKHBeNDgpPjkpay4kMigiaW52YWxpZCBjaGFyYWN0ZXIiLHMpfWVs
+c2V7aWYocT09PTMpay4kMihtLHMpCm89UC5RQShDLnhCLk5qKGEscixzKSxudWxsKQppZihvPjI1NSlr
+LiQyKGwscikKbj1xKzEKaWYocT49NClyZXR1cm4gSC5PSChqLHEpCmpbcV09bwpyPXMrMQpxPW59fWlm
+KHEhPT0zKWsuJDIobSxjKQpvPVAuUUEoQy54Qi5OaihhLHIsYyksbnVsbCkKaWYobz4yNTUpay4kMihs
+LHIpCmlmKHE+PTQpcmV0dXJuIEguT0goaixxKQpqW3FdPW8KcmV0dXJuIGp9LAplZzpmdW5jdGlvbihh
+LGIsYTApe3ZhciBzLHIscSxwLG8sbixtLGwsayxqLGksaCxnLGYsZSxkPW5ldyBQLlZDKGEpLGM9bmV3
+IFAuSlQoZCxhKQppZihhLmxlbmd0aDwyKWQuJDEoImFkZHJlc3MgaXMgdG9vIHNob3J0IikKcz1ILlZN
+KFtdLHQuYSkKZm9yKHI9YixxPXIscD0hMSxvPSExO3I8YTA7KytyKXtuPUMueEIuTyhhLHIpCmlmKG49
+PT01OCl7aWYocj09PWIpeysrcgppZihDLnhCLk8oYSxyKSE9PTU4KWQuJDIoImludmFsaWQgc3RhcnQg
+Y29sb24uIixyKQpxPXJ9aWYocj09PXEpe2lmKHApZC4kMigib25seSBvbmUgd2lsZGNhcmQgYDo6YCBp
+cyBhbGxvd2VkIixyKQpDLk5tLmkocywtMSkKcD0hMH1lbHNlIEMuTm0uaShzLGMuJDIocSxyKSkKcT1y
+KzF9ZWxzZSBpZihuPT09NDYpbz0hMH1pZihzLmxlbmd0aD09PTApZC4kMSgidG9vIGZldyBwYXJ0cyIp
+Cm09cT09PWEwCmw9Qy5ObS5ncloocykKaWYobSYmbCE9PS0xKWQuJDIoImV4cGVjdGVkIGEgcGFydCBh
+ZnRlciBsYXN0IGA6YCIsYTApCmlmKCFtKWlmKCFvKUMuTm0uaShzLGMuJDIocSxhMCkpCmVsc2V7az1Q
+LkhoKGEscSxhMCkKQy5ObS5pKHMsKGtbMF08PDh8a1sxXSk+Pj4wKQpDLk5tLmkocywoa1syXTw8OHxr
+WzNdKT4+PjApfWlmKHApe2lmKHMubGVuZ3RoPjcpZC4kMSgiYW4gYWRkcmVzcyB3aXRoIGEgd2lsZGNh
+cmQgbXVzdCBoYXZlIGxlc3MgdGhhbiA3IHBhcnRzIil9ZWxzZSBpZihzLmxlbmd0aCE9PTgpZC4kMSgi
+YW4gYWRkcmVzcyB3aXRob3V0IGEgd2lsZGNhcmQgbXVzdCBjb250YWluIGV4YWN0bHkgOCBwYXJ0cyIp
+Cmo9bmV3IFVpbnQ4QXJyYXkoMTYpCmZvcihsPXMubGVuZ3RoLGk9OS1sLHI9MCxoPTA7cjxsOysrcil7
+Zz1zW3JdCmlmKGc9PT0tMSlmb3IoZj0wO2Y8aTsrK2Ype2lmKGg8MHx8aD49MTYpcmV0dXJuIEguT0go
+aixoKQpqW2hdPTAKZT1oKzEKaWYoZT49MTYpcmV0dXJuIEguT0goaixlKQpqW2VdPTAKaCs9Mn1lbHNl
+e2U9Qy5qbi53RyhnLDgpCmlmKGg8MHx8aD49MTYpcmV0dXJuIEguT0goaixoKQpqW2hdPWUKZT1oKzEK
+aWYoZT49MTYpcmV0dXJuIEguT0goaixlKQpqW2VdPWcmMjU1CmgrPTJ9fXJldHVybiBqfSwKQ2c6ZnVu
+Y3Rpb24oYSxiLGMsZCxlLGYsZyl7cmV0dXJuIG5ldyBQLkRuKGEsYixjLGQsZSxmLGcpfSwKS0w6ZnVu
+Y3Rpb24oYSxiLGMsZCxlLGYsZyl7dmFyIHMscixxLHAsbyxuCmY9Zj09bnVsbD8iIjpQLlBpKGYsMCxm
+Lmxlbmd0aCkKZz1QLnpSKGcsMCxnPT1udWxsPzA6Zy5sZW5ndGgpCmE9UC5PZShhLDAsYT09bnVsbD8w
+OmEubGVuZ3RoLCExKQpzPVAubGUobnVsbCwwLDAsZSkKcj1QLnRHKG51bGwsMCwwKQpkPVAud0IoZCxm
+KQpxPWY9PT0iZmlsZSIKaWYoYT09bnVsbClwPWcubGVuZ3RoIT09MHx8ZCE9bnVsbHx8cQplbHNlIHA9
+ITEKaWYocClhPSIiCnA9YT09bnVsbApvPSFwCmI9UC5rYShiLDAsYj09bnVsbD8wOmIubGVuZ3RoLGMs
+ZixvKQpuPWYubGVuZ3RoPT09MAppZihuJiZwJiYhQy54Qi5uQyhiLCIvIikpYj1QLndGKGIsIW58fG8p
+CmVsc2UgYj1QLnhlKGIpCnJldHVybiBQLkNnKGYsZyxwJiZDLnhCLm5DKGIsIi8vIik/IiI6YSxkLGIs
+cyxyKX0sCndLOmZ1bmN0aW9uKGEpe2lmKGE9PT0iaHR0cCIpcmV0dXJuIDgwCmlmKGE9PT0iaHR0cHMi
+KXJldHVybiA0NDMKcmV0dXJuIDB9LApOUjpmdW5jdGlvbihhLGIpe3ZhciBzLHIscSxwLG8sbgpmb3Io
+cz1hLmxlbmd0aCxyPTA7cjxzOysrcil7cT1DLnhCLlcoYSxyKQpwPUMueEIuVyhiLHIpCm89cV5wCmlm
+KG8hPT0wKXtpZihvPT09MzIpe249cHxvCmlmKDk3PD1uJiZuPD0xMjIpY29udGludWV9cmV0dXJuITF9
+fXJldHVybiEwfSwKUjM6ZnVuY3Rpb24oYSxiLGMpe3Rocm93IEguYihQLnJyKGMsYSxiKSl9LApYZDpm
+dW5jdGlvbihhLGIsYyxkKXt2YXIgcyxyLHEscCxvLG4sbSxsLGssaixpLGg9bnVsbCxnPWIubGVuZ3Ro
+CmlmKGchPT0wKXtxPTAKd2hpbGUoITApe2lmKCEocTxnKSl7cz0iIgpyPTAKYnJlYWt9aWYoQy54Qi5X
+KGIscSk9PT02NCl7cz1DLnhCLk5qKGIsMCxxKQpyPXErMQpicmVha30rK3F9aWYocjxnJiZDLnhCLlco
+YixyKT09PTkxKXtmb3IocD1yLG89LTE7cDxnOysrcCl7bj1DLnhCLlcoYixwKQppZihuPT09MzcmJm88
+MCl7bT1DLnhCLlFpKGIsIjI1IixwKzEpP3ArMjpwCm89cApwPW19ZWxzZSBpZihuPT09OTMpYnJlYWt9
+aWYocD09PWcpdGhyb3cgSC5iKFAucnIoIkludmFsaWQgSVB2NiBob3N0IGVudHJ5LiIsYixyKSkKbD1v
+PDA/cDpvClAuZWcoYixyKzEsbCk7KytwCmlmKHAhPT1nJiZDLnhCLlcoYixwKSE9PTU4KXRocm93IEgu
+YihQLnJyKCJJbnZhbGlkIGVuZCBvZiBhdXRob3JpdHkiLGIscCkpfWVsc2UgcD1yCndoaWxlKCEwKXtp
+ZighKHA8Zykpe2s9aApicmVha31pZihDLnhCLlcoYixwKT09PTU4KXtqPUMueEIueW4oYixwKzEpCms9
+ai5sZW5ndGghPT0wP1AuUUEoaixoKTpoCmJyZWFrfSsrcH1pPUMueEIuTmooYixyLHApfWVsc2V7az1o
+Cmk9awpzPSIifXJldHVybiBQLktMKGksaCxILlZNKGMuc3BsaXQoIi8iKSx0LnMpLGssZCxhLHMpfSwK
+a0U6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyCmZvcihzPUouSVQoYSk7cy5GKCk7KXtyPXMuZ2woKQpyLnRv
+U3RyaW5nCmlmKEguU1EociwiLyIsMCkpe3M9UC5MNCgiSWxsZWdhbCBwYXRoIGNoYXJhY3RlciAiK3Ip
+CnRocm93IEguYihzKX19fSwKSE46ZnVuY3Rpb24oYSxiLGMpe3ZhciBzLHIscQpmb3Iocz1KLkE1KGEs
+Yykscz1zLmdtKHMpO3MuRigpOyl7cj1zLmdsKCkKcT1QLm51KCdbIiovOjw+P1xcXFx8XScpCnIudG9T
+dHJpbmcKaWYoSC5TUShyLHEsMCkpe3M9UC5MNCgiSWxsZWdhbCBjaGFyYWN0ZXIgaW4gcGF0aDogIity
+KQp0aHJvdyBILmIocyl9fX0sCnJnOmZ1bmN0aW9uKGEsYil7dmFyIHMKaWYoISg2NTw9YSYmYTw9OTAp
+KXM9OTc8PWEmJmE8PTEyMgplbHNlIHM9ITAKaWYocylyZXR1cm4Kcz1QLkw0KCJJbGxlZ2FsIGRyaXZl
+IGxldHRlciAiK1AuT28oYSkpCnRocm93IEguYihzKX0sCndCOmZ1bmN0aW9uKGEsYil7aWYoYSE9bnVs
+bCYmYT09PVAud0soYikpcmV0dXJuIG51bGwKcmV0dXJuIGF9LApPZTpmdW5jdGlvbihhLGIsYyxkKXt2
+YXIgcyxyLHEscCxvLG4KaWYoYT09bnVsbClyZXR1cm4gbnVsbAppZihiPT09YylyZXR1cm4iIgppZihD
+LnhCLk8oYSxiKT09PTkxKXtzPWMtMQppZihDLnhCLk8oYSxzKSE9PTkzKXtQLlIzKGEsYiwiTWlzc2lu
+ZyBlbmQgYF1gIHRvIG1hdGNoIGBbYCBpbiBob3N0IikKSC5CaSh1LmcpfXI9YisxCnE9UC50byhhLHIs
+cykKaWYocTxzKXtwPXErMQpvPVAuT0EoYSxDLnhCLlFpKGEsIjI1IixwKT9xKzM6cCxzLCIlMjUiKX1l
+bHNlIG89IiIKUC5lZyhhLHIscSkKcmV0dXJuIEMueEIuTmooYSxiLHEpLnRvTG93ZXJDYXNlKCkrbysi
+XSJ9Zm9yKG49YjtuPGM7KytuKWlmKEMueEIuTyhhLG4pPT09NTgpe3E9Qy54Qi5YVShhLCIlIixiKQpx
+PXE+PWImJnE8Yz9xOmMKaWYocTxjKXtwPXErMQpvPVAuT0EoYSxDLnhCLlFpKGEsIjI1IixwKT9xKzM6
+cCxjLCIlMjUiKX1lbHNlIG89IiIKUC5lZyhhLGIscSkKcmV0dXJuIlsiK0MueEIuTmooYSxiLHEpK28r
+Il0ifXJldHVybiBQLk9MKGEsYixjKX0sCnRvOmZ1bmN0aW9uKGEsYixjKXt2YXIgcz1DLnhCLlhVKGEs
+IiUiLGIpCnJldHVybiBzPj1iJiZzPGM/czpjfSwKT0E6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHMscixx
+LHAsbyxuLG0sbCxrLGosaT1kIT09IiI/bmV3IFAuUm4oZCk6bnVsbApmb3Iocz1iLHI9cyxxPSEwO3M8
+Yzspe3A9Qy54Qi5PKGEscykKaWYocD09PTM3KXtvPVAucnYoYSxzLCEwKQpuPW89PW51bGwKaWYobiYm
+cSl7cys9Mwpjb250aW51ZX1pZihpPT1udWxsKWk9bmV3IFAuUm4oIiIpCm09aS5hKz1DLnhCLk5qKGEs
+cixzKQppZihuKW89Qy54Qi5OaihhLHMscyszKQplbHNlIGlmKG89PT0iJSIpe1AuUjMoYSxzLCJab25l
+SUQgc2hvdWxkIG5vdCBjb250YWluICUgYW55bW9yZSIpCkguQmkodS5nKX1pLmE9bStvCnMrPTMKcj1z
+CnE9ITB9ZWxzZXtpZihwPDEyNyl7bj1wPj4+NAppZihuPj04KXJldHVybiBILk9IKEMuRjMsbikKbj0o
+Qy5GM1tuXSYxPDwocCYxNSkpIT09MH1lbHNlIG49ITEKaWYobil7aWYocSYmNjU8PXAmJjkwPj1wKXtp
+ZihpPT1udWxsKWk9bmV3IFAuUm4oIiIpCmlmKHI8cyl7aS5hKz1DLnhCLk5qKGEscixzKQpyPXN9cT0h
+MX0rK3N9ZWxzZXtpZigocCY2NDUxMik9PT01NTI5NiYmcysxPGMpe2w9Qy54Qi5PKGEscysxKQppZigo
+bCY2NDUxMik9PT01NjMyMCl7cD0ocCYxMDIzKTw8MTB8bCYxMDIzfDY1NTM2Cms9Mn1lbHNlIGs9MX1l
+bHNlIGs9MQpqPUMueEIuTmooYSxyLHMpCmlmKGk9PW51bGwpe2k9bmV3IFAuUm4oIiIpCm49aX1lbHNl
+IG49aQpuLmErPWoKbi5hKz1QLnpYKHApCnMrPWsKcj1zfX19aWYoaT09bnVsbClyZXR1cm4gQy54Qi5O
+aihhLGIsYykKaWYocjxjKWkuYSs9Qy54Qi5OaihhLHIsYykKbj1pLmEKcmV0dXJuIG4uY2hhckNvZGVB
+dCgwKT09MD9uOm59LApPTDpmdW5jdGlvbihhLGIsYyl7dmFyIHMscixxLHAsbyxuLG0sbCxrLGosaQpm
+b3Iocz1iLHI9cyxxPW51bGwscD0hMDtzPGM7KXtvPUMueEIuTyhhLHMpCmlmKG89PT0zNyl7bj1QLnJ2
+KGEscywhMCkKbT1uPT1udWxsCmlmKG0mJnApe3MrPTMKY29udGludWV9aWYocT09bnVsbClxPW5ldyBQ
+LlJuKCIiKQpsPUMueEIuTmooYSxyLHMpCms9cS5hKz0hcD9sLnRvTG93ZXJDYXNlKCk6bAppZihtKXtu
+PUMueEIuTmooYSxzLHMrMykKaj0zfWVsc2UgaWYobj09PSIlIil7bj0iJTI1IgpqPTF9ZWxzZSBqPTMK
+cS5hPWsrbgpzKz1qCnI9cwpwPSEwfWVsc2V7aWYobzwxMjcpe209bz4+PjQKaWYobT49OClyZXR1cm4g
+SC5PSChDLmVhLG0pCm09KEMuZWFbbV0mMTw8KG8mMTUpKSE9PTB9ZWxzZSBtPSExCmlmKG0pe2lmKHAm
+JjY1PD1vJiY5MD49byl7aWYocT09bnVsbClxPW5ldyBQLlJuKCIiKQppZihyPHMpe3EuYSs9Qy54Qi5O
+aihhLHIscykKcj1zfXA9ITF9KytzfWVsc2V7aWYobzw9OTMpe209bz4+PjQKaWYobT49OClyZXR1cm4g
+SC5PSChDLmFrLG0pCm09KEMuYWtbbV0mMTw8KG8mMTUpKSE9PTB9ZWxzZSBtPSExCmlmKG0pe1AuUjMo
+YSxzLCJJbnZhbGlkIGNoYXJhY3RlciIpCkguQmkodS5nKX1lbHNle2lmKChvJjY0NTEyKT09PTU1Mjk2
+JiZzKzE8Yyl7aT1DLnhCLk8oYSxzKzEpCmlmKChpJjY0NTEyKT09PTU2MzIwKXtvPShvJjEwMjMpPDwx
+MHxpJjEwMjN8NjU1MzYKaj0yfWVsc2Ugaj0xfWVsc2Ugaj0xCmw9Qy54Qi5OaihhLHIscykKaWYoIXAp
+bD1sLnRvTG93ZXJDYXNlKCkKaWYocT09bnVsbCl7cT1uZXcgUC5SbigiIikKbT1xfWVsc2UgbT1xCm0u
+YSs9bAptLmErPVAuelgobykKcys9agpyPXN9fX19aWYocT09bnVsbClyZXR1cm4gQy54Qi5OaihhLGIs
+YykKaWYocjxjKXtsPUMueEIuTmooYSxyLGMpCnEuYSs9IXA/bC50b0xvd2VyQ2FzZSgpOmx9bT1xLmEK
+cmV0dXJuIG0uY2hhckNvZGVBdCgwKT09MD9tOm19LApQaTpmdW5jdGlvbihhLGIsYyl7dmFyIHMscixx
+LHAsbz11LmcKaWYoYj09PWMpcmV0dXJuIiIKaWYoIVAuRXQoSi5ReihhLGIpKSl7UC5SMyhhLGIsIlNj
+aGVtZSBub3Qgc3RhcnRpbmcgd2l0aCBhbHBoYWJldGljIGNoYXJhY3RlciIpCkguQmkobyl9Zm9yKHM9
+YixyPSExO3M8YzsrK3Mpe3E9Qy54Qi5XKGEscykKaWYocTwxMjgpe3A9cT4+PjQKaWYocD49OClyZXR1
+cm4gSC5PSChDLm1LLHApCnA9KEMubUtbcF0mMTw8KHEmMTUpKSE9PTB9ZWxzZSBwPSExCmlmKCFwKXtQ
+LlIzKGEscywiSWxsZWdhbCBzY2hlbWUgY2hhcmFjdGVyIikKSC5CaShvKX1pZig2NTw9cSYmcTw9OTAp
+cj0hMH1hPUMueEIuTmooYSxiLGMpCnJldHVybiBQLllhKHI/YS50b0xvd2VyQ2FzZSgpOmEpfSwKWWE6
+ZnVuY3Rpb24oYSl7aWYoYT09PSJodHRwIilyZXR1cm4iaHR0cCIKaWYoYT09PSJmaWxlIilyZXR1cm4i
+ZmlsZSIKaWYoYT09PSJodHRwcyIpcmV0dXJuImh0dHBzIgppZihhPT09InBhY2thZ2UiKXJldHVybiJw
+YWNrYWdlIgpyZXR1cm4gYX0sCnpSOmZ1bmN0aW9uKGEsYixjKXtpZihhPT1udWxsKXJldHVybiIiCnJl
+dHVybiBQLlBJKGEsYixjLEMudG8sITEpfSwKa2E6ZnVuY3Rpb24oYSxiLGMsZCxlLGYpe3ZhciBzLHIs
+cT1lPT09ImZpbGUiLHA9cXx8ZgppZihhPT1udWxsKXtpZihkPT1udWxsKXJldHVybiBxPyIvIjoiIgpz
+PUgudDYoZCkKcj1uZXcgSC5sSihkLHMuQygicVUoMSkiKS5hKG5ldyBQLlJaKCkpLHMuQygibEo8MSxx
+VT4iKSkuaygwLCIvIil9ZWxzZSBpZihkIT1udWxsKXRocm93IEguYihQLnhZKCJCb3RoIHBhdGggYW5k
+IHBhdGhTZWdtZW50cyBzcGVjaWZpZWQiKSkKZWxzZSByPVAuUEkoYSxiLGMsQy5XZCwhMCkKaWYoci5s
+ZW5ndGg9PT0wKXtpZihxKXJldHVybiIvIn1lbHNlIGlmKHAmJiFDLnhCLm5DKHIsIi8iKSlyPSIvIity
+CnJldHVybiBQLkpyKHIsZSxmKX0sCkpyOmZ1bmN0aW9uKGEsYixjKXt2YXIgcz1iLmxlbmd0aD09PTAK
+aWYocyYmIWMmJiFDLnhCLm5DKGEsIi8iKSlyZXR1cm4gUC53RihhLCFzfHxjKQpyZXR1cm4gUC54ZShh
+KX0sCmxlOmZ1bmN0aW9uKGEsYixjLGQpe3ZhciBzLHI9e30KaWYoYSE9bnVsbCl7aWYoZCE9bnVsbCl0
+aHJvdyBILmIoUC54WSgiQm90aCBxdWVyeSBhbmQgcXVlcnlQYXJhbWV0ZXJzIHNwZWNpZmllZCIpKQpy
+ZXR1cm4gUC5QSShhLGIsYyxDLlZDLCEwKX1pZihkPT1udWxsKXJldHVybiBudWxsCnM9bmV3IFAuUm4o
+IiIpCnIuYT0iIgpkLksoMCxuZXcgUC55NShuZXcgUC5NRShyLHMpKSkKcj1zLmEKcmV0dXJuIHIuY2hh
+ckNvZGVBdCgwKT09MD9yOnJ9LAp0RzpmdW5jdGlvbihhLGIsYyl7aWYoYT09bnVsbClyZXR1cm4gbnVs
+bApyZXR1cm4gUC5QSShhLGIsYyxDLlZDLCEwKX0sCnJ2OmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyLHEs
+cCxvLG49YisyCmlmKG4+PWEubGVuZ3RoKXJldHVybiIlIgpzPUMueEIuTyhhLGIrMSkKcj1DLnhCLk8o
+YSxuKQpxPUgub28ocykKcD1ILm9vKHIpCmlmKHE8MHx8cDwwKXJldHVybiIlIgpvPXEqMTYrcAppZihv
+PDEyNyl7bj1DLmpuLndHKG8sNCkKaWYobj49OClyZXR1cm4gSC5PSChDLkYzLG4pCm49KEMuRjNbbl0m
+MTw8KG8mMTUpKSE9PTB9ZWxzZSBuPSExCmlmKG4pcmV0dXJuIEguTHcoYyYmNjU8PW8mJjkwPj1vPyhv
+fDMyKT4+PjA6bykKaWYocz49OTd8fHI+PTk3KXJldHVybiBDLnhCLk5qKGEsYixiKzMpLnRvVXBwZXJD
+YXNlKCkKcmV0dXJuIG51bGx9LAp6WDpmdW5jdGlvbihhKXt2YXIgcyxyLHEscCxvLG4sbSxsLGs9IjAx
+MjM0NTY3ODlBQkNERUYiCmlmKGE8MTI4KXtzPW5ldyBVaW50OEFycmF5KDMpCnNbMF09MzcKc1sxXT1D
+LnhCLlcoayxhPj4+NCkKc1syXT1DLnhCLlcoayxhJjE1KX1lbHNle2lmKGE+MjA0NylpZihhPjY1NTM1
+KXtyPTI0MApxPTR9ZWxzZXtyPTIyNApxPTN9ZWxzZXtyPTE5MgpxPTJ9cD0zKnEKcz1uZXcgVWludDhB
+cnJheShwKQpmb3Iobz0wOy0tcSxxPj0wO3I9MTI4KXtuPUMuam4uYmYoYSw2KnEpJjYzfHIKaWYobz49
+cClyZXR1cm4gSC5PSChzLG8pCnNbb109MzcKbT1vKzEKbD1DLnhCLlcoayxuPj4+NCkKaWYobT49cCly
+ZXR1cm4gSC5PSChzLG0pCnNbbV09bApsPW8rMgptPUMueEIuVyhrLG4mMTUpCmlmKGw+PXApcmV0dXJu
+IEguT0gocyxsKQpzW2xdPW0Kbys9M319cmV0dXJuIFAuSE0ocywwLG51bGwpfSwKUEk6ZnVuY3Rpb24o
+YSxiLGMsZCxlKXt2YXIgcz1QLlVsKGEsYixjLGQsZSkKcmV0dXJuIHM9PW51bGw/Qy54Qi5OaihhLGIs
+Yyk6c30sClVsOmZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIHMscixxLHAsbyxuLG0sbCxrLGo9bnVsbApm
+b3Iocz0hZSxyPWIscT1yLHA9ajtyPGM7KXtvPUMueEIuTyhhLHIpCmlmKG88MTI3KXtuPW8+Pj40Cmlm
+KG4+PTgpcmV0dXJuIEguT0goZCxuKQpuPShkW25dJjE8PChvJjE1KSkhPT0wfWVsc2Ugbj0hMQppZihu
+KSsrcgplbHNle2lmKG89PT0zNyl7bT1QLnJ2KGEsciwhMSkKaWYobT09bnVsbCl7cis9Mwpjb250aW51
+ZX1pZigiJSI9PT1tKXttPSIlMjUiCmw9MX1lbHNlIGw9M31lbHNle2lmKHMpaWYobzw9OTMpe249bz4+
+PjQKaWYobj49OClyZXR1cm4gSC5PSChDLmFrLG4pCm49KEMuYWtbbl0mMTw8KG8mMTUpKSE9PTB9ZWxz
+ZSBuPSExCmVsc2Ugbj0hMQppZihuKXtQLlIzKGEsciwiSW52YWxpZCBjaGFyYWN0ZXIiKQpILkJpKHUu
+ZykKbD1qCm09bH1lbHNle2lmKChvJjY0NTEyKT09PTU1Mjk2KXtuPXIrMQppZihuPGMpe2s9Qy54Qi5P
+KGEsbikKaWYoKGsmNjQ1MTIpPT09NTYzMjApe289KG8mMTAyMyk8PDEwfGsmMTAyM3w2NTUzNgpsPTJ9
+ZWxzZSBsPTF9ZWxzZSBsPTF9ZWxzZSBsPTEKbT1QLnpYKG8pfX1pZihwPT1udWxsKXtwPW5ldyBQLlJu
+KCIiKQpuPXB9ZWxzZSBuPXAKbi5hKz1DLnhCLk5qKGEscSxyKQpuLmErPUguRWoobSkKaWYodHlwZW9m
+IGwhPT0ibnVtYmVyIilyZXR1cm4gSC5wWShsKQpyKz1sCnE9cn19aWYocD09bnVsbClyZXR1cm4gagpp
+ZihxPGMpcC5hKz1DLnhCLk5qKGEscSxjKQpzPXAuYQpyZXR1cm4gcy5jaGFyQ29kZUF0KDApPT0wP3M6
+c30sCnlCOmZ1bmN0aW9uKGEpe2lmKEMueEIubkMoYSwiLiIpKXJldHVybiEwCnJldHVybiBDLnhCLk9Z
+KGEsIi8uIikhPT0tMX0sCnhlOmZ1bmN0aW9uKGEpe3ZhciBzLHIscSxwLG8sbixtCmlmKCFQLnlCKGEp
+KXJldHVybiBhCnM9SC5WTShbXSx0LnMpCmZvcihyPWEuc3BsaXQoIi8iKSxxPXIubGVuZ3RoLHA9ITEs
+bz0wO288cTsrK28pe249cltvXQppZihKLlJNKG4sIi4uIikpe209cy5sZW5ndGgKaWYobSE9PTApe2lm
+KDA+PW0pcmV0dXJuIEguT0gocywtMSkKcy5wb3AoKQppZihzLmxlbmd0aD09PTApQy5ObS5pKHMsIiIp
+fXA9ITB9ZWxzZSBpZigiLiI9PT1uKXA9ITAKZWxzZXtDLk5tLmkocyxuKQpwPSExfX1pZihwKUMuTm0u
+aShzLCIiKQpyZXR1cm4gQy5ObS5rKHMsIi8iKX0sCndGOmZ1bmN0aW9uKGEsYil7dmFyIHMscixxLHAs
+byxuCmlmKCFQLnlCKGEpKXJldHVybiFiP1AuQzEoYSk6YQpzPUguVk0oW10sdC5zKQpmb3Iocj1hLnNw
+bGl0KCIvIikscT1yLmxlbmd0aCxwPSExLG89MDtvPHE7KytvKXtuPXJbb10KaWYoIi4uIj09PW4paWYo
+cy5sZW5ndGghPT0wJiZDLk5tLmdyWihzKSE9PSIuLiIpe2lmKDA+PXMubGVuZ3RoKXJldHVybiBILk9I
+KHMsLTEpCnMucG9wKCkKcD0hMH1lbHNle0MuTm0uaShzLCIuLiIpCnA9ITF9ZWxzZSBpZigiLiI9PT1u
+KXA9ITAKZWxzZXtDLk5tLmkocyxuKQpwPSExfX1yPXMubGVuZ3RoCmlmKHIhPT0wKWlmKHI9PT0xKXtp
+ZigwPj1yKXJldHVybiBILk9IKHMsMCkKcj1zWzBdLmxlbmd0aD09PTB9ZWxzZSByPSExCmVsc2Ugcj0h
+MAppZihyKXJldHVybiIuLyIKaWYocHx8Qy5ObS5ncloocyk9PT0iLi4iKUMuTm0uaShzLCIiKQppZigh
+Yil7aWYoMD49cy5sZW5ndGgpcmV0dXJuIEguT0gocywwKQpDLk5tLlk1KHMsMCxQLkMxKHNbMF0pKX1y
+ZXR1cm4gQy5ObS5rKHMsIi8iKX0sCkMxOmZ1bmN0aW9uKGEpe3ZhciBzLHIscSxwPWEubGVuZ3RoCmlm
+KHA+PTImJlAuRXQoSi5ReihhLDApKSlmb3Iocz0xO3M8cDsrK3Mpe3I9Qy54Qi5XKGEscykKaWYocj09
+PTU4KXJldHVybiBDLnhCLk5qKGEsMCxzKSsiJTNBIitDLnhCLnluKGEscysxKQppZihyPD0xMjcpe3E9
+cj4+PjQKaWYocT49OClyZXR1cm4gSC5PSChDLm1LLHEpCnE9KEMubUtbcV0mMTw8KHImMTUpKT09PTB9
+ZWxzZSBxPSEwCmlmKHEpYnJlYWt9cmV0dXJuIGF9LAp1ajpmdW5jdGlvbihhLGIpe2lmKGEuaEIoInBh
+Y2thZ2UiKSYmYS5jPT1udWxsKXJldHVybiBQLmZGKGIsMCxiLmxlbmd0aCkKcmV0dXJuLTF9LAptbjpm
+dW5jdGlvbihhKXt2YXIgcyxyLHEscD1hLmdGaigpLG89Si5VNihwKQppZihvLmdBKHApPjAmJkouSG0o
+by5xKHAsMCkpPT09MiYmSi5hNihvLnEocCwwKSwxKT09PTU4KXtQLnJnKEouYTYoby5xKHAsMCksMCks
+ITEpClAuSE4ocCwhMSwxKQpzPSEwfWVsc2V7UC5ITihwLCExLDApCnM9ITF9cj1hLmd0VCgpJiYhcz8i
+XFwiOiIiCmlmKGEuZ2NqKCkpe3E9YS5nSmYoYSkKaWYocS5sZW5ndGghPT0wKXI9cisiXFwiK3ErIlxc
+In1yPVAudmcocixwLCJcXCIpCm89cyYmby5nQShwKT09PTE/cisiXFwiOnIKcmV0dXJuIG8uY2hhckNv
+ZGVBdCgwKT09MD9vOm99LApJaDpmdW5jdGlvbihhLGIpe3ZhciBzLHIscQpmb3Iocz0wLHI9MDtyPDI7
+KytyKXtxPUMueEIuVyhhLGIrcikKaWYoNDg8PXEmJnE8PTU3KXM9cyoxNitxLTQ4CmVsc2V7cXw9MzIK
+aWYoOTc8PXEmJnE8PTEwMilzPXMqMTYrcS04NwplbHNlIHRocm93IEguYihQLnhZKCJJbnZhbGlkIFVS
+TCBlbmNvZGluZyIpKX19cmV0dXJuIHN9LAprdTpmdW5jdGlvbihhLGIsYyxkLGUpe3ZhciBzLHIscSxw
+LG89Si5yWShhKSxuPWIKd2hpbGUoITApe2lmKCEobjxjKSl7cz0hMApicmVha31yPW8uVyhhLG4pCmlm
+KHI8PTEyNylpZihyIT09MzcpcT1lJiZyPT09NDMKZWxzZSBxPSEwCmVsc2UgcT0hMAppZihxKXtzPSEx
+CmJyZWFrfSsrbn1pZihzKXtpZihDLnhNIT09ZClxPSExCmVsc2UgcT0hMAppZihxKXJldHVybiBvLk5q
+KGEsYixjKQplbHNlIHA9bmV3IEgucWooby5OaihhLGIsYykpfWVsc2V7cD1ILlZNKFtdLHQuYSkKZm9y
+KG49YjtuPGM7KytuKXtyPW8uVyhhLG4pCmlmKHI+MTI3KXRocm93IEguYihQLnhZKCJJbGxlZ2FsIHBl
+cmNlbnQgZW5jb2RpbmcgaW4gVVJJIikpCmlmKHI9PT0zNyl7aWYobiszPmEubGVuZ3RoKXRocm93IEgu
+YihQLnhZKCJUcnVuY2F0ZWQgVVJJIikpCkMuTm0uaShwLFAuSWgoYSxuKzEpKQpuKz0yfWVsc2UgaWYo
+ZSYmcj09PTQzKUMuTm0uaShwLDMyKQplbHNlIEMuTm0uaShwLHIpfX10LkwuYShwKQpyZXR1cm4gQy5v
+RS5XSihwKX0sCkV0OmZ1bmN0aW9uKGEpe3ZhciBzPWF8MzIKcmV0dXJuIDk3PD1zJiZzPD0xMjJ9LApL
+RDpmdW5jdGlvbihhLGIsYyl7dmFyIHMscixxLHAsbyxuLG0sbCxrPSJJbnZhbGlkIE1JTUUgdHlwZSIs
+aj1ILlZNKFtiLTFdLHQuYSkKZm9yKHM9YS5sZW5ndGgscj1iLHE9LTEscD1udWxsO3I8czsrK3Ipe3A9
+Qy54Qi5XKGEscikKaWYocD09PTQ0fHxwPT09NTkpYnJlYWsKaWYocD09PTQ3KXtpZihxPDApe3E9cgpj
+b250aW51ZX10aHJvdyBILmIoUC5ycihrLGEscikpfX1pZihxPDAmJnI+Yil0aHJvdyBILmIoUC5ycihr
+LGEscikpCmZvcig7cCE9PTQ0Oyl7Qy5ObS5pKGoscik7KytyCmZvcihvPS0xO3I8czsrK3Ipe3A9Qy54
+Qi5XKGEscikKaWYocD09PTYxKXtpZihvPDApbz1yfWVsc2UgaWYocD09PTU5fHxwPT09NDQpYnJlYWt9
+aWYobz49MClDLk5tLmkoaixvKQplbHNle249Qy5ObS5nclooaikKaWYocCE9PTQ0fHxyIT09bis3fHwh
+Qy54Qi5RaShhLCJiYXNlNjQiLG4rMSkpdGhyb3cgSC5iKFAucnIoIkV4cGVjdGluZyAnPSciLGEscikp
+CmJyZWFrfX1DLk5tLmkoaixyKQptPXIrMQppZigoai5sZW5ndGgmMSk9PT0xKWE9Qy5oOS55cihhLG0s
+cykKZWxzZXtsPVAuVWwoYSxtLHMsQy5WQywhMCkKaWYobCE9bnVsbClhPUMueEIuaTcoYSxtLHMsbCl9
+cmV0dXJuIG5ldyBQLlBFKGEsaixjKX0sCktOOmZ1bmN0aW9uKCl7dmFyIHMscixxLHAsbyxuLG09IjAx
+MjM0NTY3ODlBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6
+LS5ffiEkJicoKSorLDs9IixsPSIuIixrPSI6IixqPSIvIixpPSI/IixoPSIjIixnPUguVk0obmV3IEFy
+cmF5KDIyKSx0LmdOKQpmb3Iocz0wO3M8MjI7KytzKWdbc109bmV3IFVpbnQ4QXJyYXkoOTYpCnI9bmV3
+IFAueUkoZykKcT1uZXcgUC5jNigpCnA9bmV3IFAucWQoKQpvPXQuZ2MKbj1vLmEoci4kMigwLDIyNSkp
+CnEuJDMobixtLDEpCnEuJDMobixsLDE0KQpxLiQzKG4saywzNCkKcS4kMyhuLGosMykKcS4kMyhuLGks
+MTcyKQpxLiQzKG4saCwyMDUpCm49by5hKHIuJDIoMTQsMjI1KSkKcS4kMyhuLG0sMSkKcS4kMyhuLGws
+MTUpCnEuJDMobixrLDM0KQpxLiQzKG4saiwyMzQpCnEuJDMobixpLDE3MikKcS4kMyhuLGgsMjA1KQpu
+PW8uYShyLiQyKDE1LDIyNSkpCnEuJDMobixtLDEpCnEuJDMobiwiJSIsMjI1KQpxLiQzKG4saywzNCkK
+cS4kMyhuLGosOSkKcS4kMyhuLGksMTcyKQpxLiQzKG4saCwyMDUpCm49by5hKHIuJDIoMSwyMjUpKQpx
+LiQzKG4sbSwxKQpxLiQzKG4saywzNCkKcS4kMyhuLGosMTApCnEuJDMobixpLDE3MikKcS4kMyhuLGgs
+MjA1KQpuPW8uYShyLiQyKDIsMjM1KSkKcS4kMyhuLG0sMTM5KQpxLiQzKG4saiwxMzEpCnEuJDMobixs
+LDE0NikKcS4kMyhuLGksMTcyKQpxLiQzKG4saCwyMDUpCm49by5hKHIuJDIoMywyMzUpKQpxLiQzKG4s
+bSwxMSkKcS4kMyhuLGosNjgpCnEuJDMobixsLDE4KQpxLiQzKG4saSwxNzIpCnEuJDMobixoLDIwNSkK
+bj1vLmEoci4kMig0LDIyOSkpCnEuJDMobixtLDUpCnAuJDMobiwiQVoiLDIyOSkKcS4kMyhuLGssMTAy
+KQpxLiQzKG4sIkAiLDY4KQpxLiQzKG4sIlsiLDIzMikKcS4kMyhuLGosMTM4KQpxLiQzKG4saSwxNzIp
+CnEuJDMobixoLDIwNSkKbj1vLmEoci4kMig1LDIyOSkpCnEuJDMobixtLDUpCnAuJDMobiwiQVoiLDIy
+OSkKcS4kMyhuLGssMTAyKQpxLiQzKG4sIkAiLDY4KQpxLiQzKG4saiwxMzgpCnEuJDMobixpLDE3MikK
+cS4kMyhuLGgsMjA1KQpuPW8uYShyLiQyKDYsMjMxKSkKcC4kMyhuLCIxOSIsNykKcS4kMyhuLCJAIiw2
+OCkKcS4kMyhuLGosMTM4KQpxLiQzKG4saSwxNzIpCnEuJDMobixoLDIwNSkKbj1vLmEoci4kMig3LDIz
+MSkpCnAuJDMobiwiMDkiLDcpCnEuJDMobiwiQCIsNjgpCnEuJDMobixqLDEzOCkKcS4kMyhuLGksMTcy
+KQpxLiQzKG4saCwyMDUpCnEuJDMoby5hKHIuJDIoOCw4KSksIl0iLDUpCm49by5hKHIuJDIoOSwyMzUp
+KQpxLiQzKG4sbSwxMSkKcS4kMyhuLGwsMTYpCnEuJDMobixqLDIzNCkKcS4kMyhuLGksMTcyKQpxLiQz
+KG4saCwyMDUpCm49by5hKHIuJDIoMTYsMjM1KSkKcS4kMyhuLG0sMTEpCnEuJDMobixsLDE3KQpxLiQz
+KG4saiwyMzQpCnEuJDMobixpLDE3MikKcS4kMyhuLGgsMjA1KQpuPW8uYShyLiQyKDE3LDIzNSkpCnEu
+JDMobixtLDExKQpxLiQzKG4saiw5KQpxLiQzKG4saSwxNzIpCnEuJDMobixoLDIwNSkKbj1vLmEoci4k
+MigxMCwyMzUpKQpxLiQzKG4sbSwxMSkKcS4kMyhuLGwsMTgpCnEuJDMobixqLDIzNCkKcS4kMyhuLGks
+MTcyKQpxLiQzKG4saCwyMDUpCm49by5hKHIuJDIoMTgsMjM1KSkKcS4kMyhuLG0sMTEpCnEuJDMobixs
+LDE5KQpxLiQzKG4saiwyMzQpCnEuJDMobixpLDE3MikKcS4kMyhuLGgsMjA1KQpuPW8uYShyLiQyKDE5
+LDIzNSkpCnEuJDMobixtLDExKQpxLiQzKG4saiwyMzQpCnEuJDMobixpLDE3MikKcS4kMyhuLGgsMjA1
+KQpuPW8uYShyLiQyKDExLDIzNSkpCnEuJDMobixtLDExKQpxLiQzKG4saiwxMCkKcS4kMyhuLGksMTcy
+KQpxLiQzKG4saCwyMDUpCm49by5hKHIuJDIoMTIsMjM2KSkKcS4kMyhuLG0sMTIpCnEuJDMobixpLDEy
+KQpxLiQzKG4saCwyMDUpCm49by5hKHIuJDIoMTMsMjM3KSkKcS4kMyhuLG0sMTMpCnEuJDMobixpLDEz
+KQpwLiQzKG8uYShyLiQyKDIwLDI0NSkpLCJheiIsMjEpCnI9by5hKHIuJDIoMjEsMjQ1KSkKcC4kMyhy
+LCJheiIsMjEpCnAuJDMociwiMDkiLDIxKQpxLiQzKHIsIistLiIsMjEpCnJldHVybiBnfSwKVUI6ZnVu
+Y3Rpb24oYSxiLGMsZCxlKXt2YXIgcyxyLHEscCxvLG49JC52WigpCmZvcihzPUouclkoYSkscj1iO3I8
+YzsrK3Ipe2lmKGQ8MHx8ZD49bi5sZW5ndGgpcmV0dXJuIEguT0gobixkKQpxPW5bZF0KcD1zLlcoYSxy
+KV45NgpvPXFbcD45NT8zMTpwXQpkPW8mMzEKQy5ObS5ZNShlLG8+Pj41LHIpfXJldHVybiBkfSwKUng6
+ZnVuY3Rpb24oYSl7aWYoYS5iPT09NyYmQy54Qi5uQyhhLmEsInBhY2thZ2UiKSYmYS5jPD0wKXJldHVy
+biBQLmZGKGEuYSxhLmUsYS5mKQpyZXR1cm4tMX0sCmZGOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyLHEK
+Zm9yKHM9YixyPTA7czxjOysrcyl7cT1DLnhCLk8oYSxzKQppZihxPT09NDcpcmV0dXJuIHIhPT0wP3M6
+LTEKaWYocT09PTM3fHxxPT09NTgpcmV0dXJuLTEKcnw9cV40Nn1yZXR1cm4tMX0sCldGOmZ1bmN0aW9u
+IFdGKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LAppUDpmdW5jdGlvbiBpUChhLGIpe3RoaXMuYT1hCnRo
+aXMuYj1ifSwKWFM6ZnVuY3Rpb24gWFMoKXt9LApDNjpmdW5jdGlvbiBDNihhKXt0aGlzLmE9YX0sCkV6
+OmZ1bmN0aW9uIEV6KCl7fSwKRjpmdW5jdGlvbiBGKCl7fSwKdTpmdW5jdGlvbiB1KGEsYixjLGQpe3Zh
+ciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5jPWMKXy5kPWR9LApiSjpmdW5jdGlvbiBiSihhLGIsYyxkLGUs
+Zil7dmFyIF89dGhpcwpfLmU9YQpfLmY9YgpfLmE9YwpfLmI9ZApfLmM9ZQpfLmQ9Zn0sCmVZOmZ1bmN0
+aW9uIGVZKGEsYixjLGQsZSl7dmFyIF89dGhpcwpfLmY9YQpfLmE9YgpfLmI9YwpfLmM9ZApfLmQ9ZX0s
+Cm1wOmZ1bmN0aW9uIG1wKGEsYixjLGQpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5jPWMKXy5kPWR9
+LAp1YjpmdW5jdGlvbiB1YihhKXt0aGlzLmE9YX0sCmRzOmZ1bmN0aW9uIGRzKGEpe3RoaXMuYT1hfSwK
+bGo6ZnVuY3Rpb24gbGooYSl7dGhpcy5hPWF9LApVVjpmdW5jdGlvbiBVVihhKXt0aGlzLmE9YX0sCms1
+OmZ1bmN0aW9uIGs1KCl7fSwKS1k6ZnVuY3Rpb24gS1koKXt9LApjOmZ1bmN0aW9uIGMoYSl7dGhpcy5h
+PWF9LApDRDpmdW5jdGlvbiBDRChhKXt0aGlzLmE9YX0sCmFFOmZ1bmN0aW9uIGFFKGEsYixjKXt0aGlz
+LmE9YQp0aGlzLmI9Ygp0aGlzLmM9Y30sCmNYOmZ1bmN0aW9uIGNYKCl7fSwKQW46ZnVuY3Rpb24gQW4o
+KXt9LApOMzpmdW5jdGlvbiBOMyhhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy4kdGk9Y30sCmM4
+OmZ1bmN0aW9uIGM4KCl7fSwKTWg6ZnVuY3Rpb24gTWgoKXt9LApaZDpmdW5jdGlvbiBaZCgpe30sClJu
+OmZ1bmN0aW9uIFJuKGEpe3RoaXMuYT1hfSwKbjE6ZnVuY3Rpb24gbjEoYSl7dGhpcy5hPWF9LApjUzpm
+dW5jdGlvbiBjUyhhKXt0aGlzLmE9YX0sClZDOmZ1bmN0aW9uIFZDKGEpe3RoaXMuYT1hfSwKSlQ6ZnVu
+Y3Rpb24gSlQoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCkRuOmZ1bmN0aW9uIERuKGEsYixjLGQsZSxm
+LGcpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5jPWMKXy5kPWQKXy5lPWUKXy5mPWYKXy5yPWcKXy5R
+PV8uej1fLnk9Xy54PSR9LApSWjpmdW5jdGlvbiBSWigpe30sCk1FOmZ1bmN0aW9uIE1FKGEsYil7dGhp
+cy5hPWEKdGhpcy5iPWJ9LAp5NTpmdW5jdGlvbiB5NShhKXt0aGlzLmE9YX0sClBFOmZ1bmN0aW9uIFBF
+KGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9Y30sCnlJOmZ1bmN0aW9uIHlJKGEpe3RoaXMu
+YT1hfSwKYzY6ZnVuY3Rpb24gYzYoKXt9LApxZDpmdW5jdGlvbiBxZCgpe30sClVmOmZ1bmN0aW9uIFVm
+KGEsYixjLGQsZSxmLGcsaCl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLmQ9ZApfLmU9ZQpf
+LmY9ZgpfLnI9ZwpfLng9aApfLnk9bnVsbH0sCnFlOmZ1bmN0aW9uIHFlKGEsYixjLGQsZSxmLGcpe3Zh
+ciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5jPWMKXy5kPWQKXy5lPWUKXy5mPWYKXy5yPWcKXy5RPV8uej1f
+Lnk9Xy54PSR9LAppSjpmdW5jdGlvbiBpSigpe30sCmpnOmZ1bmN0aW9uIGpnKGEsYil7dGhpcy5hPWEK
+dGhpcy5iPWJ9LApUYTpmdW5jdGlvbiBUYShhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKQmY6ZnVuY3Rp
+b24gQmYoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCkFzOmZ1bmN0aW9uIEFzKCl7fSwKR0U6ZnVuY3Rp
+b24gR0UoYSl7dGhpcy5hPWF9LApONzpmdW5jdGlvbiBONyhhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwK
+dVE6ZnVuY3Rpb24gdVEoKXt9LApoRjpmdW5jdGlvbiBoRigpe30sClI0OmZ1bmN0aW9uKGEsYixjLGQp
+e3ZhciBzLHIscQpILnk4KGIpCnQuai5hKGQpCmlmKEgub1QoYikpe3M9W2NdCkMuTm0uRlYocyxkKQpk
+PXN9cj10LnoKcT1QLkNIKEouTTEoZCxQLncwKCksciksITAscikKdC5ZLmEoYSkKcmV0dXJuIFAud1ko
+SC5FayhhLHEsbnVsbCkpfSwKRG06ZnVuY3Rpb24oYSxiLGMpe3ZhciBzCnRyeXtpZihPYmplY3QuaXNF
+eHRlbnNpYmxlKGEpJiYhT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGEsYikpe09i
+amVjdC5kZWZpbmVQcm9wZXJ0eShhLGIse3ZhbHVlOmN9KQpyZXR1cm4hMH19Y2F0Y2gocyl7SC5SdShz
+KX1yZXR1cm4hMX0sCk9tOmZ1bmN0aW9uKGEsYil7aWYoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9w
+ZXJ0eS5jYWxsKGEsYikpcmV0dXJuIGFbYl0KcmV0dXJuIG51bGx9LAp3WTpmdW5jdGlvbihhKXtpZihh
+PT1udWxsfHx0eXBlb2YgYT09InN0cmluZyJ8fHR5cGVvZiBhPT0ibnVtYmVyInx8SC5sKGEpKXJldHVy
+biBhCmlmKGEgaW5zdGFuY2VvZiBQLkU0KXJldHVybiBhLmEKaWYoSC5SOShhKSlyZXR1cm4gYQppZih0
+LmFrLmIoYSkpcmV0dXJuIGEKaWYoYSBpbnN0YW5jZW9mIFAuaVApcmV0dXJuIEgubzIoYSkKaWYodC5Z
+LmIoYSkpcmV0dXJuIFAuaEUoYSwiJGRhcnRfanNGdW5jdGlvbiIsbmV3IFAuUEMoKSkKcmV0dXJuIFAu
+aEUoYSwiXyRkYXJ0X2pzT2JqZWN0IixuZXcgUC5tdCgkLmtJKCkpKX0sCmhFOmZ1bmN0aW9uKGEsYixj
+KXt2YXIgcz1QLk9tKGEsYikKaWYocz09bnVsbCl7cz1jLiQxKGEpClAuRG0oYSxiLHMpfXJldHVybiBz
+fSwKZFU6ZnVuY3Rpb24oYSl7dmFyIHMscgppZihhPT1udWxsfHx0eXBlb2YgYT09InN0cmluZyJ8fHR5
+cGVvZiBhPT0ibnVtYmVyInx8dHlwZW9mIGE9PSJib29sZWFuIilyZXR1cm4gYQplbHNlIGlmKGEgaW5z
+dGFuY2VvZiBPYmplY3QmJkguUjkoYSkpcmV0dXJuIGEKZWxzZSBpZihhIGluc3RhbmNlb2YgT2JqZWN0
+JiZ0LmFrLmIoYSkpcmV0dXJuIGEKZWxzZSBpZihhIGluc3RhbmNlb2YgRGF0ZSl7cz1ILnVQKGEuZ2V0
+VGltZSgpKQppZihNYXRoLmFicyhzKTw9ODY0ZTEzKXI9ITEKZWxzZSByPSEwCmlmKHIpSC52KFAueFko
+IkRhdGVUaW1lIGlzIG91dHNpZGUgdmFsaWQgcmFuZ2U6ICIrcykpCkguY2IoITEsImlzVXRjIix0Lnkp
+CnJldHVybiBuZXcgUC5pUChzLCExKX1lbHNlIGlmKGEuY29uc3RydWN0b3I9PT0kLmtJKCkpcmV0dXJu
+IGEubwplbHNlIHJldHVybiBQLk5EKGEpfSwKTkQ6ZnVuY3Rpb24oYSl7aWYodHlwZW9mIGE9PSJmdW5j
+dGlvbiIpcmV0dXJuIFAuaVEoYSwkLncoKSxuZXcgUC5RUygpKQppZihhIGluc3RhbmNlb2YgQXJyYXkp
+cmV0dXJuIFAuaVEoYSwkLlI4KCksbmV3IFAubnAoKSkKcmV0dXJuIFAuaVEoYSwkLlI4KCksbmV3IFAu
+VXQoKSl9LAppUTpmdW5jdGlvbihhLGIsYyl7dmFyIHM9UC5PbShhLGIpCmlmKHM9PW51bGx8fCEoYSBp
+bnN0YW5jZW9mIE9iamVjdCkpe3M9Yy4kMShhKQpQLkRtKGEsYixzKX1yZXR1cm4gc30sClBDOmZ1bmN0
+aW9uIFBDKCl7fSwKbXQ6ZnVuY3Rpb24gbXQoYSl7dGhpcy5hPWF9LApRUzpmdW5jdGlvbiBRUygpe30s
+Cm5wOmZ1bmN0aW9uIG5wKCl7fSwKVXQ6ZnVuY3Rpb24gVXQoKXt9LApFNDpmdW5jdGlvbiBFNChhKXt0
+aGlzLmE9YX0sCnI3OmZ1bmN0aW9uIHI3KGEpe3RoaXMuYT1hfSwKVHo6ZnVuY3Rpb24gVHooYSxiKXt0
+aGlzLmE9YQp0aGlzLiR0aT1ifSwKY286ZnVuY3Rpb24gY28oKXt9LApuZDpmdW5jdGlvbiBuZCgpe30s
+CktlOmZ1bmN0aW9uIEtlKGEpe3RoaXMuYT1hfSwKaGk6ZnVuY3Rpb24gaGkoKXt9fSxXPXsKeDM6ZnVu
+Y3Rpb24oKXtyZXR1cm4gd2luZG93fSwKWnI6ZnVuY3Rpb24oKXtyZXR1cm4gZG9jdW1lbnR9LApKNjpm
+dW5jdGlvbihhKXt2YXIgcz1kb2N1bWVudC5jcmVhdGVFbGVtZW50KCJhIikKaWYoYSE9bnVsbClDLnhu
+LnNMVShzLGEpCnJldHVybiBzfSwKTGo6ZnVuY3Rpb24oYSl7cmV0dXJuIENTUy5lc2NhcGUoYSl9LApV
+OTpmdW5jdGlvbihhLGIsYyl7dmFyIHMscj1kb2N1bWVudC5ib2R5CnIudG9TdHJpbmcKcz1DLlJZLnI2
+KHIsYSxiLGMpCnMudG9TdHJpbmcKcj10LmFjCnI9bmV3IEguVTUobmV3IFcuZTcocyksci5DKCJhMihs
+RC5FKSIpLmEobmV3IFcuQ3YoKSksci5DKCJVNTxsRC5FPiIpKQpyZXR1cm4gdC5oLmEoci5ncjgocikp
+fSwKclM6ZnVuY3Rpb24oYSl7dmFyIHMscixxPSJlbGVtZW50IHRhZyB1bmF2YWlsYWJsZSIKdHJ5e3M9
+Si5ZRShhKQppZih0eXBlb2Ygcy5nbnMoYSk9PSJzdHJpbmciKXE9cy5nbnMoYSl9Y2F0Y2gocil7SC5S
+dShyKX1yZXR1cm4gcX0sCkMwOmZ1bmN0aW9uKGEsYil7YT1hK2ImNTM2ODcwOTExCmE9YSsoKGEmNTI0
+Mjg3KTw8MTApJjUzNjg3MDkxMQpyZXR1cm4gYV5hPj4+Nn0sCnJFOmZ1bmN0aW9uKGEsYixjLGQpe3Zh
+ciBzPVcuQzAoVy5DMChXLkMwKFcuQzAoMCxhKSxiKSxjKSxkKSxyPXMrKChzJjY3MTA4ODYzKTw8Mykm
+NTM2ODcwOTExCnJePXI+Pj4xMQpyZXR1cm4gcisoKHImMTYzODMpPDwxNSkmNTM2ODcwOTExfSwKVE46
+ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHE9YS5jbGFzc0xpc3QKZm9yKHM9Yi5sZW5ndGgscj0wO3I8Yi5s
+ZW5ndGg7Yi5sZW5ndGg9PT1zfHwoMCxILmxrKShiKSwrK3IpcS5hZGQoYltyXSl9LApKRTpmdW5jdGlv
+bihhLGIsYyxkLGUpe3ZhciBzPVcuYUYobmV3IFcudk4oYyksdC5CKQppZihzIT1udWxsJiYhMClKLmRa
+KGEsYixzLCExKQpyZXR1cm4gbmV3IFcueEMoYSxiLHMsITEsZS5DKCJ4QzwwPiIpKX0sClR3OmZ1bmN0
+aW9uKGEpe3ZhciBzPVcuSjYobnVsbCkscj13aW5kb3cubG9jYXRpb24Kcz1uZXcgVy5KUShuZXcgVy5t
+ayhzLHIpKQpzLkNZKGEpCnJldHVybiBzfSwKcUQ6ZnVuY3Rpb24oYSxiLGMsZCl7dC5oLmEoYSkKSC5o
+KGIpCkguaChjKQp0LmNyLmEoZCkKcmV0dXJuITB9LApuWjpmdW5jdGlvbihhLGIsYyxkKXt2YXIgcyxy
+LHEKdC5oLmEoYSkKSC5oKGIpCkguaChjKQpzPXQuY3IuYShkKS5hCnI9cy5hCkMueG4uc0xVKHIsYykK
+cT1yLmhvc3RuYW1lCnM9cy5iCmlmKCEocT09cy5ob3N0bmFtZSYmci5wb3J0PT1zLnBvcnQmJnIucHJv
+dG9jb2w9PXMucHJvdG9jb2wpKWlmKHE9PT0iIilpZihyLnBvcnQ9PT0iIil7cz1yLnByb3RvY29sCnM9
+cz09PSI6Inx8cz09PSIifWVsc2Ugcz0hMQplbHNlIHM9ITEKZWxzZSBzPSEwCnJldHVybiBzfSwKQmw6
+ZnVuY3Rpb24oKXt2YXIgcz10Lk4scj1QLnRNKEMuUXgscykscT10LmQwLmEobmV3IFcuSUEoKSkscD1I
+LlZNKFsiVEVNUExBVEUiXSx0LnMpCnM9bmV3IFcuY3QocixQLkxzKHMpLFAuTHMocyksUC5McyhzKSxu
+dWxsKQpzLkNZKG51bGwsbmV3IEgubEooQy5ReCxxLHQuZmopLHAsbnVsbCkKcmV0dXJuIHN9LApxYzpm
+dW5jdGlvbihhKXt2YXIgcwppZihhPT1udWxsKXJldHVybiBudWxsCmlmKCJwb3N0TWVzc2FnZSIgaW4g
+YSl7cz1XLlAxKGEpCmlmKHQuYVMuYihzKSlyZXR1cm4gcwpyZXR1cm4gbnVsbH1lbHNlIHJldHVybiB0
+LmNoLmEoYSl9LApQMTpmdW5jdGlvbihhKXtpZihhPT09d2luZG93KXJldHVybiB0LmNpLmEoYSkKZWxz
+ZSByZXR1cm4gbmV3IFcuZFcoKX0sCmFGOmZ1bmN0aW9uKGEsYil7dmFyIHM9JC5YMwppZihzPT09Qy5O
+VSlyZXR1cm4gYQpyZXR1cm4gcy5QeShhLGIpfSwKcUU6ZnVuY3Rpb24gcUUoKXt9LApHaDpmdW5jdGlv
+biBHaCgpe30sCmZZOmZ1bmN0aW9uIGZZKCl7fSwKbkI6ZnVuY3Rpb24gbkIoKXt9LApBejpmdW5jdGlv
+biBBeigpe30sClFQOmZ1bmN0aW9uIFFQKCl7fSwKbng6ZnVuY3Rpb24gbngoKXt9LApvSjpmdW5jdGlv
+biBvSigpe30sCmlkOmZ1bmN0aW9uIGlkKCl7fSwKUUY6ZnVuY3Rpb24gUUYoKXt9LApOaDpmdW5jdGlv
+biBOaCgpe30sCmFlOmZ1bmN0aW9uIGFlKCl7fSwKSUI6ZnVuY3Rpb24gSUIoKXt9LApuNzpmdW5jdGlv
+biBuNygpe30sCnd6OmZ1bmN0aW9uIHd6KGEsYil7dGhpcy5hPWEKdGhpcy4kdGk9Yn0sCmN2OmZ1bmN0
+aW9uIGN2KCl7fSwKQ3Y6ZnVuY3Rpb24gQ3YoKXt9LAplYTpmdW5jdGlvbiBlYSgpe30sCkQwOmZ1bmN0
+aW9uIEQwKCl7fSwKaEg6ZnVuY3Rpb24gaEgoKXt9LApoNDpmdW5jdGlvbiBoNCgpe30sCmJyOmZ1bmN0
+aW9uIGJyKCl7fSwKVmI6ZnVuY3Rpb24gVmIoKXt9LApmSjpmdW5jdGlvbiBmSigpe30sCndhOmZ1bmN0
+aW9uIHdhKCl7fSwKU2c6ZnVuY3Rpb24gU2coKXt9LAp3NzpmdW5jdGlvbiB3Nygpe30sCkFqOmZ1bmN0
+aW9uIEFqKCl7fSwKZTc6ZnVuY3Rpb24gZTcoYSl7dGhpcy5hPWF9LAp1SDpmdW5jdGlvbiB1SCgpe30s
+CkJIOmZ1bmN0aW9uIEJIKCl7fSwKU046ZnVuY3Rpb24gU04oKXt9LApldzpmdW5jdGlvbiBldygpe30s
+CmxwOmZ1bmN0aW9uIGxwKCl7fSwKVGI6ZnVuY3Rpb24gVGIoKXt9LApJdjpmdW5jdGlvbiBJdigpe30s
+CldQOmZ1bmN0aW9uIFdQKCl7fSwKeVk6ZnVuY3Rpb24geVkoKXt9LAp3NjpmdW5jdGlvbiB3Nigpe30s
+Cks1OmZ1bmN0aW9uIEs1KCl7fSwKQ206ZnVuY3Rpb24gQ20oKXt9LApDUTpmdW5jdGlvbiBDUSgpe30s
+Cnc0OmZ1bmN0aW9uIHc0KCl7fSwKcmg6ZnVuY3Rpb24gcmgoKXt9LApjZjpmdW5jdGlvbiBjZigpe30s
+Cmk3OmZ1bmN0aW9uIGk3KGEpe3RoaXMuYT1hfSwKU3k6ZnVuY3Rpb24gU3koYSl7dGhpcy5hPWF9LApL
+UzpmdW5jdGlvbiBLUyhhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKQTM6ZnVuY3Rpb24gQTMoYSxiKXt0
+aGlzLmE9YQp0aGlzLmI9Yn0sCkk0OmZ1bmN0aW9uIEk0KGEpe3RoaXMuYT1hfSwKRms6ZnVuY3Rpb24g
+RmsoYSxiKXt0aGlzLmE9YQp0aGlzLiR0aT1ifSwKUk86ZnVuY3Rpb24gUk8oYSxiLGMsZCl7dmFyIF89
+dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLiR0aT1kfSwKZXU6ZnVuY3Rpb24gZXUoYSxiLGMsZCl7dmFy
+IF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLiR0aT1kfSwKeEM6ZnVuY3Rpb24geEMoYSxiLGMsZCxl
+KXt2YXIgXz10aGlzCl8uYj1hCl8uYz1iCl8uZD1jCl8uZT1kCl8uJHRpPWV9LAp2TjpmdW5jdGlvbiB2
+TihhKXt0aGlzLmE9YX0sCkpROmZ1bmN0aW9uIEpRKGEpe3RoaXMuYT1hfSwKR206ZnVuY3Rpb24gR20o
+KXt9LAp2RDpmdW5jdGlvbiB2RChhKXt0aGlzLmE9YX0sClV2OmZ1bmN0aW9uIFV2KGEpe3RoaXMuYT1h
+fSwKRWc6ZnVuY3Rpb24gRWcoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKbTY6ZnVu
+Y3Rpb24gbTYoKXt9LApFbzpmdW5jdGlvbiBFbygpe30sCldrOmZ1bmN0aW9uIFdrKCl7fSwKY3Q6ZnVu
+Y3Rpb24gY3QoYSxiLGMsZCxlKXt2YXIgXz10aGlzCl8uZT1hCl8uYT1iCl8uYj1jCl8uYz1kCl8uZD1l
+fSwKSUE6ZnVuY3Rpb24gSUEoKXt9LApPdzpmdW5jdGlvbiBPdygpe30sClc5OmZ1bmN0aW9uIFc5KGEs
+YixjKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz0tMQpfLmQ9bnVsbApfLiR0aT1jfSwKZFc6ZnVu
+Y3Rpb24gZFcoKXt9LAptazpmdW5jdGlvbiBtayhhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKS286ZnVu
+Y3Rpb24gS28oYSl7dGhpcy5hPWEKdGhpcy5iPSExfSwKZm06ZnVuY3Rpb24gZm0oYSl7dGhpcy5hPWF9
+LApMZTpmdW5jdGlvbiBMZSgpe30sCks3OmZ1bmN0aW9uIEs3KCl7fSwKckI6ZnVuY3Rpb24gckIoKXt9
+LApYVzpmdW5jdGlvbiBYVygpe30sCm9hOmZ1bmN0aW9uIG9hKCl7fX0sVT17CmpmOmZ1bmN0aW9uKGEp
+e3ZhciBzLHIscSxwCmlmKGE9PW51bGwpcz1udWxsCmVsc2V7cz1ILlZNKFtdLHQuZDcpCmZvcihyPUou
+SVQodC5VLmEoYSkpO3IuRigpOyl7cT1yLmdsKCkKcD1KLlU2KHEpCnMucHVzaChuZXcgVS5TZShILmgo
+cC5xKHEsImRlc2NyaXB0aW9uIikpLEguaChwLnEocSwiaHJlZiIpKSkpfX1yZXR1cm4gc30sCk5kOmZ1
+bmN0aW9uKGEpe3ZhciBzLHIKaWYoYT09bnVsbClzPW51bGwKZWxzZXtzPUguVk0oW10sdC5hQSkKZm9y
+KHI9Si5JVCh0LlUuYShhKSk7ci5GKCk7KXMucHVzaChVLk5mKHIuZ2woKSkpfXJldHVybiBzfSwKTmY6
+ZnVuY3Rpb24oYSl7dmFyIHM9Si5VNihhKSxyPUguaChzLnEoYSwiZGVzY3JpcHRpb24iKSkscT1ILlZN
+KFtdLHQuYUopCmZvcihzPUouSVQodC5VLmEocy5xKGEsImVudHJpZXMiKSkpO3MuRigpOylxLnB1c2go
+VS5SaihzLmdsKCkpKQpyZXR1cm4gbmV3IFUueUQocixxKX0sClJqOmZ1bmN0aW9uKGEpe3ZhciBzLHI9
+Si5VNihhKSxxPUguaChyLnEoYSwiZGVzY3JpcHRpb24iKSkscD1ILmgoci5xKGEsImZ1bmN0aW9uIikp
+LG89ci5xKGEsImxpbmsiKQppZihvPT1udWxsKW89bnVsbAplbHNle3M9Si5VNihvKQpvPW5ldyBVLk1s
+KEguaChzLnEobywiaHJlZiIpKSxILnVQKHMucShvLCJsaW5lIikpLEguaChzLnEobywicGF0aCIpKSl9
+cj10LmZLLmEoci5xKGEsImhpbnRBY3Rpb25zIikpCnI9cj09bnVsbD9udWxsOkouTTEocixuZXcgVS5h
+TigpLHQuYVgpCnI9cj09bnVsbD9udWxsOnIuYnIoMCkKcmV0dXJuIG5ldyBVLndiKHEscCxvLHI9PW51
+bGw/Qy5kbjpyKX0sCmQyOmZ1bmN0aW9uIGQyKGEsYixjLGQsZSxmKXt2YXIgXz10aGlzCl8uYT1hCl8u
+Yj1iCl8uYz1jCl8uZD1kCl8uZT1lCl8uZj1mfSwKU2U6ZnVuY3Rpb24gU2UoYSxiKXt0aGlzLmE9YQp0
+aGlzLmI9Yn0sCk1sOmZ1bmN0aW9uIE1sKGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9Y30s
+CnlEOmZ1bmN0aW9uIHlEKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LAp3YjpmdW5jdGlvbiB3YihhLGIs
+YyxkKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz1jCl8uZD1kfSwKYU46ZnVuY3Rpb24gYU4oKXt9
+LApiMDpmdW5jdGlvbiBiMCgpe319LEI9ewp3UjpmdW5jdGlvbigpe3JldHVybiBuZXcgQi5xcCgiIiwi
+IiwiIixDLkR4KX0sCllmOmZ1bmN0aW9uKGEpe3ZhciBzLHIscSxwLG8sbixtLGwsaz1ILmgoYS5xKDAs
+InJlZ2lvbnMiKSksaj1ILmgoYS5xKDAsIm5hdmlnYXRpb25Db250ZW50IikpLGk9SC5oKGEucSgwLCJz
+b3VyY2VDb2RlIikpLGg9UC5GbCh0LlgsdC5kXykKZm9yKHM9dC50LmEoYS5xKDAsImVkaXRzIikpLHM9
+cy5nUHUocykscz1zLmdtKHMpLHI9dC5VLHE9dC5oNDtzLkYoKTspe3A9cy5nbCgpCm89cC5hCm49SC5W
+TShbXSxxKQpmb3IocD1KLklUKHIuYShwLmIpKTtwLkYoKTspe209cC5nbCgpCmw9Si5VNihtKQpuLnB1
+c2gobmV3IEIuajgoSC51UChsLnEobSwibGluZSIpKSxILmgobC5xKG0sImV4cGxhbmF0aW9uIikpLEgu
+dVAobC5xKG0sIm9mZnNldCIpKSkpfWguWTUoMCxvLG4pfXJldHVybiBuZXcgQi5xcChrLGosaSxoKX0s
+Cmo4OmZ1bmN0aW9uIGo4KGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9Y30sCnFwOmZ1bmN0
+aW9uIHFwKGEsYixjLGQpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5jPWMKXy5kPWR9LApmdjpmdW5j
+dGlvbiBmdigpe30sCk9TOmZ1bmN0aW9uKGEpe3ZhciBzCmlmKCEoYT49NjUmJmE8PTkwKSlzPWE+PTk3
+JiZhPD0xMjIKZWxzZSBzPSEwCnJldHVybiBzfSwKWXU6ZnVuY3Rpb24oYSxiKXt2YXIgcz1hLmxlbmd0
+aCxyPWIrMgppZihzPHIpcmV0dXJuITEKaWYoIUIuT1MoQy54Qi5PKGEsYikpKXJldHVybiExCmlmKEMu
+eEIuTyhhLGIrMSkhPT01OClyZXR1cm4hMQppZihzPT09cilyZXR1cm4hMApyZXR1cm4gQy54Qi5PKGEs
+cik9PT00N319LFQ9e21ROmZ1bmN0aW9uIG1RKCl7fX0sTD17CklxOmZ1bmN0aW9uKCl7Qy5CWi5CKGRv
+Y3VtZW50LCJET01Db250ZW50TG9hZGVkIixuZXcgTC5lKCkpCkMub2wuQih3aW5kb3csInBvcHN0YXRl
+IixuZXcgTC5MKCkpfSwKa3o6ZnVuY3Rpb24oYSl7dmFyIHMscj10LmcuYShhLnBhcmVudE5vZGUpLnF1
+ZXJ5U2VsZWN0b3IoIjpzY29wZSA+IHVsIikscT1yLnN0eWxlLHA9IiIrQy5DRC56UShyLm9mZnNldEhl
+aWdodCkqMisicHgiCnEubWF4SGVpZ2h0PXAKcT1KLnFGKGEpCnA9cS4kdGkKcz1wLkMoIn4oMSk/Iiku
+YShuZXcgTC5XeChyLGEpKQp0LlouYShudWxsKQpXLkpFKHEuYSxxLmIscywhMSxwLmMpfSwKeVg6ZnVu
+Y3Rpb24oYSxiKXt2YXIgcyxyLHEscCxvLG4sbT0icXVlcnlTZWxlY3RvckFsbCIsbD1kb2N1bWVudC5x
+dWVyeVNlbGVjdG9yKGEpLGs9dC5nCmwudG9TdHJpbmcKcz10LmgKSC5EaChrLHMsIlQiLG0pCnI9dC5S
+CnE9bmV3IFcud3oobC5xdWVyeVNlbGVjdG9yQWxsKCIubmF2LWxpbmsiKSxyKQpxLksocSxuZXcgTC5B
+TyhiKSkKSC5EaChrLHMsIlQiLG0pCnA9bmV3IFcud3oobC5xdWVyeVNlbGVjdG9yQWxsKCIucmVnaW9u
+IikscikKaWYoIXAuZ2wwKHApKXtvPWwucXVlcnlTZWxlY3RvcigidGFibGVbZGF0YS1wYXRoXSIpCm8u
+dG9TdHJpbmcKcC5LKHAsbmV3IEwuSG8oby5nZXRBdHRyaWJ1dGUoImRhdGEtIituZXcgVy5TeShuZXcg
+Vy5pNyhvKSkuT1UoInBhdGgiKSkpKX1ILkRoKGsscywiVCIsbSkKbj1uZXcgVy53eihsLnF1ZXJ5U2Vs
+ZWN0b3JBbGwoIi5hZGQtaGludC1saW5rIikscikKbi5LKG4sbmV3IEwuSUMoKSl9LApRNjpmdW5jdGlv
+bihhLGIsYyl7dmFyIHM9bmV3IFhNTEh0dHBSZXF1ZXN0KCkKQy5EdC5lbyhzLCJHRVQiLEwuUTQoYSxi
+KSwhMCkKcy5zZXRSZXF1ZXN0SGVhZGVyKCJDb250ZW50LVR5cGUiLCJhcHBsaWNhdGlvbi9qc29uOyBj
+aGFyc2V0PVVURi04IikKcmV0dXJuIEwuTFUocyxudWxsLGMuQygiMCoiKSl9LAp0eTpmdW5jdGlvbihh
+LGIpe3ZhciBzPW5ldyBYTUxIdHRwUmVxdWVzdCgpLHI9dC5YCkMuRHQuZW8ocywiUE9TVCIsTC5RNChh
+LFAuRmwocixyKSksITApCnMuc2V0UmVxdWVzdEhlYWRlcigiQ29udGVudC1UeXBlIiwiYXBwbGljYXRp
+b24vanNvbjsgY2hhcnNldD1VVEYtOCIpCnJldHVybiBMLkxVKHMsYix0LnQpfSwKTFU6ZnVuY3Rpb24o
+YSxiLGMpe3JldHVybiBMLlRnKGEsYixjLGMuQygiMCoiKSl9LApUZzpmdW5jdGlvbihhLGIsYyxkKXt2
+YXIgcz0wLHI9UC5GWChkKSxxLHA9MixvLG49W10sbSxsLGssaixpLGgsZyxmLGUKdmFyICRhc3luYyRM
+VT1QLmx6KGZ1bmN0aW9uKGEwLGExKXtpZihhMD09PTEpe289YTEKcz1wfXdoaWxlKHRydWUpc3dpdGNo
+KHMpe2Nhc2UgMDpoPW5ldyBQLlpmKG5ldyBQLnZzKCQuWDMsdC5nViksdC5iQykKZz10LmViCmY9Zy5h
+KG5ldyBMLmZDKGgsYSkpCnQuWi5hKG51bGwpCms9dC5lUQpXLkpFKGEsImxvYWQiLGYsITEsaykKVy5K
+RShhLCJlcnJvciIsZy5hKGguZ1lKKCkpLCExLGspCmEuc2VuZChiPT1udWxsP251bGw6Qy5DdC5PQihi
+LG51bGwpKQpwPTQKcz03CnJldHVybiBQLmpRKGguYSwkYXN5bmMkTFUpCmNhc2UgNzpwPTIKcz02CmJy
+ZWFrCmNhc2UgNDpwPTMKZT1vCkguUnUoZSkKbT1ILnRzKGUpCmc9YS5yZWFkeVN0YXRlCmlmKGc9PT00
+JiZhLnN0YXR1cz09PTApdGhyb3cgSC5iKEwuVEcoIkVycm9yIHJlYWNoaW5nIG1pZ3JhdGlvbiBwcmV2
+aWV3IHNlcnZlciIsIlRoaXMgdXN1YWxseSBoYXBwZW5zIGJlY2F1c2UgdGhlIG1pZ3JhdGlvbiBwcmV2
+aWV3IHNlcnZlciBoYXMgZXhpdGVkLiAgRm9yXG5leGFtcGxlIGl0IG1heSBoYXZlIGJlZW4gYWJvcnRl
+ZCB3aXRoIEN0cmwtQywgb3IgeW91IG1heSBoYXZlIGNvbXBsZXRlZCB0aGlzXG5taWdyYXRpb24sIG9y
+IGFuIGV4Y2VwdGlvbiBtYXkgaGF2ZSBvY2N1cnJlZC4gIFBsZWFzZSBjaGVjayB0aGUgY29uc29sZSB3
+aGVyZVxueW91IGludm9rZWQgYGRhcnQgbWlncmF0ZWAgdG8gdmVyaWZ5IHRoYXQgdGhlIHByZXZpZXcg
+c2VydmVyIGlzIHN0aWxsIHJ1bm5pbmcuXG4iKSkKZWxzZXtsPW5ldyBILmxKKEguVk0oWyJyZWFkeVN0
+YXRlPSIrSC5FaihnKSwicmVzcG9uc2VUZXh0PSIrQy5DdC5PQihhLnJlc3BvbnNlVGV4dCxudWxsKSwi
+cmVzcG9uc2VUeXBlPSIrQy5DdC5PQihhLnJlc3BvbnNlVHlwZSxudWxsKSwicmVzcG9uc2VVcmw9IitD
+LkN0Lk9CKGEucmVzcG9uc2VVUkwsbnVsbCksInN0YXR1cz0iK0guRWooYS5zdGF0dXMpLCJzdGF0dXNU
+ZXh0PSIrQy5DdC5PQihhLnN0YXR1c1RleHQsbnVsbCldLHQuaSksdC5lcS5hKG5ldyBMLlRtKCkpLHQu
+ZlApLmsoMCwiLCAiKQp0aHJvdyBILmIoUC5UbCgiRXJyb3IgcmVhY2hpbmcgbWlncmF0aW9uIHByZXZp
+ZXcgc2VydmVyOiAiK0guRWoobCksbSkpfXM9NgpicmVhawpjYXNlIDM6cz0yCmJyZWFrCmNhc2UgNjpp
+ZihhLnN0YXR1cz09PTQwMSl0aHJvdyBILmIoTC5URygiVW5hdXRob3JpemVkIHJlc3BvbnNlIGZyb20g
+bWlncmF0aW9uIHByZXZpZXcgc2VydmVyIiwiVGhlIG1pZ3JhdGlvbiBwcmV2aWV3IHNlcnZlciBoYXMg
+ZGV0ZWN0ZWQgYSBtaXNtYXRjaCBiZXR3ZWVuIHRoZSBhdXRoVG9rZW4gaW5cbnlvdXIgVVJMIGFuZCB0
+aGUgdG9rZW4gdGhhdCB3YXMgZ2VuZXJhdGVkIGF0IHRoZSB0aW1lIHRoYXQgYGRhcnQgbWlncmF0ZWAg
+d2FzXG5ydW4uICBIYXZlIHlvdSByZXN0YXJ0ZWQgdGhlIG1pZ3JhdGlvbiBzZXJ2ZXIgcmVjZW50bHk/
+ICBJZiBzbywgeW91J2xsIG5lZWQgdG9cbmNoZWNrIGl0cyBvdXRwdXQgZm9yIGEgZnJlc2ggVVJMLCBh
+bmQgdXNlIHRoYXQgVVJMIHRvIHBlcmZvcm0geW91ciBtaWdyYXRpb24uXG4iKSkKaT1DLkN0LnBXKDAs
+YS5yZXNwb25zZVRleHQsbnVsbCkKaWYoYS5zdGF0dXM9PT0yMDApe3E9Yy5DKCIwKiIpLmEoaSkKcz0x
+CmJyZWFrfWVsc2UgdGhyb3cgSC5iKGkpCmNhc2UgMTpyZXR1cm4gUC55QyhxLHIpCmNhc2UgMjpyZXR1
+cm4gUC5mMyhvLHIpfX0pCnJldHVybiBQLkRJKCRhc3luYyRMVSxyKX0sCmFLOmZ1bmN0aW9uKGEpe3Zh
+ciBzPVAuaEsoYSkuZ2hZKCkucSgwLCJsaW5lIikKcmV0dXJuIHM9PW51bGw/bnVsbDpILkhwKHMsbnVs
+bCl9LApHNjpmdW5jdGlvbihhKXt2YXIgcz1QLmhLKGEpLmdoWSgpLnEoMCwib2Zmc2V0IikKcmV0dXJu
+IHM9PW51bGw/bnVsbDpILkhwKHMsbnVsbCl9LAppNjpmdW5jdGlvbihhKXtyZXR1cm4gTC5uVyh0Lk8u
+YShhKSl9LApuVzpmdW5jdGlvbihhKXt2YXIgcz0wLHI9UC5GWCh0LnopLHE9MSxwLG89W10sbixtLGws
+ayxqLGksaAp2YXIgJGFzeW5jJGk2PVAubHooZnVuY3Rpb24oYixjKXtpZihiPT09MSl7cD1jCnM9cX13
+aGlsZSh0cnVlKXN3aXRjaChzKXtjYXNlIDA6aT10LmcuYShXLnFjKGEuY3VycmVudFRhcmdldCkpLmdl
+dEF0dHJpYnV0ZSgiaHJlZiIpCmEucHJldmVudERlZmF1bHQoKQpxPTMKaz1kb2N1bWVudApuPUMuQ0Qu
+elEoay5xdWVyeVNlbGVjdG9yKCIuY29udGVudCIpLnNjcm9sbFRvcCkKcz02CnJldHVybiBQLmpRKEwu
+dHkoaSxudWxsKSwkYXN5bmMkaTYpCmNhc2UgNjpzPTcKcmV0dXJuIFAualEoTC5HNyh3aW5kb3cubG9j
+YXRpb24ucGF0aG5hbWUsbnVsbCxudWxsLCExLG51bGwpLCRhc3luYyRpNikKY2FzZSA3OmsuYm9keS5j
+bGFzc0xpc3QuYWRkKCJuZWVkcy1yZXJ1biIpCms9ay5xdWVyeVNlbGVjdG9yKCIuY29udGVudCIpCmsu
+dG9TdHJpbmcKay5zY3JvbGxUb3A9Si5WdShuKQpxPTEKcz01CmJyZWFrCmNhc2UgMzpxPTIKaD1wCm09
+SC5SdShoKQpsPUgudHMoaCkKTC5DMigiY291bGRuJ3QgYWRkL3JlbW92ZSBoaW50IixtLGwpCnM9NQpi
+cmVhawpjYXNlIDI6cz0xCmJyZWFrCmNhc2UgNTpyZXR1cm4gUC55QyhudWxsLHIpCmNhc2UgMTpyZXR1
+cm4gUC5mMyhwLHIpfX0pCnJldHVybiBQLkRJKCRhc3luYyRpNixyKX0sCkMyOmZ1bmN0aW9uKGEsYixj
+KXt2YXIgcyxyLHEscCxvLG49ImV4Y2VwdGlvbiIsbT0ic3RhY2tUcmFjZSIKaWYodC50LmIoYikmJkou
+Uk0oYi5xKDAsInN1Y2Nlc3MiKSwhMSkmJmIueDQobikmJmIueDQobSkpe3M9Si5VNihiKQpyPUguaChz
+LnEoYixuKSkKYz1zLnEoYixtKQpxPW51bGx9ZWxzZSBpZihiIGluc3RhbmNlb2YgTC5RVyl7cj1iLmEK
+cT1iLmJ9ZWxzZXtyPUouaihiKQpxPW51bGx9aWYocT09bnVsbClxPWMKcz1kb2N1bWVudApwPXMucXVl
+cnlTZWxlY3RvcigiLnBvcHVwLXBhbmUiKQpwLnF1ZXJ5U2VsZWN0b3IoImgyIikuaW5uZXJUZXh0PWEK
+cC5xdWVyeVNlbGVjdG9yKCJwIikuaW5uZXJUZXh0PXIKcC5xdWVyeVNlbGVjdG9yKCJwcmUiKS5pbm5l
+clRleHQ9Si5qKHEpCm89dC5kZC5hKHAucXVlcnlTZWxlY3RvcigiYS5ib3R0b20iKSk7KG8mJkMueG4p
+LnNMVShvLFAuWGQoImh0dHBzIiwiZ2l0aHViLmNvbSIsImRhcnQtbGFuZy9zZGsvaXNzdWVzL25ldyIs
+UC5FRihbInRpdGxlIiwiQ3VzdG9tZXItcmVwb3J0ZWQgaXNzdWUgd2l0aCBOTkJEIG1pZ3JhdGlvbiB0
+b29sOiAiK2EsImxhYmVscyIsdS5kLCJib2R5IixhKyJcblxuRXJyb3I6ICIrSC5FaihyKSsiXG5cblBs
+ZWFzZSBmaWxsIGluIHRoZSBmb2xsb3dpbmc6XG5cbioqTmFtZSBvZiBwYWNrYWdlIGJlaW5nIG1pZ3Jh
+dGVkIChpZiBwdWJsaWMpKio6XG4qKldoYXQgSSB3YXMgZG9pbmcgd2hlbiB0aGlzIGlzc3VlIG9jY3Vy
+cmVkKio6XG4qKklzIGl0IHBvc3NpYmxlIHRvIHdvcmsgYXJvdW5kIHRoaXMgaXNzdWUqKjpcbioqSGFz
+IHRoaXMgaXNzdWUgaGFwcGVuZWQgYmVmb3JlLCBhbmQgaWYgc28sIGhvdyBvZnRlbioqOlxuKipEYXJ0
+IFNESyB2ZXJzaW9uKio6ICIrSC5FaihzLmdldEVsZW1lbnRCeUlkKCJzZGstdmVyc2lvbiIpLnRleHRD
+b250ZW50KSsiXG4qKkFkZGl0aW9uYWwgZGV0YWlscyoqOlxuXG5UaGFua3MgZm9yIGZpbGluZyFcblxu
+U3RhY2t0cmFjZTogX2F1dG8gcG9wdWxhdGVkIGJ5IG1pZ3JhdGlvbiBwcmV2aWV3IHRvb2wuX1xuXG5g
+YGBcbiIrSC5FaihjKSsiXG5gYGBcbiJdLHQuWCx0LnopKS5nbkQoKSkKcz1vLnN0eWxlCnMuZGlzcGxh
+eT0iaW5pdGlhbCIKcz1wLnN0eWxlCnMuZGlzcGxheT0iaW5pdGlhbCIKcz1hKyI6ICIrSC5FaihiKQp3
+aW5kb3cKaWYodHlwZW9mIGNvbnNvbGUhPSJ1bmRlZmluZWQiKXdpbmRvdy5jb25zb2xlLmVycm9yKHMp
+CndpbmRvdwpzPUguRWooYykKaWYodHlwZW9mIGNvbnNvbGUhPSJ1bmRlZmluZWQiKXdpbmRvdy5jb25z
+b2xlLmVycm9yKHMpfSwKdDI6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEscCxvPXQuZy5hKFcucWMoYS5j
+dXJyZW50VGFyZ2V0KSkKYS5wcmV2ZW50RGVmYXVsdCgpCnM9by5nZXRBdHRyaWJ1dGUoImhyZWYiKQpy
+PUwuVXMocykKcT1MLkc2KHMpCnA9TC5hSyhzKQppZihxIT1udWxsKUwuYWYocixxLHAsYixuZXcgTC5u
+VChyLHEscCkpCmVsc2UgTC5hZihyLG51bGwsbnVsbCxiLG5ldyBMLk5ZKHIpKX0sCkswOmZ1bmN0aW9u
+KGEpe3ZhciBzLHIscSxwPWRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoIi5wb3B1cC1wYW5lIikKcC5xdWVy
+eVNlbGVjdG9yKCJoMiIpLmlubmVyVGV4dD0iRmFpbGVkIHRvIHJlcnVuIGZyb20gc291cmNlcyIKcC5x
+dWVyeVNlbGVjdG9yKCJwIikuaW5uZXJUZXh0PSJTb3VyY2VzIGNvbnRhaW4gc3RhdGljIGFuYWx5c2lz
+IGVycm9yczoiCnM9cC5xdWVyeVNlbGVjdG9yKCJwcmUiKQpyPUouRWwoYSx0LmF3KQpxPUguTGgocikK
+cy5pbm5lclRleHQ9bmV3IEgubEoocixxLkMoInFVKihsRC5FKSIpLmEobmV3IEwudWUoKSkscS5DKCJs
+SjxsRC5FLHFVKj4iKSkuaygwLCJcbiIpCnE9cC5xdWVyeVNlbGVjdG9yKCJhLmJvdHRvbSIpLnN0eWxl
+CnEuZGlzcGxheT0ibm9uZSIKcz1wLnN0eWxlCnMuZGlzcGxheT0iaW5pdGlhbCJ9LAp2VTpmdW5jdGlv
+bigpe3ZhciBzPWRvY3VtZW50CkguRGgodC5nLHQuaCwiVCIsInF1ZXJ5U2VsZWN0b3JBbGwiKQpzPW5l
+dyBXLnd6KHMucXVlcnlTZWxlY3RvckFsbCgiLmNvZGUiKSx0LlIpCnMuSyhzLG5ldyBMLmVYKCkpfSwK
+aFg6ZnVuY3Rpb24oYSxiLGMpe3JldHVybiBMLll3KGEsYixjKX0sCll3OmZ1bmN0aW9uKGEsYixjKXt2
+YXIgcz0wLHI9UC5GWCh0LnopLHE9MSxwLG89W10sbixtLGwsayxqLGksaCxnCnZhciAkYXN5bmMkaFg9
+UC5seihmdW5jdGlvbihkLGUpe2lmKGQ9PT0xKXtwPWUKcz1xfXdoaWxlKHRydWUpc3dpdGNoKHMpe2Nh
+c2UgMDpxPTMKaj10LlgKcz02CnJldHVybiBQLmpRKEwuUTYoYSxQLkVGKFsicmVnaW9uIiwicmVnaW9u
+Iiwib2Zmc2V0IixILkVqKGIpXSxqLGopLHQudCksJGFzeW5jJGhYKQpjYXNlIDY6bj1lCmo9bgppPUou
+VTYoaikKbT1uZXcgVS5kMihVLmpmKGkucShqLCJlZGl0cyIpKSxILmgoaS5xKGosImV4cGxhbmF0aW9u
+IikpLEgudVAoaS5xKGosImxpbmUiKSksSC5oKGkucShqLCJkaXNwbGF5UGF0aCIpKSxILmgoaS5xKGos
+InVyaVBhdGgiKSksVS5OZChpLnEoaiwidHJhY2VzIikpKQpMLlQxKG0pCkwuRnIoYSxiLGMpCkwueVgo
+Ii5lZGl0LXBhbmVsIC5wYW5lbC1jb250ZW50IiwhMSkKcT0xCnM9NQpicmVhawpjYXNlIDM6cT0yCmc9
+cApsPUguUnUoZykKaz1ILnRzKGcpCkwuQzIoImNvdWxkbid0IGxvYWQgZWRpdCBkZXRhaWxzIixsLGsp
+CnM9NQpicmVhawpjYXNlIDI6cz0xCmJyZWFrCmNhc2UgNTpyZXR1cm4gUC55QyhudWxsLHIpCmNhc2Ug
+MTpyZXR1cm4gUC5mMyhwLHIpfX0pCnJldHVybiBQLkRJKCRhc3luYyRoWCxyKX0sCkc3OmZ1bmN0aW9u
+KGEsYixjLGQsZSl7cmV0dXJuIEwuTDUoYSxiLGMsZCxlKX0sCkw1OmZ1bmN0aW9uKGEsYixjLGQsZSl7
+dmFyIHM9MCxyPVAuRlgodC5IKSxxLHA9MixvLG49W10sbSxsLGssaixpLGgsZwp2YXIgJGFzeW5jJEc3
+PVAubHooZnVuY3Rpb24oZixhMCl7aWYoZj09PTEpe289YTAKcz1wfXdoaWxlKHRydWUpc3dpdGNoKHMp
+e2Nhc2UgMDppZighSi5wNChhLCIuZGFydCIpKXtMLkJFKGEsQi53UigpLGQpCkwuQlgoYSxudWxsKQpp
+ZihlIT1udWxsKWUuJDAoKQpzPTEKYnJlYWt9cD00Cmk9dC5YCnM9NwpyZXR1cm4gUC5qUShMLlE2KGEs
+UC5FRihbImlubGluZSIsInRydWUiXSxpLGkpLHQudCksJGFzeW5jJEc3KQpjYXNlIDc6bT1hMApMLkJF
+KGEsQi5ZZihtKSxkKQpMLmZHKGIsYykKbD1MLlVzKGEpCkwuQlgobCxiKQppZihlIT1udWxsKWUuJDAo
+KQpwPTIKcz02CmJyZWFrCmNhc2UgNDpwPTMKZz1vCms9SC5SdShnKQpqPUgudHMoZykKTC5DMigiY291
+bGRuJ3QgbG9hZCBkYXJ0IGZpbGUgIithLGssaikKcz02CmJyZWFrCmNhc2UgMzpzPTIKYnJlYWsKY2Fz
+ZSA2OmNhc2UgMTpyZXR1cm4gUC55QyhxLHIpCmNhc2UgMjpyZXR1cm4gUC5mMyhvLHIpfX0pCnJldHVy
+biBQLkRJKCRhc3luYyRHNyxyKX0sCkdlOmZ1bmN0aW9uKCl7dmFyIHM9MCxyPVAuRlgodC56KSxxPTEs
+cCxvPVtdLG4sbSxsLGssaixpLGgsZwp2YXIgJGFzeW5jJEdlPVAubHooZnVuY3Rpb24oYSxiKXtpZihh
+PT09MSl7cD1iCnM9cX13aGlsZSh0cnVlKXN3aXRjaChzKXtjYXNlIDA6aD0iL19wcmV2aWV3L25hdmln
+YXRpb25UcmVlLmpzb24iCnE9MwpzPTYKcmV0dXJuIFAualEoTC5RNihoLEMuQ00sdC5lRSksJGFzeW5j
+JEdlKQpjYXNlIDY6bj1iCm09ZG9jdW1lbnQucXVlcnlTZWxlY3RvcigiLm5hdi10cmVlIikKSi5sNSht
+LCIiKQpqPUwubUsobikKJC5JUj1qCkwudFgobSxqLCEwKQpxPTEKcz01CmJyZWFrCmNhc2UgMzpxPTIK
+Zz1wCmw9SC5SdShnKQprPUgudHMoZykKTC5DMigiY291bGRuJ3QgbG9hZCBuYXZpZ2F0aW9uIHRyZWUi
+LGwsaykKcz01CmJyZWFrCmNhc2UgMjpzPTEKYnJlYWsKY2FzZSA1OnJldHVybiBQLnlDKG51bGwscikK
+Y2FzZSAxOnJldHVybiBQLmYzKHAscil9fSkKcmV0dXJuIFAuREkoJGFzeW5jJEdlLHIpfSwKcU86ZnVu
+Y3Rpb24oYSl7dmFyIHMscj1hLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLHE9Qy5DRC56USgkLmZpKCku
+b2Zmc2V0SGVpZ2h0KSxwPXdpbmRvdy5pbm5lckhlaWdodCxvPUMuQ0QuelEoJC5EVygpLm9mZnNldEhl
+aWdodCkKaWYodHlwZW9mIHAhPT0ibnVtYmVyIilyZXR1cm4gcC5ITigpCnM9ci5ib3R0b20Kcy50b1N0
+cmluZwppZihzPnAtKG8rMTQpKUouZGgoYSkKZWxzZXtwPXIudG9wCnAudG9TdHJpbmcKaWYocDxxKzE0
+KUouZGgoYSl9fSwKZkc6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEscCxvCmlmKGEhPW51bGwpe3M9ZG9j
+dW1lbnQKcj1zLmdldEVsZW1lbnRCeUlkKCJvIitILkVqKGEpKQpxPXMucXVlcnlTZWxlY3RvcigiLmxp
+bmUtIitILkVqKGIpKQppZihyIT1udWxsKXtMLnFPKHIpCkouZFIocikuaSgwLCJ0YXJnZXQiKX1lbHNl
+IGlmKHEhPW51bGwpTC5xTyhxLnBhcmVudEVsZW1lbnQpCmlmKHEhPW51bGwpSi5kUih0LmcuYShxLnBh
+cmVudE5vZGUpKS5pKDAsImhpZ2hsaWdodCIpfWVsc2V7cz1kb2N1bWVudApwPXQuZwpILkRoKHAsdC5o
+LCJUIiwicXVlcnlTZWxlY3RvckFsbCIpCnM9cy5xdWVyeVNlbGVjdG9yQWxsKCIubGluZS1ubyIpCm89
+bmV3IFcud3oocyx0LlIpCmlmKG8uZ0Eobyk9PT0wKXJldHVybgpMLnFPKHAuYShDLnQ1Lmd0SChzKSkp
+fX0sCmFmOmZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIHMscixxPUwuRzYod2luZG93LmxvY2F0aW9uLmhy
+ZWYpLHA9TC5hSyh3aW5kb3cubG9jYXRpb24uaHJlZikKaWYocSE9bnVsbCl7cz1kb2N1bWVudC5nZXRF
+bGVtZW50QnlJZCgibyIrSC5FaihxKSkKaWYocyE9bnVsbClKLmRSKHMpLlIoMCwidGFyZ2V0Iil9aWYo
+cCE9bnVsbCl7cj1kb2N1bWVudC5xdWVyeVNlbGVjdG9yKCIubGluZS0iK0guRWoocCkpCmlmKHIhPW51
+bGwpSi5kUihyLnBhcmVudEVsZW1lbnQpLlIoMCwiaGlnaGxpZ2h0Iil9aWYoYT09d2luZG93LmxvY2F0
+aW9uLnBhdGhuYW1lKXtMLmZHKGIsYykKZS4kMCgpfWVsc2UgTC5HNyhhLGIsYyxkLGUpfSwKUTQ6ZnVu
+Y3Rpb24oYSxiKXt2YXIgcyxyLHE9UC5oSyhhKSxwPXQuWApwPVAuRmwocCxwKQpmb3Iocz1xLmdoWSgp
+LHM9cy5nUHUocykscz1zLmdtKHMpO3MuRigpOyl7cj1zLmdsKCkKcC5ZNSgwLHIuYSxyLmIpfWZvcihz
+PWIuZ1B1KGIpLHM9cy5nbShzKTtzLkYoKTspe3I9cy5nbCgpCnAuWTUoMCxyLmEsci5iKX1wLlk1KDAs
+ImF1dGhUb2tlbiIsJC5VRSgpKQpyZXR1cm4gcS5ubSgwLHApLmduRCgpfSwKVDE6ZnVuY3Rpb24oYSl7
+dmFyIHMscixxLHAsbyxuLG0sbCxrLGo9JC5oTCgpCkoubDUoaiwiIikKaWYoYT09bnVsbCl7cz1kb2N1
+bWVudC5jcmVhdGVFbGVtZW50KCJwIikKQy5MdC5zYTQocywiU2VlIGRldGFpbHMgYWJvdXQgYSBwcm9w
+b3NlZCBlZGl0LiIpCkMuTHQuc1AocyxILlZNKFsicGxhY2Vob2xkZXIiXSx0LmkpKQpqLmFwcGVuZENo
+aWxkKHMpCkMuTHQuRkYocykKcmV0dXJufXI9YS5kCnE9JC5uVSgpCnA9cS56ZihyKQpvPWEuYgpuPWRv
+Y3VtZW50Cm09cS5IUChyLEouVDAobi5xdWVyeVNlbGVjdG9yKCIucm9vdCIpLnRleHRDb250ZW50KSkK
+bD1hLmMKaz1uLmNyZWF0ZUVsZW1lbnQoInAiKQpqLmFwcGVuZENoaWxkKGspCmsuYXBwZW5kQ2hpbGQo
+bi5jcmVhdGVUZXh0Tm9kZShILkVqKG8pKyIgYXQgIikpCnE9dC5YCnE9Vy5KNihMLlE0KGEuZSxQLkVG
+KFsibGluZSIsSi5qKGwpXSxxLHEpKSkKcS5hcHBlbmRDaGlsZChuLmNyZWF0ZVRleHROb2RlKEguRWoo
+bSkrIjoiK0guRWoobCkrIi4iKSkKay5hcHBlbmRDaGlsZChxKQpKLmRoKGspCkwuQ0MoYSxqLHApCkwu
+RnooYSxqKX0sCkxIOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyLHEscCxvLG4sbSxsLGssaixpLGgsZyxm
+LGU9JC55UCgpCkoubDUoZSwiIikKaWYoYi5nQShiKT09PTApe3M9ZG9jdW1lbnQKcj1zLmNyZWF0ZUVs
+ZW1lbnQoInAiKQplLmFwcGVuZENoaWxkKHIpCnIuYXBwZW5kQ2hpbGQocy5jcmVhdGVUZXh0Tm9kZSgi
+Tm8gcHJvcG9zZWQgZWRpdHMiKSl9ZWxzZSBmb3IoZT1iLmdQdShiKSxlPWUuZ20oZSkscz10LlgscT10
+LmsscD1xLkMoIn4oMSk/Iiksbz10LloscT1xLmM7ZS5GKCk7KXtuPWUuZ2woKQptPWRvY3VtZW50CnI9
+bS5jcmVhdGVFbGVtZW50KCJwIikKbD0kLnlQKCkKbC5hcHBlbmRDaGlsZChyKQpyLmFwcGVuZENoaWxk
+KG0uY3JlYXRlVGV4dE5vZGUoSC5FaihuLmEpKyI6IikpCms9bS5jcmVhdGVFbGVtZW50KCJ1bCIpCmwu
+YXBwZW5kQ2hpbGQoaykKZm9yKG49Si5JVChuLmIpO24uRigpOyl7bD1uLmdsKCkKaj1tLmNyZWF0ZUVs
+ZW1lbnQoImxpIikKay5hcHBlbmRDaGlsZChqKQpKLmRSKGopLmkoMCwiZWRpdCIpCmk9bS5jcmVhdGVF
+bGVtZW50KCJhIikKai5hcHBlbmRDaGlsZChpKQppLmNsYXNzTGlzdC5hZGQoImVkaXQtbGluayIpCmg9
+bC5jCmc9SC5FaihoKQppLnNldEF0dHJpYnV0ZSgiZGF0YS0iK25ldyBXLlN5KG5ldyBXLmk3KGkpKS5P
+VSgib2Zmc2V0IiksZykKZj1sLmEKZz1ILkVqKGYpCmkuc2V0QXR0cmlidXRlKCJkYXRhLSIrbmV3IFcu
+U3kobmV3IFcuaTcoaSkpLk9VKCJsaW5lIiksZykKaS5hcHBlbmRDaGlsZChtLmNyZWF0ZVRleHROb2Rl
+KCJsaW5lICIrSC5FaihmKSkpCmkuc2V0QXR0cmlidXRlKCJocmVmIixMLlE0KHdpbmRvdy5sb2NhdGlv
+bi5wYXRobmFtZSxQLkVGKFsibGluZSIsSC5FaihmKSwib2Zmc2V0IixILkVqKGgpXSxzLHMpKSkKZz1w
+LmEobmV3IEwuRUUoaCxmLGEpKQpvLmEobnVsbCkKVy5KRShpLCJjbGljayIsZywhMSxxKQpqLmFwcGVu
+ZENoaWxkKG0uY3JlYXRlVGV4dE5vZGUoIjogIitILkVqKGwuYikpKX19aWYoYylMLlQxKG51bGwpfSwK
+RnI6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzLHIscT13aW5kb3cubG9jYXRpb24scD1QLmhLKChxJiZDLkV4
+KS5nRHIocSkrSC5FaihhKSkKcT10LlgKcT1QLkZsKHEscSkKaWYoYiE9bnVsbClxLlk1KDAsIm9mZnNl
+dCIsSC5FaihiKSkKaWYoYyE9bnVsbClxLlk1KDAsImxpbmUiLEguRWooYykpCnEuWTUoMCwiYXV0aFRv
+a2VuIiwkLlVFKCkpCnA9cC5ubSgwLHEpCnE9d2luZG93Lmhpc3RvcnkKcz10LnoKcj1wLmduRCgpCnEu
+dG9TdHJpbmcKcS5wdXNoU3RhdGUobmV3IFAuQmYoW10sW10pLlB2KFAuRmwocyxzKSksIiIscil9LApF
+bjpmdW5jdGlvbihhKXt2YXIgcz1KLmJiKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoIi5yb290IikudGV4
+dENvbnRlbnQsIi8iKQppZihDLnhCLm5DKGEscykpcmV0dXJuIEMueEIueW4oYSxzLmxlbmd0aCkKZWxz
+ZSByZXR1cm4gYX0sCk90OmZ1bmN0aW9uKGEpe3N3aXRjaChhLnIpe2Nhc2UgQy5jdzpicmVhawpjYXNl
+IEMuV0Q6YS5yPUMuWGoKYnJlYWsKY2FzZSBDLlhqOmEucj1DLldECmJyZWFrCmNhc2UgQy5kYzp0aHJv
+dyBILmIoUC5QVigiRmlsZSAiK0guRWooYS5jKSsiIHNob3VsZCBub3QgaGF2ZSBpbmRldGVybWluYXRl
+IG1pZ3JhdGlvbiBzdGF0dXMiKSl9fSwKdGE6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyPSJjaGVja19ib3gi
+LHE9InRpdGxlIixwPSJvcHRlZC1vdXQiLG89Im1pZ3JhdGluZyIKc3dpdGNoKGIpe2Nhc2UgQy5jdzph
+LmlubmVyVGV4dD1yCnM9Si5ZRShhKQpzLmdQKGEpLmkoMCwiYWxyZWFkeS1taWdyYXRlZCIpCnMuZ1Ao
+YSkuaSgwLCJkaXNhYmxlZCIpCmEuc2V0QXR0cmlidXRlKHEsIkFscmVhZHkgbWlncmF0ZWQiKQpicmVh
+awpjYXNlIEMuV0Q6YS5pbm5lclRleHQ9cgpzPUouWUUoYSkKcy5nUChhKS5SKDAscCkKcy5nUChhKS5p
+KDAsbykKYS5zZXRBdHRyaWJ1dGUocSwiTWlncmF0aW5nIHRvIG51bGwgc2FmZXR5IikKYnJlYWsKY2Fz
+ZSBDLlhqOmEuaW5uZXJUZXh0PSJjaGVja19ib3hfb3V0bGluZV9ibGFuayIKcz1KLllFKGEpCnMuZ1Ao
+YSkuUigwLG8pCnMuZ1AoYSkuaSgwLHApCmEuc2V0QXR0cmlidXRlKHEsIk9wdGluZyBvdXQgb2YgbnVs
+bCBzYWZldHkiKQpicmVhawpkZWZhdWx0OmEuaW5uZXJUZXh0PSJpbmRldGVybWluYXRlX2NoZWNrX2Jv
+eCIKcz1KLllFKGEpCnMuZ1AoYSkuUigwLG8pCnMuZ1AoYSkuaSgwLHApCmEuc2V0QXR0cmlidXRlKHEs
+Ik1peGVkIHN0YXR1c2VzIG9mICdtaWdyYXRpbmcnIGFuZCAnb3B0aW5nIG91dCciKQpicmVha319LAp4
+bjpmdW5jdGlvbihhLGIpe3ZhciBzLHIscT0iZGlzYWJsZWQiLHA9Yi5nTCgpCkwudGEoYSxwKQppZihi
+LmM9PSQuRDkoKS5pbm5lclRleHQpe3M9YiBpbnN0YW5jZW9mIEwuY0QmJiFILm9UKGIueCkKcj1KLllF
+KGEpCmlmKHMpci5nUChhKS5pKDAscSkKZWxzZSByLmdQKGEpLlIoMCxxKQpMLnRhKCQuYzAoKSxwKX19
+LApCWDpmdW5jdGlvbihhLGIpe3ZhciBzLHIscT17fQpxLmE9YQphPUwuRW4oYSkKcS5hPWEKSi5kcigk
+LkQ5KCksYSkKcz1kb2N1bWVudApILkRoKHQuZyx0LmgsIlQiLCJxdWVyeVNlbGVjdG9yQWxsIikKcz1u
+ZXcgVy53eihzLnF1ZXJ5U2VsZWN0b3JBbGwoIi5uYXYtcGFuZWwgLm5hdi1saW5rIiksdC5SKQpzLkso
+cyxuZXcgTC5WUyhxKSkKcz0kLklSCnI9cz09bnVsbD9udWxsOkwueXcocyxxLmEpCmlmKHI9PW51bGwp
+Si5kUigkLmJOKCkpLlIoMCwidmlzaWJsZSIpCmVsc2V7Si5kUigkLmJOKCkpLmkoMCwidmlzaWJsZSIp
+CkwudGEoJC5jMCgpLHIuZ0woKSl9fSwKQVI6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHE9Yi5iCmlmKHEh
+PW51bGwpe3M9dC5nCnI9cy5hKHMuYShhLnBhcmVudE5vZGUpLnBhcmVudE5vZGUpCkwueG4oci5xdWVy
+eVNlbGVjdG9yKCI6c2NvcGUgPiAuc3RhdHVzLWljb24iKSxxKQpMLkFSKHIscSl9fSwKaGw6ZnVuY3Rp
+b24oYSxiKXt2YXIgcyxyLHEscCxvLG4sbT0iOnNjb3BlID4gLnN0YXR1cy1pY29uIgpmb3Iocz1iLmQs
+cj1zLmxlbmd0aCxxPXQuZyxwPTA7cDxzLmxlbmd0aDtzLmxlbmd0aD09PXJ8fCgwLEgubGspKHMpLCsr
+cCl7bz1zW3BdCm49YS5xdWVyeVNlbGVjdG9yKCdbZGF0YS1uYW1lKj0iJytILkVqKFcuTGooby5jKSkr
+JyJdJykKaWYobyBpbnN0YW5jZW9mIEwudnQpe0wuaGwobixvKQpMLnhuKG4ucXVlcnlTZWxlY3Rvciht
+KSxiKX1lbHNlIEwueG4ocS5hKG4ucGFyZW50Tm9kZSkucXVlcnlTZWxlY3RvcihtKSxvKX19LApCRTpm
+dW5jdGlvbihhLGIsYyl7dmFyIHM9Ii5yZWdpb25zIixyPWRvY3VtZW50LHE9ci5xdWVyeVNlbGVjdG9y
+KHMpLHA9ci5xdWVyeVNlbGVjdG9yKCIuY29kZSIpCkoudEgocSxiLmEsJC5LRygpKQpKLnRIKHAsYi5i
+LCQuS0coKSkKTC5MSChhLGIuZCxjKQppZihiLmMubGVuZ3RoPDJlNSlMLnZVKCkKTC55WCgiLmNvZGUi
+LCEwKQpMLnlYKHMsITApfSwKdFg6ZnVuY3Rpb24oYTEsYTIsYTMpe3ZhciBzLHIscSxwLG8sbixtLGws
+ayxqLGksaCxnLGYsZSxkLGM9Im1hdGVyaWFsLWljb25zIixiPSJzdGF0dXMtaWNvbiIsYT1kb2N1bWVu
+dCxhMD1hLmNyZWF0ZUVsZW1lbnQoInVsIikKYTEuYXBwZW5kQ2hpbGQoYTApCmZvcihzPWEyLmxlbmd0
+aCxyPXQuWCxxPXQuWixwPTA7cDxhMi5sZW5ndGg7YTIubGVuZ3RoPT09c3x8KDAsSC5saykoYTIpLCsr
+cCl7bz1hMltwXQpuPWEuY3JlYXRlRWxlbWVudCgibGkiKQphMC5hcHBlbmRDaGlsZChuKQppZihvIGlu
+c3RhbmNlb2YgTC52dCl7bT1KLllFKG4pCm0uZ1AobikuaSgwLCJkaXIiKQpuLnNldEF0dHJpYnV0ZSgi
+ZGF0YS0iK25ldyBXLlN5KG5ldyBXLmk3KG4pKS5PVSgibmFtZSIpLG8uYykKbD1hLmNyZWF0ZUVsZW1l
+bnQoInNwYW4iKQpuLmFwcGVuZENoaWxkKGwpCms9Si5ZRShsKQprLmdQKGwpLmkoMCwiYXJyb3ciKQpr
+LnNoZihsLCImI3gyNUJDOyIpCmo9YS5jcmVhdGVFbGVtZW50KCJzcGFuIikKSi5kUihqKS5pKDAsYykK
+ai5pbm5lclRleHQ9ImZvbGRlcl9vcGVuIgpuLmFwcGVuZENoaWxkKGopCm4uYXBwZW5kQ2hpbGQoYS5j
+cmVhdGVUZXh0Tm9kZShvLmEpKQpMLnRYKG4sby5kLCEwKQppPWEuY3JlYXRlRWxlbWVudCgic3BhbiIp
+Cms9Si5ZRShpKQprLmdQKGkpLmkoMCxjKQppLmlubmVyVGV4dD0iaW5kZXRlcm1pbmF0ZV9jaGVja19i
+b3giCmsuZ1AoaSkuaSgwLGIpCkwueG4oaSxvKQprPWsuZ1ZsKGkpCmg9ay4kdGkKZz1oLkMoIn4oMSk/
+IikuYShuZXcgTC5URChvLG4saSkpCnEuYShudWxsKQpXLkpFKGsuYSxrLmIsZywhMSxoLmMpCm0ubUso
+bixpLGopCkwua3oobCl9ZWxzZSBpZihvIGluc3RhbmNlb2YgTC5jRCl7aT1hLmNyZWF0ZUVsZW1lbnQo
+InNwYW4iKQptPUouWUUoaSkKbS5nUChpKS5pKDAsYykKaS5pbm5lclRleHQ9IiIKbS5nUChpKS5pKDAs
+YikKaz1ILm9UKG8ueCkKaWYoIWspbS5nUChpKS5pKDAsImRpc2FibGVkIikKTC54bihpLG8pCmlmKGsp
+e209bS5nVmwoaSkKaz1tLiR0aQpoPWsuQygifigxKT8iKS5hKG5ldyBMLklmKG8saSxuKSkKcS5hKG51
+bGwpClcuSkUobS5hLG0uYixoLCExLGsuYyl9bi5hcHBlbmRDaGlsZChpKQptPWEuY3JlYXRlRWxlbWVu
+dCgic3BhbiIpCkouZFIobSkuaSgwLGMpCm0uaW5uZXJUZXh0PSJpbnNlcnRfZHJpdmVfZmlsZSIKbi5h
+cHBlbmRDaGlsZChtKQpmPWEuY3JlYXRlRWxlbWVudCgiYSIpCm4uYXBwZW5kQ2hpbGQoZikKbT1KLllF
+KGYpCm0uZ1AoZikuaSgwLCJuYXYtbGluayIpCmYuc2V0QXR0cmlidXRlKCJkYXRhLSIrbmV3IFcuU3ko
+bmV3IFcuaTcoZikpLk9VKCJuYW1lIiksby5jKQpmLnNldEF0dHJpYnV0ZSgiaHJlZiIsTC5RNChvLmQs
+UC5GbChyLHIpKSkKZi5hcHBlbmRDaGlsZChhLmNyZWF0ZVRleHROb2RlKG8uYSkpCm09bS5nVmwoZikK
+az1tLiR0aQpoPWsuQygifigxKT8iKS5hKG5ldyBMLnRCKCkpCnEuYShudWxsKQpXLkpFKG0uYSxtLmIs
+aCwhMSxrLmMpCmU9by5lCmlmKHR5cGVvZiBlIT09Im51bWJlciIpcmV0dXJuIGUub3MoKQppZihlPjAp
+e2Q9YS5jcmVhdGVFbGVtZW50KCJzcGFuIikKbi5hcHBlbmRDaGlsZChkKQpKLmRSKGQpLmkoMCwiZWRp
+dC1jb3VudCIpCm09IiIrZSsiICIKaWYoZT09PTEpaz0icHJvcG9zZWQgZWRpdCIKZWxzZSBrPSJwcm9w
+b3NlZCBlZGl0cyIKZC5zZXRBdHRyaWJ1dGUoInRpdGxlIixtK2spCmQuYXBwZW5kQ2hpbGQoYS5jcmVh
+dGVUZXh0Tm9kZShDLmpuLncoZSkpKX19fX0sCnV6OmZ1bmN0aW9uKGEsYixjKXt2YXIgcz1kb2N1bWVu
+dCxyPXMuY3JlYXRlRWxlbWVudCgiYnV0dG9uIikscT10LmsscD1xLkMoIn4oMSk/IikuYShuZXcgTC5t
+MihhLGMpKQp0LlouYShudWxsKQpXLkpFKHIsImNsaWNrIixwLCExLHEuYykKci5hcHBlbmRDaGlsZChz
+LmNyZWF0ZVRleHROb2RlKFIuT1goYS5hKSkpCmIuYXBwZW5kQ2hpbGQocil9LApGejpmdW5jdGlvbihh
+LGIpe3ZhciBzLHIscSxwLG8sbixtLGwsayxqLGksaD1hLmEKaWYoaD09bnVsbClyZXR1cm4Kcz1kb2N1
+bWVudApyPXMuY3JlYXRlRWxlbWVudCgicCIpCnE9Yi5hcHBlbmRDaGlsZChyKQpyPXMuY3JlYXRlRWxl
+bWVudCgic3BhbiIpCnA9dC5pCkouTXUocixILlZNKFsidHlwZS1kZXNjcmlwdGlvbiJdLHApKQpyLmFw
+cGVuZENoaWxkKHMuY3JlYXRlVGV4dE5vZGUoIkFjdGlvbnMiKSkKcS5hcHBlbmRDaGlsZChyKQpxLmFw
+cGVuZENoaWxkKHMuY3JlYXRlVGV4dE5vZGUoIjoiKSkKbz1zLmNyZWF0ZUVsZW1lbnQoInAiKQpiLmFw
+cGVuZENoaWxkKG8pCmZvcihyPWgubGVuZ3RoLG49dC5RLG09MDttPGgubGVuZ3RoO2gubGVuZ3RoPT09
+cnx8KDAsSC5saykoaCksKyttKXtsPWhbbV0Kaz1zLmNyZWF0ZUVsZW1lbnQoImEiKQpvLmFwcGVuZENo
+aWxkKGspCmsuYXBwZW5kQ2hpbGQocy5jcmVhdGVUZXh0Tm9kZShsLmEpKQprLnNldEF0dHJpYnV0ZSgi
+aHJlZiIsbC5iKQpqPW4uYShILlZNKFsiYWRkLWhpbnQtbGluayIsImJlZm9yZS1hcHBseSIsImJ1dHRv
+biJdLHApKQppPUouZFIoaykKaS5WMSgwKQppLkZWKDAsail9fSwKQ0M6ZnVuY3Rpb24oYTQsYTUsYTYp
+e3ZhciBzLHIscSxwLG8sbixtLGwsayxqLGksaCxnLGYsZSxkLGMsYixhLGEwLGExLGEyLGEzCmZvcihz
+PWE0LmYscj1zLmxlbmd0aCxxPXQuaSxwPXQuUSxvPTA7bzxzLmxlbmd0aDtzLmxlbmd0aD09PXJ8fCgw
+LEgubGspKHMpLCsrbyl7bj1zW29dCm09ZG9jdW1lbnQKbD1tLmNyZWF0ZUVsZW1lbnQoInAiKQprPXAu
+YShILlZNKFsidHJhY2UiXSxxKSkKaj1KLmRSKGwpCmouVjEoMCkKai5GVigwLGspCmk9YTUuYXBwZW5k
+Q2hpbGQobCkKbD1tLmNyZWF0ZUVsZW1lbnQoInNwYW4iKQprPXAuYShILlZNKFsidHlwZS1kZXNjcmlw
+dGlvbiJdLHEpKQpqPUouZFIobCkKai5WMSgwKQpqLkZWKDAsaykKbC5hcHBlbmRDaGlsZChtLmNyZWF0
+ZVRleHROb2RlKG4uYSkpCmkuYXBwZW5kQ2hpbGQobCkKaS5hcHBlbmRDaGlsZChtLmNyZWF0ZVRleHRO
+b2RlKCI6IikpCmw9bS5jcmVhdGVFbGVtZW50KCJ1bCIpCms9cC5hKEguVk0oWyJ0cmFjZSJdLHEpKQpq
+PUouZFIobCkKai5WMSgwKQpqLkZWKDAsaykKaD1pLmFwcGVuZENoaWxkKGwpCmZvcihsPW4uYixrPWwu
+bGVuZ3RoLGc9MDtnPGwubGVuZ3RoO2wubGVuZ3RoPT09a3x8KDAsSC5saykobCksKytnKXtmPWxbZ10K
+ZT1tLmNyZWF0ZUVsZW1lbnQoImxpIikKaC5hcHBlbmRDaGlsZChlKQpkPW0uY3JlYXRlRWxlbWVudCgi
+c3BhbiIpCmM9cC5hKEguVk0oWyJmdW5jdGlvbiJdLHEpKQpqPUouZFIoZCkKai5WMSgwKQpqLkZWKDAs
+YykKYz1mLmIKTC5XaihkLGM9PW51bGw/InVua25vd24iOmMpCmUuYXBwZW5kQ2hpbGQoZCkKYj1mLmMK
+aWYoYiE9bnVsbCl7ZS5hcHBlbmRDaGlsZChtLmNyZWF0ZVRleHROb2RlKCIgKCIpKQphPWIuYgphMD1t
+LmNyZWF0ZUVsZW1lbnQoImEiKQphMC5hcHBlbmRDaGlsZChtLmNyZWF0ZVRleHROb2RlKEguRWooYi5j
+KSsiOiIrSC5FaihhKSkpCmEwLnNldEF0dHJpYnV0ZSgiaHJlZiIsYi5hKQphMC5jbGFzc0xpc3QuYWRk
+KCJuYXYtbGluayIpCmUuYXBwZW5kQ2hpbGQoYTApCmUuYXBwZW5kQ2hpbGQobS5jcmVhdGVUZXh0Tm9k
+ZSgiKSIpKX1lLmFwcGVuZENoaWxkKG0uY3JlYXRlVGV4dE5vZGUoIjogIikpCmQ9Zi5hCkwuV2ooZSxk
+PT1udWxsPyJ1bmtub3duIjpkKQpkPWYuZAppZihkLmxlbmd0aCE9PTApe2M9bS5jcmVhdGVFbGVtZW50
+KCJwIikKYTE9cC5hKEguVk0oWyJkcmF3ZXIiLCJiZWZvcmUtYXBwbHkiXSxxKSkKaj1KLmRSKGMpCmou
+VjEoMCkKai5GVigwLGExKQphMj1lLmFwcGVuZENoaWxkKGMpCmZvcihjPWQubGVuZ3RoLGEzPTA7YTM8
+ZC5sZW5ndGg7ZC5sZW5ndGg9PT1jfHwoMCxILmxrKShkKSwrK2EzKUwudXooZFthM10sYTIsYil9fX19
+LApVczpmdW5jdGlvbihhKXtyZXR1cm4gSi56bChhLCI/Iik/Qy54Qi5OaihhLDAsQy54Qi5PWShhLCI/
+IikpOmF9LApURzpmdW5jdGlvbihhLGIpe3JldHVybiBuZXcgTC5RVyhhLGIpfSwKeXc6ZnVuY3Rpb24o
+YSxiKXt2YXIgcyxyLHEscApmb3Iocz1hLmxlbmd0aCxyPTA7cjxhLmxlbmd0aDthLmxlbmd0aD09PXN8
+fCgwLEgubGspKGEpLCsrcil7cT1hW3JdCmlmKHEgaW5zdGFuY2VvZiBMLnZ0KXtwPUwueXcocS5kLGIp
+CmlmKHAhPW51bGwpcmV0dXJuIHB9ZWxzZSBpZihxLmM9PWIpcmV0dXJuIHF9cmV0dXJuIG51bGx9LApX
+ajpmdW5jdGlvbihhLGIpe3ZhciBzLHIscT1ILlZNKGIuc3BsaXQoIi4iKSx0LnMpLHA9Qy5ObS5ndEgo
+cSksbz1kb2N1bWVudAphLmFwcGVuZENoaWxkKG8uY3JlYXRlVGV4dE5vZGUocCkpCmZvcihwPUgucUMo
+cSwxLG51bGwsdC5OKSxwPW5ldyBILmE3KHAscC5nQShwKSxwLiR0aS5DKCJhNzxhTC5FPiIpKSxzPUou
+WUUoYSk7cC5GKCk7KXtyPXAuZApzLm56KGEsImJlZm9yZWVuZCIsIiYjODIwMzsuIixudWxsLG51bGwp
+CmEuYXBwZW5kQ2hpbGQoby5jcmVhdGVUZXh0Tm9kZShyKSl9fSwKZTpmdW5jdGlvbiBlKCl7fSwKVlc6
+ZnVuY3Rpb24gVlcoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKb1o6ZnVuY3Rpb24g
+b1ooKXt9LApqcjpmdW5jdGlvbiBqcigpe30sCnFsOmZ1bmN0aW9uIHFsKCl7fSwKSGk6ZnVuY3Rpb24g
+SGkoKXt9LApCVDpmdW5jdGlvbiBCVCgpe30sClBZOmZ1bmN0aW9uIFBZKCl7fSwKdTg6ZnVuY3Rpb24g
+dTgoKXt9LApMOmZ1bmN0aW9uIEwoKXt9LApXeDpmdW5jdGlvbiBXeChhLGIpe3RoaXMuYT1hCnRoaXMu
+Yj1ifSwKQU86ZnVuY3Rpb24gQU8oYSl7dGhpcy5hPWF9LApkTjpmdW5jdGlvbiBkTihhKXt0aGlzLmE9
+YX0sCkhvOmZ1bmN0aW9uIEhvKGEpe3RoaXMuYT1hfSwKeHo6ZnVuY3Rpb24geHooYSxiKXt0aGlzLmE9
+YQp0aGlzLmI9Yn0sCklDOmZ1bmN0aW9uIElDKCl7fSwKZkM6ZnVuY3Rpb24gZkMoYSxiKXt0aGlzLmE9
+YQp0aGlzLmI9Yn0sClRtOmZ1bmN0aW9uIFRtKCl7fSwKblQ6ZnVuY3Rpb24gblQoYSxiLGMpe3RoaXMu
+YT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKTlk6ZnVuY3Rpb24gTlkoYSl7dGhpcy5hPWF9LAp1ZTpmdW5j
+dGlvbiB1ZSgpe30sCmVYOmZ1bmN0aW9uIGVYKCl7fSwKRUU6ZnVuY3Rpb24gRUUoYSxiLGMpe3RoaXMu
+YT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKUUw6ZnVuY3Rpb24gUUwoYSxiKXt0aGlzLmE9YQp0aGlzLmI9
+Yn0sClZTOmZ1bmN0aW9uIFZTKGEpe3RoaXMuYT1hfSwKVEQ6ZnVuY3Rpb24gVEQoYSxiLGMpe3RoaXMu
+YT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKSWY6ZnVuY3Rpb24gSWYoYSxiLGMpe3RoaXMuYT1hCnRoaXMu
+Yj1iCnRoaXMuYz1jfSwKdEI6ZnVuY3Rpb24gdEIoKXt9LAptMjpmdW5jdGlvbiBtMihhLGIpe3RoaXMu
+YT1hCnRoaXMuYj1ifSwKUVc6ZnVuY3Rpb24gUVcoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sClhBOmZ1
+bmN0aW9uIFhBKCl7fSwKWnM6ZnVuY3Rpb24oYSl7dmFyIHMscixxPUouVTYoYSkKaWYoTC5wMihILmgo
+cS5xKGEsInR5cGUiKSkpPT09Qy5ZMil7cz1ILmgocS5xKGEsIm5hbWUiKSkKcj1ILmgocS5xKGEsInBh
+dGgiKSkKcT1xLnEoYSwic3VidHJlZSIpCnE9bmV3IEwudnQocT09bnVsbD9udWxsOkwubUsocSkscyxy
+KQpxLkxWKCkKcmV0dXJuIHF9ZWxzZXtzPUguaChxLnEoYSwibmFtZSIpKQpyPUguaChxLnEoYSwicGF0
+aCIpKQpyZXR1cm4gbmV3IEwuY0QoSC5oKHEucShhLCJocmVmIikpLEgudVAocS5xKGEsImVkaXRDb3Vu
+dCIpKSxILnk4KHEucShhLCJ3YXNFeHBsaWNpdGx5T3B0ZWRPdXQiKSksTC52QihILnVQKHEucShhLCJt
+aWdyYXRpb25TdGF0dXMiKSkpLEgueTgocS5xKGEsIm1pZ3JhdGlvblN0YXR1c0NhbkJlQ2hhbmdlZCIp
+KSxzLHIpfX0sCm1LOmZ1bmN0aW9uKGEpe3ZhciBzLHI9SC5WTShbXSx0LmNRKQpmb3Iocz1KLklUKHQu
+VS5hKGEpKTtzLkYoKTspci5wdXNoKEwuWnMocy5nbCgpKSkKcmV0dXJuIHJ9LApWRDpmdW5jdGlvbihh
+KXt2YXIgcyxyLHE9SC5WTShbXSx0LkcpCmZvcihzPWEubGVuZ3RoLHI9MDtyPGEubGVuZ3RoO2EubGVu
+Z3RoPT09c3x8KDAsSC5saykoYSksKytyKXEucHVzaChhW3JdLkx0KCkpCnJldHVybiBxfSwKdkI6ZnVu
+Y3Rpb24oYSl7aWYoYT09bnVsbClyZXR1cm4gbnVsbAppZihhPj4+MCE9PWF8fGE+PTQpcmV0dXJuIEgu
+T0goQy5sMCxhKQpyZXR1cm4gQy5sMFthXX0sCnAyOmZ1bmN0aW9uKGEpe3N3aXRjaChhKXtjYXNlImRp
+cmVjdG9yeSI6cmV0dXJuIEMuWTIKY2FzZSJmaWxlIjpyZXR1cm4gQy5yZgpkZWZhdWx0OnRocm93IEgu
+YihQLlBWKCJVbnJlY29nbml6ZWQgbmF2aWdhdGlvbiB0cmVlIG5vZGUgdHlwZTogIitILkVqKGEpKSl9
+fSwKdnQ6ZnVuY3Rpb24gdnQoYSxiLGMpe3ZhciBfPXRoaXMKXy5kPWEKXy5hPWIKXy5iPW51bGwKXy5j
+PWN9LApjRDpmdW5jdGlvbiBjRChhLGIsYyxkLGUsZixnKXt2YXIgXz10aGlzCl8uZD1hCl8uZT1iCl8u
+Zj1jCl8ucj1kCl8ueD1lCl8uYT1mCl8uYj1udWxsCl8uYz1nfSwKRDg6ZnVuY3Rpb24gRDgoKXt9LApP
+OTpmdW5jdGlvbiBPOShhKXt0aGlzLmI9YX0sCkdiOmZ1bmN0aW9uIEdiKGEsYil7dGhpcy5hPWEKdGhp
+cy5iPWJ9LApJVjpmdW5jdGlvbiBJVihhLGIsYyxkKXt2YXIgXz10aGlzCl8uZD1hCl8uZT1iCl8uZj1j
+Cl8ucj1kfX0sUj17Cm56OmZ1bmN0aW9uKGEpe3ZhciBzPUgudVAoYS5xKDAsIm5vZGVJZCIpKQpyZXR1
+cm4gbmV3IFIuTEwoQy5ObS5IdChDLnJrLG5ldyBSLk1EKGEpKSxzKX0sCk9YOmZ1bmN0aW9uKGEpe3N3
+aXRjaChhKXtjYXNlIEMuQWQ6cmV0dXJuIkFkZCAvKj8qLyBoaW50IgpjYXNlIEMubmU6cmV0dXJuIkFk
+ZCAvKiEqLyBoaW50IgpjYXNlIEMud1Y6cmV0dXJuIlJlbW92ZSAvKj8qLyBoaW50IgpjYXNlIEMuZlI6
+cmV0dXJuIlJlbW92ZSAvKiEqLyBoaW50IgpjYXNlIEMubXk6cmV0dXJuIkNoYW5nZSB0byAvKj8qLyBo
+aW50IgpjYXNlIEMucng6cmV0dXJuIkNoYW5nZSB0byAvKiEqLyBoaW50In1yZXR1cm4gbnVsbH0sCkxM
+OmZ1bmN0aW9uIExMKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApNRDpmdW5jdGlvbiBNRChhKXt0aGlz
+LmE9YX0sCkg3OmZ1bmN0aW9uIEg3KGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9fSxNPXsKWUY6ZnVuY3Rp
+b24oYSxiKXt2YXIgcyxyLHEscCxvLG4sbSxsCmZvcihzPWIubGVuZ3RoLHI9MTtyPHM7KytyKXtpZihi
+W3JdPT1udWxsfHxiW3ItMV0hPW51bGwpY29udGludWUKZm9yKDtzPj0xO3M9cSl7cT1zLTEKaWYoYltx
+XSE9bnVsbClicmVha31wPW5ldyBQLlJuKCIiKQpvPWErIigiCnAuYT1vCm49SC50NihiKQptPW4uQygi
+bkg8MT4iKQpsPW5ldyBILm5IKGIsMCxzLG0pCmwuSGQoYiwwLHMsbi5jKQptPW8rbmV3IEgubEoobCxt
+LkMoInFVKGFMLkUpIikuYShuZXcgTS5ObygpKSxtLkMoImxKPGFMLkUscVU+IikpLmsoMCwiLCAiKQpw
+LmE9bQpwLmE9bSsoIik6IHBhcnQgIisoci0xKSsiIHdhcyBudWxsLCBidXQgcGFydCAiK3IrIiB3YXMg
+bm90LiIpCnRocm93IEguYihQLnhZKHAudygwKSkpfX0sCmxJOmZ1bmN0aW9uIGxJKGEpe3RoaXMuYT1h
+fSwKcTc6ZnVuY3Rpb24gcTcoKXt9LApObzpmdW5jdGlvbiBObygpe319LFg9ewpDTDpmdW5jdGlvbihh
+LGIpe3ZhciBzLHIscSxwLG8sbj1iLnhaKGEpCmIuaEsoYSkKaWYobiE9bnVsbClhPUouS1YoYSxuLmxl
+bmd0aCkKcz10LnMKcj1ILlZNKFtdLHMpCnE9SC5WTShbXSxzKQpzPWEubGVuZ3RoCmlmKHMhPT0wJiZi
+LnI0KEMueEIuVyhhLDApKSl7aWYoMD49cylyZXR1cm4gSC5PSChhLDApCkMuTm0uaShxLGFbMF0pCnA9
+MX1lbHNle0MuTm0uaShxLCIiKQpwPTB9Zm9yKG89cDtvPHM7KytvKWlmKGIucjQoQy54Qi5XKGEsbykp
+KXtDLk5tLmkocixDLnhCLk5qKGEscCxvKSkKQy5ObS5pKHEsYVtvXSkKcD1vKzF9aWYocDxzKXtDLk5t
+LmkocixDLnhCLnluKGEscCkpCkMuTm0uaShxLCIiKX1yZXR1cm4gbmV3IFguV0QoYixuLHIscSl9LApX
+RDpmdW5jdGlvbiBXRChhLGIsYyxkKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uZD1jCl8uZT1kfSwK
+STc6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBYLmR2KGEpfSwKZHY6ZnVuY3Rpb24gZHYoYSl7dGhpcy5h
+PWF9fSxPPXsKUmg6ZnVuY3Rpb24oKXt2YXIgcyxyPW51bGwKaWYoUC51bygpLmdGaSgpIT09ImZpbGUi
+KXJldHVybiAkLkViKCkKcz1QLnVvKCkKaWYoIUMueEIuVGMocy5nSWkocyksIi8iKSlyZXR1cm4gJC5F
+YigpCmlmKFAuS0wociwiYS9iIixyLHIscixyLHIpLnQ0KCk9PT0iYVxcYiIpcmV0dXJuICQuS2soKQpy
+ZXR1cm4gJC5iRCgpfSwKekw6ZnVuY3Rpb24gekwoKXt9fSxFPXtPRjpmdW5jdGlvbiBPRihhLGIsYyl7
+dGhpcy5kPWEKdGhpcy5lPWIKdGhpcy5mPWN9fSxGPXtydTpmdW5jdGlvbiBydShhLGIsYyxkKXt2YXIg
+Xz10aGlzCl8uZD1hCl8uZT1iCl8uZj1jCl8ucj1kfX0sRD17CmFiOmZ1bmN0aW9uKCl7dmFyIHMscixx
+LHAsbz1udWxsCnRyeXtvPVAudW8oKX1jYXRjaChzKXtpZih0Lmc4LmIoSC5SdShzKSkpe3I9JC5GZgpp
+ZihyIT1udWxsKXJldHVybiByCnRocm93IHN9ZWxzZSB0aHJvdyBzfWlmKEouUk0obywkLkk2KSl7cj0k
+LkZmCnIudG9TdHJpbmcKcmV0dXJuIHJ9JC5JNj1vCmlmKCQuSGsoKT09JC5FYigpKXI9JC5GZj1vLlpJ
+KCIuIikudygwKQplbHNle3E9by50NCgpCnA9cS5sZW5ndGgtMQpyPSQuRmY9cD09PTA/cTpDLnhCLk5q
+KHEsMCxwKX1yLnRvU3RyaW5nCnJldHVybiByfX0KdmFyIHc9W0MsSCxKLFAsVyxVLEIsVCxMLFIsTSxY
+LE8sRSxGLERdCmh1bmtIZWxwZXJzLnNldEZ1bmN0aW9uTmFtZXNJZk5lY2Vzc2FyeSh3KQp2YXIgJD17
+fQpILkZLLnByb3RvdHlwZT17fQpKLkd2LnByb3RvdHlwZT17CkROOmZ1bmN0aW9uKGEsYil7cmV0dXJu
+IGE9PT1ifSwKZ2lPOmZ1bmN0aW9uKGEpe3JldHVybiBILmVRKGEpfSwKdzpmdW5jdGlvbihhKXtyZXR1
+cm4iSW5zdGFuY2Ugb2YgJyIrSC5FaihILk0oYSkpKyInIn0sCmU3OmZ1bmN0aW9uKGEsYil7dC5vLmEo
+YikKdGhyb3cgSC5iKFAubHIoYSxiLmdXYSgpLGIuZ25kKCksYi5nVm0oKSkpfX0KSi55RS5wcm90b3R5
+cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiBTdHJpbmcoYSl9LApnaU86ZnVuY3Rpb24oYSl7cmV0dXJu
+IGE/NTE5MDE4OjIxODE1OX0sCiRpYTI6MX0KSi53ZS5wcm90b3R5cGU9ewpETjpmdW5jdGlvbihhLGIp
+e3JldHVybiBudWxsPT1ifSwKdzpmdW5jdGlvbihhKXtyZXR1cm4ibnVsbCJ9LApnaU86ZnVuY3Rpb24o
+YSl7cmV0dXJuIDB9LAplNzpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLlNqKGEsdC5vLmEoYikpfSwK
+JGljODoxfQpKLk1GLnByb3RvdHlwZT17CmdpTzpmdW5jdGlvbihhKXtyZXR1cm4gMH0sCnc6ZnVuY3Rp
+b24oYSl7cmV0dXJuIFN0cmluZyhhKX0sCiRpdm06MX0KSi5pQy5wcm90b3R5cGU9e30KSi5rZC5wcm90
+b3R5cGU9e30KSi5jNS5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3ZhciBzPWFbJC53KCldCmlmKHM9
+PW51bGwpcmV0dXJuIHRoaXMudChhKQpyZXR1cm4iSmF2YVNjcmlwdCBmdW5jdGlvbiBmb3IgIitILkVq
+KEouaihzKSl9LAokaUVIOjF9CkouamQucHJvdG90eXBlPXsKZHI6ZnVuY3Rpb24oYSxiKXtyZXR1cm4g
+bmV3IEgualYoYSxILnQ2KGEpLkMoIkA8MT4iKS5LcShiKS5DKCJqVjwxLDI+IikpfSwKaTpmdW5jdGlv
+bihhLGIpe0gudDYoYSkuYy5hKGIpCmlmKCEhYS5maXhlZCRsZW5ndGgpSC52KFAuTDQoImFkZCIpKQph
+LnB1c2goYil9LApXNDpmdW5jdGlvbihhLGIpe3ZhciBzCmlmKCEhYS5maXhlZCRsZW5ndGgpSC52KFAu
+TDQoInJlbW92ZUF0IikpCnM9YS5sZW5ndGgKaWYoYj49cyl0aHJvdyBILmIoUC5PNyhiLG51bGwpKQpy
+ZXR1cm4gYS5zcGxpY2UoYiwxKVswXX0sClVHOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyCkgudDYoYSku
+QygiY1g8MT4iKS5hKGMpCmlmKCEhYS5maXhlZCRsZW5ndGgpSC52KFAuTDQoImluc2VydEFsbCIpKQpQ
+LndBKGIsMCxhLmxlbmd0aCwiaW5kZXgiKQppZighdC5kLmIoYykpYz1KLlJYKGMpCnM9Si5IbShjKQph
+Lmxlbmd0aD1hLmxlbmd0aCtzCnI9YitzCnRoaXMuWVcoYSxyLGEubGVuZ3RoLGEsYikKdGhpcy52Zyhh
+LGIscixjKX0sCkZWOmZ1bmN0aW9uKGEsYil7dmFyIHMKSC50NihhKS5DKCJjWDwxPiIpLmEoYikKaWYo
+ISFhLmZpeGVkJGxlbmd0aClILnYoUC5MNCgiYWRkQWxsIikpCmlmKEFycmF5LmlzQXJyYXkoYikpe3Ro
+aXMuS2goYSxiKQpyZXR1cm59Zm9yKHM9Si5JVChiKTtzLkYoKTspYS5wdXNoKHMuZ2woKSl9LApLaDpm
+dW5jdGlvbihhLGIpe3ZhciBzLHIKdC5iLmEoYikKcz1iLmxlbmd0aAppZihzPT09MClyZXR1cm4KaWYo
+YT09PWIpdGhyb3cgSC5iKFAuYTQoYSkpCmZvcihyPTA7cjxzOysrcilhLnB1c2goYltyXSl9LApFMjpm
+dW5jdGlvbihhLGIsYyl7dmFyIHM9SC50NihhKQpyZXR1cm4gbmV3IEgubEooYSxzLktxKGMpLkMoIjEo
+MikiKS5hKGIpLHMuQygiQDwxPiIpLktxKGMpLkMoImxKPDEsMj4iKSl9LAprOmZ1bmN0aW9uKGEsYil7
+dmFyIHMscj1QLk84KGEubGVuZ3RoLCIiLCExLHQuTikKZm9yKHM9MDtzPGEubGVuZ3RoOysrcyl0aGlz
+Llk1KHIscyxILkVqKGFbc10pKQpyZXR1cm4gci5qb2luKGIpfSwKZVI6ZnVuY3Rpb24oYSxiKXtyZXR1
+cm4gSC5xQyhhLGIsbnVsbCxILnQ2KGEpLmMpfSwKTjA6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHMscixx
+CmQuYShiKQpILnQ2KGEpLktxKGQpLkMoIjEoMSwyKSIpLmEoYykKcz1hLmxlbmd0aApmb3Iocj1iLHE9
+MDtxPHM7KytxKXtyPWMuJDIocixhW3FdKQppZihhLmxlbmd0aCE9PXMpdGhyb3cgSC5iKFAuYTQoYSkp
+fXJldHVybiByfSwKSHQ6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEscCxvCkgudDYoYSkuQygiYTIoMSki
+KS5hKGIpCnM9YS5sZW5ndGgKZm9yKHI9bnVsbCxxPSExLHA9MDtwPHM7KytwKXtvPWFbcF0KaWYoSC5v
+VChiLiQxKG8pKSl7aWYocSl0aHJvdyBILmIoSC5BbSgpKQpyPW8KcT0hMH1pZihzIT09YS5sZW5ndGgp
+dGhyb3cgSC5iKFAuYTQoYSkpfWlmKHEpcmV0dXJuIHIKdGhyb3cgSC5iKEguV3AoKSl9LApFOmZ1bmN0
+aW9uKGEsYil7aWYoYjwwfHxiPj1hLmxlbmd0aClyZXR1cm4gSC5PSChhLGIpCnJldHVybiBhW2JdfSwK
+Z3RIOmZ1bmN0aW9uKGEpe2lmKGEubGVuZ3RoPjApcmV0dXJuIGFbMF0KdGhyb3cgSC5iKEguV3AoKSl9
+LApnclo6ZnVuY3Rpb24oYSl7dmFyIHM9YS5sZW5ndGgKaWYocz4wKXJldHVybiBhW3MtMV0KdGhyb3cg
+SC5iKEguV3AoKSl9LApZVzpmdW5jdGlvbihhLGIsYyxkLGUpe3ZhciBzLHIscSxwLG8KSC50NihhKS5D
+KCJjWDwxPiIpLmEoZCkKaWYoISFhLmltbXV0YWJsZSRsaXN0KUgudihQLkw0KCJzZXRSYW5nZSIpKQpQ
+LmpCKGIsYyxhLmxlbmd0aCkKcz1jLWIKaWYocz09PTApcmV0dXJuClAuazEoZSwic2tpcENvdW50IikK
+aWYodC5qLmIoZCkpe3I9ZApxPWV9ZWxzZXtyPUouQTUoZCxlKS50dCgwLCExKQpxPTB9cD1KLlU2KHIp
+CmlmKHErcz5wLmdBKHIpKXRocm93IEguYihILmFyKCkpCmlmKHE8Yilmb3Iobz1zLTE7bz49MDstLW8p
+YVtiK29dPXAucShyLHErbykKZWxzZSBmb3Iobz0wO288czsrK28pYVtiK29dPXAucShyLHErbyl9LAp2
+ZzpmdW5jdGlvbihhLGIsYyxkKXtyZXR1cm4gdGhpcy5ZVyhhLGIsYyxkLDApfSwKVnI6ZnVuY3Rpb24o
+YSxiKXt2YXIgcyxyCkgudDYoYSkuQygiYTIoMSkiKS5hKGIpCnM9YS5sZW5ndGgKZm9yKHI9MDtyPHM7
+KytyKXtpZihILm9UKGIuJDEoYVtyXSkpKXJldHVybiEwCmlmKGEubGVuZ3RoIT09cyl0aHJvdyBILmIo
+UC5hNChhKSl9cmV0dXJuITF9LAp0ZzpmdW5jdGlvbihhLGIpe3ZhciBzCmZvcihzPTA7czxhLmxlbmd0
+aDsrK3MpaWYoSi5STShhW3NdLGIpKXJldHVybiEwCnJldHVybiExfSwKZ2wwOmZ1bmN0aW9uKGEpe3Jl
+dHVybiBhLmxlbmd0aD09PTB9LApnb3I6ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVuZ3RoIT09MH0sCnc6
+ZnVuY3Rpb24oYSl7cmV0dXJuIFAuV0UoYSwiWyIsIl0iKX0sCnR0OmZ1bmN0aW9uKGEsYil7dmFyIHM9
+SC5WTShhLnNsaWNlKDApLEgudDYoYSkpCnJldHVybiBzfSwKYnI6ZnVuY3Rpb24oYSl7cmV0dXJuIHRo
+aXMudHQoYSwhMCl9LApnbTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IEoubTEoYSxhLmxlbmd0aCxILnQ2
+KGEpLkMoIm0xPDE+IikpfSwKZ2lPOmZ1bmN0aW9uKGEpe3JldHVybiBILmVRKGEpfSwKZ0E6ZnVuY3Rp
+b24oYSl7cmV0dXJuIGEubGVuZ3RofSwKc0E6ZnVuY3Rpb24oYSxiKXtpZighIWEuZml4ZWQkbGVuZ3Ro
+KUgudihQLkw0KCJzZXQgbGVuZ3RoIikpCmlmKGI8MCl0aHJvdyBILmIoUC5URShiLDAsbnVsbCwibmV3
+TGVuZ3RoIixudWxsKSkKYS5sZW5ndGg9Yn0sCnE6ZnVuY3Rpb24oYSxiKXtILnVQKGIpCmlmKGI+PWEu
+bGVuZ3RofHxiPDApdGhyb3cgSC5iKEguSFkoYSxiKSkKcmV0dXJuIGFbYl19LApZNTpmdW5jdGlvbihh
+LGIsYyl7SC50NihhKS5jLmEoYykKaWYoISFhLmltbXV0YWJsZSRsaXN0KUgudihQLkw0KCJpbmRleGVk
+IHNldCIpKQppZihiPj1hLmxlbmd0aHx8YjwwKXRocm93IEguYihILkhZKGEsYikpCmFbYl09Y30sCiRp
+YlE6MSwKJGljWDoxLAokaXpNOjF9CkouUG8ucHJvdG90eXBlPXt9CkoubTEucHJvdG90eXBlPXsKZ2w6
+ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5kfSwKRjpmdW5jdGlvbigpe3ZhciBzLHI9dGhpcyxxPXIuYSxw
+PXEubGVuZ3RoCmlmKHIuYiE9PXApdGhyb3cgSC5iKEgubGsocSkpCnM9ci5jCmlmKHM+PXApe3Iuc00o
+bnVsbCkKcmV0dXJuITF9ci5zTShxW3NdKTsrK3IuYwpyZXR1cm4hMH0sCnNNOmZ1bmN0aW9uKGEpe3Ro
+aXMuZD10aGlzLiR0aS5DKCIxPyIpLmEoYSl9LAokaUFuOjF9CkoucUkucHJvdG90eXBlPXsKelE6ZnVu
+Y3Rpb24oYSl7aWYoYT4wKXtpZihhIT09MS8wKXJldHVybiBNYXRoLnJvdW5kKGEpfWVsc2UgaWYoYT4t
+MS8wKXJldHVybiAwLU1hdGgucm91bmQoMC1hKQp0aHJvdyBILmIoUC5MNCgiIithKyIucm91bmQoKSIp
+KX0sCnc6ZnVuY3Rpb24oYSl7aWYoYT09PTAmJjEvYTwwKXJldHVybiItMC4wIgplbHNlIHJldHVybiIi
+K2F9LApnaU86ZnVuY3Rpb24oYSl7dmFyIHMscixxLHAsbz1hfDAKaWYoYT09PW8pcmV0dXJuIG8mNTM2
+ODcwOTExCnM9TWF0aC5hYnMoYSkKcj1NYXRoLmxvZyhzKS8wLjY5MzE0NzE4MDU1OTk0NTN8MApxPU1h
+dGgucG93KDIscikKcD1zPDE/cy9xOnEvcwpyZXR1cm4oKHAqOTAwNzE5OTI1NDc0MDk5MnwwKSsocCoz
+NTQyMjQzMTgxMTc2NTIxfDApKSo1OTkxOTcrcioxMjU5JjUzNjg3MDkxMX0sCnpZOmZ1bmN0aW9uKGEs
+Yil7dmFyIHM9YSViCmlmKHM9PT0wKXJldHVybiAwCmlmKHM+MClyZXR1cm4gcwppZihiPDApcmV0dXJu
+IHMtYgplbHNlIHJldHVybiBzK2J9LApCVTpmdW5jdGlvbihhLGIpe3JldHVybihhfDApPT09YT9hL2J8
+MDp0aGlzLkRKKGEsYil9LApESjpmdW5jdGlvbihhLGIpe3ZhciBzPWEvYgppZihzPj0tMjE0NzQ4MzY0
+OCYmczw9MjE0NzQ4MzY0NylyZXR1cm4gc3wwCmlmKHM+MCl7aWYocyE9PTEvMClyZXR1cm4gTWF0aC5m
+bG9vcihzKX1lbHNlIGlmKHM+LTEvMClyZXR1cm4gTWF0aC5jZWlsKHMpCnRocm93IEguYihQLkw0KCJS
+ZXN1bHQgb2YgdHJ1bmNhdGluZyBkaXZpc2lvbiBpcyAiK0guRWoocykrIjogIitILkVqKGEpKyIgfi8g
+IitiKSl9LAp3RzpmdW5jdGlvbihhLGIpe3ZhciBzCmlmKGE+MClzPXRoaXMucDMoYSxiKQplbHNle3M9
+Yj4zMT8zMTpiCnM9YT4+cz4+PjB9cmV0dXJuIHN9LApiZjpmdW5jdGlvbihhLGIpe2lmKGI8MCl0aHJv
+dyBILmIoSC50TChiKSkKcmV0dXJuIHRoaXMucDMoYSxiKX0sCnAzOmZ1bmN0aW9uKGEsYil7cmV0dXJu
+IGI+MzE/MDphPj4+Yn0sCiRpQ1A6MSwKJGlaWjoxfQpKLmJVLnByb3RvdHlwZT17JGlJajoxfQpKLmtE
+LnByb3RvdHlwZT17fQpKLkRyLnByb3RvdHlwZT17Ck86ZnVuY3Rpb24oYSxiKXtpZihiPDApdGhyb3cg
+SC5iKEguSFkoYSxiKSkKaWYoYj49YS5sZW5ndGgpSC52KEguSFkoYSxiKSkKcmV0dXJuIGEuY2hhckNv
+ZGVBdChiKX0sClc6ZnVuY3Rpb24oYSxiKXtpZihiPj1hLmxlbmd0aCl0aHJvdyBILmIoSC5IWShhLGIp
+KQpyZXR1cm4gYS5jaGFyQ29kZUF0KGIpfSwKZGQ6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gbmV3IEgudW4o
+YixhLDApfSwKaDpmdW5jdGlvbihhLGIpe2lmKHR5cGVvZiBiIT0ic3RyaW5nIil0aHJvdyBILmIoUC5M
+MyhiLG51bGwsbnVsbCkpCnJldHVybiBhK2J9LApUYzpmdW5jdGlvbihhLGIpe3ZhciBzPWIubGVuZ3Ro
+LHI9YS5sZW5ndGgKaWYocz5yKXJldHVybiExCnJldHVybiBiPT09dGhpcy55bihhLHItcyl9LAppNzpm
+dW5jdGlvbihhLGIsYyxkKXt2YXIgcz1QLmpCKGIsYyxhLmxlbmd0aCkscj1hLnN1YnN0cmluZygwLGIp
+LHE9YS5zdWJzdHJpbmcocykKcmV0dXJuIHIrZCtxfSwKUWk6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzCmlm
+KGM8MHx8Yz5hLmxlbmd0aCl0aHJvdyBILmIoUC5URShjLDAsYS5sZW5ndGgsbnVsbCxudWxsKSkKcz1j
+K2IubGVuZ3RoCmlmKHM+YS5sZW5ndGgpcmV0dXJuITEKcmV0dXJuIGI9PT1hLnN1YnN0cmluZyhjLHMp
+fSwKbkM6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5RaShhLGIsMCl9LApOajpmdW5jdGlvbihhLGIs
+Yyl7aWYoYz09bnVsbCljPWEubGVuZ3RoCmlmKGI8MCl0aHJvdyBILmIoUC5PNyhiLG51bGwpKQppZihi
+PmMpdGhyb3cgSC5iKFAuTzcoYixudWxsKSkKaWYoYz5hLmxlbmd0aCl0aHJvdyBILmIoUC5PNyhjLG51
+bGwpKQpyZXR1cm4gYS5zdWJzdHJpbmcoYixjKX0sCnluOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMu
+TmooYSxiLG51bGwpfSwKaGM6ZnVuY3Rpb24oYSl7cmV0dXJuIGEudG9Mb3dlckNhc2UoKX0sCmJTOmZ1
+bmN0aW9uKGEpe3ZhciBzLHIscSxwPWEudHJpbSgpLG89cC5sZW5ndGgKaWYobz09PTApcmV0dXJuIHAK
+aWYodGhpcy5XKHAsMCk9PT0xMzMpe3M9Si5tbShwLDEpCmlmKHM9PT1vKXJldHVybiIifWVsc2Ugcz0w
+CnI9by0xCnE9dGhpcy5PKHAscik9PT0xMzM/Si5jMShwLHIpOm8KaWYocz09PTAmJnE9PT1vKXJldHVy
+biBwCnJldHVybiBwLnN1YnN0cmluZyhzLHEpfSwKVDpmdW5jdGlvbihhLGIpe3ZhciBzLHIKaWYoMD49
+YilyZXR1cm4iIgppZihiPT09MXx8YS5sZW5ndGg9PT0wKXJldHVybiBhCmlmKGIhPT1iPj4+MCl0aHJv
+dyBILmIoQy5FcSkKZm9yKHM9YSxyPSIiOyEwOyl7aWYoKGImMSk9PT0xKXI9cytyCmI9Yj4+PjEKaWYo
+Yj09PTApYnJlYWsKcys9c31yZXR1cm4gcn0sClhVOmZ1bmN0aW9uKGEsYixjKXt2YXIgcwppZihjPDB8
+fGM+YS5sZW5ndGgpdGhyb3cgSC5iKFAuVEUoYywwLGEubGVuZ3RoLG51bGwsbnVsbCkpCnM9YS5pbmRl
+eE9mKGIsYykKcmV0dXJuIHN9LApPWTpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLlhVKGEsYiwwKX0s
+ClBrOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyCmlmKGM9PW51bGwpYz1hLmxlbmd0aAplbHNlIGlmKGM8
+MHx8Yz5hLmxlbmd0aCl0aHJvdyBILmIoUC5URShjLDAsYS5sZW5ndGgsbnVsbCxudWxsKSkKcz1iLmxl
+bmd0aApyPWEubGVuZ3RoCmlmKGMrcz5yKWM9ci1zCnJldHVybiBhLmxhc3RJbmRleE9mKGIsYyl9LApj
+bjpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLlBrKGEsYixudWxsKX0sCklzOmZ1bmN0aW9uKGEsYixj
+KXt2YXIgcz1hLmxlbmd0aAppZihjPnMpdGhyb3cgSC5iKFAuVEUoYywwLHMsbnVsbCxudWxsKSkKcmV0
+dXJuIEguU1EoYSxiLGMpfSwKdGc6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5JcyhhLGIsMCl9LAp3
+OmZ1bmN0aW9uKGEpe3JldHVybiBhfSwKZ2lPOmZ1bmN0aW9uKGEpe3ZhciBzLHIscQpmb3Iocz1hLmxl
+bmd0aCxyPTAscT0wO3E8czsrK3Epe3I9cithLmNoYXJDb2RlQXQocSkmNTM2ODcwOTExCnI9cisoKHIm
+NTI0Mjg3KTw8MTApJjUzNjg3MDkxMQpyXj1yPj42fXI9cisoKHImNjcxMDg4NjMpPDwzKSY1MzY4NzA5
+MTEKcl49cj4+MTEKcmV0dXJuIHIrKChyJjE2MzgzKTw8MTUpJjUzNjg3MDkxMX0sCmdBOmZ1bmN0aW9u
+KGEpe3JldHVybiBhLmxlbmd0aH0sCnE6ZnVuY3Rpb24oYSxiKXtILnVQKGIpCmlmKGI+PWEubGVuZ3Ro
+fHwhMSl0aHJvdyBILmIoSC5IWShhLGIpKQpyZXR1cm4gYVtiXX0sCiRpdlg6MSwKJGlxVToxfQpILkJS
+LnByb3RvdHlwZT17CmdtOmZ1bmN0aW9uKGEpe3ZhciBzPUguTGgodGhpcykKcmV0dXJuIG5ldyBILkU3
+KEouSVQodGhpcy5nT04oKSkscy5DKCJAPDE+IikuS3Eocy5RWzFdKS5DKCJFNzwxLDI+IikpfSwKZ0E6
+ZnVuY3Rpb24oYSl7cmV0dXJuIEouSG0odGhpcy5nT04oKSl9LApnbDA6ZnVuY3Rpb24oYSl7cmV0dXJu
+IEoudVUodGhpcy5nT04oKSl9LApnb3I6ZnVuY3Rpb24oYSl7cmV0dXJuIEouRjcodGhpcy5nT04oKSl9
+LAplUjpmdW5jdGlvbihhLGIpe3ZhciBzPUguTGgodGhpcykKcmV0dXJuIEguR0ooSi5BNSh0aGlzLmdP
+TigpLGIpLHMuYyxzLlFbMV0pfSwKRTpmdW5jdGlvbihhLGIpe3JldHVybiBILkxoKHRoaXMpLlFbMV0u
+YShKLkdBKHRoaXMuZ09OKCksYikpfSwKdzpmdW5jdGlvbihhKXtyZXR1cm4gSi5qKHRoaXMuZ09OKCkp
+fX0KSC5FNy5wcm90b3R5cGU9ewpGOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuYS5GKCl9LApnbDpmdW5j
+dGlvbigpe3JldHVybiB0aGlzLiR0aS5RWzFdLmEodGhpcy5hLmdsKCkpfSwKJGlBbjoxfQpILlp5LnBy
+b3RvdHlwZT17CmdPTjpmdW5jdGlvbigpe3JldHVybiB0aGlzLmF9fQpILm9sLnByb3RvdHlwZT17JGli
+UToxfQpILlVxLnByb3RvdHlwZT17CnE6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhpcy4kdGkuUVsxXS5h
+KEoueDkodGhpcy5hLEgudVAoYikpKX0sClk1OmZ1bmN0aW9uKGEsYixjKXt2YXIgcz10aGlzLiR0aQpK
+LnU5KHRoaXMuYSxiLHMuYy5hKHMuUVsxXS5hKGMpKSl9LAokaWJROjEsCiRpek06MX0KSC5qVi5wcm90
+b3R5cGU9ewpkcjpmdW5jdGlvbihhLGIpe3JldHVybiBuZXcgSC5qVih0aGlzLmEsdGhpcy4kdGkuQygi
+QDwxPiIpLktxKGIpLkMoImpWPDEsMj4iKSl9LApnT046ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5hfX0K
+SC5uLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7dmFyIHM9dGhpcy5hCnJldHVybiBzIT1udWxsPyJM
+YXRlSW5pdGlhbGl6YXRpb25FcnJvcjogIitzOiJMYXRlSW5pdGlhbGl6YXRpb25FcnJvciJ9fQpILnIz
+LnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7dmFyIHM9IlJlYWNoYWJpbGl0eUVycm9yOiAiK3RoaXMu
+YQpyZXR1cm4gc319CkgucWoucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYS5s
+ZW5ndGh9LApxOmZ1bmN0aW9uKGEsYil7cmV0dXJuIEMueEIuTyh0aGlzLmEsSC51UChiKSl9fQpILkdN
+LnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7cmV0dXJuIk51bGwgaXMgbm90IGEgdmFsaWQgdmFsdWUg
+Zm9yIHRoZSBwYXJhbWV0ZXIgJyIrdGhpcy5hKyInIG9mIHR5cGUgJyIrSC5LeCh0aGlzLiR0aS5jKS53
+KDApKyInIn19CkguYlEucHJvdG90eXBlPXt9CkguYUwucHJvdG90eXBlPXsKZ206ZnVuY3Rpb24oYSl7
+dmFyIHM9dGhpcwpyZXR1cm4gbmV3IEguYTcocyxzLmdBKHMpLEguTGgocykuQygiYTc8YUwuRT4iKSl9
+LApnbDA6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuZ0EodGhpcyk9PT0wfSwKazpmdW5jdGlvbihhLGIp
+e3ZhciBzLHIscSxwPXRoaXMsbz1wLmdBKHApCmlmKGIubGVuZ3RoIT09MCl7aWYobz09PTApcmV0dXJu
+IiIKcz1ILkVqKHAuRSgwLDApKQppZihvIT09cC5nQShwKSl0aHJvdyBILmIoUC5hNChwKSkKZm9yKHI9
+cyxxPTE7cTxvOysrcSl7cj1yK2IrSC5FaihwLkUoMCxxKSkKaWYobyE9PXAuZ0EocCkpdGhyb3cgSC5i
+KFAuYTQocCkpfXJldHVybiByLmNoYXJDb2RlQXQoMCk9PTA/cjpyfWVsc2V7Zm9yKHE9MCxyPSIiO3E8
+bzsrK3Epe3IrPUguRWoocC5FKDAscSkpCmlmKG8hPT1wLmdBKHApKXRocm93IEguYihQLmE0KHApKX1y
+ZXR1cm4gci5jaGFyQ29kZUF0KDApPT0wP3I6cn19LApldjpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlz
+LkdHKDAsSC5MaCh0aGlzKS5DKCJhMihhTC5FKSIpLmEoYikpfSwKRTI6ZnVuY3Rpb24oYSxiLGMpe3Zh
+ciBzPUguTGgodGhpcykKcmV0dXJuIG5ldyBILmxKKHRoaXMscy5LcShjKS5DKCIxKGFMLkUpIikuYShi
+KSxzLkMoIkA8YUwuRT4iKS5LcShjKS5DKCJsSjwxLDI+IikpfSwKZVI6ZnVuY3Rpb24oYSxiKXtyZXR1
+cm4gSC5xQyh0aGlzLGIsbnVsbCxILkxoKHRoaXMpLkMoImFMLkUiKSl9LAp0dDpmdW5jdGlvbihhLGIp
+e3JldHVybiBQLlkxKHRoaXMsITAsSC5MaCh0aGlzKS5DKCJhTC5FIikpfSwKYnI6ZnVuY3Rpb24oYSl7
+cmV0dXJuIHRoaXMudHQoYSwhMCl9fQpILm5ILnByb3RvdHlwZT17CkhkOmZ1bmN0aW9uKGEsYixjLGQp
+e3ZhciBzLHI9dGhpcy5iClAuazEociwic3RhcnQiKQpzPXRoaXMuYwppZihzIT1udWxsKXtQLmsxKHMs
+ImVuZCIpCmlmKHI+cyl0aHJvdyBILmIoUC5URShyLDAscywic3RhcnQiLG51bGwpKX19LApnVUQ6ZnVu
+Y3Rpb24oKXt2YXIgcz1KLkhtKHRoaXMuYSkscj10aGlzLmMKaWYocj09bnVsbHx8cj5zKXJldHVybiBz
+CnJldHVybiByfSwKZ0FzOmZ1bmN0aW9uKCl7dmFyIHM9Si5IbSh0aGlzLmEpLHI9dGhpcy5iCmlmKHI+
+cylyZXR1cm4gcwpyZXR1cm4gcn0sCmdBOmZ1bmN0aW9uKGEpe3ZhciBzLHI9Si5IbSh0aGlzLmEpLHE9
+dGhpcy5iCmlmKHE+PXIpcmV0dXJuIDAKcz10aGlzLmMKaWYocz09bnVsbHx8cz49cilyZXR1cm4gci1x
+CmlmKHR5cGVvZiBzIT09Im51bWJlciIpcmV0dXJuIHMuSE4oKQpyZXR1cm4gcy1xfSwKRTpmdW5jdGlv
+bihhLGIpe3ZhciBzPXRoaXMscj1zLmdBcygpK2IKaWYoYjwwfHxyPj1zLmdVRCgpKXRocm93IEguYihQ
+LkNmKGIscywiaW5kZXgiLG51bGwsbnVsbCkpCnJldHVybiBKLkdBKHMuYSxyKX0sCmVSOmZ1bmN0aW9u
+KGEsYil7dmFyIHMscixxPXRoaXMKUC5rMShiLCJjb3VudCIpCnM9cS5iK2IKcj1xLmMKaWYociE9bnVs
+bCYmcz49cilyZXR1cm4gbmV3IEguTUIocS4kdGkuQygiTUI8MT4iKSkKcmV0dXJuIEgucUMocS5hLHMs
+cixxLiR0aS5jKX0sCnR0OmZ1bmN0aW9uKGEsYil7dmFyIHMscixxLHA9dGhpcyxvPXAuYixuPXAuYSxt
+PUouVTYobiksbD1tLmdBKG4pLGs9cC5jCmlmKGshPW51bGwmJms8bClsPWsKaWYodHlwZW9mIGwhPT0i
+bnVtYmVyIilyZXR1cm4gbC5ITigpCnM9bC1vCmlmKHM8PTApe249Si5RaSgwLHAuJHRpLmMpCnJldHVy
+biBufXI9UC5POChzLG0uRShuLG8pLCExLHAuJHRpLmMpCmZvcihxPTE7cTxzOysrcSl7Qy5ObS5ZNShy
+LHEsbS5FKG4sbytxKSkKaWYobS5nQShuKTxsKXRocm93IEguYihQLmE0KHApKX1yZXR1cm4gcn19Ckgu
+YTcucHJvdG90eXBlPXsKZ2w6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5kfSwKRjpmdW5jdGlvbigpe3Zh
+ciBzLHI9dGhpcyxxPXIuYSxwPUouVTYocSksbz1wLmdBKHEpCmlmKHIuYiE9PW8pdGhyb3cgSC5iKFAu
+YTQocSkpCnM9ci5jCmlmKHM+PW8pe3Iuc0kobnVsbCkKcmV0dXJuITF9ci5zSShwLkUocSxzKSk7Kyty
+LmMKcmV0dXJuITB9LApzSTpmdW5jdGlvbihhKXt0aGlzLmQ9dGhpcy4kdGkuQygiMT8iKS5hKGEpfSwK
+JGlBbjoxfQpILmkxLnByb3RvdHlwZT17CmdtOmZ1bmN0aW9uKGEpe3ZhciBzPUguTGgodGhpcykKcmV0
+dXJuIG5ldyBILk1IKEouSVQodGhpcy5hKSx0aGlzLmIscy5DKCJAPDE+IikuS3Eocy5RWzFdKS5DKCJN
+SDwxLDI+IikpfSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIEouSG0odGhpcy5hKX0sCmdsMDpmdW5jdGlv
+bihhKXtyZXR1cm4gSi51VSh0aGlzLmEpfSwKRTpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLmIuJDEo
+Si5HQSh0aGlzLmEsYikpfX0KSC54eS5wcm90b3R5cGU9eyRpYlE6MX0KSC5NSC5wcm90b3R5cGU9ewpG
+OmZ1bmN0aW9uKCl7dmFyIHM9dGhpcyxyPXMuYgppZihyLkYoKSl7cy5zSShzLmMuJDEoci5nbCgpKSkK
+cmV0dXJuITB9cy5zSShudWxsKQpyZXR1cm4hMX0sCmdsOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuYX0s
+CnNJOmZ1bmN0aW9uKGEpe3RoaXMuYT10aGlzLiR0aS5DKCIyPyIpLmEoYSl9fQpILmxKLnByb3RvdHlw
+ZT17CmdBOmZ1bmN0aW9uKGEpe3JldHVybiBKLkhtKHRoaXMuYSl9LApFOmZ1bmN0aW9uKGEsYil7cmV0
+dXJuIHRoaXMuYi4kMShKLkdBKHRoaXMuYSxiKSl9fQpILlU1LnByb3RvdHlwZT17CmdtOmZ1bmN0aW9u
+KGEpe3JldHVybiBuZXcgSC5TTyhKLklUKHRoaXMuYSksdGhpcy5iLHRoaXMuJHRpLkMoIlNPPDE+Iikp
+fX0KSC5TTy5wcm90b3R5cGU9ewpGOmZ1bmN0aW9uKCl7dmFyIHMscgpmb3Iocz10aGlzLmEscj10aGlz
+LmI7cy5GKCk7KWlmKEgub1Qoci4kMShzLmdsKCkpKSlyZXR1cm4hMApyZXR1cm4hMX0sCmdsOmZ1bmN0
+aW9uKCl7cmV0dXJuIHRoaXMuYS5nbCgpfX0KSC5BTS5wcm90b3R5cGU9ewplUjpmdW5jdGlvbihhLGIp
+e1AuazEoYiwiY291bnQiKQpyZXR1cm4gbmV3IEguQU0odGhpcy5hLHRoaXMuYitiLEguTGgodGhpcyku
+QygiQU08MT4iKSl9LApnbTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IEguVTEoSi5JVCh0aGlzLmEpLHRo
+aXMuYixILkxoKHRoaXMpLkMoIlUxPDE+IikpfX0KSC5kNS5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihh
+KXt2YXIgcz1KLkhtKHRoaXMuYSktdGhpcy5iCmlmKHM+PTApcmV0dXJuIHMKcmV0dXJuIDB9LAplUjpm
+dW5jdGlvbihhLGIpe1AuazEoYiwiY291bnQiKQpyZXR1cm4gbmV3IEguZDUodGhpcy5hLHRoaXMuYiti
+LHRoaXMuJHRpKX0sCiRpYlE6MX0KSC5VMS5wcm90b3R5cGU9ewpGOmZ1bmN0aW9uKCl7dmFyIHMscgpm
+b3Iocz10aGlzLmEscj0wO3I8dGhpcy5iOysrcilzLkYoKQp0aGlzLmI9MApyZXR1cm4gcy5GKCl9LApn
+bDpmdW5jdGlvbigpe3JldHVybiB0aGlzLmEuZ2woKX19CkguTUIucHJvdG90eXBlPXsKZ206ZnVuY3Rp
+b24oYSl7cmV0dXJuIEMuR3d9LApnbDA6ZnVuY3Rpb24oYSl7cmV0dXJuITB9LApnQTpmdW5jdGlvbihh
+KXtyZXR1cm4gMH0sCkU6ZnVuY3Rpb24oYSxiKXt0aHJvdyBILmIoUC5URShiLDAsMCwiaW5kZXgiLG51
+bGwpKX0sCmVSOmZ1bmN0aW9uKGEsYil7UC5rMShiLCJjb3VudCIpCnJldHVybiB0aGlzfX0KSC5GdS5w
+cm90b3R5cGU9ewpGOmZ1bmN0aW9uKCl7cmV0dXJuITF9LApnbDpmdW5jdGlvbigpe3Rocm93IEguYihI
+LldwKCkpfSwKJGlBbjoxfQpILnU2LnByb3RvdHlwZT17CmdtOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcg
+SC5KQihKLklUKHRoaXMuYSksdGhpcy4kdGkuQygiSkI8MT4iKSl9fQpILkpCLnByb3RvdHlwZT17CkY6
+ZnVuY3Rpb24oKXt2YXIgcyxyCmZvcihzPXRoaXMuYSxyPXRoaXMuJHRpLmM7cy5GKCk7KWlmKHIuYihz
+LmdsKCkpKXJldHVybiEwCnJldHVybiExfSwKZ2w6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy4kdGkuYy5h
+KHRoaXMuYS5nbCgpKX0sCiRpQW46MX0KSC5TVS5wcm90b3R5cGU9e30KSC5SZS5wcm90b3R5cGU9ewpZ
+NTpmdW5jdGlvbihhLGIsYyl7SC5MaCh0aGlzKS5DKCJSZS5FIikuYShjKQp0aHJvdyBILmIoUC5MNCgi
+Q2Fubm90IG1vZGlmeSBhbiB1bm1vZGlmaWFibGUgbGlzdCIpKX19CkgudzIucHJvdG90eXBlPXt9Ckgu
+d3YucHJvdG90eXBlPXsKZ2lPOmZ1bmN0aW9uKGEpe3ZhciBzPXRoaXMuX2hhc2hDb2RlCmlmKHMhPW51
+bGwpcmV0dXJuIHMKcz02NjQ1OTcqSi5oZih0aGlzLmEpJjUzNjg3MDkxMQp0aGlzLl9oYXNoQ29kZT1z
+CnJldHVybiBzfSwKdzpmdW5jdGlvbihhKXtyZXR1cm4nU3ltYm9sKCInK0guRWoodGhpcy5hKSsnIikn
+fSwKRE46ZnVuY3Rpb24oYSxiKXtpZihiPT1udWxsKXJldHVybiExCnJldHVybiBiIGluc3RhbmNlb2Yg
+SC53diYmdGhpcy5hPT1iLmF9LAokaUdEOjF9CkguUUMucHJvdG90eXBlPXt9CkguUEQucHJvdG90eXBl
+PXt9CkguV1UucHJvdG90eXBlPXsKZ2wwOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmdBKHRoaXMpPT09
+MH0sCnc6ZnVuY3Rpb24oYSl7cmV0dXJuIFAubk8odGhpcyl9LApZNTpmdW5jdGlvbihhLGIsYyl7dmFy
+IHM9SC5MaCh0aGlzKQpzLmMuYShiKQpzLlFbMV0uYShjKQpILmRjKCkKSC5CaSh1LmcpfSwKZ1B1OmZ1
+bmN0aW9uKGEpe3JldHVybiB0aGlzLnE0KDAsSC5MaCh0aGlzKS5DKCJOMzwxLDI+IikpfSwKcTQ6ZnVu
+Y3Rpb24oYSxiKXt2YXIgcz10aGlzCnJldHVybiBQLmwwKGZ1bmN0aW9uKCl7dmFyIHI9YQp2YXIgcT0w
+LHA9MSxvLG4sbSxsLGsKcmV0dXJuIGZ1bmN0aW9uICRhc3luYyRnUHUoYyxkKXtpZihjPT09MSl7bz1k
+CnE9cH13aGlsZSh0cnVlKXN3aXRjaChxKXtjYXNlIDA6bj1zLmd2YygpLG49bi5nbShuKSxtPUguTGgo
+cyksbT1tLkMoIkA8MT4iKS5LcShtLlFbMV0pLkMoIk4zPDEsMj4iKQpjYXNlIDI6aWYoIW4uRigpKXtx
+PTMKYnJlYWt9bD1uLmdsKCkKaz1zLnEoMCxsKQprLnRvU3RyaW5nCnE9NApyZXR1cm4gbmV3IFAuTjMo
+bCxrLG0pCmNhc2UgNDpxPTIKYnJlYWsKY2FzZSAzOnJldHVybiBQLlRoKCkKY2FzZSAxOnJldHVybiBQ
+LlltKG8pfX19LGIpfSwKJGlaMDoxfQpILkxQLnByb3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3JldHVy
+biB0aGlzLmF9LAp4NDpmdW5jdGlvbihhKXtpZih0eXBlb2YgYSE9InN0cmluZyIpcmV0dXJuITEKaWYo
+Il9fcHJvdG9fXyI9PT1hKXJldHVybiExCnJldHVybiB0aGlzLmIuaGFzT3duUHJvcGVydHkoYSl9LApx
+OmZ1bmN0aW9uKGEsYil7aWYoIXRoaXMueDQoYikpcmV0dXJuIG51bGwKcmV0dXJuIHRoaXMucVAoYil9
+LApxUDpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5iW0guaChhKV19LApLOmZ1bmN0aW9uKGEsYil7dmFy
+IHMscixxLHAsbz1ILkxoKHRoaXMpCm8uQygifigxLDIpIikuYShiKQpzPXRoaXMuYwpmb3Iocj1zLmxl
+bmd0aCxvPW8uUVsxXSxxPTA7cTxyOysrcSl7cD1zW3FdCmIuJDIocCxvLmEodGhpcy5xUChwKSkpfX0s
+Cmd2YzpmdW5jdGlvbigpe3JldHVybiBuZXcgSC5YUih0aGlzLEguTGgodGhpcykuQygiWFI8MT4iKSl9
+fQpILlhSLnByb3RvdHlwZT17CmdtOmZ1bmN0aW9uKGEpe3ZhciBzPXRoaXMuYS5jCnJldHVybiBuZXcg
+Si5tMShzLHMubGVuZ3RoLEgudDYocykuQygibTE8MT4iKSl9LApnQTpmdW5jdGlvbihhKXtyZXR1cm4g
+dGhpcy5hLmMubGVuZ3RofX0KSC5MSS5wcm90b3R5cGU9ewpnV2E6ZnVuY3Rpb24oKXt2YXIgcz10aGlz
+LmEKcmV0dXJuIHN9LApnbmQ6ZnVuY3Rpb24oKXt2YXIgcyxyLHEscCxvPXRoaXMKaWYoby5jPT09MSly
+ZXR1cm4gQy5oVQpzPW8uZApyPXMubGVuZ3RoLW8uZS5sZW5ndGgtby5mCmlmKHI9PT0wKXJldHVybiBD
+LmhVCnE9W10KZm9yKHA9MDtwPHI7KytwKXtpZihwPj1zLmxlbmd0aClyZXR1cm4gSC5PSChzLHApCnEu
+cHVzaChzW3BdKX1yZXR1cm4gSi56QyhxKX0sCmdWbTpmdW5jdGlvbigpe3ZhciBzLHIscSxwLG8sbixt
+LGwsaz10aGlzCmlmKGsuYyE9PTApcmV0dXJuIEMuV08Kcz1rLmUKcj1zLmxlbmd0aApxPWsuZApwPXEu
+bGVuZ3RoLXItay5mCmlmKHI9PT0wKXJldHVybiBDLldPCm89bmV3IEguTjUodC5lbykKZm9yKG49MDtu
+PHI7KytuKXtpZihuPj1zLmxlbmd0aClyZXR1cm4gSC5PSChzLG4pCm09c1tuXQpsPXArbgppZihsPDB8
+fGw+PXEubGVuZ3RoKXJldHVybiBILk9IKHEsbCkKby5ZNSgwLG5ldyBILnd2KG0pLHFbbF0pfXJldHVy
+biBuZXcgSC5QRChvLHQuZ0YpfSwKJGl2UToxfQpILkNqLnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEs
+Yil7dmFyIHMKSC5oKGEpCnM9dGhpcy5hCnMuYj1zLmIrIiQiK0guRWooYSkKQy5ObS5pKHRoaXMuYixh
+KQpDLk5tLmkodGhpcy5jLGIpOysrcy5hfSwKJFM6MTN9CkguZjkucHJvdG90eXBlPXsKcVM6ZnVuY3Rp
+b24oYSl7dmFyIHMscixxPXRoaXMscD1uZXcgUmVnRXhwKHEuYSkuZXhlYyhhKQppZihwPT1udWxsKXJl
+dHVybiBudWxsCnM9T2JqZWN0LmNyZWF0ZShudWxsKQpyPXEuYgppZihyIT09LTEpcy5hcmd1bWVudHM9
+cFtyKzFdCnI9cS5jCmlmKHIhPT0tMSlzLmFyZ3VtZW50c0V4cHI9cFtyKzFdCnI9cS5kCmlmKHIhPT0t
+MSlzLmV4cHI9cFtyKzFdCnI9cS5lCmlmKHIhPT0tMSlzLm1ldGhvZD1wW3IrMV0Kcj1xLmYKaWYociE9
+PS0xKXMucmVjZWl2ZXI9cFtyKzFdCnJldHVybiBzfX0KSC5XMC5wcm90b3R5cGU9ewp3OmZ1bmN0aW9u
+KGEpe3ZhciBzPXRoaXMuYgppZihzPT1udWxsKXJldHVybiJOb1N1Y2hNZXRob2RFcnJvcjogIitILkVq
+KHRoaXMuYSkKcmV0dXJuIk5vU3VjaE1ldGhvZEVycm9yOiBtZXRob2Qgbm90IGZvdW5kOiAnIitzKyIn
+IG9uIG51bGwifX0KSC5hei5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3ZhciBzLHI9dGhpcyxxPSJO
+b1N1Y2hNZXRob2RFcnJvcjogbWV0aG9kIG5vdCBmb3VuZDogJyIscD1yLmIKaWYocD09bnVsbClyZXR1
+cm4iTm9TdWNoTWV0aG9kRXJyb3I6ICIrSC5FaihyLmEpCnM9ci5jCmlmKHM9PW51bGwpcmV0dXJuIHEr
+cCsiJyAoIitILkVqKHIuYSkrIikiCnJldHVybiBxK3ArIicgb24gJyIrcysiJyAoIitILkVqKHIuYSkr
+IikifX0KSC52Vi5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3ZhciBzPXRoaXMuYQpyZXR1cm4gcy5s
+ZW5ndGg9PT0wPyJFcnJvciI6IkVycm9yOiAiK3N9fQpILnRlLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24o
+YSl7cmV0dXJuIlRocm93IG9mIG51bGwgKCciKyh0aGlzLmE9PT1udWxsPyJudWxsIjoidW5kZWZpbmVk
+IikrIicgZnJvbSBKYXZhU2NyaXB0KSJ9LAokaVJ6OjF9CkguYnEucHJvdG90eXBlPXt9CkguWE8ucHJv
+dG90eXBlPXsKdzpmdW5jdGlvbihhKXt2YXIgcyxyPXRoaXMuYgppZihyIT1udWxsKXJldHVybiByCnI9
+dGhpcy5hCnM9ciE9PW51bGwmJnR5cGVvZiByPT09Im9iamVjdCI/ci5zdGFjazpudWxsCnJldHVybiB0
+aGlzLmI9cz09bnVsbD8iIjpzfSwKJGlHejoxfQpILlRwLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7
+dmFyIHM9dGhpcy5jb25zdHJ1Y3RvcixyPXM9PW51bGw/bnVsbDpzLm5hbWUKcmV0dXJuIkNsb3N1cmUg
+JyIrSC5OUShyPT1udWxsPyJ1bmtub3duIjpyKSsiJyJ9LAokaUVIOjEsCmdLdTpmdW5jdGlvbigpe3Jl
+dHVybiB0aGlzfSwKJEM6IiQxIiwKJFI6MSwKJEQ6bnVsbH0KSC5sYy5wcm90b3R5cGU9e30KSC56eC5w
+cm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3ZhciBzPXRoaXMuJHN0YXRpY19uYW1lCmlmKHM9PW51bGwp
+cmV0dXJuIkNsb3N1cmUgb2YgdW5rbm93biBzdGF0aWMgbWV0aG9kIgpyZXR1cm4iQ2xvc3VyZSAnIitI
+Lk5RKHMpKyInIn19CkguclQucHJvdG90eXBlPXsKRE46ZnVuY3Rpb24oYSxiKXt2YXIgcz10aGlzCmlm
+KGI9PW51bGwpcmV0dXJuITEKaWYocz09PWIpcmV0dXJuITAKaWYoIShiIGluc3RhbmNlb2YgSC5yVCkp
+cmV0dXJuITEKcmV0dXJuIHMuYT09PWIuYSYmcy5iPT09Yi5iJiZzLmM9PT1iLmN9LApnaU86ZnVuY3Rp
+b24oYSl7dmFyIHMscj10aGlzLmMKaWYocj09bnVsbClzPUguZVEodGhpcy5hKQplbHNlIHM9dHlwZW9m
+IHIhPT0ib2JqZWN0Ij9KLmhmKHIpOkguZVEocikKcj1ILmVRKHRoaXMuYikKaWYodHlwZW9mIHMhPT0i
+bnVtYmVyIilyZXR1cm4gcy5ZKCkKcmV0dXJuKHNecik+Pj4wfSwKdzpmdW5jdGlvbihhKXt2YXIgcz10
+aGlzLmMKaWYocz09bnVsbClzPXRoaXMuYQpyZXR1cm4iQ2xvc3VyZSAnIitILkVqKHRoaXMuZCkrIicg
+b2YgIisoIkluc3RhbmNlIG9mICciK0guRWooSC5NKHMpKSsiJyIpfX0KSC5FcS5wcm90b3R5cGU9ewp3
+OmZ1bmN0aW9uKGEpe3JldHVybiJSdW50aW1lRXJyb3I6ICIrdGhpcy5hfX0KSC5rWS5wcm90b3R5cGU9
+ewp3OmZ1bmN0aW9uKGEpe3JldHVybiJBc3NlcnRpb24gZmFpbGVkOiAiK1AucCh0aGlzLmEpfX0KSC5r
+ci5wcm90b3R5cGU9e30KSC5ONS5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5h
+fSwKZ2wwOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmE9PT0wfSwKZ3ZjOmZ1bmN0aW9uKCl7cmV0dXJu
+IG5ldyBILmk1KHRoaXMsSC5MaCh0aGlzKS5DKCJpNTwxPiIpKX0sCng0OmZ1bmN0aW9uKGEpe3ZhciBz
+LHIKaWYodHlwZW9mIGE9PSJzdHJpbmciKXtzPXRoaXMuYgppZihzPT1udWxsKXJldHVybiExCnJldHVy
+biB0aGlzLlh1KHMsYSl9ZWxzZXtyPXRoaXMuQ1goYSkKcmV0dXJuIHJ9fSwKQ1g6ZnVuY3Rpb24oYSl7
+dmFyIHM9dGhpcy5kCmlmKHM9PW51bGwpcmV0dXJuITEKcmV0dXJuIHRoaXMuRmgodGhpcy5CdChzLEou
+aGYoYSkmMHgzZmZmZmZmKSxhKT49MH0sCnE6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEscCxvPXRoaXMs
+bj1udWxsCmlmKHR5cGVvZiBiPT0ic3RyaW5nIil7cz1vLmIKaWYocz09bnVsbClyZXR1cm4gbgpyPW8u
+ajIocyxiKQpxPXI9PW51bGw/bjpyLmIKcmV0dXJuIHF9ZWxzZSBpZih0eXBlb2YgYj09Im51bWJlciIm
+JihiJjB4M2ZmZmZmZik9PT1iKXtwPW8uYwppZihwPT1udWxsKXJldHVybiBuCnI9by5qMihwLGIpCnE9
+cj09bnVsbD9uOnIuYgpyZXR1cm4gcX1lbHNlIHJldHVybiBvLmFhKGIpfSwKYWE6ZnVuY3Rpb24oYSl7
+dmFyIHMscixxPXRoaXMuZAppZihxPT1udWxsKXJldHVybiBudWxsCnM9dGhpcy5CdChxLEouaGYoYSkm
+MHgzZmZmZmZmKQpyPXRoaXMuRmgocyxhKQppZihyPDApcmV0dXJuIG51bGwKcmV0dXJuIHNbcl0uYn0s
+Clk1OmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyLHEscCxvLG4sbT10aGlzLGw9SC5MaChtKQpsLmMuYShi
+KQpsLlFbMV0uYShjKQppZih0eXBlb2YgYj09InN0cmluZyIpe3M9bS5iCm0uRUgocz09bnVsbD9tLmI9
+bS56SygpOnMsYixjKX1lbHNlIGlmKHR5cGVvZiBiPT0ibnVtYmVyIiYmKGImMHgzZmZmZmZmKT09PWIp
+e3I9bS5jCm0uRUgocj09bnVsbD9tLmM9bS56SygpOnIsYixjKX1lbHNle3E9bS5kCmlmKHE9PW51bGwp
+cT1tLmQ9bS56SygpCnA9Si5oZihiKSYweDNmZmZmZmYKbz1tLkJ0KHEscCkKaWYobz09bnVsbCltLkVJ
+KHEscCxbbS5IbihiLGMpXSkKZWxzZXtuPW0uRmgobyxiKQppZihuPj0wKW9bbl0uYj1jCmVsc2Ugby5w
+dXNoKG0uSG4oYixjKSl9fX0sCks6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHE9dGhpcwpILkxoKHEpLkMo
+In4oMSwyKSIpLmEoYikKcz1xLmUKcj1xLnIKZm9yKDtzIT1udWxsOyl7Yi4kMihzLmEscy5iKQppZihy
+IT09cS5yKXRocm93IEguYihQLmE0KHEpKQpzPXMuY319LApFSDpmdW5jdGlvbihhLGIsYyl7dmFyIHMs
+cj10aGlzLHE9SC5MaChyKQpxLmMuYShiKQpxLlFbMV0uYShjKQpzPXIuajIoYSxiKQppZihzPT1udWxs
+KXIuRUkoYSxiLHIuSG4oYixjKSkKZWxzZSBzLmI9Y30sCmtzOmZ1bmN0aW9uKCl7dGhpcy5yPXRoaXMu
+cisxJjY3MTA4ODYzfSwKSG46ZnVuY3Rpb24oYSxiKXt2YXIgcz10aGlzLHI9SC5MaChzKSxxPW5ldyBI
+LnZoKHIuYy5hKGEpLHIuUVsxXS5hKGIpKQppZihzLmU9PW51bGwpcy5lPXMuZj1xCmVsc2V7cj1zLmYK
+ci50b1N0cmluZwpxLmQ9cgpzLmY9ci5jPXF9KytzLmEKcy5rcygpCnJldHVybiBxfSwKRmg6ZnVuY3Rp
+b24oYSxiKXt2YXIgcyxyCmlmKGE9PW51bGwpcmV0dXJuLTEKcz1hLmxlbmd0aApmb3Iocj0wO3I8czsr
+K3IpaWYoSi5STShhW3JdLmEsYikpcmV0dXJuIHIKcmV0dXJuLTF9LAp3OmZ1bmN0aW9uKGEpe3JldHVy
+biBQLm5PKHRoaXMpfSwKajI6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gYVtiXX0sCkJ0OmZ1bmN0aW9uKGEs
+Yil7cmV0dXJuIGFbYl19LApFSTpmdW5jdGlvbihhLGIsYyl7YVtiXT1jfSwKcm46ZnVuY3Rpb24oYSxi
+KXtkZWxldGUgYVtiXX0sClh1OmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuajIoYSxiKSE9bnVsbH0s
+CnpLOmZ1bmN0aW9uKCl7dmFyIHM9Ijxub24taWRlbnRpZmllci1rZXk+IixyPU9iamVjdC5jcmVhdGUo
+bnVsbCkKdGhpcy5FSShyLHMscikKdGhpcy5ybihyLHMpCnJldHVybiByfSwKJGlGbzoxfQpILnZoLnBy
+b3RvdHlwZT17fQpILmk1LnByb3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmEuYX0s
+CmdsMDpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hLmE9PT0wfSwKZ206ZnVuY3Rpb24oYSl7dmFyIHM9
+dGhpcy5hLHI9bmV3IEguTjYocyxzLnIsdGhpcy4kdGkuQygiTjY8MT4iKSkKci5jPXMuZQpyZXR1cm4g
+cn0sCnRnOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuYS54NChiKX19CkguTjYucHJvdG90eXBlPXsK
+Z2w6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5kfSwKRjpmdW5jdGlvbigpe3ZhciBzLHI9dGhpcyxxPXIu
+YQppZihyLmIhPT1xLnIpdGhyb3cgSC5iKFAuYTQocSkpCnM9ci5jCmlmKHM9PW51bGwpe3Iuc3FZKG51
+bGwpCnJldHVybiExfWVsc2V7ci5zcVkocy5hKQpyLmM9cy5jCnJldHVybiEwfX0sCnNxWTpmdW5jdGlv
+bihhKXt0aGlzLmQ9dGhpcy4kdGkuQygiMT8iKS5hKGEpfSwKJGlBbjoxfQpILmRDLnByb3RvdHlwZT17
+CiQxOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmEoYSl9LAokUzo0fQpILndOLnByb3RvdHlwZT17CiQy
+OmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuYShhLGIpfSwKJFM6MzR9CkguVlgucHJvdG90eXBlPXsK
+JDE6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYShILmgoYSkpfSwKJFM6MzJ9CkguVlIucHJvdG90eXBl
+PXsKdzpmdW5jdGlvbihhKXtyZXR1cm4iUmVnRXhwLyIrdGhpcy5hKyIvIit0aGlzLmIuZmxhZ3N9LApn
+SGM6ZnVuY3Rpb24oKXt2YXIgcz10aGlzLHI9cy5jCmlmKHIhPW51bGwpcmV0dXJuIHIKcj1zLmIKcmV0
+dXJuIHMuYz1ILnY0KHMuYSxyLm11bHRpbGluZSwhci5pZ25vcmVDYXNlLHIudW5pY29kZSxyLmRvdEFs
+bCwhMCl9LApkZDpmdW5jdGlvbihhLGIpe3JldHVybiBuZXcgSC5LVyh0aGlzLGIsMCl9LApVWjpmdW5j
+dGlvbihhLGIpe3ZhciBzLHI9dGhpcy5nSGMoKQpyLmxhc3RJbmRleD1iCnM9ci5leGVjKGEpCmlmKHM9
+PW51bGwpcmV0dXJuIG51bGwKcmV0dXJuIG5ldyBILkVLKHMpfSwKJGl2WDoxLAokaXdMOjF9CkguRUsu
+cHJvdG90eXBlPXsKcTpmdW5jdGlvbihhLGIpe3ZhciBzCkgudVAoYikKcz10aGlzLmIKaWYoYj49cy5s
+ZW5ndGgpcmV0dXJuIEguT0gocyxiKQpyZXR1cm4gc1tiXX0sCiRpT2Q6MSwKJGlpYjoxfQpILktXLnBy
+b3RvdHlwZT17CmdtOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgSC5QYih0aGlzLmEsdGhpcy5iLHRoaXMu
+Yyl9fQpILlBiLnByb3RvdHlwZT17CmdsOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuZH0sCkY6ZnVuY3Rp
+b24oKXt2YXIgcyxyLHEscCxvLG4sbT10aGlzLGw9bS5iCmlmKGw9PW51bGwpcmV0dXJuITEKcz1tLmMK
+cj1sLmxlbmd0aAppZihzPD1yKXtxPW0uYQpwPXEuVVoobCxzKQppZihwIT1udWxsKXttLmQ9cApzPXAu
+YgpvPXMuaW5kZXgKbj1vK3NbMF0ubGVuZ3RoCmlmKG89PT1uKXtpZihxLmIudW5pY29kZSl7cz1tLmMK
+cT1zKzEKaWYocTxyKXtzPUMueEIuTyhsLHMpCmlmKHM+PTU1Mjk2JiZzPD01NjMxOSl7cz1DLnhCLk8o
+bCxxKQpzPXM+PTU2MzIwJiZzPD01NzM0M31lbHNlIHM9ITF9ZWxzZSBzPSExfWVsc2Ugcz0hMQpuPShz
+P24rMTpuKSsxfW0uYz1uCnJldHVybiEwfX1tLmI9bS5kPW51bGwKcmV0dXJuITF9LAokaUFuOjF9Ckgu
+dFEucHJvdG90eXBlPXsKcTpmdW5jdGlvbihhLGIpe0gudVAoYikKaWYoYiE9PTApSC52KFAuTzcoYixu
+dWxsKSkKcmV0dXJuIHRoaXMuY30sCiRpT2Q6MX0KSC51bi5wcm90b3R5cGU9ewpnbTpmdW5jdGlvbihh
+KXtyZXR1cm4gbmV3IEguU2QodGhpcy5hLHRoaXMuYix0aGlzLmMpfX0KSC5TZC5wcm90b3R5cGU9ewpG
+OmZ1bmN0aW9uKCl7dmFyIHMscixxPXRoaXMscD1xLmMsbz1xLmIsbj1vLmxlbmd0aCxtPXEuYSxsPW0u
+bGVuZ3RoCmlmKHArbj5sKXtxLmQ9bnVsbApyZXR1cm4hMX1zPW0uaW5kZXhPZihvLHApCmlmKHM8MCl7
+cS5jPWwrMQpxLmQ9bnVsbApyZXR1cm4hMX1yPXMrbgpxLmQ9bmV3IEgudFEocyxvKQpxLmM9cj09PXEu
+Yz9yKzE6cgpyZXR1cm4hMH0sCmdsOmZ1bmN0aW9uKCl7dmFyIHM9dGhpcy5kCnMudG9TdHJpbmcKcmV0
+dXJuIHN9LAokaUFuOjF9CkguRVQucHJvdG90eXBlPXskaUVUOjEsJGlBUzoxfQpILkxaLnByb3RvdHlw
+ZT17CmdBOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxlbmd0aH0sCiRpWGo6MX0KSC5EZy5wcm90b3R5cGU9
+ewpxOmZ1bmN0aW9uKGEsYil7SC51UChiKQpILm9kKGIsYSxhLmxlbmd0aCkKcmV0dXJuIGFbYl19LApZ
+NTpmdW5jdGlvbihhLGIsYyl7SC5HSChjKQpILm9kKGIsYSxhLmxlbmd0aCkKYVtiXT1jfSwKJGliUTox
+LAokaWNYOjEsCiRpek06MX0KSC5QZy5wcm90b3R5cGU9ewpZNTpmdW5jdGlvbihhLGIsYyl7SC51UChj
+KQpILm9kKGIsYSxhLmxlbmd0aCkKYVtiXT1jfSwKJGliUToxLAokaWNYOjEsCiRpek06MX0KSC54ai5w
 cm90b3R5cGU9ewpxOmZ1bmN0aW9uKGEsYil7SC51UChiKQpILm9kKGIsYSxhLmxlbmd0aCkKcmV0dXJu
-IGFbYl19fQpILmVFLnByb3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxlbmd0aH0sCnE6
-ZnVuY3Rpb24oYSxiKXtILnVQKGIpCkgub2QoYixhLGEubGVuZ3RoKQpyZXR1cm4gYVtiXX19CkguVjYu
-cHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVuZ3RofSwKcTpmdW5jdGlvbihhLGIp
-e0gudVAoYikKSC5vZChiLGEsYS5sZW5ndGgpCnJldHVybiBhW2JdfSwKJGlWNjoxLAokaW42OjF9Ckgu
-UkcucHJvdG90eXBlPXt9CkguVlAucHJvdG90eXBlPXt9CkguV0IucHJvdG90eXBlPXt9CkguWkcucHJv
-dG90eXBlPXt9CkguSmMucHJvdG90eXBlPXsKQzpmdW5jdGlvbihhKXtyZXR1cm4gSC5jRSh2LnR5cGVV
-bml2ZXJzZSx0aGlzLGEpfSwKS3E6ZnVuY3Rpb24oYSl7cmV0dXJuIEgudjUodi50eXBlVW5pdmVyc2Us
-dGhpcyxhKX19CkguRy5wcm90b3R5cGU9e30KSC5sWS5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3Jl
-dHVybiBILmRtKHRoaXMuYSxudWxsKX19Ckgua1MucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1
-cm4gdGhpcy5hfX0KSC5pTS5wcm90b3R5cGU9e30KUC50aC5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihh
-KXt2YXIgcz10aGlzLmEscj1zLmEKcy5hPW51bGwKci4kMCgpfSwKJFM6MTB9ClAuaGEucHJvdG90eXBl
-PXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHMscgp0aGlzLmEuYT10Lk0uYShhKQpzPXRoaXMuYgpyPXRoaXMu
-YwpzLmZpcnN0Q2hpbGQ/cy5yZW1vdmVDaGlsZChyKTpzLmFwcGVuZENoaWxkKHIpfSwKJFM6NTJ9ClAu
-VnMucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXt0aGlzLmEuJDAoKX0sCiRDOiIkMCIsCiRSOjAsCiRT
-OjJ9ClAuRnQucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXt0aGlzLmEuJDAoKX0sCiRDOiIkMCIsCiRS
-OjAsCiRTOjJ9ClAuVzMucHJvdG90eXBlPXsKQ1k6ZnVuY3Rpb24oYSxiKXtpZihzZWxmLnNldFRpbWVv
-dXQhPW51bGwpc2VsZi5zZXRUaW1lb3V0KEgudFIobmV3IFAueUgodGhpcyxiKSwwKSxhKQplbHNlIHRo
-cm93IEguYihQLkw0KCJgc2V0VGltZW91dCgpYCBub3QgZm91bmQuIikpfX0KUC55SC5wcm90b3R5cGU9
-ewokMDpmdW5jdGlvbigpe3RoaXMuYi4kMCgpfSwKJEM6IiQwIiwKJFI6MCwKJFM6MH0KUC5paC5wcm90
-b3R5cGU9ewphTTpmdW5jdGlvbihhLGIpe3ZhciBzLHI9dGhpcyxxPXIuJHRpCnEuQygiMS8/IikuYShi
-KQppZighci5iKXIuYS5YZihiKQplbHNle3M9ci5hCmlmKHEuQygiYjg8MT4iKS5iKGIpKXMuY1UoYikK
-ZWxzZSBzLlgyKHEuYy5hKGIpKX19LAp3MDpmdW5jdGlvbihhLGIpe3ZhciBzCmlmKGI9PW51bGwpYj1Q
-LnYwKGEpCnM9dGhpcy5hCmlmKHRoaXMuYilzLlpMKGEsYikKZWxzZSBzLk5rKGEsYil9fQpQLldNLnBy
-b3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmEuJDIoMCxhKX0sCiRTOjQzfQpQLlNY
-LnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7dGhpcy5hLiQyKDEsbmV3IEguYnEoYSx0LmwuYShi
-KSkpfSwKJEM6IiQyIiwKJFI6MiwKJFM6NTR9ClAuR3MucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxi
-KXt0aGlzLmEoSC51UChhKSxiKX0sCiRTOjI0fQpQLkZ5LnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7
-cmV0dXJuIkl0ZXJhdGlvbk1hcmtlcigiK3RoaXMuYisiLCAiK0guRWoodGhpcy5hKSsiKSJ9fQpQLkdW
-LnByb3RvdHlwZT17CmdsOmZ1bmN0aW9uKCl7dmFyIHM9dGhpcy5jCmlmKHM9PW51bGwpcmV0dXJuIHRo
-aXMuJHRpLmMuYSh0aGlzLmIpCnJldHVybiBzLmdsKCl9LApGOmZ1bmN0aW9uKCl7dmFyIHMscixxLHAs
-byxuLG09dGhpcwpmb3Iocz1tLiR0aS5DKCJBbjwxPiIpOyEwOyl7cj1tLmMKaWYociE9bnVsbClpZihy
-LkYoKSlyZXR1cm4hMAplbHNlIG0uc1g5KG51bGwpCnE9ZnVuY3Rpb24oYSxiLGMpe3ZhciBsLGs9Ygp3
-aGlsZSh0cnVlKXRyeXtyZXR1cm4gYShrLGwpfWNhdGNoKGope2w9agprPWN9fShtLmEsMCwxKQppZihx
-IGluc3RhbmNlb2YgUC5GeSl7cD1xLmIKaWYocD09PTIpe289bS5kCmlmKG89PW51bGx8fG8ubGVuZ3Ro
-PT09MCl7bS5zRUMobnVsbCkKcmV0dXJuITF9aWYoMD49by5sZW5ndGgpcmV0dXJuIEguT0gobywtMSkK
-bS5hPW8ucG9wKCkKY29udGludWV9ZWxzZXtyPXEuYQppZihwPT09Myl0aHJvdyByCmVsc2V7bj1zLmEo
-Si5JVChyKSkKaWYobiBpbnN0YW5jZW9mIFAuR1Ype3I9bS5kCmlmKHI9PW51bGwpcj1tLmQ9W10KQy5O
-bS5pKHIsbS5hKQptLmE9bi5hCmNvbnRpbnVlfWVsc2V7bS5zWDkobikKY29udGludWV9fX19ZWxzZXtt
-LnNFQyhxKQpyZXR1cm4hMH19cmV0dXJuITF9LApzRUM6ZnVuY3Rpb24oYSl7dGhpcy5iPXRoaXMuJHRp
-LkMoIjE/IikuYShhKX0sCnNYOTpmdW5jdGlvbihhKXt0aGlzLmM9dGhpcy4kdGkuQygiQW48MT4/Iiku
-YShhKX0sCiRpQW46MX0KUC5xNC5wcm90b3R5cGU9ewpnbTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFAu
-R1YodGhpcy5hKCksdGhpcy4kdGkuQygiR1Y8MT4iKSl9fQpQLkN3LnByb3RvdHlwZT17Cnc6ZnVuY3Rp
-b24oYSl7cmV0dXJuIEguRWoodGhpcy5hKX0sCiRpWFM6MSwKZ0lJOmZ1bmN0aW9uKCl7cmV0dXJuIHRo
-aXMuYn19ClAuUGYucHJvdG90eXBlPXsKdzA6ZnVuY3Rpb24oYSxiKXt2YXIgcwpILmNiKGEsImVycm9y
-Iix0LkspCnM9dGhpcy5hCmlmKHMuYSE9PTApdGhyb3cgSC5iKFAuUFYoIkZ1dHVyZSBhbHJlYWR5IGNv
-bXBsZXRlZCIpKQppZihiPT1udWxsKWI9UC52MChhKQpzLk5rKGEsYil9LApwbTpmdW5jdGlvbihhKXty
-ZXR1cm4gdGhpcy53MChhLG51bGwpfX0KUC5aZi5wcm90b3R5cGU9ewphTTpmdW5jdGlvbihhLGIpe3Zh
-ciBzLHI9dGhpcy4kdGkKci5DKCIxLz8iKS5hKGIpCnM9dGhpcy5hCmlmKHMuYSE9PTApdGhyb3cgSC5i
-KFAuUFYoIkZ1dHVyZSBhbHJlYWR5IGNvbXBsZXRlZCIpKQpzLlhmKHIuQygiMS8iKS5hKGIpKX19ClAu
-RmUucHJvdG90eXBlPXsKSFI6ZnVuY3Rpb24oYSl7aWYoKHRoaXMuYyYxNSkhPT02KXJldHVybiEwCnJl
-dHVybiB0aGlzLmIuYi5idih0LmFsLmEodGhpcy5kKSxhLmEsdC55LHQuSyl9LApLdzpmdW5jdGlvbihh
-KXt2YXIgcz10aGlzLmUscj10LnoscT10LksscD10aGlzLiR0aS5DKCIyLyIpLG89dGhpcy5iLmIKaWYo
-dC5hZy5iKHMpKXJldHVybiBwLmEoby5ycChzLGEuYSxhLmIscixxLHQubCkpCmVsc2UgcmV0dXJuIHAu
-YShvLmJ2KHQuYkkuYShzKSxhLmEscixxKSl9fQpQLnZzLnByb3RvdHlwZT17ClNxOmZ1bmN0aW9uKGEs
-YixjKXt2YXIgcyxyLHEscD10aGlzLiR0aQpwLktxKGMpLkMoIjEvKDIpIikuYShhKQpzPSQuWDMKaWYo
-cyE9PUMuTlUpe2MuQygiQDwwLz4iKS5LcShwLmMpLkMoIjEoMikiKS5hKGEpCmlmKGIhPW51bGwpYj1Q
-LlZIKGIscyl9cj1uZXcgUC52cyhzLGMuQygidnM8MD4iKSkKcT1iPT1udWxsPzE6Mwp0aGlzLnhmKG5l
-dyBQLkZlKHIscSxhLGIscC5DKCJAPDE+IikuS3EoYykuQygiRmU8MSwyPiIpKSkKcmV0dXJuIHJ9LApX
-NzpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLlNxKGEsbnVsbCxiKX0sClFkOmZ1bmN0aW9uKGEsYixj
-KXt2YXIgcyxyPXRoaXMuJHRpCnIuS3EoYykuQygiMS8oMikiKS5hKGEpCnM9bmV3IFAudnMoJC5YMyxj
-LkMoInZzPDA+IikpCnRoaXMueGYobmV3IFAuRmUocywxOSxhLGIsci5DKCJAPDE+IikuS3EoYykuQygi
-RmU8MSwyPiIpKSkKcmV0dXJuIHN9LAp4ZjpmdW5jdGlvbihhKXt2YXIgcyxyPXRoaXMscT1yLmEKaWYo
-cTw9MSl7YS5hPXQuRi5hKHIuYykKci5jPWF9ZWxzZXtpZihxPT09Mil7cz10LmMuYShyLmMpCnE9cy5h
-CmlmKHE8NCl7cy54ZihhKQpyZXR1cm59ci5hPXEKci5jPXMuY31QLlRrKG51bGwsbnVsbCxyLmIsdC5N
-LmEobmV3IFAuZGEocixhKSkpfX0sCmpROmZ1bmN0aW9uKGEpe3ZhciBzLHIscSxwLG8sbixtPXRoaXMs
-bD17fQpsLmE9YQppZihhPT1udWxsKXJldHVybgpzPW0uYQppZihzPD0xKXtyPXQuRi5hKG0uYykKbS5j
-PWEKaWYociE9bnVsbCl7cT1hLmEKZm9yKHA9YTtxIT1udWxsO3A9cSxxPW8pbz1xLmEKcC5hPXJ9fWVs
-c2V7aWYocz09PTIpe249dC5jLmEobS5jKQpzPW4uYQppZihzPDQpe24ualEoYSkKcmV0dXJufW0uYT1z
-Cm0uYz1uLmN9bC5hPW0uTjgoYSkKUC5UayhudWxsLG51bGwsbS5iLHQuTS5hKG5ldyBQLm9RKGwsbSkp
-KX19LAphaDpmdW5jdGlvbigpe3ZhciBzPXQuRi5hKHRoaXMuYykKdGhpcy5jPW51bGwKcmV0dXJuIHRo
-aXMuTjgocyl9LApOODpmdW5jdGlvbihhKXt2YXIgcyxyLHEKZm9yKHM9YSxyPW51bGw7cyE9bnVsbDty
-PXMscz1xKXtxPXMuYQpzLmE9cn1yZXR1cm4gcn0sCmVjOmZ1bmN0aW9uKGEpe3ZhciBzLHIscSxwPXRo
-aXMKcC5hPTEKdHJ5e2EuU3EobmV3IFAucFYocCksbmV3IFAuVTcocCksdC5QKX1jYXRjaChxKXtzPUgu
-UnUocSkKcj1ILnRzKHEpClAucmIobmV3IFAudnIocCxzLHIpKX19LApYMjpmdW5jdGlvbihhKXt2YXIg
-cyxyPXRoaXMKci4kdGkuYy5hKGEpCnM9ci5haCgpCnIuYT00CnIuYz1hClAuSFoocixzKX0sClpMOmZ1
-bmN0aW9uKGEsYil7dmFyIHMscixxPXRoaXMKdC5sLmEoYikKcz1xLmFoKCkKcj1QLlRsKGEsYikKcS5h
-PTgKcS5jPXIKUC5IWihxLHMpfSwKWGY6ZnVuY3Rpb24oYSl7dmFyIHM9dGhpcy4kdGkKcy5DKCIxLyIp
-LmEoYSkKaWYocy5DKCJiODwxPiIpLmIoYSkpe3RoaXMuY1UoYSkKcmV0dXJufXRoaXMud1Uocy5jLmEo
-YSkpfSwKd1U6ZnVuY3Rpb24oYSl7dmFyIHM9dGhpcwpzLiR0aS5jLmEoYSkKcy5hPTEKUC5UayhudWxs
-LG51bGwscy5iLHQuTS5hKG5ldyBQLnJ0KHMsYSkpKX0sCmNVOmZ1bmN0aW9uKGEpe3ZhciBzPXRoaXMs
-cj1zLiR0aQpyLkMoImI4PDE+IikuYShhKQppZihyLmIoYSkpe2lmKGEuYT09PTgpe3MuYT0xClAuVGso
-bnVsbCxudWxsLHMuYix0Lk0uYShuZXcgUC5LRihzLGEpKSl9ZWxzZSBQLkE5KGEscykKcmV0dXJufXMu
-ZWMoYSl9LApOazpmdW5jdGlvbihhLGIpe3RoaXMuYT0xClAuVGsobnVsbCxudWxsLHRoaXMuYix0Lk0u
-YShuZXcgUC5aTCh0aGlzLGEsYikpKX0sCiRpYjg6MX0KUC5kYS5wcm90b3R5cGU9ewokMDpmdW5jdGlv
-bigpe1AuSFoodGhpcy5hLHRoaXMuYil9LAokUzowfQpQLm9RLnByb3RvdHlwZT17CiQwOmZ1bmN0aW9u
-KCl7UC5IWih0aGlzLmIsdGhpcy5hLmEpfSwKJFM6MH0KUC5wVi5wcm90b3R5cGU9ewokMTpmdW5jdGlv
-bihhKXt2YXIgcyxyLHEscD10aGlzLmEKcC5hPTAKdHJ5e3AuWDIocC4kdGkuYy5hKGEpKX1jYXRjaChx
-KXtzPUguUnUocSkKcj1ILnRzKHEpCnAuWkwocyxyKX19LAokUzoxMH0KUC5VNy5wcm90b3R5cGU9ewok
-MjpmdW5jdGlvbihhLGIpe3RoaXMuYS5aTChhLHQubC5hKGIpKX0sCiRDOiIkMiIsCiRSOjIsCiRTOjI4
-fQpQLnZyLnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7dGhpcy5hLlpMKHRoaXMuYix0aGlzLmMpfSwK
-JFM6MH0KUC5ydC5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe3RoaXMuYS5YMih0aGlzLmIpfSwKJFM6
-MH0KUC5LRi5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe1AuQTkodGhpcy5iLHRoaXMuYSl9LAokUzow
-fQpQLlpMLnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7dGhpcy5hLlpMKHRoaXMuYix0aGlzLmMpfSwK
-JFM6MH0KUC5SVC5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe3ZhciBzLHIscSxwLG8sbixtPXRoaXMs
-bD1udWxsCnRyeXtxPW0uYS5hCmw9cS5iLmIuenoodC5mTy5hKHEuZCksdC56KX1jYXRjaChwKXtzPUgu
-UnUocCkKcj1ILnRzKHApCmlmKG0uYyl7cT10Lm4uYShtLmIuYS5jKS5hCm89cwpvPXE9PW51bGw/bz09
-bnVsbDpxPT09bwpxPW99ZWxzZSBxPSExCm89bS5hCmlmKHEpby5jPXQubi5hKG0uYi5hLmMpCmVsc2Ug
-by5jPVAuVGwocyxyKQpvLmI9ITAKcmV0dXJufWlmKGwgaW5zdGFuY2VvZiBQLnZzJiZsLmE+PTQpe2lm
-KGwuYT09PTgpe3E9bS5hCnEuYz10Lm4uYShsLmMpCnEuYj0hMH1yZXR1cm59aWYodC5lLmIobCkpe249
-bS5iLmEKcT1tLmEKcS5jPWwuVzcobmV3IFAualoobiksdC56KQpxLmI9ITF9fSwKJFM6MH0KUC5qWi5w
-cm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hfSwKJFM6Mjl9ClAucnEucHJvdG90
-eXBlPXsKJDA6ZnVuY3Rpb24oKXt2YXIgcyxyLHEscCxvLG4sbSxsCnRyeXtxPXRoaXMuYQpwPXEuYQpv
-PXAuJHRpCm49by5jCm09bi5hKHRoaXMuYikKcS5jPXAuYi5iLmJ2KG8uQygiMi8oMSkiKS5hKHAuZCks
-bSxvLkMoIjIvIiksbil9Y2F0Y2gobCl7cz1ILlJ1KGwpCnI9SC50cyhsKQpxPXRoaXMuYQpxLmM9UC5U
-bChzLHIpCnEuYj0hMH19LAokUzowfQpQLlJXLnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7dmFyIHMs
-cixxLHAsbyxuLG0sbCxrPXRoaXMKdHJ5e3M9dC5uLmEoay5hLmEuYykKcD1rLmIKaWYoSC5vVChwLmEu
-SFIocykpJiZwLmEuZSE9bnVsbCl7cC5jPXAuYS5LdyhzKQpwLmI9ITF9fWNhdGNoKG8pe3I9SC5SdShv
-KQpxPUgudHMobykKcD10Lm4uYShrLmEuYS5jKQpuPXAuYQptPXIKbD1rLmIKaWYobj09bnVsbD9tPT1u
-dWxsOm49PT1tKWwuYz1wCmVsc2UgbC5jPVAuVGwocixxKQpsLmI9ITB9fSwKJFM6MH0KUC5PTS5wcm90
-b3R5cGU9e30KUC5xaC5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXt2YXIgcyxyLHE9dGhpcyxwPXt9
-LG89bmV3IFAudnMoJC5YMyx0LmZKKQpwLmE9MApzPUguTGgocSkKcj1zLkMoIn4oMSk/IikuYShuZXcg
-UC5CNShwLHEpKQp0LlouYShuZXcgUC51TyhwLG8pKQpXLkpFKHEuYSxxLmIsciwhMSxzLmMpCnJldHVy
-biBvfX0KUC5CNS5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtILkxoKHRoaXMuYikuYy5hKGEpOysr
-dGhpcy5hLmF9LAokUzpmdW5jdGlvbigpe3JldHVybiBILkxoKHRoaXMuYikuQygifigxKSIpfX0KUC51
-Ty5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe3ZhciBzPXRoaXMuYixyPXMuJHRpLHE9ci5DKCIxLyIp
-LmEodGhpcy5hLmEpLHA9cy5haCgpCnIuYy5hKHEpCnMuYT00CnMuYz1xClAuSFoocyxwKX0sCiRTOjB9
-ClAuTU8ucHJvdG90eXBlPXt9ClAua1QucHJvdG90eXBlPXt9ClAueEkucHJvdG90eXBlPXt9ClAubTAu
-cHJvdG90eXBlPXskaVFtOjF9ClAucEsucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXt2YXIgcz1ILmIo
-dGhpcy5hKQpzLnN0YWNrPUouaih0aGlzLmIpCnRocm93IHN9LAokUzowfQpQLkppLnByb3RvdHlwZT17
-CmJIOmZ1bmN0aW9uKGEpe3ZhciBzLHIscSxwPW51bGwKdC5NLmEoYSkKdHJ5e2lmKEMuTlU9PT0kLlgz
-KXthLiQwKCkKcmV0dXJufVAuVDgocCxwLHRoaXMsYSx0LkgpfWNhdGNoKHEpe3M9SC5SdShxKQpyPUgu
-dHMocSkKUC5MMihwLHAsdGhpcyxzLHQubC5hKHIpKX19LApEbDpmdW5jdGlvbihhLGIsYyl7dmFyIHMs
-cixxLHA9bnVsbApjLkMoIn4oMCkiKS5hKGEpCmMuYShiKQp0cnl7aWYoQy5OVT09PSQuWDMpe2EuJDEo
-YikKcmV0dXJufVAueXYocCxwLHRoaXMsYSxiLHQuSCxjKX1jYXRjaChxKXtzPUguUnUocSkKcj1ILnRz
-KHEpClAuTDIocCxwLHRoaXMscyx0LmwuYShyKSl9fSwKR1k6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQ
-LlZwKHRoaXMsdC5NLmEoYSkpfSwKUHk6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gbmV3IFAuT1IodGhpcyxi
-LkMoIn4oMCkiKS5hKGEpLGIpfSwKcTpmdW5jdGlvbihhLGIpe3JldHVybiBudWxsfSwKeno6ZnVuY3Rp
-b24oYSxiKXtiLkMoIjAoKSIpLmEoYSkKaWYoJC5YMz09PUMuTlUpcmV0dXJuIGEuJDAoKQpyZXR1cm4g
-UC5UOChudWxsLG51bGwsdGhpcyxhLGIpfSwKYnY6ZnVuY3Rpb24oYSxiLGMsZCl7Yy5DKCJAPDA+Iiku
-S3EoZCkuQygiMSgyKSIpLmEoYSkKZC5hKGIpCmlmKCQuWDM9PT1DLk5VKXJldHVybiBhLiQxKGIpCnJl
-dHVybiBQLnl2KG51bGwsbnVsbCx0aGlzLGEsYixjLGQpfSwKcnA6ZnVuY3Rpb24oYSxiLGMsZCxlLGYp
-e2QuQygiQDwwPiIpLktxKGUpLktxKGYpLkMoIjEoMiwzKSIpLmEoYSkKZS5hKGIpCmYuYShjKQppZigk
-LlgzPT09Qy5OVSlyZXR1cm4gYS4kMihiLGMpCnJldHVybiBQLlF4KG51bGwsbnVsbCx0aGlzLGEsYixj
-LGQsZSxmKX0sCkxqOmZ1bmN0aW9uKGEsYixjLGQpe3JldHVybiBiLkMoIkA8MD4iKS5LcShjKS5LcShk
-KS5DKCIxKDIsMykiKS5hKGEpfX0KUC5WcC5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe3JldHVybiB0
-aGlzLmEuYkgodGhpcy5iKX0sCiRTOjB9ClAuT1IucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFy
-IHM9dGhpcy5jCnJldHVybiB0aGlzLmEuRGwodGhpcy5iLHMuYShhKSxzKX0sCiRTOmZ1bmN0aW9uKCl7
-cmV0dXJuIHRoaXMuYy5DKCJ+KDApIil9fQpQLmI2LnByb3RvdHlwZT17CmdtOmZ1bmN0aW9uKGEpe3Zh
-ciBzPXRoaXMscj1uZXcgUC5sbShzLHMucixILkxoKHMpLkMoImxtPDE+IikpCnIuYz1zLmUKcmV0dXJu
-IHJ9LApnQTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hfSwKZ2wwOmZ1bmN0aW9uKGEpe3JldHVybiB0
-aGlzLmE9PT0wfSwKZ29yOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmEhPT0wfSwKdGc6ZnVuY3Rpb24o
-YSxiKXt2YXIgcyxyCmlmKHR5cGVvZiBiPT0ic3RyaW5nIiYmYiE9PSJfX3Byb3RvX18iKXtzPXRoaXMu
-YgppZihzPT1udWxsKXJldHVybiExCnJldHVybiB0Lm0uYShzW2JdKSE9bnVsbH1lbHNle3I9dGhpcy5Q
-UihiKQpyZXR1cm4gcn19LApQUjpmdW5jdGlvbihhKXt2YXIgcz10aGlzLmQKaWYocz09bnVsbClyZXR1
-cm4hMQpyZXR1cm4gdGhpcy5ERihzW3RoaXMuTihhKV0sYSk+PTB9LAppOmZ1bmN0aW9uKGEsYil7dmFy
-IHMscixxPXRoaXMKSC5MaChxKS5jLmEoYikKaWYodHlwZW9mIGI9PSJzdHJpbmciJiZiIT09Il9fcHJv
-dG9fXyIpe3M9cS5iCnJldHVybiBxLmJRKHM9PW51bGw/cS5iPVAuVDIoKTpzLGIpfWVsc2UgaWYodHlw
-ZW9mIGI9PSJudW1iZXIiJiYoYiYxMDczNzQxODIzKT09PWIpe3I9cS5jCnJldHVybiBxLmJRKHI9PW51
-bGw/cS5jPVAuVDIoKTpyLGIpfWVsc2UgcmV0dXJuIHEuQjcoYil9LApCNzpmdW5jdGlvbihhKXt2YXIg
-cyxyLHEscD10aGlzCkguTGgocCkuYy5hKGEpCnM9cC5kCmlmKHM9PW51bGwpcz1wLmQ9UC5UMigpCnI9
-cC5OKGEpCnE9c1tyXQppZihxPT1udWxsKXNbcl09W3AueW8oYSldCmVsc2V7aWYocC5ERihxLGEpPj0w
-KXJldHVybiExCnEucHVzaChwLnlvKGEpKX1yZXR1cm4hMH0sClI6ZnVuY3Rpb24oYSxiKXt2YXIgcz10
-aGlzCmlmKHR5cGVvZiBiPT0ic3RyaW5nIiYmYiE9PSJfX3Byb3RvX18iKXJldHVybiBzLkgocy5iLGIp
-CmVsc2UgaWYodHlwZW9mIGI9PSJudW1iZXIiJiYoYiYxMDczNzQxODIzKT09PWIpcmV0dXJuIHMuSChz
-LmMsYikKZWxzZSByZXR1cm4gcy5xZyhiKX0sCnFnOmZ1bmN0aW9uKGEpe3ZhciBzLHIscSxwLG89dGhp
-cyxuPW8uZAppZihuPT1udWxsKXJldHVybiExCnM9by5OKGEpCnI9bltzXQpxPW8uREYocixhKQppZihx
-PDApcmV0dXJuITEKcD1yLnNwbGljZShxLDEpWzBdCmlmKDA9PT1yLmxlbmd0aClkZWxldGUgbltzXQpv
-LkcocCkKcmV0dXJuITB9LApiUTpmdW5jdGlvbihhLGIpe0guTGgodGhpcykuYy5hKGIpCmlmKHQubS5h
-KGFbYl0pIT1udWxsKXJldHVybiExCmFbYl09dGhpcy55byhiKQpyZXR1cm4hMH0sCkg6ZnVuY3Rpb24o
-YSxiKXt2YXIgcwppZihhPT1udWxsKXJldHVybiExCnM9dC5tLmEoYVtiXSkKaWYocz09bnVsbClyZXR1
-cm4hMQp0aGlzLkcocykKZGVsZXRlIGFbYl0KcmV0dXJuITB9LApTOmZ1bmN0aW9uKCl7dGhpcy5yPXRo
-aXMucisxJjEwNzM3NDE4MjN9LAp5bzpmdW5jdGlvbihhKXt2YXIgcyxyPXRoaXMscT1uZXcgUC5ibihI
-LkxoKHIpLmMuYShhKSkKaWYoci5lPT1udWxsKXIuZT1yLmY9cQplbHNle3M9ci5mCnMudG9TdHJpbmcK
-cS5jPXMKci5mPXMuYj1xfSsrci5hCnIuUygpCnJldHVybiBxfSwKRzpmdW5jdGlvbihhKXt2YXIgcz10
-aGlzLHI9YS5jLHE9YS5iCmlmKHI9PW51bGwpcy5lPXEKZWxzZSByLmI9cQppZihxPT1udWxsKXMuZj1y
-CmVsc2UgcS5jPXI7LS1zLmEKcy5TKCl9LApOOmZ1bmN0aW9uKGEpe3JldHVybiBKLmhmKGEpJjEwNzM3
-NDE4MjN9LApERjpmdW5jdGlvbihhLGIpe3ZhciBzLHIKaWYoYT09bnVsbClyZXR1cm4tMQpzPWEubGVu
-Z3RoCmZvcihyPTA7cjxzOysrcilpZihKLlJNKGFbcl0uYSxiKSlyZXR1cm4gcgpyZXR1cm4tMX19ClAu
-Ym4ucHJvdG90eXBlPXt9ClAubG0ucHJvdG90eXBlPXsKZ2w6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5k
-fSwKRjpmdW5jdGlvbigpe3ZhciBzPXRoaXMscj1zLmMscT1zLmEKaWYocy5iIT09cS5yKXRocm93IEgu
-YihQLmE0KHEpKQplbHNlIGlmKHI9PW51bGwpe3Muc2oobnVsbCkKcmV0dXJuITF9ZWxzZXtzLnNqKHMu
-JHRpLkMoIjE/IikuYShyLmEpKQpzLmM9ci5iCnJldHVybiEwfX0sCnNqOmZ1bmN0aW9uKGEpe3RoaXMu
-ZD10aGlzLiR0aS5DKCIxPyIpLmEoYSl9LAokaUFuOjF9ClAubVcucHJvdG90eXBlPXt9ClAudXkucHJv
-dG90eXBlPXskaWJROjEsJGljWDoxLCRpek06MX0KUC5sRC5wcm90b3R5cGU9ewpnbTpmdW5jdGlvbihh
-KXtyZXR1cm4gbmV3IEguYTcoYSx0aGlzLmdBKGEpLEgueihhKS5DKCJhNzxsRC5FPiIpKX0sCkU6ZnVu
-Y3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5xKGEsYil9LApLOmZ1bmN0aW9uKGEsYil7dmFyIHMscgpILnoo
-YSkuQygifihsRC5FKSIpLmEoYikKcz10aGlzLmdBKGEpCmZvcihyPTA7cjxzOysrcil7Yi4kMSh0aGlz
-LnEoYSxyKSkKaWYocyE9PXRoaXMuZ0EoYSkpdGhyb3cgSC5iKFAuYTQoYSkpfX0sCmdsMDpmdW5jdGlv
-bihhKXtyZXR1cm4gdGhpcy5nQShhKT09PTB9LApnb3I6ZnVuY3Rpb24oYSl7cmV0dXJuIXRoaXMuZ2ww
-KGEpfSwKRTI6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzPUgueihhKQpyZXR1cm4gbmV3IEgubEooYSxzLktx
-KGMpLkMoIjEobEQuRSkiKS5hKGIpLHMuQygiQDxsRC5FPiIpLktxKGMpLkMoImxKPDEsMj4iKSl9LApl
-UjpmdW5jdGlvbihhLGIpe3JldHVybiBILnFDKGEsYixudWxsLEgueihhKS5DKCJsRC5FIikpfSwKZHI6
-ZnVuY3Rpb24oYSxiKXtyZXR1cm4gbmV3IEgualYoYSxILnooYSkuQygiQDxsRC5FPiIpLktxKGIpLkMo
-ImpWPDEsMj4iKSl9LApkdTpmdW5jdGlvbihhLGIsYyxkKXt2YXIgcwpILnooYSkuQygibEQuRT8iKS5h
-KGQpClAuakIoYixjLHRoaXMuZ0EoYSkpCmZvcihzPWI7czxjOysrcyl0aGlzLlk1KGEscyxkKX0sCnc6
-ZnVuY3Rpb24oYSl7cmV0dXJuIFAuV0UoYSwiWyIsIl0iKX19ClAuaWwucHJvdG90eXBlPXt9ClAucmEu
-cHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyPXRoaXMuYQppZighci5hKXRoaXMuYi5h
-Kz0iLCAiCnIuYT0hMQpyPXRoaXMuYgpzPXIuYSs9SC5FaihhKQpyLmE9cysiOiAiCnIuYSs9SC5Faihi
-KX0sCiRTOjExfQpQLllrLnByb3RvdHlwZT17Cks6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyCkguTGgodGhp
-cykuQygifihZay5LLFlrLlYpIikuYShiKQpmb3Iocz1KLklUKHRoaXMuZ3ZjKCkpO3MuRigpOyl7cj1z
-LmdsKCkKYi4kMihyLHRoaXMucSgwLHIpKX19LApnUHU6ZnVuY3Rpb24oYSl7cmV0dXJuIEouTTEodGhp
-cy5ndmMoKSxuZXcgUC55USh0aGlzKSxILkxoKHRoaXMpLkMoIk4zPFlrLkssWWsuVj4iKSl9LAp4NDpm
-dW5jdGlvbihhKXtyZXR1cm4gSi56bCh0aGlzLmd2YygpLGEpfSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJu
-IEouSG0odGhpcy5ndmMoKSl9LApnbDA6ZnVuY3Rpb24oYSl7cmV0dXJuIEoudVUodGhpcy5ndmMoKSl9
-LAp3OmZ1bmN0aW9uKGEpe3JldHVybiBQLm5PKHRoaXMpfSwKJGlaMDoxfQpQLnlRLnByb3RvdHlwZT17
-CiQxOmZ1bmN0aW9uKGEpe3ZhciBzPXRoaXMuYSxyPUguTGgocykKci5DKCJZay5LIikuYShhKQpyZXR1
-cm4gbmV3IFAuTjMoYSxzLnEoMCxhKSxyLkMoIkA8WWsuSz4iKS5LcShyLkMoIllrLlYiKSkuQygiTjM8
-MSwyPiIpKX0sCiRTOmZ1bmN0aW9uKCl7cmV0dXJuIEguTGgodGhpcy5hKS5DKCJOMzxZay5LLFlrLlY+
-KFlrLkspIil9fQpQLktQLnByb3RvdHlwZT17Clk1OmZ1bmN0aW9uKGEsYixjKXt2YXIgcz1ILkxoKHRo
-aXMpCnMuYy5hKGIpCnMuUVsxXS5hKGMpCnRocm93IEguYihQLkw0KCJDYW5ub3QgbW9kaWZ5IHVubW9k
-aWZpYWJsZSBtYXAiKSl9fQpQLlBuLnByb3RvdHlwZT17CnE6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhp
-cy5hLnEoMCxiKX0sClk1OmZ1bmN0aW9uKGEsYixjKXt2YXIgcz1ILkxoKHRoaXMpCnRoaXMuYS5ZNSgw
-LHMuYy5hKGIpLHMuUVsxXS5hKGMpKX0sCng0OmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmEueDQoYSl9
-LApLOmZ1bmN0aW9uKGEsYil7dGhpcy5hLksoMCxILkxoKHRoaXMpLkMoIn4oMSwyKSIpLmEoYikpfSwK
-Z2wwOmZ1bmN0aW9uKGEpe3ZhciBzPXRoaXMuYQpyZXR1cm4gcy5nbDAocyl9LApnQTpmdW5jdGlvbihh
-KXt2YXIgcz10aGlzLmEKcmV0dXJuIHMuZ0Eocyl9LAp3OmZ1bmN0aW9uKGEpe3JldHVybiBKLmoodGhp
-cy5hKX0sCmdQdTpmdW5jdGlvbihhKXt2YXIgcz10aGlzLmEKcmV0dXJuIHMuZ1B1KHMpfSwKJGlaMDox
-fQpQLkdqLnByb3RvdHlwZT17fQpQLmxmLnByb3RvdHlwZT17CmdsMDpmdW5jdGlvbihhKXtyZXR1cm4g
-dGhpcy5nQSh0aGlzKT09PTB9LApnb3I6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuZ0EodGhpcykhPT0w
-fSwKRlY6ZnVuY3Rpb24oYSxiKXt2YXIgcwpmb3Iocz1KLklUKEguTGgodGhpcykuQygiY1g8bGYuRT4i
-KS5hKGIpKTtzLkYoKTspdGhpcy5pKDAscy5nbCgpKX0sCnc6ZnVuY3Rpb24oYSl7cmV0dXJuIFAuV0Uo
-dGhpcywieyIsIn0iKX0sCms6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyPXRoaXMuZ20odGhpcykKaWYoIXIu
-RigpKXJldHVybiIiCmlmKGI9PT0iIil7cz0iIgpkbyBzKz1ILkVqKHIuZCkKd2hpbGUoci5GKCkpfWVs
-c2V7cz1ILkVqKHIuZCkKZm9yKDtyLkYoKTspcz1zK2IrSC5FaihyLmQpfXJldHVybiBzLmNoYXJDb2Rl
-QXQoMCk9PTA/czpzfSwKZVI6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gSC5iSyh0aGlzLGIsSC5MaCh0aGlz
-KS5DKCJsZi5FIikpfSwKRTpmdW5jdGlvbihhLGIpe3ZhciBzLHIscSxwPSJpbmRleCIKSC5jYihiLHAs
-dC5TKQpQLmsxKGIscCkKZm9yKHM9dGhpcy5nbSh0aGlzKSxyPTA7cy5GKCk7KXtxPXMuZAppZihiPT09
-cilyZXR1cm4gcTsrK3J9dGhyb3cgSC5iKFAuQ2YoYix0aGlzLHAsbnVsbCxyKSl9fQpQLlZqLnByb3Rv
-dHlwZT17JGliUToxLCRpY1g6MSwkaXh1OjF9ClAuWHYucHJvdG90eXBlPXskaWJROjEsJGljWDoxLCRp
-eHU6MX0KUC5uWS5wcm90b3R5cGU9e30KUC5XWS5wcm90b3R5cGU9e30KUC5SVS5wcm90b3R5cGU9e30K
-UC5wUi5wcm90b3R5cGU9e30KUC51dy5wcm90b3R5cGU9ewpxOmZ1bmN0aW9uKGEsYil7dmFyIHMscj10
-aGlzLmIKaWYocj09bnVsbClyZXR1cm4gdGhpcy5jLnEoMCxiKQplbHNlIGlmKHR5cGVvZiBiIT0ic3Ry
-aW5nIilyZXR1cm4gbnVsbAplbHNle3M9cltiXQpyZXR1cm4gdHlwZW9mIHM9PSJ1bmRlZmluZWQiP3Ro
-aXMuZmIoYik6c319LApnQTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5iPT1udWxsP3RoaXMuYy5hOnRo
-aXMuQ2YoKS5sZW5ndGh9LApnbDA6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuZ0EodGhpcyk9PT0wfSwK
-Z3ZjOmZ1bmN0aW9uKCl7aWYodGhpcy5iPT1udWxsKXt2YXIgcz10aGlzLmMKcmV0dXJuIG5ldyBILmk1
-KHMsSC5MaChzKS5DKCJpNTwxPiIpKX1yZXR1cm4gbmV3IFAuaTgodGhpcyl9LApZNTpmdW5jdGlvbihh
-LGIsYyl7dmFyIHMscixxPXRoaXMKaWYocS5iPT1udWxsKXEuYy5ZNSgwLGIsYykKZWxzZSBpZihxLng0
-KGIpKXtzPXEuYgpzW2JdPWMKcj1xLmEKaWYocj09bnVsbD9zIT1udWxsOnIhPT1zKXJbYl09bnVsbH1l
-bHNlIHEuWEsoKS5ZNSgwLGIsYyl9LAp4NDpmdW5jdGlvbihhKXtpZih0aGlzLmI9PW51bGwpcmV0dXJu
-IHRoaXMuYy54NChhKQpyZXR1cm4gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHRo
-aXMuYSxhKX0sCks6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEscCxvPXRoaXMKdC5jQS5hKGIpCmlmKG8u
-Yj09bnVsbClyZXR1cm4gby5jLksoMCxiKQpzPW8uQ2YoKQpmb3Iocj0wO3I8cy5sZW5ndGg7KytyKXtx
-PXNbcl0KcD1vLmJbcV0KaWYodHlwZW9mIHA9PSJ1bmRlZmluZWQiKXtwPVAuUWUoby5hW3FdKQpvLmJb
-cV09cH1iLiQyKHEscCkKaWYocyE9PW8uYyl0aHJvdyBILmIoUC5hNChvKSl9fSwKQ2Y6ZnVuY3Rpb24o
-KXt2YXIgcz10LmJNLmEodGhpcy5jKQppZihzPT1udWxsKXM9dGhpcy5jPUguVk0oT2JqZWN0LmtleXMo
-dGhpcy5hKSx0LnMpCnJldHVybiBzfSwKWEs6ZnVuY3Rpb24oKXt2YXIgcyxyLHEscCxvLG49dGhpcwpp
-ZihuLmI9PW51bGwpcmV0dXJuIG4uYwpzPVAuRmwodC5OLHQueikKcj1uLkNmKCkKZm9yKHE9MDtwPXIu
-bGVuZ3RoLHE8cDsrK3Epe289cltxXQpzLlk1KDAsbyxuLnEoMCxvKSl9aWYocD09PTApQy5ObS5pKHIs
-IiIpCmVsc2UgQy5ObS5zQShyLDApCm4uYT1uLmI9bnVsbApyZXR1cm4gbi5jPXN9LApmYjpmdW5jdGlv
-bihhKXt2YXIgcwppZighT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHRoaXMuYSxh
-KSlyZXR1cm4gbnVsbApzPVAuUWUodGhpcy5hW2FdKQpyZXR1cm4gdGhpcy5iW2FdPXN9fQpQLmk4LnBy
-b3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3ZhciBzPXRoaXMuYQpyZXR1cm4gcy5nQShzKX0sCkU6ZnVu
-Y3Rpb24oYSxiKXt2YXIgcz10aGlzLmEKaWYocy5iPT1udWxsKXM9cy5ndmMoKS5FKDAsYikKZWxzZXtz
-PXMuQ2YoKQppZihiPDB8fGI+PXMubGVuZ3RoKXJldHVybiBILk9IKHMsYikKcz1zW2JdfXJldHVybiBz
-fSwKZ206ZnVuY3Rpb24oYSl7dmFyIHM9dGhpcy5hCmlmKHMuYj09bnVsbCl7cz1zLmd2YygpCnM9cy5n
-bShzKX1lbHNle3M9cy5DZigpCnM9bmV3IEoubTEocyxzLmxlbmd0aCxILnQ2KHMpLkMoIm0xPDE+Iikp
-fXJldHVybiBzfSwKdGc6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5hLng0KGIpfX0KUC54ci5wcm90
-b3R5cGU9ewokMDpmdW5jdGlvbigpe3ZhciBzLHIKdHJ5e3M9bmV3IFRleHREZWNvZGVyKCJ1dGYtOCIs
-e2ZhdGFsOnRydWV9KQpyZXR1cm4gc31jYXRjaChyKXtILlJ1KHIpfXJldHVybiBudWxsfSwKJFM6MTJ9
-ClAuTnoucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXt2YXIgcyxyCnRyeXtzPW5ldyBUZXh0RGVjb2Rl
-cigidXRmLTgiLHtmYXRhbDpmYWxzZX0pCnJldHVybiBzfWNhdGNoKHIpe0guUnUocil9cmV0dXJuIG51
-bGx9LAokUzoxMn0KUC5DVi5wcm90b3R5cGU9ewp5cjpmdW5jdGlvbihhMCxhMSxhMil7dmFyIHMscixx
-LHAsbyxuLG0sbCxrLGosaSxoLGcsZixlLGQsYyxiLGE9IkludmFsaWQgYmFzZTY0IGVuY29kaW5nIGxl
-bmd0aCAiCmEyPVAuakIoYTEsYTIsYTAubGVuZ3RoKQpzPSQuVjcoKQpmb3Iocj1hMSxxPXIscD1udWxs
-LG89LTEsbj0tMSxtPTA7cjxhMjtyPWwpe2w9cisxCms9Qy54Qi5XKGEwLHIpCmlmKGs9PT0zNyl7aj1s
-KzIKaWYoajw9YTIpe2k9SC5vbyhDLnhCLlcoYTAsbCkpCmg9SC5vbyhDLnhCLlcoYTAsbCsxKSkKZz1p
-KjE2K2gtKGgmMjU2KQppZihnPT09MzcpZz0tMQpsPWp9ZWxzZSBnPS0xfWVsc2UgZz1rCmlmKDA8PWcm
-Jmc8PTEyNyl7aWYoZzwwfHxnPj1zLmxlbmd0aClyZXR1cm4gSC5PSChzLGcpCmY9c1tnXQppZihmPj0w
-KXtnPUMueEIuTygiQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2
-d3h5ejAxMjM0NTY3ODkrLyIsZikKaWYoZz09PWspY29udGludWUKaz1nfWVsc2V7aWYoZj09PS0xKXtp
-ZihvPDApe2U9cD09bnVsbD9udWxsOnAuYS5sZW5ndGgKaWYoZT09bnVsbCllPTAKbz1lKyhyLXEpCm49
-cn0rK20KaWYoaz09PTYxKWNvbnRpbnVlfWs9Z31pZihmIT09LTIpe2lmKHA9PW51bGwpe3A9bmV3IFAu
-Um4oIiIpCmU9cH1lbHNlIGU9cAplLmErPUMueEIuTmooYTAscSxyKQplLmErPUguTHcoaykKcT1sCmNv
-bnRpbnVlfX10aHJvdyBILmIoUC5ycigiSW52YWxpZCBiYXNlNjQgZGF0YSIsYTAscikpfWlmKHAhPW51
-bGwpe2U9cC5hKz1DLnhCLk5qKGEwLHEsYTIpCmQ9ZS5sZW5ndGgKaWYobz49MClQLnhNKGEwLG4sYTIs
-byxtLGQpCmVsc2V7Yz1DLmpuLnpZKGQtMSw0KSsxCmlmKGM9PT0xKXRocm93IEguYihQLnJyKGEsYTAs
-YTIpKQpmb3IoO2M8NDspe2UrPSI9IgpwLmE9ZTsrK2N9fWU9cC5hCnJldHVybiBDLnhCLmk3KGEwLGEx
-LGEyLGUuY2hhckNvZGVBdCgwKT09MD9lOmUpfWI9YTItYTEKaWYobz49MClQLnhNKGEwLG4sYTIsbyxt
-LGIpCmVsc2V7Yz1DLmpuLnpZKGIsNCkKaWYoYz09PTEpdGhyb3cgSC5iKFAucnIoYSxhMCxhMikpCmlm
-KGM+MSlhMD1DLnhCLmk3KGEwLGEyLGEyLGM9PT0yPyI9PSI6Ij0iKX1yZXR1cm4gYTB9fQpQLlU4LnBy
-b3RvdHlwZT17fQpQLlVrLnByb3RvdHlwZT17fQpQLndJLnByb3RvdHlwZT17fQpQLlppLnByb3RvdHlw
-ZT17fQpQLlVkLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7dmFyIHM9UC5wKHRoaXMuYSkKcmV0dXJu
-KHRoaXMuYiE9bnVsbD8iQ29udmVydGluZyBvYmplY3QgdG8gYW4gZW5jb2RhYmxlIG9iamVjdCBmYWls
-ZWQ6IjoiQ29udmVydGluZyBvYmplY3QgZGlkIG5vdCByZXR1cm4gYW4gZW5jb2RhYmxlIG9iamVjdDoi
-KSsiICIrc319ClAuSzgucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4iQ3ljbGljIGVycm9y
-IGluIEpTT04gc3RyaW5naWZ5In19ClAuYnkucHJvdG90eXBlPXsKcFc6ZnVuY3Rpb24oYSxiLGMpe3Zh
-ciBzCnQuZlYuYShjKQpzPVAuQlMoYix0aGlzLmdIZSgpLmEpCnJldHVybiBzfSwKT0I6ZnVuY3Rpb24o
-YSxiKXt2YXIgcwp0LmRBLmEoYikKcz1QLnVYKGEsdGhpcy5nWkUoKS5iLG51bGwpCnJldHVybiBzfSwK
-Z1pFOmZ1bmN0aW9uKCl7cmV0dXJuIEMublh9LApnSGU6ZnVuY3Rpb24oKXtyZXR1cm4gQy5BM319ClAu
-b2oucHJvdG90eXBlPXt9ClAuTXgucHJvdG90eXBlPXt9ClAuU2gucHJvdG90eXBlPXsKUlQ6ZnVuY3Rp
-b24oYSl7dmFyIHMscixxLHAsbyxuLG0sbD1hLmxlbmd0aApmb3Iocz1KLnJZKGEpLHI9dGhpcy5jLHE9
-MCxwPTA7cDxsOysrcCl7bz1zLlcoYSxwKQppZihvPjkyKXtpZihvPj01NTI5Nil7bj1vJjY0NTEyCmlm
-KG49PT01NTI5Nil7bT1wKzEKbT0hKG08bCYmKEMueEIuVyhhLG0pJjY0NTEyKT09PTU2MzIwKX1lbHNl
-IG09ITEKaWYoIW0paWYobj09PTU2MzIwKXtuPXAtMQpuPSEobj49MCYmKEMueEIuTyhhLG4pJjY0NTEy
-KT09PTU1Mjk2KX1lbHNlIG49ITEKZWxzZSBuPSEwCmlmKG4pe2lmKHA+cSlyLmErPUMueEIuTmooYSxx
-LHApCnE9cCsxCnIuYSs9SC5Mdyg5MikKci5hKz1ILkx3KDExNykKci5hKz1ILkx3KDEwMCkKbj1vPj4+
-OCYxNQpyLmErPUguTHcobjwxMD80OCtuOjg3K24pCm49bz4+PjQmMTUKci5hKz1ILkx3KG48MTA/NDgr
-bjo4NytuKQpuPW8mMTUKci5hKz1ILkx3KG48MTA/NDgrbjo4NytuKX19Y29udGludWV9aWYobzwzMil7
-aWYocD5xKXIuYSs9Qy54Qi5OaihhLHEscCkKcT1wKzEKci5hKz1ILkx3KDkyKQpzd2l0Y2gobyl7Y2Fz
-ZSA4OnIuYSs9SC5Mdyg5OCkKYnJlYWsKY2FzZSA5OnIuYSs9SC5MdygxMTYpCmJyZWFrCmNhc2UgMTA6
-ci5hKz1ILkx3KDExMCkKYnJlYWsKY2FzZSAxMjpyLmErPUguTHcoMTAyKQpicmVhawpjYXNlIDEzOnIu
-YSs9SC5MdygxMTQpCmJyZWFrCmRlZmF1bHQ6ci5hKz1ILkx3KDExNykKci5hKz1ILkx3KDQ4KQpyLmEr
-PUguTHcoNDgpCm49bz4+PjQmMTUKci5hKz1ILkx3KG48MTA/NDgrbjo4NytuKQpuPW8mMTUKci5hKz1I
-Lkx3KG48MTA/NDgrbjo4NytuKQpicmVha319ZWxzZSBpZihvPT09MzR8fG89PT05Mil7aWYocD5xKXIu
-YSs9Qy54Qi5OaihhLHEscCkKcT1wKzEKci5hKz1ILkx3KDkyKQpyLmErPUguTHcobyl9fWlmKHE9PT0w
-KXIuYSs9SC5FaihhKQplbHNlIGlmKHE8bClyLmErPXMuTmooYSxxLGwpfSwKSm46ZnVuY3Rpb24oYSl7
-dmFyIHMscixxLHAKZm9yKHM9dGhpcy5hLHI9cy5sZW5ndGgscT0wO3E8cjsrK3Epe3A9c1txXQppZihh
-PT1udWxsP3A9PW51bGw6YT09PXApdGhyb3cgSC5iKG5ldyBQLks4KGEsbnVsbCkpfUMuTm0uaShzLGEp
-fSwKaVU6ZnVuY3Rpb24oYSl7dmFyIHMscixxLHAsbz10aGlzCmlmKG8udE0oYSkpcmV0dXJuCm8uSm4o
-YSkKdHJ5e3M9by5iLiQxKGEpCmlmKCFvLnRNKHMpKXtxPVAuR3koYSxudWxsLG8uZ1ZLKCkpCnRocm93
-IEguYihxKX1xPW8uYQppZigwPj1xLmxlbmd0aClyZXR1cm4gSC5PSChxLC0xKQpxLnBvcCgpfWNhdGNo
-KHApe3I9SC5SdShwKQpxPVAuR3koYSxyLG8uZ1ZLKCkpCnRocm93IEguYihxKX19LAp0TTpmdW5jdGlv
-bihhKXt2YXIgcyxyLHE9dGhpcwppZih0eXBlb2YgYT09Im51bWJlciIpe2lmKCFpc0Zpbml0ZShhKSly
-ZXR1cm4hMQpxLmMuYSs9Qy5DRC53KGEpCnJldHVybiEwfWVsc2UgaWYoYT09PSEwKXtxLmMuYSs9InRy
-dWUiCnJldHVybiEwfWVsc2UgaWYoYT09PSExKXtxLmMuYSs9ImZhbHNlIgpyZXR1cm4hMH1lbHNlIGlm
-KGE9PW51bGwpe3EuYy5hKz0ibnVsbCIKcmV0dXJuITB9ZWxzZSBpZih0eXBlb2YgYT09InN0cmluZyIp
-e3M9cS5jCnMuYSs9JyInCnEuUlQoYSkKcy5hKz0nIicKcmV0dXJuITB9ZWxzZSBpZih0LmouYihhKSl7
-cS5KbihhKQpxLmxLKGEpCnM9cS5hCmlmKDA+PXMubGVuZ3RoKXJldHVybiBILk9IKHMsLTEpCnMucG9w
-KCkKcmV0dXJuITB9ZWxzZSBpZih0LmYuYihhKSl7cS5KbihhKQpyPXEuancoYSkKcz1xLmEKaWYoMD49
-cy5sZW5ndGgpcmV0dXJuIEguT0gocywtMSkKcy5wb3AoKQpyZXR1cm4gcn1lbHNlIHJldHVybiExfSwK
-bEs6ZnVuY3Rpb24oYSl7dmFyIHMscixxPXRoaXMuYwpxLmErPSJbIgpzPUouVTYoYSkKaWYocy5nb3Io
-YSkpe3RoaXMuaVUocy5xKGEsMCkpCmZvcihyPTE7cjxzLmdBKGEpOysrcil7cS5hKz0iLCIKdGhpcy5p
-VShzLnEoYSxyKSl9fXEuYSs9Il0ifSwKanc6ZnVuY3Rpb24oYSl7dmFyIHMscixxLHAsbyxuLG09dGhp
-cyxsPXt9CmlmKGEuZ2wwKGEpKXttLmMuYSs9Int9IgpyZXR1cm4hMH1zPWEuZ0EoYSkqMgpyPVAuTzgo
-cyxudWxsLCExLHQuVykKcT1sLmE9MApsLmI9ITAKYS5LKDAsbmV3IFAudGkobCxyKSkKaWYoIWwuYily
-ZXR1cm4hMQpwPW0uYwpwLmErPSJ7Igpmb3Iobz0nIic7cTxzO3ErPTIsbz0nLCInKXtwLmErPW8KbS5S
-VChILmgocltxXSkpCnAuYSs9JyI6JwpuPXErMQppZihuPj1zKXJldHVybiBILk9IKHIsbikKbS5pVShy
-W25dKX1wLmErPSJ9IgpyZXR1cm4hMH19ClAudGkucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt2
-YXIgcyxyCmlmKHR5cGVvZiBhIT0ic3RyaW5nIil0aGlzLmEuYj0hMQpzPXRoaXMuYgpyPXRoaXMuYQpD
-Lk5tLlk1KHMsci5hKyssYSkKQy5ObS5ZNShzLHIuYSsrLGIpfSwKJFM6MTF9ClAudHUucHJvdG90eXBl
-PXsKZ1ZLOmZ1bmN0aW9uKCl7dmFyIHM9dGhpcy5jLmEKcmV0dXJuIHMuY2hhckNvZGVBdCgwKT09MD9z
-OnN9fQpQLnU1LnByb3RvdHlwZT17CmdaRTpmdW5jdGlvbigpe3JldHVybiBDLlFrfX0KUC5FMy5wcm90
-b3R5cGU9ewpXSjpmdW5jdGlvbihhKXt2YXIgcyxyLHEscD1QLmpCKDAsbnVsbCxhLmxlbmd0aCksbz1w
-LTAKaWYobz09PTApcmV0dXJuIG5ldyBVaW50OEFycmF5KDApCnM9byozCnI9bmV3IFVpbnQ4QXJyYXko
-cykKcT1uZXcgUC5SdyhyKQppZihxLkd4KGEsMCxwKSE9PXApe0ouYTYoYSxwLTEpCnEuUk8oKX1yZXR1
-cm4gbmV3IFVpbnQ4QXJyYXkoci5zdWJhcnJheSgwLEguck0oMCxxLmIscykpKX19ClAuUncucHJvdG90
-eXBlPXsKUk86ZnVuY3Rpb24oKXt2YXIgcz10aGlzLHI9cy5jLHE9cy5iLHA9cy5iPXErMSxvPXIubGVu
-Z3RoCmlmKHE+PW8pcmV0dXJuIEguT0gocixxKQpyW3FdPTIzOQpxPXMuYj1wKzEKaWYocD49bylyZXR1
-cm4gSC5PSChyLHApCnJbcF09MTkxCnMuYj1xKzEKaWYocT49bylyZXR1cm4gSC5PSChyLHEpCnJbcV09
-MTg5fSwKTzY6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEscCxvLG49dGhpcwppZigoYiY2NDUxMik9PT01
-NjMyMCl7cz02NTUzNisoKGEmMTAyMyk8PDEwKXxiJjEwMjMKcj1uLmMKcT1uLmIKcD1uLmI9cSsxCm89
-ci5sZW5ndGgKaWYocT49bylyZXR1cm4gSC5PSChyLHEpCnJbcV09cz4+PjE4fDI0MApxPW4uYj1wKzEK
-aWYocD49bylyZXR1cm4gSC5PSChyLHApCnJbcF09cz4+PjEyJjYzfDEyOApwPW4uYj1xKzEKaWYocT49
-bylyZXR1cm4gSC5PSChyLHEpCnJbcV09cz4+PjYmNjN8MTI4Cm4uYj1wKzEKaWYocD49bylyZXR1cm4g
-SC5PSChyLHApCnJbcF09cyY2M3wxMjgKcmV0dXJuITB9ZWxzZXtuLlJPKCkKcmV0dXJuITF9fSwKR3g6
-ZnVuY3Rpb24oYSxiLGMpe3ZhciBzLHIscSxwLG8sbixtLGw9dGhpcwppZihiIT09YyYmKEMueEIuTyhh
-LGMtMSkmNjQ1MTIpPT09NTUyOTYpLS1jCmZvcihzPWwuYyxyPXMubGVuZ3RoLHE9YjtxPGM7KytxKXtw
-PUMueEIuVyhhLHEpCmlmKHA8PTEyNyl7bz1sLmIKaWYobz49cilicmVhawpsLmI9bysxCnNbb109cH1l
-bHNle289cCY2NDUxMgppZihvPT09NTUyOTYpe2lmKGwuYis0PnIpYnJlYWsKbj1xKzEKaWYobC5PNihw
-LEMueEIuVyhhLG4pKSlxPW59ZWxzZSBpZihvPT09NTYzMjApe2lmKGwuYiszPnIpYnJlYWsKbC5STygp
-fWVsc2UgaWYocDw9MjA0Nyl7bz1sLmIKbT1vKzEKaWYobT49cilicmVhawpsLmI9bQppZihvPj1yKXJl
-dHVybiBILk9IKHMsbykKc1tvXT1wPj4+NnwxOTIKbC5iPW0rMQpzW21dPXAmNjN8MTI4fWVsc2V7bz1s
-LmIKaWYobysyPj1yKWJyZWFrCm09bC5iPW8rMQppZihvPj1yKXJldHVybiBILk9IKHMsbykKc1tvXT1w
-Pj4+MTJ8MjI0Cm89bC5iPW0rMQppZihtPj1yKXJldHVybiBILk9IKHMsbSkKc1ttXT1wPj4+NiY2M3wx
-MjgKbC5iPW8rMQppZihvPj1yKXJldHVybiBILk9IKHMsbykKc1tvXT1wJjYzfDEyOH19fXJldHVybiBx
-fX0KUC5HWS5wcm90b3R5cGU9ewpXSjpmdW5jdGlvbihhKXt2YXIgcyxyCnQuTC5hKGEpCnM9dGhpcy5h
-CnI9UC5reShzLGEsMCxudWxsKQppZihyIT1udWxsKXJldHVybiByCnJldHVybiBuZXcgUC5ieihzKS5O
-ZShhLDAsbnVsbCwhMCl9fQpQLmJ6LnByb3RvdHlwZT17Ck5lOmZ1bmN0aW9uKGEsYixjLGQpe3ZhciBz
-LHIscSxwLG8sbj10aGlzCnQuTC5hKGEpCnM9UC5qQihiLGMsSi5IbShhKSkKaWYoYj09PXMpcmV0dXJu
-IiIKcj1QLmp5KGEsYixzKQpxPW4uaE8ociwwLHMtYiwhMCkKcD1uLmIKaWYoKHAmMSkhPT0wKXtvPVAu
-ajQocCkKbi5iPTAKdGhyb3cgSC5iKFAucnIobyxhLGIrbi5jKSl9cmV0dXJuIHF9LApoTzpmdW5jdGlv
-bihhLGIsYyxkKXt2YXIgcyxyLHE9dGhpcwppZihjLWI+MTAwMCl7cz1DLmpuLkJVKGIrYywyKQpyPXEu
-aE8oYSxiLHMsITEpCmlmKChxLmImMSkhPT0wKXJldHVybiByCnJldHVybiByK3EuaE8oYSxzLGMsZCl9
-cmV0dXJuIHEuRWgoYSxiLGMsZCl9LApFaDpmdW5jdGlvbihhLGIsYyxkKXt2YXIgcyxyLHEscCxvLG4s
-bSxsLGs9dGhpcyxqPTY1NTMzLGk9ay5iLGg9ay5jLGc9bmV3IFAuUm4oIiIpLGY9YisxLGU9YS5sZW5n
-dGgKaWYoYjwwfHxiPj1lKXJldHVybiBILk9IKGEsYikKcz1hW2JdCiRsYWJlbDAkMDpmb3Iocj1rLmE7
-ITA7KXtmb3IoOyEwO2Y9byl7cT1DLnhCLlcoIkFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFB
+IGFbYl19fQpILmRFLnByb3RvdHlwZT17CnE6ZnVuY3Rpb24oYSxiKXtILnVQKGIpCkgub2QoYixhLGEu
+bGVuZ3RoKQpyZXR1cm4gYVtiXX19CkguWkEucHJvdG90eXBlPXsKcTpmdW5jdGlvbihhLGIpe0gudVAo
+YikKSC5vZChiLGEsYS5sZW5ndGgpCnJldHVybiBhW2JdfX0KSC5kVC5wcm90b3R5cGU9ewpxOmZ1bmN0
+aW9uKGEsYil7SC51UChiKQpILm9kKGIsYSxhLmxlbmd0aCkKcmV0dXJuIGFbYl19fQpILlBxLnByb3Rv
+dHlwZT17CnE6ZnVuY3Rpb24oYSxiKXtILnVQKGIpCkgub2QoYixhLGEubGVuZ3RoKQpyZXR1cm4gYVti
+XX19CkguZUUucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVuZ3RofSwKcTpmdW5j
+dGlvbihhLGIpe0gudVAoYikKSC5vZChiLGEsYS5sZW5ndGgpCnJldHVybiBhW2JdfX0KSC5WNi5wcm90
+b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gYS5sZW5ndGh9LApxOmZ1bmN0aW9uKGEsYil7SC51
+UChiKQpILm9kKGIsYSxhLmxlbmd0aCkKcmV0dXJuIGFbYl19LAokaVY2OjEsCiRpbjY6MX0KSC5SRy5w
+cm90b3R5cGU9e30KSC5WUC5wcm90b3R5cGU9e30KSC5XQi5wcm90b3R5cGU9e30KSC5aRy5wcm90b3R5
+cGU9e30KSC5KYy5wcm90b3R5cGU9ewpDOmZ1bmN0aW9uKGEpe3JldHVybiBILmNFKHYudHlwZVVuaXZl
+cnNlLHRoaXMsYSl9LApLcTpmdW5jdGlvbihhKXtyZXR1cm4gSC52NSh2LnR5cGVVbml2ZXJzZSx0aGlz
+LGEpfX0KSC5HLnByb3RvdHlwZT17fQpILmxZLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7cmV0dXJu
+IEguZG0odGhpcy5hLG51bGwpfX0KSC5rUy5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiB0
+aGlzLmF9fQpILmlNLnByb3RvdHlwZT17fQpQLnRoLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3Zh
+ciBzPXRoaXMuYSxyPXMuYQpzLmE9bnVsbApyLiQwKCl9LAokUzoxMH0KUC5oYS5wcm90b3R5cGU9ewok
+MTpmdW5jdGlvbihhKXt2YXIgcyxyCnRoaXMuYS5hPXQuTS5hKGEpCnM9dGhpcy5iCnI9dGhpcy5jCnMu
+Zmlyc3RDaGlsZD9zLnJlbW92ZUNoaWxkKHIpOnMuYXBwZW5kQ2hpbGQocil9LAokUzo1M30KUC5Wcy5w
+cm90b3R5cGU9ewokMDpmdW5jdGlvbigpe3RoaXMuYS4kMCgpfSwKJEM6IiQwIiwKJFI6MCwKJFM6Mn0K
+UC5GdC5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe3RoaXMuYS4kMCgpfSwKJEM6IiQwIiwKJFI6MCwK
+JFM6Mn0KUC5XMy5wcm90b3R5cGU9ewpDWTpmdW5jdGlvbihhLGIpe2lmKHNlbGYuc2V0VGltZW91dCE9
+bnVsbClzZWxmLnNldFRpbWVvdXQoSC50UihuZXcgUC55SCh0aGlzLGIpLDApLGEpCmVsc2UgdGhyb3cg
+SC5iKFAuTDQoImBzZXRUaW1lb3V0KClgIG5vdCBmb3VuZC4iKSl9fQpQLnlILnByb3RvdHlwZT17CiQw
+OmZ1bmN0aW9uKCl7dGhpcy5iLiQwKCl9LAokQzoiJDAiLAokUjowLAokUzowfQpQLmloLnByb3RvdHlw
+ZT17CmFNOmZ1bmN0aW9uKGEsYil7dmFyIHMscj10aGlzLHE9ci4kdGkKcS5DKCIxLz8iKS5hKGIpCmlm
+KCFyLmIpci5hLlhmKGIpCmVsc2V7cz1yLmEKaWYocS5DKCJiODwxPiIpLmIoYikpcy5jVShiKQplbHNl
+IHMuWDIocS5jLmEoYikpfX0sCncwOmZ1bmN0aW9uKGEsYil7dmFyIHMKaWYoYj09bnVsbCliPVAudjAo
+YSkKcz10aGlzLmEKaWYodGhpcy5iKXMuWkwoYSxiKQplbHNlIHMuTmsoYSxiKX19ClAuV00ucHJvdG90
+eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYS4kMigwLGEpfSwKJFM6NDN9ClAuU1gucHJv
+dG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt0aGlzLmEuJDIoMSxuZXcgSC5icShhLHQubC5hKGIpKSl9
+LAokQzoiJDIiLAokUjoyLAokUzo1NX0KUC5Hcy5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3Ro
+aXMuYShILnVQKGEpLGIpfSwKJFM6MjR9ClAuRnkucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1
+cm4iSXRlcmF0aW9uTWFya2VyKCIrdGhpcy5iKyIsICIrSC5Faih0aGlzLmEpKyIpIn19ClAuR1YucHJv
+dG90eXBlPXsKZ2w6ZnVuY3Rpb24oKXt2YXIgcz10aGlzLmMKaWYocz09bnVsbClyZXR1cm4gdGhpcy4k
+dGkuYy5hKHRoaXMuYikKcmV0dXJuIHMuZ2woKX0sCkY6ZnVuY3Rpb24oKXt2YXIgcyxyLHEscCxvLG4s
+bT10aGlzCmZvcihzPW0uJHRpLkMoIkFuPDE+Iik7ITA7KXtyPW0uYwppZihyIT1udWxsKWlmKHIuRigp
+KXJldHVybiEwCmVsc2UgbS5zWDkobnVsbCkKcT1mdW5jdGlvbihhLGIsYyl7dmFyIGwsaz1iCndoaWxl
+KHRydWUpdHJ5e3JldHVybiBhKGssbCl9Y2F0Y2goail7bD1qCms9Y319KG0uYSwwLDEpCmlmKHEgaW5z
+dGFuY2VvZiBQLkZ5KXtwPXEuYgppZihwPT09Mil7bz1tLmQKaWYobz09bnVsbHx8by5sZW5ndGg9PT0w
+KXttLnNFQyhudWxsKQpyZXR1cm4hMX1pZigwPj1vLmxlbmd0aClyZXR1cm4gSC5PSChvLC0xKQptLmE9
+by5wb3AoKQpjb250aW51ZX1lbHNle3I9cS5hCmlmKHA9PT0zKXRocm93IHIKZWxzZXtuPXMuYShKLklU
+KHIpKQppZihuIGluc3RhbmNlb2YgUC5HVil7cj1tLmQKaWYocj09bnVsbClyPW0uZD1bXQpDLk5tLmko
+cixtLmEpCm0uYT1uLmEKY29udGludWV9ZWxzZXttLnNYOShuKQpjb250aW51ZX19fX1lbHNle20uc0VD
+KHEpCnJldHVybiEwfX1yZXR1cm4hMX0sCnNFQzpmdW5jdGlvbihhKXt0aGlzLmI9dGhpcy4kdGkuQygi
+MT8iKS5hKGEpfSwKc1g5OmZ1bmN0aW9uKGEpe3RoaXMuYz10aGlzLiR0aS5DKCJBbjwxPj8iKS5hKGEp
+fSwKJGlBbjoxfQpQLnE0LnByb3RvdHlwZT17CmdtOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgUC5HVih0
+aGlzLmEoKSx0aGlzLiR0aS5DKCJHVjwxPiIpKX19ClAuQ3cucHJvdG90eXBlPXsKdzpmdW5jdGlvbihh
+KXtyZXR1cm4gSC5Faih0aGlzLmEpfSwKJGlYUzoxLApnSUk6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5i
+fX0KUC5QZi5wcm90b3R5cGU9ewp3MDpmdW5jdGlvbihhLGIpe3ZhciBzCkguY2IoYSwiZXJyb3IiLHQu
+SykKcz10aGlzLmEKaWYocy5hIT09MCl0aHJvdyBILmIoUC5QVigiRnV0dXJlIGFscmVhZHkgY29tcGxl
+dGVkIikpCmlmKGI9PW51bGwpYj1QLnYwKGEpCnMuTmsoYSxiKX0sCnBtOmZ1bmN0aW9uKGEpe3JldHVy
+biB0aGlzLncwKGEsbnVsbCl9fQpQLlpmLnByb3RvdHlwZT17CmFNOmZ1bmN0aW9uKGEsYil7dmFyIHMs
+cj10aGlzLiR0aQpyLkMoIjEvPyIpLmEoYikKcz10aGlzLmEKaWYocy5hIT09MCl0aHJvdyBILmIoUC5Q
+VigiRnV0dXJlIGFscmVhZHkgY29tcGxldGVkIikpCnMuWGYoci5DKCIxLyIpLmEoYikpfX0KUC5GZS5w
+cm90b3R5cGU9ewpIUjpmdW5jdGlvbihhKXtpZigodGhpcy5jJjE1KSE9PTYpcmV0dXJuITAKcmV0dXJu
+IHRoaXMuYi5iLmJ2KHQuYWwuYSh0aGlzLmQpLGEuYSx0LnksdC5LKX0sCkt3OmZ1bmN0aW9uKGEpe3Zh
+ciBzPXRoaXMuZSxyPXQueixxPXQuSyxwPXRoaXMuJHRpLkMoIjIvIiksbz10aGlzLmIuYgppZih0LmFn
+LmIocykpcmV0dXJuIHAuYShvLnJwKHMsYS5hLGEuYixyLHEsdC5sKSkKZWxzZSByZXR1cm4gcC5hKG8u
+YnYodC5iSS5hKHMpLGEuYSxyLHEpKX19ClAudnMucHJvdG90eXBlPXsKU3E6ZnVuY3Rpb24oYSxiLGMp
+e3ZhciBzLHIscSxwPXRoaXMuJHRpCnAuS3EoYykuQygiMS8oMikiKS5hKGEpCnM9JC5YMwppZihzIT09
+Qy5OVSl7Yy5DKCJAPDAvPiIpLktxKHAuYykuQygiMSgyKSIpLmEoYSkKaWYoYiE9bnVsbCliPVAuVkgo
+YixzKX1yPW5ldyBQLnZzKHMsYy5DKCJ2czwwPiIpKQpxPWI9PW51bGw/MTozCnRoaXMueGYobmV3IFAu
+RmUocixxLGEsYixwLkMoIkA8MT4iKS5LcShjKS5DKCJGZTwxLDI+IikpKQpyZXR1cm4gcn0sClc3OmZ1
+bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuU3EoYSxudWxsLGIpfSwKUWQ6ZnVuY3Rpb24oYSxiLGMpe3Zh
+ciBzLHI9dGhpcy4kdGkKci5LcShjKS5DKCIxLygyKSIpLmEoYSkKcz1uZXcgUC52cygkLlgzLGMuQygi
+dnM8MD4iKSkKdGhpcy54ZihuZXcgUC5GZShzLDE5LGEsYixyLkMoIkA8MT4iKS5LcShjKS5DKCJGZTwx
+LDI+IikpKQpyZXR1cm4gc30sCnhmOmZ1bmN0aW9uKGEpe3ZhciBzLHI9dGhpcyxxPXIuYQppZihxPD0x
+KXthLmE9dC5GLmEoci5jKQpyLmM9YX1lbHNle2lmKHE9PT0yKXtzPXQuYy5hKHIuYykKcT1zLmEKaWYo
+cTw0KXtzLnhmKGEpCnJldHVybn1yLmE9cQpyLmM9cy5jfVAuVGsobnVsbCxudWxsLHIuYix0Lk0uYShu
+ZXcgUC5kYShyLGEpKSl9fSwKalE6ZnVuY3Rpb24oYSl7dmFyIHMscixxLHAsbyxuLG09dGhpcyxsPXt9
+CmwuYT1hCmlmKGE9PW51bGwpcmV0dXJuCnM9bS5hCmlmKHM8PTEpe3I9dC5GLmEobS5jKQptLmM9YQpp
+ZihyIT1udWxsKXtxPWEuYQpmb3IocD1hO3EhPW51bGw7cD1xLHE9bylvPXEuYQpwLmE9cn19ZWxzZXtp
+ZihzPT09Mil7bj10LmMuYShtLmMpCnM9bi5hCmlmKHM8NCl7bi5qUShhKQpyZXR1cm59bS5hPXMKbS5j
+PW4uY31sLmE9bS5OOChhKQpQLlRrKG51bGwsbnVsbCxtLmIsdC5NLmEobmV3IFAub1EobCxtKSkpfX0s
+CmFoOmZ1bmN0aW9uKCl7dmFyIHM9dC5GLmEodGhpcy5jKQp0aGlzLmM9bnVsbApyZXR1cm4gdGhpcy5O
+OChzKX0sCk44OmZ1bmN0aW9uKGEpe3ZhciBzLHIscQpmb3Iocz1hLHI9bnVsbDtzIT1udWxsO3I9cyxz
+PXEpe3E9cy5hCnMuYT1yfXJldHVybiByfSwKZWM6ZnVuY3Rpb24oYSl7dmFyIHMscixxLHA9dGhpcwpw
+LmE9MQp0cnl7YS5TcShuZXcgUC5wVihwKSxuZXcgUC5VNyhwKSx0LlApfWNhdGNoKHEpe3M9SC5SdShx
+KQpyPUgudHMocSkKUC5yYihuZXcgUC52cihwLHMscikpfX0sClgyOmZ1bmN0aW9uKGEpe3ZhciBzLHI9
+dGhpcwpyLiR0aS5jLmEoYSkKcz1yLmFoKCkKci5hPTQKci5jPWEKUC5IWihyLHMpfSwKWkw6ZnVuY3Rp
+b24oYSxiKXt2YXIgcyxyLHE9dGhpcwp0LmwuYShiKQpzPXEuYWgoKQpyPVAuVGwoYSxiKQpxLmE9OApx
+LmM9cgpQLkhaKHEscyl9LApYZjpmdW5jdGlvbihhKXt2YXIgcz10aGlzLiR0aQpzLkMoIjEvIikuYShh
+KQppZihzLkMoImI4PDE+IikuYihhKSl7dGhpcy5jVShhKQpyZXR1cm59dGhpcy53VShzLmMuYShhKSl9
+LAp3VTpmdW5jdGlvbihhKXt2YXIgcz10aGlzCnMuJHRpLmMuYShhKQpzLmE9MQpQLlRrKG51bGwsbnVs
+bCxzLmIsdC5NLmEobmV3IFAucnQocyxhKSkpfSwKY1U6ZnVuY3Rpb24oYSl7dmFyIHM9dGhpcyxyPXMu
+JHRpCnIuQygiYjg8MT4iKS5hKGEpCmlmKHIuYihhKSl7aWYoYS5hPT09OCl7cy5hPTEKUC5UayhudWxs
+LG51bGwscy5iLHQuTS5hKG5ldyBQLktGKHMsYSkpKX1lbHNlIFAuQTkoYSxzKQpyZXR1cm59cy5lYyhh
+KX0sCk5rOmZ1bmN0aW9uKGEsYil7dGhpcy5hPTEKUC5UayhudWxsLG51bGwsdGhpcy5iLHQuTS5hKG5l
+dyBQLlpMKHRoaXMsYSxiKSkpfSwKJGliODoxfQpQLmRhLnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7
+UC5IWih0aGlzLmEsdGhpcy5iKX0sCiRTOjB9ClAub1EucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXtQ
+LkhaKHRoaXMuYix0aGlzLmEuYSl9LAokUzowfQpQLnBWLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEp
+e3ZhciBzLHIscSxwPXRoaXMuYQpwLmE9MAp0cnl7cC5YMihwLiR0aS5jLmEoYSkpfWNhdGNoKHEpe3M9
+SC5SdShxKQpyPUgudHMocSkKcC5aTChzLHIpfX0sCiRTOjEwfQpQLlU3LnByb3RvdHlwZT17CiQyOmZ1
+bmN0aW9uKGEsYil7dGhpcy5hLlpMKGEsdC5sLmEoYikpfSwKJEM6IiQyIiwKJFI6MiwKJFM6Mjh9ClAu
+dnIucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXt0aGlzLmEuWkwodGhpcy5iLHRoaXMuYyl9LAokUzow
+fQpQLnJ0LnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7dGhpcy5hLlgyKHRoaXMuYil9LAokUzowfQpQ
+LktGLnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7UC5BOSh0aGlzLmIsdGhpcy5hKX0sCiRTOjB9ClAu
+WkwucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXt0aGlzLmEuWkwodGhpcy5iLHRoaXMuYyl9LAokUzow
+fQpQLlJULnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7dmFyIHMscixxLHAsbyxuLG09dGhpcyxsPW51
+bGwKdHJ5e3E9bS5hLmEKbD1xLmIuYi56eih0LmZPLmEocS5kKSx0LnopfWNhdGNoKHApe3M9SC5SdShw
+KQpyPUgudHMocCkKaWYobS5jKXtxPXQubi5hKG0uYi5hLmMpLmEKbz1zCm89cT09bnVsbD9vPT1udWxs
+OnE9PT1vCnE9b31lbHNlIHE9ITEKbz1tLmEKaWYocSlvLmM9dC5uLmEobS5iLmEuYykKZWxzZSBvLmM9
+UC5UbChzLHIpCm8uYj0hMApyZXR1cm59aWYobCBpbnN0YW5jZW9mIFAudnMmJmwuYT49NCl7aWYobC5h
+PT09OCl7cT1tLmEKcS5jPXQubi5hKGwuYykKcS5iPSEwfXJldHVybn1pZih0LmUuYihsKSl7bj1tLmIu
+YQpxPW0uYQpxLmM9bC5XNyhuZXcgUC5qWihuKSx0LnopCnEuYj0hMX19LAokUzowfQpQLmpaLnByb3Rv
+dHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmF9LAokUzoyOX0KUC5ycS5wcm90b3R5cGU9
+ewokMDpmdW5jdGlvbigpe3ZhciBzLHIscSxwLG8sbixtLGwKdHJ5e3E9dGhpcy5hCnA9cS5hCm89cC4k
+dGkKbj1vLmMKbT1uLmEodGhpcy5iKQpxLmM9cC5iLmIuYnYoby5DKCIyLygxKSIpLmEocC5kKSxtLG8u
+QygiMi8iKSxuKX1jYXRjaChsKXtzPUguUnUobCkKcj1ILnRzKGwpCnE9dGhpcy5hCnEuYz1QLlRsKHMs
+cikKcS5iPSEwfX0sCiRTOjB9ClAuUlcucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXt2YXIgcyxyLHEs
+cCxvLG4sbSxsLGs9dGhpcwp0cnl7cz10Lm4uYShrLmEuYS5jKQpwPWsuYgppZihILm9UKHAuYS5IUihz
+KSkmJnAuYS5lIT1udWxsKXtwLmM9cC5hLkt3KHMpCnAuYj0hMX19Y2F0Y2gobyl7cj1ILlJ1KG8pCnE9
+SC50cyhvKQpwPXQubi5hKGsuYS5hLmMpCm49cC5hCm09cgpsPWsuYgppZihuPT1udWxsP209PW51bGw6
+bj09PW0pbC5jPXAKZWxzZSBsLmM9UC5UbChyLHEpCmwuYj0hMH19LAokUzowfQpQLk9NLnByb3RvdHlw
+ZT17fQpQLnFoLnByb3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3ZhciBzLHIscT10aGlzLHA9e30sbz1u
+ZXcgUC52cygkLlgzLHQuZkopCnAuYT0wCnM9SC5MaChxKQpyPXMuQygifigxKT8iKS5hKG5ldyBQLkI1
+KHAscSkpCnQuWi5hKG5ldyBQLnVPKHAsbykpClcuSkUocS5hLHEuYixyLCExLHMuYykKcmV0dXJuIG99
+fQpQLkI1LnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe0guTGgodGhpcy5iKS5jLmEoYSk7Kyt0aGlz
+LmEuYX0sCiRTOmZ1bmN0aW9uKCl7cmV0dXJuIEguTGgodGhpcy5iKS5DKCJ+KDEpIil9fQpQLnVPLnBy
+b3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7dmFyIHM9dGhpcy5iLHI9cy4kdGkscT1yLkMoIjEvIikuYSh0
+aGlzLmEuYSkscD1zLmFoKCkKci5jLmEocSkKcy5hPTQKcy5jPXEKUC5IWihzLHApfSwKJFM6MH0KUC5N
+Ty5wcm90b3R5cGU9e30KUC5rVC5wcm90b3R5cGU9e30KUC54SS5wcm90b3R5cGU9e30KUC5tMC5wcm90
+b3R5cGU9eyRpUW06MX0KUC5wSy5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe3ZhciBzPUguYih0aGlz
+LmEpCnMuc3RhY2s9Si5qKHRoaXMuYikKdGhyb3cgc30sCiRTOjB9ClAuSmkucHJvdG90eXBlPXsKYkg6
+ZnVuY3Rpb24oYSl7dmFyIHMscixxLHA9bnVsbAp0Lk0uYShhKQp0cnl7aWYoQy5OVT09PSQuWDMpe2Eu
+JDAoKQpyZXR1cm59UC5UOChwLHAsdGhpcyxhLHQuSCl9Y2F0Y2gocSl7cz1ILlJ1KHEpCnI9SC50cyhx
+KQpQLkwyKHAscCx0aGlzLHMsdC5sLmEocikpfX0sCkRsOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyLHEs
+cD1udWxsCmMuQygifigwKSIpLmEoYSkKYy5hKGIpCnRyeXtpZihDLk5VPT09JC5YMyl7YS4kMShiKQpy
+ZXR1cm59UC55dihwLHAsdGhpcyxhLGIsdC5ILGMpfWNhdGNoKHEpe3M9SC5SdShxKQpyPUgudHMocSkK
+UC5MMihwLHAsdGhpcyxzLHQubC5hKHIpKX19LApHWTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFAuVnAo
+dGhpcyx0Lk0uYShhKSl9LApQeTpmdW5jdGlvbihhLGIpe3JldHVybiBuZXcgUC5PUih0aGlzLGIuQygi
+figwKSIpLmEoYSksYil9LApxOmZ1bmN0aW9uKGEsYil7cmV0dXJuIG51bGx9LAp6ejpmdW5jdGlvbihh
+LGIpe2IuQygiMCgpIikuYShhKQppZigkLlgzPT09Qy5OVSlyZXR1cm4gYS4kMCgpCnJldHVybiBQLlQ4
+KG51bGwsbnVsbCx0aGlzLGEsYil9LApidjpmdW5jdGlvbihhLGIsYyxkKXtjLkMoIkA8MD4iKS5LcShk
+KS5DKCIxKDIpIikuYShhKQpkLmEoYikKaWYoJC5YMz09PUMuTlUpcmV0dXJuIGEuJDEoYikKcmV0dXJu
+IFAueXYobnVsbCxudWxsLHRoaXMsYSxiLGMsZCl9LApycDpmdW5jdGlvbihhLGIsYyxkLGUsZil7ZC5D
+KCJAPDA+IikuS3EoZSkuS3EoZikuQygiMSgyLDMpIikuYShhKQplLmEoYikKZi5hKGMpCmlmKCQuWDM9
+PT1DLk5VKXJldHVybiBhLiQyKGIsYykKcmV0dXJuIFAuUXgobnVsbCxudWxsLHRoaXMsYSxiLGMsZCxl
+LGYpfSwKTGo6ZnVuY3Rpb24oYSxiLGMsZCl7cmV0dXJuIGIuQygiQDwwPiIpLktxKGMpLktxKGQpLkMo
+IjEoMiwzKSIpLmEoYSl9fQpQLlZwLnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMu
+YS5iSCh0aGlzLmIpfSwKJFM6MH0KUC5PUi5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgcz10
+aGlzLmMKcmV0dXJuIHRoaXMuYS5EbCh0aGlzLmIscy5hKGEpLHMpfSwKJFM6ZnVuY3Rpb24oKXtyZXR1
+cm4gdGhpcy5jLkMoIn4oMCkiKX19ClAuYjYucHJvdG90eXBlPXsKZ206ZnVuY3Rpb24oYSl7dmFyIHM9
+dGhpcyxyPW5ldyBQLmxtKHMscy5yLEguTGgocykuQygibG08MT4iKSkKci5jPXMuZQpyZXR1cm4gcn0s
+CmdBOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmF9LApnbDA6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMu
+YT09PTB9LApnb3I6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYSE9PTB9LAp0ZzpmdW5jdGlvbihhLGIp
+e3ZhciBzLHIKaWYodHlwZW9mIGI9PSJzdHJpbmciJiZiIT09Il9fcHJvdG9fXyIpe3M9dGhpcy5iCmlm
+KHM9PW51bGwpcmV0dXJuITEKcmV0dXJuIHQubS5hKHNbYl0pIT1udWxsfWVsc2V7cj10aGlzLlBSKGIp
+CnJldHVybiByfX0sClBSOmZ1bmN0aW9uKGEpe3ZhciBzPXRoaXMuZAppZihzPT1udWxsKXJldHVybiEx
+CnJldHVybiB0aGlzLkRGKHNbdGhpcy5OKGEpXSxhKT49MH0sCmk6ZnVuY3Rpb24oYSxiKXt2YXIgcyxy
+LHE9dGhpcwpILkxoKHEpLmMuYShiKQppZih0eXBlb2YgYj09InN0cmluZyImJmIhPT0iX19wcm90b19f
+Iil7cz1xLmIKcmV0dXJuIHEuYlEocz09bnVsbD9xLmI9UC5UMigpOnMsYil9ZWxzZSBpZih0eXBlb2Yg
+Yj09Im51bWJlciImJihiJjEwNzM3NDE4MjMpPT09Yil7cj1xLmMKcmV0dXJuIHEuYlEocj09bnVsbD9x
+LmM9UC5UMigpOnIsYil9ZWxzZSByZXR1cm4gcS5CNyhiKX0sCkI3OmZ1bmN0aW9uKGEpe3ZhciBzLHIs
+cSxwPXRoaXMKSC5MaChwKS5jLmEoYSkKcz1wLmQKaWYocz09bnVsbClzPXAuZD1QLlQyKCkKcj1wLk4o
+YSkKcT1zW3JdCmlmKHE9PW51bGwpc1tyXT1bcC55byhhKV0KZWxzZXtpZihwLkRGKHEsYSk+PTApcmV0
+dXJuITEKcS5wdXNoKHAueW8oYSkpfXJldHVybiEwfSwKUjpmdW5jdGlvbihhLGIpe3ZhciBzPXRoaXMK
+aWYodHlwZW9mIGI9PSJzdHJpbmciJiZiIT09Il9fcHJvdG9fXyIpcmV0dXJuIHMuSChzLmIsYikKZWxz
+ZSBpZih0eXBlb2YgYj09Im51bWJlciImJihiJjEwNzM3NDE4MjMpPT09YilyZXR1cm4gcy5IKHMuYyxi
+KQplbHNlIHJldHVybiBzLnFnKGIpfSwKcWc6ZnVuY3Rpb24oYSl7dmFyIHMscixxLHAsbz10aGlzLG49
+by5kCmlmKG49PW51bGwpcmV0dXJuITEKcz1vLk4oYSkKcj1uW3NdCnE9by5ERihyLGEpCmlmKHE8MCly
+ZXR1cm4hMQpwPXIuc3BsaWNlKHEsMSlbMF0KaWYoMD09PXIubGVuZ3RoKWRlbGV0ZSBuW3NdCm8uRyhw
+KQpyZXR1cm4hMH0sCmJROmZ1bmN0aW9uKGEsYil7SC5MaCh0aGlzKS5jLmEoYikKaWYodC5tLmEoYVti
+XSkhPW51bGwpcmV0dXJuITEKYVtiXT10aGlzLnlvKGIpCnJldHVybiEwfSwKSDpmdW5jdGlvbihhLGIp
+e3ZhciBzCmlmKGE9PW51bGwpcmV0dXJuITEKcz10Lm0uYShhW2JdKQppZihzPT1udWxsKXJldHVybiEx
+CnRoaXMuRyhzKQpkZWxldGUgYVtiXQpyZXR1cm4hMH0sClM6ZnVuY3Rpb24oKXt0aGlzLnI9dGhpcy5y
+KzEmMTA3Mzc0MTgyM30sCnlvOmZ1bmN0aW9uKGEpe3ZhciBzLHI9dGhpcyxxPW5ldyBQLmJuKEguTGgo
+cikuYy5hKGEpKQppZihyLmU9PW51bGwpci5lPXIuZj1xCmVsc2V7cz1yLmYKcy50b1N0cmluZwpxLmM9
+cwpyLmY9cy5iPXF9KytyLmEKci5TKCkKcmV0dXJuIHF9LApHOmZ1bmN0aW9uKGEpe3ZhciBzPXRoaXMs
+cj1hLmMscT1hLmIKaWYocj09bnVsbClzLmU9cQplbHNlIHIuYj1xCmlmKHE9PW51bGwpcy5mPXIKZWxz
+ZSBxLmM9cjstLXMuYQpzLlMoKX0sCk46ZnVuY3Rpb24oYSl7cmV0dXJuIEouaGYoYSkmMTA3Mzc0MTgy
+M30sCkRGOmZ1bmN0aW9uKGEsYil7dmFyIHMscgppZihhPT1udWxsKXJldHVybi0xCnM9YS5sZW5ndGgK
+Zm9yKHI9MDtyPHM7KytyKWlmKEouUk0oYVtyXS5hLGIpKXJldHVybiByCnJldHVybi0xfX0KUC5ibi5w
+cm90b3R5cGU9e30KUC5sbS5wcm90b3R5cGU9ewpnbDpmdW5jdGlvbigpe3JldHVybiB0aGlzLmR9LApG
+OmZ1bmN0aW9uKCl7dmFyIHM9dGhpcyxyPXMuYyxxPXMuYQppZihzLmIhPT1xLnIpdGhyb3cgSC5iKFAu
+YTQocSkpCmVsc2UgaWYocj09bnVsbCl7cy5zaihudWxsKQpyZXR1cm4hMX1lbHNle3Muc2oocy4kdGku
+QygiMT8iKS5hKHIuYSkpCnMuYz1yLmIKcmV0dXJuITB9fSwKc2o6ZnVuY3Rpb24oYSl7dGhpcy5kPXRo
+aXMuJHRpLkMoIjE/IikuYShhKX0sCiRpQW46MX0KUC5tVy5wcm90b3R5cGU9e30KUC51eS5wcm90b3R5
+cGU9eyRpYlE6MSwkaWNYOjEsJGl6TToxfQpQLmxELnByb3RvdHlwZT17CmdtOmZ1bmN0aW9uKGEpe3Jl
+dHVybiBuZXcgSC5hNyhhLHRoaXMuZ0EoYSksSC56KGEpLkMoImE3PGxELkU+IikpfSwKRTpmdW5jdGlv
+bihhLGIpe3JldHVybiB0aGlzLnEoYSxiKX0sCks6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyCkgueihhKS5D
+KCJ+KGxELkUpIikuYShiKQpzPXRoaXMuZ0EoYSkKZm9yKHI9MDtyPHM7KytyKXtiLiQxKHRoaXMucShh
+LHIpKQppZihzIT09dGhpcy5nQShhKSl0aHJvdyBILmIoUC5hNChhKSl9fSwKZ2wwOmZ1bmN0aW9uKGEp
+e3JldHVybiB0aGlzLmdBKGEpPT09MH0sCmdvcjpmdW5jdGlvbihhKXtyZXR1cm4hdGhpcy5nbDAoYSl9
+LApFMjpmdW5jdGlvbihhLGIsYyl7dmFyIHM9SC56KGEpCnJldHVybiBuZXcgSC5sSihhLHMuS3EoYyku
+QygiMShsRC5FKSIpLmEoYikscy5DKCJAPGxELkU+IikuS3EoYykuQygibEo8MSwyPiIpKX0sCmVSOmZ1
+bmN0aW9uKGEsYil7cmV0dXJuIEgucUMoYSxiLG51bGwsSC56KGEpLkMoImxELkUiKSl9LApkcjpmdW5j
+dGlvbihhLGIpe3JldHVybiBuZXcgSC5qVihhLEgueihhKS5DKCJAPGxELkU+IikuS3EoYikuQygialY8
+MSwyPiIpKX0sCmR1OmZ1bmN0aW9uKGEsYixjLGQpe3ZhciBzCkgueihhKS5DKCJsRC5FPyIpLmEoZCkK
+UC5qQihiLGMsdGhpcy5nQShhKSkKZm9yKHM9YjtzPGM7KytzKXRoaXMuWTUoYSxzLGQpfSwKdzpmdW5j
+dGlvbihhKXtyZXR1cm4gUC5XRShhLCJbIiwiXSIpfX0KUC5pbC5wcm90b3R5cGU9e30KUC5yYS5wcm90
+b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3ZhciBzLHI9dGhpcy5hCmlmKCFyLmEpdGhpcy5iLmErPSIs
+ICIKci5hPSExCnI9dGhpcy5iCnM9ci5hKz1ILkVqKGEpCnIuYT1zKyI6ICIKci5hKz1ILkVqKGIpfSwK
+JFM6MTF9ClAuWWsucHJvdG90eXBlPXsKSzpmdW5jdGlvbihhLGIpe3ZhciBzLHIKSC5MaCh0aGlzKS5D
+KCJ+KFlrLkssWWsuVikiKS5hKGIpCmZvcihzPUouSVQodGhpcy5ndmMoKSk7cy5GKCk7KXtyPXMuZ2wo
+KQpiLiQyKHIsdGhpcy5xKDAscikpfX0sCmdQdTpmdW5jdGlvbihhKXtyZXR1cm4gSi5NMSh0aGlzLmd2
+YygpLG5ldyBQLnlRKHRoaXMpLEguTGgodGhpcykuQygiTjM8WWsuSyxZay5WPiIpKX0sCng0OmZ1bmN0
+aW9uKGEpe3JldHVybiBKLnpsKHRoaXMuZ3ZjKCksYSl9LApnQTpmdW5jdGlvbihhKXtyZXR1cm4gSi5I
+bSh0aGlzLmd2YygpKX0sCmdsMDpmdW5jdGlvbihhKXtyZXR1cm4gSi51VSh0aGlzLmd2YygpKX0sCnc6
+ZnVuY3Rpb24oYSl7cmV0dXJuIFAubk8odGhpcyl9LAokaVowOjF9ClAueVEucHJvdG90eXBlPXsKJDE6
+ZnVuY3Rpb24oYSl7dmFyIHM9dGhpcy5hLHI9SC5MaChzKQpyLkMoIllrLksiKS5hKGEpCnJldHVybiBu
+ZXcgUC5OMyhhLHMucSgwLGEpLHIuQygiQDxZay5LPiIpLktxKHIuQygiWWsuViIpKS5DKCJOMzwxLDI+
+IikpfSwKJFM6ZnVuY3Rpb24oKXtyZXR1cm4gSC5MaCh0aGlzLmEpLkMoIk4zPFlrLkssWWsuVj4oWWsu
+SykiKX19ClAuS1AucHJvdG90eXBlPXsKWTU6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzPUguTGgodGhpcykK
+cy5jLmEoYikKcy5RWzFdLmEoYykKdGhyb3cgSC5iKFAuTDQoIkNhbm5vdCBtb2RpZnkgdW5tb2RpZmlh
+YmxlIG1hcCIpKX19ClAuUG4ucHJvdG90eXBlPXsKcTpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLmEu
+cSgwLGIpfSwKWTU6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzPUguTGgodGhpcykKdGhpcy5hLlk1KDAscy5j
+LmEoYikscy5RWzFdLmEoYykpfSwKeDQ6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYS54NChhKX0sCks6
+ZnVuY3Rpb24oYSxiKXt0aGlzLmEuSygwLEguTGgodGhpcykuQygifigxLDIpIikuYShiKSl9LApnbDA6
+ZnVuY3Rpb24oYSl7dmFyIHM9dGhpcy5hCnJldHVybiBzLmdsMChzKX0sCmdBOmZ1bmN0aW9uKGEpe3Zh
+ciBzPXRoaXMuYQpyZXR1cm4gcy5nQShzKX0sCnc6ZnVuY3Rpb24oYSl7cmV0dXJuIEouaih0aGlzLmEp
+fSwKZ1B1OmZ1bmN0aW9uKGEpe3ZhciBzPXRoaXMuYQpyZXR1cm4gcy5nUHUocyl9LAokaVowOjF9ClAu
+R2oucHJvdG90eXBlPXt9ClAubGYucHJvdG90eXBlPXsKZ2wwOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlz
+LmdBKHRoaXMpPT09MH0sCmdvcjpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5nQSh0aGlzKSE9PTB9LApG
+VjpmdW5jdGlvbihhLGIpe3ZhciBzCmZvcihzPUouSVQoSC5MaCh0aGlzKS5DKCJjWDxsZi5FPiIpLmEo
+YikpO3MuRigpOyl0aGlzLmkoMCxzLmdsKCkpfSwKdzpmdW5jdGlvbihhKXtyZXR1cm4gUC5XRSh0aGlz
+LCJ7IiwifSIpfSwKazpmdW5jdGlvbihhLGIpe3ZhciBzLHI9dGhpcy5nbSh0aGlzKQppZighci5GKCkp
+cmV0dXJuIiIKaWYoYj09PSIiKXtzPSIiCmRvIHMrPUguRWooci5kKQp3aGlsZShyLkYoKSl9ZWxzZXtz
+PUguRWooci5kKQpmb3IoO3IuRigpOylzPXMrYitILkVqKHIuZCl9cmV0dXJuIHMuY2hhckNvZGVBdCgw
+KT09MD9zOnN9LAplUjpmdW5jdGlvbihhLGIpe3JldHVybiBILmJLKHRoaXMsYixILkxoKHRoaXMpLkMo
+ImxmLkUiKSl9LApFOmZ1bmN0aW9uKGEsYil7dmFyIHMscixxLHA9ImluZGV4IgpILmNiKGIscCx0LlMp
+ClAuazEoYixwKQpmb3Iocz10aGlzLmdtKHRoaXMpLHI9MDtzLkYoKTspe3E9cy5kCmlmKGI9PT1yKXJl
+dHVybiBxOysrcn10aHJvdyBILmIoUC5DZihiLHRoaXMscCxudWxsLHIpKX19ClAuVmoucHJvdG90eXBl
+PXskaWJROjEsJGljWDoxLCRpeHU6MX0KUC5Ydi5wcm90b3R5cGU9eyRpYlE6MSwkaWNYOjEsJGl4dTox
+fQpQLm5ZLnByb3RvdHlwZT17fQpQLldZLnByb3RvdHlwZT17fQpQLlJVLnByb3RvdHlwZT17fQpQLnBS
+LnByb3RvdHlwZT17fQpQLnV3LnByb3RvdHlwZT17CnE6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyPXRoaXMu
+YgppZihyPT1udWxsKXJldHVybiB0aGlzLmMucSgwLGIpCmVsc2UgaWYodHlwZW9mIGIhPSJzdHJpbmci
+KXJldHVybiBudWxsCmVsc2V7cz1yW2JdCnJldHVybiB0eXBlb2Ygcz09InVuZGVmaW5lZCI/dGhpcy5m
+YihiKTpzfX0sCmdBOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmI9PW51bGw/dGhpcy5jLmE6dGhpcy5D
+ZigpLmxlbmd0aH0sCmdsMDpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5nQSh0aGlzKT09PTB9LApndmM6
+ZnVuY3Rpb24oKXtpZih0aGlzLmI9PW51bGwpe3ZhciBzPXRoaXMuYwpyZXR1cm4gbmV3IEguaTUocyxI
+LkxoKHMpLkMoImk1PDE+IikpfXJldHVybiBuZXcgUC5pOCh0aGlzKX0sClk1OmZ1bmN0aW9uKGEsYixj
+KXt2YXIgcyxyLHE9dGhpcwppZihxLmI9PW51bGwpcS5jLlk1KDAsYixjKQplbHNlIGlmKHEueDQoYikp
+e3M9cS5iCnNbYl09YwpyPXEuYQppZihyPT1udWxsP3MhPW51bGw6ciE9PXMpcltiXT1udWxsfWVsc2Ug
+cS5YSygpLlk1KDAsYixjKX0sCng0OmZ1bmN0aW9uKGEpe2lmKHRoaXMuYj09bnVsbClyZXR1cm4gdGhp
+cy5jLng0KGEpCnJldHVybiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwodGhpcy5h
+LGEpfSwKSzpmdW5jdGlvbihhLGIpe3ZhciBzLHIscSxwLG89dGhpcwp0LmNBLmEoYikKaWYoby5iPT1u
+dWxsKXJldHVybiBvLmMuSygwLGIpCnM9by5DZigpCmZvcihyPTA7cjxzLmxlbmd0aDsrK3Ipe3E9c1ty
+XQpwPW8uYltxXQppZih0eXBlb2YgcD09InVuZGVmaW5lZCIpe3A9UC5RZShvLmFbcV0pCm8uYltxXT1w
+fWIuJDIocSxwKQppZihzIT09by5jKXRocm93IEguYihQLmE0KG8pKX19LApDZjpmdW5jdGlvbigpe3Zh
+ciBzPXQuYk0uYSh0aGlzLmMpCmlmKHM9PW51bGwpcz10aGlzLmM9SC5WTShPYmplY3Qua2V5cyh0aGlz
+LmEpLHQucykKcmV0dXJuIHN9LApYSzpmdW5jdGlvbigpe3ZhciBzLHIscSxwLG8sbj10aGlzCmlmKG4u
+Yj09bnVsbClyZXR1cm4gbi5jCnM9UC5GbCh0Lk4sdC56KQpyPW4uQ2YoKQpmb3IocT0wO3A9ci5sZW5n
+dGgscTxwOysrcSl7bz1yW3FdCnMuWTUoMCxvLG4ucSgwLG8pKX1pZihwPT09MClDLk5tLmkociwiIikK
+ZWxzZSBDLk5tLnNBKHIsMCkKbi5hPW4uYj1udWxsCnJldHVybiBuLmM9c30sCmZiOmZ1bmN0aW9uKGEp
+e3ZhciBzCmlmKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwodGhpcy5hLGEpKXJl
+dHVybiBudWxsCnM9UC5RZSh0aGlzLmFbYV0pCnJldHVybiB0aGlzLmJbYV09c319ClAuaTgucHJvdG90
+eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7dmFyIHM9dGhpcy5hCnJldHVybiBzLmdBKHMpfSwKRTpmdW5jdGlv
+bihhLGIpe3ZhciBzPXRoaXMuYQppZihzLmI9PW51bGwpcz1zLmd2YygpLkUoMCxiKQplbHNle3M9cy5D
+ZigpCmlmKGI8MHx8Yj49cy5sZW5ndGgpcmV0dXJuIEguT0gocyxiKQpzPXNbYl19cmV0dXJuIHN9LApn
+bTpmdW5jdGlvbihhKXt2YXIgcz10aGlzLmEKaWYocy5iPT1udWxsKXtzPXMuZ3ZjKCkKcz1zLmdtKHMp
+fWVsc2V7cz1zLkNmKCkKcz1uZXcgSi5tMShzLHMubGVuZ3RoLEgudDYocykuQygibTE8MT4iKSl9cmV0
+dXJuIHN9LAp0ZzpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLmEueDQoYil9fQpQLnhyLnByb3RvdHlw
+ZT17CiQwOmZ1bmN0aW9uKCl7dmFyIHMscgp0cnl7cz1uZXcgVGV4dERlY29kZXIoInV0Zi04Iix7ZmF0
+YWw6dHJ1ZX0pCnJldHVybiBzfWNhdGNoKHIpe0guUnUocil9cmV0dXJuIG51bGx9LAokUzoxMn0KUC5O
+ei5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe3ZhciBzLHIKdHJ5e3M9bmV3IFRleHREZWNvZGVyKCJ1
+dGYtOCIse2ZhdGFsOmZhbHNlfSkKcmV0dXJuIHN9Y2F0Y2gocil7SC5SdShyKX1yZXR1cm4gbnVsbH0s
+CiRTOjEyfQpQLkNWLnByb3RvdHlwZT17CnlyOmZ1bmN0aW9uKGEwLGExLGEyKXt2YXIgcyxyLHEscCxv
+LG4sbSxsLGssaixpLGgsZyxmLGUsZCxjLGIsYT0iSW52YWxpZCBiYXNlNjQgZW5jb2RpbmcgbGVuZ3Ro
+ICIKYTI9UC5qQihhMSxhMixhMC5sZW5ndGgpCnM9JC5WNygpCmZvcihyPWExLHE9cixwPW51bGwsbz0t
+MSxuPS0xLG09MDtyPGEyO3I9bCl7bD1yKzEKaz1DLnhCLlcoYTAscikKaWYoaz09PTM3KXtqPWwrMgpp
+ZihqPD1hMil7aT1ILm9vKEMueEIuVyhhMCxsKSkKaD1ILm9vKEMueEIuVyhhMCxsKzEpKQpnPWkqMTYr
+aC0oaCYyNTYpCmlmKGc9PT0zNylnPS0xCmw9an1lbHNlIGc9LTF9ZWxzZSBnPWsKaWYoMDw9ZyYmZzw9
+MTI3KXtpZihnPDB8fGc+PXMubGVuZ3RoKXJldHVybiBILk9IKHMsZykKZj1zW2ddCmlmKGY+PTApe2c9
+Qy54Qi5PKCJBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6
+MDEyMzQ1Njc4OSsvIixmKQppZihnPT09ayljb250aW51ZQprPWd9ZWxzZXtpZihmPT09LTEpe2lmKG88
+MCl7ZT1wPT1udWxsP251bGw6cC5hLmxlbmd0aAppZihlPT1udWxsKWU9MApvPWUrKHItcSkKbj1yfSsr
+bQppZihrPT09NjEpY29udGludWV9az1nfWlmKGYhPT0tMil7aWYocD09bnVsbCl7cD1uZXcgUC5Sbigi
+IikKZT1wfWVsc2UgZT1wCmUuYSs9Qy54Qi5OaihhMCxxLHIpCmUuYSs9SC5MdyhrKQpxPWwKY29udGlu
+dWV9fXRocm93IEguYihQLnJyKCJJbnZhbGlkIGJhc2U2NCBkYXRhIixhMCxyKSl9aWYocCE9bnVsbCl7
+ZT1wLmErPUMueEIuTmooYTAscSxhMikKZD1lLmxlbmd0aAppZihvPj0wKVAueE0oYTAsbixhMixvLG0s
+ZCkKZWxzZXtjPUMuam4uelkoZC0xLDQpKzEKaWYoYz09PTEpdGhyb3cgSC5iKFAucnIoYSxhMCxhMikp
+CmZvcig7Yzw0Oyl7ZSs9Ij0iCnAuYT1lOysrY319ZT1wLmEKcmV0dXJuIEMueEIuaTcoYTAsYTEsYTIs
+ZS5jaGFyQ29kZUF0KDApPT0wP2U6ZSl9Yj1hMi1hMQppZihvPj0wKVAueE0oYTAsbixhMixvLG0sYikK
+ZWxzZXtjPUMuam4uelkoYiw0KQppZihjPT09MSl0aHJvdyBILmIoUC5ycihhLGEwLGEyKSkKaWYoYz4x
+KWEwPUMueEIuaTcoYTAsYTIsYTIsYz09PTI/Ij09IjoiPSIpfXJldHVybiBhMH19ClAuVTgucHJvdG90
+eXBlPXt9ClAuVWsucHJvdG90eXBlPXt9ClAud0kucHJvdG90eXBlPXt9ClAuWmkucHJvdG90eXBlPXt9
+ClAuVWQucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXt2YXIgcz1QLnAodGhpcy5hKQpyZXR1cm4odGhp
+cy5iIT1udWxsPyJDb252ZXJ0aW5nIG9iamVjdCB0byBhbiBlbmNvZGFibGUgb2JqZWN0IGZhaWxlZDoi
+OiJDb252ZXJ0aW5nIG9iamVjdCBkaWQgbm90IHJldHVybiBhbiBlbmNvZGFibGUgb2JqZWN0OiIpKyIg
+IitzfX0KUC5LOC5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiJDeWNsaWMgZXJyb3IgaW4g
+SlNPTiBzdHJpbmdpZnkifX0KUC5ieS5wcm90b3R5cGU9ewpwVzpmdW5jdGlvbihhLGIsYyl7dmFyIHMK
+dC5mVi5hKGMpCnM9UC5CUyhiLHRoaXMuZ0hlKCkuYSkKcmV0dXJuIHN9LApPQjpmdW5jdGlvbihhLGIp
+e3ZhciBzCnQuZEEuYShiKQpzPVAudVgoYSx0aGlzLmdaRSgpLmIsbnVsbCkKcmV0dXJuIHN9LApnWkU6
+ZnVuY3Rpb24oKXtyZXR1cm4gQy5uWH0sCmdIZTpmdW5jdGlvbigpe3JldHVybiBDLkEzfX0KUC5vai5w
+cm90b3R5cGU9e30KUC5NeC5wcm90b3R5cGU9e30KUC5TaC5wcm90b3R5cGU9ewpSVDpmdW5jdGlvbihh
+KXt2YXIgcyxyLHEscCxvLG4sbSxsPWEubGVuZ3RoCmZvcihzPUouclkoYSkscj10aGlzLmMscT0wLHA9
+MDtwPGw7KytwKXtvPXMuVyhhLHApCmlmKG8+OTIpe2lmKG8+PTU1Mjk2KXtuPW8mNjQ1MTIKaWYobj09
+PTU1Mjk2KXttPXArMQptPSEobTxsJiYoQy54Qi5XKGEsbSkmNjQ1MTIpPT09NTYzMjApfWVsc2UgbT0h
+MQppZighbSlpZihuPT09NTYzMjApe249cC0xCm49IShuPj0wJiYoQy54Qi5PKGEsbikmNjQ1MTIpPT09
+NTUyOTYpfWVsc2Ugbj0hMQplbHNlIG49ITAKaWYobil7aWYocD5xKXIuYSs9Qy54Qi5OaihhLHEscCkK
+cT1wKzEKci5hKz1ILkx3KDkyKQpyLmErPUguTHcoMTE3KQpyLmErPUguTHcoMTAwKQpuPW8+Pj44JjE1
+CnIuYSs9SC5MdyhuPDEwPzQ4K246ODcrbikKbj1vPj4+NCYxNQpyLmErPUguTHcobjwxMD80OCtuOjg3
+K24pCm49byYxNQpyLmErPUguTHcobjwxMD80OCtuOjg3K24pfX1jb250aW51ZX1pZihvPDMyKXtpZihw
+PnEpci5hKz1DLnhCLk5qKGEscSxwKQpxPXArMQpyLmErPUguTHcoOTIpCnN3aXRjaChvKXtjYXNlIDg6
+ci5hKz1ILkx3KDk4KQpicmVhawpjYXNlIDk6ci5hKz1ILkx3KDExNikKYnJlYWsKY2FzZSAxMDpyLmEr
+PUguTHcoMTEwKQpicmVhawpjYXNlIDEyOnIuYSs9SC5MdygxMDIpCmJyZWFrCmNhc2UgMTM6ci5hKz1I
+Lkx3KDExNCkKYnJlYWsKZGVmYXVsdDpyLmErPUguTHcoMTE3KQpyLmErPUguTHcoNDgpCnIuYSs9SC5M
+dyg0OCkKbj1vPj4+NCYxNQpyLmErPUguTHcobjwxMD80OCtuOjg3K24pCm49byYxNQpyLmErPUguTHco
+bjwxMD80OCtuOjg3K24pCmJyZWFrfX1lbHNlIGlmKG89PT0zNHx8bz09PTkyKXtpZihwPnEpci5hKz1D
+LnhCLk5qKGEscSxwKQpxPXArMQpyLmErPUguTHcoOTIpCnIuYSs9SC5MdyhvKX19aWYocT09PTApci5h
+Kz1ILkVqKGEpCmVsc2UgaWYocTxsKXIuYSs9cy5OaihhLHEsbCl9LApKbjpmdW5jdGlvbihhKXt2YXIg
+cyxyLHEscApmb3Iocz10aGlzLmEscj1zLmxlbmd0aCxxPTA7cTxyOysrcSl7cD1zW3FdCmlmKGE9PW51
+bGw/cD09bnVsbDphPT09cCl0aHJvdyBILmIobmV3IFAuSzgoYSxudWxsKSl9Qy5ObS5pKHMsYSl9LApp
+VTpmdW5jdGlvbihhKXt2YXIgcyxyLHEscCxvPXRoaXMKaWYoby50TShhKSlyZXR1cm4Kby5KbihhKQp0
+cnl7cz1vLmIuJDEoYSkKaWYoIW8udE0ocykpe3E9UC5HeShhLG51bGwsby5nVksoKSkKdGhyb3cgSC5i
+KHEpfXE9by5hCmlmKDA+PXEubGVuZ3RoKXJldHVybiBILk9IKHEsLTEpCnEucG9wKCl9Y2F0Y2gocCl7
+cj1ILlJ1KHApCnE9UC5HeShhLHIsby5nVksoKSkKdGhyb3cgSC5iKHEpfX0sCnRNOmZ1bmN0aW9uKGEp
+e3ZhciBzLHIscT10aGlzCmlmKHR5cGVvZiBhPT0ibnVtYmVyIil7aWYoIWlzRmluaXRlKGEpKXJldHVy
+biExCnEuYy5hKz1DLkNELncoYSkKcmV0dXJuITB9ZWxzZSBpZihhPT09ITApe3EuYy5hKz0idHJ1ZSIK
+cmV0dXJuITB9ZWxzZSBpZihhPT09ITEpe3EuYy5hKz0iZmFsc2UiCnJldHVybiEwfWVsc2UgaWYoYT09
+bnVsbCl7cS5jLmErPSJudWxsIgpyZXR1cm4hMH1lbHNlIGlmKHR5cGVvZiBhPT0ic3RyaW5nIil7cz1x
+LmMKcy5hKz0nIicKcS5SVChhKQpzLmErPSciJwpyZXR1cm4hMH1lbHNlIGlmKHQuai5iKGEpKXtxLkpu
+KGEpCnEubEsoYSkKcz1xLmEKaWYoMD49cy5sZW5ndGgpcmV0dXJuIEguT0gocywtMSkKcy5wb3AoKQpy
+ZXR1cm4hMH1lbHNlIGlmKHQuZi5iKGEpKXtxLkpuKGEpCnI9cS5qdyhhKQpzPXEuYQppZigwPj1zLmxl
+bmd0aClyZXR1cm4gSC5PSChzLC0xKQpzLnBvcCgpCnJldHVybiByfWVsc2UgcmV0dXJuITF9LApsSzpm
+dW5jdGlvbihhKXt2YXIgcyxyLHE9dGhpcy5jCnEuYSs9IlsiCnM9Si5VNihhKQppZihzLmdvcihhKSl7
+dGhpcy5pVShzLnEoYSwwKSkKZm9yKHI9MTtyPHMuZ0EoYSk7KytyKXtxLmErPSIsIgp0aGlzLmlVKHMu
+cShhLHIpKX19cS5hKz0iXSJ9LApqdzpmdW5jdGlvbihhKXt2YXIgcyxyLHEscCxvLG4sbT10aGlzLGw9
+e30KaWYoYS5nbDAoYSkpe20uYy5hKz0ie30iCnJldHVybiEwfXM9YS5nQShhKSoyCnI9UC5POChzLG51
+bGwsITEsdC5XKQpxPWwuYT0wCmwuYj0hMAphLksoMCxuZXcgUC50aShsLHIpKQppZighbC5iKXJldHVy
+biExCnA9bS5jCnAuYSs9InsiCmZvcihvPSciJztxPHM7cSs9MixvPScsIicpe3AuYSs9bwptLlJUKEgu
+aChyW3FdKSkKcC5hKz0nIjonCm49cSsxCmlmKG4+PXMpcmV0dXJuIEguT0gocixuKQptLmlVKHJbbl0p
+fXAuYSs9In0iCnJldHVybiEwfX0KUC50aS5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3ZhciBz
+LHIKaWYodHlwZW9mIGEhPSJzdHJpbmciKXRoaXMuYS5iPSExCnM9dGhpcy5iCnI9dGhpcy5hCkMuTm0u
+WTUocyxyLmErKyxhKQpDLk5tLlk1KHMsci5hKyssYil9LAokUzoxMX0KUC50dS5wcm90b3R5cGU9ewpn
+Vks6ZnVuY3Rpb24oKXt2YXIgcz10aGlzLmMuYQpyZXR1cm4gcy5jaGFyQ29kZUF0KDApPT0wP3M6c319
+ClAudTUucHJvdG90eXBlPXsKZ1pFOmZ1bmN0aW9uKCl7cmV0dXJuIEMuUWt9fQpQLkUzLnByb3RvdHlw
+ZT17CldKOmZ1bmN0aW9uKGEpe3ZhciBzLHIscSxwPVAuakIoMCxudWxsLGEubGVuZ3RoKSxvPXAtMApp
+ZihvPT09MClyZXR1cm4gbmV3IFVpbnQ4QXJyYXkoMCkKcz1vKjMKcj1uZXcgVWludDhBcnJheShzKQpx
+PW5ldyBQLlJ3KHIpCmlmKHEuR3goYSwwLHApIT09cCl7Si5hNihhLHAtMSkKcS5STygpfXJldHVybiBu
+ZXcgVWludDhBcnJheShyLnN1YmFycmF5KDAsSC5yTSgwLHEuYixzKSkpfX0KUC5Sdy5wcm90b3R5cGU9
+ewpSTzpmdW5jdGlvbigpe3ZhciBzPXRoaXMscj1zLmMscT1zLmIscD1zLmI9cSsxLG89ci5sZW5ndGgK
+aWYocT49bylyZXR1cm4gSC5PSChyLHEpCnJbcV09MjM5CnE9cy5iPXArMQppZihwPj1vKXJldHVybiBI
+Lk9IKHIscCkKcltwXT0xOTEKcy5iPXErMQppZihxPj1vKXJldHVybiBILk9IKHIscSkKcltxXT0xODl9
+LApPNjpmdW5jdGlvbihhLGIpe3ZhciBzLHIscSxwLG8sbj10aGlzCmlmKChiJjY0NTEyKT09PTU2MzIw
+KXtzPTY1NTM2KygoYSYxMDIzKTw8MTApfGImMTAyMwpyPW4uYwpxPW4uYgpwPW4uYj1xKzEKbz1yLmxl
+bmd0aAppZihxPj1vKXJldHVybiBILk9IKHIscSkKcltxXT1zPj4+MTh8MjQwCnE9bi5iPXArMQppZihw
+Pj1vKXJldHVybiBILk9IKHIscCkKcltwXT1zPj4+MTImNjN8MTI4CnA9bi5iPXErMQppZihxPj1vKXJl
+dHVybiBILk9IKHIscSkKcltxXT1zPj4+NiY2M3wxMjgKbi5iPXArMQppZihwPj1vKXJldHVybiBILk9I
+KHIscCkKcltwXT1zJjYzfDEyOApyZXR1cm4hMH1lbHNle24uUk8oKQpyZXR1cm4hMX19LApHeDpmdW5j
+dGlvbihhLGIsYyl7dmFyIHMscixxLHAsbyxuLG0sbD10aGlzCmlmKGIhPT1jJiYoQy54Qi5PKGEsYy0x
+KSY2NDUxMik9PT01NTI5NiktLWMKZm9yKHM9bC5jLHI9cy5sZW5ndGgscT1iO3E8YzsrK3Epe3A9Qy54
+Qi5XKGEscSkKaWYocDw9MTI3KXtvPWwuYgppZihvPj1yKWJyZWFrCmwuYj1vKzEKc1tvXT1wfWVsc2V7
+bz1wJjY0NTEyCmlmKG89PT01NTI5Nil7aWYobC5iKzQ+cilicmVhawpuPXErMQppZihsLk82KHAsQy54
+Qi5XKGEsbikpKXE9bn1lbHNlIGlmKG89PT01NjMyMCl7aWYobC5iKzM+cilicmVhawpsLlJPKCl9ZWxz
+ZSBpZihwPD0yMDQ3KXtvPWwuYgptPW8rMQppZihtPj1yKWJyZWFrCmwuYj1tCmlmKG8+PXIpcmV0dXJu
+IEguT0gocyxvKQpzW29dPXA+Pj42fDE5MgpsLmI9bSsxCnNbbV09cCY2M3wxMjh9ZWxzZXtvPWwuYgpp
+ZihvKzI+PXIpYnJlYWsKbT1sLmI9bysxCmlmKG8+PXIpcmV0dXJuIEguT0gocyxvKQpzW29dPXA+Pj4x
+MnwyMjQKbz1sLmI9bSsxCmlmKG0+PXIpcmV0dXJuIEguT0gocyxtKQpzW21dPXA+Pj42JjYzfDEyOAps
+LmI9bysxCmlmKG8+PXIpcmV0dXJuIEguT0gocyxvKQpzW29dPXAmNjN8MTI4fX19cmV0dXJuIHF9fQpQ
+LkdZLnByb3RvdHlwZT17CldKOmZ1bmN0aW9uKGEpe3ZhciBzLHIKdC5MLmEoYSkKcz10aGlzLmEKcj1Q
+Lmt5KHMsYSwwLG51bGwpCmlmKHIhPW51bGwpcmV0dXJuIHIKcmV0dXJuIG5ldyBQLmJ6KHMpLk5lKGEs
+MCxudWxsLCEwKX19ClAuYnoucHJvdG90eXBlPXsKTmU6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHMscixx
+LHAsbyxuPXRoaXMKdC5MLmEoYSkKcz1QLmpCKGIsYyxKLkhtKGEpKQppZihiPT09cylyZXR1cm4iIgpy
+PVAuankoYSxiLHMpCnE9bi5oTyhyLDAscy1iLCEwKQpwPW4uYgppZigocCYxKSE9PTApe289UC5qNChw
+KQpuLmI9MAp0aHJvdyBILmIoUC5ycihvLGEsYituLmMpKX1yZXR1cm4gcX0sCmhPOmZ1bmN0aW9uKGEs
+YixjLGQpe3ZhciBzLHIscT10aGlzCmlmKGMtYj4xMDAwKXtzPUMuam4uQlUoYitjLDIpCnI9cS5oTyhh
+LGIscywhMSkKaWYoKHEuYiYxKSE9PTApcmV0dXJuIHIKcmV0dXJuIHIrcS5oTyhhLHMsYyxkKX1yZXR1
+cm4gcS5FaChhLGIsYyxkKX0sCkVoOmZ1bmN0aW9uKGEsYixjLGQpe3ZhciBzLHIscSxwLG8sbixtLGws
+az10aGlzLGo9NjU1MzMsaT1rLmIsaD1rLmMsZz1uZXcgUC5SbigiIiksZj1iKzEsZT1hLmxlbmd0aApp
+ZihiPDB8fGI+PWUpcmV0dXJuIEguT0goYSxiKQpzPWFbYl0KJGxhYmVsMCQwOmZvcihyPWsuYTshMDsp
+e2Zvcig7ITA7Zj1vKXtxPUMueEIuVygiQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFB
 QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFB
-QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBRkZGRkZGRkZGRkZGRkZGRkdHR0dHR0dH
-R0dHR0dHR0dISEhISEhISEhISEhISEhISEhISEhISEhISEhJSEhISkVFQkJCQkJCQkJCQkJCQkJCQkJC
-QkJCQkJCQkJCQkJCS0NDQ0NDQ0NDQ0NDQ0RDTE9OTk5NRUVFRUVFRUVFRUUiLHMpJjMxCmg9aTw9MzI/
-cyY2MTY5ND4+PnE6KHMmNjN8aDw8Nik+Pj4wCmk9Qy54Qi5XKCIgXHgwMDA6WEVDQ0NDQ046bERiIFx4
-MDAwOlhFQ0NDQ0NOdmxEYiBceDAwMDpYRUNDQ0NDTjpsRGIgQUFBQUFceDAwXHgwMFx4MDBceDAwXHgw
-MEFBQUFBMDAwMDBBQUFBQTo6Ojo6QUFBQUFHRzAwMEFBQUFBMDBLS0tBQUFBQUc6Ojo6QUFBQUE6SUlJ
-SUFBQUFBMDAwXHg4MDBBQUFBQVx4MDBceDAwXHgwMFx4MDAgQUFBQUEiLGkrcSkKaWYoaT09PTApe2cu
-YSs9SC5MdyhoKQppZihmPT09YylicmVhayAkbGFiZWwwJDAKYnJlYWt9ZWxzZSBpZigoaSYxKSE9PTAp
-e2lmKHIpc3dpdGNoKGkpe2Nhc2UgNjk6Y2FzZSA2NzpnLmErPUguTHcoaikKYnJlYWsKY2FzZSA2NTpn
-LmErPUguTHcoaik7LS1mCmJyZWFrCmRlZmF1bHQ6cD1nLmErPUguTHcoaikKZy5hPXArSC5MdyhqKQpi
-cmVha31lbHNle2suYj1pCmsuYz1mLTEKcmV0dXJuIiJ9aT0wfWlmKGY9PT1jKWJyZWFrICRsYWJlbDAk
-MApvPWYrMQppZihmPDB8fGY+PWUpcmV0dXJuIEguT0goYSxmKQpzPWFbZl19bz1mKzEKaWYoZjwwfHxm
-Pj1lKXJldHVybiBILk9IKGEsZikKcz1hW2ZdCmlmKHM8MTI4KXt3aGlsZSghMCl7aWYoIShvPGMpKXtu
-PWMKYnJlYWt9bT1vKzEKaWYobzwwfHxvPj1lKXJldHVybiBILk9IKGEsbykKcz1hW29dCmlmKHM+PTEy
-OCl7bj1tLTEKbz1tCmJyZWFrfW89bX1pZihuLWY8MjApZm9yKGw9ZjtsPG47KytsKXtpZihsPj1lKXJl
-dHVybiBILk9IKGEsbCkKZy5hKz1ILkx3KGFbbF0pfWVsc2UgZy5hKz1QLkhNKGEsZixuKQppZihuPT09
-YylicmVhayAkbGFiZWwwJDAKZj1vfWVsc2UgZj1vfWlmKGQmJmk+MzIpaWYocilnLmErPUguTHcoaikK
-ZWxzZXtrLmI9NzcKay5jPWMKcmV0dXJuIiJ9ay5iPWkKay5jPWgKZT1nLmEKcmV0dXJuIGUuY2hhckNv
-ZGVBdCgwKT09MD9lOmV9fQpQLldGLnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7dmFyIHMscixx
-CnQuZm8uYShhKQpzPXRoaXMuYgpyPXRoaXMuYQpzLmErPXIuYQpxPXMuYSs9SC5FaihhLmEpCnMuYT1x
-KyI6ICIKcy5hKz1QLnAoYikKci5hPSIsICJ9LAokUzo0MH0KUC5pUC5wcm90b3R5cGU9ewpETjpmdW5j
-dGlvbihhLGIpe2lmKGI9PW51bGwpcmV0dXJuITEKcmV0dXJuIGIgaW5zdGFuY2VvZiBQLmlQJiZ0aGlz
-LmE9PT1iLmEmJiEwfSwKZ2lPOmZ1bmN0aW9uKGEpe3ZhciBzPXRoaXMuYQpyZXR1cm4oc15DLmpuLndH
-KHMsMzApKSYxMDczNzQxODIzfSwKdzpmdW5jdGlvbihhKXt2YXIgcz10aGlzLHI9UC5HcShILnRKKHMp
-KSxxPVAuaDAoSC5OUyhzKSkscD1QLmgwKEguakEocykpLG89UC5oMChILklYKHMpKSxuPVAuaDAoSC5j
-aChzKSksbT1QLmgwKEguSmQocykpLGw9UC5WeChILm8xKHMpKSxrPXIrIi0iK3ErIi0iK3ArIiAiK28r
-IjoiK24rIjoiK20rIi4iK2wKcmV0dXJuIGt9fQpQLlhTLnByb3RvdHlwZT17CmdJSTpmdW5jdGlvbigp
-e3JldHVybiBILnRzKHRoaXMuJHRocm93bkpzRXJyb3IpfX0KUC5DNi5wcm90b3R5cGU9ewp3OmZ1bmN0
-aW9uKGEpe3ZhciBzPXRoaXMuYQppZihzIT1udWxsKXJldHVybiJBc3NlcnRpb24gZmFpbGVkOiAiK1Au
-cChzKQpyZXR1cm4iQXNzZXJ0aW9uIGZhaWxlZCJ9fQpQLkV6LnByb3RvdHlwZT17fQpQLkYucHJvdG90
-eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4iVGhyb3cgb2YgbnVsbC4ifX0KUC51LnByb3RvdHlwZT17
-CmdaOmZ1bmN0aW9uKCl7cmV0dXJuIkludmFsaWQgYXJndW1lbnQiKyghdGhpcy5hPyIocykiOiIiKX0s
-Cmd1OmZ1bmN0aW9uKCl7cmV0dXJuIiJ9LAp3OmZ1bmN0aW9uKGEpe3ZhciBzLHIscT10aGlzLHA9cS5j
-LG89cD09bnVsbD8iIjoiICgiK3ArIikiLG49cS5kLG09bj09bnVsbD8iIjoiOiAiK0guRWoobiksbD1x
-LmdaKCkrbyttCmlmKCFxLmEpcmV0dXJuIGwKcz1xLmd1KCkKcj1QLnAocS5iKQpyZXR1cm4gbCtzKyI6
-ICIrcn19ClAuYkoucHJvdG90eXBlPXsKZ1o6ZnVuY3Rpb24oKXtyZXR1cm4iUmFuZ2VFcnJvciJ9LApn
-dTpmdW5jdGlvbigpe3ZhciBzLHI9dGhpcy5lLHE9dGhpcy5mCmlmKHI9PW51bGwpcz1xIT1udWxsPyI6
-IE5vdCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gIitILkVqKHEpOiIiCmVsc2UgaWYocT09bnVsbClzPSI6
-IE5vdCBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gIitILkVqKHIpCmVsc2UgaWYocT5yKXM9IjogTm90
-IGluIGluY2x1c2l2ZSByYW5nZSAiK0guRWoocikrIi4uIitILkVqKHEpCmVsc2Ugcz1xPHI/IjogVmFs
-aWQgdmFsdWUgcmFuZ2UgaXMgZW1wdHkiOiI6IE9ubHkgdmFsaWQgdmFsdWUgaXMgIitILkVqKHIpCnJl
-dHVybiBzfX0KUC5lWS5wcm90b3R5cGU9ewpnWjpmdW5jdGlvbigpe3JldHVybiJSYW5nZUVycm9yIn0s
-Cmd1OmZ1bmN0aW9uKCl7dmFyIHMscj1ILnVQKHRoaXMuYikKaWYodHlwZW9mIHIhPT0ibnVtYmVyIily
-ZXR1cm4gci5KKCkKaWYocjwwKXJldHVybiI6IGluZGV4IG11c3Qgbm90IGJlIG5lZ2F0aXZlIgpzPXRo
-aXMuZgppZihzPT09MClyZXR1cm4iOiBubyBpbmRpY2VzIGFyZSB2YWxpZCIKcmV0dXJuIjogaW5kZXgg
-c2hvdWxkIGJlIGxlc3MgdGhhbiAiK0guRWoocyl9LApnQTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5m
-fX0KUC5tcC5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3ZhciBzLHIscSxwLG8sbixtLGwsaz10aGlz
-LGo9e30saT1uZXcgUC5SbigiIikKai5hPSIiCnM9ay5jCmZvcihyPXMubGVuZ3RoLHE9MCxwPSIiLG89
-IiI7cTxyOysrcSxvPSIsICIpe249c1txXQppLmE9cCtvCnA9aS5hKz1QLnAobikKai5hPSIsICJ9ay5k
-LksoMCxuZXcgUC5XRihqLGkpKQptPVAucChrLmEpCmw9aS53KDApCnI9Ik5vU3VjaE1ldGhvZEVycm9y
-OiBtZXRob2Qgbm90IGZvdW5kOiAnIitILkVqKGsuYi5hKSsiJ1xuUmVjZWl2ZXI6ICIrbSsiXG5Bcmd1
-bWVudHM6IFsiK2wrIl0iCnJldHVybiByfX0KUC51Yi5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3Jl
-dHVybiJVbnN1cHBvcnRlZCBvcGVyYXRpb246ICIrdGhpcy5hfX0KUC5kcy5wcm90b3R5cGU9ewp3OmZ1
-bmN0aW9uKGEpe3ZhciBzPXRoaXMuYQpyZXR1cm4gcyE9bnVsbD8iVW5pbXBsZW1lbnRlZEVycm9yOiAi
-K3M6IlVuaW1wbGVtZW50ZWRFcnJvciJ9fQpQLmxqLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7cmV0
-dXJuIkJhZCBzdGF0ZTogIit0aGlzLmF9fQpQLlVWLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7dmFy
-IHM9dGhpcy5hCmlmKHM9PW51bGwpcmV0dXJuIkNvbmN1cnJlbnQgbW9kaWZpY2F0aW9uIGR1cmluZyBp
-dGVyYXRpb24uIgpyZXR1cm4iQ29uY3VycmVudCBtb2RpZmljYXRpb24gZHVyaW5nIGl0ZXJhdGlvbjog
-IitQLnAocykrIi4ifX0KUC5rNS5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiJPdXQgb2Yg
-TWVtb3J5In0sCmdJSTpmdW5jdGlvbigpe3JldHVybiBudWxsfSwKJGlYUzoxfQpQLktZLnByb3RvdHlw
-ZT17Cnc6ZnVuY3Rpb24oYSl7cmV0dXJuIlN0YWNrIE92ZXJmbG93In0sCmdJSTpmdW5jdGlvbigpe3Jl
-dHVybiBudWxsfSwKJGlYUzoxfQpQLmMucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXt2YXIgcz10aGlz
-LmEKcmV0dXJuIHM9PW51bGw/IlJlYWRpbmcgc3RhdGljIHZhcmlhYmxlIGR1cmluZyBpdHMgaW5pdGlh
-bGl6YXRpb24iOiJSZWFkaW5nIHN0YXRpYyB2YXJpYWJsZSAnIitzKyInIGR1cmluZyBpdHMgaW5pdGlh
-bGl6YXRpb24ifX0KUC5DRC5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiJFeGNlcHRpb246
-ICIrdGhpcy5hfSwKJGlSejoxfQpQLmFFLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7dmFyIHMscixx
-LHAsbyxuLG0sbCxrLGosaSxoLGc9dGhpcy5hLGY9ZyE9bnVsbCYmIiIhPT1nPyJGb3JtYXRFeGNlcHRp
-b246ICIrSC5FaihnKToiRm9ybWF0RXhjZXB0aW9uIixlPXRoaXMuYyxkPXRoaXMuYgppZih0eXBlb2Yg
-ZD09InN0cmluZyIpe2lmKGUhPW51bGwpcz1lPDB8fGU+ZC5sZW5ndGgKZWxzZSBzPSExCmlmKHMpZT1u
-dWxsCmlmKGU9PW51bGwpe2lmKGQubGVuZ3RoPjc4KWQ9Qy54Qi5OaihkLDAsNzUpKyIuLi4iCnJldHVy
-biBmKyJcbiIrZH1mb3Iocj0xLHE9MCxwPSExLG89MDtvPGU7KytvKXtuPUMueEIuVyhkLG8pCmlmKG49
-PT0xMCl7aWYocSE9PW98fCFwKSsrcgpxPW8rMQpwPSExfWVsc2UgaWYobj09PTEzKXsrK3IKcT1vKzEK
-cD0hMH19Zj1yPjE/ZisoIiAoYXQgbGluZSAiK3IrIiwgY2hhcmFjdGVyICIrKGUtcSsxKSsiKVxuIik6
-ZisoIiAoYXQgY2hhcmFjdGVyICIrKGUrMSkrIilcbiIpCm09ZC5sZW5ndGgKZm9yKG89ZTtvPG07Kytv
-KXtuPUMueEIuTyhkLG8pCmlmKG49PT0xMHx8bj09PTEzKXttPW8KYnJlYWt9fWlmKG0tcT43OClpZihl
-LXE8NzUpe2w9cSs3NQprPXEKaj0iIgppPSIuLi4ifWVsc2V7aWYobS1lPDc1KXtrPW0tNzUKbD1tCmk9
-IiJ9ZWxzZXtrPWUtMzYKbD1lKzM2Cmk9Ii4uLiJ9aj0iLi4uIn1lbHNle2w9bQprPXEKaj0iIgppPSIi
-fWg9Qy54Qi5OaihkLGssbCkKcmV0dXJuIGYraitoK2krIlxuIitDLnhCLlQoIiAiLGUtaytqLmxlbmd0
-aCkrIl5cbiJ9ZWxzZSByZXR1cm4gZSE9bnVsbD9mKygiIChhdCBvZmZzZXQgIitILkVqKGUpKyIpIik6
-Zn0sCiRpUno6MX0KUC5jWC5wcm90b3R5cGU9ewpkcjpmdW5jdGlvbihhLGIpe3JldHVybiBILkdKKHRo
-aXMsSC5MaCh0aGlzKS5DKCJjWC5FIiksYil9LApFMjpmdW5jdGlvbihhLGIsYyl7dmFyIHM9SC5MaCh0
-aGlzKQpyZXR1cm4gSC5LMSh0aGlzLHMuS3EoYykuQygiMShjWC5FKSIpLmEoYikscy5DKCJjWC5FIiks
-Yyl9LApldjpmdW5jdGlvbihhLGIpe3ZhciBzPUguTGgodGhpcykKcmV0dXJuIG5ldyBILlU1KHRoaXMs
-cy5DKCJhMihjWC5FKSIpLmEoYikscy5DKCJVNTxjWC5FPiIpKX0sCnR0OmZ1bmN0aW9uKGEsYil7cmV0
-dXJuIFAuWTEodGhpcyxiLEguTGgodGhpcykuQygiY1guRSIpKX0sCmJyOmZ1bmN0aW9uKGEpe3JldHVy
-biB0aGlzLnR0KGEsITApfSwKZ0E6ZnVuY3Rpb24oYSl7dmFyIHMscj10aGlzLmdtKHRoaXMpCmZvcihz
-PTA7ci5GKCk7KSsrcwpyZXR1cm4gc30sCmdsMDpmdW5jdGlvbihhKXtyZXR1cm4hdGhpcy5nbSh0aGlz
-KS5GKCl9LApnb3I6ZnVuY3Rpb24oYSl7cmV0dXJuIXRoaXMuZ2wwKHRoaXMpfSwKZVI6ZnVuY3Rpb24o
-YSxiKXtyZXR1cm4gSC5iSyh0aGlzLGIsSC5MaCh0aGlzKS5DKCJjWC5FIikpfSwKZ3I4OmZ1bmN0aW9u
-KGEpe3ZhciBzLHI9dGhpcy5nbSh0aGlzKQppZighci5GKCkpdGhyb3cgSC5iKEguV3AoKSkKcz1yLmds
-KCkKaWYoci5GKCkpdGhyb3cgSC5iKEguQW0oKSkKcmV0dXJuIHN9LApFOmZ1bmN0aW9uKGEsYil7dmFy
-IHMscixxClAuazEoYiwiaW5kZXgiKQpmb3Iocz10aGlzLmdtKHRoaXMpLHI9MDtzLkYoKTspe3E9cy5n
-bCgpCmlmKGI9PT1yKXJldHVybiBxOysrcn10aHJvdyBILmIoUC5DZihiLHRoaXMsImluZGV4IixudWxs
-LHIpKX0sCnc6ZnVuY3Rpb24oYSl7cmV0dXJuIFAuRVAodGhpcywiKCIsIikiKX19ClAuQW4ucHJvdG90
-eXBlPXt9ClAuTjMucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4iTWFwRW50cnkoIitILkVq
-KEouaih0aGlzLmEpKSsiOiAiK0guRWooSi5qKHRoaXMuYikpKyIpIn19ClAuYzgucHJvdG90eXBlPXsK
-Z2lPOmZ1bmN0aW9uKGEpe3JldHVybiBQLk1oLnByb3RvdHlwZS5naU8uY2FsbChDLmpOLHRoaXMpfSwK
-dzpmdW5jdGlvbihhKXtyZXR1cm4ibnVsbCJ9fQpQLk1oLnByb3RvdHlwZT17Y29uc3RydWN0b3I6UC5N
-aCwkaU1oOjEsCkROOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXM9PT1ifSwKZ2lPOmZ1bmN0aW9uKGEp
-e3JldHVybiBILmVRKHRoaXMpfSwKdzpmdW5jdGlvbihhKXtyZXR1cm4iSW5zdGFuY2Ugb2YgJyIrSC5F
-aihILk0odGhpcykpKyInIn0sCmU3OmZ1bmN0aW9uKGEsYil7dC5vLmEoYikKdGhyb3cgSC5iKFAubHIo
-dGhpcyxiLmdXYSgpLGIuZ25kKCksYi5nVm0oKSkpfSwKdG9TdHJpbmc6ZnVuY3Rpb24oKXtyZXR1cm4g
-dGhpcy53KHRoaXMpfX0KUC5aZC5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiIifSwKJGlH
-ejoxfQpQLlJuLnByb3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmEubGVuZ3RofSwK
-dzpmdW5jdGlvbihhKXt2YXIgcz10aGlzLmEKcmV0dXJuIHMuY2hhckNvZGVBdCgwKT09MD9zOnN9LAok
-aUJMOjF9ClAubjEucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEscAp0LkouYShh
-KQpILmgoYikKcz1KLnJZKGIpLk9ZKGIsIj0iKQppZihzPT09LTEpe2lmKGIhPT0iIilhLlk1KDAsUC5r
-dShiLDAsYi5sZW5ndGgsdGhpcy5hLCEwKSwiIil9ZWxzZSBpZihzIT09MCl7cj1DLnhCLk5qKGIsMCxz
-KQpxPUMueEIueW4oYixzKzEpCnA9dGhpcy5hCmEuWTUoMCxQLmt1KHIsMCxyLmxlbmd0aCxwLCEwKSxQ
-Lmt1KHEsMCxxLmxlbmd0aCxwLCEwKSl9cmV0dXJuIGF9LAokUzo0MX0KUC5jUy5wcm90b3R5cGU9ewok
-MjpmdW5jdGlvbihhLGIpe3Rocm93IEguYihQLnJyKCJJbGxlZ2FsIElQdjQgYWRkcmVzcywgIithLHRo
-aXMuYSxiKSl9LAokUzoyMX0KUC5WQy5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3Rocm93IEgu
-YihQLnJyKCJJbGxlZ2FsIElQdjYgYWRkcmVzcywgIithLHRoaXMuYSxiKSl9LAokMTpmdW5jdGlvbihh
-KXtyZXR1cm4gdGhpcy4kMihhLG51bGwpfSwKJFM6NDZ9ClAuSlQucHJvdG90eXBlPXsKJDI6ZnVuY3Rp
-b24oYSxiKXt2YXIgcwppZihiLWE+NCl0aGlzLmEuJDIoImFuIElQdjYgcGFydCBjYW4gb25seSBjb250
-YWluIGEgbWF4aW11bSBvZiA0IGhleCBkaWdpdHMiLGEpCnM9UC5RQShDLnhCLk5qKHRoaXMuYixhLGIp
-LDE2KQppZihzPDB8fHM+NjU1MzUpdGhpcy5hLiQyKCJlYWNoIHBhcnQgbXVzdCBiZSBpbiB0aGUgcmFu
-Z2Ugb2YgYDB4MC4uMHhGRkZGYCIsYSkKcmV0dXJuIHN9LAokUzo1MX0KUC5Ebi5wcm90b3R5cGU9ewpn
-bkQ6ZnVuY3Rpb24oKXt2YXIgcyxyLHEscD10aGlzLG89cC54CmlmKG89PT0kKXtvPXAuYQpzPW8ubGVu
-Z3RoIT09MD9vKyI6IjoiIgpyPXAuYwpxPXI9PW51bGwKaWYoIXF8fG89PT0iZmlsZSIpe289cysiLy8i
-CnM9cC5iCmlmKHMubGVuZ3RoIT09MClvPW8rcysiQCIKaWYoIXEpbys9cgpzPXAuZAppZihzIT1udWxs
-KW89bysiOiIrSC5FaihzKX1lbHNlIG89cwpvKz1wLmUKcz1wLmYKaWYocyE9bnVsbClvPW8rIj8iK3MK
-cz1wLnIKaWYocyE9bnVsbClvPW8rIiMiK3MKbz1vLmNoYXJDb2RlQXQoMCk9PTA/bzpvCmlmKHAueD09
-PSQpcC54PW8KZWxzZSBvPUgudihILkdRKCJfdGV4dCIpKX1yZXR1cm4gb30sCmdGajpmdW5jdGlvbigp
-e3ZhciBzLHI9dGhpcyxxPXIueQppZihxPT09JCl7cz1yLmUKaWYocy5sZW5ndGghPT0wJiZDLnhCLlco
-cywwKT09PTQ3KXM9Qy54Qi55bihzLDEpCnE9cy5sZW5ndGg9PT0wP0MueEQ6UC5BRihuZXcgSC5sSihI
-LlZNKHMuc3BsaXQoIi8iKSx0LnMpLHQuZE8uYShQLlBIKCkpLHQuZG8pLHQuTikKaWYoci55PT09JCly
-LnNLcChxKQplbHNlIHE9SC52KEguR1EoInBhdGhTZWdtZW50cyIpKX1yZXR1cm4gcX0sCmdpTzpmdW5j
-dGlvbihhKXt2YXIgcz10aGlzLHI9cy56CmlmKHI9PT0kKXtyPUouaGYocy5nbkQoKSkKaWYocy56PT09
-JClzLno9cgplbHNlIHI9SC52KEguR1EoImhhc2hDb2RlIikpfXJldHVybiByfSwKZ2hZOmZ1bmN0aW9u
-KCl7dmFyIHM9dGhpcyxyPXMuUQppZihyPT09JCl7cj1uZXcgUC5HaihQLldYKHMuZ3RQKCkpLHQuZHcp
-CmlmKHMuUT09PSQpcy5zTk0ocikKZWxzZSByPUgudihILkdRKCJxdWVyeVBhcmFtZXRlcnMiKSl9cmV0
-dXJuIHJ9LApna3U6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5ifSwKZ0pmOmZ1bmN0aW9uKGEpe3ZhciBz
-PXRoaXMuYwppZihzPT1udWxsKXJldHVybiIiCmlmKEMueEIubihzLCJbIikpcmV0dXJuIEMueEIuTmoo
-cywxLHMubGVuZ3RoLTEpCnJldHVybiBzfSwKZ3RwOmZ1bmN0aW9uKGEpe3ZhciBzPXRoaXMuZApyZXR1
-cm4gcz09bnVsbD9QLndLKHRoaXMuYSk6c30sCmd0UDpmdW5jdGlvbigpe3ZhciBzPXRoaXMuZgpyZXR1
-cm4gcz09bnVsbD8iIjpzfSwKZ0thOmZ1bmN0aW9uKCl7dmFyIHM9dGhpcy5yCnJldHVybiBzPT1udWxs
-PyIiOnN9LApoQjpmdW5jdGlvbihhKXt2YXIgcz10aGlzLmEKaWYoYS5sZW5ndGghPT1zLmxlbmd0aCly
-ZXR1cm4hMQpyZXR1cm4gUC5OUihhLHMpfSwKbm06ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEscCxvLG4s
-bSxsLGssaj10aGlzCnQuYzkuYShiKQpzPWouYQpyPXM9PT0iZmlsZSIKcT1qLmIKcD1qLmQKbz1qLmMK
-aWYoIShvIT1udWxsKSlvPXEubGVuZ3RoIT09MHx8cCE9bnVsbHx8cj8iIjpudWxsCm49ai5lCmlmKCFy
-KW09byE9bnVsbCYmbi5sZW5ndGghPT0wCmVsc2UgbT0hMAppZihtJiYhQy54Qi5uKG4sIi8iKSluPSIv
-IituCmw9bgprPVAubGUobnVsbCwwLDAsYikKcmV0dXJuIFAuQ2cocyxxLG8scCxsLGssai5yKX0sCkpo
-OmZ1bmN0aW9uKGEsYil7dmFyIHMscixxLHAsbyxuCmZvcihzPTAscj0wO0MueEIuUWkoYiwiLi4vIixy
-KTspe3IrPTM7KytzfXE9Qy54Qi5jbihhLCIvIikKd2hpbGUoITApe2lmKCEocT4wJiZzPjApKWJyZWFr
-CnA9Qy54Qi5QayhhLCIvIixxLTEpCmlmKHA8MClicmVhawpvPXEtcApuPW8hPT0yCmlmKCFufHxvPT09
-MylpZihDLnhCLk8oYSxwKzEpPT09NDYpbj0hbnx8Qy54Qi5PKGEscCsyKT09PTQ2CmVsc2Ugbj0hMQpl
-bHNlIG49ITEKaWYobilicmVhazstLXMKcT1wfXJldHVybiBDLnhCLmk3KGEscSsxLG51bGwsQy54Qi55
-bihiLHItMypzKSl9LApaSTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5tUyhQLmhLKGEpKX0sCm1TOmZ1
-bmN0aW9uKGEpe3ZhciBzLHIscSxwLG8sbixtLGwsayxqLGk9dGhpcyxoPW51bGwKaWYoYS5nRmkoKS5s
-ZW5ndGghPT0wKXtzPWEuZ0ZpKCkKaWYoYS5nY2ooKSl7cj1hLmdrdSgpCnE9YS5nSmYoYSkKcD1hLmd4
-QSgpP2EuZ3RwKGEpOmh9ZWxzZXtwPWgKcT1wCnI9IiJ9bz1QLnhlKGEuZ0lpKGEpKQpuPWEuZ1FEKCk/
-YS5ndFAoKTpofWVsc2V7cz1pLmEKaWYoYS5nY2ooKSl7cj1hLmdrdSgpCnE9YS5nSmYoYSkKcD1QLndC
-KGEuZ3hBKCk/YS5ndHAoYSk6aCxzKQpvPVAueGUoYS5nSWkoYSkpCm49YS5nUUQoKT9hLmd0UCgpOmh9
-ZWxzZXtyPWkuYgpxPWkuYwpwPWkuZApvPWkuZQppZihhLmdJaShhKT09PSIiKW49YS5nUUQoKT9hLmd0
-UCgpOmkuZgplbHNle209UC51aihpLG8pCmlmKG0+MCl7bD1DLnhCLk5qKG8sMCxtKQpvPWEuZ3RUKCk/
-bCtQLnhlKGEuZ0lpKGEpKTpsK1AueGUoaS5KaChDLnhCLnluKG8sbC5sZW5ndGgpLGEuZ0lpKGEpKSl9
-ZWxzZSBpZihhLmd0VCgpKW89UC54ZShhLmdJaShhKSkKZWxzZSBpZihvLmxlbmd0aD09PTApaWYocT09
-bnVsbClvPXMubGVuZ3RoPT09MD9hLmdJaShhKTpQLnhlKGEuZ0lpKGEpKQplbHNlIG89UC54ZSgiLyIr
-YS5nSWkoYSkpCmVsc2V7az1pLkpoKG8sYS5nSWkoYSkpCmo9cy5sZW5ndGg9PT0wCmlmKCFqfHxxIT1u
-dWxsfHxDLnhCLm4obywiLyIpKW89UC54ZShrKQplbHNlIG89UC53RihrLCFqfHxxIT1udWxsKX1uPWEu
-Z1FEKCk/YS5ndFAoKTpofX19cmV0dXJuIFAuQ2cocyxyLHEscCxvLG4sYS5nWjgoKT9hLmdLYSgpOmgp
-fSwKZ2NqOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuYyE9bnVsbH0sCmd4QTpmdW5jdGlvbigpe3JldHVy
-biB0aGlzLmQhPW51bGx9LApnUUQ6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5mIT1udWxsfSwKZ1o4OmZ1
-bmN0aW9uKCl7cmV0dXJuIHRoaXMuciE9bnVsbH0sCmd0VDpmdW5jdGlvbigpe3JldHVybiBDLnhCLm4o
-dGhpcy5lLCIvIil9LAp0NDpmdW5jdGlvbigpe3ZhciBzLHI9dGhpcyxxPXIuYQppZihxIT09IiImJnEh
-PT0iZmlsZSIpdGhyb3cgSC5iKFAuTDQoIkNhbm5vdCBleHRyYWN0IGEgZmlsZSBwYXRoIGZyb20gYSAi
-K3ErIiBVUkkiKSkKaWYoci5ndFAoKSE9PSIiKXRocm93IEguYihQLkw0KHUuaSkpCmlmKHIuZ0thKCkh
-PT0iIil0aHJvdyBILmIoUC5MNCh1LmwpKQpxPSQud1EoKQppZihILm9UKHEpKXE9UC5tbihyKQplbHNl
-e2lmKHIuYyE9bnVsbCYmci5nSmYocikhPT0iIilILnYoUC5MNCh1LmopKQpzPXIuZ0ZqKCkKUC5rRShz
-LCExKQpxPVAudmcoQy54Qi5uKHIuZSwiLyIpPyIvIjoiIixzLCIvIikKcT1xLmNoYXJDb2RlQXQoMCk9
-PTA/cTpxfXJldHVybiBxfSwKdzpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5nbkQoKX0sCkROOmZ1bmN0
-aW9uKGEsYil7dmFyIHM9dGhpcwppZihiPT1udWxsKXJldHVybiExCmlmKHM9PT1iKXJldHVybiEwCnJl
-dHVybiB0LmRELmIoYikmJnMuYT09PWIuZ0ZpKCkmJnMuYyE9bnVsbD09PWIuZ2NqKCkmJnMuYj09PWIu
-Z2t1KCkmJnMuZ0pmKHMpPT09Yi5nSmYoYikmJnMuZ3RwKHMpPT09Yi5ndHAoYikmJnMuZT09PWIuZ0lp
-KGIpJiZzLmYhPW51bGw9PT1iLmdRRCgpJiZzLmd0UCgpPT09Yi5ndFAoKSYmcy5yIT1udWxsPT09Yi5n
-WjgoKSYmcy5nS2EoKT09PWIuZ0thKCl9LApzS3A6ZnVuY3Rpb24oYSl7dGhpcy55PXQuYmsuYShhKX0s
+QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFGRkZGRkZGRkZGRkZGRkZGR0dHR0dHR0dHR0dH
+R0dHR0hISEhISEhISEhISEhISEhISEhISEhISEhISElISEhKRUVCQkJCQkJCQkJCQkJCQkJCQkJCQkJC
+QkJCQkJCQkJLQ0NDQ0NDQ0NDQ0NDRENMT05OTk1FRUVFRUVFRUVFRSIscykmMzEKaD1pPD0zMj9zJjYx
+Njk0Pj4+cToocyY2M3xoPDw2KT4+PjAKaT1DLnhCLlcoIiBceDAwMDpYRUNDQ0NDTjpsRGIgXHgwMDA6
+WEVDQ0NDQ052bERiIFx4MDAwOlhFQ0NDQ0NOOmxEYiBBQUFBQVx4MDBceDAwXHgwMFx4MDBceDAwQUFB
+QUEwMDAwMEFBQUFBOjo6OjpBQUFBQUdHMDAwQUFBQUEwMEtLS0FBQUFBRzo6OjpBQUFBQTpJSUlJQUFB
+QUEwMDBceDgwMEFBQUFBXHgwMFx4MDBceDAwXHgwMCBBQUFBQSIsaStxKQppZihpPT09MCl7Zy5hKz1I
+Lkx3KGgpCmlmKGY9PT1jKWJyZWFrICRsYWJlbDAkMApicmVha31lbHNlIGlmKChpJjEpIT09MCl7aWYo
+cilzd2l0Y2goaSl7Y2FzZSA2OTpjYXNlIDY3OmcuYSs9SC5MdyhqKQpicmVhawpjYXNlIDY1OmcuYSs9
+SC5MdyhqKTstLWYKYnJlYWsKZGVmYXVsdDpwPWcuYSs9SC5MdyhqKQpnLmE9cCtILkx3KGopCmJyZWFr
+fWVsc2V7ay5iPWkKay5jPWYtMQpyZXR1cm4iIn1pPTB9aWYoZj09PWMpYnJlYWsgJGxhYmVsMCQwCm89
+ZisxCmlmKGY8MHx8Zj49ZSlyZXR1cm4gSC5PSChhLGYpCnM9YVtmXX1vPWYrMQppZihmPDB8fGY+PWUp
+cmV0dXJuIEguT0goYSxmKQpzPWFbZl0KaWYoczwxMjgpe3doaWxlKCEwKXtpZighKG88Yykpe249Ywpi
+cmVha31tPW8rMQppZihvPDB8fG8+PWUpcmV0dXJuIEguT0goYSxvKQpzPWFbb10KaWYocz49MTI4KXtu
+PW0tMQpvPW0KYnJlYWt9bz1tfWlmKG4tZjwyMClmb3IobD1mO2w8bjsrK2wpe2lmKGw+PWUpcmV0dXJu
+IEguT0goYSxsKQpnLmErPUguTHcoYVtsXSl9ZWxzZSBnLmErPVAuSE0oYSxmLG4pCmlmKG49PT1jKWJy
+ZWFrICRsYWJlbDAkMApmPW99ZWxzZSBmPW99aWYoZCYmaT4zMilpZihyKWcuYSs9SC5MdyhqKQplbHNl
+e2suYj03NwprLmM9YwpyZXR1cm4iIn1rLmI9aQprLmM9aAplPWcuYQpyZXR1cm4gZS5jaGFyQ29kZUF0
+KDApPT0wP2U6ZX19ClAuV0YucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEKdC5m
+by5hKGEpCnM9dGhpcy5iCnI9dGhpcy5hCnMuYSs9ci5hCnE9cy5hKz1ILkVqKGEuYSkKcy5hPXErIjog
+IgpzLmErPVAucChiKQpyLmE9IiwgIn0sCiRTOjQwfQpQLmlQLnByb3RvdHlwZT17CkROOmZ1bmN0aW9u
+KGEsYil7aWYoYj09bnVsbClyZXR1cm4hMQpyZXR1cm4gYiBpbnN0YW5jZW9mIFAuaVAmJnRoaXMuYT09
+PWIuYSYmITB9LApnaU86ZnVuY3Rpb24oYSl7dmFyIHM9dGhpcy5hCnJldHVybihzXkMuam4ud0cocywz
+MCkpJjEwNzM3NDE4MjN9LAp3OmZ1bmN0aW9uKGEpe3ZhciBzPXRoaXMscj1QLkdxKEgudEoocykpLHE9
+UC5oMChILk5TKHMpKSxwPVAuaDAoSC5qQShzKSksbz1QLmgwKEguSVgocykpLG49UC5oMChILmNoKHMp
+KSxtPVAuaDAoSC5KZChzKSksbD1QLlZ4KEgubzEocykpLGs9cisiLSIrcSsiLSIrcCsiICIrbysiOiIr
+bisiOiIrbSsiLiIrbApyZXR1cm4ga319ClAuWFMucHJvdG90eXBlPXsKZ0lJOmZ1bmN0aW9uKCl7cmV0
+dXJuIEgudHModGhpcy4kdGhyb3duSnNFcnJvcil9fQpQLkM2LnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24o
+YSl7dmFyIHM9dGhpcy5hCmlmKHMhPW51bGwpcmV0dXJuIkFzc2VydGlvbiBmYWlsZWQ6ICIrUC5wKHMp
+CnJldHVybiJBc3NlcnRpb24gZmFpbGVkIn19ClAuRXoucHJvdG90eXBlPXt9ClAuRi5wcm90b3R5cGU9
+ewp3OmZ1bmN0aW9uKGEpe3JldHVybiJUaHJvdyBvZiBudWxsLiJ9fQpQLnUucHJvdG90eXBlPXsKZ1o6
+ZnVuY3Rpb24oKXtyZXR1cm4iSW52YWxpZCBhcmd1bWVudCIrKCF0aGlzLmE/IihzKSI6IiIpfSwKZ3U6
+ZnVuY3Rpb24oKXtyZXR1cm4iIn0sCnc6ZnVuY3Rpb24oYSl7dmFyIHMscixxPXRoaXMscD1xLmMsbz1w
+PT1udWxsPyIiOiIgKCIrcCsiKSIsbj1xLmQsbT1uPT1udWxsPyIiOiI6ICIrSC5FaihuKSxsPXEuZ1oo
+KStvK20KaWYoIXEuYSlyZXR1cm4gbApzPXEuZ3UoKQpyPVAucChxLmIpCnJldHVybiBsK3MrIjogIity
+fX0KUC5iSi5wcm90b3R5cGU9ewpnWjpmdW5jdGlvbigpe3JldHVybiJSYW5nZUVycm9yIn0sCmd1OmZ1
+bmN0aW9uKCl7dmFyIHMscj10aGlzLmUscT10aGlzLmYKaWYocj09bnVsbClzPXEhPW51bGw/IjogTm90
+IGxlc3MgdGhhbiBvciBlcXVhbCB0byAiK0guRWoocSk6IiIKZWxzZSBpZihxPT1udWxsKXM9IjogTm90
+IGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAiK0guRWoocikKZWxzZSBpZihxPnIpcz0iOiBOb3QgaW4g
+aW5jbHVzaXZlIHJhbmdlICIrSC5FaihyKSsiLi4iK0guRWoocSkKZWxzZSBzPXE8cj8iOiBWYWxpZCB2
+YWx1ZSByYW5nZSBpcyBlbXB0eSI6IjogT25seSB2YWxpZCB2YWx1ZSBpcyAiK0guRWoocikKcmV0dXJu
+IHN9fQpQLmVZLnByb3RvdHlwZT17CmdaOmZ1bmN0aW9uKCl7cmV0dXJuIlJhbmdlRXJyb3IifSwKZ3U6
+ZnVuY3Rpb24oKXt2YXIgcyxyPUgudVAodGhpcy5iKQppZih0eXBlb2YgciE9PSJudW1iZXIiKXJldHVy
+biByLkooKQppZihyPDApcmV0dXJuIjogaW5kZXggbXVzdCBub3QgYmUgbmVnYXRpdmUiCnM9dGhpcy5m
+CmlmKHM9PT0wKXJldHVybiI6IG5vIGluZGljZXMgYXJlIHZhbGlkIgpyZXR1cm4iOiBpbmRleCBzaG91
+bGQgYmUgbGVzcyB0aGFuICIrSC5FaihzKX0sCmdBOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmZ9fQpQ
+Lm1wLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7dmFyIHMscixxLHAsbyxuLG0sbCxrPXRoaXMsaj17
+fSxpPW5ldyBQLlJuKCIiKQpqLmE9IiIKcz1rLmMKZm9yKHI9cy5sZW5ndGgscT0wLHA9IiIsbz0iIjtx
+PHI7KytxLG89IiwgIil7bj1zW3FdCmkuYT1wK28KcD1pLmErPVAucChuKQpqLmE9IiwgIn1rLmQuSygw
+LG5ldyBQLldGKGosaSkpCm09UC5wKGsuYSkKbD1pLncoMCkKcj0iTm9TdWNoTWV0aG9kRXJyb3I6IG1l
+dGhvZCBub3QgZm91bmQ6ICciK0guRWooay5iLmEpKyInXG5SZWNlaXZlcjogIittKyJcbkFyZ3VtZW50
+czogWyIrbCsiXSIKcmV0dXJuIHJ9fQpQLnViLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7cmV0dXJu
+IlVuc3VwcG9ydGVkIG9wZXJhdGlvbjogIit0aGlzLmF9fQpQLmRzLnByb3RvdHlwZT17Cnc6ZnVuY3Rp
+b24oYSl7dmFyIHM9dGhpcy5hCnJldHVybiBzIT1udWxsPyJVbmltcGxlbWVudGVkRXJyb3I6ICIrczoi
+VW5pbXBsZW1lbnRlZEVycm9yIn19ClAubGoucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4i
+QmFkIHN0YXRlOiAiK3RoaXMuYX19ClAuVVYucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXt2YXIgcz10
+aGlzLmEKaWYocz09bnVsbClyZXR1cm4iQ29uY3VycmVudCBtb2RpZmljYXRpb24gZHVyaW5nIGl0ZXJh
+dGlvbi4iCnJldHVybiJDb25jdXJyZW50IG1vZGlmaWNhdGlvbiBkdXJpbmcgaXRlcmF0aW9uOiAiK1Au
+cChzKSsiLiJ9fQpQLms1LnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7cmV0dXJuIk91dCBvZiBNZW1v
+cnkifSwKZ0lJOmZ1bmN0aW9uKCl7cmV0dXJuIG51bGx9LAokaVhTOjF9ClAuS1kucHJvdG90eXBlPXsK
+dzpmdW5jdGlvbihhKXtyZXR1cm4iU3RhY2sgT3ZlcmZsb3cifSwKZ0lJOmZ1bmN0aW9uKCl7cmV0dXJu
+IG51bGx9LAokaVhTOjF9ClAuYy5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3ZhciBzPXRoaXMuYQpy
+ZXR1cm4gcz09bnVsbD8iUmVhZGluZyBzdGF0aWMgdmFyaWFibGUgZHVyaW5nIGl0cyBpbml0aWFsaXph
+dGlvbiI6IlJlYWRpbmcgc3RhdGljIHZhcmlhYmxlICciK3MrIicgZHVyaW5nIGl0cyBpbml0aWFsaXph
+dGlvbiJ9fQpQLkNELnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7cmV0dXJuIkV4Y2VwdGlvbjogIit0
+aGlzLmF9LAokaVJ6OjF9ClAuYUUucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXt2YXIgcyxyLHEscCxv
+LG4sbSxsLGssaixpLGgsZz10aGlzLmEsZj1nIT1udWxsJiYiIiE9PWc/IkZvcm1hdEV4Y2VwdGlvbjog
+IitILkVqKGcpOiJGb3JtYXRFeGNlcHRpb24iLGU9dGhpcy5jLGQ9dGhpcy5iCmlmKHR5cGVvZiBkPT0i
+c3RyaW5nIil7aWYoZSE9bnVsbClzPWU8MHx8ZT5kLmxlbmd0aAplbHNlIHM9ITEKaWYocyllPW51bGwK
+aWYoZT09bnVsbCl7aWYoZC5sZW5ndGg+NzgpZD1DLnhCLk5qKGQsMCw3NSkrIi4uLiIKcmV0dXJuIGYr
+IlxuIitkfWZvcihyPTEscT0wLHA9ITEsbz0wO288ZTsrK28pe249Qy54Qi5XKGQsbykKaWYobj09PTEw
+KXtpZihxIT09b3x8IXApKytyCnE9bysxCnA9ITF9ZWxzZSBpZihuPT09MTMpeysrcgpxPW8rMQpwPSEw
+fX1mPXI+MT9mKygiIChhdCBsaW5lICIrcisiLCBjaGFyYWN0ZXIgIisoZS1xKzEpKyIpXG4iKTpmKygi
+IChhdCBjaGFyYWN0ZXIgIisoZSsxKSsiKVxuIikKbT1kLmxlbmd0aApmb3Iobz1lO288bTsrK28pe249
+Qy54Qi5PKGQsbykKaWYobj09PTEwfHxuPT09MTMpe209bwpicmVha319aWYobS1xPjc4KWlmKGUtcTw3
+NSl7bD1xKzc1Cms9cQpqPSIiCmk9Ii4uLiJ9ZWxzZXtpZihtLWU8NzUpe2s9bS03NQpsPW0KaT0iIn1l
+bHNle2s9ZS0zNgpsPWUrMzYKaT0iLi4uIn1qPSIuLi4ifWVsc2V7bD1tCms9cQpqPSIiCmk9IiJ9aD1D
+LnhCLk5qKGQsayxsKQpyZXR1cm4gZitqK2graSsiXG4iK0MueEIuVCgiICIsZS1rK2oubGVuZ3RoKSsi
+XlxuIn1lbHNlIHJldHVybiBlIT1udWxsP2YrKCIgKGF0IG9mZnNldCAiK0guRWooZSkrIikiKTpmfSwK
+JGlSejoxfQpQLmNYLnByb3RvdHlwZT17CmRyOmZ1bmN0aW9uKGEsYil7cmV0dXJuIEguR0oodGhpcyxI
+LkxoKHRoaXMpLkMoImNYLkUiKSxiKX0sCkUyOmZ1bmN0aW9uKGEsYixjKXt2YXIgcz1ILkxoKHRoaXMp
+CnJldHVybiBILksxKHRoaXMscy5LcShjKS5DKCIxKGNYLkUpIikuYShiKSxzLkMoImNYLkUiKSxjKX0s
+CmV2OmZ1bmN0aW9uKGEsYil7dmFyIHM9SC5MaCh0aGlzKQpyZXR1cm4gbmV3IEguVTUodGhpcyxzLkMo
+ImEyKGNYLkUpIikuYShiKSxzLkMoIlU1PGNYLkU+IikpfSwKdHQ6ZnVuY3Rpb24oYSxiKXtyZXR1cm4g
+UC5ZMSh0aGlzLGIsSC5MaCh0aGlzKS5DKCJjWC5FIikpfSwKYnI6ZnVuY3Rpb24oYSl7cmV0dXJuIHRo
+aXMudHQoYSwhMCl9LApnQTpmdW5jdGlvbihhKXt2YXIgcyxyPXRoaXMuZ20odGhpcykKZm9yKHM9MDty
+LkYoKTspKytzCnJldHVybiBzfSwKZ2wwOmZ1bmN0aW9uKGEpe3JldHVybiF0aGlzLmdtKHRoaXMpLkYo
+KX0sCmdvcjpmdW5jdGlvbihhKXtyZXR1cm4hdGhpcy5nbDAodGhpcyl9LAplUjpmdW5jdGlvbihhLGIp
+e3JldHVybiBILmJLKHRoaXMsYixILkxoKHRoaXMpLkMoImNYLkUiKSl9LApncjg6ZnVuY3Rpb24oYSl7
+dmFyIHMscj10aGlzLmdtKHRoaXMpCmlmKCFyLkYoKSl0aHJvdyBILmIoSC5XcCgpKQpzPXIuZ2woKQpp
+ZihyLkYoKSl0aHJvdyBILmIoSC5BbSgpKQpyZXR1cm4gc30sCkU6ZnVuY3Rpb24oYSxiKXt2YXIgcyxy
+LHEKUC5rMShiLCJpbmRleCIpCmZvcihzPXRoaXMuZ20odGhpcykscj0wO3MuRigpOyl7cT1zLmdsKCkK
+aWYoYj09PXIpcmV0dXJuIHE7KytyfXRocm93IEguYihQLkNmKGIsdGhpcywiaW5kZXgiLG51bGwscikp
+fSwKdzpmdW5jdGlvbihhKXtyZXR1cm4gUC5FUCh0aGlzLCIoIiwiKSIpfX0KUC5Bbi5wcm90b3R5cGU9
+e30KUC5OMy5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiJNYXBFbnRyeSgiK0guRWoodGhp
+cy5hKSsiOiAiK0guRWoodGhpcy5iKSsiKSJ9fQpQLmM4LnByb3RvdHlwZT17CmdpTzpmdW5jdGlvbihh
+KXtyZXR1cm4gUC5NaC5wcm90b3R5cGUuZ2lPLmNhbGwodGhpcyx0aGlzKX0sCnc6ZnVuY3Rpb24oYSl7
+cmV0dXJuIm51bGwifX0KUC5NaC5wcm90b3R5cGU9e2NvbnN0cnVjdG9yOlAuTWgsJGlNaDoxLApETjpm
+dW5jdGlvbihhLGIpe3JldHVybiB0aGlzPT09Yn0sCmdpTzpmdW5jdGlvbihhKXtyZXR1cm4gSC5lUSh0
+aGlzKX0sCnc6ZnVuY3Rpb24oYSl7cmV0dXJuIkluc3RhbmNlIG9mICciK0guRWooSC5NKHRoaXMpKSsi
+JyJ9LAplNzpmdW5jdGlvbihhLGIpe3Quby5hKGIpCnRocm93IEguYihQLmxyKHRoaXMsYi5nV2EoKSxi
+LmduZCgpLGIuZ1ZtKCkpKX0sCnRvU3RyaW5nOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMudyh0aGlzKX19
+ClAuWmQucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4iIn0sCiRpR3o6MX0KUC5Sbi5wcm90
+b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hLmxlbmd0aH0sCnc6ZnVuY3Rpb24oYSl7
+dmFyIHM9dGhpcy5hCnJldHVybiBzLmNoYXJDb2RlQXQoMCk9PTA/czpzfSwKJGlCTDoxfQpQLm4xLnBy
+b3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7dmFyIHMscixxLHAKdC5KLmEoYSkKSC5oKGIpCnM9Si5E
+MShiLCI9IikKaWYocz09PS0xKXtpZihiIT09IiIpYS5ZNSgwLFAua3UoYiwwLGIubGVuZ3RoLHRoaXMu
+YSwhMCksIiIpfWVsc2UgaWYocyE9PTApe3I9Qy54Qi5OaihiLDAscykKcT1DLnhCLnluKGIscysxKQpw
+PXRoaXMuYQphLlk1KDAsUC5rdShyLDAsci5sZW5ndGgscCwhMCksUC5rdShxLDAscS5sZW5ndGgscCwh
+MCkpfXJldHVybiBhfSwKJFM6NDF9ClAuY1MucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt0aHJv
+dyBILmIoUC5ycigiSWxsZWdhbCBJUHY0IGFkZHJlc3MsICIrYSx0aGlzLmEsYikpfSwKJFM6MjF9ClAu
+VkMucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt0aHJvdyBILmIoUC5ycigiSWxsZWdhbCBJUHY2
+IGFkZHJlc3MsICIrYSx0aGlzLmEsYikpfSwKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuJDIoYSxu
+dWxsKX0sCiRTOjQ1fQpQLkpULnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7dmFyIHMKaWYoYi1h
+PjQpdGhpcy5hLiQyKCJhbiBJUHY2IHBhcnQgY2FuIG9ubHkgY29udGFpbiBhIG1heGltdW0gb2YgNCBo
+ZXggZGlnaXRzIixhKQpzPVAuUUEoQy54Qi5Oaih0aGlzLmIsYSxiKSwxNikKaWYoczwwfHxzPjY1NTM1
+KXRoaXMuYS4kMigiZWFjaCBwYXJ0IG11c3QgYmUgaW4gdGhlIHJhbmdlIG9mIGAweDAuLjB4RkZGRmAi
+LGEpCnJldHVybiBzfSwKJFM6NTJ9ClAuRG4ucHJvdG90eXBlPXsKZ25EOmZ1bmN0aW9uKCl7dmFyIHMs
+cixxLHA9dGhpcyxvPXAueAppZihvPT09JCl7bz1wLmEKcz1vLmxlbmd0aCE9PTA/bysiOiI6IiIKcj1w
+LmMKcT1yPT1udWxsCmlmKCFxfHxvPT09ImZpbGUiKXtvPXMrIi8vIgpzPXAuYgppZihzLmxlbmd0aCE9
+PTApbz1vK3MrIkAiCmlmKCFxKW8rPXIKcz1wLmQKaWYocyE9bnVsbClvPW8rIjoiK0guRWoocyl9ZWxz
+ZSBvPXMKbys9cC5lCnM9cC5mCmlmKHMhPW51bGwpbz1vKyI/IitzCnM9cC5yCmlmKHMhPW51bGwpbz1v
+KyIjIitzCm89by5jaGFyQ29kZUF0KDApPT0wP286bwppZihwLng9PT0kKXAueD1vCmVsc2Ugbz1ILnYo
+SC5HUSgiX3RleHQiKSl9cmV0dXJuIG99LApnRmo6ZnVuY3Rpb24oKXt2YXIgcyxyPXRoaXMscT1yLnkK
+aWYocT09PSQpe3M9ci5lCmlmKHMubGVuZ3RoIT09MCYmQy54Qi5XKHMsMCk9PT00NylzPUMueEIueW4o
+cywxKQpxPXMubGVuZ3RoPT09MD9DLnhEOlAuQUYobmV3IEgubEooSC5WTShzLnNwbGl0KCIvIiksdC5z
+KSx0LmRPLmEoUC5QSCgpKSx0LmRvKSx0Lk4pCmlmKHIueT09PSQpci5zS3AocSkKZWxzZSBxPUgudihI
+LkdRKCJwYXRoU2VnbWVudHMiKSl9cmV0dXJuIHF9LApnaU86ZnVuY3Rpb24oYSl7dmFyIHM9dGhpcyxy
+PXMuegppZihyPT09JCl7cj1KLmhmKHMuZ25EKCkpCmlmKHMuej09PSQpcy56PXIKZWxzZSByPUgudihI
+LkdRKCJoYXNoQ29kZSIpKX1yZXR1cm4gcn0sCmdoWTpmdW5jdGlvbigpe3ZhciBzPXRoaXMscj1zLlEK
+aWYocj09PSQpe3I9cy5mCnI9bmV3IFAuR2ooUC5XWChyPT1udWxsPyIiOnIpLHQuZHcpCmlmKHMuUT09
+PSQpcy5zTk0ocikKZWxzZSByPUgudihILkdRKCJxdWVyeVBhcmFtZXRlcnMiKSl9cmV0dXJuIHJ9LApn
+a3U6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5ifSwKZ0pmOmZ1bmN0aW9uKGEpe3ZhciBzPXRoaXMuYwpp
+ZihzPT1udWxsKXJldHVybiIiCmlmKEMueEIubkMocywiWyIpKXJldHVybiBDLnhCLk5qKHMsMSxzLmxl
+bmd0aC0xKQpyZXR1cm4gc30sCmd0cDpmdW5jdGlvbihhKXt2YXIgcz10aGlzLmQKcmV0dXJuIHM9PW51
+bGw/UC53Syh0aGlzLmEpOnN9LApndFA6ZnVuY3Rpb24oKXt2YXIgcz10aGlzLmYKcmV0dXJuIHM9PW51
+bGw/IiI6c30sCmdLYTpmdW5jdGlvbigpe3ZhciBzPXRoaXMucgpyZXR1cm4gcz09bnVsbD8iIjpzfSwK
+aEI6ZnVuY3Rpb24oYSl7dmFyIHM9dGhpcy5hCmlmKGEubGVuZ3RoIT09cy5sZW5ndGgpcmV0dXJuITEK
+cmV0dXJuIFAuTlIoYSxzKX0sCm5tOmZ1bmN0aW9uKGEsYil7dmFyIHMscixxLHAsbyxuLG0sbCxrLGo9
+dGhpcwp0LmM5LmEoYikKcz1qLmEKcj1zPT09ImZpbGUiCnE9ai5iCnA9ai5kCm89ai5jCmlmKCEobyE9
+bnVsbCkpbz1xLmxlbmd0aCE9PTB8fHAhPW51bGx8fHI/IiI6bnVsbApuPWouZQppZighciltPW8hPW51
+bGwmJm4ubGVuZ3RoIT09MAplbHNlIG09ITAKaWYobSYmIUMueEIubkMobiwiLyIpKW49Ii8iK24KbD1u
+Cms9UC5sZShudWxsLDAsMCxiKQpyZXR1cm4gUC5DZyhzLHEsbyxwLGwsayxqLnIpfSwKSmg6ZnVuY3Rp
+b24oYSxiKXt2YXIgcyxyLHEscCxvLG4KZm9yKHM9MCxyPTA7Qy54Qi5RaShiLCIuLi8iLHIpOyl7cis9
+MzsrK3N9cT1DLnhCLmNuKGEsIi8iKQp3aGlsZSghMCl7aWYoIShxPjAmJnM+MCkpYnJlYWsKcD1DLnhC
+LlBrKGEsIi8iLHEtMSkKaWYocDwwKWJyZWFrCm89cS1wCm49byE9PTIKaWYoIW58fG89PT0zKWlmKEMu
+eEIuTyhhLHArMSk9PT00NiluPSFufHxDLnhCLk8oYSxwKzIpPT09NDYKZWxzZSBuPSExCmVsc2Ugbj0h
+MQppZihuKWJyZWFrOy0tcwpxPXB9cmV0dXJuIEMueEIuaTcoYSxxKzEsbnVsbCxDLnhCLnluKGIsci0z
+KnMpKX0sClpJOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLm1TKFAuaEsoYSkpfSwKbVM6ZnVuY3Rpb24o
+YSl7dmFyIHMscixxLHAsbyxuLG0sbCxrLGosaT10aGlzLGg9bnVsbAppZihhLmdGaSgpLmxlbmd0aCE9
+PTApe3M9YS5nRmkoKQppZihhLmdjaigpKXtyPWEuZ2t1KCkKcT1hLmdKZihhKQpwPWEuZ3hBKCk/YS5n
+dHAoYSk6aH1lbHNle3A9aApxPXAKcj0iIn1vPVAueGUoYS5nSWkoYSkpCm49YS5nUUQoKT9hLmd0UCgp
+Omh9ZWxzZXtzPWkuYQppZihhLmdjaigpKXtyPWEuZ2t1KCkKcT1hLmdKZihhKQpwPVAud0IoYS5neEEo
+KT9hLmd0cChhKTpoLHMpCm89UC54ZShhLmdJaShhKSkKbj1hLmdRRCgpP2EuZ3RQKCk6aH1lbHNle3I9
+aS5iCnE9aS5jCnA9aS5kCm89aS5lCmlmKGEuZ0lpKGEpPT09IiIpbj1hLmdRRCgpP2EuZ3RQKCk6aS5m
+CmVsc2V7bT1QLnVqKGksbykKaWYobT4wKXtsPUMueEIuTmoobywwLG0pCm89YS5ndFQoKT9sK1AueGUo
+YS5nSWkoYSkpOmwrUC54ZShpLkpoKEMueEIueW4obyxsLmxlbmd0aCksYS5nSWkoYSkpKX1lbHNlIGlm
+KGEuZ3RUKCkpbz1QLnhlKGEuZ0lpKGEpKQplbHNlIGlmKG8ubGVuZ3RoPT09MClpZihxPT1udWxsKW89
+cy5sZW5ndGg9PT0wP2EuZ0lpKGEpOlAueGUoYS5nSWkoYSkpCmVsc2Ugbz1QLnhlKCIvIithLmdJaShh
+KSkKZWxzZXtrPWkuSmgobyxhLmdJaShhKSkKaj1zLmxlbmd0aD09PTAKaWYoIWp8fHEhPW51bGx8fEMu
+eEIubkMobywiLyIpKW89UC54ZShrKQplbHNlIG89UC53RihrLCFqfHxxIT1udWxsKX1uPWEuZ1FEKCk/
+YS5ndFAoKTpofX19cmV0dXJuIFAuQ2cocyxyLHEscCxvLG4sYS5nWjgoKT9hLmdLYSgpOmgpfSwKZ2Nq
+OmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuYyE9bnVsbH0sCmd4QTpmdW5jdGlvbigpe3JldHVybiB0aGlz
+LmQhPW51bGx9LApnUUQ6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5mIT1udWxsfSwKZ1o4OmZ1bmN0aW9u
+KCl7cmV0dXJuIHRoaXMuciE9bnVsbH0sCmd0VDpmdW5jdGlvbigpe3JldHVybiBDLnhCLm5DKHRoaXMu
+ZSwiLyIpfSwKdDQ6ZnVuY3Rpb24oKXt2YXIgcyxyPXRoaXMscT1yLmEKaWYocSE9PSIiJiZxIT09ImZp
+bGUiKXRocm93IEguYihQLkw0KCJDYW5ub3QgZXh0cmFjdCBhIGZpbGUgcGF0aCBmcm9tIGEgIitxKyIg
+VVJJIikpCnE9ci5mCmlmKChxPT1udWxsPyIiOnEpIT09IiIpdGhyb3cgSC5iKFAuTDQodS5pKSkKcT1y
+LnIKaWYoKHE9PW51bGw/IiI6cSkhPT0iIil0aHJvdyBILmIoUC5MNCh1LmwpKQpxPSQud1EoKQppZihI
+Lm9UKHEpKXE9UC5tbihyKQplbHNle2lmKHIuYyE9bnVsbCYmci5nSmYocikhPT0iIilILnYoUC5MNCh1
+LmopKQpzPXIuZ0ZqKCkKUC5rRShzLCExKQpxPVAudmcoQy54Qi5uQyhyLmUsIi8iKT8iLyI6IiIscywi
+LyIpCnE9cS5jaGFyQ29kZUF0KDApPT0wP3E6cX1yZXR1cm4gcX0sCnc6ZnVuY3Rpb24oYSl7cmV0dXJu
+IHRoaXMuZ25EKCl9LApETjpmdW5jdGlvbihhLGIpe3ZhciBzLHIscT10aGlzCmlmKGI9PW51bGwpcmV0
+dXJuITEKaWYocT09PWIpcmV0dXJuITAKaWYodC5kRC5iKGIpKWlmKHEuYT09PWIuZ0ZpKCkpaWYocS5j
+IT1udWxsPT09Yi5nY2ooKSlpZihxLmI9PT1iLmdrdSgpKWlmKHEuZ0pmKHEpPT09Yi5nSmYoYikpaWYo
+cS5ndHAocSk9PT1iLmd0cChiKSlpZihxLmU9PT1iLmdJaShiKSl7cz1xLmYKcj1zPT1udWxsCmlmKCFy
+PT09Yi5nUUQoKSl7aWYocilzPSIiCmlmKHM9PT1iLmd0UCgpKXtzPXEucgpyPXM9PW51bGwKaWYoIXI9
+PT1iLmdaOCgpKXtpZihyKXM9IiIKcz1zPT09Yi5nS2EoKX1lbHNlIHM9ITF9ZWxzZSBzPSExfWVsc2Ug
+cz0hMX1lbHNlIHM9ITEKZWxzZSBzPSExCmVsc2Ugcz0hMQplbHNlIHM9ITEKZWxzZSBzPSExCmVsc2Ug
+cz0hMQplbHNlIHM9ITEKcmV0dXJuIHN9LApzS3A6ZnVuY3Rpb24oYSl7dGhpcy55PXQuYmsuYShhKX0s
 CnNOTTpmdW5jdGlvbihhKXt0aGlzLlE9dC5jWi5hKGEpfSwKJGlpRDoxLApnRmk6ZnVuY3Rpb24oKXty
 ZXR1cm4gdGhpcy5hfSwKZ0lpOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmV9fQpQLlJaLnByb3RvdHlw
 ZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiBQLmVQKEMuWkosSC5oKGEpLEMueE0sITEpfSwKJFM6NX0K
@@ -10435,69 +10461,69 @@
 Pj4wCmlmKHE+PTk2KXJldHVybiBILk9IKGEscSkKYVtxXT1jfX0sCiRTOjE0fQpQLlVmLnByb3RvdHlw
 ZT17CmdjajpmdW5jdGlvbigpe3JldHVybiB0aGlzLmM+MH0sCmd4QTpmdW5jdGlvbigpe3JldHVybiB0
 aGlzLmM+MCYmdGhpcy5kKzE8dGhpcy5lfSwKZ1FEOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuZjx0aGlz
-LnJ9LApnWjg6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5yPHRoaXMuYS5sZW5ndGh9LApnTnc6ZnVuY3Rp
-b24oKXtyZXR1cm4gdGhpcy5iPT09NCYmQy54Qi5uKHRoaXMuYSwiZmlsZSIpfSwKZ1daOmZ1bmN0aW9u
-KCl7cmV0dXJuIHRoaXMuYj09PTQmJkMueEIubih0aGlzLmEsImh0dHAiKX0sCmdSZTpmdW5jdGlvbigp
-e3JldHVybiB0aGlzLmI9PT01JiZDLnhCLm4odGhpcy5hLCJodHRwcyIpfSwKZ1piOmZ1bmN0aW9uKCl7
-cmV0dXJuIHRoaXMuYj09PTcmJkMueEIubih0aGlzLmEsInBhY2thZ2UiKX0sCmd0VDpmdW5jdGlvbigp
-e3JldHVybiBDLnhCLlFpKHRoaXMuYSwiLyIsdGhpcy5lKX0sCmdGaTpmdW5jdGlvbigpe3ZhciBzPXRo
-aXMueApyZXR1cm4gcz09bnVsbD90aGlzLng9dGhpcy5VMigpOnN9LApVMjpmdW5jdGlvbigpe3ZhciBz
-PXRoaXMscj1zLmIKaWYocjw9MClyZXR1cm4iIgppZihzLmdXWigpKXJldHVybiJodHRwIgppZihzLmdS
-ZSgpKXJldHVybiJodHRwcyIKaWYocy5nTncoKSlyZXR1cm4iZmlsZSIKaWYocy5nWmIoKSlyZXR1cm4i
-cGFja2FnZSIKcmV0dXJuIEMueEIuTmoocy5hLDAscil9LApna3U6ZnVuY3Rpb24oKXt2YXIgcz10aGlz
-LmMscj10aGlzLmIrMwpyZXR1cm4gcz5yP0MueEIuTmoodGhpcy5hLHIscy0xKToiIn0sCmdKZjpmdW5j
-dGlvbihhKXt2YXIgcz10aGlzLmMKcmV0dXJuIHM+MD9DLnhCLk5qKHRoaXMuYSxzLHRoaXMuZCk6IiJ9
-LApndHA6ZnVuY3Rpb24oYSl7dmFyIHM9dGhpcwppZihzLmd4QSgpKXJldHVybiBQLlFBKEMueEIuTmoo
-cy5hLHMuZCsxLHMuZSksbnVsbCkKaWYocy5nV1ooKSlyZXR1cm4gODAKaWYocy5nUmUoKSlyZXR1cm4g
-NDQzCnJldHVybiAwfSwKZ0lpOmZ1bmN0aW9uKGEpe3JldHVybiBDLnhCLk5qKHRoaXMuYSx0aGlzLmUs
-dGhpcy5mKX0sCmd0UDpmdW5jdGlvbigpe3ZhciBzPXRoaXMuZixyPXRoaXMucgpyZXR1cm4gczxyP0Mu
-eEIuTmoodGhpcy5hLHMrMSxyKToiIn0sCmdLYTpmdW5jdGlvbigpe3ZhciBzPXRoaXMucixyPXRoaXMu
-YQpyZXR1cm4gczxyLmxlbmd0aD9DLnhCLnluKHIscysxKToiIn0sCmdGajpmdW5jdGlvbigpe3ZhciBz
-LHIscT10aGlzLmUscD10aGlzLmYsbz10aGlzLmEKaWYoQy54Qi5RaShvLCIvIixxKSkrK3EKaWYocT09
-PXApcmV0dXJuIEMueEQKcz1ILlZNKFtdLHQucykKZm9yKHI9cTtyPHA7KytyKWlmKEMueEIuTyhvLHIp
-PT09NDcpe0MuTm0uaShzLEMueEIuTmoobyxxLHIpKQpxPXIrMX1DLk5tLmkocyxDLnhCLk5qKG8scSxw
-KSkKcmV0dXJuIFAuQUYocyx0Lk4pfSwKZ2hZOmZ1bmN0aW9uKCl7aWYodGhpcy5mPj10aGlzLnIpcmV0
-dXJuIEMuQ00KcmV0dXJuIG5ldyBQLkdqKFAuV1godGhpcy5ndFAoKSksdC5kdyl9LAprWDpmdW5jdGlv
-bihhKXt2YXIgcz10aGlzLmQrMQpyZXR1cm4gcythLmxlbmd0aD09PXRoaXMuZSYmQy54Qi5RaSh0aGlz
-LmEsYSxzKX0sCk45OmZ1bmN0aW9uKCl7dmFyIHM9dGhpcyxyPXMucixxPXMuYQppZihyPj1xLmxlbmd0
-aClyZXR1cm4gcwpyZXR1cm4gbmV3IFAuVWYoQy54Qi5OaihxLDAscikscy5iLHMuYyxzLmQscy5lLHMu
-ZixyLHMueCl9LApubTpmdW5jdGlvbihhLGIpe3ZhciBzLHIscSxwLG8sbixtLGwsayxqLGk9dGhpcyxo
-PW51bGwKdC5jOS5hKGIpCnM9aS5nRmkoKQpyPXM9PT0iZmlsZSIKcT1pLmMKcD1xPjA/Qy54Qi5Oaihp
-LmEsaS5iKzMscSk6IiIKbz1pLmd4QSgpP2kuZ3RwKGkpOmgKcT1pLmMKaWYocT4wKW49Qy54Qi5Oaihp
-LmEscSxpLmQpCmVsc2Ugbj1wLmxlbmd0aCE9PTB8fG8hPW51bGx8fHI/IiI6aApxPWkuYQptPUMueEIu
-TmoocSxpLmUsaS5mKQppZighcilsPW4hPW51bGwmJm0ubGVuZ3RoIT09MAplbHNlIGw9ITAKaWYobCYm
-IUMueEIubihtLCIvIikpbT0iLyIrbQprPVAubGUoaCwwLDAsYikKbD1pLnIKaj1sPHEubGVuZ3RoP0Mu
-eEIueW4ocSxsKzEpOmgKcmV0dXJuIFAuQ2cocyxwLG4sbyxtLGssail9LApaSTpmdW5jdGlvbihhKXty
-ZXR1cm4gdGhpcy5tUyhQLmhLKGEpKX0sCm1TOmZ1bmN0aW9uKGEpe2lmKGEgaW5zdGFuY2VvZiBQLlVm
-KXJldHVybiB0aGlzLnUxKHRoaXMsYSkKcmV0dXJuIHRoaXMudnMoKS5tUyhhKX0sCnUxOmZ1bmN0aW9u
-KGEsYil7dmFyIHMscixxLHAsbyxuLG0sbCxrLGosaSxoLGcsZixlLGQ9Yi5iCmlmKGQ+MClyZXR1cm4g
-YgpzPWIuYwppZihzPjApe3I9YS5iCmlmKHI8PTApcmV0dXJuIGIKaWYoYS5nTncoKSlxPWIuZSE9PWIu
-ZgplbHNlIGlmKGEuZ1daKCkpcT0hYi5rWCgiODAiKQplbHNlIHE9IWEuZ1JlKCl8fCFiLmtYKCI0NDMi
-KQppZihxKXtwPXIrMQpyZXR1cm4gbmV3IFAuVWYoQy54Qi5OaihhLmEsMCxwKStDLnhCLnluKGIuYSxk
-KzEpLHIscytwLGIuZCtwLGIuZStwLGIuZitwLGIucitwLGEueCl9ZWxzZSByZXR1cm4gdGhpcy52cygp
-Lm1TKGIpfW89Yi5lCmQ9Yi5mCmlmKG89PT1kKXtzPWIucgppZihkPHMpe3I9YS5mCnA9ci1kCnJldHVy
-biBuZXcgUC5VZihDLnhCLk5qKGEuYSwwLHIpK0MueEIueW4oYi5hLGQpLGEuYixhLmMsYS5kLGEuZSxk
-K3AscytwLGEueCl9ZD1iLmEKaWYoczxkLmxlbmd0aCl7cj1hLnIKcmV0dXJuIG5ldyBQLlVmKEMueEIu
-TmooYS5hLDAscikrQy54Qi55bihkLHMpLGEuYixhLmMsYS5kLGEuZSxhLmYscysoci1zKSxhLngpfXJl
-dHVybiBhLk45KCl9cz1iLmEKaWYoQy54Qi5RaShzLCIvIixvKSl7bj1hLmUKbT1QLlJ4KHRoaXMpCmw9
-bT4wP206bgpwPWwtbwpyZXR1cm4gbmV3IFAuVWYoQy54Qi5OaihhLmEsMCxsKStDLnhCLnluKHMsbyks
-YS5iLGEuYyxhLmQsbixkK3AsYi5yK3AsYS54KX1rPWEuZQpqPWEuZgppZihrPT09aiYmYS5jPjApe2Zv
-cig7Qy54Qi5RaShzLCIuLi8iLG8pOylvKz0zCnA9ay1vKzEKcmV0dXJuIG5ldyBQLlVmKEMueEIuTmoo
-YS5hLDAsaykrIi8iK0MueEIueW4ocyxvKSxhLmIsYS5jLGEuZCxrLGQrcCxiLnIrcCxhLngpfWk9YS5h
-Cm09UC5SeCh0aGlzKQppZihtPj0wKWg9bQplbHNlIGZvcihoPWs7Qy54Qi5RaShpLCIuLi8iLGgpOylo
-Kz0zCmc9MAp3aGlsZSghMCl7Zj1vKzMKaWYoIShmPD1kJiZDLnhCLlFpKHMsIi4uLyIsbykpKWJyZWFr
-OysrZwpvPWZ9Zm9yKGU9IiI7aj5oOyl7LS1qCmlmKEMueEIuTyhpLGopPT09NDcpe2lmKGc9PT0wKXtl
-PSIvIgpicmVha30tLWcKZT0iLyJ9fWlmKGo9PT1oJiZhLmI8PTAmJiFDLnhCLlFpKGksIi8iLGspKXtv
-LT1nKjMKZT0iIn1wPWotbytlLmxlbmd0aApyZXR1cm4gbmV3IFAuVWYoQy54Qi5OaihpLDAsaikrZStD
-LnhCLnluKHMsbyksYS5iLGEuYyxhLmQsayxkK3AsYi5yK3AsYS54KX0sCnQ0OmZ1bmN0aW9uKCl7dmFy
-IHMscixxLHA9dGhpcwppZihwLmI+PTAmJiFwLmdOdygpKXRocm93IEguYihQLkw0KCJDYW5ub3QgZXh0
-cmFjdCBhIGZpbGUgcGF0aCBmcm9tIGEgIitwLmdGaSgpKyIgVVJJIikpCnM9cC5mCnI9cC5hCmlmKHM8
-ci5sZW5ndGgpe2lmKHM8cC5yKXRocm93IEguYihQLkw0KHUuaSkpCnRocm93IEguYihQLkw0KHUubCkp
-fXE9JC53USgpCmlmKEgub1QocSkpcz1QLm1uKHApCmVsc2V7aWYocC5jPHAuZClILnYoUC5MNCh1Lmop
-KQpzPUMueEIuTmoocixwLmUscyl9cmV0dXJuIHN9LApnaU86ZnVuY3Rpb24oYSl7dmFyIHM9dGhpcy55
+LnJ9LApnWjg6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5yPHRoaXMuYS5sZW5ndGh9LApndFQ6ZnVuY3Rp
+b24oKXtyZXR1cm4gQy54Qi5RaSh0aGlzLmEsIi8iLHRoaXMuZSl9LApnRmk6ZnVuY3Rpb24oKXt2YXIg
+cz10aGlzLngKcmV0dXJuIHM9PW51bGw/dGhpcy54PXRoaXMuVTIoKTpzfSwKVTI6ZnVuY3Rpb24oKXt2
+YXIgcyxyPXRoaXMscT1yLmIKaWYocTw9MClyZXR1cm4iIgpzPXE9PT00CmlmKHMmJkMueEIubkMoci5h
+LCJodHRwIikpcmV0dXJuImh0dHAiCmlmKHE9PT01JiZDLnhCLm5DKHIuYSwiaHR0cHMiKSlyZXR1cm4i
+aHR0cHMiCmlmKHMmJkMueEIubkMoci5hLCJmaWxlIikpcmV0dXJuImZpbGUiCmlmKHE9PT03JiZDLnhC
+Lm5DKHIuYSwicGFja2FnZSIpKXJldHVybiJwYWNrYWdlIgpyZXR1cm4gQy54Qi5OaihyLmEsMCxxKX0s
+CmdrdTpmdW5jdGlvbigpe3ZhciBzPXRoaXMuYyxyPXRoaXMuYiszCnJldHVybiBzPnI/Qy54Qi5Oaih0
+aGlzLmEscixzLTEpOiIifSwKZ0pmOmZ1bmN0aW9uKGEpe3ZhciBzPXRoaXMuYwpyZXR1cm4gcz4wP0Mu
+eEIuTmoodGhpcy5hLHMsdGhpcy5kKToiIn0sCmd0cDpmdW5jdGlvbihhKXt2YXIgcyxyPXRoaXMKaWYo
+ci5neEEoKSlyZXR1cm4gUC5RQShDLnhCLk5qKHIuYSxyLmQrMSxyLmUpLG51bGwpCnM9ci5iCmlmKHM9
+PT00JiZDLnhCLm5DKHIuYSwiaHR0cCIpKXJldHVybiA4MAppZihzPT09NSYmQy54Qi5uQyhyLmEsImh0
+dHBzIikpcmV0dXJuIDQ0MwpyZXR1cm4gMH0sCmdJaTpmdW5jdGlvbihhKXtyZXR1cm4gQy54Qi5Oaih0
+aGlzLmEsdGhpcy5lLHRoaXMuZil9LApndFA6ZnVuY3Rpb24oKXt2YXIgcz10aGlzLmYscj10aGlzLnIK
+cmV0dXJuIHM8cj9DLnhCLk5qKHRoaXMuYSxzKzEscik6IiJ9LApnS2E6ZnVuY3Rpb24oKXt2YXIgcz10
+aGlzLnIscj10aGlzLmEKcmV0dXJuIHM8ci5sZW5ndGg/Qy54Qi55bihyLHMrMSk6IiJ9LApnRmo6ZnVu
+Y3Rpb24oKXt2YXIgcyxyLHE9dGhpcy5lLHA9dGhpcy5mLG89dGhpcy5hCmlmKEMueEIuUWkobywiLyIs
+cSkpKytxCmlmKHE9PT1wKXJldHVybiBDLnhECnM9SC5WTShbXSx0LnMpCmZvcihyPXE7cjxwOysrcilp
+ZihDLnhCLk8obyxyKT09PTQ3KXtDLk5tLmkocyxDLnhCLk5qKG8scSxyKSkKcT1yKzF9Qy5ObS5pKHMs
+Qy54Qi5OaihvLHEscCkpCnJldHVybiBQLkFGKHMsdC5OKX0sCmdoWTpmdW5jdGlvbigpe2lmKHRoaXMu
+Zj49dGhpcy5yKXJldHVybiBDLkNNCnJldHVybiBuZXcgUC5HaihQLldYKHRoaXMuZ3RQKCkpLHQuZHcp
+fSwKa1g6ZnVuY3Rpb24oYSl7dmFyIHM9dGhpcy5kKzEKcmV0dXJuIHMrYS5sZW5ndGg9PT10aGlzLmUm
+JkMueEIuUWkodGhpcy5hLGEscyl9LApOOTpmdW5jdGlvbigpe3ZhciBzPXRoaXMscj1zLnIscT1zLmEK
+aWYocj49cS5sZW5ndGgpcmV0dXJuIHMKcmV0dXJuIG5ldyBQLlVmKEMueEIuTmoocSwwLHIpLHMuYixz
+LmMscy5kLHMuZSxzLmYscixzLngpfSwKbm06ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEscCxvLG4sbSxs
+LGssaixpPXRoaXMsaD1udWxsCnQuYzkuYShiKQpzPWkuZ0ZpKCkKcj1zPT09ImZpbGUiCnE9aS5jCnA9
+cT4wP0MueEIuTmooaS5hLGkuYiszLHEpOiIiCm89aS5neEEoKT9pLmd0cChpKTpoCnE9aS5jCmlmKHE+
+MCluPUMueEIuTmooaS5hLHEsaS5kKQplbHNlIG49cC5sZW5ndGghPT0wfHxvIT1udWxsfHxyPyIiOmgK
+cT1pLmEKbT1DLnhCLk5qKHEsaS5lLGkuZikKaWYoIXIpbD1uIT1udWxsJiZtLmxlbmd0aCE9PTAKZWxz
+ZSBsPSEwCmlmKGwmJiFDLnhCLm5DKG0sIi8iKSltPSIvIittCms9UC5sZShoLDAsMCxiKQpsPWkucgpq
+PWw8cS5sZW5ndGg/Qy54Qi55bihxLGwrMSk6aApyZXR1cm4gUC5DZyhzLHAsbixvLG0sayxqKX0sClpJ
+OmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLm1TKFAuaEsoYSkpfSwKbVM6ZnVuY3Rpb24oYSl7aWYoYSBp
+bnN0YW5jZW9mIFAuVWYpcmV0dXJuIHRoaXMudTEodGhpcyxhKQpyZXR1cm4gdGhpcy5SZSgpLm1TKGEp
+fSwKdTE6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEscCxvLG4sbSxsLGssaixpLGgsZyxmLGUsZCxjPWIu
+YgppZihjPjApcmV0dXJuIGIKcz1iLmMKaWYocz4wKXtyPWEuYgppZihyPD0wKXJldHVybiBiCnE9cj09
+PTQKaWYocSYmQy54Qi5uQyhhLmEsImZpbGUiKSlwPWIuZSE9PWIuZgplbHNlIGlmKHEmJkMueEIubkMo
+YS5hLCJodHRwIikpcD0hYi5rWCgiODAiKQplbHNlIHA9IShyPT09NSYmQy54Qi5uQyhhLmEsImh0dHBz
+IikpfHwhYi5rWCgiNDQzIikKaWYocCl7bz1yKzEKcmV0dXJuIG5ldyBQLlVmKEMueEIuTmooYS5hLDAs
+bykrQy54Qi55bihiLmEsYysxKSxyLHMrbyxiLmQrbyxiLmUrbyxiLmYrbyxiLnIrbyxhLngpfWVsc2Ug
+cmV0dXJuIHRoaXMuUmUoKS5tUyhiKX1uPWIuZQpjPWIuZgppZihuPT09Yyl7cz1iLnIKaWYoYzxzKXty
+PWEuZgpvPXItYwpyZXR1cm4gbmV3IFAuVWYoQy54Qi5OaihhLmEsMCxyKStDLnhCLnluKGIuYSxjKSxh
+LmIsYS5jLGEuZCxhLmUsYytvLHMrbyxhLngpfWM9Yi5hCmlmKHM8Yy5sZW5ndGgpe3I9YS5yCnJldHVy
+biBuZXcgUC5VZihDLnhCLk5qKGEuYSwwLHIpK0MueEIueW4oYyxzKSxhLmIsYS5jLGEuZCxhLmUsYS5m
+LHMrKHItcyksYS54KX1yZXR1cm4gYS5OOSgpfXM9Yi5hCmlmKEMueEIuUWkocywiLyIsbikpe209YS5l
+Cmw9UC5SeCh0aGlzKQprPWw+MD9sOm0Kbz1rLW4KcmV0dXJuIG5ldyBQLlVmKEMueEIuTmooYS5hLDAs
+aykrQy54Qi55bihzLG4pLGEuYixhLmMsYS5kLG0sYytvLGIucitvLGEueCl9aj1hLmUKaT1hLmYKaWYo
+aj09PWkmJmEuYz4wKXtmb3IoO0MueEIuUWkocywiLi4vIixuKTspbis9MwpvPWotbisxCnJldHVybiBu
+ZXcgUC5VZihDLnhCLk5qKGEuYSwwLGopKyIvIitDLnhCLnluKHMsbiksYS5iLGEuYyxhLmQsaixjK28s
+Yi5yK28sYS54KX1oPWEuYQpsPVAuUngodGhpcykKaWYobD49MClnPWwKZWxzZSBmb3IoZz1qO0MueEIu
+UWkoaCwiLi4vIixnKTspZys9MwpmPTAKd2hpbGUoITApe2U9biszCmlmKCEoZTw9YyYmQy54Qi5RaShz
+LCIuLi8iLG4pKSlicmVhazsrK2YKbj1lfWZvcihkPSIiO2k+Zzspey0taQppZihDLnhCLk8oaCxpKT09
+PTQ3KXtpZihmPT09MCl7ZD0iLyIKYnJlYWt9LS1mCmQ9Ii8ifX1pZihpPT09ZyYmYS5iPD0wJiYhQy54
+Qi5RaShoLCIvIixqKSl7bi09ZiozCmQ9IiJ9bz1pLW4rZC5sZW5ndGgKcmV0dXJuIG5ldyBQLlVmKEMu
+eEIuTmooaCwwLGkpK2QrQy54Qi55bihzLG4pLGEuYixhLmMsYS5kLGosYytvLGIucitvLGEueCl9LAp0
+NDpmdW5jdGlvbigpe3ZhciBzLHIscT10aGlzLHA9cS5iCmlmKHA+PTApe3M9IShwPT09NCYmQy54Qi5u
+QyhxLmEsImZpbGUiKSkKcD1zfWVsc2UgcD0hMQppZihwKXRocm93IEguYihQLkw0KCJDYW5ub3QgZXh0
+cmFjdCBhIGZpbGUgcGF0aCBmcm9tIGEgIitxLmdGaSgpKyIgVVJJIikpCnA9cS5mCnM9cS5hCmlmKHA8
+cy5sZW5ndGgpe2lmKHA8cS5yKXRocm93IEguYihQLkw0KHUuaSkpCnRocm93IEguYihQLkw0KHUubCkp
+fXI9JC53USgpCmlmKEgub1QocikpcD1QLm1uKHEpCmVsc2V7aWYocS5jPHEuZClILnYoUC5MNCh1Lmop
+KQpwPUMueEIuTmoocyxxLmUscCl9cmV0dXJuIHB9LApnaU86ZnVuY3Rpb24oYSl7dmFyIHM9dGhpcy55
 CnJldHVybiBzPT1udWxsP3RoaXMueT1DLnhCLmdpTyh0aGlzLmEpOnN9LApETjpmdW5jdGlvbihhLGIp
 e2lmKGI9PW51bGwpcmV0dXJuITEKaWYodGhpcz09PWIpcmV0dXJuITAKcmV0dXJuIHQuZEQuYihiKSYm
-dGhpcy5hPT09Yi53KDApfSwKdnM6ZnVuY3Rpb24oKXt2YXIgcz10aGlzLHI9bnVsbCxxPXMuZ0ZpKCks
+dGhpcy5hPT09Yi53KDApfSwKUmU6ZnVuY3Rpb24oKXt2YXIgcz10aGlzLHI9bnVsbCxxPXMuZ0ZpKCks
 cD1zLmdrdSgpLG89cy5jPjA/cy5nSmYocyk6cixuPXMuZ3hBKCk/cy5ndHAocyk6cixtPXMuYSxsPXMu
 ZixrPUMueEIuTmoobSxzLmUsbCksaj1zLnIKbD1sPGo/cy5ndFAoKTpyCnJldHVybiBQLkNnKHEscCxv
 LG4sayxsLGo8bS5sZW5ndGg/cy5nS2EoKTpyKX0sCnc6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYX0s
@@ -10656,1173 +10682,1176 @@
 aXMuT1UoYiksYyl9LApLOmZ1bmN0aW9uKGEsYil7dGhpcy5hLksoMCxuZXcgVy5LUyh0aGlzLHQuZUEu
 YShiKSkpfSwKZ3ZjOmZ1bmN0aW9uKCl7dmFyIHM9SC5WTShbXSx0LnMpCnRoaXMuYS5LKDAsbmV3IFcu
 QTModGhpcyxzKSkKcmV0dXJuIHN9LApnQTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5ndmMoKS5sZW5n
-dGh9LApnbDA6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuZ3ZjKCkubGVuZ3RoPT09MH0sCnhxOmZ1bmN0
-aW9uKGEpe3ZhciBzLHIscT1ILlZNKGEuc3BsaXQoIi0iKSx0LnMpCmZvcihzPTE7czxxLmxlbmd0aDsr
-K3Mpe3I9cVtzXQppZihyLmxlbmd0aD4wKUMuTm0uWTUocSxzLHJbMF0udG9VcHBlckNhc2UoKStKLktW
-KHIsMSkpfXJldHVybiBDLk5tLmsocSwiIil9LApPVTpmdW5jdGlvbihhKXt2YXIgcyxyLHEscCxvCmZv
-cihzPWEubGVuZ3RoLHI9MCxxPSIiO3I8czsrK3Ipe3A9YVtyXQpvPXAudG9Mb3dlckNhc2UoKQpxPShw
-IT09byYmcj4wP3ErIi0iOnEpK299cmV0dXJuIHEuY2hhckNvZGVBdCgwKT09MD9xOnF9fQpXLktTLnBy
-b3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7aWYoSi5yWShhKS5uKGEsImRhdGEtIikpdGhpcy5iLiQy
-KHRoaXMuYS54cShDLnhCLnluKGEsNSkpLGIpfSwKJFM6MTV9ClcuQTMucHJvdG90eXBlPXsKJDI6ZnVu
-Y3Rpb24oYSxiKXtpZihKLnJZKGEpLm4oYSwiZGF0YS0iKSlDLk5tLmkodGhpcy5iLHRoaXMuYS54cShD
-LnhCLnluKGEsNSkpKX0sCiRTOjE1fQpXLkk0LnByb3RvdHlwZT17CkQ6ZnVuY3Rpb24oKXt2YXIgcyxy
-LHEscCxvPVAuTHModC5OKQpmb3Iocz10aGlzLmEuY2xhc3NOYW1lLnNwbGl0KCIgIikscj1zLmxlbmd0
-aCxxPTA7cTxyOysrcSl7cD1KLlQwKHNbcV0pCmlmKHAubGVuZ3RoIT09MClvLmkoMCxwKX1yZXR1cm4g
-b30sClg6ZnVuY3Rpb24oYSl7dGhpcy5hLmNsYXNzTmFtZT10LkMuYShhKS5rKDAsIiAiKX0sCmdBOmZ1
-bmN0aW9uKGEpe3JldHVybiB0aGlzLmEuY2xhc3NMaXN0Lmxlbmd0aH0sCmdsMDpmdW5jdGlvbihhKXty
-ZXR1cm4gdGhpcy5hLmNsYXNzTGlzdC5sZW5ndGg9PT0wfSwKZ29yOmZ1bmN0aW9uKGEpe3JldHVybiB0
-aGlzLmEuY2xhc3NMaXN0Lmxlbmd0aCE9PTB9LApWMTpmdW5jdGlvbihhKXt0aGlzLmEuY2xhc3NOYW1l
-PSIifSwKdGc6ZnVuY3Rpb24oYSxiKXt2YXIgcz10aGlzLmEuY2xhc3NMaXN0LmNvbnRhaW5zKGIpCnJl
-dHVybiBzfSwKaTpmdW5jdGlvbihhLGIpe3ZhciBzLHIKSC5oKGIpCnM9dGhpcy5hLmNsYXNzTGlzdApy
-PXMuY29udGFpbnMoYikKcy5hZGQoYikKcmV0dXJuIXJ9LApSOmZ1bmN0aW9uKGEsYil7dmFyIHMscixx
-CmlmKHR5cGVvZiBiPT0ic3RyaW5nIil7cz10aGlzLmEuY2xhc3NMaXN0CnI9cy5jb250YWlucyhiKQpz
-LnJlbW92ZShiKQpxPXJ9ZWxzZSBxPSExCnJldHVybiBxfSwKRlY6ZnVuY3Rpb24oYSxiKXtXLlROKHRo
-aXMuYSx0LlEuYShiKSl9fQpXLkZrLnByb3RvdHlwZT17fQpXLlJPLnByb3RvdHlwZT17fQpXLmV1LnBy
-b3RvdHlwZT17fQpXLnhDLnByb3RvdHlwZT17fQpXLnZOLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEp
-e3JldHVybiB0aGlzLmEuJDEodC5CLmEoYSkpfSwKJFM6Mjd9ClcuSlEucHJvdG90eXBlPXsKQ1k6ZnVu
-Y3Rpb24oYSl7dmFyIHMKaWYoJC5vci5hPT09MCl7Zm9yKHM9MDtzPDI2MjsrK3MpJC5vci5ZNSgwLEMu
-Y21bc10sVy5wUygpKQpmb3Iocz0wO3M8MTI7KytzKSQub3IuWTUoMCxDLkJJW3NdLFcuVjQoKSl9fSwK
-aTA6ZnVuY3Rpb24oYSl7cmV0dXJuICQuQU4oKS50ZygwLFcuclMoYSkpfSwKRWI6ZnVuY3Rpb24oYSxi
-LGMpe3ZhciBzPSQub3IucSgwLEguRWooVy5yUyhhKSkrIjo6IitiKQppZihzPT1udWxsKXM9JC5vci5x
-KDAsIio6OiIrYikKaWYocz09bnVsbClyZXR1cm4hMQpyZXR1cm4gSC55OChzLiQ0KGEsYixjLHRoaXMp
-KX0sCiRpa0Y6MX0KVy5HbS5wcm90b3R5cGU9ewpnbTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFcuVzko
-YSx0aGlzLmdBKGEpLEgueihhKS5DKCJXOTxHbS5FPiIpKX19ClcudkQucHJvdG90eXBlPXsKaTA6ZnVu
-Y3Rpb24oYSl7cmV0dXJuIEMuTm0uVnIodGhpcy5hLG5ldyBXLlV2KGEpKX0sCkViOmZ1bmN0aW9uKGEs
-YixjKXtyZXR1cm4gQy5ObS5Wcih0aGlzLmEsbmV3IFcuRWcoYSxiLGMpKX0sCiRpa0Y6MX0KVy5Vdi5w
-cm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gdC5FLmEoYSkuaTAodGhpcy5hKX0sCiRTOjE2
-fQpXLkVnLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiB0LkUuYShhKS5FYih0aGlzLmEs
-dGhpcy5iLHRoaXMuYyl9LAokUzoxNn0KVy5tNi5wcm90b3R5cGU9ewpDWTpmdW5jdGlvbihhLGIsYyxk
-KXt2YXIgcyxyLHEKdGhpcy5hLkZWKDAsYykKcz1iLmV2KDAsbmV3IFcuRW8oKSkKcj1iLmV2KDAsbmV3
-IFcuV2soKSkKdGhpcy5iLkZWKDAscykKcT10aGlzLmMKcS5GVigwLEMueEQpCnEuRlYoMCxyKX0sCmkw
-OmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmEudGcoMCxXLnJTKGEpKX0sCkViOmZ1bmN0aW9uKGEsYixj
-KXt2YXIgcz10aGlzLHI9Vy5yUyhhKSxxPXMuYwppZihxLnRnKDAsSC5FaihyKSsiOjoiK2IpKXJldHVy
-biBzLmQuRHQoYykKZWxzZSBpZihxLnRnKDAsIio6OiIrYikpcmV0dXJuIHMuZC5EdChjKQplbHNle3E9
-cy5iCmlmKHEudGcoMCxILkVqKHIpKyI6OiIrYikpcmV0dXJuITAKZWxzZSBpZihxLnRnKDAsIio6OiIr
-YikpcmV0dXJuITAKZWxzZSBpZihxLnRnKDAsSC5FaihyKSsiOjoqIikpcmV0dXJuITAKZWxzZSBpZihx
-LnRnKDAsIio6OioiKSlyZXR1cm4hMH1yZXR1cm4hMX0sCiRpa0Y6MX0KVy5Fby5wcm90b3R5cGU9ewok
-MTpmdW5jdGlvbihhKXtyZXR1cm4hQy5ObS50ZyhDLkJJLEguaChhKSl9LAokUzo2fQpXLldrLnByb3Rv
-dHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiBDLk5tLnRnKEMuQkksSC5oKGEpKX0sCiRTOjZ9Clcu
-Y3QucHJvdG90eXBlPXsKRWI6ZnVuY3Rpb24oYSxiLGMpe2lmKHRoaXMuakYoYSxiLGMpKXJldHVybiEw
-CmlmKGI9PT0idGVtcGxhdGUiJiZjPT09IiIpcmV0dXJuITAKaWYoYS5nZXRBdHRyaWJ1dGUoInRlbXBs
-YXRlIik9PT0iIilyZXR1cm4gdGhpcy5lLnRnKDAsYikKcmV0dXJuITF9fQpXLklBLnByb3RvdHlwZT17
-CiQxOmZ1bmN0aW9uKGEpe3JldHVybiJURU1QTEFURTo6IitILkVqKEguaChhKSl9LAokUzo1fQpXLk93
-LnByb3RvdHlwZT17CmkwOmZ1bmN0aW9uKGEpe3ZhciBzCmlmKHQuZXcuYihhKSlyZXR1cm4hMQpzPXQu
-ZzcuYihhKQppZihzJiZXLnJTKGEpPT09ImZvcmVpZ25PYmplY3QiKXJldHVybiExCmlmKHMpcmV0dXJu
-ITAKcmV0dXJuITF9LApFYjpmdW5jdGlvbihhLGIsYyl7aWYoYj09PSJpcyJ8fEMueEIubihiLCJvbiIp
-KXJldHVybiExCnJldHVybiB0aGlzLmkwKGEpfSwKJGlrRjoxfQpXLlc5LnByb3RvdHlwZT17CkY6ZnVu
-Y3Rpb24oKXt2YXIgcz10aGlzLHI9cy5jKzEscT1zLmIKaWYocjxxKXtzLnNwKEoueDkocy5hLHIpKQpz
-LmM9cgpyZXR1cm4hMH1zLnNwKG51bGwpCnMuYz1xCnJldHVybiExfSwKZ2w6ZnVuY3Rpb24oKXtyZXR1
-cm4gdGhpcy5kfSwKc3A6ZnVuY3Rpb24oYSl7dGhpcy5kPXRoaXMuJHRpLkMoIjE/IikuYShhKX0sCiRp
-QW46MX0KVy5kVy5wcm90b3R5cGU9eyRpRDA6MSwkaXY2OjF9ClcubWsucHJvdG90eXBlPXskaXkwOjF9
-ClcuS28ucHJvdG90eXBlPXsKUG46ZnVuY3Rpb24oYSl7dmFyIHM9dGhpcyxyPW5ldyBXLmZtKHMpCnMu
-Yj0hMQpyLiQyKGEsbnVsbCkKZm9yKDtzLmI7KXtzLmI9ITEKci4kMihhLG51bGwpfX0sCkVQOmZ1bmN0
-aW9uKGEsYil7dmFyIHM9dGhpcy5iPSEwCmlmKGIhPW51bGw/YiE9PWEucGFyZW50Tm9kZTpzKUouTHQo
-YSkKZWxzZSBiLnJlbW92ZUNoaWxkKGEpfSwKSTQ6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEscCxvLG49
-ITAsbT1udWxsLGw9bnVsbAp0cnl7bT1KLmlnKGEpCmw9bS5hLmdldEF0dHJpYnV0ZSgiaXMiKQp0Lmgu
-YShhKQpzPWZ1bmN0aW9uKGMpe2lmKCEoYy5hdHRyaWJ1dGVzIGluc3RhbmNlb2YgTmFtZWROb2RlTWFw
-KSlyZXR1cm4gdHJ1ZQppZihjLmlkPT0nbGFzdENoaWxkJ3x8Yy5uYW1lPT0nbGFzdENoaWxkJ3x8Yy5p
-ZD09J3ByZXZpb3VzU2libGluZyd8fGMubmFtZT09J3ByZXZpb3VzU2libGluZyd8fGMuaWQ9PSdjaGls
-ZHJlbid8fGMubmFtZT09J2NoaWxkcmVuJylyZXR1cm4gdHJ1ZQp2YXIgaz1jLmNoaWxkTm9kZXMKaWYo
-Yy5sYXN0Q2hpbGQmJmMubGFzdENoaWxkIT09a1trLmxlbmd0aC0xXSlyZXR1cm4gdHJ1ZQppZihjLmNo
-aWxkcmVuKWlmKCEoYy5jaGlsZHJlbiBpbnN0YW5jZW9mIEhUTUxDb2xsZWN0aW9ufHxjLmNoaWxkcmVu
-IGluc3RhbmNlb2YgTm9kZUxpc3QpKXJldHVybiB0cnVlCnZhciBqPTAKaWYoYy5jaGlsZHJlbilqPWMu
-Y2hpbGRyZW4ubGVuZ3RoCmZvcih2YXIgaT0wO2k8ajtpKyspe3ZhciBoPWMuY2hpbGRyZW5baV0KaWYo
-aC5pZD09J2F0dHJpYnV0ZXMnfHxoLm5hbWU9PSdhdHRyaWJ1dGVzJ3x8aC5pZD09J2xhc3RDaGlsZCd8
-fGgubmFtZT09J2xhc3RDaGlsZCd8fGguaWQ9PSdwcmV2aW91c1NpYmxpbmcnfHxoLm5hbWU9PSdwcmV2
-aW91c1NpYmxpbmcnfHxoLmlkPT0nY2hpbGRyZW4nfHxoLm5hbWU9PSdjaGlsZHJlbicpcmV0dXJuIHRy
-dWV9cmV0dXJuIGZhbHNlfShhKQpuPUgub1Qocyk/ITA6IShhLmF0dHJpYnV0ZXMgaW5zdGFuY2VvZiBO
-YW1lZE5vZGVNYXApfWNhdGNoKHApe0guUnUocCl9cj0iZWxlbWVudCB1bnByaW50YWJsZSIKdHJ5e3I9
-Si5qKGEpfWNhdGNoKHApe0guUnUocCl9dHJ5e3E9Vy5yUyhhKQp0aGlzLmtSKHQuaC5hKGEpLGIsbixy
-LHEsdC5mLmEobSksSC5rKGwpKX1jYXRjaChwKXtpZihILlJ1KHApIGluc3RhbmNlb2YgUC51KXRocm93
-IHAKZWxzZXt0aGlzLkVQKGEsYikKd2luZG93Cm89IlJlbW92aW5nIGNvcnJ1cHRlZCBlbGVtZW50ICIr
-SC5FaihyKQppZih0eXBlb2YgY29uc29sZSE9InVuZGVmaW5lZCIpd2luZG93LmNvbnNvbGUud2Fybihv
-KX19fSwKa1I6ZnVuY3Rpb24oYSxiLGMsZCxlLGYsZyl7dmFyIHMscixxLHAsbyxuLG09dGhpcwppZihj
-KXttLkVQKGEsYikKd2luZG93CnM9IlJlbW92aW5nIGVsZW1lbnQgZHVlIHRvIGNvcnJ1cHRlZCBhdHRy
-aWJ1dGVzIG9uIDwiK2QrIj4iCmlmKHR5cGVvZiBjb25zb2xlIT0idW5kZWZpbmVkIil3aW5kb3cuY29u
-c29sZS53YXJuKHMpCnJldHVybn1pZighbS5hLmkwKGEpKXttLkVQKGEsYikKd2luZG93CnM9IlJlbW92
-aW5nIGRpc2FsbG93ZWQgZWxlbWVudCA8IitILkVqKGUpKyI+IGZyb20gIitILkVqKGIpCmlmKHR5cGVv
-ZiBjb25zb2xlIT0idW5kZWZpbmVkIil3aW5kb3cuY29uc29sZS53YXJuKHMpCnJldHVybn1pZihnIT1u
-dWxsKWlmKCFtLmEuRWIoYSwiaXMiLGcpKXttLkVQKGEsYikKd2luZG93CnM9IlJlbW92aW5nIGRpc2Fs
-bG93ZWQgdHlwZSBleHRlbnNpb24gPCIrSC5FaihlKSsnIGlzPSInK2crJyI+JwppZih0eXBlb2YgY29u
-c29sZSE9InVuZGVmaW5lZCIpd2luZG93LmNvbnNvbGUud2FybihzKQpyZXR1cm59cz1mLmd2YygpCnI9
-SC5WTShzLnNsaWNlKDApLEgudDYocykpCmZvcihxPWYuZ3ZjKCkubGVuZ3RoLTEscz1mLmE7cT49MDst
-LXEpe2lmKHE+PXIubGVuZ3RoKXJldHVybiBILk9IKHIscSkKcD1yW3FdCm89bS5hCm49Si5jSChwKQpI
-LmgocCkKaWYoIW8uRWIoYSxuLHMuZ2V0QXR0cmlidXRlKHApKSl7d2luZG93Cm89IlJlbW92aW5nIGRp
-c2FsbG93ZWQgYXR0cmlidXRlIDwiK0guRWooZSkrIiAiK3ArJz0iJytILkVqKHMuZ2V0QXR0cmlidXRl
-KHApKSsnIj4nCmlmKHR5cGVvZiBjb25zb2xlIT0idW5kZWZpbmVkIil3aW5kb3cuY29uc29sZS53YXJu
-KG8pCnMucmVtb3ZlQXR0cmlidXRlKHApfX1pZih0LmFXLmIoYSkpe3M9YS5jb250ZW50CnMudG9TdHJp
-bmcKbS5QbihzKX19LAokaW9uOjF9ClcuZm0ucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt2YXIg
-cyxyLHEscCxvLG4sbT10aGlzLmEKc3dpdGNoKGEubm9kZVR5cGUpe2Nhc2UgMTptLkk0KGEsYikKYnJl
-YWsKY2FzZSA4OmNhc2UgMTE6Y2FzZSAzOmNhc2UgNDpicmVhawpkZWZhdWx0Om0uRVAoYSxiKX1zPWEu
-bGFzdENoaWxkCmZvcihxPXQuQTtudWxsIT1zOyl7cj1udWxsCnRyeXtyPXMucHJldmlvdXNTaWJsaW5n
-CmlmKHIhPW51bGwpe3A9ci5uZXh0U2libGluZwpvPXMKbz1wPT1udWxsP28hPW51bGw6cCE9PW8KcD1v
-fWVsc2UgcD0hMQppZihwKXtwPVAuUFYoIkNvcnJ1cHQgSFRNTCIpCnRocm93IEguYihwKX19Y2F0Y2go
-bil7SC5SdShuKQpwPXEuYShzKQptLmI9ITAKbz1wLnBhcmVudE5vZGUKbz1hPT1udWxsP28hPW51bGw6
-YSE9PW8KaWYobyl7bz1wLnBhcmVudE5vZGUKaWYobyE9bnVsbClvLnJlbW92ZUNoaWxkKHApfWVsc2Ug
-YS5yZW1vdmVDaGlsZChwKQpzPW51bGwKcj1hLmxhc3RDaGlsZH1pZihzIT1udWxsKXRoaXMuJDIocyxh
-KQpzPXJ9fSwKJFM6MzB9ClcuTGUucHJvdG90eXBlPXt9ClcuSzcucHJvdG90eXBlPXt9ClcuckIucHJv
-dG90eXBlPXt9ClcuWFcucHJvdG90eXBlPXt9Clcub2EucHJvdG90eXBlPXt9ClAuaUoucHJvdG90eXBl
-PXsKVkg6ZnVuY3Rpb24oYSl7dmFyIHMscj10aGlzLmEscT1yLmxlbmd0aApmb3Iocz0wO3M8cTsrK3Mp
-aWYocltzXT09PWEpcmV0dXJuIHMKQy5ObS5pKHIsYSkKQy5ObS5pKHRoaXMuYixudWxsKQpyZXR1cm4g
-cX0sClB2OmZ1bmN0aW9uKGEpe3ZhciBzLHIscSxwPXRoaXMsbz17fQppZihhPT1udWxsKXJldHVybiBh
-CmlmKEgubChhKSlyZXR1cm4gYQppZih0eXBlb2YgYT09Im51bWJlciIpcmV0dXJuIGEKaWYodHlwZW9m
-IGE9PSJzdHJpbmciKXJldHVybiBhCmlmKGEgaW5zdGFuY2VvZiBQLmlQKXJldHVybiBuZXcgRGF0ZShh
-LmEpCmlmKHQuZnYuYihhKSl0aHJvdyBILmIoUC5TWSgic3RydWN0dXJlZCBjbG9uZSBvZiBSZWdFeHAi
-KSkKaWYodC5jOC5iKGEpKXJldHVybiBhCmlmKHQudy5iKGEpKXJldHVybiBhCmlmKHQuSS5iKGEpKXJl
-dHVybiBhCnM9dC5kRS5iKGEpfHwhMQppZihzKXJldHVybiBhCmlmKHQuZi5iKGEpKXtyPXAuVkgoYSkK
-cz1wLmIKaWYocj49cy5sZW5ndGgpcmV0dXJuIEguT0gocyxyKQpxPW8uYT1zW3JdCmlmKHEhPW51bGwp
-cmV0dXJuIHEKcT17fQpvLmE9cQpDLk5tLlk1KHMscixxKQphLksoMCxuZXcgUC5qZyhvLHApKQpyZXR1
-cm4gby5hfWlmKHQuai5iKGEpKXtyPXAuVkgoYSkKbz1wLmIKaWYocj49by5sZW5ndGgpcmV0dXJuIEgu
-T0gobyxyKQpxPW9bcl0KaWYocSE9bnVsbClyZXR1cm4gcQpyZXR1cm4gcC5layhhLHIpfWlmKHQuZUgu
-YihhKSl7cj1wLlZIKGEpCnM9cC5iCmlmKHI+PXMubGVuZ3RoKXJldHVybiBILk9IKHMscikKcT1vLmI9
-c1tyXQppZihxIT1udWxsKXJldHVybiBxCnE9e30Kby5iPXEKQy5ObS5ZNShzLHIscSkKcC5pbShhLG5l
-dyBQLlRhKG8scCkpCnJldHVybiBvLmJ9dGhyb3cgSC5iKFAuU1koInN0cnVjdHVyZWQgY2xvbmUgb2Yg
-b3RoZXIgdHlwZSIpKX0sCmVrOmZ1bmN0aW9uKGEsYil7dmFyIHMscj1KLlU2KGEpLHE9ci5nQShhKSxw
-PW5ldyBBcnJheShxKQpDLk5tLlk1KHRoaXMuYixiLHApCmZvcihzPTA7czxxOysrcylDLk5tLlk1KHAs
-cyx0aGlzLlB2KHIucShhLHMpKSkKcmV0dXJuIHB9fQpQLmpnLnByb3RvdHlwZT17CiQyOmZ1bmN0aW9u
-KGEsYil7dGhpcy5hLmFbYV09dGhpcy5iLlB2KGIpfSwKJFM6MzF9ClAuVGEucHJvdG90eXBlPXsKJDI6
-ZnVuY3Rpb24oYSxiKXt0aGlzLmEuYlthXT10aGlzLmIuUHYoYil9LAokUzoxN30KUC5CZi5wcm90b3R5
-cGU9ewppbTpmdW5jdGlvbihhLGIpe3ZhciBzLHIscSxwCnQuYjguYShiKQpmb3Iocz1PYmplY3Qua2V5
-cyhhKSxyPXMubGVuZ3RoLHE9MDtxPHI7KytxKXtwPXNbcV0KYi4kMihwLGFbcF0pfX19ClAuQXMucHJv
-dG90eXBlPXsKVjpmdW5jdGlvbihhKXt2YXIgcwpILmgoYSkKcz0kLmhHKCkuYgppZih0eXBlb2YgYSE9
-InN0cmluZyIpSC52KEgudEwoYSkpCmlmKHMudGVzdChhKSlyZXR1cm4gYQp0aHJvdyBILmIoUC5MMyhh
-LCJ2YWx1ZSIsIk5vdCBhIHZhbGlkIGNsYXNzIHRva2VuIikpfSwKdzpmdW5jdGlvbihhKXtyZXR1cm4g
-dGhpcy5EKCkuaygwLCIgIil9LApnbTpmdW5jdGlvbihhKXt2YXIgcz10aGlzLkQoKQpyZXR1cm4gUC5y
-aihzLHMucixILkxoKHMpLmMpfSwKZ2wwOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLkQoKS5hPT09MH0s
-CmdvcjpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5EKCkuYSE9PTB9LApnQTpmdW5jdGlvbihhKXtyZXR1
-cm4gdGhpcy5EKCkuYX0sCnRnOmZ1bmN0aW9uKGEsYil7dGhpcy5WKGIpCnJldHVybiB0aGlzLkQoKS50
-ZygwLGIpfSwKaTpmdW5jdGlvbihhLGIpe3ZhciBzCkguaChiKQp0aGlzLlYoYikKcz10aGlzLk9TKG5l
-dyBQLkdFKGIpKQpyZXR1cm4gSC55OChzPT1udWxsPyExOnMpfSwKUjpmdW5jdGlvbihhLGIpe3ZhciBz
-LHIKaWYodHlwZW9mIGIhPSJzdHJpbmciKXJldHVybiExCnRoaXMuVihiKQpzPXRoaXMuRCgpCnI9cy5S
-KDAsYikKdGhpcy5YKHMpCnJldHVybiByfSwKRlY6ZnVuY3Rpb24oYSxiKXt0aGlzLk9TKG5ldyBQLk43
-KHRoaXMsdC5RLmEoYikpKX0sCmVSOmZ1bmN0aW9uKGEsYil7dmFyIHM9dGhpcy5EKCkKcmV0dXJuIEgu
-YksocyxiLEguTGgocykuQygibGYuRSIpKX0sCkU6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5EKCku
-RSgwLGIpfSwKVjE6ZnVuY3Rpb24oYSl7dGhpcy5PUyhuZXcgUC51USgpKX0sCk9TOmZ1bmN0aW9uKGEp
-e3ZhciBzLHIKdC5iVS5hKGEpCnM9dGhpcy5EKCkKcj1hLiQxKHMpCnRoaXMuWChzKQpyZXR1cm4gcn19
-ClAuR0UucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIHQuQy5hKGEpLmkoMCx0aGlzLmEp
-fSwKJFM6MzN9ClAuTjcucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHM9dGhpcy5iLHI9SC50
-NihzKQpyZXR1cm4gdC5DLmEoYSkuRlYoMCxuZXcgSC5sSihzLHIuQygicVUoMSkiKS5hKHRoaXMuYS5n
-dU0oKSksci5DKCJsSjwxLHFVPiIpKSl9LAokUzoxOH0KUC51US5wcm90b3R5cGU9ewokMTpmdW5jdGlv
-bihhKXt0LkMuYShhKQppZihhLmE+MCl7YS5iPWEuYz1hLmQ9YS5lPWEuZj1udWxsCmEuYT0wCmEuUygp
-fXJldHVybiBudWxsfSwKJFM6MTh9ClAuaEYucHJvdG90eXBlPXskaWhGOjF9ClAuUEMucHJvdG90eXBl
-PXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHMKdC5ZLmEoYSkKcz1mdW5jdGlvbihiLGMsZCl7cmV0dXJuIGZ1
-bmN0aW9uKCl7cmV0dXJuIGIoYyxkLHRoaXMsQXJyYXkucHJvdG90eXBlLnNsaWNlLmFwcGx5KGFyZ3Vt
-ZW50cykpfX0oUC5SNCxhLCExKQpQLkRtKHMsJC53KCksYSkKcmV0dXJuIHN9LAokUzo0fQpQLm10LnBy
-b3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgdGhpcy5hKGEpfSwKJFM6NH0KUC5RUy5w
-cm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFAucjcoYSl9LAokUzozNX0KUC5ucC5w
-cm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFAuVHooYSx0LmFtKX0sCiRTOjQ1fQpQ
-LlV0LnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgUC5FNChhKX0sCiRTOjM3fQpQ
-LkU0LnByb3RvdHlwZT17CnE6ZnVuY3Rpb24oYSxiKXtpZih0eXBlb2YgYiE9InN0cmluZyImJnR5cGVv
-ZiBiIT0ibnVtYmVyIil0aHJvdyBILmIoUC54WSgicHJvcGVydHkgaXMgbm90IGEgU3RyaW5nIG9yIG51
-bSIpKQpyZXR1cm4gUC5kVSh0aGlzLmFbYl0pfSwKWTU6ZnVuY3Rpb24oYSxiLGMpe2lmKHR5cGVvZiBi
-IT0ic3RyaW5nIiYmdHlwZW9mIGIhPSJudW1iZXIiKXRocm93IEguYihQLnhZKCJwcm9wZXJ0eSBpcyBu
-b3QgYSBTdHJpbmcgb3IgbnVtIikpCnRoaXMuYVtiXT1QLndZKGMpfSwKRE46ZnVuY3Rpb24oYSxiKXtp
-ZihiPT1udWxsKXJldHVybiExCnJldHVybiBiIGluc3RhbmNlb2YgUC5FNCYmdGhpcy5hPT09Yi5hfSwK
-dzpmdW5jdGlvbihhKXt2YXIgcyxyCnRyeXtzPVN0cmluZyh0aGlzLmEpCnJldHVybiBzfWNhdGNoKHIp
-e0guUnUocikKcz10aGlzLnhiKDApCnJldHVybiBzfX0sClY3OmZ1bmN0aW9uKGEsYil7dmFyIHMscj10
-aGlzLmEKaWYoYj09bnVsbClzPW51bGwKZWxzZXtzPUgudDYoYikKcz1QLkNIKG5ldyBILmxKKGIscy5D
-KCJAKDEpIikuYShQLmlHKCkpLHMuQygibEo8MSxAPiIpKSwhMCx0LnopfXJldHVybiBQLmRVKHJbYV0u
-YXBwbHkocixzKSl9LApnaU86ZnVuY3Rpb24oYSl7cmV0dXJuIDB9fQpQLnI3LnByb3RvdHlwZT17fQpQ
-LlR6LnByb3RvdHlwZT17CmNQOmZ1bmN0aW9uKGEpe3ZhciBzPXRoaXMscj1hPDB8fGE+PXMuZ0EocykK
-aWYocil0aHJvdyBILmIoUC5URShhLDAscy5nQShzKSxudWxsLG51bGwpKX0sCnE6ZnVuY3Rpb24oYSxi
-KXtpZihILm9rKGIpKXRoaXMuY1AoYikKcmV0dXJuIHRoaXMuJHRpLmMuYSh0aGlzLlVyKDAsYikpfSwK
-WTU6ZnVuY3Rpb24oYSxiLGMpe3RoaXMuY1AoYikKdGhpcy5iaCgwLGIsYyl9LApnQTpmdW5jdGlvbihh
-KXt2YXIgcz10aGlzLmEubGVuZ3RoCmlmKHR5cGVvZiBzPT09Im51bWJlciImJnM+Pj4wPT09cylyZXR1
-cm4gcwp0aHJvdyBILmIoUC5QVigiQmFkIEpzQXJyYXkgbGVuZ3RoIikpfSwKJGliUToxLAokaWNYOjEs
-CiRpek06MX0KUC5jby5wcm90b3R5cGU9ewpZNTpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIHRoaXMuZTQo
-MCxiLGMpfX0KUC5uZC5wcm90b3R5cGU9eyRpbmQ6MX0KUC5LZS5wcm90b3R5cGU9ewpEOmZ1bmN0aW9u
-KCl7dmFyIHMscixxLHAsbz10aGlzLmEuZ2V0QXR0cmlidXRlKCJjbGFzcyIpLG49UC5Mcyh0Lk4pCmlm
-KG89PW51bGwpcmV0dXJuIG4KZm9yKHM9by5zcGxpdCgiICIpLHI9cy5sZW5ndGgscT0wO3E8cjsrK3Ep
-e3A9Si5UMChzW3FdKQppZihwLmxlbmd0aCE9PTApbi5pKDAscCl9cmV0dXJuIG59LApYOmZ1bmN0aW9u
-KGEpe3RoaXMuYS5zZXRBdHRyaWJ1dGUoImNsYXNzIixhLmsoMCwiICIpKX19ClAuaGkucHJvdG90eXBl
-PXsKZ1A6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLktlKGEpfSwKc2hmOmZ1bmN0aW9uKGEsYil7dGhp
-cy5ZQyhhLGIpfSwKcjY6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHMscixxLHAsbyxuCmlmKGQ9PW51bGwp
-e3M9SC5WTShbXSx0LnYpCmQ9bmV3IFcudkQocykKQy5ObS5pKHMsVy5UdyhudWxsKSkKQy5ObS5pKHMs
-Vy5CbCgpKQpDLk5tLmkocyxuZXcgVy5PdygpKX1jPW5ldyBXLktvKGQpCnI9JzxzdmcgdmVyc2lvbj0i
-MS4xIj4nK0guRWooYikrIjwvc3ZnPiIKcz1kb2N1bWVudApxPXMuYm9keQpxLnRvU3RyaW5nCnA9Qy5S
-WS5BSChxLHIsYykKbz1zLmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKQpwLnRvU3RyaW5nCnM9bmV3IFcu
-ZTcocCkKbj1zLmdyOChzKQpmb3IoO3M9bi5maXJzdENoaWxkLHMhPW51bGw7KW8uYXBwZW5kQ2hpbGQo
-cykKcmV0dXJuIG99LApuejpmdW5jdGlvbihhLGIsYyxkLGUpe3Rocm93IEguYihQLkw0KCJDYW5ub3Qg
-aW52b2tlIGluc2VydEFkamFjZW50SHRtbCBvbiBTVkcuIikpfSwKZ1ZsOmZ1bmN0aW9uKGEpe3JldHVy
-biBuZXcgVy5ldShhLCJjbGljayIsITEsdC5rKX0sCiRpaGk6MX0KVS5kMi5wcm90b3R5cGU9ewpMdDpm
-dW5jdGlvbigpe3ZhciBzLHIscSxwLG89dGhpcyxuPXQuWCxtPXQuXyxsPVAuRmwobixtKSxrPW8uYQpp
-ZihrIT1udWxsKXtzPUguVk0oW10sdC5HKQpmb3Iocj1rLmxlbmd0aCxxPTA7cTxrLmxlbmd0aDtrLmxl
-bmd0aD09PXJ8fCgwLEgubGspKGspLCsrcSl7cD1rW3FdCnMucHVzaChQLkVGKFsiZGVzY3JpcHRpb24i
-LHAuYSwiaHJlZiIscC5iXSxuLG0pKX1sLlk1KDAsImVkaXRzIixzKX1sLlk1KDAsImV4cGxhbmF0aW9u
-IixvLmIpCmwuWTUoMCwibGluZSIsby5jKQpsLlk1KDAsImRpc3BsYXlQYXRoIixvLmQpCmwuWTUoMCwi
-dXJpUGF0aCIsby5lKQpuPW8uZgppZihuIT1udWxsKXttPUguVk0oW10sdC5HKQpmb3Ioaz1uLmxlbmd0
-aCxxPTA7cTxuLmxlbmd0aDtuLmxlbmd0aD09PWt8fCgwLEgubGspKG4pLCsrcSltLnB1c2gobltxXS5M
-dCgpKQpsLlk1KDAsInRyYWNlcyIsbSl9cmV0dXJuIGx9fQpVLlNlLnByb3RvdHlwZT17Ckx0OmZ1bmN0
-aW9uKCl7cmV0dXJuIFAuRUYoWyJkZXNjcmlwdGlvbiIsdGhpcy5hLCJocmVmIix0aGlzLmJdLHQuWCx0
-Ll8pfX0KVS5NbC5wcm90b3R5cGU9ewpMdDpmdW5jdGlvbigpe3JldHVybiBQLkVGKFsiaHJlZiIsdGhp
-cy5hLCJsaW5lIix0aGlzLmIsInBhdGgiLHRoaXMuY10sdC5YLHQuXyl9fQpVLnlELnByb3RvdHlwZT17
-Ckx0OmZ1bmN0aW9uKCl7dmFyIHMscixxLHA9SC5WTShbXSx0LkcpCmZvcihzPXRoaXMuYixyPXMubGVu
-Z3RoLHE9MDtxPHMubGVuZ3RoO3MubGVuZ3RoPT09cnx8KDAsSC5saykocyksKytxKXAucHVzaChzW3Fd
-Lkx0KCkpCnJldHVybiBQLkVGKFsiZGVzY3JpcHRpb24iLHRoaXMuYSwiZW50cmllcyIscF0sdC5YLHQu
-Xyl9fQpVLndiLnByb3RvdHlwZT17Ckx0OmZ1bmN0aW9uKCl7dmFyIHMscixxLHA9dGhpcyxvPVAuRmwo
-dC5YLHQuXykKby5ZNSgwLCJkZXNjcmlwdGlvbiIscC5hKQpzPXAuYgppZihzIT1udWxsKW8uWTUoMCwi
-ZnVuY3Rpb24iLHMpCnM9cC5jCmlmKHMhPW51bGwpby5ZNSgwLCJsaW5rIixzLkx0KCkpCnM9cC5kCmlm
-KHMubGVuZ3RoIT09MCl7cj1ILnQ2KHMpCnE9ci5DKCJsSjwxLFowPHFVKixNaCo+Kj4iKQpvLlk1KDAs
-ImhpbnRBY3Rpb25zIixQLlkxKG5ldyBILmxKKHMsci5DKCJaMDxxVSosTWgqPiooMSkiKS5hKG5ldyBV
-LmIwKCkpLHEpLCEwLHEuQygiYUwuRSIpKSl9cmV0dXJuIG99fQpVLmFOLnByb3RvdHlwZT17CiQxOmZ1
-bmN0aW9uKGEpe3JldHVybiBSLm56KHQudC5hKGEpKX0sCiRTOjM4fQpVLmIwLnByb3RvdHlwZT17CiQx
-OmZ1bmN0aW9uKGEpe3JldHVybiB0LmFYLmEoYSkuTHQoKX0sCiRTOjM5fQpCLmo4LnByb3RvdHlwZT17
-Ckx0OmZ1bmN0aW9uKCl7cmV0dXJuIFAuRUYoWyJsaW5lIix0aGlzLmEsImV4cGxhbmF0aW9uIix0aGlz
-LmIsIm9mZnNldCIsdGhpcy5jXSx0LlgsdC5fKX19CkIucXAucHJvdG90eXBlPXsKTHQ6ZnVuY3Rpb24o
-KXt2YXIgcyxyLHEscCxvLG4sbSxsPXRoaXMsaz10Llgsaj1QLkZsKGssdC5kcCkKZm9yKHM9bC5kLHM9
-cy5nUHUocykscz1zLmdtKHMpLHI9dC5fLHE9dC5HO3MuRigpOyl7cD1zLmdsKCkKbz1wLmEKbj1ILlZN
-KFtdLHEpCmZvcihwPUouSVQocC5iKTtwLkYoKTspe209cC5nbCgpCm4ucHVzaChQLkVGKFsibGluZSIs
-bS5hLCJleHBsYW5hdGlvbiIsbS5iLCJvZmZzZXQiLG0uY10sayxyKSl9ai5ZNSgwLG8sbil9cmV0dXJu
-IFAuRUYoWyJyZWdpb25zIixsLmEsIm5hdmlnYXRpb25Db250ZW50IixsLmIsInNvdXJjZUNvZGUiLGwu
-YywiZWRpdHMiLGpdLGsscil9fQpULm1RLnByb3RvdHlwZT17fQpMLmUucHJvdG90eXBlPXsKJDE6ZnVu
-Y3Rpb24oYSl7dmFyIHMscixxLHAsbyxuLG0KdC5hTC5hKGEpCnM9d2luZG93LmxvY2F0aW9uLnBhdGhu
-YW1lCnI9TC5HNih3aW5kb3cubG9jYXRpb24uaHJlZikKcT1MLmFLKHdpbmRvdy5sb2NhdGlvbi5ocmVm
-KQpMLkdlKCkKaWYocyE9PSIvIiYmcyE9PUouVDAoZG9jdW1lbnQucXVlcnlTZWxlY3RvcigiLnJvb3Qi
-KS50ZXh0Q29udGVudCkpTC5HNyhzLHIscSwhMCxuZXcgTC5WVyhzLHIscSkpCnA9ZG9jdW1lbnQKbz1K
-LnFGKHAucXVlcnlTZWxlY3RvcigiLmFwcGx5LW1pZ3JhdGlvbiIpKQpuPW8uJHRpCm09bi5DKCJ+KDEp
-PyIpLmEobmV3IEwub1ooKSkKdC5aLmEobnVsbCkKVy5KRShvLmEsby5iLG0sITEsbi5jKQpuPUoucUYo
-cC5xdWVyeVNlbGVjdG9yKCIucmVydW4tbWlncmF0aW9uIikpCm09bi4kdGkKVy5KRShuLmEsbi5iLG0u
-QygifigxKT8iKS5hKG5ldyBMLkhpKCkpLCExLG0uYykKbT1KLnFGKHAucXVlcnlTZWxlY3RvcigiLnJl
-cG9ydC1wcm9ibGVtIikpCm49bS4kdGkKVy5KRShtLmEsbS5iLG4uQygifigxKT8iKS5hKG5ldyBMLkJU
-KCkpLCExLG4uYykKcD1KLnFGKHAucXVlcnlTZWxlY3RvcigiLnBvcHVwLXBhbmUgLmNsb3NlIikpCm49
-cC4kdGkKVy5KRShwLmEscC5iLG4uQygifigxKT8iKS5hKG5ldyBMLlBZKCkpLCExLG4uYykKbj1KLnFG
-KCQuYzAoKSkKcD1uLiR0aQpXLkpFKG4uYSxuLmIscC5DKCJ+KDEpPyIpLmEobmV3IEwudTgoKSksITEs
-cC5jKX0sCiRTOjE5fQpMLlZXLnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7TC5Gcih0aGlzLmEsdGhp
-cy5iLHRoaXMuYyl9LAokUzoyfQpMLm9aLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciBzLHIs
-cSxwLG8KdC5PLmEoYSkKaWYoSC5vVChDLm9sLnVzKHdpbmRvdywiVGhpcyB3aWxsIGFwcGx5IHRoZSBj
-aGFuZ2VzIHlvdSd2ZSBwcmV2aWV3ZWQgdG8geW91ciB3b3JraW5nIGRpcmVjdG9yeS4gSXQgaXMgcmVj
-b21tZW5kZWQgeW91IGNvbW1pdCBhbnkgY2hhbmdlcyB5b3UgbWFkZSBiZWZvcmUgZG9pbmcgdGhpcy4i
-KSkpe3M9SC5WTShbXSx0LkcpCmZvcihyPSQuSVIscT1yLmxlbmd0aCxwPTA7cDxyLmxlbmd0aDtyLmxl
-bmd0aD09PXF8fCgwLEgubGspKHIpLCsrcClzLnB1c2gocltwXS5MdCgpKQpzPUwudHkoIi9hcHBseS1t
-aWdyYXRpb24iLFAuRUYoWyJuYXZpZ2F0aW9uVHJlZSIsc10sdC5YLHQuZHApKS5XNyhuZXcgTC5qcigp
-LHQuUCkKbz1uZXcgTC5xbCgpCnQuYjcuYShudWxsKQpyPXMuJHRpCnE9JC5YMwppZihxIT09Qy5OVSlv
-PVAuVkgobyxxKQpzLnhmKG5ldyBQLkZlKG5ldyBQLnZzKHEsciksMixudWxsLG8sci5DKCJAPDE+Iiku
-S3Eoci5jKS5DKCJGZTwxLDI+IikpKX19LAokUzoxfQpMLmpyLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9u
-KGEpe3ZhciBzCnQudC5hKGEpCnM9ZG9jdW1lbnQuYm9keQpzLmNsYXNzTGlzdC5yZW1vdmUoInByb3Bv
-c2VkIikKcy5jbGFzc0xpc3QuYWRkKCJhcHBsaWVkIil9LAokUzo0Mn0KTC5xbC5wcm90b3R5cGU9ewok
-MjpmdW5jdGlvbihhLGIpe0wuQzIoIkNvdWxkIG5vdCBhcHBseSBtaWdyYXRpb24iLGEsYil9LAokQzoi
-JDIiLAokUjoyLAokUzoxN30KTC5IaS5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gdGhp
-cy54bih0Lk8uYShhKSl9LAp4bjpmdW5jdGlvbihhKXt2YXIgcz0wLHI9UC5GWCh0LlApLHE9MSxwLG89
-W10sbixtLGwsayxqCnZhciAkYXN5bmMkJDE9UC5seihmdW5jdGlvbihiLGMpe2lmKGI9PT0xKXtwPWMK
-cz1xfXdoaWxlKHRydWUpc3dpdGNoKHMpe2Nhc2UgMDpxPTMKZG9jdW1lbnQuYm9keS5jbGFzc0xpc3Qu
-YWRkKCJyZXJ1bm5pbmciKQpzPTYKcmV0dXJuIFAualEoTC50eSgiL3JlcnVuLW1pZ3JhdGlvbiIsbnVs
-bCksJGFzeW5jJCQxKQpjYXNlIDY6bj1jCmlmKEgub1QoSC55OChKLng5KG4sInN1Y2Nlc3MiKSkpKXdp
-bmRvdy5sb2NhdGlvbi5yZWxvYWQoKQplbHNlIEwuSzAodC5lRS5hKEoueDkobiwiZXJyb3JzIikpKQpv
-LnB1c2goNSkKcz00CmJyZWFrCmNhc2UgMzpxPTIKaj1wCm09SC5SdShqKQpsPUgudHMoaikKTC5DMigi
-RmFpbGVkIHRvIHJlcnVuIG1pZ3JhdGlvbiIsbSxsKQpvLnB1c2goNSkKcz00CmJyZWFrCmNhc2UgMjpv
-PVsxXQpjYXNlIDQ6cT0xCmRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LnJlbW92ZSgicmVydW5uaW5nIikK
-cz1vLnBvcCgpCmJyZWFrCmNhc2UgNTpyZXR1cm4gUC55QyhudWxsLHIpCmNhc2UgMTpyZXR1cm4gUC5m
-MyhwLHIpfX0pCnJldHVybiBQLkRJKCRhc3luYyQkMSxyKX0sCiRTOjIwfQpMLkJULnByb3RvdHlwZT17
-CiQxOmZ1bmN0aW9uKGEpe3QuTy5hKGEpCkMub2wuUG8od2luZG93LFAuWGQoImh0dHBzIiwiZ2l0aHVi
-LmNvbSIsImRhcnQtbGFuZy9zZGsvaXNzdWVzL25ldyIsUC5FRihbInRpdGxlIiwiQ3VzdG9tZXItcmVw
-b3J0ZWQgaXNzdWUgd2l0aCBOTkJEIG1pZ3JhdGlvbiB0b29sIiwibGFiZWxzIix1LmQsImJvZHkiLCIj
-IyMjIFN0ZXBzIHRvIHJlcHJvZHVjZVxuXG4jIyMjIFdoYXQgZGlkIHlvdSBleHBlY3QgdG8gaGFwcGVu
-P1xuXG4jIyMjIFdoYXQgYWN0dWFsbHkgaGFwcGVuZWQ/XG5cbl9TY3JlZW5zaG90cyBhcmUgYXBwcmVj
-aWF0ZWRfXG5cbioqRGFydCBTREsgdmVyc2lvbioqOiAiK0guRWooZG9jdW1lbnQuZ2V0RWxlbWVudEJ5
-SWQoInNkay12ZXJzaW9uIikudGV4dENvbnRlbnQpKyJcblxuVGhhbmtzIGZvciBmaWxpbmchXG4iXSx0
-LlgsdC56KSkuZ25EKCksInJlcG9ydC1wcm9ibGVtIil9LAokUzoxfQpMLlBZLnByb3RvdHlwZT17CiQx
-OmZ1bmN0aW9uKGEpe3ZhciBzCnQuTy5hKGEpCnM9ZG9jdW1lbnQucXVlcnlTZWxlY3RvcigiLnBvcHVw
-LXBhbmUiKS5zdHlsZQpzLmRpc3BsYXk9Im5vbmUiCnJldHVybiJub25lIn0sCiRTOjQ0fQpMLnU4LnBy
-b3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciBzLHIscSxwCnQuTy5hKGEpCnM9JC5EOSgpLmlubmVy
-VGV4dApyPXQuZy5hKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5uYXYtcGFuZWwgW2RhdGEtbmFtZSo9
-IicrSC5FaihzKSsnIl0nKS5wYXJlbnROb2RlKQpxPXIucXVlcnlTZWxlY3RvcigiLnN0YXR1cy1pY29u
-IikKcD1MLm1IKCQuSVIscykKaWYocCBpbnN0YW5jZW9mIEwuY0QmJkgub1QocC54KSl7TC5PdChwKQpM
-LnhuKHEscCkKTC5BUihyLHApfX0sCiRTOjF9CkwuTC5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2
-YXIgcyxyLHEKdC5hTC5hKGEpCnM9d2luZG93LmxvY2F0aW9uLnBhdGhuYW1lCnI9TC5HNih3aW5kb3cu
-bG9jYXRpb24uaHJlZikKcT1MLmFLKHdpbmRvdy5sb2NhdGlvbi5ocmVmKQppZihzLmxlbmd0aD4xKUwu
-RzcocyxyLHEsITEsbnVsbCkKZWxzZXtMLkJFKHMsQi53UigpLCEwKQpMLkJYKCImbmJzcDsiLG51bGwp
-fX0sCiRTOjE5fQpMLld4LnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciBzLHIscSxwPSJjb2xs
-YXBzZWQiCnQuTy5hKGEpCnM9dGhpcy5hCnI9Si5ZRShzKQpxPXRoaXMuYgppZighci5nUChzKS50Zygw
-LHApKXtyLmdQKHMpLmkoMCxwKQpKLmRSKHEpLmkoMCxwKX1lbHNle3IuZ1AocykuUigwLHApCkouZFIo
-cSkuUigwLHApfX0sCiRTOjF9CkwuQU8ucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHM9Si5x
-Rih0LmcuYShhKSkscj1zLiR0aSxxPXIuQygifigxKT8iKS5hKG5ldyBMLmROKHRoaXMuYSkpCnQuWi5h
-KG51bGwpClcuSkUocy5hLHMuYixxLCExLHIuYyl9LAokUzozfQpMLmROLnByb3RvdHlwZT17CiQxOmZ1
-bmN0aW9uKGEpe3JldHVybiBMLnQyKHQuTy5hKGEpLHRoaXMuYSl9LAokUzo3fQpMLkhvLnByb3RvdHlw
-ZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciBzLHIscQp0LmcuYShhKQpzPUoucUYoYSkKcj1zLiR0aQpxPXIu
-QygifigxKT8iKS5hKG5ldyBMLnh6KGEsdGhpcy5hKSkKdC5aLmEobnVsbCkKVy5KRShzLmEscy5iLHEs
-ITEsci5jKX0sCiRTOjN9CkwueHoucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHMKdC5PLmEo
-YSkKcz10aGlzLmEKTC5oWCh0aGlzLmIsUC5RQShzLmdldEF0dHJpYnV0ZSgiZGF0YS0iK25ldyBXLlN5
-KG5ldyBXLmk3KHMpKS5PVSgib2Zmc2V0IikpLG51bGwpLFAuUUEocy5nZXRBdHRyaWJ1dGUoImRhdGEt
-IituZXcgVy5TeShuZXcgVy5pNyhzKSkuT1UoImxpbmUiKSksbnVsbCkpfSwKJFM6MX0KTC5JQy5wcm90
-b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgcz1KLnFGKHQuZy5hKGEpKSxyPXMuJHRpCnIuQygifigx
-KT8iKS5hKEwuaVMoKSkKdC5aLmEobnVsbCkKVy5KRShzLmEscy5iLEwuaVMoKSwhMSxyLmMpfSwKJFM6
-M30KTC5mQy5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt0LmVRLmEoYSkKdGhpcy5hLmFNKDAsdGhp
-cy5iKX0sCiRTOjQ3fQpMLm5ULnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7TC5Gcih0aGlzLmEsdGhp
-cy5iLHRoaXMuYyl9LAokUzoyfQpMLk5ZLnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7TC5Gcih0aGlz
-LmEsbnVsbCxudWxsKX0sCiRTOjJ9CkwudWUucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dC5hdy5h
-KGEpCnJldHVybiBILkVqKGEucSgwLCJzZXZlcml0eSIpKSsiIC0gIitILkVqKGEucSgwLCJtZXNzYWdl
-IikpKyIgYXQgIitILkVqKGEucSgwLCJsb2NhdGlvbiIpKSsiIC0gKCIrSC5FaihhLnEoMCwiY29kZSIp
-KSsiKSJ9LAokUzo0OH0KTC5lWC5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt0LmcuYShhKQokLnpC
-KCkudG9TdHJpbmcKdC5kSC5hKCQub3coKS5xKDAsImhsanMiKSkuVjcoImhpZ2hsaWdodEJsb2NrIixb
-YV0pfSwKJFM6M30KTC5FRS5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgcyxyCnQuTy5hKGEp
-LnByZXZlbnREZWZhdWx0KCkKcz10aGlzLmEKcj10aGlzLmIKTC5hZih3aW5kb3cubG9jYXRpb24ucGF0
-aG5hbWUscyxyLCEwLG5ldyBMLlFMKHMscikpCkwuaFgodGhpcy5jLHMscil9LAokUzoxfQpMLlFMLnBy
-b3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7TC5Gcih3aW5kb3cubG9jYXRpb24ucGF0aG5hbWUsdGhpcy5h
-LHRoaXMuYil9LAokUzoyfQpMLlZTLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciBzLHI9InNl
-bGVjdGVkLWZpbGUiCnQuZy5hKGEpCmEudG9TdHJpbmcKcz1KLllFKGEpCmlmKGEuZ2V0QXR0cmlidXRl
-KCJkYXRhLSIrbmV3IFcuU3kobmV3IFcuaTcoYSkpLk9VKCJuYW1lIikpPT09dGhpcy5hLmEpcy5nUChh
-KS5pKDAscikKZWxzZSBzLmdQKGEpLlIoMCxyKX0sCiRTOjN9CkwuVEQucHJvdG90eXBlPXsKJDE6ZnVu
-Y3Rpb24oYSl7dmFyIHMscgp0Lk8uYShhKQpzPXRoaXMuYQpzd2l0Y2gocy5nTCgpKXtjYXNlIEMuY3c6
-YnJlYWsKY2FzZSBDLldEOnMubkcoKQpicmVhawpjYXNlIEMuWGo6cy5jMigpCmJyZWFrCmNhc2UgQy5k
-YzpzLmMyKCkKYnJlYWt9cj10aGlzLmIKTC5obChyLHMpCkwueG4odGhpcy5jLHMpCkwuQVIocixzKX0s
-CiRTOjF9CkwuSWYucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHMKdC5PLmEoYSkKcz10aGlz
-LmEKTC5PdChzKQpMLnhuKHRoaXMuYixzKQpMLkFSKHRoaXMuYyxzKX0sCiRTOjF9CkwudEIucHJvdG90
-eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIEwudDIodC5PLmEoYSksITApfSwKJFM6N30KTC5tMi5w
-cm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5SSSh0Lk8uYShhKSl9LApSSTpmdW5j
-dGlvbihhKXt2YXIgcz0wLHI9UC5GWCh0LlApLHE9MSxwLG89W10sbj10aGlzLG0sbCxrLGosaSxoLGcs
-Zgp2YXIgJGFzeW5jJCQxPVAubHooZnVuY3Rpb24oYixjKXtpZihiPT09MSl7cD1jCnM9cX13aGlsZSh0
-cnVlKXN3aXRjaChzKXtjYXNlIDA6cT0zCmk9ZG9jdW1lbnQKbT1DLkNELnpRKGkucXVlcnlTZWxlY3Rv
-cigiLmNvbnRlbnQiKS5zY3JvbGxUb3ApCmg9dC5YCnM9NgpyZXR1cm4gUC5qUShMLnR5KEwuUTQoIi9h
-cHBseS1oaW50IixQLkZsKGgsaCkpLG4uYS5MdCgpKSwkYXN5bmMkJDEpCmNhc2UgNjpoPW4uYgpsPUwu
-VXMoaC5hKQpzPTcKcmV0dXJuIFAualEoTC5HNyhsLG51bGwsaC5iLCExLG51bGwpLCRhc3luYyQkMSkK
-Y2FzZSA3OmkuYm9keS5jbGFzc0xpc3QuYWRkKCJuZWVkcy1yZXJ1biIpCmk9aS5xdWVyeVNlbGVjdG9y
-KCIuY29udGVudCIpCmkudG9TdHJpbmcKaS5zY3JvbGxUb3A9Si5WdShtKQpxPTEKcz01CmJyZWFrCmNh
-c2UgMzpxPTIKZj1wCms9SC5SdShmKQpqPUgudHMoZikKTC5DMigiQ291bGQgbm90IGFwcGx5IGhpbnQi
-LGssaikKcz01CmJyZWFrCmNhc2UgMjpzPTEKYnJlYWsKY2FzZSA1OnJldHVybiBQLnlDKG51bGwscikK
-Y2FzZSAxOnJldHVybiBQLmYzKHAscil9fSkKcmV0dXJuIFAuREkoJGFzeW5jJCQxLHIpfSwKJFM6MjB9
-CkwuWEEucHJvdG90eXBlPXsKRWI6ZnVuY3Rpb24oYSxiLGMpe3JldHVybiEwfSwKaTA6ZnVuY3Rpb24o
-YSl7cmV0dXJuITB9LAokaWtGOjF9CkwudnQucHJvdG90eXBlPXsKZ0w6ZnVuY3Rpb24oKXt2YXIgcyxy
-LHEscCxvLG4sbSxsPXRoaXMuZAppZihsLmxlbmd0aD09PTApcmV0dXJuIEMuY3cKcz1DLk5tLmd0SChs
-KS5nTCgpCmZvcihyPWwubGVuZ3RoLHE9ITAscD0hMCxvPTA7bzxsLmxlbmd0aDtsLmxlbmd0aD09PXJ8
-fCgwLEgubGspKGwpLCsrbyl7bj1sW29dLmdMKCkKaWYobiE9cylzPW51bGwKbT1uIT09Qy5jdwppZiht
-JiZuIT09Qy5XRClxPSExCmlmKG0mJm4hPT1DLlhqKXA9ITF9aWYocyE9bnVsbClyZXR1cm4gcwppZihx
-KXJldHVybiBDLldECmlmKHApcmV0dXJuIEMuWGoKcmV0dXJuIEMuZGN9LApMVjpmdW5jdGlvbigpe3Zh
-ciBzLHIscT10aGlzLmQKaWYocSE9bnVsbClmb3Iocz1xLmxlbmd0aCxyPTA7cjxzOysrcilxW3JdLmI9
-dGhpc30sCmMyOmZ1bmN0aW9uKCl7dmFyIHMscixxLHAKZm9yKHM9dGhpcy5kLHI9cy5sZW5ndGgscT0w
-O3E8cy5sZW5ndGg7cy5sZW5ndGg9PT1yfHwoMCxILmxrKShzKSwrK3Epe3A9c1txXQppZihwIGluc3Rh
-bmNlb2YgTC52dClwLmMyKCkKZWxzZSBpZihwIGluc3RhbmNlb2YgTC5jRCYmSC5vVChwLngpJiZwLnI9
-PT1DLlhqKXAucj1DLldEfX0sCm5HOmZ1bmN0aW9uKCl7dmFyIHMscixxLHAKZm9yKHM9dGhpcy5kLHI9
-cy5sZW5ndGgscT0wO3E8cy5sZW5ndGg7cy5sZW5ndGg9PT1yfHwoMCxILmxrKShzKSwrK3Epe3A9c1tx
-XQppZihwIGluc3RhbmNlb2YgTC52dClwLm5HKCkKZWxzZSBpZihwIGluc3RhbmNlb2YgTC5jRCYmSC5v
-VChwLngpJiZwLnI9PT1DLldEKXAucj1DLlhqfX0sCkx0OmZ1bmN0aW9uKCl7dmFyIHMscj1QLkZsKHQu
-WCx0Ll8pCnIuWTUoMCwidHlwZSIsImRpcmVjdG9yeSIpCnIuWTUoMCwibmFtZSIsdGhpcy5hKQpyLlk1
-KDAsInN1YnRyZWUiLEwuVkQodGhpcy5kKSkKcz10aGlzLmMKaWYocyE9bnVsbClyLlk1KDAsInBhdGgi
-LHMpCnJldHVybiByfX0KTC5jRC5wcm90b3R5cGU9ewpMdDpmdW5jdGlvbigpe3ZhciBzLHI9dGhpcyxx
-PVAuRmwodC5YLHQuXykKcS5ZNSgwLCJ0eXBlIiwiZmlsZSIpCnEuWTUoMCwibmFtZSIsci5hKQpzPXIu
-YwppZihzIT1udWxsKXEuWTUoMCwicGF0aCIscykKcz1yLmQKaWYocyE9bnVsbClxLlk1KDAsImhyZWYi
-LHMpCnM9ci5lCmlmKHMhPW51bGwpcS5ZNSgwLCJlZGl0Q291bnQiLHMpCnM9ci5mCmlmKHMhPW51bGwp
-cS5ZNSgwLCJ3YXNFeHBsaWNpdGx5T3B0ZWRPdXQiLHMpCnM9ci5yCmlmKHMhPW51bGwpcS5ZNSgwLCJt
-aWdyYXRpb25TdGF0dXMiLHMuYSkKcz1yLngKaWYocyE9bnVsbClxLlk1KDAsIm1pZ3JhdGlvblN0YXR1
-c0NhbkJlQ2hhbmdlZCIscykKcmV0dXJuIHF9LApnTDpmdW5jdGlvbigpe3JldHVybiB0aGlzLnJ9fQpM
-LkQ4LnByb3RvdHlwZT17fQpMLk85LnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMu
-Yn19CkwuR2IucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5ifX0KUi5MTC5wcm90
-b3R5cGU9ewpMdDpmdW5jdGlvbigpe3JldHVybiBQLkVGKFsibm9kZUlkIix0aGlzLmIsImtpbmQiLHRo
-aXMuYS5hXSx0LlgsdC5fKX19ClIuTUQucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIHQu
-ZkUuYShhKS5hPT09dGhpcy5hLnEoMCwia2luZCIpfSwKJFM6NDl9ClIuSDcucHJvdG90eXBlPXsKdzpm
-dW5jdGlvbihhKXtyZXR1cm4gdGhpcy5ifX0KTS5sSS5wcm90b3R5cGU9ewpnbDpmdW5jdGlvbigpe3Zh
-ciBzPUQuYWIoKQpyZXR1cm4gc30sCldPOmZ1bmN0aW9uKGEsYil7dmFyIHMscixxPXQuZDQKTS5ZRigi
-YWJzb2x1dGUiLEguVk0oW2IsbnVsbCxudWxsLG51bGwsbnVsbCxudWxsLG51bGxdLHEpKQpzPXRoaXMu
-YQpzPXMuWXIoYik+MCYmIXMuaEsoYikKaWYocylyZXR1cm4gYgpyPUguVk0oW3RoaXMuZ2woKSxiLG51
-bGwsbnVsbCxudWxsLG51bGwsbnVsbCxudWxsXSxxKQpNLllGKCJqb2luIixyKQpyZXR1cm4gdGhpcy5J
-UChuZXcgSC51NihyLHQuZUopKX0sCnpmOmZ1bmN0aW9uKGEpe3ZhciBzLHIscT1YLkNMKGEsdGhpcy5h
-KQpxLkl4KCkKcz1xLmQKcj1zLmxlbmd0aAppZihyPT09MCl7cz1xLmIKcmV0dXJuIHM9PW51bGw/Ii4i
-OnN9aWYocj09PTEpe3M9cS5iCnJldHVybiBzPT1udWxsPyIuIjpzfWlmKDA+PXIpcmV0dXJuIEguT0go
-cywtMSkKcy5wb3AoKQpzPXEuZQppZigwPj1zLmxlbmd0aClyZXR1cm4gSC5PSChzLC0xKQpzLnBvcCgp
-CnEuSXgoKQpyZXR1cm4gcS53KDApfSwKSVA6ZnVuY3Rpb24oYSl7dmFyIHMscixxLHAsbyxuLG0sbCxr
-LGoKdC5RLmEoYSkKZm9yKHM9YS4kdGkscj1zLkMoImEyKGNYLkUpIikuYShuZXcgTS5xNygpKSxxPWEu
-Z20oYSkscz1uZXcgSC5TTyhxLHIscy5DKCJTTzxjWC5FPiIpKSxyPXRoaXMuYSxwPSExLG89ITEsbj0i
-IjtzLkYoKTspe209cS5nbCgpCmlmKHIuaEsobSkmJm8pe2w9WC5DTChtLHIpCms9bi5jaGFyQ29kZUF0
-KDApPT0wP246bgpuPUMueEIuTmooaywwLHIuU3AoaywhMCkpCmwuYj1uCmlmKHIuZHMobikpQy5ObS5Z
-NShsLmUsMCxyLmdtSSgpKQpuPWwudygwKX1lbHNlIGlmKHIuWXIobSk+MCl7bz0hci5oSyhtKQpuPUgu
-RWoobSl9ZWxzZXtqPW0ubGVuZ3RoCmlmKGohPT0wKXtpZigwPj1qKXJldHVybiBILk9IKG0sMCkKaj1y
-LlVkKG1bMF0pfWVsc2Ugaj0hMQppZighailpZihwKW4rPXIuZ21JKCkKbis9bX1wPXIuZHMobSl9cmV0
-dXJuIG4uY2hhckNvZGVBdCgwKT09MD9uOm59LApvNTpmdW5jdGlvbihhKXt2YXIgcwppZighdGhpcy55
-MyhhKSlyZXR1cm4gYQpzPVguQ0woYSx0aGlzLmEpCnMuclIoKQpyZXR1cm4gcy53KDApfSwKeTM6ZnVu
-Y3Rpb24oYSl7dmFyIHMscixxLHAsbyxuLG0sbCxrLGoKYS50b1N0cmluZwpzPXRoaXMuYQpyPXMuWXIo
-YSkKaWYociE9PTApe2lmKHM9PT0kLktrKCkpZm9yKHE9MDtxPHI7KytxKWlmKEMueEIuVyhhLHEpPT09
-NDcpcmV0dXJuITAKcD1yCm89NDd9ZWxzZXtwPTAKbz1udWxsfWZvcihuPW5ldyBILnFqKGEpLmEsbT1u
-Lmxlbmd0aCxxPXAsbD1udWxsO3E8bTsrK3EsbD1vLG89ayl7az1DLnhCLk8obixxKQppZihzLnI0KGsp
-KXtpZihzPT09JC5LaygpJiZrPT09NDcpcmV0dXJuITAKaWYobyE9bnVsbCYmcy5yNChvKSlyZXR1cm4h
-MAppZihvPT09NDYpaj1sPT1udWxsfHxsPT09NDZ8fHMucjQobCkKZWxzZSBqPSExCmlmKGopcmV0dXJu
-ITB9fWlmKG89PW51bGwpcmV0dXJuITAKaWYocy5yNChvKSlyZXR1cm4hMAppZihvPT09NDYpcz1sPT1u
-dWxsfHxzLnI0KGwpfHxsPT09NDYKZWxzZSBzPSExCmlmKHMpcmV0dXJuITAKcmV0dXJuITF9LApIUDpm
-dW5jdGlvbihhLGIpe3ZhciBzLHIscSxwLG8sbixtLGw9dGhpcyxrPSdVbmFibGUgdG8gZmluZCBhIHBh
-dGggdG8gIicKYj1sLldPKDAsYikKcz1sLmEKaWYocy5ZcihiKTw9MCYmcy5ZcihhKT4wKXJldHVybiBs
-Lm81KGEpCmlmKHMuWXIoYSk8PTB8fHMuaEsoYSkpYT1sLldPKDAsYSkKaWYocy5ZcihhKTw9MCYmcy5Z
-cihiKT4wKXRocm93IEguYihYLkk3KGsrSC5FaihhKSsnIiBmcm9tICInK0guRWooYikrJyIuJykpCnI9
-WC5DTChiLHMpCnIuclIoKQpxPVguQ0woYSxzKQpxLnJSKCkKcD1yLmQKbz1wLmxlbmd0aAppZihvIT09
-MCl7aWYoMD49bylyZXR1cm4gSC5PSChwLDApCnA9Si5STShwWzBdLCIuIil9ZWxzZSBwPSExCmlmKHAp
-cmV0dXJuIHEudygwKQpwPXIuYgpvPXEuYgppZihwIT1vKXA9cD09bnVsbHx8bz09bnVsbHx8IXMuTmMo
-cCxvKQplbHNlIHA9ITEKaWYocClyZXR1cm4gcS53KDApCndoaWxlKCEwKXtwPXIuZApvPXAubGVuZ3Ro
-CmlmKG8hPT0wKXtuPXEuZAptPW4ubGVuZ3RoCmlmKG0hPT0wKXtpZigwPj1vKXJldHVybiBILk9IKHAs
-MCkKcD1wWzBdCmlmKDA+PW0pcmV0dXJuIEguT0gobiwwKQpuPXMuTmMocCxuWzBdKQpwPW59ZWxzZSBw
-PSExfWVsc2UgcD0hMQppZighcClicmVhawpDLk5tLlc0KHIuZCwwKQpDLk5tLlc0KHIuZSwxKQpDLk5t
-Llc0KHEuZCwwKQpDLk5tLlc0KHEuZSwxKX1wPXIuZApvPXAubGVuZ3RoCmlmKG8hPT0wKXtpZigwPj1v
-KXJldHVybiBILk9IKHAsMCkKcD1KLlJNKHBbMF0sIi4uIil9ZWxzZSBwPSExCmlmKHApdGhyb3cgSC5i
-KFguSTcoaytILkVqKGEpKyciIGZyb20gIicrSC5FaihiKSsnIi4nKSkKcD10Lk4KQy5ObS5VRyhxLmQs
-MCxQLk84KHIuZC5sZW5ndGgsIi4uIiwhMSxwKSkKQy5ObS5ZNShxLmUsMCwiIikKQy5ObS5VRyhxLmUs
-MSxQLk84KHIuZC5sZW5ndGgscy5nbUkoKSwhMSxwKSkKcz1xLmQKcD1zLmxlbmd0aAppZihwPT09MCly
-ZXR1cm4iLiIKaWYocD4xJiZKLlJNKEMuTm0uZ3JaKHMpLCIuIikpe3M9cS5kCmlmKDA+PXMubGVuZ3Ro
-KXJldHVybiBILk9IKHMsLTEpCnMucG9wKCkKcz1xLmUKaWYoMD49cy5sZW5ndGgpcmV0dXJuIEguT0go
-cywtMSkKcy5wb3AoKQppZigwPj1zLmxlbmd0aClyZXR1cm4gSC5PSChzLC0xKQpzLnBvcCgpCkMuTm0u
-aShzLCIiKX1xLmI9IiIKcS5JeCgpCnJldHVybiBxLncoMCl9fQpNLnE3LnByb3RvdHlwZT17CiQxOmZ1
-bmN0aW9uKGEpe3JldHVybiBILmgoYSkhPT0iIn0sCiRTOjZ9Ck0uTm8ucHJvdG90eXBlPXsKJDE6ZnVu
-Y3Rpb24oYSl7SC5rKGEpCnJldHVybiBhPT1udWxsPyJudWxsIjonIicrYSsnIid9LAokUzo1MH0KQi5m
-di5wcm90b3R5cGU9ewp4WjpmdW5jdGlvbihhKXt2YXIgcyxyPXRoaXMuWXIoYSkKaWYocj4wKXJldHVy
-biBKLmxkKGEsMCxyKQppZih0aGlzLmhLKGEpKXtpZigwPj1hLmxlbmd0aClyZXR1cm4gSC5PSChhLDAp
-CnM9YVswXX1lbHNlIHM9bnVsbApyZXR1cm4gc30sCk5jOmZ1bmN0aW9uKGEsYil7cmV0dXJuIGE9PWJ9
-fQpYLldELnByb3RvdHlwZT17Ckl4OmZ1bmN0aW9uKCl7dmFyIHMscixxPXRoaXMKd2hpbGUoITApe3M9
-cS5kCmlmKCEocy5sZW5ndGghPT0wJiZKLlJNKEMuTm0uZ3JaKHMpLCIiKSkpYnJlYWsKcz1xLmQKaWYo
-MD49cy5sZW5ndGgpcmV0dXJuIEguT0gocywtMSkKcy5wb3AoKQpzPXEuZQppZigwPj1zLmxlbmd0aCly
-ZXR1cm4gSC5PSChzLC0xKQpzLnBvcCgpfXM9cS5lCnI9cy5sZW5ndGgKaWYociE9PTApQy5ObS5ZNShz
-LHItMSwiIil9LApyUjpmdW5jdGlvbigpe3ZhciBzLHIscSxwLG8sbixtPXRoaXMsbD1ILlZNKFtdLHQu
-cykKZm9yKHM9bS5kLHI9cy5sZW5ndGgscT0wLHA9MDtwPHMubGVuZ3RoO3MubGVuZ3RoPT09cnx8KDAs
-SC5saykocyksKytwKXtvPXNbcF0Kbj1KLmlhKG8pCmlmKCEobi5ETihvLCIuIil8fG4uRE4obywiIikp
-KWlmKG4uRE4obywiLi4iKSl7bj1sLmxlbmd0aAppZihuIT09MCl7aWYoMD49bilyZXR1cm4gSC5PSChs
-LC0xKQpsLnBvcCgpfWVsc2UgKytxfWVsc2UgQy5ObS5pKGwsbyl9aWYobS5iPT1udWxsKUMuTm0uVUco
-bCwwLFAuTzgocSwiLi4iLCExLHQuTikpCmlmKGwubGVuZ3RoPT09MCYmbS5iPT1udWxsKUMuTm0uaShs
-LCIuIikKbS5zbkoobCkKcz1tLmEKbS5zUGgoUC5POChsLmxlbmd0aCsxLHMuZ21JKCksITAsdC5OKSkK
-cj1tLmIKaWYocj09bnVsbHx8bC5sZW5ndGg9PT0wfHwhcy5kcyhyKSlDLk5tLlk1KG0uZSwwLCIiKQpy
-PW0uYgppZihyIT1udWxsJiZzPT09JC5LaygpKXtyLnRvU3RyaW5nCm0uYj1ILnlzKHIsIi8iLCJcXCIp
-fW0uSXgoKX0sCnc6ZnVuY3Rpb24oYSl7dmFyIHMscixxPXRoaXMscD1xLmIKcD1wIT1udWxsP3A6IiIK
-Zm9yKHM9MDtzPHEuZC5sZW5ndGg7KytzKXtyPXEuZQppZihzPj1yLmxlbmd0aClyZXR1cm4gSC5PSChy
-LHMpCnI9cCtILkVqKHJbc10pCnA9cS5kCmlmKHM+PXAubGVuZ3RoKXJldHVybiBILk9IKHAscykKcD1y
-K0guRWoocFtzXSl9cCs9SC5FaihDLk5tLmdyWihxLmUpKQpyZXR1cm4gcC5jaGFyQ29kZUF0KDApPT0w
-P3A6cH0sCnNuSjpmdW5jdGlvbihhKXt0aGlzLmQ9dC5ELmEoYSl9LApzUGg6ZnVuY3Rpb24oYSl7dGhp
-cy5lPXQuRC5hKGEpfX0KWC5kdi5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiJQYXRoRXhj
-ZXB0aW9uOiAiK3RoaXMuYX0sCiRpUno6MX0KTy56TC5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3Jl
-dHVybiB0aGlzLmdvYyh0aGlzKX19CkUuT0YucHJvdG90eXBlPXsKVWQ6ZnVuY3Rpb24oYSl7cmV0dXJu
-IEMueEIudGcoYSwiLyIpfSwKcjQ6ZnVuY3Rpb24oYSl7cmV0dXJuIGE9PT00N30sCmRzOmZ1bmN0aW9u
-KGEpe3ZhciBzPWEubGVuZ3RoCnJldHVybiBzIT09MCYmQy54Qi5PKGEscy0xKSE9PTQ3fSwKU3A6ZnVu
-Y3Rpb24oYSxiKXtpZihhLmxlbmd0aCE9PTAmJkMueEIuVyhhLDApPT09NDcpcmV0dXJuIDEKcmV0dXJu
-IDB9LApZcjpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5TcChhLCExKX0sCmhLOmZ1bmN0aW9uKGEpe3Jl
-dHVybiExfSwKZ29jOmZ1bmN0aW9uKCl7cmV0dXJuInBvc2l4In0sCmdtSTpmdW5jdGlvbigpe3JldHVy
-biIvIn19CkYucnUucHJvdG90eXBlPXsKVWQ6ZnVuY3Rpb24oYSl7cmV0dXJuIEMueEIudGcoYSwiLyIp
-fSwKcjQ6ZnVuY3Rpb24oYSl7cmV0dXJuIGE9PT00N30sCmRzOmZ1bmN0aW9uKGEpe3ZhciBzPWEubGVu
-Z3RoCmlmKHM9PT0wKXJldHVybiExCmlmKEMueEIuTyhhLHMtMSkhPT00NylyZXR1cm4hMApyZXR1cm4g
-Qy54Qi5UYyhhLCI6Ly8iKSYmdGhpcy5ZcihhKT09PXN9LApTcDpmdW5jdGlvbihhLGIpe3ZhciBzLHIs
-cSxwLG89YS5sZW5ndGgKaWYobz09PTApcmV0dXJuIDAKaWYoQy54Qi5XKGEsMCk9PT00NylyZXR1cm4g
-MQpmb3Iocz0wO3M8bzsrK3Mpe3I9Qy54Qi5XKGEscykKaWYocj09PTQ3KXJldHVybiAwCmlmKHI9PT01
-OCl7aWYocz09PTApcmV0dXJuIDAKcT1DLnhCLlhVKGEsIi8iLEMueEIuUWkoYSwiLy8iLHMrMSk/cysz
-OnMpCmlmKHE8PTApcmV0dXJuIG8KaWYoIWJ8fG88cSszKXJldHVybiBxCmlmKCFDLnhCLm4oYSwiZmls
-ZTovLyIpKXJldHVybiBxCmlmKCFCLll1KGEscSsxKSlyZXR1cm4gcQpwPXErMwpyZXR1cm4gbz09PXA/
-cDpxKzR9fXJldHVybiAwfSwKWXI6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuU3AoYSwhMSl9LApoSzpm
-dW5jdGlvbihhKXtyZXR1cm4gYS5sZW5ndGghPT0wJiZDLnhCLlcoYSwwKT09PTQ3fSwKZ29jOmZ1bmN0
-aW9uKCl7cmV0dXJuInVybCJ9LApnbUk6ZnVuY3Rpb24oKXtyZXR1cm4iLyJ9fQpMLklWLnByb3RvdHlw
-ZT17ClVkOmZ1bmN0aW9uKGEpe3JldHVybiBDLnhCLnRnKGEsIi8iKX0sCnI0OmZ1bmN0aW9uKGEpe3Jl
-dHVybiBhPT09NDd8fGE9PT05Mn0sCmRzOmZ1bmN0aW9uKGEpe3ZhciBzPWEubGVuZ3RoCmlmKHM9PT0w
-KXJldHVybiExCnM9Qy54Qi5PKGEscy0xKQpyZXR1cm4hKHM9PT00N3x8cz09PTkyKX0sClNwOmZ1bmN0
-aW9uKGEsYil7dmFyIHMscixxPWEubGVuZ3RoCmlmKHE9PT0wKXJldHVybiAwCnM9Qy54Qi5XKGEsMCkK
-aWYocz09PTQ3KXJldHVybiAxCmlmKHM9PT05Mil7aWYocTwyfHxDLnhCLlcoYSwxKSE9PTkyKXJldHVy
-biAxCnI9Qy54Qi5YVShhLCJcXCIsMikKaWYocj4wKXtyPUMueEIuWFUoYSwiXFwiLHIrMSkKaWYocj4w
-KXJldHVybiByfXJldHVybiBxfWlmKHE8MylyZXR1cm4gMAppZighQi5PUyhzKSlyZXR1cm4gMAppZihD
-LnhCLlcoYSwxKSE9PTU4KXJldHVybiAwCnE9Qy54Qi5XKGEsMikKaWYoIShxPT09NDd8fHE9PT05Mikp
-cmV0dXJuIDAKcmV0dXJuIDN9LApZcjpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5TcChhLCExKX0sCmhL
-OmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLllyKGEpPT09MX0sCk90OmZ1bmN0aW9uKGEsYil7dmFyIHMK
-aWYoYT09PWIpcmV0dXJuITAKaWYoYT09PTQ3KXJldHVybiBiPT09OTIKaWYoYT09PTkyKXJldHVybiBi
-PT09NDcKaWYoKGFeYikhPT0zMilyZXR1cm4hMQpzPWF8MzIKcmV0dXJuIHM+PTk3JiZzPD0xMjJ9LApO
-YzpmdW5jdGlvbihhLGIpe3ZhciBzLHIscQppZihhPT1iKXJldHVybiEwCnM9YS5sZW5ndGgKaWYocyE9
-PWIubGVuZ3RoKXJldHVybiExCmZvcihyPUouclkoYikscT0wO3E8czsrK3EpaWYoIXRoaXMuT3QoQy54
-Qi5XKGEscSksci5XKGIscSkpKXJldHVybiExCnJldHVybiEwfSwKZ29jOmZ1bmN0aW9uKCl7cmV0dXJu
-IndpbmRvd3MifSwKZ21JOmZ1bmN0aW9uKCl7cmV0dXJuIlxcIn19OyhmdW5jdGlvbiBhbGlhc2VzKCl7
-dmFyIHM9Si5Hdi5wcm90b3R5cGUKcy5VPXMudwpzLlNqPXMuZTcKcz1KLk1GLnByb3RvdHlwZQpzLnQ9
-cy53CnM9UC5jWC5wcm90b3R5cGUKcy5HRz1zLmV2CnM9UC5NaC5wcm90b3R5cGUKcy54Yj1zLncKcz1X
-LmN2LnByb3RvdHlwZQpzLkRXPXMucjYKcz1XLm02LnByb3RvdHlwZQpzLmpGPXMuRWIKcz1QLkU0LnBy
-b3RvdHlwZQpzLlVyPXMucQpzLmU0PXMuWTUKcz1QLmNvLnByb3RvdHlwZQpzLmJoPXMuWTV9KSgpOyhm
-dW5jdGlvbiBpbnN0YWxsVGVhck9mZnMoKXt2YXIgcz1odW5rSGVscGVycy5fc3RhdGljXzEscj1odW5r
-SGVscGVycy5fc3RhdGljXzAscT1odW5rSGVscGVycy5pbnN0YWxsSW5zdGFuY2VUZWFyT2ZmLHA9aHVu
-a0hlbHBlcnMuaW5zdGFsbFN0YXRpY1RlYXJPZmYsbz1odW5rSGVscGVycy5faW5zdGFuY2VfMXUKcyhQ
-LCJFWCIsIlpWIiw4KQpzKFAsInl0Iiwib0EiLDgpCnMoUCwicVciLCJCeiIsOCkKcihQLCJVSSIsImVO
-IiwwKQpxKFAuUGYucHJvdG90eXBlLCJnWUoiLDAsMSxudWxsLFsiJDIiLCIkMSJdLFsidzAiLCJwbSJd
-LDI2LDApCnMoUCwiQ3kiLCJOQyIsNCkKcyhQLCJQSCIsIk10Iiw1KQpwKFcsInBTIiw0LG51bGwsWyIk
-NCJdLFsicUQiXSw5LDApCnAoVywiVjQiLDQsbnVsbCxbIiQ0Il0sWyJRVyJdLDksMCkKbyhQLkFzLnBy
-b3RvdHlwZSwiZ3VNIiwiViIsNSkKcyhQLCJpRyIsIndZIiw1MykKcyhQLCJ3MCIsImRVIiwzNikKcyhM
-LCJpUyIsImk2Iiw3KX0pKCk7KGZ1bmN0aW9uIGluaGVyaXRhbmNlKCl7dmFyIHM9aHVua0hlbHBlcnMu
-bWl4aW4scj1odW5rSGVscGVycy5pbmhlcml0LHE9aHVua0hlbHBlcnMuaW5oZXJpdE1hbnkKcihQLk1o
-LG51bGwpCnEoUC5NaCxbSC5GSyxKLkd2LEoubTEsUC5jWCxILkU3LFAuWFMsUC5uWSxILmE3LFAuQW4s
-SC5GdSxILkpCLEguU1UsSC5SZSxILnd2LFAuUG4sSC5XVSxILkxJLEguVHAsSC5mOSxILnRlLEguYnEs
-SC5YTyxILmtyLFAuWWssSC52aCxILk42LEguVlIsSC5FSyxILlBiLEgudFEsSC5TZCxILkpjLEguRyxI
-LmxZLFAuVzMsUC5paCxQLkZ5LFAuR1YsUC5DdyxQLlBmLFAuRmUsUC52cyxQLk9NLFAucWgsUC5NTyxQ
-LmtULFAueEksUC5tMCxQLnBSLFAuYm4sUC5sbSxQLmxELFAuS1AsUC5sZixQLldZLFAuVWssUC5TaCxQ
-LlJ3LFAuYnosUC5pUCxQLms1LFAuS1ksUC5DRCxQLmFFLFAuTjMsUC5jOCxQLlpkLFAuUm4sUC5EbixQ
-LlBFLFAuVWYsVy5pZCxXLkZrLFcuSlEsVy5HbSxXLnZELFcubTYsVy5PdyxXLlc5LFcuZFcsVy5tayxX
-LktvLFAuaUosUC5FNCxVLmQyLFUuU2UsVS5NbCxVLnlELFUud2IsQi5qOCxCLnFwLFQubVEsTC5YQSxM
-LkQ4LEwuTzksTC5HYixSLkxMLFIuSDcsTS5sSSxPLnpMLFguV0QsWC5kdl0pCnEoSi5HdixbSi55RSxK
-LndlLEouTUYsSi5qZCxKLnFJLEouRHIsSC5FVCxXLkQwLFcuQXosVy5MZSxXLk5oLFcuYWUsVy5JQixX
-Lm43LFcuZWEsVy5icixXLlNnLFcudzcsVy5LNyxXLlhXLFAuaEZdKQpxKEouTUYsW0ouaUMsSi5rZCxK
-LmM1XSkKcihKLlBvLEouamQpCnEoSi5xSSxbSi5iVSxKLkZOXSkKcShQLmNYLFtILkJSLEguYlEsSC5p
-MSxILlU1LEguQU0sSC51NixILlhSLFAubVcsSC51bl0pCnEoSC5CUixbSC5aeSxILlFDXSkKcihILm9s
-LEguWnkpCnIoSC5VcSxILlFDKQpyKEgualYsSC5VcSkKcShQLlhTLFtILm4sSC5yMyxILkdNLFAuRXos
-SC5heixILnZWLEguRXEsUC5DNixILmtTLFAuVWQsUC5GLFAudSxQLm1wLFAudWIsUC5kcyxQLmxqLFAu
-VVYsUC5jXSkKcihQLnV5LFAublkpCnEoUC51eSxbSC53MixXLnd6LFcuZTddKQpyKEgucWosSC53MikK
-cShILmJRLFtILmFMLEguTUIsSC5pNV0pCnEoSC5hTCxbSC5uSCxILmxKLFAuaThdKQpyKEgueHksSC5p
-MSkKcShQLkFuLFtILk1ILEguU08sSC5VMV0pCnIoSC5kNSxILkFNKQpyKFAuUlUsUC5QbikKcihQLkdq
-LFAuUlUpCnIoSC5QRCxQLkdqKQpyKEguTFAsSC5XVSkKcShILlRwLFtILkNqLEgubGMsSC5kQyxILndO
-LEguVlgsUC50aCxQLmhhLFAuVnMsUC5GdCxQLnlILFAuV00sUC5TWCxQLkdzLFAuZGEsUC5vUSxQLnBW
-LFAuVTcsUC52cixQLnJ0LFAuS0YsUC5aTCxQLlJULFAualosUC5ycSxQLlJXLFAuQjUsUC51TyxQLnBL
-LFAuVnAsUC5PUixQLnJhLFAueVEsUC54cixQLk56LFAudGksUC5XRixQLm4xLFAuY1MsUC5WQyxQLkpU
-LFAuUlosUC5NRSxQLnk1LFAueUksUC5jNixQLnFkLFcuQ3YsVy5LUyxXLkEzLFcudk4sVy5VdixXLkVn
-LFcuRW8sVy5XayxXLklBLFcuZm0sUC5qZyxQLlRhLFAuR0UsUC5ONyxQLnVRLFAuUEMsUC5tdCxQLlFT
-LFAubnAsUC5VdCxVLmFOLFUuYjAsTC5lLEwuVlcsTC5vWixMLmpyLEwucWwsTC5IaSxMLkJULEwuUFks
-TC51OCxMLkwsTC5XeCxMLkFPLEwuZE4sTC5IbyxMLnh6LEwuSUMsTC5mQyxMLm5ULEwuTlksTC51ZSxM
-LmVYLEwuRUUsTC5RTCxMLlZTLEwuVEQsTC5JZixMLnRCLEwubTIsUi5NRCxNLnE3LE0uTm9dKQpyKEgu
-VzAsUC5FeikKcShILmxjLFtILnp4LEguclRdKQpyKEgua1ksUC5DNikKcihQLmlsLFAuWWspCnEoUC5p
-bCxbSC5ONSxQLnV3LFcuY2YsVy5TeV0pCnEoUC5tVyxbSC5LVyxQLnE0XSkKcihILkxaLEguRVQpCnEo
-SC5MWixbSC5SRyxILldCXSkKcihILlZQLEguUkcpCnIoSC5EZyxILlZQKQpyKEguWkcsSC5XQikKcihI
-LlBnLEguWkcpCnEoSC5QZyxbSC54aixILmRFLEguWkEsSC5kVCxILlBxLEguZUUsSC5WNl0pCnIoSC5p
-TSxILmtTKQpyKFAuWmYsUC5QZikKcihQLkppLFAubTApCnIoUC5YdixQLnBSKQpyKFAuYjYsUC5YdikK
-cihQLlZqLFAuV1kpCnEoUC5VayxbUC5DVixQLlppLFAuYnldKQpyKFAud0ksUC5rVCkKcShQLndJLFtQ
-LlU4LFAub2osUC5NeCxQLkUzLFAuR1ldKQpyKFAuSzgsUC5VZCkKcihQLnR1LFAuU2gpCnIoUC51NSxQ
-LlppKQpxKFAudSxbUC5iSixQLmVZXSkKcihQLnFlLFAuRG4pCnEoVy5EMCxbVy51SCxXLndhLFcuSzUs
-Vy5DbV0pCnEoVy51SCxbVy5jdixXLm54LFcuUUYsVy5DUV0pCnEoVy5jdixbVy5xRSxQLmhpXSkKcShX
-LnFFLFtXLkdoLFcuZlksVy5uQixXLlFQLFcuaDQsVy5TTixXLmxwLFcuVGIsVy5JdixXLldQLFcueVld
-KQpyKFcub0osVy5MZSkKcihXLmhILFcuQXopCnIoVy5WYixXLlFGKQpyKFcuZkosVy53YSkKcShXLmVh
-LFtXLnc2LFcuZXddKQpyKFcuQWosVy53NikKcihXLnJCLFcuSzcpCnIoVy5CSCxXLnJCKQpyKFcudzQs
-Vy5JQikKcihXLm9hLFcuWFcpCnIoVy5yaCxXLm9hKQpyKFcuaTcsVy5jZikKcihQLkFzLFAuVmopCnEo
-UC5BcyxbVy5JNCxQLktlXSkKcihXLlJPLFAucWgpCnIoVy5ldSxXLlJPKQpyKFcueEMsUC5NTykKcihX
-LmN0LFcubTYpCnIoUC5CZixQLmlKKQpxKFAuRTQsW1AucjcsUC5jb10pCnIoUC5UeixQLmNvKQpyKFAu
-bmQsUC5oaSkKcShMLkQ4LFtMLnZ0LEwuY0RdKQpyKEIuZnYsTy56TCkKcShCLmZ2LFtFLk9GLEYucnUs
-TC5JVl0pCnMoSC53MixILlJlKQpzKEguUUMsUC5sRCkKcyhILlJHLFAubEQpCnMoSC5WUCxILlNVKQpz
-KEguV0IsUC5sRCkKcyhILlpHLEguU1UpCnMoUC5uWSxQLmxEKQpzKFAuV1ksUC5sZikKcyhQLlJVLFAu
-S1ApCnMoUC5wUixQLmxmKQpzKFcuTGUsVy5pZCkKcyhXLks3LFAubEQpCnMoVy5yQixXLkdtKQpzKFcu
-WFcsUC5sRCkKcyhXLm9hLFcuR20pCnMoUC5jbyxQLmxEKX0pKCkKdmFyIHY9e3R5cGVVbml2ZXJzZTp7
-ZUM6bmV3IE1hcCgpLHRSOnt9LGVUOnt9LHRQVjp7fSxzRUE6W119LG1hbmdsZWRHbG9iYWxOYW1lczp7
-QjI6ImludCIsQ1A6ImRvdWJsZSIsWlo6Im51bSIscVU6IlN0cmluZyIsYTI6ImJvb2wiLGM4OiJOdWxs
-Iix6TToiTGlzdCJ9LG1hbmdsZWROYW1lczp7fSxnZXRUeXBlRnJvbU5hbWU6Z2V0R2xvYmFsRnJvbU5h
-bWUsbWV0YWRhdGE6W10sdHlwZXM6WyJ+KCkiLCJjOChBaiopIiwiYzgoKSIsImM4KGN2KikiLCJAKEAp
-IiwicVUocVUpIiwiYTIocVUpIiwifihBaiopIiwifih+KCkpIiwiYTIoY3YscVUscVUsSlEpIiwiYzgo
-QCkiLCJ+KE1oPyxNaD8pIiwiQCgpIiwifihxVSxAKSIsIn4objYscVUsQjIpIiwifihxVSxxVSkiLCJh
-MihrRikiLCJjOChALEApIiwifih4dTxxVT4pIiwiYzgoZWEqKSIsImI4PGM4PiooQWoqKSIsIn4ocVUs
-QjIpIiwifihxVSxxVT8pIiwibjYoQCxAKSIsIn4oQjIsQCkiLCJhMih1SCkiLCJ+KE1oW0d6P10pIiwi
-fihlYSkiLCJjOChNaCxHeikiLCJ2czxAPihAKSIsIn4odUgsdUg/KSIsIn4oQCxAKSIsIkAocVUpIiwi
-YTIoeHU8cVU+KSIsIkAoQCxxVSkiLCJyNyhAKSIsIk1oPyhAKSIsIkU0KEApIiwiTEwqKEApIiwiWjA8
-cVUqLE1oKj4qKExMKikiLCJ+KEdELEApIiwiWjA8cVUscVU+KFowPHFVLHFVPixxVSkiLCJjOChaMDxx
-VSosTWgqPiopIiwifihAKSIsInFVKihBaiopIiwiVHo8QD4oQCkiLCJ+KHFVW0BdKSIsImM4KGV3Kiki
-LCJxVSooWjA8QCxAPiopIiwiYTIqKEg3KikiLCJxVShxVT8pIiwiQjIoQjIsQjIpIiwiYzgofigpKSIs
-Ik1oPyhNaD8pIiwiYzgoQCxHeikiXSxpbnRlcmNlcHRvcnNCeVRhZzpudWxsLGxlYWZUYWdzOm51bGws
-YXJyYXlSdGk6dHlwZW9mIFN5bWJvbD09ImZ1bmN0aW9uIiYmdHlwZW9mIFN5bWJvbCgpPT0ic3ltYm9s
-Ij9TeW1ib2woIiR0aSIpOiIkdGkifQpILnhiKHYudHlwZVVuaXZlcnNlLEpTT04ucGFyc2UoJ3siaUMi
-OiJNRiIsImtkIjoiTUYiLCJjNSI6Ik1GIiwicngiOiJlYSIsImU1IjoiZWEiLCJZMCI6ImhpIiwidHAi
-OiJoaSIsIkc4IjoiZXciLCJNciI6InFFIiwiZUwiOiJxRSIsIkkwIjoidUgiLCJocyI6InVIIiwiWGci
-OiJRRiIsIm5yIjoiQWoiLCJ5NCI6Inc2IiwiYVAiOiJDbSIsInhjIjoibngiLCJrSiI6Im54IiwielUi
-OiJEZyIsImRmIjoiRVQiLCJ5RSI6eyJhMiI6W119LCJ3ZSI6eyJjOCI6W119LCJNRiI6eyJ2bSI6W10s
-IkVIIjpbXX0sImpkIjp7InpNIjpbIjEiXSwiYlEiOlsiMSJdLCJjWCI6WyIxIl19LCJQbyI6eyJqZCI6
-WyIxIl0sInpNIjpbIjEiXSwiYlEiOlsiMSJdLCJjWCI6WyIxIl19LCJtMSI6eyJBbiI6WyIxIl19LCJx
-SSI6eyJDUCI6W10sIlpaIjpbXX0sImJVIjp7IkNQIjpbXSwiQjIiOltdLCJaWiI6W119LCJGTiI6eyJD
-UCI6W10sIlpaIjpbXX0sIkRyIjp7InFVIjpbXSwidlgiOltdfSwiQlIiOnsiY1giOlsiMiJdfSwiRTci
-OnsiQW4iOlsiMiJdfSwiWnkiOnsiQlIiOlsiMSIsIjIiXSwiY1giOlsiMiJdLCJjWC5FIjoiMiJ9LCJv
-bCI6eyJaeSI6WyIxIiwiMiJdLCJCUiI6WyIxIiwiMiJdLCJiUSI6WyIyIl0sImNYIjpbIjIiXSwiY1gu
-RSI6IjIifSwiVXEiOnsibEQiOlsiMiJdLCJ6TSI6WyIyIl0sIkJSIjpbIjEiLCIyIl0sImJRIjpbIjIi
-XSwiY1giOlsiMiJdfSwialYiOnsiVXEiOlsiMSIsIjIiXSwibEQiOlsiMiJdLCJ6TSI6WyIyIl0sIkJS
-IjpbIjEiLCIyIl0sImJRIjpbIjIiXSwiY1giOlsiMiJdLCJsRC5FIjoiMiIsImNYLkUiOiIyIn0sIm4i
-OnsiWFMiOltdfSwicjMiOnsiWFMiOltdfSwicWoiOnsibEQiOlsiQjIiXSwiUmUiOlsiQjIiXSwiek0i
-OlsiQjIiXSwiYlEiOlsiQjIiXSwiY1giOlsiQjIiXSwibEQuRSI6IkIyIiwiUmUuRSI6IkIyIn0sIkdN
-Ijp7IlhTIjpbXX0sImJRIjp7ImNYIjpbIjEiXX0sImFMIjp7ImJRIjpbIjEiXSwiY1giOlsiMSJdfSwi
-bkgiOnsiYUwiOlsiMSJdLCJiUSI6WyIxIl0sImNYIjpbIjEiXSwiYUwuRSI6IjEiLCJjWC5FIjoiMSJ9
-LCJhNyI6eyJBbiI6WyIxIl19LCJpMSI6eyJjWCI6WyIyIl0sImNYLkUiOiIyIn0sInh5Ijp7ImkxIjpb
-IjEiLCIyIl0sImJRIjpbIjIiXSwiY1giOlsiMiJdLCJjWC5FIjoiMiJ9LCJNSCI6eyJBbiI6WyIyIl19
-LCJsSiI6eyJhTCI6WyIyIl0sImJRIjpbIjIiXSwiY1giOlsiMiJdLCJhTC5FIjoiMiIsImNYLkUiOiIy
-In0sIlU1Ijp7ImNYIjpbIjEiXSwiY1guRSI6IjEifSwiU08iOnsiQW4iOlsiMSJdfSwiQU0iOnsiY1gi
-OlsiMSJdLCJjWC5FIjoiMSJ9LCJkNSI6eyJBTSI6WyIxIl0sImJRIjpbIjEiXSwiY1giOlsiMSJdLCJj
-WC5FIjoiMSJ9LCJVMSI6eyJBbiI6WyIxIl19LCJNQiI6eyJiUSI6WyIxIl0sImNYIjpbIjEiXSwiY1gu
-RSI6IjEifSwiRnUiOnsiQW4iOlsiMSJdfSwidTYiOnsiY1giOlsiMSJdLCJjWC5FIjoiMSJ9LCJKQiI6
-eyJBbiI6WyIxIl19LCJ3MiI6eyJsRCI6WyIxIl0sIlJlIjpbIjEiXSwiek0iOlsiMSJdLCJiUSI6WyIx
-Il0sImNYIjpbIjEiXX0sInd2Ijp7IkdEIjpbXX0sIlBEIjp7IkdqIjpbIjEiLCIyIl0sIlJVIjpbIjEi
-LCIyIl0sIlBuIjpbIjEiLCIyIl0sIktQIjpbIjEiLCIyIl0sIlowIjpbIjEiLCIyIl19LCJXVSI6eyJa
-MCI6WyIxIiwiMiJdfSwiTFAiOnsiV1UiOlsiMSIsIjIiXSwiWjAiOlsiMSIsIjIiXX0sIlhSIjp7ImNY
-IjpbIjEiXSwiY1guRSI6IjEifSwiTEkiOnsidlEiOltdfSwiVzAiOnsiWFMiOltdfSwiYXoiOnsiWFMi
-OltdfSwidlYiOnsiWFMiOltdfSwidGUiOnsiUnoiOltdfSwiWE8iOnsiR3oiOltdfSwiVHAiOnsiRUgi
-OltdfSwibGMiOnsiRUgiOltdfSwiengiOnsiRUgiOltdfSwiclQiOnsiRUgiOltdfSwiRXEiOnsiWFMi
-OltdfSwia1kiOnsiWFMiOltdfSwiTjUiOnsiWWsiOlsiMSIsIjIiXSwiRm8iOlsiMSIsIjIiXSwiWjAi
-OlsiMSIsIjIiXSwiWWsuSyI6IjEiLCJZay5WIjoiMiJ9LCJpNSI6eyJiUSI6WyIxIl0sImNYIjpbIjEi
-XSwiY1guRSI6IjEifSwiTjYiOnsiQW4iOlsiMSJdfSwiVlIiOnsid0wiOltdLCJ2WCI6W119LCJFSyI6
-eyJpYiI6W10sIk9kIjpbXX0sIktXIjp7ImNYIjpbImliIl0sImNYLkUiOiJpYiJ9LCJQYiI6eyJBbiI6
-WyJpYiJdfSwidFEiOnsiT2QiOltdfSwidW4iOnsiY1giOlsiT2QiXSwiY1guRSI6Ik9kIn0sIlNkIjp7
-IkFuIjpbIk9kIl19LCJFVCI6eyJBUyI6W119LCJMWiI6eyJYaiI6WyIxIl0sIkVUIjpbXSwiQVMiOltd
-fSwiRGciOnsibEQiOlsiQ1AiXSwiWGoiOlsiQ1AiXSwiek0iOlsiQ1AiXSwiRVQiOltdLCJiUSI6WyJD
-UCJdLCJBUyI6W10sImNYIjpbIkNQIl0sIlNVIjpbIkNQIl0sImxELkUiOiJDUCJ9LCJQZyI6eyJsRCI6
-WyJCMiJdLCJYaiI6WyJCMiJdLCJ6TSI6WyJCMiJdLCJFVCI6W10sImJRIjpbIkIyIl0sIkFTIjpbXSwi
-Y1giOlsiQjIiXSwiU1UiOlsiQjIiXX0sInhqIjp7ImxEIjpbIkIyIl0sIlhqIjpbIkIyIl0sInpNIjpb
-IkIyIl0sIkVUIjpbXSwiYlEiOlsiQjIiXSwiQVMiOltdLCJjWCI6WyJCMiJdLCJTVSI6WyJCMiJdLCJs
-RC5FIjoiQjIifSwiZEUiOnsibEQiOlsiQjIiXSwiWGoiOlsiQjIiXSwiek0iOlsiQjIiXSwiRVQiOltd
-LCJiUSI6WyJCMiJdLCJBUyI6W10sImNYIjpbIkIyIl0sIlNVIjpbIkIyIl0sImxELkUiOiJCMiJ9LCJa
-QSI6eyJsRCI6WyJCMiJdLCJYaiI6WyJCMiJdLCJ6TSI6WyJCMiJdLCJFVCI6W10sImJRIjpbIkIyIl0s
-IkFTIjpbXSwiY1giOlsiQjIiXSwiU1UiOlsiQjIiXSwibEQuRSI6IkIyIn0sImRUIjp7ImxEIjpbIkIy
-Il0sIlhqIjpbIkIyIl0sInpNIjpbIkIyIl0sIkVUIjpbXSwiYlEiOlsiQjIiXSwiQVMiOltdLCJjWCI6
-WyJCMiJdLCJTVSI6WyJCMiJdLCJsRC5FIjoiQjIifSwiUHEiOnsibEQiOlsiQjIiXSwiWGoiOlsiQjIi
-XSwiek0iOlsiQjIiXSwiRVQiOltdLCJiUSI6WyJCMiJdLCJBUyI6W10sImNYIjpbIkIyIl0sIlNVIjpb
-IkIyIl0sImxELkUiOiJCMiJ9LCJlRSI6eyJsRCI6WyJCMiJdLCJYaiI6WyJCMiJdLCJ6TSI6WyJCMiJd
-LCJFVCI6W10sImJRIjpbIkIyIl0sIkFTIjpbXSwiY1giOlsiQjIiXSwiU1UiOlsiQjIiXSwibEQuRSI6
-IkIyIn0sIlY2Ijp7ImxEIjpbIkIyIl0sIm42IjpbXSwiWGoiOlsiQjIiXSwiek0iOlsiQjIiXSwiRVQi
-OltdLCJiUSI6WyJCMiJdLCJBUyI6W10sImNYIjpbIkIyIl0sIlNVIjpbIkIyIl0sImxELkUiOiJCMiJ9
-LCJrUyI6eyJYUyI6W119LCJpTSI6eyJYUyI6W119LCJHViI6eyJBbiI6WyIxIl19LCJxNCI6eyJjWCI6
-WyIxIl0sImNYLkUiOiIxIn0sIkN3Ijp7IlhTIjpbXX0sIlpmIjp7IlBmIjpbIjEiXX0sInZzIjp7ImI4
-IjpbIjEiXX0sIm0wIjp7IlFtIjpbXX0sIkppIjp7Im0wIjpbXSwiUW0iOltdfSwiYjYiOnsibGYiOlsi
-MSJdLCJ4dSI6WyIxIl0sImJRIjpbIjEiXSwiY1giOlsiMSJdLCJsZi5FIjoiMSJ9LCJsbSI6eyJBbiI6
-WyIxIl19LCJtVyI6eyJjWCI6WyIxIl19LCJ1eSI6eyJsRCI6WyIxIl0sInpNIjpbIjEiXSwiYlEiOlsi
-MSJdLCJjWCI6WyIxIl19LCJpbCI6eyJZayI6WyIxIiwiMiJdLCJaMCI6WyIxIiwiMiJdfSwiWWsiOnsi
-WjAiOlsiMSIsIjIiXX0sIlBuIjp7IlowIjpbIjEiLCIyIl19LCJHaiI6eyJSVSI6WyIxIiwiMiJdLCJQ
-biI6WyIxIiwiMiJdLCJLUCI6WyIxIiwiMiJdLCJaMCI6WyIxIiwiMiJdfSwiVmoiOnsibGYiOlsiMSJd
-LCJ4dSI6WyIxIl0sImJRIjpbIjEiXSwiY1giOlsiMSJdfSwiWHYiOnsibGYiOlsiMSJdLCJ4dSI6WyIx
-Il0sImJRIjpbIjEiXSwiY1giOlsiMSJdfSwidXciOnsiWWsiOlsicVUiLCJAIl0sIlowIjpbInFVIiwi
-QCJdLCJZay5LIjoicVUiLCJZay5WIjoiQCJ9LCJpOCI6eyJhTCI6WyJxVSJdLCJiUSI6WyJxVSJdLCJj
-WCI6WyJxVSJdLCJhTC5FIjoicVUiLCJjWC5FIjoicVUifSwiQ1YiOnsiVWsiOlsiek08QjI+IiwicVUi
-XSwiVWsuUyI6InpNPEIyPiJ9LCJVOCI6eyJ3SSI6WyJ6TTxCMj4iLCJxVSJdfSwiWmkiOnsiVWsiOlsi
-cVUiLCJ6TTxCMj4iXX0sIlVkIjp7IlhTIjpbXX0sIks4Ijp7IlhTIjpbXX0sImJ5Ijp7IlVrIjpbIk1o
-PyIsInFVIl0sIlVrLlMiOiJNaD8ifSwib2oiOnsid0kiOlsiTWg/IiwicVUiXX0sIk14Ijp7IndJIjpb
-InFVIiwiTWg/Il19LCJ1NSI6eyJVayI6WyJxVSIsInpNPEIyPiJdLCJVay5TIjoicVUifSwiRTMiOnsi
-d0kiOlsicVUiLCJ6TTxCMj4iXX0sIkdZIjp7IndJIjpbInpNPEIyPiIsInFVIl19LCJDUCI6eyJaWiI6
-W119LCJCMiI6eyJaWiI6W119LCJ6TSI6eyJiUSI6WyIxIl0sImNYIjpbIjEiXX0sImliIjp7Ik9kIjpb
-XX0sInh1Ijp7ImJRIjpbIjEiXSwiY1giOlsiMSJdfSwicVUiOnsidlgiOltdfSwiQzYiOnsiWFMiOltd
-fSwiRXoiOnsiWFMiOltdfSwiRiI6eyJYUyI6W119LCJ1Ijp7IlhTIjpbXX0sImJKIjp7IlhTIjpbXX0s
-ImVZIjp7IlhTIjpbXX0sIm1wIjp7IlhTIjpbXX0sInViIjp7IlhTIjpbXX0sImRzIjp7IlhTIjpbXX0s
-ImxqIjp7IlhTIjpbXX0sIlVWIjp7IlhTIjpbXX0sIms1Ijp7IlhTIjpbXX0sIktZIjp7IlhTIjpbXX0s
-ImMiOnsiWFMiOltdfSwiQ0QiOnsiUnoiOltdfSwiYUUiOnsiUnoiOltdfSwiWmQiOnsiR3oiOltdfSwi
-Um4iOnsiQkwiOltdfSwiRG4iOnsiaUQiOltdfSwiVWYiOnsiaUQiOltdfSwicWUiOnsiaUQiOltdfSwi
-cUUiOnsiY3YiOltdLCJ1SCI6W10sIkQwIjpbXX0sIkdoIjp7ImN2IjpbXSwidUgiOltdLCJEMCI6W119
-LCJmWSI6eyJjdiI6W10sInVIIjpbXSwiRDAiOltdfSwibkIiOnsiY3YiOltdLCJ1SCI6W10sIkQwIjpb
-XX0sIlFQIjp7ImN2IjpbXSwidUgiOltdLCJEMCI6W119LCJueCI6eyJ1SCI6W10sIkQwIjpbXX0sIlFG
-Ijp7InVIIjpbXSwiRDAiOltdfSwiSUIiOnsidG4iOlsiWloiXX0sInd6Ijp7ImxEIjpbIjEiXSwiek0i
-OlsiMSJdLCJiUSI6WyIxIl0sImNYIjpbIjEiXSwibEQuRSI6IjEifSwiY3YiOnsidUgiOltdLCJEMCI6
-W119LCJoSCI6eyJBeiI6W119LCJoNCI6eyJjdiI6W10sInVIIjpbXSwiRDAiOltdfSwiVmIiOnsidUgi
-OltdLCJEMCI6W119LCJmSiI6eyJEMCI6W119LCJ3YSI6eyJEMCI6W119LCJBaiI6eyJlYSI6W119LCJl
-NyI6eyJsRCI6WyJ1SCJdLCJ6TSI6WyJ1SCJdLCJiUSI6WyJ1SCJdLCJjWCI6WyJ1SCJdLCJsRC5FIjoi
-dUgifSwidUgiOnsiRDAiOltdfSwiQkgiOnsibEQiOlsidUgiXSwiR20iOlsidUgiXSwiek0iOlsidUgi
-XSwiWGoiOlsidUgiXSwiYlEiOlsidUgiXSwiY1giOlsidUgiXSwibEQuRSI6InVIIiwiR20uRSI6InVI
-In0sIlNOIjp7ImN2IjpbXSwidUgiOltdLCJEMCI6W119LCJldyI6eyJlYSI6W119LCJscCI6eyJjdiI6
-W10sInVIIjpbXSwiRDAiOltdfSwiVGIiOnsiY3YiOltdLCJ1SCI6W10sIkQwIjpbXX0sIkl2Ijp7ImN2
-IjpbXSwidUgiOltdLCJEMCI6W119LCJXUCI6eyJjdiI6W10sInVIIjpbXSwiRDAiOltdfSwieVkiOnsi
-Y3YiOltdLCJ1SCI6W10sIkQwIjpbXX0sInc2Ijp7ImVhIjpbXX0sIks1Ijp7InY2IjpbXSwiRDAiOltd
-fSwiQ20iOnsiRDAiOltdfSwiQ1EiOnsidUgiOltdLCJEMCI6W119LCJ3NCI6eyJ0biI6WyJaWiJdfSwi
-cmgiOnsibEQiOlsidUgiXSwiR20iOlsidUgiXSwiek0iOlsidUgiXSwiWGoiOlsidUgiXSwiYlEiOlsi
-dUgiXSwiY1giOlsidUgiXSwibEQuRSI6InVIIiwiR20uRSI6InVIIn0sImNmIjp7IllrIjpbInFVIiwi
-cVUiXSwiWjAiOlsicVUiLCJxVSJdfSwiaTciOnsiWWsiOlsicVUiLCJxVSJdLCJaMCI6WyJxVSIsInFV
-Il0sIllrLksiOiJxVSIsIllrLlYiOiJxVSJ9LCJTeSI6eyJZayI6WyJxVSIsInFVIl0sIlowIjpbInFV
-IiwicVUiXSwiWWsuSyI6InFVIiwiWWsuViI6InFVIn0sIkk0Ijp7ImxmIjpbInFVIl0sInh1IjpbInFV
-Il0sImJRIjpbInFVIl0sImNYIjpbInFVIl0sImxmLkUiOiJxVSJ9LCJSTyI6eyJxaCI6WyIxIl19LCJl
-dSI6eyJSTyI6WyIxIl0sInFoIjpbIjEiXX0sInhDIjp7Ik1PIjpbIjEiXX0sIkpRIjp7ImtGIjpbXX0s
-InZEIjp7ImtGIjpbXX0sIm02Ijp7ImtGIjpbXX0sImN0Ijp7ImtGIjpbXX0sIk93Ijp7ImtGIjpbXX0s
-Ilc5Ijp7IkFuIjpbIjEiXX0sImRXIjp7InY2IjpbXSwiRDAiOltdfSwibWsiOnsieTAiOltdfSwiS28i
-Onsib24iOltdfSwiQXMiOnsibGYiOlsicVUiXSwieHUiOlsicVUiXSwiYlEiOlsicVUiXSwiY1giOlsi
-cVUiXX0sInI3Ijp7IkU0IjpbXX0sIlR6Ijp7ImxEIjpbIjEiXSwiek0iOlsiMSJdLCJiUSI6WyIxIl0s
-IkU0IjpbXSwiY1giOlsiMSJdLCJsRC5FIjoiMSJ9LCJuZCI6eyJoaSI6W10sImN2IjpbXSwidUgiOltd
-LCJEMCI6W119LCJLZSI6eyJsZiI6WyJxVSJdLCJ4dSI6WyJxVSJdLCJiUSI6WyJxVSJdLCJjWCI6WyJx
-VSJdLCJsZi5FIjoicVUifSwiaGkiOnsiY3YiOltdLCJ1SCI6W10sIkQwIjpbXX0sIlhBIjp7ImtGIjpb
-XX0sInZ0Ijp7IkQ4IjpbXX0sImNEIjp7IkQ4IjpbXX0sImR2Ijp7IlJ6IjpbXX0sIk9GIjp7ImZ2Ijpb
-XX0sInJ1Ijp7ImZ2IjpbXX0sIklWIjp7ImZ2IjpbXX0sIm42Ijp7InpNIjpbIkIyIl0sImJRIjpbIkIy
-Il0sImNYIjpbIkIyIl0sIkFTIjpbXX19JykpCkguRkYodi50eXBlVW5pdmVyc2UsSlNPTi5wYXJzZSgn
-eyJ3MiI6MSwiUUMiOjIsIkxaIjoxLCJrVCI6MiwibVciOjEsInV5IjoxLCJpbCI6MiwiVmoiOjEsIlh2
-IjoxLCJuWSI6MSwiV1kiOjEsInBSIjoxLCJjbyI6MX0nKSkKdmFyIHU9e2w6IkNhbm5vdCBleHRyYWN0
-IGEgZmlsZSBwYXRoIGZyb20gYSBVUkkgd2l0aCBhIGZyYWdtZW50IGNvbXBvbmVudCIsaToiQ2Fubm90
-IGV4dHJhY3QgYSBmaWxlIHBhdGggZnJvbSBhIFVSSSB3aXRoIGEgcXVlcnkgY29tcG9uZW50IixqOiJD
-YW5ub3QgZXh0cmFjdCBhIG5vbi1XaW5kb3dzIGZpbGUgcGF0aCBmcm9tIGEgZmlsZSBVUkkgd2l0aCBh
-biBhdXRob3JpdHkiLGc6ImBudWxsYCBlbmNvdW50ZXJlZCBhcyB0aGUgcmVzdWx0IGZyb20gZXhwcmVz
-c2lvbiB3aXRoIHR5cGUgYE5ldmVyYC4iLGQ6ImFyZWEtYW5hbHl6ZXIsYW5hbHl6ZXItbm5iZC1taWdy
-YXRpb24sdHlwZS1idWcifQp2YXIgdD0oZnVuY3Rpb24gcnRpaSgpe3ZhciBzPUguTjAKcmV0dXJue246
-cygiQ3ciKSxjUjpzKCJuQiIpLHc6cygiQXoiKSxwOnMoIlFQIiksZ0Y6cygiUEQ8R0QsQD4iKSxkOnMo
-ImJRPEA+IiksaDpzKCJjdiIpLHI6cygiWFMiKSxCOnMoImVhIiksYVM6cygiRDAiKSxnODpzKCJSeiIp
-LGM4OnMoImhIIiksWTpzKCJFSCIpLGU6cygiYjg8QD4iKSxJOnMoIlNnIiksbzpzKCJ2USIpLGVoOnMo
-ImNYPHVIPiIpLFE6cygiY1g8cVU+IiksdTpzKCJjWDxAPiIpLHY6cygiamQ8a0Y+IiksczpzKCJqZDxx
-VT4iKSxnTjpzKCJqZDxuNj4iKSxiOnMoImpkPEA+IiksYTpzKCJqZDxCMj4iKSxkNzpzKCJqZDxTZSo+
-IiksaDQ6cygiamQ8ajgqPiIpLEc6cygiamQ8WjA8cVUqLE1oKj4qPiIpLGNROnMoImpkPEQ4Kj4iKSxp
-OnMoImpkPHFVKj4iKSxhQTpzKCJqZDx5RCo+IiksYUo6cygiamQ8d2IqPiIpLFY6cygiamQ8QjIqPiIp
-LGQ0OnMoImpkPHFVPz4iKSxUOnMoIndlIiksZUg6cygidm0iKSx4OnMoImM1IiksYVU6cygiWGo8QD4i
-KSxhbTpzKCJUejxAPiIpLGVvOnMoIk41PEdELEA+IiksZHo6cygiaEYiKSxEOnMoInpNPHFVPiIpLGo6
-cygiek08QD4iKSxMOnMoInpNPEIyPiIpLEo6cygiWjA8cVUscVU+IiksZjpzKCJaMDxALEA+IiksZG86
-cygibEo8cVUsQD4iKSxmajpzKCJsSjxxVSoscVU+IiksZEU6cygiRVQiKSxibTpzKCJWNiIpLEE6cygi
+dGh9LApnbDA6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuZ3ZjKCkubGVuZ3RoPT09MH0sCm46ZnVuY3Rp
+b24oYSl7dmFyIHMscixxPUguVk0oYS5zcGxpdCgiLSIpLHQucykKZm9yKHM9MTtzPHEubGVuZ3RoOysr
+cyl7cj1xW3NdCmlmKHIubGVuZ3RoPjApQy5ObS5ZNShxLHMsclswXS50b1VwcGVyQ2FzZSgpK0ouS1Yo
+ciwxKSl9cmV0dXJuIEMuTm0uayhxLCIiKX0sCk9VOmZ1bmN0aW9uKGEpe3ZhciBzLHIscSxwLG8KZm9y
+KHM9YS5sZW5ndGgscj0wLHE9IiI7cjxzOysrcil7cD1hW3JdCm89cC50b0xvd2VyQ2FzZSgpCnE9KHAh
+PT1vJiZyPjA/cSsiLSI6cSkrb31yZXR1cm4gcS5jaGFyQ29kZUF0KDApPT0wP3E6cX19ClcuS1MucHJv
+dG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXtpZihKLmF1KGEsImRhdGEtIikpdGhpcy5iLiQyKHRoaXMu
+YS5uKEMueEIueW4oYSw1KSksYil9LAokUzoxNX0KVy5BMy5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihh
+LGIpe2lmKEouYXUoYSwiZGF0YS0iKSlDLk5tLmkodGhpcy5iLHRoaXMuYS5uKEMueEIueW4oYSw1KSkp
+fSwKJFM6MTV9ClcuSTQucHJvdG90eXBlPXsKRDpmdW5jdGlvbigpe3ZhciBzLHIscSxwLG89UC5Mcyh0
+Lk4pCmZvcihzPXRoaXMuYS5jbGFzc05hbWUuc3BsaXQoIiAiKSxyPXMubGVuZ3RoLHE9MDtxPHI7Kytx
+KXtwPUouVDAoc1txXSkKaWYocC5sZW5ndGghPT0wKW8uaSgwLHApfXJldHVybiBvfSwKWDpmdW5jdGlv
+bihhKXt0aGlzLmEuY2xhc3NOYW1lPXQuQy5hKGEpLmsoMCwiICIpfSwKZ0E6ZnVuY3Rpb24oYSl7cmV0
+dXJuIHRoaXMuYS5jbGFzc0xpc3QubGVuZ3RofSwKZ2wwOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmEu
+Y2xhc3NMaXN0Lmxlbmd0aD09PTB9LApnb3I6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYS5jbGFzc0xp
+c3QubGVuZ3RoIT09MH0sClYxOmZ1bmN0aW9uKGEpe3RoaXMuYS5jbGFzc05hbWU9IiJ9LAp0ZzpmdW5j
+dGlvbihhLGIpe3ZhciBzPXRoaXMuYS5jbGFzc0xpc3QuY29udGFpbnMoYikKcmV0dXJuIHN9LAppOmZ1
+bmN0aW9uKGEsYil7dmFyIHMscgpILmgoYikKcz10aGlzLmEuY2xhc3NMaXN0CnI9cy5jb250YWlucyhi
+KQpzLmFkZChiKQpyZXR1cm4hcn0sClI6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEKaWYodHlwZW9mIGI9
+PSJzdHJpbmciKXtzPXRoaXMuYS5jbGFzc0xpc3QKcj1zLmNvbnRhaW5zKGIpCnMucmVtb3ZlKGIpCnE9
+cn1lbHNlIHE9ITEKcmV0dXJuIHF9LApGVjpmdW5jdGlvbihhLGIpe1cuVE4odGhpcy5hLHQuUS5hKGIp
+KX19ClcuRmsucHJvdG90eXBlPXt9ClcuUk8ucHJvdG90eXBlPXt9ClcuZXUucHJvdG90eXBlPXt9Clcu
+eEMucHJvdG90eXBlPXt9Clcudk4ucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMu
+YS4kMSh0LkIuYShhKSl9LAokUzoyN30KVy5KUS5wcm90b3R5cGU9ewpDWTpmdW5jdGlvbihhKXt2YXIg
+cwppZigkLm9yLmE9PT0wKXtmb3Iocz0wO3M8MjYyOysrcykkLm9yLlk1KDAsQy5jbVtzXSxXLnBTKCkp
+CmZvcihzPTA7czwxMjsrK3MpJC5vci5ZNSgwLEMuQklbc10sVy5WNCgpKX19LAppMDpmdW5jdGlvbihh
+KXtyZXR1cm4gJC5BTigpLnRnKDAsVy5yUyhhKSl9LApFYjpmdW5jdGlvbihhLGIsYyl7dmFyIHM9JC5v
+ci5xKDAsSC5FaihXLnJTKGEpKSsiOjoiK2IpCmlmKHM9PW51bGwpcz0kLm9yLnEoMCwiKjo6IitiKQpp
+ZihzPT1udWxsKXJldHVybiExCnJldHVybiBILnk4KHMuJDQoYSxiLGMsdGhpcykpfSwKJGlrRjoxfQpX
+LkdtLnByb3RvdHlwZT17CmdtOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgVy5XOShhLHRoaXMuZ0EoYSks
+SC56KGEpLkMoIlc5PEdtLkU+IikpfX0KVy52RC5wcm90b3R5cGU9ewppMDpmdW5jdGlvbihhKXtyZXR1
+cm4gQy5ObS5Wcih0aGlzLmEsbmV3IFcuVXYoYSkpfSwKRWI6ZnVuY3Rpb24oYSxiLGMpe3JldHVybiBD
+Lk5tLlZyKHRoaXMuYSxuZXcgVy5FZyhhLGIsYykpfSwKJGlrRjoxfQpXLlV2LnByb3RvdHlwZT17CiQx
+OmZ1bmN0aW9uKGEpe3JldHVybiB0LkUuYShhKS5pMCh0aGlzLmEpfSwKJFM6MTZ9ClcuRWcucHJvdG90
+eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIHQuRS5hKGEpLkViKHRoaXMuYSx0aGlzLmIsdGhpcy5j
+KX0sCiRTOjE2fQpXLm02LnByb3RvdHlwZT17CkNZOmZ1bmN0aW9uKGEsYixjLGQpe3ZhciBzLHIscQp0
+aGlzLmEuRlYoMCxjKQpzPWIuZXYoMCxuZXcgVy5FbygpKQpyPWIuZXYoMCxuZXcgVy5XaygpKQp0aGlz
+LmIuRlYoMCxzKQpxPXRoaXMuYwpxLkZWKDAsQy54RCkKcS5GVigwLHIpfSwKaTA6ZnVuY3Rpb24oYSl7
+cmV0dXJuIHRoaXMuYS50ZygwLFcuclMoYSkpfSwKRWI6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzPXRoaXMs
+cj1XLnJTKGEpLHE9cy5jCmlmKHEudGcoMCxILkVqKHIpKyI6OiIrYikpcmV0dXJuIHMuZC5EdChjKQpl
+bHNlIGlmKHEudGcoMCwiKjo6IitiKSlyZXR1cm4gcy5kLkR0KGMpCmVsc2V7cT1zLmIKaWYocS50Zygw
+LEguRWoocikrIjo6IitiKSlyZXR1cm4hMAplbHNlIGlmKHEudGcoMCwiKjo6IitiKSlyZXR1cm4hMApl
+bHNlIGlmKHEudGcoMCxILkVqKHIpKyI6OioiKSlyZXR1cm4hMAplbHNlIGlmKHEudGcoMCwiKjo6KiIp
+KXJldHVybiEwfXJldHVybiExfSwKJGlrRjoxfQpXLkVvLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEp
+e3JldHVybiFDLk5tLnRnKEMuQkksSC5oKGEpKX0sCiRTOjd9ClcuV2sucHJvdG90eXBlPXsKJDE6ZnVu
+Y3Rpb24oYSl7cmV0dXJuIEMuTm0udGcoQy5CSSxILmgoYSkpfSwKJFM6N30KVy5jdC5wcm90b3R5cGU9
+ewpFYjpmdW5jdGlvbihhLGIsYyl7aWYodGhpcy5qRihhLGIsYykpcmV0dXJuITAKaWYoYj09PSJ0ZW1w
+bGF0ZSImJmM9PT0iIilyZXR1cm4hMAppZihhLmdldEF0dHJpYnV0ZSgidGVtcGxhdGUiKT09PSIiKXJl
+dHVybiB0aGlzLmUudGcoMCxiKQpyZXR1cm4hMX19ClcuSUEucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24o
+YSl7cmV0dXJuIlRFTVBMQVRFOjoiK0guRWooSC5oKGEpKX0sCiRTOjV9ClcuT3cucHJvdG90eXBlPXsK
+aTA6ZnVuY3Rpb24oYSl7dmFyIHMKaWYodC5ldy5iKGEpKXJldHVybiExCnM9dC5nNy5iKGEpCmlmKHMm
+JlcuclMoYSk9PT0iZm9yZWlnbk9iamVjdCIpcmV0dXJuITEKaWYocylyZXR1cm4hMApyZXR1cm4hMX0s
+CkViOmZ1bmN0aW9uKGEsYixjKXtpZihiPT09ImlzInx8Qy54Qi5uQyhiLCJvbiIpKXJldHVybiExCnJl
+dHVybiB0aGlzLmkwKGEpfSwKJGlrRjoxfQpXLlc5LnByb3RvdHlwZT17CkY6ZnVuY3Rpb24oKXt2YXIg
+cz10aGlzLHI9cy5jKzEscT1zLmIKaWYocjxxKXtzLnNwKEoueDkocy5hLHIpKQpzLmM9cgpyZXR1cm4h
+MH1zLnNwKG51bGwpCnMuYz1xCnJldHVybiExfSwKZ2w6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5kfSwK
+c3A6ZnVuY3Rpb24oYSl7dGhpcy5kPXRoaXMuJHRpLkMoIjE/IikuYShhKX0sCiRpQW46MX0KVy5kVy5w
+cm90b3R5cGU9eyRpRDA6MSwkaXY2OjF9ClcubWsucHJvdG90eXBlPXskaXkwOjF9ClcuS28ucHJvdG90
+eXBlPXsKUG46ZnVuY3Rpb24oYSl7dmFyIHM9dGhpcyxyPW5ldyBXLmZtKHMpCnMuYj0hMQpyLiQyKGEs
+bnVsbCkKZm9yKDtzLmI7KXtzLmI9ITEKci4kMihhLG51bGwpfX0sCkVQOmZ1bmN0aW9uKGEsYil7dmFy
+IHM9dGhpcy5iPSEwCmlmKGIhPW51bGw/YiE9PWEucGFyZW50Tm9kZTpzKUouTHQoYSkKZWxzZSBiLnJl
+bW92ZUNoaWxkKGEpfSwKSTQ6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEscCxvLG49ITAsbT1udWxsLGw9
+bnVsbAp0cnl7bT1KLmlnKGEpCmw9bS5hLmdldEF0dHJpYnV0ZSgiaXMiKQp0LmguYShhKQpzPWZ1bmN0
+aW9uKGMpe2lmKCEoYy5hdHRyaWJ1dGVzIGluc3RhbmNlb2YgTmFtZWROb2RlTWFwKSlyZXR1cm4gdHJ1
+ZQppZihjLmlkPT0nbGFzdENoaWxkJ3x8Yy5uYW1lPT0nbGFzdENoaWxkJ3x8Yy5pZD09J3ByZXZpb3Vz
+U2libGluZyd8fGMubmFtZT09J3ByZXZpb3VzU2libGluZyd8fGMuaWQ9PSdjaGlsZHJlbid8fGMubmFt
+ZT09J2NoaWxkcmVuJylyZXR1cm4gdHJ1ZQp2YXIgaz1jLmNoaWxkTm9kZXMKaWYoYy5sYXN0Q2hpbGQm
+JmMubGFzdENoaWxkIT09a1trLmxlbmd0aC0xXSlyZXR1cm4gdHJ1ZQppZihjLmNoaWxkcmVuKWlmKCEo
+Yy5jaGlsZHJlbiBpbnN0YW5jZW9mIEhUTUxDb2xsZWN0aW9ufHxjLmNoaWxkcmVuIGluc3RhbmNlb2Yg
+Tm9kZUxpc3QpKXJldHVybiB0cnVlCnZhciBqPTAKaWYoYy5jaGlsZHJlbilqPWMuY2hpbGRyZW4ubGVu
+Z3RoCmZvcih2YXIgaT0wO2k8ajtpKyspe3ZhciBoPWMuY2hpbGRyZW5baV0KaWYoaC5pZD09J2F0dHJp
+YnV0ZXMnfHxoLm5hbWU9PSdhdHRyaWJ1dGVzJ3x8aC5pZD09J2xhc3RDaGlsZCd8fGgubmFtZT09J2xh
+c3RDaGlsZCd8fGguaWQ9PSdwcmV2aW91c1NpYmxpbmcnfHxoLm5hbWU9PSdwcmV2aW91c1NpYmxpbmcn
+fHxoLmlkPT0nY2hpbGRyZW4nfHxoLm5hbWU9PSdjaGlsZHJlbicpcmV0dXJuIHRydWV9cmV0dXJuIGZh
+bHNlfShhKQpuPUgub1Qocyk/ITA6IShhLmF0dHJpYnV0ZXMgaW5zdGFuY2VvZiBOYW1lZE5vZGVNYXAp
+fWNhdGNoKHApe0guUnUocCl9cj0iZWxlbWVudCB1bnByaW50YWJsZSIKdHJ5e3I9Si5qKGEpfWNhdGNo
+KHApe0guUnUocCl9dHJ5e3E9Vy5yUyhhKQp0aGlzLmtSKHQuaC5hKGEpLGIsbixyLHEsdC5mLmEobSks
+SC5rKGwpKX1jYXRjaChwKXtpZihILlJ1KHApIGluc3RhbmNlb2YgUC51KXRocm93IHAKZWxzZXt0aGlz
+LkVQKGEsYikKd2luZG93Cm89IlJlbW92aW5nIGNvcnJ1cHRlZCBlbGVtZW50ICIrSC5FaihyKQppZih0
+eXBlb2YgY29uc29sZSE9InVuZGVmaW5lZCIpd2luZG93LmNvbnNvbGUud2FybihvKX19fSwKa1I6ZnVu
+Y3Rpb24oYSxiLGMsZCxlLGYsZyl7dmFyIHMscixxLHAsbyxuLG09dGhpcwppZihjKXttLkVQKGEsYikK
+d2luZG93CnM9IlJlbW92aW5nIGVsZW1lbnQgZHVlIHRvIGNvcnJ1cHRlZCBhdHRyaWJ1dGVzIG9uIDwi
+K2QrIj4iCmlmKHR5cGVvZiBjb25zb2xlIT0idW5kZWZpbmVkIil3aW5kb3cuY29uc29sZS53YXJuKHMp
+CnJldHVybn1pZighbS5hLmkwKGEpKXttLkVQKGEsYikKd2luZG93CnM9IlJlbW92aW5nIGRpc2FsbG93
+ZWQgZWxlbWVudCA8IitILkVqKGUpKyI+IGZyb20gIitILkVqKGIpCmlmKHR5cGVvZiBjb25zb2xlIT0i
+dW5kZWZpbmVkIil3aW5kb3cuY29uc29sZS53YXJuKHMpCnJldHVybn1pZihnIT1udWxsKWlmKCFtLmEu
+RWIoYSwiaXMiLGcpKXttLkVQKGEsYikKd2luZG93CnM9IlJlbW92aW5nIGRpc2FsbG93ZWQgdHlwZSBl
+eHRlbnNpb24gPCIrSC5FaihlKSsnIGlzPSInK2crJyI+JwppZih0eXBlb2YgY29uc29sZSE9InVuZGVm
+aW5lZCIpd2luZG93LmNvbnNvbGUud2FybihzKQpyZXR1cm59cz1mLmd2YygpCnI9SC5WTShzLnNsaWNl
+KDApLEgudDYocykpCmZvcihxPWYuZ3ZjKCkubGVuZ3RoLTEscz1mLmE7cT49MDstLXEpe2lmKHE+PXIu
+bGVuZ3RoKXJldHVybiBILk9IKHIscSkKcD1yW3FdCm89bS5hCm49Si5jSChwKQpILmgocCkKaWYoIW8u
+RWIoYSxuLHMuZ2V0QXR0cmlidXRlKHApKSl7d2luZG93Cm89IlJlbW92aW5nIGRpc2FsbG93ZWQgYXR0
+cmlidXRlIDwiK0guRWooZSkrIiAiK3ArJz0iJytILkVqKHMuZ2V0QXR0cmlidXRlKHApKSsnIj4nCmlm
+KHR5cGVvZiBjb25zb2xlIT0idW5kZWZpbmVkIil3aW5kb3cuY29uc29sZS53YXJuKG8pCnMucmVtb3Zl
+QXR0cmlidXRlKHApfX1pZih0LmFXLmIoYSkpe3M9YS5jb250ZW50CnMudG9TdHJpbmcKbS5QbihzKX19
+LAokaW9uOjF9ClcuZm0ucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEscCxvLG4s
+bT10aGlzLmEKc3dpdGNoKGEubm9kZVR5cGUpe2Nhc2UgMTptLkk0KGEsYikKYnJlYWsKY2FzZSA4OmNh
+c2UgMTE6Y2FzZSAzOmNhc2UgNDpicmVhawpkZWZhdWx0Om0uRVAoYSxiKX1zPWEubGFzdENoaWxkCmZv
+cihxPXQuQTtudWxsIT1zOyl7cj1udWxsCnRyeXtyPXMucHJldmlvdXNTaWJsaW5nCmlmKHIhPW51bGwp
+e3A9ci5uZXh0U2libGluZwpvPXMKbz1wPT1udWxsP28hPW51bGw6cCE9PW8KcD1vfWVsc2UgcD0hMQpp
+ZihwKXtwPVAuUFYoIkNvcnJ1cHQgSFRNTCIpCnRocm93IEguYihwKX19Y2F0Y2gobil7SC5SdShuKQpw
+PXEuYShzKQptLmI9ITAKbz1wLnBhcmVudE5vZGUKbz1hPT1udWxsP28hPW51bGw6YSE9PW8KaWYobyl7
+bz1wLnBhcmVudE5vZGUKaWYobyE9bnVsbClvLnJlbW92ZUNoaWxkKHApfWVsc2UgYS5yZW1vdmVDaGls
+ZChwKQpzPW51bGwKcj1hLmxhc3RDaGlsZH1pZihzIT1udWxsKXRoaXMuJDIocyxhKQpzPXJ9fSwKJFM6
+MzB9ClcuTGUucHJvdG90eXBlPXt9ClcuSzcucHJvdG90eXBlPXt9ClcuckIucHJvdG90eXBlPXt9Clcu
+WFcucHJvdG90eXBlPXt9Clcub2EucHJvdG90eXBlPXt9ClAuaUoucHJvdG90eXBlPXsKVkg6ZnVuY3Rp
+b24oYSl7dmFyIHMscj10aGlzLmEscT1yLmxlbmd0aApmb3Iocz0wO3M8cTsrK3MpaWYocltzXT09PWEp
+cmV0dXJuIHMKQy5ObS5pKHIsYSkKQy5ObS5pKHRoaXMuYixudWxsKQpyZXR1cm4gcX0sClB2OmZ1bmN0
+aW9uKGEpe3ZhciBzLHIscSxwPXRoaXMsbz17fQppZihhPT1udWxsKXJldHVybiBhCmlmKEgubChhKSly
+ZXR1cm4gYQppZih0eXBlb2YgYT09Im51bWJlciIpcmV0dXJuIGEKaWYodHlwZW9mIGE9PSJzdHJpbmci
+KXJldHVybiBhCmlmKGEgaW5zdGFuY2VvZiBQLmlQKXJldHVybiBuZXcgRGF0ZShhLmEpCmlmKHQuZnYu
+YihhKSl0aHJvdyBILmIoUC5TWSgic3RydWN0dXJlZCBjbG9uZSBvZiBSZWdFeHAiKSkKaWYodC5jOC5i
+KGEpKXJldHVybiBhCmlmKHQudy5iKGEpKXJldHVybiBhCmlmKHQuSS5iKGEpKXJldHVybiBhCnM9dC5k
+RS5iKGEpfHwhMQppZihzKXJldHVybiBhCmlmKHQuZi5iKGEpKXtyPXAuVkgoYSkKcz1wLmIKaWYocj49
+cy5sZW5ndGgpcmV0dXJuIEguT0gocyxyKQpxPW8uYT1zW3JdCmlmKHEhPW51bGwpcmV0dXJuIHEKcT17
+fQpvLmE9cQpDLk5tLlk1KHMscixxKQphLksoMCxuZXcgUC5qZyhvLHApKQpyZXR1cm4gby5hfWlmKHQu
+ai5iKGEpKXtyPXAuVkgoYSkKbz1wLmIKaWYocj49by5sZW5ndGgpcmV0dXJuIEguT0gobyxyKQpxPW9b
+cl0KaWYocSE9bnVsbClyZXR1cm4gcQpyZXR1cm4gcC5layhhLHIpfWlmKHQuZUguYihhKSl7cj1wLlZI
+KGEpCnM9cC5iCmlmKHI+PXMubGVuZ3RoKXJldHVybiBILk9IKHMscikKcT1vLmI9c1tyXQppZihxIT1u
+dWxsKXJldHVybiBxCnE9e30Kby5iPXEKQy5ObS5ZNShzLHIscSkKcC5pbShhLG5ldyBQLlRhKG8scCkp
+CnJldHVybiBvLmJ9dGhyb3cgSC5iKFAuU1koInN0cnVjdHVyZWQgY2xvbmUgb2Ygb3RoZXIgdHlwZSIp
+KX0sCmVrOmZ1bmN0aW9uKGEsYil7dmFyIHMscj1KLlU2KGEpLHE9ci5nQShhKSxwPW5ldyBBcnJheShx
+KQpDLk5tLlk1KHRoaXMuYixiLHApCmZvcihzPTA7czxxOysrcylDLk5tLlk1KHAscyx0aGlzLlB2KHIu
+cShhLHMpKSkKcmV0dXJuIHB9fQpQLmpnLnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7dGhpcy5h
+LmFbYV09dGhpcy5iLlB2KGIpfSwKJFM6MzF9ClAuVGEucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxi
+KXt0aGlzLmEuYlthXT10aGlzLmIuUHYoYil9LAokUzoxN30KUC5CZi5wcm90b3R5cGU9ewppbTpmdW5j
+dGlvbihhLGIpe3ZhciBzLHIscSxwCnQuYjguYShiKQpmb3Iocz1PYmplY3Qua2V5cyhhKSxyPXMubGVu
+Z3RoLHE9MDtxPHI7KytxKXtwPXNbcV0KYi4kMihwLGFbcF0pfX19ClAuQXMucHJvdG90eXBlPXsKVjpm
+dW5jdGlvbihhKXt2YXIgcwpILmgoYSkKcz0kLmhHKCkuYgppZih0eXBlb2YgYSE9InN0cmluZyIpSC52
+KEgudEwoYSkpCmlmKHMudGVzdChhKSlyZXR1cm4gYQp0aHJvdyBILmIoUC5MMyhhLCJ2YWx1ZSIsIk5v
+dCBhIHZhbGlkIGNsYXNzIHRva2VuIikpfSwKdzpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5EKCkuaygw
+LCIgIil9LApnbTpmdW5jdGlvbihhKXt2YXIgcz10aGlzLkQoKQpyZXR1cm4gUC5yaihzLHMucixILkxo
+KHMpLmMpfSwKZ2wwOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLkQoKS5hPT09MH0sCmdvcjpmdW5jdGlv
+bihhKXtyZXR1cm4gdGhpcy5EKCkuYSE9PTB9LApnQTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5EKCku
+YX0sCnRnOmZ1bmN0aW9uKGEsYil7dGhpcy5WKGIpCnJldHVybiB0aGlzLkQoKS50ZygwLGIpfSwKaTpm
+dW5jdGlvbihhLGIpe3ZhciBzCkguaChiKQp0aGlzLlYoYikKcz10aGlzLk9TKG5ldyBQLkdFKGIpKQpy
+ZXR1cm4gSC55OChzPT1udWxsPyExOnMpfSwKUjpmdW5jdGlvbihhLGIpe3ZhciBzLHIKaWYodHlwZW9m
+IGIhPSJzdHJpbmciKXJldHVybiExCnRoaXMuVihiKQpzPXRoaXMuRCgpCnI9cy5SKDAsYikKdGhpcy5Y
+KHMpCnJldHVybiByfSwKRlY6ZnVuY3Rpb24oYSxiKXt0aGlzLk9TKG5ldyBQLk43KHRoaXMsdC5RLmEo
+YikpKX0sCmVSOmZ1bmN0aW9uKGEsYil7dmFyIHM9dGhpcy5EKCkKcmV0dXJuIEguYksocyxiLEguTGgo
+cykuQygibGYuRSIpKX0sCkU6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5EKCkuRSgwLGIpfSwKVjE6
+ZnVuY3Rpb24oYSl7dGhpcy5PUyhuZXcgUC51USgpKX0sCk9TOmZ1bmN0aW9uKGEpe3ZhciBzLHIKdC5i
+VS5hKGEpCnM9dGhpcy5EKCkKcj1hLiQxKHMpCnRoaXMuWChzKQpyZXR1cm4gcn19ClAuR0UucHJvdG90
+eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIHQuQy5hKGEpLmkoMCx0aGlzLmEpfSwKJFM6MzN9ClAu
+TjcucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHM9dGhpcy5iLHI9SC50NihzKQpyZXR1cm4g
+dC5DLmEoYSkuRlYoMCxuZXcgSC5sSihzLHIuQygicVUoMSkiKS5hKHRoaXMuYS5ndU0oKSksci5DKCJs
+SjwxLHFVPiIpKSl9LAokUzoxOH0KUC51US5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt0LkMuYShh
+KQppZihhLmE+MCl7YS5iPWEuYz1hLmQ9YS5lPWEuZj1udWxsCmEuYT0wCmEuUygpfXJldHVybiBudWxs
+fSwKJFM6MTh9ClAuaEYucHJvdG90eXBlPXskaWhGOjF9ClAuUEMucHJvdG90eXBlPXsKJDE6ZnVuY3Rp
+b24oYSl7dmFyIHMKdC5ZLmEoYSkKcz1mdW5jdGlvbihiLGMsZCl7cmV0dXJuIGZ1bmN0aW9uKCl7cmV0
+dXJuIGIoYyxkLHRoaXMsQXJyYXkucHJvdG90eXBlLnNsaWNlLmFwcGx5KGFyZ3VtZW50cykpfX0oUC5S
+NCxhLCExKQpQLkRtKHMsJC53KCksYSkKcmV0dXJuIHN9LAokUzo0fQpQLm10LnByb3RvdHlwZT17CiQx
+OmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgdGhpcy5hKGEpfSwKJFM6NH0KUC5RUy5wcm90b3R5cGU9ewok
+MTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFAucjcoYSl9LAokUzozNX0KUC5ucC5wcm90b3R5cGU9ewok
+MTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFAuVHooYSx0LmFtKX0sCiRTOjQ2fQpQLlV0LnByb3RvdHlw
+ZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgUC5FNChhKX0sCiRTOjM3fQpQLkU0LnByb3RvdHlw
+ZT17CnE6ZnVuY3Rpb24oYSxiKXtpZih0eXBlb2YgYiE9InN0cmluZyImJnR5cGVvZiBiIT0ibnVtYmVy
+Iil0aHJvdyBILmIoUC54WSgicHJvcGVydHkgaXMgbm90IGEgU3RyaW5nIG9yIG51bSIpKQpyZXR1cm4g
+UC5kVSh0aGlzLmFbYl0pfSwKWTU6ZnVuY3Rpb24oYSxiLGMpe2lmKHR5cGVvZiBiIT0ic3RyaW5nIiYm
+dHlwZW9mIGIhPSJudW1iZXIiKXRocm93IEguYihQLnhZKCJwcm9wZXJ0eSBpcyBub3QgYSBTdHJpbmcg
+b3IgbnVtIikpCnRoaXMuYVtiXT1QLndZKGMpfSwKRE46ZnVuY3Rpb24oYSxiKXtpZihiPT1udWxsKXJl
+dHVybiExCnJldHVybiBiIGluc3RhbmNlb2YgUC5FNCYmdGhpcy5hPT09Yi5hfSwKdzpmdW5jdGlvbihh
+KXt2YXIgcyxyCnRyeXtzPVN0cmluZyh0aGlzLmEpCnJldHVybiBzfWNhdGNoKHIpe0guUnUocikKcz10
+aGlzLnhiKDApCnJldHVybiBzfX0sClY3OmZ1bmN0aW9uKGEsYil7dmFyIHMscj10aGlzLmEKaWYoYj09
+bnVsbClzPW51bGwKZWxzZXtzPUgudDYoYikKcz1QLkNIKG5ldyBILmxKKGIscy5DKCJAKDEpIikuYShQ
+LmlHKCkpLHMuQygibEo8MSxAPiIpKSwhMCx0LnopfXJldHVybiBQLmRVKHJbYV0uYXBwbHkocixzKSl9
+LApnaU86ZnVuY3Rpb24oYSl7cmV0dXJuIDB9fQpQLnI3LnByb3RvdHlwZT17fQpQLlR6LnByb3RvdHlw
+ZT17CmNQOmZ1bmN0aW9uKGEpe3ZhciBzPXRoaXMscj1hPDB8fGE+PXMuZ0EocykKaWYocil0aHJvdyBI
+LmIoUC5URShhLDAscy5nQShzKSxudWxsLG51bGwpKX0sCnE6ZnVuY3Rpb24oYSxiKXtpZihILm9rKGIp
+KXRoaXMuY1AoYikKcmV0dXJuIHRoaXMuJHRpLmMuYSh0aGlzLlVyKDAsYikpfSwKWTU6ZnVuY3Rpb24o
+YSxiLGMpe3RoaXMuY1AoYikKdGhpcy5iaCgwLGIsYyl9LApnQTpmdW5jdGlvbihhKXt2YXIgcz10aGlz
+LmEubGVuZ3RoCmlmKHR5cGVvZiBzPT09Im51bWJlciImJnM+Pj4wPT09cylyZXR1cm4gcwp0aHJvdyBI
+LmIoUC5QVigiQmFkIEpzQXJyYXkgbGVuZ3RoIikpfSwKJGliUToxLAokaWNYOjEsCiRpek06MX0KUC5j
+by5wcm90b3R5cGU9ewpZNTpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIHRoaXMuZTQoMCxiLGMpfX0KUC5u
+ZC5wcm90b3R5cGU9eyRpbmQ6MX0KUC5LZS5wcm90b3R5cGU9ewpEOmZ1bmN0aW9uKCl7dmFyIHMscixx
+LHAsbz10aGlzLmEuZ2V0QXR0cmlidXRlKCJjbGFzcyIpLG49UC5Mcyh0Lk4pCmlmKG89PW51bGwpcmV0
+dXJuIG4KZm9yKHM9by5zcGxpdCgiICIpLHI9cy5sZW5ndGgscT0wO3E8cjsrK3Epe3A9Si5UMChzW3Fd
+KQppZihwLmxlbmd0aCE9PTApbi5pKDAscCl9cmV0dXJuIG59LApYOmZ1bmN0aW9uKGEpe3RoaXMuYS5z
+ZXRBdHRyaWJ1dGUoImNsYXNzIixhLmsoMCwiICIpKX19ClAuaGkucHJvdG90eXBlPXsKZ1A6ZnVuY3Rp
+b24oYSl7cmV0dXJuIG5ldyBQLktlKGEpfSwKc2hmOmZ1bmN0aW9uKGEsYil7dGhpcy5ZQyhhLGIpfSwK
+cjY6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHMscixxLHAsbyxuCmlmKGQ9PW51bGwpe3M9SC5WTShbXSx0
+LnYpCmQ9bmV3IFcudkQocykKQy5ObS5pKHMsVy5UdyhudWxsKSkKQy5ObS5pKHMsVy5CbCgpKQpDLk5t
+LmkocyxuZXcgVy5PdygpKX1jPW5ldyBXLktvKGQpCnI9JzxzdmcgdmVyc2lvbj0iMS4xIj4nK0guRWoo
+YikrIjwvc3ZnPiIKcz1kb2N1bWVudApxPXMuYm9keQpxLnRvU3RyaW5nCnA9Qy5SWS5BSChxLHIsYykK
+bz1zLmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKQpwLnRvU3RyaW5nCnM9bmV3IFcuZTcocCkKbj1zLmdy
+OChzKQpmb3IoO3M9bi5maXJzdENoaWxkLHMhPW51bGw7KW8uYXBwZW5kQ2hpbGQocykKcmV0dXJuIG99
+LApuejpmdW5jdGlvbihhLGIsYyxkLGUpe3Rocm93IEguYihQLkw0KCJDYW5ub3QgaW52b2tlIGluc2Vy
+dEFkamFjZW50SHRtbCBvbiBTVkcuIikpfSwKZ1ZsOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgVy5ldShh
+LCJjbGljayIsITEsdC5rKX0sCiRpaGk6MX0KVS5kMi5wcm90b3R5cGU9ewpMdDpmdW5jdGlvbigpe3Zh
+ciBzLHIscSxwLG89dGhpcyxuPXQuWCxtPXQuXyxsPVAuRmwobixtKSxrPW8uYQppZihrIT1udWxsKXtz
+PUguVk0oW10sdC5HKQpmb3Iocj1rLmxlbmd0aCxxPTA7cTxrLmxlbmd0aDtrLmxlbmd0aD09PXJ8fCgw
+LEgubGspKGspLCsrcSl7cD1rW3FdCnMucHVzaChQLkVGKFsiZGVzY3JpcHRpb24iLHAuYSwiaHJlZiIs
+cC5iXSxuLG0pKX1sLlk1KDAsImVkaXRzIixzKX1sLlk1KDAsImV4cGxhbmF0aW9uIixvLmIpCmwuWTUo
+MCwibGluZSIsby5jKQpsLlk1KDAsImRpc3BsYXlQYXRoIixvLmQpCmwuWTUoMCwidXJpUGF0aCIsby5l
+KQpuPW8uZgppZihuIT1udWxsKXttPUguVk0oW10sdC5HKQpmb3Ioaz1uLmxlbmd0aCxxPTA7cTxuLmxl
+bmd0aDtuLmxlbmd0aD09PWt8fCgwLEgubGspKG4pLCsrcSltLnB1c2gobltxXS5MdCgpKQpsLlk1KDAs
+InRyYWNlcyIsbSl9cmV0dXJuIGx9fQpVLlNlLnByb3RvdHlwZT17Ckx0OmZ1bmN0aW9uKCl7cmV0dXJu
+IFAuRUYoWyJkZXNjcmlwdGlvbiIsdGhpcy5hLCJocmVmIix0aGlzLmJdLHQuWCx0Ll8pfX0KVS5NbC5w
+cm90b3R5cGU9ewpMdDpmdW5jdGlvbigpe3JldHVybiBQLkVGKFsiaHJlZiIsdGhpcy5hLCJsaW5lIix0
+aGlzLmIsInBhdGgiLHRoaXMuY10sdC5YLHQuXyl9fQpVLnlELnByb3RvdHlwZT17Ckx0OmZ1bmN0aW9u
+KCl7dmFyIHMscixxLHA9SC5WTShbXSx0LkcpCmZvcihzPXRoaXMuYixyPXMubGVuZ3RoLHE9MDtxPHMu
+bGVuZ3RoO3MubGVuZ3RoPT09cnx8KDAsSC5saykocyksKytxKXAucHVzaChzW3FdLkx0KCkpCnJldHVy
+biBQLkVGKFsiZGVzY3JpcHRpb24iLHRoaXMuYSwiZW50cmllcyIscF0sdC5YLHQuXyl9fQpVLndiLnBy
+b3RvdHlwZT17Ckx0OmZ1bmN0aW9uKCl7dmFyIHMscixxLHA9dGhpcyxvPVAuRmwodC5YLHQuXykKby5Z
+NSgwLCJkZXNjcmlwdGlvbiIscC5hKQpzPXAuYgppZihzIT1udWxsKW8uWTUoMCwiZnVuY3Rpb24iLHMp
+CnM9cC5jCmlmKHMhPW51bGwpby5ZNSgwLCJsaW5rIixzLkx0KCkpCnM9cC5kCmlmKHMubGVuZ3RoIT09
+MCl7cj1ILnQ2KHMpCnE9ci5DKCJsSjwxLFowPHFVKixNaCo+Kj4iKQpvLlk1KDAsImhpbnRBY3Rpb25z
+IixQLlkxKG5ldyBILmxKKHMsci5DKCJaMDxxVSosTWgqPiooMSkiKS5hKG5ldyBVLmIwKCkpLHEpLCEw
+LHEuQygiYUwuRSIpKSl9cmV0dXJuIG99fQpVLmFOLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3Jl
+dHVybiBSLm56KHQudC5hKGEpKX0sCiRTOjM4fQpVLmIwLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEp
+e3JldHVybiB0LmFYLmEoYSkuTHQoKX0sCiRTOjM5fQpCLmo4LnByb3RvdHlwZT17Ckx0OmZ1bmN0aW9u
+KCl7cmV0dXJuIFAuRUYoWyJsaW5lIix0aGlzLmEsImV4cGxhbmF0aW9uIix0aGlzLmIsIm9mZnNldCIs
+dGhpcy5jXSx0LlgsdC5fKX19CkIucXAucHJvdG90eXBlPXsKTHQ6ZnVuY3Rpb24oKXt2YXIgcyxyLHEs
+cCxvLG4sbSxsPXRoaXMsaz10Llgsaj1QLkZsKGssdC5kcCkKZm9yKHM9bC5kLHM9cy5nUHUocykscz1z
+LmdtKHMpLHI9dC5fLHE9dC5HO3MuRigpOyl7cD1zLmdsKCkKbz1wLmEKbj1ILlZNKFtdLHEpCmZvcihw
+PUouSVQocC5iKTtwLkYoKTspe209cC5nbCgpCm4ucHVzaChQLkVGKFsibGluZSIsbS5hLCJleHBsYW5h
+dGlvbiIsbS5iLCJvZmZzZXQiLG0uY10sayxyKSl9ai5ZNSgwLG8sbil9cmV0dXJuIFAuRUYoWyJyZWdp
+b25zIixsLmEsIm5hdmlnYXRpb25Db250ZW50IixsLmIsInNvdXJjZUNvZGUiLGwuYywiZWRpdHMiLGpd
+LGsscil9fQpULm1RLnByb3RvdHlwZT17fQpMLmUucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFy
+IHMscixxLHAsbyxuLG0KdC5hTC5hKGEpCnM9d2luZG93LmxvY2F0aW9uLnBhdGhuYW1lCnI9TC5HNih3
+aW5kb3cubG9jYXRpb24uaHJlZikKcT1MLmFLKHdpbmRvdy5sb2NhdGlvbi5ocmVmKQpMLkdlKCkKaWYo
+cyE9PSIvIiYmcyE9PUouVDAoZG9jdW1lbnQucXVlcnlTZWxlY3RvcigiLnJvb3QiKS50ZXh0Q29udGVu
+dCkpTC5HNyhzLHIscSwhMCxuZXcgTC5WVyhzLHIscSkpCnA9ZG9jdW1lbnQKbz1KLnFGKHAucXVlcnlT
+ZWxlY3RvcigiLmFwcGx5LW1pZ3JhdGlvbiIpKQpuPW8uJHRpCm09bi5DKCJ+KDEpPyIpLmEobmV3IEwu
+b1ooKSkKdC5aLmEobnVsbCkKVy5KRShvLmEsby5iLG0sITEsbi5jKQpuPUoucUYocC5xdWVyeVNlbGVj
+dG9yKCIucmVydW4tbWlncmF0aW9uIikpCm09bi4kdGkKVy5KRShuLmEsbi5iLG0uQygifigxKT8iKS5h
+KG5ldyBMLkhpKCkpLCExLG0uYykKbT1KLnFGKHAucXVlcnlTZWxlY3RvcigiLnJlcG9ydC1wcm9ibGVt
+IikpCm49bS4kdGkKVy5KRShtLmEsbS5iLG4uQygifigxKT8iKS5hKG5ldyBMLkJUKCkpLCExLG4uYykK
+cD1KLnFGKHAucXVlcnlTZWxlY3RvcigiLnBvcHVwLXBhbmUgLmNsb3NlIikpCm49cC4kdGkKVy5KRShw
+LmEscC5iLG4uQygifigxKT8iKS5hKG5ldyBMLlBZKCkpLCExLG4uYykKbj1KLnFGKCQuYzAoKSkKcD1u
+LiR0aQpXLkpFKG4uYSxuLmIscC5DKCJ+KDEpPyIpLmEobmV3IEwudTgoKSksITEscC5jKX0sCiRTOjE5
+fQpMLlZXLnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7TC5Gcih0aGlzLmEsdGhpcy5iLHRoaXMuYyl9
+LAokUzoyfQpMLm9aLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciBzLHIscSxwLG8KdC5PLmEo
+YSkKaWYoSC5vVChDLm9sLnVzKHdpbmRvdywiVGhpcyB3aWxsIGFwcGx5IHRoZSBjaGFuZ2VzIHlvdSd2
+ZSBwcmV2aWV3ZWQgdG8geW91ciB3b3JraW5nIGRpcmVjdG9yeS4gSXQgaXMgcmVjb21tZW5kZWQgeW91
+IGNvbW1pdCBhbnkgY2hhbmdlcyB5b3UgbWFkZSBiZWZvcmUgZG9pbmcgdGhpcy4iKSkpe3M9SC5WTShb
+XSx0LkcpCmZvcihyPSQuSVIscT1yLmxlbmd0aCxwPTA7cDxyLmxlbmd0aDtyLmxlbmd0aD09PXF8fCgw
+LEgubGspKHIpLCsrcClzLnB1c2gocltwXS5MdCgpKQpzPUwudHkoIi9hcHBseS1taWdyYXRpb24iLFAu
+RUYoWyJuYXZpZ2F0aW9uVHJlZSIsc10sdC5YLHQuZHApKS5XNyhuZXcgTC5qcigpLHQuUCkKbz1uZXcg
+TC5xbCgpCnQuYjcuYShudWxsKQpyPXMuJHRpCnE9JC5YMwppZihxIT09Qy5OVSlvPVAuVkgobyxxKQpz
+LnhmKG5ldyBQLkZlKG5ldyBQLnZzKHEsciksMixudWxsLG8sci5DKCJAPDE+IikuS3Eoci5jKS5DKCJG
+ZTwxLDI+IikpKX19LAokUzoxfQpMLmpyLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciBzCnQu
+dC5hKGEpCnM9ZG9jdW1lbnQuYm9keQpzLmNsYXNzTGlzdC5yZW1vdmUoInByb3Bvc2VkIikKcy5jbGFz
+c0xpc3QuYWRkKCJhcHBsaWVkIil9LAokUzo0Mn0KTC5xbC5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihh
+LGIpe0wuQzIoIkNvdWxkbid0IGFwcGx5IG1pZ3JhdGlvbiIsYSxiKX0sCiRDOiIkMiIsCiRSOjIsCiRT
+OjE3fQpMLkhpLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLnhuKHQuTy5hKGEp
+KX0sCnhuOmZ1bmN0aW9uKGEpe3ZhciBzPTAscj1QLkZYKHQuUCkscT0xLHAsbz1bXSxuLG0sbCxrLGoK
+dmFyICRhc3luYyQkMT1QLmx6KGZ1bmN0aW9uKGIsYyl7aWYoYj09PTEpe3A9YwpzPXF9d2hpbGUodHJ1
+ZSlzd2l0Y2gocyl7Y2FzZSAwOnE9Mwpkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5hZGQoInJlcnVubmlu
+ZyIpCnM9NgpyZXR1cm4gUC5qUShMLnR5KCIvcmVydW4tbWlncmF0aW9uIixudWxsKSwkYXN5bmMkJDEp
+CmNhc2UgNjpuPWMKaWYoSC5vVChILnk4KEoueDkobiwic3VjY2VzcyIpKSkpd2luZG93LmxvY2F0aW9u
+LnJlbG9hZCgpCmVsc2UgTC5LMCh0LmVFLmEoSi54OShuLCJlcnJvcnMiKSkpCm8ucHVzaCg1KQpzPTQK
+YnJlYWsKY2FzZSAzOnE9MgpqPXAKbT1ILlJ1KGopCmw9SC50cyhqKQpMLkMyKCJGYWlsZWQgdG8gcmVy
+dW4gbWlncmF0aW9uIixtLGwpCm8ucHVzaCg1KQpzPTQKYnJlYWsKY2FzZSAyOm89WzFdCmNhc2UgNDpx
+PTEKZG9jdW1lbnQuYm9keS5jbGFzc0xpc3QucmVtb3ZlKCJyZXJ1bm5pbmciKQpzPW8ucG9wKCkKYnJl
+YWsKY2FzZSA1OnJldHVybiBQLnlDKG51bGwscikKY2FzZSAxOnJldHVybiBQLmYzKHAscil9fSkKcmV0
+dXJuIFAuREkoJGFzeW5jJCQxLHIpfSwKJFM6MjB9CkwuQlQucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24o
+YSl7dC5PLmEoYSkKQy5vbC5Qbyh3aW5kb3csUC5YZCgiaHR0cHMiLCJnaXRodWIuY29tIiwiZGFydC1s
+YW5nL3Nkay9pc3N1ZXMvbmV3IixQLkVGKFsidGl0bGUiLCJDdXN0b21lci1yZXBvcnRlZCBpc3N1ZSB3
+aXRoIE5OQkQgbWlncmF0aW9uIHRvb2wiLCJsYWJlbHMiLHUuZCwiYm9keSIsIiMjIyMgU3RlcHMgdG8g
+cmVwcm9kdWNlXG5cbiMjIyMgV2hhdCBkaWQgeW91IGV4cGVjdCB0byBoYXBwZW4/XG5cbiMjIyMgV2hh
+dCBhY3R1YWxseSBoYXBwZW5lZD9cblxuX1NjcmVlbnNob3RzIGFyZSBhcHByZWNpYXRlZF9cblxuKipE
+YXJ0IFNESyB2ZXJzaW9uKio6ICIrSC5Faihkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgic2RrLXZlcnNp
+b24iKS50ZXh0Q29udGVudCkrIlxuXG5UaGFua3MgZm9yIGZpbGluZyFcbiJdLHQuWCx0LnopKS5nbkQo
+KSwicmVwb3J0LXByb2JsZW0iKX0sCiRTOjF9CkwuUFkucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7
+dmFyIHMKdC5PLmEoYSkKcz1kb2N1bWVudC5xdWVyeVNlbGVjdG9yKCIucG9wdXAtcGFuZSIpLnN0eWxl
+CnMuZGlzcGxheT0ibm9uZSIKcmV0dXJuIm5vbmUifSwKJFM6NDR9CkwudTgucHJvdG90eXBlPXsKJDE6
+ZnVuY3Rpb24oYSl7dmFyIHMscixxLHAKdC5PLmEoYSkKcz0kLkQ5KCkuaW5uZXJUZXh0CnI9dC5nLmEo
+ZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLm5hdi1wYW5lbCBbZGF0YS1uYW1lKj0iJytILkVqKFcuTGoo
+cykpKyciXScpLnBhcmVudE5vZGUpCnE9ci5xdWVyeVNlbGVjdG9yKCIuc3RhdHVzLWljb24iKQpwPUwu
+eXcoJC5JUixzKQppZihwIGluc3RhbmNlb2YgTC5jRCYmSC5vVChwLngpKXtMLk90KHApCkwueG4ocSxw
+KQpMLkFSKHIscCl9fSwKJFM6MX0KTC5MLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciBzLHIs
+cQp0LmFMLmEoYSkKcz13aW5kb3cubG9jYXRpb24ucGF0aG5hbWUKcj1MLkc2KHdpbmRvdy5sb2NhdGlv
+bi5ocmVmKQpxPUwuYUsod2luZG93LmxvY2F0aW9uLmhyZWYpCmlmKHMubGVuZ3RoPjEpTC5HNyhzLHIs
+cSwhMSxudWxsKQplbHNle0wuQkUocyxCLndSKCksITApCkwuQlgoIiZuYnNwOyIsbnVsbCl9fSwKJFM6
+MTl9CkwuV3gucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHMscixxLHAsbz0iY29sbGFwc2Vk
+Igp0Lk8uYShhKQpzPXRoaXMuYQpyPUouWUUocykKcT10aGlzLmIKcD1KLllFKHEpCmlmKCFyLmdQKHMp
+LnRnKDAsbykpe3IuZ1AocykuaSgwLG8pCnAuZ1AocSkuaSgwLG8pfWVsc2V7ci5nUChzKS5SKDAsbykK
+cC5nUChxKS5SKDAsbyl9fSwKJFM6MX0KTC5BTy5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIg
+cz1KLnFGKHQuZy5hKGEpKSxyPXMuJHRpLHE9ci5DKCJ+KDEpPyIpLmEobmV3IEwuZE4odGhpcy5hKSkK
+dC5aLmEobnVsbCkKVy5KRShzLmEscy5iLHEsITEsci5jKX0sCiRTOjN9CkwuZE4ucHJvdG90eXBlPXsK
+JDE6ZnVuY3Rpb24oYSl7cmV0dXJuIEwudDIodC5PLmEoYSksdGhpcy5hKX0sCiRTOjZ9CkwuSG8ucHJv
+dG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHMscixxCnQuZy5hKGEpCnM9Si5xRihhKQpyPXMuJHRp
+CnE9ci5DKCJ+KDEpPyIpLmEobmV3IEwueHooYSx0aGlzLmEpKQp0LlouYShudWxsKQpXLkpFKHMuYSxz
+LmIscSwhMSxyLmMpfSwKJFM6M30KTC54ei5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgcwp0
+Lk8uYShhKQpzPXRoaXMuYQpMLmhYKHRoaXMuYixQLlFBKHMuZ2V0QXR0cmlidXRlKCJkYXRhLSIrbmV3
+IFcuU3kobmV3IFcuaTcocykpLk9VKCJvZmZzZXQiKSksbnVsbCksUC5RQShzLmdldEF0dHJpYnV0ZSgi
+ZGF0YS0iK25ldyBXLlN5KG5ldyBXLmk3KHMpKS5PVSgibGluZSIpKSxudWxsKSl9LAokUzoxfQpMLklD
+LnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciBzPUoucUYodC5nLmEoYSkpLHI9cy4kdGkKci5D
+KCJ+KDEpPyIpLmEoTC5pUygpKQp0LlouYShudWxsKQpXLkpFKHMuYSxzLmIsTC5pUygpLCExLHIuYyl9
+LAokUzozfQpMLmZDLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3QuZVEuYShhKQp0aGlzLmEuYU0o
+MCx0aGlzLmIpfSwKJFM6NDd9CkwuVG0ucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7SC5oKGEpCnJl
+dHVybiBhLmxlbmd0aD40MD9KLmxkKGEsMCw0MCkrIi4uLiI6YX0sCiRTOjQ4fQpMLm5ULnByb3RvdHlw
+ZT17CiQwOmZ1bmN0aW9uKCl7TC5Gcih0aGlzLmEsdGhpcy5iLHRoaXMuYyl9LAokUzoyfQpMLk5ZLnBy
+b3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7TC5Gcih0aGlzLmEsbnVsbCxudWxsKX0sCiRTOjJ9CkwudWUu
+cHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dC5hdy5hKGEpCnJldHVybiBILkVqKGEucSgwLCJzZXZl
+cml0eSIpKSsiIC0gIitILkVqKGEucSgwLCJtZXNzYWdlIikpKyIgYXQgIitILkVqKGEucSgwLCJsb2Nh
+dGlvbiIpKSsiIC0gKCIrSC5FaihhLnEoMCwiY29kZSIpKSsiKSJ9LAokUzo0OX0KTC5lWC5wcm90b3R5
+cGU9ewokMTpmdW5jdGlvbihhKXt0LmcuYShhKQokLnpCKCkudG9TdHJpbmcKdC5kSC5hKCQub3coKS5x
+KDAsImhsanMiKSkuVjcoImhpZ2hsaWdodEJsb2NrIixbYV0pfSwKJFM6M30KTC5FRS5wcm90b3R5cGU9
+ewokMTpmdW5jdGlvbihhKXt2YXIgcyxyCnQuTy5hKGEpLnByZXZlbnREZWZhdWx0KCkKcz10aGlzLmEK
+cj10aGlzLmIKTC5hZih3aW5kb3cubG9jYXRpb24ucGF0aG5hbWUscyxyLCEwLG5ldyBMLlFMKHMscikp
+CkwuaFgodGhpcy5jLHMscil9LAokUzoxfQpMLlFMLnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7TC5G
+cih3aW5kb3cubG9jYXRpb24ucGF0aG5hbWUsdGhpcy5hLHRoaXMuYil9LAokUzoyfQpMLlZTLnByb3Rv
+dHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciBzLHI9InNlbGVjdGVkLWZpbGUiCnQuZy5hKGEpCmEudG9T
+dHJpbmcKcz1KLllFKGEpCmlmKGEuZ2V0QXR0cmlidXRlKCJkYXRhLSIrbmV3IFcuU3kobmV3IFcuaTco
+YSkpLk9VKCJuYW1lIikpPT09dGhpcy5hLmEpcy5nUChhKS5pKDAscikKZWxzZSBzLmdQKGEpLlIoMCxy
+KX0sCiRTOjN9CkwuVEQucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHMscgp0Lk8uYShhKQpz
+PXRoaXMuYQpzd2l0Y2gocy5nTCgpKXtjYXNlIEMuY3c6YnJlYWsKY2FzZSBDLldEOnMubkcoKQpicmVh
+awpjYXNlIEMuWGo6cy5jMigpCmJyZWFrCmNhc2UgQy5kYzpzLmMyKCkKYnJlYWt9cj10aGlzLmIKTC5o
+bChyLHMpCkwueG4odGhpcy5jLHMpCkwuQVIocixzKX0sCiRTOjF9CkwuSWYucHJvdG90eXBlPXsKJDE6
+ZnVuY3Rpb24oYSl7dmFyIHMKdC5PLmEoYSkKcz10aGlzLmEKTC5PdChzKQpMLnhuKHRoaXMuYixzKQpM
+LkFSKHRoaXMuYyxzKX0sCiRTOjF9CkwudEIucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJu
+IEwudDIodC5PLmEoYSksITApfSwKJFM6Nn0KTC5tMi5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXty
+ZXR1cm4gdGhpcy5SSSh0Lk8uYShhKSl9LApSSTpmdW5jdGlvbihhKXt2YXIgcz0wLHI9UC5GWCh0LlAp
+LHE9MSxwLG89W10sbj10aGlzLG0sbCxrLGosaSxoLGcsZgp2YXIgJGFzeW5jJCQxPVAubHooZnVuY3Rp
+b24oYixjKXtpZihiPT09MSl7cD1jCnM9cX13aGlsZSh0cnVlKXN3aXRjaChzKXtjYXNlIDA6cT0zCmk9
+ZG9jdW1lbnQKbT1DLkNELnpRKGkucXVlcnlTZWxlY3RvcigiLmNvbnRlbnQiKS5zY3JvbGxUb3ApCmg9
+dC5YCnM9NgpyZXR1cm4gUC5qUShMLnR5KEwuUTQoIi9hcHBseS1oaW50IixQLkZsKGgsaCkpLG4uYS5M
+dCgpKSwkYXN5bmMkJDEpCmNhc2UgNjpoPW4uYgpsPUwuVXMoaC5hKQpzPTcKcmV0dXJuIFAualEoTC5H
+NyhsLG51bGwsaC5iLCExLG51bGwpLCRhc3luYyQkMSkKY2FzZSA3OmkuYm9keS5jbGFzc0xpc3QuYWRk
+KCJuZWVkcy1yZXJ1biIpCmk9aS5xdWVyeVNlbGVjdG9yKCIuY29udGVudCIpCmkudG9TdHJpbmcKaS5z
+Y3JvbGxUb3A9Si5WdShtKQpxPTEKcz01CmJyZWFrCmNhc2UgMzpxPTIKZj1wCms9SC5SdShmKQpqPUgu
+dHMoZikKTC5DMigiY291bGRuJ3QgYXBwbHkgaGludCIsayxqKQpzPTUKYnJlYWsKY2FzZSAyOnM9MQpi
+cmVhawpjYXNlIDU6cmV0dXJuIFAueUMobnVsbCxyKQpjYXNlIDE6cmV0dXJuIFAuZjMocCxyKX19KQpy
+ZXR1cm4gUC5ESSgkYXN5bmMkJDEscil9LAokUzoyMH0KTC5RVy5wcm90b3R5cGU9ewp3OmZ1bmN0aW9u
+KGEpe3JldHVybiB0aGlzLmErIjpcbiIrdGhpcy5ifSwKJGlSejoxfQpMLlhBLnByb3RvdHlwZT17CkVi
+OmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4hMH0sCmkwOmZ1bmN0aW9uKGEpe3JldHVybiEwfSwKJGlrRjox
+fQpMLnZ0LnByb3RvdHlwZT17CmdMOmZ1bmN0aW9uKCl7dmFyIHMscixxLHAsbyxuLG0sbD10aGlzLmQK
+aWYobC5sZW5ndGg9PT0wKXJldHVybiBDLmN3CnM9Qy5ObS5ndEgobCkuZ0woKQpmb3Iocj1sLmxlbmd0
+aCxxPSEwLHA9ITAsbz0wO288bC5sZW5ndGg7bC5sZW5ndGg9PT1yfHwoMCxILmxrKShsKSwrK28pe249
+bFtvXS5nTCgpCmlmKG4hPXMpcz1udWxsCm09biE9PUMuY3cKaWYobSYmbiE9PUMuV0QpcT0hMQppZiht
+JiZuIT09Qy5YailwPSExfWlmKHMhPW51bGwpcmV0dXJuIHMKaWYocSlyZXR1cm4gQy5XRAppZihwKXJl
+dHVybiBDLlhqCnJldHVybiBDLmRjfSwKTFY6ZnVuY3Rpb24oKXt2YXIgcyxyLHE9dGhpcy5kCmlmKHEh
+PW51bGwpZm9yKHM9cS5sZW5ndGgscj0wO3I8czsrK3IpcVtyXS5iPXRoaXN9LApjMjpmdW5jdGlvbigp
+e3ZhciBzLHIscSxwCmZvcihzPXRoaXMuZCxyPXMubGVuZ3RoLHE9MDtxPHMubGVuZ3RoO3MubGVuZ3Ro
+PT09cnx8KDAsSC5saykocyksKytxKXtwPXNbcV0KaWYocCBpbnN0YW5jZW9mIEwudnQpcC5jMigpCmVs
+c2UgaWYocCBpbnN0YW5jZW9mIEwuY0QmJkgub1QocC54KSYmcC5yPT09Qy5YailwLnI9Qy5XRH19LApu
+RzpmdW5jdGlvbigpe3ZhciBzLHIscSxwCmZvcihzPXRoaXMuZCxyPXMubGVuZ3RoLHE9MDtxPHMubGVu
+Z3RoO3MubGVuZ3RoPT09cnx8KDAsSC5saykocyksKytxKXtwPXNbcV0KaWYocCBpbnN0YW5jZW9mIEwu
+dnQpcC5uRygpCmVsc2UgaWYocCBpbnN0YW5jZW9mIEwuY0QmJkgub1QocC54KSYmcC5yPT09Qy5XRClw
+LnI9Qy5Yan19LApMdDpmdW5jdGlvbigpe3ZhciBzLHI9UC5GbCh0LlgsdC5fKQpyLlk1KDAsInR5cGUi
+LCJkaXJlY3RvcnkiKQpyLlk1KDAsIm5hbWUiLHRoaXMuYSkKci5ZNSgwLCJzdWJ0cmVlIixMLlZEKHRo
+aXMuZCkpCnM9dGhpcy5jCmlmKHMhPW51bGwpci5ZNSgwLCJwYXRoIixzKQpyZXR1cm4gcn19CkwuY0Qu
+cHJvdG90eXBlPXsKTHQ6ZnVuY3Rpb24oKXt2YXIgcyxyPXRoaXMscT1QLkZsKHQuWCx0Ll8pCnEuWTUo
+MCwidHlwZSIsImZpbGUiKQpxLlk1KDAsIm5hbWUiLHIuYSkKcz1yLmMKaWYocyE9bnVsbClxLlk1KDAs
+InBhdGgiLHMpCnM9ci5kCmlmKHMhPW51bGwpcS5ZNSgwLCJocmVmIixzKQpzPXIuZQppZihzIT1udWxs
+KXEuWTUoMCwiZWRpdENvdW50IixzKQpzPXIuZgppZihzIT1udWxsKXEuWTUoMCwid2FzRXhwbGljaXRs
+eU9wdGVkT3V0IixzKQpzPXIucgppZihzIT1udWxsKXEuWTUoMCwibWlncmF0aW9uU3RhdHVzIixzLmEp
+CnM9ci54CmlmKHMhPW51bGwpcS5ZNSgwLCJtaWdyYXRpb25TdGF0dXNDYW5CZUNoYW5nZWQiLHMpCnJl
+dHVybiBxfSwKZ0w6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5yfX0KTC5EOC5wcm90b3R5cGU9e30KTC5P
+OS5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmJ9fQpMLkdiLnByb3RvdHlwZT17
+Cnc6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYn19ClIuTEwucHJvdG90eXBlPXsKTHQ6ZnVuY3Rpb24o
+KXtyZXR1cm4gUC5FRihbIm5vZGVJZCIsdGhpcy5iLCJraW5kIix0aGlzLmEuYV0sdC5YLHQuXyl9fQpS
+Lk1ELnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiB0LmZFLmEoYSkuYT09PXRoaXMuYS5x
+KDAsImtpbmQiKX0sCiRTOjUwfQpSLkg3LnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7cmV0dXJuIHRo
+aXMuYn19Ck0ubEkucHJvdG90eXBlPXsKV086ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHE9dC5kNApNLllG
+KCJhYnNvbHV0ZSIsSC5WTShbYixudWxsLG51bGwsbnVsbCxudWxsLG51bGwsbnVsbF0scSkpCnM9dGhp
+cy5hCnM9cy5ZcihiKT4wJiYhcy5oSyhiKQppZihzKXJldHVybiBiCnM9RC5hYigpCnI9SC5WTShbcyxi
+LG51bGwsbnVsbCxudWxsLG51bGwsbnVsbCxudWxsXSxxKQpNLllGKCJqb2luIixyKQpyZXR1cm4gdGhp
+cy5JUChuZXcgSC51NihyLHQuZUopKX0sCnpmOmZ1bmN0aW9uKGEpe3ZhciBzLHIscT1YLkNMKGEsdGhp
+cy5hKQpxLkl4KCkKcz1xLmQKcj1zLmxlbmd0aAppZihyPT09MCl7cz1xLmIKcmV0dXJuIHM9PW51bGw/
+Ii4iOnN9aWYocj09PTEpe3M9cS5iCnJldHVybiBzPT1udWxsPyIuIjpzfWlmKDA+PXIpcmV0dXJuIEgu
+T0gocywtMSkKcy5wb3AoKQpzPXEuZQppZigwPj1zLmxlbmd0aClyZXR1cm4gSC5PSChzLC0xKQpzLnBv
+cCgpCnEuSXgoKQpyZXR1cm4gcS53KDApfSwKSVA6ZnVuY3Rpb24oYSl7dmFyIHMscixxLHAsbyxuLG0s
+bCxrLGoKdC5RLmEoYSkKZm9yKHM9YS4kdGkscj1zLkMoImEyKGNYLkUpIikuYShuZXcgTS5xNygpKSxx
+PWEuZ20oYSkscz1uZXcgSC5TTyhxLHIscy5DKCJTTzxjWC5FPiIpKSxyPXRoaXMuYSxwPSExLG89ITEs
+bj0iIjtzLkYoKTspe209cS5nbCgpCmlmKHIuaEsobSkmJm8pe2w9WC5DTChtLHIpCms9bi5jaGFyQ29k
+ZUF0KDApPT0wP246bgpuPUMueEIuTmooaywwLHIuU3AoaywhMCkpCmwuYj1uCmlmKHIuZHMobikpQy5O
+bS5ZNShsLmUsMCxyLmdtSSgpKQpuPWwudygwKX1lbHNlIGlmKHIuWXIobSk+MCl7bz0hci5oSyhtKQpu
+PUguRWoobSl9ZWxzZXtqPW0ubGVuZ3RoCmlmKGohPT0wKXtpZigwPj1qKXJldHVybiBILk9IKG0sMCkK
+aj1yLlVkKG1bMF0pfWVsc2Ugaj0hMQppZighailpZihwKW4rPXIuZ21JKCkKbis9bX1wPXIuZHMobSl9
+cmV0dXJuIG4uY2hhckNvZGVBdCgwKT09MD9uOm59LApvNTpmdW5jdGlvbihhKXt2YXIgcwppZighdGhp
+cy55MyhhKSlyZXR1cm4gYQpzPVguQ0woYSx0aGlzLmEpCnMuclIoKQpyZXR1cm4gcy53KDApfSwKeTM6
+ZnVuY3Rpb24oYSl7dmFyIHMscixxLHAsbyxuLG0sbCxrLGoKYS50b1N0cmluZwpzPXRoaXMuYQpyPXMu
+WXIoYSkKaWYociE9PTApe2lmKHM9PT0kLktrKCkpZm9yKHE9MDtxPHI7KytxKWlmKEMueEIuVyhhLHEp
+PT09NDcpcmV0dXJuITAKcD1yCm89NDd9ZWxzZXtwPTAKbz1udWxsfWZvcihuPW5ldyBILnFqKGEpLmEs
+bT1uLmxlbmd0aCxxPXAsbD1udWxsO3E8bTsrK3EsbD1vLG89ayl7az1DLnhCLk8obixxKQppZihzLnI0
+KGspKXtpZihzPT09JC5LaygpJiZrPT09NDcpcmV0dXJuITAKaWYobyE9bnVsbCYmcy5yNChvKSlyZXR1
+cm4hMAppZihvPT09NDYpaj1sPT1udWxsfHxsPT09NDZ8fHMucjQobCkKZWxzZSBqPSExCmlmKGopcmV0
+dXJuITB9fWlmKG89PW51bGwpcmV0dXJuITAKaWYocy5yNChvKSlyZXR1cm4hMAppZihvPT09NDYpcz1s
+PT1udWxsfHxzLnI0KGwpfHxsPT09NDYKZWxzZSBzPSExCmlmKHMpcmV0dXJuITAKcmV0dXJuITF9LApI
+UDpmdW5jdGlvbihhLGIpe3ZhciBzLHIscSxwLG8sbixtLGw9dGhpcyxrPSdVbmFibGUgdG8gZmluZCBh
+IHBhdGggdG8gIicKYj1sLldPKDAsYikKcz1sLmEKaWYocy5ZcihiKTw9MCYmcy5ZcihhKT4wKXJldHVy
+biBsLm81KGEpCmlmKHMuWXIoYSk8PTB8fHMuaEsoYSkpYT1sLldPKDAsYSkKaWYocy5ZcihhKTw9MCYm
+cy5ZcihiKT4wKXRocm93IEguYihYLkk3KGsrSC5FaihhKSsnIiBmcm9tICInK0guRWooYikrJyIuJykp
+CnI9WC5DTChiLHMpCnIuclIoKQpxPVguQ0woYSxzKQpxLnJSKCkKcD1yLmQKbz1wLmxlbmd0aAppZihv
+IT09MCl7aWYoMD49bylyZXR1cm4gSC5PSChwLDApCnA9Si5STShwWzBdLCIuIil9ZWxzZSBwPSExCmlm
+KHApcmV0dXJuIHEudygwKQpwPXIuYgpvPXEuYgppZihwIT1vKXA9cD09bnVsbHx8bz09bnVsbHx8IXMu
+TmMocCxvKQplbHNlIHA9ITEKaWYocClyZXR1cm4gcS53KDApCndoaWxlKCEwKXtwPXIuZApvPXAubGVu
+Z3RoCmlmKG8hPT0wKXtuPXEuZAptPW4ubGVuZ3RoCmlmKG0hPT0wKXtpZigwPj1vKXJldHVybiBILk9I
+KHAsMCkKcD1wWzBdCmlmKDA+PW0pcmV0dXJuIEguT0gobiwwKQpuPXMuTmMocCxuWzBdKQpwPW59ZWxz
+ZSBwPSExfWVsc2UgcD0hMQppZighcClicmVhawpDLk5tLlc0KHIuZCwwKQpDLk5tLlc0KHIuZSwxKQpD
+Lk5tLlc0KHEuZCwwKQpDLk5tLlc0KHEuZSwxKX1wPXIuZApvPXAubGVuZ3RoCmlmKG8hPT0wKXtpZigw
+Pj1vKXJldHVybiBILk9IKHAsMCkKcD1KLlJNKHBbMF0sIi4uIil9ZWxzZSBwPSExCmlmKHApdGhyb3cg
+SC5iKFguSTcoaytILkVqKGEpKyciIGZyb20gIicrSC5FaihiKSsnIi4nKSkKcD10Lk4KQy5ObS5VRyhx
+LmQsMCxQLk84KHIuZC5sZW5ndGgsIi4uIiwhMSxwKSkKQy5ObS5ZNShxLmUsMCwiIikKQy5ObS5VRyhx
+LmUsMSxQLk84KHIuZC5sZW5ndGgscy5nbUkoKSwhMSxwKSkKcz1xLmQKcD1zLmxlbmd0aAppZihwPT09
+MClyZXR1cm4iLiIKaWYocD4xJiZKLlJNKEMuTm0uZ3JaKHMpLCIuIikpe3M9cS5kCmlmKDA+PXMubGVu
+Z3RoKXJldHVybiBILk9IKHMsLTEpCnMucG9wKCkKcz1xLmUKaWYoMD49cy5sZW5ndGgpcmV0dXJuIEgu
+T0gocywtMSkKcy5wb3AoKQppZigwPj1zLmxlbmd0aClyZXR1cm4gSC5PSChzLC0xKQpzLnBvcCgpCkMu
+Tm0uaShzLCIiKX1xLmI9IiIKcS5JeCgpCnJldHVybiBxLncoMCl9fQpNLnE3LnByb3RvdHlwZT17CiQx
+OmZ1bmN0aW9uKGEpe3JldHVybiBILmgoYSkhPT0iIn0sCiRTOjd9Ck0uTm8ucHJvdG90eXBlPXsKJDE6
+ZnVuY3Rpb24oYSl7SC5rKGEpCnJldHVybiBhPT1udWxsPyJudWxsIjonIicrYSsnIid9LAokUzo1MX0K
+Qi5mdi5wcm90b3R5cGU9ewp4WjpmdW5jdGlvbihhKXt2YXIgcyxyPXRoaXMuWXIoYSkKaWYocj4wKXJl
+dHVybiBKLmxkKGEsMCxyKQppZih0aGlzLmhLKGEpKXtpZigwPj1hLmxlbmd0aClyZXR1cm4gSC5PSChh
+LDApCnM9YVswXX1lbHNlIHM9bnVsbApyZXR1cm4gc30sCk5jOmZ1bmN0aW9uKGEsYil7cmV0dXJuIGE9
+PWJ9fQpYLldELnByb3RvdHlwZT17Ckl4OmZ1bmN0aW9uKCl7dmFyIHMscixxPXRoaXMKd2hpbGUoITAp
+e3M9cS5kCmlmKCEocy5sZW5ndGghPT0wJiZKLlJNKEMuTm0uZ3JaKHMpLCIiKSkpYnJlYWsKcz1xLmQK
+aWYoMD49cy5sZW5ndGgpcmV0dXJuIEguT0gocywtMSkKcy5wb3AoKQpzPXEuZQppZigwPj1zLmxlbmd0
+aClyZXR1cm4gSC5PSChzLC0xKQpzLnBvcCgpfXM9cS5lCnI9cy5sZW5ndGgKaWYociE9PTApQy5ObS5Z
+NShzLHItMSwiIil9LApyUjpmdW5jdGlvbigpe3ZhciBzLHIscSxwLG8sbixtPXRoaXMsbD1ILlZNKFtd
+LHQucykKZm9yKHM9bS5kLHI9cy5sZW5ndGgscT0wLHA9MDtwPHMubGVuZ3RoO3MubGVuZ3RoPT09cnx8
+KDAsSC5saykocyksKytwKXtvPXNbcF0Kbj1KLmlhKG8pCmlmKCEobi5ETihvLCIuIil8fG4uRE4obywi
+IikpKWlmKG4uRE4obywiLi4iKSl7bj1sLmxlbmd0aAppZihuIT09MCl7aWYoMD49bilyZXR1cm4gSC5P
+SChsLC0xKQpsLnBvcCgpfWVsc2UgKytxfWVsc2UgQy5ObS5pKGwsbyl9aWYobS5iPT1udWxsKUMuTm0u
+VUcobCwwLFAuTzgocSwiLi4iLCExLHQuTikpCmlmKGwubGVuZ3RoPT09MCYmbS5iPT1udWxsKUMuTm0u
+aShsLCIuIikKbS5zbkoobCkKcz1tLmEKbS5zUGgoUC5POChsLmxlbmd0aCsxLHMuZ21JKCksITAsdC5O
+KSkKcj1tLmIKaWYocj09bnVsbHx8bC5sZW5ndGg9PT0wfHwhcy5kcyhyKSlDLk5tLlk1KG0uZSwwLCIi
+KQpyPW0uYgppZihyIT1udWxsJiZzPT09JC5LaygpKXtyLnRvU3RyaW5nCm0uYj1ILnlzKHIsIi8iLCJc
+XCIpfW0uSXgoKX0sCnc6ZnVuY3Rpb24oYSl7dmFyIHMscixxPXRoaXMscD1xLmIKcD1wIT1udWxsP3A6
+IiIKZm9yKHM9MDtzPHEuZC5sZW5ndGg7KytzKXtyPXEuZQppZihzPj1yLmxlbmd0aClyZXR1cm4gSC5P
+SChyLHMpCnI9cCtILkVqKHJbc10pCnA9cS5kCmlmKHM+PXAubGVuZ3RoKXJldHVybiBILk9IKHAscykK
+cD1yK0guRWoocFtzXSl9cCs9SC5FaihDLk5tLmdyWihxLmUpKQpyZXR1cm4gcC5jaGFyQ29kZUF0KDAp
+PT0wP3A6cH0sCnNuSjpmdW5jdGlvbihhKXt0aGlzLmQ9dC5ELmEoYSl9LApzUGg6ZnVuY3Rpb24oYSl7
+dGhpcy5lPXQuRC5hKGEpfX0KWC5kdi5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiJQYXRo
+RXhjZXB0aW9uOiAiK3RoaXMuYX0sCiRpUno6MX0KTy56TC5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEp
+e3JldHVybiB0aGlzLmdvYyh0aGlzKX19CkUuT0YucHJvdG90eXBlPXsKVWQ6ZnVuY3Rpb24oYSl7cmV0
+dXJuIEMueEIudGcoYSwiLyIpfSwKcjQ6ZnVuY3Rpb24oYSl7cmV0dXJuIGE9PT00N30sCmRzOmZ1bmN0
+aW9uKGEpe3ZhciBzPWEubGVuZ3RoCnJldHVybiBzIT09MCYmQy54Qi5PKGEscy0xKSE9PTQ3fSwKU3A6
+ZnVuY3Rpb24oYSxiKXtpZihhLmxlbmd0aCE9PTAmJkMueEIuVyhhLDApPT09NDcpcmV0dXJuIDEKcmV0
+dXJuIDB9LApZcjpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5TcChhLCExKX0sCmhLOmZ1bmN0aW9uKGEp
+e3JldHVybiExfSwKZ29jOmZ1bmN0aW9uKCl7cmV0dXJuInBvc2l4In0sCmdtSTpmdW5jdGlvbigpe3Jl
+dHVybiIvIn19CkYucnUucHJvdG90eXBlPXsKVWQ6ZnVuY3Rpb24oYSl7cmV0dXJuIEMueEIudGcoYSwi
+LyIpfSwKcjQ6ZnVuY3Rpb24oYSl7cmV0dXJuIGE9PT00N30sCmRzOmZ1bmN0aW9uKGEpe3ZhciBzPWEu
+bGVuZ3RoCmlmKHM9PT0wKXJldHVybiExCmlmKEMueEIuTyhhLHMtMSkhPT00NylyZXR1cm4hMApyZXR1
+cm4gQy54Qi5UYyhhLCI6Ly8iKSYmdGhpcy5ZcihhKT09PXN9LApTcDpmdW5jdGlvbihhLGIpe3ZhciBz
+LHIscSxwLG89YS5sZW5ndGgKaWYobz09PTApcmV0dXJuIDAKaWYoQy54Qi5XKGEsMCk9PT00NylyZXR1
+cm4gMQpmb3Iocz0wO3M8bzsrK3Mpe3I9Qy54Qi5XKGEscykKaWYocj09PTQ3KXJldHVybiAwCmlmKHI9
+PT01OCl7aWYocz09PTApcmV0dXJuIDAKcT1DLnhCLlhVKGEsIi8iLEMueEIuUWkoYSwiLy8iLHMrMSk/
+cyszOnMpCmlmKHE8PTApcmV0dXJuIG8KaWYoIWJ8fG88cSszKXJldHVybiBxCmlmKCFDLnhCLm5DKGEs
+ImZpbGU6Ly8iKSlyZXR1cm4gcQppZighQi5ZdShhLHErMSkpcmV0dXJuIHEKcD1xKzMKcmV0dXJuIG89
+PT1wP3A6cSs0fX1yZXR1cm4gMH0sCllyOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLlNwKGEsITEpfSwK
+aEs6ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVuZ3RoIT09MCYmQy54Qi5XKGEsMCk9PT00N30sCmdvYzpm
+dW5jdGlvbigpe3JldHVybiJ1cmwifSwKZ21JOmZ1bmN0aW9uKCl7cmV0dXJuIi8ifX0KTC5JVi5wcm90
+b3R5cGU9ewpVZDpmdW5jdGlvbihhKXtyZXR1cm4gQy54Qi50ZyhhLCIvIil9LApyNDpmdW5jdGlvbihh
+KXtyZXR1cm4gYT09PTQ3fHxhPT09OTJ9LApkczpmdW5jdGlvbihhKXt2YXIgcz1hLmxlbmd0aAppZihz
+PT09MClyZXR1cm4hMQpzPUMueEIuTyhhLHMtMSkKcmV0dXJuIShzPT09NDd8fHM9PT05Mil9LApTcDpm
+dW5jdGlvbihhLGIpe3ZhciBzLHIscT1hLmxlbmd0aAppZihxPT09MClyZXR1cm4gMApzPUMueEIuVyhh
+LDApCmlmKHM9PT00NylyZXR1cm4gMQppZihzPT09OTIpe2lmKHE8Mnx8Qy54Qi5XKGEsMSkhPT05Mily
+ZXR1cm4gMQpyPUMueEIuWFUoYSwiXFwiLDIpCmlmKHI+MCl7cj1DLnhCLlhVKGEsIlxcIixyKzEpCmlm
+KHI+MClyZXR1cm4gcn1yZXR1cm4gcX1pZihxPDMpcmV0dXJuIDAKaWYoIUIuT1MocykpcmV0dXJuIDAK
+aWYoQy54Qi5XKGEsMSkhPT01OClyZXR1cm4gMApxPUMueEIuVyhhLDIpCmlmKCEocT09PTQ3fHxxPT09
+OTIpKXJldHVybiAwCnJldHVybiAzfSwKWXI6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuU3AoYSwhMSl9
+LApoSzpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5ZcihhKT09PTF9LApPdDpmdW5jdGlvbihhLGIpe3Zh
+ciBzCmlmKGE9PT1iKXJldHVybiEwCmlmKGE9PT00NylyZXR1cm4gYj09PTkyCmlmKGE9PT05MilyZXR1
+cm4gYj09PTQ3CmlmKChhXmIpIT09MzIpcmV0dXJuITEKcz1hfDMyCnJldHVybiBzPj05NyYmczw9MTIy
+fSwKTmM6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEKaWYoYT09YilyZXR1cm4hMApzPWEubGVuZ3RoCmlm
+KHMhPT1iLmxlbmd0aClyZXR1cm4hMQpmb3Iocj1KLnJZKGIpLHE9MDtxPHM7KytxKWlmKCF0aGlzLk90
+KEMueEIuVyhhLHEpLHIuVyhiLHEpKSlyZXR1cm4hMQpyZXR1cm4hMH0sCmdvYzpmdW5jdGlvbigpe3Jl
+dHVybiJ3aW5kb3dzIn0sCmdtSTpmdW5jdGlvbigpe3JldHVybiJcXCJ9fTsoZnVuY3Rpb24gYWxpYXNl
+cygpe3ZhciBzPUouR3YucHJvdG90eXBlCnMuVT1zLncKcy5Taj1zLmU3CnM9Si5NRi5wcm90b3R5cGUK
+cy50PXMudwpzPVAuY1gucHJvdG90eXBlCnMuR0c9cy5ldgpzPVAuTWgucHJvdG90eXBlCnMueGI9cy53
+CnM9Vy5jdi5wcm90b3R5cGUKcy5EVz1zLnI2CnM9Vy5tNi5wcm90b3R5cGUKcy5qRj1zLkViCnM9UC5F
+NC5wcm90b3R5cGUKcy5Vcj1zLnEKcy5lND1zLlk1CnM9UC5jby5wcm90b3R5cGUKcy5iaD1zLlk1fSko
+KTsoZnVuY3Rpb24gaW5zdGFsbFRlYXJPZmZzKCl7dmFyIHM9aHVua0hlbHBlcnMuX3N0YXRpY18xLHI9
+aHVua0hlbHBlcnMuX3N0YXRpY18wLHE9aHVua0hlbHBlcnMuaW5zdGFsbEluc3RhbmNlVGVhck9mZixw
+PWh1bmtIZWxwZXJzLmluc3RhbGxTdGF0aWNUZWFyT2ZmLG89aHVua0hlbHBlcnMuX2luc3RhbmNlXzF1
+CnMoUCwiRVgiLCJaViIsOCkKcyhQLCJ5dCIsIm9BIiw4KQpzKFAsInFXIiwiQnoiLDgpCnIoUCwiVUki
+LCJlTiIsMCkKcShQLlBmLnByb3RvdHlwZSwiZ1lKIiwwLDEsbnVsbCxbIiQyIiwiJDEiXSxbIncwIiwi
+cG0iXSwyNiwwKQpzKFAsIkN5IiwiTkMiLDQpCnMoUCwiUEgiLCJNdCIsNSkKcChXLCJwUyIsNCxudWxs
+LFsiJDQiXSxbInFEIl0sOSwwKQpwKFcsIlY0Iiw0LG51bGwsWyIkNCJdLFsibloiXSw5LDApCm8oUC5B
+cy5wcm90b3R5cGUsImd1TSIsIlYiLDUpCnMoUCwiaUciLCJ3WSIsNTQpCnMoUCwidzAiLCJkVSIsMzYp
+CnMoTCwiaVMiLCJpNiIsNil9KSgpOyhmdW5jdGlvbiBpbmhlcml0YW5jZSgpe3ZhciBzPWh1bmtIZWxw
+ZXJzLm1peGluLHI9aHVua0hlbHBlcnMuaW5oZXJpdCxxPWh1bmtIZWxwZXJzLmluaGVyaXRNYW55CnIo
+UC5NaCxudWxsKQpxKFAuTWgsW0guRkssSi5HdixKLm0xLFAuY1gsSC5FNyxQLlhTLFAublksSC5hNyxQ
+LkFuLEguRnUsSC5KQixILlNVLEguUmUsSC53dixQLlBuLEguV1UsSC5MSSxILlRwLEguZjksSC50ZSxI
+LmJxLEguWE8sSC5rcixQLllrLEgudmgsSC5ONixILlZSLEguRUssSC5QYixILnRRLEguU2QsSC5KYyxI
+LkcsSC5sWSxQLlczLFAuaWgsUC5GeSxQLkdWLFAuQ3csUC5QZixQLkZlLFAudnMsUC5PTSxQLnFoLFAu
+TU8sUC5rVCxQLnhJLFAubTAsUC5wUixQLmJuLFAubG0sUC5sRCxQLktQLFAubGYsUC5XWSxQLlVrLFAu
+U2gsUC5SdyxQLmJ6LFAuaVAsUC5rNSxQLktZLFAuQ0QsUC5hRSxQLk4zLFAuYzgsUC5aZCxQLlJuLFAu
+RG4sUC5QRSxQLlVmLFcuaWQsVy5GayxXLkpRLFcuR20sVy52RCxXLm02LFcuT3csVy5XOSxXLmRXLFcu
+bWssVy5LbyxQLmlKLFAuRTQsVS5kMixVLlNlLFUuTWwsVS55RCxVLndiLEIuajgsQi5xcCxULm1RLEwu
+WEEsTC5EOCxMLk85LEwuR2IsUi5MTCxSLkg3LE0ubEksTy56TCxYLldELFguZHZdKQpxKEouR3YsW0ou
+eUUsSi53ZSxKLk1GLEouamQsSi5xSSxKLkRyLEguRVQsVy5EMCxXLkF6LFcuTGUsVy5OaCxXLmFlLFcu
+SUIsVy5uNyxXLmVhLFcuYnIsVy5TZyxXLnc3LFcuSzcsVy5YVyxQLmhGXSkKcShKLk1GLFtKLmlDLEou
+a2QsSi5jNV0pCnIoSi5QbyxKLmpkKQpxKEoucUksW0ouYlUsSi5rRF0pCnEoUC5jWCxbSC5CUixILmJR
+LEguaTEsSC5VNSxILkFNLEgudTYsSC5YUixQLm1XLEgudW5dKQpxKEguQlIsW0guWnksSC5RQ10pCnIo
+SC5vbCxILlp5KQpyKEguVXEsSC5RQykKcihILmpWLEguVXEpCnEoUC5YUyxbSC5uLEgucjMsSC5HTSxQ
+LkV6LEguYXosSC52VixILkVxLFAuQzYsSC5rUyxQLlVkLFAuRixQLnUsUC5tcCxQLnViLFAuZHMsUC5s
+aixQLlVWLFAuYyxMLlFXXSkKcihQLnV5LFAublkpCnEoUC51eSxbSC53MixXLnd6LFcuZTddKQpyKEgu
+cWosSC53MikKcShILmJRLFtILmFMLEguTUIsSC5pNV0pCnEoSC5hTCxbSC5uSCxILmxKLFAuaThdKQpy
+KEgueHksSC5pMSkKcShQLkFuLFtILk1ILEguU08sSC5VMV0pCnIoSC5kNSxILkFNKQpyKFAuUlUsUC5Q
+bikKcihQLkdqLFAuUlUpCnIoSC5QRCxQLkdqKQpyKEguTFAsSC5XVSkKcShILlRwLFtILkNqLEgubGMs
+SC5kQyxILndOLEguVlgsUC50aCxQLmhhLFAuVnMsUC5GdCxQLnlILFAuV00sUC5TWCxQLkdzLFAuZGEs
+UC5vUSxQLnBWLFAuVTcsUC52cixQLnJ0LFAuS0YsUC5aTCxQLlJULFAualosUC5ycSxQLlJXLFAuQjUs
+UC51TyxQLnBLLFAuVnAsUC5PUixQLnJhLFAueVEsUC54cixQLk56LFAudGksUC5XRixQLm4xLFAuY1Ms
+UC5WQyxQLkpULFAuUlosUC5NRSxQLnk1LFAueUksUC5jNixQLnFkLFcuQ3YsVy5LUyxXLkEzLFcudk4s
+Vy5VdixXLkVnLFcuRW8sVy5XayxXLklBLFcuZm0sUC5qZyxQLlRhLFAuR0UsUC5ONyxQLnVRLFAuUEMs
+UC5tdCxQLlFTLFAubnAsUC5VdCxVLmFOLFUuYjAsTC5lLEwuVlcsTC5vWixMLmpyLEwucWwsTC5IaSxM
+LkJULEwuUFksTC51OCxMLkwsTC5XeCxMLkFPLEwuZE4sTC5IbyxMLnh6LEwuSUMsTC5mQyxMLlRtLEwu
+blQsTC5OWSxMLnVlLEwuZVgsTC5FRSxMLlFMLEwuVlMsTC5URCxMLklmLEwudEIsTC5tMixSLk1ELE0u
+cTcsTS5Ob10pCnIoSC5XMCxQLkV6KQpxKEgubGMsW0guengsSC5yVF0pCnIoSC5rWSxQLkM2KQpyKFAu
+aWwsUC5ZaykKcShQLmlsLFtILk41LFAudXcsVy5jZixXLlN5XSkKcShQLm1XLFtILktXLFAucTRdKQpy
+KEguTFosSC5FVCkKcShILkxaLFtILlJHLEguV0JdKQpyKEguVlAsSC5SRykKcihILkRnLEguVlApCnIo
+SC5aRyxILldCKQpyKEguUGcsSC5aRykKcShILlBnLFtILnhqLEguZEUsSC5aQSxILmRULEguUHEsSC5l
+RSxILlY2XSkKcihILmlNLEgua1MpCnIoUC5aZixQLlBmKQpyKFAuSmksUC5tMCkKcihQLlh2LFAucFIp
+CnIoUC5iNixQLlh2KQpyKFAuVmosUC5XWSkKcShQLlVrLFtQLkNWLFAuWmksUC5ieV0pCnIoUC53SSxQ
+LmtUKQpxKFAud0ksW1AuVTgsUC5vaixQLk14LFAuRTMsUC5HWV0pCnIoUC5LOCxQLlVkKQpyKFAudHUs
+UC5TaCkKcihQLnU1LFAuWmkpCnEoUC51LFtQLmJKLFAuZVldKQpyKFAucWUsUC5EbikKcShXLkQwLFtX
+LnVILFcud2EsVy5LNSxXLkNtXSkKcShXLnVILFtXLmN2LFcubngsVy5RRixXLkNRXSkKcShXLmN2LFtX
+LnFFLFAuaGldKQpxKFcucUUsW1cuR2gsVy5mWSxXLm5CLFcuUVAsVy5oNCxXLlNOLFcubHAsVy5UYixX
+Lkl2LFcuV1AsVy55WV0pCnIoVy5vSixXLkxlKQpyKFcuaEgsVy5BeikKcihXLlZiLFcuUUYpCnIoVy5m
+SixXLndhKQpxKFcuZWEsW1cudzYsVy5ld10pCnIoVy5BaixXLnc2KQpyKFcuckIsVy5LNykKcihXLkJI
+LFcuckIpCnIoVy53NCxXLklCKQpyKFcub2EsVy5YVykKcihXLnJoLFcub2EpCnIoVy5pNyxXLmNmKQpy
+KFAuQXMsUC5WaikKcShQLkFzLFtXLkk0LFAuS2VdKQpyKFcuUk8sUC5xaCkKcihXLmV1LFcuUk8pCnIo
+Vy54QyxQLk1PKQpyKFcuY3QsVy5tNikKcihQLkJmLFAuaUopCnEoUC5FNCxbUC5yNyxQLmNvXSkKcihQ
+LlR6LFAuY28pCnIoUC5uZCxQLmhpKQpxKEwuRDgsW0wudnQsTC5jRF0pCnIoQi5mdixPLnpMKQpxKEIu
+ZnYsW0UuT0YsRi5ydSxMLklWXSkKcyhILncyLEguUmUpCnMoSC5RQyxQLmxEKQpzKEguUkcsUC5sRCkK
+cyhILlZQLEguU1UpCnMoSC5XQixQLmxEKQpzKEguWkcsSC5TVSkKcyhQLm5ZLFAubEQpCnMoUC5XWSxQ
+LmxmKQpzKFAuUlUsUC5LUCkKcyhQLnBSLFAubGYpCnMoVy5MZSxXLmlkKQpzKFcuSzcsUC5sRCkKcyhX
+LnJCLFcuR20pCnMoVy5YVyxQLmxEKQpzKFcub2EsVy5HbSkKcyhQLmNvLFAubEQpfSkoKQp2YXIgdj17
+dHlwZVVuaXZlcnNlOntlQzpuZXcgTWFwKCksdFI6e30sZVQ6e30sdFBWOnt9LHNFQTpbXX0sbWFuZ2xl
+ZEdsb2JhbE5hbWVzOntJajoiaW50IixDUDoiZG91YmxlIixaWjoibnVtIixxVToiU3RyaW5nIixhMjoi
+Ym9vbCIsYzg6Ik51bGwiLHpNOiJMaXN0In0sbWFuZ2xlZE5hbWVzOnt9LGdldFR5cGVGcm9tTmFtZTpn
+ZXRHbG9iYWxGcm9tTmFtZSxtZXRhZGF0YTpbXSx0eXBlczpbIn4oKSIsImM4KEFqKikiLCJjOCgpIiwi
+YzgoY3YqKSIsIkAoQCkiLCJxVShxVSkiLCJ+KEFqKikiLCJhMihxVSkiLCJ+KH4oKSkiLCJhMihjdixx
+VSxxVSxKUSkiLCJjOChAKSIsIn4oTWg/LE1oPykiLCJAKCkiLCJ+KHFVLEApIiwifihuNixxVSxJaiki
+LCJ+KHFVLHFVKSIsImEyKGtGKSIsImM4KEAsQCkiLCJ+KHh1PHFVPikiLCJjOChlYSopIiwiYjg8Yzg+
+KihBaiopIiwifihxVSxJaikiLCJ+KHFVLHFVPykiLCJuNihALEApIiwifihJaixAKSIsImEyKHVIKSIs
+In4oTWhbR3o/XSkiLCJ+KGVhKSIsImM4KE1oLEd6KSIsInZzPEA+KEApIiwifih1SCx1SD8pIiwifihA
+LEApIiwiQChxVSkiLCJhMih4dTxxVT4pIiwiQChALHFVKSIsInI3KEApIiwiTWg/KEApIiwiRTQoQCki
+LCJMTCooQCkiLCJaMDxxVSosTWgqPiooTEwqKSIsIn4oR0QsQCkiLCJaMDxxVSxxVT4oWjA8cVUscVU+
+LHFVKSIsImM4KFowPHFVKixNaCo+KikiLCJ+KEApIiwicVUqKEFqKikiLCJ+KHFVW0BdKSIsIlR6PEA+
+KEApIiwiYzgoZXcqKSIsInFVKihxVSopIiwicVUqKFowPEAsQD4qKSIsImEyKihINyopIiwicVUocVU/
+KSIsIklqKElqLElqKSIsImM4KH4oKSkiLCJNaD8oTWg/KSIsImM4KEAsR3opIl0saW50ZXJjZXB0b3Jz
+QnlUYWc6bnVsbCxsZWFmVGFnczpudWxsLGFycmF5UnRpOnR5cGVvZiBTeW1ib2w9PSJmdW5jdGlvbiIm
+JnR5cGVvZiBTeW1ib2woKT09InN5bWJvbCI/U3ltYm9sKCIkdGkiKToiJHRpIn0KSC54Yih2LnR5cGVV
+bml2ZXJzZSxKU09OLnBhcnNlKCd7ImlDIjoiTUYiLCJrZCI6Ik1GIiwiYzUiOiJNRiIsInJ4IjoiZWEi
+LCJlNSI6ImVhIiwiWTAiOiJoaSIsInRwIjoiaGkiLCJHOCI6ImV3IiwiTXIiOiJxRSIsImVMIjoicUUi
+LCJJMCI6InVIIiwiaHMiOiJ1SCIsIlhnIjoiUUYiLCJuciI6IkFqIiwieTQiOiJ3NiIsImFQIjoiQ20i
+LCJ4YyI6Im54Iiwia0oiOiJueCIsInpVIjoiRGciLCJkZiI6IkVUIiwieUUiOnsiYTIiOltdfSwid2Ui
+OnsiYzgiOltdfSwiTUYiOnsidm0iOltdfSwiamQiOnsiek0iOlsiMSJdLCJiUSI6WyIxIl0sImNYIjpb
+IjEiXX0sIlBvIjp7ImpkIjpbIjEiXSwiek0iOlsiMSJdLCJiUSI6WyIxIl0sImNYIjpbIjEiXX0sIm0x
+Ijp7IkFuIjpbIjEiXX0sInFJIjp7IkNQIjpbXSwiWloiOltdfSwiYlUiOnsiQ1AiOltdLCJJaiI6W10s
+IlpaIjpbXX0sImtEIjp7IkNQIjpbXSwiWloiOltdfSwiRHIiOnsicVUiOltdLCJ2WCI6W119LCJiUSI6
+eyJjWCI6WyIxIl19LCJCUiI6eyJjWCI6WyIyIl19LCJFNyI6eyJBbiI6WyIyIl19LCJaeSI6eyJCUiI6
+WyIxIiwiMiJdLCJjWCI6WyIyIl0sImNYLkUiOiIyIn0sIm9sIjp7Ilp5IjpbIjEiLCIyIl0sIkJSIjpb
+IjEiLCIyIl0sImJRIjpbIjIiXSwiY1giOlsiMiJdLCJjWC5FIjoiMiJ9LCJVcSI6eyJsRCI6WyIyIl0s
+InpNIjpbIjIiXSwiQlIiOlsiMSIsIjIiXSwiYlEiOlsiMiJdLCJjWCI6WyIyIl19LCJqViI6eyJVcSI6
+WyIxIiwiMiJdLCJsRCI6WyIyIl0sInpNIjpbIjIiXSwiQlIiOlsiMSIsIjIiXSwiYlEiOlsiMiJdLCJj
+WCI6WyIyIl0sImxELkUiOiIyIiwiY1guRSI6IjIifSwibiI6eyJYUyI6W119LCJyMyI6eyJYUyI6W119
+LCJxaiI6eyJsRCI6WyJJaiJdLCJSZSI6WyJJaiJdLCJ6TSI6WyJJaiJdLCJiUSI6WyJJaiJdLCJjWCI6
+WyJJaiJdLCJsRC5FIjoiSWoiLCJSZS5FIjoiSWoifSwiR00iOnsiWFMiOltdfSwiYUwiOnsiYlEiOlsi
+MSJdLCJjWCI6WyIxIl19LCJuSCI6eyJhTCI6WyIxIl0sImJRIjpbIjEiXSwiY1giOlsiMSJdLCJhTC5F
+IjoiMSIsImNYLkUiOiIxIn0sImE3Ijp7IkFuIjpbIjEiXX0sImkxIjp7ImNYIjpbIjIiXSwiY1guRSI6
+IjIifSwieHkiOnsiaTEiOlsiMSIsIjIiXSwiYlEiOlsiMiJdLCJjWCI6WyIyIl0sImNYLkUiOiIyIn0s
+Ik1IIjp7IkFuIjpbIjIiXX0sImxKIjp7ImFMIjpbIjIiXSwiYlEiOlsiMiJdLCJjWCI6WyIyIl0sImFM
+LkUiOiIyIiwiY1guRSI6IjIifSwiVTUiOnsiY1giOlsiMSJdLCJjWC5FIjoiMSJ9LCJTTyI6eyJBbiI6
+WyIxIl19LCJBTSI6eyJjWCI6WyIxIl0sImNYLkUiOiIxIn0sImQ1Ijp7IkFNIjpbIjEiXSwiYlEiOlsi
+MSJdLCJjWCI6WyIxIl0sImNYLkUiOiIxIn0sIlUxIjp7IkFuIjpbIjEiXX0sIk1CIjp7ImJRIjpbIjEi
+XSwiY1giOlsiMSJdLCJjWC5FIjoiMSJ9LCJGdSI6eyJBbiI6WyIxIl19LCJ1NiI6eyJjWCI6WyIxIl0s
+ImNYLkUiOiIxIn0sIkpCIjp7IkFuIjpbIjEiXX0sIncyIjp7ImxEIjpbIjEiXSwiUmUiOlsiMSJdLCJ6
+TSI6WyIxIl0sImJRIjpbIjEiXSwiY1giOlsiMSJdfSwid3YiOnsiR0QiOltdfSwiUEQiOnsiR2oiOlsi
+MSIsIjIiXSwiUlUiOlsiMSIsIjIiXSwiUG4iOlsiMSIsIjIiXSwiS1AiOlsiMSIsIjIiXSwiWjAiOlsi
+MSIsIjIiXX0sIldVIjp7IlowIjpbIjEiLCIyIl19LCJMUCI6eyJXVSI6WyIxIiwiMiJdLCJaMCI6WyIx
+IiwiMiJdfSwiWFIiOnsiY1giOlsiMSJdLCJjWC5FIjoiMSJ9LCJMSSI6eyJ2USI6W119LCJXMCI6eyJY
+UyI6W119LCJheiI6eyJYUyI6W119LCJ2ViI6eyJYUyI6W119LCJ0ZSI6eyJSeiI6W119LCJYTyI6eyJH
+eiI6W119LCJUcCI6eyJFSCI6W119LCJsYyI6eyJFSCI6W119LCJ6eCI6eyJFSCI6W119LCJyVCI6eyJF
+SCI6W119LCJFcSI6eyJYUyI6W119LCJrWSI6eyJYUyI6W119LCJONSI6eyJZayI6WyIxIiwiMiJdLCJG
+byI6WyIxIiwiMiJdLCJaMCI6WyIxIiwiMiJdLCJZay5LIjoiMSIsIllrLlYiOiIyIn0sImk1Ijp7ImJR
+IjpbIjEiXSwiY1giOlsiMSJdLCJjWC5FIjoiMSJ9LCJONiI6eyJBbiI6WyIxIl19LCJWUiI6eyJ3TCI6
+W10sInZYIjpbXX0sIkVLIjp7ImliIjpbXSwiT2QiOltdfSwiS1ciOnsiY1giOlsiaWIiXSwiY1guRSI6
+ImliIn0sIlBiIjp7IkFuIjpbImliIl19LCJ0USI6eyJPZCI6W119LCJ1biI6eyJjWCI6WyJPZCJdLCJj
+WC5FIjoiT2QifSwiU2QiOnsiQW4iOlsiT2QiXX0sIkVUIjp7IkFTIjpbXX0sIkxaIjp7IlhqIjpbIjEi
+XSwiRVQiOltdLCJBUyI6W119LCJEZyI6eyJsRCI6WyJDUCJdLCJYaiI6WyJDUCJdLCJ6TSI6WyJDUCJd
+LCJFVCI6W10sImJRIjpbIkNQIl0sIkFTIjpbXSwiY1giOlsiQ1AiXSwiU1UiOlsiQ1AiXSwibEQuRSI6
+IkNQIn0sIlBnIjp7ImxEIjpbIklqIl0sIlhqIjpbIklqIl0sInpNIjpbIklqIl0sIkVUIjpbXSwiYlEi
+OlsiSWoiXSwiQVMiOltdLCJjWCI6WyJJaiJdLCJTVSI6WyJJaiJdfSwieGoiOnsibEQiOlsiSWoiXSwi
+WGoiOlsiSWoiXSwiek0iOlsiSWoiXSwiRVQiOltdLCJiUSI6WyJJaiJdLCJBUyI6W10sImNYIjpbIklq
+Il0sIlNVIjpbIklqIl0sImxELkUiOiJJaiJ9LCJkRSI6eyJsRCI6WyJJaiJdLCJYaiI6WyJJaiJdLCJ6
+TSI6WyJJaiJdLCJFVCI6W10sImJRIjpbIklqIl0sIkFTIjpbXSwiY1giOlsiSWoiXSwiU1UiOlsiSWoi
+XSwibEQuRSI6IklqIn0sIlpBIjp7ImxEIjpbIklqIl0sIlhqIjpbIklqIl0sInpNIjpbIklqIl0sIkVU
+IjpbXSwiYlEiOlsiSWoiXSwiQVMiOltdLCJjWCI6WyJJaiJdLCJTVSI6WyJJaiJdLCJsRC5FIjoiSWoi
+fSwiZFQiOnsibEQiOlsiSWoiXSwiWGoiOlsiSWoiXSwiek0iOlsiSWoiXSwiRVQiOltdLCJiUSI6WyJJ
+aiJdLCJBUyI6W10sImNYIjpbIklqIl0sIlNVIjpbIklqIl0sImxELkUiOiJJaiJ9LCJQcSI6eyJsRCI6
+WyJJaiJdLCJYaiI6WyJJaiJdLCJ6TSI6WyJJaiJdLCJFVCI6W10sImJRIjpbIklqIl0sIkFTIjpbXSwi
+Y1giOlsiSWoiXSwiU1UiOlsiSWoiXSwibEQuRSI6IklqIn0sImVFIjp7ImxEIjpbIklqIl0sIlhqIjpb
+IklqIl0sInpNIjpbIklqIl0sIkVUIjpbXSwiYlEiOlsiSWoiXSwiQVMiOltdLCJjWCI6WyJJaiJdLCJT
+VSI6WyJJaiJdLCJsRC5FIjoiSWoifSwiVjYiOnsibEQiOlsiSWoiXSwibjYiOltdLCJYaiI6WyJJaiJd
+LCJ6TSI6WyJJaiJdLCJFVCI6W10sImJRIjpbIklqIl0sIkFTIjpbXSwiY1giOlsiSWoiXSwiU1UiOlsi
+SWoiXSwibEQuRSI6IklqIn0sImtTIjp7IlhTIjpbXX0sImlNIjp7IlhTIjpbXX0sInZzIjp7ImI4Ijpb
+IjEiXX0sIkdWIjp7IkFuIjpbIjEiXX0sInE0Ijp7ImNYIjpbIjEiXSwiY1guRSI6IjEifSwiQ3ciOnsi
+WFMiOltdfSwiWmYiOnsiUGYiOlsiMSJdfSwibTAiOnsiUW0iOltdfSwiSmkiOnsibTAiOltdLCJRbSI6
+W119LCJiNiI6eyJsZiI6WyIxIl0sInh1IjpbIjEiXSwiYlEiOlsiMSJdLCJjWCI6WyIxIl0sImxmLkUi
+OiIxIn0sImxtIjp7IkFuIjpbIjEiXX0sIm1XIjp7ImNYIjpbIjEiXX0sInV5Ijp7ImxEIjpbIjEiXSwi
+ek0iOlsiMSJdLCJiUSI6WyIxIl0sImNYIjpbIjEiXX0sImlsIjp7IllrIjpbIjEiLCIyIl0sIlowIjpb
+IjEiLCIyIl19LCJZayI6eyJaMCI6WyIxIiwiMiJdfSwiUG4iOnsiWjAiOlsiMSIsIjIiXX0sIkdqIjp7
+IlJVIjpbIjEiLCIyIl0sIlBuIjpbIjEiLCIyIl0sIktQIjpbIjEiLCIyIl0sIlowIjpbIjEiLCIyIl19
+LCJWaiI6eyJsZiI6WyIxIl0sInh1IjpbIjEiXSwiYlEiOlsiMSJdLCJjWCI6WyIxIl19LCJYdiI6eyJs
+ZiI6WyIxIl0sInh1IjpbIjEiXSwiYlEiOlsiMSJdLCJjWCI6WyIxIl19LCJ1dyI6eyJZayI6WyJxVSIs
+IkAiXSwiWjAiOlsicVUiLCJAIl0sIllrLksiOiJxVSIsIllrLlYiOiJAIn0sImk4Ijp7ImFMIjpbInFV
+Il0sImJRIjpbInFVIl0sImNYIjpbInFVIl0sImFMLkUiOiJxVSIsImNYLkUiOiJxVSJ9LCJDViI6eyJV
+ayI6WyJ6TTxJaj4iLCJxVSJdLCJVay5TIjoiek08SWo+In0sIlU4Ijp7IndJIjpbInpNPElqPiIsInFV
+Il19LCJaaSI6eyJVayI6WyJxVSIsInpNPElqPiJdfSwiVWQiOnsiWFMiOltdfSwiSzgiOnsiWFMiOltd
+fSwiYnkiOnsiVWsiOlsiTWg/IiwicVUiXSwiVWsuUyI6Ik1oPyJ9LCJvaiI6eyJ3SSI6WyJNaD8iLCJx
+VSJdfSwiTXgiOnsid0kiOlsicVUiLCJNaD8iXX0sInU1Ijp7IlVrIjpbInFVIiwiek08SWo+Il0sIlVr
+LlMiOiJxVSJ9LCJFMyI6eyJ3SSI6WyJxVSIsInpNPElqPiJdfSwiR1kiOnsid0kiOlsiek08SWo+Iiwi
+cVUiXX0sIkNQIjp7IlpaIjpbXX0sIklqIjp7IlpaIjpbXX0sInpNIjp7ImJRIjpbIjEiXSwiY1giOlsi
+MSJdfSwiaWIiOnsiT2QiOltdfSwieHUiOnsiYlEiOlsiMSJdLCJjWCI6WyIxIl19LCJxVSI6eyJ2WCI6
+W119LCJDNiI6eyJYUyI6W119LCJFeiI6eyJYUyI6W119LCJGIjp7IlhTIjpbXX0sInUiOnsiWFMiOltd
+fSwiYkoiOnsiWFMiOltdfSwiZVkiOnsiWFMiOltdfSwibXAiOnsiWFMiOltdfSwidWIiOnsiWFMiOltd
+fSwiZHMiOnsiWFMiOltdfSwibGoiOnsiWFMiOltdfSwiVVYiOnsiWFMiOltdfSwiazUiOnsiWFMiOltd
+fSwiS1kiOnsiWFMiOltdfSwiYyI6eyJYUyI6W119LCJDRCI6eyJSeiI6W119LCJhRSI6eyJSeiI6W119
+LCJaZCI6eyJHeiI6W119LCJSbiI6eyJCTCI6W119LCJEbiI6eyJpRCI6W119LCJVZiI6eyJpRCI6W119
+LCJxZSI6eyJpRCI6W119LCJjdiI6eyJ1SCI6W10sIkQwIjpbXX0sImZKIjp7IkQwIjpbXX0sIndhIjp7
+IkQwIjpbXX0sIkFqIjp7ImVhIjpbXX0sInVIIjp7IkQwIjpbXX0sImV3Ijp7ImVhIjpbXX0sInc2Ijp7
+ImVhIjpbXX0sIkpRIjp7ImtGIjpbXX0sInFFIjp7ImN2IjpbXSwidUgiOltdLCJEMCI6W119LCJHaCI6
+eyJjdiI6W10sInVIIjpbXSwiRDAiOltdfSwiZlkiOnsiY3YiOltdLCJ1SCI6W10sIkQwIjpbXX0sIm5C
+Ijp7ImN2IjpbXSwidUgiOltdLCJEMCI6W119LCJRUCI6eyJjdiI6W10sInVIIjpbXSwiRDAiOltdfSwi
+bngiOnsidUgiOltdLCJEMCI6W119LCJRRiI6eyJ1SCI6W10sIkQwIjpbXX0sIklCIjp7InRuIjpbIlpa
+Il19LCJ3eiI6eyJsRCI6WyIxIl0sInpNIjpbIjEiXSwiYlEiOlsiMSJdLCJjWCI6WyIxIl0sImxELkUi
+OiIxIn0sImhIIjp7IkF6IjpbXX0sImg0Ijp7ImN2IjpbXSwidUgiOltdLCJEMCI6W119LCJWYiI6eyJ1
+SCI6W10sIkQwIjpbXX0sImU3Ijp7ImxEIjpbInVIIl0sInpNIjpbInVIIl0sImJRIjpbInVIIl0sImNY
+IjpbInVIIl0sImxELkUiOiJ1SCJ9LCJCSCI6eyJsRCI6WyJ1SCJdLCJHbSI6WyJ1SCJdLCJ6TSI6WyJ1
+SCJdLCJYaiI6WyJ1SCJdLCJiUSI6WyJ1SCJdLCJjWCI6WyJ1SCJdLCJsRC5FIjoidUgiLCJHbS5FIjoi
+dUgifSwiU04iOnsiY3YiOltdLCJ1SCI6W10sIkQwIjpbXX0sImxwIjp7ImN2IjpbXSwidUgiOltdLCJE
+MCI6W119LCJUYiI6eyJjdiI6W10sInVIIjpbXSwiRDAiOltdfSwiSXYiOnsiY3YiOltdLCJ1SCI6W10s
+IkQwIjpbXX0sIldQIjp7ImN2IjpbXSwidUgiOltdLCJEMCI6W119LCJ5WSI6eyJjdiI6W10sInVIIjpb
+XSwiRDAiOltdfSwiSzUiOnsidjYiOltdLCJEMCI6W119LCJDbSI6eyJEMCI6W119LCJDUSI6eyJ1SCI6
+W10sIkQwIjpbXX0sInc0Ijp7InRuIjpbIlpaIl19LCJyaCI6eyJsRCI6WyJ1SCJdLCJHbSI6WyJ1SCJd
+LCJ6TSI6WyJ1SCJdLCJYaiI6WyJ1SCJdLCJiUSI6WyJ1SCJdLCJjWCI6WyJ1SCJdLCJsRC5FIjoidUgi
+LCJHbS5FIjoidUgifSwiY2YiOnsiWWsiOlsicVUiLCJxVSJdLCJaMCI6WyJxVSIsInFVIl19LCJpNyI6
+eyJZayI6WyJxVSIsInFVIl0sIlowIjpbInFVIiwicVUiXSwiWWsuSyI6InFVIiwiWWsuViI6InFVIn0s
+IlN5Ijp7IllrIjpbInFVIiwicVUiXSwiWjAiOlsicVUiLCJxVSJdLCJZay5LIjoicVUiLCJZay5WIjoi
+cVUifSwiSTQiOnsibGYiOlsicVUiXSwieHUiOlsicVUiXSwiYlEiOlsicVUiXSwiY1giOlsicVUiXSwi
+bGYuRSI6InFVIn0sIlJPIjp7InFoIjpbIjEiXX0sImV1Ijp7IlJPIjpbIjEiXSwicWgiOlsiMSJdfSwi
+eEMiOnsiTU8iOlsiMSJdfSwidkQiOnsia0YiOltdfSwibTYiOnsia0YiOltdfSwiY3QiOnsia0YiOltd
+fSwiT3ciOnsia0YiOltdfSwiVzkiOnsiQW4iOlsiMSJdfSwiZFciOnsidjYiOltdLCJEMCI6W119LCJt
+ayI6eyJ5MCI6W119LCJLbyI6eyJvbiI6W119LCJBcyI6eyJsZiI6WyJxVSJdLCJ4dSI6WyJxVSJdLCJi
+USI6WyJxVSJdLCJjWCI6WyJxVSJdfSwicjciOnsiRTQiOltdfSwiVHoiOnsibEQiOlsiMSJdLCJ6TSI6
+WyIxIl0sImJRIjpbIjEiXSwiRTQiOltdLCJjWCI6WyIxIl0sImxELkUiOiIxIn0sIm5kIjp7ImhpIjpb
+XSwiY3YiOltdLCJ1SCI6W10sIkQwIjpbXX0sIktlIjp7ImxmIjpbInFVIl0sInh1IjpbInFVIl0sImJR
+IjpbInFVIl0sImNYIjpbInFVIl0sImxmLkUiOiJxVSJ9LCJoaSI6eyJjdiI6W10sInVIIjpbXSwiRDAi
+OltdfSwiUVciOnsiWFMiOltdLCJSeiI6W119LCJYQSI6eyJrRiI6W119LCJ2dCI6eyJEOCI6W119LCJj
+RCI6eyJEOCI6W119LCJkdiI6eyJSeiI6W119LCJPRiI6eyJmdiI6W119LCJydSI6eyJmdiI6W119LCJJ
+ViI6eyJmdiI6W119LCJuNiI6eyJ6TSI6WyJJaiJdLCJiUSI6WyJJaiJdLCJjWCI6WyJJaiJdLCJBUyI6
+W119fScpKQpILkZGKHYudHlwZVVuaXZlcnNlLEpTT04ucGFyc2UoJ3sidzIiOjEsIlFDIjoyLCJMWiI6
+MSwia1QiOjIsIm1XIjoxLCJ1eSI6MSwiaWwiOjIsIlZqIjoxLCJYdiI6MSwiblkiOjEsIldZIjoxLCJw
+UiI6MSwiY28iOjF9JykpCnZhciB1PXtsOiJDYW5ub3QgZXh0cmFjdCBhIGZpbGUgcGF0aCBmcm9tIGEg
+VVJJIHdpdGggYSBmcmFnbWVudCBjb21wb25lbnQiLGk6IkNhbm5vdCBleHRyYWN0IGEgZmlsZSBwYXRo
+IGZyb20gYSBVUkkgd2l0aCBhIHF1ZXJ5IGNvbXBvbmVudCIsajoiQ2Fubm90IGV4dHJhY3QgYSBub24t
+V2luZG93cyBmaWxlIHBhdGggZnJvbSBhIGZpbGUgVVJJIHdpdGggYW4gYXV0aG9yaXR5IixnOiJgbnVs
+bGAgZW5jb3VudGVyZWQgYXMgdGhlIHJlc3VsdCBmcm9tIGV4cHJlc3Npb24gd2l0aCB0eXBlIGBOZXZl
+cmAuIixkOiJhcmVhLWFuYWx5emVyLGFuYWx5emVyLW5uYmQtbWlncmF0aW9uLHR5cGUtYnVnIn0KdmFy
+IHQ9KGZ1bmN0aW9uIHJ0aWkoKXt2YXIgcz1ILk4wCnJldHVybntuOnMoIkN3IiksY1I6cygibkIiKSx3
+OnMoIkF6IikscDpzKCJRUCIpLGdGOnMoIlBEPEdELEA+IiksZDpzKCJiUTxAPiIpLGg6cygiY3YiKSxy
+OnMoIlhTIiksQjpzKCJlYSIpLGFTOnMoIkQwIiksZzg6cygiUnoiKSxjODpzKCJoSCIpLFk6cygiRUgi
+KSxlOnMoImI4PEA+IiksSTpzKCJTZyIpLG86cygidlEiKSxlaDpzKCJjWDx1SD4iKSxROnMoImNYPHFV
+PiIpLHU6cygiY1g8QD4iKSx2OnMoImpkPGtGPiIpLHM6cygiamQ8cVU+IiksZ046cygiamQ8bjY+Iiks
+YjpzKCJqZDxAPiIpLGE6cygiamQ8SWo+IiksZDc6cygiamQ8U2UqPiIpLGg0OnMoImpkPGo4Kj4iKSxH
+OnMoImpkPFowPHFVKixNaCo+Kj4iKSxjUTpzKCJqZDxEOCo+IiksaTpzKCJqZDxxVSo+IiksYUE6cygi
+amQ8eUQqPiIpLGFKOnMoImpkPHdiKj4iKSxWOnMoImpkPElqKj4iKSxkNDpzKCJqZDxxVT8+IiksVDpz
+KCJ3ZSIpLGVIOnMoInZtIikseDpzKCJjNSIpLGFVOnMoIlhqPEA+IiksYW06cygiVHo8QD4iKSxlbzpz
+KCJONTxHRCxAPiIpLGR6OnMoImhGIiksRDpzKCJ6TTxxVT4iKSxqOnMoInpNPEA+IiksTDpzKCJ6TTxJ
+aj4iKSxKOnMoIlowPHFVLHFVPiIpLGY6cygiWjA8QCxAPiIpLGRvOnMoImxKPHFVLEA+IiksZmo6cygi
+bEo8cVUqLHFVPiIpLGZQOnMoImxKPHFVKixxVSo+IiksZEU6cygiRVQiKSxibTpzKCJWNiIpLEE6cygi
 dUgiKSxFOnMoImtGIiksUDpzKCJjOCIpLEs6cygiTWgiKSxxOnMoInRuPFpaPiIpLGZ2OnMoIndMIiks
 ZXc6cygibmQiKSxDOnMoInh1PHFVPiIpLGw6cygiR3oiKSxOOnMoInFVIiksZDA6cygicVUocVUqKSIp
 LGc3OnMoImhpIiksZm86cygiR0QiKSxhVzpzKCJ5WSIpLGFrOnMoIkFTIiksZ2M6cygibjYiKSxiSjpz
 KCJrZCIpLGR3OnMoIkdqPHFVLHFVPiIpLGREOnMoImlEIiksZUo6cygidTY8cVU+IiksZzQ6cygiSzUi
 KSxjaTpzKCJ2NiIpLGcyOnMoIkNtIiksYkM6cygiWmY8ZkoqPiIpLGg5OnMoIkNRIiksYWM6cygiZTci
-KSxrOnMoImV1PEFqKj4iKSxSOnMoInd6PGN2Kj4iKSxjOnMoInZzPEA+IiksZko6cygidnM8QjI+Iiks
+KSxrOnMoImV1PEFqKj4iKSxSOnMoInd6PGN2Kj4iKSxjOnMoInZzPEA+IiksZko6cygidnM8SWo+Iiks
 Z1Y6cygidnM8ZkoqPiIpLGNyOnMoIkpRIikseTpzKCJhMiIpLGFsOnMoImEyKE1oKSIpLGdSOnMoIkNQ
 IiksejpzKCJAIiksZk86cygiQCgpIiksYkk6cygiQChNaCkiKSxhZzpzKCJAKE1oLEd6KSIpLGJVOnMo
-IkAoeHU8cVU+KSIpLGRPOnMoIkAocVUpIiksYjg6cygiQChALEApIiksUzpzKCJCMiIpLGRkOnMoIkdo
+IkAoeHU8cVU+KSIpLGRPOnMoIkAocVUpIiksYjg6cygiQChALEApIiksUzpzKCJJaiIpLGRkOnMoIkdo
 KiIpLGc6cygiY3YqIiksYUw6cygiZWEqIiksYVg6cygiTEwqIiksZkU6cygiSDcqIiksVTpzKCJjWDxA
 PioiKSxkSDpzKCJFNCoiKSxmSzpzKCJ6TTxAPioiKSxkXzpzKCJ6TTxqOCo+KiIpLGRwOnMoInpNPFow
 PHFVKixNaCo+Kj4qIiksZUU6cygiek08TWgqPioiKSxhdzpzKCJaMDxALEA+KiIpLHQ6cygiWjA8cVUq
 LE1oKj4qIiksTzpzKCJBaioiKSxjRjpzKCIwJioiKSxfOnMoIk1oKiIpLGVROnMoImV3KiIpLFg6cygi
-cVUqIiksY2g6cygiRDA/IiksYkc6cygiYjg8Yzg+PyIpLGJrOnMoInpNPHFVPj8iKSxiTTpzKCJ6TTxA
-Pj8iKSxjWjpzKCJaMDxxVSxxVT4/IiksYzk6cygiWjA8cVUsQD4/IiksVzpzKCJNaD8iKSxGOnMoIkZl
-PEAsQD4/IiksbTpzKCJibj8iKSxiNzpzKCJhMihNaCk/IiksYnc6cygiQChlYSk/IiksZlY6cygiTWg/
-KE1oPyxNaD8pPyIpLGRBOnMoIk1oPyhAKT8iKSxaOnMoIn4oKT8iKSxlYjpzKCJ+KGV3Kik/IiksZGk6
-cygiWloiKSxIOnMoIn4iKSxNOnMoIn4oKSIpLGVBOnMoIn4ocVUscVUpIiksY0E6cygifihxVSxAKSIp
-fX0pKCk7KGZ1bmN0aW9uIGNvbnN0YW50cygpe3ZhciBzPWh1bmtIZWxwZXJzLm1ha2VDb25zdExpc3QK
-Qy54bj1XLkdoLnByb3RvdHlwZQpDLlJZPVcuUVAucHJvdG90eXBlCkMubUg9Vy5hZS5wcm90b3R5cGUK
-Qy5CWj1XLlZiLnByb3RvdHlwZQpDLkR0PVcuZkoucHJvdG90eXBlCkMuT2s9Si5Hdi5wcm90b3R5cGUK
-Qy5ObT1KLmpkLnByb3RvdHlwZQpDLmpuPUouYlUucHJvdG90eXBlCkMuak49Si53ZS5wcm90b3R5cGUK
-Qy5DRD1KLnFJLnByb3RvdHlwZQpDLnhCPUouRHIucHJvdG90eXBlCkMuREc9Si5jNS5wcm90b3R5cGUK
-Qy5FeD1XLnc3LnByb3RvdHlwZQpDLk5BPUguVjYucHJvdG90eXBlCkMudDU9Vy5CSC5wcm90b3R5cGUK
-Qy5MdD1XLlNOLnByb3RvdHlwZQpDLlpRPUouaUMucHJvdG90eXBlCkMuSWU9Vy5UYi5wcm90b3R5cGUK
-Qy52Qj1KLmtkLnByb3RvdHlwZQpDLm9sPVcuSzUucHJvdG90eXBlCkMueTg9bmV3IFAuVTgoKQpDLmg5
-PW5ldyBQLkNWKCkKQy5Hdz1uZXcgSC5GdShILk4wKCJGdTwwJio+IikpCkMuTzQ9ZnVuY3Rpb24gZ2V0
-VGFnRmFsbGJhY2sobykgewogIHZhciBzID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG8p
-OwogIHJldHVybiBzLnN1YnN0cmluZyg4LCBzLmxlbmd0aCAtIDEpOwp9CkMuWXE9ZnVuY3Rpb24oKSB7
-CiAgdmFyIHRvU3RyaW5nRnVuY3Rpb24gPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nOwogIGZ1bmN0
-aW9uIGdldFRhZyhvKSB7CiAgICB2YXIgcyA9IHRvU3RyaW5nRnVuY3Rpb24uY2FsbChvKTsKICAgIHJl
-dHVybiBzLnN1YnN0cmluZyg4LCBzLmxlbmd0aCAtIDEpOwogIH0KICBmdW5jdGlvbiBnZXRVbmtub3du
-VGFnKG9iamVjdCwgdGFnKSB7CiAgICBpZiAoL15IVE1MW0EtWl0uKkVsZW1lbnQkLy50ZXN0KHRhZykp
-IHsKICAgICAgdmFyIG5hbWUgPSB0b1N0cmluZ0Z1bmN0aW9uLmNhbGwob2JqZWN0KTsKICAgICAgaWYg
-KG5hbWUgPT0gIltvYmplY3QgT2JqZWN0XSIpIHJldHVybiBudWxsOwogICAgICByZXR1cm4gIkhUTUxF
-bGVtZW50IjsKICAgIH0KICB9CiAgZnVuY3Rpb24gZ2V0VW5rbm93blRhZ0dlbmVyaWNCcm93c2VyKG9i
-amVjdCwgdGFnKSB7CiAgICBpZiAoc2VsZi5IVE1MRWxlbWVudCAmJiBvYmplY3QgaW5zdGFuY2VvZiBI
-VE1MRWxlbWVudCkgcmV0dXJuICJIVE1MRWxlbWVudCI7CiAgICByZXR1cm4gZ2V0VW5rbm93blRhZyhv
-YmplY3QsIHRhZyk7CiAgfQogIGZ1bmN0aW9uIHByb3RvdHlwZUZvclRhZyh0YWcpIHsKICAgIGlmICh0
-eXBlb2Ygd2luZG93ID09ICJ1bmRlZmluZWQiKSByZXR1cm4gbnVsbDsKICAgIGlmICh0eXBlb2Ygd2lu
-ZG93W3RhZ10gPT0gInVuZGVmaW5lZCIpIHJldHVybiBudWxsOwogICAgdmFyIGNvbnN0cnVjdG9yID0g
-d2luZG93W3RhZ107CiAgICBpZiAodHlwZW9mIGNvbnN0cnVjdG9yICE9ICJmdW5jdGlvbiIpIHJldHVy
-biBudWxsOwogICAgcmV0dXJuIGNvbnN0cnVjdG9yLnByb3RvdHlwZTsKICB9CiAgZnVuY3Rpb24gZGlz
-Y3JpbWluYXRvcih0YWcpIHsgcmV0dXJuIG51bGw7IH0KICB2YXIgaXNCcm93c2VyID0gdHlwZW9mIG5h
-dmlnYXRvciA9PSAib2JqZWN0IjsKICByZXR1cm4gewogICAgZ2V0VGFnOiBnZXRUYWcsCiAgICBnZXRV
-bmtub3duVGFnOiBpc0Jyb3dzZXIgPyBnZXRVbmtub3duVGFnR2VuZXJpY0Jyb3dzZXIgOiBnZXRVbmtu
-b3duVGFnLAogICAgcHJvdG90eXBlRm9yVGFnOiBwcm90b3R5cGVGb3JUYWcsCiAgICBkaXNjcmltaW5h
-dG9yOiBkaXNjcmltaW5hdG9yIH07Cn0KQy53Yj1mdW5jdGlvbihnZXRUYWdGYWxsYmFjaykgewogIHJl
-dHVybiBmdW5jdGlvbihob29rcykgewogICAgaWYgKHR5cGVvZiBuYXZpZ2F0b3IgIT0gIm9iamVjdCIp
-IHJldHVybiBob29rczsKICAgIHZhciB1YSA9IG5hdmlnYXRvci51c2VyQWdlbnQ7CiAgICBpZiAodWEu
-aW5kZXhPZigiRHVtcFJlbmRlclRyZWUiKSA+PSAwKSByZXR1cm4gaG9va3M7CiAgICBpZiAodWEuaW5k
-ZXhPZigiQ2hyb21lIikgPj0gMCkgewogICAgICBmdW5jdGlvbiBjb25maXJtKHApIHsKICAgICAgICBy
-ZXR1cm4gdHlwZW9mIHdpbmRvdyA9PSAib2JqZWN0IiAmJiB3aW5kb3dbcF0gJiYgd2luZG93W3BdLm5h
-bWUgPT0gcDsKICAgICAgfQogICAgICBpZiAoY29uZmlybSgiV2luZG93IikgJiYgY29uZmlybSgiSFRN
-TEVsZW1lbnQiKSkgcmV0dXJuIGhvb2tzOwogICAgfQogICAgaG9va3MuZ2V0VGFnID0gZ2V0VGFnRmFs
-bGJhY2s7CiAgfTsKfQpDLktVPWZ1bmN0aW9uKGhvb2tzKSB7CiAgaWYgKHR5cGVvZiBkYXJ0RXhwZXJp
-bWVudGFsRml4dXBHZXRUYWcgIT0gImZ1bmN0aW9uIikgcmV0dXJuIGhvb2tzOwogIGhvb2tzLmdldFRh
-ZyA9IGRhcnRFeHBlcmltZW50YWxGaXh1cEdldFRhZyhob29rcy5nZXRUYWcpOwp9CkMuZlE9ZnVuY3Rp
-b24oaG9va3MpIHsKICB2YXIgZ2V0VGFnID0gaG9va3MuZ2V0VGFnOwogIHZhciBwcm90b3R5cGVGb3JU
-YWcgPSBob29rcy5wcm90b3R5cGVGb3JUYWc7CiAgZnVuY3Rpb24gZ2V0VGFnRml4ZWQobykgewogICAg
-dmFyIHRhZyA9IGdldFRhZyhvKTsKICAgIGlmICh0YWcgPT0gIkRvY3VtZW50IikgewogICAgICBpZiAo
-ISFvLnhtbFZlcnNpb24pIHJldHVybiAiIURvY3VtZW50IjsKICAgICAgcmV0dXJuICIhSFRNTERvY3Vt
-ZW50IjsKICAgIH0KICAgIHJldHVybiB0YWc7CiAgfQogIGZ1bmN0aW9uIHByb3RvdHlwZUZvclRhZ0Zp
-eGVkKHRhZykgewogICAgaWYgKHRhZyA9PSAiRG9jdW1lbnQiKSByZXR1cm4gbnVsbDsKICAgIHJldHVy
-biBwcm90b3R5cGVGb3JUYWcodGFnKTsKICB9CiAgaG9va3MuZ2V0VGFnID0gZ2V0VGFnRml4ZWQ7CiAg
-aG9va3MucHJvdG90eXBlRm9yVGFnID0gcHJvdG90eXBlRm9yVGFnRml4ZWQ7Cn0KQy5kaz1mdW5jdGlv
-bihob29rcykgewogIHZhciB1c2VyQWdlbnQgPSB0eXBlb2YgbmF2aWdhdG9yID09ICJvYmplY3QiID8g
-bmF2aWdhdG9yLnVzZXJBZ2VudCA6ICIiOwogIGlmICh1c2VyQWdlbnQuaW5kZXhPZigiRmlyZWZveCIp
-ID09IC0xKSByZXR1cm4gaG9va3M7CiAgdmFyIGdldFRhZyA9IGhvb2tzLmdldFRhZzsKICB2YXIgcXVp
-Y2tNYXAgPSB7CiAgICAiQmVmb3JlVW5sb2FkRXZlbnQiOiAiRXZlbnQiLAogICAgIkRhdGFUcmFuc2Zl
-ciI6ICJDbGlwYm9hcmQiLAogICAgIkdlb0dlb2xvY2F0aW9uIjogIkdlb2xvY2F0aW9uIiwKICAgICJM
-b2NhdGlvbiI6ICIhTG9jYXRpb24iLAogICAgIldvcmtlck1lc3NhZ2VFdmVudCI6ICJNZXNzYWdlRXZl
-bnQiLAogICAgIlhNTERvY3VtZW50IjogIiFEb2N1bWVudCJ9OwogIGZ1bmN0aW9uIGdldFRhZ0ZpcmVm
-b3gobykgewogICAgdmFyIHRhZyA9IGdldFRhZyhvKTsKICAgIHJldHVybiBxdWlja01hcFt0YWddIHx8
-IHRhZzsKICB9CiAgaG9va3MuZ2V0VGFnID0gZ2V0VGFnRmlyZWZveDsKfQpDLnhpPWZ1bmN0aW9uKGhv
-b2tzKSB7CiAgdmFyIHVzZXJBZ2VudCA9IHR5cGVvZiBuYXZpZ2F0b3IgPT0gIm9iamVjdCIgPyBuYXZp
-Z2F0b3IudXNlckFnZW50IDogIiI7CiAgaWYgKHVzZXJBZ2VudC5pbmRleE9mKCJUcmlkZW50LyIpID09
+cVUqIiksZXE6cygicVUqKHFVKikiKSxjaDpzKCJEMD8iKSxiRzpzKCJiODxjOD4/IiksYms6cygiek08
+cVU+PyIpLGJNOnMoInpNPEA+PyIpLGNaOnMoIlowPHFVLHFVPj8iKSxjOTpzKCJaMDxxVSxAPj8iKSxX
+OnMoIk1oPyIpLEY6cygiRmU8QCxAPj8iKSxtOnMoImJuPyIpLGI3OnMoImEyKE1oKT8iKSxidzpzKCJA
+KGVhKT8iKSxmVjpzKCJNaD8oTWg/LE1oPyk/IiksZEE6cygiTWg/KEApPyIpLFo6cygifigpPyIpLGVi
+OnMoIn4oZXcqKT8iKSxkaTpzKCJaWiIpLEg6cygifiIpLE06cygifigpIiksZUE6cygifihxVSxxVSki
+KSxjQTpzKCJ+KHFVLEApIil9fSkoKTsoZnVuY3Rpb24gY29uc3RhbnRzKCl7dmFyIHM9aHVua0hlbHBl
+cnMubWFrZUNvbnN0TGlzdApDLnhuPVcuR2gucHJvdG90eXBlCkMuUlk9Vy5RUC5wcm90b3R5cGUKQy5t
+SD1XLmFlLnByb3RvdHlwZQpDLkJaPVcuVmIucHJvdG90eXBlCkMuRHQ9Vy5mSi5wcm90b3R5cGUKQy5P
+az1KLkd2LnByb3RvdHlwZQpDLk5tPUouamQucHJvdG90eXBlCkMuam49Si5iVS5wcm90b3R5cGUKQy5D
+RD1KLnFJLnByb3RvdHlwZQpDLnhCPUouRHIucHJvdG90eXBlCkMuREc9Si5jNS5wcm90b3R5cGUKQy5F
+eD1XLnc3LnByb3RvdHlwZQpDLk5BPUguVjYucHJvdG90eXBlCkMudDU9Vy5CSC5wcm90b3R5cGUKQy5M
+dD1XLlNOLnByb3RvdHlwZQpDLlpRPUouaUMucHJvdG90eXBlCkMuSWU9Vy5UYi5wcm90b3R5cGUKQy52
+Qj1KLmtkLnByb3RvdHlwZQpDLm9sPVcuSzUucHJvdG90eXBlCkMueTg9bmV3IFAuVTgoKQpDLmg5PW5l
+dyBQLkNWKCkKQy5Hdz1uZXcgSC5GdShILk4wKCJGdTwwJio+IikpCkMuTzQ9ZnVuY3Rpb24gZ2V0VGFn
+RmFsbGJhY2sobykgewogIHZhciBzID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG8pOwog
+IHJldHVybiBzLnN1YnN0cmluZyg4LCBzLmxlbmd0aCAtIDEpOwp9CkMuWXE9ZnVuY3Rpb24oKSB7CiAg
+dmFyIHRvU3RyaW5nRnVuY3Rpb24gPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nOwogIGZ1bmN0aW9u
+IGdldFRhZyhvKSB7CiAgICB2YXIgcyA9IHRvU3RyaW5nRnVuY3Rpb24uY2FsbChvKTsKICAgIHJldHVy
+biBzLnN1YnN0cmluZyg4LCBzLmxlbmd0aCAtIDEpOwogIH0KICBmdW5jdGlvbiBnZXRVbmtub3duVGFn
+KG9iamVjdCwgdGFnKSB7CiAgICBpZiAoL15IVE1MW0EtWl0uKkVsZW1lbnQkLy50ZXN0KHRhZykpIHsK
+ICAgICAgdmFyIG5hbWUgPSB0b1N0cmluZ0Z1bmN0aW9uLmNhbGwob2JqZWN0KTsKICAgICAgaWYgKG5h
+bWUgPT0gIltvYmplY3QgT2JqZWN0XSIpIHJldHVybiBudWxsOwogICAgICByZXR1cm4gIkhUTUxFbGVt
+ZW50IjsKICAgIH0KICB9CiAgZnVuY3Rpb24gZ2V0VW5rbm93blRhZ0dlbmVyaWNCcm93c2VyKG9iamVj
+dCwgdGFnKSB7CiAgICBpZiAoc2VsZi5IVE1MRWxlbWVudCAmJiBvYmplY3QgaW5zdGFuY2VvZiBIVE1M
+RWxlbWVudCkgcmV0dXJuICJIVE1MRWxlbWVudCI7CiAgICByZXR1cm4gZ2V0VW5rbm93blRhZyhvYmpl
+Y3QsIHRhZyk7CiAgfQogIGZ1bmN0aW9uIHByb3RvdHlwZUZvclRhZyh0YWcpIHsKICAgIGlmICh0eXBl
+b2Ygd2luZG93ID09ICJ1bmRlZmluZWQiKSByZXR1cm4gbnVsbDsKICAgIGlmICh0eXBlb2Ygd2luZG93
+W3RhZ10gPT0gInVuZGVmaW5lZCIpIHJldHVybiBudWxsOwogICAgdmFyIGNvbnN0cnVjdG9yID0gd2lu
+ZG93W3RhZ107CiAgICBpZiAodHlwZW9mIGNvbnN0cnVjdG9yICE9ICJmdW5jdGlvbiIpIHJldHVybiBu
+dWxsOwogICAgcmV0dXJuIGNvbnN0cnVjdG9yLnByb3RvdHlwZTsKICB9CiAgZnVuY3Rpb24gZGlzY3Jp
+bWluYXRvcih0YWcpIHsgcmV0dXJuIG51bGw7IH0KICB2YXIgaXNCcm93c2VyID0gdHlwZW9mIG5hdmln
+YXRvciA9PSAib2JqZWN0IjsKICByZXR1cm4gewogICAgZ2V0VGFnOiBnZXRUYWcsCiAgICBnZXRVbmtu
+b3duVGFnOiBpc0Jyb3dzZXIgPyBnZXRVbmtub3duVGFnR2VuZXJpY0Jyb3dzZXIgOiBnZXRVbmtub3du
+VGFnLAogICAgcHJvdG90eXBlRm9yVGFnOiBwcm90b3R5cGVGb3JUYWcsCiAgICBkaXNjcmltaW5hdG9y
+OiBkaXNjcmltaW5hdG9yIH07Cn0KQy53Yj1mdW5jdGlvbihnZXRUYWdGYWxsYmFjaykgewogIHJldHVy
+biBmdW5jdGlvbihob29rcykgewogICAgaWYgKHR5cGVvZiBuYXZpZ2F0b3IgIT0gIm9iamVjdCIpIHJl
+dHVybiBob29rczsKICAgIHZhciB1YSA9IG5hdmlnYXRvci51c2VyQWdlbnQ7CiAgICBpZiAodWEuaW5k
+ZXhPZigiRHVtcFJlbmRlclRyZWUiKSA+PSAwKSByZXR1cm4gaG9va3M7CiAgICBpZiAodWEuaW5kZXhP
+ZigiQ2hyb21lIikgPj0gMCkgewogICAgICBmdW5jdGlvbiBjb25maXJtKHApIHsKICAgICAgICByZXR1
+cm4gdHlwZW9mIHdpbmRvdyA9PSAib2JqZWN0IiAmJiB3aW5kb3dbcF0gJiYgd2luZG93W3BdLm5hbWUg
+PT0gcDsKICAgICAgfQogICAgICBpZiAoY29uZmlybSgiV2luZG93IikgJiYgY29uZmlybSgiSFRNTEVs
+ZW1lbnQiKSkgcmV0dXJuIGhvb2tzOwogICAgfQogICAgaG9va3MuZ2V0VGFnID0gZ2V0VGFnRmFsbGJh
+Y2s7CiAgfTsKfQpDLktVPWZ1bmN0aW9uKGhvb2tzKSB7CiAgaWYgKHR5cGVvZiBkYXJ0RXhwZXJpbWVu
+dGFsRml4dXBHZXRUYWcgIT0gImZ1bmN0aW9uIikgcmV0dXJuIGhvb2tzOwogIGhvb2tzLmdldFRhZyA9
+IGRhcnRFeHBlcmltZW50YWxGaXh1cEdldFRhZyhob29rcy5nZXRUYWcpOwp9CkMuZlE9ZnVuY3Rpb24o
+aG9va3MpIHsKICB2YXIgZ2V0VGFnID0gaG9va3MuZ2V0VGFnOwogIHZhciBwcm90b3R5cGVGb3JUYWcg
+PSBob29rcy5wcm90b3R5cGVGb3JUYWc7CiAgZnVuY3Rpb24gZ2V0VGFnRml4ZWQobykgewogICAgdmFy
+IHRhZyA9IGdldFRhZyhvKTsKICAgIGlmICh0YWcgPT0gIkRvY3VtZW50IikgewogICAgICBpZiAoISFv
+LnhtbFZlcnNpb24pIHJldHVybiAiIURvY3VtZW50IjsKICAgICAgcmV0dXJuICIhSFRNTERvY3VtZW50
+IjsKICAgIH0KICAgIHJldHVybiB0YWc7CiAgfQogIGZ1bmN0aW9uIHByb3RvdHlwZUZvclRhZ0ZpeGVk
+KHRhZykgewogICAgaWYgKHRhZyA9PSAiRG9jdW1lbnQiKSByZXR1cm4gbnVsbDsKICAgIHJldHVybiBw
+cm90b3R5cGVGb3JUYWcodGFnKTsKICB9CiAgaG9va3MuZ2V0VGFnID0gZ2V0VGFnRml4ZWQ7CiAgaG9v
+a3MucHJvdG90eXBlRm9yVGFnID0gcHJvdG90eXBlRm9yVGFnRml4ZWQ7Cn0KQy5kaz1mdW5jdGlvbiho
+b29rcykgewogIHZhciB1c2VyQWdlbnQgPSB0eXBlb2YgbmF2aWdhdG9yID09ICJvYmplY3QiID8gbmF2
+aWdhdG9yLnVzZXJBZ2VudCA6ICIiOwogIGlmICh1c2VyQWdlbnQuaW5kZXhPZigiRmlyZWZveCIpID09
 IC0xKSByZXR1cm4gaG9va3M7CiAgdmFyIGdldFRhZyA9IGhvb2tzLmdldFRhZzsKICB2YXIgcXVpY2tN
 YXAgPSB7CiAgICAiQmVmb3JlVW5sb2FkRXZlbnQiOiAiRXZlbnQiLAogICAgIkRhdGFUcmFuc2ZlciI6
-ICJDbGlwYm9hcmQiLAogICAgIkhUTUxEREVsZW1lbnQiOiAiSFRNTEVsZW1lbnQiLAogICAgIkhUTUxE
-VEVsZW1lbnQiOiAiSFRNTEVsZW1lbnQiLAogICAgIkhUTUxQaHJhc2VFbGVtZW50IjogIkhUTUxFbGVt
-ZW50IiwKICAgICJQb3NpdGlvbiI6ICJHZW9wb3NpdGlvbiIKICB9OwogIGZ1bmN0aW9uIGdldFRhZ0lF
-KG8pIHsKICAgIHZhciB0YWcgPSBnZXRUYWcobyk7CiAgICB2YXIgbmV3VGFnID0gcXVpY2tNYXBbdGFn
-XTsKICAgIGlmIChuZXdUYWcpIHJldHVybiBuZXdUYWc7CiAgICBpZiAodGFnID09ICJPYmplY3QiKSB7
-CiAgICAgIGlmICh3aW5kb3cuRGF0YVZpZXcgJiYgKG8gaW5zdGFuY2VvZiB3aW5kb3cuRGF0YVZpZXcp
-KSByZXR1cm4gIkRhdGFWaWV3IjsKICAgIH0KICAgIHJldHVybiB0YWc7CiAgfQogIGZ1bmN0aW9uIHBy
-b3RvdHlwZUZvclRhZ0lFKHRhZykgewogICAgdmFyIGNvbnN0cnVjdG9yID0gd2luZG93W3RhZ107CiAg
-ICBpZiAoY29uc3RydWN0b3IgPT0gbnVsbCkgcmV0dXJuIG51bGw7CiAgICByZXR1cm4gY29uc3RydWN0
-b3IucHJvdG90eXBlOwogIH0KICBob29rcy5nZXRUYWcgPSBnZXRUYWdJRTsKICBob29rcy5wcm90b3R5
-cGVGb3JUYWcgPSBwcm90b3R5cGVGb3JUYWdJRTsKfQpDLmk3PWZ1bmN0aW9uKGhvb2tzKSB7IHJldHVy
-biBob29rczsgfQoKQy5DdD1uZXcgUC5ieSgpCkMuRXE9bmV3IFAuazUoKQpDLnhNPW5ldyBQLnU1KCkK
-Qy5Raz1uZXcgUC5FMygpCkMuTnY9bmV3IEgua3IoKQpDLk5VPW5ldyBQLkppKCkKQy5wZD1uZXcgUC5a
-ZCgpCkMuQWQ9bmV3IFIuSDcoMCwiSGludEFjdGlvbktpbmQuYWRkTnVsbGFibGVIaW50IikKQy5uZT1u
-ZXcgUi5INygxLCJIaW50QWN0aW9uS2luZC5hZGROb25OdWxsYWJsZUhpbnQiKQpDLm15PW5ldyBSLkg3
-KDIsIkhpbnRBY3Rpb25LaW5kLmNoYW5nZVRvTnVsbGFibGVIaW50IikKQy5yeD1uZXcgUi5INygzLCJI
-aW50QWN0aW9uS2luZC5jaGFuZ2VUb05vbk51bGxhYmxlSGludCIpCkMud1Y9bmV3IFIuSDcoNCwiSGlu
-dEFjdGlvbktpbmQucmVtb3ZlTnVsbGFibGVIaW50IikKQy5mUj1uZXcgUi5INyg1LCJIaW50QWN0aW9u
-S2luZC5yZW1vdmVOb25OdWxsYWJsZUhpbnQiKQpDLkEzPW5ldyBQLk14KG51bGwpCkMublg9bmV3IFAu
-b2oobnVsbCkKQy5jdz1uZXcgTC5HYigwLCJVbml0TWlncmF0aW9uU3RhdHVzLmFscmVhZHlNaWdyYXRl
-ZCIpCkMuZGM9bmV3IEwuR2IoMSwiVW5pdE1pZ3JhdGlvblN0YXR1cy5pbmRldGVybWluYXRlIikKQy5X
-RD1uZXcgTC5HYigyLCJVbml0TWlncmF0aW9uU3RhdHVzLm1pZ3JhdGluZyIpCkMuWGo9bmV3IEwuR2Io
-MywiVW5pdE1pZ3JhdGlvblN0YXR1cy5vcHRpbmdPdXQiKQpDLmwwPUguVk0ocyhbQy5jdyxDLmRjLEMu
-V0QsQy5Yal0pLEguTjAoImpkPEdiKj4iKSkKQy5haz1ILlZNKHMoWzAsMCwzMjc3NiwzMzc5MiwxLDEw
-MjQwLDAsMF0pLHQuVikKQy5jbT1ILlZNKHMoWyIqOjpjbGFzcyIsIio6OmRpciIsIio6OmRyYWdnYWJs
-ZSIsIio6OmhpZGRlbiIsIio6OmlkIiwiKjo6aW5lcnQiLCIqOjppdGVtcHJvcCIsIio6Oml0ZW1yZWYi
-LCIqOjppdGVtc2NvcGUiLCIqOjpsYW5nIiwiKjo6c3BlbGxjaGVjayIsIio6OnRpdGxlIiwiKjo6dHJh
-bnNsYXRlIiwiQTo6YWNjZXNza2V5IiwiQTo6Y29vcmRzIiwiQTo6aHJlZmxhbmciLCJBOjpuYW1lIiwi
-QTo6c2hhcGUiLCJBOjp0YWJpbmRleCIsIkE6OnRhcmdldCIsIkE6OnR5cGUiLCJBUkVBOjphY2Nlc3Nr
-ZXkiLCJBUkVBOjphbHQiLCJBUkVBOjpjb29yZHMiLCJBUkVBOjpub2hyZWYiLCJBUkVBOjpzaGFwZSIs
-IkFSRUE6OnRhYmluZGV4IiwiQVJFQTo6dGFyZ2V0IiwiQVVESU86OmNvbnRyb2xzIiwiQVVESU86Omxv
-b3AiLCJBVURJTzo6bWVkaWFncm91cCIsIkFVRElPOjptdXRlZCIsIkFVRElPOjpwcmVsb2FkIiwiQkRP
-OjpkaXIiLCJCT0RZOjphbGluayIsIkJPRFk6OmJnY29sb3IiLCJCT0RZOjpsaW5rIiwiQk9EWTo6dGV4
-dCIsIkJPRFk6OnZsaW5rIiwiQlI6OmNsZWFyIiwiQlVUVE9OOjphY2Nlc3NrZXkiLCJCVVRUT046OmRp
-c2FibGVkIiwiQlVUVE9OOjpuYW1lIiwiQlVUVE9OOjp0YWJpbmRleCIsIkJVVFRPTjo6dHlwZSIsIkJV
-VFRPTjo6dmFsdWUiLCJDQU5WQVM6OmhlaWdodCIsIkNBTlZBUzo6d2lkdGgiLCJDQVBUSU9OOjphbGln
-biIsIkNPTDo6YWxpZ24iLCJDT0w6OmNoYXIiLCJDT0w6OmNoYXJvZmYiLCJDT0w6OnNwYW4iLCJDT0w6
-OnZhbGlnbiIsIkNPTDo6d2lkdGgiLCJDT0xHUk9VUDo6YWxpZ24iLCJDT0xHUk9VUDo6Y2hhciIsIkNP
-TEdST1VQOjpjaGFyb2ZmIiwiQ09MR1JPVVA6OnNwYW4iLCJDT0xHUk9VUDo6dmFsaWduIiwiQ09MR1JP
-VVA6OndpZHRoIiwiQ09NTUFORDo6Y2hlY2tlZCIsIkNPTU1BTkQ6OmNvbW1hbmQiLCJDT01NQU5EOjpk
-aXNhYmxlZCIsIkNPTU1BTkQ6OmxhYmVsIiwiQ09NTUFORDo6cmFkaW9ncm91cCIsIkNPTU1BTkQ6OnR5
-cGUiLCJEQVRBOjp2YWx1ZSIsIkRFTDo6ZGF0ZXRpbWUiLCJERVRBSUxTOjpvcGVuIiwiRElSOjpjb21w
-YWN0IiwiRElWOjphbGlnbiIsIkRMOjpjb21wYWN0IiwiRklFTERTRVQ6OmRpc2FibGVkIiwiRk9OVDo6
-Y29sb3IiLCJGT05UOjpmYWNlIiwiRk9OVDo6c2l6ZSIsIkZPUk06OmFjY2VwdCIsIkZPUk06OmF1dG9j
-b21wbGV0ZSIsIkZPUk06OmVuY3R5cGUiLCJGT1JNOjptZXRob2QiLCJGT1JNOjpuYW1lIiwiRk9STTo6
-bm92YWxpZGF0ZSIsIkZPUk06OnRhcmdldCIsIkZSQU1FOjpuYW1lIiwiSDE6OmFsaWduIiwiSDI6OmFs
-aWduIiwiSDM6OmFsaWduIiwiSDQ6OmFsaWduIiwiSDU6OmFsaWduIiwiSDY6OmFsaWduIiwiSFI6OmFs
-aWduIiwiSFI6Om5vc2hhZGUiLCJIUjo6c2l6ZSIsIkhSOjp3aWR0aCIsIkhUTUw6OnZlcnNpb24iLCJJ
-RlJBTUU6OmFsaWduIiwiSUZSQU1FOjpmcmFtZWJvcmRlciIsIklGUkFNRTo6aGVpZ2h0IiwiSUZSQU1F
-OjptYXJnaW5oZWlnaHQiLCJJRlJBTUU6Om1hcmdpbndpZHRoIiwiSUZSQU1FOjp3aWR0aCIsIklNRzo6
-YWxpZ24iLCJJTUc6OmFsdCIsIklNRzo6Ym9yZGVyIiwiSU1HOjpoZWlnaHQiLCJJTUc6OmhzcGFjZSIs
-IklNRzo6aXNtYXAiLCJJTUc6Om5hbWUiLCJJTUc6OnVzZW1hcCIsIklNRzo6dnNwYWNlIiwiSU1HOjp3
-aWR0aCIsIklOUFVUOjphY2NlcHQiLCJJTlBVVDo6YWNjZXNza2V5IiwiSU5QVVQ6OmFsaWduIiwiSU5Q
-VVQ6OmFsdCIsIklOUFVUOjphdXRvY29tcGxldGUiLCJJTlBVVDo6YXV0b2ZvY3VzIiwiSU5QVVQ6OmNo
-ZWNrZWQiLCJJTlBVVDo6ZGlzYWJsZWQiLCJJTlBVVDo6aW5wdXRtb2RlIiwiSU5QVVQ6OmlzbWFwIiwi
-SU5QVVQ6Omxpc3QiLCJJTlBVVDo6bWF4IiwiSU5QVVQ6Om1heGxlbmd0aCIsIklOUFVUOjptaW4iLCJJ
-TlBVVDo6bXVsdGlwbGUiLCJJTlBVVDo6bmFtZSIsIklOUFVUOjpwbGFjZWhvbGRlciIsIklOUFVUOjpy
-ZWFkb25seSIsIklOUFVUOjpyZXF1aXJlZCIsIklOUFVUOjpzaXplIiwiSU5QVVQ6OnN0ZXAiLCJJTlBV
-VDo6dGFiaW5kZXgiLCJJTlBVVDo6dHlwZSIsIklOUFVUOjp1c2VtYXAiLCJJTlBVVDo6dmFsdWUiLCJJ
-TlM6OmRhdGV0aW1lIiwiS0VZR0VOOjpkaXNhYmxlZCIsIktFWUdFTjo6a2V5dHlwZSIsIktFWUdFTjo6
-bmFtZSIsIkxBQkVMOjphY2Nlc3NrZXkiLCJMQUJFTDo6Zm9yIiwiTEVHRU5EOjphY2Nlc3NrZXkiLCJM
-RUdFTkQ6OmFsaWduIiwiTEk6OnR5cGUiLCJMSTo6dmFsdWUiLCJMSU5LOjpzaXplcyIsIk1BUDo6bmFt
-ZSIsIk1FTlU6OmNvbXBhY3QiLCJNRU5VOjpsYWJlbCIsIk1FTlU6OnR5cGUiLCJNRVRFUjo6aGlnaCIs
-Ik1FVEVSOjpsb3ciLCJNRVRFUjo6bWF4IiwiTUVURVI6Om1pbiIsIk1FVEVSOjp2YWx1ZSIsIk9CSkVD
-VDo6dHlwZW11c3RtYXRjaCIsIk9MOjpjb21wYWN0IiwiT0w6OnJldmVyc2VkIiwiT0w6OnN0YXJ0Iiwi
-T0w6OnR5cGUiLCJPUFRHUk9VUDo6ZGlzYWJsZWQiLCJPUFRHUk9VUDo6bGFiZWwiLCJPUFRJT046OmRp
-c2FibGVkIiwiT1BUSU9OOjpsYWJlbCIsIk9QVElPTjo6c2VsZWN0ZWQiLCJPUFRJT046OnZhbHVlIiwi
-T1VUUFVUOjpmb3IiLCJPVVRQVVQ6Om5hbWUiLCJQOjphbGlnbiIsIlBSRTo6d2lkdGgiLCJQUk9HUkVT
-Uzo6bWF4IiwiUFJPR1JFU1M6Om1pbiIsIlBST0dSRVNTOjp2YWx1ZSIsIlNFTEVDVDo6YXV0b2NvbXBs
-ZXRlIiwiU0VMRUNUOjpkaXNhYmxlZCIsIlNFTEVDVDo6bXVsdGlwbGUiLCJTRUxFQ1Q6Om5hbWUiLCJT
-RUxFQ1Q6OnJlcXVpcmVkIiwiU0VMRUNUOjpzaXplIiwiU0VMRUNUOjp0YWJpbmRleCIsIlNPVVJDRTo6
-dHlwZSIsIlRBQkxFOjphbGlnbiIsIlRBQkxFOjpiZ2NvbG9yIiwiVEFCTEU6OmJvcmRlciIsIlRBQkxF
-OjpjZWxscGFkZGluZyIsIlRBQkxFOjpjZWxsc3BhY2luZyIsIlRBQkxFOjpmcmFtZSIsIlRBQkxFOjpy
-dWxlcyIsIlRBQkxFOjpzdW1tYXJ5IiwiVEFCTEU6OndpZHRoIiwiVEJPRFk6OmFsaWduIiwiVEJPRFk6
-OmNoYXIiLCJUQk9EWTo6Y2hhcm9mZiIsIlRCT0RZOjp2YWxpZ24iLCJURDo6YWJiciIsIlREOjphbGln
-biIsIlREOjpheGlzIiwiVEQ6OmJnY29sb3IiLCJURDo6Y2hhciIsIlREOjpjaGFyb2ZmIiwiVEQ6OmNv
-bHNwYW4iLCJURDo6aGVhZGVycyIsIlREOjpoZWlnaHQiLCJURDo6bm93cmFwIiwiVEQ6OnJvd3NwYW4i
-LCJURDo6c2NvcGUiLCJURDo6dmFsaWduIiwiVEQ6OndpZHRoIiwiVEVYVEFSRUE6OmFjY2Vzc2tleSIs
-IlRFWFRBUkVBOjphdXRvY29tcGxldGUiLCJURVhUQVJFQTo6Y29scyIsIlRFWFRBUkVBOjpkaXNhYmxl
-ZCIsIlRFWFRBUkVBOjppbnB1dG1vZGUiLCJURVhUQVJFQTo6bmFtZSIsIlRFWFRBUkVBOjpwbGFjZWhv
-bGRlciIsIlRFWFRBUkVBOjpyZWFkb25seSIsIlRFWFRBUkVBOjpyZXF1aXJlZCIsIlRFWFRBUkVBOjpy
-b3dzIiwiVEVYVEFSRUE6OnRhYmluZGV4IiwiVEVYVEFSRUE6OndyYXAiLCJURk9PVDo6YWxpZ24iLCJU
-Rk9PVDo6Y2hhciIsIlRGT09UOjpjaGFyb2ZmIiwiVEZPT1Q6OnZhbGlnbiIsIlRIOjphYmJyIiwiVEg6
-OmFsaWduIiwiVEg6OmF4aXMiLCJUSDo6Ymdjb2xvciIsIlRIOjpjaGFyIiwiVEg6OmNoYXJvZmYiLCJU
-SDo6Y29sc3BhbiIsIlRIOjpoZWFkZXJzIiwiVEg6OmhlaWdodCIsIlRIOjpub3dyYXAiLCJUSDo6cm93
-c3BhbiIsIlRIOjpzY29wZSIsIlRIOjp2YWxpZ24iLCJUSDo6d2lkdGgiLCJUSEVBRDo6YWxpZ24iLCJU
-SEVBRDo6Y2hhciIsIlRIRUFEOjpjaGFyb2ZmIiwiVEhFQUQ6OnZhbGlnbiIsIlRSOjphbGlnbiIsIlRS
-OjpiZ2NvbG9yIiwiVFI6OmNoYXIiLCJUUjo6Y2hhcm9mZiIsIlRSOjp2YWxpZ24iLCJUUkFDSzo6ZGVm
-YXVsdCIsIlRSQUNLOjpraW5kIiwiVFJBQ0s6OmxhYmVsIiwiVFJBQ0s6OnNyY2xhbmciLCJVTDo6Y29t
-cGFjdCIsIlVMOjp0eXBlIiwiVklERU86OmNvbnRyb2xzIiwiVklERU86OmhlaWdodCIsIlZJREVPOjps
-b29wIiwiVklERU86Om1lZGlhZ3JvdXAiLCJWSURFTzo6bXV0ZWQiLCJWSURFTzo6cHJlbG9hZCIsIlZJ
-REVPOjp3aWR0aCJdKSx0LmkpCkMuVkM9SC5WTShzKFswLDAsNjU0OTAsNDUwNTUsNjU1MzUsMzQ4MTUs
-NjU1MzQsMTg0MzFdKSx0LlYpCkMubUs9SC5WTShzKFswLDAsMjY2MjQsMTAyMyw2NTUzNCwyMDQ3LDY1
-NTM0LDIwNDddKSx0LlYpCkMuU3E9SC5WTShzKFsiSEVBRCIsIkFSRUEiLCJCQVNFIiwiQkFTRUZPTlQi
-LCJCUiIsIkNPTCIsIkNPTEdST1VQIiwiRU1CRUQiLCJGUkFNRSIsIkZSQU1FU0VUIiwiSFIiLCJJTUFH
-RSIsIklNRyIsIklOUFVUIiwiSVNJTkRFWCIsIkxJTksiLCJNRVRBIiwiUEFSQU0iLCJTT1VSQ0UiLCJT
-VFlMRSIsIlRJVExFIiwiV0JSIl0pLHQuaSkKQy5oVT1ILlZNKHMoW10pLHQuYikKQy5kbj1ILlZNKHMo
-W10pLEguTjAoImpkPExMKj4iKSkKQy54RD1ILlZNKHMoW10pLHQuaSkKQy50bz1ILlZNKHMoWzAsMCwz
-MjcyMiwxMjI4Nyw2NTUzNCwzNDgxNSw2NTUzNCwxODQzMV0pLHQuVikKQy5yaz1ILlZNKHMoW0MuQWQs
-Qy5uZSxDLm15LEMucngsQy53VixDLmZSXSksSC5OMCgiamQ8SDcqPiIpKQpDLkYzPUguVk0ocyhbMCww
-LDI0NTc2LDEwMjMsNjU1MzQsMzQ4MTUsNjU1MzQsMTg0MzFdKSx0LlYpCkMuZWE9SC5WTShzKFswLDAs
-MzI3NTQsMTEyNjMsNjU1MzQsMzQ4MTUsNjU1MzQsMTg0MzFdKSx0LlYpCkMuWko9SC5WTShzKFswLDAs
-MzI3MjIsMTIyODcsNjU1MzUsMzQ4MTUsNjU1MzQsMTg0MzFdKSx0LlYpCkMuV2Q9SC5WTShzKFswLDAs
-NjU0OTAsMTIyODcsNjU1MzUsMzQ4MTUsNjU1MzQsMTg0MzFdKSx0LlYpCkMuUXg9SC5WTShzKFsiYmlu
-ZCIsImlmIiwicmVmIiwicmVwZWF0Iiwic3ludGF4Il0pLHQuaSkKQy5CST1ILlZNKHMoWyJBOjpocmVm
-IiwiQVJFQTo6aHJlZiIsIkJMT0NLUVVPVEU6OmNpdGUiLCJCT0RZOjpiYWNrZ3JvdW5kIiwiQ09NTUFO
-RDo6aWNvbiIsIkRFTDo6Y2l0ZSIsIkZPUk06OmFjdGlvbiIsIklNRzo6c3JjIiwiSU5QVVQ6OnNyYyIs
-IklOUzo6Y2l0ZSIsIlE6OmNpdGUiLCJWSURFTzo6cG9zdGVyIl0pLHQuaSkKQy5EeD1uZXcgSC5MUCgw
-LHt9LEMueEQsSC5OMCgiTFA8cVUqLHpNPGo4Kj4qPiIpKQpDLkNNPW5ldyBILkxQKDAse30sQy54RCxI
-Lk4wKCJMUDxxVSoscVUqPiIpKQpDLmlIPUguVk0ocyhbXSksSC5OMCgiamQ8R0QqPiIpKQpDLldPPW5l
-dyBILkxQKDAse30sQy5pSCxILk4wKCJMUDxHRCosQD4iKSkKQy5ZMj1uZXcgTC5POSgiTmF2aWdhdGlv
-blRyZWVOb2RlVHlwZS5kaXJlY3RvcnkiKQpDLnJmPW5ldyBMLk85KCJOYXZpZ2F0aW9uVHJlZU5vZGVU
-eXBlLmZpbGUiKQpDLlRlPW5ldyBILnd2KCJjYWxsIikKQy5vRT1uZXcgUC5HWSghMSkKQy53UT1uZXcg
-UC5GeShudWxsLDIpfSkoKTsoZnVuY3Rpb24gc3RhdGljRmllbGRzKCl7JC56bT1udWxsCiQueWo9MAok
-Lm1KPW51bGwKJC5QND1udWxsCiQuTkY9bnVsbAokLlRYPW51bGwKJC54Nz1udWxsCiQubnc9bnVsbAok
-LnZ2PW51bGwKJC5Cdj1udWxsCiQuUzY9bnVsbAokLms4PW51bGwKJC5tZz1udWxsCiQuVUQ9ITEKJC5Y
-Mz1DLk5VCiQueGc9SC5WTShbXSxILk4wKCJqZDxNaD4iKSkKJC54bz1udWxsCiQuQk89bnVsbAokLmx0
-PW51bGwKJC5FVT1udWxsCiQub3I9UC5GbCh0Lk4sdC5ZKQokLklSPW51bGwKJC5JNj1udWxsCiQuRmY9
-bnVsbH0pKCk7KGZ1bmN0aW9uIGxhenlJbml0aWFsaXplcnMoKXt2YXIgcz1odW5rSGVscGVycy5sYXp5
-RmluYWwscj1odW5rSGVscGVycy5sYXp5T2xkCnMoJCwiZmEiLCJ3IixmdW5jdGlvbigpe3JldHVybiBI
-LllnKCJfJGRhcnRfZGFydENsb3N1cmUiKX0pCnMoJCwiVTIiLCJTbiIsZnVuY3Rpb24oKXtyZXR1cm4g
-SC5jTShILlM3KHsKdG9TdHJpbmc6ZnVuY3Rpb24oKXtyZXR1cm4iJHJlY2VpdmVyJCJ9fSkpfSkKcygk
-LCJ4cSIsImxxIixmdW5jdGlvbigpe3JldHVybiBILmNNKEguUzcoeyRtZXRob2QkOm51bGwsCnRvU3Ry
-aW5nOmZ1bmN0aW9uKCl7cmV0dXJuIiRyZWNlaXZlciQifX0pKX0pCnMoJCwiUjEiLCJOOSIsZnVuY3Rp
-b24oKXtyZXR1cm4gSC5jTShILlM3KG51bGwpKX0pCnMoJCwiZk4iLCJpSSIsZnVuY3Rpb24oKXtyZXR1
-cm4gSC5jTShmdW5jdGlvbigpe3ZhciAkYXJndW1lbnRzRXhwciQ9IiRhcmd1bWVudHMkIgp0cnl7bnVs
-bC4kbWV0aG9kJCgkYXJndW1lbnRzRXhwciQpfWNhdGNoKHEpe3JldHVybiBxLm1lc3NhZ2V9fSgpKX0p
-CnMoJCwicWkiLCJVTiIsZnVuY3Rpb24oKXtyZXR1cm4gSC5jTShILlM3KHZvaWQgMCkpfSkKcygkLCJy
-WiIsIlpoIixmdW5jdGlvbigpe3JldHVybiBILmNNKGZ1bmN0aW9uKCl7dmFyICRhcmd1bWVudHNFeHBy
-JD0iJGFyZ3VtZW50cyQiCnRyeXsodm9pZCAwKS4kbWV0aG9kJCgkYXJndW1lbnRzRXhwciQpfWNhdGNo
-KHEpe3JldHVybiBxLm1lc3NhZ2V9fSgpKX0pCnMoJCwia3EiLCJyTiIsZnVuY3Rpb24oKXtyZXR1cm4g
-SC5jTShILk1qKG51bGwpKX0pCnMoJCwidHQiLCJjMyIsZnVuY3Rpb24oKXtyZXR1cm4gSC5jTShmdW5j
-dGlvbigpe3RyeXtudWxsLiRtZXRob2QkfWNhdGNoKHEpe3JldHVybiBxLm1lc3NhZ2V9fSgpKX0pCnMo
-JCwiZHQiLCJISyIsZnVuY3Rpb24oKXtyZXR1cm4gSC5jTShILk1qKHZvaWQgMCkpfSkKcygkLCJBNyIs
-InIxIixmdW5jdGlvbigpe3JldHVybiBILmNNKGZ1bmN0aW9uKCl7dHJ5eyh2b2lkIDApLiRtZXRob2Qk
-fWNhdGNoKHEpe3JldHVybiBxLm1lc3NhZ2V9fSgpKX0pCnMoJCwiV2MiLCJ1dCIsZnVuY3Rpb24oKXty
-ZXR1cm4gUC5PaigpfSkKcygkLCJraCIsInJmIixmdW5jdGlvbigpe3JldHVybiBuZXcgUC54cigpLiQw
-KCl9KQpzKCQsImRIIiwiSEciLGZ1bmN0aW9uKCl7cmV0dXJuIG5ldyBQLk56KCkuJDAoKX0pCnMoJCwi
-aGoiLCJWNyIsZnVuY3Rpb24oKXtyZXR1cm4gbmV3IEludDhBcnJheShILlhGKEguVk0oWy0yLC0yLC0y
+ICJDbGlwYm9hcmQiLAogICAgIkdlb0dlb2xvY2F0aW9uIjogIkdlb2xvY2F0aW9uIiwKICAgICJMb2Nh
+dGlvbiI6ICIhTG9jYXRpb24iLAogICAgIldvcmtlck1lc3NhZ2VFdmVudCI6ICJNZXNzYWdlRXZlbnQi
+LAogICAgIlhNTERvY3VtZW50IjogIiFEb2N1bWVudCJ9OwogIGZ1bmN0aW9uIGdldFRhZ0ZpcmVmb3go
+bykgewogICAgdmFyIHRhZyA9IGdldFRhZyhvKTsKICAgIHJldHVybiBxdWlja01hcFt0YWddIHx8IHRh
+ZzsKICB9CiAgaG9va3MuZ2V0VGFnID0gZ2V0VGFnRmlyZWZveDsKfQpDLnhpPWZ1bmN0aW9uKGhvb2tz
+KSB7CiAgdmFyIHVzZXJBZ2VudCA9IHR5cGVvZiBuYXZpZ2F0b3IgPT0gIm9iamVjdCIgPyBuYXZpZ2F0
+b3IudXNlckFnZW50IDogIiI7CiAgaWYgKHVzZXJBZ2VudC5pbmRleE9mKCJUcmlkZW50LyIpID09IC0x
+KSByZXR1cm4gaG9va3M7CiAgdmFyIGdldFRhZyA9IGhvb2tzLmdldFRhZzsKICB2YXIgcXVpY2tNYXAg
+PSB7CiAgICAiQmVmb3JlVW5sb2FkRXZlbnQiOiAiRXZlbnQiLAogICAgIkRhdGFUcmFuc2ZlciI6ICJD
+bGlwYm9hcmQiLAogICAgIkhUTUxEREVsZW1lbnQiOiAiSFRNTEVsZW1lbnQiLAogICAgIkhUTUxEVEVs
+ZW1lbnQiOiAiSFRNTEVsZW1lbnQiLAogICAgIkhUTUxQaHJhc2VFbGVtZW50IjogIkhUTUxFbGVtZW50
+IiwKICAgICJQb3NpdGlvbiI6ICJHZW9wb3NpdGlvbiIKICB9OwogIGZ1bmN0aW9uIGdldFRhZ0lFKG8p
+IHsKICAgIHZhciB0YWcgPSBnZXRUYWcobyk7CiAgICB2YXIgbmV3VGFnID0gcXVpY2tNYXBbdGFnXTsK
+ICAgIGlmIChuZXdUYWcpIHJldHVybiBuZXdUYWc7CiAgICBpZiAodGFnID09ICJPYmplY3QiKSB7CiAg
+ICAgIGlmICh3aW5kb3cuRGF0YVZpZXcgJiYgKG8gaW5zdGFuY2VvZiB3aW5kb3cuRGF0YVZpZXcpKSBy
+ZXR1cm4gIkRhdGFWaWV3IjsKICAgIH0KICAgIHJldHVybiB0YWc7CiAgfQogIGZ1bmN0aW9uIHByb3Rv
+dHlwZUZvclRhZ0lFKHRhZykgewogICAgdmFyIGNvbnN0cnVjdG9yID0gd2luZG93W3RhZ107CiAgICBp
+ZiAoY29uc3RydWN0b3IgPT0gbnVsbCkgcmV0dXJuIG51bGw7CiAgICByZXR1cm4gY29uc3RydWN0b3Iu
+cHJvdG90eXBlOwogIH0KICBob29rcy5nZXRUYWcgPSBnZXRUYWdJRTsKICBob29rcy5wcm90b3R5cGVG
+b3JUYWcgPSBwcm90b3R5cGVGb3JUYWdJRTsKfQpDLmk3PWZ1bmN0aW9uKGhvb2tzKSB7IHJldHVybiBo
+b29rczsgfQoKQy5DdD1uZXcgUC5ieSgpCkMuRXE9bmV3IFAuazUoKQpDLnhNPW5ldyBQLnU1KCkKQy5R
+az1uZXcgUC5FMygpCkMuTnY9bmV3IEgua3IoKQpDLk5VPW5ldyBQLkppKCkKQy5wZD1uZXcgUC5aZCgp
+CkMuQWQ9bmV3IFIuSDcoMCwiSGludEFjdGlvbktpbmQuYWRkTnVsbGFibGVIaW50IikKQy5uZT1uZXcg
+Ui5INygxLCJIaW50QWN0aW9uS2luZC5hZGROb25OdWxsYWJsZUhpbnQiKQpDLm15PW5ldyBSLkg3KDIs
+IkhpbnRBY3Rpb25LaW5kLmNoYW5nZVRvTnVsbGFibGVIaW50IikKQy5yeD1uZXcgUi5INygzLCJIaW50
+QWN0aW9uS2luZC5jaGFuZ2VUb05vbk51bGxhYmxlSGludCIpCkMud1Y9bmV3IFIuSDcoNCwiSGludEFj
+dGlvbktpbmQucmVtb3ZlTnVsbGFibGVIaW50IikKQy5mUj1uZXcgUi5INyg1LCJIaW50QWN0aW9uS2lu
+ZC5yZW1vdmVOb25OdWxsYWJsZUhpbnQiKQpDLkEzPW5ldyBQLk14KG51bGwpCkMublg9bmV3IFAub2oo
+bnVsbCkKQy5jdz1uZXcgTC5HYigwLCJVbml0TWlncmF0aW9uU3RhdHVzLmFscmVhZHlNaWdyYXRlZCIp
+CkMuZGM9bmV3IEwuR2IoMSwiVW5pdE1pZ3JhdGlvblN0YXR1cy5pbmRldGVybWluYXRlIikKQy5XRD1u
+ZXcgTC5HYigyLCJVbml0TWlncmF0aW9uU3RhdHVzLm1pZ3JhdGluZyIpCkMuWGo9bmV3IEwuR2IoMywi
+VW5pdE1pZ3JhdGlvblN0YXR1cy5vcHRpbmdPdXQiKQpDLmwwPUguVk0ocyhbQy5jdyxDLmRjLEMuV0Qs
+Qy5Yal0pLEguTjAoImpkPEdiKj4iKSkKQy5haz1ILlZNKHMoWzAsMCwzMjc3NiwzMzc5MiwxLDEwMjQw
+LDAsMF0pLHQuVikKQy5jbT1ILlZNKHMoWyIqOjpjbGFzcyIsIio6OmRpciIsIio6OmRyYWdnYWJsZSIs
+Iio6OmhpZGRlbiIsIio6OmlkIiwiKjo6aW5lcnQiLCIqOjppdGVtcHJvcCIsIio6Oml0ZW1yZWYiLCIq
+OjppdGVtc2NvcGUiLCIqOjpsYW5nIiwiKjo6c3BlbGxjaGVjayIsIio6OnRpdGxlIiwiKjo6dHJhbnNs
+YXRlIiwiQTo6YWNjZXNza2V5IiwiQTo6Y29vcmRzIiwiQTo6aHJlZmxhbmciLCJBOjpuYW1lIiwiQTo6
+c2hhcGUiLCJBOjp0YWJpbmRleCIsIkE6OnRhcmdldCIsIkE6OnR5cGUiLCJBUkVBOjphY2Nlc3NrZXki
+LCJBUkVBOjphbHQiLCJBUkVBOjpjb29yZHMiLCJBUkVBOjpub2hyZWYiLCJBUkVBOjpzaGFwZSIsIkFS
+RUE6OnRhYmluZGV4IiwiQVJFQTo6dGFyZ2V0IiwiQVVESU86OmNvbnRyb2xzIiwiQVVESU86Omxvb3Ai
+LCJBVURJTzo6bWVkaWFncm91cCIsIkFVRElPOjptdXRlZCIsIkFVRElPOjpwcmVsb2FkIiwiQkRPOjpk
+aXIiLCJCT0RZOjphbGluayIsIkJPRFk6OmJnY29sb3IiLCJCT0RZOjpsaW5rIiwiQk9EWTo6dGV4dCIs
+IkJPRFk6OnZsaW5rIiwiQlI6OmNsZWFyIiwiQlVUVE9OOjphY2Nlc3NrZXkiLCJCVVRUT046OmRpc2Fi
+bGVkIiwiQlVUVE9OOjpuYW1lIiwiQlVUVE9OOjp0YWJpbmRleCIsIkJVVFRPTjo6dHlwZSIsIkJVVFRP
+Tjo6dmFsdWUiLCJDQU5WQVM6OmhlaWdodCIsIkNBTlZBUzo6d2lkdGgiLCJDQVBUSU9OOjphbGlnbiIs
+IkNPTDo6YWxpZ24iLCJDT0w6OmNoYXIiLCJDT0w6OmNoYXJvZmYiLCJDT0w6OnNwYW4iLCJDT0w6OnZh
+bGlnbiIsIkNPTDo6d2lkdGgiLCJDT0xHUk9VUDo6YWxpZ24iLCJDT0xHUk9VUDo6Y2hhciIsIkNPTEdS
+T1VQOjpjaGFyb2ZmIiwiQ09MR1JPVVA6OnNwYW4iLCJDT0xHUk9VUDo6dmFsaWduIiwiQ09MR1JPVVA6
+OndpZHRoIiwiQ09NTUFORDo6Y2hlY2tlZCIsIkNPTU1BTkQ6OmNvbW1hbmQiLCJDT01NQU5EOjpkaXNh
+YmxlZCIsIkNPTU1BTkQ6OmxhYmVsIiwiQ09NTUFORDo6cmFkaW9ncm91cCIsIkNPTU1BTkQ6OnR5cGUi
+LCJEQVRBOjp2YWx1ZSIsIkRFTDo6ZGF0ZXRpbWUiLCJERVRBSUxTOjpvcGVuIiwiRElSOjpjb21wYWN0
+IiwiRElWOjphbGlnbiIsIkRMOjpjb21wYWN0IiwiRklFTERTRVQ6OmRpc2FibGVkIiwiRk9OVDo6Y29s
+b3IiLCJGT05UOjpmYWNlIiwiRk9OVDo6c2l6ZSIsIkZPUk06OmFjY2VwdCIsIkZPUk06OmF1dG9jb21w
+bGV0ZSIsIkZPUk06OmVuY3R5cGUiLCJGT1JNOjptZXRob2QiLCJGT1JNOjpuYW1lIiwiRk9STTo6bm92
+YWxpZGF0ZSIsIkZPUk06OnRhcmdldCIsIkZSQU1FOjpuYW1lIiwiSDE6OmFsaWduIiwiSDI6OmFsaWdu
+IiwiSDM6OmFsaWduIiwiSDQ6OmFsaWduIiwiSDU6OmFsaWduIiwiSDY6OmFsaWduIiwiSFI6OmFsaWdu
+IiwiSFI6Om5vc2hhZGUiLCJIUjo6c2l6ZSIsIkhSOjp3aWR0aCIsIkhUTUw6OnZlcnNpb24iLCJJRlJB
+TUU6OmFsaWduIiwiSUZSQU1FOjpmcmFtZWJvcmRlciIsIklGUkFNRTo6aGVpZ2h0IiwiSUZSQU1FOjpt
+YXJnaW5oZWlnaHQiLCJJRlJBTUU6Om1hcmdpbndpZHRoIiwiSUZSQU1FOjp3aWR0aCIsIklNRzo6YWxp
+Z24iLCJJTUc6OmFsdCIsIklNRzo6Ym9yZGVyIiwiSU1HOjpoZWlnaHQiLCJJTUc6OmhzcGFjZSIsIklN
+Rzo6aXNtYXAiLCJJTUc6Om5hbWUiLCJJTUc6OnVzZW1hcCIsIklNRzo6dnNwYWNlIiwiSU1HOjp3aWR0
+aCIsIklOUFVUOjphY2NlcHQiLCJJTlBVVDo6YWNjZXNza2V5IiwiSU5QVVQ6OmFsaWduIiwiSU5QVVQ6
+OmFsdCIsIklOUFVUOjphdXRvY29tcGxldGUiLCJJTlBVVDo6YXV0b2ZvY3VzIiwiSU5QVVQ6OmNoZWNr
+ZWQiLCJJTlBVVDo6ZGlzYWJsZWQiLCJJTlBVVDo6aW5wdXRtb2RlIiwiSU5QVVQ6OmlzbWFwIiwiSU5Q
+VVQ6Omxpc3QiLCJJTlBVVDo6bWF4IiwiSU5QVVQ6Om1heGxlbmd0aCIsIklOUFVUOjptaW4iLCJJTlBV
+VDo6bXVsdGlwbGUiLCJJTlBVVDo6bmFtZSIsIklOUFVUOjpwbGFjZWhvbGRlciIsIklOUFVUOjpyZWFk
+b25seSIsIklOUFVUOjpyZXF1aXJlZCIsIklOUFVUOjpzaXplIiwiSU5QVVQ6OnN0ZXAiLCJJTlBVVDo6
+dGFiaW5kZXgiLCJJTlBVVDo6dHlwZSIsIklOUFVUOjp1c2VtYXAiLCJJTlBVVDo6dmFsdWUiLCJJTlM6
+OmRhdGV0aW1lIiwiS0VZR0VOOjpkaXNhYmxlZCIsIktFWUdFTjo6a2V5dHlwZSIsIktFWUdFTjo6bmFt
+ZSIsIkxBQkVMOjphY2Nlc3NrZXkiLCJMQUJFTDo6Zm9yIiwiTEVHRU5EOjphY2Nlc3NrZXkiLCJMRUdF
+TkQ6OmFsaWduIiwiTEk6OnR5cGUiLCJMSTo6dmFsdWUiLCJMSU5LOjpzaXplcyIsIk1BUDo6bmFtZSIs
+Ik1FTlU6OmNvbXBhY3QiLCJNRU5VOjpsYWJlbCIsIk1FTlU6OnR5cGUiLCJNRVRFUjo6aGlnaCIsIk1F
+VEVSOjpsb3ciLCJNRVRFUjo6bWF4IiwiTUVURVI6Om1pbiIsIk1FVEVSOjp2YWx1ZSIsIk9CSkVDVDo6
+dHlwZW11c3RtYXRjaCIsIk9MOjpjb21wYWN0IiwiT0w6OnJldmVyc2VkIiwiT0w6OnN0YXJ0IiwiT0w6
+OnR5cGUiLCJPUFRHUk9VUDo6ZGlzYWJsZWQiLCJPUFRHUk9VUDo6bGFiZWwiLCJPUFRJT046OmRpc2Fi
+bGVkIiwiT1BUSU9OOjpsYWJlbCIsIk9QVElPTjo6c2VsZWN0ZWQiLCJPUFRJT046OnZhbHVlIiwiT1VU
+UFVUOjpmb3IiLCJPVVRQVVQ6Om5hbWUiLCJQOjphbGlnbiIsIlBSRTo6d2lkdGgiLCJQUk9HUkVTUzo6
+bWF4IiwiUFJPR1JFU1M6Om1pbiIsIlBST0dSRVNTOjp2YWx1ZSIsIlNFTEVDVDo6YXV0b2NvbXBsZXRl
+IiwiU0VMRUNUOjpkaXNhYmxlZCIsIlNFTEVDVDo6bXVsdGlwbGUiLCJTRUxFQ1Q6Om5hbWUiLCJTRUxF
+Q1Q6OnJlcXVpcmVkIiwiU0VMRUNUOjpzaXplIiwiU0VMRUNUOjp0YWJpbmRleCIsIlNPVVJDRTo6dHlw
+ZSIsIlRBQkxFOjphbGlnbiIsIlRBQkxFOjpiZ2NvbG9yIiwiVEFCTEU6OmJvcmRlciIsIlRBQkxFOjpj
+ZWxscGFkZGluZyIsIlRBQkxFOjpjZWxsc3BhY2luZyIsIlRBQkxFOjpmcmFtZSIsIlRBQkxFOjpydWxl
+cyIsIlRBQkxFOjpzdW1tYXJ5IiwiVEFCTEU6OndpZHRoIiwiVEJPRFk6OmFsaWduIiwiVEJPRFk6OmNo
+YXIiLCJUQk9EWTo6Y2hhcm9mZiIsIlRCT0RZOjp2YWxpZ24iLCJURDo6YWJiciIsIlREOjphbGlnbiIs
+IlREOjpheGlzIiwiVEQ6OmJnY29sb3IiLCJURDo6Y2hhciIsIlREOjpjaGFyb2ZmIiwiVEQ6OmNvbHNw
+YW4iLCJURDo6aGVhZGVycyIsIlREOjpoZWlnaHQiLCJURDo6bm93cmFwIiwiVEQ6OnJvd3NwYW4iLCJU
+RDo6c2NvcGUiLCJURDo6dmFsaWduIiwiVEQ6OndpZHRoIiwiVEVYVEFSRUE6OmFjY2Vzc2tleSIsIlRF
+WFRBUkVBOjphdXRvY29tcGxldGUiLCJURVhUQVJFQTo6Y29scyIsIlRFWFRBUkVBOjpkaXNhYmxlZCIs
+IlRFWFRBUkVBOjppbnB1dG1vZGUiLCJURVhUQVJFQTo6bmFtZSIsIlRFWFRBUkVBOjpwbGFjZWhvbGRl
+ciIsIlRFWFRBUkVBOjpyZWFkb25seSIsIlRFWFRBUkVBOjpyZXF1aXJlZCIsIlRFWFRBUkVBOjpyb3dz
+IiwiVEVYVEFSRUE6OnRhYmluZGV4IiwiVEVYVEFSRUE6OndyYXAiLCJURk9PVDo6YWxpZ24iLCJURk9P
+VDo6Y2hhciIsIlRGT09UOjpjaGFyb2ZmIiwiVEZPT1Q6OnZhbGlnbiIsIlRIOjphYmJyIiwiVEg6OmFs
+aWduIiwiVEg6OmF4aXMiLCJUSDo6Ymdjb2xvciIsIlRIOjpjaGFyIiwiVEg6OmNoYXJvZmYiLCJUSDo6
+Y29sc3BhbiIsIlRIOjpoZWFkZXJzIiwiVEg6OmhlaWdodCIsIlRIOjpub3dyYXAiLCJUSDo6cm93c3Bh
+biIsIlRIOjpzY29wZSIsIlRIOjp2YWxpZ24iLCJUSDo6d2lkdGgiLCJUSEVBRDo6YWxpZ24iLCJUSEVB
+RDo6Y2hhciIsIlRIRUFEOjpjaGFyb2ZmIiwiVEhFQUQ6OnZhbGlnbiIsIlRSOjphbGlnbiIsIlRSOjpi
+Z2NvbG9yIiwiVFI6OmNoYXIiLCJUUjo6Y2hhcm9mZiIsIlRSOjp2YWxpZ24iLCJUUkFDSzo6ZGVmYXVs
+dCIsIlRSQUNLOjpraW5kIiwiVFJBQ0s6OmxhYmVsIiwiVFJBQ0s6OnNyY2xhbmciLCJVTDo6Y29tcGFj
+dCIsIlVMOjp0eXBlIiwiVklERU86OmNvbnRyb2xzIiwiVklERU86OmhlaWdodCIsIlZJREVPOjpsb29w
+IiwiVklERU86Om1lZGlhZ3JvdXAiLCJWSURFTzo6bXV0ZWQiLCJWSURFTzo6cHJlbG9hZCIsIlZJREVP
+Ojp3aWR0aCJdKSx0LmkpCkMuVkM9SC5WTShzKFswLDAsNjU0OTAsNDUwNTUsNjU1MzUsMzQ4MTUsNjU1
+MzQsMTg0MzFdKSx0LlYpCkMubUs9SC5WTShzKFswLDAsMjY2MjQsMTAyMyw2NTUzNCwyMDQ3LDY1NTM0
+LDIwNDddKSx0LlYpCkMuU3E9SC5WTShzKFsiSEVBRCIsIkFSRUEiLCJCQVNFIiwiQkFTRUZPTlQiLCJC
+UiIsIkNPTCIsIkNPTEdST1VQIiwiRU1CRUQiLCJGUkFNRSIsIkZSQU1FU0VUIiwiSFIiLCJJTUFHRSIs
+IklNRyIsIklOUFVUIiwiSVNJTkRFWCIsIkxJTksiLCJNRVRBIiwiUEFSQU0iLCJTT1VSQ0UiLCJTVFlM
+RSIsIlRJVExFIiwiV0JSIl0pLHQuaSkKQy5oVT1ILlZNKHMoW10pLHQuYikKQy5kbj1ILlZNKHMoW10p
+LEguTjAoImpkPExMKj4iKSkKQy54RD1ILlZNKHMoW10pLHQuaSkKQy50bz1ILlZNKHMoWzAsMCwzMjcy
+MiwxMjI4Nyw2NTUzNCwzNDgxNSw2NTUzNCwxODQzMV0pLHQuVikKQy5yaz1ILlZNKHMoW0MuQWQsQy5u
+ZSxDLm15LEMucngsQy53VixDLmZSXSksSC5OMCgiamQ8SDcqPiIpKQpDLkYzPUguVk0ocyhbMCwwLDI0
+NTc2LDEwMjMsNjU1MzQsMzQ4MTUsNjU1MzQsMTg0MzFdKSx0LlYpCkMuZWE9SC5WTShzKFswLDAsMzI3
+NTQsMTEyNjMsNjU1MzQsMzQ4MTUsNjU1MzQsMTg0MzFdKSx0LlYpCkMuWko9SC5WTShzKFswLDAsMzI3
+MjIsMTIyODcsNjU1MzUsMzQ4MTUsNjU1MzQsMTg0MzFdKSx0LlYpCkMuV2Q9SC5WTShzKFswLDAsNjU0
+OTAsMTIyODcsNjU1MzUsMzQ4MTUsNjU1MzQsMTg0MzFdKSx0LlYpCkMuUXg9SC5WTShzKFsiYmluZCIs
+ImlmIiwicmVmIiwicmVwZWF0Iiwic3ludGF4Il0pLHQuaSkKQy5CST1ILlZNKHMoWyJBOjpocmVmIiwi
+QVJFQTo6aHJlZiIsIkJMT0NLUVVPVEU6OmNpdGUiLCJCT0RZOjpiYWNrZ3JvdW5kIiwiQ09NTUFORDo6
+aWNvbiIsIkRFTDo6Y2l0ZSIsIkZPUk06OmFjdGlvbiIsIklNRzo6c3JjIiwiSU5QVVQ6OnNyYyIsIklO
+Uzo6Y2l0ZSIsIlE6OmNpdGUiLCJWSURFTzo6cG9zdGVyIl0pLHQuaSkKQy5EeD1uZXcgSC5MUCgwLHt9
+LEMueEQsSC5OMCgiTFA8cVUqLHpNPGo4Kj4qPiIpKQpDLkNNPW5ldyBILkxQKDAse30sQy54RCxILk4w
+KCJMUDxxVSoscVUqPiIpKQpDLmlIPUguVk0ocyhbXSksSC5OMCgiamQ8R0QqPiIpKQpDLldPPW5ldyBI
+LkxQKDAse30sQy5pSCxILk4wKCJMUDxHRCosQD4iKSkKQy5ZMj1uZXcgTC5POSgiTmF2aWdhdGlvblRy
+ZWVOb2RlVHlwZS5kaXJlY3RvcnkiKQpDLnJmPW5ldyBMLk85KCJOYXZpZ2F0aW9uVHJlZU5vZGVUeXBl
+LmZpbGUiKQpDLlRlPW5ldyBILnd2KCJjYWxsIikKQy5vRT1uZXcgUC5HWSghMSkKQy53UT1uZXcgUC5G
+eShudWxsLDIpfSkoKTsoZnVuY3Rpb24gc3RhdGljRmllbGRzKCl7JC56bT1udWxsCiQueWo9MAokLm1K
+PW51bGwKJC5QND1udWxsCiQuTkY9bnVsbAokLlRYPW51bGwKJC54Nz1udWxsCiQubnc9bnVsbAokLnZ2
+PW51bGwKJC5Cdj1udWxsCiQuUzY9bnVsbAokLms4PW51bGwKJC5tZz1udWxsCiQuVUQ9ITEKJC5YMz1D
+Lk5VCiQueGc9SC5WTShbXSxILk4wKCJqZDxNaD4iKSkKJC54bz1udWxsCiQuQk89bnVsbAokLmx0PW51
+bGwKJC5FVT1udWxsCiQub3I9UC5GbCh0Lk4sdC5ZKQokLklSPW51bGwKJC5JNj1udWxsCiQuRmY9bnVs
+bH0pKCk7KGZ1bmN0aW9uIGxhenlJbml0aWFsaXplcnMoKXt2YXIgcz1odW5rSGVscGVycy5sYXp5Rmlu
+YWwscj1odW5rSGVscGVycy5sYXp5T2xkCnMoJCwiZmEiLCJ3IixmdW5jdGlvbigpe3JldHVybiBILlln
+KCJfJGRhcnRfZGFydENsb3N1cmUiKX0pCnMoJCwiVTIiLCJTbiIsZnVuY3Rpb24oKXtyZXR1cm4gSC5j
+TShILlM3KHsKdG9TdHJpbmc6ZnVuY3Rpb24oKXtyZXR1cm4iJHJlY2VpdmVyJCJ9fSkpfSkKcygkLCJ4
+cSIsImxxIixmdW5jdGlvbigpe3JldHVybiBILmNNKEguUzcoeyRtZXRob2QkOm51bGwsCnRvU3RyaW5n
+OmZ1bmN0aW9uKCl7cmV0dXJuIiRyZWNlaXZlciQifX0pKX0pCnMoJCwiUjEiLCJOOSIsZnVuY3Rpb24o
+KXtyZXR1cm4gSC5jTShILlM3KG51bGwpKX0pCnMoJCwiZk4iLCJpSSIsZnVuY3Rpb24oKXtyZXR1cm4g
+SC5jTShmdW5jdGlvbigpe3ZhciAkYXJndW1lbnRzRXhwciQ9IiRhcmd1bWVudHMkIgp0cnl7bnVsbC4k
+bWV0aG9kJCgkYXJndW1lbnRzRXhwciQpfWNhdGNoKHEpe3JldHVybiBxLm1lc3NhZ2V9fSgpKX0pCnMo
+JCwicWkiLCJVTiIsZnVuY3Rpb24oKXtyZXR1cm4gSC5jTShILlM3KHZvaWQgMCkpfSkKcygkLCJyWiIs
+IlpoIixmdW5jdGlvbigpe3JldHVybiBILmNNKGZ1bmN0aW9uKCl7dmFyICRhcmd1bWVudHNFeHByJD0i
+JGFyZ3VtZW50cyQiCnRyeXsodm9pZCAwKS4kbWV0aG9kJCgkYXJndW1lbnRzRXhwciQpfWNhdGNoKHEp
+e3JldHVybiBxLm1lc3NhZ2V9fSgpKX0pCnMoJCwia3EiLCJyTiIsZnVuY3Rpb24oKXtyZXR1cm4gSC5j
+TShILk1qKG51bGwpKX0pCnMoJCwidHQiLCJjMyIsZnVuY3Rpb24oKXtyZXR1cm4gSC5jTShmdW5jdGlv
+bigpe3RyeXtudWxsLiRtZXRob2QkfWNhdGNoKHEpe3JldHVybiBxLm1lc3NhZ2V9fSgpKX0pCnMoJCwi
+ZHQiLCJISyIsZnVuY3Rpb24oKXtyZXR1cm4gSC5jTShILk1qKHZvaWQgMCkpfSkKcygkLCJBNyIsInIx
+IixmdW5jdGlvbigpe3JldHVybiBILmNNKGZ1bmN0aW9uKCl7dHJ5eyh2b2lkIDApLiRtZXRob2QkfWNh
+dGNoKHEpe3JldHVybiBxLm1lc3NhZ2V9fSgpKX0pCnMoJCwiV2MiLCJ1dCIsZnVuY3Rpb24oKXtyZXR1
+cm4gUC5PaigpfSkKcygkLCJraCIsInJmIixmdW5jdGlvbigpe3JldHVybiBuZXcgUC54cigpLiQwKCl9
+KQpzKCQsImRIIiwiSEciLGZ1bmN0aW9uKCl7cmV0dXJuIG5ldyBQLk56KCkuJDAoKX0pCnMoJCwiaGoi
+LCJWNyIsZnVuY3Rpb24oKXtyZXR1cm4gbmV3IEludDhBcnJheShILlhGKEguVk0oWy0yLC0yLC0yLC0y
 LC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0y
-LC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0xLC0yLC0yLC0yLC0yLC0y
-LDYyLC0yLDYyLC0yLDYzLDUyLDUzLDU0LDU1LDU2LDU3LDU4LDU5LDYwLDYxLC0yLC0yLC0yLC0xLC0y
-LC0yLC0yLDAsMSwyLDMsNCw1LDYsNyw4LDksMTAsMTEsMTIsMTMsMTQsMTUsMTYsMTcsMTgsMTksMjAs
-MjEsMjIsMjMsMjQsMjUsLTIsLTIsLTIsLTIsNjMsLTIsMjYsMjcsMjgsMjksMzAsMzEsMzIsMzMsMzQs
-MzUsMzYsMzcsMzgsMzksNDAsNDEsNDIsNDMsNDQsNDUsNDYsNDcsNDgsNDksNTAsNTEsLTIsLTIsLTIs
-LTIsLTJdLHQuYSkpKX0pCnMoJCwiTTUiLCJ3USIsZnVuY3Rpb24oKXtyZXR1cm4gdHlwZW9mIHByb2Nl
-c3MhPSJ1bmRlZmluZWQiJiZPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwocHJvY2Vzcyk9PSJb
-b2JqZWN0IHByb2Nlc3NdIiYmcHJvY2Vzcy5wbGF0Zm9ybT09IndpbjMyIn0pCnMoJCwibWYiLCJ6NCIs
-ZnVuY3Rpb24oKXtyZXR1cm4gUC5udSgiXltcXC1cXC4wLTlBLVpfYS16fl0qJCIpfSkKcygkLCJPUSIs
-InZaIixmdW5jdGlvbigpe3JldHVybiBQLktOKCl9KQpzKCQsIlNDIiwiQU4iLGZ1bmN0aW9uKCl7cmV0
-dXJuIFAudE0oWyJBIiwiQUJCUiIsIkFDUk9OWU0iLCJBRERSRVNTIiwiQVJFQSIsIkFSVElDTEUiLCJB
-U0lERSIsIkFVRElPIiwiQiIsIkJESSIsIkJETyIsIkJJRyIsIkJMT0NLUVVPVEUiLCJCUiIsIkJVVFRP
-TiIsIkNBTlZBUyIsIkNBUFRJT04iLCJDRU5URVIiLCJDSVRFIiwiQ09ERSIsIkNPTCIsIkNPTEdST1VQ
-IiwiQ09NTUFORCIsIkRBVEEiLCJEQVRBTElTVCIsIkREIiwiREVMIiwiREVUQUlMUyIsIkRGTiIsIkRJ
-UiIsIkRJViIsIkRMIiwiRFQiLCJFTSIsIkZJRUxEU0VUIiwiRklHQ0FQVElPTiIsIkZJR1VSRSIsIkZP
-TlQiLCJGT09URVIiLCJGT1JNIiwiSDEiLCJIMiIsIkgzIiwiSDQiLCJINSIsIkg2IiwiSEVBREVSIiwi
-SEdST1VQIiwiSFIiLCJJIiwiSUZSQU1FIiwiSU1HIiwiSU5QVVQiLCJJTlMiLCJLQkQiLCJMQUJFTCIs
-IkxFR0VORCIsIkxJIiwiTUFQIiwiTUFSSyIsIk1FTlUiLCJNRVRFUiIsIk5BViIsIk5PQlIiLCJPTCIs
-Ik9QVEdST1VQIiwiT1BUSU9OIiwiT1VUUFVUIiwiUCIsIlBSRSIsIlBST0dSRVNTIiwiUSIsIlMiLCJT
-QU1QIiwiU0VDVElPTiIsIlNFTEVDVCIsIlNNQUxMIiwiU09VUkNFIiwiU1BBTiIsIlNUUklLRSIsIlNU
-Uk9ORyIsIlNVQiIsIlNVTU1BUlkiLCJTVVAiLCJUQUJMRSIsIlRCT0RZIiwiVEQiLCJURVhUQVJFQSIs
-IlRGT09UIiwiVEgiLCJUSEVBRCIsIlRJTUUiLCJUUiIsIlRSQUNLIiwiVFQiLCJVIiwiVUwiLCJWQVIi
-LCJWSURFTyIsIldCUiJdLHQuTil9KQpzKCQsIlg0IiwiaEciLGZ1bmN0aW9uKCl7cmV0dXJuIFAubnUo
-Il5cXFMrJCIpfSkKcygkLCJ3TyIsIm93IixmdW5jdGlvbigpe3JldHVybiBQLk5EKHNlbGYpfSkKcygk
-LCJrdCIsIlI4IixmdW5jdGlvbigpe3JldHVybiBILllnKCJfJGRhcnRfZGFydE9iamVjdCIpfSkKcygk
-LCJmSyIsImtJIixmdW5jdGlvbigpe3JldHVybiBmdW5jdGlvbiBEYXJ0T2JqZWN0KGEpe3RoaXMubz1h
-fX0pCnIoJCwicXQiLCJ6QiIsZnVuY3Rpb24oKXtyZXR1cm4gbmV3IFQubVEoKX0pCnIoJCwiT2wiLCJV
-RSIsZnVuY3Rpb24oKXtyZXR1cm4gUC5oSyhDLm9sLmdtVyhXLngzKCkpLmhyZWYpLmdoWSgpLnEoMCwi
-YXV0aFRva2VuIil9KQpyKCQsImhUIiwieVAiLGZ1bmN0aW9uKCl7cmV0dXJuIFcuWnIoKS5xdWVyeVNl
-bGVjdG9yKCIuZWRpdC1saXN0IC5wYW5lbC1jb250ZW50Iil9KQpyKCQsIlc2IiwiaEwiLGZ1bmN0aW9u
-KCl7cmV0dXJuIFcuWnIoKS5xdWVyeVNlbGVjdG9yKCIuZWRpdC1wYW5lbCAucGFuZWwtY29udGVudCIp
-fSkKcigkLCJUUiIsIkRXIixmdW5jdGlvbigpe3JldHVybiBXLlpyKCkucXVlcnlTZWxlY3RvcigiZm9v
-dGVyIil9KQpyKCQsIkVZIiwiZmkiLGZ1bmN0aW9uKCl7cmV0dXJuIFcuWnIoKS5xdWVyeVNlbGVjdG9y
-KCJoZWFkZXIiKX0pCnIoJCwiYXYiLCJEOSIsZnVuY3Rpb24oKXtyZXR1cm4gVy5acigpLnF1ZXJ5U2Vs
-ZWN0b3IoIiN1bml0LW5hbWUiKX0pCnIoJCwidDAiLCJiTiIsZnVuY3Rpb24oKXtyZXR1cm4gVy5acigp
-LnF1ZXJ5U2VsZWN0b3IoIiNtaWdyYXRlLXVuaXQtc3RhdHVzLWljb24tbGFiZWwiKX0pCnIoJCwiYkEi
-LCJjMCIsZnVuY3Rpb24oKXtyZXR1cm4gVy5acigpLnF1ZXJ5U2VsZWN0b3IoIiNtaWdyYXRlLXVuaXQt
-c3RhdHVzLWljb24iKX0pCnIoJCwiZmUiLCJLRyIsZnVuY3Rpb24oKXtyZXR1cm4gbmV3IEwuWEEoKX0p
-CnMoJCwiZW8iLCJuVSIsZnVuY3Rpb24oKXtyZXR1cm4gbmV3IE0ubEkoJC5IaygpKX0pCnMoJCwieXIi
-LCJiRCIsZnVuY3Rpb24oKXtyZXR1cm4gbmV3IEUuT0YoUC5udSgiLyIpLFAubnUoIlteL10kIiksUC5u
-dSgiXi8iKSl9KQpzKCQsIk1rIiwiS2siLGZ1bmN0aW9uKCl7cmV0dXJuIG5ldyBMLklWKFAubnUoIlsv
-XFxcXF0iKSxQLm51KCJbXi9cXFxcXSQiKSxQLm51KCJeKFxcXFxcXFxcW15cXFxcXStcXFxcW15cXFxc
-L10rfFthLXpBLVpdOlsvXFxcXF0pIiksUC5udSgiXlsvXFxcXF0oPyFbL1xcXFxdKSIpKX0pCnMoJCwi
-YWsiLCJFYiIsZnVuY3Rpb24oKXtyZXR1cm4gbmV3IEYucnUoUC5udSgiLyIpLFAubnUoIiheW2EtekEt
-Wl1bLSsuYS16QS1aXFxkXSo6Ly98W14vXSkkIiksUC5udSgiW2EtekEtWl1bLSsuYS16QS1aXFxkXSo6
-Ly9bXi9dKiIpLFAubnUoIl4vIikpfSkKcygkLCJscyIsIkhrIixmdW5jdGlvbigpe3JldHVybiBPLlJo
-KCl9KX0pKCk7KGZ1bmN0aW9uIG5hdGl2ZVN1cHBvcnQoKXshZnVuY3Rpb24oKXt2YXIgcz1mdW5jdGlv
-bihhKXt2YXIgbT17fQptW2FdPTEKcmV0dXJuIE9iamVjdC5rZXlzKGh1bmtIZWxwZXJzLmNvbnZlcnRU
-b0Zhc3RPYmplY3QobSkpWzBdfQp2LmdldElzb2xhdGVUYWc9ZnVuY3Rpb24oYSl7cmV0dXJuIHMoIl9f
-X2RhcnRfIithK3YuaXNvbGF0ZVRhZyl9CnZhciByPSJfX19kYXJ0X2lzb2xhdGVfdGFnc18iCnZhciBx
-PU9iamVjdFtyXXx8KE9iamVjdFtyXT1PYmplY3QuY3JlYXRlKG51bGwpKQp2YXIgcD0iX1p4WXhYIgpm
-b3IodmFyIG89MDs7bysrKXt2YXIgbj1zKHArIl8iK28rIl8iKQppZighKG4gaW4gcSkpe3Fbbl09MQp2
-Lmlzb2xhdGVUYWc9bgpicmVha319di5kaXNwYXRjaFByb3BlcnR5TmFtZT12LmdldElzb2xhdGVUYWco
-ImRpc3BhdGNoX3JlY29yZCIpfSgpCmh1bmtIZWxwZXJzLnNldE9yVXBkYXRlSW50ZXJjZXB0b3JzQnlU
-YWcoe0RPTUVycm9yOkouR3YsTWVkaWFFcnJvcjpKLkd2LE5hdmlnYXRvcjpKLkd2LE5hdmlnYXRvckNv
-bmN1cnJlbnRIYXJkd2FyZTpKLkd2LE5hdmlnYXRvclVzZXJNZWRpYUVycm9yOkouR3YsT3ZlcmNvbnN0
-cmFpbmVkRXJyb3I6Si5HdixQb3NpdGlvbkVycm9yOkouR3YsUmFuZ2U6Si5HdixTUUxFcnJvcjpKLkd2
-LERhdGFWaWV3OkguRVQsQXJyYXlCdWZmZXJWaWV3OkguRVQsRmxvYXQzMkFycmF5OkguRGcsRmxvYXQ2
-NEFycmF5OkguRGcsSW50MTZBcnJheTpILnhqLEludDMyQXJyYXk6SC5kRSxJbnQ4QXJyYXk6SC5aQSxV
-aW50MTZBcnJheTpILmRULFVpbnQzMkFycmF5OkguUHEsVWludDhDbGFtcGVkQXJyYXk6SC5lRSxDYW52
-YXNQaXhlbEFycmF5OkguZUUsVWludDhBcnJheTpILlY2LEhUTUxBdWRpb0VsZW1lbnQ6Vy5xRSxIVE1M
-QlJFbGVtZW50OlcucUUsSFRNTEJ1dHRvbkVsZW1lbnQ6Vy5xRSxIVE1MQ2FudmFzRWxlbWVudDpXLnFF
-LEhUTUxDb250ZW50RWxlbWVudDpXLnFFLEhUTUxETGlzdEVsZW1lbnQ6Vy5xRSxIVE1MRGF0YUVsZW1l
-bnQ6Vy5xRSxIVE1MRGF0YUxpc3RFbGVtZW50OlcucUUsSFRNTERldGFpbHNFbGVtZW50OlcucUUsSFRN
-TERpYWxvZ0VsZW1lbnQ6Vy5xRSxIVE1MRGl2RWxlbWVudDpXLnFFLEhUTUxFbWJlZEVsZW1lbnQ6Vy5x
-RSxIVE1MRmllbGRTZXRFbGVtZW50OlcucUUsSFRNTEhSRWxlbWVudDpXLnFFLEhUTUxIZWFkRWxlbWVu
-dDpXLnFFLEhUTUxIZWFkaW5nRWxlbWVudDpXLnFFLEhUTUxIdG1sRWxlbWVudDpXLnFFLEhUTUxJRnJh
-bWVFbGVtZW50OlcucUUsSFRNTEltYWdlRWxlbWVudDpXLnFFLEhUTUxJbnB1dEVsZW1lbnQ6Vy5xRSxI
-VE1MTElFbGVtZW50OlcucUUsSFRNTExhYmVsRWxlbWVudDpXLnFFLEhUTUxMZWdlbmRFbGVtZW50Olcu
-cUUsSFRNTExpbmtFbGVtZW50OlcucUUsSFRNTE1hcEVsZW1lbnQ6Vy5xRSxIVE1MTWVkaWFFbGVtZW50
-OlcucUUsSFRNTE1lbnVFbGVtZW50OlcucUUsSFRNTE1ldGFFbGVtZW50OlcucUUsSFRNTE1ldGVyRWxl
-bWVudDpXLnFFLEhUTUxNb2RFbGVtZW50OlcucUUsSFRNTE9MaXN0RWxlbWVudDpXLnFFLEhUTUxPYmpl
-Y3RFbGVtZW50OlcucUUsSFRNTE9wdEdyb3VwRWxlbWVudDpXLnFFLEhUTUxPcHRpb25FbGVtZW50Olcu
-cUUsSFRNTE91dHB1dEVsZW1lbnQ6Vy5xRSxIVE1MUGFyYW1FbGVtZW50OlcucUUsSFRNTFBpY3R1cmVF
-bGVtZW50OlcucUUsSFRNTFByZUVsZW1lbnQ6Vy5xRSxIVE1MUHJvZ3Jlc3NFbGVtZW50OlcucUUsSFRN
-TFF1b3RlRWxlbWVudDpXLnFFLEhUTUxTY3JpcHRFbGVtZW50OlcucUUsSFRNTFNoYWRvd0VsZW1lbnQ6
-Vy5xRSxIVE1MU2xvdEVsZW1lbnQ6Vy5xRSxIVE1MU291cmNlRWxlbWVudDpXLnFFLEhUTUxTcGFuRWxl
-bWVudDpXLnFFLEhUTUxTdHlsZUVsZW1lbnQ6Vy5xRSxIVE1MVGFibGVDYXB0aW9uRWxlbWVudDpXLnFF
-LEhUTUxUYWJsZUNlbGxFbGVtZW50OlcucUUsSFRNTFRhYmxlRGF0YUNlbGxFbGVtZW50OlcucUUsSFRN
-TFRhYmxlSGVhZGVyQ2VsbEVsZW1lbnQ6Vy5xRSxIVE1MVGFibGVDb2xFbGVtZW50OlcucUUsSFRNTFRl
-eHRBcmVhRWxlbWVudDpXLnFFLEhUTUxUaW1lRWxlbWVudDpXLnFFLEhUTUxUaXRsZUVsZW1lbnQ6Vy5x
-RSxIVE1MVHJhY2tFbGVtZW50OlcucUUsSFRNTFVMaXN0RWxlbWVudDpXLnFFLEhUTUxVbmtub3duRWxl
-bWVudDpXLnFFLEhUTUxWaWRlb0VsZW1lbnQ6Vy5xRSxIVE1MRGlyZWN0b3J5RWxlbWVudDpXLnFFLEhU
-TUxGb250RWxlbWVudDpXLnFFLEhUTUxGcmFtZUVsZW1lbnQ6Vy5xRSxIVE1MRnJhbWVTZXRFbGVtZW50
-OlcucUUsSFRNTE1hcnF1ZWVFbGVtZW50OlcucUUsSFRNTEVsZW1lbnQ6Vy5xRSxIVE1MQW5jaG9yRWxl
-bWVudDpXLkdoLEhUTUxBcmVhRWxlbWVudDpXLmZZLEhUTUxCYXNlRWxlbWVudDpXLm5CLEJsb2I6Vy5B
-eixIVE1MQm9keUVsZW1lbnQ6Vy5RUCxDREFUQVNlY3Rpb246Vy5ueCxDaGFyYWN0ZXJEYXRhOlcubngs
-Q29tbWVudDpXLm54LFByb2Nlc3NpbmdJbnN0cnVjdGlvbjpXLm54LFRleHQ6Vy5ueCxDU1NTdHlsZURl
-Y2xhcmF0aW9uOlcub0osTVNTdHlsZUNTU1Byb3BlcnRpZXM6Vy5vSixDU1MyUHJvcGVydGllczpXLm9K
-LFhNTERvY3VtZW50OlcuUUYsRG9jdW1lbnQ6Vy5RRixET01FeGNlcHRpb246Vy5OaCxET01JbXBsZW1l
-bnRhdGlvbjpXLmFlLERPTVJlY3RSZWFkT25seTpXLklCLERPTVRva2VuTGlzdDpXLm43LEVsZW1lbnQ6
-Vy5jdixBYm9ydFBheW1lbnRFdmVudDpXLmVhLEFuaW1hdGlvbkV2ZW50OlcuZWEsQW5pbWF0aW9uUGxh
-eWJhY2tFdmVudDpXLmVhLEFwcGxpY2F0aW9uQ2FjaGVFcnJvckV2ZW50OlcuZWEsQmFja2dyb3VuZEZl
-dGNoQ2xpY2tFdmVudDpXLmVhLEJhY2tncm91bmRGZXRjaEV2ZW50OlcuZWEsQmFja2dyb3VuZEZldGNo
-RmFpbEV2ZW50OlcuZWEsQmFja2dyb3VuZEZldGNoZWRFdmVudDpXLmVhLEJlZm9yZUluc3RhbGxQcm9t
-cHRFdmVudDpXLmVhLEJlZm9yZVVubG9hZEV2ZW50OlcuZWEsQmxvYkV2ZW50OlcuZWEsQ2FuTWFrZVBh
-eW1lbnRFdmVudDpXLmVhLENsaXBib2FyZEV2ZW50OlcuZWEsQ2xvc2VFdmVudDpXLmVhLEN1c3RvbUV2
-ZW50OlcuZWEsRGV2aWNlTW90aW9uRXZlbnQ6Vy5lYSxEZXZpY2VPcmllbnRhdGlvbkV2ZW50OlcuZWEs
-RXJyb3JFdmVudDpXLmVhLEV4dGVuZGFibGVFdmVudDpXLmVhLEV4dGVuZGFibGVNZXNzYWdlRXZlbnQ6
-Vy5lYSxGZXRjaEV2ZW50OlcuZWEsRm9udEZhY2VTZXRMb2FkRXZlbnQ6Vy5lYSxGb3JlaWduRmV0Y2hF
-dmVudDpXLmVhLEdhbWVwYWRFdmVudDpXLmVhLEhhc2hDaGFuZ2VFdmVudDpXLmVhLEluc3RhbGxFdmVu
-dDpXLmVhLE1lZGlhRW5jcnlwdGVkRXZlbnQ6Vy5lYSxNZWRpYUtleU1lc3NhZ2VFdmVudDpXLmVhLE1l
-ZGlhUXVlcnlMaXN0RXZlbnQ6Vy5lYSxNZWRpYVN0cmVhbUV2ZW50OlcuZWEsTWVkaWFTdHJlYW1UcmFj
-a0V2ZW50OlcuZWEsTWVzc2FnZUV2ZW50OlcuZWEsTUlESUNvbm5lY3Rpb25FdmVudDpXLmVhLE1JRElN
-ZXNzYWdlRXZlbnQ6Vy5lYSxNdXRhdGlvbkV2ZW50OlcuZWEsTm90aWZpY2F0aW9uRXZlbnQ6Vy5lYSxQ
-YWdlVHJhbnNpdGlvbkV2ZW50OlcuZWEsUGF5bWVudFJlcXVlc3RFdmVudDpXLmVhLFBheW1lbnRSZXF1
-ZXN0VXBkYXRlRXZlbnQ6Vy5lYSxQb3BTdGF0ZUV2ZW50OlcuZWEsUHJlc2VudGF0aW9uQ29ubmVjdGlv
-bkF2YWlsYWJsZUV2ZW50OlcuZWEsUHJlc2VudGF0aW9uQ29ubmVjdGlvbkNsb3NlRXZlbnQ6Vy5lYSxQ
-cm9taXNlUmVqZWN0aW9uRXZlbnQ6Vy5lYSxQdXNoRXZlbnQ6Vy5lYSxSVENEYXRhQ2hhbm5lbEV2ZW50
-OlcuZWEsUlRDRFRNRlRvbmVDaGFuZ2VFdmVudDpXLmVhLFJUQ1BlZXJDb25uZWN0aW9uSWNlRXZlbnQ6
-Vy5lYSxSVENUcmFja0V2ZW50OlcuZWEsU2VjdXJpdHlQb2xpY3lWaW9sYXRpb25FdmVudDpXLmVhLFNl
-bnNvckVycm9yRXZlbnQ6Vy5lYSxTcGVlY2hSZWNvZ25pdGlvbkVycm9yOlcuZWEsU3BlZWNoUmVjb2du
-aXRpb25FdmVudDpXLmVhLFNwZWVjaFN5bnRoZXNpc0V2ZW50OlcuZWEsU3RvcmFnZUV2ZW50OlcuZWEs
-U3luY0V2ZW50OlcuZWEsVHJhY2tFdmVudDpXLmVhLFRyYW5zaXRpb25FdmVudDpXLmVhLFdlYktpdFRy
-YW5zaXRpb25FdmVudDpXLmVhLFZSRGV2aWNlRXZlbnQ6Vy5lYSxWUkRpc3BsYXlFdmVudDpXLmVhLFZS
-U2Vzc2lvbkV2ZW50OlcuZWEsTW9qb0ludGVyZmFjZVJlcXVlc3RFdmVudDpXLmVhLFVTQkNvbm5lY3Rp
-b25FdmVudDpXLmVhLElEQlZlcnNpb25DaGFuZ2VFdmVudDpXLmVhLEF1ZGlvUHJvY2Vzc2luZ0V2ZW50
-OlcuZWEsT2ZmbGluZUF1ZGlvQ29tcGxldGlvbkV2ZW50OlcuZWEsV2ViR0xDb250ZXh0RXZlbnQ6Vy5l
-YSxFdmVudDpXLmVhLElucHV0RXZlbnQ6Vy5lYSxTdWJtaXRFdmVudDpXLmVhLEV2ZW50VGFyZ2V0Olcu
-RDAsRmlsZTpXLmhILEhUTUxGb3JtRWxlbWVudDpXLmg0LEhpc3Rvcnk6Vy5icixIVE1MRG9jdW1lbnQ6
-Vy5WYixYTUxIdHRwUmVxdWVzdDpXLmZKLFhNTEh0dHBSZXF1ZXN0RXZlbnRUYXJnZXQ6Vy53YSxJbWFn
-ZURhdGE6Vy5TZyxMb2NhdGlvbjpXLnc3LE1vdXNlRXZlbnQ6Vy5BaixEcmFnRXZlbnQ6Vy5BaixQb2lu
-dGVyRXZlbnQ6Vy5BaixXaGVlbEV2ZW50OlcuQWosRG9jdW1lbnRGcmFnbWVudDpXLnVILFNoYWRvd1Jv
-b3Q6Vy51SCxEb2N1bWVudFR5cGU6Vy51SCxOb2RlOlcudUgsTm9kZUxpc3Q6Vy5CSCxSYWRpb05vZGVM
-aXN0OlcuQkgsSFRNTFBhcmFncmFwaEVsZW1lbnQ6Vy5TTixQcm9ncmVzc0V2ZW50OlcuZXcsUmVzb3Vy
-Y2VQcm9ncmVzc0V2ZW50OlcuZXcsSFRNTFNlbGVjdEVsZW1lbnQ6Vy5scCxIVE1MVGFibGVFbGVtZW50
-OlcuVGIsSFRNTFRhYmxlUm93RWxlbWVudDpXLkl2LEhUTUxUYWJsZVNlY3Rpb25FbGVtZW50OlcuV1As
-SFRNTFRlbXBsYXRlRWxlbWVudDpXLnlZLENvbXBvc2l0aW9uRXZlbnQ6Vy53NixGb2N1c0V2ZW50Olcu
-dzYsS2V5Ym9hcmRFdmVudDpXLnc2LFRleHRFdmVudDpXLnc2LFRvdWNoRXZlbnQ6Vy53NixVSUV2ZW50
-OlcudzYsV2luZG93OlcuSzUsRE9NV2luZG93OlcuSzUsRGVkaWNhdGVkV29ya2VyR2xvYmFsU2NvcGU6
-Vy5DbSxTZXJ2aWNlV29ya2VyR2xvYmFsU2NvcGU6Vy5DbSxTaGFyZWRXb3JrZXJHbG9iYWxTY29wZTpX
-LkNtLFdvcmtlckdsb2JhbFNjb3BlOlcuQ20sQXR0cjpXLkNRLENsaWVudFJlY3Q6Vy53NCxET01SZWN0
-OlcudzQsTmFtZWROb2RlTWFwOlcucmgsTW96TmFtZWRBdHRyTWFwOlcucmgsSURCS2V5UmFuZ2U6UC5o
-RixTVkdTY3JpcHRFbGVtZW50OlAubmQsU1ZHQUVsZW1lbnQ6UC5oaSxTVkdBbmltYXRlRWxlbWVudDpQ
-LmhpLFNWR0FuaW1hdGVNb3Rpb25FbGVtZW50OlAuaGksU1ZHQW5pbWF0ZVRyYW5zZm9ybUVsZW1lbnQ6
-UC5oaSxTVkdBbmltYXRpb25FbGVtZW50OlAuaGksU1ZHQ2lyY2xlRWxlbWVudDpQLmhpLFNWR0NsaXBQ
-YXRoRWxlbWVudDpQLmhpLFNWR0RlZnNFbGVtZW50OlAuaGksU1ZHRGVzY0VsZW1lbnQ6UC5oaSxTVkdE
-aXNjYXJkRWxlbWVudDpQLmhpLFNWR0VsbGlwc2VFbGVtZW50OlAuaGksU1ZHRkVCbGVuZEVsZW1lbnQ6
-UC5oaSxTVkdGRUNvbG9yTWF0cml4RWxlbWVudDpQLmhpLFNWR0ZFQ29tcG9uZW50VHJhbnNmZXJFbGVt
-ZW50OlAuaGksU1ZHRkVDb21wb3NpdGVFbGVtZW50OlAuaGksU1ZHRkVDb252b2x2ZU1hdHJpeEVsZW1l
-bnQ6UC5oaSxTVkdGRURpZmZ1c2VMaWdodGluZ0VsZW1lbnQ6UC5oaSxTVkdGRURpc3BsYWNlbWVudE1h
-cEVsZW1lbnQ6UC5oaSxTVkdGRURpc3RhbnRMaWdodEVsZW1lbnQ6UC5oaSxTVkdGRUZsb29kRWxlbWVu
-dDpQLmhpLFNWR0ZFRnVuY0FFbGVtZW50OlAuaGksU1ZHRkVGdW5jQkVsZW1lbnQ6UC5oaSxTVkdGRUZ1
-bmNHRWxlbWVudDpQLmhpLFNWR0ZFRnVuY1JFbGVtZW50OlAuaGksU1ZHRkVHYXVzc2lhbkJsdXJFbGVt
-ZW50OlAuaGksU1ZHRkVJbWFnZUVsZW1lbnQ6UC5oaSxTVkdGRU1lcmdlRWxlbWVudDpQLmhpLFNWR0ZF
-TWVyZ2VOb2RlRWxlbWVudDpQLmhpLFNWR0ZFTW9ycGhvbG9neUVsZW1lbnQ6UC5oaSxTVkdGRU9mZnNl
-dEVsZW1lbnQ6UC5oaSxTVkdGRVBvaW50TGlnaHRFbGVtZW50OlAuaGksU1ZHRkVTcGVjdWxhckxpZ2h0
-aW5nRWxlbWVudDpQLmhpLFNWR0ZFU3BvdExpZ2h0RWxlbWVudDpQLmhpLFNWR0ZFVGlsZUVsZW1lbnQ6
-UC5oaSxTVkdGRVR1cmJ1bGVuY2VFbGVtZW50OlAuaGksU1ZHRmlsdGVyRWxlbWVudDpQLmhpLFNWR0Zv
-cmVpZ25PYmplY3RFbGVtZW50OlAuaGksU1ZHR0VsZW1lbnQ6UC5oaSxTVkdHZW9tZXRyeUVsZW1lbnQ6
-UC5oaSxTVkdHcmFwaGljc0VsZW1lbnQ6UC5oaSxTVkdJbWFnZUVsZW1lbnQ6UC5oaSxTVkdMaW5lRWxl
-bWVudDpQLmhpLFNWR0xpbmVhckdyYWRpZW50RWxlbWVudDpQLmhpLFNWR01hcmtlckVsZW1lbnQ6UC5o
-aSxTVkdNYXNrRWxlbWVudDpQLmhpLFNWR01ldGFkYXRhRWxlbWVudDpQLmhpLFNWR1BhdGhFbGVtZW50
-OlAuaGksU1ZHUGF0dGVybkVsZW1lbnQ6UC5oaSxTVkdQb2x5Z29uRWxlbWVudDpQLmhpLFNWR1BvbHls
-aW5lRWxlbWVudDpQLmhpLFNWR1JhZGlhbEdyYWRpZW50RWxlbWVudDpQLmhpLFNWR1JlY3RFbGVtZW50
-OlAuaGksU1ZHU2V0RWxlbWVudDpQLmhpLFNWR1N0b3BFbGVtZW50OlAuaGksU1ZHU3R5bGVFbGVtZW50
-OlAuaGksU1ZHU1ZHRWxlbWVudDpQLmhpLFNWR1N3aXRjaEVsZW1lbnQ6UC5oaSxTVkdTeW1ib2xFbGVt
-ZW50OlAuaGksU1ZHVFNwYW5FbGVtZW50OlAuaGksU1ZHVGV4dENvbnRlbnRFbGVtZW50OlAuaGksU1ZH
-VGV4dEVsZW1lbnQ6UC5oaSxTVkdUZXh0UGF0aEVsZW1lbnQ6UC5oaSxTVkdUZXh0UG9zaXRpb25pbmdF
-bGVtZW50OlAuaGksU1ZHVGl0bGVFbGVtZW50OlAuaGksU1ZHVXNlRWxlbWVudDpQLmhpLFNWR1ZpZXdF
-bGVtZW50OlAuaGksU1ZHR3JhZGllbnRFbGVtZW50OlAuaGksU1ZHQ29tcG9uZW50VHJhbnNmZXJGdW5j
-dGlvbkVsZW1lbnQ6UC5oaSxTVkdGRURyb3BTaGFkb3dFbGVtZW50OlAuaGksU1ZHTVBhdGhFbGVtZW50
-OlAuaGksU1ZHRWxlbWVudDpQLmhpfSkKaHVua0hlbHBlcnMuc2V0T3JVcGRhdGVMZWFmVGFncyh7RE9N
-RXJyb3I6dHJ1ZSxNZWRpYUVycm9yOnRydWUsTmF2aWdhdG9yOnRydWUsTmF2aWdhdG9yQ29uY3VycmVu
-dEhhcmR3YXJlOnRydWUsTmF2aWdhdG9yVXNlck1lZGlhRXJyb3I6dHJ1ZSxPdmVyY29uc3RyYWluZWRF
-cnJvcjp0cnVlLFBvc2l0aW9uRXJyb3I6dHJ1ZSxSYW5nZTp0cnVlLFNRTEVycm9yOnRydWUsRGF0YVZp
-ZXc6dHJ1ZSxBcnJheUJ1ZmZlclZpZXc6ZmFsc2UsRmxvYXQzMkFycmF5OnRydWUsRmxvYXQ2NEFycmF5
-OnRydWUsSW50MTZBcnJheTp0cnVlLEludDMyQXJyYXk6dHJ1ZSxJbnQ4QXJyYXk6dHJ1ZSxVaW50MTZB
-cnJheTp0cnVlLFVpbnQzMkFycmF5OnRydWUsVWludDhDbGFtcGVkQXJyYXk6dHJ1ZSxDYW52YXNQaXhl
-bEFycmF5OnRydWUsVWludDhBcnJheTpmYWxzZSxIVE1MQXVkaW9FbGVtZW50OnRydWUsSFRNTEJSRWxl
-bWVudDp0cnVlLEhUTUxCdXR0b25FbGVtZW50OnRydWUsSFRNTENhbnZhc0VsZW1lbnQ6dHJ1ZSxIVE1M
-Q29udGVudEVsZW1lbnQ6dHJ1ZSxIVE1MRExpc3RFbGVtZW50OnRydWUsSFRNTERhdGFFbGVtZW50OnRy
-dWUsSFRNTERhdGFMaXN0RWxlbWVudDp0cnVlLEhUTUxEZXRhaWxzRWxlbWVudDp0cnVlLEhUTUxEaWFs
-b2dFbGVtZW50OnRydWUsSFRNTERpdkVsZW1lbnQ6dHJ1ZSxIVE1MRW1iZWRFbGVtZW50OnRydWUsSFRN
-TEZpZWxkU2V0RWxlbWVudDp0cnVlLEhUTUxIUkVsZW1lbnQ6dHJ1ZSxIVE1MSGVhZEVsZW1lbnQ6dHJ1
-ZSxIVE1MSGVhZGluZ0VsZW1lbnQ6dHJ1ZSxIVE1MSHRtbEVsZW1lbnQ6dHJ1ZSxIVE1MSUZyYW1lRWxl
-bWVudDp0cnVlLEhUTUxJbWFnZUVsZW1lbnQ6dHJ1ZSxIVE1MSW5wdXRFbGVtZW50OnRydWUsSFRNTExJ
-RWxlbWVudDp0cnVlLEhUTUxMYWJlbEVsZW1lbnQ6dHJ1ZSxIVE1MTGVnZW5kRWxlbWVudDp0cnVlLEhU
-TUxMaW5rRWxlbWVudDp0cnVlLEhUTUxNYXBFbGVtZW50OnRydWUsSFRNTE1lZGlhRWxlbWVudDp0cnVl
-LEhUTUxNZW51RWxlbWVudDp0cnVlLEhUTUxNZXRhRWxlbWVudDp0cnVlLEhUTUxNZXRlckVsZW1lbnQ6
-dHJ1ZSxIVE1MTW9kRWxlbWVudDp0cnVlLEhUTUxPTGlzdEVsZW1lbnQ6dHJ1ZSxIVE1MT2JqZWN0RWxl
-bWVudDp0cnVlLEhUTUxPcHRHcm91cEVsZW1lbnQ6dHJ1ZSxIVE1MT3B0aW9uRWxlbWVudDp0cnVlLEhU
-TUxPdXRwdXRFbGVtZW50OnRydWUsSFRNTFBhcmFtRWxlbWVudDp0cnVlLEhUTUxQaWN0dXJlRWxlbWVu
-dDp0cnVlLEhUTUxQcmVFbGVtZW50OnRydWUsSFRNTFByb2dyZXNzRWxlbWVudDp0cnVlLEhUTUxRdW90
-ZUVsZW1lbnQ6dHJ1ZSxIVE1MU2NyaXB0RWxlbWVudDp0cnVlLEhUTUxTaGFkb3dFbGVtZW50OnRydWUs
-SFRNTFNsb3RFbGVtZW50OnRydWUsSFRNTFNvdXJjZUVsZW1lbnQ6dHJ1ZSxIVE1MU3BhbkVsZW1lbnQ6
-dHJ1ZSxIVE1MU3R5bGVFbGVtZW50OnRydWUsSFRNTFRhYmxlQ2FwdGlvbkVsZW1lbnQ6dHJ1ZSxIVE1M
-VGFibGVDZWxsRWxlbWVudDp0cnVlLEhUTUxUYWJsZURhdGFDZWxsRWxlbWVudDp0cnVlLEhUTUxUYWJs
-ZUhlYWRlckNlbGxFbGVtZW50OnRydWUsSFRNTFRhYmxlQ29sRWxlbWVudDp0cnVlLEhUTUxUZXh0QXJl
-YUVsZW1lbnQ6dHJ1ZSxIVE1MVGltZUVsZW1lbnQ6dHJ1ZSxIVE1MVGl0bGVFbGVtZW50OnRydWUsSFRN
-TFRyYWNrRWxlbWVudDp0cnVlLEhUTUxVTGlzdEVsZW1lbnQ6dHJ1ZSxIVE1MVW5rbm93bkVsZW1lbnQ6
-dHJ1ZSxIVE1MVmlkZW9FbGVtZW50OnRydWUsSFRNTERpcmVjdG9yeUVsZW1lbnQ6dHJ1ZSxIVE1MRm9u
-dEVsZW1lbnQ6dHJ1ZSxIVE1MRnJhbWVFbGVtZW50OnRydWUsSFRNTEZyYW1lU2V0RWxlbWVudDp0cnVl
-LEhUTUxNYXJxdWVlRWxlbWVudDp0cnVlLEhUTUxFbGVtZW50OmZhbHNlLEhUTUxBbmNob3JFbGVtZW50
-OnRydWUsSFRNTEFyZWFFbGVtZW50OnRydWUsSFRNTEJhc2VFbGVtZW50OnRydWUsQmxvYjpmYWxzZSxI
-VE1MQm9keUVsZW1lbnQ6dHJ1ZSxDREFUQVNlY3Rpb246dHJ1ZSxDaGFyYWN0ZXJEYXRhOnRydWUsQ29t
-bWVudDp0cnVlLFByb2Nlc3NpbmdJbnN0cnVjdGlvbjp0cnVlLFRleHQ6dHJ1ZSxDU1NTdHlsZURlY2xh
-cmF0aW9uOnRydWUsTVNTdHlsZUNTU1Byb3BlcnRpZXM6dHJ1ZSxDU1MyUHJvcGVydGllczp0cnVlLFhN
-TERvY3VtZW50OnRydWUsRG9jdW1lbnQ6ZmFsc2UsRE9NRXhjZXB0aW9uOnRydWUsRE9NSW1wbGVtZW50
-YXRpb246dHJ1ZSxET01SZWN0UmVhZE9ubHk6ZmFsc2UsRE9NVG9rZW5MaXN0OnRydWUsRWxlbWVudDpm
-YWxzZSxBYm9ydFBheW1lbnRFdmVudDp0cnVlLEFuaW1hdGlvbkV2ZW50OnRydWUsQW5pbWF0aW9uUGxh
-eWJhY2tFdmVudDp0cnVlLEFwcGxpY2F0aW9uQ2FjaGVFcnJvckV2ZW50OnRydWUsQmFja2dyb3VuZEZl
-dGNoQ2xpY2tFdmVudDp0cnVlLEJhY2tncm91bmRGZXRjaEV2ZW50OnRydWUsQmFja2dyb3VuZEZldGNo
-RmFpbEV2ZW50OnRydWUsQmFja2dyb3VuZEZldGNoZWRFdmVudDp0cnVlLEJlZm9yZUluc3RhbGxQcm9t
-cHRFdmVudDp0cnVlLEJlZm9yZVVubG9hZEV2ZW50OnRydWUsQmxvYkV2ZW50OnRydWUsQ2FuTWFrZVBh
-eW1lbnRFdmVudDp0cnVlLENsaXBib2FyZEV2ZW50OnRydWUsQ2xvc2VFdmVudDp0cnVlLEN1c3RvbUV2
-ZW50OnRydWUsRGV2aWNlTW90aW9uRXZlbnQ6dHJ1ZSxEZXZpY2VPcmllbnRhdGlvbkV2ZW50OnRydWUs
-RXJyb3JFdmVudDp0cnVlLEV4dGVuZGFibGVFdmVudDp0cnVlLEV4dGVuZGFibGVNZXNzYWdlRXZlbnQ6
-dHJ1ZSxGZXRjaEV2ZW50OnRydWUsRm9udEZhY2VTZXRMb2FkRXZlbnQ6dHJ1ZSxGb3JlaWduRmV0Y2hF
-dmVudDp0cnVlLEdhbWVwYWRFdmVudDp0cnVlLEhhc2hDaGFuZ2VFdmVudDp0cnVlLEluc3RhbGxFdmVu
-dDp0cnVlLE1lZGlhRW5jcnlwdGVkRXZlbnQ6dHJ1ZSxNZWRpYUtleU1lc3NhZ2VFdmVudDp0cnVlLE1l
-ZGlhUXVlcnlMaXN0RXZlbnQ6dHJ1ZSxNZWRpYVN0cmVhbUV2ZW50OnRydWUsTWVkaWFTdHJlYW1UcmFj
-a0V2ZW50OnRydWUsTWVzc2FnZUV2ZW50OnRydWUsTUlESUNvbm5lY3Rpb25FdmVudDp0cnVlLE1JRElN
-ZXNzYWdlRXZlbnQ6dHJ1ZSxNdXRhdGlvbkV2ZW50OnRydWUsTm90aWZpY2F0aW9uRXZlbnQ6dHJ1ZSxQ
-YWdlVHJhbnNpdGlvbkV2ZW50OnRydWUsUGF5bWVudFJlcXVlc3RFdmVudDp0cnVlLFBheW1lbnRSZXF1
-ZXN0VXBkYXRlRXZlbnQ6dHJ1ZSxQb3BTdGF0ZUV2ZW50OnRydWUsUHJlc2VudGF0aW9uQ29ubmVjdGlv
-bkF2YWlsYWJsZUV2ZW50OnRydWUsUHJlc2VudGF0aW9uQ29ubmVjdGlvbkNsb3NlRXZlbnQ6dHJ1ZSxQ
-cm9taXNlUmVqZWN0aW9uRXZlbnQ6dHJ1ZSxQdXNoRXZlbnQ6dHJ1ZSxSVENEYXRhQ2hhbm5lbEV2ZW50
-OnRydWUsUlRDRFRNRlRvbmVDaGFuZ2VFdmVudDp0cnVlLFJUQ1BlZXJDb25uZWN0aW9uSWNlRXZlbnQ6
-dHJ1ZSxSVENUcmFja0V2ZW50OnRydWUsU2VjdXJpdHlQb2xpY3lWaW9sYXRpb25FdmVudDp0cnVlLFNl
-bnNvckVycm9yRXZlbnQ6dHJ1ZSxTcGVlY2hSZWNvZ25pdGlvbkVycm9yOnRydWUsU3BlZWNoUmVjb2du
-aXRpb25FdmVudDp0cnVlLFNwZWVjaFN5bnRoZXNpc0V2ZW50OnRydWUsU3RvcmFnZUV2ZW50OnRydWUs
-U3luY0V2ZW50OnRydWUsVHJhY2tFdmVudDp0cnVlLFRyYW5zaXRpb25FdmVudDp0cnVlLFdlYktpdFRy
-YW5zaXRpb25FdmVudDp0cnVlLFZSRGV2aWNlRXZlbnQ6dHJ1ZSxWUkRpc3BsYXlFdmVudDp0cnVlLFZS
-U2Vzc2lvbkV2ZW50OnRydWUsTW9qb0ludGVyZmFjZVJlcXVlc3RFdmVudDp0cnVlLFVTQkNvbm5lY3Rp
-b25FdmVudDp0cnVlLElEQlZlcnNpb25DaGFuZ2VFdmVudDp0cnVlLEF1ZGlvUHJvY2Vzc2luZ0V2ZW50
-OnRydWUsT2ZmbGluZUF1ZGlvQ29tcGxldGlvbkV2ZW50OnRydWUsV2ViR0xDb250ZXh0RXZlbnQ6dHJ1
-ZSxFdmVudDpmYWxzZSxJbnB1dEV2ZW50OmZhbHNlLFN1Ym1pdEV2ZW50OmZhbHNlLEV2ZW50VGFyZ2V0
-OmZhbHNlLEZpbGU6dHJ1ZSxIVE1MRm9ybUVsZW1lbnQ6dHJ1ZSxIaXN0b3J5OnRydWUsSFRNTERvY3Vt
-ZW50OnRydWUsWE1MSHR0cFJlcXVlc3Q6dHJ1ZSxYTUxIdHRwUmVxdWVzdEV2ZW50VGFyZ2V0OmZhbHNl
-LEltYWdlRGF0YTp0cnVlLExvY2F0aW9uOnRydWUsTW91c2VFdmVudDp0cnVlLERyYWdFdmVudDp0cnVl
-LFBvaW50ZXJFdmVudDp0cnVlLFdoZWVsRXZlbnQ6dHJ1ZSxEb2N1bWVudEZyYWdtZW50OnRydWUsU2hh
-ZG93Um9vdDp0cnVlLERvY3VtZW50VHlwZTp0cnVlLE5vZGU6ZmFsc2UsTm9kZUxpc3Q6dHJ1ZSxSYWRp
-b05vZGVMaXN0OnRydWUsSFRNTFBhcmFncmFwaEVsZW1lbnQ6dHJ1ZSxQcm9ncmVzc0V2ZW50OnRydWUs
-UmVzb3VyY2VQcm9ncmVzc0V2ZW50OnRydWUsSFRNTFNlbGVjdEVsZW1lbnQ6dHJ1ZSxIVE1MVGFibGVF
-bGVtZW50OnRydWUsSFRNTFRhYmxlUm93RWxlbWVudDp0cnVlLEhUTUxUYWJsZVNlY3Rpb25FbGVtZW50
-OnRydWUsSFRNTFRlbXBsYXRlRWxlbWVudDp0cnVlLENvbXBvc2l0aW9uRXZlbnQ6dHJ1ZSxGb2N1c0V2
-ZW50OnRydWUsS2V5Ym9hcmRFdmVudDp0cnVlLFRleHRFdmVudDp0cnVlLFRvdWNoRXZlbnQ6dHJ1ZSxV
-SUV2ZW50OmZhbHNlLFdpbmRvdzp0cnVlLERPTVdpbmRvdzp0cnVlLERlZGljYXRlZFdvcmtlckdsb2Jh
-bFNjb3BlOnRydWUsU2VydmljZVdvcmtlckdsb2JhbFNjb3BlOnRydWUsU2hhcmVkV29ya2VyR2xvYmFs
-U2NvcGU6dHJ1ZSxXb3JrZXJHbG9iYWxTY29wZTp0cnVlLEF0dHI6dHJ1ZSxDbGllbnRSZWN0OnRydWUs
-RE9NUmVjdDp0cnVlLE5hbWVkTm9kZU1hcDp0cnVlLE1vek5hbWVkQXR0ck1hcDp0cnVlLElEQktleVJh
-bmdlOnRydWUsU1ZHU2NyaXB0RWxlbWVudDp0cnVlLFNWR0FFbGVtZW50OnRydWUsU1ZHQW5pbWF0ZUVs
-ZW1lbnQ6dHJ1ZSxTVkdBbmltYXRlTW90aW9uRWxlbWVudDp0cnVlLFNWR0FuaW1hdGVUcmFuc2Zvcm1F
-bGVtZW50OnRydWUsU1ZHQW5pbWF0aW9uRWxlbWVudDp0cnVlLFNWR0NpcmNsZUVsZW1lbnQ6dHJ1ZSxT
-VkdDbGlwUGF0aEVsZW1lbnQ6dHJ1ZSxTVkdEZWZzRWxlbWVudDp0cnVlLFNWR0Rlc2NFbGVtZW50OnRy
-dWUsU1ZHRGlzY2FyZEVsZW1lbnQ6dHJ1ZSxTVkdFbGxpcHNlRWxlbWVudDp0cnVlLFNWR0ZFQmxlbmRF
-bGVtZW50OnRydWUsU1ZHRkVDb2xvck1hdHJpeEVsZW1lbnQ6dHJ1ZSxTVkdGRUNvbXBvbmVudFRyYW5z
-ZmVyRWxlbWVudDp0cnVlLFNWR0ZFQ29tcG9zaXRlRWxlbWVudDp0cnVlLFNWR0ZFQ29udm9sdmVNYXRy
-aXhFbGVtZW50OnRydWUsU1ZHRkVEaWZmdXNlTGlnaHRpbmdFbGVtZW50OnRydWUsU1ZHRkVEaXNwbGFj
-ZW1lbnRNYXBFbGVtZW50OnRydWUsU1ZHRkVEaXN0YW50TGlnaHRFbGVtZW50OnRydWUsU1ZHRkVGbG9v
-ZEVsZW1lbnQ6dHJ1ZSxTVkdGRUZ1bmNBRWxlbWVudDp0cnVlLFNWR0ZFRnVuY0JFbGVtZW50OnRydWUs
-U1ZHRkVGdW5jR0VsZW1lbnQ6dHJ1ZSxTVkdGRUZ1bmNSRWxlbWVudDp0cnVlLFNWR0ZFR2F1c3NpYW5C
-bHVyRWxlbWVudDp0cnVlLFNWR0ZFSW1hZ2VFbGVtZW50OnRydWUsU1ZHRkVNZXJnZUVsZW1lbnQ6dHJ1
-ZSxTVkdGRU1lcmdlTm9kZUVsZW1lbnQ6dHJ1ZSxTVkdGRU1vcnBob2xvZ3lFbGVtZW50OnRydWUsU1ZH
-RkVPZmZzZXRFbGVtZW50OnRydWUsU1ZHRkVQb2ludExpZ2h0RWxlbWVudDp0cnVlLFNWR0ZFU3BlY3Vs
-YXJMaWdodGluZ0VsZW1lbnQ6dHJ1ZSxTVkdGRVNwb3RMaWdodEVsZW1lbnQ6dHJ1ZSxTVkdGRVRpbGVF
-bGVtZW50OnRydWUsU1ZHRkVUdXJidWxlbmNlRWxlbWVudDp0cnVlLFNWR0ZpbHRlckVsZW1lbnQ6dHJ1
-ZSxTVkdGb3JlaWduT2JqZWN0RWxlbWVudDp0cnVlLFNWR0dFbGVtZW50OnRydWUsU1ZHR2VvbWV0cnlF
-bGVtZW50OnRydWUsU1ZHR3JhcGhpY3NFbGVtZW50OnRydWUsU1ZHSW1hZ2VFbGVtZW50OnRydWUsU1ZH
-TGluZUVsZW1lbnQ6dHJ1ZSxTVkdMaW5lYXJHcmFkaWVudEVsZW1lbnQ6dHJ1ZSxTVkdNYXJrZXJFbGVt
-ZW50OnRydWUsU1ZHTWFza0VsZW1lbnQ6dHJ1ZSxTVkdNZXRhZGF0YUVsZW1lbnQ6dHJ1ZSxTVkdQYXRo
-RWxlbWVudDp0cnVlLFNWR1BhdHRlcm5FbGVtZW50OnRydWUsU1ZHUG9seWdvbkVsZW1lbnQ6dHJ1ZSxT
-VkdQb2x5bGluZUVsZW1lbnQ6dHJ1ZSxTVkdSYWRpYWxHcmFkaWVudEVsZW1lbnQ6dHJ1ZSxTVkdSZWN0
-RWxlbWVudDp0cnVlLFNWR1NldEVsZW1lbnQ6dHJ1ZSxTVkdTdG9wRWxlbWVudDp0cnVlLFNWR1N0eWxl
-RWxlbWVudDp0cnVlLFNWR1NWR0VsZW1lbnQ6dHJ1ZSxTVkdTd2l0Y2hFbGVtZW50OnRydWUsU1ZHU3lt
-Ym9sRWxlbWVudDp0cnVlLFNWR1RTcGFuRWxlbWVudDp0cnVlLFNWR1RleHRDb250ZW50RWxlbWVudDp0
-cnVlLFNWR1RleHRFbGVtZW50OnRydWUsU1ZHVGV4dFBhdGhFbGVtZW50OnRydWUsU1ZHVGV4dFBvc2l0
-aW9uaW5nRWxlbWVudDp0cnVlLFNWR1RpdGxlRWxlbWVudDp0cnVlLFNWR1VzZUVsZW1lbnQ6dHJ1ZSxT
-VkdWaWV3RWxlbWVudDp0cnVlLFNWR0dyYWRpZW50RWxlbWVudDp0cnVlLFNWR0NvbXBvbmVudFRyYW5z
-ZmVyRnVuY3Rpb25FbGVtZW50OnRydWUsU1ZHRkVEcm9wU2hhZG93RWxlbWVudDp0cnVlLFNWR01QYXRo
-RWxlbWVudDp0cnVlLFNWR0VsZW1lbnQ6ZmFsc2V9KQpILkxaLiRuYXRpdmVTdXBlcmNsYXNzVGFnPSJB
-cnJheUJ1ZmZlclZpZXciCkguUkcuJG5hdGl2ZVN1cGVyY2xhc3NUYWc9IkFycmF5QnVmZmVyVmlldyIK
-SC5WUC4kbmF0aXZlU3VwZXJjbGFzc1RhZz0iQXJyYXlCdWZmZXJWaWV3IgpILkRnLiRuYXRpdmVTdXBl
-cmNsYXNzVGFnPSJBcnJheUJ1ZmZlclZpZXciCkguV0IuJG5hdGl2ZVN1cGVyY2xhc3NUYWc9IkFycmF5
-QnVmZmVyVmlldyIKSC5aRy4kbmF0aXZlU3VwZXJjbGFzc1RhZz0iQXJyYXlCdWZmZXJWaWV3IgpILlBn
-LiRuYXRpdmVTdXBlcmNsYXNzVGFnPSJBcnJheUJ1ZmZlclZpZXcifSkoKQpjb252ZXJ0QWxsVG9GYXN0
-T2JqZWN0KHcpCmNvbnZlcnRUb0Zhc3RPYmplY3QoJCk7KGZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBkb2N1
-bWVudD09PSJ1bmRlZmluZWQiKXthKG51bGwpCnJldHVybn1pZih0eXBlb2YgZG9jdW1lbnQuY3VycmVu
-dFNjcmlwdCE9InVuZGVmaW5lZCIpe2EoZG9jdW1lbnQuY3VycmVudFNjcmlwdCkKcmV0dXJufXZhciBz
-PWRvY3VtZW50LnNjcmlwdHMKZnVuY3Rpb24gb25Mb2FkKGIpe2Zvcih2YXIgcT0wO3E8cy5sZW5ndGg7
-KytxKXNbcV0ucmVtb3ZlRXZlbnRMaXN0ZW5lcigibG9hZCIsb25Mb2FkLGZhbHNlKQphKGIudGFyZ2V0
-KX1mb3IodmFyIHI9MDtyPHMubGVuZ3RoOysrcilzW3JdLmFkZEV2ZW50TGlzdGVuZXIoImxvYWQiLG9u
-TG9hZCxmYWxzZSl9KShmdW5jdGlvbihhKXt2LmN1cnJlbnRTY3JpcHQ9YQp2YXIgcz1MLklxCmlmKHR5
-cGVvZiBkYXJ0TWFpblJ1bm5lcj09PSJmdW5jdGlvbiIpZGFydE1haW5SdW5uZXIocyxbXSkKZWxzZSBz
-KFtdKX0pfSkoKQovLyMgc291cmNlTWFwcGluZ1VSTD1taWdyYXRpb24uanMubWFwCg==
+LC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0xLC0yLC0yLC0yLC0yLC0yLDYy
+LC0yLDYyLC0yLDYzLDUyLDUzLDU0LDU1LDU2LDU3LDU4LDU5LDYwLDYxLC0yLC0yLC0yLC0xLC0yLC0y
+LC0yLDAsMSwyLDMsNCw1LDYsNyw4LDksMTAsMTEsMTIsMTMsMTQsMTUsMTYsMTcsMTgsMTksMjAsMjEs
+MjIsMjMsMjQsMjUsLTIsLTIsLTIsLTIsNjMsLTIsMjYsMjcsMjgsMjksMzAsMzEsMzIsMzMsMzQsMzUs
+MzYsMzcsMzgsMzksNDAsNDEsNDIsNDMsNDQsNDUsNDYsNDcsNDgsNDksNTAsNTEsLTIsLTIsLTIsLTIs
+LTJdLHQuYSkpKX0pCnMoJCwiTTUiLCJ3USIsZnVuY3Rpb24oKXtyZXR1cm4gdHlwZW9mIHByb2Nlc3Mh
+PSJ1bmRlZmluZWQiJiZPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwocHJvY2Vzcyk9PSJbb2Jq
+ZWN0IHByb2Nlc3NdIiYmcHJvY2Vzcy5wbGF0Zm9ybT09IndpbjMyIn0pCnMoJCwibWYiLCJ6NCIsZnVu
+Y3Rpb24oKXtyZXR1cm4gUC5udSgiXltcXC1cXC4wLTlBLVpfYS16fl0qJCIpfSkKcygkLCJPUSIsInZa
+IixmdW5jdGlvbigpe3JldHVybiBQLktOKCl9KQpzKCQsIlNDIiwiQU4iLGZ1bmN0aW9uKCl7cmV0dXJu
+IFAudE0oWyJBIiwiQUJCUiIsIkFDUk9OWU0iLCJBRERSRVNTIiwiQVJFQSIsIkFSVElDTEUiLCJBU0lE
+RSIsIkFVRElPIiwiQiIsIkJESSIsIkJETyIsIkJJRyIsIkJMT0NLUVVPVEUiLCJCUiIsIkJVVFRPTiIs
+IkNBTlZBUyIsIkNBUFRJT04iLCJDRU5URVIiLCJDSVRFIiwiQ09ERSIsIkNPTCIsIkNPTEdST1VQIiwi
+Q09NTUFORCIsIkRBVEEiLCJEQVRBTElTVCIsIkREIiwiREVMIiwiREVUQUlMUyIsIkRGTiIsIkRJUiIs
+IkRJViIsIkRMIiwiRFQiLCJFTSIsIkZJRUxEU0VUIiwiRklHQ0FQVElPTiIsIkZJR1VSRSIsIkZPTlQi
+LCJGT09URVIiLCJGT1JNIiwiSDEiLCJIMiIsIkgzIiwiSDQiLCJINSIsIkg2IiwiSEVBREVSIiwiSEdS
+T1VQIiwiSFIiLCJJIiwiSUZSQU1FIiwiSU1HIiwiSU5QVVQiLCJJTlMiLCJLQkQiLCJMQUJFTCIsIkxF
+R0VORCIsIkxJIiwiTUFQIiwiTUFSSyIsIk1FTlUiLCJNRVRFUiIsIk5BViIsIk5PQlIiLCJPTCIsIk9Q
+VEdST1VQIiwiT1BUSU9OIiwiT1VUUFVUIiwiUCIsIlBSRSIsIlBST0dSRVNTIiwiUSIsIlMiLCJTQU1Q
+IiwiU0VDVElPTiIsIlNFTEVDVCIsIlNNQUxMIiwiU09VUkNFIiwiU1BBTiIsIlNUUklLRSIsIlNUUk9O
+RyIsIlNVQiIsIlNVTU1BUlkiLCJTVVAiLCJUQUJMRSIsIlRCT0RZIiwiVEQiLCJURVhUQVJFQSIsIlRG
+T09UIiwiVEgiLCJUSEVBRCIsIlRJTUUiLCJUUiIsIlRSQUNLIiwiVFQiLCJVIiwiVUwiLCJWQVIiLCJW
+SURFTyIsIldCUiJdLHQuTil9KQpzKCQsIlg0IiwiaEciLGZ1bmN0aW9uKCl7cmV0dXJuIFAubnUoIl5c
+XFMrJCIpfSkKcygkLCJ3TyIsIm93IixmdW5jdGlvbigpe3JldHVybiBQLk5EKHNlbGYpfSkKcygkLCJr
+dCIsIlI4IixmdW5jdGlvbigpe3JldHVybiBILllnKCJfJGRhcnRfZGFydE9iamVjdCIpfSkKcygkLCJm
+SyIsImtJIixmdW5jdGlvbigpe3JldHVybiBmdW5jdGlvbiBEYXJ0T2JqZWN0KGEpe3RoaXMubz1hfX0p
+CnIoJCwicXQiLCJ6QiIsZnVuY3Rpb24oKXtyZXR1cm4gbmV3IFQubVEoKX0pCnIoJCwiT2wiLCJVRSIs
+ZnVuY3Rpb24oKXtyZXR1cm4gUC5oSyhDLm9sLmdtVyhXLngzKCkpLmhyZWYpLmdoWSgpLnEoMCwiYXV0
+aFRva2VuIil9KQpyKCQsImhUIiwieVAiLGZ1bmN0aW9uKCl7cmV0dXJuIFcuWnIoKS5xdWVyeVNlbGVj
+dG9yKCIuZWRpdC1saXN0IC5wYW5lbC1jb250ZW50Iil9KQpyKCQsIlc2IiwiaEwiLGZ1bmN0aW9uKCl7
+cmV0dXJuIFcuWnIoKS5xdWVyeVNlbGVjdG9yKCIuZWRpdC1wYW5lbCAucGFuZWwtY29udGVudCIpfSkK
+cigkLCJUUiIsIkRXIixmdW5jdGlvbigpe3JldHVybiBXLlpyKCkucXVlcnlTZWxlY3RvcigiZm9vdGVy
+Iil9KQpyKCQsIkVZIiwiZmkiLGZ1bmN0aW9uKCl7cmV0dXJuIFcuWnIoKS5xdWVyeVNlbGVjdG9yKCJo
+ZWFkZXIiKX0pCnIoJCwiYkEiLCJjMCIsZnVuY3Rpb24oKXtyZXR1cm4gVy5acigpLnF1ZXJ5U2VsZWN0
+b3IoIiNtaWdyYXRlLXVuaXQtc3RhdHVzLWljb24iKX0pCnIoJCwidDAiLCJiTiIsZnVuY3Rpb24oKXty
+ZXR1cm4gVy5acigpLnF1ZXJ5U2VsZWN0b3IoIiNtaWdyYXRlLXVuaXQtc3RhdHVzLWljb24tbGFiZWwi
+KX0pCnIoJCwiYXYiLCJEOSIsZnVuY3Rpb24oKXtyZXR1cm4gVy5acigpLnF1ZXJ5U2VsZWN0b3IoIiN1
+bml0LW5hbWUiKX0pCnIoJCwiZmUiLCJLRyIsZnVuY3Rpb24oKXtyZXR1cm4gbmV3IEwuWEEoKX0pCnMo
+JCwiZW8iLCJuVSIsZnVuY3Rpb24oKXtyZXR1cm4gbmV3IE0ubEkoJC5IaygpKX0pCnMoJCwieXIiLCJi
+RCIsZnVuY3Rpb24oKXtyZXR1cm4gbmV3IEUuT0YoUC5udSgiLyIpLFAubnUoIlteL10kIiksUC5udSgi
+Xi8iKSl9KQpzKCQsIk1rIiwiS2siLGZ1bmN0aW9uKCl7cmV0dXJuIG5ldyBMLklWKFAubnUoIlsvXFxc
+XF0iKSxQLm51KCJbXi9cXFxcXSQiKSxQLm51KCJeKFxcXFxcXFxcW15cXFxcXStcXFxcW15cXFxcL10r
+fFthLXpBLVpdOlsvXFxcXF0pIiksUC5udSgiXlsvXFxcXF0oPyFbL1xcXFxdKSIpKX0pCnMoJCwiYWsi
+LCJFYiIsZnVuY3Rpb24oKXtyZXR1cm4gbmV3IEYucnUoUC5udSgiLyIpLFAubnUoIiheW2EtekEtWl1b
+LSsuYS16QS1aXFxkXSo6Ly98W14vXSkkIiksUC5udSgiW2EtekEtWl1bLSsuYS16QS1aXFxkXSo6Ly9b
+Xi9dKiIpLFAubnUoIl4vIikpfSkKcygkLCJscyIsIkhrIixmdW5jdGlvbigpe3JldHVybiBPLlJoKCl9
+KX0pKCk7KGZ1bmN0aW9uIG5hdGl2ZVN1cHBvcnQoKXshZnVuY3Rpb24oKXt2YXIgcz1mdW5jdGlvbihh
+KXt2YXIgbT17fQptW2FdPTEKcmV0dXJuIE9iamVjdC5rZXlzKGh1bmtIZWxwZXJzLmNvbnZlcnRUb0Zh
+c3RPYmplY3QobSkpWzBdfQp2LmdldElzb2xhdGVUYWc9ZnVuY3Rpb24oYSl7cmV0dXJuIHMoIl9fX2Rh
+cnRfIithK3YuaXNvbGF0ZVRhZyl9CnZhciByPSJfX19kYXJ0X2lzb2xhdGVfdGFnc18iCnZhciBxPU9i
+amVjdFtyXXx8KE9iamVjdFtyXT1PYmplY3QuY3JlYXRlKG51bGwpKQp2YXIgcD0iX1p4WXhYIgpmb3Io
+dmFyIG89MDs7bysrKXt2YXIgbj1zKHArIl8iK28rIl8iKQppZighKG4gaW4gcSkpe3Fbbl09MQp2Lmlz
+b2xhdGVUYWc9bgpicmVha319di5kaXNwYXRjaFByb3BlcnR5TmFtZT12LmdldElzb2xhdGVUYWcoImRp
+c3BhdGNoX3JlY29yZCIpfSgpCmh1bmtIZWxwZXJzLnNldE9yVXBkYXRlSW50ZXJjZXB0b3JzQnlUYWco
+e0RPTUVycm9yOkouR3YsTWVkaWFFcnJvcjpKLkd2LE5hdmlnYXRvcjpKLkd2LE5hdmlnYXRvckNvbmN1
+cnJlbnRIYXJkd2FyZTpKLkd2LE5hdmlnYXRvclVzZXJNZWRpYUVycm9yOkouR3YsT3ZlcmNvbnN0cmFp
+bmVkRXJyb3I6Si5HdixQb3NpdGlvbkVycm9yOkouR3YsUmFuZ2U6Si5HdixTUUxFcnJvcjpKLkd2LERh
+dGFWaWV3OkguRVQsQXJyYXlCdWZmZXJWaWV3OkguRVQsRmxvYXQzMkFycmF5OkguRGcsRmxvYXQ2NEFy
+cmF5OkguRGcsSW50MTZBcnJheTpILnhqLEludDMyQXJyYXk6SC5kRSxJbnQ4QXJyYXk6SC5aQSxVaW50
+MTZBcnJheTpILmRULFVpbnQzMkFycmF5OkguUHEsVWludDhDbGFtcGVkQXJyYXk6SC5lRSxDYW52YXNQ
+aXhlbEFycmF5OkguZUUsVWludDhBcnJheTpILlY2LEhUTUxBdWRpb0VsZW1lbnQ6Vy5xRSxIVE1MQlJF
+bGVtZW50OlcucUUsSFRNTEJ1dHRvbkVsZW1lbnQ6Vy5xRSxIVE1MQ2FudmFzRWxlbWVudDpXLnFFLEhU
+TUxDb250ZW50RWxlbWVudDpXLnFFLEhUTUxETGlzdEVsZW1lbnQ6Vy5xRSxIVE1MRGF0YUVsZW1lbnQ6
+Vy5xRSxIVE1MRGF0YUxpc3RFbGVtZW50OlcucUUsSFRNTERldGFpbHNFbGVtZW50OlcucUUsSFRNTERp
+YWxvZ0VsZW1lbnQ6Vy5xRSxIVE1MRGl2RWxlbWVudDpXLnFFLEhUTUxFbWJlZEVsZW1lbnQ6Vy5xRSxI
+VE1MRmllbGRTZXRFbGVtZW50OlcucUUsSFRNTEhSRWxlbWVudDpXLnFFLEhUTUxIZWFkRWxlbWVudDpX
+LnFFLEhUTUxIZWFkaW5nRWxlbWVudDpXLnFFLEhUTUxIdG1sRWxlbWVudDpXLnFFLEhUTUxJRnJhbWVF
+bGVtZW50OlcucUUsSFRNTEltYWdlRWxlbWVudDpXLnFFLEhUTUxJbnB1dEVsZW1lbnQ6Vy5xRSxIVE1M
+TElFbGVtZW50OlcucUUsSFRNTExhYmVsRWxlbWVudDpXLnFFLEhUTUxMZWdlbmRFbGVtZW50OlcucUUs
+SFRNTExpbmtFbGVtZW50OlcucUUsSFRNTE1hcEVsZW1lbnQ6Vy5xRSxIVE1MTWVkaWFFbGVtZW50Olcu
+cUUsSFRNTE1lbnVFbGVtZW50OlcucUUsSFRNTE1ldGFFbGVtZW50OlcucUUsSFRNTE1ldGVyRWxlbWVu
+dDpXLnFFLEhUTUxNb2RFbGVtZW50OlcucUUsSFRNTE9MaXN0RWxlbWVudDpXLnFFLEhUTUxPYmplY3RF
+bGVtZW50OlcucUUsSFRNTE9wdEdyb3VwRWxlbWVudDpXLnFFLEhUTUxPcHRpb25FbGVtZW50OlcucUUs
+SFRNTE91dHB1dEVsZW1lbnQ6Vy5xRSxIVE1MUGFyYW1FbGVtZW50OlcucUUsSFRNTFBpY3R1cmVFbGVt
+ZW50OlcucUUsSFRNTFByZUVsZW1lbnQ6Vy5xRSxIVE1MUHJvZ3Jlc3NFbGVtZW50OlcucUUsSFRNTFF1
+b3RlRWxlbWVudDpXLnFFLEhUTUxTY3JpcHRFbGVtZW50OlcucUUsSFRNTFNoYWRvd0VsZW1lbnQ6Vy5x
+RSxIVE1MU2xvdEVsZW1lbnQ6Vy5xRSxIVE1MU291cmNlRWxlbWVudDpXLnFFLEhUTUxTcGFuRWxlbWVu
+dDpXLnFFLEhUTUxTdHlsZUVsZW1lbnQ6Vy5xRSxIVE1MVGFibGVDYXB0aW9uRWxlbWVudDpXLnFFLEhU
+TUxUYWJsZUNlbGxFbGVtZW50OlcucUUsSFRNTFRhYmxlRGF0YUNlbGxFbGVtZW50OlcucUUsSFRNTFRh
+YmxlSGVhZGVyQ2VsbEVsZW1lbnQ6Vy5xRSxIVE1MVGFibGVDb2xFbGVtZW50OlcucUUsSFRNTFRleHRB
+cmVhRWxlbWVudDpXLnFFLEhUTUxUaW1lRWxlbWVudDpXLnFFLEhUTUxUaXRsZUVsZW1lbnQ6Vy5xRSxI
+VE1MVHJhY2tFbGVtZW50OlcucUUsSFRNTFVMaXN0RWxlbWVudDpXLnFFLEhUTUxVbmtub3duRWxlbWVu
+dDpXLnFFLEhUTUxWaWRlb0VsZW1lbnQ6Vy5xRSxIVE1MRGlyZWN0b3J5RWxlbWVudDpXLnFFLEhUTUxG
+b250RWxlbWVudDpXLnFFLEhUTUxGcmFtZUVsZW1lbnQ6Vy5xRSxIVE1MRnJhbWVTZXRFbGVtZW50Olcu
+cUUsSFRNTE1hcnF1ZWVFbGVtZW50OlcucUUsSFRNTEVsZW1lbnQ6Vy5xRSxIVE1MQW5jaG9yRWxlbWVu
+dDpXLkdoLEhUTUxBcmVhRWxlbWVudDpXLmZZLEhUTUxCYXNlRWxlbWVudDpXLm5CLEJsb2I6Vy5BeixI
+VE1MQm9keUVsZW1lbnQ6Vy5RUCxDREFUQVNlY3Rpb246Vy5ueCxDaGFyYWN0ZXJEYXRhOlcubngsQ29t
+bWVudDpXLm54LFByb2Nlc3NpbmdJbnN0cnVjdGlvbjpXLm54LFRleHQ6Vy5ueCxDU1NTdHlsZURlY2xh
+cmF0aW9uOlcub0osTVNTdHlsZUNTU1Byb3BlcnRpZXM6Vy5vSixDU1MyUHJvcGVydGllczpXLm9KLFhN
+TERvY3VtZW50OlcuUUYsRG9jdW1lbnQ6Vy5RRixET01FeGNlcHRpb246Vy5OaCxET01JbXBsZW1lbnRh
+dGlvbjpXLmFlLERPTVJlY3RSZWFkT25seTpXLklCLERPTVRva2VuTGlzdDpXLm43LEVsZW1lbnQ6Vy5j
+dixBYm9ydFBheW1lbnRFdmVudDpXLmVhLEFuaW1hdGlvbkV2ZW50OlcuZWEsQW5pbWF0aW9uUGxheWJh
+Y2tFdmVudDpXLmVhLEFwcGxpY2F0aW9uQ2FjaGVFcnJvckV2ZW50OlcuZWEsQmFja2dyb3VuZEZldGNo
+Q2xpY2tFdmVudDpXLmVhLEJhY2tncm91bmRGZXRjaEV2ZW50OlcuZWEsQmFja2dyb3VuZEZldGNoRmFp
+bEV2ZW50OlcuZWEsQmFja2dyb3VuZEZldGNoZWRFdmVudDpXLmVhLEJlZm9yZUluc3RhbGxQcm9tcHRF
+dmVudDpXLmVhLEJlZm9yZVVubG9hZEV2ZW50OlcuZWEsQmxvYkV2ZW50OlcuZWEsQ2FuTWFrZVBheW1l
+bnRFdmVudDpXLmVhLENsaXBib2FyZEV2ZW50OlcuZWEsQ2xvc2VFdmVudDpXLmVhLEN1c3RvbUV2ZW50
+OlcuZWEsRGV2aWNlTW90aW9uRXZlbnQ6Vy5lYSxEZXZpY2VPcmllbnRhdGlvbkV2ZW50OlcuZWEsRXJy
+b3JFdmVudDpXLmVhLEV4dGVuZGFibGVFdmVudDpXLmVhLEV4dGVuZGFibGVNZXNzYWdlRXZlbnQ6Vy5l
+YSxGZXRjaEV2ZW50OlcuZWEsRm9udEZhY2VTZXRMb2FkRXZlbnQ6Vy5lYSxGb3JlaWduRmV0Y2hFdmVu
+dDpXLmVhLEdhbWVwYWRFdmVudDpXLmVhLEhhc2hDaGFuZ2VFdmVudDpXLmVhLEluc3RhbGxFdmVudDpX
+LmVhLE1lZGlhRW5jcnlwdGVkRXZlbnQ6Vy5lYSxNZWRpYUtleU1lc3NhZ2VFdmVudDpXLmVhLE1lZGlh
+UXVlcnlMaXN0RXZlbnQ6Vy5lYSxNZWRpYVN0cmVhbUV2ZW50OlcuZWEsTWVkaWFTdHJlYW1UcmFja0V2
+ZW50OlcuZWEsTWVzc2FnZUV2ZW50OlcuZWEsTUlESUNvbm5lY3Rpb25FdmVudDpXLmVhLE1JRElNZXNz
+YWdlRXZlbnQ6Vy5lYSxNdXRhdGlvbkV2ZW50OlcuZWEsTm90aWZpY2F0aW9uRXZlbnQ6Vy5lYSxQYWdl
+VHJhbnNpdGlvbkV2ZW50OlcuZWEsUGF5bWVudFJlcXVlc3RFdmVudDpXLmVhLFBheW1lbnRSZXF1ZXN0
+VXBkYXRlRXZlbnQ6Vy5lYSxQb3BTdGF0ZUV2ZW50OlcuZWEsUHJlc2VudGF0aW9uQ29ubmVjdGlvbkF2
+YWlsYWJsZUV2ZW50OlcuZWEsUHJlc2VudGF0aW9uQ29ubmVjdGlvbkNsb3NlRXZlbnQ6Vy5lYSxQcm9t
+aXNlUmVqZWN0aW9uRXZlbnQ6Vy5lYSxQdXNoRXZlbnQ6Vy5lYSxSVENEYXRhQ2hhbm5lbEV2ZW50Olcu
+ZWEsUlRDRFRNRlRvbmVDaGFuZ2VFdmVudDpXLmVhLFJUQ1BlZXJDb25uZWN0aW9uSWNlRXZlbnQ6Vy5l
+YSxSVENUcmFja0V2ZW50OlcuZWEsU2VjdXJpdHlQb2xpY3lWaW9sYXRpb25FdmVudDpXLmVhLFNlbnNv
+ckVycm9yRXZlbnQ6Vy5lYSxTcGVlY2hSZWNvZ25pdGlvbkVycm9yOlcuZWEsU3BlZWNoUmVjb2duaXRp
+b25FdmVudDpXLmVhLFNwZWVjaFN5bnRoZXNpc0V2ZW50OlcuZWEsU3RvcmFnZUV2ZW50OlcuZWEsU3lu
+Y0V2ZW50OlcuZWEsVHJhY2tFdmVudDpXLmVhLFRyYW5zaXRpb25FdmVudDpXLmVhLFdlYktpdFRyYW5z
+aXRpb25FdmVudDpXLmVhLFZSRGV2aWNlRXZlbnQ6Vy5lYSxWUkRpc3BsYXlFdmVudDpXLmVhLFZSU2Vz
+c2lvbkV2ZW50OlcuZWEsTW9qb0ludGVyZmFjZVJlcXVlc3RFdmVudDpXLmVhLFVTQkNvbm5lY3Rpb25F
+dmVudDpXLmVhLElEQlZlcnNpb25DaGFuZ2VFdmVudDpXLmVhLEF1ZGlvUHJvY2Vzc2luZ0V2ZW50Olcu
+ZWEsT2ZmbGluZUF1ZGlvQ29tcGxldGlvbkV2ZW50OlcuZWEsV2ViR0xDb250ZXh0RXZlbnQ6Vy5lYSxF
+dmVudDpXLmVhLElucHV0RXZlbnQ6Vy5lYSxTdWJtaXRFdmVudDpXLmVhLEV2ZW50VGFyZ2V0OlcuRDAs
+RmlsZTpXLmhILEhUTUxGb3JtRWxlbWVudDpXLmg0LEhpc3Rvcnk6Vy5icixIVE1MRG9jdW1lbnQ6Vy5W
+YixYTUxIdHRwUmVxdWVzdDpXLmZKLFhNTEh0dHBSZXF1ZXN0RXZlbnRUYXJnZXQ6Vy53YSxJbWFnZURh
+dGE6Vy5TZyxMb2NhdGlvbjpXLnc3LE1vdXNlRXZlbnQ6Vy5BaixEcmFnRXZlbnQ6Vy5BaixQb2ludGVy
+RXZlbnQ6Vy5BaixXaGVlbEV2ZW50OlcuQWosRG9jdW1lbnRGcmFnbWVudDpXLnVILFNoYWRvd1Jvb3Q6
+Vy51SCxEb2N1bWVudFR5cGU6Vy51SCxOb2RlOlcudUgsTm9kZUxpc3Q6Vy5CSCxSYWRpb05vZGVMaXN0
+OlcuQkgsSFRNTFBhcmFncmFwaEVsZW1lbnQ6Vy5TTixQcm9ncmVzc0V2ZW50OlcuZXcsUmVzb3VyY2VQ
+cm9ncmVzc0V2ZW50OlcuZXcsSFRNTFNlbGVjdEVsZW1lbnQ6Vy5scCxIVE1MVGFibGVFbGVtZW50Olcu
+VGIsSFRNTFRhYmxlUm93RWxlbWVudDpXLkl2LEhUTUxUYWJsZVNlY3Rpb25FbGVtZW50OlcuV1AsSFRN
+TFRlbXBsYXRlRWxlbWVudDpXLnlZLENvbXBvc2l0aW9uRXZlbnQ6Vy53NixGb2N1c0V2ZW50OlcudzYs
+S2V5Ym9hcmRFdmVudDpXLnc2LFRleHRFdmVudDpXLnc2LFRvdWNoRXZlbnQ6Vy53NixVSUV2ZW50Olcu
+dzYsV2luZG93OlcuSzUsRE9NV2luZG93OlcuSzUsRGVkaWNhdGVkV29ya2VyR2xvYmFsU2NvcGU6Vy5D
+bSxTZXJ2aWNlV29ya2VyR2xvYmFsU2NvcGU6Vy5DbSxTaGFyZWRXb3JrZXJHbG9iYWxTY29wZTpXLkNt
+LFdvcmtlckdsb2JhbFNjb3BlOlcuQ20sQXR0cjpXLkNRLENsaWVudFJlY3Q6Vy53NCxET01SZWN0Olcu
+dzQsTmFtZWROb2RlTWFwOlcucmgsTW96TmFtZWRBdHRyTWFwOlcucmgsSURCS2V5UmFuZ2U6UC5oRixT
+VkdTY3JpcHRFbGVtZW50OlAubmQsU1ZHQUVsZW1lbnQ6UC5oaSxTVkdBbmltYXRlRWxlbWVudDpQLmhp
+LFNWR0FuaW1hdGVNb3Rpb25FbGVtZW50OlAuaGksU1ZHQW5pbWF0ZVRyYW5zZm9ybUVsZW1lbnQ6UC5o
+aSxTVkdBbmltYXRpb25FbGVtZW50OlAuaGksU1ZHQ2lyY2xlRWxlbWVudDpQLmhpLFNWR0NsaXBQYXRo
+RWxlbWVudDpQLmhpLFNWR0RlZnNFbGVtZW50OlAuaGksU1ZHRGVzY0VsZW1lbnQ6UC5oaSxTVkdEaXNj
+YXJkRWxlbWVudDpQLmhpLFNWR0VsbGlwc2VFbGVtZW50OlAuaGksU1ZHRkVCbGVuZEVsZW1lbnQ6UC5o
+aSxTVkdGRUNvbG9yTWF0cml4RWxlbWVudDpQLmhpLFNWR0ZFQ29tcG9uZW50VHJhbnNmZXJFbGVtZW50
+OlAuaGksU1ZHRkVDb21wb3NpdGVFbGVtZW50OlAuaGksU1ZHRkVDb252b2x2ZU1hdHJpeEVsZW1lbnQ6
+UC5oaSxTVkdGRURpZmZ1c2VMaWdodGluZ0VsZW1lbnQ6UC5oaSxTVkdGRURpc3BsYWNlbWVudE1hcEVs
+ZW1lbnQ6UC5oaSxTVkdGRURpc3RhbnRMaWdodEVsZW1lbnQ6UC5oaSxTVkdGRUZsb29kRWxlbWVudDpQ
+LmhpLFNWR0ZFRnVuY0FFbGVtZW50OlAuaGksU1ZHRkVGdW5jQkVsZW1lbnQ6UC5oaSxTVkdGRUZ1bmNH
+RWxlbWVudDpQLmhpLFNWR0ZFRnVuY1JFbGVtZW50OlAuaGksU1ZHRkVHYXVzc2lhbkJsdXJFbGVtZW50
+OlAuaGksU1ZHRkVJbWFnZUVsZW1lbnQ6UC5oaSxTVkdGRU1lcmdlRWxlbWVudDpQLmhpLFNWR0ZFTWVy
+Z2VOb2RlRWxlbWVudDpQLmhpLFNWR0ZFTW9ycGhvbG9neUVsZW1lbnQ6UC5oaSxTVkdGRU9mZnNldEVs
+ZW1lbnQ6UC5oaSxTVkdGRVBvaW50TGlnaHRFbGVtZW50OlAuaGksU1ZHRkVTcGVjdWxhckxpZ2h0aW5n
+RWxlbWVudDpQLmhpLFNWR0ZFU3BvdExpZ2h0RWxlbWVudDpQLmhpLFNWR0ZFVGlsZUVsZW1lbnQ6UC5o
+aSxTVkdGRVR1cmJ1bGVuY2VFbGVtZW50OlAuaGksU1ZHRmlsdGVyRWxlbWVudDpQLmhpLFNWR0ZvcmVp
+Z25PYmplY3RFbGVtZW50OlAuaGksU1ZHR0VsZW1lbnQ6UC5oaSxTVkdHZW9tZXRyeUVsZW1lbnQ6UC5o
+aSxTVkdHcmFwaGljc0VsZW1lbnQ6UC5oaSxTVkdJbWFnZUVsZW1lbnQ6UC5oaSxTVkdMaW5lRWxlbWVu
+dDpQLmhpLFNWR0xpbmVhckdyYWRpZW50RWxlbWVudDpQLmhpLFNWR01hcmtlckVsZW1lbnQ6UC5oaSxT
+VkdNYXNrRWxlbWVudDpQLmhpLFNWR01ldGFkYXRhRWxlbWVudDpQLmhpLFNWR1BhdGhFbGVtZW50OlAu
+aGksU1ZHUGF0dGVybkVsZW1lbnQ6UC5oaSxTVkdQb2x5Z29uRWxlbWVudDpQLmhpLFNWR1BvbHlsaW5l
+RWxlbWVudDpQLmhpLFNWR1JhZGlhbEdyYWRpZW50RWxlbWVudDpQLmhpLFNWR1JlY3RFbGVtZW50OlAu
+aGksU1ZHU2V0RWxlbWVudDpQLmhpLFNWR1N0b3BFbGVtZW50OlAuaGksU1ZHU3R5bGVFbGVtZW50OlAu
+aGksU1ZHU1ZHRWxlbWVudDpQLmhpLFNWR1N3aXRjaEVsZW1lbnQ6UC5oaSxTVkdTeW1ib2xFbGVtZW50
+OlAuaGksU1ZHVFNwYW5FbGVtZW50OlAuaGksU1ZHVGV4dENvbnRlbnRFbGVtZW50OlAuaGksU1ZHVGV4
+dEVsZW1lbnQ6UC5oaSxTVkdUZXh0UGF0aEVsZW1lbnQ6UC5oaSxTVkdUZXh0UG9zaXRpb25pbmdFbGVt
+ZW50OlAuaGksU1ZHVGl0bGVFbGVtZW50OlAuaGksU1ZHVXNlRWxlbWVudDpQLmhpLFNWR1ZpZXdFbGVt
+ZW50OlAuaGksU1ZHR3JhZGllbnRFbGVtZW50OlAuaGksU1ZHQ29tcG9uZW50VHJhbnNmZXJGdW5jdGlv
+bkVsZW1lbnQ6UC5oaSxTVkdGRURyb3BTaGFkb3dFbGVtZW50OlAuaGksU1ZHTVBhdGhFbGVtZW50OlAu
+aGksU1ZHRWxlbWVudDpQLmhpfSkKaHVua0hlbHBlcnMuc2V0T3JVcGRhdGVMZWFmVGFncyh7RE9NRXJy
+b3I6dHJ1ZSxNZWRpYUVycm9yOnRydWUsTmF2aWdhdG9yOnRydWUsTmF2aWdhdG9yQ29uY3VycmVudEhh
+cmR3YXJlOnRydWUsTmF2aWdhdG9yVXNlck1lZGlhRXJyb3I6dHJ1ZSxPdmVyY29uc3RyYWluZWRFcnJv
+cjp0cnVlLFBvc2l0aW9uRXJyb3I6dHJ1ZSxSYW5nZTp0cnVlLFNRTEVycm9yOnRydWUsRGF0YVZpZXc6
+dHJ1ZSxBcnJheUJ1ZmZlclZpZXc6ZmFsc2UsRmxvYXQzMkFycmF5OnRydWUsRmxvYXQ2NEFycmF5OnRy
+dWUsSW50MTZBcnJheTp0cnVlLEludDMyQXJyYXk6dHJ1ZSxJbnQ4QXJyYXk6dHJ1ZSxVaW50MTZBcnJh
+eTp0cnVlLFVpbnQzMkFycmF5OnRydWUsVWludDhDbGFtcGVkQXJyYXk6dHJ1ZSxDYW52YXNQaXhlbEFy
+cmF5OnRydWUsVWludDhBcnJheTpmYWxzZSxIVE1MQXVkaW9FbGVtZW50OnRydWUsSFRNTEJSRWxlbWVu
+dDp0cnVlLEhUTUxCdXR0b25FbGVtZW50OnRydWUsSFRNTENhbnZhc0VsZW1lbnQ6dHJ1ZSxIVE1MQ29u
+dGVudEVsZW1lbnQ6dHJ1ZSxIVE1MRExpc3RFbGVtZW50OnRydWUsSFRNTERhdGFFbGVtZW50OnRydWUs
+SFRNTERhdGFMaXN0RWxlbWVudDp0cnVlLEhUTUxEZXRhaWxzRWxlbWVudDp0cnVlLEhUTUxEaWFsb2dF
+bGVtZW50OnRydWUsSFRNTERpdkVsZW1lbnQ6dHJ1ZSxIVE1MRW1iZWRFbGVtZW50OnRydWUsSFRNTEZp
+ZWxkU2V0RWxlbWVudDp0cnVlLEhUTUxIUkVsZW1lbnQ6dHJ1ZSxIVE1MSGVhZEVsZW1lbnQ6dHJ1ZSxI
+VE1MSGVhZGluZ0VsZW1lbnQ6dHJ1ZSxIVE1MSHRtbEVsZW1lbnQ6dHJ1ZSxIVE1MSUZyYW1lRWxlbWVu
+dDp0cnVlLEhUTUxJbWFnZUVsZW1lbnQ6dHJ1ZSxIVE1MSW5wdXRFbGVtZW50OnRydWUsSFRNTExJRWxl
+bWVudDp0cnVlLEhUTUxMYWJlbEVsZW1lbnQ6dHJ1ZSxIVE1MTGVnZW5kRWxlbWVudDp0cnVlLEhUTUxM
+aW5rRWxlbWVudDp0cnVlLEhUTUxNYXBFbGVtZW50OnRydWUsSFRNTE1lZGlhRWxlbWVudDp0cnVlLEhU
+TUxNZW51RWxlbWVudDp0cnVlLEhUTUxNZXRhRWxlbWVudDp0cnVlLEhUTUxNZXRlckVsZW1lbnQ6dHJ1
+ZSxIVE1MTW9kRWxlbWVudDp0cnVlLEhUTUxPTGlzdEVsZW1lbnQ6dHJ1ZSxIVE1MT2JqZWN0RWxlbWVu
+dDp0cnVlLEhUTUxPcHRHcm91cEVsZW1lbnQ6dHJ1ZSxIVE1MT3B0aW9uRWxlbWVudDp0cnVlLEhUTUxP
+dXRwdXRFbGVtZW50OnRydWUsSFRNTFBhcmFtRWxlbWVudDp0cnVlLEhUTUxQaWN0dXJlRWxlbWVudDp0
+cnVlLEhUTUxQcmVFbGVtZW50OnRydWUsSFRNTFByb2dyZXNzRWxlbWVudDp0cnVlLEhUTUxRdW90ZUVs
+ZW1lbnQ6dHJ1ZSxIVE1MU2NyaXB0RWxlbWVudDp0cnVlLEhUTUxTaGFkb3dFbGVtZW50OnRydWUsSFRN
+TFNsb3RFbGVtZW50OnRydWUsSFRNTFNvdXJjZUVsZW1lbnQ6dHJ1ZSxIVE1MU3BhbkVsZW1lbnQ6dHJ1
+ZSxIVE1MU3R5bGVFbGVtZW50OnRydWUsSFRNTFRhYmxlQ2FwdGlvbkVsZW1lbnQ6dHJ1ZSxIVE1MVGFi
+bGVDZWxsRWxlbWVudDp0cnVlLEhUTUxUYWJsZURhdGFDZWxsRWxlbWVudDp0cnVlLEhUTUxUYWJsZUhl
+YWRlckNlbGxFbGVtZW50OnRydWUsSFRNTFRhYmxlQ29sRWxlbWVudDp0cnVlLEhUTUxUZXh0QXJlYUVs
+ZW1lbnQ6dHJ1ZSxIVE1MVGltZUVsZW1lbnQ6dHJ1ZSxIVE1MVGl0bGVFbGVtZW50OnRydWUsSFRNTFRy
+YWNrRWxlbWVudDp0cnVlLEhUTUxVTGlzdEVsZW1lbnQ6dHJ1ZSxIVE1MVW5rbm93bkVsZW1lbnQ6dHJ1
+ZSxIVE1MVmlkZW9FbGVtZW50OnRydWUsSFRNTERpcmVjdG9yeUVsZW1lbnQ6dHJ1ZSxIVE1MRm9udEVs
+ZW1lbnQ6dHJ1ZSxIVE1MRnJhbWVFbGVtZW50OnRydWUsSFRNTEZyYW1lU2V0RWxlbWVudDp0cnVlLEhU
+TUxNYXJxdWVlRWxlbWVudDp0cnVlLEhUTUxFbGVtZW50OmZhbHNlLEhUTUxBbmNob3JFbGVtZW50OnRy
+dWUsSFRNTEFyZWFFbGVtZW50OnRydWUsSFRNTEJhc2VFbGVtZW50OnRydWUsQmxvYjpmYWxzZSxIVE1M
+Qm9keUVsZW1lbnQ6dHJ1ZSxDREFUQVNlY3Rpb246dHJ1ZSxDaGFyYWN0ZXJEYXRhOnRydWUsQ29tbWVu
+dDp0cnVlLFByb2Nlc3NpbmdJbnN0cnVjdGlvbjp0cnVlLFRleHQ6dHJ1ZSxDU1NTdHlsZURlY2xhcmF0
+aW9uOnRydWUsTVNTdHlsZUNTU1Byb3BlcnRpZXM6dHJ1ZSxDU1MyUHJvcGVydGllczp0cnVlLFhNTERv
+Y3VtZW50OnRydWUsRG9jdW1lbnQ6ZmFsc2UsRE9NRXhjZXB0aW9uOnRydWUsRE9NSW1wbGVtZW50YXRp
+b246dHJ1ZSxET01SZWN0UmVhZE9ubHk6ZmFsc2UsRE9NVG9rZW5MaXN0OnRydWUsRWxlbWVudDpmYWxz
+ZSxBYm9ydFBheW1lbnRFdmVudDp0cnVlLEFuaW1hdGlvbkV2ZW50OnRydWUsQW5pbWF0aW9uUGxheWJh
+Y2tFdmVudDp0cnVlLEFwcGxpY2F0aW9uQ2FjaGVFcnJvckV2ZW50OnRydWUsQmFja2dyb3VuZEZldGNo
+Q2xpY2tFdmVudDp0cnVlLEJhY2tncm91bmRGZXRjaEV2ZW50OnRydWUsQmFja2dyb3VuZEZldGNoRmFp
+bEV2ZW50OnRydWUsQmFja2dyb3VuZEZldGNoZWRFdmVudDp0cnVlLEJlZm9yZUluc3RhbGxQcm9tcHRF
+dmVudDp0cnVlLEJlZm9yZVVubG9hZEV2ZW50OnRydWUsQmxvYkV2ZW50OnRydWUsQ2FuTWFrZVBheW1l
+bnRFdmVudDp0cnVlLENsaXBib2FyZEV2ZW50OnRydWUsQ2xvc2VFdmVudDp0cnVlLEN1c3RvbUV2ZW50
+OnRydWUsRGV2aWNlTW90aW9uRXZlbnQ6dHJ1ZSxEZXZpY2VPcmllbnRhdGlvbkV2ZW50OnRydWUsRXJy
+b3JFdmVudDp0cnVlLEV4dGVuZGFibGVFdmVudDp0cnVlLEV4dGVuZGFibGVNZXNzYWdlRXZlbnQ6dHJ1
+ZSxGZXRjaEV2ZW50OnRydWUsRm9udEZhY2VTZXRMb2FkRXZlbnQ6dHJ1ZSxGb3JlaWduRmV0Y2hFdmVu
+dDp0cnVlLEdhbWVwYWRFdmVudDp0cnVlLEhhc2hDaGFuZ2VFdmVudDp0cnVlLEluc3RhbGxFdmVudDp0
+cnVlLE1lZGlhRW5jcnlwdGVkRXZlbnQ6dHJ1ZSxNZWRpYUtleU1lc3NhZ2VFdmVudDp0cnVlLE1lZGlh
+UXVlcnlMaXN0RXZlbnQ6dHJ1ZSxNZWRpYVN0cmVhbUV2ZW50OnRydWUsTWVkaWFTdHJlYW1UcmFja0V2
+ZW50OnRydWUsTWVzc2FnZUV2ZW50OnRydWUsTUlESUNvbm5lY3Rpb25FdmVudDp0cnVlLE1JRElNZXNz
+YWdlRXZlbnQ6dHJ1ZSxNdXRhdGlvbkV2ZW50OnRydWUsTm90aWZpY2F0aW9uRXZlbnQ6dHJ1ZSxQYWdl
+VHJhbnNpdGlvbkV2ZW50OnRydWUsUGF5bWVudFJlcXVlc3RFdmVudDp0cnVlLFBheW1lbnRSZXF1ZXN0
+VXBkYXRlRXZlbnQ6dHJ1ZSxQb3BTdGF0ZUV2ZW50OnRydWUsUHJlc2VudGF0aW9uQ29ubmVjdGlvbkF2
+YWlsYWJsZUV2ZW50OnRydWUsUHJlc2VudGF0aW9uQ29ubmVjdGlvbkNsb3NlRXZlbnQ6dHJ1ZSxQcm9t
+aXNlUmVqZWN0aW9uRXZlbnQ6dHJ1ZSxQdXNoRXZlbnQ6dHJ1ZSxSVENEYXRhQ2hhbm5lbEV2ZW50OnRy
+dWUsUlRDRFRNRlRvbmVDaGFuZ2VFdmVudDp0cnVlLFJUQ1BlZXJDb25uZWN0aW9uSWNlRXZlbnQ6dHJ1
+ZSxSVENUcmFja0V2ZW50OnRydWUsU2VjdXJpdHlQb2xpY3lWaW9sYXRpb25FdmVudDp0cnVlLFNlbnNv
+ckVycm9yRXZlbnQ6dHJ1ZSxTcGVlY2hSZWNvZ25pdGlvbkVycm9yOnRydWUsU3BlZWNoUmVjb2duaXRp
+b25FdmVudDp0cnVlLFNwZWVjaFN5bnRoZXNpc0V2ZW50OnRydWUsU3RvcmFnZUV2ZW50OnRydWUsU3lu
+Y0V2ZW50OnRydWUsVHJhY2tFdmVudDp0cnVlLFRyYW5zaXRpb25FdmVudDp0cnVlLFdlYktpdFRyYW5z
+aXRpb25FdmVudDp0cnVlLFZSRGV2aWNlRXZlbnQ6dHJ1ZSxWUkRpc3BsYXlFdmVudDp0cnVlLFZSU2Vz
+c2lvbkV2ZW50OnRydWUsTW9qb0ludGVyZmFjZVJlcXVlc3RFdmVudDp0cnVlLFVTQkNvbm5lY3Rpb25F
+dmVudDp0cnVlLElEQlZlcnNpb25DaGFuZ2VFdmVudDp0cnVlLEF1ZGlvUHJvY2Vzc2luZ0V2ZW50OnRy
+dWUsT2ZmbGluZUF1ZGlvQ29tcGxldGlvbkV2ZW50OnRydWUsV2ViR0xDb250ZXh0RXZlbnQ6dHJ1ZSxF
+dmVudDpmYWxzZSxJbnB1dEV2ZW50OmZhbHNlLFN1Ym1pdEV2ZW50OmZhbHNlLEV2ZW50VGFyZ2V0OmZh
+bHNlLEZpbGU6dHJ1ZSxIVE1MRm9ybUVsZW1lbnQ6dHJ1ZSxIaXN0b3J5OnRydWUsSFRNTERvY3VtZW50
+OnRydWUsWE1MSHR0cFJlcXVlc3Q6dHJ1ZSxYTUxIdHRwUmVxdWVzdEV2ZW50VGFyZ2V0OmZhbHNlLElt
+YWdlRGF0YTp0cnVlLExvY2F0aW9uOnRydWUsTW91c2VFdmVudDp0cnVlLERyYWdFdmVudDp0cnVlLFBv
+aW50ZXJFdmVudDp0cnVlLFdoZWVsRXZlbnQ6dHJ1ZSxEb2N1bWVudEZyYWdtZW50OnRydWUsU2hhZG93
+Um9vdDp0cnVlLERvY3VtZW50VHlwZTp0cnVlLE5vZGU6ZmFsc2UsTm9kZUxpc3Q6dHJ1ZSxSYWRpb05v
+ZGVMaXN0OnRydWUsSFRNTFBhcmFncmFwaEVsZW1lbnQ6dHJ1ZSxQcm9ncmVzc0V2ZW50OnRydWUsUmVz
+b3VyY2VQcm9ncmVzc0V2ZW50OnRydWUsSFRNTFNlbGVjdEVsZW1lbnQ6dHJ1ZSxIVE1MVGFibGVFbGVt
+ZW50OnRydWUsSFRNTFRhYmxlUm93RWxlbWVudDp0cnVlLEhUTUxUYWJsZVNlY3Rpb25FbGVtZW50OnRy
+dWUsSFRNTFRlbXBsYXRlRWxlbWVudDp0cnVlLENvbXBvc2l0aW9uRXZlbnQ6dHJ1ZSxGb2N1c0V2ZW50
+OnRydWUsS2V5Ym9hcmRFdmVudDp0cnVlLFRleHRFdmVudDp0cnVlLFRvdWNoRXZlbnQ6dHJ1ZSxVSUV2
+ZW50OmZhbHNlLFdpbmRvdzp0cnVlLERPTVdpbmRvdzp0cnVlLERlZGljYXRlZFdvcmtlckdsb2JhbFNj
+b3BlOnRydWUsU2VydmljZVdvcmtlckdsb2JhbFNjb3BlOnRydWUsU2hhcmVkV29ya2VyR2xvYmFsU2Nv
+cGU6dHJ1ZSxXb3JrZXJHbG9iYWxTY29wZTp0cnVlLEF0dHI6dHJ1ZSxDbGllbnRSZWN0OnRydWUsRE9N
+UmVjdDp0cnVlLE5hbWVkTm9kZU1hcDp0cnVlLE1vek5hbWVkQXR0ck1hcDp0cnVlLElEQktleVJhbmdl
+OnRydWUsU1ZHU2NyaXB0RWxlbWVudDp0cnVlLFNWR0FFbGVtZW50OnRydWUsU1ZHQW5pbWF0ZUVsZW1l
+bnQ6dHJ1ZSxTVkdBbmltYXRlTW90aW9uRWxlbWVudDp0cnVlLFNWR0FuaW1hdGVUcmFuc2Zvcm1FbGVt
+ZW50OnRydWUsU1ZHQW5pbWF0aW9uRWxlbWVudDp0cnVlLFNWR0NpcmNsZUVsZW1lbnQ6dHJ1ZSxTVkdD
+bGlwUGF0aEVsZW1lbnQ6dHJ1ZSxTVkdEZWZzRWxlbWVudDp0cnVlLFNWR0Rlc2NFbGVtZW50OnRydWUs
+U1ZHRGlzY2FyZEVsZW1lbnQ6dHJ1ZSxTVkdFbGxpcHNlRWxlbWVudDp0cnVlLFNWR0ZFQmxlbmRFbGVt
+ZW50OnRydWUsU1ZHRkVDb2xvck1hdHJpeEVsZW1lbnQ6dHJ1ZSxTVkdGRUNvbXBvbmVudFRyYW5zZmVy
+RWxlbWVudDp0cnVlLFNWR0ZFQ29tcG9zaXRlRWxlbWVudDp0cnVlLFNWR0ZFQ29udm9sdmVNYXRyaXhF
+bGVtZW50OnRydWUsU1ZHRkVEaWZmdXNlTGlnaHRpbmdFbGVtZW50OnRydWUsU1ZHRkVEaXNwbGFjZW1l
+bnRNYXBFbGVtZW50OnRydWUsU1ZHRkVEaXN0YW50TGlnaHRFbGVtZW50OnRydWUsU1ZHRkVGbG9vZEVs
+ZW1lbnQ6dHJ1ZSxTVkdGRUZ1bmNBRWxlbWVudDp0cnVlLFNWR0ZFRnVuY0JFbGVtZW50OnRydWUsU1ZH
+RkVGdW5jR0VsZW1lbnQ6dHJ1ZSxTVkdGRUZ1bmNSRWxlbWVudDp0cnVlLFNWR0ZFR2F1c3NpYW5CbHVy
+RWxlbWVudDp0cnVlLFNWR0ZFSW1hZ2VFbGVtZW50OnRydWUsU1ZHRkVNZXJnZUVsZW1lbnQ6dHJ1ZSxT
+VkdGRU1lcmdlTm9kZUVsZW1lbnQ6dHJ1ZSxTVkdGRU1vcnBob2xvZ3lFbGVtZW50OnRydWUsU1ZHRkVP
+ZmZzZXRFbGVtZW50OnRydWUsU1ZHRkVQb2ludExpZ2h0RWxlbWVudDp0cnVlLFNWR0ZFU3BlY3VsYXJM
+aWdodGluZ0VsZW1lbnQ6dHJ1ZSxTVkdGRVNwb3RMaWdodEVsZW1lbnQ6dHJ1ZSxTVkdGRVRpbGVFbGVt
+ZW50OnRydWUsU1ZHRkVUdXJidWxlbmNlRWxlbWVudDp0cnVlLFNWR0ZpbHRlckVsZW1lbnQ6dHJ1ZSxT
+VkdGb3JlaWduT2JqZWN0RWxlbWVudDp0cnVlLFNWR0dFbGVtZW50OnRydWUsU1ZHR2VvbWV0cnlFbGVt
+ZW50OnRydWUsU1ZHR3JhcGhpY3NFbGVtZW50OnRydWUsU1ZHSW1hZ2VFbGVtZW50OnRydWUsU1ZHTGlu
+ZUVsZW1lbnQ6dHJ1ZSxTVkdMaW5lYXJHcmFkaWVudEVsZW1lbnQ6dHJ1ZSxTVkdNYXJrZXJFbGVtZW50
+OnRydWUsU1ZHTWFza0VsZW1lbnQ6dHJ1ZSxTVkdNZXRhZGF0YUVsZW1lbnQ6dHJ1ZSxTVkdQYXRoRWxl
+bWVudDp0cnVlLFNWR1BhdHRlcm5FbGVtZW50OnRydWUsU1ZHUG9seWdvbkVsZW1lbnQ6dHJ1ZSxTVkdQ
+b2x5bGluZUVsZW1lbnQ6dHJ1ZSxTVkdSYWRpYWxHcmFkaWVudEVsZW1lbnQ6dHJ1ZSxTVkdSZWN0RWxl
+bWVudDp0cnVlLFNWR1NldEVsZW1lbnQ6dHJ1ZSxTVkdTdG9wRWxlbWVudDp0cnVlLFNWR1N0eWxlRWxl
+bWVudDp0cnVlLFNWR1NWR0VsZW1lbnQ6dHJ1ZSxTVkdTd2l0Y2hFbGVtZW50OnRydWUsU1ZHU3ltYm9s
+RWxlbWVudDp0cnVlLFNWR1RTcGFuRWxlbWVudDp0cnVlLFNWR1RleHRDb250ZW50RWxlbWVudDp0cnVl
+LFNWR1RleHRFbGVtZW50OnRydWUsU1ZHVGV4dFBhdGhFbGVtZW50OnRydWUsU1ZHVGV4dFBvc2l0aW9u
+aW5nRWxlbWVudDp0cnVlLFNWR1RpdGxlRWxlbWVudDp0cnVlLFNWR1VzZUVsZW1lbnQ6dHJ1ZSxTVkdW
+aWV3RWxlbWVudDp0cnVlLFNWR0dyYWRpZW50RWxlbWVudDp0cnVlLFNWR0NvbXBvbmVudFRyYW5zZmVy
+RnVuY3Rpb25FbGVtZW50OnRydWUsU1ZHRkVEcm9wU2hhZG93RWxlbWVudDp0cnVlLFNWR01QYXRoRWxl
+bWVudDp0cnVlLFNWR0VsZW1lbnQ6ZmFsc2V9KQpILkxaLiRuYXRpdmVTdXBlcmNsYXNzVGFnPSJBcnJh
+eUJ1ZmZlclZpZXciCkguUkcuJG5hdGl2ZVN1cGVyY2xhc3NUYWc9IkFycmF5QnVmZmVyVmlldyIKSC5W
+UC4kbmF0aXZlU3VwZXJjbGFzc1RhZz0iQXJyYXlCdWZmZXJWaWV3IgpILkRnLiRuYXRpdmVTdXBlcmNs
+YXNzVGFnPSJBcnJheUJ1ZmZlclZpZXciCkguV0IuJG5hdGl2ZVN1cGVyY2xhc3NUYWc9IkFycmF5QnVm
+ZmVyVmlldyIKSC5aRy4kbmF0aXZlU3VwZXJjbGFzc1RhZz0iQXJyYXlCdWZmZXJWaWV3IgpILlBnLiRu
+YXRpdmVTdXBlcmNsYXNzVGFnPSJBcnJheUJ1ZmZlclZpZXcifSkoKQpjb252ZXJ0QWxsVG9GYXN0T2Jq
+ZWN0KHcpCmNvbnZlcnRUb0Zhc3RPYmplY3QoJCk7KGZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBkb2N1bWVu
+dD09PSJ1bmRlZmluZWQiKXthKG51bGwpCnJldHVybn1pZih0eXBlb2YgZG9jdW1lbnQuY3VycmVudFNj
+cmlwdCE9InVuZGVmaW5lZCIpe2EoZG9jdW1lbnQuY3VycmVudFNjcmlwdCkKcmV0dXJufXZhciBzPWRv
+Y3VtZW50LnNjcmlwdHMKZnVuY3Rpb24gb25Mb2FkKGIpe2Zvcih2YXIgcT0wO3E8cy5sZW5ndGg7Kytx
+KXNbcV0ucmVtb3ZlRXZlbnRMaXN0ZW5lcigibG9hZCIsb25Mb2FkLGZhbHNlKQphKGIudGFyZ2V0KX1m
+b3IodmFyIHI9MDtyPHMubGVuZ3RoOysrcilzW3JdLmFkZEV2ZW50TGlzdGVuZXIoImxvYWQiLG9uTG9h
+ZCxmYWxzZSl9KShmdW5jdGlvbihhKXt2LmN1cnJlbnRTY3JpcHQ9YQp2YXIgcz1MLklxCmlmKHR5cGVv
+ZiBkYXJ0TWFpblJ1bm5lcj09PSJmdW5jdGlvbiIpZGFydE1haW5SdW5uZXIocyxbXSkKZWxzZSBzKFtd
+KX0pfSkoKQovLyMgc291cmNlTWFwcGluZ1VSTD1taWdyYXRpb24uanMubWFwCg==
 ''';
diff --git a/pkg/nnbd_migration/lib/src/front_end/unit_renderer.dart b/pkg/nnbd_migration/lib/src/front_end/unit_renderer.dart
index cddd307..0ede8f9 100644
--- a/pkg/nnbd_migration/lib/src/front_end/unit_renderer.dart
+++ b/pkg/nnbd_migration/lib/src/front_end/unit_renderer.dart
@@ -26,6 +26,7 @@
     NullabilityFixKind.noValidMigrationForNull,
     NullabilityFixKind.compoundAssignmentHasBadCombinedType,
     NullabilityFixKind.compoundAssignmentHasNullableSource,
+    NullabilityFixKind.addThen,
     NullabilityFixKind.removeDeadCode,
     NullabilityFixKind.conditionTrueInStrongMode,
     NullabilityFixKind.conditionFalseInStrongMode,
@@ -277,6 +278,8 @@
     var s = count == 1 ? '' : 's';
     var es = count == 1 ? '' : 'es';
     switch (kind) {
+      case NullabilityFixKind.addThen:
+        return '$count invocation$s of `.then` added';
       case NullabilityFixKind.addImport:
         return '$count import$s added';
       case NullabilityFixKind.addLate:
@@ -302,10 +305,10 @@
       case NullabilityFixKind.checkExpressionDueToHint:
         return '$count null check hint$s converted to null check$s';
       case NullabilityFixKind.compoundAssignmentHasBadCombinedType:
-        return '$count compound assignment$s could not be migrated (bad '
+        return "$count compound assignment$s couldn't be migrated (bad "
             'combined type)';
       case NullabilityFixKind.compoundAssignmentHasNullableSource:
-        return '$count compound assignment$s could not be migrated (nullable '
+        return "$count compound assignment$s couldn't be migrated (nullable "
             'source)';
       case NullabilityFixKind.conditionTrueInStrongMode:
         return '$count condition$s will be true in strong checking mode';
@@ -318,7 +321,7 @@
       case NullabilityFixKind.makeTypeNullableDueToHint:
         return '$count nullability hint$s converted to ?$s';
       case NullabilityFixKind.noValidMigrationForNull:
-        return '$count literal `null`$s could not be migrated';
+        return "$count literal `null`$s couldn't be migrated";
       case NullabilityFixKind.nullAwarenessUnnecessaryInStrongMode:
         return '$count null-aware access$es will be unnecessary in strong '
             'checking mode';
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 d62b4e1..2e40c87 100644
--- a/pkg/nnbd_migration/lib/src/front_end/web/migration.dart
+++ b/pkg/nnbd_migration/lib/src/front_end/web/migration.dart
@@ -50,7 +50,7 @@
             ..remove('proposed')
             ..add('applied');
         }).catchError((e, st) {
-          handleError('Could not apply migration', e, st);
+          handleError("Couldn't apply migration", e, st);
         });
       }
     });
@@ -83,7 +83,7 @@
     migrateUnitStatusIcon.onClick.listen((MouseEvent event) {
       var unitPath = unitName.innerText;
       var unitNavItem = document
-          .querySelector('.nav-panel [data-name*="$unitPath"]')
+          .querySelector('.nav-panel [data-name*="${Css.escape(unitPath)}"]')
           .parentNode as Element;
       var statusIcon = unitNavItem.querySelector('.status-icon');
       var entity = navigationTree.find(unitPath);
@@ -129,20 +129,20 @@
 
 final Element headerPanel = document.querySelector('header');
 
-final Element unitName = document.querySelector('#unit-name');
+final Element migrateUnitStatusIcon =
+    document.querySelector('#migrate-unit-status-icon');
 
 final Element migrateUnitStatusIconLabel =
     document.querySelector('#migrate-unit-status-icon-label');
 
-final Element migrateUnitStatusIcon =
-    document.querySelector('#migrate-unit-status-icon');
+List<NavigationTreeNode> /*?*/ navigationTree;
+
+final Element unitName = document.querySelector('#unit-name');
 
 String get rootPath => querySelector('.root').text.trim();
 
 String get sdkVersion => document.getElementById('sdk-version').text;
 
-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
@@ -233,10 +233,45 @@
   try {
     await completer.future;
   } catch (e, st) {
-    // Handle refused connection and make it user-presentable.
-    throw AsyncError('Error reaching migration preview server.', st);
+    if (xhr.readyState == HttpRequest.DONE && xhr.status == 0) {
+      // Request completed with error, and no status information.  Most likely
+      // the server has terminated.
+      throw UserError('Error reaching migration preview server', '''
+This usually happens because the migration preview server has exited.  For
+example it may have been aborted with Ctrl-C, or you may have completed this
+migration, or an exception may have occurred.  Please check the console where
+you invoked `dart migrate` to verify that the preview server is still running.
+''');
+    } else {
+      // The attempt to connect to the server failed in an unexpected way.
+      // Report as many details as possible so that the user's bug report will
+      // be easier to address.
+      var details = [
+        'readyState=${xhr.readyState}',
+        'responseText=${jsonEncode(xhr.responseText)}',
+        'responseType=${jsonEncode(xhr.responseType)}',
+        'responseUrl=${jsonEncode(xhr.responseUrl)}',
+        'status=${xhr.status}',
+        'statusText=${jsonEncode(xhr.statusText)}',
+      ]
+          .map((detail) =>
+              detail.length > 40 ? detail.substring(0, 40) + '...' : detail)
+          .join(', ');
+      throw AsyncError('Error reaching migration preview server: $details', st);
+    }
   }
 
+  if (xhr.status == 401) {
+    // Server returned "unauthorized".  It's not useful to try to decode the
+    // response text (since it's in HTML, not JSON).  Just tell the user what
+    // happened.
+    throw UserError('Unauthorized response from migration preview server', '''
+The migration preview server has detected a mismatch between the authToken in
+your URL and the token that was generated at the time that `dart migrate` was
+run.  Have you restarted the migration server recently?  If so, you'll need to
+check its output for a fresh URL, and use that URL to perform your migration.
+''');
+  }
   final json = jsonDecode(xhr.responseText);
   if (xhr.status == 200) {
     // Request OK.
@@ -321,27 +356,36 @@
     // the response.
     await doPost(path);
     await loadFile(window.location.pathname, null, null, false);
+    document.body.classes.add('needs-rerun');
     _scrollContentTo(previousScrollPosition);
   } catch (e, st) {
-    handleError('Could not add/remove hint', e, st);
+    handleError("couldn't add/remove hint", e, st);
   }
 }
 
 void handleError(String header, Object exception, Object stackTrace) {
   String subheader;
+  Object details;
   if (exception is Map<String, Object> &&
       exception['success'] == false &&
       exception.containsKey('exception') &&
       exception.containsKey('stackTrace')) {
     subheader = exception['exception'] as String;
     stackTrace = exception['stackTrace'];
+  } else if (exception is UserError) {
+    subheader = exception.message;
+    // Don't show the user a stacktrace; show them the detailed error message
+    // text instead.
+    details = exception.details;
   } else {
     subheader = exception.toString();
   }
+  // If there was no detailed error message, use the stacktrace instead.
+  details ??= stackTrace;
   final popupPane = document.querySelector('.popup-pane');
   popupPane.querySelector('h2').innerText = header;
   popupPane.querySelector('p').innerText = subheader;
-  popupPane.querySelector('pre').innerText = stackTrace.toString();
+  popupPane.querySelector('pre').innerText = details.toString();
   var bottom = popupPane.querySelector('a.bottom') as AnchorElement;
   bottom
     ..href = getGitHubErrorUri(header, subheader, stackTrace).toString()
@@ -403,7 +447,7 @@
     pushState(path, offset, line);
     addClickHandlers('.edit-panel .panel-content', false);
   } catch (e, st) {
-    handleError('Could not load edit details', e, st);
+    handleError("couldn't load edit details", e, st);
   }
 }
 
@@ -439,7 +483,7 @@
       callback();
     }
   } catch (e, st) {
-    handleError('Could not load dart file $path', e, st);
+    handleError("couldn't load dart file $path", e, st);
   }
 }
 
@@ -456,7 +500,7 @@
     writeNavigationSubtree(navTree, navigationTree,
         enablePartialMigration: true);
   } catch (e, st) {
-    handleError('Could not load navigation tree', e, st);
+    handleError("couldn't load navigation tree", e, st);
   }
 }
 
@@ -730,25 +774,6 @@
   }
 }
 
-/// Updates the navigation [icon] and current file icon according to the current
-/// migration status of [entity].
-void updateIconsForNode(Element icon, NavigationTreeNode entity) {
-  var status = entity.migrationStatus;
-  updateIconForStatus(icon, status);
-  // Update the status at the top of the file view if [entity] represents the
-  // current file.
-  var unitPath = unitName.innerText;
-  if (entity.path == unitPath) {
-    if (entity is NavigationTreeFileNode &&
-        !entity.migrationStatusCanBeChanged) {
-      icon.classes.add('disabled');
-    } else {
-      icon.classes.remove('disabled');
-    }
-    updateIconForStatus(migrateUnitStatusIcon, status);
-  }
-}
-
 /// Updates [icon] according to [status].
 void updateIconForStatus(Element icon, UnitMigrationStatus status) {
   switch (status) {
@@ -781,6 +806,25 @@
   }
 }
 
+/// Updates the navigation [icon] and current file icon according to the current
+/// migration status of [entity].
+void updateIconsForNode(Element icon, NavigationTreeNode entity) {
+  var status = entity.migrationStatus;
+  updateIconForStatus(icon, status);
+  // Update the status at the top of the file view if [entity] represents the
+  // current file.
+  var unitPath = unitName.innerText;
+  if (entity.path == unitPath) {
+    if (entity is NavigationTreeFileNode &&
+        !entity.migrationStatusCanBeChanged) {
+      icon.classes.add('disabled');
+    } else {
+      icon.classes.remove('disabled');
+    }
+    updateIconForStatus(migrateUnitStatusIcon, status);
+  }
+}
+
 /// Update the heading and navigation links.
 ///
 /// Call this after updating page content on a navigation.
@@ -825,7 +869,8 @@
 /// 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}"]');
+    var childNode =
+        element.querySelector('[data-name*="${Css.escape(child.path)}"]');
     if (child is NavigationTreeDirectoryNode) {
       updateSubtreeIcons(childNode, child);
       var childIcon = childNode.querySelector(':scope > .status-icon');
@@ -939,7 +984,7 @@
         document.body.classes.add('needs-rerun');
         _scrollContentTo(previousScrollPosition);
       } catch (e, st) {
-        handleError('Could not apply hint', e, st);
+        handleError("couldn't apply hint", e, st);
       }
     })
     ..appendText(hintAction.kind.description));
@@ -1021,6 +1066,16 @@
 String _stripQuery(String path) =>
     path.contains('?') ? path.substring(0, path.indexOf('?')) : path;
 
+class UserError extends Error implements Exception {
+  final String message;
+
+  final String details;
+
+  UserError(this.message, this.details);
+
+  String toString() => '$message:\n$details';
+}
+
 class _PermissiveNodeValidator implements NodeValidator {
   static _PermissiveNodeValidator instance = _PermissiveNodeValidator();
 
@@ -1039,20 +1094,6 @@
   }
 }
 
-/// An extension on Element that fits into cascades.
-extension on Element {
-  /// Append [text] to this, inserting a word break before each '.' character.
-  void appendTextWithBreaks(String text) {
-    var textParts = text.split('.');
-    append(Text(textParts.first));
-    for (var substring in textParts.skip(1)) {
-      // Replace the '.' with a zero-width space and a '.'.
-      appendHtml('&#8203;.');
-      append(Text(substring));
-    }
-  }
-}
-
 extension on List<NavigationTreeNode> {
   /// Finds the node with path equal to [path], recursively, or `null`.
   NavigationTreeNode find(String path) {
@@ -1068,3 +1109,17 @@
     return null;
   }
 }
+
+/// An extension on Element that fits into cascades.
+extension on Element {
+  /// Append [text] to this, inserting a word break before each '.' character.
+  void appendTextWithBreaks(String text) {
+    var textParts = text.split('.');
+    append(Text(textParts.first));
+    for (var substring in textParts.skip(1)) {
+      // Replace the '.' with a zero-width space and a '.'.
+      appendHtml('&#8203;.');
+      append(Text(substring));
+    }
+  }
+}
diff --git a/pkg/nnbd_migration/lib/src/nullability_migration_impl.dart b/pkg/nnbd_migration/lib/src/nullability_migration_impl.dart
index 69bde9d..4e235b0 100644
--- a/pkg/nnbd_migration/lib/src/nullability_migration_impl.dart
+++ b/pkg/nnbd_migration/lib/src/nullability_migration_impl.dart
@@ -276,13 +276,16 @@
 
   static Location _computeLocation(
       LineInfo lineInfo, SourceEdit edit, Source source) {
-    final locationInfo = lineInfo.getLocation(edit.offset);
+    final startLocation = lineInfo.getLocation(edit.offset);
+    final endLocation = lineInfo.getLocation(edit.end);
     var location = Location(
       source.fullName,
       edit.offset,
       edit.length,
-      locationInfo.lineNumber,
-      locationInfo.columnNumber,
+      startLocation.lineNumber,
+      startLocation.columnNumber,
+      endLocation.lineNumber,
+      endLocation.columnNumber,
     );
     return location;
   }
diff --git a/pkg/nnbd_migration/lib/src/preview/preview_site.dart b/pkg/nnbd_migration/lib/src/preview/preview_site.dart
index bd690a9..d648ad7 100644
--- a/pkg/nnbd_migration/lib/src/preview/preview_site.dart
+++ b/pkg/nnbd_migration/lib/src/preview/preview_site.dart
@@ -497,8 +497,16 @@
       if (!file.path.endsWith('.dart')) {
         continue;
       }
+      var unitInfo = unitInfoMap[file.path];
+      if (unitInfo == null) {
+        // No disk content was recorded for this path at the time migration was
+        // performed.  This usually happens because the file is an unreferenced
+        // part (and therefore it didn't contribute to the migration at all). So
+        // just skip this file.
+        continue;
+      }
       var code = file.exists ? file.readAsStringSync() : '';
-      if (!unitInfoMap[file.path].hadDiskContent(code)) {
+      if (!unitInfo.hadDiskContent(code)) {
         throw StateError('Cannot apply migration. Files on disk do not match'
             ' the expected pre-migration state. Press the "rerun from sources"'
             ' button and then try again. (Changed file path is ${file.path})');
diff --git a/pkg/nnbd_migration/lib/src/variables.dart b/pkg/nnbd_migration/lib/src/variables.dart
index 0362d62..68492a3 100644
--- a/pkg/nnbd_migration/lib/src/variables.dart
+++ b/pkg/nnbd_migration/lib/src/variables.dart
@@ -187,12 +187,6 @@
         {})[uniqueIdentifierForSpan(node.offset, node.end)];
   }
 
-  /// If the given [node] is preceded by a `/*required*/` hint, returns the
-  /// HintComment for it; otherwise returns `null`.  See [recordRequiredHint].
-  HintComment getRequiredHint(Source source, FormalParameter node) {
-    return (_requiredHints[source] ?? {})[node.offset];
-  }
-
   /// If the given [expression] is followed by a null check hint (`/*!*/`),
   /// returns the HintComment for it; otherwise returns `null`.  See
   /// [recordNullCheckHint].
@@ -201,6 +195,12 @@
         {})[(uniqueIdentifierForSpan(expression.offset, expression.end))];
   }
 
+  /// If the given [node] is preceded by a `/*required*/` hint, returns the
+  /// HintComment for it; otherwise returns `null`.  See [recordRequiredHint].
+  HintComment getRequiredHint(Source source, FormalParameter node) {
+    return (_requiredHints[source] ?? {})[node.offset];
+  }
+
   /// Records conditional discard information for the given AST node (which is
   /// an `if` statement or a conditional (`?:`) expression).
   void recordConditionalDiscard(
@@ -268,12 +268,6 @@
         {})[uniqueIdentifierForSpan(node.offset, node.end)] = hintComment;
   }
 
-  /// Records that the given [node] was preceded by a `/*required*/` hint.
-  void recordRequiredHint(
-      Source source, FormalParameter node, HintComment hint) {
-    (_requiredHints[source] ??= {})[node.offset] = hint;
-  }
-
   /// Records that the given [expression] is followed by a null check hint
   /// (`/*!*/`), for later recall by [hasNullCheckHint].
   void recordNullCheckHint(
@@ -283,6 +277,12 @@
         hintComment;
   }
 
+  /// Records that the given [node] was preceded by a `/*required*/` hint.
+  void recordRequiredHint(
+      Source source, FormalParameter node, HintComment hint) {
+    (_requiredHints[source] ??= {})[node.offset] = hint;
+  }
+
   /// Records the fact that prior to migration, an unnecessary cast existed at
   /// [node].
   void recordUnnecessaryCast(Source source, AsExpression node) {
@@ -371,7 +371,8 @@
   /// Creates a decorated type for the given [element], which should come from
   /// an already-migrated library (or the SDK).
   DecoratedType _createDecoratedElementType(Element element) {
-    if (_graph.isBeingMigrated(element.library.source)) {
+    if (_graph.isBeingMigrated(element.library.source) &&
+        !_isLoadLibraryElement(element)) {
       var description;
       if (ElementTypeProvider.current is MigrationResolutionHooksImpl) {
         // Don't attempt to call toString() on element, or we will overflow.
@@ -429,6 +430,12 @@
     return result;
   }
 
+  bool _isLoadLibraryElement(Element element) =>
+      element.isSynthetic &&
+      element is FunctionElement &&
+      element.enclosingElement is LibraryElement &&
+      element.name == 'loadLibrary';
+
   /// Inverts the logic of [uniqueIdentifierForSpan], producing an (offset, end)
   /// pair.
   static OffsetEndPair spanForUniqueIdentifier(int span) {
diff --git a/pkg/nnbd_migration/test/api_test.dart b/pkg/nnbd_migration/test/api_test.dart
index 97bac6d..f4d8542 100644
--- a/pkg/nnbd_migration/test/api_test.dart
+++ b/pkg/nnbd_migration/test/api_test.dart
@@ -1570,6 +1570,28 @@
     await _checkSingleFileChanges(content, expected);
   }
 
+  Future<void> test_do_not_surround_named_expression() async {
+    var content = '''
+void f(int/*?*/ x, int/*?*/ y) {
+  g(named: <int>[x, y]);
+}
+g({List<int/*!*/>/*!*/ named}) {}
+''';
+    // Note: this test is to ensure that we don't produce
+    // `g((named: <int?>[x, y]) as List<int>)` (which would be a parse error).
+    // The migration we produce (`g(named: <int?>[x, y])`) still isn't great,
+    // because it's a type mismatch, but it's better.
+    //
+    // TODO(paulberry): a better migration would be `g(named: <int>[x!, y!])`.
+    var expected = '''
+void f(int? x, int? y) {
+  g(named: <int?>[x, y]);
+}
+g({required List<int> named}) {}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
   Future<void> test_downcast_dynamic_function_to_functionType() async {
     var content = '''
 void f(Function a) {
@@ -3357,6 +3379,32 @@
     await _checkSingleFileChanges(content, expected);
   }
 
+  Future<void> test_future_nullability_mismatch() async {
+    var content = '''
+String foo;
+
+Future<String> getNullableFoo() async {
+  return foo;
+}
+
+Future<String/*!*/> getFoo() {
+  return getNullableFoo();
+}
+''';
+    var expected = '''
+String? foo;
+
+Future<String?> getNullableFoo() async {
+  return foo;
+}
+
+Future<String> getFoo() {
+  return getNullableFoo().then((value) => value!);
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
   Future<void> test_future_or_t_downcast_to_t() async {
     var content = '''
 import 'dart:async';
@@ -3389,6 +3437,30 @@
     await _checkSingleFileChanges(content, expected);
   }
 
+  Future<void> test_future_type_mismatch() async {
+    var content = '''
+Future<List<int>> getNullableInts() async {
+  return [null];
+}
+
+Future<List<int/*!*/>> getInts() {
+  return getNullableInts();
+}
+''';
+    // TODO(paulberry): this is not a good migration.  Really we should produce
+    // getNullableInts.then((value) => value.cast());
+    var expected = '''
+Future<List<int?>> getNullableInts() async {
+  return [null];
+}
+
+Future<List<int>> getInts() {
+  return getNullableInts().then((value) => value as List<int>);
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
   Future<void> test_generic_exact_propagation() async {
     var content = '''
 class C<T> {
@@ -4695,6 +4767,46 @@
     await _checkSingleFileChanges(content, expected);
   }
 
+  Future<void> test_loadLibrary_call() async {
+    var testPath = convertPath('$testsPath/lib/test.dart');
+    var otherPath = convertPath('$testsPath/lib/other.dart');
+    var content = {
+      testPath: '''
+import 'other.dart' deferred as other;
+Future<Object> f() => other.loadLibrary();
+''',
+      otherPath: ''
+    };
+    var expected = {
+      testPath: '''
+import 'other.dart' deferred as other;
+Future<Object?> f() => other.loadLibrary();
+''',
+      otherPath: ''
+    };
+    await _checkMultipleFileChanges(content, expected);
+  }
+
+  Future<void> test_loadLibrary_tearOff() async {
+    var testPath = convertPath('$testsPath/lib/test.dart');
+    var otherPath = convertPath('$testsPath/lib/other.dart');
+    var content = {
+      testPath: '''
+import 'other.dart' deferred as other;
+Future<Object> Function() f() => other.loadLibrary;
+''',
+      otherPath: ''
+    };
+    var expected = {
+      testPath: '''
+import 'other.dart' deferred as other;
+Future<Object?> Function() f() => other.loadLibrary;
+''',
+      otherPath: ''
+    };
+    await _checkMultipleFileChanges(content, expected);
+  }
+
   Future<void> test_local_function() async {
     var content = '''
 int f(int i) {
diff --git a/pkg/nnbd_migration/test/edit_plan_test.dart b/pkg/nnbd_migration/test/edit_plan_test.dart
index 64ff882..078318e 100644
--- a/pkg/nnbd_migration/test/edit_plan_test.dart
+++ b/pkg/nnbd_migration/test/edit_plan_test.dart
@@ -315,6 +315,30 @@
         expectedIncludingInformative: 'f() => 0 /* zero */ .isEven;');
   }
 
+  Future<void> test_addPostfix_inner_precedence_add_parens() async {
+    await analyze('f(x) => -x;');
+    checkPlan(
+        planner.addPostfix(
+            planner.passThrough(findNode.prefix('-x')), '.abs()'),
+        'f(x) => (-x).abs();');
+  }
+
+  Future<void> test_addPostfix_inner_precedence_no_parens() async {
+    await analyze('f(x) => x++;');
+    checkPlan(
+        planner.addPostfix(
+            planner.passThrough(findNode.postfix('x++')), '.abs()'),
+        'f(x) => x++.abs();');
+  }
+
+  Future<void> test_addPostfix_outer_precedence() async {
+    await analyze('f(x) => x/*!*/;');
+    checkPlan(
+        planner.addPostfix(
+            planner.passThrough(findNode.simple('x/*!*/')), '.abs()'),
+        'f(x) => x.abs()/*!*/;');
+  }
+
   Future<void> test_addUnaryPostfix_inner_precedence_add_parens() async {
     await analyze('f(x) => -x;');
     checkPlan(
diff --git a/pkg/nnbd_migration/test/fix_aggregator_test.dart b/pkg/nnbd_migration/test/fix_aggregator_test.dart
index de9e76a..4430123 100644
--- a/pkg/nnbd_migration/test/fix_aggregator_test.dart
+++ b/pkg/nnbd_migration/test/fix_aggregator_test.dart
@@ -165,7 +165,8 @@
         ..addImport('package:collection/collection.dart', 'IterableExtension'),
       findNode.import('package:fixnum').combinators[0]:
           NodeChangeForShowCombinator()..addName('Int64'),
-      findNode.expression('null'): NodeChangeForExpression()..addNullCheck(null)
+      findNode.expression('null'): NodeChangeForExpression()
+        ..addExpressionChange(NullCheckChange(MockDartType()), null)
     });
     expect(previewInfo.applyTo(code), '''
 import 'package:args/args.dart';
@@ -342,10 +343,12 @@
     var aRef = findNode.simple('a +');
     var bRef = findNode.simple('b;');
     var previewInfo = run({
-      aRef: NodeChangeForExpression()..addNullCheck(_MockInfo()),
-      bRef: NodeChangeForExpression()..addNullCheck(_MockInfo()),
+      aRef: NodeChangeForExpression()
+        ..addExpressionChange(NullCheckChange(MockDartType()), _MockInfo()),
+      bRef: NodeChangeForExpression()
+        ..addExpressionChange(NullCheckChange(MockDartType()), _MockInfo()),
       findNode.binary('a + b'): NodeChangeForExpression()
-        ..addNullCheck(_MockInfo())
+        ..addExpressionChange(NullCheckChange(MockDartType()), _MockInfo())
     });
     expect(previewInfo.applyTo(code), 'f(a, b) => (a! + b!)!;');
   }
@@ -392,7 +395,8 @@
     var previewInfo = run({
       findNode.methodInvocation('f(x').argumentList: NodeChangeForArgumentList()
         ..dropArgument(findNode.simple('y);'), null),
-      findNode.simple('x, y'): NodeChangeForExpression()..addNullCheck(null)
+      findNode.simple('x, y'): NodeChangeForExpression()
+        ..addExpressionChange(NullCheckChange(MockDartType()), null)
     });
     expect(previewInfo.applyTo(code), '''
 f([int x, int y]) => null;
@@ -404,7 +408,8 @@
     var content = 'f(int x, int y) => x += y;';
     await analyze(content);
     var previewInfo = run({
-      findNode.assignment('+='): NodeChangeForAssignment()..addNullCheck(null)
+      findNode.assignment('+='): NodeChangeForAssignment()
+        ..addExpressionChange(NullCheckChange(MockDartType()), null)
     });
     expect(previewInfo.applyTo(code), 'f(int x, int y) => (x += y)!;');
   }
@@ -415,7 +420,7 @@
     var previewInfo = run({
       findNode.assignment('+='): NodeChangeForAssignment(),
       findNode.index('[0]').target: NodeChangeForExpression()
-        ..addNullCheck(null)
+        ..addExpressionChange(NullCheckChange(MockDartType()), null)
     });
     expect(previewInfo.applyTo(code), 'f(List<int> x, int y) => x![0] += y;');
   }
@@ -426,7 +431,8 @@
     var assignment = findNode.assignment('+=');
     var previewInfo = run({
       assignment: NodeChangeForAssignment(),
-      assignment.rightHandSide: NodeChangeForExpression()..addNullCheck(null)
+      assignment.rightHandSide: NodeChangeForExpression()
+        ..addExpressionChange(NullCheckChange(MockDartType()), null)
     });
     expect(previewInfo.applyTo(code), 'f(int x, int y) => x += y!;');
   }
@@ -468,7 +474,9 @@
     await analyze(content);
     var previewInfo = run({
       findNode.assignment('+='): NodeChangeForAssignment()
-        ..introduceAs(nnbdTypeProvider.intType, null)
+        ..addExpressionChange(
+            IntroduceAsChange(nnbdTypeProvider.intType, isDowncast: false),
+            null)
     });
     expect(previewInfo.applyTo(code), 'f(int x, int y) => (x += y) as int;');
   }
@@ -509,7 +517,7 @@
       findNode.statement('if'): NodeChangeForIfStatement()
         ..conditionValue = true,
       findNode.simple('j.isEven'): NodeChangeForExpression()
-        ..addNullCheck(_MockInfo())
+        ..addExpressionChange(NullCheckChange(MockDartType()), _MockInfo())
     });
     expect(previewInfo.applyTo(code), '''
 f(int i, int/*?*/ j) {
@@ -530,7 +538,7 @@
       findNode.statement('if'): NodeChangeForIfStatement()
         ..conditionValue = true,
       findNode.simple('j.isEven'): NodeChangeForExpression()
-        ..addNullCheck(_MockInfo())
+        ..addExpressionChange(NullCheckChange(MockDartType()), _MockInfo())
     });
     expect(previewInfo.applyTo(code), '''
 f(int i, int/*?*/ j) {
@@ -830,7 +838,9 @@
     var cd = findNode.cascade('c..d');
     var previewInfo = run({
       cd: NodeChangeForExpression()
-        ..introduceAs(nnbdTypeProvider.intType, _MockInfo())
+        ..addExpressionChange(
+            IntroduceAsChange(nnbdTypeProvider.intType, isDowncast: false),
+            _MockInfo())
     });
     expect(
         previewInfo.applyTo(code), 'f(a, c) => a..b = (throw (c..d) as int);');
@@ -841,7 +851,9 @@
     var expr = findNode.simple('o;');
     var previewInfo = run({
       expr: NodeChangeForExpression()
-        ..introduceAs(nnbdTypeProvider.dynamicType, _MockInfo())
+        ..addExpressionChange(
+            IntroduceAsChange(nnbdTypeProvider.dynamicType, isDowncast: false),
+            _MockInfo())
     });
     expect(previewInfo.applyTo(code), 'f(Object o) => o as dynamic;');
   }
@@ -855,7 +867,10 @@
     var expr = findNode.simple('o;');
     var previewInfo = run({
       expr: NodeChangeForExpression()
-        ..introduceAs(nnbdTypeProvider.futureNullType, _MockInfo())
+        ..addExpressionChange(
+            IntroduceAsChange(nnbdTypeProvider.futureNullType,
+                isDowncast: false),
+            _MockInfo())
     });
     expect(previewInfo.applyTo(code), '''
 import 'dart:async' as a;
@@ -869,12 +884,14 @@
     var expr = findNode.simple('o;');
     var previewInfo = run({
       expr: NodeChangeForExpression()
-        ..introduceAs(
-            FunctionTypeImpl(
-                returnType: nnbdTypeProvider.boolType,
-                typeFormals: [],
-                parameters: [],
-                nullabilitySuffix: NullabilitySuffix.none),
+        ..addExpressionChange(
+            IntroduceAsChange(
+                FunctionTypeImpl(
+                    returnType: nnbdTypeProvider.boolType,
+                    typeFormals: [],
+                    parameters: [],
+                    nullabilitySuffix: NullabilitySuffix.none),
+                isDowncast: false),
             _MockInfo())
     });
     expect(previewInfo.applyTo(code), 'f(Object o) => o as bool Function();');
@@ -885,15 +902,17 @@
     var expr = findNode.simple('o;');
     var previewInfo = run({
       expr: NodeChangeForExpression()
-        ..introduceAs(
-            FunctionTypeImpl(
-                returnType: nnbdTypeProvider.boolType,
-                typeFormals: [
-                  TypeParameterElementImpl.synthetic('T')
-                    ..bound = nnbdTypeProvider.numType
-                ],
-                parameters: [],
-                nullabilitySuffix: NullabilitySuffix.none),
+        ..addExpressionChange(
+            IntroduceAsChange(
+                FunctionTypeImpl(
+                    returnType: nnbdTypeProvider.boolType,
+                    typeFormals: [
+                      TypeParameterElementImpl.synthetic('T')
+                        ..bound = nnbdTypeProvider.numType
+                    ],
+                    parameters: [],
+                    nullabilitySuffix: NullabilitySuffix.none),
+                isDowncast: false),
             _MockInfo())
     });
     expect(previewInfo.applyTo(code),
@@ -905,15 +924,17 @@
     var expr = findNode.simple('o;');
     var previewInfo = run({
       expr: NodeChangeForExpression()
-        ..introduceAs(
-            FunctionTypeImpl(
-                returnType: nnbdTypeProvider.boolType,
-                typeFormals: [
-                  TypeParameterElementImpl.synthetic('T')
-                    ..bound = nnbdTypeProvider.dynamicType
-                ],
-                parameters: [],
-                nullabilitySuffix: NullabilitySuffix.none),
+        ..addExpressionChange(
+            IntroduceAsChange(
+                FunctionTypeImpl(
+                    returnType: nnbdTypeProvider.boolType,
+                    typeFormals: [
+                      TypeParameterElementImpl.synthetic('T')
+                        ..bound = nnbdTypeProvider.dynamicType
+                    ],
+                    parameters: [],
+                    nullabilitySuffix: NullabilitySuffix.none),
+                isDowncast: false),
             _MockInfo())
     });
     expect(
@@ -925,15 +946,17 @@
     var expr = findNode.simple('o;');
     var previewInfo = run({
       expr: NodeChangeForExpression()
-        ..introduceAs(
-            FunctionTypeImpl(
-                returnType: nnbdTypeProvider.boolType,
-                typeFormals: [
-                  TypeParameterElementImpl.synthetic('T')
-                    ..bound = nnbdTypeProvider.objectType
-                ],
-                parameters: [],
-                nullabilitySuffix: NullabilitySuffix.none),
+        ..addExpressionChange(
+            IntroduceAsChange(
+                FunctionTypeImpl(
+                    returnType: nnbdTypeProvider.boolType,
+                    typeFormals: [
+                      TypeParameterElementImpl.synthetic('T')
+                        ..bound = nnbdTypeProvider.objectType
+                    ],
+                    parameters: [],
+                    nullabilitySuffix: NullabilitySuffix.none),
+                isDowncast: false),
             _MockInfo())
     });
     expect(previewInfo.applyTo(code),
@@ -946,16 +969,18 @@
     var expr = findNode.simple('o;');
     var previewInfo = run({
       expr: NodeChangeForExpression()
-        ..introduceAs(
-            FunctionTypeImpl(
-                returnType: nnbdTypeProvider.boolType,
-                typeFormals: [
-                  TypeParameterElementImpl.synthetic('T')
-                    ..bound = (nnbdTypeProvider.objectType as TypeImpl)
-                        .withNullability(NullabilitySuffix.question)
-                ],
-                parameters: [],
-                nullabilitySuffix: NullabilitySuffix.none),
+        ..addExpressionChange(
+            IntroduceAsChange(
+                FunctionTypeImpl(
+                    returnType: nnbdTypeProvider.boolType,
+                    typeFormals: [
+                      TypeParameterElementImpl.synthetic('T')
+                        ..bound = (nnbdTypeProvider.objectType as TypeImpl)
+                            .withNullability(NullabilitySuffix.question)
+                    ],
+                    parameters: [],
+                    nullabilitySuffix: NullabilitySuffix.none),
+                isDowncast: false),
             _MockInfo())
     });
     expect(
@@ -967,16 +992,18 @@
     var expr = findNode.simple('o;');
     var previewInfo = run({
       expr: NodeChangeForExpression()
-        ..introduceAs(
-            FunctionTypeImpl(
-                returnType: nnbdTypeProvider.boolType,
-                typeFormals: [
-                  TypeParameterElementImpl.synthetic('T')
-                    ..bound = (nnbdTypeProvider.numType as TypeImpl)
-                        .withNullability(NullabilitySuffix.question)
-                ],
-                parameters: [],
-                nullabilitySuffix: NullabilitySuffix.none),
+        ..addExpressionChange(
+            IntroduceAsChange(
+                FunctionTypeImpl(
+                    returnType: nnbdTypeProvider.boolType,
+                    typeFormals: [
+                      TypeParameterElementImpl.synthetic('T')
+                        ..bound = (nnbdTypeProvider.numType as TypeImpl)
+                            .withNullability(NullabilitySuffix.question)
+                    ],
+                    parameters: [],
+                    nullabilitySuffix: NullabilitySuffix.none),
+                isDowncast: false),
             _MockInfo())
     });
     expect(previewInfo.applyTo(code),
@@ -988,15 +1015,17 @@
     var expr = findNode.simple('o;');
     var previewInfo = run({
       expr: NodeChangeForExpression()
-        ..introduceAs(
-            FunctionTypeImpl(
-                returnType: nnbdTypeProvider.boolType,
-                typeFormals: [
-                  TypeParameterElementImpl.synthetic('T'),
-                  TypeParameterElementImpl.synthetic('U')
-                ],
-                parameters: [],
-                nullabilitySuffix: NullabilitySuffix.none),
+        ..addExpressionChange(
+            IntroduceAsChange(
+                FunctionTypeImpl(
+                    returnType: nnbdTypeProvider.boolType,
+                    typeFormals: [
+                      TypeParameterElementImpl.synthetic('T'),
+                      TypeParameterElementImpl.synthetic('U')
+                    ],
+                    parameters: [],
+                    nullabilitySuffix: NullabilitySuffix.none),
+                isDowncast: false),
             _MockInfo())
     });
     expect(previewInfo.applyTo(code),
@@ -1008,17 +1037,19 @@
     var expr = findNode.simple('o;');
     var previewInfo = run({
       expr: NodeChangeForExpression()
-        ..introduceAs(
-            FunctionTypeImpl(
-                returnType: nnbdTypeProvider.boolType,
-                typeFormals: [],
-                parameters: [
-                  ParameterElementImpl.synthetic(
-                      'x', nnbdTypeProvider.intType, ParameterKind.REQUIRED),
-                  ParameterElementImpl.synthetic(
-                      'y', nnbdTypeProvider.numType, ParameterKind.REQUIRED)
-                ],
-                nullabilitySuffix: NullabilitySuffix.none),
+        ..addExpressionChange(
+            IntroduceAsChange(
+                FunctionTypeImpl(
+                    returnType: nnbdTypeProvider.boolType,
+                    typeFormals: [],
+                    parameters: [
+                      ParameterElementImpl.synthetic('x',
+                          nnbdTypeProvider.intType, ParameterKind.REQUIRED),
+                      ParameterElementImpl.synthetic(
+                          'y', nnbdTypeProvider.numType, ParameterKind.REQUIRED)
+                    ],
+                    nullabilitySuffix: NullabilitySuffix.none),
+                isDowncast: false),
             _MockInfo())
     });
     expect(previewInfo.applyTo(code),
@@ -1030,17 +1061,19 @@
     var expr = findNode.simple('o;');
     var previewInfo = run({
       expr: NodeChangeForExpression()
-        ..introduceAs(
-            FunctionTypeImpl(
-                returnType: nnbdTypeProvider.boolType,
-                typeFormals: [],
-                parameters: [
-                  ParameterElementImpl.synthetic(
-                      'x', nnbdTypeProvider.intType, ParameterKind.NAMED),
-                  ParameterElementImpl.synthetic(
-                      'y', nnbdTypeProvider.numType, ParameterKind.NAMED)
-                ],
-                nullabilitySuffix: NullabilitySuffix.none),
+        ..addExpressionChange(
+            IntroduceAsChange(
+                FunctionTypeImpl(
+                    returnType: nnbdTypeProvider.boolType,
+                    typeFormals: [],
+                    parameters: [
+                      ParameterElementImpl.synthetic(
+                          'x', nnbdTypeProvider.intType, ParameterKind.NAMED),
+                      ParameterElementImpl.synthetic(
+                          'y', nnbdTypeProvider.numType, ParameterKind.NAMED)
+                    ],
+                    nullabilitySuffix: NullabilitySuffix.none),
+                isDowncast: false),
             _MockInfo())
     });
     expect(previewInfo.applyTo(code),
@@ -1052,17 +1085,19 @@
     var expr = findNode.simple('o;');
     var previewInfo = run({
       expr: NodeChangeForExpression()
-        ..introduceAs(
-            FunctionTypeImpl(
-                returnType: nnbdTypeProvider.boolType,
-                typeFormals: [],
-                parameters: [
-                  ParameterElementImpl.synthetic(
-                      'x', nnbdTypeProvider.intType, ParameterKind.POSITIONAL),
-                  ParameterElementImpl.synthetic(
-                      'y', nnbdTypeProvider.numType, ParameterKind.POSITIONAL)
-                ],
-                nullabilitySuffix: NullabilitySuffix.none),
+        ..addExpressionChange(
+            IntroduceAsChange(
+                FunctionTypeImpl(
+                    returnType: nnbdTypeProvider.boolType,
+                    typeFormals: [],
+                    parameters: [
+                      ParameterElementImpl.synthetic('x',
+                          nnbdTypeProvider.intType, ParameterKind.POSITIONAL),
+                      ParameterElementImpl.synthetic('y',
+                          nnbdTypeProvider.numType, ParameterKind.POSITIONAL)
+                    ],
+                    nullabilitySuffix: NullabilitySuffix.none),
+                isDowncast: false),
             _MockInfo())
     });
     expect(previewInfo.applyTo(code),
@@ -1074,9 +1109,11 @@
     var expr = findNode.simple('o;');
     var previewInfo = run({
       expr: NodeChangeForExpression()
-        ..introduceAs(
-            nnbdTypeProvider.mapType(
-                nnbdTypeProvider.intType, nnbdTypeProvider.boolType),
+        ..addExpressionChange(
+            IntroduceAsChange(
+                nnbdTypeProvider.mapType(
+                    nnbdTypeProvider.intType, nnbdTypeProvider.boolType),
+                isDowncast: false),
             _MockInfo())
     });
     expect(previewInfo.applyTo(code), 'f(Object o) => o as Map<int, bool>;');
@@ -1087,7 +1124,9 @@
     var expr = findNode.binary('a | b');
     var previewInfo = run({
       expr: NodeChangeForExpression()
-        ..introduceAs(nnbdTypeProvider.intType, _MockInfo())
+        ..addExpressionChange(
+            IntroduceAsChange(nnbdTypeProvider.intType, isDowncast: false),
+            _MockInfo())
     });
     expect(previewInfo.applyTo(code), 'f(a, b) => a | b as int;');
   }
@@ -1097,7 +1136,9 @@
     var expr = findNode.binary('a < b');
     var previewInfo = run({
       expr: NodeChangeForExpression()
-        ..introduceAs(nnbdTypeProvider.boolType, _MockInfo())
+        ..addExpressionChange(
+            IntroduceAsChange(nnbdTypeProvider.boolType, isDowncast: false),
+            _MockInfo())
     });
     expect(previewInfo.applyTo(code), 'f(a, b) => (a < b) as bool;');
   }
@@ -1110,7 +1151,10 @@
     var expr = findNode.simple('o;');
     var previewInfo = run({
       expr: NodeChangeForExpression()
-        ..introduceAs(nnbdTypeProvider.futureNullType, _MockInfo())
+        ..addExpressionChange(
+            IntroduceAsChange(nnbdTypeProvider.futureNullType,
+                isDowncast: false),
+            _MockInfo())
     });
     expect(previewInfo.applyTo(code), '''
 import 'dart:async' as a;
@@ -1123,8 +1167,10 @@
     var expr = findNode.simple('x;');
     var previewInfo = run({
       expr: NodeChangeForExpression()
-        ..introduceAs(nnbdTypeProvider.intType, _MockInfo())
-        ..addNullCheck(_MockInfo())
+        ..addExpressionChange(NullCheckChange(MockDartType()), _MockInfo())
+        ..addExpressionChange(
+            IntroduceAsChange(nnbdTypeProvider.intType, isDowncast: false),
+            _MockInfo())
     });
     expect(previewInfo.applyTo(code), 'f(x) => x! as int;');
   }
@@ -1191,8 +1237,11 @@
   Future<void> test_noValidMigration() async {
     await analyze('f(a) => null;');
     var literal = findNode.nullLiteral('null');
-    var previewInfo = run(
-        {literal: NodeChangeForExpression()..addNoValidMigration(_MockInfo())});
+    var previewInfo = run({
+      literal: NodeChangeForExpression()
+        ..addExpressionChange(
+            NoValidMigrationChange(MockDartType()), _MockInfo())
+    });
     expect(previewInfo.applyTo(code), code);
     expect(previewInfo.applyTo(code, includeInformative: true),
         'f(a) => null /* no valid migration */;');
@@ -1201,40 +1250,50 @@
   Future<void> test_nullCheck_index_cascadeResult() async {
     await analyze('f(a) => a..[0].c;');
     var index = findNode.index('[0]');
-    var previewInfo =
-        run({index: NodeChangeForExpression()..addNullCheck(_MockInfo())});
+    var previewInfo = run({
+      index: NodeChangeForExpression()
+        ..addExpressionChange(NullCheckChange(MockDartType()), _MockInfo())
+    });
     expect(previewInfo.applyTo(code), 'f(a) => a..[0]!.c;');
   }
 
   Future<void> test_nullCheck_methodInvocation_cascadeResult() async {
     await analyze('f(a) => a..b().c;');
     var method = findNode.methodInvocation('b()');
-    var previewInfo = run(
-        {method: NodeChangeForMethodInvocation()..addNullCheck(_MockInfo())});
+    var previewInfo = run({
+      method: NodeChangeForMethodInvocation()
+        ..addExpressionChange(NullCheckChange(MockDartType()), _MockInfo())
+    });
     expect(previewInfo.applyTo(code), 'f(a) => a..b()!.c;');
   }
 
   Future<void> test_nullCheck_no_parens() async {
     await analyze('f(a) => a++;');
     var expr = findNode.postfix('a++');
-    var previewInfo =
-        run({expr: NodeChangeForExpression()..addNullCheck(_MockInfo())});
+    var previewInfo = run({
+      expr: NodeChangeForExpression()
+        ..addExpressionChange(NullCheckChange(MockDartType()), _MockInfo())
+    });
     expect(previewInfo.applyTo(code), 'f(a) => a++!;');
   }
 
   Future<void> test_nullCheck_parens() async {
     await analyze('f(a) => -a;');
     var expr = findNode.prefix('-a');
-    var previewInfo =
-        run({expr: NodeChangeForExpression()..addNullCheck(_MockInfo())});
+    var previewInfo = run({
+      expr: NodeChangeForExpression()
+        ..addExpressionChange(NullCheckChange(MockDartType()), _MockInfo())
+    });
     expect(previewInfo.applyTo(code), 'f(a) => (-a)!;');
   }
 
   Future<void> test_nullCheck_propertyAccess_cascadeResult() async {
     await analyze('f(a) => a..b.c;');
     var property = findNode.propertyAccess('b');
-    var previewInfo = run(
-        {property: NodeChangeForPropertyAccess()..addNullCheck(_MockInfo())});
+    var previewInfo = run({
+      property: NodeChangeForPropertyAccess()
+        ..addExpressionChange(NullCheckChange(MockDartType()), _MockInfo())
+    });
     expect(previewInfo.applyTo(code), 'f(a) => a..b!.c;');
   }
 
@@ -1409,7 +1468,7 @@
     await analyze(content);
     var previewInfo = run({
       findNode.postfix('++'): NodeChangeForPostfixExpression()
-        ..addNullCheck(null)
+        ..addExpressionChange(NullCheckChange(MockDartType()), null)
     });
     expect(previewInfo.applyTo(code), 'f(int x) => x++!;');
   }
@@ -1420,7 +1479,7 @@
     var previewInfo = run({
       findNode.postfix('++'): NodeChangeForPostfixExpression(),
       findNode.index('[0]').target: NodeChangeForExpression()
-        ..addNullCheck(null)
+        ..addExpressionChange(NullCheckChange(MockDartType()), null)
     });
     expect(previewInfo.applyTo(code), 'f(List<int> x) => x![0]++;');
   }
@@ -1430,7 +1489,9 @@
     await analyze(content);
     var previewInfo = run({
       findNode.postfix('++'): NodeChangeForPostfixExpression()
-        ..introduceAs(nnbdTypeProvider.intType, null)
+        ..addExpressionChange(
+            IntroduceAsChange(nnbdTypeProvider.intType, isDowncast: false),
+            null)
     });
     expect(previewInfo.applyTo(code), 'f(int x) => x++ as int;');
   }
@@ -1471,7 +1532,8 @@
     var content = 'f(int x) => ++x;';
     await analyze(content);
     var previewInfo = run({
-      findNode.prefix('++'): NodeChangeForPrefixExpression()..addNullCheck(null)
+      findNode.prefix('++'): NodeChangeForPrefixExpression()
+        ..addExpressionChange(NullCheckChange(MockDartType()), null)
     });
     expect(previewInfo.applyTo(code), 'f(int x) => (++x)!;');
   }
@@ -1482,7 +1544,7 @@
     var previewInfo = run({
       findNode.prefix('++'): NodeChangeForPrefixExpression(),
       findNode.index('[0]').target: NodeChangeForExpression()
-        ..addNullCheck(null)
+        ..addExpressionChange(NullCheckChange(MockDartType()), null)
     });
     expect(previewInfo.applyTo(code), 'f(List<int> x) => ++x![0];');
   }
@@ -1492,7 +1554,9 @@
     await analyze(content);
     var previewInfo = run({
       findNode.prefix('++'): NodeChangeForPrefixExpression()
-        ..introduceAs(nnbdTypeProvider.intType, null)
+        ..addExpressionChange(
+            IntroduceAsChange(nnbdTypeProvider.intType, isDowncast: false),
+            null)
     });
     expect(previewInfo.applyTo(code), 'f(int x) => ++x as int;');
   }
@@ -1727,7 +1791,8 @@
     var previewInfo = run({
       methodInvocation: NodeChangeForMethodInvocation()
         ..removeNullAwareness = true,
-      argument: NodeChangeForExpression()..addNullCheck(_MockInfo())
+      argument: NodeChangeForExpression()
+        ..addExpressionChange(NullCheckChange(MockDartType()), _MockInfo())
     });
     expect(previewInfo.applyTo(code), 'f(x) => x.m(x!);');
   }
@@ -1906,7 +1971,7 @@
           NodeChangeForVariableDeclarationList()
             ..addExplicitType = nnbdTypeProvider.intType,
       findNode.integerLiteral('0'): NodeChangeForExpression()
-        ..addNullCheck(_MockInfo())
+        ..addExpressionChange(NullCheckChange(MockDartType()), _MockInfo())
     });
     expect(previewInfo.applyTo(code), 'int x = 0!;');
   }
diff --git a/pkg/nnbd_migration/test/fix_builder_test.dart b/pkg/nnbd_migration/test/fix_builder_test.dart
index e292a6f..1c437ba 100644
--- a/pkg/nnbd_migration/test/fix_builder_test.dart
+++ b/pkg/nnbd_migration/test/fix_builder_test.dart
@@ -1429,9 +1429,7 @@
       methodInvocation.methodName: isMethodNameChange('firstWhereOrNull'),
       methodInvocation.argumentList:
           isDropArgument({functionExpression.parent: anything}),
-      // Behavior of the function expression and its subexpression don't matter
-      // because they're being dropped.
-      functionExpression.parent: anything,
+      // Behavior of the null literal doesn't matter because it's being dropped.
       findNode.nullLiteral('null'): anything
     });
     expect(fixBuilder.needsIterableExtension, true);
@@ -3267,7 +3265,7 @@
     var propertyAccess = findNode.propertyAccess('?.');
     visitSubexpression(propertyAccess, 'int', changes: {
       propertyAccess: TypeMatcher<NodeChangeForPropertyAccess>()
-          .having((c) => c.addsNullCheck, 'addsNullCheck', true)
+          .havingNullCheckWithInfo(isNotNull)
           .having((c) => c.removeNullAwareness, 'removeNullAwareness', true)
     });
   }
@@ -3906,21 +3904,25 @@
           .having((c) => c.conditionValue, 'conditionValue', knownValue);
 }
 
-extension on TypeMatcher<NodeChangeForExpression> {
-  TypeMatcher<NodeChangeForExpression> havingNullCheckWithInfo(
-          dynamic matcher) =>
-      having((c) => c.addsNullCheck, 'addsNullCheck', true)
-          .having((c) => c.addNullCheckInfo, 'addNullCheckInfo', matcher);
+extension _NodeChangeForExpressionExtension<T extends NodeChangeForExpression>
+    on TypeMatcher<T> {
+  TypeMatcher<T> havingExpressionChange(
+          dynamic changeMatcher, dynamic infoMatcher) =>
+      having((c) => c.expressionChanges.single, 'expressionChanges.single',
+              changeMatcher)
+          .having((c) => c.expressionChangeInfos.single,
+              'expressionChangeInfos.single', infoMatcher);
 
-  TypeMatcher<NodeChangeForExpression> havingNoValidMigrationWithInfo(
-          dynamic matcher) =>
-      having((c) => c.addsNoValidMigration, 'addsNoValidMigration', true)
-          .having((c) => c.addNoValidMigrationInfo, 'addNoValidMigrationInfo',
-              matcher);
+  TypeMatcher<T> havingNullCheckWithInfo(dynamic matcher) =>
+      havingExpressionChange(TypeMatcher<NullCheckChange>(), matcher);
 
-  TypeMatcher<NodeChangeForExpression> havingIndroduceAsWithInfo(
+  TypeMatcher<T> havingNoValidMigrationWithInfo(dynamic matcher) =>
+      havingExpressionChange(TypeMatcher<NoValidMigrationChange>(), matcher);
+
+  TypeMatcher<T> havingIndroduceAsWithInfo(
           dynamic typeStringMatcher, dynamic infoMatcher) =>
-      having((c) => c.introducesAsType.toString(), 'introducesAsType (string)',
-              typeStringMatcher)
-          .having((c) => c.introducesAsInfo, 'introducesAsInfo', infoMatcher);
+      havingExpressionChange(
+          TypeMatcher<IntroduceAsChange>().having(
+              (c) => c.type.toString(), 'type (string)', typeStringMatcher),
+          infoMatcher);
 }
diff --git a/pkg/nnbd_migration/test/migration_cli_test.dart b/pkg/nnbd_migration/test/migration_cli_test.dart
index f065da9..5758e9a 100644
--- a/pkg/nnbd_migration/test/migration_cli_test.dart
+++ b/pkg/nnbd_migration/test/migration_cli_test.dart
@@ -125,16 +125,6 @@
   }
 
   @override
-  void listenForSignalInterrupt() {
-    if (_runWhilePreviewServerActive == null) {
-      fail('Preview server not expected to have been started');
-    }
-    sigIntSignalled = Completer();
-    _runWhilePreviewServerActive.call().then((_) => sigIntSignalled.complete());
-    _runWhilePreviewServerActive = null;
-  }
-
-  @override
   Object computeBindAddress() {
     var address = super.computeBindAddress();
     if (Platform.environment.containsKey('FORCE_IPV6') &&
@@ -176,6 +166,16 @@
     }
   }
 
+  @override
+  void listenForSignalInterrupt() {
+    if (_runWhilePreviewServerActive == null) {
+      fail('Preview server not expected to have been started');
+    }
+    sigIntSignalled = Completer();
+    _runWhilePreviewServerActive.call().then((_) => sigIntSignalled.complete());
+    _runWhilePreviewServerActive = null;
+  }
+
   Future<void> runWithPreviewServer(Future<void> Function() callback) async {
     _runWhilePreviewServerActive = callback;
     await run();
@@ -1002,6 +1002,31 @@
     });
   }
 
+  test_lifecycle_preview_apply_changes_unreferenced_part() async {
+    var projectContents = simpleProject()
+      ..['lib/unreferenced_part.dart'] = '''
+part of foo;
+
+int f() => null;
+''';
+    var projectDir = createProjectDir(projectContents);
+    var cli = _createCli();
+    bool applyHookCalled = false;
+    cli._onApplyHook = () {
+      expect(applyHookCalled, false);
+      applyHookCalled = true;
+      // Changes should have been made
+      assertProjectContents(projectDir, simpleProject(migrated: true));
+    };
+    await runWithPreviewServer(cli, [projectDir], (url) async {
+      expect(
+          logger.stdoutBuffer.toString(), contains('No analysis issues found'));
+      await assertPreviewServerResponsive(url);
+      await _tellPreviewToApplyChanges(url);
+      expect(applyHookCalled, true);
+    });
+  }
+
   test_lifecycle_preview_extra_forward_slash() async {
     var projectDir = createProjectDir(simpleProject());
     var cli = _createCli();
diff --git a/pkg/nnbd_migration/test/preview/preview_site_test.dart b/pkg/nnbd_migration/test/preview/preview_site_test.dart
index 550cd92..313c365 100644
--- a/pkg/nnbd_migration/test/preview/preview_site_test.dart
+++ b/pkg/nnbd_migration/test/preview/preview_site_test.dart
@@ -65,7 +65,7 @@
     // Add a source change for analysis_options, which has no UnitInfo.
     dartfixListener.addSourceFileEdit(
         'enable experiment',
-        Location(analysisOptionsPath, 9, 0, 1, 9),
+        Location(analysisOptionsPath, 9, 0, 1, 9, 1, 9),
         SourceFileEdit(analysisOptionsPath, 0, edits: [
           SourceEdit(9, 0, '\n  enable-experiment:\n  - non-nullable')
         ]));
@@ -100,7 +100,7 @@
     file.writeAsStringSync(currentContent);
     dartfixListener.addSourceFileEdit(
         'test change',
-        Location(path, 10, 0, 1, 10),
+        Location(path, 10, 0, 1, 10, 1, 10),
         SourceFileEdit(path, 0, edits: [SourceEdit(10, 0, 'List args')]));
     expect(() => site.performApply([]), throwsA(isA<StateError>()));
     expect(file.readAsStringSync(), currentContent);
@@ -115,7 +115,7 @@
     site.unitInfoMap[path] = UnitInfo(path)..diskContent = content;
     dartfixListener.addSourceFileEdit(
         'test change',
-        Location(path, 10, 0, 1, 10),
+        Location(path, 10, 0, 1, 10, 1, 10),
         SourceFileEdit(path, 0, edits: [
           SourceEdit(10, 0, 'List args'),
           SourceEdit(13, 0, '\n  print(args);\n')
@@ -136,7 +136,7 @@
     site.unitInfoMap[path] = UnitInfo(path)..diskContent = content;
     dartfixListener.addSourceFileEdit(
         'test change',
-        Location(path, 10, 0, 1, 10),
+        Location(path, 10, 0, 1, 10, 1, 10),
         SourceFileEdit(path, 0, edits: [SourceEdit(10, 0, 'List args')]));
     site.performApply([]);
     expect(file.readAsStringSync(), 'void main(List args) {}');
@@ -159,12 +159,6 @@
         equals('// comment\n\n// @dart=2.9\n\nvoid main() {}'));
   }
 
-  void test_optOutOfNullSafety_commentThenSemicolon() {
-    expect(
-        IncrementalPlan.optCodeOutOfNullSafety('// comment\n;\nvoid main() {}'),
-        equals('// comment\n\n// @dart=2.9\n\n;\nvoid main() {}'));
-  }
-
   void test_optOutOfNullSafety_commentThenCode_windows() {
     expect(
         IncrementalPlan.optCodeOutOfNullSafety(
@@ -187,6 +181,12 @@
             '// comment\n// comment\n\n// @dart=2.9\n\nimport "dart:core";'));
   }
 
+  void test_optOutOfNullSafety_commentThenSemicolon() {
+    expect(
+        IncrementalPlan.optCodeOutOfNullSafety('// comment\n;\nvoid main() {}'),
+        equals('// comment\n\n// @dart=2.9\n\n;\nvoid main() {}'));
+  }
+
   void test_optOutOfNullSafety_empty() {
     expect(IncrementalPlan.optCodeOutOfNullSafety(''), equals('// @dart=2.9'));
   }
@@ -388,6 +388,32 @@
     expect(state.needsRerun, true);
   }
 
+  void test_applyMigration_doNotOptOutFileNotInPathsToProcess() async {
+    final pathA = convertPath('$projectPath/lib/a.dart');
+    final pathB = convertPath('$projectPath/lib/b.dart');
+    final content = 'void main() {}';
+    await setUpMigrationInfo({pathA: content, pathB: content},
+        // Neither [pathA] nor [[pathB] should be migrated.
+        shouldBeMigratedFunction: (String path) => false,
+        pathsToProcess: [pathA]);
+    site.unitInfoMap[pathA] = UnitInfo(pathA)
+      ..diskContent = content
+      ..wasExplicitlyOptedOut = false
+      ..migrationStatus = UnitMigrationStatus.optingOut;
+    site.unitInfoMap[pathB] = UnitInfo(pathB)
+      ..diskContent = content
+      ..wasExplicitlyOptedOut = false
+      ..migrationStatus = UnitMigrationStatus.optingOut;
+    var navigationTree =
+        NavigationTreeRenderer(migrationInfo, state.pathMapper).render();
+    site.performApply(navigationTree);
+    expect(getFile(pathA).readAsStringSync(), '''
+// @dart=2.9
+
+void main() {}''');
+    expect(getFile(pathB).readAsStringSync(), 'void main() {}');
+  }
+
   void test_applyMigration_migratePreviouslyOptedOutFile() async {
     final path = convertPath('$projectPath/lib/a.dart');
     final content = '''
@@ -400,7 +426,7 @@
       ..wasExplicitlyOptedOut = true;
     dartfixListener.addSourceFileEdit(
         'remove DLV comment',
-        Location(path, 0, 14, 1, 1),
+        Location(path, 0, 14, 1, 1, 3, 1),
         SourceFileEdit(path, 0, edits: [SourceEdit(0, 14, '')]));
     var navigationTree =
         NavigationTreeRenderer(migrationInfo, state.pathMapper).render();
@@ -441,7 +467,7 @@
       ..wasExplicitlyOptedOut = false;
     dartfixListener.addSourceFileEdit(
         'test change',
-        Location(path, 10, 0, 1, 10),
+        Location(path, 10, 0, 1, 10, 1, 10),
         SourceFileEdit(path, 0, edits: [SourceEdit(10, 0, 'List args')]));
     var navigationTree =
         NavigationTreeRenderer(migrationInfo, state.pathMapper).render();
@@ -482,32 +508,6 @@
 '''));
   }
 
-  void test_applyMigration_doNotOptOutFileNotInPathsToProcess() async {
-    final pathA = convertPath('$projectPath/lib/a.dart');
-    final pathB = convertPath('$projectPath/lib/b.dart');
-    final content = 'void main() {}';
-    await setUpMigrationInfo({pathA: content, pathB: content},
-        // Neither [pathA] nor [[pathB] should be migrated.
-        shouldBeMigratedFunction: (String path) => false,
-        pathsToProcess: [pathA]);
-    site.unitInfoMap[pathA] = UnitInfo(pathA)
-      ..diskContent = content
-      ..wasExplicitlyOptedOut = false
-      ..migrationStatus = UnitMigrationStatus.optingOut;
-    site.unitInfoMap[pathB] = UnitInfo(pathB)
-      ..diskContent = content
-      ..wasExplicitlyOptedOut = false
-      ..migrationStatus = UnitMigrationStatus.optingOut;
-    var navigationTree =
-        NavigationTreeRenderer(migrationInfo, state.pathMapper).render();
-    site.performApply(navigationTree);
-    expect(getFile(pathA).readAsStringSync(), '''
-// @dart=2.9
-
-void main() {}''');
-    expect(getFile(pathB).readAsStringSync(), 'void main() {}');
-  }
-
   void test_applyMigration_optOutOne_migrateAnother() async {
     final pathA = convertPath('$projectPath/lib/a.dart');
     final pathB = convertPath('$projectPath/lib/b.dart');
@@ -521,11 +521,11 @@
       ..wasExplicitlyOptedOut = false;
     dartfixListener.addSourceFileEdit(
         'test change',
-        Location(pathA, 10, 0, 1, 10),
+        Location(pathA, 10, 0, 1, 10, 1, 10),
         SourceFileEdit(pathA, 0, edits: [SourceEdit(10, 0, 'List args')]));
     dartfixListener.addSourceFileEdit(
         'test change',
-        Location(pathB, 10, 0, 1, 10),
+        Location(pathB, 10, 0, 1, 10, 1, 10),
         SourceFileEdit(pathB, 0, edits: [SourceEdit(10, 0, 'List args')]));
     var navigationTree =
         NavigationTreeRenderer(migrationInfo, state.pathMapper).render();
@@ -559,7 +559,7 @@
       ..wasExplicitlyOptedOut = true;
     dartfixListener.addSourceFileEdit(
         'remove DLV comment',
-        Location(path, 0, 14, 1, 1),
+        Location(path, 0, 14, 1, 1, 3, 1),
         SourceFileEdit(path, 0, edits: [SourceEdit(0, 14, '')]));
     var navigationTree =
         NavigationTreeRenderer(migrationInfo, state.pathMapper).render();
diff --git a/pkg/nnbd_migration/tool/codegen/extract_resource.dart b/pkg/nnbd_migration/tool/codegen/extract_resource.dart
new file mode 100644
index 0000000..3b60593
--- /dev/null
+++ b/pkg/nnbd_migration/tool/codegen/extract_resource.dart
@@ -0,0 +1,128 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for 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 script provides a quick way, via the command line, to extract one of the
+// resources encoded in the file lib/src/front_end/resources/resources.g.dart.
+
+import 'dart:convert';
+import 'dart:io';
+import 'dart:typed_data';
+
+import 'package:analyzer/dart/analysis/utilities.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:args/args.dart';
+import 'package:path/path.dart' as path;
+
+main(List<String> args) {
+  var argResults = argParser.parse(args);
+  if (argResults['help'] as bool) {
+    fail(null, showUsage: true);
+  }
+  if (argResults.rest.isNotEmpty) {
+    fail('Unexpected extra arguments', showUsage: true);
+  }
+  bool list = argResults['list'] as bool;
+  String path = argResults['path'] as String;
+  String resource = argResults['resource'] as String;
+  if (list && resource != null) {
+    fail('Only one of --resource and --list may be provided');
+  } else if (!list && resource == null) {
+    fail('Either --resource or --list must be provided');
+  }
+  var file = locateResourcesFile(path);
+  var parseResult =
+      parseString(content: file.readAsStringSync(), path: file.path);
+  final variableNameRegExp = RegExp(r'^_(.*)_base64$');
+  for (var declaration in parseResult.unit.declarations) {
+    if (declaration is TopLevelVariableDeclaration) {
+      for (var variable in declaration.variables.variables) {
+        if (variable.initializer == null) continue;
+        var match = variableNameRegExp.matchAsPrefix(variable.name.name);
+        if (match == null) continue;
+        var shortName = match.group(1);
+        if (list) {
+          stdout.writeln(shortName);
+        } else if (resource == shortName) {
+          stdout.add(decodeVariableDeclaration(variable));
+          return;
+        }
+      }
+    }
+  }
+  if (list) {
+    return;
+  } else {
+    fail('Resource $resource not found in ${file.path}');
+  }
+}
+
+final argParser = ArgParser()
+  ..addOption('resource',
+      abbr: 'r', valueHelp: 'RESOURCE', help: 'Extract resource RESOURCE')
+  ..addFlag('list',
+      negatable: false, abbr: 'l', help: 'List which resources are present')
+  ..addOption('path',
+      abbr: 'p',
+      valueHelp: 'PATH',
+      help:
+          'Search for resources.g.dart inside PATH rather than current working '
+          'directory')
+  ..addFlag('help', negatable: false, abbr: 'h');
+
+Uint8List decodeVariableDeclaration(VariableDeclaration variable) {
+  var initializer = variable.initializer as StringLiteral;
+  var stringValue = initializer.stringValue;
+  return base64.decode(stringValue.replaceAll('\n', '').trim());
+}
+
+void fail(String message, {bool showUsage = false}) {
+  if (message != null) {
+    stderr.writeln(message);
+  }
+  if (showUsage) {
+    stderr.writeln('''
+usage: dart pkg/nnbd_migration/tool/codegen/extract_resource.dart -r <resource>
+
+Reads the file `resources.g.dart` from the appropriate directory, extracts the
+embedded resource named `<resource>`, and prints it to standard out.
+''');
+    stderr.writeln(argParser.usage);
+  }
+  exit(1);
+}
+
+/// Tries to guess the location of `resources.g.dart` using optional [pathHint]
+/// as a starting point.
+File locateResourcesFile(String pathHint) {
+  pathHint ??= '.';
+  final pathParts =
+      'pkg/nnbd_migration/lib/src/front_end/resources/resources.g.dart'
+          .split('/');
+  var currentPath = path.normalize(pathHint);
+  while (true) {
+    for (int i = 0; i <= pathParts.length; i++) {
+      var pathToTry = path.normalize(path.join(
+          currentPath, path.joinAll(pathParts.sublist(pathParts.length - i))));
+      var file = File(pathToTry);
+      var type = file.statSync().type;
+      if (type == FileSystemEntityType.notFound && i == 0) {
+        fail('No such file or directory: $pathToTry');
+      }
+      if (type == FileSystemEntityType.link) {
+        type = File(file.resolveSymbolicLinksSync()).statSync().type;
+      }
+      if (type == FileSystemEntityType.file) {
+        return file;
+      }
+    }
+    if (currentPath == '.') {
+      currentPath = Directory.current.path;
+    }
+    var nextPath = path.dirname(currentPath);
+    if (nextPath == currentPath) {
+      fail('Could not find file `resources.g.dart` starting at $pathHint');
+    }
+    currentPath = nextPath;
+  }
+}
diff --git a/pkg/scrape/example/null_aware.dart b/pkg/scrape/example/null_aware.dart
index 392798e..4437bd2 100644
--- a/pkg/scrape/example/null_aware.dart
+++ b/pkg/scrape/example/null_aware.dart
@@ -3,7 +3,6 @@
 // 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:scrape/scrape.dart';
 
 void main(List<String> arguments) {
@@ -235,7 +234,7 @@
     }
 
     if (parent is BinaryExpression) {
-      recordType('Uncategorized ${parent}');
+      recordType('Uncategorized $parent');
       return;
     }
 
diff --git a/pkg/test_runner/bin/test_runner.dart b/pkg/test_runner/bin/test_runner.dart
index 7cb77ae..1c2d26a 100644
--- a/pkg/test_runner/bin/test_runner.dart
+++ b/pkg/test_runner/bin/test_runner.dart
@@ -37,6 +37,7 @@
     print(exception.message);
     exit(1);
   }
+
   if (configurations.isEmpty) return;
   await buildConfigurations(configurations);
   // Run all of the configured tests.
diff --git a/pkg/test_runner/lib/src/command_output.dart b/pkg/test_runner/lib/src/command_output.dart
index 4c953dd..09134bb 100644
--- a/pkg/test_runner/lib/src/command_output.dart
+++ b/pkg/test_runner/lib/src/command_output.dart
@@ -551,18 +551,57 @@
 class AnalysisCommandOutput extends CommandOutput with _StaticErrorOutput {
   static void parseErrors(String stderr, List<StaticError> errors,
       [List<StaticError> warnings]) {
-    for (var error in AnalyzerError.parseStderr(stderr)) {
-      var staticError = StaticError({ErrorSource.analyzer: error.errorCode},
-          line: error.line, column: error.column, length: error.length);
+    var jsonData = json.decode(stderr) as Map<String, dynamic>;
+    var version = jsonData['version'];
+    if (version != 1) {
+      DebugLogger.error('Unexpected analyzer JSON data version: $version');
+      throw UnimplementedError();
+    }
+    for (var diagnostic in jsonData['diagnostics'] as List<dynamic>) {
+      var diagnosticMap = diagnostic as Map<String, dynamic>;
+      var location = diagnosticMap['location'] as Map<String, dynamic>;
+      var file = location['file'] as String;
+      var type = diagnosticMap['type'] as String;
+      var code = (diagnosticMap['code'] as String).toUpperCase();
+      var staticError =
+          _decodeStaticError(ErrorSource.analyzer, '$type.$code', location);
+      var contextMessages = diagnosticMap['contextMessages'] as List<dynamic>;
+      for (var contextMessage in contextMessages ?? const []) {
+        var contextMessageMap = contextMessage as Map<String, dynamic>;
+        var contextLocation =
+            contextMessageMap['location'] as Map<String, dynamic>;
+        if (contextLocation['file'] == file) {
+          staticError.contextMessages.add(_decodeStaticError(
+              ErrorSource.context,
+              contextMessageMap['message'] as String,
+              contextLocation));
+        } else {
+          DebugLogger.warning(
+              "Context messages in other files not currently supported.");
+        }
+      }
 
-      if (error.severity == 'ERROR') {
+      var severity = diagnosticMap['severity'] as String;
+      if (severity == 'ERROR') {
         errors.add(staticError);
-      } else if (error.severity == 'WARNING') {
+      } else if (severity == 'WARNING') {
         warnings?.add(staticError);
       }
     }
   }
 
+  static StaticError _decodeStaticError(
+      ErrorSource errorSource, String message, Map<String, dynamic> location) {
+    var locationRange = location['range'] as Map<String, dynamic>;
+    var locationRangeStart = locationRange['start'] as Map<String, dynamic>;
+    var locationRangeEnd = locationRange['end'] as Map<String, dynamic>;
+    return StaticError(errorSource, message,
+        line: locationRangeStart['line'] as int,
+        column: locationRangeStart['column'] as int,
+        length: (locationRangeEnd['offset'] as int) -
+            (locationRangeStart['offset'] as int));
+  }
+
   AnalysisCommandOutput(
       Command command,
       int exitCode,
@@ -584,6 +623,23 @@
     if (hasTimedOut) return Expectation.timeout;
     if (hasNonUtf8) return Expectation.nonUtf8Error;
 
+    List<StaticError> errors;
+    try {
+      errors = this.errors;
+    } catch (_) {
+      // This can happen in at least two scenarios:
+      // - The analyzer output was too long so it got truncated (so the
+      //   resulting output was ill-formed).  See also
+      //   https://github.com/dart-lang/sdk/issues/44493.
+      // - The analyzer did not find a file to analyze at the specified
+      //   location, so it generated the output "No dart files found at
+      //   <path>.dart" (which is not valid JSON).  See
+      //   https://github.com/dart-lang/sdk/issues/45556.
+      // TODO(paulberry,rnystrom): remove this logic once the two above bugs are
+      // fixed.
+      return Expectation.crash;
+    }
+
     // If it's a static error test, validate the exact errors.
     if (testCase.testFile.isStaticErrorTest) {
       return _validateExpectedErrors(testCase);
@@ -628,6 +684,23 @@
     if (hasTimedOut) return Expectation.timeout;
     if (hasNonUtf8) return Expectation.nonUtf8Error;
 
+    List<StaticError> errors;
+    try {
+      errors = this.errors;
+    } catch (_) {
+      // This can happen in at least two scenarios:
+      // - The analyzer output was too long so it got truncated (so the
+      //   resulting output was ill-formed).  See also
+      //   https://github.com/dart-lang/sdk/issues/44493.
+      // - The analyzer did not find a file to analyze at the specified
+      //   location, so it generated the output "No dart files found at
+      //   <path>.dart" (which is not valid JSON).  See
+      //   https://github.com/dart-lang/sdk/issues/45556.
+      // TODO(paulberry,rnystrom): remove this logic once the two above bugs are
+      // fixed.
+      return Expectation.crash;
+    }
+
     // If it's a static error test, validate the exact errors.
     if (testCase.testFile.isStaticErrorTest) {
       return _validateExpectedErrors(testCase);
@@ -984,8 +1057,9 @@
   ///
   /// The test runner only validates the main error message, and not the
   /// suggested fixes, so we only parse the first line.
+  // TODO(rnystrom): Support validating context messages.
   static final _errorRegexp =
-      RegExp(r"^([^:]+):(\d+):(\d+):\nError: (.*)$", multiLine: true);
+      RegExp(r"^([^:]+):(\d+):(\d+):\n(Error): (.*)$", multiLine: true);
 
   Dart2jsCompilerCommandOutput(
       Command command,
@@ -1017,8 +1091,9 @@
   ///
   /// The test runner only validates the main error message, and not the
   /// suggested fixes, so we only parse the first line.
+  // TODO(rnystrom): Support validating context messages.
   static final _errorRegexp = RegExp(
-      r"^org-dartlang-app:/([^:]+):(\d+):(\d+): Error: (.*)$",
+      r"^org-dartlang-app:/([^:]+):(\d+):(\d+): (Error): (.*)$",
       multiLine: true);
 
   DevCompilerCommandOutput(
@@ -1252,36 +1327,22 @@
   static void parseErrors(
       String stdout, List<StaticError> errors, List<StaticError> warnings) {
     _StaticErrorOutput._parseCfeErrors(
-        ErrorSource.cfe, _errorRegexp, stdout, errors);
-    _StaticErrorOutput._parseCfeErrors(
-        ErrorSource.cfe, _warningRegexp, stdout, warnings);
+        ErrorSource.cfe, _errorRegexp, stdout, errors, warnings);
   }
 
-  /// Matches the first line of a Fasta error message. Fasta prints errors to
-  /// stdout that look like:
+  /// Matches the first line of a Fasta error, warning, or context message.
+  /// Fasta prints to stdout like:
   ///
   ///     tests/language_2/some_test.dart:7:21: Error: Some message.
   ///     Try fixing the code to be less bad.
   ///       var _ = <int>[if (1) 2];
   ///                    ^
   ///
-  /// The test runner only validates the main error message, and not the
-  /// suggested fixes, so we only parse the first line.
-  static final _errorRegexp =
-      RegExp(r"^([^:]+):(\d+):(\d+): Error: (.*)$", multiLine: true);
-
-  /// Matches the first line of a Fasta warning message. Fasta prints errors to
-  /// stdout that look like:
-  ///
-  ///     tests/language_2/some_test.dart:7:21: Warning: Some message.
-  ///     Try fixing the code to be less bad.
-  ///       var _ = <int>[if (1) 2];
-  ///                    ^
-  ///
-  /// The test runner only validates the main error message, and not the
-  /// suggested fixes, so we only parse the first line.
-  static final _warningRegexp =
-      RegExp(r"^([^:]+):(\d+):(\d+): Warning: (.*)$", multiLine: true);
+  /// The test runner only validates the first line of the message, and not the
+  /// suggested fixes.
+  static final _errorRegexp = RegExp(
+      r"^([^:]+):(\d+):(\d+): (Context|Error|Warning): (.*)$",
+      multiLine: true);
 
   FastaCommandOutput(
       Command command,
@@ -1310,13 +1371,35 @@
   /// Parses compile errors reported by CFE using the given [regExp] and adds
   /// them to [errors] as coming from [errorSource].
   static void _parseCfeErrors(ErrorSource errorSource, RegExp regExp,
-      String stdout, List<StaticError> errors) {
+      String stdout, List<StaticError> errors,
+      [List<StaticError> warnings]) {
+    StaticError previousError;
     for (var match in regExp.allMatches(stdout)) {
       var line = int.parse(match.group(2));
       var column = int.parse(match.group(3));
-      var message = match.group(4);
-      errors
-          .add(StaticError({errorSource: message}, line: line, column: column));
+      var severity = match.group(4);
+      var message = match.group(5);
+
+      var error = StaticError(
+          severity == "Context" ? ErrorSource.context : errorSource, message,
+          line: line, column: column);
+
+      if (severity == "Context") {
+        // Attach context messages to the preceding error/warning.
+        if (previousError == null) {
+          DebugLogger.error("Got context message in CFE output before "
+              "error to attach it to.");
+        } else {
+          previousError.contextMessages.add(error);
+        }
+      } else {
+        if (severity == "Error") {
+          errors.add(error);
+        } else {
+          warnings.add(error);
+        }
+        previousError = error;
+      }
     }
   }
 
@@ -1353,7 +1436,14 @@
     // Handle static error test output specially. We don't want to show the raw
     // stdout if we can give the user the parsed expectations instead.
     if (testCase.testFile.isStaticErrorTest && !hasCrashed && !hasTimedOut) {
-      _validateExpectedErrors(testCase, output);
+      try {
+        _validateExpectedErrors(testCase, output);
+      } catch (_) {
+        // In the event of a crash trying to compute errors, go ahead and give
+        // the raw output.
+        super.describe(testCase, progress, output);
+        return;
+      }
     }
 
     // Don't show the "raw" output unless something strange happened or the
@@ -1417,7 +1507,7 @@
     assert(errorSource != null);
 
     var expected = testCase.testFile.expectedErrors
-        .where((error) => error.hasError(errorSource));
+        .where((error) => error.source == errorSource);
 
     var validation = StaticError.validateExpectations(
       expected,
diff --git a/pkg/test_runner/lib/src/options.dart b/pkg/test_runner/lib/src/options.dart
index af07581a..b002c93 100644
--- a/pkg/test_runner/lib/src/options.dart
+++ b/pkg/test_runner/lib/src/options.dart
@@ -426,7 +426,7 @@
     if (arguments.contains("--help") || arguments.contains("-h")) {
       _printHelp(
           verbose: arguments.contains("--verbose") || arguments.contains("-v"));
-      return null;
+      return const [];
     }
 
     // Parse the command line arguments to a map.
@@ -563,12 +563,12 @@
 
     if (options.containsKey('find-configurations')) {
       findConfigurations(options);
-      return null;
+      return const [];
     }
 
     if (options.containsKey('list-configurations')) {
       listConfigurations(options);
-      return null;
+      return const [];
     }
 
     // If a named configuration was specified ensure no other options, which are
@@ -833,7 +833,7 @@
       // Expand architectures.
       var architectures = data["arch"] as String;
       if (architectures == "all") {
-        architectures = "ia32,x64,simarm,simarm64";
+        architectures = "ia32,x64,x64c,simarm,simarm64,simarm64c";
       }
 
       for (var architectureName in architectures.split(",")) {
diff --git a/pkg/test_runner/lib/src/static_error.dart b/pkg/test_runner/lib/src/static_error.dart
index 08104d7..8252dc5 100644
--- a/pkg/test_runner/lib/src/static_error.dart
+++ b/pkg/test_runner/lib/src/static_error.dart
@@ -11,6 +11,9 @@
   static const cfe = ErrorSource._("CFE");
   static const web = ErrorSource._("web");
 
+  /// Pseudo-front end for context messages.
+  static const context = ErrorSource._("context");
+
   /// All of the supported front ends.
   ///
   /// The order is significant here. In static error tests, error expectations
@@ -24,6 +27,8 @@
       if (source.marker == name) return source;
     }
 
+    if (name == "context") return context;
+
     return null;
   }
 
@@ -36,7 +41,7 @@
   const ErrorSource._(this.name);
 }
 
-/// Describes one or more static errors that should be reported at a specific
+/// Describes a single static error reported by a single front end at a specific
 /// location.
 ///
 /// These can be parsed from comments in [TestFile]s, in which case they
@@ -45,11 +50,6 @@
 /// produces the expected compile-time errors. This same class is also used for
 /// *reported* errors when parsing the output of a front end.
 ///
-/// Because there are multiple front ends that each report errors somewhat
-/// differently, each [StaticError] has a map to associate an error message
-/// with each front end. If there is no message for a given front end, it means
-/// the error is not reported by that front end.
-///
 /// For analyzer errors, the error "message" is actually the constant name for
 /// the error code, like "CompileTimeErrorCode.WRONG_TYPE".
 class StaticError implements Comparable<StaticError> {
@@ -98,85 +98,6 @@
   static List<StaticError> parseExpectations(String source) =>
       _ErrorExpectationParser(source)._parse();
 
-  /// Collapses overlapping [errors] into a shorter list of errors where
-  /// possible.
-  ///
-  /// Errors on the same location can be collapsed if none of them both define
-  /// a message for the same front end.
-  static List<StaticError> simplify(List<StaticError> errors) {
-    var result = errors.toList();
-    result.sort();
-
-    for (var i = 0; i < result.length - 1; i++) {
-      var a = result[i];
-
-      // Look for a later error we can merge with this one. Usually, it will be
-      // adjacent to this one, but if there are multiple errors with no length
-      // on the same location, those will all be next to each other and their
-      // merge targets will come later. This happens when CFE reports multiple
-      // errors at the same location (messages but no length) and analyzer does
-      // too (codes and lengths but no messages).
-      for (var j = i + 1; j < result.length; j++) {
-        var b = result[j];
-
-        // Position must be the same. If the position is different, we can
-        // stop looking because all same-position errors will be adjacent.
-        if (a.line != b.line) break;
-        if (a.column != b.column) break;
-
-        // If they both have lengths that are different, we can't discard that
-        // information.
-        if (a.length != null && b.length != null && a.length != b.length) {
-          continue;
-        }
-
-        // Can't lose any messages.
-        if (ErrorSource.all
-            .any((source) => a.hasError(source) && b.hasError(source))) {
-          continue;
-        }
-
-        // TODO(rnystrom): Now that there are more than two front ends, this
-        // isn't as smart as it could be. It could try to pack all of the
-        // messages in a given location into as few errors as possible by
-        // taking only the non-colliding messages from one error. But that's
-        // weird.
-        //
-        // A cleaner model is to have each StaticError represent a unique error
-        // location. It would have an open-ended list of every message that
-        // occurs at that location, across the various front-ends, including
-        // multiple messages for the same front end. But that would change how
-        // the existing static error tests look since something like:
-        //
-        //     // ^^^
-        //     // [cfe] Message 1.
-        //     // ^^^
-        //     // [cfe] Message 2.
-        //
-        // Would turn into:
-        //
-        //     // ^^^
-        //     // [cfe] Message 1.
-        //     // [cfe] Message 2.
-        //
-        // That's a good change to do, but should probably wait until after
-        // NNBD.
-
-        // Merge the two errors.
-        result[i] = StaticError({...a._errors, ...b._errors},
-            line: a.line, column: a.column, length: a.length ?? b.length);
-
-        // Continue trying to merge this merged error with more since multiple
-        // errors might collapse into a single one.
-        result.removeAt(j);
-        a = result[i];
-        j--;
-      }
-    }
-
-    return result;
-  }
-
   /// Determines whether all [actualErrors] match the given [expectedErrors].
   ///
   /// If they match, returns `null`. Otherwise returns a string describing the
@@ -185,88 +106,131 @@
   /// An expected error that is completely identical to an actual error is
   /// treated as a match. Everything else is a failure.
   ///
-  /// It treats line number as the "identity" of an error. So if there are two
-  /// errors on the same line that differ in other properties, it reports that
-  /// as a "wrong" error. Any expected error on a line containing no actual
-  /// error is reported as a "missing" error. Conversely, an actual error on a
-  /// line containing no expected error is an "unexpected" error.
+  /// It has a few heuristics to try to determine what the discrepancies mean,
+  /// which it applies in order:
   ///
-  /// By not treating the error's index in the list to be its identity, we
-  /// gracefully handle extra or missing errors without causing cascading
-  /// failures for later errors in the lists.
+  /// *   If it sees an actual errors with the same message but different
+  ///     location as expected ones, it considers those to be the same error
+  ///     but with the wrong location.
+  ///
+  /// *   If it sees an actual errors at the same location as expected ones,
+  ///     it considers those to be wrong messages.
+  ///
+  /// *   Otherwise, any remaining expected errors are considered missing
+  ///     errors and remaining actual errors are considered unexpected.
+  ///
+  /// Also describes any mismatches between the context messages in the expected
+  /// and actual errors.
   static String validateExpectations(Iterable<StaticError> expectedErrors,
       Iterable<StaticError> actualErrors) {
-    // Don't require the test or front end to output in any specific order.
-    var sortedExpected = expectedErrors.toList();
-    var sortedActual = actualErrors.toList();
-    sortedExpected.sort();
-    sortedActual.sort();
+    var expected = expectedErrors.toList();
+    var actual = actualErrors.toList();
+
+    // Put them in a deterministic order.
+    expected.sort();
+    actual.sort();
 
     var buffer = StringBuffer();
 
-    describeError(String adjective, StaticError error, String verb) {
-      buffer.writeln("$adjective static error at ${error.location}:");
+    // Pair up errors by location and message.
+    for (var i = 0; i < expected.length; i++) {
+      var matchedExpected = false;
 
-      for (var source in ErrorSource.all) {
-        var sourceError = error._errors[source];
-        if (sourceError == _unspecified) {
-          buffer.writeln("- $verb unspecified ${source.name} error.");
-        } else if (sourceError != null) {
-          buffer.writeln("- $verb ${source.name} error '$sourceError'.");
+      for (var j = 0; j < actual.length; j++) {
+        if (actual[j] == null) continue;
+
+        if (expected[i]._matchMessage(actual[j]) &&
+            expected[i]._matchLocation(actual[j])) {
+          // Report any mismatches in the context messages.
+          expected[i]._validateContext(actual[j], buffer);
+
+          actual[j] = null;
+          matchedExpected = true;
+
+          // If the expected error is unspecified, keep going so that it can
+          // consume multiple errors on the same line.
+          if (expected[i].isSpecified) break;
         }
       }
 
+      if (matchedExpected) expected[i] = null;
+    }
+
+    expected.removeWhere((error) => error == null);
+    actual.removeWhere((error) => error == null);
+
+    // If every error was paired up, and the contexts matched, we're done.
+    if (expected.isEmpty && actual.isEmpty && buffer.isEmpty) return null;
+
+    void fail(StaticError error, String label, String contextLabel,
+        [String secondary]) {
+      if (error.isContext) label = contextLabel;
+
+      if (error.isSpecified) {
+        buffer.writeln("- $label ${error.location}: ${error.message}");
+      } else {
+        label = label.replaceAll("error", "unspecified error");
+        buffer.writeln("- $label ${error.location}.");
+      }
+
+      if (secondary != null) buffer.writeln("  $secondary");
       buffer.writeln();
     }
 
-    var expectedIndex = 0;
-    var actualIndex = 0;
-    for (;
-        expectedIndex < sortedExpected.length &&
-            actualIndex < sortedActual.length;) {
-      var expected = sortedExpected[expectedIndex];
-      var actual = sortedActual[actualIndex];
+    // Look for matching messages, which means a wrong location.
+    for (var i = 0; i < expected.length; i++) {
+      if (expected[i] == null) continue;
 
-      var differences = expected.describeDifferences(actual);
-      if (differences == null) {
-        // Consume this actual error.
-        actualIndex++;
+      for (var j = 0; j < actual.length; j++) {
+        if (actual[j] == null) continue;
 
-        // Consume the expectation, unless it's an unspecified error that can
-        // match more actual errors.
-        if (expected.isSpecifiedFor(actual) ||
-            actualIndex == sortedActual.length ||
-            sortedActual[actualIndex].line != expected.line) {
-          expectedIndex++;
+        if (expected[i].message == actual[j].message) {
+          fail(expected[i], "Wrong error location", "Wrong context location",
+              expected[i]._locationError(actual[j]));
+          // Report any mismatches in the context messages.
+          expected[i]._validateContext(actual[j], buffer);
+
+          // Only report this mismatch once.
+          expected[i] = null;
+          actual[j] = null;
+          break;
         }
-      } else if (expected.line == actual.line) {
-        buffer.writeln("Wrong static error at ${expected.location}:");
-        for (var difference in differences) {
-          buffer.writeln("- $difference");
-        }
-        buffer.writeln();
-        expectedIndex++;
-        actualIndex++;
-      } else if (expected.line < actual.line) {
-        describeError("Missing", expected, "Expected");
-        expectedIndex++;
-      } else {
-        describeError("Unexpected", actual, "Had");
-        actualIndex++;
       }
     }
 
-    // Output any trailing expected or actual errors if the lengths of the
-    // lists differ.
-    for (; expectedIndex < sortedExpected.length; expectedIndex++) {
-      describeError("Missing", sortedExpected[expectedIndex], "Expected");
+    // Look for matching locations, which means a wrong message.
+    for (var i = 0; i < expected.length; i++) {
+      if (expected[i] == null) continue;
+      for (var j = 0; j < actual.length; j++) {
+        if (actual[j] == null) continue;
+
+        if (expected[i]._matchLocation(actual[j])) {
+          fail(actual[j], "Wrong message at", "Wrong context message at",
+              "Expected: ${expected[i].message}");
+          // Report any mismatches in the context messages.
+          expected[i]._validateContext(actual[j], buffer);
+
+          // Only report this mismatch once.
+          expected[i] = null;
+          actual[j] = null;
+          break;
+        }
+      }
     }
 
-    for (; actualIndex < sortedActual.length; actualIndex++) {
-      describeError("Unexpected", sortedActual[actualIndex], "Had");
+    // Any remaining expected errors are missing.
+    for (var i = 0; i < expected.length; i++) {
+      if (expected[i] == null) continue;
+      fail(expected[i], "Missing expected error at",
+          "Missing expected context message at");
     }
 
-    if (buffer.isEmpty) return null;
+    // Any remaining actual errors are unexpected.
+    for (var j = 0; j < actual.length; j++) {
+      if (actual[j] == null) continue;
+      fail(actual[j], "Unexpected error at", "Unexpected context message at");
+    }
+
     return buffer.toString().trimRight();
   }
 
@@ -281,27 +245,21 @@
   /// This is optional. The CFE only reports error location, but not length.
   final int length;
 
-  /// The error messages that should be or were reported by each front end.
-  final Map<ErrorSource, String> _errors;
+  /// The front end this error is for.
+  final ErrorSource source;
 
-  /// Whether this static error exists for [source].
-  bool hasError(ErrorSource source) => _errors.containsKey(source);
+  final String message;
 
-  /// The error for [source] or `null` if this error isn't expected to
-  /// reported by that source.
-  String errorFor(ErrorSource source) => _errors[source];
+  /// Additional context messages associated with this error.
+  final List<StaticError> contextMessages = [];
 
-  /// The zero-based index of the first line in the [TestFile] containing the
-  /// marker comments that define this error.
+  /// The zero-based numbers of the lines in the [TestFile] containing comments
+  /// that were parsed to produce this error.
   ///
-  /// If this error was not parsed from a file, this may be `null`.
-  final int markerStartLine;
-
-  /// The zero-based index of the last line in the [TestFile] containing the
-  /// marker comments that define this error, inclusive.
-  ///
-  /// If this error was not parsed from a file, this may be `null`.
-  final int markerEndLine;
+  /// This includes a line for the location comment, as well as lines for the
+  /// error message. Note that lines may not be contiguous and multiple errors
+  /// may share the same line number for a shared location marker.
+  final Set<int> sourceLines;
 
   /// Creates a new StaticError at the given location with the given expected
   /// error code and message.
@@ -312,19 +270,12 @@
   /// code or message be the special string "unspecified". When an unspecified
   /// error is tested, a front end is expected to report *some* error on that
   /// error's line, but it can be any location, error code, or message.
-  StaticError(Map<ErrorSource, String> errors,
-      {this.line,
-      this.column,
-      this.length,
-      this.markerStartLine,
-      this.markerEndLine})
-      : _errors = errors {
+  StaticError(this.source, this.message,
+      {this.line, this.column, this.length, Set<int> sourceLines})
+      : sourceLines = {...?sourceLines} {
     // Must have a location.
     assert(line != null);
     assert(column != null);
-
-    // Must have at least one piece of description.
-    assert(_errors.isNotEmpty);
   }
 
   /// A textual description of this error's location.
@@ -334,36 +285,49 @@
     return result;
   }
 
+  /// True if this error has a specific expected message and location.
+  ///
+  /// Otherwise, it is an "unspecified error", which means that as long as some
+  /// actual error is reported on this error's line, then the expectation is
+  /// met.
+  bool get isSpecified => message != _unspecified;
+
+  /// Whether this is a context message instead of an error.
+  bool get isContext => source == ErrorSource.context;
+
   /// Whether this error is only considered a warning on all front ends that
   /// report it.
   bool get isWarning {
-    var analyzer = _errors[ErrorSource.analyzer];
-    if (analyzer != null && !_analyzerWarningCodes.contains(analyzer)) {
-      return false;
+    switch (source) {
+      case ErrorSource.analyzer:
+        return _analyzerWarningCodes.contains(message);
+      case ErrorSource.cfe:
+        // TODO(42787): Once CFE starts reporting warnings, encode that in the
+        // message somehow and then look for it here.
+        return false;
+      case ErrorSource.web:
+        // TODO(rnystrom): If the web compilers report warnings, encode that in
+        // the message somehow and then look for it here.
+        return false;
     }
 
-    // TODO(42787): Once CFE starts reporting warnings, encode that in the
-    // message somehow and then look for it here.
-    if (hasError(ErrorSource.cfe)) return false;
-
-    // TODO(rnystrom): If the web compilers report warnings, encode that in the
-    // message somehow and then look for it here.
-    if (hasError(ErrorSource.web)) return false;
-
-    return true;
+    throw FallThroughError();
   }
 
   String toString() {
-    var result = "Error at $location";
+    var buffer = StringBuffer("StaticError(");
+    buffer.write("line: $line, column: $column");
+    if (length != null) buffer.write(", length: $length");
+    buffer.write(", message: '$message'");
 
-    for (var source in ErrorSource.all) {
-      var sourceError = _errors[source];
-      if (sourceError != null) {
-        result += "\n[${source.name.toLowerCase()}] $sourceError";
-      }
+    if (contextMessages.isNotEmpty) {
+      buffer.write(", context: [ ");
+      buffer.writeAll(contextMessages, ", ");
+      buffer.write(" ]");
     }
 
-    return result;
+    buffer.write(")");
+    return buffer.toString();
   }
 
   /// Orders errors primarily by location, then by other fields if needed.
@@ -377,92 +341,104 @@
     if (length != null && other.length == null) return -1;
     if (length != other.length) return length.compareTo(other.length);
 
-    for (var source in ErrorSource.all) {
-      var thisError = _errors[source] ?? "";
-      var otherError = other._errors[source] ?? "";
-      if (thisError != otherError) {
-        return thisError.compareTo(otherError);
-      }
+    if (source != other.source) {
+      return source.marker.compareTo(other.source.marker);
     }
 
-    return 0;
+    return message.compareTo(other.message);
   }
 
   @override
-  bool operator ==(other) => other is StaticError && compareTo(other) == 0;
+  bool operator ==(other) {
+    if (other is StaticError) {
+      if (compareTo(other) != 0) return false;
+
+      if (contextMessages.length != other.contextMessages.length) return false;
+      for (var i = 0; i < contextMessages.length; i++) {
+        if (contextMessages[i] != other.contextMessages[i]) return false;
+      }
+
+      return true;
+    }
+
+    return false;
+  }
 
   @override
   int get hashCode =>
       3 * line.hashCode +
       5 * column.hashCode +
       7 * (length ?? 0).hashCode +
-      11 * (_errors[ErrorSource.analyzer] ?? "").hashCode +
-      13 * (_errors[ErrorSource.cfe] ?? "").hashCode +
-      17 * (_errors[ErrorSource.web] ?? "").hashCode;
+      11 * source.hashCode +
+      13 * message.hashCode;
 
-  /// Whether this error expectation is a specified error for the front end
-  /// reported by [actual].
-  bool isSpecifiedFor(StaticError actual) {
-    assert(actual._errors.length == 1,
-        "Actual error should only have one source.");
-
-    for (var source in ErrorSource.all) {
-      if (actual.hasError(source)) {
-        return hasError(source) && _errors[source] != _unspecified;
-      }
-    }
-
-    return false;
+  /// Returns true if [actual]'s message matches this one.
+  ///
+  /// Takes unspecified errors into account.
+  bool _matchMessage(StaticError actual) {
+    return !isSpecified || message == actual.message;
   }
 
-  /// Compares this error expectation to [actual].
+  /// Returns true if [actual]'s location matches this one.
   ///
-  /// If this error correctly matches [actual], returns `null`. Otherwise
-  /// returns a list of strings describing the mismatch.
-  ///
-  /// Note that this does *not* check to see that [actual] matches the front
-  /// ends that this error expects. For example, if [actual] only reports an
-  /// analyzer error and this error only specifies a CFE error, this will still
-  /// report differences in location information. This method expects that error
-  /// expectations have already been filtered by platform so this will only be
-  /// called in cases where the platforms do match.
-  List<String> describeDifferences(StaticError actual) {
-    var differences = <String>[];
+  /// Takes into account unspecified errors and errors without lengths.
+  bool _matchLocation(StaticError actual) {
+    if (line != actual.line) return false;
+
+    // Ignore column and length for unspecified errors.
+    if (isSpecified) {
+      if (column != actual.column) return false;
+      if (actual.length != null && length != actual.length) return false;
+    }
+
+    return true;
+  }
+
+  /// Returns a string describing how this error's expected location differs
+  /// from [actual].
+  String _locationError(StaticError actual) {
+    var expectedMismatches = <String>[];
+    var actualMismatches = <String>[];
 
     if (line != actual.line) {
-      differences.add("Expected on line $line but was on ${actual.line}.");
+      expectedMismatches.add("line $line");
+      actualMismatches.add("line ${actual.line}");
     }
 
-    // If the error is unspecified on the front end being tested, the column
-    // and length can be any values.
-    if (isSpecifiedFor(actual)) {
+    // Ignore column and length for unspecified errors.
+    if (isSpecified) {
       if (column != actual.column) {
-        differences
-            .add("Expected on column $column but was on ${actual.column}.");
+        expectedMismatches.add("column $column");
+        actualMismatches.add("column ${actual.column}");
       }
 
-      // This error represents an expectation, so should have a length.
-      assert(length != null);
       if (actual.length != null && length != actual.length) {
-        differences.add("Expected length $length but was ${actual.length}.");
+        expectedMismatches.add("length $column");
+        actualMismatches.add("length ${actual.column}");
       }
     }
 
-    for (var source in ErrorSource.all) {
-      var error = _errors[source];
-      var actualError = actual._errors[source];
+    // Should only call this when the locations don't match.
+    assert(expectedMismatches.isNotEmpty);
 
-      if (error != null &&
-          error != _unspecified &&
-          actualError != null &&
-          error != actualError) {
-        differences.add("Expected ${source.name} error '$error' "
-            "but was '$actualError'.");
-      }
+    var expectedList = expectedMismatches.join(", ");
+    var actualList = actualMismatches.join(", ");
+    return "Expected $expectedList but was $actualList.";
+  }
+
+  /// Validates that this expected error's context messages match [actual]'s.
+  ///
+  /// Writes any mismatch errors to [buffer].
+  void _validateContext(StaticError actual, StringBuffer buffer) {
+    // If the expected error has no context, then ignore actual context
+    // messages.
+    if (contextMessages.isEmpty) return;
+
+    var result = validateExpectations(contextMessages, actual.contextMessages);
+    if (result != null) {
+      buffer.writeln(result);
+      buffer.writeln();
     }
-
-    if (differences.isNotEmpty) return differences;
-    return null;
   }
 }
 
@@ -490,7 +466,10 @@
       RegExp(r"^\s*//\s*\[\s*error line\s+(\d+)\s*,\s*column\s+(\d+)\s*\]\s*$");
 
   /// Matches the beginning of an error message, like `// [analyzer]`.
-  static final _errorMessageRegExp = RegExp(r"^\s*// \[(\w+)\]\s*(.*)");
+  ///
+  /// May have an optional number like `// [cfe 32]`.
+  static final _errorMessageRegExp =
+      RegExp(r"^\s*// \[(\w+)(\s+\d+)?\]\s*(.*)");
 
   /// An analyzer error code is a dotted identifier or the magic string
   /// "unspecified".
@@ -500,11 +479,24 @@
   /// are part of it.
   static final _errorMessageRestRegExp = RegExp(r"^\s*//\s*(.*)");
 
-  /// Matches the multitest marker and yields the preceding content.
-  final _stripMultitestRegExp = RegExp(r"(.*)//#");
-
   final List<String> _lines;
   final List<StaticError> _errors = [];
+
+  /// The parsed context messages.
+  ///
+  /// Once parsing is done, these are added to the errors that own them.
+  final List<StaticError> _contextMessages = [];
+
+  /// For errors that have a number associated with them, tracks that number.
+  ///
+  /// These are used after parsing to attach context messages to their errors.
+  ///
+  /// Note: if the same context message appears multiple times at the same
+  /// location, there will be distinct (non-identical) StaticError instances
+  /// that compare equal.  We use `Map.identity` to ensure that we can associate
+  /// each with its own context number.
+  final Map<StaticError, int> _errorNumbers = Map.identity();
+
   int _currentLine = 0;
 
   // One-based index of the last line that wasn't part of an error expectation.
@@ -513,6 +505,7 @@
   _ErrorExpectationParser(String source) : _lines = source.split("\n");
 
   List<StaticError> _parse() {
+    // Read all the lines.
     while (_canPeek(0)) {
       var sourceLine = _peek(0);
 
@@ -522,7 +515,7 @@
           _fail("An error expectation must follow some code.");
         }
 
-        _parseErrorMessages(
+        _parseErrors(
             line: _lastRealLine,
             column: sourceLine.indexOf("^") + 1,
             length: match.group(1).length);
@@ -532,7 +525,7 @@
 
       match = _explicitLocationAndLengthRegExp.firstMatch(sourceLine);
       if (match != null) {
-        _parseErrorMessages(
+        _parseErrors(
             line: int.parse(match.group(1)),
             column: int.parse(match.group(2)),
             length: int.parse(match.group(3)));
@@ -542,7 +535,7 @@
 
       match = _explicitLocationRegExp.firstMatch(sourceLine);
       if (match != null) {
-        _parseErrorMessages(
+        _parseErrors(
             line: int.parse(match.group(1)), column: int.parse(match.group(2)));
         _advance();
         continue;
@@ -552,25 +545,32 @@
       _advance();
     }
 
+    _attachContext();
     return _errors;
   }
 
-  /// Finishes parsing an error expectation after parsing the location.
-  void _parseErrorMessages({int line, int column, int length}) {
-    var errors = <ErrorSource, String>{};
+  /// Finishes parsing a series of error expectations after parsing a location.
+  void _parseErrors({int line, int column, int length}) {
+    var locationLine = _currentLine;
+    var parsedError = false;
 
-    var startLine = _currentLine;
-
+    // Allow errors for multiple front-ends to share the same location marker.
     while (_canPeek(1)) {
       var match = _errorMessageRegExp.firstMatch(_peek(1));
       if (match == null) break;
 
+      var number = match.group(2) != null ? int.parse(match.group(2)) : null;
+
       var sourceName = match.group(1);
       var source = ErrorSource.find(sourceName);
       if (source == null) _fail("Unknown front end '[$sourceName]'.");
+      if (source == ErrorSource.context && number == null) {
+        _fail("Context messages must have an error number.");
+      }
 
-      var message = match.group(2);
+      var message = match.group(3);
       _advance();
+      var sourceLines = {locationLine, _currentLine};
 
       // Consume as many additional error message lines as we find.
       while (_canPeek(1)) {
@@ -589,6 +589,7 @@
 
         message += "\n" + messageMatch.group(1);
         _advance();
+        sourceLines.add(_currentLine);
       }
 
       if (source == ErrorSource.analyzer &&
@@ -596,35 +597,81 @@
         _fail("An analyzer error expectation should be a dotted identifier.");
       }
 
-      if (errors.containsKey(source)) {
-        _fail("Already have an error for ${source.name}:\n${errors[source]}");
+      // Hack: If the error is CFE-only and the length is one, treat it as no
+      // length. The CFE does not output length information, and when the update
+      // tool writes a CFE-only error, it implicitly uses a length of one. Thus,
+      // when we parse back in a length one CFE error, we ignore the length so
+      // that the error round-trips correctly.
+      // TODO(rnystrom): Stop doing this when the CFE reports error lengths.
+      var errorLength = length;
+      if (errorLength == 1 && source == ErrorSource.cfe) {
+        errorLength = null;
       }
 
-      errors[source] = message;
+      var error = StaticError(source, message,
+          line: line,
+          column: column,
+          length: errorLength,
+          sourceLines: sourceLines);
+
+      if (number != null) {
+        // Make sure two errors don't claim the same number.
+        if (source != ErrorSource.context) {
+          var existingError = _errors.firstWhere(
+              (error) => _errorNumbers[error] == number,
+              orElse: () => null);
+          if (existingError != null) {
+            _fail("Already have an error with number $number.");
+          }
+        }
+
+        _errorNumbers[error] = number;
+      }
+
+      if (source == ErrorSource.context) {
+        _contextMessages.add(error);
+      } else {
+        _errors.add(error);
+      }
+
+      parsedError = true;
     }
 
-    if (errors.isEmpty) {
+    if (!parsedError) {
       _fail("An error expectation must specify at least one error message.");
     }
+  }
 
-    // Hack: If the error is CFE-only and the length is one, treat it as no
-    // length. The CFE does not output length information, and when the update
-    // tool writes a CFE-only error, it implicitly uses a length of one. Thus,
-    // when we parse back in a length one CFE error, we ignore the length so
-    // that the error round-trips correctly.
-    // TODO(rnystrom): Stop doing this when the CFE reports error lengths.
-    if (length == 1 &&
-        errors.length == 1 &&
-        errors.containsKey(ErrorSource.cfe)) {
-      length = null;
+  /// Attach context messages to their errors and validate that everything lines
+  /// up.
+  void _attachContext() {
+    for (var contextMessage in _contextMessages) {
+      var number = _errorNumbers[contextMessage];
+
+      var error = _errors.firstWhere((error) => _errorNumbers[error] == number,
+          orElse: () => null);
+      if (error == null) {
+        throw FormatException("No error with number $number for context "
+            "message '${contextMessage.message}'.");
+      }
+
+      error.contextMessages.add(contextMessage);
     }
 
-    _errors.add(StaticError(errors,
-        line: line,
-        column: column,
-        length: length,
-        markerStartLine: startLine,
-        markerEndLine: _currentLine));
+    // Make sure every numbered error does have some context, otherwise the
+    // number is pointless.
+    for (var error in _errors) {
+      var number = _errorNumbers[error];
+      if (number == null) continue;
+
+      var context = _contextMessages.firstWhere(
+          (context) => _errorNumbers[context] == number,
+          orElse: () => null);
+      if (context == null) {
+        throw FormatException("Missing context for numbered error $number "
+            "'${error.message}'.");
+      }
+    }
   }
 
   bool _canPeek(int offset) => _currentLine + offset < _lines.length;
@@ -637,9 +684,9 @@
     var line = _lines[_currentLine + offset];
 
     // Strip off any multitest marker.
-    var multitestMatch = _stripMultitestRegExp.firstMatch(line);
-    if (multitestMatch != null) {
-      line = multitestMatch.group(1).trimRight();
+    var index = line.indexOf("//#");
+    if (index != -1) {
+      line = line.substring(0, index).trimRight();
     }
 
     return line;
diff --git a/pkg/test_runner/lib/src/test_file.dart b/pkg/test_runner/lib/src/test_file.dart
index 01afcd9..7b92bc9 100644
--- a/pkg/test_runner/lib/src/test_file.dart
+++ b/pkg/test_runner/lib/src/test_file.dart
@@ -78,7 +78,7 @@
   /// These tests exist to validate that a Dart web compiler reports the right
   /// expected errors.
   bool get isWebStaticErrorTest =>
-      expectedErrors.any((error) => error.hasError(ErrorSource.web));
+      expectedErrors.any((error) => error.source == ErrorSource.web);
 
   /// If the tests has no static error expectations, or all of the expectations
   /// are warnings, then the test tests runtime semantics.
diff --git a/pkg/test_runner/lib/src/test_suite.dart b/pkg/test_runner/lib/src/test_suite.dart
index c27f66b..1f9253f 100644
--- a/pkg/test_runner/lib/src/test_suite.dart
+++ b/pkg/test_runner/lib/src/test_suite.dart
@@ -980,7 +980,7 @@
     }
     args.addAll(additionalOptions(testFile.path));
     if (configuration.compiler == Compiler.dart2analyzer) {
-      args.add('--format=machine');
+      args.add('--format=json');
       args.add('--no-hints');
     }
 
diff --git a/pkg/test_runner/lib/src/testing_servers.dart b/pkg/test_runner/lib/src/testing_servers.dart
index 5e9df68..984f83c 100644
--- a/pkg/test_runner/lib/src/testing_servers.dart
+++ b/pkg/test_runner/lib/src/testing_servers.dart
@@ -7,7 +7,6 @@
 import 'dart:io';
 
 import 'package:package_config/package_config.dart';
-
 import 'package:test_runner/src/configuration.dart';
 import 'package:test_runner/src/repository.dart';
 import 'package:test_runner/src/utils.dart';
@@ -343,7 +342,7 @@
       ]) {
         response.headers.set(header, content_header_value);
       }
-      if (const ["safari"].contains(runtime)) {
+      if (runtime == Runtime.safari) {
         response.headers.set("X-WebKit-CSP", content_header_value);
       }
     }
diff --git a/pkg/test_runner/lib/src/update_errors.dart b/pkg/test_runner/lib/src/update_errors.dart
index a961ea9a..7ef97fe 100644
--- a/pkg/test_runner/lib/src/update_errors.dart
+++ b/pkg/test_runner/lib/src/update_errors.dart
@@ -13,48 +13,66 @@
 /// for the given [errors].
 ///
 /// If [remove] is not `null`, then only removes existing errors for the given
-/// sources.
+/// sources. If [includeContext] is `true`, then includes context messages in
+/// the output. Otherwise discards them.
 String updateErrorExpectations(String source, List<StaticError> errors,
-    {Set<ErrorSource> remove}) {
+    {Set<ErrorSource> remove, bool includeContext = false}) {
   remove ??= {};
 
+  // Split the existing errors into kept and deleted lists.
   var existingErrors = StaticError.parseExpectations(source);
+  var keptErrors = <StaticError>[];
+  var removedErrors = <StaticError>[];
+  for (var error in existingErrors) {
+    if (remove.contains(error.source)) {
+      removedErrors.add(error);
+    } else {
+      keptErrors.add(error);
+    }
+  }
+
   var lines = source.split("\n");
 
   // Keep track of the indentation on any existing expectation markers. If
   // found, it will try to preserve that indentation.
   var indentation = <int, int>{};
 
-  // Remove existing markers that should be removed.
-  var preservedErrors = <StaticError>[];
+  // Remove all existing marker comments in the file, even for errors we are
+  // preserving. We will regenerate marker comments for those errors too so
+  // they can properly share location comments with new errors if needed.
+  void removeLine(int line) {
+    if (lines[line] == null) return;
+
+    indentation[line] = _countIndentation(lines[line]);
+
+    // Null the line instead of removing it so that line numbers in the
+    // reported errors are still correct.
+    lines[line] = null;
+  }
+
   for (var error in existingErrors) {
-    for (var i = error.markerStartLine; i <= error.markerEndLine; i++) {
-      indentation[i] = _countIndentation(lines[i]);
-
-      // Null the line instead of removing it so that line numbers in the
-      // reported errors are still correct.
-      lines[i] = null;
-    }
-
-    // Re-add errors for the portions we intend to preserve.
-    var keptErrors = {
-      for (var source in ErrorSource.all.toSet().difference(remove))
-        if (error.hasError(source)) source: error.errorFor(source)
-    };
-
-    if (keptErrors.isNotEmpty) {
-      preservedErrors.add(StaticError(keptErrors,
-          line: error.line, column: error.column, length: error.length));
+    error.sourceLines.forEach(removeLine);
+    for (var contextMessage in error.contextMessages) {
+      contextMessage.sourceLines.forEach(removeLine);
     }
   }
 
   // Merge the new errors with the preserved ones.
-  errors = StaticError.simplify([...errors, ...preservedErrors]);
+  errors = [...errors, ...keptErrors];
 
+  // Group errors by the line where they appear.
   var errorMap = <int, List<StaticError>>{};
   for (var error in errors) {
     // -1 to translate from one-based to zero-based index.
     errorMap.putIfAbsent(error.line - 1, () => []).add(error);
+
+    // Flatten out and include context messages.
+    if (includeContext) {
+      for (var context in error.contextMessages) {
+        // -1 to translate from one-based to zero-based index.
+        errorMap.putIfAbsent(context.line - 1, () => []).add(context);
+      }
+    }
   }
 
   // If there are multiple errors on the same line, order them
@@ -63,6 +81,9 @@
     errorList.sort();
   }
 
+  var errorNumbers = _numberErrors(errors);
+
+  // Rebuild the source file a line at a time.
   var previousIndent = 0;
   var codeLine = 1;
   var result = <String>[];
@@ -82,6 +103,10 @@
     // Add expectations for any errors reported on this line.
     var errorsHere = errorMap[i];
     if (errorsHere == null) continue;
+
+    var previousColumn = -1;
+    var previousLength = -1;
+
     for (var error in errorsHere) {
       // Try to indent the line nicely to match either the existing expectation
       // that is being regenerated, or, barring that, the previous line of code.
@@ -90,44 +115,55 @@
       // If the error is to the left of the indent and the "//", sacrifice the
       // indentation.
       if (error.column - 1 < indent + 2) indent = 0;
-
       var comment = (" " * indent) + "//";
 
-      // If the error can't fit in a line comment, or no source location is
-      // sepcified, use an explicit location.
-      if (error.column <= 2 || error.length == 0) {
-        if (error.length == null) {
-          result.add("$comment [error line $codeLine, column "
-              "${error.column}]");
+      // Write the location line, unless we already have an identical one. Allow
+      // sharing locations between errors with and without explicit lengths.
+      if (error.column != previousColumn ||
+          (previousLength != null &&
+              error.length != null &&
+              error.length != previousLength)) {
+        // If the error can't fit in a line comment, or no source location is
+        // sepcified, use an explicit location.
+        if (error.column <= 2 || error.length == 0) {
+          if (error.length == null) {
+            result.add("$comment [error line $codeLine, column "
+                "${error.column}]");
+          } else {
+            result.add("$comment [error line $codeLine, column "
+                "${error.column}, length ${error.length}]");
+          }
         } else {
-          result.add("$comment [error line $codeLine, column "
-              "${error.column}, length ${error.length}]");
+          var spacing = " " * (error.column - 1 - 2 - indent);
+          // A CFE-only error may not have a length, so treat it as length 1.
+          var carets = "^" * (error.length ?? 1);
+          result.add("$comment$spacing$carets");
         }
-      } else {
-        var spacing = " " * (error.column - 1 - 2 - indent);
-        // A CFE-only error may not have a length, so treat it as length 1.
-        var carets = "^" * (error.length ?? 1);
-        result.add("$comment$spacing$carets");
       }
 
-      for (var source in ErrorSource.all) {
-        var sourceError = error.errorFor(source);
-        if (sourceError == null) continue;
+      // If multiple errors share the same location, let them share a location
+      // marker.
+      previousColumn = error.column;
+      previousLength = error.length;
 
-        var errorLines = sourceError.split("\n");
-        result.add("$comment [${source.marker}] ${errorLines[0]}");
-        for (var errorLine in errorLines.skip(1)) {
-          result.add("$comment $errorLine");
-        }
+      var errorLines = error.message.split("\n");
+      var line = "$comment [${error.source.marker}";
+      if (includeContext && errorNumbers.containsKey(error)) {
+        line += " ${errorNumbers[error]}";
+      }
+      line += "] ${errorLines[0]}";
+      result.add(line);
+      for (var errorLine in errorLines.skip(1)) {
+        result.add("$comment $errorLine");
+      }
 
-        // If the very next line in the source is a line comment, it would
-        // become part of the inserted message. To prevent that, insert a blank
-        // line.
-        if (i < lines.length - 1 &&
-            lines[i + 1] != null &&
-            _lineCommentRegExp.hasMatch(lines[i + 1])) {
-          result.add("");
-        }
+      // If the very next line in the source is a line comment, it would
+      // become part of the inserted message. To prevent that, insert a blank
+      // line.
+      if (i < lines.length - 1 &&
+          lines[i + 1] != null &&
+          _lineCommentRegExp.hasMatch(lines[i + 1])) {
+        result.add("");
       }
     }
   }
@@ -135,6 +171,29 @@
   return result.join("\n");
 }
 
+/// Assigns unique numbers to all [errors] that have context messages, as well
+/// as their context messages.
+Map<StaticError, int> _numberErrors(List<StaticError> errors) {
+  // Note: if the same context message appears multiple times at the same
+  // location, there will be distinct (non-identical) StaticError instances
+  // that compare equal.  We use `Map.identity` to ensure that we can associate
+  // each with its own context number.
+  var result = Map<StaticError, int>.identity();
+  var number = 1;
+  for (var error in errors) {
+    if (error.contextMessages.isEmpty) continue;
+
+    result[error] = number;
+    for (var context in error.contextMessages) {
+      result[context] = number;
+    }
+
+    number++;
+  }
+
+  return result;
+}
+
 /// Returns the number of characters of leading spaces in [line].
 int _countIndentation(String line) {
   var match = _indentationRegExp.firstMatch(line);
diff --git a/pkg/test_runner/lib/test_runner.dart b/pkg/test_runner/lib/test_runner.dart
index c02d3e7..33f93ba 100644
--- a/pkg/test_runner/lib/test_runner.dart
+++ b/pkg/test_runner/lib/test_runner.dart
@@ -195,42 +195,50 @@
 /// Locates the build number of the [commit] on the [builder], or throws an
 /// exception if the builder hasn't built the commit.
 Future<BuildSearchResult> searchForBuild(String builder, String commit) async {
-  var requestUrl = Uri.parse(
-      "https://cr-buildbucket.appspot.com/_ah/api/buildbucket/v1/search"
-      "?bucket=luci.dart.ci.sandbox"
-      "&tag=builder%3A$builder"
-      "&tag=buildset%3Acommit%2Fgit%2F$commit"
-      "&fields=builds(status%2Ctags%2Curl)");
+  var requestBody = jsonEncode({
+    "fields": "builds.*.status,builds.*.number",
+    "predicate": {
+      "builder": {
+        "project": "dart",
+        "bucket": "ci.sandbox",
+        "builder": builder
+      },
+      "tags": [
+        {
+          "key": "buildset",
+          "value": "commit/gitiles/dart.googlesource.com/sdk/+/$commit"
+        }
+      ]
+    }
+  });
+  var requestUrl = Uri.https(
+      "cr-buildbucket.appspot.com", "prpc/buildbucket.v2.Builds/SearchBuilds");
   var client = HttpClient();
-  var request = await client.getUrl(requestUrl);
+  var request = await client.postUrl(requestUrl);
+  request.headers.add(HttpHeaders.acceptHeader, ContentType.json.mimeType);
+  request.headers.add(HttpHeaders.contentTypeHeader, ContentType.json.mimeType);
+  request.write(requestBody);
   var response = await request.close();
-  var object = await response
-      .cast<List<int>>()
-      .transform(const Utf8Decoder())
-      .transform(const JsonDecoder())
-      .first as Map<String, dynamic>;
+  var responseString = await const Utf8Decoder().bind(response).join();
   client.close();
+  // Remove XSSI protection prefix )]}'\n before parsing the response.
+  var object = jsonDecode(responseString.substring(5)) as Map<String, dynamic>;
   var builds = object["builds"] as List<dynamic>;
   if (builds == null || builds.isEmpty) {
     throw NoResultsForCommitException(
         "Builder $builder hasn't built commit $commit");
   }
   var build = builds.last;
-  var tags = (build["tags"] as List).cast<String>();
-  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 NoResultsForCommitException(
-        "Build $buildAddress isn't completed yet");
+  var buildNumber = build["number"] as int;
+  if (!{"SUCCESS", "FAILURE"}.contains(build["status"])) {
+    throw NoResultsForCommitException("Build $buildNumber isn't completed yet");
   }
   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");
+        "Build $buildNumber did not upload results");
   }
   return BuildSearchResult(buildNumber, commit);
 }
diff --git a/pkg/test_runner/test/static_error_test.dart b/pkg/test_runner/test/static_error_test.dart
index a3e9897..285e41d 100644
--- a/pkg/test_runner/test/static_error_test.dart
+++ b/pkg/test_runner/test/static_error_test.dart
@@ -9,74 +9,35 @@
 import 'utils.dart';
 
 void main() {
-  testHasError();
-  testErrorFor();
+  testProperties();
   testIsWarning();
-  testIsSpecifiedFor();
   testCompareTo();
-  testDescribeDifferences();
-  testSimplify();
   testValidate();
 }
 
-void testHasError() {
-  var analyzer =
-      makeError(line: 1, column: 2, length: 3, analyzerError: "E.CODE");
-  var cfe = makeError(line: 1, column: 2, length: 3, cfeError: "Error.");
-  var web = makeError(line: 1, column: 2, length: 3, webError: "Web.");
-  var all = makeError(
-      line: 1,
-      column: 2,
-      length: 3,
-      analyzerError: "E.CODE",
-      cfeError: "Error.",
-      webError: "Web.");
+void testProperties() {
+  var analyzer = StaticError(ErrorSource.analyzer, "E.CODE",
+      line: 1, column: 2, length: 3, sourceLines: {1, 3, 5});
+  Expect.equals(analyzer.source, ErrorSource.analyzer);
+  Expect.equals(analyzer.message, "E.CODE");
+  Expect.equals(analyzer.line, 1);
+  Expect.equals(analyzer.column, 2);
+  Expect.equals(analyzer.length, 3);
+  Expect.isTrue(analyzer.isSpecified);
+  Expect.setEquals({1, 3, 5}, analyzer.sourceLines);
 
-  Expect.isTrue(analyzer.hasError(ErrorSource.analyzer));
-  Expect.isFalse(analyzer.hasError(ErrorSource.cfe));
-  Expect.isFalse(analyzer.hasError(ErrorSource.web));
+  var cfe = StaticError(ErrorSource.cfe, "Error.", line: 4, column: 5);
+  Expect.equals(cfe.source, ErrorSource.cfe);
+  Expect.equals(cfe.message, "Error.");
+  Expect.equals(cfe.line, 4);
+  Expect.equals(cfe.column, 5);
+  Expect.isNull(cfe.length);
+  Expect.isTrue(cfe.isSpecified);
+  Expect.isTrue(cfe.sourceLines.isEmpty);
 
-  Expect.isFalse(cfe.hasError(ErrorSource.analyzer));
-  Expect.isTrue(cfe.hasError(ErrorSource.cfe));
-  Expect.isFalse(cfe.hasError(ErrorSource.web));
-
-  Expect.isFalse(web.hasError(ErrorSource.analyzer));
-  Expect.isFalse(web.hasError(ErrorSource.cfe));
-  Expect.isTrue(web.hasError(ErrorSource.web));
-
-  Expect.isTrue(all.hasError(ErrorSource.analyzer));
-  Expect.isTrue(all.hasError(ErrorSource.cfe));
-  Expect.isTrue(all.hasError(ErrorSource.web));
-}
-
-void testErrorFor() {
-  var analyzer =
-      makeError(line: 1, column: 2, length: 3, analyzerError: "E.CODE");
-  var cfe = makeError(line: 1, column: 2, length: 3, cfeError: "Error.");
-  var web = makeError(line: 1, column: 2, length: 3, webError: "Web.");
-  var all = makeError(
-      line: 1,
-      column: 2,
-      length: 3,
-      analyzerError: "E.CODE",
-      cfeError: "Error.",
-      webError: "Web.");
-
-  Expect.equals("E.CODE", analyzer.errorFor(ErrorSource.analyzer));
-  Expect.isNull(analyzer.errorFor(ErrorSource.cfe));
-  Expect.isNull(analyzer.errorFor(ErrorSource.web));
-
-  Expect.isNull(cfe.errorFor(ErrorSource.analyzer));
-  Expect.equals("Error.", cfe.errorFor(ErrorSource.cfe));
-  Expect.isNull(cfe.errorFor(ErrorSource.web));
-
-  Expect.isNull(web.errorFor(ErrorSource.analyzer));
-  Expect.isNull(web.errorFor(ErrorSource.cfe));
-  Expect.equals("Web.", web.errorFor(ErrorSource.web));
-
-  Expect.equals("E.CODE", all.errorFor(ErrorSource.analyzer));
-  Expect.equals("Error.", all.errorFor(ErrorSource.cfe));
-  Expect.equals("Web.", all.errorFor(ErrorSource.web));
+  var unspecified =
+      StaticError(ErrorSource.web, "unspecified", line: 1, column: 2);
+  Expect.isFalse(unspecified.isSpecified);
 }
 
 void testIsWarning() {
@@ -95,180 +56,29 @@
 
   // Web only.
   Expect.isFalse(makeError(webError: "Any error message.").isWarning);
-
-  // Multiple front ends.
-  Expect.isFalse(makeError(
-          analyzerError: "STATIC_WARNING.INVALID_OPTION",
-          cfeError: "Any error message.")
-      .isWarning);
-  Expect.isFalse(
-      makeError(cfeError: "Any error message.", webError: "Any error message.")
-          .isWarning);
-  Expect.isFalse(makeError(
-          analyzerError: "STATIC_WARNING.INVALID_OPTION",
-          webError: "Any error message.")
-      .isWarning);
-  Expect.isFalse(makeError(
-          analyzerError: "STATIC_WARNING.INVALID_OPTION",
-          cfeError: "Any error message.",
-          webError: "Any error message.")
-      .isWarning);
-}
-
-void testIsSpecifiedFor() {
-  var specifiedAll = makeError(
-      line: 1,
-      column: 2,
-      length: 3,
-      analyzerError: "ERR.CODE",
-      cfeError: "Message.",
-      webError: "Web.");
-  var unspecifiedAll = makeError(
-      line: 1,
-      column: 2,
-      length: 3,
-      analyzerError: "unspecified",
-      cfeError: "unspecified",
-      webError: "unspecified");
-  var specifiedAnalyzer = makeError(
-      line: 1,
-      column: 2,
-      length: 3,
-      analyzerError: "ERR.CODE",
-      cfeError: "unspecified",
-      webError: "unspecified");
-  var specifiedCfe = makeError(
-      line: 1,
-      column: 2,
-      length: 3,
-      analyzerError: "unspecified",
-      cfeError: "Message.",
-      webError: "unspecified");
-  var specifiedWeb = makeError(
-      line: 1,
-      column: 2,
-      length: 3,
-      analyzerError: "unspecified",
-      cfeError: "unspecified",
-      webError: "Web.");
-
-  var specifiedAnalyzerOnly =
-      makeError(line: 1, column: 2, length: 3, analyzerError: "ERR.CODE");
-  var specifiedCfeOnly =
-      makeError(line: 1, column: 2, length: 3, cfeError: "Message.");
-  var specifiedWebOnly =
-      makeError(line: 1, column: 2, length: 3, webError: "Web.");
-
-  var unspecifiedAnalyzerOnly =
-      makeError(line: 1, column: 2, length: 3, analyzerError: "unspecified");
-  var unspecifiedCfeOnly =
-      makeError(line: 1, column: 2, length: 3, cfeError: "unspecified");
-  var unspecifiedWebOnly =
-      makeError(line: 1, column: 2, length: 3, webError: "unspecified");
-
-  var analyzer =
-      makeError(line: 1, column: 2, length: 3, analyzerError: "E.CODE");
-  var cfe = makeError(line: 1, column: 2, length: 3, cfeError: "E.");
-  var web = makeError(line: 1, column: 2, length: 3, webError: "E.");
-
-  // isSpecifiedFor().
-  Expect.isTrue(specifiedAll.isSpecifiedFor(analyzer));
-  Expect.isTrue(specifiedAll.isSpecifiedFor(cfe));
-  Expect.isTrue(specifiedAll.isSpecifiedFor(web));
-
-  Expect.isFalse(unspecifiedAll.isSpecifiedFor(analyzer));
-  Expect.isFalse(unspecifiedAll.isSpecifiedFor(cfe));
-  Expect.isFalse(unspecifiedAll.isSpecifiedFor(web));
-
-  Expect.isTrue(specifiedAnalyzer.isSpecifiedFor(analyzer));
-  Expect.isFalse(specifiedAnalyzer.isSpecifiedFor(cfe));
-  Expect.isFalse(specifiedAnalyzer.isSpecifiedFor(web));
-
-  Expect.isFalse(specifiedCfe.isSpecifiedFor(analyzer));
-  Expect.isTrue(specifiedCfe.isSpecifiedFor(cfe));
-  Expect.isFalse(specifiedCfe.isSpecifiedFor(web));
-
-  Expect.isFalse(specifiedWeb.isSpecifiedFor(analyzer));
-  Expect.isFalse(specifiedWeb.isSpecifiedFor(cfe));
-  Expect.isTrue(specifiedWeb.isSpecifiedFor(web));
-
-  Expect.isTrue(specifiedAnalyzerOnly.isSpecifiedFor(analyzer));
-  Expect.isFalse(specifiedAnalyzerOnly.isSpecifiedFor(cfe));
-  Expect.isFalse(specifiedAnalyzerOnly.isSpecifiedFor(web));
-
-  Expect.isFalse(specifiedCfeOnly.isSpecifiedFor(analyzer));
-  Expect.isTrue(specifiedCfeOnly.isSpecifiedFor(cfe));
-  Expect.isFalse(specifiedCfeOnly.isSpecifiedFor(web));
-
-  Expect.isFalse(specifiedWebOnly.isSpecifiedFor(analyzer));
-  Expect.isFalse(specifiedWebOnly.isSpecifiedFor(cfe));
-  Expect.isTrue(specifiedWebOnly.isSpecifiedFor(web));
-
-  Expect.isFalse(unspecifiedAnalyzerOnly.isSpecifiedFor(analyzer));
-  Expect.isFalse(unspecifiedAnalyzerOnly.isSpecifiedFor(cfe));
-  Expect.isFalse(unspecifiedAnalyzerOnly.isSpecifiedFor(web));
-
-  Expect.isFalse(unspecifiedCfeOnly.isSpecifiedFor(analyzer));
-  Expect.isFalse(unspecifiedCfeOnly.isSpecifiedFor(cfe));
-  Expect.isFalse(unspecifiedCfeOnly.isSpecifiedFor(web));
-
-  Expect.isFalse(unspecifiedWebOnly.isSpecifiedFor(analyzer));
-  Expect.isFalse(unspecifiedWebOnly.isSpecifiedFor(cfe));
-  Expect.isFalse(unspecifiedWebOnly.isSpecifiedFor(web));
 }
 
 void testCompareTo() {
   var errors = [
     // Order by line.
-    makeError(
-        line: 1, column: 2, length: 2, analyzerError: "E.CODE", cfeError: "E."),
-    makeError(
-        line: 2, column: 1, length: 1, analyzerError: "E.CODE", cfeError: "E."),
+    makeError(line: 1, column: 2, length: 2, cfeError: "E."),
+    makeError(line: 2, column: 1, length: 1, cfeError: "E."),
 
     // Then column.
-    makeError(
-        line: 3, column: 1, length: 2, analyzerError: "E.CODE", cfeError: "E."),
-    makeError(
-        line: 3,
-        column: 2,
-        length: 1,
-        analyzerError: "Error.CODE",
-        cfeError: "E."),
+    makeError(line: 3, column: 1, length: 2, cfeError: "E."),
+    makeError(line: 3, column: 2, length: 1, cfeError: "E."),
 
     // Then length.
-    makeError(
-        line: 4, column: 1, length: 1, analyzerError: "Z.CODE", cfeError: "Z."),
-    makeError(
-        line: 4, column: 1, length: 2, analyzerError: "A.CODE", cfeError: "A."),
+    makeError(line: 4, column: 1, length: 1, cfeError: "Z."),
+    makeError(line: 4, column: 1, length: 2, cfeError: "A."),
 
-    // Then analyzer error.
-    makeError(line: 5, column: 1, length: 1, cfeError: "Z."),
-    makeError(
-        line: 5, column: 1, length: 1, analyzerError: "A.CODE", cfeError: "Z."),
-    makeError(
-        line: 5, column: 1, length: 1, analyzerError: "Z.CODE", cfeError: "Z."),
+    // Then source.
+    makeError(line: 5, column: 1, length: 1, analyzerError: "Z.CODE"),
+    makeError(line: 5, column: 1, length: 1, cfeError: "A."),
 
-    // Then CFE error.
-    makeError(line: 6, column: 1, length: 1, analyzerError: "E.CODE"),
-    makeError(
-        line: 6,
-        column: 1,
-        length: 1,
-        analyzerError: "E.CODE",
-        cfeError: "A.",
-        webError: "Z."),
-    makeError(
-        line: 6,
-        column: 1,
-        length: 1,
-        analyzerError: "E.CODE",
-        cfeError: "Z.",
-        webError: "A."),
-
-    // Then web error.
-    makeError(line: 7, column: 1, length: 1, cfeError: "E."),
-    makeError(line: 7, column: 1, length: 1, cfeError: "E.", webError: "A."),
-    makeError(line: 7, column: 1, length: 1, cfeError: "E.", webError: "Z."),
+    // Then message.
+    makeError(line: 6, column: 1, length: 1, cfeError: "A."),
+    makeError(line: 6, column: 1, length: 1, cfeError: "Z."),
   ];
 
   // Every pair of errors in the array should be ordered correctly.
@@ -281,347 +91,15 @@
   }
 }
 
-void testDescribeDifferences() {
-  var precise = makeError(
-      line: 2,
-      column: 3,
-      length: 4,
-      analyzerError: "Error.CODE",
-      cfeError: "Error message.",
-      webError: "Web error.");
-
-  // Perfect match.
-  expectNoDifferences(precise,
-      makeError(line: 2, column: 3, length: 4, analyzerError: "Error.CODE"));
-  expectNoDifferences(precise,
-      makeError(line: 2, column: 3, length: 4, cfeError: "Error message."));
-  expectNoDifferences(precise,
-      makeError(line: 2, column: 3, length: 4, webError: "Web error."));
-
-  // Ignore null analyzer error.
-  expectNoDifferences(
-      makeError(
-          line: 2,
-          column: 3,
-          length: 4,
-          cfeError: "Error message.",
-          webError: "Web error."),
-      makeError(line: 2, column: 3, length: 4, cfeError: "Error message."));
-
-  // Ignore null CFE error.
-  expectNoDifferences(
-      makeError(
-          line: 2,
-          column: 3,
-          length: 4,
-          analyzerError: "Error.CODE",
-          webError: "Web error."),
-      makeError(line: 2, column: 3, length: 4, analyzerError: "Error.CODE"));
-
-  // Ignore null web error.
-  expectNoDifferences(
-      makeError(
-          line: 2,
-          column: 3,
-          length: 4,
-          analyzerError: "Error.CODE",
-          cfeError: "Error message."),
-      makeError(line: 2, column: 3, length: 4, cfeError: "Error message."));
-
-  // Different line.
-  expectDifferences(precise,
-      makeError(line: 4, column: 3, length: 4, analyzerError: "Error.CODE"), """
-  Expected on line 2 but was on 4.
-  """);
-
-  // Different column.
-  expectDifferences(precise,
-      makeError(line: 2, column: 5, length: 4, cfeError: "Error message."), """
-  Expected on column 3 but was on 5.
-  """);
-
-  // Different length.
-  expectDifferences(precise,
-      makeError(line: 2, column: 3, length: 6, webError: "Web error."), """
-  Expected length 4 but was 6.
-  """);
-
-  // Different analyzer error.
-  expectDifferences(
-      precise,
-      makeError(line: 2, column: 3, length: 4, analyzerError: "Weird.ERROR"),
-      """
-  Expected analyzer error 'Error.CODE' but was 'Weird.ERROR'.
-  """);
-
-  // Different CFE error.
-  expectDifferences(precise,
-      makeError(line: 2, column: 3, length: 4, cfeError: "Funny story."), """
-  Expected CFE error 'Error message.' but was 'Funny story.'.
-  """);
-
-  // Different web error.
-  expectDifferences(precise,
-      makeError(line: 2, column: 3, length: 4, webError: "Funny story."), """
-  Expected web error 'Web error.' but was 'Funny story.'.
-  """);
-
-  // Multiple differences.
-  expectDifferences(
-      precise,
-      makeError(line: 4, column: 3, length: 6, analyzerError: "Weird.ERROR"),
-      """
-  Expected on line 2 but was on 4.
-  Expected length 4 but was 6.
-  Expected analyzer error 'Error.CODE' but was 'Weird.ERROR'.
-  """);
-
-  // Unspecified errors.
-  var unspecified = makeError(
-      line: 2,
-      column: 3,
-      length: 4,
-      analyzerError: "unspecified",
-      cfeError: "unspecified",
-      webError: "unspecified");
-  var specifiedAnalyzer = makeError(
-      line: 2,
-      column: 3,
-      length: 4,
-      analyzerError: "Error.CODE",
-      cfeError: "unspecified",
-      webError: "unspecified");
-  var specifiedCfe = makeError(
-      line: 2,
-      column: 3,
-      length: 4,
-      analyzerError: "unspecified",
-      cfeError: "Error message.",
-      webError: "unspecified");
-  var specifiedWeb = makeError(
-      line: 2,
-      column: 3,
-      length: 4,
-      analyzerError: "unspecified",
-      cfeError: "unspecified",
-      webError: "Web error.");
-
-  // Matches if line is right.
-  expectNoDifferences(unspecified,
-      makeError(line: 2, column: 3, length: 4, analyzerError: "Error.CODE"));
-
-  // Does not match if lines differ.
-  expectDifferences(unspecified,
-      makeError(line: 3, column: 3, length: 4, cfeError: "Error message."), """
-  Expected on line 2 but was on 3.
-  """);
-
-  // If error is specified on analyzer, must match fields when actual is
-  // analyzer error.
-  expectDifferences(
-      specifiedAnalyzer,
-      makeError(line: 2, column: 5, length: 6, analyzerError: "Weird.ERROR"),
-      """
-  Expected on column 3 but was on 5.
-  Expected length 4 but was 6.
-  Expected analyzer error 'Error.CODE' but was 'Weird.ERROR'.
-  """);
-  expectNoDifferences(specifiedAnalyzer,
-      makeError(line: 2, column: 3, length: 4, analyzerError: "Error.CODE"));
-
-  // If error is specified on CFE, must match fields when actual is
-  // CFE error.
-  expectDifferences(
-      specifiedCfe,
-      makeError(line: 2, column: 5, length: 6, cfeError: "Different message."),
-      """
-  Expected on column 3 but was on 5.
-  Expected length 4 but was 6.
-  Expected CFE error 'Error message.' but was 'Different message.'.
-  """);
-  expectNoDifferences(specifiedCfe,
-      makeError(line: 2, column: 3, length: 4, cfeError: "Error message."));
-
-  // If error is specified on web, must match fields when actual is web error.
-  expectDifferences(
-      specifiedWeb,
-      makeError(line: 2, column: 5, length: 6, webError: "Different message."),
-      """
-  Expected on column 3 but was on 5.
-  Expected length 4 but was 6.
-  Expected web error 'Web error.' but was 'Different message.'.
-  """);
-  expectNoDifferences(specifiedWeb,
-      makeError(line: 2, column: 3, length: 4, webError: "Web error."));
-}
-
-void testSimplify() {
-  // Merges errors if each has only one error.
-  expectSimplify([
-    makeError(line: 1, column: 2, length: 3, analyzerError: "Weird.ERROR"),
-    makeError(line: 1, column: 2, length: 3, cfeError: "Message."),
-    makeError(line: 1, column: 2, length: 3, webError: "Web.")
-  ], [
-    makeError(
-        line: 1,
-        column: 2,
-        length: 3,
-        analyzerError: "Weird.ERROR",
-        cfeError: "Message.",
-        webError: "Web.")
-  ]);
-
-  // Merges if length is null.
-  expectSimplify([
-    makeError(line: 1, column: 1, analyzerError: "A.ERR"),
-    makeError(line: 1, column: 1, length: 3, cfeError: "A."),
-    makeError(line: 2, column: 1, length: 4, analyzerError: "B.ERR"),
-    makeError(line: 2, column: 1, webError: "B."),
-    makeError(line: 3, column: 1, analyzerError: "C.ERR"),
-    makeError(line: 3, column: 1, cfeError: "C."),
-  ], [
-    makeError(
-        line: 1, column: 1, length: 3, analyzerError: "A.ERR", cfeError: "A."),
-    makeError(
-        line: 2, column: 1, length: 4, analyzerError: "B.ERR", webError: "B."),
-    makeError(line: 3, column: 1, analyzerError: "C.ERR", cfeError: "C."),
-  ]);
-
-  // Merges multiple errors with no length with errors that have length.
-  expectSimplify([
-    makeError(line: 1, column: 2, length: 3, analyzerError: "ERROR.A"),
-    makeError(line: 1, column: 4, length: 3, analyzerError: "ERROR.C"),
-    makeError(line: 1, column: 2, length: 5, analyzerError: "ERROR.B"),
-    makeError(line: 1, column: 2, cfeError: "One."),
-    makeError(line: 1, column: 4, cfeError: "Three."),
-    makeError(line: 1, column: 2, cfeError: "Two."),
-    makeError(line: 1, column: 2, webError: "Web 1."),
-    makeError(line: 1, column: 2, webError: "Web 2."),
-  ], [
-    makeError(
-        line: 1,
-        column: 2,
-        length: 3,
-        analyzerError: "ERROR.A",
-        cfeError: "One.",
-        webError: "Web 1."),
-    makeError(
-        line: 1,
-        column: 2,
-        length: 5,
-        analyzerError: "ERROR.B",
-        cfeError: "Two.",
-        webError: "Web 2."),
-    makeError(
-        line: 1,
-        column: 4,
-        length: 3,
-        analyzerError: "ERROR.C",
-        cfeError: "Three."),
-  ]);
-
-  // Merges even if not adjacent in input array.
-  expectSimplify([
-    makeError(line: 1, column: 2, length: 3, analyzerError: "Some.ERROR"),
-    makeError(line: 10, column: 2, length: 3, analyzerError: "Other.ERROR"),
-    makeError(line: 1, column: 2, length: 3, cfeError: "Message."),
-    makeError(line: 10, column: 2, length: 3, webError: "Web two."),
-    makeError(line: 1, column: 2, length: 3, webError: "Web."),
-  ], [
-    makeError(
-        line: 1,
-        column: 2,
-        length: 3,
-        analyzerError: "Some.ERROR",
-        cfeError: "Message.",
-        webError: "Web."),
-    makeError(
-        line: 10,
-        column: 2,
-        length: 3,
-        analyzerError: "Other.ERROR",
-        webError: "Web two.")
-  ]);
-
-  // Does not merge if positions differ.
-  expectSimplify([
-    makeError(line: 1, column: 1, length: 1, analyzerError: "A.ERR"),
-    makeError(line: 2, column: 1, length: 1, cfeError: "A."),
-  ], [
-    makeError(line: 1, column: 1, length: 1, analyzerError: "A.ERR"),
-    makeError(line: 2, column: 1, length: 1, cfeError: "A."),
-  ]);
-  expectSimplify([
-    makeError(line: 1, column: 1, length: 1, analyzerError: "A.ERR"),
-    makeError(line: 1, column: 2, length: 1, webError: "A."),
-  ], [
-    makeError(line: 1, column: 1, length: 1, analyzerError: "A.ERR"),
-    makeError(line: 1, column: 2, length: 1, webError: "A."),
-  ]);
-  expectSimplify([
-    makeError(line: 1, column: 1, length: 1, cfeError: "A."),
-    makeError(line: 1, column: 1, length: 2, webError: "W."),
-  ], [
-    makeError(line: 1, column: 1, length: 1, cfeError: "A."),
-    makeError(line: 1, column: 1, length: 2, webError: "W."),
-  ]);
-
-  // Does not merge if it would lose a message.
-  expectSimplify([
-    makeError(line: 1, column: 1, length: 1, analyzerError: "ERR.ONE"),
-    makeError(line: 1, column: 1, length: 1, analyzerError: "ERR.TWO"),
-    makeError(line: 2, column: 1, length: 1, cfeError: "One."),
-    makeError(line: 2, column: 1, length: 1, cfeError: "Two."),
-    makeError(line: 3, column: 1, length: 1, webError: "One."),
-    makeError(line: 3, column: 1, length: 1, webError: "Two."),
-  ], [
-    makeError(line: 1, column: 1, length: 1, analyzerError: "ERR.ONE"),
-    makeError(line: 1, column: 1, length: 1, analyzerError: "ERR.TWO"),
-    makeError(line: 2, column: 1, length: 1, cfeError: "One."),
-    makeError(line: 2, column: 1, length: 1, cfeError: "Two."),
-    makeError(line: 3, column: 1, length: 1, webError: "One."),
-    makeError(line: 3, column: 1, length: 1, webError: "Two."),
-  ]);
-
-  // Orders output.
-  expectSimplify([
-    makeError(line: 2, column: 1, length: 1, cfeError: "Two."),
-    makeError(line: 3, column: 1, length: 1, cfeError: "Three."),
-    makeError(line: 1, column: 1, length: 1, cfeError: "One."),
-  ], [
-    makeError(line: 1, column: 1, length: 1, cfeError: "One."),
-    makeError(line: 2, column: 1, length: 1, cfeError: "Two."),
-    makeError(line: 3, column: 1, length: 1, cfeError: "Three."),
-  ]);
-}
-
 void testValidate() {
   // No errors.
   expectValidate([], [], null);
 
   // Same errors.
   expectValidate([
-    makeError(
-        line: 1,
-        column: 2,
-        length: 3,
-        analyzerError: "ERR.A",
-        cfeError: "One.",
-        webError: "Web 1."),
-    makeError(
-        line: 2,
-        column: 2,
-        length: 3,
-        analyzerError: "ERR.B",
-        cfeError: "Two.",
-        webError: "Web 2."),
-    makeError(
-        line: 3,
-        column: 2,
-        length: 3,
-        analyzerError: "ERR.C",
-        cfeError: "Tres.",
-        webError: "Web 3."),
+    makeError(line: 1, column: 2, length: 3, analyzerError: "ERR.A"),
+    makeError(line: 2, column: 2, length: 3, analyzerError: "ERR.B"),
+    makeError(line: 3, column: 2, length: 3, analyzerError: "ERR.C"),
   ], [
     // Order doesn't matter.
     makeError(line: 3, column: 2, length: 3, analyzerError: "ERR.C"),
@@ -629,35 +107,6 @@
     makeError(line: 2, column: 2, length: 3, analyzerError: "ERR.B"),
   ], null);
 
-  // Ignore fields that aren't in actual errors.
-  expectValidate([
-    makeError(
-        line: 1,
-        column: 2,
-        length: 3,
-        analyzerError: "ERR.A",
-        cfeError: "One.",
-        webError: "Web 1."),
-    makeError(
-        line: 2,
-        column: 2,
-        length: 3,
-        analyzerError: "ERR.B",
-        cfeError: "Two.",
-        webError: "Web 2."),
-    makeError(
-        line: 3,
-        column: 2,
-        length: 3,
-        analyzerError: "ERR.C",
-        cfeError: "Tres.",
-        webError: "Web 3."),
-  ], [
-    makeError(line: 1, column: 2, cfeError: "One."),
-    makeError(line: 2, column: 2, length: 3, cfeError: "Two."),
-    makeError(line: 3, column: 2, length: 3, cfeError: "Tres."),
-  ], null);
-
   // Catches differences in any field.
   expectValidate([
     makeError(line: 1, column: 2, length: 3, analyzerError: "ERR.A"),
@@ -668,52 +117,36 @@
     makeError(line: 2, column: 2, length: 9, analyzerError: "ERR.B"),
     makeError(line: 3, column: 2, length: 3, analyzerError: "ERR.Z"),
   ], """
-Wrong static error at line 1, column 2, length 3:
-- Expected on column 2 but was on 9.
+- Wrong error location line 1, column 2, length 3: ERR.A
+  Expected column 2 but was column 9.
 
-Wrong static error at line 2, column 2, length 3:
-- Expected length 3 but was 9.
+- Wrong error location line 2, column 2, length 3: ERR.B
+  Expected length 2 but was length 2.
 
-Wrong static error at line 3, column 2, length 3:
-- Expected analyzer error 'ERR.C' but was 'ERR.Z'.""");
+- Wrong message at line 3, column 2, length 3: ERR.Z
+  Expected: ERR.C""");
 
   expectValidate([
     makeError(line: 4, column: 2, length: 3, cfeError: "Four."),
   ], [
     makeError(line: 4, column: 2, length: 3, cfeError: "Zzz."),
   ], """
-Wrong static error at line 4, column 2, length 3:
-- Expected CFE error 'Four.' but was 'Zzz.'.""");
+- Wrong message at line 4, column 2, length 3: Zzz.
+  Expected: Four.""");
 
   expectValidate([
     makeError(line: 5, column: 2, length: 3, webError: "Web 5."),
   ], [
     makeError(line: 5, column: 2, length: 3, webError: "Web Z."),
   ], """
-Wrong static error at line 5, column 2, length 3:
-- Expected web error 'Web 5.' but was 'Web Z.'.""");
+- Wrong message at line 5, column 2, length 3: Web Z.
+  Expected: Web 5.""");
 
   // Unexpected errors.
   expectValidate([
-    makeError(
-        line: 2,
-        column: 2,
-        length: 3,
-        analyzerError: "ERR.A",
-        cfeError: "One."),
-    makeError(
-        line: 4,
-        column: 2,
-        length: 3,
-        analyzerError: "ERR.B",
-        cfeError: "Two.",
-        webError: "Web 2."),
-    makeError(
-        line: 6,
-        column: 2,
-        length: 3,
-        analyzerError: "ERR.C",
-        cfeError: "Tres."),
+    makeError(line: 2, column: 2, length: 3, cfeError: "One."),
+    makeError(line: 4, column: 2, length: 3, cfeError: "Two."),
+    makeError(line: 6, column: 2, length: 3, cfeError: "Tres."),
   ], [
     makeError(line: 1, column: 2, length: 3, cfeError: "1."),
     makeError(line: 2, column: 2, length: 3, cfeError: "One."),
@@ -723,17 +156,13 @@
     makeError(line: 6, column: 2, length: 3, cfeError: "Tres."),
     makeError(line: 7, column: 2, length: 3, cfeError: "7."),
   ], """
-Unexpected static error at line 1, column 2, length 3:
-- Had CFE error '1.'.
+- Unexpected error at line 1, column 2, length 3: 1.
 
-Unexpected static error at line 3, column 2, length 3:
-- Had CFE error '3.'.
+- Unexpected error at line 3, column 2, length 3: 3.
 
-Unexpected static error at line 5, column 2, length 3:
-- Had CFE error '5.'.
+- Unexpected error at line 5, column 2, length 3: 5.
 
-Unexpected static error at line 7, column 2, length 3:
-- Had CFE error '7.'.""");
+- Unexpected error at line 7, column 2, length 3: 7.""");
 
   // Missing errors.
   expectValidate([
@@ -746,14 +175,11 @@
     makeError(line: 2, column: 2, length: 3, analyzerError: "ERR.B"),
     makeError(line: 4, column: 2, length: 3, analyzerError: "ERR.D"),
   ], """
-Missing static error at line 1, column 2, length 3:
-- Expected analyzer error 'ERR.A'.
+- Missing expected error at line 1, column 2, length 3: ERR.A
 
-Missing static error at line 3, column 2, length 3:
-- Expected analyzer error 'ERR.C'.
+- Missing expected error at line 3, column 2, length 3: ERR.C
 
-Missing static error at line 5, column 2, length 3:
-- Expected analyzer error 'ERR.E'.""");
+- Missing expected error at line 5, column 2, length 3: ERR.E""");
 
   // Unspecified errors.
   expectValidate([
@@ -768,161 +194,133 @@
     // Unexpected.
     makeError(line: 9, column: 9, length: 3, cfeError: "Actual 2."),
   ], """
-Missing static error at line 2, column 2, length 3:
-- Expected unspecified CFE error.
+- Missing expected unspecified error at line 2, column 2, length 3.
 
-Unexpected static error at line 9, column 9, length 3:
-- Had CFE error 'Actual 2.'.""");
+- Unexpected error at line 9, column 9, length 3: Actual 2.""");
 
   // Unspecified errors can match multiple errors on the same line.
-  var actualAnalyzer = [
+  expectValidate([
+    makeError(line: 1, column: 2, length: 3, analyzerError: "unspecified"),
+  ], [
     makeError(line: 1, column: 1, length: 3, analyzerError: "ERROR.CODE1"),
     makeError(line: 1, column: 2, length: 3, analyzerError: "ERROR.CODE2"),
     makeError(line: 1, column: 3, length: 3, analyzerError: "ERROR.CODE3"),
-  ];
-
-  var actualCfe = [
-    makeError(line: 1, column: 1, length: 3, cfeError: "Actual 1."),
-    makeError(line: 1, column: 2, length: 3, cfeError: "Actual 2."),
-    makeError(line: 1, column: 3, length: 3, cfeError: "Actual 3."),
-  ];
-
-  var actualWeb = [
-    makeError(line: 1, column: 1, length: 3, webError: "Web 1."),
-    makeError(line: 1, column: 2, length: 3, webError: "Web 2."),
-    makeError(line: 1, column: 3, length: 3, webError: "Web 3."),
-  ];
-
-  // Unspecified error specific to one front end.
-  expectValidate([
-    makeError(line: 1, column: 2, length: 3, analyzerError: "unspecified"),
-  ], actualAnalyzer, null);
+  ], null);
 
   expectValidate([
     makeError(line: 1, column: 2, length: 3, cfeError: "unspecified"),
-  ], actualCfe, null);
+  ], [
+    makeError(line: 1, column: 1, length: 3, cfeError: "Actual 1."),
+    makeError(line: 1, column: 2, length: 3, cfeError: "Actual 2."),
+    makeError(line: 1, column: 3, length: 3, cfeError: "Actual 3."),
+  ], null);
 
   expectValidate([
     makeError(line: 1, column: 2, length: 3, webError: "unspecified"),
-  ], actualWeb, null);
+  ], [
+    makeError(line: 1, column: 1, length: 3, webError: "Web 1."),
+    makeError(line: 1, column: 2, length: 3, webError: "Web 2."),
+    makeError(line: 1, column: 3, length: 3, webError: "Web 3."),
+  ], null);
 
-  // Unspecified error on multiple front ends.
+  // If expectation has context, actual must match it.
   expectValidate([
-    makeError(
-        line: 1,
-        column: 2,
-        length: 3,
-        analyzerError: "unspecified",
-        cfeError: "unspecified"),
-  ], actualAnalyzer, null);
+    makeError(line: 1, column: 2, length: 3, cfeError: "Error.", context: [
+      makeError(line: 4, column: 5, length: 6, contextError: "Context A."),
+      makeError(line: 7, column: 8, length: 9, contextError: "Context B."),
+    ]),
+  ], [
+    makeError(line: 1, column: 2, length: 3, cfeError: "Error.", context: [
+      makeError(line: 4, column: 5, length: 6, contextError: "Context A."),
+      makeError(line: 7, column: 8, length: 9, contextError: "Context B."),
+    ]),
+  ], null);
 
+  // Actual context is different.
   expectValidate([
-    makeError(
-        line: 1,
-        column: 2,
-        length: 3,
-        cfeError: "unspecified",
-        webError: "unspecified"),
-  ], actualCfe, null);
+    makeError(line: 1, column: 2, length: 3, cfeError: "Error.", context: [
+      makeError(line: 4, column: 5, length: 6, contextError: "Context A."),
+    ]),
+  ], [
+    makeError(line: 1, column: 2, length: 3, cfeError: "Error.", context: [
+      makeError(line: 4, column: 5, length: 6, contextError: "Context Z."),
+    ]),
+  ], """
+- Wrong context message at line 4, column 5, length 6: Context Z.
+  Expected: Context A.""");
 
+  // Missing some actual context.
   expectValidate([
-    makeError(
-        line: 1,
-        column: 2,
-        length: 3,
-        analyzerError: "unspecified",
-        webError: "unspecified"),
-  ], actualWeb, null);
+    makeError(line: 1, column: 2, length: 3, cfeError: "Error.", context: [
+      makeError(line: 4, column: 5, length: 6, contextError: "Context A."),
+      makeError(line: 7, column: 8, length: 9, contextError: "Context B."),
+    ]),
+  ], [
+    makeError(line: 1, column: 2, length: 3, cfeError: "Error.", context: [
+      makeError(line: 7, column: 8, length: 9, contextError: "Context B."),
+    ]),
+  ], """
+- Missing expected context message at line 4, column 5, length 6: Context A.""");
 
+  // Missing all actual context.
   expectValidate([
-    makeError(
-        line: 1,
-        column: 2,
-        length: 3,
-        analyzerError: "unspecified",
-        cfeError: "unspecified",
-        webError: "unspecified"),
-  ], actualAnalyzer, null);
+    makeError(line: 1, column: 2, length: 3, cfeError: "Error.", context: [
+      makeError(line: 4, column: 5, length: 6, contextError: "Context A."),
+      makeError(line: 7, column: 8, length: 9, contextError: "Context B."),
+    ]),
+  ], [
+    makeError(line: 1, column: 2, length: 3, cfeError: "Error."),
+  ], """
+- Missing expected context message at line 4, column 5, length 6: Context A.
 
-  // Specified on one, unspecified on another, no error at all on the third.
-  var specifiedAnalyzer = [
-    makeError(
-        line: 1,
-        column: 1,
-        length: 3,
-        analyzerError: "ERROR.CODE1",
-        cfeError: "unspecified")
-  ];
+- Missing expected context message at line 7, column 8, length 9: Context B.""");
 
-  var specifiedCfe = [
-    makeError(
-        line: 1,
-        column: 1,
-        length: 3,
-        cfeError: "Actual 1.",
-        webError: "unspecified")
-  ];
+  // Unexpected extra actual context.
+  expectValidate([
+    makeError(line: 1, column: 2, length: 3, cfeError: "Error.", context: [
+      makeError(line: 4, column: 5, length: 6, contextError: "Context A."),
+    ]),
+  ], [
+    makeError(line: 1, column: 2, length: 3, cfeError: "Error.", context: [
+      makeError(line: 4, column: 5, length: 6, contextError: "Context A."),
+      makeError(line: 7, column: 8, length: 9, contextError: "Context B."),
+    ]),
+  ], """
+- Unexpected context message at line 7, column 8, length 9: Context B.""");
 
-  var specifiedWeb = [
-    makeError(
-        line: 1,
-        column: 1,
-        length: 3,
-        analyzerError: "unspecified",
-        webError: "Web 1.")
-  ];
+  // Actual context owned by wrong error.
+  // TODO(rnystrom): This error is pretty confusing. Ideally we would detect
+  // this case specifically and give better guidance.
+  expectValidate([
+    makeError(line: 1, column: 2, length: 3, cfeError: "Error A.", context: [
+      makeError(line: 4, column: 5, length: 6, contextError: "Context A."),
+      makeError(line: 33, column: 5, length: 6, contextError: "Context."),
+    ]),
+    makeError(line: 10, column: 2, length: 3, cfeError: "Error B.", context: [
+      makeError(line: 11, column: 5, length: 6, contextError: "Context B."),
+    ]),
+  ], [
+    makeError(line: 1, column: 2, length: 3, cfeError: "Error A.", context: [
+      makeError(line: 4, column: 5, length: 6, contextError: "Context A."),
+    ]),
+    makeError(line: 10, column: 2, length: 3, cfeError: "Error B.", context: [
+      makeError(line: 11, column: 5, length: 6, contextError: "Context B."),
+      makeError(line: 33, column: 5, length: 6, contextError: "Context."),
+    ]),
+  ], """
+- Missing expected context message at line 33, column 5, length 6: Context.
 
-  expectValidate(specifiedAnalyzer, actualCfe, null);
-  expectValidate(specifiedCfe, actualWeb, null);
-  expectValidate(specifiedWeb, actualAnalyzer, null);
+- Unexpected context message at line 33, column 5, length 6: Context.""");
 
-  expectValidate(specifiedAnalyzer, actualAnalyzer, """
-Unexpected static error at line 1, column 2, length 3:
-- Had analyzer error 'ERROR.CODE2'.
-
-Unexpected static error at line 1, column 3, length 3:
-- Had analyzer error 'ERROR.CODE3'.""");
-
-  expectValidate(specifiedCfe, actualCfe, """
-Unexpected static error at line 1, column 2, length 3:
-- Had CFE error 'Actual 2.'.
-
-Unexpected static error at line 1, column 3, length 3:
-- Had CFE error 'Actual 3.'.""");
-
-  expectValidate(specifiedWeb, actualWeb, """
-Unexpected static error at line 1, column 2, length 3:
-- Had web error 'Web 2.'.
-
-Unexpected static error at line 1, column 3, length 3:
-- Had web error 'Web 3.'.""");
-}
-
-void expectNoDifferences(StaticError expectedError, StaticError actualError) {
-  var actualLines = expectedError.describeDifferences(actualError);
-  if (actualLines != null) {
-    Expect.fail("Expected no differences, but got:\n${actualLines.join('\n')}");
-  }
-}
-
-void expectDifferences(StaticError expectedError, StaticError actualError,
-    String expectedDifferences) {
-  var expectedLines = expectedDifferences
-      .split("\n")
-      .map((line) => line.trim())
-      .where((line) => line.isNotEmpty)
-      .toList();
-  var actualLines = expectedError.describeDifferences(actualError);
-  if (actualLines == null) {
-    Expect.fail("Got no differences, but expected:\n$expectedDifferences");
-  }
-  Expect.listEquals(expectedLines, actualLines);
-}
-
-void expectSimplify(List<StaticError> input, List<StaticError> expected) {
-  var actual = StaticError.simplify(input);
-  Expect.listEquals(expected.map((error) => error.toString()).toList(),
-      actual.map((error) => error.toString()).toList());
+  // If expectation has no context at all, then ignore actual context.
+  expectValidate([
+    makeError(line: 1, column: 2, length: 3, cfeError: "Error."),
+  ], [
+    makeError(line: 1, column: 2, length: 3, cfeError: "Error.", context: [
+      makeError(line: 4, column: 5, length: 6, contextError: "Context A."),
+      makeError(line: 7, column: 8, length: 9, contextError: "Context B."),
+    ]),
+  ], null);
 }
 
 void expectValidate(List<StaticError> expected, List<StaticError> actual,
diff --git a/pkg/test_runner/test/test_file_test.dart b/pkg/test_runner/test/test_file_test.dart
index 251f60d..8e5ddc1 100644
--- a/pkg/test_runner/test/test_file_test.dart
+++ b/pkg/test_runner/test/test_file_test.dart
@@ -28,6 +28,7 @@
   testParseMultitest();
   testParseErrorFlags();
   testParseErrorExpectations();
+  testParseContextMessages();
   testIsRuntimeTest();
   testName();
   testMultitest();
@@ -299,6 +300,7 @@
 /\/      ^^^
 /\/ [analyzer] CompileTimeErrorCode.WRONG_TYPE
 /\/ [cfe] Error: Can't assign a string to an int.
+/\/ [cfe] Another CFE error.
 /\/ [web] Web-specific error.
 
 num j = "str";
@@ -311,16 +313,25 @@
         line: 1,
         column: 9,
         length: 3,
-        analyzerError: "CompileTimeErrorCode.WRONG_TYPE",
-        cfeError: "Error: Can't assign a string to an int.",
-        webError: "Web-specific error."),
+        analyzerError: "CompileTimeErrorCode.WRONG_TYPE"),
     makeError(
-        line: 7,
+        line: 1,
+        column: 9,
+        length: 3,
+        cfeError: "Error: Can't assign a string to an int."),
+    makeError(line: 1, column: 9, length: 3, cfeError: "Another CFE error."),
+    makeError(line: 1, column: 9, length: 3, webError: "Web-specific error."),
+    makeError(
+        line: 8,
         column: 9,
         length: 5,
-        analyzerError: "CompileTimeErrorCode.ALSO_WRONG_TYPE",
-        cfeError: "Error: Can't assign a string to a num.",
-        webError: "Another web error.")
+        analyzerError: "CompileTimeErrorCode.ALSO_WRONG_TYPE"),
+    makeError(
+        line: 8,
+        column: 9,
+        length: 5,
+        cfeError: "Error: Can't assign a string to a num."),
+    makeError(line: 8, column: 9, length: 5, webError: "Another web error.")
   ]);
 
   // Explicit error location.
@@ -341,15 +352,15 @@
         line: 123,
         column: 45,
         length: 678,
-        analyzerError: "CompileTimeErrorCode.FIRST",
-        cfeError: "First error."),
+        analyzerError: "CompileTimeErrorCode.FIRST"),
+    makeError(line: 123, column: 45, length: 678, cfeError: "First error."),
     makeError(
         line: 23,
         column: 5,
         length: 78,
-        analyzerError: "CompileTimeErrorCode.SECOND",
-        cfeError: "Second error.",
-        webError: "Second web error."),
+        analyzerError: "CompileTimeErrorCode.SECOND"),
+    makeError(line: 23, column: 5, length: 78, cfeError: "Second error."),
+    makeError(line: 23, column: 5, length: 78, webError: "Second web error."),
     makeError(line: 9, column: 8, length: 7, cfeError: "Third."),
     makeError(line: 10, column: 9, cfeError: "No length.")
   ]);
@@ -372,8 +383,16 @@
         line: 1,
         column: 9,
         length: 3,
-        analyzerError: "CompileTimeErrorCode.WRONG_TYPE",
-        cfeError: "First line.\nSecond line.\nThird line.",
+        analyzerError: "CompileTimeErrorCode.WRONG_TYPE"),
+    makeError(
+        line: 1,
+        column: 9,
+        length: 3,
+        cfeError: "First line.\nSecond line.\nThird line."),
+    makeError(
+        line: 1,
+        column: 9,
+        length: 3,
         webError: "Web first line.\nWeb second line.\nWeb third line.")
   ]);
 
@@ -418,25 +437,13 @@
 /\/     ^^^
 // [web] unspecified
 """, [
-    makeError(
-        line: 1,
-        column: 8,
-        length: 3,
-        analyzerError: "unspecified",
-        cfeError: "unspecified",
-        webError: "unspecified"),
-    makeError(
-        line: 6,
-        column: 8,
-        length: 3,
-        analyzerError: "unspecified",
-        cfeError: "Message."),
-    makeError(
-        line: 10,
-        column: 8,
-        length: 3,
-        analyzerError: "Error.CODE",
-        cfeError: "unspecified"),
+    makeError(line: 1, column: 8, length: 3, analyzerError: "unspecified"),
+    makeError(line: 1, column: 8, length: 3, cfeError: "unspecified"),
+    makeError(line: 1, column: 8, length: 3, webError: "unspecified"),
+    makeError(line: 6, column: 8, length: 3, analyzerError: "unspecified"),
+    makeError(line: 6, column: 8, length: 3, cfeError: "Message."),
+    makeError(line: 10, column: 8, length: 3, analyzerError: "Error.CODE"),
+    makeError(line: 10, column: 8, length: 3, cfeError: "unspecified"),
     makeError(line: 14, column: 8, length: 3, analyzerError: "unspecified"),
     makeError(line: 17, column: 8, length: 3, cfeError: "unspecified"),
     makeError(line: 20, column: 8, length: 3, webError: "unspecified"),
@@ -453,11 +460,9 @@
 /\/ [cfe] Message.
 """, [
     makeError(
-        line: 1,
-        column: 9,
-        length: 3,
-        analyzerError: "ErrorCode.BAD_THING",
-        cfeError: "Message.\nMore message."),
+        line: 1, column: 9, length: 3, analyzerError: "ErrorCode.BAD_THING"),
+    makeError(
+        line: 1, column: 9, length: 3, cfeError: "Message.\nMore message."),
     makeError(line: 12, column: 34, length: 56, cfeError: "Message."),
   ]);
 
@@ -468,12 +473,9 @@
 /\/ [cfe] Error message.
 /\/ [analyzer] ErrorCode.BAD_THING
 """, [
+    makeError(line: 1, column: 9, length: 3, cfeError: "Error message."),
     makeError(
-        line: 1,
-        column: 9,
-        length: 3,
-        analyzerError: "ErrorCode.BAD_THING",
-        cfeError: "Error message."),
+        line: 1, column: 9, length: 3, analyzerError: "ErrorCode.BAD_THING"),
   ]);
   expectParseErrorExpectations("""
 int i = "s";
@@ -481,12 +483,9 @@
 /\/ [web] Web message.
 /\/ [analyzer] ErrorCode.BAD_THING
 """, [
+    makeError(line: 1, column: 9, length: 3, webError: "Web message."),
     makeError(
-        line: 1,
-        column: 9,
-        length: 3,
-        analyzerError: "ErrorCode.BAD_THING",
-        webError: "Web message."),
+        line: 1, column: 9, length: 3, analyzerError: "ErrorCode.BAD_THING"),
   ]);
   expectParseErrorExpectations("""
 int i = "s";
@@ -494,12 +493,8 @@
 /\/ [web] Web message.
 /\/ [cfe] Error message.
 """, [
-    makeError(
-        line: 1,
-        column: 9,
-        length: 3,
-        cfeError: "Error message.",
-        webError: "Web message."),
+    makeError(line: 1, column: 9, length: 3, webError: "Web message."),
+    makeError(line: 1, column: 9, length: 3, cfeError: "Error message."),
   ]);
 
   // Must have at least one error message.
@@ -538,7 +533,7 @@
 /\/ [analyzer] Not error code.
 """);
 
-  // A CFE-only error with length one is treated as having no length.
+  // A CFE error with length one is treated as having no length.
   expectParseErrorExpectations("""
 int i = "s";
 /\/      ^
@@ -555,39 +550,149 @@
 /\/ [web] Web message.
 """, [
     makeError(line: 1, column: 9, length: null, cfeError: "Message."),
+    makeError(line: 5, column: 9, length: 1, analyzerError: "Error.BAD"),
+    makeError(line: 5, column: 9, length: null, cfeError: "Message."),
+    makeError(line: 10, column: 9, length: null, cfeError: "Message."),
+    makeError(line: 10, column: 9, length: 1, webError: "Web message."),
+  ]);
+}
+
+void testParseContextMessages() {
+  // Multiple messages.
+  expectParseErrorExpectations("""
+var string = "str";
+/\/  ^^^^^^
+/\/ [context 1] Analyzer context before.
+/\/ [context 2] CFE context before.
+
+int j = string;
+/\/      ^^^^^^
+/\/ [analyzer 1] Error.BAD
+/\/ [cfe 2] Error message.
+
+var string = "str";
+/\/            ^^^
+/\/ [context 2] CFE context after.
+
+var string = "str";
+/\/            ^^^
+/\/ [context 1] Analyzer context after.
+""", [
+    makeError(
+        line: 6,
+        column: 9,
+        length: 6,
+        analyzerError: "Error.BAD",
+        context: [
+          makeError(
+              line: 1,
+              column: 5,
+              length: 6,
+              analyzerError: "Analyzer context before."),
+          makeError(
+              line: 15,
+              column: 15,
+              length: 3,
+              analyzerError: "Analyzer context after.")
+        ]),
+    makeError(
+        line: 6,
+        column: 9,
+        length: 6,
+        cfeError: "Error message.",
+        context: [
+          makeError(
+              line: 1,
+              column: 5,
+              length: 6,
+              analyzerError: "CFE context before."),
+          makeError(
+              line: 11,
+              column: 15,
+              length: 3,
+              analyzerError: "CFE context after.")
+        ]),
+  ]);
+
+  // Context before error.
+  expectParseErrorExpectations("""
+var string = "str";
+/\/  ^^^^^^
+/\/ [context 1] Context.
+
+int j = string;
+/\/      ^^^^^^
+/\/ [analyzer 1] Error.BAD
+""", [
     makeError(
         line: 5,
         column: 9,
-        length: 1,
+        length: 6,
         analyzerError: "Error.BAD",
-        cfeError: "Message."),
-    makeError(
-      line: 10,
-      column: 9,
-      length: 1,
-      cfeError: "Message.",
-      webError: "Web message.",
-    ),
+        context: [
+          makeError(line: 1, column: 5, length: 6, analyzerError: "Context.")
+        ]),
   ]);
 
-  // Cannot have the same front end more than once.
+  // Context after error.
+  expectParseErrorExpectations("""
+int j = string;
+/\/      ^^^^^^
+/\/ [analyzer 1] Error.BAD
+
+var string = "str";
+/\/  ^^^^^^
+/\/ [context 1] Context.
+""", [
+    makeError(
+        line: 1,
+        column: 9,
+        length: 6,
+        analyzerError: "Error.BAD",
+        context: [
+          makeError(line: 5, column: 5, length: 6, analyzerError: "Context.")
+        ]),
+  ]);
+
+  // Context must have a number.
   expectFormatError("""
 int i = "s";
 /\/      ^^^
-/\/ [analyzer] ErrorCode.BAD_THING
-/\/ [analyzer] ErrorCode.ANOTHER_THING
+/\/ [context] No number.
+
+int i = "s";
+/\/      ^^^
+/\/ [cfe 1] Error.
 """);
+
+  // Context number must match an error.
   expectFormatError("""
 int i = "s";
 /\/      ^^^
-/\/ [cfe] Message 1.
-/\/ [cfe] Message 2.
+/\/ [context 2] Wrong number.
+
+int i = "s";
+/\/      ^^^
+/\/ [cfe 1] Error.
 """);
+
+  // Two errors with same number.
   expectFormatError("""
 int i = "s";
 /\/      ^^^
-/\/ [web] Web 1.
-/\/ [web] Web 2.
+/\/ [context 1] Context.
+
+int i = "s";
+/\/      ^^^
+/\/ [cfe 1] Error.
+/\/ [analyzer 1] Error.CODE
+""");
+
+  // Numbered error with no context.
+  expectFormatError("""
+int i = "s";
+/\/      ^^^
+/\/ [cfe 1] Error.
 """);
 }
 
diff --git a/pkg/test_runner/test/update_errors_test.dart b/pkg/test_runner/test/update_errors_test.dart
index 6c433625..afe5db9 100644
--- a/pkg/test_runner/test/update_errors_test.dart
+++ b/pkg/test_runner/test/update_errors_test.dart
@@ -53,31 +53,15 @@
 
 int last = "oops";
 """, errors: [
-    makeError(
-        line: 1,
-        column: 9,
-        length: 5,
-        analyzerError: "some.error",
-        cfeError: "Bad."),
-    makeError(
-        line: 3,
-        column: 15,
-        length: 7,
-        cfeError: "Another bad.",
-        webError: "Web.\nError."),
-    makeError(
-        line: 5,
-        column: 13,
-        length: 5,
-        analyzerError: "third.error",
-        webError: "Web error."),
-    makeError(
-        line: 7,
-        column: 12,
-        length: 6,
-        analyzerError: "last.error",
-        cfeError: "Final.\nError.",
-        webError: "Web error."),
+    makeError(line: 1, column: 9, length: 5, analyzerError: "some.error"),
+    makeError(line: 1, column: 9, length: 5, cfeError: "Bad."),
+    makeError(line: 3, column: 15, length: 7, cfeError: "Another bad."),
+    makeError(line: 3, column: 15, length: 7, webError: "Web.\nError."),
+    makeError(line: 5, column: 13, length: 5, analyzerError: "third.error"),
+    makeError(line: 5, column: 13, length: 5, webError: "Web error."),
+    makeError(line: 7, column: 12, length: 6, analyzerError: "last.error"),
+    makeError(line: 7, column: 12, length: 6, cfeError: "Final.\nError."),
+    makeError(line: 7, column: 12, length: 6, webError: "Web error."),
   ], expected: """
 int i = "bad";
 /\/      ^^^^^
@@ -215,12 +199,9 @@
     /\/    ^^
     /\/ [analyzer] previous.error
 """, errors: [
+    makeError(line: 1, column: 9, length: 5, analyzerError: "updated.error"),
     makeError(
-        line: 1,
-        column: 9,
-        length: 5,
-        analyzerError: "updated.error",
-        cfeError: "Long.\nError.\nMessage."),
+        line: 1, column: 9, length: 5, cfeError: "Long.\nError.\nMessage."),
   ], expected: """
 int i = "bad";
     /\/  ^^^^^
@@ -389,6 +370,28 @@
 /\/ [cfe] Wrong 1.
 """);
 
+  // Shared locations between errors with and without length.
+  expectUpdate("""
+someBadCode(arg);
+
+moreBadCode(arg);
+""", errors: [
+    makeError(line: 1, column: 13, length: 3, analyzerError: "Error.CODE"),
+    makeError(line: 1, column: 13, cfeError: "Wrong 1."),
+    makeError(line: 3, column: 13, cfeError: "Wrong 2."),
+    makeError(line: 3, column: 13, length: 3, webError: "Web error."),
+  ], expected: """
+someBadCode(arg);
+/\/          ^^^
+/\/ [analyzer] Error.CODE
+/\/ [cfe] Wrong 1.
+
+moreBadCode(arg);
+/\/          ^^^
+/\/ [web] Web error.
+/\/ [cfe] Wrong 2.
+""");
+
   // Doesn't crash with RangeError.
   expectUpdate("""
 x
@@ -400,9 +403,192 @@
 // [error line 1, column 1, length 0]
 // [cfe] Foo""");
 
+  contextMessages();
   regression();
 }
 
+void contextMessages() {
+  // Inserts context messages.
+  expectUpdate(
+      """
+int i = "bad";
+
+int another = "wrong";
+
+int third = "boo";
+""",
+      errors: [
+        makeError(
+            line: 3,
+            column: 15,
+            length: 7,
+            analyzerError: "some.error",
+            context: [
+              makeError(
+                  line: 1,
+                  column: 9,
+                  length: 5,
+                  contextError: "Analyzer context."),
+              makeError(
+                  line: 5,
+                  column: 13,
+                  length: 5,
+                  contextError: "More context."),
+            ]),
+        makeError(
+            line: 3,
+            column: 15,
+            length: 7,
+            cfeError: "CFE error.",
+            context: [
+              makeError(
+                  line: 1, column: 9, length: 5, contextError: "CFE context."),
+            ]),
+      ],
+      remove: {ErrorSource.analyzer},
+      includeContext: true,
+      expected: """
+int i = "bad";
+/\/      ^^^^^
+/\/ [context 1] Analyzer context.
+/\/ [context 2] CFE context.
+
+int another = "wrong";
+/\/            ^^^^^^^
+/\/ [analyzer 1] some.error
+/\/ [cfe 2] CFE error.
+
+int third = "boo";
+/\/          ^^^^^
+/\/ [context 1] More context.
+""");
+
+  // Removes context messages for removed errors.
+  expectUpdate(
+      """
+int i = "bad";
+/\/      ^^^^^
+/\/ [context 1] Analyzer context.
+/\/ [context 2] CFE context.
+
+int another = "wrong";
+/\/            ^^^^^^^
+/\/ [analyzer 1] some.error
+/\/ [cfe 2] CFE error.
+
+int third = "boo";
+/\/          ^^^^^
+/\/ [context 1] More context.
+""",
+      remove: {ErrorSource.analyzer},
+      includeContext: true,
+      expected: """
+int i = "bad";
+/\/      ^^^^^
+/\/ [context 1] CFE context.
+
+int another = "wrong";
+/\/            ^^^^^^^
+/\/ [cfe 1] CFE error.
+
+int third = "boo";
+""");
+
+  // Discards context messages when not told to include them.
+  expectUpdate(
+      """
+int i = "bad";
+
+int another = "wrong";
+
+int third = "boo";
+""",
+      errors: [
+        makeError(
+            line: 3,
+            column: 15,
+            length: 7,
+            analyzerError: "some.error",
+            context: [
+              makeError(
+                  line: 1,
+                  column: 9,
+                  length: 5,
+                  contextError: "Analyzer context."),
+              makeError(
+                  line: 5,
+                  column: 13,
+                  length: 5,
+                  contextError: "More context."),
+            ]),
+        makeError(
+            line: 3,
+            column: 15,
+            length: 7,
+            cfeError: "CFE error.",
+            context: [
+              makeError(
+                  line: 1, column: 9, length: 5, contextError: "CFE context."),
+            ]),
+      ],
+      includeContext: false,
+      expected: """
+int i = "bad";
+
+int another = "wrong";
+/\/            ^^^^^^^
+/\/ [analyzer] some.error
+/\/ [cfe] CFE error.
+
+int third = "boo";
+""");
+
+  // Discards existing context messages when not told to include them.
+  expectUpdate(
+      """
+int i = "bad";
+/\/      ^^^^^
+/\/ [context 1] CFE context.
+
+int another = "wrong";
+/\/            ^^^^^^^
+/\/ [cfe 1] CFE error.
+
+int third = "boo";
+""",
+      errors: [
+        makeError(
+            line: 5,
+            column: 15,
+            length: 7,
+            analyzerError: "some.error",
+            context: [
+              makeError(
+                  line: 1,
+                  column: 9,
+                  length: 5,
+                  contextError: "Analyzer context."),
+              makeError(
+                  line: 7,
+                  column: 13,
+                  length: 5,
+                  contextError: "More context."),
+            ]),
+      ],
+      remove: {ErrorSource.analyzer},
+      includeContext: false,
+      expected: """
+int i = "bad";
+
+int another = "wrong";
+/\/            ^^^^^^^
+/\/ [analyzer] some.error
+/\/ [cfe] CFE error.
+
+int third = "boo";
+""");
+}
+
 void regression() {
   // https://github.com/dart-lang/sdk/issues/37990.
   expectUpdate("""
@@ -459,11 +645,16 @@
 }
 
 void expectUpdate(String original,
-    {List<StaticError> errors, Set<ErrorSource> remove, String expected}) {
+    {List<StaticError> errors,
+    Set<ErrorSource> remove,
+    bool includeContext,
+    String expected}) {
   errors ??= const [];
   remove ??= ErrorSource.all.toSet();
+  includeContext ??= false;
 
-  var actual = updateErrorExpectations(original, errors, remove: remove);
+  var actual = updateErrorExpectations(original, errors,
+      remove: remove, includeContext: includeContext);
   if (actual != expected) {
     // Not using Expect.equals() because the diffs it shows aren't helpful for
     // strings this large.
diff --git a/pkg/test_runner/test/utils.dart b/pkg/test_runner/test/utils.dart
index b88d7ab..e0d8f07 100644
--- a/pkg/test_runner/test/utils.dart
+++ b/pkg/test_runner/test/utils.dart
@@ -26,19 +26,46 @@
         List<TestFile> testFiles, String suite) =>
     _MockTestSuite(configuration, testFiles, suite);
 
+/// Creates a [StaticError].
+///
+/// Only one of [analyzerError], [cfeError], [webError], or [contextError] may
+/// be passed.
 StaticError makeError(
     {int line = 1,
     int column = 2,
     int length,
     String analyzerError,
     String cfeError,
-    String webError}) {
-  var errors = {
-    if (analyzerError != null) ErrorSource.analyzer: analyzerError,
-    if (cfeError != null) ErrorSource.cfe: cfeError,
-    if (webError != null) ErrorSource.web: webError,
-  };
-  return StaticError(errors, line: line, column: column, length: length);
+    String webError,
+    String contextError,
+    List<StaticError> context}) {
+  ErrorSource source;
+  String message;
+  if (analyzerError != null) {
+    assert(cfeError == null);
+    assert(webError == null);
+    assert(contextError == null);
+    source = ErrorSource.analyzer;
+    message = analyzerError;
+  } else if (cfeError != null) {
+    assert(webError == null);
+    assert(contextError == null);
+    source = ErrorSource.cfe;
+    message = cfeError;
+  } else if (webError != null) {
+    assert(contextError == null);
+    source = ErrorSource.web;
+    message = webError;
+  } else {
+    assert(contextError != null);
+    source = ErrorSource.context;
+    message = contextError;
+  }
+
+  var error =
+      StaticError(source, message, line: line, column: column, length: length);
+  if (context != null) error.contextMessages.addAll(context);
+  return error;
 }
 
 class _MockTestSuite extends StandardTestSuite {
diff --git a/pkg/test_runner/tool/update_static_error_tests.dart b/pkg/test_runner/tool/update_static_error_tests.dart
index 20ed7f5..9758107 100644
--- a/pkg/test_runner/tool/update_static_error_tests.dart
+++ b/pkg/test_runner/tool/update_static_error_tests.dart
@@ -37,6 +37,8 @@
       abbr: "n",
       help: "Print result but do not overwrite any files.",
       negatable: false);
+  parser.addFlag("context",
+      abbr: "c", help: "Include context messages in output.");
 
   parser.addSeparator("What operations to perform:");
   parser.addFlag("remove-all",
@@ -61,8 +63,6 @@
       help: "Update error expectations for given front ends.",
       allowed: sources);
 
-  parser.addSeparator("Other flags:");
-
   var results = parser.parse(args);
 
   if (results["help"] as bool) {
@@ -76,6 +76,8 @@
 
   var dryRun = results["dry-run"] as bool;
 
+  var includeContext = results["context"] as bool;
+
   var removeSources = <ErrorSource>{};
   var insertSources = <ErrorSource>{};
 
@@ -132,7 +134,10 @@
 
     if (entry is pkg_file.File) {
       await _processFile(entry,
-          dryRun: dryRun, remove: removeSources, insert: insertSources);
+          dryRun: dryRun,
+          includeContext: includeContext,
+          remove: removeSources,
+          insert: insertSources);
     }
   }
 }
@@ -146,7 +151,10 @@
 }
 
 Future<void> _processFile(File file,
-    {bool dryRun, Set<ErrorSource> remove, Set<ErrorSource> insert}) async {
+    {bool dryRun,
+    bool includeContext,
+    Set<ErrorSource> remove,
+    Set<ErrorSource> insert}) async {
   stdout.write("${file.path}...");
   var source = file.readAsStringSync();
   var testFile = TestFile.parse(Path("."), file.absolute.path, source);
@@ -203,9 +211,8 @@
     }
   }
 
-  errors = StaticError.simplify(errors);
-
-  var result = updateErrorExpectations(source, errors, remove: remove);
+  var result = updateErrorExpectations(source, errors,
+      remove: remove, includeContext: includeContext);
 
   stdout.writeln("\r${file.path} (Updated with ${errors.length} errors)");
 
@@ -223,7 +230,7 @@
   // mode.
   var result = await Process.run(_analyzerPath, [
     ...options,
-    "--format=machine",
+    "--format=json",
     path,
   ]);
 
@@ -291,8 +298,7 @@
       return dart2jsError.line == cfeError.line &&
           dart2jsError.column == cfeError.column &&
           dart2jsError.length == cfeError.length &&
-          dart2jsError.errorFor(ErrorSource.web) ==
-              cfeError.errorFor(ErrorSource.cfe);
+          dart2jsError.message == cfeError.message;
     });
   });
 
diff --git a/pkg/testing/lib/src/chain.dart b/pkg/testing/lib/src/chain.dart
index 1f7fc84..c56fc21 100644
--- a/pkg/testing/lib/src/chain.dart
+++ b/pkg/testing/lib/src/chain.dart
@@ -322,12 +322,29 @@
 
   String get name;
 
+  /// Sets this (*and effectively subsequent*) test step(s) as async.
+  ///
+  /// TL;DR: Either set to false, or only set to true when this and all
+  /// subsequent steps can run intertwined with another test.
+  ///
+  /// Details:
+  ///
+  /// A single test (TestDescription) can have several steps (Step).
+  /// When running a test the first step is executed, and when that step is done
+  /// the next step is executed by the now-ending step.
+  ///
+  /// When isAsync is false each step returns a future which is awaited,
+  /// effectivly meaning that only a single test is run at a time.
+  ///
+  /// When isAsync is true that step doesn't return a future (but adds it's
+  /// future to a list which is awaited before sending an 'entire suite done'
+  /// message), meaning that the next test can start before the step is
+  /// finished. As the next step in the test only starts after the current
+  /// step finishes, that also means that the next test can start - and run
+  /// intertwined with - a subsequent step even if such a subsequent step has
+  /// isAsync set to false.
   bool get isAsync => false;
 
-  bool get isCompiler => false;
-
-  bool get isRuntime => false;
-
   Future<Result<O>> run(I input, C context);
 
   Result<O> unhandledError(error, StackTrace trace) {
diff --git a/pkg/vm/lib/metadata/direct_call.dart b/pkg/vm/lib/metadata/direct_call.dart
index 22a26fd..8e4298b 100644
--- a/pkg/vm/lib/metadata/direct_call.dart
+++ b/pkg/vm/lib/metadata/direct_call.dart
@@ -48,7 +48,7 @@
   @override
   DirectCallMetadata readFromBinary(Node node, BinarySource source) {
     final targetReference =
-        source.readNullableCanonicalNameReference()?.getReference();
+        source.readNullableCanonicalNameReference()?.reference;
     if (targetReference == null) {
       throw 'DirectCallMetadata should have a non-null target';
     }
diff --git a/pkg/vm/lib/metadata/inferred_type.dart b/pkg/vm/lib/metadata/inferred_type.dart
index 5f0c9af..4d609fd 100644
--- a/pkg/vm/lib/metadata/inferred_type.dart
+++ b/pkg/vm/lib/metadata/inferred_type.dart
@@ -114,8 +114,9 @@
   void writeToBinary(InferredType metadata, Node node, BinarySink sink) {
     // TODO(sjindel/tfa): Implement serialization of type arguments when can use
     // them for optimizations.
-    sink.writeNullAllowedCanonicalNameReference(
-        getCanonicalNameOfClass(metadata.concreteClass));
+    sink.writeNullAllowedCanonicalNameReference(metadata.concreteClass != null
+        ? getCanonicalNameOfClass(metadata.concreteClass)
+        : null);
     sink.writeByte(metadata._flags);
     if (metadata.constantValue != null) {
       sink.writeConstantReference(metadata.constantValue);
@@ -127,7 +128,7 @@
     // TODO(sjindel/tfa): Implement serialization of type arguments when can use
     // them for optimizations.
     final concreteClassReference =
-        source.readNullableCanonicalNameReference()?.getReference();
+        source.readNullableCanonicalNameReference()?.reference;
     final flags = source.readByte();
     final constantValue = (flags & InferredType.flagConstant) != 0
         ? source.readConstantReference()
diff --git a/pkg/vm/lib/transformations/ffi.dart b/pkg/vm/lib/transformations/ffi.dart
index 449b5b0..1551f46 100644
--- a/pkg/vm/lib/transformations/ffi.dart
+++ b/pkg/vm/lib/transformations/ffi.dart
@@ -7,13 +7,14 @@
 
 library vm.transformations.ffi;
 
-import 'package:kernel/ast.dart';
+import 'package:kernel/ast.dart' hide MapEntry;
 import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
 import 'package:kernel/core_types.dart';
 import 'package:kernel/library_index.dart' show LibraryIndex;
 import 'package:kernel/reference_from_index.dart';
 import 'package:kernel/target/targets.dart' show DiagnosticReporter;
-import 'package:kernel/type_environment.dart' show TypeEnvironment;
+import 'package:kernel/type_environment.dart'
+    show TypeEnvironment, SubtypeCheckMode;
 
 /// Represents the (instantiated) ffi.NativeType.
 enum NativeType {
@@ -181,6 +182,11 @@
   NativeType.kPointer,
 ];
 
+const List<NativeType> unalignedLoadsStores = [
+  NativeType.kFloat,
+  NativeType.kDouble,
+];
+
 /// [FfiTransformer] contains logic which is shared between
 /// _FfiUseSiteTransformer and _FfiDefinitionTransformer.
 class FfiTransformer extends Transformer {
@@ -212,15 +218,24 @@
   final Class allocatorClass;
   final Class nativeFunctionClass;
   final Class opaqueClass;
-  final Class cArrayClass;
-  final Class cArraySizeClass;
+  final Class arrayClass;
+  final Class arraySizeClass;
+  final Field arraySizeDimension1Field;
+  final Field arraySizeDimension2Field;
+  final Field arraySizeDimension3Field;
+  final Field arraySizeDimension4Field;
+  final Field arraySizeDimension5Field;
+  final Field arraySizeDimensionsField;
   final Class pointerClass;
   final Class structClass;
   final Class ffiStructLayoutClass;
   final Field ffiStructLayoutTypesField;
+  final Field ffiStructLayoutPackingField;
   final Class ffiInlineArrayClass;
   final Field ffiInlineArrayElementTypeField;
   final Field ffiInlineArrayLengthField;
+  final Class packedClass;
+  final Field packedMemberAlignmentField;
   final Procedure allocateMethod;
   final Procedure allocatorAllocateMethod;
   final Procedure castMethod;
@@ -230,22 +245,32 @@
   final Procedure structPointerRef;
   final Procedure structPointerElemAt;
   final Procedure structArrayElemAt;
+  final Procedure arrayArrayElemAt;
+  final Procedure arrayArrayAssignAt;
   final Procedure asFunctionMethod;
   final Procedure asFunctionInternal;
   final Procedure sizeOfMethod;
   final Procedure lookupFunctionMethod;
   final Procedure fromFunctionMethod;
   final Field addressOfField;
-  final Field cArrayTypedDataBaseField;
+  final Field arrayTypedDataBaseField;
+  final Field arraySizeField;
+  final Field arrayNestedDimensionsField;
+  final Procedure arrayCheckIndex;
+  final Field arrayNestedDimensionsFlattened;
+  final Field arrayNestedDimensionsFirst;
+  final Field arrayNestedDimensionsRest;
   final Constructor structFromPointer;
-  final Constructor cArrayConstructor;
+  final Constructor arrayConstructor;
   final Procedure fromAddressInternal;
   final Procedure libraryLookupMethod;
   final Procedure abiMethod;
   final Procedure pointerFromFunctionProcedure;
   final Procedure nativeCallbackFunctionProcedure;
   final Map<NativeType, Procedure> loadMethods;
+  final Map<NativeType, Procedure> loadUnalignedMethods;
   final Map<NativeType, Procedure> storeMethods;
+  final Map<NativeType, Procedure> storeUnalignedMethods;
   final Map<NativeType, Procedure> elementAtMethods;
   final Procedure memCopy;
   final Procedure allocationTearoff;
@@ -285,18 +310,35 @@
         allocatorClass = index.getClass('dart:ffi', 'Allocator'),
         nativeFunctionClass = index.getClass('dart:ffi', 'NativeFunction'),
         opaqueClass = index.getClass('dart:ffi', 'Opaque'),
-        cArrayClass = index.getClass('dart:ffi', 'Array'),
-        cArraySizeClass = index.getClass('dart:ffi', '_ArraySize'),
+        arrayClass = index.getClass('dart:ffi', 'Array'),
+        arraySizeClass = index.getClass('dart:ffi', '_ArraySize'),
+        arraySizeDimension1Field =
+            index.getMember('dart:ffi', '_ArraySize', 'dimension1'),
+        arraySizeDimension2Field =
+            index.getMember('dart:ffi', '_ArraySize', 'dimension2'),
+        arraySizeDimension3Field =
+            index.getMember('dart:ffi', '_ArraySize', 'dimension3'),
+        arraySizeDimension4Field =
+            index.getMember('dart:ffi', '_ArraySize', 'dimension4'),
+        arraySizeDimension5Field =
+            index.getMember('dart:ffi', '_ArraySize', 'dimension5'),
+        arraySizeDimensionsField =
+            index.getMember('dart:ffi', '_ArraySize', 'dimensions'),
         pointerClass = index.getClass('dart:ffi', 'Pointer'),
         structClass = index.getClass('dart:ffi', 'Struct'),
         ffiStructLayoutClass = index.getClass('dart:ffi', '_FfiStructLayout'),
         ffiStructLayoutTypesField =
             index.getMember('dart:ffi', '_FfiStructLayout', 'fieldTypes'),
+        ffiStructLayoutPackingField =
+            index.getMember('dart:ffi', '_FfiStructLayout', 'packing'),
         ffiInlineArrayClass = index.getClass('dart:ffi', '_FfiInlineArray'),
         ffiInlineArrayElementTypeField =
             index.getMember('dart:ffi', '_FfiInlineArray', 'elementType'),
         ffiInlineArrayLengthField =
             index.getMember('dart:ffi', '_FfiInlineArray', 'length'),
+        packedClass = index.getClass('dart:ffi', 'Packed'),
+        packedMemberAlignmentField =
+            index.getMember('dart:ffi', 'Packed', 'memberAlignment'),
         allocateMethod = index.getMember('dart:ffi', 'AllocatorAlloc', 'call'),
         allocatorAllocateMethod =
             index.getMember('dart:ffi', 'Allocator', 'allocate'),
@@ -305,11 +347,21 @@
         elementAtMethod = index.getMember('dart:ffi', 'Pointer', 'elementAt'),
         addressGetter = index.getMember('dart:ffi', 'Pointer', 'get:address'),
         addressOfField = index.getMember('dart:ffi', 'Struct', '_addressOf'),
-        cArrayTypedDataBaseField =
+        arrayTypedDataBaseField =
             index.getMember('dart:ffi', 'Array', '_typedDataBase'),
+        arraySizeField = index.getMember('dart:ffi', 'Array', '_size'),
+        arrayNestedDimensionsField =
+            index.getMember('dart:ffi', 'Array', '_nestedDimensions'),
+        arrayCheckIndex = index.getMember('dart:ffi', 'Array', '_checkIndex'),
+        arrayNestedDimensionsFlattened =
+            index.getMember('dart:ffi', 'Array', '_nestedDimensionsFlattened'),
+        arrayNestedDimensionsFirst =
+            index.getMember('dart:ffi', 'Array', '_nestedDimensionsFirst'),
+        arrayNestedDimensionsRest =
+            index.getMember('dart:ffi', 'Array', '_nestedDimensionsRest'),
         structFromPointer =
             index.getMember('dart:ffi', 'Struct', '_fromPointer'),
-        cArrayConstructor = index.getMember('dart:ffi', 'Array', '_'),
+        arrayConstructor = index.getMember('dart:ffi', 'Array', '_'),
         fromAddressInternal =
             index.getTopLevelMember('dart:ffi', '_fromAddress'),
         structPointerRef =
@@ -317,6 +369,8 @@
         structPointerElemAt =
             index.getMember('dart:ffi', 'StructPointer', '[]'),
         structArrayElemAt = index.getMember('dart:ffi', 'StructArray', '[]'),
+        arrayArrayElemAt = index.getMember('dart:ffi', 'ArrayArray', '[]'),
+        arrayArrayAssignAt = index.getMember('dart:ffi', 'ArrayArray', '[]='),
         asFunctionMethod =
             index.getMember('dart:ffi', 'NativeFunctionPointer', 'asFunction'),
         asFunctionInternal =
@@ -340,10 +394,20 @@
           final name = nativeTypeClassNames[t.index];
           return index.getTopLevelMember('dart:ffi', "_load$name");
         }),
+        loadUnalignedMethods =
+            Map.fromIterable(unalignedLoadsStores, value: (t) {
+          final name = nativeTypeClassNames[t.index];
+          return index.getTopLevelMember('dart:ffi', "_load${name}Unaligned");
+        }),
         storeMethods = Map.fromIterable(optimizedTypes, value: (t) {
           final name = nativeTypeClassNames[t.index];
           return index.getTopLevelMember('dart:ffi', "_store$name");
         }),
+        storeUnalignedMethods =
+            Map.fromIterable(unalignedLoadsStores, value: (t) {
+          final name = nativeTypeClassNames[t.index];
+          return index.getTopLevelMember('dart:ffi', "_store${name}Unaligned");
+        }),
         elementAtMethods = Map.fromIterable(optimizedTypes, value: (t) {
           final name = nativeTypeClassNames[t.index];
           return index.getTopLevelMember('dart:ffi', "_elementAt$name");
@@ -391,7 +455,8 @@
   DartType convertNativeTypeToDartType(DartType nativeType,
       {bool allowStructs = false,
       bool allowStructItself = false,
-      bool allowHandle = false}) {
+      bool allowHandle = false,
+      bool allowInlineArray = false}) {
     if (nativeType is! InterfaceType) {
       return null;
     }
@@ -399,6 +464,12 @@
     final Class nativeClass = native.classNode;
     final NativeType nativeType_ = getType(nativeClass);
 
+    if (nativeClass == arrayClass) {
+      if (!allowInlineArray) {
+        return null;
+      }
+      return nativeType;
+    }
     if (hierarchy.isSubclassOf(nativeClass, structClass)) {
       if (structClass == nativeClass) {
         return allowStructItself ? nativeType : null;
@@ -457,18 +528,22 @@
     return NativeType.values[index];
   }
 
+  ConstantExpression intListConstantExpression(List<int> values) =>
+      ConstantExpression(
+          ListConstant(InterfaceType(intClass, Nullability.legacy),
+              [for (var v in values) IntConstant(v)]),
+          InterfaceType(listClass, Nullability.legacy,
+              [InterfaceType(intClass, Nullability.legacy)]));
+
   /// Expression that queries VM internals at runtime to figure out on which ABI
   /// we are.
   Expression runtimeBranchOnLayout(Map<Abi, int> values) {
     return MethodInvocation(
-        ConstantExpression(
-            ListConstant(InterfaceType(intClass, Nullability.legacy), [
-              IntConstant(values[Abi.wordSize64]),
-              IntConstant(values[Abi.wordSize32Align32]),
-              IntConstant(values[Abi.wordSize32Align64])
-            ]),
-            InterfaceType(listClass, Nullability.legacy,
-                [InterfaceType(intClass, Nullability.legacy)])),
+        intListConstantExpression([
+          values[Abi.wordSize64],
+          values[Abi.wordSize32Align32],
+          values[Abi.wordSize32Align64]
+        ]),
         Name("[]"),
         Arguments([StaticInvocation(abiMethod, Arguments([]))]),
         listElementAt);
@@ -578,6 +653,102 @@
                 fileOffset),
             coreTypes.objectNonNullableRawType));
   }
+
+  bool isPrimitiveType(DartType type) {
+    if (type is InvalidType) {
+      return false;
+    }
+    if (type is NullType) {
+      return false;
+    }
+    if (!env.isSubtypeOf(
+        type,
+        InterfaceType(nativeTypesClasses[NativeType.kNativeType.index],
+            Nullability.legacy),
+        SubtypeCheckMode.ignoringNullabilities)) {
+      return false;
+    }
+    if (isPointerType(type)) {
+      return false;
+    }
+    if (type is InterfaceType) {
+      final nativeType = getType(type.classNode);
+      return nativeType != null;
+    }
+    return false;
+  }
+
+  bool isPointerType(DartType type) {
+    if (type is InvalidType) {
+      return false;
+    }
+    if (type is NullType) {
+      return false;
+    }
+    return env.isSubtypeOf(
+        type,
+        InterfaceType(pointerClass, Nullability.legacy, [
+          InterfaceType(nativeTypesClasses[NativeType.kNativeType.index],
+              Nullability.legacy)
+        ]),
+        SubtypeCheckMode.ignoringNullabilities);
+  }
+
+  bool isArrayType(DartType type) {
+    if (type is InvalidType) {
+      return false;
+    }
+    if (type is NullType) {
+      return false;
+    }
+    return env.isSubtypeOf(
+        type,
+        InterfaceType(arrayClass, Nullability.legacy, [
+          InterfaceType(nativeTypesClasses[NativeType.kNativeType.index],
+              Nullability.legacy)
+        ]),
+        SubtypeCheckMode.ignoringNullabilities);
+  }
+
+  /// Returns the single element type nested type argument of `Array`.
+  ///
+  /// `Array<Array<Array<Int8>>>` -> `Int8`.
+  DartType arraySingleElementType(DartType dartType) {
+    InterfaceType elementType = dartType as InterfaceType;
+    while (elementType.classNode == arrayClass) {
+      elementType = elementType.typeArguments[0] as InterfaceType;
+    }
+    return elementType;
+  }
+
+  /// Returns the number of dimensions of `Array`.
+  ///
+  /// `Array<Array<Array<Int8>>>` -> 3.
+  int arrayDimensions(DartType dartType) {
+    InterfaceType elementType = dartType as InterfaceType;
+    int dimensions = 0;
+    while (elementType.classNode == arrayClass) {
+      elementType = elementType.typeArguments[0] as InterfaceType;
+      dimensions++;
+    }
+    return dimensions;
+  }
+
+  bool isStructSubtype(DartType type) {
+    if (type is InvalidType) {
+      return false;
+    }
+    if (type is NullType) {
+      return false;
+    }
+    if (type is InterfaceType) {
+      if (type.classNode == structClass) {
+        return false;
+      }
+    }
+    return env.isSubtypeOf(type, InterfaceType(structClass, Nullability.legacy),
+        SubtypeCheckMode.ignoringNullabilities);
+  }
 }
 
 /// Contains all information collected by _FfiDefinitionTransformer that is
diff --git a/pkg/vm/lib/transformations/ffi_definitions.dart b/pkg/vm/lib/transformations/ffi_definitions.dart
index 1311f82..522510b 100644
--- a/pkg/vm/lib/transformations/ffi_definitions.dart
+++ b/pkg/vm/lib/transformations/ffi_definitions.dart
@@ -8,15 +8,18 @@
 
 import 'package:front_end/src/api_unstable/vm.dart'
     show
+        messageFfiPackedAnnotationAlignment,
         templateFfiEmptyStruct,
         templateFfiFieldAnnotation,
         templateFfiFieldNull,
         templateFfiFieldCyclic,
         templateFfiFieldNoAnnotation,
-        templateFfiTypeInvalid,
         templateFfiTypeMismatch,
         templateFfiFieldInitializer,
+        templateFfiPackedAnnotation,
+        templateFfiPackedNestingNonPacked,
         templateFfiSizeAnnotation,
+        templateFfiSizeAnnotationDimensions,
         templateFfiStructGeneric;
 
 import 'package:kernel/ast.dart' hide MapEntry;
@@ -177,13 +180,13 @@
       return node;
     }
 
-    _checkStructClass(node);
+    final packing = _checkStructClass(node);
 
     final indexedClass = currentLibraryIndex?.lookupIndexedClass(node.name);
     _checkConstructors(node, indexedClass);
     indexedStructClasses[node] = indexedClass;
 
-    fieldsValid[node] = _checkFieldAnnotations(node);
+    fieldsValid[node] = _checkFieldAnnotations(node, packing);
 
     return node;
   }
@@ -197,7 +200,8 @@
     }
   }
 
-  void _checkStructClass(Class node) {
+  /// Returns packing if any.
+  int _checkStructClass(Class node) {
     if (node.typeParameters.length > 0) {
       diagnosticReporter.report(
           templateFfiStructGeneric.withArguments(node.name),
@@ -209,50 +213,30 @@
     if (node.supertype?.classNode != structClass) {
       // Not a struct, but extends a struct. The error will be emitted by
       // _FfiUseSiteTransformer.
-      return;
+      return null;
     }
-  }
 
-  bool _isPointerType(DartType type) {
-    if (type is InvalidType) {
-      return false;
+    final packingAnnotations = _getPackedAnnotations(node);
+    if (packingAnnotations.length > 1) {
+      diagnosticReporter.report(
+          templateFfiPackedAnnotation.withArguments(node.name),
+          node.fileOffset,
+          node.name.length,
+          node.location.file);
     }
-    return env.isSubtypeOf(
-        type,
-        InterfaceType(pointerClass, Nullability.legacy, [
-          InterfaceType(nativeTypesClasses[NativeType.kNativeType.index],
-              Nullability.legacy)
-        ]),
-        SubtypeCheckMode.ignoringNullabilities);
-  }
-
-  bool _isArrayType(DartType type) {
-    if (type is InvalidType) {
-      return false;
-    }
-    return env.isSubtypeOf(
-        type,
-        InterfaceType(cArrayClass, Nullability.legacy, [
-          InterfaceType(nativeTypesClasses[NativeType.kNativeType.index],
-              Nullability.legacy)
-        ]),
-        SubtypeCheckMode.ignoringNullabilities);
-  }
-
-  bool _isStructSubtype(DartType type) {
-    if (type is InvalidType) {
-      return false;
-    }
-    if (type is NullType) {
-      return false;
-    }
-    if (type is InterfaceType) {
-      if (type.classNode == structClass) {
-        return false;
+    if (packingAnnotations.isNotEmpty) {
+      final packing = packingAnnotations.first;
+      if (!(packing == 1 ||
+          packing == 2 ||
+          packing == 4 ||
+          packing == 8 ||
+          packing == 16)) {
+        diagnosticReporter.report(messageFfiPackedAnnotationAlignment,
+            node.fileOffset, node.name.length, node.location.file);
       }
+      return packing;
     }
-    return env.isSubtypeOf(type, InterfaceType(structClass, Nullability.legacy),
-        SubtypeCheckMode.ignoringNullabilities);
+    return null;
   }
 
   /// Returns members of [node] that correspond to struct fields.
@@ -284,7 +268,7 @@
     return p.function.positionalParameters.single.type;
   }
 
-  bool _checkFieldAnnotations(Class node) {
+  bool _checkFieldAnnotations(Class node, int packing) {
     bool success = true;
     structClassDependencies[node] = {};
     final membersWithAnnotations = _structFieldMembers(node)
@@ -311,9 +295,9 @@
             f.fileUri);
         // This class is invalid, but continue reporting other errors on it.
         success = false;
-      } else if (_isPointerType(type) ||
-          _isStructSubtype(type) ||
-          _isArrayType(type)) {
+      } else if (isPointerType(type) ||
+          isStructSubtype(type) ||
+          isArrayType(type)) {
         if (nativeTypeAnnos.length != 0) {
           diagnosticReporter.report(
               templateFfiFieldNoAnnotation.withArguments(f.name.text),
@@ -323,24 +307,26 @@
           // This class is invalid, but continue reporting other errors on it.
           success = false;
         }
-        if (_isStructSubtype(type)) {
+        if (isStructSubtype(type)) {
           final clazz = (type as InterfaceType).classNode;
           structClassDependencies[node].add(clazz);
-        } else if (_isArrayType(type)) {
+          _checkPacking(node, packing, clazz, f);
+        } else if (isArrayType(type)) {
           final sizeAnnotations = _getArraySizeAnnotations(f);
           if (sizeAnnotations.length == 1) {
-            final typeArgument = (type as InterfaceType).typeArguments.single;
-            if (_isStructSubtype(typeArgument)) {
-              final clazz = (typeArgument as InterfaceType).classNode;
+            final singleElementType = arraySingleElementType(type);
+            if (isStructSubtype(singleElementType)) {
+              final clazz = (singleElementType as InterfaceType).classNode;
               structClassDependencies[node].add(clazz);
-            } else if (_isArrayType(typeArgument)) {
+              _checkPacking(node, packing, clazz, f);
+            }
+            if (arrayDimensions(type) != sizeAnnotations.single.length) {
               diagnosticReporter.report(
-                  templateFfiTypeInvalid.withArguments(
-                      typeArgument, currentLibrary.isNonNullableByDefault),
+                  templateFfiSizeAnnotationDimensions
+                      .withArguments(f.name.text),
                   f.fileOffset,
                   f.name.text.length,
                   f.fileUri);
-              success = false;
             }
           } else {
             diagnosticReporter.report(
@@ -384,6 +370,35 @@
     return success;
   }
 
+  void _checkPacking(Class outerClass, int outerClassPacking, Class fieldClass,
+      Member errorNode) {
+    if (outerClassPacking == null) {
+      // Outer struct has no packing, nesting anything is fine.
+      return;
+    }
+
+    final fieldPackingAnnotations = _getPackedAnnotations(fieldClass);
+    bool error = false;
+    if (fieldPackingAnnotations.isEmpty) {
+      // Outer struct has packing but inner one doesn't.
+      error = true;
+    } else {
+      final fieldPacking = fieldPackingAnnotations.first;
+      if (fieldPacking > outerClassPacking) {
+        // Outer struct has stricter packing than the inner.
+        error = true;
+      }
+    }
+    if (error) {
+      diagnosticReporter.report(
+          templateFfiPackedNestingNonPacked.withArguments(
+              fieldClass.name, outerClass.name),
+          errorNode.fileOffset,
+          errorNode.name.text.length,
+          errorNode.fileUri);
+    }
+  }
+
   void _checkConstructors(Class node, IndexedClass indexedClass) {
     final toRemove = <Initializer>[];
 
@@ -446,38 +461,17 @@
       final dartType = _structFieldMemberType(m);
 
       NativeTypeCfe type;
-      if (_isPointerType(dartType)) {
-        type = PointerNativeTypeCfe();
-      } else if (_isStructSubtype(dartType)) {
-        final clazz = (dartType as InterfaceType).classNode;
-        type = structCache[clazz];
-        if (emptyStructs.contains(clazz)) {
-          diagnosticReporter.report(
-              templateFfiEmptyStruct.withArguments(clazz.name),
-              m.fileOffset,
-              1,
-              m.location.file);
-        }
-      } else if (_isArrayType(dartType)) {
+      if (isArrayType(dartType)) {
         final sizeAnnotations = _getArraySizeAnnotations(m).toList();
         if (sizeAnnotations.length == 1) {
-          final elementClass =
-              ((dartType as InterfaceType).typeArguments[0] as InterfaceType)
-                  .classNode;
-          final elementNativeType =
-              _getFieldType(elementClass) ?? NativeType.kStruct;
-          final arraySize = sizeAnnotations.single;
-          if (elementNativeType == NativeType.kStruct) {
-            type = ArrayNativeTypeCfe(structCache[elementClass], arraySize);
-          } else if (elementNativeType == NativeType.kPointer) {
-            type = ArrayNativeTypeCfe(PointerNativeTypeCfe(), arraySize);
-          } else {
-            type = ArrayNativeTypeCfe(
-                PrimitiveNativeTypeCfe(elementNativeType, elementClass),
-                arraySize);
-          }
+          final arrayDimensions = sizeAnnotations.single;
+          type = NativeTypeCfe(this, dartType,
+              structCache: structCache, arrayDimensions: arrayDimensions);
         }
+      } else if (isPointerType(dartType) || isStructSubtype(dartType)) {
+        type = NativeTypeCfe(this, dartType, structCache: structCache);
       } else {
+        // The C type is in the annotation, not the field type itself.
         final nativeTypeAnnos = _getNativeTypeAnnotations(m).toList();
         if (nativeTypeAnnos.length == 1) {
           final clazz = nativeTypeAnnos.first;
@@ -504,22 +498,27 @@
       }
     }
 
-    _annoteStructWithFields(node, types);
+    final packingAnnotations = _getPackedAnnotations(node);
+    final packing =
+        (!packingAnnotations.isEmpty) ? packingAnnotations.first : null;
+
+    _annoteStructWithFields(node, types, packing);
     if (types.isEmpty) {
       diagnosticReporter.report(templateFfiEmptyStruct.withArguments(node.name),
           node.fileOffset, node.name.length, node.location.file);
       emptyStructs.add(node);
     }
 
-    final structType = StructNativeTypeCfe(node, types);
+    final structType = StructNativeTypeCfe(node, types, packing: packing);
     structCache[node] = structType;
     final structLayout = structType.layout;
 
+    final unalignedAccess = packing != null;
     for (final i in fields.keys) {
       final fieldOffsets = structLayout
           .map((Abi abi, StructLayout v) => MapEntry(abi, v.offsets[i]));
       final methods = _generateMethodsForField(
-          fields[i], types[i], fieldOffsets, indexedClass);
+          fields[i], types[i], fieldOffsets, unalignedAccess, indexedClass);
       methods.forEach((p) => node.addProcedure(p));
     }
 
@@ -532,7 +531,11 @@
           .map((Abi abi, StructLayout v) => MapEntry(abi, v.offsets[i]));
       Procedure getter = getters[i];
       getter.function.body = types[i].generateGetterStatement(
-          getter.function.returnType, getter.fileOffset, fieldOffsets, this);
+          getter.function.returnType,
+          getter.fileOffset,
+          fieldOffsets,
+          unalignedAccess,
+          this);
       getter.isExternal = false;
     }
 
@@ -544,6 +547,7 @@
           setter.function.positionalParameters.single.type,
           setter.fileOffset,
           fieldOffsets,
+          unalignedAccess,
           setter.function.positionalParameters.single,
           this);
       setter.isExternal = false;
@@ -552,7 +556,9 @@
     return structLayout.map((k, v) => MapEntry(k, v.size));
   }
 
-  void _annoteStructWithFields(Class node, List<NativeTypeCfe> types) {
+  // packing is `int?`.
+  void _annoteStructWithFields(
+      Class node, List<NativeTypeCfe> types, int packing) {
     List<Constant> constants =
         types.map((t) => t.generateConstant(this)).toList();
 
@@ -562,37 +568,51 @@
           pragmaOptions.getterReference:
               InstanceConstant(ffiStructLayoutClass.reference, [], {
             ffiStructLayoutTypesField.getterReference: ListConstant(
-                InterfaceType(typeClass, Nullability.nonNullable), constants)
+                InterfaceType(typeClass, Nullability.nonNullable), constants),
+            ffiStructLayoutPackingField.getterReference:
+                packing == null ? NullConstant() : IntConstant(packing)
           })
         }),
         InterfaceType(pragmaClass, Nullability.nonNullable, [])));
   }
 
   List<Procedure> _generateMethodsForField(Field field, NativeTypeCfe type,
-      Map<Abi, int> offsets, IndexedClass indexedClass) {
+      Map<Abi, int> offsets, bool unalignedAccess, IndexedClass indexedClass) {
+    // TODO(johnniwinther): Avoid passing [indexedClass]. When compiling
+    // incrementally, [field] should already carry the references from
+    // [indexedClass].
     final getterStatement = type.generateGetterStatement(
-        field.type, field.fileOffset, offsets, this);
+        field.type, field.fileOffset, offsets, unalignedAccess, this);
+    Reference getterReference =
+        indexedClass?.lookupGetterReference(field.name) ??
+            field.getterReference;
+    assert(getterReference == field.getterReference,
+        "Unexpected getter reference for ${field}, found $getterReference.");
     final Procedure getter = Procedure(field.name, ProcedureKind.Getter,
         FunctionNode(getterStatement, returnType: field.type),
-        fileUri: field.fileUri,
-        reference: indexedClass?.lookupGetterReference(field.name))
+        fileUri: field.fileUri, reference: getterReference)
       ..fileOffset = field.fileOffset
       ..isNonNullableByDefault = field.isNonNullableByDefault;
 
     Procedure setter = null;
     if (!field.isFinal) {
+      Reference setterReference =
+          indexedClass?.lookupSetterReference(field.name) ??
+              field.setterReference;
+      assert(setterReference == field.setterReference,
+          "Unexpected setter reference for ${field}, found $setterReference.");
       final VariableDeclaration argument =
           VariableDeclaration('#v', type: field.type)
             ..fileOffset = field.fileOffset;
-      final setterStatement = type.generateSetterStatement(
-          field.type, field.fileOffset, offsets, argument, this);
+      final setterStatement = type.generateSetterStatement(field.type,
+          field.fileOffset, offsets, unalignedAccess, argument, this);
       setter = Procedure(
           field.name,
           ProcedureKind.Setter,
           FunctionNode(setterStatement,
               returnType: VoidType(), positionalParameters: [argument]),
           fileUri: field.fileUri,
-          reference: indexedClass?.lookupSetterReference(field.name))
+          reference: setterReference)
         ..fileOffset = field.fileOffset
         ..isNonNullableByDefault = field.isNonNullableByDefault;
     }
@@ -648,13 +668,52 @@
         .where((klass) => _getFieldType(klass) != null);
   }
 
-  Iterable<int> _getArraySizeAnnotations(Member node) {
+  Iterable<List<int>> _getArraySizeAnnotations(Member node) {
     return node.annotations
         .whereType<ConstantExpression>()
         .map((e) => e.constant)
         .whereType<InstanceConstant>()
-        .where((e) => e.classNode == cArraySizeClass)
-        .map((e) => (e.fieldValues.values.single as IntConstant).value);
+        .where((e) => e.classNode == arraySizeClass)
+        .map(_arraySize);
+  }
+
+  List<int> _arraySize(InstanceConstant constant) {
+    final dimensions =
+        constant.fieldValues[arraySizeDimensionsField.getterReference];
+    if (dimensions != null) {
+      if (dimensions is ListConstant) {
+        final result = dimensions.entries
+            .whereType<IntConstant>()
+            .map((e) => e.value)
+            .toList();
+        assert(result.length > 0);
+        return result;
+      }
+    }
+    final dimensionFields = [
+      arraySizeDimension1Field,
+      arraySizeDimension2Field,
+      arraySizeDimension3Field,
+      arraySizeDimension4Field,
+      arraySizeDimension5Field
+    ];
+    final result = dimensionFields
+        .map((f) => constant.fieldValues[f.getterReference])
+        .whereType<IntConstant>()
+        .map((c) => c.value)
+        .toList();
+    return result;
+  }
+
+  Iterable<int> _getPackedAnnotations(Class node) {
+    return node.annotations
+        .whereType<ConstantExpression>()
+        .map((expr) => expr.constant)
+        .whereType<InstanceConstant>()
+        .where((e) => e.classNode == packedClass)
+        .map((e) => e.fieldValues.values.single)
+        .whereType<IntConstant>()
+        .map((e) => e.value);
   }
 }
 
@@ -677,6 +736,37 @@
 /// This algebraic data structure does not stand on its own but refers
 /// intimately to AST nodes such as [Class].
 abstract class NativeTypeCfe {
+  factory NativeTypeCfe(FfiTransformer transformer, DartType dartType,
+      {List<int> arrayDimensions,
+      Map<Class, StructNativeTypeCfe> structCache = const {}}) {
+    if (transformer.isPrimitiveType(dartType)) {
+      final clazz = (dartType as InterfaceType).classNode;
+      final nativeType = transformer.getType(clazz);
+      return PrimitiveNativeTypeCfe(nativeType, clazz);
+    }
+    if (transformer.isPointerType(dartType)) {
+      return PointerNativeTypeCfe();
+    }
+    if (transformer.isStructSubtype(dartType)) {
+      final clazz = (dartType as InterfaceType).classNode;
+      if (structCache.containsKey(clazz)) {
+        return structCache[clazz];
+      } else {
+        throw "$clazz not found in structCache";
+      }
+    }
+    if (transformer.isArrayType(dartType)) {
+      if (arrayDimensions == null) {
+        throw "Must have array dimensions for ArrayType";
+      }
+      final elementType = transformer.arraySingleElementType(dartType);
+      final elementCfeType =
+          NativeTypeCfe(transformer, elementType, structCache: structCache);
+      return ArrayNativeTypeCfe.multi(elementCfeType, arrayDimensions);
+    }
+    throw "Invalid type $dartType";
+  }
+
   /// The size in bytes per [Abi].
   Map<Abi, int> get size;
 
@@ -696,7 +786,7 @@
   ///
   /// Takes [transformer] to be able to lookup classes and methods.
   ReturnStatement generateGetterStatement(DartType dartType, int fileOffset,
-      Map<Abi, int> offsets, FfiTransformer transformer);
+      Map<Abi, int> offsets, bool unalignedAccess, FfiTransformer transformer);
 
   /// Generates the return statement for a struct field setter with this type.
   ///
@@ -705,6 +795,7 @@
       DartType dartType,
       int fileOffset,
       Map<Abi, int> offsets,
+      bool unalignedAccess,
       VariableDeclaration argument,
       FfiTransformer transformer);
 }
@@ -733,16 +824,37 @@
   Constant generateConstant(FfiTransformer transformer) =>
       TypeLiteralConstant(InterfaceType(clazz, Nullability.nonNullable));
 
+  bool get isFloat =>
+      nativeType == NativeType.kFloat || nativeType == NativeType.kDouble;
+
+  bool isUnaligned(Map<Abi, int> offsets) {
+    final alignments = alignment;
+    for (final abi in offsets.keys) {
+      final offset = offsets[abi];
+      final alignment = alignments[abi];
+      if (offset % alignment != 0) {
+        return true;
+      }
+    }
+    return false;
+  }
+
   /// Sample output for `int get x =>`:
   ///
   /// ```
   /// _loadInt8(_addressOf, offset);
   /// ```
   @override
-  ReturnStatement generateGetterStatement(DartType dartType, int fileOffset,
-          Map<Abi, int> offsets, FfiTransformer transformer) =>
+  ReturnStatement generateGetterStatement(
+          DartType dartType,
+          int fileOffset,
+          Map<Abi, int> offsets,
+          bool unalignedAccess,
+          FfiTransformer transformer) =>
       ReturnStatement(StaticInvocation(
-          transformer.loadMethods[nativeType],
+          (unalignedAccess && isFloat
+              ? transformer.loadUnalignedMethods
+              : transformer.loadMethods)[nativeType],
           Arguments([
             PropertyGet(ThisExpression(), transformer.addressOfField.name,
                 transformer.addressOfField)
@@ -761,10 +873,13 @@
           DartType dartType,
           int fileOffset,
           Map<Abi, int> offsets,
+          bool unalignedAccess,
           VariableDeclaration argument,
           FfiTransformer transformer) =>
       ReturnStatement(StaticInvocation(
-          transformer.storeMethods[nativeType],
+          (unalignedAccess && isFloat
+              ? transformer.storeUnalignedMethods
+              : transformer.storeMethods)[nativeType],
           Arguments([
             PropertyGet(ThisExpression(), transformer.addressOfField.name,
                 transformer.addressOfField)
@@ -795,8 +910,12 @@
   /// _fromAddress<Int8>(_loadIntPtr(_addressOf, offset));
   /// ```
   @override
-  ReturnStatement generateGetterStatement(DartType dartType, int fileOffset,
-          Map<Abi, int> offsets, FfiTransformer transformer) =>
+  ReturnStatement generateGetterStatement(
+          DartType dartType,
+          int fileOffset,
+          Map<Abi, int> offsets,
+          bool unalignedAccess,
+          FfiTransformer transformer) =>
       ReturnStatement(StaticInvocation(
           transformer.fromAddressInternal,
           Arguments([
@@ -824,6 +943,7 @@
           DartType dartType,
           int fileOffset,
           Map<Abi, int> offsets,
+          bool unalignedAccess,
           VariableDeclaration argument,
           FfiTransformer transformer) =>
       ReturnStatement(StaticInvocation(
@@ -845,23 +965,31 @@
 
   final List<NativeTypeCfe> members;
 
+  // Nullable int.
+  final int packing;
+
   final Map<Abi, StructLayout> layout;
 
-  factory StructNativeTypeCfe(Class clazz, List<NativeTypeCfe> members) {
-    final layout = Map.fromEntries(
-        Abi.values.map((abi) => MapEntry(abi, _calculateLayout(members, abi))));
-    return StructNativeTypeCfe._(clazz, members, layout);
+  factory StructNativeTypeCfe(Class clazz, List<NativeTypeCfe> members,
+      {int packing}) {
+    final layout = Map.fromEntries(Abi.values
+        .map((abi) => MapEntry(abi, _calculateLayout(members, packing, abi))));
+    return StructNativeTypeCfe._(clazz, members, packing, layout);
   }
 
   // Keep consistent with runtime/vm/compiler/ffi/native_type.cc
   // NativeCompoundType::FromNativeTypes.
-  static StructLayout _calculateLayout(List<NativeTypeCfe> types, Abi abi) {
+  static StructLayout _calculateLayout(
+      List<NativeTypeCfe> types, int packing, Abi abi) {
     int offset = 0;
     final offsets = <int>[];
     int structAlignment = 1;
     for (int i = 0; i < types.length; i++) {
       final int size = types[i].size[abi];
-      final int alignment = types[i].alignment[abi];
+      int alignment = types[i].alignment[abi];
+      if (packing != null && packing < alignment) {
+        alignment = packing;
+      }
       offset = _alignOffset(offset, alignment);
       offsets.add(offset);
       offset += size;
@@ -871,7 +999,7 @@
     return StructLayout(size, structAlignment, offsets);
   }
 
-  StructNativeTypeCfe._(this.clazz, this.members, this.layout);
+  StructNativeTypeCfe._(this.clazz, this.members, this.packing, this.layout);
 
   @override
   Map<Abi, int> get size =>
@@ -894,7 +1022,7 @@
   /// ```
   @override
   ReturnStatement generateGetterStatement(DartType dartType, int fileOffset,
-      Map<Abi, int> offsets, FfiTransformer transformer) {
+      Map<Abi, int> offsets, bool unalignedAccess, FfiTransformer transformer) {
     final constructor = clazz.constructors
         .firstWhere((c) => c.name == Name("#fromTypedDataBase"));
 
@@ -923,6 +1051,7 @@
           DartType dartType,
           int fileOffset,
           Map<Abi, int> offsets,
+          bool unalignedAccess,
           VariableDeclaration argument,
           FfiTransformer transformer) =>
       ReturnStatement(StaticInvocation(
@@ -947,6 +1076,37 @@
 
   ArrayNativeTypeCfe(this.elementType, this.length);
 
+  factory ArrayNativeTypeCfe.multi(
+      NativeTypeCfe elementType, List<int> dimensions) {
+    if (dimensions.length == 1) {
+      return ArrayNativeTypeCfe(elementType, dimensions.single);
+    }
+    return ArrayNativeTypeCfe(
+        ArrayNativeTypeCfe.multi(elementType, dimensions.sublist(1)),
+        dimensions.first);
+  }
+
+  List<int> get dimensions {
+    final elementType = this.elementType;
+    if (elementType is ArrayNativeTypeCfe) {
+      return [length, ...elementType.dimensions];
+    }
+    return [length];
+  }
+
+  List<int> get nestedDimensions => dimensions.sublist(1);
+
+  int get dimensionsFlattened =>
+      dimensions.fold(1, (accumulator, element) => accumulator * element);
+
+  NativeTypeCfe get singleElementType {
+    final elementType = this.elementType;
+    if (elementType is ArrayNativeTypeCfe) {
+      return elementType.singleElementType;
+    }
+    return elementType;
+  }
+
   @override
   Map<Abi, int> get size =>
       elementType.size.map((abi, size) => MapEntry(abi, size * length));
@@ -954,13 +1114,14 @@
   @override
   Map<Abi, int> get alignment => elementType.alignment;
 
+  // Note that we flatten multi dimensional arrays.
   @override
   Constant generateConstant(FfiTransformer transformer) =>
       InstanceConstant(transformer.ffiInlineArrayClass.reference, [], {
         transformer.ffiInlineArrayElementTypeField.getterReference:
-            elementType.generateConstant(transformer),
+            singleElementType.generateConstant(transformer),
         transformer.ffiInlineArrayLengthField.getterReference:
-            IntConstant(length)
+            IntConstant(dimensionsFlattened)
       });
 
   /// Sample output for `Array<Int8> get x =>`:
@@ -972,11 +1133,11 @@
   /// ```
   @override
   ReturnStatement generateGetterStatement(DartType dartType, int fileOffset,
-      Map<Abi, int> offsets, FfiTransformer transformer) {
+      Map<Abi, int> offsets, bool unalignedAccess, FfiTransformer transformer) {
     InterfaceType typeArgument =
         (dartType as InterfaceType).typeArguments.single as InterfaceType;
     return ReturnStatement(ConstructorInvocation(
-        transformer.cArrayConstructor,
+        transformer.arrayConstructor,
         Arguments([
           transformer.typedDataBaseOffset(
               PropertyGet(ThisExpression(), transformer.addressOfField.name,
@@ -986,9 +1147,10 @@
               transformer.runtimeBranchOnLayout(size),
               typeArgument,
               fileOffset),
-          ConstantExpression(IntConstant(length))
+          ConstantExpression(IntConstant(length)),
+          transformer.intListConstantExpression(nestedDimensions)
         ], types: [
-          dartType
+          typeArgument
         ]))
       ..fileOffset = fileOffset);
   }
@@ -1003,6 +1165,7 @@
           DartType dartType,
           int fileOffset,
           Map<Abi, int> offsets,
+          bool unalignedAccess,
           VariableDeclaration argument,
           FfiTransformer transformer) =>
       ReturnStatement(StaticInvocation(
@@ -1014,8 +1177,8 @@
             transformer.runtimeBranchOnLayout(offsets),
             PropertyGet(
                 VariableGet(argument),
-                transformer.cArrayTypedDataBaseField.name,
-                transformer.cArrayTypedDataBaseField)
+                transformer.arrayTypedDataBaseField.name,
+                transformer.arrayTypedDataBaseField)
               ..fileOffset = fileOffset,
             ConstantExpression(IntConstant(0)),
             transformer.runtimeBranchOnLayout(size),
diff --git a/pkg/vm/lib/transformations/ffi_use_sites.dart b/pkg/vm/lib/transformations/ffi_use_sites.dart
index 377721f..aad89d8 100644
--- a/pkg/vm/lib/transformations/ffi_use_sites.dart
+++ b/pkg/vm/lib/transformations/ffi_use_sites.dart
@@ -188,6 +188,20 @@
         _ensureNativeTypeValid(nativeType, node, allowStructItself: false);
 
         return _replaceRefArray(node);
+      } else if (target == arrayArrayElemAt) {
+        final DartType nativeType = node.arguments.types[0];
+
+        _ensureNativeTypeValid(nativeType, node,
+            allowStructItself: false, allowInlineArray: true);
+
+        return _replaceArrayArrayElemAt(node);
+      } else if (target == arrayArrayAssignAt) {
+        final DartType nativeType = node.arguments.types[0];
+
+        _ensureNativeTypeValid(nativeType, node,
+            allowStructItself: false, allowInlineArray: true);
+
+        return _replaceArrayArrayElemAt(node, setter: true);
       } else if (target == sizeOfMethod) {
         final DartType nativeType = node.arguments.types[0];
 
@@ -469,7 +483,7 @@
 
     final typedDataBasePrime = typedDataBaseOffset(
         PropertyGet(NullCheck(node.arguments.positional[0]),
-            cArrayTypedDataBaseField.name, cArrayTypedDataBaseField),
+            arrayTypedDataBaseField.name, arrayTypedDataBaseField),
         MethodInvocation(node.arguments.positional[1], numMultiplication.name,
             Arguments([StaticGet(clazz.fields.single)]), numMultiplication),
         StaticGet(clazz.fields.single),
@@ -479,6 +493,146 @@
     return ConstructorInvocation(constructor, Arguments([typedDataBasePrime]));
   }
 
+  /// Generates an expression that returns a new `Array<dartType>`.
+  ///
+  /// Sample input getter:
+  /// ```
+  /// this<Array<T>>[index]
+  /// ```
+  ///
+  /// Sample output getter:
+  ///
+  /// ```
+  /// Array #array = this!;
+  /// int #index = index!;
+  /// #array._checkIndex(#index);
+  /// int #singleElementSize = _inlineSizeOf<innermost(T)>();
+  /// int #elementSize = #array.nestedDimensionsFlattened * #singleElementSize;
+  /// int #offset = #elementSize * #index;
+  ///
+  /// new Array<T>._(
+  ///   typedDataBaseOffset(#array._typedDataBase, #offset, #elementSize),
+  ///   #array.nestedDimensionsFirst,
+  ///   #array.nestedDimensionsRest
+  /// )
+  /// ```
+  ///
+  /// Sample input setter:
+  /// ```
+  /// this<Array<T>>[index] = value
+  /// ```
+  ///
+  /// Sample output setter:
+  ///
+  /// ```
+  /// Array #array = this!;
+  /// int #index = index!;
+  /// #array._checkIndex(#index);
+  /// int #singleElementSize = _inlineSizeOf<innermost(T)>();
+  /// int #elementSize = #array.nestedDimensionsFlattened * #singleElementSize;
+  /// int #offset = #elementSize * #index;
+  ///
+  /// _memCopy(
+  ///   #array._typedDataBase, #offset, value._typedDataBase, 0, #elementSize)
+  /// ```
+  Expression _replaceArrayArrayElemAt(StaticInvocation node,
+      {bool setter: false}) {
+    final dartType = node.arguments.types[0];
+    final elementType = arraySingleElementType(dartType as InterfaceType);
+
+    final arrayVar = VariableDeclaration("#array",
+        initializer: NullCheck(node.arguments.positional[0]),
+        type: InterfaceType(arrayClass, Nullability.nonNullable))
+      ..fileOffset = node.fileOffset;
+    final indexVar = VariableDeclaration("#index",
+        initializer: NullCheck(node.arguments.positional[1]),
+        type: coreTypes.intNonNullableRawType)
+      ..fileOffset = node.fileOffset;
+    final singleElementSizeVar = VariableDeclaration("#singleElementSize",
+        initializer: _inlineSizeOf(elementType),
+        type: coreTypes.intNonNullableRawType)
+      ..fileOffset = node.fileOffset;
+    final elementSizeVar = VariableDeclaration("#elementSize",
+        initializer: MethodInvocation(
+            VariableGet(singleElementSizeVar),
+            numMultiplication.name,
+            Arguments([
+              PropertyGet(
+                  VariableGet(arrayVar),
+                  arrayNestedDimensionsFlattened.name,
+                  arrayNestedDimensionsFlattened)
+            ]),
+            numMultiplication),
+        type: coreTypes.intNonNullableRawType)
+      ..fileOffset = node.fileOffset;
+    final offsetVar = VariableDeclaration("#offset",
+        initializer: MethodInvocation(
+            VariableGet(elementSizeVar),
+            numMultiplication.name,
+            Arguments([
+              VariableGet(indexVar),
+            ]),
+            numMultiplication),
+        type: coreTypes.intNonNullableRawType)
+      ..fileOffset = node.fileOffset;
+
+    final checkIndexAndLocalVars = Block([
+      arrayVar,
+      indexVar,
+      ExpressionStatement(MethodInvocation(
+          VariableGet(arrayVar),
+          arrayCheckIndex.name,
+          Arguments([VariableGet(indexVar)]),
+          arrayCheckIndex)),
+      singleElementSizeVar,
+      elementSizeVar,
+      offsetVar
+    ]);
+
+    if (!setter) {
+      // `[]`
+      return BlockExpression(
+          checkIndexAndLocalVars,
+          ConstructorInvocation(
+              arrayConstructor,
+              Arguments([
+                typedDataBaseOffset(
+                    PropertyGet(VariableGet(arrayVar),
+                        arrayTypedDataBaseField.name, arrayTypedDataBaseField),
+                    VariableGet(offsetVar),
+                    VariableGet(elementSizeVar),
+                    dartType,
+                    node.fileOffset),
+                PropertyGet(
+                    VariableGet(arrayVar),
+                    arrayNestedDimensionsFirst.name,
+                    arrayNestedDimensionsFirst),
+                PropertyGet(VariableGet(arrayVar),
+                    arrayNestedDimensionsRest.name, arrayNestedDimensionsRest)
+              ], types: [
+                dartType
+              ])));
+    }
+
+    // `[]=`
+    return BlockExpression(
+        checkIndexAndLocalVars,
+        StaticInvocation(
+            memCopy,
+            Arguments([
+              PropertyGet(VariableGet(arrayVar), arrayTypedDataBaseField.name,
+                  arrayTypedDataBaseField)
+                ..fileOffset = node.fileOffset,
+              VariableGet(offsetVar),
+              PropertyGet(node.arguments.positional[2],
+                  arrayTypedDataBaseField.name, arrayTypedDataBaseField)
+                ..fileOffset = node.fileOffset,
+              ConstantExpression(IntConstant(0)),
+              VariableGet(elementSizeVar),
+            ]))
+          ..fileOffset = node.fileOffset);
+  }
+
   @override
   visitMethodInvocation(MethodInvocation node) {
     super.visitMethodInvocation(node);
@@ -543,11 +697,14 @@
   }
 
   void _ensureNativeTypeValid(DartType nativeType, Expression node,
-      {bool allowHandle: false, bool allowStructItself = true}) {
+      {bool allowHandle: false,
+      bool allowStructItself = true,
+      bool allowInlineArray = false}) {
     if (!_nativeTypeValid(nativeType,
         allowStructs: true,
         allowStructItself: allowStructItself,
-        allowHandle: allowHandle)) {
+        allowHandle: allowHandle,
+        allowInlineArray: allowInlineArray)) {
       diagnosticReporter.report(
           templateFfiTypeInvalid.withArguments(
               nativeType, currentLibrary.isNonNullableByDefault),
@@ -586,11 +743,13 @@
   bool _nativeTypeValid(DartType nativeType,
       {bool allowStructs: false,
       bool allowStructItself = false,
-      bool allowHandle = false}) {
+      bool allowHandle = false,
+      bool allowInlineArray = false}) {
     return convertNativeTypeToDartType(nativeType,
             allowStructs: allowStructs,
             allowStructItself: allowStructItself,
-            allowHandle: allowHandle) !=
+            allowHandle: allowHandle,
+            allowInlineArray: allowInlineArray) !=
         null;
   }
 
@@ -621,7 +780,7 @@
           : null;
     }
 
-    if (!nativeTypesClasses.contains(klass) && klass != cArrayClass) {
+    if (!nativeTypesClasses.contains(klass) && klass != arrayClass) {
       for (final parent in nativeTypesClasses) {
         if (hierarchy.isSubtypeOf(klass, parent)) {
           return parent;
diff --git a/pkg/vm/lib/transformations/pragma.dart b/pkg/vm/lib/transformations/pragma.dart
index d27f3d8..cde363a 100644
--- a/pkg/vm/lib/transformations/pragma.dart
+++ b/pkg/vm/lib/transformations/pragma.dart
@@ -13,6 +13,7 @@
 const kResultTypeUsesPassedTypeArguments =
     "result-type-uses-passed-type-arguments";
 const kRecognizedPragmaName = "vm:recognized";
+const kDisableUnboxedParametetersPragmaName = "vm:disable-unboxed-parameters";
 
 abstract class ParsedPragma {}
 
@@ -46,6 +47,10 @@
   ParsedRecognized(this.type);
 }
 
+class ParsedDisableUnboxedParameters extends ParsedPragma {
+  ParsedDisableUnboxedParameters();
+}
+
 abstract class PragmaAnnotationParser {
   /// May return 'null' if the annotation does not represent a recognized
   /// @pragma.
@@ -142,6 +147,8 @@
               "pragma: $options";
         }
         return new ParsedRecognized(type);
+      case kDisableUnboxedParametetersPragmaName:
+        return new ParsedDisableUnboxedParameters();
       default:
         return null;
     }
diff --git a/pkg/vm/lib/transformations/type_flow/analysis.dart b/pkg/vm/lib/transformations/type_flow/analysis.dart
index 45d05d8..c8a530d 100644
--- a/pkg/vm/lib/transformations/type_flow/analysis.dart
+++ b/pkg/vm/lib/transformations/type_flow/analysis.dart
@@ -1636,14 +1636,13 @@
   /// ---- Implementation of [EntryPointsListener] interface. ----
 
   @override
-  void addDirectFieldAccess(Field field, Type value) {
+  void addFieldUsedInConstant(Field field, Type instance, Type value) {
+    assert(!field.isStatic);
     final fieldValue = getFieldValue(field);
-    if (field.isStatic) {
-      fieldValue.setValue(value, this, /*receiver_type=*/ null);
-    } else {
-      final receiver = new ConeType(hierarchyCache.getTFClass(field.parent));
-      fieldValue.setValue(value, this, receiver);
-    }
+    fieldValue.setValue(value, this, instance);
+    // Make sure the field is retained as removing fields used in constants
+    // may affect identity of the constants.
+    fieldValue.isGetterUsed = true;
   }
 
   @override
diff --git a/pkg/vm/lib/transformations/type_flow/native_code.dart b/pkg/vm/lib/transformations/type_flow/native_code.dart
index 2a67d18..e24408b 100644
--- a/pkg/vm/lib/transformations/type_flow/native_code.dart
+++ b/pkg/vm/lib/transformations/type_flow/native_code.dart
@@ -21,7 +21,7 @@
   void addRawCall(Selector selector);
 
   /// Sets the type of the given field.
-  void addDirectFieldAccess(Field field, Type value);
+  void addFieldUsedInConstant(Field field, Type instance, Type value);
 
   /// Add instantiation of the given class.
   ConcreteType addAllocatedClass(Class c);
@@ -233,6 +233,19 @@
         (expectedTypes == null || expectedTypes.contains(type));
   }
 
+  bool hasDisableUnboxedParameters(Member member) {
+    for (var annotation in member.annotations) {
+      ParsedPragma pragma = _matcher.parsePragma(annotation);
+      if (pragma is ParsedDisableUnboxedParameters) {
+        if (member.enclosingLibrary.importUri.scheme != "dart") {
+          throw "ERROR: Cannot use @pragma(vm:disable-unboxed-parameters) outside core libraries.";
+        }
+        return true;
+      }
+    }
+    return false;
+  }
+
   /// 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/summary_collector.dart b/pkg/vm/lib/transformations/type_flow/summary_collector.dart
index 1756791..34c375b 100644
--- a/pkg/vm/lib/transformations/type_flow/summary_collector.dart
+++ b/pkg/vm/lib/transformations/type_flow/summary_collector.dart
@@ -2415,8 +2415,8 @@
     final resultClass = summaryCollector._entryPointsListener
         .addAllocatedClass(constant.classNode);
     constant.fieldValues.forEach((Reference fieldReference, Constant value) {
-      summaryCollector._entryPointsListener
-          .addDirectFieldAccess(fieldReference.asField, typeFor(value));
+      summaryCollector._entryPointsListener.addFieldUsedInConstant(
+          fieldReference.asField, resultClass, typeFor(value));
     });
     return new ConcreteType(resultClass.cls, null, constant);
   }
diff --git a/pkg/vm/lib/transformations/type_flow/transformer.dart b/pkg/vm/lib/transformations/type_flow/transformer.dart
index ac88a41..427af73 100644
--- a/pkg/vm/lib/transformations/type_flow/transformer.dart
+++ b/pkg/vm/lib/transformations/type_flow/transformer.dart
@@ -554,7 +554,17 @@
                   isFieldInitializerReachable(f) &&
                   mayHaveSideEffects(f.initializer)) ||
               (f.isLate && f.isFinal)) ||
-      isMemberReferencedFromNativeCode(f);
+      isMemberReferencedFromNativeCode(f) ||
+      _isInstanceFieldOfAllocatedEnum(f);
+
+  /// Preserve instance fields of allocated enums as VM relies on their
+  /// existence. Non-allocated enums are converted into ordinary classes during
+  /// the 2nd pass.
+  bool _isInstanceFieldOfAllocatedEnum(Field node) =>
+      !node.isStatic &&
+      node.enclosingClass != null &&
+      node.enclosingClass.isEnum &&
+      isClassAllocated(node.enclosingClass);
 
   void addClassUsedInType(Class c) {
     if (_classesUsedInType.add(c)) {
@@ -1166,9 +1176,10 @@
     if (_isUnreachable(node)) {
       return _makeUnreachableInitializer([node.value]);
     } else {
-      assert(shaker.isMemberBodyReachable(node.field),
-          "Field should be reachable: ${node.field}");
-      if (!shaker.retainField(node.field)) {
+      final field = node.field;
+      assert(shaker.isMemberBodyReachable(field),
+          "Field should be reachable: ${field}");
+      if (!shaker.retainField(field)) {
         if (mayHaveSideEffects(node.value)) {
           return LocalInitializer(
               VariableDeclaration(null, initializer: node.value));
@@ -1246,7 +1257,7 @@
     for (Source source in component.uriToSource.values) {
       source?.constantCoverageConstructors?.removeWhere((Reference reference) {
         Member node = reference.asMember;
-        return !shaker.isMemberUsed(node) && !_preserveSpecialMember(node);
+        return !shaker.isMemberUsed(node);
       });
     }
   }
@@ -1282,7 +1293,11 @@
       debugPrint('Dropped class ${node.name}');
       // Ensure that kernel file writer will not be able to
       // write a dangling reference to the deleted class.
-      node.reference.canonicalName = null;
+      assert(
+          node.reference.node == node,
+          "Trying to remove canonical name from reference on $node which has "
+          "been repurposed for ${node.reference.node}.");
+      node.reference.canonicalName?.unbind();
       Statistics.classesDropped++;
       return removalSentinel; // Remove the class.
     }
@@ -1297,6 +1312,7 @@
       node.implementedTypes.clear();
       node.typeParameters.clear();
       node.isAbstract = true;
+      node.isEnum = false;
       // Mixin applications cannot have static members.
       assert(node.mixedInType == null);
       node.annotations = const <Expression>[];
@@ -1305,6 +1321,7 @@
     if (!shaker.isClassAllocated(node)) {
       debugPrint('Class ${node.name} converted to abstract');
       node.isAbstract = true;
+      node.isEnum = false;
     }
 
     node.transformOrRemoveChildren(this);
@@ -1312,19 +1329,31 @@
     return node;
   }
 
-  /// Preserve instance fields of enums as VM relies on their existence.
-  bool _preserveSpecialMember(Member node) =>
-      node is Field &&
-      !node.isStatic &&
-      node.enclosingClass != null &&
-      node.enclosingClass.isEnum;
-
   @override
   Member defaultMember(Member node, TreeNode removalSentinel) {
-    if (!shaker.isMemberUsed(node) && !_preserveSpecialMember(node)) {
+    if (!shaker.isMemberUsed(node)) {
       // Ensure that kernel file writer will not be able to
       // write a dangling reference to the deleted member.
-      node.reference.canonicalName = null;
+      if (node is Field) {
+        assert(
+            node.getterReference.node == node,
+            "Trying to remove canonical name from getter reference on $node "
+            "which has been repurposed for ${node.getterReference.node}.");
+        node.getterReference.canonicalName?.unbind();
+        if (node.hasSetter) {
+          assert(
+              node.setterReference.node == node,
+              "Trying to remove canonical name from reference on $node which "
+              "has been repurposed for ${node.setterReference.node}.");
+          node.setterReference.canonicalName?.unbind();
+        }
+      } else {
+        assert(
+            node.reference.node == node,
+            "Trying to remove canonical name from reference on $node which has "
+            "been repurposed for ${node.reference.node}.");
+        node.reference.canonicalName?.unbind();
+      }
       Statistics.membersDropped++;
       return removalSentinel;
     }
diff --git a/pkg/vm/lib/transformations/type_flow/unboxing_info.dart b/pkg/vm/lib/transformations/type_flow/unboxing_info.dart
index 792dc99..03f7ef2 100644
--- a/pkg/vm/lib/transformations/type_flow/unboxing_info.dart
+++ b/pkg/vm/lib/transformations/type_flow/unboxing_info.dart
@@ -203,7 +203,8 @@
         _nativeCodeOracle.isRecognized(member, const [
           PragmaRecognizedType.AsmIntrinsic,
           PragmaRecognizedType.Other
-        ]);
+        ]) ||
+        _nativeCodeOracle.hasDisableUnboxedParameters(member);
   }
 
   bool _isNative(Member member) => getExternalName(member) != null;
diff --git a/pkg/vm/test/transformations/type_flow/summary_collector_test.dart b/pkg/vm/test/transformations/type_flow/summary_collector_test.dart
index a046634..cad4936 100644
--- a/pkg/vm/test/transformations/type_flow/summary_collector_test.dart
+++ b/pkg/vm/test/transformations/type_flow/summary_collector_test.dart
@@ -44,7 +44,7 @@
   void addRawCall(Selector selector) {}
 
   @override
-  void addDirectFieldAccess(Field field, Type value) {}
+  void addFieldUsedInConstant(Field field, Type instance, Type value) {}
 
   @override
   ConcreteType addAllocatedClass(Class c) {
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/enum_used_as_type.dart b/pkg/vm/testcases/transformations/type_flow/transformer/enum_used_as_type.dart
new file mode 100644
index 0000000..da8fb17
--- /dev/null
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/enum_used_as_type.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+enum Enum { a }
+
+class Class {
+  int method(Enum e) => e.index;
+}
+
+main() {
+  List list = [];
+  if (list.isNotEmpty) {
+    new Class().method(null as dynamic);
+  }
+}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/enum_used_as_type.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/enum_used_as_type.dart.expect
new file mode 100644
index 0000000..89d9a31
--- /dev/null
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/enum_used_as_type.dart.expect
@@ -0,0 +1,21 @@
+library #lib;
+import self as self;
+import "dart:core" as core;
+import "dart:_internal" as _in;
+
+abstract class Enum extends core::Object {
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:1]  abstract get index() → core::int*;
+}
+class Class extends core::Object {
+  synthetic constructor •() → self::Class*
+    : super core::Object::•()
+    ;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:2,getterSelectorId:3]  method method() → core::int*
+    return [@vm.inferred-type.metadata=!](#C1).{self::Enum::index};
+}
+static method main() → dynamic {
+  core::List<dynamic>* list = [@vm.inferred-type.metadata=dart.core::_GrowableList<dynamic>] core::_GrowableList::•<dynamic>(0);
+  if([@vm.direct-call.metadata=dart.core::_GrowableList.isNotEmpty] [@vm.inferred-type.metadata=dart.core::bool] list.{core::Iterable::isNotEmpty}) {
+    let final self::Class* #t1 = new self::Class::•() in let final self::Enum* #t2 = _in::unsafeCast<self::Enum*>(_in::unsafeCast<dynamic>(null)) in [@vm.direct-call.metadata=#lib::Class.method] [@vm.inferred-type.metadata=!? (skip check)] #t1.{self::Class::method}();
+  }
+}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/regress_45324.dart b/pkg/vm/testcases/transformations/type_flow/transformer/regress_45324.dart
new file mode 100644
index 0000000..76c439a
--- /dev/null
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/regress_45324.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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 {
+  final int targetPlatform;
+  const A(this.targetPlatform);
+
+  static const BAR = A(1);
+}
+
+class X implements A {
+  int get targetPlatform => 2;
+}
+
+A a = X();
+
+void main() {
+  print(a.targetPlatform);
+  print(A.BAR);
+}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/regress_45324.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/regress_45324.dart.expect
new file mode 100644
index 0000000..ad855f7
--- /dev/null
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/regress_45324.dart.expect
@@ -0,0 +1,19 @@
+library #lib;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object /*hasConstConstructor*/  {
+[@vm.inferred-type.metadata=dart.core::_Smi (value: 1)] [@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* targetPlatform;
+}
+class X extends core::Object implements self::A {
+  synthetic constructor •() → self::X*
+    : super core::Object::•()
+    ;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:1] [@vm.unboxing-info.metadata=()->i]  get targetPlatform() → core::int*
+    return 2;
+}
+[@vm.inferred-type.metadata=#lib::X?]static field self::A* a = new self::X::•();
+static method main() → void {
+  core::print([@vm.direct-call.metadata=#lib::X.targetPlatform??] [@vm.inferred-type.metadata=dart.core::_Smi (value: 2)] [@vm.inferred-type.metadata=#lib::X?] self::a.{self::A::targetPlatform});
+  core::print(#C2);
+}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/regress_45324_2.dart b/pkg/vm/testcases/transformations/type_flow/transformer/regress_45324_2.dart
new file mode 100644
index 0000000..6c4d972
--- /dev/null
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/regress_45324_2.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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.12
+
+class A {
+  void doTest(Z a) {
+    print(a.appName);
+  }
+}
+
+class Z {
+  final String? appName;
+  Z({this.appName});
+}
+
+class X extends Base implements Z {}
+
+class Base {
+  String get appName => 'x';
+}
+
+void main() {
+  Z();
+  A().doTest(X());
+}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/regress_45324_2.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/regress_45324_2.dart.expect
new file mode 100644
index 0000000..2ef7c98
--- /dev/null
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/regress_45324_2.dart.expect
@@ -0,0 +1,34 @@
+library #lib /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2]  method doTest([@vm.inferred-type.metadata=#lib::X] self::Z a) → void {
+    core::print([@vm.direct-call.metadata=#lib::Base.appName] [@vm.inferred-type.metadata=dart.core::_OneByteString (value: "x")] a.{self::Z::appName});
+  }
+}
+class Z extends core::Object {
+  constructor •() → self::Z
+    : super core::Object::•()
+    ;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:3]  abstract get /*isLegacy*/ appName() → core::String?;
+}
+class X extends self::Base implements self::Z {
+  synthetic constructor •() → self::X
+    : super self::Base::•()
+    ;
+}
+abstract class Base extends core::Object {
+  synthetic constructor •() → self::Base
+    : super core::Object::•()
+    ;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:3]  get appName() → core::String
+    return "x";
+}
+static method main() → void {
+  new self::Z::•();
+  [@vm.direct-call.metadata=#lib::A.doTest] [@vm.inferred-type.metadata=!? (skip check)] new self::A::•().{self::A::doTest}(new self::X::•());
+}
diff --git a/pkg/vm_service/CHANGELOG.md b/pkg/vm_service/CHANGELOG.md
index 97d2b78..2492753 100644
--- a/pkg/vm_service/CHANGELOG.md
+++ b/pkg/vm_service/CHANGELOG.md
@@ -1,6 +1,11 @@
 # Changelog
+
+## 6.2.0
+- Added support for `getHttpProfile` and `clearHttpProfile` `dart:io` service extensions.
+
 ## 6.1.1
 - Callsite `StackTrace`s are now attached to `RPCError`s and `SentinelException`s.
+- Added `identityHashCode` property to `InstanceRef` and `Instance`.
 
 ## 6.1.0+1
 - Documentation update.
diff --git a/pkg/vm_service/example/vm_service_assert.dart b/pkg/vm_service/example/vm_service_assert.dart
index 040f653..7122a12 100644
--- a/pkg/vm_service/example/vm_service_assert.dart
+++ b/pkg/vm_service/example/vm_service_assert.dart
@@ -605,6 +605,7 @@
   assertNotNull(obj);
   assertString(obj.id!);
   assertInstanceKind(obj.kind!);
+  assertInt(obj.identityHashCode!);
   assertClassRef(obj.classRef!);
   return obj;
 }
@@ -620,6 +621,7 @@
   assertNotNull(obj);
   assertString(obj.id!);
   assertInstanceKind(obj.kind!);
+  assertInt(obj.identityHashCode!);
   assertClassRef(obj.classRef!);
   return obj;
 }
@@ -831,6 +833,7 @@
   assertNotNull(obj);
   assertString(obj.id!);
   assertInstanceKind(obj.kind!);
+  assertInt(obj.identityHashCode!);
   assertClassRef(obj.classRef!);
   assertString(obj.valueAsString!);
   return obj;
@@ -847,6 +850,7 @@
   assertNotNull(obj);
   assertString(obj.id!);
   assertInstanceKind(obj.kind!);
+  assertInt(obj.identityHashCode!);
   assertClassRef(obj.classRef!);
   assertString(obj.valueAsString!);
   return obj;
diff --git a/pkg/vm_service/example/vm_service_tester.dart b/pkg/vm_service/example/vm_service_tester.dart
index 2406111..eb5158b 100644
--- a/pkg/vm_service/example/vm_service_tester.dart
+++ b/pkg/vm_service/example/vm_service_tester.dart
@@ -44,9 +44,7 @@
 
     // ignore: unawaited_futures
     process!.exitCode.then((code) => print('vm exited: ${code}'));
-    // ignore: strong_mode_down_cast_composite
     process!.stdout.transform(utf8.decoder).listen(print);
-    // ignore: strong_mode_down_cast_composite
     process!.stderr.transform(utf8.decoder).listen(print);
 
     await Future.delayed(Duration(milliseconds: 500));
@@ -76,7 +74,6 @@
       }
       expect(originalJson, isNotNull, reason: 'Unrecognized event type! $json');
 
-      // ignore: invalid_use_of_visible_for_testing_member
       var instance =
           createServiceObject(originalJson, const ['Event', 'Success']);
       expect(instance, isNotNull,
diff --git a/pkg/vm_service/java/version.properties b/pkg/vm_service/java/version.properties
index bdd96e7..452573e 100644
--- a/pkg/vm_service/java/version.properties
+++ b/pkg/vm_service/java/version.properties
@@ -1 +1 @@
-version=3.43
+version=3.44
diff --git a/pkg/vm_service/lib/src/dart_io_extensions.dart b/pkg/vm_service/lib/src/dart_io_extensions.dart
index 22581b3..73b3b84 100644
--- a/pkg/vm_service/lib/src/dart_io_extensions.dart
+++ b/pkg/vm_service/lib/src/dart_io_extensions.dart
@@ -5,8 +5,9 @@
 // TODO(bkonyi): autogenerate from service_extensions.md
 
 import 'dart:collection';
+import 'dart:typed_data';
 
-import 'vm_service.dart';
+import 'vm_service.dart' hide Error;
 
 extension DartIOExtension on VmService {
   static bool _factoriesRegistered = false;
@@ -81,7 +82,7 @@
         'enable': enable,
       });
 
-  /// The _httpEnableTimelineLogging_ RPC is used to set and inspect the value of
+  /// The `httpEnableTimelineLogging` RPC is used to set and inspect the value of
   /// `HttpClient.enableTimelineLogging`, which determines if HTTP client requests
   /// should be logged to the timeline. If `enabled` is provided, the state of
   /// `HttpClient.enableTimelineLogging` will be updated to the value of `enabled`.
@@ -102,6 +103,35 @@
         });
   }
 
+  /// The `getHttpProfile` RPC is used to retrieve HTTP profiling information
+  /// for requests made via `dart:io`'s `HttpClient`.
+  ///
+  /// The returned [HttpProfile] will only include requests issued after
+  /// `httpTimelineLogging` has been enabled or after the last
+  /// `clearHttpProfile` invocation.
+  ///
+  /// If `updatedSince` is provided, only requests started or updated since
+  /// the specified time will be reported.
+  Future<HttpProfile> getHttpProfile(String isolateId, {int? updatedSince}) =>
+      _callHelper('ext.dart.io.getHttpProfile', isolateId, args: {
+        if (updatedSince != null) 'updatedSince': updatedSince,
+      });
+
+  /// The `getHttpProfileRequest` RPC is used to retrieve an instance of
+  /// [HttpProfileRequest], which includes request and response body data.
+  Future<HttpProfileRequest> getHttpProfileRequest(String isolateId, int id) =>
+      _callHelper('ext.dart.io.getHttpProfileRequest', isolateId, args: {
+        'id': id,
+      });
+
+  /// The `clearHttpProfile` RPC is used to clear previously recorded HTTP
+  /// requests from the HTTP profiler state. Requests still in-flight after
+  /// clearing the profiler state will be ignored by the profiler.
+  Future<Success> clearHttpProfile(String isolateId) => _callHelper(
+        'ext.dart.io.clearHttpProfile',
+        isolateId,
+      );
+
   /// The `getOpenFiles` RPC is used to retrieve the list of files currently
   /// opened files by `dart:io` from a given isolate.
   Future<OpenFileList> getOpenFiles(String isolateId) => _callHelper(
@@ -164,6 +194,8 @@
     addTypeFactory('SocketProfile', SocketProfile.parse);
     addTypeFactory('SocketStatistic', SocketStatistic.parse);
     addTypeFactory('SocketProfilingState', SocketProfilingState.parse);
+    addTypeFactory('HttpProfile', HttpProfile.parse);
+    addTypeFactory('HttpProfileRequest', HttpProfileRequest.parse);
     _factoriesRegistered = true;
   }
 }
@@ -271,6 +303,427 @@
       : super._fromJson(json);
 }
 
+/// A collection of HTTP request data collected by the profiler.
+class HttpProfile extends Response {
+  static HttpProfile? parse(Map<String, dynamic>? json) =>
+      json == null ? null : HttpProfile._fromJson(json);
+
+  HttpProfile._fromJson(Map<String, dynamic> json)
+      : timestamp = json['timestamp'],
+        requests = (json['requests'] as List)
+            .cast<Map<String, dynamic>>()
+            .map((e) => HttpProfileRequest._fromJson(e))
+            .toList();
+
+  HttpProfile({required this.requests, required this.timestamp});
+
+  @override
+  String get type => 'HttpProfile';
+
+  @override
+  String toString() => '[HttpProfile]';
+
+  /// The time at which this HTTP profile was built, in microseconds.
+  final int timestamp;
+
+  /// The set of recorded HTTP requests.
+  final List<HttpProfileRequest> requests;
+}
+
+/// Profiling information for a single HTTP request.
+class HttpProfileRequestRef {
+  static HttpProfileRequestRef? parse(Map<String, dynamic>? json) =>
+      json == null ? null : HttpProfileRequestRef._fromJson(json);
+
+  HttpProfileRequestRef._fromJson(Map<String, dynamic> json)
+      : isolateId = json['isolateId'],
+        id = json['id'],
+        method = json['method'],
+        uri = Uri.parse(json['uri']),
+        startTime = json['startTime'],
+        endTime = json['endTime'],
+        request = HttpProfileRequestData.parse(json['request']),
+        response = HttpProfileResponseData.parse(json['response']);
+
+  HttpProfileRequestRef({
+    required this.isolateId,
+    required this.id,
+    required this.method,
+    required this.uri,
+    required this.startTime,
+    this.endTime,
+    this.request,
+    this.response,
+  });
+
+  // The ID of the isolate this request was issued from.
+  final String isolateId;
+
+  /// The ID associated with this request.
+  ///
+  /// This ID corresponds to the ID of the timeline event for this request.
+  final int id;
+
+  /// The HTTP request method associated with this request.
+  final String method;
+
+  /// The URI for this HTTP request.
+  final Uri uri;
+
+  /// The time at which this request was initiated, in microseconds.
+  final int startTime;
+
+  /// The time at which this request was completed, in microseconds.
+  ///
+  /// Will be `null` if the request is still in progress.
+  final int? endTime;
+
+  /// Returns `true` if the initial HTTP request has completed.
+  bool get isRequestComplete => endTime != null;
+
+  /// Returns `true` if the entirety of the response has been received.
+  bool get isResponseComplete => response?.isComplete ?? false;
+
+  /// Information sent as part of the initial HTTP request.
+  ///
+  /// Can be `null` if the request has not yet been completed.
+  final HttpProfileRequestData? request;
+
+  /// Information received in response to the initial HTTP request.
+  ///
+  /// Can be `null` if the request has not yet been responded to.
+  final HttpProfileResponseData? response;
+}
+
+/// Profiling information for a single HTTP request, including request and
+/// response body data.
+class HttpProfileRequest extends HttpProfileRequestRef {
+  static HttpProfileRequest? parse(Map<String, dynamic>? json) =>
+      json == null ? null : HttpProfileRequest._fromJson(json);
+
+  HttpProfileRequest._fromJson(Map<String, dynamic> json)
+      : requestBody =
+            Uint8List.fromList(json['requestBody']?.cast<int>() ?? <int>[]),
+        responseBody =
+            Uint8List.fromList(json['responseBody']?.cast<int>() ?? <int>[]),
+        super._fromJson(json);
+
+  HttpProfileRequest({
+    required int id,
+    required String isolateId,
+    required String method,
+    required Uri uri,
+    required int startTime,
+    required this.requestBody,
+    required this.responseBody,
+    int? endTime,
+    HttpProfileRequestData? request,
+    HttpProfileResponseData? response,
+  }) : super(
+          id: id,
+          isolateId: isolateId,
+          method: method,
+          uri: uri,
+          startTime: startTime,
+          endTime: endTime,
+          request: request,
+          response: response,
+        );
+
+  /// The body sent as part of this request.
+  ///
+  /// Data written to a request body before encountering an error will be
+  /// reported.
+  final Uint8List? requestBody;
+
+  /// The body received in response to the request.
+  final Uint8List? responseBody;
+}
+
+/// Information sent as part of the initial HTTP request.
+class HttpProfileRequestData {
+  static HttpProfileRequestData? parse(Map<String, dynamic>? json) =>
+      json == null ? null : HttpProfileRequestData._fromJson(json);
+
+  HttpProfileRequestData._fromJson(Map<String, dynamic> json)
+      : _headers = json['headers'],
+        _connectionInfo = UnmodifiableMapView(json['connectionInfo'] ?? {}),
+        _contentLength = json['contentLength'],
+        _cookies = UnmodifiableListView(json['cookies']?.cast<String>() ?? []),
+        _followRedirects = json['followRedirects'] ?? false,
+        _maxRedirects = json['maxRedirects'] ?? 0,
+        _method = json['method'],
+        _persistentConnection = json['persistentConnection'] ?? false,
+        proxyDetails = HttpProfileProxyData.parse(json['proxyDetails']),
+        error = json['error'],
+        events = UnmodifiableListView((json['events'] as List)
+            .cast<Map<String, dynamic>>()
+            .map((e) => HttpProfileRequestEvent._fromJson(e))
+            .toList());
+
+  HttpProfileRequestData.buildSuccessfulRequest({
+    required Map<String, dynamic> headers,
+    required Map<String, dynamic>? connectionInfo,
+    required int contentLength,
+    required List<String> cookies,
+    required bool followRedirects,
+    required int maxRedirects,
+    required String method,
+    required bool persistentConnection,
+    required this.events,
+    this.proxyDetails,
+  })  : _headers = headers,
+        _connectionInfo = connectionInfo,
+        _contentLength = contentLength,
+        _cookies = cookies,
+        _followRedirects = followRedirects,
+        _maxRedirects = maxRedirects,
+        _method = method,
+        _persistentConnection = persistentConnection,
+        error = null;
+
+  HttpProfileRequestData.buildErrorRequest({
+    required this.error,
+    required this.events,
+  })   : _connectionInfo = null,
+        _contentLength = null,
+        _cookies = [],
+        _followRedirects = null,
+        _headers = null,
+        _maxRedirects = null,
+        _method = null,
+        _persistentConnection = null,
+        proxyDetails = null;
+
+  /// Returns `true` if an error has occurred while issuing the request.
+  ///
+  /// If `true`, attempting to access some fields will throw a [HttpProfileRequestError].
+  bool get hasError => error != null;
+
+  /// Information about the client connection.
+  Map<String, dynamic>? get connectionInfo {
+    return _connectionInfo == null
+        ? null
+        : UnmodifiableMapView(_connectionInfo!);
+  }
+
+  final Map<String, dynamic>? _connectionInfo;
+
+  /// The content length of the request, in bytes.
+  ///
+  /// Throws [HttpProfileRequestError] is `hasError` is `true`.
+  int get contentLength => _returnIfNoError(_contentLength);
+  final int? _contentLength;
+
+  /// Cookies presented to the server (in the 'cookie' header).
+  ///
+  /// Throws [HttpProfileRequestError] is `hasError` is `true`.
+  List<String> get cookies => _returnIfNoError(_cookies);
+  final List<String> _cookies;
+
+  /// Events that has occurred while issuing this HTTP request.
+  final List<HttpProfileRequestEvent> events;
+
+  /// The error associated with the failed request.
+  final String? error;
+
+  /// Whether redirects are followed automatically.
+  ///
+  /// Throws [HttpProfileRequestError] is `hasError` is `true`.
+  bool get followRedirects => _returnIfNoError(_followRedirects);
+  final bool? _followRedirects;
+
+  /// Returns the client request headers.
+  ///
+  /// Throws [HttpProfileRequestError] is `hasError` is `true`.
+  Map<String, dynamic> get headers => UnmodifiableMapView(
+        _returnIfNoError(_headers),
+      );
+  final Map<String, dynamic>? _headers;
+
+  /// The maximum number of redirects to follow when `followRedirects` is true.
+  ///
+  /// Throws [HttpProfileRequestError] is `hasError` is `true`.
+  int get maxRedirects => _returnIfNoError(_maxRedirects);
+  final int? _maxRedirects;
+
+  /// The method of the request.
+  ///
+  /// Throws [HttpProfileRequestError] is `hasError` is `true`.
+  String get method => _returnIfNoError(_method);
+  final String? _method;
+
+  /// The requested persistent connection state.
+  ///
+  /// Throws [HttpProfileRequestError] is `hasError` is `true`.
+  bool get persistentConnection => _returnIfNoError(_persistentConnection);
+  final bool? _persistentConnection;
+
+  /// Proxy authentication details for this request.
+  final HttpProfileProxyData? proxyDetails;
+
+  T _returnIfNoError<T>(T? field) {
+    if (hasError) {
+      throw HttpProfileRequestError(error!);
+    }
+    return field!;
+  }
+}
+
+/// An [Error] thrown when attempting to inspect fields in a
+/// [HttpProfileRequestData] instance when `hasError` is `true`.
+class HttpProfileRequestError implements Error {
+  HttpProfileRequestError(this.error);
+
+  final String error;
+
+  @override
+  final StackTrace stackTrace = StackTrace.current;
+
+  @override
+  String toString() => 'HttpProfileRequestError: $error.';
+}
+
+/// Proxy authentication details associated with a [HttpProfileRequest].
+class HttpProfileProxyData {
+  static HttpProfileProxyData? parse(Map<String, dynamic>? json) =>
+      json == null ? null : HttpProfileProxyData._fromJson(json);
+
+  HttpProfileProxyData._fromJson(Map<String, dynamic> json)
+      : host = json['timestamp'],
+        port = json['event'],
+        username = json['arguments'];
+
+  HttpProfileProxyData({
+    this.host,
+    this.username,
+    this.port,
+  });
+
+  /// The URI of the proxy server.
+  final String? host;
+
+  /// The port the proxy server is listening on.
+  final int? port;
+
+  /// The username used to authenticate with the proxy server.
+  final String? username;
+}
+
+/// Describes an event that has occurred while issuing a HTTP request.
+class HttpProfileRequestEvent {
+  static HttpProfileRequestEvent? parse(Map<String, dynamic>? json) =>
+      json == null ? null : HttpProfileRequestEvent._fromJson(json);
+
+  HttpProfileRequestEvent._fromJson(Map<String, dynamic> json)
+      : timestamp = json['timestamp'],
+        event = json['event'],
+        arguments = json['arguments'];
+
+  HttpProfileRequestEvent({
+    required this.event,
+    required this.timestamp,
+    this.arguments,
+  });
+
+  final Map<String, dynamic>? arguments;
+  final String event;
+  final int timestamp;
+}
+
+/// Information received in response to an initial HTTP request.
+class HttpProfileResponseData {
+  static HttpProfileResponseData? parse(Map<String, dynamic>? json) =>
+      json == null ? null : HttpProfileResponseData._fromJson(json);
+
+  HttpProfileResponseData._fromJson(Map<String, dynamic> json)
+      : startTime = json['startTime']!,
+        endTime = json['endTime'],
+        headers = json['headers']!,
+        connectionInfo = json['connectionInfo']!,
+        contentLength = json['contentLength']!,
+        compressionState = json['compressionState']!,
+        cookies = UnmodifiableListView(json['cookies']!.cast<String>()),
+        error = json['error'],
+        isRedirect = json['isRedirect'],
+        persistentConnection = json['persistentConnection'],
+        reasonPhrase = json['reasonPhrase'],
+        redirects = UnmodifiableListView(
+            json['redirects']!.cast<Map<String, dynamic>>()),
+        statusCode = json['statusCode'];
+
+  HttpProfileResponseData({
+    required this.startTime,
+    this.endTime,
+    required this.headers,
+    required this.compressionState,
+    required this.connectionInfo,
+    required this.contentLength,
+    required this.cookies,
+    required this.isRedirect,
+    required this.persistentConnection,
+    required this.reasonPhrase,
+    required this.redirects,
+    required this.statusCode,
+    this.error,
+  });
+
+  bool get isComplete => endTime != null;
+  bool get hasError => error != null;
+
+  /// Returns the series of redirects this connection has been through.
+  ///
+  /// The list will be empty if no redirects were followed. redirects will be
+  /// updated both in the case of an automatic and a manual redirect.
+  final List<Map<String, dynamic>> redirects;
+
+  /// Cookies set by the server (from the 'set-cookie' header).
+  final List<String> cookies;
+
+  /// Information about the client connection.
+  final Map<String, dynamic>? connectionInfo;
+
+  /// Returns the client response headers.
+  final Map<String, dynamic> headers;
+
+  /// The compression state of the response.
+  ///
+  /// This specifies whether the response bytes were compressed when they were
+  /// received across the wire and whether callers will receive compressed or
+  /// uncompressed bytes when they listed to this response's byte stream.
+  ///
+  /// See [HttpClientResponseCompressionState](https://api.dart.dev/stable/dart-io/HttpClientResponseCompressionState-class.html) for possible values.
+  final String compressionState;
+
+  /// Returns the reason phrase associated with the status code.
+  final String reasonPhrase;
+
+  /// Returns whether the status code is one of the normal redirect codes.
+  final bool isRedirect;
+
+  /// The persistent connection state returned by the server.
+  final bool persistentConnection;
+
+  /// Returns the content length of the response body.
+  ///
+  /// Returns -1 if the size of the response body is not known in advance.
+  final int contentLength;
+
+  /// Returns the status code.
+  final int statusCode;
+
+  /// The time at which the initial response was received, in microseconds.
+  final int startTime;
+
+  /// The time at which the response was completed, in microseconds.
+  ///
+  /// Will be `null` if response data is still being received.
+  final int? endTime;
+
+  /// The error associated with the failed response.
+  final String? error;
+}
+
 /// A [SocketProfilingState] provides information about the current state of
 /// socket profiling for a given isolate.
 class SocketProfilingState extends _State {
@@ -479,7 +932,6 @@
         _files = List<OpenFileRef>.from(
             createServiceObject(json['files'], const ['OpenFileRef']) as List);
 
-  @override
   String get type => 'OpenFileList';
 
   /// A list of all files opened through dart:io on a given isolate.
diff --git a/pkg/vm_service/lib/src/vm_service.dart b/pkg/vm_service/lib/src/vm_service.dart
index 4413911..8b869fb 100644
--- a/pkg/vm_service/lib/src/vm_service.dart
+++ b/pkg/vm_service/lib/src/vm_service.dart
@@ -26,7 +26,7 @@
         HeapSnapshotObjectNoData,
         HeapSnapshotObjectNullData;
 
-const String vmServiceVersion = '3.43.0';
+const String vmServiceVersion = '3.44.0';
 
 /// @optional
 const String optional = 'optional';
@@ -2703,7 +2703,7 @@
   FieldRef? decl;
 
   /// [value] can be one of [InstanceRef] or [Sentinel].
-  dynamic? value;
+  dynamic value;
 
   BoundField({
     required this.decl,
@@ -2747,7 +2747,7 @@
   String? name;
 
   /// [value] can be one of [InstanceRef], [TypeArgumentsRef] or [Sentinel].
-  dynamic? value;
+  dynamic value;
 
   /// The token position where this variable was declared.
   int? declarationTokenPos;
@@ -2822,7 +2822,7 @@
   /// a breakpoint is not resolved.
   ///
   /// [location] can be one of [SourceLocation] or [UnresolvedSourceLocation].
-  dynamic? location;
+  dynamic location;
 
   Breakpoint({
     required this.breakpointNumber,
@@ -3331,7 +3331,7 @@
       json == null ? null : ContextElement._fromJson(json);
 
   /// [value] can be one of [InstanceRef] or [Sentinel].
-  dynamic? value;
+  dynamic value;
 
   ContextElement({
     required this.value,
@@ -3368,7 +3368,11 @@
   /// The number of samples returned.
   int? sampleCount;
 
-  /// The timespan the set of returned samples covers, in microseconds.
+  /// The timespan the set of returned samples covers, in microseconds
+  /// (deprecated).
+  ///
+  /// Note: this property is deprecated and will always return -1. Use
+  /// `timeExtentMicros` instead.
   int? timeSpan;
 
   /// The start of the period of time in which the returned samples were
@@ -4052,7 +4056,7 @@
   ///
   /// [staticValue] can be one of [InstanceRef] or [Sentinel].
   @optional
-  dynamic? staticValue;
+  dynamic staticValue;
 
   /// The location of this field in the source code.
   @optional
@@ -4082,7 +4086,7 @@
     isFinal = json['final'] ?? false;
     isStatic = json['static'] ?? false;
     staticValue = createServiceObject(
-        json['staticValue'], const ['InstanceRef', 'Sentinel']) as dynamic?;
+        json['staticValue'], const ['InstanceRef', 'Sentinel']) as dynamic;
     location = createServiceObject(json['location'], const ['SourceLocation'])
         as SourceLocation?;
   }
@@ -4276,7 +4280,7 @@
   /// The owner of this function, which can be a Library, Class, or a Function.
   ///
   /// [owner] can be one of [LibraryRef], [ClassRef] or [FuncRef].
-  dynamic? owner;
+  dynamic owner;
 
   /// Is this function static?
   bool? isStatic;
@@ -4338,7 +4342,7 @@
   /// The owner of this function, which can be a Library, Class, or a Function.
   ///
   /// [owner] can be one of [LibraryRef], [ClassRef] or [FuncRef].
-  dynamic? owner;
+  dynamic owner;
 
   /// Is this function static?
   bool? isStatic;
@@ -4412,6 +4416,11 @@
   /// What kind of instance is this?
   /*InstanceKind*/ String? kind;
 
+  /// The identityHashCode assigned to the allocated object. This hash code is
+  /// the same as the hash code provided in HeapSnapshot and CpuSample's
+  /// returned by getAllocationTraces().
+  int? identityHashCode;
+
   /// Instance references always include their class.
   ClassRef? classRef;
 
@@ -4528,6 +4537,7 @@
 
   InstanceRef({
     required this.kind,
+    required this.identityHashCode,
     required this.classRef,
     required String id,
     this.valueAsString,
@@ -4548,6 +4558,7 @@
 
   InstanceRef._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
     kind = json['kind'] ?? '';
+    identityHashCode = json['identityHashCode'] ?? -1;
     classRef =
         createServiceObject(json['class']!, const ['ClassRef']) as ClassRef;
     valueAsString = json['valueAsString'];
@@ -4583,6 +4594,7 @@
     json['type'] = type;
     json.addAll({
       'kind': kind,
+      'identityHashCode': identityHashCode,
       'class': classRef?.toJson(),
     });
     _setIfNotNull(json, 'valueAsString', valueAsString);
@@ -4604,8 +4616,9 @@
 
   operator ==(other) => other is InstanceRef && id == other.id;
 
-  String toString() =>
-      '[InstanceRef id: ${id}, kind: ${kind}, classRef: ${classRef}]';
+  String toString() => '[InstanceRef ' //
+      'id: ${id}, kind: ${kind}, identityHashCode: ${identityHashCode}, ' //
+      'classRef: ${classRef}]';
 }
 
 /// An `Instance` represents an instance of the Dart language class `Obj`.
@@ -4616,6 +4629,11 @@
   /// What kind of instance is this?
   /*InstanceKind*/ String? kind;
 
+  /// The identityHashCode assigned to the allocated object. This hash code is
+  /// the same as the hash code provided in HeapSnapshot and CpuSample's
+  /// returned by getAllocationTraces().
+  int? identityHashCode;
+
   /// Instance references always include their class.
   @override
   ClassRef? classRef;
@@ -4887,6 +4905,7 @@
 
   Instance({
     required this.kind,
+    required this.identityHashCode,
     required this.classRef,
     required String id,
     this.valueAsString,
@@ -4923,6 +4942,7 @@
 
   Instance._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
     kind = json['kind'] ?? '';
+    identityHashCode = json['identityHashCode'] ?? -1;
     classRef =
         createServiceObject(json['class']!, const ['ClassRef']) as ClassRef;
     valueAsString = json['valueAsString'];
@@ -4992,6 +5012,7 @@
     json['type'] = type;
     json.addAll({
       'kind': kind,
+      'identityHashCode': identityHashCode,
       'class': classRef?.toJson(),
     });
     _setIfNotNull(json, 'valueAsString', valueAsString);
@@ -5029,8 +5050,9 @@
 
   operator ==(other) => other is Instance && id == other.id;
 
-  String toString() =>
-      '[Instance id: ${id}, kind: ${kind}, classRef: ${classRef}]';
+  String toString() => '[Instance ' //
+      'id: ${id}, kind: ${kind}, identityHashCode: ${identityHashCode}, ' //
+      'classRef: ${classRef}]';
 }
 
 /// `IsolateRef` is a reference to an `Isolate` object.
@@ -5788,10 +5810,10 @@
       json == null ? null : MapAssociation._fromJson(json);
 
   /// [key] can be one of [InstanceRef] or [Sentinel].
-  dynamic? key;
+  dynamic key;
 
   /// [value] can be one of [InstanceRef] or [Sentinel].
-  dynamic? value;
+  dynamic value;
 
   MapAssociation({
     required this.key,
@@ -5985,6 +6007,7 @@
     required this.valueAsString,
   }) : super(
           id: 'instance/null',
+          identityHashCode: 0,
           kind: InstanceKind.kNull,
           classRef: ClassRef(
             id: 'class/null',
@@ -6014,7 +6037,8 @@
   operator ==(other) => other is NullValRef && id == other.id;
 
   String toString() => '[NullValRef ' //
-      'id: ${id}, kind: ${kind}, classRef: ${classRef}, valueAsString: ${valueAsString}]';
+      'id: ${id}, kind: ${kind}, identityHashCode: ${identityHashCode}, ' //
+      'classRef: ${classRef}, valueAsString: ${valueAsString}]';
 }
 
 /// A `NullVal` object represents the Dart language value null.
@@ -6030,6 +6054,7 @@
     required this.valueAsString,
   }) : super(
           id: 'instance/null',
+          identityHashCode: 0,
           kind: InstanceKind.kNull,
           classRef: ClassRef(
             id: 'class/null',
@@ -6059,7 +6084,8 @@
   operator ==(other) => other is NullVal && id == other.id;
 
   String toString() => '[NullVal ' //
-      'id: ${id}, kind: ${kind}, classRef: ${classRef}, valueAsString: ${valueAsString}]';
+      'id: ${id}, kind: ${kind}, identityHashCode: ${identityHashCode}, ' //
+      'classRef: ${classRef}, valueAsString: ${valueAsString}]';
 }
 
 /// `ObjRef` is a reference to a `Obj`.
@@ -6241,7 +6267,7 @@
   String? resolvedUrl;
 
   /// The function captured during profiling.
-  dynamic? function;
+  dynamic function;
 
   ProfileFunction({
     required this.kind,
diff --git a/pkg/vm_service/pubspec.yaml b/pkg/vm_service/pubspec.yaml
index b3e0010..5ba220b 100644
--- a/pkg/vm_service/pubspec.yaml
+++ b/pkg/vm_service/pubspec.yaml
@@ -3,7 +3,7 @@
   A library to communicate with a service implementing the Dart VM
   service protocol.
 
-version: 6.1.1
+version: 6.2.0
 
 homepage: https://github.com/dart-lang/sdk/tree/master/pkg/vm_service
 
diff --git a/pkg/vm_service/test/get_allocation_traces_test.dart b/pkg/vm_service/test/get_allocation_traces_test.dart
index 7dd4cc7..4d12086 100644
--- a/pkg/vm_service/test/get_allocation_traces_test.dart
+++ b/pkg/vm_service/test/get_allocation_traces_test.dart
@@ -86,6 +86,18 @@
     expect(profileResponse, isNotNull);
     expect(profileResponse.samples!.length, 1);
     expect(profileResponse.samples!.first.identityHashCode != 0, true);
+
+    final instances = await service.getInstances(
+      isolate.id!,
+      fooClass.id!,
+      1,
+    );
+    expect(instances.totalCount, 1);
+    final instance = instances.instances!.first as InstanceRef;
+    expect(instance.identityHashCode != 0, isTrue);
+    expect(instance.identityHashCode,
+        profileResponse.samples!.first.identityHashCode);
+
     await service.setTraceClassAllocation(isolate.id!, fooClass.id!, false);
 
     fooClass = await service.getObject(isolate.id!, fooClass.id!) as Class;
diff --git a/pkg/vm_service/test/get_http_profile_test.dart b/pkg/vm_service/test/get_http_profile_test.dart
new file mode 100644
index 0000000..59219fb
--- /dev/null
+++ b/pkg/vm_service/test/get_http_profile_test.dart
@@ -0,0 +1,313 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// VMOptions=--timeline_streams=Dart
+
+import 'dart:async';
+import 'dart:convert';
+import 'dart:io';
+import 'dart:math';
+import 'dart:typed_data';
+import 'package:vm_service/vm_service.dart';
+import 'package:test/test.dart';
+
+import 'common/test_helper.dart';
+
+final rng = Random();
+
+// Enable to test redirects.
+const shouldTestRedirects = false;
+
+const maxRequestDelayMs = 3000;
+const maxResponseDelayMs = 500;
+const serverShutdownDelayMs = 2000;
+
+void randomlyAddCookie(HttpResponse response) {
+  if (rng.nextInt(3) == 0) {
+    response.cookies.add(Cookie('Cookie-Monster', 'Me-want-cookie!'));
+  }
+}
+
+Future<bool> randomlyRedirect(HttpServer server, HttpResponse response) async {
+  if (shouldTestRedirects && rng.nextInt(5) == 0) {
+    final redirectUri = Uri(host: 'www.google.com', port: 80);
+    await response.redirect(redirectUri);
+    return true;
+  }
+  return false;
+}
+
+// Execute HTTP requests with random delays so requests have some overlap. This
+// way we can be certain that timeline events are matching up properly even when
+// connections are interrupted or can't be established.
+Future<void> executeWithRandomDelay(Function f) =>
+    Future<void>.delayed(Duration(milliseconds: rng.nextInt(maxRequestDelayMs)))
+        .then((_) async {
+      try {
+        await f();
+      } on HttpException catch (_) {} on SocketException catch (_) {} on StateError catch (_) {} on OSError catch (_) {}
+    });
+
+Uri randomlyAddRequestParams(Uri uri) {
+  const possiblePathSegments = <String>['foo', 'bar', 'baz', 'foobar'];
+  final segmentSubset =
+      possiblePathSegments.sublist(0, rng.nextInt(possiblePathSegments.length));
+  uri = uri.replace(pathSegments: segmentSubset);
+  if (rng.nextInt(3) == 0) {
+    uri = uri.replace(queryParameters: {
+      'foo': 'bar',
+      'year': '2019',
+    });
+  }
+  return uri;
+}
+
+Future<HttpServer> startServer() async {
+  final server = await HttpServer.bind(InternetAddress.loopbackIPv4, 0);
+  server.listen((request) async {
+    final response = request.response;
+    response.write(request.method);
+    randomlyAddCookie(response);
+    if (await randomlyRedirect(server, response)) {
+      // Redirect calls close() on the response.
+      return;
+    }
+    // Randomly delay response.
+    await Future.delayed(
+        Duration(milliseconds: rng.nextInt(maxResponseDelayMs)));
+    await response.close();
+  });
+  return server;
+}
+
+Future<void> testMain() async {
+  final server = await startServer();
+  HttpClient.enableTimelineLogging = true;
+  final client = HttpClient();
+  final requests = <Future>[];
+  final address =
+      Uri(scheme: 'http', host: server.address.host, port: server.port);
+
+  // HTTP DELETE
+  for (int i = 0; i < 10; ++i) {
+    final future = executeWithRandomDelay(() async {
+      final r = await client.deleteUrl(randomlyAddRequestParams(address));
+      final string = 'DELETE $address';
+      r.headers.add(HttpHeaders.contentLengthHeader, string.length);
+      r.write(string);
+      final response = await r.close();
+      response.listen((_) {});
+    });
+    requests.add(future);
+  }
+
+  // HTTP GET
+  for (int i = 0; i < 10; ++i) {
+    final future = executeWithRandomDelay(() async {
+      final r = await client.getUrl(randomlyAddRequestParams(address));
+      final response = await r.close();
+      await response.drain();
+    });
+    requests.add(future);
+  }
+  // HTTP HEAD
+  for (int i = 0; i < 10; ++i) {
+    final future = executeWithRandomDelay(() async {
+      final r = await client.headUrl(randomlyAddRequestParams(address));
+      await r.close();
+    });
+    requests.add(future);
+  }
+
+  // HTTP CONNECT
+  for (int i = 0; i < 10; ++i) {
+    final future = executeWithRandomDelay(() async {
+      final r =
+          await client.openUrl('connect', randomlyAddRequestParams(address));
+      await r.close();
+    });
+    requests.add(future);
+  }
+
+  // HTTP PATCH
+  for (int i = 0; i < 10; ++i) {
+    final future = executeWithRandomDelay(() async {
+      final r = await client.patchUrl(randomlyAddRequestParams(address));
+      final response = await r.close();
+      response.listen(null);
+    });
+    requests.add(future);
+  }
+
+  // HTTP POST
+  for (int i = 0; i < 10; ++i) {
+    final future = executeWithRandomDelay(() async {
+      final r = await client.postUrl(randomlyAddRequestParams(address));
+      r.add(Uint8List.fromList([0, 1, 2]));
+      await r.close();
+    });
+    requests.add(future);
+  }
+
+  // HTTP PUT
+  for (int i = 0; i < 10; ++i) {
+    final future = executeWithRandomDelay(() async {
+      final r = await client.putUrl(randomlyAddRequestParams(address));
+      await r.close();
+    });
+    requests.add(future);
+  }
+
+  // Purposefully close server before some connections can be made to ensure
+  // that refused / interrupted connections correctly create finish timeline
+  // events.
+  await Future.delayed(Duration(milliseconds: serverShutdownDelayMs));
+  await server.close();
+
+  // Ensure all requests complete before finishing.
+  await Future.wait(requests);
+}
+
+late VmService vmService;
+
+Future<void> hasValidHttpRequests(HttpProfile profile, String method) async {
+  final requests = profile.requests
+      .where(
+        (element) => element.method == method,
+      )
+      .toList();
+  expect(requests.length, 10);
+
+  for (final r in requests) {
+    final fullRequest =
+        await vmService.getHttpProfileRequest(r.isolateId, r.id);
+    if (r.isRequestComplete) {
+      final requestData = fullRequest.request!;
+
+      if (r.request!.hasError) {
+        void expectThrows(Function f) {
+          try {
+            f();
+            fail('Excepted exception');
+          } on HttpProfileRequestError {
+            // Expected.
+          }
+        }
+
+        expect(requestData.error, isNotNull);
+        expect(requestData.error!.isNotEmpty, true);
+
+        // Some data is available even if a request errored out.
+        expect(requestData.events.length, greaterThanOrEqualTo(0));
+        expect(fullRequest.requestBody!.length, greaterThanOrEqualTo(0));
+
+        // Accessing the following properties should cause an exception for
+        // requests which have encountered an error.
+        expectThrows(() => requestData.contentLength);
+        expectThrows(() => requestData.cookies);
+        expectThrows(() => requestData.followRedirects);
+        expectThrows(() => requestData.headers);
+        expectThrows(() => requestData.maxRedirects);
+        expectThrows(() => requestData.method);
+        expectThrows(() => requestData.persistentConnection);
+      } else {
+        // Invoke all non-nullable getters to ensure each is present in the JSON
+        // response.
+        requestData.connectionInfo;
+        requestData.contentLength;
+        requestData.cookies;
+        requestData.headers;
+        expect(requestData.maxRedirects, greaterThanOrEqualTo(0));
+        requestData.persistentConnection;
+        // If proxyInfo is non-null, uri and port _must_ be non-null.
+        if (requestData.proxyDetails != null) {
+          final proxyInfo = requestData.proxyDetails!;
+          expect(proxyInfo.host, true);
+          expect(proxyInfo.port, true);
+        }
+
+        // Check body of request has been sent and recorded correctly.
+        if (method == 'DELETE' || method == 'POST') {
+          if (method == 'POST') {
+            // add() was used
+            expect(
+              <int>[0, 1, 2],
+              fullRequest.requestBody!,
+            );
+          } else {
+            // write() was used.
+            expect(
+              utf8.decode(fullRequest.requestBody!).startsWith('$method http'),
+              true,
+            );
+          }
+        }
+
+        if (r.isResponseComplete) {
+          final responseData = r.response!;
+          expect(responseData.statusCode, greaterThanOrEqualTo(100));
+          expect(responseData.endTime, isNotNull);
+          expect(responseData.startTime > r.endTime!, true);
+          expect(responseData.endTime! >= responseData.startTime, true);
+          expect(utf8.decode(fullRequest.responseBody!), method);
+          responseData.headers;
+          responseData.compressionState;
+          responseData.connectionInfo;
+          responseData.contentLength;
+          responseData.cookies;
+          responseData.isRedirect;
+          responseData.persistentConnection;
+          responseData.reasonPhrase;
+          responseData.redirects;
+          expect(responseData.hasError, false);
+          expect(responseData.error, null);
+        }
+      }
+    }
+  }
+}
+
+void hasValidHttpProfile(HttpProfile profile, String method) {
+  expect(profile.requests.where((e) => e.method == method).length, 10);
+}
+
+Future<void> hasValidHttpCONNECTs(HttpProfile profile) =>
+    hasValidHttpRequests(profile, 'CONNECT');
+Future<void> hasValidHttpDELETEs(HttpProfile profile) =>
+    hasValidHttpRequests(profile, 'DELETE');
+Future<void> hasValidHttpGETs(HttpProfile profile) =>
+    hasValidHttpRequests(profile, 'GET');
+Future<void> hasValidHttpHEADs(HttpProfile profile) =>
+    hasValidHttpRequests(profile, 'HEAD');
+Future<void> hasValidHttpPATCHs(HttpProfile profile) =>
+    hasValidHttpRequests(profile, 'PATCH');
+Future<void> hasValidHttpPOSTs(HttpProfile profile) =>
+    hasValidHttpRequests(profile, 'POST');
+Future<void> hasValidHttpPUTs(HttpProfile profile) =>
+    hasValidHttpRequests(profile, 'PUT');
+
+var tests = <IsolateTest>[
+  (VmService service, IsolateRef isolateRef) async {
+    vmService = service;
+    final isolateId = isolateRef.id!;
+
+    final httpProfile = await service.getHttpProfile(isolateId);
+    expect(httpProfile.requests.length, 70);
+
+    // Verify timeline events.
+    await hasValidHttpCONNECTs(httpProfile);
+    await hasValidHttpDELETEs(httpProfile);
+    await hasValidHttpGETs(httpProfile);
+    await hasValidHttpHEADs(httpProfile);
+    await hasValidHttpPATCHs(httpProfile);
+    await hasValidHttpPOSTs(httpProfile);
+    await hasValidHttpPUTs(httpProfile);
+  },
+];
+
+main(args) async => runIsolateTests(
+      args,
+      tests,
+      'get_http_profile_test.dart',
+      testeeBefore: testMain,
+    );
diff --git a/pkg/vm_service/test/verify_http_timeline_test.dart b/pkg/vm_service/test/verify_http_timeline_test.dart
new file mode 100644
index 0000000..033571a
--- /dev/null
+++ b/pkg/vm_service/test/verify_http_timeline_test.dart
@@ -0,0 +1,343 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for 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=--timeline_streams=Dart
+
+import 'dart:async';
+import 'dart:convert';
+import 'dart:io';
+import 'dart:math';
+import 'dart:typed_data';
+import 'package:vm_service/vm_service.dart';
+import 'package:test/test.dart';
+
+import 'common/test_helper.dart';
+
+final rng = Random();
+
+// Enable to test redirects.
+const shouldTestRedirects = false;
+
+const maxRequestDelayMs = 3000;
+const maxResponseDelayMs = 500;
+const serverShutdownDelayMs = 2000;
+
+void randomlyAddCookie(HttpResponse response) {
+  if (rng.nextInt(3) == 0) {
+    response.cookies.add(Cookie('Cookie-Monster', 'Me-want-cookie!'));
+  }
+}
+
+Future<bool> randomlyRedirect(HttpServer server, HttpResponse response) async {
+  if (shouldTestRedirects && rng.nextInt(5) == 0) {
+    final redirectUri = Uri(host: 'www.google.com', port: 80);
+    await response.redirect(redirectUri);
+    return true;
+  }
+  return false;
+}
+
+// Execute HTTP requests with random delays so requests have some overlap. This
+// way we can be certain that timeline events are matching up properly even when
+// connections are interrupted or can't be established.
+Future<void> executeWithRandomDelay(Function f) =>
+    Future<void>.delayed(Duration(milliseconds: rng.nextInt(maxRequestDelayMs)))
+        .then((_) async {
+      try {
+        await f();
+      } on HttpException catch (_) {} on SocketException catch (_) {} on StateError catch (_) {} on OSError catch (_) {}
+    });
+
+Uri randomlyAddRequestParams(Uri uri) {
+  const possiblePathSegments = <String>['foo', 'bar', 'baz', 'foobar'];
+  final segmentSubset =
+      possiblePathSegments.sublist(0, rng.nextInt(possiblePathSegments.length));
+  uri = uri.replace(pathSegments: segmentSubset);
+  if (rng.nextInt(3) == 0) {
+    uri = uri.replace(queryParameters: {
+      'foo': 'bar',
+      'year': '2019',
+    });
+  }
+  return uri;
+}
+
+Future<HttpServer> startServer() async {
+  final server = await HttpServer.bind(InternetAddress.loopbackIPv4, 0);
+  server.listen((request) async {
+    final response = request.response;
+    response.write(request.method);
+    randomlyAddCookie(response);
+    if (await randomlyRedirect(server, response)) {
+      // Redirect calls close() on the response.
+      return;
+    }
+    // Randomly delay response.
+    await Future.delayed(
+        Duration(milliseconds: rng.nextInt(maxResponseDelayMs)));
+    await response.close();
+  });
+  return server;
+}
+
+Future<void> testMain() async {
+  print('starting');
+  final server = await startServer();
+  HttpClient.enableTimelineLogging = true;
+  final client = HttpClient();
+  final requests = <Future>[];
+  final address =
+      Uri(scheme: 'http', host: server.address.host, port: server.port);
+
+  // HTTP DELETE
+  for (int i = 0; i < 10; ++i) {
+    final future = executeWithRandomDelay(() async {
+      final r = await client.deleteUrl(randomlyAddRequestParams(address));
+      final string = 'DELETE $address';
+      r.headers.add(HttpHeaders.contentLengthHeader, string.length);
+      r.write(string);
+      final response = await r.close();
+      response.listen((_) {});
+    });
+    requests.add(future);
+  }
+
+  // HTTP GET
+  for (int i = 0; i < 10; ++i) {
+    final future = executeWithRandomDelay(() async {
+      final r = await client.getUrl(randomlyAddRequestParams(address));
+      final response = await r.close();
+      await response.drain();
+    });
+    requests.add(future);
+  }
+  // HTTP HEAD
+  for (int i = 0; i < 10; ++i) {
+    final future = executeWithRandomDelay(() async {
+      final r = await client.headUrl(randomlyAddRequestParams(address));
+      await r.close();
+    });
+    requests.add(future);
+  }
+
+  // HTTP CONNECT
+  for (int i = 0; i < 10; ++i) {
+    final future = executeWithRandomDelay(() async {
+      final r =
+          await client.openUrl('connect', randomlyAddRequestParams(address));
+      await r.close();
+    });
+    requests.add(future);
+  }
+
+  // HTTP PATCH
+  for (int i = 0; i < 10; ++i) {
+    final future = executeWithRandomDelay(() async {
+      final r = await client.patchUrl(randomlyAddRequestParams(address));
+      final response = await r.close();
+      response.listen(null);
+    });
+    requests.add(future);
+  }
+
+  // HTTP POST
+  for (int i = 0; i < 10; ++i) {
+    final future = executeWithRandomDelay(() async {
+      final r = await client.postUrl(randomlyAddRequestParams(address));
+      r.add(Uint8List.fromList([0, 1, 2]));
+      await r.close();
+    });
+    requests.add(future);
+  }
+
+  // HTTP PUT
+  for (int i = 0; i < 10; ++i) {
+    final future = executeWithRandomDelay(() async {
+      final r = await client.putUrl(randomlyAddRequestParams(address));
+      await r.close();
+    });
+    requests.add(future);
+  }
+
+  // Purposefully close server before some connections can be made to ensure
+  // that refused / interrupted connections correctly create finish timeline
+  // events.
+  await Future.delayed(Duration(milliseconds: serverShutdownDelayMs));
+  await server.close();
+
+  // Ensure all requests complete before finishing.
+  await Future.wait(requests);
+  print('done');
+}
+
+bool isStartEvent(Map event) => (event['ph'] == 'b');
+bool isFinishEvent(Map event) => (event['ph'] == 'e');
+
+bool hasCompletedEvents(List<TimelineEvent> traceEvents) {
+  final events = <String, int>{};
+  for (final event in traceEvents) {
+    final id = event.json!['id'];
+    events.putIfAbsent(id, () => 0);
+    if (isStartEvent(event.json!)) {
+      events[id] = events[id]! + 1;
+    } else if (isFinishEvent(event.json!)) {
+      events[id] = events[id]! - 1;
+    }
+  }
+  bool valid = true;
+  events.forEach((id, count) {
+    if (count != 0) {
+      valid = false;
+    }
+  });
+  return valid;
+}
+
+List<TimelineEvent> filterEventsByName(
+        List<TimelineEvent> traceEvents, String name) =>
+    traceEvents.where((e) => e.json!.containsKey(name)).toList();
+
+List<TimelineEvent> filterEventsByIdAndName(
+        List<TimelineEvent> traceEvents, String id, String name) =>
+    traceEvents
+        .where((e) => e.json!['id'] == id && e.json!['name'].contains(name))
+        .toList();
+
+void hasValidHttpConnections(List<TimelineEvent> traceEvents) {
+  final events = filterEventsByName(traceEvents, 'HTTP Connection');
+  expect(hasCompletedEvents(events), isTrue);
+}
+
+void validateHttpStartEvent(Map event, String method) {
+  expect(event.containsKey('args'), isTrue);
+  final args = event['args'];
+  expect(args.containsKey('method'), isTrue);
+  expect(args['method'], method);
+  expect(args['filterKey'], 'HTTP/client');
+  expect(args.containsKey('uri'), isTrue);
+}
+
+void validateHttpFinishEvent(Map event) {
+  expect(event.containsKey('args'), isTrue);
+  final args = event['args'];
+  expect(args['filterKey'], 'HTTP/client');
+  if (!args.containsKey('error')) {
+    expect(args.containsKey('requestHeaders'), isTrue);
+    expect(args['requestHeaders'] != null, isTrue);
+    expect(args.containsKey('compressionState'), isTrue);
+    expect(args.containsKey('connectionInfo'), isTrue);
+    expect(args.containsKey('contentLength'), isTrue);
+    expect(args.containsKey('cookies'), isTrue);
+    expect(args.containsKey('responseHeaders'), isTrue);
+    expect(args.containsKey('isRedirect'), isTrue);
+    expect(args.containsKey('persistentConnection'), isTrue);
+    expect(args.containsKey('reasonPhrase'), isTrue);
+    expect(args.containsKey('redirects'), isTrue);
+    expect(args.containsKey('statusCode'), isTrue);
+    // If proxyInfo is non-null, uri and port _must_ be non-null.
+    if (args.containsKey('proxyInfo')) {
+      final proxyInfo = args['proxyInfo'];
+      expect(proxyInfo.containsKey('uri'), isTrue);
+      expect(proxyInfo.containsKey('port'), isTrue);
+    }
+  }
+}
+
+void hasValidHttpRequests(
+    HttpProfile profile, List<TimelineEvent> traceEvents, String method) {
+  final requests = profile.requests
+      .where(
+        (element) => element.method == method,
+      )
+      .toList();
+  expect(requests.length, 10);
+
+  var events = filterEventsByName(traceEvents, 'HTTP CLIENT $method');
+  for (final event in events) {
+    final json = event.json!;
+    if (isStartEvent(json)) {
+      validateHttpStartEvent(event.json!, method);
+      final id = json['id'];
+
+      // HttpProfile request IDs should match up with their corresponding
+      // timeline event IDS.
+      final httpProfileRequest =
+          requests.singleWhere((element) => element.id == id);
+      expect(httpProfileRequest.id, id);
+    } else if (isFinishEvent(json)) {
+      validateHttpFinishEvent(json);
+    } else {
+      fail('unexpected event type: ${json["ph"]}');
+    }
+  }
+
+  // Check response body matches string stored in the map.
+  events = filterEventsByName(traceEvents, 'HTTP CLIENT response of $method');
+  if (method == 'DELETE') {
+    // It called listen().
+    expect(hasCompletedEvents(events), isTrue);
+  }
+  for (final event in events) {
+    final json = event.json!;
+    // Each response will be associated with a request.
+    if (isFinishEvent(json)) {
+      continue;
+    }
+    final id = json['id'];
+    final data = filterEventsByIdAndName(traceEvents, id, 'Response body');
+    if (data.isNotEmpty) {
+      expect(data.length, 1);
+      expect(utf8.encode(method), data[0].json!['args']['data']);
+    }
+  }
+}
+
+void hasValidHttpProfile(HttpProfile profile, String method) {
+  expect(profile.requests.where((e) => e.method == method).length, 10);
+}
+
+void hasValidHttpCONNECTs(
+        HttpProfile profile, List<TimelineEvent> traceEvents) =>
+    hasValidHttpRequests(profile, traceEvents, 'CONNECT');
+void hasValidHttpDELETEs(
+        HttpProfile profile, List<TimelineEvent> traceEvents) =>
+    hasValidHttpRequests(profile, traceEvents, 'DELETE');
+void hasValidHttpGETs(HttpProfile profile, List<TimelineEvent> traceEvents) =>
+    hasValidHttpRequests(profile, traceEvents, 'GET');
+void hasValidHttpHEADs(HttpProfile profile, List<TimelineEvent> traceEvents) =>
+    hasValidHttpRequests(profile, traceEvents, 'HEAD');
+void hasValidHttpPATCHs(HttpProfile profile, List<TimelineEvent> traceEvents) =>
+    hasValidHttpRequests(profile, traceEvents, 'PATCH');
+void hasValidHttpPOSTs(HttpProfile profile, List<TimelineEvent> traceEvents) =>
+    hasValidHttpRequests(profile, traceEvents, 'POST');
+void hasValidHttpPUTs(HttpProfile profile, List<TimelineEvent> traceEvents) =>
+    hasValidHttpRequests(profile, traceEvents, 'PUT');
+
+var tests = <IsolateTest>[
+  (VmService service, IsolateRef isolateRef) async {
+    final isolateId = isolateRef.id!;
+
+    final httpProfile = await service.getHttpProfile(isolateId);
+    expect(httpProfile.requests.length, 70);
+
+    // Verify timeline events.
+    final result = await service.getVMTimeline();
+    final traceEvents = result.traceEvents!;
+    expect(traceEvents.isNotEmpty, isTrue);
+    hasValidHttpConnections(traceEvents);
+    hasValidHttpCONNECTs(httpProfile, traceEvents);
+    hasValidHttpDELETEs(httpProfile, traceEvents);
+    hasValidHttpGETs(httpProfile, traceEvents);
+    hasValidHttpHEADs(httpProfile, traceEvents);
+    hasValidHttpPATCHs(httpProfile, traceEvents);
+    hasValidHttpPOSTs(httpProfile, traceEvents);
+    hasValidHttpPUTs(httpProfile, traceEvents);
+  },
+];
+
+main(args) async => runIsolateTests(
+      args,
+      tests,
+      'verify_http_timeline_test.dart',
+      testeeBefore: testMain,
+    );
diff --git a/pkg/vm_service/tool/dart/generate_dart.dart b/pkg/vm_service/tool/dart/generate_dart.dart
index 774f271..5e348b1 100644
--- a/pkg/vm_service/tool/dart/generate_dart.dart
+++ b/pkg/vm_service/tool/dart/generate_dart.dart
@@ -1200,7 +1200,7 @@
     gen.write('Future<${returnType.name}> ${name}(');
     bool startedOptional = false;
     gen.write(args.map((MethodArg arg) {
-      String? typeName;
+      String typeName;
       if (api.isEnumName(arg.type.name)) {
         if (arg.type.isArray) {
           typeName = typeName = '/*${arg.type}*/ List<String>';
@@ -1268,7 +1268,7 @@
     }
   }
 
-  String? get name {
+  String get name {
     if (types.isEmpty) return '';
     if (types.length == 1) return types.first.ref;
     if (isReturnType) return 'Response';
@@ -1286,7 +1286,7 @@
 
   bool get isArray => types.length == 1 && types.first.isArray;
 
-  void generate(DartGenerator gen) => gen.write(name!);
+  void generate(DartGenerator gen) => gen.write(name);
 }
 
 class TypeRef {
@@ -1296,7 +1296,7 @@
 
   TypeRef(this.name);
 
-  String? get ref {
+  String get ref {
     if (arrayDepth == 2) {
       return 'List<List<${name}>>';
     } else if (arrayDepth == 1) {
@@ -1304,7 +1304,7 @@
     } else if (genericTypes != null) {
       return '$name<${genericTypes!.join(', ')}>';
     } else {
-      return name!.startsWith('_') ? name!.substring(1) : name;
+      return name!.startsWith('_') ? name!.substring(1) : name!;
     }
   }
 
@@ -1340,7 +1340,7 @@
           name == 'double' ||
           name == 'ByteData');
 
-  String toString() => ref!;
+  String toString() => ref;
 }
 
 class MethodArg extends Member {
@@ -1488,6 +1488,7 @@
     } else if (name!.contains('NullVal')) {
       gen.writeln(' : super(');
       gen.writeln("id: 'instance/null',");
+      gen.writeln('identityHashCode: 0,');
       gen.writeln('kind: InstanceKind.kNull,');
       gen.writeln("classRef: ClassRef(id: 'class/null',");
       gen.writeln("name: 'Null',),");
@@ -1639,9 +1640,11 @@
         }
       } else {
         String typesList = _typeRefListToString(field.type.types);
+        String nullable =
+            field.optional && field.type.name != 'dynamic' ? '?' : '';
         gen.writeln("${field.generatableName} = "
             "createServiceObject(json['${field.name}']${field.optional ? '' : '!'}, "
-            "$typesList) as ${field.type.name}${field.optional ? '?' : ''};");
+            "$typesList) as ${field.type.name}$nullable;");
       }
     });
     if (fields.isNotEmpty) {
@@ -1851,8 +1854,8 @@
           gen.writeln('}');
         } else {
           String assertMethodName = 'assert' +
-              type.name!.substring(0, 1).toUpperCase() +
-              type.name!.substring(1);
+              type.name.substring(0, 1).toUpperCase() +
+              type.name.substring(1);
           gen.writeln('$assertMethodName(obj.${field.generatableName}!);');
         }
       }
@@ -1943,7 +1946,9 @@
     {
       String? typeName =
           api.isEnumName(type.name) ? '/*${type.name}*/ String' : type.name;
-      typeName = '$typeName?';
+      if (typeName != 'dynamic') {
+        typeName = '$typeName?';
+      }
       gen.writeStatement('${typeName} ${generatableName};');
       if (parent.fields.any((field) => field.hasDocs)) gen.writeln();
     }
diff --git a/pkg/vm_snapshot_analysis/CHANGELOG.md b/pkg/vm_snapshot_analysis/CHANGELOG.md
index 96e8132..b011f35 100644
--- a/pkg/vm_snapshot_analysis/CHANGELOG.md
+++ b/pkg/vm_snapshot_analysis/CHANGELOG.md
@@ -1,5 +1,9 @@
 # Changelog
 
+## 0.6.0
+
+- Update to latest args, path, meta dependency.
+
 ## 0.5.6
 - Fix for flutter/flutter#76313 causing issues with profiles containing
 WSRs serialized as smi-s instead of actual WSR objects.=
diff --git a/pkg/vm_snapshot_analysis/pubspec.yaml b/pkg/vm_snapshot_analysis/pubspec.yaml
index fdac362..5b75e91 100644
--- a/pkg/vm_snapshot_analysis/pubspec.yaml
+++ b/pkg/vm_snapshot_analysis/pubspec.yaml
@@ -1,6 +1,6 @@
 name: vm_snapshot_analysis
 description: Utilities for analysing AOT snapshot size.
-version: 0.5.6
+version: 0.6.0
 
 homepage: https://github.com/dart-lang/sdk/tree/master/pkg/vm_snapshot_analysis
 
@@ -11,10 +11,10 @@
   snapshot_analysis: analyse
 
 dependencies:
-  args: ^1.6.0
-  path: ^1.7.0
-  meta: ^1.1.8
+  args: ^2.0.0
+  path: ^1.8.0
+  meta: ^1.3.0
 
 dev_dependencies:
-  pedantic: ^1.9.0
-  test: ^1.15.1
+  pedantic: ^1.11.0
+  test: ^1.16.8
diff --git a/pkg/vm_snapshot_analysis/test/instruction_sizes_test.dart b/pkg/vm_snapshot_analysis/test/instruction_sizes_test.dart
index ddb2ac4..5347acc 100644
--- a/pkg/vm_snapshot_analysis/test/instruction_sizes_test.dart
+++ b/pkg/vm_snapshot_analysis/test/instruction_sizes_test.dart
@@ -50,6 +50,12 @@
   }
 }
 
+class D {
+  static dynamic tornOff() sync* {
+    yield const K(5);
+  }
+}
+
 @pragma('vm:never-inline')
 Function tearOff(dynamic o) {
   return o.tornOff;
@@ -61,6 +67,7 @@
   }
   print(tearOff(args.isEmpty ? A() : B()));
   print(C.tornOff);
+  print(D.tornOff);
 }
 """
 };
@@ -107,6 +114,12 @@
   }
 }
 
+class D {
+  static dynamic tornOff() sync* {
+    yield const K(5);
+  }
+}
+
 @pragma('vm:never-inline')
 Function tearOff(dynamic o) {
   return o.tornOff;
@@ -116,6 +129,7 @@
   // modified
   print(tearOff(args.isEmpty ? A() : B()));
   print(C.tornOff);
+  print(D.tornOff);
 }
 """
 };
@@ -154,6 +168,12 @@
   }
 }
 
+class D {
+  static dynamic tornOff() sync* {
+    yield const K(5);
+  }
+}
+
 @pragma('vm:never-inline')
 Function tearOff(dynamic o) {
   return o.tornOff;
@@ -165,6 +185,7 @@
   }
   print(tearOff(args.isEmpty ? A() : B()));
   print(C.tornOff);
+  print(D.tornOff);
 }
 """
 };
@@ -285,6 +306,10 @@
         // with {body}.
         expect(inputDartSymbolNames['C'], contains('[tear-off] tornOff'));
 
+        // Presence of sync* modifier should not cause tear-off name to end
+        // with {body}.
+        expect(inputDartSymbolNames['D'], contains('[tear-off] tornOff'));
+
         // Check that output does not contain '[unknown stub]'
         expect(symbolRawNames[''][''], isNot(contains('[unknown stub]')),
             reason: 'All stubs must be named');
@@ -306,6 +331,7 @@
         expect(inputLib.children, contains('A'));
         expect(inputLib.children, contains('B'));
         expect(inputLib.children, contains('C'));
+        expect(inputLib.children, contains('D'));
 
         final topLevel = inputLib.children[''];
         expect(topLevel.children, contains('makeSomeClosures'));
@@ -336,6 +362,16 @@
           expect(inputLib.children['C'].children, contains(name));
           expect(inputLib.children['C'].children[name].children, isEmpty);
         }
+
+        for (var name in [
+          'tornOff{body}',
+          'tornOff{body depth 2}',
+          'tornOff',
+          '[tear-off] tornOff'
+        ]) {
+          expect(inputLib.children['D'].children, contains(name));
+          expect(inputLib.children['D'].children[name].children, isEmpty);
+        }
       });
     });
 
@@ -356,6 +392,10 @@
             bySymbol.buckets,
             contains(bySymbol.bucketFor(
                 'package:input', 'package:input/input.dart', 'C', 'tornOff')));
+        expect(
+            bySymbol.buckets,
+            contains(bySymbol.bucketFor(
+                'package:input', 'package:input/input.dart', 'D', 'tornOff')));
 
         final byClass = computeHistogram(info, HistogramType.byClass);
         expect(
@@ -370,6 +410,10 @@
             byClass.buckets,
             contains(byClass.bucketFor('package:input',
                 'package:input/input.dart', 'C', 'does-not-matter')));
+        expect(
+            byClass.buckets,
+            contains(byClass.bucketFor('package:input',
+                'package:input/input.dart', 'D', 'does-not-matter')));
 
         final byLibrary = computeHistogram(info, HistogramType.byLibrary);
         expect(
@@ -538,6 +582,21 @@
             .where((n) => n.type == 'Class')
             .map((n) => n.name);
         expect(classesOwnedByC, equals(['C']));
+
+        final classD = inputLib.children['D'];
+        expect(classD.children, contains('tornOff'));
+        for (var name in ['tornOff{body}', '[tear-off] tornOff']) {
+          expect(classD.children['tornOff'].children, contains(name));
+        }
+        expect(classD.children['tornOff'].children['tornOff{body}'].children,
+            contains('tornOff{body depth 2}'));
+
+        // Verify that [ProgramInfoNode] owns its corresponding snapshot [Node].
+        final classesOwnedByD = info.snapshotInfo.snapshot.nodes
+            .where((n) => info.snapshotInfo.ownerOf(n) == classD)
+            .where((n) => n.type == 'Class')
+            .map((n) => n.name);
+        expect(classesOwnedByD, equals(['D']));
       });
     });
 
@@ -592,6 +651,10 @@
             bySymbol.buckets,
             contains(bySymbol.bucketFor(
                 'package:input', 'package:input/input.dart', 'C', 'tornOff')));
+        expect(
+            bySymbol.buckets,
+            contains(bySymbol.bucketFor(
+                'package:input', 'package:input/input.dart', 'D', 'tornOff')));
 
         final byClass = computeHistogram(info, HistogramType.byClass);
         expect(
@@ -606,6 +669,10 @@
             byClass.buckets,
             contains(byClass.bucketFor('package:input',
                 'package:input/input.dart', 'C', 'does-not-matter')));
+        expect(
+            byClass.buckets,
+            contains(byClass.bucketFor('package:input',
+                'package:input/input.dart', 'D', 'does-not-matter')));
 
         final byLibrary = computeHistogram(info, HistogramType.byLibrary);
         expect(
diff --git a/runtime/bin/BUILD.gn b/runtime/bin/BUILD.gn
index 5eae1d9..1bc8225 100644
--- a/runtime/bin/BUILD.gn
+++ b/runtime/bin/BUILD.gn
@@ -897,9 +897,6 @@
     "..:libdart_precompiler",
     "//third_party/zlib",
   ]
-  if (defined(checkout_llvm) && checkout_llvm) {
-    deps += [ "//runtime/llvm_codegen/bit:test" ]
-  }
   include_dirs = [
     "..",
     "$target_gen_dir",
diff --git a/runtime/bin/builtin_impl_sources.gni b/runtime/bin/builtin_impl_sources.gni
index 1045fdc..d1f7d95 100644
--- a/runtime/bin/builtin_impl_sources.gni
+++ b/runtime/bin/builtin_impl_sources.gni
@@ -62,6 +62,7 @@
   "thread_macos.h",
   "thread_win.cc",
   "thread_win.h",
+  "utils.cc",
   "utils.h",
   "utils_android.cc",
   "utils_fuchsia.cc",
diff --git a/runtime/bin/builtin_natives.cc b/runtime/bin/builtin_natives.cc
index 0c27be9..14762ed 100644
--- a/runtime/bin/builtin_natives.cc
+++ b/runtime/bin/builtin_natives.cc
@@ -99,8 +99,12 @@
   if (ShouldCaptureStdout()) {
     // For now we report print output on the Stdout stream.
     uint8_t newline[] = {'\n'};
-    Dart_ServiceSendDataEvent("Stdout", "WriteEvent", chars, length);
-    Dart_ServiceSendDataEvent("Stdout", "WriteEvent", newline, sizeof(newline));
+    const char* res =
+        Dart_ServiceSendDataEvent("Stdout", "WriteEvent", chars, length);
+    ASSERT(res == nullptr);
+    res = Dart_ServiceSendDataEvent("Stdout", "WriteEvent", newline,
+                                    sizeof(newline));
+    ASSERT(res == nullptr);
   }
 }
 
diff --git a/runtime/bin/eventhandler.h b/runtime/bin/eventhandler.h
index 69a8e3a..b45deac 100644
--- a/runtime/bin/eventhandler.h
+++ b/runtime/bin/eventhandler.h
@@ -90,7 +90,6 @@
 
  private:
   PriorityQueue<int64_t, Dart_Port> timeouts_;
-  int64_t next_timeout_;
 
   DISALLOW_COPY_AND_ASSIGN(TimeoutQueue);
 };
diff --git a/runtime/bin/ffi_test/ffi_test_functions.cc b/runtime/bin/ffi_test/ffi_test_functions.cc
index 69a0e51..49ab86f 100644
--- a/runtime/bin/ffi_test/ffi_test_functions.cc
+++ b/runtime/bin/ffi_test/ffi_test_functions.cc
@@ -1113,4 +1113,15 @@
   return my_struct->someValue;
 }
 
+#pragma pack(push, 1)
+struct Struct3BytesPackedIntCopy {
+  int8_t a0;
+  int16_t a1;
+};
+#pragma pack(pop)
+
+DART_EXPORT uint64_t SizeOfStruct3BytesPackedInt() {
+  return sizeof(Struct3BytesPackedIntCopy);
+}
+
 }  // namespace dart
diff --git a/runtime/bin/ffi_test/ffi_test_functions_generated.cc b/runtime/bin/ffi_test/ffi_test_functions_generated.cc
index 220b5c1..6d3a2cf 100644
--- a/runtime/bin/ffi_test/ffi_test_functions_generated.cc
+++ b/runtime/bin/ffi_test/ffi_test_functions_generated.cc
@@ -451,6 +451,73 @@
   int16_t a2[2];
 };
 
+struct Struct8BytesInlineArrayMultiDimensionalInt {
+  uint8_t a0[2][2][2];
+};
+
+struct Struct32BytesInlineArrayMultiDimensionalInt {
+  uint8_t a0[2][2][2][2][2];
+};
+
+struct Struct64BytesInlineArrayMultiDimensionalInt {
+  uint8_t a0[2][2][2][2][2][2];
+};
+
+struct Struct4BytesInlineArrayMultiDimensionalInt {
+  Struct1ByteInt a0[2][2];
+};
+
+#pragma pack(push, 1)
+struct Struct3BytesPackedInt {
+  int8_t a0;
+  int16_t a1;
+};
+#pragma pack(pop)
+
+#pragma pack(push, 1)
+struct Struct3BytesPackedIntMembersAligned {
+  int8_t a0;
+  int16_t a1;
+};
+#pragma pack(pop)
+
+#pragma pack(push, 1)
+struct Struct5BytesPackedMixed {
+  float a0;
+  uint8_t a1;
+};
+#pragma pack(pop)
+
+struct StructNestedAlignmentStruct5BytesPackedMixed {
+  uint8_t a0;
+  Struct5BytesPackedMixed a1;
+};
+
+struct Struct6BytesInlineArrayInt {
+  Struct3BytesPackedIntMembersAligned a0[2];
+};
+
+#pragma pack(push, 1)
+struct Struct8BytesPackedInt {
+  uint8_t a0;
+  uint32_t a1;
+  uint8_t a2;
+  uint8_t a3;
+  uint8_t a4;
+};
+#pragma pack(pop)
+
+#pragma pack(push, 1)
+struct Struct9BytesPackedMixed {
+  uint8_t a0;
+  double a1;
+};
+#pragma pack(pop)
+
+struct Struct15BytesInlineArrayMixed {
+  Struct5BytesPackedMixed a0[3];
+};
+
 // Used for testing structs by value.
 // Smallest struct with data.
 // 10 struct arguments will exhaust available registers.
@@ -3826,6 +3893,460 @@
 }
 
 // Used for testing structs by value.
+// Test multi dimensional inline array struct as argument.
+DART_EXPORT uint32_t PassUint8Struct32BytesInlineArrayMultiDimensionalI(
+    uint8_t a0,
+    Struct32BytesInlineArrayMultiDimensionalInt a1,
+    uint8_t a2,
+    Struct8BytesInlineArrayMultiDimensionalInt a3,
+    uint8_t a4,
+    Struct8BytesInlineArrayMultiDimensionalInt a5,
+    uint8_t a6) {
+  std::cout << "PassUint8Struct32BytesInlineArrayMultiDimensionalI"
+            << "(" << static_cast<int>(a0) << ", ([[[[["
+            << static_cast<int>(a1.a0[0][0][0][0][0]) << ", "
+            << static_cast<int>(a1.a0[0][0][0][0][1]) << "], ["
+            << static_cast<int>(a1.a0[0][0][0][1][0]) << ", "
+            << static_cast<int>(a1.a0[0][0][0][1][1]) << "]], [["
+            << static_cast<int>(a1.a0[0][0][1][0][0]) << ", "
+            << static_cast<int>(a1.a0[0][0][1][0][1]) << "], ["
+            << static_cast<int>(a1.a0[0][0][1][1][0]) << ", "
+            << static_cast<int>(a1.a0[0][0][1][1][1]) << "]]], [[["
+            << static_cast<int>(a1.a0[0][1][0][0][0]) << ", "
+            << static_cast<int>(a1.a0[0][1][0][0][1]) << "], ["
+            << static_cast<int>(a1.a0[0][1][0][1][0]) << ", "
+            << static_cast<int>(a1.a0[0][1][0][1][1]) << "]], [["
+            << static_cast<int>(a1.a0[0][1][1][0][0]) << ", "
+            << static_cast<int>(a1.a0[0][1][1][0][1]) << "], ["
+            << static_cast<int>(a1.a0[0][1][1][1][0]) << ", "
+            << static_cast<int>(a1.a0[0][1][1][1][1]) << "]]]], [[[["
+            << static_cast<int>(a1.a0[1][0][0][0][0]) << ", "
+            << static_cast<int>(a1.a0[1][0][0][0][1]) << "], ["
+            << static_cast<int>(a1.a0[1][0][0][1][0]) << ", "
+            << static_cast<int>(a1.a0[1][0][0][1][1]) << "]], [["
+            << static_cast<int>(a1.a0[1][0][1][0][0]) << ", "
+            << static_cast<int>(a1.a0[1][0][1][0][1]) << "], ["
+            << static_cast<int>(a1.a0[1][0][1][1][0]) << ", "
+            << static_cast<int>(a1.a0[1][0][1][1][1]) << "]]], [[["
+            << static_cast<int>(a1.a0[1][1][0][0][0]) << ", "
+            << static_cast<int>(a1.a0[1][1][0][0][1]) << "], ["
+            << static_cast<int>(a1.a0[1][1][0][1][0]) << ", "
+            << static_cast<int>(a1.a0[1][1][0][1][1]) << "]], [["
+            << static_cast<int>(a1.a0[1][1][1][0][0]) << ", "
+            << static_cast<int>(a1.a0[1][1][1][0][1]) << "], ["
+            << static_cast<int>(a1.a0[1][1][1][1][0]) << ", "
+            << static_cast<int>(a1.a0[1][1][1][1][1]) << "]]]]]), "
+            << static_cast<int>(a2) << ", ([[["
+            << static_cast<int>(a3.a0[0][0][0]) << ", "
+            << static_cast<int>(a3.a0[0][0][1]) << "], ["
+            << static_cast<int>(a3.a0[0][1][0]) << ", "
+            << static_cast<int>(a3.a0[0][1][1]) << "]], [["
+            << static_cast<int>(a3.a0[1][0][0]) << ", "
+            << static_cast<int>(a3.a0[1][0][1]) << "], ["
+            << static_cast<int>(a3.a0[1][1][0]) << ", "
+            << static_cast<int>(a3.a0[1][1][1]) << "]]]), "
+            << static_cast<int>(a4) << ", ([[["
+            << static_cast<int>(a5.a0[0][0][0]) << ", "
+            << static_cast<int>(a5.a0[0][0][1]) << "], ["
+            << static_cast<int>(a5.a0[0][1][0]) << ", "
+            << static_cast<int>(a5.a0[0][1][1]) << "]], [["
+            << static_cast<int>(a5.a0[1][0][0]) << ", "
+            << static_cast<int>(a5.a0[1][0][1]) << "], ["
+            << static_cast<int>(a5.a0[1][1][0]) << ", "
+            << static_cast<int>(a5.a0[1][1][1]) << "]]]), "
+            << static_cast<int>(a6) << ")"
+            << "\n";
+
+  uint32_t result = 0;
+
+  result += a0;
+  result += a1.a0[0][0][0][0][0];
+  result += a1.a0[0][0][0][0][1];
+  result += a1.a0[0][0][0][1][0];
+  result += a1.a0[0][0][0][1][1];
+  result += a1.a0[0][0][1][0][0];
+  result += a1.a0[0][0][1][0][1];
+  result += a1.a0[0][0][1][1][0];
+  result += a1.a0[0][0][1][1][1];
+  result += a1.a0[0][1][0][0][0];
+  result += a1.a0[0][1][0][0][1];
+  result += a1.a0[0][1][0][1][0];
+  result += a1.a0[0][1][0][1][1];
+  result += a1.a0[0][1][1][0][0];
+  result += a1.a0[0][1][1][0][1];
+  result += a1.a0[0][1][1][1][0];
+  result += a1.a0[0][1][1][1][1];
+  result += a1.a0[1][0][0][0][0];
+  result += a1.a0[1][0][0][0][1];
+  result += a1.a0[1][0][0][1][0];
+  result += a1.a0[1][0][0][1][1];
+  result += a1.a0[1][0][1][0][0];
+  result += a1.a0[1][0][1][0][1];
+  result += a1.a0[1][0][1][1][0];
+  result += a1.a0[1][0][1][1][1];
+  result += a1.a0[1][1][0][0][0];
+  result += a1.a0[1][1][0][0][1];
+  result += a1.a0[1][1][0][1][0];
+  result += a1.a0[1][1][0][1][1];
+  result += a1.a0[1][1][1][0][0];
+  result += a1.a0[1][1][1][0][1];
+  result += a1.a0[1][1][1][1][0];
+  result += a1.a0[1][1][1][1][1];
+  result += a2;
+  result += a3.a0[0][0][0];
+  result += a3.a0[0][0][1];
+  result += a3.a0[0][1][0];
+  result += a3.a0[0][1][1];
+  result += a3.a0[1][0][0];
+  result += a3.a0[1][0][1];
+  result += a3.a0[1][1][0];
+  result += a3.a0[1][1][1];
+  result += a4;
+  result += a5.a0[0][0][0];
+  result += a5.a0[0][0][1];
+  result += a5.a0[0][1][0];
+  result += a5.a0[0][1][1];
+  result += a5.a0[1][0][0];
+  result += a5.a0[1][0][1];
+  result += a5.a0[1][1][0];
+  result += a5.a0[1][1][1];
+  result += a6;
+
+  std::cout << "result = " << result << "\n";
+
+  return result;
+}
+
+// Used for testing structs by value.
+// Test struct in multi dimensional inline array.
+DART_EXPORT uint32_t PassUint8Struct4BytesInlineArrayMultiDimensionalIn(
+    uint8_t a0,
+    Struct4BytesInlineArrayMultiDimensionalInt a1,
+    uint8_t a2) {
+  std::cout << "PassUint8Struct4BytesInlineArrayMultiDimensionalIn"
+            << "(" << static_cast<int>(a0) << ", ([[("
+            << static_cast<int>(a1.a0[0][0].a0) << "), ("
+            << static_cast<int>(a1.a0[0][1].a0) << ")], [("
+            << static_cast<int>(a1.a0[1][0].a0) << "), ("
+            << static_cast<int>(a1.a0[1][1].a0) << ")]]), "
+            << static_cast<int>(a2) << ")"
+            << "\n";
+
+  uint32_t result = 0;
+
+  result += a0;
+  result += a1.a0[0][0].a0;
+  result += a1.a0[0][1].a0;
+  result += a1.a0[1][0].a0;
+  result += a1.a0[1][1].a0;
+  result += a2;
+
+  std::cout << "result = " << result << "\n";
+
+  return result;
+}
+
+// Used for testing structs by value.
+// Small struct with mis-aligned member.
+DART_EXPORT int64_t PassStruct3BytesPackedIntx10(Struct3BytesPackedInt a0,
+                                                 Struct3BytesPackedInt a1,
+                                                 Struct3BytesPackedInt a2,
+                                                 Struct3BytesPackedInt a3,
+                                                 Struct3BytesPackedInt a4,
+                                                 Struct3BytesPackedInt a5,
+                                                 Struct3BytesPackedInt a6,
+                                                 Struct3BytesPackedInt a7,
+                                                 Struct3BytesPackedInt a8,
+                                                 Struct3BytesPackedInt a9) {
+  std::cout << "PassStruct3BytesPackedIntx10"
+            << "((" << static_cast<int>(a0.a0) << ", " << a0.a1 << "), ("
+            << static_cast<int>(a1.a0) << ", " << a1.a1 << "), ("
+            << static_cast<int>(a2.a0) << ", " << a2.a1 << "), ("
+            << static_cast<int>(a3.a0) << ", " << a3.a1 << "), ("
+            << static_cast<int>(a4.a0) << ", " << a4.a1 << "), ("
+            << static_cast<int>(a5.a0) << ", " << a5.a1 << "), ("
+            << static_cast<int>(a6.a0) << ", " << a6.a1 << "), ("
+            << static_cast<int>(a7.a0) << ", " << a7.a1 << "), ("
+            << static_cast<int>(a8.a0) << ", " << a8.a1 << "), ("
+            << static_cast<int>(a9.a0) << ", " << a9.a1 << "))"
+            << "\n";
+
+  int64_t result = 0;
+
+  result += a0.a0;
+  result += a0.a1;
+  result += a1.a0;
+  result += a1.a1;
+  result += a2.a0;
+  result += a2.a1;
+  result += a3.a0;
+  result += a3.a1;
+  result += a4.a0;
+  result += a4.a1;
+  result += a5.a0;
+  result += a5.a1;
+  result += a6.a0;
+  result += a6.a1;
+  result += a7.a0;
+  result += a7.a1;
+  result += a8.a0;
+  result += a8.a1;
+  result += a9.a0;
+  result += a9.a1;
+
+  std::cout << "result = " << result << "\n";
+
+  return result;
+}
+
+// Used for testing structs by value.
+// Struct with mis-aligned member.
+DART_EXPORT int64_t PassStruct8BytesPackedIntx10(Struct8BytesPackedInt a0,
+                                                 Struct8BytesPackedInt a1,
+                                                 Struct8BytesPackedInt a2,
+                                                 Struct8BytesPackedInt a3,
+                                                 Struct8BytesPackedInt a4,
+                                                 Struct8BytesPackedInt a5,
+                                                 Struct8BytesPackedInt a6,
+                                                 Struct8BytesPackedInt a7,
+                                                 Struct8BytesPackedInt a8,
+                                                 Struct8BytesPackedInt a9) {
+  std::cout << "PassStruct8BytesPackedIntx10"
+            << "((" << static_cast<int>(a0.a0) << ", " << a0.a1 << ", "
+            << static_cast<int>(a0.a2) << ", " << static_cast<int>(a0.a3)
+            << ", " << static_cast<int>(a0.a4) << "), ("
+            << static_cast<int>(a1.a0) << ", " << a1.a1 << ", "
+            << static_cast<int>(a1.a2) << ", " << static_cast<int>(a1.a3)
+            << ", " << static_cast<int>(a1.a4) << "), ("
+            << static_cast<int>(a2.a0) << ", " << a2.a1 << ", "
+            << static_cast<int>(a2.a2) << ", " << static_cast<int>(a2.a3)
+            << ", " << static_cast<int>(a2.a4) << "), ("
+            << static_cast<int>(a3.a0) << ", " << a3.a1 << ", "
+            << static_cast<int>(a3.a2) << ", " << static_cast<int>(a3.a3)
+            << ", " << static_cast<int>(a3.a4) << "), ("
+            << static_cast<int>(a4.a0) << ", " << a4.a1 << ", "
+            << static_cast<int>(a4.a2) << ", " << static_cast<int>(a4.a3)
+            << ", " << static_cast<int>(a4.a4) << "), ("
+            << static_cast<int>(a5.a0) << ", " << a5.a1 << ", "
+            << static_cast<int>(a5.a2) << ", " << static_cast<int>(a5.a3)
+            << ", " << static_cast<int>(a5.a4) << "), ("
+            << static_cast<int>(a6.a0) << ", " << a6.a1 << ", "
+            << static_cast<int>(a6.a2) << ", " << static_cast<int>(a6.a3)
+            << ", " << static_cast<int>(a6.a4) << "), ("
+            << static_cast<int>(a7.a0) << ", " << a7.a1 << ", "
+            << static_cast<int>(a7.a2) << ", " << static_cast<int>(a7.a3)
+            << ", " << static_cast<int>(a7.a4) << "), ("
+            << static_cast<int>(a8.a0) << ", " << a8.a1 << ", "
+            << static_cast<int>(a8.a2) << ", " << static_cast<int>(a8.a3)
+            << ", " << static_cast<int>(a8.a4) << "), ("
+            << static_cast<int>(a9.a0) << ", " << a9.a1 << ", "
+            << static_cast<int>(a9.a2) << ", " << static_cast<int>(a9.a3)
+            << ", " << static_cast<int>(a9.a4) << "))"
+            << "\n";
+
+  int64_t result = 0;
+
+  result += a0.a0;
+  result += a0.a1;
+  result += a0.a2;
+  result += a0.a3;
+  result += a0.a4;
+  result += a1.a0;
+  result += a1.a1;
+  result += a1.a2;
+  result += a1.a3;
+  result += a1.a4;
+  result += a2.a0;
+  result += a2.a1;
+  result += a2.a2;
+  result += a2.a3;
+  result += a2.a4;
+  result += a3.a0;
+  result += a3.a1;
+  result += a3.a2;
+  result += a3.a3;
+  result += a3.a4;
+  result += a4.a0;
+  result += a4.a1;
+  result += a4.a2;
+  result += a4.a3;
+  result += a4.a4;
+  result += a5.a0;
+  result += a5.a1;
+  result += a5.a2;
+  result += a5.a3;
+  result += a5.a4;
+  result += a6.a0;
+  result += a6.a1;
+  result += a6.a2;
+  result += a6.a3;
+  result += a6.a4;
+  result += a7.a0;
+  result += a7.a1;
+  result += a7.a2;
+  result += a7.a3;
+  result += a7.a4;
+  result += a8.a0;
+  result += a8.a1;
+  result += a8.a2;
+  result += a8.a3;
+  result += a8.a4;
+  result += a9.a0;
+  result += a9.a1;
+  result += a9.a2;
+  result += a9.a3;
+  result += a9.a4;
+
+  std::cout << "result = " << result << "\n";
+
+  return result;
+}
+
+// Used for testing structs by value.
+// Struct with mis-aligned member.
+// Tests backfilling of CPU and FPU registers.
+DART_EXPORT double PassStruct9BytesPackedMixedx10DoubleInt32(
+    Struct9BytesPackedMixed a0,
+    Struct9BytesPackedMixed a1,
+    Struct9BytesPackedMixed a2,
+    Struct9BytesPackedMixed a3,
+    Struct9BytesPackedMixed a4,
+    Struct9BytesPackedMixed a5,
+    Struct9BytesPackedMixed a6,
+    Struct9BytesPackedMixed a7,
+    Struct9BytesPackedMixed a8,
+    Struct9BytesPackedMixed a9,
+    double a10,
+    int32_t a11) {
+  std::cout << "PassStruct9BytesPackedMixedx10DoubleInt32"
+            << "((" << static_cast<int>(a0.a0) << ", " << a0.a1 << "), ("
+            << static_cast<int>(a1.a0) << ", " << a1.a1 << "), ("
+            << static_cast<int>(a2.a0) << ", " << a2.a1 << "), ("
+            << static_cast<int>(a3.a0) << ", " << a3.a1 << "), ("
+            << static_cast<int>(a4.a0) << ", " << a4.a1 << "), ("
+            << static_cast<int>(a5.a0) << ", " << a5.a1 << "), ("
+            << static_cast<int>(a6.a0) << ", " << a6.a1 << "), ("
+            << static_cast<int>(a7.a0) << ", " << a7.a1 << "), ("
+            << static_cast<int>(a8.a0) << ", " << a8.a1 << "), ("
+            << static_cast<int>(a9.a0) << ", " << a9.a1 << "), " << a10 << ", "
+            << a11 << ")"
+            << "\n";
+
+  double result = 0;
+
+  result += a0.a0;
+  result += a0.a1;
+  result += a1.a0;
+  result += a1.a1;
+  result += a2.a0;
+  result += a2.a1;
+  result += a3.a0;
+  result += a3.a1;
+  result += a4.a0;
+  result += a4.a1;
+  result += a5.a0;
+  result += a5.a1;
+  result += a6.a0;
+  result += a6.a1;
+  result += a7.a0;
+  result += a7.a1;
+  result += a8.a0;
+  result += a8.a1;
+  result += a9.a0;
+  result += a9.a1;
+  result += a10;
+  result += a11;
+
+  std::cout << "result = " << result << "\n";
+
+  return result;
+}
+
+// Used for testing structs by value.
+// This packed struct happens to have only aligned members.
+DART_EXPORT double PassStruct5BytesPackedMixed(Struct5BytesPackedMixed a0) {
+  std::cout << "PassStruct5BytesPackedMixed"
+            << "((" << a0.a0 << ", " << static_cast<int>(a0.a1) << "))"
+            << "\n";
+
+  double result = 0;
+
+  result += a0.a0;
+  result += a0.a1;
+
+  std::cout << "result = " << result << "\n";
+
+  return result;
+}
+
+// Used for testing structs by value.
+// Check alignment of packed struct in non-packed struct.
+DART_EXPORT double PassStructNestedAlignmentStruct5BytesPackedMixed(
+    StructNestedAlignmentStruct5BytesPackedMixed a0) {
+  std::cout << "PassStructNestedAlignmentStruct5BytesPackedMixed"
+            << "((" << static_cast<int>(a0.a0) << ", (" << a0.a1.a0 << ", "
+            << static_cast<int>(a0.a1.a1) << ")))"
+            << "\n";
+
+  double result = 0;
+
+  result += a0.a0;
+  result += a0.a1.a0;
+  result += a0.a1.a1;
+
+  std::cout << "result = " << result << "\n";
+
+  return result;
+}
+
+// Used for testing structs by value.
+// Check alignment of packed struct array in non-packed struct.
+DART_EXPORT double PassStruct6BytesInlineArrayInt(
+    Struct6BytesInlineArrayInt a0) {
+  std::cout << "PassStruct6BytesInlineArrayInt"
+            << "(([(" << static_cast<int>(a0.a0[0].a0) << ", " << a0.a0[0].a1
+            << "), (" << static_cast<int>(a0.a0[1].a0) << ", " << a0.a0[1].a1
+            << ")]))"
+            << "\n";
+
+  double result = 0;
+
+  result += a0.a0[0].a0;
+  result += a0.a0[0].a1;
+  result += a0.a0[1].a0;
+  result += a0.a0[1].a1;
+
+  std::cout << "result = " << result << "\n";
+
+  return result;
+}
+
+// Used for testing structs by value.
+// Check alignment of packed struct array in non-packed struct.
+DART_EXPORT double PassStruct15BytesInlineArrayMixed(
+    Struct15BytesInlineArrayMixed a0) {
+  std::cout << "PassStruct15BytesInlineArrayMixed"
+            << "(([(" << a0.a0[0].a0 << ", " << static_cast<int>(a0.a0[0].a1)
+            << "), (" << a0.a0[1].a0 << ", " << static_cast<int>(a0.a0[1].a1)
+            << "), (" << a0.a0[2].a0 << ", " << static_cast<int>(a0.a0[2].a1)
+            << ")]))"
+            << "\n";
+
+  double result = 0;
+
+  result += a0.a0[0].a0;
+  result += a0.a0[0].a1;
+  result += a0.a0[1].a0;
+  result += a0.a0[1].a1;
+  result += a0.a0[2].a0;
+  result += a0.a0[2].a1;
+
+  std::cout << "result = " << result << "\n";
+
+  return result;
+}
+
+// Used for testing structs by value.
 // Smallest struct with data.
 DART_EXPORT Struct1ByteInt ReturnStruct1ByteInt(int8_t a0) {
   std::cout << "ReturnStruct1ByteInt"
@@ -4762,6 +5283,78 @@
 }
 
 // Used for testing structs by value.
+// Small struct with mis-aligned member.
+DART_EXPORT Struct3BytesPackedInt ReturnStruct3BytesPackedInt(int8_t a0,
+                                                              int16_t a1) {
+  std::cout << "ReturnStruct3BytesPackedInt"
+            << "(" << static_cast<int>(a0) << ", " << a1 << ")"
+            << "\n";
+
+  Struct3BytesPackedInt result;
+
+  result.a0 = a0;
+  result.a1 = a1;
+
+  std::cout << "result = "
+            << "(" << static_cast<int>(result.a0) << ", " << result.a1 << ")"
+            << "\n";
+
+  return result;
+}
+
+// Used for testing structs by value.
+// Struct with mis-aligned member.
+DART_EXPORT Struct8BytesPackedInt ReturnStruct8BytesPackedInt(uint8_t a0,
+                                                              uint32_t a1,
+                                                              uint8_t a2,
+                                                              uint8_t a3,
+                                                              uint8_t a4) {
+  std::cout << "ReturnStruct8BytesPackedInt"
+            << "(" << static_cast<int>(a0) << ", " << a1 << ", "
+            << static_cast<int>(a2) << ", " << static_cast<int>(a3) << ", "
+            << static_cast<int>(a4) << ")"
+            << "\n";
+
+  Struct8BytesPackedInt result;
+
+  result.a0 = a0;
+  result.a1 = a1;
+  result.a2 = a2;
+  result.a3 = a3;
+  result.a4 = a4;
+
+  std::cout << "result = "
+            << "(" << static_cast<int>(result.a0) << ", " << result.a1 << ", "
+            << static_cast<int>(result.a2) << ", "
+            << static_cast<int>(result.a3) << ", "
+            << static_cast<int>(result.a4) << ")"
+            << "\n";
+
+  return result;
+}
+
+// Used for testing structs by value.
+// Struct with mis-aligned member.
+// Tests backfilling of CPU and FPU registers.
+DART_EXPORT Struct9BytesPackedMixed ReturnStruct9BytesPackedMixed(uint8_t a0,
+                                                                  double a1) {
+  std::cout << "ReturnStruct9BytesPackedMixed"
+            << "(" << static_cast<int>(a0) << ", " << a1 << ")"
+            << "\n";
+
+  Struct9BytesPackedMixed result;
+
+  result.a0 = a0;
+  result.a1 = a1;
+
+  std::cout << "result = "
+            << "(" << static_cast<int>(result.a0) << ", " << result.a1 << ")"
+            << "\n";
+
+  return result;
+}
+
+// Used for testing structs by value.
 // Test that a struct passed in as argument can be returned.
 // Especially for ffi callbacks.
 // Struct is passed in int registers in most ABIs.
@@ -9997,6 +10590,671 @@
 }
 
 // Used for testing structs by value.
+// Test multi dimensional inline array struct as argument.
+DART_EXPORT intptr_t TestPassUint8Struct32BytesInlineArrayMultiDimensionalI(
+    // NOLINTNEXTLINE(whitespace/parens)
+    uint32_t (*f)(uint8_t a0,
+                  Struct32BytesInlineArrayMultiDimensionalInt a1,
+                  uint8_t a2,
+                  Struct8BytesInlineArrayMultiDimensionalInt a3,
+                  uint8_t a4,
+                  Struct8BytesInlineArrayMultiDimensionalInt a5,
+                  uint8_t a6)) {
+  uint8_t a0;
+  Struct32BytesInlineArrayMultiDimensionalInt a1;
+  uint8_t a2;
+  Struct8BytesInlineArrayMultiDimensionalInt a3;
+  uint8_t a4;
+  Struct8BytesInlineArrayMultiDimensionalInt a5;
+  uint8_t a6;
+
+  a0 = 1;
+  a1.a0[0][0][0][0][0] = 2;
+  a1.a0[0][0][0][0][1] = 3;
+  a1.a0[0][0][0][1][0] = 4;
+  a1.a0[0][0][0][1][1] = 5;
+  a1.a0[0][0][1][0][0] = 6;
+  a1.a0[0][0][1][0][1] = 7;
+  a1.a0[0][0][1][1][0] = 8;
+  a1.a0[0][0][1][1][1] = 9;
+  a1.a0[0][1][0][0][0] = 10;
+  a1.a0[0][1][0][0][1] = 11;
+  a1.a0[0][1][0][1][0] = 12;
+  a1.a0[0][1][0][1][1] = 13;
+  a1.a0[0][1][1][0][0] = 14;
+  a1.a0[0][1][1][0][1] = 15;
+  a1.a0[0][1][1][1][0] = 16;
+  a1.a0[0][1][1][1][1] = 17;
+  a1.a0[1][0][0][0][0] = 18;
+  a1.a0[1][0][0][0][1] = 19;
+  a1.a0[1][0][0][1][0] = 20;
+  a1.a0[1][0][0][1][1] = 21;
+  a1.a0[1][0][1][0][0] = 22;
+  a1.a0[1][0][1][0][1] = 23;
+  a1.a0[1][0][1][1][0] = 24;
+  a1.a0[1][0][1][1][1] = 25;
+  a1.a0[1][1][0][0][0] = 26;
+  a1.a0[1][1][0][0][1] = 27;
+  a1.a0[1][1][0][1][0] = 28;
+  a1.a0[1][1][0][1][1] = 29;
+  a1.a0[1][1][1][0][0] = 30;
+  a1.a0[1][1][1][0][1] = 31;
+  a1.a0[1][1][1][1][0] = 32;
+  a1.a0[1][1][1][1][1] = 33;
+  a2 = 34;
+  a3.a0[0][0][0] = 35;
+  a3.a0[0][0][1] = 36;
+  a3.a0[0][1][0] = 37;
+  a3.a0[0][1][1] = 38;
+  a3.a0[1][0][0] = 39;
+  a3.a0[1][0][1] = 40;
+  a3.a0[1][1][0] = 41;
+  a3.a0[1][1][1] = 42;
+  a4 = 43;
+  a5.a0[0][0][0] = 44;
+  a5.a0[0][0][1] = 45;
+  a5.a0[0][1][0] = 46;
+  a5.a0[0][1][1] = 47;
+  a5.a0[1][0][0] = 48;
+  a5.a0[1][0][1] = 49;
+  a5.a0[1][1][0] = 50;
+  a5.a0[1][1][1] = 51;
+  a6 = 52;
+
+  std::cout << "Calling TestPassUint8Struct32BytesInlineArrayMultiDimensionalI("
+            << "(" << static_cast<int>(a0) << ", ([[[[["
+            << static_cast<int>(a1.a0[0][0][0][0][0]) << ", "
+            << static_cast<int>(a1.a0[0][0][0][0][1]) << "], ["
+            << static_cast<int>(a1.a0[0][0][0][1][0]) << ", "
+            << static_cast<int>(a1.a0[0][0][0][1][1]) << "]], [["
+            << static_cast<int>(a1.a0[0][0][1][0][0]) << ", "
+            << static_cast<int>(a1.a0[0][0][1][0][1]) << "], ["
+            << static_cast<int>(a1.a0[0][0][1][1][0]) << ", "
+            << static_cast<int>(a1.a0[0][0][1][1][1]) << "]]], [[["
+            << static_cast<int>(a1.a0[0][1][0][0][0]) << ", "
+            << static_cast<int>(a1.a0[0][1][0][0][1]) << "], ["
+            << static_cast<int>(a1.a0[0][1][0][1][0]) << ", "
+            << static_cast<int>(a1.a0[0][1][0][1][1]) << "]], [["
+            << static_cast<int>(a1.a0[0][1][1][0][0]) << ", "
+            << static_cast<int>(a1.a0[0][1][1][0][1]) << "], ["
+            << static_cast<int>(a1.a0[0][1][1][1][0]) << ", "
+            << static_cast<int>(a1.a0[0][1][1][1][1]) << "]]]], [[[["
+            << static_cast<int>(a1.a0[1][0][0][0][0]) << ", "
+            << static_cast<int>(a1.a0[1][0][0][0][1]) << "], ["
+            << static_cast<int>(a1.a0[1][0][0][1][0]) << ", "
+            << static_cast<int>(a1.a0[1][0][0][1][1]) << "]], [["
+            << static_cast<int>(a1.a0[1][0][1][0][0]) << ", "
+            << static_cast<int>(a1.a0[1][0][1][0][1]) << "], ["
+            << static_cast<int>(a1.a0[1][0][1][1][0]) << ", "
+            << static_cast<int>(a1.a0[1][0][1][1][1]) << "]]], [[["
+            << static_cast<int>(a1.a0[1][1][0][0][0]) << ", "
+            << static_cast<int>(a1.a0[1][1][0][0][1]) << "], ["
+            << static_cast<int>(a1.a0[1][1][0][1][0]) << ", "
+            << static_cast<int>(a1.a0[1][1][0][1][1]) << "]], [["
+            << static_cast<int>(a1.a0[1][1][1][0][0]) << ", "
+            << static_cast<int>(a1.a0[1][1][1][0][1]) << "], ["
+            << static_cast<int>(a1.a0[1][1][1][1][0]) << ", "
+            << static_cast<int>(a1.a0[1][1][1][1][1]) << "]]]]]), "
+            << static_cast<int>(a2) << ", ([[["
+            << static_cast<int>(a3.a0[0][0][0]) << ", "
+            << static_cast<int>(a3.a0[0][0][1]) << "], ["
+            << static_cast<int>(a3.a0[0][1][0]) << ", "
+            << static_cast<int>(a3.a0[0][1][1]) << "]], [["
+            << static_cast<int>(a3.a0[1][0][0]) << ", "
+            << static_cast<int>(a3.a0[1][0][1]) << "], ["
+            << static_cast<int>(a3.a0[1][1][0]) << ", "
+            << static_cast<int>(a3.a0[1][1][1]) << "]]]), "
+            << static_cast<int>(a4) << ", ([[["
+            << static_cast<int>(a5.a0[0][0][0]) << ", "
+            << static_cast<int>(a5.a0[0][0][1]) << "], ["
+            << static_cast<int>(a5.a0[0][1][0]) << ", "
+            << static_cast<int>(a5.a0[0][1][1]) << "]], [["
+            << static_cast<int>(a5.a0[1][0][0]) << ", "
+            << static_cast<int>(a5.a0[1][0][1]) << "], ["
+            << static_cast<int>(a5.a0[1][1][0]) << ", "
+            << static_cast<int>(a5.a0[1][1][1]) << "]]]), "
+            << static_cast<int>(a6) << ")"
+            << ")\n";
+
+  uint32_t result = f(a0, a1, a2, a3, a4, a5, a6);
+
+  std::cout << "result = " << result << "\n";
+
+  CHECK_EQ(1378, result);
+
+  // Pass argument that will make the Dart callback throw.
+  a0 = 42;
+
+  result = f(a0, a1, a2, a3, a4, a5, a6);
+
+  CHECK_EQ(0, result);
+
+  // Pass argument that will make the Dart callback return null.
+  a0 = 84;
+
+  result = f(a0, a1, a2, a3, a4, a5, a6);
+
+  CHECK_EQ(0, result);
+
+  return 0;
+}
+
+// Used for testing structs by value.
+// Test struct in multi dimensional inline array.
+DART_EXPORT intptr_t TestPassUint8Struct4BytesInlineArrayMultiDimensionalIn(
+    // NOLINTNEXTLINE(whitespace/parens)
+    uint32_t (*f)(uint8_t a0,
+                  Struct4BytesInlineArrayMultiDimensionalInt a1,
+                  uint8_t a2)) {
+  uint8_t a0;
+  Struct4BytesInlineArrayMultiDimensionalInt a1;
+  uint8_t a2;
+
+  a0 = 1;
+  a1.a0[0][0].a0 = 2;
+  a1.a0[0][1].a0 = -3;
+  a1.a0[1][0].a0 = 4;
+  a1.a0[1][1].a0 = -5;
+  a2 = 6;
+
+  std::cout << "Calling TestPassUint8Struct4BytesInlineArrayMultiDimensionalIn("
+            << "(" << static_cast<int>(a0) << ", ([[("
+            << static_cast<int>(a1.a0[0][0].a0) << "), ("
+            << static_cast<int>(a1.a0[0][1].a0) << ")], [("
+            << static_cast<int>(a1.a0[1][0].a0) << "), ("
+            << static_cast<int>(a1.a0[1][1].a0) << ")]]), "
+            << static_cast<int>(a2) << ")"
+            << ")\n";
+
+  uint32_t result = f(a0, a1, a2);
+
+  std::cout << "result = " << result << "\n";
+
+  CHECK_EQ(5, result);
+
+  // Pass argument that will make the Dart callback throw.
+  a0 = 42;
+
+  result = f(a0, a1, a2);
+
+  CHECK_EQ(0, result);
+
+  // Pass argument that will make the Dart callback return null.
+  a0 = 84;
+
+  result = f(a0, a1, a2);
+
+  CHECK_EQ(0, result);
+
+  return 0;
+}
+
+// Used for testing structs by value.
+// Small struct with mis-aligned member.
+DART_EXPORT intptr_t TestPassStruct3BytesPackedIntx10(
+    // NOLINTNEXTLINE(whitespace/parens)
+    int64_t (*f)(Struct3BytesPackedInt a0,
+                 Struct3BytesPackedInt a1,
+                 Struct3BytesPackedInt a2,
+                 Struct3BytesPackedInt a3,
+                 Struct3BytesPackedInt a4,
+                 Struct3BytesPackedInt a5,
+                 Struct3BytesPackedInt a6,
+                 Struct3BytesPackedInt a7,
+                 Struct3BytesPackedInt a8,
+                 Struct3BytesPackedInt a9)) {
+  Struct3BytesPackedInt a0;
+  Struct3BytesPackedInt a1;
+  Struct3BytesPackedInt a2;
+  Struct3BytesPackedInt a3;
+  Struct3BytesPackedInt a4;
+  Struct3BytesPackedInt a5;
+  Struct3BytesPackedInt a6;
+  Struct3BytesPackedInt a7;
+  Struct3BytesPackedInt a8;
+  Struct3BytesPackedInt a9;
+
+  a0.a0 = -1;
+  a0.a1 = 2;
+  a1.a0 = -3;
+  a1.a1 = 4;
+  a2.a0 = -5;
+  a2.a1 = 6;
+  a3.a0 = -7;
+  a3.a1 = 8;
+  a4.a0 = -9;
+  a4.a1 = 10;
+  a5.a0 = -11;
+  a5.a1 = 12;
+  a6.a0 = -13;
+  a6.a1 = 14;
+  a7.a0 = -15;
+  a7.a1 = 16;
+  a8.a0 = -17;
+  a8.a1 = 18;
+  a9.a0 = -19;
+  a9.a1 = 20;
+
+  std::cout << "Calling TestPassStruct3BytesPackedIntx10("
+            << "((" << static_cast<int>(a0.a0) << ", " << a0.a1 << "), ("
+            << static_cast<int>(a1.a0) << ", " << a1.a1 << "), ("
+            << static_cast<int>(a2.a0) << ", " << a2.a1 << "), ("
+            << static_cast<int>(a3.a0) << ", " << a3.a1 << "), ("
+            << static_cast<int>(a4.a0) << ", " << a4.a1 << "), ("
+            << static_cast<int>(a5.a0) << ", " << a5.a1 << "), ("
+            << static_cast<int>(a6.a0) << ", " << a6.a1 << "), ("
+            << static_cast<int>(a7.a0) << ", " << a7.a1 << "), ("
+            << static_cast<int>(a8.a0) << ", " << a8.a1 << "), ("
+            << static_cast<int>(a9.a0) << ", " << a9.a1 << "))"
+            << ")\n";
+
+  int64_t result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  std::cout << "result = " << result << "\n";
+
+  CHECK_EQ(10, result);
+
+  // Pass argument that will make the Dart callback throw.
+  a0.a0 = 42;
+
+  result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  CHECK_EQ(0, result);
+
+  // Pass argument that will make the Dart callback return null.
+  a0.a0 = 84;
+
+  result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  CHECK_EQ(0, result);
+
+  return 0;
+}
+
+// Used for testing structs by value.
+// Struct with mis-aligned member.
+DART_EXPORT intptr_t TestPassStruct8BytesPackedIntx10(
+    // NOLINTNEXTLINE(whitespace/parens)
+    int64_t (*f)(Struct8BytesPackedInt a0,
+                 Struct8BytesPackedInt a1,
+                 Struct8BytesPackedInt a2,
+                 Struct8BytesPackedInt a3,
+                 Struct8BytesPackedInt a4,
+                 Struct8BytesPackedInt a5,
+                 Struct8BytesPackedInt a6,
+                 Struct8BytesPackedInt a7,
+                 Struct8BytesPackedInt a8,
+                 Struct8BytesPackedInt a9)) {
+  Struct8BytesPackedInt a0;
+  Struct8BytesPackedInt a1;
+  Struct8BytesPackedInt a2;
+  Struct8BytesPackedInt a3;
+  Struct8BytesPackedInt a4;
+  Struct8BytesPackedInt a5;
+  Struct8BytesPackedInt a6;
+  Struct8BytesPackedInt a7;
+  Struct8BytesPackedInt a8;
+  Struct8BytesPackedInt a9;
+
+  a0.a0 = 1;
+  a0.a1 = 2;
+  a0.a2 = 3;
+  a0.a3 = 4;
+  a0.a4 = 5;
+  a1.a0 = 6;
+  a1.a1 = 7;
+  a1.a2 = 8;
+  a1.a3 = 9;
+  a1.a4 = 10;
+  a2.a0 = 11;
+  a2.a1 = 12;
+  a2.a2 = 13;
+  a2.a3 = 14;
+  a2.a4 = 15;
+  a3.a0 = 16;
+  a3.a1 = 17;
+  a3.a2 = 18;
+  a3.a3 = 19;
+  a3.a4 = 20;
+  a4.a0 = 21;
+  a4.a1 = 22;
+  a4.a2 = 23;
+  a4.a3 = 24;
+  a4.a4 = 25;
+  a5.a0 = 26;
+  a5.a1 = 27;
+  a5.a2 = 28;
+  a5.a3 = 29;
+  a5.a4 = 30;
+  a6.a0 = 31;
+  a6.a1 = 32;
+  a6.a2 = 33;
+  a6.a3 = 34;
+  a6.a4 = 35;
+  a7.a0 = 36;
+  a7.a1 = 37;
+  a7.a2 = 38;
+  a7.a3 = 39;
+  a7.a4 = 40;
+  a8.a0 = 41;
+  a8.a1 = 42;
+  a8.a2 = 43;
+  a8.a3 = 44;
+  a8.a4 = 45;
+  a9.a0 = 46;
+  a9.a1 = 47;
+  a9.a2 = 48;
+  a9.a3 = 49;
+  a9.a4 = 50;
+
+  std::cout << "Calling TestPassStruct8BytesPackedIntx10("
+            << "((" << static_cast<int>(a0.a0) << ", " << a0.a1 << ", "
+            << static_cast<int>(a0.a2) << ", " << static_cast<int>(a0.a3)
+            << ", " << static_cast<int>(a0.a4) << "), ("
+            << static_cast<int>(a1.a0) << ", " << a1.a1 << ", "
+            << static_cast<int>(a1.a2) << ", " << static_cast<int>(a1.a3)
+            << ", " << static_cast<int>(a1.a4) << "), ("
+            << static_cast<int>(a2.a0) << ", " << a2.a1 << ", "
+            << static_cast<int>(a2.a2) << ", " << static_cast<int>(a2.a3)
+            << ", " << static_cast<int>(a2.a4) << "), ("
+            << static_cast<int>(a3.a0) << ", " << a3.a1 << ", "
+            << static_cast<int>(a3.a2) << ", " << static_cast<int>(a3.a3)
+            << ", " << static_cast<int>(a3.a4) << "), ("
+            << static_cast<int>(a4.a0) << ", " << a4.a1 << ", "
+            << static_cast<int>(a4.a2) << ", " << static_cast<int>(a4.a3)
+            << ", " << static_cast<int>(a4.a4) << "), ("
+            << static_cast<int>(a5.a0) << ", " << a5.a1 << ", "
+            << static_cast<int>(a5.a2) << ", " << static_cast<int>(a5.a3)
+            << ", " << static_cast<int>(a5.a4) << "), ("
+            << static_cast<int>(a6.a0) << ", " << a6.a1 << ", "
+            << static_cast<int>(a6.a2) << ", " << static_cast<int>(a6.a3)
+            << ", " << static_cast<int>(a6.a4) << "), ("
+            << static_cast<int>(a7.a0) << ", " << a7.a1 << ", "
+            << static_cast<int>(a7.a2) << ", " << static_cast<int>(a7.a3)
+            << ", " << static_cast<int>(a7.a4) << "), ("
+            << static_cast<int>(a8.a0) << ", " << a8.a1 << ", "
+            << static_cast<int>(a8.a2) << ", " << static_cast<int>(a8.a3)
+            << ", " << static_cast<int>(a8.a4) << "), ("
+            << static_cast<int>(a9.a0) << ", " << a9.a1 << ", "
+            << static_cast<int>(a9.a2) << ", " << static_cast<int>(a9.a3)
+            << ", " << static_cast<int>(a9.a4) << "))"
+            << ")\n";
+
+  int64_t result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  std::cout << "result = " << result << "\n";
+
+  CHECK_EQ(1275, result);
+
+  // Pass argument that will make the Dart callback throw.
+  a0.a0 = 42;
+
+  result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  CHECK_EQ(0, result);
+
+  // Pass argument that will make the Dart callback return null.
+  a0.a0 = 84;
+
+  result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  CHECK_EQ(0, result);
+
+  return 0;
+}
+
+// Used for testing structs by value.
+// Struct with mis-aligned member.
+// Tests backfilling of CPU and FPU registers.
+DART_EXPORT intptr_t TestPassStruct9BytesPackedMixedx10DoubleInt32(
+    // NOLINTNEXTLINE(whitespace/parens)
+    double (*f)(Struct9BytesPackedMixed a0,
+                Struct9BytesPackedMixed a1,
+                Struct9BytesPackedMixed a2,
+                Struct9BytesPackedMixed a3,
+                Struct9BytesPackedMixed a4,
+                Struct9BytesPackedMixed a5,
+                Struct9BytesPackedMixed a6,
+                Struct9BytesPackedMixed a7,
+                Struct9BytesPackedMixed a8,
+                Struct9BytesPackedMixed a9,
+                double a10,
+                int32_t a11)) {
+  Struct9BytesPackedMixed a0;
+  Struct9BytesPackedMixed a1;
+  Struct9BytesPackedMixed a2;
+  Struct9BytesPackedMixed a3;
+  Struct9BytesPackedMixed a4;
+  Struct9BytesPackedMixed a5;
+  Struct9BytesPackedMixed a6;
+  Struct9BytesPackedMixed a7;
+  Struct9BytesPackedMixed a8;
+  Struct9BytesPackedMixed a9;
+  double a10;
+  int32_t a11;
+
+  a0.a0 = 1;
+  a0.a1 = 2.0;
+  a1.a0 = 3;
+  a1.a1 = 4.0;
+  a2.a0 = 5;
+  a2.a1 = 6.0;
+  a3.a0 = 7;
+  a3.a1 = 8.0;
+  a4.a0 = 9;
+  a4.a1 = 10.0;
+  a5.a0 = 11;
+  a5.a1 = 12.0;
+  a6.a0 = 13;
+  a6.a1 = 14.0;
+  a7.a0 = 15;
+  a7.a1 = 16.0;
+  a8.a0 = 17;
+  a8.a1 = 18.0;
+  a9.a0 = 19;
+  a9.a1 = 20.0;
+  a10 = -21.0;
+  a11 = 22;
+
+  std::cout << "Calling TestPassStruct9BytesPackedMixedx10DoubleInt32("
+            << "((" << static_cast<int>(a0.a0) << ", " << a0.a1 << "), ("
+            << static_cast<int>(a1.a0) << ", " << a1.a1 << "), ("
+            << static_cast<int>(a2.a0) << ", " << a2.a1 << "), ("
+            << static_cast<int>(a3.a0) << ", " << a3.a1 << "), ("
+            << static_cast<int>(a4.a0) << ", " << a4.a1 << "), ("
+            << static_cast<int>(a5.a0) << ", " << a5.a1 << "), ("
+            << static_cast<int>(a6.a0) << ", " << a6.a1 << "), ("
+            << static_cast<int>(a7.a0) << ", " << a7.a1 << "), ("
+            << static_cast<int>(a8.a0) << ", " << a8.a1 << "), ("
+            << static_cast<int>(a9.a0) << ", " << a9.a1 << "), " << a10 << ", "
+            << a11 << ")"
+            << ")\n";
+
+  double result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11);
+
+  std::cout << "result = " << result << "\n";
+
+  CHECK_APPROX(211.0, result);
+
+  // Pass argument that will make the Dart callback throw.
+  a0.a0 = 42;
+
+  result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11);
+
+  CHECK_APPROX(0.0, result);
+
+  // Pass argument that will make the Dart callback return null.
+  a0.a0 = 84;
+
+  result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11);
+
+  CHECK_APPROX(0.0, result);
+
+  return 0;
+}
+
+// Used for testing structs by value.
+// This packed struct happens to have only aligned members.
+DART_EXPORT intptr_t TestPassStruct5BytesPackedMixed(
+    // NOLINTNEXTLINE(whitespace/parens)
+    double (*f)(Struct5BytesPackedMixed a0)) {
+  Struct5BytesPackedMixed a0;
+
+  a0.a0 = -1.0;
+  a0.a1 = 2;
+
+  std::cout << "Calling TestPassStruct5BytesPackedMixed("
+            << "((" << a0.a0 << ", " << static_cast<int>(a0.a1) << "))"
+            << ")\n";
+
+  double result = f(a0);
+
+  std::cout << "result = " << result << "\n";
+
+  CHECK_APPROX(1.0, result);
+
+  // Pass argument that will make the Dart callback throw.
+  a0.a0 = 42;
+
+  result = f(a0);
+
+  CHECK_APPROX(0.0, result);
+
+  // Pass argument that will make the Dart callback return null.
+  a0.a0 = 84;
+
+  result = f(a0);
+
+  CHECK_APPROX(0.0, result);
+
+  return 0;
+}
+
+// Used for testing structs by value.
+// Check alignment of packed struct in non-packed struct.
+DART_EXPORT intptr_t TestPassStructNestedAlignmentStruct5BytesPackedMixed(
+    // NOLINTNEXTLINE(whitespace/parens)
+    double (*f)(StructNestedAlignmentStruct5BytesPackedMixed a0)) {
+  StructNestedAlignmentStruct5BytesPackedMixed a0;
+
+  a0.a0 = 1;
+  a0.a1.a0 = 2.0;
+  a0.a1.a1 = 3;
+
+  std::cout << "Calling TestPassStructNestedAlignmentStruct5BytesPackedMixed("
+            << "((" << static_cast<int>(a0.a0) << ", (" << a0.a1.a0 << ", "
+            << static_cast<int>(a0.a1.a1) << ")))"
+            << ")\n";
+
+  double result = f(a0);
+
+  std::cout << "result = " << result << "\n";
+
+  CHECK_APPROX(6.0, result);
+
+  // Pass argument that will make the Dart callback throw.
+  a0.a0 = 42;
+
+  result = f(a0);
+
+  CHECK_APPROX(0.0, result);
+
+  // Pass argument that will make the Dart callback return null.
+  a0.a0 = 84;
+
+  result = f(a0);
+
+  CHECK_APPROX(0.0, result);
+
+  return 0;
+}
+
+// Used for testing structs by value.
+// Check alignment of packed struct array in non-packed struct.
+DART_EXPORT intptr_t TestPassStruct6BytesInlineArrayInt(
+    // NOLINTNEXTLINE(whitespace/parens)
+    double (*f)(Struct6BytesInlineArrayInt a0)) {
+  Struct6BytesInlineArrayInt a0;
+
+  a0.a0[0].a0 = -1;
+  a0.a0[0].a1 = 2;
+  a0.a0[1].a0 = -3;
+  a0.a0[1].a1 = 4;
+
+  std::cout << "Calling TestPassStruct6BytesInlineArrayInt("
+            << "(([(" << static_cast<int>(a0.a0[0].a0) << ", " << a0.a0[0].a1
+            << "), (" << static_cast<int>(a0.a0[1].a0) << ", " << a0.a0[1].a1
+            << ")]))"
+            << ")\n";
+
+  double result = f(a0);
+
+  std::cout << "result = " << result << "\n";
+
+  CHECK_APPROX(2.0, result);
+
+  // Pass argument that will make the Dart callback throw.
+  a0.a0[0].a0 = 42;
+
+  result = f(a0);
+
+  CHECK_APPROX(0.0, result);
+
+  // Pass argument that will make the Dart callback return null.
+  a0.a0[0].a0 = 84;
+
+  result = f(a0);
+
+  CHECK_APPROX(0.0, result);
+
+  return 0;
+}
+
+// Used for testing structs by value.
+// Check alignment of packed struct array in non-packed struct.
+DART_EXPORT intptr_t TestPassStruct15BytesInlineArrayMixed(
+    // NOLINTNEXTLINE(whitespace/parens)
+    double (*f)(Struct15BytesInlineArrayMixed a0)) {
+  Struct15BytesInlineArrayMixed a0;
+
+  a0.a0[0].a0 = -1.0;
+  a0.a0[0].a1 = 2;
+  a0.a0[1].a0 = -3.0;
+  a0.a0[1].a1 = 4;
+  a0.a0[2].a0 = -5.0;
+  a0.a0[2].a1 = 6;
+
+  std::cout << "Calling TestPassStruct15BytesInlineArrayMixed("
+            << "(([(" << a0.a0[0].a0 << ", " << static_cast<int>(a0.a0[0].a1)
+            << "), (" << a0.a0[1].a0 << ", " << static_cast<int>(a0.a0[1].a1)
+            << "), (" << a0.a0[2].a0 << ", " << static_cast<int>(a0.a0[2].a1)
+            << ")]))"
+            << ")\n";
+
+  double result = f(a0);
+
+  std::cout << "result = " << result << "\n";
+
+  CHECK_APPROX(3.0, result);
+
+  // Pass argument that will make the Dart callback throw.
+  a0.a0[0].a0 = 42;
+
+  result = f(a0);
+
+  CHECK_APPROX(0.0, result);
+
+  // Pass argument that will make the Dart callback return null.
+  a0.a0[0].a0 = 84;
+
+  result = f(a0);
+
+  CHECK_APPROX(0.0, result);
+
+  return 0;
+}
+
+// Used for testing structs by value.
 // Smallest struct with data.
 DART_EXPORT intptr_t TestReturnStruct1ByteInt(
     // NOLINTNEXTLINE(whitespace/parens)
@@ -12157,6 +13415,157 @@
 }
 
 // Used for testing structs by value.
+// Small struct with mis-aligned member.
+DART_EXPORT intptr_t TestReturnStruct3BytesPackedInt(
+    // NOLINTNEXTLINE(whitespace/parens)
+    Struct3BytesPackedInt (*f)(int8_t a0, int16_t a1)) {
+  int8_t a0;
+  int16_t a1;
+
+  a0 = -1;
+  a1 = 2;
+
+  std::cout << "Calling TestReturnStruct3BytesPackedInt("
+            << "(" << static_cast<int>(a0) << ", " << a1 << ")"
+            << ")\n";
+
+  Struct3BytesPackedInt result = f(a0, a1);
+
+  std::cout << "result = "
+            << "(" << static_cast<int>(result.a0) << ", " << result.a1 << ")"
+            << "\n";
+
+  CHECK_EQ(a0, result.a0);
+  CHECK_EQ(a1, result.a1);
+
+  // Pass argument that will make the Dart callback throw.
+  a0 = 42;
+
+  result = f(a0, a1);
+
+  CHECK_EQ(0, result.a0);
+  CHECK_EQ(0, result.a1);
+
+  // Pass argument that will make the Dart callback return null.
+  a0 = 84;
+
+  result = f(a0, a1);
+
+  CHECK_EQ(0, result.a0);
+  CHECK_EQ(0, result.a1);
+
+  return 0;
+}
+
+// Used for testing structs by value.
+// Struct with mis-aligned member.
+DART_EXPORT intptr_t TestReturnStruct8BytesPackedInt(
+    // NOLINTNEXTLINE(whitespace/parens)
+    Struct8BytesPackedInt (
+        *f)(uint8_t a0, uint32_t a1, uint8_t a2, uint8_t a3, uint8_t a4)) {
+  uint8_t a0;
+  uint32_t a1;
+  uint8_t a2;
+  uint8_t a3;
+  uint8_t a4;
+
+  a0 = 1;
+  a1 = 2;
+  a2 = 3;
+  a3 = 4;
+  a4 = 5;
+
+  std::cout << "Calling TestReturnStruct8BytesPackedInt("
+            << "(" << static_cast<int>(a0) << ", " << a1 << ", "
+            << static_cast<int>(a2) << ", " << static_cast<int>(a3) << ", "
+            << static_cast<int>(a4) << ")"
+            << ")\n";
+
+  Struct8BytesPackedInt result = f(a0, a1, a2, a3, a4);
+
+  std::cout << "result = "
+            << "(" << static_cast<int>(result.a0) << ", " << result.a1 << ", "
+            << static_cast<int>(result.a2) << ", "
+            << static_cast<int>(result.a3) << ", "
+            << static_cast<int>(result.a4) << ")"
+            << "\n";
+
+  CHECK_EQ(a0, result.a0);
+  CHECK_EQ(a1, result.a1);
+  CHECK_EQ(a2, result.a2);
+  CHECK_EQ(a3, result.a3);
+  CHECK_EQ(a4, result.a4);
+
+  // Pass argument that will make the Dart callback throw.
+  a0 = 42;
+
+  result = f(a0, a1, a2, a3, a4);
+
+  CHECK_EQ(0, result.a0);
+  CHECK_EQ(0, result.a1);
+  CHECK_EQ(0, result.a2);
+  CHECK_EQ(0, result.a3);
+  CHECK_EQ(0, result.a4);
+
+  // Pass argument that will make the Dart callback return null.
+  a0 = 84;
+
+  result = f(a0, a1, a2, a3, a4);
+
+  CHECK_EQ(0, result.a0);
+  CHECK_EQ(0, result.a1);
+  CHECK_EQ(0, result.a2);
+  CHECK_EQ(0, result.a3);
+  CHECK_EQ(0, result.a4);
+
+  return 0;
+}
+
+// Used for testing structs by value.
+// Struct with mis-aligned member.
+// Tests backfilling of CPU and FPU registers.
+DART_EXPORT intptr_t TestReturnStruct9BytesPackedMixed(
+    // NOLINTNEXTLINE(whitespace/parens)
+    Struct9BytesPackedMixed (*f)(uint8_t a0, double a1)) {
+  uint8_t a0;
+  double a1;
+
+  a0 = 1;
+  a1 = 2.0;
+
+  std::cout << "Calling TestReturnStruct9BytesPackedMixed("
+            << "(" << static_cast<int>(a0) << ", " << a1 << ")"
+            << ")\n";
+
+  Struct9BytesPackedMixed result = f(a0, a1);
+
+  std::cout << "result = "
+            << "(" << static_cast<int>(result.a0) << ", " << result.a1 << ")"
+            << "\n";
+
+  CHECK_EQ(a0, result.a0);
+  CHECK_APPROX(a1, result.a1);
+
+  // Pass argument that will make the Dart callback throw.
+  a0 = 42;
+
+  result = f(a0, a1);
+
+  CHECK_EQ(0, result.a0);
+  CHECK_APPROX(0.0, result.a1);
+
+  // Pass argument that will make the Dart callback return null.
+  a0 = 84;
+
+  result = f(a0, a1);
+
+  CHECK_EQ(0, result.a0);
+  CHECK_APPROX(0.0, result.a1);
+
+  return 0;
+}
+
+// Used for testing structs by value.
 // Test that a struct passed in as argument can be returned.
 // Especially for ffi callbacks.
 // Struct is passed in int registers in most ABIs.
diff --git a/runtime/bin/file_support.cc b/runtime/bin/file_support.cc
index 722e321..f70253f 100644
--- a/runtime/bin/file_support.cc
+++ b/runtime/bin/file_support.cc
@@ -71,15 +71,17 @@
   }
   if (capture_stdout || capture_stderr) {
     intptr_t fd = GetFD();
+    const char* result = nullptr;
     if ((fd == STDOUT_FILENO) && capture_stdout) {
-      Dart_ServiceSendDataEvent("Stdout", "WriteEvent",
-                                reinterpret_cast<const uint8_t*>(buffer),
-                                num_bytes);
+      result = Dart_ServiceSendDataEvent(
+          "Stdout", "WriteEvent", reinterpret_cast<const uint8_t*>(buffer),
+          num_bytes);
     } else if ((fd == STDERR_FILENO) && capture_stderr) {
-      Dart_ServiceSendDataEvent("Stderr", "WriteEvent",
-                                reinterpret_cast<const uint8_t*>(buffer),
-                                num_bytes);
+      result = Dart_ServiceSendDataEvent(
+          "Stderr", "WriteEvent", reinterpret_cast<const uint8_t*>(buffer),
+          num_bytes);
     }
+    ASSERT(result == nullptr);
   }
   return true;
 }
diff --git a/runtime/bin/io_natives.cc b/runtime/bin/io_natives.cc
index 9730817..ed0c781 100644
--- a/runtime/bin/io_natives.cc
+++ b/runtime/bin/io_natives.cc
@@ -89,6 +89,7 @@
   V(Namespace_GetDefault, 0)                                                   \
   V(Namespace_GetPointer, 1)                                                   \
   V(NetworkInterface_ListSupported, 0)                                         \
+  V(OSError_inProgressErrorCode, 0)                                            \
   V(Platform_NumberOfProcessors, 0)                                            \
   V(Platform_OperatingSystem, 0)                                               \
   V(Platform_OperatingSystemVersion, 0)                                        \
diff --git a/runtime/bin/loader.cc b/runtime/bin/loader.cc
index e855baf..df166696 100644
--- a/runtime/bin/loader.cc
+++ b/runtime/bin/loader.cc
@@ -79,7 +79,8 @@
 
   char* lib_path = NULL;
   if (strncmp(lib_uri_str, "file://", 7) == 0) {
-    lib_path = DartUtils::DirName(lib_uri_str + 7);
+    auto path = File::UriToPath(lib_uri_str);
+    lib_path = DartUtils::DirName(path.get());
   } else {
     lib_path = Utils::StrDup(lib_uri_str);
   }
@@ -125,7 +126,8 @@
 
     char* lib_path = NULL;
     if (strncmp(lib_uri, "file://", 7) == 0) {
-      lib_path = DartUtils::DirName(DartUtils::RemoveScheme(lib_uri));
+      auto path = File::UriToPath(lib_uri);
+      lib_path = DartUtils::DirName(path.get());
     } else {
       lib_path = Utils::StrDup(lib_uri);
     }
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
index cddacb8..67d9c2d 100644
--- a/runtime/bin/main.cc
+++ b/runtime/bin/main.cc
@@ -553,6 +553,13 @@
     vm_service_server_port = 0;
   }
 
+  // We do not want to wait for DDS to advertise availability of VM service in the
+  // following scenarios:
+  // - When the VM service is disabled (can be started at a later time via SIGQUIT).
+  // - The DartDev CLI is disabled (CLI isolate starts DDS) and VM service is enabled.
+  bool wait_for_dds_to_advertise_service =
+    !Options::disable_dart_dev() && Options::enable_vm_service();
+
   // Load embedder specific bits and return.
   if (!VmService::Setup(
           Options::disable_dart_dev() ? Options::vm_service_server_ip()
@@ -561,7 +568,7 @@
           Options::vm_service_auth_disabled(),
           Options::vm_write_service_info_filename(), Options::trace_loading(),
           Options::deterministic(), Options::enable_service_port_fallback(),
-          !Options::disable_dart_dev())) {
+          wait_for_dds_to_advertise_service)) {
     *error = Utils::StrDup(VmService::GetErrorMessage());
     return NULL;
   }
diff --git a/runtime/bin/main_options.h b/runtime/bin/main_options.h
index adec23c..658cea3 100644
--- a/runtime/bin/main_options.h
+++ b/runtime/bin/main_options.h
@@ -138,6 +138,7 @@
 
   static dart::SimpleHashMap* environment() { return environment_; }
 
+  static bool enable_vm_service() { return enable_vm_service_; }
   static const char* vm_service_server_ip() { return vm_service_server_ip_; }
   static int vm_service_server_port() { return vm_service_server_port_; }
 
diff --git a/runtime/bin/utils.cc b/runtime/bin/utils.cc
new file mode 100644
index 0000000..3182185
--- /dev/null
+++ b/runtime/bin/utils.cc
@@ -0,0 +1,25 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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 "bin/utils.h"
+
+#include <errno.h>  // NOLINT
+
+#include "bin/builtin.h"
+#include "bin/dartutils.h"
+
+#include "include/dart_api.h"
+
+#include "platform/globals.h"
+#include "platform/utils.h"
+
+namespace dart {
+namespace bin {
+
+void FUNCTION_NAME(OSError_inProgressErrorCode)(Dart_NativeArguments args) {
+  Dart_SetIntegerReturnValue(args, EINPROGRESS);
+}
+
+}  // namespace bin
+}  // namespace dart
diff --git a/runtime/docs/gc.md b/runtime/docs/gc.md
index ad3c964..1780c11 100644
--- a/runtime/docs/gc.md
+++ b/runtime/docs/gc.md
@@ -1,6 +1,6 @@
 # Garbage Collection
 
-The Dart VM has a generational garbage collector with two generations. The new generation is collected by a stop-the-world semispace [scavenger](https://github.com/dart-lang/sdk/blob/master/runtime/vm/heap/scavenger.h). The old generation is collected by concurrent-[mark](https://github.com/dart-lang/sdk/blob/master/runtime/vm/heap/marker.h)-concurrent-[sweep](https://github.com/dart-lang/sdk/blob/master/runtime/vm/heap/sweeper.h) or by concurrent-mark-parallel-[compact](https://github.com/dart-lang/sdk/blob/master/runtime/vm/heap/compactor.h).
+The Dart VM has a generational garbage collector with two generations. The new generation is collected by a parallel, stop-the-world semispace [scavenger](https://github.com/dart-lang/sdk/blob/master/runtime/vm/heap/scavenger.h). The old generation is collected by concurrent-[mark](https://github.com/dart-lang/sdk/blob/master/runtime/vm/heap/marker.h)-concurrent-[sweep](https://github.com/dart-lang/sdk/blob/master/runtime/vm/heap/sweeper.h) or by concurrent-mark-parallel-[compact](https://github.com/dart-lang/sdk/blob/master/runtime/vm/heap/compactor.h).
 
 ## Object representation
 
@@ -10,7 +10,7 @@
 
 A tag of 1 has no penalty on heap object access because removing the tag can be folded into the offset used by load and store instructions.
 
-Heap objects are always allocated in double-word increments. Objects in old-space are kept at double-word alignment, and objects in new-space are kept offset from double-word alignment. This allows checking an object's age without comparing to a boundry address, avoiding restrictions on heap placement and avoiding loading the boundry from thread-local storage. Additionally, the scavenger can quickly skip over both immediates and old objects with a single branch.
+Heap objects are always allocated in double-word increments. Objects in old-space are kept at double-word alignment (address % double-word == 0), and objects in new-space are kept offset from double-word alignment (address % double-word == word). This allows checking an object's age without comparing to a boundry address, avoiding restrictions on heap placement and avoiding loading the boundry from thread-local storage. Additionally, the scavenger can quickly skip over both immediates and old objects with a single branch.
 
 | Pointer    | Referent                                |
 | ---        | ---                                     |
@@ -21,7 +21,29 @@
 
 Heap objects have a single-word header, which encodes the object's class, size, and some status flags.
 
-On 64-bit architectures, the header of heap objects also contains a 32-bit identity hash field. On 32-bit architectures, the identity hash for heap objects is kept in a side table.
+On 64-bit architectures, the header of heap objects also contains a 32-bit identity hash field. On 32-bit architectures, the identity hash for heap objects is kept in a separate hash table.
+
+## Handles
+
+The Dart VM's GC is precise and moving.
+
+A GC is said to be "precise" if when a collection happens it knows exactly what is and is not a pointer into the heap. For example, in compiled Dart code the VM tracks which stack slots contain object pointers and which contain unboxed values. This is opposed to a "conservative" collector that considers any pointer-sized value might be a pointer into the heap, though it might just be an unboxed value.
+
+In a "moving" GC, the address of an object might change, requiring pointers to that object to be updated. In the Dart VM, objects can move during a scavenge or a compaction. A moving GC must be a precise GC: if a conservative GC updates a value that is not guarenteed to be a pointer, it will corrupt execution when the value was not in fact a pointer.
+
+The VM does not know which stack slots, globals or object fields in foreign languages contain pointers into the Dart heap, including the VM's own runtime implemented in C++. For the GC to remain precise, foreign languages reference Dart objects indirectly through "handles". Handles can be thought of as pointers to pointers. They are allocated from the VM, and the GC will visit (and possibly update) the pointers contained in handles during collections.
+
+## Safepoints
+
+Any non-GC thread or task that can allocate, read or write to the heap is called a "mutator" (because it can mutate the object graph).
+
+Some phases of GC require that the heap is not being used by a mutator; we call these "[safepoint](https://github.com/dart-lang/sdk/blob/master/runtime/vm/heap/safepoint.h) operations". Examples of safepoint operations include marking roots at the beginning of concurrent marking and the entirety of a scavenge.
+
+To perform these operations, all mutators need to temporarily stop accessing the heap; we say that these mutators have reached a "safepoint". A mutator that has reached a safepoint will not resume accessing the heap (leave the safepoint) until the safepoint operation is complete. In addition to not accessing the heap, a mutator at a safepoint must not hold any pointers into the heap unless these pointers can be visited by the GC. For code in the VM runtime, this last property means holding only handles and no ObjectPtr nor UntaggedObject. Examples of places that might enter a safepoint include allocations, stack overflow checks, and transitions between compiled code and the runtime and native code.
+
+Note that a mutator can be at a safepoint without being suspended. It might be performing a long task that doesn't access the heap. It will, however, need to wait for any safepoint operation to complete in order to leave its safepoint and resume accessing the heap.
+
+Because a safepoint operation excludes execution of Dart code, it is sometimes used for non-GC tasks that requires only this property. For example, when a background compilation has completed and wants to install its result, it uses a safepoint operation to ensure no Dart execution sees the intermediate states during installation.
 
 ## Scavenge
 
@@ -29,7 +51,7 @@
 
 ## Parallel Scavenge
 
-FLAG_scavenger_tasks (default 2) workers are started on separate threads. Each worker competes to process parts of the root set (including the remembered set). When a worker copies an object to to-space, it allocates from a worker-local bump allocation region. The same worker will process the copied object. When a worker promotes an object to old-space, it allocates from a worker-local freelist, which uses bump allocation for large free blocks. The promoted object is added to a work list that implements work stealing, so some other worker may process the promoted object. After the object is evacuated, the worker using a compare-and-swap to install the forwarding pointer into the from-space object's header. If it loses the race, it un-allocates the to-space or old-space object it just allocated, and uses the winner's object to update the pointer it was processing. Workers run until all of the work set have been processed, and every worker have processed its to-space objects and local part of the promoted work list.
+FLAG_scavenger_tasks (default 2) workers are started on separate threads. Each worker competes to process parts of the root set (including the remembered set). When a worker copies an object to to-space, it allocates from a worker-local bump allocation region. The same worker will process the copied object. When a worker promotes an object to old-space, it allocates from a worker-local freelist, which uses bump allocation for large free blocks. The promoted object is added to a work list that implements work stealing, so some other worker may process the promoted object. After the object is evacuated, the worker uses a compare-and-swap to install the forwarding pointer into the from-space object's header. If it loses the race, it un-allocates the to-space or old-space object it just allocated, and uses the winner's object to update the pointer it was processing. Workers run until all of the work sets have been processed, and every worker has processed its to-space objects and its local part of the promoted work list.
 
 ## Mark-Sweep
 
@@ -45,18 +67,6 @@
 
 The Dart VM includes a sliding compactor. The forwarding table is compactly represented by dividing the heap into blocks and for each block recording its target address and the bitvector for each surviving double-word. The table is accessed in constant time by keeping heap pages aligned so the page header of any object can be accessed by masking the object.
 
-## Safepoints
-
-Any thread or task that can allocate, read or write to the heap is called a "mutator" (because it can mutate the object graph).
-
-Some phases of GC require that the heap is not being used by a mutator; we call these "[safepoint](https://github.com/dart-lang/sdk/blob/master/runtime/vm/heap/safepoint.h) operations". Examples of safepoint operations include marking roots at the beginning of concurrent marking and the entirety of a scavenge.
-
-To perform these operations, all mutators need to temporarily stop accessing the heap; we say that these mutators have reached a "safepoint". A mutator that has reached a safepoint will not resume accessing the heap (leave the safepoint) until the safepoint operation is complete. In addition to not accessing the heap, a mutator at a safepoint must not hold any pointers into the heap unless these pointers can be visited by the GC. For code in the VM runtime, this last property means holding only handles and no RawObject pointers. Examples of places that might enter a safepoint include allocations, stack overflow checks, and transitions between compiled code and the runtime and native code.
-
-Note that a mutator can be at a safepoint without being suspended. It might be performing a long task that doesn't access the heap. It will, however, need to wait for any safepoint operation to complete in order to leave its safepoint and resume accessing the heap.
-
-Because a safepoint operation excludes excution of Dart code, it is sometimes used for non-GC tasks that requires only this property. For example, when a background compilation has completed and wants to install its result, it uses a safepoint operation to ensure no Dart execution sees the intermediate states during installation.
-
 ## Concurrent Marking
 
 To reduce the time the mutator is paused for old-space GCs, we allow the mutator to continue running during most of the marking work. 
@@ -140,7 +150,7 @@
 
 For old-space objects created before marking started, in each slot the marker can see either its value at the time marking started or any subsequent value sorted in the slot. Any slot that contained a pointer continues to continue a valid pointer for the object's lifetime, so no matter which value the marker sees, it won't interpret a non-pointer as a pointer. (The one interesting case here is array truncation, where some slot in the array will become the header of a filler object. We ensure this is safe for concurrent marking by ensuring the header for the filler object looks like a Smi.) If the marker sees an old value, we may lose some precision and retain a dead object, but we remain correct because the new value has been marked by the mutator.
 
-For old-space objects created after marking started, the marker may see uninitialized values because operations on slots are not synchronized. To prevent this, during marking we allocate old-space objects black (marked) so the marker will not visit them.
+For old-space objects created after marking started, the marker may see uninitialized values because operations on slots are not synchronized. To prevent this, during marking we allocate old-space objects [black (marked)](https://en.wikipedia.org/wiki/Tracing_garbage_collection#TRI-COLOR) so the marker will not visit them.
 
 New-space objects and roots are only visited during a safepoint, and safepoints establish synchronization.
 
diff --git a/runtime/include/dart_tools_api.h b/runtime/include/dart_tools_api.h
index a106d42..3ed741b 100644
--- a/runtime/include/dart_tools_api.h
+++ b/runtime/include/dart_tools_api.h
@@ -260,13 +260,13 @@
  *
  * \param bytes_length The length of the byte array.
  *
- * \return Success if the arguments are well formed.  Otherwise, returns an
- *   error handle.
+ * \return NULL if the arguments are well formed.  Otherwise, returns an
+ *   error string. The caller is responsible for freeing the error message.
  */
-DART_EXPORT Dart_Handle Dart_ServiceSendDataEvent(const char* stream_id,
-                                                  const char* event_kind,
-                                                  const uint8_t* bytes,
-                                                  intptr_t bytes_length);
+DART_EXPORT char* Dart_ServiceSendDataEvent(const char* stream_id,
+                                            const char* event_kind,
+                                            const uint8_t* bytes,
+                                            intptr_t bytes_length);
 
 /**
  * Usage statistics for a space/generation at a particular moment in time.
diff --git a/runtime/lib/regexp.cc b/runtime/lib/regexp.cc
index 3e0e337..6c10d7d 100644
--- a/runtime/lib/regexp.cc
+++ b/runtime/lib/regexp.cc
@@ -85,7 +85,7 @@
   const RegExp& regexp = RegExp::CheckedHandle(zone, arguments->NativeArgAt(0));
   ASSERT(!regexp.IsNull());
   if (regexp.is_initialized()) {
-    return regexp.num_bracket_expressions();
+    return Smi::New(regexp.num_bracket_expressions());
   }
   const String& pattern = String::Handle(regexp.pattern());
   const String& errmsg =
diff --git a/runtime/llvm_codegen/bit/BUILD.gn b/runtime/llvm_codegen/bit/BUILD.gn
deleted file mode 100644
index a021ffe..0000000
--- a/runtime/llvm_codegen/bit/BUILD.gn
+++ /dev/null
@@ -1,32 +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.
-
-executable("bit") {
-  sources = [ "main.cc" ]
-  root_dir = rebase_path(root_out_dir)
-  clang_dir = rebase_path("//buildtools/linux-x64/clang/bin")
-  defines = [
-    "BIT_BINARY_DIR=\"$root_dir\"",
-    "BIT_CLANG_DIR=\"$clang_dir\"",
-  ]
-  deps = [ "../../../third_party/llvm:LLVMSupport" ]
-  data_deps = [ "../codegen" ]
-}
-
-source_set("test") {
-  sources = [ "test.cc" ]
-
-  root_dir = rebase_path(root_out_dir)
-  clang_dir = rebase_path("//buildtools/linux-x64/clang/bin")
-  defines = [
-    "BIT_BINARY_DIR=\"$root_dir\"",
-    "BIT_CLANG_DIR=\"$clang_dir\"",
-  ]
-
-  deps = [ "../../../third_party/llvm:LLVMSupport" ]
-
-  include_dirs = [ "//runtime" ]
-
-  defines += [ "TESTING" ]
-}
diff --git a/runtime/llvm_codegen/bit/bit.h b/runtime/llvm_codegen/bit/bit.h
deleted file mode 100644
index ea57b03..0000000
--- a/runtime/llvm_codegen/bit/bit.h
+++ /dev/null
@@ -1,80 +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.
-
-#include <stdio.h>
-
-#include <map>
-#include <regex>
-
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/LineIterator.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/Path.h"
-#include "llvm/Support/Regex.h"
-#include "llvm/Support/WithColor.h"
-
-namespace {
-
-using namespace llvm;
-
-struct Config {
-  StringRef filename;
-  StringRef out_dir;
-};
-
-StringMap<std::string> GetSubstitutions(const Config& config) {
-  // Compute all of our strings needed for substitutions.
-  StringRef test_dir = sys::path::parent_path(config.filename);
-  StringRef basename = sys::path::filename(config.filename);
-  SmallString<128> tmp_file;
-  sys::path::append(tmp_file, sys::path::Style::native, config.out_dir,
-                    basename + ".tmp");
-  SmallString<128> codegen;
-  sys::path::append(codegen, sys::path::Style::native, BIT_BINARY_DIR,
-                    "codegen");
-  SmallString<128> bit;
-  sys::path::append(bit, sys::path::Style::native, BIT_BINARY_DIR, "bit");
-
-  SmallString<128> clang;
-  sys::path::append(clang, sys::path::Style::native, BIT_CLANG_DIR, "clang");
-
-  // Set up our substitutions.
-  StringMap<std::string> subs;
-  subs["s"] = config.filename.str();
-  subs["p"] = test_dir.str();
-  subs["P"] = test_dir.str();
-  subs["t"] = tmp_file.str().str();
-  subs["{codegen}"] = codegen.str().str();
-  subs["{bit}"] = bit.str().str();
-  subs["{clang}"] = clang.str().str();
-  return subs;
-}
-
-std::string PerformSubstitutions(const StringMap<std::string>& subs,
-                                 StringRef string) {
-  std::string out = string.str();
-  for (const auto& sub : subs) {
-    std::string key = (Twine("%") + sub.getKeyData()).str();
-    size_t pos = 0;
-    while ((pos = out.find(key, pos)) != std::string::npos) {
-      if (pos != 0 && out[pos - 1] == '%') {
-        pos += key.size();
-        continue;
-      }
-      out.replace(pos, key.size(), sub.getValue());
-      pos += sub.second.size();
-    }
-  }
-  return out;
-}
-
-Optional<std::string> GetCommand(StringRef line) {
-  static Regex run_line("^;[ ]*RUN:[ ]*(.*)$");
-  SmallVector<StringRef, 2> cmd;
-  if (!run_line.match(line, &cmd)) return Optional<std::string>{};
-  assert(cmd.size() == 2);
-  return cmd[1].str();
-}
-
-}  // namespace
diff --git a/runtime/llvm_codegen/bit/main.cc b/runtime/llvm_codegen/bit/main.cc
deleted file mode 100644
index 17a5854..0000000
--- a/runtime/llvm_codegen/bit/main.cc
+++ /dev/null
@@ -1,122 +0,0 @@
-// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#include <stdio.h>
-
-#include <cctype>
-#include <map>
-#include <regex>
-
-#include "bit.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/InitLLVM.h"
-#include "llvm/Support/LineIterator.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/Path.h"
-#include "llvm/Support/Process.h"
-#include "llvm/Support/Program.h"
-#include "llvm/Support/Regex.h"
-#include "llvm/Support/VirtualFileSystem.h"
-#include "llvm/Support/WithColor.h"
-
-using namespace llvm;
-
-namespace {
-
-StringRef tool_name;
-
-LLVM_ATTRIBUTE_NORETURN void Fail(Twine message) {
-  WithColor::error(errs(), tool_name) << message << ".\n";
-  errs().flush();
-  exit(1);
-}
-
-LLVM_ATTRIBUTE_NORETURN void Fail(Error e) {
-  assert(E);
-  std::string buf;
-  raw_string_ostream os(buf);
-  logAllUnhandledErrors(std::move(e), os);
-  os.flush();
-  WithColor::error(errs(), tool_name) << buf;
-  exit(1);
-}
-
-LLVM_ATTRIBUTE_NORETURN void ReportError(StringRef file, std::error_code ec) {
-  assert(ec);
-  Fail(createFileError(file, ec));
-}
-
-std::string ReadFile(FILE* file) {
-  std::string output;
-  constexpr size_t buf_size = 256;
-  char buf[buf_size];
-  size_t size;
-  while ((size = fread(buf, buf_size, sizeof(buf[0]), file)))
-    output.append(buf, buf + buf_size);
-  return output;
-}
-
-bool IsPosixFullyPortablePath(StringRef path) {
-  const char* extra = "._-/";
-  for (auto c : path)
-    if (!isalnum(c) && !strchr(extra, c)) return false;
-  return true;
-}
-
-}  // namespace
-
-int main(int argc, char** argv) {
-  InitLLVM X(argc, argv);
-
-  // Make sure we have both arguments.
-  tool_name = argv[0];
-  if (argc != 3) Fail("expected exactly 2 arguments");
-
-  // Makes sure that stdin/stdout are setup correctly.
-  if (sys::Process::FixupStandardFileDescriptors())
-    Fail("std in/out fixup failed");
-
-  // Set our config.
-  Config config;
-  config.filename = argv[1];
-  config.out_dir = argv[2];
-
-  // Make sure we have valid filepaths.
-  if (!IsPosixFullyPortablePath(config.filename))
-    Fail("'" + config.filename + "' is not a posix fully portable filename");
-  if (!IsPosixFullyPortablePath(config.out_dir))
-    Fail("'" + config.out_dir + "' is not a posix fully portable filename");
-
-  // Compute substitutions.
-  auto subs = GetSubstitutions(config);
-
-  // The lines we execute are allowed to assume that %p will exist.
-  sys::fs::create_directory(subs["p"]);
-
-  // Open the file for reading.
-  auto buf_or = vfs::getRealFileSystem()->getBufferForFile(config.filename);
-  if (!buf_or) ReportError(config.filename, buf_or.getError());
-  auto buf = std::move(*buf_or);
-
-  // Now iterate over the lines in the file.
-  line_iterator it{*buf};
-  int count = 0;
-  for (StringRef line = *it; !it.is_at_end(); line = *++it) {
-    auto cmd = GetCommand(line);
-    if (!cmd) continue;
-    ++count;
-    auto subbed = PerformSubstitutions(subs, *cmd);
-    FILE* file = popen(subbed.c_str(), "r");
-    std::string output = ReadFile(file);
-    if (pclose(file) != 0) {
-      errs() << output << "\n";
-      Fail("Failure on line " + Twine(it.line_number()) + "\n\t" + subbed + "");
-    }
-  }
-  if (count == 0) {
-    Fail("No commands to run");
-  }
-  outs() << "Commands run: " << count << "\n";
-  return 0;
-}
diff --git a/runtime/llvm_codegen/bit/test.cc b/runtime/llvm_codegen/bit/test.cc
deleted file mode 100644
index 7b800ff..0000000
--- a/runtime/llvm_codegen/bit/test.cc
+++ /dev/null
@@ -1,71 +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.
-
-#include <stdio.h>
-
-#include <utility>
-#include <vector>
-
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/LineIterator.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/Path.h"
-#include "llvm/Support/Regex.h"
-#include "llvm/Support/WithColor.h"
-#include "platform/assert.h"
-#include "vm/unit_test.h"
-
-#define LIT_BINARY_DIR "/path/to/bins"
-#include "bit.h"
-
-UNIT_TEST_CASE(BasicGetSubstitutions) {
-  Config config;
-  config.filename = "/foo/bar/baz.ll";
-  config.out_dir = "/test/out/dir";
-
-  StringMap<std::string> expected;
-  expected["s"] = "/foo/bar/baz.ll";
-  expected["p"] = "/foo/bar";
-  expected["P"] = "/test/out/dir";
-  expected["t"] = "/test/out/dir/baz.ll.tmp";
-  expected["codegen"] = "/path/to/bins/codegen";
-  expected["bit"] = "/path/to/bins/bit";
-
-  StringMap<std::string> actual = GetSubstitutions(config);
-
-  EXPECT_EQ(actual.size(), expected.size());
-  for (const auto& p : actual)
-    EXPECT_EQ(p.getValue(), expected[p.getKey()]);
-}
-
-UNIT_TEST_CASE(BasicPerformSubstitutions) {
-  StringMap<std::string> subs;
-  subs["foo"] = "/foo/path";
-  subs["bar"] = "/bar/path";
-  subs["baz"] = "/baz/path";
-  std::vector<std::pair<std::string, std::string>> cases = {
-      {"%foo", "/foo/path"},
-      {"%bar", "/bar/path"},
-      {"%baz", "/baz/path"},
-      {"this has %foo, and %bar, and %baz2",
-       "this has /foo/path, and /bar/path, and /baz/path2"},
-      {"we don't want %this to expand", "we don't want %this to expand"},
-      {"%", "%"}};
-  for (const auto& test : cases) {
-    auto out = PerformSubstitutions(subs, test.first);
-    EXPECT_EQ(out, test.second);
-  }
-}
-
-UNIT_TEST_CASE(BasicGetCommand) {
-  EXPECT(!GetCommand("; this is some test"));
-  EXPECT(!GetCommand("2 + 2"));
-  EXPECT(!GetCommand("echo $VAR > %bit"));
-
-  EXPECT(GetCommand(";RUN: blarg") == Optional<std::string>{"blarg"});
-  EXPECT(GetCommand(";      RUN:        foo") == Optional<std::string>{"blarg"});
-  EXPECT(
-      GetCommand("; RUN: echo %bit %p/Input/$(%t2) > $(baz \"$BAR->%t\")") ==
-      Optional<std::string>("echo %bit %p/Input/$(%t2) > $(baz \"$BAR->%t\")"));
-}
diff --git a/runtime/llvm_codegen/codegen/BUILD.gn b/runtime/llvm_codegen/codegen/BUILD.gn
deleted file mode 100644
index 2e0a833b..0000000
--- a/runtime/llvm_codegen/codegen/BUILD.gn
+++ /dev/null
@@ -1,41 +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("../../vm/compiler/compiler_sources.gni")
-
-config("config") {
-  include_dirs = [ "../../" ]
-
-  cflags = [ "-Wno-unused-private-field" ]
-}
-
-_lib_llvm_so = "../../../third_party/llvm/lib/libLLVM-9svn.so"
-
-config("llvm") {
-  include_dirs = [ "../../../third_party/llvm/include" ]
-  libs = [ _lib_llvm_so ]
-}
-
-copy("lib_llvm") {
-  sources = [ _lib_llvm_so ]
-  outputs = [ "$root_out_dir/libLLVM-9svn.so" ]
-  public_configs = [ ":llvm" ]
-}
-
-executable("codegen") {
-  sources = [
-    "custom_zone.cc",
-    "custom_zone.h",
-    "dart.cc",
-    "dart.h",
-    "main.cc",
-  ]
-
-  deps = [
-    ":lib_llvm",
-    "../../third_party/double-conversion/src:libdouble_conversion",
-  ]
-
-  configs += [ ":config" ]
-}
diff --git a/runtime/llvm_codegen/codegen/custom_zone.cc b/runtime/llvm_codegen/codegen/custom_zone.cc
deleted file mode 100644
index f514fe5..0000000
--- a/runtime/llvm_codegen/codegen/custom_zone.cc
+++ /dev/null
@@ -1,54 +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.
-
-#include "custom_zone.h"
-
-#include "platform/text_buffer.h"
-#include "platform/unicode.h"
-#include "platform/utils.h"
-#include "vm/double_conversion.h"
-#include "vm/os.h"
-
-#include "platform/assert.cc"  // NOLINT
-#include "platform/syslog_linux.cc"  // NOLINT
-#include "platform/text_buffer.cc"  // NOLINT
-#include "platform/unicode.cc"  // NOLINT
-#include "platform/utils.cc"  // NOLINT
-#include "platform/utils_linux.cc"  // NOLINT
-#include "vm/compiler/backend/sexpression.cc"  // NOLINT
-#include "vm/double_conversion.cc"  // NOLINT
-#include "vm/flags.cc"  // NOLINT
-#include "vm/os_linux.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/llvm_codegen/codegen/custom_zone.h b/runtime/llvm_codegen/codegen/custom_zone.h
deleted file mode 100644
index 3b38104..0000000
--- a/runtime/llvm_codegen/codegen/custom_zone.h
+++ /dev/null
@@ -1,52 +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.
-
-#ifndef RUNTIME_LLVM_CODEGEN_CODEGEN_CUSTOM_ZONE_H_
-#define RUNTIME_LLVM_CODEGEN_CODEGEN_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_LLVM_CODEGEN_CODEGEN_CUSTOM_ZONE_H_
diff --git a/runtime/llvm_codegen/codegen/dart.cc b/runtime/llvm_codegen/codegen/dart.cc
deleted file mode 100644
index fe21974..0000000
--- a/runtime/llvm_codegen/codegen/dart.cc
+++ /dev/null
@@ -1,358 +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.
-
-#include <utility>
-
-#include "dart.h"
-
-#include "llvm/ADT/StringSwitch.h"
-
-using namespace llvm;
-
-Value* DartThreadObject::GetOffset(Type* type, intptr_t offset) const {
-  auto& ctx = bb_builder_.Context();
-  auto& builder = bb_builder_.Builder();
-  auto int64ty = IntegerType::getInt64Ty(ctx);
-  // TODO: This is only correct for x86_64. On x86 we need to use 257,
-  // and only arm targets an entirely different mechanism will be
-  // required since there isn't an unused register. On Arm we can
-  // probably still use the thread register as long as we're careful
-  // to set it back on thread boundaries.
-  // On x86_64 fs (257) is used for TLS but gs (256) is unused
-  // On x86 gs (256) is used for TLS but fs (257) is unused
-  // we use the unused segment so as to not conflict with TLS which
-  // allows linking against native code that uses TLS without needing
-  // to handle any kind of context switching.
-  constexpr unsigned kDartThreadPointerAddressSpace = 256;
-  auto* ptr_tls = PointerType::get(type, kDartThreadPointerAddressSpace);
-  auto* offset_value = ConstantInt::get(int64ty, offset);
-  auto* tls_value = builder.CreateIntToPtr(offset_value, ptr_tls);
-  return builder.CreateLoad(tls_value);
-}
-
-Value* DartThreadObject::StackLimit() const {
-  auto& ctx = bb_builder_.Context();
-  return GetOffset(IntegerType::getInt64Ty(ctx), kThreadStackLimitOffset);
-}
-
-Value* BasicBlockBuilder::GetValue(const DartValue* v) {
-  auto iter = values_.find(v);
-  if (iter == values_.end()) {
-    auto* out = v->Make(*this);
-    values_[v] = out;
-    return out;
-  }
-  return iter->second;
-}
-
-DartInstruction::~DartInstruction() {}
-
-static Error CreateError(const Twine& err) {
-  return make_error<StringError>(err, inconvertibleErrorCode());
-}
-
-Value* DartConstant::Make(BasicBlockBuilder& bb_builder) const {
-  auto& ctx = bb_builder.Context();
-  switch (type) {
-    case DartConstant::Type::String:
-      auto constant = ConstantDataArray::getString(ctx, str);
-      auto gv =
-          new GlobalVariable(bb_builder.Module(), constant->getType(), true,
-                             GlobalVariable::ExternalLinkage, constant);
-      return ConstantExpr::getBitCast(gv, GetType(bb_builder));
-  }
-}
-
-Type* DartConstant::GetType(BasicBlockBuilder& bb_builder) const {
-  // TODO: Right now this returns a c-string type but that's not correct.
-  // We should move this to a generic object type (e.g. a tagged pointer).
-  auto& ctx = bb_builder.Context();
-  auto int8ty = IntegerType::getInt8Ty(ctx);
-  return PointerType::get(int8ty, 0);
-}
-
-void InstCheckStackOverflow::Build(BasicBlockBuilder& bb_builder) const {
-  auto& builder = bb_builder.Builder();
-  auto& ctx = bb_builder.Context();
-  auto& module = bb_builder.Module();
-  auto& thread_object = bb_builder.ThreadObject();
-
-  // TODO: This is only correct on 64-bit architectures.
-  auto int64ty = IntegerType::getInt64Ty(ctx);
-
-  // Get the stack pointer.
-  auto spi_type = Intrinsic::getType(ctx, Intrinsic::stacksave);
-  auto spi_func = Intrinsic::getDeclaration(&module, Intrinsic::stacksave);
-  auto sp_raw = builder.CreateCall(spi_type, spi_func);
-  auto sp = builder.CreatePtrToInt(sp_raw, int64ty);
-
-  // Get the stack limit from the thread pointer.
-  auto stack_limit = thread_object.StackLimit();
-
-  // Now compare the stack pointer and limit.
-  auto error_bb = bb_builder.AddBasicBlock();
-  auto cont_bb = bb_builder.AddBasicBlock();
-  auto cmp = builder.CreateICmpULT(sp, stack_limit);
-  builder.CreateCondBr(cmp, error_bb, cont_bb);
-
-  // Now build the error path.
-  // TODO: Don't just trap here. For now we just trap rather than
-  // handling the proper exceptional control flow here.
-  builder.SetInsertPoint(error_bb);
-  auto trap_type = Intrinsic::getType(ctx, Intrinsic::trap);
-  auto trap_func = Intrinsic::getDeclaration(&module, Intrinsic::trap);
-  builder.CreateCall(trap_type, trap_func);
-  builder.CreateBr(cont_bb);
-
-  // Now pretend as if this new block is just the end of the block we
-  // started with.
-  builder.SetInsertPoint(cont_bb);
-}
-
-Expected<std::unique_ptr<DartInstruction>> InstCheckStackOverflow::Construct(
-    dart::SExpList* inst,
-    DartBasicBlockBuilder& bb_builder) {
-  // inst = (CheckStackoverflow)
-  return llvm::make_unique<InstCheckStackOverflow>();
-}
-
-void InstPushArgument::Build(BasicBlockBuilder& bb_builder) const {
-  bb_builder.PushArgument(bb_builder.GetValue(arg_));
-}
-
-Expected<std::unique_ptr<DartInstruction>> InstPushArgument::Construct(
-    dart::SExpList* inst,
-    DartBasicBlockBuilder& bb_builder) {
-  // inst = (PushArgument <arg>)
-  if (inst->Length() != 2) {
-    return CreateError("PushArgument should have exactly 1 argument");
-  }
-  dart::SExpSymbol* arg = inst->At(1)->AsSymbol();
-  if (arg == nullptr) {
-    return CreateError("Expected PushArgument's argument to be a symbol");
-  }
-  const DartValue* dvalue = bb_builder.GetDef(arg->value());
-  if (dvalue == nullptr) {
-    return CreateError(Twine(arg->value()) + " is not a valid symbol");
-  }
-  return llvm::make_unique<InstPushArgument>(dvalue);
-}
-
-void InstStaticCall::Build(BasicBlockBuilder& bb_builder) const {
-  // inst = (StaticCall <function-symbol> <arg> ...)
-
-  SmallVector<Value*, 8> args;
-  size_t arg_count = args_len_;
-  while (arg_count > 0) {
-    arg_count--;
-    args.push_back(bb_builder.PopArgument());
-  }
-  auto& builder = bb_builder.Builder();
-
-  // Hard code the function type for now.
-  auto& ctx = bb_builder.Context();
-  auto int8ty = IntegerType::getInt8Ty(ctx);
-  auto i8ptr = PointerType::get(int8ty, 0);
-  SmallVector<Type*, 8> arg_types;
-  arg_types.push_back(i8ptr);
-  auto print_type = FunctionType::get(Type::getVoidTy(ctx), arg_types, false);
-
-  // Get the function value we need.
-  auto func = bb_builder.GetValue(function_);
-  builder.CreateCall(print_type, func, args);
-}
-
-Expected<std::unique_ptr<DartInstruction>> InstStaticCall::Construct(
-    dart::SExpList* inst,
-    DartBasicBlockBuilder& bb_builder) {
-  // inst = (StaticCall <function_name> { args_len <N> })
-  if (inst->Length() != 2) {
-    return CreateError("StaticCall should have exactly 1 argument");
-  }
-  dart::SExpSymbol* func = inst->At(1)->AsSymbol();
-  if (!func) {
-    return CreateError("Expected StaticCall's argument to be a symbol");
-  }
-  const DartValue* dvalue = bb_builder.GetDef(func->value());
-  dart::SExpression* args_len_expr = inst->ExtraLookupValue("args_len");
-  // If args_len_expr isn't found args_len is assumed to be zero.
-  size_t args_len = 0;
-  if (args_len_expr) {
-    dart::SExpInteger* args_len_expr_int = args_len_expr->AsInteger();
-    if (args_len_expr_int) args_len = args_len_expr_int->value();
-  }
-  return llvm::make_unique<InstStaticCall>(dvalue, 1);
-}
-
-void InstReturn::Build(BasicBlockBuilder& bb_builder) const {
-  auto& builder = bb_builder.Builder();
-  builder.CreateRetVoid();
-}
-
-Expected<std::unique_ptr<DartInstruction>> InstReturn::Construct(
-    dart::SExpList* inst,
-    DartBasicBlockBuilder& bb_builder) {
-  // inst = (Return)
-  return llvm::make_unique<InstReturn>();
-}
-
-static Expected<StringMap<DartConstant>> MakeConstants(dart::Zone* zone,
-                                                       dart::SExpList* sexpr) {
-  StringMap<DartConstant> out;
-  for (intptr_t i = 1; i < sexpr->Length(); ++i) {
-    DartConstant constant;
-    dart::SExpList* def = sexpr->At(i)->AsList();
-    if (!def) {
-      return CreateError(Twine("Stray token in constants at location ") +
-                         Twine(i) + sexpr->At(i)->ToCString(zone));
-    }
-    if (def->Length() != 3) {
-      return CreateError("Constant definitions must have exactly 3 lines");
-    }
-    dart::SExpSymbol* def_symbol = def->At(0)->AsSymbol();
-    if (def_symbol->value() != StringRef("def")) {
-      return CreateError(
-          "first element in a constant definition expected to be `def`");
-    }
-    dart::SExpSymbol* def_name = def->At(1)->AsSymbol();
-    if (!def_name) {
-      return CreateError("element after `def` in constant expected to be name");
-    }
-    dart::SExpression* def_value = def->At(2);
-    if (def_value->IsString()) {
-      constant.str = def_value->AsString()->value();
-      constant.type = DartConstant::Type::String;
-    } else {
-      return CreateError("We can't yet handle that element type");
-    }
-    out[def_name->value()] = constant;
-  }
-  return out;
-}
-
-#define FOREACH_INSTRUCTION(M)                                                 \
-  M(CheckStackOverflow)                                                        \
-  M(PushArgument)                                                              \
-  M(StaticCall)                                                                \
-  M(Return)
-
-static Expected<std::unique_ptr<DartInstruction>> MakeInstruction(
-    dart::SExpList* sexpr,
-    DartBasicBlockBuilder& bb_builder) {
-  if (sexpr->Length() < 1)
-    return CreateError("An empty list can't be an instruction");
-  dart::SExpSymbol* inst_sym = sexpr->At(0)->AsSymbol();
-  if (!inst_sym)
-    return CreateError(
-        "Expected first element of list in instruction to be a symbol");
-  using CtorFunc = std::function<Expected<std::unique_ptr<DartInstruction>>(
-      dart::SExpList*, DartBasicBlockBuilder&)>;
-  CtorFunc ctor = StringSwitch<CtorFunc>(inst_sym->value())
-#define HANDLE_INSTRUCTION_CASE(INST) .Case(#INST, Inst##INST::Construct)
-      FOREACH_INSTRUCTION(HANDLE_INSTRUCTION_CASE);
-#undef HANDLE_INSTRUCTION_CASE
-  return ctor(sexpr, bb_builder);
-}
-
-static Expected<DartBlock> MakeBlock(dart::SExpList* sexpr,
-                                     DartFunction& function,
-                                     const StringMap<const DartValue*>& env) {
-  // Construct the basic block builder
-  DartBasicBlockBuilder bb_builder;
-  for (const auto& c : function.constants)
-    bb_builder.AddDef(c.getKey(), &c.getValue());
-  for (const auto& c : env)
-    bb_builder.AddDef(c.getKey(), c.getValue());
-
-  DartBlock out;
-
-  // Make sure we have a basic block and get the name
-  if (sexpr->Length() <= 2)
-    return CreateError("too few elements in basic block");
-  dart::SExpSymbol* block_name = sexpr->At(1)->AsSymbol();
-  if (!block_name)
-    return CreateError("expected block name after `block` symbol");
-  out.name = block_name->value();
-
-  // Now construct each instruction and add it to the basic block
-  for (intptr_t i = 2; i < sexpr->Length(); ++i) {
-    dart::SExpList* inst = sexpr->At(i)->AsList();
-    if (!inst)
-      return CreateError("stray token at element " + Twine(i) +
-                         " in basic block " + out.name);
-    auto inst_or = MakeInstruction(inst, bb_builder);
-    if (!inst_or) return inst_or.takeError();
-    out.instructions.emplace_back(std::move(*inst_or));
-  }
-  return out;
-}
-
-Expected<DartFunction> MakeFunction(dart::Zone* zone,
-                                    dart::SExpression* sexpr,
-                                    const StringMap<const DartValue*>& env) {
-  // Basic checking that this s-expression looks like a function
-  dart::SExpList* flist = sexpr->AsList();
-  if (!flist) return CreateError("S-Expression was not a function list");
-  if (flist->Length() < 2)
-    return CreateError("S-Expression list was too short to be a function");
-  dart::SExpSymbol* function_symbol = flist->At(0)->AsSymbol();
-  if (function_symbol == nullptr ||
-      function_symbol->value() != StringRef("function"))
-    return CreateError(
-        "S-Expression cannot be a function as it does not start with "
-        "`function`");
-  dart::SExpSymbol* function_name = flist->At(1)->AsSymbol();
-  if (function_name == nullptr)
-    return CreateError("Expected symbol name after `function` symbol");
-
-  // Now we fill in all the details
-  DartFunction function;
-  function.name = function_name->value();
-  Optional<StringRef> normal_entry;
-  for (intptr_t i = 2; i < flist->Length(); ++i) {
-    dart::SExpList* chunk = flist->At(i)->AsList();
-    // Everything is a list so far so error out on other options
-    if (!chunk) {
-      return CreateError(Twine("Stray token in function at location ") +
-                         Twine(i) + ": " + flist->At(i)->ToCString(zone));
-    }
-    dart::SExpSymbol* chunk_symbol = chunk->At(0)->AsSymbol();
-    if (!chunk_symbol)
-      return CreateError(Twine("Expected element ") + Twine(i) +
-                         " of function to start with a symbol");
-    StringRef chunk_tag = chunk_symbol->value();
-
-    if (chunk_tag == "constants") {
-      auto constants = MakeConstants(zone, chunk);
-      if (!constants) return constants.takeError();
-      function.constants = std::move(*constants);
-    }
-
-    if (chunk_tag == "block") {
-      auto block = MakeBlock(chunk, function, env);
-      if (!block) return block.takeError();
-      StringRef name = block->name;
-      function.blocks[name] = std::move(*block);
-    }
-
-    if (chunk_tag == "normal-entry") {
-      if (chunk->Length() != 2)
-        return CreateError("Expected 1 argument to normal-entry");
-      dart::SExpSymbol* block_name = chunk->At(1)->AsSymbol();
-      if (!block_name)
-        return CreateError("expected block name after normal-entry symbol");
-      normal_entry = block_name->value();
-    }
-  }
-
-  if (normal_entry) {
-    auto iter = function.blocks.find(*normal_entry);
-    if (iter != function.blocks.end())
-      function.normal_entry = &iter->getValue();
-  } else {
-    function.normal_entry = nullptr;
-  }
-
-  return function;
-}
diff --git a/runtime/llvm_codegen/codegen/dart.h b/runtime/llvm_codegen/codegen/dart.h
deleted file mode 100644
index 826397a..0000000
--- a/runtime/llvm_codegen/codegen/dart.h
+++ /dev/null
@@ -1,314 +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.
-
-#ifndef RUNTIME_LLVM_CODEGEN_CODEGEN_DART_H_
-#define RUNTIME_LLVM_CODEGEN_CODEGEN_DART_H_
-
-#include <memory>
-#include <vector>
-#include <string>
-
-#include "llvm/ADT/StringRef.h"
-#include "llvm/IR/IRBuilder.h"
-#include "llvm/IR/Module.h"
-#include "llvm/IR/ValueSymbolTable.h"
-#include "llvm/Support/Error.h"
-#include "llvm/Support/WithColor.h"
-
-// Ensure to use our own zone.
-#include "custom_zone.h"
-#include "vm/compiler/backend/sexpression.h"
-
-// This file introduces several representations that exist between
-// S-Expressions and llvm IR. To explain how each part is intended
-// to be roughly translated using these I'll provide a mapping
-// showing how each part is translated.
-
-// At a high level two translations are very seamless:
-//
-// (function foo ...) -> DartFunction -> llvm::Function*
-// (block B ...) -> DartBlock -> (sort of) llvm::BasicBlock*
-//
-// Internally within a function constants are given names and are then used in
-// blocks. Each block additionally defines more names. Each of these names
-// needs to be mapped to a DartValue (more on that later) so a context to help
-// keep track of these name to DartValue mappings called a
-// DartBasicBlockBuilder exists. It is only used for to aid in the
-// (block B ...) -> DartBlock translation which is in turn used in the
-// (function foo ...) -> DartFunction translation. DartFunctions and DartBlocks
-// can be seen as validated representations of their S-Expression forms.
-
-// Within a DartBlock we have DartInstructions. Each DartInstruction either
-// has some effect (like calling a function or updating a value) or defines
-// a new name mapping it to a DartValue later. DartValues are referenced as
-// arguments to DartInstructions and map to llvm::Value*s. DartInstructions
-// have no analogue which they're directly translated to in code but they
-// do closely correspond mentally to llvm::Instruction*. The challenge is that
-// a DartInstruction might map to a near arbitrary number of llvm Instructions
-// and that mapping is very dependent on context. So instead of mapping them
-// to objects DartInstructions just know how to add their llvm Instructions to
-// an llvm::BasicBlock. These instructions might reference a verity of context
-// and so BasicBlockBuilder is passed in to provide them with this context.
-// Each DartInstruction is expected to already hold each DartValue that it
-// needs as previously supplied by the DartBasicBlockBuilder on construction.
-
-// An additional issue arises when translating DartInstructions into llvm IR.
-// Many require introducing control flow when lowered to the level of llvm IR
-// but this requires using multiple llvm::BasicBlock for a single DartBlock.
-// Luckily each DartInstruction that is not a terminator is expected to make it
-// possible for all non-exceptional control flow paths to wind up at a single
-// basic block. Since BasicBlockBuilder keeps track of a "current" basic block
-// via llvm::IRBuilder we simply ensure that after generating many blocks we
-// end each instruction which requires new basic blocks on this final basic
-// block that all generated blocks flow into. A picture better explains this:
-
-// Say you have a DartBlock B_1 it would then be mapped to llvm blocks that
-// look like this:
-//
-//                          B_1
-//                          / \
-//                         /   \
-//                 B_1_left    B_1_right
-//                         \   /
-//                          \ /
-//                         B_1_0
-//
-// And then we go on adding to B_1_0 as if it were the end of B_1 from before.
-
-// Each DartValue knows how to map itself to an llvm::Value. In llvm a Value
-// is really just anything you can give a name to in the IR but a DartValue
-// is intended to be more specific, it's a compile time representation of a
-// object, be it an integer, a tagged SMI, a pointer to a Dart Object, etc...
-// its intended to correspond to some actual object that we're computing on.
-
-// Class FunctionBuilder provides functionality for building
-// and LLVM function object including the ability to add a
-// named basic block, find an existing block, get the current
-// context/module and additionally retrieve llvm Values valid
-// in the current function.
-class FunctionBuilder {
- public:
-  FunctionBuilder(llvm::LLVMContext& ctx,
-                  llvm::Module& mod,
-                  llvm::Function& func)
-      : ctx_(ctx), mod_(mod), func_(func) {}
-  llvm::LLVMContext& Context() { return ctx_; }
-  llvm::Module& Module() { return mod_; }
-  llvm::Value* GetSymbolValue(llvm::StringRef name) {
-    auto* symtab = func_.getValueSymbolTable();
-    return symtab->lookup(name);
-  }
-  llvm::BasicBlock* AddBasicBlock() {
-    return llvm::BasicBlock::Create(ctx_, "", &func_);
-  }
-  llvm::BasicBlock* AddBasicBlock(llvm::StringRef name) {
-    auto* bb = llvm::BasicBlock::Create(ctx_, name, &func_);
-    basic_blocks_[name] = bb;
-    return bb;
-  }
-  llvm::BasicBlock* GetBasicBlock(llvm::StringRef name) const {
-    auto iter = basic_blocks_.find(name);
-    if (iter != basic_blocks_.end()) return iter->getValue();
-    return nullptr;
-  }
-
- private:
-  llvm::LLVMContext& ctx_;
-  llvm::Module& mod_;
-  llvm::Function& func_;
-  llvm::StringMap<llvm::BasicBlock*> basic_blocks_;
-};
-
-class BasicBlockBuilder;
-
-// TODO(jakehehrlich): Make this architecture dependent
-// Class DartThreadObject is used as a high level object for generating
-// code that reads fields from the thread object.
-class DartThreadObject {
- public:
-  explicit DartThreadObject(BasicBlockBuilder& bb_builder)
-      : bb_builder_(bb_builder) {}
-
-  // StackLimit returns an llvm::Value representing the stack limit
-  // of the thread object.
-  llvm::Value* StackLimit() const;
-
- private:
-  static constexpr intptr_t kThreadStackLimitOffset = 72;
-
-  BasicBlockBuilder& bb_builder_;
-
-  // GetOffset returns an llvm::Value* representing a pointer to a particular
-  // field of the thread object. It adds the specified offset to the thread
-  // pointer, and then casts to the specified type.
-  llvm::Value* GetOffset(llvm::Type* type, intptr_t offset) const;
-};
-
-class DartValue;
-
-// A class for keeping track of the basic block state and SSA values.
-// This is similar to IRBuilder but also keeps track of the argument stack and
-// basic block names.
-class BasicBlockBuilder {
- public:
-  BasicBlockBuilder(llvm::BasicBlock* bb, FunctionBuilder& fb)
-      : fb_(fb), top_(bb), builder_(bb), thread_object_(*this) {}
-  llvm::LLVMContext& Context() { return fb_.Context(); }
-  llvm::Module& Module() { return fb_.Module(); }
-  llvm::IRBuilder<>& Builder() { return builder_; }
-  const DartThreadObject& ThreadObject() { return thread_object_; }
-  llvm::BasicBlock* AddBasicBlock() { return fb_.AddBasicBlock(); }
-  llvm::BasicBlock* GetBasicBlock(llvm::StringRef Name) const {
-    return fb_.GetBasicBlock(Name);
-  }
-  llvm::Value* GetSymbolValue(llvm::StringRef name) const {
-    return fb_.GetBasicBlock(name);
-  }
-  llvm::Value* GetValue(const DartValue* v);
-  void PushArgument(llvm::Value* v) { stack_.push_back(v); }
-  llvm::Value* PopArgument() {
-    llvm::Value* out = stack_.back();
-    stack_.pop_back();
-    return out;
-  }
-
- private:
-  FunctionBuilder& fb_;
-  llvm::BasicBlock* top_;
-  llvm::SmallVector<llvm::Value*, 16> stack_;
-  llvm::IRBuilder<> builder_;
-  llvm::DenseMap<const DartValue*, llvm::Value*> values_;
-  DartThreadObject thread_object_;
-};
-
-// Class DartValue represents an SSA value from the Dart SSA
-// such that it can be converted into an llvm::Value*.
-class DartValue {
- public:
-  virtual ~DartValue() {}
-  virtual llvm::Value* Make(BasicBlockBuilder& bb_builder) const = 0;
-  virtual llvm::Type* GetType(BasicBlockBuilder& bb_builder) const = 0;
-};
-
-// Class DartBasicBlockBuilder provides helpful context for going
-// from an S-Expression basic block to a DartBlock. It just lets
-// one lookup DartValue's by name at this time.
-class DartBasicBlockBuilder {
- public:
-  void AddDef(llvm::StringRef name, const DartValue* v) { defs_[name] = v; }
-  const DartValue* GetDef(llvm::StringRef name) const {
-    auto iter = defs_.find(name);
-    if (iter != defs_.end()) return iter->getValue();
-    return nullptr;
-  }
-
- private:
-  llvm::StringMap<const DartValue*> defs_;
-};
-
-// A DartConstant is a DartValue for a constant.
-class DartConstant : public DartValue {
- public:
-  std::string str;
-  enum class Type { String };
-  Type type;
-
-  llvm::Value* Make(BasicBlockBuilder& bb_builder) const override;
-  llvm::Type* GetType(BasicBlockBuilder& bb_builder) const override;
-};
-
-// Class DartInstruction represents a step within a DartBasicBlock.
-// CheckStackOverflow or PushArgument are instructions. They contain
-// DartValues as arguments typically. SSA definitions are also
-// DartInstructions which assign DartValues to names in the function's
-// context.
-class DartInstruction {
- public:
-  virtual ~DartInstruction();
-  virtual void Build(BasicBlockBuilder& bb_builder) const = 0;
-};
-
-// Class InstCheckStackOverflow is a DartInstruction that represents
-// an instance of a CheckStackOverflow instruction.
-class InstCheckStackOverflow : public DartInstruction {
- public:
-  InstCheckStackOverflow() {}
-  ~InstCheckStackOverflow() override {}
-  void Build(BasicBlockBuilder& bb_builder) const override;
-  static llvm::Expected<std::unique_ptr<DartInstruction>> Construct(
-      dart::SExpList* inst,
-      DartBasicBlockBuilder& bb_builder);
-};
-
-// Class InstPushArgument is a DartInstruction that represents
-// and instance of a PushArgument Instruction.
-class InstPushArgument : public DartInstruction {
- public:
-  explicit InstPushArgument(const DartValue* arg) : arg_(arg) {}
-  ~InstPushArgument() override {}
-  void Build(BasicBlockBuilder& bb_builder) const override;
-  static llvm::Expected<std::unique_ptr<DartInstruction>> Construct(
-      dart::SExpList* inst,
-      DartBasicBlockBuilder& bb_builder);
-
- private:
-  const DartValue* arg_;
-};
-
-// Class InstStaticCall is a DartInstruction that represents a
-// StaticCall instruction.
-class InstStaticCall : public DartInstruction {
- public:
-  InstStaticCall(const DartValue* func, size_t args_len)
-      : function_(func), args_len_(args_len) {}
-  ~InstStaticCall() override {}
-  void Build(BasicBlockBuilder& bb_builder) const override;
-  static llvm::Expected<std::unique_ptr<DartInstruction>> Construct(
-      dart::SExpList* inst,
-      DartBasicBlockBuilder& bb_builder);
-
- private:
-  const DartValue* function_;
-  size_t args_len_;
-};
-
-// Class InstReturn is a DartInstruction that represents a Return
-// instruction.
-class InstReturn : public DartInstruction {
- public:
-  InstReturn() {}
-  ~InstReturn() override {}
-  void Build(BasicBlockBuilder& bb_builder) const override;
-  static llvm::Expected<std::unique_ptr<DartInstruction>> Construct(
-      dart::SExpList* inst,
-      DartBasicBlockBuilder& bb_builder);
-};
-
-// Class DartBlock represents a validated basic block as parsed from
-// a (block ...) S-Expression.
-struct DartBlock {
-  std::string name;
-  std::vector<std::unique_ptr<DartInstruction>> instructions;
-};
-
-// Class DartFunction represents a validated function parsed from a
-// (function ...) S-Expression.
-struct DartFunction {
-  std::string name;
-  DartBlock* normal_entry;
-  llvm::StringMap<DartConstant> constants;
-  llvm::StringMap<DartBlock> blocks;
-};
-
-// MakeFunction takes an S-Expression and an environment of externally
-// defined DartValues and produces a DartFunction corresponding to the
-// S-Expression if everything is valid. If something about the syntax
-// of the S-Expression is invalid then the llvm::Expected will hold an
-// error explaining the issue.
-llvm::Expected<DartFunction> MakeFunction(
-    dart::Zone* zone,
-    dart::SExpression* sexpr,
-    const llvm::StringMap<const DartValue*>& env);
-
-#endif  // RUNTIME_LLVM_CODEGEN_CODEGEN_DART_H_
diff --git a/runtime/llvm_codegen/codegen/main.cc b/runtime/llvm_codegen/codegen/main.cc
deleted file mode 100644
index 40d8b3f..0000000
--- a/runtime/llvm_codegen/codegen/main.cc
+++ /dev/null
@@ -1,150 +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.
-
-#include "dart.h"
-
-#include "llvm/Analysis/TargetLibraryInfo.h"
-#include "llvm/IR/LegacyPassManager.h"
-#include "llvm/Support/Host.h"
-#include "llvm/Support/InitLLVM.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/TargetRegistry.h"
-#include "llvm/Support/TargetSelect.h"
-#include "llvm/Target/TargetMachine.h"
-
-using namespace llvm;
-
-namespace {
-
-StringRef tool_name;
-
-LLVM_ATTRIBUTE_NORETURN void error(Twine message) {
-  WithColor::error(errs(), "llvm-codegen") << message << ".\n";
-  errs().flush();
-  exit(1);
-}
-
-LLVM_ATTRIBUTE_NORETURN void error(Error e) {
-  assert(e);
-  std::string buf;
-  raw_string_ostream os(buf);
-  logAllUnhandledErrors(std::move(e), os);
-  os.flush();
-  WithColor::error(errs(), tool_name) << buf;
-  exit(1);
-}
-
-LLVM_ATTRIBUTE_NORETURN void reportError(StringRef File, std::error_code EC) {
-  assert(EC);
-  error(createFileError(File, EC));
-}
-
-// We need a prelude function for printing to help get something functional
-// up off the ground.
-class DartPrint : public DartValue {
- public:
-  Type* GetType(BasicBlockBuilder& bbb) const override {
-    auto& ctx = bbb.Context();
-    auto int8ty = IntegerType::getInt8Ty(ctx);
-    auto i8ptr = PointerType::get(int8ty, 0);
-    SmallVector<Type*, 1> arg_types;
-    arg_types.push_back(i8ptr);
-    return FunctionType::get(Type::getVoidTy(ctx), arg_types, false);
-  }
-  Value* Make(BasicBlockBuilder& bbb) const override {
-    auto ft = dyn_cast<FunctionType>(GetType(bbb));
-    if (ft == nullptr) return nullptr;
-    return Function::Create(ft, Function::ExternalLinkage, "dart:core::print",
-                            bbb.Module());
-  }
-};
-
-cl::opt<std::string> sexpr_file(cl::Positional,
-                                cl::desc("The input S-Expression file"));
-cl::opt<std::string> dump_obj(
-    "dump-obj",
-    cl::desc("Specifies where to output the .o file"));
-
-void Dump(Module* module, StringRef file, TargetMachine::CodeGenFileType type) {
-  legacy::PassManager pm;
-  std::error_code ec;
-  raw_fd_ostream out(file, ec);
-  if (ec) reportError(file, ec);
-  Triple target_triple{sys::getDefaultTargetTriple()};
-  TargetOptions options;
-  std::string err;
-  const Target* the_target =
-      TargetRegistry::lookupTarget(target_triple.getTriple(), err);
-  if (the_target == nullptr) error(err);
-  std::unique_ptr<TargetMachine> target(the_target->createTargetMachine(
-      target_triple.getTriple(), "generic", "", options, Reloc::PIC_));
-
-  if (target->addPassesToEmitFile(pm, out, nullptr, type, false))
-    error("couldn't add pass to emit file");
-  pm.run(*module);
-}
-
-}  // namespace
-
-int main(int argc, const char** argv) {
-  // Init llvm
-  InitLLVM X(argc, argv);
-  InitializeAllTargetInfos();
-  InitializeAllTargets();
-  InitializeAllTargetMCs();
-  InitializeAllAsmParsers();
-  InitializeAllAsmPrinters();
-
-  // Basic init
-  tool_name = argv[0];
-  cl::ParseCommandLineOptions(argc, argv, "llvm system compiler\n");
-
-  // Read in the file
-  auto file_or = MemoryBuffer::getFile(argv[1]);
-  if (!file_or) reportError(argv[1], file_or.getError());
-  std::unique_ptr<MemoryBuffer> file = std::move(file_or.get());
-
-  // Parse the file
-  dart::Zone zone;
-  dart::SExpParser parser(&zone, file->getBufferStart(), file->getBufferSize());
-  dart::SExpression* root = parser.Parse();
-  if (root == nullptr)
-    error(Twine("SExpParser failed: ") + parser.error_message());
-
-  // Setup our basic prelude
-  StringMap<const DartValue*> prelude;
-  DartPrint print;
-  prelude["dart:core::print"] = &print;
-
-  // Convert the function into an error checked format
-  auto function_or = MakeFunction(&zone, root, prelude);
-  if (!function_or) error(function_or.takeError());
-  auto dart_function = std::move(*function_or);
-  if (!dart_function.normal_entry)
-    error(Twine("function ") + dart_function.name + " has no normal-entry");
-
-  // Setup state for output an LLVMModule
-  LLVMContext context;
-  auto module = llvm::make_unique<Module>(argv[1], context);
-  auto function_type = FunctionType::get(Type::getVoidTy(context), {}, false);
-  auto function = Function::Create(function_type, Function::ExternalLinkage,
-                                   dart_function.name, module.get());
-  FunctionBuilder fb{context, *module, *function};
-  for (auto& bbkey : dart_function.blocks) {
-    auto& bb = bbkey.getValue();
-    auto llvmbb = fb.AddBasicBlock(bb.name);
-    BasicBlockBuilder bbb{llvmbb, fb};
-    for (auto& inst : bb.instructions) {
-      inst->Build(bbb);
-    }
-  }
-
-  // Dump and print the file
-  if (!dump_obj.empty())
-    Dump(module.get(), dump_obj, LLVMTargetMachine::CGFT_ObjectFile);
-
-  module->print(llvm::outs(), nullptr);
-
-  return 0;
-}
diff --git a/runtime/llvm_codegen/test/BUILD.gn b/runtime/llvm_codegen/test/BUILD.gn
deleted file mode 100644
index 633d3dc..0000000
--- a/runtime/llvm_codegen/test/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.
-
-group("test") {
-  deps = [
-    "bit",
-    "codegen",
-  ]
-}
diff --git a/runtime/llvm_codegen/test/bit/BUILD.gn b/runtime/llvm_codegen/test/bit/BUILD.gn
deleted file mode 100644
index 068ef59..0000000
--- a/runtime/llvm_codegen/test/bit/BUILD.gn
+++ /dev/null
@@ -1,9 +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("../bit_test.gni")
-
-bit_test("bit") {
-  tests = [ "basic.test" ]
-}
diff --git a/runtime/llvm_codegen/test/bit/Inputs/basic_input.test b/runtime/llvm_codegen/test/bit/Inputs/basic_input.test
deleted file mode 100644
index 092dc80..0000000
--- a/runtime/llvm_codegen/test/bit/Inputs/basic_input.test
+++ /dev/null
@@ -1 +0,0 @@
-; RUN: %{codegen} %p/../../codegen/Inputs/hello.sexp
diff --git a/runtime/llvm_codegen/test/bit/Inputs/percent.test b/runtime/llvm_codegen/test/bit/Inputs/percent.test
deleted file mode 100644
index 8b6782d..0000000
--- a/runtime/llvm_codegen/test/bit/Inputs/percent.test
+++ /dev/null
@@ -1 +0,0 @@
-this is a percent sign: %
diff --git a/runtime/llvm_codegen/test/bit/basic.test b/runtime/llvm_codegen/test/bit/basic.test
deleted file mode 100644
index 88f0479..0000000
--- a/runtime/llvm_codegen/test/bit/basic.test
+++ /dev/null
@@ -1,8 +0,0 @@
-; RUN: echo this is a test > %t1
-; RUN: echo this is a test > %t2
-; RUN: cmp %t1 %t2
-; RUN: echo this is a percent sign: % > %t3
-; RUN: cmp %t3 %p/Inputs/percent.test
-; RUN: %{bit} %p/Inputs/basic_input.test %P > %t.test
-; RUN: echo Commands run: 1 > %t.test2
-; RUN: cmp %t.test %t.test2
diff --git a/runtime/llvm_codegen/test/bit_test.gni b/runtime/llvm_codegen/test/bit_test.gni
deleted file mode 100644
index 6b19e62..0000000
--- a/runtime/llvm_codegen/test/bit_test.gni
+++ /dev/null
@@ -1,38 +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("../../../build/executable_suffix.gni")
-
-# This file defines a template for running bit tests.
-#
-# - bit_test()
-#   Runs bit on the specified file.
-
-# A template for running bit. This lets bit commands be run as ninja commands.
-#
-# Parameters:
-#   tests:
-#     The list of files to input into bit
-template("bit_test") {
-  assert(defined(invoker.tests), "tests must be defined for $target_name")
-
-  action_foreach(target_name) {
-    script = "//runtime/llvm_codegen/test/run_bit.py"
-    sources = invoker.tests
-
-    deps = [ "../../bit" ]
-    inputs = [ "${root_out_dir}/bit$executable_suffix" ]
-
-    # This output is always dirty so ninja will always run this step when asked to.
-    outputs = [ "$target_gen_dir/{{source_name_part}}}" ]
-    args = [
-      "--bit",
-      rebase_path("${root_out_dir}/bit"),
-      "--test",
-      "{{source}}",
-      "--out",
-      rebase_path(target_gen_dir),
-    ]
-  }
-}
diff --git a/runtime/llvm_codegen/test/codegen/BUILD.gn b/runtime/llvm_codegen/test/codegen/BUILD.gn
deleted file mode 100644
index 34dbba2..0000000
--- a/runtime/llvm_codegen/test/codegen/BUILD.gn
+++ /dev/null
@@ -1,9 +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("../bit_test.gni")
-
-bit_test("codegen") {
-  tests = [ "hello.test" ]
-}
diff --git a/runtime/llvm_codegen/test/codegen/Inputs/hello.expected b/runtime/llvm_codegen/test/codegen/Inputs/hello.expected
deleted file mode 100644
index 8ab686e..0000000
--- a/runtime/llvm_codegen/test/codegen/Inputs/hello.expected
+++ /dev/null
@@ -1 +0,0 @@
-Hello, World!
diff --git a/runtime/llvm_codegen/test/codegen/Inputs/hello.ll.expected b/runtime/llvm_codegen/test/codegen/Inputs/hello.ll.expected
deleted file mode 100644
index 187fd59..0000000
--- a/runtime/llvm_codegen/test/codegen/Inputs/hello.ll.expected
+++ /dev/null
@@ -1,35 +0,0 @@
-; ModuleID = '../../runtime/llvm_codegen/test/codegen/Inputs/hello.sexp'
-source_filename = "../../runtime/llvm_codegen/test/codegen/Inputs/hello.sexp"
-
-@0 = constant [14 x i8] c"Hello, World!\00"
-
-define void @"hello.dart::main"() {
-B1:
-  %0 = call i8* @llvm.stacksave()
-  %1 = ptrtoint i8* %0 to i64
-  %2 = load i64, i64 addrspace(256)* inttoptr (i64 72 to i64 addrspace(256)*)
-  %3 = icmp ult i64 %1, %2
-  br i1 %3, label %4, label %5
-
-4:                                                ; preds = %B1
-  call void @llvm.trap()
-  br label %5
-
-5:                                                ; preds = %4, %B1
-  call void @"dart:core::print"(i8* getelementptr inbounds ([14 x i8], [14 x i8]* @0, i32 0, i32 0))
-  ret void
-}
-
-; Function Attrs: nounwind
-declare i8* @llvm.stacksave() #0
-
-; Function Attrs: cold noreturn nounwind
-declare void @llvm.trap() #1
-
-declare void @"dart:core::print"(i8*)
-
-; Function Attrs: nounwind
-declare void @llvm.stackprotector(i8*, i8**) #0
-
-attributes #0 = { nounwind }
-attributes #1 = { cold noreturn nounwind }
diff --git a/runtime/llvm_codegen/test/codegen/Inputs/hello.sexp b/runtime/llvm_codegen/test/codegen/Inputs/hello.sexp
deleted file mode 100644
index c43c359..0000000
--- a/runtime/llvm_codegen/test/codegen/Inputs/hello.sexp
+++ /dev/null
@@ -1,9 +0,0 @@
-(function hello.dart::main
-  (constants
-    (def v2 "Hello, World!"))
-  (normal-entry B1)
-  (block B1
-    (CheckStackOverflow)
-    (PushArgument v2)
-    (StaticCall dart:core::print { args_len 1, env (v0 arg[0]), })
-    (Return v0)))
diff --git a/runtime/llvm_codegen/test/codegen/Inputs/runtime.S b/runtime/llvm_codegen/test/codegen/Inputs/runtime.S
deleted file mode 100644
index 7bb2c76..0000000
--- a/runtime/llvm_codegen/test/codegen/Inputs/runtime.S
+++ /dev/null
@@ -1,38 +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.
-
-.data
-
-.type _threadObject,@object
-.size _threadObject,1400
-_threadObject:
-  .fill 1400
-
-.text
-.file "runtime.S"
-
-.globl main
-.type main,@function
-
-.globl "dart:core::print"
-.type "dart:core::print",@function
-
-.globl arch_prctl
-.type arch_prctl,@function
-
-main:
-  movq %rsp, %rax
-  subq $0x1000, %rax
-  movq %rax, [_threadObject + 72]
-  # Pass ARCH_SET_GS
-  movq $0x1001, %rdi
-  # Pass $_threadObject
-  movq $_threadObject, %rsi
-  callq arch_prctl
-  callq "hello.dart::main"
-  ret
-
-"dart:core::print":
-  callq puts
-  ret
diff --git a/runtime/llvm_codegen/test/codegen/hello.test b/runtime/llvm_codegen/test/codegen/hello.test
deleted file mode 100644
index 6b836d7..0000000
--- a/runtime/llvm_codegen/test/codegen/hello.test
+++ /dev/null
@@ -1,6 +0,0 @@
-; RUN: %{codegen} %p/Inputs/hello.sexp --dump-obj %t.o > %t.ll
-; RUN: diff %t.ll %p/Inputs/hello.ll.expected
-; RUN: %{clang} -g -c %p/Inputs/runtime.S -o %t.runtime.o
-; RUN: %{clang} %t.o %t.runtime.o -o %t.hello.exe
-; RUN: %t.hello.exe > %t.hello.exe.stdout
-; RUN: diff %t.hello.exe.stdout %p/Inputs/hello.expected
diff --git a/runtime/llvm_codegen/test/run_bit.py b/runtime/llvm_codegen/test/run_bit.py
deleted file mode 100644
index 29863f1..0000000
--- a/runtime/llvm_codegen/test/run_bit.py
+++ /dev/null
@@ -1,15 +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 subprocess
-import argparse
-
-parser = argparse.ArgumentParser(description="A tool to run the bit integration tester")
-parser.add_argument("--bit", help="Sets the path to bit")
-parser.add_argument("--test", help="Path to test to be run")
-parser.add_argument("--out", help="Path to out directory")
-args = parser.parse_args()
-
-subprocess.check_call([args.bit, args.test, args.out])
-
diff --git a/runtime/observatory/lib/src/sample_profile/sample_profile.dart b/runtime/observatory/lib/src/sample_profile/sample_profile.dart
index 06280ce..91bf3ac 100644
--- a/runtime/observatory/lib/src/sample_profile/sample_profile.dart
+++ b/runtime/observatory/lib/src/sample_profile/sample_profile.dart
@@ -784,7 +784,7 @@
   static const String _kSamples = 'samples';
   static const String _kStack = 'stack';
   static const String _kMaxStackDepth = 'maxStackDepth';
-  static const String _kTimeSpan = 'timespan';
+  static const String _kTimeSpan = 'timeExtentMicros';
   static const String _kUserTag = 'userTag';
   static const String _kVmTag = 'vmTag';
 
@@ -895,7 +895,7 @@
       samplePeriod = profile[_kSamplePeriod];
       sampleRate = (Duration.microsecondsPerSecond / samplePeriod);
       maxStackDepth = profile[_kMaxStackDepth];
-      timeSpan = profile[_kTimeSpan];
+      timeSpan = profile[_kTimeSpan] / Duration.microsecondsPerSecond;
 
       num length = 0;
 
diff --git a/runtime/observatory/tests/service/allocations_test.dart b/runtime/observatory/tests/service/allocations_test.dart
index 6a7d002..bc98c0e 100644
--- a/runtime/observatory/tests/service/allocations_test.dart
+++ b/runtime/observatory/tests/service/allocations_test.dart
@@ -8,6 +8,7 @@
 import 'package:test/test.dart';
 import 'test_helper.dart';
 
+@pragma('vm:entry-point')
 class Foo {}
 
 // Prevent TFA from removing this static field to ensure the objects are kept
diff --git a/runtime/observatory/tests/service/break_on_function_child_isolate_test.dart b/runtime/observatory/tests/service/break_on_function_child_isolate_test.dart
new file mode 100644
index 0000000..bd471ac
--- /dev/null
+++ b/runtime/observatory/tests/service/break_on_function_child_isolate_test.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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=--verbose_debug --enable-isolate-groups --experimental-enable-isolate-groups-jit
+
+import 'break_on_function_many_child_isolates_test.dart';
+
+main(args) async {
+  await runIsolateBreakpointPauseTest(args, /*nIsolates=*/ 1);
+}
diff --git a/runtime/observatory/tests/service/break_on_function_many_child_isolates_test.dart b/runtime/observatory/tests/service/break_on_function_many_child_isolates_test.dart
new file mode 100644
index 0000000..916e6f9
--- /dev/null
+++ b/runtime/observatory/tests/service/break_on_function_many_child_isolates_test.dart
@@ -0,0 +1,113 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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=--verbose_debug --enable-isolate-groups --experimental-enable-isolate-groups-jit
+//
+// Tests breakpoint pausing and resuming with many isolates running and pausing
+// simultaneously.
+
+import 'dart:async';
+import 'dart:developer';
+import 'dart:isolate' as dart_isolate;
+
+import 'package:observatory/service_io.dart';
+import 'package:test/test.dart';
+
+import 'service_test_common.dart';
+import 'test_helper.dart';
+
+const int LINE_A = 23;
+const int LINE_B = 35;
+const int LINE_C = 41;
+
+foo(args) { // LINE_A
+  print('${dart_isolate.Isolate.current.debugName}: $args');
+  final sendPort = args[0] as dart_isolate.SendPort;
+  final int i = args[1] as int;
+  sendPort.send('reply from foo: $i');
+}
+
+int nIsolates = -1;
+
+testMain() async {
+  final rps = List<dart_isolate.ReceivePort>.generate(
+      nIsolates, (i) => dart_isolate.ReceivePort());
+  debugger(); // LINE_B
+  for (int i = 0; i < nIsolates; i++) {
+    await dart_isolate.Isolate.spawn(foo, [rps[i].sendPort, i],
+        debugName: "foo$i");
+  }
+  print(await Future.wait(rps.map((rp) => rp.first)));
+  debugger(); // LINE_C
+}
+
+final completerAtFoo = List<Completer>.generate(nIsolates, (_) => Completer());
+int completerCount = 0;
+
+final tests = <IsolateTest>[
+  hasPausedAtStart,
+  resumeIsolate,
+  hasStoppedAtBreakpoint,
+  stoppedAtLine(LINE_B + 1),
+  (Isolate isolate) async {
+    // Set up a listener to wait for child isolate launch and breakpoint events.
+    final stream = await isolate.vm.getEventStream(VM.kDebugStream);
+    var subscription;
+    subscription = stream.listen((ServiceEvent event) async {
+      switch (event.kind) {
+        case ServiceEvent.kPauseStart:
+          final childIsolate = event.isolate!;
+          await childIsolate.reload();
+
+          for (Library lib in childIsolate.libraries) {
+            await lib.load();
+            if (lib.uri!
+                .endsWith('break_on_function_many_child_isolates_test.dart')) {
+              final foo = lib.functions.singleWhere((f) => f.name == 'foo');
+              final bpt = await childIsolate.addBreakpointAtEntry(foo);
+
+              expect(bpt is Breakpoint, isTrue);
+              break;
+            }
+          }
+          childIsolate.resume();
+          break;
+        case ServiceEvent.kPauseBreakpoint:
+          final name = event.isolate!.name!;
+          if (!name.startsWith('foo')) {
+            break;
+          }
+          final childIsolate = event.isolate;
+          final ndx = int.parse(name.substring('foo'.length));
+          final stack = await childIsolate!.getStack();
+          final top = stack['frames'][0];
+          final script = await top.location.script.load() as Script;
+          expect(script.tokenToLine(top.location.tokenPos), equals(LINE_A));
+
+          childIsolate.resume();
+          if ((++completerCount) == nIsolates) {
+            subscription.cancel();
+          }
+          completerAtFoo[ndx].complete();
+          break;
+      }
+    });
+  },
+  resumeIsolate,
+  (Isolate isolate) async {
+    await Future.wait(completerAtFoo.map((c) => c.future));
+  },
+  hasStoppedAtBreakpoint,
+  stoppedAtLine(LINE_C + 1),
+  resumeIsolate,
+];
+
+Future runIsolateBreakpointPauseTest(args, nIsolates_) {
+  nIsolates = nIsolates_;
+  return runIsolateTests(args, tests,
+      testeeConcurrent: testMain, pause_on_start: true);
+}
+
+main(args) async {
+  await runIsolateBreakpointPauseTest(args, /*nIsolates=*/ 30);
+}
diff --git a/runtime/observatory/tests/service/capture_stdio_test.dart b/runtime/observatory/tests/service/capture_stdio_test.dart
index b02e476..fa4afc7 100644
--- a/runtime/observatory/tests/service/capture_stdio_test.dart
+++ b/runtime/observatory/tests/service/capture_stdio_test.dart
@@ -28,6 +28,7 @@
     var stdoutSub;
     stdoutSub = await isolate.vm.listenEventStream(VM.kStdoutStream,
         (ServiceEvent event) {
+      expect(event.isolate != null, isTrue);
       expect(event.kind, equals('WriteEvent'));
       expect(event.bytesAsString, equals('stdout'));
       stdoutSub.cancel().then((_) {
@@ -44,6 +45,7 @@
     int eventNumber = 1;
     stdoutSub = await isolate.vm.listenEventStream(VM.kStdoutStream,
         (ServiceEvent event) {
+      expect(event.isolate != null, isTrue);
       expect(event.kind, equals('WriteEvent'));
       if (eventNumber == 1) {
         expect(event.bytesAsString, equals('print'));
@@ -66,6 +68,7 @@
     var stderrSub;
     stderrSub = await isolate.vm.listenEventStream(VM.kStderrStream,
         (ServiceEvent event) {
+      expect(event.isolate != null, isTrue);
       expect(event.kind, equals('WriteEvent'));
       expect(event.bytesAsString, equals('stderr'));
       stderrSub.cancel().then((_) {
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 c2abb01..bd23544 100644
--- a/runtime/observatory/tests/service/get_retaining_path_rpc_test.dart
+++ b/runtime/observatory/tests/service/get_retaining_path_rpc_test.dart
@@ -10,9 +10,9 @@
 class _TestClass {
   _TestClass();
   // Make sure these fields are not removed by the tree shaker.
-  @pragma("vm:entry-point")
+  @pragma("vm:entry-point") // Prevent obfuscation
   dynamic x;
-  @pragma("vm:entry-point")
+  @pragma("vm:entry-point") // Prevent obfuscation
   dynamic y;
 }
 
@@ -22,6 +22,7 @@
 dynamic target4 = new _TestClass();
 dynamic target5 = new _TestClass();
 dynamic target6 = new _TestClass();
+@pragma("vm:entry-point") // Prevent obfuscation
 Expando<_TestClass> expando = Expando<_TestClass>();
 @pragma("vm:entry-point") // Prevent obfuscation
 dynamic globalObject = new _TestClass();
@@ -40,45 +41,45 @@
   globalMap2[target5] = 'value';
 }
 
-@pragma("vm:entry-point")
+@pragma("vm:entry-point") // Prevent obfuscation
 getGlobalObject() => globalObject;
 
-@pragma("vm:entry-point")
+@pragma("vm:entry-point") // Prevent obfuscation
 takeTarget1() {
   var tmp = target1;
   target1 = null;
   return tmp;
 }
 
-@pragma("vm:entry-point")
+@pragma("vm:entry-point") // Prevent obfuscation
 takeTarget2() {
   var tmp = target2;
   target2 = null;
   return tmp;
 }
 
-@pragma("vm:entry-point")
+@pragma("vm:entry-point") // Prevent obfuscation
 takeTarget3() {
   var tmp = target3;
   target3 = null;
   return tmp;
 }
 
-@pragma("vm:entry-point")
+@pragma("vm:entry-point") // Prevent obfuscation
 takeTarget4() {
   var tmp = target4;
   target4 = null;
   return tmp;
 }
 
-@pragma("vm:entry-point")
+@pragma("vm:entry-point") // Prevent obfuscation
 takeTarget5() {
   var tmp = target5;
   target5 = null;
   return tmp;
 }
 
-@pragma("vm:entry-point")
+@pragma("vm:entry-point") // Prevent obfuscation
 takeExpandoTarget() {
   var tmp = target6;
   target6 = null;
@@ -87,7 +88,7 @@
   return tmp2;
 }
 
-@pragma("vm:entry-point")
+@pragma("vm:entry-point") // Prevent obfuscation
 getTrue() => true;
 
 invoke(Isolate isolate, String selector) async {
@@ -216,7 +217,6 @@
     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');
   },
 
diff --git a/runtime/observatory/tests/service/get_user_level_retaining_path_rpc_test.dart b/runtime/observatory/tests/service/get_user_level_retaining_path_rpc_test.dart
index 535c882..4273caf 100644
--- a/runtime/observatory/tests/service/get_user_level_retaining_path_rpc_test.dart
+++ b/runtime/observatory/tests/service/get_user_level_retaining_path_rpc_test.dart
@@ -13,13 +13,16 @@
   var y;
 }
 
+@pragma("vm:entry-point") // Prevent obfuscation
 class _TestConst {
   const _TestConst();
 }
 
 _TopLevelClosure() {}
 
+@pragma("vm:entry-point") // Prevent obfuscation
 var x;
+@pragma("vm:entry-point") // Prevent obfuscation
 var fn;
 
 void warmup() {
@@ -27,10 +30,10 @@
   fn = _TopLevelClosure;
 }
 
-@pragma("vm:entry-point")
+@pragma("vm:entry-point") // Prevent obfuscation
 getX() => x;
 
-@pragma("vm:entry-point")
+@pragma("vm:entry-point") // Prevent obfuscation
 getFn() => fn;
 
 invoke(Isolate isolate, String selector) async {
diff --git a/runtime/observatory/tests/service/get_version_rpc_test.dart b/runtime/observatory/tests/service/get_version_rpc_test.dart
index 9596513..b63155d 100644
--- a/runtime/observatory/tests/service/get_version_rpc_test.dart
+++ b/runtime/observatory/tests/service/get_version_rpc_test.dart
@@ -12,7 +12,7 @@
     final result = await vm.invokeRpcNoUpgrade('getVersion', {});
     expect(result['type'], 'Version');
     expect(result['major'], 3);
-    expect(result['minor'], 43);
+    expect(result['minor'], 44);
     expect(result['_privateMajor'], 0);
     expect(result['_privateMinor'], 0);
   },
diff --git a/runtime/observatory/tests/service/inbound_references_test.dart b/runtime/observatory/tests/service/inbound_references_test.dart
index 548aa7e..9e781c0 100644
--- a/runtime/observatory/tests/service/inbound_references_test.dart
+++ b/runtime/observatory/tests/service/inbound_references_test.dart
@@ -8,14 +8,16 @@
 import 'package:test/test.dart';
 import 'test_helper.dart';
 
+@pragma("vm:entry-point") // Prevent obfuscation
 class Node {
   // Make sure this field is not removed by the tree shaker.
-  @pragma("vm:entry-point")
+  @pragma("vm:entry-point") // Prevent obfuscation
   var edge;
 }
 
 class Edge {}
 
+@pragma("vm:entry-point") // Prevent obfuscation
 var n, e, array;
 
 void script() {
diff --git a/runtime/observatory/tests/service/object_graph_identity_hash_test.dart b/runtime/observatory/tests/service/object_graph_identity_hash_test.dart
index eb7c109..66a029f 100644
--- a/runtime/observatory/tests/service/object_graph_identity_hash_test.dart
+++ b/runtime/observatory/tests/service/object_graph_identity_hash_test.dart
@@ -8,40 +8,42 @@
 import 'service_test_common.dart';
 import 'test_helper.dart';
 
+@pragma("vm:entry-point") // Prevent obfuscation
 class Foo {}
 
+@pragma("vm:entry-point") // Prevent obfuscation
 class Bar {}
 
 class Container1 {
-  @pragma("vm:entry-point")
+  @pragma("vm:entry-point") // Prevent obfuscation
   Foo foo = Foo();
-  @pragma("vm:entry-point")
+  @pragma("vm:entry-point") // Prevent obfuscation
   Bar bar = Bar();
 }
 
 class Container2 {
   Container2(this.foo);
 
-  @pragma("vm:entry-point")
+  @pragma("vm:entry-point") // Prevent obfuscation
   Foo foo;
-  @pragma("vm:entry-point")
+  @pragma("vm:entry-point") // Prevent obfuscation
   Bar bar = Bar();
 }
 
 class Container3 {
-  @pragma("vm:entry-point")
+  @pragma("vm:entry-point") // Prevent obfuscation
   int number = 42;
-  @pragma("vm:entry-point")
+  @pragma("vm:entry-point") // Prevent obfuscation
   double doub = 3.14;
-  @pragma("vm:entry-point")
+  @pragma("vm:entry-point") // Prevent obfuscation
   String foo = 'foobar';
-  @pragma("vm:entry-point")
+  @pragma("vm:entry-point") // Prevent obfuscation
   bool bar = false;
-  @pragma("vm:entry-point")
+  @pragma("vm:entry-point") // Prevent obfuscation
   late Map baz;
-  @pragma("vm:entry-point")
+  @pragma("vm:entry-point") // Prevent obfuscation
   late List list;
-  @pragma("vm:entry-point")
+  @pragma("vm:entry-point") // Prevent obfuscation
   late List unmodifiableList;
 
   Container3() {
@@ -53,11 +55,11 @@
   }
 }
 
-@pragma("vm:entry-point")
+@pragma("vm:entry-point") // Prevent obfuscation
 late Container1 c1;
-@pragma("vm:entry-point")
+@pragma("vm:entry-point") // Prevent obfuscation
 late Container2 c2;
-@pragma("vm:entry-point")
+@pragma("vm:entry-point") // Prevent obfuscation
 late Container3 c3;
 
 void script() {
diff --git a/runtime/observatory/tests/service/reachable_size_test.dart b/runtime/observatory/tests/service/reachable_size_test.dart
index 8cf9f9e..db0a3ee 100644
--- a/runtime/observatory/tests/service/reachable_size_test.dart
+++ b/runtime/observatory/tests/service/reachable_size_test.dart
@@ -10,13 +10,15 @@
 
 class Pair {
   // Make sure these fields are not removed by the tree shaker.
-  @pragma("vm:entry-point")
+  @pragma("vm:entry-point") // Prevent obfuscation
   dynamic x;
-  @pragma("vm:entry-point")
+  @pragma("vm:entry-point") // Prevent obfuscation
   dynamic y;
 }
 
+@pragma("vm:entry-point") // Prevent obfuscation
 dynamic p1;
+@pragma("vm:entry-point") // Prevent obfuscation
 dynamic p2;
 
 buildGraph() {
diff --git a/runtime/observatory/tests/service/service_kernel.status b/runtime/observatory/tests/service/service_kernel.status
index 16e2d93..3ddf48d 100644
--- a/runtime/observatory/tests/service/service_kernel.status
+++ b/runtime/observatory/tests/service/service_kernel.status
@@ -31,6 +31,7 @@
 pause_on_exceptions_test: SkipByDesign # No incremental compiler available.
 rewind_optimized_out_test: SkipByDesign # No incremental compiler available.
 rewind_test: SkipByDesign # No incremental compiler available.
+sigquit_starts_service_test: SkipByDesign # Spawns a secondary process using Platform.executable.
 
 [ $compiler == dartk ]
 bad_reload_test: RuntimeError # Issue 34025
@@ -38,6 +39,7 @@
 evaluate_activation_test/instance: RuntimeError # http://dartbug.com/20047
 evaluate_activation_test/scope: RuntimeError # http://dartbug.com/20047
 get_source_report_test: RuntimeError # Should pass again when constant evaluation is relanded, see http://dartbug.com/36600
+pause_on_exception_from_slow_path_test: Pass, Slow
 pause_on_unhandled_async_exceptions2_test: Pass, Slow
 
 [ $compiler == dartkp ]
@@ -58,6 +60,8 @@
 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_child_isolate_test: SkipByDesign # Debugger is disabled in AOT mode.
+break_on_function_many_child_isolates_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.
@@ -172,6 +176,7 @@
 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.
+sigquit_starts_service_test: SkipByDesign # Spawns a secondary process using Platform.executable.
 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.
@@ -298,6 +303,7 @@
 rewind_optimized_out_test: RuntimeError # Issue #34736
 rewind_test: Pass, RuntimeError
 set_name_rpc_test: RuntimeError # Please triage.
+sigquit_starts_service_test: SkipByDesign # Spawns a secondary process using Platform.executable.
 simple_reload_test: RuntimeError, Timeout
 valid_source_locations_test: Skip # Issue 34736, too slow.
 
diff --git a/runtime/observatory/tests/service/sigquit_starts_service_script.dart b/runtime/observatory/tests/service/sigquit_starts_service_script.dart
new file mode 100644
index 0000000..e5f24e8
--- /dev/null
+++ b/runtime/observatory/tests/service/sigquit_starts_service_script.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+Future<void> main() async {
+  print('ready');
+  while (true) {
+    await Future.delayed(const Duration(seconds: 1));
+  }
+}
diff --git a/runtime/observatory/tests/service/sigquit_starts_service_test.dart b/runtime/observatory/tests/service/sigquit_starts_service_test.dart
new file mode 100644
index 0000000..911c12d
--- /dev/null
+++ b/runtime/observatory/tests/service/sigquit_starts_service_test.dart
@@ -0,0 +1,43 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:convert';
+import 'dart:io';
+
+import 'package:test/test.dart';
+
+void runTest(bool withDartDev) {
+  test(
+      'Displays service URI on SIGQUIT ${withDartDev ? '' : 'with --disable-dart-dev'}',
+      () async {
+    final process = await Process.start(Platform.resolvedExecutable, [
+      if (!withDartDev) '--disable-dart-dev',
+      Platform.script.resolve('sigquit_starts_service_script.dart').toString(),
+    ]);
+
+    final readyCompleter = Completer<void>();
+    final completer = Completer<void>();
+    late StreamSubscription sub;
+    sub = process.stdout.transform(utf8.decoder).listen((e) async {
+      if (e.contains('ready') && !readyCompleter.isCompleted) {
+        readyCompleter.complete();
+      } else if (e.contains('Observatory listening on')) {
+        await sub.cancel();
+        completer.complete();
+      }
+    });
+
+    // Wait for the process to start.
+    await readyCompleter.future;
+    process.kill(ProcessSignal.sigquit);
+    await completer.future;
+    process.kill();
+  }, skip: Platform.isWindows);
+}
+
+void main() {
+  runTest(true);
+  runTest(false);
+}
diff --git a/runtime/observatory/tests/service/string_escaping_test.dart b/runtime/observatory/tests/service/string_escaping_test.dart
index d306186..866178c6 100644
--- a/runtime/observatory/tests/service/string_escaping_test.dart
+++ b/runtime/observatory/tests/service/string_escaping_test.dart
@@ -9,20 +9,35 @@
 import 'package:test/test.dart';
 import 'test_helper.dart';
 
+@pragma("vm:entry-point") // Prevent obfuscation
 var ascii;
+@pragma("vm:entry-point") // Prevent obfuscation
 var latin1;
+@pragma("vm:entry-point") // Prevent obfuscation
 var unicode;
+@pragma("vm:entry-point") // Prevent obfuscation
 var hebrew;
+@pragma("vm:entry-point") // Prevent obfuscation
 var singleQuotes;
+@pragma("vm:entry-point") // Prevent obfuscation
 var doubleQuotes;
+@pragma("vm:entry-point") // Prevent obfuscation
 var newLines;
+@pragma("vm:entry-point") // Prevent obfuscation
 var tabs;
+@pragma("vm:entry-point") // Prevent obfuscation
 var suggrogatePairs;
+@pragma("vm:entry-point") // Prevent obfuscation
 var nullInTheMiddle;
+@pragma("vm:entry-point") // Prevent obfuscation
 var escapedUnicodeEscape;
+@pragma("vm:entry-point") // Prevent obfuscation
 var longStringEven;
+@pragma("vm:entry-point") // Prevent obfuscation
 var longStringOdd;
+@pragma("vm:entry-point") // Prevent obfuscation
 var malformedWithLeadSurrogate;
+@pragma("vm:entry-point") // Prevent obfuscation
 var malformedWithTrailSurrogate;
 
 void script() {
diff --git a/runtime/observatory/tests/service/typed_data_test.dart b/runtime/observatory/tests/service/typed_data_test.dart
index 9c4ba3b..d37a79f 100644
--- a/runtime/observatory/tests/service/typed_data_test.dart
+++ b/runtime/observatory/tests/service/typed_data_test.dart
@@ -9,25 +9,42 @@
 import 'package:test/test.dart';
 import 'test_helper.dart';
 
+@pragma("vm:entry-point") // Prevent obfuscation
 var int8List;
+@pragma("vm:entry-point") // Prevent obfuscation
 var int16List;
+@pragma("vm:entry-point") // Prevent obfuscation
 var int32List;
+@pragma("vm:entry-point") // Prevent obfuscation
 var int64List;
 
+@pragma("vm:entry-point") // Prevent obfuscation
 var uint8List;
+@pragma("vm:entry-point") // Prevent obfuscation
 var uint16List;
+@pragma("vm:entry-point") // Prevent obfuscation
 var uint32List;
+@pragma("vm:entry-point") // Prevent obfuscation
 var uint64List;
+@pragma("vm:entry-point") // Prevent obfuscation
 var uint8ClampedList;
 
+@pragma("vm:entry-point") // Prevent obfuscation
 var float32List;
+@pragma("vm:entry-point") // Prevent obfuscation
 var float64List;
 
+@pragma("vm:entry-point") // Prevent obfuscation
 var int32x4;
+@pragma("vm:entry-point") // Prevent obfuscation
 var float32x4;
+@pragma("vm:entry-point") // Prevent obfuscation
 var float64x2;
+@pragma("vm:entry-point") // Prevent obfuscation
 var int32x4List;
+@pragma("vm:entry-point") // Prevent obfuscation
 var float32x4List;
+@pragma("vm:entry-point") // Prevent obfuscation
 var float64x2List;
 
 void script() {
diff --git a/runtime/observatory/tests/service/verify_http_timeline_test.dart b/runtime/observatory/tests/service/verify_http_timeline_test.dart
index 7c9d7c8..9ef4719 100644
--- a/runtime/observatory/tests/service/verify_http_timeline_test.dart
+++ b/runtime/observatory/tests/service/verify_http_timeline_test.dart
@@ -249,24 +249,6 @@
   for (final event in events) {
     if (isStartEvent(event)) {
       validateHttpStartEvent(event, method);
-      // Check body of request has been sent and recorded correctly.
-      if (method == 'DELETE' || method == 'POST') {
-        final id = event['id'];
-        final bodyEvent =
-            filterEventsByIdAndName(traceEvents, id, 'Request body');
-        // Due to randomness, it doesn't guarantee to have the timeline events.
-        if (bodyEvent.length == 1) {
-          if (method == 'POST') {
-            // add() was used
-            Expect.listEquals(
-                <int>[0, 1, 2], bodyEvent[0]['args']['encodedData']);
-          } else {
-            // write() was used.
-            Expect.isTrue(
-                bodyEvent[0]['args']['data'].startsWith('$method http'));
-          }
-        }
-      }
     } else if (isFinishEvent(event)) {
       validateHttpFinishEvent(event);
     } else {
diff --git a/runtime/observatory_2/lib/src/sample_profile/sample_profile.dart b/runtime/observatory_2/lib/src/sample_profile/sample_profile.dart
index 48667cc..8d1a385 100644
--- a/runtime/observatory_2/lib/src/sample_profile/sample_profile.dart
+++ b/runtime/observatory_2/lib/src/sample_profile/sample_profile.dart
@@ -780,7 +780,7 @@
   static const String _kSamples = 'samples';
   static const String _kStack = 'stack';
   static const String _kMaxStackDepth = 'maxStackDepth';
-  static const String _kTimeSpan = 'timespan';
+  static const String _kTimeSpan = 'timeExtentMicros';
   static const String _kUserTag = 'userTag';
   static const String _kVmTag = 'vmTag';
 
@@ -891,7 +891,7 @@
       samplePeriod = profile[_kSamplePeriod];
       sampleRate = (Duration.microsecondsPerSecond / samplePeriod);
       maxStackDepth = profile[_kMaxStackDepth];
-      timeSpan = profile[_kTimeSpan];
+      timeSpan = profile[_kTimeSpan] / Duration.microsecondsPerSecond;
 
       num length = 0;
 
diff --git a/runtime/observatory_2/tests/service_2/allocations_test.dart b/runtime/observatory_2/tests/service_2/allocations_test.dart
index 3fb6ce4..2732498 100644
--- a/runtime/observatory_2/tests/service_2/allocations_test.dart
+++ b/runtime/observatory_2/tests/service_2/allocations_test.dart
@@ -8,6 +8,7 @@
 import 'package:test/test.dart';
 import 'test_helper.dart';
 
+@pragma('vm:entry-point')
 class Foo {}
 
 // Prevent TFA from removing this static field to ensure the objects are kept
diff --git a/runtime/observatory_2/tests/service_2/break_on_function_child_isolate_test.dart b/runtime/observatory_2/tests/service_2/break_on_function_child_isolate_test.dart
new file mode 100644
index 0000000..bd471ac
--- /dev/null
+++ b/runtime/observatory_2/tests/service_2/break_on_function_child_isolate_test.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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=--verbose_debug --enable-isolate-groups --experimental-enable-isolate-groups-jit
+
+import 'break_on_function_many_child_isolates_test.dart';
+
+main(args) async {
+  await runIsolateBreakpointPauseTest(args, /*nIsolates=*/ 1);
+}
diff --git a/runtime/observatory_2/tests/service_2/break_on_function_many_child_isolates_test.dart b/runtime/observatory_2/tests/service_2/break_on_function_many_child_isolates_test.dart
new file mode 100644
index 0000000..b527cb54
--- /dev/null
+++ b/runtime/observatory_2/tests/service_2/break_on_function_many_child_isolates_test.dart
@@ -0,0 +1,113 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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=--verbose_debug --enable-isolate-groups --experimental-enable-isolate-groups-jit
+//
+// Tests breakpoint pausing and resuming with many isolates running and pausing
+// simultaneously.
+
+import 'dart:async';
+import 'dart:developer';
+import 'dart:isolate' as dart_isolate;
+
+import 'package:observatory_2/service_io.dart';
+import 'package:test/test.dart';
+
+import 'service_test_common.dart';
+import 'test_helper.dart';
+
+const int LINE_A = 23;
+const int LINE_B = 35;
+const int LINE_C = 41;
+
+foo(args) { // LINE_A
+  print('${dart_isolate.Isolate.current.debugName}: $args');
+  final sendPort = args[0] as dart_isolate.SendPort;
+  final int i = args[1] as int;
+  sendPort.send('reply from foo: $i');
+}
+
+int nIsolates = -1;
+
+testMain() async {
+  final rps = List<dart_isolate.ReceivePort>.generate(
+      nIsolates, (i) => dart_isolate.ReceivePort());
+  debugger(); // LINE_B
+  for (int i = 0; i < nIsolates; i++) {
+    await dart_isolate.Isolate.spawn(foo, [rps[i].sendPort, i],
+        debugName: "foo$i");
+  }
+  print(await Future.wait(rps.map((rp) => rp.first)));
+  debugger(); // LINE_C
+}
+
+final completerAtFoo = List<Completer>.generate(nIsolates, (_) => Completer());
+int completerCount = 0;
+
+final tests = <IsolateTest>[
+  hasPausedAtStart,
+  resumeIsolate,
+  hasStoppedAtBreakpoint,
+  stoppedAtLine(LINE_B + 1),
+  (Isolate isolate) async {
+    // Set up a listener to wait for child isolate launch and breakpoint events.
+    final stream = await isolate.vm.getEventStream(VM.kDebugStream);
+    var subscription;
+    subscription = stream.listen((ServiceEvent event) async {
+      switch (event.kind) {
+        case ServiceEvent.kPauseStart:
+          final childIsolate = event.isolate;
+          await childIsolate.reload();
+
+          for (Library lib in childIsolate.libraries) {
+            await lib.load();
+            if (lib.uri
+                .endsWith('break_on_function_many_child_isolates_test.dart')) {
+              final foo = lib.functions.singleWhere((f) => f.name == 'foo');
+              final bpt = await childIsolate.addBreakpointAtEntry(foo);
+
+              expect(bpt is Breakpoint, isTrue);
+              break;
+            }
+          }
+          childIsolate.resume();
+          break;
+        case ServiceEvent.kPauseBreakpoint:
+          final name = event.isolate.name;
+          if (!name.startsWith('foo')) {
+            break;
+          }
+          final childIsolate = event.isolate;
+          final ndx = int.parse(name.substring('foo'.length));
+          final stack = await childIsolate.getStack();
+          final top = stack['frames'][0];
+          final script = await top.location.script.load() as Script;
+          expect(script.tokenToLine(top.location.tokenPos), equals(LINE_A));
+
+          childIsolate.resume();
+          if ((++completerCount) == nIsolates) {
+            subscription.cancel();
+          }
+          completerAtFoo[ndx].complete();
+          break;
+      }
+    });
+  },
+  resumeIsolate,
+  (Isolate isolate) async {
+    await Future.wait(completerAtFoo.map((c) => c.future));
+  },
+  hasStoppedAtBreakpoint,
+  stoppedAtLine(LINE_C + 1),
+  resumeIsolate,
+];
+
+Future runIsolateBreakpointPauseTest(args, nIsolates_) {
+  nIsolates = nIsolates_;
+  return runIsolateTests(args, tests,
+      testeeConcurrent: testMain, pause_on_start: true);
+}
+
+main(args) async {
+  await runIsolateBreakpointPauseTest(args, /*nIsolates=*/ 30);
+}
diff --git a/runtime/observatory_2/tests/service_2/capture_stdio_test.dart b/runtime/observatory_2/tests/service_2/capture_stdio_test.dart
index dc81e5a..ccbdbfd 100644
--- a/runtime/observatory_2/tests/service_2/capture_stdio_test.dart
+++ b/runtime/observatory_2/tests/service_2/capture_stdio_test.dart
@@ -28,6 +28,7 @@
     var stdoutSub;
     stdoutSub = await isolate.vm.listenEventStream(VM.kStdoutStream,
         (ServiceEvent event) {
+      expect(event.isolate != null, isTrue);
       expect(event.kind, equals('WriteEvent'));
       expect(event.bytesAsString, equals('stdout'));
       stdoutSub.cancel().then((_) {
@@ -44,6 +45,7 @@
     int eventNumber = 1;
     stdoutSub = await isolate.vm.listenEventStream(VM.kStdoutStream,
         (ServiceEvent event) {
+      expect(event.isolate != null, isTrue);
       expect(event.kind, equals('WriteEvent'));
       if (eventNumber == 1) {
         expect(event.bytesAsString, equals('print'));
@@ -66,6 +68,7 @@
     var stderrSub;
     stderrSub = await isolate.vm.listenEventStream(VM.kStderrStream,
         (ServiceEvent event) {
+      expect(event.isolate != null, isTrue);
       expect(event.kind, equals('WriteEvent'));
       expect(event.bytesAsString, equals('stderr'));
       stderrSub.cancel().then((_) {
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 43f02e5..56ccd2e 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
@@ -10,9 +10,9 @@
 class _TestClass {
   _TestClass();
   // Make sure these fields are not removed by the tree shaker.
-  @pragma("vm:entry-point")
+  @pragma("vm:entry-point") // Prevent obfuscation
   var x;
-  @pragma("vm:entry-point")
+  @pragma("vm:entry-point") // Prevent obfuscation
   var y;
 }
 
@@ -22,6 +22,7 @@
 var target4 = new _TestClass();
 var target5 = new _TestClass();
 var target6 = new _TestClass();
+@pragma("vm:entry-point") // Prevent obfuscation
 Expando<_TestClass> expando = Expando<_TestClass>();
 @pragma("vm:entry-point") // Prevent obfuscation
 var globalObject = new _TestClass();
@@ -40,45 +41,45 @@
   globalMap2[target5] = 'value';
 }
 
-@pragma("vm:entry-point")
+@pragma("vm:entry-point") // Prevent obfuscation
 getGlobalObject() => globalObject;
 
-@pragma("vm:entry-point")
+@pragma("vm:entry-point") // Prevent obfuscation
 takeTarget1() {
   var tmp = target1;
   target1 = null;
   return tmp;
 }
 
-@pragma("vm:entry-point")
+@pragma("vm:entry-point") // Prevent obfuscation
 takeTarget2() {
   var tmp = target2;
   target2 = null;
   return tmp;
 }
 
-@pragma("vm:entry-point")
+@pragma("vm:entry-point") // Prevent obfuscation
 takeTarget3() {
   var tmp = target3;
   target3 = null;
   return tmp;
 }
 
-@pragma("vm:entry-point")
+@pragma("vm:entry-point") // Prevent obfuscation
 takeTarget4() {
   var tmp = target4;
   target4 = null;
   return tmp;
 }
 
-@pragma("vm:entry-point")
+@pragma("vm:entry-point") // Prevent obfuscation
 takeTarget5() {
   var tmp = target5;
   target5 = null;
   return tmp;
 }
 
-@pragma("vm:entry-point")
+@pragma("vm:entry-point") // Prevent obfuscation
 takeExpandoTarget() {
   var tmp = target6;
   target6 = null;
@@ -87,7 +88,7 @@
   return tmp2;
 }
 
-@pragma("vm:entry-point")
+@pragma("vm:entry-point") // Prevent obfuscation
 getTrue() => true;
 
 invoke(Isolate isolate, String selector) async {
@@ -216,7 +217,6 @@
     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');
   },
 
diff --git a/runtime/observatory_2/tests/service_2/get_user_level_retaining_path_rpc_test.dart b/runtime/observatory_2/tests/service_2/get_user_level_retaining_path_rpc_test.dart
index 45c8941..e88a74c 100644
--- a/runtime/observatory_2/tests/service_2/get_user_level_retaining_path_rpc_test.dart
+++ b/runtime/observatory_2/tests/service_2/get_user_level_retaining_path_rpc_test.dart
@@ -13,13 +13,16 @@
   var y;
 }
 
+@pragma("vm:entry-point") // Prevent obfuscation
 class _TestConst {
   const _TestConst();
 }
 
 _TopLevelClosure() {}
 
+@pragma("vm:entry-point") // Prevent obfuscation
 var x;
+@pragma("vm:entry-point") // Prevent obfuscation
 var fn;
 
 void warmup() {
@@ -27,10 +30,10 @@
   fn = _TopLevelClosure;
 }
 
-@pragma("vm:entry-point")
+@pragma("vm:entry-point") // Prevent obfuscation
 getX() => x;
 
-@pragma("vm:entry-point")
+@pragma("vm:entry-point") // Prevent obfuscation
 getFn() => fn;
 
 invoke(Isolate isolate, String selector) async {
diff --git a/runtime/observatory_2/tests/service_2/get_version_rpc_test.dart b/runtime/observatory_2/tests/service_2/get_version_rpc_test.dart
index 9e2bc43..e7a9528 100644
--- a/runtime/observatory_2/tests/service_2/get_version_rpc_test.dart
+++ b/runtime/observatory_2/tests/service_2/get_version_rpc_test.dart
@@ -12,7 +12,7 @@
     var result = await vm.invokeRpcNoUpgrade('getVersion', {});
     expect(result['type'], equals('Version'));
     expect(result['major'], equals(3));
-    expect(result['minor'], equals(43));
+    expect(result['minor'], equals(44));
     expect(result['_privateMajor'], equals(0));
     expect(result['_privateMinor'], equals(0));
   },
diff --git a/runtime/observatory_2/tests/service_2/inbound_references_test.dart b/runtime/observatory_2/tests/service_2/inbound_references_test.dart
index 6053042..40601e2 100644
--- a/runtime/observatory_2/tests/service_2/inbound_references_test.dart
+++ b/runtime/observatory_2/tests/service_2/inbound_references_test.dart
@@ -8,14 +8,16 @@
 import 'package:test/test.dart';
 import 'test_helper.dart';
 
+@pragma("vm:entry-point") // Prevent obfuscation
 class Node {
   // Make sure this field is not removed by the tree shaker.
-  @pragma("vm:entry-point")
+  @pragma("vm:entry-point") // Prevent obfuscation
   var edge;
 }
 
 class Edge {}
 
+@pragma("vm:entry-point") // Prevent obfuscation
 var n, e, array;
 
 void script() {
diff --git a/runtime/observatory_2/tests/service_2/object_graph_identity_hash_test.dart b/runtime/observatory_2/tests/service_2/object_graph_identity_hash_test.dart
index ed5c71b..3ab0ae1 100644
--- a/runtime/observatory_2/tests/service_2/object_graph_identity_hash_test.dart
+++ b/runtime/observatory_2/tests/service_2/object_graph_identity_hash_test.dart
@@ -8,40 +8,42 @@
 import 'service_test_common.dart';
 import 'test_helper.dart';
 
+@pragma("vm:entry-point") // Prevent obfuscation
 class Foo {}
 
+@pragma("vm:entry-point") // Prevent obfuscation
 class Bar {}
 
 class Container1 {
-  @pragma("vm:entry-point")
+  @pragma("vm:entry-point") // Prevent obfuscation
   Foo foo = Foo();
-  @pragma("vm:entry-point")
+  @pragma("vm:entry-point") // Prevent obfuscation
   Bar bar = Bar();
 }
 
 class Container2 {
   Container2(this.foo);
 
-  @pragma("vm:entry-point")
+  @pragma("vm:entry-point") // Prevent obfuscation
   Foo foo;
-  @pragma("vm:entry-point")
+  @pragma("vm:entry-point") // Prevent obfuscation
   Bar bar = Bar();
 }
 
 class Container3 {
-  @pragma("vm:entry-point")
+  @pragma("vm:entry-point") // Prevent obfuscation
   int number = 42;
-  @pragma("vm:entry-point")
+  @pragma("vm:entry-point") // Prevent obfuscation
   double doub = 3.14;
-  @pragma("vm:entry-point")
+  @pragma("vm:entry-point") // Prevent obfuscation
   String foo = 'foobar';
-  @pragma("vm:entry-point")
+  @pragma("vm:entry-point") // Prevent obfuscation
   bool bar = false;
-  @pragma("vm:entry-point")
+  @pragma("vm:entry-point") // Prevent obfuscation
   Map baz;
-  @pragma("vm:entry-point")
+  @pragma("vm:entry-point") // Prevent obfuscation
   List list;
-  @pragma("vm:entry-point")
+  @pragma("vm:entry-point") // Prevent obfuscation
   List unmodifiableList;
 
   Container3() {
@@ -53,11 +55,11 @@
   }
 }
 
-@pragma("vm:entry-point")
+@pragma("vm:entry-point") // Prevent obfuscation
 Container1 c1;
-@pragma("vm:entry-point")
+@pragma("vm:entry-point") // Prevent obfuscation
 Container2 c2;
-@pragma("vm:entry-point")
+@pragma("vm:entry-point") // Prevent obfuscation
 Container3 c3;
 
 void script() {
diff --git a/runtime/observatory_2/tests/service_2/reachable_size_test.dart b/runtime/observatory_2/tests/service_2/reachable_size_test.dart
index f92962d..5073e9c 100644
--- a/runtime/observatory_2/tests/service_2/reachable_size_test.dart
+++ b/runtime/observatory_2/tests/service_2/reachable_size_test.dart
@@ -10,13 +10,15 @@
 
 class Pair {
   // Make sure these fields are not removed by the tree shaker.
-  @pragma("vm:entry-point")
+  @pragma("vm:entry-point") // Prevent obfuscation
   var x;
-  @pragma("vm:entry-point")
+  @pragma("vm:entry-point") // Prevent obfuscation
   var y;
 }
 
+@pragma("vm:entry-point") // Prevent obfuscation
 var p1;
+@pragma("vm:entry-point") // Prevent obfuscation
 var p2;
 
 buildGraph() {
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 f352aa6..099e686 100644
--- a/runtime/observatory_2/tests/service_2/service_2_kernel.status
+++ b/runtime/observatory_2/tests/service_2/service_2_kernel.status
@@ -31,6 +31,7 @@
 pause_on_exceptions_test: SkipByDesign # No incremental compiler available.
 rewind_optimized_out_test: SkipByDesign # No incremental compiler available.
 rewind_test: SkipByDesign # No incremental compiler available.
+sigquit_starts_service_test: SkipByDesign # Spawns a secondary process using Platform.executable.
 
 [ $compiler == dartk ]
 bad_reload_test: RuntimeError # Issue 34025
@@ -38,6 +39,7 @@
 evaluate_activation_test/instance: RuntimeError # http://dartbug.com/20047
 evaluate_activation_test/scope: RuntimeError # http://dartbug.com/20047
 get_source_report_test: RuntimeError # Should pass again when constant evaluation is relanded, see http://dartbug.com/36600
+pause_on_exception_from_slow_path_test: Pass, Slow
 pause_on_unhandled_async_exceptions2_test: Pass, Slow
 
 [ $compiler == dartkp ]
@@ -58,6 +60,8 @@
 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_child_isolate_test: SkipByDesign # Debugger is disabled in AOT mode.
+break_on_function_many_child_isolates_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.
@@ -171,6 +175,7 @@
 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.
+sigquit_starts_service_test: SkipByDesign # Spawns a secondary process using Platform.executable.
 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.
@@ -297,6 +302,7 @@
 rewind_optimized_out_test: RuntimeError # Issue #34736
 rewind_test: Pass, RuntimeError
 set_name_rpc_test: RuntimeError # Please triage.
+sigquit_starts_service_test: SkipByDesign # Spawns a secondary process using Platform.executable.
 simple_reload_test: RuntimeError, Timeout
 valid_source_locations_test: Skip # Issue 34736, too slow.
 
diff --git a/runtime/observatory_2/tests/service_2/sigquit_starts_service_script.dart b/runtime/observatory_2/tests/service_2/sigquit_starts_service_script.dart
new file mode 100644
index 0000000..e5f24e8
--- /dev/null
+++ b/runtime/observatory_2/tests/service_2/sigquit_starts_service_script.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+Future<void> main() async {
+  print('ready');
+  while (true) {
+    await Future.delayed(const Duration(seconds: 1));
+  }
+}
diff --git a/runtime/observatory_2/tests/service_2/sigquit_starts_service_test.dart b/runtime/observatory_2/tests/service_2/sigquit_starts_service_test.dart
new file mode 100644
index 0000000..b056477
--- /dev/null
+++ b/runtime/observatory_2/tests/service_2/sigquit_starts_service_test.dart
@@ -0,0 +1,43 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:convert';
+import 'dart:io';
+
+import 'package:test/test.dart';
+
+void runTest(bool withDartDev) {
+  test(
+      'Displays service URI on SIGQUIT ${withDartDev ? '' : 'with --disable-dart-dev'}',
+      () async {
+    final process = await Process.start(Platform.resolvedExecutable, [
+      if (!withDartDev) '--disable-dart-dev',
+      Platform.script.resolve('sigquit_starts_service_script.dart').toString(),
+    ]);
+
+    final readyCompleter = Completer<void>();
+    final completer = Completer<void>();
+    StreamSubscription sub;
+    sub = process.stdout.transform(utf8.decoder).listen((e) async {
+      if (e.contains('ready') && !readyCompleter.isCompleted) {
+        readyCompleter.complete();
+      } else if (e.contains('Observatory listening on')) {
+        await sub.cancel();
+        completer.complete();
+      }
+    });
+
+    // Wait for the process to start.
+    await readyCompleter.future;
+    process.kill(ProcessSignal.sigquit);
+    await completer.future;
+    process.kill();
+  }, skip: Platform.isWindows);
+}
+
+void main() {
+  runTest(true);
+  runTest(false);
+}
diff --git a/runtime/observatory_2/tests/service_2/string_escaping_test.dart b/runtime/observatory_2/tests/service_2/string_escaping_test.dart
index 6a9c829..4d48a3f 100644
--- a/runtime/observatory_2/tests/service_2/string_escaping_test.dart
+++ b/runtime/observatory_2/tests/service_2/string_escaping_test.dart
@@ -9,20 +9,35 @@
 import 'package:test/test.dart';
 import 'test_helper.dart';
 
+@pragma("vm:entry-point") // Prevent obfuscation
 var ascii;
+@pragma("vm:entry-point") // Prevent obfuscation
 var latin1;
+@pragma("vm:entry-point") // Prevent obfuscation
 var unicode;
+@pragma("vm:entry-point") // Prevent obfuscation
 var hebrew;
+@pragma("vm:entry-point") // Prevent obfuscation
 var singleQuotes;
+@pragma("vm:entry-point") // Prevent obfuscation
 var doubleQuotes;
+@pragma("vm:entry-point") // Prevent obfuscation
 var newLines;
+@pragma("vm:entry-point") // Prevent obfuscation
 var tabs;
+@pragma("vm:entry-point") // Prevent obfuscation
 var suggrogatePairs;
+@pragma("vm:entry-point") // Prevent obfuscation
 var nullInTheMiddle;
+@pragma("vm:entry-point") // Prevent obfuscation
 var escapedUnicodeEscape;
+@pragma("vm:entry-point") // Prevent obfuscation
 var longStringEven;
+@pragma("vm:entry-point") // Prevent obfuscation
 var longStringOdd;
+@pragma("vm:entry-point") // Prevent obfuscation
 var malformedWithLeadSurrogate;
+@pragma("vm:entry-point") // Prevent obfuscation
 var malformedWithTrailSurrogate;
 
 void script() {
diff --git a/runtime/observatory_2/tests/service_2/typed_data_test.dart b/runtime/observatory_2/tests/service_2/typed_data_test.dart
index 3de01a8..e6ae724 100644
--- a/runtime/observatory_2/tests/service_2/typed_data_test.dart
+++ b/runtime/observatory_2/tests/service_2/typed_data_test.dart
@@ -9,25 +9,42 @@
 import 'package:test/test.dart';
 import 'test_helper.dart';
 
+@pragma("vm:entry-point") // Prevent obfuscation
 var int8List;
+@pragma("vm:entry-point") // Prevent obfuscation
 var int16List;
+@pragma("vm:entry-point") // Prevent obfuscation
 var int32List;
+@pragma("vm:entry-point") // Prevent obfuscation
 var int64List;
 
+@pragma("vm:entry-point") // Prevent obfuscation
 var uint8List;
+@pragma("vm:entry-point") // Prevent obfuscation
 var uint16List;
+@pragma("vm:entry-point") // Prevent obfuscation
 var uint32List;
+@pragma("vm:entry-point") // Prevent obfuscation
 var uint64List;
+@pragma("vm:entry-point") // Prevent obfuscation
 var uint8ClampedList;
 
+@pragma("vm:entry-point") // Prevent obfuscation
 var float32List;
+@pragma("vm:entry-point") // Prevent obfuscation
 var float64List;
 
+@pragma("vm:entry-point") // Prevent obfuscation
 var int32x4;
+@pragma("vm:entry-point") // Prevent obfuscation
 var float32x4;
+@pragma("vm:entry-point") // Prevent obfuscation
 var float64x2;
+@pragma("vm:entry-point") // Prevent obfuscation
 var int32x4List;
+@pragma("vm:entry-point") // Prevent obfuscation
 var float32x4List;
+@pragma("vm:entry-point") // Prevent obfuscation
 var float64x2List;
 
 void script() {
diff --git a/runtime/platform/BUILD.gn b/runtime/platform/BUILD.gn
index c727eea..f339a1e 100644
--- a/runtime/platform/BUILD.gn
+++ b/runtime/platform/BUILD.gn
@@ -18,11 +18,20 @@
 
   if (is_fuchsia) {
     if (using_fuchsia_gn_sdk) {
-      extra_deps += [ "$fuchsia_sdk_root/pkg/sys_cpp" ]
+      extra_deps += [
+        "$fuchsia_sdk_root/pkg/sys_cpp",
+        "$fuchsia_sdk_root/pkg/sys_inspect_cpp",
+      ]
     } else if (using_fuchsia_sdk) {
-      extra_deps += [ "$fuchsia_sdk_root/pkg:sys_cpp" ]
+      extra_deps += [
+        "$fuchsia_sdk_root/pkg:sys_cpp",
+        "$fuchsia_sdk_root/pkg:sys_inspect_cpp",
+      ]
     } else {
-      extra_deps += [ "//sdk/lib/sys/cpp" ]
+      extra_deps += [
+        "//sdk/lib/sys/cpp",
+        "//sdk/lib/sys/inspect/cpp",
+      ]
     }
   }
 }
diff --git a/runtime/platform/assert.cc b/runtime/platform/assert.cc
index b1dbd65..85e4ea2 100644
--- a/runtime/platform/assert.cc
+++ b/runtime/platform/assert.cc
@@ -8,11 +8,17 @@
 #include "platform/globals.h"
 #include "platform/syslog.h"
 
+#if defined(HOST_OS_ANDROID)
+extern "C" __attribute__((weak)) void android_set_abort_message(const char*);
+#endif  // defined(HOST_OS_ANDROID)
+
 namespace dart {
 
 bool Expect::failed_ = false;
 
-void DynamicAssertionHelper::Print(const char* format, va_list arguments) {
+void DynamicAssertionHelper::Print(const char* format,
+                                   va_list arguments,
+                                   bool will_abort /* = false */) {
   // Take only the last 1KB of the file name if it is longer.
   const intptr_t file_len = strlen(file_);
   const intptr_t file_offset = (file_len > (1 * KB)) ? file_len - (1 * KB) : 0;
@@ -30,12 +36,17 @@
 
   // Print the buffer on stderr and/or syslog.
   Syslog::PrintErr("%s\n", buffer);
+#if defined(HOST_OS_ANDROID)
+  if (will_abort && (&android_set_abort_message != nullptr)) {
+    android_set_abort_message(buffer);
+  }
+#endif  // defined(HOST_OS_ANDROID)
 }
 
 void Assert::Fail(const char* format, ...) {
   va_list arguments;
   va_start(arguments, format);
-  Print(format, arguments);
+  Print(format, arguments, /*will_abort=*/true);
   va_end(arguments);
 
   // Abort right away.
diff --git a/runtime/platform/assert.h b/runtime/platform/assert.h
index 64351b6..c4155d0 100644
--- a/runtime/platform/assert.h
+++ b/runtime/platform/assert.h
@@ -30,7 +30,7 @@
       : file_(file), line_(line) {}
 
  protected:
-  void Print(const char* format, va_list arguments);
+  void Print(const char* format, va_list arguments, bool will_abort = false);
 
   const char* const file_;
   const int line_;
diff --git a/runtime/platform/globals.h b/runtime/platform/globals.h
index 407304e..52201dc 100644
--- a/runtime/platform/globals.h
+++ b/runtime/platform/globals.h
@@ -20,7 +20,13 @@
 // from the way the Dart project expects it: DEBUG indicating a debug build.
 #if !defined(NDEBUG) && !defined(DEBUG)
 #define DEBUG
-#endif  // !NDEBUG && !DEBUG
+#endif  // !NDEBUG && !DEBUG                                                   \
+#else
+// Since <cassert> uses NDEBUG to signify that assert() macros should be turned
+// off, we'll define it when DEBUG is _not_ set.
+#if !defined(DEBUG)
+#define NDEBUG
+#endif
 #endif  // GOOGLE3
 
 // __STDC_FORMAT_MACROS has to be defined before including <inttypes.h> to
@@ -85,6 +91,8 @@
 #include <string.h>
 #include <sys/types.h>
 
+#include <cassert>  // For assert() in constant expressions.
+
 #if defined(_WIN32)
 #include "platform/floating_point_win.h"
 #endif  // defined(_WIN32)
@@ -136,12 +144,6 @@
 #define DEBUG_ONLY(code)
 #endif  // defined(DEBUG)
 
-#if defined(DEBUG)
-#define UNLESS_DEBUG(code)
-#else  // defined(DEBUG)
-#define UNLESS_DEBUG(code) code
-#endif  // defined(DEBUG)
-
 namespace dart {
 
 struct simd128_value_t {
diff --git a/runtime/platform/utils.cc b/runtime/platform/utils.cc
index dc10160..0799742 100644
--- a/runtime/platform/utils.cc
+++ b/runtime/platform/utils.cc
@@ -5,6 +5,7 @@
 #include "platform/utils.h"
 
 #include "platform/allocation.h"
+#include "platform/globals.h"
 
 namespace dart {
 
@@ -212,31 +213,103 @@
   *shift = p - 64;
 }
 
+// This implementation is based on the public domain MurmurHash
+// version 2.0. The constants M and R have been determined
+// to work well experimentally.
+static constexpr uint32_t kStringHashM = 0x5bd1e995;
+static constexpr int kStringHashR = 24;
+
+// hash and part must be lvalues.
+#define MIX(hash, part)                                                        \
+  {                                                                            \
+    (part) *= kStringHashM;                                                    \
+    (part) ^= (part) >> kStringHashR;                                          \
+    (part) *= kStringHashM;                                                    \
+    (hash) *= kStringHashM;                                                    \
+    (hash) ^= (part);                                                          \
+  }
+
 uint32_t Utils::StringHash(const char* data, int length) {
-  // This implementation is based on the public domain MurmurHash
-  // version 2.0. It assumes that the underlying CPU can read from
-  // unaligned addresses. The constants M and R have been determined
-  // to work well experimentally.
-  // TODO(3158902): need to account for unaligned address access on ARM.
-  const uint32_t M = 0x5bd1e995;
-  const int R = 24;
   int size = length;
   uint32_t hash = size;
 
-  // Mix four bytes at a time into the hash.
-  const uint8_t* cursor = reinterpret_cast<const uint8_t*>(data);
-  while (size >= 4) {
-    uint32_t part = *reinterpret_cast<const uint32_t*>(cursor);
-    part *= M;
-    part ^= part >> R;
-    part *= M;
-    hash *= M;
-    hash ^= part;
-    cursor += 4;
-    size -= 4;
+  auto cursor = reinterpret_cast<const uint8_t*>(data);
+
+  if (size >= kInt32Size) {
+    const intptr_t misalignment =
+        reinterpret_cast<intptr_t>(cursor) % kInt32Size;
+    if (misalignment > 0) {
+      // Stores 4-byte values starting from the start of the string to mimic
+      // the algorithm on aligned data.
+      uint32_t data_window = 0;
+
+      // Shift sizes for adjusting the data window when adding the next aligned
+      // piece of data.
+      const uint32_t sr = misalignment * kBitsPerByte;
+      const uint32_t sl = kBitsPerInt32 - sr;
+
+      const intptr_t pre_alignment_length = kInt32Size - misalignment;
+      switch (pre_alignment_length) {
+        case 3:
+          data_window |= cursor[2] << 16;
+          FALL_THROUGH;
+        case 2:
+          data_window |= cursor[1] << 8;
+          FALL_THROUGH;
+        case 1:
+          data_window |= cursor[0];
+      }
+      cursor += pre_alignment_length;
+      size -= pre_alignment_length;
+
+      // Mix four bytes at a time now that we're at an aligned spot.
+      for (; size >= kInt32Size; cursor += kInt32Size, size -= kInt32Size) {
+        uint32_t aligned_part = *reinterpret_cast<const uint32_t*>(cursor);
+        data_window |= (aligned_part << sl);
+        MIX(hash, data_window);
+        data_window = aligned_part >> sr;
+      }
+
+      if (size >= misalignment) {
+        // There's one more full window in the data. We'll let the normal tail
+        // code handle any partial window.
+        switch (misalignment) {
+          case 3:
+            data_window |= cursor[2] << (16 + sl);
+            FALL_THROUGH;
+          case 2:
+            data_window |= cursor[1] << (8 + sl);
+            FALL_THROUGH;
+          case 1:
+            data_window |= cursor[0] << sl;
+        }
+        MIX(hash, data_window);
+        cursor += misalignment;
+        size -= misalignment;
+      } else {
+        // This is a partial window, so just xor and multiply by M.
+        switch (size) {
+          case 2:
+            data_window |= cursor[1] << (8 + sl);
+            FALL_THROUGH;
+          case 1:
+            data_window |= cursor[0] << sl;
+        }
+        hash ^= data_window;
+        hash *= kStringHashM;
+        cursor += size;
+        size = 0;
+      }
+    } else {
+      // Mix four bytes at a time into the hash.
+      for (; size >= kInt32Size; size -= kInt32Size, cursor += kInt32Size) {
+        uint32_t part = *reinterpret_cast<const uint32_t*>(cursor);
+        MIX(hash, part);
+      }
+    }
   }
 
-  // Handle the last few bytes of the string.
+  // Handle the last few bytes of the string if any.
   switch (size) {
     case 3:
       hash ^= cursor[2] << 16;
@@ -246,17 +319,19 @@
       FALL_THROUGH;
     case 1:
       hash ^= cursor[0];
-      hash *= M;
+      hash *= kStringHashM;
   }
 
   // Do a few final mixes of the hash to ensure the last few bytes are
   // well-incorporated.
   hash ^= hash >> 13;
-  hash *= M;
+  hash *= kStringHashM;
   hash ^= hash >> 15;
   return hash;
 }
 
+#undef MIX
+
 uint32_t Utils::WordHash(intptr_t key) {
   // TODO(iposva): Need to check hash spreading.
   // This example is from http://www.concentric.net/~Ttwang/tech/inthash.htm
diff --git a/runtime/platform/utils.h b/runtime/platform/utils.h
index eecab24..a381505 100644
--- a/runtime/platform/utils.h
+++ b/runtime/platform/utils.h
@@ -57,7 +57,7 @@
   }
 
   template <typename T>
-  static inline bool IsPowerOfTwo(T x) {
+  static constexpr bool IsPowerOfTwo(T x) {
     return ((x & (x - 1)) == 0) && (x != 0);
   }
 
@@ -73,13 +73,13 @@
   }
 
   template <typename T>
-  static inline bool IsAligned(T x, intptr_t n) {
-    ASSERT(IsPowerOfTwo(n));
+  static constexpr bool IsAligned(T x, intptr_t n) {
+    assert(IsPowerOfTwo(n));
     return (x & (n - 1)) == 0;
   }
 
   template <typename T>
-  static inline bool IsAligned(T* x, intptr_t n) {
+  static constexpr bool IsAligned(T* x, intptr_t n) {
     return IsAligned(reinterpret_cast<uword>(x), n);
   }
 
@@ -292,6 +292,13 @@
     return static_cast<T>(static_cast<Unsigned>(a) * static_cast<Unsigned>(b));
   }
 
+  template <typename T = int64_t>
+  static inline T NegWithWrapAround(T a) {
+    // Avoid undefined behavior by doing arithmetic in the unsigned type.
+    using Unsigned = typename std::make_unsigned<T>::type;
+    return static_cast<T>(-static_cast<Unsigned>(a));
+  }
+
   // Shifts int64_t value left. Supports any non-negative number of bits and
   // silently discards shifted out bits.
   static inline int64_t ShiftLeftWithTruncation(int64_t a, int64_t b) {
diff --git a/runtime/platform/utils_fuchsia.cc b/runtime/platform/utils_fuchsia.cc
index cfa17e6..a6d9f37 100644
--- a/runtime/platform/utils_fuchsia.cc
+++ b/runtime/platform/utils_fuchsia.cc
@@ -6,8 +6,10 @@
 #if defined(HOST_OS_FUCHSIA)
 
 #include <memory>
+#include <utility>
 
 #include "lib/sys/cpp/component_context.h"
+#include "lib/sys/inspect/cpp/component.h"
 #include "platform/utils.h"
 #include "platform/utils_fuchsia.h"
 
@@ -57,6 +59,23 @@
   return context.get();
 }
 
+std::unique_ptr<inspect::Node> vm_node;
+void SetDartVmNode(std::unique_ptr<inspect::Node> node) {
+  vm_node = std::move(node);
+}
+
+std::unique_ptr<inspect::Node> TakeDartVmNode() {
+  // TODO(fxbug.dev/69558) Remove the creation of the node_ from this call
+  // after the runners have been migrated to injecting this object.
+  if (vm_node == nullptr) {
+    static std::unique_ptr<sys::ComponentInspector> component_inspector =
+        std::make_unique<sys::ComponentInspector>(dart::ComponentContext());
+    inspect::Node& root = component_inspector->inspector()->GetRoot();
+    vm_node = std::make_unique<inspect::Node>(root.CreateChild("vm"));
+  }
+  return std::move(vm_node);
+}
+
 }  // namespace dart
 
 #endif  // defined(HOST_OS_FUCHSIA)
diff --git a/runtime/platform/utils_fuchsia.h b/runtime/platform/utils_fuchsia.h
index 4b2064e..b88328a 100644
--- a/runtime/platform/utils_fuchsia.h
+++ b/runtime/platform/utils_fuchsia.h
@@ -6,6 +6,7 @@
 #define RUNTIME_PLATFORM_UTILS_FUCHSIA_H_
 
 #include <endian.h>
+#include <memory>
 
 namespace sys {
 
@@ -14,6 +15,13 @@
 
 }  // namespace sys
 
+namespace inspect {
+
+// From Fuchsia SDK.
+class Node;
+
+}  // namespace inspect
+
 namespace dart {
 
 inline uint16_t Utils::HostToBigEndian16(uint16_t value) {
@@ -57,6 +65,18 @@
 // call sys::ComponentContext::Create().
 sys::ComponentContext* ComponentContext();
 
+// Sets the inspect node set to be used in the dart vm
+//
+// This method will take ownership of the node
+void SetDartVmNode(std::unique_ptr<inspect::Node> node);
+
+// Returns the inspect node set in SetDartVmNode().
+//
+// The caller should take ownership of the returned node because
+// the value will be set to null after this call.
+// This call may return null if no node is provided.
+std::unique_ptr<inspect::Node> TakeDartVmNode();
+
 }  // namespace dart
 
 #endif  // RUNTIME_PLATFORM_UTILS_FUCHSIA_H_
diff --git a/runtime/runtime_args.gni b/runtime/runtime_args.gni
index 7e4e9b4..ae564be 100644
--- a/runtime/runtime_args.gni
+++ b/runtime/runtime_args.gni
@@ -75,9 +75,6 @@
   # Whether libdart should export the symbols of the Dart API.
   dart_lib_export_symbols = true
 
-  # Whether package:wasm should be enabled.
-  dart_enable_wasm = false
-
   # Whether to use compressed pointers.
   dart_use_compressed_pointers = false
 }
diff --git a/runtime/tests/vm/dart/base_il_serialization_test.dart b/runtime/tests/vm/dart/base_il_serialization_test.dart
deleted file mode 100644
index 569b661..0000000
--- a/runtime/tests/vm/dart/base_il_serialization_test.dart
+++ /dev/null
@@ -1,16 +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=--serialize_flow_graphs_to=il_tmp.txt
-// VMOptions=--serialize_flow_graphs_to=il_tmp.txt --populate_llvm_constant_pool
-// VMOptions=--serialize_flow_graphs_to=il_tmp.txt --no_serialize_flow_graph_types
-// VMOptions=--serialize_flow_graphs_to=il_tmp.txt --verbose_flow_graph_serialization
-// VMOptions=--serialize_flow_graphs_to=il_tmp.txt --no_serialize_flow_graph_types --verbose_flow_graph_serialization
-
-// Just use the existing hello world test.
-import 'hello_world_test.dart' as test;
-
-main(args) {
-  test.main();
-}
diff --git a/runtime/tests/vm/dart/deopt/allocate_array_test.dart b/runtime/tests/vm/dart/deopt/allocate_array_test.dart
new file mode 100644
index 0000000..eb06336
--- /dev/null
+++ b/runtime/tests/vm/dart/deopt/allocate_array_test.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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=--disable-dart-dev --no-inline-alloc --use-slow-path --deoptimize-on-runtime-call-every=1 --deterministic --optimization-counter-threshold=1 --deoptimize-on-runtime-call-name-filter=AllocateArray
+
+main() {
+  for (int i = 0; i < 20; ++i) {
+    final list = foo(1);
+    if (list[0] != 42) throw 'a';
+  }
+}
+
+@pragma('vm:never-inline')
+List foo(int a) {
+  return List<dynamic>.filled(a, null)..[0] = 42;
+}
diff --git a/runtime/tests/vm/dart/deopt/allocate_context_test.dart b/runtime/tests/vm/dart/deopt/allocate_context_test.dart
new file mode 100644
index 0000000..c52abc0
--- /dev/null
+++ b/runtime/tests/vm/dart/deopt/allocate_context_test.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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=--disable-dart-dev --no-inline-alloc --use-slow-path --deoptimize-on-runtime-call-every=1 --deterministic --optimization-counter-threshold=1 --deoptimize-on-runtime-call-name-filter=AllocateContext
+
+main() {
+  for (int i = 0; i < 20; ++i) {
+    final fun = foo(1);
+    if (fun(1) != 3) throw 'a';
+    if (fun(2) != 6) throw 'b';
+  }
+}
+
+@pragma('vm:never-inline')
+int Function(int) foo(int a) {
+  int b = 1;
+  return (int c) {
+    return a++ + b++ + c;
+  };
+}
diff --git a/runtime/tests/vm/dart/deopt/allocate_object_test.dart b/runtime/tests/vm/dart/deopt/allocate_object_test.dart
new file mode 100644
index 0000000..efcd883
--- /dev/null
+++ b/runtime/tests/vm/dart/deopt/allocate_object_test.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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=--disable-dart-dev --no-inline-alloc --use-slow-path --deoptimize-on-runtime-call-every=1 --deterministic --optimization-counter-threshold=1 --deoptimize-on-runtime-call-name-filter=AllocateObject
+
+main() {
+  for (int i = 0; i < 20; ++i) {
+    final foo = bar(1);
+    if (foo.fun(1) != 3) throw 'a';
+    if (foo.fun(2) != 6) throw 'b';
+  }
+}
+
+@pragma('vm:never-inline')
+Foo bar(int a) {
+  int b = 1;
+  return Foo(a, (int c) {
+    return a++ + b++ + c++;
+  });
+}
+
+class Foo {
+  final int value;
+  final int Function(int) fun;
+  Foo(this.value, this.fun);
+}
diff --git a/runtime/tests/vm/dart/deopt/allocate_typed_data_test.dart b/runtime/tests/vm/dart/deopt/allocate_typed_data_test.dart
new file mode 100644
index 0000000..6556661
--- /dev/null
+++ b/runtime/tests/vm/dart/deopt/allocate_typed_data_test.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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=--disable-dart-dev --no-inline-alloc --use-slow-path --deoptimize-on-runtime-call-every=1 --deterministic --optimization-counter-threshold=1 --deoptimize-on-runtime-call-name-filter=AllocateTypedData
+
+import 'dart:typed_data';
+
+main() {
+  for (int i = 0; i < 20; ++i) {
+    final foo = bar(1);
+    if (foo[0] != 42) throw 'a';
+  }
+}
+
+@pragma('vm:never-inline')
+Uint32List bar(int a) {
+  return Uint32List(1)..[0] = 42;
+}
diff --git a/runtime/tests/vm/dart/deopt/assert_subtype_test.dart b/runtime/tests/vm/dart/deopt/assert_subtype_test.dart
new file mode 100644
index 0000000..964aa7d
--- /dev/null
+++ b/runtime/tests/vm/dart/deopt/assert_subtype_test.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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=--disable-dart-dev --deoptimize-on-runtime-call-every=1 --deterministic --optimization-counter-threshold=1 --deoptimize-on-runtime-call-name-filter=SubtypeCheck
+
+main() {
+  for (int i = 0; i < 20; ++i) {
+    if (foo()<int>() != 42) throw 'a';
+    if (foo()<double>() != 42) throw 'a';
+  }
+}
+
+@pragma('vm:never-inline')
+dynamic foo() {
+  int bar<T extends num>() => 42;
+  return bar;
+}
diff --git a/runtime/tests/vm/dart/deopt/clone_context_test.dart b/runtime/tests/vm/dart/deopt/clone_context_test.dart
new file mode 100644
index 0000000..5320404
--- /dev/null
+++ b/runtime/tests/vm/dart/deopt/clone_context_test.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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=--disable-dart-dev --no-inline-alloc --use-slow-path --deoptimize-on-runtime-call-every=1 --deterministic --optimization-counter-threshold=1 --deoptimize-on-runtime-call-name-filter=CloneContext
+
+main() {
+  for (int i = 0; i < 20; ++i) {
+    if (foo(1)[1]() != 2) throw 'a';
+  }
+}
+
+@pragma('vm:never-inline')
+List foo(int a) {
+  final l = <int Function()>[];
+  for (int i = 0; i < 10; ++i) {
+    l.add(() => a + i);
+  }
+  return l;
+}
diff --git a/runtime/tests/vm/dart/deopt/instantiate_type_arguments_test.dart b/runtime/tests/vm/dart/deopt/instantiate_type_arguments_test.dart
new file mode 100644
index 0000000..4426064
--- /dev/null
+++ b/runtime/tests/vm/dart/deopt/instantiate_type_arguments_test.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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=--disable-dart-dev --deoptimize-on-runtime-call-every=1 --deterministic --optimization-counter-threshold=1 --deoptimize-on-runtime-call-name-filter=InstantiateTypeArguments
+
+main() {
+  final a = A<int>();
+  for (int i = 0; i < 20; ++i) {
+    final m = a.foo<double>();
+    if (m is! Map<int, double>) throw 'a';
+  }
+}
+
+class A<T> {
+  @pragma('vm:never-inline')
+  Map foo<H>() => <T, H>{};
+}
diff --git a/runtime/tests/vm/dart/deopt/instantiate_type_test.dart b/runtime/tests/vm/dart/deopt/instantiate_type_test.dart
new file mode 100644
index 0000000..2ae579e
--- /dev/null
+++ b/runtime/tests/vm/dart/deopt/instantiate_type_test.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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=--disable-dart-dev --deoptimize-on-runtime-call-every=1 --deterministic --optimization-counter-threshold=1 --deoptimize-on-runtime-call-name-filter=InstantiateType
+
+main() {
+  final a = A<int>();
+  for (int i = 0; i < 20; ++i) {
+    final l = a.foo<double>();
+    if (l[0] != int) throw 'a';
+    if (l[1] != double) throw 'a';
+  }
+}
+
+class A<T> {
+  @pragma('vm:never-inline')
+  List<Type> foo<H>() {
+    final l = <Type>[];
+    for (int i = 0; i < 10; ++i) {
+      l.add(T);
+      l.add(H);
+    }
+    return l;
+  }
+}
diff --git a/runtime/tests/vm/dart/isolate_send_regex_test.dart b/runtime/tests/vm/dart/isolate_send_regex_test.dart
new file mode 100644
index 0000000..cac6d09
--- /dev/null
+++ b/runtime/tests/vm/dart/isolate_send_regex_test.dart
@@ -0,0 +1,38 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+import 'dart:isolate';
+
+import 'package:expect/expect.dart';
+
+f(List args) {
+  final sendPort = args[0] as SendPort;
+  final re = args[1] as RegExp;
+  Expect.stringEquals("RegExp: pattern=abc flags=", re.toString());
+  sendPort.send(true);
+}
+
+main() async {
+  final rpError = RawReceivePort((e) {
+    Expect.fail('Spawned isolated failed with $e');
+  });
+  {
+    // Test sending of initialized RegExp
+    final rp = ReceivePort();
+    final re = RegExp('abc');
+    print(re.hasMatch('kukabcdef'));
+    await Isolate.spawn(f, <dynamic>[rp.sendPort, re],
+        onError: rpError.sendPort);
+    Expect.isTrue(await rp.first);
+  }
+  {
+    // Test send of uninitialized RegExp(num_groups is null)
+    final rp = ReceivePort();
+    final re = RegExp('abc');
+    await Isolate.spawn(f, <dynamic>[rp.sendPort, re],
+        onError: rpError.sendPort);
+    Expect.isTrue(await rp.first);
+  }
+  rpError.close();
+}
diff --git a/runtime/tests/vm/dart/regress_38661_test.dart b/runtime/tests/vm/dart/regress_38661_test.dart
deleted file mode 100644
index 2e1ba13..0000000
--- a/runtime/tests/vm/dart/regress_38661_test.dart
+++ /dev/null
@@ -1,27 +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=--serialize_flow_graphs_to=il_tmp.txt
-// VMOptions=--serialize_flow_graphs_to=il_tmp.txt --populate_llvm_constant_pool
-// VMOptions=--serialize_flow_graphs_to=il_tmp.txt --no_serialize_flow_graph_types
-// VMOptions=--serialize_flow_graphs_to=il_tmp.txt --verbose_flow_graph_serialization
-// VMOptions=--serialize_flow_graphs_to=il_tmp.txt --no_serialize_flow_graph_types --verbose_flow_graph_serialization
-
-class A {
-  const A();
-}
-
-class B {
-  Object a = const A();
-}
-
-foo(int i) {
-  if (i == 3) {
-    new B();
-  }
-}
-
-main(args) {
-  foo(4);
-}
diff --git a/runtime/tests/vm/dart/regress_45207_test.dart b/runtime/tests/vm/dart/regress_45207_test.dart
new file mode 100644
index 0000000..9f01648
--- /dev/null
+++ b/runtime/tests/vm/dart/regress_45207_test.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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 --deoptimize-on-runtime-call-name-filter=TypeCheck --deoptimize-on-runtime-call-every=1 --max-subtype-cache-entries=0
+
+main() {
+  void nop() {}
+  for (int i = 0; i < 1000; ++i) {
+    if (assertAssignable(nop) != 1) {
+      throw 'broken';
+    }
+  }
+}
+
+@pragma('vm:never-inline')
+int assertAssignable(dynamic a0) {
+  return ensureValidExpressionStack(1, a0 as void Function());
+}
+
+@pragma('vm:never-inline')
+int ensureValidExpressionStack(int b, void Function() a) => b;
diff --git a/runtime/tests/vm/dart/regress_45270_test.dart b/runtime/tests/vm/dart/regress_45270_test.dart
new file mode 100644
index 0000000..867e2bd
--- /dev/null
+++ b/runtime/tests/vm/dart/regress_45270_test.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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/45270
+
+void main() {
+  // Function.apply.
+  test<int?>(42);
+  test<int?>(null);
+
+  // Dynamic closure calls.
+  test2<int?>(42);
+  test2<int?>(null);
+}
+
+void test<T>(T value) {
+  final f = (T inner) {
+    print('f inner=$inner T=$T');
+  };
+  Function.apply(f, [value]);
+}
+
+void test2<T>(T value) {
+  dynamic f = (T inner) {
+    print('f inner=$inner T=$T');
+  };
+  f(value);
+}
diff --git a/runtime/tests/vm/dart/regress_45306_test.dart b/runtime/tests/vm/dart/regress_45306_test.dart
new file mode 100644
index 0000000..2b5e3c0
--- /dev/null
+++ b/runtime/tests/vm/dart/regress_45306_test.dart
@@ -0,0 +1,33 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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/45306.
+// Verifies that ScopeBuilder doesn't crash on an async closure inside
+// instance field initializer.
+
+class X {
+  late final Y y = Y(
+    () async {},
+  );
+
+  final double? a;
+  final double? b;
+  final String? c;
+
+  X({
+    this.a,
+    this.b,
+    this.c,
+  });
+}
+
+typedef Callback = Future<void> Function();
+
+class Y {
+  Y(Callback? f);
+}
+
+void main() {
+  X();
+}
diff --git a/runtime/tests/vm/dart/use_trace_precompiler_flag_test.dart b/runtime/tests/vm/dart/use_trace_precompiler_flag_test.dart
new file mode 100644
index 0000000..7ea2d60
--- /dev/null
+++ b/runtime/tests/vm/dart/use_trace_precompiler_flag_test.dart
@@ -0,0 +1,110 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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 ensures that --trace-precompiler runs without issue and prints
+// valid JSON for reasons to retain objects.
+
+// OtherResources=use_dwarf_stack_traces_flag_program.dart
+
+import "dart:convert";
+import "dart:io";
+
+import 'package:expect/expect.dart';
+import 'package:path/path.dart' as path;
+
+import 'use_flag_test_helper.dart';
+
+main(List<String> args) async {
+  if (!isAOTRuntime) {
+    return; // Running in JIT: AOT binaries not available.
+  }
+
+  if (Platform.isAndroid) {
+    return; // SDK tree and dart_bootstrap not available on the test device.
+  }
+
+  // These are the tools we need to be available to run on a given platform:
+  if (!await testExecutable(genSnapshot)) {
+    throw "Cannot run test as $genSnapshot not available";
+  }
+  if (!await testExecutable(aotRuntime)) {
+    throw "Cannot run test as $aotRuntime not available";
+  }
+  if (!File(platformDill).existsSync()) {
+    throw "Cannot run test as $platformDill does not exist";
+  }
+
+  await withTempDir('trace-precompiler-flag-test', (String tempDir) async {
+    final cwDir = path.dirname(Platform.script.toFilePath());
+    // We can just reuse the program for the use_dwarf_stack_traces test.
+    final script = path.join(cwDir, 'use_dwarf_stack_traces_flag_program.dart');
+    final scriptDill = path.join(tempDir, 'flag_program.dill');
+
+    // Compile script to Kernel IR.
+    await run(genKernel, <String>[
+      '--aot',
+      '--platform=$platformDill',
+      '-o',
+      scriptDill,
+      script,
+    ]);
+
+    // Run the AOT compiler with every enabled/disabled combination of the
+    // following flags that affect object retention:
+    final retentionFlags = [
+      'retain-function-objects',
+      'dwarf-stack-traces-mode'
+    ];
+
+    for (var i = 0; i < 1 << retentionFlags.length; i++) {
+      final flags = <String>[];
+      for (var j = 0; j < retentionFlags.length; j++) {
+        final buffer = StringBuffer('--');
+        if ((i & (1 << j)) == 0) {
+          buffer.write('no-');
+        }
+        buffer.write(retentionFlags[j]);
+        flags.add(buffer.toString());
+      }
+      await testTracePrecompiler(tempDir, scriptDill, flags);
+    }
+  });
+}
+
+Future<void> testTracePrecompiler(
+    String tempDir, String scriptDill, List<String> flags) async {
+  final reasonsFile = path.join(tempDir, 'reasons.json');
+  final snapshot = path.join(tempDir, 'snapshot.so');
+  final result = await run(genSnapshot, <String>[
+    ...flags,
+    '--write-retained-reasons-to=$reasonsFile',
+    '--snapshot-kind=app-aot-elf',
+    '--elf=$snapshot',
+    scriptDill,
+  ]);
+
+  final stream = Stream.fromFuture(File(reasonsFile).readAsString());
+  final decisionsJson = await json.decoder.bind(stream).first;
+  Expect.isTrue(decisionsJson is List, 'not a list of decisions');
+  Expect.isTrue((decisionsJson as List).every((o) => o is Map),
+      'not a list of decision objects');
+  final decisions = (decisionsJson as List).map((o) => o as Map);
+  for (final m in decisions) {
+    Expect.isTrue(m.containsKey("name"), 'no name field in decision');
+    Expect.isTrue(m["name"] is String, 'name field is not a string');
+    Expect.isTrue(m.containsKey("type"), 'no type field in decision');
+    Expect.isTrue(m["type"] is String, 'type field is not a string');
+    Expect.isTrue(m.containsKey("retained"), 'no retained field in decision');
+    Expect.isTrue(m["retained"] is bool, 'retained field is not a boolean');
+    if (m["retained"] as bool) {
+      Expect.isTrue(m.containsKey("reasons"), 'no reasons field in decision');
+      Expect.isTrue(m["reasons"] is List, 'reasons field is not a list');
+      final reasons = m["reasons"] as List;
+      Expect.isFalse(reasons.isEmpty, 'reasons list should not be empty');
+      for (final o in reasons) {
+        Expect.isTrue(o is String, 'reason is not a string');
+      }
+    }
+  }
+}
diff --git a/runtime/tests/vm/dart_2/base_il_serialization_test.dart b/runtime/tests/vm/dart_2/base_il_serialization_test.dart
deleted file mode 100644
index 569b661..0000000
--- a/runtime/tests/vm/dart_2/base_il_serialization_test.dart
+++ /dev/null
@@ -1,16 +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=--serialize_flow_graphs_to=il_tmp.txt
-// VMOptions=--serialize_flow_graphs_to=il_tmp.txt --populate_llvm_constant_pool
-// VMOptions=--serialize_flow_graphs_to=il_tmp.txt --no_serialize_flow_graph_types
-// VMOptions=--serialize_flow_graphs_to=il_tmp.txt --verbose_flow_graph_serialization
-// VMOptions=--serialize_flow_graphs_to=il_tmp.txt --no_serialize_flow_graph_types --verbose_flow_graph_serialization
-
-// Just use the existing hello world test.
-import 'hello_world_test.dart' as test;
-
-main(args) {
-  test.main();
-}
diff --git a/runtime/tests/vm/dart_2/deopt/allocate_array_test.dart b/runtime/tests/vm/dart_2/deopt/allocate_array_test.dart
new file mode 100644
index 0000000..eb06336
--- /dev/null
+++ b/runtime/tests/vm/dart_2/deopt/allocate_array_test.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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=--disable-dart-dev --no-inline-alloc --use-slow-path --deoptimize-on-runtime-call-every=1 --deterministic --optimization-counter-threshold=1 --deoptimize-on-runtime-call-name-filter=AllocateArray
+
+main() {
+  for (int i = 0; i < 20; ++i) {
+    final list = foo(1);
+    if (list[0] != 42) throw 'a';
+  }
+}
+
+@pragma('vm:never-inline')
+List foo(int a) {
+  return List<dynamic>.filled(a, null)..[0] = 42;
+}
diff --git a/runtime/tests/vm/dart_2/deopt/allocate_context_test.dart b/runtime/tests/vm/dart_2/deopt/allocate_context_test.dart
new file mode 100644
index 0000000..c52abc0
--- /dev/null
+++ b/runtime/tests/vm/dart_2/deopt/allocate_context_test.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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=--disable-dart-dev --no-inline-alloc --use-slow-path --deoptimize-on-runtime-call-every=1 --deterministic --optimization-counter-threshold=1 --deoptimize-on-runtime-call-name-filter=AllocateContext
+
+main() {
+  for (int i = 0; i < 20; ++i) {
+    final fun = foo(1);
+    if (fun(1) != 3) throw 'a';
+    if (fun(2) != 6) throw 'b';
+  }
+}
+
+@pragma('vm:never-inline')
+int Function(int) foo(int a) {
+  int b = 1;
+  return (int c) {
+    return a++ + b++ + c;
+  };
+}
diff --git a/runtime/tests/vm/dart_2/deopt/allocate_object_test.dart b/runtime/tests/vm/dart_2/deopt/allocate_object_test.dart
new file mode 100644
index 0000000..efcd883
--- /dev/null
+++ b/runtime/tests/vm/dart_2/deopt/allocate_object_test.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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=--disable-dart-dev --no-inline-alloc --use-slow-path --deoptimize-on-runtime-call-every=1 --deterministic --optimization-counter-threshold=1 --deoptimize-on-runtime-call-name-filter=AllocateObject
+
+main() {
+  for (int i = 0; i < 20; ++i) {
+    final foo = bar(1);
+    if (foo.fun(1) != 3) throw 'a';
+    if (foo.fun(2) != 6) throw 'b';
+  }
+}
+
+@pragma('vm:never-inline')
+Foo bar(int a) {
+  int b = 1;
+  return Foo(a, (int c) {
+    return a++ + b++ + c++;
+  });
+}
+
+class Foo {
+  final int value;
+  final int Function(int) fun;
+  Foo(this.value, this.fun);
+}
diff --git a/runtime/tests/vm/dart_2/deopt/allocate_typed_data_test.dart b/runtime/tests/vm/dart_2/deopt/allocate_typed_data_test.dart
new file mode 100644
index 0000000..6556661
--- /dev/null
+++ b/runtime/tests/vm/dart_2/deopt/allocate_typed_data_test.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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=--disable-dart-dev --no-inline-alloc --use-slow-path --deoptimize-on-runtime-call-every=1 --deterministic --optimization-counter-threshold=1 --deoptimize-on-runtime-call-name-filter=AllocateTypedData
+
+import 'dart:typed_data';
+
+main() {
+  for (int i = 0; i < 20; ++i) {
+    final foo = bar(1);
+    if (foo[0] != 42) throw 'a';
+  }
+}
+
+@pragma('vm:never-inline')
+Uint32List bar(int a) {
+  return Uint32List(1)..[0] = 42;
+}
diff --git a/runtime/tests/vm/dart_2/deopt/assert_subtype_test.dart b/runtime/tests/vm/dart_2/deopt/assert_subtype_test.dart
new file mode 100644
index 0000000..964aa7d
--- /dev/null
+++ b/runtime/tests/vm/dart_2/deopt/assert_subtype_test.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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=--disable-dart-dev --deoptimize-on-runtime-call-every=1 --deterministic --optimization-counter-threshold=1 --deoptimize-on-runtime-call-name-filter=SubtypeCheck
+
+main() {
+  for (int i = 0; i < 20; ++i) {
+    if (foo()<int>() != 42) throw 'a';
+    if (foo()<double>() != 42) throw 'a';
+  }
+}
+
+@pragma('vm:never-inline')
+dynamic foo() {
+  int bar<T extends num>() => 42;
+  return bar;
+}
diff --git a/runtime/tests/vm/dart_2/deopt/clone_context_test.dart b/runtime/tests/vm/dart_2/deopt/clone_context_test.dart
new file mode 100644
index 0000000..5320404
--- /dev/null
+++ b/runtime/tests/vm/dart_2/deopt/clone_context_test.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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=--disable-dart-dev --no-inline-alloc --use-slow-path --deoptimize-on-runtime-call-every=1 --deterministic --optimization-counter-threshold=1 --deoptimize-on-runtime-call-name-filter=CloneContext
+
+main() {
+  for (int i = 0; i < 20; ++i) {
+    if (foo(1)[1]() != 2) throw 'a';
+  }
+}
+
+@pragma('vm:never-inline')
+List foo(int a) {
+  final l = <int Function()>[];
+  for (int i = 0; i < 10; ++i) {
+    l.add(() => a + i);
+  }
+  return l;
+}
diff --git a/runtime/tests/vm/dart_2/deopt/instantiate_type_arguments_test.dart b/runtime/tests/vm/dart_2/deopt/instantiate_type_arguments_test.dart
new file mode 100644
index 0000000..4426064
--- /dev/null
+++ b/runtime/tests/vm/dart_2/deopt/instantiate_type_arguments_test.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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=--disable-dart-dev --deoptimize-on-runtime-call-every=1 --deterministic --optimization-counter-threshold=1 --deoptimize-on-runtime-call-name-filter=InstantiateTypeArguments
+
+main() {
+  final a = A<int>();
+  for (int i = 0; i < 20; ++i) {
+    final m = a.foo<double>();
+    if (m is! Map<int, double>) throw 'a';
+  }
+}
+
+class A<T> {
+  @pragma('vm:never-inline')
+  Map foo<H>() => <T, H>{};
+}
diff --git a/runtime/tests/vm/dart_2/deopt/instantiate_type_test.dart b/runtime/tests/vm/dart_2/deopt/instantiate_type_test.dart
new file mode 100644
index 0000000..2ae579e
--- /dev/null
+++ b/runtime/tests/vm/dart_2/deopt/instantiate_type_test.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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=--disable-dart-dev --deoptimize-on-runtime-call-every=1 --deterministic --optimization-counter-threshold=1 --deoptimize-on-runtime-call-name-filter=InstantiateType
+
+main() {
+  final a = A<int>();
+  for (int i = 0; i < 20; ++i) {
+    final l = a.foo<double>();
+    if (l[0] != int) throw 'a';
+    if (l[1] != double) throw 'a';
+  }
+}
+
+class A<T> {
+  @pragma('vm:never-inline')
+  List<Type> foo<H>() {
+    final l = <Type>[];
+    for (int i = 0; i < 10; ++i) {
+      l.add(T);
+      l.add(H);
+    }
+    return l;
+  }
+}
diff --git a/runtime/tests/vm/dart_2/isolate_send_regex_test.dart b/runtime/tests/vm/dart_2/isolate_send_regex_test.dart
new file mode 100644
index 0000000..cac6d09
--- /dev/null
+++ b/runtime/tests/vm/dart_2/isolate_send_regex_test.dart
@@ -0,0 +1,38 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+import 'dart:isolate';
+
+import 'package:expect/expect.dart';
+
+f(List args) {
+  final sendPort = args[0] as SendPort;
+  final re = args[1] as RegExp;
+  Expect.stringEquals("RegExp: pattern=abc flags=", re.toString());
+  sendPort.send(true);
+}
+
+main() async {
+  final rpError = RawReceivePort((e) {
+    Expect.fail('Spawned isolated failed with $e');
+  });
+  {
+    // Test sending of initialized RegExp
+    final rp = ReceivePort();
+    final re = RegExp('abc');
+    print(re.hasMatch('kukabcdef'));
+    await Isolate.spawn(f, <dynamic>[rp.sendPort, re],
+        onError: rpError.sendPort);
+    Expect.isTrue(await rp.first);
+  }
+  {
+    // Test send of uninitialized RegExp(num_groups is null)
+    final rp = ReceivePort();
+    final re = RegExp('abc');
+    await Isolate.spawn(f, <dynamic>[rp.sendPort, re],
+        onError: rpError.sendPort);
+    Expect.isTrue(await rp.first);
+  }
+  rpError.close();
+}
diff --git a/runtime/tests/vm/dart_2/regress_38661_test.dart b/runtime/tests/vm/dart_2/regress_38661_test.dart
deleted file mode 100644
index 2e1ba13..0000000
--- a/runtime/tests/vm/dart_2/regress_38661_test.dart
+++ /dev/null
@@ -1,27 +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=--serialize_flow_graphs_to=il_tmp.txt
-// VMOptions=--serialize_flow_graphs_to=il_tmp.txt --populate_llvm_constant_pool
-// VMOptions=--serialize_flow_graphs_to=il_tmp.txt --no_serialize_flow_graph_types
-// VMOptions=--serialize_flow_graphs_to=il_tmp.txt --verbose_flow_graph_serialization
-// VMOptions=--serialize_flow_graphs_to=il_tmp.txt --no_serialize_flow_graph_types --verbose_flow_graph_serialization
-
-class A {
-  const A();
-}
-
-class B {
-  Object a = const A();
-}
-
-foo(int i) {
-  if (i == 3) {
-    new B();
-  }
-}
-
-main(args) {
-  foo(4);
-}
diff --git a/runtime/tests/vm/dart_2/regress_45207_test.dart b/runtime/tests/vm/dart_2/regress_45207_test.dart
new file mode 100644
index 0000000..9f01648
--- /dev/null
+++ b/runtime/tests/vm/dart_2/regress_45207_test.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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 --deoptimize-on-runtime-call-name-filter=TypeCheck --deoptimize-on-runtime-call-every=1 --max-subtype-cache-entries=0
+
+main() {
+  void nop() {}
+  for (int i = 0; i < 1000; ++i) {
+    if (assertAssignable(nop) != 1) {
+      throw 'broken';
+    }
+  }
+}
+
+@pragma('vm:never-inline')
+int assertAssignable(dynamic a0) {
+  return ensureValidExpressionStack(1, a0 as void Function());
+}
+
+@pragma('vm:never-inline')
+int ensureValidExpressionStack(int b, void Function() a) => b;
diff --git a/runtime/tests/vm/dart_2/regress_45306_test.dart b/runtime/tests/vm/dart_2/regress_45306_test.dart
new file mode 100644
index 0000000..36af440
--- /dev/null
+++ b/runtime/tests/vm/dart_2/regress_45306_test.dart
@@ -0,0 +1,33 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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/45306.
+// Verifies that ScopeBuilder doesn't crash on an async closure inside
+// instance field initializer.
+
+class X {
+  final Y y = Y(
+    () async {},
+  );
+
+  final double a;
+  final double b;
+  final String c;
+
+  X({
+    this.a,
+    this.b,
+    this.c,
+  });
+}
+
+typedef Callback = Future<void> Function();
+
+class Y {
+  Y(Callback f);
+}
+
+void main() {
+  X();
+}
diff --git a/runtime/tests/vm/dart_2/use_trace_precompiler_flag_test.dart b/runtime/tests/vm/dart_2/use_trace_precompiler_flag_test.dart
new file mode 100644
index 0000000..7ea2d60
--- /dev/null
+++ b/runtime/tests/vm/dart_2/use_trace_precompiler_flag_test.dart
@@ -0,0 +1,110 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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 ensures that --trace-precompiler runs without issue and prints
+// valid JSON for reasons to retain objects.
+
+// OtherResources=use_dwarf_stack_traces_flag_program.dart
+
+import "dart:convert";
+import "dart:io";
+
+import 'package:expect/expect.dart';
+import 'package:path/path.dart' as path;
+
+import 'use_flag_test_helper.dart';
+
+main(List<String> args) async {
+  if (!isAOTRuntime) {
+    return; // Running in JIT: AOT binaries not available.
+  }
+
+  if (Platform.isAndroid) {
+    return; // SDK tree and dart_bootstrap not available on the test device.
+  }
+
+  // These are the tools we need to be available to run on a given platform:
+  if (!await testExecutable(genSnapshot)) {
+    throw "Cannot run test as $genSnapshot not available";
+  }
+  if (!await testExecutable(aotRuntime)) {
+    throw "Cannot run test as $aotRuntime not available";
+  }
+  if (!File(platformDill).existsSync()) {
+    throw "Cannot run test as $platformDill does not exist";
+  }
+
+  await withTempDir('trace-precompiler-flag-test', (String tempDir) async {
+    final cwDir = path.dirname(Platform.script.toFilePath());
+    // We can just reuse the program for the use_dwarf_stack_traces test.
+    final script = path.join(cwDir, 'use_dwarf_stack_traces_flag_program.dart');
+    final scriptDill = path.join(tempDir, 'flag_program.dill');
+
+    // Compile script to Kernel IR.
+    await run(genKernel, <String>[
+      '--aot',
+      '--platform=$platformDill',
+      '-o',
+      scriptDill,
+      script,
+    ]);
+
+    // Run the AOT compiler with every enabled/disabled combination of the
+    // following flags that affect object retention:
+    final retentionFlags = [
+      'retain-function-objects',
+      'dwarf-stack-traces-mode'
+    ];
+
+    for (var i = 0; i < 1 << retentionFlags.length; i++) {
+      final flags = <String>[];
+      for (var j = 0; j < retentionFlags.length; j++) {
+        final buffer = StringBuffer('--');
+        if ((i & (1 << j)) == 0) {
+          buffer.write('no-');
+        }
+        buffer.write(retentionFlags[j]);
+        flags.add(buffer.toString());
+      }
+      await testTracePrecompiler(tempDir, scriptDill, flags);
+    }
+  });
+}
+
+Future<void> testTracePrecompiler(
+    String tempDir, String scriptDill, List<String> flags) async {
+  final reasonsFile = path.join(tempDir, 'reasons.json');
+  final snapshot = path.join(tempDir, 'snapshot.so');
+  final result = await run(genSnapshot, <String>[
+    ...flags,
+    '--write-retained-reasons-to=$reasonsFile',
+    '--snapshot-kind=app-aot-elf',
+    '--elf=$snapshot',
+    scriptDill,
+  ]);
+
+  final stream = Stream.fromFuture(File(reasonsFile).readAsString());
+  final decisionsJson = await json.decoder.bind(stream).first;
+  Expect.isTrue(decisionsJson is List, 'not a list of decisions');
+  Expect.isTrue((decisionsJson as List).every((o) => o is Map),
+      'not a list of decision objects');
+  final decisions = (decisionsJson as List).map((o) => o as Map);
+  for (final m in decisions) {
+    Expect.isTrue(m.containsKey("name"), 'no name field in decision');
+    Expect.isTrue(m["name"] is String, 'name field is not a string');
+    Expect.isTrue(m.containsKey("type"), 'no type field in decision');
+    Expect.isTrue(m["type"] is String, 'type field is not a string');
+    Expect.isTrue(m.containsKey("retained"), 'no retained field in decision');
+    Expect.isTrue(m["retained"] is bool, 'retained field is not a boolean');
+    if (m["retained"] as bool) {
+      Expect.isTrue(m.containsKey("reasons"), 'no reasons field in decision');
+      Expect.isTrue(m["reasons"] is List, 'reasons field is not a list');
+      final reasons = m["reasons"] as List;
+      Expect.isFalse(reasons.isEmpty, 'reasons list should not be empty');
+      for (final o in reasons) {
+        Expect.isTrue(o is String, 'reason is not a string');
+      }
+    }
+  }
+}
diff --git a/runtime/tools/dartfuzz/dartfuzz.dart b/runtime/tools/dartfuzz/dartfuzz.dart
index af137ed..8322ba6 100644
--- a/runtime/tools/dartfuzz/dartfuzz.dart
+++ b/runtime/tools/dartfuzz/dartfuzz.dart
@@ -16,7 +16,7 @@
 // Version of DartFuzz. Increase this each time changes are made
 // to preserve the property that a given version of DartFuzz yields
 // the same fuzzed program for a deterministic random seed.
-const String version = '1.88';
+const String version = '1.89';
 
 // Restriction on statements and expressions.
 const int stmtDepth = 1;
@@ -792,6 +792,7 @@
     emitLn('// Program generated as:');
     emitLn('//   dart dartfuzz.dart --seed $seed --${fp ? "" : "no-"}fp '
         '--${ffi ? "" : "no-"}ffi --${flatTp ? "" : "no-"}flat');
+    emitLn('// @dart=2.7');
     emitNewline();
     emitImport('dart:async');
     emitImport('dart:cli');
diff --git a/runtime/tools/dartfuzz/dartfuzz_test.dart b/runtime/tools/dartfuzz/dartfuzz_test.dart
index 8e826fa..612c1aa 100644
--- a/runtime/tools/dartfuzz/dartfuzz_test.dart
+++ b/runtime/tools/dartfuzz/dartfuzz_test.dart
@@ -116,12 +116,16 @@
   static String getTag(String mode) {
     if (mode.endsWith('debug-ia32')) return 'DebugIA32';
     if (mode.endsWith('debug-x64')) return 'DebugX64';
+    if (mode.endsWith('debug-x64c')) return 'DebugX64C';
     if (mode.endsWith('debug-arm32')) return 'DebugSIMARM';
     if (mode.endsWith('debug-arm64')) return 'DebugSIMARM64';
+    if (mode.endsWith('debug-arm64c')) return 'DebugSIMARM64C';
     if (mode.endsWith('ia32')) return 'ReleaseIA32';
     if (mode.endsWith('x64')) return 'ReleaseX64';
+    if (mode.endsWith('x64c')) return 'ReleaseX64C';
     if (mode.endsWith('arm32')) return 'ReleaseSIMARM';
     if (mode.endsWith('arm64')) return 'ReleaseSIMARM64';
+    if (mode.endsWith('arm64c')) return 'ReleaseSIMARM64C';
     throw ('unknown tag in mode: $mode');
   }
 
@@ -674,14 +678,20 @@
   static const List<String> clusterModes = [
     'jit-debug-ia32',
     'jit-debug-x64',
+    'jit-debug-x64c',
     'jit-debug-arm32',
     'jit-debug-arm64',
+    'jit-debug-arm64c',
     'jit-ia32',
     'jit-x64',
+    'jit-x64c',
     'jit-arm32',
     'jit-arm64',
+    'jit-arm64c',
     'aot-debug-x64',
+    'aot-debug-x64c',
     'aot-x64',
+    'aot-x64c',
   ];
 
   // Modes not used on cluster runs because they have outstanding issues.
@@ -689,8 +699,10 @@
     // Times out often:
     'aot-debug-arm32',
     'aot-debug-arm64',
+    'aot-debug-arm64c',
     'aot-arm32',
     'aot-arm64',
+    'aot-arm64c',
     // Too many divergences (due to arithmetic):
     'js-x64',
   ];
diff --git a/runtime/tools/run_clang_tidy.dart b/runtime/tools/run_clang_tidy.dart
index 5b18c61..0d9831a 100644
--- a/runtime/tools/run_clang_tidy.dart
+++ b/runtime/tools/run_clang_tidy.dart
@@ -108,12 +108,6 @@
   'runtime/vm/stack_frame_ia32.h',
   'runtime/vm/stack_frame_x64.h',
 
-  // By default the gclient checkout doesn't have llvm pulled in.
-  'runtime/llvm_codegen/bit/bit.h',
-  'runtime/llvm_codegen/bit/main.cc',
-  'runtime/llvm_codegen/bit/test.cc',
-  'runtime/llvm_codegen/codegen/main.cc',
-
   // Only available in special builds
   'runtime/bin/io_service_no_ssl.h',
   'runtime/bin/utils_win.h',
diff --git a/runtime/vm/bitfield.h b/runtime/vm/bitfield.h
index 1eaa94d..b982d83 100644
--- a/runtime/vm/bitfield.h
+++ b/runtime/vm/bitfield.h
@@ -5,7 +5,8 @@
 #ifndef RUNTIME_VM_BITFIELD_H_
 #define RUNTIME_VM_BITFIELD_H_
 
-#include "platform/assert.h"
+#include <type_traits>
+
 #include "platform/globals.h"
 
 namespace dart {
@@ -17,19 +18,22 @@
 template <typename S,
           typename T,
           int position,
-          int size = (sizeof(S) * kBitsPerByte) - position>
+          int size = (sizeof(S) * kBitsPerByte) - position,
+          bool sign_extend = false>
 class BitField {
  public:
   typedef T Type;
 
   static_assert((sizeof(S) * kBitsPerByte) >= (position + size),
                 "BitField does not fit into the type.");
+  static_assert(!sign_extend || std::is_signed<T>::value,
+                "Should only sign extend signed bitfield types");
 
   static const intptr_t kNextBit = position + size;
 
   // Tells whether the provided value fits into the bit field.
   static constexpr bool is_valid(T value) {
-    return (static_cast<S>(value) & ~((kUwordOne << size) - 1)) == 0;
+    return decode(encode_unchecked(value)) == value;
   }
 
   // Returns a S mask of the bit field.
@@ -37,9 +41,7 @@
 
   // Returns a S mask of the bit field which can be applied directly to
   // to the raw unshifted bits.
-  static constexpr S mask_in_place() {
-    return ((kUwordOne << size) - 1) << position;
-  }
+  static constexpr S mask_in_place() { return mask() << position; }
 
   // Returns the shift count needed to right-shift the bit field to
   // the least-significant bits.
@@ -49,22 +51,38 @@
   static constexpr int bitsize() { return size; }
 
   // Returns an S with the bit field value encoded.
-  static UNLESS_DEBUG(constexpr) S encode(T value) {
-    DEBUG_ASSERT(is_valid(value));
-    return static_cast<S>(value) << position;
+  static constexpr S encode(T value) {
+    assert(is_valid(value));
+    return encode_unchecked(value);
   }
 
   // Extracts the bit field from the value.
   static constexpr T decode(S value) {
-    return static_cast<T>((value >> position) & ((kUwordOne << size) - 1));
+    // Ensure we slide down the sign bit if the value in the bit field is signed
+    // and negative. We use 64-bit ints inside the expression since we can have
+    // both cases: sizeof(S) > sizeof(T) or sizeof(S) < sizeof(T).
+    if constexpr (sign_extend) {
+      auto const u = static_cast<uint64_t>(value);
+      return static_cast<T>((static_cast<int64_t>(u << (64 - kNextBit))) >>
+                            (64 - size));
+    } else {
+      auto const u = static_cast<typename std::make_unsigned<S>::type>(value);
+      return static_cast<T>((u >> position) & mask());
+    }
   }
 
   // Returns an S with the bit field value encoded based on the
   // original value. Only the bits corresponding to this bit field
   // will be changed.
-  static UNLESS_DEBUG(constexpr) S update(T value, S original) {
-    DEBUG_ASSERT(is_valid(value));
-    return (static_cast<S>(value) << position) | (~mask_in_place() & original);
+  static constexpr S update(T value, S original) {
+    return encode(value) | (~mask_in_place() & original);
+  }
+
+ private:
+  // Returns an S with the bit field value encoded.
+  static constexpr S encode_unchecked(T value) {
+    auto const u = static_cast<typename std::make_unsigned<S>::type>(value);
+    return (u & mask()) << position;
   }
 };
 
diff --git a/runtime/vm/bitfield_test.cc b/runtime/vm/bitfield_test.cc
index d8e8182..e2d40f0 100644
--- a/runtime/vm/bitfield_test.cc
+++ b/runtime/vm/bitfield_test.cc
@@ -23,4 +23,63 @@
   EXPECT_EQ(2U, TestBitFields::update(1, 16));
 }
 
+template <typename T>
+static void TestSignExtendedBitField() {
+  class F1 : public BitField<T, intptr_t, 0, 8, /*sign_extend=*/true> {};
+  class F2
+      : public BitField<T, uintptr_t, F1::kNextBit, 8, /*sign_extend=*/false> {
+  };
+  class F3
+      : public BitField<T, intptr_t, F2::kNextBit, 8, /*sign_extend=*/true> {};
+  class F4
+      : public BitField<T, uintptr_t, F3::kNextBit, 8, /*sign_extend=*/false> {
+  };
+
+  const uint32_t value =
+      F1::encode(-1) | F2::encode(1) | F3::encode(-2) | F4::encode(2);
+  EXPECT_EQ(0x02fe01ffU, value);
+  EXPECT_EQ(-1, F1::decode(value));
+  EXPECT_EQ(1U, F2::decode(value));
+  EXPECT_EQ(-2, F3::decode(value));
+  EXPECT_EQ(2U, F4::decode(value));
+}
+
+template <typename T>
+static void TestNotSignExtendedBitField() {
+  class F1 : public BitField<T, intptr_t, 0, 8, /*sign_extend=*/false> {};
+  class F2
+      : public BitField<T, uintptr_t, F1::kNextBit, 8, /*sign_extend=*/false> {
+  };
+  class F3
+      : public BitField<T, intptr_t, F2::kNextBit, 8, /*sign_extend=*/false> {};
+  class F4
+      : public BitField<T, uintptr_t, F3::kNextBit, 8, /*sign_extend=*/false> {
+  };
+
+  const uint32_t value =
+      F1::encode(-1) | F2::encode(1) | F3::encode(-2) | F4::encode(2);
+  EXPECT_EQ(0x02fe01ffU, value);
+  EXPECT_EQ(3, F1::decode(value));
+  EXPECT_EQ(1, F2::decode(value));
+  EXPECT_EQ(2, F3::decode(value));
+  EXPECT_EQ(2, F3::decode(value));
+}
+
+VM_UNIT_TEST_CASE(BitFields_SignedField) {
+  TestSignExtendedBitField<uint32_t>();
+  TestSignExtendedBitField<int32_t>();
+}
+
+#if defined(DEBUG)
+#define DEBUG_CRASH "Crash"
+#else
+#define DEBUG_CRASH "Pass"
+#endif
+
+VM_UNIT_TEST_CASE_WITH_EXPECTATION(BitFields_Assert, DEBUG_CRASH) {
+  class F : public BitField<uint32_t, uint32_t, 0, 8, /*sign_extend=*/false> {};
+  const uint32_t value = F::encode(kMaxUint32);
+  EXPECT_EQ(kMaxUint8, value);
+}
+
 }  // namespace dart
diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc
index 6073695..9d182ed 100644
--- a/runtime/vm/class_finalizer.cc
+++ b/runtime/vm/class_finalizer.cc
@@ -1432,10 +1432,10 @@
           Map(param->untag()->parameterized_class_id_);
     } else if (obj->IsType()) {
       TypePtr type = Type::RawCast(obj);
-      ObjectPtr id = type->untag()->type_class_id_;
+      ObjectPtr id = type->untag()->type_class_id();
       if (!id->IsHeapObject()) {
-        type->untag()->type_class_id_ =
-            Smi::New(Map(Smi::Value(Smi::RawCast(id))));
+        type->untag()->set_type_class_id(
+            Smi::New(Map(Smi::Value(Smi::RawCast(id)))));
       }
     } else {
       intptr_t old_cid = obj->GetClassId();
diff --git a/runtime/vm/closure_functions_cache.cc b/runtime/vm/closure_functions_cache.cc
index e70d6ce..ff62680 100644
--- a/runtime/vm/closure_functions_cache.cc
+++ b/runtime/vm/closure_functions_cache.cc
@@ -172,7 +172,7 @@
   const auto& closures =
       GrowableObjectArray::Handle(zone, object_store->closure_functions());
 
-  {
+  if (!thread->IsInStoppedMutatorsScope()) {
     // The empty read locker scope will implicitly issue an acquire memory
     // fence, which means any closure functions added so far will be visible and
     // iterated further down.
diff --git a/runtime/vm/clustered_snapshot.cc b/runtime/vm/clustered_snapshot.cc
index b13f0ba..a94e18a 100644
--- a/runtime/vm/clustered_snapshot.cc
+++ b/runtime/vm/clustered_snapshot.cc
@@ -52,6 +52,69 @@
             "Write a snapshot profile in V8 format to a file.");
 #endif  // defined(DART_PRECOMPILER)
 
+namespace {
+// StorageTrait for HashTable which allows to create hash tables backed by
+// zone memory. Used to compute cluster order for canonical clusters.
+struct GrowableArrayStorageTraits {
+  class Array {
+   public:
+    explicit Array(Zone* zone, intptr_t length)
+        : length_(length), array_(zone->Alloc<ObjectPtr>(length)) {}
+
+    intptr_t Length() const { return length_; }
+    void SetAt(intptr_t index, const Object& value) const {
+      array_[index] = value.ptr();
+    }
+    ObjectPtr At(intptr_t index) const { return array_[index]; }
+
+   private:
+    intptr_t length_ = 0;
+    ObjectPtr* array_ = nullptr;
+    DISALLOW_COPY_AND_ASSIGN(Array);
+  };
+
+  using ArrayPtr = Array*;
+  class ArrayHandle : public ZoneAllocated {
+   public:
+    explicit ArrayHandle(ArrayPtr ptr) : ptr_(ptr) {}
+    ArrayHandle() {}
+
+    void SetFrom(const ArrayHandle& other) { ptr_ = other.ptr_; }
+    void Clear() { ptr_ = nullptr; }
+    bool IsNull() const { return ptr_ == nullptr; }
+    ArrayPtr ptr() { return ptr_; }
+
+    intptr_t Length() const { return ptr_->Length(); }
+    void SetAt(intptr_t index, const Object& value) const {
+      ptr_->SetAt(index, value);
+    }
+    ObjectPtr At(intptr_t index) const { return ptr_->At(index); }
+
+   private:
+    ArrayPtr ptr_ = nullptr;
+    DISALLOW_COPY_AND_ASSIGN(ArrayHandle);
+  };
+
+  static ArrayHandle& PtrToHandle(ArrayPtr ptr) {
+    return *new ArrayHandle(ptr);
+  }
+
+  static void SetHandle(ArrayHandle& dst, const ArrayHandle& src) {  // NOLINT
+    dst.SetFrom(src);
+  }
+
+  static void ClearHandle(ArrayHandle& dst) {  // NOLINT
+    dst.Clear();
+  }
+
+  static ArrayPtr New(Zone* zone, intptr_t length, Heap::Space space) {
+    return new (zone) Array(zone, length);
+  }
+
+  static bool IsImmutable(const ArrayHandle& handle) { return false; }
+};
+}  // namespace
+
 #if defined(DART_PRECOMPILER) && !defined(TARGET_ARCH_IA32)
 
 static void RelocateCodeObjects(
@@ -236,7 +299,7 @@
 
  private:
   void WriteClass(Serializer* s, ClassPtr cls) {
-    AutoTraceObjectName(cls, cls->untag()->name_);
+    AutoTraceObjectName(cls, cls->untag()->name());
     WriteFromTo(cls);
     intptr_t class_id = cls->untag()->id_;
     if (class_id == kIllegalCid) {
@@ -275,7 +338,7 @@
     // unsound nullability mode.
     if (cls->untag()->host_type_arguments_field_offset_in_words_ ==
             Class::kNoTypeArguments ||
-        cls->untag()->constants_ == Array::null()) {
+        cls->untag()->constants() == Array::null()) {
       return false;
     }
     Zone* zone = Thread::Current()->zone();
@@ -406,10 +469,229 @@
   intptr_t predefined_stop_index_;
 };
 
+// Super classes for writing out clusters which contain objects grouped into
+// a canonical set (e.g. String, Type, TypeArguments, etc).
+// To save space in the snapshot we avoid writing such canonical sets
+// explicitly as Array objects into the snapshot and instead utilize a different
+// encoding: objects in a cluster representing a canonical set are sorted
+// to appear in the same order they appear in the Array representing the set,
+// and we additionaly write out array of values describing gaps between objects.
+//
+// In some situations not all canonical objects of the some type need to
+// be added to the resulting canonical set because they are cached in some
+// special way (see Type::Canonicalize as an example, which caches declaration
+// types in a special way). In this case subclass can set
+// kAllCanonicalObjectsAreIncludedIntoSet to |false| and override
+// IsInCanonicalSet filter.
 #if !defined(DART_PRECOMPILED_RUNTIME)
-class TypeArgumentsSerializationCluster : public SerializationCluster {
+template <typename SetType,
+          typename HandleType,
+          typename PointerType,
+          bool kAllCanonicalObjectsAreIncludedIntoSet = true>
+class CanonicalSetSerializationCluster : public SerializationCluster {
+ protected:
+  CanonicalSetSerializationCluster(bool represents_canonical_set,
+                                   const char* name,
+                                   intptr_t target_instance_size = 0)
+      : SerializationCluster(name, target_instance_size),
+        represents_canonical_set_(represents_canonical_set) {}
+
+  virtual bool IsInCanonicalSet(Serializer* s, PointerType ptr) {
+    // Must override this function if kAllCanonicalObjectsAreIncludedIntoSet
+    // is set to |false|.
+    ASSERT(kAllCanonicalObjectsAreIncludedIntoSet);
+    return true;
+  }
+
+  void ReorderObjects(Serializer* s) {
+    if (!represents_canonical_set_) {
+      return;
+    }
+
+    // Sort objects before writing them out so that they appear in the same
+    // order as they would appear in a CanonicalStringSet.
+    using ZoneCanonicalSet =
+        HashTable<typename SetType::Traits, 0, 0, GrowableArrayStorageTraits>;
+
+    // Compute required capacity for the hashtable (to avoid overallocating).
+    intptr_t required_capacity = 0;
+    for (auto ptr : objects_) {
+      if (kAllCanonicalObjectsAreIncludedIntoSet || IsInCanonicalSet(s, ptr)) {
+        required_capacity++;
+      }
+    }
+
+    intptr_t num_occupied = 0;
+
+    // Build canonical set out of objects that should belong to it.
+    // Objects that don't belong to it are copied to the prefix of objects_.
+    ZoneCanonicalSet table(
+        s->zone(), HashTables::New<ZoneCanonicalSet>(required_capacity));
+    HandleType& element = HandleType::Handle(s->zone());
+    for (auto ptr : objects_) {
+      if (kAllCanonicalObjectsAreIncludedIntoSet || IsInCanonicalSet(s, ptr)) {
+        element ^= ptr;
+        intptr_t entry = -1;
+        const bool present = table.FindKeyOrDeletedOrUnused(element, &entry);
+        ASSERT(!present);
+        table.InsertKey(entry, element);
+      } else {
+        objects_[num_occupied++] = ptr;
+      }
+    }
+
+    const auto prefix_length = num_occupied;
+
+    // Compute objects_ order and gaps based on canonical set layout.
+    auto& arr = table.Release();
+    intptr_t last_occupied = ZoneCanonicalSet::kFirstKeyIndex - 1;
+    for (intptr_t i = ZoneCanonicalSet::kFirstKeyIndex, length = arr.Length();
+         i < length; i++) {
+      ObjectPtr v = arr.At(i);
+      ASSERT(v != ZoneCanonicalSet::DeletedMarker().ptr());
+      if (v != ZoneCanonicalSet::UnusedMarker().ptr()) {
+        const intptr_t unused_run_length = (i - 1) - last_occupied;
+        gaps_.Add(unused_run_length);
+        objects_[num_occupied++] = static_cast<PointerType>(v);
+        last_occupied = i;
+      }
+    }
+    ASSERT(num_occupied == objects_.length());
+    ASSERT(prefix_length == (objects_.length() - gaps_.length()));
+    table_length_ = arr.Length();
+  }
+
+  void WriteCanonicalSetLayout(Serializer* s) {
+    if (represents_canonical_set_) {
+      s->WriteUnsigned(table_length_);
+      if (kAllCanonicalObjectsAreIncludedIntoSet) {
+        ASSERT(objects_.length() == gaps_.length());
+      } else {
+        s->WriteUnsigned(objects_.length() - gaps_.length());
+      }
+      for (auto gap : gaps_) {
+        s->WriteUnsigned(gap);
+      }
+      target_memory_size_ +=
+          compiler::target::Array::InstanceSize(table_length_);
+    }
+  }
+
+  GrowableArray<PointerType> objects_;
+
+ private:
+  const bool represents_canonical_set_;
+  GrowableArray<intptr_t> gaps_;
+  intptr_t table_length_ = 0;
+};
+#endif
+
+template <typename SetType, bool kAllCanonicalObjectsAreIncludedIntoSet = true>
+class CanonicalSetDeserializationCluster : public DeserializationCluster {
  public:
-  TypeArgumentsSerializationCluster() : SerializationCluster("TypeArguments") {}
+  CanonicalSetDeserializationCluster(bool is_root_unit, const char* name)
+      : DeserializationCluster(name),
+        is_root_unit_(is_root_unit),
+        table_(Array::Handle()) {}
+
+  void BuildCanonicalSetFromLayout(Deserializer* d, bool is_canonical) {
+    if (!is_root_unit_ || !is_canonical) {
+      return;
+    }
+
+    const auto table_length = d->ReadUnsigned();
+    first_element_ =
+        kAllCanonicalObjectsAreIncludedIntoSet ? 0 : d->ReadUnsigned();
+    const intptr_t count = stop_index_ - (start_index_ + first_element_);
+    auto table = StartDeserialization(d, table_length, count);
+    for (intptr_t i = start_index_ + first_element_; i < stop_index_; i++) {
+      table.FillGap(d->ReadUnsigned());
+      table.WriteElement(d, d->Ref(i));
+    }
+    table_ = table.Finish();
+  }
+
+ protected:
+  const bool is_root_unit_;
+  intptr_t first_element_;
+  Array& table_;
+
+  void VerifyCanonicalSet(Deserializer* d,
+                          const Array& refs,
+                          const Array& current_table) {
+#if defined(DEBUG)
+    // First check that we are not overwriting a table and loosing information.
+    if (!current_table.IsNull()) {
+      SetType current_set(d->zone(), current_table.ptr());
+      ASSERT(current_set.NumOccupied() == 0);
+      current_set.Release();
+    }
+
+    // Now check that manually created table behaves correctly as a canonical
+    // set.
+    SetType canonical_set(d->zone(), table_.ptr());
+    Object& key = Object::Handle();
+    for (intptr_t i = start_index_ + first_element_; i < stop_index_; i++) {
+      key = refs.At(i);
+      ASSERT(canonical_set.GetOrNull(key) != Object::null());
+    }
+    canonical_set.Release();
+#endif  // defined(DEBUG)
+  }
+
+ private:
+  struct DeserializationFinger {
+    ArrayPtr table;
+    intptr_t current_index;
+    ObjectPtr gap_element;
+
+    void FillGap(int length) {
+      for (intptr_t j = 0; j < length; j++) {
+        table->untag()->data()[current_index + j] = gap_element;
+      }
+      current_index += length;
+    }
+
+    void WriteElement(Deserializer* d, ObjectPtr object) {
+      table->untag()->data()[current_index++] = object;
+    }
+
+    ArrayPtr Finish() {
+      if (table != Array::null()) {
+        FillGap(Smi::Value(table->untag()->length_) - current_index);
+      }
+      auto result = table;
+      table = Array::null();
+      return result;
+    }
+  };
+
+  static DeserializationFinger StartDeserialization(Deserializer* d,
+                                                    intptr_t length,
+                                                    intptr_t count) {
+    const intptr_t instance_size = Array::InstanceSize(length);
+    ArrayPtr table = static_cast<ArrayPtr>(
+        AllocateUninitialized(d->heap()->old_space(), instance_size));
+    Deserializer::InitializeHeader(table, kArrayCid, instance_size);
+    table->untag()->type_arguments_ = TypeArguments::null();
+    table->untag()->length_ = Smi::New(length);
+    for (intptr_t i = 0; i < SetType::kFirstKeyIndex; i++) {
+      table->untag()->data()[i] = Smi::New(0);
+    }
+    table->untag()->data()[SetType::kOccupiedEntriesIndex] = Smi::New(count);
+    return {table, SetType::kFirstKeyIndex, SetType::UnusedMarker().ptr()};
+  }
+};
+
+#if !defined(DART_PRECOMPILED_RUNTIME)
+class TypeArgumentsSerializationCluster
+    : public CanonicalSetSerializationCluster<CanonicalTypeArgumentsSet,
+                                              TypeArguments,
+                                              TypeArgumentsPtr> {
+ public:
+  explicit TypeArgumentsSerializationCluster(bool represents_canonical_set)
+      : CanonicalSetSerializationCluster(represents_canonical_set,
+                                         "TypeArguments") {}
   ~TypeArgumentsSerializationCluster() {}
 
   void Trace(Serializer* s, ObjectPtr object) {
@@ -427,6 +709,7 @@
     s->WriteCid(kTypeArgumentsCid);
     const intptr_t count = objects_.length();
     s->WriteUnsigned(count);
+    ReorderObjects(s);
     for (intptr_t i = 0; i < count; i++) {
       TypeArgumentsPtr type_args = objects_[i];
       s->AssignRef(type_args);
@@ -436,6 +719,7 @@
       target_memory_size_ +=
           compiler::target::TypeArguments::InstanceSize(length);
     }
+    WriteCanonicalSetLayout(s);
   }
 
   void WriteFill(Serializer* s) {
@@ -455,16 +739,14 @@
       }
     }
   }
-
- private:
-  GrowableArray<TypeArgumentsPtr> objects_;
 };
 #endif  // !DART_PRECOMPILED_RUNTIME
 
-class TypeArgumentsDeserializationCluster : public DeserializationCluster {
+class TypeArgumentsDeserializationCluster
+    : public CanonicalSetDeserializationCluster<CanonicalTypeArgumentsSet> {
  public:
-  TypeArgumentsDeserializationCluster()
-      : DeserializationCluster("TypeArguments") {}
+  explicit TypeArgumentsDeserializationCluster(bool is_root_unit)
+      : CanonicalSetDeserializationCluster(is_root_unit, "TypeArguments") {}
   ~TypeArgumentsDeserializationCluster() {}
 
   void ReadAlloc(Deserializer* d, bool stamp_canonical) {
@@ -477,6 +759,7 @@
                                          TypeArguments::InstanceSize(length)));
     }
     stop_index_ = d->next_index();
+    BuildCanonicalSetFromLayout(d, stamp_canonical);
   }
 
   void ReadFill(Deserializer* d, bool stamp_canonical) {
@@ -498,12 +781,16 @@
   }
 
   void PostLoad(Deserializer* d, const Array& refs, bool canonicalize) {
-    if (canonicalize) {
-      Thread* thread = Thread::Current();
+    if (!table_.IsNull()) {
+      auto object_store = d->isolate_group()->object_store();
+      VerifyCanonicalSet(
+          d, refs, Array::Handle(object_store->canonical_type_arguments()));
+      object_store->set_canonical_type_arguments(table_);
+    } else if (canonicalize) {
       TypeArguments& type_arg = TypeArguments::Handle(d->zone());
       for (intptr_t i = start_index_; i < stop_index_; i++) {
         type_arg ^= refs.At(i);
-        type_arg = type_arg.Canonicalize(thread, nullptr);
+        type_arg = type_arg.Canonicalize(d->thread(), nullptr);
         refs.SetAt(i, type_arg);
       }
     }
@@ -598,11 +885,11 @@
 
     PushFromTo(func);
     if (kind == Snapshot::kFullAOT) {
-      s->Push(func->untag()->code_);
+      s->Push(func->untag()->code());
     } else if (kind == Snapshot::kFullJIT) {
-      NOT_IN_PRECOMPILED(s->Push(func->untag()->unoptimized_code_));
-      s->Push(func->untag()->code_);
-      s->Push(func->untag()->ic_data_array_);
+      NOT_IN_PRECOMPILED(s->Push(func->untag()->unoptimized_code()));
+      s->Push(func->untag()->code());
+      s->Push(func->untag()->ic_data_array());
     }
   }
 
@@ -624,11 +911,11 @@
       AutoTraceObjectName(func, MakeDisambiguatedFunctionName(s, func));
       WriteFromTo(func);
       if (kind == Snapshot::kFullAOT) {
-        WriteField(func, code_);
+        WriteCompressedField(func, code);
       } else if (s->kind() == Snapshot::kFullJIT) {
-        NOT_IN_PRECOMPILED(WriteField(func, unoptimized_code_));
-        WriteField(func, code_);
-        WriteField(func, ic_data_array_);
+        NOT_IN_PRECOMPILED(WriteCompressedField(func, unoptimized_code));
+        WriteCompressedField(func, code);
+        WriteCompressedField(func, ic_data_array);
       }
 
       if (kind != Snapshot::kFullAOT) {
@@ -732,12 +1019,12 @@
       Function& func = Function::Handle(d->zone());
       for (intptr_t i = start_index_; i < stop_index_; i++) {
         func ^= refs.At(i);
-        ASSERT(func.ptr()->untag()->code_->IsCode());
-        uword entry_point = func.ptr()->untag()->code_->untag()->entry_point_;
+        ASSERT(func.ptr()->untag()->code()->IsCode());
+        uword entry_point = func.ptr()->untag()->code()->untag()->entry_point_;
         ASSERT(entry_point != 0);
         func.ptr()->untag()->entry_point_ = entry_point;
         uword unchecked_entry_point =
-            func.ptr()->untag()->code_->untag()->unchecked_entry_point_;
+            func.ptr()->untag()->code()->untag()->unchecked_entry_point_;
         ASSERT(unchecked_entry_point != 0);
         func.ptr()->untag()->unchecked_entry_point_ = unchecked_entry_point;
       }
@@ -777,12 +1064,11 @@
     objects_.Add(data);
 
     if (s->kind() != Snapshot::kFullAOT) {
-      s->Push(data->untag()->context_scope_);
+      s->Push(data->untag()->context_scope());
     }
-    s->Push(data->untag()->parent_function_);
-    s->Push(data->untag()->closure_);
-    s->Push(data->untag()->default_type_arguments_);
-    s->Push(data->untag()->default_type_arguments_info_);
+    s->Push(data->untag()->parent_function());
+    s->Push(data->untag()->closure());
+    s->Push(data->untag()->default_type_arguments());
   }
 
   void WriteAlloc(Serializer* s) {
@@ -801,12 +1087,13 @@
       ClosureDataPtr data = objects_[i];
       AutoTraceObject(data);
       if (s->kind() != Snapshot::kFullAOT) {
-        WriteField(data, context_scope_);
+        WriteCompressedField(data, context_scope);
       }
-      WriteField(data, parent_function_);
-      WriteField(data, closure_);
-      WriteField(data, default_type_arguments_);
-      WriteField(data, default_type_arguments_info_);
+      WriteCompressedField(data, parent_function);
+      WriteCompressedField(data, closure);
+      WriteCompressedField(data, default_type_arguments);
+      s->WriteUnsigned(
+          static_cast<intptr_t>(data->untag()->default_type_arguments_kind_));
     }
   }
 
@@ -847,8 +1134,8 @@
       data->untag()->closure_ = static_cast<InstancePtr>(d->ReadRef());
       data->untag()->default_type_arguments_ =
           static_cast<TypeArgumentsPtr>(d->ReadRef());
-      data->untag()->default_type_arguments_info_ =
-          static_cast<SmiPtr>(d->ReadRef());
+      data->untag()->default_type_arguments_kind_ =
+          static_cast<ClosureData::DefaultTypeArgumentsKind>(d->ReadUnsigned());
     }
   }
 };
@@ -888,7 +1175,7 @@
         s->WriteUnsigned(data->untag()->callback_id_);
       } else {
         // FFI callbacks can only be written to AOT snapshots.
-        ASSERT(data->untag()->callback_target_ == Object::null());
+        ASSERT(data->untag()->callback_target() == Object::null());
       }
     }
   }
@@ -942,22 +1229,22 @@
 
     Snapshot::Kind kind = s->kind();
 
-    s->Push(field->untag()->name_);
-    s->Push(field->untag()->owner_);
-    s->Push(field->untag()->type_);
+    s->Push(field->untag()->name());
+    s->Push(field->untag()->owner());
+    s->Push(field->untag()->type());
     // Write out the initializer function
-    s->Push(field->untag()->initializer_function_);
+    s->Push(field->untag()->initializer_function());
 
     if (kind != Snapshot::kFullAOT) {
-      s->Push(field->untag()->guarded_list_length_);
+      s->Push(field->untag()->guarded_list_length());
     }
     if (kind == Snapshot::kFullJIT) {
-      s->Push(field->untag()->dependent_code_);
+      s->Push(field->untag()->dependent_code());
     }
     // Write out either the initial static value or field offset.
     if (Field::StaticBit::decode(field->untag()->kind_bits_)) {
       const intptr_t field_id =
-          Smi::Value(field->untag()->host_offset_or_field_id_);
+          Smi::Value(field->untag()->host_offset_or_field_id());
       s->Push(s->initial_field_table()->At(field_id));
     } else {
       s->Push(Smi::New(Field::TargetOffsetOf(field)));
@@ -979,18 +1266,18 @@
     const intptr_t count = objects_.length();
     for (intptr_t i = 0; i < count; i++) {
       FieldPtr field = objects_[i];
-      AutoTraceObjectName(field, field->untag()->name_);
+      AutoTraceObjectName(field, field->untag()->name());
 
-      WriteField(field, name_);
-      WriteField(field, owner_);
-      WriteField(field, type_);
+      WriteCompressedField(field, name);
+      WriteCompressedField(field, owner);
+      WriteCompressedField(field, type);
       // Write out the initializer function and initial value if not in AOT.
-      WriteField(field, initializer_function_);
+      WriteCompressedField(field, initializer_function);
       if (kind != Snapshot::kFullAOT) {
-        WriteField(field, guarded_list_length_);
+        WriteCompressedField(field, guarded_list_length);
       }
       if (kind == Snapshot::kFullJIT) {
-        WriteField(field, dependent_code_);
+        WriteCompressedField(field, dependent_code);
       }
 
       if (kind != Snapshot::kFullAOT) {
@@ -1006,7 +1293,7 @@
       // Write out either the initial static value or field offset.
       if (Field::StaticBit::decode(field->untag()->kind_bits_)) {
         const intptr_t field_id =
-            Smi::Value(field->untag()->host_offset_or_field_id_);
+            Smi::Value(field->untag()->host_offset_or_field_id());
         WriteFieldValue("static value", s->initial_field_table()->At(field_id));
         s->WriteUnsigned(field_id);
       } else {
@@ -1086,7 +1373,7 @@
             Smi::RawCast(value_or_offset);
 #if !defined(DART_PRECOMPILED_RUNTIME)
         field->untag()->target_offset_ =
-            Smi::Value(field->untag()->host_offset_or_field_id_);
+            Smi::Value(field->untag()->host_offset_or_field_id());
 #endif  //  !defined(DART_PRECOMPILED_RUNTIME)
       }
     }
@@ -1142,7 +1429,7 @@
     const intptr_t count = objects_.length();
     for (intptr_t i = 0; i < count; i++) {
       ScriptPtr script = objects_[i];
-      AutoTraceObjectName(script, script->untag()->url_);
+      AutoTraceObjectName(script, script->untag()->url());
       WriteFromTo(script);
       s->Write<int32_t>(script->untag()->line_offset_);
       s->Write<int32_t>(script->untag()->col_offset_);
@@ -1226,7 +1513,7 @@
     const intptr_t count = objects_.length();
     for (intptr_t i = 0; i < count; i++) {
       LibraryPtr lib = objects_[i];
-      AutoTraceObjectName(lib, lib->untag()->url_);
+      AutoTraceObjectName(lib, lib->untag()->url());
       WriteFromTo(lib);
       s->Write<int32_t>(lib->untag()->index_);
       s->Write<uint16_t>(lib->untag()->num_imports_);
@@ -2051,8 +2338,9 @@
       intptr_t restore_position = d->position();
       d->set_position(fill_position_);
 
-      ObjectPool& pool = ObjectPool::Handle();
-      Object& entry = Object::Handle();
+      auto Z = d->zone();
+      ObjectPool& pool = ObjectPool::Handle(Z);
+      Object& entry = Object::Handle(Z);
       for (intptr_t id = start_index_; id < stop_index_; id++) {
         pool ^= refs.At(id);
         const intptr_t length = d->ReadUnsigned();
@@ -2374,12 +2662,20 @@
 
 #if !defined(DART_PRECOMPILED_RUNTIME) && !defined(DART_COMPRESSED_POINTERS)
 // PcDescriptor, CompressedStackMaps, OneByteString, TwoByteString
-class RODataSerializationCluster : public SerializationCluster {
+class RODataSerializationCluster
+    : public CanonicalSetSerializationCluster<CanonicalStringSet,
+                                              String,
+                                              ObjectPtr> {
  public:
-  RODataSerializationCluster(Zone* zone, const char* type, intptr_t cid)
-      : SerializationCluster(ImageWriter::TagObjectTypeAsReadOnly(zone, type)),
+  RODataSerializationCluster(Zone* zone,
+                             const char* type,
+                             intptr_t cid,
+                             bool is_canonical)
+      : CanonicalSetSerializationCluster(
+            is_canonical && IsStringClassId(cid),
+            ImageWriter::TagObjectTypeAsReadOnly(zone, type)),
+        zone_(zone),
         cid_(cid),
-        objects_(),
         type_(type) {}
   ~RODataSerializationCluster() {}
 
@@ -2399,15 +2695,18 @@
   }
 
   void WriteAlloc(Serializer* s) {
+    const bool is_string_cluster = IsStringClassId(cid_);
     s->WriteCid(cid_);
 
     intptr_t count = objects_.length();
     s->WriteUnsigned(count);
+    ReorderObjects(s);
+
     uint32_t running_offset = 0;
     for (intptr_t i = 0; i < count; i++) {
       ObjectPtr object = objects_[i];
       s->AssignRef(object);
-      if (cid_ == kOneByteStringCid || cid_ == kTwoByteStringCid) {
+      if (is_string_cluster) {
         s->TraceStartWritingObject(type_, object, String::RawCast(object));
       } else {
         s->TraceStartWritingObject(type_, object, nullptr);
@@ -2422,6 +2721,7 @@
       running_offset = offset;
       s->TraceEndWritingObject();
     }
+    WriteCanonicalSetLayout(s);
   }
 
   void WriteFill(Serializer* s) {
@@ -2429,17 +2729,18 @@
   }
 
  private:
+  Zone* zone_;
   const intptr_t cid_;
-  GrowableArray<ObjectPtr> objects_;
   const char* const type_;
 };
 #endif  // !DART_PRECOMPILED_RUNTIME && !DART_COMPRESSED_POINTERS
 
 #if !defined(DART_COMPRESSED_POINTERS)
-class RODataDeserializationCluster : public DeserializationCluster {
+class RODataDeserializationCluster
+    : public CanonicalSetDeserializationCluster<CanonicalStringSet> {
  public:
-  explicit RODataDeserializationCluster(intptr_t cid)
-      : DeserializationCluster("ROData"), cid_(cid) {}
+  explicit RODataDeserializationCluster(bool is_root_unit, intptr_t cid)
+      : CanonicalSetDeserializationCluster(is_root_unit, "ROData"), cid_(cid) {}
   ~RODataDeserializationCluster() {}
 
   void ReadAlloc(Deserializer* d, bool stamp_canonical) {
@@ -2448,9 +2749,11 @@
     uint32_t running_offset = 0;
     for (intptr_t i = 0; i < count; i++) {
       running_offset += d->ReadUnsigned() << kObjectAlignmentLog2;
-      d->AssignRef(d->GetObjectAt(running_offset));
+      ObjectPtr object = d->GetObjectAt(running_offset);
+      d->AssignRef(object);
     }
     stop_index_ = d->next_index();
+    BuildCanonicalSetFromLayout(d, cid_ == kStringCid);
   }
 
   void ReadFill(Deserializer* d, bool stamp_canonical) {
@@ -2458,7 +2761,14 @@
   }
 
   void PostLoad(Deserializer* d, const Array& refs, bool canonicalize) {
-    if (canonicalize) {
+    if (!table_.IsNull()) {
+      auto object_store = d->isolate_group()->object_store();
+      VerifyCanonicalSet(d, refs, Array::Handle(object_store->symbol_table()));
+      object_store->set_symbol_table(table_);
+      if (d->isolate_group() == Dart::vm_isolate_group()) {
+        Symbols::InitFromSnapshot(d->isolate_group());
+      }
+    } else if (canonicalize) {
       FATAL("Cannot recanonicalize RO objects.");
     }
   }
@@ -2479,7 +2789,7 @@
     ExceptionHandlersPtr handlers = ExceptionHandlers::RawCast(object);
     objects_.Add(handlers);
 
-    s->Push(handlers->untag()->handled_types_data_);
+    s->Push(handlers->untag()->handled_types_data());
   }
 
   void WriteAlloc(Serializer* s) {
@@ -2504,7 +2814,7 @@
       AutoTraceObject(handlers);
       const intptr_t length = handlers->untag()->num_entries_;
       s->WriteUnsigned(length);
-      WriteField(handlers, handled_types_data_);
+      WriteCompressedField(handlers, handled_types_data);
       for (intptr_t j = 0; j < length; j++) {
         const ExceptionHandlerInfo& info = handlers->untag()->data()[j];
         s->Write<uint32_t>(info.handler_pc_offset);
@@ -2939,13 +3249,6 @@
       // In --use-bare-instruction we reduce the extra indirection via the
       // [Function] object by storing the entry point directly into the hashmap.
       //
-      // Currently our AOT compiler will emit megamorphic calls in certain
-      // situations (namely in slow-path code of CheckedSmi* instructions).
-      //
-      // TODO(compiler-team): Change the CheckedSmi* slow path code to use
-      // normal switchable calls instead of megamorphic calls. (This is also a
-      // memory balance beause [MegamorphicCache]s are per-selector while
-      // [ICData] are per-callsite.)
       auto& cache = MegamorphicCache::Handle(d->zone());
       for (intptr_t i = start_index_; i < stop_index_; ++i) {
         cache ^= refs.At(i);
@@ -3034,7 +3337,7 @@
   void Trace(Serializer* s, ObjectPtr object) {
     LoadingUnitPtr unit = LoadingUnit::RawCast(object);
     objects_.Add(unit);
-    s->Push(unit->untag()->parent_);
+    s->Push(unit->untag()->parent());
   }
 
   void WriteAlloc(Serializer* s) {
@@ -3052,7 +3355,7 @@
     for (intptr_t i = 0; i < count; i++) {
       LoadingUnitPtr unit = objects_[i];
       AutoTraceObject(unit);
-      WriteField(unit, parent_);
+      WriteCompressedField(unit, parent);
       s->Write<int32_t>(unit->untag()->id_);
     }
   }
@@ -3333,13 +3636,12 @@
  public:
   void PostLoad(Deserializer* d, const Array& refs, bool canonicalize) {
     if (canonicalize) {
-      Thread* thread = Thread::Current();
       SafepointMutexLocker ml(
-          thread->isolate_group()->constant_canonicalization_mutex());
+          d->isolate_group()->constant_canonicalization_mutex());
       Instance& instance = Instance::Handle(d->zone());
       for (intptr_t i = start_index_; i < stop_index_; i++) {
         instance ^= refs.At(i);
-        instance = instance.CanonicalizeLocked(thread);
+        instance = instance.CanonicalizeLocked(d->thread());
         refs.SetAt(i, instance);
       }
     }
@@ -3482,10 +3784,18 @@
 static constexpr intptr_t kNullabilityBitMask = (1 << kNullabilityBitSize) - 1;
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
-class TypeSerializationCluster : public SerializationCluster {
+class TypeSerializationCluster
+    : public CanonicalSetSerializationCluster<
+          CanonicalTypeSet,
+          Type,
+          TypePtr,
+          /*kAllCanonicalObjectsAreIncludedIntoSet=*/false> {
  public:
-  TypeSerializationCluster()
-      : SerializationCluster("Type", compiler::target::Type::InstanceSize()) {}
+  explicit TypeSerializationCluster(bool represents_canonical_set)
+      : CanonicalSetSerializationCluster(
+            represents_canonical_set,
+            "Type",
+            compiler::target::Type::InstanceSize()) {}
   ~TypeSerializationCluster() {}
 
   void Trace(Serializer* s, ObjectPtr object) {
@@ -3494,12 +3804,12 @@
 
     PushFromTo(type);
 
-    if (type->untag()->type_class_id_->IsHeapObject()) {
+    if (type->untag()->type_class_id()->IsHeapObject()) {
       // Type class is still an unresolved class.
       UNREACHABLE();
     }
 
-    SmiPtr raw_type_class_id = Smi::RawCast(type->untag()->type_class_id_);
+    SmiPtr raw_type_class_id = Smi::RawCast(type->untag()->type_class_id());
     ClassPtr type_class =
         s->isolate_group()->class_table()->At(Smi::Value(raw_type_class_id));
     s->Push(type_class);
@@ -3509,10 +3819,12 @@
     s->WriteCid(kTypeCid);
     intptr_t count = objects_.length();
     s->WriteUnsigned(count);
+    ReorderObjects(s);
     for (intptr_t i = 0; i < count; i++) {
       TypePtr type = objects_[i];
       s->AssignRef(type);
     }
+    WriteCanonicalSetLayout(s);
   }
 
   void WriteFill(Serializer* s) {
@@ -3523,6 +3835,27 @@
   }
 
  private:
+  Type& type_ = Type::Handle();
+  Class& cls_ = Class::Handle();
+
+  // Type::Canonicalize does not actually put all canonical Type objects into
+  // canonical_types set. Some of the canonical declaration types (but not all
+  // of them) are simply cached in UntaggedClass::declaration_type_ and are not
+  // inserted into the canonical_types set.
+  // Keep in sync with Type::Canonicalize.
+  virtual bool IsInCanonicalSet(Serializer* s, TypePtr type) {
+    SmiPtr raw_type_class_id = Smi::RawCast(type->untag()->type_class_id());
+    ClassPtr type_class =
+        s->isolate_group()->class_table()->At(Smi::Value(raw_type_class_id));
+    if (type_class->untag()->declaration_type() != type) {
+      return true;
+    }
+
+    type_ = type;
+    cls_ = type_class;
+    return !type_.IsDeclarationTypeOf(cls_);
+  }
+
   void WriteType(Serializer* s, TypePtr type) {
     AutoTraceObject(type);
     WriteFromTo(type);
@@ -3538,14 +3871,16 @@
     ASSERT_EQUAL(type->untag()->nullability_, combined & kNullabilityBitMask);
     s->Write<uint8_t>(combined);
   }
-
-  GrowableArray<TypePtr> objects_;
 };
 #endif  // !DART_PRECOMPILED_RUNTIME
 
-class TypeDeserializationCluster : public DeserializationCluster {
+class TypeDeserializationCluster
+    : public CanonicalSetDeserializationCluster<
+          CanonicalTypeSet,
+          /*kAllCanonicalObjectsAreIncludedIntoSet=*/false> {
  public:
-  TypeDeserializationCluster() : DeserializationCluster("Type") {}
+  explicit TypeDeserializationCluster(bool is_root_unit)
+      : CanonicalSetDeserializationCluster(is_root_unit, "Type") {}
   ~TypeDeserializationCluster() {}
 
   void ReadAlloc(Deserializer* d, bool stamp_canonical) {
@@ -3553,9 +3888,11 @@
     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, Type::InstanceSize()));
+      ObjectPtr object = AllocateUninitialized(old_space, Type::InstanceSize());
+      d->AssignRef(object);
     }
     stop_index_ = d->next_index();
+    BuildCanonicalSetFromLayout(d, stamp_canonical);
   }
 
   void ReadFill(Deserializer* d, bool stamp_canonical) {
@@ -3571,12 +3908,16 @@
   }
 
   void PostLoad(Deserializer* d, const Array& refs, bool canonicalize) {
-    if (canonicalize) {
-      Thread* thread = Thread::Current();
+    if (!table_.IsNull()) {
+      auto object_store = d->isolate_group()->object_store();
+      VerifyCanonicalSet(d, refs,
+                         Array::Handle(object_store->canonical_types()));
+      object_store->set_canonical_types(table_);
+    } else if (canonicalize) {
       AbstractType& type = AbstractType::Handle(d->zone());
       for (intptr_t i = start_index_; i < stop_index_; i++) {
         type ^= refs.At(i);
-        type = type.Canonicalize(thread, nullptr);
+        type = type.Canonicalize(d->thread(), nullptr);
         refs.SetAt(i, type);
       }
     }
@@ -3601,11 +3942,16 @@
 };
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
-class FunctionTypeSerializationCluster : public SerializationCluster {
+class FunctionTypeSerializationCluster
+    : public CanonicalSetSerializationCluster<CanonicalFunctionTypeSet,
+                                              FunctionType,
+                                              FunctionTypePtr> {
  public:
-  FunctionTypeSerializationCluster()
-      : SerializationCluster("FunctionType",
-                             compiler::target::FunctionType::InstanceSize()) {}
+  explicit FunctionTypeSerializationCluster(bool represents_canonical_set)
+      : CanonicalSetSerializationCluster(
+            represents_canonical_set,
+            "FunctionType",
+            compiler::target::FunctionType::InstanceSize()) {}
   ~FunctionTypeSerializationCluster() {}
 
   void Trace(Serializer* s, ObjectPtr object) {
@@ -3618,10 +3964,13 @@
     s->WriteCid(kFunctionTypeCid);
     intptr_t count = objects_.length();
     s->WriteUnsigned(count);
+    ReorderObjects(s);
+
     for (intptr_t i = 0; i < count; i++) {
       FunctionTypePtr type = objects_[i];
       s->AssignRef(type);
     }
+    WriteCanonicalSetLayout(s);
   }
 
   void WriteFill(Serializer* s) {
@@ -3650,15 +3999,14 @@
     s->Write<uint8_t>(combined);
     s->Write<uint32_t>(type->untag()->packed_fields_);
   }
-
-  GrowableArray<FunctionTypePtr> objects_;
 };
 #endif  // !DART_PRECOMPILED_RUNTIME
 
-class FunctionTypeDeserializationCluster : public DeserializationCluster {
+class FunctionTypeDeserializationCluster
+    : public CanonicalSetDeserializationCluster<CanonicalFunctionTypeSet> {
  public:
-  FunctionTypeDeserializationCluster()
-      : DeserializationCluster("FunctionType") {}
+  explicit FunctionTypeDeserializationCluster(bool is_root_unit)
+      : CanonicalSetDeserializationCluster(is_root_unit, "FunctionType") {}
   ~FunctionTypeDeserializationCluster() {}
 
   void ReadAlloc(Deserializer* d, bool stamp_canonical) {
@@ -3666,10 +4014,12 @@
     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, FunctionType::InstanceSize()));
+      ObjectPtr object =
+          AllocateUninitialized(old_space, FunctionType::InstanceSize());
+      d->AssignRef(object);
     }
     stop_index_ = d->next_index();
+    BuildCanonicalSetFromLayout(d, stamp_canonical);
   }
 
   void ReadFill(Deserializer* d, bool stamp_canonical) {
@@ -3687,12 +4037,16 @@
   }
 
   void PostLoad(Deserializer* d, const Array& refs, bool canonicalize) {
-    if (canonicalize) {
-      Thread* thread = Thread::Current();
+    if (!table_.IsNull()) {
+      auto object_store = d->isolate_group()->object_store();
+      VerifyCanonicalSet(
+          d, refs, Array::Handle(object_store->canonical_function_types()));
+      object_store->set_canonical_function_types(table_);
+    } else if (canonicalize) {
       AbstractType& type = AbstractType::Handle(d->zone());
       for (intptr_t i = start_index_; i < stop_index_; i++) {
         type ^= refs.At(i);
-        type = type.Canonicalize(thread, nullptr);
+        type = type.Canonicalize(d->thread(), nullptr);
         refs.SetAt(i, type);
       }
     }
@@ -3780,11 +4134,10 @@
 
   void PostLoad(Deserializer* d, const Array& refs, bool canonicalize) {
     if (canonicalize) {
-      Thread* thread = Thread::Current();
       AbstractType& type = AbstractType::Handle(d->zone());
       for (intptr_t i = start_index_; i < stop_index_; i++) {
         type ^= refs.At(i);
-        type = type.Canonicalize(thread, nullptr);
+        type = type.Canonicalize(d->thread(), nullptr);
         refs.SetAt(i, type);
       }
     }
@@ -3810,11 +4163,17 @@
 };
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
-class TypeParameterSerializationCluster : public SerializationCluster {
+class TypeParameterSerializationCluster
+    : public CanonicalSetSerializationCluster<CanonicalTypeParameterSet,
+                                              TypeParameter,
+                                              TypeParameterPtr> {
  public:
-  TypeParameterSerializationCluster()
-      : SerializationCluster("TypeParameter",
-                             compiler::target::TypeParameter::InstanceSize()) {}
+  explicit TypeParameterSerializationCluster(
+      bool cluster_represents_canonical_set)
+      : CanonicalSetSerializationCluster(
+            cluster_represents_canonical_set,
+            "TypeParameter",
+            compiler::target::TypeParameter::InstanceSize()) {}
   ~TypeParameterSerializationCluster() {}
 
   void Trace(Serializer* s, ObjectPtr object) {
@@ -3828,10 +4187,12 @@
     s->WriteCid(kTypeParameterCid);
     intptr_t count = objects_.length();
     s->WriteUnsigned(count);
+    ReorderObjects(s);
     for (intptr_t i = 0; i < count; i++) {
       TypeParameterPtr type = objects_[i];
       s->AssignRef(type);
     }
+    WriteCanonicalSetLayout(s);
   }
 
   void WriteFill(Serializer* s) {
@@ -3859,15 +4220,14 @@
     ASSERT_EQUAL(type->untag()->nullability_, combined & kNullabilityBitMask);
     s->Write<uint8_t>(combined);
   }
-
-  GrowableArray<TypeParameterPtr> objects_;
 };
 #endif  // !DART_PRECOMPILED_RUNTIME
 
-class TypeParameterDeserializationCluster : public DeserializationCluster {
+class TypeParameterDeserializationCluster
+    : public CanonicalSetDeserializationCluster<CanonicalTypeParameterSet> {
  public:
-  TypeParameterDeserializationCluster()
-      : DeserializationCluster("TypeParameter") {}
+  explicit TypeParameterDeserializationCluster(bool is_root_unit)
+      : CanonicalSetDeserializationCluster(is_root_unit, "TypeParameter") {}
   ~TypeParameterDeserializationCluster() {}
 
   void ReadAlloc(Deserializer* d, bool stamp_canonical) {
@@ -3879,6 +4239,7 @@
           AllocateUninitialized(old_space, TypeParameter::InstanceSize()));
     }
     stop_index_ = d->next_index();
+    BuildCanonicalSetFromLayout(d, stamp_canonical);
   }
 
   void ReadFill(Deserializer* d, bool stamp_canonical) {
@@ -3898,12 +4259,16 @@
   }
 
   void PostLoad(Deserializer* d, const Array& refs, bool canonicalize) {
-    if (canonicalize) {
-      Thread* thread = Thread::Current();
+    if (!table_.IsNull()) {
+      auto object_store = d->isolate_group()->object_store();
+      VerifyCanonicalSet(
+          d, refs, Array::Handle(object_store->canonical_type_parameters()));
+      object_store->set_canonical_type_parameters(table_);
+    } else if (canonicalize) {
       TypeParameter& type_param = TypeParameter::Handle(d->zone());
       for (intptr_t i = start_index_; i < stop_index_; i++) {
         type_param ^= refs.At(i);
-        type_param ^= type_param.Canonicalize(thread, nullptr);
+        type_param ^= type_param.Canonicalize(d->thread(), nullptr);
         refs.SetAt(i, type_param);
       }
     }
@@ -4066,13 +4431,12 @@
 
   void PostLoad(Deserializer* d, const Array& refs, bool canonicalize) {
     if (canonicalize) {
-      Thread* thread = Thread::Current();
       const Class& mint_cls = Class::Handle(
           d->zone(), d->isolate_group()->object_store()->mint_class());
       Object& number = Object::Handle(d->zone());
       Mint& number2 = Mint::Handle(d->zone());
       SafepointMutexLocker ml(
-          thread->isolate_group()->constant_canonicalization_mutex());
+          d->isolate_group()->constant_canonicalization_mutex());
       for (intptr_t i = start_index_; i < stop_index_; i++) {
         number = refs.At(i);
         if (!number.IsMint()) continue;
@@ -4152,18 +4516,19 @@
 
   void PostLoad(Deserializer* d, const Array& refs, bool canonicalize) {
     if (canonicalize) {
-      const Class& cls = Class::Handle(
-          d->zone(), d->isolate_group()->object_store()->double_class());
-      SafepointMutexLocker ml(
-          d->isolate_group()->constant_canonicalization_mutex());
-      Double& dbl = Double::Handle(d->zone());
-      Double& dbl2 = Double::Handle(d->zone());
+      auto Z = d->zone();
+      auto isolate_group = d->isolate_group();
+      const Class& cls =
+          Class::Handle(Z, isolate_group->object_store()->double_class());
+      SafepointMutexLocker ml(isolate_group->constant_canonicalization_mutex());
+      Double& dbl = Double::Handle(Z);
+      Double& dbl2 = Double::Handle(Z);
       for (intptr_t i = start_index_; i < stop_index_; i++) {
         dbl ^= refs.At(i);
-        dbl2 = cls.LookupCanonicalDouble(d->zone(), dbl.value());
+        dbl2 = cls.LookupCanonicalDouble(Z, dbl.value());
         if (dbl2.IsNull()) {
           dbl.SetCanonical();
-          cls.InsertCanonicalDouble(d->zone(), dbl);
+          cls.InsertCanonicalDouble(Z, dbl);
         } else {
           refs.SetAt(i, dbl2);
         }
@@ -4262,7 +4627,7 @@
       TypedDataPtr data = objects_[i];
       s->AssignRef(data);
       AutoTraceObject(data);
-      const intptr_t length = Smi::Value(data->untag()->length_);
+      const intptr_t length = Smi::Value(data->untag()->length());
       s->WriteUnsigned(length);
       target_memory_size_ +=
           compiler::target::TypedData::InstanceSize(length * element_size);
@@ -4275,7 +4640,7 @@
     for (intptr_t i = 0; i < count; i++) {
       TypedDataPtr data = objects_[i];
       AutoTraceObject(data);
-      const intptr_t length = Smi::Value(data->untag()->length_);
+      const intptr_t length = Smi::Value(data->untag()->length());
       s->WriteUnsigned(length);
       uint8_t* cdata = reinterpret_cast<uint8_t*>(data->untag()->data());
       s->WriteBytes(cdata, length * element_size);
@@ -4440,7 +4805,7 @@
     for (intptr_t i = 0; i < count; i++) {
       ExternalTypedDataPtr data = objects_[i];
       AutoTraceObject(data);
-      const intptr_t length = Smi::Value(data->untag()->length_);
+      const intptr_t length = Smi::Value(data->untag()->length());
       s->WriteUnsigned(length);
       uint8_t* cdata = reinterpret_cast<uint8_t*>(data->untag()->data_);
       s->Align(ExternalTypedData::kDataSerializationAlignment);
@@ -4931,7 +5296,7 @@
       OneByteStringPtr str = objects_[i];
       s->AssignRef(str);
       AutoTraceObject(str);
-      const intptr_t length = Smi::Value(str->untag()->length_);
+      const intptr_t length = Smi::Value(str->untag()->length());
       s->WriteUnsigned(length);
       target_memory_size_ +=
           compiler::target::OneByteString::InstanceSize(length);
@@ -4943,7 +5308,7 @@
     for (intptr_t i = 0; i < count; i++) {
       OneByteStringPtr str = objects_[i];
       AutoTraceObject(str);
-      const intptr_t length = Smi::Value(str->untag()->length_);
+      const intptr_t length = Smi::Value(str->untag()->length());
       ASSERT(length <= compiler::target::kSmiMax);
       s->WriteUnsigned(length);
       s->WriteBytes(str->untag()->data(), length);
@@ -4963,13 +5328,13 @@
  public:
   void PostLoad(Deserializer* d, const Array& refs, bool canonicalize) {
     if (canonicalize) {
-      Thread* thread = Thread::Current();
-      SafepointMutexLocker ml(
-          thread->isolate_group()->constant_canonicalization_mutex());
-      CanonicalStringSet table(
-          d->zone(), d->isolate_group()->object_store()->symbol_table());
-      String& str = String::Handle(d->zone());
-      String& str2 = String::Handle(d->zone());
+      auto Z = d->zone();
+      auto isolate_group = d->isolate_group();
+      SafepointMutexLocker ml(isolate_group->constant_canonicalization_mutex());
+      CanonicalStringSet table(Z,
+                               isolate_group->object_store()->symbol_table());
+      String& str = String::Handle(Z);
+      String& str2 = String::Handle(Z);
       for (intptr_t i = start_index_; i < stop_index_; i++) {
         str ^= refs.At(i);
         str2 ^= table.InsertOrGet(str);
@@ -4979,7 +5344,7 @@
           refs.SetAt(i, str2);
         }
       }
-      d->isolate_group()->object_store()->set_symbol_table(table.Release());
+      isolate_group->object_store()->set_symbol_table(table.Release());
     }
   }
 };
@@ -5041,7 +5406,7 @@
       TwoByteStringPtr str = objects_[i];
       s->AssignRef(str);
       AutoTraceObject(str);
-      const intptr_t length = Smi::Value(str->untag()->length_);
+      const intptr_t length = Smi::Value(str->untag()->length());
       s->WriteUnsigned(length);
       target_memory_size_ +=
           compiler::target::TwoByteString::InstanceSize(length);
@@ -5053,7 +5418,7 @@
     for (intptr_t i = 0; i < count; i++) {
       TwoByteStringPtr str = objects_[i];
       AutoTraceObject(str);
-      const intptr_t length = Smi::Value(str->untag()->length_);
+      const intptr_t length = Smi::Value(str->untag()->length());
       ASSERT(length <= (compiler::target::kSmiMax / 2));
       s->WriteUnsigned(length);
       s->WriteBytes(reinterpret_cast<uint8_t*>(str->untag()->data()),
@@ -5128,8 +5493,10 @@
 #if !defined(DART_PRECOMPILED_RUNTIME)
 class VMSerializationRoots : public SerializationRoots {
  public:
-  explicit VMSerializationRoots(const Array& symbols)
-      : symbols_(symbols), zone_(Thread::Current()->zone()) {}
+  explicit VMSerializationRoots(const Array& symbols, bool should_write_symbols)
+      : symbols_(symbols),
+        should_write_symbols_(should_write_symbols),
+        zone_(Thread::Current()->zone()) {}
 
   void AddBaseObjects(Serializer* s) {
     // These objects are always allocated by Object::InitOnce, so they are not
@@ -5199,7 +5566,13 @@
   }
 
   void PushRoots(Serializer* s) {
-    s->Push(symbols_.ptr());
+    if (should_write_symbols_) {
+      s->Push(symbols_.ptr());
+    } else {
+      for (intptr_t i = 0; i < symbols_.Length(); i++) {
+        s->Push(symbols_.At(i));
+      }
+    }
     if (Snapshot::IncludesCode(s->kind())) {
       for (intptr_t i = 0; i < StubCode::NumEntries(); i++) {
         s->Push(StubCode::EntryAt(i).ptr());
@@ -5208,17 +5581,37 @@
   }
 
   void WriteRoots(Serializer* s) {
-    s->WriteRootRef(symbols_.ptr(), "symbol-table");
+    s->WriteRootRef(should_write_symbols_ ? symbols_.ptr() : Object::null(),
+                    "symbol-table");
     if (Snapshot::IncludesCode(s->kind())) {
       for (intptr_t i = 0; i < StubCode::NumEntries(); i++) {
         s->WriteRootRef(StubCode::EntryAt(i).ptr(),
                         zone_->PrintToString("Stub:%s", StubCode::NameAt(i)));
       }
     }
+
+    if (!should_write_symbols_ && s->profile_writer() != nullptr) {
+      // If writing V8 snapshot profile create an artifical node representing
+      // VM isolate symbol table.
+      auto symbols_ref = s->AssignArtificialRef(symbols_.ptr());
+      const V8SnapshotProfileWriter::ObjectId symbols_snapshot_id(
+          V8SnapshotProfileWriter::kSnapshot, symbols_ref);
+      s->profile_writer()->AddRoot(symbols_snapshot_id, "vm_symbols");
+      s->profile_writer()->SetObjectTypeAndName(symbols_snapshot_id, "Symbols",
+                                                nullptr);
+      for (intptr_t i = 0; i < symbols_.Length(); i++) {
+        const V8SnapshotProfileWriter::ObjectId code_id(
+            V8SnapshotProfileWriter::kSnapshot, s->RefId(symbols_.At(i)));
+        s->profile_writer()->AttributeReferenceTo(
+            symbols_snapshot_id,
+            {code_id, V8SnapshotProfileWriter::Reference::kElement, i});
+      }
+    }
   }
 
  private:
   const Array& symbols_;
+  const bool should_write_symbols_;
   Zone* zone_;
 };
 #endif  // !DART_PRECOMPILED_RUNTIME
@@ -5282,7 +5675,9 @@
 
   void ReadRoots(Deserializer* d) {
     symbol_table_ ^= d->ReadRef();
-    d->isolate_group()->object_store()->set_symbol_table(symbol_table_);
+    if (!symbol_table_.IsNull()) {
+      d->isolate_group()->object_store()->set_symbol_table(symbol_table_);
+    }
     if (Snapshot::IncludesCode(d->kind())) {
       for (intptr_t i = 0; i < StubCode::NumEntries(); i++) {
         Code* code = Code::ReadOnlyHandle();
@@ -5297,7 +5692,9 @@
     // allocations (e.g., FinalizeVMIsolate) before allocating new pages.
     d->heap()->old_space()->AbandonBumpAllocation();
 
-    Symbols::InitFromSnapshot(d->isolate_group());
+    if (!symbol_table_.IsNull()) {
+      Symbols::InitFromSnapshot(d->isolate_group());
+    }
 
     Object::set_vm_isolate_snapshot_object_table(refs);
   }
@@ -5319,29 +5716,51 @@
 class ProgramSerializationRoots : public SerializationRoots {
  public:
   ProgramSerializationRoots(ZoneGrowableArray<Object*>* base_objects,
-                            ObjectStore* object_store)
+                            ObjectStore* object_store,
+                            Snapshot::Kind snapshot_kind)
       : base_objects_(base_objects),
         object_store_(object_store),
-        dispatch_table_entries_(Array::Handle()) {
+        dispatch_table_entries_(Array::Handle()),
+        saved_symbol_table_(Array::Handle()),
+        saved_canonical_types_(Array::Handle()),
+        saved_canonical_function_types_(Array::Handle()),
+        saved_canonical_type_arguments_(Array::Handle()),
+        saved_canonical_type_parameters_(Array::Handle()) {
+    saved_symbol_table_ = object_store->symbol_table();
+    if (Snapshot::IncludesStringsInROData(snapshot_kind)) {
+      object_store->set_symbol_table(
+          Array::Handle(HashTables::New<CanonicalStringSet>(4)));
+    } else {
 #if defined(DART_PRECOMPILER)
-    if (FLAG_precompiled_mode) {
-      // Elements of constant tables are treated as weak so literals used only
-      // in deferred libraries do not end up in the main snapshot.
-      Array& table = Array::Handle();
-      table = object_store->symbol_table();
-      HashTables::Weaken(table);
-      table = object_store->canonical_types();
-      HashTables::Weaken(table);
-      table = object_store->canonical_function_types();
-      HashTables::Weaken(table);
-      table = object_store->canonical_type_parameters();
-      HashTables::Weaken(table);
-      table = object_store->canonical_type_arguments();
-      HashTables::Weaken(table);
-    }
+      if (FLAG_precompiled_mode) {
+        HashTables::Weaken(saved_symbol_table_);
+      }
 #endif
+    }
+    saved_canonical_types_ = object_store->canonical_types();
+    object_store->set_canonical_types(
+        Array::Handle(HashTables::New<CanonicalTypeSet>(4)));
+    saved_canonical_function_types_ = object_store->canonical_function_types();
+    object_store->set_canonical_function_types(
+        Array::Handle(HashTables::New<CanonicalFunctionTypeSet>(4)));
+    saved_canonical_type_arguments_ = object_store->canonical_type_arguments();
+    object_store->set_canonical_type_arguments(
+        Array::Handle(HashTables::New<CanonicalTypeArgumentsSet>(4)));
+    saved_canonical_type_parameters_ =
+        object_store->canonical_type_parameters();
+    object_store->set_canonical_type_parameters(
+        Array::Handle(HashTables::New<CanonicalTypeParameterSet>(4)));
   }
-  ~ProgramSerializationRoots() {}
+  ~ProgramSerializationRoots() {
+    object_store_->set_symbol_table(saved_symbol_table_);
+    object_store_->set_canonical_types(saved_canonical_types_);
+    object_store_->set_canonical_function_types(
+        saved_canonical_function_types_);
+    object_store_->set_canonical_type_arguments(
+        saved_canonical_type_arguments_);
+    object_store_->set_canonical_type_parameters(
+        saved_canonical_type_parameters_);
+  }
 
   void AddBaseObjects(Serializer* s) {
     if (base_objects_ == nullptr) {
@@ -5397,6 +5816,11 @@
   ZoneGrowableArray<Object*>* base_objects_;
   ObjectStore* object_store_;
   Array& dispatch_table_entries_;
+  Array& saved_symbol_table_;
+  Array& saved_canonical_types_;
+  Array& saved_canonical_function_types_;
+  Array& saved_canonical_type_arguments_;
+  Array& saved_canonical_type_parameters_;
 };
 #endif  // !DART_PRECOMPILED_RUNTIME
 
@@ -5427,7 +5851,7 @@
   }
 
   void PostLoad(Deserializer* d, const Array& refs) {
-    auto isolate_group = d->thread()->isolate_group();
+    auto isolate_group = d->isolate_group();
     isolate_group->class_table()->CopySizesFromClassObjects();
     d->heap()->old_space()->EvaluateAfterLoading();
 
@@ -5592,10 +6016,10 @@
 
     // Reinitialize the dispatch table by rereading the table's serialization
     // in the root snapshot.
-    IsolateGroup* group = d->thread()->isolate_group();
-    if (group->dispatch_table_snapshot() != nullptr) {
-      ReadStream stream(group->dispatch_table_snapshot(),
-                        group->dispatch_table_snapshot_size());
+    auto isolate_group = d->isolate_group();
+    if (isolate_group->dispatch_table_snapshot() != nullptr) {
+      ReadStream stream(isolate_group->dispatch_table_snapshot(),
+                        isolate_group->dispatch_table_snapshot_size());
       d->ReadDispatchTable(&stream);
     }
   }
@@ -5795,28 +6219,28 @@
       name = FunctionSerializationCluster::MakeDisambiguatedFunctionName(this,
                                                                          func);
       owner_ref_name = "owner_";
-      owner = func->untag()->owner_;
+      owner = func->untag()->owner();
       break;
     }
     case kClassCid: {
       ClassPtr cls = static_cast<ClassPtr>(obj);
       type = "Class";
-      name_string = cls->untag()->name_;
+      name_string = cls->untag()->name();
       owner_ref_name = "library_";
-      owner = cls->untag()->library_;
+      owner = cls->untag()->library();
       break;
     }
     case kPatchClassCid: {
       PatchClassPtr patch_cls = static_cast<PatchClassPtr>(obj);
       type = "PatchClass";
       owner_ref_name = "patched_class_";
-      owner = patch_cls->untag()->patched_class_;
+      owner = patch_cls->untag()->patched_class();
       break;
     }
     case kLibraryCid: {
       LibraryPtr lib = static_cast<LibraryPtr>(obj);
       type = "Library";
-      name_string = lib->untag()->url_;
+      name_string = lib->untag()->url();
       break;
     }
     default:
@@ -5855,6 +6279,9 @@
       return "CodeSourceMap";
     case kCompressedStackMapsCid:
       return "CompressedStackMaps";
+    case kStringCid:
+      RELEASE_ASSERT(current_loading_unit_id_ <= LoadingUnit::kRootId);
+      return "CanonicalString";
     case kOneByteStringCid:
       return current_loading_unit_id_ <= LoadingUnit::kRootId
                  ? "OneByteStringCid"
@@ -5868,7 +6295,8 @@
   }
 }
 
-SerializationCluster* Serializer::NewClusterForClass(intptr_t cid) {
+SerializationCluster* Serializer::NewClusterForClass(intptr_t cid,
+                                                     bool is_canonical) {
 #if defined(DART_PRECOMPILED_RUNTIME)
   UNREACHABLE();
   return NULL;
@@ -5899,16 +6327,20 @@
   // compressed pointers.
   if (Snapshot::IncludesCode(kind_)) {
     if (auto const type = ReadOnlyObjectType(cid)) {
-      return new (Z) RODataSerializationCluster(Z, type, cid);
+      return new (Z) RODataSerializationCluster(Z, type, cid, is_canonical);
     }
   }
 #endif
 
+  const bool cluster_represents_canonical_set =
+      current_loading_unit_id_ <= LoadingUnit::kRootId && is_canonical;
+
   switch (cid) {
     case kClassCid:
       return new (Z) ClassSerializationCluster(num_cids_ + num_tlc_cids_);
     case kTypeArgumentsCid:
-      return new (Z) TypeArgumentsSerializationCluster();
+      return new (Z)
+          TypeArgumentsSerializationCluster(cluster_represents_canonical_set);
     case kPatchClassCid:
       return new (Z) PatchClassSerializationCluster();
     case kFunctionCid:
@@ -5960,13 +6392,15 @@
     case kLibraryPrefixCid:
       return new (Z) LibraryPrefixSerializationCluster();
     case kTypeCid:
-      return new (Z) TypeSerializationCluster();
+      return new (Z) TypeSerializationCluster(cluster_represents_canonical_set);
     case kFunctionTypeCid:
-      return new (Z) FunctionTypeSerializationCluster();
+      return new (Z)
+          FunctionTypeSerializationCluster(cluster_represents_canonical_set);
     case kTypeRefCid:
       return new (Z) TypeRefSerializationCluster();
     case kTypeParameterCid:
-      return new (Z) TypeParameterSerializationCluster();
+      return new (Z)
+          TypeParameterSerializationCluster(cluster_represents_canonical_set);
     case kClosureCid:
       return new (Z) ClosureSerializationCluster();
     case kMintCid:
@@ -6195,11 +6629,16 @@
     cid = object->GetClassId();
     is_canonical = object->untag()->IsCanonical();
   }
+  if (Snapshot::IncludesStringsInROData(kind_) && is_canonical &&
+      IsStringClassId(cid) &&
+      current_loading_unit_id_ <= LoadingUnit::kRootId) {
+    cid = kStringCid;
+  }
 
   SerializationCluster** cluster_ref =
       is_canonical ? &canonical_clusters_by_cid_[cid] : &clusters_by_cid_[cid];
   if (*cluster_ref == nullptr) {
-    *cluster_ref = NewClusterForClass(cid);
+    *cluster_ref = NewClusterForClass(cid, is_canonical);
     if (*cluster_ref == nullptr) {
       UnexpectedObject(object, "No serialization cluster defined");
     }
@@ -6673,13 +7112,16 @@
       case kPcDescriptorsCid:
       case kCodeSourceMapCid:
       case kCompressedStackMapsCid:
-        return new (Z) RODataDeserializationCluster(cid);
+        return new (Z) RODataDeserializationCluster(!is_non_root_unit_, cid);
       case kOneByteStringCid:
       case kTwoByteStringCid:
         if (!is_non_root_unit_) {
-          return new (Z) RODataDeserializationCluster(cid);
+          return new (Z) RODataDeserializationCluster(!is_non_root_unit_, cid);
         }
         break;
+      case kStringCid:
+        RELEASE_ASSERT(!is_non_root_unit_);
+        return new (Z) RODataDeserializationCluster(!is_non_root_unit_, cid);
     }
   }
 #endif
@@ -6688,7 +7130,7 @@
     case kClassCid:
       return new (Z) ClassDeserializationCluster();
     case kTypeArgumentsCid:
-      return new (Z) TypeArgumentsDeserializationCluster();
+      return new (Z) TypeArgumentsDeserializationCluster(!is_non_root_unit_);
     case kPatchClassCid:
       return new (Z) PatchClassDeserializationCluster();
     case kFunctionCid:
@@ -6742,13 +7184,13 @@
     case kLibraryPrefixCid:
       return new (Z) LibraryPrefixDeserializationCluster();
     case kTypeCid:
-      return new (Z) TypeDeserializationCluster();
+      return new (Z) TypeDeserializationCluster(!is_non_root_unit_);
     case kFunctionTypeCid:
-      return new (Z) FunctionTypeDeserializationCluster();
+      return new (Z) FunctionTypeDeserializationCluster(!is_non_root_unit_);
     case kTypeRefCid:
       return new (Z) TypeRefDeserializationCluster();
     case kTypeParameterCid:
-      return new (Z) TypeParameterDeserializationCluster();
+      return new (Z) TypeParameterDeserializationCluster(!is_non_root_unit_);
     case kClosureCid:
       return new (Z) ClosureDeserializationCluster();
     case kMintCid:
@@ -7251,7 +7693,8 @@
   serializer.ReserveHeader();
   serializer.WriteVersionAndFeatures(true);
   VMSerializationRoots roots(
-      Array::Handle(Dart::vm_isolate_group()->object_store()->symbol_table()));
+      Array::Handle(Dart::vm_isolate_group()->object_store()->symbol_table()),
+      /*should_write_symbols=*/!Snapshot::IncludesStringsInROData(kind_));
   ZoneGrowableArray<Object*>* objects = serializer.Serialize(&roots);
   serializer.FillHeader(serializer.kind());
   clustered_vm_size_ = serializer.bytes_written();
@@ -7293,7 +7736,7 @@
 
   serializer.ReserveHeader();
   serializer.WriteVersionAndFeatures(false);
-  ProgramSerializationRoots roots(objects, object_store);
+  ProgramSerializationRoots roots(objects, object_store, kind_);
   objects = serializer.Serialize(&roots);
   if (units != nullptr) {
     (*units)[LoadingUnit::kRootId]->set_objects(objects);
diff --git a/runtime/vm/clustered_snapshot.h b/runtime/vm/clustered_snapshot.h
index 3262967..0888bbb 100644
--- a/runtime/vm/clustered_snapshot.h
+++ b/runtime/vm/clustered_snapshot.h
@@ -226,7 +226,7 @@
   ObjectPtr ParentOf(const Object& object);
 #endif
 
-  SerializationCluster* NewClusterForClass(intptr_t cid);
+  SerializationCluster* NewClusterForClass(intptr_t cid, bool is_canonical);
 
   void ReserveHeader() {
     // Make room for recording snapshot buffer size.
@@ -348,20 +348,21 @@
 
   template <typename T, typename... P>
   void WriteFromTo(T obj, P&&... args) {
-    ObjectPtr* from = obj->untag()->from();
-    ObjectPtr* to = obj->untag()->to_snapshot(kind(), args...);
-    for (ObjectPtr* p = from; p <= to; p++) {
-      WriteOffsetRef(*p, (p - reinterpret_cast<ObjectPtr*>(obj->untag())) *
-                             sizeof(ObjectPtr));
+    auto* from = obj->untag()->from();
+    auto* to = obj->untag()->to_snapshot(kind(), args...);
+    for (auto* p = from; p <= to; p++) {
+      WriteOffsetRef(
+          p->Decompress(obj->heap_base()),
+          reinterpret_cast<uword>(p) - reinterpret_cast<uword>(obj->untag()));
     }
   }
 
   template <typename T, typename... P>
   void PushFromTo(T obj, P&&... args) {
-    ObjectPtr* from = obj->untag()->from();
-    ObjectPtr* to = obj->untag()->to_snapshot(kind(), args...);
-    for (ObjectPtr* p = from; p <= to; p++) {
-      Push(*p);
+    auto* from = obj->untag()->from();
+    auto* to = obj->untag()->to_snapshot(kind(), args...);
+    for (auto* p = from; p <= to; p++) {
+      Push(p->Decompress(obj->heap_base()));
     }
   }
 
@@ -399,13 +400,13 @@
   bool CreateArtificalNodeIfNeeded(ObjectPtr obj);
 
   bool InCurrentLoadingUnit(ObjectPtr obj, bool record = false);
-  GrowableArray<LoadingUnitSerializationData*>* loading_units() {
+  GrowableArray<LoadingUnitSerializationData*>* loading_units() const {
     return loading_units_;
   }
   void set_loading_units(GrowableArray<LoadingUnitSerializationData*>* units) {
     loading_units_ = units;
   }
-  intptr_t current_loading_unit_id() { return current_loading_unit_id_; }
+  intptr_t current_loading_unit_id() const { return current_loading_unit_id_; }
   void set_current_loading_unit_id(intptr_t id) {
     current_loading_unit_id_ = id;
   }
@@ -501,6 +502,8 @@
 #define PushFromTo(obj, ...) s->PushFromTo(obj, ##__VA_ARGS__);
 
 #define WriteField(obj, field) s->WritePropertyRef(obj->untag()->field, #field)
+#define WriteCompressedField(obj, name)                                        \
+  s->WritePropertyRef(obj->untag()->name(), #name "_")
 
 class SerializerWritingObjectScope {
  public:
@@ -625,17 +628,17 @@
 
   template <typename T, typename... P>
   void ReadFromTo(T obj, P&&... params) {
-    ObjectPtr* from = obj->untag()->from();
-    ObjectPtr* to_snapshot = obj->untag()->to_snapshot(kind(), params...);
-    ObjectPtr* to = obj->untag()->to(params...);
-    for (ObjectPtr* p = from; p <= to_snapshot; p++) {
+    auto* from = obj->untag()->from();
+    auto* to_snapshot = obj->untag()->to_snapshot(kind(), params...);
+    auto* to = obj->untag()->to(params...);
+    for (auto* p = from; p <= to_snapshot; p++) {
       *p = ReadRef();
     }
     // This is necessary because, unlike Object::Allocate, the clustered
     // deserializer allocates object without null-initializing them. Instead,
     // each deserialization cluster is responsible for initializing every field,
     // ensuring that every field is written to exactly once.
-    for (ObjectPtr* p = to_snapshot + 1; p <= to; p++) {
+    for (auto* p = to_snapshot + 1; p <= to; p++) {
       *p = Object::null();
     }
   }
diff --git a/runtime/vm/compiler/aot/aot_call_specializer.cc b/runtime/vm/compiler/aot/aot_call_specializer.cc
index 2729e66..215bca5 100644
--- a/runtime/vm/compiler/aot/aot_call_specializer.cc
+++ b/runtime/vm/compiler/aot/aot_call_specializer.cc
@@ -224,33 +224,6 @@
   return false;
 }
 
-static bool HasLikelySmiOperand(InstanceCallInstr* instr) {
-  ASSERT(instr->type_args_len() == 0);
-
-  // If Smi is not assignable to the interface target of the call, the receiver
-  // is definitely not a Smi.
-  if (!instr->CanReceiverBeSmiBasedOnInterfaceTarget(
-          Thread::Current()->zone())) {
-    return false;
-  }
-
-  // Phis with at least one known smi are // guessed to be likely smi as well.
-  for (intptr_t i = 0; i < instr->ArgumentCount(); ++i) {
-    PhiInstr* phi = instr->ArgumentAt(i)->AsPhi();
-    if (phi != NULL) {
-      for (intptr_t j = 0; j < phi->InputCount(); ++j) {
-        if (phi->InputAt(j)->Type()->ToCid() == kSmiCid) return true;
-      }
-    }
-  }
-  // If all of the inputs are known smis or the result of CheckedSmiOp,
-  // we guess the operand to be likely smi.
-  for (intptr_t i = 0; i < instr->ArgumentCount(); ++i) {
-    if (!instr->ArgumentAt(i)->IsCheckedSmiOp()) return false;
-  }
-  return true;
-}
-
 bool AotCallSpecializer::TryInlineFieldAccess(InstanceCallInstr* call) {
   const Token::Kind op_kind = call->token_kind();
   if ((op_kind == Token::kGET) && TryInlineInstanceGetter(call)) {
@@ -286,8 +259,7 @@
       return true;
     }
 
-    if (FlowGraphCompiler::SupportsUnboxedInt64() &&
-        FlowGraphCompiler::CanConvertInt64ToDouble()) {
+    if (FlowGraphCompiler::CanConvertInt64ToDouble()) {
       return true;
     }
   }
@@ -315,8 +287,7 @@
 
     if (input->Type()->ToNullableCid() == kSmiCid) {
       conversion = new (Z) SmiToDoubleInstr(input, call->source());
-    } else if (FlowGraphCompiler::SupportsUnboxedInt64() &&
-               FlowGraphCompiler::CanConvertInt64ToDouble()) {
+    } else if (FlowGraphCompiler::CanConvertInt64ToDouble()) {
       conversion = new (Z) Int64ToDoubleInstr(input, DeoptId::kNone,
                                               Instruction::kNotSpeculative);
     } else {
@@ -477,7 +448,6 @@
     CompileType* left_type = left_value->Type();
     CompileType* right_type = right_value->Type();
 
-    const bool is_equality_op = Token::IsEqualityOperator(op_kind);
     bool has_nullable_int_args =
         left_type->IsNullableInt() && right_type->IsNullableInt();
 
@@ -487,12 +457,6 @@
       }
     }
 
-    // NOTE: We cannot use strict comparisons if the receiver has an overridden
-    // == operator or if either side can be a double, since 1.0 == 1.
-    const bool can_use_strict_compare =
-        is_equality_op && has_nullable_int_args &&
-        (left_type->IsNullableSmi() || right_type->IsNullableSmi());
-
     // We only support binary operations if both operands are nullable integers
     // or when we can use a cheap strict comparison operation.
     if (!has_nullable_int_args) {
@@ -502,56 +466,32 @@
     switch (op_kind) {
       case Token::kEQ:
       case Token::kNE:
-      case Token::kLT:
-      case Token::kLTE:
-      case Token::kGT:
-      case Token::kGTE: {
-        const bool supports_unboxed_int =
-            FlowGraphCompiler::SupportsUnboxedInt64();
-        const bool can_use_equality_compare =
-            supports_unboxed_int && is_equality_op && left_type->IsInt() &&
-            right_type->IsInt();
-
-        // We prefer equality compare, since it doesn't require boxing.
-        if (!can_use_equality_compare && can_use_strict_compare) {
+        if (left_type->IsNull() || left_type->IsNullableSmi() ||
+            right_type->IsNull() || right_type->IsNullableSmi()) {
           replacement = new (Z) StrictCompareInstr(
               instr->source(),
               (op_kind == Token::kEQ) ? Token::kEQ_STRICT : Token::kNE_STRICT,
               left_value->CopyWithType(Z), right_value->CopyWithType(Z),
               /*needs_number_check=*/false, DeoptId::kNone);
-          break;
-        }
-
-        if (supports_unboxed_int) {
-          if (can_use_equality_compare) {
-            replacement = new (Z) EqualityCompareInstr(
-                instr->source(), op_kind, left_value->CopyWithType(Z),
-                right_value->CopyWithType(Z), kMintCid, DeoptId::kNone,
-                Instruction::kNotSpeculative);
-            break;
-          } else if (Token::IsRelationalOperator(op_kind)) {
-            left_value = PrepareStaticOpInput(left_value, kMintCid, instr);
-            right_value = PrepareStaticOpInput(right_value, kMintCid, instr);
-            replacement = new (Z) RelationalOpInstr(
-                instr->source(), op_kind, left_value, right_value, kMintCid,
-                DeoptId::kNone, Instruction::kNotSpeculative);
-            break;
-          } else {
-            // TODO(dartbug.com/30480): Figure out how to handle null in
-            // equality comparisons.
-            replacement = new (Z)
-                CheckedSmiComparisonInstr(op_kind, left_value->CopyWithType(Z),
-                                          right_value->CopyWithType(Z), instr);
-            break;
-          }
         } else {
-          replacement = new (Z)
-              CheckedSmiComparisonInstr(op_kind, left_value->CopyWithType(Z),
-                                        right_value->CopyWithType(Z), instr);
-          break;
+          const bool null_aware =
+              left_type->is_nullable() || right_type->is_nullable();
+          replacement = new (Z) EqualityCompareInstr(
+              instr->source(), op_kind, left_value->CopyWithType(Z),
+              right_value->CopyWithType(Z), kMintCid, DeoptId::kNone,
+              null_aware, Instruction::kNotSpeculative);
         }
         break;
-      }
+      case Token::kLT:
+      case Token::kLTE:
+      case Token::kGT:
+      case Token::kGTE:
+        left_value = PrepareStaticOpInput(left_value, kMintCid, instr);
+        right_value = PrepareStaticOpInput(right_value, kMintCid, instr);
+        replacement = new (Z) RelationalOpInstr(
+            instr->source(), op_kind, left_value, right_value, kMintCid,
+            DeoptId::kNone, Instruction::kNotSpeculative);
+        break;
       case Token::kMOD:
         replacement = TryOptimizeMod(instr, op_kind, left_value, right_value);
         if (replacement != nullptr) break;
@@ -580,28 +520,18 @@
       case Token::kSUB:
         FALL_THROUGH;
       case Token::kMUL: {
-        if (FlowGraphCompiler::SupportsUnboxedInt64()) {
-          if (op_kind == Token::kSHL || op_kind == Token::kSHR ||
-              op_kind == Token::kUSHR) {
-            left_value = PrepareStaticOpInput(left_value, kMintCid, instr);
-            right_value = PrepareStaticOpInput(right_value, kMintCid, instr);
-            replacement = new (Z) ShiftInt64OpInstr(
-                op_kind, left_value, right_value, DeoptId::kNone);
-            break;
-          } else {
-            left_value = PrepareStaticOpInput(left_value, kMintCid, instr);
-            right_value = PrepareStaticOpInput(right_value, kMintCid, instr);
-            replacement = new (Z) BinaryInt64OpInstr(
-                op_kind, left_value, right_value, DeoptId::kNone,
-                Instruction::kNotSpeculative);
-            break;
-          }
-        }
-        if (op_kind != Token::kMOD && op_kind != Token::kTRUNCDIV) {
-          replacement =
-              new (Z) CheckedSmiOpInstr(op_kind, left_value->CopyWithType(Z),
-                                        right_value->CopyWithType(Z), instr);
-          break;
+        if (op_kind == Token::kSHL || op_kind == Token::kSHR ||
+            op_kind == Token::kUSHR) {
+          left_value = PrepareStaticOpInput(left_value, kMintCid, instr);
+          right_value = PrepareStaticOpInput(right_value, kMintCid, instr);
+          replacement = new (Z) ShiftInt64OpInstr(op_kind, left_value,
+                                                  right_value, DeoptId::kNone);
+        } else {
+          left_value = PrepareStaticOpInput(left_value, kMintCid, instr);
+          right_value = PrepareStaticOpInput(right_value, kMintCid, instr);
+          replacement = new (Z)
+              BinaryInt64OpInstr(op_kind, left_value, right_value,
+                                 DeoptId::kNone, Instruction::kNotSpeculative);
         }
         break;
       }
@@ -618,12 +548,10 @@
       return false;
     }
 
-    if (FlowGraphCompiler::SupportsUnboxedInt64()) {
-      if (op_kind == Token::kNEGATE || op_kind == Token::kBIT_NOT) {
-        left_value = PrepareStaticOpInput(left_value, kMintCid, instr);
-        replacement = new (Z) UnaryInt64OpInstr(
-            op_kind, left_value, DeoptId::kNone, Instruction::kNotSpeculative);
-      }
+    if (op_kind == Token::kNEGATE || op_kind == Token::kBIT_NOT) {
+      left_value = PrepareStaticOpInput(left_value, kMintCid, instr);
+      replacement = new (Z) UnaryInt64OpInstr(
+          op_kind, left_value, DeoptId::kNone, Instruction::kNotSpeculative);
     }
   }
 
@@ -679,7 +607,8 @@
           right_value = PrepareStaticOpInput(right_value, kDoubleCid, instr);
           replacement = new (Z) EqualityCompareInstr(
               instr->source(), op_kind, left_value, right_value, kDoubleCid,
-              DeoptId::kNone, Instruction::kNotSpeculative);
+              DeoptId::kNone, /*null_aware=*/false,
+              Instruction::kNotSpeculative);
           break;
         }
         break;
@@ -825,53 +754,6 @@
     }
   }
 
-  switch (instr->token_kind()) {
-    case Token::kEQ:
-    case Token::kNE:
-    case Token::kLT:
-    case Token::kLTE:
-    case Token::kGT:
-    case Token::kGTE: {
-      if (instr->BinaryFeedback().OperandsAre(kSmiCid) ||
-          HasLikelySmiOperand(instr)) {
-        ASSERT(receiver_idx == 0);
-        Definition* left = instr->ArgumentAt(0);
-        Definition* right = instr->ArgumentAt(1);
-        CheckedSmiComparisonInstr* smi_op = new (Z)
-            CheckedSmiComparisonInstr(instr->token_kind(), new (Z) Value(left),
-                                      new (Z) Value(right), instr);
-        ReplaceCall(instr, smi_op);
-        return;
-      }
-      break;
-    }
-    case Token::kSHL:
-    case Token::kSHR:
-    case Token::kUSHR:
-    case Token::kBIT_OR:
-    case Token::kBIT_XOR:
-    case Token::kBIT_AND:
-    case Token::kADD:
-    case Token::kSUB:
-    case Token::kMUL: {
-      if (instr->BinaryFeedback().OperandsAre(kSmiCid) ||
-          HasLikelySmiOperand(instr)) {
-        ASSERT(receiver_idx == 0);
-        Definition* left = instr->ArgumentAt(0);
-        Definition* right = instr->ArgumentAt(1);
-        CheckedSmiOpInstr* smi_op =
-            new (Z) CheckedSmiOpInstr(instr->token_kind(), new (Z) Value(left),
-                                      new (Z) Value(right), instr);
-
-        ReplaceCall(instr, smi_op);
-        return;
-      }
-      break;
-    }
-    default:
-      break;
-  }
-
   // No IC data checks. Try resolve target using the propagated cid.
   const intptr_t receiver_cid =
       instr->ArgumentValueAt(receiver_idx)->Type()->ToCid();
diff --git a/runtime/vm/compiler/aot/aot_call_specializer.h b/runtime/vm/compiler/aot/aot_call_specializer.h
index fd23ebf..b537ae8 100644
--- a/runtime/vm/compiler/aot/aot_call_specializer.h
+++ b/runtime/vm/compiler/aot/aot_call_specializer.h
@@ -59,12 +59,12 @@
   const Function& InterfaceTargetForTableDispatch(InstanceCallBaseInstr* call);
 
   // Try to replace a call with a more specialized instruction working on
-  // integers (e.g. BinaryInt64OpInstr, CheckedSmiComparisonInstr,
+  // integers (e.g. BinaryInt64OpInstr, EqualityCompareInstr,
   // RelationalOpInstr)
   bool TryOptimizeIntegerOperation(TemplateDartCall<0>* call, Token::Kind kind);
 
   // Try to replace a call with a more specialized instruction working on
-  // doubles (e.g. BinaryDoubleOpInstr, CheckedSmiComparisonInstr,
+  // doubles (e.g. BinaryDoubleOpInstr, EqualityCompareInstr,
   // RelationalOpInstr)
   bool TryOptimizeDoubleOperation(TemplateDartCall<0>* call, Token::Kind kind);
 
diff --git a/runtime/vm/compiler/aot/precompiler.cc b/runtime/vm/compiler/aot/precompiler.cc
index 4c05ba8..4eddc2e 100644
--- a/runtime/vm/compiler/aot/precompiler.cc
+++ b/runtime/vm/compiler/aot/precompiler.cc
@@ -5,6 +5,7 @@
 #include "vm/compiler/aot/precompiler.h"
 
 #include "platform/unicode.h"
+#include "platform/utils.h"
 #include "vm/canonical_tables.h"
 #include "vm/class_finalizer.h"
 #include "vm/closure_functions_cache.h"
@@ -18,7 +19,6 @@
 #include "vm/compiler/backend/flow_graph.h"
 #include "vm/compiler/backend/flow_graph_compiler.h"
 #include "vm/compiler/backend/il_printer.h"
-#include "vm/compiler/backend/il_serializer.h"
 #include "vm/compiler/backend/inliner.h"
 #include "vm/compiler/backend/linearscan.h"
 #include "vm/compiler/backend/range_analysis.h"
@@ -68,6 +68,10 @@
     max_speculative_inlining_attempts,
     1,
     "Max number of attempts with speculative inlining (precompilation only)");
+DEFINE_FLAG(charp,
+            write_retained_reasons_to,
+            nullptr,
+            "Print reasons for retaining objects to the given file");
 
 DECLARE_FLAG(bool, print_flow_graph);
 DECLARE_FLAG(bool, print_flow_graph_optimized);
@@ -87,21 +91,206 @@
 DECLARE_FLAG(int, inlining_constant_arguments_min_size_threshold);
 DECLARE_FLAG(bool, print_instruction_stats);
 
-DEFINE_FLAG(charp,
-            serialize_flow_graphs_to,
-            nullptr,
-            "Serialize flow graphs to the given file");
-
-DEFINE_FLAG(bool,
-            populate_llvm_constant_pool,
-            false,
-            "Add constant pool entries from flow graphs to a special pool "
-            "serialized in AOT snapshots (with --serialize_flow_graphs_to)");
-
 Precompiler* Precompiler::singleton_ = nullptr;
 
 #if defined(DART_PRECOMPILER) && !defined(TARGET_ARCH_IA32)
 
+// Reasons for retaining a given object.
+struct RetainReasons : public AllStatic {
+  // The LLVM pools are active and the object appears in one of them.
+  static constexpr const char* kLLVMPool = "llvm pool";
+  // The object is an invoke field dispatcher.
+  static constexpr const char* kInvokeFieldDispatcher =
+      "invoke field dispatcher";
+  // The object is a dynamic invocation forwarder.
+  static constexpr const char* kDynamicInvocationForwarder =
+      "dynamic invocation forwarder";
+  // The object is a method extractor.
+  static constexpr const char* kMethodExtractor = "method extractor";
+  // The object is for a compiled implicit closure.
+  static constexpr const char* kImplicitClosure = "implicit closure";
+  // The object is a local closure.
+  static constexpr const char* kLocalClosure = "local closure";
+  // The object is a sync or async function or in the parent chain of one.
+  static constexpr const char* kIsSyncAsyncFunction = "sync or async function";
+  // The object is the initializer for a static field.
+  static constexpr const char* kStaticFieldInitializer =
+      "static field initializer";
+  // The object is the initializer for a instance field.
+  static constexpr const char* kInstanceFieldInitializer =
+      "instance field initializer";
+  // The object is the initializer for a late field.
+  static constexpr const char* kLateFieldInitializer = "late field initializer";
+  // The object is an implicit getter.
+  static constexpr const char* kImplicitGetter = "implicit getter";
+  // The object is an implicit setter.
+  static constexpr const char* kImplicitSetter = "implicit setter";
+  // The object is an implicit static getter.
+  static constexpr const char* kImplicitStaticGetter = "implicit static getter";
+  // The object is a function that is called through a getter method.
+  static constexpr const char* kCalledThroughGetter = "called through getter";
+  // The object is a function that is called via selector.
+  static constexpr const char* kCalledViaSelector = "called via selector";
+  // The object is a function and the flag --retain-function-objects is enabled.
+  static constexpr const char* kForcedRetain = "forced via flag";
+  // The object is a function and symbolic stack traces are enabled.
+  static constexpr const char* kSymbolicStackTraces =
+      "needed for symbolic stack traces";
+  // The object is a function that is only used via its implicit closure
+  // function, into which it was inlined.
+  static constexpr const char* kInlinedIntoICF =
+      "inlined into implicit closure function";
+  // The object is a parent function function of a non-inlined local function.
+  static constexpr const char* kLocalParent = "parent of a local function";
+  // The object has an entry point pragma that requires it be retained.
+  static constexpr const char* kEntryPointPragma = "entry point pragma";
+  // The function is a target of FFI callback.
+  static constexpr const char* kFfiCallbackTarget = "ffi callback target";
+};
+
+class RetainedReasonsWriter : public ValueObject {
+ public:
+  explicit RetainedReasonsWriter(Zone* zone)
+      : zone_(zone), retained_reasons_map_(zone) {}
+
+  void Init(const char* filename) {
+    if (filename == nullptr) return;
+    const auto file_open = Dart::file_open_callback();
+    if (file_open == nullptr) return;
+
+    const auto file = file_open(filename, /*write=*/true);
+    if (file == nullptr) {
+      OS::PrintErr("Failed to open file %s\n", filename);
+      return;
+    }
+
+    file_ = file;
+    // We open the array here so that we can also print some objects to the
+    // JSON as we go, instead of requiring all information be collected
+    // and printed at one point. This avoids having to keep otherwise
+    // unneeded information around.
+    writer_.OpenArray();
+  }
+
+  void AddDropped(const Object& obj) {
+    if (HasReason(obj)) {
+      FATAL("dropped object has reasons to retain");
+    }
+    writer_.OpenObject();
+    WriteRetainedObjectSpecificFields(obj);
+    writer_.PrintPropertyBool("retained", false);
+    writer_.CloseObject();
+  }
+
+  bool HasReason(const Object& obj) const {
+    return retained_reasons_map_.HasKey(&obj);
+  }
+
+  void AddReason(const Object& obj, const char* reason) {
+    if (auto const kv = retained_reasons_map_.Lookup(&obj)) {
+      if (kv->value->Lookup(reason) == nullptr) {
+        kv->value->Insert(reason);
+      }
+      return;
+    }
+    auto const key = &Object::ZoneHandle(zone_, obj.ptr());
+    auto const value = new (zone_) ZoneCStringSet(zone_);
+    value->Insert(reason);
+    retained_reasons_map_.Insert(RetainedReasonsTrait::Pair(key, value));
+  }
+
+  // Finalizes the JSON output and writes it.
+  void Write() {
+    if (file_ == nullptr) return;
+
+    // Add all the objects for which we have reasons to retain.
+    auto it = retained_reasons_map_.GetIterator();
+
+    for (auto kv = it.Next(); kv != nullptr; kv = it.Next()) {
+      writer_.OpenObject();
+      WriteRetainedObjectSpecificFields(*kv->key);
+      writer_.PrintPropertyBool("retained", true);
+
+      writer_.OpenArray("reasons");
+      auto it = kv->value->GetIterator();
+      for (auto cstrp = it.Next(); cstrp != nullptr; cstrp = it.Next()) {
+        ASSERT(*cstrp != nullptr);
+        writer_.PrintValue(*cstrp);
+      }
+      writer_.CloseArray();
+
+      writer_.CloseObject();
+    }
+
+    writer_.CloseArray();
+    char* output = nullptr;
+    intptr_t length = -1;
+    writer_.Steal(&output, &length);
+
+    if (const auto file_write = Dart::file_write_callback()) {
+      file_write(output, length, file_);
+    }
+
+    if (const auto file_close = Dart::file_close_callback()) {
+      file_close(file_);
+    }
+
+    free(output);
+  }
+
+ private:
+  struct RetainedReasonsTrait {
+    using Key = const Object*;
+    using Value = ZoneCStringSet*;
+
+    struct Pair {
+      Key key;
+      Value value;
+
+      Pair() : key(nullptr), value(nullptr) {}
+      Pair(Key key, Value value) : key(key), value(value) {}
+    };
+
+    static Key KeyOf(Pair kv) { return kv.key; }
+
+    static Value ValueOf(Pair kv) { return kv.value; }
+
+    static inline intptr_t Hashcode(Key key) {
+      if (key->IsFunction()) {
+        return Function::Cast(*key).Hash();
+      }
+      if (key->IsClass()) {
+        return Utils::WordHash(Class::Cast(*key).id());
+      }
+      return Utils::WordHash(key->GetClassId());
+    }
+
+    static inline bool IsKeyEqual(Pair pair, Key key) {
+      return pair.key->ptr() == key->ptr();
+    }
+  };
+
+  using RetainedReasonsMap = DirectChainedHashMap<RetainedReasonsTrait>;
+
+  void WriteRetainedObjectSpecificFields(const Object& obj) {
+    if (obj.IsFunction()) {
+      writer_.PrintProperty("type", "Function");
+      const auto& function = Function::Cast(obj);
+      writer_.PrintProperty("name",
+                            function.ToLibNamePrefixedQualifiedCString());
+      writer_.PrintProperty("kind",
+                            UntaggedFunction::KindToCString(function.kind()));
+      return;
+    }
+    FATAL("Unexpected object %s", obj.ToCString());
+  }
+
+  Zone* const zone_;
+  RetainedReasonsMap retained_reasons_map_;
+  JSONWriter writer_;
+  void* file_;
+};
+
 class PrecompileParsedFunctionHelper : public ValueObject {
  public:
   PrecompileParsedFunctionHelper(Precompiler* precompiler,
@@ -188,8 +377,7 @@
       consts_to_retain_(),
       seen_table_selectors_(),
       error_(Error::Handle()),
-      get_runtime_type_is_unique_(false),
-      il_serialization_stream_(nullptr) {
+      get_runtime_type_is_unique_(false) {
   ASSERT(Precompiler::singleton_ == NULL);
   Precompiler::singleton_ = this;
 }
@@ -210,6 +398,12 @@
   {
     StackZone stack_zone(T);
     zone_ = stack_zone.GetZone();
+    RetainedReasonsWriter reasons_writer(zone_);
+
+    if (FLAG_write_retained_reasons_to != nullptr) {
+      reasons_writer.Init(FLAG_write_retained_reasons_to);
+      retained_reasons_writer_ = &reasons_writer;
+    }
 
     if (FLAG_use_bare_instructions) {
       // Since we keep the object pool until the end of AOT compilation, it
@@ -255,32 +449,6 @@
       ClassFinalizer::ClearAllCode(
           /*including_nonchanging_cids=*/FLAG_use_bare_instructions);
 
-      // After this point, it should be safe to serialize flow graphs produced
-      // during compilation and add constants to the LLVM constant pool.
-      //
-      // Check that both the file open and write callbacks are available, though
-      // we only use the latter during IL processing.
-      if (FLAG_serialize_flow_graphs_to != nullptr &&
-          Dart::file_write_callback() != nullptr) {
-        if (auto file_open = Dart::file_open_callback()) {
-          auto file = file_open(FLAG_serialize_flow_graphs_to, /*write=*/true);
-          set_il_serialization_stream(file);
-        }
-        if (FLAG_populate_llvm_constant_pool) {
-          auto const object_store = IG->object_store();
-          auto& llvm_constants = GrowableObjectArray::Handle(
-              Z, GrowableObjectArray::New(16, Heap::kOld));
-          auto& llvm_functions = GrowableObjectArray::Handle(
-              Z, GrowableObjectArray::New(16, Heap::kOld));
-          auto& llvm_constant_hash_table = Array::Handle(
-              Z, HashTables::New<FlowGraphSerializer::LLVMPoolMap>(16,
-                                                                   Heap::kOld));
-          object_store->set_llvm_constant_pool(llvm_constants);
-          object_store->set_llvm_function_pool(llvm_functions);
-          object_store->set_llvm_constant_hash_table(llvm_constant_hash_table);
-        }
-      }
-
       tracer_ = PrecompilerTracer::StartTracingIfRequested(this);
 
       // All stubs have already been generated, all of them share the same pool.
@@ -360,45 +528,6 @@
         }
       }
 
-      if (FLAG_serialize_flow_graphs_to != nullptr &&
-          Dart::file_write_callback() != nullptr) {
-        if (auto file_close = Dart::file_close_callback()) {
-          file_close(il_serialization_stream());
-        }
-        set_il_serialization_stream(nullptr);
-        if (FLAG_populate_llvm_constant_pool) {
-          // We don't want the Array backing for any mappings in the snapshot,
-          // only the pools themselves.
-          IG->object_store()->set_llvm_constant_hash_table(Array::null_array());
-
-          // Keep any functions, classes, etc. referenced from the LLVM pools,
-          // even if they could have been dropped due to not being otherwise
-          // needed at runtime.
-          const auto& constant_pool = GrowableObjectArray::Handle(
-              Z, IG->object_store()->llvm_constant_pool());
-          auto& object = Object::Handle(Z);
-          for (intptr_t i = 0; i < constant_pool.Length(); i++) {
-            object = constant_pool.At(i);
-            if (object.IsNull()) continue;
-            if (object.IsInstance()) {
-              AddConstObject(Instance::Cast(object));
-            } else if (object.IsField()) {
-              AddField(Field::Cast(object));
-            } else if (object.IsFunction()) {
-              AddFunction(Function::Cast(object));
-            }
-          }
-
-          const auto& function_pool = GrowableObjectArray::Handle(
-              Z, IG->object_store()->llvm_function_pool());
-          auto& function = Function::Handle(Z);
-          for (intptr_t i = 0; i < function_pool.Length(); i++) {
-            function ^= function_pool.At(i);
-            AddFunction(function);
-          }
-        }
-      }
-
       if (tracer_ != nullptr) {
         tracer_->Finalize();
         tracer_ = nullptr;
@@ -454,6 +583,11 @@
     DiscardCodeObjects();
     ProgramVisitor::Dedup(T);
 
+    if (FLAG_write_retained_reasons_to != nullptr) {
+      reasons_writer.Write();
+      retained_reasons_writer_ = nullptr;
+    }
+
     zone_ = NULL;
   }
 
@@ -627,7 +761,7 @@
                 THR_Print("Added invoke-field-dispatcher for %s to %s\n",
                           field_name.ToCString(), subcls.ToCString());
               }
-              AddFunction(dispatcher);
+              AddFunction(dispatcher, RetainReasons::kInvokeFieldDispatcher);
             }
           }
         }
@@ -680,7 +814,16 @@
   for (auto& view : static_calls) {
     entry = view.Get<Code::kSCallTableFunctionTarget>();
     if (entry.IsFunction()) {
-      AddFunction(Function::Cast(entry), FLAG_retain_function_objects);
+      // Since generally function objects are retained when symbolic stack
+      // traces are enabled, only return kForcedRetain to mark that retention
+      // was otherwise forced.
+      const char* const reason =
+          FLAG_retain_function_objects
+              ? (!FLAG_dwarf_stack_traces_mode
+                     ? RetainReasons::kSymbolicStackTraces
+                     : RetainReasons::kForcedRetain)
+              : nullptr;
+      AddFunction(Function::Cast(entry), reason);
       ASSERT(view.Get<Code::kSCallTableCodeOrTypeTarget>() == Code::null());
       continue;
     }
@@ -691,6 +834,28 @@
     }
   }
 
+  const ExceptionHandlers& handlers =
+      ExceptionHandlers::Handle(Z, code.exception_handlers());
+  if (!handlers.IsNull()) {
+#if defined(PRODUCT)
+    // List of handled types is only used by debugger and
+    // can be removed in PRODUCT mode.
+    for (intptr_t i = 0; i < handlers.num_entries(); i++) {
+      handlers.SetHandledTypes(i, Array::empty_array());
+    }
+#else
+    Array& types = Array::Handle(Z);
+    AbstractType& type = AbstractType::Handle(Z);
+    for (intptr_t i = 0; i < handlers.num_entries(); i++) {
+      types = handlers.GetHandledTypes(i);
+      for (intptr_t j = 0; j < types.Length(); j++) {
+        type ^= types.At(j);
+        AddType(type);
+      }
+    }
+#endif  // defined(PRODUCT)
+  }
+
 #if defined(TARGET_ARCH_IA32)
   FATAL("Callee scanning unimplemented for IA32");
 #endif
@@ -726,6 +891,7 @@
         Array::Handle(Z, code.inlined_id_to_function());
     for (intptr_t i = 0; i < inlined_functions.Length(); i++) {
       target ^= inlined_functions.At(i);
+      AddRetainReason(target, RetainReasons::kSymbolicStackTraces);
       AddTypesOf(target);
     }
   }
@@ -770,7 +936,14 @@
   } else if (entry.IsFunction()) {
     // Local closure function.
     const auto& target = Function::Cast(entry);
-    AddFunction(target);
+    AddFunction(target, RetainReasons::kLocalClosure);
+    if (target.IsFfiTrampoline()) {
+      const auto& callback_target =
+          Function::Handle(Z, target.FfiCallbackTarget());
+      if (!callback_target.IsNull()) {
+        AddFunction(callback_target, RetainReasons::kFfiCallbackTarget);
+      }
+    }
   } else if (entry.IsCode()) {
     const auto& target_code = Code::Cast(entry);
     if (target_code.IsAllocationStubCode()) {
@@ -798,11 +971,21 @@
   AddType(type);
 }
 
+void Precompiler::AddRetainReason(const Object& obj, const char* reason) {
+  if (retained_reasons_writer_ == nullptr || reason == nullptr) return;
+  retained_reasons_writer_->AddReason(obj, reason);
+}
+
 void Precompiler::AddTypesOf(const Function& function) {
   if (function.IsNull()) return;
   if (functions_to_retain_.ContainsKey(function)) return;
   functions_to_retain_.Insert(function);
 
+  if (retained_reasons_writer_ != nullptr &&
+      !retained_reasons_writer_->HasReason(function)) {
+    FATAL("no retaining reasons given");
+  }
+
   if (function.NeedsMonomorphicCheckedEntry(Z) ||
       Function::IsDynamicInvocationForwarderName(function.name())) {
     functions_called_dynamically_.Insert(function);
@@ -811,7 +994,6 @@
   const FunctionType& signature = FunctionType::Handle(Z, function.signature());
   AddType(signature);
 
-  AbstractType& type = AbstractType::Handle(Z);
   // At this point, ensure any cached default type arguments are canonicalized.
   function.UpdateCachedDefaultTypeArguments(thread());
   if (function.CachesDefaultTypeArguments()) {
@@ -820,29 +1002,51 @@
     ASSERT(defaults.IsCanonical());
     AddTypeArguments(defaults);
   }
-  Code& code = Code::Handle(Z, function.CurrentCode());
-  ASSERT(!code.IsNull());
-  const ExceptionHandlers& handlers =
-      ExceptionHandlers::Handle(Z, code.exception_handlers());
-  if (!handlers.IsNull()) {
-    Array& types = Array::Handle(Z);
-    for (intptr_t i = 0; i < handlers.num_entries(); i++) {
-      types = handlers.GetHandledTypes(i);
-      for (intptr_t j = 0; j < types.Length(); j++) {
-        type ^= types.At(j);
-        AddType(type);
-      }
-    }
-  }
-  // A function can always be inlined and have only a nested local function
-  // remain.
-  const Function& parent = Function::Handle(Z, function.parent_function());
-  if (!parent.IsNull()) {
-    AddTypesOf(parent);
-  }
+
   // A class may have all functions inlined except a local function.
   const Class& owner = Class::Handle(Z, function.Owner());
   AddTypesOf(owner);
+
+  const auto& parent_function = Function::Handle(Z, function.parent_function());
+  if (parent_function.IsNull()) {
+    return;
+  }
+
+  // It can happen that all uses of a function are inlined, leaving
+  // a compiled local function with an uncompiled parent. Retain such
+  // parents and their enclosing classes and libraries when needed.
+
+  // We always retain parents if symbolic stack traces are enabled.
+  if (!FLAG_dwarf_stack_traces_mode) {
+    AddRetainReason(parent_function, RetainReasons::kSymbolicStackTraces);
+    AddTypesOf(parent_function);
+    return;
+  }
+
+  // Special case to allow walking of lazy async stacks to work.
+  // Should match parent checks in CallerClosureFinder::FindCaller.
+  if (parent_function.recognized_kind() == MethodRecognizer::kFutureTimeout ||
+      parent_function.recognized_kind() == MethodRecognizer::kFutureWait) {
+    AddRetainReason(parent_function, RetainReasons::kIsSyncAsyncFunction);
+    AddTypesOf(parent_function);
+    return;
+  }
+
+  // Preserve parents for generated bodies in async/async*/sync* functions,
+  // since predicates like Function::IsAsyncClosure(), etc. need that info.
+  if (function.is_generated_body()) {
+    AddRetainReason(parent_function, RetainReasons::kIsSyncAsyncFunction);
+    AddTypesOf(parent_function);
+    return;
+  }
+
+  // We're not retaining the parent due to this function, so wrap it with
+  // a weak serialization reference.
+  const auto& data = ClosureData::CheckedHandle(Z, function.data());
+  const auto& wsr = WeakSerializationReference::Handle(
+      Z, WeakSerializationReference::New(parent_function,
+                                         Object::null_function()));
+  data.set_parent_function(wsr);
 }
 
 void Precompiler::AddType(const AbstractType& abstype) {
@@ -930,7 +1134,7 @@
     const Function& func =
         Function::Handle(Z, Closure::Cast(instance).function());
     ASSERT(func.is_static());
-    AddFunction(func);
+    AddFunction(func, RetainReasons::kImplicitClosure);
     AddTypeArguments(TypeArguments::Handle(
         Z, Closure::Cast(instance).instantiator_type_arguments()));
     AddTypeArguments(TypeArguments::Handle(
@@ -1014,7 +1218,7 @@
                               call_selector, arguments_descriptor,
                               UntaggedFunction::kInvokeFieldDispatcher,
                               true /* create_if_absent */));
-  AddFunction(dispatcher);
+  AddFunction(dispatcher, RetainReasons::kInvokeFieldDispatcher);
 }
 
 void Precompiler::AddField(const Field& field) {
@@ -1043,11 +1247,14 @@
       (field.is_static() || field.is_late())) {
     const Function& initializer =
         Function::ZoneHandle(Z, field.EnsureInitializerFunction());
-    AddFunction(initializer);
+    const char* const reason = field.is_static()
+                                   ? RetainReasons::kStaticFieldInitializer
+                                   : RetainReasons::kLateFieldInitializer;
+    AddFunction(initializer, reason);
   }
 }
 
-bool Precompiler::MustRetainFunction(const Function& function) {
+const char* Precompiler::MustRetainFunction(const Function& function) {
   // There are some cases where we must retain, even if there are no directly
   // observable need for function objects at runtime. Here, we check for cases
   // where the function is not marked with the vm:entry-point pragma, which also
@@ -1057,42 +1264,47 @@
   // * Selector matches a symbol used in Resolver::ResolveDynamic calls
   //   in dart_entry.cc or dart_api_impl.cc.
   // * _Closure.call (used in async stack handling)
-  if (function.is_native()) return true;
-
-  // Resolver::ResolveDynamic uses.
-  const auto& selector = String::Handle(Z, function.name());
-  if (selector.ptr() == Symbols::toString().ptr()) return true;
-  if (selector.ptr() == Symbols::AssignIndexToken().ptr()) return true;
-  if (selector.ptr() == Symbols::IndexToken().ptr()) return true;
-  if (selector.ptr() == Symbols::hashCode().ptr()) return true;
-  if (selector.ptr() == Symbols::NoSuchMethod().ptr()) return true;
-  if (selector.ptr() == Symbols::EqualOperator().ptr()) return true;
+  if (function.is_native()) {
+    return "native function";
+  }
 
   // Use the same check for _Closure.call as in stack_trace.{h|cc}.
+  const auto& selector = String::Handle(Z, function.name());
   if (selector.ptr() == Symbols::Call().ptr()) {
     const auto& name = String::Handle(Z, function.QualifiedScrubbedName());
-    if (name.Equals(Symbols::_ClosureCall())) return true;
+    if (name.Equals(Symbols::_ClosureCall())) {
+      return "_Closure.call";
+    }
   }
 
   // We have to retain functions which can be a target of a SwitchableCall
   // at AOT runtime, since the AOT runtime needs to be able to find the
   // function object in the class.
-  if (function.NeedsMonomorphicCheckedEntry(Z) ||
-      Function::IsDynamicInvocationForwarderName(function.name())) {
-    return true;
+  if (function.NeedsMonomorphicCheckedEntry(Z)) {
+    return "needs monomorphic checked entry";
+  }
+  if (Function::IsDynamicInvocationForwarderName(function.name())) {
+    return "dynamic invocation forwarder";
   }
 
-  return false;
+  return nullptr;
 }
 
-void Precompiler::AddFunction(const Function& function, bool retain) {
+void Precompiler::AddFunction(const Function& function,
+                              const char* retain_reason) {
   if (is_tracing()) {
     tracer_->WriteFunctionRef(function);
   }
 
-  if (possibly_retained_functions_.ContainsKey(function)) return;
+  if (retain_reason == nullptr) {
+    retain_reason = MustRetainFunction(function);
+  }
+  // Add even if we've already marked this function as possibly retained
+  // because this could be an additional reason for doing so.
+  AddRetainReason(function, retain_reason);
 
-  if (retain || MustRetainFunction(function)) {
+  if (possibly_retained_functions_.ContainsKey(function)) return;
+  if (retain_reason != nullptr) {
     possibly_retained_functions_.Insert(function);
   }
 
@@ -1251,7 +1463,7 @@
 
           if (type == EntryPointPragma::kAlways ||
               type == EntryPointPragma::kCallOnly) {
-            AddFunction(function);
+            AddFunction(function, RetainReasons::kEntryPointPragma);
             entry_point_functions_.Insert(function);
           }
 
@@ -1260,7 +1472,7 @@
               function.kind() != UntaggedFunction::kConstructor &&
               !function.IsSetterFunction()) {
             function2 = function.ImplicitClosureFunction();
-            AddFunction(function2);
+            AddFunction(function2, RetainReasons::kEntryPointPragma);
             entry_point_functions_.Insert(function2);
           }
 
@@ -1274,7 +1486,7 @@
           for (intptr_t i = 0; i < implicit_getters.Length(); ++i) {
             field ^= implicit_getters.At(i);
             if (function.accessor_field() == field.ptr()) {
-              AddFunction(function);
+              AddFunction(function, RetainReasons::kImplicitGetter);
               entry_point_functions_.Insert(function);
             }
           }
@@ -1284,7 +1496,7 @@
           for (intptr_t i = 0; i < implicit_setters.Length(); ++i) {
             field ^= implicit_setters.At(i);
             if (function.accessor_field() == field.ptr()) {
-              AddFunction(function);
+              AddFunction(function, RetainReasons::kImplicitSetter);
               entry_point_functions_.Insert(function);
             }
           }
@@ -1294,7 +1506,7 @@
           for (intptr_t i = 0; i < implicit_static_getters.Length(); ++i) {
             field ^= implicit_static_getters.At(i);
             if (function.accessor_field() == field.ptr()) {
-              AddFunction(function);
+              AddFunction(function, RetainReasons::kImplicitStaticGetter);
               entry_point_functions_.Insert(function);
             }
           }
@@ -1339,10 +1551,12 @@
 
         selector = function.name();
         if (IsSent(selector)) {
-          AddFunction(function);
+          AddFunction(function, RetainReasons::kCalledViaSelector);
         }
         if (IsHitByTableSelector(function)) {
-          AddFunction(function, FLAG_retain_function_objects);
+          AddFunction(function, FLAG_retain_function_objects
+                                    ? RetainReasons::kForcedRetain
+                                    : nullptr);
         }
 
         bool found_metadata = false;
@@ -1359,14 +1573,14 @@
           // method foo first.
           selector2 = Field::NameFromGetter(selector);
           if (IsSent(selector2)) {
-            AddFunction(function);
+            AddFunction(function, RetainReasons::kCalledThroughGetter);
           }
           selector2 = Function::CreateDynamicInvocationForwarderName(selector2);
           if (IsSent(selector2)) {
             selector2 =
                 Function::CreateDynamicInvocationForwarderName(selector);
             function2 = function.GetDynamicInvocationForwarder(selector2);
-            AddFunction(function2);
+            AddFunction(function2, RetainReasons::kDynamicInvocationForwarder);
           }
         } else if (function.kind() == UntaggedFunction::kRegularFunction) {
           selector2 = Field::LookupGetterSymbol(selector);
@@ -1383,11 +1597,11 @@
               // Closurization.
               // Function is foo and somewhere get:foo is called.
               function2 = function.ImplicitClosureFunction();
-              AddFunction(function2);
+              AddFunction(function2, RetainReasons::kImplicitClosure);
 
               // Add corresponding method extractor.
               function2 = function.GetMethodExtractor(selector2);
-              AddFunction(function2);
+              AddFunction(function2, RetainReasons::kMethodExtractor);
             }
           }
         }
@@ -1414,12 +1628,14 @@
             if (is_getter) {
               if (metadata.getter_called_dynamically) {
                 function2 = function.GetDynamicInvocationForwarder(selector2);
-                AddFunction(function2);
+                AddFunction(function2,
+                            RetainReasons::kDynamicInvocationForwarder);
               }
             } else {
               if (metadata.method_or_setter_called_dynamically) {
                 function2 = function.GetDynamicInvocationForwarder(selector2);
-                AddFunction(function2);
+                AddFunction(function2,
+                            RetainReasons::kDynamicInvocationForwarder);
               }
             }
           }
@@ -1589,6 +1805,8 @@
   String& name = String::Handle(Z);
   Function& function = Function::Handle(Z);
   Function& function2 = Function::Handle(Z);
+  Array& fields = Array::Handle(Z);
+  Field& field = Field::Handle(Z);
 
   for (intptr_t i = 0; i < libraries_.Length(); i++) {
     lib ^= libraries_.At(i);
@@ -1606,10 +1824,31 @@
           // static calls, etc.
           function2 = function.ImplicitClosureFunction();
           retain = function2.HasCode();
+          if (retain) {
+            AddRetainReason(function, RetainReasons::kInlinedIntoICF);
+          }
         }
         if (retain) {
           function.DropUncompiledImplicitClosureFunction();
           AddTypesOf(function);
+          if (function.HasImplicitClosureFunction()) {
+            function2 = function.ImplicitClosureFunction();
+            if (possibly_retained_functions_.ContainsKey(function2)) {
+              AddTypesOf(function2);
+            }
+          }
+        }
+      }
+
+      fields = cls.fields();
+      for (intptr_t j = 0; j < fields.Length(); j++) {
+        field ^= fields.At(j);
+        if (fields_to_retain_.HasKey(&field) &&
+            field.HasInitializerFunction()) {
+          function = field.InitializerFunction();
+          if (possibly_retained_functions_.ContainsKey(function)) {
+            AddTypesOf(function);
+          }
         }
       }
 
@@ -1628,26 +1867,28 @@
     }
   }
 
-  auto& parent_function = Function::Handle(Z);
   ClosureFunctionsCache::ForAllClosureFunctions([&](const Function& function) {
-    bool retain = possibly_retained_functions_.ContainsKey(function);
-    if (retain) {
+    if (possibly_retained_functions_.ContainsKey(function)) {
       AddTypesOf(function);
-
-      cls = function.Owner();
-      AddTypesOf(cls);
-
-      // It can happen that all uses of a function are inlined, leaving
-      // a compiled local function with an uncompiled parent. Retain such
-      // parents and their enclosing classes and libraries.
-      parent_function = function.parent_function();
-      while (!parent_function.IsNull()) {
-        AddTypesOf(parent_function);
-        parent_function = parent_function.parent_function();
-      }
     }
     return true;  // Continue iteration.
   });
+
+#ifdef DEBUG
+  // Make sure functions_to_retain_ is a super-set of
+  // possibly_retained_functions_.
+  FunctionSet::Iterator it(&possibly_retained_functions_);
+  while (it.MoveNext()) {
+    function ^= possibly_retained_functions_.GetKey(it.Current());
+    // Ffi trampoline functions are not reachable from program structure,
+    // they are referenced only from code (object pool).
+    if (!functions_to_retain_.ContainsKey(function) &&
+        !function.IsFfiTrampoline()) {
+      FATAL1("Function %s was not traced in TraceForRetainedFunctions\n",
+             function.ToFullyQualifiedCString());
+    }
+  }
+#endif  // DEBUG
 }
 
 void Precompiler::FinalizeDispatchTable() {
@@ -1789,6 +2030,9 @@
       THR_Print("Dropping function %s\n",
                 function.ToLibNamePrefixedQualifiedCString());
     }
+    if (retained_reasons_writer_ != nullptr) {
+      retained_reasons_writer_->AddDropped(function);
+    }
   };
 
   SafepointWriteRwLocker ml(T, T->isolate_group()->program_lock());
@@ -1888,13 +2132,20 @@
         }
 #endif
         if (retain) {
+          if (FLAG_trace_precompiler) {
+            THR_Print("Retaining %s field %s\n",
+                      field.is_static() ? "static" : "instance",
+                      field.ToCString());
+          }
           retained_fields.Add(field);
           type = field.type();
           AddType(type);
         } else {
           dropped_field_count_++;
           if (FLAG_trace_precompiler) {
-            THR_Print("Dropping field %s\n", field.ToCString());
+            THR_Print("Dropping %s field %s\n",
+                      field.is_static() ? "static" : "instance",
+                      field.ToCString());
           }
 
           // This cleans up references to field current and initial values.
diff --git a/runtime/vm/compiler/aot/precompiler.h b/runtime/vm/compiler/aot/precompiler.h
index 4544053..2af72af 100644
--- a/runtime/vm/compiler/aot/precompiler.h
+++ b/runtime/vm/compiler/aot/precompiler.h
@@ -29,6 +29,7 @@
 class Precompiler;
 class FlowGraph;
 class PrecompilerTracer;
+class RetainedReasonsWriter;
 
 class TableSelectorKeyValueTrait {
  public:
@@ -250,8 +251,6 @@
     return dispatch_table_generator_->selector_map();
   }
 
-  void* il_serialization_stream() const { return il_serialization_stream_; }
-
   static Precompiler* Instance() { return singleton_; }
 
   void AddField(const Field& field);
@@ -295,6 +294,7 @@
   void AddAnnotatedRoots();
   void Iterate();
 
+  void AddRetainReason(const Object& obj, const char* reason);
   void AddType(const AbstractType& type);
   void AddTypesOf(const Class& cls);
   void AddTypesOf(const Function& function);
@@ -306,12 +306,13 @@
   void AddConstObject(const class Instance& instance);
   void AddClosureCall(const String& selector,
                       const Array& arguments_descriptor);
-  void AddFunction(const Function& function, bool retain = true);
+  void AddFunction(const Function& function, const char* retain_reason);
   void AddInstantiatedClass(const Class& cls);
   void AddSelector(const String& selector);
   bool IsSent(const String& selector);
   bool IsHitByTableSelector(const Function& function);
-  bool MustRetainFunction(const Function& function);
+  // Returns the reason if the function must be retained, otherwise nullptr.
+  const char* MustRetainFunction(const Function& function);
 
   void ProcessFunction(const Function& function);
   void CheckForNewDynamicFunctions();
@@ -346,10 +347,6 @@
 
   void FinalizeAllClasses();
 
-  void set_il_serialization_stream(void* file) {
-    il_serialization_stream_ = file;
-  }
-
   Thread* thread() const { return thread_; }
   Zone* zone() const { return zone_; }
   Isolate* isolate() const { return isolate_; }
@@ -395,10 +392,10 @@
   compiler::DispatchTableGenerator* dispatch_table_generator_;
 
   bool get_runtime_type_is_unique_;
-  void* il_serialization_stream_;
 
   Phase phase_ = Phase::kPreparation;
   PrecompilerTracer* tracer_ = nullptr;
+  RetainedReasonsWriter* retained_reasons_writer_ = nullptr;
   bool is_tracing_ = false;
 };
 
diff --git a/runtime/vm/compiler/asm_intrinsifier_arm.cc b/runtime/vm/compiler/asm_intrinsifier_arm.cc
index 4dff2a2..101ea94 100644
--- a/runtime/vm/compiler/asm_intrinsifier_arm.cc
+++ b/runtime/vm/compiler/asm_intrinsifier_arm.cc
@@ -91,179 +91,6 @@
   __ b(not_smi, NE);
 }
 
-void AsmIntrinsifier::Integer_add(Assembler* assembler, Label* normal_ir_body) {
-  TestBothArgumentsSmis(assembler, normal_ir_body);  // Checks two smis.
-  __ adds(R0, R0, Operand(R1));                      // Adds.
-  READS_RETURN_ADDRESS_FROM_LR(__ bx(LR, VC));       // Return if no overflow.
-  // Otherwise fall through.
-  __ Bind(normal_ir_body);
-}
-
-void AsmIntrinsifier::Integer_sub(Assembler* assembler, Label* normal_ir_body) {
-  TestBothArgumentsSmis(assembler, normal_ir_body);
-  __ subs(R0, R1, Operand(R0));  // Subtract.
-  READS_RETURN_ADDRESS_FROM_LR(__ bx(LR, VC));  // Return if no overflow.
-  // Otherwise fall through.
-  __ Bind(normal_ir_body);
-}
-
-void AsmIntrinsifier::Integer_mul(Assembler* assembler, Label* normal_ir_body) {
-  TestBothArgumentsSmis(assembler, normal_ir_body);  // checks two smis
-  __ SmiUntag(R0);           // Untags R0. We only want result shifted by one.
-  __ smull(R0, IP, R0, R1);  // IP:R0 <- R0 * R1.
-  __ cmp(IP, Operand(R0, ASR, 31));
-  READS_RETURN_ADDRESS_FROM_LR(__ bx(LR, EQ));
-  __ Bind(normal_ir_body);  // Fall through on overflow.
-}
-
-// Optimizations:
-// - result is 0 if:
-//   - left is 0
-//   - left equals right
-// - result is left if
-//   - left > 0 && left < right
-// R1: Tagged left (dividend).
-// R0: Tagged right (divisor).
-// Returns:
-//   R1: Untagged fallthrough result (remainder to be adjusted), or
-//   R0: Tagged return result (remainder).
-static void EmitRemainderOperation(Assembler* assembler) {
-  Label modulo;
-  const Register left = R1;
-  const Register right = R0;
-  const Register result = R1;
-  const Register tmp = R2;
-  ASSERT(left == result);
-
-  // Check for quick zero results.
-  __ cmp(left, Operand(0));
-  __ mov(R0, Operand(0), EQ);
-  READS_RETURN_ADDRESS_FROM_LR(__ bx(LR, EQ));  // left is 0? Return 0.
-  __ cmp(left, Operand(right));
-  __ mov(R0, Operand(0), EQ);
-  READS_RETURN_ADDRESS_FROM_LR(__ bx(LR, EQ));  // left == right? Return 0.
-
-  // Check if result should be left.
-  __ cmp(left, Operand(0));
-  __ b(&modulo, LT);
-  // left is positive.
-  __ cmp(left, Operand(right));
-  // left is less than right, result is left.
-  __ mov(R0, Operand(left), LT);
-  READS_RETURN_ADDRESS_FROM_LR(__ bx(LR, LT));
-  __ Bind(&modulo);
-  // result <- left - right * (left / right)
-  __ SmiUntag(left);
-  __ SmiUntag(right);
-
-  __ IntegerDivide(tmp, left, right, D1, D0);
-
-  __ mls(result, right, tmp, left);  // result <- left - right * TMP
-}
-
-// Implementation:
-//  res = left % right;
-//  if (res < 0) {
-//    if (right < 0) {
-//      res = res - right;
-//    } else {
-//      res = res + right;
-//    }
-//  }
-void AsmIntrinsifier::Integer_mod(Assembler* assembler, Label* normal_ir_body) {
-  if (!TargetCPUFeatures::can_divide()) {
-    return;
-  }
-  // Check to see if we have integer division
-  __ ldr(R0, Address(SP, +0 * target::kWordSize));
-  __ ldr(R1, Address(SP, +1 * target::kWordSize));
-  __ orr(TMP, R0, Operand(R1));
-  __ tst(TMP, Operand(kSmiTagMask));
-  __ b(normal_ir_body, NE);
-  // R1: Tagged left (dividend).
-  // R0: Tagged right (divisor).
-  // Check if modulo by zero -> exception thrown in main function.
-  __ cmp(R0, Operand(0));
-  __ b(normal_ir_body, EQ);
-  EmitRemainderOperation(assembler);
-  // Untagged right in R0. Untagged remainder result in R1.
-
-  __ cmp(R1, Operand(0));
-  __ mov(R0, Operand(R1, LSL, 1), GE);  // Tag and move result to R0.
-  READS_RETURN_ADDRESS_FROM_LR(__ bx(LR, GE));
-  // Result is negative, adjust it.
-  __ cmp(R0, Operand(0));
-  __ sub(R0, R1, Operand(R0), LT);
-  __ add(R0, R1, Operand(R0), GE);
-  __ SmiTag(R0);
-  __ Ret();
-
-  __ Bind(normal_ir_body);
-}
-
-void AsmIntrinsifier::Integer_truncDivide(Assembler* assembler,
-                                          Label* normal_ir_body) {
-  if (!TargetCPUFeatures::can_divide()) {
-    return;
-  }
-  // Check to see if we have integer division
-
-  TestBothArgumentsSmis(assembler, normal_ir_body);
-  __ cmp(R0, Operand(0));
-  __ b(normal_ir_body, EQ);  // If b is 0, fall through.
-
-  __ SmiUntag(R0);
-  __ SmiUntag(R1);
-
-  __ IntegerDivide(R0, R1, R0, D1, D0);
-
-  // Check the corner case of dividing the 'MIN_SMI' with -1, in which case we
-  // cannot tag the result.
-  __ CompareImmediate(R0, 0x40000000);
-  __ SmiTag(R0, NE);  // Not equal. Okay to tag and return.
-  READS_RETURN_ADDRESS_FROM_LR(__ bx(LR, NE));
-  __ Bind(normal_ir_body);
-}
-
-void AsmIntrinsifier::Integer_negate(Assembler* assembler,
-                                     Label* normal_ir_body) {
-  __ ldr(R0, Address(SP, +0 * target::kWordSize));  // Grab first argument.
-  __ tst(R0, Operand(kSmiTagMask));                 // Test for Smi.
-  __ b(normal_ir_body, NE);
-  __ rsbs(R0, R0, Operand(0));  // R0 is a Smi. R0 <- 0 - R0.
-  READS_RETURN_ADDRESS_FROM_LR(__ bx(
-      LR, VC));  // Return if there wasn't overflow, fall through otherwise.
-  // R0 is not a Smi. Fall through.
-  __ Bind(normal_ir_body);
-}
-
-void AsmIntrinsifier::Integer_bitAnd(Assembler* assembler,
-                                     Label* normal_ir_body) {
-  TestBothArgumentsSmis(assembler, normal_ir_body);  // checks two smis
-  __ and_(R0, R0, Operand(R1));
-
-  __ Ret();
-  __ Bind(normal_ir_body);
-}
-
-void AsmIntrinsifier::Integer_bitOr(Assembler* assembler,
-                                    Label* normal_ir_body) {
-  TestBothArgumentsSmis(assembler, normal_ir_body);  // checks two smis
-  __ orr(R0, R0, Operand(R1));
-
-  __ Ret();
-  __ Bind(normal_ir_body);
-}
-
-void AsmIntrinsifier::Integer_bitXor(Assembler* assembler,
-                                     Label* normal_ir_body) {
-  TestBothArgumentsSmis(assembler, normal_ir_body);  // checks two smis
-  __ eor(R0, R0, Operand(R1));
-
-  __ Ret();
-  __ Bind(normal_ir_body);
-}
-
 void AsmIntrinsifier::Integer_shl(Assembler* assembler, Label* normal_ir_body) {
   ASSERT(kSmiTagShift == 1);
   ASSERT(kSmiTag == 0);
@@ -471,33 +298,6 @@
   Integer_equalToInteger(assembler, normal_ir_body);
 }
 
-void AsmIntrinsifier::Integer_sar(Assembler* assembler, Label* normal_ir_body) {
-  TestBothArgumentsSmis(assembler, normal_ir_body);
-  // Shift amount in R0. Value to shift in R1.
-
-  // Fall through if shift amount is negative.
-  __ SmiUntag(R0);
-  __ CompareImmediate(R0, 0);
-  __ b(normal_ir_body, LT);
-
-  // If shift amount is bigger than 31, set to 31.
-  __ CompareImmediate(R0, 0x1F);
-  __ LoadImmediate(R0, 0x1F, GT);
-  __ SmiUntag(R1);
-  __ mov(R0, Operand(R1, ASR, R0));
-  __ SmiTag(R0);
-  __ Ret();
-  __ Bind(normal_ir_body);
-}
-
-void AsmIntrinsifier::Smi_bitNegate(Assembler* assembler,
-                                    Label* normal_ir_body) {
-  __ ldr(R0, Address(SP, 0 * target::kWordSize));
-  __ mvn(R0, Operand(R0));
-  __ bic(R0, R0, Operand(kSmiTagMask));  // Remove inverted smi-tag.
-  __ Ret();
-}
-
 void AsmIntrinsifier::Smi_bitLength(Assembler* assembler,
                                     Label* normal_ir_body) {
   __ ldr(R0, Address(SP, 0 * target::kWordSize));
diff --git a/runtime/vm/compiler/asm_intrinsifier_arm64.cc b/runtime/vm/compiler/asm_intrinsifier_arm64.cc
index 3176eea..91c8e54 100644
--- a/runtime/vm/compiler/asm_intrinsifier_arm64.cc
+++ b/runtime/vm/compiler/asm_intrinsifier_arm64.cc
@@ -92,209 +92,6 @@
   __ BranchIfNotSmi(TMP, not_smi);
 }
 
-void AsmIntrinsifier::Integer_add(Assembler* assembler, Label* normal_ir_body) {
-  TestBothArgumentsSmis(assembler, normal_ir_body);  // Checks two smis.
-#if !defined(DART_COMPRESSED_POINTERS)
-  __ adds(R0, R0, Operand(R1));  // Add.
-  __ b(normal_ir_body, VS);  // Fall-through on overflow.
-#else
-  __ addsw(R0, R0, Operand(R1));  // Add (32-bit).
-  __ b(normal_ir_body, VS);       // Fall-through on overflow.
-  __ sxtw(R0, R0);                // Sign extend.
-#endif
-  __ ret();
-  __ Bind(normal_ir_body);
-}
-
-void AsmIntrinsifier::Integer_sub(Assembler* assembler, Label* normal_ir_body) {
-  TestBothArgumentsSmis(assembler, normal_ir_body);
-#if !defined(DART_COMPRESSED_POINTERS)
-  __ subs(R0, R1, Operand(R0));  // Subtract.
-  __ b(normal_ir_body, VS);      // Fall-through on overflow.
-#else
-  __ subsw(R0, R1, Operand(R0));  // Subtract (32-bit).
-  __ b(normal_ir_body, VS);       // Fall-through on overflow.
-  __ sxtw(R0, R0);                // Sign extend.
-#endif
-  __ ret();
-  __ Bind(normal_ir_body);
-}
-
-void AsmIntrinsifier::Integer_mul(Assembler* assembler, Label* normal_ir_body) {
-  TestBothArgumentsSmis(assembler, normal_ir_body);  // checks two smis
-  __ SmiUntag(R0);  // Untags R6. We only want result shifted by one.
-
-#if !defined(DART_COMPRESSED_POINTERS)
-  __ mul(TMP, R0, R1);
-  __ smulh(TMP2, R0, R1);
-  // TMP: result bits 64..127.
-#else
-  __ smull(TMP, R0, R1);
-  __ AsrImmediate(TMP2, TMP, 31);
-  // TMP: result bits 32..63.
-#endif
-  __ cmp(TMP2, Operand(TMP, ASR, 63));
-  __ b(normal_ir_body, NE);
-  __ mov(R0, TMP);
-  __ ret();
-  __ Bind(normal_ir_body);
-}
-
-// Optimizations:
-// - result is 0 if:
-//   - left is 0
-//   - left equals right
-// - result is left if
-//   - left > 0 && left < right
-// R1: Tagged left (dividend).
-// R0: Tagged right (divisor).
-// Returns:
-//   R1: Untagged fallthrough result (remainder to be adjusted), or
-//   R0: Tagged return result (remainder).
-static void EmitRemainderOperation(Assembler* assembler) {
-  Label return_zero, modulo;
-  const Register left = R1;
-  const Register right = R0;
-  const Register result = R1;
-  const Register tmp = R2;
-  ASSERT(left == result);
-
-  // Check for quick zero results.
-  __ CompareRegisters(left, ZR);
-  __ b(&return_zero, EQ);
-  __ CompareRegisters(left, right);
-  __ b(&return_zero, EQ);
-
-  // Check if result should be left.
-  __ CompareRegisters(left, ZR);
-  __ b(&modulo, LT);
-  // left is positive.
-  __ CompareRegisters(left, right);
-  // left is less than right, result is left.
-  __ b(&modulo, GT);
-  __ mov(R0, left);
-  __ ret();
-
-  __ Bind(&return_zero);
-  __ mov(R0, ZR);
-  __ ret();
-
-  __ Bind(&modulo);
-  // result <- left - right * (left / right)
-  __ SmiUntag(left);
-  __ SmiUntag(right);
-
-  __ sdiv(tmp, left, right);
-  __ msub(result, right, tmp, left);  // result <- left - right * tmp
-}
-
-// Implementation:
-//  res = left % right;
-//  if (res < 0) {
-//    if (right < 0) {
-//      res = res - right;
-//    } else {
-//      res = res + right;
-//    }
-//  }
-void AsmIntrinsifier::Integer_mod(Assembler* assembler, Label* normal_ir_body) {
-  // Check to see if we have integer division
-  Label neg_remainder, fall_through;
-  __ ldr(R0, Address(SP, +0 * target::kWordSize));
-  __ ldr(R1, Address(SP, +1 * target::kWordSize));
-  __ orr(TMP, R0, Operand(R1));
-  __ BranchIfNotSmi(TMP, normal_ir_body);
-  // R1: Tagged left (dividend).
-  // R0: Tagged right (divisor).
-  // Check if modulo by zero -> exception thrown in main function.
-  __ CompareRegisters(R0, ZR);
-  __ b(normal_ir_body, EQ);
-  EmitRemainderOperation(assembler);
-  // Untagged right in R0. Untagged remainder result in R1.
-
-  __ CompareRegisters(R1, ZR);
-  __ b(&neg_remainder, LT);
-  __ SmiTag(R0, R1);  // Tag and move result to R0.
-  __ ret();
-
-  __ Bind(&neg_remainder);
-  // Result is negative, adjust it.
-  __ CompareRegisters(R0, ZR);
-  __ sub(TMP, R1, Operand(R0));
-  __ add(TMP2, R1, Operand(R0));
-  __ csel(R0, TMP2, TMP, GE);
-  __ SmiTag(R0);
-  __ ret();
-
-  __ Bind(normal_ir_body);
-}
-
-void AsmIntrinsifier::Integer_truncDivide(Assembler* assembler,
-                                          Label* normal_ir_body) {
-  // Check to see if we have integer division
-
-  TestBothArgumentsSmis(assembler, normal_ir_body);
-  __ CompareRegisters(R0, ZR);
-  __ b(normal_ir_body, EQ);  // If b is 0, fall through.
-
-  __ SmiUntag(R0);
-  __ SmiUntag(R1);
-
-  __ sdiv(R0, R1, R0);
-
-  // Check the corner case of dividing the 'MIN_SMI' with -1, in which case we
-  // cannot tag the result.
-#if !defined(DART_COMPRESSED_POINTERS)
-  __ CompareImmediate(R0, 0x4000000000000000);
-#else
-  __ CompareImmediate(R0, 0x40000000);
-#endif
-  __ b(normal_ir_body, EQ);
-  __ SmiTag(R0);  // Not equal. Okay to tag and return.
-  __ ret();       // Return.
-  __ Bind(normal_ir_body);
-}
-
-void AsmIntrinsifier::Integer_negate(Assembler* assembler,
-                                     Label* normal_ir_body) {
-  __ ldr(R0, Address(SP, +0 * target::kWordSize));  // Grab first argument.
-  __ BranchIfNotSmi(R0, normal_ir_body);
-#if !defined(DART_COMPRESSED_POINTERS)
-  __ negs(R0, R0);
-  __ b(normal_ir_body, VS);
-#else
-  __ negsw(R0, R0);
-  __ b(normal_ir_body, VS);
-  __ sxtw(R0, R0);
-#endif
-  __ ret();
-  __ Bind(normal_ir_body);
-}
-
-void AsmIntrinsifier::Integer_bitAnd(Assembler* assembler,
-                                     Label* normal_ir_body) {
-  TestBothArgumentsSmis(assembler, normal_ir_body);  // Checks two smis.
-  __ and_(R0, R0, Operand(R1));
-  __ ret();
-  __ Bind(normal_ir_body);
-}
-
-void AsmIntrinsifier::Integer_bitOr(Assembler* assembler,
-                                    Label* normal_ir_body) {
-  TestBothArgumentsSmis(assembler, normal_ir_body);  // Checks two smis.
-  __ orr(R0, R0, Operand(R1));
-  __ ret();
-  __ Bind(normal_ir_body);
-}
-
-void AsmIntrinsifier::Integer_bitXor(Assembler* assembler,
-                                     Label* normal_ir_body) {
-  TestBothArgumentsSmis(assembler, normal_ir_body);  // Checks two smis.
-  __ eor(R0, R0, Operand(R1));
-  __ ret();
-  __ Bind(normal_ir_body);
-}
-
 void AsmIntrinsifier::Integer_shl(Assembler* assembler, Label* normal_ir_body) {
   ASSERT(kSmiTagShift == 1);
   ASSERT(kSmiTag == 0);
@@ -304,25 +101,20 @@
   const Register result = R0;
 
   TestBothArgumentsSmis(assembler, normal_ir_body);
-  __ CompareImmediate(right, target::ToRawSmi(target::kSmiBits));
+  __ CompareImmediate(right, target::ToRawSmi(target::kSmiBits),
+                      compiler::kObjectBytes);
   __ b(normal_ir_body, CS);
 
   // Left is not a constant.
   // Check if count too large for handling it inlined.
   __ SmiUntag(TMP, right);  // SmiUntag right into TMP.
   // Overflow test (preserve left, right, and TMP);
-#if !defined(DART_COMPRESSED_POINTERS)
-  __ lslv(temp, left, TMP);
-  __ asrv(TMP2, temp, TMP);
-  __ CompareRegisters(left, TMP2);
-#else
-  __ lslvw(temp, left, TMP);
-  __ asrvw(TMP2, temp, TMP);
-  __ cmpw(left, Operand(TMP2));
-#endif
+  __ lslv(temp, left, TMP, kObjectBytes);
+  __ asrv(TMP2, temp, TMP, kObjectBytes);
+  __ cmp(left, Operand(TMP2), kObjectBytes);
   __ b(normal_ir_body, NE);  // Overflow.
   // Shift for result now we know there is no overflow.
-  __ lslv(result, left, TMP);
+  __ lslv(result, left, TMP, kObjectBytes);
   __ ret();
   __ Bind(normal_ir_body);
 }
@@ -333,7 +125,7 @@
   Label true_label;
   TestBothArgumentsSmis(assembler, normal_ir_body);
   // R0 contains the right argument, R1 the left.
-  __ CompareRegisters(R1, R0);
+  __ CompareObjectRegisters(R1, R0);
   __ LoadObject(R0, CastHandle<Object>(FalseObject()));
   __ LoadObject(TMP, CastHandle<Object>(TrueObject()));
   __ csel(R0, TMP, R0, true_condition);
@@ -369,7 +161,7 @@
   // For integer receiver '===' check first.
   __ ldr(R0, Address(SP, 0 * target::kWordSize));
   __ ldr(R1, Address(SP, 1 * target::kWordSize));
-  __ cmp(R0, Operand(R1));
+  __ CompareObjectRegisters(R0, R1);
   __ b(&true_label, EQ);
 
   __ orr(R2, R0, Operand(R1));
@@ -418,42 +210,20 @@
   Integer_equalToInteger(assembler, normal_ir_body);
 }
 
-void AsmIntrinsifier::Integer_sar(Assembler* assembler, Label* normal_ir_body) {
-  TestBothArgumentsSmis(assembler, normal_ir_body);
-  // Shift amount in R0. Value to shift in R1.
-
-  // Fall through if shift amount is negative.
-  __ SmiUntag(R0);
-  __ CompareRegisters(R0, ZR);
-  __ b(normal_ir_body, LT);
-
-  // If shift amount is bigger than 63, set to 63.
-  __ LoadImmediate(TMP, 0x3F);
-  __ CompareRegisters(R0, TMP);
-  __ csel(R0, TMP, R0, GT);
-  __ SmiUntag(R1);
-  __ asrv(R0, R1, R0);
-  __ SmiTag(R0);
-  __ ret();
-  __ Bind(normal_ir_body);
-}
-
-void AsmIntrinsifier::Smi_bitNegate(Assembler* assembler,
-                                    Label* normal_ir_body) {
-  __ ldr(R0, Address(SP, 0 * target::kWordSize));
-  __ mvn(R0, R0);
-  __ andi(R0, R0, Immediate(~kSmiTagMask));  // Remove inverted smi-tag.
-  __ ret();
-}
-
 void AsmIntrinsifier::Smi_bitLength(Assembler* assembler,
                                     Label* normal_ir_body) {
   __ ldr(R0, Address(SP, 0 * target::kWordSize));
   __ SmiUntag(R0);
   // XOR with sign bit to complement bits if value is negative.
+#if !defined(DART_COMPRESSED_POINTERS)
   __ eor(R0, R0, Operand(R0, ASR, 63));
   __ clz(R0, R0);
   __ LoadImmediate(R1, 64);
+#else
+  __ eorw(R0, R0, Operand(R0, ASR, 31));
+  __ clzw(R0, R0);
+  __ LoadImmediate(R1, 32);
+#endif
   __ sub(R0, R1, Operand(R0));
   __ SmiTag(R0);
   __ ret();
@@ -1349,14 +1119,14 @@
   __ fcmpd(V0, V0);
   __ b(normal_ir_body, VS);
 
-#if !defined(DART_COMPRESSED_POINTERS)
   __ fcvtzdsx(R0, V0);
+
+#if !defined(DART_COMPRESSED_POINTERS)
   // Overflow is signaled with minint.
   // Check for overflow and that it fits into Smi.
   __ CompareImmediate(R0, 0xC000000000000000);
   __ b(normal_ir_body, MI);
 #else
-  __ fcvtzdsw(R0, V0);
   // Overflow is signaled with minint.
   // Check for overflow and that it fits into Smi.
   __ AsrImmediate(TMP, R0, 30);
@@ -1397,14 +1167,8 @@
   // overflow is signalled by fcvt through clamping R0 to either
   // INT64_MAX or INT64_MIN (saturation).
   ASSERT(kSmiTag == 0 && kSmiTagShift == 1);
-#if !defined(DART_COMPRESSED_POINTERS)
-  __ adds(R0, R0, Operand(R0));
+  __ adds(R0, R0, Operand(R0), kObjectBytes);
   __ b(normal_ir_body, VS);
-#else
-  __ addsw(R0, R0, Operand(R0));
-  __ b(normal_ir_body, VS);
-  __ sxtw(R0, R0);  // Sign extend.
-#endif
 
   // Compare the two double values. If they are equal, we return the
   // Smi tagged result immediately as the hash code.
@@ -1476,7 +1240,7 @@
                                    Label* normal_ir_body) {
   __ ldr(R0, Address(SP, 0 * target::kWordSize));
   __ ldr(R1, Address(SP, 1 * target::kWordSize));
-  __ cmp(R0, Operand(R1));
+  __ CompareObjectRegisters(R0, R1);
   __ LoadObject(R0, CastHandle<Object>(FalseObject()));
   __ LoadObject(TMP, CastHandle<Object>(TrueObject()));
   __ csel(R0, TMP, R0, EQ);
@@ -1587,7 +1351,8 @@
   __ CompareImmediate(R3, 0);
   __ b(normal_ir_body, NE);
 
-  __ ldr(R0, FieldAddress(R2, target::Class::declaration_type_offset()));
+  __ LoadCompressed(R0,
+                    FieldAddress(R2, target::Class::declaration_type_offset()));
   __ CompareObject(R0, NullObject());
   __ b(normal_ir_body, EQ);
   __ ret();
@@ -1692,7 +1457,7 @@
 void AsmIntrinsifier::Type_getHashCode(Assembler* assembler,
                                        Label* normal_ir_body) {
   __ ldr(R0, Address(SP, 0 * target::kWordSize));
-  __ ldr(R0, FieldAddress(R0, target::Type::hash_offset()));
+  __ LoadCompressed(R0, FieldAddress(R0, target::Type::hash_offset()));
   __ cbz(normal_ir_body, R0);
   __ ret();
   // Hash not yet computed.
@@ -1704,7 +1469,7 @@
   Label equal, not_equal, equiv_cids, check_legacy;
 
   __ ldp(R1, R2, Address(SP, 0 * target::kWordSize, Address::PairOffset));
-  __ cmp(R1, Operand(R2));
+  __ CompareObjectRegisters(R1, R2);
   __ b(&equal, EQ);
 
   // R1 might not be a Type object, so check that first (R2 should be though,
@@ -1714,9 +1479,11 @@
   __ b(normal_ir_body, NE);
 
   // Check if types are syntactically equal.
-  __ ldr(R3, FieldAddress(R1, target::Type::type_class_id_offset()));
+  __ LoadCompressedSmi(R3,
+                       FieldAddress(R1, target::Type::type_class_id_offset()));
   __ SmiUntag(R3);
-  __ ldr(R4, FieldAddress(R2, target::Type::type_class_id_offset()));
+  __ LoadCompressedSmi(R4,
+                       FieldAddress(R2, target::Type::type_class_id_offset()));
   __ SmiUntag(R4);
   EquivalentClassIds(assembler, normal_ir_body, &equiv_cids, &not_equal, R3, R4,
                      R0);
@@ -1756,7 +1523,7 @@
 void AsmIntrinsifier::FunctionType_getHashCode(Assembler* assembler,
                                                Label* normal_ir_body) {
   __ ldr(R0, Address(SP, 0 * target::kWordSize));
-  __ ldr(R0, FieldAddress(R0, target::FunctionType::hash_offset()));
+  __ LoadCompressed(R0, FieldAddress(R0, target::FunctionType::hash_offset()));
   __ cbz(normal_ir_body, R0);
   __ ret();
   // Hash not yet computed.
@@ -1766,7 +1533,7 @@
 void AsmIntrinsifier::FunctionType_equality(Assembler* assembler,
                                             Label* normal_ir_body) {
   __ ldp(R1, R2, Address(SP, 0 * target::kWordSize, Address::PairOffset));
-  __ cmp(R1, Operand(R2));
+  __ CompareObjectRegisters(R1, R2);
   __ b(normal_ir_body, NE);
 
   __ LoadObject(R0, CastHandle<Object>(TrueObject()));
@@ -1807,10 +1574,11 @@
                                             Label* return_true,
                                             Label* return_false) {
   __ SmiUntag(R1);
-  __ ldr(R8, FieldAddress(R0, target::String::length_offset()));  // this.length
+  __ LoadCompressedSmi(
+      R8, FieldAddress(R0, target::String::length_offset()));  // this.length
   __ SmiUntag(R8);
-  __ ldr(R9,
-         FieldAddress(R2, target::String::length_offset()));  // other.length
+  __ LoadCompressedSmi(
+      R9, FieldAddress(R2, target::String::length_offset()));  // other.length
   __ SmiUntag(R9);
 
   // if (other.length == 0) return true;
@@ -1917,7 +1685,7 @@
   __ ldr(R0, Address(SP, 1 * target::kWordSize));  // String.
   __ BranchIfNotSmi(R1, normal_ir_body);           // Index is not a Smi.
   // Range check.
-  __ ldr(R2, FieldAddress(R0, target::String::length_offset()));
+  __ LoadCompressedSmi(R2, FieldAddress(R0, target::String::length_offset()));
   __ cmp(R1, Operand(R2));
   __ b(normal_ir_body, CS);  // Runtime throws exception.
 
@@ -1954,8 +1722,8 @@
 void AsmIntrinsifier::StringBaseIsEmpty(Assembler* assembler,
                                         Label* normal_ir_body) {
   __ ldr(R0, Address(SP, 0 * target::kWordSize));
-  __ ldr(R0, FieldAddress(R0, target::String::length_offset()));
-  __ cmp(R0, Operand(target::ToRawSmi(0)));
+  __ LoadCompressedSmi(R0, FieldAddress(R0, target::String::length_offset()));
+  __ cmp(R0, Operand(target::ToRawSmi(0)), kObjectBytes);
   __ LoadObject(R0, CastHandle<Object>(TrueObject()));
   __ LoadObject(TMP, CastHandle<Object>(FalseObject()));
   __ csel(R0, TMP, R0, NE);
@@ -1973,7 +1741,7 @@
   __ ret();  // Return if already computed.
 
   __ Bind(&compute_hash);
-  __ ldr(R2, FieldAddress(R1, target::String::length_offset()));
+  __ LoadCompressedSmi(R2, FieldAddress(R1, target::String::length_offset()));
   __ SmiUntag(R2);
 
   Label done;
@@ -2108,7 +1876,7 @@
   }
 
   // Set the length field using the saved length (R6).
-  __ StoreIntoObjectNoBarrier(
+  __ StoreCompressedIntoObjectNoBarrier(
       R0, FieldAddress(R0, target::String::length_offset()), R6);
   __ b(ok);
 }
@@ -2234,7 +2002,7 @@
   __ ldr(R1, Address(SP, 0 * target::kWordSize));  // Other.
 
   // Are identical?
-  __ cmp(R0, Operand(R1));
+  __ CompareObjectRegisters(R0, R1);
   __ b(&is_true, EQ);
 
   // Is other OneByteString?
@@ -2243,9 +2011,9 @@
   __ b(normal_ir_body, NE);
 
   // Have same length?
-  __ ldr(R2, FieldAddress(R0, target::String::length_offset()));
-  __ ldr(R3, FieldAddress(R1, target::String::length_offset()));
-  __ cmp(R2, Operand(R3));
+  __ LoadCompressedSmi(R2, FieldAddress(R0, target::String::length_offset()));
+  __ LoadCompressedSmi(R3, FieldAddress(R1, target::String::length_offset()));
+  __ CompareObjectRegisters(R2, R3);
   __ b(&is_false, NE);
 
   // Check contents, no fall-through possible.
@@ -2320,16 +2088,21 @@
   __ ldr(R1, Address(SP, kStringParamOffset));
   __ LoadClassId(R1, R1);
   __ AddImmediate(R1, -kOneByteStringCid);
+#if !defined(DART_COMPRESSED_POINTERS)
   __ add(R1, R2, Operand(R1, LSL, target::kWordSizeLog2));
-  __ ldr(R0, FieldAddress(R1, target::RegExp::function_offset(kOneByteStringCid,
-                                                              sticky)));
+#else
+  __ add(R1, R2, Operand(R1, LSL, target::kWordSizeLog2 - 1));
+#endif
+  __ LoadCompressed(R0, FieldAddress(R1, target::RegExp::function_offset(
+                                             kOneByteStringCid, sticky)));
 
   // Registers are now set up for the lazy compile stub. It expects the function
   // in R0, the argument descriptor in R4, and IC-Data in R5.
   __ eor(R5, R5, Operand(R5));
 
   // Tail-call the function.
-  __ ldr(CODE_REG, FieldAddress(R0, target::Function::code_offset()));
+  __ LoadCompressed(CODE_REG,
+                    FieldAddress(R0, target::Function::code_offset()));
   __ ldr(R1, FieldAddress(R0, target::Function::entry_point_offset()));
   __ br(R1);
 }
diff --git a/runtime/vm/compiler/asm_intrinsifier_ia32.cc b/runtime/vm/compiler/asm_intrinsifier_ia32.cc
index a6d5e20..9cfe941 100644
--- a/runtime/vm/compiler/asm_intrinsifier_ia32.cc
+++ b/runtime/vm/compiler/asm_intrinsifier_ia32.cc
@@ -93,188 +93,6 @@
   __ j(NOT_ZERO, not_smi, Assembler::kNearJump);
 }
 
-void AsmIntrinsifier::Integer_add(Assembler* assembler, Label* normal_ir_body) {
-  TestBothArgumentsSmis(assembler, normal_ir_body);
-  __ addl(EAX, Address(ESP, +2 * target::kWordSize));
-  __ j(OVERFLOW, normal_ir_body, Assembler::kNearJump);
-  // Result is in EAX.
-  __ ret();
-  __ Bind(normal_ir_body);
-}
-
-void AsmIntrinsifier::Integer_sub(Assembler* assembler, Label* normal_ir_body) {
-  TestBothArgumentsSmis(assembler, normal_ir_body);
-  __ movl(EBX, EAX);
-  __ movl(EAX, Address(ESP, +2 * target::kWordSize));
-  __ subl(EAX, EBX);
-  __ j(OVERFLOW, normal_ir_body, Assembler::kNearJump);
-  // Result is in EAX.
-  __ ret();
-  __ Bind(normal_ir_body);
-}
-
-void AsmIntrinsifier::Integer_mul(Assembler* assembler, Label* normal_ir_body) {
-  TestBothArgumentsSmis(assembler, normal_ir_body);
-  ASSERT(kSmiTag == 0);  // Adjust code below if not the case.
-  __ SmiUntag(EAX);
-  __ imull(EAX, Address(ESP, +2 * target::kWordSize));
-  __ j(OVERFLOW, normal_ir_body, Assembler::kNearJump);
-  // Result is in EAX.
-  __ ret();
-  __ Bind(normal_ir_body);
-}
-
-// Optimizations:
-// - result is 0 if:
-//   - left is 0
-//   - left equals right
-// - result is left if
-//   - left > 0 && left < right
-// EAX: Tagged left (dividend).
-// EBX: Tagged right (divisor).
-// Returns:
-//   EDX: Untagged fallthrough result (remainder to be adjusted), or
-//   EAX: Tagged return result (remainder).
-static void EmitRemainderOperation(Assembler* assembler) {
-  Label return_zero, modulo;
-  // Check for quick zero results.
-  __ cmpl(EAX, Immediate(0));
-  __ j(EQUAL, &return_zero, Assembler::kNearJump);
-  __ cmpl(EAX, EBX);
-  __ j(EQUAL, &return_zero, Assembler::kNearJump);
-
-  // Check if result equals left.
-  __ cmpl(EAX, Immediate(0));
-  __ j(LESS, &modulo, Assembler::kNearJump);
-  // left is positive.
-  __ cmpl(EAX, EBX);
-  __ j(GREATER, &modulo, Assembler::kNearJump);
-  // left is less than right, result is left (EAX).
-  __ ret();
-
-  __ Bind(&return_zero);
-  __ xorl(EAX, EAX);
-  __ ret();
-
-  __ Bind(&modulo);
-  __ SmiUntag(EBX);
-  __ SmiUntag(EAX);
-  __ cdq();
-  __ idivl(EBX);
-}
-
-// Implementation:
-//  res = left % right;
-//  if (res < 0) {
-//    if (right < 0) {
-//      res = res - right;
-//    } else {
-//      res = res + right;
-//    }
-//  }
-void AsmIntrinsifier::Integer_mod(Assembler* assembler, Label* normal_ir_body) {
-  Label subtract;
-  __ movl(EAX, Address(ESP, +2 * target::kWordSize));
-  __ movl(EBX, Address(ESP, +1 * target::kWordSize));
-  __ orl(EBX, EAX);
-  __ testl(EBX, Immediate(kSmiTagMask));
-  __ j(NOT_ZERO, normal_ir_body);
-  __ movl(EBX, Address(ESP, +1 * target::kWordSize));
-  // EAX: Tagged left (dividend).
-  // EBX: Tagged right (divisor).
-  // Check if modulo by zero -> exception thrown in main function.
-  __ cmpl(EBX, Immediate(0));
-  __ j(EQUAL, normal_ir_body, Assembler::kNearJump);
-  EmitRemainderOperation(assembler);
-  // Untagged remainder result in EDX.
-  Label done;
-  __ movl(EAX, EDX);
-  __ cmpl(EAX, Immediate(0));
-  __ j(GREATER_EQUAL, &done, Assembler::kNearJump);
-  // Result is negative, adjust it.
-  __ cmpl(EBX, Immediate(0));
-  __ j(LESS, &subtract, Assembler::kNearJump);
-  __ addl(EAX, EBX);
-  __ SmiTag(EAX);
-  __ ret();
-
-  __ Bind(&subtract);
-  __ subl(EAX, EBX);
-
-  __ Bind(&done);
-  // The remainder of two smis is always a smi, no overflow check needed.
-  __ SmiTag(EAX);
-  __ ret();
-
-  __ Bind(normal_ir_body);
-}
-
-void AsmIntrinsifier::Integer_truncDivide(Assembler* assembler,
-                                          Label* normal_ir_body) {
-  TestBothArgumentsSmis(assembler, normal_ir_body);
-  // EAX: right argument (divisor)
-  __ cmpl(EAX, Immediate(0));
-  __ j(EQUAL, normal_ir_body, Assembler::kNearJump);
-  __ movl(EBX, EAX);
-  __ SmiUntag(EBX);
-  __ movl(EAX,
-          Address(ESP, +2 * target::kWordSize));  // Left argument (dividend).
-  __ SmiUntag(EAX);
-  __ pushl(EDX);  // Preserve EDX in case of 'fall_through'.
-  __ cdq();
-  __ idivl(EBX);
-  __ popl(EDX);
-  // Check the corner case of dividing the 'MIN_SMI' with -1, in which case we
-  // cannot tag the result.
-  __ cmpl(EAX, Immediate(0x40000000));
-  __ j(EQUAL, normal_ir_body);
-  __ SmiTag(EAX);
-  __ ret();
-  __ Bind(normal_ir_body);
-}
-
-void AsmIntrinsifier::Integer_negate(Assembler* assembler,
-                                     Label* normal_ir_body) {
-  __ movl(EAX, Address(ESP, +1 * target::kWordSize));
-  __ testl(EAX, Immediate(kSmiTagMask));
-  __ j(NOT_ZERO, normal_ir_body, Assembler::kNearJump);  // Non-smi value.
-  __ negl(EAX);
-  __ j(OVERFLOW, normal_ir_body, Assembler::kNearJump);
-  // Result is in EAX.
-  __ ret();
-  __ Bind(normal_ir_body);
-}
-
-void AsmIntrinsifier::Integer_bitAnd(Assembler* assembler,
-                                     Label* normal_ir_body) {
-  TestBothArgumentsSmis(assembler, normal_ir_body);
-  __ movl(EBX, Address(ESP, +2 * target::kWordSize));
-  __ andl(EAX, EBX);
-  // Result is in EAX.
-  __ ret();
-  __ Bind(normal_ir_body);
-}
-
-void AsmIntrinsifier::Integer_bitOr(Assembler* assembler,
-                                    Label* normal_ir_body) {
-  TestBothArgumentsSmis(assembler, normal_ir_body);
-  __ movl(EBX, Address(ESP, +2 * target::kWordSize));
-  __ orl(EAX, EBX);
-  // Result is in EAX.
-  __ ret();
-  __ Bind(normal_ir_body);
-}
-
-void AsmIntrinsifier::Integer_bitXor(Assembler* assembler,
-                                     Label* normal_ir_body) {
-  TestBothArgumentsSmis(assembler, normal_ir_body);
-  __ movl(EBX, Address(ESP, +2 * target::kWordSize));
-  __ xorl(EAX, EBX);
-  // Result is in EAX.
-  __ ret();
-  __ Bind(normal_ir_body);
-}
-
 void AsmIntrinsifier::Integer_shl(Assembler* assembler, Label* normal_ir_body) {
   ASSERT(kSmiTagShift == 1);
   ASSERT(kSmiTag == 0);
@@ -483,40 +301,7 @@
   Integer_equalToInteger(assembler, normal_ir_body);
 }
 
-void AsmIntrinsifier::Integer_sar(Assembler* assembler, Label* normal_ir_body) {
-  Label shift_count_ok;
-  TestBothArgumentsSmis(assembler, normal_ir_body);
-  // Can destroy ECX since we are not falling through.
-  const Immediate& count_limit = Immediate(0x1F);
-  // Check that the count is not larger than what the hardware can handle.
-  // For shifting right a Smi the result is the same for all numbers
-  // >= count_limit.
-  __ SmiUntag(EAX);
-  // Negative counts throw exception.
-  __ cmpl(EAX, Immediate(0));
-  __ j(LESS, normal_ir_body, Assembler::kNearJump);
-  __ cmpl(EAX, count_limit);
-  __ j(LESS_EQUAL, &shift_count_ok, Assembler::kNearJump);
-  __ movl(EAX, count_limit);
-  __ Bind(&shift_count_ok);
-  __ movl(ECX, EAX);  // Shift amount must be in ECX.
-  __ movl(EAX, Address(ESP, +2 * target::kWordSize));  // Value.
-  __ SmiUntag(EAX);                                    // Value.
-  __ sarl(EAX, ECX);
-  __ SmiTag(EAX);
-  __ ret();
-  __ Bind(normal_ir_body);
-}
-
 // Argument is Smi (receiver).
-void AsmIntrinsifier::Smi_bitNegate(Assembler* assembler,
-                                    Label* normal_ir_body) {
-  __ movl(EAX, Address(ESP, +1 * target::kWordSize));  // Receiver.
-  __ notl(EAX);
-  __ andl(EAX, Immediate(~kSmiTagMask));  // Remove inverted smi-tag.
-  __ ret();
-}
-
 void AsmIntrinsifier::Smi_bitLength(Assembler* assembler,
                                     Label* normal_ir_body) {
   ASSERT(kSmiTagShift == 1);
diff --git a/runtime/vm/compiler/asm_intrinsifier_x64.cc b/runtime/vm/compiler/asm_intrinsifier_x64.cc
index 3254745..c47d307 100644
--- a/runtime/vm/compiler/asm_intrinsifier_x64.cc
+++ b/runtime/vm/compiler/asm_intrinsifier_x64.cc
@@ -90,291 +90,13 @@
   __ j(NOT_ZERO, not_smi);
 }
 
-void AsmIntrinsifier::Integer_add(Assembler* assembler, Label* normal_ir_body) {
-  TestBothArgumentsSmis(assembler, normal_ir_body);
-  // RAX contains right argument.
-#if !defined(DART_COMPRESSED_POINTERS)
-  __ addq(RAX, Address(RSP, +2 * target::kWordSize));
-  __ j(OVERFLOW, normal_ir_body, Assembler::kNearJump);
-#else
-  __ addl(RAX, Address(RSP, +2 * target::kWordSize));
-  __ j(OVERFLOW, normal_ir_body, Assembler::kNearJump);
-  __ movsxd(RAX, RAX);
-#endif
-  // Result is in RAX.
-  __ ret();
-  __ Bind(normal_ir_body);
-}
-
-void AsmIntrinsifier::Integer_sub(Assembler* assembler, Label* normal_ir_body) {
-  TestBothArgumentsSmis(assembler, normal_ir_body);
-  // RAX contains right argument, which is the actual subtrahend of subtraction.
-  __ movq(RCX, RAX);
-  __ movq(RAX, Address(RSP, +2 * target::kWordSize));
-#if !defined(DART_COMPRESSED_POINTERS)
-  __ subq(RAX, RCX);
-  __ j(OVERFLOW, normal_ir_body, Assembler::kNearJump);
-#else
-  __ subl(RAX, RCX);
-  __ j(OVERFLOW, normal_ir_body, Assembler::kNearJump);
-  __ movsxd(RAX, RAX);
-#endif
-  // Result is in RAX.
-  __ ret();
-  __ Bind(normal_ir_body);
-}
-
-void AsmIntrinsifier::Integer_mul(Assembler* assembler, Label* normal_ir_body) {
-  TestBothArgumentsSmis(assembler, normal_ir_body);
-  // RAX is the right argument.
-  ASSERT(kSmiTag == 0);  // Adjust code below if not the case.
-  __ SmiUntag(RAX);
-#if !defined(DART_COMPRESSED_POINTERS)
-  __ imulq(RAX, Address(RSP, +2 * target::kWordSize));
-  __ j(OVERFLOW, normal_ir_body, Assembler::kNearJump);
-#else
-  __ imull(RAX, Address(RSP, +2 * target::kWordSize));
-  __ j(OVERFLOW, normal_ir_body, Assembler::kNearJump);
-  __ movsxd(RAX, RAX);
-#endif
-  // Result is in RAX.
-  __ ret();
-  __ Bind(normal_ir_body);
-}
-
-// Optimizations:
-// - result is 0 if:
-//   - left is 0
-//   - left equals right
-// - result is left if
-//   - left > 0 && left < right
-// RAX: Tagged left (dividend).
-// RCX: Tagged right (divisor).
-// Returns:
-//   RAX: Untagged fallthrough result (remainder to be adjusted), or
-//   RAX: Tagged return result (remainder).
-static void EmitRemainderOperation(Assembler* assembler) {
-  Label return_zero, try_modulo, not_32bit, done;
-  // Check for quick zero results.
-  __ cmpq(RAX, Immediate(0));
-  __ j(EQUAL, &return_zero, Assembler::kNearJump);
-  __ cmpq(RAX, RCX);
-  __ j(EQUAL, &return_zero, Assembler::kNearJump);
-
-  // Check if result equals left.
-  __ cmpq(RAX, Immediate(0));
-  __ j(LESS, &try_modulo, Assembler::kNearJump);
-  // left is positive.
-  __ cmpq(RAX, RCX);
-  __ j(GREATER, &try_modulo, Assembler::kNearJump);
-  // left is less than right, result is left (RAX).
-  __ ret();
-
-  __ Bind(&return_zero);
-  __ xorq(RAX, RAX);
-  __ ret();
-
-  __ Bind(&try_modulo);
-
-#if !defined(DART_COMPRESSED_POINTERS)
-  // Check if both operands fit into 32bits as idiv with 64bit operands
-  // requires twice as many cycles and has much higher latency. We are checking
-  // this before untagging them to avoid corner case dividing INT_MAX by -1 that
-  // raises exception because quotient is too large for 32bit register.
-  __ movsxd(RBX, RAX);
-  __ cmpq(RBX, RAX);
-  __ j(NOT_EQUAL, &not_32bit, Assembler::kNearJump);
-  __ movsxd(RBX, RCX);
-  __ cmpq(RBX, RCX);
-  __ j(NOT_EQUAL, &not_32bit, Assembler::kNearJump);
-#endif
-
-  // Both operands are 31bit smis. Divide using 32bit idiv.
-  __ SmiUntag(RAX);
-  __ SmiUntag(RCX);
-  __ cdq();
-  __ idivl(RCX);
-  __ movsxd(RAX, RDX);
-#if !defined(DART_COMPRESSED_POINTERS)
-  __ jmp(&done, Assembler::kNearJump);
-
-  // Divide using 64bit idiv.
-  __ Bind(&not_32bit);
-  __ SmiUntag(RAX);
-  __ SmiUntag(RCX);
-  __ cqo();
-  __ idivq(RCX);
-  __ movq(RAX, RDX);
-  __ Bind(&done);
-#endif
-}
-
-// Implementation:
-//  res = left % right;
-//  if (res < 0) {
-//    if (right < 0) {
-//      res = res - right;
-//    } else {
-//      res = res + right;
-//    }
-//  }
-void AsmIntrinsifier::Integer_mod(Assembler* assembler, Label* normal_ir_body) {
-  Label negative_result;
-
-  __ movq(RAX, Address(RSP, +2 * target::kWordSize));
-  __ movq(RCX, Address(RSP, +1 * target::kWordSize));
-  __ orq(RCX, RAX);
-  __ testq(RCX, Immediate(kSmiTagMask));
-  __ j(NOT_ZERO, normal_ir_body);
-  __ movq(RCX, Address(RSP, +1 * target::kWordSize));
-  // RAX: Tagged left (dividend).
-  // RCX: Tagged right (divisor).
-  __ cmpq(RCX, Immediate(0));
-  __ j(EQUAL, normal_ir_body);
-  EmitRemainderOperation(assembler);
-  // Untagged remainder result in RAX.
-  __ cmpq(RAX, Immediate(0));
-  __ j(LESS, &negative_result, Assembler::kNearJump);
-  __ SmiTag(RAX);
-  __ ret();
-
-  __ Bind(&negative_result);
-  Label subtract;
-  // RAX: Untagged result.
-  // RCX: Untagged right.
-  __ cmpq(RCX, Immediate(0));
-  __ j(LESS, &subtract, Assembler::kNearJump);
-  __ addq(RAX, RCX);
-  __ SmiTag(RAX);
-  __ ret();
-
-  __ Bind(&subtract);
-  __ subq(RAX, RCX);
-  __ SmiTag(RAX);
-  __ ret();
-
-  __ Bind(normal_ir_body);
-}
-
-void AsmIntrinsifier::Integer_truncDivide(Assembler* assembler,
-                                          Label* normal_ir_body) {
-  Label not_32bit;
-  TestBothArgumentsSmis(assembler, normal_ir_body);
-  // RAX: right argument (divisor)
-  __ cmpq(RAX, Immediate(0));
-  __ j(EQUAL, normal_ir_body, Assembler::kNearJump);
-  __ movq(RCX, RAX);
-  __ movq(RAX,
-          Address(RSP, +2 * target::kWordSize));  // Left argument (dividend).
-
-#if !defined(DART_COMPRESSED_POINTERS)
-  // Check if both operands fit into 32bits as idiv with 64bit operands
-  // requires twice as many cycles and has much higher latency. We are checking
-  // this before untagging them to avoid corner case dividing INT_MAX by -1 that
-  // raises exception because quotient is too large for 32bit register.
-  __ movsxd(RBX, RAX);
-  __ cmpq(RBX, RAX);
-  __ j(NOT_EQUAL, &not_32bit);
-  __ movsxd(RBX, RCX);
-  __ cmpq(RBX, RCX);
-  __ j(NOT_EQUAL, &not_32bit);
-
-  // Both operands are 31bit smis. Divide using 32bit idiv.
-  __ SmiUntag(RAX);
-  __ SmiUntag(RCX);
-  __ cdq();
-  __ idivl(RCX);
-  __ movsxd(RAX, RAX);
-  __ SmiTag(RAX);  // Result is guaranteed to fit into a smi.
-  __ ret();
-
-  // Divide using 64bit idiv.
-  __ Bind(&not_32bit);
-  __ SmiUntag(RAX);
-  __ SmiUntag(RCX);
-  __ pushq(RDX);  // Preserve RDX in case of 'fall_through'.
-  __ cqo();
-  __ idivq(RCX);
-  __ popq(RDX);
-  // Check the corner case of dividing the 'MIN_SMI' with -1, in which case we
-  // cannot tag the result.
-  __ cmpq(RAX, Immediate(0x4000000000000000));
-  __ j(EQUAL, normal_ir_body);
-  __ SmiTag(RAX);
-  __ ret();
-#else
-  // Check the corner case of dividing the 'MIN_SMI' with -1, in which case we
-  // cannot tag the result.
-  __ cmpq(RAX, Immediate(target::ToRawSmi(target::kSmiMin)));
-  __ j(EQUAL, normal_ir_body);
-
-  // Both operands are 31bit smis. Divide using 32bit idiv.
-  __ SmiUntag(RAX);
-  __ SmiUntag(RCX);
-  __ cdq();
-  __ idivl(RCX);
-  __ SmiTag(RAX);  // Result is guaranteed to fit into a smi.
-  __ movsxd(RAX, RAX);
-  __ ret();
-#endif
-  __ Bind(normal_ir_body);
-}
-
-void AsmIntrinsifier::Integer_negate(Assembler* assembler,
-                                     Label* normal_ir_body) {
-  __ movq(RAX, Address(RSP, +1 * target::kWordSize));
-  __ testq(RAX, Immediate(kSmiTagMask));
-  __ j(NOT_ZERO, normal_ir_body, Assembler::kNearJump);  // Non-smi value.
-#if !defined(DART_COMPRESSED_POINTERS)
-  __ negq(RAX);
-  __ j(OVERFLOW, normal_ir_body, Assembler::kNearJump);
-#else
-  __ negl(RAX);
-  __ j(OVERFLOW, normal_ir_body, Assembler::kNearJump);
-  __ movsxd(RAX, RAX);
-#endif
-  // Result is in RAX.
-  __ ret();
-  __ Bind(normal_ir_body);
-}
-
-void AsmIntrinsifier::Integer_bitAnd(Assembler* assembler,
-                                     Label* normal_ir_body) {
-  TestBothArgumentsSmis(assembler, normal_ir_body);
-  // RAX is the right argument.
-  __ andq(RAX, Address(RSP, +2 * target::kWordSize));
-  // Result is in RAX.
-  __ ret();
-  __ Bind(normal_ir_body);
-}
-
-void AsmIntrinsifier::Integer_bitOr(Assembler* assembler,
-                                    Label* normal_ir_body) {
-  TestBothArgumentsSmis(assembler, normal_ir_body);
-  // RAX is the right argument.
-  __ orq(RAX, Address(RSP, +2 * target::kWordSize));
-  // Result is in RAX.
-  __ ret();
-  __ Bind(normal_ir_body);
-}
-
-void AsmIntrinsifier::Integer_bitXor(Assembler* assembler,
-                                     Label* normal_ir_body) {
-  TestBothArgumentsSmis(assembler, normal_ir_body);
-  // RAX is the right argument.
-  __ xorq(RAX, Address(RSP, +2 * target::kWordSize));
-  // Result is in RAX.
-  __ ret();
-  __ Bind(normal_ir_body);
-}
-
 void AsmIntrinsifier::Integer_shl(Assembler* assembler, Label* normal_ir_body) {
   ASSERT(kSmiTagShift == 1);
   ASSERT(kSmiTag == 0);
   Label overflow;
   TestBothArgumentsSmis(assembler, normal_ir_body);
   // Shift value is in RAX. Compare with tagged Smi.
-  __ cmpq(RAX, Immediate(target::ToRawSmi(target::kSmiBits)));
+  __ OBJ(cmp)(RAX, Immediate(target::ToRawSmi(target::kSmiBits)));
   __ j(ABOVE_EQUAL, normal_ir_body, Assembler::kNearJump);
 
   __ SmiUntag(RAX);
@@ -383,18 +105,12 @@
 
   // Overflow test - all the shifted-out bits must be same as the sign bit.
   __ movq(RDI, RAX);
-#if !defined(DART_COMPRESSED_POINTERS)
-  __ shlq(RAX, RCX);
-  __ sarq(RAX, RCX);
-#else
-  __ shll(RAX, RCX);
-  __ sarl(RAX, RCX);
-  __ movsxd(RAX, RAX);
-#endif
-  __ cmpq(RAX, RDI);
+  __ OBJ(shl)(RAX, RCX);
+  __ OBJ(sar)(RAX, RCX);
+  __ OBJ(cmp)(RAX, RDI);
   __ j(NOT_EQUAL, &overflow, Assembler::kNearJump);
 
-  __ shlq(RAX, RCX);  // Shift for result now we know there is no overflow.
+  __ OBJ(shl)(RAX, RCX);  // Shift for result now we know there is no overflow.
 
   // RAX is a correctly tagged Smi.
   __ ret();
@@ -411,7 +127,7 @@
   Label true_label;
   TestBothArgumentsSmis(assembler, normal_ir_body);
   // RAX contains the right argument.
-  __ cmpq(Address(RSP, +2 * target::kWordSize), RAX);
+  __ OBJ(cmp)(Address(RSP, +2 * target::kWordSize), RAX);
   __ j(true_condition, &true_label, Assembler::kNearJump);
   __ LoadObject(RAX, CastHandle<Object>(FalseObject()));
   __ ret();
@@ -452,7 +168,7 @@
   // For integer receiver '===' check first.
   __ movq(RAX, Address(RSP, +kArgumentOffset * target::kWordSize));
   __ movq(RCX, Address(RSP, +kReceiverOffset * target::kWordSize));
-  __ cmpq(RAX, RCX);
+  __ OBJ(cmp)(RAX, RCX);
   __ j(EQUAL, &true_label, Assembler::kNearJump);
   __ orq(RAX, RCX);
   __ testq(RAX, Immediate(kSmiTagMask));
@@ -501,47 +217,17 @@
   Integer_equalToInteger(assembler, normal_ir_body);
 }
 
-void AsmIntrinsifier::Integer_sar(Assembler* assembler, Label* normal_ir_body) {
-  Label shift_count_ok;
-  TestBothArgumentsSmis(assembler, normal_ir_body);
-  const Immediate& count_limit = Immediate(0x3F);
-  // Check that the count is not larger than what the hardware can handle.
-  // For shifting right a Smi the result is the same for all numbers
-  // >= count_limit.
-  __ SmiUntag(RAX);
-  // Negative counts throw exception.
-  __ cmpq(RAX, Immediate(0));
-  __ j(LESS, normal_ir_body, Assembler::kNearJump);
-  __ cmpq(RAX, count_limit);
-  __ j(LESS_EQUAL, &shift_count_ok, Assembler::kNearJump);
-  __ movq(RAX, count_limit);
-  __ Bind(&shift_count_ok);
-  __ movq(RCX, RAX);  // Shift amount must be in RCX.
-  __ movq(RAX, Address(RSP, +2 * target::kWordSize));  // Value.
-  __ SmiUntag(RAX);                                    // Value.
-  __ sarq(RAX, RCX);
-  __ SmiTag(RAX);
-  __ ret();
-  __ Bind(normal_ir_body);
-}
-
-// Argument is Smi (receiver).
-void AsmIntrinsifier::Smi_bitNegate(Assembler* assembler,
-                                    Label* normal_ir_body) {
-  __ movq(RAX, Address(RSP, +1 * target::kWordSize));  // Index.
-  __ notq(RAX);
-  __ andq(RAX, Immediate(~kSmiTagMask));  // Remove inverted smi-tag.
-  __ ret();
-}
-
 void AsmIntrinsifier::Smi_bitLength(Assembler* assembler,
                                     Label* normal_ir_body) {
   ASSERT(kSmiTagShift == 1);
   __ movq(RAX, Address(RSP, +1 * target::kWordSize));  // Index.
+#if defined(DART_COMPRESSED_POINTERS)
+  __ movsxd(RAX, RAX);
+#endif
   // XOR with sign bit to complement bits if value is negative.
   __ movq(RCX, RAX);
   __ sarq(RCX, Immediate(63));  // All 0 or all 1.
-  __ xorq(RAX, RCX);
+  __ OBJ (xor)(RAX, RCX);
   // BSR does not write the destination register if source is zero.  Put a 1 in
   // the Smi tag bit to ensure BSR writes to destination register.
   __ orq(RAX, Immediate(kSmiTagMask));
@@ -1111,7 +797,7 @@
   __ ret();
   __ Bind(&is_smi);
   __ SmiUntag(RAX);
-  __ cvtsi2sdq(XMM1, RAX);
+  __ OBJ(cvtsi2sd)(XMM1, RAX);
   __ jmp(&double_op);
   __ Bind(normal_ir_body);
 }
@@ -1177,7 +863,7 @@
   __ ret();
   __ Bind(&is_smi);
   __ SmiUntag(RAX);
-  __ cvtsi2sdq(XMM1, RAX);
+  __ OBJ(cvtsi2sd)(XMM1, RAX);
   __ jmp(&double_op);
   __ Bind(normal_ir_body);
 }
@@ -1206,7 +892,7 @@
   __ j(NOT_ZERO, normal_ir_body);
   // Is Smi.
   __ SmiUntag(RAX);
-  __ cvtsi2sdq(XMM1, RAX);
+  __ OBJ(cvtsi2sd)(XMM1, RAX);
   __ movq(RAX, Address(RSP, +2 * target::kWordSize));
   __ movsd(XMM0, FieldAddress(RAX, target::Double::value_offset()));
   __ mulsd(XMM0, XMM1);
@@ -1227,11 +913,7 @@
   __ j(NOT_ZERO, normal_ir_body);
   // Is Smi.
   __ SmiUntag(RAX);
-#if !defined(DART_COMPRESSED_POINTER)
-  __ cvtsi2sdq(XMM0, RAX);
-#else
-  __ cvtsi2sdl(XMM0, RAX);
-#endif
+  __ OBJ(cvtsi2sd)(XMM0, RAX);
   const Class& double_class = DoubleClass();
   __ TryAllocate(double_class, normal_ir_body, Assembler::kFarJump,
                  RAX,  // Result register.
@@ -1303,26 +985,13 @@
                                       Label* normal_ir_body) {
   __ movq(RAX, Address(RSP, +1 * target::kWordSize));
   __ movsd(XMM0, FieldAddress(RAX, target::Double::value_offset()));
-#if !defined(DART_COMPRESSED_POINTERS)
-  __ cvttsd2siq(RAX, XMM0);
-#else
-  __ cvttsd2sil(RAX, XMM0);
-#endif
+  __ OBJ(cvttsd2si)(RAX, XMM0);
   // Overflow is signalled with minint.
   // Check for overflow and that it fits into Smi.
   __ movq(RCX, RAX);
-#if !defined(DART_COMPRESSED_POINTERS)
-  __ shlq(RCX, Immediate(1));
-#else
-  __ shll(RCX, Immediate(1));
-#endif
+  __ OBJ(shl)(RCX, Immediate(1));
   __ j(OVERFLOW, normal_ir_body, Assembler::kNearJump);
-#if !defined(DART_COMPRESSED_POINTERS)
   __ SmiTag(RAX);
-#else
-  ASSERT((kSmiTagShift == 1) && (kSmiTag == 0));
-  __ movsxd(RAX, RCX);
-#endif
   __ ret();
   __ Bind(normal_ir_body);
 }
@@ -1335,26 +1004,15 @@
   // back to a double in XMM1.
   __ movq(RCX, Address(RSP, +1 * target::kWordSize));
   __ movsd(XMM0, FieldAddress(RCX, target::Double::value_offset()));
-#if !defined(DART_COMPRESSED_POINTERS)
-  __ cvttsd2siq(RAX, XMM0);
-  __ cvtsi2sdq(XMM1, RAX);
-#else
-  __ cvttsd2sil(RAX, XMM0);
-  __ cvtsi2sdl(XMM1, RAX);
-#endif
+  __ OBJ(cvttsd2si)(RAX, XMM0);
+  __ OBJ(cvtsi2sd)(XMM1, RAX);
 
   // Tag the int as a Smi, making sure that it fits; this checks for
   // overflow and NaN in the conversion from double to int. Conversion
   // overflow from cvttsd2si is signalled with an INT64_MIN value.
   ASSERT(kSmiTag == 0 && kSmiTagShift == 1);
-#if !defined(DART_COMPRESSED_POINTERS)
-  __ addq(RAX, RAX);
+  __ OBJ(add)(RAX, RAX);
   __ j(OVERFLOW, normal_ir_body, Assembler::kNearJump);
-#else
-  __ addl(RAX, RAX);
-  __ j(OVERFLOW, normal_ir_body, Assembler::kNearJump);
-  __ movsxd(RAX, RAX);
-#endif
 
   // Compare the two double values. If they are equal, we return the
   // Smi tagged result immediately as the hash code.
@@ -1392,7 +1050,7 @@
   __ ret();
   __ Bind(&is_smi);
   __ SmiUntag(RAX);
-  __ cvtsi2sdq(XMM1, RAX);
+  __ OBJ(cvtsi2sd)(XMM1, RAX);
   __ jmp(&double_op);
   __ Bind(normal_ir_body);
 }
@@ -1437,7 +1095,7 @@
   const intptr_t kArgumentOffset = 1;
 
   __ movq(RAX, Address(RSP, +kArgumentOffset * target::kWordSize));
-  __ cmpq(RAX, Address(RSP, +kReceiverOffset * target::kWordSize));
+  __ OBJ(cmp)(RAX, Address(RSP, +kReceiverOffset * target::kWordSize));
   __ j(EQUAL, &is_true, Assembler::kNearJump);
   __ LoadObject(RAX, CastHandle<Object>(FalseObject()));
   __ ret();
@@ -1543,7 +1201,8 @@
   __ movzxw(RCX, FieldAddress(RDI, target::Class::num_type_arguments_offset()));
   __ cmpq(RCX, Immediate(0));
   __ j(NOT_EQUAL, normal_ir_body, Assembler::kNearJump);
-  __ movq(RAX, FieldAddress(RDI, target::Class::declaration_type_offset()));
+  __ LoadCompressed(
+      RAX, FieldAddress(RDI, target::Class::declaration_type_offset()));
   __ CompareObject(RAX, NullObject());
   __ j(EQUAL, normal_ir_body, Assembler::kNearJump);  // Not yet set.
   __ ret();
@@ -1649,7 +1308,7 @@
 void AsmIntrinsifier::Type_getHashCode(Assembler* assembler,
                                        Label* normal_ir_body) {
   __ movq(RAX, Address(RSP, +1 * target::kWordSize));  // Type object.
-  __ movq(RAX, FieldAddress(RAX, target::Type::hash_offset()));
+  __ LoadCompressed(RAX, FieldAddress(RAX, target::Type::hash_offset()));
   ASSERT(kSmiTag == 0);
   ASSERT(kSmiTagShift == 1);
   __ testq(RAX, RAX);
@@ -1665,7 +1324,7 @@
 
   __ movq(RCX, Address(RSP, +1 * target::kWordSize));
   __ movq(RDX, Address(RSP, +2 * target::kWordSize));
-  __ cmpq(RCX, RDX);
+  __ OBJ(cmp)(RCX, RDX);
   __ j(EQUAL, &equal);
 
   // RCX might not be a Type object, so check that first (RDX should be though,
@@ -1675,9 +1334,11 @@
   __ j(NOT_EQUAL, normal_ir_body);
 
   // Check if types are syntactically equal.
-  __ movq(RDI, FieldAddress(RCX, target::Type::type_class_id_offset()));
+  __ LoadCompressedSmi(RDI,
+                       FieldAddress(RCX, target::Type::type_class_id_offset()));
   __ SmiUntag(RDI);
-  __ movq(RSI, FieldAddress(RDX, target::Type::type_class_id_offset()));
+  __ LoadCompressedSmi(RSI,
+                       FieldAddress(RDX, target::Type::type_class_id_offset()));
   __ SmiUntag(RSI);
   EquivalentClassIds(assembler, normal_ir_body, &equiv_cids, &not_equal, RDI,
                      RSI, RAX);
@@ -1715,7 +1376,8 @@
 void AsmIntrinsifier::FunctionType_getHashCode(Assembler* assembler,
                                                Label* normal_ir_body) {
   __ movq(RAX, Address(RSP, +1 * target::kWordSize));  // FunctionType object.
-  __ movq(RAX, FieldAddress(RAX, target::FunctionType::hash_offset()));
+  __ LoadCompressed(RAX,
+                    FieldAddress(RAX, target::FunctionType::hash_offset()));
   ASSERT(kSmiTag == 0);
   ASSERT(kSmiTagShift == 1);
   __ testq(RAX, RAX);
@@ -1729,7 +1391,7 @@
                                             Label* normal_ir_body) {
   __ movq(RCX, Address(RSP, +1 * target::kWordSize));
   __ movq(RDX, Address(RSP, +2 * target::kWordSize));
-  __ cmpq(RCX, RDX);
+  __ OBJ(cmp)(RCX, RDX);
   __ j(NOT_EQUAL, normal_ir_body);
 
   __ LoadObject(RAX, CastHandle<Object>(TrueObject()));
@@ -1763,8 +1425,11 @@
                                             intptr_t other_cid,
                                             Label* return_true,
                                             Label* return_false) {
-  __ movq(R8, FieldAddress(RAX, target::String::length_offset()));
-  __ movq(R9, FieldAddress(RCX, target::String::length_offset()));
+  __ SmiUntag(RBX);
+  __ LoadCompressedSmi(R8, FieldAddress(RAX, target::String::length_offset()));
+  __ SmiUntag(R8);
+  __ LoadCompressedSmi(R9, FieldAddress(RCX, target::String::length_offset()));
+  __ SmiUntag(R9);
 
   // if (other.length == 0) return true;
   __ testq(R9, R9);
@@ -1780,8 +1445,6 @@
   __ cmpq(R11, R8);
   __ j(GREATER, return_false);
 
-  __ SmiUntag(RBX);                     // start
-  __ SmiUntag(R9);                      // other.length
   __ LoadImmediate(R11, Immediate(0));  // i = 0
 
   // do
@@ -1870,7 +1533,7 @@
   __ testq(RCX, Immediate(kSmiTagMask));
   __ j(NOT_ZERO, normal_ir_body);  // Non-smi index.
   // Range check.
-  __ cmpq(RCX, FieldAddress(RAX, target::String::length_offset()));
+  __ OBJ(cmp)(RCX, FieldAddress(RAX, target::String::length_offset()));
   // Runtime throws exception.
   __ j(ABOVE_EQUAL, normal_ir_body);
   __ CompareClassId(RAX, kOneByteStringCid);
@@ -1910,8 +1573,8 @@
   Label is_true;
   // Get length.
   __ movq(RAX, Address(RSP, +1 * target::kWordSize));  // String object.
-  __ movq(RAX, FieldAddress(RAX, target::String::length_offset()));
-  __ cmpq(RAX, Immediate(target::ToRawSmi(0)));
+  __ LoadCompressedSmi(RAX, FieldAddress(RAX, target::String::length_offset()));
+  __ OBJ(cmp)(RAX, Immediate(target::ToRawSmi(0)));
   __ j(EQUAL, &is_true, Assembler::kNearJump);
   __ LoadObject(RAX, CastHandle<Object>(FalseObject()));
   __ ret();
@@ -1934,7 +1597,7 @@
 
   __ Bind(&compute_hash);
   // Hash not yet computed, use algorithm of class StringHasher.
-  __ movq(RCX, FieldAddress(RBX, target::String::length_offset()));
+  __ LoadCompressedSmi(RCX, FieldAddress(RBX, target::String::length_offset()));
   __ SmiUntag(RCX);
   __ xorq(RAX, RAX);
   __ xorq(RDI, RDI);
@@ -2076,7 +1739,7 @@
 
   // Set the length field.
   __ popq(RDI);
-  __ StoreIntoObjectNoBarrier(
+  __ StoreCompressedIntoObjectNoBarrier(
       RAX, FieldAddress(RAX, target::String::length_offset()), RDI);
   __ jmp(ok, Assembler::kNearJump);
 
@@ -2195,7 +1858,7 @@
   __ movq(RCX, Address(RSP, +1 * target::kWordSize));  // Other.
 
   // Are identical?
-  __ cmpq(RAX, RCX);
+  __ OBJ(cmp)(RAX, RCX);
   __ j(EQUAL, &is_true, Assembler::kNearJump);
 
   // Is other target::OneByteString?
@@ -2205,8 +1868,8 @@
   __ j(NOT_EQUAL, normal_ir_body, Assembler::kNearJump);
 
   // Have same length?
-  __ movq(RDI, FieldAddress(RAX, target::String::length_offset()));
-  __ cmpq(RDI, FieldAddress(RCX, target::String::length_offset()));
+  __ LoadCompressedSmi(RDI, FieldAddress(RAX, target::String::length_offset()));
+  __ OBJ(cmp)(RDI, FieldAddress(RCX, target::String::length_offset()));
   __ j(NOT_EQUAL, &is_false, Assembler::kNearJump);
 
   // Check contents, no fall-through possible.
@@ -2274,16 +1937,23 @@
   __ movq(RDI, Address(RSP, kStringParamOffset));
   __ LoadClassId(RDI, RDI);
   __ SubImmediate(RDI, Immediate(kOneByteStringCid));
+#if !defined(DART_COMPRESSED_POINTERS)
   __ movq(RAX, FieldAddress(
                    RBX, RDI, TIMES_8,
                    target::RegExp::function_offset(kOneByteStringCid, sticky)));
+#else
+  __ LoadCompressed(RAX, FieldAddress(RBX, RDI, TIMES_4,
+                                      target::RegExp::function_offset(
+                                          kOneByteStringCid, sticky)));
+#endif
 
   // Registers are now set up for the lazy compile stub. It expects the function
   // in RAX, the argument descriptor in R10, and IC-Data in RCX.
   __ xorq(RCX, RCX);
 
   // Tail-call the function.
-  __ movq(CODE_REG, FieldAddress(RAX, target::Function::code_offset()));
+  __ LoadCompressed(CODE_REG,
+                    FieldAddress(RAX, target::Function::code_offset()));
   __ movq(RDI, FieldAddress(RAX, target::Function::entry_point_offset()));
   __ jmp(RDI);
 }
diff --git a/runtime/vm/compiler/assembler/assembler_arm.h b/runtime/vm/compiler/assembler/assembler_arm.h
index 4efc1e9..68bcae0 100644
--- a/runtime/vm/compiler/assembler/assembler_arm.h
+++ b/runtime/vm/compiler/assembler/assembler_arm.h
@@ -389,6 +389,9 @@
   void Jump(const Address& address) { Branch(address); }
 
   void LoadField(Register dst, FieldAddress address) { ldr(dst, address); }
+  void LoadCompressedField(Register dst, FieldAddress address) {
+    LoadField(dst, address);
+  }
   void LoadMemoryValue(Register dst, Register base, int32_t offset) {
     LoadFromOffset(dst, base, offset);
   }
@@ -933,6 +936,13 @@
                            Condition cond = AL) {
     LoadFromOffset(reg, base, offset - kHeapObjectTag, type, cond);
   }
+  void LoadCompressedFieldFromOffset(Register reg,
+                                     Register base,
+                                     int32_t offset,
+                                     OperandSize type = kFourBytes,
+                                     Condition cond = AL) {
+    LoadFieldFromOffset(reg, base, offset, type, cond);
+  }
   // 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.
@@ -1019,6 +1029,9 @@
   void PopNativeCalleeSavedRegisters();
 
   void CompareRegisters(Register rn, Register rm) { cmp(rn, Operand(rm)); }
+  void CompareObjectRegisters(Register rn, Register rm) {
+    CompareRegisters(rn, rm);
+  }
   // Branches to the given label if the condition holds.
   // [distance] is ignored on ARM.
   void BranchIf(Condition condition,
diff --git a/runtime/vm/compiler/assembler/assembler_arm64.cc b/runtime/vm/compiler/assembler/assembler_arm64.cc
index 91c5e85..c54c816 100644
--- a/runtime/vm/compiler/assembler/assembler_arm64.cc
+++ b/runtime/vm/compiler/assembler/assembler_arm64.cc
@@ -529,16 +529,16 @@
   ASSERT(IsOriginalObject(object));
   word offset = 0;
   if (IsSameObject(compiler::NullObject(), object)) {
-    CompareRegisters(reg, NULL_REG);
+    CompareObjectRegisters(reg, NULL_REG);
   } else if (target::CanLoadFromThread(object, &offset)) {
     ldr(TMP, Address(THR, offset));
-    CompareRegisters(reg, TMP);
+    CompareObjectRegisters(reg, TMP);
   } else if (CanLoadFromObjectPool(object)) {
     LoadObject(TMP, object);
-    CompareRegisters(reg, TMP);
+    CompareObjectRegisters(reg, TMP);
   } else {
     ASSERT(target::IsSmi(object));
-    CompareImmediate(reg, target::ToRawSmi(object));
+    CompareImmediate(reg, target::ToRawSmi(object), kObjectBytes);
   }
 }
 
@@ -667,7 +667,12 @@
   Call(FieldAddress(CODE_REG, target::Code::entry_point_offset(entry_kind)));
 }
 
-void Assembler::AddImmediate(Register dest, Register rn, int64_t imm) {
+void Assembler::AddImmediate(Register dest,
+                             Register rn,
+                             int64_t imm,
+                             OperandSize sz) {
+  ASSERT(sz == kEightBytes || sz == kFourBytes);
+  int width = sz == kEightBytes ? kXRegSizeInBits : kWRegSizeInBits;
   Operand op;
   if (imm == 0) {
     if (dest != rn) {
@@ -675,16 +680,15 @@
     }
     return;
   }
-  if (Operand::CanHold(imm, kXRegSizeInBits, &op) == Operand::Immediate) {
-    add(dest, rn, op);
-  } else if (Operand::CanHold(-imm, kXRegSizeInBits, &op) ==
-             Operand::Immediate) {
-    sub(dest, rn, op);
+  if (Operand::CanHold(imm, width, &op) == Operand::Immediate) {
+    add(dest, rn, op, sz);
+  } else if (Operand::CanHold(-imm, width, &op) == Operand::Immediate) {
+    sub(dest, rn, op, sz);
   } else {
     // TODO(zra): Try adding top 12 bits, then bottom 12 bits.
     ASSERT(rn != TMP2);
     LoadImmediate(TMP2, imm);
-    add(dest, rn, Operand(TMP2));
+    add(dest, rn, Operand(TMP2), sz);
   }
 }
 
@@ -783,7 +787,7 @@
     tsti(rn, Immediate(imm), sz);
   } else {
     LoadImmediate(TMP, imm);
-    tst(rn, Operand(TMP));
+    tst(rn, Operand(TMP), sz);
   }
 }
 
@@ -920,23 +924,26 @@
   vmuls(vd, vd, VTMP);
 }
 
-void Assembler::LoadCompressed(Register dest,
-                               const Address& slot,
-                               CanBeSmi can_value_be_smi) {
+void Assembler::LoadCompressed(Register dest, const Address& slot) {
 #if !defined(DART_COMPRESSED_POINTERS)
   ldr(dest, slot);
 #else
-  Label done;
-  ldr(dest, slot, kFourBytes);  // Sign-extension.
-  if (can_value_be_smi == kValueCanBeSmi) {
-    BranchIfSmi(dest, &done);
-  }
+  ldr(dest, slot, kUnsignedFourBytes);  // Zero-extension.
   add(dest, dest, Operand(HEAP_BASE));
-  Bind(&done);
+#endif
+}
 
-  // After further Smi changes:
-  // ldr(dest, slot, kUnsignedFourBytes);  // Zero-extension.
-  // add(dest, dest, Operand(HEAP_BASE));
+void Assembler::LoadCompressedSmi(Register dest, const Address& slot) {
+#if !defined(DART_COMPRESSED_POINTERS)
+  ldr(dest, slot);
+#else
+  ldr(dest, slot, kUnsignedFourBytes);  // Zero-extension.
+#endif
+#if defined(DEBUG)
+  Label done;
+  BranchIfSmi(dest, &done);
+  Stop("Expected Smi");
+  Bind(&done);
 #endif
 }
 
@@ -990,10 +997,38 @@
   }
 }
 
+void Assembler::StoreCompressedIntoObjectOffset(Register object,
+                                                int32_t offset,
+                                                Register value,
+                                                CanBeSmi value_can_be_smi) {
+  if (Address::CanHoldOffset(offset - kHeapObjectTag)) {
+    StoreCompressedIntoObject(object, FieldAddress(object, offset), value,
+                              value_can_be_smi);
+  } else {
+    AddImmediate(TMP, object, offset - kHeapObjectTag);
+    StoreCompressedIntoObject(object, Address(TMP), value, value_can_be_smi);
+  }
+}
+
 void Assembler::StoreIntoObject(Register object,
                                 const Address& dest,
                                 Register value,
                                 CanBeSmi can_be_smi) {
+  str(value, dest);
+  StoreBarrier(object, value, can_be_smi);
+}
+
+void Assembler::StoreCompressedIntoObject(Register object,
+                                          const Address& dest,
+                                          Register value,
+                                          CanBeSmi can_be_smi) {
+  str(value, dest, kObjectBytes);
+  StoreBarrier(object, value, can_be_smi);
+}
+
+void Assembler::StoreBarrier(Register object,
+                             Register value,
+                             CanBeSmi can_be_smi) {
   const bool spill_lr = lr_state().LRContainsReturnAddress();
   // x.slot = x. Barrier should have be removed at the IL level.
   ASSERT(object != value);
@@ -1004,8 +1039,6 @@
   ASSERT(value != TMP);
   ASSERT(value != TMP2);
 
-  str(value, dest);
-
   // In parallel, test whether
   //  - object is old and not remembered and value is new, or
   //  - object is old and value is old and not marked and concurrent marking is
@@ -1129,6 +1162,25 @@
   // No store buffer update.
 }
 
+void Assembler::StoreCompressedIntoObjectNoBarrier(Register object,
+                                                   const Address& dest,
+                                                   Register value) {
+  str(value, dest, kObjectBytes);
+#if defined(DEBUG)
+  Label done;
+  StoreIntoObjectFilter(object, value, &done, kValueCanBeSmi, kJumpToNoUpdate);
+
+  ldr(TMP, FieldAddress(object, target::Object::tags_offset(), kByte),
+      kUnsignedByte);
+  tsti(TMP, Immediate(1 << target::UntaggedObject::kOldAndNotRememberedBit));
+  b(&done, ZERO);
+
+  Stop("Store buffer update is required");
+  Bind(&done);
+#endif  // defined(DEBUG)
+  // No store buffer update.
+}
+
 void Assembler::StoreIntoObjectOffsetNoBarrier(Register object,
                                                int32_t offset,
                                                Register value) {
@@ -1140,6 +1192,18 @@
   }
 }
 
+void Assembler::StoreCompressedIntoObjectOffsetNoBarrier(Register object,
+                                                         int32_t offset,
+                                                         Register value) {
+  if (Address::CanHoldOffset(offset - kHeapObjectTag)) {
+    StoreCompressedIntoObjectNoBarrier(object, FieldAddress(object, offset),
+                                       value);
+  } else {
+    AddImmediate(TMP, object, offset - kHeapObjectTag);
+    StoreCompressedIntoObjectNoBarrier(object, Address(TMP), value);
+  }
+}
+
 void Assembler::StoreIntoObjectNoBarrier(Register object,
                                          const Address& dest,
                                          const Object& value) {
@@ -1154,6 +1218,20 @@
   }
 }
 
+void Assembler::StoreCompressedIntoObjectNoBarrier(Register object,
+                                                   const Address& dest,
+                                                   const Object& value) {
+  ASSERT(IsOriginalObject(value));
+  ASSERT(IsNotTemporaryScopedHandle(value));
+  // No store buffer update.
+  if (IsSameObject(compiler::NullObject(), value)) {
+    str(NULL_REG, dest, kObjectBytes);
+  } else {
+    LoadObject(TMP2, value);
+    str(TMP2, dest, kObjectBytes);
+  }
+}
+
 void Assembler::StoreIntoObjectOffsetNoBarrier(Register object,
                                                int32_t offset,
                                                const Object& value) {
@@ -1165,6 +1243,18 @@
   }
 }
 
+void Assembler::StoreCompressedIntoObjectOffsetNoBarrier(Register object,
+                                                         int32_t offset,
+                                                         const Object& value) {
+  if (Address::CanHoldOffset(offset - kHeapObjectTag)) {
+    StoreCompressedIntoObjectNoBarrier(object, FieldAddress(object, offset),
+                                       value);
+  } else {
+    AddImmediate(TMP, object, offset - kHeapObjectTag);
+    StoreCompressedIntoObjectNoBarrier(object, Address(TMP), value);
+  }
+}
+
 void Assembler::StoreInternalPointer(Register object,
                                      const Address& dest,
                                      Register value) {
@@ -1899,15 +1989,33 @@
   const intptr_t boxing_shift = index_unboxed ? 0 : -kSmiTagShift;
   const intptr_t shift = Utils::ShiftForPowerOfTwo(index_scale) + boxing_shift;
   const int32_t offset = HeapDataOffset(is_external, cid);
+#if !defined(DART_COMPRESSED_POINTERS)
+  const bool index_is_32bit = false;
+#else
+  const bool index_is_32bit = !index_unboxed;
+#endif
   ASSERT(array != temp);
   ASSERT(index != temp);
   if ((offset == 0) && (shift == 0)) {
-    return Address(array, index, UXTX, Address::Unscaled);
+    if (index_is_32bit) {
+      return Address(array, index, SXTW, Address::Unscaled);
+    } else {
+      return Address(array, index, UXTX, Address::Unscaled);
+    }
   } else if (shift < 0) {
     ASSERT(shift == -1);
-    add(temp, array, Operand(index, ASR, 1));
+    if (index_is_32bit) {
+      AsrImmediate(temp, index, 1, kFourBytes);
+      add(temp, array, Operand(temp, SXTW, 0));
+    } else {
+      add(temp, array, Operand(index, ASR, 1));
+    }
   } else {
-    add(temp, array, Operand(index, LSL, shift));
+    if (index_is_32bit) {
+      add(temp, array, Operand(index, SXTW, shift));
+    } else {
+      add(temp, array, Operand(index, LSL, shift));
+    }
   }
   ASSERT(Address::CanHoldOffset(offset, Address::Offset, size));
   return Address(temp, offset, Address::Offset, size);
@@ -1924,13 +2032,31 @@
   const intptr_t boxing_shift = index_unboxed ? 0 : -kSmiTagShift;
   const intptr_t shift = Utils::ShiftForPowerOfTwo(index_scale) + boxing_shift;
   const int32_t offset = HeapDataOffset(is_external, cid);
+#if !defined(DART_COMPRESSED_POINTERS)
+  const bool index_is_32bit = false;
+#else
+  const bool index_is_32bit = !index_unboxed;
+#endif
   if (shift == 0) {
-    add(address, array, Operand(index));
+    if (index_is_32bit) {
+      add(address, array, Operand(index, SXTW, 0));
+    } else {
+      add(address, array, Operand(index));
+    }
   } else if (shift < 0) {
     ASSERT(shift == -1);
-    add(address, array, Operand(index, ASR, 1));
+    if (index_is_32bit) {
+      sxtw(index, index);
+      add(address, array, Operand(index, ASR, 1));
+    } else {
+      add(address, array, Operand(index, ASR, 1));
+    }
   } else {
-    add(address, array, Operand(index, LSL, shift));
+    if (index_is_32bit) {
+      add(address, array, Operand(index, SXTW, shift));
+    } else {
+      add(address, array, Operand(index, LSL, shift));
+    }
   }
   if (offset != 0) {
     AddImmediate(address, offset);
@@ -2046,7 +2172,7 @@
   }
 }
 
-bool Assembler::CanGenerateXCbzTbz(Register rn, Condition cond) {
+bool Assembler::CanGenerateCbzTbz(Register rn, Condition cond) {
   if (rn == CSP) {
     return false;
   }
@@ -2063,9 +2189,12 @@
   }
 }
 
-void Assembler::GenerateXCbzTbz(Register rn, Condition cond, Label* label) {
-  constexpr int32_t bit_no = 63;
-  constexpr OperandSize sz = kEightBytes;
+void Assembler::GenerateCbzTbz(Register rn,
+                               Condition cond,
+                               Label* label,
+                               OperandSize sz) {
+  ASSERT((sz == kEightBytes) || (sz == kFourBytes));
+  const int32_t sign_bit = sz == kEightBytes ? 63 : 31;
   ASSERT(rn != CSP);
   switch (cond) {
     case EQ:  // equal
@@ -2076,11 +2205,11 @@
       return;
     case MI:  // minus/negative
     case LT:  // signed less than
-      tbnz(label, rn, bit_no);
+      tbnz(label, rn, sign_bit);
       return;
     case PL:  // plus/positive or zero
     case GE:  // signed greater than or equal
-      tbz(label, rn, bit_no);
+      tbz(label, rn, sign_bit);
       return;
     default:
       // Only conditions above allow single instruction emission.
diff --git a/runtime/vm/compiler/assembler/assembler_arm64.h b/runtime/vm/compiler/assembler/assembler_arm64.h
index 14ac5aa..fdfe351 100644
--- a/runtime/vm/compiler/assembler/assembler_arm64.h
+++ b/runtime/vm/compiler/assembler/assembler_arm64.h
@@ -547,6 +547,9 @@
   }
 
   void LoadField(Register dst, FieldAddress address) { ldr(dst, address); }
+  void LoadCompressedField(Register dst, FieldAddress address) {
+    LoadCompressed(dst, address);
+  }
   void LoadMemoryValue(Register dst, Register base, int32_t offset) {
     LoadFromOffset(dst, base, offset, kEightBytes);
   }
@@ -897,29 +900,47 @@
   }
 
   // Misc. arithmetic.
-  void udiv(Register rd, Register rn, Register rm) {
-    EmitMiscDP2Source(UDIV, rd, rn, rm, kEightBytes);
+  void udiv(Register rd,
+            Register rn,
+            Register rm,
+            OperandSize sz = kEightBytes) {
+    EmitMiscDP2Source(UDIV, rd, rn, rm, sz);
   }
-  void sdiv(Register rd, Register rn, Register rm) {
-    EmitMiscDP2Source(SDIV, rd, rn, rm, kEightBytes);
+  void sdiv(Register rd,
+            Register rn,
+            Register rm,
+            OperandSize sz = kEightBytes) {
+    EmitMiscDP2Source(SDIV, rd, rn, rm, sz);
   }
-  void lslv(Register rd, Register rn, Register rm) {
-    EmitMiscDP2Source(LSLV, rd, rn, rm, kEightBytes);
+  void lslv(Register rd,
+            Register rn,
+            Register rm,
+            OperandSize sz = kEightBytes) {
+    EmitMiscDP2Source(LSLV, rd, rn, rm, sz);
   }
-  void lsrv(Register rd, Register rn, Register rm) {
-    EmitMiscDP2Source(LSRV, rd, rn, rm, kEightBytes);
+  void lsrv(Register rd,
+            Register rn,
+            Register rm,
+            OperandSize sz = kEightBytes) {
+    EmitMiscDP2Source(LSRV, rd, rn, rm, sz);
   }
-  void asrv(Register rd, Register rn, Register rm) {
-    EmitMiscDP2Source(ASRV, rd, rn, rm, kEightBytes);
+  void asrv(Register rd,
+            Register rn,
+            Register rm,
+            OperandSize sz = kEightBytes) {
+    EmitMiscDP2Source(ASRV, rd, rn, rm, sz);
+  }
+  void sdivw(Register rd, Register rn, Register rm) {
+    sdiv(rd, rn, rm, kFourBytes);
   }
   void lslvw(Register rd, Register rn, Register rm) {
-    EmitMiscDP2Source(LSLV, rd, rn, rm, kFourBytes);
+    lslv(rd, rn, rm, kFourBytes);
   }
   void lsrvw(Register rd, Register rn, Register rm) {
-    EmitMiscDP2Source(LSRV, rd, rn, rm, kFourBytes);
+    lsrv(rd, rn, rm, kFourBytes);
   }
   void asrvw(Register rd, Register rn, Register rm) {
-    EmitMiscDP2Source(ASRV, rd, rn, rm, kFourBytes);
+    asrv(rd, rn, rm, kFourBytes);
   }
   void madd(Register rd,
             Register rn,
@@ -1115,6 +1136,11 @@
     }
   }
 
+  void CompareObjectRegisters(Register rn, Register rm) {
+    ASSERT(rn != CSP);
+    cmp(rn, Operand(rm), kObjectBytes);
+  }
+
   // Conditional branch.
   void b(Label* label, Condition cond = AL) {
     EmitConditionalBranch(BCOND, cond, label);
@@ -1149,10 +1175,13 @@
     EmitCompareAndBranch(CBNZ, rt, label, sz);
   }
 
-  // Generate 64-bit compare with zero and branch when condition allows to use
-  // a single instruction: cbz/cbnz/tbz/tbnz.
-  bool CanGenerateXCbzTbz(Register rn, Condition cond);
-  void GenerateXCbzTbz(Register rn, Condition cond, Label* label);
+  // Generate 64/32-bit compare with zero and branch when condition allows to
+  // use a single instruction: cbz/cbnz/tbz/tbnz.
+  bool CanGenerateCbzTbz(Register rn, Condition cond);
+  void GenerateCbzTbz(Register rn,
+                      Condition cond,
+                      Label* label,
+                      OperandSize sz = kEightBytes);
 
   // Test bit and branch if zero.
   void tbz(Label* label, Register rt, intptr_t bit_number) {
@@ -1442,8 +1471,10 @@
   void mvn(Register rd, Register rm) { orn(rd, ZR, Operand(rm)); }
   void mvnw(Register rd, Register rm) { ornw(rd, ZR, Operand(rm)); }
   void neg(Register rd, Register rm) { sub(rd, ZR, Operand(rm)); }
-  void negs(Register rd, Register rm) { subs(rd, ZR, Operand(rm)); }
-  void negsw(Register rd, Register rm) { subsw(rd, ZR, Operand(rm)); }
+  void negs(Register rd, Register rm, OperandSize sz = kEightBytes) {
+    subs(rd, ZR, Operand(rm), sz);
+  }
+  void negsw(Register rd, Register rm) { negs(rd, rm, kFourBytes); }
   void mul(Register rd, Register rn, Register rm) {
     madd(rd, rn, rm, ZR, kEightBytes);
   }
@@ -1538,9 +1569,11 @@
   void VRecps(VRegister vd, VRegister vn);
   void VRSqrts(VRegister vd, VRegister vn);
 
-  void SmiUntag(Register reg) { AsrImmediate(reg, reg, kSmiTagSize); }
+  void SmiUntag(Register reg) {
+    sbfm(reg, reg, kSmiTagSize, target::kSmiBits + 1);
+  }
   void SmiUntag(Register dst, Register src) {
-    AsrImmediate(dst, src, kSmiTagSize);
+    sbfm(dst, src, kSmiTagSize, target::kSmiBits + 1);
   }
   void SmiTag(Register reg) { LslImmediate(reg, reg, kSmiTagSize); }
   void SmiTag(Register dst, Register src) {
@@ -1617,7 +1650,10 @@
   // the object pool when possible. Unless you are sure that the untagged object
   // pool pointer is in another register, or that it is not available at all,
   // PP should be passed for pp. `dest` can be TMP2, `rn` cannot.
-  void AddImmediate(Register dest, Register rn, int64_t imm);
+  void AddImmediate(Register dest,
+                    Register rn,
+                    int64_t imm,
+                    OperandSize sz = kEightBytes);
   void AddImmediateSetFlags(Register dest,
                             Register rn,
                             int64_t imm,
@@ -1654,6 +1690,11 @@
                            OperandSize sz = kEightBytes) {
     LoadFromOffset(dest, base, offset - kHeapObjectTag, sz);
   }
+  void LoadCompressedFieldFromOffset(Register dest,
+                                     Register base,
+                                     int32_t offset) {
+    LoadCompressed(dest, FieldAddress(base, offset));
+  }
   // 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.
@@ -1706,9 +1747,8 @@
     kValueCanBeSmi,
   };
 
-  void LoadCompressed(Register dest,
-                      const Address& slot,
-                      CanBeSmi can_value_be_smi = kValueCanBeSmi);
+  void LoadCompressed(Register dest, const Address& slot);
+  void LoadCompressedSmi(Register dest, const Address& slot);
 
   // Store into a heap object and apply the generational and incremental write
   // barriers. All stores into heap objects must pass through this function or,
@@ -1719,6 +1759,11 @@
                        const Address& dest,
                        Register value,
                        CanBeSmi can_value_be_smi = kValueCanBeSmi);
+  void StoreCompressedIntoObject(Register object,
+                                 const Address& dest,
+                                 Register value,
+                                 CanBeSmi can_value_be_smi = kValueCanBeSmi);
+  void StoreBarrier(Register object, Register value, CanBeSmi can_value_be_smi);
   void StoreIntoArray(Register object,
                       Register slot,
                       Register value,
@@ -1728,18 +1773,35 @@
                              int32_t offset,
                              Register value,
                              CanBeSmi can_value_be_smi = kValueCanBeSmi);
+  void StoreCompressedIntoObjectOffset(
+      Register object,
+      int32_t offset,
+      Register value,
+      CanBeSmi can_value_be_smi = kValueCanBeSmi);
   void StoreIntoObjectNoBarrier(Register object,
                                 const Address& dest,
                                 Register value);
+  void StoreCompressedIntoObjectNoBarrier(Register object,
+                                          const Address& dest,
+                                          Register value);
   void StoreIntoObjectOffsetNoBarrier(Register object,
                                       int32_t offset,
                                       Register value);
+  void StoreCompressedIntoObjectOffsetNoBarrier(Register object,
+                                                int32_t offset,
+                                                Register value);
   void StoreIntoObjectNoBarrier(Register object,
                                 const Address& dest,
                                 const Object& value);
+  void StoreCompressedIntoObjectNoBarrier(Register object,
+                                          const Address& dest,
+                                          const Object& value);
   void StoreIntoObjectOffsetNoBarrier(Register object,
                                       int32_t offset,
                                       const Object& value);
+  void StoreCompressedIntoObjectOffsetNoBarrier(Register object,
+                                                int32_t offset,
+                                                const Object& value);
 
   // Stores a non-tagged value into a heap object.
   void StoreInternalPointer(Register object,
diff --git a/runtime/vm/compiler/assembler/assembler_base.h b/runtime/vm/compiler/assembler/assembler_base.h
index a650f43..1ce7b58 100644
--- a/runtime/vm/compiler/assembler/assembler_base.h
+++ b/runtime/vm/compiler/assembler/assembler_base.h
@@ -191,6 +191,12 @@
   kRegList,
   // 64-bit ARM specific constants.
   kQWord,
+
+#if defined(TARGET_ARCH_IS_64_BIT) && !defined(DART_COMPRESSED_POINTERS)
+  kObjectBytes = kEightBytes,
+#else
+  kObjectBytes = kFourBytes,
+#endif
 };
 
 // Forward declarations.
diff --git a/runtime/vm/compiler/assembler/assembler_ia32.cc b/runtime/vm/compiler/assembler/assembler_ia32.cc
index c845d8a..56c4f3e 100644
--- a/runtime/vm/compiler/assembler/assembler_ia32.cc
+++ b/runtime/vm/compiler/assembler/assembler_ia32.cc
@@ -1763,20 +1763,19 @@
 }
 
 void Assembler::LoadFromOffset(Register reg,
-                               Register base,
-                               int32_t offset,
+                               const Address& address,
                                OperandSize type) {
   switch (type) {
     case kByte:
-      return movsxb(reg, Address(base, offset));
+      return movsxb(reg, address);
     case kUnsignedByte:
-      return movzxb(reg, Address(base, offset));
+      return movzxb(reg, address);
     case kTwoBytes:
-      return movsxw(reg, Address(base, offset));
+      return movsxw(reg, address);
     case kUnsignedTwoBytes:
-      return movzxw(reg, Address(base, offset));
+      return movzxw(reg, address);
     case kFourBytes:
-      return movl(reg, Address(base, offset));
+      return movl(reg, address);
     default:
       UNREACHABLE();
       break;
@@ -2409,6 +2408,15 @@
   call(FieldAddress(CODE_REG, target::Code::entry_point_offset(entry_kind)));
 }
 
+void Assembler::CallVmStub(const Code& target) {
+  const Object& target_as_object = CastHandle<Object, Code>(target);
+  ASSERT(target::CanEmbedAsRawPointerInGeneratedCode(target_as_object));
+  call(Address::Absolute(
+      target::ToRawPointer(target_as_object) +
+      target::Code::entry_point_offset(CodeEntryKind::kNormal) -
+      kHeapObjectTag));
+}
+
 void Assembler::CallToRuntime() {
   call(Address(THR, target::Thread::call_to_runtime_entry_point_offset()));
 }
diff --git a/runtime/vm/compiler/assembler/assembler_ia32.h b/runtime/vm/compiler/assembler/assembler_ia32.h
index 82b9745..a46152c 100644
--- a/runtime/vm/compiler/assembler/assembler_ia32.h
+++ b/runtime/vm/compiler/assembler/assembler_ia32.h
@@ -572,6 +572,9 @@
 
   void Ret() { ret(); }
   void CompareRegisters(Register a, Register b);
+  void CompareObjectRegisters(Register a, Register b) {
+    CompareRegisters(a, b);
+  }
   void BranchIf(Condition condition,
                 Label* label,
                 JumpDistance distance = kFarJump) {
@@ -584,23 +587,42 @@
     j(ZERO, label, distance);
   }
 
-  void LoadFromOffset(Register reg,
+  // Arch-specific LoadFromOffset to choose the right operation for [sz].
+  void LoadFromOffset(Register dst,
+                      const Address& address,
+                      OperandSize sz = kFourBytes);
+  void LoadFromOffset(Register dst,
                       Register base,
                       int32_t offset,
-                      OperandSize type = kFourBytes);
-  void LoadField(Register dst, FieldAddress address) { movl(dst, address); }
+                      OperandSize sz = kFourBytes) {
+    LoadFromOffset(dst, Address(base, offset), sz);
+  }
+  void LoadField(Register dst,
+                 const FieldAddress& address,
+                 OperandSize sz = kFourBytes) {
+    LoadFromOffset(dst, address, sz);
+  }
+  void LoadCompressedField(Register dst, const FieldAddress& address) {
+    LoadField(dst, address);
+  }
   void LoadFieldFromOffset(Register reg,
                            Register base,
                            int32_t offset,
-                           OperandSize type = kFourBytes) {
-    LoadFromOffset(reg, base, offset - kHeapObjectTag, type);
+                           OperandSize sz = kFourBytes) {
+    LoadFromOffset(reg, FieldAddress(base, offset), sz);
   }
-  void LoadIndexedFieldFromOffset(Register reg,
-                                  Register base,
-                                  int32_t offset,
-                                  Register index,
-                                  ScaleFactor scale) {
-    LoadField(reg, FieldAddress(base, index, scale, offset));
+  void LoadCompressedFieldFromOffset(Register reg,
+                                     Register base,
+                                     int32_t offset) {
+    LoadFieldFromOffset(reg, base, offset);
+  }
+  void LoadIndexedPayload(Register dst,
+                          Register base,
+                          int32_t payload_offset,
+                          Register index,
+                          ScaleFactor scale,
+                          OperandSize sz = kFourBytes) {
+    LoadFromOffset(dst, FieldAddress(base, index, scale, payload_offset), sz);
   }
   void LoadFromStack(Register dst, intptr_t depth);
   void StoreToStack(Register src, intptr_t depth);
@@ -770,6 +792,9 @@
             bool movable_target = false,
             CodeEntryKind entry_kind = CodeEntryKind::kNormal);
   void CallToRuntime();
+  // Will not clobber any registers and can therefore be called with 5 live
+  // registers.
+  void CallVmStub(const Code& code);
 
   void Call(Address target) { call(target); }
 
diff --git a/runtime/vm/compiler/assembler/assembler_x64.cc b/runtime/vm/compiler/assembler/assembler_x64.cc
index 7a616d9..274a5d8 100644
--- a/runtime/vm/compiler/assembler/assembler_x64.cc
+++ b/runtime/vm/compiler/assembler/assembler_x64.cc
@@ -533,22 +533,36 @@
   EmitSimple(0xDD, 0xC0 + value);
 }
 
-void Assembler::CompareImmediate(Register reg, const Immediate& imm) {
-  if (imm.is_int32()) {
-    cmpq(reg, imm);
+void Assembler::CompareImmediate(Register reg,
+                                 const Immediate& imm,
+                                 OperandSize width) {
+  if (width == kEightBytes) {
+    if (imm.is_int32()) {
+      cmpq(reg, imm);
+    } else {
+      ASSERT(reg != TMP);
+      LoadImmediate(TMP, imm);
+      cmpq(reg, TMP);
+    }
   } else {
-    ASSERT(reg != TMP);
-    LoadImmediate(TMP, imm);
-    cmpq(reg, TMP);
+    ASSERT(width == kFourBytes);
+    cmpl(reg, imm);
   }
 }
 
-void Assembler::CompareImmediate(const Address& address, const Immediate& imm) {
-  if (imm.is_int32()) {
-    cmpq(address, imm);
+void Assembler::CompareImmediate(const Address& address,
+                                 const Immediate& imm,
+                                 OperandSize width) {
+  if (width == kEightBytes) {
+    if (imm.is_int32()) {
+      cmpq(address, imm);
+    } else {
+      LoadImmediate(TMP, imm);
+      cmpq(address, TMP);
+    }
   } else {
-    LoadImmediate(TMP, imm);
-    cmpq(address, TMP);
+    ASSERT(width == kFourBytes);
+    cmpl(address, imm);
   }
 }
 
@@ -607,13 +621,20 @@
   }
 }
 
-void Assembler::TestImmediate(Register dst, const Immediate& imm) {
-  if (imm.is_int32() || imm.is_uint32()) {
-    testq(dst, imm);
+void Assembler::TestImmediate(Register dst,
+                              const Immediate& imm,
+                              OperandSize width) {
+  if (width == kEightBytes) {
+    if (imm.is_int32() || imm.is_uint32()) {
+      testq(dst, imm);
+    } else {
+      ASSERT(dst != TMP);
+      LoadImmediate(TMP, imm);
+      testq(dst, TMP);
+    }
   } else {
-    ASSERT(dst != TMP);
-    LoadImmediate(TMP, imm);
-    testq(dst, TMP);
+    ASSERT(width == kFourBytes);
+    testl(dst, imm);
   }
 }
 
@@ -1303,15 +1324,15 @@
 
   intptr_t offset_from_thread;
   if (target::CanLoadFromThread(object, &offset_from_thread)) {
-    cmpq(reg, Address(THR, offset_from_thread));
+    OBJ(cmp)(reg, Address(THR, offset_from_thread));
   } else if (CanLoadFromObjectPool(object)) {
     const intptr_t idx = object_pool_builder().FindObject(
         object, ObjectPoolBuilderEntry::kNotPatchable);
     const int32_t offset = target::ObjectPool::element_offset(idx);
-    cmpq(reg, Address(PP, offset - kHeapObjectTag));
+    OBJ(cmp)(reg, Address(PP, offset - kHeapObjectTag));
   } else {
     ASSERT(target::IsSmi(object));
-    CompareImmediate(reg, Immediate(target::ToRawSmi(object)));
+    CompareImmediate(reg, Immediate(target::ToRawSmi(object)), kObjectBytes);
   }
 }
 
@@ -1339,23 +1360,26 @@
   }
 }
 
-void Assembler::LoadCompressed(Register dest,
-                               const Address& slot,
-                               CanBeSmi can_value_be_smi) {
+void Assembler::LoadCompressed(Register dest, const Address& slot) {
 #if !defined(DART_COMPRESSED_POINTERS)
   movq(dest, slot);
 #else
-  Label done;
-  movsxd(dest, slot);  // (movslq) Sign-extension.
-  if (can_value_be_smi == kValueCanBeSmi) {
-    BranchIfSmi(dest, &done, kNearJump);
-  }
+  movl(dest, slot);  // Zero-extension.
   addq(dest, Address(THR, target::Thread::heap_base_offset()));
-  Bind(&done);
+#endif
+}
 
-  // After further Smi changes:
-  // movl(dest, slot);  // Zero-extension.
-  // addq(dest, Address(THR, target::Thread::heap_base_offset());
+void Assembler::LoadCompressedSmi(Register dest, const Address& slot) {
+#if !defined(DART_COMPRESSED_POINTERS)
+  movq(dest, slot);
+#else
+  movl(dest, slot);  // Zero-extension.
+#endif
+#if defined(DEBUG)
+  Label done;
+  BranchIfSmi(dest, &done);
+  Stop("Expected Smi");
+  Bind(&done);
 #endif
 }
 
@@ -1401,13 +1425,26 @@
                                 const Address& dest,
                                 Register value,
                                 CanBeSmi can_be_smi) {
+  movq(dest, value);
+  StoreBarrier(object, value, can_be_smi);
+}
+
+void Assembler::StoreCompressedIntoObject(Register object,
+                                          const Address& dest,
+                                          Register value,
+                                          CanBeSmi can_be_smi) {
+  OBJ(mov)(dest, value);
+  StoreBarrier(object, value, can_be_smi);
+}
+
+void Assembler::StoreBarrier(Register object,
+                             Register value,
+                             CanBeSmi can_be_smi) {
   // x.slot = x. Barrier should have be removed at the IL level.
   ASSERT(object != value);
   ASSERT(object != TMP);
   ASSERT(value != TMP);
 
-  movq(dest, value);
-
   // In parallel, test whether
   //  - object is old and not remembered and value is new, or
   //  - object is old and value is old and not marked and concurrent marking is
@@ -1511,12 +1548,39 @@
   // No store buffer update.
 }
 
+void Assembler::StoreCompressedIntoObjectNoBarrier(Register object,
+                                                   const Address& dest,
+                                                   Register value) {
+  OBJ(mov)(dest, value);
+#if defined(DEBUG)
+  Label done;
+  pushq(value);
+  StoreIntoObjectFilter(object, value, &done, kValueCanBeSmi, kJumpToNoUpdate);
+
+  testb(FieldAddress(object, target::Object::tags_offset()),
+        Immediate(1 << target::UntaggedObject::kOldAndNotRememberedBit));
+  j(ZERO, &done, Assembler::kNearJump);
+
+  Stop("Store buffer update is required");
+  Bind(&done);
+  popq(value);
+#endif  // defined(DEBUG)
+  // No store buffer update.
+}
+
 void Assembler::StoreIntoObjectNoBarrier(Register object,
                                          const Address& dest,
                                          const Object& value) {
   StoreObject(dest, value);
 }
 
+void Assembler::StoreCompressedIntoObjectNoBarrier(Register object,
+                                                   const Address& dest,
+                                                   const Object& value) {
+  LoadObject(TMP, value);
+  StoreCompressedIntoObjectNoBarrier(object, dest, TMP);
+}
+
 void Assembler::StoreInternalPointer(Register object,
                                      const Address& dest,
                                      Register value) {
@@ -1539,6 +1603,11 @@
   movq(dest, zero);
 }
 
+void Assembler::ZeroInitCompressedSmiField(const Address& dest) {
+  Immediate zero(target::ToRawSmi(0));
+  OBJ(mov)(dest, zero);
+}
+
 void Assembler::IncrementSmiField(const Address& dest, int64_t increment) {
   // Note: FlowGraphCompiler::EdgeCounterIncrementSizeInBytes depends on
   // the length of this instruction sequence.
@@ -1888,7 +1957,11 @@
   j(NOT_EQUAL, &miss, Assembler::kNearJump);
   addl(FieldAddress(RBX, count_offset), Immediate(target::ToRawSmi(1)));
   xorq(R10, R10);  // GC-safe for OptimizeInvokedFunction.
+#if !defined(DART_COMPRESSED_POINTERS)
   nop(1);
+#else
+  nop(2);
+#endif
 
   // Fall through to unchecked entry.
   ASSERT_EQUAL(CodeSize() - start,
@@ -1921,7 +1994,11 @@
 
   // Ensure the unchecked entry is 2-byte aligned (so GC can see them if we
   // store them in ICData / MegamorphicCache arrays).
+#if !defined(DART_COMPRESSED_POINTERS)
   nop(1);
+#else
+  nop(2);
+#endif
 
   // Fall through to unchecked entry.
   ASSERT_EQUAL(CodeSize() - start,
@@ -2230,6 +2307,7 @@
 void Assembler::SmiUntagOrCheckClass(Register object,
                                      intptr_t class_id,
                                      Label* is_smi) {
+#if !defined(DART_COMPRESSED_POINTERS)
   ASSERT(kSmiTagShift == 1);
   ASSERT(target::UntaggedObject::kClassIdTagPos == 16);
   ASSERT(target::UntaggedObject::kClassIdTagSize == 16);
@@ -2244,6 +2322,11 @@
   // factor in the addressing mode to compensate for this.
   movzxw(TMP, Address(object, TIMES_2, class_id_offset));
   cmpl(TMP, Immediate(class_id));
+#else
+  // Cannot speculatively untag compressed Smis because it erases upper address
+  // bits.
+  UNREACHABLE();
+#endif
 }
 
 void Assembler::LoadClassIdMayBeSmi(Register result, Register object) {
diff --git a/runtime/vm/compiler/assembler/assembler_x64.h b/runtime/vm/compiler/assembler/assembler_x64.h
index cffa9e9..75822c0 100644
--- a/runtime/vm/compiler/assembler/assembler_x64.h
+++ b/runtime/vm/compiler/assembler/assembler_x64.h
@@ -286,6 +286,12 @@
   }
 };
 
+#if !defined(DART_COMPRESSED_POINTERS)
+#define OBJ(op) op##q
+#else
+#define OBJ(op) op##l
+#endif
+
 class Assembler : public AssemblerBase {
  public:
   explicit Assembler(ObjectPoolBuilder* object_pool_builder,
@@ -544,10 +550,16 @@
   };
   void roundsd(XmmRegister dst, XmmRegister src, RoundingMode mode);
 
-  void CompareImmediate(Register reg, const Immediate& imm);
-  void CompareImmediate(const Address& address, const Immediate& imm);
-  void CompareImmediate(Register reg, int32_t immediate) {
-    return CompareImmediate(reg, Immediate(immediate));
+  void CompareImmediate(Register reg,
+                        const Immediate& imm,
+                        OperandSize width = kEightBytes);
+  void CompareImmediate(const Address& address,
+                        const Immediate& imm,
+                        OperandSize width = kEightBytes);
+  void CompareImmediate(Register reg,
+                        int32_t immediate,
+                        OperandSize width = kEightBytes) {
+    return CompareImmediate(reg, Immediate(immediate), width);
   }
 
   void testl(Register reg, const Immediate& imm) { testq(reg, imm); }
@@ -555,7 +567,9 @@
   void testb(const Address& address, Register reg);
 
   void testq(Register reg, const Immediate& imm);
-  void TestImmediate(Register dst, const Immediate& imm);
+  void TestImmediate(Register dst,
+                     const Immediate& imm,
+                     OperandSize width = kEightBytes);
 
   void AndImmediate(Register dst, const Immediate& imm);
   void OrImmediate(Register dst, const Immediate& imm);
@@ -678,6 +692,7 @@
   // Methods for High-level operations and implemented on all architectures.
   void Ret() { ret(); }
   void CompareRegisters(Register a, Register b);
+  void CompareObjectRegisters(Register a, Register b) { OBJ(cmp)(a, b); }
   void BranchIf(Condition condition,
                 Label* label,
                 JumpDistance distance = kFarJump) {
@@ -767,9 +782,8 @@
     kValueCanBeSmi,
   };
 
-  void LoadCompressed(Register dest,
-                      const Address& slot,
-                      CanBeSmi can_value_be_smi = kValueCanBeSmi);
+  void LoadCompressed(Register dest, const Address& slot);
+  void LoadCompressedSmi(Register dest, const Address& slot);
 
   // Store into a heap object and apply the generational and incremental write
   // barriers. All stores into heap objects must pass through this function or,
@@ -780,6 +794,14 @@
                        const Address& dest,  // Where we are storing into.
                        Register value,       // Value we are storing.
                        CanBeSmi can_be_smi = kValueCanBeSmi);
+  void StoreCompressedIntoObject(
+      Register object,      // Object we are storing into.
+      const Address& dest,  // Where we are storing into.
+      Register value,       // Value we are storing.
+      CanBeSmi can_be_smi = kValueCanBeSmi);
+  void StoreBarrier(Register object,  // Object we are storing into.
+                    Register value,   // Value we are storing.
+                    CanBeSmi can_be_smi);
   void StoreIntoArray(Register object,  // Object we are storing into.
                       Register slot,    // Where we are storing into.
                       Register value,   // Value we are storing.
@@ -788,9 +810,15 @@
   void StoreIntoObjectNoBarrier(Register object,
                                 const Address& dest,
                                 Register value);
+  void StoreCompressedIntoObjectNoBarrier(Register object,
+                                          const Address& dest,
+                                          Register value);
   void StoreIntoObjectNoBarrier(Register object,
                                 const Address& dest,
                                 const Object& value);
+  void StoreCompressedIntoObjectNoBarrier(Register object,
+                                          const Address& dest,
+                                          const Object& value);
 
   // Stores a non-tagged value into a heap object.
   void StoreInternalPointer(Register object,
@@ -800,6 +828,7 @@
   // Stores a Smi value into a heap object field that always contains a Smi.
   void StoreIntoSmiField(const Address& dest, Register value);
   void ZeroInitSmiField(const Address& dest);
+  void ZeroInitCompressedSmiField(const Address& dest);
   // Increments a Smi field. Leaves flags in same state as an 'addq'.
   void IncrementSmiField(const Address& dest, int64_t increment);
 
@@ -864,9 +893,21 @@
   void SmiUntagOrCheckClass(Register object, intptr_t class_id, Label* smi);
 
   // Misc. functionality.
-  void SmiTag(Register reg) { addq(reg, reg); }
+  void SmiTag(Register reg) { OBJ(add)(reg, reg); }
 
-  void SmiUntag(Register reg) { sarq(reg, Immediate(kSmiTagSize)); }
+  void SmiUntag(Register reg) { OBJ(sar)(reg, Immediate(kSmiTagSize)); }
+
+  void SmiUntagAndSignExtend(Register reg) {
+#if !defined(DART_COMPRESSED_POINTERS)
+    sarq(reg, Immediate(kSmiTagSize));
+#else
+    // This is shorter than
+    // shlq reg, 32
+    // sraq reg, 33
+    sarl(reg, Immediate(1));
+    movsxd(reg, reg);
+#endif
+  }
 
   void BranchIfNotSmi(Register reg,
                       Label* label,
@@ -906,12 +947,20 @@
                  OperandSize sz = kEightBytes) {
     LoadFromOffset(dst, address, sz);
   }
+  void LoadCompressedField(Register dst, FieldAddress address) {
+    LoadCompressed(dst, address);
+  }
   void LoadFieldFromOffset(Register dst,
                            Register base,
                            int32_t offset,
                            OperandSize sz = kEightBytes) {
     LoadFromOffset(dst, FieldAddress(base, offset), sz);
   }
+  void LoadCompressedFieldFromOffset(Register dst,
+                                     Register base,
+                                     int32_t offset) {
+    LoadCompressed(dst, FieldAddress(base, offset));
+  }
   void LoadIndexedPayload(Register dst,
                           Register base,
                           int32_t payload_offset,
@@ -950,7 +999,7 @@
   }
 
   void CompareWithFieldValue(Register value, FieldAddress address) {
-    cmpq(value, address);
+    OBJ(cmp)(value, address);
   }
 
   void CompareTypeNullabilityWith(Register type, int8_t value) {
diff --git a/runtime/vm/compiler/assembler/assembler_x64_test.cc b/runtime/vm/compiler/assembler/assembler_x64_test.cc
index 39d492d..9704c22 100644
--- a/runtime/vm/compiler/assembler/assembler_x64_test.cc
+++ b/runtime/vm/compiler/assembler/assembler_x64_test.cc
@@ -4971,6 +4971,7 @@
 ASSEMBLER_TEST_RUN(TestObjectCompare, test) {
   bool res = test->InvokeWithCodeAndThread<bool>();
   EXPECT_EQ(true, res);
+#if !defined(DART_COMPRESSED_POINTERS)
   EXPECT_DISASSEMBLY_NOT_WINDOWS(
       "push rbp\n"
       "movq rbp,rsp\n"
@@ -5014,6 +5015,51 @@
       "movq rsp,rbp\n"
       "pop rbp\n"
       "ret\n");
+#else
+  EXPECT_DISASSEMBLY_NOT_WINDOWS(
+      "push rbp\n"
+      "movq rbp,rsp\n"
+      "push r12\n"
+      "push pp\n"
+      "push thr\n"
+      "movq r12,[rdi+0x8]\n"
+      "movq thr,rsi\n"
+      "movq pp,[r12+0x27]\n"
+      "movq rax,[pp+0xf]\n"
+      "cmpl rax,[pp+0xf]\n"
+      "jnz 0x................\n"
+      "movq rcx,[pp+0xf]\n"
+      "cmpl rcx,[pp+0xf]\n"
+      "jnz 0x................\n"
+      "movl rcx,0x1e\n"
+      "cmpl rcx,0x1e\n"
+      "jnz 0x................\n"
+      "push rax\n"
+      "movq r11,[pp+0xf]\n"
+      "movq [rsp],r11\n"
+      "pop rcx\n"
+      "cmpl rcx,[pp+0xf]\n"
+      "jnz 0x................\n"
+      "push rax\n"
+      "movq [rsp],0x1e\n"
+      "pop rcx\n"
+      "cmpl rcx,0x1e\n"
+      "jnz 0x................\n"
+      "movl rax,1\n"
+      "pop thr\n"
+      "pop pp\n"
+      "pop r12\n"
+      "movq rsp,rbp\n"
+      "pop rbp\n"
+      "ret\n"
+      "movl rax,0\n"
+      "pop thr\n"
+      "pop pp\n"
+      "pop r12\n"
+      "movq rsp,rbp\n"
+      "pop rbp\n"
+      "ret\n");
+#endif
 }
 
 ASSEMBLER_TEST_GENERATE(TestNop, assembler) {
diff --git a/runtime/vm/compiler/assembler/disassembler.cc b/runtime/vm/compiler/assembler/disassembler.cc
index 9e19290..e950867 100644
--- a/runtime/vm/compiler/assembler/disassembler.cc
+++ b/runtime/vm/compiler/assembler/disassembler.cc
@@ -463,8 +463,7 @@
   TextBuffer buffer(128);
   const char* function_fullname = function.ToFullyQualifiedCString();
   buffer.Printf("%s", Function::KindToCString(function.kind()));
-  if (function.IsInvokeFieldDispatcher() ||
-      function.IsNoSuchMethodDispatcher()) {
+  if (function.HasSavedArgumentsDescriptor()) {
     const auto& args_desc_array = Array::Handle(function.saved_args_desc());
     const ArgumentsDescriptor args_desc(args_desc_array);
     buffer.AddString(", ");
diff --git a/runtime/vm/compiler/backend/block_builder.h b/runtime/vm/compiler/backend/block_builder.h
index ef51d8d..9c4dc68 100644
--- a/runtime/vm/compiler/backend/block_builder.h
+++ b/runtime/vm/compiler/backend/block_builder.h
@@ -25,7 +25,7 @@
         entry_(entry),
         current_(entry),
         dummy_env_(
-            new Environment(0, 0, flow_graph->parsed_function(), nullptr)) {
+            new Environment(0, 0, 0, flow_graph->parsed_function(), nullptr)) {
     // Some graph transformations use environments from block entries.
     entry->SetEnvironment(dummy_env_);
   }
@@ -50,6 +50,7 @@
   template <typename T>
   T* AddInstruction(T* instr) {
     if (instr->ComputeCanDeoptimize() ||
+        instr->ComputeCanDeoptimizeAfterCall() ||
         instr->CanBecomeDeoptimizationTarget()) {
       // All instructions that can deoptimize must have an environment attached
       // to them.
diff --git a/runtime/vm/compiler/backend/compile_type.h b/runtime/vm/compiler/backend/compile_type.h
index 3a7d6aa..9d81af6 100644
--- a/runtime/vm/compiler/backend/compile_type.h
+++ b/runtime/vm/compiler/backend/compile_type.h
@@ -18,9 +18,6 @@
 class AbstractType;
 class BaseTextBuffer;
 class Definition;
-class FlowGraphSerializer;
-class SExpression;
-class SExpList;
 
 template <typename T>
 class GrowableArray;
@@ -200,8 +197,7 @@
       return true;
     }
     if (cid_ == kIllegalCid || cid_ == kDynamicCid) {
-      return type_ != nullptr &&
-             (compiler::IsIntType(*type_) || compiler::IsSmiType(*type_));
+      return type_ != nullptr && compiler::IsSubtypeOfInt(*type_);
     }
     return false;
   }
@@ -248,8 +244,6 @@
   bool Specialize(GrowableArray<intptr_t>* class_ids);
 
   void PrintTo(BaseTextBuffer* f) const;
-  SExpression* ToSExpression(FlowGraphSerializer* s) const;
-  void AddExtraInfoToSExpression(SExpList* sexp, FlowGraphSerializer* s) const;
 
   const char* ToCString() const;
 
diff --git a/runtime/vm/compiler/backend/constant_propagator.cc b/runtime/vm/compiler/backend/constant_propagator.cc
index df2b9df..1ba1c36 100644
--- a/runtime/vm/compiler/backend/constant_propagator.cc
+++ b/runtime/vm/compiler/backend/constant_propagator.cc
@@ -1155,15 +1155,6 @@
   SetValue(binary_op, non_constant_);
 }
 
-void ConstantPropagator::VisitCheckedSmiOp(CheckedSmiOpInstr* instr) {
-  SetValue(instr, non_constant_);
-}
-
-void ConstantPropagator::VisitCheckedSmiComparison(
-    CheckedSmiComparisonInstr* instr) {
-  SetValue(instr, non_constant_);
-}
-
 void ConstantPropagator::VisitBinarySmiOp(BinarySmiOpInstr* instr) {
   VisitBinaryIntegerOp(instr);
 }
diff --git a/runtime/vm/compiler/backend/constant_propagator_test.cc b/runtime/vm/compiler/backend/constant_propagator_test.cc
index 3eb3218..5265ea0 100644
--- a/runtime/vm/compiler/backend/constant_propagator_test.cc
+++ b/runtime/vm/compiler/backend/constant_propagator_test.cc
@@ -51,7 +51,7 @@
 
   {
     BlockBuilder builder(H.flow_graph(), b2);
-    v1 = H.Phi(b2, {{b1, v0}, {b3, FlowGraphBuilderHelper::kPhiSelfReference}});
+    v1 = H.Phi(b2, {{b1, v0}, {b3, &v1}});
     builder.AddPhi(v1);
     auto v2 = builder.AddDefinition(
         new EqualityCompareInstr(InstructionSource(), Token::kEQ, new Value(v1),
diff --git a/runtime/vm/compiler/backend/evaluator.cc b/runtime/vm/compiler/backend/evaluator.cc
index 11b007a..fd8c0e8 100644
--- a/runtime/vm/compiler/backend/evaluator.cc
+++ b/runtime/vm/compiler/backend/evaluator.cc
@@ -71,9 +71,8 @@
 int64_t Evaluator::TruncateTo(int64_t v, Representation r) {
   switch (r) {
     case kTagged: {
-      // Smi occupies word minus kSmiTagShift bits.
       const intptr_t kTruncateBits =
-          (kBitsPerInt64 - kBitsPerWord) + kSmiTagShift;
+          kBitsPerInt64 - (compiler::target::kSmiBits + 1 /*sign bit*/);
       return Utils::ShiftLeftWithTruncation(v, kTruncateBits) >> kTruncateBits;
     }
     case kUnboxedInt32:
diff --git a/runtime/vm/compiler/backend/flow_graph.cc b/runtime/vm/compiler/backend/flow_graph.cc
index 69b2bd0..2f14395 100644
--- a/runtime/vm/compiler/backend/flow_graph.cc
+++ b/runtime/vm/compiler/backend/flow_graph.cc
@@ -1304,24 +1304,9 @@
 
 void FlowGraph::AttachEnvironment(Instruction* instr,
                                   GrowableArray<Definition*>* env) {
-  Environment* deopt_env =
-      Environment::From(zone(), *env, num_direct_parameters_, parsed_function_);
-  if (instr->IsClosureCall() || instr->IsLoadField()) {
-    // Trim extra inputs of ClosureCall and LoadField instructions from
-    // the environment. Inputs of those instructions are not pushed onto
-    // the stack at the point where deoptimization can occur.
-    // Note that in case of LoadField there can be two possible situations,
-    // the code here handles LoadField to LoadField lazy deoptimization in
-    // which we are transitioning from position after the call to initialization
-    // stub in optimized code to a similar position after the call to
-    // initialization stub in unoptimized code. There is another variant
-    // (LoadField deoptimizing into a position after a getter call) which is
-    // handled in a different way (see
-    // CallSpecializer::InlineImplicitInstanceGetter).
-    deopt_env =
-        deopt_env->DeepCopy(zone(), deopt_env->Length() - instr->InputCount() +
-                                        instr->ArgumentCount());
-  }
+  auto deopt_env = Environment::From(zone(), *env, num_direct_parameters_,
+                                     instr->NumberOfInputsConsumedBeforeCall(),
+                                     parsed_function_);
   instr->SetEnvironment(deopt_env);
   for (Environment::DeepIterator it(deopt_env); !it.Done(); it.Advance()) {
     Value* use = it.CurrentValue();
@@ -1901,7 +1886,7 @@
   }
 }
 
-static void UnboxPhi(PhiInstr* phi) {
+static void UnboxPhi(PhiInstr* phi, bool is_aot) {
   Representation unboxed = phi->representation();
 
   switch (phi->Type()->ToCid()) {
@@ -2004,10 +1989,22 @@
     }
   }
 
+#if defined(TARGET_ARCH_IS_64_BIT)
+  // In AOT mode on 64-bit platforms always unbox integer typed phis (similar
+  // to how we treat doubles and other boxed numeric types).
+  // In JIT mode only unbox phis which are not fully known to be Smi.
+  if ((unboxed == kTagged) && phi->Type()->IsInt() &&
+      (is_aot || phi->Type()->ToCid() != kSmiCid)) {
+    unboxed = kUnboxedInt64;
+  }
+#endif
+
   phi->set_representation(unboxed);
 }
 
 void FlowGraph::SelectRepresentations() {
+  const auto is_aot = CompilerState::Current().is_aot();
+
   // First we decide for each phi if it is beneficial to unbox it. If so, we
   // change it's `phi->representation()`
   for (BlockIterator block_it = reverse_postorder_iterator(); !block_it.Done();
@@ -2016,7 +2013,7 @@
     if (join_entry != NULL) {
       for (PhiIterator it(join_entry); !it.Done(); it.Advance()) {
         PhiInstr* phi = it.Current();
-        UnboxPhi(phi);
+        UnboxPhi(phi, is_aot);
       }
     }
   }
@@ -2296,6 +2293,7 @@
     for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) {
       Instruction* current = it.Current();
       if (!current->ComputeCanDeoptimize() &&
+          !current->ComputeCanDeoptimizeAfterCall() &&
           (!current->MayThrow() || !current->GetBlock()->InsideTryBlock())) {
         // Instructions that can throw need an environment for optimized
         // try-catch.
diff --git a/runtime/vm/compiler/backend/flow_graph_checker.cc b/runtime/vm/compiler/backend/flow_graph_checker.cc
index 0943943..162fdd3 100644
--- a/runtime/vm/compiler/backend/flow_graph_checker.cc
+++ b/runtime/vm/compiler/backend/flow_graph_checker.cc
@@ -118,8 +118,11 @@
     // correspond directly with the arguments.
     const intptr_t env_count = env->Length();
     const intptr_t arg_count = call->ArgumentCount();
-    ASSERT(arg_count <= env_count);
-    const intptr_t env_base = env_count - arg_count;
+    // Some calls (e.g. closure calls) have more inputs than actual arguments.
+    // Those extra inputs will be consumed from the stack before the call.
+    const intptr_t after_args_input_count = call->env()->LazyDeoptPruneCount();
+    ASSERT((arg_count + after_args_input_count) <= env_count);
+    const intptr_t env_base = env_count - arg_count - after_args_input_count;
     for (intptr_t i = 0; i < arg_count; i++) {
       if (call->HasPushArguments()) {
         ASSERT(call->ArgumentAt(i) == env->ValueAt(env_base + i)
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler.cc b/runtime/vm/compiler/backend/flow_graph_compiler.cc
index f5423f3c..da51b20 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler.cc
@@ -508,7 +508,7 @@
     // deoptimization point in optimized code, after call.
     const intptr_t deopt_id_after = DeoptId::ToDeoptAfter(deopt_id);
     if (is_optimizing()) {
-      AddDeoptIndexAtCall(deopt_id_after);
+      AddDeoptIndexAtCall(deopt_id_after, env);
     } else {
       // Add deoptimization continuation point after the call and before the
       // arguments are removed.
@@ -902,14 +902,21 @@
   dispatch_table_call_targets_.Add(selector);
 }
 
-CompilerDeoptInfo* FlowGraphCompiler::AddDeoptIndexAtCall(intptr_t deopt_id) {
+CompilerDeoptInfo* FlowGraphCompiler::AddDeoptIndexAtCall(intptr_t deopt_id,
+                                                          Environment* env) {
   ASSERT(is_optimizing());
   ASSERT(!intrinsic_mode());
   ASSERT(!FLAG_precompiled_mode);
+  if (env == nullptr) {
+    env = pending_deoptimization_env_;
+  }
+  if (env != nullptr) {
+    env = env->GetLazyDeoptEnv(zone());
+  }
   CompilerDeoptInfo* info =
       new (zone()) CompilerDeoptInfo(deopt_id, ICData::kDeoptAtCall,
                                      0,  // No flags.
-                                     pending_deoptimization_env_);
+                                     env);
   info->set_pc_offset(assembler()->CodeSize());
   deopt_infos_.Add(info);
   return info;
@@ -1104,7 +1111,8 @@
     return nullptr;
   }
 
-  Environment* slow_path_env = env->DeepCopy(zone());
+  Environment* slow_path_env =
+      env->DeepCopy(zone(), env->Length() - env->LazyDeoptPruneCount());
   // 1. Iterate the registers in the order they will be spilled to compute
   //    the slots they will be spilled to.
   intptr_t next_slot = StackSize() + slow_path_env->CountArgsPushed();
@@ -2532,10 +2540,12 @@
     // 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());
+    __ LoadCompressedFieldFromOffset(
+        kScratch1Reg, kScratch1Reg,
+        compiler::target::Class::super_type_offset());
+    __ LoadCompressedFieldFromOffset(
+        kScratch1Reg, kScratch1Reg,
+        compiler::target::Type::type_class_id_offset());
     __ CompareImmediate(kScratch1Reg, Smi::RawValue(type_class.id()));
     __ BranchIf(EQUAL, is_instance_lbl);
   }
@@ -2744,7 +2754,6 @@
   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.
@@ -2806,6 +2815,7 @@
   __ Bind(&done);
 }
 
+#if !defined(TARGET_ARCH_IA32)
 // Expected inputs (from TypeTestABI):
 // - kInstanceReg: instance (preserved).
 // - kDstTypeReg: destination type (for test_kind != kTestTypeOneArg).
@@ -2929,6 +2939,7 @@
   } else {
     GenerateIndirectTTSCall(assembler(), reg_with_type, sub_type_cache_index);
   }
+
   EmitCallsiteMetadata(source, deopt_id, UntaggedPcDescriptors::kOther, locs);
 }
 
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler.h b/runtime/vm/compiler/backend/flow_graph_compiler.h
index f3f422e..6973f62 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler.h
+++ b/runtime/vm/compiler/backend/flow_graph_compiler.h
@@ -436,7 +436,6 @@
   ~FlowGraphCompiler();
 
   static bool SupportsUnboxedDoubles();
-  static bool SupportsUnboxedInt64();
   static bool SupportsUnboxedSimd128();
   static bool SupportsHardwareDivision();
   static bool CanConvertInt64ToDouble();
@@ -765,8 +764,7 @@
                        intptr_t total_ic_calls,
                        Code::EntryKind entry_kind = Code::EntryKind::kNormal);
 
-  void EmitDispatchTableCall(Register cid_reg,
-                             int32_t selector_offset,
+  void EmitDispatchTableCall(int32_t selector_offset,
                              const Array& arguments_descriptor);
 
   Condition EmitEqualityRegConstCompare(Register reg,
@@ -862,7 +860,8 @@
                                 ICData::DeoptReasonId reason,
                                 uint32_t flags = 0);
 
-  CompilerDeoptInfo* AddDeoptIndexAtCall(intptr_t deopt_id);
+  CompilerDeoptInfo* AddDeoptIndexAtCall(intptr_t deopt_id,
+                                         Environment* env = nullptr);
   CompilerDeoptInfo* AddSlowPathDeoptInfo(intptr_t deopt_id, Environment* env);
 
   void AddSlowPathCode(SlowPathCode* slow_path);
@@ -984,8 +983,6 @@
   friend class StoreIndexedInstr;        // For AddPcRelativeCallStubTarget().
   friend class StoreInstanceFieldInstr;  // For AddPcRelativeCallStubTarget().
   friend class CheckStackOverflowSlowPath;  // For pending_deoptimization_env_.
-  friend class CheckedSmiSlowPath;          // Same.
-  friend class CheckedSmiComparisonSlowPath;  // Same.
   friend class GraphInstrinsicCodeGenScope;   // For optimizing_.
 
   // Architecture specific implementation of simple native moves.
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc b/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
index d9a48c0..f3acbb0 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
@@ -25,7 +25,6 @@
 namespace dart {
 
 DEFINE_FLAG(bool, trap_on_deoptimization, false, "Trap on deoptimization.");
-DEFINE_FLAG(bool, unbox_mints, true, "Optimize 64-bit integer arithmetic.");
 DEFINE_FLAG(bool, unbox_doubles, true, "Optimize double arithmetic.");
 DECLARE_FLAG(bool, enable_simd_inline);
 
@@ -70,10 +69,6 @@
   return TargetCPUFeatures::vfp_supported() && FLAG_unbox_doubles;
 }
 
-bool FlowGraphCompiler::SupportsUnboxedInt64() {
-  return FLAG_unbox_mints;
-}
-
 bool FlowGraphCompiler::SupportsUnboxedSimd128() {
   return TargetCPUFeatures::neon_supported() && FLAG_enable_simd_inline;
 }
@@ -148,7 +143,7 @@
     // For any outer environment the deopt id is that of the call instruction
     // which is recorded in the outer environment.
     builder->AddReturnAddress(current->function(),
-                              DeoptId::ToDeoptAfter(current->deopt_id()),
+                              DeoptId::ToDeoptAfter(current->GetDeoptId()),
                               slot_ix++);
 
     // The values of outgoing arguments can be changed from the inlined call so
@@ -701,9 +696,9 @@
 }
 
 void FlowGraphCompiler::EmitDispatchTableCall(
-    Register cid_reg,
     int32_t selector_offset,
     const Array& arguments_descriptor) {
+  const auto cid_reg = DispatchTableNullErrorABI::kClassIdReg;
   ASSERT(CanCallDart());
   ASSERT(cid_reg != ARGS_DESC_REG);
   if (!arguments_descriptor.IsNull()) {
@@ -712,6 +707,9 @@
   intptr_t offset = (selector_offset - DispatchTable::OriginElement()) *
                     compiler::target::kWordSize;
   CLOBBERS_LR({
+    // Would like cid_reg to be available on entry to the target function
+    // for checking purposes.
+    ASSERT(cid_reg != LR);
     if (offset == 0) {
       __ ldr(LR, compiler::Address(DISPATCH_TABLE_REG, cid_reg, LSL,
                                    compiler::target::kWordSizeLog2));
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc b/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc
index 40347c7..888f4f1 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc
@@ -26,7 +26,6 @@
 
 DEFINE_FLAG(bool, trap_on_deoptimization, false, "Trap on deoptimization.");
 DECLARE_FLAG(bool, enable_simd_inline);
-DEFINE_FLAG(bool, unbox_mints, true, "Optimize 64-bit integer arithmetic.");
 
 void FlowGraphCompiler::ArchSpecificInitialization() {
   if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
@@ -66,10 +65,6 @@
   return true;
 }
 
-bool FlowGraphCompiler::SupportsUnboxedInt64() {
-  return FLAG_unbox_mints;
-}
-
 bool FlowGraphCompiler::SupportsUnboxedSimd128() {
   return FLAG_enable_simd_inline;
 }
@@ -142,7 +137,7 @@
     // For any outer environment the deopt id is that of the call instruction
     // which is recorded in the outer environment.
     builder->AddReturnAddress(current->function(),
-                              DeoptId::ToDeoptAfter(current->deopt_id()),
+                              DeoptId::ToDeoptAfter(current->GetDeoptId()),
                               slot_ix++);
 
     // The values of outgoing arguments can be changed from the inlined call so
@@ -694,18 +689,23 @@
 }
 
 void FlowGraphCompiler::EmitDispatchTableCall(
-    Register cid_reg,
     int32_t selector_offset,
     const Array& arguments_descriptor) {
+  const auto cid_reg = DispatchTableNullErrorABI::kClassIdReg;
   ASSERT(CanCallDart());
   ASSERT(cid_reg != ARGS_DESC_REG);
   if (!arguments_descriptor.IsNull()) {
     __ LoadObject(ARGS_DESC_REG, arguments_descriptor);
   }
   const intptr_t offset = selector_offset - DispatchTable::OriginElement();
-  __ AddImmediate(cid_reg, cid_reg, offset);
-  __ Call(compiler::Address(DISPATCH_TABLE_REG, cid_reg, UXTX,
-                            compiler::Address::Scaled));
+  CLOBBERS_LR({
+    // Would like cid_reg to be available on entry to the target function
+    // for checking purposes.
+    ASSERT(cid_reg != LR);
+    __ AddImmediate(LR, cid_reg, offset);
+    __ Call(compiler::Address(DISPATCH_TABLE_REG, LR, UXTX,
+                              compiler::Address::Scaled));
+  });
 }
 
 Condition FlowGraphCompiler::EmitEqualityRegConstCompare(
@@ -751,7 +751,7 @@
     // Stub returns result in flags (result of a cmp, we need Z computed).
     __ PopPair(right, left);
   } else {
-    __ CompareRegisters(left, right);
+    __ CompareObjectRegisters(left, right);
   }
   return EQ;
 }
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc b/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc
index d89ec9a..5984b26 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc
@@ -26,7 +26,6 @@
 namespace dart {
 
 DEFINE_FLAG(bool, trap_on_deoptimization, false, "Trap on deoptimization.");
-DEFINE_FLAG(bool, unbox_mints, true, "Optimize 64-bit integer arithmetic.");
 
 DECLARE_FLAG(bool, enable_simd_inline);
 
@@ -45,10 +44,6 @@
   return true;
 }
 
-bool FlowGraphCompiler::SupportsUnboxedInt64() {
-  return FLAG_unbox_mints;
-}
-
 bool FlowGraphCompiler::SupportsUnboxedSimd128() {
   return FLAG_enable_simd_inline;
 }
@@ -118,7 +113,7 @@
     // For any outer environment the deopt id is that of the call instruction
     // which is recorded in the outer environment.
     builder->AddReturnAddress(current->function(),
-                              DeoptId::ToDeoptAfter(current->deopt_id()),
+                              DeoptId::ToDeoptAfter(current->GetDeoptId()),
                               slot_ix++);
 
     // The values of outgoing arguments can be changed from the inlined call so
@@ -252,75 +247,6 @@
   return type_test_cache.ptr();
 }
 
-// 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:
-// - EAX: object.
-// - EDX: instantiator type arguments or raw_null.
-// - ECX: function type arguments or raw_null.
-// Returns:
-// - true or false in EAX.
-void FlowGraphCompiler::GenerateInstanceOf(const InstructionSource& source,
-                                           intptr_t deopt_id,
-                                           const AbstractType& type,
-                                           LocationSummary* locs) {
-  ASSERT(type.IsFinalized());
-  ASSERT(!type.IsTopTypeForInstanceOf());  // Already checked.
-
-  const compiler::Immediate& raw_null =
-      compiler::Immediate(static_cast<intptr_t>(Object::null()));
-  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().
-    __ cmpl(EAX, raw_null);
-    __ 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());
-  test_cache =
-      GenerateInlineInstanceof(source, 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.
-    __ PushObject(Object::null_object());  // Make room for the result.
-    __ pushl(TypeTestABI::kInstanceReg);   // Push the instance.
-    __ PushObject(type);                   // Push the type.
-    __ pushl(TypeTestABI::kInstantiatorTypeArgumentsReg);
-    __ pushl(TypeTestABI::kFunctionTypeArgumentsReg);
-    // Can reuse kInstanceReg as scratch here since it was pushed above.
-    __ LoadObject(TypeTestABI::kInstanceReg, test_cache);
-    __ pushl(TypeTestABI::kInstanceReg);
-    GenerateRuntimeCall(source, 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(TypeTestABI::kInstanceOfResultReg);
-    __ jmp(&done, compiler::Assembler::kNearJump);
-  }
-  __ Bind(&is_not_instance);
-  __ LoadObject(TypeTestABI::kInstanceOfResultReg, Bool::Get(false));
-  __ jmp(&done, compiler::Assembler::kNearJump);
-
-  __ Bind(&is_instance);
-  __ LoadObject(TypeTestABI::kInstanceOfResultReg, Bool::Get(true));
-  __ Bind(&done);
-}
-
 // Optimize assignable type check by adding inlined tests for:
 // - NULL -> return NULL.
 // - Smi -> compile time subtype check (only if dst class is not parameterized).
@@ -395,26 +321,33 @@
   }
 
   __ Bind(&runtime_call);
-  __ PushObject(Object::null_object());            // Make room for the result.
-  __ pushl(TypeTestABI::kInstanceReg);             // Push the source object.
-  // Push the type of the destination.
+
+  // We push the inputs of [AssertAssignable] in the same order as they lie on
+  // the stack in unoptimized code.
+  // That will make the deopt environment we emit as metadata correct and
+  // doesn't need pruning (as in other architectures).
+
+  static_assert(AssertAssignableInstr::kNumInputs == 4,
+                "Expected AssertAssignable to have 4 inputs");
+
+  __ PushRegister(TypeTestABI::kInstanceReg);
   if (!dst_type.IsNull()) {
     __ PushObject(dst_type);
   } else {
-    __ pushl(TypeTestABI::kDstTypeReg);
+    __ PushRegister(TypeTestABI::kDstTypeReg);
   }
-  __ pushl(TypeTestABI::kInstantiatorTypeArgumentsReg);
-  __ pushl(TypeTestABI::kFunctionTypeArgumentsReg);
-  __ PushObject(dst_name);  // Push the name of the destination.
-  // 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(source, deopt_id, kTypeCheckRuntimeEntry, 7, locs);
-  // Pop the parameters supplied to the runtime entry. The result of the
-  // type check runtime call is the checked value.
-  __ Drop(7);
-  __ popl(TypeTestABI::kInstanceReg);
+  __ PushRegister(TypeTestABI::kInstantiatorTypeArgumentsReg);
+  __ PushRegister(TypeTestABI::kFunctionTypeArgumentsReg);
+
+  // Pass destination name and subtype test reg as register arguments.
+  __ LoadObject(AssertAssignableStubABI::kDstNameReg, dst_name);
+  __ LoadObject(AssertAssignableStubABI::kSubtypeTestReg, test_cache);
+
+  GenerateStubCall(source, StubCode::AssertAssignable(),
+                   UntaggedPcDescriptors::kOther, locs, deopt_id);
+
+  __ Drop(AssertAssignableInstr::kNumInputs - 1);
+  __ PopRegister(TypeTestABI::kInstanceReg);
 
   __ Bind(&is_assignable);
 }
@@ -532,7 +465,11 @@
 }
 
 void FlowGraphCompiler::EmitCallToStub(const Code& stub) {
-  __ Call(stub);
+  if (stub.InVMIsolateHeap()) {
+    __ CallVmStub(stub);
+  } else {
+    __ Call(stub);
+  }
   AddStubCallTarget(stub);
 }
 
@@ -718,7 +655,6 @@
 }
 
 void FlowGraphCompiler::EmitDispatchTableCall(
-    Register cid_reg,
     int32_t selector_offset,
     const Array& arguments_descriptor) {
   // Only generated with precompilation.
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc b/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
index 89f2a24..11cfcb6 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
@@ -25,7 +25,6 @@
 namespace dart {
 
 DEFINE_FLAG(bool, trap_on_deoptimization, false, "Trap on deoptimization.");
-DEFINE_FLAG(bool, unbox_mints, true, "Optimize 64-bit integer arithmetic.");
 DECLARE_FLAG(bool, enable_simd_inline);
 
 void FlowGraphCompiler::ArchSpecificInitialization() {
@@ -67,10 +66,6 @@
   return true;
 }
 
-bool FlowGraphCompiler::SupportsUnboxedInt64() {
-  return FLAG_unbox_mints;
-}
-
 bool FlowGraphCompiler::SupportsUnboxedSimd128() {
   return FLAG_enable_simd_inline;
 }
@@ -143,7 +138,7 @@
     // For any outer environment the deopt id is that of the call instruction
     // which is recorded in the outer environment.
     builder->AddReturnAddress(current->function(),
-                              DeoptId::ToDeoptAfter(current->deopt_id()),
+                              DeoptId::ToDeoptAfter(current->GetDeoptId()),
                               slot_ix++);
 
     // The values of outgoing arguments can be changed from the inlined call so
@@ -682,9 +677,9 @@
 }
 
 void FlowGraphCompiler::EmitDispatchTableCall(
-    Register cid_reg,
     int32_t selector_offset,
     const Array& arguments_descriptor) {
+  const auto cid_reg = DispatchTableNullErrorABI::kClassIdReg;
   ASSERT(CanCallDart());
   const Register table_reg = RAX;
   ASSERT(cid_reg != table_reg);
@@ -708,7 +703,7 @@
 
   if (obj.IsSmi() && (Smi::Cast(obj).Value() == 0)) {
     ASSERT(!needs_number_check);
-    __ testq(reg, reg);
+    __ OBJ(test)(reg, reg);
     return EQUAL;
   }
 
@@ -749,7 +744,7 @@
     __ popq(right);
     __ popq(left);
   } else {
-    __ CompareRegisters(left, right);
+    __ CompareObjectRegisters(left, right);
   }
   return EQUAL;
 }
diff --git a/runtime/vm/compiler/backend/flow_graph_test.cc b/runtime/vm/compiler/backend/flow_graph_test.cc
new file mode 100644
index 0000000..00baa85
--- /dev/null
+++ b/runtime/vm/compiler/backend/flow_graph_test.cc
@@ -0,0 +1,84 @@
+// 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 "vm/compiler/backend/flow_graph.h"
+
+#include <vector>
+
+#include "platform/utils.h"
+#include "vm/compiler/backend/block_builder.h"
+#include "vm/compiler/backend/il_printer.h"
+#include "vm/compiler/backend/il_test_helper.h"
+#include "vm/compiler/backend/type_propagator.h"
+#include "vm/unit_test.h"
+
+namespace dart {
+
+#if defined(TARGET_ARCH_IS_64_BIT)
+ISOLATE_UNIT_TEST_CASE(FlowGraph_UnboxInt64Phi) {
+  using compiler::BlockBuilder;
+
+  CompilerState S(thread, /*is_aot=*/true, /*is_optimizing=*/true);
+
+  FlowGraphBuilderHelper H;
+
+  // Add a variable into the scope which would provide static type for the
+  // parameter.
+  LocalVariable* v0_var =
+      new LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource,
+                        String::Handle(Symbols::New(thread, "v0")),
+                        AbstractType::ZoneHandle(Type::IntType()),
+                        new CompileType(CompileType::Int()));
+  v0_var->set_type_check_mode(LocalVariable::kTypeCheckedByCaller);
+  H.flow_graph()->parsed_function().scope()->AddVariable(v0_var);
+
+  auto normal_entry = H.flow_graph()->graph_entry()->normal_entry();
+  auto loop_header = H.JoinEntry();
+  auto loop_body = H.TargetEntry();
+  auto loop_exit = H.TargetEntry();
+
+  Definition* v0;
+  PhiInstr* loop_var;
+  Definition* add1;
+
+  {
+    BlockBuilder builder(H.flow_graph(), normal_entry);
+    v0 = builder.AddParameter(0, 0, /*with_frame=*/true, kTagged);
+    builder.AddInstruction(new GotoInstr(loop_header, S.GetNextDeoptId()));
+  }
+
+  {
+    BlockBuilder builder(H.flow_graph(), loop_header);
+    loop_var = H.Phi(loop_header, {{normal_entry, v0}, {loop_body, &add1}});
+    builder.AddPhi(loop_var);
+    builder.AddBranch(new RelationalOpInstr(
+                          InstructionSource(), Token::kLT, new Value(loop_var),
+                          new Value(H.IntConstant(50)), kMintCid,
+                          S.GetNextDeoptId(), Instruction::kNotSpeculative),
+                      loop_body, loop_exit);
+  }
+
+  {
+    BlockBuilder builder(H.flow_graph(), loop_body);
+    add1 = builder.AddDefinition(new BinaryInt64OpInstr(
+        Token::kADD, new Value(loop_var), new Value(H.IntConstant(1)),
+        S.GetNextDeoptId(), Instruction::kNotSpeculative));
+    builder.AddInstruction(new GotoInstr(loop_header, S.GetNextDeoptId()));
+  }
+
+  {
+    BlockBuilder builder(H.flow_graph(), loop_exit);
+    builder.AddReturn(new Value(loop_var));
+  }
+
+  H.FinishGraph();
+
+  FlowGraphTypePropagator::Propagate(H.flow_graph());
+  H.flow_graph()->SelectRepresentations();
+
+  EXPECT_PROPERTY(loop_var, it.representation() == kUnboxedInt64);
+}
+#endif  // defined(TARGET_ARCH_IS_64_BIT)
+
+}  // namespace dart
diff --git a/runtime/vm/compiler/backend/il.cc b/runtime/vm/compiler/backend/il.cc
index 441120c..9b15447 100644
--- a/runtime/vm/compiler/backend/il.cc
+++ b/runtime/vm/compiler/backend/il.cc
@@ -995,8 +995,9 @@
 
 AllocateUninitializedContextInstr::AllocateUninitializedContextInstr(
     const InstructionSource& source,
-    intptr_t num_context_variables)
-    : TemplateAllocation(source),
+    intptr_t num_context_variables,
+    intptr_t deopt_id)
+    : TemplateAllocation(source, deopt_id),
       num_context_variables_(num_context_variables) {
   // This instruction is not used in AOT for code size reasons.
   ASSERT(!CompilerState::Current().is_aot());
@@ -1019,7 +1020,7 @@
   const Code& stub = Code::ZoneHandle(
       compiler->zone(), StubCode::GetAllocationStubForTypedData(class_id()));
   compiler->GenerateStubCall(source(), stub, UntaggedPcDescriptors::kOther,
-                             locs());
+                             locs(), deopt_id());
 }
 
 bool StoreInstanceFieldInstr::IsUnboxedStore() const {
@@ -1131,7 +1132,8 @@
 }
 
 bool LoadStaticFieldInstr::AttributesEqual(Instruction* other) const {
-  ASSERT(IsFieldInitialized());
+  ASSERT(AllowsCSE());
+  ASSERT(!field().is_late() || calls_initializer());
   return field().ptr() == other->AsLoadStaticField()->field().ptr();
 }
 
@@ -1580,11 +1582,15 @@
 }
 
 void Instruction::RepairPushArgsInEnvironment() const {
+  // Some calls (e.g. closure calls) have more inputs than actual arguments.
+  // Those extra inputs will be consumed from the stack before the call.
+  const intptr_t after_args_input_count = env()->LazyDeoptPruneCount();
   PushArgumentsArray* push_arguments = GetPushArguments();
   ASSERT(push_arguments != nullptr);
   const intptr_t arg_count = ArgumentCount();
-  ASSERT(arg_count <= env()->Length());
-  const intptr_t env_base = env()->Length() - arg_count;
+  ASSERT((arg_count + after_args_input_count) <= env()->Length());
+  const intptr_t env_base =
+      env()->Length() - arg_count - after_args_input_count;
   for (intptr_t i = 0; i < arg_count; ++i) {
     env()->ValueAt(env_base + i)->BindToEnvironment(push_arguments->At(i));
   }
@@ -2226,14 +2232,18 @@
 
 Definition* DoubleToFloatInstr::Canonicalize(FlowGraph* flow_graph) {
 #ifdef DEBUG
-  // Must only be used in Float32 StoreIndexedInstr or FloatToDoubleInstr or
-  // Phis introduce by load forwarding.
+  // Must only be used in Float32 StoreIndexedInstr, FloatToDoubleInstr,
+  // Phis introduce by load forwarding, or MaterializeObject for
+  // eliminated Float32 array.
   ASSERT(env_use_list() == NULL);
   for (Value* use = input_use_list(); use != NULL; use = use->next_use()) {
     ASSERT(use->instruction()->IsPhi() ||
            use->instruction()->IsFloatToDouble() ||
            (use->instruction()->IsStoreIndexed() &&
             (use->instruction()->AsStoreIndexed()->class_id() ==
+             kTypedDataFloat32ArrayCid)) ||
+           (use->instruction()->IsMaterializeObject() &&
+            (use->instruction()->AsMaterializeObject()->cls().id() ==
              kTypedDataFloat32ArrayCid)));
   }
 #endif
@@ -2431,80 +2441,6 @@
   return op;
 }
 
-Definition* CheckedSmiOpInstr::Canonicalize(FlowGraph* flow_graph) {
-  if ((left()->Type()->ToCid() == kSmiCid) &&
-      (right()->Type()->ToCid() == kSmiCid)) {
-    Definition* replacement = NULL;
-    // Operations that can't deoptimize are specialized here: These include
-    // bit-wise operators and comparisons. Other arithmetic operations can
-    // overflow or divide by 0 and can't be specialized unless we have extra
-    // range information.
-    switch (op_kind()) {
-      case Token::kBIT_AND:
-        FALL_THROUGH;
-      case Token::kBIT_OR:
-        FALL_THROUGH;
-      case Token::kBIT_XOR:
-        replacement = new BinarySmiOpInstr(
-            op_kind(), new Value(left()->definition()),
-            new Value(right()->definition()), DeoptId::kNone);
-        FALL_THROUGH;
-      default:
-        break;
-    }
-    if (replacement != NULL) {
-      flow_graph->InsertBefore(this, replacement, env(), FlowGraph::kValue);
-      return replacement;
-    }
-  }
-  return this;
-}
-
-ComparisonInstr* CheckedSmiComparisonInstr::CopyWithNewOperands(Value* left,
-                                                                Value* right) {
-  UNREACHABLE();
-  return NULL;
-}
-
-Definition* CheckedSmiComparisonInstr::Canonicalize(FlowGraph* flow_graph) {
-  CompileType* left_type = left()->Type();
-  CompileType* right_type = right()->Type();
-  intptr_t op_cid = kIllegalCid;
-  SpeculativeMode speculative_mode = kGuardInputs;
-
-  if ((left_type->ToCid() == kSmiCid) && (right_type->ToCid() == kSmiCid)) {
-    op_cid = kSmiCid;
-  } else if (FlowGraphCompiler::SupportsUnboxedInt64() &&
-             // TODO(dartbug.com/30480): handle nullable types here
-             left_type->IsNullableInt() && !left_type->is_nullable() &&
-             right_type->IsNullableInt() && !right_type->is_nullable()) {
-    op_cid = kMintCid;
-    speculative_mode = kNotSpeculative;
-  }
-
-  if (op_cid != kIllegalCid) {
-    Definition* replacement = NULL;
-    if (Token::IsRelationalOperator(kind())) {
-      replacement = new RelationalOpInstr(
-          source(), kind(), left()->CopyWithType(), right()->CopyWithType(),
-          op_cid, DeoptId::kNone, speculative_mode);
-    } else if (Token::IsEqualityOperator(kind())) {
-      replacement = new EqualityCompareInstr(
-          source(), kind(), left()->CopyWithType(), right()->CopyWithType(),
-          op_cid, DeoptId::kNone, speculative_mode);
-    }
-    if (replacement != NULL) {
-      if (FLAG_trace_strong_mode_types && (op_cid == kMintCid)) {
-        THR_Print("[Strong mode] Optimization: replacing %s with %s\n",
-                  ToCString(), replacement->ToCString());
-      }
-      flow_graph->InsertBefore(this, replacement, env(), FlowGraph::kValue);
-      return replacement;
-    }
-  }
-  return this;
-}
-
 Definition* BinaryIntegerOpInstr::Canonicalize(FlowGraph* flow_graph) {
   // If both operands are constants evaluate this expression. Might
   // occur due to load forwarding after constant propagation pass
@@ -2768,7 +2704,7 @@
     case Slot::Kind::kClosure_instantiator_type_arguments:
     case Slot::Kind::kClosure_hash:
     case Slot::Kind::kClosureData_default_type_arguments:
-    case Slot::Kind::kClosureData_default_type_arguments_info:
+    case Slot::Kind::kClosureData_default_type_arguments_kind:
     case Slot::Kind::kCapturedVariable:
     case Slot::Kind::kDartField:
     case Slot::Kind::kFunction_data:
@@ -3664,6 +3600,30 @@
   return replacement;
 }
 
+Definition* EqualityCompareInstr::Canonicalize(FlowGraph* flow_graph) {
+  if (is_null_aware()) {
+    ASSERT(operation_cid() == kMintCid);
+    // Select more efficient instructions based on operand types.
+    CompileType* left_type = left()->Type();
+    CompileType* right_type = right()->Type();
+    if (left_type->IsNull() || left_type->IsNullableSmi() ||
+        right_type->IsNull() || right_type->IsNullableSmi()) {
+      auto replacement = new StrictCompareInstr(
+          source(),
+          (kind() == Token::kEQ) ? Token::kEQ_STRICT : Token::kNE_STRICT,
+          left()->CopyWithType(), right()->CopyWithType(),
+          /*needs_number_check=*/false, DeoptId::kNone);
+      flow_graph->InsertBefore(this, replacement, env(), FlowGraph::kValue);
+      return replacement;
+    } else {
+      if (!left_type->is_nullable() && !right_type->is_nullable()) {
+        set_null_aware(false);
+      }
+    }
+  }
+  return this;
+}
+
 Instruction* CheckClassInstr::Canonicalize(FlowGraph* flow_graph) {
   const intptr_t value_cid = value()->Type()->ToCid();
   if (value_cid == kDynamicCid) {
@@ -4430,9 +4390,6 @@
     UNREACHABLE();
   }
 
-  // Instruction inputs are popped from the stack at this point,
-  // so deoptimization environment has to be adjusted.
-  // This adjustment is done in FlowGraph::AttachEnvironment.
   compiler->GenerateStubCall(source(), stub,
                              /*kind=*/UntaggedPcDescriptors::kOther, locs(),
                              deopt_id());
@@ -4504,23 +4461,6 @@
   return locs;
 }
 
-void AssertBooleanInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  // Check that the type of the value is allowed in conditional context.
-  ASSERT(locs()->always_calls());
-
-  auto object_store = compiler->isolate_group()->object_store();
-  const auto& assert_boolean_stub =
-      Code::ZoneHandle(compiler->zone(), object_store->assert_boolean_stub());
-
-  compiler::Label done;
-  __ CompareObject(AssertBooleanABI::kObjectReg, Object::null_instance());
-  __ BranchIf(NOT_EQUAL, &done);
-  compiler->GenerateStubCall(source(), assert_boolean_stub,
-                             /*kind=*/UntaggedPcDescriptors::kOther, locs(),
-                             deopt_id());
-  __ Bind(&done);
-}
-
 LocationSummary* PhiInstr::MakeLocationSummary(Zone* zone,
                                                bool optimizing) const {
   UNREACHABLE();
@@ -5059,16 +4999,26 @@
   return dispatch_table_call;
 }
 
+LocationSummary* DispatchTableCallInstr::MakeLocationSummary(Zone* zone,
+                                                             bool opt) const {
+  const intptr_t kNumInputs = 1;
+  const intptr_t kNumTemps = 0;
+  LocationSummary* summary = new (zone)
+      LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
+  summary->set_in(
+      0, Location::RegisterLocation(DispatchTableNullErrorABI::kClassIdReg));
+  return MakeCallSummary(zone, this, summary);
+}
+
 void DispatchTableCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  ASSERT(locs()->in(0).reg() == DispatchTableNullErrorABI::kClassIdReg);
   Array& arguments_descriptor = Array::ZoneHandle();
   if (selector()->requires_args_descriptor) {
     ArgumentsInfo args_info(type_args_len(), ArgumentCount(), ArgumentsSize(),
                             argument_names());
     arguments_descriptor = args_info.ToArgumentsDescriptor();
   }
-  const Register cid_reg = locs()->in(0).reg();
-  compiler->EmitDispatchTableCall(cid_reg, selector()->offset,
-                                  arguments_descriptor);
+  compiler->EmitDispatchTableCall(selector()->offset, arguments_descriptor);
   compiler->EmitCallsiteMetadata(source(), DeoptId::kNone,
                                  UntaggedPcDescriptors::kOther, locs());
   if (selector()->called_on_null && !selector()->on_null_interface) {
@@ -5413,20 +5363,93 @@
 }
 
 void AssertSubtypeInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-#if defined(TARGET_ARCH_IA32)
-  __ PushRegister(AssertSubtypeABI::kInstantiatorTypeArgumentsReg);
-  __ PushRegister(AssertSubtypeABI::kFunctionTypeArgumentsReg);
-  __ PushRegister(AssertSubtypeABI::kSubTypeReg);
-  __ PushRegister(AssertSubtypeABI::kSuperTypeReg);
-  __ PushRegister(AssertSubtypeABI::kDstNameReg);
-  compiler->GenerateRuntimeCall(source(), deopt_id(), kSubtypeCheckRuntimeEntry,
-                                5, locs());
-
-  __ Drop(5);
-#else
   compiler->GenerateStubCall(source(), StubCode::AssertSubtype(),
-                             UntaggedPcDescriptors::kOther, locs());
-#endif
+                             UntaggedPcDescriptors::kOther, locs(), deopt_id());
+}
+
+LocationSummary* InstantiateTypeInstr::MakeLocationSummary(Zone* zone,
+                                                           bool opt) const {
+  const intptr_t kNumInputs = 2;
+  const intptr_t kNumTemps = 0;
+  LocationSummary* locs = new (zone)
+      LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
+  locs->set_in(0, Location::RegisterLocation(
+                      InstantiateTypeABI::kInstantiatorTypeArgumentsReg));
+  locs->set_in(1, Location::RegisterLocation(
+                      InstantiateTypeABI::kFunctionTypeArgumentsReg));
+  locs->set_out(0,
+                Location::RegisterLocation(InstantiateTypeABI::kResultTypeReg));
+  return locs;
+}
+
+void InstantiateTypeInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  __ LoadObject(InstantiateTypeABI::kTypeReg, type());
+  compiler->GenerateStubCall(source(), StubCode::InstantiateType(),
+                             UntaggedPcDescriptors::kOther, locs(), deopt_id(),
+                             env());
+}
+
+LocationSummary* InstantiateTypeArgumentsInstr::MakeLocationSummary(
+    Zone* zone,
+    bool opt) const {
+  const intptr_t kNumInputs = 3;
+  const intptr_t kNumTemps = 0;
+  LocationSummary* locs = new (zone)
+      LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
+  locs->set_in(0, Location::RegisterLocation(
+                      InstantiationABI::kInstantiatorTypeArgumentsReg));
+  locs->set_in(1, Location::RegisterLocation(
+                      InstantiationABI::kFunctionTypeArgumentsReg));
+  locs->set_in(2, Location::RegisterLocation(
+                      InstantiationABI::kUninstantiatedTypeArgumentsReg));
+  locs->set_out(
+      0, Location::RegisterLocation(InstantiationABI::kResultTypeArgumentsReg));
+  return locs;
+}
+
+void InstantiateTypeArgumentsInstr::EmitNativeCode(
+    FlowGraphCompiler* compiler) {
+  // We should never try and instantiate a TAV known at compile time to be null,
+  // so we can use a null value below for the dynamic case.
+  ASSERT(!type_arguments()->BindsToConstant() ||
+         !type_arguments()->BoundConstant().IsNull());
+  const auto& type_args =
+      type_arguments()->BindsToConstant()
+          ? TypeArguments::Cast(type_arguments()->BoundConstant())
+          : Object::null_type_arguments();
+  const intptr_t len = type_args.Length();
+  const bool can_function_type_args_be_null =
+      function_type_arguments()->CanBe(Object::null_object());
+
+  compiler::Label type_arguments_instantiated;
+  if (type_args.IsNull()) {
+    // Currently we only create dynamic InstantiateTypeArguments instructions
+    // in cases where we know the type argument is uninstantiated at runtime,
+    // so there are no extra checks needed to call the stub successfully.
+  } else if (type_args.IsRawWhenInstantiatedFromRaw(len) &&
+             can_function_type_args_be_null) {
+    // If both the instantiator and function type arguments are null and if the
+    // type argument vector instantiated from null becomes a vector of dynamic,
+    // then use null as the type arguments.
+    compiler::Label non_null_type_args;
+    __ LoadObject(InstantiationABI::kResultTypeArgumentsReg,
+                  Object::null_object());
+    __ CompareRegisters(InstantiationABI::kInstantiatorTypeArgumentsReg,
+                        InstantiationABI::kResultTypeArgumentsReg);
+    if (!function_type_arguments()->BindsToConstant()) {
+      __ BranchIf(NOT_EQUAL, &non_null_type_args,
+                  compiler::AssemblerBase::kNearJump);
+      __ CompareRegisters(InstantiationABI::kFunctionTypeArgumentsReg,
+                          InstantiationABI::kResultTypeArgumentsReg);
+    }
+    __ BranchIf(EQUAL, &type_arguments_instantiated,
+                compiler::AssemblerBase::kNearJump);
+    __ Bind(&non_null_type_args);
+  }
+
+  compiler->GenerateStubCall(source(), GetStub(), UntaggedPcDescriptors::kOther,
+                             locs(), deopt_id());
+  __ Bind(&type_arguments_instantiated);
 }
 
 LocationSummary* DeoptimizeInstr::MakeLocationSummary(Zone* zone,
@@ -5516,10 +5539,11 @@
     if (index_cid != kSmiCid) {
       __ BranchIfNotSmi(index, slow_path->entry_label());
     }
+    __ CompareObjectRegisters(index, length);
   } else {
     ASSERT(representation() == kUnboxedInt64);
+    __ CompareRegisters(index, length);
   }
-  __ CompareRegisters(index, length);
   __ BranchIf(UNSIGNED_GREATER_EQUAL, slow_path->entry_label());
 }
 
@@ -5644,9 +5668,11 @@
 Environment* Environment::From(Zone* zone,
                                const GrowableArray<Definition*>& definitions,
                                intptr_t fixed_parameter_count,
+                               intptr_t lazy_deopt_pruning_count,
                                const ParsedFunction& parsed_function) {
-  Environment* env = new (zone) Environment(
-      definitions.length(), fixed_parameter_count, parsed_function, NULL);
+  Environment* env =
+      new (zone) Environment(definitions.length(), fixed_parameter_count,
+                             lazy_deopt_pruning_count, parsed_function, NULL);
   for (intptr_t i = 0; i < definitions.length(); ++i) {
     env->values_.Add(new (zone) Value(definitions[i]));
   }
@@ -5659,10 +5685,10 @@
 
 Environment* Environment::DeepCopy(Zone* zone, intptr_t length) const {
   ASSERT(length <= values_.length());
-  Environment* copy =
-      new (zone) Environment(length, fixed_parameter_count_, parsed_function_,
-                             (outer_ == NULL) ? NULL : outer_->DeepCopy(zone));
-  copy->deopt_id_ = this->deopt_id_;
+  Environment* copy = new (zone) Environment(
+      length, fixed_parameter_count_, LazyDeoptPruneCount(), parsed_function_,
+      (outer_ == NULL) ? NULL : outer_->DeepCopy(zone));
+  copy->SetDeoptId(DeoptIdBits::decode(bitfield_));
   if (locations_ != NULL) {
     Location* new_locations = zone->Alloc<Location>(length);
     copy->set_locations(new_locations);
@@ -5699,7 +5725,9 @@
     it.CurrentValue()->RemoveFromUseList();
   }
 
-  Environment* copy = DeepCopy(zone, values_.length() - argc);
+  Environment* copy =
+      DeepCopy(zone, values_.length() - argc - LazyDeoptPruneCount());
+  copy->SetLazyDeoptPruneCount(0);
   for (intptr_t i = 0; i < argc; i++) {
     copy->values_.Add(new (zone) Value(dead));
   }
@@ -5721,11 +5749,13 @@
   ASSERT(this != NULL);
   ASSERT(instr->env()->outer() == NULL);
   intptr_t argument_count = instr->env()->fixed_parameter_count();
-  Environment* copy = DeepCopy(zone, values_.length() - argument_count);
-  copy->deopt_id_ = outer_deopt_id;
-  instr->env()->outer_ = copy;
+  Environment* outer =
+      DeepCopy(zone, values_.length() - argument_count - LazyDeoptPruneCount());
+  outer->SetDeoptId(outer_deopt_id);
+  outer->SetLazyDeoptPruneCount(0);
+  instr->env()->outer_ = outer;
   intptr_t use_index = instr->env()->Length();  // Start index after inner.
-  for (Environment::DeepIterator it(copy); !it.Done(); it.Advance()) {
+  for (Environment::DeepIterator it(outer); !it.Done(); it.Advance()) {
     Value* value = it.CurrentValue();
     value->set_instruction(instr);
     value->set_use_index(use_index++);
@@ -5742,7 +5772,8 @@
 ComparisonInstr* EqualityCompareInstr::CopyWithNewOperands(Value* new_left,
                                                            Value* new_right) {
   return new EqualityCompareInstr(source(), kind(), new_left, new_right,
-                                  operation_cid(), deopt_id());
+                                  operation_cid(), deopt_id(), is_null_aware(),
+                                  speculative_mode_);
 }
 
 ComparisonInstr* RelationalOpInstr::CopyWithNewOperands(Value* new_left,
@@ -6139,6 +6170,8 @@
     case MethodRecognizer::kMathAsin:
     case MethodRecognizer::kMathSin:
     case MethodRecognizer::kMathCos:
+    case MethodRecognizer::kMathExp:
+    case MethodRecognizer::kMathLog:
       return 1;
     case MethodRecognizer::kDoubleMod:
     case MethodRecognizer::kMathDoublePow:
@@ -6178,6 +6211,10 @@
       return kLibcAtanRuntimeEntry;
     case MethodRecognizer::kMathAtan2:
       return kLibcAtan2RuntimeEntry;
+    case MethodRecognizer::kMathExp:
+      return kLibcExpRuntimeEntry;
+    case MethodRecognizer::kMathLog:
+      return kLibcLogRuntimeEntry;
     default:
       UNREACHABLE();
   }
@@ -6522,6 +6559,8 @@
 }
 
 void EnterHandleScopeInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  ASSERT(kEnterHandleScopeRuntimeEntry.is_leaf());
+
   if (kind_ == Kind::kGetTopHandleScope) {
     __ LoadMemoryValue(CallingConventions::kReturnReg, THR,
                        compiler::target::Thread::api_top_scope_offset());
@@ -6548,6 +6587,8 @@
 }
 
 void ExitHandleScopeInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  ASSERT(kEnterHandleScopeRuntimeEntry.is_leaf());
+
   Location arg_loc = FirstArgumentLocation();
   __ EnterCFrame(arg_loc.IsRegister() ? 0 : compiler::target::kWordSize);
   NoTemporaryAllocator no_temp;
@@ -6585,6 +6626,8 @@
 }
 
 void AllocateHandleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  ASSERT(kEnterHandleScopeRuntimeEntry.is_leaf());
+
   Location arg_loc = FirstArgumentLocation();
   __ EnterCFrame(arg_loc.IsRegister() ? 0 : compiler::target::kWordSize);
   if (arg_loc.IsStackSlot()) {
diff --git a/runtime/vm/compiler/backend/il.h b/runtime/vm/compiler/backend/il.h
index a09d32c..fc05085 100644
--- a/runtime/vm/compiler/backend/il.h
+++ b/runtime/vm/compiler/backend/il.h
@@ -49,7 +49,6 @@
 class Environment;
 class FlowGraph;
 class FlowGraphCompiler;
-class FlowGraphSerializer;
 class FlowGraphVisitor;
 class ForwardInstructionIterator;
 class Instruction;
@@ -59,8 +58,6 @@
 class Range;
 class RangeAnalysis;
 class RangeBoundary;
-class SExpList;
-class SExpression;
 class SuccessorsIterable;
 class TypeUsageInfo;
 class UnboxIntegerInstr;
@@ -150,8 +147,6 @@
   void PrintTo(BaseTextBuffer* f) const;
 #endif  // defined(INCLUDE_IL_PRINTER)
 
-  SExpression* ToSExpression(FlowGraphSerializer* s) const;
-
   const char* ToCString() const;
 
   bool IsSmiValue() { return Type()->ToCid() == kSmiCid; }
@@ -369,7 +364,7 @@
     // The instruction is guaranteed to not trigger GC on a non-exceptional
     // path. If the conditions depend on parameters of the instruction, do not
     // use this attribute but overload CanTriggerGC() instead.
-    kNoGC = 1
+    kNoGC = 1,
   };
 };
 
@@ -397,7 +392,7 @@
   M(NativeReturn, kNoGC)                                                       \
   M(Throw, kNoGC)                                                              \
   M(ReThrow, kNoGC)                                                            \
-  M(Stop, _)                                                                   \
+  M(Stop, kNoGC)                                                               \
   M(Goto, kNoGC)                                                               \
   M(IndirectGoto, kNoGC)                                                       \
   M(Branch, kNoGC)                                                             \
@@ -407,10 +402,10 @@
   M(SpecialParameter, kNoGC)                                                   \
   M(ClosureCall, _)                                                            \
   M(FfiCall, _)                                                                \
-  M(EnterHandleScope, _)                                                       \
-  M(ExitHandleScope, _)                                                        \
-  M(AllocateHandle, _)                                                         \
-  M(RawStoreField, _)                                                          \
+  M(EnterHandleScope, kNoGC)                                                   \
+  M(ExitHandleScope, kNoGC)                                                    \
+  M(AllocateHandle, kNoGC)                                                     \
+  M(RawStoreField, kNoGC)                                                      \
   M(InstanceCall, _)                                                           \
   M(PolymorphicInstanceCall, _)                                                \
   M(DispatchTableCall, _)                                                      \
@@ -445,8 +440,6 @@
   M(AllocateUninitializedContext, _)                                           \
   M(CloneContext, _)                                                           \
   M(BinarySmiOp, kNoGC)                                                        \
-  M(CheckedSmiComparison, _)                                                   \
-  M(CheckedSmiOp, _)                                                           \
   M(BinaryInt32Op, kNoGC)                                                      \
   M(UnarySmiOp, kNoGC)                                                         \
   M(UnaryDoubleOp, kNoGC)                                                      \
@@ -475,19 +468,19 @@
   M(Unbox, kNoGC)                                                              \
   M(BoxInt64, _)                                                               \
   M(UnboxInt64, kNoGC)                                                         \
-  M(CaseInsensitiveCompare, _)                                                 \
+  M(CaseInsensitiveCompare, kNoGC)                                             \
   M(BinaryInt64Op, kNoGC)                                                      \
   M(ShiftInt64Op, kNoGC)                                                       \
   M(SpeculativeShiftInt64Op, kNoGC)                                            \
   M(UnaryInt64Op, kNoGC)                                                       \
   M(CheckArrayBound, kNoGC)                                                    \
   M(GenericCheckBound, kNoGC)                                                  \
-  M(Constraint, _)                                                             \
+  M(Constraint, kNoGC)                                                         \
   M(StringToCharCode, kNoGC)                                                   \
   M(OneByteStringFromCharCode, kNoGC)                                          \
   M(StringInterpolate, _)                                                      \
   M(Utf8Scan, kNoGC)                                                           \
-  M(InvokeMathCFunction, _)                                                    \
+  M(InvokeMathCFunction, kNoGC)                                                \
   M(TruncDivMod, kNoGC)                                                        \
   /*We could be more precise about when these 2 instructions can trigger GC.*/ \
   M(GuardFieldClass, _)                                                        \
@@ -506,9 +499,9 @@
   M(UnboxUint32, kNoGC)                                                        \
   M(BoxInt32, _)                                                               \
   M(UnboxInt32, kNoGC)                                                         \
-  M(BoxUint8, _)                                                               \
-  M(IntConverter, _)                                                           \
-  M(BitCast, _)                                                                \
+  M(BoxUint8, kNoGC)                                                           \
+  M(IntConverter, kNoGC)                                                       \
+  M(BitCast, kNoGC)                                                            \
   M(Deoptimize, kNoGC)                                                         \
   M(SimdOp, kNoGC)
 
@@ -569,17 +562,6 @@
 #define PRINT_OPERANDS_TO_SUPPORT
 #endif  // defined(INCLUDE_IL_PRINTER)
 
-#define TO_S_EXPRESSION_SUPPORT                                                \
-  virtual SExpression* ToSExpression(FlowGraphSerializer* s) const;
-
-#define ADD_OPERANDS_TO_S_EXPRESSION_SUPPORT                                   \
-  virtual void AddOperandsToSExpression(SExpList* sexp,                        \
-                                        FlowGraphSerializer* s) const;
-
-#define ADD_EXTRA_INFO_TO_S_EXPRESSION_SUPPORT                                 \
-  virtual void AddExtraInfoToSExpression(SExpList* sexp,                       \
-                                         FlowGraphSerializer* s) const;
-
 // Together with CidRange, this represents a mapping from a range of class-ids
 // to a method for a given selector (method name).  Also can contain an
 // indication of how frequently a given method has been called at a call site.
@@ -791,10 +773,6 @@
   explicit Instruction(const InstructionSource& source,
                        intptr_t deopt_id = DeoptId::kNone)
       : deopt_id_(deopt_id),
-        previous_(NULL),
-        next_(NULL),
-        env_(NULL),
-        locs_(NULL),
         inlining_id_(source.inlining_id) {}
 
   explicit Instruction(intptr_t deopt_id = DeoptId::kNone)
@@ -807,7 +785,8 @@
   virtual intptr_t statistics_tag() const { return tag(); }
 
   intptr_t deopt_id() const {
-    ASSERT(ComputeCanDeoptimize() || CanBecomeDeoptimizationTarget() ||
+    ASSERT(ComputeCanDeoptimize() || ComputeCanDeoptimizeAfterCall() ||
+           CanBecomeDeoptimizationTarget() || MayThrow() ||
            CompilerState::Current().is_aot());
     return GetDeoptId();
   }
@@ -867,9 +846,19 @@
   // the type or the range of input operands during compilation.
   virtual bool ComputeCanDeoptimize() const = 0;
 
+  virtual bool ComputeCanDeoptimizeAfterCall() const {
+    // TODO(dartbug.com/45213): Incrementally migrate IR instructions from using
+    // [ComputeCanDeoptimze] to either [ComputeCanDeoptimizeAfterCall] if they
+    // can only lazy deoptimize.
+    return false;
+  }
+
   // Once we removed the deopt environment, we assume that this
   // instruction can't deoptimize.
-  bool CanDeoptimize() const { return env() != NULL && ComputeCanDeoptimize(); }
+  bool CanDeoptimize() const {
+    return env() != nullptr &&
+           (ComputeCanDeoptimize() || ComputeCanDeoptimizeAfterCall());
+  }
 
   // Visiting support.
   virtual void Accept(FlowGraphVisitor* visitor) = 0;
@@ -932,11 +921,6 @@
   const char* ToCString() const;
   PRINT_TO_SUPPORT
   PRINT_OPERANDS_TO_SUPPORT
-  virtual SExpression* ToSExpression(FlowGraphSerializer* s) const;
-  virtual void AddOperandsToSExpression(SExpList* sexp,
-                                        FlowGraphSerializer* s) const;
-  virtual void AddExtraInfoToSExpression(SExpList* sexp,
-                                         FlowGraphSerializer* s) const;
 
 #define DECLARE_INSTRUCTION_TYPE_CHECK(Name, Type)                             \
   bool Is##Name() const { return (As##Name() != nullptr); }                    \
@@ -993,6 +977,8 @@
   void RemoveEnvironment();
   void ReplaceInEnvironment(Definition* current, Definition* replacement);
 
+  virtual intptr_t NumberOfInputsConsumedBeforeCall() const { return 0; }
+
   // Different compiler passes can assign pass specific ids to the instruction.
   // Only one id can be stored at a time.
   intptr_t GetPassSpecificId(CompilerPass::Id pass) const {
@@ -1110,8 +1096,8 @@
   virtual void InheritDeoptTarget(Zone* zone, Instruction* other);
 
   bool NeedsEnvironment() const {
-    return ComputeCanDeoptimize() || CanBecomeDeoptimizationTarget() ||
-           MayThrow();
+    return ComputeCanDeoptimize() || ComputeCanDeoptimizeAfterCall() ||
+           CanBecomeDeoptimizationTarget() || MayThrow();
   }
 
   virtual bool CanBecomeDeoptimizationTarget() const { return false; }
@@ -1200,12 +1186,12 @@
                   "Pass Id does not fit into the bit field");
   };
 
-  intptr_t deopt_id_;
+  intptr_t deopt_id_ = DeoptId::kNone;
   intptr_t pass_specific_id_ = PassSpecificId::kNoId;
-  Instruction* previous_;
-  Instruction* next_;
-  Environment* env_;
-  LocationSummary* locs_;
+  Instruction* previous_ = nullptr;
+  Instruction* next_ = nullptr;
+  Environment* env_ = nullptr;
+  LocationSummary* locs_ = nullptr;
   intptr_t inlining_id_;
 
   DISALLOW_COPY_AND_ASSIGN(Instruction);
@@ -1519,9 +1505,6 @@
 
   DEFINE_INSTRUCTION_TYPE_CHECK(BlockEntry)
 
-  TO_S_EXPRESSION_SUPPORT
-  ADD_OPERANDS_TO_S_EXPRESSION_SUPPORT
-  ADD_EXTRA_INFO_TO_S_EXPRESSION_SUPPORT
 
  protected:
   BlockEntryInstr(intptr_t block_id,
@@ -1822,7 +1805,6 @@
   virtual bool HasUnknownSideEffects() const { return false; }
 
   PRINT_TO_SUPPORT
-  ADD_OPERANDS_TO_S_EXPRESSION_SUPPORT
 
  private:
   // Classes that have access to predecessors_ when inlining.
@@ -2269,7 +2251,6 @@
 
   PRINT_OPERANDS_TO_SUPPORT
   PRINT_TO_SUPPORT
-  TO_S_EXPRESSION_SUPPORT
 
   bool UpdateType(CompileType new_type) {
     if (type_ == nullptr) {
@@ -2382,7 +2363,6 @@
  protected:
   friend class RangeAnalysis;
   friend class Value;
-  friend class FlowGraphSerializer;  // To access type_ directly.
 
   Range* range_ = nullptr;
 
@@ -2617,7 +2597,6 @@
   virtual bool MayThrow() const { return false; }
 
   PRINT_OPERANDS_TO_SUPPORT
-  ADD_OPERANDS_TO_S_EXPRESSION_SUPPORT
 
  private:
   virtual void RawSetInputAt(intptr_t i, Value* value) { UNREACHABLE(); }
@@ -2723,7 +2702,6 @@
   intptr_t offset() const { return offset_; }
 
   PRINT_OPERANDS_TO_SUPPORT
-  ADD_EXTRA_INFO_TO_S_EXPRESSION_SUPPORT
 
  private:
   const intptr_t offset_;
@@ -2774,7 +2752,6 @@
   intptr_t offset() const { return offset_; }
 
   PRINT_OPERANDS_TO_SUPPORT
-  ADD_EXTRA_INFO_TO_S_EXPRESSION_SUPPORT
 
  private:
   const intptr_t offset_;
@@ -2906,7 +2883,6 @@
   virtual bool ComputeCanDeoptimize() const { return false; }
 
   PRINT_OPERANDS_TO_SUPPORT
-  ADD_OPERANDS_TO_S_EXPRESSION_SUPPORT
 
  private:
   const Code& code_;
@@ -3188,7 +3164,6 @@
   }
 
   PRINT_TO_SUPPORT
-  ADD_OPERANDS_TO_S_EXPRESSION_SUPPORT
 
  private:
   BlockEntryInstr* block_;
@@ -3299,7 +3274,6 @@
            (operation_cid() == other_comparison->operation_cid());
   }
 
-  ADD_OPERANDS_TO_S_EXPRESSION_SUPPORT
 
   DEFINE_INSTRUCTION_TYPE_CHECK(Comparison)
 
@@ -3438,7 +3412,6 @@
   virtual BlockEntryInstr* SuccessorAt(intptr_t index) const;
 
   PRINT_TO_SUPPORT
-  ADD_OPERANDS_TO_S_EXPRESSION_SUPPORT
 
  private:
   virtual void RawSetInputAt(intptr_t i, Value* value) {
@@ -3592,7 +3565,6 @@
                           Register tmp = kNoRegister);
 
   PRINT_OPERANDS_TO_SUPPORT
-  ADD_OPERANDS_TO_S_EXPRESSION_SUPPORT
 
  private:
   const Object& value_;
@@ -3663,9 +3635,13 @@
 
   virtual TokenPosition token_pos() const { return token_pos_; }
 
-  virtual bool ComputeCanDeoptimize() const {
+  virtual bool ComputeCanDeoptimize() const { return false; }
+  virtual bool ComputeCanDeoptimizeAfterCall() const {
     return !CompilerState::Current().is_aot();
   }
+  virtual intptr_t NumberOfInputsConsumedBeforeCall() const {
+    return InputCount();
+  }
 
   virtual bool CanBecomeDeoptimizationTarget() const { return true; }
 
@@ -3701,6 +3677,7 @@
     kDstTypePos = 1,
     kInstantiatorTAVPos = 2,
     kFunctionTAVPos = 3,
+    kNumInputs = 4,
   };
 
   AssertAssignableInstr(const InstructionSource& source,
@@ -3738,9 +3715,21 @@
   virtual TokenPosition token_pos() const { return token_pos_; }
   const String& dst_name() const { return dst_name_; }
 
-  virtual bool ComputeCanDeoptimize() const {
+  virtual bool ComputeCanDeoptimize() const { return false; }
+  virtual bool ComputeCanDeoptimizeAfterCall() const {
     return !CompilerState::Current().is_aot();
   }
+  virtual intptr_t NumberOfInputsConsumedBeforeCall() const {
+#if !defined(TARGET_ARCH_IA32)
+    return InputCount();
+#else
+    // The ia32 implementation calls the stub by pushing the input registers
+    // in the same order onto the stack thereby making the deopt-env correct.
+    // (Due to lack of registers we cannot use all-argument calling convention
+    // as in other architectures.)
+    return 0;
+#endif
+  }
 
   virtual bool CanBecomeDeoptimizationTarget() const {
     // AssertAssignable instructions that are specialized by the optimizer
@@ -3755,7 +3744,6 @@
   virtual Value* RedefinedValue() const;
 
   PRINT_OPERANDS_TO_SUPPORT
-  ADD_EXTRA_INFO_TO_S_EXPRESSION_SUPPORT
 
  private:
   const TokenPosition token_pos_;
@@ -3780,9 +3768,13 @@
   virtual TokenPosition token_pos() const { return token_pos_; }
   Value* value() const { return inputs_[0]; }
 
-  virtual bool ComputeCanDeoptimize() const {
+  virtual bool ComputeCanDeoptimize() const { return false; }
+  virtual bool ComputeCanDeoptimizeAfterCall() const {
     return !CompilerState::Current().is_aot();
   }
+  virtual intptr_t NumberOfInputsConsumedBeforeCall() const {
+    return InputCount();
+  }
 
   virtual Definition* Canonicalize(FlowGraph* flow_graph);
 
@@ -3845,7 +3837,6 @@
   const char* ToCString() const;
 
   PRINT_OPERANDS_TO_SUPPORT
-  ADD_OPERANDS_TO_S_EXPRESSION_SUPPORT
 
  private:
   const SpecialParameterKind kind_;
@@ -3907,6 +3898,13 @@
 
   virtual intptr_t InputCount() const { return inputs_->length(); }
   virtual Value* InputAt(intptr_t i) const { return inputs_->At(i); }
+  virtual bool ComputeCanDeoptimize() const { return false; }
+  virtual bool ComputeCanDeoptimizeAfterCall() const {
+    return !CompilerState::Current().is_aot();
+  }
+  virtual intptr_t NumberOfInputsConsumedBeforeCall() const {
+    return kExtraInputs;
+  }
 
   intptr_t FirstArgIndex() const { return type_args_len_ > 0 ? 1 : 0; }
   Value* Receiver() const { return this->ArgumentValueAt(FirstArgIndex()); }
@@ -3955,7 +3953,6 @@
         ArgumentsSizeWithoutTypeArgs(), argument_names());
   }
 
-  ADD_EXTRA_INFO_TO_S_EXPRESSION_SUPPORT
 
  private:
   virtual void RawSetInputAt(intptr_t i, Value* value) {
@@ -3991,16 +3988,11 @@
   // TODO(kmillikin): implement exact call counts for closure calls.
   virtual intptr_t CallCount() const { return 1; }
 
-  virtual bool ComputeCanDeoptimize() const {
-    return !CompilerState::Current().is_aot();
-  }
-
   virtual bool HasUnknownSideEffects() const { return true; }
 
   Code::EntryKind entry_kind() const { return entry_kind_; }
 
   PRINT_OPERANDS_TO_SUPPORT
-  ADD_EXTRA_INFO_TO_S_EXPRESSION_SUPPORT
 
  private:
   const Code::EntryKind entry_kind_;
@@ -4068,10 +4060,6 @@
 
   virtual CompileType ComputeType() const;
 
-  virtual bool ComputeCanDeoptimize() const {
-    return !CompilerState::Current().is_aot();
-  }
-
   virtual bool CanBecomeDeoptimizationTarget() const {
     // Instance calls that are specialized by the optimizer need a
     // deoptimization descriptor before the call.
@@ -4098,8 +4086,6 @@
   Code::EntryKind entry_kind() const { return entry_kind_; }
   void set_entry_kind(Code::EntryKind value) { entry_kind_ = value; }
 
-  ADD_OPERANDS_TO_S_EXPRESSION_SUPPORT
-  ADD_EXTRA_INFO_TO_S_EXPRESSION_SUPPORT
   DEFINE_INSTRUCTION_TYPE_CHECK(InstanceCallBase);
 
   bool receiver_is_not_smi() const { return receiver_is_not_smi_; }
@@ -4215,7 +4201,6 @@
   virtual Definition* Canonicalize(FlowGraph* flow_graph);
 
   PRINT_OPERANDS_TO_SUPPORT
-  ADD_EXTRA_INFO_TO_S_EXPRESSION_SUPPORT
 
   bool MatchesCoreName(const String& name);
 
@@ -4290,7 +4275,6 @@
   static TypePtr ComputeRuntimeType(const CallTargets& targets);
 
   PRINT_OPERANDS_TO_SUPPORT
-  ADD_EXTRA_INFO_TO_S_EXPRESSION_SUPPORT
 
  private:
   PolymorphicInstanceCallInstr(const InstructionSource& source,
@@ -4369,8 +4353,6 @@
 
   virtual CompileType ComputeType() const;
 
-  virtual bool ComputeCanDeoptimize() const { return false; }
-
   virtual Definition* Canonicalize(FlowGraph* flow_graph);
 
   virtual bool CanBecomeDeoptimizationTarget() const { return false; }
@@ -4429,8 +4411,7 @@
 
   bool AttributesEqual(Instruction* other) const;
 
-  PRINT_OPERANDS_TO_SUPPORT
-  ADD_EXTRA_INFO_TO_S_EXPRESSION_SUPPORT;
+  PRINT_OPERANDS_TO_SUPPORT;
 
  private:
   Condition EmitComparisonCodeRegConstant(FlowGraphCompiler* compiler,
@@ -4535,8 +4516,10 @@
                        Value* right,
                        intptr_t cid,
                        intptr_t deopt_id,
+                       bool null_aware = false,
                        SpeculativeMode speculative_mode = kGuardInputs)
       : TemplateComparison(source, kind, deopt_id),
+        null_aware_(null_aware),
         speculative_mode_(speculative_mode) {
     ASSERT(Token::IsEqualityOperator(kind));
     SetInputAt(0, left);
@@ -4552,8 +4535,12 @@
 
   virtual bool ComputeCanDeoptimize() const { return false; }
 
+  bool is_null_aware() const { return null_aware_; }
+  void set_null_aware(bool value) { null_aware_ = value; }
+
   virtual Representation RequiredInputRepresentation(intptr_t idx) const {
     ASSERT((idx == 0) || (idx == 1));
+    if (is_null_aware()) return kTagged;
     if (operation_cid() == kDoubleCid) return kUnboxedDouble;
     if (operation_cid() == kMintCid) return kUnboxedInt64;
     return kTagged;
@@ -4565,12 +4552,16 @@
 
   virtual bool AttributesEqual(Instruction* other) const {
     return ComparisonInstr::AttributesEqual(other) &&
+           (null_aware_ == other->AsEqualityCompare()->null_aware_) &&
            (speculative_mode_ == other->AsEqualityCompare()->speculative_mode_);
   }
 
+  virtual Definition* Canonicalize(FlowGraph* flow_graph);
+
   PRINT_OPERANDS_TO_SUPPORT
 
  private:
+  bool null_aware_;
   const SpeculativeMode speculative_mode_;
   DISALLOW_COPY_AND_ASSIGN(EqualityCompareInstr);
 };
@@ -4863,8 +4854,6 @@
   const class BinaryFeedback& BinaryFeedback();
 
   PRINT_OPERANDS_TO_SUPPORT
-  ADD_OPERANDS_TO_S_EXPRESSION_SUPPORT
-  ADD_EXTRA_INFO_TO_S_EXPRESSION_SUPPORT
 
  private:
   const ICData* ic_data_;
@@ -4911,7 +4900,6 @@
   virtual TokenPosition token_pos() const { return token_pos_; }
 
   PRINT_OPERANDS_TO_SUPPORT
-  ADD_OPERANDS_TO_S_EXPRESSION_SUPPORT
 
  private:
   const LocalVariable& local_;
@@ -5043,7 +5031,6 @@
   virtual TokenPosition token_pos() const { return token_pos_; }
 
   PRINT_OPERANDS_TO_SUPPORT
-  ADD_OPERANDS_TO_S_EXPRESSION_SUPPORT
 
  private:
   const LocalVariable& local_;
@@ -5093,8 +5080,6 @@
   void SetupNative();
 
   PRINT_OPERANDS_TO_SUPPORT
-  ADD_OPERANDS_TO_S_EXPRESSION_SUPPORT
-  ADD_EXTRA_INFO_TO_S_EXPRESSION_SUPPORT
 
  private:
   void set_native_c_function(NativeFunction value) {
@@ -5287,7 +5272,6 @@
   virtual bool HasUnknownSideEffects() const { return true; }
   virtual Instruction* Canonicalize(FlowGraph* flow_graph);
 
-  ADD_EXTRA_INFO_TO_S_EXPRESSION_SUPPORT
 
  private:
   const TokenPosition token_pos_;
@@ -5418,8 +5402,6 @@
   virtual Instruction* Canonicalize(FlowGraph* flow_graph);
 
   PRINT_OPERANDS_TO_SUPPORT
-  ADD_OPERANDS_TO_S_EXPRESSION_SUPPORT
-  ADD_EXTRA_INFO_TO_S_EXPRESSION_SUPPORT
 
  private:
   friend class JitCallSpecializer;  // For ASSERT(initialization_).
@@ -5549,7 +5531,14 @@
   void set_calls_initializer(bool value) { calls_initializer_ = value; }
 
   virtual bool AllowsCSE() const {
-    return field().is_final() && !FLAG_fields_may_be_reset;
+    // If two loads of a static-final-late field call the initializer and one
+    // dominates another, we can remove the dominated load with the result of
+    // the dominating load.
+    //
+    // Though if the field is final-late there can be stores into it via
+    // load/compare-with-sentinel/store. Those loads have `!calls_initializer()`
+    // and we won't allow CSE for them.
+    return field().is_final() && (!field().is_late() || calls_initializer());
   }
 
   virtual bool ComputeCanDeoptimize() const {
@@ -5679,7 +5668,6 @@
 
   virtual Definition* Canonicalize(FlowGraph* flow_graph);
 
-  ADD_EXTRA_INFO_TO_S_EXPRESSION_SUPPORT
 
  private:
   const bool index_unboxed_;
@@ -5863,7 +5851,10 @@
 // }
 //
 // under these assumptions:
-// - The start and end inputs are within the bounds of bytes and in smi range.
+// - The difference between start and end must be less than 2^30, since the
+//   resulting length can be twice the input length (and the result has to be in
+//   Smi range). This is guaranteed by `_Utf8Decoder.chunkSize` which is set to
+//   `65536`.
 // - The decoder._scanFlags field is unboxed or contains a smi.
 // - The first 128 entries of the table have the value 1.
 class Utf8ScanInstr : public TemplateDefinition<5, NoThrow> {
@@ -5897,6 +5888,7 @@
   virtual bool HasUnknownSideEffects() const { return true; }
   virtual bool ComputeCanDeoptimize() const { return false; }
   virtual intptr_t DeoptimizationTarget() const { return DeoptId::kNone; }
+  virtual void InferRange(RangeAnalysis* analysis, Range* range);
 
   virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const {
     return kNotSpeculative;
@@ -5983,7 +5975,6 @@
 
   virtual Instruction* Canonicalize(FlowGraph* flow_graph);
 
-  ADD_EXTRA_INFO_TO_S_EXPRESSION_SUPPORT
 
  private:
   compiler::Assembler::CanBeSmi CanValueBeSmi() const {
@@ -6085,6 +6076,21 @@
   // is added.
   virtual bool WillAllocateNewOrRemembered() const = 0;
 
+  virtual bool MayThrow() const {
+    // Any allocation instruction may throw an OutOfMemory error.
+    return true;
+  }
+  virtual bool ComputeCanDeoptimize() const { return false; }
+  virtual bool ComputeCanDeoptimizeAfterCall() const {
+    // We test that allocation instructions have correct deopt environment
+    // (which is needed in case OOM is thrown) by actually deoptimizing
+    // optimized code in allocation slow paths.
+    return !CompilerState::Current().is_aot();
+  }
+  virtual intptr_t NumberOfInputsConsumedBeforeCall() const {
+    return InputCount();
+  }
+
   DEFINE_INSTRUCTION_TYPE_CHECK(Allocation);
 
  private:
@@ -6094,18 +6100,16 @@
   DISALLOW_COPY_AND_ASSIGN(AllocationInstr);
 };
 
-template <intptr_t N, typename ThrowsTrait>
+template <intptr_t N>
 class TemplateAllocation : public AllocationInstr {
  public:
   explicit TemplateAllocation(const InstructionSource& source,
-                              intptr_t deopt_id = DeoptId::kNone)
+                              intptr_t deopt_id)
       : AllocationInstr(source, deopt_id), inputs_() {}
 
   virtual intptr_t InputCount() const { return N; }
   virtual Value* InputAt(intptr_t i) const { return inputs_[i]; }
 
-  virtual bool MayThrow() const { return ThrowsTrait::kCanThrow; }
-
  protected:
   EmbeddedArray<Value*, N> inputs_;
 
@@ -6120,8 +6124,9 @@
  public:
   AllocateObjectInstr(const InstructionSource& source,
                       const Class& cls,
+                      intptr_t deopt_id,
                       Value* type_arguments = nullptr)
-      : AllocationInstr(source),
+      : AllocationInstr(source, deopt_id),
         cls_(cls),
         type_arguments_(type_arguments),
         closure_function_(Function::ZoneHandle()) {
@@ -6150,10 +6155,6 @@
     return type_arguments_;
   }
 
-  virtual bool MayThrow() const { return false; }
-
-  virtual bool ComputeCanDeoptimize() const { return false; }
-
   virtual bool HasUnknownSideEffects() const { return false; }
 
   virtual bool WillAllocateNewOrRemembered() const {
@@ -6165,8 +6166,6 @@
   }
 
   PRINT_OPERANDS_TO_SUPPORT
-  ADD_OPERANDS_TO_S_EXPRESSION_SUPPORT
-  ADD_EXTRA_INFO_TO_S_EXPRESSION_SUPPORT
 
  private:
   virtual void RawSetInputAt(intptr_t i, Value* value) {
@@ -6182,19 +6181,17 @@
   DISALLOW_COPY_AND_ASSIGN(AllocateObjectInstr);
 };
 
-class AllocateUninitializedContextInstr
-    : public TemplateAllocation<0, NoThrow> {
+class AllocateUninitializedContextInstr : public TemplateAllocation<0> {
  public:
   AllocateUninitializedContextInstr(const InstructionSource& source,
-                                    intptr_t num_context_variables);
+                                    intptr_t num_context_variables,
+                                    intptr_t deopt_id);
 
   DECLARE_INSTRUCTION(AllocateUninitializedContext)
   virtual CompileType ComputeType() const;
 
   intptr_t num_context_variables() const { return num_context_variables_; }
 
-  virtual bool ComputeCanDeoptimize() const { return false; }
-
   virtual bool HasUnknownSideEffects() const { return false; }
 
   virtual bool WillAllocateNewOrRemembered() const {
@@ -6316,7 +6313,7 @@
   DISALLOW_COPY_AND_ASSIGN(ArrayAllocationInstr);
 };
 
-template <intptr_t N, typename ThrowsTrait>
+template <intptr_t N>
 class TemplateArrayAllocation : public ArrayAllocationInstr {
  public:
   explicit TemplateArrayAllocation(const InstructionSource& source,
@@ -6326,8 +6323,6 @@
   virtual intptr_t InputCount() const { return N; }
   virtual Value* InputAt(intptr_t i) const { return inputs_[i]; }
 
-  virtual bool MayThrow() const { return ThrowsTrait::kCanThrow; }
-
  protected:
   EmbeddedArray<Value*, N> inputs_;
 
@@ -6335,7 +6330,7 @@
   virtual void RawSetInputAt(intptr_t i, Value* value) { inputs_[i] = value; }
 };
 
-class CreateArrayInstr : public TemplateArrayAllocation<2, Throws> {
+class CreateArrayInstr : public TemplateArrayAllocation<2> {
  public:
   CreateArrayInstr(const InstructionSource& source,
                    Value* element_type,
@@ -6354,12 +6349,6 @@
   Value* element_type() const { return inputs_[kElementTypePos]; }
   virtual Value* num_elements() const { return inputs_[kLengthPos]; }
 
-  // Throw needs environment, which is created only if instruction can
-  // deoptimize.
-  virtual bool ComputeCanDeoptimize() const {
-    return !CompilerState::Current().is_aot();
-  }
-
   virtual bool HasUnknownSideEffects() const { return false; }
 
   virtual bool WillAllocateNewOrRemembered() const {
@@ -6373,7 +6362,7 @@
   DISALLOW_COPY_AND_ASSIGN(CreateArrayInstr);
 };
 
-class AllocateTypedDataInstr : public TemplateArrayAllocation<1, Throws> {
+class AllocateTypedDataInstr : public TemplateArrayAllocation<1> {
  public:
   AllocateTypedDataInstr(const InstructionSource& source,
                          classid_t class_id,
@@ -6391,12 +6380,6 @@
   classid_t class_id() const { return class_id_; }
   virtual Value* num_elements() const { return inputs_[kLengthPos]; }
 
-  // Throw needs environment, which is created only if instruction can
-  // deoptimize.
-  virtual bool ComputeCanDeoptimize() const {
-    return !CompilerState::Current().is_aot();
-  }
-
   virtual bool HasUnknownSideEffects() const { return false; }
 
   virtual bool WillAllocateNewOrRemembered() const {
@@ -6594,9 +6577,13 @@
   DECLARE_INSTRUCTION(LoadField)
   virtual CompileType ComputeType() const;
 
-  virtual bool ComputeCanDeoptimize() const {
+  virtual bool ComputeCanDeoptimize() const { return false; }
+  virtual bool ComputeCanDeoptimizeAfterCall() const {
     return calls_initializer() && !CompilerState::Current().is_aot();
   }
+  virtual intptr_t NumberOfInputsConsumedBeforeCall() const {
+    return InputCount();
+  }
 
   virtual bool HasUnknownSideEffects() const {
     return calls_initializer() && !throw_exception_on_initialization();
@@ -6634,8 +6621,6 @@
   virtual bool AttributesEqual(Instruction* other) const;
 
   PRINT_OPERANDS_TO_SUPPORT
-  ADD_OPERANDS_TO_S_EXPRESSION_SUPPORT
-  ADD_EXTRA_INFO_TO_S_EXPRESSION_SUPPORT
 
  private:
   intptr_t OffsetInBytes() const { return slot().offset_in_bytes(); }
@@ -6674,9 +6659,13 @@
   const AbstractType& type() const { return type_; }
   virtual TokenPosition token_pos() const { return token_pos_; }
 
-  virtual bool ComputeCanDeoptimize() const {
+  virtual bool ComputeCanDeoptimize() const { return false; }
+  virtual bool ComputeCanDeoptimizeAfterCall() const {
     return !CompilerState::Current().is_aot();
   }
+  virtual intptr_t NumberOfInputsConsumedBeforeCall() const {
+    return InputCount();
+  }
 
   virtual bool HasUnknownSideEffects() const { return false; }
 
@@ -6719,9 +6708,13 @@
   const Function& function() const { return function_; }
   virtual TokenPosition token_pos() const { return token_pos_; }
 
-  virtual bool ComputeCanDeoptimize() const {
+  virtual bool ComputeCanDeoptimize() const { return false; }
+  virtual bool ComputeCanDeoptimizeAfterCall() const {
     return !CompilerState::Current().is_aot();
   }
+  virtual intptr_t NumberOfInputsConsumedBeforeCall() const {
+    return InputCount();
+  }
 
   virtual bool HasUnknownSideEffects() const { return false; }
 
@@ -6774,11 +6767,12 @@
 
 // [AllocateContext] instruction allocates a new Context object with the space
 // for the given [context_variables].
-class AllocateContextInstr : public TemplateAllocation<0, NoThrow> {
+class AllocateContextInstr : public TemplateAllocation<0> {
  public:
   AllocateContextInstr(const InstructionSource& source,
-                       const ZoneGrowableArray<const Slot*>& context_slots)
-      : TemplateAllocation(source), context_slots_(context_slots) {}
+                       const ZoneGrowableArray<const Slot*>& context_slots,
+                       intptr_t deopt_id)
+      : TemplateAllocation(source, deopt_id), context_slots_(context_slots) {}
 
   DECLARE_INSTRUCTION(AllocateContext)
   virtual CompileType ComputeType() const;
@@ -6808,7 +6802,7 @@
 
 // [CloneContext] instruction clones the given Context object assuming that
 // it contains exactly the provided [context_variables].
-class CloneContextInstr : public TemplateDefinition<1, NoThrow> {
+class CloneContextInstr : public TemplateDefinition<1, Throws> {
  public:
   CloneContextInstr(const InstructionSource& source,
                     Value* context_value,
@@ -6830,9 +6824,16 @@
   DECLARE_INSTRUCTION(CloneContext)
   virtual CompileType ComputeType() const;
 
-  virtual bool ComputeCanDeoptimize() const {
+  virtual bool ComputeCanDeoptimize() const { return false; }
+  virtual bool ComputeCanDeoptimizeAfterCall() const {
+    // We test that allocation instructions have correct deopt environment
+    // (which is needed in case OOM is thrown) by actually deoptimizing
+    // optimized code in allocation slow paths.
     return !CompilerState::Current().is_aot();
   }
+  virtual intptr_t NumberOfInputsConsumedBeforeCall() const {
+    return InputCount();
+  }
 
   virtual bool HasUnknownSideEffects() const { return false; }
 
@@ -6947,6 +6948,8 @@
 
   virtual Definition* Canonicalize(FlowGraph* flow_graph);
 
+  virtual bool CanTriggerGC() const { return !ValueFitsSmi(); }
+
   DEFINE_INSTRUCTION_TYPE_CHECK(BoxInteger)
 
  private:
@@ -7206,6 +7209,14 @@
 
   virtual Definition* Canonicalize(FlowGraph* flow_graph);
 
+  virtual bool ComputeCanDeoptimize() const {
+    if (SpeculativeModeOfInputs() == kNotSpeculative) {
+      return false;
+    }
+
+    return !value()->Type()->IsInt();
+  }
+
   DECLARE_INSTRUCTION_NO_BACKEND(UnboxInt64)
 
  private:
@@ -7464,7 +7475,6 @@
   }
 
   PRINT_OPERANDS_TO_SUPPORT
-  ADD_OPERANDS_TO_S_EXPRESSION_SUPPORT
 
   DECLARE_COMPARISON_INSTRUCTION(DoubleTestOp)
 
@@ -7605,101 +7615,6 @@
   DISALLOW_COPY_AND_ASSIGN(UnaryInt64OpInstr);
 };
 
-class CheckedSmiOpInstr : public TemplateDefinition<2, Throws> {
- public:
-  CheckedSmiOpInstr(Token::Kind op_kind,
-                    Value* left,
-                    Value* right,
-                    TemplateDartCall<0>* call)
-      : TemplateDefinition(call->deopt_id()), call_(call), op_kind_(op_kind) {
-    ASSERT(call->type_args_len() == 0);
-    ASSERT(!call->IsInstanceCallBase() ||
-           call->AsInstanceCallBase()->CanReceiverBeSmiBasedOnInterfaceTarget(
-               Thread::Current()->zone()));
-
-    SetInputAt(0, left);
-    SetInputAt(1, right);
-  }
-
-  TemplateDartCall<0>* call() const { return call_; }
-  Token::Kind op_kind() const { return op_kind_; }
-  Value* left() const { return inputs_[0]; }
-  Value* right() const { return inputs_[1]; }
-
-  virtual bool ComputeCanDeoptimize() const { return false; }
-
-  virtual CompileType ComputeType() const;
-  virtual bool RecomputeType();
-
-  virtual bool HasUnknownSideEffects() const { return true; }
-  virtual bool CanCallDart() const { return true; }
-
-  virtual Definition* Canonicalize(FlowGraph* flow_graph);
-
-  PRINT_OPERANDS_TO_SUPPORT
-  ADD_OPERANDS_TO_S_EXPRESSION_SUPPORT
-
-  DECLARE_INSTRUCTION(CheckedSmiOp)
-
- private:
-  TemplateDartCall<0>* call_;
-  const Token::Kind op_kind_;
-  DISALLOW_COPY_AND_ASSIGN(CheckedSmiOpInstr);
-};
-
-class CheckedSmiComparisonInstr : public TemplateComparison<2, Throws> {
- public:
-  CheckedSmiComparisonInstr(Token::Kind op_kind,
-                            Value* left,
-                            Value* right,
-                            TemplateDartCall<0>* call)
-      : TemplateComparison(call->source(), op_kind, call->deopt_id()),
-        call_(call),
-        is_negated_(false) {
-    ASSERT(call->type_args_len() == 0);
-    ASSERT(!call->IsInstanceCallBase() ||
-           call->AsInstanceCallBase()->CanReceiverBeSmiBasedOnInterfaceTarget(
-               Thread::Current()->zone()));
-
-    SetInputAt(0, left);
-    SetInputAt(1, right);
-  }
-
-  TemplateDartCall<0>* call() const { return call_; }
-
-  virtual bool ComputeCanDeoptimize() const { return false; }
-
-  virtual CompileType ComputeType() const;
-
-  virtual Definition* Canonicalize(FlowGraph* flow_graph);
-
-  virtual void NegateComparison() {
-    ComparisonInstr::NegateComparison();
-    is_negated_ = !is_negated_;
-  }
-
-  bool is_negated() const { return is_negated_; }
-
-  virtual bool HasUnknownSideEffects() const { return true; }
-  virtual bool CanCallDart() const { return true; }
-
-  PRINT_OPERANDS_TO_SUPPORT
-
-  DECLARE_INSTRUCTION(CheckedSmiComparison)
-
-  virtual void EmitBranchCode(FlowGraphCompiler* compiler, BranchInstr* branch);
-
-  virtual Condition EmitComparisonCode(FlowGraphCompiler* compiler,
-                                       BranchLabels labels);
-
-  virtual ComparisonInstr* CopyWithNewOperands(Value* left, Value* right);
-
- private:
-  TemplateDartCall<0>* call_;
-  bool is_negated_;
-  DISALLOW_COPY_AND_ASSIGN(CheckedSmiComparisonInstr);
-};
-
 class BinaryIntegerOpInstr : public TemplateDefinition<2, NoThrow, Pure> {
  public:
   BinaryIntegerOpInstr(Token::Kind op_kind,
@@ -7762,7 +7677,6 @@
   virtual void InferRange(RangeAnalysis* analysis, Range* range);
 
   PRINT_OPERANDS_TO_SUPPORT
-  ADD_OPERANDS_TO_S_EXPRESSION_SUPPORT
 
   DEFINE_INSTRUCTION_TYPE_CHECK(BinaryIntegerOp)
 
@@ -8215,7 +8129,6 @@
   }
 
   PRINT_OPERANDS_TO_SUPPORT
-  ADD_EXTRA_INFO_TO_S_EXPRESSION_SUPPORT
 
  private:
   const TokenPosition token_pos_;
@@ -8787,7 +8700,6 @@
 
   virtual Value* RedefinedValue() const;
 
-  ADD_EXTRA_INFO_TO_S_EXPRESSION_SUPPORT
 
   PRINT_OPERANDS_TO_SUPPORT
 
@@ -9318,8 +9230,6 @@
 
   DECLARE_INSTRUCTION(SimdOp)
   PRINT_OPERANDS_TO_SUPPORT
-  ADD_OPERANDS_TO_S_EXPRESSION_SUPPORT
-  ADD_EXTRA_INFO_TO_S_EXPRESSION_SUPPORT
 
  private:
   SimdOpInstr(Kind kind, intptr_t deopt_id)
@@ -9460,6 +9370,7 @@
   static Environment* From(Zone* zone,
                            const GrowableArray<Definition*>& definitions,
                            intptr_t fixed_parameter_count,
+                           intptr_t lazy_deopt_pruning_count,
                            const ParsedFunction& parsed_function);
 
   void set_locations(Location* locations) {
@@ -9470,9 +9381,19 @@
   // Get deopt_id associated with this environment.
   // Note that only outer environments have deopt id associated with
   // them (set by DeepCopyToOuter).
-  intptr_t deopt_id() const {
-    ASSERT(deopt_id_ != DeoptId::kNone);
-    return deopt_id_;
+  intptr_t GetDeoptId() const {
+    ASSERT(DeoptIdBits::decode(bitfield_) != DeoptId::kNone);
+    return DeoptIdBits::decode(bitfield_);
+  }
+
+  intptr_t LazyDeoptPruneCount() const {
+    return LazyDeoptPruningBits::decode(bitfield_);
+  }
+
+  Environment* GetLazyDeoptEnv(Zone* zone) {
+    const intptr_t num_args_to_prune = LazyDeoptPruneCount();
+    if (num_args_to_prune == 0) return this;
+    return DeepCopy(zone, Length() - num_args_to_prune);
   }
 
   Environment* outer() const { return outer_; }
@@ -9534,7 +9455,6 @@
                        Definition* result) const;
 
   void PrintTo(BaseTextBuffer* f) const;
-  SExpression* ToSExpression(FlowGraphSerializer* s) const;
   const char* ToCString() const;
 
   // Deep copy an environment.  The 'length' parameter may be less than the
@@ -9547,21 +9467,39 @@
   friend class compiler::BlockBuilder;  // For Environment constructor.
   friend class FlowGraphDeserializer;   // For constructor and deopt_id_.
 
+  class LazyDeoptPruningBits : public BitField<uintptr_t, uintptr_t, 0, 8> {};
+  class DeoptIdBits
+      : public BitField<uintptr_t,
+                        intptr_t,
+                        LazyDeoptPruningBits::kNextBit,
+                        kBitsPerWord - LazyDeoptPruningBits::kNextBit,
+                        /*sign_extend=*/true> {};
+
   Environment(intptr_t length,
               intptr_t fixed_parameter_count,
+              intptr_t lazy_deopt_pruning_count,
               const ParsedFunction& parsed_function,
               Environment* outer)
       : values_(length),
         fixed_parameter_count_(fixed_parameter_count),
+        bitfield_(DeoptIdBits::encode(DeoptId::kNone) |
+                  LazyDeoptPruningBits::encode(lazy_deopt_pruning_count)),
         parsed_function_(parsed_function),
         outer_(outer) {}
 
+  void SetDeoptId(intptr_t deopt_id) {
+    bitfield_ = DeoptIdBits::update(deopt_id, bitfield_);
+  }
+  void SetLazyDeoptPruneCount(intptr_t value) {
+    bitfield_ = LazyDeoptPruningBits::update(value, bitfield_);
+  }
+
   GrowableArray<Value*> values_;
   Location* locations_ = nullptr;
   const intptr_t fixed_parameter_count_;
   // Deoptimization id associated with this environment. Only set for
   // outer environments.
-  intptr_t deopt_id_ = DeoptId::kNone;
+  uintptr_t bitfield_;
   const ParsedFunction& parsed_function_;
   Environment* outer_;
 
diff --git a/runtime/vm/compiler/backend/il_arm.cc b/runtime/vm/compiler/backend/il_arm.cc
index 5d9b0e9..c8b681f 100644
--- a/runtime/vm/compiler/backend/il_arm.cc
+++ b/runtime/vm/compiler/backend/il_arm.cc
@@ -31,6 +31,9 @@
 
 namespace dart {
 
+DECLARE_FLAG(bool, inline_alloc);
+DECLARE_FLAG(bool, use_slow_path);
+
 // Generic summary for call instructions that have all arguments pushed
 // on the stack and return the result in a fixed location depending on
 // the return value (R0, Location::Pair(R0, R1) or Q0).
@@ -580,16 +583,6 @@
   }
 }
 
-LocationSummary* DispatchTableCallInstr::MakeLocationSummary(Zone* zone,
-                                                             bool opt) const {
-  const intptr_t kNumInputs = 1;
-  const intptr_t kNumTemps = 0;
-  LocationSummary* summary = new (zone)
-      LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
-  summary->set_in(0, Location::RegisterLocation(R0));  // ClassId
-  return MakeCallSummary(zone, this, summary);
-}
-
 LocationSummary* ClosureCallInstr::MakeLocationSummary(Zone* zone,
                                                        bool opt) const {
   const intptr_t kNumInputs = 1;
@@ -822,7 +815,24 @@
   return summary;
 }
 
-static Condition TokenKindToSmiCondition(Token::Kind kind) {
+void AssertBooleanInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  ASSERT(locs()->always_calls());
+
+  auto object_store = compiler->isolate_group()->object_store();
+  const auto& assert_boolean_stub =
+      Code::ZoneHandle(compiler->zone(), object_store->assert_boolean_stub());
+
+  compiler::Label done;
+  __ tst(AssertBooleanABI::kObjectReg,
+         compiler::Operand(compiler::target::ObjectAlignment::kBoolVsNullMask));
+  __ b(&done, NOT_ZERO);
+  compiler->GenerateStubCall(source(), assert_boolean_stub,
+                             /*kind=*/UntaggedPcDescriptors::kOther, locs(),
+                             deopt_id());
+  __ Bind(&done);
+}
+
+static Condition TokenKindToIntCondition(Token::Kind kind) {
   switch (kind) {
     case Token::kEQ:
       return EQ;
@@ -845,6 +855,16 @@
 LocationSummary* EqualityCompareInstr::MakeLocationSummary(Zone* zone,
                                                            bool opt) const {
   const intptr_t kNumInputs = 2;
+  if (is_null_aware()) {
+    const intptr_t kNumTemps = 1;
+    LocationSummary* locs = new (zone)
+        LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
+    locs->set_in(0, Location::RequiresRegister());
+    locs->set_in(1, Location::RequiresRegister());
+    locs->set_temp(0, Location::RequiresRegister());
+    locs->set_out(0, Location::RequiresRegister());
+    return locs;
+  }
   if (operation_cid() == kMintCid) {
     const intptr_t kNumTemps = 0;
     LocationSummary* locs = new (zone)
@@ -951,7 +971,7 @@
   Location right = locs->in(1);
   ASSERT(!left.IsConstant() || !right.IsConstant());
 
-  Condition true_condition = TokenKindToSmiCondition(kind);
+  Condition true_condition = TokenKindToIntCondition(kind);
 
   if (left.IsConstant()) {
     __ CompareObject(right.reg(), left.constant());
@@ -964,26 +984,6 @@
   return true_condition;
 }
 
-static Condition TokenKindToMintCondition(Token::Kind kind) {
-  switch (kind) {
-    case Token::kEQ:
-      return EQ;
-    case Token::kNE:
-      return NE;
-    case Token::kLT:
-      return LT;
-    case Token::kGT:
-      return GT;
-    case Token::kLTE:
-      return LE;
-    case Token::kGTE:
-      return GE;
-    default:
-      UNREACHABLE();
-      return VS;
-  }
-}
-
 static Condition EmitUnboxedMintEqualityOp(FlowGraphCompiler* compiler,
                                            LocationSummary* locs,
                                            Token::Kind kind) {
@@ -999,7 +999,7 @@
   __ cmp(left_lo, compiler::Operand(right_lo));
   // Compare upper if lower is equal.
   __ cmp(left_hi, compiler::Operand(right_hi), EQ);
-  return TokenKindToMintCondition(kind);
+  return TokenKindToIntCondition(kind);
 }
 
 static Condition EmitUnboxedMintComparisonOp(FlowGraphCompiler* compiler,
@@ -1046,6 +1046,45 @@
   return lo_cond;
 }
 
+static Condition EmitNullAwareInt64ComparisonOp(FlowGraphCompiler* compiler,
+                                                LocationSummary* locs,
+                                                Token::Kind kind,
+                                                BranchLabels labels) {
+  ASSERT((kind == Token::kEQ) || (kind == Token::kNE));
+  const Register left = locs->in(0).reg();
+  const Register right = locs->in(1).reg();
+  const Register temp = locs->temp(0).reg();
+  const Condition true_condition = TokenKindToIntCondition(kind);
+  compiler::Label* equal_result =
+      (true_condition == EQ) ? labels.true_label : labels.false_label;
+  compiler::Label* not_equal_result =
+      (true_condition == EQ) ? labels.false_label : labels.true_label;
+
+  // Check if operands have the same value. If they don't, then they could
+  // be equal only if both of them are Mints with the same value.
+  __ cmp(left, compiler::Operand(right));
+  __ b(equal_result, EQ);
+  __ and_(temp, left, compiler::Operand(right));
+  __ BranchIfSmi(temp, not_equal_result);
+  __ CompareClassId(left, kMintCid, temp);
+  __ b(not_equal_result, NE);
+  __ CompareClassId(right, kMintCid, temp);
+  __ b(not_equal_result, NE);
+  __ LoadFieldFromOffset(temp, left, compiler::target::Mint::value_offset());
+  __ LoadFieldFromOffset(TMP, right, compiler::target::Mint::value_offset());
+  __ cmp(temp, compiler::Operand(TMP));
+  __ LoadFieldFromOffset(
+      temp, left,
+      compiler::target::Mint::value_offset() + compiler::target::kWordSize,
+      compiler::kFourBytes, EQ);
+  __ LoadFieldFromOffset(
+      TMP, right,
+      compiler::target::Mint::value_offset() + compiler::target::kWordSize,
+      compiler::kFourBytes, EQ);
+  __ cmp(temp, compiler::Operand(TMP), EQ);
+  return true_condition;
+}
+
 static Condition TokenKindToDoubleCondition(Token::Kind kind) {
   switch (kind) {
     case Token::kEQ:
@@ -1087,6 +1126,10 @@
 
 Condition EqualityCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
                                                    BranchLabels labels) {
+  if (is_null_aware()) {
+    ASSERT(operation_cid() == kMintCid);
+    return EmitNullAwareInt64ComparisonOp(compiler, locs(), kind(), labels);
+  }
   if (operation_cid() == kSmiCid) {
     return EmitSmiComparisonOp(compiler, locs(), kind());
   } else if (operation_cid() == kMintCid) {
@@ -3165,13 +3208,15 @@
   ASSERT(locs()->in(kLengthPos).reg() == kLengthReg);
 
   compiler::Label slow_path, done;
-  if (compiler->is_optimizing() && !FLAG_precompiled_mode &&
-      num_elements()->BindsToConstant() &&
-      compiler::target::IsSmi(num_elements()->BoundConstant())) {
-    const intptr_t length =
-        compiler::target::SmiValue(num_elements()->BoundConstant());
-    if (Array::IsValidLength(length)) {
-      InlineArrayAllocation(compiler, length, &slow_path, &done);
+  if (!FLAG_use_slow_path && FLAG_inline_alloc) {
+    if (compiler->is_optimizing() && !FLAG_precompiled_mode &&
+        num_elements()->BindsToConstant() &&
+        compiler::target::IsSmi(num_elements()->BoundConstant())) {
+      const intptr_t length =
+          compiler::target::SmiValue(num_elements()->BoundConstant());
+      if (Array::IsValidLength(length)) {
+        InlineArrayAllocation(compiler, length, &slow_path, &done);
+      }
     }
   }
 
@@ -3444,105 +3489,6 @@
   __ Bind(&done);
 }
 
-LocationSummary* InstantiateTypeInstr::MakeLocationSummary(Zone* zone,
-                                                           bool opt) const {
-  const intptr_t kNumInputs = 2;
-  const intptr_t kNumTemps = 0;
-  LocationSummary* locs = new (zone)
-      LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
-  locs->set_in(0, Location::RegisterLocation(
-                      InstantiationABI::kInstantiatorTypeArgumentsReg));
-  locs->set_in(1, Location::RegisterLocation(
-                      InstantiationABI::kFunctionTypeArgumentsReg));
-  locs->set_out(0,
-                Location::RegisterLocation(InstantiationABI::kResultTypeReg));
-  return locs;
-}
-
-void InstantiateTypeInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  const Register instantiator_type_args_reg = locs()->in(0).reg();
-  const Register function_type_args_reg = locs()->in(1).reg();
-  const Register result_reg = locs()->out(0).reg();
-
-  // 'instantiator_type_args_reg' is a TypeArguments object (or null).
-  // 'function_type_args_reg' is a TypeArguments object (or null).
-  // A runtime call to instantiate the type is required.
-  __ PushObject(Object::null_object());  // Make room for the result.
-  __ PushObject(type());
-  static_assert(InstantiationABI::kFunctionTypeArgumentsReg <
-                    InstantiationABI::kInstantiatorTypeArgumentsReg,
-                "Should be ordered to push arguments with one instruction");
-  __ PushList((1 << instantiator_type_args_reg) |
-              (1 << function_type_args_reg));
-  compiler->GenerateRuntimeCall(source(), deopt_id(),
-                                kInstantiateTypeRuntimeEntry, 3, locs());
-  __ Drop(3);          // Drop 2 type vectors, and uninstantiated type.
-  __ Pop(result_reg);  // Pop instantiated type.
-}
-
-LocationSummary* InstantiateTypeArgumentsInstr::MakeLocationSummary(
-    Zone* zone,
-    bool opt) const {
-  const intptr_t kNumInputs = 3;
-  const intptr_t kNumTemps = 0;
-  LocationSummary* locs = new (zone)
-      LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
-  locs->set_in(0, Location::RegisterLocation(
-                      InstantiationABI::kInstantiatorTypeArgumentsReg));
-  locs->set_in(1, Location::RegisterLocation(
-                      InstantiationABI::kFunctionTypeArgumentsReg));
-  locs->set_in(2, Location::RegisterLocation(
-                      InstantiationABI::kUninstantiatedTypeArgumentsReg));
-  locs->set_out(
-      0, Location::RegisterLocation(InstantiationABI::kResultTypeArgumentsReg));
-  return locs;
-}
-
-void InstantiateTypeArgumentsInstr::EmitNativeCode(
-    FlowGraphCompiler* compiler) {
-  // We should never try and instantiate a TAV known at compile time to be null,
-  // so we can use a null value below for the dynamic case.
-  ASSERT(!type_arguments()->BindsToConstant() ||
-         !type_arguments()->BoundConstant().IsNull());
-  const auto& type_args =
-      type_arguments()->BindsToConstant()
-          ? TypeArguments::Cast(type_arguments()->BoundConstant())
-          : Object::null_type_arguments();
-  const intptr_t len = type_args.Length();
-  const bool can_function_type_args_be_null =
-      function_type_arguments()->CanBe(Object::null_object());
-
-  compiler::Label type_arguments_instantiated;
-  if (type_args.IsNull()) {
-    // Currently we only create dynamic InstantiateTypeArguments instructions
-    // in cases where we know the type argument is uninstantiated at runtime,
-    // so there are no extra checks needed to call the stub successfully.
-  } else if (type_args.IsRawWhenInstantiatedFromRaw(len) &&
-             can_function_type_args_be_null) {
-    // If both the instantiator and function type arguments are null and if the
-    // type argument vector instantiated from null becomes a vector of dynamic,
-    // then use null as the type arguments.
-    //
-    // 'instantiator_type_args_reg' is a TypeArguments object (or null).
-    // 'function_type_args_reg' is a TypeArguments object (or null).
-    const Register instantiator_type_args_reg = locs()->in(0).reg();
-    const Register function_type_args_reg = locs()->in(1).reg();
-    const Register result_reg = locs()->out(0).reg();
-    ASSERT(result_reg != instantiator_type_args_reg &&
-           result_reg != function_type_args_reg);
-    __ LoadObject(result_reg, Object::null_object());
-    __ cmp(instantiator_type_args_reg, compiler::Operand(result_reg));
-    if (!function_type_arguments()->BindsToConstant()) {
-      __ cmp(function_type_args_reg, compiler::Operand(result_reg), EQ);
-    }
-    __ b(&type_arguments_instantiated, EQ);
-  }
-  // Lookup cache in stub before calling runtime.
-  compiler->GenerateStubCall(source(), GetStub(), UntaggedPcDescriptors::kOther,
-                             locs());
-  __ Bind(&type_arguments_instantiated);
-}
-
 LocationSummary* AllocateUninitializedContextInstr::MakeLocationSummary(
     Zone* zone,
     bool opt) const {
@@ -3574,12 +3520,17 @@
 
     compiler->SaveLiveRegisters(locs);
 
+    auto slow_path_env = compiler->SlowPathEnvironmentFor(
+        instruction(), /*num_slow_path_args=*/0);
+    ASSERT(slow_path_env != nullptr);
+
     auto object_store = compiler->isolate_group()->object_store();
     const auto& allocate_context_stub = Code::ZoneHandle(
         compiler->zone(), object_store->allocate_context_stub());
     __ LoadImmediate(R1, instruction()->num_context_variables());
     compiler->GenerateStubCall(instruction()->source(), allocate_context_stub,
-                               UntaggedPcDescriptors::kOther, locs);
+                               UntaggedPcDescriptors::kOther, locs,
+                               instruction()->deopt_id(), slow_path_env);
     ASSERT(instruction()->locs()->out(0).reg() == R0);
     compiler->RestoreLiveRegisters(instruction()->locs());
     __ b(exit_label());
@@ -3597,14 +3548,19 @@
   compiler->AddSlowPathCode(slow_path);
   intptr_t instance_size = Context::InstanceSize(num_context_variables());
 
-  __ TryAllocateArray(kContextCid, instance_size, slow_path->entry_label(),
-                      result,  // instance
-                      temp0, temp1, temp2);
+  if (!FLAG_use_slow_path && FLAG_inline_alloc) {
+    __ TryAllocateArray(kContextCid, instance_size, slow_path->entry_label(),
+                        result,  // instance
+                        temp0, temp1, temp2);
 
-  // Setup up number of context variables field.
-  __ LoadImmediate(temp0, num_context_variables());
-  __ str(temp0, compiler::FieldAddress(
-                    result, compiler::target::Context::num_variables_offset()));
+    // Setup up number of context variables field.
+    __ LoadImmediate(temp0, num_context_variables());
+    __ str(temp0,
+           compiler::FieldAddress(
+               result, compiler::target::Context::num_variables_offset()));
+  } else {
+    __ Jump(slow_path->entry_label());
+  }
 
   __ Bind(slow_path->exit_label());
 }
@@ -3629,7 +3585,7 @@
       Code::ZoneHandle(compiler->zone(), object_store->allocate_context_stub());
   __ LoadImmediate(R1, num_context_variables());
   compiler->GenerateStubCall(source(), allocate_context_stub,
-                             UntaggedPcDescriptors::kOther, locs());
+                             UntaggedPcDescriptors::kOther, locs(), deopt_id());
 }
 
 LocationSummary* CloneContextInstr::MakeLocationSummary(Zone* zone,
@@ -3651,7 +3607,8 @@
   const auto& clone_context_stub =
       Code::ZoneHandle(compiler->zone(), object_store->clone_context_stub());
   compiler->GenerateStubCall(source(), clone_context_stub,
-                             /*kind=*/UntaggedPcDescriptors::kOther, locs());
+                             /*kind=*/UntaggedPcDescriptors::kOther, locs(),
+                             deopt_id());
 }
 
 LocationSummary* CatchBlockEntryInstr::MakeLocationSummary(Zone* zone,
@@ -3940,332 +3897,6 @@
   }
 }
 
-class CheckedSmiSlowPath : public TemplateSlowPathCode<CheckedSmiOpInstr> {
- public:
-  CheckedSmiSlowPath(CheckedSmiOpInstr* instruction, intptr_t try_index)
-      : TemplateSlowPathCode(instruction), try_index_(try_index) {}
-
-  static constexpr intptr_t kNumSlowPathArgs = 2;
-
-  virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
-    if (compiler::Assembler::EmittingComments()) {
-      __ Comment("slow path smi operation");
-    }
-    __ Bind(entry_label());
-    LocationSummary* locs = instruction()->locs();
-    Register result = locs->out(0).reg();
-    locs->live_registers()->Remove(Location::RegisterLocation(result));
-
-    compiler->SaveLiveRegisters(locs);
-    if (instruction()->env() != NULL) {
-      Environment* env =
-          compiler->SlowPathEnvironmentFor(instruction(), kNumSlowPathArgs);
-      compiler->pending_deoptimization_env_ = env;
-    }
-    __ Push(locs->in(0).reg());
-    __ Push(locs->in(1).reg());
-    const auto& selector = String::Handle(instruction()->call()->Selector());
-    const auto& arguments_descriptor =
-        Array::Handle(ArgumentsDescriptor::NewBoxed(
-            /*type_args_len=*/0, /*num_arguments=*/2));
-    compiler->EmitMegamorphicInstanceCall(
-        selector, arguments_descriptor, instruction()->call()->deopt_id(),
-        instruction()->source(), locs, try_index_, kNumSlowPathArgs);
-    __ mov(result, compiler::Operand(R0));
-    compiler->RestoreLiveRegisters(locs);
-    __ b(exit_label());
-    compiler->pending_deoptimization_env_ = NULL;
-  }
-
- private:
-  intptr_t try_index_;
-};
-
-LocationSummary* CheckedSmiOpInstr::MakeLocationSummary(Zone* zone,
-                                                        bool opt) const {
-  const intptr_t kNumInputs = 2;
-  const intptr_t kNumTemps = 0;
-  LocationSummary* summary = new (zone) LocationSummary(
-      zone, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath);
-  summary->set_in(0, Location::RequiresRegister());
-  summary->set_in(1, Location::RequiresRegister());
-  summary->set_out(0, Location::RequiresRegister());
-  return summary;
-}
-
-void CheckedSmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  CheckedSmiSlowPath* slow_path =
-      new CheckedSmiSlowPath(this, compiler->CurrentTryIndex());
-  compiler->AddSlowPathCode(slow_path);
-  // Test operands if necessary.
-  Register left = locs()->in(0).reg();
-  Register right = locs()->in(1).reg();
-  Register result = locs()->out(0).reg();
-  intptr_t left_cid = this->left()->Type()->ToCid();
-  intptr_t right_cid = this->right()->Type()->ToCid();
-  bool combined_smi_check = false;
-  if (this->left()->definition() == this->right()->definition()) {
-    __ tst(left, compiler::Operand(kSmiTagMask));
-  } else if (left_cid == kSmiCid) {
-    __ tst(right, compiler::Operand(kSmiTagMask));
-  } else if (right_cid == kSmiCid) {
-    __ tst(left, compiler::Operand(kSmiTagMask));
-  } else {
-    combined_smi_check = true;
-    __ orr(result, left, compiler::Operand(right));
-    __ tst(result, compiler::Operand(kSmiTagMask));
-  }
-  __ b(slow_path->entry_label(), NE);
-  switch (op_kind()) {
-    case Token::kADD:
-      __ adds(result, left, compiler::Operand(right));
-      __ b(slow_path->entry_label(), VS);
-      break;
-    case Token::kSUB:
-      __ subs(result, left, compiler::Operand(right));
-      __ b(slow_path->entry_label(), VS);
-      break;
-    case Token::kMUL:
-      __ SmiUntag(IP, left);
-      __ smull(result, IP, IP, right);
-      // IP: result bits 32..63.
-      __ cmp(IP, compiler::Operand(result, ASR, 31));
-      __ b(slow_path->entry_label(), NE);
-      break;
-    case Token::kBIT_OR:
-      // Operation may be part of combined smi check.
-      if (!combined_smi_check) {
-        __ orr(result, left, compiler::Operand(right));
-      }
-      break;
-    case Token::kBIT_AND:
-      __ and_(result, left, compiler::Operand(right));
-      break;
-    case Token::kBIT_XOR:
-      __ eor(result, left, compiler::Operand(right));
-      break;
-    case Token::kSHL:
-      ASSERT(result != left);
-      ASSERT(result != right);
-      __ CompareImmediate(
-          right, compiler::target::ToRawSmi(compiler::target::kSmiBits));
-      __ b(slow_path->entry_label(), HI);
-
-      __ SmiUntag(TMP, right);
-      // Check for overflow by shifting left and shifting back arithmetically.
-      // If the result is different from the original, there was overflow.
-      __ Lsl(result, left, TMP);
-      __ cmp(left, compiler::Operand(result, ASR, TMP));
-      __ b(slow_path->entry_label(), NE);
-      break;
-    case Token::kSHR:
-      ASSERT(result != left);
-      ASSERT(result != right);
-      __ CompareImmediate(
-          right, compiler::target::ToRawSmi(compiler::target::kSmiBits));
-      __ b(slow_path->entry_label(), HI);
-
-      __ SmiUntag(result, right);
-      __ SmiUntag(TMP, left);
-      __ Asr(result, TMP, result);
-      __ SmiTag(result);
-      break;
-    case Token::kUSHR: {
-      ASSERT(result != left);
-      ASSERT(result != right);
-      __ CompareImmediate(right, compiler::target::ToRawSmi(kBitsPerInt64));
-      __ b(slow_path->entry_label(), UNSIGNED_GREATER_EQUAL);
-
-      compiler::Label done;
-      __ SmiUntag(result, right);
-      // 64-bit representation of left operand value:
-      //
-      //       ss...sssss  s  s  xxxxxxxxxxxxx
-      //       |        |  |  |  |           |
-      //       63      32  31 30 kSmiBits-1  0
-      //
-      // Where 's' is a sign bit.
-      //
-      // If left operand is negative (sign bit is set), then
-      // result will fit into Smi range if and only if
-      // the shift amount >= 64 - kSmiBits.
-      //
-      // If left operand is non-negative, the result always
-      // fits into Smi range.
-      //
-      __ CompareImmediate(result, 64 - compiler::target::kSmiBits);
-      // Shift amount >= 64 - kSmiBits > 32, but < 64.
-      // Result is guaranteed to fit into Smi range.
-      // Low (Smi) part of the left operand is shifted out.
-      // High part is filled with sign bits.
-      __ sub(result, result, compiler::Operand(32), GE);
-      __ Asr(TMP, left, compiler::Operand(31), GE);
-      __ Lsr(result, TMP, result, GE);
-      __ SmiTag(result, GE);
-      __ b(&done, GE);
-      // Shift amount < 64 - kSmiBits.
-      // If left is negative, then result will not fit into Smi range.
-      // Also deopt in case of negative shift amount.
-      __ tst(left, compiler::Operand(left));
-      __ b(slow_path->entry_label(), MI);
-      // At this point left operand is non-negative, so unsigned shift
-      // can't overflow.
-      __ CompareImmediate(result, compiler::target::kSmiBits);
-      // Left operand >= 0, shift amount >= kSmiBits. Result is 0.
-      __ LoadImmediate(result, 0, GE);
-      // Left operand >= 0, shift amount < kSmiBits < 32.
-      __ SmiUntag(TMP, left, LT);
-      __ Lsr(result, TMP, result, LT);
-      __ SmiTag(result, LT);
-      __ Bind(&done);
-      break;
-    }
-    default:
-      UNREACHABLE();
-  }
-  __ Bind(slow_path->exit_label());
-}
-
-class CheckedSmiComparisonSlowPath
-    : public TemplateSlowPathCode<CheckedSmiComparisonInstr> {
- public:
-  static constexpr intptr_t kNumSlowPathArgs = 2;
-
-  CheckedSmiComparisonSlowPath(CheckedSmiComparisonInstr* instruction,
-                               Environment* env,
-                               intptr_t try_index,
-                               BranchLabels labels,
-                               bool merged)
-      : TemplateSlowPathCode(instruction),
-        try_index_(try_index),
-        labels_(labels),
-        merged_(merged),
-        env_(env) {
-    // The environment must either come from the comparison or the environment
-    // was cleared from the comparison (and moved to a branch).
-    ASSERT(env == instruction->env() ||
-           (merged && instruction->env() == nullptr));
-  }
-
-  virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
-    if (compiler::Assembler::EmittingComments()) {
-      __ Comment("slow path smi operation");
-    }
-    __ Bind(entry_label());
-    LocationSummary* locs = instruction()->locs();
-    Register result = merged_ ? locs->temp(0).reg() : locs->out(0).reg();
-    locs->live_registers()->Remove(Location::RegisterLocation(result));
-
-    compiler->SaveLiveRegisters(locs);
-    if (env_ != nullptr) {
-      compiler->pending_deoptimization_env_ =
-          compiler->SlowPathEnvironmentFor(env_, locs, kNumSlowPathArgs);
-    }
-    __ Push(locs->in(0).reg());
-    __ Push(locs->in(1).reg());
-    const auto& selector = String::Handle(instruction()->call()->Selector());
-    const auto& arguments_descriptor =
-        Array::Handle(ArgumentsDescriptor::NewBoxed(
-            /*type_args_len=*/0, /*num_arguments=*/2));
-    compiler->EmitMegamorphicInstanceCall(
-        selector, arguments_descriptor, instruction()->call()->deopt_id(),
-        instruction()->source(), locs, try_index_, kNumSlowPathArgs);
-    __ mov(result, compiler::Operand(R0));
-    compiler->RestoreLiveRegisters(locs);
-    compiler->pending_deoptimization_env_ = nullptr;
-    if (merged_) {
-      __ CompareObject(result, Bool::True());
-      __ b(instruction()->is_negated() ? labels_.false_label
-                                       : labels_.true_label,
-           EQ);
-      __ b(instruction()->is_negated() ? labels_.true_label
-                                       : labels_.false_label);
-    } else {
-      if (instruction()->is_negated()) {
-        // Need to negate the result of slow path call.
-        __ CompareObject(result, Bool::True());
-        __ LoadObject(result, Bool::True(), NE);
-        __ LoadObject(result, Bool::False(), EQ);
-      }
-      __ b(exit_label());
-    }
-  }
-
- private:
-  intptr_t try_index_;
-  BranchLabels labels_;
-  bool merged_;
-  Environment* env_;
-};
-
-LocationSummary* CheckedSmiComparisonInstr::MakeLocationSummary(
-    Zone* zone,
-    bool opt) const {
-  const intptr_t kNumInputs = 2;
-  const intptr_t kNumTemps = 1;
-  LocationSummary* summary = new (zone) LocationSummary(
-      zone, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath);
-  summary->set_in(0, Location::RequiresRegister());
-  summary->set_in(1, Location::RequiresRegister());
-  summary->set_temp(0, Location::RequiresRegister());
-  summary->set_out(0, Location::RequiresRegister());
-  return summary;
-}
-
-Condition CheckedSmiComparisonInstr::EmitComparisonCode(
-    FlowGraphCompiler* compiler,
-    BranchLabels labels) {
-  return EmitSmiComparisonOp(compiler, locs(), kind());
-}
-
-#define EMIT_SMI_CHECK                                                         \
-  Register left = locs()->in(0).reg();                                         \
-  Register right = locs()->in(1).reg();                                        \
-  Register temp = locs()->temp(0).reg();                                       \
-  intptr_t left_cid = this->left()->Type()->ToCid();                           \
-  intptr_t right_cid = this->right()->Type()->ToCid();                         \
-  if (this->left()->definition() == this->right()->definition()) {             \
-    __ tst(left, compiler::Operand(kSmiTagMask));                              \
-  } else if (left_cid == kSmiCid) {                                            \
-    __ tst(right, compiler::Operand(kSmiTagMask));                             \
-  } else if (right_cid == kSmiCid) {                                           \
-    __ tst(left, compiler::Operand(kSmiTagMask));                              \
-  } else {                                                                     \
-    __ orr(temp, left, compiler::Operand(right));                              \
-    __ tst(temp, compiler::Operand(kSmiTagMask));                              \
-  }                                                                            \
-  __ b(slow_path->entry_label(), NE)
-
-void CheckedSmiComparisonInstr::EmitBranchCode(FlowGraphCompiler* compiler,
-                                               BranchInstr* branch) {
-  BranchLabels labels = compiler->CreateBranchLabels(branch);
-  CheckedSmiComparisonSlowPath* slow_path = new CheckedSmiComparisonSlowPath(
-      this, branch->env(), compiler->CurrentTryIndex(), labels,
-      /* merged = */ true);
-  compiler->AddSlowPathCode(slow_path);
-  EMIT_SMI_CHECK;
-  Condition true_condition = EmitComparisonCode(compiler, labels);
-  ASSERT(true_condition != kInvalidCondition);
-  EmitBranchOnCondition(compiler, true_condition, labels);
-  __ Bind(slow_path->exit_label());
-}
-
-void CheckedSmiComparisonInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  BranchLabels labels = {NULL, NULL, NULL};
-  CheckedSmiComparisonSlowPath* slow_path = new CheckedSmiComparisonSlowPath(
-      this, env(), compiler->CurrentTryIndex(), labels,
-      /* merged = */ false);
-  compiler->AddSlowPathCode(slow_path);
-  EMIT_SMI_CHECK;
-  Condition true_condition = EmitComparisonCode(compiler, labels);
-  ASSERT(true_condition != kInvalidCondition);
-  Register result = locs()->out(0).reg();
-  __ LoadObject(result, Bool::True(), true_condition);
-  __ LoadObject(result, Bool::False(), InvertCondition(true_condition));
-  __ Bind(slow_path->exit_label());
-}
-#undef EMIT_SMI_CHECK
-
 LocationSummary* BinarySmiOpInstr::MakeLocationSummary(Zone* zone,
                                                        bool opt) const {
   const intptr_t kNumInputs = 2;
@@ -6087,6 +5718,8 @@
 }
 
 void CaseInsensitiveCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  ASSERT(TargetFunction().is_leaf());
+
   // Call the function.
   __ CallRuntime(TargetFunction(), TargetFunction().argument_count());
 }
@@ -6570,6 +6203,8 @@
 }
 
 void InvokeMathCFunctionInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  ASSERT(TargetFunction().is_leaf());
+
   if (recognized_kind() == MethodRecognizer::kMathDoublePow) {
     InvokeDoublePow(compiler, this);
     return;
@@ -7895,16 +7530,8 @@
 void BooleanNegateInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   const Register input = locs()->in(0).reg();
   const Register result = locs()->out(0).reg();
-
-  if (value()->Type()->ToCid() == kBoolCid) {
-    __ eor(
-        result, input,
-        compiler::Operand(compiler::target::ObjectAlignment::kBoolValueMask));
-  } else {
-    __ LoadObject(result, Bool::True());
-    __ cmp(result, compiler::Operand(input));
-    __ LoadObject(result, Bool::False(), EQ);
-  }
+  __ eor(result, input,
+         compiler::Operand(compiler::target::ObjectAlignment::kBoolValueMask));
 }
 
 LocationSummary* AllocateObjectInstr::MakeLocationSummary(Zone* zone,
@@ -7932,7 +7559,7 @@
   const Code& stub = Code::ZoneHandle(
       compiler->zone(), StubCode::GetAllocationStubForClass(cls()));
   compiler->GenerateStubCall(source(), stub, UntaggedPcDescriptors::kOther,
-                             locs());
+                             locs(), deopt_id());
 }
 
 void DebugStepCheckInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
diff --git a/runtime/vm/compiler/backend/il_arm64.cc b/runtime/vm/compiler/backend/il_arm64.cc
index 5f4a51c..3bab356 100644
--- a/runtime/vm/compiler/backend/il_arm64.cc
+++ b/runtime/vm/compiler/backend/il_arm64.cc
@@ -29,6 +29,9 @@
 
 namespace dart {
 
+DECLARE_FLAG(bool, inline_alloc);
+DECLARE_FLAG(bool, use_slow_path);
+
 // Generic summary for call instructions that have all arguments pushed
 // on the stack and return the result in a fixed register R0 (or V0 if
 // the return type is double).
@@ -93,14 +96,22 @@
     case kTagged:
     case kUnboxedInt64: {
       const auto out = locs()->out(0).reg();
+#if !defined(DART_COMPRESSED_POINTERS)
       __ add(out, base_reg(), compiler::Operand(index, LSL, 2));
+#else
+      __ add(out, base_reg(), compiler::Operand(index, SXTW, 2));
+#endif
       __ LoadFromOffset(out, out, offset());
       break;
     }
     case kUnboxedDouble: {
       const auto tmp = locs()->temp(0).reg();
       const auto out = locs()->out(0).fpu_reg();
+#if !defined(DART_COMPRESSED_POINTERS)
       __ add(tmp, base_reg(), compiler::Operand(index, LSL, 2));
+#else
+      __ add(tmp, base_reg(), compiler::Operand(index, SXTW, 2));
+#endif
       __ LoadDFromOffset(out, tmp, offset());
       break;
     }
@@ -114,7 +125,11 @@
                (NoLocation, Register index, Register value)) {
   ASSERT(instr->RequiredInputRepresentation(
              StoreIndexedUnsafeInstr::kIndexPos) == kTagged);  // It is a Smi.
+#if !defined(DART_COMPRESSED_POINTERS)
   __ add(TMP, instr->base_reg(), compiler::Operand(index, LSL, 2));
+#else
+  __ add(TMP, instr->base_reg(), compiler::Operand(index, SXTW, 2));
+#endif
   __ str(value, compiler::Address(TMP, instr->offset()));
 
   ASSERT(kSmiTag == 0);
@@ -485,16 +500,6 @@
   }
 }
 
-LocationSummary* DispatchTableCallInstr::MakeLocationSummary(Zone* zone,
-                                                             bool opt) const {
-  const intptr_t kNumInputs = 1;
-  const intptr_t kNumTemps = 0;
-  LocationSummary* summary = new (zone)
-      LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
-  summary->set_in(0, Location::RegisterLocation(R0));  // ClassId
-  return MakeCallSummary(zone, this, summary);
-}
-
 LocationSummary* ClosureCallInstr::MakeLocationSummary(Zone* zone,
                                                        bool opt) const {
   const intptr_t kNumInputs = 1;
@@ -516,8 +521,8 @@
   // R0: Function.
   ASSERT(locs()->in(0).reg() == R0);
   if (!FLAG_precompiled_mode || !FLAG_use_bare_instructions) {
-    __ LoadFieldFromOffset(CODE_REG, R0,
-                           compiler::target::Function::code_offset());
+    __ LoadCompressedFieldFromOffset(CODE_REG, R0,
+                                     compiler::target::Function::code_offset());
   }
   __ LoadFieldFromOffset(
       R2, R0, compiler::target::Function::entry_point_offset(entry_kind()));
@@ -720,7 +725,22 @@
   return summary;
 }
 
-static Condition TokenKindToSmiCondition(Token::Kind kind) {
+void AssertBooleanInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  ASSERT(locs()->always_calls());
+
+  auto object_store = compiler->isolate_group()->object_store();
+  const auto& assert_boolean_stub =
+      Code::ZoneHandle(compiler->zone(), object_store->assert_boolean_stub());
+
+  compiler::Label done;
+  __ tbnz(&done, AssertBooleanABI::kObjectReg, kBoolVsNullBitPosition);
+  compiler->GenerateStubCall(source(), assert_boolean_stub,
+                             /*kind=*/UntaggedPcDescriptors::kOther, locs(),
+                             deopt_id());
+  __ Bind(&done);
+}
+
+static Condition TokenKindToIntCondition(Token::Kind kind) {
   switch (kind) {
     case Token::kEQ:
       return EQ;
@@ -795,21 +815,22 @@
                                       Register rn,
                                       Condition cond,
                                       BranchLabels labels) {
-  return !AreLabelsNull(labels) && __ CanGenerateXCbzTbz(rn, cond);
+  return !AreLabelsNull(labels) && __ CanGenerateCbzTbz(rn, cond);
 }
 
 static void EmitCbzTbz(Register reg,
                        FlowGraphCompiler* compiler,
                        Condition true_condition,
-                       BranchLabels labels) {
+                       BranchLabels labels,
+                       compiler::OperandSize sz) {
   ASSERT(CanUseCbzTbzForComparison(compiler, reg, true_condition, labels));
   if (labels.fall_through == labels.false_label) {
     // If the next block is the false successor we will fall through to it.
-    __ GenerateXCbzTbz(reg, true_condition, labels.true_label);
+    __ GenerateCbzTbz(reg, true_condition, labels.true_label, sz);
   } else {
     // If the next block is not the false successor we will branch to it.
     Condition false_condition = InvertCondition(true_condition);
-    __ GenerateXCbzTbz(reg, false_condition, labels.false_label);
+    __ GenerateCbzTbz(reg, false_condition, labels.false_label, sz);
 
     // Fall through or jump to the true successor.
     if (labels.fall_through != labels.true_label) {
@@ -818,6 +839,44 @@
   }
 }
 
+static Condition EmitSmiComparisonOp(FlowGraphCompiler* compiler,
+                                     LocationSummary* locs,
+                                     Token::Kind kind,
+                                     BranchLabels labels) {
+  Location left = locs->in(0);
+  Location right = locs->in(1);
+  ASSERT(!left.IsConstant() || !right.IsConstant());
+
+  Condition true_condition = TokenKindToIntCondition(kind);
+  if (left.IsConstant() || right.IsConstant()) {
+    // Ensure constant is on the right.
+    ConstantInstr* constant = nullptr;
+    if (left.IsConstant()) {
+      constant = left.constant_instruction();
+      Location tmp = right;
+      right = left;
+      left = tmp;
+      true_condition = FlipCondition(true_condition);
+    } else {
+      constant = right.constant_instruction();
+    }
+
+    ASSERT(constant->representation() == kTagged);
+    int64_t value;
+    if (compiler::HasIntegerValue(constant->value(), &value) && (value == 0) &&
+        CanUseCbzTbzForComparison(compiler, left.reg(), true_condition,
+                                  labels)) {
+      EmitCbzTbz(left.reg(), compiler, true_condition, labels,
+                 compiler::kObjectBytes);
+      return kInvalidCondition;
+    }
+    __ CompareObject(left.reg(), right.constant());
+  } else {
+    __ CompareObjectRegisters(left.reg(), right.reg());
+  }
+  return true_condition;
+}
+
 // Similar to ComparisonInstr::EmitComparisonCode, may either:
 //   - emit comparison code and return a valid condition in which case the
 //     caller is expected to emit a branch to the true label based on that
@@ -832,7 +891,7 @@
   Location right = locs->in(1);
   ASSERT(!left.IsConstant() || !right.IsConstant());
 
-  Condition true_condition = TokenKindToSmiCondition(kind);
+  Condition true_condition = TokenKindToIntCondition(kind);
   if (left.IsConstant() || right.IsConstant()) {
     // Ensure constant is on the right.
     ConstantInstr* constant = nullptr;
@@ -852,13 +911,13 @@
       RELEASE_ASSERT(ok);
       if (value == 0 && CanUseCbzTbzForComparison(compiler, left.reg(),
                                                   true_condition, labels)) {
-        EmitCbzTbz(left.reg(), compiler, true_condition, labels);
+        EmitCbzTbz(left.reg(), compiler, true_condition, labels,
+                   compiler::kEightBytes);
         return kInvalidCondition;
       }
       __ CompareImmediate(left.reg(), value);
     } else {
-      ASSERT(constant->representation() == kTagged);
-      __ CompareObject(left.reg(), right.constant());
+      UNREACHABLE();
     }
   } else {
     __ CompareRegisters(left.reg(), right.reg());
@@ -866,6 +925,35 @@
   return true_condition;
 }
 
+static Condition EmitNullAwareInt64ComparisonOp(FlowGraphCompiler* compiler,
+                                                LocationSummary* locs,
+                                                Token::Kind kind,
+                                                BranchLabels labels) {
+  ASSERT((kind == Token::kEQ) || (kind == Token::kNE));
+  const Register left = locs->in(0).reg();
+  const Register right = locs->in(1).reg();
+  const Condition true_condition = TokenKindToIntCondition(kind);
+  compiler::Label* equal_result =
+      (true_condition == EQ) ? labels.true_label : labels.false_label;
+  compiler::Label* not_equal_result =
+      (true_condition == EQ) ? labels.false_label : labels.true_label;
+
+  // Check if operands have the same value. If they don't, then they could
+  // be equal only if both of them are Mints with the same value.
+  __ CompareObjectRegisters(left, right);
+  __ b(equal_result, EQ);
+  __ and_(TMP, left, compiler::Operand(right), compiler::kObjectBytes);
+  __ BranchIfSmi(TMP, not_equal_result);
+  __ CompareClassId(left, kMintCid);
+  __ b(not_equal_result, NE);
+  __ CompareClassId(right, kMintCid);
+  __ b(not_equal_result, NE);
+  __ LoadFieldFromOffset(TMP, left, Mint::value_offset());
+  __ LoadFieldFromOffset(TMP2, right, Mint::value_offset());
+  __ CompareRegisters(TMP, TMP2);
+  return true_condition;
+}
+
 LocationSummary* EqualityCompareInstr::MakeLocationSummary(Zone* zone,
                                                            bool opt) const {
   const intptr_t kNumInputs = 2;
@@ -882,13 +970,18 @@
     const intptr_t kNumTemps = 0;
     LocationSummary* locs = new (zone)
         LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
-    locs->set_in(0, LocationRegisterOrConstant(left()));
-    // Only one input can be a constant operand. The case of two constant
-    // operands should be handled by constant propagation.
-    // Only right can be a stack slot.
-    locs->set_in(1, locs->in(0).IsConstant()
-                        ? Location::RequiresRegister()
-                        : LocationRegisterOrConstant(right()));
+    if (is_null_aware()) {
+      locs->set_in(0, Location::RequiresRegister());
+      locs->set_in(1, Location::RequiresRegister());
+    } else {
+      locs->set_in(0, LocationRegisterOrConstant(left()));
+      // Only one input can be a constant operand. The case of two constant
+      // operands should be handled by constant propagation.
+      // Only right can be a stack slot.
+      locs->set_in(1, locs->in(0).IsConstant()
+                          ? Location::RequiresRegister()
+                          : LocationRegisterOrConstant(right()));
+    }
     locs->set_out(0, Location::RequiresRegister());
     return locs;
   }
@@ -934,7 +1027,13 @@
 
 Condition EqualityCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
                                                    BranchLabels labels) {
-  if (operation_cid() == kSmiCid || operation_cid() == kMintCid) {
+  if (is_null_aware()) {
+    ASSERT(operation_cid() == kMintCid);
+    return EmitNullAwareInt64ComparisonOp(compiler, locs(), kind(), labels);
+  }
+  if (operation_cid() == kSmiCid) {
+    return EmitSmiComparisonOp(compiler, locs(), kind(), labels);
+  } else if (operation_cid() == kMintCid) {
     return EmitInt64ComparisonOp(compiler, locs(), kind(), labels);
   } else {
     ASSERT(operation_cid() == kDoubleCid);
@@ -961,9 +1060,9 @@
   if (right.IsConstant()) {
     ASSERT(right.constant().IsSmi());
     const int64_t imm = static_cast<int64_t>(right.constant().ptr());
-    __ TestImmediate(left, imm);
+    __ TestImmediate(left, imm, compiler::kObjectBytes);
   } else {
-    __ tst(left, compiler::Operand(right.reg()));
+    __ tst(left, compiler::Operand(right.reg()), compiler::kObjectBytes);
   }
   Condition true_condition = (kind() == Token::kNE) ? NE : EQ;
   return true_condition;
@@ -1055,7 +1154,9 @@
 
 Condition RelationalOpInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
                                                 BranchLabels labels) {
-  if (operation_cid() == kSmiCid || operation_cid() == kMintCid) {
+  if (operation_cid() == kSmiCid) {
+    return EmitSmiComparisonOp(compiler, locs(), kind(), labels);
+  } else if (operation_cid() == kMintCid) {
     return EmitInt64ComparisonOp(compiler, locs(), kind(), labels);
   } else {
     ASSERT(operation_cid() == kDoubleCid);
@@ -1410,7 +1511,8 @@
   ASSERT(cid_ == kOneByteStringCid);
   const Register str = locs()->in(0).reg();
   const Register result = locs()->out(0).reg();
-  __ LoadFieldFromOffset(result, str, String::length_offset());
+  __ LoadCompressedSmi(result,
+                       compiler::FieldAddress(str, String::length_offset()));
   __ ldr(TMP,
          compiler::FieldAddress(str, OneByteString::data_offset(),
                                 compiler::kByte),
@@ -2251,8 +2353,9 @@
            compiler::FieldAddress(
                field_reg, Field::guarded_list_length_in_object_offset_offset()),
            compiler::kByte);
-    __ ldr(length_reg, compiler::FieldAddress(
-                           field_reg, Field::guarded_list_length_offset()));
+    __ LoadCompressed(
+        length_reg,
+        compiler::FieldAddress(field_reg, Field::guarded_list_length_offset()));
 
     __ tst(offset_reg, compiler::Operand(offset_reg));
     __ b(&ok, MI);
@@ -2262,7 +2365,7 @@
     // offset_reg contains offset already corrected by -kHeapObjectTag that is
     // why we use Address instead of FieldAddress.
     __ ldr(TMP, compiler::Address(value_reg, offset_reg));
-    __ CompareRegisters(length_reg, TMP);
+    __ CompareObjectRegisters(length_reg, TMP);
 
     if (deopt == NULL) {
       __ b(&ok, EQ);
@@ -2563,18 +2666,34 @@
     __ Bind(&store_pointer);
   }
 
+  const bool compressed = slot().is_compressed();
   if (ShouldEmitStoreBarrier()) {
     const Register value_reg = locs()->in(1).reg();
-    __ StoreIntoObjectOffset(instance_reg, offset_in_bytes, value_reg,
-                             CanValueBeSmi());
+    if (!compressed) {
+      __ StoreIntoObjectOffset(instance_reg, offset_in_bytes, value_reg,
+                               CanValueBeSmi());
+    } else {
+      __ StoreCompressedIntoObjectOffset(instance_reg, offset_in_bytes,
+                                         value_reg, CanValueBeSmi());
+    }
   } else {
     if (locs()->in(1).IsConstant()) {
-      __ StoreIntoObjectOffsetNoBarrier(instance_reg, offset_in_bytes,
-                                        locs()->in(1).constant());
+      if (!compressed) {
+        __ StoreIntoObjectOffsetNoBarrier(instance_reg, offset_in_bytes,
+                                          locs()->in(1).constant());
+      } else {
+        __ StoreCompressedIntoObjectOffsetNoBarrier(
+            instance_reg, offset_in_bytes, locs()->in(1).constant());
+      }
     } else {
       const Register value_reg = locs()->in(1).reg();
-      __ StoreIntoObjectOffsetNoBarrier(instance_reg, offset_in_bytes,
-                                        value_reg);
+      if (!compressed) {
+        __ StoreIntoObjectOffsetNoBarrier(instance_reg, offset_in_bytes,
+                                          value_reg);
+      } else {
+        __ StoreCompressedIntoObjectOffsetNoBarrier(instance_reg,
+                                                    offset_in_bytes, value_reg);
+      }
     }
   }
   __ Bind(&skip_store);
@@ -2714,12 +2833,15 @@
   ASSERT(locs()->in(kLengthPos).reg() == kLengthReg);
 
   compiler::Label slow_path, done;
-  if (compiler->is_optimizing() && !FLAG_precompiled_mode &&
-      num_elements()->BindsToConstant() &&
-      num_elements()->BoundConstant().IsSmi()) {
-    const intptr_t length = Smi::Cast(num_elements()->BoundConstant()).Value();
-    if (Array::IsValidLength(length)) {
-      InlineArrayAllocation(compiler, length, &slow_path, &done);
+  if (!FLAG_use_slow_path && FLAG_inline_alloc) {
+    if (compiler->is_optimizing() && !FLAG_precompiled_mode &&
+        num_elements()->BindsToConstant() &&
+        num_elements()->BoundConstant().IsSmi()) {
+      const intptr_t length =
+          Smi::Cast(num_elements()->BoundConstant()).Value();
+      if (Array::IsValidLength(length)) {
+        InlineArrayAllocation(compiler, length, &slow_path, &done);
+      }
     }
   }
 
@@ -2950,7 +3072,11 @@
     __ Bind(&load_pointer);
   }
 
-  __ LoadFieldFromOffset(result_reg, instance_reg, OffsetInBytes());
+  if (slot().is_compressed()) {
+    __ LoadCompressedFieldFromOffset(result_reg, instance_reg, OffsetInBytes());
+  } else {
+    __ LoadFieldFromOffset(result_reg, instance_reg, OffsetInBytes());
+  }
 
   if (calls_initializer()) {
     EmitNativeCodeForInitializerCall(compiler);
@@ -2959,104 +3085,6 @@
   __ Bind(&done);
 }
 
-LocationSummary* InstantiateTypeInstr::MakeLocationSummary(Zone* zone,
-                                                           bool opt) const {
-  const intptr_t kNumInputs = 2;
-  const intptr_t kNumTemps = 0;
-  LocationSummary* locs = new (zone)
-      LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
-  locs->set_in(0, Location::RegisterLocation(
-                      InstantiationABI::kInstantiatorTypeArgumentsReg));
-  locs->set_in(1, Location::RegisterLocation(
-                      InstantiationABI::kFunctionTypeArgumentsReg));
-  locs->set_out(0,
-                Location::RegisterLocation(InstantiationABI::kResultTypeReg));
-  return locs;
-}
-
-void InstantiateTypeInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  const Register instantiator_type_args_reg = locs()->in(0).reg();
-  const Register function_type_args_reg = locs()->in(1).reg();
-  const Register result_reg = locs()->out(0).reg();
-
-  // 'instantiator_type_args_reg' is a TypeArguments object (or null).
-  // 'function_type_args_reg' is a TypeArguments object (or null).
-  // A runtime call to instantiate the type is required.
-  __ LoadObject(TMP, type());
-  __ PushPair(TMP, NULL_REG);
-  __ PushPair(function_type_args_reg, instantiator_type_args_reg);
-  compiler->GenerateRuntimeCall(source(), deopt_id(),
-                                kInstantiateTypeRuntimeEntry, 3, locs());
-  __ Drop(3);          // Drop 2 type vectors, and uninstantiated type.
-  __ Pop(result_reg);  // Pop instantiated type.
-}
-
-LocationSummary* InstantiateTypeArgumentsInstr::MakeLocationSummary(
-    Zone* zone,
-    bool opt) const {
-  const intptr_t kNumInputs = 3;
-  const intptr_t kNumTemps = 0;
-  LocationSummary* locs = new (zone)
-      LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
-  locs->set_in(0, Location::RegisterLocation(
-                      InstantiationABI::kInstantiatorTypeArgumentsReg));
-  locs->set_in(1, Location::RegisterLocation(
-                      InstantiationABI::kFunctionTypeArgumentsReg));
-  locs->set_in(2, Location::RegisterLocation(
-                      InstantiationABI::kUninstantiatedTypeArgumentsReg));
-  locs->set_out(
-      0, Location::RegisterLocation(InstantiationABI::kResultTypeArgumentsReg));
-  return locs;
-}
-
-void InstantiateTypeArgumentsInstr::EmitNativeCode(
-    FlowGraphCompiler* compiler) {
-  // We should never try and instantiate a TAV known at compile time to be null,
-  // so we can use a null value below for the dynamic case.
-  ASSERT(!type_arguments()->BindsToConstant() ||
-         !type_arguments()->BoundConstant().IsNull());
-  const auto& type_args =
-      type_arguments()->BindsToConstant()
-          ? TypeArguments::Cast(type_arguments()->BoundConstant())
-          : Object::null_type_arguments();
-  const intptr_t len = type_args.Length();
-  const bool can_function_type_args_be_null =
-      function_type_arguments()->CanBe(Object::null_object());
-
-  compiler::Label type_arguments_instantiated;
-  if (type_args.IsNull()) {
-    // Currently we only create dynamic InstantiateTypeArguments instructions
-    // in cases where we know the type argument is uninstantiated at runtime,
-    // so there are no extra checks needed to call the stub successfully.
-  } else if (type_args.IsRawWhenInstantiatedFromRaw(len) &&
-             can_function_type_args_be_null) {
-    // If both the instantiator and function type arguments are null and if the
-    // type argument vector instantiated from null becomes a vector of dynamic,
-    // then use null as the type arguments.
-    compiler::Label non_null_type_args;
-    // 'instantiator_type_args_reg' is a TypeArguments object (or null).
-    // 'function_type_args_reg' is a TypeArguments object (or null).
-    const Register instantiator_type_args_reg = locs()->in(0).reg();
-    const Register function_type_args_reg = locs()->in(1).reg();
-    const Register result_reg = locs()->out(0).reg();
-    ASSERT(result_reg != instantiator_type_args_reg &&
-           result_reg != function_type_args_reg);
-    __ LoadObject(result_reg, Object::null_object());
-    __ CompareRegisters(instantiator_type_args_reg, result_reg);
-    if (!function_type_arguments()->BindsToConstant()) {
-      __ b(&non_null_type_args, NE);
-      __ CompareRegisters(function_type_args_reg, result_reg);
-    }
-    __ b(&type_arguments_instantiated, EQ);
-    __ Bind(&non_null_type_args);
-  }
-  // Lookup cache in stub before calling runtime.
-
-  compiler->GenerateStubCall(source(), GetStub(), UntaggedPcDescriptors::kOther,
-                             locs());
-  __ Bind(&type_arguments_instantiated);
-}
-
 LocationSummary* AllocateUninitializedContextInstr::MakeLocationSummary(
     Zone* zone,
     bool opt) const {
@@ -3088,13 +3116,18 @@
 
     compiler->SaveLiveRegisters(locs);
 
+    auto slow_path_env = compiler->SlowPathEnvironmentFor(
+        instruction(), /*num_slow_path_args=*/0);
+    ASSERT(slow_path_env != nullptr);
+
     auto object_store = compiler->isolate_group()->object_store();
     const auto& allocate_context_stub = Code::ZoneHandle(
         compiler->zone(), object_store->allocate_context_stub());
 
     __ LoadImmediate(R1, instruction()->num_context_variables());
     compiler->GenerateStubCall(instruction()->source(), allocate_context_stub,
-                               UntaggedPcDescriptors::kOther, locs);
+                               UntaggedPcDescriptors::kOther, locs,
+                               instruction()->deopt_id(), slow_path_env);
     ASSERT(instruction()->locs()->out(0).reg() == R0);
     compiler->RestoreLiveRegisters(instruction()->locs());
     __ b(exit_label());
@@ -3112,14 +3145,18 @@
   compiler->AddSlowPathCode(slow_path);
   intptr_t instance_size = Context::InstanceSize(num_context_variables());
 
-  __ TryAllocateArray(kContextCid, instance_size, slow_path->entry_label(),
-                      result,  // instance
-                      temp0, temp1, temp2);
+  if (!FLAG_use_slow_path && FLAG_inline_alloc) {
+    __ TryAllocateArray(kContextCid, instance_size, slow_path->entry_label(),
+                        result,  // instance
+                        temp0, temp1, temp2);
 
-  // Setup up number of context variables field.
-  __ LoadImmediate(temp0, num_context_variables());
-  __ str(temp0,
-         compiler::FieldAddress(result, Context::num_variables_offset()));
+    // Setup up number of context variables field.
+    __ LoadImmediate(temp0, num_context_variables());
+    __ str(temp0,
+           compiler::FieldAddress(result, Context::num_variables_offset()));
+  } else {
+    __ Jump(slow_path->entry_label());
+  }
 
   __ Bind(slow_path->exit_label());
 }
@@ -3144,7 +3181,7 @@
       Code::ZoneHandle(compiler->zone(), object_store->allocate_context_stub());
   __ LoadImmediate(R1, num_context_variables());
   compiler->GenerateStubCall(source(), allocate_context_stub,
-                             UntaggedPcDescriptors::kOther, locs());
+                             UntaggedPcDescriptors::kOther, locs(), deopt_id());
 }
 
 LocationSummary* CloneContextInstr::MakeLocationSummary(Zone* zone,
@@ -3166,7 +3203,8 @@
   const auto& clone_context_stub =
       Code::ZoneHandle(compiler->zone(), object_store->clone_context_stub());
   compiler->GenerateStubCall(source(), clone_context_stub,
-                             /*kind=*/UntaggedPcDescriptors::kOther, locs());
+                             /*kind=*/UntaggedPcDescriptors::kOther, locs(),
+                             deopt_id());
 }
 
 LocationSummary* CatchBlockEntryInstr::MakeLocationSummary(Zone* zone,
@@ -3368,20 +3406,12 @@
     ASSERT((0 < value) && (value < kCountLimit));
     if (shift_left->can_overflow()) {
       // Check for overflow (preserve left).
-#if !defined(DART_COMPRESSED_POINTERS)
-      __ LslImmediate(TMP, left, value);
-      __ cmp(left, compiler::Operand(TMP, ASR, value));
-#else
-      __ LslImmediate(TMP, left, value, compiler::kFourBytes);
-      __ cmpw(left, compiler::Operand(TMP, ASR, value));
-#endif
+      __ LslImmediate(TMP, left, value, compiler::kObjectBytes);
+      __ cmp(left, compiler::Operand(TMP, ASR, value), compiler::kObjectBytes);
       __ b(deopt, NE);  // Overflow.
     }
     // Shift for result now we know there is no overflow.
-    __ LslImmediate(result, left, value);
-#if defined(DART_COMPRESSED_POINTERS)
-    __ sxtw(result, result);
-#endif
+    __ LslImmediate(result, left, value, compiler::kObjectBytes);
     return;
   }
 
@@ -3395,7 +3425,7 @@
     if (obj.IsSmi()) {
       const intptr_t left_int = Smi::Cast(obj).Value();
       if (left_int == 0) {
-        __ CompareRegisters(right, ZR);
+        __ CompareObjectRegisters(right, ZR);
         __ b(deopt, MI);
         __ mov(result, ZR);
         return;
@@ -3405,14 +3435,11 @@
       const bool right_needs_check =
           !RangeUtils::IsWithin(right_range, 0, max_right - 1);
       if (right_needs_check) {
-        __ CompareImmediate(right, static_cast<int64_t>(Smi::New(max_right)));
+        __ CompareObject(right, Smi::ZoneHandle(Smi::New(max_right)));
         __ b(deopt, CS);
       }
       __ SmiUntag(TMP, right);
-      __ lslv(result, left, TMP);
-#if defined(DART_COMPRESSED_POINTERS)
-      __ sxtw(result, result);
-#endif
+      __ lslv(result, left, TMP, compiler::kObjectBytes);
     }
     return;
   }
@@ -3423,23 +3450,23 @@
     if (right_needs_check) {
       if (!RangeUtils::IsPositive(right_range)) {
         ASSERT(shift_left->CanDeoptimize());
-        __ CompareRegisters(right, ZR);
+        __ CompareObjectRegisters(right, ZR);
         __ b(deopt, MI);
       }
 
-      __ CompareImmediate(right, static_cast<int64_t>(Smi::New(Smi::kBits)));
+      __ CompareObject(right, Smi::ZoneHandle(Smi::New(Smi::kBits)));
       __ csel(result, ZR, result, CS);
       __ SmiUntag(TMP, right);
-      __ lslv(TMP, left, TMP);
+      __ lslv(TMP, left, TMP, compiler::kObjectBytes);
       __ csel(result, TMP, result, CC);
     } else {
       __ SmiUntag(TMP, right);
-      __ lslv(result, left, TMP);
+      __ lslv(result, left, TMP, compiler::kObjectBytes);
     }
   } else {
     if (right_needs_check) {
       ASSERT(shift_left->CanDeoptimize());
-      __ CompareImmediate(right, static_cast<int64_t>(Smi::New(Smi::kBits)));
+      __ CompareObject(right, Smi::ZoneHandle(Smi::New(Smi::kBits)));
       __ b(deopt, CS);
     }
     // Left is not a constant.
@@ -3447,330 +3474,12 @@
     __ SmiUntag(TMP, right);
     // Overflow test (preserve left, right, and TMP);
     const Register temp = locs.temp(0).reg();
-#if !defined(DART_COMPRESSED_POINTERS)
-    __ lslv(temp, left, TMP);
-    __ asrv(TMP2, temp, TMP);
-    __ CompareRegisters(left, TMP2);
-#else
-    __ lslvw(temp, left, TMP);
-    __ asrvw(TMP2, temp, TMP);
-    __ cmpw(left, compiler::Operand(TMP2));
-#endif
+    __ lslv(temp, left, TMP, compiler::kObjectBytes);
+    __ asrv(TMP2, temp, TMP, compiler::kObjectBytes);
+    __ cmp(left, compiler::Operand(TMP2), compiler::kObjectBytes);
     __ b(deopt, NE);  // Overflow.
     // Shift for result now we know there is no overflow.
-    __ lslv(result, left, TMP);
-  }
-}
-
-class CheckedSmiSlowPath : public TemplateSlowPathCode<CheckedSmiOpInstr> {
- public:
-  static constexpr intptr_t kNumSlowPathArgs = 2;
-
-  CheckedSmiSlowPath(CheckedSmiOpInstr* instruction, intptr_t try_index)
-      : TemplateSlowPathCode(instruction), try_index_(try_index) {}
-
-  virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
-    if (compiler::Assembler::EmittingComments()) {
-      __ Comment("slow path smi operation");
-    }
-    __ Bind(entry_label());
-    LocationSummary* locs = instruction()->locs();
-    Register result = locs->out(0).reg();
-    locs->live_registers()->Remove(Location::RegisterLocation(result));
-
-    compiler->SaveLiveRegisters(locs);
-    if (instruction()->env() != NULL) {
-      Environment* env =
-          compiler->SlowPathEnvironmentFor(instruction(), kNumSlowPathArgs);
-      compiler->pending_deoptimization_env_ = env;
-    }
-    __ PushPair(locs->in(1).reg(), locs->in(0).reg());
-    const auto& selector = String::Handle(instruction()->call()->Selector());
-    const auto& arguments_descriptor =
-        Array::Handle(ArgumentsDescriptor::NewBoxed(
-            /*type_args_len=*/0, /*num_arguments=*/2));
-    compiler->EmitMegamorphicInstanceCall(
-        selector, arguments_descriptor, instruction()->call()->deopt_id(),
-        instruction()->source(), locs, try_index_, kNumSlowPathArgs);
-    __ mov(result, R0);
-    compiler->RestoreLiveRegisters(locs);
-    __ b(exit_label());
-    compiler->pending_deoptimization_env_ = NULL;
-  }
-
- private:
-  intptr_t try_index_;
-};
-
-LocationSummary* CheckedSmiOpInstr::MakeLocationSummary(Zone* zone,
-                                                        bool opt) const {
-  const intptr_t kNumInputs = 2;
-  const intptr_t kNumTemps = 0;
-  LocationSummary* summary = new (zone) LocationSummary(
-      zone, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath);
-  summary->set_in(0, Location::RequiresRegister());
-  summary->set_in(1, Location::RequiresRegister());
-  summary->set_out(0, Location::RequiresRegister());
-  return summary;
-}
-
-void CheckedSmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  CheckedSmiSlowPath* slow_path =
-      new CheckedSmiSlowPath(this, compiler->CurrentTryIndex());
-  compiler->AddSlowPathCode(slow_path);
-  // Test operands if necessary.
-  Register left = locs()->in(0).reg();
-  Register right = locs()->in(1).reg();
-  Register result = locs()->out(0).reg();
-  intptr_t left_cid = this->left()->Type()->ToCid();
-  intptr_t right_cid = this->right()->Type()->ToCid();
-  bool combined_smi_check = false;
-  if (this->left()->definition() == this->right()->definition()) {
-    __ BranchIfNotSmi(left, slow_path->entry_label());
-  } else if (left_cid == kSmiCid) {
-    __ BranchIfNotSmi(right, slow_path->entry_label());
-  } else if (right_cid == kSmiCid) {
-    __ BranchIfNotSmi(left, slow_path->entry_label());
-  } else {
-    combined_smi_check = true;
-    __ orr(result, left, compiler::Operand(right));
-    __ BranchIfNotSmi(result, slow_path->entry_label());
-  }
-
-  switch (op_kind()) {
-    case Token::kADD:
-#if !defined(DART_COMPRESSED_POINTERS)
-      __ adds(result, left, compiler::Operand(right));
-#else
-      __ addsw(result, left, compiler::Operand(right));
-      __ sxtw(result, result);
-#endif
-      __ b(slow_path->entry_label(), VS);
-      break;
-    case Token::kSUB:
-#if !defined(DART_COMPRESSED_POINTERS)
-      __ subs(result, left, compiler::Operand(right));
-#else
-      __ subsw(result, left, compiler::Operand(right));
-      __ sxtw(result, result);
-#endif
-      __ b(slow_path->entry_label(), VS);
-      break;
-    case Token::kMUL:
-      __ SmiUntag(TMP, left);
-#if !defined(DART_COMPRESSED_POINTERS)
-      __ mul(result, TMP, right);
-      __ smulh(TMP, TMP, right);
-      // TMP: result bits 64..127.
-#else
-      __ smull(result, TMP, right);
-      __ AsrImmediate(TMP, result, 31);
-      // TMP: result bits 32..63.
-#endif
-      __ cmp(TMP, compiler::Operand(result, ASR, 63));
-      __ b(slow_path->entry_label(), NE);
-      break;
-    case Token::kBIT_OR:
-      // Operation may be part of combined smi check.
-      if (!combined_smi_check) {
-        __ orr(result, left, compiler::Operand(right));
-      }
-      break;
-    case Token::kBIT_AND:
-      __ and_(result, left, compiler::Operand(right));
-      break;
-    case Token::kBIT_XOR:
-      __ eor(result, left, compiler::Operand(right));
-      break;
-    case Token::kSHL:
-      ASSERT(result != left);
-      ASSERT(result != right);
-      __ CompareImmediate(right, static_cast<int64_t>(Smi::New(Smi::kBits)));
-      __ b(slow_path->entry_label(), CS);
-
-      __ SmiUntag(TMP, right);
-      __ lslv(result, left, TMP);
-#if !defined(DART_COMPRESSED_POINTERS)
-      __ asrv(TMP2, result, TMP);
-      __ CompareRegisters(left, TMP2);
-#else
-      __ asrvw(TMP2, result, TMP);
-      __ cmp(left, compiler::Operand(TMP2, SXTW, 0));
-#endif
-      __ b(slow_path->entry_label(), NE);  // Overflow.
-      break;
-    case Token::kSHR:
-    case Token::kUSHR:
-      ASSERT(result != left);
-      ASSERT(result != right);
-      __ CompareImmediate(right, static_cast<int64_t>(Smi::New(kBitsPerInt64)));
-      __ b(slow_path->entry_label(), UNSIGNED_GREATER_EQUAL);
-
-      __ SmiUntag(result, right);
-      __ SmiUntag(TMP, left);
-      if (op_kind() == Token::kSHR) {
-        __ asrv(result, TMP, result);
-        __ SmiTag(result);
-      } else {
-        ASSERT(op_kind() == Token::kUSHR);
-        __ lsrv(result, TMP, result);
-        __ SmiTagAndBranchIfOverflow(result, slow_path->entry_label());
-      }
-      break;
-    default:
-      UNIMPLEMENTED();
-  }
-  __ Bind(slow_path->exit_label());
-}
-
-class CheckedSmiComparisonSlowPath
-    : public TemplateSlowPathCode<CheckedSmiComparisonInstr> {
- public:
-  static constexpr intptr_t kNumSlowPathArgs = 2;
-
-  CheckedSmiComparisonSlowPath(CheckedSmiComparisonInstr* instruction,
-                               Environment* env,
-                               intptr_t try_index,
-                               BranchLabels labels,
-                               bool merged)
-      : TemplateSlowPathCode(instruction),
-        try_index_(try_index),
-        labels_(labels),
-        merged_(merged),
-        env_(env) {
-    // The environment must either come from the comparison or the environment
-    // was cleared from the comparison (and moved to a branch).
-    ASSERT(env == instruction->env() ||
-           (merged && instruction->env() == nullptr));
-  }
-
-  virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
-    if (compiler::Assembler::EmittingComments()) {
-      __ Comment("slow path smi operation");
-    }
-    __ Bind(entry_label());
-    LocationSummary* locs = instruction()->locs();
-    Register result = merged_ ? locs->temp(0).reg() : locs->out(0).reg();
-    locs->live_registers()->Remove(Location::RegisterLocation(result));
-
-    compiler->SaveLiveRegisters(locs);
-    if (env_ != nullptr) {
-      compiler->pending_deoptimization_env_ =
-          compiler->SlowPathEnvironmentFor(env_, locs, kNumSlowPathArgs);
-    }
-    __ PushPair(locs->in(1).reg(), locs->in(0).reg());
-    const auto& selector = String::Handle(instruction()->call()->Selector());
-    const auto& arguments_descriptor =
-        Array::Handle(ArgumentsDescriptor::NewBoxed(
-            /*type_args_len=*/0, /*num_arguments=*/2));
-    compiler->EmitMegamorphicInstanceCall(
-        selector, arguments_descriptor, instruction()->call()->deopt_id(),
-        instruction()->source(), locs, try_index_, kNumSlowPathArgs);
-    __ mov(result, R0);
-    compiler->RestoreLiveRegisters(locs);
-    compiler->pending_deoptimization_env_ = nullptr;
-    if (merged_) {
-      __ CompareObject(result, Bool::True());
-      __ b(instruction()->is_negated() ? labels_.false_label
-                                       : labels_.true_label,
-           EQ);
-      __ b(instruction()->is_negated() ? labels_.true_label
-                                       : labels_.false_label);
-      ASSERT(exit_label()->IsUnused());
-    } else {
-      ASSERT(!instruction()->is_negated());
-      __ b(exit_label());
-    }
-  }
-
- private:
-  intptr_t try_index_;
-  BranchLabels labels_;
-  bool merged_;
-  Environment* env_;
-};
-
-LocationSummary* CheckedSmiComparisonInstr::MakeLocationSummary(
-    Zone* zone,
-    bool opt) const {
-  const intptr_t kNumInputs = 2;
-  const intptr_t kNumTemps = 1;
-  LocationSummary* summary = new (zone) LocationSummary(
-      zone, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath);
-  summary->set_in(0, Location::RequiresRegister());
-  summary->set_in(1, Location::RequiresRegister());
-  summary->set_temp(0, Location::RequiresRegister());
-  summary->set_out(0, Location::RequiresRegister());
-  return summary;
-}
-
-Condition CheckedSmiComparisonInstr::EmitComparisonCode(
-    FlowGraphCompiler* compiler,
-    BranchLabels labels) {
-  return EmitInt64ComparisonOp(compiler, locs(), kind(), labels);
-}
-
-#define EMIT_SMI_CHECK                                                         \
-  Register left = locs()->in(0).reg();                                         \
-  Register right = locs()->in(1).reg();                                        \
-  Register temp = locs()->temp(0).reg();                                       \
-  intptr_t left_cid = this->left()->Type()->ToCid();                           \
-  intptr_t right_cid = this->right()->Type()->ToCid();                         \
-  if (this->left()->definition() == this->right()->definition()) {             \
-    __ BranchIfNotSmi(left, slow_path->entry_label());                         \
-  } else if (left_cid == kSmiCid) {                                            \
-    __ BranchIfNotSmi(right, slow_path->entry_label());                        \
-  } else if (right_cid == kSmiCid) {                                           \
-    __ BranchIfNotSmi(left, slow_path->entry_label());                         \
-  } else {                                                                     \
-    __ orr(temp, left, compiler::Operand(right));                              \
-    __ BranchIfNotSmi(temp, slow_path->entry_label());                         \
-  }
-
-void CheckedSmiComparisonInstr::EmitBranchCode(FlowGraphCompiler* compiler,
-                                               BranchInstr* branch) {
-  BranchLabels labels = compiler->CreateBranchLabels(branch);
-  CheckedSmiComparisonSlowPath* slow_path = new CheckedSmiComparisonSlowPath(
-      this, branch->env(), compiler->CurrentTryIndex(), labels,
-      /* merged = */ true);
-  compiler->AddSlowPathCode(slow_path);
-  EMIT_SMI_CHECK;
-  Condition true_condition = EmitComparisonCode(compiler, labels);
-  if (true_condition != kInvalidCondition) {
-    EmitBranchOnCondition(compiler, true_condition, labels);
-  }
-  // No need to bind slow_path->exit_label() as slow path exits through
-  // true/false branch labels.
-}
-
-void CheckedSmiComparisonInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  // Zone-allocate labels to pass them to slow-path which outlives local scope.
-  compiler::Label* true_label = new (Z) compiler::Label();
-  compiler::Label* false_label = new (Z) compiler::Label();
-  compiler::Label done;
-  BranchLabels labels = {true_label, false_label, false_label};
-  // In case of negated comparison result of a slow path call should be negated.
-  // For this purpose, 'merged' slow path is generated: it tests
-  // result of a call and jumps directly to true or false label.
-  CheckedSmiComparisonSlowPath* slow_path = new CheckedSmiComparisonSlowPath(
-      this, env(), compiler->CurrentTryIndex(), labels,
-      /* merged = */ is_negated());
-  compiler->AddSlowPathCode(slow_path);
-  EMIT_SMI_CHECK;
-  Condition true_condition = EmitComparisonCode(compiler, labels);
-  if (true_condition != kInvalidCondition) {
-    EmitBranchOnCondition(compiler, true_condition, labels);
-  }
-  Register result = locs()->out(0).reg();
-  __ Bind(false_label);
-  __ LoadObject(result, Bool::False());
-  __ b(&done);
-  __ Bind(true_label);
-  __ LoadObject(result, Bool::True());
-  __ Bind(&done);
-  // In case of negated comparison slow path exits through true/false labels.
-  if (!is_negated()) {
-    __ Bind(slow_path->exit_label());
+    __ lslv(result, left, TMP, compiler::kObjectBytes);
   }
 }
 
@@ -3833,37 +3542,21 @@
     switch (op_kind()) {
       case Token::kADD: {
         if (deopt == NULL) {
-          // When we can't overflow, prefer 64-bit op to 32-bit op followed by
-          // sign extension.
-          __ AddImmediate(result, left, imm);
+          __ AddImmediate(result, left, imm, compiler::kObjectBytes);
         } else {
-#if !defined(DART_COMPRESSED_POINTERS)
-          __ AddImmediateSetFlags(result, left, imm);
+          __ AddImmediateSetFlags(result, left, imm, compiler::kObjectBytes);
           __ b(deopt, VS);
-#else
-          __ AddImmediateSetFlags(result, left, imm, compiler::kFourBytes);
-          __ b(deopt, VS);
-          __ sxtw(result, result);
-#endif
         }
         break;
       }
       case Token::kSUB: {
         if (deopt == NULL) {
-          // When we can't overflow, prefer 64-bit op to 32-bit op followed by
-          // sign extension.
           __ AddImmediate(result, left, -imm);
         } else {
           // Negating imm and using AddImmediateSetFlags would not detect the
           // overflow when imm == kMinInt64.
-#if !defined(DART_COMPRESSED_POINTERS)
-          __ SubImmediateSetFlags(result, left, imm);
+          __ SubImmediateSetFlags(result, left, imm, compiler::kObjectBytes);
           __ b(deopt, VS);
-#else
-          __ SubImmediateSetFlags(result, left, imm, compiler::kFourBytes);
-          __ b(deopt, VS);
-          __ sxtw(result, result);
-#endif
         }
         break;
       }
@@ -3896,14 +3589,22 @@
         const intptr_t shift_count =
             Utils::ShiftForPowerOfTwo(Utils::Abs(value)) + kSmiTagSize;
         ASSERT(kSmiTagSize == 1);
+#if !defined(DART_COMPRESSED_POINTERS)
         __ AsrImmediate(TMP, left, 63);
+#else
+        __ AsrImmediate(TMP, left, 31, compiler::kFourBytes);
+#endif
         ASSERT(shift_count > 1);  // 1, -1 case handled above.
         const Register temp = TMP2;
+#if !defined(DART_COMPRESSED_POINTERS)
         __ add(temp, left, compiler::Operand(TMP, LSR, 64 - shift_count));
+#else
+        __ addw(temp, left, compiler::Operand(TMP, LSR, 32 - shift_count));
+#endif
         ASSERT(shift_count > 0);
-        __ AsrImmediate(result, temp, shift_count);
+        __ AsrImmediate(result, temp, shift_count, compiler::kObjectBytes);
         if (value < 0) {
-          __ sub(result, ZR, compiler::Operand(result));
+          __ sub(result, ZR, compiler::Operand(result), compiler::kObjectBytes);
         }
         __ SmiTag(result);
         break;
@@ -3921,12 +3622,18 @@
         __ XorImmediate(result, left, imm);
         break;
       case Token::kSHR: {
-        // Asr operation masks the count to 6 bits.
+        // Asr operation masks the count to 6/5 bits.
+#if !defined(DART_COMPRESSED_POINTERS)
         const intptr_t kCountLimit = 0x3F;
+#else
+        const intptr_t kCountLimit = 0x1F;
+#endif
         intptr_t value = Smi::Cast(constant).Value();
         __ AsrImmediate(result, left,
-                        Utils::Minimum(value + kSmiTagSize, kCountLimit));
+                        Utils::Minimum(value + kSmiTagSize, kCountLimit),
+                        compiler::kObjectBytes);
         __ SmiTag(result);
+        // BOGUS: this could be one sbfiz
         break;
       }
       case Token::kUSHR: {
@@ -3956,31 +3663,19 @@
   switch (op_kind()) {
     case Token::kADD: {
       if (deopt == NULL) {
-        __ add(result, left, compiler::Operand(right));
+        __ add(result, left, compiler::Operand(right), compiler::kObjectBytes);
       } else {
-#if !defined(DART_COMPRESSED_POINTERS)
-        __ adds(result, left, compiler::Operand(right));
+        __ adds(result, left, compiler::Operand(right), compiler::kObjectBytes);
         __ b(deopt, VS);
-#else
-        __ addsw(result, left, compiler::Operand(right));
-        __ b(deopt, VS);
-        __ sxtw(result, result);
-#endif
       }
       break;
     }
     case Token::kSUB: {
       if (deopt == NULL) {
-        __ sub(result, left, compiler::Operand(right));
+        __ sub(result, left, compiler::Operand(right), compiler::kObjectBytes);
       } else {
-#if !defined(DART_COMPRESSED_POINTERS)
-        __ subs(result, left, compiler::Operand(right));
+        __ subs(result, left, compiler::Operand(right), compiler::kObjectBytes);
         __ b(deopt, VS);
-#else
-        __ subsw(result, left, compiler::Operand(right));
-        __ b(deopt, VS);
-        __ sxtw(result, result);
-#endif
       }
       break;
     }
@@ -4022,20 +3717,20 @@
     case Token::kTRUNCDIV: {
       if (RangeUtils::CanBeZero(right_range())) {
         // Handle divide by zero in runtime.
-        __ cbz(deopt, right);
+        __ cbz(deopt, right, compiler::kObjectBytes);
       }
       const Register temp = TMP2;
       __ SmiUntag(temp, left);
       __ SmiUntag(TMP, right);
 
-      __ sdiv(result, temp, TMP);
+      __ sdiv(result, temp, TMP, compiler::kObjectBytes);
       if (RangeUtils::Overlaps(right_range(), -1, -1)) {
         // Check the corner case of dividing the 'MIN_SMI' with -1, in which
         // case we cannot tag the result.
 #if !defined(DART_COMPRESSED_POINTERS)
         __ CompareImmediate(result, 0x4000000000000000LL);
 #else
-        __ CompareImmediate(result, 0x40000000LL);
+        __ CompareImmediate(result, 0x40000000LL, compiler::kFourBytes);
 #endif
         __ b(deopt, EQ);
       }
@@ -4045,16 +3740,17 @@
     case Token::kMOD: {
       if (RangeUtils::CanBeZero(right_range())) {
         // Handle divide by zero in runtime.
-        __ cbz(deopt, right);
+        __ cbz(deopt, right, compiler::kObjectBytes);
       }
       const Register temp = TMP2;
       __ SmiUntag(temp, left);
       __ SmiUntag(TMP, right);
 
-      __ sdiv(result, temp, TMP);
+      __ sdiv(result, temp, TMP, compiler::kObjectBytes);
 
       __ SmiUntag(TMP, right);
-      __ msub(result, TMP, result, temp);  // result <- left - right * result
+      __ msub(result, TMP, result, temp,
+              compiler::kObjectBytes);  // result <- left - right * result
       __ SmiTag(result);
       //  res = left % right;
       //  if (res < 0) {
@@ -4065,12 +3761,12 @@
       //    }
       //  }
       compiler::Label done;
-      __ CompareRegisters(result, ZR);
+      __ CompareObjectRegisters(result, ZR);
       __ b(&done, GE);
       // Result is negative, adjust it.
-      __ CompareRegisters(right, ZR);
-      __ sub(TMP, result, compiler::Operand(right));
-      __ add(result, result, compiler::Operand(right));
+      __ CompareObjectRegisters(right, ZR);
+      __ sub(TMP, result, compiler::Operand(right), compiler::kObjectBytes);
+      __ add(result, result, compiler::Operand(right), compiler::kObjectBytes);
       __ csel(result, TMP, result, LT);
       __ Bind(&done);
       break;
@@ -4080,16 +3776,20 @@
         __ tbnz(deopt, right, compiler::target::kSmiBits + kSmiTagSize);
       }
       __ SmiUntag(TMP, right);
-      // asrv operation masks the count to 6 bits.
+      // asrv[w] operation masks the count to 6/5 bits.
+#if !defined(DART_COMPRESSED_POINTERS)
       const intptr_t kCountLimit = 0x3F;
+#else
+      const intptr_t kCountLimit = 0x1F;
+#endif
       if (!RangeUtils::OnlyLessThanOrEqualTo(right_range(), kCountLimit)) {
         __ LoadImmediate(TMP2, kCountLimit);
-        __ CompareRegisters(TMP, TMP2);
+        __ CompareObjectRegisters(TMP, TMP2);
         __ csel(TMP, TMP2, TMP, GT);
       }
       const Register temp = locs()->temp(0).reg();
       __ SmiUntag(temp, left);
-      __ asrv(result, temp, TMP);
+      __ asrv(result, temp, TMP, compiler::kObjectBytes);
       __ SmiTag(result);
       break;
     }
@@ -4276,7 +3976,11 @@
     case kUnboxedDouble: {
       const VRegister result = locs()->out(0).fpu_reg();
       __ SmiUntag(TMP, box);
+#if !defined(DART_COMPRESSED_POINTERS)
       __ scvtfdx(result, TMP);
+#else
+      __ scvtfdw(result, TMP);
+#endif
       break;
     }
 
@@ -4385,7 +4089,8 @@
     ASSERT(from_representation() == kUnboxedUint32);
     // A 32 bit positive Smi has one tag bit and one unused sign bit,
     // leaving only 30 bits for the payload.
-    __ ubfiz(out, value, kSmiTagSize, compiler::target::kSmiBits);
+    // __ ubfiz(out, value, kSmiTagSize, compiler::target::kSmiBits);
+    __ LslImmediate(out, value, kSmiTagSize, compiler::kFourBytes);
     if (ValueFitsSmi()) {
       return;
     }
@@ -4399,7 +4104,7 @@
   if (from_representation() == kUnboxedInt32) {
     __ sxtw(temp, value);  // Sign-extend.
   } else {
-    __ ubfiz(temp, value, 0, 32);  // Zero extend word.
+    __ uxtw(temp, value);  // Zero-extend.
   }
   __ StoreToOffset(temp, out, Mint::value_offset() - kHeapObjectTag);
   __ Bind(&done);
@@ -4459,9 +4164,7 @@
   // which causes the overflow flag to be set.
   __ b(&done, NO_OVERFLOW);
 #else
-  __ LslImmediate(out, in, kSmiTagSize,
-                  compiler::kFourBytes);  // SmiTag (32-bit);
-  __ sxtw(out, out);                      // Sign-extend.
+  __ sbfiz(out, in, kSmiTagSize, 31);  // SmiTag + sign-extend.
   __ cmp(in, compiler::Operand(out, ASR, kSmiTagSize));
   __ b(&done, EQ);
 #endif
@@ -4895,7 +4598,7 @@
 
   const Register vs[] = {v0, v1, v2, v3};
   for (intptr_t i = 0; i < 4; i++) {
-    __ CompareRegisters(vs[i], TMP2);
+    __ CompareObjectRegisters(vs[i], TMP2);
     __ csel(TMP, temp, ZR, EQ);
     __ vinsw(result, i, TMP);
   }
@@ -5113,6 +4816,8 @@
 }
 
 void CaseInsensitiveCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  ASSERT(TargetFunction().is_leaf());
+
   // Call the function.
   __ CallRuntime(TargetFunction(), TargetFunction().argument_count());
 }
@@ -5192,7 +4897,7 @@
   const Register left = locs()->in(0).reg();
   const Register right = locs()->in(1).reg();
   const Register result = locs()->out(0).reg();
-  __ CompareRegisters(left, right);
+  __ CompareObjectRegisters(left, right);
   ASSERT(result == left);
   if (is_min) {
     __ csel(result, right, left, GT);
@@ -5221,12 +4926,7 @@
     case Token::kNEGATE: {
       compiler::Label* deopt =
           compiler->AddDeoptStub(deopt_id(), ICData::kDeoptUnaryOp);
-#if !defined(DART_COMPRESSED_POINTERS)
-      __ subs(result, ZR, compiler::Operand(value));
-#else
-      __ subsw(result, ZR, compiler::Operand(value));
-      __ sxtw(result, result);
-#endif
+      __ subs(result, ZR, compiler::Operand(value), compiler::kObjectBytes);
       __ b(deopt, VS);
       break;
     }
@@ -5392,13 +5092,13 @@
   __ fcmpd(value, value);
   __ b(deopt, VS);
 
-#if !defined(DART_COMPRESSED_POINTERS)
   __ fcvtzdsx(result, value);
+
+#if !defined(DART_COMPRESSED_POINTERS)
   // Check for overflow and that it fits into Smi.
   __ CompareImmediate(result, 0xC000000000000000);
   __ b(deopt, MI);
 #else
-  __ fcvtzdsw(result, value);
   // Check for overflow and that it fits into Smi.
   __ AsrImmediate(TMP, result, 30);
   __ cmp(TMP, compiler::Operand(result, ASR, 63));
@@ -5582,6 +5282,8 @@
 }
 
 void InvokeMathCFunctionInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  ASSERT(TargetFunction().is_leaf());
+
   if (recognized_kind() == MethodRecognizer::kMathDoublePow) {
     InvokeDoublePow(compiler, this);
     return;
@@ -5663,25 +5365,25 @@
   const Register result_mod = pair->At(1).reg();
   if (RangeUtils::CanBeZero(divisor_range())) {
     // Handle divide by zero in runtime.
-    __ CompareRegisters(right, ZR);
+    __ CompareObjectRegisters(right, ZR);
     __ b(deopt, EQ);
   }
 
   __ SmiUntag(result_mod, left);
   __ SmiUntag(TMP, right);
 
-  __ sdiv(result_div, result_mod, TMP);
-
   // Check the corner case of dividing the 'MIN_SMI' with -1, in which
   // case we cannot tag the result.
 #if !defined(DART_COMPRESSED_POINTERS)
+  __ sdiv(result_div, result_mod, TMP);
   __ CompareImmediate(result_div, 0x4000000000000000);
 #else
-  __ CompareImmediate(result_div, 0x40000000);
+  __ sdivw(result_div, result_mod, TMP);
+  __ CompareImmediate(result_div, 0x40000000, compiler::kFourBytes);
 #endif
   __ b(deopt, EQ);
   // result_mod <- left - right * result_div.
-  __ msub(result_mod, TMP, result_div, result_mod);
+  __ msub(result_mod, TMP, result_div, result_mod, compiler::kObjectBytes);
   __ SmiTag(result_div);
   __ SmiTag(result_mod);
   // Correct MOD result:
@@ -5694,12 +5396,12 @@
   //    }
   //  }
   compiler::Label done;
-  __ CompareRegisters(result_mod, ZR);
+  __ CompareObjectRegisters(result_mod, ZR);
   __ b(&done, GE);
   // Result is negative, adjust it.
-  __ CompareRegisters(right, ZR);
-  __ sub(TMP2, result_mod, compiler::Operand(right));
-  __ add(TMP, result_mod, compiler::Operand(right));
+  __ CompareObjectRegisters(right, ZR);
+  __ sub(TMP2, result_mod, compiler::Operand(right), compiler::kObjectBytes);
+  __ add(TMP, result_mod, compiler::Operand(right), compiler::kObjectBytes);
   __ csel(result_mod, TMP, TMP2, GE);
   __ Bind(&done);
 }
@@ -5883,7 +5585,7 @@
   if (index_loc.IsConstant()) {
     const Register length = length_loc.reg();
     const Smi& index = Smi::Cast(index_loc.constant());
-    __ CompareImmediate(length, static_cast<int64_t>(index.ptr()));
+    __ CompareObject(length, index);
     __ b(deopt, LS);
   } else if (length_loc.IsConstant()) {
     const Smi& length = Smi::Cast(length_loc.constant());
@@ -5892,10 +5594,10 @@
       __ BranchIfNotSmi(index, deopt);
     }
     if (length.Value() == Smi::kMaxValue) {
-      __ tst(index, compiler::Operand(index));
+      __ tst(index, compiler::Operand(index), compiler::kObjectBytes);
       __ b(deopt, MI);
     } else {
-      __ CompareImmediate(index, static_cast<int64_t>(length.ptr()));
+      __ CompareObject(index, length);
       __ b(deopt, CS);
     }
   } else {
@@ -5904,7 +5606,7 @@
     if (index_cid != kSmiCid) {
       __ BranchIfNotSmi(index, deopt);
     }
-    __ CompareRegisters(index, length);
+    __ CompareObjectRegisters(index, length);
     __ b(deopt, CS);
   }
 }
@@ -6744,7 +6446,6 @@
     }
     case kUnboxedInt64: {
       ASSERT(to() == kUnboxedDouble);
-
       const Register from_reg = locs()->in(0).reg();
       const FpuRegister to_reg = locs()->out(0).fpu_reg();
       __ fmovdr(to_reg, from_reg);
@@ -6880,7 +6581,7 @@
   if (!needs_number_check() && compiler::target::IsSmi(obj) &&
       compiler::target::ToRawSmi(obj) == 0 &&
       CanUseCbzTbzForComparison(compiler, reg, orig_cond, labels)) {
-    EmitCbzTbz(reg, compiler, orig_cond, labels);
+    EmitCbzTbz(reg, compiler, orig_cond, labels, compiler::kObjectBytes);
     return kInvalidCondition;
   } else {
     return compiler->EmitEqualityRegConstCompare(reg, obj, needs_number_check(),
@@ -6892,19 +6593,27 @@
   compiler::Label is_true, is_false;
   BranchLabels labels = {&is_true, &is_false, &is_false};
   Condition true_condition = EmitComparisonCode(compiler, labels);
-  const Register result = this->locs()->out(0).reg();
 
-  // TODO(dartbug.com/29908): Use csel here for better branch prediction?
-  if (true_condition != kInvalidCondition) {
-    EmitBranchOnCondition(compiler, true_condition, labels);
+  const Register result = this->locs()->out(0).reg();
+  if (is_true.IsLinked() || is_false.IsLinked()) {
+    if (true_condition != kInvalidCondition) {
+      EmitBranchOnCondition(compiler, true_condition, labels);
+    }
+    compiler::Label done;
+    __ Bind(&is_false);
+    __ LoadObject(result, Bool::False());
+    __ b(&done);
+    __ Bind(&is_true);
+    __ LoadObject(result, Bool::True());
+    __ Bind(&done);
+  } else {
+    // If EmitComparisonCode did not use the labels and just returned
+    // a condition we can avoid the branch and use conditional loads.
+    ASSERT(true_condition != kInvalidCondition);
+    __ LoadObject(TMP, Bool::True());
+    __ LoadObject(TMP2, Bool::False());
+    __ csel(result, TMP, TMP2, true_condition);
   }
-  compiler::Label done;
-  __ Bind(&is_false);
-  __ LoadObject(result, Bool::False());
-  __ b(&done);
-  __ Bind(&is_true);
-  __ LoadObject(result, Bool::True());
-  __ Bind(&done);
 }
 
 void ComparisonInstr::EmitBranchCode(FlowGraphCompiler* compiler,
@@ -6925,17 +6634,9 @@
 void BooleanNegateInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   const Register input = locs()->in(0).reg();
   const Register result = locs()->out(0).reg();
-
-  if (value()->Type()->ToCid() == kBoolCid) {
-    __ eori(
-        result, input,
-        compiler::Immediate(compiler::target::ObjectAlignment::kBoolValueMask));
-  } else {
-    __ LoadObject(result, Bool::True());
-    __ LoadObject(TMP, Bool::False());
-    __ CompareRegisters(result, input);
-    __ csel(result, TMP, result, EQ);
-  }
+  __ eori(
+      result, input,
+      compiler::Immediate(compiler::target::ObjectAlignment::kBoolValueMask));
 }
 
 LocationSummary* AllocateObjectInstr::MakeLocationSummary(Zone* zone,
@@ -6963,7 +6664,7 @@
   const Code& stub = Code::ZoneHandle(
       compiler->zone(), StubCode::GetAllocationStubForClass(cls()));
   compiler->GenerateStubCall(source(), stub, UntaggedPcDescriptors::kOther,
-                             locs());
+                             locs(), deopt_id());
 }
 
 void DebugStepCheckInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
diff --git a/runtime/vm/compiler/backend/il_deserializer.cc b/runtime/vm/compiler/backend/il_deserializer.cc
deleted file mode 100644
index eb7f1fa..0000000
--- a/runtime/vm/compiler/backend/il_deserializer.cc
+++ /dev/null
@@ -1,2520 +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.
-
-#include "vm/compiler/backend/il_deserializer.h"
-
-#include "vm/compiler/backend/il_serializer.h"
-#include "vm/compiler/backend/range_analysis.h"
-#include "vm/compiler/call_specializer.h"
-#include "vm/compiler/frontend/base_flow_graph_builder.h"
-#include "vm/compiler/jit/compiler.h"
-#include "vm/flags.h"
-#include "vm/json_writer.h"
-#include "vm/os.h"
-
-namespace dart {
-
-DEFINE_FLAG(bool,
-            trace_round_trip_serialization,
-            false,
-            "Print out tracing information during round trip serialization.");
-DEFINE_FLAG(bool,
-            print_json_round_trip_results,
-            false,
-            "Print out results of each round trip serialization in JSON form.");
-
-// Contains the contents of a single round-trip result.
-struct RoundTripResults : public ValueObject {
-  explicit RoundTripResults(Zone* zone, const Function& func)
-      : function(func), unhandled(zone, 2) {}
-
-  // The function for which a flow graph was being parsed.
-  const Function& function;
-  // Whether the round trip succeeded.
-  bool success = false;
-  // An array of unhandled instructions found in the flow graph.
-  GrowableArray<Instruction*> unhandled;
-  // The serialized form of the flow graph, if computed.
-  SExpression* serialized = nullptr;
-  // The error information from the deserializer, if an error occurred.
-  const char* error_message = nullptr;
-  SExpression* error_sexp = nullptr;
-};
-
-// Return a textual description of how to find the sub-expression [to_find]
-// inside a [root] S-Expression.
-static const char* GetSExpressionPosition(Zone* zone,
-                                          SExpression* root,
-                                          SExpression* to_find) {
-  // The S-expression to find _is_ the root, so no description is needed.
-  if (root == to_find) return "";
-  // The S-expression to find cannot be a sub-expression of the given root,
-  // so return nullptr to signal this.
-  if (!root->IsList()) return nullptr;
-  auto const list = root->AsList();
-  for (intptr_t i = 0, n = list->Length(); i < n; i++) {
-    if (auto const str = GetSExpressionPosition(zone, list->At(i), to_find)) {
-      return OS::SCreate(zone, "element %" Pd "%s%s", i,
-                         *str == '\0' ? "" : " -> ", str);
-    }
-  }
-  auto it = list->ExtraIterator();
-  while (auto kv = it.Next()) {
-    if (auto const str = GetSExpressionPosition(zone, kv->value, to_find)) {
-      return OS::SCreate(zone, "label %s%s%s", kv->key,
-                         *str == '\0' ? "" : " -> ", str);
-    }
-  }
-  return nullptr;
-}
-
-static void PrintRoundTripResults(Zone* zone, const RoundTripResults& results) {
-  // A few checks to make sure we'll print out enough info. First, if there are
-  // no unhandled instructions, then we should have serialized the flow graph.
-  ASSERT(!results.unhandled.is_empty() || results.serialized != nullptr);
-  // If we failed, then either there are unhandled instructions or we have
-  // an appropriate error message and sexp from the FlowGraphDeserializer.
-  ASSERT(results.success || !results.unhandled.is_empty() ||
-         (results.error_message != nullptr && results.error_sexp != nullptr));
-
-  JSONWriter js;
-
-  js.OpenObject();
-  js.PrintProperty("function", results.function.ToFullyQualifiedCString());
-  js.PrintPropertyBool("success", results.success);
-
-  if (!results.unhandled.is_empty()) {
-    CStringMap<intptr_t> count_map(zone);
-    for (auto inst : results.unhandled) {
-      auto const name = inst->DebugName();
-      auto const old_count = count_map.LookupValue(name);
-      count_map.Update({name, old_count + 1});
-    }
-
-    auto count_it = count_map.GetIterator();
-    js.OpenObject("unhandled");
-    while (auto kv = count_it.Next()) {
-      js.PrintProperty64(kv->key, kv->value);
-    }
-    js.CloseObject();
-  }
-
-  if (results.serialized != nullptr) {
-    TextBuffer buf(1000);
-    results.serialized->SerializeTo(zone, &buf, "");
-    js.PrintProperty("serialized", buf.buffer());
-  }
-
-  if (results.error_message != nullptr) {
-    js.OpenObject("error");
-    js.PrintProperty("message", results.error_message);
-
-    ASSERT(results.error_sexp != nullptr);
-    TextBuffer buf(1000);
-    results.error_sexp->SerializeTo(zone, &buf, "");
-    js.PrintProperty("expression", buf.buffer());
-
-    auto const sexp_position =
-        GetSExpressionPosition(zone, results.serialized, results.error_sexp);
-    js.PrintProperty("path", sexp_position);
-    js.CloseObject();
-  }
-
-  js.CloseObject();
-  THR_Print("Results of round trip serialization: %s\n", js.buffer()->buffer());
-}
-
-void FlowGraphDeserializer::RoundTripSerialization(CompilerPassState* state) {
-  auto const flow_graph = state->flow_graph();
-
-  // The deserialized flow graph must be in the same zone as the original flow
-  // graph, to ensure it has the right lifetime. Thus, we leave an explicit
-  // use of [flow_graph->zone()] in the deserializer construction.
-  //
-  // Otherwise, it would be nice to use a StackZone to limit the lifetime of the
-  // serialized form (and other values created with this [zone] variable), since
-  // it only needs to live for the dynamic extent of this method.
-  //
-  // However, creating a StackZone for it also changes the zone associated with
-  // the thread. Also, some parts of the VM used in later updates to the
-  // deserializer implicitly pick up the zone to use either from a passed-in
-  // thread or the current thread instead of taking an explicit zone.
-  //
-  // For now, just serialize into the same zone as the original flow graph, and
-  // we can revisit this if this causes a performance issue or if we can ensure
-  // that those VM parts mentioned can be passed an explicit zone.
-  Zone* const zone = flow_graph->zone();
-
-  // Final flow graph, if we successfully serialize and deserialize.
-  FlowGraph* new_graph = nullptr;
-
-  // Stored information for printing results if requested.
-  RoundTripResults results(zone, flow_graph->function());
-
-  FlowGraphDeserializer::AllUnhandledInstructions(flow_graph,
-                                                  &results.unhandled);
-  if (results.unhandled.is_empty()) {
-    results.serialized = FlowGraphSerializer::SerializeToSExp(zone, flow_graph);
-
-    if (FLAG_trace_round_trip_serialization && results.serialized != nullptr) {
-      TextBuffer buf(1000);
-      results.serialized->SerializeTo(zone, &buf, "");
-      THR_Print("Serialized flow graph:\n%s\n", buf.buffer());
-    }
-
-    // For the deserializer, use the thread from the compiler pass and zone
-    // associated with the existing flow graph to make sure the new flow graph
-    // has the right lifetime.
-    FlowGraphDeserializer d(state->thread, flow_graph->zone(),
-                            results.serialized, &flow_graph->parsed_function());
-    new_graph = d.ParseFlowGraph();
-    if (new_graph == nullptr) {
-      ASSERT(d.error_message() != nullptr && d.error_sexp() != nullptr);
-      if (FLAG_trace_round_trip_serialization) {
-        THR_Print("Failure during deserialization: %s\n", d.error_message());
-        THR_Print("At S-expression %s\n", d.error_sexp()->ToCString(zone));
-        if (auto const pos = GetSExpressionPosition(zone, results.serialized,
-                                                    d.error_sexp())) {
-          THR_Print("Path from root: %s\n", pos);
-        }
-      }
-      results.error_message = d.error_message();
-      results.error_sexp = d.error_sexp();
-    } else {
-      if (FLAG_trace_round_trip_serialization) {
-        THR_Print("Successfully deserialized graph for %s\n",
-                  results.serialized->AsList()->At(1)->AsSymbol()->value());
-      }
-      results.success = true;
-    }
-  } else if (FLAG_trace_round_trip_serialization) {
-    THR_Print("Cannot serialize graph due to instruction: %s\n",
-              results.unhandled.At(0)->DebugName());
-  }
-
-  if (FLAG_print_json_round_trip_results) PrintRoundTripResults(zone, results);
-
-  if (new_graph != nullptr) {
-    state->set_flow_graph(new_graph);
-  }
-}
-
-#define HANDLED_CASE(name)                                                     \
-  if (inst->Is##name()) return true;
-bool FlowGraphDeserializer::IsHandledInstruction(Instruction* inst) {
-  if (auto const const_inst = inst->AsConstant()) {
-    return IsHandledConstant(const_inst->value());
-  }
-  FOR_EACH_HANDLED_BLOCK_TYPE_IN_DESERIALIZER(HANDLED_CASE)
-  FOR_EACH_HANDLED_INSTRUCTION_IN_DESERIALIZER(HANDLED_CASE)
-  return false;
-}
-#undef HANDLED_CASE
-
-void FlowGraphDeserializer::AllUnhandledInstructions(
-    const FlowGraph* graph,
-    GrowableArray<Instruction*>* unhandled) {
-  ASSERT(graph != nullptr);
-  ASSERT(unhandled != nullptr);
-  for (auto block_it = graph->reverse_postorder_iterator(); !block_it.Done();
-       block_it.Advance()) {
-    auto const entry = block_it.Current();
-    if (!IsHandledInstruction(entry)) unhandled->Add(entry);
-    // Check that the Phi instructions in JoinEntrys do not have pair
-    // representation.
-    if (auto const join_block = entry->AsJoinEntry()) {
-      auto const phis = join_block->phis();
-      auto const length = ((phis == nullptr) ? 0 : phis->length());
-      for (intptr_t i = 0; i < length; i++) {
-        auto const current = phis->At(i);
-        for (intptr_t j = 0; j < current->InputCount(); j++) {
-          if (current->InputAt(j)->definition()->HasPairRepresentation()) {
-            unhandled->Add(current);
-          }
-        }
-      }
-    }
-    if (auto const def_block = entry->AsBlockEntryWithInitialDefs()) {
-      auto const defs = def_block->initial_definitions();
-      for (intptr_t i = 0; i < defs->length(); i++) {
-        auto const current = defs->At(i);
-        if (!IsHandledInstruction(current)) unhandled->Add(current);
-      }
-    }
-    for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) {
-      auto current = it.Current();
-      // We handle branches, so we need to check the comparison instruction.
-      if (current->IsBranch()) current = current->AsBranch()->comparison();
-      if (!IsHandledInstruction(current)) unhandled->Add(current);
-    }
-  }
-}
-
-// Keep in sync with work in ParseDartValue. Right now, this is just a shallow
-// check, not a deep one.
-bool FlowGraphDeserializer::IsHandledConstant(const Object& obj) {
-  if (obj.IsArray()) return Array::Cast(obj).IsImmutable();
-  return obj.IsNull() || obj.IsClass() || obj.IsFunction() || obj.IsField() ||
-         obj.IsInstance();
-}
-
-SExpression* FlowGraphDeserializer::Retrieve(SExpList* list, intptr_t index) {
-  if (list == nullptr) return nullptr;
-  if (list->Length() <= index) {
-    StoreError(list, "expected at least %" Pd " element(s) in list", index + 1);
-    return nullptr;
-  }
-  auto const elem = list->At(index);
-  if (elem == nullptr) {
-    StoreError(list, "null value at index %" Pd "", index);
-  }
-  return elem;
-}
-
-SExpression* FlowGraphDeserializer::Retrieve(SExpList* list, const char* key) {
-  if (list == nullptr) return nullptr;
-  if (!list->ExtraHasKey(key)) {
-    StoreError(list, "expected an extra info entry for key %s", key);
-    return nullptr;
-  }
-  auto const elem = list->ExtraLookupValue(key);
-  if (elem == nullptr) {
-    StoreError(list, "null value for key %s", key);
-  }
-  return elem;
-}
-
-FlowGraph* FlowGraphDeserializer::ParseFlowGraph() {
-  auto const root = CheckTaggedList(root_sexp_, "FlowGraph");
-  if (root == nullptr) return nullptr;
-
-  intptr_t deopt_id = DeoptId::kNone;
-  if (auto const deopt_id_sexp =
-          CheckInteger(root->ExtraLookupValue("deopt_id"))) {
-    deopt_id = deopt_id_sexp->value();
-  }
-  EntryInfo common_info = {0, kInvalidTryIndex, deopt_id};
-
-  auto const graph = DeserializeGraphEntry(root, common_info);
-
-  PrologueInfo pi(-1, -1);
-  flow_graph_ = new (zone()) FlowGraph(*parsed_function_, graph, 0, pi);
-  flow_graph_->CreateCommonConstants();
-
-  intptr_t pos = 2;
-  if (auto const pool = CheckTaggedList(Retrieve(root, pos), "Constants")) {
-    if (!ParseConstantPool(pool)) return nullptr;
-    pos++;
-  }
-
-  // The deopt environment for the graph entry may use entries from the
-  // constant pool, so that must be parsed first.
-  if (auto const env_sexp = CheckList(root->ExtraLookupValue("env"))) {
-    current_block_ = graph;
-    auto const env = ParseEnvironment(env_sexp);
-    if (env == nullptr) return nullptr;
-    env->DeepCopyTo(zone(), graph);
-  }
-
-  auto const entries_sexp = CheckTaggedList(Retrieve(root, pos), "Entries");
-  if (!ParseEntries(entries_sexp)) return nullptr;
-  pos++;
-
-  // Now prime the block worklist with entries. We keep the block worklist
-  // in reverse order so that we can just pop the next block for content
-  // parsing off the end.
-  BlockWorklist block_worklist(zone(), entries_sexp->Length() - 1);
-
-  const auto& indirect_entries = graph->indirect_entries();
-  for (auto indirect_entry : indirect_entries) {
-    block_worklist.Add(indirect_entry->block_id());
-  }
-
-  const auto& catch_entries = graph->catch_entries();
-  for (auto catch_entry : catch_entries) {
-    block_worklist.Add(catch_entry->block_id());
-  }
-
-  if (auto const osr_entry = graph->osr_entry()) {
-    block_worklist.Add(osr_entry->block_id());
-  }
-  if (auto const unchecked_entry = graph->unchecked_entry()) {
-    block_worklist.Add(unchecked_entry->block_id());
-  }
-  if (auto const normal_entry = graph->normal_entry()) {
-    block_worklist.Add(normal_entry->block_id());
-  }
-
-  if (!ParseBlocks(root, pos, &block_worklist)) return nullptr;
-
-  // Before we return the new graph, make sure all definitions were found for
-  // all pending values.
-  if (values_map_.Length() > 0) {
-    auto it = values_map_.GetIterator();
-    auto const kv = it.Next();
-    ASSERT(kv->value->length() > 0);
-    const auto& value_info = kv->value->At(0);
-    StoreError(value_info.sexp, "no definition found for use in flow graph");
-    return nullptr;
-  }
-
-  flow_graph_->set_max_block_id(max_block_id_);
-  // The highest numbered SSA temp might need two slots (e.g. for unboxed
-  // integers on 32-bit platforms), so we add 2 to the highest seen SSA temp
-  // index to get to the new current SSA temp index. In cases where the highest
-  // numbered SSA temp originally had only one slot assigned, this can result
-  // in different SSA temp numbering in later passes between the original and
-  // deserialized graphs.
-  flow_graph_->set_current_ssa_temp_index(max_ssa_index_ + 2);
-  // Now that the deserializer has finished re-creating all the blocks in the
-  // flow graph, the blocks must be rediscovered. In addition, if ComputeSSA
-  // has already been run, dominators must be recomputed as well.
-  flow_graph_->DiscoverBlocks();
-  // Currently we only handle SSA graphs, so always do this.
-  GrowableArray<BitVector*> dominance_frontier;
-  flow_graph_->ComputeDominators(&dominance_frontier);
-
-  return flow_graph_;
-}
-
-bool FlowGraphDeserializer::ParseConstantPool(SExpList* pool) {
-  ASSERT(flow_graph_ != nullptr);
-  if (pool == nullptr) return false;
-  // Definitions in the constant pool may refer to later definitions. However,
-  // there should be no cycles possible between constant objects, so using a
-  // worklist algorithm we should always be able to make progress.
-  // Since we will not be adding new definitions, we make the initial size of
-  // the worklist the number of definitions in the constant pool.
-  GrowableArray<SExpList*> worklist(zone(), pool->Length() - 1);
-  // In order to ensure that the definition order is the same in the original
-  // flow graph, we can't just simply call GetConstant() whenever we
-  // successfully parse a constant. Instead, we'll create a stand-in
-  // ConstantInstr that we can temporarily stick in the definition_map_, and
-  // then once finished we'll go back through, add the constants via
-  // GetConstant() and parse any extra information.
-  DirectChainedHashMap<RawPointerKeyValueTrait<SExpList, ConstantInstr*>>
-      parsed_constants(zone());
-  // We keep old_worklist in reverse order so that we can just RemoveLast
-  // to get elements in their original order.
-  for (intptr_t i = pool->Length() - 1; i > 0; i--) {
-    const auto def_sexp = CheckTaggedList(pool->At(i), "def");
-    if (def_sexp == nullptr) return false;
-    worklist.Add(def_sexp);
-  }
-  while (true) {
-    const intptr_t worklist_len = worklist.length();
-    GrowableArray<SExpList*> parse_failures(zone(), worklist_len);
-    while (!worklist.is_empty()) {
-      const auto def_sexp = worklist.RemoveLast();
-      auto& obj = Object::ZoneHandle(zone());
-      if (!ParseDartValue(Retrieve(def_sexp, 2), &obj)) {
-        parse_failures.Add(def_sexp);
-        continue;
-      }
-      ConstantInstr* def = new (zone()) ConstantInstr(obj);
-      // Instead of parsing the whole definition, just get the SSA index so
-      // we can insert it into the definition_map_.
-      intptr_t index;
-      auto const name_sexp = CheckSymbol(Retrieve(def_sexp, 1));
-      if (!ParseSSATemp(name_sexp, &index)) return false;
-      def->set_ssa_temp_index(index);
-      ASSERT(!definition_map_.HasKey(index));
-      definition_map_.Insert(index, def);
-      parsed_constants.Insert({def_sexp, def});
-    }
-    if (parse_failures.is_empty()) break;
-    // We've gone through the whole worklist without success, so return
-    // the last error we encountered.
-    if (parse_failures.length() == worklist_len) return false;
-    // worklist was added to in order, so we need to reverse its contents
-    // when we add them to old_worklist.
-    while (!parse_failures.is_empty()) {
-      worklist.Add(parse_failures.RemoveLast());
-    }
-  }
-  // Now loop back through the constant pool definition S-expressions and
-  // get the real ConstantInstrs the flow graph will be using and finish
-  // parsing.
-  for (intptr_t i = 1; i < pool->Length(); i++) {
-    auto const def_sexp = CheckTaggedList(pool->At(i));
-    auto const temp_def = parsed_constants.LookupValue(def_sexp);
-    ASSERT(temp_def != nullptr);
-    // Remove the temporary definition from definition_map_ so this doesn't get
-    // flagged as a redefinition.
-    definition_map_.Remove(temp_def->ssa_temp_index());
-    ConstantInstr* real_def = flow_graph_->GetConstant(temp_def->value());
-    if (!ParseDefinitionWithParsedBody(def_sexp, real_def)) return false;
-    ASSERT(temp_def->ssa_temp_index() == real_def->ssa_temp_index());
-  }
-  return true;
-}
-
-bool FlowGraphDeserializer::ParseEntries(SExpList* list) {
-  ASSERT(flow_graph_ != nullptr);
-  if (list == nullptr) return false;
-  for (intptr_t i = 1; i < list->Length(); i++) {
-    const auto entry = CheckTaggedList(Retrieve(list, i));
-    if (entry == nullptr) return false;
-    intptr_t block_id;
-    if (!ParseBlockId(CheckSymbol(Retrieve(entry, 1)), &block_id)) {
-      return false;
-    }
-    if (block_map_.LookupValue(block_id) != nullptr) {
-      StoreError(entry->At(1), "multiple entries for block found");
-      return false;
-    }
-    const auto tag = entry->Tag();
-    if (ParseBlockHeader(entry, block_id, tag) == nullptr) return false;
-  }
-  return true;
-}
-
-bool FlowGraphDeserializer::ParseBlocks(SExpList* list,
-                                        intptr_t pos,
-                                        BlockWorklist* worklist) {
-  // First, ensure that all the block headers have been parsed. Set up a
-  // map from block IDs to S-expressions and the max_block_id while we're at it.
-  IntMap<SExpList*> block_sexp_map(zone());
-  for (intptr_t i = pos, n = list->Length(); i < n; i++) {
-    auto const block_sexp = CheckTaggedList(Retrieve(list, i), "Block");
-    intptr_t block_id;
-    if (!ParseBlockId(CheckSymbol(Retrieve(block_sexp, 1)), &block_id)) {
-      return false;
-    }
-    if (block_sexp_map.LookupValue(block_id) != nullptr) {
-      StoreError(block_sexp->At(1), "multiple definitions of block found");
-      return false;
-    }
-    block_sexp_map.Insert(block_id, block_sexp);
-    auto const type_tag =
-        CheckSymbol(block_sexp->ExtraLookupValue("block_type"));
-    // Entry block headers are already parsed, but others aren't.
-    if (block_map_.LookupValue(block_id) == nullptr) {
-      if (ParseBlockHeader(block_sexp, block_id, type_tag) == nullptr) {
-        return false;
-      }
-    }
-    if (max_block_id_ < block_id) max_block_id_ = block_id;
-  }
-
-  // Now start parsing the contents of blocks from the worklist. We use an
-  // IntMap to keep track of what blocks have already been fully parsed.
-  IntMap<bool> fully_parsed_block_map(zone());
-  while (!worklist->is_empty()) {
-    auto const block_id = worklist->RemoveLast();
-
-    // If we've already encountered this block, skip it.
-    if (fully_parsed_block_map.LookupValue(block_id)) continue;
-
-    auto const block_sexp = block_sexp_map.LookupValue(block_id);
-    ASSERT(block_sexp != nullptr);
-
-    current_block_ = block_map_.LookupValue(block_id);
-    ASSERT(current_block_ != nullptr);
-    ASSERT(current_block_->PredecessorCount() > 0);
-
-    if (!ParseBlockContents(block_sexp, worklist)) return false;
-
-    // Mark this block as done.
-    fully_parsed_block_map.Insert(block_id, true);
-  }
-
-  // Double-check that all blocks were reached by the worklist algorithm.
-  auto it = block_sexp_map.GetIterator();
-  while (auto kv = it.Next()) {
-    if (!fully_parsed_block_map.LookupValue(kv->key)) {
-      StoreError(kv->value, "block unreachable in flow graph");
-      return false;
-    }
-  }
-
-  return true;
-}
-
-bool FlowGraphDeserializer::ParseInitialDefinitions(SExpList* list) {
-  ASSERT(current_block_ != nullptr);
-  ASSERT(current_block_->IsBlockEntryWithInitialDefs());
-  auto const block = current_block_->AsBlockEntryWithInitialDefs();
-  if (list == nullptr) return false;
-  for (intptr_t i = 2; i < list->Length(); i++) {
-    const auto def_sexp = CheckTaggedList(Retrieve(list, i), "def");
-    const auto def = ParseDefinition(def_sexp);
-    if (def == nullptr) return false;
-    flow_graph_->AddToInitialDefinitions(block, def);
-  }
-  return true;
-}
-
-BlockEntryInstr* FlowGraphDeserializer::ParseBlockHeader(SExpList* list,
-                                                         intptr_t block_id,
-                                                         SExpSymbol* tag) {
-  ASSERT(flow_graph_ != nullptr);
-  // We should only parse block headers once.
-  ASSERT(block_map_.LookupValue(block_id) == nullptr);
-  if (list == nullptr) return nullptr;
-
-#if defined(DEBUG)
-  intptr_t parsed_block_id;
-  auto const id_sexp = CheckSymbol(Retrieve(list, 1));
-  if (!ParseBlockId(id_sexp, &parsed_block_id)) return nullptr;
-  ASSERT(block_id == parsed_block_id);
-#endif
-
-  auto const kind = FlowGraphSerializer::BlockEntryTagToKind(tag);
-
-  intptr_t deopt_id = DeoptId::kNone;
-  if (auto const deopt_int = CheckInteger(list->ExtraLookupValue("deopt_id"))) {
-    deopt_id = deopt_int->value();
-  }
-  intptr_t try_index = kInvalidTryIndex;
-  if (auto const try_int = CheckInteger(list->ExtraLookupValue("try_index"))) {
-    try_index = try_int->value();
-  }
-
-  BlockEntryInstr* block = nullptr;
-  EntryInfo common_info = {block_id, try_index, deopt_id};
-  switch (kind) {
-    case FlowGraphSerializer::kTarget:
-      block = DeserializeTargetEntry(list, common_info);
-      break;
-    case FlowGraphSerializer::kNormal:
-      block = DeserializeFunctionEntry(list, common_info);
-      if (block != nullptr) {
-        auto const graph = flow_graph_->graph_entry();
-        graph->set_normal_entry(block->AsFunctionEntry());
-      }
-      break;
-    case FlowGraphSerializer::kUnchecked: {
-      block = DeserializeFunctionEntry(list, common_info);
-      if (block != nullptr) {
-        auto const graph = flow_graph_->graph_entry();
-        graph->set_unchecked_entry(block->AsFunctionEntry());
-      }
-      break;
-    }
-    case FlowGraphSerializer::kJoin:
-      block = DeserializeJoinEntry(list, common_info);
-      break;
-    case FlowGraphSerializer::kInvalid:
-      StoreError(tag, "invalid block entry tag");
-      return nullptr;
-    default:
-      StoreError(tag, "unhandled block type");
-      return nullptr;
-  }
-  if (block == nullptr) return nullptr;
-
-  block_map_.Insert(block_id, block);
-  return block;
-}
-
-bool FlowGraphDeserializer::ParsePhis(SExpList* list) {
-  ASSERT(current_block_ != nullptr && current_block_->IsJoinEntry());
-  auto const join = current_block_->AsJoinEntry();
-  const intptr_t start_pos = 2;
-  auto const end_pos = SkipPhis(list);
-  if (end_pos < start_pos) return false;
-
-  for (intptr_t i = start_pos; i < end_pos; i++) {
-    auto const def_sexp = CheckTaggedList(Retrieve(list, i), "def");
-    auto const phi_sexp = CheckTaggedList(Retrieve(def_sexp, 2), "Phi");
-    // SkipPhis should already have checked which instructions, if any,
-    // are Phi definitions.
-    ASSERT(phi_sexp != nullptr);
-
-    // This is a generalization of FlowGraph::AddPhi where we let ParseValue
-    // create the values (as they may contain type information).
-    auto const phi = new (zone()) PhiInstr(join, phi_sexp->Length() - 1);
-    phi->mark_alive();
-    for (intptr_t i = 0, n = phi_sexp->Length() - 1; i < n; i++) {
-      auto const val = ParseValue(Retrieve(phi_sexp, i + 1));
-      if (val == nullptr) return false;
-      phi->SetInputAt(i, val);
-      val->definition()->AddInputUse(val);
-    }
-    join->InsertPhi(phi);
-
-    if (!ParseDefinitionWithParsedBody(def_sexp, phi)) return false;
-  }
-
-  return true;
-}
-
-intptr_t FlowGraphDeserializer::SkipPhis(SExpList* list) {
-  // All blocks are S-exps of the form (Block B# inst...), so skip the first
-  // two entries and then skip any Phi definitions.
-  for (intptr_t i = 2, n = list->Length(); i < n; i++) {
-    auto const def_sexp = CheckTaggedList(Retrieve(list, i), "def");
-    if (def_sexp == nullptr) return i;
-    auto const phi_sexp = CheckTaggedList(Retrieve(def_sexp, 2), "Phi");
-    if (phi_sexp == nullptr) return i;
-  }
-
-  StoreError(list, "block is empty or contains only Phi definitions");
-  return -1;
-}
-
-bool FlowGraphDeserializer::ParseBlockContents(SExpList* list,
-                                               BlockWorklist* worklist) {
-  ASSERT(current_block_ != nullptr);
-
-  // Parse any Phi definitions now before parsing the block environment.
-  if (current_block_->IsJoinEntry()) {
-    if (!ParsePhis(list)) return false;
-  }
-
-  // For blocks with initial definitions or phi definitions, this needs to be
-  // done after those are parsed. In addition, block environments can also use
-  // definitions from dominating blocks, so we need the contents of dominating
-  // blocks to first be parsed.
-  //
-  // However, we must parse the environment before parsing any instructions
-  // in the body of the block to ensure we don't mistakenly allow local
-  // definitions to appear in the environment.
-  if (auto const env_sexp = CheckList(list->ExtraLookupValue("env"))) {
-    auto const env = ParseEnvironment(env_sexp);
-    if (env == nullptr) return false;
-    env->DeepCopyTo(zone(), current_block_);
-  }
-
-  auto const pos = SkipPhis(list);
-  if (pos < 2) return false;
-  Instruction* last_inst = current_block_;
-  for (intptr_t i = pos, n = list->Length(); i < n; i++) {
-    auto const inst = ParseInstruction(CheckTaggedList(Retrieve(list, i)));
-    if (inst == nullptr) return false;
-    last_inst = last_inst->AppendInstruction(inst);
-  }
-
-  ASSERT(last_inst != nullptr && last_inst != current_block_);
-  if (last_inst->SuccessorCount() > 0) {
-    for (intptr_t i = last_inst->SuccessorCount() - 1; i >= 0; i--) {
-      auto const succ_block = last_inst->SuccessorAt(i);
-      succ_block->AddPredecessor(current_block_);
-      worklist->Add(succ_block->block_id());
-    }
-  }
-
-  return true;
-}
-
-bool FlowGraphDeserializer::ParseDefinitionWithParsedBody(SExpList* list,
-                                                          Definition* def) {
-  if (auto const type_sexp =
-          CheckTaggedList(list->ExtraLookupValue("type"), "CompileType")) {
-    CompileType* typ = ParseCompileType(type_sexp);
-    if (typ == nullptr) return false;
-    def->UpdateType(*typ);
-  }
-
-  if (auto const range_sexp =
-          CheckTaggedList(list->ExtraLookupValue("range"), "Range")) {
-    Range range;
-    if (!ParseRange(range_sexp, &range)) return false;
-    def->set_range(range);
-  }
-
-  auto const name_sexp = CheckSymbol(Retrieve(list, 1));
-  if (name_sexp == nullptr) return false;
-
-  // If the name is "_", this is a subclass of Definition where there's no real
-  // "result" that's being bound. We were just here to add Definition-specific
-  // extra info.
-  if (name_sexp->Equals("_")) return true;
-
-  intptr_t index;
-  if (ParseSSATemp(name_sexp, &index)) {
-    if (definition_map_.HasKey(index)) {
-      StoreError(list, "multiple definitions for the same SSA index");
-      return false;
-    }
-    def->set_ssa_temp_index(index);
-    if (index > max_ssa_index_) max_ssa_index_ = index;
-  } else {
-    // TODO(sstrickl): Add temp support for non-SSA computed graphs.
-    StoreError(list, "unhandled name for definition");
-    return false;
-  }
-
-  definition_map_.Insert(index, def);
-  if (!FixPendingValues(index, def)) return false;
-  return true;
-}
-
-Definition* FlowGraphDeserializer::ParseDefinition(SExpList* list) {
-  if (list == nullptr) return nullptr;
-  ASSERT(list->Tag() != nullptr && list->Tag()->Equals("def"));
-  auto const inst_sexp = CheckTaggedList(Retrieve(list, 2));
-  auto const inst = ParseInstruction(inst_sexp);
-  if (inst == nullptr) return nullptr;
-  if (auto const def = inst->AsDefinition()) {
-    if (!ParseDefinitionWithParsedBody(list, def)) return nullptr;
-    return def;
-  } else {
-    StoreError(list, "instruction cannot be body of definition");
-    return nullptr;
-  }
-}
-
-Instruction* FlowGraphDeserializer::ParseInstruction(SExpList* list) {
-  if (list == nullptr) return nullptr;
-  auto const tag = list->Tag();
-  if (tag->Equals("def")) return ParseDefinition(list);
-
-  intptr_t deopt_id = DeoptId::kNone;
-  if (auto const deopt_int = CheckInteger(list->ExtraLookupValue("deopt_id"))) {
-    deopt_id = deopt_int->value();
-  }
-  TokenPosition token_pos = TokenPosition::kNoSource;
-  if (auto const token_int =
-          CheckInteger(list->ExtraLookupValue("token_pos"))) {
-    token_pos = TokenPosition::Deserialize(token_int->value());
-  }
-  intptr_t inlining_id = -1;
-  if (auto const inlining_int =
-          CheckInteger(list->ExtraLookupValue("inlining_id"))) {
-    inlining_id = inlining_int->value();
-  }
-  InstrInfo common_info = {deopt_id, InstructionSource(token_pos, inlining_id)};
-
-  // Parse the environment before handling the instruction, as we may have
-  // references to PushArguments and parsing the instruction may pop
-  // PushArguments off the stack.
-  // TODO(alexmarkov): revise as it may not be needed anymore.
-  Environment* env = nullptr;
-  if (auto const env_sexp = CheckList(list->ExtraLookupValue("env"))) {
-    env = ParseEnvironment(env_sexp);
-    if (env == nullptr) return nullptr;
-  }
-
-  Instruction* inst = nullptr;
-
-#define HANDLE_CASE(name)                                                      \
-  case kHandled##name:                                                         \
-    inst = Deserialize##name(list, common_info);                               \
-    break;
-  switch (HandledInstructionForTag(tag)) {
-    FOR_EACH_HANDLED_INSTRUCTION_IN_DESERIALIZER(HANDLE_CASE)
-    case kHandledInvalid:
-      StoreError(tag, "unhandled instruction");
-      return nullptr;
-  }
-#undef HANDLE_CASE
-
-  if (inst == nullptr) return nullptr;
-  if (env != nullptr) env->DeepCopyTo(zone(), inst);
-  return inst;
-}
-
-FunctionEntryInstr* FlowGraphDeserializer::DeserializeFunctionEntry(
-    SExpList* sexp,
-    const EntryInfo& info) {
-  ASSERT(flow_graph_ != nullptr);
-  auto const graph = flow_graph_->graph_entry();
-  auto const block = new (zone())
-      FunctionEntryInstr(graph, info.block_id, info.try_index, info.deopt_id);
-  current_block_ = block;
-  if (!ParseInitialDefinitions(sexp)) return nullptr;
-  return block;
-}
-
-GraphEntryInstr* FlowGraphDeserializer::DeserializeGraphEntry(
-    SExpList* sexp,
-    const EntryInfo& info) {
-  auto const name_sexp = CheckSymbol(Retrieve(sexp, 1));
-  // TODO(sstrickl): If the FlowGraphDeserializer was constructed with a
-  // non-null ParsedFunction, we should check that the name matches here.
-  // If not, then we should create an appropriate ParsedFunction here.
-  if (name_sexp == nullptr) return nullptr;
-
-  intptr_t osr_id = Compiler::kNoOSRDeoptId;
-  if (auto const osr_id_sexp = CheckInteger(sexp->ExtraLookupValue("osr_id"))) {
-    osr_id = osr_id_sexp->value();
-  }
-
-  ASSERT(parsed_function_ != nullptr);
-  return new (zone()) GraphEntryInstr(*parsed_function_, osr_id, info.deopt_id);
-}
-
-JoinEntryInstr* FlowGraphDeserializer::DeserializeJoinEntry(
-    SExpList* sexp,
-    const EntryInfo& info) {
-  return new (zone())
-      JoinEntryInstr(info.block_id, info.try_index, info.deopt_id);
-}
-
-TargetEntryInstr* FlowGraphDeserializer::DeserializeTargetEntry(
-    SExpList* sexp,
-    const EntryInfo& info) {
-  return new (zone())
-      TargetEntryInstr(info.block_id, info.try_index, info.deopt_id);
-}
-
-AllocateObjectInstr* FlowGraphDeserializer::DeserializeAllocateObject(
-    SExpList* sexp,
-    const InstrInfo& info) {
-  auto& cls = Class::ZoneHandle(zone());
-  auto const cls_sexp = CheckTaggedList(Retrieve(sexp, 1), "Class");
-  if (!ParseClass(cls_sexp, &cls)) return nullptr;
-
-  Value* type_arguments = nullptr;
-  if (cls.NumTypeArguments() > 0) {
-    type_arguments = ParseValue(Retrieve(sexp, 2));
-    if (type_arguments == nullptr) return nullptr;
-  }
-
-  auto const inst =
-      new (zone()) AllocateObjectInstr(info.source, cls, type_arguments);
-
-  if (auto const closure_sexp = CheckTaggedList(
-          sexp->ExtraLookupValue("closure_function"), "Function")) {
-    auto& closure_function = Function::Handle(zone());
-    if (!ParseFunction(closure_sexp, &closure_function)) return nullptr;
-    inst->set_closure_function(closure_function);
-  }
-
-  if (auto const ident_sexp = CheckSymbol(sexp->ExtraLookupValue("identity"))) {
-    auto id = AliasIdentity::Unknown();
-    if (!AliasIdentity::Parse(ident_sexp->value(), &id)) {
-      return nullptr;
-    }
-    inst->SetIdentity(id);
-  }
-
-  return inst;
-}
-
-AssertAssignableInstr* FlowGraphDeserializer::DeserializeAssertAssignable(
-    SExpList* sexp,
-    const InstrInfo& info) {
-  auto const val = ParseValue(Retrieve(sexp, 1));
-  if (val == nullptr) return nullptr;
-
-  auto const dst_type = ParseValue(Retrieve(sexp, 2));
-  if (dst_type == nullptr) return nullptr;
-
-  auto const inst_type_args = ParseValue(Retrieve(sexp, 3));
-  if (inst_type_args == nullptr) return nullptr;
-
-  auto const func_type_args = ParseValue(Retrieve(sexp, 4));
-  if (func_type_args == nullptr) return nullptr;
-
-  auto& dst_name = String::ZoneHandle(zone());
-  auto const dst_name_sexp = Retrieve(sexp, "name");
-  if (!ParseDartValue(dst_name_sexp, &dst_name)) return nullptr;
-
-  auto kind = AssertAssignableInstr::Kind::kUnknown;
-  if (auto const kind_sexp = CheckSymbol(sexp->ExtraLookupValue("kind"))) {
-    if (!AssertAssignableInstr::ParseKind(kind_sexp->value(), &kind)) {
-      StoreError(kind_sexp, "unknown AssertAssignable kind");
-      return nullptr;
-    }
-  }
-
-  return new (zone())
-      AssertAssignableInstr(info.source, val, dst_type, inst_type_args,
-                            func_type_args, dst_name, info.deopt_id, kind);
-}
-
-AssertBooleanInstr* FlowGraphDeserializer::DeserializeAssertBoolean(
-    SExpList* sexp,
-    const InstrInfo& info) {
-  auto const val = ParseValue(Retrieve(sexp, 1));
-  if (val == nullptr) return nullptr;
-
-  return new (zone()) AssertBooleanInstr(info.source, val, info.deopt_id);
-}
-
-BooleanNegateInstr* FlowGraphDeserializer::DeserializeBooleanNegate(
-    SExpList* sexp,
-    const InstrInfo& info) {
-  auto const value = ParseValue(Retrieve(sexp, 1));
-  if (value == nullptr) return nullptr;
-
-  return new (zone()) BooleanNegateInstr(value);
-}
-
-BranchInstr* FlowGraphDeserializer::DeserializeBranch(SExpList* sexp,
-                                                      const InstrInfo& info) {
-  auto const comp_sexp = CheckTaggedList(Retrieve(sexp, 1));
-  auto const comp_inst = ParseInstruction(comp_sexp);
-  if (comp_inst == nullptr) return nullptr;
-  if (!comp_inst->IsComparison()) {
-    StoreError(sexp->At(1), "expected comparison instruction");
-    return nullptr;
-  }
-  auto const comparison = comp_inst->AsComparison();
-
-  auto const true_block = FetchBlock(CheckSymbol(Retrieve(sexp, 2)));
-  if (true_block == nullptr) return nullptr;
-  if (!true_block->IsTargetEntry()) {
-    StoreError(sexp->At(2), "true successor is not a target block");
-    return nullptr;
-  }
-
-  auto const false_block = FetchBlock(CheckSymbol(Retrieve(sexp, 3)));
-  if (false_block == nullptr) return nullptr;
-  if (!false_block->IsTargetEntry()) {
-    StoreError(sexp->At(3), "false successor is not a target block");
-    return nullptr;
-  }
-
-  auto const branch = new (zone()) BranchInstr(comparison, info.deopt_id);
-  *branch->true_successor_address() = true_block->AsTargetEntry();
-  *branch->false_successor_address() = false_block->AsTargetEntry();
-  return branch;
-}
-
-CheckNullInstr* FlowGraphDeserializer::DeserializeCheckNull(
-    SExpList* sexp,
-    const InstrInfo& info) {
-  auto const val = ParseValue(Retrieve(sexp, 1));
-  if (val == nullptr) return nullptr;
-
-  auto& func_name = String::ZoneHandle(zone());
-  if (auto const name_sexp =
-          CheckString(sexp->ExtraLookupValue("function_name"))) {
-    func_name = String::New(name_sexp->value(), Heap::kOld);
-  }
-
-  return new (zone())
-      CheckNullInstr(val, func_name, info.deopt_id, info.source);
-}
-
-CheckStackOverflowInstr* FlowGraphDeserializer::DeserializeCheckStackOverflow(
-    SExpList* sexp,
-    const InstrInfo& info) {
-  intptr_t stack_depth = 0;
-  if (auto const stack_sexp =
-          CheckInteger(sexp->ExtraLookupValue("stack_depth"))) {
-    stack_depth = stack_sexp->value();
-  }
-
-  intptr_t loop_depth = 0;
-  if (auto const loop_sexp =
-          CheckInteger(sexp->ExtraLookupValue("loop_depth"))) {
-    loop_depth = loop_sexp->value();
-  }
-
-  auto kind = CheckStackOverflowInstr::kOsrAndPreemption;
-  if (auto const kind_sexp = CheckSymbol(sexp->ExtraLookupValue("kind"))) {
-    ASSERT(kind_sexp->Equals("OsrOnly"));
-    kind = CheckStackOverflowInstr::kOsrOnly;
-  }
-
-  return new (zone()) CheckStackOverflowInstr(info.source, stack_depth,
-                                              loop_depth, info.deopt_id, kind);
-}
-
-ConstantInstr* FlowGraphDeserializer::DeserializeConstant(
-    SExpList* sexp,
-    const InstrInfo& info) {
-  Object& obj = Object::ZoneHandle(zone());
-  if (!ParseDartValue(Retrieve(sexp, 1), &obj)) return nullptr;
-  return new (zone()) ConstantInstr(obj, info.source);
-}
-
-DebugStepCheckInstr* FlowGraphDeserializer::DeserializeDebugStepCheck(
-    SExpList* sexp,
-    const InstrInfo& info) {
-  auto kind = UntaggedPcDescriptors::kAnyKind;
-  if (auto const kind_sexp = CheckSymbol(Retrieve(sexp, "stub_kind"))) {
-    if (!UntaggedPcDescriptors::ParseKind(kind_sexp->value(), &kind)) {
-      StoreError(kind_sexp, "not a valid UntaggedPcDescriptors::Kind name");
-      return nullptr;
-    }
-  }
-  return new (zone()) DebugStepCheckInstr(info.source, kind, info.deopt_id);
-}
-
-GotoInstr* FlowGraphDeserializer::DeserializeGoto(SExpList* sexp,
-                                                  const InstrInfo& info) {
-  auto const block = FetchBlock(CheckSymbol(Retrieve(sexp, 1)));
-  if (block == nullptr) return nullptr;
-  if (!block->IsJoinEntry()) {
-    StoreError(sexp->At(1), "target of goto must be join entry");
-    return nullptr;
-  }
-  return new (zone()) GotoInstr(block->AsJoinEntry(), info.deopt_id);
-}
-
-InstanceCallInstr* FlowGraphDeserializer::DeserializeInstanceCall(
-    SExpList* sexp,
-    const InstrInfo& info) {
-  auto& interface_target = Function::ZoneHandle(zone());
-  auto& tearoff_interface_target = Function::ZoneHandle(zone());
-  if (!ParseDartValue(Retrieve(sexp, "interface_target"), &interface_target)) {
-    return nullptr;
-  }
-  if (!ParseDartValue(Retrieve(sexp, "tearoff_interface_target"),
-                      &tearoff_interface_target)) {
-    return nullptr;
-  }
-  auto& function_name = String::ZoneHandle(zone());
-  // If we have an explicit function_name value, then use that value. Otherwise,
-  // if we have an non-null interface_target, use its name.
-  if (auto const name_sexp = sexp->ExtraLookupValue("function_name")) {
-    if (!ParseDartValue(name_sexp, &function_name)) return nullptr;
-  } else if (!interface_target.IsNull()) {
-    function_name = interface_target.name();
-  } else if (!tearoff_interface_target.IsNull()) {
-    function_name = tearoff_interface_target.name();
-  }
-
-  auto token_kind = Token::Kind::kILLEGAL;
-  if (auto const kind_sexp =
-          CheckSymbol(sexp->ExtraLookupValue("token_kind"))) {
-    if (!Token::FromStr(kind_sexp->value(), &token_kind)) {
-      StoreError(kind_sexp, "unexpected token kind");
-      return nullptr;
-    }
-  }
-
-  CallInfo call_info(zone());
-  if (!ParseCallInfo(sexp, &call_info)) return nullptr;
-
-  intptr_t checked_arg_count = 0;
-  if (auto const checked_sexp =
-          CheckInteger(sexp->ExtraLookupValue("checked_arg_count"))) {
-    checked_arg_count = checked_sexp->value();
-  }
-
-  auto const inst = new (zone()) InstanceCallInstr(
-      info.source, function_name, token_kind, call_info.inputs,
-      call_info.type_args_len, call_info.argument_names, checked_arg_count,
-      info.deopt_id, interface_target, tearoff_interface_target);
-
-  if (call_info.result_type != nullptr) {
-    inst->SetResultType(zone(), *call_info.result_type);
-  }
-
-  inst->set_entry_kind(call_info.entry_kind);
-
-  if (auto const ic_data_sexp =
-          CheckTaggedList(Retrieve(sexp, "ic_data"), "ICData")) {
-    if (!CreateICData(ic_data_sexp, inst)) return nullptr;
-  }
-
-  return inst;
-}
-
-LoadClassIdInstr* FlowGraphDeserializer::DeserializeLoadClassId(
-    SExpList* sexp,
-    const InstrInfo& info) {
-  auto const val = ParseValue(Retrieve(sexp, 1));
-  if (val == nullptr) return nullptr;
-
-  return new (zone()) LoadClassIdInstr(val);
-}
-
-LoadFieldInstr* FlowGraphDeserializer::DeserializeLoadField(
-    SExpList* sexp,
-    const InstrInfo& info) {
-  auto const instance = ParseValue(Retrieve(sexp, 1));
-  if (instance == nullptr) return nullptr;
-
-  const Slot* slot;
-  if (!ParseSlot(CheckTaggedList(Retrieve(sexp, 2)), &slot)) return nullptr;
-
-  bool calls_initializer = false;
-  if (auto const calls_initializer_sexp =
-          CheckBool(sexp->ExtraLookupValue("calls_initializer"))) {
-    calls_initializer = calls_initializer_sexp->value();
-  }
-
-  return new (zone()) LoadFieldInstr(instance, *slot, info.source,
-                                     calls_initializer, info.deopt_id);
-}
-
-NativeCallInstr* FlowGraphDeserializer::DeserializeNativeCall(
-    SExpList* sexp,
-    const InstrInfo& info) {
-  auto& function = Function::ZoneHandle(zone());
-  if (!ParseDartValue(Retrieve(sexp, "function"), &function)) return nullptr;
-  if (!function.IsFunction()) {
-    StoreError(sexp->At(1), "expected a Function value");
-    return nullptr;
-  }
-
-  auto const name_sexp = CheckString(Retrieve(sexp, "name"));
-  if (name_sexp == nullptr) return nullptr;
-  const auto& name =
-      String::ZoneHandle(zone(), String::New(name_sexp->value()));
-
-  bool link_lazily = false;
-  if (auto const link_sexp = CheckBool(sexp->ExtraLookupValue("link_lazily"))) {
-    link_lazily = link_sexp->value();
-  }
-
-  CallInfo call_info(zone());
-  if (!ParseCallInfo(sexp, &call_info)) return nullptr;
-
-  return new (zone()) NativeCallInstr(&name, &function, link_lazily,
-                                      info.source, call_info.inputs);
-}
-
-ParameterInstr* FlowGraphDeserializer::DeserializeParameter(
-    SExpList* sexp,
-    const InstrInfo& info) {
-  ASSERT(current_block_ != nullptr);
-  if (auto const index_sexp = CheckInteger(Retrieve(sexp, 1))) {
-    const auto param_offset_sexp =
-        CheckInteger(sexp->ExtraLookupValue("param_offset"));
-    ASSERT(param_offset_sexp != nullptr);
-    const auto representation_sexp =
-        CheckSymbol(sexp->ExtraLookupValue("representation"));
-    Representation representation;
-    if (!Location::ParseRepresentation(representation_sexp->value(),
-                                       &representation)) {
-      StoreError(representation_sexp, "unknown parameter representation");
-    }
-    return new (zone())
-        ParameterInstr(index_sexp->value(), param_offset_sexp->value(),
-                       current_block_, representation);
-  }
-  return nullptr;
-}
-
-ReturnInstr* FlowGraphDeserializer::DeserializeReturn(SExpList* list,
-                                                      const InstrInfo& info) {
-  Value* val = ParseValue(Retrieve(list, 1));
-  if (val == nullptr) return nullptr;
-  return new (zone()) ReturnInstr(info.source, val, info.deopt_id);
-}
-
-SpecialParameterInstr* FlowGraphDeserializer::DeserializeSpecialParameter(
-    SExpList* sexp,
-    const InstrInfo& info) {
-  ASSERT(current_block_ != nullptr);
-  auto const kind_sexp = CheckSymbol(Retrieve(sexp, 1));
-  if (kind_sexp == nullptr) return nullptr;
-  SpecialParameterInstr::SpecialParameterKind kind;
-  if (!SpecialParameterInstr::ParseKind(kind_sexp->value(), &kind)) {
-    StoreError(kind_sexp, "unknown special parameter kind");
-    return nullptr;
-  }
-  return new (zone())
-      SpecialParameterInstr(kind, info.deopt_id, current_block_);
-}
-
-StaticCallInstr* FlowGraphDeserializer::DeserializeStaticCall(
-    SExpList* sexp,
-    const InstrInfo& info) {
-  auto& function = Function::ZoneHandle(zone());
-  auto const function_sexp =
-      CheckTaggedList(Retrieve(sexp, "function"), "Function");
-  if (!ParseFunction(function_sexp, &function)) return nullptr;
-
-  CallInfo call_info(zone());
-  if (!ParseCallInfo(sexp, &call_info)) return nullptr;
-
-  intptr_t call_count = 0;
-  if (auto const call_count_sexp =
-          CheckInteger(sexp->ExtraLookupValue("call_count"))) {
-    call_count = call_count_sexp->value();
-  }
-
-  auto rebind_rule = ICData::kStatic;
-  if (auto const rebind_sexp =
-          CheckSymbol(sexp->ExtraLookupValue("rebind_rule"))) {
-    if (!ICData::ParseRebindRule(rebind_sexp->value(), &rebind_rule)) {
-      StoreError(rebind_sexp, "unknown rebind rule value");
-      return nullptr;
-    }
-  }
-
-  auto const inst = new (zone()) StaticCallInstr(
-      info.source, function, call_info.type_args_len, call_info.argument_names,
-      call_info.inputs, info.deopt_id, call_count, rebind_rule);
-
-  if (call_info.result_type != nullptr) {
-    inst->SetResultType(zone(), *call_info.result_type);
-  }
-
-  inst->set_entry_kind(call_info.entry_kind);
-
-  if (auto const ic_data_sexp =
-          CheckTaggedList(sexp->ExtraLookupValue("ic_data"), "ICData")) {
-    if (!CreateICData(ic_data_sexp, inst)) return nullptr;
-  }
-
-  return inst;
-}
-
-StoreInstanceFieldInstr* FlowGraphDeserializer::DeserializeStoreInstanceField(
-    SExpList* sexp,
-    const InstrInfo& info) {
-  auto const instance = ParseValue(Retrieve(sexp, 1));
-  if (instance == nullptr) return nullptr;
-
-  const Slot* slot = nullptr;
-  if (!ParseSlot(CheckTaggedList(Retrieve(sexp, 2), "Slot"), &slot)) {
-    return nullptr;
-  }
-
-  auto const value = ParseValue(Retrieve(sexp, 3));
-  if (value == nullptr) return nullptr;
-
-  auto barrier_type = kNoStoreBarrier;
-  if (auto const bar_sexp = CheckBool(sexp->ExtraLookupValue("emit_barrier"))) {
-    if (bar_sexp->value()) barrier_type = kEmitStoreBarrier;
-  }
-
-  auto kind = StoreInstanceFieldInstr::Kind::kOther;
-  if (auto const init_sexp = CheckBool(sexp->ExtraLookupValue("is_init"))) {
-    if (init_sexp->value()) kind = StoreInstanceFieldInstr::Kind::kInitializing;
-  }
-
-  return new (zone()) StoreInstanceFieldInstr(*slot, instance, value,
-                                              barrier_type, info.source, kind);
-}
-
-StrictCompareInstr* FlowGraphDeserializer::DeserializeStrictCompare(
-    SExpList* sexp,
-    const InstrInfo& info) {
-  auto const token_sexp = CheckSymbol(Retrieve(sexp, 1));
-  if (token_sexp == nullptr) return nullptr;
-  Token::Kind kind;
-  if (!Token::FromStr(token_sexp->value(), &kind)) return nullptr;
-
-  auto const left = ParseValue(Retrieve(sexp, 2));
-  if (left == nullptr) return nullptr;
-
-  auto const right = ParseValue(Retrieve(sexp, 3));
-  if (right == nullptr) return nullptr;
-
-  bool needs_check = false;
-  if (auto const check_sexp = CheckBool(Retrieve(sexp, "needs_check"))) {
-    needs_check = check_sexp->value();
-  }
-
-  return new (zone()) StrictCompareInstr(info.source, kind, left, right,
-                                         needs_check, info.deopt_id);
-}
-
-ThrowInstr* FlowGraphDeserializer::DeserializeThrow(SExpList* sexp,
-                                                    const InstrInfo& info) {
-  Value* exception = ParseValue(Retrieve(sexp, 1));
-  if (exception == nullptr) return nullptr;
-  return new (zone()) ThrowInstr(info.source, info.deopt_id, exception);
-}
-
-bool FlowGraphDeserializer::ParseCallInfo(SExpList* call,
-                                          CallInfo* out,
-                                          intptr_t num_extra_inputs) {
-  ASSERT(out != nullptr);
-
-  if (auto const len_sexp =
-          CheckInteger(call->ExtraLookupValue("type_args_len"))) {
-    out->type_args_len = len_sexp->value();
-  }
-
-  if (auto const arg_names_sexp =
-          CheckList(call->ExtraLookupValue("arg_names"))) {
-    out->argument_names = Array::New(arg_names_sexp->Length(), Heap::kOld);
-    for (intptr_t i = 0, n = arg_names_sexp->Length(); i < n; i++) {
-      auto name_sexp = CheckString(Retrieve(arg_names_sexp, i));
-      if (name_sexp == nullptr) return false;
-      tmp_string_ = String::New(name_sexp->value(), Heap::kOld);
-      out->argument_names.SetAt(i, tmp_string_);
-    }
-  }
-
-  if (auto const args_len_sexp =
-          CheckInteger(call->ExtraLookupValue("args_len"))) {
-    out->args_len = args_len_sexp->value();
-  }
-
-  if (auto const result_sexp = CheckTaggedList(
-          call->ExtraLookupValue("result_type"), "CompileType")) {
-    out->result_type = ParseCompileType(result_sexp);
-  }
-
-  if (auto const kind_sexp =
-          CheckSymbol(call->ExtraLookupValue("entry_kind"))) {
-    if (!Code::ParseEntryKind(kind_sexp->value(), &out->entry_kind))
-      return false;
-  }
-
-  // Type arguments are wrapped in a TypeArguments array, so no matter how
-  // many there are, they are contained in a single pushed argument.
-  auto const all_args_len = (out->type_args_len > 0 ? 1 : 0) + out->args_len;
-
-  const intptr_t num_inputs = all_args_len + num_extra_inputs;
-  out->inputs = new (zone()) InputsArray(zone(), num_inputs);
-  for (intptr_t i = 0; i < num_inputs; ++i) {
-    auto const input = ParseValue(Retrieve(call, 1 + i));
-    if (input == nullptr) return false;
-    out->inputs->Add(input);
-  }
-
-  return true;
-}
-
-Value* FlowGraphDeserializer::ParseValue(SExpression* sexp,
-                                         bool allow_pending) {
-  CompileType* type = nullptr;
-  bool inherit_type = false;
-  auto name = sexp->AsSymbol();
-  if (name == nullptr) {
-    auto const list = CheckTaggedList(sexp, "value");
-    name = CheckSymbol(Retrieve(list, 1));
-    if (auto const type_sexp =
-            CheckTaggedList(list->ExtraLookupValue("type"), "CompileType")) {
-      type = ParseCompileType(type_sexp);
-      if (type == nullptr) return nullptr;
-    } else if (auto const inherit_sexp =
-                   CheckBool(list->ExtraLookupValue("inherit_type"))) {
-      inherit_type = inherit_sexp->value();
-    } else {
-      // We assume that the type should be inherited from the definition for
-      // for (value ...) forms without an explicit type.
-      inherit_type = true;
-    }
-  }
-  intptr_t index;
-  if (!ParseUse(name, &index)) return nullptr;
-  auto const def = definition_map_.LookupValue(index);
-  Value* val;
-  if (def == nullptr) {
-    if (!allow_pending) {
-      StoreError(sexp, "found use prior to definition");
-      return nullptr;
-    }
-    val = AddNewPendingValue(sexp, index, inherit_type);
-  } else {
-    val = new (zone()) Value(def);
-    if (inherit_type) {
-      if (def->HasType()) {
-        val->reaching_type_ = def->Type();
-      } else {
-        StoreError(sexp, "value inherits type, but no type found");
-        return nullptr;
-      }
-    }
-  }
-  if (type != nullptr) val->SetReachingType(type);
-  return val;
-}
-
-CompileType* FlowGraphDeserializer::ParseCompileType(SExpList* sexp) {
-  // TODO(sstrickl): Currently we only print out nullable if it's false
-  // (or during verbose printing). Switch this when NNBD is the standard.
-  bool nullable = CompileType::kNullable;
-  if (auto const nullable_sexp =
-          CheckBool(sexp->ExtraLookupValue("nullable"))) {
-    nullable = nullable_sexp->value() ? CompileType::kNullable
-                                      : CompileType::kNonNullable;
-  }
-
-  intptr_t cid = kIllegalCid;
-  if (auto const cid_sexp = CheckInteger(sexp->ExtraLookupValue("cid"))) {
-    // TODO(sstrickl): Check that the cid is a valid concrete cid, or a cid
-    // otherwise found in CompileTypes like kIllegalCid or kDynamicCid.
-    cid = cid_sexp->value();
-  }
-
-  AbstractType* type = nullptr;
-  if (auto const type_sexp = sexp->ExtraLookupValue("type")) {
-    auto& type_handle = AbstractType::ZoneHandle(zone());
-    if (!ParseAbstractType(type_sexp, &type_handle)) return nullptr;
-    type = &type_handle;
-  }
-  return new (zone()) CompileType(nullable, cid, type);
-}
-
-Environment* FlowGraphDeserializer::ParseEnvironment(SExpList* list) {
-  if (list == nullptr) return nullptr;
-  intptr_t fixed_param_count = 0;
-  if (auto const fpc_sexp =
-          CheckInteger(list->ExtraLookupValue("fixed_param_count"))) {
-    fixed_param_count = fpc_sexp->value();
-  }
-  Environment* outer_env = nullptr;
-  if (auto const outer_sexp = CheckList(list->ExtraLookupValue("outer"))) {
-    outer_env = ParseEnvironment(outer_sexp);
-    if (outer_env == nullptr) return nullptr;
-    if (auto const deopt_sexp =
-            CheckInteger(outer_sexp->ExtraLookupValue("deopt_id"))) {
-      outer_env->deopt_id_ = deopt_sexp->value();
-    }
-  }
-
-  ASSERT(parsed_function_ != nullptr);
-  auto const env = new (zone()) Environment(list->Length(), fixed_param_count,
-                                            *parsed_function_, outer_env);
-
-  for (intptr_t i = 0; i < list->Length(); i++) {
-    auto const elem_sexp = Retrieve(list, i);
-    if (elem_sexp == nullptr) return nullptr;
-    auto val = ParseValue(elem_sexp, /*allow_pending=*/false);
-    if (val == nullptr) return nullptr;
-    env->PushValue(val);
-  }
-
-  return env;
-}
-
-bool FlowGraphDeserializer::ParseDartValue(SExpression* sexp, Object* out) {
-  ASSERT(out != nullptr);
-  if (sexp == nullptr) return false;
-  *out = Object::null();
-
-  if (auto const sym = sexp->AsSymbol()) {
-    // We'll use the null value in *out as a marker later, so go ahead and exit
-    // early if we parse one.
-    if (sym->Equals("null")) return true;
-    if (sym->Equals("sentinel")) {
-      *out = Object::sentinel().ptr();
-      return true;
-    }
-
-    // The only other symbols that should appear in Dart value position are
-    // names of constant definitions.
-    auto const val = ParseValue(sym, /*allow_pending=*/false);
-    if (val == nullptr) return false;
-    if (!val->BindsToConstant()) {
-      StoreError(sym, "not a reference to a constant definition");
-      return false;
-    }
-    *out = val->BoundConstant().ptr();
-    // Values used in constant definitions have already been canonicalized,
-    // so just exit.
-    return true;
-  }
-
-  // Other instance values may need to be canonicalized, so do that before
-  // returning.
-  if (auto const b = sexp->AsBool()) {
-    *out = Bool::Get(b->value()).ptr();
-  } else if (auto const str = sexp->AsString()) {
-    *out = String::New(str->value(), Heap::kOld);
-  } else if (auto const i = sexp->AsInteger()) {
-    *out = Integer::New(i->value(), Heap::kOld);
-  } else if (auto const d = sexp->AsDouble()) {
-    *out = Double::New(d->value(), Heap::kOld);
-  } else if (auto const list = CheckTaggedList(sexp)) {
-    auto const tag = list->Tag();
-    if (tag->Equals("Class")) {
-      return ParseClass(list, out);
-    } else if (tag->Equals("Type")) {
-      return ParseType(list, out);
-    } else if (tag->Equals("TypeArguments")) {
-      return ParseTypeArguments(list, out);
-    } else if (tag->Equals("Field")) {
-      return ParseField(list, out);
-    } else if (tag->Equals("Function")) {
-      return ParseFunction(list, out);
-    } else if (tag->Equals("FunctionType")) {
-      return ParseFunctionType(list, out);
-    } else if (tag->Equals("TypeParameter")) {
-      return ParseTypeParameter(list, out);
-    } else if (tag->Equals("Array")) {
-      return ParseArray(list, out);
-    } else if (tag->Equals("ImmutableList")) {
-      return ParseImmutableList(list, out);
-    } else if (tag->Equals("Instance")) {
-      return ParseInstance(list, out);
-    } else if (tag->Equals("Closure")) {
-      return ParseClosure(list, out);
-    } else if (tag->Equals("TypeRef")) {
-      return ParseTypeRef(list, out);
-    }
-  }
-
-  // If we're here and still haven't gotten a non-null value, then something
-  // went wrong. (Likely an unrecognized value.)
-  if (out->IsNull()) {
-    StoreError(sexp, "unhandled Dart value");
-    return false;
-  }
-
-  if (!out->IsInstance()) return true;
-  return CanonicalizeInstance(sexp, out);
-}
-
-bool FlowGraphDeserializer::CanonicalizeInstance(SExpression* sexp,
-                                                 Object* out) {
-  ASSERT(out != nullptr);
-  if (!out->IsInstance()) return true;
-  // Instance::Canonicalize uses the current zone for the passed in thread,
-  // not an explicitly provided zone. This means we cannot be run in a context
-  // where [thread()->zone()] does not match [zone()] (e.g., due to StackZone)
-  // until this is addressed.
-  *out = Instance::Cast(*out).Canonicalize(thread());
-  return true;
-}
-
-bool FlowGraphDeserializer::ParseAbstractType(SExpression* sexp, Object* out) {
-  ASSERT(out != nullptr);
-  if (sexp == nullptr) return false;
-
-  // If it's a symbol, it should be a reference to a constant definition, which
-  // is handled in ParseType.
-  if (auto const sym = sexp->AsSymbol()) {
-    return ParseType(sexp, out);
-  } else if (auto const list = CheckTaggedList(sexp)) {
-    auto const tag = list->Tag();
-    if (tag->Equals("Type")) {
-      return ParseType(list, out);
-    } else if (tag->Equals("TypeParameter")) {
-      return ParseTypeParameter(list, out);
-    } else if (tag->Equals("TypeRef")) {
-      return ParseTypeRef(list, out);
-    }
-  }
-
-  StoreError(sexp, "not an AbstractType");
-  return false;
-}
-
-bool FlowGraphDeserializer::ParseClass(SExpList* list, Object* out) {
-  ASSERT(out != nullptr);
-  if (list == nullptr) return false;
-
-  auto const ref_sexp = Retrieve(list, 1);
-  if (ref_sexp == nullptr) return false;
-  if (auto const cid_sexp = ref_sexp->AsInteger()) {
-    ClassTable* table = thread()->isolate_group()->class_table();
-    if (!table->HasValidClassAt(cid_sexp->value())) {
-      StoreError(cid_sexp, "no valid class found for cid");
-      return false;
-    }
-    *out = table->At(cid_sexp->value());
-  } else if (auto const name_sexp = ref_sexp->AsSymbol()) {
-    if (!ParseCanonicalName(name_sexp, out)) return false;
-    if (!out->IsClass()) {
-      StoreError(name_sexp, "expected the name of a class");
-      return false;
-    }
-  }
-  return true;
-}
-
-bool FlowGraphDeserializer::ParseClosure(SExpList* list, Object* out) {
-  ASSERT(out != nullptr);
-  if (list == nullptr) return false;
-
-  auto& function = Function::ZoneHandle(zone());
-  auto const function_sexp = CheckTaggedList(Retrieve(list, 1), "Function");
-  if (!ParseFunction(function_sexp, &function)) return false;
-
-  auto& context = Context::ZoneHandle(zone());
-  if (list->ExtraLookupValue("context") != nullptr) {
-    StoreError(list, "closures with contexts currently unhandled");
-    return false;
-  }
-
-  auto& inst_type_args = TypeArguments::ZoneHandle(zone());
-  if (auto const type_args_sexp = Retrieve(list, "inst_type_args")) {
-    if (!ParseTypeArguments(type_args_sexp, &inst_type_args)) return false;
-  }
-
-  auto& func_type_args = TypeArguments::ZoneHandle(zone());
-  if (auto const type_args_sexp = Retrieve(list, "func_type_args")) {
-    if (!ParseTypeArguments(type_args_sexp, &func_type_args)) return false;
-  }
-
-  auto& delayed_type_args = TypeArguments::ZoneHandle(zone());
-  if (auto const type_args_sexp = Retrieve(list, "delayed_type_args")) {
-    if (!ParseTypeArguments(type_args_sexp, &delayed_type_args)) {
-      return false;
-    }
-  }
-
-  *out = Closure::New(inst_type_args, func_type_args, delayed_type_args,
-                      function, context, Heap::kOld);
-  return CanonicalizeInstance(list, out);
-}
-
-bool FlowGraphDeserializer::ParseField(SExpList* list, Object* out) {
-  auto const name_sexp = CheckSymbol(Retrieve(list, 1));
-  if (!ParseCanonicalName(name_sexp, out)) return false;
-  if (!out->IsField()) {
-    StoreError(list, "expected a Field name");
-    return false;
-  }
-  return true;
-}
-
-bool FlowGraphDeserializer::ParseFunction(SExpList* list, Object* out) {
-  ASSERT(out != nullptr);
-  if (list == nullptr) return false;
-
-  auto const name_sexp = CheckSymbol(Retrieve(list, 1));
-  if (!ParseCanonicalName(name_sexp, out)) return false;
-  if (!out->IsFunction()) {
-    StoreError(list, "expected a Function name");
-    return false;
-  }
-  auto& function = Function::Cast(*out);
-  // Check the kind expected by the S-expression if one was specified.
-  if (auto const kind_sexp = CheckSymbol(list->ExtraLookupValue("kind"))) {
-    UntaggedFunction::Kind kind;
-    if (!UntaggedFunction::ParseKind(kind_sexp->value(), &kind)) {
-      StoreError(kind_sexp, "unexpected function kind");
-      return false;
-    }
-    if (function.kind() != kind) {
-      auto const kind_str = UntaggedFunction::KindToCString(function.kind());
-      StoreError(list, "retrieved function has kind %s", kind_str);
-      return false;
-    }
-  }
-  return true;
-}
-
-bool FlowGraphDeserializer::ParseFunctionType(SExpList* list, Object* out) {
-  ASSERT(out != nullptr);
-  if (list == nullptr) return false;
-  auto& type_params = TypeArguments::ZoneHandle(zone());
-  if (auto const type_params_sexp = Retrieve(list, "type_params")) {
-    if (!ParseTypeArguments(type_params_sexp, &type_params)) return false;
-  }
-  auto& result_type = AbstractType::ZoneHandle(zone());
-  if (auto const result_type_sexp = Retrieve(list, "result_type")) {
-    if (!ParseAbstractType(result_type_sexp, &result_type)) return false;
-  }
-  auto& parameter_types = Array::ZoneHandle(zone());
-  if (auto const parameter_types_sexp = Retrieve(list, "parameter_types")) {
-    if (!ParseDartValue(parameter_types_sexp, &parameter_types)) return false;
-  }
-  auto& parameter_names = Array::ZoneHandle(zone());
-  if (auto const parameter_names_sexp = Retrieve(list, "parameter_names")) {
-    if (!ParseDartValue(parameter_names_sexp, &parameter_names)) return false;
-  }
-  intptr_t packed_fields;
-  if (auto const packed_fields_sexp =
-          CheckInteger(list->ExtraLookupValue("packed_fields"))) {
-    packed_fields = packed_fields_sexp->value();
-  } else {
-    return false;
-  }
-  auto& sig = FunctionType::ZoneHandle(zone(), FunctionType::New());
-  sig.set_type_parameters(type_params);
-  sig.set_result_type(result_type);
-  sig.set_parameter_types(parameter_types);
-  sig.set_parameter_names(parameter_names);
-  sig.set_packed_fields(packed_fields);
-  *out = sig.ptr();
-  return true;
-}
-
-bool FlowGraphDeserializer::ParseArray(SExpList* list, Object* out) {
-  ASSERT(out != nullptr);
-  if (list == nullptr) return false;
-
-  *out = Array::New(list->Length() - 1, Heap::kOld);
-  auto& arr = Array::Cast(*out);
-  // Arrays may contain other arrays, so we'll need a new handle in which to
-  // store elements.
-  auto& elem = Object::Handle(zone());
-  for (intptr_t i = 1; i < list->Length(); i++) {
-    if (!ParseDartValue(Retrieve(list, i), &elem)) return false;
-    arr.SetAt(i - 1, elem);
-  }
-  if (auto type_args_sexp = list->ExtraLookupValue("type_args")) {
-    if (!ParseTypeArguments(type_args_sexp, &array_type_args_)) return false;
-    arr.SetTypeArguments(array_type_args_);
-  }
-  return true;
-}
-
-bool FlowGraphDeserializer::ParseImmutableList(SExpList* list, Object* out) {
-  if (!ParseArray(list, out)) return false;
-
-  Array::Cast(*out).MakeImmutable();
-  return CanonicalizeInstance(list, out);
-}
-
-bool FlowGraphDeserializer::ParseInstance(SExpList* list, Object* out) {
-  ASSERT(out != nullptr);
-  if (list == nullptr) return false;
-  auto const cid_sexp = CheckInteger(Retrieve(list, 1));
-  if (cid_sexp == nullptr) return false;
-
-  auto const table = thread()->isolate_group()->class_table();
-  if (!table->HasValidClassAt(cid_sexp->value())) {
-    StoreError(cid_sexp, "cid is not valid");
-    return false;
-  }
-
-  ASSERT(cid_sexp->value() != kNullCid);  // Must use canonical instances.
-  ASSERT(cid_sexp->value() != kBoolCid);  // Must use canonical instances.
-  instance_class_ = table->At(cid_sexp->value());
-  *out = Instance::New(instance_class_, Heap::kOld);
-  auto& instance = Instance::Cast(*out);
-
-  if (auto const type_args = list->ExtraLookupValue("type_args")) {
-    instance_type_args_ = TypeArguments::null();
-    if (!ParseTypeArguments(type_args, &instance_type_args_)) return false;
-    if (!instance_class_.IsGeneric()) {
-      StoreError(list,
-                 "type arguments provided for an instance of a "
-                 "non-generic class");
-      return false;
-    }
-    instance.SetTypeArguments(instance_type_args_);
-  }
-
-  // Pick out and store the final instance fields of the class, as values must
-  // be provided for them. Error if there are any non-final instance fields.
-  instance_fields_array_ = instance_class_.fields();
-  auto const field_count = instance_fields_array_.Length();
-  GrowableArray<const Field*> final_fields(zone(), field_count);
-  for (intptr_t i = 0, n = field_count; i < n; i++) {
-    instance_field_ = Field::RawCast(instance_fields_array_.At(i));
-    if (!instance_field_.is_instance()) continue;
-    if (!instance_field_.is_final()) {
-      StoreError(list, "class for instance has non-final instance fields");
-      return false;
-    }
-    auto& fresh_handle = Field::Handle(zone(), instance_field_.ptr());
-    final_fields.Add(&fresh_handle);
-  }
-
-  // If there is no (Fields...) sub-expression or it has no extra info, then
-  // ensure there are no final fields before returning the canonicalized form.
-  SExpList* fields_sexp = nullptr;
-  bool fields_provided = list->Length() > 2;
-  if (fields_provided) {
-    fields_sexp = CheckTaggedList(Retrieve(list, 2), "Fields");
-    if (fields_sexp == nullptr) return false;
-    fields_provided = fields_sexp->ExtraLength() != 0;
-  }
-  if (!fields_provided) {
-    if (!final_fields.is_empty()) {
-      StoreError(list, "values not provided for final fields of instance");
-      return false;
-    }
-    return CanonicalizeInstance(list, out);
-  }
-
-  // At this point, we have final instance field values to set on the new
-  // instance before canonicalization. When setting instance fields, we may
-  // cause field guards to be invalidated. Because of this, we must either be
-  // running on the mutator thread or be at a safepoint when calling `SetField`.
-  //
-  // For IR round-trips, the constants we create have already existed before in
-  // the VM heap, which means field invalidation cannot occur. Thus, we create a
-  // closure that sets the fields of the instance and then conditionally run
-  // that closure at a safepoint if not in the mutator thread.
-  //
-  // TODO(dartbug.com/36882): When deserializing IR that was not generated
-  // during the RoundTripSerialization pass, we are no longer guaranteed that
-  // deserialization of instances will not invalidate field guards. Thus, we may
-  // need to support invalidating field guards on non-mutator threads or fall
-  // back onto forcing the deserialization to happen on the mutator thread.
-  auto set_instance_fields = [&]() {
-    auto& inst = Instance::Cast(*out);
-    // We'll need to allocate a handle for the parsed value as we may have
-    // instances as field values and so this function may be re-entered.
-    auto& value = Object::Handle(zone());
-    for (auto field : final_fields) {
-      tmp_string_ = field->UserVisibleName();
-      auto const name = tmp_string_.ToCString();
-      auto const value_sexp = Retrieve(fields_sexp, name);
-      if (value_sexp == nullptr) {
-        StoreError(list, "no value provided for final instance field %s", name);
-        return false;
-      }
-      if (!ParseDartValue(value_sexp, &value)) return false;
-      inst.SetField(*field, value);
-    }
-    return true;
-  };
-
-  auto const t = Thread::Current();
-  if (!t->IsMutatorThread()) {
-    SafepointOperationScope safepoint_scope(t);
-    if (!set_instance_fields()) return false;
-  } else {
-    if (!set_instance_fields()) return false;
-  }
-
-  return CanonicalizeInstance(list, out);
-}
-
-bool FlowGraphDeserializer::ParseType(SExpression* sexp, Object* out) {
-  ASSERT(out != nullptr);
-  if (sexp == nullptr) return false;
-
-  if (auto const sym = sexp->AsSymbol()) {
-    auto const val = ParseValue(sexp, /*allow_pending=*/false);
-    if (val == nullptr) {
-      StoreError(sexp, "expected type or reference to constant definition");
-      return false;
-    }
-    if (!val->BindsToConstant()) {
-      StoreError(sexp, "reference to non-constant definition");
-      return false;
-    }
-    *out = val->BoundConstant().ptr();
-    if (!out->IsType()) {
-      StoreError(sexp, "expected Type constant");
-      return false;
-    }
-    return true;
-  }
-  auto const list = CheckTaggedList(sexp, "Type");
-  if (list == nullptr) return false;
-
-  const auto hash_sexp = CheckInteger(list->ExtraLookupValue("hash"));
-  const auto is_recursive = hash_sexp != nullptr;
-  // This isn't necessary the hash value we will have in the new FlowGraph, but
-  // it will be how this type is referred to by TypeRefs in the serialized one.
-  auto const old_hash = is_recursive ? hash_sexp->value() : 0;
-  ZoneGrowableArray<TypeRef*>* pending_typerefs = nullptr;
-  if (is_recursive) {
-    if (pending_typeref_map_.LookupValue(old_hash) != nullptr) {
-      StoreError(sexp, "already parsing a type with hash %" Pd64 "",
-                 hash_sexp->value());
-      return false;
-    }
-    pending_typerefs = new (zone()) ZoneGrowableArray<TypeRef*>(zone(), 2);
-    pending_typeref_map_.Insert(old_hash, pending_typerefs);
-  }
-
-  const auto cls_sexp = CheckTaggedList(Retrieve(list, 1), "Class");
-  if (cls_sexp == nullptr) {
-    // TODO(sstrickl): Handle types not derived from classes.
-    StoreError(list, "non-class types not currently handled");
-    return false;
-  }
-  TokenPosition token_pos = TokenPosition::kNoSource;
-  if (const auto pos_sexp = CheckInteger(list->ExtraLookupValue("token_pos"))) {
-    token_pos = TokenPosition::Deserialize(pos_sexp->value());
-  }
-  auto type_args_ptr = &Object::null_type_arguments();
-  if (const auto ta_sexp = list->ExtraLookupValue("type_args")) {
-    // ParseTypeArguments may re-enter ParseType after setting the contents of
-    // the passed in handle, so we need to allocate a new handle here.
-    auto& type_args = TypeArguments::Handle(zone());
-    if (!ParseTypeArguments(ta_sexp, &type_args)) return false;
-    type_args_ptr = &type_args;
-  }
-  // Guaranteed not to re-enter ParseType.
-  if (!ParseClass(cls_sexp, &type_class_)) return false;
-  const Nullability nullability =
-      type_class_.IsNullClass() ? Nullability::kNullable : Nullability::kLegacy;
-  *out = Type::New(type_class_, *type_args_ptr, nullability);
-  auto& type = Type::Cast(*out);
-  if (is_recursive) {
-    while (!pending_typerefs->is_empty()) {
-      auto const ref = pending_typerefs->RemoveLast();
-      ASSERT(ref != nullptr);
-      ref->set_type(type);
-    }
-    pending_typeref_map_.Remove(old_hash);
-
-    // If there are still pending typerefs, we can't canonicalize yet until
-    // an enclosing type where we have resolved them. This is a conservative
-    // check, as we do not ensure that any of the still-pending typerefs are
-    // found within this type.
-    //
-    // This is within the is_recursive check because if this type was
-    // non-recursive, then even if there are pending type refs, we are
-    // guaranteed that none of them are in this type.
-    if (ArePendingTypeRefs()) return true;
-  }
-
-  // Need to set this for canonicalization. We ensure in the serializer
-  // that only finalized types are successfully serialized.
-  type.SetIsFinalized();
-  return CanonicalizeInstance(list, out);
-}
-
-bool FlowGraphDeserializer::ParseTypeArguments(SExpression* sexp, Object* out) {
-  ASSERT(out != nullptr);
-  if (sexp == nullptr) return false;
-
-  if (auto const sym = sexp->AsSymbol()) {
-    auto const val = ParseValue(sexp, /*allow_pending=*/false);
-    if (val == nullptr) {
-      StoreError(sexp,
-                 "expected type arguments or reference to constant definition");
-      return false;
-    }
-    if (!val->BindsToConstant()) {
-      StoreError(sexp, "reference to non-constant definition");
-      return false;
-    }
-    *out = val->BoundConstant().ptr();
-    if (!out->IsTypeArguments()) {
-      StoreError(sexp, "expected TypeArguments constant");
-      return false;
-    }
-    return true;
-  }
-  auto const list = CheckTaggedList(sexp, "TypeArguments");
-  if (list == nullptr) return false;
-
-  *out = TypeArguments::New(list->Length() - 1, Heap::kOld);
-  auto& type_args = TypeArguments::Cast(*out);
-  // We may reenter ParseTypeArguments while parsing one of the elements, so we
-  // need a fresh handle here.
-  auto& elem = AbstractType::Handle(zone());
-  for (intptr_t i = 1, n = list->Length(); i < n; i++) {
-    if (!ParseAbstractType(Retrieve(list, i), &elem)) return false;
-    type_args.SetTypeAt(i - 1, elem);
-  }
-
-  // If there are still pending typerefs, we can't canonicalize yet.
-  if (ArePendingTypeRefs()) return true;
-
-  return CanonicalizeInstance(list, out);
-}
-
-bool FlowGraphDeserializer::ParseTypeParameter(SExpList* list, Object* out) {
-  ASSERT(out != nullptr);
-  if (list == nullptr) return false;
-
-  Class& cls = Class::Handle();
-  if (auto const cid_sexp = CheckInteger(list->ExtraLookupValue("cid"))) {
-    const intptr_t cid = cid_sexp->value();
-    ClassTable* table = thread()->isolate_group()->class_table();
-    if (!table->HasValidClassAt(cid)) {
-      StoreError(cid_sexp, "no valid class found for cid");
-      return false;
-    }
-    cls = table->At(cid);
-  } else {
-    return false;
-  }
-  auto const base_sexp = CheckInteger(list->ExtraLookupValue("base"));
-  if (base_sexp == nullptr) return false;
-  intptr_t base = base_sexp->value();
-  auto const index_sexp = CheckInteger(list->ExtraLookupValue("index"));
-  if (index_sexp == nullptr) return false;
-  intptr_t index = index_sexp->value();
-  auto const name_sexp = CheckSymbol(Retrieve(list, 1));
-  if (name_sexp == nullptr) return false;
-  tmp_string_ = String::New(name_sexp->value());
-
-  *out =
-      TypeParameter::New(cls, base, index, tmp_string_, Object::dynamic_type(),
-                         false, Nullability::kLegacy);
-  TypeParameter::Cast(*out).SetIsFinalized();
-  return CanonicalizeInstance(list, out);
-}
-
-bool FlowGraphDeserializer::ParseTypeRef(SExpList* list, Object* out) {
-  ASSERT(out != nullptr);
-  if (list == nullptr) return false;
-
-  const bool contains_type = list->Length() > 1;
-  if (contains_type) {
-    auto& type = Type::Handle(zone());
-    if (!ParseAbstractType(Retrieve(list, 1), &type)) return false;
-    *out = TypeRef::New(type);
-    // If the TypeRef appears outside the referrent, then the referrent
-    // should be already canonicalized. This serves as a double-check that
-    // is the case.
-    return CanonicalizeInstance(list, out);
-  }
-  // If there is no type in the body, then this must be a referrent to
-  // a Type containing this TypeRef. That means we must have a hash value.
-  auto const hash_sexp = CheckInteger(Retrieve(list, "hash"));
-  if (hash_sexp == nullptr) return false;
-  auto const old_hash = hash_sexp->value();
-  auto const pending = pending_typeref_map_.LookupValue(old_hash);
-  if (pending == nullptr) {
-    StoreError(list, "reference to recursive type found outside type");
-    return false;
-  }
-  *out = TypeRef::New(Object::null_abstract_type());
-  pending->Add(static_cast<TypeRef*>(out));
-
-  // We can only canonicalize TypeRefs appearing within their referrent
-  // when its containing value is canonicalized.
-  return true;
-}
-
-bool FlowGraphDeserializer::ParseCanonicalName(SExpSymbol* sym, Object* obj) {
-  ASSERT(obj != nullptr);
-  if (sym == nullptr) return false;
-  auto const name = sym->value();
-  // TODO(sstrickl): No library URL, handle this better.
-  if (*name == ':') {
-    StoreError(sym, "expected non-empty library");
-    return false;
-  }
-  const char* lib_end = nullptr;
-  if (auto const first = strchr(name, ':')) {
-    lib_end = strchr(first + 1, ':');
-    if (lib_end == nullptr) lib_end = strchr(first + 1, '\0');
-  } else {
-    StoreError(sym, "malformed library");
-    return false;
-  }
-  tmp_string_ =
-      String::FromUTF8(reinterpret_cast<const uint8_t*>(name), lib_end - name);
-  name_library_ = Library::LookupLibrary(thread(), tmp_string_);
-  if (*lib_end == '\0') {
-    *obj = name_library_.ptr();
-    return true;
-  }
-  const char* const class_start = lib_end + 1;
-  if (*class_start == '\0') {
-    StoreError(sym, "no class found after colon");
-    return false;
-  }
-  // If classes are followed by another part, it's either a function
-  // (separated by ':') or a field (separated by '.').
-  const char* class_end = strchr(class_start, ':');
-  if (class_end == nullptr) class_end = strchr(class_start, '.');
-  if (class_end == nullptr) class_end = strchr(class_start, '\0');
-  const bool empty_name = class_end == class_start;
-  name_class_ = Class::null();
-  if (empty_name) {
-    name_class_ = name_library_.toplevel_class();
-  } else {
-    tmp_string_ = String::FromUTF8(
-        reinterpret_cast<const uint8_t*>(class_start), class_end - class_start);
-    name_class_ = name_library_.LookupClassAllowPrivate(tmp_string_);
-  }
-  if (name_class_.IsNull()) {
-    StoreError(sym, "failure looking up class %s in library %s",
-               empty_name ? "at top level" : tmp_string_.ToCString(),
-               name_library_.ToCString());
-    return false;
-  }
-  if (*class_end == '\0') {
-    *obj = name_class_.ptr();
-    return true;
-  }
-  if (*class_end == '.') {
-    if (class_end[1] == '\0') {
-      StoreError(sym, "no field name found after period");
-      return false;
-    }
-    const char* const field_start = class_end + 1;
-    const char* field_end = strchr(field_start, '\0');
-    tmp_string_ = String::FromUTF8(
-        reinterpret_cast<const uint8_t*>(field_start), field_end - field_start);
-    name_field_ = name_class_.LookupFieldAllowPrivate(tmp_string_);
-    if (name_field_.IsNull()) {
-      StoreError(sym, "failure looking up field %s in class %s",
-                 tmp_string_.ToCString(),
-                 empty_name ? "at top level" : name_class_.ToCString());
-      return false;
-    }
-    *obj = name_field_.ptr();
-    return true;
-  }
-  if (class_end[1] == '\0') {
-    StoreError(sym, "no function name found after final colon");
-    return false;
-  }
-  const char* func_start = class_end + 1;
-  name_function_ = Function::null();
-  while (true) {
-    const char* func_end = strchr(func_start, ':');
-    intptr_t name_len = func_end - func_start;
-    bool is_forwarder = false;
-    if (func_end != nullptr && name_len == 3) {
-      // Special case for getters/setters, where they are prefixed with "get:"
-      // or "set:", as those colons should not be used as separators.
-      if (strncmp(func_start, "get", 3) == 0 ||
-          strncmp(func_start, "set", 3) == 0) {
-        func_end = strchr(func_end + 1, ':');
-      } else if (strncmp(func_start, "dyn", 3) == 0) {
-        // Dynamic invocation forwarders start with "dyn:" and we'll need to
-        // look up the base function and then retrieve the forwarder from it.
-        is_forwarder = true;
-        func_start = func_end + 1;
-        func_end = strchr(func_end + 1, ':');
-      }
-    }
-    if (func_end == nullptr) func_end = strchr(func_start, '\0');
-    name_len = func_end - func_start;
-
-    // Check for tearoff names before we overwrite the contents of tmp_string_.
-    if (!name_function_.IsNull()) {
-      ASSERT(!tmp_string_.IsNull());
-      auto const parent_name = tmp_string_.ToCString();
-      // ImplicitClosureFunctions (tearoffs) have the same name as the Function
-      // to which they are attached. We currently don't handle any other kinds
-      // of local functions.
-      if (name_function_.HasImplicitClosureFunction() && *func_end == '\0' &&
-          strncmp(parent_name, func_start, name_len) == 0) {
-        *obj = name_function_.ImplicitClosureFunction();
-        return true;
-      }
-      StoreError(sym, "no handling for local functions");
-      return false;
-    }
-
-    // Check for the prefix "<anonymous ..." in the name and fail if found,
-    // since we can't resolve these.
-    static auto const anon_prefix = "<anonymous ";
-    static const intptr_t prefix_len = strlen(anon_prefix);
-    if ((name_len > prefix_len) &&
-        strncmp(anon_prefix, func_start, prefix_len) == 0) {
-      StoreError(sym, "cannot resolve anonymous values");
-      return false;
-    }
-
-    tmp_string_ = String::FromUTF8(reinterpret_cast<const uint8_t*>(func_start),
-                                   name_len);
-    name_function_ = name_class_.LookupFunctionAllowPrivate(tmp_string_);
-    if (name_function_.IsNull()) {
-      StoreError(sym, "failure looking up function %s in class %s",
-                 tmp_string_.ToCString(), name_class_.ToCString());
-      return false;
-    }
-    if (is_forwarder) {
-      tmp_string_ = name_function_.name();
-      tmp_string_ = Function::CreateDynamicInvocationForwarderName(tmp_string_);
-      name_function_ =
-          name_function_.GetDynamicInvocationForwarder(tmp_string_);
-    }
-    if (func_end[0] == '\0') break;
-    if (func_end[1] == '\0') {
-      StoreError(sym, "no function name found after final colon");
-      return false;
-    }
-    func_start = func_end + 1;
-  }
-  *obj = name_function_.ptr();
-  return true;
-}
-
-bool FlowGraphDeserializer::ParseSlot(SExpList* list, const Slot** out) {
-  ASSERT(out != nullptr);
-  const auto offset_sexp = CheckInteger(Retrieve(list, 1));
-  if (offset_sexp == nullptr) return false;
-  const auto offset = offset_sexp->value();
-
-  const auto kind_sexp = CheckSymbol(Retrieve(list, "kind"));
-  if (kind_sexp == nullptr) return false;
-  Slot::Kind kind;
-  if (!Slot::ParseKind(kind_sexp->value(), &kind)) {
-    StoreError(kind_sexp, "unknown Slot kind");
-    return false;
-  }
-
-  switch (kind) {
-    case Slot::Kind::kDartField: {
-      auto& field = Field::ZoneHandle(zone());
-      const auto field_sexp = CheckTaggedList(Retrieve(list, "field"), "Field");
-      if (!ParseDartValue(field_sexp, &field)) return false;
-      ASSERT(parsed_function_ != nullptr);
-      *out =
-          &Slot::Get(kernel::BaseFlowGraphBuilder::MayCloneField(zone(), field),
-                     parsed_function_);
-      break;
-    }
-    case Slot::Kind::kTypeArguments:
-      *out = &Slot::GetTypeArgumentsSlotAt(thread(), offset);
-      break;
-    case Slot::Kind::kTypeArgumentsIndex:
-      *out = &Slot::GetTypeArgumentsIndexSlot(thread(), offset);
-      break;
-    case Slot::Kind::kArrayElement:
-      *out = &Slot::GetArrayElementSlot(thread(), offset);
-      break;
-    case Slot::Kind::kCapturedVariable:
-      StoreError(kind_sexp, "unhandled Slot kind");
-      return false;
-    default:
-      *out = &Slot::GetNativeSlot(kind);
-      break;
-  }
-  return true;
-}
-
-bool FlowGraphDeserializer::ParseRange(SExpList* list, Range* out) {
-  if (list == nullptr) return false;
-  RangeBoundary min, max;
-  if (!ParseRangeBoundary(Retrieve(list, 1), &min)) return false;
-  if (list->Length() == 2) {
-    max = min;
-  } else {
-    if (!ParseRangeBoundary(Retrieve(list, 2), &max)) return false;
-  }
-  out->min_ = min;
-  out->max_ = max;
-  return true;
-}
-
-bool FlowGraphDeserializer::ParseRangeBoundary(SExpression* sexp,
-                                               RangeBoundary* out) {
-  if (sexp == nullptr) return false;
-  if (auto const int_sexp = sexp->AsInteger()) {
-    out->kind_ = RangeBoundary::Kind::kConstant;
-    out->value_ = int_sexp->value();
-  } else if (auto const sym_sexp = sexp->AsSymbol()) {
-    if (!RangeBoundary::ParseKind(sym_sexp->value(), &out->kind_)) return false;
-  } else if (auto const list_sexp = sexp->AsList()) {
-    intptr_t index;
-    if (!ParseUse(CheckSymbol(Retrieve(list_sexp, 1)), &index)) return false;
-    auto const def = definition_map_.LookupValue(index);
-    if (def == nullptr) {
-      StoreError(list_sexp, "no definition for symbolic range boundary");
-      return false;
-    }
-    out->kind_ = RangeBoundary::Kind::kSymbol;
-    out->value_ = reinterpret_cast<intptr_t>(def);
-    if (auto const offset_sexp =
-            CheckInteger(list_sexp->ExtraLookupValue("offset"))) {
-      auto const offset = offset_sexp->value();
-      if (!RangeBoundary::IsValidOffsetForSymbolicRangeBoundary(offset)) {
-        StoreError(sexp, "invalid offset for symbolic range boundary");
-        return false;
-      }
-      out->offset_ = offset;
-    }
-  } else {
-    StoreError(sexp, "unexpected value for range boundary");
-    return false;
-  }
-  return true;
-}
-
-bool FlowGraphDeserializer::ParseBlockId(SExpSymbol* sym, intptr_t* out) {
-  return ParseSymbolAsPrefixedInt(sym, 'B', out);
-}
-
-bool FlowGraphDeserializer::ParseSSATemp(SExpSymbol* sym, intptr_t* out) {
-  return ParseSymbolAsPrefixedInt(sym, 'v', out);
-}
-
-bool FlowGraphDeserializer::ParseUse(SExpSymbol* sym, intptr_t* out) {
-  // TODO(sstrickl): Handle non-SSA temp uses.
-  return ParseSSATemp(sym, out);
-}
-
-bool FlowGraphDeserializer::ParseSymbolAsPrefixedInt(SExpSymbol* sym,
-                                                     char prefix,
-                                                     intptr_t* out) {
-  ASSERT(out != nullptr);
-  if (sym == nullptr) return false;
-  auto const name = sym->value();
-  if (*name != prefix) {
-    StoreError(sym, "expected symbol starting with '%c'", prefix);
-    return false;
-  }
-  int64_t i;
-  if (!OS::StringToInt64(name + 1, &i)) {
-    StoreError(sym, "expected number following symbol prefix '%c'", prefix);
-    return false;
-  }
-  *out = i;
-  return true;
-}
-
-bool FlowGraphDeserializer::ArePendingTypeRefs() const {
-  // We'll do a deep check, because while there may be recursive types still
-  // being parsed, if there are no pending type refs to those recursive types,
-  // we're still good to canonicalize.
-  if (pending_typeref_map_.IsEmpty()) return false;
-  auto it = pending_typeref_map_.GetIterator();
-  while (auto kv = it.Next()) {
-    if (!kv->value->is_empty()) return true;
-  }
-  return false;
-}
-
-bool FlowGraphDeserializer::CreateICData(SExpList* list, Instruction* inst) {
-  ASSERT(inst != nullptr);
-  if (list == nullptr) return false;
-
-  const String* function_name = nullptr;
-  Array& arguments_descriptor = Array::Handle(zone());
-  intptr_t num_args_checked;
-  ICData::RebindRule rebind_rule;
-
-  if (auto const call = inst->AsInstanceCall()) {
-    function_name = &call->function_name();
-    arguments_descriptor = call->GetArgumentsDescriptor();
-    num_args_checked = call->checked_argument_count();
-    rebind_rule = ICData::RebindRule::kInstance;
-  } else if (auto const call = inst->AsStaticCall()) {
-    function_name = &String::Handle(zone(), call->function().name());
-    arguments_descriptor = call->GetArgumentsDescriptor();
-    num_args_checked =
-        MethodRecognizer::NumArgsCheckedForStaticCall(call->function());
-    rebind_rule = ICData::RebindRule::kStatic;
-  } else {
-    StoreError(list, "unexpected instruction type for ICData");
-    return false;
-  }
-
-  auto type_ptr = &Object::null_abstract_type();
-  if (auto const type_sexp = list->ExtraLookupValue("receivers_static_type")) {
-    auto& type = AbstractType::ZoneHandle(zone());
-    if (!ParseAbstractType(type_sexp, &type)) return false;
-    type_ptr = &type;
-  }
-
-  ASSERT(parsed_function_ != nullptr);
-  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));
-
-  if (auto const is_mega_sexp =
-          CheckBool(list->ExtraLookupValue("is_megamorphic"))) {
-    ic_data.set_is_megamorphic(is_mega_sexp->value());
-  }
-
-  auto const class_table = thread()->isolate_group()->class_table();
-  GrowableArray<intptr_t> class_ids(zone(), 2);
-  for (intptr_t i = 1, n = list->Length(); i < n; i++) {
-    auto const entry = CheckList(Retrieve(list, i));
-    if (entry == nullptr) return false;
-    ASSERT(ic_data.NumArgsTested() == entry->Length());
-
-    intptr_t count = 0;
-    if (auto const count_sexp =
-            CheckInteger(entry->ExtraLookupValue("count"))) {
-      count = count_sexp->value();
-    }
-
-    auto& target = Function::ZoneHandle(zone());
-    if (!ParseDartValue(Retrieve(entry, "target"), &target)) return false;
-
-    // We can't use AddCheck for NumArgsTested < 2. We'll handle 0 here, and
-    // 1 after the for loop.
-    if (entry->Length() == 0) {
-      if (count != 0) {
-        StoreError(entry, "expected a zero count for no checked args");
-        return false;
-      }
-      ic_data = ICData::NewForStaticCall(parsed_function_->function(), target,
-                                         arguments_descriptor, inst->deopt_id(),
-                                         num_args_checked, rebind_rule);
-      continue;
-    }
-
-    class_ids.Clear();
-    for (intptr_t j = 0, num_cids = entry->Length(); j < num_cids; j++) {
-      auto const cid_sexp = CheckInteger(Retrieve(entry, j));
-      if (cid_sexp == nullptr) return false;
-      const intptr_t cid = cid_sexp->value();
-      // kObjectCid is a special case used for AddTarget() entries with
-      // a non-zero number of checked arguments.
-      if (cid != kObjectCid && !class_table->HasValidClassAt(cid)) {
-        StoreError(cid_sexp, "cid is not a valid class");
-        return false;
-      }
-      class_ids.Add(cid);
-    }
-
-    if (entry->Length() == 1) {
-      ic_data.AddReceiverCheck(class_ids.At(0), target, count);
-    } else {
-      ic_data.AddCheck(class_ids, target, count);
-    }
-  }
-
-  if (auto const call = inst->AsInstanceCall()) {
-    call->set_ic_data(const_cast<const ICData*>(&ic_data));
-  } else if (auto const call = inst->AsStaticCall()) {
-    call->set_ic_data(&ic_data);
-  }
-
-  return true;
-}
-
-Value* FlowGraphDeserializer::AddNewPendingValue(SExpression* sexp,
-                                                 intptr_t index,
-                                                 bool inherit_type) {
-  ASSERT(flow_graph_ != nullptr);
-  auto const value = new (zone()) Value(flow_graph_->constant_null());
-  ASSERT(!definition_map_.HasKey(index));
-  auto list = values_map_.LookupValue(index);
-  if (list == nullptr) {
-    list = new (zone()) ZoneGrowableArray<PendingValue>(zone(), 2);
-    values_map_.Insert(index, list);
-  }
-  list->Add({sexp, value, inherit_type});
-  return value;
-}
-
-bool FlowGraphDeserializer::FixPendingValues(intptr_t index, Definition* def) {
-  if (auto value_list = values_map_.LookupValue(index)) {
-    for (intptr_t i = 0; i < value_list->length(); i++) {
-      const auto& value_info = value_list->At(i);
-      auto const value = value_info.value;
-      const bool inherit_type = value_info.inherit_type;
-      value->BindTo(def);
-      if (!inherit_type) continue;
-      if (def->HasType()) {
-        value->reaching_type_ = def->Type();
-      } else {
-        StoreError(value_info.sexp, "value inherits type, but no type found");
-        return false;
-      }
-    }
-    values_map_.Remove(index);
-  }
-  return true;
-}
-
-BlockEntryInstr* FlowGraphDeserializer::FetchBlock(SExpSymbol* sym) {
-  if (sym == nullptr) return nullptr;
-  intptr_t block_id;
-  if (!ParseBlockId(sym, &block_id)) return nullptr;
-  auto const entry = block_map_.LookupValue(block_id);
-  if (entry == nullptr) {
-    StoreError(sym, "reference to undefined block");
-    return nullptr;
-  }
-  return entry;
-}
-
-#define BASE_CHECK_DEF(name, type)                                             \
-  SExp##name* FlowGraphDeserializer::Check##name(SExpression* sexp) {          \
-    if (sexp == nullptr) return nullptr;                                       \
-    if (!sexp->Is##name()) {                                                   \
-      StoreError(sexp, "expected " #name);                                     \
-      return nullptr;                                                          \
-    }                                                                          \
-    return sexp->As##name();                                                   \
-  }
-
-FOR_EACH_S_EXPRESSION(BASE_CHECK_DEF)
-
-#undef BASE_CHECK_DEF
-
-bool FlowGraphDeserializer::IsTag(SExpression* sexp, const char* label) {
-  auto const sym = CheckSymbol(sexp);
-  if (sym == nullptr) return false;
-  if (label != nullptr && !sym->Equals(label)) {
-    StoreError(sym, "expected symbol %s", label);
-    return false;
-  }
-  return true;
-}
-
-SExpList* FlowGraphDeserializer::CheckTaggedList(SExpression* sexp,
-                                                 const char* label) {
-  auto const list = CheckList(sexp);
-  const intptr_t tag_pos = 0;
-  if (!IsTag(Retrieve(list, tag_pos), label)) return nullptr;
-  return list;
-}
-
-void FlowGraphDeserializer::StoreError(SExpression* sexp,
-                                       const char* format,
-                                       ...) {
-  va_list args;
-  va_start(args, format);
-  const char* const message = OS::VSCreate(zone(), format, args);
-  va_end(args);
-  error_sexp_ = sexp;
-  error_message_ = message;
-}
-
-void FlowGraphDeserializer::ReportError() const {
-  ASSERT(error_sexp_ != nullptr);
-  ASSERT(error_message_ != nullptr);
-  OS::PrintErr("Unable to deserialize flow_graph: %s\n", error_message_);
-  OS::PrintErr("Error at S-expression %s\n", error_sexp_->ToCString(zone()));
-  OS::Abort();
-}
-
-}  // namespace dart
diff --git a/runtime/vm/compiler/backend/il_deserializer.h b/runtime/vm/compiler/backend/il_deserializer.h
deleted file mode 100644
index 5049850..0000000
--- a/runtime/vm/compiler/backend/il_deserializer.h
+++ /dev/null
@@ -1,421 +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.
-
-#ifndef RUNTIME_VM_COMPILER_BACKEND_IL_DESERIALIZER_H_
-#define RUNTIME_VM_COMPILER_BACKEND_IL_DESERIALIZER_H_
-
-#if defined(DART_PRECOMPILED_RUNTIME)
-#error "AOT runtime should not use compiler sources (including header files)"
-#endif  // defined(DART_PRECOMPILED_RUNTIME)
-
-#include "platform/assert.h"
-
-#include "vm/allocation.h"
-#include "vm/compiler/backend/flow_graph.h"
-#include "vm/compiler/backend/il.h"
-#include "vm/compiler/backend/sexpression.h"
-#include "vm/compiler/compiler_pass.h"
-#include "vm/object.h"
-#include "vm/parser.h"
-#include "vm/thread.h"
-#include "vm/zone.h"
-
-namespace dart {
-
-// Deserializes FlowGraphs from S-expressions.
-class FlowGraphDeserializer : ValueObject {
- public:
-  // Adds to the given array all the instructions in the flow graph that are
-  // guaranteed not to be handled by the current implementation of the
-  // FlowGraphDeserializer. This way, we can filter out graphs that are
-  // guaranteed not to be deserializable before going through the round-trip
-  // serialization process.
-  //
-  // Note that there may be other reasons that the deserializer may fail on
-  // a given flow graph, so no new members of the array is necessary, but not
-  // sufficient, for a successful round-trip pass.
-  static void AllUnhandledInstructions(const FlowGraph* graph,
-                                       GrowableArray<Instruction*>* out);
-
-  // Takes the FlowGraph from [state] and runs it through the serializer
-  // and deserializer. If the deserializer successfully deserializes the
-  // graph, then the FlowGraph in [state] is replaced with the new one.
-  static void RoundTripSerialization(CompilerPassState* state);
-
-  FlowGraphDeserializer(Thread* thread,
-                        Zone* zone,
-                        SExpression* root,
-                        const ParsedFunction* pf = nullptr)
-      : thread_(ASSERT_NOTNULL(thread)),
-        zone_(ASSERT_NOTNULL(zone)),
-        root_sexp_(ASSERT_NOTNULL(root)),
-        parsed_function_(pf),
-        block_map_(zone),
-        definition_map_(zone),
-        values_map_(zone),
-        recursive_types_map_(zone),
-        pending_typeref_map_(zone),
-        array_type_args_(TypeArguments::Handle(zone)),
-        instance_class_(Class::Handle(zone)),
-        instance_field_(Field::Handle(zone)),
-        instance_fields_array_(Array::Handle(zone)),
-        instance_type_args_(TypeArguments::Handle(zone)),
-        name_class_(Class::Handle(zone)),
-        name_field_(Field::Handle(zone)),
-        name_function_(Function::Handle(zone)),
-        name_library_(Library::Handle(zone)),
-        type_class_(Class::Handle(zone)),
-        type_param_class_(Class::Handle(zone)),
-        tmp_string_(String::Handle(zone)) {
-    // See canonicalization comment in ParseDartValue as to why this is
-    // currently necessary.
-    ASSERT(thread->zone() == zone);
-  }
-
-  // Walks [root_sexp_] and constructs a new FlowGraph.
-  FlowGraph* ParseFlowGraph();
-
-  const char* error_message() const { return error_message_; }
-  SExpression* error_sexp() const { return error_sexp_; }
-
-  // Prints the current error information to stderr and aborts.
-  DART_NORETURN void ReportError() const;
-
- private:
-#define FOR_EACH_HANDLED_BLOCK_TYPE_IN_DESERIALIZER(M)                         \
-  M(FunctionEntry)                                                             \
-  M(GraphEntry)                                                                \
-  M(JoinEntry)                                                                 \
-  M(TargetEntry)
-
-#define FOR_EACH_HANDLED_INSTRUCTION_IN_DESERIALIZER(M)                        \
-  M(AllocateObject)                                                            \
-  M(AssertAssignable)                                                          \
-  M(AssertBoolean)                                                             \
-  M(BooleanNegate)                                                             \
-  M(Branch)                                                                    \
-  M(CheckNull)                                                                 \
-  M(CheckStackOverflow)                                                        \
-  M(Constant)                                                                  \
-  M(DebugStepCheck)                                                            \
-  M(Goto)                                                                      \
-  M(InstanceCall)                                                              \
-  M(LoadClassId)                                                               \
-  M(LoadField)                                                                 \
-  M(NativeCall)                                                                \
-  M(Parameter)                                                                 \
-  M(Return)                                                                    \
-  M(SpecialParameter)                                                          \
-  M(StaticCall)                                                                \
-  M(StoreInstanceField)                                                        \
-  M(StrictCompare)                                                             \
-  M(Throw)
-
-  // Helper methods for AllUnhandledInstructions.
-  static bool IsHandledInstruction(Instruction* inst);
-  static bool IsHandledConstant(const Object& obj);
-
-  // **GENERAL DESIGN NOTES FOR PARSING METHODS**
-  //
-  // For functions that take an SExpression or a subclass, they should return
-  // an error signal (false, nullptr, etc.) without changing the error state if
-  // passed in nullptr. This way, methods can be chained without intermediate
-  // checking.
-  //
-  // Also, for parsing methods for expressions that are known to be of a certain
-  // form, they will take the appropriate subclass of SExpression and assume
-  // that the form was already pre-checked by the caller. For forms that are
-  // tagged lists, this includes the fact that there is at least one element
-  // and the first element is a symbol. If the form can only have one possible
-  // tag, they also assume the tag has already been checked.
-
-  // Helper functions that do length/key exists checking and also check that
-  // the retrieved element is not nullptr. Notably, do not use these if the
-  // retrieved element is optional, to avoid changing the error state
-  // unnecessarily.
-  SExpression* Retrieve(SExpList* list, intptr_t index);
-  SExpression* Retrieve(SExpList* list, const char* key);
-
-  bool ParseConstantPool(SExpList* pool);
-  bool ParseEntries(SExpList* list);
-
-  using BlockWorklist = GrowableArray<intptr_t>;
-
-  // Starts parsing the contents of [list], where the blocks begin at position
-  // [pos] and [worklist] contains the blocks whose body instructions should
-  // be parsed first.
-  bool ParseBlocks(SExpList* list, intptr_t pos, BlockWorklist* worklist);
-
-  // Block parsing is split into two passes. This pass adds function entries
-  // to the flow graph and also parses initial definitions found in the Entries
-  // list. The block is added to the [block_map_] before returning.
-  BlockEntryInstr* ParseBlockHeader(SExpList* list,
-                                    intptr_t block_id,
-                                    SExpSymbol* tag);
-
-  // Expects [current_block_] to be set before calling.
-  bool ParseInitialDefinitions(SExpList* list);
-
-  // Expects [current_block_] to be set before calling.
-  // Takes the tagged list to parse and the index where parsing should start.
-  // Attempts to parse Phi definitions until the first non-Phi instruction.
-  bool ParsePhis(SExpList* list);
-
-  // Expects [current_block_] to be set before calling.
-  // Returns the position of the first non-Phi instruction in a block.
-  intptr_t SkipPhis(SExpList* list);
-
-  // Parses the deopt environment, Phi definitions for JoinEntrys, and the
-  // instructions in the body of the block. Adds the IDs of the block successors
-  // to the worklist, if any. [current_block_] and [pushed_stack_] must be set
-  // before calling.
-  bool ParseBlockContents(SExpList* list, BlockWorklist* worklist);
-
-  // Helper function used by ParseConstantPool, ParsePhis, and ParseDefinition.
-  // This handles all the extra information stored in (def ...) expressions,
-  // and also ensures the index of the definition is appropriately adjusted to
-  // match those found in the serialized form.
-  bool ParseDefinitionWithParsedBody(SExpList* list, Definition* def);
-
-  Definition* ParseDefinition(SExpList* list);
-  Instruction* ParseInstruction(SExpList* list);
-
-  struct EntryInfo {
-    intptr_t block_id;
-    intptr_t try_index;
-    intptr_t deopt_id;
-  };
-
-#define HANDLER_DECL(name)                                                     \
-  name##Instr* Deserialize##name(SExpList* list, const EntryInfo& info);
-
-  FOR_EACH_HANDLED_BLOCK_TYPE_IN_DESERIALIZER(HANDLER_DECL);
-
-#undef HANDLER_DECL
-
-  struct InstrInfo {
-    const intptr_t deopt_id;
-    const InstructionSource source;
-  };
-
-  enum HandledInstruction {
-#define HANDLED_INST_DECL(name) kHandled##name,
-    FOR_EACH_HANDLED_INSTRUCTION_IN_DESERIALIZER(HANDLED_INST_DECL)
-#undef HANDLED_INST_DECL
-    // clang-format off
-    kHandledInvalid = -1,
-    // clang-format on
-  };
-
-#define HANDLE_CASE(name)                                                      \
-  if (strcmp(tag->value(), #name) == 0) return kHandled##name;
-  HandledInstruction HandledInstructionForTag(SExpSymbol* tag) {
-    ASSERT(tag != nullptr);
-    FOR_EACH_HANDLED_INSTRUCTION_IN_DESERIALIZER(HANDLE_CASE)
-    return kHandledInvalid;
-  }
-#undef HANDLE_CASE
-
-#define HANDLER_DECL(name)                                                     \
-  name##Instr* Deserialize##name(SExpList* list, const InstrInfo& info);
-
-  FOR_EACH_HANDLED_INSTRUCTION_IN_DESERIALIZER(HANDLER_DECL);
-
-#undef HANDLER_DECL
-
-  // Common information parsed from call instruction S-expressions.
-  struct CallInfo : public ValueObject {
-    explicit CallInfo(Zone* zone) : argument_names(Array::ZoneHandle(zone)) {}
-
-    Array& argument_names;
-    intptr_t type_args_len = 0;
-    intptr_t args_len = 0;
-    InputsArray* inputs = nullptr;
-    CompileType* result_type = nullptr;
-    Code::EntryKind entry_kind = Code::EntryKind::kNormal;
-  };
-
-  // Helper function for parsing call instructions that returns a structure
-  // of information common to all calls.
-  bool ParseCallInfo(SExpList* call,
-                     CallInfo* out,
-                     intptr_t num_extra_inputs = 0);
-
-  // Parses [sexp] as a value form, that is, either the binding name for
-  // a definition as a symbol or the form (value <name> { ... }).
-  // If [allow_pending], then values for definitions not already in the
-  // [definition_map_] will be added to the [values_map_], otherwise,
-  // values for definitions not yet seen cause an error to be stored and
-  // nullptr to be returned.
-  Value* ParseValue(SExpression* sexp, bool allow_pending = true);
-  CompileType* ParseCompileType(SExpList* list);
-
-  // Parses [list] as an environment form: a list containing either binding
-  // names for definitions or a# for pushed arguments (where # is the depth
-  // of the argument from the top of the stack). Requires [pushed_stack_] to
-  // be set if any references to pushed arguments are found.
-  Environment* ParseEnvironment(SExpList* list);
-
-  // Parsing functions for which there are no good distinguished error
-  // values, so use out parameters and a boolean return instead.
-
-  // Parses a Dart value and returns a canonicalized result.
-  bool ParseDartValue(SExpression* sexp, Object* out);
-
-  // Canonicalizes and replaces the original contents of the handle pointed to
-  // by [inst] if [inst] is an Instance (if not, it trivially succeeds). The
-  // replacement happens whether successful or not. [sexp] is the SExpression
-  // to be used for error reporting.
-  bool CanonicalizeInstance(SExpression* sexp, Object* inst);
-
-  // Helper functions for ParseDartValue for parsing particular type of values.
-  // If necessary, they canonicalize the returned value, and so may be used
-  // directly by other code as well. Helpers that take SExpression* take either
-  // serialized constants or references to constant definitions.
-  //
-  // Due to particulars of operator=() on non-Object values, for a given X,
-  // ParseX takes Object* instead of X* for the out parameter.
-  bool ParseAbstractType(SExpression* sexp, Object* out);
-  bool ParseClass(SExpList* list, Object* out);
-  bool ParseClosure(SExpList* list, Object* out);
-  bool ParseField(SExpList* list, Object* out);
-  bool ParseFunction(SExpList* list, Object* out);
-  bool ParseSignature(SExpList* list, Object* out);
-  bool ParseArray(SExpList* list, Object* out);
-  bool ParseImmutableList(SExpList* list, Object* out);
-  bool ParseInstance(SExpList* list, Object* out);
-  bool ParseType(SExpression* sexp, Object* out);
-  bool ParseFunctionType(SExpList* list, Object* out);
-  bool ParseTypeParameter(SExpList* list, Object* out);
-  bool ParseTypeArguments(SExpression* sexp, Object* out);
-  bool ParseTypeRef(SExpList* list, Object* out);
-
-  bool ParseCanonicalName(SExpSymbol* sym, Object* out);
-
-  const Field& MayCloneField(const Field& field) const;
-  bool ParseSlot(SExpList* list, const Slot** out);
-  bool ParseRange(SExpList* list, Range* out);
-  bool ParseRangeBoundary(SExpression* sexp, RangeBoundary* out);
-
-  bool ParseBlockId(SExpSymbol* sym, intptr_t* out);
-  bool ParseSSATemp(SExpSymbol* sym, intptr_t* out);
-  bool ParseUse(SExpSymbol* sym, intptr_t* out);
-  bool ParseSymbolAsPrefixedInt(SExpSymbol* sym, char prefix, intptr_t* out);
-
-  bool ArePendingTypeRefs() const;
-
-  // Allocates a new ICData structure. [list] is the ICData S-expression, while
-  // [inst] is the Instruction generated from the instruction S-expression
-  // containing [list].
-  bool CreateICData(SExpList* list, Instruction* inst);
-
-  // Helper function for creating a placeholder value when the definition
-  // with index [i] has not yet been seen. If [inherit_type], then the type of
-  // the definition should be used as the reaching type for the use. [s] is used
-  // for any errors that occur when resolving the pending value.
-  Value* AddNewPendingValue(SExpression* s, intptr_t i, bool inherit_type);
-
-  // Helper function for rebinding values pending on this definition.
-  bool FixPendingValues(intptr_t index, Definition* def);
-
-  // Retrieves the block corresponding to the given block ID symbol from
-  // [block_map_]. Assumes all blocks have had their header parsed.
-  BlockEntryInstr* FetchBlock(SExpSymbol* sym);
-
-  // Utility functions for checking the shape of an S-expression.
-  // If these functions return nullptr for a non-null argument, they have the
-  // side effect of setting the stored error message.
-#define BASE_CHECK_DECL(name, type) SExp##name* Check##name(SExpression* sexp);
-  FOR_EACH_S_EXPRESSION(BASE_CHECK_DECL)
-#undef BASE_CHECK_DECL
-
-  // Checks whether [sexp] is a symbol with the given label.
-  bool IsTag(SExpression* sexp, const char* label);
-
-  // A version of CheckList that also checks that the list has at least one
-  // element and that the first element is a symbol. If [label] is non-null,
-  // then the initial symbol element is checked against it.
-  SExpList* CheckTaggedList(SExpression* sexp, const char* label = nullptr);
-
-  // Stores appropriate error information using the SExpression as the location
-  // and the rest of the arguments as an error message for the user.
-  void StoreError(SExpression* s, const char* fmt, ...) PRINTF_ATTRIBUTE(3, 4);
-
-  Thread* thread() const { return thread_; }
-  Zone* zone() const { return zone_; }
-
-  Thread* const thread_;
-  Zone* const zone_;
-  SExpression* const root_sexp_;
-  const ParsedFunction* parsed_function_;
-
-  FlowGraph* flow_graph_ = nullptr;
-  BlockEntryInstr* current_block_ = nullptr;
-  intptr_t max_block_id_ = -1;
-  intptr_t max_ssa_index_ = -1;
-
-  // Map from block IDs to blocks. Does not contain an entry for block 0
-  // (the graph entry), since it is only used at known points and is already
-  // available via [flow_graph_].
-  IntMap<BlockEntryInstr*> block_map_;
-
-  // Map from variable indexes to definitions.
-  IntMap<Definition*> definition_map_;
-
-  // Information needed to handle uses seen prior to their definitions.
-  struct PendingValue {
-    // SExpression used for error reporting.
-    SExpression* sexp;
-    // Value to be rebound once the right definition is found.
-    Value* value;
-    // Whether the type should inherit the type of the found definition.
-    bool inherit_type;
-  };
-
-  // Map from variable indices to lists of values. The list of values are
-  // values that were parsed prior to the corresponding definition being found.
-  IntMap<ZoneGrowableArray<PendingValue>*> values_map_;
-
-  // Map from hash values to SExpLists. This is used by ParseTypeRef to
-  // determine whether or not the recursive type it refers to is being currently
-  // built. The SExpList can be used to report hash collisions.
-  IntMap<SExpList*> recursive_types_map_;
-
-  // Map from hash values to arrays of TypeRefs. This is used by ParseType and
-  // ParseTypeRef to store and later fill in TypeRefs pending on the type being
-  // constructed. Since entries are added at the start of parsing recursive
-  // Type S-exps and removed before the resulting Type is successfully returned,
-  // this map should be empty outside of parsing recursive types.
-  IntMap<ZoneGrowableArray<TypeRef*>*> pending_typeref_map_;
-
-  // Temporary handles used by functions that are not re-entrant or where the
-  // handle is not live after the re-entrant call. Comments show which handles
-  // are expected to only be used within a single method.
-  TypeArguments& array_type_args_;     // ParseImmutableList
-  Class& instance_class_;              // ParseInstance
-  Field& instance_field_;              // ParseInstance
-  Array& instance_fields_array_;       // ParseInstance
-  TypeArguments& instance_type_args_;  // ParseInstance
-  Class& name_class_;                  // ParseCanonicalName
-  Field& name_field_;                  // ParseCanonicalName
-  Function& name_function_;            // ParseCanonicalName
-  Library& name_library_;              // ParseCanonicalName
-  Class& type_class_;                  // ParseType
-  Class& type_param_class_;            // ParseTypeParameter
-  // Uses of string handles tend to be immediate, so we only need one.
-  String& tmp_string_;
-
-  // Stores a message appropriate to surfacing to the user when an error
-  // occurs.
-  const char* error_message_ = nullptr;
-  // Stores the location of the deserialization error by containing the
-  // S-expression which caused the failure.
-  SExpression* error_sexp_ = nullptr;
-
-  DISALLOW_COPY_AND_ASSIGN(FlowGraphDeserializer);
-};
-
-}  // namespace dart
-
-#endif  // RUNTIME_VM_COMPILER_BACKEND_IL_DESERIALIZER_H_
diff --git a/runtime/vm/compiler/backend/il_ia32.cc b/runtime/vm/compiler/backend/il_ia32.cc
index e192ce4..8c6fe6d 100644
--- a/runtime/vm/compiler/backend/il_ia32.cc
+++ b/runtime/vm/compiler/backend/il_ia32.cc
@@ -29,6 +29,9 @@
 
 namespace dart {
 
+DECLARE_FLAG(bool, inline_alloc);
+DECLARE_FLAG(bool, use_slow_path);
+
 // Generic summary for call instructions that have all arguments pushed
 // on the stack and return the result in a fixed register EAX.
 LocationSummary* Instruction::MakeCallSummary(Zone* zone,
@@ -508,7 +511,25 @@
   return summary;
 }
 
-static Condition TokenKindToSmiCondition(Token::Kind kind) {
+void AssertBooleanInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  ASSERT(locs()->always_calls());
+
+  auto object_store = compiler->isolate_group()->object_store();
+  const auto& assert_boolean_stub =
+      Code::ZoneHandle(compiler->zone(), object_store->assert_boolean_stub());
+
+  compiler::Label done;
+  __ testl(
+      AssertBooleanABI::kObjectReg,
+      compiler::Immediate(compiler::target::ObjectAlignment::kBoolVsNullMask));
+  __ j(NOT_ZERO, &done, compiler::Assembler::kNearJump);
+  compiler->GenerateStubCall(source(), assert_boolean_stub,
+                             /*kind=*/UntaggedPcDescriptors::kOther, locs(),
+                             deopt_id());
+  __ Bind(&done);
+}
+
+static Condition TokenKindToIntCondition(Token::Kind kind) {
   switch (kind) {
     case Token::kEQ:
       return EQUAL;
@@ -615,20 +636,23 @@
   }
 }
 
-static void EmitBranchOnCondition(FlowGraphCompiler* compiler,
-                                  Condition true_condition,
-                                  BranchLabels labels) {
+static void EmitBranchOnCondition(
+    FlowGraphCompiler* compiler,
+    Condition true_condition,
+    BranchLabels labels,
+    compiler::Assembler::JumpDistance jump_distance =
+        compiler::Assembler::kFarJump) {
   if (labels.fall_through == labels.false_label) {
     // If the next block is the false successor, fall through to it.
-    __ j(true_condition, labels.true_label);
+    __ j(true_condition, labels.true_label, jump_distance);
   } else {
     // If the next block is not the false successor, branch to it.
     Condition false_condition = InvertCondition(true_condition);
-    __ j(false_condition, labels.false_label);
+    __ j(false_condition, labels.false_label, jump_distance);
 
     // Fall through or jump to the true successor.
     if (labels.fall_through != labels.true_label) {
-      __ jmp(labels.true_label);
+      __ jmp(labels.true_label, jump_distance);
     }
   }
 }
@@ -641,7 +665,7 @@
   Location right = locs.in(1);
   ASSERT(!left.IsConstant() || !right.IsConstant());
 
-  Condition true_condition = TokenKindToSmiCondition(kind);
+  Condition true_condition = TokenKindToIntCondition(kind);
 
   if (left.IsConstant()) {
     __ CompareObject(right.reg(), left.constant());
@@ -656,26 +680,6 @@
   return true_condition;
 }
 
-static Condition TokenKindToMintCondition(Token::Kind kind) {
-  switch (kind) {
-    case Token::kEQ:
-      return EQUAL;
-    case Token::kNE:
-      return NOT_EQUAL;
-    case Token::kLT:
-      return LESS;
-    case Token::kGT:
-      return GREATER;
-    case Token::kLTE:
-      return LESS_EQUAL;
-    case Token::kGTE:
-      return GREATER_EQUAL;
-    default:
-      UNREACHABLE();
-      return OVERFLOW;
-  }
-}
-
 static Condition EmitUnboxedMintEqualityOp(FlowGraphCompiler* compiler,
                                            const LocationSummary& locs,
                                            Token::Kind kind,
@@ -694,7 +698,7 @@
   // Lower is equal, compare upper.
   __ cmpl(left2, right2);
   __ Bind(&done);
-  Condition true_condition = TokenKindToMintCondition(kind);
+  Condition true_condition = TokenKindToIntCondition(kind);
   return true_condition;
 }
 
@@ -779,6 +783,10 @@
 
 Condition EqualityCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
                                                    BranchLabels labels) {
+  if (is_null_aware()) {
+    // Null-aware EqualityCompare instruction is only used in AOT.
+    UNREACHABLE();
+  }
   if (operation_cid() == kSmiCid) {
     return EmitSmiComparisonOp(compiler, *locs(), kind(), labels);
   } else if (operation_cid() == kMintCid) {
@@ -794,7 +802,8 @@
   BranchLabels labels = {&is_true, &is_false, &is_false};
   Condition true_condition = EmitComparisonCode(compiler, labels);
   if (true_condition != kInvalidCondition) {
-    EmitBranchOnCondition(compiler, true_condition, labels);
+    EmitBranchOnCondition(compiler, true_condition, labels,
+                          compiler::Assembler::kNearJump);
   }
 
   Register result = locs()->out(0).reg();
@@ -2521,11 +2530,14 @@
   ASSERT(locs()->in(1).reg() == kLengthReg);
 
   compiler::Label slow_path, done;
-  if (compiler->is_optimizing() && num_elements()->BindsToConstant() &&
-      num_elements()->BoundConstant().IsSmi()) {
-    const intptr_t length = Smi::Cast(num_elements()->BoundConstant()).Value();
-    if (Array::IsValidLength(length)) {
-      InlineArrayAllocation(compiler, length, &slow_path, &done);
+  if (!FLAG_use_slow_path && FLAG_inline_alloc) {
+    if (compiler->is_optimizing() && num_elements()->BindsToConstant() &&
+        num_elements()->BoundConstant().IsSmi()) {
+      const intptr_t length =
+          Smi::Cast(num_elements()->BoundConstant()).Value();
+      if (Array::IsValidLength(length)) {
+        InlineArrayAllocation(compiler, length, &slow_path, &done);
+      }
     }
   }
 
@@ -2754,104 +2766,6 @@
   __ Bind(&done);
 }
 
-LocationSummary* InstantiateTypeInstr::MakeLocationSummary(Zone* zone,
-                                                           bool opt) const {
-  const intptr_t kNumInputs = 2;
-  const intptr_t kNumTemps = 0;
-  LocationSummary* locs = new (zone)
-      LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
-  locs->set_in(0, Location::RegisterLocation(
-                      InstantiationABI::kInstantiatorTypeArgumentsReg));
-  locs->set_in(1, Location::RegisterLocation(
-                      InstantiationABI::kFunctionTypeArgumentsReg));
-  locs->set_out(0,
-                Location::RegisterLocation(InstantiationABI::kResultTypeReg));
-  return locs;
-}
-
-void InstantiateTypeInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  Register instantiator_type_args_reg = locs()->in(0).reg();
-  Register function_type_args_reg = locs()->in(1).reg();
-  Register result_reg = locs()->out(0).reg();
-
-  // 'instantiator_type_args_reg' is a TypeArguments object (or null).
-  // 'function_type_args_reg' is a TypeArguments object (or null).
-  // A runtime call to instantiate the type is required.
-  __ PushObject(Object::null_object());  // Make room for the result.
-  __ PushObject(type());
-  __ pushl(instantiator_type_args_reg);  // Push instantiator type arguments.
-  __ pushl(function_type_args_reg);      // Push function type arguments.
-  compiler->GenerateRuntimeCall(source(), deopt_id(),
-                                kInstantiateTypeRuntimeEntry, 3, locs());
-  __ Drop(3);           // Drop 2 type vectors, and uninstantiated type.
-  __ popl(result_reg);  // Pop instantiated type.
-}
-
-LocationSummary* InstantiateTypeArgumentsInstr::MakeLocationSummary(
-    Zone* zone,
-    bool opt) const {
-  const intptr_t kNumInputs = 3;
-  const intptr_t kNumTemps = 0;
-  LocationSummary* locs = new (zone)
-      LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
-  locs->set_in(0, Location::RegisterLocation(
-                      InstantiationABI::kInstantiatorTypeArgumentsReg));
-  locs->set_in(1, Location::RegisterLocation(
-                      InstantiationABI::kFunctionTypeArgumentsReg));
-  locs->set_in(2, Location::RegisterLocation(
-                      InstantiationABI::kUninstantiatedTypeArgumentsReg));
-  locs->set_out(
-      0, Location::RegisterLocation(InstantiationABI::kResultTypeArgumentsReg));
-  return locs;
-}
-
-void InstantiateTypeArgumentsInstr::EmitNativeCode(
-    FlowGraphCompiler* compiler) {
-  // We should never try and instantiate a TAV known at compile time to be null,
-  // so we can use a null value below for the dynamic case.
-  ASSERT(!type_arguments()->BindsToConstant() ||
-         !type_arguments()->BoundConstant().IsNull());
-  const auto& type_args =
-      type_arguments()->BindsToConstant()
-          ? TypeArguments::Cast(type_arguments()->BoundConstant())
-          : Object::null_type_arguments();
-  const intptr_t len = type_args.Length();
-  const bool can_function_type_args_be_null =
-      function_type_arguments()->CanBe(Object::null_object());
-
-  compiler::Label type_arguments_instantiated;
-  if (type_args.IsNull()) {
-    // Currently we only create dynamic InstantiateTypeArguments instructions
-    // in cases where we know the type argument is uninstantiated at runtime,
-    // so there are no extra checks needed to call the stub successfully.
-  } else if (type_args.IsRawWhenInstantiatedFromRaw(len) &&
-             can_function_type_args_be_null) {
-    // If both the instantiator and function type arguments are null and if the
-    // type argument vector instantiated from null becomes a vector of dynamic,
-    // then use null as the type arguments.
-    compiler::Label non_null_type_args;
-    // 'instantiator_type_args_reg' is a TypeArguments object (or null).
-    // 'function_type_args_reg' is a TypeArguments object (or null).
-    const Register instantiator_type_args_reg = locs()->in(0).reg();
-    const Register function_type_args_reg = locs()->in(1).reg();
-    const Register result_reg = locs()->out(0).reg();
-    ASSERT(result_reg != instantiator_type_args_reg &&
-           result_reg != function_type_args_reg);
-    __ LoadObject(result_reg, Object::null_object());
-    __ cmpl(instantiator_type_args_reg, result_reg);
-    if (!function_type_arguments()->BindsToConstant()) {
-      __ j(NOT_EQUAL, &non_null_type_args, compiler::Assembler::kNearJump);
-      __ cmpl(function_type_args_reg, result_reg);
-    }
-    __ j(EQUAL, &type_arguments_instantiated, compiler::Assembler::kNearJump);
-    __ Bind(&non_null_type_args);
-  }
-  // Lookup cache in stub before calling runtime.
-  compiler->GenerateStubCall(source(), GetStub(), UntaggedPcDescriptors::kOther,
-                             locs());
-  __ Bind(&type_arguments_instantiated);
-}
-
 LocationSummary* AllocateUninitializedContextInstr::MakeLocationSummary(
     Zone* zone,
     bool opt) const {
@@ -2882,10 +2796,15 @@
 
     compiler->SaveLiveRegisters(locs);
 
+    auto slow_path_env = compiler->SlowPathEnvironmentFor(
+        instruction(), /*num_slow_path_args=*/0);
+    ASSERT(slow_path_env != nullptr);
+
     __ movl(EDX, compiler::Immediate(instruction()->num_context_variables()));
     compiler->GenerateStubCall(instruction()->source(),
                                StubCode::AllocateContext(),
-                               UntaggedPcDescriptors::kOther, locs);
+                               UntaggedPcDescriptors::kOther, locs,
+                               instruction()->deopt_id(), slow_path_env);
     ASSERT(instruction()->locs()->out(0).reg() == EAX);
     compiler->RestoreLiveRegisters(instruction()->locs());
     __ jmp(exit_label());
@@ -2903,15 +2822,19 @@
   compiler->AddSlowPathCode(slow_path);
   intptr_t instance_size = Context::InstanceSize(num_context_variables());
 
-  __ TryAllocateArray(kContextCid, instance_size, slow_path->entry_label(),
-                      compiler::Assembler::kFarJump,
-                      result,  // instance
-                      temp,    // end address
-                      temp2);  // temp
+  if (!FLAG_use_slow_path && FLAG_inline_alloc) {
+    __ TryAllocateArray(kContextCid, instance_size, slow_path->entry_label(),
+                        compiler::Assembler::kFarJump,
+                        result,  // instance
+                        temp,    // end address
+                        temp2);  // temp
 
-  // Setup up number of context variables field.
-  __ movl(compiler::FieldAddress(result, Context::num_variables_offset()),
-          compiler::Immediate(num_context_variables()));
+    // Setup up number of context variables field.
+    __ movl(compiler::FieldAddress(result, Context::num_variables_offset()),
+            compiler::Immediate(num_context_variables()));
+  } else {
+    __ Jump(slow_path->entry_label());
+  }
 
   __ Bind(slow_path->exit_label());
 }
@@ -2933,7 +2856,7 @@
 
   __ movl(EDX, compiler::Immediate(num_context_variables()));
   compiler->GenerateStubCall(source(), StubCode::AllocateContext(),
-                             UntaggedPcDescriptors::kOther, locs());
+                             UntaggedPcDescriptors::kOther, locs(), deopt_id());
 }
 
 LocationSummary* CloneContextInstr::MakeLocationSummary(Zone* zone,
@@ -2952,7 +2875,8 @@
   ASSERT(locs()->out(0).reg() == EAX);
 
   compiler->GenerateStubCall(source(), StubCode::CloneContext(),
-                             /*kind=*/UntaggedPcDescriptors::kOther, locs());
+                             /*kind=*/UntaggedPcDescriptors::kOther, locs(),
+                             deopt_id());
 }
 
 LocationSummary* CatchBlockEntryInstr::MakeLocationSummary(Zone* zone,
@@ -3203,45 +3127,6 @@
   }
 }
 
-LocationSummary* CheckedSmiOpInstr::MakeLocationSummary(Zone* zone,
-                                                        bool opt) const {
-  // Only for precompiled code, not on ia32 currently.
-  UNIMPLEMENTED();
-  return NULL;
-}
-
-void CheckedSmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  // Only for precompiled code, not on ia32 currently.
-  UNIMPLEMENTED();
-}
-
-LocationSummary* CheckedSmiComparisonInstr::MakeLocationSummary(
-    Zone* zone,
-    bool opt) const {
-  // Only for precompiled code, not on ia32 currently.
-  UNIMPLEMENTED();
-  return NULL;
-}
-
-Condition CheckedSmiComparisonInstr::EmitComparisonCode(
-    FlowGraphCompiler* compiler,
-    BranchLabels labels) {
-  // Only for precompiled code, not on ia32 currently.
-  UNIMPLEMENTED();
-  return ZERO;
-}
-
-void CheckedSmiComparisonInstr::EmitBranchCode(FlowGraphCompiler* compiler,
-                                               BranchInstr* instr) {
-  // Only for precompiled code, not on ia32 currently.
-  UNIMPLEMENTED();
-}
-
-void CheckedSmiComparisonInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  // Only for precompiled code, not on ia32 currently.
-  UNIMPLEMENTED();
-}
-
 static bool IsSmiValue(const Object& constant, intptr_t value) {
   return constant.IsSmi() && (Smi::Cast(constant).Value() == value);
 }
@@ -5016,6 +4901,8 @@
 }
 
 void CaseInsensitiveCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  ASSERT(TargetFunction().is_leaf());
+
   // Save ESP. EDI is chosen because it is callee saved so we do not need to
   // back it up before calling into the runtime.
   static const Register kSavedSPReg = EDI;
@@ -5523,6 +5410,8 @@
 }
 
 void InvokeMathCFunctionInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  ASSERT(TargetFunction().is_leaf());
+
   if (recognized_kind() == MethodRecognizer::kMathDoublePow) {
     InvokeDoublePow(compiler, this);
     return;
@@ -6794,13 +6683,6 @@
   }
 }
 
-LocationSummary* DispatchTableCallInstr::MakeLocationSummary(Zone* zone,
-                                                             bool opt) const {
-  // Only generated with precompilation.
-  UNREACHABLE();
-  return NULL;
-}
-
 LocationSummary* ClosureCallInstr::MakeLocationSummary(Zone* zone,
                                                        bool opt) const {
   const intptr_t kNumInputs = 1;
@@ -6836,30 +6718,16 @@
 
 LocationSummary* BooleanNegateInstr::MakeLocationSummary(Zone* zone,
                                                          bool opt) const {
-  return LocationSummary::Make(zone, 1,
-                               value()->Type()->ToCid() == kBoolCid
-                                   ? Location::SameAsFirstInput()
-                                   : Location::RequiresRegister(),
+  return LocationSummary::Make(zone, 1, Location::SameAsFirstInput(),
                                LocationSummary::kNoCall);
 }
 
 void BooleanNegateInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   Register input = locs()->in(0).reg();
   Register result = locs()->out(0).reg();
-
-  if (value()->Type()->ToCid() == kBoolCid) {
-    ASSERT(input == result);
-    __ xorl(result, compiler::Immediate(
-                        compiler::target::ObjectAlignment::kBoolValueMask));
-  } else {
-    ASSERT(input != result);
-    compiler::Label done;
-    __ LoadObject(result, Bool::True());
-    __ CompareRegisters(result, input);
-    __ j(NOT_EQUAL, &done, compiler::Assembler::kNearJump);
-    __ LoadObject(result, Bool::False());
-    __ Bind(&done);
-  }
+  ASSERT(input == result);
+  __ xorl(result, compiler::Immediate(
+                      compiler::target::ObjectAlignment::kBoolValueMask));
 }
 
 LocationSummary* AllocateObjectInstr::MakeLocationSummary(Zone* zone,
@@ -6880,7 +6748,7 @@
   const Code& stub = Code::ZoneHandle(
       compiler->zone(), StubCode::GetAllocationStubForClass(cls()));
   compiler->GenerateStubCall(source(), stub, UntaggedPcDescriptors::kOther,
-                             locs());
+                             locs(), deopt_id());
 }
 
 void DebugStepCheckInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
diff --git a/runtime/vm/compiler/backend/il_printer.cc b/runtime/vm/compiler/backend/il_printer.cc
index 981a536..5773401 100644
--- a/runtime/vm/compiler/backend/il_printer.cc
+++ b/runtime/vm/compiler/backend/il_printer.cc
@@ -55,8 +55,7 @@
               Function::KindToCString(function_.kind()));
     // Output saved arguments descriptor information for dispatchers that
     // have it, so it's easy to see which dispatcher this graph represents.
-    if (function_.IsInvokeFieldDispatcher() ||
-        function_.IsNoSuchMethodDispatcher()) {
+    if (function_.HasSavedArgumentsDescriptor()) {
       const auto& args_desc_array = Array::Handle(function_.saved_args_desc());
       const ArgumentsDescriptor args_desc(args_desc_array);
       THR_Print(", %s", args_desc.ToCString());
@@ -731,22 +730,6 @@
   value()->PrintTo(f);
 }
 
-void CheckedSmiOpInstr::PrintOperandsTo(BaseTextBuffer* f) const {
-  f->Printf("%s", Token::Str(op_kind()));
-  f->AddString(", ");
-  left()->PrintTo(f);
-  f->AddString(", ");
-  right()->PrintTo(f);
-}
-
-void CheckedSmiComparisonInstr::PrintOperandsTo(BaseTextBuffer* f) const {
-  f->Printf("%s", Token::Str(kind()));
-  f->AddString(", ");
-  left()->PrintTo(f);
-  f->AddString(", ");
-  right()->PrintTo(f);
-}
-
 void BinaryIntegerOpInstr::PrintOperandsTo(BaseTextBuffer* f) const {
   f->Printf("%s", Token::Str(op_kind()));
   if (is_truncating()) {
diff --git a/runtime/vm/compiler/backend/il_serializer.cc b/runtime/vm/compiler/backend/il_serializer.cc
deleted file mode 100644
index 31fd469..0000000
--- a/runtime/vm/compiler/backend/il_serializer.cc
+++ /dev/null
@@ -1,1508 +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.
-
-#include "vm/compiler/backend/il_serializer.h"
-
-#include "vm/compiler/backend/flow_graph.h"
-#include "vm/compiler/backend/il.h"
-#include "vm/compiler/backend/range_analysis.h"
-#include "vm/compiler/method_recognizer.h"
-#include "vm/object_store.h"
-#include "vm/os.h"
-#include "vm/zone_text_buffer.h"
-
-namespace dart {
-
-DEFINE_FLAG(bool,
-            serialize_flow_graph_types,
-            true,
-            "Serialize inferred type information in flow graphs");
-
-DEFINE_FLAG(bool,
-            verbose_flow_graph_serialization,
-            false,
-            "Serialize extra information useful for debugging");
-
-DEFINE_FLAG(bool,
-            pretty_print_serialization,
-            false,
-            "Format serialized output nicely");
-
-DECLARE_FLAG(bool, populate_llvm_constant_pool);
-
-const char* const FlowGraphSerializer::initial_indent = "";
-
-FlowGraphSerializer::FlowGraphSerializer(Zone* zone,
-                                         const FlowGraph* flow_graph)
-    : flow_graph_(ASSERT_NOTNULL(flow_graph)),
-      zone_(zone),
-      object_store_(flow_graph->thread()->isolate_group()->object_store()),
-      open_recursive_types_(zone_),
-      llvm_constants_(
-          GrowableObjectArray::Handle(zone_,
-                                      object_store_->llvm_constant_pool())),
-      llvm_functions_(
-          GrowableObjectArray::Handle(zone_,
-                                      object_store_->llvm_function_pool())),
-      llvm_constant_map_(zone_, object_store_->llvm_constant_hash_table()),
-      llvm_index_(Smi::Handle(zone_)),
-      tmp_string_(String::Handle(zone_)),
-      array_type_args_((TypeArguments::Handle(zone_))),
-      closure_context_(Context::Handle(zone_)),
-      closure_function_(Function::Handle(zone_)),
-      closure_type_args_(TypeArguments::Handle(zone_)),
-      code_owner_(Object::Handle(zone_)),
-      context_parent_(Context::Handle(zone_)),
-      context_elem_(Object::Handle(zone_)),
-      function_type_args_(TypeArguments::Handle(zone_)),
-      ic_data_target_(Function::Handle(zone_)),
-      ic_data_type_(AbstractType::Handle(zone_)),
-      instance_field_(Field::Handle(zone_)),
-      instance_type_args_(TypeArguments::Handle(zone_)),
-      serialize_library_(Library::Handle(zone_)),
-      serialize_owner_(Class::Handle(zone_)),
-      serialize_parent_(Function::Handle(zone_)),
-      type_arguments_elem_(AbstractType::Handle(zone_)),
-      type_class_(Class::Handle(zone_)),
-      type_signature_(FunctionType::Handle(zone_)),
-      type_ref_type_(AbstractType::Handle(zone_)) {
-  // Double-check that the zone in the flow graph is a parent of the
-  // zone we'll be using for serialization.
-  ASSERT(flow_graph->zone()->ContainsNestedZone(zone));
-}
-
-FlowGraphSerializer::~FlowGraphSerializer() {
-  object_store_->set_llvm_constant_hash_table(llvm_constant_map_.Release());
-}
-
-void FlowGraphSerializer::SerializeToBuffer(Zone* zone,
-                                            const FlowGraph* flow_graph,
-                                            BaseTextBuffer* buffer) {
-  ASSERT(buffer != nullptr);
-  auto const sexp = SerializeToSExp(zone, flow_graph);
-  if (FLAG_pretty_print_serialization) {
-    sexp->SerializeTo(zone, buffer, initial_indent);
-  } else {
-    sexp->SerializeToLine(buffer);
-  }
-  buffer->AddString("\n\n");
-}
-
-SExpression* FlowGraphSerializer::SerializeToSExp(Zone* zone,
-                                                  const FlowGraph* flow_graph) {
-  FlowGraphSerializer serializer(zone, flow_graph);
-  return serializer.FlowGraphToSExp();
-}
-
-#define KIND_STR(name) #name,
-static const char* block_entry_kind_tags[FlowGraphSerializer::kNumEntryKinds] =
-    {FOR_EACH_BLOCK_ENTRY_KIND(KIND_STR)};
-#undef KIND_STR
-
-FlowGraphSerializer::BlockEntryKind FlowGraphSerializer::BlockEntryTagToKind(
-    SExpSymbol* tag) {
-  if (tag == nullptr) return kTarget;
-  auto const str = tag->value();
-  for (intptr_t i = 0; i < kNumEntryKinds; i++) {
-    auto const current = block_entry_kind_tags[i];
-    if (strcmp(str, current) == 0) return static_cast<BlockEntryKind>(i);
-  }
-  return kInvalid;
-}
-
-void FlowGraphSerializer::AddBool(SExpList* sexp, bool b) {
-  sexp->Add(new (zone()) SExpBool(b));
-}
-
-void FlowGraphSerializer::AddInteger(SExpList* sexp, intptr_t i) {
-  sexp->Add(new (zone()) SExpInteger(i));
-}
-
-void FlowGraphSerializer::AddString(SExpList* sexp, const char* cstr) {
-  sexp->Add(new (zone()) SExpString(cstr));
-}
-
-void FlowGraphSerializer::AddSymbol(SExpList* sexp, const char* cstr) {
-  sexp->Add(new (zone()) SExpSymbol(cstr));
-}
-
-void FlowGraphSerializer::AddExtraBool(SExpList* sexp,
-                                       const char* label,
-                                       bool b) {
-  sexp->AddExtra(label, new (zone()) SExpBool(b));
-}
-
-void FlowGraphSerializer::AddExtraInteger(SExpList* sexp,
-                                          const char* label,
-                                          intptr_t i) {
-  sexp->AddExtra(label, new (zone()) SExpInteger(i));
-}
-
-void FlowGraphSerializer::AddExtraString(SExpList* sexp,
-                                         const char* label,
-                                         const char* cstr) {
-  sexp->AddExtra(label, new (zone()) SExpString(cstr));
-}
-
-void FlowGraphSerializer::AddExtraSymbol(SExpList* sexp,
-                                         const char* label,
-                                         const char* cstr) {
-  sexp->AddExtra(label, new (zone()) SExpSymbol(cstr));
-}
-
-SExpression* FlowGraphSerializer::BlockIdToSExp(intptr_t block_id) {
-  return new (zone()) SExpSymbol(OS::SCreate(zone(), "B%" Pd "", block_id));
-}
-
-void FlowGraphSerializer::SerializeCanonicalName(BaseTextBuffer* b,
-                                                 const Object& obj) {
-  ASSERT(!obj.IsNull());
-  if (obj.IsFunction()) {
-    const auto& function = Function::Cast(obj);
-    tmp_string_ = function.name();
-    // We only want private keys removed, no other changes.
-    tmp_string_ = String::RemovePrivateKey(tmp_string_);
-    const char* function_name = tmp_string_.ToCString();
-    // If this function is an inner closure then the parent points to its
-    // containing function, which will also be part of the canonical name.
-    //
-    // We retrieve the owner before retrieving the parent function, as the
-    // inner closure chain may be arbitrarily deep and serialize_parent_ is
-    // passed in on recursive calls. When it is, then changing serialize_parent_
-    // to the parent function also changes the contents of obj and thus we'd
-    // no longer be able to retrieve the child function or its owner.
-    //
-    // This does mean that serialize_owner_ gets overwritten for each recursive
-    // call until we reach the end of the chain, but we only use its contents at
-    // the end of the chain anyway.
-    serialize_owner_ = function.Owner();
-    serialize_parent_ = function.parent_function();
-    if (!serialize_parent_.IsNull()) {
-      SerializeCanonicalName(b, serialize_parent_);
-    } else {
-      ASSERT(!serialize_owner_.IsNull());
-      SerializeCanonicalName(b, serialize_owner_);
-    }
-    b->Printf(":%s", function_name);
-  } else if (obj.IsClass()) {
-    const auto& cls = Class::Cast(obj);
-    tmp_string_ = cls.ScrubbedName();
-    const char* class_name = tmp_string_.ToCString();
-    serialize_library_ = cls.library();
-    if (!serialize_library_.IsNull()) {
-      SerializeCanonicalName(b, serialize_library_);
-    }
-    b->Printf(":%s", class_name);
-  } else if (obj.IsLibrary()) {
-    const Library& lib = Library::Cast(obj);
-    tmp_string_ = lib.url();
-    const char* lib_name = tmp_string_.ToCString();
-    if (lib_name[0] == '\0') return;
-    b->AddString(lib_name);
-  } else if (obj.IsField()) {
-    const auto& field = Field::Cast(obj);
-    tmp_string_ = field.UserVisibleName();
-    const char* field_name = tmp_string_.ToCString();
-    serialize_owner_ = field.Owner();
-    ASSERT(!serialize_owner_.IsNull());
-    SerializeCanonicalName(b, serialize_owner_);
-    b->Printf(".%s", field_name);
-  } else {
-    UNREACHABLE();
-  }
-}
-
-SExpression* FlowGraphSerializer::CanonicalNameToSExp(const Object& obj) {
-  ASSERT(!obj.IsNull());
-  ZoneTextBuffer b(zone_, 100);
-  SerializeCanonicalName(&b, obj);
-  return new (zone()) SExpSymbol(b.buffer());
-}
-
-SExpSymbol* FlowGraphSerializer::BlockEntryKindToTag(BlockEntryKind k) {
-  ASSERT(k >= 0 && k < kNumEntryKinds);
-  return new (zone()) SExpSymbol(block_entry_kind_tags[k]);
-}
-
-#define KIND_TAG(name) block_entry_kind_tags[k##name]
-SExpSymbol* FlowGraphSerializer::BlockEntryTag(const BlockEntryInstr* entry) {
-  if (entry == nullptr) return nullptr;
-  if (entry->IsGraphEntry()) {
-    return BlockEntryKindToTag(kGraph);
-  }
-  if (entry->IsOsrEntry()) {
-    return BlockEntryKindToTag(kOSR);
-  }
-  if (entry->IsCatchBlockEntry()) {
-    return BlockEntryKindToTag(kCatch);
-  }
-  if (entry->IsIndirectEntry()) {
-    return BlockEntryKindToTag(kIndirect);
-  }
-  if (entry->IsFunctionEntry()) {
-    if (entry == flow_graph()->graph_entry()->normal_entry()) {
-      return BlockEntryKindToTag(kNormal);
-    }
-    if (entry == flow_graph()->graph_entry()->unchecked_entry()) {
-      return BlockEntryKindToTag(kUnchecked);
-    }
-  }
-  if (entry->IsJoinEntry()) {
-    return BlockEntryKindToTag(kJoin);
-  }
-  return nullptr;
-}
-#undef KIND_TAG
-
-SExpression* FlowGraphSerializer::FunctionEntryToSExp(
-    const BlockEntryInstr* entry) {
-  if (entry == nullptr) return nullptr;
-  auto sexp = new (zone()) SExpList(zone());
-  sexp->Add(BlockEntryTag(entry));
-  sexp->Add(BlockIdToSExp(entry->block_id()));
-  if (auto const with_defs = entry->AsBlockEntryWithInitialDefs()) {
-    auto const initial_defs = with_defs->initial_definitions();
-    for (intptr_t i = 0; i < initial_defs->length(); i++) {
-      sexp->Add(initial_defs->At(i)->ToSExpression(this));
-    }
-  }
-
-  // Also include the extra info here, to avoid having to find the
-  // corresponding block to get it.
-  entry->BlockEntryInstr::AddExtraInfoToSExpression(sexp, this);
-
-  return sexp;
-}
-
-SExpression* FlowGraphSerializer::EntriesToSExp(const GraphEntryInstr* start) {
-  auto sexp = new (zone()) SExpList(zone());
-  AddSymbol(sexp, "Entries");
-  if (auto const normal = FunctionEntryToSExp(start->normal_entry())) {
-    sexp->Add(normal);
-  }
-  if (auto const unchecked = FunctionEntryToSExp(start->unchecked_entry())) {
-    sexp->Add(unchecked);
-  }
-  if (auto const osr = FunctionEntryToSExp(start->osr_entry())) {
-    sexp->Add(osr);
-  }
-  for (intptr_t i = 0; i < start->catch_entries().length(); i++) {
-    sexp->Add(FunctionEntryToSExp(start->catch_entries().At(i)));
-  }
-  for (intptr_t i = 0; i < start->indirect_entries().length(); i++) {
-    sexp->Add(FunctionEntryToSExp(start->indirect_entries().At(i)));
-  }
-  return sexp;
-}
-
-SExpression* FlowGraphSerializer::FlowGraphToSExp() {
-  auto const start = flow_graph()->graph_entry();
-  auto const sexp = new (zone()) SExpList(zone());
-  AddSymbol(sexp, "FlowGraph");
-  sexp->Add(CanonicalNameToSExp(flow_graph()->function()));
-  AddExtraInteger(sexp, "deopt_id", start->deopt_id());
-  if (start->env() != nullptr) {
-    sexp->AddExtra("env", start->env()->ToSExpression(this));
-  }
-  if (start->IsCompiledForOsr()) {
-    AddExtraInteger(sexp, "osr_id", start->osr_id());
-  }
-  if (auto const constants = ConstantPoolToSExp(start)) {
-    sexp->Add(constants);
-  }
-  sexp->Add(EntriesToSExp(start));
-  auto& block_order = flow_graph()->reverse_postorder();
-  // Skip the first block, which will be the graph entry block (B0). We
-  // output all its information as part of the function expression, so it'll
-  // just show up as an empty block here.
-  ASSERT(block_order[0]->IsGraphEntry());
-  for (intptr_t i = 1; i < block_order.length(); ++i) {
-    sexp->Add(block_order[i]->ToSExpression(this));
-  }
-  if (FLAG_populate_llvm_constant_pool) {
-    auto const new_index = llvm_functions_.Length();
-    llvm_functions_.Add(flow_graph_->function());
-    AddExtraInteger(sexp, "llvm_index", new_index);
-  }
-  return sexp;
-}
-
-SExpression* FlowGraphSerializer::UseToSExp(const Definition* definition) {
-  ASSERT(definition != nullptr);
-  ASSERT(definition->HasSSATemp() || definition->HasTemp());
-  if (definition->HasSSATemp()) {
-    const intptr_t temp_index = definition->ssa_temp_index();
-    const auto name_cstr = OS::SCreate(zone(), "v%" Pd "", temp_index);
-    if (definition->HasPairRepresentation()) {
-      auto sexp = new (zone()) SExpList(zone());
-      AddSymbol(sexp, name_cstr);
-      AddSymbol(sexp, OS::SCreate(zone(), "v%" Pd "", temp_index + 1));
-      return sexp;
-    } else {
-      return new (zone()) SExpSymbol(name_cstr);
-    }
-  } else if (definition->HasTemp()) {
-    const intptr_t temp_index = definition->temp_index();
-    return new (zone()) SExpSymbol(OS::SCreate(zone(), "t%" Pd "", temp_index));
-  }
-  UNREACHABLE();
-}
-
-SExpression* FlowGraphSerializer::ClassToSExp(const Class& cls) {
-  if (cls.IsNull()) return nullptr;
-  auto sexp = new (zone()) SExpList(zone());
-  AddSymbol(sexp, "Class");
-  AddInteger(sexp, cls.id());
-  if (FLAG_verbose_flow_graph_serialization) {
-    sexp->AddExtra("name", CanonicalNameToSExp(cls));
-    // Currently, AbstractTypeToSExp assumes that serializing a class cannot
-    // re-enter it. If we make that possible by serializing parts of a class
-    // that can contain AbstractTypes, especially types that are not type
-    // parameters or type references, fix AbstractTypeToSExp appropriately.
-  }
-  return sexp;
-}
-
-static bool ShouldSerializeType(CompileType* type) {
-  return (FLAG_verbose_flow_graph_serialization ||
-          FLAG_serialize_flow_graph_types) &&
-         type != nullptr;
-}
-
-SExpression* FlowGraphSerializer::FieldToSExp(const Field& field) {
-  if (field.IsNull()) return nullptr;
-  auto sexp = new (zone()) SExpList(zone());
-  AddSymbol(sexp, "Field");
-  sexp->Add(CanonicalNameToSExp(field));
-  CompileType t(field.is_nullable(), field.guarded_cid(), nullptr);
-  if (ShouldSerializeType(&t)) {
-    sexp->AddExtra("type", t.ToSExpression(this));
-  }
-  return sexp;
-}
-
-SExpression* FlowGraphSerializer::AbstractTypeToSExp(const AbstractType& t) {
-  if (t.IsNull()) return nullptr;
-  ASSERT(t.IsFinalized());
-  auto sexp = new (zone()) SExpList(zone());
-  if (t.IsTypeParameter()) {
-    const auto& param = TypeParameter::Cast(t);
-    AddSymbol(sexp, "TypeParameter");
-    AddExtraInteger(sexp, "cid", param.parameterized_class_id());
-    AddExtraInteger(sexp, "base", param.base());
-    AddExtraInteger(sexp, "index", param.index());
-    tmp_string_ = param.name();
-    AddSymbol(sexp, tmp_string_.ToCString());
-    // TODO(regis): bound, default argument, flags, nullability, hash.
-    return sexp;
-  }
-  if (t.IsTypeRef()) {
-    const auto& ref = TypeRef::Cast(t);
-    AddSymbol(sexp, "TypeRef");
-    type_ref_type_ = ref.type();
-    auto const hash = type_ref_type_.Hash();
-    // Check to see if this is a TypeRef to a type we're currently serializing.
-    // If it is not, then we need to serialize the underlying type, as it
-    // otherwise won't be available when deserializing.
-    auto const open_type = open_recursive_types_.LookupValue(hash);
-    if (open_type == nullptr) {
-      // Allocate a new handle as we may re-enter the TypeRef branch.
-      auto& type = AbstractType::Handle(zone(), ref.type());
-      sexp->Add(AbstractTypeToSExp(type));
-      // If we serialized the referrent, then we don't need this information,
-      // but it may be useful for debugging so add it in verbose mode.
-      if (FLAG_verbose_flow_graph_serialization) {
-        AddExtraInteger(sexp, "hash", hash);
-      }
-    } else {
-      // Make sure we didn't have a hash collision.
-      ASSERT(open_type->Equals(type_ref_type_));
-      AddExtraInteger(sexp, "hash", hash);
-    }
-    if (FLAG_verbose_flow_graph_serialization) {
-      AddExtraString(sexp, "type", type_ref_type_.ToCString());
-    }
-    return sexp;
-  }
-  // We want to check for the type being recursive before we may serialize
-  // any sub-parts that include possible TypeRefs to this type.
-  const bool is_recursive = t.IsRecursive();
-  intptr_t hash = 0;
-  if (is_recursive) {
-    hash = t.Hash();
-    AddExtraInteger(sexp, "hash", hash);
-    open_recursive_types_.Insert(hash, &t);
-  }
-  if (t.IsFunctionType()) {
-    const auto& sig = FunctionType::Handle(zone(), FunctionType::Cast(t).ptr());
-    AddSymbol(sexp, "FunctionType");
-    function_type_args_ = sig.type_parameters();
-    if (auto const ta_sexp = NonEmptyTypeArgumentsToSExp(function_type_args_)) {
-      sexp->AddExtra("type_params", ta_sexp);
-    }
-    auto& type = AbstractType::Handle(zone(), sig.result_type());
-    sexp->AddExtra("result_type", AbstractTypeToSExp(type));
-    auto& parameter_types = Array::Handle(zone(), sig.parameter_types());
-    sexp->AddExtra("parameter_types", ArrayToSExp(parameter_types));
-    auto& parameter_names = Array::Handle(zone(), sig.parameter_names());
-    sexp->AddExtra("parameter_names", ArrayToSExp(parameter_names));
-    AddExtraInteger(sexp, "packed_fields", sig.packed_fields());
-    // If we were parsing a recursive type, we're now done building it, so
-    // remove it from the open recursive types.
-    if (is_recursive) open_recursive_types_.Remove(hash);
-    return sexp;
-  }
-  ASSERT(t.IsType());
-  AddSymbol(sexp, "Type");
-  const auto& type = Type::Cast(t);
-  if (type.HasTypeClass()) {
-    type_class_ = type.type_class();
-    // This avoids re-entry as long as serializing a class doesn't involve
-    // serializing concrete (non-parameter, non-reference) types.
-    sexp->Add(DartValueToSExp(type_class_));
-  } else {
-    // TODO(dartbug.com/36882): Actually structure non-class types instead of
-    // just printing out this version.
-    AddExtraString(sexp, "name", type.ToCString());
-  }
-  // Since type arguments may themselves be instantiations of generic
-  // types, we may call back into this function in the middle of printing
-  // the TypeArguments and so we must allocate a fresh handle here.
-  const auto& args = TypeArguments::Handle(zone(), type.arguments());
-  if (auto const args_sexp = NonEmptyTypeArgumentsToSExp(args)) {
-    sexp->AddExtra("type_args", args_sexp);
-  }
-  // If we were parsing a recursive type, we're now done building it, so
-  // remove it from the open recursive types.
-  if (is_recursive) open_recursive_types_.Remove(hash);
-  return sexp;
-}
-
-SExpression* FlowGraphSerializer::CodeToSExp(const Code& code) {
-  if (code.IsNull()) return nullptr;
-  auto sexp = new (zone()) SExpList(zone());
-  AddSymbol(sexp, "Code");
-  if (code.IsStubCode()) {
-    AddSymbol(sexp, StubCode::NameOfStub(code.EntryPoint()));
-    if (FLAG_verbose_flow_graph_serialization) {
-      AddExtraSymbol(sexp, "kind", "stub");
-    }
-    return sexp;
-  }
-  code_owner_ = code.owner();
-  if (!code_owner_.IsNull() && FLAG_verbose_flow_graph_serialization) {
-    if (code_owner_.IsClass()) {
-      AddExtraSymbol(sexp, "kind", "allocate");
-    } else if (code_owner_.IsAbstractType()) {
-      AddExtraSymbol(sexp, "kind", "type_test");
-    } else {
-      ASSERT(code_owner_.IsFunction());
-      AddExtraSymbol(sexp, "kind", "function");
-    }
-  }
-  sexp->Add(DartValueToSExp(code_owner_));
-  return sexp;
-}
-
-SExpression* FlowGraphSerializer::TypeArgumentsToSExp(const TypeArguments& ta) {
-  if (ta.IsNull()) return nullptr;
-  auto sexp = new (zone()) SExpList(zone());
-  AddSymbol(sexp, "TypeArguments");
-  for (intptr_t i = 0; i < ta.Length(); i++) {
-    type_arguments_elem_ = ta.TypeAt(i);
-    sexp->Add(DartValueToSExp(type_arguments_elem_));
-  }
-  if (FLAG_verbose_flow_graph_serialization && ta.IsRecursive()) {
-    AddExtraInteger(sexp, "hash", ta.Hash());
-  }
-  return sexp;
-}
-
-SExpression* FlowGraphSerializer::InstanceToSExp(const Instance& inst) {
-  if (inst.IsNull()) return nullptr;
-
-  // Since InstanceToSExp may use ObjectToSExp (via DartValueToSExp) for field
-  // values that aren't entries in the constant pool, and ObjectToSExp may
-  // re-enter InstanceToSExp, allocate fresh handles here for the argument to
-  // DartValueToSExp and other handles that are live across the call.
-  const auto& instance_class = Class::Handle(zone(), inst.clazz());
-  const auto& instance_fields_array =
-      Array::Handle(zone(), instance_class.fields());
-  auto& instance_field_value = Object::Handle(zone());
-
-  auto const sexp = new (zone()) SExpList(zone());
-  AddSymbol(sexp, "Instance");
-  AddInteger(sexp, instance_class.id());
-  auto const fields = new (zone()) SExpList(zone());
-  AddSymbol(fields, "Fields");
-  for (intptr_t i = 0; i < instance_fields_array.Length(); i++) {
-    instance_field_ = Field::RawCast(instance_fields_array.At(i));
-    // We don't need to serialize static fields, since they're shared by
-    // all instances.
-    if (instance_field_.is_static()) continue;
-    // We should only be getting const instances, which means that we
-    // should only see final instance fields.
-    ASSERT(instance_field_.is_final());
-    tmp_string_ = instance_field_.UserVisibleName();
-    auto const label = tmp_string_.ToCString();
-    instance_field_value = inst.GetField(instance_field_);
-    fields->AddExtra(label, DartValueToSExp(instance_field_value));
-  }
-  if (fields->ExtraLength() != 0 || FLAG_verbose_flow_graph_serialization) {
-    sexp->Add(fields);
-  }
-  if (instance_class.IsGeneric()) {
-    instance_type_args_ = inst.GetTypeArguments();
-    if (auto const args = NonEmptyTypeArgumentsToSExp(instance_type_args_)) {
-      sexp->AddExtra("type_args", args);
-    }
-  }
-  if (FLAG_verbose_flow_graph_serialization) {
-    AddExtraInteger(sexp, "size", inst.InstanceSize());
-    // We know the following won't call back into InstanceToSExp because we're
-    // providing it a class.
-    if (auto const cls = DartValueToSExp(instance_class)) {
-      sexp->AddExtra("class", cls);
-    }
-  }
-  return sexp;
-}
-
-SExpression* FlowGraphSerializer::FunctionToSExp(const Function& func) {
-  if (func.IsNull()) return nullptr;
-  auto const sexp = new (zone()) SExpList(zone());
-  AddSymbol(sexp, "Function");
-  sexp->Add(CanonicalNameToSExp(func));
-  if (func.IsRecognized()) {
-    AddExtraSymbol(sexp, "recognized",
-                   MethodRecognizer::KindToCString(func.recognized_kind()));
-  }
-  if (func.is_native()) {
-    tmp_string_ = func.native_name();
-    if (!tmp_string_.IsNull()) {
-      AddExtraSymbol(sexp, "native_name", tmp_string_.ToCString());
-    }
-  }
-  if (func.kind() != UntaggedFunction::Kind::kRegularFunction ||
-      FLAG_verbose_flow_graph_serialization) {
-    AddExtraSymbol(sexp, "kind", UntaggedFunction::KindToCString(func.kind()));
-  }
-  function_type_args_ = func.type_parameters();
-  if (auto const ta_sexp = NonEmptyTypeArgumentsToSExp(function_type_args_)) {
-    sexp->AddExtra("type_args", ta_sexp);
-  }
-  return sexp;
-}
-
-SExpression* FlowGraphSerializer::ImmutableListToSExp(const Array& arr) {
-  if (arr.IsNull()) return nullptr;
-  // We should only be getting immutable lists when serializing Dart values
-  // in flow graphs.
-  ASSERT(arr.IsImmutable());
-  auto sexp = new (zone()) SExpList(zone());
-  AddSymbol(sexp, "ImmutableList");
-  // We allocate a new Object handle to use for the calls to DartValueToSExp
-  // in case any Array elements contain non-constant-pool, non-empty Arrays.
-  auto& array_elem = Object::Handle(zone());
-  for (intptr_t i = 0; i < arr.Length(); i++) {
-    array_elem = arr.At(i);
-    sexp->Add(DartValueToSExp(array_elem));
-  }
-  array_type_args_ = arr.GetTypeArguments();
-  if (auto const type_args_sexp = TypeArgumentsToSExp(array_type_args_)) {
-    sexp->AddExtra("type_args", type_args_sexp);
-  }
-  return sexp;
-}
-
-SExpression* FlowGraphSerializer::ArrayToSExp(const Array& arr) {
-  if (arr.IsNull()) return nullptr;
-  auto sexp = new (zone()) SExpList(zone());
-  AddSymbol(sexp, "Array");
-  auto& array_elem = Object::Handle(zone());
-  for (intptr_t i = 0; i < arr.Length(); i++) {
-    array_elem = arr.At(i);
-    sexp->Add(DartValueToSExp(array_elem));
-  }
-  return sexp;
-}
-
-SExpression* FlowGraphSerializer::ClosureToSExp(const Closure& c) {
-  if (c.IsNull()) return nullptr;
-  auto sexp = new (zone()) SExpList(zone());
-  AddSymbol(sexp, "Closure");
-  closure_function_ = c.function();
-  if (auto const func = FunctionToSExp(closure_function_)) {
-    sexp->Add(func);
-  }
-  closure_context_ = c.context();
-  if (auto const context = ContextToSExp(closure_context_)) {
-    sexp->AddExtra("context", context);
-  }
-  closure_type_args_ = c.function_type_arguments();
-  if (auto const type_args = NonEmptyTypeArgumentsToSExp(closure_type_args_)) {
-    sexp->AddExtra("func_type_args", type_args);
-  }
-  closure_type_args_ = c.instantiator_type_arguments();
-  if (auto const type_args = NonEmptyTypeArgumentsToSExp(closure_type_args_)) {
-    sexp->AddExtra("inst_type_args", type_args);
-  }
-  closure_type_args_ = c.delayed_type_arguments();
-  if (auto const type_args = NonEmptyTypeArgumentsToSExp(closure_type_args_)) {
-    sexp->AddExtra("delayed_type_args", type_args);
-  }
-  return sexp;
-}
-
-SExpression* FlowGraphSerializer::ContextToSExp(const Context& c) {
-  if (c.IsNull()) return nullptr;
-  auto sexp = new (zone()) SExpList(zone());
-  AddSymbol(sexp, "Context");
-  for (intptr_t i = 0; i < c.num_variables(); i++) {
-    context_elem_ = c.At(i);
-    auto const elem_sexp = DartValueToSExp(context_elem_);
-    if (elem_sexp == nullptr) return nullptr;
-    sexp->Add(elem_sexp);
-  }
-  context_parent_ = c.parent();
-  if (auto const parent_sexp = ContextToSExp(context_parent_)) {
-    sexp->AddExtra("parent", parent_sexp);
-  }
-  return sexp;
-}
-
-SExpression* FlowGraphSerializer::ObjectToSExp(const Object& dartval) {
-  if (dartval.IsNull()) {
-    return new (zone()) SExpSymbol("null");
-  }
-  if (dartval.ptr() == Object::sentinel().ptr()) {
-    return new (zone()) SExpSymbol("sentinel");
-  }
-  if (dartval.IsString()) {
-    return new (zone()) SExpString(dartval.ToCString());
-  }
-  if (dartval.IsSmi()) {
-    return new (zone()) SExpInteger(Smi::Cast(dartval).Value());
-  }
-  if (dartval.IsMint()) {
-    return new (zone()) SExpInteger(Mint::Cast(dartval).value());
-  }
-  if (dartval.IsBool()) {
-    return new (zone()) SExpBool(Bool::Cast(dartval).value());
-  }
-  if (dartval.IsDouble()) {
-    return new (zone()) SExpDouble(Double::Cast(dartval).value());
-  }
-  if (dartval.IsField()) {
-    return FieldToSExp(Field::Cast(dartval));
-  }
-  if (dartval.IsClass()) {
-    return ClassToSExp(Class::Cast(dartval));
-  }
-  if (dartval.IsTypeArguments()) {
-    return TypeArgumentsToSExp(TypeArguments::Cast(dartval));
-  }
-  if (dartval.IsCode()) {
-    return CodeToSExp(Code::Cast(dartval));
-  }
-  if (dartval.IsArray()) {
-    return ImmutableListToSExp(Array::Cast(dartval));
-  }
-  if (dartval.IsFunction()) {
-    return FunctionToSExp(Function::Cast(dartval));
-  }
-  if (dartval.IsClosure()) {
-    return ClosureToSExp(Closure::Cast(dartval));
-  }
-  if (dartval.IsAbstractType()) {
-    return AbstractTypeToSExp(AbstractType::Cast(dartval));
-  }
-  ASSERT(dartval.IsInstance());
-  return InstanceToSExp(Instance::Cast(dartval));
-}
-
-SExpression* FlowGraphSerializer::DartValueToSExp(const Object& obj) {
-  if (auto const def = flow_graph()->GetExistingConstant(obj)) {
-    ASSERT(def->IsDefinition());
-    return UseToSExp(def->AsDefinition());
-  }
-  return ObjectToSExp(obj);
-}
-
-SExpression* FlowGraphSerializer::NonEmptyTypeArgumentsToSExp(
-    const TypeArguments& ta) {
-  if (ta.IsNull() || ta.Length() == 0) return nullptr;
-  return DartValueToSExp(ta);
-}
-
-SExpression* FlowGraphSerializer::ConstantPoolToSExp(
-    const GraphEntryInstr* start) {
-  auto const initial_defs = start->initial_definitions();
-  if (initial_defs == nullptr || initial_defs->is_empty()) return nullptr;
-  auto constant_list = new (zone()) SExpList(zone());
-  AddSymbol(constant_list, "Constants");
-  for (intptr_t i = 0; i < initial_defs->length(); i++) {
-    ASSERT(initial_defs->At(i)->IsConstant());
-    auto const definition = initial_defs->At(i)->AsDefinition();
-    auto elem = new (zone()) SExpList(zone());
-    AddSymbol(elem, "def");
-    elem->Add(UseToSExp(definition));
-    // Use ObjectToSExp here, not DartValueToSExp!
-    const auto& value = definition->AsConstant()->value();
-    elem->Add(ObjectToSExp(value));
-    AddDefinitionExtraInfoToSExp(definition, elem);
-    // Only add constants to the LLVM constant pool that are actually used in
-    // the flow graph.
-    if (FLAG_populate_llvm_constant_pool && definition->HasUses()) {
-      auto const pool_len = llvm_constants_.Length();
-      llvm_index_ = Smi::New(pool_len);
-      llvm_index_ ^= llvm_constant_map_.InsertOrGetValue(value, llvm_index_);
-      if (llvm_index_.Value() == pool_len) {
-        llvm_constants_.Add(value);
-      }
-      AddExtraInteger(elem, "llvm_index", llvm_index_.Value());
-    }
-    constant_list->Add(elem);
-  }
-  return constant_list;
-}
-
-SExpression* Instruction::ToSExpression(FlowGraphSerializer* s) const {
-  auto sexp = new (s->zone()) SExpList(s->zone());
-  s->AddSymbol(sexp, DebugName());
-  AddOperandsToSExpression(sexp, s);
-  AddExtraInfoToSExpression(sexp, s);
-  return sexp;
-}
-
-SExpression* BlockEntryInstr::ToSExpression(FlowGraphSerializer* s) const {
-  auto sexp = new (s->zone()) SExpList(s->zone());
-  s->AddSymbol(sexp, "Block");
-  sexp->Add(s->BlockIdToSExp(block_id()));
-  AddOperandsToSExpression(sexp, s);
-  AddExtraInfoToSExpression(sexp, s);
-  return sexp;
-}
-
-void BlockEntryInstr::AddExtraInfoToSExpression(SExpList* sexp,
-                                                FlowGraphSerializer* s) const {
-  Instruction::AddExtraInfoToSExpression(sexp, s);
-  if (try_index() != kInvalidTryIndex) {
-    s->AddExtraInteger(sexp, "try_index", try_index());
-  }
-  if (auto const entry_tag = s->BlockEntryTag(this)) {
-    sexp->AddExtra("block_type", entry_tag);
-  }
-  if (FLAG_verbose_flow_graph_serialization) {
-    if (PredecessorCount() > 0) {
-      auto const preds = new (s->zone()) SExpList(s->zone());
-      for (intptr_t i = 0; i < PredecessorCount(); i++) {
-        preds->Add(s->BlockIdToSExp(PredecessorAt(i)->block_id()));
-      }
-      sexp->AddExtra("predecessors", preds);
-    }
-  }
-}
-
-void BlockEntryInstr::AddOperandsToSExpression(SExpList* sexp,
-                                               FlowGraphSerializer* s) const {
-  for (const auto* inst = next_; inst != nullptr; inst = inst->next_) {
-    sexp->Add(inst->ToSExpression(s));
-  }
-}
-
-void JoinEntryInstr::AddOperandsToSExpression(SExpList* sexp,
-                                              FlowGraphSerializer* s) const {
-  if (auto phi_list = phis()) {
-    for (intptr_t i = 0; i < phi_list->length(); i++) {
-      sexp->Add(phi_list->At(i)->ToSExpression(s));
-    }
-  }
-  BlockEntryInstr::AddOperandsToSExpression(sexp, s);
-}
-
-void Instruction::AddOperandsToSExpression(SExpList* sexp,
-                                           FlowGraphSerializer* s) const {
-  for (intptr_t i = 0; i < InputCount(); ++i) {
-    if (InputAt(i) == nullptr) continue;
-    sexp->Add(InputAt(i)->ToSExpression(s));
-  }
-}
-
-void Instruction::AddExtraInfoToSExpression(SExpList* sexp,
-                                            FlowGraphSerializer* s) const {
-  if (GetDeoptId() != DeoptId::kNone) {
-    s->AddExtraInteger(sexp, "deopt_id", GetDeoptId());
-  }
-  if (env() != nullptr) {
-    sexp->AddExtra("env", env()->ToSExpression(s));
-  }
-  if (!token_pos().IsNoSource()) {
-    s->AddExtraInteger(sexp, "token_pos", token_pos().Serialize());
-  }
-  if (has_inlining_id()) {
-    s->AddExtraInteger(sexp, "inlining_id", inlining_id());
-  }
-}
-
-SExpression* Range::ToSExpression(FlowGraphSerializer* s) {
-  auto const sexp = new (s->zone()) SExpList(s->zone());
-  s->AddSymbol(sexp, "Range");
-  sexp->Add(min_.ToSExpression(s));
-  if (!max_.Equals(min_)) sexp->Add(max_.ToSExpression(s));
-  return sexp;
-}
-
-SExpression* RangeBoundary::ToSExpression(FlowGraphSerializer* s) {
-  switch (kind_) {
-    case kSymbol: {
-      auto const sexp = new (s->zone()) SExpList(s->zone());
-      sexp->Add(s->UseToSExp(symbol()));
-      if (offset() != 0) {
-        s->AddExtraInteger(sexp, "offset", offset());
-      }
-      return sexp;
-    }
-    case kConstant:
-      return new (s->zone()) SExpInteger(value_);
-    default:
-      return new (s->zone()) SExpSymbol(RangeBoundary::KindToCString(kind_));
-  }
-}
-
-bool FlowGraphSerializer::HasDefinitionExtraInfo(const Definition* def) {
-  return ShouldSerializeType(def->type_) || def->range() != nullptr;
-}
-
-void FlowGraphSerializer::AddDefinitionExtraInfoToSExp(const Definition* def,
-                                                       SExpList* sexp) {
-  // Type() isn't a const method as it can cause changes to the type_
-  // field, so access type_ directly instead.
-  if (ShouldSerializeType(def->type_)) {
-    sexp->AddExtra("type", def->type_->ToSExpression(this));
-  }
-  if (def->range() != nullptr) {
-    sexp->AddExtra("range", def->range()->ToSExpression(this));
-  }
-}
-
-SExpression* Definition::ToSExpression(FlowGraphSerializer* s) const {
-  // If we don't have a temp index, then this is a Definition that has no
-  // usable result.
-  const bool binds_name = HasSSATemp() || HasTemp();
-  // Don't serialize non-binding definitions as definitions unless we either
-  // have Definition-specific extra info or we're in verbose mode.
-  if (!binds_name && !FLAG_verbose_flow_graph_serialization &&
-      !s->HasDefinitionExtraInfo(this)) {
-    return Instruction::ToSExpression(s);
-  }
-  auto sexp = new (s->zone()) SExpList(s->zone());
-  s->AddSymbol(sexp, "def");
-  if (binds_name) {
-    sexp->Add(s->UseToSExp(this));
-  } else {
-    // Since there is Definition-specific extra info to serialize, we use "_"
-    // as the bound name, which lets the deserializer know the result is unused.
-    s->AddSymbol(sexp, "_");
-  }
-  // Add only Definition-specific extra info to this form. Any extra info
-  // that is Instruction-specific or specific to the actual instruction type is
-  // added to the nested instruction form.
-  s->AddDefinitionExtraInfoToSExp(this, sexp);
-  sexp->Add(Instruction::ToSExpression(s));
-  return sexp;
-}
-
-void AssertAssignableInstr::AddExtraInfoToSExpression(
-    SExpList* sexp,
-    FlowGraphSerializer* s) const {
-  Instruction::AddExtraInfoToSExpression(sexp, s);
-  sexp->AddExtra("name", s->DartValueToSExp(dst_name()));
-}
-
-void ConstantInstr::AddOperandsToSExpression(SExpList* sexp,
-                                             FlowGraphSerializer* s) const {
-  sexp->Add(s->DartValueToSExp(value()));
-}
-
-void BranchInstr::AddOperandsToSExpression(SExpList* sexp,
-                                           FlowGraphSerializer* s) const {
-  sexp->Add(comparison()->ToSExpression(s));
-  sexp->Add(s->BlockIdToSExp(true_successor()->block_id()));
-  sexp->Add(s->BlockIdToSExp(false_successor()->block_id()));
-}
-
-void ParameterInstr::AddOperandsToSExpression(SExpList* sexp,
-                                              FlowGraphSerializer* s) const {
-  s->AddInteger(sexp, index());
-  s->AddExtraInteger(sexp, "param_offset", param_offset());
-  s->AddExtraSymbol(sexp, "representation",
-                    Location::RepresentationToCString(representation()));
-}
-
-void SpecialParameterInstr::AddOperandsToSExpression(
-    SExpList* sexp,
-    FlowGraphSerializer* s) const {
-  ASSERT(kind() < SpecialParameterInstr::kNumKinds);
-  s->AddSymbol(sexp, KindToCString(kind()));
-}
-
-SExpression* FlowGraphSerializer::LocalVariableToSExp(const LocalVariable& v) {
-  auto const sexp = new (zone()) SExpList(zone());
-  AddSymbol(sexp, "LocalVariable");
-  if (!v.name().IsNull()) {
-    AddSymbol(sexp, v.name().ToCString());
-  }
-  if (v.index().IsValid()) {
-    AddExtraInteger(sexp, "index", v.index().value());
-  }
-  return sexp;
-}
-
-void LoadLocalInstr::AddOperandsToSExpression(SExpList* sexp,
-                                              FlowGraphSerializer* s) const {
-  sexp->Add(s->LocalVariableToSExp(local()));
-}
-
-void StoreLocalInstr::AddOperandsToSExpression(SExpList* sexp,
-                                               FlowGraphSerializer* s) const {
-  sexp->Add(s->LocalVariableToSExp(local()));
-}
-
-SExpression* FlowGraphSerializer::SlotToSExp(const Slot& slot) {
-  auto sexp = new (zone()) SExpList(zone());
-  AddSymbol(sexp, "Slot");
-  AddInteger(sexp, slot.offset_in_bytes());
-  AddExtraSymbol(sexp, "kind", Slot::KindToCString(slot.kind()));
-  if (slot.IsDartField()) {
-    sexp->AddExtra("field", DartValueToSExp(slot.field()));
-  }
-  return sexp;
-}
-
-void LoadFieldInstr::AddOperandsToSExpression(SExpList* sexp,
-                                              FlowGraphSerializer* s) const {
-  sexp->Add(instance()->ToSExpression(s));
-  sexp->Add(s->SlotToSExp(slot()));
-}
-
-void LoadFieldInstr::AddExtraInfoToSExpression(SExpList* sexp,
-                                               FlowGraphSerializer* s) const {
-  Instruction::AddExtraInfoToSExpression(sexp, s);
-  if (calls_initializer() || FLAG_verbose_flow_graph_serialization) {
-    s->AddExtraBool(sexp, "calls_initializer", calls_initializer());
-  }
-}
-
-void StoreInstanceFieldInstr::AddOperandsToSExpression(
-    SExpList* sexp,
-    FlowGraphSerializer* s) const {
-  sexp->Add(instance()->ToSExpression(s));
-  sexp->Add(s->SlotToSExp(slot()));
-  sexp->Add(value()->ToSExpression(s));
-}
-
-void StoreInstanceFieldInstr::AddExtraInfoToSExpression(
-    SExpList* sexp,
-    FlowGraphSerializer* s) const {
-  Instruction::AddExtraInfoToSExpression(sexp, s);
-  if (is_initialization_ || FLAG_verbose_flow_graph_serialization) {
-    s->AddExtraBool(sexp, "is_init", is_initialization_);
-  }
-  if (emit_store_barrier_ != kNoStoreBarrier ||
-      FLAG_verbose_flow_graph_serialization) {
-    // Make sure that we aren't seeing a new value added to the StoreBarrierType
-    // enum that isn't handled by the serializer.
-    ASSERT(emit_store_barrier_ == kNoStoreBarrier ||
-           emit_store_barrier_ == kEmitStoreBarrier);
-    s->AddExtraBool(sexp, "emit_barrier",
-                    emit_store_barrier_ != kNoStoreBarrier);
-  }
-}
-
-void LoadIndexedUnsafeInstr::AddExtraInfoToSExpression(
-    SExpList* sexp,
-    FlowGraphSerializer* s) const {
-  Instruction::AddExtraInfoToSExpression(sexp, s);
-  if (offset() > 0 || FLAG_verbose_flow_graph_serialization) {
-    s->AddExtraInteger(sexp, "offset", offset());
-  }
-}
-
-void StoreIndexedUnsafeInstr::AddExtraInfoToSExpression(
-    SExpList* sexp,
-    FlowGraphSerializer* s) const {
-  Instruction::AddExtraInfoToSExpression(sexp, s);
-  if (offset() > 0 || FLAG_verbose_flow_graph_serialization) {
-    s->AddExtraInteger(sexp, "offset", offset());
-  }
-}
-
-void ComparisonInstr::AddOperandsToSExpression(SExpList* sexp,
-                                               FlowGraphSerializer* s) const {
-  s->AddSymbol(sexp, Token::Str(kind()));
-  Instruction::AddOperandsToSExpression(sexp, s);
-}
-
-void StrictCompareInstr::AddExtraInfoToSExpression(
-    SExpList* sexp,
-    FlowGraphSerializer* s) const {
-  Instruction::AddExtraInfoToSExpression(sexp, s);
-  if (needs_number_check_ || FLAG_verbose_flow_graph_serialization) {
-    s->AddExtraBool(sexp, "needs_check", needs_number_check_);
-  }
-}
-
-void DoubleTestOpInstr::AddOperandsToSExpression(SExpList* sexp,
-                                                 FlowGraphSerializer* s) const {
-  const bool negated = kind() != Token::kEQ;
-  switch (op_kind()) {
-    case MethodRecognizer::kDouble_getIsNaN:
-      s->AddSymbol(sexp, negated ? "IsNotNaN" : "IsNaN");
-      break;
-    case MethodRecognizer::kDouble_getIsInfinite:
-      s->AddSymbol(sexp, negated ? "IsNotInfinite" : "IsInfinite");
-      break;
-    default:
-      UNREACHABLE();
-  }
-  sexp->Add(value()->ToSExpression(s));
-}
-
-void GotoInstr::AddOperandsToSExpression(SExpList* sexp,
-                                         FlowGraphSerializer* s) const {
-  sexp->Add(s->BlockIdToSExp(successor()->block_id()));
-}
-
-void DebugStepCheckInstr::AddExtraInfoToSExpression(
-    SExpList* sexp,
-    FlowGraphSerializer* s) const {
-  Instruction::AddExtraInfoToSExpression(sexp, s);
-  if (stub_kind_ != UntaggedPcDescriptors::kAnyKind ||
-      FLAG_verbose_flow_graph_serialization) {
-    auto const stub_kind_name =
-        UntaggedPcDescriptors::KindToCString(stub_kind_);
-    ASSERT(stub_kind_name != nullptr);
-    s->AddExtraSymbol(sexp, "stub_kind", stub_kind_name);
-  }
-}
-
-SExpression* FlowGraphSerializer::ICDataToSExp(const ICData* ic_data) {
-  auto const sexp = new (zone()) SExpList(zone());
-  AddSymbol(sexp, "ICData");
-
-  if (ic_data->is_tracking_exactness()) {
-    ic_data_type_ = ic_data->receivers_static_type();
-    sexp->AddExtra("receivers_static_type", AbstractTypeToSExp(ic_data_type_));
-  }
-
-  if (ic_data->is_megamorphic() || FLAG_verbose_flow_graph_serialization) {
-    AddExtraBool(sexp, "is_megamorphic", ic_data->is_megamorphic());
-  }
-
-  auto const num_checks = ic_data->NumberOfChecks();
-  GrowableArray<intptr_t> class_ids(zone(), 2);
-  for (intptr_t i = 0; i < num_checks; i++) {
-    auto const entry = new (zone()) SExpList(zone());
-
-    auto const count = ic_data->GetCountAt(i);
-    if (count > 0 || FLAG_verbose_flow_graph_serialization) {
-      AddExtraInteger(entry, "count", count);
-    }
-
-    class_ids.Clear();
-    ic_data->GetCheckAt(i, &class_ids, &ic_data_target_);
-    entry->AddExtra("target", DartValueToSExp(ic_data_target_));
-    for (auto const cid : class_ids) {
-      entry->Add(new (zone()) SExpInteger(cid));
-    }
-
-    sexp->Add(entry);
-  }
-
-  if (FLAG_verbose_flow_graph_serialization) {
-    AddExtraSymbol(sexp, "rebind_rule",
-                   ICData::RebindRuleToCString(ic_data->rebind_rule()));
-    tmp_string_ = ic_data->target_name();
-    AddExtraString(sexp, "target_name", tmp_string_.ToCString());
-    ic_data_target_ = ic_data->Owner();
-    sexp->AddExtra("owner", DartValueToSExp(ic_data_target_));
-    AddExtraInteger(sexp, "num_args_tested", ic_data->NumArgsTested());
-    auto& args_desc = Array::Handle(zone(), ic_data->arguments_descriptor());
-    sexp->AddExtra("arguments_descriptor", DartValueToSExp(args_desc));
-  }
-
-  return sexp;
-}
-
-void TailCallInstr::AddOperandsToSExpression(SExpList* sexp,
-                                             FlowGraphSerializer* s) const {
-  if (auto const code = s->DartValueToSExp(code_)) {
-    sexp->Add(code);
-  }
-  Instruction::AddOperandsToSExpression(sexp, s);
-}
-
-void NativeCallInstr::AddOperandsToSExpression(SExpList* sexp,
-                                               FlowGraphSerializer* s) const {
-  Instruction::AddOperandsToSExpression(sexp, s);
-}
-
-void NativeCallInstr::AddExtraInfoToSExpression(SExpList* sexp,
-                                                FlowGraphSerializer* s) const {
-  TemplateDartCall<0>::AddExtraInfoToSExpression(sexp, s);
-  if (auto const func = s->DartValueToSExp(function())) {
-    sexp->AddExtra("function", func);
-  }
-  if (!native_name().IsNull()) {
-    s->AddExtraString(sexp, "name", native_name().ToCString());
-  }
-  if (link_lazily() || FLAG_verbose_flow_graph_serialization) {
-    s->AddExtraBool(sexp, "link_lazily", link_lazily());
-  }
-}
-
-template <intptr_t kExtraInputs>
-void TemplateDartCall<kExtraInputs>::AddExtraInfoToSExpression(
-    SExpList* sexp,
-    FlowGraphSerializer* s) const {
-  Instruction::AddExtraInfoToSExpression(sexp, s);
-  if (type_args_len() > 0 || FLAG_verbose_flow_graph_serialization) {
-    s->AddExtraInteger(sexp, "type_args_len", type_args_len());
-  }
-  s->AddExtraInteger(sexp, "args_len", ArgumentCountWithoutTypeArgs());
-
-  const auto& arg_names = argument_names();
-  if (!arg_names.IsNull()) {
-    auto arg_names_sexp = new (s->zone()) SExpList(s->zone());
-    auto& str = String::Handle(s->zone());
-    for (intptr_t i = 0; i < arg_names.Length(); i++) {
-      str = String::RawCast(arg_names.At(i));
-      arg_names_sexp->Add(s->ObjectToSExp(str));
-    }
-    sexp->AddExtra("arg_names", arg_names_sexp);
-  }
-
-  ASSERT(!HasPushArguments());
-}
-
-void ClosureCallInstr::AddExtraInfoToSExpression(SExpList* sexp,
-                                                 FlowGraphSerializer* s) const {
-  // For now, just here to ensure TemplateDartCall<1>::AddExtraInfoToSExpression
-  // gets instantiated.
-  TemplateDartCall<1>::AddExtraInfoToSExpression(sexp, s);
-}
-
-void StaticCallInstr::AddOperandsToSExpression(SExpList* sexp,
-                                               FlowGraphSerializer* s) const {
-  Instruction::AddOperandsToSExpression(sexp, s);
-}
-
-void StaticCallInstr::AddExtraInfoToSExpression(SExpList* sexp,
-                                                FlowGraphSerializer* s) const {
-  TemplateDartCall<0>::AddExtraInfoToSExpression(sexp, s);
-
-  if (auto const func = s->DartValueToSExp(function())) {
-    sexp->AddExtra("function", func);
-  }
-
-  if (HasICData()) {
-    sexp->AddExtra("ic_data", s->ICDataToSExp(ic_data()));
-  } else if (CallCount() > 0 || FLAG_verbose_flow_graph_serialization) {
-    s->AddExtraInteger(sexp, "call_count", CallCount());
-  }
-
-  if (rebind_rule_ != ICData::kStatic ||
-      FLAG_verbose_flow_graph_serialization) {
-    auto const str = ICData::RebindRuleToCString(rebind_rule_);
-    ASSERT(str != nullptr);
-    s->AddExtraSymbol(sexp, "rebind_rule", str);
-  }
-
-  if (ShouldSerializeType(result_type())) {
-    sexp->AddExtra("result_type", result_type()->ToSExpression(s));
-  }
-
-  if (entry_kind() != Code::EntryKind::kNormal ||
-      FLAG_verbose_flow_graph_serialization) {
-    auto const kind_str = Code::EntryKindToCString(entry_kind());
-    s->AddExtraSymbol(sexp, "entry_kind", kind_str);
-  }
-}
-
-void InstanceCallBaseInstr::AddOperandsToSExpression(
-    SExpList* sexp,
-    FlowGraphSerializer* s) const {
-  Instruction::AddOperandsToSExpression(sexp, s);
-}
-
-void InstanceCallBaseInstr::AddExtraInfoToSExpression(
-    SExpList* sexp,
-    FlowGraphSerializer* s) const {
-  TemplateDartCall<0>::AddExtraInfoToSExpression(sexp, s);
-
-  if (auto const target = s->DartValueToSExp(interface_target())) {
-    sexp->AddExtra("interface_target", target);
-  }
-
-  if (auto const target = s->DartValueToSExp(tearoff_interface_target())) {
-    sexp->AddExtra("tearoff_interface_target", target);
-  }
-
-  if (HasICData()) {
-    sexp->AddExtra("ic_data", s->ICDataToSExp(ic_data()));
-  }
-
-  if (function_name().IsNull()) {
-    if (!interface_target().IsNull() || !tearoff_interface_target().IsNull()) {
-      s->AddExtraSymbol(sexp, "function_name", "null");
-    }
-  } else {
-    if (interface_target().IsNull() ||
-        (function_name().ptr() != interface_target().name() &&
-         function_name().ptr() != tearoff_interface_target().name())) {
-      s->AddExtraString(sexp, "function_name", function_name().ToCString());
-    }
-  }
-
-  if (token_kind() != Token::kILLEGAL) {
-    s->AddExtraSymbol(sexp, "token_kind", Token::Str(token_kind()));
-  }
-
-  if (ShouldSerializeType(result_type())) {
-    sexp->AddExtra("result_type", result_type()->ToSExpression(s));
-  }
-
-  if (entry_kind() != Code::EntryKind::kNormal ||
-      FLAG_verbose_flow_graph_serialization) {
-    auto const kind_str = Code::EntryKindToCString(entry_kind());
-    s->AddExtraSymbol(sexp, "entry_kind", kind_str);
-  }
-}
-
-void InstanceCallInstr::AddExtraInfoToSExpression(
-    SExpList* sexp,
-    FlowGraphSerializer* s) const {
-  InstanceCallBaseInstr::AddExtraInfoToSExpression(sexp, s);
-
-  if (checked_argument_count() > 0 || FLAG_verbose_flow_graph_serialization) {
-    s->AddExtraInteger(sexp, "checked_arg_count", checked_argument_count());
-  }
-}
-
-void PolymorphicInstanceCallInstr::AddExtraInfoToSExpression(
-    SExpList* sexp,
-    FlowGraphSerializer* s) const {
-  InstanceCallBaseInstr::AddExtraInfoToSExpression(sexp, s);
-
-  if (targets().length() > 0 || FLAG_verbose_flow_graph_serialization) {
-    auto elem_list = new (s->zone()) SExpList(s->zone());
-    for (intptr_t i = 0; i < targets().length(); i++) {
-      auto elem = new (s->zone()) SExpList(s->zone());
-      const TargetInfo* ti = targets().TargetAt(i);
-      if (ti->cid_start == ti->cid_end) {
-        s->AddInteger(elem, ti->cid_start);
-      } else {
-        auto range = new (s->zone()) SExpList(s->zone());
-        s->AddInteger(range, ti->cid_start);
-        s->AddInteger(range, ti->cid_end);
-        elem->Add(range);
-      }
-      if (auto const target = s->DartValueToSExp(*ti->target)) {
-        elem->Add(target);
-      }
-      elem_list->Add(elem);
-    }
-    sexp->AddExtra("targets", elem_list);
-  }
-}
-
-void AllocateObjectInstr::AddOperandsToSExpression(
-    SExpList* sexp,
-    FlowGraphSerializer* s) const {
-  if (auto const sexp_cls = s->DartValueToSExp(cls())) {
-    sexp->Add(sexp_cls);
-  }
-  if (type_arguments() != nullptr) {
-    sexp->Add(type_arguments()->ToSExpression(s));
-  }
-}
-
-void AllocateObjectInstr::AddExtraInfoToSExpression(
-    SExpList* sexp,
-    FlowGraphSerializer* s) const {
-  Instruction::AddExtraInfoToSExpression(sexp, s);
-  s->AddExtraInteger(sexp, "size", cls().target_instance_size());
-  if (auto const closure = s->DartValueToSExp(closure_function())) {
-    sexp->AddExtra("closure_function", closure);
-  }
-  if (!Identity().IsUnknown() || FLAG_verbose_flow_graph_serialization) {
-    s->AddExtraSymbol(sexp, "identity", Identity().ToCString());
-  }
-}
-
-void BinaryIntegerOpInstr::AddOperandsToSExpression(
-    SExpList* sexp,
-    FlowGraphSerializer* s) const {
-  s->AddSymbol(sexp, Token::Str(op_kind()));
-  sexp->Add(left()->ToSExpression(s));
-  sexp->Add(right()->ToSExpression(s));
-}
-
-void CheckedSmiOpInstr::AddOperandsToSExpression(SExpList* sexp,
-                                                 FlowGraphSerializer* s) const {
-  s->AddSymbol(sexp, Token::Str(op_kind()));
-  sexp->Add(left()->ToSExpression(s));
-  sexp->Add(right()->ToSExpression(s));
-}
-
-// clang-format off
-static const char* simd_op_kind_string[] = {
-#define CASE(Arity, Mask, Name, ...) #Name,
-  SIMD_OP_LIST(CASE, CASE)
-#undef CASE
-  "IllegalSimdOp",
-};
-// clang-format on
-
-void SimdOpInstr::AddOperandsToSExpression(SExpList* sexp,
-                                           FlowGraphSerializer* s) const {
-  s->AddSymbol(sexp, simd_op_kind_string[kind()]);
-  Instruction::AddOperandsToSExpression(sexp, s);
-}
-
-void SimdOpInstr::AddExtraInfoToSExpression(SExpList* sexp,
-                                            FlowGraphSerializer* s) const {
-  Instruction::AddExtraInfoToSExpression(sexp, s);
-  if (HasMask()) {
-    s->AddExtraInteger(sexp, "mask", mask());
-  }
-}
-
-void LoadIndexedInstr::AddExtraInfoToSExpression(SExpList* sexp,
-                                                 FlowGraphSerializer* s) const {
-  Instruction::AddExtraInfoToSExpression(sexp, s);
-  if (aligned() || FLAG_verbose_flow_graph_serialization) {
-    s->AddExtraBool(sexp, "aligned", aligned());
-  }
-  if (index_scale() > 1 || FLAG_verbose_flow_graph_serialization) {
-    s->AddExtraInteger(sexp, "scale", index_scale());
-  }
-  if (class_id() != kDynamicCid || FLAG_verbose_flow_graph_serialization) {
-    s->AddExtraInteger(sexp, "cid", class_id());
-  }
-}
-
-void StoreIndexedInstr::AddExtraInfoToSExpression(
-    SExpList* sexp,
-    FlowGraphSerializer* s) const {
-  Instruction::AddExtraInfoToSExpression(sexp, s);
-  if (aligned() || FLAG_verbose_flow_graph_serialization) {
-    s->AddExtraBool(sexp, "aligned", aligned());
-  }
-  if (index_scale() > 1 || FLAG_verbose_flow_graph_serialization) {
-    s->AddExtraInteger(sexp, "scale", index_scale());
-  }
-  if (class_id() != kDynamicCid || FLAG_verbose_flow_graph_serialization) {
-    s->AddExtraInteger(sexp, "cid", class_id());
-  }
-}
-
-void CheckStackOverflowInstr::AddExtraInfoToSExpression(
-    SExpList* sexp,
-    FlowGraphSerializer* s) const {
-  Instruction::AddExtraInfoToSExpression(sexp, s);
-  if (stack_depth() > 0 || FLAG_verbose_flow_graph_serialization) {
-    s->AddExtraInteger(sexp, "stack_depth", stack_depth());
-  }
-  if (in_loop() || FLAG_verbose_flow_graph_serialization) {
-    s->AddExtraInteger(sexp, "loop_depth", loop_depth());
-  }
-  if (kind_ != kOsrAndPreemption) {
-    ASSERT(kind_ == kOsrOnly);
-    s->AddExtraSymbol(sexp, "kind", "OsrOnly");
-  }
-}
-
-void CheckNullInstr::AddExtraInfoToSExpression(SExpList* sexp,
-                                               FlowGraphSerializer* s) const {
-  Instruction::AddExtraInfoToSExpression(sexp, s);
-  if (!function_name_.IsNull()) {
-    s->AddExtraString(sexp, "function_name", function_name_.ToCString());
-  }
-}
-
-SExpression* Value::ToSExpression(FlowGraphSerializer* s) const {
-  auto name = s->UseToSExp(definition());
-  // If we're not serializing types or there is no reaching type for this use,
-  // just serialize the use as the bound name.
-  if (!ShouldSerializeType(reaching_type_)) return name;
-
-  auto sexp = new (s->zone()) SExpList(s->zone());
-  s->AddSymbol(sexp, "value");
-  sexp->Add(name);
-  // If there is no owner for the type, then serialize the type in full.
-  // Otherwise the owner should be the definition, so we'll inherit the type
-  // from it. (That is, (value v<X>) with no explicit type info means the
-  // reaching type comes from the definition of v<X>.) We'll serialize an
-  // "inherit_type" extra info field to make this explicit when in verbose mode.
-  if (reaching_type_->owner() == nullptr) {
-    sexp->AddExtra("type", reaching_type_->ToSExpression(s));
-  } else {
-    ASSERT(reaching_type_->owner() == definition());
-  }
-  if (FLAG_verbose_flow_graph_serialization) {
-    s->AddExtraBool(sexp, "inherit_type",
-                    reaching_type_->owner() == definition());
-  }
-  return sexp;
-}
-
-SExpression* CompileType::ToSExpression(FlowGraphSerializer* s) const {
-  ASSERT(FLAG_verbose_flow_graph_serialization ||
-         FLAG_serialize_flow_graph_types);
-
-  auto sexp = new (s->zone()) SExpList(s->zone());
-  s->AddSymbol(sexp, "CompileType");
-  AddExtraInfoToSExpression(sexp, s);
-  return sexp;
-}
-
-void CompileType::AddExtraInfoToSExpression(SExpList* sexp,
-                                            FlowGraphSerializer* s) const {
-  if (cid_ != kIllegalCid || FLAG_verbose_flow_graph_serialization) {
-    s->AddExtraInteger(sexp, "cid", cid_);
-  }
-  // TODO(sstrickl): Currently we only print out nullable if it's false
-  // (or during verbose printing). Switch this when NNBD is the standard.
-  if (!is_nullable() || FLAG_verbose_flow_graph_serialization) {
-    s->AddExtraBool(sexp, "nullable", is_nullable());
-  }
-  if (type_ != nullptr) {
-    sexp->AddExtra("type", s->DartValueToSExp(*type_));
-  }
-}
-
-SExpression* Environment::ToSExpression(FlowGraphSerializer* s) const {
-  auto sexp = new (s->zone()) SExpList(s->zone());
-  for (intptr_t i = 0; i < values_.length(); ++i) {
-    ASSERT(!values_[i]->definition()->IsPushArgument());
-    sexp->Add(values_[i]->ToSExpression(s));
-    // TODO(sstrickl): This currently assumes that there are no locations in the
-    // environment (e.g. before register allocation). If we ever want to print
-    // out environments on steps after AllocateRegisters, we'll need to handle
-    // locations as well.
-    ASSERT(locations_ == nullptr || locations_[i].IsInvalid());
-  }
-  if (outer_ != NULL) {
-    auto outer_sexp = outer_->ToSExpression(s)->AsList();
-    if (outer_->deopt_id_ != DeoptId::kNone) {
-      s->AddExtraInteger(outer_sexp, "deopt_id", outer_->deopt_id_);
-    }
-    sexp->AddExtra("outer", outer_sexp);
-  }
-  return sexp;
-}
-
-}  // namespace dart
diff --git a/runtime/vm/compiler/backend/il_serializer.h b/runtime/vm/compiler/backend/il_serializer.h
deleted file mode 100644
index fda5731..0000000
--- a/runtime/vm/compiler/backend/il_serializer.h
+++ /dev/null
@@ -1,198 +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.
-
-#ifndef RUNTIME_VM_COMPILER_BACKEND_IL_SERIALIZER_H_
-#define RUNTIME_VM_COMPILER_BACKEND_IL_SERIALIZER_H_
-
-#if defined(DART_PRECOMPILED_RUNTIME)
-#error "AOT runtime should not use compiler sources (including header files)"
-#endif  // defined(DART_PRECOMPILED_RUNTIME)
-
-#include "platform/assert.h"
-#include "platform/text_buffer.h"
-
-#include "vm/allocation.h"
-#include "vm/compiler/backend/flow_graph.h"
-#include "vm/compiler/backend/il.h"
-#include "vm/compiler/backend/sexpression.h"
-#include "vm/hash_table.h"
-#include "vm/object.h"
-#include "vm/zone.h"
-
-namespace dart {
-
-// Flow graph serialization.
-class FlowGraphSerializer : ValueObject {
- public:
-#define FOR_EACH_BLOCK_ENTRY_KIND(M)                                           \
-  M(Target)                                                                    \
-  M(Join)                                                                      \
-  M(Graph)                                                                     \
-  M(Normal)                                                                    \
-  M(Unchecked)                                                                 \
-  M(OSR)                                                                       \
-  M(Catch)                                                                     \
-  M(Indirect)
-
-  enum BlockEntryKind {
-#define KIND_DECL(name) k##name,
-    FOR_EACH_BLOCK_ENTRY_KIND(KIND_DECL)
-#undef KIND_DECL
-    // clang-format off
-    kNumEntryKinds,
-    kInvalid = -1,
-    // clang-format on
-  };
-
-  // Special case: returns kTarget for a nullptr input.
-  static BlockEntryKind BlockEntryTagToKind(SExpSymbol* tag);
-  SExpSymbol* BlockEntryKindToTag(BlockEntryKind k);
-  static bool BlockEntryKindHasInitialDefs(BlockEntryKind kind);
-
-  static void SerializeToBuffer(Zone* zone,
-                                const FlowGraph* flow_graph,
-                                BaseTextBuffer* buffer);
-  static SExpression* SerializeToSExp(Zone* zone, const FlowGraph* flow_graph);
-
-  const FlowGraph* flow_graph() const { return flow_graph_; }
-  Zone* zone() const { return zone_; }
-
-  SExpression* FlowGraphToSExp();
-
-  SExpSymbol* BlockEntryTag(const BlockEntryInstr* entry);
-  SExpression* BlockIdToSExp(intptr_t block_id);
-  SExpression* CanonicalNameToSExp(const Object& obj);
-  SExpression* UseToSExp(const Definition* definition);
-
-  // Helper method for creating canonical names.
-  void SerializeCanonicalName(BaseTextBuffer* b, const Object& obj);
-
-  // Methods for serializing Dart values. If the argument
-  // value is the null object, the null pointer is returned.
-  SExpression* AbstractTypeToSExp(const AbstractType& typ);
-  SExpression* ArrayToSExp(const Array& arr);
-  SExpression* ImmutableListToSExp(const Array& arr);
-  SExpression* ClassToSExp(const Class& cls);
-  SExpression* ClosureToSExp(const Closure& c);
-  SExpression* ContextToSExp(const Context& c);
-  SExpression* CodeToSExp(const Code& c);
-  SExpression* FieldToSExp(const Field& f);
-  SExpression* FunctionToSExp(const Function& f);
-  SExpression* InstanceToSExp(const Instance& obj);
-  SExpression* TypeArgumentsToSExp(const TypeArguments& ta);
-
-  // A method for serializing a Dart value of arbitrary type. Unlike the
-  // type-specific methods, this returns the symbol "null" for the null object.
-  SExpression* ObjectToSExp(const Object& obj);
-
-  // A wrapper method for ObjectToSExp that first checks and sees if
-  // the provided value is in the constant pool. If it is, then it
-  // returns a reference to the constant definition via UseToSExp.
-  SExpression* DartValueToSExp(const Object& obj);
-
-  // A wrapper method for TypeArgumentsToSExp that also returns nullptr if the
-  // type arguments are empty and checks against the constant pool.
-  SExpression* NonEmptyTypeArgumentsToSExp(const TypeArguments& ta);
-
-  // Methods for serializing IL-specific values.
-  SExpression* LocalVariableToSExp(const LocalVariable& v);
-  SExpression* SlotToSExp(const Slot& s);
-  SExpression* ICDataToSExp(const ICData* ic_data);
-
-  // Helper methods for adding Definition-specific extra info.
-  bool HasDefinitionExtraInfo(const Definition* def);
-  void AddDefinitionExtraInfoToSExp(const Definition* def, SExpList* sexp);
-
-  // Helper methods for adding atoms to S-expression lists
-  void AddBool(SExpList* sexp, bool b);
-  void AddInteger(SExpList* sexp, intptr_t i);
-  void AddString(SExpList* sexp, const char* cstr);
-  void AddSymbol(SExpList* sexp, const char* cstr);
-  void AddExtraBool(SExpList* sexp, const char* label, bool b);
-  void AddExtraInteger(SExpList* sexp, const char* label, intptr_t i);
-  void AddExtraString(SExpList* sexp, const char* label, const char* cstr);
-  void AddExtraSymbol(SExpList* sexp, const char* label, const char* cstr);
-
- private:
-  friend class Precompiler;  // For LLVMConstantsMap.
-
-  FlowGraphSerializer(Zone* zone, const FlowGraph* flow_graph);
-  ~FlowGraphSerializer();
-
-  static const char* const initial_indent;
-
-  // Helper methods for the function level that are not used by any
-  // instruction serialization methods.
-  SExpression* FunctionEntryToSExp(const BlockEntryInstr* entry);
-  SExpression* EntriesToSExp(const GraphEntryInstr* start);
-  SExpression* ConstantPoolToSExp(const GraphEntryInstr* start);
-
-  const FlowGraph* const flow_graph_;
-  Zone* const zone_;
-  ObjectStore* const object_store_;
-
-  // A map of currently open (being serialized) recursive types. We use this
-  // to determine whether to serialize the referred types in TypeRefs.
-  IntMap<const AbstractType*> open_recursive_types_;
-
-  // Used for --populate-llvm-constant-pool in ConstantPoolToSExp.
-  class LLVMPoolMapKeyEqualsTraits : public AllStatic {
-   public:
-    static const char* Name() { return "LLVMPoolMapKeyEqualsTraits"; }
-    static bool ReportStats() { return false; }
-
-    static bool IsMatch(const Object& a, const Object& b) {
-      return a.ptr() == b.ptr();
-    }
-    static uword Hash(const Object& obj) {
-      if (obj.IsSmi()) return static_cast<uword>(obj.ptr());
-      if (obj.IsInstance()) return Instance::Cast(obj).CanonicalizeHash();
-      return obj.GetClassId();
-    }
-  };
-  typedef UnorderedHashMap<LLVMPoolMapKeyEqualsTraits> LLVMPoolMap;
-
-  GrowableObjectArray& llvm_constants_;
-  GrowableObjectArray& llvm_functions_;
-  LLVMPoolMap llvm_constant_map_;
-  Smi& llvm_index_;
-
-  // Handles used across functions, where the contained value is used
-  // immediately and does not need to live across calls to other serializer
-  // functions.
-  String& tmp_string_;
-
-  // Handles for use within a single function in the following cases:
-  //
-  // * The function is guaranteed to not be re-entered during execution.
-  // * The contained value is not live across any possible re-entry.
-  //
-  // Generally, the most likely source of possible re-entry is calling
-  // DartValueToSExp with a sub-element of type Object, but any call to a
-  // FlowGraphSerializer method that may eventually enter one of the methods
-  // listed below should be examined with care.
-  TypeArguments& array_type_args_;     // ArrayToSExp
-  Context& closure_context_;           // ClosureToSExp
-  Function& closure_function_;         // ClosureToSExp
-  TypeArguments& closure_type_args_;   // ClosureToSExp
-  Object& code_owner_;                 // CodeToSExp
-  Context& context_parent_;            // ContextToSExp
-  Object& context_elem_;               // ContextToSExp
-  TypeArguments& function_type_args_;  // FunctionToSExp
-  Function& ic_data_target_;           // ICDataToSExp
-  AbstractType& ic_data_type_;         // ICDataToSExp
-  Field& instance_field_;              // InstanceToSExp
-  TypeArguments& instance_type_args_;  // InstanceToSExp
-  Library& serialize_library_;         // SerializeCanonicalName
-  Class& serialize_owner_;             // SerializeCanonicalName
-  Function& serialize_parent_;         // SerializeCanonicalName
-  AbstractType& type_arguments_elem_;  // TypeArgumentsToSExp
-  Class& type_class_;                  // AbstractTypeToSExp
-  FunctionType& type_signature_;       // AbstractTypeToSExp
-  AbstractType& type_ref_type_;        // AbstractTypeToSExp
-};
-
-}  // namespace dart
-
-#endif  // RUNTIME_VM_COMPILER_BACKEND_IL_SERIALIZER_H_
diff --git a/runtime/vm/compiler/backend/il_test_helper.cc b/runtime/vm/compiler/backend/il_test_helper.cc
index ab32cd4..a99374c 100644
--- a/runtime/vm/compiler/backend/il_test_helper.cc
+++ b/runtime/vm/compiler/backend/il_test_helper.cc
@@ -21,8 +21,6 @@
 
 namespace dart {
 
-Definition* const FlowGraphBuilderHelper::kPhiSelfReference = nullptr;
-
 LibraryPtr LoadTestScript(const char* script,
                           Dart_NativeEntryResolver resolver,
                           const char* lib_uri) {
@@ -204,8 +202,7 @@
 
   // We expect there to be no deoptimizations.
   if (mode_ == CompilerPass::kAOT) {
-    // TODO(kustermann): Enable this once we get rid of [CheckedSmiSlowPath]s.
-    // EXPECT(deopt_info_array.IsNull() || deopt_info_array.Length() == 0);
+    EXPECT(deopt_info_array.IsNull() || deopt_info_array.Length() == 0);
   }
 }
 
diff --git a/runtime/vm/compiler/backend/il_test_helper.h b/runtime/vm/compiler/backend/il_test_helper.h
index e34a5fe..7ef8db3 100644
--- a/runtime/vm/compiler/backend/il_test_helper.h
+++ b/runtime/vm/compiler/backend/il_test_helper.h
@@ -5,6 +5,7 @@
 #ifndef RUNTIME_VM_COMPILER_BACKEND_IL_TEST_HELPER_H_
 #define RUNTIME_VM_COMPILER_BACKEND_IL_TEST_HELPER_H_
 
+#include <type_traits>
 #include <utility>
 #include <vector>
 
@@ -277,20 +278,48 @@
     return flow_graph_.GetConstant(Double::Handle(Double::NewCanonical(value)));
   }
 
-  static Definition* const kPhiSelfReference;
+  enum class IncomingDefKind {
+    kImmediate,
+    kDelayed,
+  };
+
+  class IncomingDef {
+   public:
+    IncomingDef(BlockEntryInstr* from, Definition* defn)
+        : kind_(IncomingDefKind::kImmediate), from_(from), defn_(defn) {}
+
+    template <typename T,
+              typename = typename std::enable_if<
+                  std::is_base_of<Definition, T>::value>::type>
+    IncomingDef(BlockEntryInstr* from, T** defn_source)
+        : kind_(IncomingDefKind::kDelayed),
+          from_(from),
+          defn_source_(reinterpret_cast<Definition**>(defn_source)) {}
+
+    BlockEntryInstr* from() const { return from_; }
+    Definition* defn() const {
+      return kind_ == IncomingDefKind::kImmediate ? defn_ : *defn_source_;
+    }
+
+   private:
+    IncomingDefKind kind_;
+    BlockEntryInstr* from_;
+    union {
+      Definition* defn_;
+      Definition** defn_source_;
+    };
+  };
 
   PhiInstr* Phi(JoinEntryInstr* join,
-                std::initializer_list<std::pair<BlockEntryInstr*, Definition*>>
-                    incoming) {
+                std::initializer_list<IncomingDef> incoming) {
     auto phi = new PhiInstr(join, incoming.size());
     for (size_t i = 0; i < incoming.size(); i++) {
       auto input = new Value(flow_graph_.constant_dead());
       phi->SetInputAt(i, input);
       input->definition()->AddInputUse(input);
     }
-    for (auto pair : incoming) {
-      pending_phis_.Add({phi, pair.first,
-                         pair.second == kPhiSelfReference ? phi : pair.second});
+    for (auto def : incoming) {
+      pending_phis_.Add({phi, def});
     }
     return phi;
   }
@@ -303,9 +332,9 @@
     for (auto& pending : pending_phis_) {
       auto join = pending.phi->block();
       EXPECT(pending.phi->InputCount() == join->PredecessorCount());
-      auto pred_index = join->IndexOfPredecessor(pending.pred);
+      auto pred_index = join->IndexOfPredecessor(pending.incoming.from());
       EXPECT(pred_index != -1);
-      pending.phi->InputAt(pred_index)->BindTo(pending.defn);
+      pending.phi->InputAt(pred_index)->BindTo(pending.incoming.defn());
     }
   }
 
@@ -347,8 +376,7 @@
 
   struct PendingPhiInput {
     PhiInstr* phi;
-    BlockEntryInstr* pred;
-    Definition* defn;
+    IncomingDef incoming;
   };
   GrowableArray<PendingPhiInput> pending_phis_;
 };
diff --git a/runtime/vm/compiler/backend/il_x64.cc b/runtime/vm/compiler/backend/il_x64.cc
index a42852b..da435ce3 100644
--- a/runtime/vm/compiler/backend/il_x64.cc
+++ b/runtime/vm/compiler/backend/il_x64.cc
@@ -30,6 +30,9 @@
 
 namespace dart {
 
+DECLARE_FLAG(bool, inline_alloc);
+DECLARE_FLAG(bool, use_slow_path);
+
 // Generic summary for call instructions that have all arguments pushed
 // on the stack and return the result in a fixed register RAX (or XMM0 if
 // the return type is double).
@@ -88,6 +91,14 @@
   ASSERT(kSmiTagSize == 1);
 
   const Register index = locs()->in(0).reg();
+#if defined(DART_COMPRESSED_POINTERS)
+  // No addressing mode will ignore the upper bits. Cannot use the shorter `orl`
+  // to clear the upper bits as this instructions uses negative indices as part
+  // of FP-relative loads.
+  // TODO(compressed-pointers): Can we guarentee the index is already
+  // sign-extended if always comes for an args-descriptor load?
+  __ movsxd(index, index);
+#endif
 
   switch (representation()) {
     case kTagged:
@@ -111,6 +122,14 @@
                (NoLocation, Register index, Register value)) {
   ASSERT(instr->RequiredInputRepresentation(
              StoreIndexedUnsafeInstr::kIndexPos) == kTagged);  // It is a Smi.
+#if defined(DART_COMPRESSED_POINTERS)
+  // No addressing mode will ignore the upper bits. Cannot use the shorter `orl`
+  // to clear the upper bits as this instructions uses negative indices as part
+  // of FP-relative stores.
+  // TODO(compressed-pointers): Can we guarentee the index is already
+  // sign-extended if always comes for an args-descriptor load?
+  __ movsxd(index, index);
+#endif
   __ movq(compiler::Address(instr->base_reg(), index, TIMES_4, instr->offset()),
           value);
 
@@ -656,6 +675,24 @@
   return summary;
 }
 
+void AssertBooleanInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  ASSERT(locs()->always_calls());
+
+  auto object_store = compiler->isolate_group()->object_store();
+  const auto& assert_boolean_stub =
+      Code::ZoneHandle(compiler->zone(), object_store->assert_boolean_stub());
+
+  compiler::Label done;
+  __ testq(
+      AssertBooleanABI::kObjectReg,
+      compiler::Immediate(compiler::target::ObjectAlignment::kBoolVsNullMask));
+  __ j(NOT_ZERO, &done, compiler::Assembler::kNearJump);
+  compiler->GenerateStubCall(source(), assert_boolean_stub,
+                             /*kind=*/UntaggedPcDescriptors::kOther, locs(),
+                             deopt_id());
+  __ Bind(&done);
+}
+
 static Condition TokenKindToIntCondition(Token::Kind kind) {
   switch (kind) {
     case Token::kEQ:
@@ -692,13 +729,18 @@
     const intptr_t kNumTemps = 0;
     LocationSummary* locs = new (zone)
         LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
-    locs->set_in(0, LocationRegisterOrConstant(left()));
-    // Only one input can be a constant operand. The case of two constant
-    // operands should be handled by constant propagation.
-    // Only right can be a stack slot.
-    locs->set_in(1, locs->in(0).IsConstant()
-                        ? Location::RequiresRegister()
-                        : LocationRegisterOrConstant(right()));
+    if (is_null_aware()) {
+      locs->set_in(0, Location::RequiresRegister());
+      locs->set_in(1, Location::RequiresRegister());
+    } else {
+      locs->set_in(0, LocationRegisterOrConstant(left()));
+      // Only one input can be a constant operand. The case of two constant
+      // operands should be handled by constant propagation.
+      // Only right can be a stack slot.
+      locs->set_in(1, locs->in(0).IsConstant()
+                          ? Location::RequiresRegister()
+                          : LocationRegisterOrConstant(right()));
+    }
     locs->set_out(0, Location::RequiresRegister());
     return locs;
   }
@@ -752,24 +794,65 @@
   }
 }
 
-static void EmitBranchOnCondition(FlowGraphCompiler* compiler,
-                                  Condition true_condition,
-                                  BranchLabels labels) {
+static void EmitBranchOnCondition(
+    FlowGraphCompiler* compiler,
+    Condition true_condition,
+    BranchLabels labels,
+    compiler::Assembler::JumpDistance jump_distance =
+        compiler::Assembler::kFarJump) {
   if (labels.fall_through == labels.false_label) {
     // If the next block is the false successor, fall through to it.
-    __ j(true_condition, labels.true_label);
+    __ j(true_condition, labels.true_label, jump_distance);
   } else {
     // If the next block is not the false successor, branch to it.
     Condition false_condition = InvertCondition(true_condition);
-    __ j(false_condition, labels.false_label);
+    __ j(false_condition, labels.false_label, jump_distance);
 
     // Fall through or jump to the true successor.
     if (labels.fall_through != labels.true_label) {
-      __ jmp(labels.true_label);
+      __ jmp(labels.true_label, jump_distance);
     }
   }
 }
 
+static Condition EmitSmiComparisonOp(FlowGraphCompiler* compiler,
+                                     const LocationSummary& locs,
+                                     Token::Kind kind) {
+  Location left = locs.in(0);
+  Location right = locs.in(1);
+  ASSERT(!left.IsConstant() || !right.IsConstant());
+
+  Condition true_condition = TokenKindToIntCondition(kind);
+  if (left.IsConstant() || right.IsConstant()) {
+    // Ensure constant is on the right.
+    ConstantInstr* constant = NULL;
+    if (left.IsConstant()) {
+      constant = left.constant_instruction();
+      Location tmp = right;
+      right = left;
+      left = tmp;
+      true_condition = FlipCondition(true_condition);
+    } else {
+      constant = right.constant_instruction();
+    }
+
+    if (RepresentationUtils::IsUnboxedInteger(constant->representation())) {
+      int64_t value;
+      const bool ok = compiler::HasIntegerValue(constant->value(), &value);
+      RELEASE_ASSERT(ok);
+      __ OBJ(cmp)(left.reg(), compiler::Immediate(value));
+    } else {
+      ASSERT(constant->representation() == kTagged);
+      __ CompareObject(left.reg(), right.constant());
+    }
+  } else if (right.IsStackSlot()) {
+    __ OBJ(cmp)(left.reg(), LocationToStackSlotAddress(right));
+  } else {
+    __ OBJ(cmp)(left.reg(), right.reg());
+  }
+  return true_condition;
+}
+
 static Condition EmitInt64ComparisonOp(FlowGraphCompiler* compiler,
                                        const LocationSummary& locs,
                                        Token::Kind kind) {
@@ -797,8 +880,7 @@
       RELEASE_ASSERT(ok);
       __ cmpq(left.reg(), compiler::Immediate(value));
     } else {
-      ASSERT(constant->representation() == kTagged);
-      __ CompareObject(left.reg(), right.constant());
+      UNREACHABLE();
     }
   } else if (right.IsStackSlot()) {
     __ cmpq(left.reg(), LocationToStackSlotAddress(right));
@@ -808,6 +890,35 @@
   return true_condition;
 }
 
+static Condition EmitNullAwareInt64ComparisonOp(FlowGraphCompiler* compiler,
+                                                const LocationSummary& locs,
+                                                Token::Kind kind,
+                                                BranchLabels labels) {
+  ASSERT((kind == Token::kEQ) || (kind == Token::kNE));
+  const Register left = locs.in(0).reg();
+  const Register right = locs.in(1).reg();
+  const Condition true_condition = TokenKindToIntCondition(kind);
+  compiler::Label* equal_result =
+      (true_condition == EQUAL) ? labels.true_label : labels.false_label;
+  compiler::Label* not_equal_result =
+      (true_condition == EQUAL) ? labels.false_label : labels.true_label;
+
+  // Check if operands have the same value. If they don't, then they could
+  // be equal only if both of them are Mints with the same value.
+  __ OBJ(cmp)(left, right);
+  __ j(EQUAL, equal_result);
+  __ OBJ(mov)(TMP, left);
+  __ OBJ(and)(TMP, right);
+  __ BranchIfSmi(TMP, not_equal_result);
+  __ CompareClassId(left, kMintCid);
+  __ j(NOT_EQUAL, not_equal_result);
+  __ CompareClassId(right, kMintCid);
+  __ j(NOT_EQUAL, not_equal_result);
+  __ movq(TMP, compiler::FieldAddress(left, Mint::value_offset()));
+  __ cmpq(TMP, compiler::FieldAddress(right, Mint::value_offset()));
+  return true_condition;
+}
+
 static Condition TokenKindToDoubleCondition(Token::Kind kind) {
   switch (kind) {
     case Token::kEQ:
@@ -846,7 +957,13 @@
 
 Condition EqualityCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
                                                    BranchLabels labels) {
-  if ((operation_cid() == kSmiCid) || (operation_cid() == kMintCid)) {
+  if (is_null_aware()) {
+    ASSERT(operation_cid() == kMintCid);
+    return EmitNullAwareInt64ComparisonOp(compiler, *locs(), kind(), labels);
+  }
+  if (operation_cid() == kSmiCid) {
+    return EmitSmiComparisonOp(compiler, *locs(), kind());
+  } else if (operation_cid() == kMintCid) {
     return EmitInt64ComparisonOp(compiler, *locs(), kind());
   } else {
     ASSERT(operation_cid() == kDoubleCid);
@@ -858,15 +975,19 @@
   compiler::Label is_true, is_false;
   BranchLabels labels = {&is_true, &is_false, &is_false};
   Condition true_condition = EmitComparisonCode(compiler, labels);
-  if (true_condition != kInvalidCondition) {
-    EmitBranchOnCondition(compiler, true_condition, labels);
-  }
 
   Register result = locs()->out(0).reg();
+  if (true_condition != kInvalidCondition) {
+    EmitBranchOnCondition(compiler, true_condition, labels,
+                          compiler::Assembler::kNearJump);
+  }
+  // Note: We use branches instead of setcc or cmov even when the branch labels
+  // are otherwise unused, as this runs faster for the x86 processors tested on
+  // our benchmarking server.
   compiler::Label done;
   __ Bind(&is_false);
   __ LoadObject(result, Bool::False());
-  __ jmp(&done);
+  __ jmp(&done, compiler::Assembler::kNearJump);
   __ Bind(&is_true);
   __ LoadObject(result, Bool::True());
   __ Bind(&done);
@@ -900,9 +1021,10 @@
   if (right.IsConstant()) {
     ASSERT(right.constant().IsSmi());
     const int64_t imm = static_cast<int64_t>(right.constant().ptr());
-    __ TestImmediate(left_reg, compiler::Immediate(imm));
+    __ TestImmediate(left_reg, compiler::Immediate(imm),
+                     compiler::kObjectBytes);
   } else {
-    __ testq(left_reg, right.reg());
+    __ OBJ(test)(left_reg, right.reg());
   }
   Condition true_condition = (kind() == Token::kNE) ? NOT_ZERO : ZERO;
   return true_condition;
@@ -993,7 +1115,9 @@
 
 Condition RelationalOpInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
                                                 BranchLabels labels) {
-  if (operation_cid() == kSmiCid || operation_cid() == kMintCid) {
+  if (operation_cid() == kSmiCid) {
+    return EmitSmiComparisonOp(compiler, *locs(), kind());
+  } else if (operation_cid() == kMintCid) {
     return EmitInt64ComparisonOp(compiler, *locs(), kind());
   } else {
     ASSERT(operation_cid() == kDoubleCid);
@@ -1267,6 +1391,15 @@
   Register char_code = locs()->in(0).reg();
   Register result = locs()->out(0).reg();
 
+#if defined(DART_COMPRESSED_POINTERS)
+  // The upper half of a compressed Smi contains undefined bits, but no x64
+  // addressing mode will ignore these bits. Assume that the index is
+  // non-negative and clear the upper bits, which is shorter than
+  // sign-extension (movsxd). Note: we don't bother to ensure index is a
+  // writable input because any other instructions using it must also not
+  // rely on the upper bits.
+  __ orl(char_code, char_code);
+#endif
   __ movq(result,
           compiler::Address(THR, Thread::predefined_symbols_address_offset()));
   __ movq(result,
@@ -1287,7 +1420,8 @@
   Register str = locs()->in(0).reg();
   Register result = locs()->out(0).reg();
   compiler::Label is_one, done;
-  __ movq(result, compiler::FieldAddress(str, String::length_offset()));
+  __ LoadCompressedSmi(result,
+                       compiler::FieldAddress(str, String::length_offset()));
   __ cmpq(result, compiler::Immediate(Smi::RawValue(1)));
   __ j(EQUAL, &is_one, compiler::Assembler::kNearJump);
   __ movq(result, compiler::Immediate(Smi::RawValue(-1)));
@@ -1597,7 +1731,7 @@
       LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
   locs->set_in(0, Location::RequiresRegister());
   // For tagged index with index_scale=1 as well as untagged index with
-  // index_scale=16 we need a writable register due to assdressing mode
+  // index_scale=16 we need a writable register due to addressing mode
   // restrictions on X64.
   const bool need_writable_index_register =
       (index_scale() == 1 && !index_unboxed_) ||
@@ -1631,6 +1765,16 @@
       // X64 does not support addressing mode using TIMES_16.
       __ SmiTag(index.reg());
       index_scale >>= 1;
+    } else if (!index_unboxed_) {
+#if defined(DART_COMPRESSED_POINTERS)
+      // The upper half of a compressed Smi contains undefined bits, but no x64
+      // addressing mode will ignore these bits. Assume that the index is
+      // non-negative and clear the upper bits, which is shorter than
+      // sign-extension (movsxd). Note: we don't bother to ensure index is a
+      // writable input because any other instructions using it must also not
+      // rely on the upper bits.
+      __ orl(index.reg(), index.reg());
+#endif
     }
   } else {
     ASSERT(index.IsConstant());
@@ -1737,6 +1881,16 @@
 
   if ((index_scale() == 1)) {
     __ SmiUntag(index.reg());
+  } else {
+#if defined(DART_COMPRESSED_POINTERS)
+    // The upper half of a compressed Smi contains undefined bits, but no x64
+    // addressing mode will ignore these bits. Assume that the index is
+    // non-negative and clear the upper bits, which is shorter than
+    // sign-extension (movsxd). Note: we don't bother to ensure index is a
+    // writable input because any other instructions using it must also not
+    // rely on the upper bits.
+    __ orl(index.reg(), index.reg());
+#endif
   }
   Register result = locs()->out(0).reg();
   switch (class_id()) {
@@ -1834,7 +1988,7 @@
       LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
   locs->set_in(0, Location::RequiresRegister());
   // For tagged index with index_scale=1 as well as untagged index with
-  // index_scale=16 we need a writable register due to assdressing mode
+  // index_scale=16 we need a writable register due to addressing mode
   // restrictions on X64.
   const bool need_writable_index_register =
       (index_scale() == 1 && !index_unboxed_) ||
@@ -1906,6 +2060,16 @@
       // X64 does not support addressing mode using TIMES_16.
       __ SmiTag(index.reg());
       index_scale >>= 1;
+    } else if (!index_unboxed_) {
+#if defined(DART_COMPRESSED_POINTERS)
+      // The upper half of a compressed Smi contains undefined bits, but no x64
+      // addressing mode will ignore these bits. Assume that the index is
+      // non-negative and clear the upper bits, which is shorter than
+      // sign-extension (movsxd). Note: we don't bother to ensure index is a
+      // writable input because any other instructions using it must also not
+      // rely on the upper bits.
+      __ orl(index.reg(), index.reg());
+#endif
     }
   } else {
     ASSERT(index.IsConstant());
@@ -2227,8 +2391,9 @@
         offset_reg,
         compiler::FieldAddress(
             field_reg, Field::guarded_list_length_in_object_offset_offset()));
-    __ movq(length_reg, compiler::FieldAddress(
-                            field_reg, Field::guarded_list_length_offset()));
+    __ LoadCompressed(
+        length_reg,
+        compiler::FieldAddress(field_reg, Field::guarded_list_length_offset()));
 
     __ cmpq(offset_reg, compiler::Immediate(0));
     __ j(NEGATIVE, &ok);
@@ -2237,7 +2402,8 @@
     // value's class matches guarded class id of the field.
     // offset_reg contains offset already corrected by -kHeapObjectTag that is
     // why we use Address instead of FieldAddress.
-    __ cmpq(length_reg, compiler::Address(value_reg, offset_reg, TIMES_1, 0));
+    __ OBJ(cmp)(length_reg,
+                compiler::Address(value_reg, offset_reg, TIMES_1, 0));
 
     if (deopt == NULL) {
       __ j(EQUAL, &ok);
@@ -2580,21 +2746,40 @@
     __ Bind(&store_pointer);
   }
 
+  const bool compressed = slot().is_compressed();
   if (ShouldEmitStoreBarrier()) {
     Register value_reg = locs()->in(1).reg();
-    __ StoreIntoObject(instance_reg,
-                       compiler::FieldAddress(instance_reg, offset_in_bytes),
-                       value_reg, CanValueBeSmi());
+    if (!compressed) {
+      __ StoreIntoObject(instance_reg,
+                         compiler::FieldAddress(instance_reg, offset_in_bytes),
+                         value_reg, CanValueBeSmi());
+    } else {
+      __ StoreCompressedIntoObject(
+          instance_reg, compiler::FieldAddress(instance_reg, offset_in_bytes),
+          value_reg, CanValueBeSmi());
+    }
   } else {
     if (locs()->in(1).IsConstant()) {
-      __ StoreIntoObjectNoBarrier(
-          instance_reg, compiler::FieldAddress(instance_reg, offset_in_bytes),
-          locs()->in(1).constant());
+      if (!compressed) {
+        __ StoreIntoObjectNoBarrier(
+            instance_reg, compiler::FieldAddress(instance_reg, offset_in_bytes),
+            locs()->in(1).constant());
+      } else {
+        __ StoreCompressedIntoObjectNoBarrier(
+            instance_reg, compiler::FieldAddress(instance_reg, offset_in_bytes),
+            locs()->in(1).constant());
+      }
     } else {
       Register value_reg = locs()->in(1).reg();
-      __ StoreIntoObjectNoBarrier(
-          instance_reg, compiler::FieldAddress(instance_reg, offset_in_bytes),
-          value_reg);
+      if (!compressed) {
+        __ StoreIntoObjectNoBarrier(
+            instance_reg, compiler::FieldAddress(instance_reg, offset_in_bytes),
+            value_reg);
+      } else {
+        __ StoreCompressedIntoObjectNoBarrier(
+            instance_reg, compiler::FieldAddress(instance_reg, offset_in_bytes),
+            value_reg);
+      }
     }
   }
   __ Bind(&skip_store);
@@ -2735,12 +2920,15 @@
   ASSERT(locs()->in(1).reg() == kLengthReg);
 
   compiler::Label slow_path, done;
-  if (compiler->is_optimizing() && !FLAG_precompiled_mode &&
-      num_elements()->BindsToConstant() &&
-      num_elements()->BoundConstant().IsSmi()) {
-    const intptr_t length = Smi::Cast(num_elements()->BoundConstant()).Value();
-    if (Array::IsValidLength(length)) {
-      InlineArrayAllocation(compiler, length, &slow_path, &done);
+  if (!FLAG_use_slow_path && FLAG_inline_alloc) {
+    if (compiler->is_optimizing() && !FLAG_precompiled_mode &&
+        num_elements()->BindsToConstant() &&
+        num_elements()->BoundConstant().IsSmi()) {
+      const intptr_t length =
+          Smi::Cast(num_elements()->BoundConstant()).Value();
+      if (Array::IsValidLength(length)) {
+        InlineArrayAllocation(compiler, length, &slow_path, &done);
+      }
     }
   }
 
@@ -2980,7 +3168,12 @@
     __ Bind(&load_pointer);
   }
 
-  __ movq(result, compiler::FieldAddress(instance_reg, OffsetInBytes()));
+  if (slot().is_compressed()) {
+    __ LoadCompressed(result,
+                      compiler::FieldAddress(instance_reg, OffsetInBytes()));
+  } else {
+    __ movq(result, compiler::FieldAddress(instance_reg, OffsetInBytes()));
+  }
 
   if (calls_initializer()) {
     EmitNativeCodeForInitializerCall(compiler);
@@ -2989,104 +3182,6 @@
   __ Bind(&done);
 }
 
-LocationSummary* InstantiateTypeInstr::MakeLocationSummary(Zone* zone,
-                                                           bool opt) const {
-  const intptr_t kNumInputs = 2;
-  const intptr_t kNumTemps = 0;
-  LocationSummary* locs = new (zone)
-      LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
-  locs->set_in(0, Location::RegisterLocation(
-                      InstantiationABI::kInstantiatorTypeArgumentsReg));
-  locs->set_in(1, Location::RegisterLocation(
-                      InstantiationABI::kFunctionTypeArgumentsReg));
-  locs->set_out(0,
-                Location::RegisterLocation(InstantiationABI::kResultTypeReg));
-  return locs;
-}
-
-void InstantiateTypeInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  Register instantiator_type_args_reg = locs()->in(0).reg();
-  Register function_type_args_reg = locs()->in(1).reg();
-  Register result_reg = locs()->out(0).reg();
-
-  // 'instantiator_type_args_reg' is a TypeArguments object (or null).
-  // 'function_type_args_reg' is a TypeArguments object (or null).
-  // A runtime call to instantiate the type is required.
-  __ PushObject(Object::null_object());  // Make room for the result.
-  __ PushObject(type());
-  __ pushq(instantiator_type_args_reg);  // Push instantiator type arguments.
-  __ pushq(function_type_args_reg);      // Push function type arguments.
-  compiler->GenerateRuntimeCall(source(), deopt_id(),
-                                kInstantiateTypeRuntimeEntry, 3, locs());
-  __ Drop(3);           // Drop 2 type vectors, and uninstantiated type.
-  __ popq(result_reg);  // Pop instantiated type.
-}
-
-LocationSummary* InstantiateTypeArgumentsInstr::MakeLocationSummary(
-    Zone* zone,
-    bool opt) const {
-  const intptr_t kNumInputs = 3;
-  const intptr_t kNumTemps = 0;
-  LocationSummary* locs = new (zone)
-      LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
-  locs->set_in(0, Location::RegisterLocation(
-                      InstantiationABI::kInstantiatorTypeArgumentsReg));
-  locs->set_in(1, Location::RegisterLocation(
-                      InstantiationABI::kFunctionTypeArgumentsReg));
-  locs->set_in(2, Location::RegisterLocation(
-                      InstantiationABI::kUninstantiatedTypeArgumentsReg));
-  locs->set_out(
-      0, Location::RegisterLocation(InstantiationABI::kResultTypeArgumentsReg));
-  return locs;
-}
-
-void InstantiateTypeArgumentsInstr::EmitNativeCode(
-    FlowGraphCompiler* compiler) {
-  // We should never try and instantiate a TAV known at compile time to be null,
-  // so we can use a null value below for the dynamic case.
-  ASSERT(!type_arguments()->BindsToConstant() ||
-         !type_arguments()->BoundConstant().IsNull());
-  const auto& type_args =
-      type_arguments()->BindsToConstant()
-          ? TypeArguments::Cast(type_arguments()->BoundConstant())
-          : Object::null_type_arguments();
-  const intptr_t len = type_args.Length();
-  const bool can_function_type_args_be_null =
-      function_type_arguments()->CanBe(Object::null_object());
-
-  compiler::Label type_arguments_instantiated;
-  if (type_args.IsNull()) {
-    // Currently we only create dynamic InstantiateTypeArguments instructions
-    // in cases where we know the type argument is uninstantiated at runtime,
-    // so there are no extra checks needed to call the stub successfully.
-  } else if (type_args.IsRawWhenInstantiatedFromRaw(len) &&
-             can_function_type_args_be_null) {
-    // If both the instantiator and function type arguments are null and if the
-    // type argument vector instantiated from null becomes a vector of dynamic,
-    // then use null as the type arguments.
-    compiler::Label non_null_type_args;
-    // 'instantiator_type_args_reg' is a TypeArguments object (or null).
-    // 'function_type_args_reg' is a TypeArguments object (or null).
-    const Register instantiator_type_args_reg = locs()->in(0).reg();
-    const Register function_type_args_reg = locs()->in(1).reg();
-    const Register result_reg = locs()->out(0).reg();
-    ASSERT(result_reg != instantiator_type_args_reg &&
-           result_reg != function_type_args_reg);
-    __ LoadObject(result_reg, Object::null_object());
-    __ cmpq(instantiator_type_args_reg, result_reg);
-    if (!function_type_arguments()->BindsToConstant()) {
-      __ j(NOT_EQUAL, &non_null_type_args, compiler::Assembler::kNearJump);
-      __ cmpq(function_type_args_reg, result_reg);
-    }
-    __ j(EQUAL, &type_arguments_instantiated, compiler::Assembler::kNearJump);
-    __ Bind(&non_null_type_args);
-  }
-  // Lookup cache in stub before calling runtime.
-  compiler->GenerateStubCall(source(), GetStub(), UntaggedPcDescriptors::kOther,
-                             locs());
-  __ Bind(&type_arguments_instantiated);
-}
-
 LocationSummary* AllocateUninitializedContextInstr::MakeLocationSummary(
     Zone* zone,
     bool opt) const {
@@ -3117,6 +3212,10 @@
 
     compiler->SaveLiveRegisters(locs);
 
+    auto slow_path_env = compiler->SlowPathEnvironmentFor(
+        instruction(), /*num_slow_path_args=*/0);
+    ASSERT(slow_path_env != nullptr);
+
     auto object_store = compiler->isolate_group()->object_store();
     const auto& allocate_context_stub = Code::ZoneHandle(
         compiler->zone(), object_store->allocate_context_stub());
@@ -3124,8 +3223,10 @@
     __ LoadImmediate(
         R10, compiler::Immediate(instruction()->num_context_variables()));
     compiler->GenerateStubCall(instruction()->source(), allocate_context_stub,
-                               UntaggedPcDescriptors::kOther, locs);
+                               UntaggedPcDescriptors::kOther, locs,
+                               instruction()->deopt_id(), slow_path_env);
     ASSERT(instruction()->locs()->out(0).reg() == RAX);
+
     compiler->RestoreLiveRegisters(instruction()->locs());
     __ jmp(exit_label());
   }
@@ -3141,15 +3242,19 @@
   compiler->AddSlowPathCode(slow_path);
   intptr_t instance_size = Context::InstanceSize(num_context_variables());
 
-  __ TryAllocateArray(kContextCid, instance_size, slow_path->entry_label(),
-                      compiler::Assembler::kFarJump,
-                      result,  // instance
-                      temp,    // end address
-                      locs()->temp(1).reg());
+  if (!FLAG_use_slow_path && FLAG_inline_alloc) {
+    __ TryAllocateArray(kContextCid, instance_size, slow_path->entry_label(),
+                        compiler::Assembler::kFarJump,
+                        result,  // instance
+                        temp,    // end address
+                        locs()->temp(1).reg());
 
-  // Setup up number of context variables field.
-  __ movq(compiler::FieldAddress(result, Context::num_variables_offset()),
-          compiler::Immediate(num_context_variables()));
+    // Setup up number of context variables field.
+    __ movq(compiler::FieldAddress(result, Context::num_variables_offset()),
+            compiler::Immediate(num_context_variables()));
+  } else {
+    __ Jump(slow_path->entry_label());
+  }
 
   __ Bind(slow_path->exit_label());
 }
@@ -3175,7 +3280,7 @@
 
   __ LoadImmediate(R10, compiler::Immediate(num_context_variables()));
   compiler->GenerateStubCall(source(), allocate_context_stub,
-                             UntaggedPcDescriptors::kOther, locs());
+                             UntaggedPcDescriptors::kOther, locs(), deopt_id());
 }
 
 LocationSummary* CloneContextInstr::MakeLocationSummary(Zone* zone,
@@ -3197,7 +3302,8 @@
   const auto& clone_context_stub =
       Code::ZoneHandle(compiler->zone(), object_store->clone_context_stub());
   compiler->GenerateStubCall(source(), clone_context_stub,
-                             /*kind=*/UntaggedPcDescriptors::kOther, locs());
+                             /*kind=*/UntaggedPcDescriptors::kOther, locs(),
+                             deopt_id());
 }
 
 LocationSummary* CatchBlockEntryInstr::MakeLocationSummary(Zone* zone,
@@ -3384,37 +3490,20 @@
     if (shift_left->can_overflow()) {
       if (value == 1) {
         // Use overflow flag.
-#if !defined(DART_COMPRESSED_POINTERS)
-        __ shlq(left, compiler::Immediate(1));
+        __ OBJ(shl)(left, compiler::Immediate(1));
         __ j(OVERFLOW, deopt);
-#else
-        __ shll(left, compiler::Immediate(1));
-        __ j(OVERFLOW, deopt);
-        __ movsxd(left, left);
-#endif
         return;
       }
       // Check for overflow.
       Register temp = locs.temp(0).reg();
-      __ movq(temp, left);
-#if !defined(DART_COMPRESSED_POINTERS)
-      __ shlq(left, compiler::Immediate(value));
-      __ sarq(left, compiler::Immediate(value));
-#else
-      __ shll(left, compiler::Immediate(value));
-      __ sarl(left, compiler::Immediate(value));
-      __ movsxd(left, left);
-#endif
-      __ cmpq(left, temp);
+      __ OBJ(mov)(temp, left);
+      __ OBJ(shl)(left, compiler::Immediate(value));
+      __ OBJ(sar)(left, compiler::Immediate(value));
+      __ OBJ(cmp)(left, temp);
       __ j(NOT_EQUAL, deopt);  // Overflow.
     }
     // Shift for result now we know there is no overflow.
-    __ shlq(left, compiler::Immediate(value));
-#if defined(DART_COMPRESSED_POINTERS)
-    if (shift_left->is_truncating()) {
-      __ movsxd(left, left);
-    }
-#endif
+    __ OBJ(shl)(left, compiler::Immediate(value));
     return;
   }
 
@@ -3428,7 +3517,8 @@
     if (obj.IsSmi()) {
       const intptr_t left_int = Smi::Cast(obj).Value();
       if (left_int == 0) {
-        __ CompareImmediate(right, compiler::Immediate(0));
+        __ CompareImmediate(right, compiler::Immediate(0),
+                            compiler::kObjectBytes);
         __ j(NEGATIVE, deopt);
         return;
       }
@@ -3436,20 +3526,11 @@
       const bool right_needs_check =
           !RangeUtils::IsWithin(right_range, 0, max_right - 1);
       if (right_needs_check) {
-        __ CompareImmediate(
-            right,
-            compiler::Immediate(static_cast<int64_t>(Smi::New(max_right))));
+        __ CompareObject(right, Smi::ZoneHandle(Smi::New(max_right)));
         __ j(ABOVE_EQUAL, deopt);
       }
       __ SmiUntag(right);
-      __ shlq(left, right);
-#if defined(DART_COMPRESSED_POINTERS)
-      if (shift_left->is_truncating()) {
-        __ movsxd(left, left);
-      }
-#endif
-    } else {
-      __ int3();  //???
+      __ OBJ(shl)(left, right);
     }
     return;
   }
@@ -3463,418 +3544,45 @@
           (right_range == NULL) || !right_range->IsPositive();
       if (right_may_be_negative) {
         ASSERT(shift_left->CanDeoptimize());
-        __ CompareImmediate(right, compiler::Immediate(0));
+        __ CompareImmediate(right, compiler::Immediate(0),
+                            compiler::kObjectBytes);
         __ j(NEGATIVE, deopt);
       }
       compiler::Label done, is_not_zero;
-      __ CompareImmediate(
-          right,
-          compiler::Immediate(static_cast<int64_t>(Smi::New(Smi::kBits))));
+      __ CompareObject(right, Smi::ZoneHandle(Smi::New(Smi::kBits)));
       __ j(BELOW, &is_not_zero, compiler::Assembler::kNearJump);
       __ xorq(left, left);
       __ jmp(&done, compiler::Assembler::kNearJump);
       __ Bind(&is_not_zero);
       __ SmiUntag(right);
-      __ shlq(left, right);
+      __ OBJ(shl)(left, right);
       __ Bind(&done);
     } else {
       __ SmiUntag(right);
-      __ shlq(left, right);
+      __ OBJ(shl)(left, right);
     }
-#if defined(DART_COMPRESSED_POINTERS)
-    if (shift_left->is_truncating()) {
-      __ movsxd(left, left);
-    }
-#endif
   } else {
     if (right_needs_check) {
       ASSERT(shift_left->CanDeoptimize());
-      __ CompareImmediate(
-          right,
-          compiler::Immediate(static_cast<int64_t>(Smi::New(Smi::kBits))));
+      __ CompareObject(right, Smi::ZoneHandle(Smi::New(Smi::kBits)));
       __ j(ABOVE_EQUAL, deopt);
     }
     // Left is not a constant.
     Register temp = locs.temp(0).reg();
     // Check if count too large for handling it inlined.
-#if !defined(DART_COMPRESSED_POINTERS)
-    __ movq(temp, left);
-#else
-    __ movl(temp, left);
-#endif
+    __ OBJ(mov)(temp, left);
     __ SmiUntag(right);
     // Overflow test (preserve temp and right);
-#if !defined(DART_COMPRESSED_POINTERS)
-    __ shlq(left, right);
-    __ sarq(left, right);
-    __ cmpq(left, temp);
-#else
-    __ shll(temp, right);
-    __ sarl(temp, right);
-    __ cmpl(temp, left);
-#endif
+    __ OBJ(shl)(left, right);
+    __ OBJ(sar)(left, right);
+    __ OBJ(cmp)(left, temp);
     __ j(NOT_EQUAL, deopt);  // Overflow.
     // Shift for result now we know there is no overflow.
-    __ shlq(left, right);
+    __ OBJ(shl)(left, right);
     ASSERT(!shift_left->is_truncating());
   }
 }
 
-class CheckedSmiSlowPath : public TemplateSlowPathCode<CheckedSmiOpInstr> {
- public:
-  CheckedSmiSlowPath(CheckedSmiOpInstr* instruction, intptr_t try_index)
-      : TemplateSlowPathCode(instruction), try_index_(try_index) {}
-
-  static constexpr intptr_t kNumSlowPathArgs = 2;
-
-  virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
-    if (compiler::Assembler::EmittingComments()) {
-      __ Comment("slow path smi operation");
-    }
-    __ Bind(entry_label());
-    LocationSummary* locs = instruction()->locs();
-    Register result = locs->out(0).reg();
-    locs->live_registers()->Remove(Location::RegisterLocation(result));
-
-    compiler->SaveLiveRegisters(locs);
-    if (instruction()->env() != NULL) {
-      Environment* env =
-          compiler->SlowPathEnvironmentFor(instruction(), kNumSlowPathArgs);
-      compiler->pending_deoptimization_env_ = env;
-    }
-    __ pushq(locs->in(0).reg());
-    __ pushq(locs->in(1).reg());
-    const auto& selector = String::Handle(instruction()->call()->Selector());
-    const auto& arguments_descriptor =
-        Array::Handle(ArgumentsDescriptor::NewBoxed(
-            /*type_args_len=*/0, /*num_arguments=*/2));
-    compiler->EmitMegamorphicInstanceCall(
-        selector, arguments_descriptor, instruction()->call()->deopt_id(),
-        instruction()->source(), locs, try_index_, kNumSlowPathArgs);
-    __ MoveRegister(result, RAX);
-    compiler->RestoreLiveRegisters(locs);
-    __ jmp(exit_label());
-    compiler->pending_deoptimization_env_ = NULL;
-  }
-
- private:
-  intptr_t try_index_;
-};
-
-LocationSummary* CheckedSmiOpInstr::MakeLocationSummary(Zone* zone,
-                                                        bool opt) const {
-  bool is_shift = (op_kind() == Token::kSHL) || (op_kind() == Token::kSHR) ||
-                  (op_kind() == Token::kUSHR);
-  const intptr_t kNumInputs = 2;
-  const intptr_t kNumTemps = is_shift ? 1 : 0;
-  LocationSummary* summary = new (zone) LocationSummary(
-      zone, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath);
-  summary->set_in(0, Location::RequiresRegister());
-  summary->set_in(1, Location::RequiresRegister());
-  switch (op_kind()) {
-    case Token::kADD:
-    case Token::kSUB:
-    case Token::kMUL:
-    case Token::kSHL:
-    case Token::kSHR:
-    case Token::kUSHR:
-      summary->set_out(0, Location::RequiresRegister());
-      break;
-    case Token::kBIT_OR:
-    case Token::kBIT_AND:
-    case Token::kBIT_XOR:
-      summary->set_out(0, Location::SameAsFirstInput());
-      break;
-    default:
-      UNIMPLEMENTED();
-  }
-  if (is_shift) {
-    summary->set_temp(0, Location::RegisterLocation(RCX));
-  }
-  return summary;
-}
-
-void CheckedSmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  CheckedSmiSlowPath* slow_path =
-      new CheckedSmiSlowPath(this, compiler->CurrentTryIndex());
-  compiler->AddSlowPathCode(slow_path);
-  // Test operands if necessary.
-
-  intptr_t left_cid = left()->Type()->ToCid();
-  intptr_t right_cid = right()->Type()->ToCid();
-  Register left = locs()->in(0).reg();
-  Register right = locs()->in(1).reg();
-  if (this->left()->definition() == this->right()->definition()) {
-    __ testq(left, compiler::Immediate(kSmiTagMask));
-  } else if (left_cid == kSmiCid) {
-    __ testq(right, compiler::Immediate(kSmiTagMask));
-  } else if (right_cid == kSmiCid) {
-    __ testq(left, compiler::Immediate(kSmiTagMask));
-  } else {
-    __ movq(TMP, left);
-    __ orq(TMP, right);
-    __ testq(TMP, compiler::Immediate(kSmiTagMask));
-  }
-  __ j(NOT_ZERO, slow_path->entry_label());
-  Register result = locs()->out(0).reg();
-  switch (op_kind()) {
-    case Token::kADD:
-      __ movq(result, left);
-#if !defined(DART_COMPRESSED_POINTERS)
-      __ addq(result, right);
-      __ j(OVERFLOW, slow_path->entry_label());
-#else
-      __ addl(result, right);
-      __ j(OVERFLOW, slow_path->entry_label());
-      __ movsxd(result, result);
-#endif
-      break;
-    case Token::kSUB:
-      __ movq(result, left);
-#if !defined(DART_COMPRESSED_POINTERS)
-      __ subq(result, right);
-      __ j(OVERFLOW, slow_path->entry_label());
-#else
-      __ subl(result, right);
-      __ j(OVERFLOW, slow_path->entry_label());
-      __ movsxd(result, result);
-#endif
-      break;
-    case Token::kMUL:
-      __ movq(result, left);
-      __ SmiUntag(result);
-#if !defined(DART_COMPRESSED_POINTERS)
-      __ imulq(result, right);
-      __ j(OVERFLOW, slow_path->entry_label());
-#else
-      __ imull(result, right);
-      __ j(OVERFLOW, slow_path->entry_label());
-      __ movsxd(result, result);
-#endif
-      break;
-    case Token::kBIT_OR:
-      ASSERT(left == result);
-      __ orq(result, right);
-      break;
-    case Token::kBIT_AND:
-      ASSERT(left == result);
-      __ andq(result, right);
-      break;
-    case Token::kBIT_XOR:
-      ASSERT(left == result);
-      __ xorq(result, right);
-      break;
-    case Token::kSHL:
-      ASSERT(result != right);
-      ASSERT(locs()->temp(0).reg() == RCX);
-      __ cmpq(right, compiler::Immediate(Smi::RawValue(Smi::kBits)));
-      __ j(ABOVE_EQUAL, slow_path->entry_label());
-
-      __ movq(RCX, right);
-      __ SmiUntag(RCX);
-      __ movq(result, left);
-#if !defined(DART_COMPRESSED_POINTERS)
-      __ shlq(result, RCX);
-      __ movq(TMP, result);
-      __ sarq(TMP, RCX);
-      __ cmpq(TMP, left);
-      __ j(NOT_EQUAL, slow_path->entry_label());
-#else
-      __ shll(result, RCX);
-      __ movq(TMP, result);
-      __ sarl(TMP, RCX);
-      __ cmpl(TMP, left);
-      __ j(NOT_EQUAL, slow_path->entry_label());
-      __ movsxd(result, result);
-#endif
-      break;
-    case Token::kSHR:
-    case Token::kUSHR: {
-      compiler::Label shift_count_ok;
-      ASSERT(result != right);
-      ASSERT(locs()->temp(0).reg() == RCX);
-      __ cmpq(right, compiler::Immediate(Smi::RawValue(kBitsPerInt64)));
-      __ j(ABOVE_EQUAL, slow_path->entry_label());
-
-      __ movq(RCX, right);
-      __ SmiUntag(RCX);
-      __ movq(result, left);
-      __ SmiUntag(result);
-      if (op_kind() == Token::kSHR) {
-        __ sarq(result, RCX);
-        __ SmiTag(result);
-      } else {
-        ASSERT(op_kind() == Token::kUSHR);
-        __ shrq(result, RCX);
-        __ SmiTag(result);
-        __ j(OVERFLOW, slow_path->entry_label());
-#if defined(DART_COMPRESSED_POINTERS)
-        const Register temp = locs()->temp(0).reg();
-        __ movsxd(temp, result);
-        __ cmpq(temp, result);
-        __ j(NOT_EQUAL, slow_path->entry_label());
-#endif  // defined(DART_COMPRESSED_POINTERS)
-      }
-      break;
-    }
-    default:
-      UNIMPLEMENTED();
-  }
-  __ Bind(slow_path->exit_label());
-}
-
-class CheckedSmiComparisonSlowPath
-    : public TemplateSlowPathCode<CheckedSmiComparisonInstr> {
- public:
-  static constexpr intptr_t kNumSlowPathArgs = 2;
-
-  CheckedSmiComparisonSlowPath(CheckedSmiComparisonInstr* instruction,
-                               Environment* env,
-                               intptr_t try_index,
-                               BranchLabels labels,
-                               bool merged)
-      : TemplateSlowPathCode(instruction),
-        try_index_(try_index),
-        labels_(labels),
-        merged_(merged),
-        env_(env) {
-    // The environment must either come from the comparison or the environment
-    // was cleared from the comparison (and moved to a branch).
-    ASSERT(env == instruction->env() ||
-           (merged && instruction->env() == nullptr));
-  }
-
-  virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
-    if (compiler::Assembler::EmittingComments()) {
-      __ Comment("slow path smi comparison");
-    }
-    __ Bind(entry_label());
-    LocationSummary* locs = instruction()->locs();
-    Register result = merged_ ? locs->temp(0).reg() : locs->out(0).reg();
-    locs->live_registers()->Remove(Location::RegisterLocation(result));
-
-    compiler->SaveLiveRegisters(locs);
-    if (env_ != nullptr) {
-      compiler->pending_deoptimization_env_ =
-          compiler->SlowPathEnvironmentFor(env_, locs, kNumSlowPathArgs);
-    }
-    __ pushq(locs->in(0).reg());
-    __ pushq(locs->in(1).reg());
-
-    const auto& selector = String::Handle(instruction()->call()->Selector());
-    const auto& arguments_descriptor =
-        Array::Handle(ArgumentsDescriptor::NewBoxed(
-            /*type_args_len=*/0, /*num_arguments=*/2));
-
-    compiler->EmitMegamorphicInstanceCall(
-        selector, arguments_descriptor, instruction()->call()->deopt_id(),
-        instruction()->source(), locs, try_index_, kNumSlowPathArgs);
-    __ MoveRegister(result, RAX);
-    compiler->RestoreLiveRegisters(locs);
-    compiler->pending_deoptimization_env_ = nullptr;
-    if (merged_) {
-      __ CompareObject(result, Bool::True());
-      __ j(EQUAL, instruction()->is_negated() ? labels_.false_label
-                                              : labels_.true_label);
-      __ jmp(instruction()->is_negated() ? labels_.true_label
-                                         : labels_.false_label);
-      ASSERT(exit_label()->IsUnused());
-    } else {
-      ASSERT(!instruction()->is_negated());
-      __ jmp(exit_label());
-    }
-  }
-
- private:
-  intptr_t try_index_;
-  BranchLabels labels_;
-  bool merged_;
-  Environment* env_;
-};
-
-LocationSummary* CheckedSmiComparisonInstr::MakeLocationSummary(
-    Zone* zone,
-    bool opt) const {
-  const intptr_t kNumInputs = 2;
-  const intptr_t kNumTemps = 1;
-  LocationSummary* summary = new (zone) LocationSummary(
-      zone, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath);
-  summary->set_in(0, Location::RequiresRegister());
-  summary->set_in(1, Location::RequiresRegister());
-  summary->set_temp(0, Location::RequiresRegister());
-  summary->set_out(0, Location::RequiresRegister());
-  return summary;
-}
-
-Condition CheckedSmiComparisonInstr::EmitComparisonCode(
-    FlowGraphCompiler* compiler,
-    BranchLabels labels) {
-  return EmitInt64ComparisonOp(compiler, *locs(), kind());
-}
-
-#define EMIT_SMI_CHECK                                                         \
-  intptr_t left_cid = left()->Type()->ToCid();                                 \
-  intptr_t right_cid = right()->Type()->ToCid();                               \
-  Register left = locs()->in(0).reg();                                         \
-  Register right = locs()->in(1).reg();                                        \
-  if (this->left()->definition() == this->right()->definition()) {             \
-    __ testq(left, compiler::Immediate(kSmiTagMask));                          \
-  } else if (left_cid == kSmiCid) {                                            \
-    __ testq(right, compiler::Immediate(kSmiTagMask));                         \
-  } else if (right_cid == kSmiCid) {                                           \
-    __ testq(left, compiler::Immediate(kSmiTagMask));                          \
-  } else {                                                                     \
-    __ movq(TMP, left);                                                        \
-    __ orq(TMP, right);                                                        \
-    __ testq(TMP, compiler::Immediate(kSmiTagMask));                           \
-  }                                                                            \
-  __ j(NOT_ZERO, slow_path->entry_label())
-
-void CheckedSmiComparisonInstr::EmitBranchCode(FlowGraphCompiler* compiler,
-                                               BranchInstr* branch) {
-  BranchLabels labels = compiler->CreateBranchLabels(branch);
-  CheckedSmiComparisonSlowPath* slow_path = new CheckedSmiComparisonSlowPath(
-      this, branch->env(), compiler->CurrentTryIndex(), labels,
-      /* merged = */ true);
-  compiler->AddSlowPathCode(slow_path);
-  EMIT_SMI_CHECK;
-  Condition true_condition = EmitComparisonCode(compiler, labels);
-  ASSERT(true_condition != kInvalidCondition);
-  EmitBranchOnCondition(compiler, true_condition, labels);
-  // No need to bind slow_path->exit_label() as slow path exits through
-  // true/false branch labels.
-}
-
-void CheckedSmiComparisonInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  // Zone-allocate labels to pass them to slow-path which outlives local scope.
-  compiler::Label* true_label = new (Z) compiler::Label();
-  compiler::Label* false_label = new (Z) compiler::Label();
-  compiler::Label done;
-  BranchLabels labels = {true_label, false_label, false_label};
-  // In case of negated comparison result of a slow path call should be negated.
-  // For this purpose, 'merged' slow path is generated: it tests
-  // result of a call and jumps directly to true or false label.
-  CheckedSmiComparisonSlowPath* slow_path = new CheckedSmiComparisonSlowPath(
-      this, env(), compiler->CurrentTryIndex(), labels,
-      /* merged = */ is_negated());
-  compiler->AddSlowPathCode(slow_path);
-  EMIT_SMI_CHECK;
-  Condition true_condition = EmitComparisonCode(compiler, labels);
-  ASSERT(true_condition != kInvalidCondition);
-  EmitBranchOnCondition(compiler, true_condition, labels);
-  Register result = locs()->out(0).reg();
-  __ Bind(false_label);
-  __ LoadObject(result, Bool::False());
-  __ jmp(&done);
-  __ Bind(true_label);
-  __ LoadObject(result, Bool::True());
-  __ Bind(&done);
-  // In case of negated comparison slow path exits through true/false labels.
-  if (!is_negated()) {
-    __ Bind(slow_path->exit_label());
-  }
-}
-
 static bool CanBeImmediate(const Object& constant) {
   return constant.IsSmi() &&
          compiler::Immediate(static_cast<int64_t>(constant.ptr())).is_int32();
@@ -4013,57 +3721,21 @@
     const int64_t imm = static_cast<int64_t>(constant.ptr());
     switch (op_kind()) {
       case Token::kADD: {
-        if (deopt == NULL) {
-          // When we can't overflow, prefer 64-bit op to 32-bit op followed by
-          // sign extension.
-          __ AddImmediate(left, compiler::Immediate(imm));
-        } else {
-#if !defined(DART_COMPRESSED_POINTERS)
-          __ AddImmediate(left, compiler::Immediate(imm));
-          __ j(OVERFLOW, deopt);
-#else
-          __ AddImmediate(left, compiler::Immediate(imm), compiler::kFourBytes);
-          __ j(OVERFLOW, deopt);
-          __ movsxd(left, left);
-#endif
-        }
+        __ AddImmediate(left, compiler::Immediate(imm), compiler::kObjectBytes);
+        if (deopt != NULL) __ j(OVERFLOW, deopt);
         break;
       }
       case Token::kSUB: {
-        if (deopt == NULL) {
-          // When we can't overflow, prefer 64-bit op to 32-bit op followed by
-          // sign extension.
-          __ SubImmediate(left, compiler::Immediate(imm));
-        } else {
-#if !defined(DART_COMPRESSED_POINTERS)
-          __ SubImmediate(left, compiler::Immediate(imm));
-          __ j(OVERFLOW, deopt);
-#else
-          __ SubImmediate(left, compiler::Immediate(imm), compiler::kFourBytes);
-          __ j(OVERFLOW, deopt);
-          __ movsxd(left, left);
-#endif
-        }
+        __ SubImmediate(left, compiler::Immediate(imm), compiler::kObjectBytes);
+        if (deopt != NULL) __ j(OVERFLOW, deopt);
         break;
       }
       case Token::kMUL: {
         // Keep left value tagged and untag right value.
         const intptr_t value = Smi::Cast(constant).Value();
-        if (deopt == NULL) {
-          // When we can't overflow, prefer 64-bit op to 32-bit op followed by
-          // sign extension.
-          __ MulImmediate(left, compiler::Immediate(value));
-        } else {
-#if !defined(DART_COMPRESSED_POINTERS)
-          __ MulImmediate(left, compiler::Immediate(value));
-          __ j(OVERFLOW, deopt);
-#else
-          __ MulImmediate(left, compiler::Immediate(value),
-                          compiler::kFourBytes);
-          __ j(OVERFLOW, deopt);
-          __ movsxd(left, left);
-#endif
-        }
+        __ MulImmediate(left, compiler::Immediate(value),
+                        compiler::kObjectBytes);
+        if (deopt != NULL) __ j(OVERFLOW, deopt);
         break;
       }
       case Token::kTRUNCDIV: {
@@ -4078,16 +3750,19 @@
 #if !defined(DART_COMPRESSED_POINTERS)
         __ sarq(temp, compiler::Immediate(63));
 #else
-        // Assumes Smis are sign extended.
-        __ sarq(temp, compiler::Immediate(31));
+        __ sarl(temp, compiler::Immediate(31));
 #endif
         ASSERT(shift_count > 1);  // 1, -1 case handled above.
+#if !defined(DART_COMPRESSED_POINTERS)
         __ shrq(temp, compiler::Immediate(64 - shift_count));
-        __ addq(left, temp);
+#else
+        __ shrl(temp, compiler::Immediate(32 - shift_count));
+#endif
+        __ OBJ(add)(left, temp);
         ASSERT(shift_count > 0);
-        __ sarq(left, compiler::Immediate(shift_count));
+        __ OBJ(sar)(left, compiler::Immediate(shift_count));
         if (value < 0) {
-          __ negq(left);
+          __ OBJ(neg)(left);
         }
         __ SmiTag(left);
         break;
@@ -4109,15 +3784,15 @@
       }
 
       case Token::kSHR: {
-        // sarq operation masks the count to 6 bits.
+        // sarq/l operation masks the count to 6/5 bits.
 #if !defined(DART_COMPRESSED_POINTERS)
         const intptr_t kCountLimit = 0x3F;
 #else
         const intptr_t kCountLimit = 0x1F;
 #endif
         const intptr_t value = Smi::Cast(constant).Value();
-        __ sarq(left, compiler::Immediate(
-                          Utils::Minimum(value + kSmiTagSize, kCountLimit)));
+        __ OBJ(sar)(left, compiler::Immediate(Utils::Minimum(
+                              value + kSmiTagSize, kCountLimit)));
         __ SmiTag(left);
         break;
       }
@@ -4129,9 +3804,9 @@
         const intptr_t kCountLimit = 0x3F;
         const intptr_t value = Smi::Cast(constant).Value();
         ASSERT((value >= 0) && (value <= kCountLimit));
-        __ SmiUntag(left);
+        __ SmiUntagAndSignExtend(left);
         __ shrq(left, compiler::Immediate(value));
-        __ SmiTag(left);
+        __ shlq(left, compiler::Immediate(1));  // SmiTag, keep hi bits.
         if (deopt != nullptr) {
           __ j(OVERFLOW, deopt);
 #if defined(DART_COMPRESSED_POINTERS)
@@ -4155,55 +3830,19 @@
     const compiler::Address& right = LocationToStackSlotAddress(locs()->in(1));
     switch (op_kind()) {
       case Token::kADD: {
-        if (deopt == NULL) {
-          // When we can't overflow, prefer 64-bit op to 32-bit op followed by
-          // sign extension.
-          __ addq(left, right);
-        } else {
-#if !defined(DART_COMPRESSED_POINTERS)
-          __ addq(left, right);
-          __ j(OVERFLOW, deopt);
-#else
-          __ addl(left, right);
-          __ j(OVERFLOW, deopt);
-          __ movsxd(left, left);
-#endif
-        }
+        __ OBJ(add)(left, right);
+        if (deopt != NULL) __ j(OVERFLOW, deopt);
         break;
       }
       case Token::kSUB: {
-        if (deopt == NULL) {
-          // When we can't overflow, prefer 64-bit op to 32-bit op followed by
-          // sign extension.
-          __ subq(left, right);
-        } else {
-#if !defined(DART_COMPRESSED_POINTERS)
-          __ subq(left, right);
-          __ j(OVERFLOW, deopt);
-#else
-          __ subl(left, right);
-          __ j(OVERFLOW, deopt);
-          __ movsxd(left, left);
-#endif
-        }
+        __ OBJ(sub)(left, right);
+        if (deopt != NULL) __ j(OVERFLOW, deopt);
         break;
       }
       case Token::kMUL: {
         __ SmiUntag(left);
-        if (deopt == NULL) {
-          // When we can't overflow, prefer 64-bit op to 32-bit op followed by
-          // sign extension.
-          __ imulq(left, right);
-        } else {
-#if !defined(DART_COMPRESSED_POINTERS)
-          __ imulq(left, right);
-          __ j(OVERFLOW, deopt);
-#else
-          __ imull(left, right);
-          __ j(OVERFLOW, deopt);
-          __ movsxd(left, left);
-#endif
-        }
+        __ OBJ(imul)(left, right);
+        if (deopt != NULL) __ j(OVERFLOW, deopt);
         break;
       }
       case Token::kBIT_AND: {
@@ -4232,55 +3871,19 @@
   Register right = locs()->in(1).reg();
   switch (op_kind()) {
     case Token::kADD: {
-#if !defined(DART_COMPRESSED_POINTERS)
-      __ addq(left, right);
+      __ OBJ(add)(left, right);
       if (deopt != NULL) __ j(OVERFLOW, deopt);
-#else
-      if (deopt == NULL) {
-        // When we can't overflow, prefer 64-bit op to 32-bit op followed by
-        // sign extension.
-        __ addq(left, right);
-      } else {
-        __ addl(left, right);
-        __ j(OVERFLOW, deopt);
-        __ movsxd(left, left);
-      }
-#endif
       break;
     }
     case Token::kSUB: {
-#if !defined(DART_COMPRESSED_POINTERS)
-      __ subq(left, right);
+      __ OBJ(sub)(left, right);
       if (deopt != NULL) __ j(OVERFLOW, deopt);
-#else
-      if (deopt == NULL) {
-        // When we can't overflow, prefer 64-bit op to 32-bit op followed by
-        // sign extension.
-        __ subq(left, right);
-      } else {
-        __ subl(left, right);
-        __ j(OVERFLOW, deopt);
-        __ movsxd(left, left);
-      }
-#endif
       break;
     }
     case Token::kMUL: {
       __ SmiUntag(left);
-#if !defined(DART_COMPRESSED_POINTERS)
-      __ imulq(left, right);
+      __ OBJ(imul)(left, right);
       if (deopt != NULL) __ j(OVERFLOW, deopt);
-#else
-      if (deopt == NULL) {
-        // When we can't overflow, prefer 64-bit op to 32-bit op followed by
-        // sign extension.
-        __ imulq(left, right);
-      } else {
-        __ imull(left, right);
-        __ j(OVERFLOW, deopt);
-        __ movsxd(left, left);
-      }
-#endif
       break;
     }
     case Token::kBIT_AND: {
@@ -4308,7 +3911,7 @@
       ASSERT(result == RAX);
       if (RangeUtils::CanBeZero(right_range())) {
         // Handle divide by zero in runtime.
-        __ testq(right, right);
+        __ OBJ(test)(right, right);
         __ j(ZERO, deopt);
       }
 #if !defined(DART_COMPRESSED_POINTERS)
@@ -4373,7 +3976,7 @@
       ASSERT(result == RDX);
       if (RangeUtils::CanBeZero(right_range())) {
         // Handle divide by zero in runtime.
-        __ testq(right, right);
+        __ OBJ(test)(right, right);
         __ j(ZERO, deopt);
       }
 #if !defined(DART_COMPRESSED_POINTERS)
@@ -4417,23 +4020,23 @@
       //    }
       //  }
       compiler::Label all_done;
-      __ cmpq(result, compiler::Immediate(0));
+      __ OBJ(cmp)(result, compiler::Immediate(0));
       __ j(GREATER_EQUAL, &all_done, compiler::Assembler::kNearJump);
       // Result is negative, adjust it.
       if (RangeUtils::Overlaps(right_range(), -1, 1)) {
         compiler::Label subtract;
-        __ cmpq(right, compiler::Immediate(0));
+        __ OBJ(cmp)(right, compiler::Immediate(0));
         __ j(LESS, &subtract, compiler::Assembler::kNearJump);
-        __ addq(result, right);
+        __ OBJ(add)(result, right);
         __ jmp(&all_done, compiler::Assembler::kNearJump);
         __ Bind(&subtract);
-        __ subq(result, right);
+        __ OBJ(sub)(result, right);
       } else if (right_range()->IsPositive()) {
         // Right is positive.
-        __ addq(result, right);
+        __ OBJ(add)(result, right);
       } else {
         // Right is negative.
-        __ subq(result, right);
+        __ OBJ(sub)(result, right);
       }
       __ Bind(&all_done);
       __ SmiTag(result);
@@ -4441,12 +4044,17 @@
     }
     case Token::kSHR: {
       if (CanDeoptimize()) {
-        __ CompareImmediate(right, compiler::Immediate(0));
+        __ CompareImmediate(right, compiler::Immediate(0),
+                            compiler::kObjectBytes);
         __ j(LESS, deopt);
       }
       __ SmiUntag(right);
-      // sarq operation masks the count to 6 bits.
+      // sarq/l operation masks the count to 6/5 bits.
+#if !defined(DART_COMPRESSED_POINTERS)
       const intptr_t kCountLimit = 0x3F;
+#else
+      const intptr_t kCountLimit = 0x1F;
+#endif
       if (!RangeUtils::OnlyLessThanOrEqualTo(right_range(), kCountLimit)) {
         __ CompareImmediate(right, compiler::Immediate(kCountLimit));
         compiler::Label count_ok;
@@ -4456,13 +4064,14 @@
       }
       ASSERT(right == RCX);  // Count must be in RCX
       __ SmiUntag(left);
-      __ sarq(left, right);
+      __ OBJ(sar)(left, right);
       __ SmiTag(left);
       break;
     }
     case Token::kUSHR: {
       if (deopt != nullptr) {
-        __ CompareImmediate(right, compiler::Immediate(0));
+        __ CompareImmediate(right, compiler::Immediate(0),
+                            compiler::kObjectBytes);
         __ j(LESS, deopt);
       }
       __ SmiUntag(right);
@@ -4471,7 +4080,8 @@
       COMPILE_ASSERT(kCountLimit + 1 == kBitsPerInt64);
       compiler::Label done;
       if (!RangeUtils::OnlyLessThanOrEqualTo(right_range(), kCountLimit)) {
-        __ CompareImmediate(right, compiler::Immediate(kCountLimit));
+        __ CompareImmediate(right, compiler::Immediate(kCountLimit),
+                            compiler::kObjectBytes);
         compiler::Label count_ok;
         __ j(LESS_EQUAL, &count_ok, compiler::Assembler::kNearJump);
         __ xorq(left, left);
@@ -4479,9 +4089,9 @@
         __ Bind(&count_ok);
       }
       ASSERT(right == RCX);  // Count must be in RCX
-      __ SmiUntag(left);
+      __ SmiUntagAndSignExtend(left);
       __ shrq(left, right);
-      __ SmiTag(left);
+      __ shlq(left, compiler::Immediate(1));  // SmiTag, keep hi bits.
       if (deopt != nullptr) {
         __ j(OVERFLOW, deopt);
 #if defined(DART_COMPRESSED_POINTERS)
@@ -4657,14 +4267,14 @@
     case kUnboxedInt64: {
       const Register result = locs()->out(0).reg();
       ASSERT(result == box);
-      __ SmiUntag(box);
+      __ SmiUntagAndSignExtend(box);
       break;
     }
 
     case kUnboxedDouble: {
       const FpuRegister result = locs()->out(0).fpu_reg();
       __ SmiUntag(box);
-      __ cvtsi2sdq(result, box);
+      __ OBJ(cvtsi2sd)(result, box);
       break;
     }
 
@@ -4679,9 +4289,22 @@
   const Register result = locs()->out(0).reg();
   ASSERT(value == result);
   compiler::Label done;
+#if !defined(DART_COMPRESSED_POINTERS)
   __ SmiUntag(value);
   __ j(NOT_CARRY, &done, compiler::Assembler::kNearJump);
   __ movsxw(result, compiler::Address(value, TIMES_2, Mint::value_offset()));
+#else
+  // Cannot speculatively untag because it erases the upper bits needed to
+  // dereference when it is a Mint.
+  // TODO(compressed-pointers): It would probably be cheaper to make
+  // result != value with compressed pointers.
+  compiler::Label not_smi;
+  __ BranchIfNotSmi(value, &not_smi, compiler::Assembler::kNearJump);
+  __ SmiUntagAndSignExtend(value);
+  __ jmp(&done, compiler::Assembler::kNearJump);
+  __ Bind(&not_smi);
+  __ movsxw(result, compiler::FieldAddress(value, Mint::value_offset()));
+#endif
   __ Bind(&done);
 }
 
@@ -4690,10 +4313,22 @@
   const Register result = locs()->out(0).reg();
   ASSERT(value == result);
   compiler::Label done;
+#if !defined(DART_COMPRESSED_POINTERS)
   __ SmiUntag(value);
   __ j(NOT_CARRY, &done, compiler::Assembler::kNearJump);
   __ movq(value, compiler::Address(value, TIMES_2, Mint::value_offset()));
   __ Bind(&done);
+#else
+  // Cannot speculatively untag because it erases the upper bits needed to
+  // dereference when it is a Mint.
+  compiler::Label not_smi;
+  __ BranchIfNotSmi(value, &not_smi, compiler::Assembler::kNearJump);
+  __ SmiUntagAndSignExtend(value);
+  __ jmp(&done, compiler::Assembler::kNearJump);
+  __ Bind(&not_smi);
+  __ movq(value, compiler::FieldAddress(value, Mint::value_offset()));
+  __ Bind(&done);
+#endif
 }
 
 LocationSummary* UnboxInteger32Instr::MakeLocationSummary(Zone* zone,
@@ -4729,23 +4364,42 @@
     // or mint value.
     ASSERT(is_truncating());
     compiler::Label done;
+#if !defined(DART_COMPRESSED_POINTERS)
     __ SmiUntag(value);
     __ j(NOT_CARRY, &done, compiler::Assembler::kNearJump);
     __ movq(value, compiler::Address(value, TIMES_2, Mint::value_offset()));
-    __ Bind(&done);
-#if defined(DART_COMPRESSED_POINTERS)
-    if (is_truncating()) {
-      __ movsxd(value, value);
-    }
+#else
+    // Cannot speculatively untag because it erases the upper bits needed to
+    // dereference when it is a Mint.
+    compiler::Label not_smi;
+    __ BranchIfNotSmi(value, &not_smi, compiler::Assembler::kNearJump);
+    __ SmiUntagAndSignExtend(value);
+    __ jmp(&done, compiler::Assembler::kNearJump);
+    __ Bind(&not_smi);
+    __ movq(value, compiler::FieldAddress(value, Mint::value_offset()));
 #endif
+    __ Bind(&done);
     return;
   } else {
     compiler::Label done;
+#if !defined(DART_COMPRESSED_POINTERS)
     // Optimistically untag value.
     __ SmiUntagOrCheckClass(value, kMintCid, &done);
     __ j(NOT_EQUAL, deopt);
     // Undo untagging by multiplying value with 2.
     __ movq(value, compiler::Address(value, TIMES_2, Mint::value_offset()));
+#else
+    // Cannot speculatively untag because it erases the upper bits needed to
+    // dereference when it is a Mint.
+    compiler::Label not_smi;
+    __ BranchIfNotSmi(value, &not_smi, compiler::Assembler::kNearJump);
+    __ SmiUntagAndSignExtend(value);
+    __ jmp(&done, compiler::Assembler::kNearJump);
+    __ Bind(&not_smi);
+    __ CompareClassId(value, kMintCid);
+    __ j(NOT_EQUAL, deopt);
+    __ movq(value, compiler::FieldAddress(value, Mint::value_offset()));
+#endif
     __ Bind(&done);
   }
 
@@ -5479,6 +5133,8 @@
 }
 
 void CaseInsensitiveCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  ASSERT(TargetFunction().is_leaf());
+
   // Save RSP. R13 is chosen because it is callee saved so we do not need to
   // back it up before calling into the runtime.
   static const Register kSavedSPReg = R13;
@@ -5506,12 +5162,7 @@
     case Token::kNEGATE: {
       compiler::Label* deopt =
           compiler->AddDeoptStub(deopt_id(), ICData::kDeoptUnaryOp);
-#if !defined(DART_COMPRESSED_POINTERS)
-      __ negq(value);
-#else
-      __ negl(value);
-      __ movsxd(value, value);
-#endif
+      __ OBJ(neg)(value);
       __ j(OVERFLOW, deopt);
       break;
     }
@@ -5622,7 +5273,7 @@
   Register left = locs()->in(0).reg();
   Register right = locs()->in(1).reg();
   Register result = locs()->out(0).reg();
-  __ cmpq(left, right);
+  __ OBJ(cmp)(left, right);
   ASSERT(result == left);
   if (is_min) {
     __ cmovgeq(result, right);
@@ -5663,11 +5314,7 @@
   Register value = locs()->in(0).reg();
   FpuRegister result = locs()->out(0).fpu_reg();
   __ SmiUntag(value);
-#if !defined(DART_COMPRESSED_POINTERS)
-  __ cvtsi2sdq(result, value);
-#else
-  __ cvtsi2sdl(result, value);
-#endif
+  __ OBJ(cvtsi2sd)(result, value);
 }
 
 DEFINE_BACKEND(Int64ToDouble, (FpuRegister result, Register value)) {
@@ -5696,25 +5343,14 @@
   ASSERT(result != temp);
   __ movsd(value_double,
            compiler::FieldAddress(value_obj, Double::value_offset()));
-#if !defined(DART_COMPRESSED_POINTERS)
-  __ cvttsd2siq(result, value_double);
-#else
-  __ cvttsd2sil(result, value_double);
-#endif
+  __ OBJ(cvttsd2si)(result, value_double);
   // Overflow is signalled with minint.
   compiler::Label do_call, done;
   // Check for overflow and that it fits into Smi.
-#if !defined(DART_COMPRESSED_POINTERS)
   __ movq(temp, result);
-  __ shlq(temp, compiler::Immediate(1));
+  __ OBJ(shl)(temp, compiler::Immediate(1));
   __ j(OVERFLOW, &do_call, compiler::Assembler::kNearJump);
   __ SmiTag(result);
-#else
-  __ movl(temp, result);
-  __ shll(temp, compiler::Immediate(1));
-  __ j(OVERFLOW, &do_call, compiler::Assembler::kNearJump);
-  __ movsxd(result, temp);
-#endif
   __ jmp(&done);
   __ Bind(&do_call);
   __ pushq(value_obj);
@@ -5753,26 +5389,14 @@
   XmmRegister value = locs()->in(0).fpu_reg();
   Register temp = locs()->temp(0).reg();
 
-#if !defined(DART_COMPRESSED_POINTERS)
-  __ cvttsd2siq(result, value);
-#else
-  __ cvttsd2sil(result, value);
-#endif
+  __ OBJ(cvttsd2si)(result, value);
   // Overflow is signalled with minint.
   compiler::Label do_call, done;
   // Check for overflow and that it fits into Smi.
-#if !defined(DART_COMPRESSED_POINTERS)
   __ movq(temp, result);
-  __ shlq(temp, compiler::Immediate(1));
+  __ OBJ(shl)(temp, compiler::Immediate(1));
   __ j(OVERFLOW, deopt);
   __ SmiTag(result);
-#else
-  __ movl(temp, result);
-  __ shll(temp, compiler::Immediate(1));
-  __ j(OVERFLOW, deopt);
-  ASSERT(kSmiTagShift == 1 && kSmiTag == 0);
-  __ movsxd(result, temp);
-#endif
 }
 
 LocationSummary* DoubleToDoubleInstr::MakeLocationSummary(Zone* zone,
@@ -5998,6 +5622,8 @@
 }
 
 void InvokeMathCFunctionInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  ASSERT(TargetFunction().is_leaf());
+
   if (recognized_kind() == MethodRecognizer::kMathDoublePow) {
     InvokeDoublePow(compiler, this);
     return;
@@ -6096,7 +5722,7 @@
   ASSERT(result2 == RDX);
   if (RangeUtils::CanBeZero(divisor_range())) {
     // Handle divide by zero in runtime.
-    __ testq(right, right);
+    __ OBJ(test)(right, right);
     __ j(ZERO, deopt);
   }
 #if !defined(DART_COMPRESSED_POINTERS)
@@ -6380,8 +6006,7 @@
   if (index_loc.IsConstant()) {
     Register length = length_loc.reg();
     const Smi& index = Smi::Cast(index_loc.constant());
-    __ CompareImmediate(length,
-                        compiler::Immediate(static_cast<int64_t>(index.ptr())));
+    __ CompareObject(length, index);
     __ j(BELOW_EQUAL, deopt);
   } else if (length_loc.IsConstant()) {
     const Smi& length = Smi::Cast(length_loc.constant());
@@ -6390,11 +6015,10 @@
       __ BranchIfNotSmi(index, deopt);
     }
     if (length.Value() == Smi::kMaxValue) {
-      __ testq(index, index);
+      __ OBJ(test)(index, index);
       __ j(NEGATIVE, deopt);
     } else {
-      __ CompareImmediate(
-          index, compiler::Immediate(static_cast<int64_t>(length.ptr())));
+      __ CompareObject(index, length);
       __ j(ABOVE_EQUAL, deopt);
     }
   } else {
@@ -6403,7 +6027,7 @@
     if (index_cid != kSmiCid) {
       __ BranchIfNotSmi(index, deopt);
     }
-    __ cmpq(index, length);
+    __ OBJ(cmp)(index, length);
     __ j(ABOVE_EQUAL, deopt);
   }
 }
@@ -7365,16 +6989,6 @@
                                                source(), deopt_id());
 }
 
-LocationSummary* DispatchTableCallInstr::MakeLocationSummary(Zone* zone,
-                                                             bool opt) const {
-  const intptr_t kNumInputs = 1;
-  const intptr_t kNumTemps = 0;
-  LocationSummary* summary = new (zone)
-      LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
-  summary->set_in(0, Location::RegisterLocation(RCX));  // ClassId
-  return MakeCallSummary(zone, this, summary);
-}
-
 LocationSummary* ClosureCallInstr::MakeLocationSummary(Zone* zone,
                                                        bool opt) const {
   const intptr_t kNumInputs = 1;
@@ -7395,8 +7009,9 @@
   // Function in RAX.
   ASSERT(locs()->in(0).reg() == RAX);
   if (!FLAG_precompiled_mode || !FLAG_use_bare_instructions) {
-    __ movq(CODE_REG, compiler::FieldAddress(
-                          RAX, compiler::target::Function::code_offset()));
+    __ LoadCompressed(
+        CODE_REG,
+        compiler::FieldAddress(RAX, compiler::target::Function::code_offset()));
   }
   __ movq(
       RCX,
@@ -7417,30 +7032,16 @@
 
 LocationSummary* BooleanNegateInstr::MakeLocationSummary(Zone* zone,
                                                          bool opt) const {
-  return LocationSummary::Make(zone, 1,
-                               value()->Type()->ToCid() == kBoolCid
-                                   ? Location::SameAsFirstInput()
-                                   : Location::RequiresRegister(),
+  return LocationSummary::Make(zone, 1, Location::SameAsFirstInput(),
                                LocationSummary::kNoCall);
 }
 
 void BooleanNegateInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   Register input = locs()->in(0).reg();
   Register result = locs()->out(0).reg();
-
-  if (value()->Type()->ToCid() == kBoolCid) {
-    ASSERT(input == result);
-    __ xorq(result, compiler::Immediate(
-                        compiler::target::ObjectAlignment::kBoolValueMask));
-  } else {
-    ASSERT(input != result);
-    compiler::Label done;
-    __ LoadObject(result, Bool::True());
-    __ CompareRegisters(result, input);
-    __ j(NOT_EQUAL, &done, compiler::Assembler::kNearJump);
-    __ LoadObject(result, Bool::False());
-    __ Bind(&done);
-  }
+  ASSERT(input == result);
+  __ xorq(result, compiler::Immediate(
+                      compiler::target::ObjectAlignment::kBoolValueMask));
 }
 
 LocationSummary* AllocateObjectInstr::MakeLocationSummary(Zone* zone,
@@ -7468,7 +7069,7 @@
   const Code& stub = Code::ZoneHandle(
       compiler->zone(), StubCode::GetAllocationStubForClass(cls()));
   compiler->GenerateStubCall(source(), stub, UntaggedPcDescriptors::kOther,
-                             locs());
+                             locs(), deopt_id());
 }
 
 void DebugStepCheckInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
diff --git a/runtime/vm/compiler/backend/inliner.cc b/runtime/vm/compiler/backend/inliner.cc
index 95ba032..4050f44 100644
--- a/runtime/vm/compiler/backend/inliner.cc
+++ b/runtime/vm/compiler/backend/inliner.cc
@@ -2385,17 +2385,6 @@
   return FlowGraphCompiler::SupportsUnboxedDoubles();
 }
 
-static bool ShouldInlineInt64ArrayOps() {
-  return FlowGraphCompiler::SupportsUnboxedInt64();
-}
-
-static bool CanUnboxInt32() {
-  // Int32/Uint32 can be unboxed if it fits into a smi or the platform
-  // supports unboxed mints.
-  return (compiler::target::kSmiBits >= 32) ||
-         FlowGraphCompiler::SupportsUnboxedInt64();
-}
-
 // Quick access to the current one.
 #undef Z
 #define Z (flow_graph->zone())
@@ -3672,16 +3661,10 @@
                               call, receiver, graph_entry, entry, last, result);
     case MethodRecognizer::kInt32ArrayGetIndexed:
     case MethodRecognizer::kUint32ArrayGetIndexed:
-      if (!CanUnboxInt32()) {
-        return false;
-      }
       return InlineGetIndexed(flow_graph, can_speculate, is_dynamic_call, kind,
                               call, receiver, graph_entry, entry, last, result);
     case MethodRecognizer::kInt64ArrayGetIndexed:
     case MethodRecognizer::kUint64ArrayGetIndexed:
-      if (!ShouldInlineInt64ArrayOps()) {
-        return false;
-      }
       return InlineGetIndexed(flow_graph, can_speculate, is_dynamic_call, kind,
                               call, receiver, graph_entry, entry, last, result);
     case MethodRecognizer::kClassIDgetID:
@@ -3732,9 +3715,6 @@
     }
     case MethodRecognizer::kInt64ArraySetIndexed:
     case MethodRecognizer::kUint64ArraySetIndexed:
-      if (!ShouldInlineInt64ArrayOps()) {
-        return false;
-      }
       return InlineSetIndexed(flow_graph, kind, target, call, receiver, source,
                               /* value_check = */ NULL, exactness, graph_entry,
                               entry, last, result);
@@ -3783,30 +3763,18 @@
                                      kTypedDataUint16ArrayCid, graph_entry,
                                      entry, last, result);
     case MethodRecognizer::kByteArrayBaseGetInt32:
-      if (!CanUnboxInt32()) {
-        return false;
-      }
       return InlineByteArrayBaseLoad(flow_graph, call, receiver, receiver_cid,
                                      kTypedDataInt32ArrayCid, graph_entry,
                                      entry, last, result);
     case MethodRecognizer::kByteArrayBaseGetUint32:
-      if (!CanUnboxInt32()) {
-        return false;
-      }
       return InlineByteArrayBaseLoad(flow_graph, call, receiver, receiver_cid,
                                      kTypedDataUint32ArrayCid, graph_entry,
                                      entry, last, result);
     case MethodRecognizer::kByteArrayBaseGetInt64:
-      if (!ShouldInlineInt64ArrayOps()) {
-        return false;
-      }
       return InlineByteArrayBaseLoad(flow_graph, call, receiver, receiver_cid,
                                      kTypedDataInt64ArrayCid, graph_entry,
                                      entry, last, result);
     case MethodRecognizer::kByteArrayBaseGetUint64:
-      if (!ShouldInlineInt64ArrayOps()) {
-        return false;
-      }
       return InlineByteArrayBaseLoad(flow_graph, call, receiver, receiver_cid,
                                      kTypedDataUint64ArrayCid, graph_entry,
                                      entry, last, result);
@@ -3863,16 +3831,10 @@
                                       receiver_cid, kTypedDataUint32ArrayCid,
                                       graph_entry, entry, last, result);
     case MethodRecognizer::kByteArrayBaseSetInt64:
-      if (!ShouldInlineInt64ArrayOps()) {
-        return false;
-      }
       return InlineByteArrayBaseStore(flow_graph, target, call, receiver,
                                       receiver_cid, kTypedDataInt64ArrayCid,
                                       graph_entry, entry, last, result);
     case MethodRecognizer::kByteArrayBaseSetUint64:
-      if (!ShouldInlineInt64ArrayOps()) {
-        return false;
-      }
       return InlineByteArrayBaseStore(flow_graph, target, call, receiver,
                                       receiver_cid, kTypedDataUint64ArrayCid,
                                       graph_entry, entry, last, result);
@@ -4023,6 +3985,8 @@
     case MethodRecognizer::kMathAcos:
     case MethodRecognizer::kMathAtan:
     case MethodRecognizer::kMathAtan2:
+    case MethodRecognizer::kMathExp:
+    case MethodRecognizer::kMathLog:
       return InlineMathCFunction(flow_graph, call, kind, graph_entry, entry,
                                  last, result);
 
diff --git a/runtime/vm/compiler/backend/inliner_test.cc b/runtime/vm/compiler/backend/inliner_test.cc
index 9a53a7b..26eb9e5 100644
--- a/runtime/vm/compiler/backend/inliner_test.cc
+++ b/runtime/vm/compiler/backend/inliner_test.cc
@@ -222,8 +222,8 @@
   RELEASE_ASSERT(cursor.TryMatch({
       kMoveGlob,
       kMatchAndMoveCreateArray,
-      kMatchAndMoveUnboxInt64,
       {kMoveAny, &unbox1},
+      kMatchAndMoveUnboxInt64,
       {kMoveAny, &unbox2},
       kMatchAndMoveGoto,
 
diff --git a/runtime/vm/compiler/backend/loops.cc b/runtime/vm/compiler/backend/loops.cc
index 4ff2dc8..f28ae39 100644
--- a/runtime/vm/compiler/backend/loops.cc
+++ b/runtime/vm/compiler/backend/loops.cc
@@ -723,13 +723,16 @@
       // Invariant + Invariant : only for same or just one instruction.
       if (x->def_ == y->def_) {
         return new (zone_)
-            InductionVar(x->offset_ + y->offset_, x->mult_ + y->mult_, x->def_);
+            InductionVar(Utils::AddWithWrapAround(x->offset_, y->offset_),
+                         Utils::AddWithWrapAround(x->mult_, y->mult_), x->def_);
       } else if (y->mult_ == 0) {
         return new (zone_)
-            InductionVar(x->offset_ + y->offset_, x->mult_, x->def_);
+            InductionVar(Utils::AddWithWrapAround(x->offset_, y->offset_),
+                         x->mult_, x->def_);
       } else if (x->mult_ == 0) {
         return new (zone_)
-            InductionVar(x->offset_ + y->offset_, y->mult_, y->def_);
+            InductionVar(Utils::AddWithWrapAround(x->offset_, y->offset_),
+                         y->mult_, y->def_);
       }
     } else if (y != nullptr) {
       // Invariant + Induction.
@@ -768,13 +771,16 @@
       // Invariant + Invariant : only for same or just one instruction.
       if (x->def_ == y->def_) {
         return new (zone_)
-            InductionVar(x->offset_ - y->offset_, x->mult_ - y->mult_, x->def_);
+            InductionVar(Utils::SubWithWrapAround(x->offset_, y->offset_),
+                         Utils::SubWithWrapAround(x->mult_, y->mult_), x->def_);
       } else if (y->mult_ == 0) {
         return new (zone_)
-            InductionVar(x->offset_ - y->offset_, x->mult_, x->def_);
+            InductionVar(Utils::SubWithWrapAround(x->offset_, y->offset_),
+                         x->mult_, x->def_);
       } else if (x->mult_ == 0) {
         return new (zone_)
-            InductionVar(x->offset_ - y->offset_, -y->mult_, y->def_);
+            InductionVar(Utils::SubWithWrapAround(x->offset_, y->offset_),
+                         Utils::NegWithWrapAround(y->mult_), y->def_);
       }
     } else if (y != nullptr) {
       // Invariant - Induction.
@@ -823,7 +829,8 @@
   if (InductionVar::IsConstant(x) && y != nullptr) {
     if (y->kind_ == InductionVar::kInvariant) {
       return new (zone_)
-          InductionVar(x->offset_ * y->offset_, x->offset_ * y->mult_, y->def_);
+          InductionVar(Utils::MulWithWrapAround(x->offset_, y->offset_),
+                       Utils::MulWithWrapAround(x->offset_, y->mult_), y->def_);
     }
     return new (zone_)
         InductionVar(y->kind_, Mul(x, y->initial_), Mul(x, y->next_));
diff --git a/runtime/vm/compiler/backend/loops_test.cc b/runtime/vm/compiler/backend/loops_test.cc
index 8f1201e..1722f3b 100644
--- a/runtime/vm/compiler/backend/loops_test.cc
+++ b/runtime/vm/compiler/backend/loops_test.cc
@@ -68,9 +68,13 @@
   Invoke(root_library, "main");
 
   std::initializer_list<CompilerPass::Id> passes = {
-      CompilerPass::kComputeSSA,      CompilerPass::kTypePropagation,
-      CompilerPass::kApplyICData,     CompilerPass::kSelectRepresentations,
-      CompilerPass::kTypePropagation, CompilerPass::kCanonicalize,
+      CompilerPass::kComputeSSA,
+      CompilerPass::kTypePropagation,
+      CompilerPass::kApplyICData,
+      CompilerPass::kTypePropagation,
+      CompilerPass::kSelectRepresentations,
+      CompilerPass::kTypePropagation,
+      CompilerPass::kCanonicalize,
   };
   const auto& function = Function::Handle(GetFunction(root_library, "foo"));
   TestPipeline pipeline(function, CompilerPass::kJIT);
@@ -300,7 +304,7 @@
   const char* expected =
       "  [0\n"
       "  WRAP(99, LIN(0 + 1 * i))\n"    // phi (w)
-      "  LIN(0 + 1 * i) 100\n"          // phi
+      "  LIN(0 + 1 * i) 100\n"          // phi (i)
       "  WRAP(102, LIN(3 + 1 * i))\n"   // a
       "  WRAP(94, LIN(-5 + 1 * i))\n"   // b
       "  WRAP(693, LIN(0 + 7 * i))\n"   // c
@@ -383,11 +387,15 @@
   const char* expected =
       "  [0\n"
       "  LIN(9223372036854775806 + 1 * i)\n"  // phi
+#if !defined(TARGET_ARCH_IS_64_BIT)
       "  LIN(9223372036854775806 + 1 * i)\n"  // (un)boxing
       "  LIN(9223372036854775806 + 1 * i)\n"
       "  LIN(9223372036854775806 + 1 * i)\n"
+#endif                                        // !defined(TARGET_ARCH_IS_64_BIT)
       "  LIN(9223372036854775807 + 1 * i)\n"  // add
+#if !defined(TARGET_ARCH_IS_64_BIT)
       "  LIN(9223372036854775807 + 1 * i)\n"  // unbox
+#endif                                        // !defined(TARGET_ARCH_IS_64_BIT)
       "  ]\n";
   EXPECT_STREQ(expected, ComputeInduction(thread, script_chars));
 }
@@ -426,11 +434,15 @@
   const char* expected =
       "  [0\n"
       "  LIN(-9223372036854775807 + -1 * i)\n"  // phi
+#if !defined(TARGET_ARCH_IS_64_BIT)
       "  LIN(-9223372036854775807 + -1 * i)\n"  // (un)boxing
       "  LIN(-9223372036854775807 + -1 * i)\n"
       "  LIN(-9223372036854775807 + -1 * i)\n"
+#endif  // !defined(TARGET_ARCH_IS_64_BIT)
       "  LIN(-9223372036854775808 + -1 * i)\n"  // sub
+#if !defined(TARGET_ARCH_IS_64_BIT)
       "  LIN(-9223372036854775808 + -1 * i)\n"  // unbox
+#endif  // !defined(TARGET_ARCH_IS_64_BIT)
       "  ]\n";
   EXPECT_STREQ(expected, ComputeInduction(thread, script_chars));
 }
diff --git a/runtime/vm/compiler/backend/range_analysis.cc b/runtime/vm/compiler/backend/range_analysis.cc
index cac72cc..51aa420 100644
--- a/runtime/vm/compiler/backend/range_analysis.cc
+++ b/runtime/vm/compiler/backend/range_analysis.cc
@@ -2742,8 +2742,9 @@
   switch (r) {
     case kTagged:
       return RangeBoundary::kRangeBoundarySmi;
+    case kUnboxedUint8:  // Overapproximate Uint8 as Int16.
+      return RangeBoundary::kRangeBoundaryInt16;
     case kUnboxedInt32:
-    case kUnboxedUint8:  // Overapproximate Uint8 as Int32.
       return RangeBoundary::kRangeBoundaryInt32;
     case kUnboxedInt64:
     case kUnboxedUint32:  // Overapproximate Uint32 as Int64.
@@ -2821,6 +2822,7 @@
       UNREACHABLE();
       break;
 
+    case Slot::Kind::kClosureData_default_type_arguments_kind:
     case Slot::Kind::kFunction_kind_tag:
     case Slot::Kind::kFunction_packed_fields:
     case Slot::Kind::kTypeParameter_flags:
@@ -2841,9 +2843,6 @@
     case Slot::Kind::kArgumentsDescriptor_size:
       *range = Range(RangeBoundary::FromConstant(0), RangeBoundary::MaxSmi());
       break;
-
-    case Slot::Kind::kClosureData_default_type_arguments_info:
-      *range = Range(RangeBoundary::FromConstant(0), RangeBoundary::MaxSmi());
   }
 }
 
@@ -2915,6 +2914,12 @@
   }
 }
 
+void Utf8ScanInstr::InferRange(RangeAnalysis* analysis, Range* range) {
+  // The input bytes given to the Utf8Scan instruction are in non-negative Smi
+  // range and so is the resulting computed length.
+  *range = Range(RangeBoundary::FromConstant(0), RangeBoundary::MaxSmi());
+}
+
 void IfThenElseInstr::InferRange(RangeAnalysis* analysis, Range* range) {
   const intptr_t min = Utils::Minimum(if_true_, if_false_);
   const intptr_t max = Utils::Maximum(if_true_, if_false_);
diff --git a/runtime/vm/compiler/backend/range_analysis.h b/runtime/vm/compiler/backend/range_analysis.h
index 7491def..b0037f4 100644
--- a/runtime/vm/compiler/backend/range_analysis.h
+++ b/runtime/vm/compiler/backend/range_analysis.h
@@ -14,9 +14,6 @@
 
 namespace dart {
 
-class SExpression;
-class FlowGraphSerializer;
-
 class RangeBoundary : public ValueObject {
  public:
 #define FOR_EACH_RANGE_BOUNDARY_KIND(V)                                        \
@@ -35,6 +32,7 @@
 
   enum RangeSize {
     kRangeBoundarySmi,
+    kRangeBoundaryInt16,
     kRangeBoundaryInt32,
     kRangeBoundaryInt64,
   };
@@ -100,6 +98,8 @@
     switch (size) {
       case kRangeBoundarySmi:
         return FromConstant(compiler::target::kSmiMin);
+      case kRangeBoundaryInt16:
+        return FromConstant(kMinInt16);
       case kRangeBoundaryInt32:
         return FromConstant(kMinInt32);
       case kRangeBoundaryInt64:
@@ -113,6 +113,8 @@
     switch (size) {
       case kRangeBoundarySmi:
         return FromConstant(compiler::target::kSmiMax);
+      case kRangeBoundaryInt16:
+        return FromConstant(kMaxInt16);
       case kRangeBoundaryInt32:
         return FromConstant(kMaxInt32);
       case kRangeBoundaryInt64:
@@ -246,7 +248,6 @@
 
   void PrintTo(BaseTextBuffer* f) const;
   const char* ToCString() const;
-  SExpression* ToSExpression(FlowGraphSerializer* s);
 
   static RangeBoundary Add(const RangeBoundary& a,
                            const RangeBoundary& b,
@@ -347,7 +348,6 @@
 
   void PrintTo(BaseTextBuffer* f) const;
   static const char* ToCString(const Range* range);
-  SExpression* ToSExpression(FlowGraphSerializer* s);
 
   bool Equals(const Range* other) {
     ASSERT(min_.IsUnknown() == max_.IsUnknown());
diff --git a/runtime/vm/compiler/backend/redundancy_elimination.cc b/runtime/vm/compiler/backend/redundancy_elimination.cc
index d63933e..fb3d09c 100644
--- a/runtime/vm/compiler/backend/redundancy_elimination.cc
+++ b/runtime/vm/compiler/backend/redundancy_elimination.cc
@@ -1336,20 +1336,21 @@
 void LICM::Hoist(ForwardInstructionIterator* it,
                  BlockEntryInstr* pre_header,
                  Instruction* current) {
-  if (current->IsCheckClass()) {
-    current->AsCheckClass()->set_licm_hoisted(true);
-  } else if (current->IsCheckSmi()) {
-    current->AsCheckSmi()->set_licm_hoisted(true);
-  } else if (current->IsCheckEitherNonSmi()) {
-    current->AsCheckEitherNonSmi()->set_licm_hoisted(true);
-  } else if (current->IsCheckArrayBound()) {
+  if (auto check = current->AsCheckClass()) {
+    check->set_licm_hoisted(true);
+  } else if (auto check = current->AsCheckSmi()) {
+    check->set_licm_hoisted(true);
+  } else if (auto check = current->AsCheckEitherNonSmi()) {
+    check->set_licm_hoisted(true);
+  } else if (auto check = current->AsCheckArrayBound()) {
     ASSERT(!CompilerState::Current().is_aot());  // speculative in JIT only
-    current->AsCheckArrayBound()->set_licm_hoisted(true);
-  } else if (current->IsGenericCheckBound()) {
+    check->set_licm_hoisted(true);
+  } else if (auto check = current->AsGenericCheckBound()) {
     ASSERT(CompilerState::Current().is_aot());  // non-speculative in AOT only
     // Does not deopt, so no need for licm_hoisted flag.
-  } else if (current->IsTestCids()) {
-    current->AsTestCids()->set_licm_hoisted(true);
+    USE(check);
+  } else if (auto check = current->AsTestCids()) {
+    check->set_licm_hoisted(true);
   }
   if (FLAG_trace_optimization) {
     THR_Print("Hoisting instruction %s:%" Pd " from B%" Pd " to B%" Pd "\n",
diff --git a/runtime/vm/compiler/backend/redundancy_elimination_test.cc b/runtime/vm/compiler/backend/redundancy_elimination_test.cc
index 65b6b80..c76394e 100644
--- a/runtime/vm/compiler/backend/redundancy_elimination_test.cc
+++ b/runtime/vm/compiler/backend/redundancy_elimination_test.cc
@@ -262,7 +262,7 @@
     BlockBuilder builder(H.flow_graph(), b1);
     auto& slot = Slot::Get(field, &H.flow_graph()->parsed_function());
     v0 = builder.AddDefinition(
-        new AllocateObjectInstr(InstructionSource(), cls));
+        new AllocateObjectInstr(InstructionSource(), cls, S.GetNextDeoptId()));
     v1 = builder.AddDefinition(
         new LoadFieldInstr(new Value(v0), slot, InstructionSource()));
     auto v2 = builder.AddDefinition(make_redefinition(&S, H.flow_graph(), v0));
@@ -435,9 +435,9 @@
     BlockBuilder builder(H.flow_graph(), b1);
     auto& slot = Slot::Get(field, &H.flow_graph()->parsed_function());
     v0 = builder.AddDefinition(
-        new AllocateObjectInstr(InstructionSource(), cls));
+        new AllocateObjectInstr(InstructionSource(), cls, S.GetNextDeoptId()));
     v5 = builder.AddDefinition(
-        new AllocateObjectInstr(InstructionSource(), cls));
+        new AllocateObjectInstr(InstructionSource(), cls, S.GetNextDeoptId()));
     if (!make_host_escape) {
       builder.AddInstruction(
           new StoreInstanceFieldInstr(slot, new Value(v5), new Value(v0),
diff --git a/runtime/vm/compiler/backend/sexpression.cc b/runtime/vm/compiler/backend/sexpression.cc
deleted file mode 100644
index 7307ef3..0000000
--- a/runtime/vm/compiler/backend/sexpression.cc
+++ /dev/null
@@ -1,686 +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.
-
-#include "vm/compiler/backend/sexpression.h"
-
-#include <ctype.h>
-#include "platform/utils.h"
-#include "vm/double_conversion.h"
-#include "vm/zone_text_buffer.h"
-
-namespace dart {
-
-SExpression* SExpression::FromCString(Zone* zone, const char* str) {
-  SExpParser parser(zone, str);
-  auto sexp = parser.Parse();
-  if (sexp == nullptr) parser.ReportError();
-  return sexp;
-}
-
-const char* SExpression::ToCString(Zone* zone) const {
-  ZoneTextBuffer buf(zone, 1 * KB);
-  SerializeToLine(&buf);
-  return buf.buffer();
-}
-
-bool SExpBool::Equals(SExpression* sexp) const {
-  if (auto const b = sexp->AsBool()) return b->Equals(value());
-  return false;
-}
-
-bool SExpBool::Equals(bool val) const {
-  return value() == val;
-}
-
-void SExpBool::SerializeToLine(BaseTextBuffer* buffer) const {
-  buffer->AddString(value() ? SExpParser::kBoolTrueSymbol
-                            : SExpParser::kBoolFalseSymbol);
-}
-
-bool SExpDouble::Equals(SExpression* sexp) const {
-  if (auto const d = sexp->AsDouble()) return d->Equals(value());
-  return false;
-}
-
-bool SExpDouble::Equals(double val) const {
-  return value() == val;
-}
-
-void SExpDouble::SerializeToLine(BaseTextBuffer* buffer) const {
-  // Use existing Dart serialization for Doubles.
-  const intptr_t kBufSize = 128;
-  char strbuf[kBufSize];
-  DoubleToCString(value(), strbuf, kBufSize);
-  buffer->Printf("%s", strbuf);
-}
-
-bool SExpInteger::Equals(SExpression* sexp) const {
-  if (auto const i = sexp->AsInteger()) return i->Equals(value());
-  return false;
-}
-
-bool SExpInteger::Equals(int64_t val) const {
-  return value() == val;
-}
-
-void SExpInteger::SerializeToLine(BaseTextBuffer* buffer) const {
-  buffer->Printf("%" Pd64 "", value());
-}
-
-bool SExpString::Equals(SExpression* sexp) const {
-  if (auto const s = sexp->AsString()) return s->Equals(value());
-  return false;
-}
-
-bool SExpString::Equals(const char* str) const {
-  return strcmp(value(), str) == 0;
-}
-
-void SExpString::SerializeToLine(BaseTextBuffer* buffer) const {
-  TextBuffer buf(80);
-  buf.AddChar('"');
-  buf.AddEscapedString(value());
-  buf.AddChar('"');
-  buffer->AddString(buf.buffer());
-}
-
-bool SExpSymbol::Equals(SExpression* sexp) const {
-  if (auto const s = sexp->AsSymbol()) return s->Equals(value());
-  return false;
-}
-
-bool SExpSymbol::Equals(const char* str) const {
-  return strcmp(value(), str) == 0;
-}
-
-void SExpSymbol::SerializeToLine(BaseTextBuffer* buffer) const {
-  buffer->AddString(value());
-}
-
-void SExpList::Add(SExpression* sexp) {
-  contents_.Add(sexp);
-}
-
-void SExpList::AddExtra(const char* label, SExpression* value) {
-  ASSERT(!extra_info_.HasKey(label));
-  extra_info_.Insert({label, value});
-}
-
-bool SExpList::Equals(SExpression* sexp) const {
-  if (!sexp->IsList()) return false;
-  auto list = sexp->AsList();
-  if (Length() != list->Length()) return false;
-  if (ExtraLength() != list->ExtraLength()) return false;
-  for (intptr_t i = 0; i < Length(); i++) {
-    if (!At(i)->Equals(list->At(i))) return false;
-  }
-  auto this_it = ExtraIterator();
-  while (auto kv = this_it.Next()) {
-    if (!list->ExtraHasKey(kv->key)) return false;
-    if (!kv->value->Equals(list->ExtraLookupValue(kv->key))) return false;
-  }
-  return true;
-}
-
-const char* const SExpList::kElemIndent = " ";
-const char* const SExpList::kExtraIndent = "  ";
-
-static intptr_t HandleLineBreaking(Zone* zone,
-                                   BaseTextBuffer* buffer,
-                                   SExpression* element,
-                                   BaseTextBuffer* line_buffer,
-                                   const char* sub_indent,
-                                   intptr_t width,
-                                   bool leading_space,
-                                   intptr_t remaining) {
-  element->SerializeToLine(line_buffer);
-  const intptr_t single_line_width = line_buffer->length();
-  const intptr_t leading_length = leading_space ? 1 : 0;
-
-  if ((leading_length + single_line_width) < remaining) {
-    if (leading_space) buffer->AddChar(' ');
-    buffer->AddString(line_buffer->buffer());
-    line_buffer->Clear();
-    return remaining - (leading_length + single_line_width);
-  }
-  const intptr_t old_length = buffer->length();
-  buffer->Printf("\n%s", sub_indent);
-  const intptr_t line_used = buffer->length() - old_length + 1;
-  remaining = width - line_used;
-  if ((single_line_width < remaining) || element->IsAtom()) {
-    buffer->AddString(line_buffer->buffer());
-    line_buffer->Clear();
-    return remaining - single_line_width;
-  }
-  line_buffer->Clear();
-  element->SerializeTo(zone, buffer, sub_indent, width);
-  return 0;
-}
-
-// Assumes that we are starting on a line after [indent] amount of space.
-void SExpList::SerializeTo(Zone* zone,
-                           BaseTextBuffer* buffer,
-                           const char* indent,
-                           intptr_t width) const {
-  TextBuffer single_line(width);
-  const char* sub_indent = OS::SCreate(zone, "%s%s", indent, kElemIndent);
-
-  buffer->AddChar('(');
-  intptr_t remaining = width - strlen(indent) - 1;
-  for (intptr_t i = 0; i < contents_.length(); i++) {
-    remaining = HandleLineBreaking(zone, buffer, contents_.At(i), &single_line,
-                                   sub_indent, width, i != 0, remaining);
-  }
-
-  if (!extra_info_.IsEmpty()) {
-    SerializeExtraInfoToLine(&single_line);
-    if (single_line.length() < remaining - 1) {
-      buffer->Printf(" %s", single_line.buffer());
-    } else {
-      const intptr_t old_length = buffer->length();
-      buffer->Printf("\n%s", sub_indent);
-      const intptr_t line_used = buffer->length() - old_length + 1;
-      remaining = width - line_used;
-      if (single_line.length() < remaining) {
-        buffer->AddString(single_line.buffer());
-      } else {
-        SerializeExtraInfoTo(zone, buffer, sub_indent, width);
-      }
-    }
-  }
-  buffer->AddChar(')');
-}
-
-void SExpList::SerializeToLine(BaseTextBuffer* buffer) const {
-  buffer->AddChar('(');
-  for (intptr_t i = 0; i < contents_.length(); i++) {
-    if (i != 0) buffer->AddChar(' ');
-    contents_.At(i)->SerializeToLine(buffer);
-  }
-  if (!extra_info_.IsEmpty()) {
-    buffer->AddChar(' ');
-    SerializeExtraInfoToLine(buffer);
-  }
-  buffer->AddChar(')');
-}
-
-void SExpList::SerializeExtraInfoTo(Zone* zone,
-                                    BaseTextBuffer* buffer,
-                                    const char* indent,
-                                    int width) const {
-  const char* sub_indent = OS::SCreate(zone, "%s%s", indent, kExtraIndent);
-  TextBuffer single_line(width);
-
-  buffer->AddChar('{');
-  auto it = ExtraIterator();
-  while (auto kv = it.Next()) {
-    const intptr_t old_length = buffer->length();
-    buffer->Printf("\n%s%s", sub_indent, kv->key);
-    const intptr_t remaining = width - (buffer->length() - old_length + 1);
-    HandleLineBreaking(zone, buffer, kv->value, &single_line, sub_indent, width,
-                       /*leading_space=*/true, remaining);
-    buffer->AddChar(',');
-  }
-  buffer->Printf("\n%s}", indent);
-}
-
-void SExpList::SerializeExtraInfoToLine(BaseTextBuffer* buffer) const {
-  buffer->AddString("{");
-  auto it = ExtraIterator();
-  while (auto kv = it.Next()) {
-    buffer->Printf(" %s ", kv->key);
-    kv->value->SerializeToLine(buffer);
-    buffer->AddChar(',');
-  }
-  buffer->AddString(" }");
-}
-
-const char* const SExpParser::kBoolTrueSymbol = "true";
-const char* const SExpParser::kBoolFalseSymbol = "false";
-char const SExpParser::kDoubleExponentChar =
-    DoubleToStringConstants::kExponentChar;
-const char* const SExpParser::kDoubleInfinitySymbol =
-    DoubleToStringConstants::kInfinitySymbol;
-const char* const SExpParser::kDoubleNaNSymbol =
-    DoubleToStringConstants::kNaNSymbol;
-
-const char* const SExpParser::ErrorStrings::kOpenString =
-    "unterminated quoted string starting at position %" Pd "";
-const char* const SExpParser::ErrorStrings::kBadUnicodeEscape =
-    "malformed Unicode escape";
-const char* const SExpParser::ErrorStrings::kOpenSExpList =
-    "unterminated S-expression list starting at position %" Pd "";
-const char* const SExpParser::ErrorStrings::kOpenMap =
-    "unterminated extra info map starting at position %" Pd "";
-const char* const SExpParser::ErrorStrings::kNestedMap =
-    "extra info map start when already within extra info map";
-const char* const SExpParser::ErrorStrings::kMapOutsideList =
-    "extra info map start not within S-expression list";
-const char* const SExpParser::ErrorStrings::kNonSymbolLabel =
-    "non-symbol in label position for extra info map";
-const char* const SExpParser::ErrorStrings::kNoMapLabel =
-    "no extra info map label provided";
-const char* const SExpParser::ErrorStrings::kRepeatedMapLabel =
-    "extra info map label %s provided more than once";
-const char* const SExpParser::ErrorStrings::kNoMapValue =
-    "no value provided for extra info map label %s";
-const char* const SExpParser::ErrorStrings::kExtraMapValue =
-    "extra value following label %s in extra info map";
-const char* const SExpParser::ErrorStrings::kUnexpectedComma =
-    "comma found outside extra info map";
-const char* const SExpParser::ErrorStrings::kUnexpectedRightParen =
-    "unexpected closing parenthesis";
-const char* const SExpParser::ErrorStrings::kUnexpectedRightCurly =
-    "unexpected closing curly brace";
-
-#define PARSE_ERROR(x, ...)                                                    \
-  StoreError(x, __VA_ARGS__);                                                  \
-  return nullptr
-
-SExpression* SExpParser::Parse() {
-  Reset();
-  while (auto token = GetNextToken()) {
-    const intptr_t start_pos = token->cstr() - buffer_;
-    switch (token->type()) {
-      case kLeftParen: {
-        if (in_extra_) {
-          if (cur_label_ == nullptr) {
-            PARSE_ERROR(start_pos, ErrorStrings::kNonSymbolLabel);
-          } else if (cur_value_ != nullptr) {
-            PARSE_ERROR(start_pos, ErrorStrings::kExtraMapValue, cur_label_);
-          }
-        }
-        auto sexp = new (zone_) SExpList(zone_, start_pos);
-        list_stack_.Add(sexp);
-        in_extra_stack_.Add(in_extra_);
-        extra_start_stack_.Add(extra_start_);
-        cur_label_stack_.Add(cur_label_);
-        in_extra_ = false;
-        extra_start_ = -1;
-        cur_label_ = nullptr;
-        break;
-      }
-      case kRightParen: {
-        if (list_stack_.is_empty()) {
-          PARSE_ERROR(start_pos, ErrorStrings::kUnexpectedRightParen);
-        }
-        if (in_extra_) {
-          PARSE_ERROR(start_pos, ErrorStrings::kOpenMap, extra_start_);
-        }
-        auto sexp = list_stack_.RemoveLast();
-        in_extra_ = in_extra_stack_.RemoveLast();
-        extra_start_ = extra_start_stack_.RemoveLast();
-        cur_label_ = cur_label_stack_.RemoveLast();
-        if (list_stack_.is_empty()) return sexp;
-        if (in_extra_) {
-          if (cur_label_ == nullptr) {
-            PARSE_ERROR(start_pos, ErrorStrings::kOpenMap, extra_start_);
-          }
-          cur_value_ = sexp;
-        } else {
-          list_stack_.Last()->Add(sexp);
-        }
-        break;
-      }
-      case kLeftCurly:
-        if (in_extra_) {
-          PARSE_ERROR(start_pos, ErrorStrings::kNestedMap);
-        }
-        if (list_stack_.is_empty()) {
-          PARSE_ERROR(start_pos, ErrorStrings::kMapOutsideList);
-        }
-        extra_start_ = start_pos;
-        in_extra_ = true;
-        break;
-      case kRightCurly:
-        if (!in_extra_ || list_stack_.is_empty()) {
-          PARSE_ERROR(start_pos, ErrorStrings::kUnexpectedRightCurly);
-        }
-        if (cur_label_ != nullptr) {
-          if (cur_value_ == nullptr) {
-            PARSE_ERROR(start_pos, ErrorStrings::kNoMapValue, cur_label_);
-          }
-          list_stack_.Last()->AddExtra(cur_label_, cur_value_);
-          cur_label_ = nullptr;
-          cur_value_ = nullptr;
-        }
-        in_extra_ = false;
-        extra_start_ = -1;
-        break;
-      case kComma: {
-        if (!in_extra_ || list_stack_.is_empty()) {
-          PARSE_ERROR(start_pos, ErrorStrings::kUnexpectedComma);
-        }
-        if (cur_label_ == nullptr) {
-          PARSE_ERROR(start_pos, ErrorStrings::kNoMapLabel);
-        } else if (cur_value_ == nullptr) {
-          PARSE_ERROR(start_pos, ErrorStrings::kNoMapValue, cur_label_);
-        }
-        list_stack_.Last()->AddExtra(cur_label_, cur_value_);
-        cur_label_ = nullptr;
-        cur_value_ = nullptr;
-        break;
-      }
-      case kSymbol: {
-        auto sexp = TokenToSExpression(token);
-        ASSERT(sexp->IsSymbol());
-        if (in_extra_) {
-          if (cur_value_ != nullptr) {
-            PARSE_ERROR(start_pos, ErrorStrings::kExtraMapValue, cur_label_);
-          }
-          if (cur_label_ == nullptr) {
-            const char* const label = sexp->AsSymbol()->value();
-            if (list_stack_.Last()->ExtraHasKey(label)) {
-              PARSE_ERROR(start_pos, ErrorStrings::kRepeatedMapLabel, label);
-            }
-            cur_label_ = sexp->AsSymbol()->value();
-          } else {
-            cur_value_ = sexp;
-          }
-        } else if (!list_stack_.is_empty()) {
-          list_stack_.Last()->Add(sexp);
-        } else {
-          return sexp;
-        }
-        break;
-      }
-      case kBoolean:
-      case kInteger:
-      case kDouble:
-      case kQuotedString: {
-        auto sexp = TokenToSExpression(token);
-        // TokenToSExpression has already set the error info, so just return.
-        if (sexp == nullptr) return nullptr;
-        if (in_extra_) {
-          if (cur_label_ == nullptr) {
-            PARSE_ERROR(start_pos, ErrorStrings::kNonSymbolLabel);
-          } else if (cur_value_ != nullptr) {
-            PARSE_ERROR(start_pos, ErrorStrings::kExtraMapValue, cur_label_);
-          }
-          cur_value_ = sexp;
-        } else if (!list_stack_.is_empty()) {
-          list_stack_.Last()->Add(sexp);
-        } else {
-          return sexp;
-        }
-        break;
-      }
-      default:
-        UNREACHABLE();
-    }
-  }
-  if (in_extra_) {
-    PARSE_ERROR(buffer_size_, ErrorStrings::kOpenMap, extra_start_);
-  } else if (!list_stack_.is_empty()) {
-    const intptr_t list_start = list_stack_.Last()->start();
-    PARSE_ERROR(buffer_size_, ErrorStrings::kOpenSExpList, list_start);
-  }
-  UNREACHABLE();
-}
-
-SExpression* SExpParser::TokenToSExpression(Token* token) {
-  const intptr_t start_pos = token->cstr() - buffer_;
-  switch (token->type()) {
-    case kSymbol:
-      return new (zone_) SExpSymbol(token->ToCString(zone_), start_pos);
-    case kInteger: {
-      const char* cstr = token->ToCString(zone_);
-      int64_t val;
-      if (!OS::StringToInt64(cstr, &val)) return nullptr;
-      return new (zone_) SExpInteger(val, start_pos);
-    }
-    case kBoolean: {
-      const bool is_true =
-          strncmp(token->cstr(), kBoolTrueSymbol, token->length()) == 0;
-      ASSERT(is_true ||
-             strncmp(token->cstr(), kBoolFalseSymbol, token->length()) == 0);
-      return new (zone_) SExpBool(is_true, start_pos);
-    }
-    case kDouble: {
-      double val;
-      if (!CStringToDouble(token->cstr(), token->length(), &val)) {
-        return nullptr;
-      }
-      return new (zone_) SExpDouble(val, start_pos);
-    }
-    case kQuotedString: {
-      const char* const cstr = token->cstr();
-      char* const buf = zone_->Alloc<char>(token->length());
-      // Skip the initial quote
-      ASSERT(cstr[0] == '"');
-      intptr_t old_pos = 1;
-      intptr_t new_pos = 0;
-      // The string _should_ end in a quote.
-      while (old_pos < token->length() - 1) {
-        if (cstr[old_pos] == '"') break;
-        if (cstr[old_pos] != '\\') {
-          buf[new_pos++] = cstr[old_pos++];
-          continue;
-        }
-        old_pos++;
-        if (old_pos >= token->length()) {
-          PARSE_ERROR(start_pos + old_pos, ErrorStrings::kOpenString,
-                      start_pos);
-        }
-        const intptr_t escape_pos = start_pos + old_pos - 1;
-        switch (cstr[old_pos]) {
-          case 'b':
-            buf[new_pos] = '\b';
-            break;
-          case 'f':
-            buf[new_pos] = '\f';
-            break;
-          case 'n':
-            buf[new_pos] = '\n';
-            break;
-          case 'r':
-            buf[new_pos] = '\r';
-            break;
-          case 't':
-            buf[new_pos] = '\t';
-            break;
-          case 'u': {
-            const intptr_t first = old_pos + 1;
-            const intptr_t last = old_pos + 4;
-            if (last >= token->length()) {
-              PARSE_ERROR(escape_pos, ErrorStrings::kBadUnicodeEscape);
-            }
-            intptr_t val = 0;
-            for (const char *cursor = cstr + first, *end = cstr + last + 1;
-                 cursor < end; cursor++) {
-              val *= 16;
-              if (!Utils::IsHexDigit(*cursor)) {
-                PARSE_ERROR(escape_pos, ErrorStrings::kBadUnicodeEscape);
-              }
-              val += Utils::HexDigitToInt(*cursor);
-            }
-            // Currently, just handle encoded ASCII instead of doing
-            // handling Unicode characters.
-            // (TextBuffer::AddEscapedString uses this for characters < 0x20.)
-            ASSERT(val <= 0x7F);
-            old_pos = last;
-            buf[new_pos] = val;
-            break;
-          }
-          default:
-            // Identity escapes.
-            buf[new_pos] = cstr[old_pos];
-            break;
-        }
-        old_pos++;
-        new_pos++;
-      }
-      if (cstr[old_pos] != '"') {
-        PARSE_ERROR(start_pos + token->length(), ErrorStrings::kOpenString,
-                    start_pos);
-      }
-      buf[new_pos] = '\0';
-      return new (zone_) SExpString(buf, start_pos);
-    }
-    default:
-      UNREACHABLE();
-  }
-}
-
-#undef PARSE_ERROR
-
-SExpParser::Token* SExpParser::GetNextToken() {
-  intptr_t start_pos = cur_pos_;
-  while (start_pos < buffer_size_) {
-    if (isspace(buffer_[start_pos]) == 0) break;
-    start_pos++;
-  }
-  if (start_pos >= buffer_size_) return nullptr;
-  const char* start = buffer_ + start_pos;
-  switch (*start) {
-    case '(':
-      cur_pos_ = start_pos + 1;
-      return new (zone_) Token(kLeftParen, start, 1);
-    case ')':
-      cur_pos_ = start_pos + 1;
-      return new (zone_) Token(kRightParen, start, 1);
-    case ',':
-      cur_pos_ = start_pos + 1;
-      return new (zone_) Token(kComma, start, 1);
-    case '{':
-      cur_pos_ = start_pos + 1;
-      return new (zone_) Token(kLeftCurly, start, 1);
-    case '}':
-      cur_pos_ = start_pos + 1;
-      return new (zone_) Token(kRightCurly, start, 1);
-    case '"': {
-      intptr_t len = 1;
-      while (start_pos + len < buffer_size_) {
-        char curr = start[len];
-        len++;  // Length should include the quote, if any.
-        if (curr == '\\') {
-          // Skip past next character (if any), since it cannot
-          // end the quoted string due to being escaped.
-          if (start_pos + len >= buffer_size_) break;
-          len++;
-          continue;
-        }
-        if (curr == '"') break;
-      }
-      cur_pos_ = start_pos + len;
-      return new (zone_) Token(kQuotedString, start, len);
-    }
-    default:
-      break;
-  }
-  intptr_t len = 0;
-  // Start number detection after possible negation sign.
-  if (start[len] == '-') {
-    len++;
-    if ((start_pos + len) >= buffer_size_) {
-      cur_pos_ = start_pos + len;
-      return new (zone_) Token(kSymbol, start, len);
-    }
-  }
-  // Keep the currently detected token type. Start off by assuming we have
-  // an integer, then fall back to doubles if we see parts appropriate for
-  // those but not integers, and fall back to symbols otherwise.
-  TokenType type = kInteger;
-  bool saw_exponent = false;
-  while ((start_pos + len) < buffer_size_) {
-    // Both numbers and symbols cannot contain these values, so we are at the
-    // end of whichever one we're in.
-    if (!IsSymbolContinue(start[len])) break;
-    if (type == kInteger && start[len] == '.') {
-      type = kDouble;
-      len++;
-      continue;
-    }
-    if (type != kSymbol && !saw_exponent && start[len] == kDoubleExponentChar) {
-      saw_exponent = true;
-      type = kDouble;
-      len++;
-      // Skip past negation in exponent if any.
-      if ((start_pos + len) < buffer_size_ && start[len] == '-') len++;
-      continue;
-    }
-    // If we find a character that can't appear in a number, then fall back
-    // to symbol-ness.
-    if (isdigit(start[len]) == 0) type = kSymbol;
-    len++;
-  }
-  cur_pos_ = start_pos + len;
-  // Skip special symbol detection if we don't have a symbol.
-  if (type != kSymbol) return new (zone_) Token(type, start, len);
-  // Check for special symbols used for booleans and certain Double values.
-  switch (len) {
-    case 3:
-      if (strncmp(start, kDoubleNaNSymbol, len) == 0) type = kDouble;
-      break;
-    case 4:
-      if (strncmp(start, kBoolTrueSymbol, len) == 0) type = kBoolean;
-      break;
-    case 5:
-      if (strncmp(start, kBoolFalseSymbol, len) == 0) type = kBoolean;
-      break;
-    case 8:
-      if (strncmp(start, kDoubleInfinitySymbol, len) == 0) type = kDouble;
-      break;
-    case 9:
-      if (start[0] == '-' &&
-          strncmp(start + 1, kDoubleInfinitySymbol, len - 1) == 0) {
-        type = kDouble;
-      }
-      break;
-    default:
-      break;
-  }
-  return new (zone_) Token(type, start, len);
-}
-
-bool SExpParser::IsSymbolContinue(char c) {
-  return (isspace(c) == 0) && c != '(' && c != ')' && c != ',' && c != '{' &&
-         c != '}' && c != '"';
-}
-
-const char* const SExpParser::Token::TokenNames[kMaxTokens] = {
-#define S_EXP_TOKEN_NAME_STRING(name) #name,
-    S_EXP_TOKEN_LIST(S_EXP_TOKEN_NAME_STRING)
-#undef S_EXP_TOKEN_NAME_STRING
-};
-
-const char* SExpParser::Token::ToCString(Zone* zone) {
-  char* const buffer = zone->Alloc<char>(len_ + 1);
-  strncpy(buffer, cstr_, len_);
-  buffer[len_] = '\0';
-  return buffer;
-}
-
-void SExpParser::Reset() {
-  cur_pos_ = 0;
-  in_extra_ = false;
-  extra_start_ = -1;
-  cur_label_ = nullptr;
-  cur_value_ = nullptr;
-  list_stack_.Clear();
-  in_extra_stack_.Clear();
-  extra_start_stack_.Clear();
-  cur_label_stack_.Clear();
-  error_pos_ = -1;
-  error_message_ = nullptr;
-}
-
-void SExpParser::StoreError(intptr_t pos, const char* format, ...) {
-  va_list args;
-  va_start(args, format);
-  const char* const message = OS::VSCreate(zone_, format, args);
-  va_end(args);
-  error_pos_ = pos;
-  error_message_ = message;
-}
-
-void SExpParser::ReportError() const {
-  ASSERT(error_message_ != nullptr);
-  ASSERT(error_pos_ >= 0);
-  OS::PrintErr("Unable to parse s-expression: %s\n", buffer_);
-  OS::PrintErr("Error at character %" Pd ": %s\n", error_pos_, error_message_);
-  OS::Abort();
-}
-
-}  // namespace dart
diff --git a/runtime/vm/compiler/backend/sexpression.h b/runtime/vm/compiler/backend/sexpression.h
deleted file mode 100644
index 6bdc36e..0000000
--- a/runtime/vm/compiler/backend/sexpression.h
+++ /dev/null
@@ -1,305 +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.
-
-#ifndef RUNTIME_VM_COMPILER_BACKEND_SEXPRESSION_H_
-#define RUNTIME_VM_COMPILER_BACKEND_SEXPRESSION_H_
-
-#if defined(DART_PRECOMPILED_RUNTIME)
-#error "AOT runtime should not use compiler sources (including header files)"
-#endif  // defined(DART_PRECOMPILED_RUNTIME)
-
-#include "platform/text_buffer.h"
-
-#include "vm/allocation.h"
-#include "vm/growable_array.h"
-#include "vm/hash_map.h"
-#include "vm/zone.h"
-
-namespace dart {
-
-#define FOR_EACH_S_EXPRESSION_ATOM(M)                                          \
-  M(Bool, bool)                                                                \
-  M(Double, double)                                                            \
-  M(Integer, int64_t)                                                          \
-  M(String, const char*)                                                       \
-  M(Symbol, const char*)
-
-#define FOR_EACH_S_EXPRESSION(M)                                               \
-  FOR_EACH_S_EXPRESSION_ATOM(M)                                                \
-  M(List, _)
-
-#define FOR_EACH_ABSTRACT_S_EXPRESSION(M) M(Atom, _)
-
-#define FORWARD_DECLARATION(name, value_type) class SExp##name;
-FOR_EACH_S_EXPRESSION(FORWARD_DECLARATION)
-FOR_EACH_ABSTRACT_S_EXPRESSION(FORWARD_DECLARATION)
-#undef FORWARD_DECLARATION
-
-// Abstract base class for S-expressions used as an intermediate form for the
-// IL serializer. These aren't true (LISP-like) S-expressions, as the atoms
-// are more restricted and the lists have extra information. Here is an
-// illustrative BNF-style grammar of the current serialized form of
-// S-expressions that includes non-whitespace literal tokens:
-//
-// <s-exp>      ::= <atom> | <list>
-// <atom>       ::= <bool> | <integer> | <string> | <symbol>
-// <list>       ::= '(' <s-exp>* <extra-info>? ')'
-// <extra-info> ::= '{' <extra-elem>* '}'
-// <extra-elem> ::= <symbol> <s-exp> ','
-//
-// Here, <string>s are double-quoted strings with backslash escaping and
-// <symbol>s are sequences of consecutive non-whitespace characters that do not
-// include commas (,), parentheses (()), curly braces ({}), or the double-quote
-// character (").
-//
-// In addition, the <extra-info> is considered a map from symbol labels to
-// S-expression values, and as such each symbol used as a key in an <extra-info>
-// block should only appear once as a key within that block.
-class SExpression : public ZoneAllocated {
- public:
-  explicit SExpression(intptr_t start = kInvalidPos) : start_(start) {}
-  virtual ~SExpression() {}
-
-  static intptr_t const kInvalidPos = -1;
-
-  static SExpression* FromCString(Zone* zone, const char* cstr);
-  const char* ToCString(Zone* zone) const;
-  intptr_t start() const { return start_; }
-
-#define S_EXPRESSION_TYPE_CHECK(name, value_type)                              \
-  bool Is##name() const { return (As##name() != nullptr); }                    \
-  SExp##name* As##name() {                                                     \
-    auto const const_this = const_cast<const SExpression*>(this);              \
-    return const_cast<SExp##name*>(const_this->As##name());                    \
-  }                                                                            \
-  virtual const SExp##name* As##name() const { return nullptr; }
-
-  FOR_EACH_S_EXPRESSION(S_EXPRESSION_TYPE_CHECK)
-  FOR_EACH_ABSTRACT_S_EXPRESSION(S_EXPRESSION_TYPE_CHECK)
-
-  virtual const char* DebugName() const = 0;
-  virtual bool Equals(SExpression* sexp) const = 0;
-  virtual void SerializeTo(Zone* zone,
-                           BaseTextBuffer* buffer,
-                           const char* indent,
-                           intptr_t width = 80) const = 0;
-  virtual void SerializeToLine(BaseTextBuffer* buffer) const = 0;
-
- private:
-  // Starting character position of the s-expression in the original
-  // serialization, if it was deserialized.
-  intptr_t const start_;
-  DISALLOW_COPY_AND_ASSIGN(SExpression);
-};
-
-class SExpAtom : public SExpression {
- public:
-  explicit SExpAtom(intptr_t start = kInvalidPos) : SExpression(start) {}
-
-  virtual const SExpAtom* AsAtom() const { return this; }
-  // No atoms have sub-elements, so they always print to a single line.
-  virtual void SerializeTo(Zone* zone,
-                           BaseTextBuffer* buffer,
-                           const char* indent,
-                           intptr_t width = 80) const {
-    SerializeToLine(buffer);
-  }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(SExpAtom);
-};
-
-#define DEFINE_S_EXPRESSION_TYPE_CHECK(name)                                   \
-  virtual const SExp##name* As##name() const { return this; }                  \
-  virtual const char* DebugName() const { return #name; }
-
-// The various concrete S-expression atom classes are thin wrappers around
-// their contained value that includes serialization and type check methods.
-#define DEFINE_S_EXPRESSION_ATOM_CLASS(name, value_type)                       \
-  class SExp##name : public SExpAtom {                                         \
-   public:                                                                     \
-    explicit SExp##name(value_type val, intptr_t start = kInvalidPos)          \
-        : SExpAtom(start), val_(val) {}                                        \
-    value_type value() const { return val_; }                                  \
-    virtual bool Equals(SExpression* sexp) const;                              \
-    bool Equals(value_type val) const;                                         \
-    virtual void SerializeToLine(BaseTextBuffer* buffer) const;                \
-    DEFINE_S_EXPRESSION_TYPE_CHECK(name)                                       \
-   private:                                                                    \
-    value_type const val_;                                                     \
-    DISALLOW_COPY_AND_ASSIGN(SExp##name);                                      \
-  };
-
-FOR_EACH_S_EXPRESSION_ATOM(DEFINE_S_EXPRESSION_ATOM_CLASS)
-
-// A list of S-expressions. Unlike normal S-expressions, an S-expression list
-// also contains a hash map kept separate from the elements, which we use for
-// extra non-argument information for IL instructions.
-class SExpList : public SExpression {
- public:
-  explicit SExpList(Zone* zone, intptr_t start = kInvalidPos)
-      : SExpression(start), contents_(zone, 2), extra_info_(zone) {}
-
-  using ExtraInfoHashMap = CStringMap<SExpression*>;
-
-  void Add(SExpression* sexp);
-  void AddExtra(const char* label, SExpression* value);
-
-  SExpression* At(intptr_t i) const { return contents_.At(i); }
-  intptr_t Length() const { return contents_.length(); }
-
-  intptr_t ExtraLength() const { return extra_info_.Length(); }
-  ExtraInfoHashMap::Iterator ExtraIterator() const {
-    return extra_info_.GetIterator();
-  }
-  bool ExtraHasKey(const char* cstr) const { return extra_info_.HasKey(cstr); }
-  SExpression* ExtraLookupValue(const char* cstr) const {
-    return extra_info_.LookupValue(cstr);
-  }
-
-  // Shortcut for retrieving the tag from a tagged list (list that contains an
-  // initial symbol). Returns nullptr if the list is not a tagged list.
-  SExpSymbol* Tag() const {
-    if (Length() == 0 || !At(0)->IsSymbol()) return nullptr;
-    return At(0)->AsSymbol();
-  }
-
-  DEFINE_S_EXPRESSION_TYPE_CHECK(List)
-  virtual bool Equals(SExpression* sexp) const;
-  virtual void SerializeTo(Zone* zone,
-                           BaseTextBuffer* buffer,
-                           const char* indent,
-                           intptr_t width = 80) const;
-  virtual void SerializeToLine(BaseTextBuffer* buffer) const;
-
- private:
-  static const char* const kElemIndent;
-  static const char* const kExtraIndent;
-
-  void SerializeExtraInfoTo(Zone* zone,
-                            BaseTextBuffer* buffer,
-                            const char* indent,
-                            int width) const;
-  void SerializeExtraInfoToLine(BaseTextBuffer* buffer) const;
-
-  ZoneGrowableArray<SExpression*> contents_;
-  ExtraInfoHashMap extra_info_;
-
-  DISALLOW_COPY_AND_ASSIGN(SExpList);
-};
-
-class SExpParser : public ValueObject {
- public:
-  SExpParser(Zone* zone, const char* cstr)
-      : SExpParser(zone, cstr, strlen(cstr)) {}
-  SExpParser(Zone* zone, const char* cstr, intptr_t len)
-      : zone_(zone),
-        buffer_(ASSERT_NOTNULL(cstr)),
-        buffer_size_(strnlen(cstr, len)),
-        cur_label_(nullptr),
-        cur_value_(nullptr),
-        list_stack_(zone, 2),
-        in_extra_stack_(zone, 2),
-        extra_start_stack_(zone, 2),
-        cur_label_stack_(zone, 2),
-        error_message_(nullptr) {}
-
-  // Constants used in serializing and deserializing S-expressions.
-  static const char* const kBoolTrueSymbol;
-  static const char* const kBoolFalseSymbol;
-  static char const kDoubleExponentChar;
-  static const char* const kDoubleInfinitySymbol;
-  static const char* const kDoubleNaNSymbol;
-
-  struct ErrorStrings : AllStatic {
-    static const char* const kOpenString;
-    static const char* const kBadUnicodeEscape;
-    static const char* const kOpenSExpList;
-    static const char* const kOpenMap;
-    static const char* const kNestedMap;
-    static const char* const kMapOutsideList;
-    static const char* const kNonSymbolLabel;
-    static const char* const kNoMapLabel;
-    static const char* const kRepeatedMapLabel;
-    static const char* const kNoMapValue;
-    static const char* const kExtraMapValue;
-    static const char* const kUnexpectedComma;
-    static const char* const kUnexpectedRightParen;
-    static const char* const kUnexpectedRightCurly;
-  };
-
-  intptr_t error_pos() const { return error_pos_; }
-  const char* error_message() const { return error_message_; }
-
-  const char* Input() const { return buffer_; }
-  SExpression* Parse();
-  DART_NORETURN void ReportError() const;
-
- private:
-#define S_EXP_TOKEN_LIST(M)                                                    \
-  M(LeftParen)                                                                 \
-  M(RightParen)                                                                \
-  M(Comma)                                                                     \
-  M(LeftCurly)                                                                 \
-  M(RightCurly)                                                                \
-  M(QuotedString)                                                              \
-  M(Integer)                                                                   \
-  M(Double)                                                                    \
-  M(Boolean)                                                                   \
-  M(Symbol)
-
-  // clang-format off
-#define DEFINE_S_EXP_TOKEN_ENUM_LINE(name) k##name,
-  enum TokenType {
-    S_EXP_TOKEN_LIST(DEFINE_S_EXP_TOKEN_ENUM_LINE)
-    kMaxTokens,
-  };
-#undef DEFINE_S_EXP_TOKEN_ENUM
-  // clang-format on
-
-  class Token : public ZoneAllocated {
-   public:
-    Token(TokenType type, const char* cstr, intptr_t len)
-        : type_(type), cstr_(cstr), len_(len) {}
-
-    TokenType type() const { return type_; }
-    intptr_t length() const { return len_; }
-    const char* cstr() const { return cstr_; }
-    const char* DebugName() const { return TokenNames[type()]; }
-    const char* ToCString(Zone* zone);
-
-   private:
-    static const char* const TokenNames[kMaxTokens];
-
-    TokenType const type_;
-    const char* const cstr_;
-    intptr_t const len_;
-  };
-
-  SExpression* TokenToSExpression(Token* token);
-  Token* GetNextToken();
-  void Reset();
-  void StoreError(intptr_t pos, const char* format, ...) PRINTF_ATTRIBUTE(3, 4);
-
-  static bool IsSymbolContinue(char c);
-
-  Zone* const zone_;
-  const char* const buffer_;
-  intptr_t const buffer_size_;
-  intptr_t cur_pos_ = 0;
-  bool in_extra_ = false;
-  intptr_t extra_start_ = -1;
-  const char* cur_label_;
-  SExpression* cur_value_;
-  ZoneGrowableArray<SExpList*> list_stack_;
-  ZoneGrowableArray<bool> in_extra_stack_;
-  ZoneGrowableArray<intptr_t> extra_start_stack_;
-  ZoneGrowableArray<const char*> cur_label_stack_;
-  intptr_t error_pos_ = -1;
-  const char* error_message_;
-};
-
-}  // namespace dart
-
-#endif  // RUNTIME_VM_COMPILER_BACKEND_SEXPRESSION_H_
diff --git a/runtime/vm/compiler/backend/sexpression_test.cc b/runtime/vm/compiler/backend/sexpression_test.cc
deleted file mode 100644
index 8c0edac..0000000
--- a/runtime/vm/compiler/backend/sexpression_test.cc
+++ /dev/null
@@ -1,355 +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.
-
-#include "vm/compiler/backend/sexpression.h"
-
-#include <cmath>
-#include "platform/assert.h"
-#include "vm/unit_test.h"
-
-namespace dart {
-
-#define EXPECT_SEXP_PARSE_ERROR(sexp, parser, pos, message)                    \
-  do {                                                                         \
-    if (sexp != nullptr) {                                                     \
-      dart::Expect(__FILE__, __LINE__)                                         \
-          .Fail("parse unexpectedly succeeded for \"%s\"", parser.Input());    \
-    }                                                                          \
-    EXPECT_EQ(pos, parser.error_pos());                                        \
-    EXPECT_STREQ(message, parser.error_message());                             \
-  } while (false);
-
-#define EXPECT_SEXP_PARSE_SUCCESS(sexp, parser)                                \
-  do {                                                                         \
-    if (sexp == nullptr) {                                                     \
-      EXPECT_NOTNULL(parser.error_message());                                  \
-      dart::Expect(__FILE__, __LINE__)                                         \
-          .Fail("parse unexpectedly failed at \"%s\": %" Pd ": %s",            \
-                parser.Input() + parser.error_pos(), parser.error_pos(),       \
-                parser.error_message());                                       \
-    }                                                                          \
-  } while (false);
-
-static const char* const shared_sexp_cstr =
-    "(def v0 (Constant 3) { type (CompileType 147 { nullable false, name "
-    "\"T{Smi}\"}), })";
-
-static void CheckDeserializedSExpParts(SExpression* sexp) {
-  EXPECT_NOTNULL(sexp);
-  EXPECT(sexp->IsList());
-  SExpList* list = sexp->AsList();
-  EXPECT_EQ(3, list->Length());
-  EXPECT_NOTNULL(list->At(0));
-  EXPECT(list->At(0)->IsSymbol());
-  EXPECT_STREQ("def", list->At(0)->AsSymbol()->value());
-  EXPECT_NOTNULL(list->At(1));
-  EXPECT(list->At(1)->IsSymbol());
-  EXPECT_STREQ("v0", list->At(1)->AsSymbol()->value());
-  EXPECT_NOTNULL(list->At(2));
-  EXPECT(list->At(2)->IsList());
-
-  SExpList* sublist = list->At(2)->AsList();
-  EXPECT_EQ(2, sublist->Length());
-  EXPECT_NOTNULL(sublist->At(0));
-  EXPECT(sublist->At(0)->IsSymbol());
-  EXPECT_STREQ("Constant", sublist->At(0)->AsSymbol()->value());
-  EXPECT_NOTNULL(sublist->At(1));
-  EXPECT(sublist->At(1)->IsInteger());
-  EXPECT_EQ(3, sublist->At(1)->AsInteger()->value());
-  EXPECT_EQ(0, sublist->ExtraLength());
-
-  EXPECT_EQ(1, list->ExtraLength());
-  EXPECT(list->ExtraHasKey("type"));
-  EXPECT(list->ExtraLookupValue("type")->IsList());
-
-  SExpList* ctype = list->ExtraLookupValue("type")->AsList();
-  EXPECT_EQ(2, ctype->Length());
-  EXPECT_NOTNULL(ctype->At(0));
-  EXPECT(ctype->At(0)->IsSymbol());
-  EXPECT_STREQ("CompileType", ctype->At(0)->AsSymbol()->value());
-  EXPECT_NOTNULL(ctype->At(1));
-  EXPECT(ctype->At(1)->IsInteger());
-  EXPECT_EQ(147, ctype->At(1)->AsInteger()->value());
-
-  EXPECT_EQ(2, ctype->ExtraLength());
-  EXPECT(ctype->ExtraHasKey("nullable"));
-  EXPECT(ctype->ExtraLookupValue("nullable")->IsBool());
-  EXPECT(!ctype->ExtraLookupValue("nullable")->AsBool()->value());
-  EXPECT(ctype->ExtraHasKey("name"));
-  EXPECT(ctype->ExtraLookupValue("name")->IsString());
-  EXPECT_STREQ(ctype->ExtraLookupValue("name")->AsString()->value(), "T{Smi}");
-}
-
-ISOLATE_UNIT_TEST_CASE(DeserializeSExp) {
-  Zone* const zone = Thread::Current()->zone();
-  SExpression* sexp = SExpression::FromCString(zone, shared_sexp_cstr);
-  CheckDeserializedSExpParts(sexp);
-
-  // Treating escaped backslash appropriately so string is terminated.
-  {
-    const char* const cstr = "(def v0 (Constant 3) { foo \"123\\\\\" })";
-    SExpParser parser(zone, cstr, strlen(cstr));
-    SExpression* const sexp = parser.Parse();
-    EXPECT_SEXP_PARSE_SUCCESS(sexp, parser);
-    EXPECT(sexp->IsList());
-    EXPECT_EQ(1, sexp->AsList()->ExtraLength());
-    EXPECT(sexp->AsList()->ExtraHasKey("foo"));
-    auto val = sexp->AsList()->ExtraLookupValue("foo");
-    EXPECT(val->IsString());
-    EXPECT_STREQ("123\\", val->AsString()->value());
-  }
-  // Valid unicode escapes are properly handled.
-  {
-    const char* const cstr =
-        "(def v0 (Constant 3) { foo \"\\u0001\\u0020\\u0054\" })";
-    SExpParser parser(zone, cstr, strlen(cstr));
-    SExpression* const sexp = parser.Parse();
-    EXPECT_SEXP_PARSE_SUCCESS(sexp, parser);
-    EXPECT(sexp->IsList());
-    EXPECT_EQ(1, sexp->AsList()->ExtraLength());
-    EXPECT(sexp->AsList()->ExtraHasKey("foo"));
-    auto val = sexp->AsList()->ExtraLookupValue("foo");
-    EXPECT(val->IsString());
-    EXPECT_STREQ("\x01 T", val->AsString()->value());
-  }
-}
-
-ISOLATE_UNIT_TEST_CASE(DeserializeSExpNumbers) {
-  Zone* const zone = Thread::Current()->zone();
-
-  // Negative integers are handled.
-  {
-    const char* const cstr = "(-4 -50 -1414243)";
-    SExpParser parser(zone, cstr, strlen(cstr));
-    SExpression* const sexp = parser.Parse();
-    EXPECT_SEXP_PARSE_SUCCESS(sexp, parser);
-    EXPECT(sexp->IsList());
-    auto list = sexp->AsList();
-    EXPECT_EQ(3, list->Length());
-    EXPECT_EQ(0, list->ExtraLength());
-    for (intptr_t i = 0; i < list->Length(); i++) {
-      EXPECT(list->At(i)->IsInteger());
-      EXPECT(list->At(i)->AsInteger()->value() < 0);
-    }
-  }
-
-  // Various decimal/exponent Doubles are appropriately handled.
-  {
-    const char* const cstr = "(1.05 0.05 .03 1e100 1e-100)";
-    SExpParser parser(zone, cstr, strlen(cstr));
-    SExpression* const sexp = parser.Parse();
-    EXPECT_SEXP_PARSE_SUCCESS(sexp, parser);
-    EXPECT(sexp->IsList());
-    auto list = sexp->AsList();
-    EXPECT_EQ(5, list->Length());
-    EXPECT_EQ(0, list->ExtraLength());
-    EXPECT(list->At(0)->IsDouble());
-    double val = list->At(0)->AsDouble()->value();
-    EXPECT(val > 1.04 && val < 1.06);
-    EXPECT(list->At(1)->IsDouble());
-    val = list->At(1)->AsDouble()->value();
-    EXPECT(val > 0.04 && val < 0.06);
-    EXPECT(list->At(2)->IsDouble());
-    val = list->At(2)->AsDouble()->value();
-    EXPECT(val > 0.02 && val < 0.04);
-    EXPECT(list->At(3)->IsDouble());
-    val = list->At(3)->AsDouble()->value();
-    EXPECT(val > 0.9e100 && val < 1.1e100);
-    EXPECT(list->At(4)->IsDouble());
-    val = list->At(4)->AsDouble()->value();
-    EXPECT(val > 0.9e-100 && val < 1.1e-100);
-  }
-
-  // Special Double symbols are appropriately handled.
-  {
-    const char* const cstr = "(NaN Infinity -Infinity)";
-    SExpParser parser(zone, cstr, strlen(cstr));
-    SExpression* const sexp = parser.Parse();
-    EXPECT_SEXP_PARSE_SUCCESS(sexp, parser);
-    EXPECT(sexp->IsList());
-    auto list = sexp->AsList();
-    EXPECT_EQ(3, list->Length());
-    EXPECT_EQ(0, list->ExtraLength());
-    EXPECT(list->At(0)->IsDouble());
-    double val = list->At(0)->AsDouble()->value();
-    EXPECT(isnan(val));
-    EXPECT(list->At(1)->IsDouble());
-    val = list->At(1)->AsDouble()->value();
-    EXPECT(val > 0.0);
-    EXPECT(isinf(val));
-    EXPECT(list->At(2)->IsDouble());
-    val = list->At(2)->AsDouble()->value();
-    EXPECT(val < 0.0);
-    EXPECT(isinf(val));
-  }
-}
-
-ISOLATE_UNIT_TEST_CASE(DeserializeSExpRoundTrip) {
-  Zone* const zone = Thread::Current()->zone();
-  SExpression* sexp = SExpression::FromCString(zone, shared_sexp_cstr);
-
-  TextBuffer buf(100);
-  sexp->SerializeTo(zone, &buf, "", 9999);
-  SExpression* round_trip = SExpression::FromCString(zone, buf.buffer());
-  CheckDeserializedSExpParts(round_trip);
-  EXPECT(sexp->Equals(round_trip));
-
-  char* const old_serialization = buf.Steal();
-  round_trip->SerializeTo(zone, &buf, "", 9999);
-  char* const new_serialization = buf.buffer();
-  EXPECT_STREQ(old_serialization, new_serialization);
-  free(old_serialization);
-}
-
-ISOLATE_UNIT_TEST_CASE(DeserializeSExpMapsJoined) {
-  Zone* const zone = Thread::Current()->zone();
-  // Same as shared_sexp_cstr except we split the map on the CompileType into
-  // two parts.
-  const char* const cstr =
-      "(def v0 (Constant 3) { type (CompileType { nullable false } 147 { name "
-      "\"T{Smi}\"}), })";
-  SExpression* sexp = SExpression::FromCString(zone, cstr);
-  CheckDeserializedSExpParts(sexp);
-}
-
-ISOLATE_UNIT_TEST_CASE(DeserializeSExpFailures) {
-  Zone* const zone = Thread::Current()->zone();
-  // Unterminated s-exp list
-  {
-    const char* const before_start = "(def v0 ";
-    const char* const after_start = "(Constant 3";
-    const char* const cstr =
-        OS::SCreate(zone, "%s%s", before_start, after_start);
-    const intptr_t start_pos = strlen(before_start);
-    const intptr_t error_pos = strlen(cstr);
-    SExpParser parser(zone, cstr, strlen(cstr));
-    SExpression* const sexp = parser.Parse();
-    const char* const expected_message =
-        OS::SCreate(zone, SExpParser::ErrorStrings::kOpenSExpList, start_pos);
-    EXPECT_SEXP_PARSE_ERROR(sexp, parser, error_pos, expected_message);
-  }
-  // Non-symbol label in map pair
-  {
-    const char* const before_error = "(def v0 (Constant 3) { ";
-    const intptr_t error_pos = strlen(before_error);
-    const char* const error = "3 4 })";
-    const char* const cstr = OS::SCreate(zone, "%s%s", before_error, error);
-    SExpParser parser(zone, cstr, strlen(cstr));
-    SExpression* const sexp = parser.Parse();
-    const char* const expected_message =
-        SExpParser::ErrorStrings::kNonSymbolLabel;
-    EXPECT_SEXP_PARSE_ERROR(sexp, parser, error_pos, expected_message);
-  }
-  // No values in a map pair
-  {
-    const char* const label = "foo";
-    const char* const before_error =
-        OS::SCreate(zone, "(def v0 (Constant 3) { %s ", label);
-    const intptr_t error_pos = strlen(before_error);
-    const char* const error = "})";
-    const char* const cstr = OS::SCreate(zone, "%s%s", before_error, error);
-    SExpParser parser(zone, cstr, strlen(cstr));
-    SExpression* const sexp = parser.Parse();
-    const char* const expected_message =
-        OS::SCreate(zone, SExpParser::ErrorStrings::kNoMapValue, label);
-    EXPECT_SEXP_PARSE_ERROR(sexp, parser, error_pos, expected_message);
-  }
-  // Multiple values in a map pair
-  {
-    const char* const label = "foo";
-    const char* const before_error =
-        OS::SCreate(zone, "(def v0 (Constant 3) { %s 4 ", label);
-    const intptr_t error_pos = strlen(before_error);
-    const char* const error = "5, })";
-    const char* const cstr = OS::SCreate(zone, "%s%s", before_error, error);
-    SExpParser parser(zone, cstr, strlen(cstr));
-    SExpression* const sexp = parser.Parse();
-    const char* const expected_message =
-        OS::SCreate(zone, SExpParser::ErrorStrings::kExtraMapValue, label);
-    EXPECT_SEXP_PARSE_ERROR(sexp, parser, error_pos, expected_message);
-  }
-  // Unterminated quoted string
-  {
-    const char* const before_string =
-        OS::SCreate(zone, "(def v0 (Constant 3) { foo ");
-    const intptr_t string_pos = strlen(before_string);
-    const char* const error = "\"abc })";
-    const char* const cstr = OS::SCreate(zone, "%s%s", before_string, error);
-    const intptr_t error_pos = strlen(cstr);
-    SExpParser parser(zone, cstr, strlen(cstr));
-    SExpression* const sexp = parser.Parse();
-    const char* const expected_message =
-        OS::SCreate(zone, SExpParser::ErrorStrings::kOpenString, string_pos);
-    EXPECT_SEXP_PARSE_ERROR(sexp, parser, error_pos, expected_message);
-  }
-  // Unterminated extra info map
-  {
-    const char* const before_map = "(def v0 (Constant 3) ";
-    const intptr_t map_pos = strlen(before_map);
-    const char* const map_start = "{ foo 3, ";
-    const char* const before_error =
-        OS::SCreate(zone, "%s%s", before_map, map_start);
-    const intptr_t error_pos = strlen(before_error);
-    const char* const error = ")";
-    const char* const cstr = OS::SCreate(zone, "%s%s", before_error, error);
-    SExpParser parser(zone, cstr, strlen(cstr));
-    SExpression* const sexp = parser.Parse();
-    const char* const expected_message =
-        OS::SCreate(zone, SExpParser::ErrorStrings::kOpenMap, map_pos);
-    EXPECT_SEXP_PARSE_ERROR(sexp, parser, error_pos, expected_message);
-  }
-  // Repeated extra info map label
-  {
-    const char* const label = "foo";
-    const char* const before_error =
-        OS::SCreate(zone, "(def v0 (Constant 3) { %s 3, ", label);
-    const intptr_t error_pos = strlen(before_error);
-    const char* const error = OS::SCreate(zone, "%s 4, })", label);
-    const char* const cstr = OS::SCreate(zone, "%s%s", before_error, error);
-    SExpParser parser(zone, cstr, strlen(cstr));
-    SExpression* const sexp = parser.Parse();
-    const char* const expected_message =
-        OS::SCreate(zone, SExpParser::ErrorStrings::kRepeatedMapLabel, label);
-    EXPECT_SEXP_PARSE_ERROR(sexp, parser, error_pos, expected_message);
-  }
-  // Unicode escape with non-hex digits.
-  {
-    const char* const before_error = "(def v0 (Constant 3) { foo \"123";
-    const intptr_t error_pos = strlen(before_error);
-    const char* const error = "\\u12FG\" })";
-    const char* const cstr = OS::SCreate(zone, "%s%s", before_error, error);
-    SExpParser parser(zone, cstr, strlen(cstr));
-    SExpression* const sexp = parser.Parse();
-    const char* const expected_message =
-        SExpParser::ErrorStrings::kBadUnicodeEscape;
-    EXPECT_SEXP_PARSE_ERROR(sexp, parser, error_pos, expected_message);
-  }
-  // Unicode escape with less than four hex digits.
-  {
-    const char* const before_error = "(def v0 (Constant 3) { foo \"123";
-    const intptr_t error_pos = strlen(before_error);
-    const char* const error = "\\u12\" })";
-    const char* const cstr = OS::SCreate(zone, "%s%s", before_error, error);
-    SExpParser parser(zone, cstr, strlen(cstr));
-    SExpression* const sexp = parser.Parse();
-    const char* const expected_message =
-        SExpParser::ErrorStrings::kBadUnicodeEscape;
-    EXPECT_SEXP_PARSE_ERROR(sexp, parser, error_pos, expected_message);
-  }
-  // Treating backslashed quote appropriately to detect unterminated string
-  {
-    const char* const before_string = "(def v0 (Constant 3) { foo ";
-    const intptr_t string_pos = strlen(before_string);
-    const char* const error = "\"123\\\" })";
-    const char* const cstr = OS::SCreate(zone, "%s%s", before_string, error);
-    const intptr_t error_pos = strlen(cstr);
-    SExpParser parser(zone, cstr, strlen(cstr));
-    SExpression* const sexp = parser.Parse();
-    const char* const expected_message =
-        OS::SCreate(zone, SExpParser::ErrorStrings::kOpenString, string_pos);
-    EXPECT_SEXP_PARSE_ERROR(sexp, parser, error_pos, expected_message);
-  }
-}
-
-}  // namespace dart
diff --git a/runtime/vm/compiler/backend/slot.cc b/runtime/vm/compiler/backend/slot.cc
index 5b814c5..75fccf8 100644
--- a/runtime/vm/compiler/backend/slot.cc
+++ b/runtime/vm/compiler/backend/slot.cc
@@ -124,7 +124,12 @@
     Slot* new_value = new Slot[kNativeSlotsCount]{
 #define NULLABLE_FIELD_FINAL                                                   \
   (IsNullableBit::encode(true) | IsImmutableBit::encode(true))
+#define NULLABLE_FIELD_FINAL_COMPRESSED                                        \
+  (IsNullableBit::encode(true) | IsImmutableBit::encode(true) |                \
+   IsCompressedBit::encode(true))
 #define NULLABLE_FIELD_VAR (IsNullableBit::encode(true))
+#define NULLABLE_FIELD_VAR_COMPRESSED                                          \
+  (IsNullableBit::encode(true) | IsCompressedBit::encode(true))
 #define DEFINE_NULLABLE_BOXED_NATIVE_FIELD(ClassName, UnderlyingType,          \
                                            FieldName, cid, mutability)         \
   Slot(Kind::k##ClassName##_##FieldName, NULLABLE_FIELD_##mutability,          \
@@ -138,7 +143,10 @@
 #undef NULLABLE_FIELD_VAR
 
 #define NONNULLABLE_FIELD_FINAL (Slot::IsImmutableBit::encode(true))
+#define NONNULLABLE_FIELD_FINAL_COMPRESSED                                     \
+  (Slot::IsImmutableBit::encode(true) | Slot::IsCompressedBit::encode(true))
 #define NONNULLABLE_FIELD_VAR (0)
+#define NONNULLABLE_FIELD_VAR_COMPRESSED (Slot::IsCompressedBit::encode(true))
 #define DEFINE_NONNULLABLE_BOXED_NATIVE_FIELD(ClassName, UnderlyingType,       \
                                               FieldName, cid, mutability)      \
   Slot(Kind::k##ClassName##_##FieldName, NONNULLABLE_FIELD_##mutability,       \
@@ -203,9 +211,10 @@
 
 const Slot& Slot::GetTypeArgumentsSlotAt(Thread* thread, intptr_t offset) {
   ASSERT(offset != Class::kNoTypeArguments);
-  return SlotCache::Instance(thread).Canonicalize(Slot(
-      Kind::kTypeArguments, IsImmutableBit::encode(true), kTypeArgumentsCid,
-      offset, ":type_arguments", /*static_type=*/nullptr, kTagged));
+  return SlotCache::Instance(thread).Canonicalize(
+      Slot(Kind::kTypeArguments, IsImmutableBit::encode(true),
+           kTypeArgumentsCid, offset, ":type_arguments",
+           /*static_type=*/nullptr, kTagged));
 }
 
 const Slot& Slot::GetTypeArgumentsSlotFor(Thread* thread, const Class& cls) {
@@ -333,7 +342,28 @@
 }
 
 CompileType Slot::ComputeCompileType() const {
-  return CompileType::CreateNullable(is_nullable(), nullable_cid());
+  // If we unboxed the slot, we may know a more precise type.
+  switch (representation()) {
+    case kUnboxedInt64:
+      if (nullable_cid() == kDynamicCid) {
+        return CompileType::Int();
+      }
+      // Might be an CID like nullable_cid == kSmiCid.
+      break;
+    case kUnboxedDouble:
+      return CompileType::FromCid(kDoubleCid);
+    case kUnboxedInt32x4:
+      return CompileType::FromCid(kInt32x4Cid);
+    case kUnboxedFloat32x4:
+      return CompileType::FromCid(kFloat32x4Cid);
+    case kUnboxedFloat64x2:
+      return CompileType::FromCid(kFloat64x2Cid);
+    default:
+      break;
+  }
+
+  return CompileType(is_nullable(), nullable_cid(),
+                     nullable_cid() == kDynamicCid ? static_type_ : nullptr);
 }
 
 const AbstractType& Slot::static_type() const {
diff --git a/runtime/vm/compiler/backend/slot.h b/runtime/vm/compiler/backend/slot.h
index 3a2a1cd..8a776de 100644
--- a/runtime/vm/compiler/backend/slot.h
+++ b/runtime/vm/compiler/backend/slot.h
@@ -52,16 +52,17 @@
 //   (i.e. initialized once at construction time and does not change after
 //   that) or like a non-final field.
 #define NULLABLE_BOXED_NATIVE_SLOTS_LIST(V)                                    \
-  V(Function, UntaggedFunction, signature, FunctionType, FINAL)                \
+  V(Function, UntaggedFunction, signature, FunctionType, FINAL_COMPRESSED)     \
   V(Context, UntaggedContext, parent, Context, FINAL)                          \
   V(Closure, UntaggedClosure, instantiator_type_arguments, TypeArguments,      \
     FINAL)                                                                     \
   V(Closure, UntaggedClosure, delayed_type_arguments, TypeArguments, FINAL)    \
   V(Closure, UntaggedClosure, function_type_arguments, TypeArguments, FINAL)   \
   V(ClosureData, UntaggedClosureData, default_type_arguments, TypeArguments,   \
-    FINAL)                                                                     \
-  V(Type, UntaggedType, arguments, TypeArguments, FINAL)                       \
-  V(FunctionType, UntaggedFunctionType, type_parameters, TypeArguments, FINAL) \
+    FINAL_COMPRESSED)                                                          \
+  V(Type, UntaggedType, arguments, TypeArguments, FINAL_COMPRESSED)            \
+  V(FunctionType, UntaggedFunctionType, type_parameters, TypeArguments,        \
+    FINAL_COMPRESSED)                                                          \
   V(WeakProperty, UntaggedWeakProperty, key, Dynamic, VAR)                     \
   V(WeakProperty, UntaggedWeakProperty, value, Dynamic, VAR)
 
@@ -83,16 +84,18 @@
   V(Closure, UntaggedClosure, function, Function, FINAL)                       \
   V(Closure, UntaggedClosure, context, Context, FINAL)                         \
   V(Closure, UntaggedClosure, hash, Context, VAR)                              \
-  V(ClosureData, UntaggedClosureData, default_type_arguments_info, Smi, FINAL) \
-  V(Function, UntaggedFunction, data, Dynamic, FINAL)                          \
-  V(FunctionType, UntaggedFunctionType, parameter_names, Array, FINAL)         \
-  V(FunctionType, UntaggedFunctionType, parameter_types, Array, FINAL)         \
+  V(Function, UntaggedFunction, data, Dynamic, FINAL_COMPRESSED)               \
+  V(FunctionType, UntaggedFunctionType, parameter_names, Array,                \
+    FINAL_COMPRESSED)                                                          \
+  V(FunctionType, UntaggedFunctionType, parameter_types, Array,                \
+    FINAL_COMPRESSED)                                                          \
   V(GrowableObjectArray, UntaggedGrowableObjectArray, length, Smi, VAR)        \
   V(GrowableObjectArray, UntaggedGrowableObjectArray, data, Array, VAR)        \
-  V(TypedDataBase, UntaggedTypedDataBase, length, Smi, FINAL)                  \
-  V(TypedDataView, UntaggedTypedDataView, offset_in_bytes, Smi, FINAL)         \
-  V(TypedDataView, UntaggedTypedDataView, data, Dynamic, FINAL)                \
-  V(String, UntaggedString, length, Smi, FINAL)                                \
+  V(TypedDataBase, UntaggedTypedDataBase, length, Smi, FINAL_COMPRESSED)       \
+  V(TypedDataView, UntaggedTypedDataView, offset_in_bytes, Smi,                \
+    FINAL_COMPRESSED)                                                          \
+  V(TypedDataView, UntaggedTypedDataView, data, Dynamic, FINAL_COMPRESSED)     \
+  V(String, UntaggedString, length, Smi, FINAL_COMPRESSED)                     \
   V(LinkedHashMap, UntaggedLinkedHashMap, index, TypedDataUint32Array, VAR)    \
   V(LinkedHashMap, UntaggedLinkedHashMap, data, Array, VAR)                    \
   V(LinkedHashMap, UntaggedLinkedHashMap, hash_mask, Smi, VAR)                 \
@@ -104,10 +107,12 @@
   V(ArgumentsDescriptor, UntaggedArray, size, Smi, FINAL)                      \
   V(PointerBase, UntaggedPointerBase, data_field, Dynamic, FINAL)              \
   V(TypeArguments, UntaggedTypeArguments, length, Smi, FINAL)                  \
-  V(TypeParameter, UntaggedTypeParameter, bound, Dynamic, FINAL)               \
-  V(TypeParameter, UntaggedTypeParameter, name, Dynamic, FINAL)                \
-  V(UnhandledException, UntaggedUnhandledException, exception, Dynamic, FINAL) \
-  V(UnhandledException, UntaggedUnhandledException, stacktrace, Dynamic, FINAL)
+  V(TypeParameter, UntaggedTypeParameter, bound, Dynamic, FINAL_COMPRESSED)    \
+  V(TypeParameter, UntaggedTypeParameter, name, Dynamic, FINAL_COMPRESSED)     \
+  V(UnhandledException, UntaggedUnhandledException, exception, Dynamic,        \
+    FINAL_COMPRESSED)                                                          \
+  V(UnhandledException, UntaggedUnhandledException, stacktrace, Dynamic,       \
+    FINAL_COMPRESSED)
 
 // List of slots that correspond to unboxed fields of native objects in the
 // following format:
@@ -125,6 +130,8 @@
 //
 // Note: As the underlying field is unboxed, these slots cannot be nullable.
 #define UNBOXED_NATIVE_SLOTS_LIST(V)                                           \
+  V(ClosureData, UntaggedClosureData, default_type_arguments_kind, Uint8,      \
+    FINAL)                                                                     \
   V(Function, UntaggedFunction, kind_tag, Uint32, FINAL)                       \
   V(Function, UntaggedFunction, packed_fields, Uint32, FINAL)                  \
   V(FunctionType, UntaggedFunctionType, packed_fields, Uint32, FINAL)          \
@@ -240,6 +247,8 @@
   // of the corresponding Dart field.
   bool is_guarded_field() const { return IsGuardedBit::decode(flags_); }
 
+  bool is_compressed() const { return IsCompressedBit::decode(flags_); }
+
   // Static type of the slots if any.
   //
   // A value that is read from the slot is guaranteed to be assignable to its
@@ -294,6 +303,7 @@
   using IsImmutableBit = BitField<int8_t, bool, 0, 1>;
   using IsNullableBit = BitField<int8_t, bool, IsImmutableBit::kNextBit, 1>;
   using IsGuardedBit = BitField<int8_t, bool, IsNullableBit::kNextBit, 1>;
+  using IsCompressedBit = BitField<int8_t, bool, IsGuardedBit::kNextBit, 1>;
 
   template <typename T>
   const T* DataAs() const {
diff --git a/runtime/vm/compiler/backend/type_propagator.cc b/runtime/vm/compiler/backend/type_propagator.cc
index dce6e90..6175f11 100644
--- a/runtime/vm/compiler/backend/type_propagator.cc
+++ b/runtime/vm/compiler/backend/type_propagator.cc
@@ -900,7 +900,7 @@
   } else if (type_ != NULL) {
     type_name = type_->IsDynamicType()
                     ? "*"
-                    : String::Handle(type_->UserVisibleName()).ToCString();
+                    : String::Handle(type_->ScrubbedName()).ToCString();
   } else if (!is_nullable()) {
     type_name = "!null";
   }
@@ -1505,21 +1505,9 @@
 }
 
 CompileType LoadFieldInstr::ComputeType() const {
-  const AbstractType& field_type = slot().static_type();
-  CompileType compile_type_cid = slot().ComputeCompileType();
-  if (field_type.ptr() == AbstractType::null()) {
-    return compile_type_cid;
-  }
-
-  const AbstractType* abstract_type = &field_type;
-  TraceStrongModeType(this, *abstract_type);
-
-  if (compile_type_cid.ToNullableCid() != kDynamicCid) {
-    abstract_type = nullptr;
-  }
-
-  return CompileType(compile_type_cid.is_nullable(),
-                     compile_type_cid.ToNullableCid(), abstract_type);
+  CompileType type = slot().ComputeCompileType();
+  TraceStrongModeType(this, &type);
+  return type;
 }
 
 CompileType LoadCodeUnitsInstr::ComputeType() const {
@@ -1595,30 +1583,6 @@
   return CompileType::Int();
 }
 
-CompileType CheckedSmiOpInstr::ComputeType() const {
-  if (left()->Type()->IsNullableInt() && right()->Type()->IsNullableInt()) {
-    const AbstractType& abstract_type =
-        AbstractType::ZoneHandle(Type::IntType());
-    TraceStrongModeType(this, abstract_type);
-    return CompileType::FromAbstractType(abstract_type,
-                                         CompileType::kNonNullable);
-  } else {
-    CompileType* type = call()->Type();
-    TraceStrongModeType(this, type);
-    return *type;
-  }
-}
-
-bool CheckedSmiOpInstr::RecomputeType() {
-  return UpdateType(ComputeType());
-}
-
-CompileType CheckedSmiComparisonInstr::ComputeType() const {
-  CompileType* type = call()->Type();
-  TraceStrongModeType(this, type);
-  return *type;
-}
-
 CompileType BoxIntegerInstr::ComputeType() const {
   return ValueFitsSmi() ? CompileType::FromCid(kSmiCid) : CompileType::Int();
 }
diff --git a/runtime/vm/compiler/backend/typed_data_aot_test.cc b/runtime/vm/compiler/backend/typed_data_aot_test.cc
index 68bca62..557139a 100644
--- a/runtime/vm/compiler/backend/typed_data_aot_test.cc
+++ b/runtime/vm/compiler/backend/typed_data_aot_test.cc
@@ -208,8 +208,6 @@
           kMatchAndMoveLoadIndexed,
           kMoveGlob,
           // Store 1
-          kMatchAndMoveGenericCheckBound,
-          kMoveGlob,
           kMoveParallelMoves,
           kMatchAndMoveLoadUntagged,
           kMoveParallelMoves,
@@ -253,8 +251,6 @@
           kMatchAndMoveLoadIndexed,
           kMoveGlob,
           // Store 1
-          kMatchAndMoveGenericCheckBound,
-          kMoveGlob,
           kMoveParallelMoves,
           kMatchAndMoveLoadUntagged,
           kMoveParallelMoves,
diff --git a/runtime/vm/compiler/call_specializer.cc b/runtime/vm/compiler/call_specializer.cc
index 4791955..e33e569 100644
--- a/runtime/vm/compiler/call_specializer.cc
+++ b/runtime/vm/compiler/call_specializer.cc
@@ -111,16 +111,7 @@
   }
 
   const Token::Kind op_kind = call->token_kind();
-  if (FLAG_guess_icdata_cid) {
-    if (CompilerState::Current().is_aot()) {
-      // In precompiler speculate that both sides of bitwise operation
-      // are Smi-s.
-      if (Token::IsBinaryBitwiseOperator(op_kind) &&
-          call->CanReceiverBeSmiBasedOnInterfaceTarget(zone())) {
-        class_ids[0] = kSmiCid;
-        class_ids[1] = kSmiCid;
-      }
-    }
+  if (FLAG_guess_icdata_cid && !CompilerState::Current().is_aot()) {
     if (Token::IsRelationalOperator(op_kind) ||
         Token::IsEqualityOperator(op_kind) ||
         Token::IsBinaryOperator(op_kind)) {
@@ -401,8 +392,7 @@
                                        call->source()),
                  call->env(), FlowGraph::kEffect);
     cid = kSmiCid;
-  } else if (binary_feedback.OperandsAreSmiOrMint() &&
-             FlowGraphCompiler::SupportsUnboxedInt64()) {
+  } else if (binary_feedback.OperandsAreSmiOrMint()) {
     cid = kMintCid;
   } else if (binary_feedback.OperandsAreSmiOrDouble() && CanUnboxDouble()) {
     // Use double comparison.
@@ -477,8 +467,7 @@
                                        call->source()),
                  call->env(), FlowGraph::kEffect);
     cid = kSmiCid;
-  } else if (binary_feedback.OperandsAreSmiOrMint() &&
-             FlowGraphCompiler::SupportsUnboxedInt64()) {
+  } else if (binary_feedback.OperandsAreSmiOrMint()) {
     cid = kMintCid;
   } else if (binary_feedback.OperandsAreSmiOrDouble() && CanUnboxDouble()) {
     // Use double comparison.
@@ -525,8 +514,7 @@
             call->ic_data()->HasDeoptReason(ICData::kDeoptBinarySmiOp)
                 ? kMintCid
                 : kSmiCid;
-      } else if (binary_feedback.OperandsAreSmiOrMint() &&
-                 FlowGraphCompiler::SupportsUnboxedInt64()) {
+      } else if (binary_feedback.OperandsAreSmiOrMint()) {
         // Don't generate mint code if the IC data is marked because of an
         // overflow.
         if (call->ic_data()->HasDeoptReason(ICData::kDeoptBinaryInt64Op))
@@ -638,7 +626,6 @@
                             call->deopt_id(), call->source());
     ReplaceCall(call, double_bin_op);
   } else if (operands_type == kMintCid) {
-    if (!FlowGraphCompiler::SupportsUnboxedInt64()) return false;
     if ((op_kind == Token::kSHL) || (op_kind == Token::kSHR) ||
         (op_kind == Token::kUSHR)) {
       SpeculativeShiftInt64OpInstr* shift_op = new (Z)
@@ -715,8 +702,7 @@
     unary_op = new (Z)
         UnarySmiOpInstr(op_kind, new (Z) Value(input), call->deopt_id());
   } else if ((op_kind == Token::kBIT_NOT) &&
-             call->Targets().ReceiverIsSmiOrMint() &&
-             FlowGraphCompiler::SupportsUnboxedInt64()) {
+             call->Targets().ReceiverIsSmiOrMint()) {
     unary_op = new (Z)
         UnaryInt64OpInstr(op_kind, new (Z) Value(input), call->deopt_id());
   } else if (call->Targets().ReceiverIs(kDoubleCid) &&
diff --git a/runtime/vm/compiler/compiler_pass.cc b/runtime/vm/compiler/compiler_pass.cc
index 2a6f91f..1dfcdce 100644
--- a/runtime/vm/compiler/compiler_pass.cc
+++ b/runtime/vm/compiler/compiler_pass.cc
@@ -8,9 +8,7 @@
 #include "vm/compiler/backend/branch_optimizer.h"
 #include "vm/compiler/backend/constant_propagator.h"
 #include "vm/compiler/backend/flow_graph_checker.h"
-#include "vm/compiler/backend/il_deserializer.h"
 #include "vm/compiler/backend/il_printer.h"
-#include "vm/compiler/backend/il_serializer.h"
 #include "vm/compiler/backend/inliner.h"
 #include "vm/compiler/backend/linearscan.h"
 #include "vm/compiler/backend/range_analysis.h"
@@ -80,14 +78,6 @@
                       "List of comma separated compilation passes flags. "
                       "Use -Name to disable a pass, Name to print IL after it. "
                       "Do --compiler-passes=help for more information.");
-DEFINE_FLAG(bool,
-            early_round_trip_serialization,
-            false,
-            "Perform early round trip serialization compiler pass.");
-DEFINE_FLAG(bool,
-            late_round_trip_serialization,
-            false,
-            "Perform late round trip serialization compiler pass.");
 DECLARE_FLAG(bool, print_flow_graph);
 DECLARE_FLAG(bool, print_flow_graph_optimized);
 
@@ -286,9 +276,6 @@
     PipelineMode mode,
     CompilerPassState* pass_state) {
   INVOKE_PASS(ComputeSSA);
-  if (FLAG_early_round_trip_serialization) {
-    INVOKE_PASS(RoundTripSerialization);
-  }
   INVOKE_PASS(SetOuterInliningId);
   INVOKE_PASS(TypePropagation);
   INVOKE_PASS(Canonicalize);
@@ -309,10 +296,6 @@
   INVOKE_PASS_AOT(DelayAllocations);
   INVOKE_PASS(EliminateWriteBarriers);
   INVOKE_PASS(FinalizeGraph);
-  INVOKE_PASS_AOT(SerializeGraph);
-  if (FLAG_late_round_trip_serialization) {
-    INVOKE_PASS(RoundTripSerialization);
-  }
   INVOKE_PASS(AllocateRegisters);
   INVOKE_PASS(ReorderBlocks);
   return pass_state->flow_graph();
@@ -321,9 +304,6 @@
 FlowGraph* CompilerPass::RunPipeline(PipelineMode mode,
                                      CompilerPassState* pass_state) {
   INVOKE_PASS(ComputeSSA);
-  if (FLAG_early_round_trip_serialization) {
-    INVOKE_PASS(RoundTripSerialization);
-  }
   INVOKE_PASS_AOT(ApplyClassIds);
   INVOKE_PASS_AOT(TypePropagation);
   INVOKE_PASS(ApplyICData);
@@ -382,12 +362,6 @@
   INVOKE_PASS(AllocationSinking_DetachMaterializations);
   INVOKE_PASS(EliminateWriteBarriers);
   INVOKE_PASS(FinalizeGraph);
-  // If we are serializing the flow graph, do it now before we start
-  // doing register allocation.
-  INVOKE_PASS_AOT(SerializeGraph);
-  if (FLAG_late_round_trip_serialization) {
-    INVOKE_PASS(RoundTripSerialization);
-  }
   INVOKE_PASS(AllocateRegisters);
   INVOKE_PASS(ReorderBlocks);
   return pass_state->flow_graph();
@@ -576,27 +550,4 @@
   flow_graph->RemoveRedefinitions();
 });
 
-#if defined(DART_PRECOMPILER)
-COMPILER_PASS(SerializeGraph, {
-  if (state->precompiler == nullptr) return false;
-  if (auto stream = state->precompiler->il_serialization_stream()) {
-    auto file_write = Dart::file_write_callback();
-    ASSERT(file_write != nullptr);
-
-    const intptr_t kInitialBufferSize = 1 * MB;
-    TextBuffer buffer(kInitialBufferSize);
-    StackZone stack_zone(Thread::Current());
-    FlowGraphSerializer::SerializeToBuffer(stack_zone.GetZone(), flow_graph,
-                                           &buffer);
-
-    file_write(buffer.buffer(), buffer.length(), stream);
-  }
-});
-#endif
-
-COMPILER_PASS(RoundTripSerialization, {
-  FlowGraphDeserializer::RoundTripSerialization(state);
-  ASSERT(state->flow_graph() != nullptr);
-})
-
 }  // namespace dart
diff --git a/runtime/vm/compiler/compiler_pass.h b/runtime/vm/compiler/compiler_pass.h
index 1904561..39dc9bd 100644
--- a/runtime/vm/compiler/compiler_pass.h
+++ b/runtime/vm/compiler/compiler_pass.h
@@ -44,9 +44,7 @@
   V(OptimizeTypedDataAccesses)                                                 \
   V(RangeAnalysis)                                                             \
   V(ReorderBlocks)                                                             \
-  V(RoundTripSerialization)                                                    \
   V(SelectRepresentations)                                                     \
-  V(SerializeGraph)                                                            \
   V(SetOuterInliningId)                                                        \
   V(TryCatchOptimization)                                                      \
   V(TryOptimizePatterns)                                                       \
diff --git a/runtime/vm/compiler/compiler_sources.gni b/runtime/vm/compiler/compiler_sources.gni
index edfa863..9135f50 100644
--- a/runtime/vm/compiler/compiler_sources.gni
+++ b/runtime/vm/compiler/compiler_sources.gni
@@ -57,13 +57,9 @@
   "backend/il.h",
   "backend/il_arm.cc",
   "backend/il_arm64.cc",
-  "backend/il_deserializer.cc",
-  "backend/il_deserializer.h",
   "backend/il_ia32.cc",
   "backend/il_printer.cc",
   "backend/il_printer.h",
-  "backend/il_serializer.cc",
-  "backend/il_serializer.h",
   "backend/il_x64.cc",
   "backend/inliner.cc",
   "backend/inliner.h",
@@ -79,8 +75,6 @@
   "backend/range_analysis.h",
   "backend/redundancy_elimination.cc",
   "backend/redundancy_elimination.h",
-  "backend/sexpression.cc",
-  "backend/sexpression.h",
   "backend/slot.cc",
   "backend/slot.h",
   "backend/type_propagator.cc",
@@ -166,6 +160,7 @@
   "assembler/disassembler_test.cc",
   "backend/bce_test.cc",
   "backend/constant_propagator_test.cc",
+  "backend/flow_graph_test.cc",
   "backend/il_test.cc",
   "backend/il_test_helper.h",
   "backend/il_test_helper.cc",
@@ -175,7 +170,6 @@
   "backend/range_analysis_test.cc",
   "backend/reachability_fence_test.cc",
   "backend/redundancy_elimination_test.cc",
-  "backend/sexpression_test.cc",
   "backend/slot_test.cc",
   "backend/type_propagator_test.cc",
   "backend/typed_data_aot_test.cc",
diff --git a/runtime/vm/compiler/ffi/native_type.cc b/runtime/vm/compiler/ffi/native_type.cc
index 19a2ace..cd4cbbb 100644
--- a/runtime/vm/compiler/ffi/native_type.cc
+++ b/runtime/vm/compiler/ffi/native_type.cc
@@ -399,12 +399,21 @@
              .Equals(Symbols::FfiStructLayout()));
   ASSERT(String::Handle(zone, library.url()).Equals(Symbols::DartFfi()));
   const auto& struct_layout_fields = Array::Handle(zone, clazz.fields());
-  ASSERT(struct_layout_fields.Length() == 1);
-  const auto& field =
+  ASSERT(struct_layout_fields.Length() == 2);
+  const auto& types_field =
       Field::Handle(zone, Field::RawCast(struct_layout_fields.At(0)));
-  ASSERT(String::Handle(zone, field.name()).Equals(Symbols::FfiFieldTypes()));
+  ASSERT(String::Handle(zone, types_field.name())
+             .Equals(Symbols::FfiFieldTypes()));
   const auto& field_types =
-      Array::Handle(zone, Array::RawCast(struct_layout.GetField(field)));
+      Array::Handle(zone, Array::RawCast(struct_layout.GetField(types_field)));
+  const auto& packed_field =
+      Field::Handle(zone, Field::RawCast(struct_layout_fields.At(1)));
+  ASSERT(String::Handle(zone, packed_field.name())
+             .Equals(Symbols::FfiFieldPacking()));
+  const auto& packed_value = Integer::Handle(
+      zone, Integer::RawCast(struct_layout.GetField(packed_field)));
+  const intptr_t member_packing =
+      packed_value.IsNull() ? kMaxInt32 : packed_value.AsInt64Value();
 
   auto& field_instance = Instance::Handle(zone);
   auto& field_type = AbstractType::Handle(zone);
@@ -445,7 +454,8 @@
     }
   }
 
-  return NativeCompoundType::FromNativeTypes(zone, field_native_types);
+  return NativeCompoundType::FromNativeTypes(zone, field_native_types,
+                                             member_packing);
 }
 #endif
 
@@ -736,23 +746,32 @@
 }
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
-bool NativePrimitiveType::ContainsUnalignedMembers() const {
+bool NativePrimitiveType::ContainsUnalignedMembers(intptr_t offset) const {
+  return offset % AlignmentInBytesField() != 0;
+}
+
+bool NativeArrayType::ContainsUnalignedMembers(intptr_t offset) const {
+  const intptr_t element_size = element_type_.SizeInBytes();
+  // We're only checking the first two elements of the array.
+  //
+  // If the element size is divisible by the alignment of the largest type
+  // contained within the element type, the alignment of all elements is the
+  // same. If not, either the first or the second element is unaligned.
+  const intptr_t max_check = 2;
+  for (intptr_t i = 0; i < Utils::Minimum(length_, max_check); i++) {
+    const intptr_t element_offset = i * element_size;
+    if (element_type_.ContainsUnalignedMembers(offset + element_offset)) {
+      return true;
+    }
+  }
   return false;
 }
 
-bool NativeArrayType::ContainsUnalignedMembers() const {
-  return element_type_.ContainsUnalignedMembers();
-}
-
-bool NativeCompoundType::ContainsUnalignedMembers() const {
+bool NativeCompoundType::ContainsUnalignedMembers(intptr_t offset) const {
   for (intptr_t i = 0; i < members_.length(); i++) {
     const auto& member = *members_.At(i);
     const intptr_t member_offset = member_offsets_.At(i);
-    const intptr_t member_alignment = member.AlignmentInBytesField();
-    if (member_offset % member_alignment != 0) {
-      return true;
-    }
-    if (member.ContainsUnalignedMembers()) {
+    if (member.ContainsUnalignedMembers(offset + member_offset)) {
       return true;
     }
   }
diff --git a/runtime/vm/compiler/ffi/native_type.h b/runtime/vm/compiler/ffi/native_type.h
index 8fbcbc5..e7a156e 100644
--- a/runtime/vm/compiler/ffi/native_type.h
+++ b/runtime/vm/compiler/ffi/native_type.h
@@ -98,7 +98,7 @@
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
   // True iff any members are misaligned recursively due to packing.
-  virtual bool ContainsUnalignedMembers() const = 0;
+  virtual bool ContainsUnalignedMembers(intptr_t offset = 0) const = 0;
 
 #if !defined(DART_PRECOMPILED_RUNTIME) && !defined(FFI_UNIT_TESTS)
   // NativeTypes which are available as unboxed Representations.
@@ -188,7 +188,7 @@
   virtual bool ContainsOnlyFloats(Range range) const;
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
-  virtual bool ContainsUnalignedMembers() const;
+  virtual bool ContainsUnalignedMembers(intptr_t offset = 0) const;
 
 #if !defined(DART_PRECOMPILED_RUNTIME) && !defined(FFI_UNIT_TESTS)
   virtual bool IsExpressibleAsRepresentation() const;
@@ -239,7 +239,7 @@
   virtual bool ContainsOnlyFloats(Range range) const;
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
-  virtual bool ContainsUnalignedMembers() const;
+  virtual bool ContainsUnalignedMembers(intptr_t offset = 0) const;
 
   virtual bool Equals(const NativeType& other) const;
 
@@ -298,7 +298,7 @@
   intptr_t NumberOfWordSizeChunksNotOnlyFloat() const;
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
-  virtual bool ContainsUnalignedMembers() const;
+  virtual bool ContainsUnalignedMembers(intptr_t offset = 0) const;
 
   // Whether this type has only same-size floating point members.
   //
diff --git a/runtime/vm/compiler/ffi/native_type_test.cc b/runtime/vm/compiler/ffi/native_type_test.cc
index d6d5ece..63cc7b4 100644
--- a/runtime/vm/compiler/ffi/native_type_test.cc
+++ b/runtime/vm/compiler/ffi/native_type_test.cc
@@ -214,6 +214,61 @@
   EXPECT(struct_type.ContainsUnalignedMembers());
 }
 
+UNIT_TEST_CASE_WITH_ZONE(NativeCompoundType_packed_array) {
+  const auto& uint8_type = *new (Z) NativePrimitiveType(kUint8);
+  const auto& uint16_type = *new (Z) NativePrimitiveType(kUint16);
+
+  auto& inner_members = *new (Z) NativeTypes(Z, 2);
+  inner_members.Add(&uint16_type);
+  inner_members.Add(&uint8_type);
+  const intptr_t packing = 1;
+  const auto& inner_struct_type =
+      NativeCompoundType::FromNativeTypes(Z, inner_members, packing);
+
+  EXPECT_EQ(3, inner_struct_type.SizeInBytes());
+  // Non-windows x64 considers this struct as all members aligned, even though
+  // its size is not a multiple of its individual member alignment.
+  EXPECT(!inner_struct_type.ContainsUnalignedMembers());
+
+  const auto& array_type = *new (Z) NativeArrayType(inner_struct_type, 2);
+
+  auto& members = *new (Z) NativeTypes(Z, 1);
+  members.Add(&array_type);
+  const auto& struct_type = NativeCompoundType::FromNativeTypes(Z, members);
+
+  EXPECT_EQ(6, struct_type.SizeInBytes());
+  // Non-windows x64 passes this as a struct with unaligned members, because
+  // the second element of the array contains unaligned members.
+  EXPECT(struct_type.ContainsUnalignedMembers());
+}
+
+UNIT_TEST_CASE_WITH_ZONE(NativeCompoundType_packed_nested) {
+  const auto& uint8_type = *new (Z) NativePrimitiveType(kUint8);
+  const auto& uint32_type = *new (Z) NativePrimitiveType(kUint32);
+
+  auto& inner_members = *new (Z) NativeTypes(Z, 2);
+  inner_members.Add(&uint32_type);
+  inner_members.Add(&uint8_type);
+  const intptr_t packing = 1;
+  const auto& inner_struct_type =
+      NativeCompoundType::FromNativeTypes(Z, inner_members, packing);
+
+  EXPECT_EQ(5, inner_struct_type.SizeInBytes());
+  // Non-windows x64 considers this struct as all members aligned, even though
+  // its size is not a multiple of its individual member alignment.
+  EXPECT(!inner_struct_type.ContainsUnalignedMembers());
+
+  auto& members = *new (Z) NativeTypes(Z, 2);
+  members.Add(&uint8_type);
+  members.Add(&inner_struct_type);
+  const auto& struct_type = NativeCompoundType::FromNativeTypes(Z, members);
+
+  EXPECT_EQ(6, struct_type.SizeInBytes());
+  // Non-windows x64 passes this as a struct with unaligned members, even
+  // though the nested struct itself has all its members aligned in isolation.
+  EXPECT(struct_type.ContainsUnalignedMembers());
+}
+
 }  // namespace ffi
 }  // namespace compiler
 }  // namespace dart
diff --git a/runtime/vm/compiler/ffi/recognized_method.cc b/runtime/vm/compiler/ffi/recognized_method.cc
index f13f041..6900a83 100644
--- a/runtime/vm/compiler/ffi/recognized_method.cc
+++ b/runtime/vm/compiler/ffi/recognized_method.cc
@@ -57,6 +57,31 @@
     CLASS_LIST_FFI_NUMERIC(LOAD_STORE)
     LOAD_STORE(Pointer)
 #undef LOAD_STORE
+    case MethodRecognizer::kFfiLoadFloatUnaligned:
+    case MethodRecognizer::kFfiStoreFloatUnaligned:
+      return kFfiFloatCid;
+    case MethodRecognizer::kFfiLoadDoubleUnaligned:
+    case MethodRecognizer::kFfiStoreDoubleUnaligned:
+      return kFfiDoubleCid;
+    default:
+      UNREACHABLE();
+  }
+}
+
+AlignmentType RecognizedMethodAlignment(MethodRecognizer::Kind kind) {
+  switch (kind) {
+#define LOAD_STORE(type)                                                       \
+  case MethodRecognizer::kFfiLoad##type:                                       \
+  case MethodRecognizer::kFfiStore##type:                                      \
+    return kAlignedAccess;
+    CLASS_LIST_FFI_NUMERIC(LOAD_STORE)
+    LOAD_STORE(Pointer)
+#undef LOAD_STORE
+    case MethodRecognizer::kFfiLoadFloatUnaligned:
+    case MethodRecognizer::kFfiStoreFloatUnaligned:
+    case MethodRecognizer::kFfiLoadDoubleUnaligned:
+    case MethodRecognizer::kFfiStoreDoubleUnaligned:
+      return kUnalignedAccess;
     default:
       UNREACHABLE();
   }
diff --git a/runtime/vm/compiler/ffi/recognized_method.h b/runtime/vm/compiler/ffi/recognized_method.h
index 8cbfca8..993306e 100644
--- a/runtime/vm/compiler/ffi/recognized_method.h
+++ b/runtime/vm/compiler/ffi/recognized_method.h
@@ -11,6 +11,7 @@
 
 #include <platform/globals.h>
 
+#include "vm/compiler/backend/il.h"
 #include "vm/compiler/method_recognizer.h"
 
 namespace dart {
@@ -25,6 +26,8 @@
 // Returns the kFFi<type>Cid for the recognized load/store method [kind].
 classid_t RecognizedMethodTypeArgCid(MethodRecognizer::Kind kind);
 
+AlignmentType RecognizedMethodAlignment(MethodRecognizer::Kind kind);
+
 }  // namespace ffi
 
 }  // namespace compiler
diff --git a/runtime/vm/compiler/frontend/base_flow_graph_builder.cc b/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
index a106f1e..ecdb481 100644
--- a/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
+++ b/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
@@ -370,7 +370,8 @@
 
 Fragment BaseFlowGraphBuilder::LoadIndexed(classid_t class_id,
                                            intptr_t index_scale,
-                                           bool index_unboxed) {
+                                           bool index_unboxed,
+                                           AlignmentType alignment) {
   Value* index = Pop();
   // A C pointer if index_unboxed, otherwise a boxed Dart value.
   Value* array = Pop();
@@ -379,7 +380,7 @@
   // all cases.
   LoadIndexedInstr* instr = new (Z)
       LoadIndexedInstr(array, index, index_unboxed, index_scale, class_id,
-                       kAlignedAccess, DeoptId::kNone, InstructionSource());
+                       alignment, DeoptId::kNone, InstructionSource());
   Push(instr);
   return Fragment(instr);
 }
@@ -636,10 +637,8 @@
 
 Fragment BaseFlowGraphBuilder::StoreIndexedTypedData(classid_t class_id,
                                                      intptr_t index_scale,
-                                                     bool index_unboxed) {
-  // We use C behavior when dereferencing pointers, we assume alignment.
-  const AlignmentType alignment = kAlignedAccess;
-
+                                                     bool index_unboxed,
+                                                     AlignmentType alignment) {
   Value* value = Pop();
   Value* index = Pop();
   Value* c_pointer = Pop();
@@ -897,8 +896,8 @@
 
 Fragment BaseFlowGraphBuilder::AllocateContext(
     const ZoneGrowableArray<const Slot*>& context_slots) {
-  AllocateContextInstr* allocate =
-      new (Z) AllocateContextInstr(InstructionSource(), context_slots);
+  AllocateContextInstr* allocate = new (Z) AllocateContextInstr(
+      InstructionSource(), context_slots, GetNextDeoptId());
   Push(allocate);
   return Fragment(allocate);
 }
@@ -907,8 +906,8 @@
     TokenPosition position,
     const Function& closure_function) {
   const Class& cls = Class::ZoneHandle(Z, IG->object_store()->closure_class());
-  AllocateObjectInstr* allocate =
-      new (Z) AllocateObjectInstr(InstructionSource(position), cls);
+  AllocateObjectInstr* allocate = new (Z)
+      AllocateObjectInstr(InstructionSource(position), cls, GetNextDeoptId());
   allocate->set_closure_function(closure_function);
   Push(allocate);
   return Fragment(allocate);
@@ -984,8 +983,8 @@
                                               intptr_t argument_count) {
   ASSERT((argument_count == 0) || (argument_count == 1));
   Value* type_arguments = (argument_count > 0) ? Pop() : nullptr;
-  AllocateObjectInstr* allocate = new (Z)
-      AllocateObjectInstr(InstructionSource(position), klass, type_arguments);
+  AllocateObjectInstr* allocate = new (Z) AllocateObjectInstr(
+      InstructionSource(position), klass, GetNextDeoptId(), type_arguments);
   Push(allocate);
   return Fragment(allocate);
 }
diff --git a/runtime/vm/compiler/frontend/base_flow_graph_builder.h b/runtime/vm/compiler/frontend/base_flow_graph_builder.h
index 50e198a..917e820 100644
--- a/runtime/vm/compiler/frontend/base_flow_graph_builder.h
+++ b/runtime/vm/compiler/frontend/base_flow_graph_builder.h
@@ -167,7 +167,8 @@
   // Pass true for index_unboxed if indexing into external typed data.
   Fragment LoadIndexed(classid_t class_id,
                        intptr_t index_scale = compiler::target::kWordSize,
-                       bool index_unboxed = false);
+                       bool index_unboxed = false,
+                       AlignmentType alignment = kAlignedAccess);
 
   Fragment LoadUntagged(intptr_t offset);
   Fragment StoreUntagged(intptr_t offset);
@@ -213,7 +214,8 @@
   // Takes a [class_id] valid for StoreIndexed.
   Fragment StoreIndexedTypedData(classid_t class_id,
                                  intptr_t index_scale,
-                                 bool index_unboxed);
+                                 bool index_unboxed,
+                                 AlignmentType alignment = kAlignedAccess);
 
   // Sign-extends kUnboxedInt32 and zero-extends kUnboxedUint32.
   Fragment Box(Representation from);
@@ -432,8 +434,7 @@
 
   // Returns whether this function has a saved arguments descriptor array.
   bool has_saved_args_desc_array() {
-    return function_.IsInvokeFieldDispatcher() ||
-           function_.IsNoSuchMethodDispatcher();
+    return function_.HasSavedArgumentsDescriptor();
   }
 
   // Returns the saved arguments descriptor array for functions that have them.
diff --git a/runtime/vm/compiler/frontend/constant_reader.cc b/runtime/vm/compiler/frontend/constant_reader.cc
index f968c45..b75d8cb 100644
--- a/runtime/vm/compiler/frontend/constant_reader.cc
+++ b/runtime/vm/compiler/frontend/constant_reader.cc
@@ -122,6 +122,9 @@
   KernelReaderHelper reader(Z, &H, script_, H.constants_table(), 0);
   reader.ReadUInt();  // skip variable-sized int for adjusted constant offset
   reader.SetOffset(reader.ReaderOffset() + constant_offset);
+  // No function types returned as part of any types built should reference
+  // free parent type args, ensured by clearing the enclosing function type.
+  ActiveEnclosingFunctionScope scope(active_class_, nullptr);
   // Construct constant from raw bytes.
   Instance& instance = Instance::Handle(Z);
   const intptr_t constant_tag = reader.ReadByte();
@@ -198,8 +201,9 @@
           Class::Handle(Z, corelib.LookupClassAllowPrivate(Symbols::_List()));
       // Build type from the raw bytes (needs temporary translator).
       TypeTranslator type_translator(
-          &reader, this, active_class_, true,
-          active_class_->RequireConstCanonicalTypeErasure(null_safety));
+          &reader, this, active_class_, /* finalize = */ true,
+          active_class_->RequireConstCanonicalTypeErasure(null_safety),
+          /* in_constant_context = */ true);
       auto& type_arguments =
           TypeArguments::Handle(Z, TypeArguments::New(1, Heap::kOld));
       AbstractType& type = type_translator.BuildType();
@@ -241,8 +245,9 @@
       instance = Instance::New(klass, Heap::kOld);
       // Build type from the raw bytes (needs temporary translator).
       TypeTranslator type_translator(
-          &reader, this, active_class_, true,
-          active_class_->RequireConstCanonicalTypeErasure(null_safety));
+          &reader, this, active_class_, /* finalize = */ true,
+          active_class_->RequireConstCanonicalTypeErasure(null_safety),
+          /* in_constant_context = */ true);
       const intptr_t number_of_type_arguments = reader.ReadUInt();
       if (klass.NumTypeArguments() > 0) {
         auto& type_arguments = TypeArguments::Handle(
@@ -264,7 +269,8 @@
       Field& field = Field::Handle(Z);
       Instance& constant = Instance::Handle(Z);
       for (intptr_t j = 0; j < number_of_fields; ++j) {
-        field = H.LookupFieldByKernelField(reader.ReadCanonicalNameReference());
+        field = H.LookupFieldByKernelGetterOrSetter(
+            reader.ReadCanonicalNameReference());
         // Recurse into lazily evaluating all "sub" constants
         // needed to evaluate the current constant.
         const intptr_t entry_offset = reader.ReadUInt();
@@ -284,8 +290,9 @@
 
       // Build type from the raw bytes (needs temporary translator).
       TypeTranslator type_translator(
-          &reader, this, active_class_, true,
-          active_class_->RequireConstCanonicalTypeErasure(null_safety));
+          &reader, this, active_class_, /* finalize = */ true,
+          active_class_->RequireConstCanonicalTypeErasure(null_safety),
+          /* in_constant_context = */ true);
       const intptr_t number_of_type_arguments = reader.ReadUInt();
       ASSERT(number_of_type_arguments > 0);
       auto& type_arguments = TypeArguments::Handle(
@@ -323,7 +330,10 @@
       // canonicalized to an identical representant independently of the null
       // safety mode currently in use (sound or unsound) or migration state of
       // the declaring library (legacy or opted-in).
-      TypeTranslator type_translator(&reader, this, active_class_, true);
+      TypeTranslator type_translator(&reader, this, active_class_,
+                                     /* finalize = */ true,
+                                     /* apply_canonical_type_erasure = */ false,
+                                     /* in_constant_context = */ true);
       instance = type_translator.BuildType().ptr();
       break;
     }
diff --git a/runtime/vm/compiler/frontend/flow_graph_builder.cc b/runtime/vm/compiler/frontend/flow_graph_builder.cc
index 5034b6d..c2ed762 100644
--- a/runtime/vm/compiler/frontend/flow_graph_builder.cc
+++ b/runtime/vm/compiler/frontend/flow_graph_builder.cc
@@ -50,6 +50,10 @@
   // Attach the outer environment on each instruction in the callee graph.
   ASSERT(call_->env() != NULL);
   ASSERT(call_->deopt_id() != DeoptId::kNone);
+
+  auto zone = callee_graph->zone();
+  auto env = call_->env();
+
   const intptr_t outer_deopt_id = call_->deopt_id();
   // Scale the edge weights by the call count for the inlined function.
   double scale_factor = 1.0;
@@ -65,18 +69,16 @@
       block->AsTargetEntry()->adjust_edge_weight(scale_factor);
     }
     Instruction* instr = block;
-    if (block->env() != NULL) {
-      call_->env()->DeepCopyToOuter(callee_graph->zone(), block,
-                                    outer_deopt_id);
+    if (block->env() != nullptr) {
+      env->DeepCopyToOuter(zone, block, outer_deopt_id);
     }
     for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) {
       instr = it.Current();
       // TODO(zerny): Avoid creating unnecessary environments. Note that some
       // optimizations need deoptimization info for non-deoptable instructions,
       // eg, LICM on GOTOs.
-      if (instr->env() != NULL) {
-        call_->env()->DeepCopyToOuter(callee_graph->zone(), instr,
-                                      outer_deopt_id);
+      if (instr->env() != nullptr) {
+        env->DeepCopyToOuter(zone, instr, outer_deopt_id);
       }
     }
     if (instr->IsGoto()) {
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
index e3708c8..d90c132 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
@@ -238,7 +238,7 @@
         ReadBool();
         const NameIndex field_name = ReadCanonicalNameReference();
         const Field& field =
-            Field::Handle(Z, H.LookupFieldByKernelField(field_name));
+            Field::Handle(Z, H.LookupFieldByKernelGetterOrSetter(field_name));
         initializer_fields[i] = &field;
         SkipExpression();
         continue;
@@ -2181,8 +2181,7 @@
   const Function* tearoff_interface_target = &Function::null_function();
   const NameIndex itarget_name =
       ReadInterfaceMemberNameReference();  // read interface_target_reference.
-  if (!H.IsRoot(itarget_name) &&
-      (H.IsGetter(itarget_name) || H.IsField(itarget_name))) {
+  if (!H.IsRoot(itarget_name) && H.IsGetter(itarget_name)) {
     interface_target = &Function::ZoneHandle(
         Z,
         H.LookupMethodByMember(itarget_name, H.DartGetterName(itarget_name)));
@@ -2550,10 +2549,11 @@
       inferred_type_metadata_helper_.GetInferredType(offset);
 
   NameIndex target = ReadCanonicalNameReference();  // read target_reference.
+  ASSERT(H.IsGetter(target));
 
-  if (H.IsField(target)) {
-    const Field& field =
-        Field::ZoneHandle(Z, H.LookupFieldByKernelField(target));
+  const Field& field = Field::ZoneHandle(
+      Z, H.LookupFieldByKernelGetterOrSetter(target, /*required=*/false));
+  if (!field.IsNull()) {
     if (field.is_const()) {
       // Since the CFE inlines all references to const variables and fields,
       // it never emits a StaticGet of a const field.
@@ -2606,44 +2606,39 @@
   if (p != NULL) *p = position;
 
   NameIndex target = ReadCanonicalNameReference();  // read target_reference.
+  ASSERT(H.IsSetter(target));
 
-  if (H.IsField(target)) {
-    const Field& field =
-        Field::ZoneHandle(Z, H.LookupFieldByKernelField(target));
-    const Class& owner = Class::Handle(Z, field.Owner());
-    const String& setter_name = H.DartSetterName(target);
-    const Function& setter =
-        Function::ZoneHandle(Z, owner.LookupStaticFunction(setter_name));
-    Fragment instructions = BuildExpression();  // read expression.
-    if (NeedsDebugStepCheck(stack(), position)) {
-      instructions = DebugStepCheck(position) + instructions;
-    }
-    LocalVariable* variable = MakeTemporary();
-    instructions += LoadLocal(variable);
-    if (!setter.IsNull() && field.NeedsSetter()) {
-      instructions += StaticCall(position, setter, 1, ICData::kStatic);
-      instructions += Drop();
-    } else {
-      instructions += StoreStaticField(position, field);
-    }
-    return instructions;
-  } else {
-    ASSERT(H.IsProcedure(target));
+  // Evaluate the expression on the right hand side.
+  Fragment instructions = BuildExpression();  // read expression.
 
-    // Evaluate the expression on the right hand side.
-    Fragment instructions = BuildExpression();  // read expression.
+  // Look up the target as a setter first and, if not present, as a field
+  // second. This order is needed to avoid looking up a final field as the
+  // target.
+  const Function& function = Function::ZoneHandle(
+      Z, H.LookupStaticMethodByKernelProcedure(target, /*required=*/false));
+
+  if (!function.IsNull()) {
     LocalVariable* variable = MakeTemporary();
 
     // Prepare argument.
     instructions += LoadLocal(variable);
 
     // Invoke the setter function.
-    const Function& function =
-        Function::ZoneHandle(Z, H.LookupStaticMethodByKernelProcedure(target));
     instructions += StaticCall(position, function, 1, ICData::kStatic);
 
     // Drop the unused result & leave the stored value on the stack.
     return instructions + Drop();
+  } else {
+    const Field& field =
+        Field::ZoneHandle(Z, H.LookupFieldByKernelGetterOrSetter(target));
+    ASSERT(!field.NeedsSetter());
+    if (NeedsDebugStepCheck(stack(), position)) {
+      instructions = DebugStepCheck(position) + instructions;
+    }
+    LocalVariable* variable = MakeTemporary();
+    instructions += LoadLocal(variable);
+    instructions += StoreStaticField(position, field);
+    return instructions;
   }
 }
 
@@ -2771,8 +2766,7 @@
   // TODO(dartbug.com/34497): Once front-end desugars calls via
   // fields/getters, filtering of field and getter interface targets here
   // can be turned into assertions.
-  if (!H.IsRoot(itarget_name) && !H.IsField(itarget_name) &&
-      !H.IsGetter(itarget_name)) {
+  if (!H.IsRoot(itarget_name) && !H.IsGetter(itarget_name)) {
     interface_target = &Function::ZoneHandle(
         Z, H.LookupMethodByMember(itarget_name,
                                   H.DartProcedureName(itarget_name)));
diff --git a/runtime/vm/compiler/frontend/kernel_fingerprints.cc b/runtime/vm/compiler/frontend/kernel_fingerprints.cc
index 9f7415c..ca9ebbf 100644
--- a/runtime/vm/compiler/frontend/kernel_fingerprints.cc
+++ b/runtime/vm/compiler/frontend/kernel_fingerprints.cc
@@ -232,7 +232,6 @@
     case kInvalidType:
     case kDynamicType:
     case kVoidType:
-    case kBottomType:
       // those contain nothing.
       break;
     case kNeverType:
@@ -323,7 +322,7 @@
 
 void KernelFingerprintHelper::CalculateGetterNameFingerprint() {
   const NameIndex name = ReadCanonicalNameReference();
-  if (!H.IsRoot(name) && (H.IsGetter(name) || H.IsField(name))) {
+  if (!H.IsRoot(name) && H.IsGetter(name)) {
     BuildHash(H.DartGetterName(name).Hash());
   }
   ReadCanonicalNameReference();  // read interface_target_origin_reference
@@ -340,7 +339,7 @@
 void KernelFingerprintHelper::CalculateMethodNameFingerprint() {
   const NameIndex name =
       ReadCanonicalNameReference();  // read interface_target_reference.
-  if (!H.IsRoot(name) && !H.IsField(name)) {
+  if (!H.IsRoot(name)) {
     BuildHash(H.DartProcedureName(name).Hash());
   }
   ReadCanonicalNameReference();  // read interface_target_origin_reference
diff --git a/runtime/vm/compiler/frontend/kernel_to_il.cc b/runtime/vm/compiler/frontend/kernel_to_il.cc
index db41553..0f193da 100644
--- a/runtime/vm/compiler/frontend/kernel_to_il.cc
+++ b/runtime/vm/compiler/frontend/kernel_to_il.cc
@@ -831,7 +831,9 @@
     case MethodRecognizer::kFfiLoadUint64:
     case MethodRecognizer::kFfiLoadIntPtr:
     case MethodRecognizer::kFfiLoadFloat:
+    case MethodRecognizer::kFfiLoadFloatUnaligned:
     case MethodRecognizer::kFfiLoadDouble:
+    case MethodRecognizer::kFfiLoadDoubleUnaligned:
     case MethodRecognizer::kFfiLoadPointer:
     case MethodRecognizer::kFfiStoreInt8:
     case MethodRecognizer::kFfiStoreInt16:
@@ -843,7 +845,9 @@
     case MethodRecognizer::kFfiStoreUint64:
     case MethodRecognizer::kFfiStoreIntPtr:
     case MethodRecognizer::kFfiStoreFloat:
+    case MethodRecognizer::kFfiStoreFloatUnaligned:
     case MethodRecognizer::kFfiStoreDouble:
+    case MethodRecognizer::kFfiStoreDoubleUnaligned:
     case MethodRecognizer::kFfiStorePointer:
     case MethodRecognizer::kFfiFromAddress:
     case MethodRecognizer::kFfiGetAddress:
@@ -1288,10 +1292,14 @@
     case MethodRecognizer::kFfiLoadUint64:
     case MethodRecognizer::kFfiLoadIntPtr:
     case MethodRecognizer::kFfiLoadFloat:
+    case MethodRecognizer::kFfiLoadFloatUnaligned:
     case MethodRecognizer::kFfiLoadDouble:
+    case MethodRecognizer::kFfiLoadDoubleUnaligned:
     case MethodRecognizer::kFfiLoadPointer: {
       const classid_t ffi_type_arg_cid =
           compiler::ffi::RecognizedMethodTypeArgCid(kind);
+      const AlignmentType alignment =
+          compiler::ffi::RecognizedMethodAlignment(kind);
       const classid_t typed_data_cid =
           compiler::ffi::ElementTypedDataCid(ffi_type_arg_cid);
       const auto& native_rep = compiler::ffi::NativeType::FromTypedDataClassId(
@@ -1314,13 +1322,26 @@
       body += LoadLocal(arg_offset_not_null);
       body += UnboxTruncate(kUnboxedFfiIntPtr);
       body += LoadIndexed(typed_data_cid, /*index_scale=*/1,
-                          /*index_unboxed=*/true);
+                          /*index_unboxed=*/true, alignment);
       if (kind == MethodRecognizer::kFfiLoadFloat ||
-          kind == MethodRecognizer::kFfiLoadDouble) {
-        if (kind == MethodRecognizer::kFfiLoadFloat) {
+          kind == MethodRecognizer::kFfiLoadFloatUnaligned ||
+          kind == MethodRecognizer::kFfiLoadDouble ||
+          kind == MethodRecognizer::kFfiLoadDoubleUnaligned) {
+        if (kind == MethodRecognizer::kFfiLoadFloat ||
+            kind == MethodRecognizer::kFfiLoadFloatUnaligned) {
           body += FloatToDouble();
         }
         body += Box(kUnboxedDouble);
+      } else if (kind == MethodRecognizer::kFfiLoadInt8 ||
+                 kind == MethodRecognizer::kFfiLoadInt16 ||
+                 kind == MethodRecognizer::kFfiLoadUint8 ||
+                 kind == MethodRecognizer::kFfiLoadUint16) {
+        // LoadIndexed instruction with 8-bit and 16-bit elements
+        // results in value with kUnboxedIntPtr representation
+        // (see LoadIndexedInstr::representation).
+        // Avoid any unnecessary (and potentially deoptimizing) int
+        // conversions by using the correct representation at the first place.
+        body += Box(kUnboxedIntPtr);
       } else {
         body += Box(native_rep.AsRepresentationOverApprox(zone_));
         if (kind == MethodRecognizer::kFfiLoadPointer) {
@@ -1369,10 +1390,14 @@
     case MethodRecognizer::kFfiStoreUint64:
     case MethodRecognizer::kFfiStoreIntPtr:
     case MethodRecognizer::kFfiStoreFloat:
+    case MethodRecognizer::kFfiStoreFloatUnaligned:
     case MethodRecognizer::kFfiStoreDouble:
+    case MethodRecognizer::kFfiStoreDoubleUnaligned:
     case MethodRecognizer::kFfiStorePointer: {
       const classid_t ffi_type_arg_cid =
           compiler::ffi::RecognizedMethodTypeArgCid(kind);
+      const AlignmentType alignment =
+          compiler::ffi::RecognizedMethodAlignment(kind);
       const classid_t typed_data_cid =
           compiler::ffi::ElementTypedDataCid(ffi_type_arg_cid);
       const auto& native_rep = compiler::ffi::NativeType::FromTypedDataClassId(
@@ -1439,16 +1464,29 @@
         body += LoadUntagged(compiler::target::Pointer::data_field_offset());
         body += ConvertUntaggedToUnboxed(kUnboxedFfiIntPtr);
       } else if (kind == MethodRecognizer::kFfiStoreFloat ||
-                 kind == MethodRecognizer::kFfiStoreDouble) {
+                 kind == MethodRecognizer::kFfiStoreFloatUnaligned ||
+                 kind == MethodRecognizer::kFfiStoreDouble ||
+                 kind == MethodRecognizer::kFfiStoreDoubleUnaligned) {
         body += UnboxTruncate(kUnboxedDouble);
-        if (kind == MethodRecognizer::kFfiStoreFloat) {
+        if (kind == MethodRecognizer::kFfiStoreFloat ||
+            kind == MethodRecognizer::kFfiStoreFloatUnaligned) {
           body += DoubleToFloat();
         }
+      } else if (kind == MethodRecognizer::kFfiStoreInt8 ||
+                 kind == MethodRecognizer::kFfiStoreInt16 ||
+                 kind == MethodRecognizer::kFfiStoreUint8 ||
+                 kind == MethodRecognizer::kFfiStoreUint16) {
+        // StoreIndexed instruction with 8-bit and 16-bit elements
+        // takes value with kUnboxedIntPtr representation
+        // (see StoreIndexedInstr::RequiredInputRepresentation).
+        // Avoid any unnecessary (and potentially deoptimizing) int
+        // conversions by using the correct representation at the first place.
+        body += UnboxTruncate(kUnboxedIntPtr);
       } else {
         body += UnboxTruncate(native_rep.AsRepresentationOverApprox(zone_));
       }
       body += StoreIndexedTypedData(typed_data_cid, /*index_scale=*/1,
-                                    /*index_unboxed=*/true);
+                                    /*index_unboxed=*/true, alignment);
       body += Drop();  // Drop [arg_value].
       body += Drop();  // Drop [arg_offset].
       body += NullConstant();
@@ -1598,9 +1636,8 @@
         StoreInstanceFieldInstr::Kind::kInitializing);
   }
 
-  // The function signature cannot have uninstantiated function type parameters,
-  // because the function cannot be local and have parent generic functions.
-  ASSERT(target.HasInstantiatedSignature(kFunctions));
+  // The function cannot be local and have parent generic functions.
+  ASSERT(!target.HasGenericParent());
 
   // Allocate a context that closes over `this`.
   // Note: this must be kept in sync with ScopeBuilder::BuildScopes.
@@ -2095,8 +2132,6 @@
   LocalVariable* parameter_names = nullptr;
   LocalVariable* parameter_types = nullptr;
   LocalVariable* type_parameters = nullptr;
-  LocalVariable* closure_data = nullptr;
-  LocalVariable* default_tav_info = nullptr;
   LocalVariable* instantiator_type_args = nullptr;
   LocalVariable* parent_function_type_args = nullptr;
 };
@@ -2216,38 +2251,40 @@
   // Load the defaults, instantiating or replacing them with the other type
   // arguments as appropriate.
   Fragment store_default;
-  store_default += LoadLocal(info.default_tav_info);
-  static_assert(
-      Function::DefaultTypeArgumentsKindField::shift() == 0,
-      "Need to generate shift for DefaultTypeArgumentsKindField bit field");
-  store_default += IntConstant(Function::DefaultTypeArgumentsKindField::mask());
-  store_default += SmiBinaryOp(Token::kBIT_AND);
+  store_default += LoadLocal(info.closure);
+  store_default += LoadNativeField(Slot::Closure_function());
+  store_default += LoadNativeField(Slot::Function_data());
+  LocalVariable* closure_data = MakeTemporary("closure_data");
+
+  store_default += LoadLocal(closure_data);
+  const auto& slot = Slot::ClosureData_default_type_arguments_kind();
+  store_default += LoadNativeField(slot);
+  store_default += Box(slot.representation());
   LocalVariable* default_tav_kind = MakeTemporary("default_tav_kind");
 
-  // One read-only stack values (default_tav_kind) that must be dropped after
-  // rejoining at done.
+  // Two locals to drop after join, closure_data and default_tav_kind.
   JoinEntryInstr* done = BuildJoinEntry();
 
   store_default += LoadLocal(default_tav_kind);
   TargetEntryInstr *is_instantiated, *is_not_instantiated;
   store_default += IntConstant(static_cast<intptr_t>(
-      Function::DefaultTypeArgumentsKind::kIsInstantiated));
+      ClosureData::DefaultTypeArgumentsKind::kIsInstantiated));
   store_default += BranchIfEqual(&is_instantiated, &is_not_instantiated);
   store_default.current = is_not_instantiated;  // Check next case.
   store_default += LoadLocal(default_tav_kind);
   TargetEntryInstr *needs_instantiation, *can_share;
   store_default += IntConstant(static_cast<intptr_t>(
-      Function::DefaultTypeArgumentsKind::kNeedsInstantiation));
+      ClosureData::DefaultTypeArgumentsKind::kNeedsInstantiation));
   store_default += BranchIfEqual(&needs_instantiation, &can_share);
   store_default.current = can_share;  // Check next case.
   store_default += LoadLocal(default_tav_kind);
   TargetEntryInstr *can_share_instantiator, *can_share_function;
   store_default += IntConstant(static_cast<intptr_t>(
-      Function::DefaultTypeArgumentsKind::kSharesInstantiatorTypeArguments));
+      ClosureData::DefaultTypeArgumentsKind::kSharesInstantiatorTypeArguments));
   store_default += BranchIfEqual(&can_share_instantiator, &can_share_function);
 
   Fragment instantiated(is_instantiated);
-  instantiated += LoadLocal(info.closure_data);
+  instantiated += LoadLocal(closure_data);
   instantiated += LoadNativeField(Slot::ClosureData_default_type_arguments());
   instantiated += StoreLocal(info.vars->function_type_args);
   instantiated += Drop();
@@ -2260,7 +2297,7 @@
   // can be used within the defaults).
   do_instantiation += LoadLocal(info.parent_function_type_args);
   // Load the default type arguments to instantiate.
-  do_instantiation += LoadLocal(info.closure_data);
+  do_instantiation += LoadLocal(closure_data);
   do_instantiation +=
       LoadNativeField(Slot::ClosureData_default_type_arguments());
   do_instantiation += InstantiateDynamicTypeArguments();
@@ -2284,6 +2321,7 @@
 
   store_default.current = done;  // Return here after branching.
   store_default += DropTemporary(&default_tav_kind);
+  store_default += DropTemporary(&closure_data);
 
   Fragment store_delayed;
   store_delayed += LoadLocal(info.closure);
@@ -2723,13 +2761,6 @@
   // full set of function type arguments, then check the local function type
   // arguments against the closure function's type parameter bounds.
   Fragment generic;
-  generic += LoadLocal(info.closure);
-  generic += LoadNativeField(Slot::Closure_function());
-  generic += LoadNativeField(Slot::Function_data());
-  info.closure_data = MakeTemporary("closure_data");
-  generic += LoadLocal(info.closure_data);
-  generic += LoadNativeField(Slot::ClosureData_default_type_arguments_info());
-  info.default_tav_info = MakeTemporary("default_tav_info");
   // Calculate the local function type arguments and store them in
   // info.vars->function_type_args.
   generic += BuildClosureCallDefaultTypeHandling(info);
@@ -2738,13 +2769,10 @@
   // Load the parent function type args.
   generic += LoadLocal(info.parent_function_type_args);
   // Load the number of parent type parameters.
-  generic += LoadLocal(info.default_tav_info);
-  static_assert(Function::NumParentTypeParametersField::shift() > 0,
-                "No need to shift for NumParentTypeParametersField bit field");
-  generic += IntConstant(Function::NumParentTypeParametersField::shift());
-  generic += SmiBinaryOp(Token::kSHR);
-  generic += IntConstant(Function::NumParentTypeParametersField::mask());
-  generic += SmiBinaryOp(Token::kBIT_AND);
+  generic += LoadLocal(info.signature);
+  generic += BuildExtractUnboxedSlotBitFieldIntoSmi<
+      UntaggedFunctionType::PackedNumParentTypeArguments>(
+      Slot::FunctionType_packed_fields());
   // Load the number of total type parameters.
   LocalVariable* num_parents = MakeTemporary();
   generic += LoadLocal(info.type_parameters);
@@ -2757,8 +2785,6 @@
                         PrependTypeArgumentsFunction(), 4, ICData::kStatic);
   generic += StoreLocal(info.vars->function_type_args);
   generic += Drop();
-  generic += DropTemporary(&info.default_tav_info);
-  generic += DropTemporary(&info.closure_data);
 
   // Now that we have the full set of function type arguments, check them
   // against the type parameter bounds. However, if the local function type
diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.cc b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
index 1da5a95..c83e6cb 100644
--- a/runtime/vm/compiler/frontend/kernel_translation_helper.cc
+++ b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
@@ -235,22 +235,7 @@
 }
 
 bool TranslationHelper::IsMember(NameIndex name) {
-  return IsConstructor(name) || IsField(name) || IsProcedure(name);
-}
-
-bool TranslationHelper::IsField(NameIndex name) {
-  // Fields with private names have the import URI of the library where they are
-  // visible as the parent and the string "@fields" as the parent's parent.
-  // Fields with non-private names have the string "@fields' as the parent.
-  if (IsRoot(name)) {
-    return false;
-  }
-  NameIndex kind = CanonicalNameParent(name);
-  if (IsPrivate(name)) {
-    kind = CanonicalNameParent(kind);
-  }
-  return StringEquals(CanonicalNameString(kind), "@fields") ||
-         StringEquals(CanonicalNameString(kind), "@=fields");
+  return IsConstructor(name) || IsProcedure(name);
 }
 
 bool TranslationHelper::IsConstructor(NameIndex name) {
@@ -330,7 +315,7 @@
 }
 
 NameIndex TranslationHelper::EnclosingName(NameIndex name) {
-  ASSERT(IsField(name) || IsConstructor(name) || IsProcedure(name));
+  ASSERT(IsConstructor(name) || IsProcedure(name));
   NameIndex enclosing = CanonicalNameParent(CanonicalNameParent(name));
   if (IsPrivate(name)) {
     enclosing = CanonicalNameParent(enclosing);
@@ -587,8 +572,10 @@
   return info_.InsertClass(thread_, name_index_handle_, klass);
 }
 
-FieldPtr TranslationHelper::LookupFieldByKernelField(NameIndex kernel_field) {
-  ASSERT(IsField(kernel_field));
+FieldPtr TranslationHelper::LookupFieldByKernelGetterOrSetter(
+    NameIndex kernel_field,
+    bool required) {
+  ASSERT(IsGetter(kernel_field) || IsSetter(kernel_field));
   NameIndex enclosing = EnclosingName(kernel_field);
 
   Class& klass = Class::Handle(Z);
@@ -604,12 +591,15 @@
   Field& field = Field::Handle(
       Z, klass.LookupFieldAllowPrivate(
              DartSymbolObfuscate(CanonicalNameString(kernel_field))));
-  CheckStaticLookup(field);
+  if (required) {
+    CheckStaticLookup(field);
+  }
   return field.ptr();
 }
 
 FunctionPtr TranslationHelper::LookupStaticMethodByKernelProcedure(
-    NameIndex procedure) {
+    NameIndex procedure,
+    bool required) {
   const String& procedure_name = DartProcedureName(procedure);
 
   // The parent is either a library or a class (in which case the procedure is a
@@ -620,7 +610,9 @@
         Library::Handle(Z, LookupLibraryByKernelLibrary(enclosing));
     Function& function =
         Function::Handle(Z, library.LookupFunctionAllowPrivate(procedure_name));
-    CheckStaticLookup(function);
+    if (required) {
+      CheckStaticLookup(function);
+    }
     return function.ptr();
   } else {
     ASSERT(IsClass(enclosing));
@@ -629,7 +621,9 @@
     ASSERT(error == Error::null());
     Function& function = Function::ZoneHandle(
         Z, klass.LookupFunctionAllowPrivate(procedure_name));
-    CheckStaticLookup(function);
+    if (required) {
+      CheckStaticLookup(function);
+    }
     return function.ptr();
   }
 }
@@ -2135,7 +2129,6 @@
     case kInvalidType:
     case kDynamicType:
     case kVoidType:
-    case kBottomType:
       // those contain nothing.
       return;
     case kNeverType:
@@ -2933,7 +2926,8 @@
                                ConstantReader* constant_reader,
                                ActiveClass* active_class,
                                bool finalize,
-                               bool apply_canonical_type_erasure)
+                               bool apply_canonical_type_erasure,
+                               bool in_constant_context)
     : helper_(helper),
       constant_reader_(constant_reader),
       translation_helper_(helper->translation_helper_),
@@ -2944,7 +2938,8 @@
       zone_(translation_helper_.zone()),
       result_(AbstractType::Handle(translation_helper_.zone())),
       finalize_(finalize),
-      apply_canonical_type_erasure_(apply_canonical_type_erasure) {}
+      apply_canonical_type_erasure_(apply_canonical_type_erasure),
+      in_constant_context_(in_constant_context) {}
 
 AbstractType& TypeTranslator::BuildType() {
   BuildTypeInternal();
@@ -2985,11 +2980,6 @@
                     .ToNullability(nullability, Heap::kOld);
       break;
     }
-    case kBottomType:
-      // Map Bottom type to Null type until not emitted by CFE anymore.
-      result_ = IG->object_store()->null_type();
-      ASSERT(result_.IsNullable());
-      break;
     case kInterfaceType:
       BuildInterfaceType(false);
       break;
@@ -3066,22 +3056,26 @@
 
   // Suspend finalization of types inside this one. They will be finalized after
   // the whole function type is constructed.
-  //
-  // TODO(31213): Test further when nested generic function types
-  // are supported by fasta.
   bool finalize = finalize_;
   finalize_ = false;
+  intptr_t type_parameter_count = 0;
 
   if (!simple) {
+    type_parameter_count = helper_->ReadListLength();
     LoadAndSetupTypeParameters(
         active_class_, Object::null_function(), Object::null_class(), signature,
-        helper_->ReadListLength(), active_class_->klass->nnbd_mode());
+        type_parameter_count, active_class_->klass->nnbd_mode());
   }
 
   ActiveTypeParametersScope scope(
       active_class_, &signature,
       TypeArguments::Handle(Z, signature.type_parameters()), Z);
 
+  if (!simple) {
+    LoadAndSetupBounds(active_class_, Object::null_function(),
+                       Object::null_class(), signature, type_parameter_count);
+  }
+
   intptr_t required_count;
   intptr_t all_count;
   intptr_t positional_count;
@@ -3160,73 +3154,76 @@
   intptr_t parameter_index = helper_->ReadUInt();  // read parameter index.
   helper_->SkipOptionalDartType();                 // read bound.
 
-  const TypeArguments& class_types =
-      TypeArguments::Handle(Z, active_class_->klass->type_parameters());
-  if (parameter_index < class_types.Length()) {
-    // The index of the type parameter in [parameters] is
-    // the same index into the `klass->type_parameters()` array.
-    const auto& type_param =
-        TypeParameter::CheckedHandle(Z, class_types.TypeAt(parameter_index));
-    result_ = type_param.ToNullability(nullability, Heap::kOld);
-    active_class_->RecordDerivedTypeParameter(Z, type_param,
-                                              TypeParameter::Cast(result_));
-    return;
-  }
-  parameter_index -= class_types.Length();
-
-  if (active_class_->HasMember()) {
-    if (active_class_->MemberIsFactoryProcedure()) {
-      //
-      // WARNING: This is a little hackish:
-      //
-      // We have a static factory constructor. The kernel IR gives the factory
-      // constructor function its own type parameters (which are equal in name
-      // and number to the ones of the enclosing class). I.e.,
-      //
-      //   class A<T> {
-      //     factory A.x() { return new B<T>(); }
-      //   }
-      //
-      //  is basically translated to this:
-      //
-      //   class A<T> {
-      //     static A.x<T'>() { return new B<T'>(); }
-      //   }
-      //
-      if (class_types.Length() > parameter_index) {
-        const auto& type_param = TypeParameter::CheckedHandle(
-            Z, class_types.TypeAt(parameter_index));
-        result_ = type_param.ToNullability(nullability, Heap::kOld);
-        active_class_->RecordDerivedTypeParameter(Z, type_param,
-                                                  TypeParameter::Cast(result_));
-        return;
-      }
-      parameter_index -= class_types.Length();
+  // If the type is from a constant, the parameter index isn't offset by the
+  // enclosing context.
+  if (!in_constant_context_) {
+    const TypeArguments& class_types =
+        TypeArguments::Handle(Z, active_class_->klass->type_parameters());
+    if (parameter_index < class_types.Length()) {
+      // The index of the type parameter in [parameters] is
+      // the same index into the `klass->type_parameters()` array.
+      const auto& type_param =
+          TypeParameter::CheckedHandle(Z, class_types.TypeAt(parameter_index));
+      result_ = type_param.ToNullability(nullability, Heap::kOld);
+      active_class_->RecordDerivedTypeParameter(Z, type_param,
+                                                TypeParameter::Cast(result_));
+      return;
     }
-    // Factory function should not be considered as procedure.
-    intptr_t procedure_type_parameter_count =
-        (active_class_->MemberIsProcedure() &&
-         !active_class_->MemberIsFactoryProcedure())
-            ? active_class_->MemberTypeParameterCount(Z)
-            : 0;
-    if (procedure_type_parameter_count > 0) {
-      if (procedure_type_parameter_count > parameter_index) {
-        const auto& type_param = TypeParameter::CheckedHandle(
-            Z,
-            TypeArguments::Handle(Z, active_class_->member->type_parameters())
-                .TypeAt(parameter_index));
-        result_ = type_param.ToNullability(nullability, Heap::kOld);
-        active_class_->RecordDerivedTypeParameter(Z, type_param,
-                                                  TypeParameter::Cast(result_));
-        if (finalize_) {
-          result_ = ClassFinalizer::FinalizeType(result_);
+    parameter_index -= class_types.Length();
+
+    if (active_class_->HasMember()) {
+      if (active_class_->MemberIsFactoryProcedure()) {
+        //
+        // WARNING: This is a little hackish:
+        //
+        // We have a static factory constructor. The kernel IR gives the factory
+        // constructor function its own type parameters (which are equal in name
+        // and number to the ones of the enclosing class). I.e.,
+        //
+        //   class A<T> {
+        //     factory A.x() { return new B<T>(); }
+        //   }
+        //
+        //  is basically translated to this:
+        //
+        //   class A<T> {
+        //     static A.x<T'>() { return new B<T'>(); }
+        //   }
+        //
+        if (class_types.Length() > parameter_index) {
+          const auto& type_param = TypeParameter::CheckedHandle(
+              Z, class_types.TypeAt(parameter_index));
+          result_ = type_param.ToNullability(nullability, Heap::kOld);
+          active_class_->RecordDerivedTypeParameter(
+              Z, type_param, TypeParameter::Cast(result_));
+          return;
         }
-        return;
+        parameter_index -= class_types.Length();
       }
-      parameter_index -= procedure_type_parameter_count;
+      // Factory function should not be considered as procedure.
+      intptr_t procedure_type_parameter_count =
+          (active_class_->MemberIsProcedure() &&
+           !active_class_->MemberIsFactoryProcedure())
+              ? active_class_->MemberTypeParameterCount(Z)
+              : 0;
+      if (procedure_type_parameter_count > 0) {
+        if (procedure_type_parameter_count > parameter_index) {
+          const auto& type_param = TypeParameter::CheckedHandle(
+              Z,
+              TypeArguments::Handle(Z, active_class_->member->type_parameters())
+                  .TypeAt(parameter_index));
+          result_ = type_param.ToNullability(nullability, Heap::kOld);
+          active_class_->RecordDerivedTypeParameter(
+              Z, type_param, TypeParameter::Cast(result_));
+          if (finalize_) {
+            result_ = ClassFinalizer::FinalizeType(result_);
+          }
+          return;
+        }
+        parameter_index -= procedure_type_parameter_count;
+      }
     }
   }
-
   if (active_class_->local_type_parameters != NULL) {
     if (parameter_index < active_class_->local_type_parameters->Length()) {
       const auto& type_param = TypeParameter::CheckedHandle(
@@ -3336,7 +3333,6 @@
                                       ? Nullability::kNonNullable
                                       : Nullability::kLegacy;
 
-  // Step a)
   // - Create array of [TypeParameter] objects (without bound).
   // - Create array of [String] objects.
   type_parameters = TypeArguments::New(type_parameter_count);
@@ -3366,20 +3362,35 @@
       } else {
         name = H.DartIdentifier(lib, helper.name_index_).ptr();
       }
+      // Bounds are filled later in LoadAndSetupBounds as bound types may
+      // reference type parameters which are not created yet.
       parameter = TypeParameter::New(
           parameterized_class, offset, offset + i, name, null_bound,
           helper.IsGenericCovariantImpl(), nullability);
       type_parameters.SetTypeAt(i, parameter);
     }
   }
+}
 
-  const FunctionType* enclosing = NULL;
-  if (!parameterized_signature.IsNull()) {
-    enclosing = &parameterized_signature;
+void TypeTranslator::LoadAndSetupBounds(
+    ActiveClass* active_class,
+    const Function& function,
+    const Class& parameterized_class,
+    const FunctionType& parameterized_signature,
+    intptr_t type_parameter_count) {
+  ASSERT(parameterized_class.IsNull() != parameterized_signature.IsNull());
+  ASSERT(type_parameter_count >= 0);
+  if (type_parameter_count == 0) {
+    return;
   }
-  ActiveTypeParametersScope scope(active_class, enclosing, type_parameters, Z);
 
-  // Step b) Fill in the bounds and default arguments of all [TypeParameter]s.
+  const TypeArguments& type_parameters =
+      TypeArguments::Handle(Z, !parameterized_class.IsNull()
+                                   ? parameterized_class.type_parameters()
+                                   : parameterized_signature.type_parameters());
+  TypeParameter& parameter = TypeParameter::Handle(Z);
+
+  // Fill in the bounds and default arguments of all [TypeParameter]s.
   for (intptr_t i = 0; i < type_parameter_count; i++) {
     TypeParameterHelper helper(helper_);
     helper.ReadUntilExcludingAndSetJustRead(TypeParameterHelper::kBound);
@@ -3401,6 +3412,9 @@
 
   // Fix bounds and default arguments in all derived type parameters (with
   // different nullabilities).
+  const intptr_t offset = !parameterized_signature.IsNull()
+                              ? parameterized_signature.NumParentTypeArguments()
+                              : 0;
   if (active_class->derived_type_parameters != nullptr) {
     auto& derived = TypeParameter::Handle(Z);
     auto& type = AbstractType::Handle(Z);
@@ -3447,9 +3461,7 @@
   if (param_pos < function.maximum_unboxed_parameter_count()) {
     switch (metadata->unboxed_args_info[param_index]) {
       case UnboxingInfoMetadata::kUnboxedIntCandidate:
-        if (FlowGraphCompiler::SupportsUnboxedInt64()) {
-          function.set_unboxed_integer_parameter_at(param_pos);
-        }
+        function.set_unboxed_integer_parameter_at(param_pos);
         break;
       case UnboxingInfoMetadata::kUnboxedDoubleCandidate:
         if (FlowGraphCompiler::SupportsUnboxedDoubles()) {
@@ -3473,9 +3485,7 @@
     const UnboxingInfoMetadata* metadata) {
   switch (metadata->return_info) {
     case UnboxingInfoMetadata::kUnboxedIntCandidate:
-      if (FlowGraphCompiler::SupportsUnboxedInt64()) {
-        function.set_unboxed_integer_return();
-      }
+      function.set_unboxed_integer_return();
       break;
     case UnboxingInfoMetadata::kUnboxedDoubleCandidate:
       if (FlowGraphCompiler::SupportsUnboxedDoubles()) {
@@ -3547,15 +3557,22 @@
 
   const FunctionType& signature = FunctionType::Handle(Z, function.signature());
   ASSERT(!signature.IsNull());
+  intptr_t type_parameter_count = 0;
   if (!is_factory) {
+    type_parameter_count = helper_->ReadListLength();
     LoadAndSetupTypeParameters(active_class_, function, Class::Handle(Z),
-                               signature, helper_->ReadListLength(),
+                               signature, type_parameter_count,
                                function.nnbd_mode());
-    function_node_helper->SetJustRead(FunctionNodeHelper::kTypeParameters);
   }
 
   ActiveTypeParametersScope scope(active_class_, function, &signature, Z);
 
+  if (!is_factory) {
+    LoadAndSetupBounds(active_class_, function, Class::Handle(Z), signature,
+                       type_parameter_count);
+    function_node_helper->SetJustRead(FunctionNodeHelper::kTypeParameters);
+  }
+
   function_node_helper->ReadUntilExcluding(
       FunctionNodeHelper::kPositionalParameters);
 
diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.h b/runtime/vm/compiler/frontend/kernel_translation_helper.h
index b76603a..64c5c8d 100644
--- a/runtime/vm/compiler/frontend/kernel_translation_helper.h
+++ b/runtime/vm/compiler/frontend/kernel_translation_helper.h
@@ -101,7 +101,6 @@
   bool IsLibrary(NameIndex name);
   bool IsClass(NameIndex name);
   bool IsMember(NameIndex name);
-  bool IsField(NameIndex name);
   bool IsConstructor(NameIndex name);
   bool IsProcedure(NameIndex name);
   bool IsMethod(NameIndex name);
@@ -164,8 +163,10 @@
   virtual LibraryPtr LookupLibraryByKernelLibrary(NameIndex library);
   virtual ClassPtr LookupClassByKernelClass(NameIndex klass);
 
-  FieldPtr LookupFieldByKernelField(NameIndex field);
-  FunctionPtr LookupStaticMethodByKernelProcedure(NameIndex procedure);
+  FieldPtr LookupFieldByKernelGetterOrSetter(NameIndex field,
+                                             bool required = true);
+  FunctionPtr LookupStaticMethodByKernelProcedure(NameIndex procedure,
+                                                  bool required = true);
   FunctionPtr LookupConstructorByKernelConstructor(NameIndex constructor);
   FunctionPtr LookupConstructorByKernelConstructor(const Class& owner,
                                                    NameIndex constructor);
@@ -1459,7 +1460,8 @@
                  ConstantReader* constant_reader,
                  ActiveClass* active_class,
                  bool finalize = false,
-                 bool apply_canonical_type_erasure = false);
+                 bool apply_canonical_type_erasure = false,
+                 bool in_constant_context = false);
 
   AbstractType& BuildType();
   AbstractType& BuildTypeWithoutFinalization();
@@ -1477,6 +1479,12 @@
                                   intptr_t type_parameter_count,
                                   const NNBDMode nnbd_mode);
 
+  void LoadAndSetupBounds(ActiveClass* active_class,
+                          const Function& function,
+                          const Class& parameterized_class,
+                          const FunctionType& parameterized_signature,
+                          intptr_t type_parameter_count);
+
   const Type& ReceiverType(const Class& klass);
 
   void SetupFunctionParameters(const Class& klass,
@@ -1534,6 +1542,7 @@
   AbstractType& result_;
   bool finalize_;
   const bool apply_canonical_type_erasure_;
+  const bool in_constant_context_;
 
   friend class ScopeBuilder;
   friend class KernelLoader;
diff --git a/runtime/vm/compiler/frontend/scope_builder.cc b/runtime/vm/compiler/frontend/scope_builder.cc
index 32f02f5..f55386b 100644
--- a/runtime/vm/compiler/frontend/scope_builder.cc
+++ b/runtime/vm/compiler/frontend/scope_builder.cc
@@ -81,7 +81,7 @@
     enclosing_scope->set_context_level(0);
     enclosing_scope->AddVariable(receiver_variable);
     enclosing_scope->AddContextVariable(receiver_variable);
-  } else if (function.IsLocalFunction()) {
+  } else if (function.HasParent()) {
     enclosing_scope = LocalScope::RestoreOuterScope(
         ContextScope::Handle(Z, function.context_scope()));
   }
@@ -361,6 +361,7 @@
       scope_->InsertParameterAt(pos++, parsed_function_->receiver_var());
 
       // Create all positional and named parameters.
+      current_function_async_marker_ = FunctionNodeHelper::kSync;
       AddPositionalAndNamedParameters(
           pos, kTypeCheckEverythingNotCheckedInNonDynamicallyInvokedMethod,
           attrs);
@@ -546,15 +547,6 @@
   }
   function_node_helper.SetJustRead(FunctionNodeHelper::kTypeParameters);
 
-  // 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.
-  if (function_node_helper.async_marker_ == FunctionNodeHelper::kSyncYielding) {
-    for (intptr_t i = 0; i < function.NumParameters(); i++) {
-      parsed_function_->ParameterVariable(i)->set_is_forced_stack();
-    }
-  }
-
   // Read (but don't visit) the positional and named parameters, because they've
   // already been added to the scope.
   function_node_helper.ReadUntilExcluding(FunctionNodeHelper::kBody);
@@ -715,15 +707,15 @@
       return;
     case kSuperPropertyGet:
       HandleLoadReceiver();
-      helper_.ReadPosition();                // read position.
-      helper_.SkipName();                    // read name.
+      helper_.ReadPosition();                      // read position.
+      helper_.SkipName();                          // read name.
       helper_.SkipInterfaceMemberNameReference();  // read target_reference.
       return;
     case kSuperPropertySet:
       HandleLoadReceiver();
-      helper_.ReadPosition();                // read position.
-      helper_.SkipName();                    // read name.
-      VisitExpression();                     // read value.
+      helper_.ReadPosition();                      // read position.
+      helper_.SkipName();                          // read name.
+      VisitExpression();                           // read value.
       helper_.SkipInterfaceMemberNameReference();  // read target_reference.
       return;
     case kStaticGet:
@@ -1318,7 +1310,6 @@
     case kInvalidType:
     case kDynamicType:
     case kVoidType:
-    case kBottomType:
       // those contain nothing.
       return;
     case kNeverType:
@@ -1538,7 +1529,11 @@
   if (helper.IsCovariant()) {
     variable->set_is_explicit_covariant_parameter();
   }
-  if (variable->name().ptr() == Symbols::IteratorParameter().ptr()) {
+
+  // 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.
+  if (current_function_async_marker_ == FunctionNodeHelper::kSyncYielding) {
     variable->set_is_forced_stack();
   }
 
diff --git a/runtime/vm/compiler/graph_intrinsifier.cc b/runtime/vm/compiler/graph_intrinsifier.cc
index 61cf909..d0ca36b 100644
--- a/runtime/vm/compiler/graph_intrinsifier.cc
+++ b/runtime/vm/compiler/graph_intrinsifier.cc
@@ -920,6 +920,98 @@
   return true;
 }
 
+static bool BuildUnarySmiOp(FlowGraph* flow_graph, Token::Kind op_kind) {
+  ASSERT(!flow_graph->function().has_unboxed_return());
+  ASSERT(!flow_graph->function().is_unboxed_parameter_at(0));
+  GraphEntryInstr* graph_entry = flow_graph->graph_entry();
+  auto normal_entry = graph_entry->normal_entry();
+  BlockBuilder builder(flow_graph, normal_entry);
+  Definition* left = builder.AddParameter(0, /*with_frame=*/false);
+  builder.AddInstruction(
+      new CheckSmiInstr(new Value(left), DeoptId::kNone, builder.Source()));
+  Definition* result = builder.AddDefinition(
+      new UnarySmiOpInstr(op_kind, new Value(left), DeoptId::kNone));
+  builder.AddReturn(new Value(result));
+  return true;
+}
+
+bool GraphIntrinsifier::Build_Smi_bitNegate(FlowGraph* flow_graph) {
+  return BuildUnarySmiOp(flow_graph, Token::kBIT_NOT);
+}
+
+bool GraphIntrinsifier::Build_Integer_negate(FlowGraph* flow_graph) {
+  return BuildUnarySmiOp(flow_graph, Token::kNEGATE);
+}
+
+static bool BuildBinarySmiOp(FlowGraph* flow_graph, Token::Kind op_kind) {
+  ASSERT(!flow_graph->function().has_unboxed_return());
+  ASSERT(!flow_graph->function().is_unboxed_parameter_at(0));
+  ASSERT(!flow_graph->function().is_unboxed_parameter_at(1));
+  GraphEntryInstr* graph_entry = flow_graph->graph_entry();
+  auto normal_entry = graph_entry->normal_entry();
+  BlockBuilder builder(flow_graph, normal_entry);
+  Definition* left = builder.AddParameter(0, /*with_frame=*/false);
+  Definition* right = builder.AddParameter(1, /*with_frame=*/false);
+  builder.AddInstruction(
+      new CheckSmiInstr(new Value(left), DeoptId::kNone, builder.Source()));
+  builder.AddInstruction(
+      new CheckSmiInstr(new Value(right), DeoptId::kNone, builder.Source()));
+  Definition* result = builder.AddDefinition(new BinarySmiOpInstr(
+      op_kind, new Value(left), new Value(right), DeoptId::kNone));
+  builder.AddReturn(new Value(result));
+  return true;
+}
+
+bool GraphIntrinsifier::Build_Integer_add(FlowGraph* flow_graph) {
+  return BuildBinarySmiOp(flow_graph, Token::kADD);
+}
+
+bool GraphIntrinsifier::Build_Integer_sub(FlowGraph* flow_graph) {
+  return BuildBinarySmiOp(flow_graph, Token::kSUB);
+}
+
+bool GraphIntrinsifier::Build_Integer_mul(FlowGraph* flow_graph) {
+  return BuildBinarySmiOp(flow_graph, Token::kMUL);
+}
+
+bool GraphIntrinsifier::Build_Integer_mod(FlowGraph* flow_graph) {
+#if defined(TARGET_ARCH_ARM)
+  if (!TargetCPUFeatures::can_divide()) {
+    return false;
+  }
+#endif
+  return BuildBinarySmiOp(flow_graph, Token::kMOD);
+}
+
+bool GraphIntrinsifier::Build_Integer_truncDivide(FlowGraph* flow_graph) {
+#if defined(TARGET_ARCH_ARM)
+  if (!TargetCPUFeatures::can_divide()) {
+    return false;
+  }
+#endif
+  return BuildBinarySmiOp(flow_graph, Token::kTRUNCDIV);
+}
+
+bool GraphIntrinsifier::Build_Integer_bitAnd(FlowGraph* flow_graph) {
+  return BuildBinarySmiOp(flow_graph, Token::kBIT_AND);
+}
+
+bool GraphIntrinsifier::Build_Integer_bitOr(FlowGraph* flow_graph) {
+  return BuildBinarySmiOp(flow_graph, Token::kBIT_OR);
+}
+
+bool GraphIntrinsifier::Build_Integer_bitXor(FlowGraph* flow_graph) {
+  return BuildBinarySmiOp(flow_graph, Token::kBIT_XOR);
+}
+
+bool GraphIntrinsifier::Build_Integer_sar(FlowGraph* flow_graph) {
+  return BuildBinarySmiOp(flow_graph, Token::kSHR);
+}
+
+bool GraphIntrinsifier::Build_Integer_shr(FlowGraph* flow_graph) {
+  return BuildBinarySmiOp(flow_graph, Token::kUSHR);
+}
+
 static Definition* ConvertOrUnboxDoubleParameter(BlockBuilder* builder,
                                                  Definition* value,
                                                  intptr_t index,
@@ -962,20 +1054,24 @@
   return true;
 }
 
-static bool BuildInvokeMathCFunction(BlockBuilder* builder,
+static bool BuildInvokeMathCFunction(FlowGraph* flow_graph,
                                      MethodRecognizer::Kind kind,
-                                     FlowGraph* flow_graph,
                                      intptr_t num_parameters = 1) {
   if (!FlowGraphCompiler::SupportsUnboxedDoubles()) {
     return false;
   }
+
+  GraphEntryInstr* graph_entry = flow_graph->graph_entry();
+  auto normal_entry = graph_entry->normal_entry();
+  BlockBuilder builder(flow_graph, normal_entry);
+
   ZoneGrowableArray<Value*>* args =
       new ZoneGrowableArray<Value*>(num_parameters);
 
   for (intptr_t i = 0; i < num_parameters; i++) {
-    Definition* value = builder->AddParameter(i, /*with_frame=*/false);
+    Definition* value = builder.AddParameter(i, /*with_frame=*/false);
     Definition* unboxed_value = ConvertOrUnboxDoubleParameter(
-        builder, value, i, /* is_checked = */ false);
+        &builder, value, i, /* is_checked = */ false);
     if (unboxed_value == nullptr) {
       return false;
     }
@@ -983,156 +1079,84 @@
   }
 
   Definition* unboxed_result =
-      builder->AddDefinition(new InvokeMathCFunctionInstr(
-          args, DeoptId::kNone, kind, builder->Source()));
+      builder.AddDefinition(new InvokeMathCFunctionInstr(
+          args, DeoptId::kNone, kind, builder.Source()));
   Definition* result =
-      CreateBoxedResultIfNeeded(builder, unboxed_result, kUnboxedDouble);
-  builder->AddReturn(new Value(result));
+      CreateBoxedResultIfNeeded(&builder, unboxed_result, kUnboxedDouble);
+  builder.AddReturn(new Value(result));
 
   return true;
 }
 
 bool GraphIntrinsifier::Build_MathSin(FlowGraph* flow_graph) {
-  if (!FlowGraphCompiler::SupportsUnboxedDoubles()) return false;
-
-  GraphEntryInstr* graph_entry = flow_graph->graph_entry();
-  auto normal_entry = graph_entry->normal_entry();
-  BlockBuilder builder(flow_graph, normal_entry);
-
-  return BuildInvokeMathCFunction(&builder, MethodRecognizer::kMathSin,
-                                  flow_graph);
+  return BuildInvokeMathCFunction(flow_graph, MethodRecognizer::kMathSin);
 }
 
 bool GraphIntrinsifier::Build_MathCos(FlowGraph* flow_graph) {
-  if (!FlowGraphCompiler::SupportsUnboxedDoubles()) return false;
-
-  GraphEntryInstr* graph_entry = flow_graph->graph_entry();
-  auto normal_entry = graph_entry->normal_entry();
-  BlockBuilder builder(flow_graph, normal_entry);
-
-  return BuildInvokeMathCFunction(&builder, MethodRecognizer::kMathCos,
-                                  flow_graph);
+  return BuildInvokeMathCFunction(flow_graph, MethodRecognizer::kMathCos);
 }
 
 bool GraphIntrinsifier::Build_MathTan(FlowGraph* flow_graph) {
-  if (!FlowGraphCompiler::SupportsUnboxedDoubles()) return false;
-
-  GraphEntryInstr* graph_entry = flow_graph->graph_entry();
-  auto normal_entry = graph_entry->normal_entry();
-  BlockBuilder builder(flow_graph, normal_entry);
-
-  return BuildInvokeMathCFunction(&builder, MethodRecognizer::kMathTan,
-                                  flow_graph);
+  return BuildInvokeMathCFunction(flow_graph, MethodRecognizer::kMathTan);
 }
 
 bool GraphIntrinsifier::Build_MathAsin(FlowGraph* flow_graph) {
-  if (!FlowGraphCompiler::SupportsUnboxedDoubles()) return false;
-
-  GraphEntryInstr* graph_entry = flow_graph->graph_entry();
-  auto normal_entry = graph_entry->normal_entry();
-  BlockBuilder builder(flow_graph, normal_entry);
-
-  return BuildInvokeMathCFunction(&builder, MethodRecognizer::kMathAsin,
-                                  flow_graph);
+  return BuildInvokeMathCFunction(flow_graph, MethodRecognizer::kMathAsin);
 }
 
 bool GraphIntrinsifier::Build_MathAcos(FlowGraph* flow_graph) {
-  if (!FlowGraphCompiler::SupportsUnboxedDoubles()) return false;
-
-  GraphEntryInstr* graph_entry = flow_graph->graph_entry();
-  auto normal_entry = graph_entry->normal_entry();
-  BlockBuilder builder(flow_graph, normal_entry);
-
-  return BuildInvokeMathCFunction(&builder, MethodRecognizer::kMathAcos,
-                                  flow_graph);
+  return BuildInvokeMathCFunction(flow_graph, MethodRecognizer::kMathAcos);
 }
 
 bool GraphIntrinsifier::Build_MathAtan(FlowGraph* flow_graph) {
-  if (!FlowGraphCompiler::SupportsUnboxedDoubles()) return false;
-
-  GraphEntryInstr* graph_entry = flow_graph->graph_entry();
-  auto normal_entry = graph_entry->normal_entry();
-  BlockBuilder builder(flow_graph, normal_entry);
-
-  return BuildInvokeMathCFunction(&builder, MethodRecognizer::kMathAtan,
-                                  flow_graph);
+  return BuildInvokeMathCFunction(flow_graph, MethodRecognizer::kMathAtan);
 }
 
 bool GraphIntrinsifier::Build_MathAtan2(FlowGraph* flow_graph) {
-  if (!FlowGraphCompiler::SupportsUnboxedDoubles()) return false;
-
-  GraphEntryInstr* graph_entry = flow_graph->graph_entry();
-  auto normal_entry = graph_entry->normal_entry();
-  BlockBuilder builder(flow_graph, normal_entry);
-
-  return BuildInvokeMathCFunction(&builder, MethodRecognizer::kMathAtan2,
-                                  flow_graph,
+  return BuildInvokeMathCFunction(flow_graph, MethodRecognizer::kMathAtan2,
                                   /* num_parameters = */ 2);
 }
 
+bool GraphIntrinsifier::Build_MathExp(FlowGraph* flow_graph) {
+  return BuildInvokeMathCFunction(flow_graph, MethodRecognizer::kMathExp);
+}
+
+bool GraphIntrinsifier::Build_MathLog(FlowGraph* flow_graph) {
+  return BuildInvokeMathCFunction(flow_graph, MethodRecognizer::kMathLog);
+}
+
 bool GraphIntrinsifier::Build_DoubleMod(FlowGraph* flow_graph) {
-  if (!FlowGraphCompiler::SupportsUnboxedDoubles()) return false;
-
-  GraphEntryInstr* graph_entry = flow_graph->graph_entry();
-  auto normal_entry = graph_entry->normal_entry();
-  BlockBuilder builder(flow_graph, normal_entry);
-
-  return BuildInvokeMathCFunction(&builder, MethodRecognizer::kDoubleMod,
-                                  flow_graph,
+  return BuildInvokeMathCFunction(flow_graph, MethodRecognizer::kDoubleMod,
                                   /* num_parameters = */ 2);
 }
 
 bool GraphIntrinsifier::Build_DoubleCeil(FlowGraph* flow_graph) {
-  if (!FlowGraphCompiler::SupportsUnboxedDoubles()) return false;
   // TODO(johnmccutchan): On X86 this intrinsic can be written in a different
   // way.
   if (TargetCPUFeatures::double_truncate_round_supported()) return false;
 
-  GraphEntryInstr* graph_entry = flow_graph->graph_entry();
-  auto normal_entry = graph_entry->normal_entry();
-  BlockBuilder builder(flow_graph, normal_entry);
-
-  return BuildInvokeMathCFunction(&builder, MethodRecognizer::kDoubleCeil,
-                                  flow_graph);
+  return BuildInvokeMathCFunction(flow_graph, MethodRecognizer::kDoubleCeil);
 }
 
 bool GraphIntrinsifier::Build_DoubleFloor(FlowGraph* flow_graph) {
-  if (!FlowGraphCompiler::SupportsUnboxedDoubles()) return false;
   // TODO(johnmccutchan): On X86 this intrinsic can be written in a different
   // way.
   if (TargetCPUFeatures::double_truncate_round_supported()) return false;
 
-  GraphEntryInstr* graph_entry = flow_graph->graph_entry();
-  auto normal_entry = graph_entry->normal_entry();
-  BlockBuilder builder(flow_graph, normal_entry);
-
-  return BuildInvokeMathCFunction(&builder, MethodRecognizer::kDoubleFloor,
-                                  flow_graph);
+  return BuildInvokeMathCFunction(flow_graph, MethodRecognizer::kDoubleFloor);
 }
 
 bool GraphIntrinsifier::Build_DoubleTruncate(FlowGraph* flow_graph) {
-  if (!FlowGraphCompiler::SupportsUnboxedDoubles()) return false;
   // TODO(johnmccutchan): On X86 this intrinsic can be written in a different
   // way.
   if (TargetCPUFeatures::double_truncate_round_supported()) return false;
 
-  GraphEntryInstr* graph_entry = flow_graph->graph_entry();
-  auto normal_entry = graph_entry->normal_entry();
-  BlockBuilder builder(flow_graph, normal_entry);
-
-  return BuildInvokeMathCFunction(&builder, MethodRecognizer::kDoubleTruncate,
-                                  flow_graph);
+  return BuildInvokeMathCFunction(flow_graph,
+                                  MethodRecognizer::kDoubleTruncate);
 }
 
 bool GraphIntrinsifier::Build_DoubleRound(FlowGraph* flow_graph) {
-  if (!FlowGraphCompiler::SupportsUnboxedDoubles()) return false;
-
-  GraphEntryInstr* graph_entry = flow_graph->graph_entry();
-  auto normal_entry = graph_entry->normal_entry();
-  BlockBuilder builder(flow_graph, normal_entry);
-
-  return BuildInvokeMathCFunction(&builder, MethodRecognizer::kDoubleRound,
-                                  flow_graph);
+  return BuildInvokeMathCFunction(flow_graph, MethodRecognizer::kDoubleRound);
 }
 
 bool GraphIntrinsifier::Build_ImplicitGetter(FlowGraph* flow_graph) {
diff --git a/runtime/vm/compiler/intrinsifier.cc b/runtime/vm/compiler/intrinsifier.cc
index a8f9559..b4161bf 100644
--- a/runtime/vm/compiler/intrinsifier.cc
+++ b/runtime/vm/compiler/intrinsifier.cc
@@ -57,8 +57,7 @@
     case MethodRecognizer::kUint64ArrayGetIndexed:
     case MethodRecognizer::kUint64ArraySetIndexed:
       // TODO(ajcbik): consider 32-bit as well.
-      if (target::kBitsPerWord == 64 &&
-          FlowGraphCompiler::SupportsUnboxedInt64()) {
+      if (target::kBitsPerWord == 64) {
         break;
       }
       if (FLAG_trace_intrinsifier) {
diff --git a/runtime/vm/compiler/jit/compiler.cc b/runtime/vm/compiler/jit/compiler.cc
index 4ca1604..c9f8883 100644
--- a/runtime/vm/compiler/jit/compiler.cc
+++ b/runtime/vm/compiler/jit/compiler.cc
@@ -233,7 +233,7 @@
 
 bool Compiler::CanOptimizeFunction(Thread* thread, const Function& function) {
 #if !defined(PRODUCT)
-  if (Debugger::IsDebugging(thread, function)) {
+  if (thread->isolate_group()->debugger()->IsDebugging(thread, function)) {
     // We cannot set breakpoints and single step in optimized code,
     // so do not optimize the function. Bump usage counter down to avoid
     // repeatedly entering the runtime for an optimization attempt.
@@ -603,6 +603,20 @@
         auto install_code_fun = [&]() {
           *result =
               FinalizeCompilation(&assembler, &graph_compiler, flow_graph);
+#if !defined(PRODUCT)
+          // Isolate debuggers need to be notified of compiled function right
+          // away as code is installed because there might be latent breakpoints
+          // in compiled function, which have to be activated before functions
+          // code is executed. Otherwise concurrently running isolates might
+          // execute code before its patched and miss a need to pause at a
+          // breakpoint.
+          if (!result->IsNull()) {
+            if (!function.HasOptimizedCode()) {
+              thread()->isolate_group()->debugger()->NotifyCompilation(
+                  function);
+            }
+          }
+#endif
         };
 
         // Grab write program_lock outside of potential safepoint, that lock
@@ -632,15 +646,6 @@
         // Must be called outside of safepoint.
         Code::NotifyCodeObservers(function, *result, optimized());
 
-#if !defined(PRODUCT)
-        if (!function.HasOptimizedCode()) {
-          // TODO(dartbug.com/36097): We might need to adjust this once we start
-          // adding debugging support to --enable-isolate-groups.
-          thread()->isolate_group()->ForEachIsolate([&](Isolate* isolate) {
-            isolate->debugger()->NotifyCompilation(function);
-          });
-        }
-#endif
         if (FLAG_disassemble && FlowGraphPrinter::ShouldPrint(function)) {
           Disassembler::DisassembleCode(function, *result, optimized());
         } else if (FLAG_disassemble_optimized && optimized() &&
diff --git a/runtime/vm/compiler/jit/jit_call_specializer.cc b/runtime/vm/compiler/jit/jit_call_specializer.cc
index 40bf22e..58115df 100644
--- a/runtime/vm/compiler/jit/jit_call_specializer.cc
+++ b/runtime/vm/compiler/jit/jit_call_specializer.cc
@@ -224,8 +224,8 @@
   ASSERT(alloc->IsAllocateContext() || alloc->IsCloneContext());
 
   AllocateUninitializedContextInstr* replacement =
-      new AllocateUninitializedContextInstr(alloc->source(),
-                                            context_variables.length());
+      new AllocateUninitializedContextInstr(
+          alloc->source(), context_variables.length(), alloc->deopt_id());
   alloc->ReplaceWith(replacement, current_iterator());
 
   Instruction* cursor = replacement;
diff --git a/runtime/vm/compiler/recognized_methods_list.h b/runtime/vm/compiler/recognized_methods_list.h
index c53fc34..fa9e3e8 100644
--- a/runtime/vm/compiler/recognized_methods_list.h
+++ b/runtime/vm/compiler/recognized_methods_list.h
@@ -176,7 +176,9 @@
   V(::, _loadUint64, FfiLoadUint64, 0x0505fdcc)                                \
   V(::, _loadIntPtr, FfiLoadIntPtr, 0xebd9b43e)                                \
   V(::, _loadFloat, FfiLoadFloat, 0xf8d9845d)                                  \
+  V(::, _loadFloatUnaligned, FfiLoadFloatUnaligned, 0xc8c8dfff)                \
   V(::, _loadDouble, FfiLoadDouble, 0xf70cc619)                                \
+  V(::, _loadDoubleUnaligned, FfiLoadDoubleUnaligned, 0xc99ebd39)              \
   V(::, _loadPointer, FfiLoadPointer, 0x4e79d0fc)                              \
   V(::, _storeInt8, FfiStoreInt8, 0xdf50af0c)                                  \
   V(::, _storeInt16, FfiStoreInt16, 0xd84df332)                                \
@@ -188,21 +190,22 @@
   V(::, _storeUint64, FfiStoreUint64, 0xe2d93239)                              \
   V(::, _storeIntPtr, FfiStoreIntPtr, 0x080266a8)                              \
   V(::, _storeFloat, FfiStoreFloat, 0x6484f07e)                                \
+  V(::, _storeFloatUnaligned, FfiStoreFloatUnaligned, 0x600a9203)              \
   V(::, _storeDouble, FfiStoreDouble, 0x42998c64)                              \
+  V(::, _storeDoubleUnaligned, FfiStoreDoubleUnaligned, 0x3dced75b)            \
   V(::, _storePointer, FfiStorePointer, 0xea6b7751)                            \
   V(::, _fromAddress, FfiFromAddress, 0xfd8cb1cc)                              \
   V(Pointer, get:address, FfiGetAddress, 0x7cde87be)                           \
   V(::, reachabilityFence, ReachabilityFence, 0x619235c1)                      \
   V(_Utf8Decoder, _scan, Utf8DecoderScan, 0x4983e111)                          \
   V(_Future, timeout, FutureTimeout, 0xc83eaf79)                               \
-  V(Future, wait, FutureWait, 0x99cfb096)                                      \
+  V(Future, wait, FutureWait, 0xc71e731d)                                      \
   V(_RootZone, runUnary, RootZoneRunUnary, 0x966a802c)                         \
   V(_FutureListener, handleValue, FutureListenerHandleValue, 0x165b47c4)       \
 
 // List of intrinsics:
 // (class-name, function-name, intrinsification method, fingerprint).
 #define CORE_LIB_INTRINSIC_LIST(V)                                             \
-  V(_Smi, ~, Smi_bitNegate, 0x8254f51b)                                        \
   V(_Smi, get:bitLength, Smi_bitLength, 0x7ab50ceb)                            \
   V(_BigIntImpl, _lsh, Bigint_lsh, 0x3f8b105e)                                 \
   V(_BigIntImpl, _rsh, Bigint_rsh, 0x117ed3f3)                                 \
@@ -253,15 +256,6 @@
   V(::, _setHash, Object_setHash, 0x8f2a5b0b)                                  \
 
 #define CORE_INTEGER_LIB_INTRINSIC_LIST(V)                                     \
-  V(_IntegerImplementation, +, Integer_add, 0xd561008f)                        \
-  V(_IntegerImplementation, -, Integer_sub, 0xc96a0f80)                        \
-  V(_IntegerImplementation, *, Integer_mul, 0xacd9641d)                        \
-  V(_IntegerImplementation, %, Integer_mod, 0xfcf7cc13)                        \
-  V(_IntegerImplementation, ~/, Integer_truncDivide, 0xdda49e7f)               \
-  V(_IntegerImplementation, unary-, Integer_negate, 0xf7a9a696)                \
-  V(_IntegerImplementation, &, Integer_bitAnd, 0x8b9d7c33)                     \
-  V(_IntegerImplementation, |, Integer_bitOr, 0x8f47f5eb)                      \
-  V(_IntegerImplementation, ^, Integer_bitXor, 0xd838bef2)                     \
   V(_IntegerImplementation, >, Integer_greaterThan, 0x402b12df)                \
   V(_IntegerImplementation, ==, Integer_equal, 0x509c9146)                     \
   V(_IntegerImplementation, _equalToInteger, Integer_equalToInteger,           \
@@ -269,8 +263,7 @@
   V(_IntegerImplementation, <, Integer_lessThan, 0x39643178)                   \
   V(_IntegerImplementation, <=, Integer_lessEqualThan, 0x73d2a9f5)             \
   V(_IntegerImplementation, >=, Integer_greaterEqualThan, 0xbc280c13)          \
-  V(_IntegerImplementation, <<, Integer_shl, 0x766f00e5)                       \
-  V(_IntegerImplementation, >>, Integer_sar, 0x931fbb8a)                       \
+  V(_IntegerImplementation, <<, Integer_shl, 0x766f04a6)                       \
   V(_Double, toInt, DoubleToInteger, 0x676f1ce8)                               \
 
 #define MATH_LIB_INTRINSIC_LIST(V)                                             \
@@ -285,6 +278,8 @@
   V(::, acos, MathAcos, 0xffb03167)                                            \
   V(::, atan, MathAtan, 0xf1ecb41a)                                            \
   V(::, atan2, MathAtan2, 0xff585505)                                          \
+  V(::, exp, MathExp, 0xbb87ac43)                                              \
+  V(::, log, MathLog, 0x27ec861f)                                              \
 
 #define GRAPH_TYPED_DATA_INTRINSICS_LIST(V)                                    \
   V(_Int8List, [], Int8ArrayGetIndexed, 0x281e2e42)                            \
@@ -356,6 +351,18 @@
     0x17f90910)                                                                \
   V(_ExternalTwoByteString, codeUnitAt, ExternalTwoByteStringCodeUnitAt,       \
     0x17f90910)                                                                \
+  V(_Smi, ~, Smi_bitNegate, 0x8254f8dc)                                        \
+  V(_IntegerImplementation, +, Integer_add, 0xd5610450)                        \
+  V(_IntegerImplementation, -, Integer_sub, 0xc96a1341)                        \
+  V(_IntegerImplementation, *, Integer_mul, 0xacd967de)                        \
+  V(_IntegerImplementation, %, Integer_mod, 0xfcf7cfd4)                        \
+  V(_IntegerImplementation, ~/, Integer_truncDivide, 0xdda4a240)               \
+  V(_IntegerImplementation, unary-, Integer_negate, 0xf7a9aa57)                \
+  V(_IntegerImplementation, &, Integer_bitAnd, 0x8b9d7ff4)                     \
+  V(_IntegerImplementation, |, Integer_bitOr, 0x8f47f9ac)                      \
+  V(_IntegerImplementation, ^, Integer_bitXor, 0xd838c2b3)                     \
+  V(_IntegerImplementation, >>, Integer_sar, 0x931fbf4b)                       \
+  V(_IntegerImplementation, >>>, Integer_shr, 0x7495fbad)                      \
   V(_Double, unary-, DoubleFlipSignBit, 0x3d39082b)                            \
   V(_Double, truncateToDouble, DoubleTruncate, 0x62d48298)                     \
   V(_Double, roundToDouble, DoubleRound, 0x5649c63f)                           \
diff --git a/runtime/vm/compiler/runtime_api.cc b/runtime/vm/compiler/runtime_api.cc
index 88539e8..4db6350 100644
--- a/runtime/vm/compiler/runtime_api.cc
+++ b/runtime/vm/compiler/runtime_api.cc
@@ -70,8 +70,9 @@
   return type.IsBoolType();
 }
 
-bool IsIntType(const AbstractType& type) {
-  return type.IsIntType();
+bool IsSubtypeOfInt(const AbstractType& type) {
+  return type.IsIntType() || type.IsIntegerImplementationType() ||
+         type.IsSmiType() || type.IsMintType();
 }
 
 bool IsSmiType(const AbstractType& type) {
@@ -815,7 +816,13 @@
 #endif  // defined(TARGET_ARCH_IA32)
 
 word RegExp::function_offset(classid_t cid, bool sticky) {
+#if !defined(DART_COMPRESSED_POINTERS)
   return TranslateOffsetInWords(dart::RegExp::function_offset(cid, sticky));
+#else
+  // TODO(rmacnak): TranslateOffsetInWords doesn't account for, say, header
+  // being 1 word and slots being half words.
+  return dart::RegExp::function_offset(cid, sticky);
+#endif
 }
 
 const word Symbols::kNumberOfOneCharCodeSymbols =
diff --git a/runtime/vm/compiler/runtime_api.h b/runtime/vm/compiler/runtime_api.h
index 3c934f6..43ec84a 100644
--- a/runtime/vm/compiler/runtime_api.h
+++ b/runtime/vm/compiler/runtime_api.h
@@ -127,8 +127,9 @@
 // Returns true if [a] and [b] represent the same type (are equal).
 bool IsEqualType(const AbstractType& a, const AbstractType& b);
 
-// Returns true if [type] is the "int" type.
-bool IsIntType(const AbstractType& type);
+// Returns true if [type] is a subtype of the "int" type (_Smi, _Mint, int or
+// _IntegerImplementation).
+bool IsSubtypeOfInt(const AbstractType& type);
 
 // Returns true if [type] is the "double" type.
 bool IsDoubleType(const AbstractType& type);
@@ -1276,7 +1277,7 @@
 class ClosureData : public AllStatic {
  public:
   static word default_type_arguments_offset();
-  static word default_type_arguments_info_offset();
+  static word default_type_arguments_kind_offset();
   static word InstanceSize();
   static word NextFieldOffset();
 };
diff --git a/runtime/vm/compiler/runtime_offsets_extracted.h b/runtime/vm/compiler/runtime_offsets_extracted.h
index 318cf08..0f37245 100644
--- a/runtime/vm/compiler/runtime_offsets_extracted.h
+++ b/runtime/vm/compiler/runtime_offsets_extracted.h
@@ -113,7 +113,7 @@
 static constexpr dart::compiler::target::word
     ClosureData_default_type_arguments_offset = 16;
 static constexpr dart::compiler::target::word
-    ClosureData_default_type_arguments_info_offset = 20;
+    ClosureData_default_type_arguments_kind_offset = 20;
 static constexpr dart::compiler::target::word Code_object_pool_offset = 20;
 static constexpr dart::compiler::target::word Code_saved_instructions_offset =
     24;
@@ -224,9 +224,9 @@
 static constexpr dart::compiler::target::word
     Thread_AllocateArray_entry_point_offset = 368;
 static constexpr dart::compiler::target::word Thread_active_exception_offset =
-    692;
+    704;
 static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
-    696;
+    708;
 static constexpr dart::compiler::target::word
     Thread_array_write_barrier_code_offset = 120;
 static constexpr dart::compiler::target::word
@@ -251,7 +251,7 @@
     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 = 732;
+static constexpr dart::compiler::target::word Thread_api_top_scope_offset = 744;
 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;
@@ -262,7 +262,7 @@
     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 = 740;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 752;
 static constexpr dart::compiler::target::word
     Thread_dispatch_table_array_offset = 48;
 static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
@@ -280,7 +280,7 @@
 static constexpr dart::compiler::target::word
     Thread_enter_safepoint_stub_offset = 248;
 static constexpr dart::compiler::target::word Thread_execution_state_offset =
-    712;
+    724;
 static constexpr dart::compiler::target::word
     Thread_exit_safepoint_stub_offset = 252;
 static constexpr dart::compiler::target::word
@@ -300,13 +300,13 @@
 static constexpr dart::compiler::target::word
     Thread_float_zerow_address_offset = 364;
 static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
-    700;
+    712;
 static constexpr dart::compiler::target::word
     Thread_invoke_dart_code_stub_offset = 132;
 static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset =
-    728;
+    740;
 static constexpr dart::compiler::target::word Thread_isolate_offset = 44;
-static constexpr dart::compiler::target::word Thread_isolate_group_offset = 744;
+static constexpr dart::compiler::target::word Thread_isolate_group_offset = 756;
 static constexpr dart::compiler::target::word Thread_field_table_values_offset =
     68;
 static constexpr dart::compiler::target::word
@@ -348,11 +348,11 @@
 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_resume_pc_offset = 716;
 static constexpr dart::compiler::target::word
-    Thread_saved_shadow_call_stack_offset = 708;
+    Thread_saved_shadow_call_stack_offset = 720;
 static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
-    716;
+    728;
 static constexpr dart::compiler::target::word
     Thread_slow_type_test_stub_offset = 240;
 static constexpr dart::compiler::target::word
@@ -386,9 +386,9 @@
 static constexpr dart::compiler::target::word Thread_write_barrier_mask_offset =
     36;
 static constexpr dart::compiler::target::word Thread_heap_base_offset = 40;
-static constexpr dart::compiler::target::word Thread_callback_code_offset = 720;
+static constexpr dart::compiler::target::word Thread_callback_code_offset = 732;
 static constexpr dart::compiler::target::word
-    Thread_callback_stack_return_offset = 724;
+    Thread_callback_stack_return_offset = 736;
 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;
@@ -450,7 +450,7 @@
     4, 12, 8, 16};
 static constexpr dart::compiler::target::word
     Thread_write_barrier_wrappers_thread_offset[] = {
-        660, 664, 668, 672, 676, -1, 680, -1, 684, 688, -1, -1, -1, -1, -1, -1};
+        672, 676, 680, 684, 688, -1, 692, -1, 696, 700, -1, -1, -1, -1, -1, -1};
 static constexpr dart::compiler::target::word AbstractType_InstanceSize = 12;
 static constexpr dart::compiler::target::word ApiError_InstanceSize = 8;
 static constexpr dart::compiler::target::word Array_InstanceSize = 12;
@@ -647,7 +647,7 @@
 static constexpr dart::compiler::target::word
     ClosureData_default_type_arguments_offset = 32;
 static constexpr dart::compiler::target::word
-    ClosureData_default_type_arguments_info_offset = 40;
+    ClosureData_default_type_arguments_kind_offset = 40;
 static constexpr dart::compiler::target::word Code_object_pool_offset = 40;
 static constexpr dart::compiler::target::word Code_saved_instructions_offset =
     48;
@@ -759,9 +759,9 @@
 static constexpr dart::compiler::target::word
     Thread_AllocateArray_entry_point_offset = 728;
 static constexpr dart::compiler::target::word Thread_active_exception_offset =
-    1400;
+    1424;
 static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
-    1408;
+    1432;
 static constexpr dart::compiler::target::word
     Thread_array_write_barrier_code_offset = 232;
 static constexpr dart::compiler::target::word
@@ -787,7 +787,7 @@
 static constexpr dart::compiler::target::word
     Thread_allocate_object_slow_stub_offset = 384;
 static constexpr dart::compiler::target::word Thread_api_top_scope_offset =
-    1480;
+    1504;
 static constexpr dart::compiler::target::word
     Thread_auto_scope_native_wrapper_entry_point_offset = 656;
 static constexpr dart::compiler::target::word Thread_bool_false_offset = 216;
@@ -798,7 +798,7 @@
     Thread_call_to_runtime_entry_point_offset = 528;
 static constexpr dart::compiler::target::word
     Thread_call_to_runtime_stub_offset = 264;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1496;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1520;
 static constexpr dart::compiler::target::word
     Thread_dispatch_table_array_offset = 96;
 static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
@@ -816,7 +816,7 @@
 static constexpr dart::compiler::target::word
     Thread_enter_safepoint_stub_offset = 488;
 static constexpr dart::compiler::target::word Thread_execution_state_offset =
-    1440;
+    1464;
 static constexpr dart::compiler::target::word
     Thread_exit_safepoint_stub_offset = 496;
 static constexpr dart::compiler::target::word
@@ -836,14 +836,14 @@
 static constexpr dart::compiler::target::word
     Thread_float_zerow_address_offset = 720;
 static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
-    1416;
+    1440;
 static constexpr dart::compiler::target::word
     Thread_invoke_dart_code_stub_offset = 256;
 static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset =
-    1472;
+    1496;
 static constexpr dart::compiler::target::word Thread_isolate_offset = 88;
 static constexpr dart::compiler::target::word Thread_isolate_group_offset =
-    1504;
+    1528;
 static constexpr dart::compiler::target::word Thread_field_table_values_offset =
     136;
 static constexpr dart::compiler::target::word
@@ -885,11 +885,11 @@
 static constexpr dart::compiler::target::word Thread_object_null_offset = 200;
 static constexpr dart::compiler::target::word
     Thread_predefined_symbols_address_offset = 664;
-static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1424;
+static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1448;
 static constexpr dart::compiler::target::word
-    Thread_saved_shadow_call_stack_offset = 1432;
+    Thread_saved_shadow_call_stack_offset = 1456;
 static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
-    1448;
+    1472;
 static constexpr dart::compiler::target::word
     Thread_slow_type_test_stub_offset = 472;
 static constexpr dart::compiler::target::word
@@ -924,9 +924,9 @@
     72;
 static constexpr dart::compiler::target::word Thread_heap_base_offset = 80;
 static constexpr dart::compiler::target::word Thread_callback_code_offset =
-    1456;
+    1480;
 static constexpr dart::compiler::target::word
-    Thread_callback_stack_return_offset = 1464;
+    Thread_callback_stack_return_offset = 1488;
 static constexpr dart::compiler::target::word TimelineStream_enabled_offset =
     16;
 static constexpr dart::compiler::target::word TwoByteString_data_offset = 16;
@@ -989,8 +989,8 @@
     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};
+        1336, 1344, 1352, 1360, -1,   -1,   1368, 1376,
+        1384, 1392, 1400, -1,   1408, 1416, -1,   -1};
 static constexpr dart::compiler::target::word AbstractType_InstanceSize = 24;
 static constexpr dart::compiler::target::word ApiError_InstanceSize = 16;
 static constexpr dart::compiler::target::word Array_InstanceSize = 24;
@@ -1186,7 +1186,7 @@
 static constexpr dart::compiler::target::word
     ClosureData_default_type_arguments_offset = 16;
 static constexpr dart::compiler::target::word
-    ClosureData_default_type_arguments_info_offset = 20;
+    ClosureData_default_type_arguments_kind_offset = 20;
 static constexpr dart::compiler::target::word Code_object_pool_offset = 20;
 static constexpr dart::compiler::target::word Code_saved_instructions_offset =
     24;
@@ -1297,9 +1297,9 @@
 static constexpr dart::compiler::target::word
     Thread_AllocateArray_entry_point_offset = 368;
 static constexpr dart::compiler::target::word Thread_active_exception_offset =
-    660;
+    672;
 static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
-    664;
+    676;
 static constexpr dart::compiler::target::word
     Thread_array_write_barrier_code_offset = 120;
 static constexpr dart::compiler::target::word
@@ -1324,7 +1324,7 @@
     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 = 700;
+static constexpr dart::compiler::target::word Thread_api_top_scope_offset = 712;
 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;
@@ -1335,7 +1335,7 @@
     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 = 708;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 720;
 static constexpr dart::compiler::target::word
     Thread_dispatch_table_array_offset = 48;
 static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
@@ -1353,7 +1353,7 @@
 static constexpr dart::compiler::target::word
     Thread_enter_safepoint_stub_offset = 248;
 static constexpr dart::compiler::target::word Thread_execution_state_offset =
-    680;
+    692;
 static constexpr dart::compiler::target::word
     Thread_exit_safepoint_stub_offset = 252;
 static constexpr dart::compiler::target::word
@@ -1373,13 +1373,13 @@
 static constexpr dart::compiler::target::word
     Thread_float_zerow_address_offset = 364;
 static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
-    668;
+    680;
 static constexpr dart::compiler::target::word
     Thread_invoke_dart_code_stub_offset = 132;
 static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset =
-    696;
+    708;
 static constexpr dart::compiler::target::word Thread_isolate_offset = 44;
-static constexpr dart::compiler::target::word Thread_isolate_group_offset = 712;
+static constexpr dart::compiler::target::word Thread_isolate_group_offset = 724;
 static constexpr dart::compiler::target::word Thread_field_table_values_offset =
     68;
 static constexpr dart::compiler::target::word
@@ -1421,11 +1421,11 @@
 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_resume_pc_offset = 684;
 static constexpr dart::compiler::target::word
-    Thread_saved_shadow_call_stack_offset = 676;
+    Thread_saved_shadow_call_stack_offset = 688;
 static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
-    684;
+    696;
 static constexpr dart::compiler::target::word
     Thread_slow_type_test_stub_offset = 240;
 static constexpr dart::compiler::target::word
@@ -1459,9 +1459,9 @@
 static constexpr dart::compiler::target::word Thread_write_barrier_mask_offset =
     36;
 static constexpr dart::compiler::target::word Thread_heap_base_offset = 40;
-static constexpr dart::compiler::target::word Thread_callback_code_offset = 688;
+static constexpr dart::compiler::target::word Thread_callback_code_offset = 700;
 static constexpr dart::compiler::target::word
-    Thread_callback_stack_return_offset = 692;
+    Thread_callback_stack_return_offset = 704;
 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;
@@ -1717,7 +1717,7 @@
 static constexpr dart::compiler::target::word
     ClosureData_default_type_arguments_offset = 32;
 static constexpr dart::compiler::target::word
-    ClosureData_default_type_arguments_info_offset = 40;
+    ClosureData_default_type_arguments_kind_offset = 40;
 static constexpr dart::compiler::target::word Code_object_pool_offset = 40;
 static constexpr dart::compiler::target::word Code_saved_instructions_offset =
     48;
@@ -1829,9 +1829,9 @@
 static constexpr dart::compiler::target::word
     Thread_AllocateArray_entry_point_offset = 728;
 static constexpr dart::compiler::target::word Thread_active_exception_offset =
-    1464;
+    1488;
 static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
-    1472;
+    1496;
 static constexpr dart::compiler::target::word
     Thread_array_write_barrier_code_offset = 232;
 static constexpr dart::compiler::target::word
@@ -1857,7 +1857,7 @@
 static constexpr dart::compiler::target::word
     Thread_allocate_object_slow_stub_offset = 384;
 static constexpr dart::compiler::target::word Thread_api_top_scope_offset =
-    1544;
+    1568;
 static constexpr dart::compiler::target::word
     Thread_auto_scope_native_wrapper_entry_point_offset = 656;
 static constexpr dart::compiler::target::word Thread_bool_false_offset = 216;
@@ -1868,7 +1868,7 @@
     Thread_call_to_runtime_entry_point_offset = 528;
 static constexpr dart::compiler::target::word
     Thread_call_to_runtime_stub_offset = 264;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1560;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1584;
 static constexpr dart::compiler::target::word
     Thread_dispatch_table_array_offset = 96;
 static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
@@ -1886,7 +1886,7 @@
 static constexpr dart::compiler::target::word
     Thread_enter_safepoint_stub_offset = 488;
 static constexpr dart::compiler::target::word Thread_execution_state_offset =
-    1504;
+    1528;
 static constexpr dart::compiler::target::word
     Thread_exit_safepoint_stub_offset = 496;
 static constexpr dart::compiler::target::word
@@ -1906,14 +1906,14 @@
 static constexpr dart::compiler::target::word
     Thread_float_zerow_address_offset = 720;
 static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
-    1480;
+    1504;
 static constexpr dart::compiler::target::word
     Thread_invoke_dart_code_stub_offset = 256;
 static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset =
-    1536;
+    1560;
 static constexpr dart::compiler::target::word Thread_isolate_offset = 88;
 static constexpr dart::compiler::target::word Thread_isolate_group_offset =
-    1568;
+    1592;
 static constexpr dart::compiler::target::word Thread_field_table_values_offset =
     136;
 static constexpr dart::compiler::target::word
@@ -1955,11 +1955,11 @@
 static constexpr dart::compiler::target::word Thread_object_null_offset = 200;
 static constexpr dart::compiler::target::word
     Thread_predefined_symbols_address_offset = 664;
-static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1488;
+static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1512;
 static constexpr dart::compiler::target::word
-    Thread_saved_shadow_call_stack_offset = 1496;
+    Thread_saved_shadow_call_stack_offset = 1520;
 static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
-    1512;
+    1536;
 static constexpr dart::compiler::target::word
     Thread_slow_type_test_stub_offset = 472;
 static constexpr dart::compiler::target::word
@@ -1994,9 +1994,9 @@
     72;
 static constexpr dart::compiler::target::word Thread_heap_base_offset = 80;
 static constexpr dart::compiler::target::word Thread_callback_code_offset =
-    1520;
+    1544;
 static constexpr dart::compiler::target::word
-    Thread_callback_stack_return_offset = 1528;
+    Thread_callback_stack_return_offset = 1552;
 static constexpr dart::compiler::target::word TimelineStream_enabled_offset =
     16;
 static constexpr dart::compiler::target::word TwoByteString_data_offset = 16;
@@ -2059,9 +2059,9 @@
     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,   -1,   1448, 1456, -1,   -1,   -1,   -1,   -1,   -1};
+        1336, 1344, 1352, 1360, 1368, 1376, 1384, 1392, 1400, 1408, 1416,
+        1424, 1432, 1440, 1448, -1,   -1,   -1,   -1,   1456, 1464, -1,
+        -1,   -1,   1472, 1480, -1,   -1,   -1,   -1,   -1,   -1};
 static constexpr dart::compiler::target::word AbstractType_InstanceSize = 24;
 static constexpr dart::compiler::target::word ApiError_InstanceSize = 16;
 static constexpr dart::compiler::target::word Array_InstanceSize = 24;
@@ -2163,14 +2163,14 @@
 
 #if defined(TARGET_ARCH_X64) && defined(DART_COMPRESSED_POINTERS)
 static constexpr dart::compiler::target::word Function_usage_counter_offset =
-    116;
+    84;
 static constexpr dart::compiler::target::word
     ICData_receivers_static_type_offset = 32;
 static constexpr dart::compiler::target::word
     ContextScope_elements_start_offset = 16;
-static constexpr dart::compiler::target::word ContextScope_element_size = 64;
+static constexpr dart::compiler::target::word ContextScope_element_size = 32;
 static constexpr dart::compiler::target::word
-    ExceptionHandlers_elements_start_offset = 24;
+    ExceptionHandlers_elements_start_offset = 16;
 static constexpr dart::compiler::target::word ExceptionHandlers_element_size =
     12;
 static constexpr dart::compiler::target::word ObjectPool_elements_start_offset =
@@ -2237,12 +2237,12 @@
 static constexpr dart::compiler::target::word Array_tags_offset = 0;
 static constexpr dart::compiler::target::word Array_type_arguments_offset = 8;
 static constexpr dart::compiler::target::word Class_declaration_type_offset =
-    104;
+    56;
 static constexpr dart::compiler::target::word Class_num_type_arguments_offset =
-    164;
-static constexpr dart::compiler::target::word Class_super_type_offset = 88;
+    92;
+static constexpr dart::compiler::target::word Class_super_type_offset = 48;
 static constexpr dart::compiler::target::word
-    Class_host_type_arguments_field_offset_in_words_offset = 176;
+    Class_host_type_arguments_field_offset_in_words_offset = 104;
 static constexpr dart::compiler::target::word
     SharedClassTable_class_heap_stats_table_offset = 0;
 static constexpr dart::compiler::target::word Closure_context_offset = 40;
@@ -2255,9 +2255,9 @@
 static constexpr dart::compiler::target::word
     Closure_instantiator_type_arguments_offset = 8;
 static constexpr dart::compiler::target::word
-    ClosureData_default_type_arguments_offset = 32;
+    ClosureData_default_type_arguments_offset = 20;
 static constexpr dart::compiler::target::word
-    ClosureData_default_type_arguments_info_offset = 40;
+    ClosureData_default_type_arguments_kind_offset = 24;
 static constexpr dart::compiler::target::word Code_object_pool_offset = 40;
 static constexpr dart::compiler::target::word Code_saved_instructions_offset =
     48;
@@ -2272,24 +2272,24 @@
 static constexpr dart::compiler::target::word Float32x4_value_offset = 8;
 static constexpr dart::compiler::target::word Float64x2_value_offset = 8;
 static constexpr dart::compiler::target::word
-    Field_initializer_function_offset = 32;
+    Field_initializer_function_offset = 20;
 static constexpr dart::compiler::target::word
-    Field_host_offset_or_field_id_offset = 40;
-static constexpr dart::compiler::target::word Field_guarded_cid_offset = 80;
+    Field_host_offset_or_field_id_offset = 24;
+static constexpr dart::compiler::target::word Field_guarded_cid_offset = 48;
 static constexpr dart::compiler::target::word
-    Field_guarded_list_length_in_object_offset_offset = 88;
+    Field_guarded_list_length_in_object_offset_offset = 56;
 static constexpr dart::compiler::target::word Field_guarded_list_length_offset =
-    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 = 72;
-static constexpr dart::compiler::target::word Function_data_offset = 56;
+    28;
+static constexpr dart::compiler::target::word Field_is_nullable_offset = 50;
+static constexpr dart::compiler::target::word Field_kind_bits_offset = 58;
+static constexpr dart::compiler::target::word Function_code_offset = 48;
+static constexpr dart::compiler::target::word Function_data_offset = 40;
 static constexpr dart::compiler::target::word Function_entry_point_offset[] = {
     8, 16};
-static constexpr dart::compiler::target::word Function_kind_tag_offset = 104;
+static constexpr dart::compiler::target::word Function_kind_tag_offset = 72;
 static constexpr dart::compiler::target::word Function_packed_fields_offset =
-    108;
-static constexpr dart::compiler::target::word Function_signature_offset = 48;
+    76;
+static constexpr dart::compiler::target::word Function_signature_offset = 36;
 static constexpr dart::compiler::target::word FutureOr_type_arguments_offset =
     8;
 static constexpr dart::compiler::target::word GrowableObjectArray_data_offset =
@@ -2369,9 +2369,9 @@
 static constexpr dart::compiler::target::word
     Thread_AllocateArray_entry_point_offset = 728;
 static constexpr dart::compiler::target::word Thread_active_exception_offset =
-    1400;
+    1424;
 static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
-    1408;
+    1432;
 static constexpr dart::compiler::target::word
     Thread_array_write_barrier_code_offset = 232;
 static constexpr dart::compiler::target::word
@@ -2397,7 +2397,7 @@
 static constexpr dart::compiler::target::word
     Thread_allocate_object_slow_stub_offset = 384;
 static constexpr dart::compiler::target::word Thread_api_top_scope_offset =
-    1480;
+    1504;
 static constexpr dart::compiler::target::word
     Thread_auto_scope_native_wrapper_entry_point_offset = 656;
 static constexpr dart::compiler::target::word Thread_bool_false_offset = 216;
@@ -2408,7 +2408,7 @@
     Thread_call_to_runtime_entry_point_offset = 528;
 static constexpr dart::compiler::target::word
     Thread_call_to_runtime_stub_offset = 264;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1496;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1520;
 static constexpr dart::compiler::target::word
     Thread_dispatch_table_array_offset = 96;
 static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
@@ -2426,7 +2426,7 @@
 static constexpr dart::compiler::target::word
     Thread_enter_safepoint_stub_offset = 488;
 static constexpr dart::compiler::target::word Thread_execution_state_offset =
-    1440;
+    1464;
 static constexpr dart::compiler::target::word
     Thread_exit_safepoint_stub_offset = 496;
 static constexpr dart::compiler::target::word
@@ -2446,14 +2446,14 @@
 static constexpr dart::compiler::target::word
     Thread_float_zerow_address_offset = 720;
 static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
-    1416;
+    1440;
 static constexpr dart::compiler::target::word
     Thread_invoke_dart_code_stub_offset = 256;
 static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset =
-    1472;
+    1496;
 static constexpr dart::compiler::target::word Thread_isolate_offset = 88;
 static constexpr dart::compiler::target::word Thread_isolate_group_offset =
-    1504;
+    1528;
 static constexpr dart::compiler::target::word Thread_field_table_values_offset =
     136;
 static constexpr dart::compiler::target::word
@@ -2495,11 +2495,11 @@
 static constexpr dart::compiler::target::word Thread_object_null_offset = 200;
 static constexpr dart::compiler::target::word
     Thread_predefined_symbols_address_offset = 664;
-static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1424;
+static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1448;
 static constexpr dart::compiler::target::word
-    Thread_saved_shadow_call_stack_offset = 1432;
+    Thread_saved_shadow_call_stack_offset = 1456;
 static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
-    1448;
+    1472;
 static constexpr dart::compiler::target::word
     Thread_slow_type_test_stub_offset = 472;
 static constexpr dart::compiler::target::word
@@ -2534,50 +2534,50 @@
     72;
 static constexpr dart::compiler::target::word Thread_heap_base_offset = 80;
 static constexpr dart::compiler::target::word Thread_callback_code_offset =
-    1456;
+    1480;
 static constexpr dart::compiler::target::word
-    Thread_callback_stack_return_offset = 1464;
+    Thread_callback_stack_return_offset = 1488;
 static constexpr dart::compiler::target::word TimelineStream_enabled_offset =
     16;
 static constexpr dart::compiler::target::word TwoByteString_data_offset = 16;
-static constexpr dart::compiler::target::word Type_arguments_offset = 32;
-static constexpr dart::compiler::target::word Type_hash_offset = 40;
-static constexpr dart::compiler::target::word Type_type_class_id_offset = 24;
-static constexpr dart::compiler::target::word Type_type_state_offset = 48;
-static constexpr dart::compiler::target::word Type_nullability_offset = 49;
-static constexpr dart::compiler::target::word FunctionType_hash_offset = 56;
+static constexpr dart::compiler::target::word Type_arguments_offset = 24;
+static constexpr dart::compiler::target::word Type_hash_offset = 28;
+static constexpr dart::compiler::target::word Type_type_class_id_offset = 20;
+static constexpr dart::compiler::target::word Type_type_state_offset = 32;
+static constexpr dart::compiler::target::word Type_nullability_offset = 33;
+static constexpr dart::compiler::target::word FunctionType_hash_offset = 36;
 static constexpr dart::compiler::target::word
-    FunctionType_packed_fields_offset = 64;
+    FunctionType_packed_fields_offset = 40;
 static constexpr dart::compiler::target::word
-    FunctionType_parameter_types_offset = 40;
+    FunctionType_parameter_types_offset = 28;
 static constexpr dart::compiler::target::word
-    FunctionType_parameter_names_offset = 48;
+    FunctionType_parameter_names_offset = 32;
 static constexpr dart::compiler::target::word
-    FunctionType_type_parameters_offset = 24;
+    FunctionType_type_parameters_offset = 20;
 static constexpr dart::compiler::target::word
-    TypeParameter_parameterized_class_id_offset = 56;
-static constexpr dart::compiler::target::word TypeParameter_index_offset = 60;
+    TypeParameter_parameterized_class_id_offset = 36;
+static constexpr dart::compiler::target::word TypeParameter_index_offset = 40;
 static constexpr dart::compiler::target::word TypeParameter_nullability_offset =
-    63;
+    43;
 static constexpr dart::compiler::target::word
     TypeArguments_instantiations_offset = 8;
 static constexpr dart::compiler::target::word TypeArguments_length_offset = 16;
 static constexpr dart::compiler::target::word TypeArguments_nullability_offset =
     32;
 static constexpr dart::compiler::target::word TypeArguments_types_offset = 40;
-static constexpr dart::compiler::target::word TypeParameter_bound_offset = 40;
-static constexpr dart::compiler::target::word TypeParameter_flags_offset = 62;
-static constexpr dart::compiler::target::word TypeParameter_name_offset = 24;
-static constexpr dart::compiler::target::word TypeRef_type_offset = 24;
+static constexpr dart::compiler::target::word TypeParameter_bound_offset = 28;
+static constexpr dart::compiler::target::word TypeParameter_flags_offset = 42;
+static constexpr dart::compiler::target::word TypeParameter_name_offset = 20;
+static constexpr dart::compiler::target::word TypeRef_type_offset = 20;
 static constexpr dart::compiler::target::word TypedDataBase_length_offset = 16;
-static constexpr dart::compiler::target::word TypedDataView_data_offset = 24;
+static constexpr dart::compiler::target::word TypedDataView_data_offset = 20;
 static constexpr dart::compiler::target::word
-    TypedDataView_offset_in_bytes_offset = 32;
+    TypedDataView_offset_in_bytes_offset = 24;
 static constexpr dart::compiler::target::word TypedData_data_offset = 24;
 static constexpr dart::compiler::target::word
     UnhandledException_exception_offset = 8;
 static constexpr dart::compiler::target::word
-    UnhandledException_stacktrace_offset = 16;
+    UnhandledException_stacktrace_offset = 12;
 static constexpr dart::compiler::target::word UserTag_tag_offset = 16;
 static constexpr dart::compiler::target::word
     MonomorphicSmiableCall_expected_cid_offset = 16;
@@ -2599,17 +2599,17 @@
     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};
+        1336, 1344, 1352, 1360, -1,   -1,   1368, 1376,
+        1384, 1392, 1400, -1,   1408, 1416, -1,   -1};
 static constexpr dart::compiler::target::word AbstractType_InstanceSize = 24;
 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 = 16;
 static constexpr dart::compiler::target::word Capability_InstanceSize = 16;
-static constexpr dart::compiler::target::word Class_InstanceSize = 200;
+static constexpr dart::compiler::target::word Class_InstanceSize = 128;
 static constexpr dart::compiler::target::word Closure_InstanceSize = 56;
-static constexpr dart::compiler::target::word ClosureData_InstanceSize = 48;
+static constexpr dart::compiler::target::word ClosureData_InstanceSize = 32;
 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 =
@@ -2620,7 +2620,7 @@
 static constexpr dart::compiler::target::word Double_InstanceSize = 16;
 static constexpr dart::compiler::target::word DynamicLibrary_InstanceSize = 16;
 static constexpr dart::compiler::target::word ExceptionHandlers_InstanceSize =
-    24;
+    16;
 static constexpr dart::compiler::target::word
     ExternalOneByteString_InstanceSize = 32;
 static constexpr dart::compiler::target::word
@@ -2628,12 +2628,12 @@
 static constexpr dart::compiler::target::word ExternalTypedData_InstanceSize =
     24;
 static constexpr dart::compiler::target::word FfiTrampolineData_InstanceSize =
-    48;
-static constexpr dart::compiler::target::word Field_InstanceSize = 96;
+    32;
+static constexpr dart::compiler::target::word Field_InstanceSize = 64;
 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 = 128;
-static constexpr dart::compiler::target::word FunctionType_InstanceSize = 72;
+static constexpr dart::compiler::target::word Function_InstanceSize = 96;
+static constexpr dart::compiler::target::word FunctionType_InstanceSize = 48;
 static constexpr dart::compiler::target::word FutureOr_InstanceSize = 16;
 static constexpr dart::compiler::target::word GrowableObjectArray_InstanceSize =
     32;
@@ -2646,10 +2646,10 @@
 static constexpr dart::compiler::target::word Int32x4_InstanceSize = 24;
 static constexpr dart::compiler::target::word Integer_InstanceSize = 8;
 static constexpr dart::compiler::target::word KernelProgramInfo_InstanceSize =
-    120;
-static constexpr dart::compiler::target::word LanguageError_InstanceSize = 48;
-static constexpr dart::compiler::target::word Library_InstanceSize = 160;
-static constexpr dart::compiler::target::word LibraryPrefix_InstanceSize = 40;
+    64;
+static constexpr dart::compiler::target::word LanguageError_InstanceSize = 32;
+static constexpr dart::compiler::target::word Library_InstanceSize = 104;
+static constexpr dart::compiler::target::word LibraryPrefix_InstanceSize = 24;
 static constexpr dart::compiler::target::word LinkedHashMap_InstanceSize = 56;
 static constexpr dart::compiler::target::word LocalVarDescriptors_InstanceSize =
     16;
@@ -2659,57 +2659,57 @@
 static constexpr dart::compiler::target::word MirrorReference_InstanceSize = 16;
 static constexpr dart::compiler::target::word
     MonomorphicSmiableCall_InstanceSize = 32;
-static constexpr dart::compiler::target::word Namespace_InstanceSize = 40;
+static constexpr dart::compiler::target::word Namespace_InstanceSize = 24;
 static constexpr dart::compiler::target::word NativeArguments_StructSize = 32;
 static constexpr dart::compiler::target::word Number_InstanceSize = 8;
 static constexpr dart::compiler::target::word Object_InstanceSize = 8;
 static constexpr dart::compiler::target::word ObjectPool_InstanceSize = 16;
 static constexpr dart::compiler::target::word OneByteString_InstanceSize = 16;
-static constexpr dart::compiler::target::word PatchClass_InstanceSize = 48;
+static constexpr dart::compiler::target::word PatchClass_InstanceSize = 32;
 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 RegExp_InstanceSize = 120;
-static constexpr dart::compiler::target::word Script_InstanceSize = 104;
+static constexpr dart::compiler::target::word ReceivePort_InstanceSize = 24;
+static constexpr dart::compiler::target::word RegExp_InstanceSize = 80;
+static constexpr dart::compiler::target::word Script_InstanceSize = 72;
 static constexpr dart::compiler::target::word SendPort_InstanceSize = 24;
 static constexpr dart::compiler::target::word SingleTargetCache_InstanceSize =
     32;
 static constexpr dart::compiler::target::word Smi_InstanceSize = 8;
-static constexpr dart::compiler::target::word StackTrace_InstanceSize = 40;
+static constexpr dart::compiler::target::word StackTrace_InstanceSize = 24;
 static constexpr dart::compiler::target::word String_InstanceSize = 16;
 static constexpr dart::compiler::target::word SubtypeTestCache_InstanceSize =
     16;
-static constexpr dart::compiler::target::word LoadingUnit_InstanceSize = 32;
+static constexpr dart::compiler::target::word LoadingUnit_InstanceSize = 24;
 static constexpr dart::compiler::target::word
     TransferableTypedData_InstanceSize = 8;
 static constexpr dart::compiler::target::word TwoByteString_InstanceSize = 16;
-static constexpr dart::compiler::target::word Type_InstanceSize = 56;
+static constexpr dart::compiler::target::word Type_InstanceSize = 40;
 static constexpr dart::compiler::target::word TypeArguments_InstanceSize = 40;
-static constexpr dart::compiler::target::word TypeParameter_InstanceSize = 64;
-static constexpr dart::compiler::target::word TypeRef_InstanceSize = 32;
+static constexpr dart::compiler::target::word TypeParameter_InstanceSize = 48;
+static constexpr dart::compiler::target::word TypeRef_InstanceSize = 24;
 static constexpr dart::compiler::target::word TypedData_InstanceSize = 24;
 static constexpr dart::compiler::target::word TypedDataBase_InstanceSize = 24;
-static constexpr dart::compiler::target::word TypedDataView_InstanceSize = 40;
+static constexpr dart::compiler::target::word TypedDataView_InstanceSize = 32;
 static constexpr dart::compiler::target::word UnhandledException_InstanceSize =
-    24;
+    16;
 static constexpr dart::compiler::target::word UnlinkedCall_InstanceSize = 32;
-static constexpr dart::compiler::target::word UnwindError_InstanceSize = 24;
+static constexpr dart::compiler::target::word UnwindError_InstanceSize = 16;
 static constexpr dart::compiler::target::word UserTag_InstanceSize = 24;
 static constexpr dart::compiler::target::word WeakProperty_InstanceSize = 32;
 static constexpr dart::compiler::target::word
-    WeakSerializationReference_InstanceSize = 24;
+    WeakSerializationReference_InstanceSize = 16;
 #endif  // defined(TARGET_ARCH_X64) && defined(DART_COMPRESSED_POINTERS)
 
 #if defined(TARGET_ARCH_ARM64) && defined(DART_COMPRESSED_POINTERS)
 static constexpr dart::compiler::target::word Function_usage_counter_offset =
-    116;
+    84;
 static constexpr dart::compiler::target::word
     ICData_receivers_static_type_offset = 32;
 static constexpr dart::compiler::target::word
     ContextScope_elements_start_offset = 16;
-static constexpr dart::compiler::target::word ContextScope_element_size = 64;
+static constexpr dart::compiler::target::word ContextScope_element_size = 32;
 static constexpr dart::compiler::target::word
-    ExceptionHandlers_elements_start_offset = 24;
+    ExceptionHandlers_elements_start_offset = 16;
 static constexpr dart::compiler::target::word ExceptionHandlers_element_size =
     12;
 static constexpr dart::compiler::target::word ObjectPool_elements_start_offset =
@@ -2776,12 +2776,12 @@
 static constexpr dart::compiler::target::word Array_tags_offset = 0;
 static constexpr dart::compiler::target::word Array_type_arguments_offset = 8;
 static constexpr dart::compiler::target::word Class_declaration_type_offset =
-    104;
+    56;
 static constexpr dart::compiler::target::word Class_num_type_arguments_offset =
-    164;
-static constexpr dart::compiler::target::word Class_super_type_offset = 88;
+    92;
+static constexpr dart::compiler::target::word Class_super_type_offset = 48;
 static constexpr dart::compiler::target::word
-    Class_host_type_arguments_field_offset_in_words_offset = 176;
+    Class_host_type_arguments_field_offset_in_words_offset = 104;
 static constexpr dart::compiler::target::word
     SharedClassTable_class_heap_stats_table_offset = 0;
 static constexpr dart::compiler::target::word Closure_context_offset = 40;
@@ -2794,9 +2794,9 @@
 static constexpr dart::compiler::target::word
     Closure_instantiator_type_arguments_offset = 8;
 static constexpr dart::compiler::target::word
-    ClosureData_default_type_arguments_offset = 32;
+    ClosureData_default_type_arguments_offset = 20;
 static constexpr dart::compiler::target::word
-    ClosureData_default_type_arguments_info_offset = 40;
+    ClosureData_default_type_arguments_kind_offset = 24;
 static constexpr dart::compiler::target::word Code_object_pool_offset = 40;
 static constexpr dart::compiler::target::word Code_saved_instructions_offset =
     48;
@@ -2811,24 +2811,24 @@
 static constexpr dart::compiler::target::word Float32x4_value_offset = 8;
 static constexpr dart::compiler::target::word Float64x2_value_offset = 8;
 static constexpr dart::compiler::target::word
-    Field_initializer_function_offset = 32;
+    Field_initializer_function_offset = 20;
 static constexpr dart::compiler::target::word
-    Field_host_offset_or_field_id_offset = 40;
-static constexpr dart::compiler::target::word Field_guarded_cid_offset = 80;
+    Field_host_offset_or_field_id_offset = 24;
+static constexpr dart::compiler::target::word Field_guarded_cid_offset = 48;
 static constexpr dart::compiler::target::word
-    Field_guarded_list_length_in_object_offset_offset = 88;
+    Field_guarded_list_length_in_object_offset_offset = 56;
 static constexpr dart::compiler::target::word Field_guarded_list_length_offset =
-    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 = 72;
-static constexpr dart::compiler::target::word Function_data_offset = 56;
+    28;
+static constexpr dart::compiler::target::word Field_is_nullable_offset = 50;
+static constexpr dart::compiler::target::word Field_kind_bits_offset = 58;
+static constexpr dart::compiler::target::word Function_code_offset = 48;
+static constexpr dart::compiler::target::word Function_data_offset = 40;
 static constexpr dart::compiler::target::word Function_entry_point_offset[] = {
     8, 16};
-static constexpr dart::compiler::target::word Function_kind_tag_offset = 104;
+static constexpr dart::compiler::target::word Function_kind_tag_offset = 72;
 static constexpr dart::compiler::target::word Function_packed_fields_offset =
-    108;
-static constexpr dart::compiler::target::word Function_signature_offset = 48;
+    76;
+static constexpr dart::compiler::target::word Function_signature_offset = 36;
 static constexpr dart::compiler::target::word FutureOr_type_arguments_offset =
     8;
 static constexpr dart::compiler::target::word GrowableObjectArray_data_offset =
@@ -2908,9 +2908,9 @@
 static constexpr dart::compiler::target::word
     Thread_AllocateArray_entry_point_offset = 728;
 static constexpr dart::compiler::target::word Thread_active_exception_offset =
-    1464;
+    1488;
 static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
-    1472;
+    1496;
 static constexpr dart::compiler::target::word
     Thread_array_write_barrier_code_offset = 232;
 static constexpr dart::compiler::target::word
@@ -2936,7 +2936,7 @@
 static constexpr dart::compiler::target::word
     Thread_allocate_object_slow_stub_offset = 384;
 static constexpr dart::compiler::target::word Thread_api_top_scope_offset =
-    1544;
+    1568;
 static constexpr dart::compiler::target::word
     Thread_auto_scope_native_wrapper_entry_point_offset = 656;
 static constexpr dart::compiler::target::word Thread_bool_false_offset = 216;
@@ -2947,7 +2947,7 @@
     Thread_call_to_runtime_entry_point_offset = 528;
 static constexpr dart::compiler::target::word
     Thread_call_to_runtime_stub_offset = 264;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1560;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1584;
 static constexpr dart::compiler::target::word
     Thread_dispatch_table_array_offset = 96;
 static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
@@ -2965,7 +2965,7 @@
 static constexpr dart::compiler::target::word
     Thread_enter_safepoint_stub_offset = 488;
 static constexpr dart::compiler::target::word Thread_execution_state_offset =
-    1504;
+    1528;
 static constexpr dart::compiler::target::word
     Thread_exit_safepoint_stub_offset = 496;
 static constexpr dart::compiler::target::word
@@ -2985,14 +2985,14 @@
 static constexpr dart::compiler::target::word
     Thread_float_zerow_address_offset = 720;
 static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
-    1480;
+    1504;
 static constexpr dart::compiler::target::word
     Thread_invoke_dart_code_stub_offset = 256;
 static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset =
-    1536;
+    1560;
 static constexpr dart::compiler::target::word Thread_isolate_offset = 88;
 static constexpr dart::compiler::target::word Thread_isolate_group_offset =
-    1568;
+    1592;
 static constexpr dart::compiler::target::word Thread_field_table_values_offset =
     136;
 static constexpr dart::compiler::target::word
@@ -3034,11 +3034,11 @@
 static constexpr dart::compiler::target::word Thread_object_null_offset = 200;
 static constexpr dart::compiler::target::word
     Thread_predefined_symbols_address_offset = 664;
-static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1488;
+static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1512;
 static constexpr dart::compiler::target::word
-    Thread_saved_shadow_call_stack_offset = 1496;
+    Thread_saved_shadow_call_stack_offset = 1520;
 static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
-    1512;
+    1536;
 static constexpr dart::compiler::target::word
     Thread_slow_type_test_stub_offset = 472;
 static constexpr dart::compiler::target::word
@@ -3073,50 +3073,50 @@
     72;
 static constexpr dart::compiler::target::word Thread_heap_base_offset = 80;
 static constexpr dart::compiler::target::word Thread_callback_code_offset =
-    1520;
+    1544;
 static constexpr dart::compiler::target::word
-    Thread_callback_stack_return_offset = 1528;
+    Thread_callback_stack_return_offset = 1552;
 static constexpr dart::compiler::target::word TimelineStream_enabled_offset =
     16;
 static constexpr dart::compiler::target::word TwoByteString_data_offset = 16;
-static constexpr dart::compiler::target::word Type_arguments_offset = 32;
-static constexpr dart::compiler::target::word Type_hash_offset = 40;
-static constexpr dart::compiler::target::word Type_type_class_id_offset = 24;
-static constexpr dart::compiler::target::word Type_type_state_offset = 48;
-static constexpr dart::compiler::target::word Type_nullability_offset = 49;
-static constexpr dart::compiler::target::word FunctionType_hash_offset = 56;
+static constexpr dart::compiler::target::word Type_arguments_offset = 24;
+static constexpr dart::compiler::target::word Type_hash_offset = 28;
+static constexpr dart::compiler::target::word Type_type_class_id_offset = 20;
+static constexpr dart::compiler::target::word Type_type_state_offset = 32;
+static constexpr dart::compiler::target::word Type_nullability_offset = 33;
+static constexpr dart::compiler::target::word FunctionType_hash_offset = 36;
 static constexpr dart::compiler::target::word
-    FunctionType_packed_fields_offset = 64;
+    FunctionType_packed_fields_offset = 40;
 static constexpr dart::compiler::target::word
-    FunctionType_parameter_types_offset = 40;
+    FunctionType_parameter_types_offset = 28;
 static constexpr dart::compiler::target::word
-    FunctionType_parameter_names_offset = 48;
+    FunctionType_parameter_names_offset = 32;
 static constexpr dart::compiler::target::word
-    FunctionType_type_parameters_offset = 24;
+    FunctionType_type_parameters_offset = 20;
 static constexpr dart::compiler::target::word
-    TypeParameter_parameterized_class_id_offset = 56;
-static constexpr dart::compiler::target::word TypeParameter_index_offset = 60;
+    TypeParameter_parameterized_class_id_offset = 36;
+static constexpr dart::compiler::target::word TypeParameter_index_offset = 40;
 static constexpr dart::compiler::target::word TypeParameter_nullability_offset =
-    63;
+    43;
 static constexpr dart::compiler::target::word
     TypeArguments_instantiations_offset = 8;
 static constexpr dart::compiler::target::word TypeArguments_length_offset = 16;
 static constexpr dart::compiler::target::word TypeArguments_nullability_offset =
     32;
 static constexpr dart::compiler::target::word TypeArguments_types_offset = 40;
-static constexpr dart::compiler::target::word TypeParameter_bound_offset = 40;
-static constexpr dart::compiler::target::word TypeParameter_flags_offset = 62;
-static constexpr dart::compiler::target::word TypeParameter_name_offset = 24;
-static constexpr dart::compiler::target::word TypeRef_type_offset = 24;
+static constexpr dart::compiler::target::word TypeParameter_bound_offset = 28;
+static constexpr dart::compiler::target::word TypeParameter_flags_offset = 42;
+static constexpr dart::compiler::target::word TypeParameter_name_offset = 20;
+static constexpr dart::compiler::target::word TypeRef_type_offset = 20;
 static constexpr dart::compiler::target::word TypedDataBase_length_offset = 16;
-static constexpr dart::compiler::target::word TypedDataView_data_offset = 24;
+static constexpr dart::compiler::target::word TypedDataView_data_offset = 20;
 static constexpr dart::compiler::target::word
-    TypedDataView_offset_in_bytes_offset = 32;
+    TypedDataView_offset_in_bytes_offset = 24;
 static constexpr dart::compiler::target::word TypedData_data_offset = 24;
 static constexpr dart::compiler::target::word
     UnhandledException_exception_offset = 8;
 static constexpr dart::compiler::target::word
-    UnhandledException_stacktrace_offset = 16;
+    UnhandledException_stacktrace_offset = 12;
 static constexpr dart::compiler::target::word UserTag_tag_offset = 16;
 static constexpr dart::compiler::target::word
     MonomorphicSmiableCall_expected_cid_offset = 16;
@@ -3138,18 +3138,18 @@
     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,   -1,   1448, 1456, -1,   -1,   -1,   -1,   -1,   -1};
+        1336, 1344, 1352, 1360, 1368, 1376, 1384, 1392, 1400, 1408, 1416,
+        1424, 1432, 1440, 1448, -1,   -1,   -1,   -1,   1456, 1464, -1,
+        -1,   -1,   1472, 1480, -1,   -1,   -1,   -1,   -1,   -1};
 static constexpr dart::compiler::target::word AbstractType_InstanceSize = 24;
 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 = 16;
 static constexpr dart::compiler::target::word Capability_InstanceSize = 16;
-static constexpr dart::compiler::target::word Class_InstanceSize = 200;
+static constexpr dart::compiler::target::word Class_InstanceSize = 128;
 static constexpr dart::compiler::target::word Closure_InstanceSize = 56;
-static constexpr dart::compiler::target::word ClosureData_InstanceSize = 48;
+static constexpr dart::compiler::target::word ClosureData_InstanceSize = 32;
 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 =
@@ -3160,7 +3160,7 @@
 static constexpr dart::compiler::target::word Double_InstanceSize = 16;
 static constexpr dart::compiler::target::word DynamicLibrary_InstanceSize = 16;
 static constexpr dart::compiler::target::word ExceptionHandlers_InstanceSize =
-    24;
+    16;
 static constexpr dart::compiler::target::word
     ExternalOneByteString_InstanceSize = 32;
 static constexpr dart::compiler::target::word
@@ -3168,12 +3168,12 @@
 static constexpr dart::compiler::target::word ExternalTypedData_InstanceSize =
     24;
 static constexpr dart::compiler::target::word FfiTrampolineData_InstanceSize =
-    48;
-static constexpr dart::compiler::target::word Field_InstanceSize = 96;
+    32;
+static constexpr dart::compiler::target::word Field_InstanceSize = 64;
 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 = 128;
-static constexpr dart::compiler::target::word FunctionType_InstanceSize = 72;
+static constexpr dart::compiler::target::word Function_InstanceSize = 96;
+static constexpr dart::compiler::target::word FunctionType_InstanceSize = 48;
 static constexpr dart::compiler::target::word FutureOr_InstanceSize = 16;
 static constexpr dart::compiler::target::word GrowableObjectArray_InstanceSize =
     32;
@@ -3186,10 +3186,10 @@
 static constexpr dart::compiler::target::word Int32x4_InstanceSize = 24;
 static constexpr dart::compiler::target::word Integer_InstanceSize = 8;
 static constexpr dart::compiler::target::word KernelProgramInfo_InstanceSize =
-    120;
-static constexpr dart::compiler::target::word LanguageError_InstanceSize = 48;
-static constexpr dart::compiler::target::word Library_InstanceSize = 160;
-static constexpr dart::compiler::target::word LibraryPrefix_InstanceSize = 40;
+    64;
+static constexpr dart::compiler::target::word LanguageError_InstanceSize = 32;
+static constexpr dart::compiler::target::word Library_InstanceSize = 104;
+static constexpr dart::compiler::target::word LibraryPrefix_InstanceSize = 24;
 static constexpr dart::compiler::target::word LinkedHashMap_InstanceSize = 56;
 static constexpr dart::compiler::target::word LocalVarDescriptors_InstanceSize =
     16;
@@ -3199,45 +3199,45 @@
 static constexpr dart::compiler::target::word MirrorReference_InstanceSize = 16;
 static constexpr dart::compiler::target::word
     MonomorphicSmiableCall_InstanceSize = 32;
-static constexpr dart::compiler::target::word Namespace_InstanceSize = 40;
+static constexpr dart::compiler::target::word Namespace_InstanceSize = 24;
 static constexpr dart::compiler::target::word NativeArguments_StructSize = 32;
 static constexpr dart::compiler::target::word Number_InstanceSize = 8;
 static constexpr dart::compiler::target::word Object_InstanceSize = 8;
 static constexpr dart::compiler::target::word ObjectPool_InstanceSize = 16;
 static constexpr dart::compiler::target::word OneByteString_InstanceSize = 16;
-static constexpr dart::compiler::target::word PatchClass_InstanceSize = 48;
+static constexpr dart::compiler::target::word PatchClass_InstanceSize = 32;
 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 RegExp_InstanceSize = 120;
-static constexpr dart::compiler::target::word Script_InstanceSize = 104;
+static constexpr dart::compiler::target::word ReceivePort_InstanceSize = 24;
+static constexpr dart::compiler::target::word RegExp_InstanceSize = 80;
+static constexpr dart::compiler::target::word Script_InstanceSize = 72;
 static constexpr dart::compiler::target::word SendPort_InstanceSize = 24;
 static constexpr dart::compiler::target::word SingleTargetCache_InstanceSize =
     32;
 static constexpr dart::compiler::target::word Smi_InstanceSize = 8;
-static constexpr dart::compiler::target::word StackTrace_InstanceSize = 40;
+static constexpr dart::compiler::target::word StackTrace_InstanceSize = 24;
 static constexpr dart::compiler::target::word String_InstanceSize = 16;
 static constexpr dart::compiler::target::word SubtypeTestCache_InstanceSize =
     16;
-static constexpr dart::compiler::target::word LoadingUnit_InstanceSize = 32;
+static constexpr dart::compiler::target::word LoadingUnit_InstanceSize = 24;
 static constexpr dart::compiler::target::word
     TransferableTypedData_InstanceSize = 8;
 static constexpr dart::compiler::target::word TwoByteString_InstanceSize = 16;
-static constexpr dart::compiler::target::word Type_InstanceSize = 56;
+static constexpr dart::compiler::target::word Type_InstanceSize = 40;
 static constexpr dart::compiler::target::word TypeArguments_InstanceSize = 40;
-static constexpr dart::compiler::target::word TypeParameter_InstanceSize = 64;
-static constexpr dart::compiler::target::word TypeRef_InstanceSize = 32;
+static constexpr dart::compiler::target::word TypeParameter_InstanceSize = 48;
+static constexpr dart::compiler::target::word TypeRef_InstanceSize = 24;
 static constexpr dart::compiler::target::word TypedData_InstanceSize = 24;
 static constexpr dart::compiler::target::word TypedDataBase_InstanceSize = 24;
-static constexpr dart::compiler::target::word TypedDataView_InstanceSize = 40;
+static constexpr dart::compiler::target::word TypedDataView_InstanceSize = 32;
 static constexpr dart::compiler::target::word UnhandledException_InstanceSize =
-    24;
+    16;
 static constexpr dart::compiler::target::word UnlinkedCall_InstanceSize = 32;
-static constexpr dart::compiler::target::word UnwindError_InstanceSize = 24;
+static constexpr dart::compiler::target::word UnwindError_InstanceSize = 16;
 static constexpr dart::compiler::target::word UserTag_InstanceSize = 24;
 static constexpr dart::compiler::target::word WeakProperty_InstanceSize = 32;
 static constexpr dart::compiler::target::word
-    WeakSerializationReference_InstanceSize = 24;
+    WeakSerializationReference_InstanceSize = 16;
 #endif  // defined(TARGET_ARCH_ARM64) && defined(DART_COMPRESSED_POINTERS)
 
 #else  // !defined(PRODUCT)
@@ -3336,7 +3336,7 @@
 static constexpr dart::compiler::target::word
     ClosureData_default_type_arguments_offset = 16;
 static constexpr dart::compiler::target::word
-    ClosureData_default_type_arguments_info_offset = 20;
+    ClosureData_default_type_arguments_kind_offset = 20;
 static constexpr dart::compiler::target::word Code_object_pool_offset = 20;
 static constexpr dart::compiler::target::word Code_saved_instructions_offset =
     24;
@@ -3446,9 +3446,9 @@
 static constexpr dart::compiler::target::word
     Thread_AllocateArray_entry_point_offset = 368;
 static constexpr dart::compiler::target::word Thread_active_exception_offset =
-    692;
+    704;
 static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
-    696;
+    708;
 static constexpr dart::compiler::target::word
     Thread_array_write_barrier_code_offset = 120;
 static constexpr dart::compiler::target::word
@@ -3473,7 +3473,7 @@
     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 = 732;
+static constexpr dart::compiler::target::word Thread_api_top_scope_offset = 744;
 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;
@@ -3484,7 +3484,7 @@
     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 = 740;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 752;
 static constexpr dart::compiler::target::word
     Thread_dispatch_table_array_offset = 48;
 static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
@@ -3502,7 +3502,7 @@
 static constexpr dart::compiler::target::word
     Thread_enter_safepoint_stub_offset = 248;
 static constexpr dart::compiler::target::word Thread_execution_state_offset =
-    712;
+    724;
 static constexpr dart::compiler::target::word
     Thread_exit_safepoint_stub_offset = 252;
 static constexpr dart::compiler::target::word
@@ -3522,13 +3522,13 @@
 static constexpr dart::compiler::target::word
     Thread_float_zerow_address_offset = 364;
 static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
-    700;
+    712;
 static constexpr dart::compiler::target::word
     Thread_invoke_dart_code_stub_offset = 132;
 static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset =
-    728;
+    740;
 static constexpr dart::compiler::target::word Thread_isolate_offset = 44;
-static constexpr dart::compiler::target::word Thread_isolate_group_offset = 744;
+static constexpr dart::compiler::target::word Thread_isolate_group_offset = 756;
 static constexpr dart::compiler::target::word Thread_field_table_values_offset =
     68;
 static constexpr dart::compiler::target::word
@@ -3570,11 +3570,11 @@
 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_resume_pc_offset = 716;
 static constexpr dart::compiler::target::word
-    Thread_saved_shadow_call_stack_offset = 708;
+    Thread_saved_shadow_call_stack_offset = 720;
 static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
-    716;
+    728;
 static constexpr dart::compiler::target::word
     Thread_slow_type_test_stub_offset = 240;
 static constexpr dart::compiler::target::word
@@ -3608,9 +3608,9 @@
 static constexpr dart::compiler::target::word Thread_write_barrier_mask_offset =
     36;
 static constexpr dart::compiler::target::word Thread_heap_base_offset = 40;
-static constexpr dart::compiler::target::word Thread_callback_code_offset = 720;
+static constexpr dart::compiler::target::word Thread_callback_code_offset = 732;
 static constexpr dart::compiler::target::word
-    Thread_callback_stack_return_offset = 724;
+    Thread_callback_stack_return_offset = 736;
 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;
@@ -3669,7 +3669,7 @@
     4, 12, 8, 16};
 static constexpr dart::compiler::target::word
     Thread_write_barrier_wrappers_thread_offset[] = {
-        660, 664, 668, 672, 676, -1, 680, -1, 684, 688, -1, -1, -1, -1, -1, -1};
+        672, 676, 680, 684, 688, -1, 692, -1, 696, 700, -1, -1, -1, -1, -1, -1};
 static constexpr dart::compiler::target::word AbstractType_InstanceSize = 12;
 static constexpr dart::compiler::target::word ApiError_InstanceSize = 8;
 static constexpr dart::compiler::target::word Array_InstanceSize = 12;
@@ -3864,7 +3864,7 @@
 static constexpr dart::compiler::target::word
     ClosureData_default_type_arguments_offset = 32;
 static constexpr dart::compiler::target::word
-    ClosureData_default_type_arguments_info_offset = 40;
+    ClosureData_default_type_arguments_kind_offset = 40;
 static constexpr dart::compiler::target::word Code_object_pool_offset = 40;
 static constexpr dart::compiler::target::word Code_saved_instructions_offset =
     48;
@@ -3975,9 +3975,9 @@
 static constexpr dart::compiler::target::word
     Thread_AllocateArray_entry_point_offset = 728;
 static constexpr dart::compiler::target::word Thread_active_exception_offset =
-    1400;
+    1424;
 static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
-    1408;
+    1432;
 static constexpr dart::compiler::target::word
     Thread_array_write_barrier_code_offset = 232;
 static constexpr dart::compiler::target::word
@@ -4003,7 +4003,7 @@
 static constexpr dart::compiler::target::word
     Thread_allocate_object_slow_stub_offset = 384;
 static constexpr dart::compiler::target::word Thread_api_top_scope_offset =
-    1480;
+    1504;
 static constexpr dart::compiler::target::word
     Thread_auto_scope_native_wrapper_entry_point_offset = 656;
 static constexpr dart::compiler::target::word Thread_bool_false_offset = 216;
@@ -4014,7 +4014,7 @@
     Thread_call_to_runtime_entry_point_offset = 528;
 static constexpr dart::compiler::target::word
     Thread_call_to_runtime_stub_offset = 264;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1496;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1520;
 static constexpr dart::compiler::target::word
     Thread_dispatch_table_array_offset = 96;
 static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
@@ -4032,7 +4032,7 @@
 static constexpr dart::compiler::target::word
     Thread_enter_safepoint_stub_offset = 488;
 static constexpr dart::compiler::target::word Thread_execution_state_offset =
-    1440;
+    1464;
 static constexpr dart::compiler::target::word
     Thread_exit_safepoint_stub_offset = 496;
 static constexpr dart::compiler::target::word
@@ -4052,14 +4052,14 @@
 static constexpr dart::compiler::target::word
     Thread_float_zerow_address_offset = 720;
 static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
-    1416;
+    1440;
 static constexpr dart::compiler::target::word
     Thread_invoke_dart_code_stub_offset = 256;
 static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset =
-    1472;
+    1496;
 static constexpr dart::compiler::target::word Thread_isolate_offset = 88;
 static constexpr dart::compiler::target::word Thread_isolate_group_offset =
-    1504;
+    1528;
 static constexpr dart::compiler::target::word Thread_field_table_values_offset =
     136;
 static constexpr dart::compiler::target::word
@@ -4101,11 +4101,11 @@
 static constexpr dart::compiler::target::word Thread_object_null_offset = 200;
 static constexpr dart::compiler::target::word
     Thread_predefined_symbols_address_offset = 664;
-static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1424;
+static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1448;
 static constexpr dart::compiler::target::word
-    Thread_saved_shadow_call_stack_offset = 1432;
+    Thread_saved_shadow_call_stack_offset = 1456;
 static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
-    1448;
+    1472;
 static constexpr dart::compiler::target::word
     Thread_slow_type_test_stub_offset = 472;
 static constexpr dart::compiler::target::word
@@ -4140,9 +4140,9 @@
     72;
 static constexpr dart::compiler::target::word Thread_heap_base_offset = 80;
 static constexpr dart::compiler::target::word Thread_callback_code_offset =
-    1456;
+    1480;
 static constexpr dart::compiler::target::word
-    Thread_callback_stack_return_offset = 1464;
+    Thread_callback_stack_return_offset = 1488;
 static constexpr dart::compiler::target::word TimelineStream_enabled_offset =
     16;
 static constexpr dart::compiler::target::word TwoByteString_data_offset = 16;
@@ -4202,8 +4202,8 @@
     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};
+        1336, 1344, 1352, 1360, -1,   -1,   1368, 1376,
+        1384, 1392, 1400, -1,   1408, 1416, -1,   -1};
 static constexpr dart::compiler::target::word AbstractType_InstanceSize = 24;
 static constexpr dart::compiler::target::word ApiError_InstanceSize = 16;
 static constexpr dart::compiler::target::word Array_InstanceSize = 24;
@@ -4397,7 +4397,7 @@
 static constexpr dart::compiler::target::word
     ClosureData_default_type_arguments_offset = 16;
 static constexpr dart::compiler::target::word
-    ClosureData_default_type_arguments_info_offset = 20;
+    ClosureData_default_type_arguments_kind_offset = 20;
 static constexpr dart::compiler::target::word Code_object_pool_offset = 20;
 static constexpr dart::compiler::target::word Code_saved_instructions_offset =
     24;
@@ -4507,9 +4507,9 @@
 static constexpr dart::compiler::target::word
     Thread_AllocateArray_entry_point_offset = 368;
 static constexpr dart::compiler::target::word Thread_active_exception_offset =
-    660;
+    672;
 static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
-    664;
+    676;
 static constexpr dart::compiler::target::word
     Thread_array_write_barrier_code_offset = 120;
 static constexpr dart::compiler::target::word
@@ -4534,7 +4534,7 @@
     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 = 700;
+static constexpr dart::compiler::target::word Thread_api_top_scope_offset = 712;
 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;
@@ -4545,7 +4545,7 @@
     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 = 708;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 720;
 static constexpr dart::compiler::target::word
     Thread_dispatch_table_array_offset = 48;
 static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
@@ -4563,7 +4563,7 @@
 static constexpr dart::compiler::target::word
     Thread_enter_safepoint_stub_offset = 248;
 static constexpr dart::compiler::target::word Thread_execution_state_offset =
-    680;
+    692;
 static constexpr dart::compiler::target::word
     Thread_exit_safepoint_stub_offset = 252;
 static constexpr dart::compiler::target::word
@@ -4583,13 +4583,13 @@
 static constexpr dart::compiler::target::word
     Thread_float_zerow_address_offset = 364;
 static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
-    668;
+    680;
 static constexpr dart::compiler::target::word
     Thread_invoke_dart_code_stub_offset = 132;
 static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset =
-    696;
+    708;
 static constexpr dart::compiler::target::word Thread_isolate_offset = 44;
-static constexpr dart::compiler::target::word Thread_isolate_group_offset = 712;
+static constexpr dart::compiler::target::word Thread_isolate_group_offset = 724;
 static constexpr dart::compiler::target::word Thread_field_table_values_offset =
     68;
 static constexpr dart::compiler::target::word
@@ -4631,11 +4631,11 @@
 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_resume_pc_offset = 684;
 static constexpr dart::compiler::target::word
-    Thread_saved_shadow_call_stack_offset = 676;
+    Thread_saved_shadow_call_stack_offset = 688;
 static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
-    684;
+    696;
 static constexpr dart::compiler::target::word
     Thread_slow_type_test_stub_offset = 240;
 static constexpr dart::compiler::target::word
@@ -4669,9 +4669,9 @@
 static constexpr dart::compiler::target::word Thread_write_barrier_mask_offset =
     36;
 static constexpr dart::compiler::target::word Thread_heap_base_offset = 40;
-static constexpr dart::compiler::target::word Thread_callback_code_offset = 688;
+static constexpr dart::compiler::target::word Thread_callback_code_offset = 700;
 static constexpr dart::compiler::target::word
-    Thread_callback_stack_return_offset = 692;
+    Thread_callback_stack_return_offset = 704;
 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;
@@ -4922,7 +4922,7 @@
 static constexpr dart::compiler::target::word
     ClosureData_default_type_arguments_offset = 32;
 static constexpr dart::compiler::target::word
-    ClosureData_default_type_arguments_info_offset = 40;
+    ClosureData_default_type_arguments_kind_offset = 40;
 static constexpr dart::compiler::target::word Code_object_pool_offset = 40;
 static constexpr dart::compiler::target::word Code_saved_instructions_offset =
     48;
@@ -5033,9 +5033,9 @@
 static constexpr dart::compiler::target::word
     Thread_AllocateArray_entry_point_offset = 728;
 static constexpr dart::compiler::target::word Thread_active_exception_offset =
-    1464;
+    1488;
 static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
-    1472;
+    1496;
 static constexpr dart::compiler::target::word
     Thread_array_write_barrier_code_offset = 232;
 static constexpr dart::compiler::target::word
@@ -5061,7 +5061,7 @@
 static constexpr dart::compiler::target::word
     Thread_allocate_object_slow_stub_offset = 384;
 static constexpr dart::compiler::target::word Thread_api_top_scope_offset =
-    1544;
+    1568;
 static constexpr dart::compiler::target::word
     Thread_auto_scope_native_wrapper_entry_point_offset = 656;
 static constexpr dart::compiler::target::word Thread_bool_false_offset = 216;
@@ -5072,7 +5072,7 @@
     Thread_call_to_runtime_entry_point_offset = 528;
 static constexpr dart::compiler::target::word
     Thread_call_to_runtime_stub_offset = 264;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1560;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1584;
 static constexpr dart::compiler::target::word
     Thread_dispatch_table_array_offset = 96;
 static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
@@ -5090,7 +5090,7 @@
 static constexpr dart::compiler::target::word
     Thread_enter_safepoint_stub_offset = 488;
 static constexpr dart::compiler::target::word Thread_execution_state_offset =
-    1504;
+    1528;
 static constexpr dart::compiler::target::word
     Thread_exit_safepoint_stub_offset = 496;
 static constexpr dart::compiler::target::word
@@ -5110,14 +5110,14 @@
 static constexpr dart::compiler::target::word
     Thread_float_zerow_address_offset = 720;
 static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
-    1480;
+    1504;
 static constexpr dart::compiler::target::word
     Thread_invoke_dart_code_stub_offset = 256;
 static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset =
-    1536;
+    1560;
 static constexpr dart::compiler::target::word Thread_isolate_offset = 88;
 static constexpr dart::compiler::target::word Thread_isolate_group_offset =
-    1568;
+    1592;
 static constexpr dart::compiler::target::word Thread_field_table_values_offset =
     136;
 static constexpr dart::compiler::target::word
@@ -5159,11 +5159,11 @@
 static constexpr dart::compiler::target::word Thread_object_null_offset = 200;
 static constexpr dart::compiler::target::word
     Thread_predefined_symbols_address_offset = 664;
-static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1488;
+static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1512;
 static constexpr dart::compiler::target::word
-    Thread_saved_shadow_call_stack_offset = 1496;
+    Thread_saved_shadow_call_stack_offset = 1520;
 static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
-    1512;
+    1536;
 static constexpr dart::compiler::target::word
     Thread_slow_type_test_stub_offset = 472;
 static constexpr dart::compiler::target::word
@@ -5198,9 +5198,9 @@
     72;
 static constexpr dart::compiler::target::word Thread_heap_base_offset = 80;
 static constexpr dart::compiler::target::word Thread_callback_code_offset =
-    1520;
+    1544;
 static constexpr dart::compiler::target::word
-    Thread_callback_stack_return_offset = 1528;
+    Thread_callback_stack_return_offset = 1552;
 static constexpr dart::compiler::target::word TimelineStream_enabled_offset =
     16;
 static constexpr dart::compiler::target::word TwoByteString_data_offset = 16;
@@ -5260,9 +5260,9 @@
     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,   -1,   1448, 1456, -1,   -1,   -1,   -1,   -1,   -1};
+        1336, 1344, 1352, 1360, 1368, 1376, 1384, 1392, 1400, 1408, 1416,
+        1424, 1432, 1440, 1448, -1,   -1,   -1,   -1,   1456, 1464, -1,
+        -1,   -1,   1472, 1480, -1,   -1,   -1,   -1,   -1,   -1};
 static constexpr dart::compiler::target::word AbstractType_InstanceSize = 24;
 static constexpr dart::compiler::target::word ApiError_InstanceSize = 16;
 static constexpr dart::compiler::target::word Array_InstanceSize = 24;
@@ -5364,14 +5364,14 @@
 
 #if defined(TARGET_ARCH_X64) && defined(DART_COMPRESSED_POINTERS)
 static constexpr dart::compiler::target::word Function_usage_counter_offset =
-    116;
+    84;
 static constexpr dart::compiler::target::word
     ICData_receivers_static_type_offset = 32;
 static constexpr dart::compiler::target::word
     ContextScope_elements_start_offset = 16;
-static constexpr dart::compiler::target::word ContextScope_element_size = 64;
+static constexpr dart::compiler::target::word ContextScope_element_size = 32;
 static constexpr dart::compiler::target::word
-    ExceptionHandlers_elements_start_offset = 24;
+    ExceptionHandlers_elements_start_offset = 16;
 static constexpr dart::compiler::target::word ExceptionHandlers_element_size =
     12;
 static constexpr dart::compiler::target::word ObjectPool_elements_start_offset =
@@ -5438,12 +5438,12 @@
 static constexpr dart::compiler::target::word Array_tags_offset = 0;
 static constexpr dart::compiler::target::word Array_type_arguments_offset = 8;
 static constexpr dart::compiler::target::word Class_declaration_type_offset =
-    104;
+    56;
 static constexpr dart::compiler::target::word Class_num_type_arguments_offset =
-    164;
-static constexpr dart::compiler::target::word Class_super_type_offset = 88;
+    92;
+static constexpr dart::compiler::target::word Class_super_type_offset = 48;
 static constexpr dart::compiler::target::word
-    Class_host_type_arguments_field_offset_in_words_offset = 176;
+    Class_host_type_arguments_field_offset_in_words_offset = 104;
 static constexpr dart::compiler::target::word Closure_context_offset = 40;
 static constexpr dart::compiler::target::word
     Closure_delayed_type_arguments_offset = 24;
@@ -5454,9 +5454,9 @@
 static constexpr dart::compiler::target::word
     Closure_instantiator_type_arguments_offset = 8;
 static constexpr dart::compiler::target::word
-    ClosureData_default_type_arguments_offset = 32;
+    ClosureData_default_type_arguments_offset = 20;
 static constexpr dart::compiler::target::word
-    ClosureData_default_type_arguments_info_offset = 40;
+    ClosureData_default_type_arguments_kind_offset = 24;
 static constexpr dart::compiler::target::word Code_object_pool_offset = 40;
 static constexpr dart::compiler::target::word Code_saved_instructions_offset =
     48;
@@ -5471,24 +5471,24 @@
 static constexpr dart::compiler::target::word Float32x4_value_offset = 8;
 static constexpr dart::compiler::target::word Float64x2_value_offset = 8;
 static constexpr dart::compiler::target::word
-    Field_initializer_function_offset = 32;
+    Field_initializer_function_offset = 20;
 static constexpr dart::compiler::target::word
-    Field_host_offset_or_field_id_offset = 40;
-static constexpr dart::compiler::target::word Field_guarded_cid_offset = 80;
+    Field_host_offset_or_field_id_offset = 24;
+static constexpr dart::compiler::target::word Field_guarded_cid_offset = 48;
 static constexpr dart::compiler::target::word
-    Field_guarded_list_length_in_object_offset_offset = 88;
+    Field_guarded_list_length_in_object_offset_offset = 56;
 static constexpr dart::compiler::target::word Field_guarded_list_length_offset =
-    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 = 72;
-static constexpr dart::compiler::target::word Function_data_offset = 56;
+    28;
+static constexpr dart::compiler::target::word Field_is_nullable_offset = 50;
+static constexpr dart::compiler::target::word Field_kind_bits_offset = 58;
+static constexpr dart::compiler::target::word Function_code_offset = 48;
+static constexpr dart::compiler::target::word Function_data_offset = 40;
 static constexpr dart::compiler::target::word Function_entry_point_offset[] = {
     8, 16};
-static constexpr dart::compiler::target::word Function_kind_tag_offset = 104;
+static constexpr dart::compiler::target::word Function_kind_tag_offset = 72;
 static constexpr dart::compiler::target::word Function_packed_fields_offset =
-    108;
-static constexpr dart::compiler::target::word Function_signature_offset = 48;
+    76;
+static constexpr dart::compiler::target::word Function_signature_offset = 36;
 static constexpr dart::compiler::target::word FutureOr_type_arguments_offset =
     8;
 static constexpr dart::compiler::target::word GrowableObjectArray_data_offset =
@@ -5567,9 +5567,9 @@
 static constexpr dart::compiler::target::word
     Thread_AllocateArray_entry_point_offset = 728;
 static constexpr dart::compiler::target::word Thread_active_exception_offset =
-    1400;
+    1424;
 static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
-    1408;
+    1432;
 static constexpr dart::compiler::target::word
     Thread_array_write_barrier_code_offset = 232;
 static constexpr dart::compiler::target::word
@@ -5595,7 +5595,7 @@
 static constexpr dart::compiler::target::word
     Thread_allocate_object_slow_stub_offset = 384;
 static constexpr dart::compiler::target::word Thread_api_top_scope_offset =
-    1480;
+    1504;
 static constexpr dart::compiler::target::word
     Thread_auto_scope_native_wrapper_entry_point_offset = 656;
 static constexpr dart::compiler::target::word Thread_bool_false_offset = 216;
@@ -5606,7 +5606,7 @@
     Thread_call_to_runtime_entry_point_offset = 528;
 static constexpr dart::compiler::target::word
     Thread_call_to_runtime_stub_offset = 264;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1496;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1520;
 static constexpr dart::compiler::target::word
     Thread_dispatch_table_array_offset = 96;
 static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
@@ -5624,7 +5624,7 @@
 static constexpr dart::compiler::target::word
     Thread_enter_safepoint_stub_offset = 488;
 static constexpr dart::compiler::target::word Thread_execution_state_offset =
-    1440;
+    1464;
 static constexpr dart::compiler::target::word
     Thread_exit_safepoint_stub_offset = 496;
 static constexpr dart::compiler::target::word
@@ -5644,14 +5644,14 @@
 static constexpr dart::compiler::target::word
     Thread_float_zerow_address_offset = 720;
 static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
-    1416;
+    1440;
 static constexpr dart::compiler::target::word
     Thread_invoke_dart_code_stub_offset = 256;
 static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset =
-    1472;
+    1496;
 static constexpr dart::compiler::target::word Thread_isolate_offset = 88;
 static constexpr dart::compiler::target::word Thread_isolate_group_offset =
-    1504;
+    1528;
 static constexpr dart::compiler::target::word Thread_field_table_values_offset =
     136;
 static constexpr dart::compiler::target::word
@@ -5693,11 +5693,11 @@
 static constexpr dart::compiler::target::word Thread_object_null_offset = 200;
 static constexpr dart::compiler::target::word
     Thread_predefined_symbols_address_offset = 664;
-static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1424;
+static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1448;
 static constexpr dart::compiler::target::word
-    Thread_saved_shadow_call_stack_offset = 1432;
+    Thread_saved_shadow_call_stack_offset = 1456;
 static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
-    1448;
+    1472;
 static constexpr dart::compiler::target::word
     Thread_slow_type_test_stub_offset = 472;
 static constexpr dart::compiler::target::word
@@ -5732,50 +5732,50 @@
     72;
 static constexpr dart::compiler::target::word Thread_heap_base_offset = 80;
 static constexpr dart::compiler::target::word Thread_callback_code_offset =
-    1456;
+    1480;
 static constexpr dart::compiler::target::word
-    Thread_callback_stack_return_offset = 1464;
+    Thread_callback_stack_return_offset = 1488;
 static constexpr dart::compiler::target::word TimelineStream_enabled_offset =
     16;
 static constexpr dart::compiler::target::word TwoByteString_data_offset = 16;
-static constexpr dart::compiler::target::word Type_arguments_offset = 32;
-static constexpr dart::compiler::target::word Type_hash_offset = 40;
-static constexpr dart::compiler::target::word Type_type_class_id_offset = 24;
-static constexpr dart::compiler::target::word Type_type_state_offset = 48;
-static constexpr dart::compiler::target::word Type_nullability_offset = 49;
-static constexpr dart::compiler::target::word FunctionType_hash_offset = 56;
+static constexpr dart::compiler::target::word Type_arguments_offset = 24;
+static constexpr dart::compiler::target::word Type_hash_offset = 28;
+static constexpr dart::compiler::target::word Type_type_class_id_offset = 20;
+static constexpr dart::compiler::target::word Type_type_state_offset = 32;
+static constexpr dart::compiler::target::word Type_nullability_offset = 33;
+static constexpr dart::compiler::target::word FunctionType_hash_offset = 36;
 static constexpr dart::compiler::target::word
-    FunctionType_packed_fields_offset = 64;
+    FunctionType_packed_fields_offset = 40;
 static constexpr dart::compiler::target::word
-    FunctionType_parameter_types_offset = 40;
+    FunctionType_parameter_types_offset = 28;
 static constexpr dart::compiler::target::word
-    FunctionType_parameter_names_offset = 48;
+    FunctionType_parameter_names_offset = 32;
 static constexpr dart::compiler::target::word
-    FunctionType_type_parameters_offset = 24;
+    FunctionType_type_parameters_offset = 20;
 static constexpr dart::compiler::target::word
-    TypeParameter_parameterized_class_id_offset = 56;
-static constexpr dart::compiler::target::word TypeParameter_index_offset = 60;
+    TypeParameter_parameterized_class_id_offset = 36;
+static constexpr dart::compiler::target::word TypeParameter_index_offset = 40;
 static constexpr dart::compiler::target::word TypeParameter_nullability_offset =
-    63;
+    43;
 static constexpr dart::compiler::target::word
     TypeArguments_instantiations_offset = 8;
 static constexpr dart::compiler::target::word TypeArguments_length_offset = 16;
 static constexpr dart::compiler::target::word TypeArguments_nullability_offset =
     32;
 static constexpr dart::compiler::target::word TypeArguments_types_offset = 40;
-static constexpr dart::compiler::target::word TypeParameter_bound_offset = 40;
-static constexpr dart::compiler::target::word TypeParameter_flags_offset = 62;
-static constexpr dart::compiler::target::word TypeParameter_name_offset = 24;
-static constexpr dart::compiler::target::word TypeRef_type_offset = 24;
+static constexpr dart::compiler::target::word TypeParameter_bound_offset = 28;
+static constexpr dart::compiler::target::word TypeParameter_flags_offset = 42;
+static constexpr dart::compiler::target::word TypeParameter_name_offset = 20;
+static constexpr dart::compiler::target::word TypeRef_type_offset = 20;
 static constexpr dart::compiler::target::word TypedDataBase_length_offset = 16;
-static constexpr dart::compiler::target::word TypedDataView_data_offset = 24;
+static constexpr dart::compiler::target::word TypedDataView_data_offset = 20;
 static constexpr dart::compiler::target::word
-    TypedDataView_offset_in_bytes_offset = 32;
+    TypedDataView_offset_in_bytes_offset = 24;
 static constexpr dart::compiler::target::word TypedData_data_offset = 24;
 static constexpr dart::compiler::target::word
     UnhandledException_exception_offset = 8;
 static constexpr dart::compiler::target::word
-    UnhandledException_stacktrace_offset = 16;
+    UnhandledException_stacktrace_offset = 12;
 static constexpr dart::compiler::target::word UserTag_tag_offset = 16;
 static constexpr dart::compiler::target::word
     MonomorphicSmiableCall_expected_cid_offset = 16;
@@ -5794,17 +5794,17 @@
     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};
+        1336, 1344, 1352, 1360, -1,   -1,   1368, 1376,
+        1384, 1392, 1400, -1,   1408, 1416, -1,   -1};
 static constexpr dart::compiler::target::word AbstractType_InstanceSize = 24;
 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 = 16;
 static constexpr dart::compiler::target::word Capability_InstanceSize = 16;
-static constexpr dart::compiler::target::word Class_InstanceSize = 200;
+static constexpr dart::compiler::target::word Class_InstanceSize = 128;
 static constexpr dart::compiler::target::word Closure_InstanceSize = 56;
-static constexpr dart::compiler::target::word ClosureData_InstanceSize = 48;
+static constexpr dart::compiler::target::word ClosureData_InstanceSize = 32;
 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 =
@@ -5815,7 +5815,7 @@
 static constexpr dart::compiler::target::word Double_InstanceSize = 16;
 static constexpr dart::compiler::target::word DynamicLibrary_InstanceSize = 16;
 static constexpr dart::compiler::target::word ExceptionHandlers_InstanceSize =
-    24;
+    16;
 static constexpr dart::compiler::target::word
     ExternalOneByteString_InstanceSize = 32;
 static constexpr dart::compiler::target::word
@@ -5823,12 +5823,12 @@
 static constexpr dart::compiler::target::word ExternalTypedData_InstanceSize =
     24;
 static constexpr dart::compiler::target::word FfiTrampolineData_InstanceSize =
-    48;
-static constexpr dart::compiler::target::word Field_InstanceSize = 96;
+    32;
+static constexpr dart::compiler::target::word Field_InstanceSize = 64;
 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 = 128;
-static constexpr dart::compiler::target::word FunctionType_InstanceSize = 72;
+static constexpr dart::compiler::target::word Function_InstanceSize = 96;
+static constexpr dart::compiler::target::word FunctionType_InstanceSize = 48;
 static constexpr dart::compiler::target::word FutureOr_InstanceSize = 16;
 static constexpr dart::compiler::target::word GrowableObjectArray_InstanceSize =
     32;
@@ -5841,10 +5841,10 @@
 static constexpr dart::compiler::target::word Int32x4_InstanceSize = 24;
 static constexpr dart::compiler::target::word Integer_InstanceSize = 8;
 static constexpr dart::compiler::target::word KernelProgramInfo_InstanceSize =
-    120;
-static constexpr dart::compiler::target::word LanguageError_InstanceSize = 48;
-static constexpr dart::compiler::target::word Library_InstanceSize = 160;
-static constexpr dart::compiler::target::word LibraryPrefix_InstanceSize = 40;
+    64;
+static constexpr dart::compiler::target::word LanguageError_InstanceSize = 32;
+static constexpr dart::compiler::target::word Library_InstanceSize = 104;
+static constexpr dart::compiler::target::word LibraryPrefix_InstanceSize = 24;
 static constexpr dart::compiler::target::word LinkedHashMap_InstanceSize = 56;
 static constexpr dart::compiler::target::word LocalVarDescriptors_InstanceSize =
     16;
@@ -5854,57 +5854,57 @@
 static constexpr dart::compiler::target::word MirrorReference_InstanceSize = 16;
 static constexpr dart::compiler::target::word
     MonomorphicSmiableCall_InstanceSize = 32;
-static constexpr dart::compiler::target::word Namespace_InstanceSize = 40;
+static constexpr dart::compiler::target::word Namespace_InstanceSize = 24;
 static constexpr dart::compiler::target::word NativeArguments_StructSize = 32;
 static constexpr dart::compiler::target::word Number_InstanceSize = 8;
 static constexpr dart::compiler::target::word Object_InstanceSize = 8;
 static constexpr dart::compiler::target::word ObjectPool_InstanceSize = 16;
 static constexpr dart::compiler::target::word OneByteString_InstanceSize = 16;
-static constexpr dart::compiler::target::word PatchClass_InstanceSize = 48;
+static constexpr dart::compiler::target::word PatchClass_InstanceSize = 32;
 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 RegExp_InstanceSize = 120;
-static constexpr dart::compiler::target::word Script_InstanceSize = 88;
+static constexpr dart::compiler::target::word ReceivePort_InstanceSize = 16;
+static constexpr dart::compiler::target::word RegExp_InstanceSize = 80;
+static constexpr dart::compiler::target::word Script_InstanceSize = 64;
 static constexpr dart::compiler::target::word SendPort_InstanceSize = 24;
 static constexpr dart::compiler::target::word SingleTargetCache_InstanceSize =
     32;
 static constexpr dart::compiler::target::word Smi_InstanceSize = 8;
-static constexpr dart::compiler::target::word StackTrace_InstanceSize = 40;
+static constexpr dart::compiler::target::word StackTrace_InstanceSize = 24;
 static constexpr dart::compiler::target::word String_InstanceSize = 16;
 static constexpr dart::compiler::target::word SubtypeTestCache_InstanceSize =
     16;
-static constexpr dart::compiler::target::word LoadingUnit_InstanceSize = 32;
+static constexpr dart::compiler::target::word LoadingUnit_InstanceSize = 24;
 static constexpr dart::compiler::target::word
     TransferableTypedData_InstanceSize = 8;
 static constexpr dart::compiler::target::word TwoByteString_InstanceSize = 16;
-static constexpr dart::compiler::target::word Type_InstanceSize = 56;
+static constexpr dart::compiler::target::word Type_InstanceSize = 40;
 static constexpr dart::compiler::target::word TypeArguments_InstanceSize = 40;
-static constexpr dart::compiler::target::word TypeParameter_InstanceSize = 64;
-static constexpr dart::compiler::target::word TypeRef_InstanceSize = 32;
+static constexpr dart::compiler::target::word TypeParameter_InstanceSize = 48;
+static constexpr dart::compiler::target::word TypeRef_InstanceSize = 24;
 static constexpr dart::compiler::target::word TypedData_InstanceSize = 24;
 static constexpr dart::compiler::target::word TypedDataBase_InstanceSize = 24;
-static constexpr dart::compiler::target::word TypedDataView_InstanceSize = 40;
+static constexpr dart::compiler::target::word TypedDataView_InstanceSize = 32;
 static constexpr dart::compiler::target::word UnhandledException_InstanceSize =
-    24;
+    16;
 static constexpr dart::compiler::target::word UnlinkedCall_InstanceSize = 32;
-static constexpr dart::compiler::target::word UnwindError_InstanceSize = 24;
+static constexpr dart::compiler::target::word UnwindError_InstanceSize = 16;
 static constexpr dart::compiler::target::word UserTag_InstanceSize = 24;
 static constexpr dart::compiler::target::word WeakProperty_InstanceSize = 32;
 static constexpr dart::compiler::target::word
-    WeakSerializationReference_InstanceSize = 24;
+    WeakSerializationReference_InstanceSize = 16;
 #endif  // defined(TARGET_ARCH_X64) && defined(DART_COMPRESSED_POINTERS)
 
 #if defined(TARGET_ARCH_ARM64) && defined(DART_COMPRESSED_POINTERS)
 static constexpr dart::compiler::target::word Function_usage_counter_offset =
-    116;
+    84;
 static constexpr dart::compiler::target::word
     ICData_receivers_static_type_offset = 32;
 static constexpr dart::compiler::target::word
     ContextScope_elements_start_offset = 16;
-static constexpr dart::compiler::target::word ContextScope_element_size = 64;
+static constexpr dart::compiler::target::word ContextScope_element_size = 32;
 static constexpr dart::compiler::target::word
-    ExceptionHandlers_elements_start_offset = 24;
+    ExceptionHandlers_elements_start_offset = 16;
 static constexpr dart::compiler::target::word ExceptionHandlers_element_size =
     12;
 static constexpr dart::compiler::target::word ObjectPool_elements_start_offset =
@@ -5971,12 +5971,12 @@
 static constexpr dart::compiler::target::word Array_tags_offset = 0;
 static constexpr dart::compiler::target::word Array_type_arguments_offset = 8;
 static constexpr dart::compiler::target::word Class_declaration_type_offset =
-    104;
+    56;
 static constexpr dart::compiler::target::word Class_num_type_arguments_offset =
-    164;
-static constexpr dart::compiler::target::word Class_super_type_offset = 88;
+    92;
+static constexpr dart::compiler::target::word Class_super_type_offset = 48;
 static constexpr dart::compiler::target::word
-    Class_host_type_arguments_field_offset_in_words_offset = 176;
+    Class_host_type_arguments_field_offset_in_words_offset = 104;
 static constexpr dart::compiler::target::word Closure_context_offset = 40;
 static constexpr dart::compiler::target::word
     Closure_delayed_type_arguments_offset = 24;
@@ -5987,9 +5987,9 @@
 static constexpr dart::compiler::target::word
     Closure_instantiator_type_arguments_offset = 8;
 static constexpr dart::compiler::target::word
-    ClosureData_default_type_arguments_offset = 32;
+    ClosureData_default_type_arguments_offset = 20;
 static constexpr dart::compiler::target::word
-    ClosureData_default_type_arguments_info_offset = 40;
+    ClosureData_default_type_arguments_kind_offset = 24;
 static constexpr dart::compiler::target::word Code_object_pool_offset = 40;
 static constexpr dart::compiler::target::word Code_saved_instructions_offset =
     48;
@@ -6004,24 +6004,24 @@
 static constexpr dart::compiler::target::word Float32x4_value_offset = 8;
 static constexpr dart::compiler::target::word Float64x2_value_offset = 8;
 static constexpr dart::compiler::target::word
-    Field_initializer_function_offset = 32;
+    Field_initializer_function_offset = 20;
 static constexpr dart::compiler::target::word
-    Field_host_offset_or_field_id_offset = 40;
-static constexpr dart::compiler::target::word Field_guarded_cid_offset = 80;
+    Field_host_offset_or_field_id_offset = 24;
+static constexpr dart::compiler::target::word Field_guarded_cid_offset = 48;
 static constexpr dart::compiler::target::word
-    Field_guarded_list_length_in_object_offset_offset = 88;
+    Field_guarded_list_length_in_object_offset_offset = 56;
 static constexpr dart::compiler::target::word Field_guarded_list_length_offset =
-    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 = 72;
-static constexpr dart::compiler::target::word Function_data_offset = 56;
+    28;
+static constexpr dart::compiler::target::word Field_is_nullable_offset = 50;
+static constexpr dart::compiler::target::word Field_kind_bits_offset = 58;
+static constexpr dart::compiler::target::word Function_code_offset = 48;
+static constexpr dart::compiler::target::word Function_data_offset = 40;
 static constexpr dart::compiler::target::word Function_entry_point_offset[] = {
     8, 16};
-static constexpr dart::compiler::target::word Function_kind_tag_offset = 104;
+static constexpr dart::compiler::target::word Function_kind_tag_offset = 72;
 static constexpr dart::compiler::target::word Function_packed_fields_offset =
-    108;
-static constexpr dart::compiler::target::word Function_signature_offset = 48;
+    76;
+static constexpr dart::compiler::target::word Function_signature_offset = 36;
 static constexpr dart::compiler::target::word FutureOr_type_arguments_offset =
     8;
 static constexpr dart::compiler::target::word GrowableObjectArray_data_offset =
@@ -6100,9 +6100,9 @@
 static constexpr dart::compiler::target::word
     Thread_AllocateArray_entry_point_offset = 728;
 static constexpr dart::compiler::target::word Thread_active_exception_offset =
-    1464;
+    1488;
 static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
-    1472;
+    1496;
 static constexpr dart::compiler::target::word
     Thread_array_write_barrier_code_offset = 232;
 static constexpr dart::compiler::target::word
@@ -6128,7 +6128,7 @@
 static constexpr dart::compiler::target::word
     Thread_allocate_object_slow_stub_offset = 384;
 static constexpr dart::compiler::target::word Thread_api_top_scope_offset =
-    1544;
+    1568;
 static constexpr dart::compiler::target::word
     Thread_auto_scope_native_wrapper_entry_point_offset = 656;
 static constexpr dart::compiler::target::word Thread_bool_false_offset = 216;
@@ -6139,7 +6139,7 @@
     Thread_call_to_runtime_entry_point_offset = 528;
 static constexpr dart::compiler::target::word
     Thread_call_to_runtime_stub_offset = 264;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1560;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1584;
 static constexpr dart::compiler::target::word
     Thread_dispatch_table_array_offset = 96;
 static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
@@ -6157,7 +6157,7 @@
 static constexpr dart::compiler::target::word
     Thread_enter_safepoint_stub_offset = 488;
 static constexpr dart::compiler::target::word Thread_execution_state_offset =
-    1504;
+    1528;
 static constexpr dart::compiler::target::word
     Thread_exit_safepoint_stub_offset = 496;
 static constexpr dart::compiler::target::word
@@ -6177,14 +6177,14 @@
 static constexpr dart::compiler::target::word
     Thread_float_zerow_address_offset = 720;
 static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
-    1480;
+    1504;
 static constexpr dart::compiler::target::word
     Thread_invoke_dart_code_stub_offset = 256;
 static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset =
-    1536;
+    1560;
 static constexpr dart::compiler::target::word Thread_isolate_offset = 88;
 static constexpr dart::compiler::target::word Thread_isolate_group_offset =
-    1568;
+    1592;
 static constexpr dart::compiler::target::word Thread_field_table_values_offset =
     136;
 static constexpr dart::compiler::target::word
@@ -6226,11 +6226,11 @@
 static constexpr dart::compiler::target::word Thread_object_null_offset = 200;
 static constexpr dart::compiler::target::word
     Thread_predefined_symbols_address_offset = 664;
-static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1488;
+static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1512;
 static constexpr dart::compiler::target::word
-    Thread_saved_shadow_call_stack_offset = 1496;
+    Thread_saved_shadow_call_stack_offset = 1520;
 static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
-    1512;
+    1536;
 static constexpr dart::compiler::target::word
     Thread_slow_type_test_stub_offset = 472;
 static constexpr dart::compiler::target::word
@@ -6265,50 +6265,50 @@
     72;
 static constexpr dart::compiler::target::word Thread_heap_base_offset = 80;
 static constexpr dart::compiler::target::word Thread_callback_code_offset =
-    1520;
+    1544;
 static constexpr dart::compiler::target::word
-    Thread_callback_stack_return_offset = 1528;
+    Thread_callback_stack_return_offset = 1552;
 static constexpr dart::compiler::target::word TimelineStream_enabled_offset =
     16;
 static constexpr dart::compiler::target::word TwoByteString_data_offset = 16;
-static constexpr dart::compiler::target::word Type_arguments_offset = 32;
-static constexpr dart::compiler::target::word Type_hash_offset = 40;
-static constexpr dart::compiler::target::word Type_type_class_id_offset = 24;
-static constexpr dart::compiler::target::word Type_type_state_offset = 48;
-static constexpr dart::compiler::target::word Type_nullability_offset = 49;
-static constexpr dart::compiler::target::word FunctionType_hash_offset = 56;
+static constexpr dart::compiler::target::word Type_arguments_offset = 24;
+static constexpr dart::compiler::target::word Type_hash_offset = 28;
+static constexpr dart::compiler::target::word Type_type_class_id_offset = 20;
+static constexpr dart::compiler::target::word Type_type_state_offset = 32;
+static constexpr dart::compiler::target::word Type_nullability_offset = 33;
+static constexpr dart::compiler::target::word FunctionType_hash_offset = 36;
 static constexpr dart::compiler::target::word
-    FunctionType_packed_fields_offset = 64;
+    FunctionType_packed_fields_offset = 40;
 static constexpr dart::compiler::target::word
-    FunctionType_parameter_types_offset = 40;
+    FunctionType_parameter_types_offset = 28;
 static constexpr dart::compiler::target::word
-    FunctionType_parameter_names_offset = 48;
+    FunctionType_parameter_names_offset = 32;
 static constexpr dart::compiler::target::word
-    FunctionType_type_parameters_offset = 24;
+    FunctionType_type_parameters_offset = 20;
 static constexpr dart::compiler::target::word
-    TypeParameter_parameterized_class_id_offset = 56;
-static constexpr dart::compiler::target::word TypeParameter_index_offset = 60;
+    TypeParameter_parameterized_class_id_offset = 36;
+static constexpr dart::compiler::target::word TypeParameter_index_offset = 40;
 static constexpr dart::compiler::target::word TypeParameter_nullability_offset =
-    63;
+    43;
 static constexpr dart::compiler::target::word
     TypeArguments_instantiations_offset = 8;
 static constexpr dart::compiler::target::word TypeArguments_length_offset = 16;
 static constexpr dart::compiler::target::word TypeArguments_nullability_offset =
     32;
 static constexpr dart::compiler::target::word TypeArguments_types_offset = 40;
-static constexpr dart::compiler::target::word TypeParameter_bound_offset = 40;
-static constexpr dart::compiler::target::word TypeParameter_flags_offset = 62;
-static constexpr dart::compiler::target::word TypeParameter_name_offset = 24;
-static constexpr dart::compiler::target::word TypeRef_type_offset = 24;
+static constexpr dart::compiler::target::word TypeParameter_bound_offset = 28;
+static constexpr dart::compiler::target::word TypeParameter_flags_offset = 42;
+static constexpr dart::compiler::target::word TypeParameter_name_offset = 20;
+static constexpr dart::compiler::target::word TypeRef_type_offset = 20;
 static constexpr dart::compiler::target::word TypedDataBase_length_offset = 16;
-static constexpr dart::compiler::target::word TypedDataView_data_offset = 24;
+static constexpr dart::compiler::target::word TypedDataView_data_offset = 20;
 static constexpr dart::compiler::target::word
-    TypedDataView_offset_in_bytes_offset = 32;
+    TypedDataView_offset_in_bytes_offset = 24;
 static constexpr dart::compiler::target::word TypedData_data_offset = 24;
 static constexpr dart::compiler::target::word
     UnhandledException_exception_offset = 8;
 static constexpr dart::compiler::target::word
-    UnhandledException_stacktrace_offset = 16;
+    UnhandledException_stacktrace_offset = 12;
 static constexpr dart::compiler::target::word UserTag_tag_offset = 16;
 static constexpr dart::compiler::target::word
     MonomorphicSmiableCall_expected_cid_offset = 16;
@@ -6327,18 +6327,18 @@
     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,   -1,   1448, 1456, -1,   -1,   -1,   -1,   -1,   -1};
+        1336, 1344, 1352, 1360, 1368, 1376, 1384, 1392, 1400, 1408, 1416,
+        1424, 1432, 1440, 1448, -1,   -1,   -1,   -1,   1456, 1464, -1,
+        -1,   -1,   1472, 1480, -1,   -1,   -1,   -1,   -1,   -1};
 static constexpr dart::compiler::target::word AbstractType_InstanceSize = 24;
 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 = 16;
 static constexpr dart::compiler::target::word Capability_InstanceSize = 16;
-static constexpr dart::compiler::target::word Class_InstanceSize = 200;
+static constexpr dart::compiler::target::word Class_InstanceSize = 128;
 static constexpr dart::compiler::target::word Closure_InstanceSize = 56;
-static constexpr dart::compiler::target::word ClosureData_InstanceSize = 48;
+static constexpr dart::compiler::target::word ClosureData_InstanceSize = 32;
 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 =
@@ -6349,7 +6349,7 @@
 static constexpr dart::compiler::target::word Double_InstanceSize = 16;
 static constexpr dart::compiler::target::word DynamicLibrary_InstanceSize = 16;
 static constexpr dart::compiler::target::word ExceptionHandlers_InstanceSize =
-    24;
+    16;
 static constexpr dart::compiler::target::word
     ExternalOneByteString_InstanceSize = 32;
 static constexpr dart::compiler::target::word
@@ -6357,12 +6357,12 @@
 static constexpr dart::compiler::target::word ExternalTypedData_InstanceSize =
     24;
 static constexpr dart::compiler::target::word FfiTrampolineData_InstanceSize =
-    48;
-static constexpr dart::compiler::target::word Field_InstanceSize = 96;
+    32;
+static constexpr dart::compiler::target::word Field_InstanceSize = 64;
 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 = 128;
-static constexpr dart::compiler::target::word FunctionType_InstanceSize = 72;
+static constexpr dart::compiler::target::word Function_InstanceSize = 96;
+static constexpr dart::compiler::target::word FunctionType_InstanceSize = 48;
 static constexpr dart::compiler::target::word FutureOr_InstanceSize = 16;
 static constexpr dart::compiler::target::word GrowableObjectArray_InstanceSize =
     32;
@@ -6375,10 +6375,10 @@
 static constexpr dart::compiler::target::word Int32x4_InstanceSize = 24;
 static constexpr dart::compiler::target::word Integer_InstanceSize = 8;
 static constexpr dart::compiler::target::word KernelProgramInfo_InstanceSize =
-    120;
-static constexpr dart::compiler::target::word LanguageError_InstanceSize = 48;
-static constexpr dart::compiler::target::word Library_InstanceSize = 160;
-static constexpr dart::compiler::target::word LibraryPrefix_InstanceSize = 40;
+    64;
+static constexpr dart::compiler::target::word LanguageError_InstanceSize = 32;
+static constexpr dart::compiler::target::word Library_InstanceSize = 104;
+static constexpr dart::compiler::target::word LibraryPrefix_InstanceSize = 24;
 static constexpr dart::compiler::target::word LinkedHashMap_InstanceSize = 56;
 static constexpr dart::compiler::target::word LocalVarDescriptors_InstanceSize =
     16;
@@ -6388,45 +6388,45 @@
 static constexpr dart::compiler::target::word MirrorReference_InstanceSize = 16;
 static constexpr dart::compiler::target::word
     MonomorphicSmiableCall_InstanceSize = 32;
-static constexpr dart::compiler::target::word Namespace_InstanceSize = 40;
+static constexpr dart::compiler::target::word Namespace_InstanceSize = 24;
 static constexpr dart::compiler::target::word NativeArguments_StructSize = 32;
 static constexpr dart::compiler::target::word Number_InstanceSize = 8;
 static constexpr dart::compiler::target::word Object_InstanceSize = 8;
 static constexpr dart::compiler::target::word ObjectPool_InstanceSize = 16;
 static constexpr dart::compiler::target::word OneByteString_InstanceSize = 16;
-static constexpr dart::compiler::target::word PatchClass_InstanceSize = 48;
+static constexpr dart::compiler::target::word PatchClass_InstanceSize = 32;
 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 RegExp_InstanceSize = 120;
-static constexpr dart::compiler::target::word Script_InstanceSize = 88;
+static constexpr dart::compiler::target::word ReceivePort_InstanceSize = 16;
+static constexpr dart::compiler::target::word RegExp_InstanceSize = 80;
+static constexpr dart::compiler::target::word Script_InstanceSize = 64;
 static constexpr dart::compiler::target::word SendPort_InstanceSize = 24;
 static constexpr dart::compiler::target::word SingleTargetCache_InstanceSize =
     32;
 static constexpr dart::compiler::target::word Smi_InstanceSize = 8;
-static constexpr dart::compiler::target::word StackTrace_InstanceSize = 40;
+static constexpr dart::compiler::target::word StackTrace_InstanceSize = 24;
 static constexpr dart::compiler::target::word String_InstanceSize = 16;
 static constexpr dart::compiler::target::word SubtypeTestCache_InstanceSize =
     16;
-static constexpr dart::compiler::target::word LoadingUnit_InstanceSize = 32;
+static constexpr dart::compiler::target::word LoadingUnit_InstanceSize = 24;
 static constexpr dart::compiler::target::word
     TransferableTypedData_InstanceSize = 8;
 static constexpr dart::compiler::target::word TwoByteString_InstanceSize = 16;
-static constexpr dart::compiler::target::word Type_InstanceSize = 56;
+static constexpr dart::compiler::target::word Type_InstanceSize = 40;
 static constexpr dart::compiler::target::word TypeArguments_InstanceSize = 40;
-static constexpr dart::compiler::target::word TypeParameter_InstanceSize = 64;
-static constexpr dart::compiler::target::word TypeRef_InstanceSize = 32;
+static constexpr dart::compiler::target::word TypeParameter_InstanceSize = 48;
+static constexpr dart::compiler::target::word TypeRef_InstanceSize = 24;
 static constexpr dart::compiler::target::word TypedData_InstanceSize = 24;
 static constexpr dart::compiler::target::word TypedDataBase_InstanceSize = 24;
-static constexpr dart::compiler::target::word TypedDataView_InstanceSize = 40;
+static constexpr dart::compiler::target::word TypedDataView_InstanceSize = 32;
 static constexpr dart::compiler::target::word UnhandledException_InstanceSize =
-    24;
+    16;
 static constexpr dart::compiler::target::word UnlinkedCall_InstanceSize = 32;
-static constexpr dart::compiler::target::word UnwindError_InstanceSize = 24;
+static constexpr dart::compiler::target::word UnwindError_InstanceSize = 16;
 static constexpr dart::compiler::target::word UserTag_InstanceSize = 24;
 static constexpr dart::compiler::target::word WeakProperty_InstanceSize = 32;
 static constexpr dart::compiler::target::word
-    WeakSerializationReference_InstanceSize = 24;
+    WeakSerializationReference_InstanceSize = 16;
 #endif  // defined(TARGET_ARCH_ARM64) && defined(DART_COMPRESSED_POINTERS)
 
 #endif  // !defined(PRODUCT)
@@ -6530,7 +6530,7 @@
 static constexpr dart::compiler::target::word
     AOT_ClosureData_default_type_arguments_offset = 16;
 static constexpr dart::compiler::target::word
-    AOT_ClosureData_default_type_arguments_info_offset = 20;
+    AOT_ClosureData_default_type_arguments_kind_offset = 20;
 static constexpr dart::compiler::target::word AOT_Code_object_pool_offset = 20;
 static constexpr dart::compiler::target::word
     AOT_Code_saved_instructions_offset = 24;
@@ -6661,9 +6661,9 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_AllocateArray_entry_point_offset = 368;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_exception_offset = 692;
+    AOT_Thread_active_exception_offset = 704;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_stacktrace_offset = 696;
+    AOT_Thread_active_stacktrace_offset = 708;
 static constexpr dart::compiler::target::word
     AOT_Thread_array_write_barrier_code_offset = 120;
 static constexpr dart::compiler::target::word
@@ -6689,7 +6689,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_allocate_object_slow_stub_offset = 196;
 static constexpr dart::compiler::target::word AOT_Thread_api_top_scope_offset =
-    732;
+    744;
 static constexpr dart::compiler::target::word
     AOT_Thread_auto_scope_native_wrapper_entry_point_offset = 332;
 static constexpr dart::compiler::target::word AOT_Thread_bool_false_offset =
@@ -6702,7 +6702,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_call_to_runtime_stub_offset = 136;
 static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset =
-    740;
+    752;
 static constexpr dart::compiler::target::word
     AOT_Thread_dispatch_table_array_offset = 48;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset =
@@ -6721,7 +6721,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_enter_safepoint_stub_offset = 248;
 static constexpr dart::compiler::target::word
-    AOT_Thread_execution_state_offset = 712;
+    AOT_Thread_execution_state_offset = 724;
 static constexpr dart::compiler::target::word
     AOT_Thread_exit_safepoint_stub_offset = 252;
 static constexpr dart::compiler::target::word
@@ -6741,14 +6741,14 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_float_zerow_address_offset = 364;
 static constexpr dart::compiler::target::word
-    AOT_Thread_global_object_pool_offset = 700;
+    AOT_Thread_global_object_pool_offset = 712;
 static constexpr dart::compiler::target::word
     AOT_Thread_invoke_dart_code_stub_offset = 132;
 static constexpr dart::compiler::target::word
-    AOT_Thread_exit_through_ffi_offset = 728;
+    AOT_Thread_exit_through_ffi_offset = 740;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 44;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_group_offset =
-    744;
+    756;
 static constexpr dart::compiler::target::word
     AOT_Thread_field_table_values_offset = 68;
 static constexpr dart::compiler::target::word
@@ -6792,11 +6792,11 @@
     104;
 static constexpr dart::compiler::target::word
     AOT_Thread_predefined_symbols_address_offset = 336;
-static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset = 704;
+static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset = 716;
 static constexpr dart::compiler::target::word
-    AOT_Thread_saved_shadow_call_stack_offset = 708;
+    AOT_Thread_saved_shadow_call_stack_offset = 720;
 static constexpr dart::compiler::target::word
-    AOT_Thread_safepoint_state_offset = 716;
+    AOT_Thread_safepoint_state_offset = 728;
 static constexpr dart::compiler::target::word
     AOT_Thread_slow_type_test_stub_offset = 240;
 static constexpr dart::compiler::target::word
@@ -6833,9 +6833,9 @@
     AOT_Thread_write_barrier_mask_offset = 36;
 static constexpr dart::compiler::target::word AOT_Thread_heap_base_offset = 40;
 static constexpr dart::compiler::target::word AOT_Thread_callback_code_offset =
-    720;
+    732;
 static constexpr dart::compiler::target::word
-    AOT_Thread_callback_stack_return_offset = 724;
+    AOT_Thread_callback_stack_return_offset = 736;
 static constexpr dart::compiler::target::word
     AOT_TimelineStream_enabled_offset = 8;
 static constexpr dart::compiler::target::word AOT_TwoByteString_data_offset =
@@ -6910,7 +6910,7 @@
     4, 12, 8, 16};
 static constexpr dart::compiler::target::word
     AOT_Thread_write_barrier_wrappers_thread_offset[] = {
-        660, 664, 668, 672, 676, -1, 680, -1, 684, 688, -1, -1, -1, -1, -1, -1};
+        672, 676, 680, 684, 688, -1, 692, -1, 696, 700, -1, -1, -1, -1, -1, -1};
 static constexpr dart::compiler::target::word AOT_AbstractType_InstanceSize =
     12;
 static constexpr dart::compiler::target::word AOT_ApiError_InstanceSize = 8;
@@ -7125,7 +7125,7 @@
 static constexpr dart::compiler::target::word
     AOT_ClosureData_default_type_arguments_offset = 32;
 static constexpr dart::compiler::target::word
-    AOT_ClosureData_default_type_arguments_info_offset = 40;
+    AOT_ClosureData_default_type_arguments_kind_offset = 40;
 static constexpr dart::compiler::target::word AOT_Code_object_pool_offset = 40;
 static constexpr dart::compiler::target::word
     AOT_Code_saved_instructions_offset = 48;
@@ -7256,9 +7256,9 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_AllocateArray_entry_point_offset = 728;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_exception_offset = 1400;
+    AOT_Thread_active_exception_offset = 1424;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_stacktrace_offset = 1408;
+    AOT_Thread_active_stacktrace_offset = 1432;
 static constexpr dart::compiler::target::word
     AOT_Thread_array_write_barrier_code_offset = 232;
 static constexpr dart::compiler::target::word
@@ -7284,7 +7284,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_allocate_object_slow_stub_offset = 384;
 static constexpr dart::compiler::target::word AOT_Thread_api_top_scope_offset =
-    1480;
+    1504;
 static constexpr dart::compiler::target::word
     AOT_Thread_auto_scope_native_wrapper_entry_point_offset = 656;
 static constexpr dart::compiler::target::word AOT_Thread_bool_false_offset =
@@ -7297,7 +7297,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_call_to_runtime_stub_offset = 264;
 static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset =
-    1496;
+    1520;
 static constexpr dart::compiler::target::word
     AOT_Thread_dispatch_table_array_offset = 96;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset =
@@ -7316,7 +7316,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_enter_safepoint_stub_offset = 488;
 static constexpr dart::compiler::target::word
-    AOT_Thread_execution_state_offset = 1440;
+    AOT_Thread_execution_state_offset = 1464;
 static constexpr dart::compiler::target::word
     AOT_Thread_exit_safepoint_stub_offset = 496;
 static constexpr dart::compiler::target::word
@@ -7336,14 +7336,14 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_float_zerow_address_offset = 720;
 static constexpr dart::compiler::target::word
-    AOT_Thread_global_object_pool_offset = 1416;
+    AOT_Thread_global_object_pool_offset = 1440;
 static constexpr dart::compiler::target::word
     AOT_Thread_invoke_dart_code_stub_offset = 256;
 static constexpr dart::compiler::target::word
-    AOT_Thread_exit_through_ffi_offset = 1472;
+    AOT_Thread_exit_through_ffi_offset = 1496;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 88;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_group_offset =
-    1504;
+    1528;
 static constexpr dart::compiler::target::word
     AOT_Thread_field_table_values_offset = 136;
 static constexpr dart::compiler::target::word
@@ -7388,11 +7388,11 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_predefined_symbols_address_offset = 664;
 static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset =
-    1424;
+    1448;
 static constexpr dart::compiler::target::word
-    AOT_Thread_saved_shadow_call_stack_offset = 1432;
+    AOT_Thread_saved_shadow_call_stack_offset = 1456;
 static constexpr dart::compiler::target::word
-    AOT_Thread_safepoint_state_offset = 1448;
+    AOT_Thread_safepoint_state_offset = 1472;
 static constexpr dart::compiler::target::word
     AOT_Thread_slow_type_test_stub_offset = 472;
 static constexpr dart::compiler::target::word
@@ -7429,9 +7429,9 @@
     AOT_Thread_write_barrier_mask_offset = 72;
 static constexpr dart::compiler::target::word AOT_Thread_heap_base_offset = 80;
 static constexpr dart::compiler::target::word AOT_Thread_callback_code_offset =
-    1456;
+    1480;
 static constexpr dart::compiler::target::word
-    AOT_Thread_callback_stack_return_offset = 1464;
+    AOT_Thread_callback_stack_return_offset = 1488;
 static constexpr dart::compiler::target::word
     AOT_TimelineStream_enabled_offset = 16;
 static constexpr dart::compiler::target::word AOT_TwoByteString_data_offset =
@@ -7507,8 +7507,8 @@
     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};
+        1336, 1344, 1352, 1360, -1,   -1,   1368, 1376,
+        1384, 1392, 1400, -1,   1408, 1416, -1,   -1};
 static constexpr dart::compiler::target::word AOT_AbstractType_InstanceSize =
     24;
 static constexpr dart::compiler::target::word AOT_ApiError_InstanceSize = 16;
@@ -7726,7 +7726,7 @@
 static constexpr dart::compiler::target::word
     AOT_ClosureData_default_type_arguments_offset = 32;
 static constexpr dart::compiler::target::word
-    AOT_ClosureData_default_type_arguments_info_offset = 40;
+    AOT_ClosureData_default_type_arguments_kind_offset = 40;
 static constexpr dart::compiler::target::word AOT_Code_object_pool_offset = 40;
 static constexpr dart::compiler::target::word
     AOT_Code_saved_instructions_offset = 48;
@@ -7857,9 +7857,9 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_AllocateArray_entry_point_offset = 728;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_exception_offset = 1464;
+    AOT_Thread_active_exception_offset = 1488;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_stacktrace_offset = 1472;
+    AOT_Thread_active_stacktrace_offset = 1496;
 static constexpr dart::compiler::target::word
     AOT_Thread_array_write_barrier_code_offset = 232;
 static constexpr dart::compiler::target::word
@@ -7885,7 +7885,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_allocate_object_slow_stub_offset = 384;
 static constexpr dart::compiler::target::word AOT_Thread_api_top_scope_offset =
-    1544;
+    1568;
 static constexpr dart::compiler::target::word
     AOT_Thread_auto_scope_native_wrapper_entry_point_offset = 656;
 static constexpr dart::compiler::target::word AOT_Thread_bool_false_offset =
@@ -7898,7 +7898,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_call_to_runtime_stub_offset = 264;
 static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset =
-    1560;
+    1584;
 static constexpr dart::compiler::target::word
     AOT_Thread_dispatch_table_array_offset = 96;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset =
@@ -7917,7 +7917,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_enter_safepoint_stub_offset = 488;
 static constexpr dart::compiler::target::word
-    AOT_Thread_execution_state_offset = 1504;
+    AOT_Thread_execution_state_offset = 1528;
 static constexpr dart::compiler::target::word
     AOT_Thread_exit_safepoint_stub_offset = 496;
 static constexpr dart::compiler::target::word
@@ -7937,14 +7937,14 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_float_zerow_address_offset = 720;
 static constexpr dart::compiler::target::word
-    AOT_Thread_global_object_pool_offset = 1480;
+    AOT_Thread_global_object_pool_offset = 1504;
 static constexpr dart::compiler::target::word
     AOT_Thread_invoke_dart_code_stub_offset = 256;
 static constexpr dart::compiler::target::word
-    AOT_Thread_exit_through_ffi_offset = 1536;
+    AOT_Thread_exit_through_ffi_offset = 1560;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 88;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_group_offset =
-    1568;
+    1592;
 static constexpr dart::compiler::target::word
     AOT_Thread_field_table_values_offset = 136;
 static constexpr dart::compiler::target::word
@@ -7989,11 +7989,11 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_predefined_symbols_address_offset = 664;
 static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset =
-    1488;
+    1512;
 static constexpr dart::compiler::target::word
-    AOT_Thread_saved_shadow_call_stack_offset = 1496;
+    AOT_Thread_saved_shadow_call_stack_offset = 1520;
 static constexpr dart::compiler::target::word
-    AOT_Thread_safepoint_state_offset = 1512;
+    AOT_Thread_safepoint_state_offset = 1536;
 static constexpr dart::compiler::target::word
     AOT_Thread_slow_type_test_stub_offset = 472;
 static constexpr dart::compiler::target::word
@@ -8030,9 +8030,9 @@
     AOT_Thread_write_barrier_mask_offset = 72;
 static constexpr dart::compiler::target::word AOT_Thread_heap_base_offset = 80;
 static constexpr dart::compiler::target::word AOT_Thread_callback_code_offset =
-    1520;
+    1544;
 static constexpr dart::compiler::target::word
-    AOT_Thread_callback_stack_return_offset = 1528;
+    AOT_Thread_callback_stack_return_offset = 1552;
 static constexpr dart::compiler::target::word
     AOT_TimelineStream_enabled_offset = 16;
 static constexpr dart::compiler::target::word AOT_TwoByteString_data_offset =
@@ -8108,9 +8108,9 @@
     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,   -1,   1448, 1456, -1,   -1,   -1,   -1,   -1,   -1};
+        1336, 1344, 1352, 1360, 1368, 1376, 1384, 1392, 1400, 1408, 1416,
+        1424, 1432, 1440, 1448, -1,   -1,   -1,   -1,   1456, 1464, -1,
+        -1,   -1,   1472, 1480, -1,   -1,   -1,   -1,   -1,   -1};
 static constexpr dart::compiler::target::word AOT_AbstractType_InstanceSize =
     24;
 static constexpr dart::compiler::target::word AOT_ApiError_InstanceSize = 16;
@@ -8231,9 +8231,9 @@
 static constexpr dart::compiler::target::word
     AOT_ContextScope_elements_start_offset = 16;
 static constexpr dart::compiler::target::word AOT_ContextScope_element_size =
-    64;
+    32;
 static constexpr dart::compiler::target::word
-    AOT_ExceptionHandlers_elements_start_offset = 24;
+    AOT_ExceptionHandlers_elements_start_offset = 16;
 static constexpr dart::compiler::target::word
     AOT_ExceptionHandlers_element_size = 12;
 static constexpr dart::compiler::target::word
@@ -8305,12 +8305,12 @@
 static constexpr dart::compiler::target::word AOT_Array_type_arguments_offset =
     8;
 static constexpr dart::compiler::target::word
-    AOT_Class_declaration_type_offset = 104;
+    AOT_Class_declaration_type_offset = 56;
 static constexpr dart::compiler::target::word
-    AOT_Class_num_type_arguments_offset = 164;
-static constexpr dart::compiler::target::word AOT_Class_super_type_offset = 88;
+    AOT_Class_num_type_arguments_offset = 92;
+static constexpr dart::compiler::target::word AOT_Class_super_type_offset = 48;
 static constexpr dart::compiler::target::word
-    AOT_Class_host_type_arguments_field_offset_in_words_offset = 176;
+    AOT_Class_host_type_arguments_field_offset_in_words_offset = 104;
 static constexpr dart::compiler::target::word
     AOT_SharedClassTable_class_heap_stats_table_offset = 0;
 static constexpr dart::compiler::target::word AOT_Closure_context_offset = 40;
@@ -8323,9 +8323,9 @@
 static constexpr dart::compiler::target::word
     AOT_Closure_instantiator_type_arguments_offset = 8;
 static constexpr dart::compiler::target::word
-    AOT_ClosureData_default_type_arguments_offset = 32;
+    AOT_ClosureData_default_type_arguments_offset = 20;
 static constexpr dart::compiler::target::word
-    AOT_ClosureData_default_type_arguments_info_offset = 40;
+    AOT_ClosureData_default_type_arguments_kind_offset = 24;
 static constexpr dart::compiler::target::word AOT_Code_object_pool_offset = 40;
 static constexpr dart::compiler::target::word
     AOT_Code_saved_instructions_offset = 48;
@@ -8341,25 +8341,25 @@
 static constexpr dart::compiler::target::word AOT_Float32x4_value_offset = 8;
 static constexpr dart::compiler::target::word AOT_Float64x2_value_offset = 8;
 static constexpr dart::compiler::target::word
-    AOT_Field_initializer_function_offset = 32;
+    AOT_Field_initializer_function_offset = 20;
 static constexpr dart::compiler::target::word
-    AOT_Field_host_offset_or_field_id_offset = 40;
-static constexpr dart::compiler::target::word AOT_Field_guarded_cid_offset = 72;
+    AOT_Field_host_offset_or_field_id_offset = 24;
+static constexpr dart::compiler::target::word AOT_Field_guarded_cid_offset = 44;
 static constexpr dart::compiler::target::word
-    AOT_Field_guarded_list_length_in_object_offset_offset = 76;
+    AOT_Field_guarded_list_length_in_object_offset_offset = 48;
 static constexpr dart::compiler::target::word
-    AOT_Field_guarded_list_length_offset = 48;
-static constexpr dart::compiler::target::word AOT_Field_is_nullable_offset = 74;
-static constexpr dart::compiler::target::word AOT_Field_kind_bits_offset = 78;
-static constexpr dart::compiler::target::word AOT_Function_code_offset = 72;
-static constexpr dart::compiler::target::word AOT_Function_data_offset = 56;
+    AOT_Field_guarded_list_length_offset = 28;
+static constexpr dart::compiler::target::word AOT_Field_is_nullable_offset = 46;
+static constexpr dart::compiler::target::word AOT_Field_kind_bits_offset = 50;
+static constexpr dart::compiler::target::word AOT_Function_code_offset = 48;
+static constexpr dart::compiler::target::word AOT_Function_data_offset = 40;
 static constexpr dart::compiler::target::word
     AOT_Function_entry_point_offset[] = {8, 16};
-static constexpr dart::compiler::target::word AOT_Function_kind_tag_offset = 80;
+static constexpr dart::compiler::target::word AOT_Function_kind_tag_offset = 52;
 static constexpr dart::compiler::target::word
-    AOT_Function_packed_fields_offset = 84;
+    AOT_Function_packed_fields_offset = 56;
 static constexpr dart::compiler::target::word AOT_Function_signature_offset =
-    48;
+    36;
 static constexpr dart::compiler::target::word
     AOT_FutureOr_type_arguments_offset = 8;
 static constexpr dart::compiler::target::word
@@ -8456,9 +8456,9 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_AllocateArray_entry_point_offset = 728;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_exception_offset = 1400;
+    AOT_Thread_active_exception_offset = 1424;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_stacktrace_offset = 1408;
+    AOT_Thread_active_stacktrace_offset = 1432;
 static constexpr dart::compiler::target::word
     AOT_Thread_array_write_barrier_code_offset = 232;
 static constexpr dart::compiler::target::word
@@ -8484,7 +8484,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_allocate_object_slow_stub_offset = 384;
 static constexpr dart::compiler::target::word AOT_Thread_api_top_scope_offset =
-    1480;
+    1504;
 static constexpr dart::compiler::target::word
     AOT_Thread_auto_scope_native_wrapper_entry_point_offset = 656;
 static constexpr dart::compiler::target::word AOT_Thread_bool_false_offset =
@@ -8497,7 +8497,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_call_to_runtime_stub_offset = 264;
 static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset =
-    1496;
+    1520;
 static constexpr dart::compiler::target::word
     AOT_Thread_dispatch_table_array_offset = 96;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset =
@@ -8516,7 +8516,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_enter_safepoint_stub_offset = 488;
 static constexpr dart::compiler::target::word
-    AOT_Thread_execution_state_offset = 1440;
+    AOT_Thread_execution_state_offset = 1464;
 static constexpr dart::compiler::target::word
     AOT_Thread_exit_safepoint_stub_offset = 496;
 static constexpr dart::compiler::target::word
@@ -8536,14 +8536,14 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_float_zerow_address_offset = 720;
 static constexpr dart::compiler::target::word
-    AOT_Thread_global_object_pool_offset = 1416;
+    AOT_Thread_global_object_pool_offset = 1440;
 static constexpr dart::compiler::target::word
     AOT_Thread_invoke_dart_code_stub_offset = 256;
 static constexpr dart::compiler::target::word
-    AOT_Thread_exit_through_ffi_offset = 1472;
+    AOT_Thread_exit_through_ffi_offset = 1496;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 88;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_group_offset =
-    1504;
+    1528;
 static constexpr dart::compiler::target::word
     AOT_Thread_field_table_values_offset = 136;
 static constexpr dart::compiler::target::word
@@ -8588,11 +8588,11 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_predefined_symbols_address_offset = 664;
 static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset =
-    1424;
+    1448;
 static constexpr dart::compiler::target::word
-    AOT_Thread_saved_shadow_call_stack_offset = 1432;
+    AOT_Thread_saved_shadow_call_stack_offset = 1456;
 static constexpr dart::compiler::target::word
-    AOT_Thread_safepoint_state_offset = 1448;
+    AOT_Thread_safepoint_state_offset = 1472;
 static constexpr dart::compiler::target::word
     AOT_Thread_slow_type_test_stub_offset = 472;
 static constexpr dart::compiler::target::word
@@ -8629,34 +8629,34 @@
     AOT_Thread_write_barrier_mask_offset = 72;
 static constexpr dart::compiler::target::word AOT_Thread_heap_base_offset = 80;
 static constexpr dart::compiler::target::word AOT_Thread_callback_code_offset =
-    1456;
+    1480;
 static constexpr dart::compiler::target::word
-    AOT_Thread_callback_stack_return_offset = 1464;
+    AOT_Thread_callback_stack_return_offset = 1488;
 static constexpr dart::compiler::target::word
     AOT_TimelineStream_enabled_offset = 16;
 static constexpr dart::compiler::target::word AOT_TwoByteString_data_offset =
     16;
-static constexpr dart::compiler::target::word AOT_Type_arguments_offset = 32;
-static constexpr dart::compiler::target::word AOT_Type_hash_offset = 40;
+static constexpr dart::compiler::target::word AOT_Type_arguments_offset = 24;
+static constexpr dart::compiler::target::word AOT_Type_hash_offset = 28;
 static constexpr dart::compiler::target::word AOT_Type_type_class_id_offset =
-    24;
-static constexpr dart::compiler::target::word AOT_Type_type_state_offset = 48;
-static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 49;
-static constexpr dart::compiler::target::word AOT_FunctionType_hash_offset = 56;
+    20;
+static constexpr dart::compiler::target::word AOT_Type_type_state_offset = 32;
+static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 33;
+static constexpr dart::compiler::target::word AOT_FunctionType_hash_offset = 36;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_packed_fields_offset = 64;
+    AOT_FunctionType_packed_fields_offset = 40;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_parameter_types_offset = 40;
+    AOT_FunctionType_parameter_types_offset = 28;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_parameter_names_offset = 48;
+    AOT_FunctionType_parameter_names_offset = 32;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_type_parameters_offset = 24;
+    AOT_FunctionType_type_parameters_offset = 20;
 static constexpr dart::compiler::target::word
-    AOT_TypeParameter_parameterized_class_id_offset = 56;
+    AOT_TypeParameter_parameterized_class_id_offset = 36;
 static constexpr dart::compiler::target::word AOT_TypeParameter_index_offset =
-    60;
+    40;
 static constexpr dart::compiler::target::word
-    AOT_TypeParameter_nullability_offset = 63;
+    AOT_TypeParameter_nullability_offset = 43;
 static constexpr dart::compiler::target::word
     AOT_TypeArguments_instantiations_offset = 8;
 static constexpr dart::compiler::target::word AOT_TypeArguments_length_offset =
@@ -8666,23 +8666,23 @@
 static constexpr dart::compiler::target::word AOT_TypeArguments_types_offset =
     40;
 static constexpr dart::compiler::target::word AOT_TypeParameter_bound_offset =
-    40;
+    28;
 static constexpr dart::compiler::target::word AOT_TypeParameter_flags_offset =
-    62;
+    42;
 static constexpr dart::compiler::target::word AOT_TypeParameter_name_offset =
-    24;
-static constexpr dart::compiler::target::word AOT_TypeRef_type_offset = 24;
+    20;
+static constexpr dart::compiler::target::word AOT_TypeRef_type_offset = 20;
 static constexpr dart::compiler::target::word AOT_TypedDataBase_length_offset =
     16;
 static constexpr dart::compiler::target::word AOT_TypedDataView_data_offset =
-    24;
+    20;
 static constexpr dart::compiler::target::word
-    AOT_TypedDataView_offset_in_bytes_offset = 32;
+    AOT_TypedDataView_offset_in_bytes_offset = 24;
 static constexpr dart::compiler::target::word AOT_TypedData_data_offset = 24;
 static constexpr dart::compiler::target::word
     AOT_UnhandledException_exception_offset = 8;
 static constexpr dart::compiler::target::word
-    AOT_UnhandledException_stacktrace_offset = 16;
+    AOT_UnhandledException_stacktrace_offset = 12;
 static constexpr dart::compiler::target::word AOT_UserTag_tag_offset = 16;
 static constexpr dart::compiler::target::word
     AOT_MonomorphicSmiableCall_expected_cid_offset = 16;
@@ -8707,8 +8707,8 @@
     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};
+        1336, 1344, 1352, 1360, -1,   -1,   1368, 1376,
+        1384, 1392, 1400, -1,   1408, 1416, -1,   -1};
 static constexpr dart::compiler::target::word AOT_AbstractType_InstanceSize =
     24;
 static constexpr dart::compiler::target::word AOT_ApiError_InstanceSize = 16;
@@ -8716,9 +8716,9 @@
 static constexpr dart::compiler::target::word AOT_Array_header_size = 24;
 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 = 184;
+static constexpr dart::compiler::target::word AOT_Class_InstanceSize = 112;
 static constexpr dart::compiler::target::word AOT_Closure_InstanceSize = 56;
-static constexpr dart::compiler::target::word AOT_ClosureData_InstanceSize = 48;
+static constexpr dart::compiler::target::word AOT_ClosureData_InstanceSize = 32;
 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
@@ -8731,7 +8731,7 @@
 static constexpr dart::compiler::target::word AOT_DynamicLibrary_InstanceSize =
     16;
 static constexpr dart::compiler::target::word
-    AOT_ExceptionHandlers_InstanceSize = 24;
+    AOT_ExceptionHandlers_InstanceSize = 16;
 static constexpr dart::compiler::target::word
     AOT_ExternalOneByteString_InstanceSize = 32;
 static constexpr dart::compiler::target::word
@@ -8739,13 +8739,13 @@
 static constexpr dart::compiler::target::word
     AOT_ExternalTypedData_InstanceSize = 24;
 static constexpr dart::compiler::target::word
-    AOT_FfiTrampolineData_InstanceSize = 48;
-static constexpr dart::compiler::target::word AOT_Field_InstanceSize = 80;
+    AOT_FfiTrampolineData_InstanceSize = 32;
+static constexpr dart::compiler::target::word AOT_Field_InstanceSize = 56;
 static constexpr dart::compiler::target::word AOT_Float32x4_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_Float64x2_InstanceSize = 24;
-static constexpr dart::compiler::target::word AOT_Function_InstanceSize = 88;
+static constexpr dart::compiler::target::word AOT_Function_InstanceSize = 64;
 static constexpr dart::compiler::target::word AOT_FunctionType_InstanceSize =
-    72;
+    48;
 static constexpr dart::compiler::target::word AOT_FutureOr_InstanceSize = 16;
 static constexpr dart::compiler::target::word
     AOT_GrowableObjectArray_InstanceSize = 32;
@@ -8758,12 +8758,12 @@
 static constexpr dart::compiler::target::word AOT_Int32x4_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_Integer_InstanceSize = 8;
 static constexpr dart::compiler::target::word
-    AOT_KernelProgramInfo_InstanceSize = 120;
+    AOT_KernelProgramInfo_InstanceSize = 64;
 static constexpr dart::compiler::target::word AOT_LanguageError_InstanceSize =
-    48;
-static constexpr dart::compiler::target::word AOT_Library_InstanceSize = 152;
+    32;
+static constexpr dart::compiler::target::word AOT_Library_InstanceSize = 96;
 static constexpr dart::compiler::target::word AOT_LibraryPrefix_InstanceSize =
-    40;
+    24;
 static constexpr dart::compiler::target::word AOT_LinkedHashMap_InstanceSize =
     56;
 static constexpr dart::compiler::target::word
@@ -8775,7 +8775,7 @@
     16;
 static constexpr dart::compiler::target::word
     AOT_MonomorphicSmiableCall_InstanceSize = 32;
-static constexpr dart::compiler::target::word AOT_Namespace_InstanceSize = 40;
+static constexpr dart::compiler::target::word AOT_Namespace_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_NativeArguments_StructSize =
     32;
 static constexpr dart::compiler::target::word AOT_Number_InstanceSize = 8;
@@ -8783,55 +8783,55 @@
 static constexpr dart::compiler::target::word AOT_ObjectPool_InstanceSize = 16;
 static constexpr dart::compiler::target::word AOT_OneByteString_InstanceSize =
     16;
-static constexpr dart::compiler::target::word AOT_PatchClass_InstanceSize = 40;
+static constexpr dart::compiler::target::word AOT_PatchClass_InstanceSize = 24;
 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_RegExp_InstanceSize = 120;
-static constexpr dart::compiler::target::word AOT_Script_InstanceSize = 88;
+static constexpr dart::compiler::target::word AOT_ReceivePort_InstanceSize = 24;
+static constexpr dart::compiler::target::word AOT_RegExp_InstanceSize = 80;
+static constexpr dart::compiler::target::word AOT_Script_InstanceSize = 56;
 static constexpr dart::compiler::target::word AOT_SendPort_InstanceSize = 24;
 static constexpr dart::compiler::target::word
     AOT_SingleTargetCache_InstanceSize = 32;
 static constexpr dart::compiler::target::word AOT_Smi_InstanceSize = 8;
-static constexpr dart::compiler::target::word AOT_StackTrace_InstanceSize = 40;
+static constexpr dart::compiler::target::word AOT_StackTrace_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_String_InstanceSize = 16;
 static constexpr dart::compiler::target::word
     AOT_SubtypeTestCache_InstanceSize = 16;
-static constexpr dart::compiler::target::word AOT_LoadingUnit_InstanceSize = 32;
+static constexpr dart::compiler::target::word AOT_LoadingUnit_InstanceSize = 24;
 static constexpr dart::compiler::target::word
     AOT_TransferableTypedData_InstanceSize = 8;
 static constexpr dart::compiler::target::word AOT_TwoByteString_InstanceSize =
     16;
-static constexpr dart::compiler::target::word AOT_Type_InstanceSize = 56;
+static constexpr dart::compiler::target::word AOT_Type_InstanceSize = 40;
 static constexpr dart::compiler::target::word AOT_TypeArguments_InstanceSize =
     40;
 static constexpr dart::compiler::target::word AOT_TypeParameter_InstanceSize =
-    64;
-static constexpr dart::compiler::target::word AOT_TypeRef_InstanceSize = 32;
+    48;
+static constexpr dart::compiler::target::word AOT_TypeRef_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_TypedData_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_TypedDataBase_InstanceSize =
     24;
 static constexpr dart::compiler::target::word AOT_TypedDataView_InstanceSize =
-    40;
+    32;
 static constexpr dart::compiler::target::word
-    AOT_UnhandledException_InstanceSize = 24;
+    AOT_UnhandledException_InstanceSize = 16;
 static constexpr dart::compiler::target::word AOT_UnlinkedCall_InstanceSize =
     32;
-static constexpr dart::compiler::target::word AOT_UnwindError_InstanceSize = 24;
+static constexpr dart::compiler::target::word AOT_UnwindError_InstanceSize = 16;
 static constexpr dart::compiler::target::word AOT_UserTag_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_WeakProperty_InstanceSize =
     32;
 static constexpr dart::compiler::target::word
-    AOT_WeakSerializationReference_InstanceSize = 24;
+    AOT_WeakSerializationReference_InstanceSize = 16;
 #endif  // defined(TARGET_ARCH_X64) && defined(DART_COMPRESSED_POINTERS)
 
 #if defined(TARGET_ARCH_ARM64) && defined(DART_COMPRESSED_POINTERS)
 static constexpr dart::compiler::target::word
     AOT_ContextScope_elements_start_offset = 16;
 static constexpr dart::compiler::target::word AOT_ContextScope_element_size =
-    64;
+    32;
 static constexpr dart::compiler::target::word
-    AOT_ExceptionHandlers_elements_start_offset = 24;
+    AOT_ExceptionHandlers_elements_start_offset = 16;
 static constexpr dart::compiler::target::word
     AOT_ExceptionHandlers_element_size = 12;
 static constexpr dart::compiler::target::word
@@ -8903,12 +8903,12 @@
 static constexpr dart::compiler::target::word AOT_Array_type_arguments_offset =
     8;
 static constexpr dart::compiler::target::word
-    AOT_Class_declaration_type_offset = 104;
+    AOT_Class_declaration_type_offset = 56;
 static constexpr dart::compiler::target::word
-    AOT_Class_num_type_arguments_offset = 164;
-static constexpr dart::compiler::target::word AOT_Class_super_type_offset = 88;
+    AOT_Class_num_type_arguments_offset = 92;
+static constexpr dart::compiler::target::word AOT_Class_super_type_offset = 48;
 static constexpr dart::compiler::target::word
-    AOT_Class_host_type_arguments_field_offset_in_words_offset = 176;
+    AOT_Class_host_type_arguments_field_offset_in_words_offset = 104;
 static constexpr dart::compiler::target::word
     AOT_SharedClassTable_class_heap_stats_table_offset = 0;
 static constexpr dart::compiler::target::word AOT_Closure_context_offset = 40;
@@ -8921,9 +8921,9 @@
 static constexpr dart::compiler::target::word
     AOT_Closure_instantiator_type_arguments_offset = 8;
 static constexpr dart::compiler::target::word
-    AOT_ClosureData_default_type_arguments_offset = 32;
+    AOT_ClosureData_default_type_arguments_offset = 20;
 static constexpr dart::compiler::target::word
-    AOT_ClosureData_default_type_arguments_info_offset = 40;
+    AOT_ClosureData_default_type_arguments_kind_offset = 24;
 static constexpr dart::compiler::target::word AOT_Code_object_pool_offset = 40;
 static constexpr dart::compiler::target::word
     AOT_Code_saved_instructions_offset = 48;
@@ -8939,25 +8939,25 @@
 static constexpr dart::compiler::target::word AOT_Float32x4_value_offset = 8;
 static constexpr dart::compiler::target::word AOT_Float64x2_value_offset = 8;
 static constexpr dart::compiler::target::word
-    AOT_Field_initializer_function_offset = 32;
+    AOT_Field_initializer_function_offset = 20;
 static constexpr dart::compiler::target::word
-    AOT_Field_host_offset_or_field_id_offset = 40;
-static constexpr dart::compiler::target::word AOT_Field_guarded_cid_offset = 72;
+    AOT_Field_host_offset_or_field_id_offset = 24;
+static constexpr dart::compiler::target::word AOT_Field_guarded_cid_offset = 44;
 static constexpr dart::compiler::target::word
-    AOT_Field_guarded_list_length_in_object_offset_offset = 76;
+    AOT_Field_guarded_list_length_in_object_offset_offset = 48;
 static constexpr dart::compiler::target::word
-    AOT_Field_guarded_list_length_offset = 48;
-static constexpr dart::compiler::target::word AOT_Field_is_nullable_offset = 74;
-static constexpr dart::compiler::target::word AOT_Field_kind_bits_offset = 78;
-static constexpr dart::compiler::target::word AOT_Function_code_offset = 72;
-static constexpr dart::compiler::target::word AOT_Function_data_offset = 56;
+    AOT_Field_guarded_list_length_offset = 28;
+static constexpr dart::compiler::target::word AOT_Field_is_nullable_offset = 46;
+static constexpr dart::compiler::target::word AOT_Field_kind_bits_offset = 50;
+static constexpr dart::compiler::target::word AOT_Function_code_offset = 48;
+static constexpr dart::compiler::target::word AOT_Function_data_offset = 40;
 static constexpr dart::compiler::target::word
     AOT_Function_entry_point_offset[] = {8, 16};
-static constexpr dart::compiler::target::word AOT_Function_kind_tag_offset = 80;
+static constexpr dart::compiler::target::word AOT_Function_kind_tag_offset = 52;
 static constexpr dart::compiler::target::word
-    AOT_Function_packed_fields_offset = 84;
+    AOT_Function_packed_fields_offset = 56;
 static constexpr dart::compiler::target::word AOT_Function_signature_offset =
-    48;
+    36;
 static constexpr dart::compiler::target::word
     AOT_FutureOr_type_arguments_offset = 8;
 static constexpr dart::compiler::target::word
@@ -9054,9 +9054,9 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_AllocateArray_entry_point_offset = 728;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_exception_offset = 1464;
+    AOT_Thread_active_exception_offset = 1488;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_stacktrace_offset = 1472;
+    AOT_Thread_active_stacktrace_offset = 1496;
 static constexpr dart::compiler::target::word
     AOT_Thread_array_write_barrier_code_offset = 232;
 static constexpr dart::compiler::target::word
@@ -9082,7 +9082,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_allocate_object_slow_stub_offset = 384;
 static constexpr dart::compiler::target::word AOT_Thread_api_top_scope_offset =
-    1544;
+    1568;
 static constexpr dart::compiler::target::word
     AOT_Thread_auto_scope_native_wrapper_entry_point_offset = 656;
 static constexpr dart::compiler::target::word AOT_Thread_bool_false_offset =
@@ -9095,7 +9095,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_call_to_runtime_stub_offset = 264;
 static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset =
-    1560;
+    1584;
 static constexpr dart::compiler::target::word
     AOT_Thread_dispatch_table_array_offset = 96;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset =
@@ -9114,7 +9114,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_enter_safepoint_stub_offset = 488;
 static constexpr dart::compiler::target::word
-    AOT_Thread_execution_state_offset = 1504;
+    AOT_Thread_execution_state_offset = 1528;
 static constexpr dart::compiler::target::word
     AOT_Thread_exit_safepoint_stub_offset = 496;
 static constexpr dart::compiler::target::word
@@ -9134,14 +9134,14 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_float_zerow_address_offset = 720;
 static constexpr dart::compiler::target::word
-    AOT_Thread_global_object_pool_offset = 1480;
+    AOT_Thread_global_object_pool_offset = 1504;
 static constexpr dart::compiler::target::word
     AOT_Thread_invoke_dart_code_stub_offset = 256;
 static constexpr dart::compiler::target::word
-    AOT_Thread_exit_through_ffi_offset = 1536;
+    AOT_Thread_exit_through_ffi_offset = 1560;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 88;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_group_offset =
-    1568;
+    1592;
 static constexpr dart::compiler::target::word
     AOT_Thread_field_table_values_offset = 136;
 static constexpr dart::compiler::target::word
@@ -9186,11 +9186,11 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_predefined_symbols_address_offset = 664;
 static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset =
-    1488;
+    1512;
 static constexpr dart::compiler::target::word
-    AOT_Thread_saved_shadow_call_stack_offset = 1496;
+    AOT_Thread_saved_shadow_call_stack_offset = 1520;
 static constexpr dart::compiler::target::word
-    AOT_Thread_safepoint_state_offset = 1512;
+    AOT_Thread_safepoint_state_offset = 1536;
 static constexpr dart::compiler::target::word
     AOT_Thread_slow_type_test_stub_offset = 472;
 static constexpr dart::compiler::target::word
@@ -9227,34 +9227,34 @@
     AOT_Thread_write_barrier_mask_offset = 72;
 static constexpr dart::compiler::target::word AOT_Thread_heap_base_offset = 80;
 static constexpr dart::compiler::target::word AOT_Thread_callback_code_offset =
-    1520;
+    1544;
 static constexpr dart::compiler::target::word
-    AOT_Thread_callback_stack_return_offset = 1528;
+    AOT_Thread_callback_stack_return_offset = 1552;
 static constexpr dart::compiler::target::word
     AOT_TimelineStream_enabled_offset = 16;
 static constexpr dart::compiler::target::word AOT_TwoByteString_data_offset =
     16;
-static constexpr dart::compiler::target::word AOT_Type_arguments_offset = 32;
-static constexpr dart::compiler::target::word AOT_Type_hash_offset = 40;
+static constexpr dart::compiler::target::word AOT_Type_arguments_offset = 24;
+static constexpr dart::compiler::target::word AOT_Type_hash_offset = 28;
 static constexpr dart::compiler::target::word AOT_Type_type_class_id_offset =
-    24;
-static constexpr dart::compiler::target::word AOT_Type_type_state_offset = 48;
-static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 49;
-static constexpr dart::compiler::target::word AOT_FunctionType_hash_offset = 56;
+    20;
+static constexpr dart::compiler::target::word AOT_Type_type_state_offset = 32;
+static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 33;
+static constexpr dart::compiler::target::word AOT_FunctionType_hash_offset = 36;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_packed_fields_offset = 64;
+    AOT_FunctionType_packed_fields_offset = 40;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_parameter_types_offset = 40;
+    AOT_FunctionType_parameter_types_offset = 28;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_parameter_names_offset = 48;
+    AOT_FunctionType_parameter_names_offset = 32;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_type_parameters_offset = 24;
+    AOT_FunctionType_type_parameters_offset = 20;
 static constexpr dart::compiler::target::word
-    AOT_TypeParameter_parameterized_class_id_offset = 56;
+    AOT_TypeParameter_parameterized_class_id_offset = 36;
 static constexpr dart::compiler::target::word AOT_TypeParameter_index_offset =
-    60;
+    40;
 static constexpr dart::compiler::target::word
-    AOT_TypeParameter_nullability_offset = 63;
+    AOT_TypeParameter_nullability_offset = 43;
 static constexpr dart::compiler::target::word
     AOT_TypeArguments_instantiations_offset = 8;
 static constexpr dart::compiler::target::word AOT_TypeArguments_length_offset =
@@ -9264,23 +9264,23 @@
 static constexpr dart::compiler::target::word AOT_TypeArguments_types_offset =
     40;
 static constexpr dart::compiler::target::word AOT_TypeParameter_bound_offset =
-    40;
+    28;
 static constexpr dart::compiler::target::word AOT_TypeParameter_flags_offset =
-    62;
+    42;
 static constexpr dart::compiler::target::word AOT_TypeParameter_name_offset =
-    24;
-static constexpr dart::compiler::target::word AOT_TypeRef_type_offset = 24;
+    20;
+static constexpr dart::compiler::target::word AOT_TypeRef_type_offset = 20;
 static constexpr dart::compiler::target::word AOT_TypedDataBase_length_offset =
     16;
 static constexpr dart::compiler::target::word AOT_TypedDataView_data_offset =
-    24;
+    20;
 static constexpr dart::compiler::target::word
-    AOT_TypedDataView_offset_in_bytes_offset = 32;
+    AOT_TypedDataView_offset_in_bytes_offset = 24;
 static constexpr dart::compiler::target::word AOT_TypedData_data_offset = 24;
 static constexpr dart::compiler::target::word
     AOT_UnhandledException_exception_offset = 8;
 static constexpr dart::compiler::target::word
-    AOT_UnhandledException_stacktrace_offset = 16;
+    AOT_UnhandledException_stacktrace_offset = 12;
 static constexpr dart::compiler::target::word AOT_UserTag_tag_offset = 16;
 static constexpr dart::compiler::target::word
     AOT_MonomorphicSmiableCall_expected_cid_offset = 16;
@@ -9305,9 +9305,9 @@
     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,   -1,   1448, 1456, -1,   -1,   -1,   -1,   -1,   -1};
+        1336, 1344, 1352, 1360, 1368, 1376, 1384, 1392, 1400, 1408, 1416,
+        1424, 1432, 1440, 1448, -1,   -1,   -1,   -1,   1456, 1464, -1,
+        -1,   -1,   1472, 1480, -1,   -1,   -1,   -1,   -1,   -1};
 static constexpr dart::compiler::target::word AOT_AbstractType_InstanceSize =
     24;
 static constexpr dart::compiler::target::word AOT_ApiError_InstanceSize = 16;
@@ -9315,9 +9315,9 @@
 static constexpr dart::compiler::target::word AOT_Array_header_size = 24;
 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 = 184;
+static constexpr dart::compiler::target::word AOT_Class_InstanceSize = 112;
 static constexpr dart::compiler::target::word AOT_Closure_InstanceSize = 56;
-static constexpr dart::compiler::target::word AOT_ClosureData_InstanceSize = 48;
+static constexpr dart::compiler::target::word AOT_ClosureData_InstanceSize = 32;
 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
@@ -9330,7 +9330,7 @@
 static constexpr dart::compiler::target::word AOT_DynamicLibrary_InstanceSize =
     16;
 static constexpr dart::compiler::target::word
-    AOT_ExceptionHandlers_InstanceSize = 24;
+    AOT_ExceptionHandlers_InstanceSize = 16;
 static constexpr dart::compiler::target::word
     AOT_ExternalOneByteString_InstanceSize = 32;
 static constexpr dart::compiler::target::word
@@ -9338,13 +9338,13 @@
 static constexpr dart::compiler::target::word
     AOT_ExternalTypedData_InstanceSize = 24;
 static constexpr dart::compiler::target::word
-    AOT_FfiTrampolineData_InstanceSize = 48;
-static constexpr dart::compiler::target::word AOT_Field_InstanceSize = 80;
+    AOT_FfiTrampolineData_InstanceSize = 32;
+static constexpr dart::compiler::target::word AOT_Field_InstanceSize = 56;
 static constexpr dart::compiler::target::word AOT_Float32x4_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_Float64x2_InstanceSize = 24;
-static constexpr dart::compiler::target::word AOT_Function_InstanceSize = 88;
+static constexpr dart::compiler::target::word AOT_Function_InstanceSize = 64;
 static constexpr dart::compiler::target::word AOT_FunctionType_InstanceSize =
-    72;
+    48;
 static constexpr dart::compiler::target::word AOT_FutureOr_InstanceSize = 16;
 static constexpr dart::compiler::target::word
     AOT_GrowableObjectArray_InstanceSize = 32;
@@ -9357,12 +9357,12 @@
 static constexpr dart::compiler::target::word AOT_Int32x4_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_Integer_InstanceSize = 8;
 static constexpr dart::compiler::target::word
-    AOT_KernelProgramInfo_InstanceSize = 120;
+    AOT_KernelProgramInfo_InstanceSize = 64;
 static constexpr dart::compiler::target::word AOT_LanguageError_InstanceSize =
-    48;
-static constexpr dart::compiler::target::word AOT_Library_InstanceSize = 152;
+    32;
+static constexpr dart::compiler::target::word AOT_Library_InstanceSize = 96;
 static constexpr dart::compiler::target::word AOT_LibraryPrefix_InstanceSize =
-    40;
+    24;
 static constexpr dart::compiler::target::word AOT_LinkedHashMap_InstanceSize =
     56;
 static constexpr dart::compiler::target::word
@@ -9374,7 +9374,7 @@
     16;
 static constexpr dart::compiler::target::word
     AOT_MonomorphicSmiableCall_InstanceSize = 32;
-static constexpr dart::compiler::target::word AOT_Namespace_InstanceSize = 40;
+static constexpr dart::compiler::target::word AOT_Namespace_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_NativeArguments_StructSize =
     32;
 static constexpr dart::compiler::target::word AOT_Number_InstanceSize = 8;
@@ -9382,46 +9382,46 @@
 static constexpr dart::compiler::target::word AOT_ObjectPool_InstanceSize = 16;
 static constexpr dart::compiler::target::word AOT_OneByteString_InstanceSize =
     16;
-static constexpr dart::compiler::target::word AOT_PatchClass_InstanceSize = 40;
+static constexpr dart::compiler::target::word AOT_PatchClass_InstanceSize = 24;
 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_RegExp_InstanceSize = 120;
-static constexpr dart::compiler::target::word AOT_Script_InstanceSize = 88;
+static constexpr dart::compiler::target::word AOT_ReceivePort_InstanceSize = 24;
+static constexpr dart::compiler::target::word AOT_RegExp_InstanceSize = 80;
+static constexpr dart::compiler::target::word AOT_Script_InstanceSize = 56;
 static constexpr dart::compiler::target::word AOT_SendPort_InstanceSize = 24;
 static constexpr dart::compiler::target::word
     AOT_SingleTargetCache_InstanceSize = 32;
 static constexpr dart::compiler::target::word AOT_Smi_InstanceSize = 8;
-static constexpr dart::compiler::target::word AOT_StackTrace_InstanceSize = 40;
+static constexpr dart::compiler::target::word AOT_StackTrace_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_String_InstanceSize = 16;
 static constexpr dart::compiler::target::word
     AOT_SubtypeTestCache_InstanceSize = 16;
-static constexpr dart::compiler::target::word AOT_LoadingUnit_InstanceSize = 32;
+static constexpr dart::compiler::target::word AOT_LoadingUnit_InstanceSize = 24;
 static constexpr dart::compiler::target::word
     AOT_TransferableTypedData_InstanceSize = 8;
 static constexpr dart::compiler::target::word AOT_TwoByteString_InstanceSize =
     16;
-static constexpr dart::compiler::target::word AOT_Type_InstanceSize = 56;
+static constexpr dart::compiler::target::word AOT_Type_InstanceSize = 40;
 static constexpr dart::compiler::target::word AOT_TypeArguments_InstanceSize =
     40;
 static constexpr dart::compiler::target::word AOT_TypeParameter_InstanceSize =
-    64;
-static constexpr dart::compiler::target::word AOT_TypeRef_InstanceSize = 32;
+    48;
+static constexpr dart::compiler::target::word AOT_TypeRef_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_TypedData_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_TypedDataBase_InstanceSize =
     24;
 static constexpr dart::compiler::target::word AOT_TypedDataView_InstanceSize =
-    40;
+    32;
 static constexpr dart::compiler::target::word
-    AOT_UnhandledException_InstanceSize = 24;
+    AOT_UnhandledException_InstanceSize = 16;
 static constexpr dart::compiler::target::word AOT_UnlinkedCall_InstanceSize =
     32;
-static constexpr dart::compiler::target::word AOT_UnwindError_InstanceSize = 24;
+static constexpr dart::compiler::target::word AOT_UnwindError_InstanceSize = 16;
 static constexpr dart::compiler::target::word AOT_UserTag_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_WeakProperty_InstanceSize =
     32;
 static constexpr dart::compiler::target::word
-    AOT_WeakSerializationReference_InstanceSize = 24;
+    AOT_WeakSerializationReference_InstanceSize = 16;
 #endif  // defined(TARGET_ARCH_ARM64) && defined(DART_COMPRESSED_POINTERS)
 
 #else  // !defined(PRODUCT)
@@ -9521,7 +9521,7 @@
 static constexpr dart::compiler::target::word
     AOT_ClosureData_default_type_arguments_offset = 16;
 static constexpr dart::compiler::target::word
-    AOT_ClosureData_default_type_arguments_info_offset = 20;
+    AOT_ClosureData_default_type_arguments_kind_offset = 20;
 static constexpr dart::compiler::target::word AOT_Code_object_pool_offset = 20;
 static constexpr dart::compiler::target::word
     AOT_Code_saved_instructions_offset = 24;
@@ -9650,9 +9650,9 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_AllocateArray_entry_point_offset = 368;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_exception_offset = 692;
+    AOT_Thread_active_exception_offset = 704;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_stacktrace_offset = 696;
+    AOT_Thread_active_stacktrace_offset = 708;
 static constexpr dart::compiler::target::word
     AOT_Thread_array_write_barrier_code_offset = 120;
 static constexpr dart::compiler::target::word
@@ -9678,7 +9678,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_allocate_object_slow_stub_offset = 196;
 static constexpr dart::compiler::target::word AOT_Thread_api_top_scope_offset =
-    732;
+    744;
 static constexpr dart::compiler::target::word
     AOT_Thread_auto_scope_native_wrapper_entry_point_offset = 332;
 static constexpr dart::compiler::target::word AOT_Thread_bool_false_offset =
@@ -9691,7 +9691,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_call_to_runtime_stub_offset = 136;
 static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset =
-    740;
+    752;
 static constexpr dart::compiler::target::word
     AOT_Thread_dispatch_table_array_offset = 48;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset =
@@ -9710,7 +9710,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_enter_safepoint_stub_offset = 248;
 static constexpr dart::compiler::target::word
-    AOT_Thread_execution_state_offset = 712;
+    AOT_Thread_execution_state_offset = 724;
 static constexpr dart::compiler::target::word
     AOT_Thread_exit_safepoint_stub_offset = 252;
 static constexpr dart::compiler::target::word
@@ -9730,14 +9730,14 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_float_zerow_address_offset = 364;
 static constexpr dart::compiler::target::word
-    AOT_Thread_global_object_pool_offset = 700;
+    AOT_Thread_global_object_pool_offset = 712;
 static constexpr dart::compiler::target::word
     AOT_Thread_invoke_dart_code_stub_offset = 132;
 static constexpr dart::compiler::target::word
-    AOT_Thread_exit_through_ffi_offset = 728;
+    AOT_Thread_exit_through_ffi_offset = 740;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 44;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_group_offset =
-    744;
+    756;
 static constexpr dart::compiler::target::word
     AOT_Thread_field_table_values_offset = 68;
 static constexpr dart::compiler::target::word
@@ -9781,11 +9781,11 @@
     104;
 static constexpr dart::compiler::target::word
     AOT_Thread_predefined_symbols_address_offset = 336;
-static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset = 704;
+static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset = 716;
 static constexpr dart::compiler::target::word
-    AOT_Thread_saved_shadow_call_stack_offset = 708;
+    AOT_Thread_saved_shadow_call_stack_offset = 720;
 static constexpr dart::compiler::target::word
-    AOT_Thread_safepoint_state_offset = 716;
+    AOT_Thread_safepoint_state_offset = 728;
 static constexpr dart::compiler::target::word
     AOT_Thread_slow_type_test_stub_offset = 240;
 static constexpr dart::compiler::target::word
@@ -9822,9 +9822,9 @@
     AOT_Thread_write_barrier_mask_offset = 36;
 static constexpr dart::compiler::target::word AOT_Thread_heap_base_offset = 40;
 static constexpr dart::compiler::target::word AOT_Thread_callback_code_offset =
-    720;
+    732;
 static constexpr dart::compiler::target::word
-    AOT_Thread_callback_stack_return_offset = 724;
+    AOT_Thread_callback_stack_return_offset = 736;
 static constexpr dart::compiler::target::word
     AOT_TimelineStream_enabled_offset = 8;
 static constexpr dart::compiler::target::word AOT_TwoByteString_data_offset =
@@ -9896,7 +9896,7 @@
     4, 12, 8, 16};
 static constexpr dart::compiler::target::word
     AOT_Thread_write_barrier_wrappers_thread_offset[] = {
-        660, 664, 668, 672, 676, -1, 680, -1, 684, 688, -1, -1, -1, -1, -1, -1};
+        672, 676, 680, 684, 688, -1, 692, -1, 696, 700, -1, -1, -1, -1, -1, -1};
 static constexpr dart::compiler::target::word AOT_AbstractType_InstanceSize =
     12;
 static constexpr dart::compiler::target::word AOT_ApiError_InstanceSize = 8;
@@ -10109,7 +10109,7 @@
 static constexpr dart::compiler::target::word
     AOT_ClosureData_default_type_arguments_offset = 32;
 static constexpr dart::compiler::target::word
-    AOT_ClosureData_default_type_arguments_info_offset = 40;
+    AOT_ClosureData_default_type_arguments_kind_offset = 40;
 static constexpr dart::compiler::target::word AOT_Code_object_pool_offset = 40;
 static constexpr dart::compiler::target::word
     AOT_Code_saved_instructions_offset = 48;
@@ -10238,9 +10238,9 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_AllocateArray_entry_point_offset = 728;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_exception_offset = 1400;
+    AOT_Thread_active_exception_offset = 1424;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_stacktrace_offset = 1408;
+    AOT_Thread_active_stacktrace_offset = 1432;
 static constexpr dart::compiler::target::word
     AOT_Thread_array_write_barrier_code_offset = 232;
 static constexpr dart::compiler::target::word
@@ -10266,7 +10266,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_allocate_object_slow_stub_offset = 384;
 static constexpr dart::compiler::target::word AOT_Thread_api_top_scope_offset =
-    1480;
+    1504;
 static constexpr dart::compiler::target::word
     AOT_Thread_auto_scope_native_wrapper_entry_point_offset = 656;
 static constexpr dart::compiler::target::word AOT_Thread_bool_false_offset =
@@ -10279,7 +10279,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_call_to_runtime_stub_offset = 264;
 static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset =
-    1496;
+    1520;
 static constexpr dart::compiler::target::word
     AOT_Thread_dispatch_table_array_offset = 96;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset =
@@ -10298,7 +10298,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_enter_safepoint_stub_offset = 488;
 static constexpr dart::compiler::target::word
-    AOT_Thread_execution_state_offset = 1440;
+    AOT_Thread_execution_state_offset = 1464;
 static constexpr dart::compiler::target::word
     AOT_Thread_exit_safepoint_stub_offset = 496;
 static constexpr dart::compiler::target::word
@@ -10318,14 +10318,14 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_float_zerow_address_offset = 720;
 static constexpr dart::compiler::target::word
-    AOT_Thread_global_object_pool_offset = 1416;
+    AOT_Thread_global_object_pool_offset = 1440;
 static constexpr dart::compiler::target::word
     AOT_Thread_invoke_dart_code_stub_offset = 256;
 static constexpr dart::compiler::target::word
-    AOT_Thread_exit_through_ffi_offset = 1472;
+    AOT_Thread_exit_through_ffi_offset = 1496;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 88;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_group_offset =
-    1504;
+    1528;
 static constexpr dart::compiler::target::word
     AOT_Thread_field_table_values_offset = 136;
 static constexpr dart::compiler::target::word
@@ -10370,11 +10370,11 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_predefined_symbols_address_offset = 664;
 static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset =
-    1424;
+    1448;
 static constexpr dart::compiler::target::word
-    AOT_Thread_saved_shadow_call_stack_offset = 1432;
+    AOT_Thread_saved_shadow_call_stack_offset = 1456;
 static constexpr dart::compiler::target::word
-    AOT_Thread_safepoint_state_offset = 1448;
+    AOT_Thread_safepoint_state_offset = 1472;
 static constexpr dart::compiler::target::word
     AOT_Thread_slow_type_test_stub_offset = 472;
 static constexpr dart::compiler::target::word
@@ -10411,9 +10411,9 @@
     AOT_Thread_write_barrier_mask_offset = 72;
 static constexpr dart::compiler::target::word AOT_Thread_heap_base_offset = 80;
 static constexpr dart::compiler::target::word AOT_Thread_callback_code_offset =
-    1456;
+    1480;
 static constexpr dart::compiler::target::word
-    AOT_Thread_callback_stack_return_offset = 1464;
+    AOT_Thread_callback_stack_return_offset = 1488;
 static constexpr dart::compiler::target::word
     AOT_TimelineStream_enabled_offset = 16;
 static constexpr dart::compiler::target::word AOT_TwoByteString_data_offset =
@@ -10486,8 +10486,8 @@
     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};
+        1336, 1344, 1352, 1360, -1,   -1,   1368, 1376,
+        1384, 1392, 1400, -1,   1408, 1416, -1,   -1};
 static constexpr dart::compiler::target::word AOT_AbstractType_InstanceSize =
     24;
 static constexpr dart::compiler::target::word AOT_ApiError_InstanceSize = 16;
@@ -10703,7 +10703,7 @@
 static constexpr dart::compiler::target::word
     AOT_ClosureData_default_type_arguments_offset = 32;
 static constexpr dart::compiler::target::word
-    AOT_ClosureData_default_type_arguments_info_offset = 40;
+    AOT_ClosureData_default_type_arguments_kind_offset = 40;
 static constexpr dart::compiler::target::word AOT_Code_object_pool_offset = 40;
 static constexpr dart::compiler::target::word
     AOT_Code_saved_instructions_offset = 48;
@@ -10832,9 +10832,9 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_AllocateArray_entry_point_offset = 728;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_exception_offset = 1464;
+    AOT_Thread_active_exception_offset = 1488;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_stacktrace_offset = 1472;
+    AOT_Thread_active_stacktrace_offset = 1496;
 static constexpr dart::compiler::target::word
     AOT_Thread_array_write_barrier_code_offset = 232;
 static constexpr dart::compiler::target::word
@@ -10860,7 +10860,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_allocate_object_slow_stub_offset = 384;
 static constexpr dart::compiler::target::word AOT_Thread_api_top_scope_offset =
-    1544;
+    1568;
 static constexpr dart::compiler::target::word
     AOT_Thread_auto_scope_native_wrapper_entry_point_offset = 656;
 static constexpr dart::compiler::target::word AOT_Thread_bool_false_offset =
@@ -10873,7 +10873,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_call_to_runtime_stub_offset = 264;
 static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset =
-    1560;
+    1584;
 static constexpr dart::compiler::target::word
     AOT_Thread_dispatch_table_array_offset = 96;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset =
@@ -10892,7 +10892,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_enter_safepoint_stub_offset = 488;
 static constexpr dart::compiler::target::word
-    AOT_Thread_execution_state_offset = 1504;
+    AOT_Thread_execution_state_offset = 1528;
 static constexpr dart::compiler::target::word
     AOT_Thread_exit_safepoint_stub_offset = 496;
 static constexpr dart::compiler::target::word
@@ -10912,14 +10912,14 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_float_zerow_address_offset = 720;
 static constexpr dart::compiler::target::word
-    AOT_Thread_global_object_pool_offset = 1480;
+    AOT_Thread_global_object_pool_offset = 1504;
 static constexpr dart::compiler::target::word
     AOT_Thread_invoke_dart_code_stub_offset = 256;
 static constexpr dart::compiler::target::word
-    AOT_Thread_exit_through_ffi_offset = 1536;
+    AOT_Thread_exit_through_ffi_offset = 1560;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 88;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_group_offset =
-    1568;
+    1592;
 static constexpr dart::compiler::target::word
     AOT_Thread_field_table_values_offset = 136;
 static constexpr dart::compiler::target::word
@@ -10964,11 +10964,11 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_predefined_symbols_address_offset = 664;
 static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset =
-    1488;
+    1512;
 static constexpr dart::compiler::target::word
-    AOT_Thread_saved_shadow_call_stack_offset = 1496;
+    AOT_Thread_saved_shadow_call_stack_offset = 1520;
 static constexpr dart::compiler::target::word
-    AOT_Thread_safepoint_state_offset = 1512;
+    AOT_Thread_safepoint_state_offset = 1536;
 static constexpr dart::compiler::target::word
     AOT_Thread_slow_type_test_stub_offset = 472;
 static constexpr dart::compiler::target::word
@@ -11005,9 +11005,9 @@
     AOT_Thread_write_barrier_mask_offset = 72;
 static constexpr dart::compiler::target::word AOT_Thread_heap_base_offset = 80;
 static constexpr dart::compiler::target::word AOT_Thread_callback_code_offset =
-    1520;
+    1544;
 static constexpr dart::compiler::target::word
-    AOT_Thread_callback_stack_return_offset = 1528;
+    AOT_Thread_callback_stack_return_offset = 1552;
 static constexpr dart::compiler::target::word
     AOT_TimelineStream_enabled_offset = 16;
 static constexpr dart::compiler::target::word AOT_TwoByteString_data_offset =
@@ -11080,9 +11080,9 @@
     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,   -1,   1448, 1456, -1,   -1,   -1,   -1,   -1,   -1};
+        1336, 1344, 1352, 1360, 1368, 1376, 1384, 1392, 1400, 1408, 1416,
+        1424, 1432, 1440, 1448, -1,   -1,   -1,   -1,   1456, 1464, -1,
+        -1,   -1,   1472, 1480, -1,   -1,   -1,   -1,   -1,   -1};
 static constexpr dart::compiler::target::word AOT_AbstractType_InstanceSize =
     24;
 static constexpr dart::compiler::target::word AOT_ApiError_InstanceSize = 16;
@@ -11203,9 +11203,9 @@
 static constexpr dart::compiler::target::word
     AOT_ContextScope_elements_start_offset = 16;
 static constexpr dart::compiler::target::word AOT_ContextScope_element_size =
-    64;
+    32;
 static constexpr dart::compiler::target::word
-    AOT_ExceptionHandlers_elements_start_offset = 24;
+    AOT_ExceptionHandlers_elements_start_offset = 16;
 static constexpr dart::compiler::target::word
     AOT_ExceptionHandlers_element_size = 12;
 static constexpr dart::compiler::target::word
@@ -11277,12 +11277,12 @@
 static constexpr dart::compiler::target::word AOT_Array_type_arguments_offset =
     8;
 static constexpr dart::compiler::target::word
-    AOT_Class_declaration_type_offset = 104;
+    AOT_Class_declaration_type_offset = 56;
 static constexpr dart::compiler::target::word
-    AOT_Class_num_type_arguments_offset = 164;
-static constexpr dart::compiler::target::word AOT_Class_super_type_offset = 88;
+    AOT_Class_num_type_arguments_offset = 92;
+static constexpr dart::compiler::target::word AOT_Class_super_type_offset = 48;
 static constexpr dart::compiler::target::word
-    AOT_Class_host_type_arguments_field_offset_in_words_offset = 176;
+    AOT_Class_host_type_arguments_field_offset_in_words_offset = 104;
 static constexpr dart::compiler::target::word AOT_Closure_context_offset = 40;
 static constexpr dart::compiler::target::word
     AOT_Closure_delayed_type_arguments_offset = 24;
@@ -11293,9 +11293,9 @@
 static constexpr dart::compiler::target::word
     AOT_Closure_instantiator_type_arguments_offset = 8;
 static constexpr dart::compiler::target::word
-    AOT_ClosureData_default_type_arguments_offset = 32;
+    AOT_ClosureData_default_type_arguments_offset = 20;
 static constexpr dart::compiler::target::word
-    AOT_ClosureData_default_type_arguments_info_offset = 40;
+    AOT_ClosureData_default_type_arguments_kind_offset = 24;
 static constexpr dart::compiler::target::word AOT_Code_object_pool_offset = 40;
 static constexpr dart::compiler::target::word
     AOT_Code_saved_instructions_offset = 48;
@@ -11311,25 +11311,25 @@
 static constexpr dart::compiler::target::word AOT_Float32x4_value_offset = 8;
 static constexpr dart::compiler::target::word AOT_Float64x2_value_offset = 8;
 static constexpr dart::compiler::target::word
-    AOT_Field_initializer_function_offset = 32;
+    AOT_Field_initializer_function_offset = 20;
 static constexpr dart::compiler::target::word
-    AOT_Field_host_offset_or_field_id_offset = 40;
-static constexpr dart::compiler::target::word AOT_Field_guarded_cid_offset = 72;
+    AOT_Field_host_offset_or_field_id_offset = 24;
+static constexpr dart::compiler::target::word AOT_Field_guarded_cid_offset = 44;
 static constexpr dart::compiler::target::word
-    AOT_Field_guarded_list_length_in_object_offset_offset = 76;
+    AOT_Field_guarded_list_length_in_object_offset_offset = 48;
 static constexpr dart::compiler::target::word
-    AOT_Field_guarded_list_length_offset = 48;
-static constexpr dart::compiler::target::word AOT_Field_is_nullable_offset = 74;
-static constexpr dart::compiler::target::word AOT_Field_kind_bits_offset = 78;
-static constexpr dart::compiler::target::word AOT_Function_code_offset = 72;
-static constexpr dart::compiler::target::word AOT_Function_data_offset = 56;
+    AOT_Field_guarded_list_length_offset = 28;
+static constexpr dart::compiler::target::word AOT_Field_is_nullable_offset = 46;
+static constexpr dart::compiler::target::word AOT_Field_kind_bits_offset = 50;
+static constexpr dart::compiler::target::word AOT_Function_code_offset = 48;
+static constexpr dart::compiler::target::word AOT_Function_data_offset = 40;
 static constexpr dart::compiler::target::word
     AOT_Function_entry_point_offset[] = {8, 16};
-static constexpr dart::compiler::target::word AOT_Function_kind_tag_offset = 80;
+static constexpr dart::compiler::target::word AOT_Function_kind_tag_offset = 52;
 static constexpr dart::compiler::target::word
-    AOT_Function_packed_fields_offset = 84;
+    AOT_Function_packed_fields_offset = 56;
 static constexpr dart::compiler::target::word AOT_Function_signature_offset =
-    48;
+    36;
 static constexpr dart::compiler::target::word
     AOT_FutureOr_type_arguments_offset = 8;
 static constexpr dart::compiler::target::word
@@ -11424,9 +11424,9 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_AllocateArray_entry_point_offset = 728;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_exception_offset = 1400;
+    AOT_Thread_active_exception_offset = 1424;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_stacktrace_offset = 1408;
+    AOT_Thread_active_stacktrace_offset = 1432;
 static constexpr dart::compiler::target::word
     AOT_Thread_array_write_barrier_code_offset = 232;
 static constexpr dart::compiler::target::word
@@ -11452,7 +11452,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_allocate_object_slow_stub_offset = 384;
 static constexpr dart::compiler::target::word AOT_Thread_api_top_scope_offset =
-    1480;
+    1504;
 static constexpr dart::compiler::target::word
     AOT_Thread_auto_scope_native_wrapper_entry_point_offset = 656;
 static constexpr dart::compiler::target::word AOT_Thread_bool_false_offset =
@@ -11465,7 +11465,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_call_to_runtime_stub_offset = 264;
 static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset =
-    1496;
+    1520;
 static constexpr dart::compiler::target::word
     AOT_Thread_dispatch_table_array_offset = 96;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset =
@@ -11484,7 +11484,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_enter_safepoint_stub_offset = 488;
 static constexpr dart::compiler::target::word
-    AOT_Thread_execution_state_offset = 1440;
+    AOT_Thread_execution_state_offset = 1464;
 static constexpr dart::compiler::target::word
     AOT_Thread_exit_safepoint_stub_offset = 496;
 static constexpr dart::compiler::target::word
@@ -11504,14 +11504,14 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_float_zerow_address_offset = 720;
 static constexpr dart::compiler::target::word
-    AOT_Thread_global_object_pool_offset = 1416;
+    AOT_Thread_global_object_pool_offset = 1440;
 static constexpr dart::compiler::target::word
     AOT_Thread_invoke_dart_code_stub_offset = 256;
 static constexpr dart::compiler::target::word
-    AOT_Thread_exit_through_ffi_offset = 1472;
+    AOT_Thread_exit_through_ffi_offset = 1496;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 88;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_group_offset =
-    1504;
+    1528;
 static constexpr dart::compiler::target::word
     AOT_Thread_field_table_values_offset = 136;
 static constexpr dart::compiler::target::word
@@ -11556,11 +11556,11 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_predefined_symbols_address_offset = 664;
 static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset =
-    1424;
+    1448;
 static constexpr dart::compiler::target::word
-    AOT_Thread_saved_shadow_call_stack_offset = 1432;
+    AOT_Thread_saved_shadow_call_stack_offset = 1456;
 static constexpr dart::compiler::target::word
-    AOT_Thread_safepoint_state_offset = 1448;
+    AOT_Thread_safepoint_state_offset = 1472;
 static constexpr dart::compiler::target::word
     AOT_Thread_slow_type_test_stub_offset = 472;
 static constexpr dart::compiler::target::word
@@ -11597,34 +11597,34 @@
     AOT_Thread_write_barrier_mask_offset = 72;
 static constexpr dart::compiler::target::word AOT_Thread_heap_base_offset = 80;
 static constexpr dart::compiler::target::word AOT_Thread_callback_code_offset =
-    1456;
+    1480;
 static constexpr dart::compiler::target::word
-    AOT_Thread_callback_stack_return_offset = 1464;
+    AOT_Thread_callback_stack_return_offset = 1488;
 static constexpr dart::compiler::target::word
     AOT_TimelineStream_enabled_offset = 16;
 static constexpr dart::compiler::target::word AOT_TwoByteString_data_offset =
     16;
-static constexpr dart::compiler::target::word AOT_Type_arguments_offset = 32;
-static constexpr dart::compiler::target::word AOT_Type_hash_offset = 40;
+static constexpr dart::compiler::target::word AOT_Type_arguments_offset = 24;
+static constexpr dart::compiler::target::word AOT_Type_hash_offset = 28;
 static constexpr dart::compiler::target::word AOT_Type_type_class_id_offset =
-    24;
-static constexpr dart::compiler::target::word AOT_Type_type_state_offset = 48;
-static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 49;
-static constexpr dart::compiler::target::word AOT_FunctionType_hash_offset = 56;
+    20;
+static constexpr dart::compiler::target::word AOT_Type_type_state_offset = 32;
+static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 33;
+static constexpr dart::compiler::target::word AOT_FunctionType_hash_offset = 36;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_packed_fields_offset = 64;
+    AOT_FunctionType_packed_fields_offset = 40;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_parameter_types_offset = 40;
+    AOT_FunctionType_parameter_types_offset = 28;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_parameter_names_offset = 48;
+    AOT_FunctionType_parameter_names_offset = 32;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_type_parameters_offset = 24;
+    AOT_FunctionType_type_parameters_offset = 20;
 static constexpr dart::compiler::target::word
-    AOT_TypeParameter_parameterized_class_id_offset = 56;
+    AOT_TypeParameter_parameterized_class_id_offset = 36;
 static constexpr dart::compiler::target::word AOT_TypeParameter_index_offset =
-    60;
+    40;
 static constexpr dart::compiler::target::word
-    AOT_TypeParameter_nullability_offset = 63;
+    AOT_TypeParameter_nullability_offset = 43;
 static constexpr dart::compiler::target::word
     AOT_TypeArguments_instantiations_offset = 8;
 static constexpr dart::compiler::target::word AOT_TypeArguments_length_offset =
@@ -11634,23 +11634,23 @@
 static constexpr dart::compiler::target::word AOT_TypeArguments_types_offset =
     40;
 static constexpr dart::compiler::target::word AOT_TypeParameter_bound_offset =
-    40;
+    28;
 static constexpr dart::compiler::target::word AOT_TypeParameter_flags_offset =
-    62;
+    42;
 static constexpr dart::compiler::target::word AOT_TypeParameter_name_offset =
-    24;
-static constexpr dart::compiler::target::word AOT_TypeRef_type_offset = 24;
+    20;
+static constexpr dart::compiler::target::word AOT_TypeRef_type_offset = 20;
 static constexpr dart::compiler::target::word AOT_TypedDataBase_length_offset =
     16;
 static constexpr dart::compiler::target::word AOT_TypedDataView_data_offset =
-    24;
+    20;
 static constexpr dart::compiler::target::word
-    AOT_TypedDataView_offset_in_bytes_offset = 32;
+    AOT_TypedDataView_offset_in_bytes_offset = 24;
 static constexpr dart::compiler::target::word AOT_TypedData_data_offset = 24;
 static constexpr dart::compiler::target::word
     AOT_UnhandledException_exception_offset = 8;
 static constexpr dart::compiler::target::word
-    AOT_UnhandledException_stacktrace_offset = 16;
+    AOT_UnhandledException_stacktrace_offset = 12;
 static constexpr dart::compiler::target::word AOT_UserTag_tag_offset = 16;
 static constexpr dart::compiler::target::word
     AOT_MonomorphicSmiableCall_expected_cid_offset = 16;
@@ -11672,8 +11672,8 @@
     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};
+        1336, 1344, 1352, 1360, -1,   -1,   1368, 1376,
+        1384, 1392, 1400, -1,   1408, 1416, -1,   -1};
 static constexpr dart::compiler::target::word AOT_AbstractType_InstanceSize =
     24;
 static constexpr dart::compiler::target::word AOT_ApiError_InstanceSize = 16;
@@ -11681,9 +11681,9 @@
 static constexpr dart::compiler::target::word AOT_Array_header_size = 24;
 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 = 184;
+static constexpr dart::compiler::target::word AOT_Class_InstanceSize = 112;
 static constexpr dart::compiler::target::word AOT_Closure_InstanceSize = 56;
-static constexpr dart::compiler::target::word AOT_ClosureData_InstanceSize = 48;
+static constexpr dart::compiler::target::word AOT_ClosureData_InstanceSize = 32;
 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
@@ -11696,7 +11696,7 @@
 static constexpr dart::compiler::target::word AOT_DynamicLibrary_InstanceSize =
     16;
 static constexpr dart::compiler::target::word
-    AOT_ExceptionHandlers_InstanceSize = 24;
+    AOT_ExceptionHandlers_InstanceSize = 16;
 static constexpr dart::compiler::target::word
     AOT_ExternalOneByteString_InstanceSize = 32;
 static constexpr dart::compiler::target::word
@@ -11704,13 +11704,13 @@
 static constexpr dart::compiler::target::word
     AOT_ExternalTypedData_InstanceSize = 24;
 static constexpr dart::compiler::target::word
-    AOT_FfiTrampolineData_InstanceSize = 48;
-static constexpr dart::compiler::target::word AOT_Field_InstanceSize = 80;
+    AOT_FfiTrampolineData_InstanceSize = 32;
+static constexpr dart::compiler::target::word AOT_Field_InstanceSize = 56;
 static constexpr dart::compiler::target::word AOT_Float32x4_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_Float64x2_InstanceSize = 24;
-static constexpr dart::compiler::target::word AOT_Function_InstanceSize = 88;
+static constexpr dart::compiler::target::word AOT_Function_InstanceSize = 64;
 static constexpr dart::compiler::target::word AOT_FunctionType_InstanceSize =
-    72;
+    48;
 static constexpr dart::compiler::target::word AOT_FutureOr_InstanceSize = 16;
 static constexpr dart::compiler::target::word
     AOT_GrowableObjectArray_InstanceSize = 32;
@@ -11723,12 +11723,12 @@
 static constexpr dart::compiler::target::word AOT_Int32x4_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_Integer_InstanceSize = 8;
 static constexpr dart::compiler::target::word
-    AOT_KernelProgramInfo_InstanceSize = 120;
+    AOT_KernelProgramInfo_InstanceSize = 64;
 static constexpr dart::compiler::target::word AOT_LanguageError_InstanceSize =
-    48;
-static constexpr dart::compiler::target::word AOT_Library_InstanceSize = 152;
+    32;
+static constexpr dart::compiler::target::word AOT_Library_InstanceSize = 96;
 static constexpr dart::compiler::target::word AOT_LibraryPrefix_InstanceSize =
-    40;
+    24;
 static constexpr dart::compiler::target::word AOT_LinkedHashMap_InstanceSize =
     56;
 static constexpr dart::compiler::target::word
@@ -11740,7 +11740,7 @@
     16;
 static constexpr dart::compiler::target::word
     AOT_MonomorphicSmiableCall_InstanceSize = 32;
-static constexpr dart::compiler::target::word AOT_Namespace_InstanceSize = 40;
+static constexpr dart::compiler::target::word AOT_Namespace_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_NativeArguments_StructSize =
     32;
 static constexpr dart::compiler::target::word AOT_Number_InstanceSize = 8;
@@ -11748,55 +11748,55 @@
 static constexpr dart::compiler::target::word AOT_ObjectPool_InstanceSize = 16;
 static constexpr dart::compiler::target::word AOT_OneByteString_InstanceSize =
     16;
-static constexpr dart::compiler::target::word AOT_PatchClass_InstanceSize = 40;
+static constexpr dart::compiler::target::word AOT_PatchClass_InstanceSize = 24;
 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_RegExp_InstanceSize = 120;
-static constexpr dart::compiler::target::word AOT_Script_InstanceSize = 88;
+static constexpr dart::compiler::target::word AOT_ReceivePort_InstanceSize = 16;
+static constexpr dart::compiler::target::word AOT_RegExp_InstanceSize = 80;
+static constexpr dart::compiler::target::word AOT_Script_InstanceSize = 56;
 static constexpr dart::compiler::target::word AOT_SendPort_InstanceSize = 24;
 static constexpr dart::compiler::target::word
     AOT_SingleTargetCache_InstanceSize = 32;
 static constexpr dart::compiler::target::word AOT_Smi_InstanceSize = 8;
-static constexpr dart::compiler::target::word AOT_StackTrace_InstanceSize = 40;
+static constexpr dart::compiler::target::word AOT_StackTrace_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_String_InstanceSize = 16;
 static constexpr dart::compiler::target::word
     AOT_SubtypeTestCache_InstanceSize = 16;
-static constexpr dart::compiler::target::word AOT_LoadingUnit_InstanceSize = 32;
+static constexpr dart::compiler::target::word AOT_LoadingUnit_InstanceSize = 24;
 static constexpr dart::compiler::target::word
     AOT_TransferableTypedData_InstanceSize = 8;
 static constexpr dart::compiler::target::word AOT_TwoByteString_InstanceSize =
     16;
-static constexpr dart::compiler::target::word AOT_Type_InstanceSize = 56;
+static constexpr dart::compiler::target::word AOT_Type_InstanceSize = 40;
 static constexpr dart::compiler::target::word AOT_TypeArguments_InstanceSize =
     40;
 static constexpr dart::compiler::target::word AOT_TypeParameter_InstanceSize =
-    64;
-static constexpr dart::compiler::target::word AOT_TypeRef_InstanceSize = 32;
+    48;
+static constexpr dart::compiler::target::word AOT_TypeRef_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_TypedData_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_TypedDataBase_InstanceSize =
     24;
 static constexpr dart::compiler::target::word AOT_TypedDataView_InstanceSize =
-    40;
+    32;
 static constexpr dart::compiler::target::word
-    AOT_UnhandledException_InstanceSize = 24;
+    AOT_UnhandledException_InstanceSize = 16;
 static constexpr dart::compiler::target::word AOT_UnlinkedCall_InstanceSize =
     32;
-static constexpr dart::compiler::target::word AOT_UnwindError_InstanceSize = 24;
+static constexpr dart::compiler::target::word AOT_UnwindError_InstanceSize = 16;
 static constexpr dart::compiler::target::word AOT_UserTag_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_WeakProperty_InstanceSize =
     32;
 static constexpr dart::compiler::target::word
-    AOT_WeakSerializationReference_InstanceSize = 24;
+    AOT_WeakSerializationReference_InstanceSize = 16;
 #endif  // defined(TARGET_ARCH_X64) && defined(DART_COMPRESSED_POINTERS)
 
 #if defined(TARGET_ARCH_ARM64) && defined(DART_COMPRESSED_POINTERS)
 static constexpr dart::compiler::target::word
     AOT_ContextScope_elements_start_offset = 16;
 static constexpr dart::compiler::target::word AOT_ContextScope_element_size =
-    64;
+    32;
 static constexpr dart::compiler::target::word
-    AOT_ExceptionHandlers_elements_start_offset = 24;
+    AOT_ExceptionHandlers_elements_start_offset = 16;
 static constexpr dart::compiler::target::word
     AOT_ExceptionHandlers_element_size = 12;
 static constexpr dart::compiler::target::word
@@ -11868,12 +11868,12 @@
 static constexpr dart::compiler::target::word AOT_Array_type_arguments_offset =
     8;
 static constexpr dart::compiler::target::word
-    AOT_Class_declaration_type_offset = 104;
+    AOT_Class_declaration_type_offset = 56;
 static constexpr dart::compiler::target::word
-    AOT_Class_num_type_arguments_offset = 164;
-static constexpr dart::compiler::target::word AOT_Class_super_type_offset = 88;
+    AOT_Class_num_type_arguments_offset = 92;
+static constexpr dart::compiler::target::word AOT_Class_super_type_offset = 48;
 static constexpr dart::compiler::target::word
-    AOT_Class_host_type_arguments_field_offset_in_words_offset = 176;
+    AOT_Class_host_type_arguments_field_offset_in_words_offset = 104;
 static constexpr dart::compiler::target::word AOT_Closure_context_offset = 40;
 static constexpr dart::compiler::target::word
     AOT_Closure_delayed_type_arguments_offset = 24;
@@ -11884,9 +11884,9 @@
 static constexpr dart::compiler::target::word
     AOT_Closure_instantiator_type_arguments_offset = 8;
 static constexpr dart::compiler::target::word
-    AOT_ClosureData_default_type_arguments_offset = 32;
+    AOT_ClosureData_default_type_arguments_offset = 20;
 static constexpr dart::compiler::target::word
-    AOT_ClosureData_default_type_arguments_info_offset = 40;
+    AOT_ClosureData_default_type_arguments_kind_offset = 24;
 static constexpr dart::compiler::target::word AOT_Code_object_pool_offset = 40;
 static constexpr dart::compiler::target::word
     AOT_Code_saved_instructions_offset = 48;
@@ -11902,25 +11902,25 @@
 static constexpr dart::compiler::target::word AOT_Float32x4_value_offset = 8;
 static constexpr dart::compiler::target::word AOT_Float64x2_value_offset = 8;
 static constexpr dart::compiler::target::word
-    AOT_Field_initializer_function_offset = 32;
+    AOT_Field_initializer_function_offset = 20;
 static constexpr dart::compiler::target::word
-    AOT_Field_host_offset_or_field_id_offset = 40;
-static constexpr dart::compiler::target::word AOT_Field_guarded_cid_offset = 72;
+    AOT_Field_host_offset_or_field_id_offset = 24;
+static constexpr dart::compiler::target::word AOT_Field_guarded_cid_offset = 44;
 static constexpr dart::compiler::target::word
-    AOT_Field_guarded_list_length_in_object_offset_offset = 76;
+    AOT_Field_guarded_list_length_in_object_offset_offset = 48;
 static constexpr dart::compiler::target::word
-    AOT_Field_guarded_list_length_offset = 48;
-static constexpr dart::compiler::target::word AOT_Field_is_nullable_offset = 74;
-static constexpr dart::compiler::target::word AOT_Field_kind_bits_offset = 78;
-static constexpr dart::compiler::target::word AOT_Function_code_offset = 72;
-static constexpr dart::compiler::target::word AOT_Function_data_offset = 56;
+    AOT_Field_guarded_list_length_offset = 28;
+static constexpr dart::compiler::target::word AOT_Field_is_nullable_offset = 46;
+static constexpr dart::compiler::target::word AOT_Field_kind_bits_offset = 50;
+static constexpr dart::compiler::target::word AOT_Function_code_offset = 48;
+static constexpr dart::compiler::target::word AOT_Function_data_offset = 40;
 static constexpr dart::compiler::target::word
     AOT_Function_entry_point_offset[] = {8, 16};
-static constexpr dart::compiler::target::word AOT_Function_kind_tag_offset = 80;
+static constexpr dart::compiler::target::word AOT_Function_kind_tag_offset = 52;
 static constexpr dart::compiler::target::word
-    AOT_Function_packed_fields_offset = 84;
+    AOT_Function_packed_fields_offset = 56;
 static constexpr dart::compiler::target::word AOT_Function_signature_offset =
-    48;
+    36;
 static constexpr dart::compiler::target::word
     AOT_FutureOr_type_arguments_offset = 8;
 static constexpr dart::compiler::target::word
@@ -12015,9 +12015,9 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_AllocateArray_entry_point_offset = 728;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_exception_offset = 1464;
+    AOT_Thread_active_exception_offset = 1488;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_stacktrace_offset = 1472;
+    AOT_Thread_active_stacktrace_offset = 1496;
 static constexpr dart::compiler::target::word
     AOT_Thread_array_write_barrier_code_offset = 232;
 static constexpr dart::compiler::target::word
@@ -12043,7 +12043,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_allocate_object_slow_stub_offset = 384;
 static constexpr dart::compiler::target::word AOT_Thread_api_top_scope_offset =
-    1544;
+    1568;
 static constexpr dart::compiler::target::word
     AOT_Thread_auto_scope_native_wrapper_entry_point_offset = 656;
 static constexpr dart::compiler::target::word AOT_Thread_bool_false_offset =
@@ -12056,7 +12056,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_call_to_runtime_stub_offset = 264;
 static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset =
-    1560;
+    1584;
 static constexpr dart::compiler::target::word
     AOT_Thread_dispatch_table_array_offset = 96;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset =
@@ -12075,7 +12075,7 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_enter_safepoint_stub_offset = 488;
 static constexpr dart::compiler::target::word
-    AOT_Thread_execution_state_offset = 1504;
+    AOT_Thread_execution_state_offset = 1528;
 static constexpr dart::compiler::target::word
     AOT_Thread_exit_safepoint_stub_offset = 496;
 static constexpr dart::compiler::target::word
@@ -12095,14 +12095,14 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_float_zerow_address_offset = 720;
 static constexpr dart::compiler::target::word
-    AOT_Thread_global_object_pool_offset = 1480;
+    AOT_Thread_global_object_pool_offset = 1504;
 static constexpr dart::compiler::target::word
     AOT_Thread_invoke_dart_code_stub_offset = 256;
 static constexpr dart::compiler::target::word
-    AOT_Thread_exit_through_ffi_offset = 1536;
+    AOT_Thread_exit_through_ffi_offset = 1560;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 88;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_group_offset =
-    1568;
+    1592;
 static constexpr dart::compiler::target::word
     AOT_Thread_field_table_values_offset = 136;
 static constexpr dart::compiler::target::word
@@ -12147,11 +12147,11 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_predefined_symbols_address_offset = 664;
 static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset =
-    1488;
+    1512;
 static constexpr dart::compiler::target::word
-    AOT_Thread_saved_shadow_call_stack_offset = 1496;
+    AOT_Thread_saved_shadow_call_stack_offset = 1520;
 static constexpr dart::compiler::target::word
-    AOT_Thread_safepoint_state_offset = 1512;
+    AOT_Thread_safepoint_state_offset = 1536;
 static constexpr dart::compiler::target::word
     AOT_Thread_slow_type_test_stub_offset = 472;
 static constexpr dart::compiler::target::word
@@ -12188,34 +12188,34 @@
     AOT_Thread_write_barrier_mask_offset = 72;
 static constexpr dart::compiler::target::word AOT_Thread_heap_base_offset = 80;
 static constexpr dart::compiler::target::word AOT_Thread_callback_code_offset =
-    1520;
+    1544;
 static constexpr dart::compiler::target::word
-    AOT_Thread_callback_stack_return_offset = 1528;
+    AOT_Thread_callback_stack_return_offset = 1552;
 static constexpr dart::compiler::target::word
     AOT_TimelineStream_enabled_offset = 16;
 static constexpr dart::compiler::target::word AOT_TwoByteString_data_offset =
     16;
-static constexpr dart::compiler::target::word AOT_Type_arguments_offset = 32;
-static constexpr dart::compiler::target::word AOT_Type_hash_offset = 40;
+static constexpr dart::compiler::target::word AOT_Type_arguments_offset = 24;
+static constexpr dart::compiler::target::word AOT_Type_hash_offset = 28;
 static constexpr dart::compiler::target::word AOT_Type_type_class_id_offset =
-    24;
-static constexpr dart::compiler::target::word AOT_Type_type_state_offset = 48;
-static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 49;
-static constexpr dart::compiler::target::word AOT_FunctionType_hash_offset = 56;
+    20;
+static constexpr dart::compiler::target::word AOT_Type_type_state_offset = 32;
+static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 33;
+static constexpr dart::compiler::target::word AOT_FunctionType_hash_offset = 36;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_packed_fields_offset = 64;
+    AOT_FunctionType_packed_fields_offset = 40;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_parameter_types_offset = 40;
+    AOT_FunctionType_parameter_types_offset = 28;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_parameter_names_offset = 48;
+    AOT_FunctionType_parameter_names_offset = 32;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_type_parameters_offset = 24;
+    AOT_FunctionType_type_parameters_offset = 20;
 static constexpr dart::compiler::target::word
-    AOT_TypeParameter_parameterized_class_id_offset = 56;
+    AOT_TypeParameter_parameterized_class_id_offset = 36;
 static constexpr dart::compiler::target::word AOT_TypeParameter_index_offset =
-    60;
+    40;
 static constexpr dart::compiler::target::word
-    AOT_TypeParameter_nullability_offset = 63;
+    AOT_TypeParameter_nullability_offset = 43;
 static constexpr dart::compiler::target::word
     AOT_TypeArguments_instantiations_offset = 8;
 static constexpr dart::compiler::target::word AOT_TypeArguments_length_offset =
@@ -12225,23 +12225,23 @@
 static constexpr dart::compiler::target::word AOT_TypeArguments_types_offset =
     40;
 static constexpr dart::compiler::target::word AOT_TypeParameter_bound_offset =
-    40;
+    28;
 static constexpr dart::compiler::target::word AOT_TypeParameter_flags_offset =
-    62;
+    42;
 static constexpr dart::compiler::target::word AOT_TypeParameter_name_offset =
-    24;
-static constexpr dart::compiler::target::word AOT_TypeRef_type_offset = 24;
+    20;
+static constexpr dart::compiler::target::word AOT_TypeRef_type_offset = 20;
 static constexpr dart::compiler::target::word AOT_TypedDataBase_length_offset =
     16;
 static constexpr dart::compiler::target::word AOT_TypedDataView_data_offset =
-    24;
+    20;
 static constexpr dart::compiler::target::word
-    AOT_TypedDataView_offset_in_bytes_offset = 32;
+    AOT_TypedDataView_offset_in_bytes_offset = 24;
 static constexpr dart::compiler::target::word AOT_TypedData_data_offset = 24;
 static constexpr dart::compiler::target::word
     AOT_UnhandledException_exception_offset = 8;
 static constexpr dart::compiler::target::word
-    AOT_UnhandledException_stacktrace_offset = 16;
+    AOT_UnhandledException_stacktrace_offset = 12;
 static constexpr dart::compiler::target::word AOT_UserTag_tag_offset = 16;
 static constexpr dart::compiler::target::word
     AOT_MonomorphicSmiableCall_expected_cid_offset = 16;
@@ -12263,9 +12263,9 @@
     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,   -1,   1448, 1456, -1,   -1,   -1,   -1,   -1,   -1};
+        1336, 1344, 1352, 1360, 1368, 1376, 1384, 1392, 1400, 1408, 1416,
+        1424, 1432, 1440, 1448, -1,   -1,   -1,   -1,   1456, 1464, -1,
+        -1,   -1,   1472, 1480, -1,   -1,   -1,   -1,   -1,   -1};
 static constexpr dart::compiler::target::word AOT_AbstractType_InstanceSize =
     24;
 static constexpr dart::compiler::target::word AOT_ApiError_InstanceSize = 16;
@@ -12273,9 +12273,9 @@
 static constexpr dart::compiler::target::word AOT_Array_header_size = 24;
 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 = 184;
+static constexpr dart::compiler::target::word AOT_Class_InstanceSize = 112;
 static constexpr dart::compiler::target::word AOT_Closure_InstanceSize = 56;
-static constexpr dart::compiler::target::word AOT_ClosureData_InstanceSize = 48;
+static constexpr dart::compiler::target::word AOT_ClosureData_InstanceSize = 32;
 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
@@ -12288,7 +12288,7 @@
 static constexpr dart::compiler::target::word AOT_DynamicLibrary_InstanceSize =
     16;
 static constexpr dart::compiler::target::word
-    AOT_ExceptionHandlers_InstanceSize = 24;
+    AOT_ExceptionHandlers_InstanceSize = 16;
 static constexpr dart::compiler::target::word
     AOT_ExternalOneByteString_InstanceSize = 32;
 static constexpr dart::compiler::target::word
@@ -12296,13 +12296,13 @@
 static constexpr dart::compiler::target::word
     AOT_ExternalTypedData_InstanceSize = 24;
 static constexpr dart::compiler::target::word
-    AOT_FfiTrampolineData_InstanceSize = 48;
-static constexpr dart::compiler::target::word AOT_Field_InstanceSize = 80;
+    AOT_FfiTrampolineData_InstanceSize = 32;
+static constexpr dart::compiler::target::word AOT_Field_InstanceSize = 56;
 static constexpr dart::compiler::target::word AOT_Float32x4_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_Float64x2_InstanceSize = 24;
-static constexpr dart::compiler::target::word AOT_Function_InstanceSize = 88;
+static constexpr dart::compiler::target::word AOT_Function_InstanceSize = 64;
 static constexpr dart::compiler::target::word AOT_FunctionType_InstanceSize =
-    72;
+    48;
 static constexpr dart::compiler::target::word AOT_FutureOr_InstanceSize = 16;
 static constexpr dart::compiler::target::word
     AOT_GrowableObjectArray_InstanceSize = 32;
@@ -12315,12 +12315,12 @@
 static constexpr dart::compiler::target::word AOT_Int32x4_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_Integer_InstanceSize = 8;
 static constexpr dart::compiler::target::word
-    AOT_KernelProgramInfo_InstanceSize = 120;
+    AOT_KernelProgramInfo_InstanceSize = 64;
 static constexpr dart::compiler::target::word AOT_LanguageError_InstanceSize =
-    48;
-static constexpr dart::compiler::target::word AOT_Library_InstanceSize = 152;
+    32;
+static constexpr dart::compiler::target::word AOT_Library_InstanceSize = 96;
 static constexpr dart::compiler::target::word AOT_LibraryPrefix_InstanceSize =
-    40;
+    24;
 static constexpr dart::compiler::target::word AOT_LinkedHashMap_InstanceSize =
     56;
 static constexpr dart::compiler::target::word
@@ -12332,7 +12332,7 @@
     16;
 static constexpr dart::compiler::target::word
     AOT_MonomorphicSmiableCall_InstanceSize = 32;
-static constexpr dart::compiler::target::word AOT_Namespace_InstanceSize = 40;
+static constexpr dart::compiler::target::word AOT_Namespace_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_NativeArguments_StructSize =
     32;
 static constexpr dart::compiler::target::word AOT_Number_InstanceSize = 8;
@@ -12340,46 +12340,46 @@
 static constexpr dart::compiler::target::word AOT_ObjectPool_InstanceSize = 16;
 static constexpr dart::compiler::target::word AOT_OneByteString_InstanceSize =
     16;
-static constexpr dart::compiler::target::word AOT_PatchClass_InstanceSize = 40;
+static constexpr dart::compiler::target::word AOT_PatchClass_InstanceSize = 24;
 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_RegExp_InstanceSize = 120;
-static constexpr dart::compiler::target::word AOT_Script_InstanceSize = 88;
+static constexpr dart::compiler::target::word AOT_ReceivePort_InstanceSize = 16;
+static constexpr dart::compiler::target::word AOT_RegExp_InstanceSize = 80;
+static constexpr dart::compiler::target::word AOT_Script_InstanceSize = 56;
 static constexpr dart::compiler::target::word AOT_SendPort_InstanceSize = 24;
 static constexpr dart::compiler::target::word
     AOT_SingleTargetCache_InstanceSize = 32;
 static constexpr dart::compiler::target::word AOT_Smi_InstanceSize = 8;
-static constexpr dart::compiler::target::word AOT_StackTrace_InstanceSize = 40;
+static constexpr dart::compiler::target::word AOT_StackTrace_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_String_InstanceSize = 16;
 static constexpr dart::compiler::target::word
     AOT_SubtypeTestCache_InstanceSize = 16;
-static constexpr dart::compiler::target::word AOT_LoadingUnit_InstanceSize = 32;
+static constexpr dart::compiler::target::word AOT_LoadingUnit_InstanceSize = 24;
 static constexpr dart::compiler::target::word
     AOT_TransferableTypedData_InstanceSize = 8;
 static constexpr dart::compiler::target::word AOT_TwoByteString_InstanceSize =
     16;
-static constexpr dart::compiler::target::word AOT_Type_InstanceSize = 56;
+static constexpr dart::compiler::target::word AOT_Type_InstanceSize = 40;
 static constexpr dart::compiler::target::word AOT_TypeArguments_InstanceSize =
     40;
 static constexpr dart::compiler::target::word AOT_TypeParameter_InstanceSize =
-    64;
-static constexpr dart::compiler::target::word AOT_TypeRef_InstanceSize = 32;
+    48;
+static constexpr dart::compiler::target::word AOT_TypeRef_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_TypedData_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_TypedDataBase_InstanceSize =
     24;
 static constexpr dart::compiler::target::word AOT_TypedDataView_InstanceSize =
-    40;
+    32;
 static constexpr dart::compiler::target::word
-    AOT_UnhandledException_InstanceSize = 24;
+    AOT_UnhandledException_InstanceSize = 16;
 static constexpr dart::compiler::target::word AOT_UnlinkedCall_InstanceSize =
     32;
-static constexpr dart::compiler::target::word AOT_UnwindError_InstanceSize = 24;
+static constexpr dart::compiler::target::word AOT_UnwindError_InstanceSize = 16;
 static constexpr dart::compiler::target::word AOT_UserTag_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_WeakProperty_InstanceSize =
     32;
 static constexpr dart::compiler::target::word
-    AOT_WeakSerializationReference_InstanceSize = 24;
+    AOT_WeakSerializationReference_InstanceSize = 16;
 #endif  // defined(TARGET_ARCH_ARM64) && defined(DART_COMPRESSED_POINTERS)
 
 #endif  // !defined(PRODUCT)
diff --git a/runtime/vm/compiler/runtime_offsets_list.h b/runtime/vm/compiler/runtime_offsets_list.h
index e708265..d2dac49 100644
--- a/runtime/vm/compiler/runtime_offsets_list.h
+++ b/runtime/vm/compiler/runtime_offsets_list.h
@@ -89,7 +89,7 @@
   FIELD(Closure, hash_offset)                                                  \
   FIELD(Closure, instantiator_type_arguments_offset)                           \
   FIELD(ClosureData, default_type_arguments_offset)                            \
-  FIELD(ClosureData, default_type_arguments_info_offset)                       \
+  FIELD(ClosureData, default_type_arguments_kind_offset)                       \
   FIELD(Code, object_pool_offset)                                              \
   FIELD(Code, saved_instructions_offset)                                       \
   FIELD(Code, owner_offset)                                                    \
diff --git a/runtime/vm/compiler/stub_code_compiler.cc b/runtime/vm/compiler/stub_code_compiler.cc
index c4ed124..bbcdc8c 100644
--- a/runtime/vm/compiler/stub_code_compiler.cc
+++ b/runtime/vm/compiler/stub_code_compiler.cc
@@ -79,12 +79,12 @@
       InitInstanceFieldABI::kResultReg == CallingConventions::kReturnReg,
       "Result is a return value from initializer");
 
-  __ LoadField(kFunctionReg,
-               FieldAddress(InitInstanceFieldABI::kFieldReg,
-                            target::Field::initializer_function_offset()));
+  __ LoadCompressedFieldFromOffset(
+      kFunctionReg, InitInstanceFieldABI::kFieldReg,
+      target::Field::initializer_function_offset());
   if (!FLAG_precompiled_mode || !FLAG_use_bare_instructions) {
-    __ LoadField(CODE_REG,
-                 FieldAddress(kFunctionReg, target::Function::code_offset()));
+    __ LoadCompressedFieldFromOffset(CODE_REG, kFunctionReg,
+                                     target::Function::code_offset());
     // Load a GC-safe value for the arguments descriptor (unused but tagged).
     __ LoadImmediate(ARGS_DESC_REG, 0);
   }
@@ -92,9 +92,14 @@
   __ Drop(1);  // Drop argument.
 
   __ PopRegisterPair(kInstanceReg, kFieldReg);
-  __ LoadField(
-      kScratchReg,
-      FieldAddress(kFieldReg, target::Field::host_offset_or_field_id_offset()));
+  __ LoadCompressedFieldFromOffset(
+      kScratchReg, kFieldReg, target::Field::host_offset_or_field_id_offset());
+#if defined(DART_COMPRESSED_POINTERS)
+  // TODO(compressed-pointers): Variant of LoadFieldAddressForRegOffset that
+  // ignores upper bits?
+  __ SmiUntag(kScratchReg);
+  __ SmiTag(kScratchReg);
+#endif
   __ LoadFieldAddressForRegOffset(kAddressReg, kInstanceReg, kScratchReg);
 
   Label throw_exception;
@@ -179,6 +184,44 @@
   __ Ret();
 }
 
+void StubCodeCompiler::GenerateAssertAssignableStub(Assembler* assembler) {
+#if !defined(TARGET_ARCH_IA32)
+  __ Breakpoint();
+#else
+  __ EnterStubFrame();
+  __ PushObject(Object::null_object());  // Make room for the result.
+  __ pushl(Address(
+      EBP, target::kWordSize * AssertAssignableStubABI::kInstanceSlotFromFp));
+  __ pushl(Address(
+      EBP, target::kWordSize * AssertAssignableStubABI::kDstTypeSlotFromFp));
+  __ pushl(Address(
+      EBP,
+      target::kWordSize * AssertAssignableStubABI::kInstantiatorTAVSlotFromFp));
+  __ pushl(Address(EBP, target::kWordSize *
+                            AssertAssignableStubABI::kFunctionTAVSlotFromFp));
+  __ PushRegister(AssertAssignableStubABI::kDstNameReg);
+  __ PushRegister(AssertAssignableStubABI::kSubtypeTestReg);
+  __ PushObject(Smi::ZoneHandle(Smi::New(kTypeCheckFromInline)));
+  __ CallRuntime(kTypeCheckRuntimeEntry, /*argument_count=*/7);
+  __ Drop(8);
+  __ LeaveStubFrame();
+  __ Ret();
+#endif
+}
+
+void StubCodeCompiler::GenerateInstantiateTypeStub(Assembler* assembler) {
+  __ EnterStubFrame();
+  __ PushObject(Object::null_object());
+  __ PushRegister(InstantiateTypeABI::kTypeReg);
+  __ PushRegister(InstantiateTypeABI::kInstantiatorTypeArgumentsReg);
+  __ PushRegister(InstantiateTypeABI::kFunctionTypeArgumentsReg);
+  __ CallRuntime(kInstantiateTypeRuntimeEntry, /*argument_count=*/3);
+  __ Drop(3);
+  __ PopRegister(InstantiateTypeABI::kResultTypeReg);
+  __ LeaveStubFrame();
+  __ Ret();
+}
+
 void StubCodeCompiler::GenerateInstanceOfStub(Assembler* assembler) {
   __ EnterStubFrame();
   __ PushObject(NullObject());  // Make room for the result.
@@ -278,7 +321,7 @@
   // instantiation may result in a top type.
   // Function types cannot be top types.
   __ BranchIf(NOT_EQUAL, &done);
-  __ LoadField(
+  __ LoadCompressedField(
       scratch2_reg,
       compiler::FieldAddress(scratch1_reg,
                              compiler::target::Type::type_class_id_offset()));
@@ -308,9 +351,10 @@
   __ 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()));
+  __ LoadCompressedField(
+      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);
@@ -333,12 +377,14 @@
                                     /*null_safety=*/true);
 }
 
-// Version of Instance::NullIsAssignableTo() used when the destination type is
-// not known at compile time. Must be kept in sync.
+// Version of Instance::NullIsAssignableTo(other, inst_tav, fun_tav) used when
+// the destination type was not known at compile time. Must be kept in sync.
 //
 // Inputs:
 // - TypeTestABI::kInstanceReg: Object to check for assignability.
 // - TypeTestABI::kDstTypeReg: Destination type.
+// - TypeTestABI::kInstantiatorTypeArgumentsReg: Instantiator TAV.
+// - TypeTestABI::kFunctionTypeArgumentsReg: Function TAV.
 //
 // Non-preserved non-output scratch registers:
 // - TypeTestABI::kScratchReg (only on non-IA32 architectures)
@@ -353,85 +399,121 @@
   // 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;
+  // both use it as a scratch to hold the current type to inspect and also
+  // clobber it for the return value.
+  const Register kCurrentTypeReg = 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;
+  // always guaranteed to have a type in it (starting with the contents of
+  // kDstTypeReg), and all non-Smi ObjectPtrs are non-zero values.
+  const Register kOutputReg = kCurrentTypeReg;
 #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;
+  const Register kScratchReg = TypeTestABI::kFunctionTypeArgumentsReg;
   // Preserve non-output scratch registers.
-  __ PushRegister(scratch2_reg);
+  __ PushRegister(kScratchReg);
 #else
-  const Register scratch2_reg = TypeTestABI::kScratchReg;
+  const Register kScratchReg = TypeTestABI::kScratchReg;
 #endif
-  static_assert(scratch1_reg != scratch2_reg,
+  static_assert(kCurrentTypeReg != kScratchReg,
                 "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);
+  __ MoveRegister(kCurrentTypeReg, 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);
+    __ BranchIf(NOT_EQUAL, &done);
     __ Bind(&check_null_assignable);
     // scratch1_reg: Current type to check.
-    EnsureIsTypeOrFunctionTypeOrTypeParameter(assembler, scratch1_reg,
-                                              scratch2_reg);
+    EnsureIsTypeOrFunctionTypeOrTypeParameter(assembler, kCurrentTypeReg,
+                                              kScratchReg);
     compiler::Label is_not_type;
-    __ CompareClassId(scratch1_reg, kTypeCid, scratch2_reg);
+    __ CompareClassId(kCurrentTypeReg, kTypeCid, kScratchReg);
     __ 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);
+        kCurrentTypeReg, static_cast<int8_t>(Nullability::kNonNullable));
+    __ BranchIf(NOT_EQUAL, &is_assignable);
     // 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,
+    __ LoadCompressedField(
+        kScratchReg,
+        compiler::FieldAddress(kCurrentTypeReg,
                                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());
+    __ SmiUntag(kScratchReg);
+    __ CompareImmediate(kScratchReg, kFutureOrCid);
+    __ BranchIf(NOT_EQUAL, &done);
+    __ LoadCompressedField(
+        kScratchReg,
+        compiler::FieldAddress(kCurrentTypeReg,
+                               compiler::target::Type::arguments_offset()));
+    __ CompareObject(kScratchReg, 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);
+    __ BranchIf(EQUAL, &is_assignable);
     __ LoadField(
-        scratch1_reg,
+        kCurrentTypeReg,
         compiler::FieldAddress(
-            scratch2_reg, compiler::target::TypeArguments::type_at_offset(0)));
+            kScratchReg, 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.
+    // Null is assignable to a type parameter only if it is nullable or if the
+    // instantiation is nullable.
     __ LoadFieldFromOffset(
-        scratch2_reg, scratch1_reg,
+        kScratchReg, kCurrentTypeReg,
         compiler::target::TypeParameter::nullability_offset(), kByte);
-    __ CompareImmediate(scratch2_reg,
+    __ CompareImmediate(kScratchReg,
                         static_cast<int8_t>(Nullability::kNonNullable));
-    __ BranchIf(EQUAL, &done, compiler::Assembler::kNearJump);
+    __ BranchIf(NOT_EQUAL, &is_assignable);
+
+    // Don't set kScratchReg in here as on IA32, that's the function TAV reg.
+    auto handle_case = [&](Register tav) {
+      // We can reuse kCurrentTypeReg to hold the index because we no longer
+      // need the type parameter afterwards.
+      auto const kIndexReg = kCurrentTypeReg;
+      // If the TAV is null, resolving gives the (nullable) dynamic type.
+      __ CompareObject(tav, NullObject());
+      __ BranchIf(EQUAL, &is_assignable, Assembler::kNearJump);
+      // Resolve the type parameter to its instantiated type and loop.
+      __ LoadFieldFromOffset(kIndexReg, kCurrentTypeReg,
+                             target::TypeParameter::index_offset(), kTwoBytes);
+      __ LoadIndexedPayload(kCurrentTypeReg, tav,
+                            target::TypeArguments::types_offset(), kIndexReg,
+                            TIMES_WORD_SIZE);
+      __ Jump(&check_null_assignable);
+    };
+
+    Label function_type_param;
+    __ LoadFieldFromOffset(
+        kScratchReg, kCurrentTypeReg,
+        target::TypeParameter::parameterized_class_id_offset(),
+        kUnsignedTwoBytes);
+    __ CompareImmediate(kScratchReg, kFunctionCid);
+    __ BranchIf(EQUAL, &function_type_param, Assembler::kNearJump);
+    handle_case(TypeTestABI::kInstantiatorTypeArgumentsReg);
+    __ Bind(&function_type_param);
+#if defined(TARGET_ARCH_IA32)
+    // Function TAV is on top of stack because we're using that register as
+    // kScratchReg.
+    __ LoadFromStack(TypeTestABI::kFunctionTypeArgumentsReg, 0);
+#endif
+    handle_case(TypeTestABI::kFunctionTypeArgumentsReg);
   } else {
     // Null in non-null-safe mode is always assignable.
     __ BranchIf(NOT_EQUAL, &done, compiler::Assembler::kNearJump);
   }
   __ Bind(&is_assignable);
-  __ LoadImmediate(output_reg, 0);
+  __ LoadImmediate(kOutputReg, 0);
   __ Bind(&done);
 #if defined(TARGET_ARCH_IA32)
   // Restore preserved scratch registers.
-  __ PopRegister(scratch2_reg);
+  __ PopRegister(kScratchReg);
 #endif
   __ Ret();
 }
diff --git a/runtime/vm/compiler/stub_code_compiler_arm.cc b/runtime/vm/compiler/stub_code_compiler_arm.cc
index dc9b44c..515e680 100644
--- a/runtime/vm/compiler/stub_code_compiler_arm.cc
+++ b/runtime/vm/compiler/stub_code_compiler_arm.cc
@@ -487,7 +487,9 @@
 void StubCodeCompiler::GenerateDispatchTableNullErrorStub(
     Assembler* assembler) {
   __ EnterStubFrame();
-  __ CallRuntime(kNullErrorRuntimeEntry, /*argument_count=*/0);
+  __ SmiTag(DispatchTableNullErrorABI::kClassIdReg);
+  __ PushRegister(DispatchTableNullErrorABI::kClassIdReg);
+  __ CallRuntime(kDispatchTableNullErrorRuntimeEntry, /*argument_count=*/1);
   // The NullError runtime entry does not return.
   __ Breakpoint();
 }
@@ -1002,7 +1004,7 @@
 //   R2: array length as Smi (must be preserved).
 // The newly allocated object is returned in R0.
 void StubCodeCompiler::GenerateAllocateArrayStub(Assembler* assembler) {
-  if (!FLAG_use_slow_path) {
+  if (!FLAG_use_slow_path && FLAG_inline_alloc) {
     Label slow_case;
     // Compute the size to be allocated, it is based on the array length
     // and is computed as:
@@ -1125,7 +1127,7 @@
 void StubCodeCompiler::GenerateAllocateMintSharedWithFPURegsStub(
     Assembler* assembler) {
   // For test purpose call allocation stub without inline allocation attempt.
-  if (!FLAG_use_slow_path) {
+  if (!FLAG_use_slow_path && FLAG_inline_alloc) {
     Label slow_case;
     __ TryAllocate(compiler::MintClass(), &slow_case,
                    AllocateMintABI::kResultReg, AllocateMintABI::kTempReg);
@@ -1146,7 +1148,7 @@
 void StubCodeCompiler::GenerateAllocateMintSharedWithoutFPURegsStub(
     Assembler* assembler) {
   // For test purpose call allocation stub without inline allocation attempt.
-  if (!FLAG_use_slow_path) {
+  if (!FLAG_use_slow_path && FLAG_inline_alloc) {
     Label slow_case;
     __ TryAllocate(compiler::MintClass(), &slow_case,
                    AllocateMintABI::kResultReg, AllocateMintABI::kTempReg);
@@ -1439,7 +1441,7 @@
 // Clobbered:
 //   Potentially any since it can go to runtime.
 void StubCodeCompiler::GenerateCloneContextStub(Assembler* assembler) {
-  {
+  if (!FLAG_use_slow_path && FLAG_inline_alloc) {
     Label slow_case;
 
     // Load num. variable in the existing context.
@@ -3430,91 +3432,95 @@
   COMPILE_ASSERT(AllocateTypedDataArrayABI::kLengthReg == R4);
   COMPILE_ASSERT(AllocateTypedDataArrayABI::kResultReg == R0);
 
-  Label call_runtime;
-  NOT_IN_PRODUCT(__ LoadAllocationStatsAddress(R2, cid));
-  NOT_IN_PRODUCT(__ MaybeTraceAllocation(R2, &call_runtime));
-  __ mov(R2, Operand(AllocateTypedDataArrayABI::kLengthReg));
-  /* Check that length is a positive Smi. */
-  /* R2: requested array length argument. */
-  __ tst(R2, Operand(kSmiTagMask));
-  __ b(&call_runtime, NE);
-  __ SmiUntag(R2);
-  /* Check for length >= 0 && length <= max_len. */
-  /* R2: untagged array length. */
-  __ CompareImmediate(R2, max_len);
-  __ b(&call_runtime, HI);
-  __ mov(R2, Operand(R2, LSL, scale_shift));
-  const intptr_t fixed_size_plus_alignment_padding =
-      target::TypedData::InstanceSize() +
-      target::ObjectAlignment::kObjectAlignment - 1;
-  __ AddImmediate(R2, fixed_size_plus_alignment_padding);
-  __ bic(R2, R2, Operand(target::ObjectAlignment::kObjectAlignment - 1));
-  __ ldr(R0, Address(THR, target::Thread::top_offset()));
+  if (!FLAG_use_slow_path && FLAG_inline_alloc) {
+    Label call_runtime;
+    NOT_IN_PRODUCT(__ LoadAllocationStatsAddress(R2, cid));
+    NOT_IN_PRODUCT(__ MaybeTraceAllocation(R2, &call_runtime));
+    __ mov(R2, Operand(AllocateTypedDataArrayABI::kLengthReg));
+    /* Check that length is a positive Smi. */
+    /* R2: requested array length argument. */
+    __ tst(R2, Operand(kSmiTagMask));
+    __ b(&call_runtime, NE);
+    __ SmiUntag(R2);
+    /* Check for length >= 0 && length <= max_len. */
+    /* R2: untagged array length. */
+    __ CompareImmediate(R2, max_len);
+    __ b(&call_runtime, HI);
+    __ mov(R2, Operand(R2, LSL, scale_shift));
+    const intptr_t fixed_size_plus_alignment_padding =
+        target::TypedData::InstanceSize() +
+        target::ObjectAlignment::kObjectAlignment - 1;
+    __ AddImmediate(R2, fixed_size_plus_alignment_padding);
+    __ bic(R2, R2, Operand(target::ObjectAlignment::kObjectAlignment - 1));
+    __ ldr(R0, Address(THR, target::Thread::top_offset()));
 
-  /* R2: allocation size. */
-  __ adds(R1, R0, Operand(R2));
-  __ b(&call_runtime, CS); /* Fail on unsigned overflow. */
+    /* R2: allocation size. */
+    __ adds(R1, R0, Operand(R2));
+    __ b(&call_runtime, CS); /* Fail on unsigned overflow. */
 
-  /* Check if the allocation fits into the remaining space. */
-  /* R0: potential new object start. */
-  /* R1: potential next object start. */
-  /* R2: allocation size. */
-  __ ldr(IP, Address(THR, target::Thread::end_offset()));
-  __ cmp(R1, Operand(IP));
-  __ b(&call_runtime, CS);
+    /* Check if the allocation fits into the remaining space. */
+    /* R0: potential new object start. */
+    /* R1: potential next object start. */
+    /* R2: allocation size. */
+    __ ldr(IP, Address(THR, target::Thread::end_offset()));
+    __ cmp(R1, Operand(IP));
+    __ b(&call_runtime, CS);
 
-  __ str(R1, Address(THR, target::Thread::top_offset()));
-  __ AddImmediate(R0, kHeapObjectTag);
-  /* Initialize the tags. */
-  /* R0: new object start as a tagged pointer. */
-  /* R1: new object end address. */
-  /* R2: allocation size. */
-  {
-    __ CompareImmediate(R2, target::UntaggedObject::kSizeTagMaxSizeTag);
+    __ str(R1, Address(THR, target::Thread::top_offset()));
+    __ AddImmediate(R0, kHeapObjectTag);
+    /* Initialize the tags. */
+    /* R0: new object start as a tagged pointer. */
+    /* R1: new object end address. */
+    /* R2: allocation size. */
+    {
+      __ CompareImmediate(R2, target::UntaggedObject::kSizeTagMaxSizeTag);
+      __ mov(R3,
+             Operand(R2, LSL,
+                     target::UntaggedObject::kTagBitsSizeTagPos -
+                         target::ObjectAlignment::kObjectAlignmentLog2),
+             LS);
+      __ mov(R3, Operand(0), HI);
+
+      /* Get the class index and insert it into the tags. */
+      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. */
+    }
+    /* Set the length field. */
+    /* R0: new object start as a tagged pointer. */
+    /* R1: new object end address. */
+    /* R2: allocation size. */
     __ mov(R3,
-           Operand(R2, LSL,
-                   target::UntaggedObject::kTagBitsSizeTagPos -
-                       target::ObjectAlignment::kObjectAlignmentLog2),
-           LS);
-    __ mov(R3, Operand(0), HI);
+           Operand(AllocateTypedDataArrayABI::kLengthReg)); /* Array length. */
+    __ StoreIntoObjectNoBarrier(
+        R0, FieldAddress(R0, target::TypedDataBase::length_offset()), R3);
+    /* Initialize all array elements to 0. */
+    /* R0: new object start as a tagged pointer. */
+    /* R1: new object end address. */
+    /* R2: allocation size. */
+    /* R3: iterator which initially points to the start of the variable */
+    /* R8, R9: zero. */
+    /* data area to be initialized. */
+    __ LoadImmediate(R8, 0);
+    __ mov(R9, Operand(R8));
+    __ AddImmediate(R3, R0, target::TypedData::InstanceSize() - 1);
+    __ StoreInternalPointer(
+        R0, FieldAddress(R0, target::TypedDataBase::data_field_offset()), R3);
+    Label init_loop;
+    __ Bind(&init_loop);
+    __ AddImmediate(R3, 2 * target::kWordSize);
+    __ cmp(R3, Operand(R1));
+    __ strd(R8, R9, R3, -2 * target::kWordSize, LS);
+    __ b(&init_loop, CC);
+    __ str(R8, Address(R3, -2 * target::kWordSize), HI);
 
-    /* Get the class index and insert it into the tags. */
-    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. */
+    __ Ret();
+
+    __ Bind(&call_runtime);
   }
-  /* Set the length field. */
-  /* R0: new object start as a tagged pointer. */
-  /* R1: new object end address. */
-  /* R2: allocation size. */
-  __ mov(R3,
-         Operand(AllocateTypedDataArrayABI::kLengthReg)); /* Array length. */
-  __ StoreIntoObjectNoBarrier(
-      R0, FieldAddress(R0, target::TypedDataBase::length_offset()), R3);
-  /* Initialize all array elements to 0. */
-  /* R0: new object start as a tagged pointer. */
-  /* R1: new object end address. */
-  /* R2: allocation size. */
-  /* R3: iterator which initially points to the start of the variable */
-  /* R8, R9: zero. */
-  /* data area to be initialized. */
-  __ LoadImmediate(R8, 0);
-  __ mov(R9, Operand(R8));
-  __ AddImmediate(R3, R0, target::TypedData::InstanceSize() - 1);
-  __ StoreInternalPointer(
-      R0, FieldAddress(R0, target::TypedDataBase::data_field_offset()), R3);
-  Label init_loop;
-  __ Bind(&init_loop);
-  __ AddImmediate(R3, 2 * target::kWordSize);
-  __ cmp(R3, Operand(R1));
-  __ strd(R8, R9, R3, -2 * target::kWordSize, LS);
-  __ b(&init_loop, CC);
-  __ str(R8, Address(R3, -2 * target::kWordSize), HI);
 
-  __ Ret();
-
-  __ Bind(&call_runtime);
   __ EnterStubFrame();
   __ PushObject(Object::null_object());            // Make room for the result.
   __ PushImmediate(target::ToRawSmi(cid));         // Cid
diff --git a/runtime/vm/compiler/stub_code_compiler_arm64.cc b/runtime/vm/compiler/stub_code_compiler_arm64.cc
index 022ba2c..bc5eb6a 100644
--- a/runtime/vm/compiler/stub_code_compiler_arm64.cc
+++ b/runtime/vm/compiler/stub_code_compiler_arm64.cc
@@ -545,7 +545,9 @@
 void StubCodeCompiler::GenerateDispatchTableNullErrorStub(
     Assembler* assembler) {
   __ EnterStubFrame();
-  __ CallRuntime(kNullErrorRuntimeEntry, /*argument_count=*/0);
+  __ SmiTag(DispatchTableNullErrorABI::kClassIdReg);
+  __ PushRegister(DispatchTableNullErrorABI::kClassIdReg);
+  __ CallRuntime(kDispatchTableNullErrorRuntimeEntry, /*argument_count=*/1);
   // The NullError runtime entry does not return.
   __ Breakpoint();
 }
@@ -1122,7 +1124,7 @@
 // NOTE: R2 cannot be clobbered here as the caller relies on it being saved.
 // The newly allocated object is returned in R0.
 void StubCodeCompiler::GenerateAllocateArrayStub(Assembler* assembler) {
-  if (!FLAG_use_slow_path) {
+  if (!FLAG_use_slow_path && FLAG_inline_alloc) {
     Label slow_case;
     // Compute the size to be allocated, it is based on the array length
     // and is computed as:
@@ -1134,7 +1136,7 @@
     // Check length >= 0 && length <= kMaxNewSpaceElements
     const intptr_t max_len =
         target::ToRawSmi(target::Array::kMaxNewSpaceElements);
-    __ CompareImmediate(R2, max_len);
+    __ CompareImmediate(R2, max_len, kObjectBytes);
     __ b(&slow_case, HI);
 
     const intptr_t cid = kArrayCid;
@@ -1149,7 +1151,7 @@
         target::Array::header_size() +
         target::ObjectAlignment::kObjectAlignment - 1;
     __ LoadImmediate(R3, fixed_size_plus_alignment_padding);
-    __ add(R3, R3, Operand(R2, LSL, 2));  // R2 is Smi.
+    __ add(R3, R3, Operand(R2, LSL, 2), kObjectBytes);  // R2 is Smi.
     ASSERT(kSmiTagShift == 1);
     __ andi(R3, R3,
             Immediate(~(target::ObjectAlignment::kObjectAlignment - 1)));
@@ -1262,7 +1264,7 @@
 void StubCodeCompiler::GenerateAllocateMintSharedWithFPURegsStub(
     Assembler* assembler) {
   // For test purpose call allocation stub without inline allocation attempt.
-  if (!FLAG_use_slow_path) {
+  if (!FLAG_use_slow_path && FLAG_inline_alloc) {
     Label slow_case;
     __ TryAllocate(compiler::MintClass(), &slow_case,
                    AllocateMintABI::kResultReg, AllocateMintABI::kTempReg);
@@ -1282,7 +1284,7 @@
 void StubCodeCompiler::GenerateAllocateMintSharedWithoutFPURegsStub(
     Assembler* assembler) {
   // For test purpose call allocation stub without inline allocation attempt.
-  if (!FLAG_use_slow_path) {
+  if (!FLAG_use_slow_path && FLAG_inline_alloc) {
     Label slow_case;
     __ TryAllocate(compiler::MintClass(), &slow_case,
                    AllocateMintABI::kResultReg, AllocateMintABI::kTempReg);
@@ -1585,7 +1587,7 @@
 // Clobbered:
 //   R1, (R2), R3, R4, (TMP)
 void StubCodeCompiler::GenerateCloneContextStub(Assembler* assembler) {
-  {
+  if (!FLAG_use_slow_path && FLAG_inline_alloc) {
     Label slow_case;
 
     // Load num. variable (int32) in the existing context.
@@ -2177,25 +2179,19 @@
   __ BranchIfNotSmi(TMP, not_smi_or_overflow);
   switch (kind) {
     case Token::kADD: {
-#if !defined(DART_COMPRESSED_POINTERS)
-      __ adds(R0, R1, Operand(R0));   // Add.
+      __ adds(R0, R1, Operand(R0), kObjectBytes);  // Add.
       __ b(not_smi_or_overflow, VS);  // Branch if overflow.
-#else
-      __ addsw(R0, R1, Operand(R0));  // Add (32-bit).
-      __ b(not_smi_or_overflow, VS);  // Branch if overflow.
-      __ sxtw(R0, R0);                // Sign extend.
-#endif
       break;
     }
     case Token::kLT: {
-      __ CompareRegisters(R0, R1);
+      __ CompareObjectRegisters(R0, R1);
       __ LoadObject(R0, CastHandle<Object>(TrueObject()));
       __ LoadObject(R1, CastHandle<Object>(FalseObject()));
       __ csel(R0, R0, R1, LT);
       break;
     }
     case Token::kEQ: {
-      __ CompareRegisters(R0, R1);
+      __ CompareObjectRegisters(R0, R1);
       __ LoadObject(R0, CastHandle<Object>(TrueObject()));
       __ LoadObject(R1, CastHandle<Object>(FalseObject()));
       __ csel(R0, R0, R1, EQ);
@@ -2472,7 +2468,8 @@
   __ Comment("Call target");
   __ Bind(&call_target_function);
   // R0: target function.
-  __ LoadFieldFromOffset(CODE_REG, R0, target::Function::code_offset());
+  __ LoadCompressedFieldFromOffset(CODE_REG, R0,
+                                   target::Function::code_offset());
   if (save_entry_point) {
     __ add(R2, R0, Operand(R8));
     __ ldr(R2, Address(R2, 0));
@@ -2653,7 +2650,8 @@
 
   // Get function and call it, if possible.
   __ LoadFromOffset(R0, R6, target_offset);
-  __ LoadFieldFromOffset(CODE_REG, R0, target::Function::code_offset());
+  __ LoadCompressedFieldFromOffset(CODE_REG, R0,
+                                   target::Function::code_offset());
   __ add(R2, R0, Operand(R8));
   __ ldr(R2, Address(R2, 0));
   __ br(R2);
@@ -2707,7 +2705,8 @@
   __ Pop(R4);  // Restore arg desc.
   __ LeaveStubFrame();
 
-  __ LoadFieldFromOffset(CODE_REG, R0, target::Function::code_offset());
+  __ LoadCompressedFieldFromOffset(CODE_REG, R0,
+                                   target::Function::code_offset());
   __ LoadFieldFromOffset(R2, R0, target::Function::entry_point_offset());
   __ br(R2);
 }
@@ -3107,7 +3106,8 @@
   __ Pop(R0);  // Discard argument.
   __ Pop(R0);  // Get Function object
   __ Pop(R4);  // Restore argument descriptor.
-  __ LoadFieldFromOffset(CODE_REG, R0, target::Function::code_offset());
+  __ LoadCompressedFieldFromOffset(CODE_REG, R0,
+                                   target::Function::code_offset());
   __ LoadFieldFromOffset(R1, R0, target::Function::entry_point_offset());
   __ LeaveStubFrame();
   __ br(R1);
@@ -3136,7 +3136,8 @@
   // Double values bitwise compare.
   __ LoadFieldFromOffset(left, left, target::Double::value_offset());
   __ LoadFieldFromOffset(right, right, target::Double::value_offset());
-  __ b(&reference_compare);
+  __ CompareRegisters(left, right);
+  __ b(&done);
 
   __ Bind(&check_mint);
   __ CompareClassId(left, kMintCid);
@@ -3145,9 +3146,11 @@
   __ b(&done, NE);
   __ LoadFieldFromOffset(left, left, target::Mint::value_offset());
   __ LoadFieldFromOffset(right, right, target::Mint::value_offset());
+  __ CompareRegisters(left, right);
+  __ b(&done);
 
   __ Bind(&reference_compare);
-  __ CompareRegisters(left, right);
+  __ CompareObjectRegisters(left, right);
   __ Bind(&done);
 }
 
@@ -3264,7 +3267,8 @@
     __ ldr(
         ARGS_DESC_REG,
         FieldAddress(R5, target::CallSiteData::arguments_descriptor_offset()));
-    __ ldr(CODE_REG, FieldAddress(R0, target::Function::code_offset()));
+    __ LoadCompressed(CODE_REG,
+                      FieldAddress(R0, target::Function::code_offset()));
   }
   __ br(R1);
 
@@ -3575,86 +3579,91 @@
   COMPILE_ASSERT(AllocateTypedDataArrayABI::kLengthReg == R4);
   COMPILE_ASSERT(AllocateTypedDataArrayABI::kResultReg == R0);
 
-  Label call_runtime;
-  NOT_IN_PRODUCT(__ MaybeTraceAllocation(cid, R2, &call_runtime));
-  __ mov(R2, AllocateTypedDataArrayABI::kLengthReg);
-  /* Check that length is a positive Smi. */
-  /* R2: requested array length argument. */
-  __ BranchIfNotSmi(R2, &call_runtime);
-  __ SmiUntag(R2);
-  /* Check for length >= 0 && length <= max_len. */
-  /* R2: untagged array length. */
-  __ CompareImmediate(R2, max_len);
-  __ b(&call_runtime, HI);
-  __ LslImmediate(R2, R2, scale_shift);
-  const intptr_t fixed_size_plus_alignment_padding =
-      target::TypedData::InstanceSize() +
-      target::ObjectAlignment::kObjectAlignment - 1;
-  __ AddImmediate(R2, fixed_size_plus_alignment_padding);
-  __ andi(R2, R2, Immediate(~(target::ObjectAlignment::kObjectAlignment - 1)));
-  __ ldr(R0, Address(THR, target::Thread::top_offset()));
+  if (!FLAG_use_slow_path && FLAG_inline_alloc) {
+    Label call_runtime;
+    NOT_IN_PRODUCT(__ MaybeTraceAllocation(cid, R2, &call_runtime));
+    __ mov(R2, AllocateTypedDataArrayABI::kLengthReg);
+    /* Check that length is a positive Smi. */
+    /* R2: requested array length argument. */
+    __ BranchIfNotSmi(R2, &call_runtime);
+    __ SmiUntag(R2);
+    /* Check for length >= 0 && length <= max_len. */
+    /* R2: untagged array length. */
+    __ CompareImmediate(R2, max_len, kObjectBytes);
+    __ b(&call_runtime, HI);
+    __ LslImmediate(R2, R2, scale_shift);
+    const intptr_t fixed_size_plus_alignment_padding =
+        target::TypedData::InstanceSize() +
+        target::ObjectAlignment::kObjectAlignment - 1;
+    __ AddImmediate(R2, fixed_size_plus_alignment_padding);
+    __ andi(R2, R2,
+            Immediate(~(target::ObjectAlignment::kObjectAlignment - 1)));
+    __ ldr(R0, Address(THR, target::Thread::top_offset()));
 
-  /* R2: allocation size. */
-  __ adds(R1, R0, Operand(R2));
-  __ b(&call_runtime, CS); /* Fail on unsigned overflow. */
+    /* R2: allocation size. */
+    __ adds(R1, R0, Operand(R2));
+    __ b(&call_runtime, CS); /* Fail on unsigned overflow. */
 
-  /* Check if the allocation fits into the remaining space. */
-  /* R0: potential new object start. */
-  /* R1: potential next object start. */
-  /* R2: allocation size. */
-  __ ldr(R6, Address(THR, target::Thread::end_offset()));
-  __ cmp(R1, Operand(R6));
-  __ b(&call_runtime, CS);
+    /* Check if the allocation fits into the remaining space. */
+    /* R0: potential new object start. */
+    /* R1: potential next object start. */
+    /* R2: allocation size. */
+    __ ldr(R6, Address(THR, target::Thread::end_offset()));
+    __ cmp(R1, Operand(R6));
+    __ b(&call_runtime, CS);
 
-  /* Successfully allocated the object(s), now update top to point to */
-  /* next object start and initialize the object. */
-  __ str(R1, Address(THR, target::Thread::top_offset()));
-  __ AddImmediate(R0, kHeapObjectTag);
-  /* Initialize the tags. */
-  /* R0: new object start as a tagged pointer. */
-  /* R1: new object end address. */
-  /* R2: allocation size. */
-  {
-    __ CompareImmediate(R2, target::UntaggedObject::kSizeTagMaxSizeTag);
-    __ LslImmediate(R2, R2,
-                    target::UntaggedObject::kTagBitsSizeTagPos -
-                        target::ObjectAlignment::kObjectAlignmentLog2);
-    __ csel(R2, ZR, R2, HI);
+    /* Successfully allocated the object(s), now update top to point to */
+    /* next object start and initialize the object. */
+    __ str(R1, Address(THR, target::Thread::top_offset()));
+    __ AddImmediate(R0, kHeapObjectTag);
+    /* Initialize the tags. */
+    /* R0: new object start as a tagged pointer. */
+    /* R1: new object end address. */
+    /* R2: allocation size. */
+    {
+      __ CompareImmediate(R2, target::UntaggedObject::kSizeTagMaxSizeTag);
+      __ LslImmediate(R2, R2,
+                      target::UntaggedObject::kTagBitsSizeTagPos -
+                          target::ObjectAlignment::kObjectAlignmentLog2);
+      __ csel(R2, ZR, R2, HI);
 
-    /* Get the class index and insert it into the tags. */
-    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. */
+      /* Get the class index and insert it into the tags. */
+      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. */
+    }
+    /* Set the length field. */
+    /* R0: new object start as a tagged pointer. */
+    /* R1: new object end address. */
+    __ mov(R2, AllocateTypedDataArrayABI::kLengthReg); /* Array length. */
+    __ StoreCompressedIntoObjectNoBarrier(
+        R0, FieldAddress(R0, target::TypedDataBase::length_offset()), R2);
+    /* Initialize all array elements to 0. */
+    /* R0: new object start as a tagged pointer. */
+    /* R1: new object end address. */
+    /* R2: iterator which initially points to the start of the variable */
+    /* R3: scratch register. */
+    /* data area to be initialized. */
+    __ mov(R3, ZR);
+    __ AddImmediate(R2, R0, target::TypedData::InstanceSize() - 1);
+    __ StoreInternalPointer(
+        R0, FieldAddress(R0, target::TypedDataBase::data_field_offset()), R2);
+    Label init_loop, done;
+    __ Bind(&init_loop);
+    __ cmp(R2, Operand(R1));
+    __ b(&done, CS);
+    __ str(R3, Address(R2, 0));
+    __ add(R2, R2, Operand(target::kWordSize));
+    __ b(&init_loop);
+    __ Bind(&done);
+
+    __ Ret();
+
+    __ Bind(&call_runtime);
   }
-  /* Set the length field. */
-  /* R0: new object start as a tagged pointer. */
-  /* R1: new object end address. */
-  __ mov(R2, AllocateTypedDataArrayABI::kLengthReg); /* Array length. */
-  __ StoreIntoObjectNoBarrier(
-      R0, FieldAddress(R0, target::TypedDataBase::length_offset()), R2);
-  /* Initialize all array elements to 0. */
-  /* R0: new object start as a tagged pointer. */
-  /* R1: new object end address. */
-  /* R2: iterator which initially points to the start of the variable */
-  /* R3: scratch register. */
-  /* data area to be initialized. */
-  __ mov(R3, ZR);
-  __ AddImmediate(R2, R0, target::TypedData::InstanceSize() - 1);
-  __ StoreInternalPointer(
-      R0, FieldAddress(R0, target::TypedDataBase::data_field_offset()), R2);
-  Label init_loop, done;
-  __ Bind(&init_loop);
-  __ cmp(R2, Operand(R1));
-  __ b(&done, CS);
-  __ str(R3, Address(R2, 0));
-  __ add(R2, R2, Operand(target::kWordSize));
-  __ b(&init_loop);
-  __ Bind(&done);
 
-  __ Ret();
-
-  __ Bind(&call_runtime);
   __ EnterStubFrame();
   __ Push(ZR);                                     // Result slot.
   __ PushImmediate(target::ToRawSmi(cid));         // Cid
diff --git a/runtime/vm/compiler/stub_code_compiler_ia32.cc b/runtime/vm/compiler/stub_code_compiler_ia32.cc
index 5c780a3..2286706 100644
--- a/runtime/vm/compiler/stub_code_compiler_ia32.cc
+++ b/runtime/vm/compiler/stub_code_compiler_ia32.cc
@@ -804,7 +804,7 @@
 // Uses EAX, EBX, ECX, EDI  as temporary registers.
 // The newly allocated object is returned in EAX.
 void StubCodeCompiler::GenerateAllocateArrayStub(Assembler* assembler) {
-  if (!FLAG_use_slow_path) {
+  if (!FLAG_use_slow_path && FLAG_inline_alloc) {
     Label slow_case;
     // Compute the size to be allocated, it is based on the array length
     // and is computed as:
@@ -1223,7 +1223,7 @@
 // Clobbered:
 //   EBX, ECX, EDX
 void StubCodeCompiler::GenerateCloneContextStub(Assembler* assembler) {
-  {
+  if (!FLAG_use_slow_path && FLAG_inline_alloc) {
     Label slow_case;
 
     // Load num. variable in the existing context.
@@ -2923,108 +2923,114 @@
   COMPILE_ASSERT(AllocateTypedDataArrayABI::kLengthReg == EAX);
   COMPILE_ASSERT(AllocateTypedDataArrayABI::kResultReg == EAX);
 
-  // Save length argument for possible runtime call, as
-  // EAX is clobbered.
-  Label call_runtime;
-  __ pushl(AllocateTypedDataArrayABI::kLengthReg);
+  if (!FLAG_use_slow_path && FLAG_inline_alloc) {
+    // Save length argument for possible runtime call, as
+    // EAX is clobbered.
+    Label call_runtime;
+    __ pushl(AllocateTypedDataArrayABI::kLengthReg);
 
-  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. */
-  __ testl(EDI, Immediate(kSmiTagMask));
-  __ j(NOT_ZERO, &call_runtime);
-  __ SmiUntag(EDI);
-  /* Check for length >= 0 && length <= max_len. */
-  /* EDI: untagged array length. */
-  __ cmpl(EDI, Immediate(max_len));
-  __ j(ABOVE, &call_runtime);
-  /* Special case for scaling by 16. */
-  if (scale_factor == TIMES_16) {
-    /* double length of array. */
-    __ addl(EDI, EDI);
-    /* only scale by 8. */
-    scale_factor = TIMES_8;
-  }
+    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. */
+    __ testl(EDI, Immediate(kSmiTagMask));
+    __ j(NOT_ZERO, &call_runtime);
+    __ SmiUntag(EDI);
+    /* Check for length >= 0 && length <= max_len. */
+    /* EDI: untagged array length. */
+    __ cmpl(EDI, Immediate(max_len));
+    __ j(ABOVE, &call_runtime);
+    /* Special case for scaling by 16. */
+    if (scale_factor == TIMES_16) {
+      /* double length of array. */
+      __ addl(EDI, EDI);
+      /* only scale by 8. */
+      scale_factor = TIMES_8;
+    }
 
-  const intptr_t fixed_size_plus_alignment_padding =
-      target::TypedData::InstanceSize() +
-      target::ObjectAlignment::kObjectAlignment - 1;
-  __ leal(EDI, Address(EDI, scale_factor, fixed_size_plus_alignment_padding));
-  __ andl(EDI, Immediate(-target::ObjectAlignment::kObjectAlignment));
-  __ movl(EAX, Address(THR, target::Thread::top_offset()));
-  __ movl(EBX, EAX);
-  /* EDI: allocation size. */
-  __ addl(EBX, EDI);
-  __ j(CARRY, &call_runtime);
+    const intptr_t fixed_size_plus_alignment_padding =
+        target::TypedData::InstanceSize() +
+        target::ObjectAlignment::kObjectAlignment - 1;
+    __ leal(EDI, Address(EDI, scale_factor, fixed_size_plus_alignment_padding));
+    __ andl(EDI, Immediate(-target::ObjectAlignment::kObjectAlignment));
+    __ movl(EAX, Address(THR, target::Thread::top_offset()));
+    __ movl(EBX, EAX);
+    /* EDI: allocation size. */
+    __ addl(EBX, EDI);
+    __ j(CARRY, &call_runtime);
 
-  /* Check if the allocation fits into the remaining space. */
-  /* EAX: potential new object start. */
-  /* EBX: potential next object start. */
-  /* EDI: allocation size. */
-  __ cmpl(EBX, Address(THR, target::Thread::end_offset()));
-  __ j(ABOVE_EQUAL, &call_runtime);
+    /* Check if the allocation fits into the remaining space. */
+    /* EAX: potential new object start. */
+    /* EBX: potential next object start. */
+    /* EDI: allocation size. */
+    __ cmpl(EBX, Address(THR, target::Thread::end_offset()));
+    __ j(ABOVE_EQUAL, &call_runtime);
 
-  /* Successfully allocated the object(s), now update top to point to */
-  /* next object start and initialize the object. */
-  __ movl(Address(THR, target::Thread::top_offset()), EBX);
-  __ addl(EAX, Immediate(kHeapObjectTag));
+    /* Successfully allocated the object(s), now update top to point to */
+    /* next object start and initialize the object. */
+    __ movl(Address(THR, target::Thread::top_offset()), EBX);
+    __ addl(EAX, Immediate(kHeapObjectTag));
 
-  /* Initialize the tags. */
-  /* EAX: new object start as a tagged pointer. */
-  /* EBX: new object end address. */
-  /* EDI: allocation size. */
-  {
-    Label size_tag_overflow, done;
-    __ cmpl(EDI, Immediate(target::UntaggedObject::kSizeTagMaxSizeTag));
-    __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump);
-    __ shll(EDI, Immediate(target::UntaggedObject::kTagBitsSizeTagPos -
-                           target::ObjectAlignment::kObjectAlignmentLog2));
-    __ jmp(&done, Assembler::kNearJump);
-    __ Bind(&size_tag_overflow);
-    __ movl(EDI, Immediate(0));
+    /* Initialize the tags. */
+    /* EAX: new object start as a tagged pointer. */
+    /* EBX: new object end address. */
+    /* EDI: allocation size. */
+    {
+      Label size_tag_overflow, done;
+      __ cmpl(EDI, Immediate(target::UntaggedObject::kSizeTagMaxSizeTag));
+      __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump);
+      __ shll(EDI, Immediate(target::UntaggedObject::kTagBitsSizeTagPos -
+                             target::ObjectAlignment::kObjectAlignmentLog2));
+      __ jmp(&done, Assembler::kNearJump);
+      __ Bind(&size_tag_overflow);
+      __ movl(EDI, Immediate(0));
+      __ Bind(&done);
+      /* Get the class index and insert it into the tags. */
+      uword tags =
+          target::MakeTagWordForNewSpaceObject(cid, /*instance_size=*/0);
+      __ orl(EDI, Immediate(tags));
+      __ movl(FieldAddress(EAX, target::Object::tags_offset()),
+              EDI); /* Tags. */
+    }
+
+    /* Set the length field. */
+    /* EAX: new object start as a tagged pointer. */
+    /* EBX: new object end address. */
+    __ popl(EDI); /* Array length. */
+    __ StoreIntoObjectNoBarrier(
+        EAX, FieldAddress(EAX, target::TypedDataBase::length_offset()), EDI);
+
+    /* Initialize all array elements to 0. */
+    /* EAX: new object start as a tagged pointer. */
+    /* EBX: new object end address. */
+    /* EDI: iterator which initially points to the start of the variable */
+    /* ECX: scratch register. */
+    /* data area to be initialized. */
+    __ xorl(ECX, ECX); /* Zero. */
+    __ leal(EDI, FieldAddress(EAX, target::TypedData::InstanceSize()));
+    __ StoreInternalPointer(
+        EAX, FieldAddress(EAX, target::TypedDataBase::data_field_offset()),
+        EDI);
+    Label done, init_loop;
+    __ Bind(&init_loop);
+    __ cmpl(EDI, EBX);
+    __ j(ABOVE_EQUAL, &done, Assembler::kNearJump);
+    __ movl(Address(EDI, 0), ECX);
+    __ addl(EDI, Immediate(target::kWordSize));
+    __ jmp(&init_loop, Assembler::kNearJump);
     __ Bind(&done);
-    /* Get the class index and insert it into the tags. */
-    uword tags = target::MakeTagWordForNewSpaceObject(cid, /*instance_size=*/0);
-    __ orl(EDI, Immediate(tags));
-    __ movl(FieldAddress(EAX, target::Object::tags_offset()), EDI); /* Tags. */
+
+    __ ret();
+
+    __ Bind(&call_runtime);
+    __ popl(AllocateTypedDataArrayABI::kLengthReg);
   }
 
-  /* Set the length field. */
-  /* EAX: new object start as a tagged pointer. */
-  /* EBX: new object end address. */
-  __ popl(EDI); /* Array length. */
-  __ StoreIntoObjectNoBarrier(
-      EAX, FieldAddress(EAX, target::TypedDataBase::length_offset()), EDI);
-
-  /* Initialize all array elements to 0. */
-  /* EAX: new object start as a tagged pointer. */
-  /* EBX: new object end address. */
-  /* EDI: iterator which initially points to the start of the variable */
-  /* ECX: scratch register. */
-  /* data area to be initialized. */
-  __ xorl(ECX, ECX); /* Zero. */
-  __ leal(EDI, FieldAddress(EAX, target::TypedData::InstanceSize()));
-  __ StoreInternalPointer(
-      EAX, FieldAddress(EAX, target::TypedDataBase::data_field_offset()), EDI);
-  Label done, init_loop;
-  __ Bind(&init_loop);
-  __ cmpl(EDI, EBX);
-  __ j(ABOVE_EQUAL, &done, Assembler::kNearJump);
-  __ movl(Address(EDI, 0), ECX);
-  __ addl(EDI, Immediate(target::kWordSize));
-  __ jmp(&init_loop, Assembler::kNearJump);
-  __ Bind(&done);
-
-  __ ret();
-
-  __ Bind(&call_runtime);
-  __ popl(EDI);  // Array length
   __ EnterStubFrame();
   __ PushObject(Object::null_object());  // Make room for the result.
   __ pushl(Immediate(target::ToRawSmi(cid)));
-  __ pushl(EDI);  // Array length
+  __ pushl(AllocateTypedDataArrayABI::kLengthReg);
   __ CallRuntime(kAllocateTypedDataRuntimeEntry, 2);
   __ Drop(2);  // Drop arguments.
   __ popl(AllocateTypedDataArrayABI::kResultReg);
diff --git a/runtime/vm/compiler/stub_code_compiler_x64.cc b/runtime/vm/compiler/stub_code_compiler_x64.cc
index 93bd854c6..8d2987a 100644
--- a/runtime/vm/compiler/stub_code_compiler_x64.cc
+++ b/runtime/vm/compiler/stub_code_compiler_x64.cc
@@ -488,7 +488,9 @@
 void StubCodeCompiler::GenerateDispatchTableNullErrorStub(
     Assembler* assembler) {
   __ EnterStubFrame();
-  __ CallRuntime(kNullErrorRuntimeEntry, /*argument_count=*/0);
+  __ SmiTag(DispatchTableNullErrorABI::kClassIdReg);
+  __ PushRegister(DispatchTableNullErrorABI::kClassIdReg);
+  __ CallRuntime(kDispatchTableNullErrorRuntimeEntry, /*argument_count=*/1);
   // The NullError runtime entry does not return.
   __ Breakpoint();
 }
@@ -1053,7 +1055,7 @@
 // NOTE: R10 cannot be clobbered here as the caller relies on it being saved.
 // The newly allocated object is returned in RAX.
 void StubCodeCompiler::GenerateAllocateArrayStub(Assembler* assembler) {
-  if (!FLAG_use_slow_path) {
+  if (!FLAG_use_slow_path && FLAG_inline_alloc) {
     Label slow_case;
     // Compute the size to be allocated, it is based on the array length
     // and is computed as:
@@ -1067,7 +1069,7 @@
     // Check length >= 0 && length <= kMaxNewSpaceElements
     const Immediate& max_len =
         Immediate(target::ToRawSmi(target::Array::kMaxNewSpaceElements));
-    __ cmpq(RDI, max_len);
+    __ OBJ(cmp)(RDI, max_len);
     __ j(ABOVE, &slow_case);
 
     // Check for allocation tracing.
@@ -1078,7 +1080,7 @@
         target::Array::header_size() +
         target::ObjectAlignment::kObjectAlignment - 1;
     // RDI is a Smi.
-    __ leaq(RDI, Address(RDI, TIMES_4, fixed_size_plus_alignment_padding));
+    __ OBJ(lea)(RDI, Address(RDI, TIMES_4, fixed_size_plus_alignment_padding));
     ASSERT(kSmiTagShift == 1);
     __ andq(RDI, Immediate(-target::ObjectAlignment::kObjectAlignment));
 
@@ -1185,7 +1187,7 @@
 void StubCodeCompiler::GenerateAllocateMintSharedWithFPURegsStub(
     Assembler* assembler) {
   // For test purpose call allocation stub without inline allocation attempt.
-  if (!FLAG_use_slow_path) {
+  if (!FLAG_use_slow_path && FLAG_inline_alloc) {
     Label slow_case;
     __ TryAllocate(compiler::MintClass(), &slow_case, Assembler::kNearJump,
                    AllocateMintABI::kResultReg, AllocateMintABI::kTempReg);
@@ -1205,7 +1207,7 @@
 void StubCodeCompiler::GenerateAllocateMintSharedWithoutFPURegsStub(
     Assembler* assembler) {
   // For test purpose call allocation stub without inline allocation attempt.
-  if (!FLAG_use_slow_path) {
+  if (!FLAG_use_slow_path && FLAG_inline_alloc) {
     Label slow_case;
     __ TryAllocate(compiler::MintClass(), &slow_case, Assembler::kNearJump,
                    AllocateMintABI::kResultReg, AllocateMintABI::kTempReg);
@@ -1528,7 +1530,7 @@
 // Clobbered:
 //   R10, R13
 void StubCodeCompiler::GenerateCloneContextStub(Assembler* assembler) {
-  {
+  if (!FLAG_use_slow_path && FLAG_inline_alloc) {
     Label slow_case;
 
     // Load num. variable (int32_t) in the existing context.
@@ -2106,18 +2108,12 @@
   __ j(NOT_ZERO, not_smi_or_overflow);
   switch (kind) {
     case Token::kADD: {
-#if !defined(DART_COMPRESSED_POINTERS)
-      __ addq(RAX, RCX);
+      __ OBJ(add)(RAX, RCX);
       __ j(OVERFLOW, not_smi_or_overflow);
-#else
-      __ addl(RAX, RCX);
-      __ j(OVERFLOW, not_smi_or_overflow);
-      __ movsxd(RAX, RAX);
-#endif
       break;
     }
     case Token::kLT: {
-      __ cmpq(RAX, RCX);
+      __ OBJ(cmp)(RAX, RCX);
       __ setcc(GREATER_EQUAL, ByteRegisterOf(RAX));
       __ movzxb(RAX, RAX);  // RAX := RAX < RCX ? 0 : 1
       __ movq(RAX,
@@ -2127,7 +2123,7 @@
       break;
     }
     case Token::kEQ: {
-      __ cmpq(RAX, RCX);
+      __ OBJ(cmp)(RAX, RCX);
       __ setcc(NOT_EQUAL, ByteRegisterOf(RAX));
       __ movzxb(RAX, RAX);  // RAX := RAX == RCX ? 0 : 1
       __ movq(RAX,
@@ -2384,7 +2380,7 @@
     // because we only emit calls to this stub when it is not null.
     __ movq(RCX,
             FieldAddress(RBX, target::ICData::receivers_static_type_offset()));
-    __ movq(RCX, FieldAddress(RCX, target::Type::arguments_offset()));
+    __ LoadCompressed(RCX, FieldAddress(RCX, target::Type::arguments_offset()));
     // RAX contains an offset to type arguments in words as a smi,
     // hence TIMES_4. RDX is guaranteed to be non-smi because it is expected
     // to have type arguments.
@@ -2408,7 +2404,8 @@
   __ Comment("Call target (via specified entry point)");
   __ Bind(&call_target_function);
   // RAX: Target function.
-  __ movq(CODE_REG, FieldAddress(RAX, target::Function::code_offset()));
+  __ LoadCompressed(CODE_REG,
+                    FieldAddress(RAX, target::Function::code_offset()));
   if (save_entry_point) {
     __ addq(R8, RAX);
     __ jmp(Address(R8, 0));
@@ -2425,7 +2422,8 @@
     }
     __ Comment("Call target (via unchecked entry point)");
     __ movq(RAX, Address(R13, target_offset));
-    __ movq(CODE_REG, FieldAddress(RAX, target::Function::code_offset()));
+    __ LoadCompressed(CODE_REG,
+                      FieldAddress(RAX, target::Function::code_offset()));
     __ jmp(FieldAddress(
         RAX, target::Function::entry_point_offset(CodeEntryKind::kUnchecked)));
   }
@@ -2606,7 +2604,8 @@
 
   // Get function and call it, if possible.
   __ movq(RAX, Address(R12, target_offset));
-  __ movq(CODE_REG, FieldAddress(RAX, target::Function::code_offset()));
+  __ LoadCompressed(CODE_REG,
+                    FieldAddress(RAX, target::Function::code_offset()));
 
   __ addq(R8, RAX);
   __ jmp(Address(R8, 0));
@@ -2657,7 +2656,8 @@
   __ popq(R10);  // Restore arguments descriptor array.
   __ LeaveStubFrame();
 
-  __ movq(CODE_REG, FieldAddress(RAX, target::Function::code_offset()));
+  __ LoadCompressed(CODE_REG,
+                    FieldAddress(RAX, target::Function::code_offset()));
   __ movq(RCX, FieldAddress(RAX, target::Function::entry_point_offset()));
   __ jmp(RCX);
 }
@@ -3060,7 +3060,8 @@
   __ popq(RAX);  // Get Code object.
   __ popq(R10);  // Restore argument descriptor.
   __ LeaveStubFrame();
-  __ movq(CODE_REG, FieldAddress(RAX, target::Function::code_offset()));
+  __ LoadCompressed(CODE_REG,
+                    FieldAddress(RAX, target::Function::code_offset()));
   __ movq(RCX, FieldAddress(RAX, target::Function::entry_point_offset()));
   __ jmp(RCX);
   __ int3();
@@ -3102,7 +3103,7 @@
   __ jmp(&done, Assembler::kFarJump);
 
   __ Bind(&reference_compare);
-  __ cmpq(left, right);
+  __ CompareObjectRegisters(left, right);
   __ Bind(&done);
 }
 
@@ -3216,7 +3217,8 @@
     __ movq(R10, FieldAddress(
                      RBX, target::CallSiteData::arguments_descriptor_offset()));
     __ movq(RCX, FieldAddress(RAX, target::Function::entry_point_offset()));
-    __ movq(CODE_REG, FieldAddress(RAX, target::Function::code_offset()));
+    __ LoadCompressed(CODE_REG,
+                      FieldAddress(RAX, target::Function::code_offset()));
     __ jmp(RCX);
   }
 
@@ -3515,108 +3517,114 @@
   COMPILE_ASSERT(AllocateTypedDataArrayABI::kLengthReg == RAX);
   COMPILE_ASSERT(AllocateTypedDataArrayABI::kResultReg == RAX);
 
-  // Save length argument for possible runtime call, as
-  // RAX is clobbered.
-  Label call_runtime;
-  __ pushq(AllocateTypedDataArrayABI::kLengthReg);
+  if (!FLAG_use_slow_path && FLAG_inline_alloc) {
+    // Save length argument for possible runtime call, as
+    // RAX is clobbered.
+    Label call_runtime;
+    __ pushq(AllocateTypedDataArrayABI::kLengthReg);
 
-  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. */
-  __ testq(RDI, Immediate(kSmiTagMask));
-  __ j(NOT_ZERO, &call_runtime);
-  __ SmiUntag(RDI);
-  /* Check for length >= 0 && length <= max_len. */
-  /* RDI: untagged array length. */
-  __ cmpq(RDI, Immediate(max_len));
-  __ j(ABOVE, &call_runtime);
-  /* Special case for scaling by 16. */
-  if (scale_factor == TIMES_16) {
-    /* double length of array. */
-    __ addq(RDI, RDI);
-    /* only scale by 8. */
-    scale_factor = TIMES_8;
-  }
-  const intptr_t fixed_size_plus_alignment_padding =
-      target::TypedData::InstanceSize() +
-      target::ObjectAlignment::kObjectAlignment - 1;
-  __ leaq(RDI, Address(RDI, scale_factor, fixed_size_plus_alignment_padding));
-  __ andq(RDI, Immediate(-target::ObjectAlignment::kObjectAlignment));
-  __ movq(RAX, Address(THR, target::Thread::top_offset()));
-  __ movq(RCX, RAX);
+    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. */
+    __ testq(RDI, Immediate(kSmiTagMask));
+    __ j(NOT_ZERO, &call_runtime);
+    __ SmiUntag(RDI);
+    /* Check for length >= 0 && length <= max_len. */
+    /* RDI: untagged array length. */
+    __ cmpq(RDI, Immediate(max_len));
+    __ j(ABOVE, &call_runtime);
+    /* Special case for scaling by 16. */
+    if (scale_factor == TIMES_16) {
+      /* double length of array. */
+      __ addq(RDI, RDI);
+      /* only scale by 8. */
+      scale_factor = TIMES_8;
+    }
+    const intptr_t fixed_size_plus_alignment_padding =
+        target::TypedData::InstanceSize() +
+        target::ObjectAlignment::kObjectAlignment - 1;
+    __ leaq(RDI, Address(RDI, scale_factor, fixed_size_plus_alignment_padding));
+    __ andq(RDI, Immediate(-target::ObjectAlignment::kObjectAlignment));
+    __ movq(RAX, Address(THR, target::Thread::top_offset()));
+    __ movq(RCX, RAX);
 
-  /* RDI: allocation size. */
-  __ addq(RCX, RDI);
-  __ j(CARRY, &call_runtime);
+    /* RDI: allocation size. */
+    __ addq(RCX, RDI);
+    __ j(CARRY, &call_runtime);
 
-  /* Check if the allocation fits into the remaining space. */
-  /* RAX: potential new object start. */
-  /* RCX: potential next object start. */
-  /* RDI: allocation size. */
-  __ cmpq(RCX, Address(THR, target::Thread::end_offset()));
-  __ j(ABOVE_EQUAL, &call_runtime);
+    /* Check if the allocation fits into the remaining space. */
+    /* RAX: potential new object start. */
+    /* RCX: potential next object start. */
+    /* RDI: allocation size. */
+    __ cmpq(RCX, Address(THR, target::Thread::end_offset()));
+    __ j(ABOVE_EQUAL, &call_runtime);
 
-  /* Successfully allocated the object(s), now update top to point to */
-  /* next object start and initialize the object. */
-  __ movq(Address(THR, target::Thread::top_offset()), RCX);
-  __ addq(RAX, Immediate(kHeapObjectTag));
-  /* Initialize the tags. */
-  /* RAX: new object start as a tagged pointer. */
-  /* RCX: new object end address. */
-  /* RDI: allocation size. */
-  /* R13: scratch register. */
-  {
-    Label size_tag_overflow, done;
-    __ cmpq(RDI, Immediate(target::UntaggedObject::kSizeTagMaxSizeTag));
-    __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump);
-    __ shlq(RDI, Immediate(target::UntaggedObject::kTagBitsSizeTagPos -
-                           target::ObjectAlignment::kObjectAlignmentLog2));
-    __ jmp(&done, Assembler::kNearJump);
+    /* Successfully allocated the object(s), now update top to point to */
+    /* next object start and initialize the object. */
+    __ movq(Address(THR, target::Thread::top_offset()), RCX);
+    __ addq(RAX, Immediate(kHeapObjectTag));
+    /* Initialize the tags. */
+    /* RAX: new object start as a tagged pointer. */
+    /* RCX: new object end address. */
+    /* RDI: allocation size. */
+    /* R13: scratch register. */
+    {
+      Label size_tag_overflow, done;
+      __ cmpq(RDI, Immediate(target::UntaggedObject::kSizeTagMaxSizeTag));
+      __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump);
+      __ shlq(RDI, Immediate(target::UntaggedObject::kTagBitsSizeTagPos -
+                             target::ObjectAlignment::kObjectAlignmentLog2));
+      __ jmp(&done, Assembler::kNearJump);
 
-    __ Bind(&size_tag_overflow);
-    __ LoadImmediate(RDI, Immediate(0));
+      __ Bind(&size_tag_overflow);
+      __ LoadImmediate(RDI, Immediate(0));
+      __ Bind(&done);
+
+      /* Get the class index and insert it into the tags. */
+      uword tags =
+          target::MakeTagWordForNewSpaceObject(cid, /*instance_size=*/0);
+      __ orq(RDI, Immediate(tags));
+      __ movq(FieldAddress(RAX, target::Object::tags_offset()),
+              RDI); /* Tags. */
+    }
+    /* Set the length field. */
+    /* RAX: new object start as a tagged pointer. */
+    /* RCX: new object end address. */
+    __ popq(RDI); /* Array length. */
+    __ StoreCompressedIntoObjectNoBarrier(
+        RAX, FieldAddress(RAX, target::TypedDataBase::length_offset()), RDI);
+    /* Initialize all array elements to 0. */
+    /* RAX: new object start as a tagged pointer. */
+    /* RCX: new object end address. */
+    /* RDI: iterator which initially points to the start of the variable */
+    /* RBX: scratch register. */
+    /* data area to be initialized. */
+    __ xorq(RBX, RBX); /* Zero. */
+    __ leaq(RDI, FieldAddress(RAX, target::TypedData::InstanceSize()));
+    __ StoreInternalPointer(
+        RAX, FieldAddress(RAX, target::TypedDataBase::data_field_offset()),
+        RDI);
+    Label done, init_loop;
+    __ Bind(&init_loop);
+    __ cmpq(RDI, RCX);
+    __ j(ABOVE_EQUAL, &done, Assembler::kNearJump);
+    __ movq(Address(RDI, 0), RBX);
+    __ addq(RDI, Immediate(target::kWordSize));
+    __ jmp(&init_loop, Assembler::kNearJump);
     __ Bind(&done);
 
-    /* Get the class index and insert it into the tags. */
-    uword tags = target::MakeTagWordForNewSpaceObject(cid, /*instance_size=*/0);
-    __ orq(RDI, Immediate(tags));
-    __ movq(FieldAddress(RAX, target::Object::tags_offset()), RDI); /* Tags. */
+    __ ret();
+
+    __ Bind(&call_runtime);
+    __ popq(AllocateTypedDataArrayABI::kLengthReg);
   }
-  /* Set the length field. */
-  /* RAX: new object start as a tagged pointer. */
-  /* RCX: new object end address. */
-  __ popq(RDI); /* Array length. */
-  __ StoreIntoObjectNoBarrier(
-      RAX, FieldAddress(RAX, target::TypedDataBase::length_offset()), RDI);
-  /* Initialize all array elements to 0. */
-  /* RAX: new object start as a tagged pointer. */
-  /* RCX: new object end address. */
-  /* RDI: iterator which initially points to the start of the variable */
-  /* RBX: scratch register. */
-  /* data area to be initialized. */
-  __ xorq(RBX, RBX); /* Zero. */
-  __ leaq(RDI, FieldAddress(RAX, target::TypedData::InstanceSize()));
-  __ StoreInternalPointer(
-      RAX, FieldAddress(RAX, target::TypedDataBase::data_field_offset()), RDI);
-  Label done, init_loop;
-  __ Bind(&init_loop);
-  __ cmpq(RDI, RCX);
-  __ j(ABOVE_EQUAL, &done, Assembler::kNearJump);
-  __ movq(Address(RDI, 0), RBX);
-  __ addq(RDI, Immediate(target::kWordSize));
-  __ jmp(&init_loop, Assembler::kNearJump);
-  __ Bind(&done);
 
-  __ ret();
-
-  __ Bind(&call_runtime);
-  __ popq(RDI);  // Array length
   __ EnterStubFrame();
   __ PushObject(Object::null_object());  // Make room for the result.
   __ PushImmediate(Immediate(target::ToRawSmi(cid)));
-  __ pushq(RDI);  // Array length
+  __ pushq(AllocateTypedDataArrayABI::kLengthReg);
   __ CallRuntime(kAllocateTypedDataRuntimeEntry, 2);
   __ Drop(2);  // Drop arguments.
   __ popq(AllocateTypedDataArrayABI::kResultReg);
diff --git a/runtime/vm/constants.h b/runtime/vm/constants.h
index 01d9d08..00e3f9b 100644
--- a/runtime/vm/constants.h
+++ b/runtime/vm/constants.h
@@ -19,6 +19,20 @@
 
 namespace dart {
 
+// An architecture independent ABI for the InstantiateType stub.
+//
+// We re-use registers from another ABI to avoid duplicating this ABI across 4
+// architectures.
+struct InstantiateTypeABI {
+  static const Register kTypeReg =
+      InstantiationABI::kUninstantiatedTypeArgumentsReg;
+  static const Register kInstantiatorTypeArgumentsReg =
+      InstantiationABI::kInstantiatorTypeArgumentsReg;
+  static const Register kFunctionTypeArgumentsReg =
+      InstantiationABI::kFunctionTypeArgumentsReg;
+  static const Register kResultTypeReg = InstantiationABI::kResultTypeReg;
+};
+
 class RegisterNames {
  public:
   static const char* RegisterName(Register reg) {
diff --git a/runtime/vm/constants_arm.h b/runtime/vm/constants_arm.h
index 82ccda5..1b7fe4c 100644
--- a/runtime/vm/constants_arm.h
+++ b/runtime/vm/constants_arm.h
@@ -463,6 +463,14 @@
   static const Register kResultReg = R0;
 };
 
+// ABI for DispatchTableNullErrorStub and consequently for all dispatch
+// table calls (though normal functions will not expect or use this
+// register). This ABI is added to distinguish memory corruption errors from
+// null errors.
+struct DispatchTableNullErrorABI {
+  static const Register kClassIdReg = R0;
+};
+
 // TODO(regis): Add ABIs for type testing stubs and is-type test stubs instead
 // of reusing the constants of the instantiation stubs ABI.
 
diff --git a/runtime/vm/constants_arm64.h b/runtime/vm/constants_arm64.h
index 16af371..a596a10 100644
--- a/runtime/vm/constants_arm64.h
+++ b/runtime/vm/constants_arm64.h
@@ -304,6 +304,14 @@
   static const Register kResultReg = R0;
 };
 
+// ABI for DispatchTableNullErrorStub and consequently for all dispatch
+// table calls (though normal functions will not expect or use this
+// register). This ABI is added to distinguish memory corruption errors from
+// null errors.
+struct DispatchTableNullErrorABI {
+  static const Register kClassIdReg = R0;
+};
+
 // TODO(regis): Add ABIs for type testing stubs and is-type test stubs instead
 // of reusing the constants of the instantiation stubs ABI.
 
diff --git a/runtime/vm/constants_ia32.h b/runtime/vm/constants_ia32.h
index da4d058..a8baa9d 100644
--- a/runtime/vm/constants_ia32.h
+++ b/runtime/vm/constants_ia32.h
@@ -138,6 +138,17 @@
   // (throws if the subtype check fails).
 };
 
+// For calling the ia32-specific AssertAssignableStub
+struct AssertAssignableStubABI {
+  static const Register kDstNameReg = EBX;
+  static const Register kSubtypeTestReg = ECX;
+
+  static const intptr_t kInstanceSlotFromFp = 2 + 3;
+  static const intptr_t kDstTypeSlotFromFp = 2 + 2;
+  static const intptr_t kInstantiatorTAVSlotFromFp = 2 + 1;
+  static const intptr_t kFunctionTAVSlotFromFp = 2 + 0;
+};
+
 // ABI for InitStaticFieldStub.
 struct InitStaticFieldABI {
   static const Register kFieldReg = EAX;
@@ -191,6 +202,16 @@
   static const Register kResultReg = EAX;
 };
 
+// ABI for DispatchTableNullErrorStub and consequently for all dispatch
+// table calls (though normal functions will not expect or use this
+// register). This ABI is added to distinguish memory corruption errors from
+// null errors.
+// Note: dispatch table calls are never actually generated on IA32, this
+// declaration is only added for completeness.
+struct DispatchTableNullErrorABI {
+  static const Register kClassIdReg = EAX;
+};
+
 typedef uint32_t RegList;
 const RegList kAllCpuRegistersList = 0xFF;
 
diff --git a/runtime/vm/constants_x64.h b/runtime/vm/constants_x64.h
index d8ffa7c..e5f647e 100644
--- a/runtime/vm/constants_x64.h
+++ b/runtime/vm/constants_x64.h
@@ -275,6 +275,14 @@
   static const Register kResultReg = RAX;
 };
 
+// ABI for DispatchTableNullErrorStub and consequently for all dispatch
+// table calls (though normal functions will not expect or use this
+// register). This ABI is added to distinguish memory corruption errors from
+// null errors.
+struct DispatchTableNullErrorABI {
+  static const Register kClassIdReg = RCX;
+};
+
 typedef uint32_t RegList;
 const RegList kAllCpuRegistersList = 0xFFFF;
 const RegList kAllFpuRegistersList = 0xFFFF;
diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc
index 65332f5..3835109 100644
--- a/runtime/vm/dart.cc
+++ b/runtime/vm/dart.cc
@@ -53,10 +53,6 @@
 DEFINE_FLAG(bool, trace_shutdown, false, "Trace VM shutdown on stderr");
 DECLARE_FLAG(bool, strong);
 
-#if defined(DART_PRECOMPILED_RUNTIME)
-DEFINE_FLAG(bool, print_llvm_constant_pool, false, "Print LLVM constant pool");
-#endif
-
 Isolate* Dart::vm_isolate_ = NULL;
 int64_t Dart::start_time_micros_ = 0;
 ThreadPool* Dart::thread_pool_ = NULL;
@@ -811,52 +807,6 @@
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
 }
 
-#if defined(DART_PRECOMPILED_RUNTIME)
-static void PrintLLVMConstantPool(Thread* T, Isolate* I) {
-  StackZone printing_zone(T);
-  HandleScope printing_scope(T);
-  TextBuffer b(1000);
-  const auto& constants = GrowableObjectArray::Handle(
-      I->group()->object_store()->llvm_constant_pool());
-  if (constants.IsNull()) {
-    b.AddString("No constant pool information in snapshot.\n\n");
-  } else {
-    auto const len = constants.Length();
-    b.Printf("Constant pool contents (length %" Pd "):\n", len);
-    auto& obj = Object::Handle();
-    for (intptr_t i = 0; i < len; i++) {
-      obj = constants.At(i);
-      b.Printf("  %5" Pd ": ", i);
-      if (obj.IsString()) {
-        b.AddChar('"');
-        b.AddEscapedString(obj.ToCString());
-        b.AddChar('"');
-      } else {
-        b.AddString(obj.ToCString());
-      }
-      b.AddChar('\n');
-    }
-    b.AddString("End of constant pool.\n\n");
-  }
-  const auto& functions = GrowableObjectArray::Handle(
-      I->group()->object_store()->llvm_function_pool());
-  if (functions.IsNull()) {
-    b.AddString("No function pool information in snapshot.\n\n");
-  } else {
-    auto const len = functions.Length();
-    b.Printf("Function pool contents (length %" Pd "):\n", len);
-    auto& obj = Function::Handle();
-    for (intptr_t i = 0; i < len; i++) {
-      obj ^= functions.At(i);
-      ASSERT(!obj.IsNull());
-      b.Printf("  %5" Pd ": %s\n", i, obj.ToFullyQualifiedCString());
-    }
-    b.AddString("End of function pool.\n\n");
-  }
-  THR_Print("%s", b.buffer());
-}
-#endif
-
 ErrorPtr Dart::InitializeIsolate(const uint8_t* snapshot_data,
                                  const uint8_t* snapshot_instructions,
                                  const uint8_t* kernel_buffer,
@@ -913,11 +863,6 @@
 #if !defined(TARGET_ARCH_IA32)
     ASSERT(IG->object_store()->build_method_extractor_code() != Code::null());
 #endif
-#if defined(DART_PRECOMPILED_RUNTIME)
-    if (FLAG_print_llvm_constant_pool) {
-      PrintLLVMConstantPool(T, I);
-    }
-#endif  // defined(DART_PRECOMPILED_RUNTIME)
   } else {
 #if !defined(TARGET_ARCH_IA32)
     if (I != Dart::vm_isolate()) {
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index 580d5e9..206aad7 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -275,36 +275,51 @@
                        current_func, field_count, num_fields);
 }
 
-static ObjectPtr Send0Arg(const Instance& receiver, const String& selector) {
-  const intptr_t kTypeArgsLen = 0;
-  const intptr_t kNumArgs = 1;
-  ArgumentsDescriptor args_desc(
-      Array::Handle(ArgumentsDescriptor::NewBoxed(kTypeArgsLen, kNumArgs)));
+static FunctionPtr FindCoreLibPrivateFunction(Zone* zone, const String& name) {
+  const Library& core_lib = Library::Handle(zone, Library::CoreLibrary());
+  ASSERT(!core_lib.IsNull());
   const Function& function =
-      Function::Handle(Resolver::ResolveDynamic(receiver, selector, args_desc));
-  if (function.IsNull()) {
-    return ApiError::New(String::Handle(String::New("")));
-  }
-  const Array& args = Array::Handle(Array::New(kNumArgs));
-  args.SetAt(0, receiver);
+      Function::Handle(zone, core_lib.LookupFunctionAllowPrivate(name));
+  ASSERT(!function.IsNull());
+  return function.ptr();
+}
+
+static ObjectPtr CallStatic1Arg(Zone* zone,
+                                const String& name,
+                                const Instance& arg0) {
+  const intptr_t kNumArgs = 1;
+  const Function& function =
+      Function::Handle(zone, FindCoreLibPrivateFunction(zone, name));
+  const Array& args = Array::Handle(zone, Array::New(kNumArgs));
+  args.SetAt(0, arg0);
   return DartEntry::InvokeFunction(function, args);
 }
 
-static ObjectPtr Send1Arg(const Instance& receiver,
-                          const String& selector,
-                          const Instance& argument) {
-  const intptr_t kTypeArgsLen = 0;
+static ObjectPtr CallStatic2Args(Zone* zone,
+                                 const String& name,
+                                 const Instance& arg0,
+                                 const Instance& arg1) {
   const intptr_t kNumArgs = 2;
-  ArgumentsDescriptor args_desc(
-      Array::Handle(ArgumentsDescriptor::NewBoxed(kTypeArgsLen, kNumArgs)));
   const Function& function =
-      Function::Handle(Resolver::ResolveDynamic(receiver, selector, args_desc));
-  if (function.IsNull()) {
-    return ApiError::New(String::Handle(String::New("")));
-  }
+      Function::Handle(zone, FindCoreLibPrivateFunction(zone, name));
+  const Array& args = Array::Handle(zone, Array::New(kNumArgs));
+  args.SetAt(0, arg0);
+  args.SetAt(1, arg1);
+  return DartEntry::InvokeFunction(function, args);
+}
+
+static ObjectPtr CallStatic3Args(Zone* zone,
+                                 const String& name,
+                                 const Instance& arg0,
+                                 const Instance& arg1,
+                                 const Instance& arg2) {
+  const intptr_t kNumArgs = 3;
+  const Function& function =
+      Function::Handle(zone, FindCoreLibPrivateFunction(zone, name));
   const Array& args = Array::Handle(Array::New(kNumArgs));
-  args.SetAt(0, receiver);
-  args.SetAt(1, argument);
+  args.SetAt(0, arg0);
+  args.SetAt(1, arg1);
+  args.SetAt(2, arg2);
   return DartEntry::InvokeFunction(function, args);
 }
 
@@ -3187,21 +3202,8 @@
     return Api::NewArgumentError(
         "Object does not implement the List interface");
   }
-  const String& name = String::Handle(Z, Field::GetterName(Symbols::Length()));
-  const int kTypeArgsLen = 0;
-  const int kNumArgs = 1;
-  ArgumentsDescriptor args_desc(
-      Array::Handle(Z, ArgumentsDescriptor::NewBoxed(kTypeArgsLen, kNumArgs)));
-  const Function& function =
-      Function::Handle(Z, Resolver::ResolveDynamic(instance, name, args_desc));
-  if (function.IsNull()) {
-    return Api::NewArgumentError("List object does not have a 'length' field.");
-  }
-
-  const Array& args = Array::Handle(Z, Array::New(kNumArgs));
-  args.SetAt(0, instance);  // Set up the receiver as the first argument.
   const Object& retval =
-      Object::Handle(Z, DartEntry::InvokeFunction(function, args));
+      Object::Handle(Z, CallStatic1Arg(Z, Symbols::_listLength(), instance));
   if (retval.IsSmi()) {
     *len = Smi::Cast(retval).Value();
     return Api::Success();
@@ -3242,9 +3244,9 @@
     // Check and handle a dart object that implements the List interface.
     const Instance& instance = Instance::Handle(Z, GetListInstance(Z, obj));
     if (!instance.IsNull()) {
-      return Api::NewHandle(T,
-                            Send1Arg(instance, Symbols::IndexToken(),
-                                     Instance::Handle(Z, Integer::New(index))));
+      return Api::NewHandle(
+          T, CallStatic2Args(Z, Symbols::_listGetAt(), instance,
+                             Instance::Handle(Z, Integer::New(index))));
     }
     return Api::NewArgumentError(
         "Object does not implement the 'List' interface");
@@ -3281,27 +3283,21 @@
     // Check and handle a dart object that implements the List interface.
     const Instance& instance = Instance::Handle(Z, GetListInstance(Z, obj));
     if (!instance.IsNull()) {
-      const intptr_t kTypeArgsLen = 0;
       const intptr_t kNumArgs = 2;
-      ArgumentsDescriptor args_desc(
-          Array::Handle(ArgumentsDescriptor::NewBoxed(kTypeArgsLen, kNumArgs)));
       const Function& function = Function::Handle(
-          Z, Resolver::ResolveDynamic(instance, Symbols::AssignIndexToken(),
-                                      args_desc));
-      if (!function.IsNull()) {
-        const Array& args = Array::Handle(Array::New(kNumArgs));
-        args.SetAt(0, instance);
-        Instance& index = Instance::Handle(Z);
-        for (intptr_t i = 0; i < length; ++i) {
-          index = Integer::New(i);
-          args.SetAt(1, index);
-          Dart_Handle value =
-              Api::NewHandle(T, DartEntry::InvokeFunction(function, args));
-          if (Api::IsError(value)) return value;
-          result[i] = value;
-        }
-        return Api::Success();
+          Z, FindCoreLibPrivateFunction(Z, Symbols::_listGetAt()));
+      const Array& args = Array::Handle(Z, Array::New(kNumArgs));
+      args.SetAt(0, instance);
+      Instance& index = Instance::Handle(Z);
+      for (intptr_t i = 0; i < length; ++i) {
+        index = Integer::New(i);
+        args.SetAt(1, index);
+        Dart_Handle value =
+            Api::NewHandle(T, DartEntry::InvokeFunction(function, args));
+        if (Api::IsError(value)) return value;
+        result[i] = value;
       }
+      return Api::Success();
     }
     return Api::NewArgumentError(
         "Object does not implement the 'List' interface");
@@ -3339,25 +3335,14 @@
     // Check and handle a dart object that implements the List interface.
     const Instance& instance = Instance::Handle(Z, GetListInstance(Z, obj));
     if (!instance.IsNull()) {
-      const intptr_t kTypeArgsLen = 0;
-      const intptr_t kNumArgs = 3;
-      ArgumentsDescriptor args_desc(
-          Array::Handle(ArgumentsDescriptor::NewBoxed(kTypeArgsLen, kNumArgs)));
-      const Function& function = Function::Handle(
-          Z, Resolver::ResolveDynamic(instance, Symbols::AssignIndexToken(),
-                                      args_desc));
-      if (!function.IsNull()) {
-        const Integer& index_obj = Integer::Handle(Z, Integer::New(index));
-        const Object& value_obj = Object::Handle(Z, Api::UnwrapHandle(value));
-        if (!value_obj.IsNull() && !value_obj.IsInstance()) {
-          RETURN_TYPE_ERROR(Z, value, Instance);
-        }
-        const Array& args = Array::Handle(Z, Array::New(kNumArgs));
-        args.SetAt(0, instance);
-        args.SetAt(1, index_obj);
-        args.SetAt(2, value_obj);
-        return Api::NewHandle(T, DartEntry::InvokeFunction(function, args));
+      const Integer& index_obj = Integer::Handle(Z, Integer::New(index));
+      const Object& value_obj = Object::Handle(Z, Api::UnwrapHandle(value));
+      if (!value_obj.IsNull() && !value_obj.IsInstance()) {
+        RETURN_TYPE_ERROR(Z, value, Instance);
       }
+      return Api::NewHandle(
+          T, CallStatic3Args(Z, Symbols::_listSetAt(), instance, index_obj,
+                             Instance::Cast(value_obj)));
     }
     return Api::NewArgumentError(
         "Object does not implement the 'List' interface");
@@ -3524,41 +3509,35 @@
   // Check and handle a dart object that implements the List interface.
   const Instance& instance = Instance::Handle(Z, GetListInstance(Z, obj));
   if (!instance.IsNull()) {
-    const int kTypeArgsLen = 0;
     const int kNumArgs = 2;
-    ArgumentsDescriptor args_desc(
-        Array::Handle(ArgumentsDescriptor::NewBoxed(kTypeArgsLen, kNumArgs)));
     const Function& function = Function::Handle(
-        Z,
-        Resolver::ResolveDynamic(instance, Symbols::IndexToken(), args_desc));
-    if (!function.IsNull()) {
-      Object& result = Object::Handle(Z);
-      Integer& intobj = Integer::Handle(Z);
-      const Array& args = Array::Handle(Z, Array::New(kNumArgs));
-      args.SetAt(0, instance);  // Set up the receiver as the first argument.
-      for (int i = 0; i < length; i++) {
-        HANDLESCOPE(T);
-        intobj = Integer::New(offset + i);
-        args.SetAt(1, intobj);
-        result = DartEntry::InvokeFunction(function, args);
-        if (result.IsError()) {
-          return Api::NewHandle(T, result.ptr());
-        }
-        if (!result.IsInteger()) {
-          return Api::NewError(
-              "%s expects the argument 'list' to be "
-              "a List of int",
-              CURRENT_FUNC);
-        }
-        const Integer& integer_result = Integer::Cast(result);
-        ASSERT(integer_result.AsInt64Value() <= 0xff);
-        // TODO(hpayer): value should always be smaller then 0xff. Add error
-        // handling.
-        native_array[i] =
-            static_cast<uint8_t>(integer_result.AsInt64Value() & 0xff);
+        Z, FindCoreLibPrivateFunction(Z, Symbols::_listGetAt()));
+    Object& result = Object::Handle(Z);
+    Integer& intobj = Integer::Handle(Z);
+    const Array& args = Array::Handle(Z, Array::New(kNumArgs));
+    args.SetAt(0, instance);  // Set up the receiver as the first argument.
+    for (int i = 0; i < length; i++) {
+      HANDLESCOPE(T);
+      intobj = Integer::New(offset + i);
+      args.SetAt(1, intobj);
+      result = DartEntry::InvokeFunction(function, args);
+      if (result.IsError()) {
+        return Api::NewHandle(T, result.ptr());
       }
-      return Api::Success();
+      if (!result.IsInteger()) {
+        return Api::NewError(
+            "%s expects the argument 'list' to be "
+            "a List of int",
+            CURRENT_FUNC);
+      }
+      const Integer& integer_result = Integer::Cast(result);
+      ASSERT(integer_result.AsInt64Value() <= 0xff);
+      // TODO(hpayer): value should always be smaller then 0xff. Add error
+      // handling.
+      native_array[i] =
+          static_cast<uint8_t>(integer_result.AsInt64Value() & 0xff);
     }
+    return Api::Success();
   }
   return Api::NewArgumentError(
       "Object does not implement the 'List' interface");
@@ -3611,31 +3590,25 @@
   // Check and handle a dart object that implements the List interface.
   const Instance& instance = Instance::Handle(Z, GetListInstance(Z, obj));
   if (!instance.IsNull()) {
-    const int kTypeArgsLen = 0;
     const int kNumArgs = 3;
-    ArgumentsDescriptor args_desc(Array::Handle(
-        Z, ArgumentsDescriptor::NewBoxed(kTypeArgsLen, kNumArgs)));
     const Function& function = Function::Handle(
-        Z, Resolver::ResolveDynamic(instance, Symbols::AssignIndexToken(),
-                                    args_desc));
-    if (!function.IsNull()) {
-      Integer& indexobj = Integer::Handle(Z);
-      Integer& valueobj = Integer::Handle(Z);
-      const Array& args = Array::Handle(Z, Array::New(kNumArgs));
-      args.SetAt(0, instance);  // Set up the receiver as the first argument.
-      for (int i = 0; i < length; i++) {
-        indexobj = Integer::New(offset + i);
-        valueobj = Integer::New(native_array[i]);
-        args.SetAt(1, indexobj);
-        args.SetAt(2, valueobj);
-        const Object& result =
-            Object::Handle(Z, DartEntry::InvokeFunction(function, args));
-        if (result.IsError()) {
-          return Api::NewHandle(T, result.ptr());
-        }
+        Z, FindCoreLibPrivateFunction(Z, Symbols::_listSetAt()));
+    Integer& indexobj = Integer::Handle(Z);
+    Integer& valueobj = Integer::Handle(Z);
+    const Array& args = Array::Handle(Z, Array::New(kNumArgs));
+    args.SetAt(0, instance);  // Set up the receiver as the first argument.
+    for (int i = 0; i < length; i++) {
+      indexobj = Integer::New(offset + i);
+      valueobj = Integer::New(native_array[i]);
+      args.SetAt(1, indexobj);
+      args.SetAt(2, valueobj);
+      const Object& result =
+          Object::Handle(Z, DartEntry::InvokeFunction(function, args));
+      if (result.IsError()) {
+        return Api::NewHandle(T, result.ptr());
       }
-      return Api::Success();
     }
+    return Api::Success();
   }
   return Api::NewArgumentError(
       "Object does not implement the 'List' interface");
@@ -3653,8 +3626,8 @@
     if (!(key_obj.IsInstance() || key_obj.IsNull())) {
       return Api::NewError("Key is not an instance");
     }
-    return Api::NewHandle(
-        T, Send1Arg(instance, Symbols::IndexToken(), Instance::Cast(key_obj)));
+    return Api::NewHandle(T, CallStatic2Args(Z, Symbols::_mapGet(), instance,
+                                             Instance::Cast(key_obj)));
   }
   return Api::NewArgumentError("Object does not implement the 'Map' interface");
 }
@@ -3670,8 +3643,8 @@
       return Api::NewError("Key is not an instance");
     }
     return Api::NewHandle(
-        T, Send1Arg(instance, String::Handle(Z, String::New("containsKey")),
-                    Instance::Cast(key_obj)));
+        T, CallStatic2Args(Z, Symbols::_mapContainsKey(), instance,
+                           Instance::Cast(key_obj)));
   }
   return Api::NewArgumentError("Object does not implement the 'Map' interface");
 }
@@ -3682,13 +3655,7 @@
   Object& obj = Object::Handle(Z, Api::UnwrapHandle(map));
   Instance& instance = Instance::Handle(Z, GetMapInstance(Z, obj));
   if (!instance.IsNull()) {
-    const Object& iterator = Object::Handle(
-        Send0Arg(instance, String::Handle(Z, String::New("get:keys"))));
-    if (!iterator.IsInstance()) {
-      return Api::NewHandle(T, iterator.ptr());
-    }
-    return Api::NewHandle(T, Send0Arg(Instance::Cast(iterator),
-                                      String::Handle(String::New("toList"))));
+    return Api::NewHandle(T, CallStatic1Arg(Z, Symbols::_mapKeys(), instance));
   }
   return Api::NewArgumentError("Object does not implement the 'Map' interface");
 }
@@ -6278,29 +6245,34 @@
 #endif
 }
 
-DART_EXPORT Dart_Handle Dart_ServiceSendDataEvent(const char* stream_id,
-                                                  const char* event_kind,
-                                                  const uint8_t* bytes,
-                                                  intptr_t bytes_length) {
+DART_EXPORT char* Dart_ServiceSendDataEvent(const char* stream_id,
+                                            const char* event_kind,
+                                            const uint8_t* bytes,
+                                            intptr_t bytes_length) {
 #if !defined(PRODUCT)
-  DARTSCOPE(Thread::Current());
-  Isolate* I = T->isolate();
   if (stream_id == NULL) {
-    RETURN_NULL_ERROR(stream_id);
+    return Utils::StrDup(
+        "Dart_ServiceSendDataEvent expects argument 'stream_id' to be "
+        "non-null.");
   }
   if (event_kind == NULL) {
-    RETURN_NULL_ERROR(event_kind);
+    return Utils::StrDup(
+        "Dart_ServiceSendDataEvent expects argument 'event_kind' to be "
+        "non-null.");
   }
   if (bytes == NULL) {
-    RETURN_NULL_ERROR(bytes);
+    return Utils::StrDup(
+        "Dart_ServiceSendDataEvent expects argument 'bytes' to be non-null.");
   }
   if (bytes_length < 0) {
-    return Api::NewError("%s expects argument 'bytes_length' to be >= 0.",
-                         CURRENT_FUNC);
+    return Utils::StrDup(
+        "Dart_ServiceSendDataEvent expects argument 'bytes_length' to be >= "
+        "0.");
   }
-  Service::SendEmbedderEvent(I, stream_id, event_kind, bytes, bytes_length);
+  Service::SendEmbedderEvent(Isolate::Current(),  // May be NULL
+                             stream_id, event_kind, bytes, bytes_length);
 #endif
-  return Api::Success();
+  return nullptr;
 }
 
 DART_EXPORT void Dart_SetGCEventCallback(Dart_GCEventCallback callback) {
@@ -6993,12 +6965,14 @@
     bool non_main_isolates_alive = false;
     {
       SafepointOperationScope safepoint(thread);
-      group->ForEachIsolate([&](Isolate* isolate) {
-        if (isolate != main_isolate) {
-          Isolate::KillIfExists(isolate, Isolate::kKillMsg);
-          non_main_isolates_alive = true;
-        }
-      });
+      group->ForEachIsolate(
+          [&](Isolate* isolate) {
+            if (isolate != main_isolate) {
+              Isolate::KillIfExists(isolate, Isolate::kKillMsg);
+              non_main_isolates_alive = true;
+            }
+          },
+          /*at_safepoint=*/true);
       if (!non_main_isolates_alive) {
         break;
       }
diff --git a/runtime/vm/dart_entry.cc b/runtime/vm/dart_entry.cc
index 691bd6c..058d039 100644
--- a/runtime/vm/dart_entry.cc
+++ b/runtime/vm/dart_entry.cc
@@ -344,21 +344,10 @@
   }
 
   // Now use the invocation mirror object and invoke NoSuchMethod.
-  const int kTypeArgsLen = 0;
   const int kNumArguments = 2;
-  const ArgumentsDescriptor nsm_args_desc(Array::Handle(
-      zone, ArgumentsDescriptor::NewBoxed(kTypeArgsLen, kNumArguments)));
-  Function& function = Function::Handle(
-      zone, Resolver::ResolveDynamic(receiver, Symbols::NoSuchMethod(),
-                                     nsm_args_desc));
-  if (function.IsNull()) {
-    ASSERT(!FLAG_lazy_dispatchers);
-    // If noSuchMethod(invocation) is not found, call Object::noSuchMethod.
-    function = Resolver::ResolveDynamicForReceiverClass(
-        Class::Handle(zone,
-                      thread->isolate_group()->object_store()->object_class()),
-        Symbols::NoSuchMethod(), nsm_args_desc);
-  }
+  const Function& function = Function::Handle(
+      zone,
+      core_lib.LookupFunctionAllowPrivate(Symbols::_objectNoSuchMethod()));
   ASSERT(!function.IsNull());
   const Array& args = Array::Handle(zone, Array::New(kNumArguments));
   args.SetAt(0, receiver);
@@ -423,24 +412,28 @@
   return names.ptr();
 }
 
-void ArgumentsDescriptor::PrintTo(BaseTextBuffer* buffer) const {
-  buffer->Printf("%" Pd " arg%s", Count(), Count() == 1 ? "" : "s");
+void ArgumentsDescriptor::PrintTo(BaseTextBuffer* buffer,
+                                  bool show_named_positions) const {
   if (TypeArgsLen() > 0) {
-    buffer->Printf(", %" Pd " type arg%s", TypeArgsLen(),
-                   TypeArgsLen() == 1 ? "" : "s");
+    buffer->Printf("<%" Pd ">", TypeArgsLen());
   }
+  buffer->Printf("(%" Pd "", Count());
   if (NamedCount() > 0) {
-    buffer->AddString(", names [");
+    buffer->AddString(" {");
     auto& str = String::Handle();
     for (intptr_t i = 0; i < NamedCount(); i++) {
       if (i != 0) {
         buffer->AddString(", ");
       }
       str = NameAt(i);
-      buffer->Printf("'%s' (%" Pd ")", str.ToCString(), PositionAt(i));
+      buffer->Printf("%s", str.ToCString());
+      if (show_named_positions) {
+        buffer->Printf(" (%" Pd ")", PositionAt(i));
+      }
     }
-    buffer->Printf("]");
+    buffer->Printf("}");
   }
+  buffer->Printf(")");
 }
 
 const char* ArgumentsDescriptor::ToCString() const {
@@ -621,55 +614,71 @@
 }
 
 ObjectPtr DartLibraryCalls::ToString(const Instance& receiver) {
-  const int kTypeArgsLen = 0;
-  const int kNumArguments = 1;  // Receiver.
-  ArgumentsDescriptor args_desc(Array::Handle(
-      ArgumentsDescriptor::NewBoxed(kTypeArgsLen, kNumArguments)));
-  const Class& receiver_class = Class::Handle(receiver.clazz());
-  const auto& error = receiver_class.EnsureIsFinalized(Thread::Current());
-  ASSERT(error == Error::null());
-  const Function& function = Function::Handle(
-      Resolver::ResolveDynamic(receiver, Symbols::toString(), args_desc));
-  ASSERT(!function.IsNull());
-  const Array& args = Array::Handle(Array::New(kNumArguments));
+  Thread* thread = Thread::Current();
+  Zone* zone = thread->zone();
+  Function& function = Function::Handle(
+      zone,
+      thread->isolate_group()->object_store()->_object_to_string_function());
+  if (function.IsNull()) {
+    const Library& core_lib = Library::Handle(zone, Library::CoreLibrary());
+    ASSERT(!core_lib.IsNull());
+    function = core_lib.LookupFunctionAllowPrivate(Symbols::_objectToString());
+    ASSERT(!function.IsNull());
+    thread->isolate_group()->object_store()->set__object_to_string_function(
+        function);
+  }
+  const int kNumArguments = 1;
+  const Array& args = Array::Handle(zone, Array::New(kNumArguments));
   args.SetAt(0, receiver);
   const Object& result =
-      Object::Handle(DartEntry::InvokeFunction(function, args));
+      Object::Handle(zone, DartEntry::InvokeFunction(function, args));
   ASSERT(result.IsInstance() || result.IsError());
   return result.ptr();
 }
 
 ObjectPtr DartLibraryCalls::HashCode(const Instance& receiver) {
-  const int kTypeArgsLen = 0;
-  const int kNumArguments = 1;  // Receiver.
-  ArgumentsDescriptor args_desc(Array::Handle(
-      ArgumentsDescriptor::NewBoxed(kTypeArgsLen, kNumArguments)));
-  const Function& function = Function::Handle(
-      Resolver::ResolveDynamic(receiver, Symbols::hashCode(), args_desc));
-  ASSERT(!function.IsNull());
-  const Array& args = Array::Handle(Array::New(kNumArguments));
+  Thread* thread = Thread::Current();
+  Zone* zone = thread->zone();
+  Function& function = Function::Handle(
+      zone,
+      thread->isolate_group()->object_store()->_object_hash_code_function());
+  if (function.IsNull()) {
+    const Library& core_lib = Library::Handle(zone, Library::CoreLibrary());
+    ASSERT(!core_lib.IsNull());
+    function = core_lib.LookupFunctionAllowPrivate(Symbols::_objectHashCode());
+    ASSERT(!function.IsNull());
+    thread->isolate_group()->object_store()->set__object_hash_code_function(
+        function);
+  }
+  const int kNumArguments = 1;
+  const Array& args = Array::Handle(zone, Array::New(kNumArguments));
   args.SetAt(0, receiver);
   const Object& result =
-      Object::Handle(DartEntry::InvokeFunction(function, args));
+      Object::Handle(zone, DartEntry::InvokeFunction(function, args));
   ASSERT(result.IsInstance() || result.IsError());
   return result.ptr();
 }
 
 ObjectPtr DartLibraryCalls::Equals(const Instance& left,
                                    const Instance& right) {
-  const int kTypeArgsLen = 0;
+  Thread* thread = Thread::Current();
+  Zone* zone = thread->zone();
+  Function& function = Function::Handle(
+      zone, thread->isolate_group()->object_store()->_object_equals_function());
+  if (function.IsNull()) {
+    const Library& core_lib = Library::Handle(zone, Library::CoreLibrary());
+    ASSERT(!core_lib.IsNull());
+    function = core_lib.LookupFunctionAllowPrivate(Symbols::_objectEquals());
+    ASSERT(!function.IsNull());
+    thread->isolate_group()->object_store()->set__object_equals_function(
+        function);
+  }
   const int kNumArguments = 2;
-  ArgumentsDescriptor args_desc(Array::Handle(
-      ArgumentsDescriptor::NewBoxed(kTypeArgsLen, kNumArguments)));
-  const Function& function = Function::Handle(
-      Resolver::ResolveDynamic(left, Symbols::EqualOperator(), args_desc));
-  ASSERT(!function.IsNull());
-
-  const Array& args = Array::Handle(Array::New(kNumArguments));
+  const Array& args = Array::Handle(zone, Array::New(kNumArguments));
   args.SetAt(0, left);
   args.SetAt(1, right);
   const Object& result =
-      Object::Handle(DartEntry::InvokeFunction(function, args));
+      Object::Handle(zone, DartEntry::InvokeFunction(function, args));
   ASSERT(result.IsInstance() || result.IsError());
   return result.ptr();
 }
@@ -821,23 +830,4 @@
   return result.ptr();
 }
 
-ObjectPtr DartLibraryCalls::MapSetAt(const Instance& map,
-                                     const Instance& key,
-                                     const Instance& value) {
-  const int kTypeArgsLen = 0;
-  const int kNumArguments = 3;
-  ArgumentsDescriptor args_desc(Array::Handle(
-      ArgumentsDescriptor::NewBoxed(kTypeArgsLen, kNumArguments)));
-  const Function& function = Function::Handle(
-      Resolver::ResolveDynamic(map, Symbols::AssignIndexToken(), args_desc));
-  ASSERT(!function.IsNull());
-  const Array& args = Array::Handle(Array::New(kNumArguments));
-  args.SetAt(0, map);
-  args.SetAt(1, key);
-  args.SetAt(2, value);
-  const Object& result =
-      Object::Handle(DartEntry::InvokeFunction(function, args));
-  return result.ptr();
-}
-
 }  // namespace dart
diff --git a/runtime/vm/dart_entry.h b/runtime/vm/dart_entry.h
index cfd0c06..2a33464 100644
--- a/runtime/vm/dart_entry.h
+++ b/runtime/vm/dart_entry.h
@@ -46,7 +46,7 @@
   bool MatchesNameAt(intptr_t i, const String& other) const;
   // Returns array of argument names in the arguments order.
   ArrayPtr GetArgumentNames() const;
-  void PrintTo(BaseTextBuffer* buffer) const;
+  void PrintTo(BaseTextBuffer* buffer, bool show_named_positions = false) const;
   const char* ToCString() const;
 
   // Generated code support.
@@ -296,13 +296,6 @@
   // _startMicrotaskLoop from dart:async.
   // Returns null on success, an ErrorPtr on failure.
   static ObjectPtr EnsureScheduleImmediate();
-
-  // map[key] = value;
-  //
-  // Returns null on success, an ErrorPtr on failure.
-  static ObjectPtr MapSetAt(const Instance& map,
-                            const Instance& key,
-                            const Instance& value);
 };
 
 }  // namespace dart
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc
index 2b5db6a..592a7e5 100644
--- a/runtime/vm/debugger.cc
+++ b/runtime/vm/debugger.cc
@@ -57,38 +57,44 @@
 #ifndef PRODUCT
 
 // Create an unresolved breakpoint in given token range and script.
-BreakpointLocation::BreakpointLocation(const Script& script,
+BreakpointLocation::BreakpointLocation(Debugger* debugger,
+                                       const Script& script,
                                        TokenPosition token_pos,
                                        TokenPosition end_token_pos,
                                        intptr_t requested_line_number,
                                        intptr_t requested_column_number)
-    : script_(script.ptr()),
+    : debugger_(debugger),
+      script_(script.ptr()),
       url_(script.url()),
+      line_number_lock_(new SafepointRwLock()),
+      line_number_(-1),  // lazily computed
       token_pos_(token_pos),
       end_token_pos_(end_token_pos),
       next_(NULL),
       conditions_(NULL),
       requested_line_number_(requested_line_number),
       requested_column_number_(requested_column_number),
-      function_(Function::null()),
       code_token_pos_(TokenPosition::kNoSource) {
   ASSERT(!script.IsNull());
   ASSERT(token_pos_.IsReal());
 }
 
 // Create a latent breakpoint at given url and line number.
-BreakpointLocation::BreakpointLocation(const String& url,
+BreakpointLocation::BreakpointLocation(Debugger* debugger,
+                                       const String& url,
                                        intptr_t requested_line_number,
                                        intptr_t requested_column_number)
-    : script_(Script::null()),
+    : debugger_(debugger),
+      script_(Script::null()),
       url_(url.ptr()),
+      line_number_lock_(new SafepointRwLock()),
+      line_number_(-1),  // lazily computed
       token_pos_(TokenPosition::kNoSource),
       end_token_pos_(TokenPosition::kNoSource),
       next_(NULL),
       conditions_(NULL),
       requested_line_number_(requested_line_number),
       requested_column_number_(requested_column_number),
-      function_(Function::null()),
       code_token_pos_(TokenPosition::kNoSource) {
   ASSERT(requested_line_number_ >= 0);
 }
@@ -112,7 +118,6 @@
   ASSERT(func.script() == script_);
   ASSERT(token_pos.IsWithin(func.token_pos(), func.end_token_pos()));
   ASSERT(func.is_debuggable());
-  function_ = func.ptr();
   token_pos_ = token_pos;
   end_token_pos_ = token_pos;
   code_token_pos_ = token_pos;
@@ -129,6 +134,21 @@
   }
 }
 
+intptr_t BreakpointLocation::line_number() {
+  // Compute line number lazily since it causes scanning of the script.
+  {
+    SafepointReadRwLocker sl(Thread::Current(), line_number_lock());
+    if (line_number_ >= 0) {
+      return line_number_;
+    }
+  }
+  SafepointWriteRwLocker sl(Thread::Current(), line_number_lock());
+  if (line_number_ < 0) {
+    Script::Handle(script()).GetTokenLocation(token_pos(), &line_number_);
+  }
+  return line_number_;
+}
+
 void Breakpoint::set_bpt_location(BreakpointLocation* new_bpt_location) {
   // Only latent breakpoints can be moved.
   ASSERT((new_bpt_location == NULL) || bpt_location_->IsLatent());
@@ -142,7 +162,6 @@
 void BreakpointLocation::VisitObjectPointers(ObjectPointerVisitor* visitor) {
   visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(&script_));
   visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(&url_));
-  visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(&function_));
 
   Breakpoint* bpt = conditions_;
   while (bpt != NULL) {
@@ -173,6 +192,23 @@
   visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(&saved_value_));
 }
 
+const char* CodeBreakpoint::ToCString() const {
+  if (breakpoint_locations_.length() == 0) {
+    return "unlinked breakpoint";
+  }
+
+  char buffer[1024];
+  BufferFormatter f(buffer, sizeof(buffer));
+  // Pick the first, all other should have same script/line number.
+  BreakpointLocation* breakpoint_location = breakpoint_locations_.At(0);
+  Script& script = Script::Handle(breakpoint_location->script());
+  String& source_url = String::Handle(script.url());
+  intptr_t line_number = breakpoint_location->line_number();
+
+  f.Printf("breakpoint at %s:%" Pd, source_url.ToCString(), line_number);
+  return Thread::Current()->zone()->MakeCopyOfString(buffer);
+}
+
 ActivationFrame::ActivationFrame(uword pc,
                                  uword fp,
                                  uword sp,
@@ -296,7 +332,7 @@
   }
   CacheStackTraces(trace, DebuggerStackTrace::CollectAsyncCausal(),
                    DebuggerStackTrace::CollectAwaiterReturn());
-  resume_action_ = kContinue;
+  set_resume_action(kContinue);
   Pause(&event);
   HandleSteppingRequest(trace);
   ClearCachedStackTraces();
@@ -323,7 +359,7 @@
   bpt->set_next(breakpoints());
   set_breakpoints(bpt);
 
-  dbg->SyncBreakpointLocation(this);
+  dbg->group_debugger()->SyncBreakpointLocation(this);
   dbg->SendBreakpointEvent(ServiceEvent::kBreakpointAdded, bpt);
 }
 
@@ -423,43 +459,32 @@
   return false;
 }
 
-bool Debugger::HasBreakpoint(const Function& func, Zone* zone) {
-  if (!func.HasCode()) {
-    // If the function is not compiled yet, just check whether there
-    // is a user-defined breakpoint that falls into the token
-    // range of the function. This may be a false positive: the breakpoint
-    // might be inside a local closure.
-    Script& script = Script::Handle(zone);
-    BreakpointLocation* sbpt = breakpoint_locations_;
-    while (sbpt != NULL) {
-      script = sbpt->script();
-      if (FunctionOverlaps(func, script, sbpt->token_pos(),
-                           sbpt->end_token_pos())) {
+bool GroupDebugger::HasCodeBreakpointInFunction(const Function& func) {
+  auto thread = Thread::Current();
+  return RunUnderReadLockIfNeeded(thread, code_breakpoints_lock(), [&]() {
+    CodeBreakpoint* cbpt = code_breakpoints_;
+    while (cbpt != NULL) {
+      if (func.ptr() == cbpt->function()) {
         return true;
       }
-      sbpt = sbpt->next_;
+      cbpt = cbpt->next_;
     }
     return false;
-  }
-  CodeBreakpoint* cbpt = code_breakpoints_;
-  while (cbpt != NULL) {
-    if (func.ptr() == cbpt->function()) {
-      return true;
-    }
-    cbpt = cbpt->next_;
-  }
-  return false;
+  });
 }
 
-bool Debugger::HasBreakpoint(const Code& code) {
-  CodeBreakpoint* cbpt = code_breakpoints_;
-  while (cbpt != NULL) {
-    if (code.ptr() == cbpt->code_) {
-      return true;
+bool GroupDebugger::HasBreakpointInCode(const Code& code) {
+  auto thread = Thread::Current();
+  return RunUnderReadLockIfNeeded(thread, code_breakpoints_lock(), [&]() {
+    CodeBreakpoint* cbpt = code_breakpoints_;
+    while (cbpt != NULL) {
+      if (code.ptr() == cbpt->code_) {
+        return true;
+      }
+      cbpt = cbpt->next_;
     }
-    cbpt = cbpt->next_;
-  }
-  return false;
+    return false;
+  });
 }
 
 void Debugger::PrintBreakpointsToJSONArray(JSONArray* jsarr) const {
@@ -1438,22 +1463,20 @@
                                UntaggedPcDescriptors::kRuntimeCall;
 
 CodeBreakpoint::CodeBreakpoint(const Code& code,
-                               TokenPosition token_pos,
+                               BreakpointLocation* breakpoint_location,
                                uword pc,
                                UntaggedPcDescriptors::Kind kind)
     : code_(code.ptr()),
-      token_pos_(token_pos),
       pc_(pc),
-      line_number_(-1),
-      is_enabled_(false),
-      bpt_location_(NULL),
+      enabled_count_(0),
       next_(NULL),
       breakpoint_kind_(kind),
       saved_value_(Code::null()) {
   ASSERT(!code.IsNull());
-  ASSERT(token_pos_.IsReal());
   ASSERT(pc_ != 0);
   ASSERT((breakpoint_kind_ & kSafepointKind) != 0);
+  AddBreakpointLocation(breakpoint_location);
+  ASSERT(breakpoint_location->token_pos().IsReal());
 }
 
 CodeBreakpoint::~CodeBreakpoint() {
@@ -1463,47 +1486,71 @@
 #ifdef DEBUG
   code_ = Code::null();
   pc_ = 0ul;
-  bpt_location_ = NULL;
   next_ = NULL;
   breakpoint_kind_ = UntaggedPcDescriptors::kOther;
 #endif
 }
 
-FunctionPtr CodeBreakpoint::function() const {
-  return Code::Handle(code_).function();
-}
-
-ScriptPtr CodeBreakpoint::SourceCode() {
-  const Function& func = Function::Handle(this->function());
-  return func.script();
-}
-
-StringPtr CodeBreakpoint::SourceUrl() {
-  const Script& script = Script::Handle(SourceCode());
-  return script.url();
-}
-
-intptr_t CodeBreakpoint::LineNumber() {
-  // Compute line number lazily since it causes scanning of the script.
-  if (line_number_ < 0) {
-    const Script& script = Script::Handle(SourceCode());
-    script.GetTokenLocation(token_pos_, &line_number_);
-  }
-  return line_number_;
-}
-
 void CodeBreakpoint::Enable() {
-  if (!is_enabled_) {
+  if (enabled_count_ == 0) {
     PatchCode();
   }
-  ASSERT(is_enabled_);
+  ++enabled_count_;
 }
 
 void CodeBreakpoint::Disable() {
-  if (is_enabled_) {
+  if (enabled_count_ == 1) {
     RestoreCode();
   }
-  ASSERT(!is_enabled_);
+  --enabled_count_;
+}
+
+bool CodeBreakpoint::HasBreakpointLocation(
+    BreakpointLocation* breakpoint_location) {
+  for (intptr_t i = 0; i < breakpoint_locations_.length(); i++) {
+    if (breakpoint_locations_[i] == breakpoint_location) {
+      return true;
+    }
+  }
+  return false;
+}
+
+bool CodeBreakpoint::FindAndDeleteBreakpointLocation(
+    BreakpointLocation* breakpoint_location) {
+  for (intptr_t i = 0; i < breakpoint_locations_.length(); i++) {
+    if (breakpoint_locations_[i] == breakpoint_location) {
+      breakpoint_locations_.EraseAt(i);
+      return true;
+    }
+  }
+  return false;
+}
+
+BreakpointLocation* CodeBreakpoint::FindBreakpointForDebugger(
+    Debugger* debugger) {
+  for (intptr_t i = 0; i < breakpoint_locations_.length(); i++) {
+    if (breakpoint_locations_[i]->debugger() == debugger) {
+      return breakpoint_locations_[i];
+    }
+  }
+  return nullptr;
+}
+
+GroupDebugger::GroupDebugger(IsolateGroup* isolate_group)
+    : isolate_group_(isolate_group),
+      code_breakpoints_lock_(new SafepointRwLock()),
+      code_breakpoints_(nullptr),
+      breakpoint_locations_lock_(new SafepointRwLock()),
+      single_stepping_set_lock_(new SafepointRwLock()),
+      needs_breakpoint_cleanup_(false) {}
+
+GroupDebugger::~GroupDebugger() {
+  while (code_breakpoints_ != nullptr) {
+    CodeBreakpoint* cbpt = code_breakpoints_;
+    code_breakpoints_ = code_breakpoints_->next();
+    ASSERT(!cbpt->IsEnabled());
+    delete cbpt;
+  }
 }
 
 Debugger::Debugger(Isolate* isolate)
@@ -1511,7 +1558,6 @@
       next_id_(1),
       latent_locations_(NULL),
       breakpoint_locations_(NULL),
-      code_breakpoints_(NULL),
       resume_action_(kContinue),
       resume_frame_index_(-1),
       post_deopt_frame_index_(-1),
@@ -1526,7 +1572,6 @@
       async_stepping_fp_(0),
       top_frame_awaiter_(Object::null()),
       skip_next_step_(false),
-      needs_breakpoint_cleanup_(false),
       synthetic_async_breakpoint_(NULL),
       exc_pause_info_(kNoPauseOnExceptions) {}
 
@@ -1534,7 +1579,6 @@
   ASSERT(!IsPaused());
   ASSERT(latent_locations_ == NULL);
   ASSERT(breakpoint_locations_ == NULL);
-  ASSERT(code_breakpoints_ == NULL);
   ASSERT(stack_trace_ == NULL);
   ASSERT(async_causal_stack_trace_ == NULL);
   ASSERT(synthetic_async_breakpoint_ == NULL);
@@ -1546,21 +1590,23 @@
   if (Isolate::IsSystemIsolate(isolate_)) {
     return;
   }
-  while (breakpoint_locations_ != NULL) {
-    BreakpointLocation* loc = breakpoint_locations_;
-    breakpoint_locations_ = breakpoint_locations_->next();
-    delete loc;
-  }
-  while (latent_locations_ != NULL) {
-    BreakpointLocation* loc = latent_locations_;
-    latent_locations_ = latent_locations_->next();
-    delete loc;
-  }
-  while (code_breakpoints_ != NULL) {
-    CodeBreakpoint* cbpt = code_breakpoints_;
-    code_breakpoints_ = code_breakpoints_->next();
-    cbpt->Disable();
-    delete cbpt;
+  {
+    SafepointWriteRwLocker sl(Thread::Current(),
+                              group_debugger()->breakpoint_locations_lock());
+    while (breakpoint_locations_ != nullptr) {
+      BreakpointLocation* loc = breakpoint_locations_;
+      group_debugger()->UnlinkCodeBreakpoints(loc);
+      group_debugger()->UnregisterBreakpointLocation(loc);
+      breakpoint_locations_ = breakpoint_locations_->next();
+      delete loc;
+    }
+    while (latent_locations_ != nullptr) {
+      BreakpointLocation* loc = latent_locations_;
+      group_debugger()->UnlinkCodeBreakpoints(loc);
+      group_debugger()->UnregisterBreakpointLocation(loc);
+      latent_locations_ = latent_locations_->next();
+      delete loc;
+    }
   }
   if (NeedsIsolateEvents()) {
     ServiceEvent event(isolate_, ServiceEvent::kIsolateExit);
@@ -1609,13 +1655,13 @@
     case kStepOver:
     case kStepOut:
     case kContinue:
-      resume_action_ = action;
+      set_resume_action(action);
       return true;
     case kStepRewind:
       if (!CanRewindFrame(frame_index, error)) {
         return false;
       }
-      resume_action_ = kStepRewind;
+      set_resume_action(kStepRewind);
       resume_frame_index_ = frame_index;
       return true;
     case kStepOverAsyncSuspension:
@@ -2439,8 +2485,47 @@
   return TokenPosition::kNoSource;
 }
 
-void Debugger::MakeCodeBreakpointAt(const Function& func,
-                                    BreakpointLocation* loc) {
+bool BreakpointLocation::EnsureIsResolved(const Function& target_function,
+                                          TokenPosition exact_token_pos) {
+  if (IsResolved()) {
+    return true;
+  }
+
+  // Resolve source breakpoint in the newly compiled function.
+  TokenPosition resolved_pos =
+      ResolveBreakpointPos(target_function, token_pos(), end_token_pos(),
+                           requested_column_number(), exact_token_pos);
+  if (!resolved_pos.IsDebugPause()) {
+    if (FLAG_verbose_debug) {
+      OS::PrintErr("Failed resolving breakpoint for function '%s'\n",
+                   target_function.ToFullyQualifiedCString());
+    }
+    return false;
+  }
+  TokenPosition requested_pos = token_pos();
+  TokenPosition requested_end_pos = end_token_pos();
+  SetResolved(target_function, resolved_pos);
+  Breakpoint* breakpoint = breakpoints();
+  while (breakpoint != nullptr) {
+    if (FLAG_verbose_debug) {
+      OS::PrintErr("Resolved breakpoint %" Pd
+                   " to pos %s, function '%s' (requested range %s-%s, "
+                   "requested col %" Pd ")\n",
+                   breakpoint->id(), token_pos().ToCString(),
+                   target_function.ToFullyQualifiedCString(),
+                   requested_pos.ToCString(), requested_end_pos.ToCString(),
+                   requested_column_number());
+    }
+    debugger()->SendBreakpointEvent(ServiceEvent::kBreakpointResolved,
+                                    breakpoint);
+    breakpoint = breakpoint->next();
+  }
+
+  return true;
+}
+
+void GroupDebugger::MakeCodeBreakpointAt(const Function& func,
+                                         BreakpointLocation* loc) {
   ASSERT(loc->token_pos_.IsReal());
   ASSERT((loc != NULL) && loc->IsResolved());
   ASSERT(!func.HasOptimizedCode());
@@ -2461,25 +2546,35 @@
       }
     }
   }
-  if (lowest_pc_offset != kUwordMax) {
-    uword lowest_pc = code.PayloadStart() + lowest_pc_offset;
-    CodeBreakpoint* code_bpt = GetCodeBreakpoint(lowest_pc);
-    if (code_bpt == NULL) {
-      // No code breakpoint for this code exists; create one.
-      code_bpt =
-          new CodeBreakpoint(code, loc->token_pos_, lowest_pc, lowest_kind);
-      if (FLAG_verbose_debug) {
-        OS::PrintErr("Setting code breakpoint at pos %s pc %#" Px
-                     " offset %#" Px "\n",
-                     loc->token_pos_.ToCString(), lowest_pc,
-                     lowest_pc - code.PayloadStart());
-      }
-      RegisterCodeBreakpoint(code_bpt);
+  if (lowest_pc_offset == kUwordMax) {
+    return;
+  }
+
+  uword lowest_pc = code.PayloadStart() + lowest_pc_offset;
+  SafepointWriteRwLocker sl(Thread::Current(), code_breakpoints_lock());
+  CodeBreakpoint* code_bpt = GetCodeBreakpoint(lowest_pc);
+  if (code_bpt == nullptr) {
+    // No code breakpoint for this code exists; create one.
+    code_bpt = new CodeBreakpoint(code, loc, lowest_pc, lowest_kind);
+    if (FLAG_verbose_debug) {
+      OS::PrintErr("Setting code breakpoint at pos %s pc %#" Px " offset %#" Px
+                   "\n",
+                   loc->token_pos_.ToCString(), lowest_pc,
+                   lowest_pc - code.PayloadStart());
     }
-    code_bpt->set_bpt_location(loc);
-    if (loc->AnyEnabled()) {
-      code_bpt->Enable();
+    RegisterCodeBreakpoint(code_bpt);
+  } else {
+    if (FLAG_verbose_debug) {
+      OS::PrintErr(
+          "Adding location to existing code breakpoint at pos %s pc %#" Px
+          " offset %#" Px "\n",
+          loc->token_pos_.ToCString(), lowest_pc,
+          lowest_pc - code.PayloadStart());
     }
+    code_bpt->AddBreakpointLocation(loc);
+  }
+  if (loc->AnyEnabled()) {
+    code_bpt->Enable();
   }
 }
 
@@ -2721,20 +2816,17 @@
   TokenPosition breakpoint_pos = ResolveBreakpointPos(
       function, token_pos, last_token_pos, requested_column, exact_token_pos);
   if (!breakpoint_pos.IsReal()) {
-    return NULL;
+    return nullptr;
   }
-  // Find an existing resolved breakpoint location.
   BreakpointLocation* loc =
-      GetBreakpointLocation(script, TokenPosition::kNoSource,
-                            /* requested_line = */ -1,
-                            /* requested_column = */ -1, breakpoint_pos);
-  if (loc == NULL) {
+      GetResolvedBreakpointLocation(script, breakpoint_pos);
+  if (loc == nullptr) {
     // Find an existing unresolved breakpoint location.
     loc = GetBreakpointLocation(script, token_pos, requested_line,
                                 requested_column);
   }
   if (loc == NULL) {
-    loc = new BreakpointLocation(script, breakpoint_pos, breakpoint_pos,
+    loc = new BreakpointLocation(this, script, breakpoint_pos, breakpoint_pos,
                                  requested_line, requested_column);
     RegisterBreakpointLocation(loc);
   }
@@ -2751,7 +2843,7 @@
   for (intptr_t i = 0; i < num_functions; i++) {
     func ^= functions.At(i);
     ASSERT(func.HasCode());
-    MakeCodeBreakpointAt(func, loc);
+    group_debugger()->MakeCodeBreakpointAt(func, loc);
   }
   if (FLAG_verbose_debug) {
     intptr_t line_number = -1;
@@ -2842,7 +2934,7 @@
   BreakpointLocation* loc =
       GetBreakpointLocation(script, token_pos, -1, requested_column);
   if (loc == NULL) {
-    loc = new BreakpointLocation(script, token_pos, last_token_pos,
+    loc = new BreakpointLocation(this, script, token_pos, last_token_pos,
                                  requested_line, requested_column);
     RegisterBreakpointLocation(loc);
   }
@@ -2851,12 +2943,13 @@
 
 // Synchronize the enabled/disabled state of all code breakpoints
 // associated with the breakpoint location loc.
-void Debugger::SyncBreakpointLocation(BreakpointLocation* loc) {
+void GroupDebugger::SyncBreakpointLocation(BreakpointLocation* loc) {
   bool any_enabled = loc->AnyEnabled();
 
+  SafepointWriteRwLocker sl(Thread::Current(), code_breakpoints_lock());
   CodeBreakpoint* cbpt = code_breakpoints_;
   while (cbpt != NULL) {
-    if (loc == cbpt->bpt_location()) {
+    if (cbpt->HasBreakpointLocation(loc)) {
       if (any_enabled) {
         cbpt->Enable();
       } else {
@@ -3044,6 +3137,115 @@
   return loc;
 }
 
+// Return innermost closure contained in 'function' that contains
+// the given token position.
+static FunctionPtr FindInnermostClosure(Zone* zone,
+                                        const Function& function,
+                                        TokenPosition token_pos) {
+  ASSERT(function.end_token_pos().IsReal());
+  const TokenPosition& func_start = function.token_pos();
+  const Script& outer_origin = Script::Handle(zone, function.script());
+
+  Function& best_fit = Function::Handle(zone);
+  ClosureFunctionsCache::ForAllClosureFunctions([&](const Function& closure) {
+    const TokenPosition& closure_start = closure.token_pos();
+    const TokenPosition& closure_end = closure.end_token_pos();
+    // We're only interested in closures that have real ending token positions.
+    // The starting token position can be synthetic.
+    if (closure_end.IsReal() && (function.end_token_pos() > closure_end) &&
+        (!closure_start.IsReal() || !func_start.IsReal() ||
+         (closure_start > func_start)) &&
+        token_pos.IsWithin(closure_start, closure_end) &&
+        (closure.script() == outer_origin.ptr())) {
+      UpdateBestFit(&best_fit, closure);
+    }
+    return true;  // Continue iteration.
+  });
+  return best_fit.ptr();
+}
+
+bool GroupDebugger::EnsureLocationIsInFunction(Zone* zone,
+                                               const Function& function,
+                                               BreakpointLocation* location) {
+  const Script& script = Script::Handle(zone, location->script());
+  if (!FunctionOverlaps(function, script, location->token_pos(),
+                        location->end_token_pos())) {
+    return false;
+  }
+
+  TokenPosition token_pos = location->token_pos();
+#if !defined(DART_PRECOMPILED_RUNTIME)
+  TokenPosition end_token_pos = location->end_token_pos();
+  if (token_pos != end_token_pos && location->requested_column_number() >= 0) {
+    // Narrow down the token position range to a single value
+    // if requested column number is provided so that inner
+    // Closure won't be missed.
+    token_pos = FindExactTokenPosition(script, token_pos,
+                                       location->requested_column_number());
+  }
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
+  const Function& inner_function =
+      Function::Handle(zone, FindInnermostClosure(zone, function, token_pos));
+  if (!inner_function.IsNull()) {
+    if (FLAG_verbose_debug) {
+      OS::PrintErr(
+          "Pending breakpoint remains unresolved in "
+          "inner function '%s'\n",
+          inner_function.ToFullyQualifiedCString());
+    }
+    return false;
+  }
+
+  // There is no local function within function that contains the
+  // breakpoint token position. Resolve the breakpoint if necessary
+  // and set the code breakpoints.
+  if (!location->EnsureIsResolved(function, token_pos)) {
+    // Failed to resolve breakpoint location for some reason
+    return false;
+  }
+  return true;
+}
+
+void GroupDebugger::NotifyCompilation(const Function& function) {
+  if (!function.is_debuggable()) {
+    return;
+  }
+  auto thread = Thread::Current();
+  auto zone = thread->zone();
+
+  // Going through BreakpointLocations of all isolates and debuggers looking
+  // for those that can be resolved and added code breakpoints at now.
+  //
+  // The check below is used instead of breakpoint_locations_lock acquisition.
+  // We don't need to acquire the lock if always run with stopped mutators.
+  // We can't acquire the lock if we run with stopped mutators as that could
+  // result in deadlock.
+  RELEASE_ASSERT(thread->IsInStoppedMutatorsScope());
+  for (intptr_t i = 0; i < breakpoint_locations_.length(); i++) {
+    BreakpointLocation* location = breakpoint_locations_.At(i);
+    if (EnsureLocationIsInFunction(zone, function, location)) {
+      if (FLAG_verbose_debug) {
+        Breakpoint* bpt = location->breakpoints();
+        while (bpt != NULL) {
+          OS::PrintErr("Setting breakpoint %" Pd " for %s '%s'\n", bpt->id(),
+                       function.IsClosureFunction() ? "closure" : "function",
+                       function.ToFullyQualifiedCString());
+          bpt = bpt->next();
+        }
+      }
+      MakeCodeBreakpointAt(function, location);
+    }
+  }
+}
+
+void GroupDebugger::VisitObjectPointers(ObjectPointerVisitor* visitor) {
+  CodeBreakpoint* cbpt = code_breakpoints_;
+  while (cbpt != nullptr) {
+    cbpt->VisitObjectPointers(visitor);
+    cbpt = cbpt->next();
+  }
+}
+
 // static
 void Debugger::VisitObjectPointers(ObjectPointerVisitor* visitor) {
   ASSERT(visitor != NULL);
@@ -3057,11 +3259,6 @@
     loc->VisitObjectPointers(visitor);
     loc = loc->next();
   }
-  CodeBreakpoint* cbpt = code_breakpoints_;
-  while (cbpt != NULL) {
-    cbpt->VisitObjectPointers(visitor);
-    cbpt = cbpt->next();
-  }
   visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(&top_frame_awaiter_));
 }
 
@@ -3102,10 +3299,15 @@
     }
   }
 
+  group_debugger()->Pause();
+  pause_event_ = nullptr;
+}
+
+void GroupDebugger::Pause() {
+  SafepointWriteRwLocker sl(Thread::Current(), code_breakpoints_lock());
   if (needs_breakpoint_cleanup_) {
     RemoveUnlinkedCodeBreakpoints();
   }
-  pause_event_ = NULL;
 }
 
 void Debugger::EnterSingleStepMode() {
@@ -3391,7 +3593,7 @@
   // We will be jumping out of the debugger rather than exiting this
   // function, so prepare the debugger state.
   ClearCachedStackTraces();
-  resume_action_ = kContinue;
+  set_resume_action(kContinue);
   resume_frame_index_ = -1;
   EnterSingleStepMode();
 
@@ -3422,7 +3624,7 @@
   // We will be jumping out of the debugger rather than exiting this
   // function, so prepare the debugger state.
   ClearCachedStackTraces();
-  resume_action_ = kContinue;
+  set_resume_action(kContinue);
   resume_frame_index_ = -1;
   EnterSingleStepMode();
 
@@ -3495,28 +3697,80 @@
   return lib.IsDebuggable();
 }
 
-bool Debugger::IsDebugging(Thread* thread, const Function& func) {
-  // TODO(dartbug.com/36097): We might need to adjust this once we start adding
-  // debugging support to --enable-isolate-groups.
-  auto isolate_group = thread->isolate_group();
+void GroupDebugger::RegisterSingleSteppingDebugger(Thread* thread,
+                                                   const Debugger* debugger) {
+  ASSERT(single_stepping_set_lock()->IsCurrentThreadWriter());
+  single_stepping_set_.Insert(debugger);
+}
 
-  bool has_breakpoint = false;
-  bool is_single_stepping = false;
-  isolate_group->ForEachIsolate(
-      [&](Isolate* isolate) {
-        if (isolate->debugger()->IsStepping()) {
-          is_single_stepping = true;
+void GroupDebugger::UnregisterSingleSteppingDebugger(Thread* thread,
+                                                     const Debugger* debugger) {
+  ASSERT(single_stepping_set_lock()->IsCurrentThreadWriter());
+  single_stepping_set_.Remove(debugger);
+}
+
+bool GroupDebugger::RunUnderReadLockIfNeededCallable(Thread* thread,
+                                                     SafepointRwLock* rw_lock,
+                                                     BoolCallable* callable) {
+  if (thread->IsInStoppedMutatorsScope()) {
+    return callable->Call();
+  }
+
+  SafepointReadRwLocker sl(thread, rw_lock);
+  return callable->Call();
+}
+
+bool GroupDebugger::HasBreakpoint(Thread* thread, const Function& function) {
+  if (RunUnderReadLockIfNeeded(thread, breakpoint_locations_lock(), [&]() {
+        // Check if function has any breakpoints.
+        Script& script = Script::Handle(thread->zone());
+        for (intptr_t i = 0; i < breakpoint_locations_.length(); i++) {
+          BreakpointLocation* location = breakpoint_locations_.At(i);
+          script = location->script();
+          if (FunctionOverlaps(function, script, location->token_pos(),
+                               location->end_token_pos())) {
+            return true;
+          }
         }
-        if (isolate->debugger()->HasBreakpoint(func, thread->zone())) {
-          has_breakpoint = true;
-        }
-      },
-      thread->IsAtSafepoint());
-  return has_breakpoint || is_single_stepping;
+        return false;
+      })) {
+    return true;
+  }
+
+  // TODO(aam): do we have to iterate over both code breakpoints and
+  // breakpoint locations? Wouldn't be sufficient to iterate over only
+  // one list? Could you have a CodeBreakpoint without corresponding
+  // BreakpointLocation?
+  if (HasCodeBreakpointInFunction(function)) {
+    return true;
+  }
+
+  return false;
+}
+
+bool GroupDebugger::IsDebugging(Thread* thread, const Function& function) {
+  if (!RunUnderReadLockIfNeeded(thread, single_stepping_set_lock(), [&]() {
+        return single_stepping_set_.IsEmpty();
+      })) {
+    return true;
+  }
+  return HasBreakpoint(thread, function);
+}
+
+void Debugger::set_resume_action(ResumeAction resume_action) {
+  auto thread = Thread::Current();
+  SafepointWriteRwLocker sl(thread,
+                            group_debugger()->single_stepping_set_lock());
+  if (resume_action == kContinue) {
+    group_debugger()->UnregisterSingleSteppingDebugger(thread, this);
+  } else {
+    group_debugger()->RegisterSingleSteppingDebugger(thread, this);
+  }
+  resume_action_ = resume_action;
 }
 
 void Debugger::SignalPausedEvent(ActivationFrame* top_frame, Breakpoint* bpt) {
-  resume_action_ = kContinue;
+  set_resume_action(kContinue);
   ResetSteppingFramePointers();
   NotifySingleStepping(false);
   ASSERT(!IsPaused());
@@ -3664,7 +3918,7 @@
   // If there is an active breakpoint at this pc, then we should have
   // already bailed out of this function in the skip_next_step_ test
   // above.
-  ASSERT(!HasActiveBreakpoint(frame->pc()));
+  ASSERT(!group_debugger()->HasActiveBreakpoint(frame->pc()));
 
   if (FLAG_verbose_debug) {
     OS::PrintErr(">>> single step break at %s:%" Pd ":%" Pd
@@ -3701,17 +3955,19 @@
   ASSERT(stack_trace->Length() > 0);
   ActivationFrame* top_frame = stack_trace->FrameAt(0);
   ASSERT(top_frame != nullptr);
-  CodeBreakpoint* cbpt = GetCodeBreakpoint(top_frame->pc());
-  ASSERT(cbpt != nullptr);
-
   if (!Library::Handle(top_frame->Library()).IsDebuggable()) {
     return Error::null();
   }
 
-  BreakpointLocation* bpt_location = cbpt->bpt_location_;
+  CodeBreakpoint* cbpt = nullptr;
+  BreakpointLocation* bpt_location =
+      group_debugger()->GetBreakpointLocationFor(this, top_frame->pc(), &cbpt);
   if (bpt_location == nullptr) {
+    // There might be no breakpoint locations for this isolate/debugger.
     return Error::null();
   }
+  ASSERT(cbpt != nullptr);
+
   Breakpoint* bpt_hit = bpt_location->FindHitBreakpoint(top_frame);
   if (bpt_hit == nullptr) {
     return Error::null();
@@ -3726,11 +3982,11 @@
     // Hit a synthetic async breakpoint.
     if (FLAG_verbose_debug) {
       OS::PrintErr(
-          ">>> hit synthetic breakpoint at %s:%" Pd
+          ">>> hit synthetic %s"
           " (func %s token %s address %#" Px " offset %#" Px ")\n",
-          String::Handle(cbpt->SourceUrl()).ToCString(), cbpt->LineNumber(),
+          cbpt->ToCString(),
           String::Handle(top_frame->QualifiedFunctionName()).ToCString(),
-          cbpt->token_pos().ToCString(), top_frame->pc(),
+          bpt_location->token_pos().ToCString(), top_frame->pc(),
           top_frame->pc() - top_frame->code().PayloadStart());
     }
 
@@ -3749,12 +4005,15 @@
   }
 
   if (FLAG_verbose_debug) {
-    OS::PrintErr(">>> hit breakpoint %" Pd " at %s:%" Pd
+    // Lock is needed for CodeBreakpoint::ToCString().
+    SafepointReadRwLocker sl(Thread::Current(),
+                             group_debugger()->code_breakpoints_lock());
+    OS::PrintErr(">>> hit %" Pd
+                 " %s"
                  " (func %s token %s address %#" Px " offset %#" Px ")\n",
-                 bpt_hit->id(), String::Handle(cbpt->SourceUrl()).ToCString(),
-                 cbpt->LineNumber(),
+                 bpt_hit->id(), cbpt->ToCString(),
                  String::Handle(top_frame->QualifiedFunctionName()).ToCString(),
-                 cbpt->token_pos().ToCString(), top_frame->pc(),
+                 bpt_location->token_pos().ToCString(), top_frame->pc(),
                  top_frame->pc() - top_frame->code().PayloadStart());
   }
 
@@ -3837,34 +4096,6 @@
   }
 }
 
-// Return innermost closure contained in 'function' that contains
-// the given token position.
-static FunctionPtr FindInnermostClosure(const Function& function,
-                                        TokenPosition token_pos) {
-  ASSERT(function.end_token_pos().IsReal());
-  const TokenPosition& func_start = function.token_pos();
-  auto thread = Thread::Current();
-  auto zone = thread->zone();
-  const Script& outer_origin = Script::Handle(zone, function.script());
-
-  Function& best_fit = Function::Handle(zone);
-  ClosureFunctionsCache::ForAllClosureFunctions([&](const Function& closure) {
-    const TokenPosition& closure_start = closure.token_pos();
-    const TokenPosition& closure_end = closure.end_token_pos();
-    // We're only interested in closures that have real ending token positions.
-    // The starting token position can be synthetic.
-    if (closure_end.IsReal() && (function.end_token_pos() > closure_end) &&
-        (!closure_start.IsReal() || !func_start.IsReal() ||
-         (closure_start > func_start)) &&
-        token_pos.IsWithin(closure_start, closure_end) &&
-        (closure.script() == outer_origin.ptr())) {
-      UpdateBestFit(&best_fit, closure);
-    }
-    return true;  // Continue iteration.
-  });
-  return best_fit.ptr();
-}
-
 #if !defined(DART_PRECOMPILED_RUNTIME)
 // On single line of code with given column number,
 // Calculate exact tokenPosition
@@ -3881,97 +4112,6 @@
 }
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
-void Debugger::NotifyCompilation(const Function& func) {
-  if (breakpoint_locations_ == NULL) {
-    // Return with minimal overhead if there are no breakpoints.
-    return;
-  }
-  if (!func.is_debuggable()) {
-    // Nothing to do if the function is not debuggable. If there is
-    // a pending breakpoint in an inner function (that is debuggable),
-    // we'll resolve the breakpoint when the inner function is compiled.
-    return;
-  }
-  // Iterate over all source breakpoints to check whether breakpoints
-  // need to be set in the newly compiled function.
-  Zone* zone = Thread::Current()->zone();
-  Script& script = Script::Handle(zone);
-  for (BreakpointLocation* loc = breakpoint_locations_; loc != NULL;
-       loc = loc->next()) {
-    script = loc->script();
-    if (FunctionOverlaps(func, script, loc->token_pos(),
-                         loc->end_token_pos())) {
-      TokenPosition token_pos = loc->token_pos();
-      TokenPosition end_token_pos = loc->end_token_pos();
-      if (token_pos != end_token_pos && loc->requested_column_number() >= 0) {
-#if !defined(DART_PRECOMPILED_RUNTIME)
-        // Narrow down the token position range to a single value
-        // if requested column number is provided so that inner
-        // Closure won't be missed.
-        token_pos = FindExactTokenPosition(script, token_pos,
-                                           loc->requested_column_number());
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
-      }
-      const Function& inner_function =
-          Function::Handle(zone, FindInnermostClosure(func, token_pos));
-      if (!inner_function.IsNull()) {
-        if (FLAG_verbose_debug) {
-          OS::PrintErr(
-              "Pending breakpoint remains unresolved in "
-              "inner function '%s'\n",
-              inner_function.ToFullyQualifiedCString());
-        }
-        continue;
-      }
-
-      // There is no local function within func that contains the
-      // breakpoint token position. Resolve the breakpoint if necessary
-      // and set the code breakpoints.
-      if (!loc->IsResolved()) {
-        // Resolve source breakpoint in the newly compiled function.
-        TokenPosition bp_pos =
-            ResolveBreakpointPos(func, loc->token_pos(), loc->end_token_pos(),
-                                 loc->requested_column_number(), token_pos);
-        if (!bp_pos.IsDebugPause()) {
-          if (FLAG_verbose_debug) {
-            OS::PrintErr("Failed resolving breakpoint for function '%s'\n",
-                         func.ToFullyQualifiedCString());
-          }
-          continue;
-        }
-        TokenPosition requested_pos = loc->token_pos();
-        TokenPosition requested_end_pos = loc->end_token_pos();
-        loc->SetResolved(func, bp_pos);
-        Breakpoint* bpt = loc->breakpoints();
-        while (bpt != NULL) {
-          if (FLAG_verbose_debug) {
-            OS::PrintErr(
-                "Resolved breakpoint %" Pd
-                " to pos %s, function '%s' (requested range %s-%s, "
-                "requested col %" Pd ")\n",
-                bpt->id(), loc->token_pos().ToCString(),
-                func.ToFullyQualifiedCString(), requested_pos.ToCString(),
-                requested_end_pos.ToCString(), loc->requested_column_number());
-          }
-          SendBreakpointEvent(ServiceEvent::kBreakpointResolved, bpt);
-          bpt = bpt->next();
-        }
-      }
-      ASSERT(loc->IsResolved());
-      if (FLAG_verbose_debug) {
-        Breakpoint* bpt = loc->breakpoints();
-        while (bpt != NULL) {
-          OS::PrintErr("Setting breakpoint %" Pd " for %s '%s'\n", bpt->id(),
-                       func.IsClosureFunction() ? "closure" : "function",
-                       func.ToFullyQualifiedCString());
-          bpt = bpt->next();
-        }
-      }
-      MakeCodeBreakpointAt(func, loc);
-    }
-  }
-}
-
 void Debugger::NotifyDoneLoading() {
   if (latent_locations_ == NULL) {
     // Common, fast path.
@@ -4039,9 +4179,9 @@
           if (existing_loc == NULL) {
             // Create and register a new source breakpoint for the
             // latent breakpoint.
-            BreakpointLocation* unresolved_loc =
-                new BreakpointLocation(script, first_token_pos, last_token_pos,
-                                       line_number, column_number);
+            BreakpointLocation* unresolved_loc = new BreakpointLocation(
+                this, script, first_token_pos, last_token_pos, line_number,
+                column_number);
             RegisterBreakpointLocation(unresolved_loc);
 
             // Move breakpoints over.
@@ -4058,7 +4198,7 @@
               }
               bpt = bpt->next();
             }
-            SyncBreakpointLocation(unresolved_loc);
+            group_debugger()->SyncBreakpointLocation(unresolved_loc);
           }
           delete matched_loc;
           // Break out of the iteration over loaded libraries. If the
@@ -4093,12 +4233,13 @@
 
 // TODO(hausner): Could potentially make this faster by checking
 // whether the call target at pc is a debugger stub.
-bool Debugger::HasActiveBreakpoint(uword pc) {
+bool GroupDebugger::HasActiveBreakpoint(uword pc) {
+  SafepointReadRwLocker sl(Thread::Current(), code_breakpoints_lock());
   CodeBreakpoint* cbpt = GetCodeBreakpoint(pc);
-  return (cbpt != NULL) && (cbpt->IsEnabled());
+  return (cbpt != nullptr) && (cbpt->IsEnabled());
 }
 
-CodeBreakpoint* Debugger::GetCodeBreakpoint(uword breakpoint_address) {
+CodeBreakpoint* GroupDebugger::GetCodeBreakpoint(uword breakpoint_address) {
   CodeBreakpoint* cbpt = code_breakpoints_;
   while (cbpt != NULL) {
     if (cbpt->pc() == breakpoint_address) {
@@ -4106,10 +4247,34 @@
     }
     cbpt = cbpt->next();
   }
-  return NULL;
+  return nullptr;
 }
 
-CodePtr Debugger::GetPatchedStubAddress(uword breakpoint_address) {
+BreakpointLocation* GroupDebugger::GetBreakpointLocationFor(
+    Debugger* debugger,
+    uword breakpoint_address,
+    CodeBreakpoint** pcbpt) {
+  ASSERT(pcbpt != nullptr);
+  SafepointReadRwLocker sl(Thread::Current(), code_breakpoints_lock());
+  *pcbpt = code_breakpoints_;
+  while (*pcbpt != nullptr) {
+    if ((*pcbpt)->pc() == breakpoint_address) {
+      return (*pcbpt)->FindBreakpointForDebugger(debugger);
+    }
+    *pcbpt = (*pcbpt)->next();
+  }
+  return nullptr;
+}
+
+void GroupDebugger::RegisterCodeBreakpoint(CodeBreakpoint* cbpt) {
+  ASSERT(cbpt->next() == NULL);
+  DEBUG_ASSERT(code_breakpoints_lock()->IsCurrentThreadWriter());
+  cbpt->set_next(code_breakpoints_);
+  code_breakpoints_ = cbpt;
+}
+
+CodePtr GroupDebugger::GetPatchedStubAddress(uword breakpoint_address) {
+  SafepointReadRwLocker sl(Thread::Current(), code_breakpoints_lock());
   CodeBreakpoint* cbpt = GetCodeBreakpoint(breakpoint_address);
   if (cbpt != NULL) {
     return cbpt->OrigStubAddress();
@@ -4121,6 +4286,8 @@
 // Remove and delete the source breakpoint bpt and its associated
 // code breakpoints.
 void Debugger::RemoveBreakpoint(intptr_t bp_id) {
+  SafepointWriteRwLocker sl(Thread::Current(),
+                            group_debugger()->breakpoint_locations_lock());
   if (RemoveBreakpointFromTheList(bp_id, &breakpoint_locations_)) {
     return;
   }
@@ -4174,8 +4341,9 @@
             // Remove references from code breakpoints to this breakpoint
             // location and disable them.
             // Latent breakpoint locations won't have code breakpoints.
-            UnlinkCodeBreakpoints(curr_loc);
+            group_debugger()->UnlinkCodeBreakpoints(curr_loc);
           }
+          group_debugger()->UnregisterBreakpointLocation(curr_loc);
           BreakpointLocation* next_loc = curr_loc->next();
           delete curr_loc;
           curr_loc = next_loc;
@@ -4196,17 +4364,32 @@
   return false;
 }
 
+void GroupDebugger::RegisterBreakpointLocation(BreakpointLocation* location) {
+  ASSERT(breakpoint_locations_lock()->IsCurrentThreadWriter());
+  breakpoint_locations_.Add(location);
+}
+
+void GroupDebugger::UnregisterBreakpointLocation(BreakpointLocation* location) {
+  ASSERT(breakpoint_locations_lock()->IsCurrentThreadWriter());
+  for (intptr_t i = 0; i < breakpoint_locations_.length(); i++) {
+    if (breakpoint_locations_.At(i) == location) {
+      breakpoint_locations_.EraseAt(i);
+      return;
+    }
+  }
+}
+
 // Unlink code breakpoints from the given breakpoint location.
 // They will later be deleted when control returns from the pause event
 // callback. Also, disable the breakpoint so it no longer fires if it
 // should be hit before it gets deleted.
-void Debugger::UnlinkCodeBreakpoints(BreakpointLocation* bpt_location) {
-  ASSERT(bpt_location != NULL);
+void GroupDebugger::UnlinkCodeBreakpoints(BreakpointLocation* bpt_location) {
+  ASSERT(bpt_location != nullptr);
+  SafepointWriteRwLocker sl(Thread::Current(), code_breakpoints_lock());
   CodeBreakpoint* curr_bpt = code_breakpoints_;
-  while (curr_bpt != NULL) {
-    if (curr_bpt->bpt_location() == bpt_location) {
+  while (curr_bpt != nullptr) {
+    if (curr_bpt->FindAndDeleteBreakpointLocation(bpt_location)) {
       curr_bpt->Disable();
-      curr_bpt->set_bpt_location(NULL);
       needs_breakpoint_cleanup_ = true;
     }
     curr_bpt = curr_bpt->next();
@@ -4215,19 +4398,19 @@
 
 // Remove and delete unlinked code breakpoints, i.e. breakpoints that
 // are not associated with a breakpoint location.
-void Debugger::RemoveUnlinkedCodeBreakpoints() {
-  CodeBreakpoint* prev_bpt = NULL;
+void GroupDebugger::RemoveUnlinkedCodeBreakpoints() {
+  ASSERT(code_breakpoints_lock()->IsCurrentThreadWriter());
+  CodeBreakpoint* prev_bpt = nullptr;
   CodeBreakpoint* curr_bpt = code_breakpoints_;
-  while (curr_bpt != NULL) {
-    if (curr_bpt->bpt_location() == NULL) {
-      if (prev_bpt == NULL) {
+  while (curr_bpt != nullptr) {
+    if (curr_bpt->HasNoBreakpointLocations()) {
+      if (prev_bpt == nullptr) {
         code_breakpoints_ = code_breakpoints_->next();
       } else {
         prev_bpt->set_next(curr_bpt->next());
       }
       CodeBreakpoint* temp_bpt = curr_bpt;
       curr_bpt = curr_bpt->next();
-      temp_bpt->Disable();
       delete temp_bpt;
     } else {
       prev_bpt = curr_bpt;
@@ -4237,6 +4420,20 @@
   needs_breakpoint_cleanup_ = false;
 }
 
+BreakpointLocation* Debugger::GetResolvedBreakpointLocation(
+    const Script& script,
+    TokenPosition code_token_pos) {
+  BreakpointLocation* loc = breakpoint_locations_;
+  while (loc != nullptr) {
+    if (loc->script_ == script.ptr() &&
+        loc->code_token_pos_ == code_token_pos) {
+      return loc;
+    }
+    loc = loc->next();
+  }
+  return nullptr;
+}
+
 BreakpointLocation* Debugger::GetBreakpointLocation(
     const Script& script,
     TokenPosition token_pos,
@@ -4317,22 +4514,19 @@
     loc = loc->next();
   }
   // No breakpoint for this location requested. Allocate new one.
-  loc = new BreakpointLocation(url, line, column);
+  loc = new BreakpointLocation(this, url, line, column);
   loc->set_next(latent_locations_);
   latent_locations_ = loc;
   return loc;
 }
 
 void Debugger::RegisterBreakpointLocation(BreakpointLocation* loc) {
+  SafepointWriteRwLocker sl(Thread::Current(),
+                            group_debugger()->breakpoint_locations_lock());
   ASSERT(loc->next() == NULL);
   loc->set_next(breakpoint_locations_);
   breakpoint_locations_ = loc;
-}
-
-void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* cbpt) {
-  ASSERT(cbpt->next() == NULL);
-  cbpt->set_next(code_breakpoints_);
-  code_breakpoints_ = cbpt;
+  group_debugger()->RegisterBreakpointLocation(loc);
 }
 
 #endif  // !PRODUCT
diff --git a/runtime/vm/debugger.h b/runtime/vm/debugger.h
index 6378fb1..bd2d0de 100644
--- a/runtime/vm/debugger.h
+++ b/runtime/vm/debugger.h
@@ -5,6 +5,8 @@
 #ifndef RUNTIME_VM_DEBUGGER_H_
 #define RUNTIME_VM_DEBUGGER_H_
 
+#include <memory>
+
 #include "include/dart_tools_api.h"
 
 #include "vm/kernel_isolate.h"
@@ -16,6 +18,8 @@
 #include "vm/stack_frame.h"
 #include "vm/stack_trace.h"
 
+#if !defined(PRODUCT)
+
 DECLARE_FLAG(bool, verbose_debug);
 
 // 'Trace Debugger' TD_Print.
@@ -120,20 +124,22 @@
 class BreakpointLocation {
  public:
   // Create a new unresolved breakpoint.
-  BreakpointLocation(const Script& script,
+  BreakpointLocation(Debugger* debugger,
+                     const Script& script,
                      TokenPosition token_pos,
                      TokenPosition end_token_pos,
                      intptr_t requested_line_number,
                      intptr_t requested_column_number);
   // Create a new latent breakpoint.
-  BreakpointLocation(const String& url,
+  BreakpointLocation(Debugger* debugger,
+                     const String& url,
                      intptr_t requested_line_number,
                      intptr_t requested_column_number);
 
   ~BreakpointLocation();
 
-  FunctionPtr function() const { return function_; }
   TokenPosition token_pos() const { return token_pos_; }
+  intptr_t line_number();
   TokenPosition end_token_pos() const { return end_token_pos_; }
 
   ScriptPtr script() const { return script_; }
@@ -154,6 +160,11 @@
   bool IsResolved() const { return code_token_pos_.IsReal(); }
   bool IsLatent() const { return !token_pos_.IsReal(); }
 
+  bool EnsureIsResolved(const Function& target_function,
+                        TokenPosition exact_token_pos);
+
+  Debugger* debugger() { return debugger_; }
+
  private:
   void VisitObjectPointers(ObjectPointerVisitor* visitor);
 
@@ -170,8 +181,13 @@
   // Finds the breakpoint we hit at |location|.
   Breakpoint* FindHitBreakpoint(ActivationFrame* top_frame);
 
+  SafepointRwLock* line_number_lock() { return line_number_lock_.get(); }
+
+  Debugger* debugger_;
   ScriptPtr script_;
   StringPtr url_;
+  std::unique_ptr<SafepointRwLock> line_number_lock_;
+  intptr_t line_number_;  // lazily computed for token_pos_
   TokenPosition token_pos_;
   TokenPosition end_token_pos_;
   BreakpointLocation* next_;
@@ -180,43 +196,72 @@
   intptr_t requested_column_number_;
 
   // Valid for resolved breakpoints:
-  FunctionPtr function_;
   TokenPosition code_token_pos_;
 
   friend class Debugger;
+  friend class GroupDebugger;
   DISALLOW_COPY_AND_ASSIGN(BreakpointLocation);
 };
 
 // CodeBreakpoint represents a location in compiled code.
 // There may be more than one CodeBreakpoint for one BreakpointLocation,
 // e.g. when a function gets compiled as a regular function and as a closure.
+// There may be more than one BreakpointLocation associated with CodeBreakpoint,
+// one for for every isolate in a group that sets a breakpoint at particular
+// code location represented by the CodeBreakpoint.
+// Each BreakpointLocation might be enabled/disabled based on whether it has
+// any actual breakpoints associated with it.
+// The CodeBreakpoint is enabled if it has any such BreakpointLocations
+// associated with it.
+// The class is not thread-safe - users of this class need to ensure the access
+// is synchronized, guarded by mutexes or run inside of a safepoint scope.
 class CodeBreakpoint {
  public:
+  // Unless CodeBreakpoint is unlinked and is no longer used there should be at
+  // least one BreakpointLocation associated with CodeBreakpoint. If there are
+  // more BreakpointLocation added assumption is is that all of them point to
+  // the same source so have the same token pos.
   CodeBreakpoint(const Code& code,
-                 TokenPosition token_pos,
+                 BreakpointLocation* loc,
                  uword pc,
                  UntaggedPcDescriptors::Kind kind);
   ~CodeBreakpoint();
 
-  FunctionPtr function() const;
-  uword pc() const { return pc_; }
-  TokenPosition token_pos() const { return token_pos_; }
+  // Used by GroupDebugger to find CodeBreakpoint associated with
+  // particular function.
+  FunctionPtr function() const { return Code::Handle(code_).function(); }
 
-  ScriptPtr SourceCode();
-  StringPtr SourceUrl();
-  intptr_t LineNumber();
+  uword pc() const { return pc_; }
+  bool HasBreakpointLocation(BreakpointLocation* breakpoint_location);
+  bool FindAndDeleteBreakpointLocation(BreakpointLocation* breakpoint_location);
+  bool HasNoBreakpointLocations() {
+    return breakpoint_locations_.length() == 0;
+  }
 
   void Enable();
   void Disable();
-  bool IsEnabled() const { return is_enabled_; }
+  bool IsEnabled() const { return enabled_count_ > 0; }
 
   CodePtr OrigStubAddress() const;
 
+  const char* ToCString() const;
+
  private:
   void VisitObjectPointers(ObjectPointerVisitor* visitor);
 
-  BreakpointLocation* bpt_location() const { return bpt_location_; }
-  void set_bpt_location(BreakpointLocation* value) { bpt_location_ = value; }
+  // Finds right BreakpointLocation for a given Isolate's debugger.
+  BreakpointLocation* FindBreakpointForDebugger(Debugger* debugger);
+  // Adds new BreakpointLocation for another isolate that wants to
+  // break at the same function/code location that this CodeBreakpoint
+  // represents.
+  void AddBreakpointLocation(BreakpointLocation* breakpoint_location) {
+    ASSERT(breakpoint_locations_.length() == 0 ||
+           (breakpoint_location->token_pos() ==
+                breakpoint_locations_.At(0)->token_pos() &&
+            breakpoint_location->script() ==
+                breakpoint_locations_.At(0)->script()));
+    breakpoint_locations_.Add(breakpoint_location);
+  }
 
   void set_next(CodeBreakpoint* value) { next_ = value; }
   CodeBreakpoint* next() const { return this->next_; }
@@ -225,18 +270,19 @@
   void RestoreCode();
 
   CodePtr code_;
-  TokenPosition token_pos_;
   uword pc_;
-  intptr_t line_number_;
-  bool is_enabled_;
+  int enabled_count_;  // incremented for every enabled breakpoint location
 
-  BreakpointLocation* bpt_location_;
+  // Breakpoint locations from different debuggers/isolates that
+  // point to this code breakpoint.
+  MallocGrowableArray<BreakpointLocation*> breakpoint_locations_;
   CodeBreakpoint* next_;
 
   UntaggedPcDescriptors::Kind breakpoint_kind_;
   CodePtr saved_value_;
 
   friend class Debugger;
+  friend class GroupDebugger;
   DISALLOW_COPY_AND_ASSIGN(CodeBreakpoint);
 };
 
@@ -473,6 +519,159 @@
   kInvalidExceptionPauseInfo
 } Dart_ExceptionPauseInfo;
 
+class DebuggerKeyValueTrait : public AllStatic {
+ public:
+  typedef const Debugger* Key;
+  typedef bool Value;
+
+  struct Pair {
+    Key key;
+    Value value;
+    Pair() : key(NULL), value(false) {}
+    Pair(const Key key, const Value& value) : key(key), value(value) {}
+    Pair(const Pair& other) : key(other.key), value(other.value) {}
+    Pair& operator=(const Pair&) = default;
+  };
+
+  static Key KeyOf(Pair kv) { return kv.key; }
+  static Value ValueOf(Pair kv) { return kv.value; }
+  static intptr_t Hashcode(Key key) { return reinterpret_cast<intptr_t>(key); }
+  static bool IsKeyEqual(Pair kv, Key key) { return kv.key == key; }
+};
+
+class DebuggerSet : public MallocDirectChainedHashMap<DebuggerKeyValueTrait> {
+ public:
+  typedef DebuggerKeyValueTrait::Key Key;
+  typedef DebuggerKeyValueTrait::Value Value;
+  typedef DebuggerKeyValueTrait::Pair Pair;
+
+  virtual ~DebuggerSet() { Clear(); }
+
+  void Insert(const Key& key) {
+    Pair pair(key, /*value=*/true);
+    MallocDirectChainedHashMap<DebuggerKeyValueTrait>::Insert(pair);
+  }
+
+  void Remove(const Key& key) {
+    MallocDirectChainedHashMap<DebuggerKeyValueTrait>::Remove(key);
+  }
+};
+
+class BoolCallable : public ValueObject {
+ public:
+  BoolCallable() {}
+  virtual ~BoolCallable() {}
+
+  virtual bool Call() = 0;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(BoolCallable);
+};
+
+template <typename T>
+class LambdaBoolCallable : public BoolCallable {
+ public:
+  explicit LambdaBoolCallable(T& lambda) : lambda_(lambda) {}
+  bool Call() { return lambda_(); }
+
+ private:
+  T& lambda_;
+  DISALLOW_COPY_AND_ASSIGN(LambdaBoolCallable);
+};
+
+class GroupDebugger {
+ public:
+  explicit GroupDebugger(IsolateGroup* isolate_group);
+  ~GroupDebugger();
+
+  void MakeCodeBreakpointAt(const Function& func, BreakpointLocation* bpt);
+
+  // Returns [nullptr] if no breakpoint exists for the given address.
+  CodeBreakpoint* GetCodeBreakpoint(uword breakpoint_address);
+  BreakpointLocation* GetBreakpointLocationFor(Debugger* debugger,
+                                               uword breakpoint_address,
+                                               CodeBreakpoint** pcbpt);
+  CodePtr GetPatchedStubAddress(uword breakpoint_address);
+
+  void RegisterBreakpointLocation(BreakpointLocation* location);
+  void UnregisterBreakpointLocation(BreakpointLocation* location);
+
+  void RemoveBreakpointLocation(BreakpointLocation* bpt_location);
+  void UnlinkCodeBreakpoints(BreakpointLocation* bpt_location);
+
+  // Returns true if the call at address pc is patched to point to
+  // a debugger stub.
+  bool HasActiveBreakpoint(uword pc);
+  bool HasCodeBreakpointInFunction(const Function& func);
+  bool HasCodeBreakpointInCode(const Code& code);
+
+  bool HasBreakpointInFunction(const Function& func);
+  bool HasBreakpointInCode(const Code& code);
+
+  void SyncBreakpointLocation(BreakpointLocation* loc);
+
+  void Pause();
+
+  bool EnsureLocationIsInFunction(Zone* zone,
+                                  const Function& function,
+                                  BreakpointLocation* location);
+  void NotifyCompilation(const Function& func);
+
+  void VisitObjectPointers(ObjectPointerVisitor* visitor);
+
+  SafepointRwLock* code_breakpoints_lock() {
+    return code_breakpoints_lock_.get();
+  }
+
+  SafepointRwLock* breakpoint_locations_lock() {
+    return breakpoint_locations_lock_.get();
+  }
+
+  SafepointRwLock* single_stepping_set_lock() {
+    return single_stepping_set_lock_.get();
+  }
+  void RegisterSingleSteppingDebugger(Thread* thread, const Debugger* debugger);
+  void UnregisterSingleSteppingDebugger(Thread* thread,
+                                        const Debugger* debugger);
+
+  bool RunUnderReadLockIfNeededCallable(Thread* thread,
+                                        SafepointRwLock* rw_lock,
+                                        BoolCallable* callable);
+
+  template <typename T>
+  bool RunUnderReadLockIfNeeded(Thread* thread,
+                                SafepointRwLock* rw_lock,
+                                T function) {
+    LambdaBoolCallable<T> callable(function);
+    return RunUnderReadLockIfNeededCallable(thread, rw_lock, &callable);
+  }
+
+  // Returns [true] if there is at least one breakpoint set in function or code.
+  // Checks for both user-defined and internal temporary breakpoints.
+  bool HasBreakpoint(Thread* thread, const Function& function);
+  bool IsDebugging(Thread* thread, const Function& function);
+
+ private:
+  IsolateGroup* isolate_group_;
+
+  std::unique_ptr<SafepointRwLock> code_breakpoints_lock_;
+  CodeBreakpoint* code_breakpoints_;
+
+  // Secondary list of all breakpoint_locations_(primary is in Debugger class).
+  // This list is kept in sync with all the lists in Isolate Debuggers and is
+  // used to quickly scan BreakpointLocations when new Function is compiled.
+  std::unique_ptr<SafepointRwLock> breakpoint_locations_lock_;
+  MallocGrowableArray<BreakpointLocation*> breakpoint_locations_;
+
+  std::unique_ptr<SafepointRwLock> single_stepping_set_lock_;
+  DebuggerSet single_stepping_set_;
+
+  void RemoveUnlinkedCodeBreakpoints();
+  void RegisterCodeBreakpoint(CodeBreakpoint* bpt);
+
+  bool needs_breakpoint_cleanup_;
+};
+
 class Debugger {
  public:
   enum ResumeAction {
@@ -490,7 +689,6 @@
   void NotifyIsolateCreated();
   void Shutdown();
 
-  void NotifyCompilation(const Function& func);
   void NotifyDoneLoading();
 
   // Set breakpoint at closest location to function entry.
@@ -555,17 +753,6 @@
 
   void VisitObjectPointers(ObjectPointerVisitor* visitor);
 
-  // Returns true if there is at least one breakpoint set in func or code.
-  // Checks for both user-defined and internal temporary breakpoints.
-  // This may be called from different threads, therefore do not use the,
-  // debugger's zone.
-  bool HasBreakpoint(const Function& func, Zone* zone);
-  bool HasBreakpoint(const Code& code);
-
-  // Returns true if the call at address pc is patched to point to
-  // a debugger stub.
-  bool HasActiveBreakpoint(uword pc);
-
   // Returns a stack trace with frames corresponding to invisible functions
   // omitted. CurrentStackTrace always returns a new trace on the current stack.
   // The trace returned by StackTrace may have been cached; it is suitable for
@@ -595,16 +782,11 @@
   // Dart.
   void PauseDeveloper(const String& msg);
 
-  CodePtr GetPatchedStubAddress(uword breakpoint_address);
-
   void PrintBreakpointsToJSONArray(JSONArray* jsarr) const;
   void PrintSettingsToJSONObject(JSONObject* jsobj) const;
 
   static bool IsDebuggable(const Function& func);
 
-  // IsolateGroupDebugger::
-  static bool IsDebugging(Thread* thread, const Function& func);
-
   intptr_t limitBreakpointId() { return next_id_; }
 
   // Callback to the debugger to continue frame rewind, post-deoptimization.
@@ -621,17 +803,14 @@
 
   void SendBreakpointEvent(ServiceEvent::EventKind kind, Breakpoint* bpt);
 
-  // IsolateGroupDebugger::
   void FindCompiledFunctions(const Script& script,
                              TokenPosition start_pos,
                              TokenPosition end_pos,
                              GrowableObjectArray* code_function_list);
-  // IsolateGroupDebugger::
   bool FindBestFit(const Script& script,
                    TokenPosition token_pos,
                    TokenPosition last_token_pos,
                    Function* best_fit);
-  // IsolateGroupDebugger::
   void DeoptimizeWorld();
   void NotifySingleStepping(bool value) const;
   BreakpointLocation* SetCodeBreakpoints(const Script& script,
@@ -649,24 +828,20 @@
                                     const Function& function);
   bool RemoveBreakpointFromTheList(intptr_t bp_id, BreakpointLocation** list);
   Breakpoint* GetBreakpointByIdInTheList(intptr_t id, BreakpointLocation* list);
-  void RemoveUnlinkedCodeBreakpoints();
-  void UnlinkCodeBreakpoints(BreakpointLocation* bpt_location);
   BreakpointLocation* GetLatentBreakpoint(const String& url,
                                           intptr_t line,
                                           intptr_t column);
   void RegisterBreakpointLocation(BreakpointLocation* bpt);
-  void RegisterCodeBreakpoint(CodeBreakpoint* bpt);
+  BreakpointLocation* GetResolvedBreakpointLocation(
+      const Script& script,
+      TokenPosition code_token_pos);
   BreakpointLocation* GetBreakpointLocation(
       const Script& script,
       TokenPosition token_pos,
       intptr_t requested_line,
       intptr_t requested_column,
       TokenPosition code_token_pos = TokenPosition::kNoSource);
-  void MakeCodeBreakpointAt(const Function& func, BreakpointLocation* bpt);
-  // Returns NULL if no breakpoint exists for the given address.
-  CodeBreakpoint* GetCodeBreakpoint(uword breakpoint_address);
 
-  void SyncBreakpointLocation(BreakpointLocation* loc);
   void PrintBreakpointsListToJSONArray(BreakpointLocation* sbpt,
                                        JSONArray* jsarr) const;
 
@@ -702,6 +877,8 @@
   void SetAsyncSteppingFramePointer(DebuggerStackTrace* stack_trace);
   void SetSyncSteppingFramePointer(DebuggerStackTrace* stack_trace);
 
+  GroupDebugger* group_debugger() { return isolate_->group()->debugger(); }
+
   Isolate* isolate_;
 
   // ID number generator.
@@ -709,10 +886,10 @@
 
   BreakpointLocation* latent_locations_;
   BreakpointLocation* breakpoint_locations_;
-  CodeBreakpoint* code_breakpoints_;
 
   // Tells debugger what to do when resuming execution after a breakpoint.
   ResumeAction resume_action_;
+  void set_resume_action(ResumeAction action);
   intptr_t resume_frame_index_;
   intptr_t post_deopt_frame_index_;
 
@@ -751,8 +928,6 @@
   // breakpoint.
   bool skip_next_step_;
 
-  bool needs_breakpoint_cleanup_;
-
   // We keep this breakpoint alive until after the debugger does the step over
   // async continuation machinery so that we can report that we've stopped
   // at the breakpoint.
@@ -787,4 +962,6 @@
 
 }  // namespace dart
 
+#endif  // !defined(PRODUCT)
+
 #endif  // RUNTIME_VM_DEBUGGER_H_
diff --git a/runtime/vm/debugger_arm.cc b/runtime/vm/debugger_arm.cc
index 7fe5605..675c98e 100644
--- a/runtime/vm/debugger_arm.cc
+++ b/runtime/vm/debugger_arm.cc
@@ -20,7 +20,7 @@
 }
 
 void CodeBreakpoint::PatchCode() {
-  ASSERT(!is_enabled_);
+  ASSERT(!IsEnabled());
   Code& stub_target = Code::Handle();
   switch (breakpoint_kind_) {
     case UntaggedPcDescriptors::kIcCall:
@@ -38,11 +38,10 @@
   const Code& code = Code::Handle(code_);
   saved_value_ = CodePatcher::GetStaticCallTargetAt(pc_, code);
   CodePatcher::PatchStaticCallAt(pc_, code, stub_target);
-  is_enabled_ = true;
 }
 
 void CodeBreakpoint::RestoreCode() {
-  ASSERT(is_enabled_);
+  ASSERT(IsEnabled());
   const Code& code = Code::Handle(code_);
   switch (breakpoint_kind_) {
     case UntaggedPcDescriptors::kIcCall:
@@ -54,7 +53,6 @@
     default:
       UNREACHABLE();
   }
-  is_enabled_ = false;
 }
 
 #endif  // !PRODUCT
diff --git a/runtime/vm/debugger_arm64.cc b/runtime/vm/debugger_arm64.cc
index d3f251b..17cb472 100644
--- a/runtime/vm/debugger_arm64.cc
+++ b/runtime/vm/debugger_arm64.cc
@@ -20,7 +20,7 @@
 }
 
 void CodeBreakpoint::PatchCode() {
-  ASSERT(!is_enabled_);
+  ASSERT(!IsEnabled());
   const Code& code = Code::Handle(code_);
   switch (breakpoint_kind_) {
     case UntaggedPcDescriptors::kIcCall: {
@@ -45,11 +45,10 @@
     default:
       UNREACHABLE();
   }
-  is_enabled_ = true;
 }
 
 void CodeBreakpoint::RestoreCode() {
-  ASSERT(is_enabled_);
+  ASSERT(IsEnabled());
   const Code& code = Code::Handle(code_);
   switch (breakpoint_kind_) {
     case UntaggedPcDescriptors::kIcCall: {
@@ -68,7 +67,6 @@
     default:
       UNREACHABLE();
   }
-  is_enabled_ = false;
 }
 
 #endif  // !PRODUCT
diff --git a/runtime/vm/debugger_ia32.cc b/runtime/vm/debugger_ia32.cc
index f9de84f..f244a34 100644
--- a/runtime/vm/debugger_ia32.cc
+++ b/runtime/vm/debugger_ia32.cc
@@ -24,7 +24,7 @@
 }
 
 void CodeBreakpoint::PatchCode() {
-  ASSERT(!is_enabled_);
+  ASSERT(!IsEnabled());
   auto thread = Thread::Current();
   auto zone = thread->zone();
   const Code& code = Code::Handle(zone, code_);
@@ -52,11 +52,10 @@
     saved_value_ = CodePatcher::GetStaticCallTargetAt(pc_, code);
     CodePatcher::PatchStaticCallAt(pc_, code, stub_target);
   });
-  is_enabled_ = true;
 }
 
 void CodeBreakpoint::RestoreCode() {
-  ASSERT(is_enabled_);
+  ASSERT(IsEnabled());
   auto thread = Thread::Current();
   auto zone = thread->zone();
   const Code& code = Code::Handle(zone, code_);
@@ -74,7 +73,6 @@
         UNREACHABLE();
     }
   });
-  is_enabled_ = false;
 }
 
 #endif  // !PRODUCT
diff --git a/runtime/vm/debugger_x64.cc b/runtime/vm/debugger_x64.cc
index 7a0e046..a6161a0 100644
--- a/runtime/vm/debugger_x64.cc
+++ b/runtime/vm/debugger_x64.cc
@@ -21,7 +21,7 @@
 }
 
 void CodeBreakpoint::PatchCode() {
-  ASSERT(!is_enabled_);
+  ASSERT(!IsEnabled());
   Code& stub_target = Code::Handle();
   switch (breakpoint_kind_) {
     case UntaggedPcDescriptors::kIcCall:
@@ -39,11 +39,10 @@
   const Code& code = Code::Handle(code_);
   saved_value_ = CodePatcher::GetStaticCallTargetAt(pc_, code);
   CodePatcher::PatchPoolPointerCallAt(pc_, code, stub_target);
-  is_enabled_ = true;
 }
 
 void CodeBreakpoint::RestoreCode() {
-  ASSERT(is_enabled_);
+  ASSERT(IsEnabled());
   const Code& code = Code::Handle(code_);
   switch (breakpoint_kind_) {
     case UntaggedPcDescriptors::kIcCall:
@@ -56,7 +55,6 @@
     default:
       UNREACHABLE();
   }
-  is_enabled_ = false;
 }
 
 #endif  // !PRODUCT
diff --git a/runtime/vm/deferred_objects.cc b/runtime/vm/deferred_objects.cc
index 6452f3f..4b21ce5 100644
--- a/runtime/vm/deferred_objects.cc
+++ b/runtime/vm/deferred_objects.cc
@@ -394,9 +394,16 @@
                   static_cast<uint64_t>(Integer::Cast(value).AsInt64Value()));
               break;
             case kTypedDataFloat32ArrayCid:
-              typed_data.SetFloat32(
-                  element_offset,
-                  static_cast<float>(Double::Cast(value).value()));
+              // Although element of Float32 array is represented with Double,
+              // it is already converted to 32-bit float via DoubleToFloat
+              // instruction before it was stored.
+              // Reinterpret double value as float to get the value back.
+              union {
+                double d;
+                float f;
+              } v;
+              v.d = Double::Cast(value).value();
+              typed_data.SetFloat32(element_offset, v.f);
               break;
             case kTypedDataFloat64ArrayCid:
               typed_data.SetFloat64(element_offset,
diff --git a/runtime/vm/experimental_features.cc b/runtime/vm/experimental_features.cc
index e341195..57eb309 100644
--- a/runtime/vm/experimental_features.cc
+++ b/runtime/vm/experimental_features.cc
@@ -18,7 +18,7 @@
 
 bool GetExperimentalFeatureDefault(ExperimentalFeature feature) {
   constexpr bool kFeatureValues[] = {
-      true, true, true, true, true, true,
+      true, true, true, true, true, true, true,
   };
   ASSERT(static_cast<size_t>(feature) < ARRAY_SIZE(kFeatureValues));
   return kFeatureValues[static_cast<int>(feature)];
@@ -26,9 +26,10 @@
 
 const char* GetExperimentalFeatureName(ExperimentalFeature feature) {
   constexpr const char* kFeatureNames[] = {
-      "non-nullable",         "extension-methods",
-      "constant-update-2018", "control-flow-collections",
-      "set-literals",         "spread-collections",
+      "nonfunction-type-aliases", "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)];
diff --git a/runtime/vm/experimental_features.h b/runtime/vm/experimental_features.h
index 8efd29e..d6816b3 100644
--- a/runtime/vm/experimental_features.h
+++ b/runtime/vm/experimental_features.h
@@ -14,6 +14,7 @@
 namespace dart {
 
 enum class ExperimentalFeature {
+  nonfunction_type_aliases,
   non_nullable,
   extension_methods,
   constant_update_2018,
diff --git a/runtime/vm/flag_list.h b/runtime/vm/flag_list.h
index c118e0f..59226e1 100644
--- a/runtime/vm/flag_list.h
+++ b/runtime/vm/flag_list.h
@@ -110,6 +110,8 @@
     "Deoptimizes we are about to return to Dart code from native entries.")    \
   C(deoptimize_every, 0, 0, int, 0,                                            \
     "Deoptimize on every N stack overflow checks")                             \
+  P(deoptimize_on_runtime_call_every, int, 0,                                  \
+    "Deoptimize functions on every runtime call.")                             \
   R(disable_alloc_stubs_after_gc, false, bool, false, "Stress testing flag.")  \
   R(dump_megamorphic_stats, false, bool, false,                                \
     "Dump megamorphic cache statistics")                                       \
diff --git a/runtime/vm/hash_map.h b/runtime/vm/hash_map.h
index 88d58ba..5af4c15 100644
--- a/runtime/vm/hash_map.h
+++ b/runtime/vm/hash_map.h
@@ -5,6 +5,7 @@
 #ifndef RUNTIME_VM_HASH_MAP_H_
 #define RUNTIME_VM_HASH_MAP_H_
 
+#include "platform/utils.h"
 #include "vm/growable_array.h"  // For Malloc, EmptyBase
 #include "vm/hash.h"
 #include "vm/zone.h"
@@ -439,6 +440,20 @@
   void operator=(const MallocDirectChainedHashMap& other) = delete;
 };
 
+template <typename KeyValueTrait>
+class ZoneDirectChainedHashMap
+    : public BaseDirectChainedHashMap<KeyValueTrait, ZoneAllocated, Zone> {
+ public:
+  ZoneDirectChainedHashMap()
+      : BaseDirectChainedHashMap<KeyValueTrait, ZoneAllocated, Zone>(
+            ThreadState::Current()->zone()) {}
+  explicit ZoneDirectChainedHashMap(Zone* zone)
+      : BaseDirectChainedHashMap<KeyValueTrait, ZoneAllocated, Zone>(zone) {}
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(ZoneDirectChainedHashMap);
+};
+
 template <typename T>
 class PointerKeyValueTrait {
  public:
@@ -489,8 +504,47 @@
   static bool IsKeyEqual(Pair kv, Key key) { return kv.key == key; }
 };
 
+class CStringSetKeyValueTrait : public PointerKeyValueTrait<const char> {
+ public:
+  using Key = PointerKeyValueTrait<const char>::Key;
+  using Value = PointerKeyValueTrait<const char>::Value;
+  using Pair = PointerKeyValueTrait<const char>::Pair;
+
+  static intptr_t Hashcode(Key key) {
+    ASSERT(key != nullptr);
+    return Utils::StringHash(key, strlen(key));
+  }
+  static bool IsKeyEqual(Pair kv, Key key) {
+    ASSERT(kv != nullptr && key != nullptr);
+    return kv == key || strcmp(kv, key) == 0;
+  }
+};
+
+template <typename B, typename Allocator>
+class BaseCStringSet
+    : public BaseDirectChainedHashMap<CStringSetKeyValueTrait, B, Allocator> {
+ public:
+  explicit BaseCStringSet(Allocator* allocator)
+      : BaseDirectChainedHashMap<CStringSetKeyValueTrait, B, Allocator>(
+            allocator) {}
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(BaseCStringSet);
+};
+
+class ZoneCStringSet : public BaseCStringSet<ZoneAllocated, Zone> {
+ public:
+  ZoneCStringSet()
+      : BaseCStringSet<ZoneAllocated, Zone>(ThreadState::Current()->zone()) {}
+  explicit ZoneCStringSet(Zone* zone)
+      : BaseCStringSet<ZoneAllocated, Zone>(zone) {}
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(ZoneCStringSet);
+};
+
 template <typename V>
-class CStringKeyValueTrait : public RawPointerKeyValueTrait<const char, V> {
+class CStringMapKeyValueTrait : public RawPointerKeyValueTrait<const char, V> {
  public:
   typedef typename RawPointerKeyValueTrait<const char, V>::Key Key;
   typedef typename RawPointerKeyValueTrait<const char, V>::Value Value;
@@ -498,11 +552,7 @@
 
   static intptr_t Hashcode(Key key) {
     ASSERT(key != nullptr);
-    intptr_t hash = 0;
-    for (size_t i = 0; i < strlen(key); i++) {
-      hash = CombineHashes(hash, key[i]);
-    }
-    return FinalizeHash(hash, kBitsPerWord - 1);
+    return Utils::StringHash(key, strlen(key));
   }
   static bool IsKeyEqual(Pair kv, Key key) {
     ASSERT(kv.key != nullptr && key != nullptr);
@@ -510,12 +560,27 @@
   }
 };
 
-template <typename V>
-class CStringMap : public DirectChainedHashMap<CStringKeyValueTrait<V>> {
+template <typename V, typename B, typename Allocator>
+class BaseCStringMap
+    : public BaseDirectChainedHashMap<CStringMapKeyValueTrait<V>,
+                                      B,
+                                      Allocator> {
  public:
-  CStringMap() : DirectChainedHashMap<CStringKeyValueTrait<V>>() {}
+  explicit BaseCStringMap(Allocator* allocator)
+      : BaseDirectChainedHashMap<CStringMapKeyValueTrait<V>, B, Allocator>(
+            allocator) {}
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(BaseCStringMap);
+};
+
+template <typename V>
+class CStringMap : public BaseCStringMap<V, ValueObject, Zone> {
+ public:
+  CStringMap()
+      : BaseCStringMap<V, ValueObject, Zone>(ThreadState::Current()->zone()) {}
   explicit CStringMap(Zone* zone)
-      : DirectChainedHashMap<CStringKeyValueTrait<V>>(zone) {}
+      : BaseCStringMap<V, ValueObject, Zone>(zone) {}
 
  private:
   DISALLOW_COPY_AND_ASSIGN(CStringMap);
diff --git a/runtime/vm/hash_map_test.cc b/runtime/vm/hash_map_test.cc
index b6d6f57..27385d9 100644
--- a/runtime/vm/hash_map_test.cc
+++ b/runtime/vm/hash_map_test.cc
@@ -114,6 +114,22 @@
   EXPECT(map2.LookupValue(&v3) == &v1);
 }
 
+TEST_CASE(ZoneDirectChainedHashMap) {
+  auto zone = thread->zone();
+  auto const map = new (zone)
+      ZoneDirectChainedHashMap<PointerKeyValueTrait<TestValue>>(zone);
+  EXPECT(map->IsEmpty());
+  TestValue v1(0);
+  TestValue v2(1);
+  TestValue v3(0);
+  map->Insert(&v1);
+  EXPECT(map->LookupValue(&v1) == &v1);
+  map->Insert(&v2);
+  EXPECT(map->LookupValue(&v1) == &v1);
+  EXPECT(map->LookupValue(&v2) == &v2);
+  EXPECT(map->LookupValue(&v3) == &v1);
+}
+
 class IntptrPair {
  public:
   IntptrPair() : first_(-1), second_(-1) {}
@@ -206,6 +222,43 @@
   }
 }
 
+TEST_CASE(ZoneCStringSet) {
+  auto zone = thread->zone();
+
+  const char* const kConst1 = "test";
+  const char* const kConst2 = "test 2";
+
+  char* const str1 = OS::SCreate(zone, "%s", kConst1);
+  char* const str2 = OS::SCreate(zone, "%s", kConst2);
+  char* const str3 = OS::SCreate(zone, "%s", kConst1);
+
+  // Make sure these strings are pointer-distinct, but C-string-equal.
+  EXPECT_NE(str1, str3);
+  EXPECT_STREQ(str1, str3);
+
+  auto const set = new (zone) ZoneCStringSet(zone);
+  EXPECT(set->IsEmpty());
+
+  set->Insert(str1);
+  EXPECT_NOTNULL(set->Lookup(str1));
+  EXPECT_NULLPTR(set->Lookup(str2));
+  EXPECT_NOTNULL(set->Lookup(str3));
+
+  set->Insert(str2);
+  EXPECT_NOTNULL(set->Lookup(str1));
+  EXPECT_NOTNULL(set->Lookup(str2));
+  EXPECT_NOTNULL(set->Lookup(str3));
+
+  EXPECT(set->Remove(str3));
+  EXPECT_NULLPTR(set->Lookup(str1));
+  EXPECT_NOTNULL(set->Lookup(str2));
+  EXPECT_NULLPTR(set->Lookup(str3));
+
+  EXPECT(!set->Remove(str3));
+  EXPECT(set->Remove(str2));
+  EXPECT(set->IsEmpty());
+}
+
 TEST_CASE(CStringMap) {
   const char* const kConst1 = "test";
   const char* const kConst2 = "test 2";
@@ -270,9 +323,9 @@
   EXPECT_STREQ(str1, str3);
   EXPECT_STREQ(str1, str4);
 
-  CStringKeyValueTrait<intptr_t>::Pair p1 = {str1, 1};
-  CStringKeyValueTrait<intptr_t>::Pair p2 = {str2, 2};
-  CStringKeyValueTrait<intptr_t>::Pair p3 = {str3, 3};
+  CStringMapKeyValueTrait<intptr_t>::Pair p1 = {str1, 1};
+  CStringMapKeyValueTrait<intptr_t>::Pair p2 = {str2, 2};
+  CStringMapKeyValueTrait<intptr_t>::Pair p3 = {str3, 3};
 
   CStringMap<intptr_t> map;
   EXPECT(map.IsEmpty());
diff --git a/runtime/vm/hash_table.h b/runtime/vm/hash_table.h
index ef89556..06fbd70 100644
--- a/runtime/vm/hash_table.h
+++ b/runtime/vm/hash_table.h
@@ -10,6 +10,37 @@
 
 namespace dart {
 
+// Storage traits control how memory is allocated for HashTable.
+// Default ArrayStorageTraits use an Array to store HashTable contents.
+struct ArrayStorageTraits {
+  using ArrayHandle = Array;
+  using ArrayPtr = dart::ArrayPtr;
+
+  static ArrayHandle& PtrToHandle(ArrayPtr ptr) { return Array::Handle(ptr); }
+
+  static void SetHandle(ArrayHandle& dst, const ArrayHandle& src) {  // NOLINT
+    dst = src.ptr();
+  }
+
+  static void ClearHandle(ArrayHandle& handle) {  // NOLINT
+    handle = Array::null();
+  }
+
+  static ArrayPtr New(Zone* zone, intptr_t length, Heap::Space space) {
+    return Array::New(length, space);
+  }
+
+  static bool IsImmutable(const ArrayHandle& handle) {
+    return handle.ptr()->untag()->InVMIsolateHeap();
+  }
+};
+
+class HashTableBase : public ValueObject {
+ public:
+  static const Object& UnusedMarker() { return Object::transition_sentinel(); }
+  static const Object& DeletedMarker() { return Object::sentinel(); }
+};
+
 // OVERVIEW:
 //
 // Hash maps and hash sets all use RawArray as backing storage. At the lowest
@@ -71,29 +102,34 @@
 //    uword Hash(const Key& key) for any number of desired lookup key types.
 //  kPayloadSize: number of components of the payload in each entry.
 //  kMetaDataSize: number of elements reserved (e.g., for iteration order data).
-template <typename KeyTraits, intptr_t kPayloadSize, intptr_t kMetaDataSize>
-class HashTable : public ValueObject {
+template <typename KeyTraits,
+          intptr_t kPayloadSize,
+          intptr_t kMetaDataSize,
+          typename StorageTraits = ArrayStorageTraits>
+class HashTable : public HashTableBase {
  public:
   typedef KeyTraits Traits;
+  typedef StorageTraits Storage;
+
   // Uses the passed in handles for all handle operations.
   // 'Release' must be called at the end to obtain the final table
   // after potential growth/shrinkage.
-  HashTable(Object* key, Smi* index, Array* data)
+  HashTable(Object* key, Smi* index, typename StorageTraits::ArrayHandle* data)
       : key_handle_(key),
         smi_handle_(index),
         data_(data),
         released_data_(NULL) {}
   // Uses 'zone' for handle allocation. 'Release' must be called at the end
   // to obtain the final table after potential growth/shrinkage.
-  HashTable(Zone* zone, ArrayPtr data)
+  HashTable(Zone* zone, typename StorageTraits::ArrayPtr data)
       : key_handle_(&Object::Handle(zone)),
         smi_handle_(&Smi::Handle(zone)),
-        data_(&Array::Handle(zone, data)),
+        data_(&StorageTraits::PtrToHandle(data)),
         released_data_(NULL) {}
 
   // Returns the final table. The handle is cleared when this HashTable is
   // destroyed.
-  Array& Release() {
+  typename StorageTraits::ArrayHandle& Release() {
     ASSERT(data_ != NULL);
     ASSERT(released_data_ == NULL);
     // Ensure that no methods are called after 'Release'.
@@ -106,7 +142,7 @@
     // In DEBUG mode, calling 'Release' is mandatory.
     ASSERT(data_ == NULL);
     if (released_data_ != NULL) {
-      *released_data_ = Array::null();
+      StorageTraits::ClearHandle(*released_data_);
     }
   }
 
@@ -245,9 +281,6 @@
     NOT_IN_PRECOMPILED(ASSERT(NumOccupied() < NumEntries()));
   }
 
-  const Object& UnusedMarker() const { return Object::transition_sentinel(); }
-  const Object& DeletedMarker() const { return *data_; }
-
   bool IsUnused(intptr_t entry) const {
     return InternalGetKey(entry) == UnusedMarker().ptr();
   }
@@ -314,7 +347,7 @@
   }
   void UpdateCollisions(intptr_t collisions) const {
     if (KeyTraits::ReportStats()) {
-      if (data_->ptr()->untag()->InVMIsolateHeap()) {
+      if (Storage::IsImmutable(*data_)) {
         return;
       }
       AdjustSmiValueAt(kNumProbesIndex, collisions + 1);
@@ -403,10 +436,17 @@
   Object* key_handle_;
   Smi* smi_handle_;
   // Exactly one of these is non-NULL, depending on whether Release was called.
-  Array* data_;
-  Array* released_data_;
+  typename StorageTraits::ArrayHandle* data_;
+  typename StorageTraits::ArrayHandle* released_data_;
 
   friend class HashTables;
+  template <typename Table, bool kAllCanonicalObjectsAreIncludedIntoSet>
+  friend class CanonicalSetDeserializationCluster;
+  template <typename Table,
+            typename HandleType,
+            typename PointerType,
+            bool kAllCanonicalObjectsAreIncludedIntoSet>
+  friend class CanonicalSetSerializationCluster;
 };
 
 // Table with unspecified iteration order. No payload overhead or metadata.
@@ -448,17 +488,20 @@
  public:
   // Allocates and initializes a table.
   template <typename Table>
-  static ArrayPtr New(intptr_t initial_capacity,
-                      Heap::Space space = Heap::kNew) {
+  static typename Table::Storage::ArrayPtr New(intptr_t initial_capacity,
+                                               Heap::Space space = Heap::kNew) {
+    auto zone = Thread::Current()->zone();
     Table table(
-        Thread::Current()->zone(),
-        Array::New(Table::ArrayLengthForNumOccupied(initial_capacity), space));
+        zone,
+        Table::Storage::New(
+            zone, Table::ArrayLengthForNumOccupied(initial_capacity), space));
     table.Initialize();
     return table.Release().ptr();
   }
 
   template <typename Table>
-  static ArrayPtr New(const Array& array) {
+  static typename Table::Storage::ArrayPtr New(
+      const typename Table::Storage::ArrayHandle& array) {
     Table table(Thread::Current()->zone(), array.ptr());
     table.Initialize();
     return table.Release().ptr();
@@ -513,7 +556,7 @@
     Table new_table(New<Table>(new_capacity,  // Is rounded up to power of 2.
                                table.data_->IsOld() ? Heap::kOld : Heap::kNew));
     Copy(table, new_table);
-    *table.data_ = new_table.Release().ptr();
+    Table::Storage::SetHandle(*table.data_, new_table.Release());
     NOT_IN_PRODUCT(table.UpdateGrowth(); table.PrintStats();)
   }
 
@@ -547,7 +590,8 @@
       for (intptr_t i = 0; i < table.Length(); i++) {
         element = table.At(i);
         if (!element.IsSmi()) {
-          element = WeakSerializationReference::New(element, table);
+          element = WeakSerializationReference::New(
+              element, HashTableBase::DeletedMarker());
           table.SetAt(i, element);
         }
       }
diff --git a/runtime/vm/heap/compactor.cc b/runtime/vm/heap/compactor.cc
index 7006f3e..462a9d2 100644
--- a/runtime/vm/heap/compactor.cc
+++ b/runtime/vm/heap/compactor.cc
@@ -275,7 +275,7 @@
     for (intptr_t i = 0; i < length; ++i) {
       auto raw_view = typed_data_views_[i];
       const classid_t cid =
-          raw_view->untag()->typed_data_->GetClassIdMayBeSmi();
+          raw_view->untag()->typed_data()->GetClassIdMayBeSmi();
 
       // If we have external typed data we can simply return, since the backing
       // store lives in C-heap and will not move. Otherwise we have to update
@@ -668,12 +668,12 @@
 }
 
 void GCCompactor::VisitTypedDataViewPointers(TypedDataViewPtr view,
-                                             ObjectPtr* first,
-                                             ObjectPtr* last) {
+                                             CompressedObjectPtr* first,
+                                             CompressedObjectPtr* last) {
   // First we forward all fields of the typed data view.
-  ObjectPtr old_backing = view->untag()->typed_data_;
-  VisitPointers(first, last);
-  ObjectPtr new_backing = view->untag()->typed_data_;
+  ObjectPtr old_backing = view->untag()->typed_data();
+  VisitCompressedPointers(view->heap_base(), first, last);
+  ObjectPtr new_backing = view->untag()->typed_data();
 
   const bool backing_moved = old_backing != new_backing;
   if (backing_moved) {
@@ -694,9 +694,9 @@
     // The backing store didn't move, we therefore don't need to update the
     // inner pointer.
     if (view->untag()->data_ == 0) {
-      ASSERT(RawSmiValue(view->untag()->offset_in_bytes_) == 0 &&
-             RawSmiValue(view->untag()->length_) == 0 &&
-             view->untag()->typed_data_ == Object::null());
+      ASSERT(RawSmiValue(view->untag()->offset_in_bytes()) == 0 &&
+             RawSmiValue(view->untag()->length()) == 0 &&
+             view->untag()->typed_data() == Object::null());
     }
   }
 }
diff --git a/runtime/vm/heap/compactor.h b/runtime/vm/heap/compactor.h
index 9dfa96d..164c214 100644
--- a/runtime/vm/heap/compactor.h
+++ b/runtime/vm/heap/compactor.h
@@ -40,8 +40,8 @@
   void ForwardPointer(ObjectPtr* ptr);
   void ForwardCompressedPointer(uword heap_base, CompressedObjectPtr* ptr);
   void VisitTypedDataViewPointers(TypedDataViewPtr view,
-                                  ObjectPtr* first,
-                                  ObjectPtr* last);
+                                  CompressedObjectPtr* first,
+                                  CompressedObjectPtr* last);
   void VisitPointers(ObjectPtr* first, ObjectPtr* last);
   void VisitCompressedPointers(uword heap_base,
                                CompressedObjectPtr* first,
diff --git a/runtime/vm/heap/heap.cc b/runtime/vm/heap/heap.cc
index f730542..52d1f65 100644
--- a/runtime/vm/heap/heap.cc
+++ b/runtime/vm/heap/heap.cc
@@ -990,64 +990,70 @@
 #ifndef PRODUCT
   // For now we'll emit the same GC events on all isolates.
   if (Service::gc_stream.enabled()) {
-    isolate_group_->ForEachIsolate([&](Isolate* isolate) {
-      if (!Isolate::IsSystemIsolate(isolate)) {
-        ServiceEvent event(isolate, ServiceEvent::kGC);
-        event.set_gc_stats(&stats_);
-        Service::HandleEvent(&event);
-      }
-    });
+    isolate_group_->ForEachIsolate(
+        [&](Isolate* isolate) {
+          if (!Isolate::IsSystemIsolate(isolate)) {
+            ServiceEvent event(isolate, ServiceEvent::kGC);
+            event.set_gc_stats(&stats_);
+            Service::HandleEvent(&event);
+          }
+        },
+        /*at_safepoint=*/true);
   }
 #endif  // !PRODUCT
   if (Dart::gc_event_callback() != nullptr) {
-    isolate_group_->ForEachIsolate([&](Isolate* isolate) {
-      if (!Isolate::IsSystemIsolate(isolate)) {
-        Dart_GCEvent event;
-        auto isolate_id = Utils::CStringUniquePtr(
-            OS::SCreate(nullptr, ISOLATE_SERVICE_ID_FORMAT_STRING,
-                        isolate->main_port()),
-            std::free);
-        int64_t isolate_uptime_micros = isolate->UptimeMicros();
+    isolate_group_->ForEachIsolate(
+        [&](Isolate* isolate) {
+          if (!Isolate::IsSystemIsolate(isolate)) {
+            Dart_GCEvent event;
+            auto isolate_id = Utils::CStringUniquePtr(
+                OS::SCreate(nullptr, ISOLATE_SERVICE_ID_FORMAT_STRING,
+                            isolate->main_port()),
+                std::free);
+            int64_t isolate_uptime_micros = isolate->UptimeMicros();
 
-        event.isolate_id = isolate_id.get();
-        event.type = GCTypeToString(stats_.type_);
-        event.reason = GCReasonToString(stats_.reason_);
+            event.isolate_id = isolate_id.get();
+            event.type = GCTypeToString(stats_.type_);
+            event.reason = GCReasonToString(stats_.reason_);
 
-        // New space - Scavenger.
-        {
-          intptr_t new_space_collections = new_space_.collections();
+            // New space - Scavenger.
+            {
+              intptr_t new_space_collections = new_space_.collections();
 
-          event.new_space.collections = new_space_collections;
-          event.new_space.used = stats_.after_.new_.used_in_words * kWordSize;
-          event.new_space.capacity =
-              stats_.after_.new_.capacity_in_words * kWordSize;
-          event.new_space.external =
-              stats_.after_.new_.external_in_words * kWordSize;
-          event.new_space.time =
-              MicrosecondsToSeconds(new_space_.gc_time_micros());
-          event.new_space.avg_collection_period =
-              AvgCollectionPeriod(isolate_uptime_micros, new_space_collections);
-        }
+              event.new_space.collections = new_space_collections;
+              event.new_space.used =
+                  stats_.after_.new_.used_in_words * kWordSize;
+              event.new_space.capacity =
+                  stats_.after_.new_.capacity_in_words * kWordSize;
+              event.new_space.external =
+                  stats_.after_.new_.external_in_words * kWordSize;
+              event.new_space.time =
+                  MicrosecondsToSeconds(new_space_.gc_time_micros());
+              event.new_space.avg_collection_period = AvgCollectionPeriod(
+                  isolate_uptime_micros, new_space_collections);
+            }
 
-        // Old space - Page.
-        {
-          intptr_t old_space_collections = old_space_.collections();
+            // Old space - Page.
+            {
+              intptr_t old_space_collections = old_space_.collections();
 
-          event.old_space.collections = old_space_collections;
-          event.old_space.used = stats_.after_.old_.used_in_words * kWordSize;
-          event.old_space.capacity =
-              stats_.after_.old_.capacity_in_words * kWordSize;
-          event.old_space.external =
-              stats_.after_.old_.external_in_words * kWordSize;
-          event.old_space.time =
-              MicrosecondsToSeconds(old_space_.gc_time_micros());
-          event.old_space.avg_collection_period =
-              AvgCollectionPeriod(isolate_uptime_micros, old_space_collections);
-        }
+              event.old_space.collections = old_space_collections;
+              event.old_space.used =
+                  stats_.after_.old_.used_in_words * kWordSize;
+              event.old_space.capacity =
+                  stats_.after_.old_.capacity_in_words * kWordSize;
+              event.old_space.external =
+                  stats_.after_.old_.external_in_words * kWordSize;
+              event.old_space.time =
+                  MicrosecondsToSeconds(old_space_.gc_time_micros());
+              event.old_space.avg_collection_period = AvgCollectionPeriod(
+                  isolate_uptime_micros, old_space_collections);
+            }
 
-        (*Dart::gc_event_callback())(&event);
-      }
-    });
+            (*Dart::gc_event_callback())(&event);
+          }
+        },
+        /*at_safepoint=*/true);
   }
 }
 
diff --git a/runtime/vm/heap/scavenger.cc b/runtime/vm/heap/scavenger.cc
index e4807d5..f0dee56 100644
--- a/runtime/vm/heap/scavenger.cc
+++ b/runtime/vm/heap/scavenger.cc
@@ -122,14 +122,30 @@
         delayed_weak_properties_(WeakProperty::null()) {}
 
   virtual void VisitTypedDataViewPointers(TypedDataViewPtr view,
-                                          ObjectPtr* first,
-                                          ObjectPtr* last) {
-    // First we forward all fields of the typed data view.
-    VisitPointers(first, last);
+                                          CompressedObjectPtr* first,
+                                          CompressedObjectPtr* last) {
+    // TypedDataViews require extra processing to update their
+    // PointerBase::data_ pointer. If the underlying typed data is external, no
+    // update is needed. If the underlying typed data is internal, the pointer
+    // must be updated if the typed data was copied or promoted. We cannot
+    // safely dereference the underlying typed data to make this distinction.
+    // It may have been forwarded by a different scavanger worker, so the access
+    // could have a data race. Rather than checking the CID of the underlying
+    // typed data, which requires dereferencing the copied/promoted header, we
+    // compare the view's internal pointer to what it should be if the
+    // underlying typed data was internal, and assume that external typed data
+    // never points into the Dart heap. We must do this before VisitPointers
+    // because we want to compare the old pointer and old typed data.
+    const bool is_external =
+        view->untag()->data_ != view->untag()->DataFieldForInternalTypedData();
+
+    // Forward all fields of the typed data view.
+    VisitCompressedPointers(view->heap_base(), first, last);
 
     if (view->untag()->data_ == nullptr) {
-      ASSERT(RawSmiValue(view->untag()->offset_in_bytes_) == 0 &&
-             RawSmiValue(view->untag()->length_) == 0);
+      ASSERT(RawSmiValue(view->untag()->offset_in_bytes()) == 0 &&
+             RawSmiValue(view->untag()->length()) == 0);
+      ASSERT(is_external);
       return;
     }
 
@@ -140,23 +156,27 @@
     ASSERT(IsTypedDataViewClassId(view->GetClassIdMayBeSmi()));
 
     // Validate that the backing store is not a forwarding word.
-    TypedDataBasePtr td = view->untag()->typed_data_;
+    TypedDataBasePtr td = view->untag()->typed_data();
     ASSERT(td->IsHeapObject());
     const uword td_header =
         *reinterpret_cast<uword*>(UntaggedObject::ToAddr(td));
     ASSERT(!IsForwarding(td_header) || td->IsOldObject());
 
-    // We can always obtain the class id from the forwarded backing store.
-    const classid_t cid = td->GetClassId();
+    if (!parallel) {
+      // When there is only one worker, there is no data race.
+      ASSERT_EQUAL(IsExternalTypedDataClassId(td->GetClassId()), is_external);
+    }
 
     // If we have external typed data we can simply return since the backing
     // store lives in C-heap and will not move.
-    if (IsExternalTypedDataClassId(cid)) {
+    if (is_external) {
       return;
     }
 
     // Now we update the inner pointer.
-    ASSERT(IsTypedDataClassId(cid));
+    if (!parallel) {
+      ASSERT(IsTypedDataClassId(td->GetClassId()));
+    }
     view->untag()->RecomputeDataFieldForInternalTypedData();
   }
 
@@ -319,8 +339,8 @@
       // of this object. Note this could be a publishing store even if the
       // object was promoted by an early invocation of ScavengePointer. Compare
       // Object::Allocate.
-      reinterpret_cast<std::atomic<ObjectPtr>*>(p)->store(
-          new_obj, std::memory_order_release);
+      reinterpret_cast<std::atomic<CompressedObjectPtr>*>(p)->store(
+          static_cast<CompressedObjectPtr>(new_obj), std::memory_order_release);
     } else {
       *p = new_obj;
     }
@@ -650,6 +670,7 @@
 }
 
 intptr_t SemiSpace::CachedSize() {
+  MutexLocker ml(page_cache_mutex);
   return page_cache_size * kNewPageSize;
 }
 
@@ -887,7 +908,20 @@
   void VisitCompressedPointers(uword heap_base,
                                CompressedObjectPtr* from,
                                CompressedObjectPtr* to) {
-    UNREACHABLE();  // Store buffer blocks are not compressed.
+    for (CompressedObjectPtr* ptr = from; ptr <= to; ptr++) {
+      ObjectPtr raw_obj = ptr->Decompress(heap_base);
+      if (raw_obj->IsHeapObject() && raw_obj->IsNewObject()) {
+        if (!is_remembered_) {
+          FATAL3(
+              "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",
+              static_cast<uword>(visiting_), static_cast<uword>(raw_obj), ptr);
+        }
+        RELEASE_ASSERT(to_->Contains(UntaggedObject::ToAddr(raw_obj)));
+      }
+    }
   }
 
  private:
diff --git a/runtime/vm/heap/weak_code.cc b/runtime/vm/heap/weak_code.cc
index c482fe7..44730a3 100644
--- a/runtime/vm/heap/weak_code.cc
+++ b/runtime/vm/heap/weak_code.cc
@@ -66,7 +66,8 @@
   return;
 #else
   // Ensure mutators see empty code_objects only after code was deoptimized.
-  SafepointWriteRwLocker ml(thread, thread->isolate_group()->program_lock());
+  DEBUG_ASSERT(
+      IsolateGroup::Current()->program_lock()->IsCurrentThreadWriter());
 
   if (code_objects.IsNull()) {
     return;
@@ -76,20 +77,22 @@
   // Deoptimize stacks and disable code with mutators stopped.
   isolate_group->RunWithStoppedMutators([&]() {
     Code& code = Code::Handle();
-    isolate_group->ForEachIsolate([&](Isolate* isolate) {
-      auto mutator_thread = isolate->mutator_thread();
-      DartFrameIterator iterator(
-          mutator_thread, StackFrameIterator::kAllowCrossThreadIteration);
-      StackFrame* frame = iterator.NextFrame();
-      while (frame != nullptr) {
-        code = frame->LookupDartCode();
-        if (IsOptimizedCode(code_objects, code)) {
-          ReportDeoptimization(code);
-          DeoptimizeAt(mutator_thread, code, frame);
-        }
-        frame = iterator.NextFrame();
-      }
-    });
+    isolate_group->ForEachIsolate(
+        [&](Isolate* isolate) {
+          auto mutator_thread = isolate->mutator_thread();
+          DartFrameIterator iterator(
+              mutator_thread, StackFrameIterator::kAllowCrossThreadIteration);
+          StackFrame* frame = iterator.NextFrame();
+          while (frame != nullptr) {
+            code = frame->LookupDartCode();
+            if (IsOptimizedCode(code_objects, code)) {
+              ReportDeoptimization(code);
+              DeoptimizeAt(mutator_thread, code, frame);
+            }
+            frame = iterator.NextFrame();
+          }
+        },
+        /*at_safepoint=*/true);
 
     // Switch functions that use dependent code to unoptimized code.
     WeakProperty& weak_property = WeakProperty::Handle();
diff --git a/runtime/vm/image_snapshot.cc b/runtime/vm/image_snapshot.cc
index 6147404..f20022e 100644
--- a/runtime/vm/image_snapshot.cc
+++ b/runtime/vm/image_snapshot.cc
@@ -535,9 +535,9 @@
       RELEASE_ASSERT(String::GetCachedHash(str.ptr()) != 0);
       RELEASE_ASSERT(str.IsOneByteString() || str.IsTwoByteString());
 
-      stream->WriteTargetWord(static_cast<uword>(str.ptr()->untag()->length_));
+      stream->WriteTargetWord(static_cast<uword>(str.ptr()->untag()->length()));
 #if !defined(HASH_IN_OBJECT_HEADER)
-      stream->WriteTargetWord(static_cast<uword>(str.ptr()->untag()->hash_));
+      stream->WriteTargetWord(static_cast<uword>(str.ptr()->untag()->hash()));
 #endif
       ASSERT_EQUAL(stream->Position() - object_start,
                    compiler::target::String::InstanceSize());
@@ -557,7 +557,7 @@
   }
 }
 
-static UNLESS_DEBUG(constexpr) const uword kReadOnlyGCBits =
+static constexpr uword kReadOnlyGCBits =
     UntaggedObject::OldBit::encode(true) |
     UntaggedObject::OldAndNotMarkedBit::encode(false) |
     UntaggedObject::OldAndNotRememberedBit::encode(true) |
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index 1cb8896..69ae961 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -386,7 +386,12 @@
       boxed_field_list_(GrowableObjectArray::null()),
       program_lock_(new SafepointRwLock()),
       active_mutators_monitor_(new Monitor()),
-      max_active_mutators_(Scavenger::MaxMutatorThreadCount()) {
+      max_active_mutators_(Scavenger::MaxMutatorThreadCount())
+#if !defined(PRODUCT)
+      ,
+      debugger_(new GroupDebugger(this))
+#endif
+{
   FlagsCopyFrom(api_flags);
   const bool is_vm_isolate = Dart::VmIsolateNameEquals(source_->name);
   if (!is_vm_isolate) {
@@ -425,6 +430,11 @@
     }
     delete[] obfuscation_map_;
   }
+
+#if !defined(PRODUCT)
+  delete debugger_;
+  debugger_ = nullptr;
+#endif
 }
 
 void IsolateGroup::RegisterIsolate(Isolate* isolate) {
@@ -1728,6 +1738,7 @@
 #undef ISOLATE_METRIC_CONSTRUCTORS
 #endif  // !defined(PRODUCT)
           start_time_micros_(OS::GetCurrentMonotonicMicros()),
+      message_notify_callback_(nullptr),
       on_shutdown_callback_(Isolate::ShutdownCallback()),
       on_cleanup_callback_(Isolate::CleanupCallback()),
       random_(),
@@ -2528,7 +2539,7 @@
   }
 
   // Cache these two fields, since they are no longer available after the
-  // `delete this` further down.
+  // `delete isolate` further down.
   IsolateGroup* isolate_group = isolate->isolate_group_;
   Dart_IsolateCleanupCallback cleanup = isolate->on_cleanup_callback();
   auto callback_data = isolate->init_callback_data_;
@@ -2721,20 +2732,27 @@
 void IsolateGroup::ForEachIsolate(
     std::function<void(Isolate* isolate)> function,
     bool at_safepoint) {
+  auto thread = Thread::Current();
   if (at_safepoint) {
-    ASSERT(Thread::Current()->IsAtSafepoint() ||
-           (Thread::Current()->task_kind() == Thread::kMutatorTask) ||
-           (Thread::Current()->task_kind() == Thread::kMarkerTask) ||
-           (Thread::Current()->task_kind() == Thread::kCompactorTask) ||
-           (Thread::Current()->task_kind() == Thread::kScavengerTask));
+    ASSERT(thread->IsAtSafepoint() ||
+           (thread->task_kind() == Thread::kMutatorTask) ||
+           (thread->task_kind() == Thread::kMarkerTask) ||
+           (thread->task_kind() == Thread::kCompactorTask) ||
+           (thread->task_kind() == Thread::kScavengerTask));
     for (Isolate* isolate : isolates_) {
       function(isolate);
     }
-  } else {
-    SafepointReadRwLocker ml(Thread::Current(), isolates_lock_.get());
+    return;
+  }
+  if (thread != nullptr && thread->IsAtSafepoint()) {
     for (Isolate* isolate : isolates_) {
       function(isolate);
     }
+    return;
+  }
+  SafepointReadRwLocker ml(thread, isolates_lock_.get());
+  for (Isolate* isolate : isolates_) {
+    function(isolate);
   }
 }
 
@@ -2752,6 +2770,7 @@
     Callable* otherwise,
     bool use_force_growth_in_otherwise) {
   auto thread = Thread::Current();
+  StoppedMutatorsScope stopped_mutators_scope(thread);
 
   if (thread->IsMutatorThread() && !IsolateGroup::AreIsolateGroupsEnabled()) {
     single_current_mutator->Call();
@@ -2811,6 +2830,12 @@
 
   NOT_IN_PRECOMPILED(background_compiler()->VisitPointers(visitor));
 
+#if !defined(PRODUCT)
+  if (debugger() != nullptr) {
+    debugger()->VisitObjectPointers(visitor);
+  }
+#endif
+
 #if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
   // Visit objects that are being used for isolate reload.
   if (program_reload_context() != nullptr) {
diff --git a/runtime/vm/isolate.h b/runtime/vm/isolate.h
index d146eac..fd19306 100644
--- a/runtime/vm/isolate.h
+++ b/runtime/vm/isolate.h
@@ -51,6 +51,7 @@
 class Debugger;
 class DeoptContext;
 class ExternalTypedData;
+class GroupDebugger;
 class HandleScope;
 class HandleVisitor;
 class Heap;
@@ -344,6 +345,10 @@
 #endif
   }
 
+#if !defined(PRODUCT)
+  GroupDebugger* debugger() const { return debugger_; }
+#endif
+
   IdleTimeHandler* idle_time_handler() { return &idle_time_handler_; }
 
   // Returns true if this is the first isolate registered.
@@ -938,6 +943,8 @@
   intptr_t active_mutators_ = 0;
   intptr_t waiting_mutators_ = 0;
   intptr_t max_active_mutators_ = 0;
+
+  NOT_IN_PRODUCT(GroupDebugger* debugger_ = nullptr);
 };
 
 // When an isolate sends-and-exits this class represent things that it passed
@@ -1017,11 +1024,11 @@
   }
 
   Dart_MessageNotifyCallback message_notify_callback() const {
-    return message_notify_callback_;
+    return message_notify_callback_.load(std::memory_order_relaxed);
   }
 
   void set_message_notify_callback(Dart_MessageNotifyCallback value) {
-    message_notify_callback_ = value;
+    message_notify_callback_.store(value, std::memory_order_release);
   }
 
   void set_on_shutdown_callback(Dart_IsolateShutdownCallback value) {
@@ -1587,7 +1594,7 @@
 
   // All other fields go here.
   int64_t start_time_micros_;
-  Dart_MessageNotifyCallback message_notify_callback_ = nullptr;
+  std::atomic<Dart_MessageNotifyCallback> message_notify_callback_;
   Dart_IsolateShutdownCallback on_shutdown_callback_ = nullptr;
   Dart_IsolateCleanupCallback on_cleanup_callback_ = nullptr;
   char* name_ = nullptr;
diff --git a/runtime/vm/isolate_reload.cc b/runtime/vm/isolate_reload.cc
index 68a4fdc..a5bd97f 100644
--- a/runtime/vm/isolate_reload.cc
+++ b/runtime/vm/isolate_reload.cc
@@ -2694,7 +2694,6 @@
 
     // Now it's our turn to request reload.
     ASSERT(reloading_thread_ == nullptr);
-    ASSERT(isolates_checked_in_ == 0);
     reloading_thread_ = Thread::Current();
 
     // At this point no isolate register/unregister, so we save the current
diff --git a/runtime/vm/kernel_binary.h b/runtime/vm/kernel_binary.h
index 472de49..29eae67 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 = 56;
-static const uint32_t kMaxSupportedKernelFormatVersion = 56;
+static const uint32_t kMinSupportedKernelFormatVersion = 60;
+static const uint32_t kMaxSupportedKernelFormatVersion = 60;
 
 // Keep in sync with package:kernel/lib/binary/tag.dart
 #define KERNEL_TAG_LIST(V)                                                     \
@@ -118,7 +118,6 @@
   V(AsyncForInStatement, 80)                                                   \
   V(AssertBlock, 81)                                                           \
   V(TypedefType, 87)                                                           \
-  V(BottomType, 89)                                                            \
   V(NeverType, 98)                                                             \
   V(InvalidType, 90)                                                           \
   V(DynamicType, 91)                                                           \
@@ -132,6 +131,7 @@
   V(InstanceGet, 118)                                                          \
   V(InstanceSet, 119)                                                          \
   V(InstanceInvocation, 120)                                                   \
+  V(InstanceGetterInvocation, 89)                                              \
   V(InstanceTearOff, 121)                                                      \
   V(DynamicGet, 122)                                                           \
   V(DynamicSet, 123)                                                           \
diff --git a/runtime/vm/kernel_loader.cc b/runtime/vm/kernel_loader.cc
index 7a1788d..c9ff576 100644
--- a/runtime/vm/kernel_loader.cc
+++ b/runtime/vm/kernel_loader.cc
@@ -1171,6 +1171,7 @@
       helper_.ReadTag();                     // read tag.
       helper_.SkipCanonicalNameReference();  // skip canonical name.
       helper_.SkipStringReference();         // skip name.
+      helper_.SkipListOfExpressions();       // skip annotations.
       helper_.ReadUInt();                    // read source uri index.
       helper_.ReadPosition();                // read file offset.
       helper_.SkipTypeParametersList();      // skip type parameter list.
@@ -1424,6 +1425,9 @@
                                Object::null_function_type(),
                                type_parameter_count, klass->nnbd_mode());
 
+  T.LoadAndSetupBounds(&active_class_, Object::null_function(), *klass,
+                       Object::null_function_type(), type_parameter_count);
+
   // Set super type.  Some classes (e.g., Object) do not have one.
   Tag type_tag = helper_.ReadTag();  // read super class type (part 1).
   if (type_tag == kSomething) {
diff --git a/runtime/vm/lockers.cc b/runtime/vm/lockers.cc
index a39f0c6..c3b35f3 100644
--- a/runtime/vm/lockers.cc
+++ b/runtime/vm/lockers.cc
@@ -108,6 +108,12 @@
 bool SafepointRwLock::EnterRead() {
   // No need to safepoint if the current thread is not attached.
   auto thread = Thread::Current();
+  // Attempt to acquire a lock while owning a safepoint could lead to a deadlock
+  // (some other thread might be forced to a safepoint while holding this lock).
+  ASSERT(thread == nullptr ||
+         !thread->isolate_group()->safepoint_handler()->IsOwnedByTheThread(
+             thread));
+
   const bool can_block_without_safepoint = thread == nullptr;
 
   bool acquired_read_lock = false;
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index dc3e61d..6eff1b4 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -529,7 +529,8 @@
     uword address = heap->Allocate(Instance::InstanceSize(), Heap::kOld);
     null_ = static_cast<InstancePtr>(address + kHeapObjectTag);
     // The call below is using 'null_' to initialize itself.
-    InitializeObject(address, kNullCid, Instance::InstanceSize());
+    InitializeObject(address, kNullCid, Instance::InstanceSize(),
+                     /*compressed*/ false);
     null_->untag()->SetCanonical();
   }
 
@@ -540,14 +541,16 @@
   {
     // Allocate a dummy bool object to give true the desired alignment.
     uword address = heap->Allocate(Bool::InstanceSize(), Heap::kOld);
-    InitializeObject(address, kBoolCid, Bool::InstanceSize());
+    InitializeObject(address, kBoolCid, Bool::InstanceSize(),
+                     /*compressed*/ false);
     static_cast<BoolPtr>(address + kHeapObjectTag)->untag()->value_ = false;
   }
   {
     // Allocate true.
     uword address = heap->Allocate(Bool::InstanceSize(), Heap::kOld);
     true_ = static_cast<BoolPtr>(address + kHeapObjectTag);
-    InitializeObject(address, kBoolCid, Bool::InstanceSize());
+    InitializeObject(address, kBoolCid, Bool::InstanceSize(),
+                     /*compressed*/ false);
     true_->untag()->value_ = true;
     true_->untag()->SetCanonical();
   }
@@ -555,7 +558,8 @@
     // Allocate false.
     uword address = heap->Allocate(Bool::InstanceSize(), Heap::kOld);
     false_ = static_cast<BoolPtr>(address + kHeapObjectTag);
-    InitializeObject(address, kBoolCid, Bool::InstanceSize());
+    InitializeObject(address, kBoolCid, Bool::InstanceSize(),
+                     /*compressed*/ false);
     false_->untag()->value_ = false;
     false_->untag()->SetCanonical();
   }
@@ -569,6 +573,9 @@
   ASSERT((static_cast<uword>(false_) & kBoolValueMask) != 0);
   ASSERT(static_cast<uword>(false_) ==
          (static_cast<uword>(true_) | kBoolValueMask));
+  ASSERT((static_cast<uword>(null_) & kBoolVsNullMask) == 0);
+  ASSERT((static_cast<uword>(true_) & kBoolVsNullMask) != 0);
+  ASSERT((static_cast<uword>(false_) & kBoolVsNullMask) != 0);
 }
 
 void Object::InitVtables() {
@@ -701,7 +708,7 @@
     intptr_t size = Class::InstanceSize();
     uword address = heap->Allocate(size, Heap::kOld);
     class_class_ = static_cast<ClassPtr>(address + kHeapObjectTag);
-    InitializeObject(address, Class::kClassId, size);
+    InitializeObject(address, Class::kClassId, size, /*compressed*/ true);
 
     Class fake;
     // Initialization from Class::New<Class>.
@@ -761,19 +768,19 @@
 
   // Allocate and initialize the sentinel values.
   {
-    *sentinel_ ^=
-        Object::Allocate(kNeverCid, Instance::InstanceSize(), Heap::kOld);
+    *sentinel_ ^= Object::Allocate(kNeverCid, Instance::InstanceSize(),
+                                   Heap::kOld, /*compressed*/ false);
 
-    *transition_sentinel_ ^=
-        Object::Allocate(kNeverCid, Instance::InstanceSize(), Heap::kOld);
+    *transition_sentinel_ ^= Object::Allocate(
+        kNeverCid, Instance::InstanceSize(), Heap::kOld, /*compressed*/ false);
   }
 
   // Allocate and initialize optimizing compiler constants.
   {
-    *unknown_constant_ ^=
-        Object::Allocate(kNeverCid, Instance::InstanceSize(), Heap::kOld);
-    *non_constant_ ^=
-        Object::Allocate(kNeverCid, Instance::InstanceSize(), Heap::kOld);
+    *unknown_constant_ ^= Object::Allocate(kNeverCid, Instance::InstanceSize(),
+                                           Heap::kOld, /*compressed*/ false);
+    *non_constant_ ^= Object::Allocate(kNeverCid, Instance::InstanceSize(),
+                                       Heap::kOld, /*compressed*/ false);
   }
 
   // Allocate the remaining VM internal classes.
@@ -923,7 +930,8 @@
   // Allocate and initialize the empty_array instance.
   {
     uword address = heap->Allocate(Array::InstanceSize(0), Heap::kOld);
-    InitializeObject(address, kImmutableArrayCid, Array::InstanceSize(0));
+    InitializeObject(address, kImmutableArrayCid, Array::InstanceSize(0),
+                     /*compressed*/ false);
     Array::initializeHandle(empty_array_,
                             static_cast<ArrayPtr>(address + kHeapObjectTag));
     empty_array_->untag()->set_length(Smi::New(0));
@@ -934,7 +942,8 @@
   // Allocate and initialize the zero_array instance.
   {
     uword address = heap->Allocate(Array::InstanceSize(1), Heap::kOld);
-    InitializeObject(address, kImmutableArrayCid, Array::InstanceSize(1));
+    InitializeObject(address, kImmutableArrayCid, Array::InstanceSize(1),
+                     /*compressed*/ false);
     Array::initializeHandle(zero_array_,
                             static_cast<ArrayPtr>(address + kHeapObjectTag));
     zero_array_->untag()->set_length(Smi::New(1));
@@ -946,7 +955,8 @@
   // Allocate and initialize the canonical empty context scope object.
   {
     uword address = heap->Allocate(ContextScope::InstanceSize(0), Heap::kOld);
-    InitializeObject(address, kContextScopeCid, ContextScope::InstanceSize(0));
+    InitializeObject(address, kContextScopeCid, ContextScope::InstanceSize(0),
+                     /*compressed*/ true);
     ContextScope::initializeHandle(
         empty_context_scope_,
         static_cast<ContextScopePtr>(address + kHeapObjectTag));
@@ -960,7 +970,8 @@
   // Allocate and initialize the canonical empty object pool object.
   {
     uword address = heap->Allocate(ObjectPool::InstanceSize(0), Heap::kOld);
-    InitializeObject(address, kObjectPoolCid, ObjectPool::InstanceSize(0));
+    InitializeObject(address, kObjectPoolCid, ObjectPool::InstanceSize(0),
+                     /*compressed*/ false);
     ObjectPool::initializeHandle(
         empty_object_pool_,
         static_cast<ObjectPoolPtr>(address + kHeapObjectTag));
@@ -973,7 +984,8 @@
   {
     const intptr_t instance_size = CompressedStackMaps::InstanceSize(0);
     uword address = heap->Allocate(instance_size, Heap::kOld);
-    InitializeObject(address, kCompressedStackMapsCid, instance_size);
+    InitializeObject(address, kCompressedStackMapsCid, instance_size,
+                     /*compressed*/ true);
     CompressedStackMaps::initializeHandle(
         empty_compressed_stackmaps_,
         static_cast<CompressedStackMapsPtr>(address + kHeapObjectTag));
@@ -985,8 +997,8 @@
   // Allocate and initialize the empty_descriptors instance.
   {
     uword address = heap->Allocate(PcDescriptors::InstanceSize(0), Heap::kOld);
-    InitializeObject(address, kPcDescriptorsCid,
-                     PcDescriptors::InstanceSize(0));
+    InitializeObject(address, kPcDescriptorsCid, PcDescriptors::InstanceSize(0),
+                     /*compressed*/ true);
     PcDescriptors::initializeHandle(
         empty_descriptors_,
         static_cast<PcDescriptorsPtr>(address + kHeapObjectTag));
@@ -1000,7 +1012,7 @@
     uword address =
         heap->Allocate(LocalVarDescriptors::InstanceSize(0), Heap::kOld);
     InitializeObject(address, kLocalVarDescriptorsCid,
-                     LocalVarDescriptors::InstanceSize(0));
+                     LocalVarDescriptors::InstanceSize(0), /*compressed*/ true);
     LocalVarDescriptors::initializeHandle(
         empty_var_descriptors_,
         static_cast<LocalVarDescriptorsPtr>(address + kHeapObjectTag));
@@ -1016,7 +1028,7 @@
     uword address =
         heap->Allocate(ExceptionHandlers::InstanceSize(0), Heap::kOld);
     InitializeObject(address, kExceptionHandlersCid,
-                     ExceptionHandlers::InstanceSize(0));
+                     ExceptionHandlers::InstanceSize(0), /*compressed*/ true);
     ExceptionHandlers::initializeHandle(
         empty_exception_handlers_,
         static_cast<ExceptionHandlersPtr>(address + kHeapObjectTag));
@@ -1028,8 +1040,8 @@
   // Allocate and initialize the canonical empty type arguments object.
   {
     uword address = heap->Allocate(TypeArguments::InstanceSize(0), Heap::kOld);
-    InitializeObject(address, kTypeArgumentsCid,
-                     TypeArguments::InstanceSize(0));
+    InitializeObject(address, kTypeArgumentsCid, TypeArguments::InstanceSize(0),
+                     /*compressed*/ false);
     TypeArguments::initializeHandle(
         empty_type_arguments_,
         static_cast<TypeArgumentsPtr>(address + kHeapObjectTag));
@@ -2489,7 +2501,10 @@
   return String::null();
 }
 
-void Object::InitializeObject(uword address, intptr_t class_id, intptr_t size) {
+void Object::InitializeObject(uword address,
+                              intptr_t class_id,
+                              intptr_t size,
+                              bool compressed) {
   // 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.
@@ -2517,6 +2532,12 @@
 #endif
     } else {
       initial_value = static_cast<uword>(null_);
+#if defined(DART_COMPRESSED_POINTERS)
+      if (compressed) {
+        initial_value &= 0xFFFFFFFF;
+        initial_value |= initial_value << 32;
+      }
+#endif
       needs_init = true;
     }
     if (needs_init) {
@@ -2573,7 +2594,10 @@
 #endif
 }
 
-ObjectPtr Object::Allocate(intptr_t cls_id, intptr_t size, Heap::Space space) {
+ObjectPtr Object::Allocate(intptr_t cls_id,
+                           intptr_t size,
+                           Heap::Space space,
+                           bool compressed) {
   ASSERT(Utils::IsAligned(size, kObjectAlignment));
   Thread* thread = Thread::Current();
   ASSERT(thread->execution_state() == Thread::kThreadInVM);
@@ -2603,7 +2627,7 @@
   }
   NoSafepointScope no_safepoint;
   ObjectPtr raw_obj;
-  InitializeObject(address, cls_id, size);
+  InitializeObject(address, cls_id, size, compressed);
   raw_obj = static_cast<ObjectPtr>(address + kHeapObjectTag);
   ASSERT(cls_id == UntaggedObject::ClassIdTag::decode(raw_obj->untag()->tags_));
   if (raw_obj->IsOldObject() && UNLIKELY(thread->is_marking())) {
@@ -2694,7 +2718,8 @@
 ObjectPtr Object::Clone(const Object& orig, Heap::Space space) {
   const Class& cls = Class::Handle(orig.clazz());
   intptr_t size = orig.ptr()->untag()->HeapSize();
-  ObjectPtr raw_clone = Object::Allocate(cls.id(), size, space);
+  ObjectPtr raw_clone =
+      Object::Allocate(cls.id(), size, space, /*compressed*/ false);
   NoSafepointScope no_safepoint;
   // Copy the body of the original into the clone.
   uword orig_addr = UntaggedObject::ToAddr(orig.ptr());
@@ -2792,8 +2817,8 @@
   ASSERT(Object::class_class() != Class::null());
   Class& result = Class::Handle();
   {
-    ObjectPtr raw =
-        Object::Allocate(Class::kClassId, Class::InstanceSize(), Heap::kOld);
+    ObjectPtr raw = Object::Allocate(Class::kClassId, Class::InstanceSize(),
+                                     Heap::kOld, /*compressed*/ true);
     NoSafepointScope no_safepoint;
     result ^= raw;
   }
@@ -4496,8 +4521,8 @@
   ASSERT(Object::class_class() != Class::null());
   Class& result = Class::Handle();
   {
-    ObjectPtr raw =
-        Object::Allocate(Class::kClassId, Class::InstanceSize(), Heap::kOld);
+    ObjectPtr raw = Object::Allocate(Class::kClassId, Class::InstanceSize(),
+                                     Heap::kOld, /*compressed*/ true);
     NoSafepointScope no_safepoint;
     result ^= raw;
   }
@@ -5951,23 +5976,24 @@
   if (num_types <= kNullabilityMaxTypes) {
     AbstractType& type = AbstractType::Handle();
     for (intptr_t i = 0; i < num_types; i++) {
-      result <<= kNullabilityBitsPerType;
       type = TypeAt(i);
+      intptr_t type_bits = 0;
       if (!type.IsNull() && !type.IsNullTypeRef()) {
         switch (type.nullability()) {
           case Nullability::kNullable:
-            result |= kNullableBits;
+            type_bits = kNullableBits;
             break;
           case Nullability::kNonNullable:
-            result |= kNonNullableBits;
+            type_bits = kNonNullableBits;
             break;
           case Nullability::kLegacy:
-            result |= kLegacyBits;
+            type_bits = kLegacyBits;
             break;
           default:
             UNREACHABLE();
         }
       }
+      result |= (type_bits << (i * kNullabilityBitsPerType));
     }
   }
   set_nullability(result);
@@ -6618,7 +6644,8 @@
   TypeArguments& result = TypeArguments::Handle();
   {
     ObjectPtr raw = Object::Allocate(TypeArguments::kClassId,
-                                     TypeArguments::InstanceSize(len), space);
+                                     TypeArguments::InstanceSize(len), space,
+                                     /*compressed*/ false);
     NoSafepointScope no_safepoint;
     result ^= raw;
     // Length must be set before we start storing into the array.
@@ -6762,8 +6789,9 @@
 
 PatchClassPtr PatchClass::New() {
   ASSERT(Object::patch_class_class() != Class::null());
-  ObjectPtr raw = Object::Allocate(PatchClass::kClassId,
-                                   PatchClass::InstanceSize(), Heap::kOld);
+  ObjectPtr raw =
+      Object::Allocate(PatchClass::kClassId, PatchClass::InstanceSize(),
+                       Heap::kOld, /*compressed*/ true);
   return static_cast<PatchClassPtr>(raw);
 }
 
@@ -6791,19 +6819,8 @@
 #if defined(PRODUCT)
   return false;
 #else
-  // TODO(dartbug.com/36097): We might need to adjust this once we start adding
-  // debugging support to --enable-isolate-groups.
   auto thread = Thread::Current();
-  auto zone = thread->zone();
-  auto isolate_group = thread->isolate_group();
-
-  bool has_breakpoint = false;
-  isolate_group->ForEachIsolate([&](Isolate* isolate) {
-    if (isolate->debugger()->HasBreakpoint(*this, zone)) {
-      has_breakpoint = true;
-    }
-  });
-  return has_breakpoint;
+  return thread->isolate_group()->debugger()->HasBreakpoint(thread, *this);
 #endif
 }
 
@@ -7054,18 +7071,23 @@
 }
 
 FunctionPtr Function::parent_function() const {
-  if (IsClosureFunction()) {
-    const Object& obj = Object::Handle(untag()->data());
-    ASSERT(!obj.IsNull());
-    return ClosureData::Cast(obj).parent_function();
-  }
-  return Function::null();
+  if (!IsClosureFunction()) return Function::null();
+  Object& obj = Object::Handle(untag()->data());
+  ASSERT(!obj.IsNull());
+#if defined(DART_PRECOMPILER)
+  obj = ClosureData::Cast(obj).parent_function();
+  obj = WeakSerializationReference::Unwrap(obj);
+  if (!obj.IsFunction()) return Function::null();
+  return Function::RawCast(obj.ptr());
+#else
+  return ClosureData::Cast(obj).parent_function();
+#endif
 }
 
 void Function::set_parent_function(const Function& value) const {
+  ASSERT(IsClosureFunction());
   const Object& obj = Object::Handle(untag()->data());
   ASSERT(!obj.IsNull());
-  ASSERT(IsClosureFunction());
   ClosureData::Cast(obj).set_parent_function(value);
 }
 
@@ -7143,12 +7165,10 @@
   if (!CachesDefaultTypeArguments()) {
     UNREACHABLE();
   }
-  const auto& closure_data =
-      ClosureData::Handle(ClosureData::RawCast(untag()->data()));
+  const auto& closure_data = ClosureData::Handle(ClosureData::RawCast(data()));
   ASSERT(!closure_data.IsNull());
   if (kind_out != nullptr) {
-    *kind_out = DefaultTypeArgumentsKindField::decode(
-        closure_data.default_type_arguments_info());
+    *kind_out = closure_data.default_type_arguments_kind();
   }
   return closure_data.default_type_arguments();
 }
@@ -7157,16 +7177,11 @@
   if (!CachesDefaultTypeArguments()) {
     UNREACHABLE();
   }
-  const auto& closure_data =
-      ClosureData::Handle(ClosureData::RawCast(untag()->data()));
+  const auto& closure_data = ClosureData::Handle(ClosureData::RawCast(data()));
   ASSERT(!closure_data.IsNull());
-  intptr_t updated_info = closure_data.default_type_arguments_info();
   auto kind = DefaultTypeArgumentsKindFor(value);
   ASSERT(kind != DefaultTypeArgumentsKind::kInvalid);
-  updated_info = DefaultTypeArgumentsKindField::update(kind, updated_info);
-  updated_info = NumParentTypeParametersField::update(NumParentTypeArguments(),
-                                                      updated_info);
-  closure_data.set_default_type_arguments_info(updated_info);
+  closure_data.set_default_type_arguments_kind(kind);
   // 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);
@@ -7201,28 +7216,12 @@
   return function.ptr();
 }
 
-bool Function::HasGenericParent() const {
-  if (IsImplicitClosureFunction()) {
-    // The parent function of an implicit closure function is not the enclosing
-    // function we are asking about here.
-    return false;
-  }
-  Function& parent = Function::Handle(parent_function());
-  while (!parent.IsNull()) {
-    if (parent.IsGeneric()) {
-      return true;
-    }
-    parent = parent.parent_function();
-  }
-  return false;
-}
-
 FunctionPtr Function::implicit_closure_function() const {
   if (IsClosureFunction() || IsFactory() || IsDispatcherOrImplicitAccessor() ||
       IsFieldInitializer() || IsFfiTrampoline()) {
     return Function::null();
   }
-  const Object& obj = Object::Handle(untag()->data());
+  const Object& obj = Object::Handle(data());
   ASSERT(obj.IsNull() || obj.IsScript() || obj.IsFunction() || obj.IsArray());
   if (obj.IsNull() || obj.IsScript()) {
     return Function::null();
@@ -7238,7 +7237,7 @@
 
 void Function::set_implicit_closure_function(const Function& value) const {
   ASSERT(!IsClosureFunction());
-  const Object& old_data = Object::Handle(untag()->data());
+  const Object& old_data = Object::Handle(data());
   if (is_native()) {
     ASSERT(old_data.IsArray());
     ASSERT((Array::Cast(old_data).At(1) == Object::null()) || value.IsNull());
@@ -7257,14 +7256,14 @@
 
 void Function::SetFfiCSignature(const FunctionType& sig) const {
   ASSERT(IsFfiTrampoline());
-  const Object& obj = Object::Handle(untag()->data());
+  const Object& obj = Object::Handle(data());
   ASSERT(!obj.IsNull());
   FfiTrampolineData::Cast(obj).set_c_signature(sig);
 }
 
 FunctionTypePtr Function::FfiCSignature() const {
   ASSERT(IsFfiTrampoline());
-  const Object& obj = Object::Handle(untag()->data());
+  const Object& obj = Object::Handle(data());
   ASSERT(!obj.IsNull());
   return FfiTrampolineData::Cast(obj).c_signature();
 }
@@ -7295,42 +7294,42 @@
 
 int32_t Function::FfiCallbackId() const {
   ASSERT(IsFfiTrampoline());
-  const Object& obj = Object::Handle(untag()->data());
+  const Object& obj = Object::Handle(data());
   ASSERT(!obj.IsNull());
   return FfiTrampolineData::Cast(obj).callback_id();
 }
 
 void Function::SetFfiCallbackId(int32_t value) const {
   ASSERT(IsFfiTrampoline());
-  const Object& obj = Object::Handle(untag()->data());
+  const Object& obj = Object::Handle(data());
   ASSERT(!obj.IsNull());
   FfiTrampolineData::Cast(obj).set_callback_id(value);
 }
 
 FunctionPtr Function::FfiCallbackTarget() const {
   ASSERT(IsFfiTrampoline());
-  const Object& obj = Object::Handle(untag()->data());
+  const Object& obj = Object::Handle(data());
   ASSERT(!obj.IsNull());
   return FfiTrampolineData::Cast(obj).callback_target();
 }
 
 void Function::SetFfiCallbackTarget(const Function& target) const {
   ASSERT(IsFfiTrampoline());
-  const Object& obj = Object::Handle(untag()->data());
+  const Object& obj = Object::Handle(data());
   ASSERT(!obj.IsNull());
   FfiTrampolineData::Cast(obj).set_callback_target(target);
 }
 
 InstancePtr Function::FfiCallbackExceptionalReturn() const {
   ASSERT(IsFfiTrampoline());
-  const Object& obj = Object::Handle(untag()->data());
+  const Object& obj = Object::Handle(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(untag()->data());
+  const Object& obj = Object::Handle(data());
   ASSERT(!obj.IsNull());
   FfiTrampolineData::Cast(obj).set_callback_exceptional_return(value);
 }
@@ -7342,7 +7341,7 @@
 FunctionPtr Function::ForwardingTarget() const {
   ASSERT(kind() == UntaggedFunction::kDynamicInvocationForwarder);
   Array& checks = Array::Handle();
-  checks ^= untag()->data();
+  checks ^= data();
   return Function::RawCast(checks.At(0));
 }
 
@@ -7377,17 +7376,6 @@
   untag()->set_data(value.ptr());
 }
 
-bool Function::IsInFactoryScope() const {
-  if (!IsLocalFunction()) {
-    return IsFactory();
-  }
-  Function& outer_function = Function::Handle(parent_function());
-  while (outer_function.IsLocalFunction()) {
-    outer_function = outer_function.parent_function();
-  }
-  return outer_function.IsFactory();
-}
-
 void Function::set_name(const String& value) const {
   ASSERT(value.IsSymbol());
   untag()->set_name(value.ptr());
@@ -7400,7 +7388,7 @@
 
 RegExpPtr Function::regexp() const {
   ASSERT(kind() == UntaggedFunction::kIrregexpFunction);
-  const Array& pair = Array::Cast(Object::Handle(untag()->data()));
+  const Array& pair = Array::Cast(Object::Handle(data()));
   return RegExp::RawCast(pair.At(0));
 }
 
@@ -7411,13 +7399,13 @@
 
 intptr_t Function::string_specialization_cid() const {
   ASSERT(kind() == UntaggedFunction::kIrregexpFunction);
-  const Array& pair = Array::Cast(Object::Handle(untag()->data()));
+  const Array& pair = Array::Cast(Object::Handle(data()));
   return StringSpecializationCid::decode(Smi::Value(Smi::RawCast(pair.At(1))));
 }
 
 bool Function::is_sticky_specialization() const {
   ASSERT(kind() == UntaggedFunction::kIrregexpFunction);
-  const Array& pair = Array::Cast(Object::Handle(untag()->data()));
+  const Array& pair = Array::Cast(Object::Handle(data()));
   return StickySpecialization::decode(Smi::Value(Smi::RawCast(pair.At(1))));
 }
 
@@ -7426,7 +7414,7 @@
                              bool sticky) const {
   ASSERT(kind() == UntaggedFunction::kIrregexpFunction);
   ASSERT(IsStringClassId(string_specialization_cid));
-  ASSERT(untag()->data() == Object::null());
+  ASSERT(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) |
@@ -7437,7 +7425,7 @@
 
 StringPtr Function::native_name() const {
   ASSERT(is_native());
-  const Object& obj = Object::Handle(untag()->data());
+  const Object& obj = Object::Handle(data());
   ASSERT(obj.IsArray());
   return String::RawCast(Array::Cast(obj).At(0));
 }
@@ -7454,7 +7442,7 @@
   // closure function.
   //
   // We therefore handle both cases.
-  const Object& old_data = Object::Handle(zone, untag()->data());
+  const Object& old_data = Object::Handle(zone, data());
   ASSERT(old_data.IsNull() ||
          (old_data.IsFunction() &&
           Function::Handle(zone, Function::RawCast(old_data.ptr()))
@@ -7718,17 +7706,9 @@
 }
 
 intptr_t Function::NumParentTypeArguments() const {
-  if (IsImplicitClosureFunction()) {
-    return 0;
-  }
-  Function& parent = Function::Handle(parent_function());
-  intptr_t num_parent_type_args = 0;
-  while (!parent.IsNull()) {
-    num_parent_type_args += parent.NumTypeParameters();
-    if (parent.IsImplicitClosureFunction()) break;
-    parent = parent.parent_function();
-  }
-  return num_parent_type_args;
+  // Don't allocate handle in cases where we know it is 0.
+  if (!IsClosureFunction()) return 0;
+  return FunctionType::Handle(signature()).NumParentTypeArguments();
 }
 
 TypeParameterPtr Function::LookupTypeParameter(const String& type_name,
@@ -7773,17 +7753,17 @@
 }
 
 void Function::set_kind(UntaggedFunction::Kind value) const {
-  set_kind_tag(KindBits::update(value, untag()->kind_tag_));
+  untag()->kind_tag_.Update<KindBits>(value);
 }
 
 void Function::set_modifier(UntaggedFunction::AsyncModifier value) const {
-  set_kind_tag(ModifierBits::update(value, untag()->kind_tag_));
+  untag()->kind_tag_.Update<ModifierBits>(value);
 }
 
 void Function::set_recognized_kind(MethodRecognizer::Kind value) const {
   // Prevent multiple settings of kind.
   ASSERT((value == MethodRecognizer::kUnknown) || !IsRecognized());
-  set_kind_tag(RecognizedBits::update(value, untag()->kind_tag_));
+  untag()->kind_tag_.Update<RecognizedBits>(value);
 }
 
 void Function::set_token_pos(TokenPosition token_pos) const {
@@ -7796,7 +7776,7 @@
 }
 
 void Function::set_kind_tag(uint32_t value) const {
-  StoreNonPointer(&untag()->kind_tag_, static_cast<uint32_t>(value));
+  untag()->kind_tag_ = value;
 }
 
 void Function::set_packed_fields(uint32_t packed_fields) const {
@@ -8245,7 +8225,8 @@
     // If the argument type is the top type, no need to check.
     if (type.IsTopTypeForSubtyping()) return true;
     if (argument.IsNull()) {
-      return Instance::NullIsAssignableTo(type);
+      return Instance::NullIsAssignableTo(type, instantiator_type_args,
+                                          function_type_args);
     }
     return argument.IsAssignableTo(type, instantiator_type_args,
                                    function_type_args);
@@ -8308,6 +8289,11 @@
       if (!check_argument(argument, type, instantiator_type_arguments,
                           function_type_arguments)) {
         auto& name = String::Handle(zone, ParameterNameAt(param_index));
+        if (!type.IsInstantiated()) {
+          type = type.InstantiateFrom(instantiator_type_arguments,
+                                      function_type_arguments, kAllFree,
+                                      Heap::kNew);
+        }
         return ThrowTypeError(token_pos(), argument, type, name);
       }
       break;
@@ -8417,32 +8403,30 @@
     Heap::Space space,
     TrailPtr trail) const {
   ASSERT(IsFinalized() || IsBeingFinalized());
-  // A FunctionType cannot be part of a cycle (self-referencing typedefs are not
-  // allowed), therefore, the passed in trail does not need to be propagated to
-  // calls instantiating types of the signature.
   Zone* zone = Thread::Current()->zone();
-  // See the comment on kCurrentAndEnclosingFree to understand why we don't
-  // adjust 'num_free_fun_type_params' downward in this case.
   const intptr_t num_parent_type_args = NumParentTypeArguments();
   bool delete_type_parameters = false;
   if (num_free_fun_type_params == kCurrentAndEnclosingFree) {
+    // See the comment on kCurrentAndEnclosingFree to understand why we don't
+    // adjust 'num_free_fun_type_params' downward in this case.
     num_free_fun_type_params = kAllFree;
     delete_type_parameters = true;
   } else {
     ASSERT(!IsInstantiated(kAny, num_free_fun_type_params));
-    if (IsGeneric() || HasGenericParent()) {
-      // We only consider the function type parameters declared by the parents
-      // of this signature function as free.
-      if (num_parent_type_args < num_free_fun_type_params) {
-        num_free_fun_type_params = num_parent_type_args;
-      }
+    // We only consider the function type parameters declared by the parents
+    // of this signature function as free.
+    if (num_parent_type_args < num_free_fun_type_params) {
+      num_free_fun_type_params = num_parent_type_args;
     }
   }
 
-  // TODO(regis): Is this correct to use num_parent_type_args here?
-  // Or should it be 0 after instantiation?
+  // The number of parent type parameters that remain uninstantiated.
+  const intptr_t remaining_parent_type_params =
+      num_free_fun_type_params < num_parent_type_args
+          ? num_parent_type_args - num_free_fun_type_params
+          : 0;
   FunctionType& sig = FunctionType::Handle(
-      FunctionType::New(num_parent_type_args, nullability(), space));
+      FunctionType::New(remaining_parent_type_params, nullability(), space));
   AbstractType& type = AbstractType::Handle(zone);
 
   // Copy the type parameters and instantiate their bounds (if necessary).
@@ -8460,7 +8444,7 @@
         if (!type.IsInstantiated(kAny, num_free_fun_type_params)) {
           type = type.InstantiateFrom(instantiator_type_arguments,
                                       function_type_arguments,
-                                      num_free_fun_type_params, space);
+                                      num_free_fun_type_params, space, trail);
           // A returned null type indicates a failed instantiation in dead code
           // that must be propagated up to the caller, the optimizing compiler.
           if (type.IsNull()) {
@@ -8495,7 +8479,7 @@
   if (!type.IsInstantiated(kAny, num_free_fun_type_params)) {
     type = type.InstantiateFrom(instantiator_type_arguments,
                                 function_type_arguments,
-                                num_free_fun_type_params, space);
+                                num_free_fun_type_params, space, trail);
     // A returned null type indicates a failed instantiation in dead code that
     // must be propagated up to the caller, the optimizing compiler.
     if (type.IsNull()) {
@@ -8514,7 +8498,7 @@
     if (!type.IsInstantiated(kAny, num_free_fun_type_params)) {
       type = type.InstantiateFrom(instantiator_type_arguments,
                                   function_type_arguments,
-                                  num_free_fun_type_params, space);
+                                  num_free_fun_type_params, space, trail);
       // A returned null type indicates a failed instantiation in dead code that
       // must be propagated up to the caller, the optimizing compiler.
       if (type.IsNull()) {
@@ -8560,7 +8544,8 @@
 }
 
 bool FunctionType::HasSameTypeParametersAndBounds(const FunctionType& other,
-                                                  TypeEquality kind) const {
+                                                  TypeEquality kind,
+                                                  TrailPtr trail) const {
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
 
@@ -8580,7 +8565,7 @@
     for (intptr_t i = 0; i < num_type_params; i++) {
       type_param ^= type_params.TypeAt(i);
       other_type_param ^= other_type_params.TypeAt(i);
-      if (!type_param.IsEquivalent(other_type_param, kind)) {
+      if (!type_param.IsEquivalent(other_type_param, kind, trail)) {
         return false;
       }
     }
@@ -8700,7 +8685,7 @@
 
 bool Function::IsImplicitStaticClosureFunction(FunctionPtr func) {
   NoSafepointScope no_safepoint;
-  uint32_t kind_tag = func->untag()->kind_tag_;
+  uint32_t kind_tag = func->untag()->kind_tag_.load(std::memory_order_relaxed);
   return (KindBits::decode(kind_tag) ==
           UntaggedFunction::kImplicitClosureFunction) &&
          StaticBit::decode(kind_tag);
@@ -8708,8 +8693,8 @@
 
 FunctionPtr Function::New(Heap::Space space) {
   ASSERT(Object::function_class() != Class::null());
-  ObjectPtr raw =
-      Object::Allocate(Function::kClassId, Function::InstanceSize(), space);
+  ObjectPtr raw = Object::Allocate(Function::kClassId, Function::InstanceSize(),
+                                   space, /*compressed*/ true);
   return static_cast<FunctionPtr>(raw);
 }
 
@@ -9087,7 +9072,7 @@
   if (!HasInstantiatedSignature(kCurrentClass)) {
     instantiator_type_arguments = receiver.GetTypeArguments();
   }
-  ASSERT(HasInstantiatedSignature(kFunctions));  // No generic parent function.
+  ASSERT(!HasGenericParent());  // No generic parent function.
   return Closure::New(instantiator_type_arguments,
                       Object::null_type_arguments(), *this, context);
 }
@@ -9185,13 +9170,18 @@
   if (num_free_fun_type_params == kCurrentAndEnclosingFree) {
     num_free_fun_type_params = kAllFree;
   } else if (genericity != kCurrentClass) {
-    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_args = NumParentTypeArguments();
-      if (num_parent_type_args < num_free_fun_type_params) {
-        num_free_fun_type_params = num_parent_type_args;
-      }
+    const intptr_t num_parent_type_args = NumParentTypeArguments();
+    if (num_parent_type_args > 0 && num_free_fun_type_params > 0) {
+      // The number of parent type arguments is cached in the FunctionType, so
+      // we can't consider any FunctionType with free parent type arguments as
+      // fully instantiated. Instead, the FunctionType must be instantiated to
+      // reduce the number of parent type arguments, even if they're unused in
+      // its component types.
+      return false;
+    }
+    // Don't consider local function type parameters as free.
+    if (num_free_fun_type_params > num_parent_type_args) {
+      num_free_fun_type_params = num_parent_type_args;
     }
   }
   AbstractType& type = AbstractType::Handle(result_type());
@@ -9266,7 +9256,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(untag()->data());
+  const Object& data = Object::Handle(this->data());
   if (IsDynamicInvocationForwarder()) {
     const auto& forwarding_target = Function::Handle(ForwardingTarget());
     return forwarding_target.script();
@@ -9294,14 +9284,18 @@
     return PatchClass::Cast(obj).script();
   }
   if (IsClosureFunction()) {
-    return Function::Handle(parent_function()).script();
+    const Function& function = Function::Handle(parent_function());
+#if defined(DART_PRECOMPILED_RUNTIME)
+    if (function.IsNull()) return Script::null();
+#endif
+    return function.script();
   }
   ASSERT(obj.IsClass());
   return Class::Cast(obj).script();
 }
 
 ExternalTypedDataPtr Function::KernelData() const {
-  Object& data = Object::Handle(untag()->data());
+  Object& data = Object::Handle(this->data());
   if (data.IsArray()) {
     Object& script = Object::Handle(Array::Cast(data).At(0));
     if (script.IsScript()) {
@@ -9328,7 +9322,7 @@
       IsFfiTrampoline()) {
     return 0;
   }
-  Object& data = Object::Handle(untag()->data());
+  Object& data = Object::Handle(this->data());
   if (data.IsArray()) {
     Object& script = Object::Handle(Array::Cast(data).At(0));
     if (script.IsScript()) {
@@ -9403,16 +9397,35 @@
   return printer.buffer();
 }
 
-void Function::PrintName(const NameFormattingParams& params,
-                         BaseTextBuffer* printer) const {
-  // If |this| is the generated asynchronous body closure, use the
-  // name of the parent function.
-  Function& fun = Function::Handle(ptr());
-
+static void FunctionPrintNameHelper(const Function& fun,
+                                    const NameFormattingParams& params,
+                                    BaseTextBuffer* printer) {
+  if (fun.IsNonImplicitClosureFunction()) {
+    if (params.include_parent_name) {
+      const auto& parent = Function::Handle(fun.parent_function());
+      if (parent.IsNull()) {
+        printer->AddString(Symbols::OptimizedOut().ToCString());
+      } else {
+        parent.PrintName(params, printer);
+      }
+      // A function's scrubbed name and its user visible name are identical.
+      printer->AddString(".");
+    }
+    if (params.disambiguate_names &&
+        fun.name() == Symbols::AnonymousClosure().ptr()) {
+      printer->Printf("<anonymous closure @%" Pd ">", fun.token_pos().Pos());
+    } else {
+      printer->AddString(fun.NameCString(params.name_visibility));
+    }
+    return;
+  }
   if (params.disambiguate_names) {
     if (fun.IsInvokeFieldDispatcher()) {
       printer->AddString("[invoke-field] ");
     }
+    if (fun.IsNoSuchMethodDispatcher()) {
+      printer->AddString("[no-such-method] ");
+    }
     if (fun.IsImplicitClosureFunction()) {
       printer->AddString("[tear-off] ");
     }
@@ -9421,53 +9434,13 @@
     }
   }
 
-  if (fun.IsNonImplicitClosureFunction()) {
-    // Sniff the parent function.
-    fun = fun.parent_function();
-    ASSERT(!fun.IsNull());
-    if (!fun.IsAsyncGenerator() && !fun.IsAsyncFunction() &&
-        !fun.IsSyncGenerator()) {
-      // Parent function is not the generator of an asynchronous body closure,
-      // start at |this|.
-      fun = ptr();
-    }
-  }
-  if (IsClosureFunction()) {
-    if (fun.IsLocalFunction() && !fun.IsImplicitClosureFunction()) {
-      Function& parent = Function::Handle(fun.parent_function());
-      if (parent.IsAsyncClosure() || parent.IsSyncGenClosureMaker() ||
-          parent.IsAsyncGenClosure()) {
-        // Skip the closure and use the real function name found in
-        // the parent.
-        parent = parent.parent_function();
-      }
-      if (params.include_parent_name) {
-        parent.PrintName(params, printer);
-        // A function's scrubbed name and its user visible name are identical.
-        printer->AddString(".");
-      }
-      if (params.disambiguate_names &&
-          fun.name() == Symbols::AnonymousClosure().ptr()) {
-        printer->Printf("<anonymous closure @%" Pd ">", fun.token_pos().Pos());
-      } else {
-        printer->AddString(fun.NameCString(params.name_visibility));
-      }
-      // If we skipped rewritten async/async*/sync* body then append a suffix
-      // to the end of the name.
-      if (fun.ptr() != ptr() && params.disambiguate_names) {
-        printer->AddString("{body}");
-      }
-      return;
-    }
-  }
-
   if (fun.kind() == UntaggedFunction::kConstructor) {
     printer->AddString("new ");
   } else if (params.include_class_name) {
-    const Class& cls = Class::Handle(Owner());
+    const Class& cls = Class::Handle(fun.Owner());
     if (!cls.IsTopLevel()) {
       const Class& mixin = Class::Handle(cls.Mixin());
-      printer->AddString(params.name_visibility == kUserVisibleName
+      printer->AddString(params.name_visibility == Object::kUserVisibleName
                              ? mixin.UserVisibleNameCString()
                              : cls.NameCString(params.name_visibility));
       printer->AddString(".");
@@ -9476,35 +9449,37 @@
 
   printer->AddString(fun.NameCString(params.name_visibility));
 
-  // If we skipped rewritten async/async*/sync* body then append a suffix
-  // to the end of the name.
-  if (fun.ptr() != ptr() && params.disambiguate_names) {
-    printer->AddString("{body}");
+  // Dispatchers that are created with an arguments descriptor need both the
+  // name and the saved arguments descriptor to disambiguate.
+  if (params.disambiguate_names && fun.HasSavedArgumentsDescriptor()) {
+    const auto& args_desc_array = Array::Handle(fun.saved_args_desc());
+    const ArgumentsDescriptor args_desc(args_desc_array);
+    args_desc.PrintTo(printer);
   }
+}
 
-  // Field dispatchers are specialized for an argument descriptor so there
-  // might be multiples of them with the same name but different argument
-  // descriptors. Add a suffix to disambiguate.
-  if (params.disambiguate_names && fun.IsInvokeFieldDispatcher()) {
-    printer->AddString(" ");
-    if (NumTypeParameters() != 0) {
-      printer->Printf("<%" Pd ">", fun.NumTypeParameters());
+void Function::PrintName(const NameFormattingParams& params,
+                         BaseTextBuffer* printer) const {
+  if (!IsLocalFunction()) {
+    FunctionPrintNameHelper(*this, params, printer);
+    return;
+  }
+  auto& fun = Function::Handle(ptr());
+  intptr_t fun_depth = 0;
+  // If |this| is a generated body closure, start with the closest
+  // non-generated parent function.
+  while (fun.is_generated_body()) {
+    fun = fun.parent_function();
+    fun_depth++;
+  }
+  FunctionPrintNameHelper(fun, params, printer);
+  // If we skipped generated bodies then append a suffix to the end.
+  if (fun_depth > 0 && params.disambiguate_names) {
+    printer->AddString("{body");
+    if (fun_depth > 1) {
+      printer->Printf(" depth %" Pd "", fun_depth);
     }
-    printer->AddString("(");
-    printer->Printf("%" Pd "", fun.num_fixed_parameters());
-    if (fun.NumOptionalPositionalParameters() != 0) {
-      printer->Printf(" [%" Pd "]", fun.NumOptionalPositionalParameters());
-    }
-    if (fun.HasOptionalNamedParameters()) {
-      printer->AddString(" {");
-      String& name = String::Handle();
-      for (intptr_t i = 0; i < fun.NumOptionalNamedParameters(); i++) {
-        name = fun.ParameterNameAt(fun.num_fixed_parameters() + i);
-        printer->Printf("%s%s", i > 0 ? ", " : "", name.ToCString());
-      }
-      printer->AddString("}");
-    }
-    printer->AddString(")");
+    printer->AddString("}");
   }
 }
 
@@ -9795,7 +9770,7 @@
 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()) {
+  if (HasSavedArgumentsDescriptor()) {
     return false;
   }
   // The prologue of those functions need to examine the arg descriptor for
@@ -9885,7 +9860,7 @@
     default:
       UNREACHABLE();
   }
-  if (IsNoSuchMethodDispatcher() || IsInvokeFieldDispatcher()) {
+  if (HasSavedArgumentsDescriptor()) {
     const auto& args_desc_array = Array::Handle(zone, saved_args_desc());
     const ArgumentsDescriptor args_desc(args_desc_array);
     buffer.AddChar('[');
@@ -9921,26 +9896,21 @@
   untag()->set_default_type_arguments(value.ptr());
 }
 
-intptr_t ClosureData::default_type_arguments_info() const {
-  const SmiPtr value = untag()->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(untag()->default_type_arguments_info());
+ClosureData::DefaultTypeArgumentsKind ClosureData::default_type_arguments_kind()
+    const {
+  return LoadNonPointer(&untag()->default_type_arguments_kind_);
 }
 
-void ClosureData::set_default_type_arguments_info(intptr_t value) const {
-  ASSERT(Smi::IsValid(value));
-  untag()->set_default_type_arguments_info(Smi::New(value));
+void ClosureData::set_default_type_arguments_kind(
+    DefaultTypeArgumentsKind value) const {
+  StoreNonPointer(&untag()->default_type_arguments_kind_, value);
 }
 
 ClosureDataPtr ClosureData::New() {
   ASSERT(Object::closure_data_class() != Class::null());
-  ObjectPtr raw = Object::Allocate(ClosureData::kClassId,
-                                   ClosureData::InstanceSize(), Heap::kOld);
+  ObjectPtr raw =
+      Object::Allocate(ClosureData::kClassId, ClosureData::InstanceSize(),
+                       Heap::kOld, /*compressed*/ true);
   return static_cast<ClosureDataPtr>(raw);
 }
 
@@ -9953,10 +9923,10 @@
   buffer.Printf("ClosureData: context_scope: 0x%" Px "",
                 static_cast<uword>(context_scope()));
   buffer.AddString(" parent_function: ");
-  if (parent_function() == Function::null()) {
+  if (parent_function() == Object::null()) {
     buffer.AddString("null");
   } else {
-    buffer.AddString(Function::Handle(zone, parent_function()).ToCString());
+    buffer.AddString(Object::Handle(parent_function()).ToCString());
   }
   buffer.Printf(" implicit_static_closure: 0x%" Px "",
                 static_cast<uword>(implicit_static_closure()));
@@ -10022,8 +9992,9 @@
 }
 
 FunctionTypePtr FunctionType::New(Heap::Space space) {
-  ObjectPtr raw = Object::Allocate(FunctionType::kClassId,
-                                   FunctionType::InstanceSize(), space);
+  ObjectPtr raw =
+      Object::Allocate(FunctionType::kClassId, FunctionType::InstanceSize(),
+                       space, /*compressed*/ true);
   return static_cast<FunctionTypePtr>(raw);
 }
 
@@ -10094,9 +10065,15 @@
   untag()->set_closure<std::memory_order_release>(closure.ptr());
 }
 
+#if defined(DART_PRECOMPILER)
+void ClosureData::set_parent_function(const Object& value) const {
+  untag()->set_parent_function(value.ptr());
+}
+#else
 void ClosureData::set_parent_function(const Function& value) const {
   untag()->set_parent_function(value.ptr());
 }
+#endif
 
 void FfiTrampolineData::set_c_signature(const FunctionType& value) const {
   untag()->set_c_signature(value.ptr());
@@ -10113,9 +10090,9 @@
 
 FfiTrampolineDataPtr FfiTrampolineData::New() {
   ASSERT(Object::ffi_trampoline_data_class() != Class::null());
-  ObjectPtr raw =
-      Object::Allocate(FfiTrampolineData::kClassId,
-                       FfiTrampolineData::InstanceSize(), Heap::kOld);
+  ObjectPtr raw = Object::Allocate(FfiTrampolineData::kClassId,
+                                   FfiTrampolineData::InstanceSize(),
+                                   Heap::kOld, /*compressed*/ true);
   FfiTrampolineDataPtr data = static_cast<FfiTrampolineDataPtr>(raw);
   data->untag()->callback_id_ = 0;
   return data;
@@ -10180,7 +10157,9 @@
   // This assertion ensures that the cid seen by the background compiler is
   // consistent. So the assertion passes if the field is a clone. It also
   // passes if the field is static, because we don't use field guards on
-  // static fields.
+  // static fields. It also passes if we're compiling unoptimized
+  // code (in which case the caller might get different answers if it obtains
+  // the guarded cid multiple times).
   Thread* thread = Thread::Current();
   ASSERT(!thread->IsInsideCompiler() ||
 #if !defined(DART_PRECOMPILED_RUNTIME)
@@ -10371,8 +10350,8 @@
 
 FieldPtr Field::New() {
   ASSERT(Object::field_class() != Class::null());
-  ObjectPtr raw =
-      Object::Allocate(Field::kClassId, Field::InstanceSize(), Heap::kOld);
+  ObjectPtr raw = Object::Allocate(Field::kClassId, Field::InstanceSize(),
+                                   Heap::kOld, /*compressed*/ true);
   return static_cast<FieldPtr>(raw);
 }
 
@@ -11790,8 +11769,8 @@
 
 ScriptPtr Script::New() {
   ASSERT(Object::script_class() != Class::null());
-  ObjectPtr raw =
-      Object::Allocate(Script::kClassId, Script::InstanceSize(), Heap::kOld);
+  ObjectPtr raw = Object::Allocate(Script::kClassId, Script::InstanceSize(),
+                                   Heap::kOld, /*compressed*/ true);
   return static_cast<ScriptPtr>(raw);
 }
 
@@ -12850,8 +12829,8 @@
 
 LibraryPtr Library::New() {
   ASSERT(Object::library_class() != Class::null());
-  ObjectPtr raw =
-      Object::Allocate(Library::kClassId, Library::InstanceSize(), Heap::kOld);
+  ObjectPtr raw = Object::Allocate(Library::kClassId, Library::InstanceSize(),
+                                   Heap::kOld, /*compressed*/ true);
   return static_cast<LibraryPtr>(raw);
 }
 
@@ -13556,8 +13535,9 @@
 }
 
 LibraryPrefixPtr LibraryPrefix::New() {
-  ObjectPtr raw = Object::Allocate(LibraryPrefix::kClassId,
-                                   LibraryPrefix::InstanceSize(), Heap::kOld);
+  ObjectPtr raw =
+      Object::Allocate(LibraryPrefix::kClassId, LibraryPrefix::InstanceSize(),
+                       Heap::kOld, /*compressed*/ false);
   return static_cast<LibraryPrefixPtr>(raw);
 }
 
@@ -13711,8 +13691,9 @@
 
 NamespacePtr Namespace::New() {
   ASSERT(Object::namespace_class() != Class::null());
-  ObjectPtr raw = Object::Allocate(Namespace::kClassId,
-                                   Namespace::InstanceSize(), Heap::kOld);
+  ObjectPtr raw =
+      Object::Allocate(Namespace::kClassId, Namespace::InstanceSize(),
+                       Heap::kOld, /*compressed*/ true);
   return static_cast<NamespacePtr>(raw);
 }
 
@@ -13731,9 +13712,9 @@
 }
 
 KernelProgramInfoPtr KernelProgramInfo::New() {
-  ObjectPtr raw =
-      Object::Allocate(KernelProgramInfo::kClassId,
-                       KernelProgramInfo::InstanceSize(), Heap::kOld);
+  ObjectPtr raw = Object::Allocate(KernelProgramInfo::kClassId,
+                                   KernelProgramInfo::InstanceSize(),
+                                   Heap::kOld, /*compressed*/ true);
   return static_cast<KernelProgramInfoPtr>(raw);
 }
 
@@ -14134,8 +14115,8 @@
   Instructions& result = Instructions::Handle();
   {
     uword aligned_size = Instructions::InstanceSize(size);
-    ObjectPtr raw =
-        Object::Allocate(Instructions::kClassId, aligned_size, Heap::kCode);
+    ObjectPtr raw = Object::Allocate(Instructions::kClassId, aligned_size,
+                                     Heap::kCode, /*compressed*/ false);
     NoSafepointScope no_safepoint;
     result ^= raw;
     result.SetSize(size);
@@ -14177,7 +14158,8 @@
   ObjectPool& result = ObjectPool::Handle();
   {
     uword size = ObjectPool::InstanceSize(len);
-    ObjectPtr raw = Object::Allocate(ObjectPool::kClassId, size, Heap::kOld);
+    ObjectPtr raw = Object::Allocate(ObjectPool::kClassId, size, Heap::kOld,
+                                     /*compressed*/ false);
     NoSafepointScope no_safepoint;
     result ^= raw;
     result.SetLength(len);
@@ -14292,8 +14274,9 @@
   Thread* thread = Thread::Current();
   PcDescriptors& result = PcDescriptors::Handle(thread->zone());
   {
-    ObjectPtr raw = Object::Allocate(
-        PcDescriptors::kClassId, PcDescriptors::InstanceSize(size), Heap::kOld);
+    ObjectPtr raw = Object::Allocate(PcDescriptors::kClassId,
+                                     PcDescriptors::InstanceSize(size),
+                                     Heap::kOld, /*compressed*/ true);
     NoSafepointScope no_safepoint;
     result ^= raw;
     result.SetLength(size);
@@ -14308,7 +14291,8 @@
   PcDescriptors& result = PcDescriptors::Handle(thread->zone());
   {
     uword size = PcDescriptors::InstanceSize(length);
-    ObjectPtr raw = Object::Allocate(PcDescriptors::kClassId, size, Heap::kOld);
+    ObjectPtr raw = Object::Allocate(PcDescriptors::kClassId, size, Heap::kOld,
+                                     /*compressed*/ true);
     NoSafepointScope no_safepoint;
     result ^= raw;
     result.SetLength(length);
@@ -14440,7 +14424,8 @@
   CodeSourceMap& result = CodeSourceMap::Handle(thread->zone());
   {
     uword size = CodeSourceMap::InstanceSize(length);
-    ObjectPtr raw = Object::Allocate(CodeSourceMap::kClassId, size, Heap::kOld);
+    ObjectPtr raw = Object::Allocate(CodeSourceMap::kClassId, size, Heap::kOld,
+                                     /*compressed*/ true);
     NoSafepointScope no_safepoint;
     result ^= raw;
     result.SetLength(length);
@@ -14629,9 +14614,9 @@
   {
     // CompressedStackMaps data objects are associated with a code object,
     // allocate them in old generation.
-    ObjectPtr raw =
-        Object::Allocate(CompressedStackMaps::kClassId,
-                         CompressedStackMaps::InstanceSize(size), Heap::kOld);
+    ObjectPtr raw = Object::Allocate(CompressedStackMaps::kClassId,
+                                     CompressedStackMaps::InstanceSize(size),
+                                     Heap::kOld, /*compressed*/ true);
     NoSafepointScope no_safepoint;
     result ^= raw;
     result.StoreNonPointer(
@@ -14665,8 +14650,8 @@
 
 StringPtr LocalVarDescriptors::GetName(intptr_t var_index) const {
   ASSERT(var_index < Length());
-  ASSERT(Object::Handle(*ptr()->untag()->nameAddrAt(var_index)).IsString());
-  return *ptr()->untag()->nameAddrAt(var_index);
+  ASSERT(Object::Handle(ptr()->untag()->name(var_index)).IsString());
+  return ptr()->untag()->name(var_index);
 }
 
 void LocalVarDescriptors::SetVar(
@@ -14675,7 +14660,7 @@
     UntaggedLocalVarDescriptors::VarInfo* info) const {
   ASSERT(var_index < Length());
   ASSERT(!name.IsNull());
-  StorePointer(ptr()->untag()->nameAddrAt(var_index), name.ptr());
+  ptr()->untag()->set_name(var_index, name.ptr());
   ptr()->untag()->data()[var_index] = *info;
 }
 
@@ -14779,8 +14764,8 @@
   LocalVarDescriptors& result = LocalVarDescriptors::Handle();
   {
     uword size = LocalVarDescriptors::InstanceSize(num_variables);
-    ObjectPtr raw =
-        Object::Allocate(LocalVarDescriptors::kClassId, size, Heap::kOld);
+    ObjectPtr raw = Object::Allocate(LocalVarDescriptors::kClassId, size,
+                                     Heap::kOld, /*compressed*/ true);
     NoSafepointScope no_safepoint;
     result ^= raw;
     result.StoreNonPointer(&result.untag()->num_entries_, num_variables);
@@ -14880,8 +14865,8 @@
   ExceptionHandlers& result = ExceptionHandlers::Handle();
   {
     uword size = ExceptionHandlers::InstanceSize(num_handlers);
-    ObjectPtr raw =
-        Object::Allocate(ExceptionHandlers::kClassId, size, Heap::kOld);
+    ObjectPtr raw = Object::Allocate(ExceptionHandlers::kClassId, size,
+                                     Heap::kOld, /*compressed*/ true);
     NoSafepointScope no_safepoint;
     result ^= raw;
     result.StoreNonPointer(&result.untag()->num_entries_, num_handlers);
@@ -14905,8 +14890,8 @@
   ExceptionHandlers& result = ExceptionHandlers::Handle();
   {
     uword size = ExceptionHandlers::InstanceSize(num_handlers);
-    ObjectPtr raw =
-        Object::Allocate(ExceptionHandlers::kClassId, size, Heap::kOld);
+    ObjectPtr raw = Object::Allocate(ExceptionHandlers::kClassId, size,
+                                     Heap::kOld, /*compressed*/ true);
     NoSafepointScope no_safepoint;
     result ^= raw;
     result.StoreNonPointer(&result.untag()->num_entries_, num_handlers);
@@ -14979,9 +14964,9 @@
   SingleTargetCache& result = SingleTargetCache::Handle();
   {
     // IC data objects are long living objects, allocate them in old generation.
-    ObjectPtr raw =
-        Object::Allocate(SingleTargetCache::kClassId,
-                         SingleTargetCache::InstanceSize(), Heap::kOld);
+    ObjectPtr raw = Object::Allocate(SingleTargetCache::kClassId,
+                                     SingleTargetCache::InstanceSize(),
+                                     Heap::kOld, /*compressed*/ false);
     NoSafepointScope no_safepoint;
     result ^= raw;
   }
@@ -15012,8 +14997,9 @@
 
 UnlinkedCallPtr UnlinkedCall::New() {
   UnlinkedCall& result = UnlinkedCall::Handle();
-  result ^= Object::Allocate(UnlinkedCall::kClassId,
-                             UnlinkedCall::InstanceSize(), Heap::kOld);
+  result ^=
+      Object::Allocate(UnlinkedCall::kClassId, UnlinkedCall::InstanceSize(),
+                       Heap::kOld, /*compressed*/ false);
   result.set_can_patch_to_monomorphic(!FLAG_precompiled_mode);
   return result.ptr();
 }
@@ -15021,9 +15007,9 @@
 MonomorphicSmiableCallPtr MonomorphicSmiableCall::New(classid_t expected_cid,
                                                       const Code& target) {
   auto& result = MonomorphicSmiableCall::Handle();
-  result ^=
-      Object::Allocate(MonomorphicSmiableCall::kClassId,
-                       MonomorphicSmiableCall::InstanceSize(), Heap::kOld);
+  result ^= Object::Allocate(MonomorphicSmiableCall::kClassId,
+                             MonomorphicSmiableCall::InstanceSize(), Heap::kOld,
+                             /*compressed*/ false);
   result.untag()->set_target(target.ptr());
   result.StoreNonPointer(&result.untag()->expected_cid_, expected_cid);
   result.StoreNonPointer(&result.untag()->entrypoint_, target.EntryPoint());
@@ -15978,8 +15964,8 @@
   ICData& result = ICData::Handle(zone);
   {
     // IC data objects are long living objects, allocate them in old generation.
-    ObjectPtr raw =
-        Object::Allocate(ICData::kClassId, ICData::InstanceSize(), Heap::kOld);
+    ObjectPtr raw = Object::Allocate(ICData::kClassId, ICData::InstanceSize(),
+                                     Heap::kOld, /*compressed*/ false);
     NoSafepointScope no_safepoint;
     result ^= raw;
   }
@@ -16002,8 +15988,8 @@
   ICData& result = ICData::Handle();
   {
     // IC data objects are long living objects, allocate them in old generation.
-    ObjectPtr raw =
-        Object::Allocate(ICData::kClassId, ICData::InstanceSize(), Heap::kOld);
+    ObjectPtr raw = Object::Allocate(ICData::kClassId, ICData::InstanceSize(),
+                                     Heap::kOld, /*compressed*/ false);
     NoSafepointScope no_safepoint;
     result ^= raw;
   }
@@ -16160,7 +16146,7 @@
   {
     ObjectPtr raw = Object::Allocate(WeakSerializationReference::kClassId,
                                      WeakSerializationReference::InstanceSize(),
-                                     Heap::kOld);
+                                     Heap::kOld, /*compressed*/ true);
     NoSafepointScope no_safepoint;
 
     result ^= raw;
@@ -16362,17 +16348,7 @@
 #if defined(PRODUCT)
   return false;
 #else
-  // TODO(dartbug.com/36097): We might need to adjust this once we start adding
-  // debugging support to --enable-isolate-groups.
-  auto isolate_group = Thread::Current()->isolate_group();
-
-  bool has_breakpoint = false;
-  isolate_group->ForEachIsolate([&](Isolate* isolate) {
-    if (isolate->debugger()->HasBreakpoint(*this)) {
-      has_breakpoint = true;
-    }
-  });
-  return has_breakpoint;
+  return IsolateGroup::Current()->debugger()->HasBreakpointInCode(*this);
 #endif
 }
 
@@ -16511,7 +16487,7 @@
     for (intptr_t i = 0; i < length_; i++) {
       comments_[i].pc_offset = comments.PCOffsetAt(i);
       comments_[i].comment =
-          Utils::CreateCStringUniquePtr(strdup(comments.CommentAt(i)));
+          Utils::CreateCStringUniquePtr(Utils::StrDup(comments.CommentAt(i)));
     }
   }
 
@@ -16604,7 +16580,8 @@
   Code& result = Code::Handle();
   {
     uword size = Code::InstanceSize(pointer_offsets_length);
-    ObjectPtr raw = Object::Allocate(Code::kClassId, size, Heap::kOld);
+    ObjectPtr raw = Object::Allocate(Code::kClassId, size, Heap::kOld,
+                                     /*compressed*/ false);
     NoSafepointScope no_safepoint;
     result ^= raw;
     result.set_pointer_offsets_length(pointer_offsets_length);
@@ -17142,8 +17119,9 @@
   }
   Context& result = Context::Handle();
   {
-    ObjectPtr raw = Object::Allocate(
-        Context::kClassId, Context::InstanceSize(num_variables), space);
+    ObjectPtr raw = Object::Allocate(Context::kClassId,
+                                     Context::InstanceSize(num_variables),
+                                     space, /*compressed*/ false);
     NoSafepointScope no_safepoint;
     result ^= raw;
     result.set_num_variables(num_variables);
@@ -17212,7 +17190,8 @@
   intptr_t size = ContextScope::InstanceSize(num_variables);
   ContextScope& result = ContextScope::Handle();
   {
-    ObjectPtr raw = Object::Allocate(ContextScope::kClassId, size, Heap::kOld);
+    ObjectPtr raw = Object::Allocate(ContextScope::kClassId, size, Heap::kOld,
+                                     /*compressed*/ true);
     NoSafepointScope no_safepoint;
     result ^= raw;
     result.set_num_variables(num_variables);
@@ -17223,50 +17202,49 @@
 
 TokenPosition ContextScope::TokenIndexAt(intptr_t scope_index) const {
   return TokenPosition::Deserialize(
-      Smi::Value(VariableDescAddr(scope_index)->token_pos));
+      Smi::Value(untag()->token_pos_at(scope_index)));
 }
 
 void ContextScope::SetTokenIndexAt(intptr_t scope_index,
                                    TokenPosition token_pos) const {
-  StoreSmi(&VariableDescAddr(scope_index)->token_pos,
-           Smi::New(token_pos.Serialize()));
+  untag()->set_token_pos_at(scope_index, Smi::New(token_pos.Serialize()));
 }
 
 TokenPosition ContextScope::DeclarationTokenIndexAt(
     intptr_t scope_index) const {
   return TokenPosition::Deserialize(
-      Smi::Value(VariableDescAddr(scope_index)->declaration_token_pos));
+      Smi::Value(untag()->declaration_token_pos_at(scope_index)));
 }
 
 void ContextScope::SetDeclarationTokenIndexAt(
     intptr_t scope_index,
     TokenPosition declaration_token_pos) const {
-  StoreSmi(&VariableDescAddr(scope_index)->declaration_token_pos,
-           Smi::New(declaration_token_pos.Serialize()));
+  untag()->set_declaration_token_pos_at(
+      scope_index, Smi::New(declaration_token_pos.Serialize()));
 }
 
 StringPtr ContextScope::NameAt(intptr_t scope_index) const {
-  return VariableDescAddr(scope_index)->name;
+  return untag()->name_at(scope_index);
 }
 
 void ContextScope::SetNameAt(intptr_t scope_index, const String& name) const {
-  StorePointer(&(VariableDescAddr(scope_index)->name), name.ptr());
+  untag()->set_name_at(scope_index, name.ptr());
 }
 
 void ContextScope::ClearFlagsAt(intptr_t scope_index) const {
-  StoreSmi(&(VariableDescAddr(scope_index)->flags), 0);
+  untag()->set_flags_at(scope_index, Smi::New(0));
 }
 
 bool ContextScope::GetFlagAt(intptr_t scope_index, intptr_t mask) const {
-  return (Smi::Value(VariableDescAddr(scope_index)->flags) & mask) != 0;
+  return (Smi::Value(untag()->flags_at(scope_index)) & mask) != 0;
 }
 
 void ContextScope::SetFlagAt(intptr_t scope_index,
                              intptr_t mask,
                              bool value) const {
-  intptr_t flags = Smi::Value(VariableDescAddr(scope_index)->flags);
-  StoreSmi(&(VariableDescAddr(scope_index)->flags),
-           Smi::New(value ? flags | mask : flags & ~mask));
+  intptr_t flags = Smi::Value(untag()->flags_at(scope_index));
+  untag()->set_flags_at(scope_index,
+                        Smi::New(value ? flags | mask : flags & ~mask));
 }
 
 bool ContextScope::IsFinalAt(intptr_t scope_index) const {
@@ -17296,54 +17274,51 @@
 }
 
 intptr_t ContextScope::LateInitOffsetAt(intptr_t scope_index) const {
-  return Smi::Value(VariableDescAddr(scope_index)->late_init_offset);
+  return Smi::Value(untag()->late_init_offset_at(scope_index));
 }
 
 void ContextScope::SetLateInitOffsetAt(intptr_t scope_index,
                                        intptr_t late_init_offset) const {
-  StoreSmi(&(VariableDescAddr(scope_index)->late_init_offset),
-           Smi::New(late_init_offset));
+  untag()->set_late_init_offset_at(scope_index, Smi::New(late_init_offset));
 }
 
 AbstractTypePtr ContextScope::TypeAt(intptr_t scope_index) const {
   ASSERT(!IsConstAt(scope_index));
-  return VariableDescAddr(scope_index)->type;
+  return untag()->type_at(scope_index);
 }
 
 void ContextScope::SetTypeAt(intptr_t scope_index,
                              const AbstractType& type) const {
-  StorePointer(&(VariableDescAddr(scope_index)->type), type.ptr());
+  untag()->set_type_at(scope_index, type.ptr());
 }
 
 InstancePtr ContextScope::ConstValueAt(intptr_t scope_index) const {
   ASSERT(IsConstAt(scope_index));
-  return VariableDescAddr(scope_index)->value;
+  return untag()->value_at(scope_index);
 }
 
 void ContextScope::SetConstValueAt(intptr_t scope_index,
                                    const Instance& value) const {
   ASSERT(IsConstAt(scope_index));
-  StorePointer(&(VariableDescAddr(scope_index)->value), value.ptr());
+  untag()->set_value_at(scope_index, value.ptr());
 }
 
 intptr_t ContextScope::ContextIndexAt(intptr_t scope_index) const {
-  return Smi::Value(VariableDescAddr(scope_index)->context_index);
+  return Smi::Value(untag()->context_index_at(scope_index));
 }
 
 void ContextScope::SetContextIndexAt(intptr_t scope_index,
                                      intptr_t context_index) const {
-  StoreSmi(&(VariableDescAddr(scope_index)->context_index),
-           Smi::New(context_index));
+  untag()->set_context_index_at(scope_index, Smi::New(context_index));
 }
 
 intptr_t ContextScope::ContextLevelAt(intptr_t scope_index) const {
-  return Smi::Value(VariableDescAddr(scope_index)->context_level);
+  return Smi::Value(untag()->context_level_at(scope_index));
 }
 
 void ContextScope::SetContextLevelAt(intptr_t scope_index,
                                      intptr_t context_level) const {
-  StoreSmi(&(VariableDescAddr(scope_index)->context_level),
-           Smi::New(context_level));
+  untag()->set_context_level_at(scope_index, Smi::New(context_level));
 }
 
 const char* ContextScope::ToCString() const {
@@ -17394,9 +17369,9 @@
 MegamorphicCachePtr MegamorphicCache::New() {
   MegamorphicCache& result = MegamorphicCache::Handle();
   {
-    ObjectPtr raw =
-        Object::Allocate(MegamorphicCache::kClassId,
-                         MegamorphicCache::InstanceSize(), Heap::kOld);
+    ObjectPtr raw = Object::Allocate(MegamorphicCache::kClassId,
+                                     MegamorphicCache::InstanceSize(),
+                                     Heap::kOld, /*compressed*/ false);
     NoSafepointScope no_safepoint;
     result ^= raw;
   }
@@ -17408,9 +17383,9 @@
                                           const Array& arguments_descriptor) {
   MegamorphicCache& result = MegamorphicCache::Handle();
   {
-    ObjectPtr raw =
-        Object::Allocate(MegamorphicCache::kClassId,
-                         MegamorphicCache::InstanceSize(), Heap::kOld);
+    ObjectPtr raw = Object::Allocate(MegamorphicCache::kClassId,
+                                     MegamorphicCache::InstanceSize(),
+                                     Heap::kOld, /*compressed*/ false);
     NoSafepointScope no_safepoint;
     result ^= raw;
   }
@@ -17594,9 +17569,9 @@
   {
     // SubtypeTestCache objects are long living objects, allocate them in the
     // old generation.
-    ObjectPtr raw =
-        Object::Allocate(SubtypeTestCache::kClassId,
-                         SubtypeTestCache::InstanceSize(), Heap::kOld);
+    ObjectPtr raw = Object::Allocate(SubtypeTestCache::kClassId,
+                                     SubtypeTestCache::InstanceSize(),
+                                     Heap::kOld, /*compressed*/ true);
     NoSafepointScope no_safepoint;
     result ^= raw;
   }
@@ -17875,8 +17850,9 @@
   {
     // LoadingUnit objects are long living objects, allocate them in the
     // old generation.
-    ObjectPtr raw = Object::Allocate(LoadingUnit::kClassId,
-                                     LoadingUnit::InstanceSize(), Heap::kOld);
+    ObjectPtr raw =
+        Object::Allocate(LoadingUnit::kClassId, LoadingUnit::InstanceSize(),
+                         Heap::kOld, /*compressed*/ true);
     NoSafepointScope no_safepoint;
     result ^= raw;
   }
@@ -17949,7 +17925,7 @@
 ApiErrorPtr ApiError::New() {
   ASSERT(Object::api_error_class() != Class::null());
   ObjectPtr raw = Object::Allocate(ApiError::kClassId, ApiError::InstanceSize(),
-                                   Heap::kOld);
+                                   Heap::kOld, /*compressed*/ true);
   return static_cast<ApiErrorPtr>(raw);
 }
 
@@ -17965,7 +17941,8 @@
   ApiError& result = ApiError::Handle();
   {
     ObjectPtr raw =
-        Object::Allocate(ApiError::kClassId, ApiError::InstanceSize(), space);
+        Object::Allocate(ApiError::kClassId, ApiError::InstanceSize(), space,
+                         /*compressed*/ true);
     NoSafepointScope no_safepoint;
     result ^= raw;
   }
@@ -17988,8 +17965,9 @@
 
 LanguageErrorPtr LanguageError::New() {
   ASSERT(Object::language_error_class() != Class::null());
-  ObjectPtr raw = Object::Allocate(LanguageError::kClassId,
-                                   LanguageError::InstanceSize(), Heap::kOld);
+  ObjectPtr raw =
+      Object::Allocate(LanguageError::kClassId, LanguageError::InstanceSize(),
+                       Heap::kOld, /*compressed*/ true);
   return static_cast<LanguageErrorPtr>(raw);
 }
 
@@ -18004,8 +17982,9 @@
   ASSERT(Object::language_error_class() != Class::null());
   LanguageError& result = LanguageError::Handle();
   {
-    ObjectPtr raw = Object::Allocate(LanguageError::kClassId,
-                                     LanguageError::InstanceSize(), space);
+    ObjectPtr raw =
+        Object::Allocate(LanguageError::kClassId, LanguageError::InstanceSize(),
+                         space, /*compressed*/ true);
     NoSafepointScope no_safepoint;
     result ^= raw;
   }
@@ -18043,8 +18022,9 @@
   ASSERT(Object::language_error_class() != Class::null());
   LanguageError& result = LanguageError::Handle();
   {
-    ObjectPtr raw = Object::Allocate(LanguageError::kClassId,
-                                     LanguageError::InstanceSize(), space);
+    ObjectPtr raw =
+        Object::Allocate(LanguageError::kClassId, LanguageError::InstanceSize(),
+                         space, /*compressed*/ true);
     NoSafepointScope no_safepoint;
     result ^= raw;
   }
@@ -18115,7 +18095,8 @@
   UnhandledException& result = UnhandledException::Handle();
   {
     ObjectPtr raw = Object::Allocate(UnhandledException::kClassId,
-                                     UnhandledException::InstanceSize(), space);
+                                     UnhandledException::InstanceSize(), space,
+                                     /*compressed*/ true);
     NoSafepointScope no_safepoint;
     result ^= raw;
   }
@@ -18129,7 +18110,8 @@
   UnhandledException& result = UnhandledException::Handle();
   {
     ObjectPtr raw = Object::Allocate(UnhandledException::kClassId,
-                                     UnhandledException::InstanceSize(), space);
+                                     UnhandledException::InstanceSize(), space,
+                                     /*compressed*/ true);
     NoSafepointScope no_safepoint;
     result ^= raw;
   }
@@ -18185,8 +18167,9 @@
   ASSERT(Object::unwind_error_class() != Class::null());
   UnwindError& result = UnwindError::Handle();
   {
-    ObjectPtr raw = Object::Allocate(UnwindError::kClassId,
-                                     UnwindError::InstanceSize(), space);
+    ObjectPtr raw =
+        Object::Allocate(UnwindError::kClassId, UnwindError::InstanceSize(),
+                         space, /*compressed*/ true);
     NoSafepointScope no_safepoint;
     result ^= raw;
   }
@@ -18820,9 +18803,28 @@
     return NullIsAssignableTo(
         AbstractType::Handle(thread->zone(), other.UnwrapFutureOr()));
   }
+  // Since the TAVs are not available, for non-nullable type parameters
+  // this returns a conservative approximation of "not assignable" .
   return false;
 }
 
+// Must be kept in sync with GenerateNullIsAssignableToType in
+// stub_code_compiler.cc if any changes are made.
+bool Instance::NullIsAssignableTo(
+    const AbstractType& other,
+    const TypeArguments& other_instantiator_type_arguments,
+    const TypeArguments& other_function_type_arguments) {
+  // Do checks that don't require instantiation first.
+  if (NullIsAssignableTo(other)) return true;
+  if (!other.IsTypeParameter()) return false;
+  const auto& type = AbstractType::Handle(other.InstantiateFrom(
+      other_instantiator_type_arguments, other_function_type_arguments,
+      kAllFree, Heap::kNew));
+  // At runtime, uses of TypeRef should not occur.
+  ASSERT(!type.IsTypeRef());
+  return NullIsAssignableTo(type);
+}
+
 bool Instance::RuntimeTypeIsSubtypeOf(
     const AbstractType& other,
     const TypeArguments& other_instantiator_type_arguments,
@@ -19029,7 +19031,8 @@
   }
   intptr_t instance_size = cls.host_instance_size();
   ASSERT(instance_size > 0);
-  ObjectPtr raw = Object::Allocate(cls.id(), instance_size, space);
+  ObjectPtr raw =
+      Object::Allocate(cls.id(), instance_size, space, /*compressed*/ false);
   return static_cast<InstancePtr>(raw);
 }
 
@@ -19038,7 +19041,8 @@
                                         Heap::Space heap) {
   const intptr_t instance_size = shared_class_table->SizeAt(cid);
   ASSERT(instance_size > 0);
-  ObjectPtr raw = Object::Allocate(cid, instance_size, heap);
+  ObjectPtr raw =
+      Object::Allocate(cid, instance_size, heap, /*compressed*/ false);
   return static_cast<InstancePtr>(raw);
 }
 
@@ -19462,7 +19466,7 @@
     case Nullability::kNonNullable:
       return "";
     case Nullability::kLegacy:
-      return (FLAG_show_internal_names || name_visibility == kInternalName)
+      return (FLAG_show_internal_names || name_visibility != kUserVisibleName)
                  ? "*"
                  : "";
     default:
@@ -19484,6 +19488,13 @@
   return Symbols::New(thread, printer.buffer());
 }
 
+StringPtr AbstractType::ScrubbedName() const {
+  Thread* thread = Thread::Current();
+  ZoneTextBuffer printer(thread->zone());
+  PrintName(kScrubbedName, &printer);
+  return Symbols::New(thread, printer.buffer());
+}
+
 void AbstractType::PrintName(NameVisibility name_visibility,
                              BaseTextBuffer* printer) const {
   if (IsTypeRef()) {
@@ -19493,11 +19504,9 @@
     ref_type.PrintName(name_visibility, printer);
     return;
   }
-  ASSERT(name_visibility != kScrubbedName);
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
   Class& cls = Class::Handle(zone);
-  String& name_str = String::Handle(zone);
   if (IsTypeParameter()) {
     const TypeParameter& type_param = TypeParameter::Cast(*this);
     printer->AddString(String::Handle(type_param.name()).ToCString());
@@ -19523,14 +19532,7 @@
   cls = type_class();
   // Do not print the full vector, but only the declared type parameters.
   num_type_params = cls.NumTypeParameters();
-  if (name_visibility == kInternalName) {
-    name_str = cls.Name();
-    printer->AddString(name_str.ToCString());
-  } else {
-    ASSERT(name_visibility == kUserVisibleName);
-    // Map internal types to their corresponding public interfaces.
-    printer->AddString(cls.UserVisibleNameCString());
-  }
+  printer->AddString(cls.NameCString(name_visibility));
   if (num_type_params > num_args) {
     first_type_param_index = 0;
     if (!IsFinalized() || IsBeingFinalized()) {
@@ -19617,6 +19619,13 @@
          (type_class() == Type::Handle(Type::IntType()).type_class());
 }
 
+bool AbstractType::IsIntegerImplementationType() const {
+  return HasTypeClass() &&
+         (type_class() == IsolateGroup::Current()
+                              ->object_store()
+                              ->integer_implementation_class());
+}
+
 bool AbstractType::IsDoubleType() const {
   return HasTypeClass() &&
          (type_class() == Type::Handle(Type::Double()).type_class());
@@ -20268,7 +20277,7 @@
 
   // Compare function type parameters and their bounds.
   // Check the type parameters and bounds of generic functions.
-  if (!HasSameTypeParametersAndBounds(other_type, kind)) {
+  if (!HasSameTypeParametersAndBounds(other_type, kind, trail)) {
     return false;
   }
   AbstractType& param_type = Type::Handle(zone);
@@ -20339,6 +20348,7 @@
   return nullability() == Nullability::kNonNullable;
 }
 
+// Keep in sync with TypeSerializationCluster::IsInCanonicalSet.
 AbstractTypePtr Type::Canonicalize(Thread* thread, TrailPtr trail) const {
   Zone* zone = thread->zone();
   ASSERT(IsFinalized());
@@ -20605,7 +20615,8 @@
 }
 
 TypePtr Type::New(Heap::Space space) {
-  ObjectPtr raw = Object::Allocate(Type::kClassId, Type::InstanceSize(), space);
+  ObjectPtr raw = Object::Allocate(Type::kClassId, Type::InstanceSize(), space,
+                                   /*compressed*/ true);
   return static_cast<TypePtr>(raw);
 }
 
@@ -20999,8 +21010,8 @@
 }
 
 TypeRefPtr TypeRef::New() {
-  ObjectPtr raw =
-      Object::Allocate(TypeRef::kClassId, TypeRef::InstanceSize(), Heap::kOld);
+  ObjectPtr raw = Object::Allocate(TypeRef::kClassId, TypeRef::InstanceSize(),
+                                   Heap::kOld, /*compressed*/ true);
   return static_cast<TypeRefPtr>(raw);
 }
 
@@ -21147,10 +21158,12 @@
         return false;
       }
       // Compare bounds.
+      if (TestAndAddBuddyToTrail(&trail, other_type_param)) {
+        return true;
+      }
       AbstractType& type = AbstractType::Handle(bound());
       AbstractType& other_type = AbstractType::Handle(other_type_param.bound());
-      if (!TestAndAddBuddyToTrail(&trail, other_type_param) &&
-          !type.IsEquivalent(other_type, kind, trail)) {
+      if (!type.IsEquivalent(other_type, kind, trail)) {
         return false;
       }
       if (kind == TypeEquality::kCanonical) {
@@ -21194,11 +21207,13 @@
       }
     }
     // Compare bounds.
+    if (TestAndAddBuddyToTrail(&trail, other_type_param)) {
+      return true;
+    }
     AbstractType& upper_bound = AbstractType::Handle(bound());
     AbstractType& other_type_param_upper_bound =
         AbstractType::Handle(other_type_param.bound());
-    if (!TestAndAddBuddyToTrail(&trail, other_type_param) &&
-        !upper_bound.IsEquivalent(other_type_param_upper_bound, kind, trail)) {
+    if (!upper_bound.IsEquivalent(other_type_param_upper_bound, kind, trail)) {
       return false;
     }
   }
@@ -21501,8 +21516,9 @@
 }
 
 TypeParameterPtr TypeParameter::New() {
-  ObjectPtr raw = Object::Allocate(TypeParameter::kClassId,
-                                   TypeParameter::InstanceSize(), Heap::kOld);
+  ObjectPtr raw =
+      Object::Allocate(TypeParameter::kClassId, TypeParameter::InstanceSize(),
+                       Heap::kOld, /*compressed*/ true);
   return static_cast<TypeParameterPtr>(raw);
 }
 
@@ -21936,8 +21952,8 @@
          Class::null());
   Mint& result = Mint::Handle();
   {
-    ObjectPtr raw =
-        Object::Allocate(Mint::kClassId, Mint::InstanceSize(), space);
+    ObjectPtr raw = Object::Allocate(Mint::kClassId, Mint::InstanceSize(),
+                                     space, /*compressed*/ false);
     NoSafepointScope no_safepoint;
     result ^= raw;
   }
@@ -22058,8 +22074,8 @@
          Class::null());
   Double& result = Double::Handle();
   {
-    ObjectPtr raw =
-        Object::Allocate(Double::kClassId, Double::InstanceSize(), space);
+    ObjectPtr raw = Object::Allocate(Double::kClassId, Double::InstanceSize(),
+                                     space, /*compressed*/ false);
     NoSafepointScope no_safepoint;
     result ^= raw;
   }
@@ -23173,7 +23189,8 @@
   }
   {
     ObjectPtr raw = Object::Allocate(OneByteString::kClassId,
-                                     OneByteString::InstanceSize(len), space);
+                                     OneByteString::InstanceSize(len), space,
+                                     /*compressed*/ true);
     NoSafepointScope no_safepoint;
     OneByteStringPtr result = static_cast<OneByteStringPtr>(raw);
     result->untag()->set_length(Smi::New(len));
@@ -23380,7 +23397,8 @@
   String& result = String::Handle();
   {
     ObjectPtr raw = Object::Allocate(TwoByteString::kClassId,
-                                     TwoByteString::InstanceSize(len), space);
+                                     TwoByteString::InstanceSize(len), space,
+                                     /*compressed*/ true);
     NoSafepointScope no_safepoint;
     result ^= raw;
     result.SetLength(len);
@@ -23535,9 +23553,9 @@
   }
   String& result = String::Handle();
   {
-    ObjectPtr raw =
-        Object::Allocate(ExternalOneByteString::kClassId,
-                         ExternalOneByteString::InstanceSize(), space);
+    ObjectPtr raw = Object::Allocate(ExternalOneByteString::kClassId,
+                                     ExternalOneByteString::InstanceSize(),
+                                     space, /*compressed*/ true);
     NoSafepointScope no_safepoint;
     result ^= raw;
     result.SetLength(len);
@@ -23565,9 +23583,9 @@
   }
   String& result = String::Handle();
   {
-    ObjectPtr raw =
-        Object::Allocate(ExternalTwoByteString::kClassId,
-                         ExternalTwoByteString::InstanceSize(), space);
+    ObjectPtr raw = Object::Allocate(ExternalTwoByteString::kClassId,
+                                     ExternalTwoByteString::InstanceSize(),
+                                     space, /*compressed*/ true);
     NoSafepointScope no_safepoint;
     result ^= raw;
     result.SetLength(len);
@@ -23578,23 +23596,6 @@
   return ExternalTwoByteString::raw(result);
 }
 
-BoolPtr Bool::New(bool value) {
-  ASSERT(IsolateGroup::Current()->object_store()->bool_class() !=
-         Class::null());
-  Bool& result = Bool::Handle();
-  {
-    // Since the two boolean instances are singletons we allocate them straight
-    // in the old generation.
-    ObjectPtr raw =
-        Object::Allocate(Bool::kClassId, Bool::InstanceSize(), Heap::kOld);
-    NoSafepointScope no_safepoint;
-    result ^= raw;
-  }
-  result.set_value(value);
-  result.SetCanonical();
-  return result.ptr();
-}
-
 const char* Bool::ToCString() const {
   return value() ? "true" : "false";
 }
@@ -23689,8 +23690,8 @@
     FATAL1("Fatal error in Array::New: invalid len %" Pd "\n", len);
   }
   {
-    ArrayPtr raw = static_cast<ArrayPtr>(
-        Object::Allocate(class_id, Array::InstanceSize(len), space));
+    ArrayPtr raw = static_cast<ArrayPtr>(Object::Allocate(
+        class_id, Array::InstanceSize(len), space, /*compressed*/ false));
     NoSafepointScope no_safepoint;
     raw->untag()->set_length(Smi::New(len));
     return raw;
@@ -23897,9 +23898,9 @@
       Class::null());
   GrowableObjectArray& result = GrowableObjectArray::Handle();
   {
-    ObjectPtr raw =
-        Object::Allocate(GrowableObjectArray::kClassId,
-                         GrowableObjectArray::InstanceSize(), space);
+    ObjectPtr raw = Object::Allocate(GrowableObjectArray::kClassId,
+                                     GrowableObjectArray::InstanceSize(), space,
+                                     /*compressed*/ false);
     NoSafepointScope no_safepoint;
     result ^= raw;
     result.SetLength(0);
@@ -23985,8 +23986,9 @@
          Class::null());
   LinkedHashMap& result = LinkedHashMap::Handle();
   {
-    ObjectPtr raw = Object::Allocate(LinkedHashMap::kClassId,
-                                     LinkedHashMap::InstanceSize(), space);
+    ObjectPtr raw =
+        Object::Allocate(LinkedHashMap::kClassId, LinkedHashMap::InstanceSize(),
+                         space, /*compressed*/ false);
     NoSafepointScope no_safepoint;
     result ^= raw;
   }
@@ -24013,7 +24015,8 @@
   Float32x4& result = Float32x4::Handle();
   {
     ObjectPtr raw =
-        Object::Allocate(Float32x4::kClassId, Float32x4::InstanceSize(), space);
+        Object::Allocate(Float32x4::kClassId, Float32x4::InstanceSize(), space,
+                         /*compressed*/ false);
     NoSafepointScope no_safepoint;
     result ^= raw;
   }
@@ -24030,7 +24033,8 @@
   Float32x4& result = Float32x4::Handle();
   {
     ObjectPtr raw =
-        Object::Allocate(Float32x4::kClassId, Float32x4::InstanceSize(), space);
+        Object::Allocate(Float32x4::kClassId, Float32x4::InstanceSize(), space,
+                         /*compressed*/ false);
     NoSafepointScope no_safepoint;
     result ^= raw;
   }
@@ -24098,8 +24102,8 @@
          Class::null());
   Int32x4& result = Int32x4::Handle();
   {
-    ObjectPtr raw =
-        Object::Allocate(Int32x4::kClassId, Int32x4::InstanceSize(), space);
+    ObjectPtr raw = Object::Allocate(Int32x4::kClassId, Int32x4::InstanceSize(),
+                                     space, /*compressed*/ false);
     NoSafepointScope no_safepoint;
     result ^= raw;
   }
@@ -24115,8 +24119,8 @@
          Class::null());
   Int32x4& result = Int32x4::Handle();
   {
-    ObjectPtr raw =
-        Object::Allocate(Int32x4::kClassId, Int32x4::InstanceSize(), space);
+    ObjectPtr raw = Object::Allocate(Int32x4::kClassId, Int32x4::InstanceSize(),
+                                     space, /*compressed*/ false);
     NoSafepointScope no_safepoint;
     result ^= raw;
   }
@@ -24181,7 +24185,8 @@
   Float64x2& result = Float64x2::Handle();
   {
     ObjectPtr raw =
-        Object::Allocate(Float64x2::kClassId, Float64x2::InstanceSize(), space);
+        Object::Allocate(Float64x2::kClassId, Float64x2::InstanceSize(), space,
+                         /*compressed*/ false);
     NoSafepointScope no_safepoint;
     result ^= raw;
   }
@@ -24196,7 +24201,8 @@
   Float64x2& result = Float64x2::Handle();
   {
     ObjectPtr raw =
-        Object::Allocate(Float64x2::kClassId, Float64x2::InstanceSize(), space);
+        Object::Allocate(Float64x2::kClassId, Float64x2::InstanceSize(), space,
+                         /*compressed*/ false);
     NoSafepointScope no_safepoint;
     result ^= raw;
   }
@@ -24298,8 +24304,9 @@
   TypedData& result = TypedData::Handle();
   {
     const intptr_t length_in_bytes = len * ElementSizeInBytes(class_id);
-    ObjectPtr raw = Object::Allocate(
-        class_id, TypedData::InstanceSize(length_in_bytes), space);
+    ObjectPtr raw =
+        Object::Allocate(class_id, TypedData::InstanceSize(length_in_bytes),
+                         space, /*compressed*/ true);
     NoSafepointScope no_safepoint;
     result ^= raw;
     result.SetLength(len);
@@ -24345,7 +24352,8 @@
   ExternalTypedData& result = ExternalTypedData::Handle();
   {
     ObjectPtr raw =
-        Object::Allocate(class_id, ExternalTypedData::InstanceSize(), space);
+        Object::Allocate(class_id, ExternalTypedData::InstanceSize(), space,
+                         /*compressed*/ true);
     NoSafepointScope no_safepoint;
     result ^= raw;
     result.SetLength(len);
@@ -24366,8 +24374,8 @@
 TypedDataViewPtr TypedDataView::New(intptr_t class_id, Heap::Space space) {
   auto& result = TypedDataView::Handle();
   {
-    ObjectPtr raw =
-        Object::Allocate(class_id, TypedDataView::InstanceSize(), space);
+    ObjectPtr raw = Object::Allocate(class_id, TypedDataView::InstanceSize(),
+                                     space, /*compressed*/ true);
     NoSafepointScope no_safepoint;
     result ^= raw;
     result.Clear();
@@ -24416,7 +24424,8 @@
   cls.EnsureIsAllocateFinalized(Thread::Current());
 
   Pointer& result = Pointer::Handle(zone);
-  result ^= Object::Allocate(kFfiPointerCid, Pointer::InstanceSize(), space);
+  result ^= Object::Allocate(kFfiPointerCid, Pointer::InstanceSize(), space,
+                             /*compressed*/ false);
   result.SetTypeArguments(type_args);
   result.SetNativeAddress(native_address);
 
@@ -24432,8 +24441,9 @@
 
 DynamicLibraryPtr DynamicLibrary::New(void* handle, Heap::Space space) {
   DynamicLibrary& result = DynamicLibrary::Handle();
-  result ^= Object::Allocate(kFfiDynamicLibraryCid,
-                             DynamicLibrary::InstanceSize(), space);
+  result ^=
+      Object::Allocate(kFfiDynamicLibraryCid, DynamicLibrary::InstanceSize(),
+                       space, /*compressed*/ false);
   NoSafepointScope no_safepoint;
   result.SetHandle(handle);
   return result.ptr();
@@ -24455,8 +24465,9 @@
 CapabilityPtr Capability::New(uint64_t id, Heap::Space space) {
   Capability& result = Capability::Handle();
   {
-    ObjectPtr raw = Object::Allocate(Capability::kClassId,
-                                     Capability::InstanceSize(), space);
+    ObjectPtr raw =
+        Object::Allocate(Capability::kClassId, Capability::InstanceSize(),
+                         space, /*compressed*/ false);
     NoSafepointScope no_safepoint;
     result ^= raw;
     result.StoreNonPointer(&result.untag()->id_, id);
@@ -24484,8 +24495,9 @@
 
   ReceivePort& result = ReceivePort::Handle(zone);
   {
-    ObjectPtr raw = Object::Allocate(ReceivePort::kClassId,
-                                     ReceivePort::InstanceSize(), space);
+    ObjectPtr raw =
+        Object::Allocate(ReceivePort::kClassId, ReceivePort::InstanceSize(),
+                         space, /*compressed*/ true);
     NoSafepointScope no_safepoint;
     result ^= raw;
     result.untag()->set_send_port(send_port.ptr());
@@ -24517,7 +24529,8 @@
   SendPort& result = SendPort::Handle();
   {
     ObjectPtr raw =
-        Object::Allocate(SendPort::kClassId, SendPort::InstanceSize(), space);
+        Object::Allocate(SendPort::kClassId, SendPort::InstanceSize(), space,
+                         /*compressed*/ false);
     NoSafepointScope no_safepoint;
     result ^= raw;
     result.StoreNonPointer(&result.untag()->id_, id);
@@ -24543,9 +24556,9 @@
   Thread* thread = Thread::Current();
   TransferableTypedData& result = TransferableTypedData::Handle();
   {
-    ObjectPtr raw =
-        Object::Allocate(TransferableTypedData::kClassId,
-                         TransferableTypedData::InstanceSize(), space);
+    ObjectPtr raw = Object::Allocate(TransferableTypedData::kClassId,
+                                     TransferableTypedData::InstanceSize(),
+                                     space, /*compressed*/ false);
     NoSafepointScope no_safepoint;
     thread->heap()->SetPeer(raw, peer);
     result ^= raw;
@@ -24676,8 +24689,8 @@
                         Heap::Space space) {
   Closure& result = Closure::Handle();
   {
-    ObjectPtr raw =
-        Object::Allocate(Closure::kClassId, Closure::InstanceSize(), space);
+    ObjectPtr raw = Object::Allocate(Closure::kClassId, Closure::InstanceSize(),
+                                     space, /*compressed*/ false);
     NoSafepointScope no_safepoint;
     result ^= raw;
     result.untag()->set_instantiator_type_arguments(
@@ -24691,8 +24704,8 @@
 }
 
 ClosurePtr Closure::New() {
-  ObjectPtr raw =
-      Object::Allocate(Closure::kClassId, Closure::InstanceSize(), Heap::kOld);
+  ObjectPtr raw = Object::Allocate(Closure::kClassId, Closure::InstanceSize(),
+                                   Heap::kOld, /*compressed*/ false);
   return static_cast<ClosurePtr>(raw);
 }
 
@@ -24787,8 +24800,9 @@
                               Heap::Space space) {
   StackTrace& result = StackTrace::Handle();
   {
-    ObjectPtr raw = Object::Allocate(StackTrace::kClassId,
-                                     StackTrace::InstanceSize(), space);
+    ObjectPtr raw =
+        Object::Allocate(StackTrace::kClassId, StackTrace::InstanceSize(),
+                         space, /*compressed*/ true);
     NoSafepointScope no_safepoint;
     result ^= raw;
   }
@@ -24806,8 +24820,9 @@
                               Heap::Space space) {
   StackTrace& result = StackTrace::Handle();
   {
-    ObjectPtr raw = Object::Allocate(StackTrace::kClassId,
-                                     StackTrace::InstanceSize(), space);
+    ObjectPtr raw =
+        Object::Allocate(StackTrace::kClassId, StackTrace::InstanceSize(),
+                         space, /*compressed*/ true);
     NoSafepointScope no_safepoint;
     result ^= raw;
   }
@@ -25113,7 +25128,29 @@
 void RegExp::set_function(intptr_t cid,
                           bool sticky,
                           const Function& value) const {
-  StorePointer(FunctionAddr(cid, sticky), value.ptr());
+  if (sticky) {
+    switch (cid) {
+      case kOneByteStringCid:
+        return untag()->set_one_byte_sticky(value.ptr());
+      case kTwoByteStringCid:
+        return untag()->set_two_byte_sticky(value.ptr());
+      case kExternalOneByteStringCid:
+        return untag()->set_external_one_byte_sticky(value.ptr());
+      case kExternalTwoByteStringCid:
+        return untag()->set_external_two_byte_sticky(value.ptr());
+    }
+  } else {
+    switch (cid) {
+      case kOneByteStringCid:
+        return untag()->set_one_byte(value.ptr());
+      case kTwoByteStringCid:
+        return untag()->set_two_byte(value.ptr());
+      case kExternalOneByteStringCid:
+        return untag()->set_external_one_byte(value.ptr());
+      case kExternalTwoByteStringCid:
+        return untag()->set_external_two_byte(value.ptr());
+    }
+  }
 }
 
 void RegExp::set_bytecode(bool is_one_byte,
@@ -25135,7 +25172,7 @@
 }
 
 void RegExp::set_num_bracket_expressions(intptr_t value) const {
-  untag()->set_num_bracket_expressions(Smi::New(value));
+  untag()->num_bracket_expressions_ = value;
 }
 
 void RegExp::set_capture_name_map(const Array& array) const {
@@ -25145,12 +25182,13 @@
 RegExpPtr RegExp::New(Heap::Space space) {
   RegExp& result = RegExp::Handle();
   {
-    ObjectPtr raw =
-        Object::Allocate(RegExp::kClassId, RegExp::InstanceSize(), space);
+    ObjectPtr raw = Object::Allocate(RegExp::kClassId, RegExp::InstanceSize(),
+                                     space, /*compressed*/ true);
     NoSafepointScope no_safepoint;
     result ^= raw;
     result.set_type(kUninitialized);
     result.set_flags(RegExpFlags());
+    result.set_num_bracket_expressions(-1);
     result.set_num_registers(/*is_one_byte=*/false, -1);
     result.set_num_registers(/*is_one_byte=*/true, -1);
   }
@@ -25225,8 +25263,9 @@
 WeakPropertyPtr WeakProperty::New(Heap::Space space) {
   ASSERT(IsolateGroup::Current()->object_store()->weak_property_class() !=
          Class::null());
-  ObjectPtr raw = Object::Allocate(WeakProperty::kClassId,
-                                   WeakProperty::InstanceSize(), space);
+  ObjectPtr raw =
+      Object::Allocate(WeakProperty::kClassId, WeakProperty::InstanceSize(),
+                       space, /*compressed*/ false);
   return static_cast<WeakPropertyPtr>(raw);
 }
 
@@ -25274,7 +25313,8 @@
   MirrorReference& result = MirrorReference::Handle();
   {
     ObjectPtr raw = Object::Allocate(MirrorReference::kClassId,
-                                     MirrorReference::InstanceSize(), space);
+                                     MirrorReference::InstanceSize(), space,
+                                     /*compressed*/ true);
     NoSafepointScope no_safepoint;
     result ^= raw;
   }
@@ -25311,8 +25351,8 @@
   }
   // No tag with label exists, create and register with isolate tag table.
   {
-    ObjectPtr raw =
-        Object::Allocate(UserTag::kClassId, UserTag::InstanceSize(), space);
+    ObjectPtr raw = Object::Allocate(UserTag::kClassId, UserTag::InstanceSize(),
+                                     space, /*compressed*/ true);
     NoSafepointScope no_safepoint;
     result ^= raw;
   }
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 01cfb33..4f4fb6c 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -613,7 +613,10 @@
   cpp_vtable vtable() const { return bit_copy<cpp_vtable>(*this); }
   void set_vtable(cpp_vtable value) { *vtable_address() = value; }
 
-  static ObjectPtr Allocate(intptr_t cls_id, intptr_t size, Heap::Space space);
+  static ObjectPtr Allocate(intptr_t cls_id,
+                            intptr_t size,
+                            Heap::Space space,
+                            bool compressed);
 
   static intptr_t RoundedAllocationSize(intptr_t size) {
     return Utils::RoundUp(size, kObjectAlignment);
@@ -636,6 +639,13 @@
   void StorePointer(type const* addr, type value) const {
     ptr()->untag()->StorePointer<type, order>(addr, value);
   }
+  template <typename type,
+            typename compressed_type,
+            std::memory_order order = std::memory_order_relaxed>
+  void StoreCompressedPointer(compressed_type const* addr, type value) const {
+    ptr()->untag()->StoreCompressedPointer<type, compressed_type, order>(addr,
+                                                                         value);
+  }
 
   // Use for storing into an explicitly Smi-typed field of an object
   // (i.e., both the previous and new value are Smis).
@@ -725,7 +735,10 @@
     return -kWordSize;
   }
 
-  static void InitializeObject(uword address, intptr_t id, intptr_t size);
+  static void InitializeObject(uword address,
+                               intptr_t id,
+                               intptr_t size,
+                               bool compressed);
 
   static void RegisterClass(const Class& cls,
                             const String& name,
@@ -1740,6 +1753,7 @@
   friend class Intrinsifier;
   friend class ProgramWalker;
   friend class Precompiler;
+  friend class ClassFinalizer;
 };
 
 // Classification of type genericity according to type parameter owners.
@@ -2255,8 +2269,6 @@
   }
 
  private:
-  friend class FlowGraphSerializer;  // For is_megamorphic()
-
   static ICDataPtr New();
 
   // Grows the array and also sets the argument to the index that should be used
@@ -2600,7 +2612,7 @@
   // Generic dispatchers only set the number without actual type parameters.
   bool IsGeneric() const { return NumTypeParameters() > 0; }
   // Return true if any parent function of this function is generic.
-  bool HasGenericParent() const;
+  bool HasGenericParent() const { return NumParentTypeArguments() > 0; }
 
   // Not thread-safe; must be called in the main thread.
   // Sets function's code and code's function.
@@ -2678,41 +2690,8 @@
   // Enclosing function of this local function.
   FunctionPtr parent_function() const;
 
-  enum class DefaultTypeArgumentsKind : uint8_t {
-    // Only here to make sure it's explicitly set appropriately.
-    kInvalid = 0,
-    // Must instantiate the default type arguments before use.
-    kNeedsInstantiation,
-    // The default type arguments are already instantiated.
-    kIsInstantiated,
-    // Use the instantiator type arguments that would be used to instantiate
-    // the default type arguments, as instantiating produces the same result.
-    kSharesInstantiatorTypeArguments,
-    // Use the function type arguments that would be used to instantiate
-    // the default type arguments, as instantiating produces the same result.
-    kSharesFunctionTypeArguments,
-  };
-  static constexpr intptr_t kDefaultTypeArgumentsKindFieldSize = 3;
-  static_assert(static_cast<uint8_t>(
-                    DefaultTypeArgumentsKind::kSharesFunctionTypeArguments) <
-                    (1 << kDefaultTypeArgumentsKindFieldSize),
-                "Wrong bit size chosen for default TAV kind field");
-
-  // 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>;
-  // TODO(regis): Rename to NumParentTypeArgumentsField.
-  // Just use the rest of the space for the number of parent type parameters.
-  using NumParentTypeParametersField =
-      BitField<intptr_t,
-               intptr_t,
-               DefaultTypeArgumentsKindField::kNextBit,
-               compiler::target::kSmiBits -
-                   DefaultTypeArgumentsKindField::kNextBit>;
+  using DefaultTypeArgumentsKind =
+      UntaggedClosureData::DefaultTypeArgumentsKind;
 
   // Returns a canonicalized vector of the type parameters instantiated
   // to bounds. If non-generic, the empty type arguments vector is returned.
@@ -2745,6 +2724,10 @@
   void set_saved_args_desc(const Array& array) const;
   ArrayPtr saved_args_desc() const;
 
+  bool HasSavedArgumentsDescriptor() const {
+    return IsInvokeFieldDispatcher() || IsNoSuchMethodDispatcher();
+  }
+
   void set_accessor_field(const Field& value) const;
   FieldPtr accessor_field() const;
 
@@ -2816,14 +2799,11 @@
   void SetForwardingChecks(const Array& checks) const;
 
   UntaggedFunction::Kind kind() const {
-    return KindBits::decode(untag()->kind_tag_);
-  }
-  static UntaggedFunction::Kind kind(FunctionPtr function) {
-    return KindBits::decode(function->untag()->kind_tag_);
+    return untag()->kind_tag_.Read<KindBits>();
   }
 
   UntaggedFunction::AsyncModifier modifier() const {
-    return ModifierBits::decode(untag()->kind_tag_);
+    return untag()->kind_tag_.Read<ModifierBits>();
   }
 
   static const char* KindToCString(UntaggedFunction::Kind kind);
@@ -2895,7 +2875,6 @@
         return false;
     }
   }
-  bool IsInFactoryScope() const;
 
   bool NeedsTypeArgumentTypeChecks() const {
     return !(is_static() || (kind() == UntaggedFunction::kConstructor));
@@ -3066,7 +3045,7 @@
   bool CanBeInlined() const;
 
   MethodRecognizer::Kind recognized_kind() const {
-    return RecognizedBits::decode(untag()->kind_tag_);
+    return untag()->kind_tag_.Read<RecognizedBits>();
   }
   void set_recognized_kind(MethodRecognizer::Kind value) const;
 
@@ -3352,8 +3331,13 @@
     return IsImplicitClosureFunction() && !is_static();
   }
 
-  // Returns true if this function represents a local function.
-  bool IsLocalFunction() const { return parent_function() != Function::null(); }
+  // Returns true if this function has a parent function.
+  bool HasParent() const { return parent_function() != Function::null(); }
+
+  // Returns true if this function is a local function.
+  bool IsLocalFunction() const {
+    return !IsImplicitClosureFunction() && HasParent();
+  }
 
   // Returns true if this function represents an ffi trampoline.
   bool IsFfiTrampoline() const {
@@ -3361,7 +3345,7 @@
   }
   static bool IsFfiTrampoline(FunctionPtr function) {
     NoSafepointScope no_safepoint;
-    return KindBits::decode(function->untag()->kind_tag_) ==
+    return function->untag()->kind_tag_.Read<KindBits>() ==
            UntaggedFunction::kFfiTrampoline;
   }
 
@@ -3462,7 +3446,7 @@
   //      }
   //   }
   bool IsSyncGenClosure() const {
-    return (parent_function() != Function::null()) &&
+    return is_generated_body() &&
            Function::Handle(parent_function()).IsSyncGenClosureMaker();
   }
 
@@ -3631,6 +3615,8 @@
   // has_pragma: Has a @pragma decoration.
   // no_such_method_forwarder: A stub method that just calls noSuchMethod.
 
+// Bits that are set when function is created, don't have to worry about
+// concurrent updates.
 #define FOR_EACH_FUNCTION_KIND_BIT(V)                                          \
   V(Static, is_static)                                                         \
   V(Const, is_const)                                                           \
@@ -3638,7 +3624,6 @@
   V(Reflectable, is_reflectable)                                               \
   V(Visible, is_visible)                                                       \
   V(Debuggable, is_debuggable)                                                 \
-  V(Inlinable, is_inlinable)                                                   \
   V(Intrinsic, is_intrinsic)                                                   \
   V(Native, is_native)                                                         \
   V(External, is_external)                                                     \
@@ -3647,15 +3632,27 @@
   V(HasPragma, has_pragma)                                                     \
   V(IsSynthetic, is_synthetic)                                                 \
   V(IsExtensionMember, is_extension_member)
+// Bit that is updated after function is constructed, has to be updated in
+// concurrent-safe manner.
+#define FOR_EACH_FUNCTION_VOLATILE_KIND_BIT(V)                                 \
+  V(Inlinable, is_inlinable)
 
 #define DEFINE_ACCESSORS(name, accessor_name)                                  \
   void set_##accessor_name(bool value) const {                                 \
-    set_kind_tag(name##Bit::update(value, untag()->kind_tag_));                \
+    untag()->kind_tag_.UpdateUnsynchronized<name##Bit>(value);                 \
   }                                                                            \
-  bool accessor_name() const { return name##Bit::decode(untag()->kind_tag_); }
+  bool accessor_name() const { return untag()->kind_tag_.Read<name##Bit>(); }
   FOR_EACH_FUNCTION_KIND_BIT(DEFINE_ACCESSORS)
 #undef DEFINE_ACCESSORS
 
+#define DEFINE_ACCESSORS(name, accessor_name)                                  \
+  void set_##accessor_name(bool value) const {                                 \
+    untag()->kind_tag_.UpdateBool<name##Bit>(value);                           \
+  }                                                                            \
+  bool accessor_name() const { return untag()->kind_tag_.Read<name##Bit>(); }
+  FOR_EACH_FUNCTION_VOLATILE_KIND_BIT(DEFINE_ACCESSORS)
+#undef DEFINE_ACCESSORS
+
   // optimizable: Candidate for going through the optimizing compiler. False for
   //              some functions known to be execute infrequently and functions
   //              which have been de-optimized too many times.
@@ -3678,6 +3675,7 @@
 // Single bit sized fields start here.
 #define DECLARE_BIT(name, _) k##name##Bit,
     FOR_EACH_FUNCTION_KIND_BIT(DECLARE_BIT)
+    FOR_EACH_FUNCTION_VOLATILE_KIND_BIT(DECLARE_BIT)
 #undef DECLARE_BIT
         kNumTagBits
   };
@@ -3705,6 +3703,7 @@
 #define DEFINE_BIT(name, _)                                                    \
   class name##Bit : public BitField<uint32_t, bool, k##name##Bit, 1> {};
   FOR_EACH_FUNCTION_KIND_BIT(DEFINE_BIT)
+  FOR_EACH_FUNCTION_VOLATILE_KIND_BIT(DEFINE_BIT)
 #undef DEFINE_BIT
 
  private:
@@ -3727,6 +3726,8 @@
   void set_eval_script(const Script& value) const;
   void set_num_optional_parameters(intptr_t value) const;  // Encoded value.
   void set_kind_tag(uint32_t value) const;
+
+  ObjectPtr data() const { return untag()->data(); }
   void set_data(const Object& value) const;
 
   static FunctionPtr New(Heap::Space space = Heap::kOld);
@@ -3740,6 +3741,7 @@
   friend class UntaggedFunction;
   friend class ClassFinalizer;  // To reset parent_function.
   friend class Type;            // To adjust parent_function.
+  friend class Precompiler;     // To access closure data.
   friend class ProgramVisitor;  // For set_parameter_types/names.
 };
 
@@ -3752,17 +3754,26 @@
   static intptr_t default_type_arguments_offset() {
     return OFFSET_OF(UntaggedClosureData, default_type_arguments_);
   }
-  static intptr_t default_type_arguments_info_offset() {
-    return OFFSET_OF(UntaggedClosureData, default_type_arguments_info_);
+  static intptr_t default_type_arguments_kind_offset() {
+    return OFFSET_OF(UntaggedClosureData, default_type_arguments_kind_);
   }
 
+  using DefaultTypeArgumentsKind =
+      UntaggedClosureData::DefaultTypeArgumentsKind;
+
  private:
-  ContextScopePtr context_scope() const { return untag()->context_scope_; }
+  ContextScopePtr context_scope() const { return untag()->context_scope(); }
   void set_context_scope(const ContextScope& value) const;
 
   // Enclosing function of this local function.
-  FunctionPtr parent_function() const { return untag()->parent_function_; }
+#if defined(DART_PRECOMPILER)
+  // Can be WSR wrapped in the precompiler.
+  ObjectPtr parent_function() const { return untag()->parent_function(); }
+  void set_parent_function(const Object& value) const;
+#else
+  FunctionPtr parent_function() const { return untag()->parent_function(); }
   void set_parent_function(const Function& value) const;
+#endif
 
   InstancePtr implicit_static_closure() const {
     return untag()->closure<std::memory_order_acquire>();
@@ -3770,12 +3781,12 @@
   void set_implicit_static_closure(const Instance& closure) const;
 
   TypeArgumentsPtr default_type_arguments() const {
-    return untag()->default_type_arguments_;
+    return untag()->default_type_arguments();
   }
   void set_default_type_arguments(const TypeArguments& value) const;
 
-  intptr_t default_type_arguments_info() const;
-  void set_default_type_arguments_info(intptr_t value) const;
+  DefaultTypeArgumentsKind default_type_arguments_kind() const;
+  void set_default_type_arguments_kind(DefaultTypeArgumentsKind value) const;
 
   static ClosureDataPtr New();
 
@@ -3783,6 +3794,7 @@
   friend class Class;
   friend class Function;
   friend class HeapProfiler;
+  friend class Precompiler;  // To wrap parent functions in WSRs.
 };
 
 enum class EntryPointPragma {
@@ -4090,7 +4102,8 @@
     set_guarded_cid_unsafe(cid);
   }
   void set_guarded_cid_unsafe(intptr_t cid) const {
-    StoreNonPointer(&untag()->guarded_cid_, cid);
+    StoreNonPointer<ClassIdTagType, ClassIdTagType, std::memory_order_relaxed>(
+        &untag()->guarded_cid_, cid);
   }
   static intptr_t guarded_cid_offset() {
     return OFFSET_OF(UntaggedField, guarded_cid_);
@@ -7079,7 +7092,7 @@
   }
 
   InstancePtr Canonicalize(Thread* thread) const;
-  // Caller must hold Isolate::constant_canonicalization_mutex_.
+  // Caller must hold IsolateGroup::constant_canonicalization_mutex_.
   virtual InstancePtr CanonicalizeLocked(Thread* thread) const;
   virtual void CanonicalizeFieldsLocked(Thread* thread) const;
 
@@ -7116,9 +7129,18 @@
 
   // Return true if the null instance can be assigned to a variable of [other]
   // type. Return false if null cannot be assigned or we cannot tell (if
-  // [other] is a type parameter in NNBD strong mode).
+  // [other] is a type parameter in NNBD strong mode). Only used for checks at
+  // compile time.
   static bool NullIsAssignableTo(const AbstractType& other);
 
+  // Return true if the null instance can be assigned to a variable of [other]
+  // type. Return false if null cannot be assigned. Used for checks at runtime,
+  // when the instantiator and function type argument vectors are available.
+  static bool NullIsAssignableTo(
+      const AbstractType& other,
+      const TypeArguments& other_instantiator_type_arguments,
+      const TypeArguments& other_function_type_arguments);
+
   bool IsValidNativeIndex(int index) const {
     return ((index >= 0) && (index < clazz()->untag()->num_native_fields_));
   }
@@ -7346,10 +7368,12 @@
   // 2 bits per type:
   //  - the high bit is set if the type is nullable or legacy.
   //  - the low bit is set if the type is nullable.
-  // The nullabilty is 0 if the vector is longer than kNullabilityMaxTypes.
+  // The nullability is 0 if the vector is longer than kNullabilityMaxTypes.
   // The condition evaluated at runtime to decide whether UTA can share ITA is
   //   (UTA.nullability & ITA.nullability) == UTA.nullability
-  // Note that this allows for ITA to be longer than UTA.
+  // Note that this allows for ITA to be longer than UTA (the bit vector must be
+  // stored in the same order as the corresponding type vector, i.e. with the
+  // least significant 2 bits representing the nullability of the first type).
   static const intptr_t kNullabilityBitsPerType = 2;
   static const intptr_t kNullabilityMaxTypes =
       kSmiBits / kNullabilityBitsPerType;
@@ -7458,7 +7482,7 @@
   // Return true if all types of this vector are finalized.
   bool IsFinalized() const;
 
-  // Caller must hold Isolate::constant_canonicalization_mutex_.
+  // Caller must hold IsolateGroup::constant_canonicalization_mutex_.
   virtual InstancePtr CanonicalizeLocked(Thread* thread) const {
     return Canonicalize(thread, nullptr);
   }
@@ -7648,7 +7672,7 @@
       Heap::Space space,
       TrailPtr trail = nullptr) const;
 
-  // Caller must hold Isolate::constant_canonicalization_mutex_.
+  // Caller must hold IsolateGroup::constant_canonicalization_mutex_.
   virtual InstancePtr CanonicalizeLocked(Thread* thread) const {
     return Canonicalize(thread, nullptr);
   }
@@ -7700,6 +7724,10 @@
   // Names of internal classes are mapped to their public interfaces.
   virtual StringPtr UserVisibleName() const;
 
+  // The name of this type, including the names of its type arguments, if any.
+  // Privacy suffixes are dropped.
+  virtual StringPtr ScrubbedName() const;
+
   // Return the internal or public name of this type, including the names of its
   // type arguments, if any.
   void PrintName(NameVisibility visibility, BaseTextBuffer* printer) const;
@@ -7751,6 +7779,9 @@
   // Check if this type represents the 'int' type.
   bool IsIntType() const;
 
+  // Check if this type represents the '_IntegerImplementation' type.
+  bool IsIntegerImplementationType() const;
+
   // Check if this type represents the 'double' type.
   bool IsDoubleType() const;
 
@@ -7769,6 +7800,9 @@
   // Check if this type represents the '_Smi' type.
   bool IsSmiType() const { return type_class_id() == kSmiCid; }
 
+  // Check if this type represents the '_Mint' type.
+  bool IsMintType() const { return type_class_id() == kMintCid; }
+
   // Check if this type represents the 'String' type.
   bool IsStringType() const;
 
@@ -8192,7 +8226,8 @@
   // with equal bounds as the other function type. Type parameter names and
   // parameter names (unless optional named) are ignored.
   bool HasSameTypeParametersAndBounds(const FunctionType& other,
-                                      TypeEquality kind) const;
+                                      TypeEquality kind,
+                                      TrailPtr trail = nullptr) const;
 
   // Return true if this function type declares type parameters.
   bool IsGeneric() const { return NumTypeParameters(Thread::Current()) > 0; }
@@ -8464,7 +8499,7 @@
   StringPtr ToString(Heap::Space space) const;
 
   // Numbers are canonicalized differently from other instances/strings.
-  // Caller must hold Isolate::constant_canonicalization_mutex_.
+  // Caller must hold IsolateGroup::constant_canonicalization_mutex_.
   virtual InstancePtr CanonicalizeLocked(Thread* thread) const;
 
 #if defined(DEBUG)
@@ -8540,9 +8575,8 @@
                      Heap::Space space = Heap::kNew) const;
 
   static int64_t GetInt64Value(const IntegerPtr obj) {
-    intptr_t raw_value = static_cast<intptr_t>(obj);
-    if ((raw_value & kSmiTagMask) == kSmiTag) {
-      return (raw_value >> kSmiTagShift);
+    if (obj->IsSmi()) {
+      return RawSmiValue(static_cast<const SmiPtr>(obj));
     } else {
       ASSERT(obj->IsMint());
       return static_cast<const MintPtr>(obj)->untag()->value_;
@@ -8866,7 +8900,7 @@
   bool EndsWith(const String& other) const;
 
   // Strings are canonicalized using the symbol table.
-  // Caller must hold Isolate::constant_canonicalization_mutex_.
+  // Caller must hold IsolateGroup::constant_canonicalization_mutex_.
   virtual InstancePtr CanonicalizeLocked(Thread* thread) const;
 
 #if defined(DEBUG)
@@ -9569,11 +9603,6 @@
   }
 
  private:
-  void set_value(bool value) const { StoreNonPointer(&untag()->value_, value); }
-
-  // New should only be called to initialize the two legal bool values.
-  static BoolPtr New(bool value);
-
   FINAL_HEAP_OBJECT_IMPLEMENTATION(Bool, Instance);
   friend class Class;
   friend class Object;  // To initialize the true and false values.
@@ -10953,18 +10982,18 @@
   }
 
   StringPtr pattern() const { return untag()->pattern(); }
-  SmiPtr num_bracket_expressions() const {
-    return untag()->num_bracket_expressions();
+  intptr_t num_bracket_expressions() const {
+    return untag()->num_bracket_expressions_;
   }
   ArrayPtr capture_name_map() const { return untag()->capture_name_map(); }
 
   TypedDataPtr bytecode(bool is_one_byte, bool sticky) const {
     if (sticky) {
-      return TypedData::RawCast(is_one_byte ? untag()->one_byte_sticky_
-                                            : untag()->two_byte_sticky_);
+      return TypedData::RawCast(is_one_byte ? untag()->one_byte_sticky()
+                                            : untag()->two_byte_sticky());
     } else {
-      return TypedData::RawCast(is_one_byte ? untag()->one_byte_
-                                            : untag()->two_byte_);
+      return TypedData::RawCast(is_one_byte ? untag()->one_byte()
+                                            : untag()->two_byte());
     }
   }
 
@@ -10997,13 +11026,33 @@
     return -1;
   }
 
-  FunctionPtr* FunctionAddr(intptr_t cid, bool sticky) const {
-    return reinterpret_cast<FunctionPtr*>(
-        FieldAddrAtOffset(function_offset(cid, sticky)));
-  }
-
   FunctionPtr function(intptr_t cid, bool sticky) const {
-    return *FunctionAddr(cid, sticky);
+    if (sticky) {
+      switch (cid) {
+        case kOneByteStringCid:
+          return static_cast<FunctionPtr>(untag()->one_byte_sticky());
+        case kTwoByteStringCid:
+          return static_cast<FunctionPtr>(untag()->two_byte_sticky());
+        case kExternalOneByteStringCid:
+          return static_cast<FunctionPtr>(untag()->external_one_byte_sticky());
+        case kExternalTwoByteStringCid:
+          return static_cast<FunctionPtr>(untag()->external_two_byte_sticky());
+      }
+    } else {
+      switch (cid) {
+        case kOneByteStringCid:
+          return static_cast<FunctionPtr>(untag()->one_byte());
+        case kTwoByteStringCid:
+          return static_cast<FunctionPtr>(untag()->two_byte());
+        case kExternalOneByteStringCid:
+          return static_cast<FunctionPtr>(untag()->external_one_byte());
+        case kExternalTwoByteStringCid:
+          return static_cast<FunctionPtr>(untag()->external_two_byte());
+      }
+    }
+
+    UNREACHABLE();
+    return Function::null();
   }
 
   void set_pattern(const String& pattern) const;
@@ -11012,6 +11061,8 @@
                     bool sticky,
                     const TypedData& bytecode) const;
 
+  void set_num_bracket_expressions(SmiPtr value) const;
+  void set_num_bracket_expressions(const Smi& value) const;
   void set_num_bracket_expressions(intptr_t value) const;
   void set_capture_name_map(const Array& array) const;
   void set_is_global() const {
@@ -11256,7 +11307,7 @@
 #if !defined(DART_PRECOMPILED_RUNTIME)
   return field->untag()->target_offset_;
 #else
-  return Smi::Value(field->untag()->host_offset_or_field_id_);
+  return Smi::Value(field->untag()->host_offset_or_field_id());
 #endif  //  !defined(DART_PRECOMPILED_RUNTIME)
 }
 
@@ -11395,7 +11446,7 @@
 
 inline intptr_t FunctionType::Hash() const {
   ASSERT(IsFinalized());
-  intptr_t result = Smi::Value(untag()->hash_);
+  intptr_t result = Smi::Value(untag()->hash());
   if (result != 0) {
     return result;
   }
@@ -11405,7 +11456,7 @@
 inline void FunctionType::SetHash(intptr_t value) const {
   // This is only safe because we create a new Smi, which does not cause
   // heap allocation.
-  StoreSmi(&untag()->hash_, Smi::New(value));
+  untag()->set_hash(Smi::New(value));
 }
 
 inline intptr_t TypeParameter::Hash() const {
diff --git a/runtime/vm/object_graph.cc b/runtime/vm/object_graph.cc
index 0b7cd00..c9b0bf3 100644
--- a/runtime/vm/object_graph.cc
+++ b/runtime/vm/object_graph.cc
@@ -905,7 +905,7 @@
                           sizeof(double));
     } else if (cid == kOneByteStringCid) {
       OneByteStringPtr str = static_cast<OneByteStringPtr>(obj);
-      intptr_t len = Smi::Value(str->untag()->length_);
+      intptr_t len = Smi::Value(str->untag()->length());
       intptr_t trunc_len = Utils::Minimum(len, kMaxStringElements);
       writer_->WriteUnsigned(kLatin1Data);
       writer_->WriteUnsigned(len);
@@ -913,7 +913,7 @@
       writer_->WriteBytes(&str->untag()->data()[0], trunc_len);
     } else if (cid == kExternalOneByteStringCid) {
       ExternalOneByteStringPtr str = static_cast<ExternalOneByteStringPtr>(obj);
-      intptr_t len = Smi::Value(str->untag()->length_);
+      intptr_t len = Smi::Value(str->untag()->length());
       intptr_t trunc_len = Utils::Minimum(len, kMaxStringElements);
       writer_->WriteUnsigned(kLatin1Data);
       writer_->WriteUnsigned(len);
@@ -921,7 +921,7 @@
       writer_->WriteBytes(&str->untag()->external_data_[0], trunc_len);
     } else if (cid == kTwoByteStringCid) {
       TwoByteStringPtr str = static_cast<TwoByteStringPtr>(obj);
-      intptr_t len = Smi::Value(str->untag()->length_);
+      intptr_t len = Smi::Value(str->untag()->length());
       intptr_t trunc_len = Utils::Minimum(len, kMaxStringElements);
       writer_->WriteUnsigned(kUTF16Data);
       writer_->WriteUnsigned(len);
@@ -929,7 +929,7 @@
       writer_->WriteBytes(&str->untag()->data()[0], trunc_len * 2);
     } else if (cid == kExternalTwoByteStringCid) {
       ExternalTwoByteStringPtr str = static_cast<ExternalTwoByteStringPtr>(obj);
-      intptr_t len = Smi::Value(str->untag()->length_);
+      intptr_t len = Smi::Value(str->untag()->length());
       intptr_t trunc_len = Utils::Minimum(len, kMaxStringElements);
       writer_->WriteUnsigned(kUTF16Data);
       writer_->WriteUnsigned(len);
@@ -953,14 +953,14 @@
     } else if (IsTypedDataClassId(cid)) {
       writer_->WriteUnsigned(kLengthData);
       writer_->WriteUnsigned(
-          Smi::Value(static_cast<TypedDataPtr>(obj)->untag()->length_));
+          Smi::Value(static_cast<TypedDataPtr>(obj)->untag()->length()));
     } else if (IsExternalTypedDataClassId(cid)) {
       writer_->WriteUnsigned(kLengthData);
-      writer_->WriteUnsigned(
-          Smi::Value(static_cast<ExternalTypedDataPtr>(obj)->untag()->length_));
+      writer_->WriteUnsigned(Smi::Value(
+          static_cast<ExternalTypedDataPtr>(obj)->untag()->length()));
     } else if (cid == kFunctionCid) {
       writer_->WriteUnsigned(kNameData);
-      ScrubAndWriteUtf8(static_cast<FunctionPtr>(obj)->untag()->name_);
+      ScrubAndWriteUtf8(static_cast<FunctionPtr>(obj)->untag()->name());
     } else if (cid == kCodeCid) {
       ObjectPtr owner = static_cast<CodePtr>(obj)->untag()->owner_;
       if (!owner->IsHeapObject()) {
@@ -969,25 +969,25 @@
         writer_->WriteUnsigned(kNoData);
       } else if (owner->IsFunction()) {
         writer_->WriteUnsigned(kNameData);
-        ScrubAndWriteUtf8(static_cast<FunctionPtr>(owner)->untag()->name_);
+        ScrubAndWriteUtf8(static_cast<FunctionPtr>(owner)->untag()->name());
       } else if (owner->IsClass()) {
         writer_->WriteUnsigned(kNameData);
-        ScrubAndWriteUtf8(static_cast<ClassPtr>(owner)->untag()->name_);
+        ScrubAndWriteUtf8(static_cast<ClassPtr>(owner)->untag()->name());
       } else {
         writer_->WriteUnsigned(kNoData);
       }
     } else if (cid == kFieldCid) {
       writer_->WriteUnsigned(kNameData);
-      ScrubAndWriteUtf8(static_cast<FieldPtr>(obj)->untag()->name_);
+      ScrubAndWriteUtf8(static_cast<FieldPtr>(obj)->untag()->name());
     } else if (cid == kClassCid) {
       writer_->WriteUnsigned(kNameData);
-      ScrubAndWriteUtf8(static_cast<ClassPtr>(obj)->untag()->name_);
+      ScrubAndWriteUtf8(static_cast<ClassPtr>(obj)->untag()->name());
     } else if (cid == kLibraryCid) {
       writer_->WriteUnsigned(kNameData);
-      ScrubAndWriteUtf8(static_cast<LibraryPtr>(obj)->untag()->url_);
+      ScrubAndWriteUtf8(static_cast<LibraryPtr>(obj)->untag()->url());
     } else if (cid == kScriptCid) {
       writer_->WriteUnsigned(kNameData);
-      ScrubAndWriteUtf8(static_cast<ScriptPtr>(obj)->untag()->url_);
+      ScrubAndWriteUtf8(static_cast<ScriptPtr>(obj)->untag()->url());
     } else {
       writer_->WriteUnsigned(kNoData);
     }
diff --git a/runtime/vm/object_service.cc b/runtime/vm/object_service.cc
index 3989db4..9edd135 100644
--- a/runtime/vm/object_service.cc
+++ b/runtime/vm/object_service.cc
@@ -7,6 +7,7 @@
 #include "vm/compiler/assembler/disassembler.h"
 #include "vm/debugger.h"
 #include "vm/object.h"
+#include "vm/object_graph.h"
 #include "vm/object_store.h"
 #include "vm/resolver.h"
 #include "vm/stub_code.h"
@@ -998,6 +999,12 @@
 
 void Instance::PrintSharedInstanceJSON(JSONObject* jsobj, bool ref) const {
   AddCommonObjectProperties(jsobj, "Instance", ref);
+  {
+    NoSafepointScope safepoint_scope;
+    uint32_t hash_code = HeapSnapshotWriter::GetHeapSnapshotIdentityHash(
+        Thread::Current(), ptr());
+    jsobj->AddProperty64("identityHashCode", hash_code);
+  }
   if (ref) {
     return;
   }
diff --git a/runtime/vm/object_store.h b/runtime/vm/object_store.h
index 7554f4d..a452fd3 100644
--- a/runtime/vm/object_store.h
+++ b/runtime/vm/object_store.h
@@ -158,6 +158,9 @@
   RW(GrowableObjectArray, pending_classes)                                     \
   RW(Instance, stack_overflow)                                                 \
   RW(Instance, out_of_memory)                                                  \
+  RW(Function, _object_equals_function)                                        \
+  RW(Function, _object_hash_code_function)                                     \
+  RW(Function, _object_to_string_function)                                     \
   RW(Function, lookup_port_handler)                                            \
   RW(Function, lookup_open_ports)                                              \
   RW(Function, handle_message_function)                                        \
@@ -169,9 +172,6 @@
   RW(Function, complete_on_async_return)                                       \
   RW(Function, complete_on_async_error)                                        \
   RW(Class, async_star_stream_controller)                                      \
-  RW(GrowableObjectArray, llvm_constant_pool)                                  \
-  RW(GrowableObjectArray, llvm_function_pool)                                  \
-  RW(Array, llvm_constant_hash_table)                                          \
   RW(CompressedStackMaps, canonicalized_stack_map_entries)                     \
   RW(ObjectPool, global_object_pool)                                           \
   RW(Array, unique_dynamic_targets)                                            \
diff --git a/runtime/vm/object_test.cc b/runtime/vm/object_test.cc
index ebd6127..8d94071 100644
--- a/runtime/vm/object_test.cc
+++ b/runtime/vm/object_test.cc
@@ -2878,7 +2878,7 @@
   EXPECT(Smi::Cast(result).Value() == kSmiTestValue);
 }
 
-#if defined(ARCH_IS_64_BIT)
+#if defined(ARCH_IS_64_BIT) && !defined(DART_COMPRESSED_POINTERS)
 // Test for Embedded Smi object in the instructions.
 ISOLATE_UNIT_TEST_CASE(EmbedSmiIn64BitCode) {
   extern void GenerateEmbedSmiInCode(compiler::Assembler * assembler,
@@ -2898,7 +2898,7 @@
       Object::Handle(DartEntry::InvokeFunction(function, Array::empty_array()));
   EXPECT(Smi::Cast(result).Value() == kSmiTestValue);
 }
-#endif  // ARCH_IS_64_BIT
+#endif  // ARCH_IS_64_BIT && !DART_COMPRESSED_POINTERS
 
 ISOLATE_UNIT_TEST_CASE(ExceptionHandlers) {
   const int kNumEntries = 4;
@@ -4452,6 +4452,7 @@
         "\"_vmType\":\"Bool\","
         "\"class\":{\"type\":\"@Class\",\"fixedId\":true,\"id\":\"\","
         "\"name\":\"bool\"},"
+        "\"identityHashCode\":0,"
         "\"kind\":\"Bool\","
         "\"fixedId\":true,"
         "\"id\":\"objects\\/bool-true\",\"valueAsString\":\"true\"}",
@@ -4470,6 +4471,7 @@
         "\"class\":{\"type\":\"@Class\",\"fixedId\":true,\"id\":\"\","
         "\"name\":\"_Smi\","
         "\"_vmName\":\"\"},"
+        "\"identityHashCode\":0,"
         "\"kind\":\"Int\","
         "\"fixedId\":true,"
         "\"id\":\"objects\\/int-7\",\"valueAsString\":\"7\"}",
@@ -4488,6 +4490,7 @@
         "\"_vmType\":\"Mint\","
         "\"class\":{\"type\":\"@Class\",\"fixedId\":true,\"id\":\"\","
         "\"name\":\"_Mint\",\"_vmName\":\"\"},"
+        "\"identityHashCode\":0,"
         "\"kind\":\"Int\","
         "\"id\":\"\",\"valueAsString\":\"-9223372036854775808\"}",
         buffer);
@@ -4505,6 +4508,7 @@
         "\"_vmType\":\"Double\","
         "\"class\":{\"type\":\"@Class\",\"fixedId\":true,\"id\":\"\","
         "\"name\":\"_Double\",\"_vmName\":\"\"},"
+        "\"identityHashCode\":0,"
         "\"kind\":\"Double\","
         "\"id\":\"\",\"valueAsString\":\"0.1234\"}",
         buffer);
@@ -4522,6 +4526,7 @@
         "\"_vmType\":\"String\","
         "\"class\":{\"type\":\"@Class\",\"fixedId\":true,\"id\":\"\","
         "\"name\":\"_OneByteString\",\"_vmName\":\"\"},"
+        "\"identityHashCode\":0,"
         "\"kind\":\"String\","
         "\"id\":\"\",\"length\":2,\"valueAsString\":\"dw\"}",
         buffer);
@@ -4539,6 +4544,7 @@
         "\"_vmType\":\"Array\","
         "\"class\":{\"type\":\"@Class\",\"fixedId\":true,\"id\":\"\","
         "\"name\":\"_List\",\"_vmName\":\"\"},"
+        "\"identityHashCode\":0,"
         "\"kind\":\"List\","
         "\"id\":\"\",\"length\":0}",
         buffer);
@@ -4558,6 +4564,7 @@
         "\"class\":{\"type\":\"@Class\",\"fixedId\":true,\"id\":\"\","
         "\"name\":\"_GrowableList\","
         "\"_vmName\":\"\"},"
+        "\"identityHashCode\":0,"
         "\"kind\":\"List\","
         "\"id\":\"\",\"length\":0}",
         buffer);
@@ -4576,6 +4583,7 @@
         "\"_vmType\":\"LinkedHashMap\","
         "\"class\":{\"type\":\"@Class\",\"fixedId\":true,\"id\":\"\","
         "\"name\":\"_InternalLinkedHashMap\",\"_vmName\":\"\"},"
+        "\"identityHashCode\":0,"
         "\"kind\":\"Map\","
         "\"id\":\"\","
         "\"length\":0}",
@@ -4589,11 +4597,15 @@
     ElideJSONSubstring("classes", js.ToCString(), buffer);
     ElideJSONSubstring("objects", buffer, buffer);
     ElideJSONSubstring("_UserTag@", buffer, buffer);
-    EXPECT_STREQ(
+    EXPECT_SUBSTRING(
         "{\"type\":\"@Instance\","
         "\"_vmType\":\"UserTag\","
         "\"class\":{\"type\":\"@Class\",\"fixedId\":true,\"id\":\"\","
         "\"name\":\"_UserTag\",\"_vmName\":\"\"},"
+        // Handle non-zero identity hash.
+        "\"identityHashCode\":",
+        buffer);
+    EXPECT_SUBSTRING(
         "\"kind\":\"PlainInstance\","
         "\"id\":\"\"}",
         buffer);
@@ -4608,11 +4620,15 @@
     ElideJSONSubstring("classes", js.ToCString(), buffer);
     ElideJSONSubstring("objects", buffer, buffer);
     ElideJSONSubstring("_Type@", buffer, buffer);
-    EXPECT_STREQ(
+    EXPECT_SUBSTRING(
         "{\"type\":\"@Instance\","
         "\"_vmType\":\"Type\","
         "\"class\":{\"type\":\"@Class\",\"fixedId\":true,\"id\":\"\","
         "\"name\":\"_Type\",\"_vmName\":\"\"},"
+        // Handle non-zero identity hash.
+        "\"identityHashCode\":",
+        buffer);
+    EXPECT_SUBSTRING(
         "\"kind\":\"Type\","
         "\"fixedId\":true,\"id\":\"\","
         "\"typeClass\":{\"type\":\"@Class\",\"fixedId\":true,\"id\":\"\","
diff --git a/runtime/vm/os_fuchsia.cc b/runtime/vm/os_fuchsia.cc
index 674bdd5..46c4303 100644
--- a/runtime/vm/os_fuchsia.cc
+++ b/runtime/vm/os_fuchsia.cc
@@ -80,23 +80,21 @@
 // Under normal operation, all metric values below should be zero.
 class InspectMetrics {
  public:
-  // Does not take ownership of inspector.
-  explicit InspectMetrics(inspect::Inspector* inspector)
-      : inspector_(inspector),
-        root_(inspector_->GetRoot()),
-        metrics_(root_.CreateChild("os")),
-        dst_status_(metrics_.CreateInt("dst_status", kUninitialized)),
-        tz_data_status_(metrics_.CreateInt("tz_data_status", kUninitialized)),
+  // Takes ownership of the vm_node.
+  explicit InspectMetrics(std::unique_ptr<inspect::Node> vm_node)
+      : vm_node_(std::move(vm_node)),
+        dst_status_(vm_node_->CreateInt("dst_status", kUninitialized)),
+        tz_data_status_(vm_node_->CreateInt("tz_data_status", kUninitialized)),
         tz_data_close_status_(
-            metrics_.CreateInt("tz_data_close_status", kUninitialized)),
+            vm_node_->CreateInt("tz_data_close_status", kUninitialized)),
         get_profile_status_(
-            metrics_.CreateInt("get_profile_status", kUninitialized)),
+            vm_node_->CreateInt("get_profile_status", kUninitialized)),
         profiles_timezone_content_status_(
-            metrics_.CreateInt("timezone_content_status", kOk)),
-        num_get_profile_calls_(metrics_.CreateInt("num_get_profile_calls", 0)),
-        num_on_change_calls_(metrics_.CreateInt("num_on_change_calls", 0)),
+            vm_node_->CreateInt("timezone_content_status", kOk)),
+        num_get_profile_calls_(vm_node_->CreateInt("num_get_profile_calls", 0)),
+        num_on_change_calls_(vm_node_->CreateInt("num_on_change_calls", 0)),
         num_intl_provider_errors_(
-            metrics_.CreateInt("num_intl_provider_errors", 0)) {}
+            vm_node_->CreateInt("num_intl_provider_errors", 0)) {}
 
   // Registers a single call to GetProfile callback.
   void RegisterGetProfileCall() { num_get_profile_calls_.Add(1); }
@@ -131,14 +129,8 @@
   }
 
  private:
-  // The inspector that all metrics are being reported into.
-  inspect::Inspector* inspector_;
-
-  // References inspector_ state.
-  inspect::Node& root_;
-
   // The OS metrics node.
-  inspect::Node metrics_;
+  std::unique_ptr<inspect::Node> vm_node_;
 
   // The status of the last GetTimeZoneOffset call.
   inspect::IntProperty dst_status_;
@@ -305,7 +297,6 @@
 std::set<const std::string> timezone_names;
 
 // Initialized on OS:Init(), deinitialized on OS::Cleanup.
-std::unique_ptr<sys::ComponentInspector> component_inspector;
 std::shared_ptr<InspectMetrics> metrics;
 std::shared_ptr<TimezoneName> timezone_name;
 async_loop_t* message_loop = nullptr;
@@ -603,9 +594,11 @@
     async_loop_start_thread(message_loop, "Fuchsia async loop", nullptr);
   }
 
-  sys::ComponentContext* context = dart::ComponentContext();
-  component_inspector = std::make_unique<sys::ComponentInspector>(context);
-  metrics = std::make_shared<InspectMetrics>(component_inspector->inspector());
+  auto vm_node = dart::TakeDartVmNode();
+
+  // TODO(fxbug.dev/69558) allow vm_node to be null and not crash
+  ASSERT(vm_node != nullptr);
+  metrics = std::make_shared<InspectMetrics>(std::move(vm_node));
 
   InitializeTZData();
   auto services = sys::ServiceDirectory::CreateFromNamespace();
@@ -620,7 +613,6 @@
   }
   timezone_name.reset();
   metrics.reset();
-  component_inspector.reset();
 
   if (message_loop != nullptr) {
     // Check message_loop is still the default dispatcher before clearing it.
diff --git a/runtime/vm/os_thread_fuchsia.cc b/runtime/vm/os_thread_fuchsia.cc
index bf2469a..9108f5d 100644
--- a/runtime/vm/os_thread_fuchsia.cc
+++ b/runtime/vm/os_thread_fuchsia.cc
@@ -133,7 +133,7 @@
   return 0;
 }
 
-const ThreadId OSThread::kInvalidThreadId = ZX_KOID_INVALID;
+const ThreadId OSThread::kInvalidThreadId = ZX_HANDLE_INVALID;
 const ThreadJoinId OSThread::kInvalidThreadJoinId =
     static_cast<ThreadJoinId>(0);
 
@@ -163,15 +163,7 @@
 }
 
 ThreadId OSThread::GetCurrentThreadId() {
-  zx_info_handle_basic_t info;
-  zx_handle_t thread_handle = thrd_get_zx_handle(thrd_current());
-  zx_status_t status =
-      zx_object_get_info(thread_handle, ZX_INFO_HANDLE_BASIC, &info,
-                         sizeof(info), nullptr, nullptr);
-  if (status != ZX_OK) {
-    FATAL1("Failed to get thread koid: %s\n", zx_status_get_string(status));
-  }
-  return info.koid;
+  return thrd_get_zx_handle(thrd_current());
 }
 
 #ifdef SUPPORT_TIMELINE
diff --git a/runtime/vm/os_thread_fuchsia.h b/runtime/vm/os_thread_fuchsia.h
index da76e8e..e17b4a6 100644
--- a/runtime/vm/os_thread_fuchsia.h
+++ b/runtime/vm/os_thread_fuchsia.h
@@ -18,7 +18,7 @@
 namespace dart {
 
 typedef pthread_key_t ThreadLocalKey;
-typedef zx_koid_t ThreadId;
+typedef zx_handle_t ThreadId;
 typedef pthread_t ThreadJoinId;
 
 static const ThreadLocalKey kUnsetThreadLocalKey =
diff --git a/runtime/vm/pointer_tagging.h b/runtime/vm/pointer_tagging.h
index a26c158..90dd053 100644
--- a/runtime/vm/pointer_tagging.h
+++ b/runtime/vm/pointer_tagging.h
@@ -37,6 +37,10 @@
   static constexpr intptr_t kBoolValueBitPosition = kObjectAlignmentLog2;
   static constexpr intptr_t kBoolValueMask = 1 << kBoolValueBitPosition;
 
+  // Discriminate between bool and null based on bit after the alignment bit.
+  static constexpr intptr_t kBoolVsNullBitPosition = kObjectAlignmentLog2 + 1;
+  static constexpr intptr_t kBoolVsNullMask = 1 << kBoolVsNullBitPosition;
+
   static constexpr intptr_t kTrueOffsetFromNull = kObjectAlignment * 2;
   static constexpr intptr_t kFalseOffsetFromNull = kObjectAlignment * 3;
 };
@@ -58,6 +62,10 @@
 static constexpr intptr_t kBoolValueBitPosition =
     HostObjectAlignment::kBoolValueBitPosition;
 static constexpr intptr_t kBoolValueMask = HostObjectAlignment::kBoolValueMask;
+static constexpr intptr_t kBoolVsNullBitPosition =
+    HostObjectAlignment::kBoolVsNullBitPosition;
+static constexpr intptr_t kBoolVsNullMask =
+    HostObjectAlignment::kBoolVsNullMask;
 static constexpr intptr_t kTrueOffsetFromNull =
     HostObjectAlignment::kTrueOffsetFromNull;
 static constexpr intptr_t kFalseOffsetFromNull =
diff --git a/runtime/vm/profiler_service.cc b/runtime/vm/profiler_service.cc
index 0ba5912..9cf5d12 100644
--- a/runtime/vm/profiler_service.cc
+++ b/runtime/vm/profiler_service.cc
@@ -1546,7 +1546,9 @@
   obj->AddProperty("maxStackDepth",
                    static_cast<intptr_t>(FLAG_max_profile_depth));
   obj->AddProperty("sampleCount", sample_count());
-  obj->AddProperty("timespan", MicrosecondsToSeconds(GetTimeSpan()));
+  // TODO(bkonyi): remove timeSpan after next major revision.
+  ASSERT(SERVICE_PROTOCOL_MAJOR_VERSION == 3);
+  obj->AddProperty64("timeSpan", -1);
   obj->AddPropertyTimeMicros("timeOriginMicros", min_time());
   obj->AddPropertyTimeMicros("timeExtentMicros", GetTimeSpan());
   obj->AddProperty64("pid", pid);
diff --git a/runtime/vm/raw_object.cc b/runtime/vm/raw_object.cc
index cfe671e..7fb0ce7 100644
--- a/runtime/vm/raw_object.cc
+++ b/runtime/vm/raw_object.cc
@@ -131,14 +131,14 @@
     case kOneByteStringCid: {
       const OneByteStringPtr raw_string =
           static_cast<const OneByteStringPtr>(this);
-      intptr_t string_length = Smi::Value(raw_string->untag()->length_);
+      intptr_t string_length = Smi::Value(raw_string->untag()->length());
       instance_size = OneByteString::InstanceSize(string_length);
       break;
     }
     case kTwoByteStringCid: {
       const TwoByteStringPtr raw_string =
           static_cast<const TwoByteStringPtr>(this);
-      intptr_t string_length = Smi::Value(raw_string->untag()->length_);
+      intptr_t string_length = Smi::Value(raw_string->untag()->length());
       instance_size = TwoByteString::InstanceSize(string_length);
       break;
     }
@@ -160,7 +160,7 @@
 #define SIZE_FROM_CLASS(clazz) case kTypedData##clazz##Cid:
       CLASS_LIST_TYPED_DATA(SIZE_FROM_CLASS) {
         const TypedDataPtr raw_obj = static_cast<const TypedDataPtr>(this);
-        intptr_t array_len = Smi::Value(raw_obj->untag()->length_);
+        intptr_t array_len = Smi::Value(raw_obj->untag()->length());
         intptr_t lengthInBytes =
             array_len * TypedData::ElementSizeInBytes(class_id);
         instance_size = TypedData::InstanceSize(lengthInBytes);
@@ -442,7 +442,7 @@
       Type##Ptr raw_obj, ObjectPointerVisitor* visitor) {                      \
     /* Make sure that we got here with the tagged pointer as this. */          \
     ASSERT(raw_obj->IsHeapObject());                                           \
-    ASSERT_UNCOMPRESSED(Type);                                                 \
+    ASSERT_COMPRESSED(Type);                                                   \
     visitor->VisitCompressedPointers(raw_obj->heap_base(),                     \
                                      raw_obj->untag()->from(),                 \
                                      raw_obj->untag()->to());                  \
@@ -460,7 +460,7 @@
       Type##Ptr raw_obj, ObjectPointerVisitor* visitor) {                      \
     /* Make sure that we got here with the tagged pointer as this. */          \
     ASSERT(raw_obj->IsHeapObject());                                           \
-    ASSERT_UNCOMPRESSED(Type);                                                 \
+    ASSERT_COMPRESSED(Type);                                                   \
     visitor->VisitTypedDataViewPointers(raw_obj, raw_obj->untag()->from(),     \
                                         raw_obj->untag()->to());               \
     return Type::InstanceSize();                                               \
@@ -526,54 +526,55 @@
     return 0;                                                                  \
   }
 
-REGULAR_VISITOR(Class)
-REGULAR_VISITOR(Type)
-REGULAR_VISITOR(FunctionType)
-REGULAR_VISITOR(TypeRef)
-REGULAR_VISITOR(TypeParameter)
-REGULAR_VISITOR(PatchClass)
-REGULAR_VISITOR(Function)
+COMPRESSED_VISITOR(Class)
+COMPRESSED_VISITOR(PatchClass)
+COMPRESSED_VISITOR(ClosureData)
+COMPRESSED_VISITOR(FfiTrampolineData)
+COMPRESSED_VISITOR(Script)
+COMPRESSED_VISITOR(Library)
+COMPRESSED_VISITOR(Namespace)
+COMPRESSED_VISITOR(KernelProgramInfo)
+COMPRESSED_VISITOR(WeakSerializationReference)
+COMPRESSED_VISITOR(Type)
+COMPRESSED_VISITOR(FunctionType)
+COMPRESSED_VISITOR(TypeRef)
+COMPRESSED_VISITOR(TypeParameter)
+COMPRESSED_VISITOR(Function)
 REGULAR_VISITOR(Closure)
-REGULAR_VISITOR(ClosureData)
-REGULAR_VISITOR(FfiTrampolineData)
-REGULAR_VISITOR(Script)
-REGULAR_VISITOR(Library)
-REGULAR_VISITOR(LibraryPrefix)
-REGULAR_VISITOR(Namespace)
+COMPRESSED_VISITOR(LibraryPrefix)
 REGULAR_VISITOR(SingleTargetCache)
 REGULAR_VISITOR(UnlinkedCall)
 REGULAR_VISITOR(MonomorphicSmiableCall)
 REGULAR_VISITOR(ICData)
 REGULAR_VISITOR(MegamorphicCache)
-REGULAR_VISITOR(ApiError)
-REGULAR_VISITOR(LanguageError)
-REGULAR_VISITOR(UnhandledException)
-REGULAR_VISITOR(UnwindError)
-REGULAR_VISITOR(ExternalOneByteString)
-REGULAR_VISITOR(ExternalTwoByteString)
+COMPRESSED_VISITOR(ApiError)
+COMPRESSED_VISITOR(LanguageError)
+COMPRESSED_VISITOR(UnhandledException)
+COMPRESSED_VISITOR(UnwindError)
+COMPRESSED_VISITOR(ExternalOneByteString)
+COMPRESSED_VISITOR(ExternalTwoByteString)
 REGULAR_VISITOR(GrowableObjectArray)
 REGULAR_VISITOR(LinkedHashMap)
-REGULAR_VISITOR(ExternalTypedData)
+COMPRESSED_VISITOR(ExternalTypedData)
 TYPED_DATA_VIEW_VISITOR(TypedDataView)
-REGULAR_VISITOR(ReceivePort)
-REGULAR_VISITOR(StackTrace)
-REGULAR_VISITOR(RegExp)
+COMPRESSED_VISITOR(ReceivePort)
+COMPRESSED_VISITOR(StackTrace)
+COMPRESSED_VISITOR(RegExp)
 REGULAR_VISITOR(WeakProperty)
-REGULAR_VISITOR(MirrorReference)
-REGULAR_VISITOR(UserTag)
+COMPRESSED_VISITOR(MirrorReference)
+COMPRESSED_VISITOR(UserTag)
 REGULAR_VISITOR(SubtypeTestCache)
-REGULAR_VISITOR(LoadingUnit)
-REGULAR_VISITOR(KernelProgramInfo)
-REGULAR_VISITOR(WeakSerializationReference)
+COMPRESSED_VISITOR(LoadingUnit)
 VARIABLE_VISITOR(TypeArguments, Smi::Value(raw_obj->untag()->length_))
-VARIABLE_VISITOR(LocalVarDescriptors, raw_obj->untag()->num_entries_)
-VARIABLE_VISITOR(ExceptionHandlers, raw_obj->untag()->num_entries_)
+VARIABLE_COMPRESSED_VISITOR(LocalVarDescriptors, raw_obj->untag()->num_entries_)
+VARIABLE_COMPRESSED_VISITOR(ExceptionHandlers, raw_obj->untag()->num_entries_)
 VARIABLE_VISITOR(Context, raw_obj->untag()->num_variables_)
 VARIABLE_VISITOR(Array, Smi::Value(raw_obj->untag()->length()))
-VARIABLE_VISITOR(TypedData,
-                 TypedData::ElementSizeInBytes(raw_obj->GetClassId()) *
-                     Smi::Value(raw_obj->untag()->length_))
-VARIABLE_VISITOR(ContextScope, raw_obj->untag()->num_variables_)
+VARIABLE_COMPRESSED_VISITOR(
+    TypedData,
+    TypedData::ElementSizeInBytes(raw_obj->GetClassId()) *
+        Smi::Value(raw_obj->untag()->length()))
+VARIABLE_COMPRESSED_VISITOR(ContextScope, raw_obj->untag()->num_variables_)
 NULL_VISITOR(Mint)
 NULL_VISITOR(Double)
 NULL_VISITOR(Float32x4)
@@ -583,7 +584,7 @@
 NULL_VISITOR(Capability)
 NULL_VISITOR(SendPort)
 NULL_VISITOR(TransferableTypedData)
-REGULAR_VISITOR(Pointer)
+COMPRESSED_VISITOR(Pointer)
 NULL_VISITOR(DynamicLibrary)
 VARIABLE_NULL_VISITOR(Instructions, Instructions::Size(raw_obj))
 VARIABLE_NULL_VISITOR(InstructionsSection, InstructionsSection::Size(raw_obj))
@@ -591,8 +592,8 @@
 VARIABLE_NULL_VISITOR(CodeSourceMap, raw_obj->untag()->length_)
 VARIABLE_NULL_VISITOR(CompressedStackMaps,
                       CompressedStackMaps::PayloadSizeOf(raw_obj))
-VARIABLE_NULL_VISITOR(OneByteString, Smi::Value(raw_obj->untag()->length_))
-VARIABLE_NULL_VISITOR(TwoByteString, Smi::Value(raw_obj->untag()->length_))
+VARIABLE_NULL_VISITOR(OneByteString, Smi::Value(raw_obj->untag()->length()))
+VARIABLE_NULL_VISITOR(TwoByteString, Smi::Value(raw_obj->untag()->length()))
 // Abstract types don't have their visitor called.
 UNREACHABLE_VISITOR(AbstractType)
 UNREACHABLE_VISITOR(CallSiteData)
@@ -608,15 +609,16 @@
 intptr_t UntaggedField::VisitFieldPointers(FieldPtr raw_obj,
                                            ObjectPointerVisitor* visitor) {
   ASSERT(raw_obj->IsHeapObject());
-  ASSERT_UNCOMPRESSED(Field);
-  visitor->VisitPointers(raw_obj->untag()->from(), raw_obj->untag()->to());
+  ASSERT_COMPRESSED(Field);
+  visitor->VisitCompressedPointers(
+      raw_obj->heap_base(), raw_obj->untag()->from(), raw_obj->untag()->to());
 
   if (visitor->trace_values_through_fields()) {
     if (Field::StaticBit::decode(raw_obj->untag()->kind_bits_)) {
       visitor->isolate_group()->ForEachIsolate(
           [&](Isolate* isolate) {
             intptr_t index =
-                Smi::Value(raw_obj->untag()->host_offset_or_field_id_);
+                Smi::Value(raw_obj->untag()->host_offset_or_field_id());
             visitor->VisitPointer(&isolate->field_table()->table()[index]);
           },
           /*at_safepoint=*/true);
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index f53df11..b24f93e 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -43,6 +43,7 @@
 CLASS_LIST(DEFINE_FORWARD_DECLARATION)
 #undef DEFINE_FORWARD_DECLARATION
 class CodeStatistics;
+class StackFrame;
 
 #define VISIT_FROM(type, first)                                                \
   type* from() { return reinterpret_cast<type*>(&first##_); }
@@ -56,12 +57,12 @@
 #define VISIT_NOTHING() int NothingToVisit();
 
 #define ASSERT_UNCOMPRESSED(Type)                                              \
-  ASSERT(SIZE_OF_DEREFERENCED_RETURNED_VALUE(Untagged##Type, from) == kWordSize)
+  ASSERT(SIZE_OF_DEREFERENCED_RETURNED_VALUE(Untagged##Type, from) ==          \
+         sizeof(ObjectPtr))
 
-// For now there are no compressed pointers, so this assert is the same as
-// the above.
 #define ASSERT_COMPRESSED(Type)                                                \
-  ASSERT(SIZE_OF_DEREFERENCED_RETURNED_VALUE(Untagged##Type, from) == kWordSize)
+  ASSERT(SIZE_OF_DEREFERENCED_RETURNED_VALUE(Untagged##Type, from) ==          \
+         sizeof(CompressedObjectPtr))
 
 #define ASSERT_NOTHING_TO_VISIT(Type)                                          \
   ASSERT(SIZE_OF_RETURNED_VALUE(Untagged##Type, NothingToVisit) == sizeof(int))
@@ -152,7 +153,7 @@
     static constexpr intptr_t kMaxSizeTag =
         kMaxSizeTagInUnitsOfAlignment * kObjectAlignment;
 
-    static UNLESS_DEBUG(constexpr) uword encode(intptr_t size) {
+    static constexpr uword encode(intptr_t size) {
       return SizeBits::encode(SizeToTagValue(size));
     }
 
@@ -160,11 +161,11 @@
       return TagValueToSize(SizeBits::decode(tag));
     }
 
-    static UNLESS_DEBUG(constexpr) uword update(intptr_t size, uword tag) {
+    static constexpr uword update(intptr_t size, uword tag) {
       return SizeBits::update(SizeToTagValue(size), tag);
     }
 
-    static UNLESS_DEBUG(constexpr) bool SizeFits(intptr_t size) {
+    static constexpr bool SizeFits(intptr_t size) {
       DEBUG_ASSERT(Utils::IsAligned(size, kObjectAlignment));
       return (size <= kMaxSizeTag);
     }
@@ -174,8 +175,8 @@
     class SizeBits
         : public BitField<uword, intptr_t, kSizeTagPos, kSizeTagSize> {};
 
-    static UNLESS_DEBUG(constexpr) intptr_t SizeToTagValue(intptr_t size) {
-      DEBUG_ASSERT(Utils::IsAligned(size, kObjectAlignment));
+    static constexpr intptr_t SizeToTagValue(intptr_t size) {
+      assert(Utils::IsAligned(size, kObjectAlignment));
       return !SizeFits(size) ? 0 : (size >> kObjectAlignmentLog2);
     }
     static constexpr intptr_t TagValueToSize(intptr_t value) {
@@ -212,21 +213,22 @@
   class ReservedBits
       : public BitField<uword, intptr_t, kReservedTagPos, kReservedTagSize> {};
 
+  template <typename T>
   class Tags {
    public:
     Tags() : tags_(0) {}
 
-    operator uword() const { return tags_.load(std::memory_order_relaxed); }
+    operator T() const { return tags_.load(std::memory_order_relaxed); }
 
-    uword operator=(uword tags) {
+    T operator=(T tags) {
       tags_.store(tags, std::memory_order_relaxed);
       return tags;
     }
 
-    uword load(std::memory_order order) const { return tags_.load(order); }
+    T load(std::memory_order order) const { return tags_.load(order); }
 
-    bool compare_exchange_weak(uword old_tags,
-                               uword new_tags,
+    bool compare_exchange_weak(T old_tags,
+                               T new_tags,
                                std::memory_order order) {
       return tags_.compare_exchange_weak(old_tags, new_tags, order);
     }
@@ -238,7 +240,7 @@
 
     template <class TagBitField>
     NO_SANITIZE_THREAD typename TagBitField::Type ReadIgnoreRace() const {
-      return TagBitField::decode(*reinterpret_cast<const uword*>(&tags_));
+      return TagBitField::decode(*reinterpret_cast<const T*>(&tags_));
     }
 
     template <class TagBitField>
@@ -252,8 +254,8 @@
 
     template <class TagBitField>
     void Update(typename TagBitField::Type value) {
-      uword old_tags = tags_.load(std::memory_order_relaxed);
-      uword new_tags;
+      T old_tags = tags_.load(std::memory_order_relaxed);
+      T new_tags;
       do {
         new_tags = TagBitField::update(value, old_tags);
       } while (!tags_.compare_exchange_weak(old_tags, new_tags,
@@ -269,21 +271,21 @@
 
     template <class TagBitField>
     bool TryAcquire() {
-      uword mask = TagBitField::encode(true);
-      uword old_tags = tags_.fetch_or(mask, std::memory_order_relaxed);
+      T mask = TagBitField::encode(true);
+      T old_tags = tags_.fetch_or(mask, std::memory_order_relaxed);
       return !TagBitField::decode(old_tags);
     }
 
     template <class TagBitField>
     bool TryClear() {
-      uword mask = ~TagBitField::encode(true);
-      uword old_tags = tags_.fetch_and(mask, std::memory_order_relaxed);
+      T mask = ~TagBitField::encode(true);
+      T old_tags = tags_.fetch_and(mask, std::memory_order_relaxed);
       return TagBitField::decode(old_tags);
     }
 
    private:
-    std::atomic<uword> tags_;
-    COMPILE_ASSERT(sizeof(std::atomic<uword>) == sizeof(uword));
+    std::atomic<T> tags_;
+    COMPILE_ASSERT(sizeof(std::atomic<T>) == sizeof(T));
   };
 
   // Assumes this is a heap object.
@@ -519,7 +521,7 @@
   }
 
  private:
-  Tags tags_;  // Various object tags (bits).
+  Tags<uword> tags_;  // Various object tags (bits).
 
   intptr_t VisitPointersPredefined(ObjectPointerVisitor* visitor,
                                    intptr_t class_id);
@@ -540,6 +542,19 @@
     return reinterpret_cast<std::atomic<type>*>(const_cast<type*>(addr))
         ->load(order);
   }
+  template <typename type,
+            typename compressed_type,
+            std::memory_order order = std::memory_order_relaxed>
+  type LoadCompressedPointer(compressed_type const* addr) const {
+    compressed_type v = reinterpret_cast<std::atomic<compressed_type>*>(
+                            const_cast<compressed_type*>(addr))
+                            ->load(order);
+    return static_cast<type>(v.Decompress(heap_base()));
+  }
+
+  uword heap_base() const {
+    return reinterpret_cast<uword>(this) & kHeapBaseMask;
+  }
 
   template <typename type, std::memory_order order = std::memory_order_relaxed>
   void StorePointer(type const* addr, type value) {
@@ -550,6 +565,18 @@
     }
   }
 
+  template <typename type,
+            typename compressed_type,
+            std::memory_order order = std::memory_order_relaxed>
+  void StoreCompressedPointer(compressed_type const* addr, type value) {
+    reinterpret_cast<std::atomic<compressed_type>*>(
+        const_cast<compressed_type*>(addr))
+        ->store(static_cast<compressed_type>(value), order);
+    if (value->IsHeapObject()) {
+      CheckHeapPointerStore(value, Thread::Current());
+    }
+  }
+
   template <typename type>
   void StorePointer(type const* addr, type value, Thread* thread) {
     *const_cast<type*>(addr) = value;
@@ -601,11 +628,19 @@
     }
   }
 
-  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))
+  template <std::memory_order order = std::memory_order_relaxed>
+  SmiPtr LoadSmi(SmiPtr const* addr) const {
+    return reinterpret_cast<std::atomic<SmiPtr>*>(const_cast<SmiPtr*>(addr))
         ->load(order);
   }
+  template <std::memory_order order = std::memory_order_relaxed>
+  SmiPtr LoadCompressedSmi(CompressedSmiPtr const* addr) const {
+    return static_cast<SmiPtr>(reinterpret_cast<std::atomic<CompressedSmiPtr>*>(
+                                   const_cast<CompressedSmiPtr*>(addr))
+                                   ->load(order)
+                                   .DecompressSmi());
+  }
+
   // 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>
@@ -615,6 +650,14 @@
     reinterpret_cast<std::atomic<SmiPtr>*>(const_cast<SmiPtr*>(addr))
         ->store(value, order);
   }
+  template <std::memory_order order = std::memory_order_relaxed>
+  void StoreCompressedSmi(CompressedSmiPtr const* addr, SmiPtr value) {
+    // Can't use Contains, as array length is initialized through this method.
+    ASSERT(reinterpret_cast<uword>(addr) >= UntaggedObject::ToAddr(this));
+    reinterpret_cast<std::atomic<CompressedSmiPtr>*>(
+        const_cast<CompressedSmiPtr*>(addr))
+        ->store(static_cast<CompressedSmiPtr>(value), order);
+  }
 
  private:
   DART_FORCE_INLINE
@@ -732,6 +775,9 @@
   friend class WriteBarrierUpdateVisitor;  // CheckHeapPointerStore
   friend class OffsetsTable;
   friend class Object;
+  friend void ReportImpossibleNullError(intptr_t cid,
+                                        StackFrame* caller_frame,
+                                        Thread* thread);
 
   DISALLOW_ALLOCATION();
   DISALLOW_IMPLICIT_CONSTRUCTORS(UntaggedObject);
@@ -755,6 +801,20 @@
  protected:                                                                    \
   type name##_;
 
+#define COMPRESSED_POINTER_FIELD(type, name)                                   \
+ public:                                                                       \
+  template <std::memory_order order = std::memory_order_relaxed>               \
+  type name() const {                                                          \
+    return LoadCompressedPointer<type, Compressed##type, order>(&name##_);     \
+  }                                                                            \
+  template <std::memory_order order = std::memory_order_relaxed>               \
+  void set_##name(type value) {                                                \
+    StoreCompressedPointer<type, Compressed##type, order>(&name##_, value);    \
+  }                                                                            \
+                                                                               \
+ protected:                                                                    \
+  Compressed##type name##_;
+
 #define ARRAY_POINTER_FIELD(type, name)                                        \
  public:                                                                       \
   template <std::memory_order order = std::memory_order_relaxed>               \
@@ -788,7 +848,7 @@
  public:                                                                       \
   template <std::memory_order order = std::memory_order_relaxed>               \
   type name() const {                                                          \
-    type result = LoadSmi<type, order>(&name##_);                              \
+    type result = LoadSmi<order>(&name##_);                                    \
     ASSERT(!result.IsHeapObject());                                            \
     return result;                                                             \
   }                                                                            \
@@ -801,6 +861,23 @@
  protected:                                                                    \
   type name##_;
 
+#define COMPRESSED_SMI_FIELD(type, name)                                       \
+ public:                                                                       \
+  template <std::memory_order order = std::memory_order_relaxed>               \
+  type name() const {                                                          \
+    type result = LoadCompressedSmi<order>(&name##_);                          \
+    ASSERT(!result.IsHeapObject());                                            \
+    return result;                                                             \
+  }                                                                            \
+  template <std::memory_order order = std::memory_order_relaxed>               \
+  void set_##name(type value) {                                                \
+    ASSERT(!value.IsHeapObject());                                             \
+    StoreCompressedSmi(&name##_, value);                                       \
+  }                                                                            \
+                                                                               \
+ protected:                                                                    \
+  Compressed##type name##_;
+
 class UntaggedClass : public UntaggedObject {
  public:
   enum ClassFinalizedState {
@@ -826,39 +903,43 @@
  private:
   RAW_HEAP_OBJECT_IMPLEMENTATION(Class);
 
-  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(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) {
+  VISIT_FROM(CompressedObjectPtr, name)
+  COMPRESSED_POINTER_FIELD(StringPtr, name)
+  COMPRESSED_POINTER_FIELD(StringPtr, user_name)
+  COMPRESSED_POINTER_FIELD(ArrayPtr, functions)
+  COMPRESSED_POINTER_FIELD(ArrayPtr, functions_hash_table)
+  COMPRESSED_POINTER_FIELD(ArrayPtr, fields)
+  COMPRESSED_POINTER_FIELD(ArrayPtr, offset_in_words_to_field)
+  COMPRESSED_POINTER_FIELD(ArrayPtr, interfaces)  // Array of AbstractType.
+  COMPRESSED_POINTER_FIELD(ScriptPtr, script)
+  COMPRESSED_POINTER_FIELD(LibraryPtr, library)
+  // Array of TypeParameter.
+  COMPRESSED_POINTER_FIELD(TypeArgumentsPtr, type_parameters)
+  COMPRESSED_POINTER_FIELD(AbstractTypePtr, super_type)
+  // Canonicalized const instances of this class.
+  COMPRESSED_POINTER_FIELD(ArrayPtr, constants)
+  // Declaration type for this class.
+  COMPRESSED_POINTER_FIELD(TypePtr, declaration_type)
+  // Cache for dispatcher functions.
+  COMPRESSED_POINTER_FIELD(ArrayPtr, invocation_dispatcher_cache)
+  // Stub code for allocation of instances.
+  COMPRESSED_POINTER_FIELD(CodePtr, allocation_stub)
+  // Array of Class.
+  COMPRESSED_POINTER_FIELD(GrowableObjectArrayPtr, direct_implementors)
+  // Array of Class.
+  COMPRESSED_POINTER_FIELD(GrowableObjectArrayPtr, direct_subclasses)
+  // CHA optimized codes.
+  COMPRESSED_POINTER_FIELD(ArrayPtr, dependent_code)
+  VISIT_TO(CompressedObjectPtr, dependent_code)
+  CompressedObjectPtr* to_snapshot(Snapshot::Kind kind) {
     switch (kind) {
       case Snapshot::kFullAOT:
-        return reinterpret_cast<ObjectPtr*>(&allocation_stub_);
+        return reinterpret_cast<CompressedObjectPtr*>(&allocation_stub_);
       case Snapshot::kFull:
       case Snapshot::kFullCore:
-        return reinterpret_cast<ObjectPtr*>(&direct_subclasses_);
+        return reinterpret_cast<CompressedObjectPtr*>(&direct_subclasses_);
       case Snapshot::kFullJIT:
-        return reinterpret_cast<ObjectPtr*>(&dependent_code_);
+        return reinterpret_cast<CompressedObjectPtr*>(&dependent_code_);
       case Snapshot::kMessage:
       case Snapshot::kNone:
       case Snapshot::kInvalid:
@@ -908,6 +989,7 @@
   friend class UntaggedTypeArguments;
   friend class SnapshotReader;
   friend class InstanceSerializationCluster;
+  friend class TypeSerializationCluster;
   friend class CidRewriteVisitor;
   friend class Api;
 };
@@ -916,21 +998,21 @@
  private:
   RAW_HEAP_OBJECT_IMPLEMENTATION(PatchClass);
 
-  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)
+  VISIT_FROM(CompressedObjectPtr, patched_class)
+  COMPRESSED_POINTER_FIELD(ClassPtr, patched_class)
+  COMPRESSED_POINTER_FIELD(ClassPtr, origin_class)
+  COMPRESSED_POINTER_FIELD(ScriptPtr, script)
+  COMPRESSED_POINTER_FIELD(ExternalTypedDataPtr, library_kernel_data)
+  VISIT_TO(CompressedObjectPtr, library_kernel_data)
 
-  ObjectPtr* to_snapshot(Snapshot::Kind kind) {
+  CompressedObjectPtr* to_snapshot(Snapshot::Kind kind) {
     switch (kind) {
       case Snapshot::kFullAOT:
-        return reinterpret_cast<ObjectPtr*>(&script_);
+        return reinterpret_cast<CompressedObjectPtr*>(&script_);
       case Snapshot::kFull:
       case Snapshot::kFullCore:
       case Snapshot::kFullJIT:
-        return reinterpret_cast<ObjectPtr*>(&library_kernel_data_);
+        return reinterpret_cast<CompressedObjectPtr*>(&library_kernel_data_);
       case Snapshot::kMessage:
       case Snapshot::kNone:
       case Snapshot::kInvalid:
@@ -1100,22 +1182,22 @@
   uword entry_point_;            // Accessed from generated code.
   uword unchecked_entry_point_;  // Accessed from generated code.
 
-  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(ArrayPtr, parameter_names)
-  POINTER_FIELD(FunctionTypePtr, signature)
-  POINTER_FIELD(ObjectPtr,
-                data)  // Additional data specific to the function kind. See
-                       // Function::set_data() for details.
-  ObjectPtr* to_snapshot(Snapshot::Kind kind) {
+  VISIT_FROM(CompressedObjectPtr, name)
+  COMPRESSED_POINTER_FIELD(StringPtr, name)
+  // Class or patch class or mixin class where this function is defined.
+  COMPRESSED_POINTER_FIELD(ObjectPtr, owner)
+  COMPRESSED_POINTER_FIELD(ArrayPtr, parameter_names)
+  COMPRESSED_POINTER_FIELD(FunctionTypePtr, signature)
+  // Additional data specific to the function kind. See Function::set_data()
+  // for details.
+  COMPRESSED_POINTER_FIELD(ObjectPtr, data)
+  CompressedObjectPtr* to_snapshot(Snapshot::Kind kind) {
     switch (kind) {
       case Snapshot::kFullAOT:
       case Snapshot::kFull:
       case Snapshot::kFullCore:
       case Snapshot::kFullJIT:
-        return reinterpret_cast<ObjectPtr*>(&data_);
+        return reinterpret_cast<CompressedObjectPtr*>(&data_);
       case Snapshot::kMessage:
       case Snapshot::kNone:
       case Snapshot::kInvalid:
@@ -1124,25 +1206,22 @@
     UNREACHABLE();
     return NULL;
   }
-  POINTER_FIELD(ArrayPtr, ic_data_array);  // ICData of unoptimized code.
-  ObjectPtr* to_no_code() {
-    return reinterpret_cast<ObjectPtr*>(&ic_data_array_);
-  }
-  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.
+  // ICData of unoptimized code.
+  COMPRESSED_POINTER_FIELD(ArrayPtr, ic_data_array);
+  // Currently active code. Accessed from generated code.
+  COMPRESSED_POINTER_FIELD(CodePtr, code);
+  // Unoptimized code, keep it after optimization.
+  NOT_IN_PRECOMPILED(COMPRESSED_POINTER_FIELD(CodePtr, unoptimized_code));
 #if defined(DART_PRECOMPILED_RUNTIME)
-  VISIT_TO(ObjectPtr, code);
+  VISIT_TO(CompressedObjectPtr, code);
 #else
-  VISIT_TO(ObjectPtr, unoptimized_code);
+  VISIT_TO(CompressedObjectPtr, unoptimized_code);
 #endif
 
   NOT_IN_PRECOMPILED(UnboxedParameterBitmap unboxed_parameters_info_);
   NOT_IN_PRECOMPILED(TokenPosition token_pos_);
   NOT_IN_PRECOMPILED(TokenPosition end_token_pos_);
-  uint32_t kind_tag_;  // See Function::KindTagBits.
+  Tags<uint32_t> kind_tag_;  // See Function::KindTagBits.
   uint32_t packed_fields_;
 
   // TODO(regis): Split packed_fields_ in 2 uint32_t if max values are too low.
@@ -1202,17 +1281,42 @@
  private:
   RAW_HEAP_OBJECT_IMPLEMENTATION(ClosureData);
 
-  VISIT_FROM(ObjectPtr, context_scope)
-  POINTER_FIELD(ContextScopePtr, context_scope)
-  POINTER_FIELD(FunctionPtr,
-                parent_function)  // Enclosing function of this local function.
-  POINTER_FIELD(InstancePtr,
-                closure)  // Closure object for static implicit closures.
+  VISIT_FROM(CompressedObjectPtr, context_scope)
+  COMPRESSED_POINTER_FIELD(ContextScopePtr, context_scope)
+  // Enclosing function of this local function.
+#if defined(DART_PRECOMPILER)
+  // Can be wrapped by a WSR in the precompiler.
+  COMPRESSED_POINTER_FIELD(ObjectPtr, parent_function)
+#else
+  COMPRESSED_POINTER_FIELD(FunctionPtr, parent_function)
+#endif
+  // Closure object for static implicit closures.
+  COMPRESSED_POINTER_FIELD(InstancePtr, closure)
   // Instantiate-to-bounds TAV for use when no TAV is provided.
-  POINTER_FIELD(TypeArgumentsPtr, default_type_arguments)
-  // Additional information about the instantiate-to-bounds TAV.
-  POINTER_FIELD(SmiPtr, default_type_arguments_info)
-  VISIT_TO(ObjectPtr, default_type_arguments_info)
+  COMPRESSED_POINTER_FIELD(TypeArgumentsPtr, default_type_arguments)
+  VISIT_TO(CompressedObjectPtr, default_type_arguments)
+
+  enum class DefaultTypeArgumentsKind : uint8_t {
+    // Only here to make sure it's explicitly set appropriately.
+    kInvalid = 0,
+    // Must instantiate the default type arguments before use.
+    kNeedsInstantiation,
+    // The default type arguments are already instantiated.
+    kIsInstantiated,
+    // Use the instantiator type arguments that would be used to instantiate
+    // the default type arguments, as instantiating produces the same result.
+    kSharesInstantiatorTypeArguments,
+    // Use the function type arguments that would be used to instantiate
+    // the default type arguments, as instantiating produces the same result.
+    kSharesFunctionTypeArguments,
+  };
+
+  // kernel_to_il.cc assumes we can load the untagged value and box it in a Smi.
+  static_assert(sizeof(DefaultTypeArgumentsKind) * kBitsPerByte <=
+                    compiler::target::kSmiBits,
+                "Default type arguments kind must fit in a Smi");
+
+  DefaultTypeArgumentsKind default_type_arguments_kind_;
 
   friend class Function;
 };
@@ -1221,18 +1325,18 @@
  private:
   RAW_HEAP_OBJECT_IMPLEMENTATION(FfiTrampolineData);
 
-  VISIT_FROM(ObjectPtr, signature_type)
-  POINTER_FIELD(TypePtr, signature_type)
-  POINTER_FIELD(FunctionTypePtr, c_signature)
+  VISIT_FROM(CompressedObjectPtr, signature_type)
+  COMPRESSED_POINTER_FIELD(TypePtr, signature_type)
+  COMPRESSED_POINTER_FIELD(FunctionTypePtr, c_signature)
 
   // Target Dart method for callbacks, otherwise null.
-  POINTER_FIELD(FunctionPtr, callback_target)
+  COMPRESSED_POINTER_FIELD(FunctionPtr, callback_target)
 
   // For callbacks, value to return if Dart target throws an exception.
-  POINTER_FIELD(InstancePtr, callback_exceptional_return)
+  COMPRESSED_POINTER_FIELD(InstancePtr, callback_exceptional_return)
 
-  VISIT_TO(ObjectPtr, callback_exceptional_return)
-  ObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
+  VISIT_TO(CompressedObjectPtr, callback_exceptional_return)
+  CompressedObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
 
   // Callback id for callbacks.
   //
@@ -1249,26 +1353,26 @@
 class UntaggedField : public UntaggedObject {
   RAW_HEAP_OBJECT_IMPLEMENTATION(Field);
 
-  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.
-
+  VISIT_FROM(CompressedObjectPtr, name)
+  COMPRESSED_POINTER_FIELD(StringPtr, name)
+  // Class or patch class or mixin class where this field is defined or original
+  // field.
+  COMPRESSED_POINTER_FIELD(ObjectPtr, owner)
+  COMPRESSED_POINTER_FIELD(AbstractTypePtr, type)
+  // Static initializer function.
+  COMPRESSED_POINTER_FIELD(FunctionPtr, initializer_function)
   // - for instance fields: offset in words to the value in the class instance.
   // - for static fields: index into field_table.
-  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) {
+  COMPRESSED_POINTER_FIELD(SmiPtr, host_offset_or_field_id)
+  COMPRESSED_POINTER_FIELD(SmiPtr, guarded_list_length)
+  COMPRESSED_POINTER_FIELD(ArrayPtr, dependent_code)
+  CompressedObjectPtr* to_snapshot(Snapshot::Kind kind) {
     switch (kind) {
       case Snapshot::kFull:
       case Snapshot::kFullCore:
       case Snapshot::kFullJIT:
       case Snapshot::kFullAOT:
-        return reinterpret_cast<ObjectPtr*>(&initializer_function_);
+        return reinterpret_cast<CompressedObjectPtr*>(&initializer_function_);
       case Snapshot::kMessage:
       case Snapshot::kNone:
       case Snapshot::kInvalid:
@@ -1278,11 +1382,11 @@
     return NULL;
   }
 #if defined(DART_PRECOMPILED_RUNTIME)
-  VISIT_TO(ObjectPtr, dependent_code);
+  VISIT_TO(CompressedObjectPtr, dependent_code);
 #else
-  POINTER_FIELD(SubtypeTestCachePtr,
-                type_test_cache);  // For type test in implicit setter.
-  VISIT_TO(ObjectPtr, type_test_cache);
+  // For type test in implicit setter.
+  COMPRESSED_POINTER_FIELD(SubtypeTestCachePtr, type_test_cache);
+  VISIT_TO(CompressedObjectPtr, type_test_cache);
 #endif
   TokenPosition token_pos_;
   TokenPosition end_token_pos_;
@@ -1320,26 +1424,26 @@
 class alignas(8) UntaggedScript : public UntaggedObject {
   RAW_HEAP_OBJECT_IMPLEMENTATION(Script);
 
-  VISIT_FROM(ObjectPtr, url)
-  POINTER_FIELD(StringPtr, url)
-  POINTER_FIELD(StringPtr, resolved_url)
-  POINTER_FIELD(ArrayPtr, compile_time_constants)
-  POINTER_FIELD(TypedDataPtr, line_starts)
+  VISIT_FROM(CompressedObjectPtr, url)
+  COMPRESSED_POINTER_FIELD(StringPtr, url)
+  COMPRESSED_POINTER_FIELD(StringPtr, resolved_url)
+  COMPRESSED_POINTER_FIELD(ArrayPtr, compile_time_constants)
+  COMPRESSED_POINTER_FIELD(TypedDataPtr, line_starts)
 #if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
-  POINTER_FIELD(ExternalTypedDataPtr, constant_coverage)
+  COMPRESSED_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) {
+  COMPRESSED_POINTER_FIELD(ArrayPtr, debug_positions)
+  COMPRESSED_POINTER_FIELD(KernelProgramInfoPtr, kernel_program_info)
+  COMPRESSED_POINTER_FIELD(StringPtr, source)
+  VISIT_TO(CompressedObjectPtr, source)
+  CompressedObjectPtr* to_snapshot(Snapshot::Kind kind) {
     switch (kind) {
       case Snapshot::kFullAOT:
-        return reinterpret_cast<ObjectPtr*>(&url_);
+        return reinterpret_cast<CompressedObjectPtr*>(&url_);
       case Snapshot::kFull:
       case Snapshot::kFullCore:
       case Snapshot::kFullJIT:
-        return reinterpret_cast<ObjectPtr*>(&kernel_program_info_);
+        return reinterpret_cast<CompressedObjectPtr*>(&kernel_program_info_);
       case Snapshot::kMessage:
       case Snapshot::kNone:
       case Snapshot::kInvalid:
@@ -1408,29 +1512,32 @@
 
   RAW_HEAP_OBJECT_IMPLEMENTATION(Library);
 
-  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) {
+  VISIT_FROM(CompressedObjectPtr, name)
+  COMPRESSED_POINTER_FIELD(StringPtr, name)
+  COMPRESSED_POINTER_FIELD(StringPtr, url)
+  COMPRESSED_POINTER_FIELD(StringPtr, private_key)
+  // Top-level names in this library.
+  COMPRESSED_POINTER_FIELD(ArrayPtr, dictionary)
+  // Metadata on classes, methods etc.
+  COMPRESSED_POINTER_FIELD(ArrayPtr, metadata)
+  // Class containing top-level elements.
+  COMPRESSED_POINTER_FIELD(ClassPtr, toplevel_class)
+  COMPRESSED_POINTER_FIELD(GrowableObjectArrayPtr, used_scripts)
+  COMPRESSED_POINTER_FIELD(LoadingUnitPtr, loading_unit)
+  // List of Namespaces imported without prefix.
+  COMPRESSED_POINTER_FIELD(ArrayPtr, imports)
+  // List of re-exported Namespaces.
+  COMPRESSED_POINTER_FIELD(ArrayPtr, exports)
+  COMPRESSED_POINTER_FIELD(ArrayPtr, dependencies)
+  COMPRESSED_POINTER_FIELD(ExternalTypedDataPtr, kernel_data)
+  CompressedObjectPtr* to_snapshot(Snapshot::Kind kind) {
     switch (kind) {
       case Snapshot::kFullAOT:
-        return reinterpret_cast<ObjectPtr*>(&exports_);
+        return reinterpret_cast<CompressedObjectPtr*>(&exports_);
       case Snapshot::kFull:
       case Snapshot::kFullCore:
       case Snapshot::kFullJIT:
-        return reinterpret_cast<ObjectPtr*>(&kernel_data_);
+        return reinterpret_cast<CompressedObjectPtr*>(&kernel_data_);
       case Snapshot::kMessage:
       case Snapshot::kNone:
       case Snapshot::kInvalid:
@@ -1439,13 +1546,13 @@
     UNREACHABLE();
     return NULL;
   }
-  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);
+  // Cache of resolved names in library scope.
+  COMPRESSED_POINTER_FIELD(ArrayPtr, resolved_names);
+  // Cache of exported names by library.
+  COMPRESSED_POINTER_FIELD(ArrayPtr, exported_names);
+  // Array of scripts loaded in this library.
+  COMPRESSED_POINTER_FIELD(ArrayPtr, loaded_scripts);
+  VISIT_TO(CompressedObjectPtr, loaded_scripts);
 
   Dart_NativeEntryResolver native_entry_resolver_;  // Resolves natives.
   Dart_NativeEntrySymbol native_entry_symbol_resolver_;
@@ -1465,20 +1572,23 @@
 class UntaggedNamespace : public UntaggedObject {
   RAW_HEAP_OBJECT_IMPLEMENTATION(Namespace);
 
-  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) {
+  VISIT_FROM(CompressedObjectPtr, target)
+  // library with name dictionary.
+  COMPRESSED_POINTER_FIELD(LibraryPtr, target)
+  // list of names that are exported.
+  COMPRESSED_POINTER_FIELD(ArrayPtr, show_names)
+  // list of names that are hidden.
+  COMPRESSED_POINTER_FIELD(ArrayPtr, hide_names)
+  COMPRESSED_POINTER_FIELD(LibraryPtr, owner)
+  VISIT_TO(CompressedObjectPtr, owner)
+  CompressedObjectPtr* to_snapshot(Snapshot::Kind kind) {
     switch (kind) {
       case Snapshot::kFullAOT:
-        return reinterpret_cast<ObjectPtr*>(&target_);
+        return reinterpret_cast<CompressedObjectPtr*>(&target_);
       case Snapshot::kFull:
       case Snapshot::kFullCore:
       case Snapshot::kFullJIT:
-        return reinterpret_cast<ObjectPtr*>(&owner_);
+        return reinterpret_cast<CompressedObjectPtr*>(&owner_);
       case Snapshot::kMessage:
       case Snapshot::kNone:
       case Snapshot::kInvalid:
@@ -1492,36 +1602,36 @@
 class UntaggedKernelProgramInfo : public UntaggedObject {
   RAW_HEAP_OBJECT_IMPLEMENTATION(KernelProgramInfo);
 
-  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)
+  VISIT_FROM(CompressedObjectPtr, string_offsets)
+  COMPRESSED_POINTER_FIELD(TypedDataPtr, string_offsets)
+  COMPRESSED_POINTER_FIELD(ExternalTypedDataPtr, string_data)
+  COMPRESSED_POINTER_FIELD(TypedDataPtr, canonical_names)
+  COMPRESSED_POINTER_FIELD(ExternalTypedDataPtr, metadata_payloads)
+  COMPRESSED_POINTER_FIELD(ExternalTypedDataPtr, metadata_mappings)
+  COMPRESSED_POINTER_FIELD(ArrayPtr, scripts)
+  COMPRESSED_POINTER_FIELD(ArrayPtr, constants)
+  COMPRESSED_POINTER_FIELD(GrowableObjectArrayPtr, potential_natives)
+  COMPRESSED_POINTER_FIELD(GrowableObjectArrayPtr, potential_pragma_functions)
+  COMPRESSED_POINTER_FIELD(ExternalTypedDataPtr, constants_table)
+  COMPRESSED_POINTER_FIELD(ArrayPtr, libraries_cache)
+  COMPRESSED_POINTER_FIELD(ArrayPtr, classes_cache)
+  COMPRESSED_POINTER_FIELD(ObjectPtr, retained_kernel_blob)
+  VISIT_TO(CompressedObjectPtr, retained_kernel_blob)
 
   uint32_t kernel_binary_version_;
 
-  ObjectPtr* to_snapshot(Snapshot::Kind kind) {
-    return reinterpret_cast<ObjectPtr*>(&constants_table_);
+  CompressedObjectPtr* to_snapshot(Snapshot::Kind kind) {
+    return reinterpret_cast<CompressedObjectPtr*>(&constants_table_);
   }
 };
 
 class UntaggedWeakSerializationReference : public UntaggedObject {
   RAW_HEAP_OBJECT_IMPLEMENTATION(WeakSerializationReference);
 
-  VISIT_FROM(ObjectPtr, target)
-  POINTER_FIELD(ObjectPtr, target)
-  POINTER_FIELD(ObjectPtr, replacement)
-  VISIT_TO(ObjectPtr, replacement)
+  VISIT_FROM(CompressedObjectPtr, target)
+  COMPRESSED_POINTER_FIELD(ObjectPtr, target)
+  COMPRESSED_POINTER_FIELD(ObjectPtr, replacement)
+  VISIT_TO(CompressedObjectPtr, replacement)
 };
 
 class UntaggedCode : public UntaggedObject {
@@ -1966,13 +2076,21 @@
   // platforms.
   uword num_entries_;
 
-  ObjectPtr* from() { return reinterpret_cast<ObjectPtr*>(&names()[0]); }
-  StringPtr* names() {
-    // Array of [num_entries_] variable names.
-    OPEN_ARRAY_START(StringPtr, StringPtr);
+  CompressedObjectPtr* from() {
+    return reinterpret_cast<CompressedObjectPtr*>(&names()[0]);
   }
-  StringPtr* nameAddrAt(intptr_t i) { return &(names()[i]); }
-  VISIT_TO_LENGTH(ObjectPtr, nameAddrAt(length - 1));
+  CompressedStringPtr* names() {
+    // Array of [num_entries_] variable names.
+    OPEN_ARRAY_START(CompressedStringPtr, CompressedStringPtr);
+  }
+  CompressedStringPtr* nameAddrAt(intptr_t i) { return &(names()[i]); }
+  StringPtr name(intptr_t i) {
+    return LoadCompressedPointer<StringPtr>(nameAddrAt(i));
+  }
+  void set_name(intptr_t i, StringPtr value) {
+    StoreCompressedPointer(nameAddrAt(i), value);
+  }
+  VISIT_TO_LENGTH(CompressedObjectPtr, nameAddrAt(length - 1));
 
   // Variable info with [num_entries_] entries.
   VarInfo* data() {
@@ -1991,9 +2109,9 @@
 
   // Array with [num_entries_] entries. Each entry is an array of all handled
   // exception types.
-  VISIT_FROM(ObjectPtr, handled_types_data)
-  POINTER_FIELD(ArrayPtr, handled_types_data)
-  VISIT_TO_LENGTH(ObjectPtr, &handled_types_data_)
+  VISIT_FROM(CompressedObjectPtr, handled_types_data)
+  COMPRESSED_POINTER_FIELD(ArrayPtr, handled_types_data)
+  VISIT_TO_LENGTH(CompressedObjectPtr, &handled_types_data_)
 
   // Exception handler info of length [num_entries_].
   const ExceptionHandlerInfo* data() const {
@@ -2027,42 +2145,64 @@
   // TODO(iposva): Switch to conventional enum offset based structure to avoid
   // alignment mishaps.
   struct VariableDesc {
-    SmiPtr declaration_token_pos;
-    SmiPtr token_pos;
-    StringPtr name;
-    SmiPtr flags;
+    CompressedSmiPtr declaration_token_pos;
+    CompressedSmiPtr token_pos;
+    CompressedStringPtr name;
+    CompressedSmiPtr flags;
     static constexpr intptr_t kIsFinal = 0x1;
     static constexpr intptr_t kIsConst = 0x2;
     static constexpr intptr_t kIsLate = 0x4;
-    SmiPtr late_init_offset;
+    CompressedSmiPtr late_init_offset;
     union {
-      AbstractTypePtr type;
-      InstancePtr value;  // iff is_const is true
+      CompressedAbstractTypePtr type;
+      CompressedInstancePtr value;  // iff is_const is true
     };
-    SmiPtr context_index;
-    SmiPtr context_level;
+    CompressedSmiPtr context_index;
+    CompressedSmiPtr context_level;
   };
 
   int32_t num_variables_;
   bool is_implicit_;  // true, if this context scope is for an implicit closure.
 
-  ObjectPtr* from() {
+  CompressedObjectPtr* from() {
     VariableDesc* begin = const_cast<VariableDesc*>(VariableDescAddr(0));
-    return reinterpret_cast<ObjectPtr*>(begin);
+    return reinterpret_cast<CompressedObjectPtr*>(begin);
   }
   // Variable length data follows here.
-  ObjectPtr const* data() const { OPEN_ARRAY_START(ObjectPtr, ObjectPtr); }
+  CompressedObjectPtr const* data() const {
+    OPEN_ARRAY_START(CompressedObjectPtr, CompressedObjectPtr);
+  }
   const VariableDesc* VariableDescAddr(intptr_t index) const {
     ASSERT((index >= 0) && (index < num_variables_ + 1));
     // data() points to the first component of the first descriptor.
     return &(reinterpret_cast<const VariableDesc*>(data())[index]);
   }
-  ObjectPtr* to(intptr_t num_vars) {
+
+#define DEFINE_ACCESSOR(type, name)                                            \
+  type name##_at(intptr_t index) {                                             \
+    return LoadCompressedPointer<type>(&VariableDescAddr(index)->name);        \
+  }                                                                            \
+  void set_##name##_at(intptr_t index, type value) {                           \
+    StoreCompressedPointer(&VariableDescAddr(index)->name, value);             \
+  }
+  DEFINE_ACCESSOR(SmiPtr, declaration_token_pos)
+  DEFINE_ACCESSOR(SmiPtr, token_pos)
+  DEFINE_ACCESSOR(StringPtr, name)
+  DEFINE_ACCESSOR(SmiPtr, flags)
+  DEFINE_ACCESSOR(SmiPtr, late_init_offset)
+  DEFINE_ACCESSOR(AbstractTypePtr, type)
+  DEFINE_ACCESSOR(InstancePtr, value)
+  DEFINE_ACCESSOR(SmiPtr, context_index)
+  DEFINE_ACCESSOR(SmiPtr, context_level)
+#undef DEFINE_ACCESSOR
+
+  CompressedObjectPtr* to(intptr_t num_vars) {
     uword end = reinterpret_cast<uword>(VariableDescAddr(num_vars));
     // 'end' is the address just beyond the last descriptor, so step back.
-    return reinterpret_cast<ObjectPtr*>(end - kWordSize);
+    return reinterpret_cast<CompressedObjectPtr*>(end -
+                                                  sizeof(CompressedObjectPtr));
   }
-  ObjectPtr* to_snapshot(Snapshot::Kind kind, intptr_t num_vars) {
+  CompressedObjectPtr* to_snapshot(Snapshot::Kind kind, intptr_t num_vars) {
     return to(num_vars);
   }
 
@@ -2164,10 +2304,10 @@
 class UntaggedLoadingUnit : public UntaggedObject {
   RAW_HEAP_OBJECT_IMPLEMENTATION(LoadingUnit);
 
-  VISIT_FROM(ObjectPtr, parent)
-  POINTER_FIELD(LoadingUnitPtr, parent)
-  POINTER_FIELD(ArrayPtr, base_objects)
-  VISIT_TO(ObjectPtr, base_objects)
+  VISIT_FROM(CompressedObjectPtr, parent)
+  COMPRESSED_POINTER_FIELD(LoadingUnitPtr, parent)
+  COMPRESSED_POINTER_FIELD(ArrayPtr, base_objects)
+  VISIT_TO(CompressedObjectPtr, base_objects)
   int32_t id_;
   bool load_outstanding_;
   bool loaded_;
@@ -2180,44 +2320,44 @@
 class UntaggedApiError : public UntaggedError {
   RAW_HEAP_OBJECT_IMPLEMENTATION(ApiError);
 
-  VISIT_FROM(ObjectPtr, message)
-  POINTER_FIELD(StringPtr, message)
-  VISIT_TO(ObjectPtr, message)
+  VISIT_FROM(CompressedObjectPtr, message)
+  COMPRESSED_POINTER_FIELD(StringPtr, message)
+  VISIT_TO(CompressedObjectPtr, message)
 };
 
 class UntaggedLanguageError : public UntaggedError {
   RAW_HEAP_OBJECT_IMPLEMENTATION(LanguageError);
 
-  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)
+  VISIT_FROM(CompressedObjectPtr, previous_error)
+  COMPRESSED_POINTER_FIELD(ErrorPtr, previous_error)  // May be null.
+  COMPRESSED_POINTER_FIELD(ScriptPtr, script)
+  COMPRESSED_POINTER_FIELD(StringPtr, message)
+  // Incl. previous error's formatted message.
+  COMPRESSED_POINTER_FIELD(StringPtr, formatted_message)
+  VISIT_TO(CompressedObjectPtr, 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.
 
-  ObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
+  CompressedObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
 };
 
 class UntaggedUnhandledException : public UntaggedError {
   RAW_HEAP_OBJECT_IMPLEMENTATION(UnhandledException);
 
-  VISIT_FROM(ObjectPtr, exception)
-  POINTER_FIELD(InstancePtr, exception)
-  POINTER_FIELD(InstancePtr, stacktrace)
-  VISIT_TO(ObjectPtr, stacktrace)
-  ObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
+  VISIT_FROM(CompressedObjectPtr, exception)
+  COMPRESSED_POINTER_FIELD(InstancePtr, exception)
+  COMPRESSED_POINTER_FIELD(InstancePtr, stacktrace)
+  VISIT_TO(CompressedObjectPtr, stacktrace)
+  CompressedObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
 };
 
 class UntaggedUnwindError : public UntaggedError {
   RAW_HEAP_OBJECT_IMPLEMENTATION(UnwindError);
 
-  VISIT_FROM(ObjectPtr, message)
-  POINTER_FIELD(StringPtr, message)
-  VISIT_TO(ObjectPtr, message)
+  VISIT_FROM(CompressedObjectPtr, message)
+  COMPRESSED_POINTER_FIELD(StringPtr, message)
+  VISIT_TO(CompressedObjectPtr, message)
   bool is_user_initiated_;
 };
 
@@ -2228,19 +2368,22 @@
 class UntaggedLibraryPrefix : public UntaggedInstance {
   RAW_HEAP_OBJECT_IMPLEMENTATION(LibraryPrefix);
 
-  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) {
+  VISIT_FROM(CompressedObjectPtr, name)
+  // Library prefix name.
+  COMPRESSED_POINTER_FIELD(StringPtr, name)
+  // Libraries imported with this prefix.
+  COMPRESSED_POINTER_FIELD(ArrayPtr, imports)
+  // Library which declares this prefix.
+  COMPRESSED_POINTER_FIELD(LibraryPtr, importer)
+  VISIT_TO(CompressedObjectPtr, importer)
+  CompressedObjectPtr* to_snapshot(Snapshot::Kind kind) {
     switch (kind) {
       case Snapshot::kFullAOT:
-        return reinterpret_cast<ObjectPtr*>(&imports_);
+        return reinterpret_cast<CompressedObjectPtr*>(&imports_);
       case Snapshot::kFull:
       case Snapshot::kFullCore:
       case Snapshot::kFullJIT:
-        return reinterpret_cast<ObjectPtr*>(&importer_);
+        return reinterpret_cast<CompressedObjectPtr*>(&importer_);
       case Snapshot::kMessage:
       case Snapshot::kNone:
       case Snapshot::kInvalid:
@@ -2288,7 +2431,7 @@
   static constexpr intptr_t kTypeStateBitSize = 2;
 
   uword type_test_stub_entry_point_;  // Accessed from generated code.
-  POINTER_FIELD(
+  COMPRESSED_POINTER_FIELD(
       CodePtr,
       type_test_stub)  // Must be the last field, since subclasses use it
                        // in their VISIT_FROM.
@@ -2304,15 +2447,15 @@
  private:
   RAW_HEAP_OBJECT_IMPLEMENTATION(Type);
 
-  VISIT_FROM(ObjectPtr, type_test_stub)
-  POINTER_FIELD(SmiPtr, type_class_id)
-  POINTER_FIELD(TypeArgumentsPtr, arguments)
-  POINTER_FIELD(SmiPtr, hash)
-  VISIT_TO(ObjectPtr, hash)
+  VISIT_FROM(CompressedObjectPtr, type_test_stub)
+  COMPRESSED_POINTER_FIELD(SmiPtr, type_class_id)
+  COMPRESSED_POINTER_FIELD(TypeArgumentsPtr, arguments)
+  COMPRESSED_POINTER_FIELD(SmiPtr, hash)
+  VISIT_TO(CompressedObjectPtr, hash)
   uint8_t type_state_;
   uint8_t nullability_;
 
-  ObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
+  CompressedObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
 
   friend class CidRewriteVisitor;
   friend class UntaggedTypeArguments;
@@ -2322,13 +2465,14 @@
  private:
   RAW_HEAP_OBJECT_IMPLEMENTATION(FunctionType);
 
-  VISIT_FROM(ObjectPtr, type_test_stub)
-  POINTER_FIELD(TypeArgumentsPtr, type_parameters)  // Array of TypeParameter.
-  POINTER_FIELD(AbstractTypePtr, result_type)
-  POINTER_FIELD(ArrayPtr, parameter_types)
-  POINTER_FIELD(ArrayPtr, parameter_names);
-  POINTER_FIELD(SmiPtr, hash)
-  VISIT_TO(ObjectPtr, hash)
+  VISIT_FROM(CompressedObjectPtr, type_test_stub)
+  // Array of TypeParameter.
+  COMPRESSED_POINTER_FIELD(TypeArgumentsPtr, type_parameters)
+  COMPRESSED_POINTER_FIELD(AbstractTypePtr, result_type)
+  COMPRESSED_POINTER_FIELD(ArrayPtr, parameter_types)
+  COMPRESSED_POINTER_FIELD(ArrayPtr, parameter_names);
+  COMPRESSED_POINTER_FIELD(SmiPtr, hash)
+  VISIT_TO(CompressedObjectPtr, hash)
   uint32_t packed_fields_;  // Number of parent type args and own parameters.
   uint8_t type_state_;
   uint8_t nullability_;
@@ -2342,6 +2486,8 @@
   static constexpr intptr_t kMaxOptionalParametersBits =
       UntaggedFunction::kMaxOptionalParametersBits;
 
+  // The bit fields are public for use in kernel_to_il.cc.
+ public:
   typedef BitField<uint32_t, uint8_t, 0, kMaxParentTypeArgumentsBits>
       PackedNumParentTypeArguments;
   typedef BitField<uint32_t,
@@ -2372,7 +2518,8 @@
                 "In-place mask for number of optional parameters cannot fit in "
                 "a Smi on the target architecture");
 
-  ObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
+ private:
+  CompressedObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
 
   friend class Function;
 };
@@ -2381,27 +2528,27 @@
  private:
   RAW_HEAP_OBJECT_IMPLEMENTATION(TypeRef);
 
-  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(); }
+  VISIT_FROM(CompressedObjectPtr, type_test_stub)
+  COMPRESSED_POINTER_FIELD(AbstractTypePtr, type)  // The referenced type.
+  VISIT_TO(CompressedObjectPtr, type)
+  CompressedObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
 };
 
 class UntaggedTypeParameter : public UntaggedAbstractType {
  private:
   RAW_HEAP_OBJECT_IMPLEMENTATION(TypeParameter);
 
-  VISIT_FROM(ObjectPtr, type_test_stub)
-  POINTER_FIELD(StringPtr, name)
-  POINTER_FIELD(SmiPtr, hash)
-  POINTER_FIELD(AbstractTypePtr,
-                bound)  // ObjectType if no explicit bound specified.
+  VISIT_FROM(CompressedObjectPtr, type_test_stub)
+  COMPRESSED_POINTER_FIELD(StringPtr, name)
+  COMPRESSED_POINTER_FIELD(SmiPtr, hash)
+  // ObjectType if no explicit bound specified.
+  COMPRESSED_POINTER_FIELD(AbstractTypePtr, bound)
   // 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.
-  POINTER_FIELD(AbstractTypePtr, default_argument)
-  VISIT_TO(ObjectPtr, default_argument)
+  COMPRESSED_POINTER_FIELD(AbstractTypePtr, default_argument)
+  VISIT_TO(CompressedObjectPtr, default_argument)
   ClassIdTagType parameterized_class_id_;  // Or kFunctionCid for function tp.
   // TODO(regis): Can we use uint8_t twice below? Or keep uint16_t?
   // Warning: BuildTypeParameterTypeTestStub assumes uint16_t.
@@ -2419,7 +2566,7 @@
   static constexpr intptr_t kFlagsBitSize = GenericCovariantImplBit::kNextBit;
 
  private:
-  ObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
+  CompressedObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
 
   friend class CidRewriteVisitor;
 };
@@ -2510,13 +2657,13 @@
   RAW_HEAP_OBJECT_IMPLEMENTATION(String);
 
  protected:
-  VISIT_FROM(ObjectPtr, length)
-  SMI_FIELD(SmiPtr, length)
+  VISIT_FROM(CompressedObjectPtr, length)
+  COMPRESSED_SMI_FIELD(SmiPtr, length)
 #if !defined(HASH_IN_OBJECT_HEADER)
-  SMI_FIELD(SmiPtr, hash)
-  VISIT_TO(ObjectPtr, hash)
+  COMPRESSED_SMI_FIELD(SmiPtr, hash)
+  VISIT_TO(CompressedObjectPtr, hash)
 #else
-  VISIT_TO(ObjectPtr, length)
+  VISIT_TO(CompressedObjectPtr, length)
 #endif
 
  private:
@@ -2585,7 +2732,7 @@
  protected:
   // The length of the view in element sizes (obtainable via
   // [TypedDataBase::ElementSizeInBytes]).
-  SMI_FIELD(SmiPtr, length);
+  COMPRESSED_SMI_FIELD(SmiPtr, length);
 
  private:
   friend class UntaggedTypedDataView;
@@ -2604,8 +2751,8 @@
   void RecomputeDataField() { data_ = internal_data(); }
 
  protected:
-  VISIT_FROM(ObjectPtr, length)
-  VISIT_TO_LENGTH(ObjectPtr, &length_)
+  VISIT_FROM(CompressedObjectPtr, length)
+  VISIT_TO_LENGTH(CompressedObjectPtr, &length_)
 
   // Variable length data follows here.
 
@@ -2639,34 +2786,38 @@
  public:
   // Recompute [data_] based on internal/external [typed_data_].
   void RecomputeDataField() {
-    const intptr_t offset_in_bytes = RawSmiValue(offset_in_bytes_);
+    const intptr_t offset_in_bytes = RawSmiValue(this->offset_in_bytes());
     uint8_t* payload = typed_data()->untag()->data_;
     data_ = payload + offset_in_bytes;
   }
 
-  // Recopute [data_] based on internal [typed_data_] - needs to be called by GC
-  // whenever the backing store moved.
+  // Recompute [data_] based on internal [typed_data_] - needs to be called by
+  // GC whenever the backing store moved.
   //
   // NOTICE: This method assumes [this] is the forwarded object and the
   // [typed_data_] pointer points to the new backing store. The backing store's
   // fields don't need to be valid - only it's address.
   void RecomputeDataFieldForInternalTypedData() {
-    const intptr_t offset_in_bytes = RawSmiValue(offset_in_bytes_);
+    data_ = DataFieldForInternalTypedData();
+  }
+
+  uint8_t* DataFieldForInternalTypedData() const {
+    const intptr_t offset_in_bytes = RawSmiValue(this->offset_in_bytes());
     uint8_t* payload =
         reinterpret_cast<uint8_t*>(UntaggedObject::ToAddr(typed_data()) +
                                    UntaggedTypedData::payload_offset());
-    data_ = payload + offset_in_bytes;
+    return payload + offset_in_bytes;
   }
 
   void ValidateInnerPointer() {
     if (typed_data()->untag()->GetClassId() == kNullCid) {
       // The view object must have gotten just initialized.
-      if (data_ != nullptr || RawSmiValue(offset_in_bytes_) != 0 ||
-          RawSmiValue(length_) != 0) {
+      if (data_ != nullptr || RawSmiValue(offset_in_bytes()) != 0 ||
+          RawSmiValue(length()) != 0) {
         FATAL("RawTypedDataView has invalid inner pointer.");
       }
     } else {
-      const intptr_t offset_in_bytes = RawSmiValue(offset_in_bytes_);
+      const intptr_t offset_in_bytes = RawSmiValue(this->offset_in_bytes());
       uint8_t* payload = typed_data()->untag()->data_;
       if ((payload + offset_in_bytes) != data_) {
         FATAL("RawTypedDataView has invalid inner pointer.");
@@ -2675,11 +2826,11 @@
   }
 
  protected:
-  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(); }
+  VISIT_FROM(CompressedObjectPtr, length)
+  COMPRESSED_POINTER_FIELD(TypedDataBasePtr, typed_data)
+  COMPRESSED_SMI_FIELD(SmiPtr, offset_in_bytes)
+  VISIT_TO(CompressedObjectPtr, offset_in_bytes)
+  CompressedObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
 
   friend class Api;
   friend class Object;
@@ -2744,7 +2895,8 @@
   friend class ICData;            // For high performance access.
   friend class SubtypeTestCache;  // For high performance access.
   friend class ReversePc;
-
+  template <typename Table, bool kAllCanonicalObjectsAreIncludedIntoSet>
+  friend class CanonicalSetDeserializationCluster;
   friend class OldPage;
 };
 
@@ -2854,16 +3006,16 @@
   RAW_HEAP_OBJECT_IMPLEMENTATION(ExternalTypedData);
 
  protected:
-  VISIT_FROM(ObjectPtr, length)
-  VISIT_TO(ObjectPtr, length)
+  VISIT_FROM(CompressedObjectPtr, length)
+  VISIT_TO(CompressedObjectPtr, length)
 };
 
 class UntaggedPointer : public UntaggedPointerBase {
   RAW_HEAP_OBJECT_IMPLEMENTATION(Pointer);
 
-  VISIT_FROM(ObjectPtr, type_arguments)
-  POINTER_FIELD(TypeArgumentsPtr, type_arguments)
-  VISIT_TO(ObjectPtr, type_arguments)
+  VISIT_FROM(CompressedObjectPtr, type_arguments)
+  COMPRESSED_POINTER_FIELD(TypeArgumentsPtr, type_arguments)
+  VISIT_TO(CompressedObjectPtr, type_arguments)
 
   friend class Pointer;
 };
@@ -2895,15 +3047,15 @@
 class UntaggedReceivePort : public UntaggedInstance {
   RAW_HEAP_OBJECT_IMPLEMENTATION(ReceivePort);
 
-  VISIT_FROM(ObjectPtr, send_port)
-  POINTER_FIELD(SendPortPtr, send_port)
-  POINTER_FIELD(InstancePtr, handler)
+  VISIT_FROM(CompressedObjectPtr, send_port)
+  COMPRESSED_POINTER_FIELD(SendPortPtr, send_port)
+  COMPRESSED_POINTER_FIELD(InstancePtr, handler)
 #if !defined(PRODUCT)
-  POINTER_FIELD(StringPtr, debug_name)
-  POINTER_FIELD(StackTracePtr, allocation_location)
-  VISIT_TO(ObjectPtr, allocation_location)
+  COMPRESSED_POINTER_FIELD(StringPtr, debug_name)
+  COMPRESSED_POINTER_FIELD(StackTracePtr, allocation_location)
+  VISIT_TO(CompressedObjectPtr, allocation_location)
 #else
-  VISIT_TO(ObjectPtr, handler)
+  VISIT_TO(CompressedObjectPtr, handler)
 #endif  // !defined(PRODUCT)
 };
 
@@ -2919,15 +3071,16 @@
 class UntaggedStackTrace : public UntaggedInstance {
   RAW_HEAP_OBJECT_IMPLEMENTATION(StackTrace);
 
-  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(TypedDataPtr, pc_offset_array);  // Offset of PC for each frame.
+  VISIT_FROM(CompressedObjectPtr, async_link)
+  // Link to parent async stack trace.
+  COMPRESSED_POINTER_FIELD(StackTracePtr, async_link);
+  // Code object for each frame in the stack trace.
+  COMPRESSED_POINTER_FIELD(ArrayPtr, code_array);
+  // Offset of PC for each frame.
+  COMPRESSED_POINTER_FIELD(TypedDataPtr, pc_offset_array);
 
-  VISIT_TO(ObjectPtr, pc_offset_array)
-  ObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
+  VISIT_TO(CompressedObjectPtr, pc_offset_array)
+  CompressedObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
 
   // False for pre-allocated stack trace (used in OOM and Stack overflow).
   bool expand_inlined_;
@@ -2941,20 +3094,22 @@
 class UntaggedRegExp : public UntaggedInstance {
   RAW_HEAP_OBJECT_IMPLEMENTATION(RegExp);
 
-  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(); }
+  VISIT_FROM(CompressedObjectPtr, capture_name_map)
+  COMPRESSED_POINTER_FIELD(ArrayPtr, capture_name_map)
+  // Pattern to be used for matching.
+  COMPRESSED_POINTER_FIELD(StringPtr, pattern)
+  COMPRESSED_POINTER_FIELD(ObjectPtr, one_byte)  // FunctionPtr or TypedDataPtr
+  COMPRESSED_POINTER_FIELD(ObjectPtr, two_byte)
+  COMPRESSED_POINTER_FIELD(ObjectPtr, external_one_byte)
+  COMPRESSED_POINTER_FIELD(ObjectPtr, external_two_byte)
+  COMPRESSED_POINTER_FIELD(ObjectPtr, one_byte_sticky)
+  COMPRESSED_POINTER_FIELD(ObjectPtr, two_byte_sticky)
+  COMPRESSED_POINTER_FIELD(ObjectPtr, external_one_byte_sticky)
+  COMPRESSED_POINTER_FIELD(ObjectPtr, external_two_byte_sticky)
+  VISIT_TO(CompressedObjectPtr, external_two_byte_sticky)
+  CompressedObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
+
+  intptr_t num_bracket_expressions_;
 
   // The same pattern may use different amount of registers if compiled
   // for a one-byte target than a two-byte target. For example, we do not
@@ -2996,18 +3151,18 @@
 class UntaggedMirrorReference : public UntaggedInstance {
   RAW_HEAP_OBJECT_IMPLEMENTATION(MirrorReference);
 
-  VISIT_FROM(ObjectPtr, referent)
-  POINTER_FIELD(ObjectPtr, referent)
-  VISIT_TO(ObjectPtr, referent)
+  VISIT_FROM(CompressedObjectPtr, referent)
+  COMPRESSED_POINTER_FIELD(ObjectPtr, referent)
+  VISIT_TO(CompressedObjectPtr, referent)
 };
 
 // UserTag are used by the profiler to track Dart script state.
 class UntaggedUserTag : public UntaggedInstance {
   RAW_HEAP_OBJECT_IMPLEMENTATION(UserTag);
 
-  VISIT_FROM(ObjectPtr, label)
-  POINTER_FIELD(StringPtr, label)
-  VISIT_TO(ObjectPtr, label)
+  VISIT_FROM(CompressedObjectPtr, label)
+  COMPRESSED_POINTER_FIELD(StringPtr, label)
+  VISIT_TO(CompressedObjectPtr, label)
 
   // Isolate unique tag.
   uword tag_;
diff --git a/runtime/vm/raw_object_snapshot.cc b/runtime/vm/raw_object_snapshot.cc
index f8c40d1..414430b 100644
--- a/runtime/vm/raw_object_snapshot.cc
+++ b/runtime/vm/raw_object_snapshot.cc
@@ -33,6 +33,14 @@
     object.StorePointer(((from) + i), reader->PassiveObjectHandle()->ptr());   \
   }
 
+#define READ_COMPRESSED_OBJECT_FIELDS(object, from, to, as_reference)          \
+  intptr_t num_flds = (to) - (from);                                           \
+  for (intptr_t i = 0; i <= num_flds; i++) {                                   \
+    (*reader->PassiveObjectHandle()) = reader->ReadObjectImpl(as_reference);   \
+    object.StoreCompressedPointer(((from) + i),                                \
+                                  reader->PassiveObjectHandle()->ptr());       \
+  }
+
 ClassPtr Class::ReadFrom(SnapshotReader* reader,
                          intptr_t object_id,
                          intptr_t tags,
@@ -93,8 +101,8 @@
   reader->EnqueueTypePostprocessing(type);
 
   // Set all the object fields.
-  READ_OBJECT_FIELDS(type, type.ptr()->untag()->from(),
-                     type.ptr()->untag()->to(), as_reference);
+  READ_COMPRESSED_OBJECT_FIELDS(type, type.ptr()->untag()->from(),
+                                type.ptr()->untag()->to(), as_reference);
 
   // Read in the type class.
   (*reader->ClassHandle()) =
@@ -158,7 +166,7 @@
   // Write out all the object pointer fields.
   ASSERT(type_class_id() != Object::null());
   SnapshotWriterVisitor visitor(writer, as_reference);
-  visitor.VisitPointers(from(), to());
+  visitor.VisitCompressedPointers(heap_base(), from(), to());
 
   // Write out the type class.
   writer->WriteObjectImpl(type_class, as_reference);
@@ -179,8 +187,8 @@
   reader->EnqueueTypePostprocessing(type_ref);
 
   // Set all the object fields.
-  READ_OBJECT_FIELDS(type_ref, type_ref.ptr()->untag()->from(),
-                     type_ref.ptr()->untag()->to(), kAsReference);
+  READ_COMPRESSED_OBJECT_FIELDS(type_ref, type_ref.ptr()->untag()->from(),
+                                type_ref.ptr()->untag()->to(), kAsReference);
 
   // Fill in the type testing stub.
   Code& code = *reader->CodeHandle();
@@ -205,7 +213,7 @@
 
   // Write out all the object pointer fields.
   SnapshotWriterVisitor visitor(writer, kAsReference);
-  visitor.VisitPointers(from(), to());
+  visitor.VisitCompressedPointers(heap_base(), from(), to());
 }
 
 TypeParameterPtr TypeParameter::ReadFrom(SnapshotReader* reader,
@@ -230,8 +238,9 @@
   reader->EnqueueTypePostprocessing(type_parameter);
 
   // Set all the object fields.
-  READ_OBJECT_FIELDS(type_parameter, type_parameter.ptr()->untag()->from(),
-                     type_parameter.ptr()->untag()->to(), kAsReference);
+  READ_COMPRESSED_OBJECT_FIELDS(
+      type_parameter, type_parameter.ptr()->untag()->from(),
+      type_parameter.ptr()->untag()->to(), kAsReference);
 
   // Read in the parameterized class.
   (*reader->ClassHandle()) =
@@ -279,7 +288,7 @@
 
   // Write out all the object pointer fields.
   SnapshotWriterVisitor visitor(writer, kAsReference);
-  visitor.VisitPointers(from(), to());
+  visitor.VisitCompressedPointers(heap_base(), from(), to());
 
   // Write out the parameterized class (or Function if cid == kFunctionCid).
   ClassPtr param_class =
@@ -491,7 +500,8 @@
     writer->Write<bool>(true);
 
     // Write out the type of 'this' the variable.
-    writer->WriteObjectImpl(var->type, kAsInlinedObject);
+    writer->WriteObjectImpl(var->type.Decompress(heap_base()),
+                            kAsInlinedObject);
 
     return;
   }
@@ -580,8 +590,8 @@
   reader->AddBackRef(object_id, &api_error, kIsDeserialized);
 
   // Set all the object fields.
-  READ_OBJECT_FIELDS(api_error, api_error.ptr()->untag()->from(),
-                     api_error.ptr()->untag()->to(), kAsReference);
+  READ_COMPRESSED_OBJECT_FIELDS(api_error, api_error.ptr()->untag()->from(),
+                                api_error.ptr()->untag()->to(), kAsReference);
 
   return api_error.ptr();
 }
@@ -601,7 +611,7 @@
 
   // Write out all the object pointer fields.
   SnapshotWriterVisitor visitor(writer, kAsReference);
-  visitor.VisitPointers(from(), to());
+  visitor.VisitCompressedPointers(heap_base(), from(), to());
 }
 
 LanguageErrorPtr LanguageError::ReadFrom(SnapshotReader* reader,
@@ -623,8 +633,9 @@
   language_error.set_kind(reader->Read<uint8_t>());
 
   // Set all the object fields.
-  READ_OBJECT_FIELDS(language_error, language_error.ptr()->untag()->from(),
-                     language_error.ptr()->untag()->to(), kAsReference);
+  READ_COMPRESSED_OBJECT_FIELDS(
+      language_error, language_error.ptr()->untag()->from(),
+      language_error.ptr()->untag()->to(), kAsReference);
 
   return language_error.ptr();
 }
@@ -649,7 +660,7 @@
 
   // Write out all the object pointer fields.
   SnapshotWriterVisitor visitor(writer, kAsReference);
-  visitor.VisitPointers(from(), to());
+  visitor.VisitCompressedPointers(heap_base(), from(), to());
 }
 
 UnhandledExceptionPtr UnhandledException::ReadFrom(SnapshotReader* reader,
@@ -662,8 +673,8 @@
   reader->AddBackRef(object_id, &result, kIsDeserialized);
 
   // Set all the object fields.
-  READ_OBJECT_FIELDS(result, result.ptr()->untag()->from(),
-                     result.ptr()->untag()->to(), kAsReference);
+  READ_COMPRESSED_OBJECT_FIELDS(result, result.ptr()->untag()->from(),
+                                result.ptr()->untag()->to(), kAsReference);
 
   return result.ptr();
 }
@@ -680,7 +691,7 @@
   writer->WriteTags(writer->GetObjectTags(this));
   // Write out all the object pointer fields.
   SnapshotWriterVisitor visitor(writer, kAsReference);
-  visitor.VisitPointers(from(), to());
+  visitor.VisitCompressedPointers(heap_base(), from(), to());
 }
 
 InstancePtr Instance::ReadFrom(SnapshotReader* reader,
@@ -693,7 +704,8 @@
   // Create an Instance object or get canonical one if it is a canonical
   // constant.
   Instance& obj = Instance::ZoneHandle(reader->zone(), Instance::null());
-  obj ^= Object::Allocate(kInstanceCid, Instance::InstanceSize(), Heap::kNew);
+  obj ^= Object::Allocate(kInstanceCid, Instance::InstanceSize(), Heap::kNew,
+                          /*compressed*/ false);
   if (UntaggedObject::IsCanonical(tags)) {
     obj = obj.Canonicalize(reader->thread());
   }
@@ -1364,7 +1376,7 @@
                                 bool as_reference) {
   ASSERT(writer != NULL);
   intptr_t cid = this->GetClassId();
-  intptr_t length = Smi::Value(length_);  // In elements.
+  intptr_t length = Smi::Value(this->length());  // In elements.
   intptr_t external_cid;
   intptr_t bytes;
   switch (cid) {
@@ -1438,7 +1450,7 @@
     // Write as external.
     writer->WriteIndexedObject(external_cid);
     writer->WriteTags(writer->GetObjectTags(this));
-    writer->Write<ObjectPtr>(length_);
+    writer->Write<ObjectPtr>(this->length());
     uint8_t* data = reinterpret_cast<uint8_t*>(this->data());
     void* passed_data = malloc(bytes);
     memmove(passed_data, data, bytes);
@@ -1451,7 +1463,7 @@
     // Write as internal.
     writer->WriteIndexedObject(cid);
     writer->WriteTags(writer->GetObjectTags(this));
-    writer->Write<ObjectPtr>(length_);
+    writer->Write<ObjectPtr>(this->length());
     uint8_t* data = reinterpret_cast<uint8_t*>(this->data());
     writer->Align(Zone::kAlignment);
     writer->WriteBytes(data, bytes);
@@ -1464,7 +1476,7 @@
                                         bool as_reference) {
   ASSERT(writer != NULL);
   intptr_t cid = this->GetClassId();
-  intptr_t length = Smi::Value(length_);  // In elements.
+  intptr_t length = Smi::Value(this->length());  // In elements.
   intptr_t bytes;
   switch (cid) {
     case kExternalTypedDataInt8ArrayCid:
@@ -1520,7 +1532,7 @@
   // Write as external.
   writer->WriteIndexedObject(cid);
   writer->WriteTags(writer->GetObjectTags(this));
-  writer->Write<ObjectPtr>(length_);
+  writer->Write<ObjectPtr>(this->length());
   uint8_t* data = reinterpret_cast<uint8_t*>(data_);
   void* passed_data = malloc(bytes);
   memmove(passed_data, data, bytes);
@@ -1536,7 +1548,7 @@
                                     Snapshot::Kind kind,
                                     bool as_reference) {
   // Views have always a backing store.
-  ASSERT(typed_data_ != Object::null());
+  ASSERT(typed_data() != Object::null());
 
   // Write out the serialization header value for this object.
   writer->WriteInlinedObjectHeader(object_id);
@@ -1546,9 +1558,9 @@
   writer->WriteTags(writer->GetObjectTags(this));
 
   // Write members.
-  writer->Write<ObjectPtr>(offset_in_bytes_);
-  writer->Write<ObjectPtr>(length_);
-  writer->WriteObjectImpl(typed_data_, as_reference);
+  writer->Write<ObjectPtr>(offset_in_bytes());
+  writer->Write<ObjectPtr>(length());
+  writer->WriteObjectImpl(typed_data(), as_reference);
 }
 
 TypedDataViewPtr TypedDataView::ReadFrom(SnapshotReader* reader,
@@ -1702,13 +1714,13 @@
   reader->AddBackRef(object_id, &regex, kIsDeserialized);
 
   // Read and Set all the other fields.
-  regex.StoreSmi(&regex.untag()->num_bracket_expressions_, reader->ReadAsSmi());
-
   *reader->ArrayHandle() ^= reader->ReadObjectImpl(kAsInlinedObject);
   regex.set_capture_name_map(*reader->ArrayHandle());
   *reader->StringHandle() ^= reader->ReadObjectImpl(kAsInlinedObject);
   regex.set_pattern(*reader->StringHandle());
 
+  regex.StoreNonPointer(&regex.untag()->num_bracket_expressions_,
+                        reader->Read<int32_t>());
   regex.StoreNonPointer(&regex.untag()->num_one_byte_registers_,
                         reader->Read<int32_t>());
   regex.StoreNonPointer(&regex.untag()->num_two_byte_registers_,
@@ -1739,8 +1751,9 @@
   writer->WriteTags(writer->GetObjectTags(this));
 
   // Write out all the other fields.
-  writer->Write<ObjectPtr>(num_bracket_expressions_);
-  writer->WriteObjectImpl(pattern_, kAsInlinedObject);
+  writer->WriteObjectImpl(capture_name_map(), kAsInlinedObject);
+  writer->WriteObjectImpl(pattern(), kAsInlinedObject);
+  writer->Write<int32_t>(num_bracket_expressions_);
   writer->Write<int32_t>(num_one_byte_registers_);
   writer->Write<int32_t>(num_two_byte_registers_);
   writer->Write<int8_t>(type_flags_);
diff --git a/runtime/vm/regexp_assembler_bytecode.cc b/runtime/vm/regexp_assembler_bytecode.cc
index 4d8841f..708297a 100644
--- a/runtime/vm/regexp_assembler_bytecode.cc
+++ b/runtime/vm/regexp_assembler_bytecode.cc
@@ -465,7 +465,7 @@
   ASSERT(regexp.num_registers(is_one_byte) != -1);
 
   return regexp.num_registers(is_one_byte) +
-         (Smi::Value(regexp.num_bracket_expressions()) + 1) * 2;
+         (regexp.num_bracket_expressions() + 1) * 2;
 }
 
 static IrregexpInterpreter::IrregexpResult ExecRaw(const RegExp& regexp,
@@ -478,12 +478,9 @@
   bool is_one_byte =
       subject.IsOneByteString() || subject.IsExternalOneByteString();
 
-  ASSERT(regexp.num_bracket_expressions() != Smi::null());
-
   // We must have done EnsureCompiledIrregexp, so we can get the number of
   // registers.
-  int number_of_capture_registers =
-      (Smi::Value(regexp.num_bracket_expressions()) + 1) * 2;
+  int number_of_capture_registers = (regexp.num_bracket_expressions() + 1) * 2;
   int32_t* raw_output = &output[number_of_capture_registers];
 
   // We do not touch the actual capture result registers until we know there
@@ -533,7 +530,7 @@
               required_registers, zone);
 
   if (result == IrregexpInterpreter::RE_SUCCESS) {
-    intptr_t capture_count = Smi::Value(regexp.num_bracket_expressions());
+    intptr_t capture_count = regexp.num_bracket_expressions();
     intptr_t capture_register_count = (capture_count + 1) * 2;
     ASSERT(required_registers >= capture_register_count);
 
diff --git a/runtime/vm/runtime_entry.cc b/runtime/vm/runtime_entry.cc
index b3325b0..2345290 100644
--- a/runtime/vm/runtime_entry.cc
+++ b/runtime/vm/runtime_entry.cc
@@ -80,6 +80,10 @@
             deoptimize_filter,
             NULL,
             "Deoptimize in named function on stack overflow checks");
+DEFINE_FLAG(charp,
+            deoptimize_on_runtime_call_name_filter,
+            NULL,
+            "Runtime call name filter for --deoptimize-on-runtime-call-every.");
 
 DEFINE_FLAG(bool,
             unopt_monomorphic_calls,
@@ -172,7 +176,7 @@
   Exceptions::ThrowByType(Exceptions::kNoSuchMethod, args);
 }
 
-DEFINE_RUNTIME_ENTRY(NullError, 0) {
+static void DoThrowNullError(Isolate* isolate, Thread* thread, Zone* zone) {
   DartFrameIterator iterator(thread,
                              StackFrameIterator::kNoCrossThreadIteration);
   const StackFrame* caller_frame = iterator.NextFrame();
@@ -202,6 +206,59 @@
   NullErrorHelper(zone, member_name);
 }
 
+DEFINE_RUNTIME_ENTRY(NullError, 0) {
+  DoThrowNullError(isolate, thread, zone);
+}
+
+// Collects information about pointers within the top |kMaxSlotsCollected|
+// slots on the stack.
+// TODO(b/179632636) This code is added in attempt to better understand
+// b/179632636 and should be removed in the future.
+void ReportImpossibleNullError(intptr_t cid,
+                               StackFrame* caller_frame,
+                               Thread* thread) {
+  TextBuffer buffer(512);
+  buffer.Printf("hit null error with cid %" Pd ", caller context: ", cid);
+
+  const intptr_t kMaxSlotsCollected = 5;
+  const auto slots = reinterpret_cast<ObjectPtr*>(caller_frame->sp());
+  const intptr_t num_slots_in_frame =
+      reinterpret_cast<ObjectPtr*>(caller_frame->fp()) - slots;
+  const auto num_slots_to_collect =
+      Utils::Maximum(kMaxSlotsCollected, num_slots_in_frame);
+  bool comma = false;
+  for (intptr_t i = 0; i < num_slots_to_collect; i++) {
+    const ObjectPtr ptr = slots[i];
+    buffer.Printf("%s[sp+%" Pd "] %" Pp "", comma ? ", " : "", i,
+                  static_cast<uword>(ptr));
+    if (ptr->IsHeapObject() &&
+        (Dart::vm_isolate_group()->heap()->Contains(
+             UntaggedObject::ToAddr(ptr)) ||
+         thread->heap()->Contains(UntaggedObject::ToAddr(ptr)))) {
+      buffer.Printf("(%" Pp ")", static_cast<uword>(ptr->untag()->tags_));
+    }
+    comma = true;
+  }
+
+  const char* message = buffer.buffer();
+  FATAL("%s", message);
+}
+
+DEFINE_RUNTIME_ENTRY(DispatchTableNullError, 1) {
+  const Smi& cid = Smi::CheckedHandle(zone, arguments.ArgAt(0));
+  if (cid.Value() != kNullCid) {
+    // We hit null error, but receiver is not null itself. This most likely
+    // is a memory corruption. Crash the VM but provide some additonal
+    // information about the arguments on the stack.
+    DartFrameIterator iterator(thread,
+                               StackFrameIterator::kNoCrossThreadIteration);
+    StackFrame* caller_frame = iterator.NextFrame();
+    RELEASE_ASSERT(caller_frame->IsDartFrame());
+    ReportImpossibleNullError(cid.Value(), caller_frame, thread);
+  }
+  DoThrowNullError(isolate, thread, zone);
+}
+
 DEFINE_RUNTIME_ENTRY(NullErrorWithSelector, 1) {
   const String& selector = String::CheckedHandle(zone, arguments.ArgAt(0));
   NullErrorHelper(zone, selector);
@@ -559,8 +616,7 @@
   }
   const Function& function =
       Function::Handle(caller_frame->LookupDartFunction());
-  if (function.IsInvokeFieldDispatcher() ||
-      function.IsNoSuchMethodDispatcher()) {
+  if (function.HasSavedArgumentsDescriptor()) {
     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(),
@@ -1089,7 +1145,8 @@
   StackFrame* caller_frame = iterator.NextFrame();
   ASSERT(caller_frame != NULL);
   Code& orig_stub = Code::Handle(zone);
-  orig_stub = isolate->debugger()->GetPatchedStubAddress(caller_frame->pc());
+  orig_stub =
+      isolate->group()->debugger()->GetPatchedStubAddress(caller_frame->pc());
   const Error& error =
       Error::Handle(zone, isolate->debugger()->PauseBreakpoint());
   ThrowIfError(error);
@@ -1217,7 +1274,10 @@
 #if !defined(PRODUCT)
   // Skip functions that contain breakpoints or when debugger is in single
   // stepping mode.
-  if (Debugger::IsDebugging(thread, caller_function)) return;
+  if (thread->isolate_group()->debugger()->IsDebugging(thread,
+                                                       caller_function)) {
+    return;
+  }
 #endif
 
   const intptr_t num_checks = ic_data.NumberOfChecks();
@@ -2953,10 +3013,7 @@
   ASSERT(!unoptimized_code.IsNull());
   // The switch to unoptimized code may have already occurred.
   if (function.HasOptimizedCode()) {
-    SafepointWriteRwLocker ml(thread, thread->isolate_group()->program_lock());
-    if (function.HasOptimizedCode()) {
-      function.SwitchToUnoptimizedCode();
-    }
+    function.SwitchToUnoptimizedCode();
   }
 
   if (frame->IsMarkedForLazyDeopt()) {
@@ -2990,23 +3047,48 @@
 // Currently checks only that all optimized frames have kDeoptIndex
 // and unoptimized code has the kDeoptAfter.
 void DeoptimizeFunctionsOnStack() {
-  auto isolate_group = IsolateGroup::Current();
+  auto thread = Thread::Current();
+  // Have to grab program_lock before stopping everybody else.
+  SafepointWriteRwLocker ml(thread, thread->isolate_group()->program_lock());
+
+  auto isolate_group = thread->isolate_group();
   isolate_group->RunWithStoppedMutators([&]() {
     Code& optimized_code = Code::Handle();
-    isolate_group->ForEachIsolate([&](Isolate* isolate) {
-      auto mutator_thread = isolate->mutator_thread();
-      DartFrameIterator iterator(
-          mutator_thread, StackFrameIterator::kAllowCrossThreadIteration);
-      StackFrame* frame = iterator.NextFrame();
-      while (frame != nullptr) {
-        optimized_code = frame->LookupDartCode();
-        if (optimized_code.is_optimized() &&
-            !optimized_code.is_force_optimized()) {
-          DeoptimizeAt(mutator_thread, optimized_code, frame);
-        }
-        frame = iterator.NextFrame();
-      }
-    });
+    isolate_group->ForEachIsolate(
+        [&](Isolate* isolate) {
+          auto mutator_thread = isolate->mutator_thread();
+          DartFrameIterator iterator(
+              mutator_thread, StackFrameIterator::kAllowCrossThreadIteration);
+          StackFrame* frame = iterator.NextFrame();
+          while (frame != nullptr) {
+            optimized_code = frame->LookupDartCode();
+            if (optimized_code.is_optimized() &&
+                !optimized_code.is_force_optimized()) {
+              DeoptimizeAt(mutator_thread, optimized_code, frame);
+            }
+            frame = iterator.NextFrame();
+          }
+        },
+        /*at_safepoint=*/true);
+  });
+}
+
+static void DeoptimizeLastDartFrameIfOptimized() {
+  auto thread = Thread::Current();
+  // Have to grab program_lock before stopping everybody else.
+  SafepointWriteRwLocker ml(thread, thread->isolate_group()->program_lock());
+
+  auto isolate = thread->isolate();
+  auto isolate_group = thread->isolate_group();
+  isolate_group->RunWithStoppedMutators([&]() {
+    auto mutator_thread = isolate->mutator_thread();
+    DartFrameIterator iterator(mutator_thread,
+                               StackFrameIterator::kNoCrossThreadIteration);
+    StackFrame* frame = iterator.NextFrame();
+    const auto& optimized_code = Code::Handle(frame->LookupDartCode());
+    if (optimized_code.is_optimized() && !optimized_code.is_force_optimized()) {
+      DeoptimizeAt(mutator_thread, optimized_code, frame);
+    }
   });
 }
 
@@ -3205,6 +3287,31 @@
   UNREACHABLE();
 }
 
+void OnEveryRuntimeEntryCall(Thread* thread, const char* runtime_call_name) {
+  ASSERT(FLAG_deoptimize_on_runtime_call_every > 0);
+  if (FLAG_precompiled_mode) {
+    return;
+  }
+  if (IsolateGroup::IsSystemIsolateGroup(thread->isolate_group())) {
+    return;
+  }
+  const bool is_deopt_related = strstr(runtime_call_name, "Deoptimize") != 0;
+  if (is_deopt_related) {
+    return;
+  }
+  if (FLAG_deoptimize_on_runtime_call_name_filter != nullptr &&
+      (strlen(runtime_call_name) !=
+           strlen(FLAG_deoptimize_on_runtime_call_name_filter) ||
+       strstr(runtime_call_name, FLAG_deoptimize_on_runtime_call_name_filter) ==
+           0)) {
+    return;
+  }
+  const uint32_t count = thread->IncrementAndGetRuntimeCallCount();
+  if ((count % FLAG_deoptimize_on_runtime_call_every) == 0) {
+    DeoptimizeLastDartFrameIfOptimized();
+  }
+}
+
 double DartModulo(double left, double right) {
   double remainder = fmod_ieee(left, right);
   if (remainder == 0.0) {
@@ -3356,6 +3463,18 @@
     true /* is_float */,
     reinterpret_cast<RuntimeFunction>(static_cast<UnaryMathCFunction>(&atan)));
 
+DEFINE_RAW_LEAF_RUNTIME_ENTRY(
+    LibcExp,
+    1,
+    true /* is_float */,
+    reinterpret_cast<RuntimeFunction>(static_cast<UnaryMathCFunction>(&exp)));
+
+DEFINE_RAW_LEAF_RUNTIME_ENTRY(
+    LibcLog,
+    1,
+    true /* is_float */,
+    reinterpret_cast<RuntimeFunction>(static_cast<UnaryMathCFunction>(&log)));
+
 extern "C" void DFLRT_EnterSafepoint(NativeArguments __unusable_) {
   CHECK_STACK_ALIGNMENT;
   TRACE_RUNTIME_CALL("%s", "EnterSafepoint");
diff --git a/runtime/vm/runtime_entry.h b/runtime/vm/runtime_entry.h
index c3468ba..3120254 100644
--- a/runtime/vm/runtime_entry.h
+++ b/runtime/vm/runtime_entry.h
@@ -114,6 +114,9 @@
       StackZone zone(thread);                                                  \
       HANDLESCOPE(thread);                                                     \
       CHECK_SIMULATOR_STACK_OVERFLOW();                                        \
+      if (FLAG_deoptimize_on_runtime_call_every > 0) {                         \
+        OnEveryRuntimeEntryCall(thread, "" #name);                             \
+      }                                                                        \
       DRT_Helper##name(isolate, thread, zone.GetZone(), arguments);            \
     }                                                                          \
   }                                                                            \
@@ -160,6 +163,8 @@
 
 const char* DeoptReasonToCString(ICData::DeoptReasonId deopt_reason);
 
+void OnEveryRuntimeEntryCall(Thread* thread, const char* runtime_call_name);
+
 void DeoptimizeAt(Thread* mutator_thread,
                   const Code& optimized_code,
                   StackFrame* frame);
diff --git a/runtime/vm/runtime_entry_list.h b/runtime/vm/runtime_entry_list.h
index 34ac296..ca32756 100644
--- a/runtime/vm/runtime_entry_list.h
+++ b/runtime/vm/runtime_entry_list.h
@@ -38,6 +38,7 @@
   V(NullErrorWithSelector)                                                     \
   V(NullCastError)                                                             \
   V(ArgumentNullError)                                                         \
+  V(DispatchTableNullError)                                                    \
   V(ArgumentError)                                                             \
   V(ArgumentErrorUnboxedInt64)                                                 \
   V(IntegerDivisionByZeroException)                                            \
@@ -80,6 +81,8 @@
   V(double, LibcAsin, double)                                                  \
   V(double, LibcAtan, double)                                                  \
   V(double, LibcAtan2, double, double)                                         \
+  V(double, LibcExp, double)                                                   \
+  V(double, LibcLog, double)                                                   \
   V(uword /*BoolPtr*/, CaseInsensitiveCompareUCS2, uword /*StringPtr*/,        \
     uword /*SmiPtr*/, uword /*SmiPtr*/, uword /*SmiPtr*/)                      \
   V(uword /*BoolPtr*/, CaseInsensitiveCompareUTF16, uword /*StringPtr*/,       \
diff --git a/runtime/vm/scopes.cc b/runtime/vm/scopes.cc
index 3b08708..c643b46 100644
--- a/runtime/vm/scopes.cc
+++ b/runtime/vm/scopes.cc
@@ -362,7 +362,7 @@
   const ContextScope& context_scope =
       ContextScope::Handle(func.context_scope());
   if (!context_scope.IsNull()) {
-    ASSERT(func.IsLocalFunction());
+    ASSERT(func.HasParent());
     for (int i = 0; i < context_scope.num_variables(); i++) {
       String& name = String::Handle(context_scope.NameAt(i));
       UntaggedLocalVarDescriptors::VarInfoKind kind;
diff --git a/runtime/vm/service.h b/runtime/vm/service.h
index 00a3f32..032fafd 100644
--- a/runtime/vm/service.h
+++ b/runtime/vm/service.h
@@ -15,7 +15,7 @@
 namespace dart {
 
 #define SERVICE_PROTOCOL_MAJOR_VERSION 3
-#define SERVICE_PROTOCOL_MINOR_VERSION 43
+#define SERVICE_PROTOCOL_MINOR_VERSION 44
 
 class Array;
 class EmbedderServiceHandler;
diff --git a/runtime/vm/service/service.md b/runtime/vm/service/service.md
index e6df0a6..e78af3e 100644
--- a/runtime/vm/service/service.md
+++ b/runtime/vm/service/service.md
@@ -1,8 +1,8 @@
-# Dart VM Service Protocol 3.43
+# Dart VM Service Protocol 3.44
 
 > Please post feedback to the [observatory-discuss group][discuss-list]
 
-This document describes of _version 3.43_ of the Dart VM Service Protocol. This
+This document describes of _version 3.44_ of the Dart VM Service Protocol. This
 protocol is used to communicate with a running Dart Virtual Machine.
 
 To use the Service Protocol, start the VM with the *--observe* flag.
@@ -1841,7 +1841,10 @@
   // The number of samples returned.
   int sampleCount;
 
-  // The timespan the set of returned samples covers, in microseconds.
+  // The timespan the set of returned samples covers, in microseconds (deprecated).
+  //
+  // Note: this property is deprecated and will always return -1. Use `timeExtentMicros`
+  // instead.
   int timeSpan;
 
   // The start of the period of time in which the returned samples were
@@ -2409,6 +2412,11 @@
   // What kind of instance is this?
   InstanceKind kind;
 
+  // The identityHashCode assigned to the allocated object. This hash
+  // code is the same as the hash code provided in HeapSnapshot and
+  // CpuSample's returned by getAllocationTraces().
+  int identityHashCode;
+
   // Instance references always include their class.
   @Class class;
 
@@ -2521,6 +2529,11 @@
   // What kind of instance is this?
   InstanceKind kind;
 
+  // The identityHashCode assigned to the allocated object. This hash
+  // code is the same as the hash code provided in HeapSnapshot and
+  // CpuSample's returned by getAllocationTraces().
+  int identityHashCode;
+
   // Instance references always include their class.
   @Class class;
 
@@ -3997,5 +4010,6 @@
 3.41 | Added `PortList` object, `ReceivePort` `InstanceKind`, and `getPorts` RPC.
 3.42 | Added `limit` optional parameter to `getStack` RPC.
 3.43 | Updated heap snapshot format to include identity hash codes. Added `getAllocationTraces` and `setTraceClassAllocation` RPCs, updated `CpuSample` to include `identityHashCode` and `classId` properties, updated `Class` to include `traceAllocations` property.
+3.44 | Added `identityHashCode` property to `@Instance` and `Instance`.
 
 [discuss-list]: https://groups.google.com/a/dartlang.org/forum/#!forum/observatory-discuss
diff --git a/runtime/vm/service/service_extension.md b/runtime/vm/service/service_extension.md
index e5cc8ea..09dab75 100644
--- a/runtime/vm/service/service_extension.md
+++ b/runtime/vm/service/service_extension.md
@@ -1,4 +1,4 @@
-# Dart VM Service Protocol Extension 1.5
+# Dart VM Service Protocol Extension 1.6
 
 This protocol describes service extensions that are made available through
 the Dart core libraries, but are not part of the core
@@ -10,7 +10,7 @@
 
 ## dart:io Extensions
 
-This section describes _version 1.5_ of the dart:io service protocol extensions.
+This section describes _version 1.6_ of the dart:io service protocol extensions.
 
 ### getVersion
 
@@ -165,9 +165,50 @@
 
 See [HttpTimelineLoggingState](#httptimelineloggingstate).
 
+### getHttpProfile
+
+```
+HttpProfile getHttpProfile(string isolateId, int updatedSince [optional])
+```
+
+The `getHttpProfile` RPC is used to retrieve HTTP profiling information
+for requests made via `dart:io`'s `HttpClient`.
+
+The returned `HttpProfile` will only include requests issued after
+`httpTimelineLogging` has been enabled or after the last
+`clearHttpProfile` invocation.
+
+If `updatedSince` is provided, only requests started or updated since
+the specified time will be reported.
+
+See [HttpProfile](#httpprofile).
+
+### getHttpProfileRequest
+
+```
+HttpProfileRequest getHttpProfileRequest(string isolateId, int id)
+```
+
+The `getHttpProfileRequest` RPC is used to retrieve an instance of `HttpProfileRequest`,
+which includes request and response body data.
+
+See [HttpProfileRequest](#httprofilerequest).
+
+### clearHttpProfile
+
+```
+Success clearHttpProfile(string isolateId)
+```
+
+The `clearHttpProfile` RPC is used to clear previously recorded HTTP
+requests from the HTTP profiler state. Requests still in-flight after
+clearing the profiler state will be ignored by the profiler.
+
+See [Success](#success).
+
 ## Public Types
 
-### File
+### OpenFile
 
 ```
 class @OpenFile extends Response {
@@ -213,6 +254,15 @@
 
 A _OpenFile_ contains information about reads and writes to a currently opened file.
 
+### OpenFileList
+
+```
+class OpenFileList extends Response {
+  // A list of all files opened through dart:io.
+  @OpenFile[] files;
+}
+```
+
 ### HttpTimelineLoggingState
 
 ```
@@ -224,15 +274,216 @@
 
 See [httpEnableTimelineLogging](#httpenabletimelinelogging).
 
-### OpenFileList
+### HttpProfile
 
 ```
-class OpenFileList extends Response {
-  // A list of all files opened through dart:io.
-  @OpenFile[] files;
+class HttpProfile extends Response {
+  // The time at which this HTTP profile was built, in microseconds.
+  int timestamp;
+
+  // The set of recorded HTTP requests.
+  @HttpProfileRequest[] requests;
 }
 ```
 
+A collection of HTTP request data collected by the profiler.
+
+See [getHttpProfile](#gethttpprofile).
+
+### HttpProfileRequest
+
+```
+class @HttpProfileRequest extends Response {
+  // The ID associated with this request.
+  //
+  // This ID corresponds to the ID of the timeline event for this request.
+  int id;
+
+  // The ID of the isolate this request was issued from.
+  string isolateId;
+
+  // The HTTP request method associated with this request.
+  string method;
+
+  // The URI for this HTTP request.
+  string uri;
+
+  // The time at which this request was initiated, in microseconds.
+  final int startTime;
+
+  // The time at which this request was completed, in microseconds.
+  int endTime [optional];
+
+  // Information sent as part of the initial HTTP request.
+  //
+  // Will not be provided if the initial request has not yet completed.
+  HttpProfileRequestData request [optional];
+
+  // Information received in response to the initial HTTP request.
+  //
+  // Will not be provided if the request has not yet been responded to.
+  HttpProfileResponseData response [optional];
+}
+```
+
+```
+class HttpProfileRequest extends @HttpProfileRequest {
+  // The body sent as part of this request.
+  //
+  // Data written to a request body before encountering an error will be
+  // reported.
+  int[] requestBody [optional];
+
+  // The body received in response to the request.
+  int[] responseBody [optional];
+}
+```
+
+Profiling information for a single HTTP request.
+
+See [HttpProfile](#httpprofile).
+
+### HttpProfileRequestData
+
+```
+class HttpProfileRequestData {
+  // Information about the client connection.
+  //
+  // This property can be null, regardless of error state.
+  map<string, dynamic> connectionInfo [optional];
+
+  // The content length of the request, in bytes.
+  int contentLength [optional];
+
+  // Cookies presented to the server (in the 'cookie' header).
+  string[] cookies;
+
+  // Events that has occurred while issuing this HTTP request.
+  //
+  // Events which occurred before encountering an error will be reported.
+  HttpProfileRequestEvent[] events;
+
+  // The error associated with the failed request.
+  string error [optional];
+
+  // Whether to redirects are followed automatically.
+  bool followRedirects [optional];
+
+  // Returns the client request headers.
+  map<string, dynamic> headers [optional];
+
+  // The maximum number of redirects to follow when `followRedirects` is true.
+  int maxRedirects [optional];
+
+  // The method of the request.
+  string method [optional];
+
+  // The requested persistent connection state.
+  bool persistentConnection [optional];
+
+  // Proxy authentication details for this request.
+  HttpProfileProxyData proxyDetails [optional];
+}
+```
+
+Information sent as part of the initial HTTP request. If `error` is present,
+other properties will be null. If `error` is not present, all other properties
+will be provided unless otherwise specified.
+
+See [HttpProfileRequest](#httpprofilerequest).
+
+### HttpProfileResponseData
+
+```
+class HttpProfileResponseData {
+  // Returns the series of redirects this connection has been through.
+  //
+  // The list will be empty if no redirects were followed. redirects will be
+  // updated both in the case of an automatic and a manual redirect.
+  map<string, dynamic>[] redirects;
+
+  // Cookies set by the server (from the 'set-cookie' header).
+  string[] cookies;
+
+  // Information about the client connection.
+  map<string, dynamic> connectionInfo [optional];
+
+  // Returns the client response headers.
+  map<string, dynamic> headers;
+
+  // The compression state of the response.
+  //
+  // This specifies whether the response bytes were compressed when they were
+  // received across the wire and whether callers will receive compressed or
+  // uncompressed bytes when they listed to this response's byte stream.
+  string compressionState;
+
+  // Returns the reason phrase associated with the status code.
+  string reasonPhrase;
+
+  // Returns whether the status code is one of the normal redirect codes.
+  bool isRedirect;
+
+  // The persistent connection state returned by the server.
+  bool persistentConnection;
+
+  // Returns the content length of the response body.
+  //
+  // Returns -1 if the size of the response body is not known in advance.
+  int contentLength;
+
+  // Returns the status code.
+  int statusCode;
+
+  // The time at which the initial response was received, in microseconds.
+  int startTime;
+
+  // The time at which the response was completed, in microseconds.
+  int endTime [optional];
+
+  // The error associated with the failed request.
+  string error [optional];
+}
+```
+
+Information received in response to an initial HTTP request.
+
+See [HttpProfileRequest](#httpprofilerequest).
+
+### HttpProfileProxyData
+
+```
+class HttpProfileProxyData {
+  string host [optional];
+  string username [optional];
+  bool isDirect;
+  int port [optional];
+}
+```
+
+Proxy authentication details associated with a HTTP request.
+
+See [HttpProfileRequestData](#httpprofilerequestdata).
+
+### HttpProfileRequestEvent
+
+```
+class HttpProfileRequestEvent {
+  // The title of the recorded event.
+  string event;
+
+  // The time at which the event occurred, in microseconds.
+  int timestamp;
+
+  // Any arguments recorded for the event.
+  map<string, dynamic> arguments [optional];
+}
+```
+
+Describes an event that has occurred while issuing a HTTP request.
+
+See [HttpProfileRequestData](#httpprofilerequestdata).
+
 ### SocketProfilingState
 
 ```
diff --git a/runtime/vm/snapshot.cc b/runtime/vm/snapshot.cc
index b3ee8a3..4d9a35f 100644
--- a/runtime/vm/snapshot.cc
+++ b/runtime/vm/snapshot.cc
@@ -301,6 +301,7 @@
       typed_data_(TypedData::Handle(zone_)),
       typed_data_view_(TypedDataView::Handle(zone_)),
       function_(Function::Handle(zone_)),
+      smi_(Smi::Handle(zone_)),
       error_(UnhandledException::Handle(zone_)),
       set_class_(Class::ZoneHandle(
           zone_,
@@ -625,7 +626,8 @@
     instance_size = cls_.host_instance_size();
     ASSERT(instance_size > 0);
     // Allocate the instance and read in all the fields for the object.
-    *result ^= Object::Allocate(cls_.id(), instance_size, Heap::kNew);
+    *result ^= Object::Allocate(cls_.id(), instance_size, Heap::kNew,
+                                /*compressed*/ false);
   } else {
     cls_ ^= ReadObjectImpl(kAsInlinedObject);
     ASSERT(!cls_.IsNull());
@@ -1128,7 +1130,14 @@
 
   // First check if it is a Smi (i.e not a heap object).
   if (!rawobj->IsHeapObject()) {
+#if !defined(DART_COMPRESSED_POINTERS)
     Write<int64_t>(static_cast<intptr_t>(rawobj));
+#else
+    // One might expect this to be unnecessary because the reader will just
+    // ignore the upper bits, but the upper bits affect the variable-length
+    // encoding and can change lower bits in the variable-length reader.
+    Write<int64_t>(static_cast<intptr_t>(rawobj) << 32 >> 32);
+#endif
     return true;
   }
 
@@ -1332,7 +1341,7 @@
   // Write out the library url and class name.
   LibraryPtr library = cls->library();
   ASSERT(library != Library::null());
-  WriteObjectImpl(library->untag()->url_, kAsInlinedObject);
+  WriteObjectImpl(library->untag()->url(), kAsInlinedObject);
   WriteObjectImpl(cls->name(), kAsInlinedObject);
 }
 
@@ -1436,7 +1445,7 @@
     return static_cast<ClassPtr>(owner);
   }
   ASSERT(class_id == kPatchClassCid);
-  return static_cast<PatchClassPtr>(owner)->untag()->patched_class_;
+  return static_cast<PatchClassPtr>(owner)->untag()->patched_class();
 }
 
 void SnapshotWriter::CheckForNativeFields(ClassPtr cls) {
diff --git a/runtime/vm/snapshot.h b/runtime/vm/snapshot.h
index 93678d0..ba3f9a9 100644
--- a/runtime/vm/snapshot.h
+++ b/runtime/vm/snapshot.h
@@ -139,6 +139,14 @@
     return (kind == kFullJIT) || (kind == kFullAOT);
   }
 
+  static bool IncludesStringsInROData(Kind kind) {
+#if !defined(DART_COMPRESSED_POINTERS)
+    return IncludesCode(kind);
+#else
+    return false;
+#endif
+  }
+
   const uint8_t* Addr() const { return reinterpret_cast<const uint8_t*>(this); }
 
   const uint8_t* DataImage() const {
@@ -277,6 +285,7 @@
   TypedData* TypedDataHandle() { return &typed_data_; }
   TypedDataView* TypedDataViewHandle() { return &typed_data_view_; }
   Function* FunctionHandle() { return &function_; }
+  Smi* SmiHandle() { return &smi_; }
   Snapshot::Kind kind() const { return kind_; }
 
   // Reads an object.
@@ -371,6 +380,7 @@
   TypedData& typed_data_;          // Temporary typed data handle.
   TypedDataView& typed_data_view_;  // Temporary typed data view handle.
   Function& function_;             // Temporary function handle.
+  Smi& smi_;                       // Temporary Smi handle.
   UnhandledException& error_;      // Error handle.
   const Class& set_class_;         // The LinkedHashSet class.
   intptr_t max_vm_isolate_object_id_;
diff --git a/runtime/vm/stack_trace.cc b/runtime/vm/stack_trace.cc
index f200269..74fa21a 100644
--- a/runtime/vm/stack_trace.cc
+++ b/runtime/vm/stack_trace.cc
@@ -238,7 +238,7 @@
     return GetCallerInFutureImpl(future_);
   }
 
-  if (receiver_function_.IsLocalFunction()) {
+  if (receiver_function_.HasParent()) {
     parent_function_ = receiver_function_.parent_function();
     if (parent_function_.recognized_kind() ==
         MethodRecognizer::kFutureTimeout) {
diff --git a/runtime/vm/stub_code_list.h b/runtime/vm/stub_code_list.h
index d99a661..d1a200f 100644
--- a/runtime/vm/stub_code_list.h
+++ b/runtime/vm/stub_code_list.h
@@ -86,6 +86,7 @@
   V(OneArgUnoptimizedStaticCall)                                               \
   V(TwoArgsUnoptimizedStaticCall)                                              \
   V(AssertSubtype)                                                             \
+  V(AssertAssignable)                                                          \
   V(TypeIsTopTypeForSubtyping)                                                 \
   V(TypeIsTopTypeForSubtypingNullSafe)                                         \
   V(NullIsAssignableToType)                                                    \
@@ -125,6 +126,7 @@
   V(ReThrow)                                                                   \
   V(AssertBoolean)                                                             \
   V(InstanceOf)                                                                \
+  V(InstantiateType)                                                           \
   V(InstantiateTypeArguments)                                                  \
   V(InstantiateTypeArgumentsMayShareInstantiatorTA)                            \
   V(InstantiateTypeArgumentsMayShareFunctionTA)                                \
diff --git a/runtime/vm/symbols.h b/runtime/vm/symbols.h
index e647701..6688a92 100644
--- a/runtime/vm/symbols.h
+++ b/runtime/vm/symbols.h
@@ -125,6 +125,7 @@
   V(FfiDouble, "Double")                                                       \
   V(FfiDynamicLibrary, "DynamicLibrary")                                       \
   V(FfiElementType, "elementType")                                             \
+  V(FfiFieldPacking, "packing")                                                \
   V(FfiFieldTypes, "fieldTypes")                                               \
   V(FfiFloat, "Float")                                                         \
   V(FfiInt16, "Int16")                                                         \
@@ -439,9 +440,19 @@
   V(_get, "_get")                                                              \
   V(_handleMessage, "_handleMessage")                                          \
   V(_instanceOf, "_instanceOf")                                                \
+  V(_listGetAt, "_listGetAt")                                                  \
+  V(_listLength, "_listLength")                                                \
+  V(_listSetAt, "_listSetAt")                                                  \
   V(_lookupHandler, "_lookupHandler")                                          \
   V(_lookupOpenPorts, "_lookupOpenPorts")                                      \
+  V(_mapContainsKey, "_mapContainsKey")                                        \
+  V(_mapGet, "_mapGet")                                                        \
+  V(_mapKeys, "_mapKeys")                                                      \
   V(_name, "_name")                                                            \
+  V(_objectEquals, "_objectEquals")                                            \
+  V(_objectHashCode, "_objectHashCode")                                        \
+  V(_objectNoSuchMethod, "_objectNoSuchMethod")                                \
+  V(_objectToString, "_objectToString")                                        \
   V(_onData, "_onData")                                                        \
   V(_rehashObjects, "_rehashObjects")                                          \
   V(_resultOrListeners, "_resultOrListeners")                                  \
diff --git a/runtime/vm/tagged_pointer.h b/runtime/vm/tagged_pointer.h
index 63b446f..b0cb20d 100644
--- a/runtime/vm/tagged_pointer.h
+++ b/runtime/vm/tagged_pointer.h
@@ -189,10 +189,15 @@
   }
 
   ObjectPtr Decompress(uword heap_base) const { return *this; }
+  ObjectPtr DecompressSmi() const { return *this; }
   uword heap_base() const {
+    // TODO(rmacnak): Why does Windows have trouble linking GetClassId used
+    // here?
+#if !defined(HOST_OS_WINDOWS)
     ASSERT(IsHeapObject());
     ASSERT(!IsInstructions());
     ASSERT(!IsInstructionsSection());
+#endif
     return tagged_pointer_ & kHeapBaseMask;
   }
 
@@ -222,23 +227,36 @@
  public:
   explicit CompressedObjectPtr(ObjectPtr uncompressed)
       : compressed_pointer_(
-            static_cast<int32_t>(static_cast<uword>(uncompressed))) {}
+            static_cast<uint32_t>(static_cast<uword>(uncompressed))) {}
 
   ObjectPtr Decompress(uword heap_base) const {
-    return static_cast<ObjectPtr>(
-        static_cast<uword>(static_cast<word>(compressed_pointer_)) + heap_base);
+    return static_cast<ObjectPtr>(static_cast<uword>(compressed_pointer_) +
+                                  heap_base);
+  }
+
+  ObjectPtr DecompressSmi() const {
+    ASSERT((compressed_pointer_ & kSmiTagMask) != kHeapObjectTag);
+    return static_cast<ObjectPtr>(static_cast<uword>(compressed_pointer_));
   }
 
   const ObjectPtr& operator=(const ObjectPtr& other) {
-    compressed_pointer_ = static_cast<int32_t>(static_cast<uword>(other));
+    compressed_pointer_ = static_cast<uint32_t>(static_cast<uword>(other));
     return other;
   }
 
  protected:
-  int32_t compressed_pointer_;
+  uint32_t compressed_pointer_;
 };
 #define DEFINE_COMPRESSED_POINTER(klass, base)                                 \
-  class Compressed##klass##Ptr : public Compressed##base##Ptr {};
+  class Compressed##klass##Ptr : public Compressed##base##Ptr {                \
+   public:                                                                     \
+    explicit Compressed##klass##Ptr(klass##Ptr uncompressed)                   \
+        : Compressed##base##Ptr(uncompressed) {}                               \
+    const klass##Ptr& operator=(const klass##Ptr& other) {                     \
+      compressed_pointer_ = static_cast<uint32_t>(static_cast<uword>(other));  \
+      return other;                                                            \
+    }                                                                          \
+  };
 #endif
 
 #define DEFINE_TAGGED_POINTER(klass, base)                                     \
@@ -349,7 +367,12 @@
 #undef DEFINE_TAGGED_POINTER
 
 inline intptr_t RawSmiValue(const SmiPtr raw_value) {
+#if !defined(DART_COMPRESSED_POINTERS)
   const intptr_t value = static_cast<intptr_t>(raw_value);
+#else
+  const intptr_t value = static_cast<intptr_t>(static_cast<int32_t>(
+      static_cast<uint32_t>(static_cast<uintptr_t>(raw_value))));
+#endif
   ASSERT((value & kSmiTagMask) == kSmiTag);
   return (value >> kSmiTagShift);
 }
diff --git a/runtime/vm/thread.h b/runtime/vm/thread.h
index 5aee930..87b76c0 100644
--- a/runtime/vm/thread.h
+++ b/runtime/vm/thread.h
@@ -340,6 +340,8 @@
     return ++stack_overflow_count_;
   }
 
+  uint32_t IncrementAndGetRuntimeCallCount() { return ++runtime_call_count_; }
+
   static uword stack_overflow_shared_stub_entry_point_offset(bool fpu_regs) {
     return fpu_regs
                ? stack_overflow_shared_with_fpu_regs_entry_point_offset()
@@ -568,6 +570,10 @@
 
   bool IsInNoReloadScope() const { return no_reload_scope_depth_ > 0; }
 
+  bool IsInStoppedMutatorsScope() const {
+    return stopped_mutators_scope_depth_ > 0;
+  }
+
 #define DEFINE_OFFSET_METHOD(type_name, member_name, expr, default_init_value) \
   static intptr_t member_name##offset() {                                      \
     return OFFSET_OF(Thread, member_name);                                     \
@@ -1006,6 +1012,7 @@
   ApiLocalScope* api_reusable_scope_;
   int32_t no_callback_scope_depth_;
   intptr_t no_reload_scope_depth_ = 0;
+  intptr_t stopped_mutators_scope_depth_ = 0;
 #if defined(DEBUG)
   int32_t no_safepoint_scope_depth_;
 #endif
@@ -1014,6 +1021,7 @@
   uint16_t deferred_interrupts_mask_;
   uint16_t deferred_interrupts_;
   int32_t stack_overflow_count_;
+  uint32_t runtime_call_count_ = 0;
 
   // Deoptimization of stack frames.
   PendingDeopts pending_deopts_;
@@ -1102,6 +1110,7 @@
   friend class NoReloadScope;
   friend class Simulator;
   friend class StackZone;
+  friend class StoppedMutatorsScope;
   friend class ThreadRegistry;
   friend class CompilerState;
   friend class compiler::target::Thread;
@@ -1170,6 +1179,28 @@
   DISALLOW_COPY_AND_ASSIGN(NoReloadScope);
 };
 
+class StoppedMutatorsScope : public ThreadStackResource {
+ public:
+  explicit StoppedMutatorsScope(Thread* thread)
+      : ThreadStackResource(thread), thread_(thread) {
+#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
+    thread->stopped_mutators_scope_depth_++;
+    ASSERT(thread->stopped_mutators_scope_depth_ >= 0);
+#endif  // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
+  }
+
+  ~StoppedMutatorsScope() {
+#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
+    thread_->stopped_mutators_scope_depth_ -= 1;
+    ASSERT(thread_->stopped_mutators_scope_depth_ >= 0);
+#endif  // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
+  }
+
+ private:
+  Thread* thread_;
+  DISALLOW_COPY_AND_ASSIGN(StoppedMutatorsScope);
+};
+
 // Within a EnterCompilerScope, the thread must operate on cloned fields.
 #if defined(DEBUG)
 class EnterCompilerScope : public ThreadStackResource {
diff --git a/runtime/vm/timeline.cc b/runtime/vm/timeline.cc
index 609f66e..5e18589 100644
--- a/runtime/vm/timeline.cc
+++ b/runtime/vm/timeline.cc
@@ -230,6 +230,7 @@
   Timeline::stream_##name##_.set_enabled(false);
   TIMELINE_STREAM_LIST(TIMELINE_STREAM_DISABLE)
 #undef TIMELINE_STREAM_DISABLE
+  Timeline::Clear();
   delete recorder_;
   recorder_ = NULL;
   if (enabled_streams_ != NULL) {
@@ -1137,6 +1138,7 @@
 }
 
 TimelineEventFixedBufferRecorder::~TimelineEventFixedBufferRecorder() {
+  MutexLocker ml(&lock_);
   // Delete all blocks.
   for (intptr_t i = 0; i < num_blocks_; i++) {
     blocks_[i].Reset();
@@ -1333,16 +1335,7 @@
 TimelineEventEndlessRecorder::TimelineEventEndlessRecorder()
     : head_(nullptr), tail_(nullptr), block_index_(0) {}
 
-TimelineEventEndlessRecorder::~TimelineEventEndlessRecorder() {
-  TimelineEventBlock* current = head_;
-  head_ = tail_ = nullptr;
-
-  while (current != nullptr) {
-    TimelineEventBlock* next = current->next();
-    delete current;
-    current = next;
-  }
-}
+TimelineEventEndlessRecorder::~TimelineEventEndlessRecorder() {}
 
 #ifndef PRODUCT
 void TimelineEventEndlessRecorder::PrintJSON(JSONStream* js,
@@ -1424,6 +1417,7 @@
 #endif
 
 void TimelineEventEndlessRecorder::Clear() {
+  MutexLocker ml(&lock_);
   TimelineEventBlock* current = head_;
   while (current != NULL) {
     TimelineEventBlock* next = current->next();
@@ -1431,9 +1425,8 @@
     current = next;
   }
   head_ = NULL;
+  tail_ = NULL;
   block_index_ = 0;
-  OSThread* thread = OSThread::Current();
-  thread->set_timeline_block(NULL);
 }
 
 TimelineEventBlock::TimelineEventBlock(intptr_t block_index)
diff --git a/runtime/vm/timeline.h b/runtime/vm/timeline.h
index 38e739a..ce3def9 100644
--- a/runtime/vm/timeline.h
+++ b/runtime/vm/timeline.h
@@ -23,7 +23,7 @@
 #if defined(__MAC_10_14) || defined (__IPHONE_12_0)
 #define HOST_OS_SUPPORTS_SIGNPOST 1
 #endif
-//signpost.h exists in macOS 10.14, iOS 12 or above
+// signpost.h exists in macOS 10.14, iOS 12 or above
 #if defined(HOST_OS_SUPPORTS_SIGNPOST)
 #include <os/signpost.h>
 #else
@@ -166,6 +166,7 @@
   TIMELINE_STREAM_LIST(TIMELINE_STREAM_DECLARE)
 #undef TIMELINE_STREAM_DECLARE
 
+  template <class>
   friend class TimelineRecorderOverride;
   friend class ReclaimBlocksIsolateVisitor;
 };
diff --git a/runtime/vm/timeline_test.cc b/runtime/vm/timeline_test.cc
index 70d162e..ba04a0b 100644
--- a/runtime/vm/timeline_test.cc
+++ b/runtime/vm/timeline_test.cc
@@ -17,14 +17,25 @@
 
 #ifndef PRODUCT
 
+template <class T>
 class TimelineRecorderOverride : public ValueObject {
  public:
-  explicit TimelineRecorderOverride(TimelineEventRecorder* new_recorder)
-      : recorder_(Timeline::recorder()) {
-    Timeline::recorder_ = new_recorder;
+  TimelineRecorderOverride() : recorder_(Timeline::recorder()) {
+    Timeline::recorder_ = new T();
   }
 
-  ~TimelineRecorderOverride() { Timeline::recorder_ = recorder_; }
+  explicit TimelineRecorderOverride(T* recorder)
+      : recorder_(Timeline::recorder()) {
+    Timeline::recorder_ = recorder;
+  }
+
+  ~TimelineRecorderOverride() {
+    Timeline::Clear();
+    delete Timeline::recorder_;
+    Timeline::recorder_ = recorder_;
+  }
+
+  T* recorder() { return static_cast<T*>(Timeline::recorder()); }
 
  private:
   TimelineEventRecorder* recorder_;
@@ -90,11 +101,6 @@
     event->Complete();
   }
 
-  static void Clear(TimelineEventRecorder* recorder) {
-    ASSERT(recorder != NULL);
-    recorder->Clear();
-  }
-
   static void FinishBlock(TimelineEventBlock* block) { block->Finish(); }
 };
 
@@ -252,10 +258,9 @@
 }
 
 TEST_CASE(TimelineEventBufferPrintJSON) {
-  TimelineEventRecorder* recorder = Timeline::recorder();
   JSONStream js;
   TimelineEventFilter filter;
-  recorder->PrintJSON(&js, &filter);
+  Timeline::recorder()->PrintJSON(&js, &filter);
   // Check the type.
   EXPECT_SUBSTRING("\"type\":\"Timeline\"", js.ToCString());
   // Check that there is a traceEvents array.
@@ -282,13 +287,13 @@
 };
 
 TEST_CASE(TimelineEventCallbackRecorderBasic) {
-  EventCounterRecorder* recorder = new EventCounterRecorder();
-  TimelineRecorderOverride override(recorder);
+  TimelineRecorderOverride<EventCounterRecorder> override;
 
   // Initial counts are all zero.
   for (intptr_t i = TimelineEvent::kNone + 1; i < TimelineEvent::kNumEventTypes;
        i++) {
-    EXPECT_EQ(0, recorder->CountFor(static_cast<TimelineEvent::EventType>(i)));
+    EXPECT_EQ(0, override.recorder()->CountFor(
+                     static_cast<TimelineEvent::EventType>(i)));
   }
 
   // Create a test stream.
@@ -297,45 +302,43 @@
   TimelineEvent* event = NULL;
 
   event = stream.StartEvent();
-  EXPECT_EQ(0, recorder->CountFor(TimelineEvent::kDuration));
+  EXPECT_EQ(0, override.recorder()->CountFor(TimelineEvent::kDuration));
   event->DurationBegin("cabbage");
-  EXPECT_EQ(0, recorder->CountFor(TimelineEvent::kDuration));
+  EXPECT_EQ(0, override.recorder()->CountFor(TimelineEvent::kDuration));
   event->DurationEnd();
-  EXPECT_EQ(0, recorder->CountFor(TimelineEvent::kDuration));
+  EXPECT_EQ(0, override.recorder()->CountFor(TimelineEvent::kDuration));
   event->Complete();
-  EXPECT_EQ(1, recorder->CountFor(TimelineEvent::kDuration));
+  EXPECT_EQ(1, override.recorder()->CountFor(TimelineEvent::kDuration));
 
   event = stream.StartEvent();
-  EXPECT_EQ(0, recorder->CountFor(TimelineEvent::kInstant));
+  EXPECT_EQ(0, override.recorder()->CountFor(TimelineEvent::kInstant));
   event->Instant("instantCabbage");
-  EXPECT_EQ(0, recorder->CountFor(TimelineEvent::kInstant));
+  EXPECT_EQ(0, override.recorder()->CountFor(TimelineEvent::kInstant));
   event->Complete();
-  EXPECT_EQ(1, recorder->CountFor(TimelineEvent::kInstant));
+  EXPECT_EQ(1, override.recorder()->CountFor(TimelineEvent::kInstant));
 
   event = stream.StartEvent();
-  EXPECT_EQ(0, recorder->CountFor(TimelineEvent::kAsyncBegin));
-  int64_t async_id = recorder->GetNextAsyncId();
+  EXPECT_EQ(0, override.recorder()->CountFor(TimelineEvent::kAsyncBegin));
+  int64_t async_id = override.recorder()->GetNextAsyncId();
   EXPECT(async_id >= 0);
   event->AsyncBegin("asyncBeginCabbage", async_id);
-  EXPECT_EQ(0, recorder->CountFor(TimelineEvent::kAsyncBegin));
+  EXPECT_EQ(0, override.recorder()->CountFor(TimelineEvent::kAsyncBegin));
   event->Complete();
-  EXPECT_EQ(1, recorder->CountFor(TimelineEvent::kAsyncBegin));
+  EXPECT_EQ(1, override.recorder()->CountFor(TimelineEvent::kAsyncBegin));
 
   event = stream.StartEvent();
-  EXPECT_EQ(0, recorder->CountFor(TimelineEvent::kAsyncInstant));
+  EXPECT_EQ(0, override.recorder()->CountFor(TimelineEvent::kAsyncInstant));
   event->AsyncInstant("asyncInstantCabbage", async_id);
-  EXPECT_EQ(0, recorder->CountFor(TimelineEvent::kAsyncInstant));
+  EXPECT_EQ(0, override.recorder()->CountFor(TimelineEvent::kAsyncInstant));
   event->Complete();
-  EXPECT_EQ(1, recorder->CountFor(TimelineEvent::kAsyncInstant));
+  EXPECT_EQ(1, override.recorder()->CountFor(TimelineEvent::kAsyncInstant));
 
   event = stream.StartEvent();
-  EXPECT_EQ(0, recorder->CountFor(TimelineEvent::kAsyncEnd));
+  EXPECT_EQ(0, override.recorder()->CountFor(TimelineEvent::kAsyncEnd));
   event->AsyncEnd("asyncEndCabbage", async_id);
-  EXPECT_EQ(0, recorder->CountFor(TimelineEvent::kAsyncEnd));
+  EXPECT_EQ(0, override.recorder()->CountFor(TimelineEvent::kAsyncEnd));
   event->Complete();
-  EXPECT_EQ(1, recorder->CountFor(TimelineEvent::kAsyncEnd));
-
-  delete recorder;
+  EXPECT_EQ(1, override.recorder()->CountFor(TimelineEvent::kAsyncEnd));
 }
 
 static bool LabelMatch(TimelineEvent* event, const char* label) {
@@ -344,20 +347,20 @@
 }
 
 TEST_CASE(TimelineAnalysis_ThreadBlockCount) {
-  TimelineEventEndlessRecorder* recorder = new TimelineEventEndlessRecorder();
-  ASSERT(recorder != NULL);
+  TimelineRecorderOverride<TimelineEventEndlessRecorder> override;
+  ASSERT(Timeline::recorder() != NULL);
   // Blocks owned by thread "1".
-  TimelineEventBlock* block_1_0 = recorder->GetNewBlock();
+  TimelineEventBlock* block_1_0 = Timeline::recorder()->GetNewBlock();
   TimelineTestHelper::SetBlockThread(block_1_0, 1);
-  TimelineEventBlock* block_1_1 = recorder->GetNewBlock();
+  TimelineEventBlock* block_1_1 = Timeline::recorder()->GetNewBlock();
   TimelineTestHelper::SetBlockThread(block_1_1, 1);
-  TimelineEventBlock* block_1_2 = recorder->GetNewBlock();
+  TimelineEventBlock* block_1_2 = Timeline::recorder()->GetNewBlock();
   TimelineTestHelper::SetBlockThread(block_1_2, 1);
   // Blocks owned by thread "2".
-  TimelineEventBlock* block_2_0 = recorder->GetNewBlock();
+  TimelineEventBlock* block_2_0 = Timeline::recorder()->GetNewBlock();
   TimelineTestHelper::SetBlockThread(block_2_0, 2);
   // Blocks owned by thread "3".
-  TimelineEventBlock* block_3_0 = recorder->GetNewBlock();
+  TimelineEventBlock* block_3_0 = Timeline::recorder()->GetNewBlock();
   TimelineTestHelper::SetBlockThread(block_3_0, 3);
   USE(block_3_0);
 
@@ -384,8 +387,8 @@
   Zone* zone = thread->zone();
   Isolate* isolate = thread->isolate();
 
-  // Discover threads in recorder.
-  TimelineAnalysis ta(zone, isolate, recorder);
+  // Discover threads in Timeline::recorder().
+  TimelineAnalysis ta(zone, isolate, Timeline::recorder());
   ta.BuildThreads();
   EXPECT(!ta.has_error());
   // block_3_0 is never used by a thread, so we only have two threads.
@@ -457,9 +460,6 @@
     EXPECT(LabelMatch(it.Next(), "F"));
     EXPECT(!it.HasNext());
   }
-
-  TimelineTestHelper::Clear(recorder);
-  delete recorder;
 }
 
 TEST_CASE(TimelineRingRecorderJSONOrder) {
@@ -467,13 +467,14 @@
 
   TimelineEventRingRecorder* recorder =
       new TimelineEventRingRecorder(TimelineEventBlock::kBlockSize * 2);
+  TimelineRecorderOverride<TimelineEventRingRecorder> override(recorder);
 
-  TimelineEventBlock* block_0 = recorder->GetNewBlock();
+  TimelineEventBlock* block_0 = Timeline::recorder()->GetNewBlock();
   EXPECT(block_0 != NULL);
-  TimelineEventBlock* block_1 = recorder->GetNewBlock();
+  TimelineEventBlock* block_1 = Timeline::recorder()->GetNewBlock();
   EXPECT(block_1 != NULL);
   // Test that we wrapped.
-  EXPECT(block_0 == recorder->GetNewBlock());
+  EXPECT(block_0 == Timeline::recorder()->GetNewBlock());
 
   // Emit the earlier event into block_1.
   TimelineTestHelper::FakeThreadEvent(block_1, 2, "Alpha", &stream);
@@ -486,7 +487,7 @@
 
   JSONStream js;
   TimelineEventFilter filter;
-  recorder->PrintJSON(&js, &filter);
+  Timeline::recorder()->PrintJSON(&js, &filter);
   // trace-event has a requirement that events for a thread must have
   // monotonically increasing timestamps.
   // Verify that "Alpha" comes before "Beta" even though "Beta" is in the first
@@ -494,393 +495,426 @@
   const char* alpha = strstr(js.ToCString(), "Alpha");
   const char* beta = strstr(js.ToCString(), "Beta");
   EXPECT(alpha < beta);
-
-  TimelineTestHelper::Clear(recorder);
-  delete recorder;
 }
 
 TEST_CASE(TimelinePauses_Basic) {
-  TimelineEventEndlessRecorder* recorder = new TimelineEventEndlessRecorder();
-  ASSERT(recorder != NULL);
   Zone* zone = thread->zone();
   Isolate* isolate = thread->isolate();
   OSThread* os_thread = thread->os_thread();
   ASSERT(os_thread != NULL);
   ThreadId tid = os_thread->trace_id();
 
-  // Test case.
-  TimelineTestHelper::FakeDuration(recorder, "a", 0, 10);
   {
-    TimelinePauses pauses(zone, isolate, recorder);
-    pauses.Setup();
-    pauses.CalculatePauseTimesForThread(tid);
-    EXPECT(!pauses.has_error());
-    EXPECT_EQ(10, pauses.InclusiveTime("a"));
-    EXPECT_EQ(10, pauses.ExclusiveTime("a"));
-    EXPECT_EQ(10, pauses.MaxInclusiveTime("a"));
-    EXPECT_EQ(10, pauses.MaxExclusiveTime("a"));
+    TimelineRecorderOverride<TimelineEventEndlessRecorder> override;
+    // Test case.
+    TimelineTestHelper::FakeDuration(Timeline::recorder(), "a", 0, 10);
+    {
+      TimelinePauses pauses(zone, isolate, Timeline::recorder());
+      pauses.Setup();
+      pauses.CalculatePauseTimesForThread(tid);
+      EXPECT(!pauses.has_error());
+      EXPECT_EQ(10, pauses.InclusiveTime("a"));
+      EXPECT_EQ(10, pauses.ExclusiveTime("a"));
+      EXPECT_EQ(10, pauses.MaxInclusiveTime("a"));
+      EXPECT_EQ(10, pauses.MaxExclusiveTime("a"));
+    }
   }
-  TimelineTestHelper::Clear(recorder);
-
-  // Test case.
-  TimelineTestHelper::FakeDuration(recorder, "a", 0, 10);
-  TimelineTestHelper::FakeDuration(recorder, "b", 0, 10);
-  {
-    TimelinePauses pauses(zone, isolate, recorder);
-    pauses.Setup();
-    pauses.CalculatePauseTimesForThread(tid);
-    EXPECT(!pauses.has_error());
-    EXPECT_EQ(10, pauses.InclusiveTime("a"));
-    EXPECT_EQ(0, pauses.ExclusiveTime("a"));
-    EXPECT_EQ(10, pauses.MaxInclusiveTime("a"));
-    EXPECT_EQ(0, pauses.MaxExclusiveTime("a"));
-    EXPECT_EQ(10, pauses.InclusiveTime("b"));
-    EXPECT_EQ(10, pauses.ExclusiveTime("b"));
-    EXPECT_EQ(10, pauses.MaxInclusiveTime("b"));
-    EXPECT_EQ(10, pauses.MaxExclusiveTime("b"));
-  }
-  TimelineTestHelper::Clear(recorder);
-
-  // Test case.
-  TimelineTestHelper::FakeDuration(recorder, "a", 0, 10);
-  TimelineTestHelper::FakeDuration(recorder, "b", 1, 8);
-  {
-    TimelinePauses pauses(zone, isolate, recorder);
-    pauses.Setup();
-    pauses.CalculatePauseTimesForThread(tid);
-    EXPECT(!pauses.has_error());
-    EXPECT_EQ(10, pauses.InclusiveTime("a"));
-    EXPECT_EQ(3, pauses.ExclusiveTime("a"));
-    EXPECT_EQ(10, pauses.MaxInclusiveTime("a"));
-    EXPECT_EQ(3, pauses.MaxExclusiveTime("a"));
-    EXPECT_EQ(7, pauses.InclusiveTime("b"));
-    EXPECT_EQ(7, pauses.ExclusiveTime("b"));
-    EXPECT_EQ(7, pauses.MaxInclusiveTime("b"));
-    EXPECT_EQ(7, pauses.MaxExclusiveTime("b"));
-  }
-  TimelineTestHelper::Clear(recorder);
-
-  // Test case.
-  TimelineTestHelper::FakeDuration(recorder, "a", 0, 10);
-  TimelineTestHelper::FakeDuration(recorder, "b", 0, 1);
-  TimelineTestHelper::FakeDuration(recorder, "b", 1, 2);
-  TimelineTestHelper::FakeDuration(recorder, "b", 2, 3);
-  TimelineTestHelper::FakeDuration(recorder, "b", 3, 4);
-  TimelineTestHelper::FakeDuration(recorder, "b", 4, 5);
-  TimelineTestHelper::FakeDuration(recorder, "b", 5, 6);
-  TimelineTestHelper::FakeDuration(recorder, "b", 6, 7);
-  TimelineTestHelper::FakeDuration(recorder, "b", 7, 8);
-  TimelineTestHelper::FakeDuration(recorder, "b", 8, 9);
-  TimelineTestHelper::FakeDuration(recorder, "b", 9, 10);
-  {
-    TimelinePauses pauses(zone, isolate, recorder);
-    pauses.Setup();
-    pauses.CalculatePauseTimesForThread(tid);
-    EXPECT(!pauses.has_error());
-    EXPECT_EQ(10, pauses.InclusiveTime("a"));
-    EXPECT_EQ(0, pauses.ExclusiveTime("a"));
-    EXPECT_EQ(10, pauses.MaxInclusiveTime("a"));
-    EXPECT_EQ(0, pauses.MaxExclusiveTime("a"));
-    EXPECT_EQ(10, pauses.InclusiveTime("b"));
-    EXPECT_EQ(10, pauses.ExclusiveTime("b"));
-    EXPECT_EQ(1, pauses.MaxInclusiveTime("b"));
-    EXPECT_EQ(1, pauses.MaxExclusiveTime("b"));
-  }
-  TimelineTestHelper::Clear(recorder);
-
-  // Test case.
-  TimelineTestHelper::FakeDuration(recorder, "a", 0, 10);
-  TimelineTestHelper::FakeDuration(recorder, "b", 0, 5);
-  TimelineTestHelper::FakeDuration(recorder, "c", 1, 4);
-  TimelineTestHelper::FakeDuration(recorder, "d", 5, 10);
 
   {
-    TimelinePauses pauses(zone, isolate, recorder);
-    pauses.Setup();
-    pauses.CalculatePauseTimesForThread(tid);
-    EXPECT(!pauses.has_error());
-    EXPECT_EQ(10, pauses.InclusiveTime("a"));
-    EXPECT_EQ(0, pauses.ExclusiveTime("a"));
-    EXPECT_EQ(10, pauses.MaxInclusiveTime("a"));
-    EXPECT_EQ(0, pauses.MaxExclusiveTime("a"));
-    EXPECT_EQ(5, pauses.InclusiveTime("b"));
-    EXPECT_EQ(2, pauses.ExclusiveTime("b"));
-    EXPECT_EQ(5, pauses.MaxInclusiveTime("b"));
-    EXPECT_EQ(2, pauses.MaxExclusiveTime("b"));
-    EXPECT_EQ(3, pauses.InclusiveTime("c"));
-    EXPECT_EQ(3, pauses.ExclusiveTime("c"));
-    EXPECT_EQ(3, pauses.MaxInclusiveTime("c"));
-    EXPECT_EQ(3, pauses.MaxExclusiveTime("c"));
-    EXPECT_EQ(5, pauses.InclusiveTime("d"));
-    EXPECT_EQ(5, pauses.ExclusiveTime("d"));
-    EXPECT_EQ(5, pauses.MaxInclusiveTime("d"));
-    EXPECT_EQ(5, pauses.MaxExclusiveTime("d"));
-  }
-  TimelineTestHelper::Clear(recorder);
+    TimelineRecorderOverride<TimelineEventEndlessRecorder> override;
 
-  // Test case.
-  TimelineTestHelper::FakeDuration(recorder, "a", 0, 10);
-  TimelineTestHelper::FakeDuration(recorder, "b", 1, 9);
-  TimelineTestHelper::FakeDuration(recorder, "c", 2, 8);
-  TimelineTestHelper::FakeDuration(recorder, "d", 3, 7);
-  TimelineTestHelper::FakeDuration(recorder, "e", 4, 6);
+    // Test case.
+    TimelineTestHelper::FakeDuration(Timeline::recorder(), "a", 0, 10);
+    TimelineTestHelper::FakeDuration(Timeline::recorder(), "b", 0, 10);
+    {
+      TimelinePauses pauses(zone, isolate, Timeline::recorder());
+      pauses.Setup();
+      pauses.CalculatePauseTimesForThread(tid);
+      EXPECT(!pauses.has_error());
+      EXPECT_EQ(10, pauses.InclusiveTime("a"));
+      EXPECT_EQ(0, pauses.ExclusiveTime("a"));
+      EXPECT_EQ(10, pauses.MaxInclusiveTime("a"));
+      EXPECT_EQ(0, pauses.MaxExclusiveTime("a"));
+      EXPECT_EQ(10, pauses.InclusiveTime("b"));
+      EXPECT_EQ(10, pauses.ExclusiveTime("b"));
+      EXPECT_EQ(10, pauses.MaxInclusiveTime("b"));
+      EXPECT_EQ(10, pauses.MaxExclusiveTime("b"));
+    }
+  }
 
   {
-    TimelinePauses pauses(zone, isolate, recorder);
-    pauses.Setup();
-    pauses.CalculatePauseTimesForThread(tid);
-    EXPECT(!pauses.has_error());
-    EXPECT_EQ(10, pauses.InclusiveTime("a"));
-    EXPECT_EQ(2, pauses.ExclusiveTime("a"));
-    EXPECT_EQ(10, pauses.MaxInclusiveTime("a"));
-    EXPECT_EQ(2, pauses.MaxExclusiveTime("a"));
-    EXPECT_EQ(8, pauses.InclusiveTime("b"));
-    EXPECT_EQ(2, pauses.ExclusiveTime("b"));
-    EXPECT_EQ(8, pauses.MaxInclusiveTime("b"));
-    EXPECT_EQ(2, pauses.MaxExclusiveTime("b"));
-    EXPECT_EQ(6, pauses.InclusiveTime("c"));
-    EXPECT_EQ(2, pauses.ExclusiveTime("c"));
-    EXPECT_EQ(6, pauses.MaxInclusiveTime("c"));
-    EXPECT_EQ(2, pauses.MaxExclusiveTime("c"));
-    EXPECT_EQ(4, pauses.InclusiveTime("d"));
-    EXPECT_EQ(2, pauses.ExclusiveTime("d"));
-    EXPECT_EQ(4, pauses.MaxInclusiveTime("d"));
-    EXPECT_EQ(2, pauses.MaxExclusiveTime("d"));
-    EXPECT_EQ(2, pauses.InclusiveTime("e"));
-    EXPECT_EQ(2, pauses.ExclusiveTime("e"));
-    EXPECT_EQ(2, pauses.MaxInclusiveTime("e"));
-    EXPECT_EQ(2, pauses.MaxExclusiveTime("e"));
-  }
-  TimelineTestHelper::Clear(recorder);
+    TimelineRecorderOverride<TimelineEventEndlessRecorder> override;
 
-  // Test case.
-  TimelineTestHelper::FakeDuration(recorder, "a", 0, 10);
-  TimelineTestHelper::FakeDuration(recorder, "a", 1, 9);
+    // Test case.
+    TimelineTestHelper::FakeDuration(Timeline::recorder(), "a", 0, 10);
+    TimelineTestHelper::FakeDuration(Timeline::recorder(), "b", 1, 8);
+    {
+      TimelinePauses pauses(zone, isolate, Timeline::recorder());
+      pauses.Setup();
+      pauses.CalculatePauseTimesForThread(tid);
+      EXPECT(!pauses.has_error());
+      EXPECT_EQ(10, pauses.InclusiveTime("a"));
+      EXPECT_EQ(3, pauses.ExclusiveTime("a"));
+      EXPECT_EQ(10, pauses.MaxInclusiveTime("a"));
+      EXPECT_EQ(3, pauses.MaxExclusiveTime("a"));
+      EXPECT_EQ(7, pauses.InclusiveTime("b"));
+      EXPECT_EQ(7, pauses.ExclusiveTime("b"));
+      EXPECT_EQ(7, pauses.MaxInclusiveTime("b"));
+      EXPECT_EQ(7, pauses.MaxExclusiveTime("b"));
+    }
+  }
 
   {
-    TimelinePauses pauses(zone, isolate, recorder);
-    pauses.Setup();
-    pauses.CalculatePauseTimesForThread(tid);
-    EXPECT(!pauses.has_error());
-    EXPECT_EQ(10, pauses.InclusiveTime("a"));
-    EXPECT_EQ(10, pauses.ExclusiveTime("a"));
-    EXPECT_EQ(10, pauses.MaxInclusiveTime("a"));
-    EXPECT_EQ(8, pauses.MaxExclusiveTime("a"));
-  }
-  TimelineTestHelper::Clear(recorder);
+    TimelineRecorderOverride<TimelineEventEndlessRecorder> override;
 
-  delete recorder;
+    // Test case.
+    TimelineTestHelper::FakeDuration(Timeline::recorder(), "a", 0, 10);
+    TimelineTestHelper::FakeDuration(Timeline::recorder(), "b", 0, 1);
+    TimelineTestHelper::FakeDuration(Timeline::recorder(), "b", 1, 2);
+    TimelineTestHelper::FakeDuration(Timeline::recorder(), "b", 2, 3);
+    TimelineTestHelper::FakeDuration(Timeline::recorder(), "b", 3, 4);
+    TimelineTestHelper::FakeDuration(Timeline::recorder(), "b", 4, 5);
+    TimelineTestHelper::FakeDuration(Timeline::recorder(), "b", 5, 6);
+    TimelineTestHelper::FakeDuration(Timeline::recorder(), "b", 6, 7);
+    TimelineTestHelper::FakeDuration(Timeline::recorder(), "b", 7, 8);
+    TimelineTestHelper::FakeDuration(Timeline::recorder(), "b", 8, 9);
+    TimelineTestHelper::FakeDuration(Timeline::recorder(), "b", 9, 10);
+    {
+      TimelinePauses pauses(zone, isolate, Timeline::recorder());
+      pauses.Setup();
+      pauses.CalculatePauseTimesForThread(tid);
+      EXPECT(!pauses.has_error());
+      EXPECT_EQ(10, pauses.InclusiveTime("a"));
+      EXPECT_EQ(0, pauses.ExclusiveTime("a"));
+      EXPECT_EQ(10, pauses.MaxInclusiveTime("a"));
+      EXPECT_EQ(0, pauses.MaxExclusiveTime("a"));
+      EXPECT_EQ(10, pauses.InclusiveTime("b"));
+      EXPECT_EQ(10, pauses.ExclusiveTime("b"));
+      EXPECT_EQ(1, pauses.MaxInclusiveTime("b"));
+      EXPECT_EQ(1, pauses.MaxExclusiveTime("b"));
+    }
+  }
+
+  {
+    TimelineRecorderOverride<TimelineEventEndlessRecorder> override;
+
+    // Test case.
+    TimelineTestHelper::FakeDuration(Timeline::recorder(), "a", 0, 10);
+    TimelineTestHelper::FakeDuration(Timeline::recorder(), "b", 0, 5);
+    TimelineTestHelper::FakeDuration(Timeline::recorder(), "c", 1, 4);
+    TimelineTestHelper::FakeDuration(Timeline::recorder(), "d", 5, 10);
+
+    {
+      TimelinePauses pauses(zone, isolate, Timeline::recorder());
+      pauses.Setup();
+      pauses.CalculatePauseTimesForThread(tid);
+      EXPECT(!pauses.has_error());
+      EXPECT_EQ(10, pauses.InclusiveTime("a"));
+      EXPECT_EQ(0, pauses.ExclusiveTime("a"));
+      EXPECT_EQ(10, pauses.MaxInclusiveTime("a"));
+      EXPECT_EQ(0, pauses.MaxExclusiveTime("a"));
+      EXPECT_EQ(5, pauses.InclusiveTime("b"));
+      EXPECT_EQ(2, pauses.ExclusiveTime("b"));
+      EXPECT_EQ(5, pauses.MaxInclusiveTime("b"));
+      EXPECT_EQ(2, pauses.MaxExclusiveTime("b"));
+      EXPECT_EQ(3, pauses.InclusiveTime("c"));
+      EXPECT_EQ(3, pauses.ExclusiveTime("c"));
+      EXPECT_EQ(3, pauses.MaxInclusiveTime("c"));
+      EXPECT_EQ(3, pauses.MaxExclusiveTime("c"));
+      EXPECT_EQ(5, pauses.InclusiveTime("d"));
+      EXPECT_EQ(5, pauses.ExclusiveTime("d"));
+      EXPECT_EQ(5, pauses.MaxInclusiveTime("d"));
+      EXPECT_EQ(5, pauses.MaxExclusiveTime("d"));
+    }
+  }
+
+  {
+    TimelineRecorderOverride<TimelineEventEndlessRecorder> override;
+
+    // Test case.
+    TimelineTestHelper::FakeDuration(Timeline::recorder(), "a", 0, 10);
+    TimelineTestHelper::FakeDuration(Timeline::recorder(), "b", 1, 9);
+    TimelineTestHelper::FakeDuration(Timeline::recorder(), "c", 2, 8);
+    TimelineTestHelper::FakeDuration(Timeline::recorder(), "d", 3, 7);
+    TimelineTestHelper::FakeDuration(Timeline::recorder(), "e", 4, 6);
+
+    {
+      TimelinePauses pauses(zone, isolate, Timeline::recorder());
+      pauses.Setup();
+      pauses.CalculatePauseTimesForThread(tid);
+      EXPECT(!pauses.has_error());
+      EXPECT_EQ(10, pauses.InclusiveTime("a"));
+      EXPECT_EQ(2, pauses.ExclusiveTime("a"));
+      EXPECT_EQ(10, pauses.MaxInclusiveTime("a"));
+      EXPECT_EQ(2, pauses.MaxExclusiveTime("a"));
+      EXPECT_EQ(8, pauses.InclusiveTime("b"));
+      EXPECT_EQ(2, pauses.ExclusiveTime("b"));
+      EXPECT_EQ(8, pauses.MaxInclusiveTime("b"));
+      EXPECT_EQ(2, pauses.MaxExclusiveTime("b"));
+      EXPECT_EQ(6, pauses.InclusiveTime("c"));
+      EXPECT_EQ(2, pauses.ExclusiveTime("c"));
+      EXPECT_EQ(6, pauses.MaxInclusiveTime("c"));
+      EXPECT_EQ(2, pauses.MaxExclusiveTime("c"));
+      EXPECT_EQ(4, pauses.InclusiveTime("d"));
+      EXPECT_EQ(2, pauses.ExclusiveTime("d"));
+      EXPECT_EQ(4, pauses.MaxInclusiveTime("d"));
+      EXPECT_EQ(2, pauses.MaxExclusiveTime("d"));
+      EXPECT_EQ(2, pauses.InclusiveTime("e"));
+      EXPECT_EQ(2, pauses.ExclusiveTime("e"));
+      EXPECT_EQ(2, pauses.MaxInclusiveTime("e"));
+      EXPECT_EQ(2, pauses.MaxExclusiveTime("e"));
+    }
+  }
+
+  {
+    TimelineRecorderOverride<TimelineEventEndlessRecorder> override;
+
+    // Test case.
+    TimelineTestHelper::FakeDuration(Timeline::recorder(), "a", 0, 10);
+    TimelineTestHelper::FakeDuration(Timeline::recorder(), "a", 1, 9);
+
+    {
+      TimelinePauses pauses(zone, isolate, Timeline::recorder());
+      pauses.Setup();
+      pauses.CalculatePauseTimesForThread(tid);
+      EXPECT(!pauses.has_error());
+      EXPECT_EQ(10, pauses.InclusiveTime("a"));
+      EXPECT_EQ(10, pauses.ExclusiveTime("a"));
+      EXPECT_EQ(10, pauses.MaxInclusiveTime("a"));
+      EXPECT_EQ(8, pauses.MaxExclusiveTime("a"));
+    }
+  }
 }
 
 TEST_CASE(TimelinePauses_BeginEnd) {
-  TimelineEventEndlessRecorder* recorder = new TimelineEventEndlessRecorder();
-  ASSERT(recorder != NULL);
   Zone* zone = thread->zone();
   Isolate* isolate = thread->isolate();
   OSThread* os_thread = thread->os_thread();
   ASSERT(os_thread != NULL);
   ThreadId tid = os_thread->trace_id();
 
-  // Test case.
-  TimelineTestHelper::FakeBegin(recorder, "a", 0);
-  TimelineTestHelper::FakeEnd(recorder, "a", 10);
+  {
+    TimelineRecorderOverride<TimelineEventEndlessRecorder> override;
+
+    // Test case.
+    TimelineTestHelper::FakeBegin(Timeline::recorder(), "a", 0);
+    TimelineTestHelper::FakeEnd(Timeline::recorder(), "a", 10);
+
+    {
+      TimelinePauses pauses(zone, isolate, Timeline::recorder());
+      pauses.Setup();
+      pauses.CalculatePauseTimesForThread(tid);
+      EXPECT(!pauses.has_error());
+      EXPECT_EQ(10, pauses.InclusiveTime("a"));
+      EXPECT_EQ(10, pauses.ExclusiveTime("a"));
+      EXPECT_EQ(10, pauses.MaxInclusiveTime("a"));
+      EXPECT_EQ(10, pauses.MaxExclusiveTime("a"));
+    }
+  }
 
   {
-    TimelinePauses pauses(zone, isolate, recorder);
-    pauses.Setup();
-    pauses.CalculatePauseTimesForThread(tid);
-    EXPECT(!pauses.has_error());
-    EXPECT_EQ(10, pauses.InclusiveTime("a"));
-    EXPECT_EQ(10, pauses.ExclusiveTime("a"));
-    EXPECT_EQ(10, pauses.MaxInclusiveTime("a"));
-    EXPECT_EQ(10, pauses.MaxExclusiveTime("a"));
-  }
-  TimelineTestHelper::Clear(recorder);
+    TimelineRecorderOverride<TimelineEventEndlessRecorder> override;
 
-  // Test case.
-  TimelineTestHelper::FakeBegin(recorder, "a", 0);
-  TimelineTestHelper::FakeBegin(recorder, "b", 0);
-  TimelineTestHelper::FakeEnd(recorder, "b", 10);
-  TimelineTestHelper::FakeEnd(recorder, "a", 10);
+    // Test case.
+    TimelineTestHelper::FakeBegin(Timeline::recorder(), "a", 0);
+    TimelineTestHelper::FakeBegin(Timeline::recorder(), "b", 0);
+    TimelineTestHelper::FakeEnd(Timeline::recorder(), "b", 10);
+    TimelineTestHelper::FakeEnd(Timeline::recorder(), "a", 10);
+
+    {
+      TimelinePauses pauses(zone, isolate, Timeline::recorder());
+      pauses.Setup();
+      pauses.CalculatePauseTimesForThread(tid);
+      EXPECT(!pauses.has_error());
+      EXPECT_EQ(10, pauses.InclusiveTime("a"));
+      EXPECT_EQ(0, pauses.ExclusiveTime("a"));
+      EXPECT_EQ(10, pauses.MaxInclusiveTime("a"));
+      EXPECT_EQ(0, pauses.MaxExclusiveTime("a"));
+      EXPECT_EQ(10, pauses.InclusiveTime("b"));
+      EXPECT_EQ(10, pauses.ExclusiveTime("b"));
+      EXPECT_EQ(10, pauses.MaxInclusiveTime("b"));
+      EXPECT_EQ(10, pauses.MaxExclusiveTime("b"));
+    }
+  }
 
   {
-    TimelinePauses pauses(zone, isolate, recorder);
-    pauses.Setup();
-    pauses.CalculatePauseTimesForThread(tid);
-    EXPECT(!pauses.has_error());
-    EXPECT_EQ(10, pauses.InclusiveTime("a"));
-    EXPECT_EQ(0, pauses.ExclusiveTime("a"));
-    EXPECT_EQ(10, pauses.MaxInclusiveTime("a"));
-    EXPECT_EQ(0, pauses.MaxExclusiveTime("a"));
-    EXPECT_EQ(10, pauses.InclusiveTime("b"));
-    EXPECT_EQ(10, pauses.ExclusiveTime("b"));
-    EXPECT_EQ(10, pauses.MaxInclusiveTime("b"));
-    EXPECT_EQ(10, pauses.MaxExclusiveTime("b"));
-  }
-  TimelineTestHelper::Clear(recorder);
+    TimelineRecorderOverride<TimelineEventEndlessRecorder> override;
 
-  // Test case.
-  TimelineTestHelper::FakeBegin(recorder, "a", 0);
-  TimelineTestHelper::FakeBegin(recorder, "b", 1);
-  TimelineTestHelper::FakeEnd(recorder, "b", 8);
-  TimelineTestHelper::FakeEnd(recorder, "a", 10);
+    // Test case.
+    TimelineTestHelper::FakeBegin(Timeline::recorder(), "a", 0);
+    TimelineTestHelper::FakeBegin(Timeline::recorder(), "b", 1);
+    TimelineTestHelper::FakeEnd(Timeline::recorder(), "b", 8);
+    TimelineTestHelper::FakeEnd(Timeline::recorder(), "a", 10);
+
+    {
+      TimelinePauses pauses(zone, isolate, Timeline::recorder());
+      pauses.Setup();
+      pauses.CalculatePauseTimesForThread(tid);
+      EXPECT(!pauses.has_error());
+      EXPECT_EQ(10, pauses.InclusiveTime("a"));
+      EXPECT_EQ(3, pauses.ExclusiveTime("a"));
+      EXPECT_EQ(10, pauses.MaxInclusiveTime("a"));
+      EXPECT_EQ(3, pauses.MaxExclusiveTime("a"));
+      EXPECT_EQ(7, pauses.InclusiveTime("b"));
+      EXPECT_EQ(7, pauses.ExclusiveTime("b"));
+      EXPECT_EQ(7, pauses.MaxInclusiveTime("b"));
+      EXPECT_EQ(7, pauses.MaxExclusiveTime("b"));
+    }
+  }
 
   {
-    TimelinePauses pauses(zone, isolate, recorder);
-    pauses.Setup();
-    pauses.CalculatePauseTimesForThread(tid);
-    EXPECT(!pauses.has_error());
-    EXPECT_EQ(10, pauses.InclusiveTime("a"));
-    EXPECT_EQ(3, pauses.ExclusiveTime("a"));
-    EXPECT_EQ(10, pauses.MaxInclusiveTime("a"));
-    EXPECT_EQ(3, pauses.MaxExclusiveTime("a"));
-    EXPECT_EQ(7, pauses.InclusiveTime("b"));
-    EXPECT_EQ(7, pauses.ExclusiveTime("b"));
-    EXPECT_EQ(7, pauses.MaxInclusiveTime("b"));
-    EXPECT_EQ(7, pauses.MaxExclusiveTime("b"));
-  }
-  TimelineTestHelper::Clear(recorder);
+    TimelineRecorderOverride<TimelineEventEndlessRecorder> override;
 
-  // Test case.
-  TimelineTestHelper::FakeBegin(recorder, "a", 0);
-  TimelineTestHelper::FakeDuration(recorder, "b", 0, 1);
-  TimelineTestHelper::FakeDuration(recorder, "b", 1, 2);
-  TimelineTestHelper::FakeDuration(recorder, "b", 2, 3);
-  TimelineTestHelper::FakeBegin(recorder, "b", 3);
-  TimelineTestHelper::FakeEnd(recorder, "b", 4);
-  TimelineTestHelper::FakeDuration(recorder, "b", 4, 5);
-  TimelineTestHelper::FakeDuration(recorder, "b", 5, 6);
-  TimelineTestHelper::FakeDuration(recorder, "b", 6, 7);
-  TimelineTestHelper::FakeBegin(recorder, "b", 7);
-  TimelineTestHelper::FakeEnd(recorder, "b", 8);
-  TimelineTestHelper::FakeBegin(recorder, "b", 8);
-  TimelineTestHelper::FakeEnd(recorder, "b", 9);
-  TimelineTestHelper::FakeDuration(recorder, "b", 9, 10);
-  TimelineTestHelper::FakeEnd(recorder, "a", 10);
+    // Test case.
+    TimelineTestHelper::FakeBegin(Timeline::recorder(), "a", 0);
+    TimelineTestHelper::FakeDuration(Timeline::recorder(), "b", 0, 1);
+    TimelineTestHelper::FakeDuration(Timeline::recorder(), "b", 1, 2);
+    TimelineTestHelper::FakeDuration(Timeline::recorder(), "b", 2, 3);
+    TimelineTestHelper::FakeBegin(Timeline::recorder(), "b", 3);
+    TimelineTestHelper::FakeEnd(Timeline::recorder(), "b", 4);
+    TimelineTestHelper::FakeDuration(Timeline::recorder(), "b", 4, 5);
+    TimelineTestHelper::FakeDuration(Timeline::recorder(), "b", 5, 6);
+    TimelineTestHelper::FakeDuration(Timeline::recorder(), "b", 6, 7);
+    TimelineTestHelper::FakeBegin(Timeline::recorder(), "b", 7);
+    TimelineTestHelper::FakeEnd(Timeline::recorder(), "b", 8);
+    TimelineTestHelper::FakeBegin(Timeline::recorder(), "b", 8);
+    TimelineTestHelper::FakeEnd(Timeline::recorder(), "b", 9);
+    TimelineTestHelper::FakeDuration(Timeline::recorder(), "b", 9, 10);
+    TimelineTestHelper::FakeEnd(Timeline::recorder(), "a", 10);
+
+    {
+      TimelinePauses pauses(zone, isolate, Timeline::recorder());
+      pauses.Setup();
+      pauses.CalculatePauseTimesForThread(tid);
+      EXPECT(!pauses.has_error());
+      EXPECT_EQ(10, pauses.InclusiveTime("a"));
+      EXPECT_EQ(0, pauses.ExclusiveTime("a"));
+      EXPECT_EQ(10, pauses.MaxInclusiveTime("a"));
+      EXPECT_EQ(0, pauses.MaxExclusiveTime("a"));
+      EXPECT_EQ(10, pauses.InclusiveTime("b"));
+      EXPECT_EQ(10, pauses.ExclusiveTime("b"));
+      EXPECT_EQ(1, pauses.MaxInclusiveTime("b"));
+      EXPECT_EQ(1, pauses.MaxExclusiveTime("b"));
+    }
+  }
 
   {
-    TimelinePauses pauses(zone, isolate, recorder);
-    pauses.Setup();
-    pauses.CalculatePauseTimesForThread(tid);
-    EXPECT(!pauses.has_error());
-    EXPECT_EQ(10, pauses.InclusiveTime("a"));
-    EXPECT_EQ(0, pauses.ExclusiveTime("a"));
-    EXPECT_EQ(10, pauses.MaxInclusiveTime("a"));
-    EXPECT_EQ(0, pauses.MaxExclusiveTime("a"));
-    EXPECT_EQ(10, pauses.InclusiveTime("b"));
-    EXPECT_EQ(10, pauses.ExclusiveTime("b"));
-    EXPECT_EQ(1, pauses.MaxInclusiveTime("b"));
-    EXPECT_EQ(1, pauses.MaxExclusiveTime("b"));
-  }
-  TimelineTestHelper::Clear(recorder);
+    TimelineRecorderOverride<TimelineEventEndlessRecorder> override;
 
-  // Test case.
-  TimelineTestHelper::FakeBegin(recorder, "a", 0);
-  TimelineTestHelper::FakeBegin(recorder, "b", 0);
-  TimelineTestHelper::FakeBegin(recorder, "c", 1);
-  TimelineTestHelper::FakeEnd(recorder, "c", 4);
-  TimelineTestHelper::FakeEnd(recorder, "b", 5);
-  TimelineTestHelper::FakeBegin(recorder, "d", 5);
-  TimelineTestHelper::FakeEnd(recorder, "d", 10);
-  TimelineTestHelper::FakeEnd(recorder, "a", 10);
+    // Test case.
+    TimelineTestHelper::FakeBegin(Timeline::recorder(), "a", 0);
+    TimelineTestHelper::FakeBegin(Timeline::recorder(), "b", 0);
+    TimelineTestHelper::FakeBegin(Timeline::recorder(), "c", 1);
+    TimelineTestHelper::FakeEnd(Timeline::recorder(), "c", 4);
+    TimelineTestHelper::FakeEnd(Timeline::recorder(), "b", 5);
+    TimelineTestHelper::FakeBegin(Timeline::recorder(), "d", 5);
+    TimelineTestHelper::FakeEnd(Timeline::recorder(), "d", 10);
+    TimelineTestHelper::FakeEnd(Timeline::recorder(), "a", 10);
+
+    {
+      TimelinePauses pauses(zone, isolate, Timeline::recorder());
+      pauses.Setup();
+      pauses.CalculatePauseTimesForThread(tid);
+      EXPECT(!pauses.has_error());
+      EXPECT_EQ(10, pauses.InclusiveTime("a"));
+      EXPECT_EQ(0, pauses.ExclusiveTime("a"));
+      EXPECT_EQ(10, pauses.MaxInclusiveTime("a"));
+      EXPECT_EQ(0, pauses.MaxExclusiveTime("a"));
+      EXPECT_EQ(5, pauses.InclusiveTime("b"));
+      EXPECT_EQ(2, pauses.ExclusiveTime("b"));
+      EXPECT_EQ(5, pauses.MaxInclusiveTime("b"));
+      EXPECT_EQ(2, pauses.MaxExclusiveTime("b"));
+      EXPECT_EQ(3, pauses.InclusiveTime("c"));
+      EXPECT_EQ(3, pauses.ExclusiveTime("c"));
+      EXPECT_EQ(3, pauses.MaxInclusiveTime("c"));
+      EXPECT_EQ(3, pauses.MaxExclusiveTime("c"));
+      EXPECT_EQ(5, pauses.InclusiveTime("d"));
+      EXPECT_EQ(5, pauses.ExclusiveTime("d"));
+      EXPECT_EQ(5, pauses.MaxInclusiveTime("d"));
+      EXPECT_EQ(5, pauses.MaxExclusiveTime("d"));
+    }
+  }
 
   {
-    TimelinePauses pauses(zone, isolate, recorder);
-    pauses.Setup();
-    pauses.CalculatePauseTimesForThread(tid);
-    EXPECT(!pauses.has_error());
-    EXPECT_EQ(10, pauses.InclusiveTime("a"));
-    EXPECT_EQ(0, pauses.ExclusiveTime("a"));
-    EXPECT_EQ(10, pauses.MaxInclusiveTime("a"));
-    EXPECT_EQ(0, pauses.MaxExclusiveTime("a"));
-    EXPECT_EQ(5, pauses.InclusiveTime("b"));
-    EXPECT_EQ(2, pauses.ExclusiveTime("b"));
-    EXPECT_EQ(5, pauses.MaxInclusiveTime("b"));
-    EXPECT_EQ(2, pauses.MaxExclusiveTime("b"));
-    EXPECT_EQ(3, pauses.InclusiveTime("c"));
-    EXPECT_EQ(3, pauses.ExclusiveTime("c"));
-    EXPECT_EQ(3, pauses.MaxInclusiveTime("c"));
-    EXPECT_EQ(3, pauses.MaxExclusiveTime("c"));
-    EXPECT_EQ(5, pauses.InclusiveTime("d"));
-    EXPECT_EQ(5, pauses.ExclusiveTime("d"));
-    EXPECT_EQ(5, pauses.MaxInclusiveTime("d"));
-    EXPECT_EQ(5, pauses.MaxExclusiveTime("d"));
-  }
-  TimelineTestHelper::Clear(recorder);
+    TimelineRecorderOverride<TimelineEventEndlessRecorder> override;
 
-  // Test case.
-  TimelineTestHelper::FakeBegin(recorder, "a", 0);
-  TimelineTestHelper::FakeBegin(recorder, "b", 1);
-  TimelineTestHelper::FakeBegin(recorder, "c", 2);
-  TimelineTestHelper::FakeBegin(recorder, "d", 3);
-  TimelineTestHelper::FakeBegin(recorder, "e", 4);
-  TimelineTestHelper::FakeEnd(recorder, "e", 6);
-  TimelineTestHelper::FakeEnd(recorder, "d", 7);
-  TimelineTestHelper::FakeEnd(recorder, "c", 8);
-  TimelineTestHelper::FakeEnd(recorder, "b", 9);
-  TimelineTestHelper::FakeEnd(recorder, "a", 10);
+    // Test case.
+    TimelineTestHelper::FakeBegin(Timeline::recorder(), "a", 0);
+    TimelineTestHelper::FakeBegin(Timeline::recorder(), "b", 1);
+    TimelineTestHelper::FakeBegin(Timeline::recorder(), "c", 2);
+    TimelineTestHelper::FakeBegin(Timeline::recorder(), "d", 3);
+    TimelineTestHelper::FakeBegin(Timeline::recorder(), "e", 4);
+    TimelineTestHelper::FakeEnd(Timeline::recorder(), "e", 6);
+    TimelineTestHelper::FakeEnd(Timeline::recorder(), "d", 7);
+    TimelineTestHelper::FakeEnd(Timeline::recorder(), "c", 8);
+    TimelineTestHelper::FakeEnd(Timeline::recorder(), "b", 9);
+    TimelineTestHelper::FakeEnd(Timeline::recorder(), "a", 10);
+
+    {
+      TimelinePauses pauses(zone, isolate, Timeline::recorder());
+      pauses.Setup();
+      pauses.CalculatePauseTimesForThread(tid);
+      EXPECT(!pauses.has_error());
+      EXPECT_EQ(10, pauses.InclusiveTime("a"));
+      EXPECT_EQ(2, pauses.ExclusiveTime("a"));
+      EXPECT_EQ(10, pauses.MaxInclusiveTime("a"));
+      EXPECT_EQ(2, pauses.MaxExclusiveTime("a"));
+      EXPECT_EQ(8, pauses.InclusiveTime("b"));
+      EXPECT_EQ(2, pauses.ExclusiveTime("b"));
+      EXPECT_EQ(8, pauses.MaxInclusiveTime("b"));
+      EXPECT_EQ(2, pauses.MaxExclusiveTime("b"));
+      EXPECT_EQ(6, pauses.InclusiveTime("c"));
+      EXPECT_EQ(2, pauses.ExclusiveTime("c"));
+      EXPECT_EQ(6, pauses.MaxInclusiveTime("c"));
+      EXPECT_EQ(2, pauses.MaxExclusiveTime("c"));
+      EXPECT_EQ(4, pauses.InclusiveTime("d"));
+      EXPECT_EQ(2, pauses.ExclusiveTime("d"));
+      EXPECT_EQ(4, pauses.MaxInclusiveTime("d"));
+      EXPECT_EQ(2, pauses.MaxExclusiveTime("d"));
+      EXPECT_EQ(2, pauses.InclusiveTime("e"));
+      EXPECT_EQ(2, pauses.ExclusiveTime("e"));
+      EXPECT_EQ(2, pauses.MaxInclusiveTime("e"));
+      EXPECT_EQ(2, pauses.MaxExclusiveTime("e"));
+    }
+  }
 
   {
-    TimelinePauses pauses(zone, isolate, recorder);
-    pauses.Setup();
-    pauses.CalculatePauseTimesForThread(tid);
-    EXPECT(!pauses.has_error());
-    EXPECT_EQ(10, pauses.InclusiveTime("a"));
-    EXPECT_EQ(2, pauses.ExclusiveTime("a"));
-    EXPECT_EQ(10, pauses.MaxInclusiveTime("a"));
-    EXPECT_EQ(2, pauses.MaxExclusiveTime("a"));
-    EXPECT_EQ(8, pauses.InclusiveTime("b"));
-    EXPECT_EQ(2, pauses.ExclusiveTime("b"));
-    EXPECT_EQ(8, pauses.MaxInclusiveTime("b"));
-    EXPECT_EQ(2, pauses.MaxExclusiveTime("b"));
-    EXPECT_EQ(6, pauses.InclusiveTime("c"));
-    EXPECT_EQ(2, pauses.ExclusiveTime("c"));
-    EXPECT_EQ(6, pauses.MaxInclusiveTime("c"));
-    EXPECT_EQ(2, pauses.MaxExclusiveTime("c"));
-    EXPECT_EQ(4, pauses.InclusiveTime("d"));
-    EXPECT_EQ(2, pauses.ExclusiveTime("d"));
-    EXPECT_EQ(4, pauses.MaxInclusiveTime("d"));
-    EXPECT_EQ(2, pauses.MaxExclusiveTime("d"));
-    EXPECT_EQ(2, pauses.InclusiveTime("e"));
-    EXPECT_EQ(2, pauses.ExclusiveTime("e"));
-    EXPECT_EQ(2, pauses.MaxInclusiveTime("e"));
-    EXPECT_EQ(2, pauses.MaxExclusiveTime("e"));
-  }
-  TimelineTestHelper::Clear(recorder);
+    TimelineRecorderOverride<TimelineEventEndlessRecorder> override;
 
-  // Test case.
-  TimelineTestHelper::FakeBegin(recorder, "a", 0);
-  TimelineTestHelper::FakeBegin(recorder, "a", 1);
-  TimelineTestHelper::FakeEnd(recorder, "a", 9);
-  TimelineTestHelper::FakeEnd(recorder, "a", 10);
+    // Test case.
+    TimelineTestHelper::FakeBegin(Timeline::recorder(), "a", 0);
+    TimelineTestHelper::FakeBegin(Timeline::recorder(), "a", 1);
+    TimelineTestHelper::FakeEnd(Timeline::recorder(), "a", 9);
+    TimelineTestHelper::FakeEnd(Timeline::recorder(), "a", 10);
+
+    {
+      TimelinePauses pauses(zone, isolate, Timeline::recorder());
+      pauses.Setup();
+      pauses.CalculatePauseTimesForThread(tid);
+      EXPECT(!pauses.has_error());
+      EXPECT_EQ(10, pauses.InclusiveTime("a"));
+      EXPECT_EQ(10, pauses.ExclusiveTime("a"));
+      EXPECT_EQ(10, pauses.MaxInclusiveTime("a"));
+      EXPECT_EQ(8, pauses.MaxExclusiveTime("a"));
+    }
+  }
 
   {
-    TimelinePauses pauses(zone, isolate, recorder);
-    pauses.Setup();
-    pauses.CalculatePauseTimesForThread(tid);
-    EXPECT(!pauses.has_error());
-    EXPECT_EQ(10, pauses.InclusiveTime("a"));
-    EXPECT_EQ(10, pauses.ExclusiveTime("a"));
-    EXPECT_EQ(10, pauses.MaxInclusiveTime("a"));
-    EXPECT_EQ(8, pauses.MaxExclusiveTime("a"));
+    TimelineRecorderOverride<TimelineEventEndlessRecorder> override;
+
+    // Test case.
+    TimelineTestHelper::FakeBegin(Timeline::recorder(), "a", 0);
+    TimelineTestHelper::FakeBegin(Timeline::recorder(), "b", 1);
+    // Pop "a" without popping "b" first.
+    TimelineTestHelper::FakeEnd(Timeline::recorder(), "a", 10);
+
+    {
+      TimelinePauses pauses(zone, isolate, Timeline::recorder());
+      pauses.Setup();
+      pauses.CalculatePauseTimesForThread(tid);
+      EXPECT(pauses.has_error());
+    }
   }
-  TimelineTestHelper::Clear(recorder);
-
-  // Test case.
-  TimelineTestHelper::FakeBegin(recorder, "a", 0);
-  TimelineTestHelper::FakeBegin(recorder, "b", 1);
-  // Pop "a" without popping "b" first.
-  TimelineTestHelper::FakeEnd(recorder, "a", 10);
-
-  {
-    TimelinePauses pauses(zone, isolate, recorder);
-    pauses.Setup();
-    pauses.CalculatePauseTimesForThread(tid);
-    EXPECT(pauses.has_error());
-  }
-  TimelineTestHelper::Clear(recorder);
-
-  delete recorder;
 }
 
 #endif  // !PRODUCT
diff --git a/runtime/vm/utils_test.cc b/runtime/vm/utils_test.cc
index 85ff6d4..ba4e296 100644
--- a/runtime/vm/utils_test.cc
+++ b/runtime/vm/utils_test.cc
@@ -4,10 +4,55 @@
 
 #include "platform/utils.h"
 #include "platform/assert.h"
+#include "platform/globals.h"
 #include "vm/unit_test.h"
 
 namespace dart {
 
+VM_UNIT_TEST_CASE(StringHash) {
+  auto hash_created_string = [](intptr_t length,
+                                intptr_t misalignment) -> uint32_t {
+    const intptr_t capacity = length + misalignment + kInt32Size;
+    char* str = new char[capacity];
+    const intptr_t alloc_misalignment =
+        reinterpret_cast<intptr_t>(str) % kInt32Size;
+    const intptr_t first_aligned_position =
+        alloc_misalignment > 0 ? kInt32Size - alloc_misalignment : 0;
+    const intptr_t start = first_aligned_position + misalignment;
+    for (intptr_t n = 0; n < start; n++) {
+      str[n] = 0xFF;
+    }
+    for (intptr_t n = 0; n < length; n++) {
+      // Fill the important string positions with uppercase letters.
+      str[start + n] = 0x40 + (n % 26);
+    }
+    for (intptr_t n = start + length; n < capacity; n++) {
+      str[n] = 0xFF;
+    }
+    const uint32_t hash = Utils::StringHash(str + start, length);
+    delete[] str;
+    return hash;
+  };
+
+  const intptr_t kMaxLength = 100;
+  ASSERT(kMaxLength >= kInt64Size);
+  uint32_t last_hash = hash_created_string(0, 0);
+  bool identical_hashes = true;
+  // Check the same string at different (mis)alignments has the same hash.
+  for (intptr_t len = 0; len < kMaxLength; len++) {
+    const uint32_t hash = hash_created_string(len, 0);
+    for (intptr_t misalignment = 1; misalignment < kInt64Size; misalignment++) {
+      EXPECT_EQ(hash, hash_created_string(len, misalignment));
+    }
+    if (hash != last_hash) {
+      identical_hashes = false;
+    }
+    last_hash = hash;
+  }
+  // Make sure at least some of the hashes were different from each other.
+  EXPECT(!identical_hashes);
+}
+
 VM_UNIT_TEST_CASE(Minimum) {
   EXPECT_EQ(0, Utils::Minimum(0, 1));
   EXPECT_EQ(0, Utils::Minimum(1, 0));
diff --git a/runtime/vm/virtual_memory_compressed.h b/runtime/vm/virtual_memory_compressed.h
index 95f4d52..4201018 100644
--- a/runtime/vm/virtual_memory_compressed.h
+++ b/runtime/vm/virtual_memory_compressed.h
@@ -12,7 +12,7 @@
 namespace dart {
 
 #if defined(DART_COMPRESSED_POINTERS)
-static constexpr intptr_t kCompressedHeapSize = 2 * GB;
+static constexpr intptr_t kCompressedHeapSize = 4 * GB;
 static constexpr intptr_t kCompressedHeapAlignment = 4 * GB;
 static constexpr intptr_t kCompressedHeapPageSize = kOldPageSize;
 static constexpr intptr_t kCompressedHeapNumPages =
diff --git a/runtime/vm/virtual_memory_posix.cc b/runtime/vm/virtual_memory_posix.cc
index dd07c76..1e0b8f8 100644
--- a/runtime/vm/virtual_memory_posix.cc
+++ b/runtime/vm/virtual_memory_posix.cc
@@ -77,7 +77,7 @@
 #if defined(DART_COMPRESSED_POINTERS)
   if (VirtualMemoryCompressedHeap::GetRegion() == nullptr) {
     void* address = GenericMapAligned(
-        PROT_READ | PROT_WRITE, kCompressedHeapSize, kCompressedHeapAlignment,
+        PROT_NONE, kCompressedHeapSize, kCompressedHeapAlignment,
         kCompressedHeapSize + kCompressedHeapAlignment,
         MAP_PRIVATE | MAP_ANONYMOUS);
     if (address == nullptr) {
@@ -347,6 +347,7 @@
 VirtualMemory::~VirtualMemory() {
 #if defined(DART_COMPRESSED_POINTERS)
   if (VirtualMemoryCompressedHeap::Contains(reserved_.pointer())) {
+    madvise(reserved_.pointer(), reserved_.size(), MADV_DONTNEED);
     VirtualMemoryCompressedHeap::Free(reserved_.pointer(), reserved_.size());
     return;
   }
diff --git a/runtime/vm/visitor.h b/runtime/vm/visitor.h
index 8365418..fd2a78c 100644
--- a/runtime/vm/visitor.h
+++ b/runtime/vm/visitor.h
@@ -28,9 +28,9 @@
   //
   // Range of pointers to visit 'first' <= pointer <= 'last'.
   virtual void VisitTypedDataViewPointers(TypedDataViewPtr view,
-                                          ObjectPtr* first,
-                                          ObjectPtr* last) {
-    VisitPointers(first, last);
+                                          CompressedObjectPtr* first,
+                                          CompressedObjectPtr* last) {
+    VisitCompressedPointers(view->heap_base(), first, last);
   }
 
   // Range of pointers to visit 'first' <= pointer <= 'last'.
diff --git a/samples/sample_extension/test/sample_extension_test_helper.dart b/samples/sample_extension/test/sample_extension_test_helper.dart
index d4cae3d..a4a78ce 100644
--- a/samples/sample_extension/test/sample_extension_test_helper.dart
+++ b/samples/sample_extension/test/sample_extension_test_helper.dart
@@ -44,6 +44,30 @@
   }
 }
 
+Future runTests(
+    String program, String testDirectory, String? snapshotKind) async {
+  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");
+      await run(Platform.executable, <String>[
+        ...Platform.executableArguments,
+        '--snapshot=$snapshot',
+        '--snapshot-kind=$snapshotKind',
+        script
+      ]);
+    }
+
+    await run(program, <String>[...Platform.executableArguments, snapshot]);
+  }
+}
+
 Future testNativeExtensions(String? snapshotKind) async {
   String buildDirectory = dirname(Platform.executable);
   Directory tempDirectory =
@@ -63,27 +87,27 @@
       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);
-      }
+    // Test native library resolution when it's next to the binary
+    await runTests(Platform.executable, testDirectory, snapshotKind);
 
-      List<String> args = new List<String>.from(Platform.executableArguments);
-      args.add(snapshot);
-      await run(Platform.executable, args);
-    }
+    // Test native library resolution when it's next to the source
+    await copyFileToDirectory(
+        join(
+            buildDirectory,
+            (Platform.isWindows ? '' : 'lib') +
+                'sample_extension' +
+                (Platform.isWindows
+                    ? '.dll'
+                    : Platform.isMacOS
+                        ? '.dylib'
+                        : '.so')),
+        testDirectory);
+    Directory tempBinDirectory = Directory(join(tempDirectory.path, 'dart-bin'))
+      ..createSync();
+    await copyFileToDirectory(Platform.executable, tempBinDirectory.path);
+    String copyPlatformExecutable =
+        join(tempBinDirectory.path, basename(Platform.executable));
+    await runTests(copyPlatformExecutable, testDirectory, snapshotKind);
   } finally {
     tempDirectory.deleteSync(recursive: true);
   }
diff --git a/samples_2/sample_extension/test/sample_extension_test_helper.dart b/samples_2/sample_extension/test/sample_extension_test_helper.dart
index 9c701bf..cabbb28 100644
--- a/samples_2/sample_extension/test/sample_extension_test_helper.dart
+++ b/samples_2/sample_extension/test/sample_extension_test_helper.dart
@@ -26,7 +26,7 @@
       result = await Process.run('cmd.exe', ['/C', 'copy $src $dst']);
       break;
     default:
-      Expect.fail('Unknown operating system ${Platform.operatingSystem}');
+      throw 'Unknown operating system ${Platform.operatingSystem}';
   }
   if (result.exitCode != 0) {
     print(result.stdout);
@@ -46,6 +46,30 @@
   }
 }
 
+Future runTests(
+    String program, String testDirectory, String snapshotKind) async {
+  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");
+      await run(Platform.executable, <String>[
+        ...Platform.executableArguments,
+        '--snapshot=$snapshot',
+        '--snapshot-kind=$snapshotKind',
+        script
+      ]);
+    }
+
+    await run(program, <String>[...Platform.executableArguments, snapshot]);
+  }
+}
+
 Future testNativeExtensions(String snapshotKind) async {
   String buildDirectory = dirname(Platform.executable);
   Directory tempDirectory =
@@ -65,27 +89,27 @@
       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);
-      }
+    // Test native library resolution when it's next to the binary
+    await runTests(Platform.executable, testDirectory, snapshotKind);
 
-      List<String> args = new List<String>.from(Platform.executableArguments);
-      args.add(snapshot);
-      await run(Platform.executable, args);
-    }
+    // Test native library resolution when it's next to the source
+    await copyFileToDirectory(
+        join(
+            buildDirectory,
+            (Platform.isWindows ? '' : 'lib') +
+                'sample_extension' +
+                (Platform.isWindows
+                    ? '.dll'
+                    : Platform.isMacOS
+                        ? '.dylib'
+                        : '.so')),
+        testDirectory);
+    Directory tempBinDirectory = Directory(join(tempDirectory.path, 'dart-bin'))
+      ..createSync();
+    await copyFileToDirectory(Platform.executable, tempBinDirectory.path);
+    String copyPlatformExecutable =
+        join(tempBinDirectory.path, basename(Platform.executable));
+    await runTests(copyPlatformExecutable, testDirectory, snapshotKind);
   } finally {
     tempDirectory.deleteSync(recursive: true);
   }
diff --git a/sdk/BUILD.gn b/sdk/BUILD.gn
index b6091dc..15a1abf 100644
--- a/sdk/BUILD.gn
+++ b/sdk/BUILD.gn
@@ -115,6 +115,10 @@
 # Snapshots that go under bin/snapshots
 _platform_sdk_snapshots = [
   [
+    "analysis_server",
+    "../utils/analysis_server",
+  ],
+  [
     "dartanalyzer",
     "../utils/dartanalyzer:generate_dartanalyzer_snapshot",
   ],
@@ -151,12 +155,6 @@
         "../utils/kernel-service:kernel-service_snapshot",
       ] ]
 }
-if (dart_target_arch != "arm") {
-  _platform_sdk_snapshots += [ [
-        "analysis_server",
-        "../utils/analysis_server",
-      ] ]
-}
 
 _full_sdk_snapshots = _platform_sdk_snapshots + [
                         [
@@ -509,29 +507,6 @@
   outputs = [ "$root_out_dir/dart-sdk/lib/_internal/{{source_file_part}}" ]
 }
 
-copy("copy_wasmer") {
-  visibility = [ ":create_common_sdk" ]
-  deps = [
-    ":copy_libraries",
-    "../third_party/wasmer:wasmer_wrap",
-  ]
-  if (is_win) {
-    prefix = ""
-    suffix = "dll"
-  } else if (is_mac) {
-    prefix = "lib"
-    suffix = "dylib"
-  } else {
-    # TODO(dartbug.com/37882): Support Fuchsia.
-    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.
 copy("copy_vm_dill_files") {
   visibility = [ ":create_common_sdk" ]
@@ -852,14 +827,6 @@
   if (is_win) {
     public_deps += [ ":copy_7zip" ]
   }
-
-  # 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
-  # isn't ready yet).
-  if (host_cpu == "x64" && (host_os == "linux" || host_os == "mac") &&
-      host_cpu == current_cpu && host_os == current_os && dart_enable_wasm) {
-    public_deps += [ ":copy_wasmer" ]
-  }
 }
 
 # Parts specific to the platform SDK.
diff --git a/sdk/lib/_http/http.dart b/sdk/lib/_http/http.dart
index 76d2c68..c4344d6 100644
--- a/sdk/lib/_http/http.dart
+++ b/sdk/lib/_http/http.dart
@@ -763,7 +763,7 @@
 
 /**
  * Representation of a header value in the form:
- * ```dart
+ * ```plaintext
  * value; parameter1=value1; parameter2=value2
  * ```
  *
@@ -834,7 +834,7 @@
 
   /**
    * Returns the formatted string representation in the form:
-   * ```
+   * ```plaintext
    * value; parameter1=value1; parameter2=value2
    * ```
    */
diff --git a/sdk/lib/_http/http_impl.dart b/sdk/lib/_http/http_impl.dart
index e99a58d..1f36df2 100644
--- a/sdk/lib/_http/http_impl.dart
+++ b/sdk/lib/_http/http_impl.dart
@@ -4,6 +4,287 @@
 
 part of dart._http;
 
+abstract class HttpProfiler {
+  static const _kType = 'HttpProfile';
+
+  static Map<int, _HttpProfileData> _profile = {};
+
+  static _HttpProfileData startRequest(
+    String method,
+    Uri uri, {
+    _HttpProfileData? parentRequest,
+  }) {
+    final data = _HttpProfileData(method, uri, parentRequest?._timeline);
+    _profile[data.id] = data;
+    return data;
+  }
+
+  static _HttpProfileData? getHttpProfileRequest(int id) => _profile[id];
+
+  static void clear() => _profile.clear();
+
+  static String toJson(int? updatedSince) {
+    return json.encode({
+      'type': _kType,
+      'timestamp': Timeline.now,
+      'requests': [
+        for (final request in _profile.values.where(
+          (e) {
+            return (updatedSince == null) || e.lastUpdateTime >= updatedSince;
+          },
+        ))
+          request.toJson(),
+      ],
+    });
+  }
+}
+
+class _HttpProfileEvent {
+  _HttpProfileEvent(this.name, this.arguments);
+  final int timestamp = Timeline.now;
+  final String name;
+  final Map? arguments;
+
+  Map<String, dynamic> toJson() {
+    return <String, dynamic>{
+      'timestamp': timestamp,
+      'event': name,
+      if (arguments != null) 'arguments': arguments,
+    };
+  }
+}
+
+class _HttpProfileData {
+  _HttpProfileData(String method, this.uri, TimelineTask? parent)
+      : method = method.toUpperCase(),
+        _timeline = TimelineTask(
+          filterKey: 'HTTP/client',
+          parent: parent,
+        ) {
+    // Grab the ID from the timeline event so HTTP profile IDs can be matched
+    // to the timeline.
+    id = _timeline.pass();
+    requestInProgress = true;
+    requestStartTimestamp = Timeline.now;
+    _timeline.start('HTTP CLIENT $method', arguments: {
+      'method': method.toUpperCase(),
+      'uri': uri.toString(),
+    });
+    _updated();
+  }
+
+  void requestEvent(String name, {Map? arguments}) {
+    _timeline.instant(name, arguments: arguments);
+    requestEvents.add(_HttpProfileEvent(name, arguments));
+    _updated();
+  }
+
+  void proxyEvent(_Proxy proxy) {
+    proxyDetails = {
+      if (proxy.host != null) 'host': proxy.host,
+      if (proxy.port != null) 'port': proxy.port,
+      if (proxy.username != null) 'username': proxy.username,
+    };
+    _timeline.instant('Establishing proxy tunnel', arguments: {
+      'proxyDetails': proxyDetails,
+    });
+    _updated();
+  }
+
+  void appendRequestData(Uint8List data) {
+    requestBody.addAll(data);
+    _updated();
+  }
+
+  Map formatHeaders(r) {
+    final headers = <String, List<String>>{};
+    r.headers.forEach((name, values) {
+      headers[name] = values;
+    });
+    return headers;
+  }
+
+  Map? formatConnectionInfo(r) => r.connectionInfo == null
+      ? null
+      : {
+          'localPort': r.connectionInfo?.localPort,
+          'remoteAddress': r.connectionInfo?.remoteAddress.address,
+          'remotePort': r.connectionInfo?.remotePort,
+        };
+
+  void finishRequest({
+    required HttpClientRequest request,
+  }) {
+    // TODO(bkonyi): include encoding?
+    requestInProgress = false;
+    requestEndTimestamp = Timeline.now;
+    requestDetails = <String, dynamic>{
+      // TODO(bkonyi): consider exposing certificate information?
+      // 'certificate': response.certificate,
+      'headers': formatHeaders(request),
+      'connectionInfo': formatConnectionInfo(request),
+      'contentLength': request.contentLength,
+      'cookies': [
+        for (final cookie in request.cookies) cookie.toString(),
+      ],
+      'followRedirects': request.followRedirects,
+      'maxRedirects': request.maxRedirects,
+      'method': request.method,
+      'persistentConnection': request.persistentConnection,
+      'uri': request.uri.toString(),
+    };
+    _timeline.finish(
+      arguments: requestDetails,
+    );
+    _updated();
+  }
+
+  void startResponse({required HttpClientResponse response}) {
+    List<Map<String, dynamic>> formatRedirectInfo() {
+      final redirects = <Map<String, dynamic>>[];
+      for (final redirect in response.redirects) {
+        redirects.add({
+          'location': redirect.location.toString(),
+          'method': redirect.method,
+          'statusCode': redirect.statusCode,
+        });
+      }
+      return redirects;
+    }
+
+    responseDetails = <String, dynamic>{
+      'headers': formatHeaders(response),
+      'compressionState': response.compressionState.toString(),
+      'connectionInfo': formatConnectionInfo(response),
+      'contentLength': response.contentLength,
+      'cookies': [
+        for (final cookie in response.cookies) cookie.toString(),
+      ],
+      'isRedirect': response.isRedirect,
+      'persistentConnection': response.persistentConnection,
+      'reasonPhrase': response.reasonPhrase,
+      'redirects': formatRedirectInfo(),
+      'statusCode': response.statusCode,
+    };
+
+    assert(!requestInProgress);
+    responseInProgress = true;
+    _responseTimeline = TimelineTask(
+      parent: _timeline,
+      filterKey: 'HTTP/client',
+    );
+
+    responseStartTimestamp = Timeline.now;
+    _responseTimeline.start(
+      'HTTP CLIENT response of $method',
+      arguments: {
+        'requestUri': uri.toString(),
+        ...responseDetails!,
+      },
+    );
+    _updated();
+  }
+
+  void finishRequestWithError(String error) {
+    requestInProgress = false;
+    requestEndTimestamp = Timeline.now;
+    requestError = error;
+    _timeline.finish(arguments: {
+      'error': error,
+    });
+    _updated();
+  }
+
+  void finishResponse() {
+    responseInProgress = false;
+    responseEndTimestamp = Timeline.now;
+    requestEvent('Content Download');
+    _responseTimeline.finish();
+    _updated();
+  }
+
+  void finishResponseWithError(String error) {
+    // Return if finishResponseWithError has already been called. Can happen if
+    // the response stream is listened to with `cancelOnError: false`.
+    if (!responseInProgress!) return;
+    responseInProgress = false;
+    responseEndTimestamp = Timeline.now;
+    responseError = error;
+    _responseTimeline.finish(arguments: {
+      'error': error,
+    });
+    _updated();
+  }
+
+  void appendResponseData(Uint8List data) {
+    responseBody.addAll(data);
+    _updated();
+  }
+
+  Map<String, dynamic> toJson({bool ref = true}) {
+    return <String, dynamic>{
+      'type': '${ref ? '@' : ''}HttpProfileRequest',
+      'id': id,
+      'isolateId': isolateId,
+      'method': method,
+      'uri': uri.toString(),
+      'startTime': requestStartTimestamp,
+      if (!requestInProgress) 'endTime': requestEndTimestamp,
+      if (!requestInProgress)
+        'request': {
+          'events': <Map<String, dynamic>>[
+            for (final event in requestEvents) event.toJson(),
+          ],
+          if (proxyDetails != null) 'proxyDetails': proxyDetails!,
+          if (requestDetails != null) ...requestDetails!,
+          if (requestError != null) 'error': requestError,
+        },
+      if (responseInProgress != null)
+        'response': <String, dynamic>{
+          'startTime': responseStartTimestamp,
+          ...responseDetails!,
+          if (!responseInProgress!) 'endTime': responseEndTimestamp,
+          if (responseError != null) 'error': responseError,
+        },
+      if (!ref) ...{
+        if (!requestInProgress) 'requestBody': requestBody,
+        if (responseInProgress != null) 'responseBody': responseBody,
+      }
+    };
+  }
+
+  void _updated() => _lastUpdateTime = Timeline.now;
+
+  static final String isolateId = Service.getIsolateID(Isolate.current)!;
+
+  bool requestInProgress = true;
+  bool? responseInProgress;
+
+  late final int id;
+  final String method;
+  final Uri uri;
+
+  late final int requestStartTimestamp;
+  late final int requestEndTimestamp;
+  Map<String, dynamic>? requestDetails;
+  Map<String, dynamic>? proxyDetails;
+  final requestBody = <int>[];
+  String? requestError;
+  final requestEvents = <_HttpProfileEvent>[];
+
+  late final int responseStartTimestamp;
+  late final int responseEndTimestamp;
+  Map<String, dynamic>? responseDetails;
+  final responseBody = <int>[];
+  String? responseError;
+
+  int get lastUpdateTime => _lastUpdateTime;
+  int _lastUpdateTime = 0;
+
+  TimelineTask _timeline;
+  late TimelineTask _responseTimeline;
+}
+
 int _nextServiceId = 1;
 
 // TODO(ajohnsen): Use other way of getting a unique id.
@@ -303,10 +584,10 @@
   // The compression state of this response.
   final HttpClientResponseCompressionState compressionState;
 
-  final TimelineTask? _timeline;
+  final _HttpProfileData? _profileData;
 
   _HttpClientResponse(_HttpIncoming _incoming, this._httpRequest,
-      this._httpClient, this._timeline)
+      this._httpClient, this._profileData)
       : compressionState = _getCompressionState(_httpClient, _incoming.headers),
         super(_incoming) {
     // Set uri for potential exceptions.
@@ -395,16 +676,10 @@
     });
   }
 
-  void _timelineFinishWithError(String error) {
-    _timeline?.finish(arguments: {
-      'error': error,
-    });
-  }
-
   StreamSubscription<Uint8List> listen(void onData(Uint8List event)?,
       {Function? onError, void onDone()?, bool? cancelOnError}) {
     if (_incoming.upgraded) {
-      _timelineFinishWithError('Connection was upgraded');
+      _profileData?.finishResponseWithError('Connection was upgraded');
       // If upgraded, the connection is already 'removed' form the client.
       // Since listening to upgraded data is 'bogus', simply close and
       // return empty stream subscription.
@@ -418,19 +693,15 @@
           .transform(gzip.decoder)
           .transform(const _ToUint8List());
     }
-    if (_timeline != null) {
+    if (_profileData != null) {
       // If _timeline is not set up, don't add unnecessary map() to the stream.
       stream = stream.map((data) {
-        _timeline?.instant('Response body', arguments: {
-          'data': data,
-        });
+        _profileData?.appendResponseData(data);
         return data;
       });
     }
     return stream.listen(onData, onError: (e, st) {
-      _timeline?.instant('Error response', arguments: {
-        'error': e.toString(),
-      });
+      _profileData?.finishResponseWithError(e.toString());
       if (onError == null) {
         return;
       }
@@ -441,7 +712,7 @@
         onError(e, st);
       }
     }, onDone: () {
-      _timeline?.finish();
+      _profileData?.finishResponse();
       if (onDone != null) {
         onDone();
       }
@@ -449,7 +720,7 @@
   }
 
   Future<Socket> detachSocket() {
-    _timelineFinishWithError('Socket has been detached');
+    _profileData?.finishResponseWithError('Socket has been detached');
     _httpClient._connectionClosed(_httpRequest._httpClientConnection);
     return _httpRequest._httpClientConnection.detachSocket();
   }
@@ -473,9 +744,9 @@
   }
 
   Future<HttpClientResponse> _authenticate(bool proxyAuth) {
-    _httpRequest._timeline?.instant('Authentication');
+    _httpRequest._profileData?.requestEvent('Authentication');
     Future<HttpClientResponse> retry() {
-      _httpRequest._timeline?.instant('Retrying');
+      _httpRequest._profileData?.requestEvent('Retrying');
       // Drain body and retry.
       return drain().then((_) {
         return _httpClient
@@ -753,8 +1024,9 @@
   Encoding _encoding;
   bool _encodingMutable = true;
 
-  final TimelineTask? _timeline;
-  _IOSinkImpl(StreamConsumer<List<int>> target, this._encoding, this._timeline)
+  final _HttpProfileData? _profileData;
+  _IOSinkImpl(
+      StreamConsumer<List<int>> target, this._encoding, this._profileData)
       : super(target);
 
   Encoding get encoding => _encoding;
@@ -769,9 +1041,11 @@
   void write(Object? obj) {
     String string = '$obj';
     if (string.isEmpty) return;
-    _timeline?.instant('Request body', arguments: {
-      'data': string,
-    });
+    _profileData?.appendRequestData(
+      Uint8List.fromList(
+        utf8.encode(string),
+      ),
+    );
     super.add(_encoding.encode(string));
   }
 
@@ -814,7 +1088,7 @@
   final _HttpHeaders headers;
 
   _HttpOutboundMessage(Uri uri, String protocolVersion, _HttpOutgoing outgoing,
-      TimelineTask? timeline,
+      _HttpProfileData? profileData,
       {_HttpHeaders? initialHeaders})
       : _uri = uri,
         headers = new _HttpHeaders(protocolVersion,
@@ -823,7 +1097,7 @@
                 : HttpClient.defaultHttpPort,
             initialHeaders: initialHeaders),
         _outgoing = outgoing,
-        super(outgoing, latin1, timeline) {
+        super(outgoing, latin1, profileData) {
     _outgoing.outbound = this;
     _encodingMutable = false;
   }
@@ -860,20 +1134,16 @@
 
   void add(List<int> data) {
     if (data.length == 0) return;
-    _timeline?.instant('Request body', arguments: {
-      'encodedData': data,
-    });
+    _profileData?.appendRequestData(Uint8List.fromList(data));
     super.add(data);
   }
 
   Future addStream(Stream<List<int>> s) {
-    if (_timeline == null) {
+    if (_profileData == null) {
       return super.addStream(s);
     }
     return super.addStream(s.map((data) {
-      _timeline?.instant('Request body', arguments: {
-        'encodedData': data,
-      });
+      _profileData?.appendRequestData(Uint8List.fromList(data));
       return data;
     }));
   }
@@ -1122,8 +1392,7 @@
   // The HttpClient this request belongs to.
   final _HttpClient _httpClient;
   final _HttpClientConnection _httpClientConnection;
-  final TimelineTask? _timeline;
-  final TimelineTask? _responseTimeline;
+  final _HttpProfileData? _profileData;
 
   final Completer<HttpClientResponse> _responseCompleter =
       new Completer<HttpClientResponse>();
@@ -1142,17 +1411,16 @@
   bool _aborted = false;
 
   _HttpClientRequest(
-      _HttpOutgoing outgoing,
-      Uri uri,
-      this.method,
-      this._proxy,
-      this._httpClient,
-      this._httpClientConnection,
-      this._timeline,
-      this._responseTimeline)
-      : uri = uri,
-        super(uri, "1.1", outgoing, _responseTimeline) {
-    _timeline?.instant('Request initiated');
+    _HttpOutgoing outgoing,
+    Uri uri,
+    this.method,
+    this._proxy,
+    this._httpClient,
+    this._httpClientConnection,
+    this._profileData,
+  )   : uri = uri,
+        super(uri, "1.1", outgoing, _profileData) {
+    _profileData?.requestEvent('Request sent');
     // GET and HEAD have 'content-length: 0' by default.
     if (method == "GET" || method == "HEAD") {
       contentLength = 0;
@@ -1160,58 +1428,15 @@
       headers.chunkedTransferEncoding = true;
     }
 
+    _profileData?.finishRequest(request: this);
+
     _responseCompleter.future.then((response) {
-      _timeline?.instant('Response received');
-      Map formatConnectionInfo() => {
-            'localPort': response.connectionInfo?.localPort,
-            'remoteAddress': response.connectionInfo?.remoteAddress.address,
-            'remotePort': response.connectionInfo?.remotePort,
-          };
-
-      Map formatHeaders() {
-        final headers = <String, List<String>>{};
-        response.headers.forEach((name, values) {
-          headers[name] = values;
-        });
-        return headers;
-      }
-
-      List<Map<String, dynamic>> formatRedirectInfo() {
-        final redirects = <Map<String, dynamic>>[];
-        for (final redirect in response.redirects) {
-          redirects.add({
-            'location': redirect.location.toString(),
-            'method': redirect.method,
-            'statusCode': redirect.statusCode,
-          });
-        }
-        return redirects;
-      }
-
-      _timeline?.finish(arguments: {
+      _profileData?.requestEvent('Waiting (TTFB)');
+      _profileData?.startResponse(
         // TODO(bkonyi): consider exposing certificate information?
         // 'certificate': response.certificate,
-        'requestHeaders': outgoing.outbound!.headers._headers,
-        'compressionState': response.compressionState.toString(),
-        'connectionInfo': formatConnectionInfo(),
-        'contentLength': response.contentLength,
-        'cookies': [for (final cookie in response.cookies) cookie.toString()],
-        'responseHeaders': formatHeaders(),
-        'isRedirect': response.isRedirect,
-        'persistentConnection': response.persistentConnection,
-        'reasonPhrase': response.reasonPhrase,
-        'redirects': formatRedirectInfo(),
-        'statusCode': response.statusCode,
-      });
-
-      // Start the timeline for response.
-      _responseTimeline?.start(
-          'HTTP CLIENT response of ${method.toUpperCase()}',
-          arguments: {
-            'requestUri': uri.toString(),
-            'statusCode': response.statusCode,
-            'reasonPhrase': response.reasonPhrase,
-          });
+        response: response,
+      );
     }, onError: (e) {});
   }
 
@@ -1247,7 +1472,7 @@
       return;
     }
     final response =
-        _HttpClientResponse(incoming, this, _httpClient, _responseTimeline);
+        _HttpClientResponse(incoming, this, _httpClient, _profileData);
     Future<HttpClientResponse> future;
     if (followRedirects && response.isRedirect) {
       if (response.redirects.length < maxRedirects) {
@@ -1855,8 +2080,8 @@
     });
   }
 
-  _HttpClientRequest send(
-      Uri uri, int port, String method, _Proxy proxy, TimelineTask? timeline) {
+  _HttpClientRequest send(Uri uri, int port, String method, _Proxy proxy,
+      _HttpProfileData? profileData) {
     if (closed) {
       throw new HttpException("Socket closed before request was sent",
           uri: uri);
@@ -1872,15 +2097,9 @@
     _SiteCredentials? creds; // Credentials used to authorize this request.
     var outgoing = new _HttpOutgoing(_socket);
 
-    final responseTimeline = timeline == null
-        ? null
-        : TimelineTask(
-            parent: timeline,
-            filterKey: 'HTTP/client',
-          );
     // Create new request object, wrapping the outgoing connection.
-    var request = new _HttpClientRequest(outgoing, uri, method, proxy,
-        _httpClient, this, timeline, responseTimeline);
+    var request = new _HttpClientRequest(
+        outgoing, uri, method, proxy, _httpClient, this, profileData);
     // For the Host header an IPv6 address must be enclosed in []'s.
     var host = uri.host;
     if (host.contains(':')) host = "[$host]";
@@ -2034,24 +2253,23 @@
       int port,
       _Proxy proxy,
       bool callback(X509Certificate certificate),
-      TimelineTask? timeline) {
-    timeline?.instant('Establishing proxy tunnel', arguments: {
-      'proxyInfo': {
-        if (proxy.host != null) 'host': proxy.host,
-        if (proxy.port != null) 'port': proxy.port,
-        if (proxy.username != null) 'username': proxy.username,
-        // TODO(bkonyi): is this something we would want to surface? Initial
-        // thought is no.
-        // if (proxy.password != null)
-        //   'password': proxy.password,
-        'isDirect': proxy.isDirect,
-      }
-    });
+      _HttpProfileData? profileData) {
     final method = "CONNECT";
     final uri = Uri(host: host, port: port);
-    _HttpClient._startRequestTimelineEvent(timeline, method, uri);
-    _HttpClientRequest request =
-        send(Uri(host: host, port: port), port, method, proxy, timeline);
+
+    profileData?.proxyEvent(proxy);
+
+    // Notify the profiler that we're starting a sub request.
+    _HttpProfileData? proxyProfileData;
+    if (profileData != null) {
+      proxyProfileData = HttpProfiler.startRequest(
+        method,
+        uri,
+        parentRequest: profileData,
+      );
+    }
+    _HttpClientRequest request = send(
+        Uri(host: host, port: port), port, method, proxy, proxyProfileData);
     if (proxy.isAuthenticated) {
       // If the proxy configuration contains user information use that
       // for proxy basic authorization.
@@ -2063,7 +2281,7 @@
       if (response.statusCode != HttpStatus.ok) {
         final error = "Proxy failed to establish tunnel "
             "(${response.statusCode} ${response.reasonPhrase})";
-        timeline?.instant(error);
+        profileData?.requestEvent(error);
         throw new HttpException(error, uri: request.uri);
       }
       var socket = (response as _HttpClientResponse)
@@ -2074,7 +2292,7 @@
           host: host, context: _context, onBadCertificate: callback);
     }).then((secureSocket) {
       String key = _HttpClientConnection.makeKey(true, host, port);
-      timeline?.instant('Proxy tunnel established');
+      profileData?.requestEvent('Proxy tunnel established');
       return new _HttpClientConnection(
           key, secureSocket, request._httpClient, true);
     });
@@ -2187,7 +2405,7 @@
   }
 
   Future<_ConnectionInfo> connect(String uriHost, int uriPort, _Proxy proxy,
-      _HttpClient client, TimelineTask? timeline) {
+      _HttpClient client, _HttpProfileData? profileData) {
     if (hasIdle) {
       var connection = takeIdle();
       client._connectionsChanged();
@@ -2198,7 +2416,8 @@
         _active.length + _connecting >= maxConnectionsPerHost) {
       var completer = new Completer<_ConnectionInfo>();
       _pending.add(() {
-        completer.complete(connect(uriHost, uriPort, proxy, client, timeline));
+        completer
+            .complete(connect(uriHost, uriPort, proxy, client, profileData));
       });
       return completer.future;
     }
@@ -2229,7 +2448,7 @@
         if (isSecure && !proxy.isDirect) {
           connection._dispose = true;
           return connection
-              .createProxyTunnel(uriHost, uriPort, proxy, callback, timeline)
+              .createProxyTunnel(uriHost, uriPort, proxy, callback, profileData)
               .then((tunnel) {
             client
                 ._getConnectionTarget(uriHost, uriPort, true)
@@ -2401,14 +2620,6 @@
 
   set findProxy(String f(Uri uri)?) => _findProxy = f;
 
-  static void _startRequestTimelineEvent(
-      TimelineTask? timeline, String method, Uri uri) {
-    timeline?.start('HTTP CLIENT ${method.toUpperCase()}', arguments: {
-      'method': method.toUpperCase(),
-      'uri': uri.toString(),
-    });
-  }
-
   Future<_HttpClientRequest> _openUrl(String method, Uri uri) {
     if (_closing) {
       throw new StateError("Client is closed");
@@ -2450,31 +2661,27 @@
         return new Future.error(error, stackTrace);
       }
     }
-    TimelineTask? timeline;
-    // TODO(bkonyi): do we want this to be opt-in?
+    _HttpProfileData? profileData;
     if (HttpClient.enableTimelineLogging) {
-      timeline = TimelineTask(filterKey: 'HTTP/client');
-      _startRequestTimelineEvent(timeline, method, uri);
+      profileData = HttpProfiler.startRequest(method, uri);
     }
-    return _getConnection(uri.host, port, proxyConf, isSecure, timeline).then(
-        (_ConnectionInfo info) {
+    return _getConnection(uri.host, port, proxyConf, isSecure, profileData)
+        .then((_ConnectionInfo info) {
       _HttpClientRequest send(_ConnectionInfo info) {
-        timeline?.instant('Connection established');
+        profileData?.requestEvent('Connection established');
         return info.connection
-            .send(uri, port, method.toUpperCase(), info.proxy, timeline);
+            .send(uri, port, method.toUpperCase(), info.proxy, profileData);
       }
 
       // If the connection was closed before the request was sent, create
       // and use another connection.
       if (info.connection.closed) {
-        return _getConnection(uri.host, port, proxyConf, isSecure, timeline)
+        return _getConnection(uri.host, port, proxyConf, isSecure, profileData)
             .then(send);
       }
       return send(info);
     }, onError: (error) {
-      timeline?.finish(arguments: {
-        'error': error.toString(),
-      });
+      profileData?.finishRequestWithError(error.toString());
       throw error;
     });
   }
@@ -2555,8 +2762,12 @@
   }
 
   // Get a new _HttpClientConnection, from the matching _ConnectionTarget.
-  Future<_ConnectionInfo> _getConnection(String uriHost, int uriPort,
-      _ProxyConfiguration proxyConf, bool isSecure, TimelineTask? timeline) {
+  Future<_ConnectionInfo> _getConnection(
+      String uriHost,
+      int uriPort,
+      _ProxyConfiguration proxyConf,
+      bool isSecure,
+      _HttpProfileData? profileData) {
     Iterator<_Proxy> proxies = proxyConf.proxies.iterator;
 
     Future<_ConnectionInfo> connect(error) {
@@ -2565,7 +2776,7 @@
       String host = proxy.isDirect ? uriHost : proxy.host!;
       int port = proxy.isDirect ? uriPort : proxy.port!;
       return _getConnectionTarget(host, port, isSecure)
-          .connect(uriHost, uriPort, proxy, this, timeline)
+          .connect(uriHost, uriPort, proxy, this, profileData)
           // On error, continue with next proxy.
           .catchError(connect);
     }
diff --git a/sdk/lib/_http/http_parser.dart b/sdk/lib/_http/http_parser.dart
index 93b6518..060291c 100644
--- a/sdk/lib/_http/http_parser.dart
+++ b/sdk/lib/_http/http_parser.dart
@@ -66,17 +66,17 @@
   static const int HEADER_FIELD = 11;
   static const int HEADER_VALUE_START = 12;
   static const int HEADER_VALUE = 13;
-  static const int HEADER_VALUE_FOLDING_OR_ENDING = 14;
+  static const int HEADER_VALUE_FOLD_OR_END_CR = 14;
   static const int HEADER_VALUE_FOLD_OR_END = 15;
   static const int HEADER_ENDING = 16;
 
   static const int CHUNK_SIZE_STARTING_CR = 17;
-  static const int CHUNK_SIZE_STARTING_LF = 18;
+  static const int CHUNK_SIZE_STARTING = 18;
   static const int CHUNK_SIZE = 19;
   static const int CHUNK_SIZE_EXTENSION = 20;
   static const int CHUNK_SIZE_ENDING = 21;
   static const int CHUNKED_BODY_DONE_CR = 22;
-  static const int CHUNKED_BODY_DONE_LF = 23;
+  static const int CHUNKED_BODY_DONE = 23;
   static const int BODY = 24;
   static const int CLOSED = 25;
   static const int UPGRADED = 26;
@@ -418,6 +418,10 @@
   // Request-Line    = Method SP Request-URI SP HTTP-Version CRLF
   // Status-Line     = HTTP-Version SP Status-Code SP Reason-Phrase CRLF
   // message-header  = field-name ":" [ field-value ]
+  //
+  // Per section 19.3 "Tolerant Applications" CRLF treats LF as a terminator
+  // and leading CR is ignored. Use of standalone CR is not allowed.
+
   void _doParse() {
     assert(!_parserCalled);
     _parserCalled = true;
@@ -570,10 +574,9 @@
           } else {
             if (byte == _CharCode.CR) {
               _state = _State.REQUEST_LINE_ENDING;
-            } else {
-              _expect(byte, _CharCode.LF);
-              _messageType = _MessageType.REQUEST;
-              _state = _State.HEADER_START;
+            } else if (byte == _CharCode.LF) {
+              _state = _State.REQUEST_LINE_ENDING;
+              _index = _index - 1; // Make the new state see the LF again.
             }
           }
           break;
@@ -588,9 +591,12 @@
           if (byte == _CharCode.SP) {
             _state = _State.RESPONSE_LINE_REASON_PHRASE;
           } else if (byte == _CharCode.CR) {
-            // Some HTTP servers does not follow the spec. and send
-            // \r\n right after the status code.
+            // Some HTTP servers do not follow the spec and send
+            // \r?\n right after the status code.
             _state = _State.RESPONSE_LINE_ENDING;
+          } else if (byte == _CharCode.LF) {
+            _state = _State.RESPONSE_LINE_ENDING;
+            _index = _index - 1; // Make the new state see the LF again.
           } else {
             _statusCodeLength++;
             if (byte < 0x30 || byte > 0x39) {
@@ -607,11 +613,10 @@
         case _State.RESPONSE_LINE_REASON_PHRASE:
           if (byte == _CharCode.CR) {
             _state = _State.RESPONSE_LINE_ENDING;
+          } else if (byte == _CharCode.LF) {
+            _state = _State.RESPONSE_LINE_ENDING;
+            _index = _index - 1; // Make the new state see the LF again.
           } else {
-            if (byte == _CharCode.CR || byte == _CharCode.LF) {
-              throw HttpException(
-                  "Invalid response, unexpected $byte in reason phrase");
-            }
             _addWithValidation(_uriOrReasonPhrase, byte);
           }
           break;
@@ -653,7 +658,7 @@
 
         case _State.HEADER_VALUE_START:
           if (byte == _CharCode.CR) {
-            _state = _State.HEADER_VALUE_FOLDING_OR_ENDING;
+            _state = _State.HEADER_VALUE_FOLD_OR_END_CR;
           } else if (byte == _CharCode.LF) {
             _state = _State.HEADER_VALUE_FOLD_OR_END;
           } else if (byte != _CharCode.SP && byte != _CharCode.HT) {
@@ -665,7 +670,7 @@
 
         case _State.HEADER_VALUE:
           if (byte == _CharCode.CR) {
-            _state = _State.HEADER_VALUE_FOLDING_OR_ENDING;
+            _state = _State.HEADER_VALUE_FOLD_OR_END_CR;
           } else if (byte == _CharCode.LF) {
             _state = _State.HEADER_VALUE_FOLD_OR_END;
           } else {
@@ -673,7 +678,7 @@
           }
           break;
 
-        case _State.HEADER_VALUE_FOLDING_OR_ENDING:
+        case _State.HEADER_VALUE_FOLD_OR_END_CR:
           _expect(byte, _CharCode.LF);
           _state = _State.HEADER_VALUE_FOLD_OR_END;
           break;
@@ -748,11 +753,16 @@
           break;
 
         case _State.CHUNK_SIZE_STARTING_CR:
+          if (byte == _CharCode.LF) {
+            _state = _State.CHUNK_SIZE_STARTING;
+            _index = _index - 1; // Make the new state see the LF again.
+            break;
+          }
           _expect(byte, _CharCode.CR);
-          _state = _State.CHUNK_SIZE_STARTING_LF;
+          _state = _State.CHUNK_SIZE_STARTING;
           break;
 
-        case _State.CHUNK_SIZE_STARTING_LF:
+        case _State.CHUNK_SIZE_STARTING:
           _expect(byte, _CharCode.LF);
           _state = _State.CHUNK_SIZE;
           break;
@@ -760,6 +770,9 @@
         case _State.CHUNK_SIZE:
           if (byte == _CharCode.CR) {
             _state = _State.CHUNK_SIZE_ENDING;
+          } else if (byte == _CharCode.LF) {
+            _state = _State.CHUNK_SIZE_ENDING;
+            _index = _index - 1; // Make the new state see the LF again.
           } else if (byte == _CharCode.SEMI_COLON) {
             _state = _State.CHUNK_SIZE_EXTENSION;
           } else {
@@ -775,6 +788,9 @@
         case _State.CHUNK_SIZE_EXTENSION:
           if (byte == _CharCode.CR) {
             _state = _State.CHUNK_SIZE_ENDING;
+          } else if (byte == _CharCode.LF) {
+            _state = _State.CHUNK_SIZE_ENDING;
+            _index = _index - 1; // Make the new state see the LF again.
           }
           break;
 
@@ -788,11 +804,15 @@
           break;
 
         case _State.CHUNKED_BODY_DONE_CR:
+          if (byte == _CharCode.LF) {
+            _state = _State.CHUNKED_BODY_DONE;
+            _index = _index - 1; // Make the new state see the LF again.
+            break;
+          }
           _expect(byte, _CharCode.CR);
-          _state = _State.CHUNKED_BODY_DONE_LF;
           break;
 
-        case _State.CHUNKED_BODY_DONE_LF:
+        case _State.CHUNKED_BODY_DONE:
           _expect(byte, _CharCode.LF);
           _reset();
           _closeIncoming();
diff --git a/sdk/lib/_http/overrides.dart b/sdk/lib/_http/overrides.dart
index bbd21ee..1fcc81d 100644
--- a/sdk/lib/_http/overrides.dart
+++ b/sdk/lib/_http/overrides.dart
@@ -13,7 +13,7 @@
 /// that construct a mock implementation. The implementation in this base class
 /// defaults to the actual [HttpClient] implementation. For example:
 ///
-/// ```
+/// ```dart
 /// class MyHttpClient implements HttpClient {
 ///   ...
 ///   // An implementation of the HttpClient interface
diff --git a/sdk/lib/_internal/fix_data.yaml b/sdk/lib/_internal/fix_data.yaml
index 2c6e8e9..1d4cc33 100644
--- a/sdk/lib/_internal/fix_data.yaml
+++ b/sdk/lib/_internal/fix_data.yaml
@@ -2,12 +2,13 @@
 # for details. All rights reserved. Use of this source code is governed by a
 # BSD-style license that can be found in the LICENSE file.
 
-# TODO(pq): Add link to public user guide when available.
-
 # Please add new fixes to the top of the file, separated by one blank line
 # from other fixes.  Add corresponding golden tests to 
 # `tests/lib/fix_data_tests` for each new fix.
 
+# For documentation about this file format, see
+# https://dart.dev/go/data-driven-fixes.
+
 version: 1
 transforms:
   - title: "Rename to 'read'"
diff --git a/sdk/lib/_internal/js_dev_runtime/patch/io_patch.dart b/sdk/lib/_internal/js_dev_runtime/patch/io_patch.dart
index 041dfd5..d0e0ba2 100644
--- a/sdk/lib/_internal/js_dev_runtime/patch/io_patch.dart
+++ b/sdk/lib/_internal/js_dev_runtime/patch/io_patch.dart
@@ -220,6 +220,14 @@
 }
 
 @patch
+class OSError {
+  @patch
+  static int inProgressErrorCode() {
+    throw new UnsupportedError("OSError.inProgressErrorCode");
+  }
+}
+
+@patch
 class _IOCrypto {
   @patch
   static Uint8List getRandomBytes(int count) {
diff --git a/sdk/lib/_internal/js_dev_runtime/private/js_number.dart b/sdk/lib/_internal/js_dev_runtime/private/js_number.dart
index c70de91..b90d786 100644
--- a/sdk/lib/_internal/js_dev_runtime/private/js_number.dart
+++ b/sdk/lib/_internal/js_dev_runtime/private/js_number.dart
@@ -335,13 +335,16 @@
     return _shrOtherPositive(other);
   }
 
-  int operator >>>(@nullCheck num other) =>
-    throw UnimplementedError('int.>>> is not implemented yet');
+  @notNull
+  int operator >>>(@nullCheck num other) {
+    if (JS<num>('!', '#', other) < 0) throwArgumentErrorValue(other);
+    return _shrUnsigned(other);
+  }
 
   @notNull
   int _shrOtherPositive(@notNull num other) {
     return JS<num>('!', '#', this) > 0
-        ? _shrBothPositive(other)
+        ? _shrUnsigned(other)
         // For negative numbers we just clamp the shift-by amount.
         // `this` could be negative but not have its 31st bit set.
         // The ">>" would then shift in 0s instead of 1s. Therefore
@@ -350,7 +353,7 @@
   }
 
   @notNull
-  int _shrBothPositive(@notNull num other) {
+  int _shrUnsigned(@notNull num other) {
     return JS<bool>('!', r'# > 31', other)
         // JavaScript only looks at the last 5 bits of the shift-amount. In JS
         // shifting by 33 is hence equivalent to a shift by 1. Shortcut the
diff --git a/sdk/lib/_internal/js_runtime/lib/async_patch.dart b/sdk/lib/_internal/js_runtime/lib/async_patch.dart
index 9c09d3d..3f1f0ad 100644
--- a/sdk/lib/_internal/js_runtime/lib/async_patch.dart
+++ b/sdk/lib/_internal/js_runtime/lib/async_patch.dart
@@ -206,8 +206,8 @@
     } else {
       // TODO(40014): Remove cast when type promotion works.
       // This would normally be `as T` but we use `as dynamic` to make the
-      // unneeded check be implict to match dart2js unsound optimizations in the
-      // user code.
+      // unneeded check be implicit to match dart2js unsound optimizations in
+      // the user code.
       _future._completeWithValue(value as dynamic);
     }
   }
diff --git a/sdk/lib/_internal/js_runtime/lib/io_patch.dart b/sdk/lib/_internal/js_runtime/lib/io_patch.dart
index 77a2530..fb7052f 100644
--- a/sdk/lib/_internal/js_runtime/lib/io_patch.dart
+++ b/sdk/lib/_internal/js_runtime/lib/io_patch.dart
@@ -228,6 +228,14 @@
 }
 
 @patch
+class OSError {
+  @patch
+  static int inProgressErrorCode() {
+    throw new UnsupportedError("OSError.inProgressErrorCode");
+  }
+}
+
+@patch
 class _Platform {
   @patch
   static int _numberOfProcessors() {
diff --git a/sdk/lib/_internal/js_runtime/lib/js_number.dart b/sdk/lib/_internal/js_runtime/lib/js_number.dart
index 1d3ad24..d0f0c71 100644
--- a/sdk/lib/_internal/js_runtime/lib/js_number.dart
+++ b/sdk/lib/_internal/js_runtime/lib/js_number.dart
@@ -404,9 +404,6 @@
     return _shrOtherPositive(other);
   }
 
-  num operator >>>(num other) =>
-    throw UnimplementedError('int.>>> is not implemented yet');
-
   num _shrOtherPositive(num other) {
     return JS('num', '#', this) > 0
         ? _shrBothPositive(other)
@@ -434,6 +431,17 @@
         : JS('JSUInt32', r'# >>> #', this, other);
   }
 
+  num operator >>>(num other) {
+    if (other is! num) throw argumentErrorValue(other);
+    if (other < 0) throw argumentErrorValue(other);
+    return _shruOtherPositive(other);
+  }
+
+  num _shruOtherPositive(num other) {
+    if (other > 31) return 0;
+    return JS('JSUInt32', r'# >>> #', this, other);
+  }
+
   num operator &(num other) {
     if (other is! num) throw argumentErrorValue(other);
     return JS('JSUInt32', r'(# & #) >>> 0', this, other);
diff --git a/sdk/lib/_internal/vm/bin/common_patch.dart b/sdk/lib/_internal/vm/bin/common_patch.dart
index f788ec7..45e8ac1 100644
--- a/sdk/lib/_internal/vm/bin/common_patch.dart
+++ b/sdk/lib/_internal/vm/bin/common_patch.dart
@@ -63,6 +63,12 @@
 }
 
 @patch
+class OSError {
+  @patch
+  static int inProgressErrorCode() native "OSError_inProgressErrorCode";
+}
+
+@patch
 class _IOCrypto {
   @patch
   static Uint8List getRandomBytes(int count) native "Crypto_GetRandomBytes";
diff --git a/sdk/lib/_internal/vm/bin/socket_patch.dart b/sdk/lib/_internal/vm/bin/socket_patch.dart
index 339d9a7..a20a0bb 100644
--- a/sdk/lib/_internal/vm/bin/socket_patch.dart
+++ b/sdk/lib/_internal/vm/bin/socket_patch.dart
@@ -491,7 +491,7 @@
   // a HttpServer, a WebSocket connection, a process pipe, etc.
   Object? owner;
 
-  static Future<List<_InternetAddress>> lookup(String host,
+  static Future<List<InternetAddress>> lookup(String host,
       {InternetAddressType type: InternetAddressType.any}) {
     return _IOService._dispatch(_IOService.socketLookup, [host, type._value])
         .then((response) {
@@ -506,9 +506,9 @@
     });
   }
 
-  static Stream<List<_InternetAddress>> lookupAsStream(String host,
+  static Stream<List<InternetAddress>> lookupAsStream(String host,
       {InternetAddressType type: InternetAddressType.any}) {
-    final controller = StreamController<List<_InternetAddress>>();
+    final controller = StreamController<List<InternetAddress>>();
     controller.onListen = () {
       lookup(host, type: type).then((list) {
         controller.add(list);
@@ -588,8 +588,8 @@
   /// This avoids making single OS lookup request that internally does both IPv4
   /// and IPv6 together, which on iOS sometimes seems to be taking unreasonably
   /// long because of slow IPv6 lookup even though IPv4 lookup is fast.
-  static Stream<List<_InternetAddress>> staggeredLookup(String host) {
-    final controller = StreamController<List<_InternetAddress>>(sync: true);
+  static Stream<List<InternetAddress>> staggeredLookup(String host) {
+    final controller = StreamController<List<InternetAddress>>(sync: true);
 
     controller.onListen = () {
       // Completed when there are no further addresses, or when the returned
@@ -684,7 +684,7 @@
       // so we run IPv4 and IPv6 name resolution in parallel(IPv6 slightly
       // delayed so if IPv4 is successfully looked up, we don't do IPv6 look up
       // at all) and grab first successfully resolved name we are able to connect to.
-      final Stream<List<_InternetAddress>> stream =
+      final Stream<List<InternetAddress>> stream =
           Platform.isIOS || staggeredLookupOverride
               ? staggeredLookup(hostname)
               : lookupAsStream(hostname);
@@ -697,7 +697,7 @@
       dynamic host,
       int port,
       _InternetAddress? source,
-      Stream<List<_InternetAddress>> addresses) {
+      Stream<List<InternetAddress>> addresses) {
     // Completer for result.
     final result = new Completer<_NativeSocket>();
     // Error, set if an error occurs.
@@ -713,14 +713,14 @@
     Timer? timer;
     // Addresses arrived from lookup stream, but haven't been tried to connect
     // to yet due to Timer-based throttling.
-    final pendingLookedUp = Queue<_InternetAddress>();
+    final pendingLookedUp = Queue<InternetAddress>();
 
     // When deciding how to handle errors we need to know whether more
     // addresses potentially are coming from the lookup stream.
     bool isLookedUpStreamClosed = false;
-    late StreamSubscription<List<_InternetAddress>> addressesSubscription;
+    late StreamSubscription<List<InternetAddress>> addressesSubscription;
 
-    Object? createConnection(_InternetAddress address, _InternetAddress? source,
+    Object? createConnection(InternetAddress address, _InternetAddress? source,
         _NativeSocket socket) {
       Object? connectionResult;
       if (address.type == InternetAddressType.unix) {
@@ -736,19 +736,20 @@
             connectionResult is Error ||
             connectionResult is OSError);
       } else {
+        final address_ = address as _InternetAddress;
         if (source == null) {
           connectionResult = socket.nativeCreateConnect(
-              address._in_addr, port, address._scope_id);
+              address_._in_addr, port, address_._scope_id);
         } else {
           connectionResult = socket.nativeCreateBindConnect(
-              address._in_addr, port, source._in_addr, address._scope_id);
+              address_._in_addr, port, source._in_addr, address_._scope_id);
         }
         assert(connectionResult == true || connectionResult is OSError);
       }
       return connectionResult;
     }
 
-    createConnectionError(Object? connectionResult, _InternetAddress address,
+    createConnectionError(Object? connectionResult, InternetAddress address,
         int port, _NativeSocket socket) {
       if (connectionResult is OSError) {
         final errorCode = connectionResult.errorCode;
@@ -801,9 +802,17 @@
       try {
         socket.port;
       } catch (e) {
-        error ??= createError(e, "Connection failed", address, port);
-        connectNext(); // Try again after failure to connect.
-        return;
+        if (e is OSError && e.errorCode == OSError.inProgressErrorCode()) {
+          // Ignore the error, proceed with waiting for a socket to become open.
+          // In non-blocking mode connect might not be established away, socket
+          // have to be waited for.
+          // EINPROGRESS error is ignored during |connect| call in native code,
+          // it has be ignored here during |port| query here.
+        } else {
+          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.
@@ -1145,7 +1154,11 @@
     if (localAddress.type == InternetAddressType.unix) return 0;
     if (localPort != 0) return localPort;
     if (isClosing || isClosed) throw const SocketException.closed();
-    return localPort = nativeGetPort();
+    var result = nativeGetPort();
+    if (result is OSError) {
+      throw result;
+    }
+    return localPort = result;
   }
 
   int get remotePort {
@@ -1529,7 +1542,7 @@
   nativeCreateBindDatagram(Uint8List addr, int port, bool reuseAddress,
       bool reusePort, int ttl) native "Socket_CreateBindDatagram";
   bool nativeAccept(_NativeSocket socket) native "ServerSocket_Accept";
-  int nativeGetPort() native "Socket_GetPort";
+  dynamic nativeGetPort() native "Socket_GetPort";
   List nativeGetRemotePeer() native "Socket_GetRemotePeer";
   int nativeGetSocketId() native "Socket_GetSocketId";
   OSError nativeGetError() native "Socket_GetError";
diff --git a/sdk/lib/_internal/vm/lib/array_patch.dart b/sdk/lib/_internal/vm/lib/array_patch.dart
index f6edca3..92824e6 100644
--- a/sdk/lib/_internal/vm/lib/array_patch.dart
+++ b/sdk/lib/_internal/vm/lib/array_patch.dart
@@ -71,3 +71,17 @@
     return makeFixedListUnmodifiable(result);
   }
 }
+
+// Used by Dart_ListLength.
+@pragma("vm:entry-point", "call")
+int _listLength(List list) => list.length;
+
+// Used by Dart_ListGetRange, Dart_ListGetAsBytes.
+@pragma("vm:entry-point", "call")
+Object? _listGetAt(List list, int index) => list[index];
+
+// Used by Dart_ListSetAt, Dart_ListSetAsBytes.
+@pragma("vm:entry-point", "call")
+void _listSetAt(List list, int index, Object? value) {
+  list[index] = value;
+}
diff --git a/sdk/lib/_internal/vm/lib/convert_patch.dart b/sdk/lib/_internal/vm/lib/convert_patch.dart
index 851c554..22bf67c 100644
--- a/sdk/lib/_internal/vm/lib/convert_patch.dart
+++ b/sdk/lib/_internal/vm/lib/convert_patch.dart
@@ -1675,7 +1675,11 @@
       "QQQQQQQQQQQQQQQQRRRRRbbbbbbbbbbb" // E0-FF
       ;
 
-  /// Max chunk to scan at a time. Avoids staying away from safepoints too long.
+  /// Max chunk to scan at a time.
+  ///
+  /// Avoids staying away from safepoints too long.
+  /// The Utf8ScanInstr relies on this being small enough to ensure the
+  /// decoded length stays within Smi range.
   static const int scanChunkSize = 65536;
 
   /// Reset the decoder to a state where it is ready to decode a new string but
diff --git a/sdk/lib/_internal/vm/lib/ffi_dynamic_library_patch.dart b/sdk/lib/_internal/vm/lib/ffi_dynamic_library_patch.dart
index 303c5a4..655006c 100644
--- a/sdk/lib/_internal/vm/lib/ffi_dynamic_library_patch.dart
+++ b/sdk/lib/_internal/vm/lib/ffi_dynamic_library_patch.dart
@@ -8,7 +8,7 @@
 import 'dart:typed_data';
 import 'dart:isolate';
 
-DynamicLibrary _open(String name) native "Ffi_dl_open";
+DynamicLibrary _open(String path) native "Ffi_dl_open";
 DynamicLibrary _processLibrary() native "Ffi_dl_processLibrary";
 DynamicLibrary _executableLibrary() native "Ffi_dl_executableLibrary";
 
@@ -16,8 +16,8 @@
 @pragma("vm:entry-point")
 class DynamicLibrary {
   @patch
-  factory DynamicLibrary.open(String name) {
-    return _open(name);
+  factory DynamicLibrary.open(String path) {
+    return _open(path);
   }
 
   @patch
diff --git a/sdk/lib/_internal/vm/lib/ffi_patch.dart b/sdk/lib/_internal/vm/lib/ffi_patch.dart
index 38dbcda..c9c3861 100644
--- a/sdk/lib/_internal/vm/lib/ffi_patch.dart
+++ b/sdk/lib/_internal/vm/lib/ffi_patch.dart
@@ -115,22 +115,23 @@
   final int _size;
 
   @pragma("vm:entry-point")
-  Array._(this._typedDataBase, this._size);
+  final List<int> _nestedDimensions;
+
+  @pragma("vm:entry-point")
+  Array._(this._typedDataBase, this._size, this._nestedDimensions);
+
+  late final int _nestedDimensionsFlattened = _nestedDimensions.fold(
+      1, (accumulator, element) => accumulator * element);
+
+  late final int _nestedDimensionsFirst = _nestedDimensions.first;
+
+  late final List<int> _nestedDimensionsRest = _nestedDimensions.sublist(1);
 
   _checkIndex(int index) {
     if (index < 0 || index >= _size) {
-      throw RangeError.range(index, 0, _size);
+      throw RangeError.range(index, 0, _size - 1);
     }
   }
-
-  @patch
-  const factory Array(int dimension1) = _ArraySize<T>;
-}
-
-class _ArraySize<T extends NativeType> implements Array<T> {
-  final int dimension1;
-
-  const _ArraySize(this.dimension1);
 }
 
 /// Returns an integer encoding the ABI used for size and alignment
@@ -228,6 +229,14 @@
     native "Ffi_loadDouble";
 
 @pragma("vm:recognized", "other")
+double _loadFloatUnaligned(Object typedDataBase, int offsetInBytes)
+    native "Ffi_loadFloatUnaligned";
+
+@pragma("vm:recognized", "other")
+double _loadDoubleUnaligned(Object typedDataBase, int offsetInBytes)
+    native "Ffi_loadDoubleUnaligned";
+
+@pragma("vm:recognized", "other")
 Pointer<S> _loadPointer<S extends NativeType>(
     Object typedDataBase, int offsetInBytes) native "Ffi_loadPointer";
 
@@ -276,6 +285,14 @@
     native "Ffi_storeDouble";
 
 @pragma("vm:recognized", "other")
+void _storeFloatUnaligned(Object typedDataBase, int offsetInBytes, double value)
+    native "Ffi_storeFloatUnaligned";
+
+@pragma("vm:recognized", "other")
+void _storeDoubleUnaligned(Object typedDataBase, int offsetInBytes,
+    double value) native "Ffi_storeDoubleUnaligned";
+
+@pragma("vm:recognized", "other")
 void _storePointer<S extends NativeType>(Object typedDataBase,
     int offsetInBytes, Pointer<S> value) native "Ffi_storePointer";
 
@@ -699,11 +716,22 @@
 
 extension PointerArray<T extends NativeType> on Array<Pointer<T>> {
   @patch
-  Pointer<T> operator [](int index) => _loadPointer(this, _intPtrSize * index);
+  Pointer<T> operator [](int index) =>
+      _loadPointer(_typedDataBase, _intPtrSize * index);
 
   @patch
   void operator []=(int index, Pointer<T> value) =>
-      _storePointer(this, _intPtrSize * index, value);
+      _storePointer(_typedDataBase, _intPtrSize * index, value);
+}
+
+extension ArrayArray<T extends NativeType> on Array<Array<T>> {
+  @patch
+  Array<T> operator [](int index) =>
+      throw "UNREACHABLE: This case should have been rewritten in the CFE.";
+
+  @patch
+  void operator []=(int index, Array<T> value) =>
+      throw "UNREACHABLE: This case should have been rewritten in the CFE.";
 }
 
 extension StructArray<T extends Struct> on Array<T> {
diff --git a/sdk/lib/_internal/vm/lib/ffi_struct_patch.dart b/sdk/lib/_internal/vm/lib/ffi_struct_patch.dart
index 3391e88..1dd4726 100644
--- a/sdk/lib/_internal/vm/lib/ffi_struct_patch.dart
+++ b/sdk/lib/_internal/vm/lib/ffi_struct_patch.dart
@@ -16,7 +16,10 @@
   @pragma("vm:entry-point")
   final List<Object> fieldTypes;
 
-  const _FfiStructLayout(this.fieldTypes);
+  @pragma("vm:entry-point")
+  final int? packing;
+
+  const _FfiStructLayout(this.fieldTypes, this.packing);
 }
 
 @pragma("vm:entry-point")
diff --git a/sdk/lib/_internal/vm/lib/integers.dart b/sdk/lib/_internal/vm/lib/integers.dart
index 123c964..95e3826 100644
--- a/sdk/lib/_internal/vm/lib/integers.dart
+++ b/sdk/lib/_internal/vm/lib/integers.dart
@@ -5,22 +5,26 @@
 // part of "core_patch.dart";
 
 abstract class _IntegerImplementation implements int {
-  @pragma("vm:recognized", "asm-intrinsic")
+  @pragma("vm:recognized", "graph-intrinsic")
   @pragma("vm:non-nullable-result-type")
   @pragma("vm:never-inline")
+  @pragma("vm:disable-unboxed-parameters")
   num operator +(num other) => other._addFromInteger(this);
-  @pragma("vm:recognized", "asm-intrinsic")
+  @pragma("vm:recognized", "graph-intrinsic")
   @pragma("vm:non-nullable-result-type")
   @pragma("vm:never-inline")
+  @pragma("vm:disable-unboxed-parameters")
   num operator -(num other) => other._subFromInteger(this);
-  @pragma("vm:recognized", "asm-intrinsic")
+  @pragma("vm:recognized", "graph-intrinsic")
   @pragma("vm:non-nullable-result-type")
   @pragma("vm:never-inline")
+  @pragma("vm:disable-unboxed-parameters")
   num operator *(num other) => other._mulFromInteger(this);
 
-  @pragma("vm:recognized", "asm-intrinsic")
+  @pragma("vm:recognized", "graph-intrinsic")
   @pragma("vm:non-nullable-result-type")
   @pragma("vm:never-inline")
+  @pragma("vm:disable-unboxed-parameters")
   int operator ~/(num other) {
     if ((other is int) && (other == 0)) {
       throw const IntegerDivisionByZeroException();
@@ -32,9 +36,10 @@
     return this.toDouble() / other.toDouble();
   }
 
-  @pragma("vm:recognized", "asm-intrinsic")
+  @pragma("vm:recognized", "graph-intrinsic")
   @pragma("vm:non-nullable-result-type")
   @pragma("vm:never-inline")
+  @pragma("vm:disable-unboxed-parameters")
   num operator %(num other) {
     if ((other is int) && (other == 0)) {
       throw const IntegerDivisionByZeroException();
@@ -42,26 +47,30 @@
     return other._moduloFromInteger(this);
   }
 
-  @pragma("vm:recognized", "asm-intrinsic")
+  @pragma("vm:recognized", "graph-intrinsic")
   @pragma("vm:non-nullable-result-type")
   @pragma("vm:never-inline")
+  @pragma("vm:disable-unboxed-parameters")
   int operator -() {
     // Issue(https://dartbug.com/39639): The analyzer incorrectly reports the
     // result type as `num`.
     return unsafeCast<int>(0 - this);
   }
 
-  @pragma("vm:recognized", "asm-intrinsic")
+  @pragma("vm:recognized", "graph-intrinsic")
   @pragma("vm:non-nullable-result-type")
   @pragma("vm:never-inline")
+  @pragma("vm:disable-unboxed-parameters")
   int operator &(int other) => other._bitAndFromInteger(this);
-  @pragma("vm:recognized", "asm-intrinsic")
+  @pragma("vm:recognized", "graph-intrinsic")
   @pragma("vm:non-nullable-result-type")
   @pragma("vm:never-inline")
+  @pragma("vm:disable-unboxed-parameters")
   int operator |(int other) => other._bitOrFromInteger(this);
-  @pragma("vm:recognized", "asm-intrinsic")
+  @pragma("vm:recognized", "graph-intrinsic")
   @pragma("vm:non-nullable-result-type")
   @pragma("vm:never-inline")
+  @pragma("vm:disable-unboxed-parameters")
   int operator ^(int other) => other._bitXorFromInteger(this);
 
   num remainder(num other) {
@@ -96,15 +105,20 @@
     return unsafeCast<int>(other - (other ~/ this) * this);
   }
 
-  @pragma("vm:recognized", "asm-intrinsic")
+  @pragma("vm:recognized", "graph-intrinsic")
   @pragma("vm:non-nullable-result-type")
   @pragma("vm:never-inline")
+  @pragma("vm:disable-unboxed-parameters")
   int operator >>(int other) => other._shrFromInteger(this);
+  @pragma("vm:recognized", "graph-intrinsic")
+  @pragma("vm:non-nullable-result-type")
   @pragma("vm:never-inline")
+  @pragma("vm:disable-unboxed-parameters")
   int operator >>>(int other) => other._ushrFromInteger(this);
   @pragma("vm:recognized", "asm-intrinsic")
   @pragma("vm:non-nullable-result-type")
   @pragma("vm:never-inline")
+  @pragma("vm:disable-unboxed-parameters")
   int operator <<(int other) => other._shlFromInteger(this);
 
   @pragma("vm:recognized", "asm-intrinsic")
@@ -540,8 +554,9 @@
 
   int get hashCode => this;
   int get _identityHashCode => this;
-  @pragma("vm:recognized", "asm-intrinsic")
+  @pragma("vm:recognized", "graph-intrinsic")
   @pragma("vm:exact-result-type", "dart:core#_Smi")
+  @pragma("vm:disable-unboxed-parameters")
   int operator ~() native "Smi_bitNegate";
   @pragma("vm:recognized", "asm-intrinsic")
   @pragma("vm:exact-result-type", "dart:core#_Smi")
diff --git a/sdk/lib/_internal/vm/lib/map_patch.dart b/sdk/lib/_internal/vm/lib/map_patch.dart
index 07dbc69..3e6b3db 100644
--- a/sdk/lib/_internal/vm/lib/map_patch.dart
+++ b/sdk/lib/_internal/vm/lib/map_patch.dart
@@ -29,3 +29,15 @@
   @patch
   factory Map() => new LinkedHashMap<K, V>();
 }
+
+// Used by Dart_MapContainsKey.
+@pragma("vm:entry-point", "call")
+bool _mapContainsKey(Map map, Object? key) => map.containsKey(key);
+
+// Used by Dart_MapGetAt.
+@pragma("vm:entry-point", "call")
+Object? _mapGet(Map map, Object? key) => map[key];
+
+// Used by Dart_MapKeys.
+@pragma("vm:entry-point", "call")
+List _mapKeys(Map map) => map.keys.toList();
diff --git a/sdk/lib/_internal/vm/lib/math_patch.dart b/sdk/lib/_internal/vm/lib/math_patch.dart
index 0e384ca..167f3f5 100644
--- a/sdk/lib/_internal/vm/lib/math_patch.dart
+++ b/sdk/lib/_internal/vm/lib/math_patch.dart
@@ -161,10 +161,14 @@
 @pragma("vm:never-inline")
 double sqrt(num x) => _sqrt(x.toDouble());
 @patch
-@pragma("vm:prefer-inline")
+@pragma("vm:recognized", "graph-intrinsic")
+@pragma("vm:exact-result-type", "dart:core#_Double")
+@pragma("vm:never-inline")
 double exp(num x) => _exp(x.toDouble());
 @patch
-@pragma("vm:prefer-inline")
+@pragma("vm:recognized", "graph-intrinsic")
+@pragma("vm:exact-result-type", "dart:core#_Double")
+@pragma("vm:never-inline")
 double log(num x) => _log(x.toDouble());
 
 double _atan2(double a, double b) native "Math_atan2";
diff --git a/sdk/lib/_internal/vm/lib/object_patch.dart b/sdk/lib/_internal/vm/lib/object_patch.dart
index ac85705..0c20579 100644
--- a/sdk/lib/_internal/vm/lib/object_patch.dart
+++ b/sdk/lib/_internal/vm/lib/object_patch.dart
@@ -78,3 +78,20 @@
   @pragma("vm:entry-point", "call")
   bool _simpleInstanceOfFalse(type) => false;
 }
+
+// Used by DartLibraryCalls::Equals.
+@pragma("vm:entry-point", "call")
+bool _objectEquals(Object? o1, Object? o2) => o1 == o2;
+
+// Used by DartLibraryCalls::HashCode.
+@pragma("vm:entry-point", "call")
+int _objectHashCode(Object? obj) => obj.hashCode;
+
+// Used by DartLibraryCalls::ToString.
+@pragma("vm:entry-point", "call")
+String _objectToString(Object? obj) => obj.toString();
+
+// Used by DartEntry::InvokeNoSuchMethod.
+@pragma("vm:entry-point", "call")
+dynamic _objectNoSuchMethod(Object? obj, Invocation invocation) =>
+    obj.noSuchMethod(invocation);
diff --git a/sdk/lib/async/future.dart b/sdk/lib/async/future.dart
index c8c1403..4d98a53 100644
--- a/sdk/lib/async/future.dart
+++ b/sdk/lib/async/future.dart
@@ -14,7 +14,7 @@
 /// `FutureOr`.
 ///
 /// # Examples
-/// ``` dart
+/// ```dart
 /// // The `Future<T>.then` function takes a callback [f] that returns either
 /// // an `S` or a `Future<S>`.
 /// Future<S> then<S>(FutureOr<S> f(T x), ...);
@@ -73,7 +73,7 @@
 /// corresponding callback.
 /// The successor is completed with an error if the invoked callback throws.
 /// For example:
-/// ```
+/// ```dart
 /// Future<int> successor = future.then((int value) {
 ///     // Invoked when the future is completed with a value.
 ///     return 42;  // The successor is completed with the value 42.
@@ -94,7 +94,7 @@
 /// However, it also means that error handlers should be installed early,
 /// so that they are present as soon as a future is completed with an error.
 /// The following example demonstrates this potential bug:
-/// ```
+/// ```dart
 /// var future = getFuture();
 /// Timer(const Duration(milliseconds: 5), () {
 ///   // The error-handler is not attached until 5 ms after the future has
@@ -116,7 +116,7 @@
 /// Using sequential handlers instead of parallel ones often leads to code that
 /// is easier to reason about.
 /// It also makes asynchronous code very similar to synchronous code:
-/// ```
+/// ```dart
 /// // Synchronous code.
 /// try {
 ///   int value = foo();
@@ -127,7 +127,7 @@
 /// ```
 ///
 /// Equivalent asynchronous code, based on futures:
-/// ```
+/// ```dart
 /// Future<int> future = Future(foo);  // Result of foo() as a future.
 /// future.then((int value) => bar(value))
 ///       .catchError((e) => 499);
@@ -796,13 +796,13 @@
 /// Most of the time, the simplest way to create a future is to just use
 /// one of the [Future] constructors to capture the result of a single
 /// asynchronous computation:
-/// ```
+/// ```dart
 /// Future(() { doSomething(); return result; });
 /// ```
 /// or, if the future represents the result of a sequence of asynchronous
 /// computations, they can be chained using [Future.then] or similar functions
 /// on [Future]:
-/// ```
+/// ```dart
 /// Future doStuff(){
 ///   return someAsyncOperation().then((result) {
 ///     return someOtherAsyncOperation(result);
@@ -812,7 +812,7 @@
 /// If you do need to create a Future from scratch — for example,
 /// when you're converting a callback-based API into a Future-based
 /// one — you can use a Completer as follows:
-/// ```
+/// ```dart
 /// class AsyncOperation {
 ///   final Completer _completer = new Completer();
 ///
@@ -845,7 +845,7 @@
   /// delayed until a later microtask.
   ///
   /// Example:
-  /// ```
+  /// ```dart
   /// var completer = new Completer();
   /// handOut(completer.future);
   /// later: {
@@ -935,11 +935,11 @@
   ///
   /// If `error` is a `Future`, the future itself is used as the error value.
   /// If you want to complete with the result of the future, you can use:
-  /// ```
+  /// ```dart
   /// thisCompleter.complete(theFuture)
   /// ```
   /// or if you only want to handle an error from the future:
-  /// ```
+  /// ```dart
   /// theFuture.catchError(thisCompleter.completeError);
   /// ```
   void completeError(Object error, [StackTrace? stackTrace]);
diff --git a/sdk/lib/async/future_impl.dart b/sdk/lib/async/future_impl.dart
index 5f9117b..e73300f 100644
--- a/sdk/lib/async/future_impl.dart
+++ b/sdk/lib/async/future_impl.dart
@@ -306,7 +306,7 @@
   /// Registers a system created result and error continuation.
   ///
   /// Used by the implementation of `await` to listen to a future.
-  /// The system created liseners are not registered in the zone,
+  /// The system created listeners are not registered in the zone,
   /// and the listener is marked as being from an `await`.
   /// This marker is used in [_continuationFunctions].
   Future<E> _thenAwait<E>(FutureOr<E> f(T value), Function onError) {
@@ -527,8 +527,8 @@
       _FutureListener? listeners = _removeListeners();
       // TODO(40014): Remove cast when type promotion works.
       // This would normally be `as T` but we use `as dynamic` to make the
-      // unneeded check be implict to match dart2js unsound optimizations in the
-      // user code.
+      // unneeded check be implicit to match dart2js unsound optimizations in
+      // the user code.
       _setValue(value as dynamic); // Value promoted to T.
       _propagateToListeners(this, listeners);
     }
@@ -569,7 +569,7 @@
     }
     // TODO(40014): Remove cast when type promotion works.
     // This would normally be `as T` but we use `as dynamic` to make the
-    // unneeded check be implict to match dart2js unsound optimizations in the
+    // unneeded check be implicit to match dart2js unsound optimizations in the
     // user code.
     _asyncCompleteWithValue(value as dynamic); // Value promoted to T.
   }
diff --git a/sdk/lib/async/stream.dart b/sdk/lib/async/stream.dart
index f779e02..131b66a 100644
--- a/sdk/lib/async/stream.dart
+++ b/sdk/lib/async/stream.dart
@@ -704,7 +704,7 @@
   /// that is, the result of `streamTransformer.bind(this)`.
   /// This method simply allows writing the call to `streamTransformer.bind`
   /// in a chained fashion, like
-  /// ```
+  /// ```dart
   /// stream.map(mapping).transform(transformation).toList()
   /// ```
   /// which can be more convenient than calling `bind` directly.
@@ -1892,7 +1892,7 @@
   ///
   /// Example:
   ///
-  /// ```
+  /// ```dart
   /// /// Starts listening to [input] and duplicates all non-error events.
   /// StreamSubscription<int> _onListen(Stream<int> input, bool cancelOnError) {
   ///   late StreamSubscription<String> subscription;
@@ -1937,7 +1937,7 @@
   ///
   /// Example use of a duplicating transformer:
   ///
-  /// ```
+  /// ```dart
   /// stringStream.transform(StreamTransformer<String, String>.fromHandlers(
   ///     handleData: (String value, EventSink<String> sink) {
   ///       sink.add(value);
@@ -1947,7 +1947,8 @@
   ///
   /// Transformers that are constructed this way cannot use captured state if
   /// they are used in streams that can be listened to multiple times.
-  /// ```
+  ///
+  /// ```dart
   /// StreamController<String> controller = StreamController.broadcast()
   /// controller.onListen = () {
   ///   scheduleMicrotask(() {
@@ -2180,7 +2181,7 @@
   /// Delivery can be delayed if other previously added events are
   /// still pending delivery, if the subscription is paused,
   /// or if the subscription isn't listening yet.
-  /// If it's necessary to know whether the "done" event has been delievered,
+  /// If it's necessary to know whether the "done" event has been delivered,
   /// [done] future will complete when that has happened.
   void closeSync();
 }
diff --git a/sdk/lib/async/stream_controller.dart b/sdk/lib/async/stream_controller.dart
index cb305fe..7121af8 100644
--- a/sdk/lib/async/stream_controller.dart
+++ b/sdk/lib/async/stream_controller.dart
@@ -217,7 +217,7 @@
   /// even if listeners are paused, so some broadcast events may not have been
   /// received yet when the returned future completes.
   ///
-  /// If noone listens to a non-broadcast stream,
+  /// If no one listens to a non-broadcast stream,
   /// or the listener pauses and never resumes,
   /// the done event will not be sent and this future will never complete.
   Future close();
diff --git a/sdk/lib/async/stream_impl.dart b/sdk/lib/async/stream_impl.dart
index 02c4504..3de0d58 100644
--- a/sdk/lib/async/stream_impl.dart
+++ b/sdk/lib/async/stream_impl.dart
@@ -476,7 +476,7 @@
   }
 
   // -------------------------------------------------------------------
-  /// Create a subscription object. Called by [subcribe].
+  /// Create a subscription object. Called by [subscribe].
   StreamSubscription<T> _createSubscription(void onData(T data)?,
       Function? onError, void onDone()?, bool cancelOnError) {
     return new _BufferingStreamSubscription<T>(
diff --git a/sdk/lib/async/zone.dart b/sdk/lib/async/zone.dart
index a96cdfb..9301ce3 100644
--- a/sdk/lib/async/zone.dart
+++ b/sdk/lib/async/zone.dart
@@ -135,7 +135,7 @@
 ///
 /// The function should return either `null` if it doesn't want
 /// to replace the original error and stack trace,
-/// or an [AsyncError] containg a replacement error and stack trace
+/// or an [AsyncError] containing a replacement error and stack trace
 /// which will be used to replace the originals.
 typedef AsyncError? ErrorCallbackHandler(Zone self, ZoneDelegate parent,
     Zone zone, Object error, StackTrace? stackTrace);
@@ -285,7 +285,7 @@
 /// A zone specification is a parameter object passed to [Zone.fork]
 /// and any underlying [ForkHandler] custom implementations.
 /// The individual handlers, if set to a non-null value,
-/// will be the implementation of the correpsonding [Zone] methods
+/// will be the implementation of the corresponding [Zone] methods
 /// for a forked zone created using this zone specification.
 ///
 /// Handlers have the same signature as the same-named methods on [Zone],
@@ -327,7 +327,7 @@
   /// The created zone specification has the handlers of [other]
   /// and any individually provided handlers.
   /// If a handler is provided both through [other] and individually,
-  /// the individually provided handler overries the one from [other].
+  /// the individually provided handler overrides the one from [other].
   factory ZoneSpecification.from(ZoneSpecification other,
       {HandleUncaughtErrorHandler? handleUncaughtError,
       RunHandler? run,
@@ -604,7 +604,7 @@
   /// different error handlers.
   ///
   /// Example:
-  /// ```
+  /// ```dart
   /// import 'dart:async';
   ///
   /// main() {
@@ -623,7 +623,7 @@
   ///
   /// Note that errors cannot enter a child zone with a different error handler
   /// either:
-  /// ```
+  /// ```dart
   /// import 'dart:async';
   ///
   /// main() {
@@ -657,7 +657,7 @@
   /// of this zone and updates them with values from [zoneValues], which either
   /// adds new values or overrides existing ones.
   ///
-  /// Note that the fork operation is interceptible. A zone can thus change
+  /// Note that the fork operation is interceptable. A zone can thus change
   /// the zone specification (or zone values), giving the forking zone full
   /// control over the child zone.
   Zone fork(
@@ -693,7 +693,7 @@
   /// errors.
   ///
   /// This function is equivalent to:
-  /// ```
+  /// ```dart
   /// try {
   ///   this.run(action);
   /// } catch (e, s) {
@@ -864,7 +864,7 @@
   /// function which makes it possible to intercept printing.
   ///
   /// Example:
-  /// ```
+  /// ```dart
   /// import 'dart:async';
   ///
   /// main() {
diff --git a/sdk/lib/cli/wait_for.dart b/sdk/lib/cli/wait_for.dart
index 35cb307..58990c8 100644
--- a/sdk/lib/cli/wait_for.dart
+++ b/sdk/lib/cli/wait_for.dart
@@ -129,7 +129,7 @@
   if (timeout != null) {
     s = new Stopwatch()..start();
   }
-  Timer.run(() {}); // Enusre there is at least one message.
+  Timer.run(() {}); // Ensure there is at least one message.
   while (!futureCompleted && (error == null)) {
     Duration? remaining;
     if (timeout != null) {
diff --git a/sdk/lib/collection/list.dart b/sdk/lib/collection/list.dart
index 0762f4b..07f1e2b 100644
--- a/sdk/lib/collection/list.dart
+++ b/sdk/lib/collection/list.dart
@@ -12,9 +12,9 @@
 /// This class implements all read operations using only the `length` and
 /// `operator[]` and members. It implements write operations using those and
 /// `add`, `length=` and `operator[]=`
-/// Classes using this base classs  should implement those five operations.
+/// Classes using this base class should implement those five operations.
 ///
-/// **NOTICE**: For backwards compatability reasons,
+/// **NOTICE**: For backwards compatibility reasons,
 /// there is a default implementation of `add`
 /// which only works for lists with a nullable element type.
 /// For list with a non-nullable element type,
@@ -53,7 +53,7 @@
 /// `add`, `length=` and `operator[]=`.
 /// Classes using this mixin should implement those five operations.
 ///
-/// **NOTICE**: For backwards compatability reasons,
+/// **NOTICE**: For backwards compatibility reasons,
 /// there is a default implementation of `add`
 /// which only works for lists with a nullable element type.
 /// For lists with a non-nullable element type,
diff --git a/sdk/lib/collection/splay_tree.dart b/sdk/lib/collection/splay_tree.dart
index 2ad35f6..5770c5b 100644
--- a/sdk/lib/collection/splay_tree.dart
+++ b/sdk/lib/collection/splay_tree.dart
@@ -11,8 +11,8 @@
 class _SplayTreeNode<K, Node extends _SplayTreeNode<K, Node>> {
   final K key;
 
-  Node? left;
-  Node? right;
+  Node? _left;
+  Node? _right;
 
   _SplayTreeNode(this.key);
 }
@@ -24,11 +24,19 @@
 
 /// A node in a splay tree based map.
 ///
-/// A [_SplayTreeNode] that also contains a value
-class _SplayTreeMapNode<K, V>
-    extends _SplayTreeNode<K, _SplayTreeMapNode<K, V>> {
-  V value;
+/// A [_SplayTreeNode] that also contains a value,
+/// and which implements [MapEntry].
+class _SplayTreeMapNode<K, V> extends _SplayTreeNode<K, _SplayTreeMapNode<K, V>>
+    implements MapEntry<K, V> {
+  final V value;
   _SplayTreeMapNode(K key, this.value) : super(key);
+
+  _SplayTreeMapNode<K, V> _replaceValue(V value) =>
+      _SplayTreeMapNode<K, V>(key, value)
+        .._left = _left
+        .._right = _right;
+
+  String toString() => "MapEntry($key: $value)";
 }
 
 /// A splay tree is a self-balancing binary search tree.
@@ -72,7 +80,12 @@
   /// Returns the result of comparing the new root of the tree to [key].
   /// Returns -1 if the table is empty.
   int _splay(K key) {
-    if (_root == null) return -1;
+    var root = _root;
+    if (root == null) {
+      // Ensure key is compatible with `_compare`.
+      _compare(key, key);
+      return -1;
+    }
 
     // The right and newTreeRight variables start out null, and are set
     // after the first move left.  The right node is the destination
@@ -85,22 +98,22 @@
     Node? newTreeRight;
     Node? left;
     Node? newTreeLeft;
-    var current = _root!;
+    var current = root;
     // Hoist the field read out of the loop.
     var compare = _compare;
     int comp;
     while (true) {
       comp = compare(current.key, key);
       if (comp > 0) {
-        var currentLeft = current.left;
+        var currentLeft = current._left;
         if (currentLeft == null) break;
         comp = compare(currentLeft.key, key);
         if (comp > 0) {
           // Rotate right.
-          current.left = currentLeft.right;
-          currentLeft.right = current;
+          current._left = currentLeft._right;
+          currentLeft._right = current;
           current = currentLeft;
-          currentLeft = current.left;
+          currentLeft = current._left;
           if (currentLeft == null) break;
         }
         // Link right.
@@ -108,20 +121,20 @@
           // First left rebalance, store the eventual right child
           newTreeRight = current;
         } else {
-          right.left = current;
+          right._left = current;
         }
         right = current;
         current = currentLeft;
       } else if (comp < 0) {
-        var currentRight = current.right;
+        var currentRight = current._right;
         if (currentRight == null) break;
         comp = compare(currentRight.key, key);
         if (comp < 0) {
           // Rotate left.
-          current.right = currentRight.left;
-          currentRight.left = current;
+          current._right = currentRight._left;
+          currentRight._left = current;
           current = currentRight;
-          currentRight = current.right;
+          currentRight = current._right;
           if (currentRight == null) break;
         }
         // Link left.
@@ -129,7 +142,7 @@
           // First right rebalance, store the eventual left child
           newTreeLeft = current;
         } else {
-          left.right = current;
+          left._right = current;
         }
         left = current;
         current = currentRight;
@@ -139,16 +152,17 @@
     }
     // Assemble.
     if (left != null) {
-      left.right = current.left;
-      current.left = newTreeLeft;
+      left._right = current._left;
+      current._left = newTreeLeft;
     }
     if (right != null) {
-      right.left = current.right;
-      current.right = newTreeRight;
+      right._left = current._right;
+      current._right = newTreeRight;
     }
-    _root = current;
-
-    _splayCount++;
+    if (!identical(_root, current)) {
+      _root = current;
+      _splayCount++;
+    }
     return comp;
   }
 
@@ -158,13 +172,13 @@
   // in any parent tree or root pointer.
   Node _splayMin(Node node) {
     var current = node;
-    var nextLeft = current.left;
+    var nextLeft = current._left;
     while (nextLeft != null) {
       var left = nextLeft;
-      current.left = left.right;
-      left.right = current;
+      current._left = left._right;
+      left._right = current;
       current = left;
-      nextLeft = current.left;
+      nextLeft = current._left;
     }
     return current;
   }
@@ -176,13 +190,13 @@
   // in any parent tree or root pointer.
   Node _splayMax(Node node) {
     var current = node;
-    var nextRight = current.right;
+    var nextRight = current._right;
     while (nextRight != null) {
       var right = nextRight;
-      current.right = right.left;
-      right.left = current;
+      current._right = right._left;
+      right._left = current;
       current = right;
-      nextRight = current.right;
+      nextRight = current._right;
     }
     return current;
   }
@@ -193,19 +207,19 @@
     if (comp != 0) return null;
     var root = _root!;
     var result = root;
-    var left = root.left;
+    var left = root._left;
     _count--;
     // assert(_count >= 0);
     if (left == null) {
-      _root = root.right;
+      _root = root._right;
     } else {
-      var right = root.right;
+      var right = root._right;
       // Splay to make sure that the new root has an empty right child.
       root = _splayMax(left);
 
       // Insert the original right child as the right child of the new
       // root.
-      root.right = right;
+      root._right = right;
       _root = root;
     }
     _modificationCount++;
@@ -226,13 +240,13 @@
     }
     // assert(_count >= 0);
     if (comp < 0) {
-      node.left = root;
-      node.right = root.right;
-      root.right = null;
+      node._left = root;
+      node._right = root._right;
+      root._right = null;
     } else {
-      node.right = root;
-      node.left = root.left;
-      root.left = null;
+      node._right = root;
+      node._left = root._left;
+      root._left = null;
     }
     _root = node;
   }
@@ -256,6 +270,10 @@
     _count = 0;
     _modificationCount++;
   }
+
+  bool _containsKey(Object? key) {
+    return _validKey(key) && _splay(key as dynamic) == 0;
+  }
 }
 
 int _dynamicCompare(dynamic a, dynamic b) => Comparable.compare(a, b);
@@ -273,8 +291,8 @@
 
 /// A [Map] of objects that can be ordered relative to each other.
 ///
-/// The map is based on a self-balancing binary tree. It allows most operations
-/// in amortized logarithmic time.
+/// The map is based on a self-balancing binary tree.
+/// It allows most single-entry operations in amortized logarithmic time.
 ///
 /// Keys of the map are compared using the `compare` function passed in
 /// the constructor, both for ordering and for equality.
@@ -303,7 +321,7 @@
       [int Function(K key1, K key2)? compare,
       bool Function(dynamic potentialKey)? isValidKey])
       : _compare = compare ?? _defaultCompare<K>(),
-        _validKey = isValidKey ?? ((dynamic v) => v is K);
+        _validKey = isValidKey ?? ((dynamic a) => a is K);
 
   /// Creates a [SplayTreeMap] that contains all key/value pairs of [other].
   ///
@@ -385,19 +403,19 @@
   }
 
   void operator []=(K key, V value) {
-    if (key == null) throw ArgumentError(key);
     // Splay on the key to move the last node on the search path for
     // the key to the root of the tree.
     int comp = _splay(key);
     if (comp == 0) {
-      _root!.value = value;
+      _root = _root!._replaceValue(value);
+      // To represent structure change, in case someone caches the old node.
+      _splayCount += 1;
       return;
     }
     _addNewRoot(_SplayTreeMapNode(key, value), comp);
   }
 
   V putIfAbsent(K key, V ifAbsent()) {
-    if (key == null) throw ArgumentError(key);
     int comp = _splay(key);
     if (comp == 0) {
       return _root!.value;
@@ -417,6 +435,49 @@
     return value;
   }
 
+  V update(K key, V update(V value), {V Function()? ifAbsent}) {
+    var comp = _splay(key);
+    if (comp == 0) {
+      var modificationCount = _modificationCount;
+      var splayCount = _splayCount;
+      var newValue = update(_root!.value);
+      if (modificationCount != _modificationCount) {
+        throw ConcurrentModificationError(this);
+      }
+      if (splayCount != _splayCount) {
+        _splay(key);
+      }
+      _root = _root!._replaceValue(newValue);
+      _splayCount += 1;
+      return newValue;
+    }
+    if (ifAbsent != null) {
+      var modificationCount = _modificationCount;
+      var splayCount = _splayCount;
+      var newValue = ifAbsent();
+      if (modificationCount != _modificationCount) {
+        throw ConcurrentModificationError(this);
+      }
+      if (splayCount != _splayCount) {
+        comp = _splay(key);
+      }
+      _addNewRoot(_SplayTreeMapNode(key, newValue), comp);
+      return newValue;
+    }
+    throw ArgumentError.value(key, "key", "Key not in map.");
+  }
+
+  void updateAll(V update(K key, V value)) {
+    var root = _root;
+    if (root == null) return;
+    var iterator = _SplayTreeMapEntryIterator(this);
+    while (iterator.moveNext()) {
+      var node = iterator.current;
+      var newValue = update(node.key, node.value);
+      iterator._replaceValue(newValue);
+    }
+  }
+
   void addAll(Map<K, V> other) {
     other.forEach((K key, V value) {
       this[key] = value;
@@ -430,10 +491,9 @@
   bool get isNotEmpty => !isEmpty;
 
   void forEach(void f(K key, V value)) {
-    Iterator<_SplayTreeMapNode<K, V>> nodes =
-        _SplayTreeNodeIterator<K, _SplayTreeMapNode<K, V>>(this);
+    Iterator<MapEntry<K, V>> nodes = _SplayTreeMapEntryIterator<K, V>(this);
     while (nodes.moveNext()) {
-      _SplayTreeMapNode<K, V> node = nodes.current;
+      MapEntry<K, V> node = nodes.current;
       f(node.key, node.value);
     }
   }
@@ -446,9 +506,7 @@
     _clear();
   }
 
-  bool containsKey(Object? key) {
-    return _validKey(key) && _splay(key as dynamic) == 0;
-  }
+  bool containsKey(Object? key) => _containsKey(key);
 
   bool containsValue(Object? value) {
     int initialSplayCount = _splayCount;
@@ -458,10 +516,10 @@
         if (initialSplayCount != _splayCount) {
           throw ConcurrentModificationError(this);
         }
-        if (node.right != null && visit(node.right)) {
+        if (node._right != null && visit(node._right)) {
           return true;
         }
-        node = node.left;
+        node = node._left;
       }
       return false;
     }
@@ -474,6 +532,9 @@
 
   Iterable<V> get values => _SplayTreeValueIterable<K, V>(this);
 
+  Iterable<MapEntry<K, V>> get entries =>
+      _SplayTreeMapEntryIterable<K, V>(this);
+
   /// The first key in the map.
   ///
   /// Returns `null` if the map is empty.
@@ -498,12 +559,12 @@
     if (_root == null) return null;
     int comp = _splay(key);
     if (comp < 0) return _root!.key;
-    _SplayTreeMapNode<K, V>? node = _root!.left;
+    _SplayTreeMapNode<K, V>? node = _root!._left;
     if (node == null) return null;
-    var nodeRight = node.right;
+    var nodeRight = node._right;
     while (nodeRight != null) {
       node = nodeRight;
-      nodeRight = node.right;
+      nodeRight = node._right;
     }
     return node!.key;
   }
@@ -515,12 +576,12 @@
     if (_root == null) return null;
     int comp = _splay(key);
     if (comp > 0) return _root!.key;
-    _SplayTreeMapNode<K, V>? node = _root!.right;
+    _SplayTreeMapNode<K, V>? node = _root!._right;
     if (node == null) return null;
-    var nodeLeft = node.left;
+    var nodeLeft = node._left;
     while (nodeLeft != null) {
       node = nodeLeft;
-      nodeLeft = node.left;
+      nodeLeft = node._left;
     }
     return node!.key;
   }
@@ -530,15 +591,10 @@
     implements Iterator<T> {
   final _SplayTree<K, Node> _tree;
 
-  /// Worklist of nodes to visit.
-  ///
-  /// These nodes have been passed over on the way down in a
-  /// depth-first left-to-right traversal. Visiting each node,
-  /// and their right subtrees will visit the remainder of
-  /// the nodes of a full traversal.
+  /// The current node, and all its ancestors in the tree.
   ///
   /// Only valid as long as the original tree isn't reordered.
-  final List<Node> _workList = [];
+  final List<Node> _path = [];
 
   /// Original modification counter of [_tree].
   ///
@@ -547,84 +603,76 @@
   ///
   /// Not final because some iterators may modify the tree knowingly,
   /// and they update the modification count in that case.
-  int _modificationCount;
-
-  /// Count of splay operations on [_tree] when [_workList] was built.
   ///
-  /// If the splay count on [_tree] increases, [_workList] becomes invalid.
-  int _splayCount;
+  /// Starts at `null` to represent a fresh, unstarted iterator.
+  int? _modificationCount;
 
-  /// Current node.
-  Node? _currentNode;
+  /// Count of splay operations on [_tree] when [_path] was built.
+  ///
+  /// If the splay count on [_tree] increases, [_path] becomes invalid.
+  int _splayCount;
 
   _SplayTreeIterator(_SplayTree<K, Node> tree)
       : _tree = tree,
-        _modificationCount = tree._modificationCount,
-        _splayCount = tree._splayCount {
-    _findLeftMostDescendent(tree._root);
-  }
-
-  _SplayTreeIterator.startAt(_SplayTree<K, Node> tree, K startKey)
-      : _tree = tree,
-        _modificationCount = tree._modificationCount,
-        _splayCount = -1 {
-    if (tree._root == null) return;
-    int compare = tree._splay(startKey);
-    _splayCount = tree._splayCount;
-    if (compare < 0) {
-      // Don't include the root, start at the next element after the root.
-      _findLeftMostDescendent(tree._root!.right);
-    } else {
-      _workList.add(tree._root!);
-    }
-  }
+        _splayCount = tree._splayCount;
 
   T get current {
-    var node = _currentNode;
-    if (node == null) return null as T;
+    if (_path.isEmpty) return null as T;
+    var node = _path.last;
     return _getValue(node);
   }
 
-  void _findLeftMostDescendent(Node? node) {
-    while (node != null) {
-      _workList.add(node);
-      node = node.left;
-    }
-  }
-
   /// Called when the tree structure of the tree has changed.
   ///
   /// This can be caused by a splay operation.
   /// If the key-set changes, iteration is aborted before getting
   /// here, so we know that the keys are the same as before, it's
   /// only the tree that has been reordered.
-  void _rebuildWorkList(Node currentNode) {
-    assert(_workList.isNotEmpty);
-    _workList.clear();
-    _tree._splay(currentNode.key);
-    _findLeftMostDescendent(_tree._root!.right);
-    assert(_workList.isNotEmpty);
+  void _rebuildPath(K key) {
+    _path.clear();
+    _tree._splay(key);
+    _path.add(_tree._root!);
+    _splayCount = _tree._splayCount;
+  }
+
+  void _findLeftMostDescendent(Node? node) {
+    while (node != null) {
+      _path.add(node);
+      node = node._left;
+    }
   }
 
   bool moveNext() {
     if (_modificationCount != _tree._modificationCount) {
+      if (_modificationCount == null) {
+        _modificationCount = _tree._modificationCount;
+        var node = _tree._root;
+        while (node != null) {
+          _path.add(node);
+          node = node._left;
+        }
+        return _path.isNotEmpty;
+      }
       throw ConcurrentModificationError(_tree);
     }
-    // Picks the next element in the worklist as current.
-    // Updates the worklist with the left-most path of the current node's
-    // right-hand child.
-    // If the worklist is no longer valid (after a splay), it is rebuild
-    // from scratch.
-    if (_workList.isEmpty) {
-      _currentNode = null;
-      return false;
+    if (_path.isEmpty) return false;
+    if (_splayCount != _tree._splayCount) {
+      _rebuildPath(_path.last.key);
     }
-    if (_tree._splayCount != _splayCount && _currentNode != null) {
-      _rebuildWorkList(_currentNode!);
+    var node = _path.last;
+    var next = node._right;
+    if (next != null) {
+      while (next != null) {
+        _path.add(next);
+        next = next._left;
+      }
+      return true;
     }
-    _currentNode = _workList.removeLast();
-    _findLeftMostDescendent(_currentNode!.right);
-    return true;
+    _path.removeLast();
+    while (_path.isNotEmpty && identical(_path.last._right, node)) {
+      node = _path.removeLast();
+    }
+    return _path.isNotEmpty;
   }
 
   T _getValue(Node node);
@@ -638,6 +686,8 @@
   bool get isEmpty => _tree._count == 0;
   Iterator<K> get iterator => _SplayTreeKeyIterator<K, Node>(_tree);
 
+  bool contains(Object? o) => _tree._containsKey(o);
+
   Set<K> toSet() {
     SplayTreeSet<K> set = SplayTreeSet<K>(_tree._compare, _tree._validKey);
     set._count = _tree._count;
@@ -654,6 +704,16 @@
   Iterator<V> get iterator => _SplayTreeValueIterator<K, V>(_map);
 }
 
+class _SplayTreeMapEntryIterable<K, V>
+    extends EfficientLengthIterable<MapEntry<K, V>> {
+  SplayTreeMap<K, V> _map;
+  _SplayTreeMapEntryIterable(this._map);
+  int get length => _map._count;
+  bool get isEmpty => _map._count == 0;
+  Iterator<MapEntry<K, V>> get iterator =>
+      _SplayTreeMapEntryIterator<K, V>(_map);
+}
+
 class _SplayTreeKeyIterator<K, Node extends _SplayTreeNode<K, Node>>
     extends _SplayTreeIterator<K, Node, K> {
   _SplayTreeKeyIterator(_SplayTree<K, Node> map) : super(map);
@@ -666,12 +726,36 @@
   V _getValue(_SplayTreeMapNode<K, V> node) => node.value;
 }
 
-class _SplayTreeNodeIterator<K, Node extends _SplayTreeNode<K, Node>>
-    extends _SplayTreeIterator<K, Node, Node> {
-  _SplayTreeNodeIterator(_SplayTree<K, Node> tree) : super(tree);
-  _SplayTreeNodeIterator.startAt(_SplayTree<K, Node> tree, K startKey)
-      : super.startAt(tree, startKey);
-  Node _getValue(Node node) => node;
+class _SplayTreeMapEntryIterator<K, V>
+    extends _SplayTreeIterator<K, _SplayTreeMapNode<K, V>, MapEntry<K, V>> {
+  _SplayTreeMapEntryIterator(SplayTreeMap<K, V> tree) : super(tree);
+  MapEntry<K, V> _getValue(_SplayTreeMapNode<K, V> node) => node;
+
+  // Replaces the value of the current node.
+  void _replaceValue(V value) {
+    assert(_path.isNotEmpty);
+    if (_modificationCount != _tree._modificationCount) {
+      throw ConcurrentModificationError(_tree);
+    }
+    if (_splayCount != _tree._splayCount) {
+      _rebuildPath(_path.last.key);
+    }
+    var last = _path.removeLast();
+    var newLast = last._replaceValue(value);
+    if (_path.isEmpty) {
+      _tree._root = newLast;
+    } else {
+      var parent = _path.last;
+      if (identical(last, parent._left)) {
+        parent._left = newLast;
+      } else {
+        assert(identical(last, parent._right));
+        parent._right = newLast;
+      }
+    }
+    _path.add(newLast);
+    _splayCount = ++_tree._splayCount;
+  }
 }
 
 /// A [Set] of objects that can be ordered relative to each other.
@@ -794,7 +878,9 @@
     return _validKey(element) && _splay(element as E) == 0;
   }
 
-  bool add(E element) {
+  bool add(E element) => _add(element);
+
+  bool _add(E element) {
     int compare = _splay(element);
     if (compare == 0) return false;
     _addNewRoot(_SplayTreeSetNode(element), compare);
@@ -808,10 +894,7 @@
 
   void addAll(Iterable<E> elements) {
     for (E element in elements) {
-      int compare = _splay(element);
-      if (compare != 0) {
-        _addNewRoot(_SplayTreeSetNode(element), compare);
-      }
+      _add(element);
     }
   }
 
@@ -890,17 +973,17 @@
       Node? left;
       Node? right;
       do {
-        left = node.left;
-        right = node.right;
+        left = node._left;
+        right = node._right;
         if (left != null) {
           var newLeft = _SplayTreeSetNode<E>(left.key);
-          dest.left = newLeft;
+          dest._left = newLeft;
           // Recursively copy the left tree.
           copyChildren(left, newLeft);
         }
         if (right != null) {
           var newRight = _SplayTreeSetNode<E>(right.key);
-          dest.right = newRight;
+          dest._right = newRight;
           // Set node and dest to copy the right tree iteratively.
           node = right;
           dest = newRight;
diff --git a/sdk/lib/convert/json.dart b/sdk/lib/convert/json.dart
index 33eaab6..a4aeb6a 100644
--- a/sdk/lib/convert/json.dart
+++ b/sdk/lib/convert/json.dart
@@ -441,7 +441,7 @@
 
 /// Sink returned when starting a chunked conversion from object to bytes.
 class _JsonUtf8EncoderSink extends ChunkedConversionSink<Object?> {
-  /// The byte sink receiveing the encoded chunks.
+  /// The byte sink receiving the encoded chunks.
   final ByteConversionSink _sink;
   final List<int>? _indent;
   final Object? Function(dynamic)? _toEncodable;
diff --git a/sdk/lib/core/bigint.dart b/sdk/lib/core/bigint.dart
index e3f7090..c905d3b50 100644
--- a/sdk/lib/core/bigint.dart
+++ b/sdk/lib/core/bigint.dart
@@ -73,7 +73,7 @@
   /// The remainder can be computed using the [remainder] method.
   ///
   /// Examples:
-  /// ```
+  /// ```dart
   /// var seven = BigInt.from(7);
   /// var three = BigInt.from(3);
   /// seven ~/ three;    // => 2
@@ -189,7 +189,7 @@
   /// To find the number of bits needed to store the value as a signed value,
   /// add one, i.e. use `x.bitLength + 1`.
   ///
-  /// ```
+  /// ```dart
   /// x.bitLength == (-x-1).bitLength
   ///
   /// BigInt.from(3).bitLength == 2;   // 00000011
@@ -260,14 +260,14 @@
   /// non-negative number (i.e. unsigned representation).  The returned value has
   /// zeros in all bit positions higher than [width].
   ///
-  /// ```
+  /// ```dart
   /// BigInt.from(-1).toUnsigned(5) == 31   // 11111111  ->  00011111
   /// ```
   ///
   /// This operation can be used to simulate arithmetic from low level languages.
   /// For example, to increment an 8 bit quantity:
   ///
-  /// ```
+  /// ```dart
   /// q = (q + 1).toUnsigned(8);
   /// ```
   ///
@@ -277,7 +277,7 @@
   /// same as the input.  The minimum width needed to avoid truncation of `x` is
   /// given by `x.bitLength`, i.e.
   ///
-  /// ```
+  /// ```dart
   /// x == x.toUnsigned(x.bitLength);
   /// ```
   BigInt toUnsigned(int width);
@@ -287,7 +287,7 @@
   /// to fit in [width] bits using an signed 2-s complement representation.  The
   /// returned value has the same bit value in all positions higher than [width].
   ///
-  /// ```
+  /// ```dart
   /// var big15 = BigInt.from(15);
   /// var big16 = BigInt.from(16);
   /// var big239 = BigInt.from(239);
@@ -300,7 +300,7 @@
   /// This operation can be used to simulate arithmetic from low level languages.
   /// For example, to increment an 8 bit signed quantity:
   ///
-  /// ```
+  /// ```dart
   /// q = (q + 1).toSigned(8);
   /// ```
   ///
@@ -311,7 +311,7 @@
   /// the same as the input.  The minimum width needed to avoid truncation of `x`
   /// is `x.bitLength + 1`, i.e.
   ///
-  /// ```
+  /// ```dart
   /// x == x.toSigned(x.bitLength + 1);
   /// ```
   BigInt toSigned(int width);
diff --git a/sdk/lib/core/date_time.dart b/sdk/lib/core/date_time.dart
index 2891f8b..045aef2 100644
--- a/sdk/lib/core/date_time.dart
+++ b/sdk/lib/core/date_time.dart
@@ -16,7 +16,7 @@
 /// as in a 24-hour clock.
 /// For example:
 ///
-/// ```
+/// ```dart
 /// var now = DateTime.now();
 /// var berlinWallFell = DateTime.utc(1989, 11, 9);
 /// var moonLanding = DateTime.parse("1969-07-20 20:18:04Z");  // 8:18pm
@@ -32,7 +32,7 @@
 /// You can use properties to get
 /// the individual units of a DateTime object.
 ///
-/// ```
+/// ```dart
 /// assert(berlinWallFell.month == 11);
 /// assert(moonLanding.hour == 20);
 /// ```
@@ -42,7 +42,7 @@
 /// name - for example, [august] and [friday].
 /// You can use these constants to improve code readability:
 ///
-/// ```
+/// ```dart
 /// var berlinWallFell = DateTime.utc(1989, DateTime.november, 9);
 /// assert(berlinWallFell.weekday == DateTime.thursday);
 /// ```
@@ -55,7 +55,7 @@
 /// A DateTime object is in the local time zone
 /// unless explicitly created in the UTC time zone.
 ///
-/// ```
+/// ```dart
 /// var dDay = DateTime.utc(1944, 6, 6);
 /// ```
 ///
@@ -74,7 +74,7 @@
 /// such as [isAfter], [isBefore], and [isAtSameMomentAs],
 /// for comparing DateTime objects.
 ///
-/// ```
+/// ```dart
 /// assert(berlinWallFell.isAfter(moonLanding) == true);
 /// assert(berlinWallFell.isBefore(moonLanding) == false);
 /// ```
@@ -86,7 +86,7 @@
 /// For example, to find the date that is sixty days (24 * 60 hours) after today,
 /// write:
 ///
-/// ```
+/// ```dart
 /// var now = DateTime.now();
 /// var sixtyDaysFromNow = now.add(const Duration(days: 60));
 /// ```
@@ -94,7 +94,7 @@
 /// To find out how much time is between two DateTime objects use
 /// [difference], which returns a [Duration] object:
 ///
-/// ```
+/// ```dart
 /// var difference = berlinWallFell.difference(moonLanding);
 /// assert(difference.inDays == 7416);
 /// ```
@@ -153,7 +153,7 @@
 
   /// True if this [DateTime] is set to UTC time.
   ///
-  /// ```
+  /// ```dart
   /// var dDay = DateTime.utc(1944, 6, 6);
   /// assert(dDay.isUtc);
   /// ```
@@ -166,7 +166,7 @@
   /// to create a DateTime object representing the 7th of September 2017,
   /// 5:30pm
   ///
-  /// ```
+  /// ```dart
   /// var dentistAppointment = DateTime(2017, 9, 7, 17, 30);
   /// ```
   DateTime(int year,
@@ -182,7 +182,7 @@
 
   /// Constructs a [DateTime] instance specified in the UTC time zone.
   ///
-  /// ```
+  /// ```dart
   /// var moonLanding = DateTime.utc(1969, 7, 20, 20, 18, 04);
   /// ```
   ///
@@ -203,7 +203,7 @@
   /// Constructs a [DateTime] instance with current date and time in the
   /// local time zone.
   ///
-  /// ```
+  /// ```dart
   /// var thisInstant = DateTime.now();
   /// ```
   DateTime.now() : this._now();
@@ -377,7 +377,7 @@
   /// Returns true if [other] is a [DateTime] at the same moment and in the
   /// same time zone (UTC or local).
   ///
-  /// ```
+  /// ```dart
   /// var dDayUtc = DateTime.utc(1944, 6, 6);
   /// var dDayLocal = dDayUtc.toLocal();
   ///
@@ -394,7 +394,7 @@
   /// The comparison is independent
   /// of whether the time is in UTC or in the local time zone.
   ///
-  /// ```
+  /// ```dart
   /// var now = DateTime.now();
   /// var earlier = now.subtract(const Duration(seconds: 5));
   /// assert(earlier.isBefore(now));
@@ -414,7 +414,7 @@
   /// The comparison is independent
   /// of whether the time is in UTC or in the local time zone.
   ///
-  /// ```
+  /// ```dart
   /// var now = DateTime.now();
   /// var later = now.add(const Duration(seconds: 5));
   /// assert(later.isAfter(now));
@@ -434,7 +434,7 @@
   /// The comparison is independent of whether the time is in UTC or in the local
   /// time zone.
   ///
-  /// ```
+  /// ```dart
   /// var now = DateTime.now();
   /// var later = now.add(const Duration(seconds: 5));
   /// assert(!later.isAtSameMomentAs(now));
@@ -464,7 +464,7 @@
   /// Returns [this] if it is already in the local time zone.
   /// Otherwise this method is equivalent to:
   ///
-  /// ```
+  /// ```dart
   /// DateTime.fromMicrosecondsSinceEpoch(microsecondsSinceEpoch,
   ///                                     isUtc: false)
   /// ```
@@ -480,7 +480,7 @@
   /// Returns [this] if it is already in UTC.
   /// Otherwise this method is equivalent to:
   ///
-  /// ```
+  /// ```dart
   /// DateTime.fromMicrosecondsSinceEpoch(microsecondsSinceEpoch,
   ///                                     isUtc: true)
   /// ```
@@ -580,7 +580,7 @@
 
   /// Returns a new [DateTime] instance with [duration] added to [this].
   ///
-  /// ```
+  /// ```dart
   /// var today = DateTime.now();
   /// var fiftyDaysFromNow = today.add(const Duration(days: 50));
   /// ```
@@ -595,7 +595,7 @@
 
   /// Returns a new [DateTime] instance with [duration] subtracted from [this].
   ///
-  /// ```
+  /// ```dart
   /// DateTime today = DateTime.now();
   /// DateTime fiftyDaysAgo = today.subtract(const Duration(days: 50));
   /// ```
@@ -613,7 +613,7 @@
   ///
   /// The returned [Duration] will be negative if [other] occurs after [this].
   ///
-  /// ```
+  /// ```dart
   /// var berlinWallFell = DateTime.utc(1989, DateTime.november, 9);
   /// var dDay = DateTime.utc(1944, DateTime.june, 6);
   ///
@@ -630,7 +630,7 @@
   ///
   /// For example, in Australia, similar code using local time instead of UTC:
   ///
-  /// ```
+  /// ```dart
   /// var berlinWallFell = DateTime(1989, DateTime.november, 9);
   /// var dDay = DateTime(1944, DateTime.june, 6);
   /// Duration difference = berlinWallFell.difference(dDay);
@@ -703,7 +703,7 @@
 
   /// The year.
   ///
-  /// ```
+  /// ```dart
   /// var moonLanding = DateTime.parse("1969-07-20 20:18:04Z");
   /// assert(moonLanding.year == 1969);
   /// ```
@@ -711,7 +711,7 @@
 
   /// The month [1..12].
   ///
-  /// ```
+  /// ```dart
   /// var moonLanding = DateTime.parse("1969-07-20 20:18:04Z");
   /// assert(moonLanding.month == 7);
   /// assert(moonLanding.month == DateTime.july);
@@ -720,7 +720,7 @@
 
   /// The day of the month [1..31].
   ///
-  /// ```
+  /// ```dart
   /// var moonLanding = DateTime.parse("1969-07-20 20:18:04Z");
   /// assert(moonLanding.day == 20);
   /// ```
@@ -728,7 +728,7 @@
 
   /// The hour of the day, expressed as in a 24-hour clock [0..23].
   ///
-  /// ```
+  /// ```dart
   /// var moonLanding = DateTime.parse("1969-07-20 20:18:04Z");
   /// assert(moonLanding.hour == 20);
   /// ```
@@ -736,7 +736,7 @@
 
   /// The minute [0...59].
   ///
-  /// ```
+  /// ```dart
   /// var moonLanding = DateTime.parse("1969-07-20 20:18:04Z");
   /// assert(moonLanding.minute == 18);
   /// ```
@@ -744,7 +744,7 @@
 
   /// The second [0...59].
   ///
-  /// ```
+  /// ```dart
   /// var moonLanding = DateTime.parse("1969-07-20 20:18:04Z");
   /// assert(moonLanding.second == 4);
   /// ```
@@ -752,7 +752,7 @@
 
   /// The millisecond [0...999].
   ///
-  /// ```
+  /// ```dart
   /// var moonLanding = DateTime.parse("1969-07-20 20:18:04Z");
   /// assert(moonLanding.millisecond == 0);
   /// ```
@@ -760,7 +760,7 @@
 
   /// The microsecond [0...999].
   ///
-  /// ```
+  /// ```dart
   /// var moonLanding = DateTime.parse("1969-07-20 20:18:04Z");
   /// assert(moonLanding.microsecond == 0);
   /// ```
@@ -771,7 +771,7 @@
   /// In accordance with ISO 8601
   /// a week starts with Monday, which has the value 1.
   ///
-  /// ```
+  /// ```dart
   /// var moonLanding = DateTime.parse("1969-07-20 20:18:04Z");
   /// assert(moonLanding.weekday == 7);
   /// assert(moonLanding.weekday == DateTime.sunday);
diff --git a/sdk/lib/core/errors.dart b/sdk/lib/core/errors.dart
index 080595a..683267d 100644
--- a/sdk/lib/core/errors.dart
+++ b/sdk/lib/core/errors.dart
@@ -29,7 +29,7 @@
 /// is very likely to cause an error to be thrown.
 ///
 /// Example (from [String.contains]):
-/// ```
+/// ```plaintext
 /// `startIndex` must not be negative or greater than `length`.
 /// ```
 /// In this case, an error will be thrown if `startIndex` is negative
@@ -156,8 +156,8 @@
   ///
   /// A message is built by suffixing the [message] argument with
   /// the [name] argument (if provided) and the value. Example:
-  /// ```
-  /// "Invalid argument (foo): null"
+  /// ```plaintext
+  /// Invalid argument (foo): null
   /// ```
   /// The `name` should match the argument name of the function, but if
   /// the function is a method implementing an interface, and its argument
@@ -520,7 +520,7 @@
 
 /// The operation was not allowed by the current state of the object.
 ///
-/// Should be used when this particular object is currenty in a state
+/// Should be used when this particular object is currently in a state
 /// which doesn't support the requested operation, but other similar
 /// objects might, or the object might change its state to one which
 /// supports the operation.
diff --git a/sdk/lib/core/function.dart b/sdk/lib/core/function.dart
index b0d7ca1..1151354 100644
--- a/sdk/lib/core/function.dart
+++ b/sdk/lib/core/function.dart
@@ -19,12 +19,12 @@
   /// if it expects different parameters.
   ///
   /// Example:
-  /// ```
+  /// ```dart
   /// Function.apply(foo, [1, 2, 3], {#f: 4, #g: 5});
   /// ```
   ///
   /// gives exactly the same result as
-  /// ```
+  /// ```dart
   /// foo(1, 2, 3, f: 4, g: 5).
   /// ```
   ///
diff --git a/sdk/lib/core/int.dart b/sdk/lib/core/int.dart
index dd35a3f..a799e46 100644
--- a/sdk/lib/core/int.dart
+++ b/sdk/lib/core/int.dart
@@ -24,12 +24,12 @@
   /// Returns the integer value of the given environment declaration [name].
   ///
   /// The result is the same as would be returned by:
-  /// ```
+  /// ```dart
   /// int.tryParse(const String.fromEnvironment(name, defaultValue: ""))
   ///     ?? defaultValue
   /// ```
   /// Example:
-  /// ```
+  /// ```dart
   /// const int.fromEnvironment("defaultPort", defaultValue: 80)
   /// ```
   ///
@@ -111,7 +111,7 @@
   ///
   /// The least significant [shiftAmount] bits are dropped,
   /// the remaining bits (if any) are shifted down,
-  /// and zero-bits are shifted in as the new most signficant bits.
+  /// and zero-bits are shifted in as the new most significant bits.
   ///
   /// The [shiftAmount] must be non-negative.
   int operator >>>(int shiftAmount);
@@ -157,7 +157,7 @@
   ///
   /// To find the number of bits needed to store the value as a signed value,
   /// add one, i.e. use `x.bitLength + 1`.
-  /// ```
+  /// ```dart
   /// x.bitLength == (-x-1).bitLength
   ///
   /// 3.bitLength == 2;     // 00000011
@@ -174,12 +174,12 @@
   /// Returns the least significant [width] bits of this integer as a
   /// non-negative number (i.e. unsigned representation).  The returned value has
   /// zeros in all bit positions higher than [width].
-  /// ```
+  /// ```dart
   /// (-1).toUnsigned(5) == 31   // 11111111  ->  00011111
   /// ```
   /// This operation can be used to simulate arithmetic from low level languages.
   /// For example, to increment an 8 bit quantity:
-  /// ```
+  /// ```dart
   /// q = (q + 1).toUnsigned(8);
   /// ```
   /// `q` will count from `0` up to `255` and then wrap around to `0`.
@@ -187,7 +187,7 @@
   /// If the input fits in [width] bits without truncation, the result is the
   /// same as the input.  The minimum width needed to avoid truncation of `x` is
   /// given by `x.bitLength`, i.e.
-  /// ```
+  /// ```dart
   /// x == x.toUnsigned(x.bitLength);
   /// ```
   int toUnsigned(int width);
@@ -197,7 +197,7 @@
   /// to fit in [width] bits using an signed 2-s complement representation.  The
   /// returned value has the same bit value in all positions higher than [width].
   ///
-  /// ```
+  /// ```dart
   ///                                V--sign bit-V
   /// 16.toSigned(5) == -16   //  00010000 -> 11110000
   /// 239.toSigned(5) == 15   //  11101111 -> 00001111
@@ -205,7 +205,7 @@
   /// ```
   /// This operation can be used to simulate arithmetic from low level languages.
   /// For example, to increment an 8 bit signed quantity:
-  /// ```
+  /// ```dart
   /// q = (q + 1).toSigned(8);
   /// ```
   /// `q` will count from `0` up to `127`, wrap to `-128` and count back up to
@@ -214,7 +214,7 @@
   /// If the input value fits in [width] bits without truncation, the result is
   /// the same as the input.  The minimum width needed to avoid truncation of `x`
   /// is `x.bitLength + 1`, i.e.
-  /// ```
+  /// ```dart
   /// x == x.toSigned(x.bitLength + 1);
   /// ```
   int toSigned(int width);
diff --git a/sdk/lib/core/list.dart b/sdk/lib/core/list.dart
index 2f7bec5..0014c2e 100644
--- a/sdk/lib/core/list.dart
+++ b/sdk/lib/core/list.dart
@@ -105,14 +105,14 @@
   /// using `[]` or other [List] constructors.
   ///
   /// All elements of the created list share the same [fill] value.
-  /// ```
+  /// ```dart
   /// var shared = List.filled(3, []);
   /// shared[0].add(499);
   /// print(shared);  // => [[499], [499], [499]]
   /// ```
   /// You can use [List.generate] to create a list with a fixed length
   /// and a new object at each position.
-  /// ```
+  /// ```dart
   /// var unique = List.generate(3, (_) => []);
   /// unique[0].add(499);
   /// print(unique); // => [[499], [], []]
@@ -377,14 +377,14 @@
   /// The first time an object `o` is encountered so that `test(o)` is true,
   /// the index of `o` is returned.
   ///
-  /// ```
+  /// ```dart
   /// var notes = ['do', 're', 'mi', 're'];
   /// notes.indexWhere((note) => note.startsWith('r'));       // 1
   /// notes.indexWhere((note) => note.startsWith('r'), 2);    // 3
   /// ```
   ///
   /// Returns -1 if [element] is not found.
-  /// ```
+  /// ```dart
   /// notes.indexWhere((note) => note.startsWith('k'));    // -1
   /// ```
   int indexWhere(bool test(E element), [int start = 0]);
@@ -396,14 +396,14 @@
   /// the index of `o` is returned.
   /// If [start] is omitted, it defaults to the [length] of the list.
   ///
-  /// ```
+  /// ```dart
   /// var notes = ['do', 're', 'mi', 're'];
   /// notes.lastIndexWhere((note) => note.startsWith('r'));       // 3
   /// notes.lastIndexWhere((note) => note.startsWith('r'), 2);    // 1
   /// ```
   ///
   /// Returns -1 if [element] is not found.
-  /// ```
+  /// ```dart
   /// notes.lastIndexWhere((note) => note.startsWith('k'));    // -1
   /// ```
   int lastIndexWhere(bool test(E element), [int? start]);
diff --git a/sdk/lib/core/map.dart b/sdk/lib/core/map.dart
index 9c5572c..17590cc 100644
--- a/sdk/lib/core/map.dart
+++ b/sdk/lib/core/map.dart
@@ -352,5 +352,5 @@
 
   const MapEntry._(this.key, this.value);
 
-  String toString() => "MapEntry(${key.toString()}: ${value.toString()})";
+  String toString() => "MapEntry($key: $value)";
 }
diff --git a/sdk/lib/core/num.dart b/sdk/lib/core/num.dart
index 36c8fec..b560025 100644
--- a/sdk/lib/core/num.dart
+++ b/sdk/lib/core/num.dart
@@ -75,7 +75,7 @@
   /// - All other values are compared using their numeric value.
   ///
   /// Examples:
-  /// ```
+  /// ```dart
   /// print(1.compareTo(2)); // => -1
   /// print(2.compareTo(1)); // => 1
   /// print(1.compareTo(1)); // => 0
diff --git a/sdk/lib/core/object.dart b/sdk/lib/core/object.dart
index 008f969..429eba0 100644
--- a/sdk/lib/core/object.dart
+++ b/sdk/lib/core/object.dart
@@ -107,7 +107,7 @@
   /// dynamic object = 1;
   /// object.add(42); // Statically allowed, run-time error
   /// ```
-  /// This invalid code will invoke the `noSuchMethod` memthod
+  /// This invalid code will invoke the `noSuchMethod` method
   /// of the integer `1` with an [Invocation] representing the
   /// `.add(42)` call and arguments (which then throws).
   ///
diff --git a/sdk/lib/core/stopwatch.dart b/sdk/lib/core/stopwatch.dart
index 024c28f..45da67e 100644
--- a/sdk/lib/core/stopwatch.dart
+++ b/sdk/lib/core/stopwatch.dart
@@ -21,7 +21,7 @@
   ///
   /// The following example shows how to start a [Stopwatch]
   /// immediately after allocation.
-  /// ```
+  /// ```dart
   /// var stopwatch = Stopwatch()..start();
   /// ```
   Stopwatch() {
diff --git a/sdk/lib/core/string.dart b/sdk/lib/core/string.dart
index fbeae71..6f7c808 100644
--- a/sdk/lib/core/string.dart
+++ b/sdk/lib/core/string.dart
@@ -136,12 +136,12 @@
   /// [defaultValue].
   ///
   /// Example of getting a value:
-  /// ```
+  /// ```dart
   /// const String.fromEnvironment("defaultFloo", defaultValue: "no floo")
   /// ```
   /// In order to check whether a declaration is there at all, use
   /// [bool.hasEnvironment]. Example:
-  /// ```
+  /// ```dart
   /// const maybeDeclared = bool.hasEnvironment("maybeDeclared")
   ///     ? String.fromEnvironment("maybeDeclared")
   ///     : null;
@@ -333,7 +333,7 @@
   /// version 6.2 or later) and the BOM character, 0xFEFF.
   ///
   /// Here is the list of trimmed characters according to Unicode version 6.3:
-  /// ```
+  /// ```plaintext
   ///     0009..000D    ; White_Space # Cc   <control-0009>..<control-000D>
   ///     0020          ; White_Space # Zs   SPACE
   ///     0085          ; White_Space # Cc   <control-0085>
diff --git a/sdk/lib/core/string_buffer.dart b/sdk/lib/core/string_buffer.dart
index b15cb77..9f5a615 100644
--- a/sdk/lib/core/string_buffer.dart
+++ b/sdk/lib/core/string_buffer.dart
@@ -24,7 +24,7 @@
   /// operation.
   bool get isNotEmpty => !isEmpty;
 
-  /// Adds the string representatoon of [object] to the buffer.
+  /// Adds the string representation of [object] to the buffer.
   external void write(Object? object);
 
   /// Adds the string representation of [charCode] to the buffer.
diff --git a/sdk/lib/core/symbol.dart b/sdk/lib/core/symbol.dart
index d9e2540..6a3566a 100644
--- a/sdk/lib/core/symbol.dart
+++ b/sdk/lib/core/symbol.dart
@@ -29,8 +29,8 @@
   /// * such an identifier followed by "=" (a setter name),
   /// * the name of a declarable operator
   ///   (one of "`+`", "`-`", "`*`", "`/`", "`%`", "`~/`", "`&`", "`|`",
-  ///   "`^`", "`~`", "`<<`", "`>>`", "`<`", "`<=`", "`>`", "`>=`", "`==`",
-  ///   "`[]`", "`[]=`", or "`unary-`"),
+  ///   "`^`", "`~`", "`<<`", "`>>`", "`>>>`", "`<`", "`<=`", "`>`", "`>=`",
+  ///   "`==`", "`[]`", "`[]=`", or "`unary-`"),
   /// * any of the above preceded by any number of qualifiers,
   ///   where a qualifier is a non-private identifier followed by '`.`',
   /// * or the empty string (the default name of a library with no library
diff --git a/sdk/lib/core/uri.dart b/sdk/lib/core/uri.dart
index 243f7ff..7d22b20 100644
--- a/sdk/lib/core/uri.dart
+++ b/sdk/lib/core/uri.dart
@@ -127,7 +127,7 @@
   ///
   /// Examples:
   ///
-  /// ```
+  /// ```dart
   /// // http://example.org/path?q=dart.
   /// Uri.http("example.org", "/path", { "q" : "dart" });
   ///
@@ -198,7 +198,7 @@
   ///
   /// Examples using non-Windows semantics:
   ///
-  /// ```
+  /// ```dart
   /// // xxx/yyy
   /// Uri.file("xxx/yyy", windows: false);
   ///
@@ -217,7 +217,7 @@
   ///
   /// Examples using Windows semantics:
   ///
-  /// ```
+  /// ```dart
   /// // xxx/yyy
   /// Uri.file(r"xxx\yyy", windows: true);
   ///
@@ -331,7 +331,7 @@
   /// The authority is formatted from the [userInfo], [host] and [port]
   /// parts.
   ///
-  /// The valie is the empty string if there is no authority component.
+  /// The value is the empty string if there is no authority component.
   String get authority;
 
   /// The user info part of the authority component.
@@ -414,7 +414,7 @@
   /// specified for FORM post in the [HTML 4.01 specification section
   /// 17.13.4](http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.13.4 "HTML 4.01 section 17.13.4").
   ///
-  /// Each key and value in the reulting map has been decoded. If there is no
+  /// Each key and value in the resulting map has been decoded. If there is no
   /// query the map is empty.
   ///
   /// Keys are mapped to lists of their values. If a key occurs only once,
@@ -3142,7 +3142,7 @@
   /// If there is a single separator left, it ends the "base64" marker.
   ///
   /// So the following separators are found for a text:
-  /// ```
+  /// ```plaintext
   /// data:text/plain;foo=bar;base64,ARGLEBARGLE=
   ///     ^          ^   ^   ^      ^
   /// ```
@@ -3318,7 +3318,7 @@
   ///
   /// The string must have the format:
   ///
-  /// ```
+  /// ```plaintext
   /// 'data:' (type '/' subtype)? (';' attribute '=' value)* (';base64')? ',' data
   /// ````
   ///
diff --git a/sdk/lib/ffi/dynamic_library.dart b/sdk/lib/ffi/dynamic_library.dart
index bcfa586..16e1b0f 100644
--- a/sdk/lib/ffi/dynamic_library.dart
+++ b/sdk/lib/ffi/dynamic_library.dart
@@ -4,47 +4,77 @@
 
 part of dart.ffi;
 
-/// Represents a dynamically loaded C library.
+/// A dynamically loaded native library.
+///
+/// A dynamically loaded library is a mapping from symbols to memory addresses.
+/// These memory addresses can be accessed through [lookup].
 class DynamicLibrary {
   /// Creates a dynamic library holding all global symbols.
   ///
-  /// Any symbol in a library currently loaded with global visibility (including
-  /// the executable itself) may be resolved in this library.
+  /// Any symbol in a library currently loaded with global visibility
+  /// (including the executable itself) may be resolved through this library.
   ///
-  /// This feature is not available on Windows, instead an exception is thrown.
+  /// This feature is not available on Windows.
   external factory DynamicLibrary.process();
 
-  /// Creates a dynamic library representing the running executable.
+  /// Creates a dynamic library containing all the symbols of the running
+  /// executable.
   external factory DynamicLibrary.executable();
 
-  /// Loads a dynamic library file with local visibility.
+  /// Loads a library file and provides access to its symbols.
   ///
-  /// Throws an [ArgumentError] if loading the dynamic library fails.
+  /// The [path] must refer to a native library file which can be successfully
+  /// loaded.
   ///
-  /// Calling this function multiple times, even in different isolates, returns
-  /// objects which are equal but not identical. The underlying library is only
-  /// loaded once into the DartVM by the OS.
-  external factory DynamicLibrary.open(String name);
+  /// Calling this function multiple times with the same [path], even across
+  /// different isolates, only loads the library into the DartVM process once.
+  /// Multiple loads of the same library file produces [DynamicLibrary] objects
+  /// which are equal (`==`), but not [identical].
+  external factory DynamicLibrary.open(String path);
 
   /// Looks up a symbol in the [DynamicLibrary] and returns its address in
-  /// memory. Equivalent of dlsym.
+  /// memory.
   ///
-  /// Throws an [ArgumentError] if it fails to lookup the symbol.
+  /// Similar to the functionality of the
+  /// [dlsym(3)](https://man7.org/linux/man-pages/man3/dlsym.3.html) system
+  /// call.
+  ///
+  /// The symbol must be provided by the dynamic library.
   external Pointer<T> lookup<T extends NativeType>(String symbolName);
 
   /// Dynamic libraries are equal if they load the same library.
   external bool operator ==(Object other);
 
-  /// The hash code for a DynamicLibrary only depends on the loaded library
+  /// The hash code for a [DynamicLibrary] only depends on the loaded library.
   external int get hashCode;
 
-  /// The handle to the dynamic library.
+  /// The opaque handle to the dynamic library.
+  ///
+  /// Similar to the return value of
+  /// [dlopen(3)](https://man7.org/linux/man-pages/man3/dlopen.3.html).
+  /// Can be used as arguments to other functions in the `dlopen` API
+  /// through FFI calls.
   external Pointer<Void> get handle;
 }
 
-/// Methods which cannot be invoked dynamically.
+/// Method which must not be invoked dynamically.
 extension DynamicLibraryExtension on DynamicLibrary {
-  /// Helper that combines lookup and cast to a Dart function.
+  /// Looks up a native function and returns it as a Dart function.
+  ///
+  /// [T] is the C function signature, and [F] is the Dart function signature.
+  /// For example:
+  ///
+  /// ```c
+  /// int32_t add(int32_t a, int32_t b) {
+  ///   return a + b;
+  /// }
+  /// ```
+  ///
+  /// ```dart
+  /// DynamicLibrary dylib;
+  /// final add = dylib.lookupFunction<Int32 Function(Int32, Int32),
+  ///                                  int Function(int, int)>('add');
+  /// ```
   external F lookupFunction<T extends Function, F extends Function>(
       String symbolName);
 }
diff --git a/sdk/lib/ffi/ffi.dart b/sdk/lib/ffi/ffi.dart
index 8510065..733c8fe 100644
--- a/sdk/lib/ffi/ffi.dart
+++ b/sdk/lib/ffi/ffi.dart
@@ -89,15 +89,58 @@
 class Array<T extends NativeType> extends NativeType {
   /// Const constructor to specify [Array] dimensions in [Struct]s.
   ///
-  /// ```
+  /// ```dart
   /// class MyStruct extends Struct {
   ///   @Array(8)
   ///   external Array<Uint8> inlineArray;
+  ///
+  ///   @Array(2, 2, 2)
+  ///   external Array<Array<Array<Uint8>>> threeDimensionalInlineArray;
   /// }
   /// ```
   ///
   /// Do not invoke in normal code.
-  external const factory Array(int dimension1);
+  const factory Array(int dimension1,
+      [int dimension2,
+      int dimension3,
+      int dimension4,
+      int dimension5]) = _ArraySize<T>;
+
+  /// Const constructor to specify [Array] dimensions in [Struct]s.
+  ///
+  /// ```dart
+  /// class MyStruct extends Struct {
+  ///   @Array.multi([2, 2, 2])
+  ///   external Array<Array<Array<Uint8>>> threeDimensionalInlineArray;
+  ///
+  ///   @Array.multi([2, 2, 2, 2, 2, 2, 2, 2])
+  ///   external Array<Array<Array<Array<Array<Array<Array<Array<Uint8>>>>>>>> eightDimensionalInlineArray;
+  /// }
+  /// ```
+  ///
+  /// Do not invoke in normal code.
+  const factory Array.multi(List<int> dimensions) = _ArraySize<T>.multi;
+}
+
+class _ArraySize<T extends NativeType> implements Array<T> {
+  final int? dimension1;
+  final int? dimension2;
+  final int? dimension3;
+  final int? dimension4;
+  final int? dimension5;
+
+  final List<int>? dimensions;
+
+  const _ArraySize(this.dimension1,
+      [this.dimension2, this.dimension3, this.dimension4, this.dimension5])
+      : dimensions = null;
+
+  const _ArraySize.multi(this.dimensions)
+      : dimension1 = null,
+        dimension2 = null,
+        dimension3 = null,
+        dimension4 = null,
+        dimension5 = null;
 }
 
 /// Extension on [Pointer] specialized for the type argument [NativeFunction].
@@ -662,6 +705,13 @@
   external T operator [](int index);
 }
 
+/// Bounds checking indexing methods on [Array]s of [Array].
+extension ArrayArray<T extends NativeType> on Array<Array<T>> {
+  external Array<T> operator [](int index);
+
+  external void operator []=(int index, Array<T> value);
+}
+
 /// Extension to retrieve the native `Dart_Port` from a [SendPort].
 extension NativePort on SendPort {
   /// The native port of this [SendPort].
@@ -698,7 +748,7 @@
       get postCObject;
 
   /// A function pointer to
-  /// ```
+  /// ```c
   /// Dart_Port Dart_NewNativePort(const char* name,
   ///                              Dart_NativeMessageHandler handler,
   ///                              bool handle_concurrently)
diff --git a/sdk/lib/ffi/struct.dart b/sdk/lib/ffi/struct.dart
index 283d04c..ebe326a 100644
--- a/sdk/lib/ffi/struct.dart
+++ b/sdk/lib/ffi/struct.dart
@@ -17,7 +17,7 @@
 /// type [int] or [float] and be annotated with a [NativeType] representing the
 /// native type, or must be of type [Pointer]. For example:
 ///
-/// ```
+/// ```c
 /// typedef struct {
 ///  int a;
 ///  float b;
@@ -25,7 +25,7 @@
 /// } my_struct;
 /// ```
 ///
-/// ```
+/// ```dart
 /// class MyStruct extends Struct {
 ///   @Int32()
 ///   external int a;
@@ -58,3 +58,13 @@
 
   Struct._fromPointer(this._addressOf);
 }
+
+/// Annotation to specify on `Struct` subtypes to indicate that its members
+/// need to be packed.
+///
+/// Valid values for [memberAlignment] are 1, 2, 4, 8, and 16.
+class Packed {
+  final int memberAlignment;
+
+  const Packed(this.memberAlignment);
+}
diff --git a/sdk/lib/internal/symbol.dart b/sdk/lib/internal/symbol.dart
index bf48493..c65e5e8 100644
--- a/sdk/lib/internal/symbol.dart
+++ b/sdk/lib/internal/symbol.dart
@@ -50,7 +50,7 @@
    * is "unary-".
    */
   static const String operatorRE =
-      r'(?:[\-+*/%&|^]|\[\]=?|==|~/?|<[<=]?|>[>=]?|unary-)';
+      r'(?:[\-+*/%&|^]|\[\]=?|==|~/?|<[<=]?|>(?:|=|>>?)|unary-)';
 
   // Grammar if symbols:
   //    symbol ::= qualifiedName | <empty>
diff --git a/sdk/lib/io/common.dart b/sdk/lib/io/common.dart
index 252d602..a2d4d73 100644
--- a/sdk/lib/io/common.dart
+++ b/sdk/lib/io/common.dart
@@ -48,6 +48,9 @@
   /// Constant used to indicate that no OS error code is available.
   static const int noErrorCode = -1;
 
+  /// Returns error code that corresponds to EINPROGRESS OS error.
+  external static int inProgressErrorCode();
+
   /// Error message supplied by the operating system. This will be empty if no
   /// message is associated with the error.
   final String message;
diff --git a/sdk/lib/io/directory.dart b/sdk/lib/io/directory.dart
index dbbcb26..0e130aa 100644
--- a/sdk/lib/io/directory.dart
+++ b/sdk/lib/io/directory.dart
@@ -20,7 +20,7 @@
 /// ```dart
 /// var myDir = Directory('myDir');
 /// ```
-/// Most intance methods of [Directory] exist in both synchronous
+/// Most instance methods of [Directory] exist in both synchronous
 /// and asynchronous variants, for example, [create] and [createSync].
 /// Unless you have a specific reason for using the synchronous version
 /// of a method, prefer the asynchronous version to avoid blocking your program.
@@ -63,7 +63,7 @@
 ///   }
 /// }
 /// ```
-/// ## The use of asynchronnous methods
+/// ## The use of asynchronous methods
 ///
 /// I/O operations can block a program for some period of time while it waits for
 /// the operation to complete. To avoid this, all
diff --git a/sdk/lib/io/file.dart b/sdk/lib/io/file.dart
index 07c3aeb..29b2810 100644
--- a/sdk/lib/io/file.dart
+++ b/sdk/lib/io/file.dart
@@ -262,7 +262,7 @@
   /// the file when it has been created.
   ///
   /// If [recursive] is `false`, the default, the file is created only if
-  /// all directories in its path alredy exist. If [recursive] is `true`, any
+  /// all directories in its path already exist. If [recursive] is `true`, any
   /// non-existing parent paths are created first.
   ///
   /// Existing files are left untouched by [create]. Calling [create] on an
diff --git a/sdk/lib/io/file_system_entity.dart b/sdk/lib/io/file_system_entity.dart
index e624473..9a858de 100644
--- a/sdk/lib/io/file_system_entity.dart
+++ b/sdk/lib/io/file_system_entity.dart
@@ -437,7 +437,7 @@
   /// [FileSystemEvent] can be or'ed together to mix events. Default is
   /// [FileSystemEvent.ALL].
   ///
-  /// A move event may be reported as seperate delete and create events.
+  /// A move event may be reported as separate delete and create events.
   Stream<FileSystemEvent> watch(
       {int events = FileSystemEvent.all, bool recursive = false}) {
     // FIXME(bkonyi): find a way to do this using the raw path.
@@ -494,7 +494,7 @@
   /// the current working directory.
   ///
   /// On Windows, a path is absolute if it starts with `\\`
-  /// (two backslashesor representing a UNC path) or with a drive letter
+  /// (two backslashes or representing a UNC path) or with a drive letter
   /// between `a` and `z` (upper or lower case) followed by `:\` or `:/`.
   /// The makes, for example, `\file.ext` a non-absolute path
   /// because it depends on the current drive letter.
diff --git a/sdk/lib/io/io.dart b/sdk/lib/io/io.dart
index 9a89e63..84ad5f9 100644
--- a/sdk/lib/io/io.dart
+++ b/sdk/lib/io/io.dart
@@ -195,12 +195,12 @@
     show HashMap, HashSet, Queue, ListQueue, MapBase, UnmodifiableMapView;
 import 'dart:convert';
 import 'dart:developer' hide log;
-import 'dart:_http' show HttpClient;
+import 'dart:_http' show HttpClient, HttpProfiler;
 import 'dart:isolate';
 import 'dart:math';
 import 'dart:typed_data';
 
-export 'dart:_http';
+export 'dart:_http' hide HttpProfiler;
 @Deprecated("Import BytesBuilder from dart:typed_data instead")
 export 'dart:_internal' show BytesBuilder;
 export 'dart:_internal' show HttpStatus;
diff --git a/sdk/lib/io/network_profiling.dart b/sdk/lib/io/network_profiling.dart
index 95fa5a3..79ee3de 100644
--- a/sdk/lib/io/network_profiling.dart
+++ b/sdk/lib/io/network_profiling.dart
@@ -6,7 +6,7 @@
 
 // TODO(bkonyi): refactor into io_resource_info.dart
 const int _versionMajor = 1;
-const int _versionMinor = 5;
+const int _versionMinor = 6;
 
 const String _tcpSocket = 'tcp';
 const String _udpSocket = 'udp';
@@ -22,6 +22,9 @@
       'ext.dart.io.setHttpEnableTimelineLogging';
   static const _kHttpEnableTimelineLogging =
       'ext.dart.io.httpEnableTimelineLogging';
+  static const _kGetHttpProfileRPC = 'ext.dart.io.getHttpProfile';
+  static const _kGetHttpProfileRequestRPC = 'ext.dart.io.getHttpProfileRequest';
+  static const _kClearHttpProfileRPC = 'ext.dart.io.clearHttpProfile';
   // Socket relative RPCs
   static const _kClearSocketProfileRPC = 'ext.dart.io.clearSocketProfile';
   static const _kGetSocketProfileRPC = 'ext.dart.io.getSocketProfile';
@@ -48,6 +51,9 @@
     registerExtension(_kSocketProfilingEnabledRPC, _serviceExtensionHandler);
     registerExtension(_kClearSocketProfileRPC, _serviceExtensionHandler);
     registerExtension(_kGetVersionRPC, _serviceExtensionHandler);
+    registerExtension(_kGetHttpProfileRPC, _serviceExtensionHandler);
+    registerExtension(_kGetHttpProfileRequestRPC, _serviceExtensionHandler);
+    registerExtension(_kClearHttpProfileRPC, _serviceExtensionHandler);
   }
 
   static Future<ServiceExtensionResponse> _serviceExtensionHandler(
@@ -75,6 +81,20 @@
           }
           responseJson = _getHttpEnableTimelineLogging();
           break;
+        case _kGetHttpProfileRPC:
+          responseJson = HttpProfiler.toJson(
+            parameters.containsKey('updatedSince')
+                ? int.tryParse(parameters['updatedSince']!)
+                : null,
+          );
+          break;
+        case _kGetHttpProfileRequestRPC:
+          responseJson = _getHttpProfileRequest(parameters);
+          break;
+        case _kClearHttpProfileRPC:
+          HttpProfiler.clear();
+          responseJson = _success();
+          break;
         case _kGetSocketProfileRPC:
           responseJson = _SocketProfile.toJson();
           break;
@@ -94,14 +114,23 @@
           responseJson = getVersion();
           break;
         default:
-          return Future.value(ServiceExtensionResponse.error(
+          return Future.value(
+            ServiceExtensionResponse.error(
               ServiceExtensionResponse.extensionError,
-              'Method $method does not exist'));
+              'Method $method does not exist',
+            ),
+          );
       }
-      return Future.value(ServiceExtensionResponse.result(responseJson));
-    } on dynamic catch (errorMessage) {
-      return Future.value(ServiceExtensionResponse.error(
-          ServiceExtensionResponse.invalidParams, errorMessage));
+      return Future.value(
+        ServiceExtensionResponse.result(responseJson),
+      );
+    } catch (errorMessage) {
+      return Future.value(
+        ServiceExtensionResponse.error(
+          ServiceExtensionResponse.invalidParams,
+          errorMessage.toString(),
+        ),
+      );
     }
   }
 
@@ -139,6 +168,23 @@
   return _success();
 }
 
+String _getHttpProfileRequest(Map<String, String> parameters) {
+  if (!parameters.containsKey('id')) {
+    throw _missingArgument('id');
+  }
+  final id = int.tryParse(parameters['id']!);
+  if (id == null) {
+    throw _invalidArgument('id', parameters['id']!);
+  }
+  final request = HttpProfiler.getHttpProfileRequest(id);
+  if (request == null) {
+    throw "Unable to find request with id: '$id'";
+  }
+  return json.encode(
+    request.toJson(ref: false),
+  );
+}
+
 String _socketProfilingEnabled(Map<String, String> parameters) {
   const String kEnabled = 'enabled';
   if (parameters.containsKey(kEnabled)) {
@@ -224,7 +270,6 @@
         break;
       default:
         throw ArgumentError('type ${type} does not exist');
-        break;
     }
   }
 
diff --git a/sdk/lib/io/overrides.dart b/sdk/lib/io/overrides.dart
index 245b9d7..65e7acf 100644
--- a/sdk/lib/io/overrides.dart
+++ b/sdk/lib/io/overrides.dart
@@ -15,7 +15,7 @@
 /// operations needed to construct mocks. The implementations in this base class
 /// default to the actual `dart:io` implementation. For example:
 ///
-/// ```
+/// ```dart
 /// class MyDirectory implements Directory {
 ///   ...
 ///   // An implementation of the Directory interface
diff --git a/sdk/lib/io/process.dart b/sdk/lib/io/process.dart
index a1ccce6..ccb9b44 100644
--- a/sdk/lib/io/process.dart
+++ b/sdk/lib/io/process.dart
@@ -177,7 +177,7 @@
 /// main() async {
 ///   // List all files in the current directory in UNIX-like systems.
 ///   var result = await Process.run('ls', ['-l']);
-///   print(results.stdout);
+///   print(result.stdout);
 /// }
 /// ```
 /// ## Start a process with the start method
diff --git a/sdk/lib/io/secure_server_socket.dart b/sdk/lib/io/secure_server_socket.dart
index bfe34af..927883d 100644
--- a/sdk/lib/io/secure_server_socket.dart
+++ b/sdk/lib/io/secure_server_socket.dart
@@ -51,7 +51,7 @@
   /// was received, the result will be null.
   ///
   /// [supportedProtocols] is an optional list of protocols (in decreasing
-  /// order of preference) to use during the ALPN protocol negogiation with
+  /// order of preference) to use during the ALPN protocol negotiation with
   /// clients.  Example values are "http/1.1" or "h2".  The selected protocol
   /// can be obtained via [SecureSocket.selectedProtocol].
   ///
diff --git a/sdk/lib/io/security_context.dart b/sdk/lib/io/security_context.dart
index 082da28..953d1e6 100644
--- a/sdk/lib/io/security_context.dart
+++ b/sdk/lib/io/security_context.dart
@@ -85,7 +85,7 @@
   /// encoded X509 certificate. It may be called multiple times to add
   /// multiple trusted certificates to the context. A DER encoded certificate
   /// can be obtained from a PEM encoded certificate by using the openssl tool:
-  /// ```
+  /// ```bash
   /// $ openssl x509 -outform der -in cert.pem -out cert.der
   /// ```
   void setTrustedCertificates(String file, {String? password});
@@ -167,7 +167,7 @@
   ///
   /// See RFC 7301 (https://tools.ietf.org/html/rfc7301) for the encoding of
   /// `List<String> protocols`:
-  /// ```
+  /// ```plaintext
   /// opaque ProtocolName<1..2^8-1>;
   ///
   /// struct {
diff --git a/sdk/lib/io/socket.dart b/sdk/lib/io/socket.dart
index 22d57dd..ab2ecf5 100644
--- a/sdk/lib/io/socket.dart
+++ b/sdk/lib/io/socket.dart
@@ -154,7 +154,7 @@
 
   /// Looks up the addresses of a host.
   ///
-  /// If [type] is [InternetAddressType.ANY], it will lookup both
+  /// If [type] is [InternetAddressType.any], it will lookup both
   /// IP version 4 (IPv4) and IP version 6 (IPv6) addresses.
   /// If [type] is either [InternetAddressType.IPv4] or
   /// [InternetAddressType.IPv6] it will only lookup addresses of the
@@ -936,7 +936,7 @@
 
   /// Leaves a multicast group.
   ///
-  /// If an error occur when trying to join the multicase group, an
+  /// If an error occur when trying to join the multicast group, an
   /// exception is thrown.
   void leaveMulticast(InternetAddress group, [NetworkInterface? interface]);
 
diff --git a/sdk/lib/io/stdio.dart b/sdk/lib/io/stdio.dart
index 137b4e0..0ea8448 100644
--- a/sdk/lib/io/stdio.dart
+++ b/sdk/lib/io/stdio.dart
@@ -248,7 +248,7 @@
   /// Message describing cause of the exception.
   final String message;
 
-  /// The underlying OS error, if avaialble.
+  /// The underlying OS error, if available.
   final OSError? osError;
 
   const StdoutException(this.message, [this.osError]);
@@ -263,7 +263,7 @@
   /// Message describing cause of the exception.
   final String message;
 
-  /// The underlying OS error, if avaialble.
+  /// The underlying OS error, if available.
   final OSError? osError;
 
   const StdinException(this.message, [this.osError]);
diff --git a/sdk/lib/isolate/isolate.dart b/sdk/lib/isolate/isolate.dart
index 7a15d7b..3e7a592 100644
--- a/sdk/lib/isolate/isolate.dart
+++ b/sdk/lib/isolate/isolate.dart
@@ -659,7 +659,7 @@
 /// The [handler] will always be invoked  in the [Zone.root] zone.
 ///
 /// The port cannot be paused. The data-handler must be set before the first
-/// messsage is received, otherwise the message is lost.
+/// message is received, otherwise the message is lost.
 ///
 /// Messages can be sent to this port using [sendPort].
 abstract class RawReceivePort {
@@ -667,7 +667,7 @@
   ///
   /// A [RawReceivePort] is low level and does not work with [Zone]s. It
   /// cannot be paused. The data-handler must be set before the first
-  /// messsage is received, otherwise the message is lost.
+  /// message is received, otherwise the message is lost.
   ///
   /// If [handler] is provided, it's set as the [RawReceivePort.handler].
   ///
diff --git a/sdk/lib/js_util/js_util.dart b/sdk/lib/js_util/js_util.dart
index b1d0e27..df75900 100644
--- a/sdk/lib/js_util/js_util.dart
+++ b/sdk/lib/js_util/js_util.dart
@@ -149,6 +149,24 @@
   //     return _wrapToDart(jsObj);
 }
 
+/// Exception for when the promise is rejected with a `null` or `undefined`
+/// value.
+///
+/// This is public to allow users to catch when the promise is rejected with
+/// `null` or `undefined` versus some other value.
+class NullRejectionException implements Exception {
+  // Indicates whether the value is `undefined` or `null`.
+  final bool isUndefined;
+
+  NullRejectionException._(this.isUndefined);
+
+  @override
+  String toString() {
+    var value = this.isUndefined ? 'undefined' : 'null';
+    return 'Promise was rejected with a value of `$value`.';
+  }
+}
+
 /// Converts a JavaScript Promise to a Dart [Future].
 ///
 /// ```dart
@@ -163,7 +181,16 @@
   final completer = Completer<T>();
 
   final success = convertDartClosureToJS((r) => completer.complete(r), 1);
-  final error = convertDartClosureToJS((e) => completer.completeError(e), 1);
+  final error = convertDartClosureToJS((e) {
+    // Note that `completeError` expects a non-nullable error regardless of
+    // whether null-safety is enabled, so a `NullRejectionException` is always
+    // provided if the error is `null` or `undefined`.
+    if (e == null) {
+      return completer.completeError(
+          NullRejectionException._(JS('bool', '# === undefined', e)));
+    }
+    return completer.completeError(e);
+  }, 1);
 
   JS('', '#.then(#, #)', jsPromise, success, error);
   return completer.future;
diff --git a/sdk/lib/math/point.dart b/sdk/lib/math/point.dart
index b3e9432..df26e9a 100644
--- a/sdk/lib/math/point.dart
+++ b/sdk/lib/math/point.dart
@@ -19,7 +19,7 @@
   /// Whether [other] is a point with the same coordinates as this point.
   ///
   /// Returns `true` if [other] is a [Point] with [x] and [y]
-  /// coordinates equal to the corresponding coordiantes of this point,
+  /// coordinates equal to the corresponding coordinates of this point,
   /// and `false` otherwise.
   bool operator ==(Object other) =>
       other is Point && x == other.x && y == other.y;
diff --git a/sdk/lib/vmservice/named_lookup.dart b/sdk/lib/vmservice/named_lookup.dart
index d611c3d..0c0a5a8 100644
--- a/sdk/lib/vmservice/named_lookup.dart
+++ b/sdk/lib/vmservice/named_lookup.dart
@@ -4,7 +4,7 @@
 
 part of dart._vmservice;
 
-/// Set like containes which automatically generated String ids for its items
+/// Set like contains which automatically generated String ids for its items
 class NamedLookup<E extends Object> extends Object with IterableMixin<E> {
   final IdGenerator _generator;
   final _elements = <String, E>{};
diff --git a/sdk_args.gni b/sdk_args.gni
index 2776011..736f414 100644
--- a/sdk_args.gni
+++ b/sdk_args.gni
@@ -18,7 +18,13 @@
   #
   # to out/ReleaseX64/args.gn. The path above can be extracted from the `.git`
   # file under the git worktree folder.
-  default_git_folder = "$_dart_root/.git"
+  # The script run here should take care of everything automatically though.
+  default_git_folder = exec_script("$_dart_root/tools/get_dot_git_folder.py",
+                                   [
+                                     rebase_path("$_dart_root/.git"),
+                                     "$_dart_root/.git",
+                                   ],
+                                   "trim string")
 
   # Whether to enable the SDK hash check that will prevent loading a kernel
   # into a VM which was built with a different SDK.
diff --git a/tests/co19/co19-co19.status b/tests/co19/co19-co19.status
index 0f04e9d..d66d5fd 100644
--- a/tests/co19/co19-co19.status
+++ b/tests/co19/co19-co19.status
@@ -2,287 +2,5 @@
 # for details. All rights reserved. Use of this source code is governed by a
 # BSD-style license that can be found in the LICENSE file.
 
-Language/Expressions/Assignment/Compound_Assignment/null_aware_compound_assignment_static_t12: Skip # Triple shift is not implemented yet
-Language/Expressions/Assignment/Compound_Assignment/null_aware_compound_assignment_t12: Skip # Triple shift is not implemented yet
-Language/Expressions/Assignment/Compound_Assignment/variable_assignment_t12: Skip # Triple shift is not implemented yet
-Language/Expressions/Bitwise_Expressions/syntax_t01: Skip # Triple shift is not implemented yet
-Language/Expressions/Constants/bitwise_operators_t01: Skip # Triple shift is not implemented yet
-Language/Expressions/Equality/syntax_t01: Skip # Triple shift is not implemented yet
-Language/Expressions/Lists/syntax_t01: Skip # Triple shift is not implemented yet
-Language/Expressions/Maps/syntax_t01: Skip # Triple shift is not implemented yet
-Language/Reference/Operator_Precedence/precedence_01_assignment_t14: Skip # Triple shift is not implemented yet
-Language/Reference/Operator_Precedence/precedence_12_Shift_t04: Skip # Triple shift is not implemented yet
-Language/Reference/Operator_Precedence/precedence_t05: Skip # Triple shift is not implemented yet
-Language/Statements/Expression_Statements/syntax_t06: Skip # Triple shift is not implemented for integers yet
-Language/Types/Type_Aliases/built-in_types_t11: Skip # Triple shift is not implemented yet
-LanguageFeatures/Extension-methods/explicit_extension_member_invocation_A15_t09: Skip # Triple shift is not implemented yet
-LanguageFeatures/Triple-Shift/*: Skip # Triple shift is not implemented yet
-LanguageFeatures/nnbd/local_variable_read_A01_t03: Skip # Triple shift is not implemented yet
-LanguageFeatures/nnbd/local_variable_read_A02_t03: Skip # Triple shift is not implemented yet
-LanguageFeatures/nnbd/local_variable_read_A03_t03: Skip # Triple shift is not implemented yet
+LibTest/ffi/Array/PointerArray_A01_t01: Skip # https://github.com/dart-lang/co19/issues/1018
 LibTest/io/RawDatagramSocket/*: Skip # https://github.com/dart-lang/co19/issues/195
-
-[ $compiler == dart2analyzer ]
-Language/Classes/Instance_Methods/Operators/allowed_names_t01: Skip # Triple shift is not fully implemented
-Language/Classes/Instance_Methods/Operators/arity_1_t19: Skip # Triple shift is not fully implemented (https://github.com/dart-lang/sdk/issues/42353)
-Language/Functions/syntax_t03: Skip # Triple shift is not implemented yet
-
-[ $compiler != fasta ]
-Language/Classes/Abstract_Instance_Members/inherited_t13: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Abstract_Instance_Members/inherited_t14: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Abstract_Instance_Members/inherited_t15: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Abstract_Instance_Members/invocation_t05: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Abstract_Instance_Members/invocation_t06: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Abstract_Instance_Members/override_default_value_t10: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Abstract_Instance_Members/override_less_positional_parameters_t03: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Abstract_Instance_Members/override_more_required_parameters_t05: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Abstract_Instance_Members/override_no_named_parameters_t07: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Abstract_Instance_Members/override_not_a_subtype_t05: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Abstract_Instance_Members/same_name_static_method_in_superclass_t07: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Constructors/Constant_Constructors/name_t01: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Constructors/Constant_Constructors/not_a_constant_in_superclass_t03: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Constructors/Constant_Constructors/superinitializer_t05: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Constructors/Constant_Constructors/superinitializer_t06: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Constructors/Factories/name_t06: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Constructors/Factories/name_t07: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Constructors/Factories/redirecting_to_itself_t05: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Constructors/Factories/redirecting_to_itself_t06: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Constructors/Factories/redirecting_to_itself_t07: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Constructors/Factories/return_type_t08: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Constructors/Factories/return_wrong_type_t08: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Constructors/Factories/return_wrong_type_t09: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Constructors/Factories/return_wrong_type_t10: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Constructors/Generative_Constructors/execution_of_a_superinitializer_t02: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Constructors/Generative_Constructors/formal_parameter_t09: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Constructors/Generative_Constructors/formal_parameter_t10: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Constructors/Generative_Constructors/formal_parameter_t11: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Constructors/Generative_Constructors/implicit_superinitializer_t03: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Constructors/Generative_Constructors/implicit_superinitializer_t04: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Constructors/Generative_Constructors/initializers_t17: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Constructors/Generative_Constructors/name_t01: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Constructors/Generative_Constructors/superinitializer_t04: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Constructors/implicit_constructor_t04: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Constructors/implicit_constructor_t05: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Constructors/name_t08: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Constructors/wrong_name_t02: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Constructors/wrong_name_t03: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Getters/instance_getter_t13: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Getters/instance_getter_t14: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Getters/override_t05: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Getters/same_name_method_t13: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Getters/same_name_method_t14: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Getters/type_object_t03: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Instance_Methods/override_different_default_values_t03: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Instance_Methods/override_fewer_parameters_t03: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Instance_Methods/override_more_parameters_t03: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Instance_Methods/override_named_parameters_t07: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Instance_Methods/override_named_parameters_t08: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Instance_Methods/override_named_parameters_t09: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Instance_Methods/override_named_parameters_t10: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Instance_Methods/override_named_parameters_t11: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Instance_Methods/override_subtype_t07: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Instance_Methods/override_subtype_t08: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Instance_Methods/override_subtype_t09: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Instance_Methods/override_subtype_t10: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Instance_Methods/override_subtype_t11: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Instance_Methods/override_subtype_t12: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Instance_Methods/same_name_getter_t03: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Instance_Methods/same_name_setter_t03: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Instance_Methods/same_name_static_member_in_superclass_t10: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Instance_Methods/same_name_static_member_in_superclass_t11: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Instance_Variables/definition_t05: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Instance_Variables/type_aliases_t01: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Instance_Variables/type_aliases_t02: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Instance_Variables/type_aliases_t03: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Setters/syntax_t06: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Static_Methods/declaration_t04: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Static_Variables/inheritance_t02: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Static_Variables/type_alias_t01: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Superclasses/Inheritance_and_Overriding/abstract_method_t02: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Superclasses/Inheritance_and_Overriding/inheritance_t08: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Superclasses/Inheritance_and_Overriding/inheritance_t09: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Superclasses/Inheritance_and_Overriding/inheritance_t10: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Superclasses/Inheritance_and_Overriding/overriding_t06: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Superclasses/Inheritance_and_Overriding/overriding_t07: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Superclasses/Inheritance_and_Overriding/overriding_t08: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Superclasses/extends_clause_t02: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Superclasses/superclass_of_itself_t03: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Superclasses/superclass_of_itself_t04: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Superclasses/transition_t02: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Superinterfaces/dynamic_type_t03: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Superinterfaces/implicit_interface_t03: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Superinterfaces/itself_t02: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Superinterfaces/more_than_once_t02: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Superinterfaces/no_member_t06: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Superinterfaces/no_member_t07: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Superinterfaces/superclass_as_superinterface_t02: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Superinterfaces/superclass_as_superinterface_t03: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Superinterfaces/superclass_as_superinterface_t04: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Superinterfaces/syntax_t03: Skip # github.com/dart-lang/language/issues/115
-Language/Enums/restrictions_t09: Skip # github.com/dart-lang/language/issues/115
-Language/Enums/restrictions_t10: Skip # github.com/dart-lang/language/issues/115
-Language/Enums/restrictions_t11: Skip # github.com/dart-lang/language/issues/115
-Language/Enums/restrictions_t12: Skip # github.com/dart-lang/language/issues/115
-Language/Enums/syntax_t10: Skip # github.com/dart-lang/language/issues/115
-Language/Expressions/Instance_Creation/New/type_t08: Skip # github.com/dart-lang/language/issues/115
-Language/Expressions/Instance_Creation/New/type_t09: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/Superbounded_types/typedef3_A01_t01: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/Superbounded_types/typedef3_A01_t02: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/Superbounded_types/typedef3_A01_t03: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/Superbounded_types/typedef3_A01_t04: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/Superbounded_types/typedef3_A01_t05: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/Superbounded_types/typedef3_A01_t06: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/parameter_A01_t03: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/parameter_A01_t04: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/parameter_A02_t03: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/parameter_A03_t03: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/parameter_A04_t03: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/parameter_A09_t03: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/syntax_t20: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/syntax_t21: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/syntax_t22: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/syntax_t23: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/syntax_t24: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/syntax_t25: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/syntax_t27: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/syntax_t28: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/syntax_t29: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/syntax_t30: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/typedef_A01_t01: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/typedef_A01_t02: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/typedef_A01_t03: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/typedef_A01_t04: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/typedef_A01_t05: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/typedef_A01_t06: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/typedef_A01_t07: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/typedef_A01_t08: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/typedef_A01_t10: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/typedef_A04_t01: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/typedef_A04_t02: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/typedef_A06_t01: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/typedef_A06_t02: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/typedef_A06_t03: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/typedef_A06_t04: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/typedef_A06_t05: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/typedef_A06_t06: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/typedef_A06_t07: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/typedef_A06_t08: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/typedef_A06_t09: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/typedef_A06_t10: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/typedef_A06_t11: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/typedef_A06_t12: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/typedef_A06_t13: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/typedef_A06_t14: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/typedef_A07_t01: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/typedef_A08_t01: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/typedef_A09_t05: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/typedef_A09_t06: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/typedef_A10_t01: Skip # github.com/dart-lang/language/issues/115
-Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/inheritance_t09: Skip # github.com/dart-lang/language/issues/115
-Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/inheritance_t10: Skip # github.com/dart-lang/language/issues/115
-Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/inheritance_t11: Skip # github.com/dart-lang/language/issues/115
-Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/inheritance_t12: Skip # github.com/dart-lang/language/issues/115
-Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/inheritance_t13: Skip # github.com/dart-lang/language/issues/115
-Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/inheritance_t14: Skip # github.com/dart-lang/language/issues/115
-Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/not_overriden_members_t03: Skip # github.com/dart-lang/language/issues/115
-Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/not_overriden_members_t04: Skip # github.com/dart-lang/language/issues/115
-Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/same_name_getters_t03: Skip # github.com/dart-lang/language/issues/115
-Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/same_name_getters_t04: Skip # github.com/dart-lang/language/issues/115
-Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/same_name_getters_type_t10: Skip # github.com/dart-lang/language/issues/115
-Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/same_name_getters_type_t11: Skip # github.com/dart-lang/language/issues/115
-Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/same_name_getters_type_t12: Skip # github.com/dart-lang/language/issues/115
-Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/same_name_members_t03: Skip # github.com/dart-lang/language/issues/115
-Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/same_name_method_and_getter_t03: Skip # github.com/dart-lang/language/issues/115
-Language/Interfaces/Superinterfaces/definition_t06: Skip # github.com/dart-lang/language/issues/115
-Language/Interfaces/Superinterfaces/superinterface_of_itself_t04: Skip # github.com/dart-lang/language/issues/115
-Language/Mixins/Mixin_Application/abstract_t09: Skip # github.com/dart-lang/language/issues/115
-Language/Mixins/Mixin_Application/abstract_t10: Skip # github.com/dart-lang/language/issues/115
-Language/Mixins/Mixin_Application/abstract_t11: Skip # github.com/dart-lang/language/issues/115
-Language/Mixins/Mixin_Application/abstract_t12: Skip # github.com/dart-lang/language/issues/115
-Language/Mixins/Mixin_Application/abstract_t13: Skip # github.com/dart-lang/language/issues/115
-Language/Mixins/Mixin_Application/deferred_t03: Skip # github.com/dart-lang/language/issues/115
-Language/Mixins/Mixin_Application/implicit_constructor_t03: Skip # github.com/dart-lang/language/issues/115
-Language/Mixins/Mixin_Application/implicit_constructor_t04: Skip # github.com/dart-lang/language/issues/115
-Language/Mixins/Mixin_Application/initializers_t04: Skip # github.com/dart-lang/language/issues/115
-Language/Mixins/Mixin_Application/initializers_t05: Skip # github.com/dart-lang/language/issues/115
-Language/Mixins/Mixin_Application/initializers_t06: Skip # github.com/dart-lang/language/issues/115
-Language/Mixins/Mixin_Application/interfaces_t06: Skip # github.com/dart-lang/language/issues/115
-Language/Mixins/Mixin_Application/interfaces_t07: Skip # github.com/dart-lang/language/issues/115
-Language/Mixins/Mixin_Application/superclass_t03: Skip # github.com/dart-lang/language/issues/115
-Language/Mixins/Mixin_Application/superclass_t04: Skip # github.com/dart-lang/language/issues/115
-Language/Mixins/Mixin_Application/superinterfaces_t10: Skip # github.com/dart-lang/language/issues/115
-Language/Mixins/Mixin_Application/superinterfaces_t11: Skip # github.com/dart-lang/language/issues/115
-Language/Mixins/Mixin_Application/superinterfaces_t12: Skip # github.com/dart-lang/language/issues/115
-Language/Mixins/Mixin_Application/superinterfaces_t13: Skip # github.com/dart-lang/language/issues/115
-Language/Mixins/Mixin_Application/superinterfaces_t14: Skip # github.com/dart-lang/language/issues/115
-Language/Mixins/Mixin_Application/syntax_t26: Skip # github.com/dart-lang/language/issues/115
-Language/Mixins/Mixin_Application/warning_t04: Skip # github.com/dart-lang/language/issues/115
-Language/Mixins/Mixin_Application/wrong_mixin_type_t09: Skip # github.com/dart-lang/language/issues/115
-Language/Mixins/Mixin_Composition/order_t02: Skip # github.com/dart-lang/language/issues/115
-Language/Mixins/declaring_constructor_t11: Skip # github.com/dart-lang/language/issues/115
-Language/Types/Type_Aliases/built-in_types_t01: Skip # github.com/dart-lang/language/issues/115
-Language/Types/Type_Aliases/built-in_types_t02: Skip # github.com/dart-lang/language/issues/115
-Language/Types/Type_Aliases/built-in_types_t03: Skip # github.com/dart-lang/language/issues/115
-Language/Types/Type_Aliases/built-in_types_t04: Skip # github.com/dart-lang/language/issues/115
-Language/Types/Type_Aliases/built-in_types_t05: Skip # github.com/dart-lang/language/issues/115
-Language/Types/Type_Aliases/built-in_types_t06: Skip # github.com/dart-lang/language/issues/115
-Language/Types/Type_Aliases/built-in_types_t07: Skip # github.com/dart-lang/language/issues/115
-Language/Types/Type_Aliases/built-in_types_t08: Skip # github.com/dart-lang/language/issues/115
-Language/Types/Type_Aliases/built-in_types_t09: Skip # github.com/dart-lang/language/issues/115
-Language/Types/Type_Aliases/built-in_types_t10: Skip # github.com/dart-lang/language/issues/115
-Language/Types/Type_Aliases/built-in_types_t11: Skip # github.com/dart-lang/language/issues/115
-Language/Types/Type_Aliases/built-in_types_t12: Skip # github.com/dart-lang/language/issues/115
-Language/Types/Type_Aliases/scope_t01: Skip # github.com/dart-lang/language/issues/115
-Language/Types/Type_Aliases/scope_t02: Skip # github.com/dart-lang/language/issues/115
-Language/Types/Type_Aliases/scope_t03: Skip # github.com/dart-lang/language/issues/115
-Language/Types/Type_Aliases/scope_t04: Skip # github.com/dart-lang/language/issues/115
-Language/Types/Type_Aliases/self_reference_t19: Skip # github.com/dart-lang/language/issues/115
-Language/Types/Type_Aliases/self_reference_t20: Skip # github.com/dart-lang/language/issues/115
-Language/Types/Type_Aliases/self_reference_t21: Skip # github.com/dart-lang/language/issues/115
-Language/Types/Type_Aliases/self_reference_t22: Skip # github.com/dart-lang/language/issues/115
-Language/Types/Type_Aliases/self_reference_t23: Skip # github.com/dart-lang/language/issues/115
-Language/Types/Type_Aliases/self_reference_t24: Skip # github.com/dart-lang/language/issues/115
-Language/Types/Type_Aliases/self_reference_t25: Skip # github.com/dart-lang/language/issues/115
-Language/Types/Type_Aliases/syntax_t01: Skip # github.com/dart-lang/language/issues/115
-Language/Types/Type_Aliases/syntax_t02: Skip # github.com/dart-lang/language/issues/115
-Language/Types/Type_Aliases/syntax_t03: Skip # github.com/dart-lang/language/issues/115
-Language/Types/Type_Aliases/syntax_t04: Skip # github.com/dart-lang/language/issues/115
-Language/Types/Type_Aliases/syntax_t05: Skip # github.com/dart-lang/language/issues/115
-Language/Types/Type_Aliases/syntax_t06: Skip # github.com/dart-lang/language/issues/115
-Language/Types/Type_Aliases/syntax_t20: Skip # github.com/dart-lang/language/issues/115
-Language/Types/Type_Aliases/syntax_t21: Skip # github.com/dart-lang/language/issues/115
-LanguageFeatures/Instantiate-to-bound/nonfunction_typedef/dynamic/*: Skip # github.com/dart-lang/language/issues/115
-LanguageFeatures/Instantiate-to-bound/nonfunction_typedef/static/*: Skip # github.com/dart-lang/language/issues/115
-LanguageFeatures/Simple-bounds/dynamic/typedef1_FutureOr_l1_t01: Skip # github.com/dart-lang/language/issues/115
-LanguageFeatures/Simple-bounds/dynamic/typedef1_FutureOr_l1_t02: Skip # github.com/dart-lang/language/issues/115
-LanguageFeatures/Simple-bounds/dynamic/typedef1_l1_t01: Skip # github.com/dart-lang/language/issues/115
-LanguageFeatures/Simple-bounds/dynamic/typedef1_l1_t02: Skip # github.com/dart-lang/language/issues/115
-LanguageFeatures/Simple-bounds/dynamic/typedef1_l1_t03: Skip # github.com/dart-lang/language/issues/115
-LanguageFeatures/Simple-bounds/dynamic/typedef1_l1_t04: Skip # github.com/dart-lang/language/issues/115
-LanguageFeatures/Simple-bounds/dynamic/typedef1_l2_t01: Skip # github.com/dart-lang/language/issues/115
-LanguageFeatures/Simple-bounds/dynamic/typedef1_l2_t02: Skip # github.com/dart-lang/language/issues/115
-LanguageFeatures/Simple-bounds/dynamic/typedef1_typedef_l1_t01: Skip # github.com/dart-lang/language/issues/115
-LanguageFeatures/Simple-bounds/dynamic/typedef1_typedef_l1_t02: Skip # github.com/dart-lang/language/issues/115
-LanguageFeatures/Simple-bounds/dynamic/typedef1_typedef_l1_t03: Skip # github.com/dart-lang/language/issues/115
-LanguageFeatures/Simple-bounds/dynamic/typedef1_typedef_l1_t04: Skip # github.com/dart-lang/language/issues/115
-LanguageFeatures/Simple-bounds/dynamic/typedef1_typedef_l1_t05: Skip # github.com/dart-lang/language/issues/115
-LanguageFeatures/Simple-bounds/dynamic/typedef1_typedef_l1_t07: Skip # github.com/dart-lang/language/issues/115
-LanguageFeatures/Simple-bounds/dynamic/typedef1_typedef_l1_t08: Skip # github.com/dart-lang/language/issues/115
-LanguageFeatures/Simple-bounds/static/typedef1_FutureOr_l1_t01: Skip # github.com/dart-lang/language/issues/115
-LanguageFeatures/Simple-bounds/static/typedef1_FutureOr_l1_t02: Skip # github.com/dart-lang/language/issues/115
-LanguageFeatures/Simple-bounds/static/typedef1_l1_t01: Skip # github.com/dart-lang/language/issues/115
-LanguageFeatures/Simple-bounds/static/typedef1_l1_t02: Skip # github.com/dart-lang/language/issues/115
-LanguageFeatures/Simple-bounds/static/typedef1_l1_t03: Skip # github.com/dart-lang/language/issues/115
-LanguageFeatures/Simple-bounds/static/typedef1_l1_t04: Skip # github.com/dart-lang/language/issues/115
-LanguageFeatures/Simple-bounds/static/typedef1_l2_t01: Skip # github.com/dart-lang/language/issues/115
-LanguageFeatures/Simple-bounds/static/typedef1_l2_t02: Skip # github.com/dart-lang/language/issues/115
-LanguageFeatures/Simple-bounds/static/typedef1_typedef_l1_t01: Skip # github.com/dart-lang/language/issues/115
-LanguageFeatures/Simple-bounds/static/typedef1_typedef_l1_t02: Skip # github.com/dart-lang/language/issues/115
-LanguageFeatures/Simple-bounds/static/typedef1_typedef_l1_t03: Skip # github.com/dart-lang/language/issues/115
-LanguageFeatures/Simple-bounds/static/typedef1_typedef_l1_t04: Skip # github.com/dart-lang/language/issues/115
-LanguageFeatures/Simple-bounds/static/typedef1_typedef_l1_t05: Skip # github.com/dart-lang/language/issues/115
-LanguageFeatures/Simple-bounds/static/typedef1_typedef_l1_t06: Skip # github.com/dart-lang/language/issues/115
-LanguageFeatures/Simple-bounds/static/typedef1_typedef_l1_t07: Skip # github.com/dart-lang/language/issues/115
-LanguageFeatures/Simple-bounds/static/typedef1_typedef_l1_t08: Skip # github.com/dart-lang/language/issues/115
-LanguageFeatures/regression/32903_t02: Skip # github.com/dart-lang/language/issues/115
-LanguageFeatures/regression/34560_t02: Skip # github.com/dart-lang/language/issues/115
diff --git a/tests/co19/co19-dart2js.status b/tests/co19/co19-dart2js.status
index 1e1adac..cab4c50 100644
--- a/tests/co19/co19-dart2js.status
+++ b/tests/co19/co19-dart2js.status
@@ -3,19 +3,19 @@
 # BSD-style license that can be found in the LICENSE file.
 
 [ $compiler == dart2js ]
-Language/Expressions/Constants/integer_size_t03: SkipByDesign # big integer cannot be represented in JavaScript
-Language/Expressions/Constants/integer_size_t04: SkipByDesign # big integer cannot be represented in JavaScript
-Language/Expressions/Constants/literal_number_t01: SkipByDesign # big integer cannot be represented in JavaScript
-Language/Expressions/Constants/math_operators_t01: SkipByDesign # big integer cannot be represented in JavaScript
-Language/Expressions/Constants/math_operators_t06: SkipByDesign # big integer cannot be represented in JavaScript
+Language/Expressions/Constants/integer_size_t03: SkipByDesign # uses integer literal not representable as JavaScript number
+Language/Expressions/Constants/integer_size_t04: SkipByDesign # uses integer literal not representable as JavaScript number
+Language/Expressions/Constants/literal_number_t01: SkipByDesign # uses integer literal not representable as JavaScript number
+Language/Expressions/Constants/math_operators_t01: SkipByDesign # uses integer literal not representable as JavaScript number
+Language/Expressions/Constants/math_operators_t06: SkipByDesign # uses integer literal not representable as JavaScript number
 Language/Expressions/Null/instance_of_class_null_t01: Skip # dart:mirrors not supported https://github.com/dart-lang/co19/issues/522.
-Language/Expressions/Numbers/integer_size_t03: SkipByDesign # big integer cannot be represented in JavaScript
-Language/Expressions/Numbers/static_type_of_int_t01: SkipByDesign # big integer cannot be represented in JavaScript
-Language/Expressions/Numbers/syntax_t06: SkipByDesign # big integer cannot be represented in JavaScript
-Language/Expressions/Numbers/syntax_t09: SkipByDesign # big integer cannot be represented in JavaScript
+Language/Expressions/Numbers/integer_size_t03: SkipByDesign # uses integer literal not representable as JavaScript number
+Language/Expressions/Numbers/static_type_of_int_t01: SkipByDesign # uses integer literal not representable as JavaScript number
+Language/Expressions/Numbers/syntax_t06: SkipByDesign # uses integer literal not representable as JavaScript number
+Language/Expressions/Numbers/syntax_t09: SkipByDesign # uses integer literal not representable as JavaScript number
 Language/Expressions/Object_Identity/object_t02: SkipByDesign # https://github.com/dart-lang/sdk/issues/42222#issuecomment-640431711
-Language/Expressions/Shift/integer_t01: SkipByDesign # big integer cannot be represented in JavaScript
-Language/Expressions/Shift/integer_t02: SkipByDesign # big integer cannot be represented in JavaScript
+Language/Expressions/Shift/integer_t06: SkipByDesign # uses integer literal not representable as JavaScript number
+Language/Expressions/Shift/integer_t07: SkipByDesign # uses integer literal not representable as JavaScript number
 Language/Expressions/Spawning_an_Isolate/new_isolate_t01: SkipByDesign
 Language/Functions/External_Functions/not_connected_to_a_body_t01: SkipByDesign # Non-JS-interop external members are not supported
 Language/Libraries_and_Scripts/Scripts/main_optional_parameters_t01: SkipByDesign # https://github.com/dart-lang/co19/issues/952
@@ -23,6 +23,7 @@
 Language/Libraries_and_Scripts/Scripts/top_level_syntax_t01: SkipByDesign # Non-JS-interop external members are not supported
 Language/Libraries_and_Scripts/top_level_syntax_t01: SkipByDesign # Non-JS-interop external members are not supported
 Language/Metadata/before*: Skip # dart:mirrors not supported https://github.com/dart-lang/co19/issues/523.
+Language/Metadata/syntax_t10: SkipByDesign # dart:mirrors is not supported
 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 # Non-JS-interop external members are not supported
 LanguageFeatures/Abstract-external-fields/static_analysis_external_A01_t02: SkipByDesign # Non-JS-interop external members are not supported
diff --git a/tests/co19/co19-dartdevc.status b/tests/co19/co19-dartdevc.status
index 7f9fab3..f326b5f 100644
--- a/tests/co19/co19-dartdevc.status
+++ b/tests/co19/co19-dartdevc.status
@@ -52,26 +52,27 @@
 Language/Classes/Instance_Variables/definition_t02: Skip # Times out
 Language/Classes/Instance_Variables/definition_t04: Skip # Times out
 Language/Classes/Setters/instance_setter_t01: Skip # Times out
-Language/Expressions/Constants/integer_size_t03: SkipByDesign # big integer cannot be represented in JavaScript
-Language/Expressions/Constants/integer_size_t04: SkipByDesign # big integer cannot be represented in JavaScript
-Language/Expressions/Constants/literal_number_t01: SkipByDesign # big integer cannot be represented in JavaScript
-Language/Expressions/Constants/math_operators_t01: SkipByDesign # big integer cannot be represented in JavaScript
-Language/Expressions/Constants/math_operators_t06: SkipByDesign # big integer cannot be represented in JavaScript
+Language/Expressions/Constants/integer_size_t03: SkipByDesign # uses integer literal not representable as JavaScript number
+Language/Expressions/Constants/integer_size_t04: SkipByDesign # uses integer literal not representable as JavaScript number
+Language/Expressions/Constants/literal_number_t01: SkipByDesign # uses integer literal not representable as JavaScript number
+Language/Expressions/Constants/math_operators_t01: SkipByDesign # uses integer literal not representable as JavaScript number
+Language/Expressions/Constants/math_operators_t06: SkipByDesign # uses integer literal not representable as JavaScript number
 Language/Expressions/Function_Invocation/async_generator_invokation_t08: Skip # Times out
 Language/Expressions/Function_Invocation/async_generator_invokation_t10: Skip # Times out
 Language/Expressions/Null/instance_of_class_null_t01: Skip # dart:mirrors not supported https://github.com/dart-lang/co19/issues/522.
-Language/Expressions/Numbers/integer_size_t03: SkipByDesign # big integer cannot be represented in JavaScript
-Language/Expressions/Numbers/static_type_of_int_t01: SkipByDesign # big integer cannot be represented in JavaScript
-Language/Expressions/Numbers/syntax_t06: SkipByDesign # big integer cannot be represented in JavaScript
-Language/Expressions/Numbers/syntax_t09: SkipByDesign # big integer cannot be represented in JavaScript
+Language/Expressions/Numbers/integer_size_t03: SkipByDesign # uses integer literal not representable as JavaScript number
+Language/Expressions/Numbers/static_type_of_int_t01: SkipByDesign # uses integer literal not representable as JavaScript number
+Language/Expressions/Numbers/syntax_t06: SkipByDesign # uses integer literal not representable as JavaScript number
+Language/Expressions/Numbers/syntax_t09: SkipByDesign # uses integer literal not representable as JavaScript number
 Language/Expressions/Object_Identity/object_t02: SkipByDesign # https://github.com/dart-lang/sdk/issues/42222#issuecomment-640431711
-Language/Expressions/Shift/integer_t01: SkipByDesign # big integer cannot be represented in JavaScript
-Language/Expressions/Shift/integer_t02: SkipByDesign # big integer cannot be represented in JavaScript
+Language/Expressions/Shift/integer_t06: SkipByDesign # uses integer literal not representable as JavaScript number
+Language/Expressions/Shift/integer_t07: SkipByDesign # uses integer literal not representable as JavaScript number
 Language/Expressions/Spawning_an_Isolate/new_isolate_t01: SkipByDesign # dart:isolate not supported.
 Language/Functions/External_Functions/not_connected_to_a_body_t01: SkipByDesign # External variables are not supported
 Language/Libraries_and_Scripts/Scripts/top_level_syntax_t01: SkipByDesign # External variables are not supported
 Language/Libraries_and_Scripts/top_level_syntax_t01: SkipByDesign # External variables are not supported
 Language/Metadata/before*: Skip # dart:mirrors not supported https://github.com/dart-lang/co19/issues/523.
+Language/Metadata/syntax_t10: SkipByDesign # dart:mirrors is not supported
 Language/Reference/Operator_Precedence/precedence_15_unary_prefix_t08: SkipByDesign # binary '~' produces different results in JavaScript and Dart
 Language/Types/Interface_Types/subtype_t27: Skip # Times out
 Language/Types/Interface_Types/subtype_t28: Skip # Times out
diff --git a/tests/co19/co19-kernel.status b/tests/co19/co19-kernel.status
index d8b00ce..21682f1 100644
--- a/tests/co19/co19-kernel.status
+++ b/tests/co19/co19-kernel.status
@@ -13,6 +13,7 @@
 LanguageFeatures/Constant-update-2018/NewOperators_A01_t06/none: Crash
 
 [ $runtime == dart_precompiled ]
+Language/Metadata/syntax_t10: SkipByDesign # dart:mirrors is not supported
 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
@@ -29,161 +30,6 @@
 LibTest/core/List/List_class_A01_t02: Slow, Pass # Does many calls
 LibTest/io/RawDatagramSocket/*: Skip # RawDatagramSocket are flacky. Skip them all until rewritten
 
-[ $fasta ]
-Language/Classes/Instance_Methods/Operators/allowed_names_t01: Skip # triple-shift flag
-Language/Classes/Instance_Methods/Operators/allowed_names_t23: Skip # triple-shift flag
-Language/Classes/Instance_Methods/Operators/arity_1_t19: Skip # triple-shift flag
-Language/Enums/restrictions_t10: Crash
-Language/Expressions/Assignment/Compound_Assignment/expression_assignment_t12: Skip # triple-shift flag
-Language/Expressions/Assignment/Compound_Assignment/indexed_expression_assignment_t12: Skip # triple-shift flag
-Language/Expressions/Assignment/Compound_Assignment/null_aware_compound_assignment_static_t12: Skip # triple-shift flag
-Language/Expressions/Assignment/Compound_Assignment/null_aware_compound_assignment_t12: Skip # triple-shift flag
-Language/Expressions/Assignment/Compound_Assignment/setter_assignment_t12: Skip # triple-shift flag
-Language/Expressions/Assignment/Compound_Assignment/variable_assignment_t12: Skip # triple-shift flag
-Language/Expressions/Bitwise_Expressions/syntax_t01: Skip # triple-shift flag
-Language/Expressions/Constants/bitwise_operators_t01: Skip # triple-shift flag
-Language/Expressions/Constants/bitwise_operators_t07: Skip # triple-shift flag
-Language/Expressions/Constants/bitwise_operators_t08: Skip # triple-shift flag
-Language/Expressions/Equality/syntax_t01: Skip # triple-shift flag
-Language/Expressions/Lists/syntax_t01: Skip # triple-shift flag
-Language/Expressions/Maps/syntax_t01: Skip # triple-shift flag
-Language/Expressions/Relational_Expressions/syntax_t01: Skip # triple-shift experiment flag
-Language/Expressions/Shift/allowed_characters_t02: Skip # triple-shift flag
-Language/Expressions/Shift/equivalent_super_t02: Skip # triple-shift flag
-Language/Expressions/Shift/equivalent_t02: Skip # triple-shift flag
-Language/Expressions/Shift/integer_t03: Skip # triple-shift flag
-Language/Expressions/Shift/integer_t04/01: Crash
-Language/Expressions/Shift/integer_t04/02: Crash
-Language/Expressions/Shift/integer_t04/03: Crash
-Language/Expressions/Shift/integer_t04/04: Crash
-Language/Expressions/Shift/integer_t04/05: Crash
-Language/Expressions/Shift/integer_t04/06: Crash
-Language/Expressions/Shift/integer_t04/07: Crash
-Language/Expressions/Shift/integer_t04/none: Crash
-Language/Expressions/Shift/syntax_t01: Skip # triple-shift experiment flag
-Language/Expressions/Shift/syntax_t15: Skip # triple-shift experiment flag
-Language/Expressions/Shift/syntax_t17: Skip # triple-shift experiment flag
-Language/Expressions/Shift/syntax_t18: Skip # triple-shift experiment flag
-Language/Expressions/Shift/syntax_t19: Skip # triple-shift experiment flag
-Language/Expressions/Shift/syntax_t21: Skip # triple-shift experiment flag
-Language/Expressions/Shift/syntax_t22: Skip # triple-shift experiment flag
-Language/Expressions/Shift/syntax_t23: Skip # triple-shift experiment flag
-Language/Expressions/Shift/syntax_t24: Skip # triple-shift experiment flag
-Language/Expressions/Shift/syntax_t25: Skip # triple-shift experiment flag
-Language/Expressions/Shift/syntax_t26: Skip # triple-shift experiment flag
-Language/Expressions/Shift/syntax_t27: Skip # triple-shift experiment flag
-Language/Expressions/Strings/String_Interpolation/syntax_t01: Skip # triple-shift experiment flag
-Language/Expressions/Symbols/syntax_t02: Skip # triple-shift experiment flag
-Language/Expressions/parentheses_t01: Skip # triple-shift experiment flag
-Language/Functions/syntax_t03: Skip # triple-shift experiment flag
-Language/Mixins/Mixin_Application/abstract_t09: Crash
-Language/Mixins/Mixin_Application/abstract_t10: Crash
-Language/Mixins/Mixin_Application/abstract_t11: Crash
-Language/Mixins/Mixin_Application/abstract_t12: Crash
-Language/Mixins/Mixin_Application/abstract_t13: Crash
-Language/Mixins/Mixin_Application/deferred_t03: Crash
-Language/Mixins/Mixin_Application/implicit_constructor_t03: Crash
-Language/Mixins/Mixin_Application/implicit_constructor_t04: Crash
-Language/Mixins/Mixin_Application/initializers_t04: Crash
-Language/Mixins/Mixin_Application/initializers_t05: Crash
-Language/Mixins/Mixin_Application/initializers_t06: Crash
-Language/Mixins/Mixin_Application/interfaces_t06: Crash
-Language/Mixins/Mixin_Application/interfaces_t07: Crash
-Language/Mixins/Mixin_Application/superclass_t03: Crash
-Language/Mixins/Mixin_Application/superclass_t04: Crash
-Language/Mixins/Mixin_Application/superinterfaces_t10: Crash
-Language/Mixins/Mixin_Application/superinterfaces_t11: Crash
-Language/Mixins/Mixin_Application/superinterfaces_t13: Crash
-Language/Mixins/Mixin_Application/superinterfaces_t14: Crash
-Language/Mixins/Mixin_Application/syntax_t26: Crash
-Language/Mixins/Mixin_Application/warning_t04: Crash
-Language/Mixins/Mixin_Application/wrong_mixin_type_t09: Crash
-Language/Mixins/Mixin_Composition/order_t02: Crash
-Language/Mixins/declaring_constructor_t11: Crash
-Language/Reference/Operator_Precedence/precedence_01_assignment_t14: Skip # triple-shift experimental flag
-Language/Reference/Operator_Precedence/precedence_12_Shift_t04: Skip # triple-shift experimental flag
-Language/Reference/Operator_Precedence/precedence_t05: Skip # triple-shift experimental flag
-Language/Statements/Expression_Statements/syntax_t06: Skip # triple-shift experimental flag
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t01: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t02: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t03/01: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t03/02: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t03/03: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t03/04: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t03/05: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t03/06: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t03/none: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t04: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t04/01: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t04/02: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t04/03: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t04/04: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t04/none: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t05/01: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t05/02: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t05/03: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t05/04: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t05/05: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t05/06: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t05/none: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t06/01: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t06/02: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t06/03: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t06/04: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t06/05: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t06/06: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t07: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t07/01: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t07/02: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t07/03: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t07/04: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t07/05: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t07/06: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t07/none: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t08/01: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t08/02: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t08/03: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t08/04: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t08/05: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t08/none: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t09: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t10/01: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t10/02: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t10/03: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t10/04: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t10/05: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t10/06: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t10/none: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t11: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t12/01: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t12/02: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t12/03: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t12/04: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t12/05: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t12/none: Crash
-LanguageFeatures/Instantiate-to-bound/class/dynamic/class_FutureOr_l1_t01: Crash
-LanguageFeatures/Instantiate-to-bound/class/dynamic/class_FutureOr_l1_t03: Crash
-LanguageFeatures/Instantiate-to-bound/class/static/class_FutureOr_l1_t01: Crash
-LanguageFeatures/Instantiate-to-bound/class/static/class_FutureOr_l1_t01/01: Crash
-LanguageFeatures/Instantiate-to-bound/class/static/class_FutureOr_l1_t01/02: Crash
-LanguageFeatures/Instantiate-to-bound/class/static/class_FutureOr_l1_t01/03: Crash
-LanguageFeatures/Instantiate-to-bound/class/static/class_FutureOr_l1_t01/04: Crash
-LanguageFeatures/Instantiate-to-bound/class/static/class_FutureOr_l1_t01/none: Crash
-LanguageFeatures/Instantiate-to-bound/class/static/class_FutureOr_l1_t03/01: Crash
-LanguageFeatures/Instantiate-to-bound/class/static/class_FutureOr_l1_t03/02: Crash
-LanguageFeatures/Instantiate-to-bound/class/static/class_FutureOr_l1_t03/none: Crash
-LanguageFeatures/Instantiate-to-bound/class/static/class_typedef_l1_t04/01: Crash
-LanguageFeatures/Instantiate-to-bound/class/static/class_typedef_l1_t04/02: Crash
-LanguageFeatures/Instantiate-to-bound/class/static/class_typedef_l1_t04/none: Crash
-LanguageFeatures/Instantiate-to-bound/class/static/class_typedef_l2_t04/01: Crash
-LanguageFeatures/Instantiate-to-bound/class/static/class_typedef_l2_t04/none: Crash
-LanguageFeatures/Instantiate-to-bound/class/static/class_typedef_l2_t08/01: Crash
-LanguageFeatures/Instantiate-to-bound/class/static/class_typedef_l2_t08/02: Crash
-LanguageFeatures/Instantiate-to-bound/class/static/class_typedef_l2_t08/none: Crash
-LanguageFeatures/Set-literals/disambiguating_A02_t03: Crash
-LanguageFeatures/regression/34803_t01: Crash
-LanguageFeatures/regression/34803_t02: Crash
-
 [ $compiler == dartk && $runtime == vm && $system == linux ]
 LibTest/isolate/Isolate/spawn_A06_t03: Crash
 
diff --git a/tests/co19/co19-runtime.status b/tests/co19/co19-runtime.status
index d54175c..80fa459 100644
--- a/tests/co19/co19-runtime.status
+++ b/tests/co19/co19-runtime.status
@@ -42,4 +42,5 @@
 LibTest/ffi/*: SkipByDesign # dart:ffi is not supported on sim architectures
 
 [ $compiler == fasta || $runtime == dart_precompiled || $runtime == vm ]
+Language/Expressions/Numbers/syntax_t34: SkipByDesign # expects integer literal error that only occurs in JS
 LibTest/html/*: SkipByDesign # dart:html not supported on VM.
diff --git a/tests/co19_2/co19_2-co19.status b/tests/co19_2/co19_2-co19.status
index 484a90b..c281e44 100644
--- a/tests/co19_2/co19_2-co19.status
+++ b/tests/co19_2/co19_2-co19.status
@@ -3,264 +3,4 @@
 # BSD-style license that can be found in the LICENSE file.
 
 [ $compiler != fasta ]
-Language/Classes/Abstract_Instance_Members/inherited_t13: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Abstract_Instance_Members/inherited_t14: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Abstract_Instance_Members/inherited_t15: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Abstract_Instance_Members/invocation_t05: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Abstract_Instance_Members/invocation_t06: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Abstract_Instance_Members/override_default_value_t10: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Abstract_Instance_Members/override_less_positional_parameters_t03: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Abstract_Instance_Members/override_more_required_parameters_t05: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Abstract_Instance_Members/override_no_named_parameters_t07: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Abstract_Instance_Members/override_not_a_subtype_t05: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Abstract_Instance_Members/same_name_static_method_in_superclass_t07: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Constructors/Constant_Constructors/name_t01: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Constructors/Constant_Constructors/not_a_constant_in_superclass_t03: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Constructors/Constant_Constructors/superinitializer_t05: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Constructors/Constant_Constructors/superinitializer_t06: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Constructors/Factories/name_t06: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Constructors/Factories/name_t07: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Constructors/Factories/redirecting_constructor_call_t03: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Constructors/Factories/redirecting_constructor_t04: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Constructors/Factories/redirecting_to_itself_t05: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Constructors/Factories/redirecting_to_itself_t06: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Constructors/Factories/redirecting_to_itself_t07: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Constructors/Factories/return_type_t08: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Constructors/Factories/return_wrong_type_t08: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Constructors/Factories/return_wrong_type_t09: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Constructors/Factories/return_wrong_type_t10: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Constructors/Generative_Constructors/execution_of_a_superinitializer_t02: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Constructors/Generative_Constructors/formal_parameter_t09: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Constructors/Generative_Constructors/formal_parameter_t10: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Constructors/Generative_Constructors/formal_parameter_t11: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Constructors/Generative_Constructors/implicit_superinitializer_t03: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Constructors/Generative_Constructors/implicit_superinitializer_t04: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Constructors/Generative_Constructors/initializers_t17: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Constructors/Generative_Constructors/name_t01: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Constructors/Generative_Constructors/superinitializer_t04: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Constructors/implicit_constructor_t04: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Constructors/implicit_constructor_t05: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Constructors/name_t08: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Constructors/wrong_name_t02: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Constructors/wrong_name_t03: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Getters/instance_getter_t13: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Getters/instance_getter_t14: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Getters/override_t05: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Getters/same_name_method_t13: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Getters/same_name_method_t14: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Getters/type_object_t03: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Instance_Methods/override_different_default_values_t03: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Instance_Methods/override_fewer_parameters_t03: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Instance_Methods/override_more_parameters_t03: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Instance_Methods/override_named_parameters_t07: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Instance_Methods/override_named_parameters_t08: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Instance_Methods/override_named_parameters_t09: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Instance_Methods/override_named_parameters_t10: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Instance_Methods/override_named_parameters_t11: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Instance_Methods/override_subtype_t07: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Instance_Methods/override_subtype_t08: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Instance_Methods/override_subtype_t09: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Instance_Methods/override_subtype_t10: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Instance_Methods/override_subtype_t11: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Instance_Methods/override_subtype_t12: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Instance_Methods/same_name_getter_t03: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Instance_Methods/same_name_setter_t03: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Instance_Methods/same_name_static_member_in_superclass_t10: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Instance_Methods/same_name_static_member_in_superclass_t11: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Instance_Variables/definition_t05: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Instance_Variables/type_aliases_t01: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Instance_Variables/type_aliases_t02: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Instance_Variables/type_aliases_t03: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Setters/syntax_t06: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Static_Methods/declaration_t04: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Static_Variables/inheritance_t02: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Static_Variables/type_alias_t01: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Superclasses/Inheritance_and_Overriding/abstract_method_t02: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Superclasses/Inheritance_and_Overriding/inheritance_t08: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Superclasses/Inheritance_and_Overriding/inheritance_t09: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Superclasses/Inheritance_and_Overriding/inheritance_t10: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Superclasses/Inheritance_and_Overriding/overriding_t06: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Superclasses/Inheritance_and_Overriding/overriding_t07: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Superclasses/Inheritance_and_Overriding/overriding_t08: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Superclasses/extends_clause_t02: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Superclasses/superclass_of_itself_t03: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Superclasses/superclass_of_itself_t04: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Superclasses/transition_t02: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Superinterfaces/dynamic_type_t03: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Superinterfaces/implicit_interface_t03: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Superinterfaces/itself_t02: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Superinterfaces/more_than_once_t02: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Superinterfaces/no_member_t06: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Superinterfaces/no_member_t07: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Superinterfaces/superclass_as_superinterface_t02: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Superinterfaces/superclass_as_superinterface_t03: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Superinterfaces/superclass_as_superinterface_t04: Skip # github.com/dart-lang/language/issues/115
-Language/Classes/Superinterfaces/syntax_t03: Skip # github.com/dart-lang/language/issues/115
-Language/Enums/restrictions_t09: Skip # github.com/dart-lang/language/issues/115
-Language/Enums/restrictions_t10: Skip # github.com/dart-lang/language/issues/115
-Language/Enums/restrictions_t11: Skip # github.com/dart-lang/language/issues/115
-Language/Enums/restrictions_t12: Skip # github.com/dart-lang/language/issues/115
-Language/Enums/syntax_t10: Skip # github.com/dart-lang/language/issues/115
-Language/Expressions/Instance_Creation/New/type_t08: Skip # github.com/dart-lang/language/issues/115
-Language/Expressions/Instance_Creation/New/type_t09: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/Superbounded_types/typedef3_A01_t01: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/Superbounded_types/typedef3_A01_t02: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/Superbounded_types/typedef3_A01_t03: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/Superbounded_types/typedef3_A01_t04: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/Superbounded_types/typedef3_A01_t05: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/Superbounded_types/typedef3_A01_t06: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/parameter_A01_t03: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/parameter_A01_t04: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/parameter_A02_t03: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/parameter_A03_t03: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/parameter_A04_t03: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/parameter_A09_t03: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/syntax_t20: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/syntax_t21: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/syntax_t22: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/syntax_t23: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/syntax_t24: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/syntax_t25: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/syntax_t27: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/syntax_t28: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/syntax_t29: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/syntax_t30: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/typedef_A01_t01: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/typedef_A01_t02: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/typedef_A01_t03: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/typedef_A01_t04: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/typedef_A01_t05: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/typedef_A01_t06: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/typedef_A01_t07: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/typedef_A01_t08: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/typedef_A01_t10: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/typedef_A04_t01: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/typedef_A04_t02: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/typedef_A06_t01: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/typedef_A06_t02: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/typedef_A06_t03: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/typedef_A06_t04: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/typedef_A06_t05: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/typedef_A06_t06: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/typedef_A06_t07: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/typedef_A06_t08: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/typedef_A06_t09: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/typedef_A06_t10: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/typedef_A06_t11: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/typedef_A06_t12: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/typedef_A06_t13: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/typedef_A06_t14: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/typedef_A07_t01: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/typedef_A08_t01: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/typedef_A09_t05: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/typedef_A09_t06: Skip # github.com/dart-lang/language/issues/115
-Language/Generics/typedef_A10_t01: Skip # github.com/dart-lang/language/issues/115
-Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/inheritance_t09: Skip # github.com/dart-lang/language/issues/115
-Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/inheritance_t10: Skip # github.com/dart-lang/language/issues/115
-Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/inheritance_t11: Skip # github.com/dart-lang/language/issues/115
-Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/inheritance_t12: Skip # github.com/dart-lang/language/issues/115
-Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/inheritance_t13: Skip # github.com/dart-lang/language/issues/115
-Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/inheritance_t14: Skip # github.com/dart-lang/language/issues/115
-Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/not_overriden_members_t03: Skip # github.com/dart-lang/language/issues/115
-Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/not_overriden_members_t04: Skip # github.com/dart-lang/language/issues/115
-Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/same_name_getters_t03: Skip # github.com/dart-lang/language/issues/115
-Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/same_name_getters_t04: Skip # github.com/dart-lang/language/issues/115
-Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/same_name_getters_type_t10: Skip # github.com/dart-lang/language/issues/115
-Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/same_name_getters_type_t11: Skip # github.com/dart-lang/language/issues/115
-Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/same_name_getters_type_t12: Skip # github.com/dart-lang/language/issues/115
-Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/same_name_members_t03: Skip # github.com/dart-lang/language/issues/115
-Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/same_name_method_and_getter_t03: Skip # github.com/dart-lang/language/issues/115
-Language/Interfaces/Superinterfaces/definition_t06: Skip # github.com/dart-lang/language/issues/115
-Language/Interfaces/Superinterfaces/superinterface_of_itself_t04: Skip # github.com/dart-lang/language/issues/115
-Language/Mixins/Mixin_Application/abstract_t09: Skip # github.com/dart-lang/language/issues/115
-Language/Mixins/Mixin_Application/abstract_t10: Skip # github.com/dart-lang/language/issues/115
-Language/Mixins/Mixin_Application/abstract_t11: Skip # github.com/dart-lang/language/issues/115
-Language/Mixins/Mixin_Application/abstract_t12: Skip # github.com/dart-lang/language/issues/115
-Language/Mixins/Mixin_Application/abstract_t13: Skip # github.com/dart-lang/language/issues/115
-Language/Mixins/Mixin_Application/deferred_t03: Skip # github.com/dart-lang/language/issues/115
-Language/Mixins/Mixin_Application/implicit_constructor_t03: Skip # github.com/dart-lang/language/issues/115
-Language/Mixins/Mixin_Application/implicit_constructor_t04: Skip # github.com/dart-lang/language/issues/115
-Language/Mixins/Mixin_Application/initializers_t04: Skip # github.com/dart-lang/language/issues/115
-Language/Mixins/Mixin_Application/initializers_t05: Skip # github.com/dart-lang/language/issues/115
-Language/Mixins/Mixin_Application/initializers_t06: Skip # github.com/dart-lang/language/issues/115
-Language/Mixins/Mixin_Application/interfaces_t06: Skip # github.com/dart-lang/language/issues/115
-Language/Mixins/Mixin_Application/interfaces_t07: Skip # github.com/dart-lang/language/issues/115
-Language/Mixins/Mixin_Application/superclass_t03: Skip # github.com/dart-lang/language/issues/115
-Language/Mixins/Mixin_Application/superclass_t04: Skip # github.com/dart-lang/language/issues/115
-Language/Mixins/Mixin_Application/superinterfaces_t10: Skip # github.com/dart-lang/language/issues/115
-Language/Mixins/Mixin_Application/superinterfaces_t11: Skip # github.com/dart-lang/language/issues/115
-Language/Mixins/Mixin_Application/superinterfaces_t12: Skip # github.com/dart-lang/language/issues/115
-Language/Mixins/Mixin_Application/superinterfaces_t13: Skip # github.com/dart-lang/language/issues/115
-Language/Mixins/Mixin_Application/superinterfaces_t14: Skip # github.com/dart-lang/language/issues/115
-Language/Mixins/Mixin_Application/syntax_t26: Skip # github.com/dart-lang/language/issues/115
-Language/Mixins/Mixin_Application/warning_t04: Skip # github.com/dart-lang/language/issues/115
-Language/Mixins/Mixin_Application/wrong_mixin_type_t09: Skip # github.com/dart-lang/language/issues/115
-Language/Mixins/Mixin_Composition/order_t02: Skip # github.com/dart-lang/language/issues/115
-Language/Mixins/declaring_constructor_t11: Skip # github.com/dart-lang/language/issues/115
-Language/Types/Type_Aliases/built-in_types_t01: Skip # github.com/dart-lang/language/issues/115
-Language/Types/Type_Aliases/built-in_types_t02: Skip # github.com/dart-lang/language/issues/115
-Language/Types/Type_Aliases/built-in_types_t03: Skip # github.com/dart-lang/language/issues/115
-Language/Types/Type_Aliases/built-in_types_t04: Skip # github.com/dart-lang/language/issues/115
-Language/Types/Type_Aliases/built-in_types_t05: Skip # github.com/dart-lang/language/issues/115
-Language/Types/Type_Aliases/built-in_types_t06: Skip # github.com/dart-lang/language/issues/115
-Language/Types/Type_Aliases/built-in_types_t07: Skip # github.com/dart-lang/language/issues/115
-Language/Types/Type_Aliases/built-in_types_t08: Skip # github.com/dart-lang/language/issues/115
-Language/Types/Type_Aliases/built-in_types_t09: Skip # github.com/dart-lang/language/issues/115
-Language/Types/Type_Aliases/built-in_types_t10: Skip # github.com/dart-lang/language/issues/115
-Language/Types/Type_Aliases/built-in_types_t11: Skip # github.com/dart-lang/language/issues/115
-Language/Types/Type_Aliases/built-in_types_t12: Skip # github.com/dart-lang/language/issues/115
-Language/Types/Type_Aliases/scope_t01: Skip # github.com/dart-lang/language/issues/115
-Language/Types/Type_Aliases/scope_t02: Skip # github.com/dart-lang/language/issues/115
-Language/Types/Type_Aliases/scope_t03: Skip # github.com/dart-lang/language/issues/115
-Language/Types/Type_Aliases/scope_t04: Skip # github.com/dart-lang/language/issues/115
-Language/Types/Type_Aliases/self_reference_t19: Skip # github.com/dart-lang/language/issues/115
-Language/Types/Type_Aliases/self_reference_t20: Skip # github.com/dart-lang/language/issues/115
-Language/Types/Type_Aliases/self_reference_t21: Skip # github.com/dart-lang/language/issues/115
-Language/Types/Type_Aliases/self_reference_t22: Skip # github.com/dart-lang/language/issues/115
-Language/Types/Type_Aliases/self_reference_t23: Skip # github.com/dart-lang/language/issues/115
-Language/Types/Type_Aliases/self_reference_t24: Skip # github.com/dart-lang/language/issues/115
-Language/Types/Type_Aliases/self_reference_t25: Skip # github.com/dart-lang/language/issues/115
-Language/Types/Type_Aliases/syntax_t01: Skip # github.com/dart-lang/language/issues/115
-Language/Types/Type_Aliases/syntax_t02: Skip # github.com/dart-lang/language/issues/115
-Language/Types/Type_Aliases/syntax_t03: Skip # github.com/dart-lang/language/issues/115
-Language/Types/Type_Aliases/syntax_t04: Skip # github.com/dart-lang/language/issues/115
-Language/Types/Type_Aliases/syntax_t05: Skip # github.com/dart-lang/language/issues/115
-Language/Types/Type_Aliases/syntax_t06: Skip # github.com/dart-lang/language/issues/115
-Language/Types/Type_Aliases/syntax_t20: Skip # github.com/dart-lang/language/issues/115
-Language/Types/Type_Aliases/syntax_t21: Skip # github.com/dart-lang/language/issues/115
-LanguageFeatures/Instantiate-to-bound/nonfunction_typedef/dynamic/*: Skip # github.com/dart-lang/language/issues/115
-LanguageFeatures/Instantiate-to-bound/nonfunction_typedef/static/*: Skip # github.com/dart-lang/language/issues/115
-LanguageFeatures/Simple-bounds/dynamic/typedef1_FutureOr_l1_t01: Skip # github.com/dart-lang/language/issues/115
-LanguageFeatures/Simple-bounds/dynamic/typedef1_FutureOr_l1_t02: Skip # github.com/dart-lang/language/issues/115
-LanguageFeatures/Simple-bounds/dynamic/typedef1_l1_t01: Skip # github.com/dart-lang/language/issues/115
-LanguageFeatures/Simple-bounds/dynamic/typedef1_l1_t02: Skip # github.com/dart-lang/language/issues/115
-LanguageFeatures/Simple-bounds/dynamic/typedef1_l1_t03: Skip # github.com/dart-lang/language/issues/115
-LanguageFeatures/Simple-bounds/dynamic/typedef1_l1_t04: Skip # github.com/dart-lang/language/issues/115
-LanguageFeatures/Simple-bounds/dynamic/typedef1_l2_t01: Skip # github.com/dart-lang/language/issues/115
-LanguageFeatures/Simple-bounds/dynamic/typedef1_l2_t02: Skip # github.com/dart-lang/language/issues/115
-LanguageFeatures/Simple-bounds/dynamic/typedef1_typedef_l1_t01: Skip # github.com/dart-lang/language/issues/115
-LanguageFeatures/Simple-bounds/dynamic/typedef1_typedef_l1_t02: Skip # github.com/dart-lang/language/issues/115
-LanguageFeatures/Simple-bounds/dynamic/typedef1_typedef_l1_t03: Skip # github.com/dart-lang/language/issues/115
-LanguageFeatures/Simple-bounds/dynamic/typedef1_typedef_l1_t04: Skip # github.com/dart-lang/language/issues/115
-LanguageFeatures/Simple-bounds/dynamic/typedef1_typedef_l1_t05: Skip # github.com/dart-lang/language/issues/115
-LanguageFeatures/Simple-bounds/dynamic/typedef1_typedef_l1_t07: Skip # github.com/dart-lang/language/issues/115
-LanguageFeatures/Simple-bounds/dynamic/typedef1_typedef_l1_t08: Skip # github.com/dart-lang/language/issues/115
-LanguageFeatures/Simple-bounds/static/typedef1_FutureOr_l1_t01: Skip # github.com/dart-lang/language/issues/115
-LanguageFeatures/Simple-bounds/static/typedef1_FutureOr_l1_t02: Skip # github.com/dart-lang/language/issues/115
-LanguageFeatures/Simple-bounds/static/typedef1_l1_t01: Skip # github.com/dart-lang/language/issues/115
-LanguageFeatures/Simple-bounds/static/typedef1_l1_t02: Skip # github.com/dart-lang/language/issues/115
-LanguageFeatures/Simple-bounds/static/typedef1_l1_t03: Skip # github.com/dart-lang/language/issues/115
-LanguageFeatures/Simple-bounds/static/typedef1_l1_t04: Skip # github.com/dart-lang/language/issues/115
-LanguageFeatures/Simple-bounds/static/typedef1_l2_t01: Skip # github.com/dart-lang/language/issues/115
-LanguageFeatures/Simple-bounds/static/typedef1_l2_t02: Skip # github.com/dart-lang/language/issues/115
-LanguageFeatures/Simple-bounds/static/typedef1_typedef_l1_t01: Skip # github.com/dart-lang/language/issues/115
-LanguageFeatures/Simple-bounds/static/typedef1_typedef_l1_t02: Skip # github.com/dart-lang/language/issues/115
-LanguageFeatures/Simple-bounds/static/typedef1_typedef_l1_t03: Skip # github.com/dart-lang/language/issues/115
-LanguageFeatures/Simple-bounds/static/typedef1_typedef_l1_t04: Skip # github.com/dart-lang/language/issues/115
-LanguageFeatures/Simple-bounds/static/typedef1_typedef_l1_t05: Skip # github.com/dart-lang/language/issues/115
-LanguageFeatures/Simple-bounds/static/typedef1_typedef_l1_t06: Skip # github.com/dart-lang/language/issues/115
-LanguageFeatures/Simple-bounds/static/typedef1_typedef_l1_t07: Skip # github.com/dart-lang/language/issues/115
-LanguageFeatures/Simple-bounds/static/typedef1_typedef_l1_t08: Skip # github.com/dart-lang/language/issues/115
-LanguageFeatures/regression/32903_t02: Skip # github.com/dart-lang/language/issues/115
-LanguageFeatures/regression/34560_t02: Skip # github.com/dart-lang/language/issues/115
 
diff --git a/tests/co19_2/co19_2-dart2js.status b/tests/co19_2/co19_2-dart2js.status
index 0d620e8..63158f2 100644
--- a/tests/co19_2/co19_2-dart2js.status
+++ b/tests/co19_2/co19_2-dart2js.status
@@ -4,6 +4,8 @@
 
 [ $compiler == dart2js ]
 Language/Expressions/Null/instance_of_class_null_t01: Skip # dart:mirrors not supported https://github.com/dart-lang/co19/issues/522.
+Language/Expressions/Numbers/syntax_t06: SkipByDesign # uses integer literal not representable as JavaScript number
+Language/Expressions/Numbers/syntax_t09: SkipByDesign # uses integer literal not representable as JavaScript number
 Language/Expressions/Spawning_an_Isolate/new_isolate_t01: SkipByDesign
 Language/Functions/External_Functions/not_connected_to_a_body_t01: SkipByDesign # Non-JS-interop external members are not supported
 Language/Libraries_and_Scripts/Scripts/top_level_syntax_t01: SkipByDesign # Non-JS-interop external members are not supported
diff --git a/tests/co19_2/co19_2-dartdevc.status b/tests/co19_2/co19_2-dartdevc.status
index 7497344..4ce31b8 100644
--- a/tests/co19_2/co19_2-dartdevc.status
+++ b/tests/co19_2/co19_2-dartdevc.status
@@ -55,6 +55,8 @@
 Language/Expressions/Function_Invocation/async_generator_invokation_t08: Skip # Times out
 Language/Expressions/Function_Invocation/async_generator_invokation_t10: Skip # Times out
 Language/Expressions/Null/instance_of_class_null_t01: Skip # dart:mirrors not supported https://github.com/dart-lang/co19/issues/522.
+Language/Expressions/Numbers/syntax_t06: SkipByDesign # uses integer literal not representable as JavaScript number
+Language/Expressions/Numbers/syntax_t09: SkipByDesign # uses integer literal not representable as JavaScript number
 Language/Expressions/Spawning_an_Isolate/new_isolate_t01: SkipByDesign # dart:isolate not supported.
 Language/Functions/External_Functions/not_connected_to_a_body_t01: SkipByDesign # External variables are not supported
 Language/Libraries_and_Scripts/Scripts/top_level_syntax_t01: SkipByDesign # External variables are not supported
diff --git a/tests/co19_2/co19_2-kernel.status b/tests/co19_2/co19_2-kernel.status
index 6af3349..8f395a7 100644
--- a/tests/co19_2/co19_2-kernel.status
+++ b/tests/co19_2/co19_2-kernel.status
@@ -18,161 +18,6 @@
 LibTest/core/List/List_class_A01_t02: Slow, Pass # Does many calls
 LibTest/io/RawDatagramSocket/*: Skip # RawDatagramSocket are flacky. Skip them all until rewritten
 
-[ $fasta ]
-Language/Classes/Instance_Methods/Operators/allowed_names_t01: Skip # triple-shift flag
-Language/Classes/Instance_Methods/Operators/allowed_names_t23: Skip # triple-shift flag
-Language/Classes/Instance_Methods/Operators/arity_1_t19: Skip # triple-shift flag
-Language/Enums/restrictions_t10: Crash
-Language/Expressions/Assignment/Compound_Assignment/expression_assignment_t12: Skip # triple-shift flag
-Language/Expressions/Assignment/Compound_Assignment/indexed_expression_assignment_t12: Skip # triple-shift flag
-Language/Expressions/Assignment/Compound_Assignment/null_aware_compound_assignment_static_t12: Skip # triple-shift flag
-Language/Expressions/Assignment/Compound_Assignment/null_aware_compound_assignment_t12: Skip # triple-shift flag
-Language/Expressions/Assignment/Compound_Assignment/setter_assignment_t12: Skip # triple-shift flag
-Language/Expressions/Assignment/Compound_Assignment/variable_assignment_t12: Skip # triple-shift flag
-Language/Expressions/Bitwise_Expressions/syntax_t01: Skip # triple-shift flag
-Language/Expressions/Constants/bitwise_operators_t01: Skip # triple-shift flag
-Language/Expressions/Constants/bitwise_operators_t07: Skip # triple-shift flag
-Language/Expressions/Constants/bitwise_operators_t08: Skip # triple-shift flag
-Language/Expressions/Equality/syntax_t01: Skip # triple-shift flag
-Language/Expressions/Lists/syntax_t01: Skip # triple-shift flag
-Language/Expressions/Maps/syntax_t01: Skip # triple-shift flag
-Language/Expressions/Relational_Expressions/syntax_t01: Skip # triple-shift experiment flag
-Language/Expressions/Shift/allowed_characters_t02: Skip # triple-shift flag
-Language/Expressions/Shift/equivalent_super_t02: Skip # triple-shift flag
-Language/Expressions/Shift/equivalent_t02: Skip # triple-shift flag
-Language/Expressions/Shift/integer_t03: Skip # triple-shift flag
-Language/Expressions/Shift/integer_t04/01: Crash
-Language/Expressions/Shift/integer_t04/02: Crash
-Language/Expressions/Shift/integer_t04/03: Crash
-Language/Expressions/Shift/integer_t04/04: Crash
-Language/Expressions/Shift/integer_t04/05: Crash
-Language/Expressions/Shift/integer_t04/06: Crash
-Language/Expressions/Shift/integer_t04/07: Crash
-Language/Expressions/Shift/integer_t04/none: Crash
-Language/Expressions/Shift/syntax_t01: Skip # triple-shift experiment flag
-Language/Expressions/Shift/syntax_t15: Skip # triple-shift experiment flag
-Language/Expressions/Shift/syntax_t17: Skip # triple-shift experiment flag
-Language/Expressions/Shift/syntax_t18: Skip # triple-shift experiment flag
-Language/Expressions/Shift/syntax_t19: Skip # triple-shift experiment flag
-Language/Expressions/Shift/syntax_t21: Skip # triple-shift experiment flag
-Language/Expressions/Shift/syntax_t22: Skip # triple-shift experiment flag
-Language/Expressions/Shift/syntax_t23: Skip # triple-shift experiment flag
-Language/Expressions/Shift/syntax_t24: Skip # triple-shift experiment flag
-Language/Expressions/Shift/syntax_t25: Skip # triple-shift experiment flag
-Language/Expressions/Shift/syntax_t26: Skip # triple-shift experiment flag
-Language/Expressions/Shift/syntax_t27: Skip # triple-shift experiment flag
-Language/Expressions/Strings/String_Interpolation/syntax_t01: Skip # triple-shift experiment flag
-Language/Expressions/Symbols/syntax_t02: Skip # triple-shift experiment flag
-Language/Expressions/parentheses_t01: Skip # triple-shift experiment flag
-Language/Functions/syntax_t03: Skip # triple-shift experiment flag
-Language/Mixins/Mixin_Application/abstract_t09: Crash
-Language/Mixins/Mixin_Application/abstract_t10: Crash
-Language/Mixins/Mixin_Application/abstract_t11: Crash
-Language/Mixins/Mixin_Application/abstract_t12: Crash
-Language/Mixins/Mixin_Application/abstract_t13: Crash
-Language/Mixins/Mixin_Application/deferred_t03: Crash
-Language/Mixins/Mixin_Application/implicit_constructor_t03: Crash
-Language/Mixins/Mixin_Application/implicit_constructor_t04: Crash
-Language/Mixins/Mixin_Application/initializers_t04: Crash
-Language/Mixins/Mixin_Application/initializers_t05: Crash
-Language/Mixins/Mixin_Application/initializers_t06: Crash
-Language/Mixins/Mixin_Application/interfaces_t06: Crash
-Language/Mixins/Mixin_Application/interfaces_t07: Crash
-Language/Mixins/Mixin_Application/superclass_t03: Crash
-Language/Mixins/Mixin_Application/superclass_t04: Crash
-Language/Mixins/Mixin_Application/superinterfaces_t10: Crash
-Language/Mixins/Mixin_Application/superinterfaces_t11: Crash
-Language/Mixins/Mixin_Application/superinterfaces_t13: Crash
-Language/Mixins/Mixin_Application/superinterfaces_t14: Crash
-Language/Mixins/Mixin_Application/syntax_t26: Crash
-Language/Mixins/Mixin_Application/warning_t04: Crash
-Language/Mixins/Mixin_Application/wrong_mixin_type_t09: Crash
-Language/Mixins/Mixin_Composition/order_t02: Crash
-Language/Mixins/declaring_constructor_t11: Crash
-Language/Reference/Operator_Precedence/precedence_01_assignment_t14: Skip # triple-shift experimental flag
-Language/Reference/Operator_Precedence/precedence_12_Shift_t04: Skip # triple-shift experimental flag
-Language/Reference/Operator_Precedence/precedence_t05: Skip # triple-shift experimental flag
-Language/Statements/Expression_Statements/syntax_t06: Skip # triple-shift experimental flag
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t01: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t02: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t03/01: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t03/02: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t03/03: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t03/04: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t03/05: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t03/06: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t03/none: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t04: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t04/01: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t04/02: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t04/03: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t04/04: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t04/none: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t05/01: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t05/02: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t05/03: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t05/04: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t05/05: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t05/06: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t05/none: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t06/01: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t06/02: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t06/03: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t06/04: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t06/05: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t06/06: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t07: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t07/01: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t07/02: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t07/03: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t07/04: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t07/05: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t07/06: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t07/none: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t08/01: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t08/02: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t08/03: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t08/04: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t08/05: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t08/none: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t09: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t10/01: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t10/02: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t10/03: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t10/04: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t10/05: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t10/06: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t10/none: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t11: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t12/01: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t12/02: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t12/03: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t12/04: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t12/05: Crash
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t12/none: Crash
-LanguageFeatures/Instantiate-to-bound/class/dynamic/class_FutureOr_l1_t01: Crash
-LanguageFeatures/Instantiate-to-bound/class/dynamic/class_FutureOr_l1_t03: Crash
-LanguageFeatures/Instantiate-to-bound/class/static/class_FutureOr_l1_t01: Crash
-LanguageFeatures/Instantiate-to-bound/class/static/class_FutureOr_l1_t01/01: Crash
-LanguageFeatures/Instantiate-to-bound/class/static/class_FutureOr_l1_t01/02: Crash
-LanguageFeatures/Instantiate-to-bound/class/static/class_FutureOr_l1_t01/03: Crash
-LanguageFeatures/Instantiate-to-bound/class/static/class_FutureOr_l1_t01/04: Crash
-LanguageFeatures/Instantiate-to-bound/class/static/class_FutureOr_l1_t01/none: Crash
-LanguageFeatures/Instantiate-to-bound/class/static/class_FutureOr_l1_t03/01: Crash
-LanguageFeatures/Instantiate-to-bound/class/static/class_FutureOr_l1_t03/02: Crash
-LanguageFeatures/Instantiate-to-bound/class/static/class_FutureOr_l1_t03/none: Crash
-LanguageFeatures/Instantiate-to-bound/class/static/class_typedef_l1_t04/01: Crash
-LanguageFeatures/Instantiate-to-bound/class/static/class_typedef_l1_t04/02: Crash
-LanguageFeatures/Instantiate-to-bound/class/static/class_typedef_l1_t04/none: Crash
-LanguageFeatures/Instantiate-to-bound/class/static/class_typedef_l2_t04/01: Crash
-LanguageFeatures/Instantiate-to-bound/class/static/class_typedef_l2_t04/none: Crash
-LanguageFeatures/Instantiate-to-bound/class/static/class_typedef_l2_t08/01: Crash
-LanguageFeatures/Instantiate-to-bound/class/static/class_typedef_l2_t08/02: Crash
-LanguageFeatures/Instantiate-to-bound/class/static/class_typedef_l2_t08/none: Crash
-LanguageFeatures/Set-literals/disambiguating_A02_t03: Crash
-LanguageFeatures/regression/34803_t01: Crash
-LanguageFeatures/regression/34803_t02: Crash
-
 [ $compiler == dartk && $runtime == vm && $system == linux ]
 LibTest/isolate/Isolate/spawn_A06_t03: Crash
 
@@ -193,3 +38,4 @@
 # These Isolate tests that use spawnURI are hence skipped on purpose.
 [ $runtime == dart_precompiled || $runtime == vm && ($arch == simarm || $arch == simarm64 || $arch == simarm64c) ]
 LibTest/isolate/Isolate/spawnUri*: Skip
+
diff --git a/tests/co19_2/co19_2-runtime.status b/tests/co19_2/co19_2-runtime.status
index a09c881..c9cfe7d 100644
--- a/tests/co19_2/co19_2-runtime.status
+++ b/tests/co19_2/co19_2-runtime.status
@@ -33,4 +33,5 @@
 LibTest/collection/ListMixin/ListMixin_class_A01_t06: SkipSlow # Very slow on sim* architectures.
 
 [ $compiler == fasta || $runtime == dart_precompiled || $runtime == vm ]
+Language/Expressions/Numbers/syntax_t34: SkipByDesign # expects integer literal error that only occurs in JS
 LibTest/html/*: SkipByDesign # dart:html not supported on VM.
diff --git a/tests/corelib/splay_tree_test.dart b/tests/corelib/splay_tree_test.dart
index 6048410..9ca5cb8 100644
--- a/tests/corelib/splay_tree_test.dart
+++ b/tests/corelib/splay_tree_test.dart
@@ -28,7 +28,6 @@
   for (var v in ["first", "second", "third", "fourth", "fifth"]) {
     Expect.isTrue(tree.containsValue(v));
   }
-  ;
   Expect.isFalse(tree.containsValue("sixth"));
 
   tree[7] = "seventh";
@@ -55,6 +54,7 @@
   regressRemoveWhere();
   regressRemoveWhere2();
   regressFromCompare();
+  regressIncomparable();
 }
 
 void regressRemoveWhere() {
@@ -132,6 +132,63 @@
   Expect.equals(42, map[key(5)]);
 }
 
+// Incomparable keys throw when added, even on an empty collection.
+void regressIncomparable() {
+  var set = SplayTreeSet();
+  Expect.throws(() => set.add(IncomparableKey(0)));
+  Expect.throws(() => set.lookup(IncomparableKey(0)));
+  set.add(1);
+  Expect.throws(() => set.add(IncomparableKey(0)));
+  Expect.throws(() => set.lookup(IncomparableKey(0)));
+
+  var map = SplayTreeMap();
+  Expect.throws(() => map[IncomparableKey(0)] = 0);
+  Expect.throws(() => map.putIfAbsent(IncomparableKey(0), () => 0));
+  map[1] = 1;
+  Expect.throws(() => map[IncomparableKey(0)] = 0);
+  Expect.throws(() => map.putIfAbsent(IncomparableKey(0), () => 0));
+
+  // But not if the compare function allows them.
+  // This now includes `null`.
+  int compare(Object? o1, Object? o2) {
+    if (o1 == null) return o2 == null ? 0 : -1;
+    if (o2 == null) return 1;
+    if (o1 is IncomparableKey && o2 is IncomparableKey) {
+      return o1.id - o2.id;
+    }
+    throw UnsupportedError("Nope");
+  }
+  for (var key in [null, IncomparableKey(0)]) {
+    set = SplayTreeSet<Object?>(compare);
+    set.add(key);
+    Expect.equals(1, set.length);
+    set.clear();
+    Expect.isNull(set.lookup(key));
+    set.clear();
+    set.add(IncomparableKey(1));
+    set.add(key);
+    Expect.identical(key, set.first);
+    Expect.identical(key, set.lookup(key));
+
+    map = SplayTreeMap<Object?, Object?>(compare);
+    map[key] = 0;
+    Expect.isTrue(map.containsKey(key));
+    map.clear();
+    map.putIfAbsent(key, () => 0);
+    Expect.isTrue(map.containsKey(key));
+    map.clear();
+    map[IncomparableKey(1)] = 0;
+    map[key] = 0;
+    Expect.isTrue(map.containsKey(key));
+    map.remove(key);
+    Expect.isFalse(map.containsKey(key));
+    map.putIfAbsent(key, () => 0);
+    Expect.isTrue(map.containsKey(key));
+    map.remove(key);
+    Expect.isFalse(map.containsKey(key));
+  }
+}
+
 class IncomparableKey {
   final int id;
   IncomparableKey(this.id);
diff --git a/tests/corelib/unsigned_shift_test.dart b/tests/corelib/unsigned_shift_test.dart
index c190ff3..ab3220f 100644
--- a/tests/corelib/unsigned_shift_test.dart
+++ b/tests/corelib/unsigned_shift_test.dart
@@ -13,7 +13,7 @@
 
 main() {
   testIntegerShifts();
-  testNonDoubleShifts();
+  testNonIntegerShifts();
   testConstantShifts();
 }
 
@@ -47,18 +47,18 @@
   // If so, it is zero when converted to a fixed precision.
   if (double.infinity is int) {
     int number = (double.infinity as int);
-    Expect.equals(0, number >> 1);
-    Expect.throws(() => 1 >>> number); // infinity > 64.
+    Expect.equals(0, number >>> 1);
+    Expect.equals(0, 1 >>> number); // infinity > 64.
   }
 }
 
-void testNonDoubleShifts() {
+void testNonIntegerShifts() {
   double n = 0.0;
   n >>> 1; //# 01: compile-time error
   for (dynamic number in [0.0, 1.0, 2.4, -2.4, double.infinity, double.nan]) {
     if (number is! int) {
-      Expect.throws(() => number >>> 1);
-      Expect.throws(() => 1 >>> number);
+      Expect.throws(() => number >>> 1); //# 07: ok
+      Expect.throws(() => 1 >>> number); //# 08: ok
     }
   }
 }
diff --git a/tests/corelib_2/splay_tree_test.dart b/tests/corelib_2/splay_tree_test.dart
index 6048410..807d700 100644
--- a/tests/corelib_2/splay_tree_test.dart
+++ b/tests/corelib_2/splay_tree_test.dart
@@ -28,7 +28,6 @@
   for (var v in ["first", "second", "third", "fourth", "fifth"]) {
     Expect.isTrue(tree.containsValue(v));
   }
-  ;
   Expect.isFalse(tree.containsValue("sixth"));
 
   tree[7] = "seventh";
@@ -55,6 +54,7 @@
   regressRemoveWhere();
   regressRemoveWhere2();
   regressFromCompare();
+  regressIncomparable();
 }
 
 void regressRemoveWhere() {
@@ -132,6 +132,63 @@
   Expect.equals(42, map[key(5)]);
 }
 
+// Incomparable keys throw when added, even on an empty collection.
+void regressIncomparable() {
+  var set = SplayTreeSet();
+  Expect.throws(() => set.add(IncomparableKey(0)));
+  Expect.throws(() => set.lookup(IncomparableKey(0)));
+  set.add(1);
+  Expect.throws(() => set.add(IncomparableKey(0)));
+  Expect.throws(() => set.lookup(IncomparableKey(0)));
+
+  var map = SplayTreeMap();
+  Expect.throws(() => map[IncomparableKey(0)] = 0);
+  Expect.throws(() => map.putIfAbsent(IncomparableKey(0), () => 0));
+  map[1] = 1;
+  Expect.throws(() => map[IncomparableKey(0)] = 0);
+  Expect.throws(() => map.putIfAbsent(IncomparableKey(0), () => 0));
+
+  // But not if the compare function allows them.
+  // This now includes `null`.
+  int compare(Object o1, Object o2) {
+    if (o1 == null) return o2 == null ? 0 : -1;
+    if (o2 == null) return 1;
+    if (o1 is IncomparableKey && o2 is IncomparableKey) {
+      return o1.id - o2.id;
+    }
+    throw UnsupportedError("Nope");
+  }
+  for (var key in [null, IncomparableKey(0)]) {
+    set = SplayTreeSet<Object>(compare);
+    set.add(key);
+    Expect.equals(1, set.length);
+    set.clear();
+    Expect.isNull(set.lookup(key));
+    set.clear();
+    set.add(IncomparableKey(1));
+    set.add(key);
+    Expect.identical(key, set.first);
+    Expect.identical(key, set.lookup(key));
+
+    map = SplayTreeMap<Object, Object>(compare);
+    map[key] = 0;
+    Expect.isTrue(map.containsKey(key));
+    map.clear();
+    map.putIfAbsent(key, () => 0);
+    Expect.isTrue(map.containsKey(key));
+    map.clear();
+    map[IncomparableKey(1)] = 0;
+    map[key] = 0;
+    Expect.isTrue(map.containsKey(key));
+    map.remove(key);
+    Expect.isFalse(map.containsKey(key));
+    map.putIfAbsent(key, () => 0);
+    Expect.isTrue(map.containsKey(key));
+    map.remove(key);
+    Expect.isFalse(map.containsKey(key));
+  }
+}
+
 class IncomparableKey {
   final int id;
   IncomparableKey(this.id);
diff --git a/tests/corelib_2/unsigned_shift_test.dart b/tests/corelib_2/unsigned_shift_test.dart
index c190ff3..ab3220f 100644
--- a/tests/corelib_2/unsigned_shift_test.dart
+++ b/tests/corelib_2/unsigned_shift_test.dart
@@ -13,7 +13,7 @@
 
 main() {
   testIntegerShifts();
-  testNonDoubleShifts();
+  testNonIntegerShifts();
   testConstantShifts();
 }
 
@@ -47,18 +47,18 @@
   // If so, it is zero when converted to a fixed precision.
   if (double.infinity is int) {
     int number = (double.infinity as int);
-    Expect.equals(0, number >> 1);
-    Expect.throws(() => 1 >>> number); // infinity > 64.
+    Expect.equals(0, number >>> 1);
+    Expect.equals(0, 1 >>> number); // infinity > 64.
   }
 }
 
-void testNonDoubleShifts() {
+void testNonIntegerShifts() {
   double n = 0.0;
   n >>> 1; //# 01: compile-time error
   for (dynamic number in [0.0, 1.0, 2.4, -2.4, double.infinity, double.nan]) {
     if (number is! int) {
-      Expect.throws(() => number >>> 1);
-      Expect.throws(() => 1 >>> number);
+      Expect.throws(() => number >>> 1); //# 07: ok
+      Expect.throws(() => 1 >>> number); //# 08: ok
     }
   }
 }
diff --git a/tests/dartdevc/container_test.dart b/tests/dartdevc/container_test.dart
deleted file mode 100644
index 54d2165..0000000
--- a/tests/dartdevc/container_test.dart
+++ /dev/null
@@ -1,38 +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.
-
-// Tests that evaluation containers aren't renamed by DDC.
-
-import 'dart:_foreign_helper' as helper show JS;
-
-import 'package:expect/expect.dart';
-
-class T {
-  final int T$Eval = 0;
-  final int S$Eval = 0;
-  String get realT$Eval => helper.JS<String>('', 'T\$Eval.toString()');
-  String get realS$Eval => helper.JS<String>('', 'S\$Eval.toString()');
-}
-
-class T$Eval {}
-
-void main() {
-  var T$Eval = T();
-  var S$Eval = T$Eval;
-
-  var container1 = helper.JS<String>('', 'T\$Eval.toString()');
-  var container2 = helper.JS<String>('', 'S\$Eval.toString()');
-
-  // Evaluation containers are JS Objects. Ensure they aren't shadowed by JS
-  // symbols or Dart constructs.
-  Expect.equals('[object Object]', '$container1');
-  Expect.equals('[object Object]', '$container2');
-
-  Expect.equals("Instance of 'T'", T$Eval.toString());
-  Expect.equals(T$Eval.T$Eval, 0);
-  Expect.equals(T$Eval.S$Eval, 0);
-  Expect.notEquals(T$Eval.toString(), container1);
-  Expect.equals(T$Eval.realT$Eval, container1);
-  Expect.equals(T$Eval.realS$Eval, container2);
-}
diff --git a/tests/dartdevc_2/variance_subtype_test.dart b/tests/dartdevc_2/variance_subtype_test.dart
deleted file mode 100644
index b930484..0000000
--- a/tests/dartdevc_2/variance_subtype_test.dart
+++ /dev/null
@@ -1,191 +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.
-
-// @dart = 2.6
-
-// SharedOptions=--enable-experiment=variance
-
-// Tests runtime subtyping with explicit variance modifiers.
-
-import 'dart:_runtime' show typeRep;
-import 'dart:async' show FutureOr;
-
-import 'runtime_utils.dart';
-
-class Upper {}
-
-class Middle extends Upper {}
-
-class Lower extends Middle {}
-
-class Covariant<out T> {}
-
-class Contravariant<in T> {}
-
-class Invariant<inout T> {}
-
-class LegacyCovariant<T> {}
-
-void main() {
-  // Covariant<Lower> <: Covariant<Middle>
-  checkProperSubtype(typeRep<Covariant<Lower>>(), typeRep<Covariant<Middle>>());
-
-  // Covariant<Middle> <: Covariant<Middle>
-  checkSubtype(typeRep<Covariant<Middle>>(), typeRep<Covariant<Middle>>());
-
-  // Contravariant<Upper> <: Contravariant<Middle>
-  checkProperSubtype(
-      typeRep<Contravariant<Upper>>(), typeRep<Contravariant<Middle>>());
-
-  // Contravariant<Middle> <: Contravariant<Middle>
-  checkSubtype(
-      typeRep<Contravariant<Middle>>(), typeRep<Contravariant<Middle>>());
-
-  // Invariant<Middle> <: Invariant<Middle>
-  checkSubtype(typeRep<Invariant<Middle>>(), typeRep<Invariant<Middle>>());
-
-  // Invariant<dynamic> <:> Invariant<Object>
-  checkMutualSubtype(
-      typeRep<Invariant<dynamic>>(), typeRep<Invariant<Object>>());
-
-  // Invariant<FutureOr<dynamic>> <:> Invariant<dynamic>
-  checkMutualSubtype(
-      typeRep<Invariant<FutureOr<dynamic>>>(), typeRep<Invariant<dynamic>>());
-
-  // Invariant<FutureOr<Null>> <:> Invariant<Future<Null>>
-  checkMutualSubtype(
-      typeRep<Invariant<FutureOr<Null>>>(), typeRep<Invariant<Future<Null>>>());
-
-  // LegacyCovariant<Lower> <: LegacyCovariant<Middle>
-  checkProperSubtype(
-      typeRep<LegacyCovariant<Lower>>(), typeRep<LegacyCovariant<Middle>>());
-
-  // List<Covariant<Lower>> <: Iterable<Covariant<Middle>>
-  checkProperSubtype(typeRep<List<Covariant<Lower>>>(),
-      typeRep<Iterable<Covariant<Middle>>>());
-
-  // List<Contravariant<Upper>> <: Iterable<Contravariant<Middle>>
-  checkProperSubtype(typeRep<List<Contravariant<Upper>>>(),
-      typeRep<Iterable<Contravariant<Middle>>>());
-
-  // List<Invariant<Middle>> <: Iterable<Invariant<Middle>>
-  checkProperSubtype(typeRep<List<Invariant<Middle>>>(),
-      typeRep<Iterable<Invariant<Middle>>>());
-
-  // List<LegacyCovariant<Lower>> <: Iterable<LegacyCovariant<Middle>>
-  checkProperSubtype(typeRep<List<LegacyCovariant<Lower>>>(),
-      typeRep<Iterable<LegacyCovariant<Middle>>>());
-
-  // String -> Covariant<Lower> <: String -> Covariant<Middle>
-  checkProperSubtype(typeRep<Covariant<Lower> Function(String)>(),
-      typeRep<Covariant<Middle> Function(String)>());
-
-  // Covariant<Upper> -> String <: Covariant<Middle> -> String
-  checkProperSubtype(typeRep<String Function(Covariant<Upper>)>(),
-      typeRep<String Function(Covariant<Middle>)>());
-
-  // String -> Contravariant<Upper> <: String -> Contravariant<Middle>
-  checkProperSubtype(typeRep<Contravariant<Upper> Function(String)>(),
-      typeRep<Contravariant<Middle> Function(String)>());
-
-  // Contravariant<Lower> -> String <: Contravariant<Middle> -> String
-  checkProperSubtype(typeRep<String Function(Contravariant<Lower>)>(),
-      typeRep<String Function(Contravariant<Middle>)>());
-
-  // String -> Invariant<Middle> <: String -> Invariant<Middle>
-  checkSubtype(typeRep<String Function(Invariant<Middle>)>(),
-      typeRep<String Function(Invariant<Middle>)>());
-
-  // Invariant<Middle> -> String <: Invariant<Middle> -> String
-  checkSubtype(typeRep<String Function(Invariant<Middle>)>(),
-      typeRep<String Function(Invariant<Middle>)>());
-
-  // String -> LegacyCovariant<Lower> <: String -> LegacyCovariant<Middle>
-  checkProperSubtype(typeRep<LegacyCovariant<Lower> Function(String)>(),
-      typeRep<LegacyCovariant<Middle> Function(String)>());
-
-  // LegacyCovariant<Upper> -> String <: LegacyCovariant<Middle> -> String
-  checkProperSubtype(typeRep<String Function(LegacyCovariant<Upper>)>(),
-      typeRep<String Function(LegacyCovariant<Middle>)>());
-
-  // Covariant<Upper> </: Covariant<Middle>
-  checkSubtypeFailure(
-      typeRep<Covariant<Upper>>(), typeRep<Covariant<Middle>>());
-
-  // Contravariant<Lower> </: Contravariant<Middle>
-  checkSubtypeFailure(
-      typeRep<Contravariant<Lower>>(), typeRep<Contravariant<Middle>>());
-
-  // Invariant<Upper> </: Invariant<Middle>
-  checkSubtypeFailure(
-      typeRep<Invariant<Upper>>(), typeRep<Invariant<Middle>>());
-
-  // Invariant<Lower> </: Invariant<Middle>
-  checkSubtypeFailure(
-      typeRep<Invariant<Lower>>(), typeRep<Invariant<Middle>>());
-
-  // LegacyCovariant<Upper> </: LegacyCovariant<Middle>
-  checkSubtypeFailure(
-      typeRep<LegacyCovariant<Upper>>(), typeRep<LegacyCovariant<Middle>>());
-
-  // List<Covariant<Upper>> </: Iterable<Covariant<Middle>>
-  checkSubtypeFailure(typeRep<List<Covariant<Upper>>>(),
-      typeRep<Iterable<Covariant<Middle>>>());
-
-  // List<Contravariant<Lower>> </: Iterable<Contravariant<Middle>>
-  checkSubtypeFailure(typeRep<List<Contravariant<Lower>>>(),
-      typeRep<Iterable<Contravariant<Middle>>>());
-
-  // List<Invariant<Upper>> </: Iterable<Invariant<Middle>>
-  checkSubtypeFailure(typeRep<List<Invariant<Upper>>>(),
-      typeRep<Iterable<Invariant<Middle>>>());
-
-  // List<Invariant<Lower>> </: Iterable<Invariant<Middle>>
-  checkSubtypeFailure(typeRep<List<Invariant<Lower>>>(),
-      typeRep<Iterable<Invariant<Middle>>>());
-
-  // List<LegacyCovariant<Upper>> </: Iterable<LegacyCovariant<Middle>>
-  checkSubtypeFailure(typeRep<List<LegacyCovariant<Upper>>>(),
-      typeRep<Iterable<LegacyCovariant<Middle>>>());
-
-  // String -> Covariant<Upper> </: String -> Covariant<Middle>
-  checkSubtypeFailure(typeRep<Covariant<Upper> Function(String)>(),
-      typeRep<Covariant<Middle> Function(String)>());
-
-  // Covariant<Lower> -> String </: Covariant<Middle> -> String
-  checkSubtypeFailure(typeRep<String Function(Covariant<Lower>)>(),
-      typeRep<String Function(Covariant<Middle>)>());
-
-  // String -> Contravariant<Lower> </: String -> Contravariant<Middle>
-  checkSubtypeFailure(typeRep<Contravariant<Lower> Function(String)>(),
-      typeRep<Contravariant<Middle> Function(String)>());
-
-  // Contravariant<Upper> -> String </: Contravariant<Middle> -> String
-  checkSubtypeFailure(typeRep<String Function(Contravariant<Upper>)>(),
-      typeRep<String Function(Contravariant<Middle>)>());
-
-  // String -> Invariant<Upper> </: String -> Invariant<Middle>
-  checkSubtypeFailure(typeRep<Invariant<Upper> Function(String)>(),
-      typeRep<Invariant<Middle> Function(String)>());
-
-  // Invariant<Upper> -> String </: Invariant<Middle> -> String
-  checkSubtypeFailure(typeRep<String Function(Invariant<Upper>)>(),
-      typeRep<String Function(Invariant<Middle>)>());
-
-  // String -> Invariant<Lower> </: String -> Invariant<Middle>
-  checkSubtypeFailure(typeRep<Invariant<Lower> Function(String)>(),
-      typeRep<Invariant<Middle> Function(String)>());
-
-  // Invariant<Lower> -> String <: Invariant<Middle> -> String
-  checkSubtypeFailure(typeRep<String Function(Invariant<Lower>)>(),
-      typeRep<String Function(Invariant<Middle>)>());
-
-  // String -> LegacyCovariant<Upper> </: String -> LegacyCovariant<Middle>
-  checkSubtypeFailure(typeRep<LegacyCovariant<Upper> Function(String)>(),
-      typeRep<LegacyCovariant<Middle> Function(String)>());
-
-  // LegacyCovariant<Lower> -> String </: LegacyCovariant<Middle> -> String
-  checkSubtypeFailure(typeRep<String Function(LegacyCovariant<Lower>)>(),
-      typeRep<String Function(LegacyCovariant<Middle>)>());
-}
diff --git a/tests/dartdevc_2/variance_test.dart b/tests/dartdevc_2/variance_test.dart
deleted file mode 100644
index 6d84f2f..0000000
--- a/tests/dartdevc_2/variance_test.dart
+++ /dev/null
@@ -1,53 +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.
-
-// @dart = 2.6
-
-// SharedOptions=--enable-experiment=variance
-
-// Tests the emission of explicit variance modifiers.
-
-import 'dart:_runtime'
-    show getGenericArgVariances, Variance, legacyTypeRep;
-
-import 'package:expect/expect.dart';
-
-class A<in T> {}
-
-class B<out T> {}
-
-class C<inout T> {}
-
-class D<T> {}
-
-class E<inout X, out Y, in Z> {}
-
-mixin F<in T> {}
-
-class G<inout T> = Object with F<T>;
-
-List getVariances(dynamic type) {
-  // TODO(nshahan) Revisit when we decide if getGenericArgVariances will handle
-  // legacy and nullable wrappers.
-  return getGenericArgVariances(type.type);
-}
-
-main() {
-  Expect.listEquals([Variance.contravariant], getVariances(legacyTypeRep<A>()));
-
-  Expect.listEquals([Variance.covariant], getVariances(legacyTypeRep<B>()));
-
-  Expect.listEquals([Variance.invariant], getVariances(legacyTypeRep<C>()));
-
-  // Implicit variance is not emitted into the generated code.
-  Expect.isNull(getVariances(legacyTypeRep<D>()));
-
-  Expect.listEquals(
-      [Variance.invariant, Variance.covariant, Variance.contravariant],
-      getVariances(legacyTypeRep<E>()));
-
-  Expect.listEquals([Variance.contravariant], getVariances(legacyTypeRep<F>()));
-
-  Expect.listEquals([Variance.invariant], getVariances(legacyTypeRep<G>()));
-}
diff --git a/tests/ffi/function_callbacks_structs_by_value_generated_test.dart b/tests/ffi/function_callbacks_structs_by_value_generated_test.dart
index 025b2d6..09648be 100644
--- a/tests/ffi/function_callbacks_structs_by_value_generated_test.dart
+++ b/tests/ffi/function_callbacks_structs_by_value_generated_test.dart
@@ -273,6 +273,54 @@
           passStructStruct16BytesMixed3x10, 0.0),
       passStructStruct16BytesMixed3x10AfterCallback),
   CallbackTest.withCheck(
+      "PassUint8Struct32BytesInlineArrayMultiDimensionalI",
+      Pointer.fromFunction<
+              PassUint8Struct32BytesInlineArrayMultiDimensionalIType>(
+          passUint8Struct32BytesInlineArrayMultiDimensionalI, 0),
+      passUint8Struct32BytesInlineArrayMultiDimensionalIAfterCallback),
+  CallbackTest.withCheck(
+      "PassUint8Struct4BytesInlineArrayMultiDimensionalIn",
+      Pointer.fromFunction<
+              PassUint8Struct4BytesInlineArrayMultiDimensionalInType>(
+          passUint8Struct4BytesInlineArrayMultiDimensionalIn, 0),
+      passUint8Struct4BytesInlineArrayMultiDimensionalInAfterCallback),
+  CallbackTest.withCheck(
+      "PassStruct3BytesPackedIntx10",
+      Pointer.fromFunction<PassStruct3BytesPackedIntx10Type>(
+          passStruct3BytesPackedIntx10, 0),
+      passStruct3BytesPackedIntx10AfterCallback),
+  CallbackTest.withCheck(
+      "PassStruct8BytesPackedIntx10",
+      Pointer.fromFunction<PassStruct8BytesPackedIntx10Type>(
+          passStruct8BytesPackedIntx10, 0),
+      passStruct8BytesPackedIntx10AfterCallback),
+  CallbackTest.withCheck(
+      "PassStruct9BytesPackedMixedx10DoubleInt32",
+      Pointer.fromFunction<PassStruct9BytesPackedMixedx10DoubleInt32Type>(
+          passStruct9BytesPackedMixedx10DoubleInt32, 0.0),
+      passStruct9BytesPackedMixedx10DoubleInt32AfterCallback),
+  CallbackTest.withCheck(
+      "PassStruct5BytesPackedMixed",
+      Pointer.fromFunction<PassStruct5BytesPackedMixedType>(
+          passStruct5BytesPackedMixed, 0.0),
+      passStruct5BytesPackedMixedAfterCallback),
+  CallbackTest.withCheck(
+      "PassStructNestedAlignmentStruct5BytesPackedMixed",
+      Pointer.fromFunction<
+              PassStructNestedAlignmentStruct5BytesPackedMixedType>(
+          passStructNestedAlignmentStruct5BytesPackedMixed, 0.0),
+      passStructNestedAlignmentStruct5BytesPackedMixedAfterCallback),
+  CallbackTest.withCheck(
+      "PassStruct6BytesInlineArrayInt",
+      Pointer.fromFunction<PassStruct6BytesInlineArrayIntType>(
+          passStruct6BytesInlineArrayInt, 0.0),
+      passStruct6BytesInlineArrayIntAfterCallback),
+  CallbackTest.withCheck(
+      "PassStruct15BytesInlineArrayMixed",
+      Pointer.fromFunction<PassStruct15BytesInlineArrayMixedType>(
+          passStruct15BytesInlineArrayMixed, 0.0),
+      passStruct15BytesInlineArrayMixedAfterCallback),
+  CallbackTest.withCheck(
       "ReturnStruct1ByteInt",
       Pointer.fromFunction<ReturnStruct1ByteIntType>(returnStruct1ByteInt),
       returnStruct1ByteIntAfterCallback),
@@ -380,6 +428,21 @@
           returnStruct1024BytesHomogeneousUint64),
       returnStruct1024BytesHomogeneousUint64AfterCallback),
   CallbackTest.withCheck(
+      "ReturnStruct3BytesPackedInt",
+      Pointer.fromFunction<ReturnStruct3BytesPackedIntType>(
+          returnStruct3BytesPackedInt),
+      returnStruct3BytesPackedIntAfterCallback),
+  CallbackTest.withCheck(
+      "ReturnStruct8BytesPackedInt",
+      Pointer.fromFunction<ReturnStruct8BytesPackedIntType>(
+          returnStruct8BytesPackedInt),
+      returnStruct8BytesPackedIntAfterCallback),
+  CallbackTest.withCheck(
+      "ReturnStruct9BytesPackedMixed",
+      Pointer.fromFunction<ReturnStruct9BytesPackedMixedType>(
+          returnStruct9BytesPackedMixed),
+      returnStruct9BytesPackedMixedAfterCallback),
+  CallbackTest.withCheck(
       "ReturnStructArgumentStruct1ByteInt",
       Pointer.fromFunction<ReturnStructArgumentStruct1ByteIntType>(
           returnStructArgumentStruct1ByteInt),
@@ -5967,6 +6030,816 @@
   Expect.approxEquals(30.0, result);
 }
 
+typedef PassUint8Struct32BytesInlineArrayMultiDimensionalIType
+    = Uint32 Function(
+        Uint8,
+        Struct32BytesInlineArrayMultiDimensionalInt,
+        Uint8,
+        Struct8BytesInlineArrayMultiDimensionalInt,
+        Uint8,
+        Struct8BytesInlineArrayMultiDimensionalInt,
+        Uint8);
+
+// Global variables to be able to test inputs after callback returned.
+int passUint8Struct32BytesInlineArrayMultiDimensionalI_a0 = 0;
+Struct32BytesInlineArrayMultiDimensionalInt
+    passUint8Struct32BytesInlineArrayMultiDimensionalI_a1 =
+    Struct32BytesInlineArrayMultiDimensionalInt();
+int passUint8Struct32BytesInlineArrayMultiDimensionalI_a2 = 0;
+Struct8BytesInlineArrayMultiDimensionalInt
+    passUint8Struct32BytesInlineArrayMultiDimensionalI_a3 =
+    Struct8BytesInlineArrayMultiDimensionalInt();
+int passUint8Struct32BytesInlineArrayMultiDimensionalI_a4 = 0;
+Struct8BytesInlineArrayMultiDimensionalInt
+    passUint8Struct32BytesInlineArrayMultiDimensionalI_a5 =
+    Struct8BytesInlineArrayMultiDimensionalInt();
+int passUint8Struct32BytesInlineArrayMultiDimensionalI_a6 = 0;
+
+// Result variable also global, so we can delete it after the callback.
+int passUint8Struct32BytesInlineArrayMultiDimensionalIResult = 0;
+
+int passUint8Struct32BytesInlineArrayMultiDimensionalICalculateResult() {
+  int result = 0;
+
+  result += passUint8Struct32BytesInlineArrayMultiDimensionalI_a0;
+  result +=
+      passUint8Struct32BytesInlineArrayMultiDimensionalI_a1.a0[0][0][0][0][0];
+  result +=
+      passUint8Struct32BytesInlineArrayMultiDimensionalI_a1.a0[0][0][0][0][1];
+  result +=
+      passUint8Struct32BytesInlineArrayMultiDimensionalI_a1.a0[0][0][0][1][0];
+  result +=
+      passUint8Struct32BytesInlineArrayMultiDimensionalI_a1.a0[0][0][0][1][1];
+  result +=
+      passUint8Struct32BytesInlineArrayMultiDimensionalI_a1.a0[0][0][1][0][0];
+  result +=
+      passUint8Struct32BytesInlineArrayMultiDimensionalI_a1.a0[0][0][1][0][1];
+  result +=
+      passUint8Struct32BytesInlineArrayMultiDimensionalI_a1.a0[0][0][1][1][0];
+  result +=
+      passUint8Struct32BytesInlineArrayMultiDimensionalI_a1.a0[0][0][1][1][1];
+  result +=
+      passUint8Struct32BytesInlineArrayMultiDimensionalI_a1.a0[0][1][0][0][0];
+  result +=
+      passUint8Struct32BytesInlineArrayMultiDimensionalI_a1.a0[0][1][0][0][1];
+  result +=
+      passUint8Struct32BytesInlineArrayMultiDimensionalI_a1.a0[0][1][0][1][0];
+  result +=
+      passUint8Struct32BytesInlineArrayMultiDimensionalI_a1.a0[0][1][0][1][1];
+  result +=
+      passUint8Struct32BytesInlineArrayMultiDimensionalI_a1.a0[0][1][1][0][0];
+  result +=
+      passUint8Struct32BytesInlineArrayMultiDimensionalI_a1.a0[0][1][1][0][1];
+  result +=
+      passUint8Struct32BytesInlineArrayMultiDimensionalI_a1.a0[0][1][1][1][0];
+  result +=
+      passUint8Struct32BytesInlineArrayMultiDimensionalI_a1.a0[0][1][1][1][1];
+  result +=
+      passUint8Struct32BytesInlineArrayMultiDimensionalI_a1.a0[1][0][0][0][0];
+  result +=
+      passUint8Struct32BytesInlineArrayMultiDimensionalI_a1.a0[1][0][0][0][1];
+  result +=
+      passUint8Struct32BytesInlineArrayMultiDimensionalI_a1.a0[1][0][0][1][0];
+  result +=
+      passUint8Struct32BytesInlineArrayMultiDimensionalI_a1.a0[1][0][0][1][1];
+  result +=
+      passUint8Struct32BytesInlineArrayMultiDimensionalI_a1.a0[1][0][1][0][0];
+  result +=
+      passUint8Struct32BytesInlineArrayMultiDimensionalI_a1.a0[1][0][1][0][1];
+  result +=
+      passUint8Struct32BytesInlineArrayMultiDimensionalI_a1.a0[1][0][1][1][0];
+  result +=
+      passUint8Struct32BytesInlineArrayMultiDimensionalI_a1.a0[1][0][1][1][1];
+  result +=
+      passUint8Struct32BytesInlineArrayMultiDimensionalI_a1.a0[1][1][0][0][0];
+  result +=
+      passUint8Struct32BytesInlineArrayMultiDimensionalI_a1.a0[1][1][0][0][1];
+  result +=
+      passUint8Struct32BytesInlineArrayMultiDimensionalI_a1.a0[1][1][0][1][0];
+  result +=
+      passUint8Struct32BytesInlineArrayMultiDimensionalI_a1.a0[1][1][0][1][1];
+  result +=
+      passUint8Struct32BytesInlineArrayMultiDimensionalI_a1.a0[1][1][1][0][0];
+  result +=
+      passUint8Struct32BytesInlineArrayMultiDimensionalI_a1.a0[1][1][1][0][1];
+  result +=
+      passUint8Struct32BytesInlineArrayMultiDimensionalI_a1.a0[1][1][1][1][0];
+  result +=
+      passUint8Struct32BytesInlineArrayMultiDimensionalI_a1.a0[1][1][1][1][1];
+  result += passUint8Struct32BytesInlineArrayMultiDimensionalI_a2;
+  result += passUint8Struct32BytesInlineArrayMultiDimensionalI_a3.a0[0][0][0];
+  result += passUint8Struct32BytesInlineArrayMultiDimensionalI_a3.a0[0][0][1];
+  result += passUint8Struct32BytesInlineArrayMultiDimensionalI_a3.a0[0][1][0];
+  result += passUint8Struct32BytesInlineArrayMultiDimensionalI_a3.a0[0][1][1];
+  result += passUint8Struct32BytesInlineArrayMultiDimensionalI_a3.a0[1][0][0];
+  result += passUint8Struct32BytesInlineArrayMultiDimensionalI_a3.a0[1][0][1];
+  result += passUint8Struct32BytesInlineArrayMultiDimensionalI_a3.a0[1][1][0];
+  result += passUint8Struct32BytesInlineArrayMultiDimensionalI_a3.a0[1][1][1];
+  result += passUint8Struct32BytesInlineArrayMultiDimensionalI_a4;
+  result += passUint8Struct32BytesInlineArrayMultiDimensionalI_a5.a0[0][0][0];
+  result += passUint8Struct32BytesInlineArrayMultiDimensionalI_a5.a0[0][0][1];
+  result += passUint8Struct32BytesInlineArrayMultiDimensionalI_a5.a0[0][1][0];
+  result += passUint8Struct32BytesInlineArrayMultiDimensionalI_a5.a0[0][1][1];
+  result += passUint8Struct32BytesInlineArrayMultiDimensionalI_a5.a0[1][0][0];
+  result += passUint8Struct32BytesInlineArrayMultiDimensionalI_a5.a0[1][0][1];
+  result += passUint8Struct32BytesInlineArrayMultiDimensionalI_a5.a0[1][1][0];
+  result += passUint8Struct32BytesInlineArrayMultiDimensionalI_a5.a0[1][1][1];
+  result += passUint8Struct32BytesInlineArrayMultiDimensionalI_a6;
+
+  passUint8Struct32BytesInlineArrayMultiDimensionalIResult = result;
+
+  return result;
+}
+
+/// Test multi dimensional inline array struct as argument.
+int passUint8Struct32BytesInlineArrayMultiDimensionalI(
+    int a0,
+    Struct32BytesInlineArrayMultiDimensionalInt a1,
+    int a2,
+    Struct8BytesInlineArrayMultiDimensionalInt a3,
+    int a4,
+    Struct8BytesInlineArrayMultiDimensionalInt a5,
+    int a6) {
+  print(
+      "passUint8Struct32BytesInlineArrayMultiDimensionalI(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6})");
+
+  // In legacy mode, possibly return null.
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0 == 42 || a0 == 84) {
+    print("throwing!");
+    throw Exception(
+        "PassUint8Struct32BytesInlineArrayMultiDimensionalI throwing on purpose!");
+  }
+
+  passUint8Struct32BytesInlineArrayMultiDimensionalI_a0 = a0;
+  passUint8Struct32BytesInlineArrayMultiDimensionalI_a1 = a1;
+  passUint8Struct32BytesInlineArrayMultiDimensionalI_a2 = a2;
+  passUint8Struct32BytesInlineArrayMultiDimensionalI_a3 = a3;
+  passUint8Struct32BytesInlineArrayMultiDimensionalI_a4 = a4;
+  passUint8Struct32BytesInlineArrayMultiDimensionalI_a5 = a5;
+  passUint8Struct32BytesInlineArrayMultiDimensionalI_a6 = a6;
+
+  final result =
+      passUint8Struct32BytesInlineArrayMultiDimensionalICalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passUint8Struct32BytesInlineArrayMultiDimensionalIAfterCallback() {
+  final result =
+      passUint8Struct32BytesInlineArrayMultiDimensionalICalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.equals(1378, result);
+}
+
+typedef PassUint8Struct4BytesInlineArrayMultiDimensionalInType = Uint32
+    Function(Uint8, Struct4BytesInlineArrayMultiDimensionalInt, Uint8);
+
+// Global variables to be able to test inputs after callback returned.
+int passUint8Struct4BytesInlineArrayMultiDimensionalIn_a0 = 0;
+Struct4BytesInlineArrayMultiDimensionalInt
+    passUint8Struct4BytesInlineArrayMultiDimensionalIn_a1 =
+    Struct4BytesInlineArrayMultiDimensionalInt();
+int passUint8Struct4BytesInlineArrayMultiDimensionalIn_a2 = 0;
+
+// Result variable also global, so we can delete it after the callback.
+int passUint8Struct4BytesInlineArrayMultiDimensionalInResult = 0;
+
+int passUint8Struct4BytesInlineArrayMultiDimensionalInCalculateResult() {
+  int result = 0;
+
+  result += passUint8Struct4BytesInlineArrayMultiDimensionalIn_a0;
+  result += passUint8Struct4BytesInlineArrayMultiDimensionalIn_a1.a0[0][0].a0;
+  result += passUint8Struct4BytesInlineArrayMultiDimensionalIn_a1.a0[0][1].a0;
+  result += passUint8Struct4BytesInlineArrayMultiDimensionalIn_a1.a0[1][0].a0;
+  result += passUint8Struct4BytesInlineArrayMultiDimensionalIn_a1.a0[1][1].a0;
+  result += passUint8Struct4BytesInlineArrayMultiDimensionalIn_a2;
+
+  passUint8Struct4BytesInlineArrayMultiDimensionalInResult = result;
+
+  return result;
+}
+
+/// Test struct in multi dimensional inline array.
+int passUint8Struct4BytesInlineArrayMultiDimensionalIn(
+    int a0, Struct4BytesInlineArrayMultiDimensionalInt a1, int a2) {
+  print(
+      "passUint8Struct4BytesInlineArrayMultiDimensionalIn(${a0}, ${a1}, ${a2})");
+
+  // In legacy mode, possibly return null.
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0 == 42 || a0 == 84) {
+    print("throwing!");
+    throw Exception(
+        "PassUint8Struct4BytesInlineArrayMultiDimensionalIn throwing on purpose!");
+  }
+
+  passUint8Struct4BytesInlineArrayMultiDimensionalIn_a0 = a0;
+  passUint8Struct4BytesInlineArrayMultiDimensionalIn_a1 = a1;
+  passUint8Struct4BytesInlineArrayMultiDimensionalIn_a2 = a2;
+
+  final result =
+      passUint8Struct4BytesInlineArrayMultiDimensionalInCalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passUint8Struct4BytesInlineArrayMultiDimensionalInAfterCallback() {
+  final result =
+      passUint8Struct4BytesInlineArrayMultiDimensionalInCalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.equals(5, result);
+}
+
+typedef PassStruct3BytesPackedIntx10Type = Int64 Function(
+    Struct3BytesPackedInt,
+    Struct3BytesPackedInt,
+    Struct3BytesPackedInt,
+    Struct3BytesPackedInt,
+    Struct3BytesPackedInt,
+    Struct3BytesPackedInt,
+    Struct3BytesPackedInt,
+    Struct3BytesPackedInt,
+    Struct3BytesPackedInt,
+    Struct3BytesPackedInt);
+
+// Global variables to be able to test inputs after callback returned.
+Struct3BytesPackedInt passStruct3BytesPackedIntx10_a0 = Struct3BytesPackedInt();
+Struct3BytesPackedInt passStruct3BytesPackedIntx10_a1 = Struct3BytesPackedInt();
+Struct3BytesPackedInt passStruct3BytesPackedIntx10_a2 = Struct3BytesPackedInt();
+Struct3BytesPackedInt passStruct3BytesPackedIntx10_a3 = Struct3BytesPackedInt();
+Struct3BytesPackedInt passStruct3BytesPackedIntx10_a4 = Struct3BytesPackedInt();
+Struct3BytesPackedInt passStruct3BytesPackedIntx10_a5 = Struct3BytesPackedInt();
+Struct3BytesPackedInt passStruct3BytesPackedIntx10_a6 = Struct3BytesPackedInt();
+Struct3BytesPackedInt passStruct3BytesPackedIntx10_a7 = Struct3BytesPackedInt();
+Struct3BytesPackedInt passStruct3BytesPackedIntx10_a8 = Struct3BytesPackedInt();
+Struct3BytesPackedInt passStruct3BytesPackedIntx10_a9 = Struct3BytesPackedInt();
+
+// Result variable also global, so we can delete it after the callback.
+int passStruct3BytesPackedIntx10Result = 0;
+
+int passStruct3BytesPackedIntx10CalculateResult() {
+  int result = 0;
+
+  result += passStruct3BytesPackedIntx10_a0.a0;
+  result += passStruct3BytesPackedIntx10_a0.a1;
+  result += passStruct3BytesPackedIntx10_a1.a0;
+  result += passStruct3BytesPackedIntx10_a1.a1;
+  result += passStruct3BytesPackedIntx10_a2.a0;
+  result += passStruct3BytesPackedIntx10_a2.a1;
+  result += passStruct3BytesPackedIntx10_a3.a0;
+  result += passStruct3BytesPackedIntx10_a3.a1;
+  result += passStruct3BytesPackedIntx10_a4.a0;
+  result += passStruct3BytesPackedIntx10_a4.a1;
+  result += passStruct3BytesPackedIntx10_a5.a0;
+  result += passStruct3BytesPackedIntx10_a5.a1;
+  result += passStruct3BytesPackedIntx10_a6.a0;
+  result += passStruct3BytesPackedIntx10_a6.a1;
+  result += passStruct3BytesPackedIntx10_a7.a0;
+  result += passStruct3BytesPackedIntx10_a7.a1;
+  result += passStruct3BytesPackedIntx10_a8.a0;
+  result += passStruct3BytesPackedIntx10_a8.a1;
+  result += passStruct3BytesPackedIntx10_a9.a0;
+  result += passStruct3BytesPackedIntx10_a9.a1;
+
+  passStruct3BytesPackedIntx10Result = result;
+
+  return result;
+}
+
+/// Small struct with mis-aligned member.
+int passStruct3BytesPackedIntx10(
+    Struct3BytesPackedInt a0,
+    Struct3BytesPackedInt a1,
+    Struct3BytesPackedInt a2,
+    Struct3BytesPackedInt a3,
+    Struct3BytesPackedInt a4,
+    Struct3BytesPackedInt a5,
+    Struct3BytesPackedInt a6,
+    Struct3BytesPackedInt a7,
+    Struct3BytesPackedInt a8,
+    Struct3BytesPackedInt a9) {
+  print(
+      "passStruct3BytesPackedIntx10(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8}, ${a9})");
+
+  // In legacy mode, possibly return null.
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0.a0 == 42 || a0.a0 == 84) {
+    print("throwing!");
+    throw Exception("PassStruct3BytesPackedIntx10 throwing on purpose!");
+  }
+
+  passStruct3BytesPackedIntx10_a0 = a0;
+  passStruct3BytesPackedIntx10_a1 = a1;
+  passStruct3BytesPackedIntx10_a2 = a2;
+  passStruct3BytesPackedIntx10_a3 = a3;
+  passStruct3BytesPackedIntx10_a4 = a4;
+  passStruct3BytesPackedIntx10_a5 = a5;
+  passStruct3BytesPackedIntx10_a6 = a6;
+  passStruct3BytesPackedIntx10_a7 = a7;
+  passStruct3BytesPackedIntx10_a8 = a8;
+  passStruct3BytesPackedIntx10_a9 = a9;
+
+  final result = passStruct3BytesPackedIntx10CalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passStruct3BytesPackedIntx10AfterCallback() {
+  final result = passStruct3BytesPackedIntx10CalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.equals(10, result);
+}
+
+typedef PassStruct8BytesPackedIntx10Type = Int64 Function(
+    Struct8BytesPackedInt,
+    Struct8BytesPackedInt,
+    Struct8BytesPackedInt,
+    Struct8BytesPackedInt,
+    Struct8BytesPackedInt,
+    Struct8BytesPackedInt,
+    Struct8BytesPackedInt,
+    Struct8BytesPackedInt,
+    Struct8BytesPackedInt,
+    Struct8BytesPackedInt);
+
+// Global variables to be able to test inputs after callback returned.
+Struct8BytesPackedInt passStruct8BytesPackedIntx10_a0 = Struct8BytesPackedInt();
+Struct8BytesPackedInt passStruct8BytesPackedIntx10_a1 = Struct8BytesPackedInt();
+Struct8BytesPackedInt passStruct8BytesPackedIntx10_a2 = Struct8BytesPackedInt();
+Struct8BytesPackedInt passStruct8BytesPackedIntx10_a3 = Struct8BytesPackedInt();
+Struct8BytesPackedInt passStruct8BytesPackedIntx10_a4 = Struct8BytesPackedInt();
+Struct8BytesPackedInt passStruct8BytesPackedIntx10_a5 = Struct8BytesPackedInt();
+Struct8BytesPackedInt passStruct8BytesPackedIntx10_a6 = Struct8BytesPackedInt();
+Struct8BytesPackedInt passStruct8BytesPackedIntx10_a7 = Struct8BytesPackedInt();
+Struct8BytesPackedInt passStruct8BytesPackedIntx10_a8 = Struct8BytesPackedInt();
+Struct8BytesPackedInt passStruct8BytesPackedIntx10_a9 = Struct8BytesPackedInt();
+
+// Result variable also global, so we can delete it after the callback.
+int passStruct8BytesPackedIntx10Result = 0;
+
+int passStruct8BytesPackedIntx10CalculateResult() {
+  int result = 0;
+
+  result += passStruct8BytesPackedIntx10_a0.a0;
+  result += passStruct8BytesPackedIntx10_a0.a1;
+  result += passStruct8BytesPackedIntx10_a0.a2;
+  result += passStruct8BytesPackedIntx10_a0.a3;
+  result += passStruct8BytesPackedIntx10_a0.a4;
+  result += passStruct8BytesPackedIntx10_a1.a0;
+  result += passStruct8BytesPackedIntx10_a1.a1;
+  result += passStruct8BytesPackedIntx10_a1.a2;
+  result += passStruct8BytesPackedIntx10_a1.a3;
+  result += passStruct8BytesPackedIntx10_a1.a4;
+  result += passStruct8BytesPackedIntx10_a2.a0;
+  result += passStruct8BytesPackedIntx10_a2.a1;
+  result += passStruct8BytesPackedIntx10_a2.a2;
+  result += passStruct8BytesPackedIntx10_a2.a3;
+  result += passStruct8BytesPackedIntx10_a2.a4;
+  result += passStruct8BytesPackedIntx10_a3.a0;
+  result += passStruct8BytesPackedIntx10_a3.a1;
+  result += passStruct8BytesPackedIntx10_a3.a2;
+  result += passStruct8BytesPackedIntx10_a3.a3;
+  result += passStruct8BytesPackedIntx10_a3.a4;
+  result += passStruct8BytesPackedIntx10_a4.a0;
+  result += passStruct8BytesPackedIntx10_a4.a1;
+  result += passStruct8BytesPackedIntx10_a4.a2;
+  result += passStruct8BytesPackedIntx10_a4.a3;
+  result += passStruct8BytesPackedIntx10_a4.a4;
+  result += passStruct8BytesPackedIntx10_a5.a0;
+  result += passStruct8BytesPackedIntx10_a5.a1;
+  result += passStruct8BytesPackedIntx10_a5.a2;
+  result += passStruct8BytesPackedIntx10_a5.a3;
+  result += passStruct8BytesPackedIntx10_a5.a4;
+  result += passStruct8BytesPackedIntx10_a6.a0;
+  result += passStruct8BytesPackedIntx10_a6.a1;
+  result += passStruct8BytesPackedIntx10_a6.a2;
+  result += passStruct8BytesPackedIntx10_a6.a3;
+  result += passStruct8BytesPackedIntx10_a6.a4;
+  result += passStruct8BytesPackedIntx10_a7.a0;
+  result += passStruct8BytesPackedIntx10_a7.a1;
+  result += passStruct8BytesPackedIntx10_a7.a2;
+  result += passStruct8BytesPackedIntx10_a7.a3;
+  result += passStruct8BytesPackedIntx10_a7.a4;
+  result += passStruct8BytesPackedIntx10_a8.a0;
+  result += passStruct8BytesPackedIntx10_a8.a1;
+  result += passStruct8BytesPackedIntx10_a8.a2;
+  result += passStruct8BytesPackedIntx10_a8.a3;
+  result += passStruct8BytesPackedIntx10_a8.a4;
+  result += passStruct8BytesPackedIntx10_a9.a0;
+  result += passStruct8BytesPackedIntx10_a9.a1;
+  result += passStruct8BytesPackedIntx10_a9.a2;
+  result += passStruct8BytesPackedIntx10_a9.a3;
+  result += passStruct8BytesPackedIntx10_a9.a4;
+
+  passStruct8BytesPackedIntx10Result = result;
+
+  return result;
+}
+
+/// Struct with mis-aligned member.
+int passStruct8BytesPackedIntx10(
+    Struct8BytesPackedInt a0,
+    Struct8BytesPackedInt a1,
+    Struct8BytesPackedInt a2,
+    Struct8BytesPackedInt a3,
+    Struct8BytesPackedInt a4,
+    Struct8BytesPackedInt a5,
+    Struct8BytesPackedInt a6,
+    Struct8BytesPackedInt a7,
+    Struct8BytesPackedInt a8,
+    Struct8BytesPackedInt a9) {
+  print(
+      "passStruct8BytesPackedIntx10(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8}, ${a9})");
+
+  // In legacy mode, possibly return null.
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0.a0 == 42 || a0.a0 == 84) {
+    print("throwing!");
+    throw Exception("PassStruct8BytesPackedIntx10 throwing on purpose!");
+  }
+
+  passStruct8BytesPackedIntx10_a0 = a0;
+  passStruct8BytesPackedIntx10_a1 = a1;
+  passStruct8BytesPackedIntx10_a2 = a2;
+  passStruct8BytesPackedIntx10_a3 = a3;
+  passStruct8BytesPackedIntx10_a4 = a4;
+  passStruct8BytesPackedIntx10_a5 = a5;
+  passStruct8BytesPackedIntx10_a6 = a6;
+  passStruct8BytesPackedIntx10_a7 = a7;
+  passStruct8BytesPackedIntx10_a8 = a8;
+  passStruct8BytesPackedIntx10_a9 = a9;
+
+  final result = passStruct8BytesPackedIntx10CalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passStruct8BytesPackedIntx10AfterCallback() {
+  final result = passStruct8BytesPackedIntx10CalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.equals(1275, result);
+}
+
+typedef PassStruct9BytesPackedMixedx10DoubleInt32Type = Double Function(
+    Struct9BytesPackedMixed,
+    Struct9BytesPackedMixed,
+    Struct9BytesPackedMixed,
+    Struct9BytesPackedMixed,
+    Struct9BytesPackedMixed,
+    Struct9BytesPackedMixed,
+    Struct9BytesPackedMixed,
+    Struct9BytesPackedMixed,
+    Struct9BytesPackedMixed,
+    Struct9BytesPackedMixed,
+    Double,
+    Int32);
+
+// Global variables to be able to test inputs after callback returned.
+Struct9BytesPackedMixed passStruct9BytesPackedMixedx10DoubleInt32_a0 =
+    Struct9BytesPackedMixed();
+Struct9BytesPackedMixed passStruct9BytesPackedMixedx10DoubleInt32_a1 =
+    Struct9BytesPackedMixed();
+Struct9BytesPackedMixed passStruct9BytesPackedMixedx10DoubleInt32_a2 =
+    Struct9BytesPackedMixed();
+Struct9BytesPackedMixed passStruct9BytesPackedMixedx10DoubleInt32_a3 =
+    Struct9BytesPackedMixed();
+Struct9BytesPackedMixed passStruct9BytesPackedMixedx10DoubleInt32_a4 =
+    Struct9BytesPackedMixed();
+Struct9BytesPackedMixed passStruct9BytesPackedMixedx10DoubleInt32_a5 =
+    Struct9BytesPackedMixed();
+Struct9BytesPackedMixed passStruct9BytesPackedMixedx10DoubleInt32_a6 =
+    Struct9BytesPackedMixed();
+Struct9BytesPackedMixed passStruct9BytesPackedMixedx10DoubleInt32_a7 =
+    Struct9BytesPackedMixed();
+Struct9BytesPackedMixed passStruct9BytesPackedMixedx10DoubleInt32_a8 =
+    Struct9BytesPackedMixed();
+Struct9BytesPackedMixed passStruct9BytesPackedMixedx10DoubleInt32_a9 =
+    Struct9BytesPackedMixed();
+double passStruct9BytesPackedMixedx10DoubleInt32_a10 = 0.0;
+int passStruct9BytesPackedMixedx10DoubleInt32_a11 = 0;
+
+// Result variable also global, so we can delete it after the callback.
+double passStruct9BytesPackedMixedx10DoubleInt32Result = 0.0;
+
+double passStruct9BytesPackedMixedx10DoubleInt32CalculateResult() {
+  double result = 0;
+
+  result += passStruct9BytesPackedMixedx10DoubleInt32_a0.a0;
+  result += passStruct9BytesPackedMixedx10DoubleInt32_a0.a1;
+  result += passStruct9BytesPackedMixedx10DoubleInt32_a1.a0;
+  result += passStruct9BytesPackedMixedx10DoubleInt32_a1.a1;
+  result += passStruct9BytesPackedMixedx10DoubleInt32_a2.a0;
+  result += passStruct9BytesPackedMixedx10DoubleInt32_a2.a1;
+  result += passStruct9BytesPackedMixedx10DoubleInt32_a3.a0;
+  result += passStruct9BytesPackedMixedx10DoubleInt32_a3.a1;
+  result += passStruct9BytesPackedMixedx10DoubleInt32_a4.a0;
+  result += passStruct9BytesPackedMixedx10DoubleInt32_a4.a1;
+  result += passStruct9BytesPackedMixedx10DoubleInt32_a5.a0;
+  result += passStruct9BytesPackedMixedx10DoubleInt32_a5.a1;
+  result += passStruct9BytesPackedMixedx10DoubleInt32_a6.a0;
+  result += passStruct9BytesPackedMixedx10DoubleInt32_a6.a1;
+  result += passStruct9BytesPackedMixedx10DoubleInt32_a7.a0;
+  result += passStruct9BytesPackedMixedx10DoubleInt32_a7.a1;
+  result += passStruct9BytesPackedMixedx10DoubleInt32_a8.a0;
+  result += passStruct9BytesPackedMixedx10DoubleInt32_a8.a1;
+  result += passStruct9BytesPackedMixedx10DoubleInt32_a9.a0;
+  result += passStruct9BytesPackedMixedx10DoubleInt32_a9.a1;
+  result += passStruct9BytesPackedMixedx10DoubleInt32_a10;
+  result += passStruct9BytesPackedMixedx10DoubleInt32_a11;
+
+  passStruct9BytesPackedMixedx10DoubleInt32Result = result;
+
+  return result;
+}
+
+/// Struct with mis-aligned member.
+/// Tests backfilling of CPU and FPU registers.
+double passStruct9BytesPackedMixedx10DoubleInt32(
+    Struct9BytesPackedMixed a0,
+    Struct9BytesPackedMixed a1,
+    Struct9BytesPackedMixed a2,
+    Struct9BytesPackedMixed a3,
+    Struct9BytesPackedMixed a4,
+    Struct9BytesPackedMixed a5,
+    Struct9BytesPackedMixed a6,
+    Struct9BytesPackedMixed a7,
+    Struct9BytesPackedMixed a8,
+    Struct9BytesPackedMixed a9,
+    double a10,
+    int a11) {
+  print(
+      "passStruct9BytesPackedMixedx10DoubleInt32(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8}, ${a9}, ${a10}, ${a11})");
+
+  // In legacy mode, possibly return null.
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0.a0 == 42 || a0.a0 == 84) {
+    print("throwing!");
+    throw Exception(
+        "PassStruct9BytesPackedMixedx10DoubleInt32 throwing on purpose!");
+  }
+
+  passStruct9BytesPackedMixedx10DoubleInt32_a0 = a0;
+  passStruct9BytesPackedMixedx10DoubleInt32_a1 = a1;
+  passStruct9BytesPackedMixedx10DoubleInt32_a2 = a2;
+  passStruct9BytesPackedMixedx10DoubleInt32_a3 = a3;
+  passStruct9BytesPackedMixedx10DoubleInt32_a4 = a4;
+  passStruct9BytesPackedMixedx10DoubleInt32_a5 = a5;
+  passStruct9BytesPackedMixedx10DoubleInt32_a6 = a6;
+  passStruct9BytesPackedMixedx10DoubleInt32_a7 = a7;
+  passStruct9BytesPackedMixedx10DoubleInt32_a8 = a8;
+  passStruct9BytesPackedMixedx10DoubleInt32_a9 = a9;
+  passStruct9BytesPackedMixedx10DoubleInt32_a10 = a10;
+  passStruct9BytesPackedMixedx10DoubleInt32_a11 = a11;
+
+  final result = passStruct9BytesPackedMixedx10DoubleInt32CalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passStruct9BytesPackedMixedx10DoubleInt32AfterCallback() {
+  final result = passStruct9BytesPackedMixedx10DoubleInt32CalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.approxEquals(211.0, result);
+}
+
+typedef PassStruct5BytesPackedMixedType = Double Function(
+    Struct5BytesPackedMixed);
+
+// Global variables to be able to test inputs after callback returned.
+Struct5BytesPackedMixed passStruct5BytesPackedMixed_a0 =
+    Struct5BytesPackedMixed();
+
+// Result variable also global, so we can delete it after the callback.
+double passStruct5BytesPackedMixedResult = 0.0;
+
+double passStruct5BytesPackedMixedCalculateResult() {
+  double result = 0;
+
+  result += passStruct5BytesPackedMixed_a0.a0;
+  result += passStruct5BytesPackedMixed_a0.a1;
+
+  passStruct5BytesPackedMixedResult = result;
+
+  return result;
+}
+
+/// This packed struct happens to have only aligned members.
+double passStruct5BytesPackedMixed(Struct5BytesPackedMixed a0) {
+  print("passStruct5BytesPackedMixed(${a0})");
+
+  // In legacy mode, possibly return null.
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0.a0 == 42 || a0.a0 == 84) {
+    print("throwing!");
+    throw Exception("PassStruct5BytesPackedMixed throwing on purpose!");
+  }
+
+  passStruct5BytesPackedMixed_a0 = a0;
+
+  final result = passStruct5BytesPackedMixedCalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passStruct5BytesPackedMixedAfterCallback() {
+  final result = passStruct5BytesPackedMixedCalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.approxEquals(1.0, result);
+}
+
+typedef PassStructNestedAlignmentStruct5BytesPackedMixedType = Double Function(
+    StructNestedAlignmentStruct5BytesPackedMixed);
+
+// Global variables to be able to test inputs after callback returned.
+StructNestedAlignmentStruct5BytesPackedMixed
+    passStructNestedAlignmentStruct5BytesPackedMixed_a0 =
+    StructNestedAlignmentStruct5BytesPackedMixed();
+
+// Result variable also global, so we can delete it after the callback.
+double passStructNestedAlignmentStruct5BytesPackedMixedResult = 0.0;
+
+double passStructNestedAlignmentStruct5BytesPackedMixedCalculateResult() {
+  double result = 0;
+
+  result += passStructNestedAlignmentStruct5BytesPackedMixed_a0.a0;
+  result += passStructNestedAlignmentStruct5BytesPackedMixed_a0.a1.a0;
+  result += passStructNestedAlignmentStruct5BytesPackedMixed_a0.a1.a1;
+
+  passStructNestedAlignmentStruct5BytesPackedMixedResult = result;
+
+  return result;
+}
+
+/// Check alignment of packed struct in non-packed struct.
+double passStructNestedAlignmentStruct5BytesPackedMixed(
+    StructNestedAlignmentStruct5BytesPackedMixed a0) {
+  print("passStructNestedAlignmentStruct5BytesPackedMixed(${a0})");
+
+  // In legacy mode, possibly return null.
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0.a0 == 42 || a0.a0 == 84) {
+    print("throwing!");
+    throw Exception(
+        "PassStructNestedAlignmentStruct5BytesPackedMixed throwing on purpose!");
+  }
+
+  passStructNestedAlignmentStruct5BytesPackedMixed_a0 = a0;
+
+  final result =
+      passStructNestedAlignmentStruct5BytesPackedMixedCalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passStructNestedAlignmentStruct5BytesPackedMixedAfterCallback() {
+  final result =
+      passStructNestedAlignmentStruct5BytesPackedMixedCalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.approxEquals(6.0, result);
+}
+
+typedef PassStruct6BytesInlineArrayIntType = Double Function(
+    Struct6BytesInlineArrayInt);
+
+// Global variables to be able to test inputs after callback returned.
+Struct6BytesInlineArrayInt passStruct6BytesInlineArrayInt_a0 =
+    Struct6BytesInlineArrayInt();
+
+// Result variable also global, so we can delete it after the callback.
+double passStruct6BytesInlineArrayIntResult = 0.0;
+
+double passStruct6BytesInlineArrayIntCalculateResult() {
+  double result = 0;
+
+  result += passStruct6BytesInlineArrayInt_a0.a0[0].a0;
+  result += passStruct6BytesInlineArrayInt_a0.a0[0].a1;
+  result += passStruct6BytesInlineArrayInt_a0.a0[1].a0;
+  result += passStruct6BytesInlineArrayInt_a0.a0[1].a1;
+
+  passStruct6BytesInlineArrayIntResult = result;
+
+  return result;
+}
+
+/// Check alignment of packed struct array in non-packed struct.
+double passStruct6BytesInlineArrayInt(Struct6BytesInlineArrayInt a0) {
+  print("passStruct6BytesInlineArrayInt(${a0})");
+
+  // In legacy mode, possibly return null.
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0.a0[0].a0 == 42 || a0.a0[0].a0 == 84) {
+    print("throwing!");
+    throw Exception("PassStruct6BytesInlineArrayInt throwing on purpose!");
+  }
+
+  passStruct6BytesInlineArrayInt_a0 = a0;
+
+  final result = passStruct6BytesInlineArrayIntCalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passStruct6BytesInlineArrayIntAfterCallback() {
+  final result = passStruct6BytesInlineArrayIntCalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.approxEquals(2.0, result);
+}
+
+typedef PassStruct15BytesInlineArrayMixedType = Double Function(
+    Struct15BytesInlineArrayMixed);
+
+// Global variables to be able to test inputs after callback returned.
+Struct15BytesInlineArrayMixed passStruct15BytesInlineArrayMixed_a0 =
+    Struct15BytesInlineArrayMixed();
+
+// Result variable also global, so we can delete it after the callback.
+double passStruct15BytesInlineArrayMixedResult = 0.0;
+
+double passStruct15BytesInlineArrayMixedCalculateResult() {
+  double result = 0;
+
+  result += passStruct15BytesInlineArrayMixed_a0.a0[0].a0;
+  result += passStruct15BytesInlineArrayMixed_a0.a0[0].a1;
+  result += passStruct15BytesInlineArrayMixed_a0.a0[1].a0;
+  result += passStruct15BytesInlineArrayMixed_a0.a0[1].a1;
+  result += passStruct15BytesInlineArrayMixed_a0.a0[2].a0;
+  result += passStruct15BytesInlineArrayMixed_a0.a0[2].a1;
+
+  passStruct15BytesInlineArrayMixedResult = result;
+
+  return result;
+}
+
+/// Check alignment of packed struct array in non-packed struct.
+double passStruct15BytesInlineArrayMixed(Struct15BytesInlineArrayMixed a0) {
+  print("passStruct15BytesInlineArrayMixed(${a0})");
+
+  // In legacy mode, possibly return null.
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0.a0[0].a0 == 42 || a0.a0[0].a0 == 84) {
+    print("throwing!");
+    throw Exception("PassStruct15BytesInlineArrayMixed throwing on purpose!");
+  }
+
+  passStruct15BytesInlineArrayMixed_a0 = a0;
+
+  final result = passStruct15BytesInlineArrayMixedCalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passStruct15BytesInlineArrayMixedAfterCallback() {
+  final result = passStruct15BytesInlineArrayMixedCalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.approxEquals(3.0, result);
+}
+
 typedef ReturnStruct1ByteIntType = Struct1ByteInt Function(Int8);
 
 // Global variables to be able to test inputs after callback returned.
@@ -8040,6 +8913,182 @@
   calloc.free(returnStruct1024BytesHomogeneousUint64ResultPointer);
 }
 
+typedef ReturnStruct3BytesPackedIntType = Struct3BytesPackedInt Function(
+    Int8, Int16);
+
+// Global variables to be able to test inputs after callback returned.
+int returnStruct3BytesPackedInt_a0 = 0;
+int returnStruct3BytesPackedInt_a1 = 0;
+
+// Result variable also global, so we can delete it after the callback.
+Pointer<Struct3BytesPackedInt> returnStruct3BytesPackedIntResultPointer =
+    nullptr;
+
+Struct3BytesPackedInt returnStruct3BytesPackedIntCalculateResult() {
+  final resultPointer = calloc<Struct3BytesPackedInt>();
+  final result = resultPointer.ref;
+
+  result.a0 = returnStruct3BytesPackedInt_a0;
+  result.a1 = returnStruct3BytesPackedInt_a1;
+
+  returnStruct3BytesPackedIntResultPointer = resultPointer;
+
+  return result;
+}
+
+/// Small struct with mis-aligned member.
+Struct3BytesPackedInt returnStruct3BytesPackedInt(int a0, int a1) {
+  print("returnStruct3BytesPackedInt(${a0}, ${a1})");
+
+  // In legacy mode, possibly return null.
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0 == 42 || a0 == 84) {
+    print("throwing!");
+    throw Exception("ReturnStruct3BytesPackedInt throwing on purpose!");
+  }
+
+  returnStruct3BytesPackedInt_a0 = a0;
+  returnStruct3BytesPackedInt_a1 = a1;
+
+  final result = returnStruct3BytesPackedIntCalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void returnStruct3BytesPackedIntAfterCallback() {
+  calloc.free(returnStruct3BytesPackedIntResultPointer);
+
+  final result = returnStruct3BytesPackedIntCalculateResult();
+
+  print("after callback result = $result");
+
+  calloc.free(returnStruct3BytesPackedIntResultPointer);
+}
+
+typedef ReturnStruct8BytesPackedIntType = Struct8BytesPackedInt Function(
+    Uint8, Uint32, Uint8, Uint8, Uint8);
+
+// Global variables to be able to test inputs after callback returned.
+int returnStruct8BytesPackedInt_a0 = 0;
+int returnStruct8BytesPackedInt_a1 = 0;
+int returnStruct8BytesPackedInt_a2 = 0;
+int returnStruct8BytesPackedInt_a3 = 0;
+int returnStruct8BytesPackedInt_a4 = 0;
+
+// Result variable also global, so we can delete it after the callback.
+Pointer<Struct8BytesPackedInt> returnStruct8BytesPackedIntResultPointer =
+    nullptr;
+
+Struct8BytesPackedInt returnStruct8BytesPackedIntCalculateResult() {
+  final resultPointer = calloc<Struct8BytesPackedInt>();
+  final result = resultPointer.ref;
+
+  result.a0 = returnStruct8BytesPackedInt_a0;
+  result.a1 = returnStruct8BytesPackedInt_a1;
+  result.a2 = returnStruct8BytesPackedInt_a2;
+  result.a3 = returnStruct8BytesPackedInt_a3;
+  result.a4 = returnStruct8BytesPackedInt_a4;
+
+  returnStruct8BytesPackedIntResultPointer = resultPointer;
+
+  return result;
+}
+
+/// Struct with mis-aligned member.
+Struct8BytesPackedInt returnStruct8BytesPackedInt(
+    int a0, int a1, int a2, int a3, int a4) {
+  print("returnStruct8BytesPackedInt(${a0}, ${a1}, ${a2}, ${a3}, ${a4})");
+
+  // In legacy mode, possibly return null.
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0 == 42 || a0 == 84) {
+    print("throwing!");
+    throw Exception("ReturnStruct8BytesPackedInt throwing on purpose!");
+  }
+
+  returnStruct8BytesPackedInt_a0 = a0;
+  returnStruct8BytesPackedInt_a1 = a1;
+  returnStruct8BytesPackedInt_a2 = a2;
+  returnStruct8BytesPackedInt_a3 = a3;
+  returnStruct8BytesPackedInt_a4 = a4;
+
+  final result = returnStruct8BytesPackedIntCalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void returnStruct8BytesPackedIntAfterCallback() {
+  calloc.free(returnStruct8BytesPackedIntResultPointer);
+
+  final result = returnStruct8BytesPackedIntCalculateResult();
+
+  print("after callback result = $result");
+
+  calloc.free(returnStruct8BytesPackedIntResultPointer);
+}
+
+typedef ReturnStruct9BytesPackedMixedType = Struct9BytesPackedMixed Function(
+    Uint8, Double);
+
+// Global variables to be able to test inputs after callback returned.
+int returnStruct9BytesPackedMixed_a0 = 0;
+double returnStruct9BytesPackedMixed_a1 = 0.0;
+
+// Result variable also global, so we can delete it after the callback.
+Pointer<Struct9BytesPackedMixed> returnStruct9BytesPackedMixedResultPointer =
+    nullptr;
+
+Struct9BytesPackedMixed returnStruct9BytesPackedMixedCalculateResult() {
+  final resultPointer = calloc<Struct9BytesPackedMixed>();
+  final result = resultPointer.ref;
+
+  result.a0 = returnStruct9BytesPackedMixed_a0;
+  result.a1 = returnStruct9BytesPackedMixed_a1;
+
+  returnStruct9BytesPackedMixedResultPointer = resultPointer;
+
+  return result;
+}
+
+/// Struct with mis-aligned member.
+/// Tests backfilling of CPU and FPU registers.
+Struct9BytesPackedMixed returnStruct9BytesPackedMixed(int a0, double a1) {
+  print("returnStruct9BytesPackedMixed(${a0}, ${a1})");
+
+  // In legacy mode, possibly return null.
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0 == 42 || a0 == 84) {
+    print("throwing!");
+    throw Exception("ReturnStruct9BytesPackedMixed throwing on purpose!");
+  }
+
+  returnStruct9BytesPackedMixed_a0 = a0;
+  returnStruct9BytesPackedMixed_a1 = a1;
+
+  final result = returnStruct9BytesPackedMixedCalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void returnStruct9BytesPackedMixedAfterCallback() {
+  calloc.free(returnStruct9BytesPackedMixedResultPointer);
+
+  final result = returnStruct9BytesPackedMixedCalculateResult();
+
+  print("after callback result = $result");
+
+  calloc.free(returnStruct9BytesPackedMixedResultPointer);
+}
+
 typedef ReturnStructArgumentStruct1ByteIntType = Struct1ByteInt Function(
     Struct1ByteInt);
 
diff --git a/tests/ffi/function_callbacks_test.dart b/tests/ffi/function_callbacks_test.dart
index 2b12a98..e9a853c 100644
--- a/tests/ffi/function_callbacks_test.dart
+++ b/tests/ffi/function_callbacks_test.dart
@@ -13,6 +13,7 @@
 // VMOptions=--use-slow-path --enable-testing-pragmas --write-protect-code --no-dual-map-code
 // VMOptions=--use-slow-path --enable-testing-pragmas --write-protect-code --no-dual-map-code --stacktrace-every=100
 // VMOptions=--use-bare-instructions=false
+// VMOptions=--enable-testing-pragmas --dwarf_stack_traces --no-retain_function_objects --no-retain_code_objects
 // SharedObjects=ffi_test_functions
 
 import 'dart:ffi';
@@ -25,6 +26,13 @@
   return x + y;
 }
 
+class Foo {
+  static int simpleAddition(int x, int y) {
+    print("Foo.simpleAddition($x, $y)");
+    return x + y;
+  }
+}
+
 typedef IntComputationType = Int64 Function(Int8, Int16, Int32, Int64);
 int intComputation(int a, int b, int c, int d) {
   print("intComputation($a, $b, $c, $d)");
@@ -190,6 +198,8 @@
 final testcases = [
   CallbackTest("SimpleAddition",
       Pointer.fromFunction<SimpleAdditionType>(simpleAddition, 0)),
+  CallbackTest("SimpleAddition",
+      Pointer.fromFunction<SimpleAdditionType>(Foo.simpleAddition, 0)),
   CallbackTest("IntComputation",
       Pointer.fromFunction<IntComputationType>(intComputation, 0)),
   CallbackTest("UintComputation",
diff --git a/tests/ffi/function_structs_by_value_generated_test.dart b/tests/ffi/function_structs_by_value_generated_test.dart
index e909559..d52c0d3 100644
--- a/tests/ffi/function_structs_by_value_generated_test.dart
+++ b/tests/ffi/function_structs_by_value_generated_test.dart
@@ -68,6 +68,15 @@
     testPassStructStruct16BytesHomogeneousFloat2x5();
     testPassStructStruct32BytesHomogeneousDouble2x5();
     testPassStructStruct16BytesMixed3x10();
+    testPassUint8Struct32BytesInlineArrayMultiDimensionalI();
+    testPassUint8Struct4BytesInlineArrayMultiDimensionalIn();
+    testPassStruct3BytesPackedIntx10();
+    testPassStruct8BytesPackedIntx10();
+    testPassStruct9BytesPackedMixedx10DoubleInt32();
+    testPassStruct5BytesPackedMixed();
+    testPassStructNestedAlignmentStruct5BytesPackedMixed();
+    testPassStruct6BytesInlineArrayInt();
+    testPassStruct15BytesInlineArrayMixed();
     testReturnStruct1ByteInt();
     testReturnStruct3BytesHomogeneousUint8();
     testReturnStruct3BytesInt2ByteAligned();
@@ -90,6 +99,9 @@
     testReturnStruct32BytesHomogeneousDouble();
     testReturnStruct40BytesHomogeneousDouble();
     testReturnStruct1024BytesHomogeneousUint64();
+    testReturnStruct3BytesPackedInt();
+    testReturnStruct8BytesPackedInt();
+    testReturnStruct9BytesPackedMixed();
     testReturnStructArgumentStruct1ByteInt();
     testReturnStructArgumentInt32x8Struct1ByteInt();
     testReturnStructArgumentStruct8BytesHomogeneousFloat();
@@ -1043,7 +1055,7 @@
   @Array(8)
   external Array<Uint8> a0;
 
-  String toString() => "(${[for (var i = 0; i < 8; i += 1) a0[i]]})";
+  String toString() => "(${[for (var i0 = 0; i0 < 8; i0 += 1) a0[i0]]})";
 }
 
 class StructInlineArrayIrregular extends Struct {
@@ -1053,14 +1065,14 @@
   @Uint8()
   external int a1;
 
-  String toString() => "(${[for (var i = 0; i < 2; i += 1) a0[i]]}, ${a1})";
+  String toString() => "(${[for (var i0 = 0; i0 < 2; i0 += 1) a0[i0]]}, ${a1})";
 }
 
 class StructInlineArray100Bytes extends Struct {
   @Array(100)
   external Array<Uint8> a0;
 
-  String toString() => "(${[for (var i = 0; i < 100; i += 1) a0[i]]})";
+  String toString() => "(${[for (var i0 = 0; i0 < 100; i0 += 1) a0[i0]]})";
 }
 
 class StructInlineArrayBig extends Struct {
@@ -1074,7 +1086,7 @@
   external Array<Uint8> a2;
 
   String toString() =>
-      "(${a0}, ${a1}, ${[for (var i = 0; i < 4000; i += 1) a2[i]]})";
+      "(${a0}, ${a1}, ${[for (var i0 = 0; i0 < 4000; i0 += 1) a2[i0]]})";
 }
 
 class StructStruct16BytesHomogeneousFloat2 extends Struct {
@@ -1087,7 +1099,7 @@
   external double a2;
 
   String toString() =>
-      "(${a0}, ${[for (var i = 0; i < 2; i += 1) a1[i]]}, ${a2})";
+      "(${a0}, ${[for (var i0 = 0; i0 < 2; i0 += 1) a1[i0]]}, ${a2})";
 }
 
 class StructStruct32BytesHomogeneousDouble2 extends Struct {
@@ -1100,7 +1112,7 @@
   external double a2;
 
   String toString() =>
-      "(${a0}, ${[for (var i = 0; i < 2; i += 1) a1[i]]}, ${a2})";
+      "(${a0}, ${[for (var i0 = 0; i0 < 2; i0 += 1) a1[i0]]}, ${a2})";
 }
 
 class StructStruct16BytesMixed3 extends Struct {
@@ -1112,11 +1124,165 @@
   @Array(2)
   external Array<Int16> a2;
 
-  String toString() => "(${a0}, ${[for (var i = 0; i < 1; i += 1) a1[i]]}, ${[
-        for (var i = 0; i < 2; i += 1) a2[i]
+  String toString() => "(${a0}, ${[
+        for (var i0 = 0; i0 < 1; i0 += 1) a1[i0]
+      ]}, ${[for (var i0 = 0; i0 < 2; i0 += 1) a2[i0]]})";
+}
+
+class Struct8BytesInlineArrayMultiDimensionalInt extends Struct {
+  @Array(2, 2, 2)
+  external Array<Array<Array<Uint8>>> a0;
+
+  String toString() => "(${[
+        for (var i0 = 0; i0 < 2; i0 += 1)
+          [
+            for (var i1 = 0; i1 < 2; i1 += 1)
+              [for (var i2 = 0; i2 < 2; i2 += 1) a0[i0][i1][i2]]
+          ]
       ]})";
 }
 
+class Struct32BytesInlineArrayMultiDimensionalInt extends Struct {
+  @Array(2, 2, 2, 2, 2)
+  external Array<Array<Array<Array<Array<Uint8>>>>> a0;
+
+  String toString() => "(${[
+        for (var i0 = 0; i0 < 2; i0 += 1)
+          [
+            for (var i1 = 0; i1 < 2; i1 += 1)
+              [
+                for (var i2 = 0; i2 < 2; i2 += 1)
+                  [
+                    for (var i3 = 0; i3 < 2; i3 += 1)
+                      [for (var i4 = 0; i4 < 2; i4 += 1) a0[i0][i1][i2][i3][i4]]
+                  ]
+              ]
+          ]
+      ]})";
+}
+
+class Struct64BytesInlineArrayMultiDimensionalInt extends Struct {
+  @Array.multi([2, 2, 2, 2, 2, 2])
+  external Array<Array<Array<Array<Array<Array<Uint8>>>>>> a0;
+
+  String toString() => "(${[
+        for (var i0 = 0; i0 < 2; i0 += 1)
+          [
+            for (var i1 = 0; i1 < 2; i1 += 1)
+              [
+                for (var i2 = 0; i2 < 2; i2 += 1)
+                  [
+                    for (var i3 = 0; i3 < 2; i3 += 1)
+                      [
+                        for (var i4 = 0; i4 < 2; i4 += 1)
+                          [
+                            for (var i5 = 0; i5 < 2; i5 += 1)
+                              a0[i0][i1][i2][i3][i4][i5]
+                          ]
+                      ]
+                  ]
+              ]
+          ]
+      ]})";
+}
+
+class Struct4BytesInlineArrayMultiDimensionalInt extends Struct {
+  @Array(2, 2)
+  external Array<Array<Struct1ByteInt>> a0;
+
+  String toString() => "(${[
+        for (var i0 = 0; i0 < 2; i0 += 1)
+          [for (var i1 = 0; i1 < 2; i1 += 1) a0[i0][i1]]
+      ]})";
+}
+
+@Packed(1)
+class Struct3BytesPackedInt extends Struct {
+  @Int8()
+  external int a0;
+
+  @Int16()
+  external int a1;
+
+  String toString() => "(${a0}, ${a1})";
+}
+
+@Packed(1)
+class Struct3BytesPackedIntMembersAligned extends Struct {
+  @Int8()
+  external int a0;
+
+  @Int16()
+  external int a1;
+
+  String toString() => "(${a0}, ${a1})";
+}
+
+@Packed(1)
+class Struct5BytesPackedMixed extends Struct {
+  @Float()
+  external double a0;
+
+  @Uint8()
+  external int a1;
+
+  String toString() => "(${a0}, ${a1})";
+}
+
+class StructNestedAlignmentStruct5BytesPackedMixed extends Struct {
+  @Uint8()
+  external int a0;
+
+  external Struct5BytesPackedMixed a1;
+
+  String toString() => "(${a0}, ${a1})";
+}
+
+class Struct6BytesInlineArrayInt extends Struct {
+  @Array(2)
+  external Array<Struct3BytesPackedIntMembersAligned> a0;
+
+  String toString() => "(${[for (var i0 = 0; i0 < 2; i0 += 1) a0[i0]]})";
+}
+
+@Packed(1)
+class Struct8BytesPackedInt extends Struct {
+  @Uint8()
+  external int a0;
+
+  @Uint32()
+  external int a1;
+
+  @Uint8()
+  external int a2;
+
+  @Uint8()
+  external int a3;
+
+  @Uint8()
+  external int a4;
+
+  String toString() => "(${a0}, ${a1}, ${a2}, ${a3}, ${a4})";
+}
+
+@Packed(1)
+class Struct9BytesPackedMixed extends Struct {
+  @Uint8()
+  external int a0;
+
+  @Double()
+  external double a1;
+
+  String toString() => "(${a0}, ${a1})";
+}
+
+class Struct15BytesInlineArrayMixed extends Struct {
+  @Array(3)
+  external Array<Struct5BytesPackedMixed> a0;
+
+  String toString() => "(${[for (var i0 = 0; i0 < 3; i0 += 1) a0[i0]]})";
+}
+
 final passStruct1ByteIntx10 = ffiTestFunctions.lookupFunction<
     Int64 Function(
         Struct1ByteInt,
@@ -5227,6 +5393,529 @@
   calloc.free(a9Pointer);
 }
 
+final passUint8Struct32BytesInlineArrayMultiDimensionalI =
+    ffiTestFunctions.lookupFunction<
+        Uint32 Function(
+            Uint8,
+            Struct32BytesInlineArrayMultiDimensionalInt,
+            Uint8,
+            Struct8BytesInlineArrayMultiDimensionalInt,
+            Uint8,
+            Struct8BytesInlineArrayMultiDimensionalInt,
+            Uint8),
+        int Function(
+            int,
+            Struct32BytesInlineArrayMultiDimensionalInt,
+            int,
+            Struct8BytesInlineArrayMultiDimensionalInt,
+            int,
+            Struct8BytesInlineArrayMultiDimensionalInt,
+            int)>("PassUint8Struct32BytesInlineArrayMultiDimensionalI");
+
+/// Test multi dimensional inline array struct as argument.
+void testPassUint8Struct32BytesInlineArrayMultiDimensionalI() {
+  int a0;
+  final a1Pointer = calloc<Struct32BytesInlineArrayMultiDimensionalInt>();
+  final Struct32BytesInlineArrayMultiDimensionalInt a1 = a1Pointer.ref;
+  int a2;
+  final a3Pointer = calloc<Struct8BytesInlineArrayMultiDimensionalInt>();
+  final Struct8BytesInlineArrayMultiDimensionalInt a3 = a3Pointer.ref;
+  int a4;
+  final a5Pointer = calloc<Struct8BytesInlineArrayMultiDimensionalInt>();
+  final Struct8BytesInlineArrayMultiDimensionalInt a5 = a5Pointer.ref;
+  int a6;
+
+  a0 = 1;
+  a1.a0[0][0][0][0][0] = 2;
+  a1.a0[0][0][0][0][1] = 3;
+  a1.a0[0][0][0][1][0] = 4;
+  a1.a0[0][0][0][1][1] = 5;
+  a1.a0[0][0][1][0][0] = 6;
+  a1.a0[0][0][1][0][1] = 7;
+  a1.a0[0][0][1][1][0] = 8;
+  a1.a0[0][0][1][1][1] = 9;
+  a1.a0[0][1][0][0][0] = 10;
+  a1.a0[0][1][0][0][1] = 11;
+  a1.a0[0][1][0][1][0] = 12;
+  a1.a0[0][1][0][1][1] = 13;
+  a1.a0[0][1][1][0][0] = 14;
+  a1.a0[0][1][1][0][1] = 15;
+  a1.a0[0][1][1][1][0] = 16;
+  a1.a0[0][1][1][1][1] = 17;
+  a1.a0[1][0][0][0][0] = 18;
+  a1.a0[1][0][0][0][1] = 19;
+  a1.a0[1][0][0][1][0] = 20;
+  a1.a0[1][0][0][1][1] = 21;
+  a1.a0[1][0][1][0][0] = 22;
+  a1.a0[1][0][1][0][1] = 23;
+  a1.a0[1][0][1][1][0] = 24;
+  a1.a0[1][0][1][1][1] = 25;
+  a1.a0[1][1][0][0][0] = 26;
+  a1.a0[1][1][0][0][1] = 27;
+  a1.a0[1][1][0][1][0] = 28;
+  a1.a0[1][1][0][1][1] = 29;
+  a1.a0[1][1][1][0][0] = 30;
+  a1.a0[1][1][1][0][1] = 31;
+  a1.a0[1][1][1][1][0] = 32;
+  a1.a0[1][1][1][1][1] = 33;
+  a2 = 34;
+  a3.a0[0][0][0] = 35;
+  a3.a0[0][0][1] = 36;
+  a3.a0[0][1][0] = 37;
+  a3.a0[0][1][1] = 38;
+  a3.a0[1][0][0] = 39;
+  a3.a0[1][0][1] = 40;
+  a3.a0[1][1][0] = 41;
+  a3.a0[1][1][1] = 42;
+  a4 = 43;
+  a5.a0[0][0][0] = 44;
+  a5.a0[0][0][1] = 45;
+  a5.a0[0][1][0] = 46;
+  a5.a0[0][1][1] = 47;
+  a5.a0[1][0][0] = 48;
+  a5.a0[1][0][1] = 49;
+  a5.a0[1][1][0] = 50;
+  a5.a0[1][1][1] = 51;
+  a6 = 52;
+
+  final result = passUint8Struct32BytesInlineArrayMultiDimensionalI(
+      a0, a1, a2, a3, a4, a5, a6);
+
+  print("result = $result");
+
+  Expect.equals(1378, result);
+
+  calloc.free(a1Pointer);
+  calloc.free(a3Pointer);
+  calloc.free(a5Pointer);
+}
+
+final passUint8Struct4BytesInlineArrayMultiDimensionalIn =
+    ffiTestFunctions.lookupFunction<
+        Uint32 Function(
+            Uint8, Struct4BytesInlineArrayMultiDimensionalInt, Uint8),
+        int Function(int, Struct4BytesInlineArrayMultiDimensionalInt,
+            int)>("PassUint8Struct4BytesInlineArrayMultiDimensionalIn");
+
+/// Test struct in multi dimensional inline array.
+void testPassUint8Struct4BytesInlineArrayMultiDimensionalIn() {
+  int a0;
+  final a1Pointer = calloc<Struct4BytesInlineArrayMultiDimensionalInt>();
+  final Struct4BytesInlineArrayMultiDimensionalInt a1 = a1Pointer.ref;
+  int a2;
+
+  a0 = 1;
+  a1.a0[0][0].a0 = 2;
+  a1.a0[0][1].a0 = -3;
+  a1.a0[1][0].a0 = 4;
+  a1.a0[1][1].a0 = -5;
+  a2 = 6;
+
+  final result = passUint8Struct4BytesInlineArrayMultiDimensionalIn(a0, a1, a2);
+
+  print("result = $result");
+
+  Expect.equals(5, result);
+
+  calloc.free(a1Pointer);
+}
+
+final passStruct3BytesPackedIntx10 = ffiTestFunctions.lookupFunction<
+    Int64 Function(
+        Struct3BytesPackedInt,
+        Struct3BytesPackedInt,
+        Struct3BytesPackedInt,
+        Struct3BytesPackedInt,
+        Struct3BytesPackedInt,
+        Struct3BytesPackedInt,
+        Struct3BytesPackedInt,
+        Struct3BytesPackedInt,
+        Struct3BytesPackedInt,
+        Struct3BytesPackedInt),
+    int Function(
+        Struct3BytesPackedInt,
+        Struct3BytesPackedInt,
+        Struct3BytesPackedInt,
+        Struct3BytesPackedInt,
+        Struct3BytesPackedInt,
+        Struct3BytesPackedInt,
+        Struct3BytesPackedInt,
+        Struct3BytesPackedInt,
+        Struct3BytesPackedInt,
+        Struct3BytesPackedInt)>("PassStruct3BytesPackedIntx10");
+
+/// Small struct with mis-aligned member.
+void testPassStruct3BytesPackedIntx10() {
+  final a0Pointer = calloc<Struct3BytesPackedInt>();
+  final Struct3BytesPackedInt a0 = a0Pointer.ref;
+  final a1Pointer = calloc<Struct3BytesPackedInt>();
+  final Struct3BytesPackedInt a1 = a1Pointer.ref;
+  final a2Pointer = calloc<Struct3BytesPackedInt>();
+  final Struct3BytesPackedInt a2 = a2Pointer.ref;
+  final a3Pointer = calloc<Struct3BytesPackedInt>();
+  final Struct3BytesPackedInt a3 = a3Pointer.ref;
+  final a4Pointer = calloc<Struct3BytesPackedInt>();
+  final Struct3BytesPackedInt a4 = a4Pointer.ref;
+  final a5Pointer = calloc<Struct3BytesPackedInt>();
+  final Struct3BytesPackedInt a5 = a5Pointer.ref;
+  final a6Pointer = calloc<Struct3BytesPackedInt>();
+  final Struct3BytesPackedInt a6 = a6Pointer.ref;
+  final a7Pointer = calloc<Struct3BytesPackedInt>();
+  final Struct3BytesPackedInt a7 = a7Pointer.ref;
+  final a8Pointer = calloc<Struct3BytesPackedInt>();
+  final Struct3BytesPackedInt a8 = a8Pointer.ref;
+  final a9Pointer = calloc<Struct3BytesPackedInt>();
+  final Struct3BytesPackedInt a9 = a9Pointer.ref;
+
+  a0.a0 = -1;
+  a0.a1 = 2;
+  a1.a0 = -3;
+  a1.a1 = 4;
+  a2.a0 = -5;
+  a2.a1 = 6;
+  a3.a0 = -7;
+  a3.a1 = 8;
+  a4.a0 = -9;
+  a4.a1 = 10;
+  a5.a0 = -11;
+  a5.a1 = 12;
+  a6.a0 = -13;
+  a6.a1 = 14;
+  a7.a0 = -15;
+  a7.a1 = 16;
+  a8.a0 = -17;
+  a8.a1 = 18;
+  a9.a0 = -19;
+  a9.a1 = 20;
+
+  final result =
+      passStruct3BytesPackedIntx10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  print("result = $result");
+
+  Expect.equals(10, result);
+
+  calloc.free(a0Pointer);
+  calloc.free(a1Pointer);
+  calloc.free(a2Pointer);
+  calloc.free(a3Pointer);
+  calloc.free(a4Pointer);
+  calloc.free(a5Pointer);
+  calloc.free(a6Pointer);
+  calloc.free(a7Pointer);
+  calloc.free(a8Pointer);
+  calloc.free(a9Pointer);
+}
+
+final passStruct8BytesPackedIntx10 = ffiTestFunctions.lookupFunction<
+    Int64 Function(
+        Struct8BytesPackedInt,
+        Struct8BytesPackedInt,
+        Struct8BytesPackedInt,
+        Struct8BytesPackedInt,
+        Struct8BytesPackedInt,
+        Struct8BytesPackedInt,
+        Struct8BytesPackedInt,
+        Struct8BytesPackedInt,
+        Struct8BytesPackedInt,
+        Struct8BytesPackedInt),
+    int Function(
+        Struct8BytesPackedInt,
+        Struct8BytesPackedInt,
+        Struct8BytesPackedInt,
+        Struct8BytesPackedInt,
+        Struct8BytesPackedInt,
+        Struct8BytesPackedInt,
+        Struct8BytesPackedInt,
+        Struct8BytesPackedInt,
+        Struct8BytesPackedInt,
+        Struct8BytesPackedInt)>("PassStruct8BytesPackedIntx10");
+
+/// Struct with mis-aligned member.
+void testPassStruct8BytesPackedIntx10() {
+  final a0Pointer = calloc<Struct8BytesPackedInt>();
+  final Struct8BytesPackedInt a0 = a0Pointer.ref;
+  final a1Pointer = calloc<Struct8BytesPackedInt>();
+  final Struct8BytesPackedInt a1 = a1Pointer.ref;
+  final a2Pointer = calloc<Struct8BytesPackedInt>();
+  final Struct8BytesPackedInt a2 = a2Pointer.ref;
+  final a3Pointer = calloc<Struct8BytesPackedInt>();
+  final Struct8BytesPackedInt a3 = a3Pointer.ref;
+  final a4Pointer = calloc<Struct8BytesPackedInt>();
+  final Struct8BytesPackedInt a4 = a4Pointer.ref;
+  final a5Pointer = calloc<Struct8BytesPackedInt>();
+  final Struct8BytesPackedInt a5 = a5Pointer.ref;
+  final a6Pointer = calloc<Struct8BytesPackedInt>();
+  final Struct8BytesPackedInt a6 = a6Pointer.ref;
+  final a7Pointer = calloc<Struct8BytesPackedInt>();
+  final Struct8BytesPackedInt a7 = a7Pointer.ref;
+  final a8Pointer = calloc<Struct8BytesPackedInt>();
+  final Struct8BytesPackedInt a8 = a8Pointer.ref;
+  final a9Pointer = calloc<Struct8BytesPackedInt>();
+  final Struct8BytesPackedInt a9 = a9Pointer.ref;
+
+  a0.a0 = 1;
+  a0.a1 = 2;
+  a0.a2 = 3;
+  a0.a3 = 4;
+  a0.a4 = 5;
+  a1.a0 = 6;
+  a1.a1 = 7;
+  a1.a2 = 8;
+  a1.a3 = 9;
+  a1.a4 = 10;
+  a2.a0 = 11;
+  a2.a1 = 12;
+  a2.a2 = 13;
+  a2.a3 = 14;
+  a2.a4 = 15;
+  a3.a0 = 16;
+  a3.a1 = 17;
+  a3.a2 = 18;
+  a3.a3 = 19;
+  a3.a4 = 20;
+  a4.a0 = 21;
+  a4.a1 = 22;
+  a4.a2 = 23;
+  a4.a3 = 24;
+  a4.a4 = 25;
+  a5.a0 = 26;
+  a5.a1 = 27;
+  a5.a2 = 28;
+  a5.a3 = 29;
+  a5.a4 = 30;
+  a6.a0 = 31;
+  a6.a1 = 32;
+  a6.a2 = 33;
+  a6.a3 = 34;
+  a6.a4 = 35;
+  a7.a0 = 36;
+  a7.a1 = 37;
+  a7.a2 = 38;
+  a7.a3 = 39;
+  a7.a4 = 40;
+  a8.a0 = 41;
+  a8.a1 = 42;
+  a8.a2 = 43;
+  a8.a3 = 44;
+  a8.a4 = 45;
+  a9.a0 = 46;
+  a9.a1 = 47;
+  a9.a2 = 48;
+  a9.a3 = 49;
+  a9.a4 = 50;
+
+  final result =
+      passStruct8BytesPackedIntx10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  print("result = $result");
+
+  Expect.equals(1275, result);
+
+  calloc.free(a0Pointer);
+  calloc.free(a1Pointer);
+  calloc.free(a2Pointer);
+  calloc.free(a3Pointer);
+  calloc.free(a4Pointer);
+  calloc.free(a5Pointer);
+  calloc.free(a6Pointer);
+  calloc.free(a7Pointer);
+  calloc.free(a8Pointer);
+  calloc.free(a9Pointer);
+}
+
+final passStruct9BytesPackedMixedx10DoubleInt32 =
+    ffiTestFunctions.lookupFunction<
+        Double Function(
+            Struct9BytesPackedMixed,
+            Struct9BytesPackedMixed,
+            Struct9BytesPackedMixed,
+            Struct9BytesPackedMixed,
+            Struct9BytesPackedMixed,
+            Struct9BytesPackedMixed,
+            Struct9BytesPackedMixed,
+            Struct9BytesPackedMixed,
+            Struct9BytesPackedMixed,
+            Struct9BytesPackedMixed,
+            Double,
+            Int32),
+        double Function(
+            Struct9BytesPackedMixed,
+            Struct9BytesPackedMixed,
+            Struct9BytesPackedMixed,
+            Struct9BytesPackedMixed,
+            Struct9BytesPackedMixed,
+            Struct9BytesPackedMixed,
+            Struct9BytesPackedMixed,
+            Struct9BytesPackedMixed,
+            Struct9BytesPackedMixed,
+            Struct9BytesPackedMixed,
+            double,
+            int)>("PassStruct9BytesPackedMixedx10DoubleInt32");
+
+/// Struct with mis-aligned member.
+/// Tests backfilling of CPU and FPU registers.
+void testPassStruct9BytesPackedMixedx10DoubleInt32() {
+  final a0Pointer = calloc<Struct9BytesPackedMixed>();
+  final Struct9BytesPackedMixed a0 = a0Pointer.ref;
+  final a1Pointer = calloc<Struct9BytesPackedMixed>();
+  final Struct9BytesPackedMixed a1 = a1Pointer.ref;
+  final a2Pointer = calloc<Struct9BytesPackedMixed>();
+  final Struct9BytesPackedMixed a2 = a2Pointer.ref;
+  final a3Pointer = calloc<Struct9BytesPackedMixed>();
+  final Struct9BytesPackedMixed a3 = a3Pointer.ref;
+  final a4Pointer = calloc<Struct9BytesPackedMixed>();
+  final Struct9BytesPackedMixed a4 = a4Pointer.ref;
+  final a5Pointer = calloc<Struct9BytesPackedMixed>();
+  final Struct9BytesPackedMixed a5 = a5Pointer.ref;
+  final a6Pointer = calloc<Struct9BytesPackedMixed>();
+  final Struct9BytesPackedMixed a6 = a6Pointer.ref;
+  final a7Pointer = calloc<Struct9BytesPackedMixed>();
+  final Struct9BytesPackedMixed a7 = a7Pointer.ref;
+  final a8Pointer = calloc<Struct9BytesPackedMixed>();
+  final Struct9BytesPackedMixed a8 = a8Pointer.ref;
+  final a9Pointer = calloc<Struct9BytesPackedMixed>();
+  final Struct9BytesPackedMixed a9 = a9Pointer.ref;
+  double a10;
+  int a11;
+
+  a0.a0 = 1;
+  a0.a1 = 2.0;
+  a1.a0 = 3;
+  a1.a1 = 4.0;
+  a2.a0 = 5;
+  a2.a1 = 6.0;
+  a3.a0 = 7;
+  a3.a1 = 8.0;
+  a4.a0 = 9;
+  a4.a1 = 10.0;
+  a5.a0 = 11;
+  a5.a1 = 12.0;
+  a6.a0 = 13;
+  a6.a1 = 14.0;
+  a7.a0 = 15;
+  a7.a1 = 16.0;
+  a8.a0 = 17;
+  a8.a1 = 18.0;
+  a9.a0 = 19;
+  a9.a1 = 20.0;
+  a10 = -21.0;
+  a11 = 22;
+
+  final result = passStruct9BytesPackedMixedx10DoubleInt32(
+      a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11);
+
+  print("result = $result");
+
+  Expect.approxEquals(211.0, result);
+
+  calloc.free(a0Pointer);
+  calloc.free(a1Pointer);
+  calloc.free(a2Pointer);
+  calloc.free(a3Pointer);
+  calloc.free(a4Pointer);
+  calloc.free(a5Pointer);
+  calloc.free(a6Pointer);
+  calloc.free(a7Pointer);
+  calloc.free(a8Pointer);
+  calloc.free(a9Pointer);
+}
+
+final passStruct5BytesPackedMixed = ffiTestFunctions.lookupFunction<
+    Double Function(Struct5BytesPackedMixed),
+    double Function(Struct5BytesPackedMixed)>("PassStruct5BytesPackedMixed");
+
+/// This packed struct happens to have only aligned members.
+void testPassStruct5BytesPackedMixed() {
+  final a0Pointer = calloc<Struct5BytesPackedMixed>();
+  final Struct5BytesPackedMixed a0 = a0Pointer.ref;
+
+  a0.a0 = -1.0;
+  a0.a1 = 2;
+
+  final result = passStruct5BytesPackedMixed(a0);
+
+  print("result = $result");
+
+  Expect.approxEquals(1.0, result);
+
+  calloc.free(a0Pointer);
+}
+
+final passStructNestedAlignmentStruct5BytesPackedMixed =
+    ffiTestFunctions.lookupFunction<
+            Double Function(StructNestedAlignmentStruct5BytesPackedMixed),
+            double Function(StructNestedAlignmentStruct5BytesPackedMixed)>(
+        "PassStructNestedAlignmentStruct5BytesPackedMixed");
+
+/// Check alignment of packed struct in non-packed struct.
+void testPassStructNestedAlignmentStruct5BytesPackedMixed() {
+  final a0Pointer = calloc<StructNestedAlignmentStruct5BytesPackedMixed>();
+  final StructNestedAlignmentStruct5BytesPackedMixed a0 = a0Pointer.ref;
+
+  a0.a0 = 1;
+  a0.a1.a0 = 2.0;
+  a0.a1.a1 = 3;
+
+  final result = passStructNestedAlignmentStruct5BytesPackedMixed(a0);
+
+  print("result = $result");
+
+  Expect.approxEquals(6.0, result);
+
+  calloc.free(a0Pointer);
+}
+
+final passStruct6BytesInlineArrayInt = ffiTestFunctions.lookupFunction<
+    Double Function(Struct6BytesInlineArrayInt),
+    double Function(
+        Struct6BytesInlineArrayInt)>("PassStruct6BytesInlineArrayInt");
+
+/// Check alignment of packed struct array in non-packed struct.
+void testPassStruct6BytesInlineArrayInt() {
+  final a0Pointer = calloc<Struct6BytesInlineArrayInt>();
+  final Struct6BytesInlineArrayInt a0 = a0Pointer.ref;
+
+  a0.a0[0].a0 = -1;
+  a0.a0[0].a1 = 2;
+  a0.a0[1].a0 = -3;
+  a0.a0[1].a1 = 4;
+
+  final result = passStruct6BytesInlineArrayInt(a0);
+
+  print("result = $result");
+
+  Expect.approxEquals(2.0, result);
+
+  calloc.free(a0Pointer);
+}
+
+final passStruct15BytesInlineArrayMixed = ffiTestFunctions.lookupFunction<
+    Double Function(Struct15BytesInlineArrayMixed),
+    double Function(
+        Struct15BytesInlineArrayMixed)>("PassStruct15BytesInlineArrayMixed");
+
+/// Check alignment of packed struct array in non-packed struct.
+void testPassStruct15BytesInlineArrayMixed() {
+  final a0Pointer = calloc<Struct15BytesInlineArrayMixed>();
+  final Struct15BytesInlineArrayMixed a0 = a0Pointer.ref;
+
+  a0.a0[0].a0 = -1.0;
+  a0.a0[0].a1 = 2;
+  a0.a0[1].a0 = -3.0;
+  a0.a0[1].a1 = 4;
+  a0.a0[2].a0 = -5.0;
+  a0.a0[2].a1 = 6;
+
+  final result = passStruct15BytesInlineArrayMixed(a0);
+
+  print("result = $result");
+
+  Expect.approxEquals(3.0, result);
+
+  calloc.free(a0Pointer);
+}
+
 final returnStruct1ByteInt = ffiTestFunctions.lookupFunction<
     Struct1ByteInt Function(Int8),
     Struct1ByteInt Function(int)>("ReturnStruct1ByteInt");
@@ -6645,6 +7334,78 @@
   Expect.equals(a127, result.a127);
 }
 
+final returnStruct3BytesPackedInt = ffiTestFunctions.lookupFunction<
+    Struct3BytesPackedInt Function(Int8, Int16),
+    Struct3BytesPackedInt Function(int, int)>("ReturnStruct3BytesPackedInt");
+
+/// Small struct with mis-aligned member.
+void testReturnStruct3BytesPackedInt() {
+  int a0;
+  int a1;
+
+  a0 = -1;
+  a1 = 2;
+
+  final result = returnStruct3BytesPackedInt(a0, a1);
+
+  print("result = $result");
+
+  Expect.equals(a0, result.a0);
+  Expect.equals(a1, result.a1);
+}
+
+final returnStruct8BytesPackedInt = ffiTestFunctions.lookupFunction<
+    Struct8BytesPackedInt Function(Uint8, Uint32, Uint8, Uint8, Uint8),
+    Struct8BytesPackedInt Function(
+        int, int, int, int, int)>("ReturnStruct8BytesPackedInt");
+
+/// Struct with mis-aligned member.
+void testReturnStruct8BytesPackedInt() {
+  int a0;
+  int a1;
+  int a2;
+  int a3;
+  int a4;
+
+  a0 = 1;
+  a1 = 2;
+  a2 = 3;
+  a3 = 4;
+  a4 = 5;
+
+  final result = returnStruct8BytesPackedInt(a0, a1, a2, a3, a4);
+
+  print("result = $result");
+
+  Expect.equals(a0, result.a0);
+  Expect.equals(a1, result.a1);
+  Expect.equals(a2, result.a2);
+  Expect.equals(a3, result.a3);
+  Expect.equals(a4, result.a4);
+}
+
+final returnStruct9BytesPackedMixed = ffiTestFunctions.lookupFunction<
+    Struct9BytesPackedMixed Function(Uint8, Double),
+    Struct9BytesPackedMixed Function(
+        int, double)>("ReturnStruct9BytesPackedMixed");
+
+/// Struct with mis-aligned member.
+/// Tests backfilling of CPU and FPU registers.
+void testReturnStruct9BytesPackedMixed() {
+  int a0;
+  double a1;
+
+  a0 = 1;
+  a1 = 2.0;
+
+  final result = returnStruct9BytesPackedMixed(a0, a1);
+
+  print("result = $result");
+
+  Expect.equals(a0, result.a0);
+  Expect.approxEquals(a1, result.a1);
+}
+
 final returnStructArgumentStruct1ByteInt = ffiTestFunctions.lookupFunction<
     Struct1ByteInt Function(Struct1ByteInt),
     Struct1ByteInt Function(
diff --git a/tests/ffi/generator/c_types.dart b/tests/ffi/generator/c_types.dart
index 70fbfe1..df3b44b 100644
--- a/tests/ffi/generator/c_types.dart
+++ b/tests/ffi/generator/c_types.dart
@@ -133,8 +133,8 @@
   String get cStructField {
     String postFix = "";
     if (type is FixedLengthArrayType) {
-      final length = (type as FixedLengthArrayType).length;
-      postFix = "[$length]";
+      final dimensions = (type as FixedLengthArrayType).dimensions;
+      postFix = "[${dimensions.join("][")}]";
     }
     return "${type.cType} $name$postFix;";
   }
@@ -155,20 +155,24 @@
 class StructType extends CType {
   final List<Member> members;
 
+  final int? packing;
+
   /// To disambiguate same size structs.
   final String suffix;
 
   /// To override names.
   final String overrideName;
 
-  StructType(List<CType> memberTypes)
+  StructType(List<CType> memberTypes, {int? this.packing})
       : this.members = generateMemberNames(memberTypes),
         this.suffix = "",
         this.overrideName = "";
-  StructType.disambiguate(List<CType> memberTypes, this.suffix)
+  StructType.disambiguate(List<CType> memberTypes, this.suffix,
+      {int? this.packing})
       : this.members = generateMemberNames(memberTypes),
         this.overrideName = "";
-  StructType.override(List<CType> memberTypes, this.overrideName)
+  StructType.override(List<CType> memberTypes, this.overrideName,
+      {int? this.packing})
       : this.members = generateMemberNames(memberTypes),
         this.suffix = "";
 
@@ -183,9 +187,19 @@
       !memberTypes.map((e) => e.hasSize).contains(false) && !hasPadding;
   int get size => memberTypes.fold(0, (int acc, e) => acc + e.size);
 
-  /// Rough approximation, to not redo all ABI logic here.
-  bool get hasPadding =>
-      members.length < 2 ? false : members[0].type.size < members[1].type.size;
+  bool get hasPacking => packing != null;
+
+  bool get hasPadding {
+    if (members.length < 2) {
+      return false;
+    }
+    if (packing == 1) {
+      return false;
+    }
+
+    /// Rough approximation, to not redo all ABI logic here.
+    return members[0].type.size < members[1].type.size;
+  }
 
   bool get hasNestedStructs =>
       members.map((e) => e.type is StructType).contains(true);
@@ -193,6 +207,12 @@
   bool get hasInlineArrays =>
       members.map((e) => e.type is FixedLengthArrayType).contains(true);
 
+  bool get hasMultiDimensionalInlineArrays => members
+      .map((e) => e.type)
+      .whereType<FixedLengthArrayType>()
+      .where((e) => e.isMulti)
+      .isNotEmpty;
+
   /// All members have the same type.
   bool get isHomogeneous => memberTypes.toSet().length == 1;
 
@@ -211,11 +231,20 @@
     if (hasSize) {
       result += "${size}Byte" + (size != 1 ? "s" : "");
     }
+    if (hasPacking) {
+      result += "Packed";
+      if (packing! > 1) {
+        result += "$packing";
+      }
+    }
     if (hasNestedStructs) {
       result += "Nested";
     }
     if (hasInlineArrays) {
       result += "InlineArray";
+      if (hasMultiDimensionalInlineArrays) {
+        result += "MultiDimensional";
+      }
     }
     if (members.length == 0) {
       // No suffix.
@@ -241,10 +270,37 @@
 
   FixedLengthArrayType(this.elementType, this.length);
 
+  factory FixedLengthArrayType.multi(CType elementType, List<int> dimensions) {
+    if (dimensions.length == 1) {
+      return FixedLengthArrayType(elementType, dimensions.single);
+    }
+
+    final remainingDimensions = dimensions.sublist(1);
+    final nestedArray =
+        FixedLengthArrayType.multi(elementType, remainingDimensions);
+    return FixedLengthArrayType(nestedArray, dimensions.first);
+  }
+
   String get cType => elementType.cType;
-  String get dartCType => "Array<${elementType.dartType}>";
+  String get dartCType => "Array<${elementType.dartCType}>";
   String get dartType => "Array<${elementType.dartCType}>";
-  String get dartStructFieldAnnotation => "@Array($length)";
+
+  String get dartStructFieldAnnotation {
+    if (dimensions.length > 5) {
+      return "@Array.multi([${dimensions.join(", ")}])";
+    }
+    return "@Array(${dimensions.join(", ")})";
+  }
+
+  List<int> get dimensions {
+    final elementType = this.elementType;
+    if (elementType is FixedLengthArrayType) {
+      return [length, ...elementType.dimensions];
+    }
+    return [length];
+  }
+
+  bool get isMulti => elementType is FixedLengthArrayType;
 
   bool get hasSize => elementType.hasSize;
   int get size => elementType.size * length;
diff --git a/tests/ffi/generator/structs_by_value_tests_configuration.dart b/tests/ffi/generator/structs_by_value_tests_configuration.dart
index c681f8a..1ad3c11 100644
--- a/tests/ffi/generator/structs_by_value_tests_configuration.dart
+++ b/tests/ffi/generator/structs_by_value_tests_configuration.dart
@@ -310,6 +310,54 @@
 On x64, it will exhaust the integer registers with the 6th argument.
 The rest goes on the stack.
 On arm, arguments are 4 byte aligned."""),
+  FunctionType(
+      [
+        uint8,
+        struct32bytesInlineArrayMultiDimesional,
+        uint8,
+        struct8bytesInlineArrayMultiDimesional,
+        uint8,
+        struct8bytesInlineArrayMultiDimesional,
+        uint8
+      ],
+      uint32,
+      """
+Test multi dimensional inline array struct as argument."""),
+  FunctionType(
+      [uint8, structMultiDimensionalStruct, uint8],
+      uint32,
+      """
+Test struct in multi dimensional inline array."""),
+  FunctionType(List.filled(10, struct3bytesPacked), int64, """
+Small struct with mis-aligned member."""),
+  FunctionType(List.filled(10, struct8bytesPacked), int64, """
+Struct with mis-aligned member."""),
+  FunctionType(
+      [...List.filled(10, struct9bytesPacked), double_, int32],
+      double_,
+      """
+Struct with mis-aligned member.
+Tests backfilling of CPU and FPU registers."""),
+  FunctionType(
+      [struct5bytesPacked],
+      double_,
+      """
+This packed struct happens to have only aligned members."""),
+  FunctionType(
+      [struct6bytesPacked],
+      double_,
+      """
+Check alignment of packed struct in non-packed struct."""),
+  FunctionType(
+      [struct6bytesPacked2],
+      double_,
+      """
+Check alignment of packed struct array in non-packed struct."""),
+  FunctionType(
+      [struct15bytesPacked],
+      double_,
+      """
+Check alignment of packed struct array in non-packed struct."""),
   FunctionType(struct1byteInt.memberTypes, struct1byteInt, """
 Smallest struct with data."""),
   FunctionType(struct3bytesInt.memberTypes, struct3bytesInt, """
@@ -365,6 +413,13 @@
 Return value too big to go in FPU registers on arm64."""),
   FunctionType(struct1024bytesInt.memberTypes, struct1024bytesInt, """
 Test 1kb struct."""),
+  FunctionType(struct3bytesPacked.memberTypes, struct3bytesPacked, """
+Small struct with mis-aligned member."""),
+  FunctionType(struct8bytesPacked.memberTypes, struct8bytesPacked, """
+Struct with mis-aligned member."""),
+  FunctionType(struct9bytesPacked.memberTypes, struct9bytesPacked, """
+Struct with mis-aligned member.
+Tests backfilling of CPU and FPU registers."""),
   FunctionType(
       [struct1byteInt],
       struct1byteInt,
@@ -507,6 +562,18 @@
   struct16bytesFloatInlineNested,
   struct32bytesDoubleInlineNested,
   struct16bytesMixedInlineNested,
+  struct8bytesInlineArrayMultiDimesional,
+  struct32bytesInlineArrayMultiDimesional,
+  struct64bytesInlineArrayMultiDimesional,
+  structMultiDimensionalStruct,
+  struct3bytesPacked,
+  struct3bytesPackedMembersAligned,
+  struct5bytesPacked,
+  struct6bytesPacked,
+  struct6bytesPacked2,
+  struct8bytesPacked,
+  struct9bytesPacked,
+  struct15bytesPacked,
 ];
 
 final struct1byteInt = StructType([int8]);
@@ -634,3 +701,43 @@
   FixedLengthArrayType(StructType([float, int16, int16]), 1),
   FixedLengthArrayType(int16, 2),
 ], "Struct16BytesMixed3");
+
+final struct8bytesInlineArrayMultiDimesional = StructType([
+  FixedLengthArrayType.multi(uint8, [2, 2, 2])
+]);
+
+final struct32bytesInlineArrayMultiDimesional = StructType([
+  FixedLengthArrayType.multi(uint8, [2, 2, 2, 2, 2])
+]);
+
+final struct64bytesInlineArrayMultiDimesional = StructType([
+  FixedLengthArrayType.multi(uint8, [2, 2, 2, 2, 2, 2])
+]);
+
+final structMultiDimensionalStruct = StructType([
+  FixedLengthArrayType.multi(struct1byteInt, [2, 2])
+]);
+
+final struct3bytesPacked = StructType([int8, int16], packing: 1);
+
+final struct3bytesPackedMembersAligned =
+    StructType.disambiguate([int8, int16], "MembersAligned", packing: 1);
+
+final struct5bytesPacked = StructType([float, uint8], packing: 1);
+
+/// The float in the nested struct is not aligned.
+final struct6bytesPacked = StructType([uint8, struct5bytesPacked]);
+
+/// The second element in the array has a nested misaligned int16.
+final struct6bytesPacked2 =
+    StructType([FixedLengthArrayType(struct3bytesPackedMembersAligned, 2)]);
+
+final struct8bytesPacked =
+    StructType([uint8, uint32, uint8, uint8, uint8], packing: 1);
+
+final struct9bytesPacked = StructType([uint8, double_], packing: 1);
+
+/// The float in the nested struct is aligned in the first element in the
+/// inline array, but not in the subsequent ones.
+final struct15bytesPacked =
+    StructType([FixedLengthArrayType(struct5bytesPacked, 3)]);
diff --git a/tests/ffi/generator/structs_by_value_tests_generator.dart b/tests/ffi/generator/structs_by_value_tests_generator.dart
index 7ebb535..c66dbea 100644
--- a/tests/ffi/generator/structs_by_value_tests_generator.dart
+++ b/tests/ffi/generator/structs_by_value_tests_generator.dart
@@ -332,7 +332,7 @@
       case FixedLengthArrayType:
         final this_ = this as FixedLengthArrayType;
         return """
-for(int i = 0; i < ${this_.length}; i++){
+for (int i = 0; i < ${this_.length}; i++){
   ${this_.elementType.dartExpectsStatements("$expected[i]", "$actual[i]")}
 }
 """;
@@ -370,7 +370,7 @@
       case FixedLengthArrayType:
         final this_ = this as FixedLengthArrayType;
         return """
-for(intptr_t i = 0; i < ${this_.length}; i++){
+for (intptr_t i = 0; i < ${this_.length}; i++){
   ${this_.elementType.cExpectsStatements("$expected[i]", "$actual[i]")}
 }
 """;
@@ -397,7 +397,7 @@
       case FixedLengthArrayType:
         final this_ = this as FixedLengthArrayType;
         return """
-for(intptr_t i = 0; i < ${this_.length}; i++){
+for (intptr_t i = 0; i < ${this_.length}; i++){
   ${this_.elementType.cExpectsZeroStatements("$actual[i]")}
 }
 """;
@@ -455,18 +455,30 @@
 
 extension on StructType {
   String dartClass(bool nnbd) {
+    final packingAnnotation = hasPacking ? "@Packed(${packing})" : "";
     String dartFields = "";
     for (final member in members) {
       dartFields += "${member.dartStructField(nnbd)}\n\n";
     }
     String toStringBody = members.map((m) {
       if (m.type is FixedLengthArrayType) {
-        final length = (m.type as FixedLengthArrayType).length;
-        return "\$\{[for (var i = 0; i < $length; i += 1) ${m.name}[i]]\}";
+        int dimensionNumber = 0;
+        String inlineFor = "";
+        String read = m.name;
+        String closing = "";
+        for (final dimension in (m.type as FixedLengthArrayType).dimensions) {
+          final i = "i$dimensionNumber";
+          inlineFor += "[for (var $i = 0; $i < $dimension; $i += 1)";
+          read += "[$i]";
+          closing += "]";
+          dimensionNumber++;
+        }
+        return "\$\{$inlineFor $read $closing\}";
       }
       return "\$\{${m.name}\}";
     }).join(", ");
     return """
+    $packingAnnotation
     class $name extends Struct {
       $dartFields
 
@@ -476,14 +488,19 @@
   }
 
   String get cDefinition {
+    final packingPragmaPush =
+        hasPacking ? "#pragma pack(push, ${packing})" : "";
+    final packingPragmaPop = hasPacking ? "#pragma pack(pop)" : "";
     String cFields = "";
     for (final member in members) {
       cFields += "  ${member.cStructField}\n";
     }
     return """
+    $packingPragmaPush
     struct $name {
       $cFields
     };
+    $packingPragmaPop
 
     """;
   }
diff --git a/tests/ffi/inline_array_multi_dimensional_test.dart b/tests/ffi/inline_array_multi_dimensional_test.dart
new file mode 100644
index 0000000..15d2059
--- /dev/null
+++ b/tests/ffi/inline_array_multi_dimensional_test.dart
@@ -0,0 +1,164 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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
+
+import 'dart:ffi';
+
+import "package:expect/expect.dart";
+import 'package:ffi/ffi.dart';
+
+// Reuse struct definitions.
+import 'function_structs_by_value_generated_test.dart';
+
+void main() {
+  testSizeOf();
+  testLoad();
+  testLoadMultiAnnotation();
+  testStore();
+  testToString();
+  testRange();
+}
+
+void testSizeOf() {
+  Expect.equals(32, sizeOf<Struct32BytesInlineArrayMultiDimensionalInt>());
+  Expect.equals(64, sizeOf<Struct64BytesInlineArrayMultiDimensionalInt>());
+}
+
+/// Tests the load of nested `Array`s.
+///
+/// Only stores into arrays which do not have nested arrays.
+void testLoad() {
+  final Pointer<Struct32BytesInlineArrayMultiDimensionalInt> pointer = calloc();
+  final struct = pointer.ref;
+  final array = struct.a0;
+  for (int i = 0; i < 2; i++) {
+    for (int j = 0; j < 2; j++) {
+      for (int k = 0; k < 2; k++) {
+        for (int l = 0; l < 2; l++) {
+          for (int m = 0; m < 2; m++) {
+            array[i][j][k][l][m] = i + j + k + l + m;
+          }
+        }
+      }
+    }
+  }
+  for (int i = 0; i < 2; i++) {
+    for (int j = 0; j < 2; j++) {
+      for (int k = 0; k < 2; k++) {
+        for (int l = 0; l < 2; l++) {
+          for (int m = 0; m < 2; m++) {
+            Expect.equals(i + j + k + l + m, array[i][j][k][l][m]);
+          }
+        }
+      }
+    }
+  }
+  calloc.free(pointer);
+}
+
+/// Tests the load of nested `Array`s.
+///
+/// Only stores into arrays which do not have nested arrays.
+void testLoadMultiAnnotation() {
+  final Pointer<Struct64BytesInlineArrayMultiDimensionalInt> pointer = calloc();
+  final struct = pointer.ref;
+  final array = struct.a0;
+  for (int i = 0; i < 2; i++) {
+    for (int j = 0; j < 2; j++) {
+      for (int k = 0; k < 2; k++) {
+        for (int l = 0; l < 2; l++) {
+          for (int m = 0; m < 2; m++) {
+            for (int o = 0; o < 2; o++) {
+              array[i][j][k][l][m][o] = i + j + k + l + m + o;
+            }
+          }
+        }
+      }
+    }
+  }
+  for (int i = 0; i < 2; i++) {
+    for (int j = 0; j < 2; j++) {
+      for (int k = 0; k < 2; k++) {
+        for (int l = 0; l < 2; l++) {
+          for (int m = 0; m < 2; m++) {
+            for (int o = 0; o < 2; o++) {
+              Expect.equals(i + j + k + l + m + o, array[i][j][k][l][m][o]);
+            }
+          }
+        }
+      }
+    }
+  }
+  calloc.free(pointer);
+}
+
+void testStore() {
+  final Pointer<Struct32BytesInlineArrayMultiDimensionalInt> pointer = calloc();
+  final struct = pointer.ref;
+  final array = struct.a0;
+  for (int i = 0; i < 2; i++) {
+    for (int j = 0; j < 2; j++) {
+      for (int k = 0; k < 2; k++) {
+        for (int l = 0; l < 2; l++) {
+          for (int m = 0; m < 2; m++) {
+            array[i][j][k][l][m] = i + j + k + l + m;
+          }
+        }
+      }
+    }
+  }
+  array[0] = array[1]; // Copy many things.
+  for (int j = 0; j < 2; j++) {
+    for (int k = 0; k < 2; k++) {
+      for (int l = 0; l < 2; l++) {
+        for (int m = 0; m < 2; m++) {
+          Expect.equals(array[1][j][k][l][m], array[0][j][k][l][m]);
+        }
+      }
+    }
+  }
+  calloc.free(pointer);
+}
+
+// // Tests the toString of the test generator.
+void testToString() {
+  final Pointer<Struct32BytesInlineArrayMultiDimensionalInt> pointer = calloc();
+  final struct = pointer.ref;
+  final array = struct.a0;
+  for (int i = 0; i < 2; i++) {
+    for (int j = 0; j < 2; j++) {
+      for (int k = 0; k < 2; k++) {
+        for (int l = 0; l < 2; l++) {
+          for (int m = 0; m < 2; m++) {
+            array[i][j][k][l][m] = 16 * i + 8 * j + 4 * k + 2 * l + m;
+          }
+        }
+      }
+    }
+  }
+  Expect.equals(
+      "([[[[[0, 1], [2, 3]], [[4, 5], [6, 7]]], [[[8, 9], [10, 11]], [[12, 13], [14, 15]]]], [[[[16, 17], [18, 19]], [[20, 21], [22, 23]]], [[[24, 25], [26, 27]], [[28, 29], [30, 31]]]]])",
+      struct.toString());
+  calloc.free(pointer);
+}
+
+void testRange() {
+  final pointer = calloc<Struct32BytesInlineArrayMultiDimensionalInt>();
+  final struct = pointer.ref;
+  final array = struct.a0;
+  array[0];
+  array[1];
+  Expect.throws(() => array[-1]);
+  Expect.throws(() => array[-1] = array[1]);
+  Expect.throws(() => array[2]);
+  Expect.throws(() => array[2] = array[1]);
+  array[0][0];
+  array[0][1];
+  Expect.throws(() => array[0][-1]);
+  Expect.throws(() => array[0][-1] = array[0][1]);
+  Expect.throws(() => array[0][2]);
+  Expect.throws(() => array[0][2] = array[0][1]);
+  calloc.free(pointer);
+}
diff --git a/tests/ffi/inline_array_test.dart b/tests/ffi/inline_array_test.dart
index 518d62e..868d117 100644
--- a/tests/ffi/inline_array_test.dart
+++ b/tests/ffi/inline_array_test.dart
@@ -30,11 +30,11 @@
 void testLoad() {
   final pointer = calloc<Struct8BytesInlineArrayInt>();
   final struct = pointer.ref;
-  final cArray = struct.a0;
+  final array = struct.a0;
   pointer.cast<Uint8>()[0] = 42;
   pointer.cast<Uint8>()[7] = 3;
-  Expect.equals(42, cArray[0]);
-  Expect.equals(3, cArray[7]);
+  Expect.equals(42, array[0]);
+  Expect.equals(3, array[7]);
   calloc.free(pointer);
 }
 
@@ -55,9 +55,9 @@
 void testToString() {
   final pointer = calloc<Struct8BytesInlineArrayInt>();
   final struct = pointer.ref;
-  final cArray = struct.a0;
+  final array = struct.a0;
   for (var i = 0; i < 8; i++) {
-    cArray[i] = i;
+    array[i] = i;
   }
   Expect.equals("([0, 1, 2, 3, 4, 5, 6, 7])", struct.toString());
   calloc.free(pointer);
@@ -77,14 +77,14 @@
 void testRange() {
   final pointer = calloc<Struct8BytesInlineArrayInt>();
   final struct = pointer.ref;
-  final cArray = struct.a0;
-  cArray[0] = 1;
-  Expect.equals(1, cArray[0]);
-  cArray[7] = 7;
-  Expect.equals(7, cArray[7]);
-  Expect.throws(() => cArray[-1]);
-  Expect.throws(() => cArray[-1] = 0);
-  Expect.throws(() => cArray[8]);
-  Expect.throws(() => cArray[8] = 0);
+  final array = struct.a0;
+  array[0] = 1;
+  Expect.equals(1, array[0]);
+  array[7] = 7;
+  Expect.equals(7, array[7]);
+  Expect.throws(() => array[-1]);
+  Expect.throws(() => array[-1] = 0);
+  Expect.throws(() => array[8]);
+  Expect.throws(() => array[8] = 0);
   calloc.free(pointer);
 }
diff --git a/tests/ffi/regress_45189_test.dart b/tests/ffi/regress_45189_test.dart
new file mode 100644
index 0000000..980d1bc
--- /dev/null
+++ b/tests/ffi/regress_45189_test.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. 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 "package:ffi/ffi.dart";
+import 'package:expect/expect.dart';
+
+class Struct8BytesInlineArrayInt extends Struct {
+  @Array(8)
+  external Array<Uint8> a0;
+}
+
+void main() {
+  final pointer = calloc<Struct8BytesInlineArrayInt>();
+  final array = pointer.ref.a0;
+  try {
+    array[8]; // RangeError: Invalid value: Not in inclusive range 0..8: 8
+  } on RangeError catch (exception) {
+    final toString = exception.toString();
+    Expect.equals(
+        "RangeError: Invalid value: Not in inclusive range 0..7: 8", toString);
+  }
+  calloc.free(pointer);
+}
diff --git a/tests/ffi/regress_45198_test.dart b/tests/ffi/regress_45198_test.dart
new file mode 100644
index 0000000..3247d27
--- /dev/null
+++ b/tests/ffi/regress_45198_test.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. 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 "package:expect/expect.dart";
+import "package:ffi/ffi.dart";
+
+class Struct8BytesInlineArrayInt extends Struct {
+  @Array(2)
+  external Array<Pointer<Int8>> a0;
+}
+
+void main() {
+  final arrayPointer = calloc<Struct8BytesInlineArrayInt>();
+
+  final pointer = Pointer<Int8>.fromAddress(0xdeadbeef);
+
+  final array = arrayPointer.ref.a0;
+  print(arrayPointer);
+  print(array);
+  Expect.type<Array<Pointer<Int8>>>(array);
+  Expect.equals(nullptr, array[0]);
+  array[0] = pointer;
+  Expect.equals(pointer, array[0]);
+
+  calloc.free(arrayPointer);
+}
diff --git a/tests/ffi/regress_45507_test.dart b/tests/ffi/regress_45507_test.dart
new file mode 100644
index 0000000..9f46552
--- /dev/null
+++ b/tests/ffi/regress_45507_test.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. 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 "package:expect/expect.dart";
+
+const EIGHT = 8;
+
+class Struct8BytesInlineArrayInt extends Struct {
+  @Array(EIGHT)
+  external Array<Uint8> a0;
+}
+
+void main() {
+  Expect.equals(8, sizeOf<Struct8BytesInlineArrayInt>());
+}
diff --git a/tests/ffi/regress_flutter79441_test.dart b/tests/ffi/regress_flutter79441_test.dart
new file mode 100644
index 0000000..7f1336f
--- /dev/null
+++ b/tests/ffi/regress_flutter79441_test.dart
@@ -0,0 +1,38 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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/flutter/flutter/issues/79441.
+
+import 'dart:ffi';
+
+// FFI signature
+typedef _dart_memset = void Function(Pointer<Uint8>, int, int);
+typedef _c_memset = Void Function(Pointer<Uint8>, Int32, IntPtr);
+
+_dart_memset? fbMemset;
+
+void _fallbackMemset(Pointer<Uint8> ptr, int byte, int size) {
+  final bytes = ptr.cast<Uint8>();
+  for (var i = 0; i < size; i++) {
+    bytes[i] = byte;
+  }
+}
+
+void main() {
+  try {
+    fbMemset = DynamicLibrary.process()
+        .lookupFunction<_c_memset, _dart_memset>('memset');
+  } catch (_) {
+    // This works:
+    // fbMemset = _fallbackMemset;
+
+    // This doesn't: /aot/precompiler.cc: 2761: error: unreachable code
+    fbMemset = (Pointer<Uint8> ptr, int byte, int size) {
+      final bytes = ptr.cast<Uint8>();
+      for (var i = 0; i < size; i++) {
+        bytes[i] = byte;
+      }
+    };
+  }
+}
diff --git a/tests/ffi/structs_packed_test.dart b/tests/ffi/structs_packed_test.dart
new file mode 100644
index 0000000..cec7703
--- /dev/null
+++ b/tests/ffi/structs_packed_test.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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
+
+import 'dart:ffi';
+
+import "package:expect/expect.dart";
+
+import 'dylib_utils.dart';
+
+// Reuse struct definitions.
+import 'function_structs_by_value_generated_test.dart';
+
+void main() {
+  testSizeOfC();
+  testSizeOfDart();
+}
+
+final ffiTestFunctions = dlopenPlatformSpecific("ffi_test_functions");
+
+final sizeOfStruct3BytesPackedInt =
+    ffiTestFunctions.lookupFunction<Uint64 Function(), int Function()>(
+        "SizeOfStruct3BytesPackedInt");
+
+void testSizeOfC() {
+  Expect.equals(3, sizeOfStruct3BytesPackedInt());
+}
+
+void testSizeOfDart() {
+  // No packing needed to get to 3 bytes.
+  Expect.equals(3, sizeOf<Struct3BytesHomogeneousUint8>());
+
+  // Contents 3 bytes, but alignment forces it to be 4 bytes.
+  Expect.equals(4, sizeOf<Struct3BytesInt2ByteAligned>());
+
+  // Alignment gets the same content back to 3 bytes.
+  Expect.equals(3, sizeOf<Struct3BytesPackedInt>());
+}
diff --git a/tests/ffi/unaligned_test.dart b/tests/ffi/unaligned_test.dart
new file mode 100644
index 0000000..3220003
--- /dev/null
+++ b/tests/ffi/unaligned_test.dart
@@ -0,0 +1,74 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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 tests exercises misaligned reads/writes on memory.
+//
+// The only architecture on which this is known to fail is arm32 on Android.
+
+import 'dart:ffi';
+import 'dart:io';
+
+import 'package:expect/expect.dart';
+import 'package:ffi/ffi.dart';
+
+void main() {
+  print("hello");
+  testUnalignedInt16(); //# 01: ok
+  testUnalignedInt32(); //# 02: ok
+  testUnalignedInt64(); //# 03: ok
+  if (!Platform.isAndroid || sizeOf<Pointer>() == 8) {
+    // TODO(http://dartbug.com/45009): Support unaligned reads/writes on
+    // Android arm32.
+    testUnalignedFloat(); //# 04: ok
+    testUnalignedDouble(); //# 05: ok
+  }
+  _freeAll();
+}
+
+void testUnalignedInt16() {
+  final pointer = _allocateUnaligned<Int16>();
+  pointer.value = 20;
+  Expect.equals(20, pointer.value);
+}
+
+void testUnalignedInt32() {
+  final pointer = _allocateUnaligned<Int32>();
+  pointer.value = 20;
+  Expect.equals(20, pointer.value);
+}
+
+void testUnalignedInt64() {
+  final pointer = _allocateUnaligned<Int64>();
+  pointer.value = 20;
+  Expect.equals(20, pointer.value);
+}
+
+void testUnalignedFloat() {
+  final pointer = _allocateUnaligned<Float>();
+  pointer.value = 20.0;
+  Expect.approxEquals(20.0, pointer.value);
+}
+
+void testUnalignedDouble() {
+  final pointer = _allocateUnaligned<Double>();
+  pointer.value = 20.0;
+  Expect.equals(20.0, pointer.value);
+}
+
+final Set<Pointer> _pool = {};
+
+void _freeAll() {
+  for (final pointer in _pool) {
+    calloc.free(pointer);
+  }
+}
+
+/// Up to `size<T>() == 8`.
+Pointer<T> _allocateUnaligned<T extends NativeType>() {
+  final pointer = calloc<Int8>(16);
+  _pool.add(pointer);
+  final misaligned = pointer.elementAt(1).cast<T>();
+  Expect.equals(1, misaligned.address % 2);
+  return misaligned;
+}
diff --git a/tests/ffi/vmspecific_static_checks_test.dart b/tests/ffi/vmspecific_static_checks_test.dart
index 3ec5ac0..72636d8 100644
--- a/tests/ffi/vmspecific_static_checks_test.dart
+++ b/tests/ffi/vmspecific_static_checks_test.dart
@@ -58,6 +58,7 @@
   testRefStruct();
   testSizeOfGeneric();
   testSizeOfNativeType();
+  testSizeOfHandle();
   testElementAtGeneric();
   testElementAtNativeType();
 }
@@ -636,11 +637,11 @@
 }
 
 void testSizeOfNativeType() {
-  try {
-    sizeOf(); //# 1301: compile-time error
-  } catch (e) {
-    print(e);
-  }
+  sizeOf(); //# 1301: compile-time error
+}
+
+void testSizeOfHandle() {
+  sizeOf<Handle>(); //# 1302: compile-time error
 }
 
 void testElementAtGeneric() {
@@ -677,8 +678,85 @@
 }
 
 class TestStruct1402 extends Struct {
-  @Array(8) //# 1402: compile-time error
+  @Array(8, 8, 8) //# 1402: compile-time error
   external Array<Array<Uint8>> a0; //# 1402: compile-time error
 
   external Pointer<Uint8> notEmpty;
 }
+
+class TestStruct1403 extends Struct {
+  @Array(8, 8) //# 1403: compile-time error
+  external Array<Array<Array<Uint8>>> a0; //# 1403: compile-time error
+
+  external Pointer<Uint8> notEmpty;
+}
+
+class TestStruct1404 extends Struct {
+  @Array.multi([8, 8, 8]) //# 1404: compile-time error
+  external Array<Array<Uint8>> a0; //# 1404: compile-time error
+
+  external Pointer<Uint8> notEmpty;
+}
+
+class TestStruct1405 extends Struct {
+  @Array.multi([8, 8]) //# 1405: compile-time error
+  external Array<Array<Array<Uint8>>> a0; //# 1405: compile-time error
+
+  external Pointer<Uint8> notEmpty;
+}
+
+@Packed(1)
+class TestStruct1600 extends Struct {
+  external Pointer<Uint8> notEmpty;
+}
+
+@Packed(1)
+@Packed(1) //# 1601: compile-time error
+class TestStruct1601 extends Struct {
+  external Pointer<Uint8> notEmpty;
+}
+
+@Packed(3) //# 1602: compile-time error
+class TestStruct1602 extends Struct {
+  external Pointer<Uint8> notEmpty;
+}
+
+class TestStruct1603 extends Struct {
+  external Pointer<Uint8> notEmpty;
+}
+
+@Packed(1)
+class TestStruct1603Packed extends Struct {
+  external Pointer<Uint8> notEmpty;
+
+  external TestStruct1603 nestedNotPacked; //# 1603: compile-time error
+}
+
+@Packed(8)
+class TestStruct1604 extends Struct {
+  external Pointer<Uint8> notEmpty;
+}
+
+@Packed(1)
+class TestStruct1604Packed extends Struct {
+  external Pointer<Uint8> notEmpty;
+
+  external TestStruct1604 nestedLooselyPacked; //# 1604: compile-time error
+}
+
+@Packed(1)
+class TestStruct1605Packed extends Struct {
+  external Pointer<Uint8> notEmpty;
+
+  @Array(2) //# 1605: compile-time error
+  external Array<TestStruct1603> nestedNotPacked; //# 1605: compile-time error
+}
+
+@Packed(1)
+class TestStruct1606Packed extends Struct {
+  external Pointer<Uint8> notEmpty;
+
+  @Array(2) //# 1606: compile-time error
+  external Array<TestStruct1604> //# 1606: compile-time error
+      nestedLooselyPacked; //# 1606: compile-time error
+}
diff --git a/tests/ffi_2/function_callbacks_structs_by_value_generated_test.dart b/tests/ffi_2/function_callbacks_structs_by_value_generated_test.dart
index ec212c5..c063d7f 100644
--- a/tests/ffi_2/function_callbacks_structs_by_value_generated_test.dart
+++ b/tests/ffi_2/function_callbacks_structs_by_value_generated_test.dart
@@ -273,6 +273,54 @@
           passStructStruct16BytesMixed3x10, 0.0),
       passStructStruct16BytesMixed3x10AfterCallback),
   CallbackTest.withCheck(
+      "PassUint8Struct32BytesInlineArrayMultiDimensionalI",
+      Pointer.fromFunction<
+              PassUint8Struct32BytesInlineArrayMultiDimensionalIType>(
+          passUint8Struct32BytesInlineArrayMultiDimensionalI, 0),
+      passUint8Struct32BytesInlineArrayMultiDimensionalIAfterCallback),
+  CallbackTest.withCheck(
+      "PassUint8Struct4BytesInlineArrayMultiDimensionalIn",
+      Pointer.fromFunction<
+              PassUint8Struct4BytesInlineArrayMultiDimensionalInType>(
+          passUint8Struct4BytesInlineArrayMultiDimensionalIn, 0),
+      passUint8Struct4BytesInlineArrayMultiDimensionalInAfterCallback),
+  CallbackTest.withCheck(
+      "PassStruct3BytesPackedIntx10",
+      Pointer.fromFunction<PassStruct3BytesPackedIntx10Type>(
+          passStruct3BytesPackedIntx10, 0),
+      passStruct3BytesPackedIntx10AfterCallback),
+  CallbackTest.withCheck(
+      "PassStruct8BytesPackedIntx10",
+      Pointer.fromFunction<PassStruct8BytesPackedIntx10Type>(
+          passStruct8BytesPackedIntx10, 0),
+      passStruct8BytesPackedIntx10AfterCallback),
+  CallbackTest.withCheck(
+      "PassStruct9BytesPackedMixedx10DoubleInt32",
+      Pointer.fromFunction<PassStruct9BytesPackedMixedx10DoubleInt32Type>(
+          passStruct9BytesPackedMixedx10DoubleInt32, 0.0),
+      passStruct9BytesPackedMixedx10DoubleInt32AfterCallback),
+  CallbackTest.withCheck(
+      "PassStruct5BytesPackedMixed",
+      Pointer.fromFunction<PassStruct5BytesPackedMixedType>(
+          passStruct5BytesPackedMixed, 0.0),
+      passStruct5BytesPackedMixedAfterCallback),
+  CallbackTest.withCheck(
+      "PassStructNestedAlignmentStruct5BytesPackedMixed",
+      Pointer.fromFunction<
+              PassStructNestedAlignmentStruct5BytesPackedMixedType>(
+          passStructNestedAlignmentStruct5BytesPackedMixed, 0.0),
+      passStructNestedAlignmentStruct5BytesPackedMixedAfterCallback),
+  CallbackTest.withCheck(
+      "PassStruct6BytesInlineArrayInt",
+      Pointer.fromFunction<PassStruct6BytesInlineArrayIntType>(
+          passStruct6BytesInlineArrayInt, 0.0),
+      passStruct6BytesInlineArrayIntAfterCallback),
+  CallbackTest.withCheck(
+      "PassStruct15BytesInlineArrayMixed",
+      Pointer.fromFunction<PassStruct15BytesInlineArrayMixedType>(
+          passStruct15BytesInlineArrayMixed, 0.0),
+      passStruct15BytesInlineArrayMixedAfterCallback),
+  CallbackTest.withCheck(
       "ReturnStruct1ByteInt",
       Pointer.fromFunction<ReturnStruct1ByteIntType>(returnStruct1ByteInt),
       returnStruct1ByteIntAfterCallback),
@@ -380,6 +428,21 @@
           returnStruct1024BytesHomogeneousUint64),
       returnStruct1024BytesHomogeneousUint64AfterCallback),
   CallbackTest.withCheck(
+      "ReturnStruct3BytesPackedInt",
+      Pointer.fromFunction<ReturnStruct3BytesPackedIntType>(
+          returnStruct3BytesPackedInt),
+      returnStruct3BytesPackedIntAfterCallback),
+  CallbackTest.withCheck(
+      "ReturnStruct8BytesPackedInt",
+      Pointer.fromFunction<ReturnStruct8BytesPackedIntType>(
+          returnStruct8BytesPackedInt),
+      returnStruct8BytesPackedIntAfterCallback),
+  CallbackTest.withCheck(
+      "ReturnStruct9BytesPackedMixed",
+      Pointer.fromFunction<ReturnStruct9BytesPackedMixedType>(
+          returnStruct9BytesPackedMixed),
+      returnStruct9BytesPackedMixedAfterCallback),
+  CallbackTest.withCheck(
       "ReturnStructArgumentStruct1ByteInt",
       Pointer.fromFunction<ReturnStructArgumentStruct1ByteIntType>(
           returnStructArgumentStruct1ByteInt),
@@ -6159,6 +6222,852 @@
   Expect.approxEquals(30.0, result);
 }
 
+typedef PassUint8Struct32BytesInlineArrayMultiDimensionalIType
+    = Uint32 Function(
+        Uint8,
+        Struct32BytesInlineArrayMultiDimensionalInt,
+        Uint8,
+        Struct8BytesInlineArrayMultiDimensionalInt,
+        Uint8,
+        Struct8BytesInlineArrayMultiDimensionalInt,
+        Uint8);
+
+// Global variables to be able to test inputs after callback returned.
+int passUint8Struct32BytesInlineArrayMultiDimensionalI_a0 = 0;
+Struct32BytesInlineArrayMultiDimensionalInt
+    passUint8Struct32BytesInlineArrayMultiDimensionalI_a1 =
+    Struct32BytesInlineArrayMultiDimensionalInt();
+int passUint8Struct32BytesInlineArrayMultiDimensionalI_a2 = 0;
+Struct8BytesInlineArrayMultiDimensionalInt
+    passUint8Struct32BytesInlineArrayMultiDimensionalI_a3 =
+    Struct8BytesInlineArrayMultiDimensionalInt();
+int passUint8Struct32BytesInlineArrayMultiDimensionalI_a4 = 0;
+Struct8BytesInlineArrayMultiDimensionalInt
+    passUint8Struct32BytesInlineArrayMultiDimensionalI_a5 =
+    Struct8BytesInlineArrayMultiDimensionalInt();
+int passUint8Struct32BytesInlineArrayMultiDimensionalI_a6 = 0;
+
+// Result variable also global, so we can delete it after the callback.
+int passUint8Struct32BytesInlineArrayMultiDimensionalIResult = 0;
+
+int passUint8Struct32BytesInlineArrayMultiDimensionalICalculateResult() {
+  int result = 0;
+
+  result += passUint8Struct32BytesInlineArrayMultiDimensionalI_a0;
+  result +=
+      passUint8Struct32BytesInlineArrayMultiDimensionalI_a1.a0[0][0][0][0][0];
+  result +=
+      passUint8Struct32BytesInlineArrayMultiDimensionalI_a1.a0[0][0][0][0][1];
+  result +=
+      passUint8Struct32BytesInlineArrayMultiDimensionalI_a1.a0[0][0][0][1][0];
+  result +=
+      passUint8Struct32BytesInlineArrayMultiDimensionalI_a1.a0[0][0][0][1][1];
+  result +=
+      passUint8Struct32BytesInlineArrayMultiDimensionalI_a1.a0[0][0][1][0][0];
+  result +=
+      passUint8Struct32BytesInlineArrayMultiDimensionalI_a1.a0[0][0][1][0][1];
+  result +=
+      passUint8Struct32BytesInlineArrayMultiDimensionalI_a1.a0[0][0][1][1][0];
+  result +=
+      passUint8Struct32BytesInlineArrayMultiDimensionalI_a1.a0[0][0][1][1][1];
+  result +=
+      passUint8Struct32BytesInlineArrayMultiDimensionalI_a1.a0[0][1][0][0][0];
+  result +=
+      passUint8Struct32BytesInlineArrayMultiDimensionalI_a1.a0[0][1][0][0][1];
+  result +=
+      passUint8Struct32BytesInlineArrayMultiDimensionalI_a1.a0[0][1][0][1][0];
+  result +=
+      passUint8Struct32BytesInlineArrayMultiDimensionalI_a1.a0[0][1][0][1][1];
+  result +=
+      passUint8Struct32BytesInlineArrayMultiDimensionalI_a1.a0[0][1][1][0][0];
+  result +=
+      passUint8Struct32BytesInlineArrayMultiDimensionalI_a1.a0[0][1][1][0][1];
+  result +=
+      passUint8Struct32BytesInlineArrayMultiDimensionalI_a1.a0[0][1][1][1][0];
+  result +=
+      passUint8Struct32BytesInlineArrayMultiDimensionalI_a1.a0[0][1][1][1][1];
+  result +=
+      passUint8Struct32BytesInlineArrayMultiDimensionalI_a1.a0[1][0][0][0][0];
+  result +=
+      passUint8Struct32BytesInlineArrayMultiDimensionalI_a1.a0[1][0][0][0][1];
+  result +=
+      passUint8Struct32BytesInlineArrayMultiDimensionalI_a1.a0[1][0][0][1][0];
+  result +=
+      passUint8Struct32BytesInlineArrayMultiDimensionalI_a1.a0[1][0][0][1][1];
+  result +=
+      passUint8Struct32BytesInlineArrayMultiDimensionalI_a1.a0[1][0][1][0][0];
+  result +=
+      passUint8Struct32BytesInlineArrayMultiDimensionalI_a1.a0[1][0][1][0][1];
+  result +=
+      passUint8Struct32BytesInlineArrayMultiDimensionalI_a1.a0[1][0][1][1][0];
+  result +=
+      passUint8Struct32BytesInlineArrayMultiDimensionalI_a1.a0[1][0][1][1][1];
+  result +=
+      passUint8Struct32BytesInlineArrayMultiDimensionalI_a1.a0[1][1][0][0][0];
+  result +=
+      passUint8Struct32BytesInlineArrayMultiDimensionalI_a1.a0[1][1][0][0][1];
+  result +=
+      passUint8Struct32BytesInlineArrayMultiDimensionalI_a1.a0[1][1][0][1][0];
+  result +=
+      passUint8Struct32BytesInlineArrayMultiDimensionalI_a1.a0[1][1][0][1][1];
+  result +=
+      passUint8Struct32BytesInlineArrayMultiDimensionalI_a1.a0[1][1][1][0][0];
+  result +=
+      passUint8Struct32BytesInlineArrayMultiDimensionalI_a1.a0[1][1][1][0][1];
+  result +=
+      passUint8Struct32BytesInlineArrayMultiDimensionalI_a1.a0[1][1][1][1][0];
+  result +=
+      passUint8Struct32BytesInlineArrayMultiDimensionalI_a1.a0[1][1][1][1][1];
+  result += passUint8Struct32BytesInlineArrayMultiDimensionalI_a2;
+  result += passUint8Struct32BytesInlineArrayMultiDimensionalI_a3.a0[0][0][0];
+  result += passUint8Struct32BytesInlineArrayMultiDimensionalI_a3.a0[0][0][1];
+  result += passUint8Struct32BytesInlineArrayMultiDimensionalI_a3.a0[0][1][0];
+  result += passUint8Struct32BytesInlineArrayMultiDimensionalI_a3.a0[0][1][1];
+  result += passUint8Struct32BytesInlineArrayMultiDimensionalI_a3.a0[1][0][0];
+  result += passUint8Struct32BytesInlineArrayMultiDimensionalI_a3.a0[1][0][1];
+  result += passUint8Struct32BytesInlineArrayMultiDimensionalI_a3.a0[1][1][0];
+  result += passUint8Struct32BytesInlineArrayMultiDimensionalI_a3.a0[1][1][1];
+  result += passUint8Struct32BytesInlineArrayMultiDimensionalI_a4;
+  result += passUint8Struct32BytesInlineArrayMultiDimensionalI_a5.a0[0][0][0];
+  result += passUint8Struct32BytesInlineArrayMultiDimensionalI_a5.a0[0][0][1];
+  result += passUint8Struct32BytesInlineArrayMultiDimensionalI_a5.a0[0][1][0];
+  result += passUint8Struct32BytesInlineArrayMultiDimensionalI_a5.a0[0][1][1];
+  result += passUint8Struct32BytesInlineArrayMultiDimensionalI_a5.a0[1][0][0];
+  result += passUint8Struct32BytesInlineArrayMultiDimensionalI_a5.a0[1][0][1];
+  result += passUint8Struct32BytesInlineArrayMultiDimensionalI_a5.a0[1][1][0];
+  result += passUint8Struct32BytesInlineArrayMultiDimensionalI_a5.a0[1][1][1];
+  result += passUint8Struct32BytesInlineArrayMultiDimensionalI_a6;
+
+  passUint8Struct32BytesInlineArrayMultiDimensionalIResult = result;
+
+  return result;
+}
+
+/// Test multi dimensional inline array struct as argument.
+int passUint8Struct32BytesInlineArrayMultiDimensionalI(
+    int a0,
+    Struct32BytesInlineArrayMultiDimensionalInt a1,
+    int a2,
+    Struct8BytesInlineArrayMultiDimensionalInt a3,
+    int a4,
+    Struct8BytesInlineArrayMultiDimensionalInt a5,
+    int a6) {
+  print(
+      "passUint8Struct32BytesInlineArrayMultiDimensionalI(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6})");
+
+  // In legacy mode, possibly return null.
+  if (a0 == 84) {
+    print("returning null!");
+    return null;
+  }
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0 == 42 || a0 == 84) {
+    print("throwing!");
+    throw Exception(
+        "PassUint8Struct32BytesInlineArrayMultiDimensionalI throwing on purpose!");
+  }
+
+  passUint8Struct32BytesInlineArrayMultiDimensionalI_a0 = a0;
+  passUint8Struct32BytesInlineArrayMultiDimensionalI_a1 = a1;
+  passUint8Struct32BytesInlineArrayMultiDimensionalI_a2 = a2;
+  passUint8Struct32BytesInlineArrayMultiDimensionalI_a3 = a3;
+  passUint8Struct32BytesInlineArrayMultiDimensionalI_a4 = a4;
+  passUint8Struct32BytesInlineArrayMultiDimensionalI_a5 = a5;
+  passUint8Struct32BytesInlineArrayMultiDimensionalI_a6 = a6;
+
+  final result =
+      passUint8Struct32BytesInlineArrayMultiDimensionalICalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passUint8Struct32BytesInlineArrayMultiDimensionalIAfterCallback() {
+  final result =
+      passUint8Struct32BytesInlineArrayMultiDimensionalICalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.equals(1378, result);
+}
+
+typedef PassUint8Struct4BytesInlineArrayMultiDimensionalInType = Uint32
+    Function(Uint8, Struct4BytesInlineArrayMultiDimensionalInt, Uint8);
+
+// Global variables to be able to test inputs after callback returned.
+int passUint8Struct4BytesInlineArrayMultiDimensionalIn_a0 = 0;
+Struct4BytesInlineArrayMultiDimensionalInt
+    passUint8Struct4BytesInlineArrayMultiDimensionalIn_a1 =
+    Struct4BytesInlineArrayMultiDimensionalInt();
+int passUint8Struct4BytesInlineArrayMultiDimensionalIn_a2 = 0;
+
+// Result variable also global, so we can delete it after the callback.
+int passUint8Struct4BytesInlineArrayMultiDimensionalInResult = 0;
+
+int passUint8Struct4BytesInlineArrayMultiDimensionalInCalculateResult() {
+  int result = 0;
+
+  result += passUint8Struct4BytesInlineArrayMultiDimensionalIn_a0;
+  result += passUint8Struct4BytesInlineArrayMultiDimensionalIn_a1.a0[0][0].a0;
+  result += passUint8Struct4BytesInlineArrayMultiDimensionalIn_a1.a0[0][1].a0;
+  result += passUint8Struct4BytesInlineArrayMultiDimensionalIn_a1.a0[1][0].a0;
+  result += passUint8Struct4BytesInlineArrayMultiDimensionalIn_a1.a0[1][1].a0;
+  result += passUint8Struct4BytesInlineArrayMultiDimensionalIn_a2;
+
+  passUint8Struct4BytesInlineArrayMultiDimensionalInResult = result;
+
+  return result;
+}
+
+/// Test struct in multi dimensional inline array.
+int passUint8Struct4BytesInlineArrayMultiDimensionalIn(
+    int a0, Struct4BytesInlineArrayMultiDimensionalInt a1, int a2) {
+  print(
+      "passUint8Struct4BytesInlineArrayMultiDimensionalIn(${a0}, ${a1}, ${a2})");
+
+  // In legacy mode, possibly return null.
+  if (a0 == 84) {
+    print("returning null!");
+    return null;
+  }
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0 == 42 || a0 == 84) {
+    print("throwing!");
+    throw Exception(
+        "PassUint8Struct4BytesInlineArrayMultiDimensionalIn throwing on purpose!");
+  }
+
+  passUint8Struct4BytesInlineArrayMultiDimensionalIn_a0 = a0;
+  passUint8Struct4BytesInlineArrayMultiDimensionalIn_a1 = a1;
+  passUint8Struct4BytesInlineArrayMultiDimensionalIn_a2 = a2;
+
+  final result =
+      passUint8Struct4BytesInlineArrayMultiDimensionalInCalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passUint8Struct4BytesInlineArrayMultiDimensionalInAfterCallback() {
+  final result =
+      passUint8Struct4BytesInlineArrayMultiDimensionalInCalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.equals(5, result);
+}
+
+typedef PassStruct3BytesPackedIntx10Type = Int64 Function(
+    Struct3BytesPackedInt,
+    Struct3BytesPackedInt,
+    Struct3BytesPackedInt,
+    Struct3BytesPackedInt,
+    Struct3BytesPackedInt,
+    Struct3BytesPackedInt,
+    Struct3BytesPackedInt,
+    Struct3BytesPackedInt,
+    Struct3BytesPackedInt,
+    Struct3BytesPackedInt);
+
+// Global variables to be able to test inputs after callback returned.
+Struct3BytesPackedInt passStruct3BytesPackedIntx10_a0 = Struct3BytesPackedInt();
+Struct3BytesPackedInt passStruct3BytesPackedIntx10_a1 = Struct3BytesPackedInt();
+Struct3BytesPackedInt passStruct3BytesPackedIntx10_a2 = Struct3BytesPackedInt();
+Struct3BytesPackedInt passStruct3BytesPackedIntx10_a3 = Struct3BytesPackedInt();
+Struct3BytesPackedInt passStruct3BytesPackedIntx10_a4 = Struct3BytesPackedInt();
+Struct3BytesPackedInt passStruct3BytesPackedIntx10_a5 = Struct3BytesPackedInt();
+Struct3BytesPackedInt passStruct3BytesPackedIntx10_a6 = Struct3BytesPackedInt();
+Struct3BytesPackedInt passStruct3BytesPackedIntx10_a7 = Struct3BytesPackedInt();
+Struct3BytesPackedInt passStruct3BytesPackedIntx10_a8 = Struct3BytesPackedInt();
+Struct3BytesPackedInt passStruct3BytesPackedIntx10_a9 = Struct3BytesPackedInt();
+
+// Result variable also global, so we can delete it after the callback.
+int passStruct3BytesPackedIntx10Result = 0;
+
+int passStruct3BytesPackedIntx10CalculateResult() {
+  int result = 0;
+
+  result += passStruct3BytesPackedIntx10_a0.a0;
+  result += passStruct3BytesPackedIntx10_a0.a1;
+  result += passStruct3BytesPackedIntx10_a1.a0;
+  result += passStruct3BytesPackedIntx10_a1.a1;
+  result += passStruct3BytesPackedIntx10_a2.a0;
+  result += passStruct3BytesPackedIntx10_a2.a1;
+  result += passStruct3BytesPackedIntx10_a3.a0;
+  result += passStruct3BytesPackedIntx10_a3.a1;
+  result += passStruct3BytesPackedIntx10_a4.a0;
+  result += passStruct3BytesPackedIntx10_a4.a1;
+  result += passStruct3BytesPackedIntx10_a5.a0;
+  result += passStruct3BytesPackedIntx10_a5.a1;
+  result += passStruct3BytesPackedIntx10_a6.a0;
+  result += passStruct3BytesPackedIntx10_a6.a1;
+  result += passStruct3BytesPackedIntx10_a7.a0;
+  result += passStruct3BytesPackedIntx10_a7.a1;
+  result += passStruct3BytesPackedIntx10_a8.a0;
+  result += passStruct3BytesPackedIntx10_a8.a1;
+  result += passStruct3BytesPackedIntx10_a9.a0;
+  result += passStruct3BytesPackedIntx10_a9.a1;
+
+  passStruct3BytesPackedIntx10Result = result;
+
+  return result;
+}
+
+/// Small struct with mis-aligned member.
+int passStruct3BytesPackedIntx10(
+    Struct3BytesPackedInt a0,
+    Struct3BytesPackedInt a1,
+    Struct3BytesPackedInt a2,
+    Struct3BytesPackedInt a3,
+    Struct3BytesPackedInt a4,
+    Struct3BytesPackedInt a5,
+    Struct3BytesPackedInt a6,
+    Struct3BytesPackedInt a7,
+    Struct3BytesPackedInt a8,
+    Struct3BytesPackedInt a9) {
+  print(
+      "passStruct3BytesPackedIntx10(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8}, ${a9})");
+
+  // In legacy mode, possibly return null.
+  if (a0.a0 == 84) {
+    print("returning null!");
+    return null;
+  }
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0.a0 == 42 || a0.a0 == 84) {
+    print("throwing!");
+    throw Exception("PassStruct3BytesPackedIntx10 throwing on purpose!");
+  }
+
+  passStruct3BytesPackedIntx10_a0 = a0;
+  passStruct3BytesPackedIntx10_a1 = a1;
+  passStruct3BytesPackedIntx10_a2 = a2;
+  passStruct3BytesPackedIntx10_a3 = a3;
+  passStruct3BytesPackedIntx10_a4 = a4;
+  passStruct3BytesPackedIntx10_a5 = a5;
+  passStruct3BytesPackedIntx10_a6 = a6;
+  passStruct3BytesPackedIntx10_a7 = a7;
+  passStruct3BytesPackedIntx10_a8 = a8;
+  passStruct3BytesPackedIntx10_a9 = a9;
+
+  final result = passStruct3BytesPackedIntx10CalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passStruct3BytesPackedIntx10AfterCallback() {
+  final result = passStruct3BytesPackedIntx10CalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.equals(10, result);
+}
+
+typedef PassStruct8BytesPackedIntx10Type = Int64 Function(
+    Struct8BytesPackedInt,
+    Struct8BytesPackedInt,
+    Struct8BytesPackedInt,
+    Struct8BytesPackedInt,
+    Struct8BytesPackedInt,
+    Struct8BytesPackedInt,
+    Struct8BytesPackedInt,
+    Struct8BytesPackedInt,
+    Struct8BytesPackedInt,
+    Struct8BytesPackedInt);
+
+// Global variables to be able to test inputs after callback returned.
+Struct8BytesPackedInt passStruct8BytesPackedIntx10_a0 = Struct8BytesPackedInt();
+Struct8BytesPackedInt passStruct8BytesPackedIntx10_a1 = Struct8BytesPackedInt();
+Struct8BytesPackedInt passStruct8BytesPackedIntx10_a2 = Struct8BytesPackedInt();
+Struct8BytesPackedInt passStruct8BytesPackedIntx10_a3 = Struct8BytesPackedInt();
+Struct8BytesPackedInt passStruct8BytesPackedIntx10_a4 = Struct8BytesPackedInt();
+Struct8BytesPackedInt passStruct8BytesPackedIntx10_a5 = Struct8BytesPackedInt();
+Struct8BytesPackedInt passStruct8BytesPackedIntx10_a6 = Struct8BytesPackedInt();
+Struct8BytesPackedInt passStruct8BytesPackedIntx10_a7 = Struct8BytesPackedInt();
+Struct8BytesPackedInt passStruct8BytesPackedIntx10_a8 = Struct8BytesPackedInt();
+Struct8BytesPackedInt passStruct8BytesPackedIntx10_a9 = Struct8BytesPackedInt();
+
+// Result variable also global, so we can delete it after the callback.
+int passStruct8BytesPackedIntx10Result = 0;
+
+int passStruct8BytesPackedIntx10CalculateResult() {
+  int result = 0;
+
+  result += passStruct8BytesPackedIntx10_a0.a0;
+  result += passStruct8BytesPackedIntx10_a0.a1;
+  result += passStruct8BytesPackedIntx10_a0.a2;
+  result += passStruct8BytesPackedIntx10_a0.a3;
+  result += passStruct8BytesPackedIntx10_a0.a4;
+  result += passStruct8BytesPackedIntx10_a1.a0;
+  result += passStruct8BytesPackedIntx10_a1.a1;
+  result += passStruct8BytesPackedIntx10_a1.a2;
+  result += passStruct8BytesPackedIntx10_a1.a3;
+  result += passStruct8BytesPackedIntx10_a1.a4;
+  result += passStruct8BytesPackedIntx10_a2.a0;
+  result += passStruct8BytesPackedIntx10_a2.a1;
+  result += passStruct8BytesPackedIntx10_a2.a2;
+  result += passStruct8BytesPackedIntx10_a2.a3;
+  result += passStruct8BytesPackedIntx10_a2.a4;
+  result += passStruct8BytesPackedIntx10_a3.a0;
+  result += passStruct8BytesPackedIntx10_a3.a1;
+  result += passStruct8BytesPackedIntx10_a3.a2;
+  result += passStruct8BytesPackedIntx10_a3.a3;
+  result += passStruct8BytesPackedIntx10_a3.a4;
+  result += passStruct8BytesPackedIntx10_a4.a0;
+  result += passStruct8BytesPackedIntx10_a4.a1;
+  result += passStruct8BytesPackedIntx10_a4.a2;
+  result += passStruct8BytesPackedIntx10_a4.a3;
+  result += passStruct8BytesPackedIntx10_a4.a4;
+  result += passStruct8BytesPackedIntx10_a5.a0;
+  result += passStruct8BytesPackedIntx10_a5.a1;
+  result += passStruct8BytesPackedIntx10_a5.a2;
+  result += passStruct8BytesPackedIntx10_a5.a3;
+  result += passStruct8BytesPackedIntx10_a5.a4;
+  result += passStruct8BytesPackedIntx10_a6.a0;
+  result += passStruct8BytesPackedIntx10_a6.a1;
+  result += passStruct8BytesPackedIntx10_a6.a2;
+  result += passStruct8BytesPackedIntx10_a6.a3;
+  result += passStruct8BytesPackedIntx10_a6.a4;
+  result += passStruct8BytesPackedIntx10_a7.a0;
+  result += passStruct8BytesPackedIntx10_a7.a1;
+  result += passStruct8BytesPackedIntx10_a7.a2;
+  result += passStruct8BytesPackedIntx10_a7.a3;
+  result += passStruct8BytesPackedIntx10_a7.a4;
+  result += passStruct8BytesPackedIntx10_a8.a0;
+  result += passStruct8BytesPackedIntx10_a8.a1;
+  result += passStruct8BytesPackedIntx10_a8.a2;
+  result += passStruct8BytesPackedIntx10_a8.a3;
+  result += passStruct8BytesPackedIntx10_a8.a4;
+  result += passStruct8BytesPackedIntx10_a9.a0;
+  result += passStruct8BytesPackedIntx10_a9.a1;
+  result += passStruct8BytesPackedIntx10_a9.a2;
+  result += passStruct8BytesPackedIntx10_a9.a3;
+  result += passStruct8BytesPackedIntx10_a9.a4;
+
+  passStruct8BytesPackedIntx10Result = result;
+
+  return result;
+}
+
+/// Struct with mis-aligned member.
+int passStruct8BytesPackedIntx10(
+    Struct8BytesPackedInt a0,
+    Struct8BytesPackedInt a1,
+    Struct8BytesPackedInt a2,
+    Struct8BytesPackedInt a3,
+    Struct8BytesPackedInt a4,
+    Struct8BytesPackedInt a5,
+    Struct8BytesPackedInt a6,
+    Struct8BytesPackedInt a7,
+    Struct8BytesPackedInt a8,
+    Struct8BytesPackedInt a9) {
+  print(
+      "passStruct8BytesPackedIntx10(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8}, ${a9})");
+
+  // In legacy mode, possibly return null.
+  if (a0.a0 == 84) {
+    print("returning null!");
+    return null;
+  }
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0.a0 == 42 || a0.a0 == 84) {
+    print("throwing!");
+    throw Exception("PassStruct8BytesPackedIntx10 throwing on purpose!");
+  }
+
+  passStruct8BytesPackedIntx10_a0 = a0;
+  passStruct8BytesPackedIntx10_a1 = a1;
+  passStruct8BytesPackedIntx10_a2 = a2;
+  passStruct8BytesPackedIntx10_a3 = a3;
+  passStruct8BytesPackedIntx10_a4 = a4;
+  passStruct8BytesPackedIntx10_a5 = a5;
+  passStruct8BytesPackedIntx10_a6 = a6;
+  passStruct8BytesPackedIntx10_a7 = a7;
+  passStruct8BytesPackedIntx10_a8 = a8;
+  passStruct8BytesPackedIntx10_a9 = a9;
+
+  final result = passStruct8BytesPackedIntx10CalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passStruct8BytesPackedIntx10AfterCallback() {
+  final result = passStruct8BytesPackedIntx10CalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.equals(1275, result);
+}
+
+typedef PassStruct9BytesPackedMixedx10DoubleInt32Type = Double Function(
+    Struct9BytesPackedMixed,
+    Struct9BytesPackedMixed,
+    Struct9BytesPackedMixed,
+    Struct9BytesPackedMixed,
+    Struct9BytesPackedMixed,
+    Struct9BytesPackedMixed,
+    Struct9BytesPackedMixed,
+    Struct9BytesPackedMixed,
+    Struct9BytesPackedMixed,
+    Struct9BytesPackedMixed,
+    Double,
+    Int32);
+
+// Global variables to be able to test inputs after callback returned.
+Struct9BytesPackedMixed passStruct9BytesPackedMixedx10DoubleInt32_a0 =
+    Struct9BytesPackedMixed();
+Struct9BytesPackedMixed passStruct9BytesPackedMixedx10DoubleInt32_a1 =
+    Struct9BytesPackedMixed();
+Struct9BytesPackedMixed passStruct9BytesPackedMixedx10DoubleInt32_a2 =
+    Struct9BytesPackedMixed();
+Struct9BytesPackedMixed passStruct9BytesPackedMixedx10DoubleInt32_a3 =
+    Struct9BytesPackedMixed();
+Struct9BytesPackedMixed passStruct9BytesPackedMixedx10DoubleInt32_a4 =
+    Struct9BytesPackedMixed();
+Struct9BytesPackedMixed passStruct9BytesPackedMixedx10DoubleInt32_a5 =
+    Struct9BytesPackedMixed();
+Struct9BytesPackedMixed passStruct9BytesPackedMixedx10DoubleInt32_a6 =
+    Struct9BytesPackedMixed();
+Struct9BytesPackedMixed passStruct9BytesPackedMixedx10DoubleInt32_a7 =
+    Struct9BytesPackedMixed();
+Struct9BytesPackedMixed passStruct9BytesPackedMixedx10DoubleInt32_a8 =
+    Struct9BytesPackedMixed();
+Struct9BytesPackedMixed passStruct9BytesPackedMixedx10DoubleInt32_a9 =
+    Struct9BytesPackedMixed();
+double passStruct9BytesPackedMixedx10DoubleInt32_a10 = 0.0;
+int passStruct9BytesPackedMixedx10DoubleInt32_a11 = 0;
+
+// Result variable also global, so we can delete it after the callback.
+double passStruct9BytesPackedMixedx10DoubleInt32Result = 0.0;
+
+double passStruct9BytesPackedMixedx10DoubleInt32CalculateResult() {
+  double result = 0;
+
+  result += passStruct9BytesPackedMixedx10DoubleInt32_a0.a0;
+  result += passStruct9BytesPackedMixedx10DoubleInt32_a0.a1;
+  result += passStruct9BytesPackedMixedx10DoubleInt32_a1.a0;
+  result += passStruct9BytesPackedMixedx10DoubleInt32_a1.a1;
+  result += passStruct9BytesPackedMixedx10DoubleInt32_a2.a0;
+  result += passStruct9BytesPackedMixedx10DoubleInt32_a2.a1;
+  result += passStruct9BytesPackedMixedx10DoubleInt32_a3.a0;
+  result += passStruct9BytesPackedMixedx10DoubleInt32_a3.a1;
+  result += passStruct9BytesPackedMixedx10DoubleInt32_a4.a0;
+  result += passStruct9BytesPackedMixedx10DoubleInt32_a4.a1;
+  result += passStruct9BytesPackedMixedx10DoubleInt32_a5.a0;
+  result += passStruct9BytesPackedMixedx10DoubleInt32_a5.a1;
+  result += passStruct9BytesPackedMixedx10DoubleInt32_a6.a0;
+  result += passStruct9BytesPackedMixedx10DoubleInt32_a6.a1;
+  result += passStruct9BytesPackedMixedx10DoubleInt32_a7.a0;
+  result += passStruct9BytesPackedMixedx10DoubleInt32_a7.a1;
+  result += passStruct9BytesPackedMixedx10DoubleInt32_a8.a0;
+  result += passStruct9BytesPackedMixedx10DoubleInt32_a8.a1;
+  result += passStruct9BytesPackedMixedx10DoubleInt32_a9.a0;
+  result += passStruct9BytesPackedMixedx10DoubleInt32_a9.a1;
+  result += passStruct9BytesPackedMixedx10DoubleInt32_a10;
+  result += passStruct9BytesPackedMixedx10DoubleInt32_a11;
+
+  passStruct9BytesPackedMixedx10DoubleInt32Result = result;
+
+  return result;
+}
+
+/// Struct with mis-aligned member.
+/// Tests backfilling of CPU and FPU registers.
+double passStruct9BytesPackedMixedx10DoubleInt32(
+    Struct9BytesPackedMixed a0,
+    Struct9BytesPackedMixed a1,
+    Struct9BytesPackedMixed a2,
+    Struct9BytesPackedMixed a3,
+    Struct9BytesPackedMixed a4,
+    Struct9BytesPackedMixed a5,
+    Struct9BytesPackedMixed a6,
+    Struct9BytesPackedMixed a7,
+    Struct9BytesPackedMixed a8,
+    Struct9BytesPackedMixed a9,
+    double a10,
+    int a11) {
+  print(
+      "passStruct9BytesPackedMixedx10DoubleInt32(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8}, ${a9}, ${a10}, ${a11})");
+
+  // In legacy mode, possibly return null.
+  if (a0.a0 == 84) {
+    print("returning null!");
+    return null;
+  }
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0.a0 == 42 || a0.a0 == 84) {
+    print("throwing!");
+    throw Exception(
+        "PassStruct9BytesPackedMixedx10DoubleInt32 throwing on purpose!");
+  }
+
+  passStruct9BytesPackedMixedx10DoubleInt32_a0 = a0;
+  passStruct9BytesPackedMixedx10DoubleInt32_a1 = a1;
+  passStruct9BytesPackedMixedx10DoubleInt32_a2 = a2;
+  passStruct9BytesPackedMixedx10DoubleInt32_a3 = a3;
+  passStruct9BytesPackedMixedx10DoubleInt32_a4 = a4;
+  passStruct9BytesPackedMixedx10DoubleInt32_a5 = a5;
+  passStruct9BytesPackedMixedx10DoubleInt32_a6 = a6;
+  passStruct9BytesPackedMixedx10DoubleInt32_a7 = a7;
+  passStruct9BytesPackedMixedx10DoubleInt32_a8 = a8;
+  passStruct9BytesPackedMixedx10DoubleInt32_a9 = a9;
+  passStruct9BytesPackedMixedx10DoubleInt32_a10 = a10;
+  passStruct9BytesPackedMixedx10DoubleInt32_a11 = a11;
+
+  final result = passStruct9BytesPackedMixedx10DoubleInt32CalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passStruct9BytesPackedMixedx10DoubleInt32AfterCallback() {
+  final result = passStruct9BytesPackedMixedx10DoubleInt32CalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.approxEquals(211.0, result);
+}
+
+typedef PassStruct5BytesPackedMixedType = Double Function(
+    Struct5BytesPackedMixed);
+
+// Global variables to be able to test inputs after callback returned.
+Struct5BytesPackedMixed passStruct5BytesPackedMixed_a0 =
+    Struct5BytesPackedMixed();
+
+// Result variable also global, so we can delete it after the callback.
+double passStruct5BytesPackedMixedResult = 0.0;
+
+double passStruct5BytesPackedMixedCalculateResult() {
+  double result = 0;
+
+  result += passStruct5BytesPackedMixed_a0.a0;
+  result += passStruct5BytesPackedMixed_a0.a1;
+
+  passStruct5BytesPackedMixedResult = result;
+
+  return result;
+}
+
+/// This packed struct happens to have only aligned members.
+double passStruct5BytesPackedMixed(Struct5BytesPackedMixed a0) {
+  print("passStruct5BytesPackedMixed(${a0})");
+
+  // In legacy mode, possibly return null.
+  if (a0.a0 == 84) {
+    print("returning null!");
+    return null;
+  }
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0.a0 == 42 || a0.a0 == 84) {
+    print("throwing!");
+    throw Exception("PassStruct5BytesPackedMixed throwing on purpose!");
+  }
+
+  passStruct5BytesPackedMixed_a0 = a0;
+
+  final result = passStruct5BytesPackedMixedCalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passStruct5BytesPackedMixedAfterCallback() {
+  final result = passStruct5BytesPackedMixedCalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.approxEquals(1.0, result);
+}
+
+typedef PassStructNestedAlignmentStruct5BytesPackedMixedType = Double Function(
+    StructNestedAlignmentStruct5BytesPackedMixed);
+
+// Global variables to be able to test inputs after callback returned.
+StructNestedAlignmentStruct5BytesPackedMixed
+    passStructNestedAlignmentStruct5BytesPackedMixed_a0 =
+    StructNestedAlignmentStruct5BytesPackedMixed();
+
+// Result variable also global, so we can delete it after the callback.
+double passStructNestedAlignmentStruct5BytesPackedMixedResult = 0.0;
+
+double passStructNestedAlignmentStruct5BytesPackedMixedCalculateResult() {
+  double result = 0;
+
+  result += passStructNestedAlignmentStruct5BytesPackedMixed_a0.a0;
+  result += passStructNestedAlignmentStruct5BytesPackedMixed_a0.a1.a0;
+  result += passStructNestedAlignmentStruct5BytesPackedMixed_a0.a1.a1;
+
+  passStructNestedAlignmentStruct5BytesPackedMixedResult = result;
+
+  return result;
+}
+
+/// Check alignment of packed struct in non-packed struct.
+double passStructNestedAlignmentStruct5BytesPackedMixed(
+    StructNestedAlignmentStruct5BytesPackedMixed a0) {
+  print("passStructNestedAlignmentStruct5BytesPackedMixed(${a0})");
+
+  // In legacy mode, possibly return null.
+  if (a0.a0 == 84) {
+    print("returning null!");
+    return null;
+  }
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0.a0 == 42 || a0.a0 == 84) {
+    print("throwing!");
+    throw Exception(
+        "PassStructNestedAlignmentStruct5BytesPackedMixed throwing on purpose!");
+  }
+
+  passStructNestedAlignmentStruct5BytesPackedMixed_a0 = a0;
+
+  final result =
+      passStructNestedAlignmentStruct5BytesPackedMixedCalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passStructNestedAlignmentStruct5BytesPackedMixedAfterCallback() {
+  final result =
+      passStructNestedAlignmentStruct5BytesPackedMixedCalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.approxEquals(6.0, result);
+}
+
+typedef PassStruct6BytesInlineArrayIntType = Double Function(
+    Struct6BytesInlineArrayInt);
+
+// Global variables to be able to test inputs after callback returned.
+Struct6BytesInlineArrayInt passStruct6BytesInlineArrayInt_a0 =
+    Struct6BytesInlineArrayInt();
+
+// Result variable also global, so we can delete it after the callback.
+double passStruct6BytesInlineArrayIntResult = 0.0;
+
+double passStruct6BytesInlineArrayIntCalculateResult() {
+  double result = 0;
+
+  result += passStruct6BytesInlineArrayInt_a0.a0[0].a0;
+  result += passStruct6BytesInlineArrayInt_a0.a0[0].a1;
+  result += passStruct6BytesInlineArrayInt_a0.a0[1].a0;
+  result += passStruct6BytesInlineArrayInt_a0.a0[1].a1;
+
+  passStruct6BytesInlineArrayIntResult = result;
+
+  return result;
+}
+
+/// Check alignment of packed struct array in non-packed struct.
+double passStruct6BytesInlineArrayInt(Struct6BytesInlineArrayInt a0) {
+  print("passStruct6BytesInlineArrayInt(${a0})");
+
+  // In legacy mode, possibly return null.
+  if (a0.a0[0].a0 == 84) {
+    print("returning null!");
+    return null;
+  }
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0.a0[0].a0 == 42 || a0.a0[0].a0 == 84) {
+    print("throwing!");
+    throw Exception("PassStruct6BytesInlineArrayInt throwing on purpose!");
+  }
+
+  passStruct6BytesInlineArrayInt_a0 = a0;
+
+  final result = passStruct6BytesInlineArrayIntCalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passStruct6BytesInlineArrayIntAfterCallback() {
+  final result = passStruct6BytesInlineArrayIntCalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.approxEquals(2.0, result);
+}
+
+typedef PassStruct15BytesInlineArrayMixedType = Double Function(
+    Struct15BytesInlineArrayMixed);
+
+// Global variables to be able to test inputs after callback returned.
+Struct15BytesInlineArrayMixed passStruct15BytesInlineArrayMixed_a0 =
+    Struct15BytesInlineArrayMixed();
+
+// Result variable also global, so we can delete it after the callback.
+double passStruct15BytesInlineArrayMixedResult = 0.0;
+
+double passStruct15BytesInlineArrayMixedCalculateResult() {
+  double result = 0;
+
+  result += passStruct15BytesInlineArrayMixed_a0.a0[0].a0;
+  result += passStruct15BytesInlineArrayMixed_a0.a0[0].a1;
+  result += passStruct15BytesInlineArrayMixed_a0.a0[1].a0;
+  result += passStruct15BytesInlineArrayMixed_a0.a0[1].a1;
+  result += passStruct15BytesInlineArrayMixed_a0.a0[2].a0;
+  result += passStruct15BytesInlineArrayMixed_a0.a0[2].a1;
+
+  passStruct15BytesInlineArrayMixedResult = result;
+
+  return result;
+}
+
+/// Check alignment of packed struct array in non-packed struct.
+double passStruct15BytesInlineArrayMixed(Struct15BytesInlineArrayMixed a0) {
+  print("passStruct15BytesInlineArrayMixed(${a0})");
+
+  // In legacy mode, possibly return null.
+  if (a0.a0[0].a0 == 84) {
+    print("returning null!");
+    return null;
+  }
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0.a0[0].a0 == 42 || a0.a0[0].a0 == 84) {
+    print("throwing!");
+    throw Exception("PassStruct15BytesInlineArrayMixed throwing on purpose!");
+  }
+
+  passStruct15BytesInlineArrayMixed_a0 = a0;
+
+  final result = passStruct15BytesInlineArrayMixedCalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passStruct15BytesInlineArrayMixedAfterCallback() {
+  final result = passStruct15BytesInlineArrayMixedCalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.approxEquals(3.0, result);
+}
+
 typedef ReturnStruct1ByteIntType = Struct1ByteInt Function(Int8);
 
 // Global variables to be able to test inputs after callback returned.
@@ -8320,6 +9229,194 @@
   calloc.free(returnStruct1024BytesHomogeneousUint64ResultPointer);
 }
 
+typedef ReturnStruct3BytesPackedIntType = Struct3BytesPackedInt Function(
+    Int8, Int16);
+
+// Global variables to be able to test inputs after callback returned.
+int returnStruct3BytesPackedInt_a0 = 0;
+int returnStruct3BytesPackedInt_a1 = 0;
+
+// Result variable also global, so we can delete it after the callback.
+Pointer<Struct3BytesPackedInt> returnStruct3BytesPackedIntResultPointer =
+    nullptr;
+
+Struct3BytesPackedInt returnStruct3BytesPackedIntCalculateResult() {
+  final resultPointer = calloc<Struct3BytesPackedInt>();
+  final result = resultPointer.ref;
+
+  result.a0 = returnStruct3BytesPackedInt_a0;
+  result.a1 = returnStruct3BytesPackedInt_a1;
+
+  returnStruct3BytesPackedIntResultPointer = resultPointer;
+
+  return result;
+}
+
+/// Small struct with mis-aligned member.
+Struct3BytesPackedInt returnStruct3BytesPackedInt(int a0, int a1) {
+  print("returnStruct3BytesPackedInt(${a0}, ${a1})");
+
+  // In legacy mode, possibly return null.
+  if (a0 == 84) {
+    print("returning null!");
+    return null;
+  }
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0 == 42 || a0 == 84) {
+    print("throwing!");
+    throw Exception("ReturnStruct3BytesPackedInt throwing on purpose!");
+  }
+
+  returnStruct3BytesPackedInt_a0 = a0;
+  returnStruct3BytesPackedInt_a1 = a1;
+
+  final result = returnStruct3BytesPackedIntCalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void returnStruct3BytesPackedIntAfterCallback() {
+  calloc.free(returnStruct3BytesPackedIntResultPointer);
+
+  final result = returnStruct3BytesPackedIntCalculateResult();
+
+  print("after callback result = $result");
+
+  calloc.free(returnStruct3BytesPackedIntResultPointer);
+}
+
+typedef ReturnStruct8BytesPackedIntType = Struct8BytesPackedInt Function(
+    Uint8, Uint32, Uint8, Uint8, Uint8);
+
+// Global variables to be able to test inputs after callback returned.
+int returnStruct8BytesPackedInt_a0 = 0;
+int returnStruct8BytesPackedInt_a1 = 0;
+int returnStruct8BytesPackedInt_a2 = 0;
+int returnStruct8BytesPackedInt_a3 = 0;
+int returnStruct8BytesPackedInt_a4 = 0;
+
+// Result variable also global, so we can delete it after the callback.
+Pointer<Struct8BytesPackedInt> returnStruct8BytesPackedIntResultPointer =
+    nullptr;
+
+Struct8BytesPackedInt returnStruct8BytesPackedIntCalculateResult() {
+  final resultPointer = calloc<Struct8BytesPackedInt>();
+  final result = resultPointer.ref;
+
+  result.a0 = returnStruct8BytesPackedInt_a0;
+  result.a1 = returnStruct8BytesPackedInt_a1;
+  result.a2 = returnStruct8BytesPackedInt_a2;
+  result.a3 = returnStruct8BytesPackedInt_a3;
+  result.a4 = returnStruct8BytesPackedInt_a4;
+
+  returnStruct8BytesPackedIntResultPointer = resultPointer;
+
+  return result;
+}
+
+/// Struct with mis-aligned member.
+Struct8BytesPackedInt returnStruct8BytesPackedInt(
+    int a0, int a1, int a2, int a3, int a4) {
+  print("returnStruct8BytesPackedInt(${a0}, ${a1}, ${a2}, ${a3}, ${a4})");
+
+  // In legacy mode, possibly return null.
+  if (a0 == 84) {
+    print("returning null!");
+    return null;
+  }
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0 == 42 || a0 == 84) {
+    print("throwing!");
+    throw Exception("ReturnStruct8BytesPackedInt throwing on purpose!");
+  }
+
+  returnStruct8BytesPackedInt_a0 = a0;
+  returnStruct8BytesPackedInt_a1 = a1;
+  returnStruct8BytesPackedInt_a2 = a2;
+  returnStruct8BytesPackedInt_a3 = a3;
+  returnStruct8BytesPackedInt_a4 = a4;
+
+  final result = returnStruct8BytesPackedIntCalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void returnStruct8BytesPackedIntAfterCallback() {
+  calloc.free(returnStruct8BytesPackedIntResultPointer);
+
+  final result = returnStruct8BytesPackedIntCalculateResult();
+
+  print("after callback result = $result");
+
+  calloc.free(returnStruct8BytesPackedIntResultPointer);
+}
+
+typedef ReturnStruct9BytesPackedMixedType = Struct9BytesPackedMixed Function(
+    Uint8, Double);
+
+// Global variables to be able to test inputs after callback returned.
+int returnStruct9BytesPackedMixed_a0 = 0;
+double returnStruct9BytesPackedMixed_a1 = 0.0;
+
+// Result variable also global, so we can delete it after the callback.
+Pointer<Struct9BytesPackedMixed> returnStruct9BytesPackedMixedResultPointer =
+    nullptr;
+
+Struct9BytesPackedMixed returnStruct9BytesPackedMixedCalculateResult() {
+  final resultPointer = calloc<Struct9BytesPackedMixed>();
+  final result = resultPointer.ref;
+
+  result.a0 = returnStruct9BytesPackedMixed_a0;
+  result.a1 = returnStruct9BytesPackedMixed_a1;
+
+  returnStruct9BytesPackedMixedResultPointer = resultPointer;
+
+  return result;
+}
+
+/// Struct with mis-aligned member.
+/// Tests backfilling of CPU and FPU registers.
+Struct9BytesPackedMixed returnStruct9BytesPackedMixed(int a0, double a1) {
+  print("returnStruct9BytesPackedMixed(${a0}, ${a1})");
+
+  // In legacy mode, possibly return null.
+  if (a0 == 84) {
+    print("returning null!");
+    return null;
+  }
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0 == 42 || a0 == 84) {
+    print("throwing!");
+    throw Exception("ReturnStruct9BytesPackedMixed throwing on purpose!");
+  }
+
+  returnStruct9BytesPackedMixed_a0 = a0;
+  returnStruct9BytesPackedMixed_a1 = a1;
+
+  final result = returnStruct9BytesPackedMixedCalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void returnStruct9BytesPackedMixedAfterCallback() {
+  calloc.free(returnStruct9BytesPackedMixedResultPointer);
+
+  final result = returnStruct9BytesPackedMixedCalculateResult();
+
+  print("after callback result = $result");
+
+  calloc.free(returnStruct9BytesPackedMixedResultPointer);
+}
+
 typedef ReturnStructArgumentStruct1ByteIntType = Struct1ByteInt Function(
     Struct1ByteInt);
 
diff --git a/tests/ffi_2/function_callbacks_test.dart b/tests/ffi_2/function_callbacks_test.dart
index 2b12a98..e9a853c 100644
--- a/tests/ffi_2/function_callbacks_test.dart
+++ b/tests/ffi_2/function_callbacks_test.dart
@@ -13,6 +13,7 @@
 // VMOptions=--use-slow-path --enable-testing-pragmas --write-protect-code --no-dual-map-code
 // VMOptions=--use-slow-path --enable-testing-pragmas --write-protect-code --no-dual-map-code --stacktrace-every=100
 // VMOptions=--use-bare-instructions=false
+// VMOptions=--enable-testing-pragmas --dwarf_stack_traces --no-retain_function_objects --no-retain_code_objects
 // SharedObjects=ffi_test_functions
 
 import 'dart:ffi';
@@ -25,6 +26,13 @@
   return x + y;
 }
 
+class Foo {
+  static int simpleAddition(int x, int y) {
+    print("Foo.simpleAddition($x, $y)");
+    return x + y;
+  }
+}
+
 typedef IntComputationType = Int64 Function(Int8, Int16, Int32, Int64);
 int intComputation(int a, int b, int c, int d) {
   print("intComputation($a, $b, $c, $d)");
@@ -190,6 +198,8 @@
 final testcases = [
   CallbackTest("SimpleAddition",
       Pointer.fromFunction<SimpleAdditionType>(simpleAddition, 0)),
+  CallbackTest("SimpleAddition",
+      Pointer.fromFunction<SimpleAdditionType>(Foo.simpleAddition, 0)),
   CallbackTest("IntComputation",
       Pointer.fromFunction<IntComputationType>(intComputation, 0)),
   CallbackTest("UintComputation",
diff --git a/tests/ffi_2/function_structs_by_value_generated_test.dart b/tests/ffi_2/function_structs_by_value_generated_test.dart
index a3f7561..48c7b59 100644
--- a/tests/ffi_2/function_structs_by_value_generated_test.dart
+++ b/tests/ffi_2/function_structs_by_value_generated_test.dart
@@ -68,6 +68,15 @@
     testPassStructStruct16BytesHomogeneousFloat2x5();
     testPassStructStruct32BytesHomogeneousDouble2x5();
     testPassStructStruct16BytesMixed3x10();
+    testPassUint8Struct32BytesInlineArrayMultiDimensionalI();
+    testPassUint8Struct4BytesInlineArrayMultiDimensionalIn();
+    testPassStruct3BytesPackedIntx10();
+    testPassStruct8BytesPackedIntx10();
+    testPassStruct9BytesPackedMixedx10DoubleInt32();
+    testPassStruct5BytesPackedMixed();
+    testPassStructNestedAlignmentStruct5BytesPackedMixed();
+    testPassStruct6BytesInlineArrayInt();
+    testPassStruct15BytesInlineArrayMixed();
     testReturnStruct1ByteInt();
     testReturnStruct3BytesHomogeneousUint8();
     testReturnStruct3BytesInt2ByteAligned();
@@ -90,6 +99,9 @@
     testReturnStruct32BytesHomogeneousDouble();
     testReturnStruct40BytesHomogeneousDouble();
     testReturnStruct1024BytesHomogeneousUint64();
+    testReturnStruct3BytesPackedInt();
+    testReturnStruct8BytesPackedInt();
+    testReturnStruct9BytesPackedMixed();
     testReturnStructArgumentStruct1ByteInt();
     testReturnStructArgumentInt32x8Struct1ByteInt();
     testReturnStructArgumentStruct8BytesHomogeneousFloat();
@@ -1043,7 +1055,7 @@
   @Array(8)
   Array<Uint8> a0;
 
-  String toString() => "(${[for (var i = 0; i < 8; i += 1) a0[i]]})";
+  String toString() => "(${[for (var i0 = 0; i0 < 8; i0 += 1) a0[i0]]})";
 }
 
 class StructInlineArrayIrregular extends Struct {
@@ -1053,14 +1065,14 @@
   @Uint8()
   int a1;
 
-  String toString() => "(${[for (var i = 0; i < 2; i += 1) a0[i]]}, ${a1})";
+  String toString() => "(${[for (var i0 = 0; i0 < 2; i0 += 1) a0[i0]]}, ${a1})";
 }
 
 class StructInlineArray100Bytes extends Struct {
   @Array(100)
   Array<Uint8> a0;
 
-  String toString() => "(${[for (var i = 0; i < 100; i += 1) a0[i]]})";
+  String toString() => "(${[for (var i0 = 0; i0 < 100; i0 += 1) a0[i0]]})";
 }
 
 class StructInlineArrayBig extends Struct {
@@ -1074,7 +1086,7 @@
   Array<Uint8> a2;
 
   String toString() =>
-      "(${a0}, ${a1}, ${[for (var i = 0; i < 4000; i += 1) a2[i]]})";
+      "(${a0}, ${a1}, ${[for (var i0 = 0; i0 < 4000; i0 += 1) a2[i0]]})";
 }
 
 class StructStruct16BytesHomogeneousFloat2 extends Struct {
@@ -1087,7 +1099,7 @@
   double a2;
 
   String toString() =>
-      "(${a0}, ${[for (var i = 0; i < 2; i += 1) a1[i]]}, ${a2})";
+      "(${a0}, ${[for (var i0 = 0; i0 < 2; i0 += 1) a1[i0]]}, ${a2})";
 }
 
 class StructStruct32BytesHomogeneousDouble2 extends Struct {
@@ -1100,7 +1112,7 @@
   double a2;
 
   String toString() =>
-      "(${a0}, ${[for (var i = 0; i < 2; i += 1) a1[i]]}, ${a2})";
+      "(${a0}, ${[for (var i0 = 0; i0 < 2; i0 += 1) a1[i0]]}, ${a2})";
 }
 
 class StructStruct16BytesMixed3 extends Struct {
@@ -1112,11 +1124,165 @@
   @Array(2)
   Array<Int16> a2;
 
-  String toString() => "(${a0}, ${[for (var i = 0; i < 1; i += 1) a1[i]]}, ${[
-        for (var i = 0; i < 2; i += 1) a2[i]
+  String toString() => "(${a0}, ${[
+        for (var i0 = 0; i0 < 1; i0 += 1) a1[i0]
+      ]}, ${[for (var i0 = 0; i0 < 2; i0 += 1) a2[i0]]})";
+}
+
+class Struct8BytesInlineArrayMultiDimensionalInt extends Struct {
+  @Array(2, 2, 2)
+  Array<Array<Array<Uint8>>> a0;
+
+  String toString() => "(${[
+        for (var i0 = 0; i0 < 2; i0 += 1)
+          [
+            for (var i1 = 0; i1 < 2; i1 += 1)
+              [for (var i2 = 0; i2 < 2; i2 += 1) a0[i0][i1][i2]]
+          ]
       ]})";
 }
 
+class Struct32BytesInlineArrayMultiDimensionalInt extends Struct {
+  @Array(2, 2, 2, 2, 2)
+  Array<Array<Array<Array<Array<Uint8>>>>> a0;
+
+  String toString() => "(${[
+        for (var i0 = 0; i0 < 2; i0 += 1)
+          [
+            for (var i1 = 0; i1 < 2; i1 += 1)
+              [
+                for (var i2 = 0; i2 < 2; i2 += 1)
+                  [
+                    for (var i3 = 0; i3 < 2; i3 += 1)
+                      [for (var i4 = 0; i4 < 2; i4 += 1) a0[i0][i1][i2][i3][i4]]
+                  ]
+              ]
+          ]
+      ]})";
+}
+
+class Struct64BytesInlineArrayMultiDimensionalInt extends Struct {
+  @Array.multi([2, 2, 2, 2, 2, 2])
+  Array<Array<Array<Array<Array<Array<Uint8>>>>>> a0;
+
+  String toString() => "(${[
+        for (var i0 = 0; i0 < 2; i0 += 1)
+          [
+            for (var i1 = 0; i1 < 2; i1 += 1)
+              [
+                for (var i2 = 0; i2 < 2; i2 += 1)
+                  [
+                    for (var i3 = 0; i3 < 2; i3 += 1)
+                      [
+                        for (var i4 = 0; i4 < 2; i4 += 1)
+                          [
+                            for (var i5 = 0; i5 < 2; i5 += 1)
+                              a0[i0][i1][i2][i3][i4][i5]
+                          ]
+                      ]
+                  ]
+              ]
+          ]
+      ]})";
+}
+
+class Struct4BytesInlineArrayMultiDimensionalInt extends Struct {
+  @Array(2, 2)
+  Array<Array<Struct1ByteInt>> a0;
+
+  String toString() => "(${[
+        for (var i0 = 0; i0 < 2; i0 += 1)
+          [for (var i1 = 0; i1 < 2; i1 += 1) a0[i0][i1]]
+      ]})";
+}
+
+@Packed(1)
+class Struct3BytesPackedInt extends Struct {
+  @Int8()
+  int a0;
+
+  @Int16()
+  int a1;
+
+  String toString() => "(${a0}, ${a1})";
+}
+
+@Packed(1)
+class Struct3BytesPackedIntMembersAligned extends Struct {
+  @Int8()
+  int a0;
+
+  @Int16()
+  int a1;
+
+  String toString() => "(${a0}, ${a1})";
+}
+
+@Packed(1)
+class Struct5BytesPackedMixed extends Struct {
+  @Float()
+  double a0;
+
+  @Uint8()
+  int a1;
+
+  String toString() => "(${a0}, ${a1})";
+}
+
+class StructNestedAlignmentStruct5BytesPackedMixed extends Struct {
+  @Uint8()
+  int a0;
+
+  Struct5BytesPackedMixed a1;
+
+  String toString() => "(${a0}, ${a1})";
+}
+
+class Struct6BytesInlineArrayInt extends Struct {
+  @Array(2)
+  Array<Struct3BytesPackedIntMembersAligned> a0;
+
+  String toString() => "(${[for (var i0 = 0; i0 < 2; i0 += 1) a0[i0]]})";
+}
+
+@Packed(1)
+class Struct8BytesPackedInt extends Struct {
+  @Uint8()
+  int a0;
+
+  @Uint32()
+  int a1;
+
+  @Uint8()
+  int a2;
+
+  @Uint8()
+  int a3;
+
+  @Uint8()
+  int a4;
+
+  String toString() => "(${a0}, ${a1}, ${a2}, ${a3}, ${a4})";
+}
+
+@Packed(1)
+class Struct9BytesPackedMixed extends Struct {
+  @Uint8()
+  int a0;
+
+  @Double()
+  double a1;
+
+  String toString() => "(${a0}, ${a1})";
+}
+
+class Struct15BytesInlineArrayMixed extends Struct {
+  @Array(3)
+  Array<Struct5BytesPackedMixed> a0;
+
+  String toString() => "(${[for (var i0 = 0; i0 < 3; i0 += 1) a0[i0]]})";
+}
+
 final passStruct1ByteIntx10 = ffiTestFunctions.lookupFunction<
     Int64 Function(
         Struct1ByteInt,
@@ -5227,6 +5393,529 @@
   calloc.free(a9Pointer);
 }
 
+final passUint8Struct32BytesInlineArrayMultiDimensionalI =
+    ffiTestFunctions.lookupFunction<
+        Uint32 Function(
+            Uint8,
+            Struct32BytesInlineArrayMultiDimensionalInt,
+            Uint8,
+            Struct8BytesInlineArrayMultiDimensionalInt,
+            Uint8,
+            Struct8BytesInlineArrayMultiDimensionalInt,
+            Uint8),
+        int Function(
+            int,
+            Struct32BytesInlineArrayMultiDimensionalInt,
+            int,
+            Struct8BytesInlineArrayMultiDimensionalInt,
+            int,
+            Struct8BytesInlineArrayMultiDimensionalInt,
+            int)>("PassUint8Struct32BytesInlineArrayMultiDimensionalI");
+
+/// Test multi dimensional inline array struct as argument.
+void testPassUint8Struct32BytesInlineArrayMultiDimensionalI() {
+  int a0;
+  final a1Pointer = calloc<Struct32BytesInlineArrayMultiDimensionalInt>();
+  final Struct32BytesInlineArrayMultiDimensionalInt a1 = a1Pointer.ref;
+  int a2;
+  final a3Pointer = calloc<Struct8BytesInlineArrayMultiDimensionalInt>();
+  final Struct8BytesInlineArrayMultiDimensionalInt a3 = a3Pointer.ref;
+  int a4;
+  final a5Pointer = calloc<Struct8BytesInlineArrayMultiDimensionalInt>();
+  final Struct8BytesInlineArrayMultiDimensionalInt a5 = a5Pointer.ref;
+  int a6;
+
+  a0 = 1;
+  a1.a0[0][0][0][0][0] = 2;
+  a1.a0[0][0][0][0][1] = 3;
+  a1.a0[0][0][0][1][0] = 4;
+  a1.a0[0][0][0][1][1] = 5;
+  a1.a0[0][0][1][0][0] = 6;
+  a1.a0[0][0][1][0][1] = 7;
+  a1.a0[0][0][1][1][0] = 8;
+  a1.a0[0][0][1][1][1] = 9;
+  a1.a0[0][1][0][0][0] = 10;
+  a1.a0[0][1][0][0][1] = 11;
+  a1.a0[0][1][0][1][0] = 12;
+  a1.a0[0][1][0][1][1] = 13;
+  a1.a0[0][1][1][0][0] = 14;
+  a1.a0[0][1][1][0][1] = 15;
+  a1.a0[0][1][1][1][0] = 16;
+  a1.a0[0][1][1][1][1] = 17;
+  a1.a0[1][0][0][0][0] = 18;
+  a1.a0[1][0][0][0][1] = 19;
+  a1.a0[1][0][0][1][0] = 20;
+  a1.a0[1][0][0][1][1] = 21;
+  a1.a0[1][0][1][0][0] = 22;
+  a1.a0[1][0][1][0][1] = 23;
+  a1.a0[1][0][1][1][0] = 24;
+  a1.a0[1][0][1][1][1] = 25;
+  a1.a0[1][1][0][0][0] = 26;
+  a1.a0[1][1][0][0][1] = 27;
+  a1.a0[1][1][0][1][0] = 28;
+  a1.a0[1][1][0][1][1] = 29;
+  a1.a0[1][1][1][0][0] = 30;
+  a1.a0[1][1][1][0][1] = 31;
+  a1.a0[1][1][1][1][0] = 32;
+  a1.a0[1][1][1][1][1] = 33;
+  a2 = 34;
+  a3.a0[0][0][0] = 35;
+  a3.a0[0][0][1] = 36;
+  a3.a0[0][1][0] = 37;
+  a3.a0[0][1][1] = 38;
+  a3.a0[1][0][0] = 39;
+  a3.a0[1][0][1] = 40;
+  a3.a0[1][1][0] = 41;
+  a3.a0[1][1][1] = 42;
+  a4 = 43;
+  a5.a0[0][0][0] = 44;
+  a5.a0[0][0][1] = 45;
+  a5.a0[0][1][0] = 46;
+  a5.a0[0][1][1] = 47;
+  a5.a0[1][0][0] = 48;
+  a5.a0[1][0][1] = 49;
+  a5.a0[1][1][0] = 50;
+  a5.a0[1][1][1] = 51;
+  a6 = 52;
+
+  final result = passUint8Struct32BytesInlineArrayMultiDimensionalI(
+      a0, a1, a2, a3, a4, a5, a6);
+
+  print("result = $result");
+
+  Expect.equals(1378, result);
+
+  calloc.free(a1Pointer);
+  calloc.free(a3Pointer);
+  calloc.free(a5Pointer);
+}
+
+final passUint8Struct4BytesInlineArrayMultiDimensionalIn =
+    ffiTestFunctions.lookupFunction<
+        Uint32 Function(
+            Uint8, Struct4BytesInlineArrayMultiDimensionalInt, Uint8),
+        int Function(int, Struct4BytesInlineArrayMultiDimensionalInt,
+            int)>("PassUint8Struct4BytesInlineArrayMultiDimensionalIn");
+
+/// Test struct in multi dimensional inline array.
+void testPassUint8Struct4BytesInlineArrayMultiDimensionalIn() {
+  int a0;
+  final a1Pointer = calloc<Struct4BytesInlineArrayMultiDimensionalInt>();
+  final Struct4BytesInlineArrayMultiDimensionalInt a1 = a1Pointer.ref;
+  int a2;
+
+  a0 = 1;
+  a1.a0[0][0].a0 = 2;
+  a1.a0[0][1].a0 = -3;
+  a1.a0[1][0].a0 = 4;
+  a1.a0[1][1].a0 = -5;
+  a2 = 6;
+
+  final result = passUint8Struct4BytesInlineArrayMultiDimensionalIn(a0, a1, a2);
+
+  print("result = $result");
+
+  Expect.equals(5, result);
+
+  calloc.free(a1Pointer);
+}
+
+final passStruct3BytesPackedIntx10 = ffiTestFunctions.lookupFunction<
+    Int64 Function(
+        Struct3BytesPackedInt,
+        Struct3BytesPackedInt,
+        Struct3BytesPackedInt,
+        Struct3BytesPackedInt,
+        Struct3BytesPackedInt,
+        Struct3BytesPackedInt,
+        Struct3BytesPackedInt,
+        Struct3BytesPackedInt,
+        Struct3BytesPackedInt,
+        Struct3BytesPackedInt),
+    int Function(
+        Struct3BytesPackedInt,
+        Struct3BytesPackedInt,
+        Struct3BytesPackedInt,
+        Struct3BytesPackedInt,
+        Struct3BytesPackedInt,
+        Struct3BytesPackedInt,
+        Struct3BytesPackedInt,
+        Struct3BytesPackedInt,
+        Struct3BytesPackedInt,
+        Struct3BytesPackedInt)>("PassStruct3BytesPackedIntx10");
+
+/// Small struct with mis-aligned member.
+void testPassStruct3BytesPackedIntx10() {
+  final a0Pointer = calloc<Struct3BytesPackedInt>();
+  final Struct3BytesPackedInt a0 = a0Pointer.ref;
+  final a1Pointer = calloc<Struct3BytesPackedInt>();
+  final Struct3BytesPackedInt a1 = a1Pointer.ref;
+  final a2Pointer = calloc<Struct3BytesPackedInt>();
+  final Struct3BytesPackedInt a2 = a2Pointer.ref;
+  final a3Pointer = calloc<Struct3BytesPackedInt>();
+  final Struct3BytesPackedInt a3 = a3Pointer.ref;
+  final a4Pointer = calloc<Struct3BytesPackedInt>();
+  final Struct3BytesPackedInt a4 = a4Pointer.ref;
+  final a5Pointer = calloc<Struct3BytesPackedInt>();
+  final Struct3BytesPackedInt a5 = a5Pointer.ref;
+  final a6Pointer = calloc<Struct3BytesPackedInt>();
+  final Struct3BytesPackedInt a6 = a6Pointer.ref;
+  final a7Pointer = calloc<Struct3BytesPackedInt>();
+  final Struct3BytesPackedInt a7 = a7Pointer.ref;
+  final a8Pointer = calloc<Struct3BytesPackedInt>();
+  final Struct3BytesPackedInt a8 = a8Pointer.ref;
+  final a9Pointer = calloc<Struct3BytesPackedInt>();
+  final Struct3BytesPackedInt a9 = a9Pointer.ref;
+
+  a0.a0 = -1;
+  a0.a1 = 2;
+  a1.a0 = -3;
+  a1.a1 = 4;
+  a2.a0 = -5;
+  a2.a1 = 6;
+  a3.a0 = -7;
+  a3.a1 = 8;
+  a4.a0 = -9;
+  a4.a1 = 10;
+  a5.a0 = -11;
+  a5.a1 = 12;
+  a6.a0 = -13;
+  a6.a1 = 14;
+  a7.a0 = -15;
+  a7.a1 = 16;
+  a8.a0 = -17;
+  a8.a1 = 18;
+  a9.a0 = -19;
+  a9.a1 = 20;
+
+  final result =
+      passStruct3BytesPackedIntx10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  print("result = $result");
+
+  Expect.equals(10, result);
+
+  calloc.free(a0Pointer);
+  calloc.free(a1Pointer);
+  calloc.free(a2Pointer);
+  calloc.free(a3Pointer);
+  calloc.free(a4Pointer);
+  calloc.free(a5Pointer);
+  calloc.free(a6Pointer);
+  calloc.free(a7Pointer);
+  calloc.free(a8Pointer);
+  calloc.free(a9Pointer);
+}
+
+final passStruct8BytesPackedIntx10 = ffiTestFunctions.lookupFunction<
+    Int64 Function(
+        Struct8BytesPackedInt,
+        Struct8BytesPackedInt,
+        Struct8BytesPackedInt,
+        Struct8BytesPackedInt,
+        Struct8BytesPackedInt,
+        Struct8BytesPackedInt,
+        Struct8BytesPackedInt,
+        Struct8BytesPackedInt,
+        Struct8BytesPackedInt,
+        Struct8BytesPackedInt),
+    int Function(
+        Struct8BytesPackedInt,
+        Struct8BytesPackedInt,
+        Struct8BytesPackedInt,
+        Struct8BytesPackedInt,
+        Struct8BytesPackedInt,
+        Struct8BytesPackedInt,
+        Struct8BytesPackedInt,
+        Struct8BytesPackedInt,
+        Struct8BytesPackedInt,
+        Struct8BytesPackedInt)>("PassStruct8BytesPackedIntx10");
+
+/// Struct with mis-aligned member.
+void testPassStruct8BytesPackedIntx10() {
+  final a0Pointer = calloc<Struct8BytesPackedInt>();
+  final Struct8BytesPackedInt a0 = a0Pointer.ref;
+  final a1Pointer = calloc<Struct8BytesPackedInt>();
+  final Struct8BytesPackedInt a1 = a1Pointer.ref;
+  final a2Pointer = calloc<Struct8BytesPackedInt>();
+  final Struct8BytesPackedInt a2 = a2Pointer.ref;
+  final a3Pointer = calloc<Struct8BytesPackedInt>();
+  final Struct8BytesPackedInt a3 = a3Pointer.ref;
+  final a4Pointer = calloc<Struct8BytesPackedInt>();
+  final Struct8BytesPackedInt a4 = a4Pointer.ref;
+  final a5Pointer = calloc<Struct8BytesPackedInt>();
+  final Struct8BytesPackedInt a5 = a5Pointer.ref;
+  final a6Pointer = calloc<Struct8BytesPackedInt>();
+  final Struct8BytesPackedInt a6 = a6Pointer.ref;
+  final a7Pointer = calloc<Struct8BytesPackedInt>();
+  final Struct8BytesPackedInt a7 = a7Pointer.ref;
+  final a8Pointer = calloc<Struct8BytesPackedInt>();
+  final Struct8BytesPackedInt a8 = a8Pointer.ref;
+  final a9Pointer = calloc<Struct8BytesPackedInt>();
+  final Struct8BytesPackedInt a9 = a9Pointer.ref;
+
+  a0.a0 = 1;
+  a0.a1 = 2;
+  a0.a2 = 3;
+  a0.a3 = 4;
+  a0.a4 = 5;
+  a1.a0 = 6;
+  a1.a1 = 7;
+  a1.a2 = 8;
+  a1.a3 = 9;
+  a1.a4 = 10;
+  a2.a0 = 11;
+  a2.a1 = 12;
+  a2.a2 = 13;
+  a2.a3 = 14;
+  a2.a4 = 15;
+  a3.a0 = 16;
+  a3.a1 = 17;
+  a3.a2 = 18;
+  a3.a3 = 19;
+  a3.a4 = 20;
+  a4.a0 = 21;
+  a4.a1 = 22;
+  a4.a2 = 23;
+  a4.a3 = 24;
+  a4.a4 = 25;
+  a5.a0 = 26;
+  a5.a1 = 27;
+  a5.a2 = 28;
+  a5.a3 = 29;
+  a5.a4 = 30;
+  a6.a0 = 31;
+  a6.a1 = 32;
+  a6.a2 = 33;
+  a6.a3 = 34;
+  a6.a4 = 35;
+  a7.a0 = 36;
+  a7.a1 = 37;
+  a7.a2 = 38;
+  a7.a3 = 39;
+  a7.a4 = 40;
+  a8.a0 = 41;
+  a8.a1 = 42;
+  a8.a2 = 43;
+  a8.a3 = 44;
+  a8.a4 = 45;
+  a9.a0 = 46;
+  a9.a1 = 47;
+  a9.a2 = 48;
+  a9.a3 = 49;
+  a9.a4 = 50;
+
+  final result =
+      passStruct8BytesPackedIntx10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  print("result = $result");
+
+  Expect.equals(1275, result);
+
+  calloc.free(a0Pointer);
+  calloc.free(a1Pointer);
+  calloc.free(a2Pointer);
+  calloc.free(a3Pointer);
+  calloc.free(a4Pointer);
+  calloc.free(a5Pointer);
+  calloc.free(a6Pointer);
+  calloc.free(a7Pointer);
+  calloc.free(a8Pointer);
+  calloc.free(a9Pointer);
+}
+
+final passStruct9BytesPackedMixedx10DoubleInt32 =
+    ffiTestFunctions.lookupFunction<
+        Double Function(
+            Struct9BytesPackedMixed,
+            Struct9BytesPackedMixed,
+            Struct9BytesPackedMixed,
+            Struct9BytesPackedMixed,
+            Struct9BytesPackedMixed,
+            Struct9BytesPackedMixed,
+            Struct9BytesPackedMixed,
+            Struct9BytesPackedMixed,
+            Struct9BytesPackedMixed,
+            Struct9BytesPackedMixed,
+            Double,
+            Int32),
+        double Function(
+            Struct9BytesPackedMixed,
+            Struct9BytesPackedMixed,
+            Struct9BytesPackedMixed,
+            Struct9BytesPackedMixed,
+            Struct9BytesPackedMixed,
+            Struct9BytesPackedMixed,
+            Struct9BytesPackedMixed,
+            Struct9BytesPackedMixed,
+            Struct9BytesPackedMixed,
+            Struct9BytesPackedMixed,
+            double,
+            int)>("PassStruct9BytesPackedMixedx10DoubleInt32");
+
+/// Struct with mis-aligned member.
+/// Tests backfilling of CPU and FPU registers.
+void testPassStruct9BytesPackedMixedx10DoubleInt32() {
+  final a0Pointer = calloc<Struct9BytesPackedMixed>();
+  final Struct9BytesPackedMixed a0 = a0Pointer.ref;
+  final a1Pointer = calloc<Struct9BytesPackedMixed>();
+  final Struct9BytesPackedMixed a1 = a1Pointer.ref;
+  final a2Pointer = calloc<Struct9BytesPackedMixed>();
+  final Struct9BytesPackedMixed a2 = a2Pointer.ref;
+  final a3Pointer = calloc<Struct9BytesPackedMixed>();
+  final Struct9BytesPackedMixed a3 = a3Pointer.ref;
+  final a4Pointer = calloc<Struct9BytesPackedMixed>();
+  final Struct9BytesPackedMixed a4 = a4Pointer.ref;
+  final a5Pointer = calloc<Struct9BytesPackedMixed>();
+  final Struct9BytesPackedMixed a5 = a5Pointer.ref;
+  final a6Pointer = calloc<Struct9BytesPackedMixed>();
+  final Struct9BytesPackedMixed a6 = a6Pointer.ref;
+  final a7Pointer = calloc<Struct9BytesPackedMixed>();
+  final Struct9BytesPackedMixed a7 = a7Pointer.ref;
+  final a8Pointer = calloc<Struct9BytesPackedMixed>();
+  final Struct9BytesPackedMixed a8 = a8Pointer.ref;
+  final a9Pointer = calloc<Struct9BytesPackedMixed>();
+  final Struct9BytesPackedMixed a9 = a9Pointer.ref;
+  double a10;
+  int a11;
+
+  a0.a0 = 1;
+  a0.a1 = 2.0;
+  a1.a0 = 3;
+  a1.a1 = 4.0;
+  a2.a0 = 5;
+  a2.a1 = 6.0;
+  a3.a0 = 7;
+  a3.a1 = 8.0;
+  a4.a0 = 9;
+  a4.a1 = 10.0;
+  a5.a0 = 11;
+  a5.a1 = 12.0;
+  a6.a0 = 13;
+  a6.a1 = 14.0;
+  a7.a0 = 15;
+  a7.a1 = 16.0;
+  a8.a0 = 17;
+  a8.a1 = 18.0;
+  a9.a0 = 19;
+  a9.a1 = 20.0;
+  a10 = -21.0;
+  a11 = 22;
+
+  final result = passStruct9BytesPackedMixedx10DoubleInt32(
+      a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11);
+
+  print("result = $result");
+
+  Expect.approxEquals(211.0, result);
+
+  calloc.free(a0Pointer);
+  calloc.free(a1Pointer);
+  calloc.free(a2Pointer);
+  calloc.free(a3Pointer);
+  calloc.free(a4Pointer);
+  calloc.free(a5Pointer);
+  calloc.free(a6Pointer);
+  calloc.free(a7Pointer);
+  calloc.free(a8Pointer);
+  calloc.free(a9Pointer);
+}
+
+final passStruct5BytesPackedMixed = ffiTestFunctions.lookupFunction<
+    Double Function(Struct5BytesPackedMixed),
+    double Function(Struct5BytesPackedMixed)>("PassStruct5BytesPackedMixed");
+
+/// This packed struct happens to have only aligned members.
+void testPassStruct5BytesPackedMixed() {
+  final a0Pointer = calloc<Struct5BytesPackedMixed>();
+  final Struct5BytesPackedMixed a0 = a0Pointer.ref;
+
+  a0.a0 = -1.0;
+  a0.a1 = 2;
+
+  final result = passStruct5BytesPackedMixed(a0);
+
+  print("result = $result");
+
+  Expect.approxEquals(1.0, result);
+
+  calloc.free(a0Pointer);
+}
+
+final passStructNestedAlignmentStruct5BytesPackedMixed =
+    ffiTestFunctions.lookupFunction<
+            Double Function(StructNestedAlignmentStruct5BytesPackedMixed),
+            double Function(StructNestedAlignmentStruct5BytesPackedMixed)>(
+        "PassStructNestedAlignmentStruct5BytesPackedMixed");
+
+/// Check alignment of packed struct in non-packed struct.
+void testPassStructNestedAlignmentStruct5BytesPackedMixed() {
+  final a0Pointer = calloc<StructNestedAlignmentStruct5BytesPackedMixed>();
+  final StructNestedAlignmentStruct5BytesPackedMixed a0 = a0Pointer.ref;
+
+  a0.a0 = 1;
+  a0.a1.a0 = 2.0;
+  a0.a1.a1 = 3;
+
+  final result = passStructNestedAlignmentStruct5BytesPackedMixed(a0);
+
+  print("result = $result");
+
+  Expect.approxEquals(6.0, result);
+
+  calloc.free(a0Pointer);
+}
+
+final passStruct6BytesInlineArrayInt = ffiTestFunctions.lookupFunction<
+    Double Function(Struct6BytesInlineArrayInt),
+    double Function(
+        Struct6BytesInlineArrayInt)>("PassStruct6BytesInlineArrayInt");
+
+/// Check alignment of packed struct array in non-packed struct.
+void testPassStruct6BytesInlineArrayInt() {
+  final a0Pointer = calloc<Struct6BytesInlineArrayInt>();
+  final Struct6BytesInlineArrayInt a0 = a0Pointer.ref;
+
+  a0.a0[0].a0 = -1;
+  a0.a0[0].a1 = 2;
+  a0.a0[1].a0 = -3;
+  a0.a0[1].a1 = 4;
+
+  final result = passStruct6BytesInlineArrayInt(a0);
+
+  print("result = $result");
+
+  Expect.approxEquals(2.0, result);
+
+  calloc.free(a0Pointer);
+}
+
+final passStruct15BytesInlineArrayMixed = ffiTestFunctions.lookupFunction<
+    Double Function(Struct15BytesInlineArrayMixed),
+    double Function(
+        Struct15BytesInlineArrayMixed)>("PassStruct15BytesInlineArrayMixed");
+
+/// Check alignment of packed struct array in non-packed struct.
+void testPassStruct15BytesInlineArrayMixed() {
+  final a0Pointer = calloc<Struct15BytesInlineArrayMixed>();
+  final Struct15BytesInlineArrayMixed a0 = a0Pointer.ref;
+
+  a0.a0[0].a0 = -1.0;
+  a0.a0[0].a1 = 2;
+  a0.a0[1].a0 = -3.0;
+  a0.a0[1].a1 = 4;
+  a0.a0[2].a0 = -5.0;
+  a0.a0[2].a1 = 6;
+
+  final result = passStruct15BytesInlineArrayMixed(a0);
+
+  print("result = $result");
+
+  Expect.approxEquals(3.0, result);
+
+  calloc.free(a0Pointer);
+}
+
 final returnStruct1ByteInt = ffiTestFunctions.lookupFunction<
     Struct1ByteInt Function(Int8),
     Struct1ByteInt Function(int)>("ReturnStruct1ByteInt");
@@ -6645,6 +7334,78 @@
   Expect.equals(a127, result.a127);
 }
 
+final returnStruct3BytesPackedInt = ffiTestFunctions.lookupFunction<
+    Struct3BytesPackedInt Function(Int8, Int16),
+    Struct3BytesPackedInt Function(int, int)>("ReturnStruct3BytesPackedInt");
+
+/// Small struct with mis-aligned member.
+void testReturnStruct3BytesPackedInt() {
+  int a0;
+  int a1;
+
+  a0 = -1;
+  a1 = 2;
+
+  final result = returnStruct3BytesPackedInt(a0, a1);
+
+  print("result = $result");
+
+  Expect.equals(a0, result.a0);
+  Expect.equals(a1, result.a1);
+}
+
+final returnStruct8BytesPackedInt = ffiTestFunctions.lookupFunction<
+    Struct8BytesPackedInt Function(Uint8, Uint32, Uint8, Uint8, Uint8),
+    Struct8BytesPackedInt Function(
+        int, int, int, int, int)>("ReturnStruct8BytesPackedInt");
+
+/// Struct with mis-aligned member.
+void testReturnStruct8BytesPackedInt() {
+  int a0;
+  int a1;
+  int a2;
+  int a3;
+  int a4;
+
+  a0 = 1;
+  a1 = 2;
+  a2 = 3;
+  a3 = 4;
+  a4 = 5;
+
+  final result = returnStruct8BytesPackedInt(a0, a1, a2, a3, a4);
+
+  print("result = $result");
+
+  Expect.equals(a0, result.a0);
+  Expect.equals(a1, result.a1);
+  Expect.equals(a2, result.a2);
+  Expect.equals(a3, result.a3);
+  Expect.equals(a4, result.a4);
+}
+
+final returnStruct9BytesPackedMixed = ffiTestFunctions.lookupFunction<
+    Struct9BytesPackedMixed Function(Uint8, Double),
+    Struct9BytesPackedMixed Function(
+        int, double)>("ReturnStruct9BytesPackedMixed");
+
+/// Struct with mis-aligned member.
+/// Tests backfilling of CPU and FPU registers.
+void testReturnStruct9BytesPackedMixed() {
+  int a0;
+  double a1;
+
+  a0 = 1;
+  a1 = 2.0;
+
+  final result = returnStruct9BytesPackedMixed(a0, a1);
+
+  print("result = $result");
+
+  Expect.equals(a0, result.a0);
+  Expect.approxEquals(a1, result.a1);
+}
+
 final returnStructArgumentStruct1ByteInt = ffiTestFunctions.lookupFunction<
     Struct1ByteInt Function(Struct1ByteInt),
     Struct1ByteInt Function(
diff --git a/tests/ffi_2/generator/c_types.dart b/tests/ffi_2/generator/c_types.dart
index 70fbfe1..df3b44b 100644
--- a/tests/ffi_2/generator/c_types.dart
+++ b/tests/ffi_2/generator/c_types.dart
@@ -133,8 +133,8 @@
   String get cStructField {
     String postFix = "";
     if (type is FixedLengthArrayType) {
-      final length = (type as FixedLengthArrayType).length;
-      postFix = "[$length]";
+      final dimensions = (type as FixedLengthArrayType).dimensions;
+      postFix = "[${dimensions.join("][")}]";
     }
     return "${type.cType} $name$postFix;";
   }
@@ -155,20 +155,24 @@
 class StructType extends CType {
   final List<Member> members;
 
+  final int? packing;
+
   /// To disambiguate same size structs.
   final String suffix;
 
   /// To override names.
   final String overrideName;
 
-  StructType(List<CType> memberTypes)
+  StructType(List<CType> memberTypes, {int? this.packing})
       : this.members = generateMemberNames(memberTypes),
         this.suffix = "",
         this.overrideName = "";
-  StructType.disambiguate(List<CType> memberTypes, this.suffix)
+  StructType.disambiguate(List<CType> memberTypes, this.suffix,
+      {int? this.packing})
       : this.members = generateMemberNames(memberTypes),
         this.overrideName = "";
-  StructType.override(List<CType> memberTypes, this.overrideName)
+  StructType.override(List<CType> memberTypes, this.overrideName,
+      {int? this.packing})
       : this.members = generateMemberNames(memberTypes),
         this.suffix = "";
 
@@ -183,9 +187,19 @@
       !memberTypes.map((e) => e.hasSize).contains(false) && !hasPadding;
   int get size => memberTypes.fold(0, (int acc, e) => acc + e.size);
 
-  /// Rough approximation, to not redo all ABI logic here.
-  bool get hasPadding =>
-      members.length < 2 ? false : members[0].type.size < members[1].type.size;
+  bool get hasPacking => packing != null;
+
+  bool get hasPadding {
+    if (members.length < 2) {
+      return false;
+    }
+    if (packing == 1) {
+      return false;
+    }
+
+    /// Rough approximation, to not redo all ABI logic here.
+    return members[0].type.size < members[1].type.size;
+  }
 
   bool get hasNestedStructs =>
       members.map((e) => e.type is StructType).contains(true);
@@ -193,6 +207,12 @@
   bool get hasInlineArrays =>
       members.map((e) => e.type is FixedLengthArrayType).contains(true);
 
+  bool get hasMultiDimensionalInlineArrays => members
+      .map((e) => e.type)
+      .whereType<FixedLengthArrayType>()
+      .where((e) => e.isMulti)
+      .isNotEmpty;
+
   /// All members have the same type.
   bool get isHomogeneous => memberTypes.toSet().length == 1;
 
@@ -211,11 +231,20 @@
     if (hasSize) {
       result += "${size}Byte" + (size != 1 ? "s" : "");
     }
+    if (hasPacking) {
+      result += "Packed";
+      if (packing! > 1) {
+        result += "$packing";
+      }
+    }
     if (hasNestedStructs) {
       result += "Nested";
     }
     if (hasInlineArrays) {
       result += "InlineArray";
+      if (hasMultiDimensionalInlineArrays) {
+        result += "MultiDimensional";
+      }
     }
     if (members.length == 0) {
       // No suffix.
@@ -241,10 +270,37 @@
 
   FixedLengthArrayType(this.elementType, this.length);
 
+  factory FixedLengthArrayType.multi(CType elementType, List<int> dimensions) {
+    if (dimensions.length == 1) {
+      return FixedLengthArrayType(elementType, dimensions.single);
+    }
+
+    final remainingDimensions = dimensions.sublist(1);
+    final nestedArray =
+        FixedLengthArrayType.multi(elementType, remainingDimensions);
+    return FixedLengthArrayType(nestedArray, dimensions.first);
+  }
+
   String get cType => elementType.cType;
-  String get dartCType => "Array<${elementType.dartType}>";
+  String get dartCType => "Array<${elementType.dartCType}>";
   String get dartType => "Array<${elementType.dartCType}>";
-  String get dartStructFieldAnnotation => "@Array($length)";
+
+  String get dartStructFieldAnnotation {
+    if (dimensions.length > 5) {
+      return "@Array.multi([${dimensions.join(", ")}])";
+    }
+    return "@Array(${dimensions.join(", ")})";
+  }
+
+  List<int> get dimensions {
+    final elementType = this.elementType;
+    if (elementType is FixedLengthArrayType) {
+      return [length, ...elementType.dimensions];
+    }
+    return [length];
+  }
+
+  bool get isMulti => elementType is FixedLengthArrayType;
 
   bool get hasSize => elementType.hasSize;
   int get size => elementType.size * length;
diff --git a/tests/ffi_2/generator/structs_by_value_tests_configuration.dart b/tests/ffi_2/generator/structs_by_value_tests_configuration.dart
index c681f8a..1ad3c11 100644
--- a/tests/ffi_2/generator/structs_by_value_tests_configuration.dart
+++ b/tests/ffi_2/generator/structs_by_value_tests_configuration.dart
@@ -310,6 +310,54 @@
 On x64, it will exhaust the integer registers with the 6th argument.
 The rest goes on the stack.
 On arm, arguments are 4 byte aligned."""),
+  FunctionType(
+      [
+        uint8,
+        struct32bytesInlineArrayMultiDimesional,
+        uint8,
+        struct8bytesInlineArrayMultiDimesional,
+        uint8,
+        struct8bytesInlineArrayMultiDimesional,
+        uint8
+      ],
+      uint32,
+      """
+Test multi dimensional inline array struct as argument."""),
+  FunctionType(
+      [uint8, structMultiDimensionalStruct, uint8],
+      uint32,
+      """
+Test struct in multi dimensional inline array."""),
+  FunctionType(List.filled(10, struct3bytesPacked), int64, """
+Small struct with mis-aligned member."""),
+  FunctionType(List.filled(10, struct8bytesPacked), int64, """
+Struct with mis-aligned member."""),
+  FunctionType(
+      [...List.filled(10, struct9bytesPacked), double_, int32],
+      double_,
+      """
+Struct with mis-aligned member.
+Tests backfilling of CPU and FPU registers."""),
+  FunctionType(
+      [struct5bytesPacked],
+      double_,
+      """
+This packed struct happens to have only aligned members."""),
+  FunctionType(
+      [struct6bytesPacked],
+      double_,
+      """
+Check alignment of packed struct in non-packed struct."""),
+  FunctionType(
+      [struct6bytesPacked2],
+      double_,
+      """
+Check alignment of packed struct array in non-packed struct."""),
+  FunctionType(
+      [struct15bytesPacked],
+      double_,
+      """
+Check alignment of packed struct array in non-packed struct."""),
   FunctionType(struct1byteInt.memberTypes, struct1byteInt, """
 Smallest struct with data."""),
   FunctionType(struct3bytesInt.memberTypes, struct3bytesInt, """
@@ -365,6 +413,13 @@
 Return value too big to go in FPU registers on arm64."""),
   FunctionType(struct1024bytesInt.memberTypes, struct1024bytesInt, """
 Test 1kb struct."""),
+  FunctionType(struct3bytesPacked.memberTypes, struct3bytesPacked, """
+Small struct with mis-aligned member."""),
+  FunctionType(struct8bytesPacked.memberTypes, struct8bytesPacked, """
+Struct with mis-aligned member."""),
+  FunctionType(struct9bytesPacked.memberTypes, struct9bytesPacked, """
+Struct with mis-aligned member.
+Tests backfilling of CPU and FPU registers."""),
   FunctionType(
       [struct1byteInt],
       struct1byteInt,
@@ -507,6 +562,18 @@
   struct16bytesFloatInlineNested,
   struct32bytesDoubleInlineNested,
   struct16bytesMixedInlineNested,
+  struct8bytesInlineArrayMultiDimesional,
+  struct32bytesInlineArrayMultiDimesional,
+  struct64bytesInlineArrayMultiDimesional,
+  structMultiDimensionalStruct,
+  struct3bytesPacked,
+  struct3bytesPackedMembersAligned,
+  struct5bytesPacked,
+  struct6bytesPacked,
+  struct6bytesPacked2,
+  struct8bytesPacked,
+  struct9bytesPacked,
+  struct15bytesPacked,
 ];
 
 final struct1byteInt = StructType([int8]);
@@ -634,3 +701,43 @@
   FixedLengthArrayType(StructType([float, int16, int16]), 1),
   FixedLengthArrayType(int16, 2),
 ], "Struct16BytesMixed3");
+
+final struct8bytesInlineArrayMultiDimesional = StructType([
+  FixedLengthArrayType.multi(uint8, [2, 2, 2])
+]);
+
+final struct32bytesInlineArrayMultiDimesional = StructType([
+  FixedLengthArrayType.multi(uint8, [2, 2, 2, 2, 2])
+]);
+
+final struct64bytesInlineArrayMultiDimesional = StructType([
+  FixedLengthArrayType.multi(uint8, [2, 2, 2, 2, 2, 2])
+]);
+
+final structMultiDimensionalStruct = StructType([
+  FixedLengthArrayType.multi(struct1byteInt, [2, 2])
+]);
+
+final struct3bytesPacked = StructType([int8, int16], packing: 1);
+
+final struct3bytesPackedMembersAligned =
+    StructType.disambiguate([int8, int16], "MembersAligned", packing: 1);
+
+final struct5bytesPacked = StructType([float, uint8], packing: 1);
+
+/// The float in the nested struct is not aligned.
+final struct6bytesPacked = StructType([uint8, struct5bytesPacked]);
+
+/// The second element in the array has a nested misaligned int16.
+final struct6bytesPacked2 =
+    StructType([FixedLengthArrayType(struct3bytesPackedMembersAligned, 2)]);
+
+final struct8bytesPacked =
+    StructType([uint8, uint32, uint8, uint8, uint8], packing: 1);
+
+final struct9bytesPacked = StructType([uint8, double_], packing: 1);
+
+/// The float in the nested struct is aligned in the first element in the
+/// inline array, but not in the subsequent ones.
+final struct15bytesPacked =
+    StructType([FixedLengthArrayType(struct5bytesPacked, 3)]);
diff --git a/tests/ffi_2/generator/structs_by_value_tests_generator.dart b/tests/ffi_2/generator/structs_by_value_tests_generator.dart
index 7ebb535..c66dbea 100644
--- a/tests/ffi_2/generator/structs_by_value_tests_generator.dart
+++ b/tests/ffi_2/generator/structs_by_value_tests_generator.dart
@@ -332,7 +332,7 @@
       case FixedLengthArrayType:
         final this_ = this as FixedLengthArrayType;
         return """
-for(int i = 0; i < ${this_.length}; i++){
+for (int i = 0; i < ${this_.length}; i++){
   ${this_.elementType.dartExpectsStatements("$expected[i]", "$actual[i]")}
 }
 """;
@@ -370,7 +370,7 @@
       case FixedLengthArrayType:
         final this_ = this as FixedLengthArrayType;
         return """
-for(intptr_t i = 0; i < ${this_.length}; i++){
+for (intptr_t i = 0; i < ${this_.length}; i++){
   ${this_.elementType.cExpectsStatements("$expected[i]", "$actual[i]")}
 }
 """;
@@ -397,7 +397,7 @@
       case FixedLengthArrayType:
         final this_ = this as FixedLengthArrayType;
         return """
-for(intptr_t i = 0; i < ${this_.length}; i++){
+for (intptr_t i = 0; i < ${this_.length}; i++){
   ${this_.elementType.cExpectsZeroStatements("$actual[i]")}
 }
 """;
@@ -455,18 +455,30 @@
 
 extension on StructType {
   String dartClass(bool nnbd) {
+    final packingAnnotation = hasPacking ? "@Packed(${packing})" : "";
     String dartFields = "";
     for (final member in members) {
       dartFields += "${member.dartStructField(nnbd)}\n\n";
     }
     String toStringBody = members.map((m) {
       if (m.type is FixedLengthArrayType) {
-        final length = (m.type as FixedLengthArrayType).length;
-        return "\$\{[for (var i = 0; i < $length; i += 1) ${m.name}[i]]\}";
+        int dimensionNumber = 0;
+        String inlineFor = "";
+        String read = m.name;
+        String closing = "";
+        for (final dimension in (m.type as FixedLengthArrayType).dimensions) {
+          final i = "i$dimensionNumber";
+          inlineFor += "[for (var $i = 0; $i < $dimension; $i += 1)";
+          read += "[$i]";
+          closing += "]";
+          dimensionNumber++;
+        }
+        return "\$\{$inlineFor $read $closing\}";
       }
       return "\$\{${m.name}\}";
     }).join(", ");
     return """
+    $packingAnnotation
     class $name extends Struct {
       $dartFields
 
@@ -476,14 +488,19 @@
   }
 
   String get cDefinition {
+    final packingPragmaPush =
+        hasPacking ? "#pragma pack(push, ${packing})" : "";
+    final packingPragmaPop = hasPacking ? "#pragma pack(pop)" : "";
     String cFields = "";
     for (final member in members) {
       cFields += "  ${member.cStructField}\n";
     }
     return """
+    $packingPragmaPush
     struct $name {
       $cFields
     };
+    $packingPragmaPop
 
     """;
   }
diff --git a/tests/ffi_2/inline_array_multi_dimensional_test.dart b/tests/ffi_2/inline_array_multi_dimensional_test.dart
new file mode 100644
index 0000000..15d2059
--- /dev/null
+++ b/tests/ffi_2/inline_array_multi_dimensional_test.dart
@@ -0,0 +1,164 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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
+
+import 'dart:ffi';
+
+import "package:expect/expect.dart";
+import 'package:ffi/ffi.dart';
+
+// Reuse struct definitions.
+import 'function_structs_by_value_generated_test.dart';
+
+void main() {
+  testSizeOf();
+  testLoad();
+  testLoadMultiAnnotation();
+  testStore();
+  testToString();
+  testRange();
+}
+
+void testSizeOf() {
+  Expect.equals(32, sizeOf<Struct32BytesInlineArrayMultiDimensionalInt>());
+  Expect.equals(64, sizeOf<Struct64BytesInlineArrayMultiDimensionalInt>());
+}
+
+/// Tests the load of nested `Array`s.
+///
+/// Only stores into arrays which do not have nested arrays.
+void testLoad() {
+  final Pointer<Struct32BytesInlineArrayMultiDimensionalInt> pointer = calloc();
+  final struct = pointer.ref;
+  final array = struct.a0;
+  for (int i = 0; i < 2; i++) {
+    for (int j = 0; j < 2; j++) {
+      for (int k = 0; k < 2; k++) {
+        for (int l = 0; l < 2; l++) {
+          for (int m = 0; m < 2; m++) {
+            array[i][j][k][l][m] = i + j + k + l + m;
+          }
+        }
+      }
+    }
+  }
+  for (int i = 0; i < 2; i++) {
+    for (int j = 0; j < 2; j++) {
+      for (int k = 0; k < 2; k++) {
+        for (int l = 0; l < 2; l++) {
+          for (int m = 0; m < 2; m++) {
+            Expect.equals(i + j + k + l + m, array[i][j][k][l][m]);
+          }
+        }
+      }
+    }
+  }
+  calloc.free(pointer);
+}
+
+/// Tests the load of nested `Array`s.
+///
+/// Only stores into arrays which do not have nested arrays.
+void testLoadMultiAnnotation() {
+  final Pointer<Struct64BytesInlineArrayMultiDimensionalInt> pointer = calloc();
+  final struct = pointer.ref;
+  final array = struct.a0;
+  for (int i = 0; i < 2; i++) {
+    for (int j = 0; j < 2; j++) {
+      for (int k = 0; k < 2; k++) {
+        for (int l = 0; l < 2; l++) {
+          for (int m = 0; m < 2; m++) {
+            for (int o = 0; o < 2; o++) {
+              array[i][j][k][l][m][o] = i + j + k + l + m + o;
+            }
+          }
+        }
+      }
+    }
+  }
+  for (int i = 0; i < 2; i++) {
+    for (int j = 0; j < 2; j++) {
+      for (int k = 0; k < 2; k++) {
+        for (int l = 0; l < 2; l++) {
+          for (int m = 0; m < 2; m++) {
+            for (int o = 0; o < 2; o++) {
+              Expect.equals(i + j + k + l + m + o, array[i][j][k][l][m][o]);
+            }
+          }
+        }
+      }
+    }
+  }
+  calloc.free(pointer);
+}
+
+void testStore() {
+  final Pointer<Struct32BytesInlineArrayMultiDimensionalInt> pointer = calloc();
+  final struct = pointer.ref;
+  final array = struct.a0;
+  for (int i = 0; i < 2; i++) {
+    for (int j = 0; j < 2; j++) {
+      for (int k = 0; k < 2; k++) {
+        for (int l = 0; l < 2; l++) {
+          for (int m = 0; m < 2; m++) {
+            array[i][j][k][l][m] = i + j + k + l + m;
+          }
+        }
+      }
+    }
+  }
+  array[0] = array[1]; // Copy many things.
+  for (int j = 0; j < 2; j++) {
+    for (int k = 0; k < 2; k++) {
+      for (int l = 0; l < 2; l++) {
+        for (int m = 0; m < 2; m++) {
+          Expect.equals(array[1][j][k][l][m], array[0][j][k][l][m]);
+        }
+      }
+    }
+  }
+  calloc.free(pointer);
+}
+
+// // Tests the toString of the test generator.
+void testToString() {
+  final Pointer<Struct32BytesInlineArrayMultiDimensionalInt> pointer = calloc();
+  final struct = pointer.ref;
+  final array = struct.a0;
+  for (int i = 0; i < 2; i++) {
+    for (int j = 0; j < 2; j++) {
+      for (int k = 0; k < 2; k++) {
+        for (int l = 0; l < 2; l++) {
+          for (int m = 0; m < 2; m++) {
+            array[i][j][k][l][m] = 16 * i + 8 * j + 4 * k + 2 * l + m;
+          }
+        }
+      }
+    }
+  }
+  Expect.equals(
+      "([[[[[0, 1], [2, 3]], [[4, 5], [6, 7]]], [[[8, 9], [10, 11]], [[12, 13], [14, 15]]]], [[[[16, 17], [18, 19]], [[20, 21], [22, 23]]], [[[24, 25], [26, 27]], [[28, 29], [30, 31]]]]])",
+      struct.toString());
+  calloc.free(pointer);
+}
+
+void testRange() {
+  final pointer = calloc<Struct32BytesInlineArrayMultiDimensionalInt>();
+  final struct = pointer.ref;
+  final array = struct.a0;
+  array[0];
+  array[1];
+  Expect.throws(() => array[-1]);
+  Expect.throws(() => array[-1] = array[1]);
+  Expect.throws(() => array[2]);
+  Expect.throws(() => array[2] = array[1]);
+  array[0][0];
+  array[0][1];
+  Expect.throws(() => array[0][-1]);
+  Expect.throws(() => array[0][-1] = array[0][1]);
+  Expect.throws(() => array[0][2]);
+  Expect.throws(() => array[0][2] = array[0][1]);
+  calloc.free(pointer);
+}
diff --git a/tests/ffi_2/inline_array_test.dart b/tests/ffi_2/inline_array_test.dart
index 518d62e..868d117 100644
--- a/tests/ffi_2/inline_array_test.dart
+++ b/tests/ffi_2/inline_array_test.dart
@@ -30,11 +30,11 @@
 void testLoad() {
   final pointer = calloc<Struct8BytesInlineArrayInt>();
   final struct = pointer.ref;
-  final cArray = struct.a0;
+  final array = struct.a0;
   pointer.cast<Uint8>()[0] = 42;
   pointer.cast<Uint8>()[7] = 3;
-  Expect.equals(42, cArray[0]);
-  Expect.equals(3, cArray[7]);
+  Expect.equals(42, array[0]);
+  Expect.equals(3, array[7]);
   calloc.free(pointer);
 }
 
@@ -55,9 +55,9 @@
 void testToString() {
   final pointer = calloc<Struct8BytesInlineArrayInt>();
   final struct = pointer.ref;
-  final cArray = struct.a0;
+  final array = struct.a0;
   for (var i = 0; i < 8; i++) {
-    cArray[i] = i;
+    array[i] = i;
   }
   Expect.equals("([0, 1, 2, 3, 4, 5, 6, 7])", struct.toString());
   calloc.free(pointer);
@@ -77,14 +77,14 @@
 void testRange() {
   final pointer = calloc<Struct8BytesInlineArrayInt>();
   final struct = pointer.ref;
-  final cArray = struct.a0;
-  cArray[0] = 1;
-  Expect.equals(1, cArray[0]);
-  cArray[7] = 7;
-  Expect.equals(7, cArray[7]);
-  Expect.throws(() => cArray[-1]);
-  Expect.throws(() => cArray[-1] = 0);
-  Expect.throws(() => cArray[8]);
-  Expect.throws(() => cArray[8] = 0);
+  final array = struct.a0;
+  array[0] = 1;
+  Expect.equals(1, array[0]);
+  array[7] = 7;
+  Expect.equals(7, array[7]);
+  Expect.throws(() => array[-1]);
+  Expect.throws(() => array[-1] = 0);
+  Expect.throws(() => array[8]);
+  Expect.throws(() => array[8] = 0);
   calloc.free(pointer);
 }
diff --git a/tests/ffi_2/regress_45189_test.dart b/tests/ffi_2/regress_45189_test.dart
new file mode 100644
index 0000000..1aff90b
--- /dev/null
+++ b/tests/ffi_2/regress_45189_test.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. 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 "package:ffi/ffi.dart";
+import 'package:expect/expect.dart';
+
+class Struct8BytesInlineArrayInt extends Struct {
+  @Array(8)
+  Array<Uint8> a0;
+}
+
+void main() {
+  final pointer = calloc<Struct8BytesInlineArrayInt>();
+  final array = pointer.ref.a0;
+  try {
+    array[8]; // RangeError: Invalid value: Not in inclusive range 0..8: 8
+  } on RangeError catch (exception) {
+    final toString = exception.toString();
+    Expect.equals(
+        "RangeError: Invalid value: Not in inclusive range 0..7: 8", toString);
+  }
+  calloc.free(pointer);
+}
diff --git a/tests/ffi_2/regress_45198_test.dart b/tests/ffi_2/regress_45198_test.dart
new file mode 100644
index 0000000..48c1204
--- /dev/null
+++ b/tests/ffi_2/regress_45198_test.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. 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 "package:expect/expect.dart";
+import "package:ffi/ffi.dart";
+
+class Struct8BytesInlineArrayInt extends Struct {
+  @Array(2)
+  Array<Pointer<Int8>> a0;
+}
+
+void main() {
+  final arrayPointer = calloc<Struct8BytesInlineArrayInt>();
+
+  final pointer = Pointer<Int8>.fromAddress(0xdeadbeef);
+
+  final array = arrayPointer.ref.a0;
+  print(arrayPointer);
+  print(array);
+  Expect.type<Array<Pointer<Int8>>>(array);
+  Expect.equals(nullptr, array[0]);
+  array[0] = pointer;
+  Expect.equals(pointer, array[0]);
+
+  calloc.free(arrayPointer);
+}
diff --git a/tests/ffi_2/regress_45507_test.dart b/tests/ffi_2/regress_45507_test.dart
new file mode 100644
index 0000000..926c719
--- /dev/null
+++ b/tests/ffi_2/regress_45507_test.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. 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 "package:expect/expect.dart";
+
+const EIGHT = 8;
+
+class Struct8BytesInlineArrayInt extends Struct {
+  @Array(EIGHT)
+  Array<Uint8> a0;
+}
+
+void main() {
+  Expect.equals(8, sizeOf<Struct8BytesInlineArrayInt>());
+}
diff --git a/tests/ffi_2/regress_flutter79441_test.dart b/tests/ffi_2/regress_flutter79441_test.dart
new file mode 100644
index 0000000..a9b17de
--- /dev/null
+++ b/tests/ffi_2/regress_flutter79441_test.dart
@@ -0,0 +1,38 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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/flutter/flutter/issues/79441.
+
+import 'dart:ffi';
+
+// FFI signature
+typedef _dart_memset = void Function(Pointer<Uint8>, int, int);
+typedef _c_memset = Void Function(Pointer<Uint8>, Int32, IntPtr);
+
+_dart_memset fbMemset;
+
+void _fallbackMemset(Pointer<Uint8> ptr, int byte, int size) {
+  final bytes = ptr.cast<Uint8>();
+  for (var i = 0; i < size; i++) {
+    bytes[i] = byte;
+  }
+}
+
+void main() {
+  try {
+    fbMemset = DynamicLibrary.process()
+        .lookupFunction<_c_memset, _dart_memset>('memset');
+  } catch (_) {
+    // This works:
+    // fbMemset = _fallbackMemset;
+
+    // This doesn't: /aot/precompiler.cc: 2761: error: unreachable code
+    fbMemset = (Pointer<Uint8> ptr, int byte, int size) {
+      final bytes = ptr.cast<Uint8>();
+      for (var i = 0; i < size; i++) {
+        bytes[i] = byte;
+      }
+    };
+  }
+}
diff --git a/tests/ffi_2/structs_packed_test.dart b/tests/ffi_2/structs_packed_test.dart
new file mode 100644
index 0000000..cec7703
--- /dev/null
+++ b/tests/ffi_2/structs_packed_test.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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
+
+import 'dart:ffi';
+
+import "package:expect/expect.dart";
+
+import 'dylib_utils.dart';
+
+// Reuse struct definitions.
+import 'function_structs_by_value_generated_test.dart';
+
+void main() {
+  testSizeOfC();
+  testSizeOfDart();
+}
+
+final ffiTestFunctions = dlopenPlatformSpecific("ffi_test_functions");
+
+final sizeOfStruct3BytesPackedInt =
+    ffiTestFunctions.lookupFunction<Uint64 Function(), int Function()>(
+        "SizeOfStruct3BytesPackedInt");
+
+void testSizeOfC() {
+  Expect.equals(3, sizeOfStruct3BytesPackedInt());
+}
+
+void testSizeOfDart() {
+  // No packing needed to get to 3 bytes.
+  Expect.equals(3, sizeOf<Struct3BytesHomogeneousUint8>());
+
+  // Contents 3 bytes, but alignment forces it to be 4 bytes.
+  Expect.equals(4, sizeOf<Struct3BytesInt2ByteAligned>());
+
+  // Alignment gets the same content back to 3 bytes.
+  Expect.equals(3, sizeOf<Struct3BytesPackedInt>());
+}
diff --git a/tests/ffi_2/unaligned_test.dart b/tests/ffi_2/unaligned_test.dart
new file mode 100644
index 0000000..3220003
--- /dev/null
+++ b/tests/ffi_2/unaligned_test.dart
@@ -0,0 +1,74 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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 tests exercises misaligned reads/writes on memory.
+//
+// The only architecture on which this is known to fail is arm32 on Android.
+
+import 'dart:ffi';
+import 'dart:io';
+
+import 'package:expect/expect.dart';
+import 'package:ffi/ffi.dart';
+
+void main() {
+  print("hello");
+  testUnalignedInt16(); //# 01: ok
+  testUnalignedInt32(); //# 02: ok
+  testUnalignedInt64(); //# 03: ok
+  if (!Platform.isAndroid || sizeOf<Pointer>() == 8) {
+    // TODO(http://dartbug.com/45009): Support unaligned reads/writes on
+    // Android arm32.
+    testUnalignedFloat(); //# 04: ok
+    testUnalignedDouble(); //# 05: ok
+  }
+  _freeAll();
+}
+
+void testUnalignedInt16() {
+  final pointer = _allocateUnaligned<Int16>();
+  pointer.value = 20;
+  Expect.equals(20, pointer.value);
+}
+
+void testUnalignedInt32() {
+  final pointer = _allocateUnaligned<Int32>();
+  pointer.value = 20;
+  Expect.equals(20, pointer.value);
+}
+
+void testUnalignedInt64() {
+  final pointer = _allocateUnaligned<Int64>();
+  pointer.value = 20;
+  Expect.equals(20, pointer.value);
+}
+
+void testUnalignedFloat() {
+  final pointer = _allocateUnaligned<Float>();
+  pointer.value = 20.0;
+  Expect.approxEquals(20.0, pointer.value);
+}
+
+void testUnalignedDouble() {
+  final pointer = _allocateUnaligned<Double>();
+  pointer.value = 20.0;
+  Expect.equals(20.0, pointer.value);
+}
+
+final Set<Pointer> _pool = {};
+
+void _freeAll() {
+  for (final pointer in _pool) {
+    calloc.free(pointer);
+  }
+}
+
+/// Up to `size<T>() == 8`.
+Pointer<T> _allocateUnaligned<T extends NativeType>() {
+  final pointer = calloc<Int8>(16);
+  _pool.add(pointer);
+  final misaligned = pointer.elementAt(1).cast<T>();
+  Expect.equals(1, misaligned.address % 2);
+  return misaligned;
+}
diff --git a/tests/ffi_2/vmspecific_static_checks_test.dart b/tests/ffi_2/vmspecific_static_checks_test.dart
index 217df34..3ae9b04 100644
--- a/tests/ffi_2/vmspecific_static_checks_test.dart
+++ b/tests/ffi_2/vmspecific_static_checks_test.dart
@@ -58,6 +58,7 @@
   testRefStruct();
   testSizeOfGeneric();
   testSizeOfNativeType();
+  testSizeOfHandle();
   testElementAtGeneric();
   testElementAtNativeType();
 }
@@ -634,11 +635,11 @@
 }
 
 void testSizeOfNativeType() {
-  try {
-    sizeOf(); //# 1301: compile-time error
-  } catch (e) {
-    print(e);
-  }
+  sizeOf(); //# 1301: compile-time error
+}
+
+void testSizeOfHandle() {
+  sizeOf<Handle>(); //# 1302: compile-time error
 }
 
 void testElementAtGeneric() {
@@ -675,8 +676,84 @@
 }
 
 class TestStruct1402 extends Struct {
-  @Array(8) //# 1402: compile-time error
+  @Array(8, 8, 8) //# 1402: compile-time error
   Array<Array<Uint8>> a0; //# 1402: compile-time error
 
   Pointer<Uint8> notEmpty;
 }
+
+class TestStruct1403 extends Struct {
+  @Array(8, 8) //# 1403: compile-time error
+  Array<Array<Array<Uint8>>> a0; //# 1403: compile-time error
+
+  Pointer<Uint8> notEmpty;
+}
+
+class TestStruct1404 extends Struct {
+  @Array.multi([8, 8, 8]) //# 1404: compile-time error
+  Array<Array<Uint8>> a0; //# 1404: compile-time error
+
+  Pointer<Uint8> notEmpty;
+}
+
+class TestStruct1405 extends Struct {
+  @Array.multi([8, 8]) //# 1405: compile-time error
+  Array<Array<Array<Uint8>>> a0; //# 1405: compile-time error
+
+  Pointer<Uint8> notEmpty;
+}
+
+@Packed(1)
+class TestStruct1600 extends Struct {
+  Pointer<Uint8> notEmpty;
+}
+
+@Packed(1)
+@Packed(1) //# 1601: compile-time error
+class TestStruct1601 extends Struct {
+  Pointer<Uint8> notEmpty;
+}
+
+@Packed(3) //# 1602: compile-time error
+class TestStruct1602 extends Struct {
+  Pointer<Uint8> notEmpty;
+}
+
+class TestStruct1603 extends Struct {
+  Pointer<Uint8> notEmpty;
+}
+
+@Packed(1)
+class TestStruct1603Packed extends Struct {
+  Pointer<Uint8> notEmpty;
+
+  TestStruct1603 nestedNotPacked; //# 1603: compile-time error
+}
+
+@Packed(8)
+class TestStruct1604 extends Struct {
+  Pointer<Uint8> notEmpty;
+}
+
+@Packed(1)
+class TestStruct1604Packed extends Struct {
+  Pointer<Uint8> notEmpty;
+
+  TestStruct1604 nestedLooselyPacked; //# 1604: compile-time error
+}
+
+@Packed(1)
+class TestStruct1605Packed extends Struct {
+  Pointer<Uint8> notEmpty;
+
+  @Array(2) //# 1605: compile-time error
+  Array<TestStruct1603> nestedNotPacked; //# 1605: compile-time error
+}
+
+@Packed(1)
+class TestStruct1606Packed extends Struct {
+  Pointer<Uint8> notEmpty;
+
+  @Array(2) //# 1606: compile-time error
+  Array<TestStruct1604> nestedLooselyPacked; //# 1606: compile-time error
+}
diff --git a/tests/language/const_functions/const_functions_assert_statements_error_test.dart b/tests/language/const_functions/const_functions_assert_statements_error_test.dart
new file mode 100644
index 0000000..d48b87a
--- /dev/null
+++ b/tests/language/const_functions/const_functions_assert_statements_error_test.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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 assert statement exception throwing with const functions.
+
+// SharedOptions=--enable-experiment=const-functions
+
+import "package:expect/expect.dart";
+
+const var1 = fn();
+//           ^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+// [cfe] Constant evaluation error:
+int fn() {
+  int x = 1;
+  assert(x == 0, "fail");
+  return x;
+}
diff --git a/tests/language/const_functions/const_functions_assert_statements_test.dart b/tests/language/const_functions/const_functions_assert_statements_test.dart
new file mode 100644
index 0000000..1fe02bb
--- /dev/null
+++ b/tests/language/const_functions/const_functions_assert_statements_test.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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 assert statements with const functions.
+
+// SharedOptions=--enable-experiment=const-functions
+
+import "package:expect/expect.dart";
+
+const var1 = fn();
+//           ^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+int fn() {
+  int x = 0;
+  assert(x == 0, "fail");
+  return x;
+}
+
+void main() {
+  Expect.equals(var1, 0);
+}
diff --git a/tests/language/const_functions/const_functions_block_test.dart b/tests/language/const_functions/const_functions_block_test.dart
new file mode 100644
index 0000000..a258dd5
--- /dev/null
+++ b/tests/language/const_functions/const_functions_block_test.dart
@@ -0,0 +1,55 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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 blocks and scope with const functions.
+
+// SharedOptions=--enable-experiment=const-functions
+
+import "package:expect/expect.dart";
+
+void blockTest() {
+  int x() => 1;
+  const i = x();
+  //        ^^^
+  // [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+  Expect.equals(i, 1);
+  {
+    int x() => 2;
+    const y = x();
+    //        ^^^
+    // [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+    Expect.equals(y, 2);
+    {
+      int x() => 3;
+      const y = x();
+      //        ^^^
+      // [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+      Expect.equals(y, 3);
+    }
+  }
+  const z = x();
+  //        ^^^
+  // [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+  Expect.equals(z, 1);
+}
+
+void blockTest1() {
+  int x() {
+    int z = 3;
+    {
+      int z = 4;
+    }
+    return z;
+  }
+
+  const i = x();
+  //        ^^^
+  // [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+  Expect.equals(i, 3);
+}
+
+void main() {
+  blockTest();
+  blockTest1();
+}
diff --git a/tests/language/const_functions/const_functions_const_factory_disabled_test.dart b/tests/language/const_functions/const_functions_const_factory_disabled_test.dart
new file mode 100644
index 0000000..e6bf9c6
--- /dev/null
+++ b/tests/language/const_functions/const_functions_const_factory_disabled_test.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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 const factories with const functions disabled.
+
+import "package:expect/expect.dart";
+
+const printConst = MessageType.parse("print");
+
+class MessageType {
+  static const print = MessageType._('print');
+
+  static const skip = MessageType._('skip');
+
+  final String name;
+
+  const factory MessageType.parse(String name) {
+//^^^^^
+// [analyzer] SYNTACTIC_ERROR.CONST_FACTORY
+// [cfe] Only redirecting factory constructors can be declared to be 'const'.
+    if (name == 'print') {
+      return MessageType.print;
+    }
+    return MessageType.skip;
+  }
+
+  const MessageType._(this.name);
+}
diff --git a/tests/language/const_functions/const_functions_const_factory_test.dart b/tests/language/const_functions/const_functions_const_factory_test.dart
new file mode 100644
index 0000000..2ff63bc
--- /dev/null
+++ b/tests/language/const_functions/const_functions_const_factory_test.dart
@@ -0,0 +1,34 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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 const factories with const functions.
+
+// SharedOptions=--enable-experiment=const-functions
+
+import "package:expect/expect.dart";
+
+const printConst = MessageType.parse("print");
+
+class MessageType {
+  static const print = MessageType._('print');
+
+  static const skip = MessageType._('skip');
+
+  final String name;
+
+  const factory MessageType.parse(String name) {
+//^^^^^
+// [analyzer] SYNTACTIC_ERROR.CONST_FACTORY
+    if (name == 'print') {
+      return MessageType.print;
+    }
+    return MessageType.skip;
+  }
+
+  const MessageType._(this.name);
+}
+
+void main() {
+  Expect.equals(printConst, MessageType.print);
+}
diff --git a/tests/language/const_functions/const_functions_do_statements_error_test.dart b/tests/language/const_functions/const_functions_do_statements_error_test.dart
new file mode 100644
index 0000000..38a769f
--- /dev/null
+++ b/tests/language/const_functions/const_functions_do_statements_error_test.dart
@@ -0,0 +1,47 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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 erroneous do-while statements for const functions.
+
+// SharedOptions=--enable-experiment=const-functions
+
+import "package:expect/expect.dart";
+
+const var1 = fn();
+//           ^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+int fn() {
+  int x = 0;
+  do {
+    x++;
+  } while (x);
+  //       ^
+  // [analyzer] COMPILE_TIME_ERROR.NON_BOOL_CONDITION
+  // [cfe] A value of type 'int' can't be assigned to a variable of type 'bool'.
+  return 2;
+}
+
+const var2 = fn2();
+//           ^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+// [cfe] Constant evaluation error:
+int fn2() {
+  int x = 0;
+  do {
+    x++;
+  } while (x as dynamic);
+  return 2;
+}
+
+const var3 = fn3();
+//           ^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+// [cfe] Constant evaluation error:
+int fn3() {
+  dynamic x = 0;
+  do {
+    x++;
+  } while (x);
+  return 2;
+}
diff --git a/tests/language/const_functions/const_functions_do_statements_test.dart b/tests/language/const_functions/const_functions_do_statements_test.dart
new file mode 100644
index 0000000..1ca0c2b
--- /dev/null
+++ b/tests/language/const_functions/const_functions_do_statements_test.dart
@@ -0,0 +1,56 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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 do-while statements for const functions.
+
+// SharedOptions=--enable-experiment=const-functions
+
+import "package:expect/expect.dart";
+
+const var1 = fn();
+//           ^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+int fn() {
+  int x = 0;
+  do {
+    x++;
+  } while (x < 2);
+  return x;
+}
+
+const var2 = fn2(2);
+//           ^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+const var3 = fn2(10);
+//           ^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+int fn2(int a) {
+  int x = 0, b = 0;
+  do {
+    if (x > 5) break;
+    x += a;
+    b++;
+  } while (b < 2);
+  return x;
+}
+
+const var4 = fn3();
+//           ^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+int fn3() {
+  int x = 0, b = 0;
+  do {
+    x += 1;
+    if (x % 2 == 1) continue;
+    b += x;
+  } while (x < 5);
+  return b;
+}
+
+void main() {
+  Expect.equals(var1, 2);
+  Expect.equals(var2, 4);
+  Expect.equals(var3, 10);
+  Expect.equals(var4, 6);
+}
diff --git a/tests/language/const_functions/const_functions_for_statements_error_test.dart b/tests/language/const_functions/const_functions_for_statements_error_test.dart
new file mode 100644
index 0000000..86b9908
--- /dev/null
+++ b/tests/language/const_functions/const_functions_for_statements_error_test.dart
@@ -0,0 +1,47 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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 erroneous for statements for const functions.
+
+// SharedOptions=--enable-experiment=const-functions
+
+import "package:expect/expect.dart";
+
+const var1 = fn();
+//           ^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+int fn() {
+  int val = 0;
+  for (; val;) {
+    //   ^^^
+    // [analyzer] COMPILE_TIME_ERROR.NON_BOOL_CONDITION
+    // [cfe] A value of type 'int' can't be assigned to a variable of type 'bool'.
+    val += 1;
+  }
+  return val;
+}
+
+const var2 = fn2();
+//           ^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+// [cfe] Constant evaluation error:
+int fn2() {
+  int val = 0;
+  for (; val as dynamic;) {
+    val += 1;
+  }
+  return val;
+}
+
+const var3 = fn3();
+//           ^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+// [cfe] Constant evaluation error:
+int fn3() {
+  dynamic val = 0;
+  for (; val;) {
+    val += 1;
+  }
+  return val;
+}
diff --git a/tests/language/const_functions/const_functions_for_statements_test.dart b/tests/language/const_functions/const_functions_for_statements_test.dart
new file mode 100644
index 0000000..781b76b
--- /dev/null
+++ b/tests/language/const_functions/const_functions_for_statements_test.dart
@@ -0,0 +1,114 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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 for statements for const functions.
+
+// SharedOptions=--enable-experiment=const-functions
+
+import "package:expect/expect.dart";
+
+const var1 = fn(2);
+//           ^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+const var2 = fn(3);
+//           ^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+int fn(int a) {
+  int b = a;
+  for (int i = 0; i < 2; i++) {
+    b += a;
+  }
+  return b;
+}
+
+const var3 = fn1(2);
+//           ^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+const var4 = fn1(3);
+//           ^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+int fn1(int a) {
+  int b = a;
+  for (int i = 0;; i++) {
+    b *= 3;
+    if (b > 10) return b;
+  }
+}
+
+const var5 = fn2();
+//           ^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+int fn2() {
+  for (int i = 0, j = 2;; i += 2, j += 1) {
+    if (i + j > 10) {
+      return i + j;
+    }
+  }
+}
+
+const var6 = fnContinue();
+//           ^^^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+int fnContinue() {
+  int a = 0;
+  for (int i = 0; i < 5; i++) {
+    if (i % 2 == 1) continue;
+    a += i;
+  }
+  return a;
+}
+
+const var7 = fnBreak(2);
+//           ^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+const var8 = fnBreak(3);
+//           ^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+int fnBreak(int a) {
+  int b = a;
+  for (int i = 0; i < 2; i++) {
+    if (b == 2) break;
+    b += a;
+  }
+  return b;
+}
+
+const var9 = fnNestedFor();
+//           ^^^^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+int fnNestedFor() {
+  int a = 0;
+  for (;;) {
+    for (;;) {
+      break;
+    }
+    return 1;
+  }
+}
+
+const var10 = fnBreakLabel();
+//            ^^^^^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+int fnBreakLabel() {
+  foo:
+  for (;;) {
+    for (;;) {
+      break foo;
+    }
+  }
+  return 3;
+}
+
+void main() {
+  Expect.equals(var1, 6);
+  Expect.equals(var2, 9);
+  Expect.equals(var3, 18);
+  Expect.equals(var4, 27);
+  Expect.equals(var5, 11);
+  Expect.equals(var6, 6);
+  Expect.equals(var7, 2);
+  Expect.equals(var8, 9);
+  Expect.equals(var9, 1);
+  Expect.equals(var10, 3);
+}
diff --git a/tests/language/const_functions/const_functions_if_statements_error_test.dart b/tests/language/const_functions/const_functions_if_statements_error_test.dart
new file mode 100644
index 0000000..31a25d5
--- /dev/null
+++ b/tests/language/const_functions/const_functions_if_statements_error_test.dart
@@ -0,0 +1,47 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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 erroneous if statements for const functions.
+
+// SharedOptions=--enable-experiment=const-functions
+
+import "package:expect/expect.dart";
+
+const var1 = fn();
+//           ^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+int fn() {
+  int val = 0;
+  if (val) {
+    //^^^
+    // [analyzer] COMPILE_TIME_ERROR.NON_BOOL_CONDITION
+    // [cfe] A value of type 'int' can't be assigned to a variable of type 'bool'.
+    val += 1;
+  }
+  return val;
+}
+
+const var2 = fn2();
+//           ^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+// [cfe] Constant evaluation error:
+int fn2() {
+  int val = 0;
+  if (val as dynamic) {
+    val += 1;
+  }
+  return val;
+}
+
+const var3 = fn3();
+//           ^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+// [cfe] Constant evaluation error:
+int fn3() {
+  dynamic val = 0;
+  if (val) {
+    val += 1;
+  }
+  return val;
+}
diff --git a/tests/language/const_functions/const_functions_if_statements_test.dart b/tests/language/const_functions/const_functions_if_statements_test.dart
new file mode 100644
index 0000000..e4998ee
--- /dev/null
+++ b/tests/language/const_functions/const_functions_if_statements_test.dart
@@ -0,0 +1,97 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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 if statements for const functions.
+
+// SharedOptions=--enable-experiment=const-functions
+
+import "package:expect/expect.dart";
+
+const var1 = ifTest(1);
+//           ^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+const var2 = ifTest(2);
+//           ^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+const var3 = ifTest(3);
+//           ^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+int ifTest(int a) {
+  if (a == 1) {
+    return 100;
+  } else if (a == 2) {
+    return 200;
+  } else {
+    return 300;
+  }
+}
+
+const one = 1;
+const var4 = ifTest2(1);
+//           ^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+const var5 = ifTest2(2);
+//           ^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+int ifTest2(int a) {
+  if (a == one) {
+    return 100;
+  } else {
+    return 200;
+  }
+}
+
+const var6 = ifTest3(1);
+//           ^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+const var6_1 = ifTest3(2);
+//             ^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+const var6_2 = ifTest3(0);
+//             ^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+int ifTest3(int a) {
+  if (a > 0) {
+    if (a == 1) return 100;
+    return 200;
+  }
+  return 300;
+}
+
+const var7 = ifTest4(1);
+//           ^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+int ifTest4(int a) {
+  int b = a;
+  if (a == 1) {
+    b += a;
+    if (a % 2 == 1) {
+      b += a;
+    }
+  } else if (a == 2) {
+    b -= a;
+  }
+
+  return b;
+}
+
+const var8 = ifTest5();
+//           ^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+int ifTest5() {
+  var x = 10;
+  if (true) var x = 20;
+  return x;
+}
+
+void main() {
+  Expect.equals(var1, 100);
+  Expect.equals(var2, 200);
+  Expect.equals(var3, 300);
+  Expect.equals(var4, 100);
+  Expect.equals(var5, 200);
+  Expect.equals(var6, 100);
+  Expect.equals(var7, 3);
+  Expect.equals(var8, 10);
+}
diff --git a/tests/language/const_functions/const_functions_local_functions_test.dart b/tests/language/const_functions/const_functions_local_functions_test.dart
new file mode 100644
index 0000000..1358e62
--- /dev/null
+++ b/tests/language/const_functions/const_functions_local_functions_test.dart
@@ -0,0 +1,93 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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 local function usage, some having references to other constant values.
+
+// SharedOptions=--enable-experiment=const-functions
+
+import "package:expect/expect.dart";
+
+int function1() {
+  int add(int a, int b) => a + b;
+  const value = add(10, 2);
+  //            ^^^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+  return value;
+}
+
+const constTwo = 2;
+int function2() {
+  int addTwo(int a) {
+    int b = a + constTwo;
+    return b;
+  }
+
+  const value = addTwo(2);
+  //            ^^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+  return value;
+}
+
+int function3() {
+  int addTwoReturn(int a) => a + constTwo;
+  const value = addTwoReturn(3);
+  //            ^^^^^^^^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+  return value;
+}
+
+int function4() {
+  const localTwo = 2;
+  int addTwo(int a) => a + localTwo;
+  const value = addTwo(20);
+  //            ^^^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+  return value;
+}
+
+int function5() {
+  T typeFn<T>(T a) => a;
+  const value = typeFn(3);
+  //            ^^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+  return value;
+}
+
+int function6() {
+  int optionalFn([int a = 0]) => a;
+  const value = optionalFn(1);
+  //            ^^^^^^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+  return value;
+}
+
+int function7() {
+  int namedFn({int a = 0}) => a;
+  const value = namedFn(a: 2);
+  //            ^^^^^^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+  return value;
+}
+
+int function8() {
+  int add(int a, int b) => a + b;
+  const value = add(1, 1);
+  //            ^^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+  const value1 = add(2, 3);
+  //             ^^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+  return value + value1;
+}
+
+void main() {
+  Expect.equals(function1(), 12);
+  Expect.equals(function2(), 4);
+  Expect.equals(function3(), 5);
+  Expect.equals(function4(), 22);
+  Expect.equals(function5(), 3);
+  Expect.equals(function6(), 1);
+  Expect.equals(function7(), 2);
+  Expect.equals(function8(), 7);
+}
diff --git a/tests/language/const_functions/const_functions_recursion_error_test.dart b/tests/language/const_functions/const_functions_recursion_error_test.dart
new file mode 100644
index 0000000..f4332a9
--- /dev/null
+++ b/tests/language/const_functions/const_functions_recursion_error_test.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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 recursive function calls for const functions which have a cycle in the
+// dependencies.
+
+// SharedOptions=--enable-experiment=const-functions
+
+import "package:expect/expect.dart";
+
+const dependsOnB = b;
+//                 ^
+// [cfe] Constant evaluation error:
+const b = fn(4);
+//        ^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+int fn(int a) {
+  if (a == 1) return dependsOnB;
+  return dependsOnB * fn(a - 1);
+}
diff --git a/tests/language/const_functions/const_functions_recursion_test.dart b/tests/language/const_functions/const_functions_recursion_test.dart
new file mode 100644
index 0000000..c1343b1
--- /dev/null
+++ b/tests/language/const_functions/const_functions_recursion_test.dart
@@ -0,0 +1,34 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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 recursive function calls for const functions.
+
+// SharedOptions=--enable-experiment=const-functions
+
+import "package:expect/expect.dart";
+
+const b = fn(4);
+//        ^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+int fn(int a) {
+  if (a == 1) return 1;
+  return a * fn(a - 1);
+}
+
+int localTest() {
+  int fnLocal(int a) {
+    if (a == 1) return 1;
+    return a * fnLocal(a - 1);
+  }
+
+  const c = fnLocal(4);
+  //        ^^^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+  return c;
+}
+
+void main() {
+  Expect.equals(b, 24);
+  Expect.equals(localTest(), 24);
+}
diff --git a/tests/language/const_functions/const_functions_simple_invocations_test.dart b/tests/language/const_functions/const_functions_simple_invocations_test.dart
index 2280197..9c51ea6 100644
--- a/tests/language/const_functions/const_functions_simple_invocations_test.dart
+++ b/tests/language/const_functions/const_functions_simple_invocations_test.dart
@@ -59,6 +59,14 @@
 // [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
 double doubleFn(double a, double b) => a * b;
 
+const multi = multiFn(1);
+//            ^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+const multi2 = multiFn(2);
+//             ^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+int multiFn(int a) => a + 1;
+
 void main() {
   Expect.equals(binary, 1);
   Expect.equals(optional, 2);
@@ -71,4 +79,6 @@
   Expect.equals(neg, -2);
   Expect.equals(boolean, true);
   Expect.equals(doub, 4.4);
+  Expect.equals(multi, 2);
+  Expect.equals(multi2, 3);
 }
diff --git a/tests/language/const_functions/const_functions_switch_statements_error_test.dart b/tests/language/const_functions/const_functions_switch_statements_error_test.dart
new file mode 100644
index 0000000..659e3a4
--- /dev/null
+++ b/tests/language/const_functions/const_functions_switch_statements_error_test.dart
@@ -0,0 +1,43 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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 erroneous switch statements for const functions.
+
+// SharedOptions=--enable-experiment=const-functions
+
+import "package:expect/expect.dart";
+
+const var1 = labelDoesNotExistSwitch(1);
+//           ^^^^^^^^^^^^^^^^^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+int labelDoesNotExistSwitch(int x) {
+  switch (x) {
+    labelOtherSwitch:
+    case 1:
+      break;
+  }
+  switch (x) {
+    case 1:
+      continue labelOtherSwitch;
+//    ^
+// [cfe] Can't find label 'labelOtherSwitch'.
+//             ^^^^^^^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.LABEL_UNDEFINED
+  }
+  return 0;
+}
+
+const var2 = wrongTypeSwitch(1);
+//           ^^^^^^^^^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+int wrongTypeSwitch(int x) {
+  switch (x) {
+    case "string":
+      // ^^^^^^^^
+      // [analyzer] COMPILE_TIME_ERROR.CASE_EXPRESSION_TYPE_IS_NOT_SWITCH_EXPRESSION_SUBTYPE
+      // [cfe] Type 'String' of the case expression is not a subtype of type 'int' of this switch expression.
+      return 100;
+  }
+  return 0;
+}
diff --git a/tests/language/const_functions/const_functions_switch_statements_test.dart b/tests/language/const_functions/const_functions_switch_statements_test.dart
new file mode 100644
index 0000000..dd1e5c1
--- /dev/null
+++ b/tests/language/const_functions/const_functions_switch_statements_test.dart
@@ -0,0 +1,85 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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 switch statements for const functions.
+
+// SharedOptions=--enable-experiment=const-functions
+
+import "package:expect/expect.dart";
+
+const var1 = basicSwitch(1);
+//           ^^^^^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+const var2 = basicSwitch(2);
+//           ^^^^^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+int basicSwitch(int x) {
+  switch (x) {
+    case 1:
+      return 100;
+    default:
+      x++;
+      break;
+  }
+  return x;
+}
+
+const var3 = multipleCaseSwitch(1);
+//           ^^^^^^^^^^^^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+const var4 = multipleCaseSwitch(2);
+//           ^^^^^^^^^^^^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+const var5 = multipleCaseSwitch(3);
+//           ^^^^^^^^^^^^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+int multipleCaseSwitch(int x) {
+  switch (x) {
+    case 1:
+    case 2:
+      return 100;
+    default:
+      break;
+  }
+  return 0;
+}
+
+const var6 = continueLabelSwitch(1);
+//           ^^^^^^^^^^^^^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+const var7 = continueLabelSwitch(2);
+//           ^^^^^^^^^^^^^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+const var8 = continueLabelSwitch(3);
+//           ^^^^^^^^^^^^^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+const var9 = continueLabelSwitch(4);
+//           ^^^^^^^^^^^^^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+int continueLabelSwitch(int x) {
+  switch (x) {
+    label1:
+    case 1:
+      x = x + 100;
+      continue label3;
+    case 2:
+      continue label1;
+    label3:
+    case 3:
+      return x + 3;
+  }
+  return 0;
+}
+
+void main() {
+  Expect.equals(var1, 100);
+  Expect.equals(var2, 3);
+  Expect.equals(var3, 100);
+  Expect.equals(var4, 100);
+  Expect.equals(var5, 0);
+  Expect.equals(var6, 104);
+  Expect.equals(var7, 105);
+  Expect.equals(var8, 6);
+  Expect.equals(var9, 0);
+}
diff --git a/tests/language/const_functions/const_functions_variable_assignments_test.dart b/tests/language/const_functions/const_functions_variable_assignments_test.dart
new file mode 100644
index 0000000..0348ee6
--- /dev/null
+++ b/tests/language/const_functions/const_functions_variable_assignments_test.dart
@@ -0,0 +1,52 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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 variable assignments for const functions.
+
+// SharedOptions=--enable-experiment=const-functions
+
+import "package:expect/expect.dart";
+
+const var1 = varAssignmentTest(1);
+//           ^^^^^^^^^^^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+int varAssignmentTest(int a) {
+  int x = 4;
+  {
+    x = 3;
+  }
+  return x;
+}
+
+int function() {
+  int varAssignmentTest2() {
+    int x = 2;
+    x += 1;
+    return x;
+  }
+
+  const var2 = varAssignmentTest2();
+  //           ^^^^^^^^^^^^^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+  return var2;
+}
+
+const var3 = varAssignmentTest3(1);
+//           ^^^^^^^^^^^^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+const var4 = varAssignmentTest3(2);
+//           ^^^^^^^^^^^^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+int varAssignmentTest3(int a) {
+  int x = 4;
+  x = a + 1;
+  return x;
+}
+
+void main() {
+  Expect.equals(var1, 3);
+  Expect.equals(function(), 3);
+  Expect.equals(var3, 2);
+  Expect.equals(var4, 3);
+}
diff --git a/tests/language/const_functions/const_functions_variable_declarations_test.dart b/tests/language/const_functions/const_functions_variable_declarations_test.dart
new file mode 100644
index 0000000..492a8cc
--- /dev/null
+++ b/tests/language/const_functions/const_functions_variable_declarations_test.dart
@@ -0,0 +1,63 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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 creating new local variables within const functions.
+
+// SharedOptions=--enable-experiment=const-functions
+
+import "package:expect/expect.dart";
+
+const var1 = function1(1, 2);
+//           ^^^^^^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+const var1_1 = function1(2, 2);
+//             ^^^^^^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+int function1(int a, int b) {
+  var x = 1 + a + b;
+  return x;
+}
+
+const var2 = function2();
+//           ^^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+String function2() {
+  dynamic x = "string";
+  return x;
+}
+
+const var3 = function3();
+//           ^^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+int function3() {
+  var first = 2;
+  var second = 2 + first;
+  return 2 + second;
+}
+
+const var4 = function4();
+//           ^^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+int function4() {
+  var first = 2;
+  var second = 0;
+  return first + second;
+}
+
+const var5 = function5();
+//           ^^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+int function5() {
+  const constant = -2;
+  return constant;
+}
+
+void main() {
+  Expect.equals(var1, 4);
+  Expect.equals(var1_1, 5);
+  Expect.equals(var2, "string");
+  Expect.equals(var3, 6);
+  Expect.equals(var4, 2);
+  Expect.equals(var5, -2);
+}
diff --git a/tests/language/const_functions/const_functions_while_statements_error_test.dart b/tests/language/const_functions/const_functions_while_statements_error_test.dart
new file mode 100644
index 0000000..1b7bc18
--- /dev/null
+++ b/tests/language/const_functions/const_functions_while_statements_error_test.dart
@@ -0,0 +1,47 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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 erroneous while statements for const functions.
+
+// SharedOptions=--enable-experiment=const-functions
+
+import "package:expect/expect.dart";
+
+const var1 = fn();
+//           ^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+int fn() {
+  int val = 0;
+  while (val) {
+    //   ^^^
+    // [analyzer] COMPILE_TIME_ERROR.NON_BOOL_CONDITION
+    // [cfe] A value of type 'int' can't be assigned to a variable of type 'bool'.
+    val += 1;
+  }
+  return val;
+}
+
+const var2 = fn2();
+//           ^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+// [cfe] Constant evaluation error:
+int fn2() {
+  int val = 0;
+  while (val as dynamic) {
+    val += 1;
+  }
+  return val;
+}
+
+const var3 = fn3();
+//           ^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+// [cfe] Constant evaluation error:
+int fn3() {
+  dynamic val = 0;
+  while (val) {
+    val += 1;
+  }
+  return val;
+}
diff --git a/tests/language/const_functions/const_functions_while_statements_test.dart b/tests/language/const_functions/const_functions_while_statements_test.dart
new file mode 100644
index 0000000..40e68f5
--- /dev/null
+++ b/tests/language/const_functions/const_functions_while_statements_test.dart
@@ -0,0 +1,111 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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 while statements for const functions.
+
+// SharedOptions=--enable-experiment=const-functions
+
+import "package:expect/expect.dart";
+
+const var1 = fn(2);
+//           ^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+const var2 = fn(3);
+//           ^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+int fn(int a) {
+  int b = a;
+  int i = 0;
+  while (i < 2) {
+    b += a;
+    i++;
+  }
+  return b;
+}
+
+const var3 = fn1(2);
+//           ^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+const var4 = fn1(3);
+//           ^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+int fn1(int a) {
+  int b = a;
+  while (true) {
+    b *= 3;
+    if (b > 10) return b;
+  }
+}
+
+const var5 = fnContinue();
+//           ^^^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+int fnContinue() {
+  int a = 0;
+  int i = 0;
+  while (i < 5) {
+    if (i % 2 == 1) {
+      i++;
+      continue;
+    }
+    a += i;
+    i++;
+  }
+  return a;
+}
+
+const var6 = fnBreak(2);
+//           ^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+const var7 = fnBreak(3);
+//           ^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+int fnBreak(int a) {
+  int b = a;
+  int i = 0;
+  while (i < 2) {
+    if (b == 2) break;
+    b += a;
+    i++;
+  }
+  return b;
+}
+
+const var8 = fnNestedWhile();
+//           ^^^^^^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+int fnNestedWhile() {
+  int a = 0;
+  while (true) {
+    while (true) {
+      break;
+    }
+    return 1;
+  }
+}
+
+const var9 = fnBreakLabel();
+//           ^^^^^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+int fnBreakLabel() {
+  foo:
+  while (true) {
+    while (true) {
+      break foo;
+    }
+  }
+  return 3;
+}
+
+void main() {
+  Expect.equals(var1, 6);
+  Expect.equals(var2, 9);
+  Expect.equals(var3, 18);
+  Expect.equals(var4, 27);
+  Expect.equals(var5, 6);
+  Expect.equals(var6, 2);
+  Expect.equals(var7, 9);
+  Expect.equals(var8, 1);
+  Expect.equals(var9, 3);
+}
diff --git a/tests/language/deferred/inheritance_constraints_test.dart b/tests/language/deferred/inheritance_constraints_test.dart
index 2d9429b..7477a57 100644
--- a/tests/language/deferred/inheritance_constraints_test.dart
+++ b/tests/language/deferred/inheritance_constraints_test.dart
@@ -11,17 +11,17 @@
 
 class A extends lib.Foo {}
 //              ^^^^^^^
-// [analyzer] COMPILE_TIME_ERROR.EXTENDS_DEFERRED_CLASS
+// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_DEFERRED_CLASS
 
 class B implements lib.Foo {}
 //                 ^^^^^^^
-// [analyzer] COMPILE_TIME_ERROR.IMPLEMENTS_DEFERRED_CLASS
+// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_DEFERRED_CLASS
 
 class C1 {}
 
 class C = C1 with lib.Foo;
 //                ^^^^^^^
-// [analyzer] COMPILE_TIME_ERROR.MIXIN_DEFERRED_CLASS
+// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_DEFERRED_CLASS
 
 class D {
   D();
diff --git a/tests/language/deferred/load_constants_test.dart b/tests/language/deferred/load_constants_test.dart
index a57e24c..546b038 100644
--- a/tests/language/deferred/load_constants_test.dart
+++ b/tests/language/deferred/load_constants_test.dart
@@ -28,31 +28,31 @@
     //                  ^
     // [cfe] Constant evaluation error:
     //                         ^^^^^
-    // [analyzer] COMPILE_TIME_ERROR.NON_CONSTANT_LIST_ELEMENT_FROM_DEFERRED_LIBRARY
+    // [analyzer] COMPILE_TIME_ERROR.COLLECTION_ELEMENT_FROM_DEFERRED_LIBRARY
     // [cfe] 'foo' can't be used in a constant expression because it's marked as 'deferred' which means it isn't available until loaded.
     Expect.throws(() => const [foo.C]);
     //                  ^
     // [cfe] Constant evaluation error:
     //                         ^^^^^
-    // [analyzer] COMPILE_TIME_ERROR.NON_CONSTANT_LIST_ELEMENT_FROM_DEFERRED_LIBRARY
+    // [analyzer] COMPILE_TIME_ERROR.COLLECTION_ELEMENT_FROM_DEFERRED_LIBRARY
     // [cfe] 'foo' can't be used in a constant expression because it's marked as 'deferred' which means it isn't available until loaded.
     Expect.throws(() => const [foo.funtype]);
     //                  ^
     // [cfe] Constant evaluation error:
     //                         ^^^^^^^^^^^
-    // [analyzer] COMPILE_TIME_ERROR.NON_CONSTANT_LIST_ELEMENT_FROM_DEFERRED_LIBRARY
+    // [analyzer] COMPILE_TIME_ERROR.COLLECTION_ELEMENT_FROM_DEFERRED_LIBRARY
     // [cfe] 'foo' can't be used in a constant expression because it's marked as 'deferred' which means it isn't available until loaded.
     Expect.throws(() => const [foo.toplevel]);
     //                  ^
     // [cfe] Constant evaluation error:
     //                         ^^^^^^^^^^^^
-    // [analyzer] COMPILE_TIME_ERROR.NON_CONSTANT_LIST_ELEMENT_FROM_DEFERRED_LIBRARY
+    // [analyzer] COMPILE_TIME_ERROR.COLLECTION_ELEMENT_FROM_DEFERRED_LIBRARY
     // [cfe] 'foo' can't be used in a constant expression because it's marked as 'deferred' which means it isn't available until loaded.
     Expect.throws(() => const [foo.C.staticfun]);
     //                  ^
     // [cfe] Constant evaluation error:
     //                         ^^^^^^^^^^^^^^^
-    // [analyzer] COMPILE_TIME_ERROR.NON_CONSTANT_LIST_ELEMENT_FROM_DEFERRED_LIBRARY
+    // [analyzer] COMPILE_TIME_ERROR.COLLECTION_ELEMENT_FROM_DEFERRED_LIBRARY
     // [cfe] 'foo' can't be used in a constant expression because it's marked as 'deferred' which means it isn't available until loaded.
 
     asyncEnd();
diff --git a/tests/language/extension_methods/issue_45551_error_test.dart b/tests/language/extension_methods/issue_45551_error_test.dart
new file mode 100644
index 0000000..524b4f6
--- /dev/null
+++ b/tests/language/extension_methods/issue_45551_error_test.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for 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 illustrates the error scenario described in
+// https://github.com/dart-lang/sdk/issues/45551
+
+class C {}
+
+extension on C {
+  void Function() get call => () {};
+}
+
+test(C c) {
+  c();
+//^
+// [analyzer] COMPILE_TIME_ERROR.INVOCATION_OF_NON_FUNCTION_EXPRESSION
+// ^
+// [cfe] Cannot invoke an instance of 'C' because it declares 'call' to be something other than a method.
+}
+
+main() {}
diff --git a/tests/language/extension_methods/static_extension_this_not_promoted_error_test.dart b/tests/language/extension_methods/static_extension_this_not_promoted_error_test.dart
index 342ccca..bedb6da 100644
--- a/tests/language/extension_methods/static_extension_this_not_promoted_error_test.dart
+++ b/tests/language/extension_methods/static_extension_this_not_promoted_error_test.dart
@@ -15,7 +15,7 @@
   void testCQuestion() {
     if (this != null) {
       f(this.cProp);
-      //^^^^
+      //     ^^^^^
       // [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
       //     ^
       // [cfe] Property 'cProp' cannot be accessed on 'C?' because it is potentially null.
diff --git a/tests/language/generic/function_typedef2_test.dart b/tests/language/generic/function_typedef2_test.dart
index 0ad79c5..22fd248 100644
--- a/tests/language/generic/function_typedef2_test.dart
+++ b/tests/language/generic/function_typedef2_test.dart
@@ -3,6 +3,10 @@
 // BSD-style license that can be found in the LICENSE file.
 // Dart test for a function type test that cannot be eliminated at compile time.
 
+// This test validates the static errors for typedefs in language versions
+// prior to the release of nonfunction type aliases (Dart 2.13).
+// @dart=2.12
+
 import "package:expect/expect.dart";
 
 class A {}
@@ -11,19 +15,19 @@
 
 typedef G = F;
 //        ^
-// [analyzer] SYNTACTIC_ERROR.INVALID_GENERIC_FUNCTION_TYPE
+// [analyzer] SYNTACTIC_ERROR.EXPERIMENT_NOT_ENABLED
 // [cfe] Can't create typedef from non-function type.
 typedef H = int;
 //        ^
-// [analyzer] SYNTACTIC_ERROR.INVALID_GENERIC_FUNCTION_TYPE
+// [analyzer] SYNTACTIC_ERROR.EXPERIMENT_NOT_ENABLED
 // [cfe] Can't create typedef from non-function type.
 typedef I = A;
 //        ^
-// [analyzer] SYNTACTIC_ERROR.INVALID_GENERIC_FUNCTION_TYPE
+// [analyzer] SYNTACTIC_ERROR.EXPERIMENT_NOT_ENABLED
 // [cfe] Can't create typedef from non-function type.
 typedef J = List<int>;
 //        ^
-// [analyzer] SYNTACTIC_ERROR.INVALID_GENERIC_FUNCTION_TYPE
+// [analyzer] SYNTACTIC_ERROR.EXPERIMENT_NOT_ENABLED
 // [cfe] Can't create typedef from non-function type.
 typedef K = Function(Function<A>(A<int>));
 //                               ^^^^^^
diff --git a/tests/language/generic/function_typedef3_test.dart b/tests/language/generic/function_typedef3_test.dart
new file mode 100644
index 0000000..47c3838
--- /dev/null
+++ b/tests/language/generic/function_typedef3_test.dart
@@ -0,0 +1,47 @@
+// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test for a function type test that cannot be eliminated at compile time.
+
+// This test validates the static errors for typedefs as per the code in
+// function_typedef2_test.dart in language versions after the release of
+// nonfunction type aliases (Dart 2.13).
+
+import "package:expect/expect.dart";
+
+class A {}
+
+typedef int F();
+
+typedef G = F;
+
+typedef H = int;
+
+typedef I = A;
+
+typedef J = List<int>;
+
+typedef K = Function(Function<A>(A<int>));
+//                               ^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.WRONG_NUMBER_OF_TYPE_ARGUMENTS
+// [cfe] Can't use type arguments with type variable 'A'.
+typedef L = Function({x});
+//                    ^
+// [analyzer] COMPILE_TIME_ERROR.UNDEFINED_CLASS
+// [cfe] Type 'x' not found.
+//                     ^
+// [analyzer] SYNTACTIC_ERROR.MISSING_IDENTIFIER
+// [cfe] Expected an identifier, but got '}'.
+
+typedef M = Function({int});
+        //               ^
+        // [analyzer] SYNTACTIC_ERROR.MISSING_IDENTIFIER
+        // [cfe] Expected an identifier, but got '}'.
+
+foo({bool int = false}) {}
+main() {
+  bool b = true;
+  Expect.isFalse(b is L);
+  Expect.isFalse(b is M);
+  Expect.isTrue(foo is M);
+}
diff --git a/tests/language/generic/generic_function_type_argument_test.dart b/tests/language/generic/generic_function_type_argument_test.dart
index c51c674..c54516f 100644
--- a/tests/language/generic/generic_function_type_argument_test.dart
+++ b/tests/language/generic/generic_function_type_argument_test.dart
@@ -28,7 +28,7 @@
 typedef FB<T extends F> = S Function<S extends T>(S);
 
 // For a class:
-class CB<T extends F> {
+class CB<T extends FB<F>> {
   final T function;
   const CB(this.function);
 }
diff --git a/tests/language/language_dart2js.status b/tests/language/language_dart2js.status
index aaaf533..7b214ff 100644
--- a/tests/language/language_dart2js.status
+++ b/tests/language/language_dart2js.status
@@ -14,6 +14,7 @@
 
 [ $builder_tag == dart2js_production && $compiler == dart2js ]
 control_flow_collections/for_non_bool_condition_test: Crash # Issue 36442
+regress/regress45428_test: SkipByDesign # No argument type checks in production mode, issue 45528
 
 [ $compiler == dart2js && $runtime == chromeOnAndroid ]
 override_field_test/02: Slow, Pass # TODO(kasperl): Please triage.
diff --git a/tests/language/language_dartdevc.status b/tests/language/language_dartdevc.status
index 0c012d1..5ab9a1e 100644
--- a/tests/language/language_dartdevc.status
+++ b/tests/language/language_dartdevc.status
@@ -5,10 +5,6 @@
 # Sections in this file should contain "$compiler == dartdevc" or dartdevk.
 [ $compiler == dartdevc ]
 class/large_class_declaration_test: Slow, Pass
-const/double_in_int_op_test/dd6: Skip # Triple shift
-const/double_in_int_op_test/di6: Skip # Triple shift
-const/double_in_int_op_test/id6: Skip # Triple shift
-const/double_in_int_op_test/ii6: Skip # Triple shift
 extension_methods/*: SkipByDesign # Analyzer DDC is expected to be turned down before releasing extension methods.
 nnbd/*: Skip
 variance/*: SkipByDesign # Analyzer DDC is expected to be turned down before releasing variance.
diff --git a/tests/language/list/literal5_test.dart b/tests/language/list/literal5_test.dart
index a1cbe6a..ea27f04 100644
--- a/tests/language/list/literal5_test.dart
+++ b/tests/language/list/literal5_test.dart
@@ -6,13 +6,7 @@
 
 main() {
   new List<int>[1, 2];
-  //  ^^^^^^^^^
-  // [analyzer] COMPILE_TIME_ERROR.DEFAULT_LIST_CONSTRUCTOR
-  // [cfe] Can't use the default List constructor.
-  //          ^
-  // [analyzer] SYNTACTIC_ERROR.EXPECTED_TOKEN
-  // [cfe] Expected '(' after this.
-  //             ^
-  // [analyzer] SYNTACTIC_ERROR.EXPECTED_TOKEN
-  // [cfe] Expected ']' before this.
+//^^^^^^^^
+// [analyzer] SYNTACTIC_ERROR.LITERAL_WITH_CLASS_AND_NEW
+// [cfe] A list literal can't be prefixed by 'new List'.
 }
diff --git a/tests/language/map/literal13_test.dart b/tests/language/map/literal13_test.dart
index 08f06e4..1ab622b2 100644
--- a/tests/language/map/literal13_test.dart
+++ b/tests/language/map/literal13_test.dart
@@ -6,76 +6,19 @@
 
 main() {
   var map = new Map<int>{ "a": 1, "b": 2, "c": 3 };
-  //            ^^^^^^^^
-  // [analyzer] COMPILE_TIME_ERROR.WRONG_NUMBER_OF_TYPE_ARGUMENTS
-  // [cfe] Expected 2 type arguments.
-  //                   ^
-  // [analyzer] SYNTACTIC_ERROR.EXPECTED_TOKEN
-  // [cfe] Expected '(' after this.
-  //                    ^
-  // [analyzer] SYNTACTIC_ERROR.EXPECTED_TOKEN
-  // [cfe] Expected ';' after this.
-  //                      ^^^
-  // [analyzer] SYNTACTIC_ERROR.EXPECTED_TOKEN
-  // [cfe] Expected ';' after this.
+  //        ^^^^^^^
+  // [analyzer] SYNTACTIC_ERROR.LITERAL_WITH_CLASS_AND_NEW
+  // [cfe] A map literal can't be prefixed by 'new Map'.
+  //                      ^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.MAP_ENTRY_NOT_IN_MAP
   //                         ^
-  // [analyzer] SYNTACTIC_ERROR.EXPECTED_TOKEN
-  // [cfe] Expected ';' after this.
-  //                         ^
-  // [analyzer] SYNTACTIC_ERROR.MISSING_IDENTIFIER
-  // [cfe] Expected an identifier, but got ':'.
-  //                         ^
-  // [analyzer] SYNTACTIC_ERROR.UNEXPECTED_TOKEN
-  // [cfe] Unexpected token ':'.
-  //                           ^
-  // [analyzer] SYNTACTIC_ERROR.EXPECTED_TOKEN
-  // [cfe] Expected ';' after this.
-  //                            ^
-  // [analyzer] SYNTACTIC_ERROR.EXPECTED_TOKEN
-  // [cfe] Expected ';' after this.
-  //                            ^
-  // [analyzer] SYNTACTIC_ERROR.MISSING_IDENTIFIER
-  // [cfe] Expected an identifier, but got ','.
-  //                            ^
-  // [analyzer] SYNTACTIC_ERROR.UNEXPECTED_TOKEN
-  // [cfe] Unexpected token ','.
-  //                              ^^^
-  // [analyzer] SYNTACTIC_ERROR.EXPECTED_TOKEN
-  // [cfe] Expected ';' after this.
+  // [cfe] Expected ',' before this.
+  //                              ^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.MAP_ENTRY_NOT_IN_MAP
   //                                 ^
-  // [analyzer] SYNTACTIC_ERROR.EXPECTED_TOKEN
-  // [cfe] Expected ';' after this.
-  //                                 ^
-  // [analyzer] SYNTACTIC_ERROR.MISSING_IDENTIFIER
-  // [cfe] Expected an identifier, but got ':'.
-  //                                 ^
-  // [analyzer] SYNTACTIC_ERROR.UNEXPECTED_TOKEN
-  // [cfe] Unexpected token ':'.
-  //                                   ^
-  // [analyzer] SYNTACTIC_ERROR.EXPECTED_TOKEN
-  // [cfe] Expected ';' after this.
-  //                                    ^
-  // [analyzer] SYNTACTIC_ERROR.EXPECTED_TOKEN
-  // [cfe] Expected ';' after this.
-  //                                    ^
-  // [analyzer] SYNTACTIC_ERROR.MISSING_IDENTIFIER
-  // [cfe] Expected an identifier, but got ','.
-  //                                    ^
-  // [analyzer] SYNTACTIC_ERROR.UNEXPECTED_TOKEN
-  // [cfe] Unexpected token ','.
-  //                                      ^^^
-  // [analyzer] SYNTACTIC_ERROR.EXPECTED_TOKEN
-  // [cfe] Expected ';' after this.
+  // [cfe] Expected ',' before this.
+  //                                      ^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.MAP_ENTRY_NOT_IN_MAP
   //                                         ^
-  // [analyzer] SYNTACTIC_ERROR.EXPECTED_TOKEN
-  // [cfe] Expected ';' after this.
-  //                                         ^
-  // [analyzer] SYNTACTIC_ERROR.MISSING_IDENTIFIER
-  // [cfe] Expected an identifier, but got ':'.
-  //                                         ^
-  // [analyzer] SYNTACTIC_ERROR.UNEXPECTED_TOKEN
-  // [cfe] Unexpected token ':'.
-  //                                           ^
-  // [analyzer] SYNTACTIC_ERROR.EXPECTED_TOKEN
-  // [cfe] Expected ';' after this.
+  // [cfe] Expected ',' before this.
 }
diff --git a/tests/language/nnbd/resolution/null_aware_subscript_produces_nullable_type_test.dart b/tests/language/nnbd/resolution/null_aware_subscript_produces_nullable_type_test.dart
index e7bf5b2..c0bd3e2 100644
--- a/tests/language/nnbd/resolution/null_aware_subscript_produces_nullable_type_test.dart
+++ b/tests/language/nnbd/resolution/null_aware_subscript_produces_nullable_type_test.dart
@@ -18,7 +18,7 @@
 
 void f2(NotGeneric? x) {
   x?[0] + 1;
-//^^^^^
+//      ^
 // [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
 // [cfe] unspecified
   x?[0] = 1;
@@ -45,14 +45,14 @@
 
 void f3<T extends num>(Generic<T>? x) {
   x?[0] + 1;
-//^^^^^
+//      ^
 // [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
 // [cfe] unspecified
 }
 
 void f4<T extends num>(Generic<T?> x) {
   x[0] + 1;
-//^^^^
+//     ^
 // [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
 // [cfe] unspecified
 }
diff --git a/tests/language/nnbd/resolution/question_question_lub_test.dart b/tests/language/nnbd/resolution/question_question_lub_test.dart
index 12bafae..0f58626 100644
--- a/tests/language/nnbd/resolution/question_question_lub_test.dart
+++ b/tests/language/nnbd/resolution/question_question_lub_test.dart
@@ -14,18 +14,16 @@
 ) {
   (nullableInt ?? nonNullInt) + 1;
   (nullableInt ?? nullableInt) + 1;
-//^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
 //                             ^
+// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
 // [cfe] Operator '+' cannot be called on 'int?' because it is potentially null.
   (nonNullInt ?? nullableInt) + 1;
-//^^^^^^^^^^^^^^^^^^^^^^^^^^^
-// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
 // ^
 // [cfe] Operand of null-aware operation '??' has type 'int' which excludes null.
 //               ^^^^^^^^^^^
 // [analyzer] STATIC_WARNING.DEAD_NULL_AWARE_EXPRESSION
 //                            ^
+// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
 // [cfe] Operator '+' cannot be called on 'int?' because it is potentially null.
   (nonNullInt ?? nonNullInt) + 1;
 // ^
diff --git a/tests/language/nnbd/type_promotion/null_type_insufficient_for_equals_null_check_error_test.dart b/tests/language/nnbd/type_promotion/null_type_insufficient_for_equals_null_check_error_test.dart
index 55d529b..bc800dc 100644
--- a/tests/language/nnbd/type_promotion/null_type_insufficient_for_equals_null_check_error_test.dart
+++ b/tests/language/nnbd/type_promotion/null_type_insufficient_for_equals_null_check_error_test.dart
@@ -12,7 +12,7 @@
 void assignNullRhs(int? x) {
   if (x != (x = null)) {
     x.isEven;
-//  ^
+//    ^^^^^^
 // [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
     //^
     // [cfe] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
@@ -25,7 +25,7 @@
   // promote in order to be consistent with the `assignNullRhs` case.
   if ((x = null) != x) {
     x.isEven;
-//  ^
+//    ^^^^^^
 // [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
     //^
     // [cfe] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
@@ -35,7 +35,7 @@
 void unrelatedVarRhs(int? x, Null n) {
   if (x != n) {
     x.isEven;
-//  ^
+//    ^^^^^^
 // [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
     //^
     // [cfe] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
@@ -45,7 +45,7 @@
 void unrelatedVarLhs(int? x, Null n) {
   if (n != x) {
     x.isEven;
-//  ^
+//    ^^^^^^
 // [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
     //^
     // [cfe] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
diff --git a/tests/language/nonfunction_type_aliases/generic_usage_type_variable_error_test.dart b/tests/language/nonfunction_type_aliases/generic_usage_type_variable_error_test.dart
index 80b22b7..a0ee00c 100644
--- a/tests/language/nonfunction_type_aliases/generic_usage_type_variable_error_test.dart
+++ b/tests/language/nonfunction_type_aliases/generic_usage_type_variable_error_test.dart
@@ -21,22 +21,45 @@
   // [cfe] unspecified
 }
 
-class D1<X> extends T<X> {}
-//                  ^
+class D {}
+mixin M {}
+
+abstract class D1<X> extends T<D> {}
+//                           ^
 // [analyzer] unspecified
 // [cfe] unspecified
 
-abstract class D2 extends C with T<int> {}
+abstract class D2 extends C with T<M> {}
 //                               ^
 // [analyzer] unspecified
 // [cfe] unspecified
 
-abstract class D3<X, Y> implements T<T> {}
+abstract class D3<X, Y> implements T<T<D>> {}
 //                                 ^
 // [analyzer] unspecified
 // [cfe] unspecified
 
-abstract class D4 = C with T<void>;
+abstract class D4 = C with T<D>;
+//                         ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+class D5<X> extends T<X> {}
+//                  ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+abstract class D6 extends C with T<int> {}
+//                               ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+abstract class D7<X, Y> implements T<T> {}
+//                                 ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+abstract class D8 = C with T<void>;
 //                         ^
 // [analyzer] unspecified
 // [cfe] unspecified
diff --git a/tests/language/nonfunction_type_aliases/generic_usage_type_variable_test.dart b/tests/language/nonfunction_type_aliases/generic_usage_type_variable_test.dart
index 291fc7d..a9cd0c2 100644
--- a/tests/language/nonfunction_type_aliases/generic_usage_type_variable_test.dart
+++ b/tests/language/nonfunction_type_aliases/generic_usage_type_variable_test.dart
@@ -45,12 +45,6 @@
 }
 
 class D {}
-mixin M {}
-
-abstract class D1<X> extends T<D> {}
-abstract class D2 extends C with T<M> {}
-abstract class D3<X, Y> implements T<T<D>> {}
-abstract class D4 = C with T<D>;
 
 extension E on T<dynamic> {
   T<dynamic> foo(T<dynamic> t) => t;
diff --git a/tests/language/nonfunction_type_aliases/mixed/aliased_cyclic_superclass_error_lib.dart b/tests/language/nonfunction_type_aliases/mixed/aliased_cyclic_superclass_error_lib.dart
index 5cb088f..4453a67 100644
--- a/tests/language/nonfunction_type_aliases/mixed/aliased_cyclic_superclass_error_lib.dart
+++ b/tests/language/nonfunction_type_aliases/mixed/aliased_cyclic_superclass_error_lib.dart
@@ -2,9 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-typedef T = C;
+import 'aliased_cyclic_superclass_error_test.dart';
 
-class C extends T {}
-//    ^
-// [analyzer] unspecified
-// [cfe] unspecified
+typedef T = C;
diff --git a/tests/language/nonfunction_type_aliases/mixed/aliased_cyclic_superclass_error_test.dart b/tests/language/nonfunction_type_aliases/mixed/aliased_cyclic_superclass_error_test.dart
index 282e4c2..b034e76 100644
--- a/tests/language/nonfunction_type_aliases/mixed/aliased_cyclic_superclass_error_test.dart
+++ b/tests/language/nonfunction_type_aliases/mixed/aliased_cyclic_superclass_error_test.dart
@@ -11,4 +11,9 @@
 
 import 'aliased_cyclic_superclass_error_lib.dart';
 
+class C extends T {}
+//    ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
 main() => C();
diff --git a/tests/language/nonfunction_type_aliases/mixed/generic_usage_type_variable_error_test.dart b/tests/language/nonfunction_type_aliases/mixed/generic_usage_type_variable_error_test.dart
index a398f3b..cad1f88 100644
--- a/tests/language/nonfunction_type_aliases/mixed/generic_usage_type_variable_error_test.dart
+++ b/tests/language/nonfunction_type_aliases/mixed/generic_usage_type_variable_error_test.dart
@@ -23,22 +23,45 @@
   // [cfe] unspecified
 }
 
-class D1<X> extends T<X> {}
-//                  ^
+class D {}
+mixin M {}
+
+abstract class D1<X> extends T<D> {}
+//                           ^
 // [analyzer] unspecified
 // [cfe] unspecified
 
-abstract class D2 extends C with T<int> {}
+abstract class D2 extends C with T<M> {}
 //                               ^
 // [analyzer] unspecified
 // [cfe] unspecified
 
-abstract class D3<X, Y> implements T<T> {}
+abstract class D3<X, Y> implements T<T<D>> {}
 //                                 ^
 // [analyzer] unspecified
 // [cfe] unspecified
 
-abstract class D4 = C with T<void>;
+abstract class D4 = C with T<D>;
+//                         ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+class D5<X> extends T<X> {}
+//                  ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+abstract class D6 extends C with T<int> {}
+//                               ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+abstract class D7<X, Y> implements T<T> {}
+//                                 ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+abstract class D8 = C with T<void>;
 //                         ^
 // [analyzer] unspecified
 // [cfe] unspecified
diff --git a/tests/language/nonfunction_type_aliases/mixed/generic_usage_type_variable_test.dart b/tests/language/nonfunction_type_aliases/mixed/generic_usage_type_variable_test.dart
index 6e8688f..52b2f4b 100644
--- a/tests/language/nonfunction_type_aliases/mixed/generic_usage_type_variable_test.dart
+++ b/tests/language/nonfunction_type_aliases/mixed/generic_usage_type_variable_test.dart
@@ -47,16 +47,6 @@
 
 class D {}
 
-mixin M {}
-
-abstract class D1<X> extends T<D> {}
-
-abstract class D2 extends C with T<M> {}
-
-abstract class D3<X, Y> implements T<T<D>> {}
-
-abstract class D4 = C with T<D>;
-
 extension E on T<dynamic> {
   T<dynamic> foo(T<dynamic> t) => t;
 }
diff --git a/tests/language/nonfunction_type_aliases/mixed/usage_type_variable_error_test.dart b/tests/language/nonfunction_type_aliases/mixed/usage_type_variable_error_test.dart
index 840809b..a544e21 100644
--- a/tests/language/nonfunction_type_aliases/mixed/usage_type_variable_error_test.dart
+++ b/tests/language/nonfunction_type_aliases/mixed/usage_type_variable_error_test.dart
@@ -22,16 +22,28 @@
   // [cfe] unspecified
 }
 
+class D1 extends T {}
+//               ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
 abstract class D2 extends C with T {}
 //             ^
 // [analyzer] unspecified
 // [cfe] unspecified
 
+abstract class D3 implements T {}
+//                           ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
 abstract class D4 = C with T;
 //             ^
 // [analyzer] unspecified
 // [cfe] unspecified
 
+X foo<X>(X x) => x;
+
 main() {
   var v14 = <Set<T>, Set<T>>{{}: {}};
   v14[{}] = {T()};
diff --git a/tests/language/nonfunction_type_aliases/mixed/usage_type_variable_test.dart b/tests/language/nonfunction_type_aliases/mixed/usage_type_variable_test.dart
index d4212df..983f6a6 100644
--- a/tests/language/nonfunction_type_aliases/mixed/usage_type_variable_test.dart
+++ b/tests/language/nonfunction_type_aliases/mixed/usage_type_variable_test.dart
@@ -45,10 +45,6 @@
   noSuchMethod(Invocation invocation) => throw 0;
 }
 
-class D1 extends T {}
-
-abstract class D3 implements T {}
-
 extension E on T {
   T foo(T t) => t;
 }
@@ -60,7 +56,6 @@
 main() {
   var v13 = <T>[];
   var v14 = <Set<T>, Set<T>>{{}: {}};
-  v14[{}] = {D1()};
   var v15 = {v13};
   Set<List<T>> v16 = v15;
   v15 = v16;
diff --git a/tests/language/nonfunction_type_aliases/near_expand_to_type_variable_test.dart b/tests/language/nonfunction_type_aliases/near_expand_to_type_variable_test.dart
new file mode 100644
index 0000000..27c816f
--- /dev/null
+++ b/tests/language/nonfunction_type_aliases/near_expand_to_type_variable_test.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=nonfunction-type-aliases
+
+import 'package:expect/expect.dart';
+
+typedef TB<T extends C> = T;
+typedef AC = C;  // Direct.
+typedef AEC = TB<C>;  // Explicit C argument.
+typedef AIC = TB;  // Implicit instantiate to bounds.
+
+class C {
+  static const c = 42;
+  static int s = 42;
+  final int y;
+  const C(this.y);
+  const C.name(this.y);
+}
+
+main() {
+  const c0 = AC.c;
+  const c1 = AEC.c;
+  const c2 = AIC.c;
+  Expect.equals(42, AC.s);
+  Expect.equals(42, AEC.s);
+  Expect.equals(42, AIC.s);
+  Expect.equals(0, AC(0).y);
+  Expect.equals(0, AEC(0).y);
+  Expect.equals(0, AIC(0).y);
+  Expect.equals(0, AC.name(0).y);
+  Expect.equals(0, AEC.name(0).y);
+  Expect.equals(0, AIC.name(0).y);
+}
diff --git a/tests/language/nonfunction_type_aliases/private_names/private_name_extension_test.dart b/tests/language/nonfunction_type_aliases/private_names/private_name_extension_test.dart
new file mode 100644
index 0000000..ece07c3
--- /dev/null
+++ b/tests/language/nonfunction_type_aliases/private_names/private_name_extension_test.dart
@@ -0,0 +1,45 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=nonfunction-type-aliases
+
+// Test that private names exported via public typedefs allow extension.
+
+import "package:expect/expect.dart";
+
+import "private_name_library.dart";
+
+class Derived extends PublicClass {
+  Derived() : super(0);
+}
+
+class AlsoDerived extends AlsoPublicClass {
+  AlsoDerived() : super.named(0);
+  int instanceMethod() => 0;
+  int _privateInstanceMethod() => 0;
+}
+
+/// Test that inherited methods work correctly.
+void test1() {
+  {
+    PublicClass p = Derived();
+    Expect.equals(3, p.instanceMethod());
+    Expect.throwsNoSuchMethodError(() => (p as dynamic)._privateInstanceMethod());
+  }
+}
+
+/// Test that inherited methods work correctly.
+void test2() {
+  {
+    var p = AlsoDerived();
+    Expect.equals(0, p.instanceMethod());
+    Expect.equals(0, p._privateInstanceMethod());
+    Expect.equals(0, (p as dynamic)._privateInstanceMethod());
+  }
+}
+
+void main() {
+  test1();
+  test2();
+}
diff --git a/tests/language/nonfunction_type_aliases/private_names/private_name_library.dart b/tests/language/nonfunction_type_aliases/private_names/private_name_library.dart
new file mode 100644
index 0000000..07e441c
--- /dev/null
+++ b/tests/language/nonfunction_type_aliases/private_names/private_name_library.dart
@@ -0,0 +1,32 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Shared code for tests that private names exported publicly via a typedef work
+// as expected.
+
+library private;
+
+class _PrivateClass {
+  int x;
+  _PrivateClass(this.x);
+  _PrivateClass.named(this.x);
+  static int staticMethod() => 3;
+  static int _privateStaticMethod() => 3;
+  int instanceMethod() => 3;
+  int _privateInstanceMethod() => 3;
+}
+
+typedef PublicClass = _PrivateClass;
+PublicClass mkPublicClass() => PublicClass(0);
+
+typedef _PrivateTypeDef = _PrivateClass;
+typedef AlsoPublicClass = _PrivateTypeDef;
+AlsoPublicClass mkAlsoPublicClass() => AlsoPublicClass(0);
+
+class _PrivateGenericClass<T> {
+  static int staticMethod() => 3;
+}
+typedef PublicGenericClass<T> = _PrivateGenericClass<T>;
+PublicGenericClass<T> mkPublicGenericClass<T>() => PublicGenericClass();
+typedef PublicGenericClassOfInt = _PrivateGenericClass<int>;
diff --git a/tests/language/nonfunction_type_aliases/private_names/private_name_static_methods_error_test.dart b/tests/language/nonfunction_type_aliases/private_names/private_name_static_methods_error_test.dart
new file mode 100644
index 0000000..53d90ec
--- /dev/null
+++ b/tests/language/nonfunction_type_aliases/private_names/private_name_static_methods_error_test.dart
@@ -0,0 +1,32 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=nonfunction-type-aliases
+
+// Test that private names exported via public typedefs don't give access to
+// private static methods.
+
+import "private_name_library.dart";
+
+/// Test that accessing private static methods is not accidentally enabled.
+void test1() {
+  {
+    PublicClass._privateStaticMethod();
+//              ^^^^^^^^^^^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.UNDEFINED_METHOD
+// [cfe] Method not found: '_PrivateClass._privateStaticMethod'.
+    AlsoPublicClass._privateStaticMethod();
+//                  ^^^^^^^^^^^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.UNDEFINED_METHOD
+// [cfe] Method not found: '_PrivateClass._privateStaticMethod'.
+    PublicGenericClassOfInt._privateStaticMethod();
+//                          ^^^^^^^^^^^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.UNDEFINED_METHOD
+// [cfe] Method not found: '_PrivateGenericClass._privateStaticMethod'.
+  }
+}
+
+void main() {
+  test1();
+}
diff --git a/tests/language/nonfunction_type_aliases/private_names/private_name_static_methods_test.dart b/tests/language/nonfunction_type_aliases/private_names/private_name_static_methods_test.dart
new file mode 100644
index 0000000..8ea31a4
--- /dev/null
+++ b/tests/language/nonfunction_type_aliases/private_names/private_name_static_methods_test.dart
@@ -0,0 +1,31 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=nonfunction-type-aliases
+
+// Test that private names exported via public typedefs work correctly for
+// accessing static methods.
+
+import "package:expect/expect.dart";
+
+import "../../static_type_helper.dart";
+import "private_name_library.dart";
+
+/// Test that each public typedef can be used to access static methods.
+void test1() {
+  {
+    Expect.equals(3, PublicClass.staticMethod());
+    PublicClass.staticMethod().expectStaticType<Exactly<int>>();
+
+    Expect.equals(3, AlsoPublicClass.staticMethod());
+    AlsoPublicClass.staticMethod().expectStaticType<Exactly<int>>();
+
+    Expect.equals(3, PublicGenericClassOfInt.staticMethod());
+    PublicGenericClassOfInt.staticMethod().expectStaticType<Exactly<int>>();
+  }
+}
+
+void main() {
+  test1();
+}
diff --git a/tests/language/nonfunction_type_aliases/private_names/private_name_types_test.dart b/tests/language/nonfunction_type_aliases/private_names/private_name_types_test.dart
new file mode 100644
index 0000000..27fa686
--- /dev/null
+++ b/tests/language/nonfunction_type_aliases/private_names/private_name_types_test.dart
@@ -0,0 +1,66 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=nonfunction-type-aliases
+
+// Test that private names exported via public typedefs work correctly as
+// types.
+
+import "package:expect/expect.dart";
+
+import "private_name_library.dart";
+import "private_name_library.dart" as prefixed;
+
+/// Test that each public typedef is usable as a type, and that the types
+/// behave as expected.
+void test1() {
+  {
+    PublicClass p0 = mkPublicClass();
+    AlsoPublicClass p1 = mkAlsoPublicClass();
+    // Test that equivalent private types are still equivalent
+    p0 = p1;
+    p1 = p0;
+  }
+
+  {
+    PublicGenericClass<int> p0 = mkPublicGenericClass();
+    PublicGenericClassOfInt p1 = mkPublicGenericClass();
+    // Test that equivalent private types are still equivalent
+    p0 = p1;
+    p1 = p0;
+
+    // Test that inference works on private generic names.
+    Type capture<T>(PublicGenericClass<T> a) => T;
+    Expect.equals(int, capture(p1));
+  }
+}
+
+/// Test that each public typedef is usable as a type when the types are
+/// imported with a prefix, and that the types behave as expected.
+void test2() {
+  {
+    prefixed.PublicClass p0 = prefixed.mkPublicClass();
+    prefixed.AlsoPublicClass p1 = prefixed.mkAlsoPublicClass();
+    // Test that equivalent private types are still equivalent
+    p0 = p1;
+    p1 = p0;
+  }
+
+  {
+    prefixed.PublicGenericClass<int> p0 = prefixed.mkPublicGenericClass();
+    prefixed.PublicGenericClassOfInt p1 = prefixed.mkPublicGenericClass();
+    // Test that equivalent private types are still equivalent
+    p0 = p1;
+    p1 = p0;
+
+    // Test that inference works on private generic names.
+    Type capture<T>(prefixed.PublicGenericClass<T> a) => T;
+    Expect.equals(capture(p1), int);
+  }
+}
+
+void main() {
+  test1();
+  test2();
+}
diff --git a/tests/language/nonfunction_type_aliases/usage_type_variable_error_test.dart b/tests/language/nonfunction_type_aliases/usage_type_variable_error_test.dart
index b24e824..5a6ffb3 100644
--- a/tests/language/nonfunction_type_aliases/usage_type_variable_error_test.dart
+++ b/tests/language/nonfunction_type_aliases/usage_type_variable_error_test.dart
@@ -25,16 +25,29 @@
   // [cfe] unspecified
 }
 
+class D1 extends T {}
+//               ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
 abstract class D2 extends C with T {}
 //             ^
 // [analyzer] unspecified
 // [cfe] unspecified
 
+abstract class D3 implements T {}
+//                           ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+
 abstract class D4 = C with T;
 //             ^
 // [analyzer] unspecified
 // [cfe] unspecified
 
+X foo<X>(X x) => x;
+
 main() {
   var v14 = <Set<T>, Set<T>>{{}: {}};
   v14[{}] = {T()};
diff --git a/tests/language/nonfunction_type_aliases/usage_type_variable_test.dart b/tests/language/nonfunction_type_aliases/usage_type_variable_test.dart
index 6c1b6c8..2c511b6 100644
--- a/tests/language/nonfunction_type_aliases/usage_type_variable_test.dart
+++ b/tests/language/nonfunction_type_aliases/usage_type_variable_test.dart
@@ -48,9 +48,6 @@
   noSuchMethod(Invocation invocation) => throw 0;
 }
 
-class D1 extends T {}
-abstract class D3 implements T {}
-
 extension E on T {
   T foo(T t) => t;
 }
@@ -62,7 +59,6 @@
 main() {
   var v13 = <T>[];
   var v14 = <Set<T>, Set<T>>{{}: {}};
-  v14[{}] = {D1()};
   var v15 = {v13};
   Set<List<T>> v16 = v15;
   v15 = v16;
diff --git a/tests/language/null_aware/prefix_not_shortening_test.dart b/tests/language/null_aware/prefix_not_shortening_test.dart
index 20ef1af..9a9e6cd 100644
--- a/tests/language/null_aware/prefix_not_shortening_test.dart
+++ b/tests/language/null_aware/prefix_not_shortening_test.dart
@@ -11,14 +11,12 @@
 void main() {
   final C? c = new C();
   /**/ -c?.e();
-  //    ^^^^^^
-  // [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
   //   ^
+  // [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
   // [cfe] Operator 'unary-' cannot be called on 'C?' because it is potentially null.
 
   /**/ ~c?.e();
-  //    ^^^^^^
-  // [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
   //   ^
+  // [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
   // [cfe] Operator '~' cannot be called on 'C?' because it is potentially null.
 }
diff --git a/tests/language/operator/invalid_assignment_to_postfix_increment_test.dart b/tests/language/operator/invalid_assignment_to_postfix_increment_test.dart
index 751c947..2c10bfc 100644
--- a/tests/language/operator/invalid_assignment_to_postfix_increment_test.dart
+++ b/tests/language/operator/invalid_assignment_to_postfix_increment_test.dart
@@ -18,12 +18,12 @@
 // ^
 // [cfe] Illegal assignment to non-assignable expression.
   z++ ??= y;
-//^
-// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
 //^^^
 // [analyzer] SYNTACTIC_ERROR.ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE
 //^^^
 // [analyzer] SYNTACTIC_ERROR.MISSING_ASSIGNABLE_SELECTOR
+// ^^
+// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
 // ^
 // [cfe] Illegal assignment to non-assignable expression.
 }
diff --git a/tests/language/regress/regress33479_test.dart b/tests/language/regress/regress33479_test.dart
index 568b6f8..a825b94 100644
--- a/tests/language/regress/regress33479_test.dart
+++ b/tests/language/regress/regress33479_test.dart
@@ -1,13 +1,17 @@
 class Hest<TypeX extends Fisk> {}
+//                       ^^^^
+// [analyzer] COMPILE_TIME_ERROR.NOT_INSTANTIATED_BOUND
 //         ^
 // [cfe] Type variables can't have generic function types in their bounds.
 
 typedef Fisk = void Function // don't merge lines
-// [error line 5, column 1, length 346]
+// [error line 7, 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.NOT_INSTANTIATED_BOUND
 
 main() {
   Hest hest = new Hest();
diff --git a/tests/language/regress/regress45313_test.dart b/tests/language/regress/regress45313_test.dart
new file mode 100644
index 0000000..0c6a5a1
--- /dev/null
+++ b/tests/language/regress/regress45313_test.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=generic-metadata
+
+import "package:expect/expect.dart";
+
+typedef TEST_TYPEDEF<TT extends T Function<T>(T)> = void
+    Function<TTT extends TT>();
+void testme<TT extends T Function<T>(T)>() {}
+
+main() {
+  Expect.isTrue(testme is TEST_TYPEDEF);
+  TEST_TYPEDEF ttttt = testme;
+  Expect.isTrue(ttttt is TEST_TYPEDEF);
+}
diff --git a/tests/language/regress/regress45428_test.dart b/tests/language/regress/regress45428_test.dart
new file mode 100644
index 0000000..37c1427
--- /dev/null
+++ b/tests/language/regress/regress45428_test.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use 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 something(List<String> l) {
+  String s = l.first;
+}
+
+void checkAndInvoke(Function f) {
+  f(["foo"]);
+  var l = <int>[1];
+  Expect.throwsTypeError(() => f(l));
+  if (f is Function(List<Never>)) {
+    Expect.throwsTypeError(() => (f as Function)(l));
+  }
+}
+
+void main() {
+  checkAndInvoke(something);
+}
diff --git a/tests/language/regress/regress45443_test.dart b/tests/language/regress/regress45443_test.dart
new file mode 100644
index 0000000..a979342
--- /dev/null
+++ b/tests/language/regress/regress45443_test.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=generic-metadata
+
+class C1<T extends void Function<TT extends T>()> {}
+
+class C2<T extends TT Function<TT extends T>()> {}
+
+main() {
+  print("OK");
+}
diff --git a/tests/language/regress/regress45529_test.dart b/tests/language/regress/regress45529_test.dart
new file mode 100644
index 0000000..6cd4ed2
--- /dev/null
+++ b/tests/language/regress/regress45529_test.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+void main() {
+  final baz = Foo<Null>().baz;
+  Expect.equals("Baz<Bar<Null>?>", baz.runtimeType.toString());
+  baz.v = baz.v;
+}
+
+class Bar<T> {}
+
+class Foo<T> extends Quux<Bar<T>> {}
+
+class Baz<T> {
+  Baz(this.v);
+  T v;
+}
+
+class Quux<T> {
+  final baz = Baz<T?>(null);
+}
diff --git a/tests/language/super/conditional_operator_test.dart b/tests/language/super/conditional_operator_test.dart
index 5ae030d..734f7fc 100644
--- a/tests/language/super/conditional_operator_test.dart
+++ b/tests/language/super/conditional_operator_test.dart
@@ -49,13 +49,13 @@
     // [analyzer] SYNTACTIC_ERROR.INVALID_OPERATOR_QUESTIONMARK_PERIOD_FOR_SUPER
     // [cfe] The operator '?.' cannot be used with 'super' because 'super' cannot be null.
     -super?.field;
-//   ^^^^^^^^^^^^
+//  ^
 // [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
 //        ^^
 // [analyzer] SYNTACTIC_ERROR.INVALID_OPERATOR_QUESTIONMARK_PERIOD_FOR_SUPER
 // [cfe] The operator '?.' cannot be used with 'super' because 'super' cannot be null.
     ~super?.field;
-//   ^^^^^^^^^^^^
+//  ^
 // [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
 //        ^^
 // [analyzer] SYNTACTIC_ERROR.INVALID_OPERATOR_QUESTIONMARK_PERIOD_FOR_SUPER
diff --git a/tests/language/vm/allocation_sinking_arrays_test.dart b/tests/language/vm/allocation_sinking_arrays_test.dart
index ed5aa9b..c6dc0a5 100644
--- a/tests/language/vm/allocation_sinking_arrays_test.dart
+++ b/tests/language/vm/allocation_sinking_arrays_test.dart
@@ -66,9 +66,13 @@
   Vector2 v2 = new Vector2(1.0, 2.0);
   Vector2 v3 = v2 + Vector2(x, x);
   double sum = v3.x + v3.y;
+  Float32List v4 = Float32List(2);
+  v4[0] = 11.0;
+  v4[1] = sum + 3;
+  print(v4[0]);
   // Deoptimization is triggered here to materialize removed allocations.
   doDeopt + 2;
-  return "v1: [${v1[0]},${v1[1]}], v2: [${v2.x},${v2.y}], v3: [${v3.x},${v3.y}], sum: $sum";
+  return "v1: [${v1[0]},${v1[1]}], v2: [${v2.x},${v2.y}], v3: [${v3.x},${v3.y}], v4: [${v4[0]}, ${v4[1]}], sum: $sum";
 }
 
 main() {
@@ -80,6 +84,8 @@
   for (int i = 0; i < 130; ++i) {
     final num doDeopt = (i < 120 ? 1 : 2.0);
     final result = foo(3.0, doDeopt);
-    Expect.equals("v1: [1,hi], v2: [1.0,2.0], v3: [4.0,5.0], sum: 9.0", result);
+    Expect.equals(
+        "v1: [1,hi], v2: [1.0,2.0], v3: [4.0,5.0], v4: [11.0, 12.0], sum: 9.0",
+        result);
   }
 }
diff --git a/tests/language/vm/checked_smi_comparison_test.dart b/tests/language/vm/checked_smi_comparison_test.dart
new file mode 100644
index 0000000..d22cb01
--- /dev/null
+++ b/tests/language/vm/checked_smi_comparison_test.dart
@@ -0,0 +1,86 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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=
+// VMOptions=--use_slow_path
+
+import "package:expect/expect.dart";
+
+@pragma("vm:never-inline")
+dynamic hiddenSmi() {
+  try {
+    throw 42;
+  } catch (e) {
+    return e;
+  }
+  return 0;
+}
+
+@pragma("vm:never-inline")
+dynamic hiddenMint() {
+  try {
+    throw 0x8000000000000000;
+  } catch (e) {
+    return e;
+  }
+  return 0;
+}
+
+@pragma("vm:never-inline")
+dynamic hiddenDouble() {
+  try {
+    throw 3.0;
+  } catch (e) {
+    return e;
+  }
+  return 0;
+}
+
+@pragma("vm:never-inline")
+dynamic hiddenCustom() {
+  try {
+    throw new Custom();
+  } catch (e) {
+    return e;
+  }
+  return 0;
+}
+
+class Custom {
+  operator <(other) => "lt";
+  operator >(other) => "gt";
+  operator <=(other) => "le";
+  operator >=(other) => "ge";
+  operator ==(other) => false;
+}
+
+main() {
+  Expect.equals(false, hiddenSmi() < 2);
+  Expect.equals(true, hiddenSmi() > 2);
+  Expect.equals(false, hiddenSmi() <= 2);
+  Expect.equals(true, hiddenSmi() >= 2);
+  Expect.equals(false, hiddenSmi() == 2);
+  Expect.equals(true, hiddenSmi() != 2);
+
+  Expect.equals(true, hiddenMint() < 2);
+  Expect.equals(false, hiddenMint() > 2);
+  Expect.equals(true, hiddenMint() <= 2);
+  Expect.equals(false, hiddenMint() >= 2);
+  Expect.equals(false, hiddenMint() == 2);
+  Expect.equals(true, hiddenMint() != 2);
+
+  Expect.equals(false, hiddenDouble() < 2);
+  Expect.equals(true, hiddenDouble() > 2);
+  Expect.equals(false, hiddenDouble() <= 2);
+  Expect.equals(true, hiddenDouble() >= 2);
+  Expect.equals(false, hiddenDouble() == 2);
+  Expect.equals(true, hiddenDouble() != 2);
+
+  Expect.equals("lt", hiddenCustom() < 2);
+  Expect.equals("gt", hiddenCustom() > 2);
+  Expect.equals("le", hiddenCustom() <= 2);
+  Expect.equals("ge", hiddenCustom() >= 2);
+  Expect.equals(false, hiddenCustom() == 2);
+  Expect.equals(true, hiddenCustom() != 2);
+}
diff --git a/tests/language/vm/checked_smi_op_test.dart b/tests/language/vm/checked_smi_op_test.dart
new file mode 100644
index 0000000..f1ae4a6
--- /dev/null
+++ b/tests/language/vm/checked_smi_op_test.dart
@@ -0,0 +1,113 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=triple-shift
+// VMOptions=
+// VMOptions=--use_slow_path
+
+import "package:expect/expect.dart";
+
+@pragma("vm:never-inline")
+dynamic hiddenSmi() {
+  try {
+    throw 42;
+  } catch (e) {
+    return e;
+  }
+  return 0;
+}
+
+@pragma("vm:never-inline")
+dynamic hiddenMint() {
+  try {
+    throw 0x8000000000000000;
+  } catch (e) {
+    return e;
+  }
+  return 0;
+}
+
+@pragma("vm:never-inline")
+dynamic hiddenDouble() {
+  try {
+    throw 3.0;
+  } catch (e) {
+    return e;
+  }
+  return 0;
+}
+
+@pragma("vm:never-inline")
+dynamic hiddenCustom() {
+  try {
+    throw new Custom();
+  } catch (e) {
+    return e;
+  }
+  return 0;
+}
+
+class Custom {
+  operator +(other) => "add";
+  operator -(other) => "sub";
+  operator *(other) => "mul";
+  operator ~/(other) => "div";
+  operator %(other) => "mod";
+  operator &(other) => "and";
+  operator |(other) => "or";
+  operator ^(other) => "xor";
+  operator <<(other) => "sll";
+  operator >>(other) => "sra";
+  operator >>>(other) => "srl";
+}
+
+main() {
+  Expect.equals(44, hiddenSmi() + 2);
+  Expect.equals(40, hiddenSmi() - 2);
+  Expect.equals(84, hiddenSmi() * 2);
+  Expect.equals(21, hiddenSmi() ~/ 2);
+  Expect.equals(0, hiddenSmi() % 2);
+  Expect.equals(2, hiddenSmi() & 2);
+  Expect.equals(42, hiddenSmi() | 2);
+  Expect.equals(40, hiddenSmi() ^ 2);
+  Expect.equals(168, hiddenSmi() << 2);
+  Expect.equals(10, hiddenSmi() >> 2);
+  Expect.equals(10, hiddenSmi() >>> 2);
+
+  Expect.equals(-9223372036854775806, hiddenMint() + 2);
+  Expect.equals(9223372036854775806, hiddenMint() - 2);
+  Expect.equals(0, hiddenMint() * 2);
+  Expect.equals(-4611686018427387904, hiddenMint() ~/ 2);
+  Expect.equals(0, hiddenMint() % 2);
+  Expect.equals(0, hiddenMint() & 2);
+  Expect.equals(-9223372036854775806, hiddenMint() | 2);
+  Expect.equals(-9223372036854775806, hiddenMint() ^ 2);
+  Expect.equals(0, hiddenMint() << 2);
+  Expect.equals(-2305843009213693952, hiddenMint() >> 2);
+  Expect.equals(2305843009213693952, hiddenMint() >>> 2);
+
+  Expect.equals(5.0, hiddenDouble() + 2);
+  Expect.equals(1.0, hiddenDouble() - 2);
+  Expect.equals(6.0, hiddenDouble() * 2);
+  Expect.equals(1, hiddenDouble() ~/ 2);
+  Expect.equals(1.0, hiddenDouble() % 2);
+  Expect.throws(() => hiddenDouble() & 2, (e) => e is NoSuchMethodError);
+  Expect.throws(() => hiddenDouble() | 2, (e) => e is NoSuchMethodError);
+  Expect.throws(() => hiddenDouble() ^ 2, (e) => e is NoSuchMethodError);
+  Expect.throws(() => hiddenDouble() << 2, (e) => e is NoSuchMethodError);
+  Expect.throws(() => hiddenDouble() >> 2, (e) => e is NoSuchMethodError);
+  Expect.throws(() => hiddenDouble() >>> 2, (e) => e is NoSuchMethodError);
+
+  Expect.equals("add", hiddenCustom() + 2);
+  Expect.equals("sub", hiddenCustom() - 2);
+  Expect.equals("mul", hiddenCustom() * 2);
+  Expect.equals("div", hiddenCustom() ~/ 2);
+  Expect.equals("mod", hiddenCustom() % 2);
+  Expect.equals("and", hiddenCustom() & 2);
+  Expect.equals("or", hiddenCustom() | 2);
+  Expect.equals("xor", hiddenCustom() ^ 2);
+  Expect.equals("sll", hiddenCustom() << 2);
+  Expect.equals("sra", hiddenCustom() >> 2);
+  Expect.equals("srl", hiddenCustom() >>> 2);
+}
diff --git a/tests/language/vm/div_mod_test.dart b/tests/language/vm/div_mod_test.dart
index f534e67..ea22240 100755
--- a/tests/language/vm/div_mod_test.dart
+++ b/tests/language/vm/div_mod_test.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 // VMOptions=--deterministic
+// VMOptions=--deterministic --use_slow_path
 
 // Unit tests on DIV and MOV operations by various constants.
 
diff --git a/tests/language/vm/modtruncdiv_int_test.dart b/tests/language/vm/modtruncdiv_int_test.dart
index f5a51ce..9fc5b53 100644
--- a/tests/language/vm/modtruncdiv_int_test.dart
+++ b/tests/language/vm/modtruncdiv_int_test.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 // VMOptions=--no_background_compilation --optimization_counter_threshold=10
+// VMOptions=--no_background_compilation --optimization_counter_threshold=10 --use_slow_path
 
 import "package:expect/expect.dart";
 
diff --git a/tests/language/vm/mult_int_test.dart b/tests/language/vm/mult_int_test.dart
index b13cbd5..16df391 100644
--- a/tests/language/vm/mult_int_test.dart
+++ b/tests/language/vm/mult_int_test.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 // VMOptions=--no_background_compilation --optimization_counter_threshold=10
+// VMOptions=--no_background_compilation --optimization_counter_threshold=10 --use_slow_path
 
 import "package:expect/expect.dart";
 
diff --git a/tests/language/vm/negate_int_test.dart b/tests/language/vm/negate_int_test.dart
index 8703aef..253756e 100644
--- a/tests/language/vm/negate_int_test.dart
+++ b/tests/language/vm/negate_int_test.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 // VMOptions=--no_background_compilation --optimization_counter_threshold=10
+// VMOptions=--no_background_compilation --optimization_counter_threshold=10 --use_slow_path
 
 import "package:expect/expect.dart";
 
diff --git a/tests/language/vm/no_such_args_error_message_vm_test.dart b/tests/language/vm/no_such_args_error_message_vm_test.dart
index d3ca510..3429907 100644
--- a/tests/language/vm/no_such_args_error_message_vm_test.dart
+++ b/tests/language/vm/no_such_args_error_message_vm_test.dart
@@ -15,10 +15,11 @@
   try {
     call_with_bar(() {});
   } catch (e) {
-    final expectedStrings = [
-      'Tried calling: testClosureMessage.<anonymous closure>("bar")',
-    ];
-    Expect.stringContainsInOrder(e.toString(), expectedStrings);
+    // The latter may happen if in --dwarf-stack-traces mode.
+    final possibleNames = ['testClosureMessage', '<optimized out>'];
+    Expect.containsOneOf(
+        possibleNames.map((s) => s + '.<anonymous closure>("bar")'),
+        e.toString());
   }
 }
 
diff --git a/tests/language/vm/regress_45524_test.dart b/tests/language/vm/regress_45524_test.dart
new file mode 100644
index 0000000..9df16c8
--- /dev/null
+++ b/tests/language/vm/regress_45524_test.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+// Reduced from:
+// The Dart Project Fuzz Tester (1.89).
+// Program generated as:
+//   dart dartfuzz.dart --seed 3959760722 --no-fp --no-ffi --flat
+
+bool var17 = bool.fromEnvironment('2y');
+
+class X0 {
+  num fld0_2 = 9223372036854775807;
+}
+
+extension XE0 on X0 {
+  bool foo0_Extension0() {
+    if (-12 >= -(((var17 ? -92 : fld0_2)))) {
+      return true;
+    } else {
+      return false;
+    }
+  }
+}
+
+main() {
+  Expect.equals(true, X0().foo0_Extension0());
+}
diff --git a/tests/language/vm/regress_45525_test.dart b/tests/language/vm/regress_45525_test.dart
new file mode 100644
index 0000000..2becc03
--- /dev/null
+++ b/tests/language/vm/regress_45525_test.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// VMOptions=--optimization-counter-threshold=10  --no-background-compilation
+
+import "package:expect/expect.dart";
+
+dynamic a() {
+  return 23;
+}
+
+dynamic b() {
+  return 26;
+}
+
+@pragma("vm:never-inline")
+dynamic foo() {
+  // BinarySmiOp(<<) marked truncating
+  return (a() << b()) & 0xFFFFFFF;
+}
+
+main() {
+  for (var i = 0; i < 20; i++) {
+    Expect.equals(201326592, foo());
+  }
+}
diff --git a/tests/language/vm/shift_special_cases_test.dart b/tests/language/vm/shift_special_cases_test.dart
index 2cba918..b0fd2ed 100644
--- a/tests/language/vm/shift_special_cases_test.dart
+++ b/tests/language/vm/shift_special_cases_test.dart
@@ -1,7 +1,9 @@
 // Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
+
 // VMOptions=--optimization-counter-threshold=10 --no-background-compilation
+// VMOptions=--optimization-counter-threshold=10 --no-background-compilation --use_slow_path
 
 // Test for special cases of << and >> integer operations with int64.
 
diff --git a/tests/language/why_not_promoted/argument_type_not_assignable_nullability_error_test.dart b/tests/language/why_not_promoted/argument_type_not_assignable_nullability_error_test.dart
new file mode 100644
index 0000000..c4f6955
--- /dev/null
+++ b/tests/language/why_not_promoted/argument_type_not_assignable_nullability_error_test.dart
@@ -0,0 +1,643 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for 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 contains a test case for each condition that can lead to the front
+// end's `ArgumentTypeNotAssignableNullability` error, for which we wish to
+// report "why not promoted" context information.
+
+class C1 {
+  int? bad;
+  //   ^^^
+  // [context 29] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 47] 'bad' refers to a property so it couldn't be promoted.
+  f(int i) {}
+}
+
+required_unnamed(C1 c) {
+  if (c.bad == null) return;
+  c.f(c.bad);
+  //  ^^^^^
+  // [analyzer 29] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
+  //    ^
+  // [cfe 47] The argument type 'int?' can't be assigned to the parameter type 'int' because 'int?' is nullable and 'int' isn't.
+}
+
+class C2 {
+  int? bad;
+  //   ^^^
+  // [context 38] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 48] 'bad' refers to a property so it couldn't be promoted.
+  f([int i = 0]) {}
+}
+
+optional_unnamed(C2 c) {
+  if (c.bad == null) return;
+  c.f(c.bad);
+  //  ^^^^^
+  // [analyzer 38] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
+  //    ^
+  // [cfe 48] The argument type 'int?' can't be assigned to the parameter type 'int' because 'int?' is nullable and 'int' isn't.
+}
+
+class C3 {
+  int? bad;
+  //   ^^^
+  // [context 6] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 49] 'bad' refers to a property so it couldn't be promoted.
+  f({required int i}) {}
+}
+
+required_named(C3 c) {
+  if (c.bad == null) return;
+  c.f(i: c.bad);
+  //  ^^^^^^^^
+  // [analyzer 6] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
+  //       ^
+  // [cfe 49] The argument type 'int?' can't be assigned to the parameter type 'int' because 'int?' is nullable and 'int' isn't.
+}
+
+class C4 {
+  int? bad;
+  //   ^^^
+  // [context 16] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 50] 'bad' refers to a property so it couldn't be promoted.
+  f({int i = 0}) {}
+}
+
+optional_named(C4 c) {
+  if (c.bad == null) return;
+  c.f(i: c.bad);
+  //  ^^^^^^^^
+  // [analyzer 16] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
+  //       ^
+  // [cfe 50] The argument type 'int?' can't be assigned to the parameter type 'int' because 'int?' is nullable and 'int' isn't.
+}
+
+class C5 {
+  List<int>? bad;
+  //         ^^^
+  // [context 33] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 51] 'bad' refers to a property so it couldn't be promoted.
+  f<T>(List<T> x) {}
+}
+
+type_inferred(C5 c) {
+  if (c.bad == null) return;
+  c.f(c.bad);
+  //  ^^^^^
+  // [analyzer 33] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
+  //    ^
+  // [cfe 51] The argument type 'List<int>?' can't be assigned to the parameter type 'List<int>' because 'List<int>?' is nullable and 'List<int>' isn't.
+}
+
+class C6 {
+  int? bad;
+  //   ^^^
+  // [context 21] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 52] 'bad' refers to a property so it couldn't be promoted.
+  C6(int i);
+}
+
+C6? constructor_with_implicit_new(C6 c) {
+  if (c.bad == null) return null;
+  return C6(c.bad);
+  //        ^^^^^
+  // [analyzer 21] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
+  //          ^
+  // [cfe 52] The argument type 'int?' can't be assigned to the parameter type 'int' because 'int?' is nullable and 'int' isn't.
+}
+
+class C7 {
+  int? bad;
+  //   ^^^
+  // [context 42] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 53] 'bad' refers to a property so it couldn't be promoted.
+  C7(int i);
+}
+
+C7? constructor_with_explicit_new(C7 c) {
+  if (c.bad == null) return null;
+  return new C7(c.bad);
+  //            ^^^^^
+  // [analyzer 42] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
+  //              ^
+  // [cfe 53] The argument type 'int?' can't be assigned to the parameter type 'int' because 'int?' is nullable and 'int' isn't.
+}
+
+class C8 {
+  int? bad;
+  //   ^^^
+  // [context 13] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 54] 'bad' refers to a property so it couldn't be promoted.
+}
+
+userDefinableBinaryOpRhs(C8 c) {
+  if (c.bad == null) return;
+  1 + c.bad;
+  //  ^^^^^
+  // [analyzer 13] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
+  //    ^
+  // [cfe 54] A value of type 'int?' can't be assigned to a variable of type 'num' because 'int?' is nullable and 'num' isn't.
+}
+
+class C9 {
+  int? bad;
+  f(int i) {}
+}
+
+questionQuestionRhs(C9 c, int? i) {
+  // Note: "why not supported" functionality is currently not supported for the
+  // RHS of `??` because it requires more clever reasoning than we currently do:
+  // we would have to understand that the reason `i ?? c.bad` has a type of
+  // `int?` rather than `int` is because `c.bad` was not promoted.  We currently
+  // only support detecting non-promotion when the expression that had the wrong
+  // type *is* the expression that wasn't promoted.
+  if (c.bad == null) return;
+  c.f(i ?? c.bad);
+  //  ^^^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
+  //    ^
+  // [cfe] The argument type 'int?' can't be assigned to the parameter type 'int' because 'int?' is nullable and 'int' isn't.
+}
+
+class C10 {
+  D10? bad;
+  f(bool b) {}
+}
+
+class D10 {
+  bool operator ==(covariant D10 other) => true;
+}
+
+equalRhs(C10 c, D10 d) {
+  if (c.bad == null) return;
+  // Note: we don't report an error here because `==` always accepts `null`.
+  c.f(d == c.bad);
+  c.f(d != c.bad);
+}
+
+class C11 {
+  bool? bad;
+  //    ^^^
+  // [context 30] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 46] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 55] 'bad' refers to a property so it couldn't be promoted.
+  // [context 56] 'bad' refers to a property so it couldn't be promoted.
+  f(bool b) {}
+}
+
+andOperand(C11 c, bool b) {
+  if (c.bad == null) return;
+  c.f(c.bad && b);
+  //  ^^^^^
+  // [analyzer 46] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  //    ^
+  // [cfe 55] A value of type 'bool?' can't be assigned to a variable of type 'bool' because 'bool?' is nullable and 'bool' isn't.
+  c.f(b && c.bad);
+  //       ^^^^^
+  // [analyzer 30] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  //         ^
+  // [cfe 56] A value of type 'bool?' can't be assigned to a variable of type 'bool' because 'bool?' is nullable and 'bool' isn't.
+}
+
+class C12 {
+  bool? bad;
+  //    ^^^
+  // [context 27] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 36] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 57] 'bad' refers to a property so it couldn't be promoted.
+  // [context 58] 'bad' refers to a property so it couldn't be promoted.
+  f(bool b) {}
+}
+
+orOperand(C12 c, bool b) {
+  if (c.bad == null) return;
+  c.f(c.bad || b);
+  //  ^^^^^
+  // [analyzer 27] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  //    ^
+  // [cfe 57] A value of type 'bool?' can't be assigned to a variable of type 'bool' because 'bool?' is nullable and 'bool' isn't.
+  c.f(b || c.bad);
+  //       ^^^^^
+  // [analyzer 36] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  //         ^
+  // [cfe 58] A value of type 'bool?' can't be assigned to a variable of type 'bool' because 'bool?' is nullable and 'bool' isn't.
+}
+
+class C13 {
+  bool? bad;
+  //    ^^^
+  // [context 40] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 59] 'bad' refers to a property so it couldn't be promoted.
+}
+
+assertStatementCondition(C13 c) {
+  if (c.bad == null) return;
+  assert(c.bad);
+  //     ^^^^^
+  // [analyzer 40] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  //       ^
+  // [cfe 59] A value of type 'bool?' can't be assigned to a variable of type 'bool' because 'bool?' is nullable and 'bool' isn't.
+}
+
+class C14 {
+  bool? bad;
+  //    ^^^
+  // [context 1] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 60] 'bad' refers to a property so it couldn't be promoted.
+  C14.assertInitializerCondition(C14 c)
+      : bad = c.bad!,
+        assert(c.bad);
+        //     ^^^^^
+        // [analyzer 1] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+        //       ^
+        // [cfe 60] A value of type 'bool?' can't be assigned to a variable of type 'bool' because 'bool?' is nullable and 'bool' isn't.
+}
+
+class C15 {
+  bool? bad;
+  //    ^^^
+  // [context 28] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 61] 'bad' refers to a property so it couldn't be promoted.
+  f(bool b) {}
+}
+
+notOperand(C15 c) {
+  if (c.bad == null) return;
+  c.f(!c.bad);
+  //   ^^^^^
+  // [analyzer 28] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  //     ^
+  // [cfe 61] A value of type 'bool?' can't be assigned to a variable of type 'bool' because 'bool?' is nullable and 'bool' isn't.
+}
+
+class C16 {
+  bool? bad;
+  //    ^^^
+  // [context 22] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 24] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 25] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 32] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 62] 'bad' refers to a property so it couldn't be promoted.
+  // [context 63] 'bad' refers to a property so it couldn't be promoted.
+  // [context 64] 'bad' refers to a property so it couldn't be promoted.
+  // [context 65] 'bad' refers to a property so it couldn't be promoted.
+}
+
+forLoopCondition(C16 c) {
+  if (c.bad == null) return;
+  for (; c.bad;) {}
+  //     ^^^^^
+  // [analyzer 32] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  //       ^
+  // [cfe 62] A value of type 'bool?' can't be assigned to a variable of type 'bool' because 'bool?' is nullable and 'bool' isn't.
+  [for (; c.bad;) null];
+  //      ^^^^^
+  // [analyzer 25] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  //        ^
+  // [cfe 63] A value of type 'bool?' can't be assigned to a variable of type 'bool' because 'bool?' is nullable and 'bool' isn't.
+  ({for (; c.bad;) null});
+  //       ^^^^^
+  // [analyzer 22] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  //         ^
+  // [cfe 64] A value of type 'bool?' can't be assigned to a variable of type 'bool' because 'bool?' is nullable and 'bool' isn't.
+  ({for (; c.bad;) null: null});
+  //       ^^^^^
+  // [analyzer 24] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  //         ^
+  // [cfe 65] A value of type 'bool?' can't be assigned to a variable of type 'bool' because 'bool?' is nullable and 'bool' isn't.
+}
+
+class C17 {
+  bool? bad;
+  //    ^^^
+  // [context 10] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 66] 'bad' refers to a property so it couldn't be promoted.
+  f(int i) {}
+}
+
+conditionalExpressionCondition(C17 c) {
+  if (c.bad == null) return;
+  c.f(c.bad ? 1 : 2);
+  //  ^^^^^
+  // [analyzer 10] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  //    ^
+  // [cfe 66] A value of type 'bool?' can't be assigned to a variable of type 'bool' because 'bool?' is nullable and 'bool' isn't.
+}
+
+class C18 {
+  bool? bad;
+  //    ^^^
+  // [context 26] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 67] 'bad' refers to a property so it couldn't be promoted.
+}
+
+doLoopCondition(C18 c) {
+  if (c.bad == null) return;
+  do {} while (c.bad);
+  //           ^^^^^
+  // [analyzer 26] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  //             ^
+  // [cfe 67] A value of type 'bool?' can't be assigned to a variable of type 'bool' because 'bool?' is nullable and 'bool' isn't.
+}
+
+class C19 {
+  bool? bad;
+  //    ^^^
+  // [context 5] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 9] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 12] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 39] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 68] 'bad' refers to a property so it couldn't be promoted.
+  // [context 69] 'bad' refers to a property so it couldn't be promoted.
+  // [context 70] 'bad' refers to a property so it couldn't be promoted.
+  // [context 71] 'bad' refers to a property so it couldn't be promoted.
+}
+
+ifCondition(C19 c) {
+  if (c.bad == null) return;
+  if (c.bad) {}
+  //  ^^^^^
+  // [analyzer 5] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  //    ^
+  // [cfe 68] A value of type 'bool?' can't be assigned to a variable of type 'bool' because 'bool?' is nullable and 'bool' isn't.
+  [if (c.bad) null];
+  //   ^^^^^
+  // [analyzer 12] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  //     ^
+  // [cfe 69] A value of type 'bool?' can't be assigned to a variable of type 'bool' because 'bool?' is nullable and 'bool' isn't.
+  ({if (c.bad) null});
+  //    ^^^^^
+  // [analyzer 9] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  //      ^
+  // [cfe 70] A value of type 'bool?' can't be assigned to a variable of type 'bool' because 'bool?' is nullable and 'bool' isn't.
+  ({if (c.bad) null: null});
+  //    ^^^^^
+  // [analyzer 39] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  //      ^
+  // [cfe 71] A value of type 'bool?' can't be assigned to a variable of type 'bool' because 'bool?' is nullable and 'bool' isn't.
+}
+
+class C20 {
+  bool? bad;
+  //    ^^^
+  // [context 3] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 72] 'bad' refers to a property so it couldn't be promoted.
+}
+
+whileCondition(C20 c) {
+  if (c.bad == null) return;
+  while (c.bad) {}
+  //     ^^^^^
+  // [analyzer 3] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  //       ^
+  // [cfe 72] A value of type 'bool?' can't be assigned to a variable of type 'bool' because 'bool?' is nullable and 'bool' isn't.
+}
+
+class C21 {
+  int? bad;
+  //   ^^^
+  // [context 17] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 73] 'bad' refers to a property so it couldn't be promoted.
+}
+
+assignmentRhs(C21 c, int i) {
+  if (c.bad == null) return;
+  i = c.bad;
+  //  ^^^^^
+  // [analyzer 17] COMPILE_TIME_ERROR.INVALID_ASSIGNMENT
+  //    ^
+  // [cfe 73] A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
+}
+
+class C22 {
+  int? bad;
+  //   ^^^
+  // [context 18] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 74] 'bad' refers to a property so it couldn't be promoted.
+}
+
+variableInitializer(C22 c) {
+  if (c.bad == null) return;
+  int i = c.bad;
+  //      ^^^^^
+  // [analyzer 18] COMPILE_TIME_ERROR.INVALID_ASSIGNMENT
+  //        ^
+  // [cfe 74] A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
+}
+
+class C23 {
+  int? bad;
+  //   ^^^
+  // [context 20] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 75] 'bad' refers to a property so it couldn't be promoted.
+  final int x;
+  final int y;
+  C23.constructorInitializer(C23 c)
+      : x = c.bad!,
+        y = c.bad;
+        //  ^^^^^
+        // [analyzer 20] COMPILE_TIME_ERROR.FIELD_INITIALIZER_NOT_ASSIGNABLE
+        //    ^
+        // [cfe 75] A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
+}
+
+class C24 {
+  int? bad;
+  //   ^^^
+  // [context 14] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 41] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 43] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 44] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 76] 'bad' refers to a property so it couldn't be promoted.
+  // [context 77] 'bad' refers to a property so it couldn't be promoted.
+  // [context 78] 'bad' refers to a property so it couldn't be promoted.
+  // [context 79] 'bad' refers to a property so it couldn't be promoted.
+}
+
+forVariableInitializer(C24 c) {
+  if (c.bad == null) return;
+  for (int i = c.bad; false;) {}
+  //           ^^^^^
+  // [analyzer 44] COMPILE_TIME_ERROR.INVALID_ASSIGNMENT
+  //             ^
+  // [cfe 76] A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
+  [for (int i = c.bad; false;) null];
+  //            ^^^^^
+  // [analyzer 43] COMPILE_TIME_ERROR.INVALID_ASSIGNMENT
+  //              ^
+  // [cfe 77] A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
+  ({for (int i = c.bad; false;) null});
+  //             ^^^^^
+  // [analyzer 41] COMPILE_TIME_ERROR.INVALID_ASSIGNMENT
+  //               ^
+  // [cfe 78] A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
+  ({for (int i = c.bad; false;) null: null});
+  //             ^^^^^
+  // [analyzer 14] COMPILE_TIME_ERROR.INVALID_ASSIGNMENT
+  //               ^
+  // [cfe 79] A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
+}
+
+class C25 {
+  int? bad;
+  //   ^^^
+  // [context 2] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 4] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 8] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 11] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 80] 'bad' refers to a property so it couldn't be promoted.
+  // [context 81] 'bad' refers to a property so it couldn't be promoted.
+  // [context 82] 'bad' refers to a property so it couldn't be promoted.
+  // [context 83] 'bad' refers to a property so it couldn't be promoted.
+}
+
+forAssignmentInitializer(C25 c, int i) {
+  if (c.bad == null) return;
+  for (i = c.bad; false;) {}
+  //       ^^^^^
+  // [analyzer 2] COMPILE_TIME_ERROR.INVALID_ASSIGNMENT
+  //         ^
+  // [cfe 80] A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
+  [for (i = c.bad; false;) null];
+  //        ^^^^^
+  // [analyzer 4] COMPILE_TIME_ERROR.INVALID_ASSIGNMENT
+  //          ^
+  // [cfe 81] A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
+  ({for (i = c.bad; false;) null});
+  //         ^^^^^
+  // [analyzer 11] COMPILE_TIME_ERROR.INVALID_ASSIGNMENT
+  //           ^
+  // [cfe 82] A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
+  ({for (i = c.bad; false;) null: null});
+  //         ^^^^^
+  // [analyzer 8] COMPILE_TIME_ERROR.INVALID_ASSIGNMENT
+  //           ^
+  // [cfe 83] A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
+}
+
+class C26 {
+  int? bad;
+  //   ^^^
+  // [context 45] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 84] 'bad' refers to a property so it couldn't be promoted.
+}
+
+compoundAssignmentRhs(C26 c) {
+  num n = 0;
+  if (c.bad == null) return;
+  n += c.bad;
+  //   ^^^^^
+  // [analyzer 45] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
+  //     ^
+  // [cfe 84] A value of type 'int?' can't be assigned to a variable of type 'num' because 'int?' is nullable and 'num' isn't.
+}
+
+class C27 {
+  int? bad;
+  //   ^^^
+  // [context 7] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 85] 'bad' refers to a property so it couldn't be promoted.
+}
+
+indexGet(C27 c, List<int> values) {
+  if (c.bad == null) return;
+  values[c.bad];
+  //     ^^^^^
+  // [analyzer 7] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
+  //       ^
+  // [cfe 85] A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
+}
+
+class C28 {
+  int? bad;
+  //   ^^^
+  // [context 23] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 86] 'bad' refers to a property so it couldn't be promoted.
+}
+
+indexSet(C28 c, List<int> values) {
+  if (c.bad == null) return;
+  values[c.bad] = 0;
+  //     ^^^^^
+  // [analyzer 23] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
+  //       ^
+  // [cfe 86] A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
+}
+
+class C29 {
+  int? bad;
+  //   ^^^
+  // [context 19] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+}
+
+indexSetCompound(C29 c, List<int> values) {
+  // TODO(paulberry): get this to work with the CFE
+  if (c.bad == null) return;
+  values[c.bad] += 1;
+  //     ^^^^^
+  // [analyzer 19] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
+  //       ^
+  // [cfe] A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
+}
+
+class C30 {
+  int? bad;
+  //   ^^^
+  // [context 37] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+}
+
+indexSetIfNull(C30 c, List<int?> values) {
+  // TODO(paulberry): get this to work with the CFE
+  if (c.bad == null) return;
+  values[c.bad] ??= 1;
+  //     ^^^^^
+  // [analyzer 37] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
+  //       ^
+  // [cfe] A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
+}
+
+class C31 {
+  int? bad;
+  //   ^^^
+  // [context 31] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 35] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+}
+
+indexSetPreIncDec(C31 c, List<int> values) {
+  // TODO(paulberry): get this to work with the CFE
+  if (c.bad == null) return;
+  ++values[c.bad];
+  //       ^^^^^
+  // [analyzer 31] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
+  //         ^
+  // [cfe] A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
+  --values[c.bad];
+  //       ^^^^^
+  // [analyzer 35] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
+  //         ^
+  // [cfe] A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
+}
+
+class C32 {
+  int? bad;
+  //   ^^^
+  // [context 15] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 34] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+}
+
+indexSetPostIncDec(C32 c, List<int> values) {
+  // TODO(paulberry): get this to work with the CFE
+  if (c.bad == null) return;
+  values[c.bad]++;
+  //     ^^^^^
+  // [analyzer 34] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
+  //       ^
+  // [cfe] A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
+  values[c.bad]--;
+  //     ^^^^^
+  // [analyzer 15] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
+  //       ^
+  // [cfe] A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
+}
diff --git a/tests/language/why_not_promoted/assignment_error_test.dart b/tests/language/why_not_promoted/assignment_error_test.dart
new file mode 100644
index 0000000..9c1c3a4
--- /dev/null
+++ b/tests/language/why_not_promoted/assignment_error_test.dart
@@ -0,0 +1,114 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+abstract class C {
+  C? operator +(int i);
+  int get cProperty => 0;
+}
+
+direct_assignment(int? i, int? j) {
+  if (i == null) return;
+  i = j;
+//^^^^^
+// [context 6] Variable 'i' could not be promoted due to an assignment.  See http://dart.dev/go/non-promo-write
+// [context 10] Variable 'i' could not be promoted due to an assignment.
+  i.isEven;
+//  ^^^^^^
+// [analyzer 6] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// [cfe 10] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
+}
+
+compound_assignment(C? c, int i) {
+  if (c == null) return;
+  c += i;
+//^^^^^^
+// [context 7] Variable 'c' could not be promoted due to an assignment.  See http://dart.dev/go/non-promo-write
+// [context 11] Variable 'c' could not be promoted due to an assignment.
+  c.cProperty;
+//  ^^^^^^^^^
+// [analyzer 7] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// [cfe 11] Property 'cProperty' cannot be accessed on 'C?' because it is potentially null.
+}
+
+via_postfix_op(C? c) {
+  if (c == null) return;
+  c++;
+//^^^
+// [context 4] Variable 'c' could not be promoted due to an assignment.  See http://dart.dev/go/non-promo-write
+// [context 12] Variable 'c' could not be promoted due to an assignment.
+  c.cProperty;
+//  ^^^^^^^^^
+// [analyzer 4] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// [cfe 12] Property 'cProperty' cannot be accessed on 'C?' because it is potentially null.
+}
+
+via_prefix_op(C? c) {
+  if (c == null) return;
+  ++c;
+//^^^
+// [context 9] Variable 'c' could not be promoted due to an assignment.  See http://dart.dev/go/non-promo-write
+  //^
+  // [context 13] Variable 'c' could not be promoted due to an assignment.
+  c.cProperty;
+//  ^^^^^^^^^
+// [analyzer 9] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// [cfe 13] Property 'cProperty' cannot be accessed on 'C?' because it is potentially null.
+}
+
+via_for_each_statement(int? i, List<int?> list) {
+  if (i == null) return;
+  for (i in list) {
+  //   ^
+  // [context 3] Variable 'i' could not be promoted due to an assignment.  See http://dart.dev/go/non-promo-write
+  // [context 14] Variable 'i' could not be promoted due to an assignment.
+    i.isEven;
+//    ^^^^^^
+// [analyzer 3] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// [cfe 14] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
+  }
+}
+
+via_for_each_list_element(int? i, List<int?> list) {
+  if (i == null) return;
+  [for (i in list) i.isEven];
+  //    ^
+  // [context 8] Variable 'i' could not be promoted due to an assignment.  See http://dart.dev/go/non-promo-write
+  // [context 15] Variable 'i' could not be promoted due to an assignment.
+  //                 ^^^^^^
+  // [analyzer 8] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  // [cfe 15] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
+}
+
+via_for_each_set_element(int? i, List<int?> list) {
+  if (i == null) return;
+  ({for (i in list) i.isEven});
+  //     ^
+  // [context 1] Variable 'i' could not be promoted due to an assignment.  See http://dart.dev/go/non-promo-write
+  // [context 16] Variable 'i' could not be promoted due to an assignment.
+  //                  ^^^^^^
+  // [analyzer 1] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  // [cfe 16] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
+}
+
+via_for_each_map_key(int? i, List<int?> list) {
+  if (i == null) return;
+  ({for (i in list) i.isEven: null});
+  //     ^
+  // [context 2] Variable 'i' could not be promoted due to an assignment.  See http://dart.dev/go/non-promo-write
+  // [context 17] Variable 'i' could not be promoted due to an assignment.
+  //                  ^^^^^^
+  // [analyzer 2] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  // [cfe 17] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
+}
+
+via_for_each_map_value(int? i, List<int?> list) {
+  if (i == null) return;
+  ({for (i in list) null: i.isEven});
+  //     ^
+  // [context 5] Variable 'i' could not be promoted due to an assignment.  See http://dart.dev/go/non-promo-write
+  // [context 18] Variable 'i' could not be promoted due to an assignment.
+  //                        ^^^^^^
+  // [analyzer 5] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  // [cfe 18] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
+}
diff --git a/tests/language/why_not_promoted/extension_property_error_test.dart b/tests/language/why_not_promoted/extension_property_error_test.dart
new file mode 100644
index 0000000..d7de5cc
--- /dev/null
+++ b/tests/language/why_not_promoted/extension_property_error_test.dart
@@ -0,0 +1,83 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class C {
+  get_property_via_explicit_this() {
+    if (this.i == null) return;
+    this.i.isEven;
+//         ^^^^^^
+// [analyzer 4] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// [cfe 6] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
+  }
+
+  get_property_via_explicit_this_parenthesized() {
+    if ((this).i == null) return;
+    (this).i.isEven;
+//           ^^^^^^
+// [analyzer 1] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// [cfe 7] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
+  }
+
+  get_property_by_implicit_this() {
+    if (i == null) return;
+    i.isEven;
+//    ^^^^^^
+// [analyzer 2] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// [cfe 8] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
+  }
+}
+
+extension E on C {
+  int? get i => null;
+  //       ^
+  // [context 1] 'i' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 2] 'i' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 3] 'i' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 4] 'i' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 5] 'i' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 6] 'i' refers to a property so it couldn't be promoted.
+  // [context 7] 'i' refers to a property so it couldn't be promoted.
+  // [context 8] 'i' refers to a property so it couldn't be promoted.
+  // [context 9] 'i' refers to a property so it couldn't be promoted.
+  // [context 10] 'i' refers to a property so it couldn't be promoted.
+  int? get j => null;
+}
+
+class D extends C {
+  get_property_by_implicit_super() {
+    if (i == null) return;
+    i.isEven;
+//    ^^^^^^
+// [analyzer 5] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// [cfe 9] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
+  }
+}
+
+get_property_via_prefixed_identifier(C c) {
+  if (c.i == null) return;
+  c.i.isEven;
+//    ^^^^^^
+// [analyzer 3] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// [cfe 10] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
+}
+
+get_property_via_prefixed_identifier_mismatched_target(C c1, C c2) {
+  // Note: no context on this error because the property the user is attempting
+  // to promote is on c1, but the property the user is accessing is on c2.
+  if (c1.i == null) return;
+  c2.i.isEven;
+//     ^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// [cfe] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
+}
+
+get_property_via_prefixed_identifier_mismatched_property(C c) {
+  // Note: no context on this error because the property the user is attempting
+  // to promote is C.i, but the property the user is accessing is C.j.
+  if (c.i == null) return;
+  c.j.isEven;
+//    ^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// [cfe] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
+}
diff --git a/tests/language/why_not_promoted/field_error_test.dart b/tests/language/why_not_promoted/field_error_test.dart
new file mode 100644
index 0000000..d010924
--- /dev/null
+++ b/tests/language/why_not_promoted/field_error_test.dart
@@ -0,0 +1,91 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class C {
+  int? i;
+  //   ^
+  // [context 1] 'i' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 2] 'i' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 3] 'i' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 4] 'i' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 5] 'i' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 6] 'i' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 7] 'i' refers to a property so it couldn't be promoted.
+  // [context 8] 'i' refers to a property so it couldn't be promoted.
+  // [context 9] 'i' refers to a property so it couldn't be promoted.
+  // [context 10] 'i' refers to a property so it couldn't be promoted.
+  // [context 11] 'i' refers to a property so it couldn't be promoted.
+  // [context 12] 'i' refers to a property so it couldn't be promoted.
+  int? j;
+
+  get_field_via_explicit_this() {
+    if (this.i == null) return;
+    this.i.isEven;
+//         ^^^^^^
+// [analyzer 2] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// [cfe 7] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
+  }
+
+  get_field_via_explicit_this_parenthesized() {
+    if ((this).i == null) return;
+    (this).i.isEven;
+//           ^^^^^^
+// [analyzer 3] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// [cfe 8] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
+  }
+
+  get_field_by_implicit_this() {
+    if (i == null) return;
+    i.isEven;
+//    ^^^^^^
+// [analyzer 5] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// [cfe 9] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
+  }
+}
+
+class D extends C {
+  get_field_via_explicit_super() {
+    if (super.i == null) return;
+    super.i.isEven;
+//          ^^^^^^
+// [analyzer 4] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// [cfe 10] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
+  }
+
+  get_field_by_implicit_super() {
+    if (i == null) return;
+    i.isEven;
+//    ^^^^^^
+// [analyzer 1] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// [cfe 11] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
+  }
+}
+
+get_field_via_prefixed_identifier(C c) {
+  if (c.i == null) return;
+  c.i.isEven;
+//    ^^^^^^
+// [analyzer 6] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// [cfe 12] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
+}
+
+get_field_via_prefixed_identifier_mismatched_target(C c1, C c2) {
+  // Note: no context on this error because the property the user is attempting
+  // to promote is on c1, but the property the user is accessing is on c2.
+  if (c1.i == null) return;
+  c2.i.isEven;
+//     ^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// [cfe] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
+}
+
+get_field_via_prefixed_identifier_mismatched_property(C c) {
+  // Note: no context on this error because the property the user is attempting
+  // to promote is C.i, but the property the user is accessing is C.j.
+  if (c.i == null) return;
+  c.j.isEven;
+//    ^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// [cfe] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
+}
diff --git a/tests/language/why_not_promoted/for_in_loop_type_not_iterable_nullability_error_test.dart b/tests/language/why_not_promoted/for_in_loop_type_not_iterable_nullability_error_test.dart
new file mode 100644
index 0000000..ecf7b84
--- /dev/null
+++ b/tests/language/why_not_promoted/for_in_loop_type_not_iterable_nullability_error_test.dart
@@ -0,0 +1,101 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for 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 contains a test case for each condition that can lead to the front
+// end's `ForInLoopTypeNotIterableNullability` or
+// `ForInLoopTypeNotIterablePartNullability` errors, for which we wish to report
+// "why not promoted" context information.
+
+class C1 {
+  List<int>? bad;
+  //         ^^^
+  // [context 1] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 2] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 3] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 4] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 5] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 6] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 7] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 8] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 9] 'bad' refers to a property so it couldn't be promoted.
+  // [context 10] 'bad' refers to a property so it couldn't be promoted.
+  // [context 11] 'bad' refers to a property so it couldn't be promoted.
+  // [context 12] 'bad' refers to a property so it couldn't be promoted.
+  // [context 13] 'bad' refers to a property so it couldn't be promoted.
+  // [context 14] 'bad' refers to a property so it couldn't be promoted.
+  // [context 15] 'bad' refers to a property so it couldn't be promoted.
+  // [context 16] 'bad' refers to a property so it couldn't be promoted.
+}
+
+forStatement(C1 c) {
+  if (c.bad == null) return;
+  for (var x in c.bad) {}
+  //            ^^^^^
+  // [analyzer 6] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  //              ^
+  // [cfe 9] The type 'List<int>?' used in the 'for' loop must implement 'Iterable<dynamic>' because 'List<int>?' is nullable and 'Iterable<dynamic>' isn't.
+}
+
+forElementInList(C1 c) {
+  if (c.bad == null) return;
+  [for (var x in c.bad) null];
+  //             ^^^^^
+  // [analyzer 7] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  //               ^
+  // [cfe 10] The type 'List<int>?' used in the 'for' loop must implement 'Iterable<dynamic>' because 'List<int>?' is nullable and 'Iterable<dynamic>' isn't.
+}
+
+forElementInSet(C1 c) {
+  if (c.bad == null) return;
+  <dynamic>{for (var x in c.bad) null};
+  //                      ^^^^^
+  // [analyzer 3] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  //                        ^
+  // [cfe 11] The type 'List<int>?' used in the 'for' loop must implement 'Iterable<dynamic>' because 'List<int>?' is nullable and 'Iterable<dynamic>' isn't.
+}
+
+forElementInMap(C1 c) {
+  if (c.bad == null) return;
+  <dynamic, dynamic>{for (var x in c.bad) null: null};
+  //                               ^^^^^
+  // [analyzer 1] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  //                                 ^
+  // [cfe 12] The type 'List<int>?' used in the 'for' loop must implement 'Iterable<dynamic>' because 'List<int>?' is nullable and 'Iterable<dynamic>' isn't.
+}
+
+forElementInAmbiguousSet_resolvableDuringParsing(C1 c) {
+  if (c.bad == null) return;
+  ({for (var x in c.bad) null});
+  //              ^^^^^
+  // [analyzer 5] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  //                ^
+  // [cfe 13] The type 'List<int>?' used in the 'for' loop must implement 'Iterable<dynamic>' because 'List<int>?' is nullable and 'Iterable<dynamic>' isn't.
+}
+
+forElementInAmbiguousMap_resolvableDuringParsing(C1 c) {
+  if (c.bad == null) return;
+  ({for (var x in c.bad) null: null});
+  //              ^^^^^
+  // [analyzer 2] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  //                ^
+  // [cfe 14] The type 'List<int>?' used in the 'for' loop must implement 'Iterable<dynamic>' because 'List<int>?' is nullable and 'Iterable<dynamic>' isn't.
+}
+
+forElementInAmbiguousSet_notResolvableDuringParsing(C1 c, List list) {
+  if (c.bad == null) return;
+  ({for (var x in c.bad) ...list});
+  //              ^^^^^
+  // [analyzer 4] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  //                ^
+  // [cfe 15] The type 'List<int>?' used in the 'for' loop must implement 'Iterable<dynamic>' because 'List<int>?' is nullable and 'Iterable<dynamic>' isn't.
+}
+
+forElementInAmbiguousMap_notResolvableDuringParsing(C1 c, Map map) {
+  if (c.bad == null) return;
+  ({for (var x in c.bad) ...map});
+  //              ^^^^^
+  // [analyzer 8] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  //                ^
+  // [cfe 16] The type 'List<int>?' used in the 'for' loop must implement 'Iterable<dynamic>' because 'List<int>?' is nullable and 'Iterable<dynamic>' isn't.
+}
diff --git a/tests/language/why_not_promoted/invalid_assignment_error_nullability_error_test.dart b/tests/language/why_not_promoted/invalid_assignment_error_nullability_error_test.dart
new file mode 100644
index 0000000..67f6c40
--- /dev/null
+++ b/tests/language/why_not_promoted/invalid_assignment_error_nullability_error_test.dart
@@ -0,0 +1,25 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for 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 contains a test case for each condition that can lead to the front
+// end's `InvalidAssignmentErrorNullability` or
+// `InvalidAssignmentErrorPartNullability` errors, for which we wish to report
+// "why not promoted" context information.
+
+class C1 {
+  List<int>? bad;
+  //         ^^^
+  // [context 1] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 2] 'bad' refers to a property so it couldn't be promoted.
+}
+
+test(C1 c) sync* {
+  if (c.bad == null) return;
+  yield* c.bad;
+  //     ^^^^^
+  // [analyzer 1] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  // [analyzer] COMPILE_TIME_ERROR.YIELD_OF_INVALID_TYPE
+  //       ^
+  // [cfe 2] A value of type 'List<int>?' can't be assigned to a variable of type 'Iterable<dynamic>' because 'List<int>?' is nullable and 'Iterable<dynamic>' isn't.
+}
diff --git a/tests/language/why_not_promoted/nullable_expression_call_error_test.dart b/tests/language/why_not_promoted/nullable_expression_call_error_test.dart
new file mode 100644
index 0000000..46413a9
--- /dev/null
+++ b/tests/language/why_not_promoted/nullable_expression_call_error_test.dart
@@ -0,0 +1,139 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for 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 contains a test case for each condition that can lead to the front
+// end's `NullableExpressionCallError`, for which we wish to report "why not
+// promoted" context information.
+
+class C1 {
+  C2? bad;
+  //  ^^^
+  // [context 3] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 7] 'bad' refers to a property so it couldn't be promoted.
+}
+
+class C2 {
+  void call() {}
+}
+
+instance_method_invocation(C1 c) {
+  if (c.bad == null) return;
+  c.bad();
+//^^^^^
+// [analyzer 3] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+//     ^
+// [cfe 7] Can't use an expression of type 'C2?' as a function because it's potentially null.
+}
+
+class C3 {
+  C4? ok;
+  C5? bad;
+  //  ^^^
+  // [context 1] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 8] 'bad' refers to a property so it couldn't be promoted.
+}
+
+class C4 {}
+
+class C5 {}
+
+extension on C4? {
+  void call() {}
+}
+
+extension on C5 {
+  void call() {}
+}
+
+extension_invocation_method(C3 c) {
+  if (c.ok == null) return;
+  c.ok();
+  if (c.bad == null) return;
+  c.bad();
+//^^^^^
+// [analyzer 1] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+//     ^
+// [cfe 8] Can't use an expression of type 'C5?' as a function because it's potentially null.
+}
+
+class C6 {
+  C7? bad;
+  //  ^^^
+  // [context 6] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 9] 'bad' refers to a property so it couldn't be promoted.
+}
+
+class C7 {
+  void Function() get call => () {};
+}
+
+instance_getter_invocation(C6 c) {
+  if (c.bad == null) return;
+  c.bad();
+//^^^^^
+// [analyzer] COMPILE_TIME_ERROR.INVOCATION_OF_NON_FUNCTION_EXPRESSION
+// [analyzer 6] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+//     ^
+// [cfe 9] Can't use an expression of type 'C7?' as a function because it's potentially null.
+}
+
+class C8 {
+  C10? bad;
+  //   ^^^
+  // [context 4] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 10] 'bad' refers to a property so it couldn't be promoted.
+}
+
+class C10 {}
+
+extension on C10 {
+  void Function() get call => () {};
+}
+
+extension_invocation_getter(C8 c) {
+  if (c.bad == null) return;
+  c.bad();
+//^^^^^
+// [analyzer 4] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+//     ^
+// [cfe 10] Can't use an expression of type 'C10?' as a function because it's potentially null.
+}
+
+class C11 {
+  void Function()? bad;
+  //               ^^^
+  // [context 5] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 11] 'bad' refers to a property so it couldn't be promoted.
+}
+
+function_invocation(C11 c) {
+  if (c.bad == null) return;
+  c.bad();
+//^^^^^
+// [analyzer 5] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+//     ^
+// [cfe 11] Can't use an expression of type 'void Function()?' as a function because it's potentially null.
+}
+
+class C12 {
+  C13? bad;
+  //   ^^^
+  // [context 2] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 12] 'bad' refers to a property so it couldn't be promoted.
+}
+
+class C13 {
+  void Function() foo;
+  C13(this.foo);
+}
+
+instance_field_invocation(C12 c) {
+  if (c.bad == null) return;
+  // Note: the CFE error message is misleading here.  See
+  // https://github.com/dart-lang/sdk/issues/45552
+  c.bad.foo();
+//      ^^^
+// [analyzer 2] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// [cfe 12] Can't use an expression of type 'C13?' as a function because it's potentially null.
+}
diff --git a/tests/language/why_not_promoted/nullable_method_call_error_test.dart b/tests/language/why_not_promoted/nullable_method_call_error_test.dart
new file mode 100644
index 0000000..56d5e93
--- /dev/null
+++ b/tests/language/why_not_promoted/nullable_method_call_error_test.dart
@@ -0,0 +1,101 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for 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 contains a test case for each condition that can lead to the front
+// end's `NullableMethodCallError`, for which we wish to report "why not
+// promoted" context information.
+
+class C {
+  int? i;
+  //   ^
+  // [context 2] 'i' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 3] 'i' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 4] 'i' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 5] 'i' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 10] 'i' refers to a property so it couldn't be promoted.
+  // [context 11] 'i' refers to a property so it couldn't be promoted.
+  // [context 12] 'i' refers to a property so it couldn't be promoted.
+  // [context 13] 'i' refers to a property so it couldn't be promoted.
+  void Function()? f;
+  //               ^
+  // [context 7] 'f' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 14] 'f' refers to a property so it couldn't be promoted.
+}
+
+extension on int {
+  get propertyOnNonNullInt => null;
+  void methodOnNonNullInt() {}
+}
+
+extension on int? {
+  get propertyOnNullableInt => null;
+  void methodOnNullableInt() {}
+}
+
+property_get_of_variable(int? i, int? j) {
+  if (i == null) return;
+  i = j;
+//^^^^^
+// [context 6] Variable 'i' could not be promoted due to an assignment.  See http://dart.dev/go/non-promo-write
+// [context 8] Variable 'i' could not be promoted due to an assignment.
+  i.isEven;
+//  ^^^^^^
+// [analyzer 6] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// [cfe 8] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
+}
+
+extension_property_get_of_variable(int? i, int? j) {
+  if (i == null) return;
+  i = j;
+//^^^^^
+// [context 1] Variable 'i' could not be promoted due to an assignment.  See http://dart.dev/go/non-promo-write
+// [context 9] Variable 'i' could not be promoted due to an assignment.
+  i.propertyOnNullableInt;
+  i.propertyOnNonNullInt;
+//  ^^^^^^^^^^^^^^^^^^^^
+// [analyzer 1] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// [cfe 9] Property 'propertyOnNonNullInt' cannot be accessed on 'int?' because it is potentially null.
+}
+
+property_get_of_expression(C c) {
+  if (c.i == null) return;
+  c.i.isEven;
+//    ^^^^^^
+// [analyzer 3] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// [cfe 10] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
+}
+
+extension_property_get_of_expression(C c) {
+  if (c.i == null) return;
+  c.i.propertyOnNullableInt;
+  c.i.propertyOnNonNullInt;
+//    ^^^^^^^^^^^^^^^^^^^^
+// [analyzer 2] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// [cfe 11] Property 'propertyOnNonNullInt' cannot be accessed on 'int?' because it is potentially null.
+}
+
+method_invocation(C c) {
+  if (c.i == null) return;
+  c.i.abs();
+//    ^^^
+// [analyzer 4] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// [cfe 12] Method 'abs' cannot be called on 'int?' because it is potentially null.
+}
+
+extension_method_invocation(C c) {
+  if (c.i == null) return;
+  c.i.methodOnNullableInt();
+  c.i.methodOnNonNullInt();
+//    ^^^^^^^^^^^^^^^^^^
+// [analyzer 5] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// [cfe 13] Method 'methodOnNonNullInt' cannot be called on 'int?' because it is potentially null.
+}
+
+call_invocation(C c) {
+  if (c.f == null) return;
+  c.f.call();
+//    ^^^^
+// [analyzer 7] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// [cfe 14] Method 'call' cannot be called on 'void Function()?' because it is potentially null.
+}
diff --git a/tests/language/why_not_promoted/nullable_spread_error_test.dart b/tests/language/why_not_promoted/nullable_spread_error_test.dart
new file mode 100644
index 0000000..03d98ed
--- /dev/null
+++ b/tests/language/why_not_promoted/nullable_spread_error_test.dart
@@ -0,0 +1,215 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for 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 contains a test case for each condition that can lead to the front
+// end's `NullableSpreadError` error, for which we wish to report "why not
+// promoted" context information.
+
+class C {
+  List<int>? listQuestion;
+  //         ^^^^^^^^^^^^
+  // [context 7] 'listQuestion' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 9] 'listQuestion' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 15] 'listQuestion' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 17] 'listQuestion' refers to a property so it couldn't be promoted.
+  // [context 21] 'listQuestion' refers to a property so it couldn't be promoted.
+  // [context 27] 'listQuestion' refers to a property so it couldn't be promoted.
+  Object? objectQuestion;
+  //      ^^^^^^^^^^^^^^
+  // [context 1] 'objectQuestion' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 6] 'objectQuestion' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 10] 'objectQuestion' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 11] 'objectQuestion' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 12] 'objectQuestion' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 16] 'objectQuestion' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 20] 'objectQuestion' refers to a property so it couldn't be promoted.
+  // [context 24] 'objectQuestion' refers to a property so it couldn't be promoted.
+  // [context 25] 'objectQuestion' refers to a property so it couldn't be promoted.
+  // [context 26] 'objectQuestion' refers to a property so it couldn't be promoted.
+  // [context 30] 'objectQuestion' refers to a property so it couldn't be promoted.
+  // [context 31] 'objectQuestion' refers to a property so it couldn't be promoted.
+  Set<int>? setQuestion;
+  //        ^^^^^^^^^^^
+  // [context 4] 'setQuestion' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 5] 'setQuestion' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 8] 'setQuestion' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 14] 'setQuestion' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 18] 'setQuestion' refers to a property so it couldn't be promoted.
+  // [context 22] 'setQuestion' refers to a property so it couldn't be promoted.
+  // [context 28] 'setQuestion' refers to a property so it couldn't be promoted.
+  // [context 32] 'setQuestion' refers to a property so it couldn't be promoted.
+  Map<int, int>? mapQuestion;
+  //             ^^^^^^^^^^^
+  // [context 2] 'mapQuestion' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 3] 'mapQuestion' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 13] 'mapQuestion' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 19] 'mapQuestion' refers to a property so it couldn't be promoted.
+  // [context 23] 'mapQuestion' refers to a property so it couldn't be promoted.
+  // [context 29] 'mapQuestion' refers to a property so it couldn't be promoted.
+}
+
+list_from_list_question(C c) {
+  if (c.listQuestion == null) return;
+  return [...c.listQuestion];
+  //         ^^^^^^^^^^^^^^
+  // [analyzer 7] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  //           ^
+  // [cfe 17] An expression whose value can be 'null' must be null-checked before it can be dereferenced.
+}
+
+list_from_set_question(C c) {
+  if (c.setQuestion == null) return;
+  return [...c.setQuestion];
+  //         ^^^^^^^^^^^^^
+  // [analyzer 4] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  //           ^
+  // [cfe 18] An expression whose value can be 'null' must be null-checked before it can be dereferenced.
+}
+
+list_from_map_question(C c) {
+  if (c.mapQuestion == null) return;
+  return [...c.mapQuestion];
+  //         ^^^^^^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.NOT_ITERABLE_SPREAD
+  // [analyzer 3] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  //           ^
+  // [cfe 19] An expression whose value can be 'null' must be null-checked before it can be dereferenced.
+  // [cfe] Unexpected type 'Map<int, int>?' of a spread.  Expected 'dynamic' or an Iterable.
+}
+
+list_from_object_question(C c) {
+  if (c.objectQuestion is! List<int>) return;
+  return [...c.objectQuestion];
+  //         ^^^^^^^^^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.NOT_ITERABLE_SPREAD
+  // [analyzer 16] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  //           ^
+  // [cfe 20] An expression whose value can be 'null' must be null-checked before it can be dereferenced.
+  // [cfe] Unexpected type 'Object?' of a spread.  Expected 'dynamic' or an Iterable.
+}
+
+set_from_list_question(C c) {
+  if (c.listQuestion == null) return;
+  return {...c.listQuestion};
+  //         ^^^^^^^^^^^^^^
+  // [analyzer 9] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  //           ^
+  // [cfe 21] An expression whose value can be 'null' must be null-checked before it can be dereferenced.
+}
+
+set_from_set_question(C c) {
+  if (c.setQuestion == null) return;
+  return {...c.setQuestion};
+  //         ^^^^^^^^^^^^^
+  // [analyzer 5] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  //           ^
+  // [cfe 22] An expression whose value can be 'null' must be null-checked before it can be dereferenced.
+}
+
+set_from_map_question(C c) {
+  if (c.mapQuestion == null) return;
+  return {...c.mapQuestion};
+  //         ^^^^^^^^^^^^^
+  // [analyzer 2] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  //           ^
+  // [cfe 23] An expression whose value can be 'null' must be null-checked before it can be dereferenced.
+}
+
+set_from_object_question_type_disambiguate_by_entry(C c) {
+  if (c.objectQuestion is! Set<int>) return;
+  return {null, ...c.objectQuestion};
+  //     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_SET_OR_MAP_LITERAL_EITHER
+  //               ^^^^^^^^^^^^^^^^
+  // [analyzer 6] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  //                 ^
+  // [cfe 24] An expression whose value can be 'null' must be null-checked before it can be dereferenced.
+  // [cfe] Unexpected type 'Object?' of a spread.  Expected 'dynamic' or an Iterable.
+}
+
+set_from_object_question_type_disambiguate_by_previous_spread(C c) {
+  if (c.objectQuestion is! Set<int>) return;
+  return {...<int>{}, ...c.objectQuestion};
+  //     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_SET_OR_MAP_LITERAL_EITHER
+  //                     ^^^^^^^^^^^^^^^^
+  // [analyzer 12] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  //                       ^
+  // [cfe 25] Unexpected type 'Object?' of a map spread entry.  Expected 'dynamic' or a Map.
+}
+
+set_from_object_question_type_disambiguate_by_literal_args(C c) {
+  if (c.objectQuestion is! Set<int>) return;
+  return <int>{...c.objectQuestion};
+  //              ^^^^^^^^^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.NOT_ITERABLE_SPREAD
+  // [analyzer 1] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  //                ^
+  // [cfe 26] An expression whose value can be 'null' must be null-checked before it can be dereferenced.
+  // [cfe] Unexpected type 'Object?' of a spread.  Expected 'dynamic' or an Iterable.
+}
+
+map_from_list_question(C c) {
+  if (c.listQuestion == null) return;
+  return {...c.listQuestion};
+  //         ^^^^^^^^^^^^^^
+  // [analyzer 15] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  //           ^
+  // [cfe 27] An expression whose value can be 'null' must be null-checked before it can be dereferenced.
+}
+
+map_from_set_question(C c) {
+  if (c.setQuestion == null) return;
+  return {...c.setQuestion};
+  //         ^^^^^^^^^^^^^
+  // [analyzer 14] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  //           ^
+  // [cfe 28] An expression whose value can be 'null' must be null-checked before it can be dereferenced.
+}
+
+map_from_map_question(C c) {
+  if (c.mapQuestion == null) return;
+  return {...c.mapQuestion};
+  //         ^^^^^^^^^^^^^
+  // [analyzer 13] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  //           ^
+  // [cfe 29] An expression whose value can be 'null' must be null-checked before it can be dereferenced.
+}
+
+map_from_object_question_type_disambiguate_by_key_value_pair(C c) {
+  if (c.objectQuestion is! Map<int, int>) return;
+  return {null: null, ...c.objectQuestion};
+  //     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_SET_OR_MAP_LITERAL_EITHER
+  //                     ^^^^^^^^^^^^^^^^
+  // [analyzer 10] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  //                       ^
+  // [cfe 30] Unexpected type 'Object?' of a map spread entry.  Expected 'dynamic' or a Map.
+}
+
+map_from_object_question_type_disambiguate_by_previous_spread(C c) {
+  if (c.objectQuestion is! Map<int, int>) return;
+  return {...<int, int>{}, ...c.objectQuestion};
+  //     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_SET_OR_MAP_LITERAL_EITHER
+  //                          ^^^^^^^^^^^^^^^^
+  // [analyzer 11] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  //                            ^
+  // [cfe 31] Unexpected type 'Object?' of a map spread entry.  Expected 'dynamic' or a Map.
+}
+
+map_from_set_question_type_disambiguate_by_literal_args(C c) {
+  // Note: analyzer shows "why not promoted" information here, but CFE doesn't.
+  // That's probably ok, since there are two problems here (set/map mismatch and
+  // null safety); it's a matter of interpretation whether to prioritize one or
+  // the other.
+  if (c.setQuestion == null) return;
+  return <int, int>{...c.setQuestion};
+  //                   ^^^^^^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.NOT_MAP_SPREAD
+  // [analyzer 8] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  //                     ^
+  // [cfe 32] An expression whose value can be 'null' must be null-checked before it can be dereferenced.
+  // [cfe] Unexpected type 'Set<int>?' of a map spread entry.  Expected 'dynamic' or a Map.
+}
diff --git a/tests/language/why_not_promoted/property_error_test.dart b/tests/language/why_not_promoted/property_error_test.dart
new file mode 100644
index 0000000..02b1615
--- /dev/null
+++ b/tests/language/why_not_promoted/property_error_test.dart
@@ -0,0 +1,91 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class C {
+  int? get i => null;
+  //       ^
+  // [context 1] 'i' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 2] 'i' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 3] 'i' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 4] 'i' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 5] 'i' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 6] 'i' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
+  // [context 7] 'i' refers to a property so it couldn't be promoted.
+  // [context 8] 'i' refers to a property so it couldn't be promoted.
+  // [context 9] 'i' refers to a property so it couldn't be promoted.
+  // [context 10] 'i' refers to a property so it couldn't be promoted.
+  // [context 11] 'i' refers to a property so it couldn't be promoted.
+  // [context 12] 'i' refers to a property so it couldn't be promoted.
+  int? get j => null;
+
+  get_property_via_explicit_this() {
+    if (this.i == null) return;
+    this.i.isEven;
+//         ^^^^^^
+// [analyzer 1] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// [cfe 7] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
+  }
+
+  get_property_via_explicit_this_parenthesized() {
+    if ((this).i == null) return;
+    (this).i.isEven;
+//           ^^^^^^
+// [analyzer 3] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// [cfe 8] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
+  }
+
+  get_property_by_implicit_this() {
+    if (i == null) return;
+    i.isEven;
+//    ^^^^^^
+// [analyzer 4] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// [cfe 9] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
+  }
+}
+
+class D extends C {
+  get_property_via_explicit_super() {
+    if (super.i == null) return;
+    super.i.isEven;
+//          ^^^^^^
+// [analyzer 6] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// [cfe 10] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
+  }
+
+  get_property_by_implicit_super() {
+    if (i == null) return;
+    i.isEven;
+//    ^^^^^^
+// [analyzer 5] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// [cfe 11] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
+  }
+}
+
+get_property_via_prefixed_identifier(C c) {
+  if (c.i == null) return;
+  c.i.isEven;
+//    ^^^^^^
+// [analyzer 2] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// [cfe 12] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
+}
+
+get_property_via_prefixed_identifier_mismatched_target(C c1, C c2) {
+  // Note: no context on this error because the property the user is attempting
+  // to promote is on c1, but the property the user is accessing is on c2.
+  if (c1.i == null) return;
+  c2.i.isEven;
+//     ^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// [cfe] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
+}
+
+get_property_via_prefixed_identifier_mismatched_property(C c) {
+  // Note: no context on this error because the property the user is attempting
+  // to promote is C.i, but the property the user is accessing is C.j.
+  if (c.i == null) return;
+  c.j.isEven;
+//    ^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// [cfe] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
+}
diff --git a/tests/language/why_not_promoted/this_error_test.dart b/tests/language/why_not_promoted/this_error_test.dart
new file mode 100644
index 0000000..2d836ee
--- /dev/null
+++ b/tests/language/why_not_promoted/this_error_test.dart
@@ -0,0 +1,32 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for 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 validates integration of "why not promoted" when the user tries to
+// promote `this`.
+
+// TODO(paulberry): once we support adding "why not promoted" information to
+// errors that aren't related to null safety, test references to `this` in
+// classes and mixins.
+
+extension on int? {
+  extension_explicit_this() {
+    // TODO(paulberry): get this to work with the CFE.
+    if (this == null) return;
+    this.isEven;
+//       ^^^^^^
+// [analyzer 2] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// [context 2] 'this' can't be promoted.  See http://dart.dev/go/non-promo-this
+// [cfe] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
+  }
+
+  extension_implicit_this() {
+    // TODO(paulberry): get this to work with the CFE.
+    if (this == null) return;
+    isEven;
+//  ^^^^^^
+// [analyzer 1] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// [context 1] 'this' can't be promoted.  See http://dart.dev/go/non-promo-this
+// [cfe] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
+  }
+}
diff --git a/tests/language_2/deferred/inheritance_constraints_test.dart b/tests/language_2/deferred/inheritance_constraints_test.dart
index 2d9429b..7477a57 100644
--- a/tests/language_2/deferred/inheritance_constraints_test.dart
+++ b/tests/language_2/deferred/inheritance_constraints_test.dart
@@ -11,17 +11,17 @@
 
 class A extends lib.Foo {}
 //              ^^^^^^^
-// [analyzer] COMPILE_TIME_ERROR.EXTENDS_DEFERRED_CLASS
+// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_DEFERRED_CLASS
 
 class B implements lib.Foo {}
 //                 ^^^^^^^
-// [analyzer] COMPILE_TIME_ERROR.IMPLEMENTS_DEFERRED_CLASS
+// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_DEFERRED_CLASS
 
 class C1 {}
 
 class C = C1 with lib.Foo;
 //                ^^^^^^^
-// [analyzer] COMPILE_TIME_ERROR.MIXIN_DEFERRED_CLASS
+// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_DEFERRED_CLASS
 
 class D {
   D();
diff --git a/tests/language_2/deferred/load_constants_test.dart b/tests/language_2/deferred/load_constants_test.dart
index a57e24c..546b038 100644
--- a/tests/language_2/deferred/load_constants_test.dart
+++ b/tests/language_2/deferred/load_constants_test.dart
@@ -28,31 +28,31 @@
     //                  ^
     // [cfe] Constant evaluation error:
     //                         ^^^^^
-    // [analyzer] COMPILE_TIME_ERROR.NON_CONSTANT_LIST_ELEMENT_FROM_DEFERRED_LIBRARY
+    // [analyzer] COMPILE_TIME_ERROR.COLLECTION_ELEMENT_FROM_DEFERRED_LIBRARY
     // [cfe] 'foo' can't be used in a constant expression because it's marked as 'deferred' which means it isn't available until loaded.
     Expect.throws(() => const [foo.C]);
     //                  ^
     // [cfe] Constant evaluation error:
     //                         ^^^^^
-    // [analyzer] COMPILE_TIME_ERROR.NON_CONSTANT_LIST_ELEMENT_FROM_DEFERRED_LIBRARY
+    // [analyzer] COMPILE_TIME_ERROR.COLLECTION_ELEMENT_FROM_DEFERRED_LIBRARY
     // [cfe] 'foo' can't be used in a constant expression because it's marked as 'deferred' which means it isn't available until loaded.
     Expect.throws(() => const [foo.funtype]);
     //                  ^
     // [cfe] Constant evaluation error:
     //                         ^^^^^^^^^^^
-    // [analyzer] COMPILE_TIME_ERROR.NON_CONSTANT_LIST_ELEMENT_FROM_DEFERRED_LIBRARY
+    // [analyzer] COMPILE_TIME_ERROR.COLLECTION_ELEMENT_FROM_DEFERRED_LIBRARY
     // [cfe] 'foo' can't be used in a constant expression because it's marked as 'deferred' which means it isn't available until loaded.
     Expect.throws(() => const [foo.toplevel]);
     //                  ^
     // [cfe] Constant evaluation error:
     //                         ^^^^^^^^^^^^
-    // [analyzer] COMPILE_TIME_ERROR.NON_CONSTANT_LIST_ELEMENT_FROM_DEFERRED_LIBRARY
+    // [analyzer] COMPILE_TIME_ERROR.COLLECTION_ELEMENT_FROM_DEFERRED_LIBRARY
     // [cfe] 'foo' can't be used in a constant expression because it's marked as 'deferred' which means it isn't available until loaded.
     Expect.throws(() => const [foo.C.staticfun]);
     //                  ^
     // [cfe] Constant evaluation error:
     //                         ^^^^^^^^^^^^^^^
-    // [analyzer] COMPILE_TIME_ERROR.NON_CONSTANT_LIST_ELEMENT_FROM_DEFERRED_LIBRARY
+    // [analyzer] COMPILE_TIME_ERROR.COLLECTION_ELEMENT_FROM_DEFERRED_LIBRARY
     // [cfe] 'foo' can't be used in a constant expression because it's marked as 'deferred' which means it isn't available until loaded.
 
     asyncEnd();
diff --git a/tests/language_2/extension_methods/issue_45551_error_test.dart b/tests/language_2/extension_methods/issue_45551_error_test.dart
new file mode 100644
index 0000000..524b4f6
--- /dev/null
+++ b/tests/language_2/extension_methods/issue_45551_error_test.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for 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 illustrates the error scenario described in
+// https://github.com/dart-lang/sdk/issues/45551
+
+class C {}
+
+extension on C {
+  void Function() get call => () {};
+}
+
+test(C c) {
+  c();
+//^
+// [analyzer] COMPILE_TIME_ERROR.INVOCATION_OF_NON_FUNCTION_EXPRESSION
+// ^
+// [cfe] Cannot invoke an instance of 'C' because it declares 'call' to be something other than a method.
+}
+
+main() {}
diff --git a/tests/language_2/generic/function_typedef2_test.dart b/tests/language_2/generic/function_typedef2_test.dart
index 704a824..b7ae03a 100644
--- a/tests/language_2/generic/function_typedef2_test.dart
+++ b/tests/language_2/generic/function_typedef2_test.dart
@@ -11,19 +11,19 @@
 
 typedef G = F;
 //        ^
-// [analyzer] SYNTACTIC_ERROR.INVALID_GENERIC_FUNCTION_TYPE
+// [analyzer] SYNTACTIC_ERROR.EXPERIMENT_NOT_ENABLED
 // [cfe] Can't create typedef from non-function type.
 typedef H = int;
 //        ^
-// [analyzer] SYNTACTIC_ERROR.INVALID_GENERIC_FUNCTION_TYPE
+// [analyzer] SYNTACTIC_ERROR.EXPERIMENT_NOT_ENABLED
 // [cfe] Can't create typedef from non-function type.
 typedef I = A;
 //        ^
-// [analyzer] SYNTACTIC_ERROR.INVALID_GENERIC_FUNCTION_TYPE
+// [analyzer] SYNTACTIC_ERROR.EXPERIMENT_NOT_ENABLED
 // [cfe] Can't create typedef from non-function type.
 typedef J = List<int>;
 //        ^
-// [analyzer] SYNTACTIC_ERROR.INVALID_GENERIC_FUNCTION_TYPE
+// [analyzer] SYNTACTIC_ERROR.EXPERIMENT_NOT_ENABLED
 // [cfe] Can't create typedef from non-function type.
 typedef K = Function(Function<A>(A<int>));
 //                               ^^^^^^
diff --git a/tests/language_2/language_2_dart2js.status b/tests/language_2/language_2_dart2js.status
index aaaf533..7b214ff 100644
--- a/tests/language_2/language_2_dart2js.status
+++ b/tests/language_2/language_2_dart2js.status
@@ -14,6 +14,7 @@
 
 [ $builder_tag == dart2js_production && $compiler == dart2js ]
 control_flow_collections/for_non_bool_condition_test: Crash # Issue 36442
+regress/regress45428_test: SkipByDesign # No argument type checks in production mode, issue 45528
 
 [ $compiler == dart2js && $runtime == chromeOnAndroid ]
 override_field_test/02: Slow, Pass # TODO(kasperl): Please triage.
diff --git a/tests/language_2/list/literal5_test.dart b/tests/language_2/list/literal5_test.dart
index 81969be..ea27f04 100644
--- a/tests/language_2/list/literal5_test.dart
+++ b/tests/language_2/list/literal5_test.dart
@@ -6,10 +6,7 @@
 
 main() {
   new List<int>[1, 2];
-  //          ^
-  // [analyzer] SYNTACTIC_ERROR.EXPECTED_TOKEN
-  // [cfe] Expected '(' after this.
-  //             ^
-  // [analyzer] SYNTACTIC_ERROR.EXPECTED_TOKEN
-  // [cfe] Expected ']' before this.
+//^^^^^^^^
+// [analyzer] SYNTACTIC_ERROR.LITERAL_WITH_CLASS_AND_NEW
+// [cfe] A list literal can't be prefixed by 'new List'.
 }
diff --git a/tests/language_2/map/literal13_test.dart b/tests/language_2/map/literal13_test.dart
index 08f06e4..1ab622b2 100644
--- a/tests/language_2/map/literal13_test.dart
+++ b/tests/language_2/map/literal13_test.dart
@@ -6,76 +6,19 @@
 
 main() {
   var map = new Map<int>{ "a": 1, "b": 2, "c": 3 };
-  //            ^^^^^^^^
-  // [analyzer] COMPILE_TIME_ERROR.WRONG_NUMBER_OF_TYPE_ARGUMENTS
-  // [cfe] Expected 2 type arguments.
-  //                   ^
-  // [analyzer] SYNTACTIC_ERROR.EXPECTED_TOKEN
-  // [cfe] Expected '(' after this.
-  //                    ^
-  // [analyzer] SYNTACTIC_ERROR.EXPECTED_TOKEN
-  // [cfe] Expected ';' after this.
-  //                      ^^^
-  // [analyzer] SYNTACTIC_ERROR.EXPECTED_TOKEN
-  // [cfe] Expected ';' after this.
+  //        ^^^^^^^
+  // [analyzer] SYNTACTIC_ERROR.LITERAL_WITH_CLASS_AND_NEW
+  // [cfe] A map literal can't be prefixed by 'new Map'.
+  //                      ^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.MAP_ENTRY_NOT_IN_MAP
   //                         ^
-  // [analyzer] SYNTACTIC_ERROR.EXPECTED_TOKEN
-  // [cfe] Expected ';' after this.
-  //                         ^
-  // [analyzer] SYNTACTIC_ERROR.MISSING_IDENTIFIER
-  // [cfe] Expected an identifier, but got ':'.
-  //                         ^
-  // [analyzer] SYNTACTIC_ERROR.UNEXPECTED_TOKEN
-  // [cfe] Unexpected token ':'.
-  //                           ^
-  // [analyzer] SYNTACTIC_ERROR.EXPECTED_TOKEN
-  // [cfe] Expected ';' after this.
-  //                            ^
-  // [analyzer] SYNTACTIC_ERROR.EXPECTED_TOKEN
-  // [cfe] Expected ';' after this.
-  //                            ^
-  // [analyzer] SYNTACTIC_ERROR.MISSING_IDENTIFIER
-  // [cfe] Expected an identifier, but got ','.
-  //                            ^
-  // [analyzer] SYNTACTIC_ERROR.UNEXPECTED_TOKEN
-  // [cfe] Unexpected token ','.
-  //                              ^^^
-  // [analyzer] SYNTACTIC_ERROR.EXPECTED_TOKEN
-  // [cfe] Expected ';' after this.
+  // [cfe] Expected ',' before this.
+  //                              ^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.MAP_ENTRY_NOT_IN_MAP
   //                                 ^
-  // [analyzer] SYNTACTIC_ERROR.EXPECTED_TOKEN
-  // [cfe] Expected ';' after this.
-  //                                 ^
-  // [analyzer] SYNTACTIC_ERROR.MISSING_IDENTIFIER
-  // [cfe] Expected an identifier, but got ':'.
-  //                                 ^
-  // [analyzer] SYNTACTIC_ERROR.UNEXPECTED_TOKEN
-  // [cfe] Unexpected token ':'.
-  //                                   ^
-  // [analyzer] SYNTACTIC_ERROR.EXPECTED_TOKEN
-  // [cfe] Expected ';' after this.
-  //                                    ^
-  // [analyzer] SYNTACTIC_ERROR.EXPECTED_TOKEN
-  // [cfe] Expected ';' after this.
-  //                                    ^
-  // [analyzer] SYNTACTIC_ERROR.MISSING_IDENTIFIER
-  // [cfe] Expected an identifier, but got ','.
-  //                                    ^
-  // [analyzer] SYNTACTIC_ERROR.UNEXPECTED_TOKEN
-  // [cfe] Unexpected token ','.
-  //                                      ^^^
-  // [analyzer] SYNTACTIC_ERROR.EXPECTED_TOKEN
-  // [cfe] Expected ';' after this.
+  // [cfe] Expected ',' before this.
+  //                                      ^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.MAP_ENTRY_NOT_IN_MAP
   //                                         ^
-  // [analyzer] SYNTACTIC_ERROR.EXPECTED_TOKEN
-  // [cfe] Expected ';' after this.
-  //                                         ^
-  // [analyzer] SYNTACTIC_ERROR.MISSING_IDENTIFIER
-  // [cfe] Expected an identifier, but got ':'.
-  //                                         ^
-  // [analyzer] SYNTACTIC_ERROR.UNEXPECTED_TOKEN
-  // [cfe] Unexpected token ':'.
-  //                                           ^
-  // [analyzer] SYNTACTIC_ERROR.EXPECTED_TOKEN
-  // [cfe] Expected ';' after this.
+  // [cfe] Expected ',' before this.
 }
diff --git a/tests/language_2/regress/regress33479_test.dart b/tests/language_2/regress/regress33479_test.dart
index 568b6f8..a825b94 100644
--- a/tests/language_2/regress/regress33479_test.dart
+++ b/tests/language_2/regress/regress33479_test.dart
@@ -1,13 +1,17 @@
 class Hest<TypeX extends Fisk> {}
+//                       ^^^^
+// [analyzer] COMPILE_TIME_ERROR.NOT_INSTANTIATED_BOUND
 //         ^
 // [cfe] Type variables can't have generic function types in their bounds.
 
 typedef Fisk = void Function // don't merge lines
-// [error line 5, column 1, length 346]
+// [error line 7, 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.NOT_INSTANTIATED_BOUND
 
 main() {
   Hest hest = new Hest();
diff --git a/tests/language_2/regress/regress45428_test.dart b/tests/language_2/regress/regress45428_test.dart
new file mode 100644
index 0000000..37c1427
--- /dev/null
+++ b/tests/language_2/regress/regress45428_test.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use 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 something(List<String> l) {
+  String s = l.first;
+}
+
+void checkAndInvoke(Function f) {
+  f(["foo"]);
+  var l = <int>[1];
+  Expect.throwsTypeError(() => f(l));
+  if (f is Function(List<Never>)) {
+    Expect.throwsTypeError(() => (f as Function)(l));
+  }
+}
+
+void main() {
+  checkAndInvoke(something);
+}
diff --git a/tests/language_2/vm/allocation_sinking_arrays_test.dart b/tests/language_2/vm/allocation_sinking_arrays_test.dart
index ed5aa9b..c6dc0a5 100644
--- a/tests/language_2/vm/allocation_sinking_arrays_test.dart
+++ b/tests/language_2/vm/allocation_sinking_arrays_test.dart
@@ -66,9 +66,13 @@
   Vector2 v2 = new Vector2(1.0, 2.0);
   Vector2 v3 = v2 + Vector2(x, x);
   double sum = v3.x + v3.y;
+  Float32List v4 = Float32List(2);
+  v4[0] = 11.0;
+  v4[1] = sum + 3;
+  print(v4[0]);
   // Deoptimization is triggered here to materialize removed allocations.
   doDeopt + 2;
-  return "v1: [${v1[0]},${v1[1]}], v2: [${v2.x},${v2.y}], v3: [${v3.x},${v3.y}], sum: $sum";
+  return "v1: [${v1[0]},${v1[1]}], v2: [${v2.x},${v2.y}], v3: [${v3.x},${v3.y}], v4: [${v4[0]}, ${v4[1]}], sum: $sum";
 }
 
 main() {
@@ -80,6 +84,8 @@
   for (int i = 0; i < 130; ++i) {
     final num doDeopt = (i < 120 ? 1 : 2.0);
     final result = foo(3.0, doDeopt);
-    Expect.equals("v1: [1,hi], v2: [1.0,2.0], v3: [4.0,5.0], sum: 9.0", result);
+    Expect.equals(
+        "v1: [1,hi], v2: [1.0,2.0], v3: [4.0,5.0], v4: [11.0, 12.0], sum: 9.0",
+        result);
   }
 }
diff --git a/tests/language_2/vm/checked_smi_comparison_test.dart b/tests/language_2/vm/checked_smi_comparison_test.dart
new file mode 100644
index 0000000..d22cb01
--- /dev/null
+++ b/tests/language_2/vm/checked_smi_comparison_test.dart
@@ -0,0 +1,86 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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=
+// VMOptions=--use_slow_path
+
+import "package:expect/expect.dart";
+
+@pragma("vm:never-inline")
+dynamic hiddenSmi() {
+  try {
+    throw 42;
+  } catch (e) {
+    return e;
+  }
+  return 0;
+}
+
+@pragma("vm:never-inline")
+dynamic hiddenMint() {
+  try {
+    throw 0x8000000000000000;
+  } catch (e) {
+    return e;
+  }
+  return 0;
+}
+
+@pragma("vm:never-inline")
+dynamic hiddenDouble() {
+  try {
+    throw 3.0;
+  } catch (e) {
+    return e;
+  }
+  return 0;
+}
+
+@pragma("vm:never-inline")
+dynamic hiddenCustom() {
+  try {
+    throw new Custom();
+  } catch (e) {
+    return e;
+  }
+  return 0;
+}
+
+class Custom {
+  operator <(other) => "lt";
+  operator >(other) => "gt";
+  operator <=(other) => "le";
+  operator >=(other) => "ge";
+  operator ==(other) => false;
+}
+
+main() {
+  Expect.equals(false, hiddenSmi() < 2);
+  Expect.equals(true, hiddenSmi() > 2);
+  Expect.equals(false, hiddenSmi() <= 2);
+  Expect.equals(true, hiddenSmi() >= 2);
+  Expect.equals(false, hiddenSmi() == 2);
+  Expect.equals(true, hiddenSmi() != 2);
+
+  Expect.equals(true, hiddenMint() < 2);
+  Expect.equals(false, hiddenMint() > 2);
+  Expect.equals(true, hiddenMint() <= 2);
+  Expect.equals(false, hiddenMint() >= 2);
+  Expect.equals(false, hiddenMint() == 2);
+  Expect.equals(true, hiddenMint() != 2);
+
+  Expect.equals(false, hiddenDouble() < 2);
+  Expect.equals(true, hiddenDouble() > 2);
+  Expect.equals(false, hiddenDouble() <= 2);
+  Expect.equals(true, hiddenDouble() >= 2);
+  Expect.equals(false, hiddenDouble() == 2);
+  Expect.equals(true, hiddenDouble() != 2);
+
+  Expect.equals("lt", hiddenCustom() < 2);
+  Expect.equals("gt", hiddenCustom() > 2);
+  Expect.equals("le", hiddenCustom() <= 2);
+  Expect.equals("ge", hiddenCustom() >= 2);
+  Expect.equals(false, hiddenCustom() == 2);
+  Expect.equals(true, hiddenCustom() != 2);
+}
diff --git a/tests/language_2/vm/checked_smi_op_test.dart b/tests/language_2/vm/checked_smi_op_test.dart
new file mode 100644
index 0000000..f1ae4a6
--- /dev/null
+++ b/tests/language_2/vm/checked_smi_op_test.dart
@@ -0,0 +1,113 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=triple-shift
+// VMOptions=
+// VMOptions=--use_slow_path
+
+import "package:expect/expect.dart";
+
+@pragma("vm:never-inline")
+dynamic hiddenSmi() {
+  try {
+    throw 42;
+  } catch (e) {
+    return e;
+  }
+  return 0;
+}
+
+@pragma("vm:never-inline")
+dynamic hiddenMint() {
+  try {
+    throw 0x8000000000000000;
+  } catch (e) {
+    return e;
+  }
+  return 0;
+}
+
+@pragma("vm:never-inline")
+dynamic hiddenDouble() {
+  try {
+    throw 3.0;
+  } catch (e) {
+    return e;
+  }
+  return 0;
+}
+
+@pragma("vm:never-inline")
+dynamic hiddenCustom() {
+  try {
+    throw new Custom();
+  } catch (e) {
+    return e;
+  }
+  return 0;
+}
+
+class Custom {
+  operator +(other) => "add";
+  operator -(other) => "sub";
+  operator *(other) => "mul";
+  operator ~/(other) => "div";
+  operator %(other) => "mod";
+  operator &(other) => "and";
+  operator |(other) => "or";
+  operator ^(other) => "xor";
+  operator <<(other) => "sll";
+  operator >>(other) => "sra";
+  operator >>>(other) => "srl";
+}
+
+main() {
+  Expect.equals(44, hiddenSmi() + 2);
+  Expect.equals(40, hiddenSmi() - 2);
+  Expect.equals(84, hiddenSmi() * 2);
+  Expect.equals(21, hiddenSmi() ~/ 2);
+  Expect.equals(0, hiddenSmi() % 2);
+  Expect.equals(2, hiddenSmi() & 2);
+  Expect.equals(42, hiddenSmi() | 2);
+  Expect.equals(40, hiddenSmi() ^ 2);
+  Expect.equals(168, hiddenSmi() << 2);
+  Expect.equals(10, hiddenSmi() >> 2);
+  Expect.equals(10, hiddenSmi() >>> 2);
+
+  Expect.equals(-9223372036854775806, hiddenMint() + 2);
+  Expect.equals(9223372036854775806, hiddenMint() - 2);
+  Expect.equals(0, hiddenMint() * 2);
+  Expect.equals(-4611686018427387904, hiddenMint() ~/ 2);
+  Expect.equals(0, hiddenMint() % 2);
+  Expect.equals(0, hiddenMint() & 2);
+  Expect.equals(-9223372036854775806, hiddenMint() | 2);
+  Expect.equals(-9223372036854775806, hiddenMint() ^ 2);
+  Expect.equals(0, hiddenMint() << 2);
+  Expect.equals(-2305843009213693952, hiddenMint() >> 2);
+  Expect.equals(2305843009213693952, hiddenMint() >>> 2);
+
+  Expect.equals(5.0, hiddenDouble() + 2);
+  Expect.equals(1.0, hiddenDouble() - 2);
+  Expect.equals(6.0, hiddenDouble() * 2);
+  Expect.equals(1, hiddenDouble() ~/ 2);
+  Expect.equals(1.0, hiddenDouble() % 2);
+  Expect.throws(() => hiddenDouble() & 2, (e) => e is NoSuchMethodError);
+  Expect.throws(() => hiddenDouble() | 2, (e) => e is NoSuchMethodError);
+  Expect.throws(() => hiddenDouble() ^ 2, (e) => e is NoSuchMethodError);
+  Expect.throws(() => hiddenDouble() << 2, (e) => e is NoSuchMethodError);
+  Expect.throws(() => hiddenDouble() >> 2, (e) => e is NoSuchMethodError);
+  Expect.throws(() => hiddenDouble() >>> 2, (e) => e is NoSuchMethodError);
+
+  Expect.equals("add", hiddenCustom() + 2);
+  Expect.equals("sub", hiddenCustom() - 2);
+  Expect.equals("mul", hiddenCustom() * 2);
+  Expect.equals("div", hiddenCustom() ~/ 2);
+  Expect.equals("mod", hiddenCustom() % 2);
+  Expect.equals("and", hiddenCustom() & 2);
+  Expect.equals("or", hiddenCustom() | 2);
+  Expect.equals("xor", hiddenCustom() ^ 2);
+  Expect.equals("sll", hiddenCustom() << 2);
+  Expect.equals("sra", hiddenCustom() >> 2);
+  Expect.equals("srl", hiddenCustom() >>> 2);
+}
diff --git a/tests/language_2/vm/div_mod_test.dart b/tests/language_2/vm/div_mod_test.dart
index 92fab4f..ff9a88c 100755
--- a/tests/language_2/vm/div_mod_test.dart
+++ b/tests/language_2/vm/div_mod_test.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 // VMOptions=--deterministic
+// VMOptions=--deterministic --use_slow_path
 
 // Unit tests on DIV and MOV operations by various constants.
 
diff --git a/tests/language_2/vm/modtruncdiv_int_test.dart b/tests/language_2/vm/modtruncdiv_int_test.dart
index b838b15..018995e 100644
--- a/tests/language_2/vm/modtruncdiv_int_test.dart
+++ b/tests/language_2/vm/modtruncdiv_int_test.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 // VMOptions=--no_background_compilation --optimization_counter_threshold=10
+// VMOptions=--no_background_compilation --optimization_counter_threshold=10 --use_slow_path
 
 import "package:expect/expect.dart";
 
diff --git a/tests/language_2/vm/mult_int_test.dart b/tests/language_2/vm/mult_int_test.dart
index b13cbd5..16df391 100644
--- a/tests/language_2/vm/mult_int_test.dart
+++ b/tests/language_2/vm/mult_int_test.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 // VMOptions=--no_background_compilation --optimization_counter_threshold=10
+// VMOptions=--no_background_compilation --optimization_counter_threshold=10 --use_slow_path
 
 import "package:expect/expect.dart";
 
diff --git a/tests/language_2/vm/negate_int_test.dart b/tests/language_2/vm/negate_int_test.dart
index 8703aef..253756e 100644
--- a/tests/language_2/vm/negate_int_test.dart
+++ b/tests/language_2/vm/negate_int_test.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 // VMOptions=--no_background_compilation --optimization_counter_threshold=10
+// VMOptions=--no_background_compilation --optimization_counter_threshold=10 --use_slow_path
 
 import "package:expect/expect.dart";
 
diff --git a/tests/language_2/vm/no_such_args_error_message_vm_test.dart b/tests/language_2/vm/no_such_args_error_message_vm_test.dart
index d3ca510..3429907 100644
--- a/tests/language_2/vm/no_such_args_error_message_vm_test.dart
+++ b/tests/language_2/vm/no_such_args_error_message_vm_test.dart
@@ -15,10 +15,11 @@
   try {
     call_with_bar(() {});
   } catch (e) {
-    final expectedStrings = [
-      'Tried calling: testClosureMessage.<anonymous closure>("bar")',
-    ];
-    Expect.stringContainsInOrder(e.toString(), expectedStrings);
+    // The latter may happen if in --dwarf-stack-traces mode.
+    final possibleNames = ['testClosureMessage', '<optimized out>'];
+    Expect.containsOneOf(
+        possibleNames.map((s) => s + '.<anonymous closure>("bar")'),
+        e.toString());
   }
 }
 
diff --git a/tests/language_2/vm/regress_45524_test.dart b/tests/language_2/vm/regress_45524_test.dart
new file mode 100644
index 0000000..3f33adb
--- /dev/null
+++ b/tests/language_2/vm/regress_45524_test.dart
@@ -0,0 +1,31 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+// Reduced from:
+// The Dart Project Fuzz Tester (1.89).
+// Program generated as:
+//   dart dartfuzz.dart --seed 3959760722 --no-fp --no-ffi --flat
+// @dart=2.7
+
+bool var17 = bool.fromEnvironment('2y');
+
+class X0 {
+  num fld0_2 = 9223372036854775807;
+}
+
+extension XE0 on X0 {
+  bool foo0_Extension0() {
+    if (-12 >= -(((var17 ? -92 : fld0_2)))) {
+      return true;
+    } else {
+      return false;
+    }
+  }
+}
+
+main() {
+  Expect.equals(true, X0().foo0_Extension0());
+}
diff --git a/tests/language_2/vm/regress_45525_test.dart b/tests/language_2/vm/regress_45525_test.dart
new file mode 100644
index 0000000..2becc03
--- /dev/null
+++ b/tests/language_2/vm/regress_45525_test.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// VMOptions=--optimization-counter-threshold=10  --no-background-compilation
+
+import "package:expect/expect.dart";
+
+dynamic a() {
+  return 23;
+}
+
+dynamic b() {
+  return 26;
+}
+
+@pragma("vm:never-inline")
+dynamic foo() {
+  // BinarySmiOp(<<) marked truncating
+  return (a() << b()) & 0xFFFFFFF;
+}
+
+main() {
+  for (var i = 0; i < 20; i++) {
+    Expect.equals(201326592, foo());
+  }
+}
diff --git a/tests/language_2/vm/shift_special_cases_test.dart b/tests/language_2/vm/shift_special_cases_test.dart
index 604a0a3..f854461 100644
--- a/tests/language_2/vm/shift_special_cases_test.dart
+++ b/tests/language_2/vm/shift_special_cases_test.dart
@@ -1,7 +1,9 @@
 // Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
+
 // VMOptions=--optimization-counter-threshold=10 --no-background-compilation
+// VMOptions=--optimization-counter-threshold=10 --no-background-compilation --use_slow_path
 
 // Test for special cases of << and >> integer operations with int64.
 
diff --git a/tests/lib/js/js_util/promise_reject_null_test.dart b/tests/lib/js/js_util/promise_reject_null_test.dart
new file mode 100644
index 0000000..70da7f9
--- /dev/null
+++ b/tests/lib/js/js_util/promise_reject_null_test.dart
@@ -0,0 +1,64 @@
+@JS()
+library promise_reject_null_test;
+
+import 'package:js/js.dart';
+import 'package:js/js_util.dart' show promiseToFuture, NullRejectionException;
+
+import 'package:expect/minitest.dart';
+
+@JS()
+external void eval(String s);
+
+@JS('Promise.reject')
+external dynamic getRejectedPromise(v);
+
+@JS()
+external void reject(v);
+@JS()
+external dynamic getNewPromise();
+
+void main() async {
+  eval('''
+    self.getNewPromise = function () {
+      return new Promise(function (_, reject) {
+        self.reject = reject;
+      });
+    };
+  ''');
+
+  // Rejected promise with a `null` value should trigger a
+  // `NullRejectionException`.
+  await promiseToFuture(getRejectedPromise(null)).then((_) {
+    fail("Expected promise to reject and not fulfill.");
+  }).catchError((e) {
+    expect(e is NullRejectionException, true);
+    expect(e.isUndefined, false);
+  });
+
+  // Similar to the above, except we reject using JS interop.
+  var future = promiseToFuture(getNewPromise()).then((_) {
+    fail("Expected promise to reject and not fulfill.");
+  }).catchError((e) {
+    expect(e is NullRejectionException, true);
+    expect(e.isUndefined, false);
+  });
+
+  reject(null);
+
+  await future;
+
+  // It's also possible to reject with `undefined`. Make sure that the exception
+  // correctly flags that case.
+  future = promiseToFuture(getNewPromise()).then((_) {
+    fail("Expected promise to reject and not fulfill.");
+  }).catchError((e) {
+    expect(e is NullRejectionException, true);
+    expect(e.isUndefined, true);
+  });
+
+  eval('''
+    self.reject(undefined);
+  ''');
+
+  await future;
+}
diff --git a/tests/lib/lib.status b/tests/lib/lib.status
index 9069e5b..1c4e7ce 100644
--- a/tests/lib/lib.status
+++ b/tests/lib/lib.status
@@ -39,6 +39,7 @@
 js/instanceof_test: SkipByDesign # Issue 42085. CSP policy disallows injected JS code
 js/js_util/async_test: SkipByDesign # Issue 42085. CSP policy disallows injected JS code
 js/js_util/jsify_test: SkipByDesign # Issue 42085. CSP policy disallows injected JS code
+js/js_util/promise_reject_null_test: SkipByDesign # Issue 42085. CSP policy disallows injected JS code
 js/js_util/properties_test: SkipByDesign # Issue 42085. CSP policy disallows injected JS code
 js/method_call_on_object_test: SkipByDesign # Issue 42085.
 js/mock_test/*: SkipByDesign # Issue 42085.
diff --git a/tests/lib_2/js/js_util/promise_reject_null_test.dart b/tests/lib_2/js/js_util/promise_reject_null_test.dart
new file mode 100644
index 0000000..70da7f9
--- /dev/null
+++ b/tests/lib_2/js/js_util/promise_reject_null_test.dart
@@ -0,0 +1,64 @@
+@JS()
+library promise_reject_null_test;
+
+import 'package:js/js.dart';
+import 'package:js/js_util.dart' show promiseToFuture, NullRejectionException;
+
+import 'package:expect/minitest.dart';
+
+@JS()
+external void eval(String s);
+
+@JS('Promise.reject')
+external dynamic getRejectedPromise(v);
+
+@JS()
+external void reject(v);
+@JS()
+external dynamic getNewPromise();
+
+void main() async {
+  eval('''
+    self.getNewPromise = function () {
+      return new Promise(function (_, reject) {
+        self.reject = reject;
+      });
+    };
+  ''');
+
+  // Rejected promise with a `null` value should trigger a
+  // `NullRejectionException`.
+  await promiseToFuture(getRejectedPromise(null)).then((_) {
+    fail("Expected promise to reject and not fulfill.");
+  }).catchError((e) {
+    expect(e is NullRejectionException, true);
+    expect(e.isUndefined, false);
+  });
+
+  // Similar to the above, except we reject using JS interop.
+  var future = promiseToFuture(getNewPromise()).then((_) {
+    fail("Expected promise to reject and not fulfill.");
+  }).catchError((e) {
+    expect(e is NullRejectionException, true);
+    expect(e.isUndefined, false);
+  });
+
+  reject(null);
+
+  await future;
+
+  // It's also possible to reject with `undefined`. Make sure that the exception
+  // correctly flags that case.
+  future = promiseToFuture(getNewPromise()).then((_) {
+    fail("Expected promise to reject and not fulfill.");
+  }).catchError((e) {
+    expect(e is NullRejectionException, true);
+    expect(e.isUndefined, true);
+  });
+
+  eval('''
+    self.reject(undefined);
+  ''');
+
+  await future;
+}
diff --git a/tests/lib_2/lib_2.status b/tests/lib_2/lib_2.status
index 5a1d63b..a6d093b 100644
--- a/tests/lib_2/lib_2.status
+++ b/tests/lib_2/lib_2.status
@@ -39,6 +39,7 @@
 js/instanceof_test: SkipByDesign # Issue 42085. CSP policy disallows injected JS code
 js/js_util/async_test: SkipByDesign # Issue 42085. CSP policy disallows injected JS code
 js/js_util/jsify_test: SkipByDesign # Issue 42085. CSP policy disallows injected JS code
+js/js_util/promise_reject_null_test: SkipByDesign # Issue 42085. CSP policy disallows injected JS code
 js/js_util/properties_test: SkipByDesign # Issue 42085. CSP policy disallows injected JS code
 js/method_call_on_object_test: SkipByDesign # Issue 42085.
 js/mock_test/*: SkipByDesign # Issue 42085.
diff --git a/tests/modular/private_class_exposed_by_typedef/main.dart b/tests/modular/private_class_exposed_by_typedef/main.dart
new file mode 100644
index 0000000..70c26d1
--- /dev/null
+++ b/tests/modular/private_class_exposed_by_typedef/main.dart
@@ -0,0 +1,61 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+import "private_name_library.dart";
+
+// These tests are adapted from the set located in
+// language/nonfunction_type_aliases/private_names/ to highlight a specific
+// DDC issue with public fields in private classes.
+
+void main() {
+  test1();
+  test2();
+}
+
+/// Extend a private class via a public typedef without overriding any methods.
+class Derived extends PublicClass {
+  Derived() : super();
+}
+
+/// Extend a private class via a public typedef overriding methods and
+/// properties.  The final field `x` is overriden with a getter which returns
+/// different values every time it is called.
+class AlsoDerived extends AlsoPublicClass {
+  int backingStore = publicNameSentinel;
+  int get x => ++backingStore;
+  int get y => super.x;
+  AlsoDerived() : super.named(privateNameSentinel);
+}
+
+/// Test that inherited properties work correctly
+void test1() {
+  var p = Derived();
+  // Reading the virtual field should give the private value
+  Expect.equals(privateNameSentinel, p.x);
+  // Reading the virtual field from the private library should give the private
+  // value
+  Expect.equals(privateNameSentinel, readInstanceField(p));
+}
+
+/// Test that overridden properties work correctly.
+void test2() {
+  var p = AlsoDerived();
+  // Reading the original virtual field should give the private value.
+  Expect.equals(privateNameSentinel, p.y);
+  // Reading the overriding getter from the private library should give the
+  // public value and increment it each time it is called.
+  Expect.equals(publicNameSentinel, p.backingStore);
+  Expect.equals(publicNameSentinel + 1, readInstanceField2(p));
+  Expect.equals(publicNameSentinel + 1, p.backingStore);
+  // Reading the overriding getter from the original library should give the
+  // public value and increment it each time it is called.
+  Expect.equals(publicNameSentinel + 2, p.x);
+  Expect.equals(publicNameSentinel + 2, p.backingStore);
+  Expect.equals(privateNameSentinel, p.y);
+  Expect.equals(publicNameSentinel + 2, p.backingStore);
+  Expect.equals(publicNameSentinel + 3, readInstanceField2(p));
+  Expect.equals(publicNameSentinel + 4, p.x);
+}
diff --git a/tests/modular/private_class_exposed_by_typedef/modules.yaml b/tests/modular/private_class_exposed_by_typedef/modules.yaml
new file mode 100644
index 0000000..530016e
--- /dev/null
+++ b/tests/modular/private_class_exposed_by_typedef/modules.yaml
@@ -0,0 +1,8 @@
+# Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+#
+dependencies:
+  main: [expect, private_name_library]
+flags:
+  - nonfunction-type-aliases
diff --git a/tests/modular/private_class_exposed_by_typedef/private_name_library.dart b/tests/modular/private_class_exposed_by_typedef/private_name_library.dart
new file mode 100644
index 0000000..74559cc
--- /dev/null
+++ b/tests/modular/private_class_exposed_by_typedef/private_name_library.dart
@@ -0,0 +1,39 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Shared code for tests that private names exported publicly via a typedef work
+// as expected.
+library private;
+
+/// Sentinel values for checking that the correct methods are called.
+const int privateNameSentinel = -1;
+const int publicNameSentinel = privateNameSentinel + 1;
+
+/// A private class that will be exported via a public typedef.
+class _PrivateClass {
+  int x;
+  _PrivateClass(): x = privateNameSentinel;
+  _PrivateClass.named(this.x);
+}
+
+class _PrivateClass2 {
+  int x;
+  _PrivateClass2(): x = privateNameSentinel;
+  _PrivateClass2.named(this.x);
+}
+
+/// Export the private class publicly.
+typedef PublicClass = _PrivateClass;
+
+/// Export the private class publicly via an indirection through another private
+/// typedef.
+typedef _PrivateTypeDef = _PrivateClass2;
+typedef AlsoPublicClass = _PrivateTypeDef;
+
+/// Helper methods to do virtual calls on instances of _PrivateClass in this
+/// library context.
+int readInstanceField(_PrivateClass other) => other.x;
+
+/// Helper methods to do virtual calls on instances of _PrivateClass in this
+/// library context.
+int readInstanceField2(_PrivateClass2 other) => other.x;
diff --git a/tests/standalone/io/address_lookup_test.dart b/tests/standalone/io/address_lookup_test.dart
new file mode 100644
index 0000000..74b76c5
--- /dev/null
+++ b/tests/standalone/io/address_lookup_test.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+// Verifies that one can provide timeout handler for InternetAddress.lookup,
+// which was reported broken https://github.com/dart-lang/sdk/issues/45542.
+
+import "dart:io";
+
+import "package:async_helper/async_helper.dart";
+import "package:expect/expect.dart";
+
+void main() async {
+  asyncStart();
+  final result = <InternetAddress>[];
+  try {
+    result.addAll(await InternetAddress.lookup("some.bad.host.name.7654321")
+        .timeout(const Duration(milliseconds: 1), onTimeout: () => []));
+  } catch (e) {
+    print('managed to fail with $e lookup before timeout');
+  }
+  Expect.isTrue(result.isEmpty);
+  asyncEnd();
+}
diff --git a/tests/standalone/io/http_100_continue.dart b/tests/standalone/io/http_100_continue.dart
deleted file mode 100644
index f0e18a5..0000000
--- a/tests/standalone/io/http_100_continue.dart
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import "dart:async";
-import 'dart:convert';
-import "dart:io";
-
-import "package:expect/expect.dart";
-
-void test(responseBytes, bodyLength) async {
-  fullRequest(bytes) {
-    var len = bytes.length;
-    return len > 4 &&
-        bytes[len - 4] == 13 &&
-        bytes[len - 3] == 10 &&
-        bytes[len - 2] == 13 &&
-        bytes[len - 1] == 10;
-  }
-
-  handleSocket(socket) async {
-    var bytes = [];
-    await for (var data in socket) {
-      bytes.addAll(data);
-      if (fullRequest(bytes)) {
-        socket.add(responseBytes);
-        socket.close();
-      }
-    }
-  }
-
-  var server = await ServerSocket.bind('127.0.0.1', 0);
-  server.listen(handleSocket);
-
-  var client = new HttpClient();
-  var request =
-      await client.getUrl(Uri.parse('http://127.0.0.1:${server.port}/'));
-  var response = await request.close();
-  Expect.equals(response.statusCode, 200);
-  Expect.equals(bodyLength,
-      (await response.fold<List<int>>(<int>[], (p, e) => p..addAll(e))).length);
-  server.close();
-}
-
-main() {
-  var r1 = '''
-HTTP/1.1 100 Continue\r
-\r
-HTTP/1.1 200 OK\r
-\r
-''';
-
-  var r2 = '''
-HTTP/1.1 100 Continue\r
-My-Header-1: hello\r
-My-Header-2: world\r
-\r
-HTTP/1.1 200 OK\r
-\r
-''';
-
-  var r3 = '''
-HTTP/1.1 100 Continue\r
-\r
-HTTP/1.1 200 OK\r
-Content-Length: 2\r
-\r
-AB''';
-
-  test(ascii.encode(r1), 0);
-  test(ascii.encode(r2), 0);
-  test(ascii.encode(r3), 2);
-}
diff --git a/tests/standalone/io/http_100_continue_test.dart b/tests/standalone/io/http_100_continue_test.dart
new file mode 100644
index 0000000..61af598
--- /dev/null
+++ b/tests/standalone/io/http_100_continue_test.dart
@@ -0,0 +1,77 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:async";
+import 'dart:convert';
+import "dart:io";
+
+import "package:expect/expect.dart";
+
+void test(responseBytes, bodyLength) async {
+  fullRequest(bytes) {
+    var len = bytes.length;
+    return len > 4 &&
+        bytes[len - 4] == 13 &&
+        bytes[len - 3] == 10 &&
+        bytes[len - 2] == 13 &&
+        bytes[len - 1] == 10;
+  }
+
+  handleSocket(socket) async {
+    var bytes = [];
+    await for (var data in socket) {
+      bytes.addAll(data);
+      if (fullRequest(bytes)) {
+        socket.add(responseBytes);
+        socket.close();
+      }
+    }
+  }
+
+  var server = await ServerSocket.bind('127.0.0.1', 0);
+  server.listen(handleSocket);
+
+  var client = new HttpClient();
+  var request =
+      await client.getUrl(Uri.parse('http://127.0.0.1:${server.port}/'));
+  var response = await request.close();
+  Expect.equals(response.statusCode, 200);
+  Expect.equals(bodyLength,
+      (await response.fold<List<int>>(<int>[], (p, e) => p..addAll(e))).length);
+  server.close();
+}
+
+main() {
+  var r1 = '''
+HTTP/1.1 100 Continue\r
+\r
+HTTP/1.1 200 OK\r
+\r
+''';
+
+  var r2 = '''
+HTTP/1.1 100 Continue\r
+My-Header-1: hello\r
+My-Header-2: world\r
+\r
+HTTP/1.1 200 OK\r
+\r
+''';
+
+  var r3 = '''
+HTTP/1.1 100 Continue\r
+\r
+HTTP/1.1 200 OK\r
+Content-Length: 2\r
+\r
+AB''';
+
+  test(ascii.encode(r1), 0);
+  test(ascii.encode(r2), 0);
+  test(ascii.encode(r3), 2);
+
+  test(ascii.encode(r1.replaceAll('\r\n', '\n')), 0);
+  test(ascii.encode(r2.replaceAll('\r\n', '\n')), 0);
+  test(ascii.encode(r3.replaceAll('\r\n', '\n')), 2);
+}
diff --git a/tests/standalone/io/http_client_parser_crlfs_tolerant_test.dart b/tests/standalone/io/http_client_parser_crlfs_tolerant_test.dart
new file mode 100644
index 0000000..1d02c39
--- /dev/null
+++ b/tests/standalone/io/http_client_parser_crlfs_tolerant_test.dart
@@ -0,0 +1,76 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+// Tests that CR*LF sequence works as well as CRLF in http client parser.
+
+import "package:expect/expect.dart";
+import "package:async_helper/async_helper.dart";
+
+import "dart:async";
+import "dart:convert";
+import "dart:io";
+import "dart:isolate";
+
+Future testHttpClient(header) {
+  final completer = Completer();
+  ServerSocket.bind("127.0.0.1", 0).then((server) async {
+    server.listen((socket) async {
+      int port = server.port;
+      socket.write(header);
+      await socket.flush();
+      completer.future.catchError((_) {}).whenComplete(() {
+        socket.destroy();
+      });
+    });
+
+    await runZonedGuarded(() {
+      var client = new HttpClient();
+      client.userAgent = null;
+      client
+          .get("127.0.0.1", server.port, "/")
+          .then((request) => request.close())
+          .then((response) {
+        response.transform(utf8.decoder).listen((contents) {
+          completer.complete();
+        }, onDone: () {
+          client.close(force: true);
+          server.close();
+        });
+      });
+    }, (e, st) {
+      server.close();
+      completer.completeError(e, st);
+    });
+  });
+  return completer.future;
+}
+
+void main() async {
+  const good = <String>[
+    "HTTP/1.1 200 OK\n\nTest!",
+    "HTTP/1.1 200 OK\r\n\nTest!",
+    "HTTP/1.1 200 OK\n\r\nTest!",
+    "HTTP/1.1 200 OK\r\n\r\nTest!",
+  ];
+  asyncStart();
+  for (final header in good) {
+    await testHttpClient(header);
+  }
+  const bad = <String>[
+    "HTTP/1.1 200 OK\n\rTest!",
+    "HTTP/1.1 200 OK\r\r\n\nTest!",
+    "HTTP/1.1 200 OK\r\rTest!",
+    "HTTP/1.1 200 OK\rTest!",
+  ];
+  for (final header in bad) {
+    var caught;
+    try {
+      await testHttpClient(header);
+    } catch (e, st) {
+      caught = e;
+    }
+    Expect.isTrue(caught is HttpException);
+  }
+  asyncEnd();
+}
diff --git a/tests/standalone/io/http_cookie_date_test.dart b/tests/standalone/io/http_cookie_date_test.dart
index 2d6f70f..f750fdf 100644
--- a/tests/standalone/io/http_cookie_date_test.dart
+++ b/tests/standalone/io/http_cookie_date_test.dart
@@ -9,6 +9,7 @@
 import "dart:convert";
 import "dart:developer";
 import "dart:io";
+import "dart:isolate";
 import "dart:math";
 import "dart:typed_data";
 
diff --git a/tests/standalone/io/http_parser_test.dart b/tests/standalone/io/http_parser_test.dart
index 022a9b9..c689a0c 100644
--- a/tests/standalone/io/http_parser_test.dart
+++ b/tests/standalone/io/http_parser_test.dart
@@ -26,14 +26,25 @@
 part "../../../sdk/lib/_http/http_session.dart";
 
 class HttpParserTest {
+  final String Function(String) transform;
+  HttpParserTest(this.transform);
+
   static void runAllTests() {
-    testParseRequest();
-    testParseResponse();
-    testParseInvalidRequest();
-    testParseInvalidResponse();
+    final testCRLF = HttpParserTest((String s) => s);
+    testCRLF.testParseRequest();
+    testCRLF.testParseResponse();
+    testCRLF.testParseInvalidRequest();
+    testCRLF.testParseInvalidResponse();
+
+    // Ensure http parser is CR?LF tolerant.
+    final testLF = HttpParserTest((String s) => s.replaceAll('\r', ''));
+    testLF.testParseRequest();
+    testLF.testParseResponse();
+    testLF.testParseInvalidRequest();
+    testLF.testParseInvalidResponse();
   }
 
-  static void _testParseRequest(
+  void _testParseRequest(
       String request, String expectedMethod, String expectedUri,
       {int expectedTransferLength: 0,
       int expectedBytesReceived: 0,
@@ -118,13 +129,14 @@
 
     // Test parsing the request three times delivering the data in
     // different chunks.
-    List<int> requestData = new Uint8List.fromList(request.codeUnits);
+    List<int> requestData =
+        new Uint8List.fromList(transform(request).codeUnits);
     testWrite(requestData);
     testWrite(requestData, 10);
     testWrite(requestData, 1);
   }
 
-  static void _testParseRequestLean(
+  void _testParseRequestLean(
       String request, String expectedMethod, String expectedUri,
       {int expectedTransferLength: 0,
       int expectedBytesReceived: 0,
@@ -155,7 +167,7 @@
         expectedVersion: expectedVersion);
   }
 
-  static void _testParseInvalidRequest(String request) {
+  void _testParseInvalidRequest(String request) {
     _HttpParser httpParser;
     bool errorCalled = false;
     late StreamController<Uint8List> controller;
@@ -192,13 +204,14 @@
 
     // Test parsing the request three times delivering the data in
     // different chunks.
-    List<int> requestData = new Uint8List.fromList(request.codeUnits);
+    List<int> requestData =
+        new Uint8List.fromList(transform(request).codeUnits);
     testWrite(requestData);
     testWrite(requestData, 10);
     testWrite(requestData, 1);
   }
 
-  static void _testParseResponse(
+  void _testParseResponse(
       String response, int expectedStatusCode, String expectedReasonPhrase,
       {int expectedTransferLength: 0,
       int expectedBytesReceived: 0,
@@ -286,13 +299,14 @@
 
     // Test parsing the request three times delivering the data in
     // different chunks.
-    List<int> responseData = new Uint8List.fromList(response.codeUnits);
+    List<int> responseData =
+        new Uint8List.fromList(transform(response).codeUnits);
     testWrite(responseData);
     testWrite(responseData, 10);
     testWrite(responseData, 1);
   }
 
-  static void _testParseInvalidResponse(String response, [bool close = false]) {
+  void _testParseInvalidResponse(String response, [bool close = false]) {
     void testWrite(List<int> requestData, [int chunkSize = -1]) {
       _HttpParser httpParser = new _HttpParser.responseParser();
       StreamController<Uint8List> controller = new StreamController(sync: true);
@@ -329,13 +343,14 @@
 
     // Test parsing the request three times delivering the data in
     // different chunks.
-    List<int> responseData = new Uint8List.fromList(response.codeUnits);
+    List<int> responseData =
+        new Uint8List.fromList(transform(response).codeUnits);
     testWrite(responseData);
     testWrite(responseData, 10);
     testWrite(responseData, 1);
   }
 
-  static void testParseRequest() {
+  void testParseRequest() {
     String request;
     Map<String, String> headers;
     var methods = [
@@ -552,7 +567,7 @@
         expectedHeaders: headers, upgrade: true, unparsedLength: 7);
   }
 
-  static void testParseResponse() {
+  void testParseResponse() {
     String response;
     Map<String, String> headers;
     response = "HTTP/1.1 100 Continue\r\nContent-Length: 0\r\n\r\n";
@@ -714,7 +729,7 @@
         expectedHeaders: headers, upgrade: true, unparsedLength: 4);
   }
 
-  static void testParseInvalidRequest() {
+  void testParseInvalidRequest() {
     String request;
     request = "GET /\r\n\r\n";
     _testParseInvalidRequest(request);
@@ -770,7 +785,7 @@
     _testParseInvalidRequest(request);
   }
 
-  static void testParseInvalidResponse() {
+  void testParseInvalidResponse() {
     String response;
 
     response = "HTTP/1.1\r\nContent-Length: 0\r\n\r\n";
diff --git a/tests/standalone_2/io/address_lookup_test.dart b/tests/standalone_2/io/address_lookup_test.dart
new file mode 100644
index 0000000..74b76c5
--- /dev/null
+++ b/tests/standalone_2/io/address_lookup_test.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+// Verifies that one can provide timeout handler for InternetAddress.lookup,
+// which was reported broken https://github.com/dart-lang/sdk/issues/45542.
+
+import "dart:io";
+
+import "package:async_helper/async_helper.dart";
+import "package:expect/expect.dart";
+
+void main() async {
+  asyncStart();
+  final result = <InternetAddress>[];
+  try {
+    result.addAll(await InternetAddress.lookup("some.bad.host.name.7654321")
+        .timeout(const Duration(milliseconds: 1), onTimeout: () => []));
+  } catch (e) {
+    print('managed to fail with $e lookup before timeout');
+  }
+  Expect.isTrue(result.isEmpty);
+  asyncEnd();
+}
diff --git a/tests/standalone_2/io/http_100_continue.dart b/tests/standalone_2/io/http_100_continue.dart
deleted file mode 100644
index b0e4116..0000000
--- a/tests/standalone_2/io/http_100_continue.dart
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import "dart:async";
-import 'dart:convert';
-import "dart:io";
-
-import "package:expect/expect.dart";
-
-void test(responseBytes, bodyLength) async {
-  fullRequest(bytes) {
-    var len = bytes.length;
-    return len > 4 &&
-        bytes[len - 4] == 13 &&
-        bytes[len - 3] == 10 &&
-        bytes[len - 2] == 13 &&
-        bytes[len - 1] == 10;
-  }
-
-  handleSocket(socket) async {
-    var bytes = [];
-    await for (var data in socket) {
-      bytes.addAll(data);
-      if (fullRequest(bytes)) {
-        socket.add(responseBytes);
-        socket.close();
-      }
-    }
-  }
-
-  var server = await ServerSocket.bind('127.0.0.1', 0);
-  server.listen(handleSocket);
-
-  var client = new HttpClient();
-  var request =
-      await client.getUrl(Uri.parse('http://127.0.0.1:${server.port}/'));
-  var response = await request.close();
-  Expect.equals(response.statusCode, 200);
-  Expect.equals(
-      bodyLength, (await response.fold([], (p, e) => p..addAll(e))).length);
-  server.close();
-}
-
-main() {
-  var r1 = '''
-HTTP/1.1 100 Continue\r
-\r
-HTTP/1.1 200 OK\r
-\r
-''';
-
-  var r2 = '''
-HTTP/1.1 100 Continue\r
-My-Header-1: hello\r
-My-Header-2: world\r
-\r
-HTTP/1.1 200 OK\r
-\r
-''';
-
-  var r3 = '''
-HTTP/1.1 100 Continue\r
-\r
-HTTP/1.1 200 OK\r
-Content-Length: 2\r
-\r
-AB''';
-
-  test(ascii.encode(r1), 0);
-  test(ascii.encode(r2), 0);
-  test(ascii.encode(r3), 2);
-}
diff --git a/tests/standalone_2/io/http_100_continue_test.dart b/tests/standalone_2/io/http_100_continue_test.dart
new file mode 100644
index 0000000..fb7abae
--- /dev/null
+++ b/tests/standalone_2/io/http_100_continue_test.dart
@@ -0,0 +1,77 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:async";
+import 'dart:convert';
+import "dart:io";
+
+import "package:expect/expect.dart";
+
+void test(responseBytes, bodyLength) async {
+  fullRequest(bytes) {
+    var len = bytes.length;
+    return len > 4 &&
+        bytes[len - 4] == 13 &&
+        bytes[len - 3] == 10 &&
+        bytes[len - 2] == 13 &&
+        bytes[len - 1] == 10;
+  }
+
+  handleSocket(socket) async {
+    var bytes = [];
+    await for (var data in socket) {
+      bytes.addAll(data);
+      if (fullRequest(bytes)) {
+        socket.add(responseBytes);
+        socket.close();
+      }
+    }
+  }
+
+  var server = await ServerSocket.bind('127.0.0.1', 0);
+  server.listen(handleSocket);
+
+  var client = new HttpClient();
+  var request =
+      await client.getUrl(Uri.parse('http://127.0.0.1:${server.port}/'));
+  var response = await request.close();
+  Expect.equals(response.statusCode, 200);
+  Expect.equals(
+      bodyLength, (await response.fold([], (p, e) => p..addAll(e))).length);
+  server.close();
+}
+
+main() {
+  var r1 = '''
+HTTP/1.1 100 Continue\r
+\r
+HTTP/1.1 200 OK\r
+\r
+''';
+
+  var r2 = '''
+HTTP/1.1 100 Continue\r
+My-Header-1: hello\r
+My-Header-2: world\r
+\r
+HTTP/1.1 200 OK\r
+\r
+''';
+
+  var r3 = '''
+HTTP/1.1 100 Continue\r
+\r
+HTTP/1.1 200 OK\r
+Content-Length: 2\r
+\r
+AB''';
+
+  test(ascii.encode(r1), 0);
+  test(ascii.encode(r2), 0);
+  test(ascii.encode(r3), 2);
+
+  test(ascii.encode(r1.replaceAll('\r\n', '\n')), 0);
+  test(ascii.encode(r2.replaceAll('\r\n', '\n')), 0);
+  test(ascii.encode(r3.replaceAll('\r\n', '\n')), 2);
+}
diff --git a/tests/standalone_2/io/http_client_parser_crlfs_tolerant_test.dart b/tests/standalone_2/io/http_client_parser_crlfs_tolerant_test.dart
new file mode 100644
index 0000000..1d02c39
--- /dev/null
+++ b/tests/standalone_2/io/http_client_parser_crlfs_tolerant_test.dart
@@ -0,0 +1,76 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+// Tests that CR*LF sequence works as well as CRLF in http client parser.
+
+import "package:expect/expect.dart";
+import "package:async_helper/async_helper.dart";
+
+import "dart:async";
+import "dart:convert";
+import "dart:io";
+import "dart:isolate";
+
+Future testHttpClient(header) {
+  final completer = Completer();
+  ServerSocket.bind("127.0.0.1", 0).then((server) async {
+    server.listen((socket) async {
+      int port = server.port;
+      socket.write(header);
+      await socket.flush();
+      completer.future.catchError((_) {}).whenComplete(() {
+        socket.destroy();
+      });
+    });
+
+    await runZonedGuarded(() {
+      var client = new HttpClient();
+      client.userAgent = null;
+      client
+          .get("127.0.0.1", server.port, "/")
+          .then((request) => request.close())
+          .then((response) {
+        response.transform(utf8.decoder).listen((contents) {
+          completer.complete();
+        }, onDone: () {
+          client.close(force: true);
+          server.close();
+        });
+      });
+    }, (e, st) {
+      server.close();
+      completer.completeError(e, st);
+    });
+  });
+  return completer.future;
+}
+
+void main() async {
+  const good = <String>[
+    "HTTP/1.1 200 OK\n\nTest!",
+    "HTTP/1.1 200 OK\r\n\nTest!",
+    "HTTP/1.1 200 OK\n\r\nTest!",
+    "HTTP/1.1 200 OK\r\n\r\nTest!",
+  ];
+  asyncStart();
+  for (final header in good) {
+    await testHttpClient(header);
+  }
+  const bad = <String>[
+    "HTTP/1.1 200 OK\n\rTest!",
+    "HTTP/1.1 200 OK\r\r\n\nTest!",
+    "HTTP/1.1 200 OK\r\rTest!",
+    "HTTP/1.1 200 OK\rTest!",
+  ];
+  for (final header in bad) {
+    var caught;
+    try {
+      await testHttpClient(header);
+    } catch (e, st) {
+      caught = e;
+    }
+    Expect.isTrue(caught is HttpException);
+  }
+  asyncEnd();
+}
diff --git a/tests/web/45046_test.dart b/tests/web/45046_test.dart
new file mode 100644
index 0000000..1e4f9b1
--- /dev/null
+++ b/tests/web/45046_test.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+
+class A {}
+
+class B extends A {}
+
+class Foo<T> {}
+
+T cast<T>(dynamic x) => x as T;
+
+void test(Foo<A> Function(dynamic) f) {
+  var foo = Foo<B>();
+  Expect.identical(foo, f(foo));
+}
+
+void main() {
+  test(cast);
+}
diff --git a/tests/web/deferred/shadowed_types/lib_shared.dart b/tests/web/deferred/shadowed_types/lib_shared.dart
new file mode 100644
index 0000000..ee8202f
--- /dev/null
+++ b/tests/web/deferred/shadowed_types/lib_shared.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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 has a type used in libb, but a class used in liba.
+class A {}
+
+// Class B has a class used in the main output unit, and a type used in libb.
+class B {}
+
+// Class C_Parent is extended is libb, and closed around in the main output
+// unit.
+class C_Parent {}
+
+// Classes D through F represent a simple heirarchy.
+// D's type is used in liba.
+// F is instantiated, but unused in libb.
+class D {}
+
+class E extends D {}
+
+class F {}
diff --git a/tests/web/deferred/shadowed_types/liba.dart b/tests/web/deferred/shadowed_types/liba.dart
new file mode 100644
index 0000000..7283385
--- /dev/null
+++ b/tests/web/deferred/shadowed_types/liba.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'lib_shared.dart';
+
+@pragma('dart2js:noInline')
+isA(foo) {
+  return foo is A;
+}
+
+@pragma('dart2js:noInline')
+isD(foo) {
+  return foo is D;
+}
diff --git a/tests/web/deferred/shadowed_types/libb.dart b/tests/web/deferred/shadowed_types/libb.dart
new file mode 100644
index 0000000..1a9e83c
--- /dev/null
+++ b/tests/web/deferred/shadowed_types/libb.dart
@@ -0,0 +1,33 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'lib_shared.dart';
+
+@pragma('dart2js:noInline')
+createA() {
+  return A();
+}
+
+@pragma('dart2js:noInline')
+isB(foo) {
+  return foo is B;
+}
+
+class C extends C_Parent {}
+
+@pragma('dart2js:noInline')
+createC() {
+  return C();
+}
+
+@pragma('dart2js:noInline')
+createE() {
+  return E();
+}
+
+@pragma('dart2js:noInline')
+isFWithUnused(foo) {
+  var unused = F();
+  return foo is F;
+}
diff --git a/tests/web/deferred/shadowed_types/shadowed_types_test.dart b/tests/web/deferred/shadowed_types/shadowed_types_test.dart
new file mode 100644
index 0000000..0bc3fa0
--- /dev/null
+++ b/tests/web/deferred/shadowed_types/shadowed_types_test.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+import 'liba.dart' deferred as liba;
+import 'libb.dart' deferred as libb;
+import 'lib_shared.dart';
+
+main() async {
+  var f = () => libb.C();
+  Expect.isTrue(f is C_Parent Function());
+  await liba.loadLibrary();
+  await libb.loadLibrary();
+
+  Expect.isTrue(liba.isA(libb.createA()));
+  print(libb.createA());
+  print(libb.createC());
+  Expect.isTrue(libb.isB(B()));
+  Expect.isTrue(liba.isD(libb.createE()));
+  Expect.isFalse(libb.isFWithUnused(null as dynamic));
+}
diff --git a/tests/web/regress/45413_test.dart b/tests/web/regress/45413_test.dart
new file mode 100644
index 0000000..b24c72d
--- /dev/null
+++ b/tests/web/regress/45413_test.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Regression test for dart2js stack overflow.
+
+import 'package:expect/expect.dart';
+
+void main() {
+  int x = 0;
+  do {
+    x++;
+  } while (x % 10 == 7 ? false : true);
+  Expect.equals(7, x);
+}
diff --git a/tests/web_2/45046_test.dart b/tests/web_2/45046_test.dart
new file mode 100644
index 0000000..7f5333e
--- /dev/null
+++ b/tests/web_2/45046_test.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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 'package:expect/expect.dart';
+
+class A {}
+
+class B extends A {}
+
+class Foo<T> {}
+
+T cast<T>(dynamic x) => x as T;
+
+void test(Foo<A> Function(dynamic) f) {
+  var foo = Foo<B>();
+  Expect.identical(foo, f(foo));
+}
+
+void main() {
+  test(cast);
+}
diff --git a/tests/web_2/regress/183227419_test.dart b/tests/web_2/regress/183227419_test.dart
new file mode 100644
index 0000000..2d94ec8
--- /dev/null
+++ b/tests/web_2/regress/183227419_test.dart
@@ -0,0 +1,56 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for 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
+
+// Regression test for variable allocator live range bug.
+//
+// Pre-fix, this program would crash because t2 was reused before it was dead.
+//
+//     algo$1: function(n) {
+//       var t1 = this.ax,
+//         t2 = t1 == null;
+//       if ((t2 ? null : t1.a) == null)
+//         return;
+//       t2 = n + 1;  // the old value of t2 is used below!
+//       (t2 ? null : t1.a).parameters.addAll$2(0, t2, t2);
+//     }
+//
+// Several things were necessary to tickle the bug:
+//
+//  [A] The repeated test that gets shared from the two null-aware `ax?.a`
+//      expressions.
+//  [B] A null-aware `parameters?.` that is optimized away because `parameters`
+//      is always non-null.
+//  [C] A repeated expression after the optimized null-aware access.
+
+class Thing {
+  @pragma('dart2js:noInline')
+  void addAll(x, y) {}
+}
+
+class A {
+  Thing parameters = Thing();
+}
+
+class AX {
+  A a;
+  AX(this.a);
+}
+
+class Host {
+  AX ax;
+  Host(this.ax);
+
+  algo(int n) {
+    if (ax?.a == null) return;
+    ax?.a.parameters?.addAll(n + 1, n + 1);
+  }
+}
+
+main() {
+  Host(null).algo(1);
+  Host(AX(A())).algo(2);
+  Host(AX(null)).algo(3);
+}
diff --git a/third_party/llvm/BUILD.gn b/third_party/llvm/BUILD.gn
deleted file mode 100644
index bb18f60..0000000
--- a/third_party/llvm/BUILD.gn
+++ /dev/null
@@ -1,1520 +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.
-
-declare_args() {
-  llvm_prefix = "//third_party/llvm"
-}
-
-template("llvm_library") {
-  config(target_name + "_config") {
-    visibility = [ ":*" ]
-    include_dirs = [ "include" ]
-    libs = [ "lib/lib${target_name}.a" ]
-  }
-
-  group(target_name) {
-    forward_variables_from(invoker, [ "deps" ])
-    public_configs = [ ":${target_name}_config" ]
-  }
-}
-
-llvm_library("LLVMDemangle") {
-}
-
-llvm_library("LLVMSupport") {
-  deps = [ ":LLVMDemangle" ]
-}
-
-llvm_library("LLVMAArch64Utils") {
-  deps = [ ":LLVMSupport" ]
-}
-
-llvm_library("LLVMBinaryFormat") {
-  deps = [ ":LLVMSupport" ]
-}
-
-llvm_library("LLVMDebugInfoMSF") {
-  deps = [ ":LLVMSupport" ]
-}
-
-llvm_library("LLVMDebugInfoCodeView") {
-  deps = [
-    ":LLVMDebugInfoMSF",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMMC") {
-  deps = [
-    ":LLVMBinaryFormat",
-    ":LLVMDebugInfoCodeView",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMAArch64AsmPrinter") {
-  deps = [
-    ":LLVMAArch64Utils",
-    ":LLVMMC",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMAArch64Info") {
-  deps = [ ":LLVMSupport" ]
-}
-
-llvm_library("LLVMAArch64Desc") {
-  deps = [
-    ":LLVMAArch64AsmPrinter",
-    ":LLVMAArch64Info",
-    ":LLVMMC",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMMCParser") {
-  deps = [
-    ":LLVMMC",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMAArch64AsmParser") {
-  deps = [
-    ":LLVMAArch64Desc",
-    ":LLVMAArch64Info",
-    ":LLVMAArch64Utils",
-    ":LLVMMC",
-    ":LLVMMCParser",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMCore") {
-  deps = [
-    ":LLVMBinaryFormat",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMBitReader") {
-  deps = [
-    ":LLVMCore",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMObject") {
-  deps = [
-    ":LLVMBinaryFormat",
-    ":LLVMBitReader",
-    ":LLVMCore",
-    ":LLVMMC",
-    ":LLVMMCParser",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMProfileData") {
-  deps = [
-    ":LLVMCore",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMAnalysis") {
-  deps = [
-    ":LLVMBinaryFormat",
-    ":LLVMCore",
-    ":LLVMObject",
-    ":LLVMProfileData",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMBitWriter") {
-  deps = [
-    ":LLVMAnalysis",
-    ":LLVMCore",
-    ":LLVMMC",
-    ":LLVMObject",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMTransformUtils") {
-  deps = [
-    ":LLVMAnalysis",
-    ":LLVMCore",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMAggressiveInstCombine") {
-  deps = [
-    ":LLVMAnalysis",
-    ":LLVMCore",
-    ":LLVMSupport",
-    ":LLVMTransformUtils",
-  ]
-}
-
-llvm_library("LLVMInstCombine") {
-  deps = [
-    ":LLVMAnalysis",
-    ":LLVMCore",
-    ":LLVMSupport",
-    ":LLVMTransformUtils",
-  ]
-}
-
-llvm_library("LLVMScalarOpts") {
-  deps = [
-    ":LLVMAggressiveInstCombine",
-    ":LLVMAnalysis",
-    ":LLVMCore",
-    ":LLVMInstCombine",
-    ":LLVMSupport",
-    ":LLVMTransformUtils",
-  ]
-}
-
-llvm_library("LLVMTarget") {
-  deps = [
-    ":LLVMAnalysis",
-    ":LLVMCore",
-    ":LLVMMC",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMCodeGen") {
-  deps = [
-    ":LLVMAnalysis",
-    ":LLVMBitReader",
-    ":LLVMBitWriter",
-    ":LLVMCore",
-    ":LLVMMC",
-    ":LLVMProfileData",
-    ":LLVMScalarOpts",
-    ":LLVMSupport",
-    ":LLVMTarget",
-    ":LLVMTransformUtils",
-  ]
-}
-
-llvm_library("LLVMAsmPrinter") {
-  deps = [
-    ":LLVMAnalysis",
-    ":LLVMBinaryFormat",
-    ":LLVMCodeGen",
-    ":LLVMCore",
-    ":LLVMDebugInfoCodeView",
-    ":LLVMDebugInfoMSF",
-    ":LLVMMC",
-    ":LLVMMCParser",
-    ":LLVMSupport",
-    ":LLVMTarget",
-  ]
-}
-
-llvm_library("LLVMSelectionDAG") {
-  deps = [
-    ":LLVMAnalysis",
-    ":LLVMCodeGen",
-    ":LLVMCore",
-    ":LLVMMC",
-    ":LLVMSupport",
-    ":LLVMTarget",
-    ":LLVMTransformUtils",
-  ]
-}
-
-llvm_library("LLVMGlobalISel") {
-  deps = [
-    ":LLVMAnalysis",
-    ":LLVMCodeGen",
-    ":LLVMCore",
-    ":LLVMMC",
-    ":LLVMSupport",
-    ":LLVMTarget",
-    ":LLVMTransformUtils",
-  ]
-}
-
-llvm_library("LLVMAArch64CodeGen") {
-  deps = [
-    ":LLVMAArch64AsmPrinter",
-    ":LLVMAArch64Desc",
-    ":LLVMAArch64Info",
-    ":LLVMAArch64Utils",
-    ":LLVMAnalysis",
-    ":LLVMAsmPrinter",
-    ":LLVMCodeGen",
-    ":LLVMCore",
-    ":LLVMGlobalISel",
-    ":LLVMMC",
-    ":LLVMScalarOpts",
-    ":LLVMSelectionDAG",
-    ":LLVMSupport",
-    ":LLVMTarget",
-  ]
-}
-
-llvm_library("LLVMMCDisassembler") {
-  deps = [
-    ":LLVMMC",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMAArch64Disassembler") {
-  deps = [
-    ":LLVMAArch64Desc",
-    ":LLVMAArch64Info",
-    ":LLVMAArch64Utils",
-    ":LLVMMC",
-    ":LLVMMCDisassembler",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMAMDGPUUtils") {
-  deps = [
-    ":LLVMCore",
-    ":LLVMMC",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMAMDGPUAsmPrinter") {
-  deps = [
-    ":LLVMAMDGPUUtils",
-    ":LLVMMC",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMAMDGPUInfo") {
-  deps = [ ":LLVMSupport" ]
-}
-
-llvm_library("LLVMAMDGPUDesc") {
-  deps = [
-    ":LLVMAMDGPUAsmPrinter",
-    ":LLVMAMDGPUInfo",
-    ":LLVMAMDGPUUtils",
-    ":LLVMCore",
-    ":LLVMMC",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMAMDGPUAsmParser") {
-  deps = [
-    ":LLVMAMDGPUDesc",
-    ":LLVMAMDGPUInfo",
-    ":LLVMAMDGPUUtils",
-    ":LLVMMC",
-    ":LLVMMCParser",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMAsmParser") {
-  deps = [
-    ":LLVMBinaryFormat",
-    ":LLVMCore",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMIRReader") {
-  deps = [
-    ":LLVMAsmParser",
-    ":LLVMBitReader",
-    ":LLVMCore",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMLinker") {
-  deps = [
-    ":LLVMCore",
-    ":LLVMSupport",
-    ":LLVMTransformUtils",
-  ]
-}
-
-llvm_library("LLVMVectorize") {
-  deps = [
-    ":LLVMAnalysis",
-    ":LLVMCore",
-    ":LLVMSupport",
-    ":LLVMTransformUtils",
-  ]
-}
-
-llvm_library("LLVMInstrumentation") {
-  deps = [
-    ":LLVMAnalysis",
-    ":LLVMCore",
-    ":LLVMMC",
-    ":LLVMProfileData",
-    ":LLVMSupport",
-    ":LLVMTransformUtils",
-  ]
-}
-
-llvm_library("LLVMipo") {
-  deps = [
-    ":LLVMAggressiveInstCombine",
-    ":LLVMAnalysis",
-    ":LLVMBitReader",
-    ":LLVMBitWriter",
-    ":LLVMCore",
-    ":LLVMIRReader",
-    ":LLVMInstCombine",
-    ":LLVMInstrumentation",
-    ":LLVMLinker",
-    ":LLVMObject",
-    ":LLVMProfileData",
-    ":LLVMScalarOpts",
-    ":LLVMSupport",
-    ":LLVMTransformUtils",
-    ":LLVMVectorize",
-  ]
-}
-
-llvm_library("LLVMAMDGPUCodeGen") {
-  deps = [
-    ":LLVMAMDGPUAsmPrinter",
-    ":LLVMAMDGPUDesc",
-    ":LLVMAMDGPUInfo",
-    ":LLVMAMDGPUUtils",
-    ":LLVMAnalysis",
-    ":LLVMAsmPrinter",
-    ":LLVMCodeGen",
-    ":LLVMCore",
-    ":LLVMGlobalISel",
-    ":LLVMMC",
-    ":LLVMScalarOpts",
-    ":LLVMSelectionDAG",
-    ":LLVMSupport",
-    ":LLVMTarget",
-    ":LLVMTransformUtils",
-    ":LLVMVectorize",
-    ":LLVMipo",
-  ]
-}
-
-llvm_library("LLVMAMDGPUDisassembler") {
-  deps = [
-    ":LLVMAMDGPUDesc",
-    ":LLVMAMDGPUInfo",
-    ":LLVMAMDGPUUtils",
-    ":LLVMMC",
-    ":LLVMMCDisassembler",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMARCAsmPrinter") {
-  deps = [
-    ":LLVMMC",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMARCInfo") {
-  deps = [ ":LLVMSupport" ]
-}
-
-llvm_library("LLVMARCDesc") {
-  deps = [
-    ":LLVMARCAsmPrinter",
-    ":LLVMARCInfo",
-    ":LLVMMC",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMARCCodeGen") {
-  deps = [
-    ":LLVMARCAsmPrinter",
-    ":LLVMARCDesc",
-    ":LLVMARCInfo",
-    ":LLVMAnalysis",
-    ":LLVMAsmPrinter",
-    ":LLVMCodeGen",
-    ":LLVMCore",
-    ":LLVMMC",
-    ":LLVMSelectionDAG",
-    ":LLVMSupport",
-    ":LLVMTarget",
-    ":LLVMTransformUtils",
-  ]
-}
-
-llvm_library("LLVMARCDisassembler") {
-  deps = [
-    ":LLVMARCInfo",
-    ":LLVMMCDisassembler",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMARMUtils") {
-  deps = [ ":LLVMSupport" ]
-}
-
-llvm_library("LLVMARMAsmPrinter") {
-  deps = [
-    ":LLVMARMUtils",
-    ":LLVMMC",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMARMInfo") {
-  deps = [ ":LLVMSupport" ]
-}
-
-llvm_library("LLVMARMDesc") {
-  deps = [
-    ":LLVMARMAsmPrinter",
-    ":LLVMARMInfo",
-    ":LLVMMC",
-    ":LLVMMCDisassembler",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMARMAsmParser") {
-  deps = [
-    ":LLVMARMDesc",
-    ":LLVMARMInfo",
-    ":LLVMARMUtils",
-    ":LLVMMC",
-    ":LLVMMCParser",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMARMCodeGen") {
-  deps = [
-    ":LLVMARMAsmPrinter",
-    ":LLVMARMDesc",
-    ":LLVMARMInfo",
-    ":LLVMARMUtils",
-    ":LLVMAnalysis",
-    ":LLVMAsmPrinter",
-    ":LLVMCodeGen",
-    ":LLVMCore",
-    ":LLVMGlobalISel",
-    ":LLVMMC",
-    ":LLVMScalarOpts",
-    ":LLVMSelectionDAG",
-    ":LLVMSupport",
-    ":LLVMTarget",
-    ":LLVMTransformUtils",
-  ]
-}
-
-llvm_library("LLVMARMDisassembler") {
-  deps = [
-    ":LLVMARMDesc",
-    ":LLVMARMInfo",
-    ":LLVMARMUtils",
-    ":LLVMMCDisassembler",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMAVRAsmPrinter") {
-  deps = [
-    ":LLVMMC",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMAVRInfo") {
-  deps = [
-    ":LLVMMC",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMAVRDesc") {
-  deps = [
-    ":LLVMAVRAsmPrinter",
-    ":LLVMAVRInfo",
-    ":LLVMMC",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMAVRAsmParser") {
-  deps = [
-    ":LLVMAVRDesc",
-    ":LLVMAVRInfo",
-    ":LLVMMC",
-    ":LLVMMCParser",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMAVRCodeGen") {
-  deps = [
-    ":LLVMAVRAsmPrinter",
-    ":LLVMAVRDesc",
-    ":LLVMAVRInfo",
-    ":LLVMAsmPrinter",
-    ":LLVMCodeGen",
-    ":LLVMCore",
-    ":LLVMMC",
-    ":LLVMSelectionDAG",
-    ":LLVMSupport",
-    ":LLVMTarget",
-  ]
-}
-
-llvm_library("LLVMAVRDisassembler") {
-  deps = [
-    ":LLVMAVRInfo",
-    ":LLVMMCDisassembler",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMBPFAsmPrinter") {
-  deps = [
-    ":LLVMMC",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMBPFInfo") {
-  deps = [ ":LLVMSupport" ]
-}
-
-llvm_library("LLVMBPFDesc") {
-  deps = [
-    ":LLVMBPFAsmPrinter",
-    ":LLVMBPFInfo",
-    ":LLVMMC",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMBPFAsmParser") {
-  deps = [
-    ":LLVMBPFDesc",
-    ":LLVMBPFInfo",
-    ":LLVMMC",
-    ":LLVMMCParser",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMBPFCodeGen") {
-  deps = [
-    ":LLVMAsmPrinter",
-    ":LLVMBPFAsmPrinter",
-    ":LLVMBPFDesc",
-    ":LLVMBPFInfo",
-    ":LLVMCodeGen",
-    ":LLVMCore",
-    ":LLVMMC",
-    ":LLVMSelectionDAG",
-    ":LLVMSupport",
-    ":LLVMTarget",
-  ]
-}
-
-llvm_library("LLVMBPFDisassembler") {
-  deps = [
-    ":LLVMBPFInfo",
-    ":LLVMMCDisassembler",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMCoroutines") {
-  deps = [
-    ":LLVMAnalysis",
-    ":LLVMCore",
-    ":LLVMScalarOpts",
-    ":LLVMSupport",
-    ":LLVMTransformUtils",
-    ":LLVMipo",
-  ]
-}
-
-llvm_library("LLVMCoverage") {
-  deps = [
-    ":LLVMCore",
-    ":LLVMObject",
-    ":LLVMProfileData",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMDebugInfoDWARF") {
-  deps = [
-    ":LLVMBinaryFormat",
-    ":LLVMMC",
-    ":LLVMObject",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMDebugInfoPDB") {
-  deps = [
-    ":LLVMDebugInfoCodeView",
-    ":LLVMDebugInfoMSF",
-    ":LLVMObject",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMOption") {
-  deps = [ ":LLVMSupport" ]
-}
-
-llvm_library("LLVMDlltoolDriver") {
-  deps = [
-    ":LLVMObject",
-    ":LLVMOption",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMRuntimeDyld") {
-  deps = [
-    ":LLVMMC",
-    ":LLVMObject",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMExecutionEngine") {
-  deps = [
-    ":LLVMCore",
-    ":LLVMMC",
-    ":LLVMObject",
-    ":LLVMRuntimeDyld",
-    ":LLVMSupport",
-    ":LLVMTarget",
-  ]
-}
-
-llvm_library("LLVMMCJIT") {
-  deps = [
-    ":LLVMCore",
-    ":LLVMExecutionEngine",
-    ":LLVMObject",
-    ":LLVMRuntimeDyld",
-    ":LLVMSupport",
-    ":LLVMTarget",
-  ]
-}
-
-llvm_library("LLVMFuzzMutate") {
-  deps = [
-    ":LLVMAnalysis",
-    ":LLVMBitReader",
-    ":LLVMBitWriter",
-    ":LLVMCore",
-    ":LLVMScalarOpts",
-    ":LLVMSupport",
-    ":LLVMTarget",
-  ]
-}
-
-llvm_library("LLVMHexagonInfo") {
-  deps = [ ":LLVMSupport" ]
-}
-
-llvm_library("LLVMHexagonDesc") {
-  deps = [
-    ":LLVMHexagonInfo",
-    ":LLVMMC",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMHexagonAsmParser") {
-  deps = [
-    ":LLVMHexagonDesc",
-    ":LLVMHexagonInfo",
-    ":LLVMMC",
-    ":LLVMMCParser",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMHexagonCodeGen") {
-  deps = [
-    ":LLVMAnalysis",
-    ":LLVMAsmPrinter",
-    ":LLVMCodeGen",
-    ":LLVMCore",
-    ":LLVMHexagonAsmParser",
-    ":LLVMHexagonDesc",
-    ":LLVMHexagonInfo",
-    ":LLVMMC",
-    ":LLVMScalarOpts",
-    ":LLVMSelectionDAG",
-    ":LLVMSupport",
-    ":LLVMTarget",
-    ":LLVMTransformUtils",
-    ":LLVMipo",
-  ]
-}
-
-llvm_library("LLVMHexagonDisassembler") {
-  deps = [
-    ":LLVMHexagonDesc",
-    ":LLVMHexagonInfo",
-    ":LLVMMC",
-    ":LLVMMCDisassembler",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMInterpreter") {
-  deps = [
-    ":LLVMCodeGen",
-    ":LLVMCore",
-    ":LLVMExecutionEngine",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMObjCARCOpts") {
-  deps = [
-    ":LLVMAnalysis",
-    ":LLVMCore",
-    ":LLVMSupport",
-    ":LLVMTransformUtils",
-  ]
-}
-
-llvm_library("LLVMPasses") {
-  deps = [
-    ":LLVMAggressiveInstCombine",
-    ":LLVMAnalysis",
-    ":LLVMCodeGen",
-    ":LLVMCore",
-    ":LLVMInstCombine",
-    ":LLVMInstrumentation",
-    ":LLVMScalarOpts",
-    ":LLVMSupport",
-    ":LLVMTarget",
-    ":LLVMTransformUtils",
-    ":LLVMVectorize",
-    ":LLVMipo",
-  ]
-}
-
-llvm_library("LLVMLTO") {
-  deps = [
-    ":LLVMAggressiveInstCombine",
-    ":LLVMAnalysis",
-    ":LLVMBitReader",
-    ":LLVMBitWriter",
-    ":LLVMCodeGen",
-    ":LLVMCore",
-    ":LLVMInstCombine",
-    ":LLVMLinker",
-    ":LLVMMC",
-    ":LLVMObjCARCOpts",
-    ":LLVMObject",
-    ":LLVMPasses",
-    ":LLVMScalarOpts",
-    ":LLVMSupport",
-    ":LLVMTarget",
-    ":LLVMTransformUtils",
-    ":LLVMipo",
-  ]
-}
-
-llvm_library("LLVMLanaiInfo") {
-  deps = [ ":LLVMSupport" ]
-}
-
-llvm_library("LLVMLanaiAsmPrinter") {
-  deps = [
-    ":LLVMMC",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMLanaiDesc") {
-  deps = [
-    ":LLVMLanaiAsmPrinter",
-    ":LLVMLanaiInfo",
-    ":LLVMMC",
-    ":LLVMMCDisassembler",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMLanaiAsmParser") {
-  deps = [
-    ":LLVMLanaiDesc",
-    ":LLVMLanaiInfo",
-    ":LLVMMC",
-    ":LLVMMCParser",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMLanaiCodeGen") {
-  deps = [
-    ":LLVMAnalysis",
-    ":LLVMAsmPrinter",
-    ":LLVMCodeGen",
-    ":LLVMCore",
-    ":LLVMLanaiAsmParser",
-    ":LLVMLanaiAsmPrinter",
-    ":LLVMLanaiDesc",
-    ":LLVMLanaiInfo",
-    ":LLVMMC",
-    ":LLVMSelectionDAG",
-    ":LLVMSupport",
-    ":LLVMTarget",
-    ":LLVMTransformUtils",
-  ]
-}
-
-llvm_library("LLVMLanaiDisassembler") {
-  deps = [
-    ":LLVMLanaiDesc",
-    ":LLVMLanaiInfo",
-    ":LLVMMC",
-    ":LLVMMCDisassembler",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMLibDriver") {
-  deps = [
-    ":LLVMBinaryFormat",
-    ":LLVMObject",
-    ":LLVMOption",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMLineEditor") {
-  deps = [ ":LLVMSupport" ]
-}
-
-llvm_library("LLVMMIRParser") {
-  deps = [
-    ":LLVMAsmParser",
-    ":LLVMBinaryFormat",
-    ":LLVMCodeGen",
-    ":LLVMCore",
-    ":LLVMMC",
-    ":LLVMSupport",
-    ":LLVMTarget",
-  ]
-}
-
-llvm_library("LLVMMSP430AsmPrinter") {
-  deps = [
-    ":LLVMMC",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMMSP430Info") {
-  deps = [ ":LLVMSupport" ]
-}
-
-llvm_library("LLVMMSP430Desc") {
-  deps = [
-    ":LLVMMC",
-    ":LLVMMSP430AsmPrinter",
-    ":LLVMMSP430Info",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMMSP430CodeGen") {
-  deps = [
-    ":LLVMAsmPrinter",
-    ":LLVMCodeGen",
-    ":LLVMCore",
-    ":LLVMMC",
-    ":LLVMMSP430AsmPrinter",
-    ":LLVMMSP430Desc",
-    ":LLVMMSP430Info",
-    ":LLVMSelectionDAG",
-    ":LLVMSupport",
-    ":LLVMTarget",
-  ]
-}
-
-llvm_library("LLVMMipsAsmPrinter") {
-  deps = [
-    ":LLVMMC",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMMipsInfo") {
-  deps = [ ":LLVMSupport" ]
-}
-
-llvm_library("LLVMMipsDesc") {
-  deps = [
-    ":LLVMMC",
-    ":LLVMMipsAsmPrinter",
-    ":LLVMMipsInfo",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMMipsAsmParser") {
-  deps = [
-    ":LLVMMC",
-    ":LLVMMCParser",
-    ":LLVMMipsDesc",
-    ":LLVMMipsInfo",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMMipsCodeGen") {
-  deps = [
-    ":LLVMAnalysis",
-    ":LLVMAsmPrinter",
-    ":LLVMCodeGen",
-    ":LLVMCore",
-    ":LLVMGlobalISel",
-    ":LLVMMC",
-    ":LLVMMipsAsmPrinter",
-    ":LLVMMipsDesc",
-    ":LLVMMipsInfo",
-    ":LLVMSelectionDAG",
-    ":LLVMSupport",
-    ":LLVMTarget",
-  ]
-}
-
-llvm_library("LLVMMipsDisassembler") {
-  deps = [
-    ":LLVMMCDisassembler",
-    ":LLVMMipsInfo",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMNVPTXAsmPrinter") {
-  deps = [
-    ":LLVMMC",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMNVPTXInfo") {
-  deps = [ ":LLVMSupport" ]
-}
-
-llvm_library("LLVMNVPTXDesc") {
-  deps = [
-    ":LLVMMC",
-    ":LLVMNVPTXAsmPrinter",
-    ":LLVMNVPTXInfo",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMNVPTXCodeGen") {
-  deps = [
-    ":LLVMAnalysis",
-    ":LLVMAsmPrinter",
-    ":LLVMCodeGen",
-    ":LLVMCore",
-    ":LLVMMC",
-    ":LLVMNVPTXAsmPrinter",
-    ":LLVMNVPTXDesc",
-    ":LLVMNVPTXInfo",
-    ":LLVMScalarOpts",
-    ":LLVMSelectionDAG",
-    ":LLVMSupport",
-    ":LLVMTarget",
-    ":LLVMTransformUtils",
-    ":LLVMVectorize",
-    ":LLVMipo",
-  ]
-}
-
-llvm_library("LLVMX86Utils") {
-  deps = [
-    ":LLVMCore",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMX86AsmPrinter") {
-  deps = [
-    ":LLVMMC",
-    ":LLVMSupport",
-    ":LLVMX86Utils",
-  ]
-}
-
-llvm_library("LLVMX86Info") {
-  deps = [ ":LLVMSupport" ]
-}
-
-llvm_library("LLVMX86Desc") {
-  deps = [
-    ":LLVMMC",
-    ":LLVMMCDisassembler",
-    ":LLVMObject",
-    ":LLVMSupport",
-    ":LLVMX86AsmPrinter",
-    ":LLVMX86Info",
-  ]
-}
-
-llvm_library("LLVMX86CodeGen") {
-  deps = [
-    ":LLVMAnalysis",
-    ":LLVMAsmPrinter",
-    ":LLVMCodeGen",
-    ":LLVMCore",
-    ":LLVMGlobalISel",
-    ":LLVMMC",
-    ":LLVMSelectionDAG",
-    ":LLVMSupport",
-    ":LLVMTarget",
-    ":LLVMX86AsmPrinter",
-    ":LLVMX86Desc",
-    ":LLVMX86Info",
-    ":LLVMX86Utils",
-  ]
-}
-
-llvm_library("LLVMNios2AsmPrinter") {
-  deps = [
-    ":LLVMMC",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMNios2Info") {
-  deps = [ ":LLVMSupport" ]
-}
-
-llvm_library("LLVMNios2Desc") {
-  deps = [
-    ":LLVMMC",
-    ":LLVMNios2AsmPrinter",
-    ":LLVMNios2Info",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMNios2CodeGen") {
-  deps = [
-    ":LLVMAsmPrinter",
-    ":LLVMCodeGen",
-    ":LLVMCore",
-    ":LLVMGlobalISel",
-    ":LLVMMC",
-    ":LLVMNios2Desc",
-    ":LLVMNios2Info",
-    ":LLVMSelectionDAG",
-    ":LLVMSupport",
-    ":LLVMTarget",
-  ]
-}
-
-llvm_library("LLVMObjectYAML") {
-  deps = [
-    ":LLVMDebugInfoCodeView",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMOrcJIT") {
-  deps = [
-    ":LLVMCore",
-    ":LLVMExecutionEngine",
-    ":LLVMMC",
-    ":LLVMObject",
-    ":LLVMRuntimeDyld",
-    ":LLVMSupport",
-    ":LLVMTarget",
-    ":LLVMTransformUtils",
-  ]
-}
-
-llvm_library("LLVMPowerPCAsmPrinter") {
-  deps = [
-    ":LLVMMC",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMPowerPCInfo") {
-  deps = [ ":LLVMSupport" ]
-}
-
-llvm_library("LLVMPowerPCDesc") {
-  deps = [
-    ":LLVMMC",
-    ":LLVMPowerPCAsmPrinter",
-    ":LLVMPowerPCInfo",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMPowerPCAsmParser") {
-  deps = [
-    ":LLVMMC",
-    ":LLVMMCParser",
-    ":LLVMPowerPCDesc",
-    ":LLVMPowerPCInfo",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMPowerPCCodeGen") {
-  deps = [
-    ":LLVMAnalysis",
-    ":LLVMAsmPrinter",
-    ":LLVMCodeGen",
-    ":LLVMCore",
-    ":LLVMMC",
-    ":LLVMPowerPCAsmPrinter",
-    ":LLVMPowerPCDesc",
-    ":LLVMPowerPCInfo",
-    ":LLVMScalarOpts",
-    ":LLVMSelectionDAG",
-    ":LLVMSupport",
-    ":LLVMTarget",
-    ":LLVMTransformUtils",
-  ]
-}
-
-llvm_library("LLVMPowerPCDisassembler") {
-  deps = [
-    ":LLVMMCDisassembler",
-    ":LLVMPowerPCInfo",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMRISCVAsmPrinter") {
-  deps = [
-    ":LLVMMC",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMRISCVInfo") {
-  deps = [ ":LLVMSupport" ]
-}
-
-llvm_library("LLVMRISCVDesc") {
-  deps = [
-    ":LLVMMC",
-    ":LLVMRISCVAsmPrinter",
-    ":LLVMRISCVInfo",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMRISCVAsmParser") {
-  deps = [
-    ":LLVMMC",
-    ":LLVMMCParser",
-    ":LLVMRISCVDesc",
-    ":LLVMRISCVInfo",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMRISCVCodeGen") {
-  deps = [
-    ":LLVMAsmPrinter",
-    ":LLVMCodeGen",
-    ":LLVMCore",
-    ":LLVMMC",
-    ":LLVMRISCVAsmPrinter",
-    ":LLVMRISCVDesc",
-    ":LLVMRISCVInfo",
-    ":LLVMSelectionDAG",
-    ":LLVMSupport",
-    ":LLVMTarget",
-  ]
-}
-
-llvm_library("LLVMRISCVDisassembler") {
-  deps = [
-    ":LLVMMCDisassembler",
-    ":LLVMRISCVInfo",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMSparcAsmPrinter") {
-  deps = [
-    ":LLVMMC",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMSparcInfo") {
-  deps = [ ":LLVMSupport" ]
-}
-
-llvm_library("LLVMSparcDesc") {
-  deps = [
-    ":LLVMMC",
-    ":LLVMSparcAsmPrinter",
-    ":LLVMSparcInfo",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMSparcAsmParser") {
-  deps = [
-    ":LLVMMC",
-    ":LLVMMCParser",
-    ":LLVMSparcDesc",
-    ":LLVMSparcInfo",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMSparcCodeGen") {
-  deps = [
-    ":LLVMAsmPrinter",
-    ":LLVMCodeGen",
-    ":LLVMCore",
-    ":LLVMMC",
-    ":LLVMSelectionDAG",
-    ":LLVMSparcAsmPrinter",
-    ":LLVMSparcDesc",
-    ":LLVMSparcInfo",
-    ":LLVMSupport",
-    ":LLVMTarget",
-  ]
-}
-
-llvm_library("LLVMSparcDisassembler") {
-  deps = [
-    ":LLVMMCDisassembler",
-    ":LLVMSparcInfo",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMSymbolize") {
-  deps = [
-    ":LLVMDebugInfoDWARF",
-    ":LLVMDebugInfoPDB",
-    ":LLVMDemangle",
-    ":LLVMObject",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMSystemZAsmPrinter") {
-  deps = [
-    ":LLVMMC",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMSystemZInfo") {
-  deps = [ ":LLVMSupport" ]
-}
-
-llvm_library("LLVMSystemZDesc") {
-  deps = [
-    ":LLVMMC",
-    ":LLVMSupport",
-    ":LLVMSystemZAsmPrinter",
-    ":LLVMSystemZInfo",
-  ]
-}
-
-llvm_library("LLVMSystemZAsmParser") {
-  deps = [
-    ":LLVMMC",
-    ":LLVMMCParser",
-    ":LLVMSupport",
-    ":LLVMSystemZDesc",
-    ":LLVMSystemZInfo",
-  ]
-}
-
-llvm_library("LLVMSystemZCodeGen") {
-  deps = [
-    ":LLVMAnalysis",
-    ":LLVMAsmPrinter",
-    ":LLVMCodeGen",
-    ":LLVMCore",
-    ":LLVMMC",
-    ":LLVMScalarOpts",
-    ":LLVMSelectionDAG",
-    ":LLVMSupport",
-    ":LLVMSystemZAsmPrinter",
-    ":LLVMSystemZDesc",
-    ":LLVMSystemZInfo",
-    ":LLVMTarget",
-  ]
-}
-
-llvm_library("LLVMSystemZDisassembler") {
-  deps = [
-    ":LLVMMC",
-    ":LLVMMCDisassembler",
-    ":LLVMSupport",
-    ":LLVMSystemZDesc",
-    ":LLVMSystemZInfo",
-  ]
-}
-
-llvm_library("LLVMTableGen") {
-  deps = [ ":LLVMSupport" ]
-}
-
-llvm_library("LLVMTestingSupport") {
-  deps = [ ":LLVMSupport" ]
-}
-
-llvm_library("LLVMWebAssemblyInfo") {
-  deps = [ ":LLVMSupport" ]
-}
-
-llvm_library("LLVMWebAssemblyAsmParser") {
-  deps = [
-    ":LLVMMC",
-    ":LLVMMCParser",
-    ":LLVMSupport",
-    ":LLVMWebAssemblyInfo",
-  ]
-}
-
-llvm_library("LLVMWebAssemblyAsmPrinter") {
-  deps = [
-    ":LLVMMC",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMWebAssemblyDesc") {
-  deps = [
-    ":LLVMMC",
-    ":LLVMSupport",
-    ":LLVMWebAssemblyAsmPrinter",
-    ":LLVMWebAssemblyInfo",
-  ]
-}
-
-llvm_library("LLVMWebAssemblyCodeGen") {
-  deps = [
-    ":LLVMAnalysis",
-    ":LLVMAsmPrinter",
-    ":LLVMCodeGen",
-    ":LLVMCore",
-    ":LLVMMC",
-    ":LLVMScalarOpts",
-    ":LLVMSelectionDAG",
-    ":LLVMSupport",
-    ":LLVMTarget",
-    ":LLVMTransformUtils",
-    ":LLVMWebAssemblyAsmPrinter",
-    ":LLVMWebAssemblyDesc",
-    ":LLVMWebAssemblyInfo",
-  ]
-}
-
-llvm_library("LLVMWebAssemblyDisassembler") {
-  deps = [
-    ":LLVMMCDisassembler",
-    ":LLVMSupport",
-    ":LLVMWebAssemblyInfo",
-  ]
-}
-
-llvm_library("LLVMWindowsManifest") {
-  deps = [ ":LLVMSupport" ]
-}
-
-llvm_library("LLVMX86AsmParser") {
-  deps = [
-    ":LLVMMC",
-    ":LLVMMCParser",
-    ":LLVMSupport",
-    ":LLVMX86AsmPrinter",
-    ":LLVMX86Desc",
-    ":LLVMX86Info",
-  ]
-}
-
-llvm_library("LLVMX86Disassembler") {
-  deps = [
-    ":LLVMMCDisassembler",
-    ":LLVMSupport",
-    ":LLVMX86Info",
-  ]
-}
-
-llvm_library("LLVMXCoreAsmPrinter") {
-  deps = [
-    ":LLVMMC",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMXCoreInfo") {
-  deps = [ ":LLVMSupport" ]
-}
-
-llvm_library("LLVMXCoreDesc") {
-  deps = [
-    ":LLVMMC",
-    ":LLVMSupport",
-    ":LLVMXCoreAsmPrinter",
-    ":LLVMXCoreInfo",
-  ]
-}
-
-llvm_library("LLVMXCoreCodeGen") {
-  deps = [
-    ":LLVMAnalysis",
-    ":LLVMAsmPrinter",
-    ":LLVMCodeGen",
-    ":LLVMCore",
-    ":LLVMMC",
-    ":LLVMSelectionDAG",
-    ":LLVMSupport",
-    ":LLVMTarget",
-    ":LLVMTransformUtils",
-    ":LLVMXCoreAsmPrinter",
-    ":LLVMXCoreDesc",
-    ":LLVMXCoreInfo",
-  ]
-}
-
-llvm_library("LLVMXCoreDisassembler") {
-  deps = [
-    ":LLVMMCDisassembler",
-    ":LLVMSupport",
-    ":LLVMXCoreInfo",
-  ]
-}
diff --git a/third_party/wasmer/.gitignore b/third_party/wasmer/.gitignore
deleted file mode 100644
index 86a9394..0000000
--- a/third_party/wasmer/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-!*
-Cargo.lock
diff --git a/third_party/wasmer/BUILD.gn b/third_party/wasmer/BUILD.gn
deleted file mode 100644
index 0f65bf7..0000000
--- a/third_party/wasmer/BUILD.gn
+++ /dev/null
@@ -1,24 +0,0 @@
-import("../../build/rust/rust.gni")
-
-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"
-}
diff --git a/third_party/wasmer/Cargo.toml b/third_party/wasmer/Cargo.toml
deleted file mode 100644
index a476549..0000000
--- a/third_party/wasmer/Cargo.toml
+++ /dev/null
@@ -1,13 +0,0 @@
-[package]
-name = "wasmer"
-version = "1.0.0-alpha5"
-
-[lib]
-name = "wasmer"
-crate-type = ["staticlib"]
-path = "wasmer.rs"
-
-[dependencies.wasmer-c-api]
-version = "1.0.0-alpha5"
-default-features = false
-features = ["jit", "cranelift", "wasi"]
diff --git a/third_party/wasmer/LICENSE b/third_party/wasmer/LICENSE
deleted file mode 100644
index 62bb543..0000000
--- a/third_party/wasmer/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2019-present Wasmer, Inc. and its affiliates.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/third_party/wasmer/finalizers.cc b/third_party/wasmer/finalizers.cc
deleted file mode 100644
index 85d5286..0000000
--- a/third_party/wasmer/finalizers.cc
+++ /dev/null
@@ -1,26 +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 "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/third_party/wasmer/wasmer.rs b/third_party/wasmer/wasmer.rs
deleted file mode 100644
index c4bd6e5..0000000
--- a/third_party/wasmer/wasmer.rs
+++ /dev/null
@@ -1 +0,0 @@
-pub extern crate wasmer_c_api;
diff --git a/tools/VERSION b/tools/VERSION
index b35dfdc..fa9f98f 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 13
 PATCH 0
-PRERELEASE 116
+PRERELEASE 211
 PRERELEASE_PATCH 1
\ No newline at end of file
diff --git a/tools/bots/flutter/compile_flutter.sh b/tools/bots/flutter/compile_flutter.sh
index 194beb2..4e8a59f 100755
--- a/tools/bots/flutter/compile_flutter.sh
+++ b/tools/bots/flutter/compile_flutter.sh
@@ -9,6 +9,7 @@
 
 prepareOnly=false
 leakTest=false
+weeklyTest=false
 
 REMAINING_ARGS=()
 while [[ $# -gt 0 ]]; do
@@ -21,6 +22,10 @@
       leakTest=true
       shift
       ;;
+    --weeklyTest|--weekly-test|--weekly_test)
+      weeklyTest=true
+      shift
+      ;;
     *)
       REMAINING_ARGS+=("$1")
       shift
@@ -115,6 +120,12 @@
       --enable-asserts \
       pkg/front_end/test/flutter_gallery_leak_tester.dart \
       --path=$tmpdir
+elif $weeklyTest; then
+  $dart \
+      --enable-asserts \
+      pkg/front_end/test/weekly_tester.dart \
+      --path=$tmpdir \
+      $@
 else
   $dart \
       --enable-asserts \
diff --git a/tools/bots/lib/src/firestore.dart b/tools/bots/lib/src/firestore.dart
index 166173c..80b2315 100644
--- a/tools/bots/lib/src/firestore.dart
+++ b/tools/bots/lib/src/firestore.dart
@@ -21,8 +21,11 @@
 /// tools/bots.
 class FirestoreDatabase {
   final http.Client _client = http.Client();
-  final String _authToken;
-  final String _project;
+  final Map<String, String> _headers;
+  final Uri _documentsUrl;
+  final Uri _queryUrl;
+  final Uri _beginTransactionUrl;
+  final Uri _commitUrl;
 
   /// The current transaction ID in base64 (or `null`)
   String _currentTransaction;
@@ -34,27 +37,30 @@
         .replaceAll("+", "%2B");
   }
 
-  FirestoreDatabase(this._project, this._authToken);
+  FirestoreDatabase._(this._headers, this._documentsUrl, this._queryUrl,
+      this._beginTransactionUrl, this._commitUrl);
 
-  static const apiUrl = 'https://firestore.googleapis.com/v1beta1';
-
-  String get projectUrl => '$apiUrl/projects/$_project';
-
-  String get documentsUrl => '$projectUrl/databases/(default)/documents';
-
-  String get queryUrl => '$documentsUrl:runQuery';
-
-  Map<String, String> get _headers {
-    return {
-      'Authorization': 'Bearer $_authToken',
+  factory FirestoreDatabase(String project, String authToken) {
+    var databaseUrl = _apiUrl.resolve('projects/$project/databases/(default)/');
+    var documentsUrl = databaseUrl.resolve('documents/');
+    var queryUrl = databaseUrl.resolveUri(Uri(path: 'documents:runQuery'));
+    var beginTransactionUrl =
+        databaseUrl.resolveUri(Uri(path: 'documents:beginTransaction'));
+    var commitUrl = databaseUrl.resolveUri(Uri(path: 'documents:commit'));
+    var headers = {
+      'Authorization': 'Bearer $authToken',
       'Accept': 'application/json',
       'Content-Type': 'application/json'
     };
+    return FirestoreDatabase._(
+        headers, documentsUrl, queryUrl, beginTransactionUrl, commitUrl);
   }
 
+  static final _apiUrl = Uri.https('firestore.googleapis.com', 'v1beta1/');
+
   Future<List /*!*/ > runQuery(Query query) async {
     var body = jsonEncode(query.data);
-    var response = await _client.post(queryUrl, headers: _headers, body: body);
+    var response = await _client.post(_queryUrl, headers: _headers, body: body);
     if (response.statusCode == HttpStatus.ok) {
       return jsonDecode(response.body);
     } else {
@@ -63,10 +69,11 @@
   }
 
   Future<Map> getDocument(String collectionName, String documentName) async {
-    var url = '$documentsUrl/$collectionName/$documentName';
-    if (_currentTransaction != null) {
-      url = '$url?transaction=${_escapedCurrentTransaction}';
-    }
+    var url = _documentsUrl.resolveUri(Uri(
+        path: '$collectionName/$documentName',
+        query: _currentTransaction == null
+            ? null
+            : 'transaction=${_escapedCurrentTransaction}'));
     var response = await _client.get(url, headers: _headers);
     if (response.statusCode == HttpStatus.ok) {
       var document = jsonDecode(response.body);
@@ -80,7 +87,8 @@
   }
 
   Future<Object> updateField(Map document, String field) async {
-    var url = '$apiUrl/${document["name"]}?updateMask.fieldPaths=$field';
+    var url =
+        _apiUrl.resolve('${document["name"]}?updateMask.fieldPaths=$field');
     var response =
         await _client.patch(url, headers: _headers, body: jsonEncode(document));
     if (response.statusCode == HttpStatus.ok) {
@@ -94,9 +102,9 @@
     if (_currentTransaction != null) {
       throw Exception('Error: nested transactions');
     }
-    var url = '$documentsUrl:beginTransaction';
     var body = '{"options": {}}';
-    var response = await _client.post(url, headers: _headers, body: body);
+    var response =
+        await _client.post(_beginTransactionUrl, headers: _headers, body: body);
     if (response.statusCode == HttpStatus.ok) {
       var result = jsonDecode(response.body);
       _currentTransaction = result['transaction'] as String;
@@ -116,8 +124,8 @@
       "writes": writes.map((write) => write.data).toList(),
       "transaction": "$_currentTransaction"
     });
-    var url = '$documentsUrl:commit';
-    var response = await _client.post(url, headers: _headers, body: body);
+    var response =
+        await _client.post(_commitUrl, headers: _headers, body: body);
     _currentTransaction = null;
     if (response.statusCode == HttpStatus.conflict) {
       // This HTTP status code corresponds to the ABORTED error code, see
diff --git a/tools/bots/test_matrix.json b/tools/bots/test_matrix.json
index 81e1228..9d6d61a 100644
--- a/tools/bots/test_matrix.json
+++ b/tools/bots/test_matrix.json
@@ -244,12 +244,15 @@
       "out/DebugIA32/",
       "out/DebugSIMARM/",
       "out/DebugSIMARM64/",
+      "out/DebugSIMARM64C/",
       "out/DebugX64/",
-      "out/ProductX64/",
+      "out/DebugX64C/",
       "out/ReleaseIA32/",
       "out/ReleaseSIMARM/",
       "out/ReleaseSIMARM64/",
+      "out/ReleaseSIMARM64C/",
       "out/ReleaseX64/",
+      "out/ReleaseX64C/",
       "third_party/pkg/",
       "third_party/pkg_tested/",
       "tools/sdks/dart-sdk/",
@@ -610,6 +613,18 @@
         ]
       }
     },
+    "dart2js-minified-csp-max-fragments-(linux|mac|win)-chrome": {
+      "options": {
+        "minified": true,
+        "csp": true,
+        "timeout": 240,
+        "dart2js-options": [
+          "--libraries-spec=sdk/lib/libraries.json",
+          "--platform-binaries=out/ReleaseX64/",
+          "--merge-fragments-threshold=3"
+        ]
+      }
+    },
     "dart2js-minified-(linux|mac|win)-d8": {
       "options": {
         "minified": true,
@@ -625,6 +640,19 @@
         ]
       }
     },
+    "dart2js-minified-hostasserts-weak-max-fragments-(linux|win)-x64-d8": {
+      "options": {
+        "minified": true,
+        "host-checked": true,
+        "timeout": 240,
+        "builder-tag": "dart2js-weak",
+        "dart2js-options": [
+          "--libraries-spec=sdk/lib/libraries.json",
+          "--platform-binaries=out/ReleaseX64/",
+          "--merge-fragments-threshold=3"
+        ]
+      }
+    },
     "dart2js-production-(linux|mac|win)-d8": {
       "options": {
         "builder-tag": "dart2js_production",
@@ -2576,6 +2604,16 @@
             "--dart2js-batch",
             "dart2js_2"
           ]
+        },
+        {
+          "name": "dart2js d8 fragment merging tests",
+          "arguments": [
+            "-ndart2js-minified-hostasserts-weak-max-fragments-linux-x64-d8",
+            "--dart2js-batch",
+            "web/deferred/"
+          ],
+          "shards": 1,
+          "fileset": "web_platform_hostasserts"
         }
       ]
     },
@@ -2630,6 +2668,14 @@
             "--dart2js-batch",
             "web_2"
           ]
+        },
+        {
+          "name": "dart2js d8 fragment merging tests",
+          "arguments": [
+            "-ndart2js-minified-csp-max-fragments-linux-chrome",
+            "--dart2js-batch",
+            "web/deferred/"
+          ]
         }
       ]
     },
@@ -3257,6 +3303,7 @@
           "script": "out/ReleaseX64/dart-sdk/bin/dart",
           "arguments": [
             "analyze",
+            "--fatal-infos",
             "pkg/test_runner"
           ]
         },
@@ -3342,7 +3389,8 @@
           "name": "build dart",
           "script": "tools/build.py",
           "arguments": [
-            "create_sdk"
+            "create_sdk",
+            "dartdevc_test"
           ]
         },
         {
@@ -3408,7 +3456,8 @@
           "name": "build dart",
           "script": "tools/build.py",
           "arguments": [
-            "create_sdk"
+            "create_sdk",
+            "dartdevc_test"
           ]
         },
         {
@@ -3605,7 +3654,7 @@
           "name": "run tests",
           "script": "tools/bots/flutter/compile_flutter.sh",
           "arguments": [
-            "--leakTest"
+            "--weeklyTest"
           ]
         }
       ]
@@ -3623,7 +3672,7 @@
           "script": "tools/build.py",
           "arguments": [
             "--mode=debug,release",
-            "--arch=x64,simarm64",
+            "--arch=x64,x64c,simarm64,simarm64c",
             "runtime",
             "dart_precompiled_runtime"
           ]
diff --git a/tools/experimental_features.yaml b/tools/experimental_features.yaml
index f3375ea..336213d 100644
--- a/tools/experimental_features.yaml
+++ b/tools/experimental_features.yaml
@@ -119,9 +119,6 @@
   variance:
     help: "Sound variance"
 
-  nonfunction-type-aliases:
-    help: "Type aliases define a <type>, not just a <functionType>"
-
   alternative-invalidation-strategy:
     help: "Alternative invalidation strategy for incremental compilation"
     category: "CFE"
@@ -143,6 +140,16 @@
 # on the command line, and will eventually be removed.
 #
 
+  nonfunction-type-aliases:
+    help: "Type aliases define a <type>, not just a <functionType>"
+    enabledIn: '2.13.0'
+    validation: |
+      typedef S = String;
+      void main() {
+        S s = 'feature enabled';
+        print(s);
+      }
+
   non-nullable:
     help: "Non Nullable by default"
     experimentalReleaseVersion: '2.10.0'
diff --git a/tools/get_dot_git_folder.py b/tools/get_dot_git_folder.py
new file mode 100755
index 0000000..443addbf
--- /dev/null
+++ b/tools/get_dot_git_folder.py
@@ -0,0 +1,47 @@
+#!/usr/bin/env python
+# Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+# for 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 python script is a wrapper around `git rev-parse --resolve-git-dir`.
+# This is used for the build system to work with git worktrees.
+
+import sys
+import subprocess
+import os
+import utils
+
+
+def main():
+    try:
+        if len(sys.argv) != 3:
+            raise Exception('Expects exactly 2 arguments.')
+        args = ['git', 'rev-parse', '--resolve-git-dir', sys.argv[1]]
+
+        windows = utils.GuessOS() == 'win32'
+        if windows:
+            process = subprocess.Popen(args,
+                                       stdout=subprocess.PIPE,
+                                       stderr=subprocess.PIPE,
+                                       stdin=subprocess.PIPE,
+                                       shell=True)
+        else:
+            process = subprocess.Popen(args,
+                                       stdout=subprocess.PIPE,
+                                       stderr=subprocess.PIPE,
+                                       stdin=subprocess.PIPE,
+                                       shell=False)
+
+        outs, _ = process.communicate()
+
+        if process.returncode != 0:
+            raise Exception('Got non-0 exit code from git.')
+
+        print(outs.strip())
+    except:
+        # Fall back to fall-back path.
+        print(sys.argv[2])
+
+
+if __name__ == '__main__':
+    sys.exit(main())